Skip to content

Commit

Permalink
Replace bcoin with bitcoinjs-lib for deposit-sweep (#700)
Browse files Browse the repository at this point in the history
Depends on: #696.
Refs: #695.

This PR replaces the `bcoin` library with `bitcoinjs-lib` for deposit
sweep transactions.
The `bcoin` library was removed from `deposit-sweep.ts`.
After this update, deposit sweep generally works in the same way as
before.
The only difference is that transaction inputs are always added in the
same order:
 - main UTXO is added first
 - deposit inputs are added in the same order as the provided UTXOs.
 
Before this change the inputs could be rearranged by the `bcoin`
library.
  • Loading branch information
lukasz-zimnoch authored Sep 28, 2023
2 parents d9806cd + a5ef9e8 commit c5edcdf
Show file tree
Hide file tree
Showing 11 changed files with 617 additions and 250 deletions.
2 changes: 2 additions & 0 deletions typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@
"bcoin": "git+https://github.com/keep-network/bcoin.git#5accd32c63e6025a0d35d67739c4a6e84095a1f8",
"bitcoinjs-lib": "6.0.2",
"bufio": "^1.0.6",
"ecpair": "^2.1.0",
"electrum-client-js": "git+https://github.com/keep-network/electrum-client-js.git#v0.1.1",
"ethers": "^5.5.2",
"p-timeout": "^4.1.0",
"tiny-secp256k1": "^2.2.3",
"wif": "2.0.6"
},
"devDependencies": {
Expand Down
24 changes: 24 additions & 0 deletions typescript/src/bitcoin-network.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Hex } from "./hex"
import { networks } from "bitcoinjs-lib"

/**
* Bitcoin networks.
Expand Down Expand Up @@ -64,3 +65,26 @@ export function toBcoinNetwork(bitcoinNetwork: BitcoinNetwork): string {
}
}
}

/**
* Converts the provided {@link BitcoinNetwork} enumeration to a format expected
* by the `bitcoinjs-lib` library.
* @param bitcoinNetwork - Specified Bitcoin network.
* @returns Network representation compatible with the `bitcoinjs-lib` library.
* @throws An error if the network is not supported by `bitcoinjs-lib`.
*/
export function toBitcoinJsLibNetwork(
bitcoinNetwork: BitcoinNetwork
): networks.Network {
switch (bitcoinNetwork) {
case BitcoinNetwork.Mainnet: {
return networks.bitcoin
}
case BitcoinNetwork.Testnet: {
return networks.testnet
}
default: {
throw new Error(`network not supported`)
}
}
}
88 changes: 87 additions & 1 deletion typescript/src/bitcoin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import wif from "wif"
import bufio from "bufio"
import { BigNumber, utils } from "ethers"
import { Hex } from "./hex"
import { BitcoinNetwork, toBcoinNetwork } from "./bitcoin-network"
import {
BitcoinNetwork,
toBcoinNetwork,
toBitcoinJsLibNetwork,
} from "./bitcoin-network"
import { payments } from "bitcoinjs-lib"

/**
* Represents a transaction hash (or transaction ID) as an un-prefixed hex
Expand Down Expand Up @@ -644,6 +649,31 @@ export function createAddressFromOutputScript(
?.toString(toBcoinNetwork(network))
}

/**
* Creates the Bitcoin address from the public key. Supports SegWit (P2WPKH) and
* Legacy (P2PKH) formats.
* @param publicKey - Public key used to derive the Bitcoin address.
* @param bitcoinNetwork - Target Bitcoin network.
* @param witness - Flag to determine address format: true for SegWit (P2WPKH)
* and false for Legacy (P2PKH). Default is true.
* @returns The derived Bitcoin address.
*/
export function createAddressFromPublicKey(
publicKey: Hex,
bitcoinNetwork: BitcoinNetwork,
witness: boolean = true
): string {
const network = toBitcoinJsLibNetwork(bitcoinNetwork)

if (witness) {
// P2WPKH (SegWit)
return payments.p2wpkh({ pubkey: publicKey.toBuffer(), network }).address!
} else {
// P2PKH (Legacy)
return payments.p2pkh({ pubkey: publicKey.toBuffer(), network }).address!
}
}

/**
* Reads the leading compact size uint from the provided variable length data.
*
Expand Down Expand Up @@ -683,3 +713,59 @@ export function readCompactSizeUint(varLenData: Hex): {
}
}
}

/**
* Checks if the provided script comes from a P2PKH input.
* @param script The script to be checked.
* @returns True if the script is P2PKH, false otherwise.
*/
export function isP2PKHScript(script: Buffer): boolean {
try {
payments.p2pkh({ output: script })
return true
} catch (err) {
return false
}
}

/**
* Checks if the provided script comes from a P2WPKH input.
* @param script The script to be checked.
* @returns True if the script is P2WPKH, false otherwise.
*/
export function isP2WPKHScript(script: Buffer): boolean {
try {
payments.p2wpkh({ output: script })
return true
} catch (err) {
return false
}
}

/**
* Checks if the provided script comes from a P2SH input.
* @param script The script to be checked.
* @returns True if the script is P2SH, false otherwise.
*/
export function isP2SHScript(script: Buffer): boolean {
try {
payments.p2sh({ output: script })
return true
} catch (err) {
return false
}
}

/**
* Checks if the provided script comes from a P2PKH input.
* @param script The script to be checked.
* @returns True if the script is P2WSH, false otherwise.
*/
export function isP2WSHScript(script: Buffer): boolean {
try {
payments.p2wsh({ output: script })
return true
} catch (err) {
return false
}
}
Loading

0 comments on commit c5edcdf

Please sign in to comment.