From 284e202d4d7ccef209be553d3bcf882e8c693559 Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Fri, 13 Oct 2023 10:28:58 +0200 Subject: [PATCH 01/22] Used Hex for argument in publicKeyHashToAddress --- typescript/src/lib/bitcoin/address.ts | 9 +++---- .../redemptions/redemptions-service.ts | 2 +- typescript/test/lib/bitcoin.test.ts | 26 ++++++++++++------- typescript/test/services/redemptions.test.ts | 6 ++--- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/typescript/src/lib/bitcoin/address.ts b/typescript/src/lib/bitcoin/address.ts index 3d5dd2594..a26bfe3d5 100644 --- a/typescript/src/lib/bitcoin/address.ts +++ b/typescript/src/lib/bitcoin/address.ts @@ -29,20 +29,19 @@ export function publicKeyToAddress( /** * Converts a public key hash into a P2PKH/P2WPKH address. - * @param publicKeyHash Public key hash that will be encoded. Must be an - * unprefixed hex string (without 0x prefix). + * @param publicKeyHash Public key hash that will be encoded. * @param witness If true, a witness public key hash will be encoded and * P2WPKH address will be returned. Returns P2PKH address otherwise * @param bitcoinNetwork Network the address should be encoded for. - * @returns P2PKH or P2WPKH address encoded from the given public key hash + * @returns P2PKH or P2WPKH address encoded from the given public key hash. * @throws Throws an error if network is not supported. */ function publicKeyHashToAddress( - publicKeyHash: string, + publicKeyHash: Hex, witness: boolean, bitcoinNetwork: BitcoinNetwork ): string { - const hash = Buffer.from(publicKeyHash, "hex") + const hash = publicKeyHash.toBuffer() const network = toBitcoinJsLibNetwork(bitcoinNetwork) return witness ? payments.p2wpkh({ hash, network }).address! diff --git a/typescript/src/services/redemptions/redemptions-service.ts b/typescript/src/services/redemptions/redemptions-service.ts index f3fd5f49c..a6bc302f1 100644 --- a/typescript/src/services/redemptions/redemptions-service.ts +++ b/typescript/src/services/redemptions/redemptions-service.ts @@ -239,7 +239,7 @@ export class RedemptionsService { ): Promise => { // Build the wallet Bitcoin address based on its public key hash. const walletAddress = BitcoinAddressConverter.publicKeyHashToAddress( - walletPublicKeyHash.toString(), + walletPublicKeyHash, witnessAddress, bitcoinNetwork ) diff --git a/typescript/test/lib/bitcoin.test.ts b/typescript/test/lib/bitcoin.test.ts index 8483732ba..6e3e1aaa4 100644 --- a/typescript/test/lib/bitcoin.test.ts +++ b/typescript/test/lib/bitcoin.test.ts @@ -205,7 +205,7 @@ describe("Bitcoin", () => { }) describe("BitcoinAddressConverter", () => { - const publicKeyHash = "3a38d44d6a0c8d0bb84e0232cc632b7e48c72e0e" + const publicKeyHash = Hex.from("3a38d44d6a0c8d0bb84e0232cc632b7e48c72e0e") const P2WPKHAddress = "bc1q8gudgnt2pjxshwzwqgevccet0eyvwtswt03nuy" const P2PKHAddress = "16JrGhLx5bcBSA34kew9V6Mufa4aXhFe9X" const P2WPKHAddressTestnet = "tb1q8gudgnt2pjxshwzwqgevccet0eyvwtswpf2q8h" @@ -260,7 +260,9 @@ describe("Bitcoin", () => { context("when wrong public key hash is provided", () => { it("should throw", () => { - const wrongPublicKeyHash = "02" + publicKeyHash + const wrongPublicKeyHash = Hex.from( + "02" + publicKeyHash.toString() + ) expect(() => publicKeyHashToAddress( @@ -290,7 +292,9 @@ describe("Bitcoin", () => { context("when wrong public key hash is provided", () => { it("should throw", () => { - const wrongPublicKeyHash = "02" + publicKeyHash + const wrongPublicKeyHash = Hex.from( + "02" + publicKeyHash.toString() + ) expect(() => publicKeyHashToAddress( @@ -322,7 +326,9 @@ describe("Bitcoin", () => { context("when wrong public key hash is provided", () => { it("should throw", () => { - const wrongPublicKeyHash = "02" + publicKeyHash + const wrongPublicKeyHash = Hex.from( + "02" + publicKeyHash.toString() + ) expect(() => publicKeyHashToAddress( @@ -352,7 +358,9 @@ describe("Bitcoin", () => { context("when wrong public key hash is provided", () => { it("should throw", () => { - const wrongPublicKeyHash = "02" + publicKeyHash + const wrongPublicKeyHash = Hex.from( + "02" + publicKeyHash.toString() + ) expect(() => publicKeyHashToAddress( @@ -383,7 +391,7 @@ describe("Bitcoin", () => { it("should decode P2WPKH adress correctly", () => { expect( addressToPublicKeyHash(P2WPKHAddress, BitcoinNetwork.Mainnet) - ).to.be.equal(publicKeyHash) + ).to.be.equal(publicKeyHash.toString()) }) }) @@ -391,7 +399,7 @@ describe("Bitcoin", () => { it("should decode P2PKH address correctly", () => { expect( addressToPublicKeyHash(P2PKHAddress, BitcoinNetwork.Mainnet) - ).to.be.equal(publicKeyHash) + ).to.be.equal(publicKeyHash.toString()) }) }) @@ -455,7 +463,7 @@ describe("Bitcoin", () => { P2WPKHAddressTestnet, BitcoinNetwork.Testnet ) - ).to.be.equal(publicKeyHash) + ).to.be.equal(publicKeyHash.toString()) }) }) @@ -466,7 +474,7 @@ describe("Bitcoin", () => { P2PKHAddressTestnet, BitcoinNetwork.Testnet ) - ).to.be.equal(publicKeyHash) + ).to.be.equal(publicKeyHash.toString()) }) }) diff --git a/typescript/test/services/redemptions.test.ts b/typescript/test/services/redemptions.test.ts index 1b9a82e24..95146562f 100644 --- a/typescript/test/services/redemptions.test.ts +++ b/typescript/test/services/redemptions.test.ts @@ -73,7 +73,7 @@ describe("Redemptions", () => { } as Wallet) const walletAddress = BitcoinAddressConverter.publicKeyHashToAddress( - walletPublicKeyHash.toString(), + walletPublicKeyHash, true, BitcoinNetwork.Testnet ) @@ -751,13 +751,13 @@ describe("Redemptions", () => { const walletWitnessAddress = BitcoinAddressConverter.publicKeyHashToAddress( - walletPublicKeyHash.toString(), + walletPublicKeyHash, true, bitcoinNetwork ) const walletLegacyAddress = BitcoinAddressConverter.publicKeyHashToAddress( - walletPublicKeyHash.toString(), + walletPublicKeyHash, false, bitcoinNetwork ) From c7c73e724a5f1830b6d5bbab93b8e62f4a563d51 Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Fri, 13 Oct 2023 11:07:48 +0200 Subject: [PATCH 02/22] Used Hex as return value in addressToPublicKeyHash --- typescript/src/lib/bitcoin/address.ts | 9 ++++----- typescript/src/services/deposits/deposits-service.ts | 2 +- typescript/test/lib/bitcoin.test.ts | 8 ++++---- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/typescript/src/lib/bitcoin/address.ts b/typescript/src/lib/bitcoin/address.ts index a26bfe3d5..628ab6a6c 100644 --- a/typescript/src/lib/bitcoin/address.ts +++ b/typescript/src/lib/bitcoin/address.ts @@ -53,25 +53,24 @@ function publicKeyHashToAddress( * provided address is not PKH-based. * @param address P2PKH or P2WPKH address that will be decoded. * @param bitcoinNetwork Network the address should be decoded for. - * @returns Public key hash decoded from the address. This will be an unprefixed - * hex string (without 0x prefix). + * @returns Public key hash decoded from the address. */ function addressToPublicKeyHash( address: string, bitcoinNetwork: BitcoinNetwork -): string { +): Hex { const network = toBitcoinJsLibNetwork(bitcoinNetwork) try { // Try extracting hash from P2PKH address. const hash = payments.p2pkh({ address: address, network }).hash! - return hash.toString("hex") + return Hex.from(hash) } catch (err) {} try { // Try extracting hash from P2WPKH address. const hash = payments.p2wpkh({ address: address, network }).hash! - return hash.toString("hex") + return Hex.from(hash) } catch (err) {} throw new Error("Address must be P2PKH or P2WPKH valid for given network") diff --git a/typescript/src/services/deposits/deposits-service.ts b/typescript/src/services/deposits/deposits-service.ts index e04048d29..31bb6ec20 100644 --- a/typescript/src/services/deposits/deposits-service.ts +++ b/typescript/src/services/deposits/deposits-service.ts @@ -85,7 +85,7 @@ export class DepositsService { const refundPublicKeyHash = BitcoinAddressConverter.addressToPublicKeyHash( bitcoinRecoveryAddress, bitcoinNetwork - ) + ).toString() const currentTimestamp = Math.floor(new Date().getTime() / 1000) diff --git a/typescript/test/lib/bitcoin.test.ts b/typescript/test/lib/bitcoin.test.ts index 6e3e1aaa4..224aa25f7 100644 --- a/typescript/test/lib/bitcoin.test.ts +++ b/typescript/test/lib/bitcoin.test.ts @@ -391,7 +391,7 @@ describe("Bitcoin", () => { it("should decode P2WPKH adress correctly", () => { expect( addressToPublicKeyHash(P2WPKHAddress, BitcoinNetwork.Mainnet) - ).to.be.equal(publicKeyHash.toString()) + ).to.be.deep.equal(publicKeyHash) }) }) @@ -399,7 +399,7 @@ describe("Bitcoin", () => { it("should decode P2PKH address correctly", () => { expect( addressToPublicKeyHash(P2PKHAddress, BitcoinNetwork.Mainnet) - ).to.be.equal(publicKeyHash.toString()) + ).to.be.deep.equal(publicKeyHash) }) }) @@ -463,7 +463,7 @@ describe("Bitcoin", () => { P2WPKHAddressTestnet, BitcoinNetwork.Testnet ) - ).to.be.equal(publicKeyHash.toString()) + ).to.be.deep.equal(publicKeyHash) }) }) @@ -474,7 +474,7 @@ describe("Bitcoin", () => { P2PKHAddressTestnet, BitcoinNetwork.Testnet ) - ).to.be.equal(publicKeyHash.toString()) + ).to.be.deep.equal(publicKeyHash) }) }) From 00f0e9e239677bef681761661b5588eeace9dc8b Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Fri, 13 Oct 2023 11:32:57 +0200 Subject: [PATCH 03/22] Used Hex fro argument in computeHash160 --- typescript/src/lib/bitcoin/hash.ts | 6 ++---- typescript/src/lib/ethereum/bridge.ts | 8 ++++---- typescript/src/lib/ethereum/tbtc-token.ts | 2 +- typescript/src/services/deposits/deposit.ts | 2 +- typescript/src/services/deposits/deposits-service.ts | 5 ++++- typescript/src/services/deposits/refund.ts | 3 ++- typescript/src/services/maintenance/wallet-tx.ts | 2 +- typescript/test/lib/bitcoin.test.ts | 3 ++- typescript/test/lib/ethereum.test.ts | 2 +- typescript/test/services/redemptions.test.ts | 2 +- typescript/test/utils/mock-bridge.ts | 2 +- 11 files changed, 20 insertions(+), 17 deletions(-) diff --git a/typescript/src/lib/bitcoin/hash.ts b/typescript/src/lib/bitcoin/hash.ts index 018771f19..79c1f277a 100644 --- a/typescript/src/lib/bitcoin/hash.ts +++ b/typescript/src/lib/bitcoin/hash.ts @@ -6,10 +6,8 @@ import { Hex } from "../utils" * @param text - Text the HASH160 is computed for. * @returns Hash as a 20-byte un-prefixed hex string. */ -function computeHash160(text: string): string { - const sha256Hash = utils.sha256( - Hex.from(Buffer.from(text, "hex")).toPrefixedString() - ) +function computeHash160(text: Hex): string { + const sha256Hash = utils.sha256(text.toPrefixedString()) const hash160 = utils.ripemd160(sha256Hash) return Hex.from(hash160).toString() diff --git a/typescript/src/lib/ethereum/bridge.ts b/typescript/src/lib/ethereum/bridge.ts index fecf0fe25..f20d70d19 100644 --- a/typescript/src/lib/ethereum/bridge.ts +++ b/typescript/src/lib/ethereum/bridge.ts @@ -133,7 +133,7 @@ export class EthereumBridge redeemerOutputScript: string ): Promise { const redemptionKey = EthereumBridge.buildRedemptionKey( - BitcoinHashUtils.computeHash160(walletPublicKey), + BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)), redeemerOutputScript ) @@ -156,7 +156,7 @@ export class EthereumBridge redeemerOutputScript: string ): Promise { const redemptionKey = EthereumBridge.buildRedemptionKey( - BitcoinHashUtils.computeHash160(walletPublicKey), + BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)), redeemerOutputScript ) @@ -335,7 +335,7 @@ export class EthereumBridge amount: BigNumber ): Promise { const walletPublicKeyHash = `0x${BitcoinHashUtils.computeHash160( - walletPublicKey + Hex.from(walletPublicKey) )}` const mainUtxoParam = { @@ -399,7 +399,7 @@ export class EthereumBridge } const walletPublicKeyHash = `0x${BitcoinHashUtils.computeHash160( - walletPublicKey + Hex.from(walletPublicKey) )}` await EthersTransactionUtils.sendWithRetry( diff --git a/typescript/src/lib/ethereum/tbtc-token.ts b/typescript/src/lib/ethereum/tbtc-token.ts index c100473cb..c454e9a78 100644 --- a/typescript/src/lib/ethereum/tbtc-token.ts +++ b/typescript/src/lib/ethereum/tbtc-token.ts @@ -138,7 +138,7 @@ export class EthereumTBTCToken redeemerOutputScript: string ) { const walletPublicKeyHash = `0x${BitcoinHashUtils.computeHash160( - walletPublicKey + Hex.from(walletPublicKey) )}` const mainUtxoParam = { diff --git a/typescript/src/services/deposits/deposit.ts b/typescript/src/services/deposits/deposit.ts index ed93eff73..49d160de1 100644 --- a/typescript/src/services/deposits/deposit.ts +++ b/typescript/src/services/deposits/deposit.ts @@ -186,7 +186,7 @@ export class DepositScript { // Legacy script hash needs HASH160. return this.witness ? BitcoinHashUtils.computeSha256(Hex.from(script)).toBuffer() - : Buffer.from(BitcoinHashUtils.computeHash160(script), "hex") + : Buffer.from(BitcoinHashUtils.computeHash160(Hex.from(script)), "hex") } /** diff --git a/typescript/src/services/deposits/deposits-service.ts b/typescript/src/services/deposits/deposits-service.ts index 31bb6ec20..1ebfcb9a7 100644 --- a/typescript/src/services/deposits/deposits-service.ts +++ b/typescript/src/services/deposits/deposits-service.ts @@ -10,6 +10,7 @@ import { BitcoinLocktimeUtils, } from "../../lib/bitcoin" import { Deposit } from "./deposit" +import { Hex } from "../../lib/utils" import * as crypto from "crypto" /** @@ -75,7 +76,9 @@ export class DepositsService { throw new Error("Could not get active wallet public key") } - const walletPublicKeyHash = BitcoinHashUtils.computeHash160(walletPublicKey) + const walletPublicKeyHash = BitcoinHashUtils.computeHash160( + Hex.from(walletPublicKey) + ) const bitcoinNetwork = await this.bitcoinClient.getNetwork() diff --git a/typescript/src/services/deposits/refund.ts b/typescript/src/services/deposits/refund.ts index d4ad401fb..66821e4c2 100644 --- a/typescript/src/services/deposits/refund.ts +++ b/typescript/src/services/deposits/refund.ts @@ -12,6 +12,7 @@ import { BitcoinUtxo, } from "../../lib/bitcoin" import { validateDepositReceipt } from "../../lib/contracts" +import { Hex } from "../../lib/utils" import { DepositScript } from "./" import { Signer, @@ -191,7 +192,7 @@ export class DepositRefund { const refunderPublicKey = refunderKeyPair.publicKey.toString("hex") if ( - BitcoinHashUtils.computeHash160(refunderPublicKey) != + BitcoinHashUtils.computeHash160(Hex.from(refunderPublicKey)) != this.script.receipt.refundPublicKeyHash ) { throw new Error( diff --git a/typescript/src/services/maintenance/wallet-tx.ts b/typescript/src/services/maintenance/wallet-tx.ts index dda223671..b461f6599 100644 --- a/typescript/src/services/maintenance/wallet-tx.ts +++ b/typescript/src/services/maintenance/wallet-tx.ts @@ -469,7 +469,7 @@ class DepositSweep { const walletPublicKey = walletKeyPair.publicKey.toString("hex") if ( - BitcoinHashUtils.computeHash160(walletPublicKey) != + BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)) != deposit.walletPublicKeyHash ) { throw new Error( diff --git a/typescript/test/lib/bitcoin.test.ts b/typescript/test/lib/bitcoin.test.ts index 224aa25f7..c144f617e 100644 --- a/typescript/test/lib/bitcoin.test.ts +++ b/typescript/test/lib/bitcoin.test.ts @@ -153,8 +153,9 @@ describe("Bitcoin", () => { describe("computeHash160", () => { it("should compute hash160 correctly", () => { - const compressedPublicKey = + const compressedPublicKey = Hex.from( "03474444cca71c678f5019d16782b6522735717a94602085b4adf707b465c36ca8" + ) const expectedHash160 = "3e1dfbd72483fb3964ca828ee71cf3270cafdc65" expect(computeHash160(compressedPublicKey)).to.be.equal(expectedHash160) diff --git a/typescript/test/lib/ethereum.test.ts b/typescript/test/lib/ethereum.test.ts index 727c273b3..806297a0c 100644 --- a/typescript/test/lib/ethereum.test.ts +++ b/typescript/test/lib/ethereum.test.ts @@ -557,7 +557,7 @@ describe("Ethereum", () => { [ redeemer.identifierHex, Hex.from( - BitcoinHashUtils.computeHash160(walletPublicKey) + BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)) ).toPrefixedString(), mainUtxo.transactionHash.reverse().toPrefixedString(), mainUtxo.outputIndex, diff --git a/typescript/test/services/redemptions.test.ts b/typescript/test/services/redemptions.test.ts index 95146562f..04cd7252b 100644 --- a/typescript/test/services/redemptions.test.ts +++ b/typescript/test/services/redemptions.test.ts @@ -54,7 +54,7 @@ describe("Redemptions", () => { bitcoinClient = new MockBitcoinClient() const walletPublicKeyHash = Hex.from( - BitcoinHashUtils.computeHash160(walletPublicKey) + BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)) ) // Prepare NewWalletRegisteredEvent history. Set only relevant fields. diff --git a/typescript/test/utils/mock-bridge.ts b/typescript/test/utils/mock-bridge.ts index f6fbd0757..48cd4603f 100644 --- a/typescript/test/utils/mock-bridge.ts +++ b/typescript/test/utils/mock-bridge.ts @@ -295,7 +295,7 @@ export class MockBridge implements Bridge { redemptionsMap: Map ): RedemptionRequest { const redemptionKey = MockBridge.buildRedemptionKey( - BitcoinHashUtils.computeHash160(walletPublicKey), + BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)), redeemerOutputScript ) From 5faf6b4661f73c0c23706a4bc2c25eb43582c224 Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Fri, 13 Oct 2023 11:48:35 +0200 Subject: [PATCH 04/22] Used Hex as return value in computeHash160 --- typescript/src/lib/bitcoin/hash.ts | 10 +++++----- typescript/src/lib/ethereum/bridge.ts | 12 ++++++------ typescript/src/lib/ethereum/tbtc-token.ts | 4 ++-- typescript/src/services/deposits/deposit.ts | 2 +- typescript/src/services/deposits/deposits-service.ts | 2 +- typescript/src/services/deposits/refund.ts | 2 +- typescript/src/services/maintenance/wallet-tx.ts | 2 +- typescript/test/lib/bitcoin.test.ts | 4 +++- typescript/test/lib/ethereum.test.ts | 4 ++-- typescript/test/services/redemptions.test.ts | 4 ++-- typescript/test/utils/mock-bridge.ts | 2 +- 11 files changed, 25 insertions(+), 23 deletions(-) diff --git a/typescript/src/lib/bitcoin/hash.ts b/typescript/src/lib/bitcoin/hash.ts index 79c1f277a..c92876aaf 100644 --- a/typescript/src/lib/bitcoin/hash.ts +++ b/typescript/src/lib/bitcoin/hash.ts @@ -4,19 +4,19 @@ import { Hex } from "../utils" /** * Computes the HASH160 for the given text. * @param text - Text the HASH160 is computed for. - * @returns Hash as a 20-byte un-prefixed hex string. + * @returns 20-byte-long hash. */ -function computeHash160(text: Hex): string { +function computeHash160(text: Hex): Hex { const sha256Hash = utils.sha256(text.toPrefixedString()) const hash160 = utils.ripemd160(sha256Hash) - return Hex.from(hash160).toString() + return Hex.from(hash160) } /** * Computes the double SHA256 for the given text. * @param text - Text the double SHA256 is computed for. - * @returns Hash as a 32-byte un-prefixed hex string. + * @returns 32-byte-long hash. * @dev Do not confuse it with computeSha256 which computes single SHA256. */ function computeHash256(text: Hex): Hex { @@ -38,7 +38,7 @@ function hashLEToBigNumber(hash: Hex): BigNumber { /** * Computes the single SHA256 for the given text. * @param text - Text the single SHA256 is computed for. - * @returns Hash as a 32-byte un-prefixed hex string. + * @returns 32-byte-long hash. * @dev Do not confuse it with computeHash256 which computes double SHA256. */ function computeSha256(text: Hex): Hex { diff --git a/typescript/src/lib/ethereum/bridge.ts b/typescript/src/lib/ethereum/bridge.ts index f20d70d19..f3e4ce5ab 100644 --- a/typescript/src/lib/ethereum/bridge.ts +++ b/typescript/src/lib/ethereum/bridge.ts @@ -133,7 +133,7 @@ export class EthereumBridge redeemerOutputScript: string ): Promise { const redemptionKey = EthereumBridge.buildRedemptionKey( - BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)), + BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)).toString(), redeemerOutputScript ) @@ -156,7 +156,7 @@ export class EthereumBridge redeemerOutputScript: string ): Promise { const redemptionKey = EthereumBridge.buildRedemptionKey( - BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)), + BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)).toString(), redeemerOutputScript ) @@ -334,9 +334,9 @@ export class EthereumBridge redeemerOutputScript: string, amount: BigNumber ): Promise { - const walletPublicKeyHash = `0x${BitcoinHashUtils.computeHash160( + const walletPublicKeyHash = BitcoinHashUtils.computeHash160( Hex.from(walletPublicKey) - )}` + ).toPrefixedString() const mainUtxoParam = { // The Ethereum Bridge expects this hash to be in the Bitcoin internal @@ -398,9 +398,9 @@ export class EthereumBridge txOutputValue: mainUtxo.value, } - const walletPublicKeyHash = `0x${BitcoinHashUtils.computeHash160( + const walletPublicKeyHash = BitcoinHashUtils.computeHash160( Hex.from(walletPublicKey) - )}` + ).toPrefixedString() await EthersTransactionUtils.sendWithRetry( async () => { diff --git a/typescript/src/lib/ethereum/tbtc-token.ts b/typescript/src/lib/ethereum/tbtc-token.ts index c454e9a78..7ec5dbab3 100644 --- a/typescript/src/lib/ethereum/tbtc-token.ts +++ b/typescript/src/lib/ethereum/tbtc-token.ts @@ -137,9 +137,9 @@ export class EthereumTBTCToken mainUtxo: BitcoinUtxo, redeemerOutputScript: string ) { - const walletPublicKeyHash = `0x${BitcoinHashUtils.computeHash160( + const walletPublicKeyHash = BitcoinHashUtils.computeHash160( Hex.from(walletPublicKey) - )}` + ).toPrefixedString() const mainUtxoParam = { // The Ethereum Bridge expects this hash to be in the Bitcoin internal diff --git a/typescript/src/services/deposits/deposit.ts b/typescript/src/services/deposits/deposit.ts index 49d160de1..fcc7d869a 100644 --- a/typescript/src/services/deposits/deposit.ts +++ b/typescript/src/services/deposits/deposit.ts @@ -186,7 +186,7 @@ export class DepositScript { // Legacy script hash needs HASH160. return this.witness ? BitcoinHashUtils.computeSha256(Hex.from(script)).toBuffer() - : Buffer.from(BitcoinHashUtils.computeHash160(Hex.from(script)), "hex") + : BitcoinHashUtils.computeHash160(Hex.from(script)).toBuffer() } /** diff --git a/typescript/src/services/deposits/deposits-service.ts b/typescript/src/services/deposits/deposits-service.ts index 1ebfcb9a7..b8fba8d21 100644 --- a/typescript/src/services/deposits/deposits-service.ts +++ b/typescript/src/services/deposits/deposits-service.ts @@ -78,7 +78,7 @@ export class DepositsService { const walletPublicKeyHash = BitcoinHashUtils.computeHash160( Hex.from(walletPublicKey) - ) + ).toString() const bitcoinNetwork = await this.bitcoinClient.getNetwork() diff --git a/typescript/src/services/deposits/refund.ts b/typescript/src/services/deposits/refund.ts index 66821e4c2..81d331704 100644 --- a/typescript/src/services/deposits/refund.ts +++ b/typescript/src/services/deposits/refund.ts @@ -192,7 +192,7 @@ export class DepositRefund { const refunderPublicKey = refunderKeyPair.publicKey.toString("hex") if ( - BitcoinHashUtils.computeHash160(Hex.from(refunderPublicKey)) != + BitcoinHashUtils.computeHash160(Hex.from(refunderPublicKey)).toString() != this.script.receipt.refundPublicKeyHash ) { throw new Error( diff --git a/typescript/src/services/maintenance/wallet-tx.ts b/typescript/src/services/maintenance/wallet-tx.ts index b461f6599..b0306cdff 100644 --- a/typescript/src/services/maintenance/wallet-tx.ts +++ b/typescript/src/services/maintenance/wallet-tx.ts @@ -469,7 +469,7 @@ class DepositSweep { const walletPublicKey = walletKeyPair.publicKey.toString("hex") if ( - BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)) != + BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)).toString() != deposit.walletPublicKeyHash ) { throw new Error( diff --git a/typescript/test/lib/bitcoin.test.ts b/typescript/test/lib/bitcoin.test.ts index c144f617e..cdb706947 100644 --- a/typescript/test/lib/bitcoin.test.ts +++ b/typescript/test/lib/bitcoin.test.ts @@ -158,7 +158,9 @@ describe("Bitcoin", () => { ) const expectedHash160 = "3e1dfbd72483fb3964ca828ee71cf3270cafdc65" - expect(computeHash160(compressedPublicKey)).to.be.equal(expectedHash160) + expect(computeHash160(compressedPublicKey).toString()).to.be.equal( + expectedHash160 + ) }) }) diff --git a/typescript/test/lib/ethereum.test.ts b/typescript/test/lib/ethereum.test.ts index 806297a0c..11b4086d6 100644 --- a/typescript/test/lib/ethereum.test.ts +++ b/typescript/test/lib/ethereum.test.ts @@ -556,8 +556,8 @@ describe("Ethereum", () => { ["address", "bytes20", "bytes32", "uint32", "uint64", "bytes"], [ redeemer.identifierHex, - Hex.from( - BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)) + BitcoinHashUtils.computeHash160( + Hex.from(walletPublicKey) ).toPrefixedString(), mainUtxo.transactionHash.reverse().toPrefixedString(), mainUtxo.outputIndex, diff --git a/typescript/test/services/redemptions.test.ts b/typescript/test/services/redemptions.test.ts index 04cd7252b..7b22f26ac 100644 --- a/typescript/test/services/redemptions.test.ts +++ b/typescript/test/services/redemptions.test.ts @@ -53,8 +53,8 @@ describe("Redemptions", () => { tbtcContracts = new MockTBTCContracts() bitcoinClient = new MockBitcoinClient() - const walletPublicKeyHash = Hex.from( - BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)) + const walletPublicKeyHash = BitcoinHashUtils.computeHash160( + Hex.from(walletPublicKey) ) // Prepare NewWalletRegisteredEvent history. Set only relevant fields. diff --git a/typescript/test/utils/mock-bridge.ts b/typescript/test/utils/mock-bridge.ts index 48cd4603f..fe6a8a27c 100644 --- a/typescript/test/utils/mock-bridge.ts +++ b/typescript/test/utils/mock-bridge.ts @@ -295,7 +295,7 @@ export class MockBridge implements Bridge { redemptionsMap: Map ): RedemptionRequest { const redemptionKey = MockBridge.buildRedemptionKey( - BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)), + BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)).toString(), redeemerOutputScript ) From ba1ca6e1d8fa2023e2ddf5e469aed529bedfa473 Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Fri, 13 Oct 2023 13:51:12 +0200 Subject: [PATCH 05/22] Used Hex as argument in isScript functions --- typescript/src/lib/bitcoin/script.ts | 17 +++++----- typescript/src/services/deposits/funding.ts | 2 +- typescript/src/services/deposits/refund.ts | 2 +- .../src/services/maintenance/wallet-tx.ts | 34 ++++++++++++------- typescript/test/lib/bitcoin.test.ts | 20 ++++------- 5 files changed, 39 insertions(+), 36 deletions(-) diff --git a/typescript/src/lib/bitcoin/script.ts b/typescript/src/lib/bitcoin/script.ts index a66c39305..a514bddbe 100644 --- a/typescript/src/lib/bitcoin/script.ts +++ b/typescript/src/lib/bitcoin/script.ts @@ -1,3 +1,4 @@ +import { Hex } from "../utils" import { payments } from "bitcoinjs-lib" /** @@ -5,9 +6,9 @@ import { payments } from "bitcoinjs-lib" * @param script The script to be checked. * @returns True if the script is P2PKH, false otherwise. */ -function isP2PKHScript(script: Buffer): boolean { +function isP2PKHScript(script: Hex): boolean { try { - payments.p2pkh({ output: script }) + payments.p2pkh({ output: script.toBuffer() }) return true } catch (err) { return false @@ -19,9 +20,9 @@ function isP2PKHScript(script: Buffer): boolean { * @param script The script to be checked. * @returns True if the script is P2WPKH, false otherwise. */ -function isP2WPKHScript(script: Buffer): boolean { +function isP2WPKHScript(script: Hex): boolean { try { - payments.p2wpkh({ output: script }) + payments.p2wpkh({ output: script.toBuffer() }) return true } catch (err) { return false @@ -33,9 +34,9 @@ function isP2WPKHScript(script: Buffer): boolean { * @param script The script to be checked. * @returns True if the script is P2SH, false otherwise. */ -function isP2SHScript(script: Buffer): boolean { +function isP2SHScript(script: Hex): boolean { try { - payments.p2sh({ output: script }) + payments.p2sh({ output: script.toBuffer() }) return true } catch (err) { return false @@ -47,9 +48,9 @@ function isP2SHScript(script: Buffer): boolean { * @param script The script to be checked. * @returns True if the script is P2WSH, false otherwise. */ -function isP2WSHScript(script: Buffer): boolean { +function isP2WSHScript(script: Hex): boolean { try { - payments.p2wsh({ output: script }) + payments.p2wsh({ output: script.toBuffer() }) return true } catch (err) { return false diff --git a/typescript/src/services/deposits/funding.ts b/typescript/src/services/deposits/funding.ts index c520f5e83..a3f9d8f7e 100644 --- a/typescript/src/services/deposits/funding.ts +++ b/typescript/src/services/deposits/funding.ts @@ -92,7 +92,7 @@ export class DepositFunding { // TODO: Add support for other utxo types along with unit tests for the // given type. - if (BitcoinScriptUtils.isP2WPKHScript(previousOutputScript)) { + if (BitcoinScriptUtils.isP2WPKHScript(Hex.from(previousOutputScript))) { psbt.addInput({ hash: utxo.transactionHash.reverse().toBuffer(), index: utxo.outputIndex, diff --git a/typescript/src/services/deposits/refund.ts b/typescript/src/services/deposits/refund.ts index 81d331704..219b1f3ee 100644 --- a/typescript/src/services/deposits/refund.ts +++ b/typescript/src/services/deposits/refund.ts @@ -154,7 +154,7 @@ export class DepositRefund { utxo.outputIndex ] const previousOutputValue = previousOutput.value - const previousOutputScript = previousOutput.script + const previousOutputScript = Hex.from(previousOutput.script) if (BitcoinScriptUtils.isP2SHScript(previousOutputScript)) { // P2SH deposit UTXO diff --git a/typescript/src/services/maintenance/wallet-tx.ts b/typescript/src/services/maintenance/wallet-tx.ts index b0306cdff..4756b8e59 100644 --- a/typescript/src/services/maintenance/wallet-tx.ts +++ b/typescript/src/services/maintenance/wallet-tx.ts @@ -249,7 +249,7 @@ class DepositSweep { utxo.outputIndex ] const previousOutputValue = previousOutput.value - const previousOutputScript = previousOutput.script + const previousOutputScript = Hex.from(previousOutput.script) const deposit = deposits[depositIndex] @@ -309,10 +309,13 @@ class DepositSweep { previousOutput: TxOutput, walletKeyPair: Signer ) { + const previousOutputScript = Hex.from(previousOutput.script) + const previousOutputValue = previousOutput.value + if ( !this.canSpendOutput( Hex.from(walletKeyPair.publicKey), - previousOutput.script + previousOutputScript ) ) { throw new Error("UTXO does not belong to the wallet") @@ -320,11 +323,11 @@ class DepositSweep { const sigHashType = Transaction.SIGHASH_ALL - if (BitcoinScriptUtils.isP2PKHScript(previousOutput.script)) { + if (BitcoinScriptUtils.isP2PKHScript(previousOutputScript)) { // P2PKH const sigHash = transaction.hashForSignature( inputIndex, - previousOutput.script, + previousOutputScript.toBuffer(), sigHashType ) @@ -339,16 +342,17 @@ class DepositSweep { }).input! transaction.ins[inputIndex].script = scriptSig - } else if (BitcoinScriptUtils.isP2WPKHScript(previousOutput.script)) { + } else if (BitcoinScriptUtils.isP2WPKHScript(previousOutputScript)) { // P2WPKH - const publicKeyHash = payments.p2wpkh({ output: previousOutput.script }) - .hash! + const publicKeyHash = payments.p2wpkh({ + output: previousOutputScript.toBuffer(), + }).hash! const p2pkhScript = payments.p2pkh({ hash: publicKeyHash }).output! const sigHash = transaction.hashForWitnessV0( inputIndex, p2pkhScript, - previousOutput.value, + previousOutputValue, sigHashType ) @@ -496,10 +500,14 @@ class DepositSweep { * @returns True if the provided output script matches the P2PKH or P2WPKH * output scripts derived from the given public key. False otherwise. */ - private canSpendOutput(publicKey: Hex, outputScript: Buffer): boolean { + private canSpendOutput(publicKey: Hex, outputScript: Hex): boolean { const pubkeyBuffer = publicKey.toBuffer() - const p2pkhOutput = payments.p2pkh({ pubkey: pubkeyBuffer }).output! - const p2wpkhOutput = payments.p2wpkh({ pubkey: pubkeyBuffer }).output! + const p2pkhOutput = Hex.from( + payments.p2pkh({ pubkey: pubkeyBuffer }).output! + ) + const p2wpkhOutput = Hex.from( + payments.p2wpkh({ pubkey: pubkeyBuffer }).output! + ) return outputScript.equals(p2pkhOutput) || outputScript.equals(p2wpkhOutput) } @@ -661,7 +669,7 @@ class Redemption { const previousOutput = Transaction.fromHex(mainUtxo.transactionHex).outs[ mainUtxo.outputIndex ] - const previousOutputScript = previousOutput.script + const previousOutputScript = Hex.from(previousOutput.script) const previousOutputValue = previousOutput.value if (BitcoinScriptUtils.isP2PKHScript(previousOutputScript)) { @@ -675,7 +683,7 @@ class Redemption { hash: mainUtxo.transactionHash.reverse().toBuffer(), index: mainUtxo.outputIndex, witnessUtxo: { - script: previousOutputScript, + script: previousOutputScript.toBuffer(), value: previousOutputValue, }, }) diff --git a/typescript/test/lib/bitcoin.test.ts b/typescript/test/lib/bitcoin.test.ts index cdb706947..fde3ac882 100644 --- a/typescript/test/lib/bitcoin.test.ts +++ b/typescript/test/lib/bitcoin.test.ts @@ -821,33 +821,27 @@ describe("Bitcoin", () => { const testData = [ { testFunction: isP2PKHScript, - validScript: Buffer.from( - "76a9148db50eb52063ea9d98b3eac91489a90f738986f688ac", - "hex" + validScript: Hex.from( + "76a9148db50eb52063ea9d98b3eac91489a90f738986f688ac" ), name: "P2PKH", }, { testFunction: isP2WPKHScript, - validScript: Buffer.from( - "00148db50eb52063ea9d98b3eac91489a90f738986f6", - "hex" - ), + validScript: Hex.from("00148db50eb52063ea9d98b3eac91489a90f738986f6"), name: "P2WPKH", }, { testFunction: isP2SHScript, - validScript: Buffer.from( - "a914a9a5f97d5d3c4687a52e90718168270005b369c487", - "hex" + validScript: Hex.from( + "a914a9a5f97d5d3c4687a52e90718168270005b369c487" ), name: "P2SH", }, { testFunction: isP2WSHScript, - validScript: Buffer.from( - "0020b1f83e226979dc9fe74e87f6d303dbb08a27a1c7ce91664033f34c7f2d214cd7", - "hex" + validScript: Hex.from( + "0020b1f83e226979dc9fe74e87f6d303dbb08a27a1c7ce91664033f34c7f2d214cd7" ), name: "P2WSH", }, From d5a2cf5dab1af03093dac0a1198fcf8491cd98ca Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Fri, 13 Oct 2023 13:58:47 +0200 Subject: [PATCH 06/22] Updated function docstring --- typescript/src/lib/bitcoin/ecdsa-key.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/typescript/src/lib/bitcoin/ecdsa-key.ts b/typescript/src/lib/bitcoin/ecdsa-key.ts index f7b845840..3dd1507b8 100644 --- a/typescript/src/lib/bitcoin/ecdsa-key.ts +++ b/typescript/src/lib/bitcoin/ecdsa-key.ts @@ -61,9 +61,10 @@ export const BitcoinPublicKeyUtils = { /** * Creates a Bitcoin key pair based on the given private key. - * @param privateKey Private key that should be used to create the key pair. + * @param privateKey Private key in the WIF format that should be used to create + * the key pair. * @param bitcoinNetwork Bitcoin network the given key pair is relevant for. - * @returns Bitcoin key ring. + * @returns Bitcoin key pair. */ function createKeyPair( privateKey: string, From 5122eaaeac8d4b6c2f0369a2fc2e0b1f7993a9e4 Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Fri, 13 Oct 2023 14:09:58 +0200 Subject: [PATCH 07/22] Minor function refactor --- typescript/src/lib/bitcoin/address.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/typescript/src/lib/bitcoin/address.ts b/typescript/src/lib/bitcoin/address.ts index 628ab6a6c..fb41e8221 100644 --- a/typescript/src/lib/bitcoin/address.ts +++ b/typescript/src/lib/bitcoin/address.ts @@ -63,16 +63,15 @@ function addressToPublicKeyHash( try { // Try extracting hash from P2PKH address. - const hash = payments.p2pkh({ address: address, network }).hash! - return Hex.from(hash) + return Hex.from(payments.p2pkh({ address: address, network }).hash!) } catch (err) {} try { // Try extracting hash from P2WPKH address. - const hash = payments.p2wpkh({ address: address, network }).hash! - return Hex.from(hash) + return Hex.from(payments.p2wpkh({ address: address, network }).hash!) } catch (err) {} + // If neither of them succeeded, throw an error. throw new Error("Address must be P2PKH or P2WPKH valid for given network") } From aad0b94f0ecde2f91399c64ffd96d7fb263306f7 Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Mon, 16 Oct 2023 14:46:48 +0200 Subject: [PATCH 08/22] Used Hex as argument in Bridge functions --- typescript/src/lib/contracts/bridge.ts | 24 ++++---- typescript/src/lib/ethereum/bridge.ts | 55 +++++++++---------- .../src/services/deposits/deposits-service.ts | 6 +- typescript/src/services/maintenance/spv.ts | 3 +- .../src/services/maintenance/wallet-tx.ts | 4 +- .../redemptions/redemptions-service.ts | 10 ++-- typescript/test/lib/ethereum.test.ts | 26 ++++++--- typescript/test/utils/mock-bridge.ts | 34 ++++++------ 8 files changed, 83 insertions(+), 79 deletions(-) diff --git a/typescript/src/lib/contracts/bridge.ts b/typescript/src/lib/contracts/bridge.ts index 0e26c1587..62afd55ec 100644 --- a/typescript/src/lib/contracts/bridge.ts +++ b/typescript/src/lib/contracts/bridge.ts @@ -76,14 +76,14 @@ export interface Bridge { * @param mainUtxo - The main UTXO of the wallet. Must match the main UTXO * held by the on-chain contract. * @param redeemerOutputScript - The output script that the redeemed funds will - * be locked to. Must be un-prefixed and not prepended with length. + * be locked to. Must not be prepended with length. * @param amount - The amount to be redeemed in satoshis. * @returns Empty promise. */ requestRedemption( - walletPublicKey: string, + walletPublicKey: Hex, mainUtxo: BitcoinUtxo, - redeemerOutputScript: string, + redeemerOutputScript: Hex, amount: BigNumber ): Promise @@ -99,7 +99,7 @@ export interface Bridge { redemptionTx: BitcoinRawTxVectors, redemptionProof: BitcoinSpvProof, mainUtxo: BitcoinUtxo, - walletPublicKey: string + walletPublicKey: Hex ): Promise /** @@ -116,13 +116,12 @@ export interface Bridge { * targeted to. Must be in the compressed form (33 bytes long with 02 * or 03 prefix). * @param redeemerOutputScript The redeemer output script the redeemed funds - * are supposed to be locked on. Must be un-prefixed and not prepended - * with length. + * are supposed to be locked on. Must not be prepended with length. * @returns Promise with the pending redemption. */ pendingRedemptions( - walletPublicKey: string, - redeemerOutputScript: string + walletPublicKey: Hex, + redeemerOutputScript: Hex ): Promise /** @@ -131,13 +130,12 @@ export interface Bridge { * targeted to. Must be in the compressed form (33 bytes long with 02 * or 03 prefix). * @param redeemerOutputScript The redeemer output script the redeemed funds - * are supposed to be locked on. Must be un-prefixed and not prepended - * with length. + * are supposed to be locked on. Must not be prepended with length. * @returns Promise with the pending redemption. */ timedOutRedemptions( - walletPublicKey: string, - redeemerOutputScript: string + walletPublicKey: Hex, + redeemerOutputScript: Hex ): Promise /** @@ -146,7 +144,7 @@ export interface Bridge { * public key. If there is no active wallet at the moment, undefined * is returned. */ - activeWalletPublicKey(): Promise + activeWalletPublicKey(): Promise /** * Get emitted NewWalletRegisteredEvent events. diff --git a/typescript/src/lib/ethereum/bridge.ts b/typescript/src/lib/ethereum/bridge.ts index f3e4ce5ab..80aa69c90 100644 --- a/typescript/src/lib/ethereum/bridge.ts +++ b/typescript/src/lib/ethereum/bridge.ts @@ -129,11 +129,11 @@ export class EthereumBridge * @see {Bridge#pendingRedemptions} */ async pendingRedemptions( - walletPublicKey: string, - redeemerOutputScript: string + walletPublicKey: Hex, + redeemerOutputScript: Hex ): Promise { const redemptionKey = EthereumBridge.buildRedemptionKey( - BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)).toString(), + BitcoinHashUtils.computeHash160(walletPublicKey), redeemerOutputScript ) @@ -152,11 +152,11 @@ export class EthereumBridge * @see {Bridge#timedOutRedemptions} */ async timedOutRedemptions( - walletPublicKey: string, - redeemerOutputScript: string + walletPublicKey: Hex, + redeemerOutputScript: Hex ): Promise { const redemptionKey = EthereumBridge.buildRedemptionKey( - BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)).toString(), + BitcoinHashUtils.computeHash160(walletPublicKey), redeemerOutputScript ) @@ -173,19 +173,18 @@ export class EthereumBridge /** * Builds a redemption key required to refer a redemption request. * @param walletPublicKeyHash The wallet public key hash that identifies the - * pending redemption (along with the redeemer output script). Must be - * unprefixed. + * pending redemption (along with the redeemer output script). * @param redeemerOutputScript The redeemer output script that identifies the - * pending redemption (along with the wallet public key hash). Must be - * un-prefixed and not prepended with length. + * pending redemption (along with the wallet public key hash). Must not + * be prepended with length. * @returns The redemption key. */ static buildRedemptionKey( - walletPublicKeyHash: string, - redeemerOutputScript: string + walletPublicKeyHash: Hex, + redeemerOutputScript: Hex ): string { // Convert the output script to raw bytes buffer. - const rawRedeemerOutputScript = Buffer.from(redeemerOutputScript, "hex") + const rawRedeemerOutputScript = redeemerOutputScript.toBuffer() // Prefix the output script bytes buffer with 0x and its own length. const prefixedRawRedeemerOutputScript = `0x${Buffer.concat([ Buffer.from([rawRedeemerOutputScript.length]), @@ -206,17 +205,17 @@ export class EthereumBridge * Parses a redemption request using data fetched from the on-chain contract. * @param request Data of the request. * @param redeemerOutputScript The redeemer output script that identifies the - * pending redemption (along with the wallet public key hash). Must be - * un-prefixed and not prepended with length. + * pending redemption (along with the wallet public key hash). Must not + * be prepended with length. * @returns Parsed redemption request. */ private parseRedemptionRequest( request: RedemptionRequestTypechain, - redeemerOutputScript: string + redeemerOutputScript: Hex ): RedemptionRequest { return { redeemer: EthereumAddress.from(request.redeemer), - redeemerOutputScript: redeemerOutputScript, + redeemerOutputScript: redeemerOutputScript.toString(), requestedAmount: BigNumber.from(request.requestedAmount), treasuryFee: BigNumber.from(request.treasuryFee), txMaxFee: BigNumber.from(request.txMaxFee), @@ -329,14 +328,13 @@ export class EthereumBridge * @see {Bridge#requestRedemption} */ async requestRedemption( - walletPublicKey: string, + walletPublicKey: Hex, mainUtxo: BitcoinUtxo, - redeemerOutputScript: string, + redeemerOutputScript: Hex, amount: BigNumber ): Promise { - const walletPublicKeyHash = BitcoinHashUtils.computeHash160( - Hex.from(walletPublicKey) - ).toPrefixedString() + const walletPublicKeyHash = + BitcoinHashUtils.computeHash160(walletPublicKey).toPrefixedString() const mainUtxoParam = { // The Ethereum Bridge expects this hash to be in the Bitcoin internal @@ -347,7 +345,7 @@ export class EthereumBridge } // Convert the output script to raw bytes buffer. - const rawRedeemerOutputScript = Buffer.from(redeemerOutputScript, "hex") + const rawRedeemerOutputScript = redeemerOutputScript.toBuffer() // Prefix the output script bytes buffer with 0x and its own length. const prefixedRawRedeemerOutputScript = `0x${Buffer.concat([ Buffer.from([rawRedeemerOutputScript.length]), @@ -375,7 +373,7 @@ export class EthereumBridge redemptionTx: BitcoinRawTxVectors, redemptionProof: BitcoinSpvProof, mainUtxo: BitcoinUtxo, - walletPublicKey: string + walletPublicKey: Hex ): Promise { const redemptionTxParam = { version: `0x${redemptionTx.version}`, @@ -398,9 +396,8 @@ export class EthereumBridge txOutputValue: mainUtxo.value, } - const walletPublicKeyHash = BitcoinHashUtils.computeHash160( - Hex.from(walletPublicKey) - ).toPrefixedString() + const walletPublicKeyHash = + BitcoinHashUtils.computeHash160(walletPublicKey).toPrefixedString() await EthersTransactionUtils.sendWithRetry( async () => { @@ -484,7 +481,7 @@ export class EthereumBridge /** * @see {Bridge#activeWalletPublicKey} */ - async activeWalletPublicKey(): Promise { + async activeWalletPublicKey(): Promise { const activeWalletPublicKeyHash: string = await backoffRetrier( this._totalRetryAttempts )(async () => { @@ -502,7 +499,7 @@ export class EthereumBridge Hex.from(activeWalletPublicKeyHash) ) - return walletPublicKey.toString() + return walletPublicKey } private async getWalletCompressedPublicKey(ecdsaWalletID: Hex): Promise { diff --git a/typescript/src/services/deposits/deposits-service.ts b/typescript/src/services/deposits/deposits-service.ts index b8fba8d21..091101898 100644 --- a/typescript/src/services/deposits/deposits-service.ts +++ b/typescript/src/services/deposits/deposits-service.ts @@ -10,7 +10,6 @@ import { BitcoinLocktimeUtils, } from "../../lib/bitcoin" import { Deposit } from "./deposit" -import { Hex } from "../../lib/utils" import * as crypto from "crypto" /** @@ -76,9 +75,8 @@ export class DepositsService { throw new Error("Could not get active wallet public key") } - const walletPublicKeyHash = BitcoinHashUtils.computeHash160( - Hex.from(walletPublicKey) - ).toString() + const walletPublicKeyHash = + BitcoinHashUtils.computeHash160(walletPublicKey).toString() const bitcoinNetwork = await this.bitcoinClient.getNetwork() diff --git a/typescript/src/services/maintenance/spv.ts b/typescript/src/services/maintenance/spv.ts index c00d690db..8f546330e 100644 --- a/typescript/src/services/maintenance/spv.ts +++ b/typescript/src/services/maintenance/spv.ts @@ -5,6 +5,7 @@ import { BitcoinUtxo, extractBitcoinRawTxVectors, } from "../../lib/bitcoin" +import { Hex } from "../../lib/utils" import { ChainIdentifier, TBTCContracts } from "../../lib/contracts" export class Spv { @@ -84,7 +85,7 @@ export class Spv { rawTransactionVectors, proof, mainUtxo, - walletPublicKey + Hex.from(walletPublicKey) ) } } diff --git a/typescript/src/services/maintenance/wallet-tx.ts b/typescript/src/services/maintenance/wallet-tx.ts index 4756b8e59..cccf05f94 100644 --- a/typescript/src/services/maintenance/wallet-tx.ts +++ b/typescript/src/services/maintenance/wallet-tx.ts @@ -586,8 +586,8 @@ class Redemption { for (const redeemerOutputScript of redeemerOutputScripts) { const redemptionRequest = await this.tbtcContracts.bridge.pendingRedemptions( - walletPublicKey, - redeemerOutputScript + Hex.from(walletPublicKey), + Hex.from(redeemerOutputScript) ) if (redemptionRequest.requestedAt == 0) { diff --git a/typescript/src/services/redemptions/redemptions-service.ts b/typescript/src/services/redemptions/redemptions-service.ts index a6bc302f1..5a1a304ae 100644 --- a/typescript/src/services/redemptions/redemptions-service.ts +++ b/typescript/src/services/redemptions/redemptions-service.ts @@ -140,8 +140,8 @@ export class RedemptionsService { const pendingRedemption = await this.tbtcContracts.bridge.pendingRedemptions( - walletPublicKey.toString(), - redeemerOutputScript + walletPublicKey, + Hex.from(redeemerOutputScript) ) if (pendingRedemption.requestedAt != 0) { @@ -338,21 +338,21 @@ export class RedemptionsService { const redeemerOutputScript = BitcoinAddressConverter.addressToOutputScript( bitcoinRedeemerAddress, bitcoinNetwork - ).toString() + ) let redemptionRequest: RedemptionRequest | undefined = undefined switch (type) { case "pending": { redemptionRequest = await this.tbtcContracts.bridge.pendingRedemptions( - walletPublicKey, + Hex.from(walletPublicKey), redeemerOutputScript ) break } case "timedOut": { redemptionRequest = await this.tbtcContracts.bridge.timedOutRedemptions( - walletPublicKey, + Hex.from(walletPublicKey), redeemerOutputScript ) break diff --git a/typescript/test/lib/ethereum.test.ts b/typescript/test/lib/ethereum.test.ts index 11b4086d6..dfd558362 100644 --- a/typescript/test/lib/ethereum.test.ts +++ b/typescript/test/lib/ethereum.test.ts @@ -74,8 +74,10 @@ describe("Ethereum", () => { it("should return the pending redemption", async () => { expect( await bridgeHandle.pendingRedemptions( - "03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9", - "a9143ec459d0f3c29286ae5df5fcc421e2786024277e87" + Hex.from( + "03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9" + ), + Hex.from("a9143ec459d0f3c29286ae5df5fcc421e2786024277e87") ) ).to.be.eql({ redeemer: EthereumAddress.from( @@ -113,8 +115,10 @@ describe("Ethereum", () => { it("should return the timed-out redemption", async () => { expect( await bridgeHandle.timedOutRedemptions( - "03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9", - "a9143ec459d0f3c29286ae5df5fcc421e2786024277e87" + Hex.from( + "03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9" + ), + Hex.from("a9143ec459d0f3c29286ae5df5fcc421e2786024277e87") ) ).to.be.eql({ redeemer: EthereumAddress.from( @@ -244,7 +248,9 @@ describe("Ethereum", () => { await bridgeContract.mock.requestRedemption.returns() await bridgeHandle.requestRedemption( - "03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9", + Hex.from( + "03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9" + ), { transactionHash: BitcoinTxHash.from( "f8eaf242a55ea15e602f9f990e33f67f99dfbe25d1802bbde63cc1caabf99668" @@ -252,7 +258,7 @@ describe("Ethereum", () => { outputIndex: 8, value: BigNumber.from(9999), }, - "a9143ec459d0f3c29286ae5df5fcc421e2786024277e87", + Hex.from("a9143ec459d0f3c29286ae5df5fcc421e2786024277e87"), BigNumber.from(10000) ) }) @@ -295,7 +301,9 @@ describe("Ethereum", () => { outputIndex: 8, value: BigNumber.from(9999), }, - "03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9" + Hex.from( + "03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9" + ) ) }) @@ -441,7 +449,9 @@ describe("Ethereum", () => { }) it("should return the active wallet's public key", async () => { - expect(await bridgeHandle.activeWalletPublicKey()).to.be.equal( + expect( + (await bridgeHandle.activeWalletPublicKey())?.toString() + ).to.be.equal( "03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9" ) }) diff --git a/typescript/test/utils/mock-bridge.ts b/typescript/test/utils/mock-bridge.ts index fe6a8a27c..0a7c143de 100644 --- a/typescript/test/utils/mock-bridge.ts +++ b/typescript/test/utils/mock-bridge.ts @@ -70,7 +70,7 @@ export class MockBridge implements Bridge { private _requestRedemptionLog: RequestRedemptionLogEntry[] = [] private _redemptionProofLog: RedemptionProofLogEntry[] = [] private _deposits = new Map() - private _activeWalletPublicKey: string | undefined + private _activeWalletPublicKey: Hex | undefined private _newWalletRegisteredEvents: NewWalletRegisteredEvent[] = [] private _newWalletRegisteredEventsLog: NewWalletRegisteredEventsLog[] = [] private _wallets = new Map() @@ -120,7 +120,7 @@ export class MockBridge implements Bridge { this._deposits = value } - setActiveWalletPublicKey(activeWalletPublicKey: string) { + setActiveWalletPublicKey(activeWalletPublicKey: Hex) { this._activeWalletPublicKey = activeWalletPublicKey } @@ -223,13 +223,13 @@ export class MockBridge implements Bridge { redemptionTx: BitcoinRawTxVectors, redemptionProof: BitcoinSpvProof, mainUtxo: BitcoinUtxo, - walletPublicKey: string + walletPublicKey: Hex ): Promise { this._redemptionProofLog.push({ redemptionTx, redemptionProof, mainUtxo, - walletPublicKey, + walletPublicKey: walletPublicKey.toString(), }) return new Promise((resolve, _) => { resolve() @@ -237,15 +237,15 @@ export class MockBridge implements Bridge { } requestRedemption( - walletPublicKey: string, + walletPublicKey: Hex, mainUtxo: BitcoinUtxo, - redeemerOutputScript: string, + redeemerOutputScript: Hex, amount: BigNumber ) { this._requestRedemptionLog.push({ - walletPublicKey, + walletPublicKey: walletPublicKey.toString(), mainUtxo, - redeemerOutputScript, + redeemerOutputScript: redeemerOutputScript.toString(), amount, }) return new Promise((resolve, _) => { @@ -260,14 +260,14 @@ export class MockBridge implements Bridge { } pendingRedemptions( - walletPublicKey: string, - redeemerOutputScript: string + walletPublicKey: Hex, + redeemerOutputScript: Hex ): Promise { return new Promise((resolve, _) => { resolve( this.redemptions( - walletPublicKey, - redeemerOutputScript, + walletPublicKey.toString(), + redeemerOutputScript.toString(), this._pendingRedemptions ) ) @@ -275,14 +275,14 @@ export class MockBridge implements Bridge { } timedOutRedemptions( - walletPublicKey: string, - redeemerOutputScript: string + walletPublicKey: Hex, + redeemerOutputScript: Hex ): Promise { return new Promise((resolve, _) => { resolve( this.redemptions( - walletPublicKey, - redeemerOutputScript, + walletPublicKey.toString(), + redeemerOutputScript.toString(), this._timedOutRedemptions ) ) @@ -335,7 +335,7 @@ export class MockBridge implements Bridge { ) } - async activeWalletPublicKey(): Promise { + async activeWalletPublicKey(): Promise { return this._activeWalletPublicKey } From 023170f56d6687be6b1b686bed97a8a084f25032 Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Mon, 16 Oct 2023 15:53:27 +0200 Subject: [PATCH 09/22] Used Hex in DepositReceipt --- typescript/src/lib/bitcoin/tx.ts | 6 +- typescript/src/lib/contracts/bridge.ts | 31 +++++----- typescript/src/lib/ethereum/bridge.ts | 8 +-- typescript/src/services/deposits/deposit.ts | 8 +-- .../src/services/deposits/deposits-service.ts | 8 +-- typescript/src/services/deposits/refund.ts | 12 ++-- .../src/services/maintenance/wallet-tx.ts | 5 +- typescript/test/data/deposit-refund.ts | 31 +++++++--- typescript/test/data/deposit-sweep.ts | 60 +++++++++++++------ typescript/test/lib/bitcoin.test.ts | 20 +++---- typescript/test/lib/ethereum.test.ts | 12 ++-- typescript/test/services/deposits.test.ts | 19 ++++-- 12 files changed, 133 insertions(+), 87 deletions(-) diff --git a/typescript/src/lib/bitcoin/tx.ts b/typescript/src/lib/bitcoin/tx.ts index f068500b1..a61d1f37e 100644 --- a/typescript/src/lib/bitcoin/tx.ts +++ b/typescript/src/lib/bitcoin/tx.ts @@ -207,12 +207,12 @@ function locktimeToNumber(locktimeLE: Buffer | string): number { * @param locktimeStartedAt - Unix timestamp in seconds determining the moment * of the locktime start. * @param locktimeDuration Locktime duration in seconds. - * @returns A 4-byte little-endian locktime as an un-prefixed hex string. + * @returns A 4-byte little-endian locktime. */ function calculateLocktime( locktimeStartedAt: number, locktimeDuration: number -): string { +): Hex { // Locktime is a Unix timestamp in seconds, computed as locktime start // timestamp plus locktime duration. const locktime = BigNumber.from(locktimeStartedAt + locktimeDuration) @@ -225,7 +225,7 @@ function calculateLocktime( // Bitcoin locktime is interpreted as little-endian integer, so we must // adhere to that convention by converting the locktime accordingly. - return locktimeHex.reverse().toString() + return locktimeHex.reverse() } /** diff --git a/typescript/src/lib/contracts/bridge.ts b/typescript/src/lib/contracts/bridge.ts index 62afd55ec..8742b6cf3 100644 --- a/typescript/src/lib/contracts/bridge.ts +++ b/typescript/src/lib/contracts/bridge.ts @@ -190,31 +190,30 @@ export interface DepositReceipt { depositor: ChainIdentifier /** - * An 8-byte blinding factor as an un-prefixed hex string. Must be unique - * for the given depositor, wallet public key and refund public key. + * An 8-byte blinding factor. Must be unique for the given depositor, wallet + * public key and refund public key. */ - blindingFactor: string + blindingFactor: Hex /** - * Public key hash of the wallet that is meant to receive the deposit. Must - * be an unprefixed hex string (without 0x prefix). + * Public key hash of the wallet that is meant to receive the deposit. * - * You can use `computeHash160` function to get the hash from a plain text public key. + * You can use `computeHash160` function to get the hash from a public key. */ - walletPublicKeyHash: string + walletPublicKeyHash: Hex /** * Public key hash that is meant to be used during deposit refund after the - * locktime passes. Must be an unprefixed hex string (without 0x prefix). + * locktime passes. * - * You can use `computeHash160` function to get the hash from a plain text public key. + * You can use `computeHash160` function to get the hash from a public key. */ - refundPublicKeyHash: string + refundPublicKeyHash: Hex /** - * A 4-byte little-endian refund locktime as an un-prefixed hex string. + * A 4-byte little-endian refund locktime. */ - refundLocktime: string + refundLocktime: Hex } // eslint-disable-next-line valid-jsdoc @@ -225,18 +224,18 @@ export interface DepositReceipt { * validity is chain-specific. This parameter must be validated outside. */ export function validateDepositReceipt(receipt: DepositReceipt) { - if (receipt.blindingFactor.length != 16) { + if (receipt.blindingFactor.toString().length != 16) { throw new Error("Blinding factor must be an 8-byte number") } - if (receipt.walletPublicKeyHash.length != 40) { + if (receipt.walletPublicKeyHash.toString().length != 40) { throw new Error("Invalid wallet public key hash") } - if (receipt.refundPublicKeyHash.length != 40) { + if (receipt.refundPublicKeyHash.toString().length != 40) { throw new Error("Invalid refund public key hash") } - if (receipt.refundLocktime.length != 8) { + if (receipt.refundLocktime.toString().length != 8) { throw new Error("Refund locktime must be a 4-byte number") } } diff --git a/typescript/src/lib/ethereum/bridge.ts b/typescript/src/lib/ethereum/bridge.ts index 80aa69c90..924523148 100644 --- a/typescript/src/lib/ethereum/bridge.ts +++ b/typescript/src/lib/ethereum/bridge.ts @@ -112,10 +112,10 @@ export class EthereumBridge ).toNumber(), depositor: EthereumAddress.from(event.args!.depositor), amount: BigNumber.from(event.args!.amount), - blindingFactor: Hex.from(event.args!.blindingFactor).toString(), - walletPublicKeyHash: Hex.from(event.args!.walletPubKeyHash).toString(), - refundPublicKeyHash: Hex.from(event.args!.refundPubKeyHash).toString(), - refundLocktime: Hex.from(event.args!.refundLocktime).toString(), + blindingFactor: Hex.from(event.args!.blindingFactor), + walletPublicKeyHash: Hex.from(event.args!.walletPubKeyHash), + refundPublicKeyHash: Hex.from(event.args!.refundPubKeyHash), + refundLocktime: Hex.from(event.args!.refundLocktime), vault: event.args!.vault === constants.AddressZero ? undefined diff --git a/typescript/src/services/deposits/deposit.ts b/typescript/src/services/deposits/deposit.ts index fcc7d869a..ab066d287 100644 --- a/typescript/src/services/deposits/deposit.ts +++ b/typescript/src/services/deposits/deposit.ts @@ -198,20 +198,20 @@ export class DepositScript { // All HEXes pushed to the script must be un-prefixed chunks.push(Buffer.from(this.receipt.depositor.identifierHex, "hex")) chunks.push(opcodes.OP_DROP) - chunks.push(Buffer.from(this.receipt.blindingFactor, "hex")) + chunks.push(this.receipt.blindingFactor.toBuffer()) chunks.push(opcodes.OP_DROP) chunks.push(opcodes.OP_DUP) chunks.push(opcodes.OP_HASH160) - chunks.push(Buffer.from(this.receipt.walletPublicKeyHash, "hex")) + chunks.push(this.receipt.walletPublicKeyHash.toBuffer()) chunks.push(opcodes.OP_EQUAL) chunks.push(opcodes.OP_IF) chunks.push(opcodes.OP_CHECKSIG) chunks.push(opcodes.OP_ELSE) chunks.push(opcodes.OP_DUP) chunks.push(opcodes.OP_HASH160) - chunks.push(Buffer.from(this.receipt.refundPublicKeyHash, "hex")) + chunks.push(this.receipt.refundPublicKeyHash.toBuffer()) chunks.push(opcodes.OP_EQUALVERIFY) - chunks.push(Buffer.from(this.receipt.refundLocktime, "hex")) + chunks.push(this.receipt.refundLocktime.toBuffer()) chunks.push(opcodes.OP_CHECKLOCKTIMEVERIFY) chunks.push(opcodes.OP_DROP) chunks.push(opcodes.OP_CHECKSIG) diff --git a/typescript/src/services/deposits/deposits-service.ts b/typescript/src/services/deposits/deposits-service.ts index 091101898..f123b6876 100644 --- a/typescript/src/services/deposits/deposits-service.ts +++ b/typescript/src/services/deposits/deposits-service.ts @@ -9,6 +9,7 @@ import { BitcoinHashUtils, BitcoinLocktimeUtils, } from "../../lib/bitcoin" +import { Hex } from "../../lib/utils" import { Deposit } from "./deposit" import * as crypto from "crypto" @@ -66,7 +67,7 @@ export class DepositsService { ) } - const blindingFactor = crypto.randomBytes(8).toString("hex") + const blindingFactor = Hex.from(crypto.randomBytes(8)) const walletPublicKey = await this.tbtcContracts.bridge.activeWalletPublicKey() @@ -75,8 +76,7 @@ export class DepositsService { throw new Error("Could not get active wallet public key") } - const walletPublicKeyHash = - BitcoinHashUtils.computeHash160(walletPublicKey).toString() + const walletPublicKeyHash = BitcoinHashUtils.computeHash160(walletPublicKey) const bitcoinNetwork = await this.bitcoinClient.getNetwork() @@ -86,7 +86,7 @@ export class DepositsService { const refundPublicKeyHash = BitcoinAddressConverter.addressToPublicKeyHash( bitcoinRecoveryAddress, bitcoinNetwork - ).toString() + ) const currentTimestamp = Math.floor(new Date().getTime() / 1000) diff --git a/typescript/src/services/deposits/refund.ts b/typescript/src/services/deposits/refund.ts index 219b1f3ee..edb232594 100644 --- a/typescript/src/services/deposits/refund.ts +++ b/typescript/src/services/deposits/refund.ts @@ -192,8 +192,9 @@ export class DepositRefund { const refunderPublicKey = refunderKeyPair.publicKey.toString("hex") if ( - BitcoinHashUtils.computeHash160(Hex.from(refunderPublicKey)).toString() != - this.script.receipt.refundPublicKeyHash + !BitcoinHashUtils.computeHash160(Hex.from(refunderPublicKey)).equals( + this.script.receipt.refundPublicKeyHash + ) ) { throw new Error( "Refund public key does not correspond to wallet private key" @@ -289,10 +290,7 @@ export class DepositRefund { * @param locktime - Locktime as a little endian hexstring. * @returns Locktime as a Unix timestamp. */ -function locktimeToUnixTimestamp(locktime: string): number { - const bigEndianLocktime = Buffer.from(locktime, "hex") - .reverse() - .toString("hex") - +function locktimeToUnixTimestamp(locktime: Hex): number { + const bigEndianLocktime = locktime.reverse().toString() return parseInt(bigEndianLocktime, 16) } diff --git a/typescript/src/services/maintenance/wallet-tx.ts b/typescript/src/services/maintenance/wallet-tx.ts index cccf05f94..4e2ae267a 100644 --- a/typescript/src/services/maintenance/wallet-tx.ts +++ b/typescript/src/services/maintenance/wallet-tx.ts @@ -473,8 +473,9 @@ class DepositSweep { const walletPublicKey = walletKeyPair.publicKey.toString("hex") if ( - BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)).toString() != - deposit.walletPublicKeyHash + !BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)).equals( + deposit.walletPublicKeyHash + ) ) { throw new Error( "Wallet public key does not correspond to wallet private key" diff --git a/typescript/test/data/deposit-refund.ts b/typescript/test/data/deposit-refund.ts index ff0782a2a..45dfb3699 100644 --- a/typescript/test/data/deposit-refund.ts +++ b/typescript/test/data/deposit-refund.ts @@ -1,4 +1,5 @@ import { BigNumber } from "ethers" +import { Hex } from "../../src/lib/utils" import { BitcoinRawTx, BitcoinUtxo, @@ -59,9 +60,13 @@ export const depositRefundOfWitnessDepositAndWitnessRefunderAddress: DepositRefu depositor: EthereumAddress.from( "934b98637ca318a4d6e7ca6ffd1690b8e77df637" ), - walletPublicKeyHash: "8db50eb52063ea9d98b3eac91489a90f738986f6", - refundPublicKeyHash: "1b67f27537c7b30a23d8ccefb96a4cacfc72d9a1", - blindingFactor: "f9f0c90d00039523", + walletPublicKeyHash: Hex.from( + "8db50eb52063ea9d98b3eac91489a90f738986f6" + ), + refundPublicKeyHash: Hex.from( + "1b67f27537c7b30a23d8ccefb96a4cacfc72d9a1" + ), + blindingFactor: Hex.from("f9f0c90d00039523"), refundLocktime: BitcoinLocktimeUtils.calculateLocktime( 1674820800, 3600 @@ -116,9 +121,13 @@ export const depositRefundOfNonWitnessDepositAndWitnessRefunderAddress: DepositR depositor: EthereumAddress.from( "934b98637ca318a4d6e7ca6ffd1690b8e77df637" ), - walletPublicKeyHash: "8db50eb52063ea9d98b3eac91489a90f738986f6", - refundPublicKeyHash: "1b67f27537c7b30a23d8ccefb96a4cacfc72d9a1", - blindingFactor: "f9f0c90d00039523", + walletPublicKeyHash: Hex.from( + "8db50eb52063ea9d98b3eac91489a90f738986f6" + ), + refundPublicKeyHash: Hex.from( + "1b67f27537c7b30a23d8ccefb96a4cacfc72d9a1" + ), + blindingFactor: Hex.from("f9f0c90d00039523"), refundLocktime: BitcoinLocktimeUtils.calculateLocktime( 1674820800, 3600 @@ -173,9 +182,13 @@ export const depositRefundOfWitnessDepositAndNonWitnessRefunderAddress: DepositR depositor: EthereumAddress.from( "934b98637ca318a4d6e7ca6ffd1690b8e77df637" ), - walletPublicKeyHash: "8db50eb52063ea9d98b3eac91489a90f738986f6", - refundPublicKeyHash: "1b67f27537c7b30a23d8ccefb96a4cacfc72d9a1", - blindingFactor: "f9f0c90d00039523", + walletPublicKeyHash: Hex.from( + "8db50eb52063ea9d98b3eac91489a90f738986f6" + ), + refundPublicKeyHash: Hex.from( + "1b67f27537c7b30a23d8ccefb96a4cacfc72d9a1" + ), + blindingFactor: Hex.from("f9f0c90d00039523"), refundLocktime: BitcoinLocktimeUtils.calculateLocktime( 1674820800, 3600 diff --git a/typescript/test/data/deposit-sweep.ts b/typescript/test/data/deposit-sweep.ts index 0ba6ffee6..bfe6014a3 100644 --- a/typescript/test/data/deposit-sweep.ts +++ b/typescript/test/data/deposit-sweep.ts @@ -65,10 +65,14 @@ export const depositSweepWithNoMainUtxoAndWitnessOutput: DepositSweepTestData = "934b98637ca318a4d6e7ca6ffd1690b8e77df637" ), // HASH160 of 03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9. - walletPublicKeyHash: "8db50eb52063ea9d98b3eac91489a90f738986f6", + walletPublicKeyHash: Hex.from( + "8db50eb52063ea9d98b3eac91489a90f738986f6" + ), // HASH160 of 039d61d62dcd048d3f8550d22eb90b4af908db60231d117aeede04e7bc11907bfa. - refundPublicKeyHash: "e257eccafbc07c381642ce6e7e55120fb077fbed", - blindingFactor: "f9f0c90d00039523", + refundPublicKeyHash: Hex.from( + "e257eccafbc07c381642ce6e7e55120fb077fbed" + ), + blindingFactor: Hex.from("f9f0c90d00039523"), refundLocktime: BitcoinLocktimeUtils.calculateLocktime( 1641650400, 2592000 @@ -96,10 +100,14 @@ export const depositSweepWithNoMainUtxoAndWitnessOutput: DepositSweepTestData = "934b98637ca318a4d6e7ca6ffd1690b8e77df637" ), // HASH160 of 03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9. - walletPublicKeyHash: "8db50eb52063ea9d98b3eac91489a90f738986f6", + walletPublicKeyHash: Hex.from( + "8db50eb52063ea9d98b3eac91489a90f738986f6" + ), // HASH160 of 039d61d62dcd048d3f8550d22eb90b4af908db60231d117aeede04e7bc11907bfa. - refundPublicKeyHash: "e257eccafbc07c381642ce6e7e55120fb077fbed", - blindingFactor: "f9f0c90d00039523", + refundPublicKeyHash: Hex.from( + "e257eccafbc07c381642ce6e7e55120fb077fbed" + ), + blindingFactor: Hex.from("f9f0c90d00039523"), refundLocktime: BitcoinLocktimeUtils.calculateLocktime( 1641650400, 2592000 @@ -158,10 +166,14 @@ export const depositSweepWithNoMainUtxoAndNonWitnessOutput: DepositSweepTestData "934b98637ca318a4d6e7ca6ffd1690b8e77df637" ), // HASH160 of 03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9. - walletPublicKeyHash: "8db50eb52063ea9d98b3eac91489a90f738986f6", + walletPublicKeyHash: Hex.from( + "8db50eb52063ea9d98b3eac91489a90f738986f6" + ), // HASH160 of 039d61d62dcd048d3f8550d22eb90b4af908db60231d117aeede04e7bc11907bfa. - refundPublicKeyHash: "e257eccafbc07c381642ce6e7e55120fb077fbed", - blindingFactor: "f9f0c90d00039523", + refundPublicKeyHash: Hex.from( + "e257eccafbc07c381642ce6e7e55120fb077fbed" + ), + blindingFactor: Hex.from("f9f0c90d00039523"), refundLocktime: BitcoinLocktimeUtils.calculateLocktime( 1653302600, 2592000 @@ -213,10 +225,14 @@ export const depositSweepWithWitnessMainUtxoAndWitnessOutput: DepositSweepTestDa "934b98637ca318a4d6e7ca6ffd1690b8e77df637" ), // HASH160 of 03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9. - walletPublicKeyHash: "8db50eb52063ea9d98b3eac91489a90f738986f6", + walletPublicKeyHash: Hex.from( + "8db50eb52063ea9d98b3eac91489a90f738986f6" + ), // HASH160 of 039d61d62dcd048d3f8550d22eb90b4af908db60231d117aeede04e7bc11907bfa. - refundPublicKeyHash: "e257eccafbc07c381642ce6e7e55120fb077fbed", - blindingFactor: "f9f0c90d00039523", + refundPublicKeyHash: Hex.from( + "e257eccafbc07c381642ce6e7e55120fb077fbed" + ), + blindingFactor: Hex.from("f9f0c90d00039523"), refundLocktime: BitcoinLocktimeUtils.calculateLocktime( 1641650400, 2592000 @@ -245,10 +261,14 @@ export const depositSweepWithWitnessMainUtxoAndWitnessOutput: DepositSweepTestDa "934b98637ca318a4d6e7ca6ffd1690b8e77df637" ), // HASH160 of 03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9. - walletPublicKeyHash: "8db50eb52063ea9d98b3eac91489a90f738986f6", + walletPublicKeyHash: Hex.from( + "8db50eb52063ea9d98b3eac91489a90f738986f6" + ), // HASH160 of 039d61d62dcd048d3f8550d22eb90b4af908db60231d117aeede04e7bc11907bfa. - refundPublicKeyHash: "e257eccafbc07c381642ce6e7e55120fb077fbed", - blindingFactor: "f9f0c90d00039523", + refundPublicKeyHash: Hex.from( + "e257eccafbc07c381642ce6e7e55120fb077fbed" + ), + blindingFactor: Hex.from("f9f0c90d00039523"), refundLocktime: BitcoinLocktimeUtils.calculateLocktime( 1641650400, 2592000 @@ -343,10 +363,14 @@ export const depositSweepWithNonWitnessMainUtxoAndWitnessOutput: DepositSweepTes "934b98637ca318a4d6e7ca6ffd1690b8e77df637" ), // HASH160 of 03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9. - walletPublicKeyHash: "8db50eb52063ea9d98b3eac91489a90f738986f6", + walletPublicKeyHash: Hex.from( + "8db50eb52063ea9d98b3eac91489a90f738986f6" + ), // HASH160 of 039d61d62dcd048d3f8550d22eb90b4af908db60231d117aeede04e7bc11907bfa. - refundPublicKeyHash: "e257eccafbc07c381642ce6e7e55120fb077fbed", - blindingFactor: "f9f0c90d00039523", + refundPublicKeyHash: Hex.from( + "e257eccafbc07c381642ce6e7e55120fb077fbed" + ), + blindingFactor: Hex.from("f9f0c90d00039523"), refundLocktime: BitcoinLocktimeUtils.calculateLocktime( 1653302600, 2592000 diff --git a/typescript/test/lib/bitcoin.test.ts b/typescript/test/lib/bitcoin.test.ts index fde3ac882..25dade9b5 100644 --- a/typescript/test/lib/bitcoin.test.ts +++ b/typescript/test/lib/bitcoin.test.ts @@ -596,12 +596,12 @@ describe("Bitcoin", () => { const testData = [ { contextName: "when locktime is a block height", - unprefixedHex: "ede80600", + unprefixedHex: Hex.from("ede80600"), expectedLocktime: 452845, }, { contextName: "when locktime is a timestamp", - unprefixedHex: "06241559", + unprefixedHex: Hex.from("06241559"), expectedLocktime: 1494557702, }, { @@ -615,24 +615,24 @@ describe("Bitcoin", () => { context(test.contextName, () => { context("when input is non-prefixed hex string", () => { it("should return the locktime in seconds", async () => { - expect(locktimeToNumber(test.unprefixedHex)).to.be.equal( - test.expectedLocktime - ) + expect( + locktimeToNumber(test.unprefixedHex.toString()) + ).to.be.equal(test.expectedLocktime) }) }) context("when input is 0x prefixed hex string", () => { it("should return the locktime in seconds", async () => { - expect(locktimeToNumber("0x" + test.unprefixedHex)).to.be.equal( - test.expectedLocktime - ) + expect( + locktimeToNumber(test.unprefixedHex.toPrefixedString()) + ).to.be.equal(test.expectedLocktime) }) }) context("when input is Buffer object", () => { it("should return the locktime in seconds", async () => { expect( - locktimeToNumber(Buffer.from(test.unprefixedHex, "hex")) + locktimeToNumber(test.unprefixedHex.toBuffer()) ).to.be.equal(test.expectedLocktime) }) }) @@ -668,7 +668,7 @@ describe("Bitcoin", () => { // The start timestamp is 1652776752 and locktime duration 2592000 (30 days). // So, the locktime timestamp is 1652776752 + 2592000 = 1655368752 which // is represented as 30ecaa62 hex in the little-endian format. - expect(locktime).to.be.equal("30ecaa62") + expect(locktime.toString()).to.be.equal("30ecaa62") }) }) }) diff --git a/typescript/test/lib/ethereum.test.ts b/typescript/test/lib/ethereum.test.ts index dfd558362..da2653f77 100644 --- a/typescript/test/lib/ethereum.test.ts +++ b/typescript/test/lib/ethereum.test.ts @@ -151,10 +151,14 @@ describe("Ethereum", () => { depositor: EthereumAddress.from( "934b98637ca318a4d6e7ca6ffd1690b8e77df637" ), - walletPublicKeyHash: "8db50eb52063ea9d98b3eac91489a90f738986f6", - refundPublicKeyHash: "28e081f285138ccbe389c1eb8985716230129f89", - blindingFactor: "f9f0c90d00039523", - refundLocktime: "60bcea61", + walletPublicKeyHash: Hex.from( + "8db50eb52063ea9d98b3eac91489a90f738986f6" + ), + refundPublicKeyHash: Hex.from( + "28e081f285138ccbe389c1eb8985716230129f89" + ), + blindingFactor: Hex.from("f9f0c90d00039523"), + refundLocktime: Hex.from("60bcea61"), }, EthereumAddress.from("82883a4c7a8dd73ef165deb402d432613615ced4") ) diff --git a/typescript/test/services/deposits.test.ts b/typescript/test/services/deposits.test.ts index 821228f8c..790b2996e 100644 --- a/typescript/test/services/deposits.test.ts +++ b/typescript/test/services/deposits.test.ts @@ -23,6 +23,7 @@ import { } from "../../src" import { MockBitcoinClient } from "../utils/mock-bitcoin-client" import { MockTBTCContracts } from "../utils/mock-tbtc-contracts" +import { Hex } from "../../src/lib/utils" import { txToJSON } from "../utils/helpers" import { depositRefundOfNonWitnessDepositAndWitnessRefunderAddress, @@ -40,10 +41,10 @@ describe("Deposits", () => { const deposit: DepositReceipt = { depositor: EthereumAddress.from("934b98637ca318a4d6e7ca6ffd1690b8e77df637"), // HASH160 of 03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9. - walletPublicKeyHash: "8db50eb52063ea9d98b3eac91489a90f738986f6", + walletPublicKeyHash: Hex.from("8db50eb52063ea9d98b3eac91489a90f738986f6"), // HASH160 of 0300d6f28a2f6bf9836f57fcda5d284c9a8f849316119779f0d6090830d97763a9. - refundPublicKeyHash: "28e081f285138ccbe389c1eb8985716230129f89", - blindingFactor: "f9f0c90d00039523", + refundPublicKeyHash: Hex.from("28e081f285138ccbe389c1eb8985716230129f89"), + blindingFactor: Hex.from("f9f0c90d00039523"), refundLocktime: BitcoinLocktimeUtils.calculateLocktime( depositCreatedAt, depositRefundLocktimeDuration @@ -139,7 +140,9 @@ describe("Deposits", () => { // The first byte (0x08) before the blinding factor is this byte length. // In this case it's 8 bytes. expect(script.substring(44, 46)).to.be.equal("08") - expect(script.substring(46, 62)).to.be.equal(deposit.blindingFactor) + expect(script.substring(46, 62)).to.be.equal( + deposit.blindingFactor.toString() + ) // OP_DROP opcode is 0x75. expect(script.substring(62, 64)).to.be.equal("75") @@ -154,7 +157,9 @@ describe("Deposits", () => { // The first byte (0x14) before the public key is this byte length. // In this case it's 20 bytes which is a correct length for a HASH160. expect(script.substring(68, 70)).to.be.equal("14") - expect(script.substring(70, 110)).to.be.equal(deposit.walletPublicKeyHash) + expect(script.substring(70, 110)).to.be.equal( + deposit.walletPublicKeyHash.toString() + ) // OP_EQUAL opcode is 0x87. expect(script.substring(110, 112)).to.be.equal("87") @@ -178,7 +183,9 @@ describe("Deposits", () => { // The first byte (0x14) before the public key is this byte length. // In this case it's 20 bytes which is a correct length for a HASH160. expect(script.substring(122, 124)).to.be.equal("14") - expect(script.substring(124, 164)).to.be.equal(deposit.refundPublicKeyHash) + expect(script.substring(124, 164)).to.be.equal( + deposit.refundPublicKeyHash.toString() + ) // OP_EQUALVERIFY opcode is 0x88. expect(script.substring(164, 166)).to.be.equal("88") From ce3dcff7a43ab0165158f357c9d2ac4684f7805c Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Tue, 17 Oct 2023 13:32:57 +0200 Subject: [PATCH 10/22] Used Hex for walletPublicKeyHash and redeemerOutputScript --- typescript/src/lib/contracts/bridge.ts | 11 ++-- typescript/src/lib/ethereum/bridge.ts | 6 +-- .../src/services/maintenance/wallet-tx.ts | 4 +- typescript/test/data/redemption.ts | 53 +++++++++++++------ typescript/test/lib/ethereum.test.ts | 10 ++-- typescript/test/services/maintenance.test.ts | 2 +- typescript/test/services/redemptions.test.ts | 22 ++++---- typescript/test/utils/mock-bridge.ts | 2 +- 8 files changed, 65 insertions(+), 45 deletions(-) diff --git a/typescript/src/lib/contracts/bridge.ts b/typescript/src/lib/contracts/bridge.ts index 8742b6cf3..58c3dd786 100644 --- a/typescript/src/lib/contracts/bridge.ts +++ b/typescript/src/lib/contracts/bridge.ts @@ -294,10 +294,10 @@ export interface RedemptionRequest { redeemer: ChainIdentifier /** - * The output script the redeemed Bitcoin funds are locked to. It is un-prefixed - * and is not prepended with length. + * The output script the redeemed Bitcoin funds are locked to. It is not + * prepended with length. */ - redeemerOutputScript: string + redeemerOutputScript: Hex /** * The amount of Bitcoins in satoshis that is requested to be redeemed. @@ -334,10 +334,9 @@ export type RedemptionRequestedEvent = Omit< "requestedAt" > & { /** - * Public key hash of the wallet that is meant to handle the redemption. Must - * be an unprefixed hex string (without 0x prefix). + * Public key hash of the wallet that is meant to handle the redemption. */ - walletPublicKeyHash: string + walletPublicKeyHash: Hex } & ChainEvent /* eslint-disable no-unused-vars */ diff --git a/typescript/src/lib/ethereum/bridge.ts b/typescript/src/lib/ethereum/bridge.ts index 924523148..25f059a0f 100644 --- a/typescript/src/lib/ethereum/bridge.ts +++ b/typescript/src/lib/ethereum/bridge.ts @@ -215,7 +215,7 @@ export class EthereumBridge ): RedemptionRequest { return { redeemer: EthereumAddress.from(request.redeemer), - redeemerOutputScript: redeemerOutputScript.toString(), + redeemerOutputScript: redeemerOutputScript, requestedAmount: BigNumber.from(request.requestedAmount), treasuryFee: BigNumber.from(request.treasuryFee), txMaxFee: BigNumber.from(request.txMaxFee), @@ -653,9 +653,9 @@ export class EthereumBridge blockNumber: BigNumber.from(event.blockNumber).toNumber(), blockHash: Hex.from(event.blockHash), transactionHash: Hex.from(event.transactionHash), - walletPublicKeyHash: Hex.from(event.args!.walletPubKeyHash).toString(), + walletPublicKeyHash: Hex.from(event.args!.walletPubKeyHash), redeemer: EthereumAddress.from(event.args!.redeemer), - redeemerOutputScript: redeemerOutputScript, + redeemerOutputScript: Hex.from(redeemerOutputScript), requestedAmount: BigNumber.from(event.args!.requestedAmount), treasuryFee: BigNumber.from(event.args!.treasuryFee), txMaxFee: BigNumber.from(event.args!.txMaxFee), diff --git a/typescript/src/services/maintenance/wallet-tx.ts b/typescript/src/services/maintenance/wallet-tx.ts index 4e2ae267a..e170cacf6 100644 --- a/typescript/src/services/maintenance/wallet-tx.ts +++ b/typescript/src/services/maintenance/wallet-tx.ts @@ -597,7 +597,7 @@ class Redemption { redemptionRequests.push({ ...redemptionRequest, - redeemerOutputScript: redeemerOutputScript, + redeemerOutputScript: Hex.from(redeemerOutputScript), }) } @@ -710,7 +710,7 @@ class Redemption { txTotalFee = txTotalFee.add(request.txMaxFee) psbt.addOutput({ - script: Buffer.from(request.redeemerOutputScript, "hex"), + script: request.redeemerOutputScript.toBuffer(), value: outputValue.toNumber(), }) } diff --git a/typescript/test/data/redemption.ts b/typescript/test/data/redemption.ts index f840e2b6a..3d806da34 100644 --- a/typescript/test/data/redemption.ts +++ b/typescript/test/data/redemption.ts @@ -84,8 +84,9 @@ export const singleP2PKHRedemptionWithWitnessChange: RedemptionTestData = { "82883a4c7a8dd73ef165deb402d432613615ced4" ), // script for testnet P2PKH address mmTeMR8RKu6QzMGTG4ipA71uewm3EuJng5 - redeemerOutputScript: - "76a9144130879211c54df460e484ddf9aac009cb38ee7488ac", + redeemerOutputScript: Hex.from( + "76a9144130879211c54df460e484ddf9aac009cb38ee7488ac" + ), requestedAmount: BigNumber.from(10000), treasuryFee: BigNumber.from(1000), txMaxFee: BigNumber.from(1600), @@ -141,7 +142,9 @@ export const singleP2WPKHRedemptionWithWitnessChange: RedemptionTestData = { "82883a4c7a8dd73ef165deb402d432613615ced4" ), // script for testnet P2WPKH address tb1qgycg0ys3c4xlgc8ysnwln2kqp89n3mn5ts7z3l - redeemerOutputScript: "00144130879211c54df460e484ddf9aac009cb38ee74", + redeemerOutputScript: Hex.from( + "00144130879211c54df460e484ddf9aac009cb38ee74" + ), requestedAmount: BigNumber.from(15000), treasuryFee: BigNumber.from(1100), txMaxFee: BigNumber.from(1700), @@ -197,7 +200,9 @@ export const singleP2SHRedemptionWithWitnessChange: RedemptionTestData = { "82883a4c7a8dd73ef165deb402d432613615ced4" ), // script for testnet P2SH address 2Mxy76sc1qAxiJ1fXMXDXqHvVcPLh6Lf12C - redeemerOutputScript: "a9143ec459d0f3c29286ae5df5fcc421e2786024277e87", + redeemerOutputScript: Hex.from( + "a9143ec459d0f3c29286ae5df5fcc421e2786024277e87" + ), requestedAmount: BigNumber.from(13000), treasuryFee: BigNumber.from(800), txMaxFee: BigNumber.from(1700), @@ -253,8 +258,9 @@ export const singleP2WSHRedemptionWithWitnessChange: RedemptionTestData = { "82883a4c7a8dd73ef165deb402d432613615ced4" ), // script for testnet P2WSH address tb1qs63s8nwjut4tr5t8nudgzwp4m3dpkefjzpmumn90pruce0cye2tq2jkq0y - redeemerOutputScript: - "002086a303cdd2e2eab1d1679f1a813835dc5a1b65321077cdccaf08f98cbf04ca96", + redeemerOutputScript: Hex.from( + "002086a303cdd2e2eab1d1679f1a813835dc5a1b65321077cdccaf08f98cbf04ca96" + ), requestedAmount: BigNumber.from(18000), treasuryFee: BigNumber.from(1000), txMaxFee: BigNumber.from(1400), @@ -310,8 +316,9 @@ export const multipleRedemptionsWithWitnessChange: RedemptionTestData = { "82883a4c7a8dd73ef165deb402d432613615ced4" ), // script for testnet P2PKH address mmTeMR8RKu6QzMGTG4ipA71uewm3EuJng5 - redeemerOutputScript: - "76a9144130879211c54df460e484ddf9aac009cb38ee7488ac", + redeemerOutputScript: Hex.from( + "76a9144130879211c54df460e484ddf9aac009cb38ee7488ac" + ), requestedAmount: BigNumber.from(18000), treasuryFee: BigNumber.from(1000), txMaxFee: BigNumber.from(1100), @@ -326,7 +333,9 @@ export const multipleRedemptionsWithWitnessChange: RedemptionTestData = { "82883a4c7a8dd73ef165deb402d432613615ced4" ), // script for testnet P2WPKH address tb1qgycg0ys3c4xlgc8ysnwln2kqp89n3mn5ts7z3l - redeemerOutputScript: "00144130879211c54df460e484ddf9aac009cb38ee74", + redeemerOutputScript: Hex.from( + "00144130879211c54df460e484ddf9aac009cb38ee74" + ), requestedAmount: BigNumber.from(13000), treasuryFee: BigNumber.from(800), txMaxFee: BigNumber.from(900), @@ -341,7 +350,9 @@ export const multipleRedemptionsWithWitnessChange: RedemptionTestData = { "82883a4c7a8dd73ef165deb402d432613615ced4" ), // script for testnet P2SH address 2Mxy76sc1qAxiJ1fXMXDXqHvVcPLh6Lf12C - redeemerOutputScript: "a9143ec459d0f3c29286ae5df5fcc421e2786024277e87", + redeemerOutputScript: Hex.from( + "a9143ec459d0f3c29286ae5df5fcc421e2786024277e87" + ), requestedAmount: BigNumber.from(12000), treasuryFee: BigNumber.from(1100), txMaxFee: BigNumber.from(1000), @@ -356,8 +367,9 @@ export const multipleRedemptionsWithWitnessChange: RedemptionTestData = { "82883a4c7a8dd73ef165deb402d432613615ced4" ), // script for testnet P2WSH address tb1qs63s8nwjut4tr5t8nudgzwp4m3dpkefjzpmumn90pruce0cye2tq2jkq0y - redeemerOutputScript: - "002086a303cdd2e2eab1d1679f1a813835dc5a1b65321077cdccaf08f98cbf04ca96", + redeemerOutputScript: Hex.from( + "002086a303cdd2e2eab1d1679f1a813835dc5a1b65321077cdccaf08f98cbf04ca96" + ), requestedAmount: BigNumber.from(15000), treasuryFee: BigNumber.from(700), txMaxFee: BigNumber.from(1400), @@ -416,8 +428,9 @@ export const multipleRedemptionsWithoutChange: RedemptionTestData = { "82883a4c7a8dd73ef165deb402d432613615ced4" ), // script for testnet P2PKH address mmTeMR8RKu6QzMGTG4ipA71uewm3EuJng5 - redeemerOutputScript: - "76a9144130879211c54df460e484ddf9aac009cb38ee7488ac", + redeemerOutputScript: Hex.from( + "76a9144130879211c54df460e484ddf9aac009cb38ee7488ac" + ), requestedAmount: BigNumber.from(6000), treasuryFee: BigNumber.from(0), txMaxFee: BigNumber.from(800), @@ -432,7 +445,9 @@ export const multipleRedemptionsWithoutChange: RedemptionTestData = { "82883a4c7a8dd73ef165deb402d432613615ced4" ), // script for testnet P2WPKH address tb1qf0ulldawp79s7knz9v254j5zjyn0demfx2d0xx - redeemerOutputScript: "00144bf9ffb7ae0f8b0f5a622b154aca829126f6e769", + redeemerOutputScript: Hex.from( + "00144bf9ffb7ae0f8b0f5a622b154aca829126f6e769" + ), requestedAmount: BigNumber.from(4000), treasuryFee: BigNumber.from(0), txMaxFee: BigNumber.from(900), @@ -491,7 +506,9 @@ export const singleP2SHRedemptionWithNonWitnessChange: RedemptionTestData = { "82883a4c7a8dd73ef165deb402d432613615ced4" ), // script for testnet P2SH address 2Mxy76sc1qAxiJ1fXMXDXqHvVcPLh6Lf12C - redeemerOutputScript: "a9143ec459d0f3c29286ae5df5fcc421e2786024277e87", + redeemerOutputScript: Hex.from( + "a9143ec459d0f3c29286ae5df5fcc421e2786024277e87" + ), requestedAmount: BigNumber.from(12000), treasuryFee: BigNumber.from(1000), txMaxFee: BigNumber.from(1200), @@ -902,7 +919,9 @@ export const findWalletForRedemptionData: { "0xeb9af8E66869902476347a4eFe59a527a57240ED" ), // script for testnet P2PKH address mjc2zGWypwpNyDi4ZxGbBNnUA84bfgiwYc - redeemerOutputScript: "76a9142cd680318747b720d67bf4246eb7403b476adb3488ac", + redeemerOutputScript: Hex.from( + "76a9142cd680318747b720d67bf4246eb7403b476adb3488ac" + ), requestedAmount: BigNumber.from(1000000), treasuryFee: BigNumber.from(20000), txMaxFee: BigNumber.from(20000), diff --git a/typescript/test/lib/ethereum.test.ts b/typescript/test/lib/ethereum.test.ts index da2653f77..42fe48453 100644 --- a/typescript/test/lib/ethereum.test.ts +++ b/typescript/test/lib/ethereum.test.ts @@ -83,8 +83,9 @@ describe("Ethereum", () => { redeemer: EthereumAddress.from( "f39fd6e51aad88f6f4ce6ab8827279cfffb92266" ), - redeemerOutputScript: - "a9143ec459d0f3c29286ae5df5fcc421e2786024277e87", + redeemerOutputScript: Hex.from( + "a9143ec459d0f3c29286ae5df5fcc421e2786024277e87" + ), requestedAmount: BigNumber.from(10000), treasuryFee: BigNumber.from(100), txMaxFee: BigNumber.from(50), @@ -124,8 +125,9 @@ describe("Ethereum", () => { redeemer: EthereumAddress.from( "f39fd6e51aad88f6f4ce6ab8827279cfffb92266" ), - redeemerOutputScript: - "a9143ec459d0f3c29286ae5df5fcc421e2786024277e87", + redeemerOutputScript: Hex.from( + "a9143ec459d0f3c29286ae5df5fcc421e2786024277e87" + ), requestedAmount: BigNumber.from(10000), treasuryFee: BigNumber.from(100), txMaxFee: BigNumber.from(50), diff --git a/typescript/test/services/maintenance.test.ts b/typescript/test/services/maintenance.test.ts index cbca52a78..f21d253c9 100644 --- a/typescript/test/services/maintenance.test.ts +++ b/typescript/test/services/maintenance.test.ts @@ -1450,7 +1450,7 @@ describe("Maintenance", () => { it("should revert", async () => { const redeemerOutputScripts = data.pendingRedemptions.map( (redemption) => - redemption.pendingRedemption.redeemerOutputScript + redemption.pendingRedemption.redeemerOutputScript.toString() ) const walletTx = new WalletTx( diff --git a/typescript/test/services/redemptions.test.ts b/typescript/test/services/redemptions.test.ts index 7b22f26ac..384568c41 100644 --- a/typescript/test/services/redemptions.test.ts +++ b/typescript/test/services/redemptions.test.ts @@ -105,7 +105,7 @@ describe("Redemptions", () => { await redemptionsService.requestRedemption( BitcoinAddressConverter.outputScriptToAddress( - Hex.from(redeemerOutputScript), + redeemerOutputScript, BitcoinNetwork.Testnet ), amount @@ -119,7 +119,7 @@ describe("Redemptions", () => { expect(tokenLog[0]).to.deep.equal({ walletPublicKey, mainUtxo, - redeemerOutputScript, + redeemerOutputScript: redeemerOutputScript.toString(), amount, }) }) @@ -153,7 +153,7 @@ describe("Redemptions", () => { const actualRedemptionRequest = await redemptionsService.getRedemptionRequests( BitcoinAddressConverter.outputScriptToAddress( - Hex.from(redemptionRequest.redeemerOutputScript), + redemptionRequest.redeemerOutputScript, BitcoinNetwork.Testnet ), walletPublicKey, @@ -191,7 +191,7 @@ describe("Redemptions", () => { const actualRedemptionRequest = await redemptionsService.getRedemptionRequests( BitcoinAddressConverter.outputScriptToAddress( - Hex.from(redemptionRequest.redeemerOutputScript), + redemptionRequest.redeemerOutputScript, BitcoinNetwork.Testnet ), walletPublicKey, @@ -377,7 +377,7 @@ describe("Redemptions", () => { const key = MockBridge.buildRedemptionKey( walletPublicKeyHash.toString(), - redeemerOutputScript + redeemerOutputScript.toString() ) pendingRedemptions.set( @@ -387,7 +387,7 @@ describe("Redemptions", () => { tbtcContracts.bridge.setPendingRedemptions(pendingRedemptions) result = await redemptionsService.findWalletForRedemption( - redeemerOutputScript, + redeemerOutputScript.toString(), amount ) }) @@ -466,12 +466,12 @@ describe("Redemptions", () => { const pendingRedemption1 = MockBridge.buildRedemptionKey( walletPublicKeyHash.toString(), - redeemerOutputScript + redeemerOutputScript.toString() ) const pendingRedemption2 = MockBridge.buildRedemptionKey( findWalletForRedemptionData.liveWallet.event.walletPublicKeyHash.toString(), - redeemerOutputScript + redeemerOutputScript.toString() ) pendingRedemptions.set( @@ -489,7 +489,7 @@ describe("Redemptions", () => { it("should throw an error", async () => { await expect( redemptionsService.findWalletForRedemption( - redeemerOutputScript, + redeemerOutputScript.toString(), amount ) ).to.be.rejectedWith( @@ -825,8 +825,8 @@ export async function runRedemptionScenario( ) ) - const redeemerOutputScripts = data.pendingRedemptions.map( - (redemption) => redemption.pendingRedemption.redeemerOutputScript + const redeemerOutputScripts = data.pendingRedemptions.map((redemption) => + redemption.pendingRedemption.redeemerOutputScript.toString() ) const walletTx = new WalletTx(tbtcContracts, bitcoinClient, data.witness) diff --git a/typescript/test/utils/mock-bridge.ts b/typescript/test/utils/mock-bridge.ts index 0a7c143de..31cb72365 100644 --- a/typescript/test/utils/mock-bridge.ts +++ b/typescript/test/utils/mock-bridge.ts @@ -305,7 +305,7 @@ export class MockBridge implements Bridge { ? (redemptionsMap.get(redemptionKey) as RedemptionRequest) : { redeemer: EthereumAddress.from(constants.AddressZero), - redeemerOutputScript: "", + redeemerOutputScript: Hex.from(""), requestedAmount: BigNumber.from(0), treasuryFee: BigNumber.from(0), txMaxFee: BigNumber.from(0), From 21c55310589bb2b306ecec4af9ff8352b1412455 Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Tue, 17 Oct 2023 14:13:01 +0200 Subject: [PATCH 11/22] Used Hex for TBTC token functionalities --- typescript/src/lib/contracts/tbtc-token.ts | 7 +++---- typescript/src/lib/ethereum/tbtc-token.ts | 19 ++++++++--------- .../redemptions/redemptions-service.ts | 4 ++-- typescript/test/data/redemption.ts | 3 ++- typescript/test/lib/ethereum.test.ts | 21 ++++++++++--------- typescript/test/services/maintenance.test.ts | 2 +- typescript/test/services/redemptions.test.ts | 15 +++++++------ typescript/test/utils/mock-tbtc-token.ts | 8 +++---- 8 files changed, 39 insertions(+), 40 deletions(-) diff --git a/typescript/src/lib/contracts/tbtc-token.ts b/typescript/src/lib/contracts/tbtc-token.ts index 596c88ddb..01ea195fe 100644 --- a/typescript/src/lib/contracts/tbtc-token.ts +++ b/typescript/src/lib/contracts/tbtc-token.ts @@ -32,16 +32,15 @@ export interface TBTCToken { * @param mainUtxo - The main UTXO of the wallet. Must match the main UTXO * held by the on-chain Bridge contract. * @param redeemerOutputScript - The output script that the redeemed funds - * will be locked to. Must be un-prefixed and not prepended with - * length. + * will be locked to. Must not be prepended with length. * @param amount - The amount to be redeemed with the precision of the tBTC * on-chain token contract. * @returns Transaction hash of the approve and call transaction. */ requestRedemption( - walletPublicKey: string, + walletPublicKey: Hex, mainUtxo: BitcoinUtxo, - redeemerOutputScript: string, + redeemerOutputScript: Hex, amount: BigNumber ): Promise } diff --git a/typescript/src/lib/ethereum/tbtc-token.ts b/typescript/src/lib/ethereum/tbtc-token.ts index 7ec5dbab3..719cb3aca 100644 --- a/typescript/src/lib/ethereum/tbtc-token.ts +++ b/typescript/src/lib/ethereum/tbtc-token.ts @@ -69,9 +69,9 @@ export class EthereumTBTCToken * @see {TBTCToken#requestRedemption} */ async requestRedemption( - walletPublicKey: string, + walletPublicKey: Hex, mainUtxo: BitcoinUtxo, - redeemerOutputScript: string, + redeemerOutputScript: Hex, amount: BigNumber ): Promise { const redeemer = await this._instance?.signer?.getAddress() @@ -103,9 +103,9 @@ export class EthereumTBTCToken private buildRequestRedemptionData( redeemer: EthereumAddress, - walletPublicKey: string, + walletPublicKey: Hex, mainUtxo: BitcoinUtxo, - redeemerOutputScript: string + redeemerOutputScript: Hex ): Hex { const { walletPublicKeyHash, @@ -133,13 +133,12 @@ export class EthereumTBTCToken } private buildBridgeRequestRedemptionData( - walletPublicKey: string, + walletPublicKey: Hex, mainUtxo: BitcoinUtxo, - redeemerOutputScript: string + redeemerOutputScript: Hex ) { - const walletPublicKeyHash = BitcoinHashUtils.computeHash160( - Hex.from(walletPublicKey) - ).toPrefixedString() + const walletPublicKeyHash = + BitcoinHashUtils.computeHash160(walletPublicKey).toPrefixedString() const mainUtxoParam = { // The Ethereum Bridge expects this hash to be in the Bitcoin internal @@ -150,7 +149,7 @@ export class EthereumTBTCToken } // Convert the output script to raw bytes buffer. - const rawRedeemerOutputScript = Buffer.from(redeemerOutputScript, "hex") + const rawRedeemerOutputScript = redeemerOutputScript.toBuffer() // Prefix the output script bytes buffer with 0x and its own length. const prefixedRawRedeemerOutputScript = `0x${Buffer.concat([ Buffer.from([rawRedeemerOutputScript.length]), diff --git a/typescript/src/services/redemptions/redemptions-service.ts b/typescript/src/services/redemptions/redemptions-service.ts index 5a1a304ae..74b10b680 100644 --- a/typescript/src/services/redemptions/redemptions-service.ts +++ b/typescript/src/services/redemptions/redemptions-service.ts @@ -66,9 +66,9 @@ export class RedemptionsService { ) const txHash = await this.tbtcContracts.tbtcToken.requestRedemption( - walletPublicKey, + Hex.from(walletPublicKey), mainUtxo, - redeemerOutputScript, + Hex.from(redeemerOutputScript), amount ) diff --git a/typescript/test/data/redemption.ts b/typescript/test/data/redemption.ts index 3d806da34..9bdec0dc2 100644 --- a/typescript/test/data/redemption.ts +++ b/typescript/test/data/redemption.ts @@ -25,8 +25,9 @@ export const walletPrivateKey = * Public key of the wallet in the compressed form corresponding to * walletPrivateKey. */ -export const walletPublicKey = +export const walletPublicKey = Hex.from( "03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9" +) /** * P2PKH address corresponding to walletPrivateKey. diff --git a/typescript/test/lib/ethereum.test.ts b/typescript/test/lib/ethereum.test.ts index 42fe48453..88608f0e1 100644 --- a/typescript/test/lib/ethereum.test.ts +++ b/typescript/test/lib/ethereum.test.ts @@ -528,8 +528,9 @@ describe("Ethereum", () => { vault: EthereumAddress.from( "0x24BE35e7C04E2e0a628614Ce0Ed58805e1C894F7" ), - walletPublicKey: - "03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9", + walletPublicKey: Hex.from( + "03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9" + ), mainUtxo: { transactionHash: BitcoinTxHash.from( "f8eaf242a55ea15e602f9f990e33f67f99dfbe25d1802bbde63cc1caabf99668" @@ -540,10 +541,12 @@ describe("Ethereum", () => { redeemer: EthereumAddress.from(signer.address), amount: BigNumber.from(10000), redeemerOutputScript: { - unprefixed: - "0020cdbf909e935c855d3e8d1b61aeb9c5e3c03ae8021b286839b1a72f2e48fdba70", - prefixed: - "0x220020cdbf909e935c855d3e8d1b61aeb9c5e3c03ae8021b286839b1a72f2e48fdba70", + unprefixed: Hex.from( + "0020cdbf909e935c855d3e8d1b61aeb9c5e3c03ae8021b286839b1a72f2e48fdba70" + ), + prefixed: Hex.from( + "220020cdbf909e935c855d3e8d1b61aeb9c5e3c03ae8021b286839b1a72f2e48fdba70" + ), }, } @@ -572,13 +575,11 @@ describe("Ethereum", () => { ["address", "bytes20", "bytes32", "uint32", "uint64", "bytes"], [ redeemer.identifierHex, - BitcoinHashUtils.computeHash160( - Hex.from(walletPublicKey) - ).toPrefixedString(), + BitcoinHashUtils.computeHash160(walletPublicKey).toPrefixedString(), mainUtxo.transactionHash.reverse().toPrefixedString(), mainUtxo.outputIndex, mainUtxo.value, - redeemerOutputScript.prefixed, + redeemerOutputScript.prefixed.toPrefixedString(), ] ) diff --git a/typescript/test/services/maintenance.test.ts b/typescript/test/services/maintenance.test.ts index f21d253c9..3fabe2036 100644 --- a/typescript/test/services/maintenance.test.ts +++ b/typescript/test/services/maintenance.test.ts @@ -2533,7 +2533,7 @@ describe("Maintenance", () => { await maintenanceService.spv.submitRedemptionProof( transactionHash, mainUtxo, - walletPublicKey + walletPublicKey.toString() ) }) diff --git a/typescript/test/services/redemptions.test.ts b/typescript/test/services/redemptions.test.ts index 384568c41..1a974b9e4 100644 --- a/typescript/test/services/redemptions.test.ts +++ b/typescript/test/services/redemptions.test.ts @@ -53,21 +53,20 @@ describe("Redemptions", () => { tbtcContracts = new MockTBTCContracts() bitcoinClient = new MockBitcoinClient() - const walletPublicKeyHash = BitcoinHashUtils.computeHash160( - Hex.from(walletPublicKey) - ) + const walletPublicKeyHash = + BitcoinHashUtils.computeHash160(walletPublicKey) // Prepare NewWalletRegisteredEvent history. Set only relevant fields. tbtcContracts.bridge.newWalletRegisteredEvents = [ { - walletPublicKeyHash: walletPublicKeyHash, + walletPublicKeyHash, } as NewWalletRegisteredEvent, ] // Prepare wallet data in the Bridge. Set only relevant fields. tbtcContracts.bridge.setWallet(walletPublicKeyHash.toPrefixedString(), { state: WalletState.Live, - walletPublicKey: Hex.from(walletPublicKey), + walletPublicKey, pendingRedemptionsValue: BigNumber.from(0), mainUtxoHash: tbtcContracts.bridge.buildUtxoHash(mainUtxo), } as Wallet) @@ -119,7 +118,7 @@ describe("Redemptions", () => { expect(tokenLog[0]).to.deep.equal({ walletPublicKey, mainUtxo, - redeemerOutputScript: redeemerOutputScript.toString(), + redeemerOutputScript, amount, }) }) @@ -156,7 +155,7 @@ describe("Redemptions", () => { redemptionRequest.redeemerOutputScript, BitcoinNetwork.Testnet ), - walletPublicKey, + walletPublicKey.toString(), "pending" ) @@ -194,7 +193,7 @@ describe("Redemptions", () => { redemptionRequest.redeemerOutputScript, BitcoinNetwork.Testnet ), - walletPublicKey, + walletPublicKey.toString(), "timedOut" ) diff --git a/typescript/test/utils/mock-tbtc-token.ts b/typescript/test/utils/mock-tbtc-token.ts index b2238f550..ba7fdc08d 100644 --- a/typescript/test/utils/mock-tbtc-token.ts +++ b/typescript/test/utils/mock-tbtc-token.ts @@ -5,9 +5,9 @@ import { BitcoinUtxo } from "../../src/lib/bitcoin" import { EthereumAddress } from "../../src" interface RequestRedemptionLog { - walletPublicKey: string + walletPublicKey: Hex mainUtxo: BitcoinUtxo - redeemerOutputScript: string + redeemerOutputScript: Hex amount: BigNumber } @@ -23,9 +23,9 @@ export class MockTBTCToken implements TBTCToken { } async requestRedemption( - walletPublicKey: string, + walletPublicKey: Hex, mainUtxo: BitcoinUtxo, - redeemerOutputScript: string, + redeemerOutputScript: Hex, amount: BigNumber ): Promise { this._requestRedemptionLog.push({ From 5ca3037d9cf6c363fcc6f0eab2da544e3357ea3e Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Tue, 17 Oct 2023 14:38:20 +0200 Subject: [PATCH 12/22] Used Hex for electrum --- typescript/src/lib/electrum/client.ts | 13 +++++-------- typescript/test/lib/electrum.test.ts | 5 ++++- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/typescript/src/lib/electrum/client.ts b/typescript/src/lib/electrum/client.ts index d4dbb57c8..f27b5f7d2 100644 --- a/typescript/src/lib/electrum/client.ts +++ b/typescript/src/lib/electrum/client.ts @@ -14,7 +14,7 @@ import { BitcoinHashUtils, } from "../bitcoin" import Electrum from "electrum-client-js" -import { BigNumber, utils } from "ethers" +import { BigNumber } from "ethers" import { URL } from "url" import { backoffRetrier, Hex, RetrierFn } from "../utils" @@ -261,7 +261,7 @@ export class ElectrumClient implements BitcoinClient { const script = BitcoinAddressConverter.addressToOutputScript( address, bitcoinNetwork - ).toString() + ) // eslint-disable-next-line camelcase type UnspentOutput = { tx_pos: number; value: number; tx_hash: string } @@ -292,7 +292,7 @@ export class ElectrumClient implements BitcoinClient { const script = BitcoinAddressConverter.addressToOutputScript( address, bitcoinNetwork - ).toString() + ) // eslint-disable-next-line camelcase type HistoryItem = { height: number; tx_hash: string } @@ -585,9 +585,6 @@ export class ElectrumClient implements BitcoinClient { * @param script - Bitcoin script as hex string * @returns Electrum script hash as a hex string. */ -export function computeElectrumScriptHash(script: string): string { - const _script = Hex.from(Buffer.from(script, "hex")).toPrefixedString() - const hash256 = utils.sha256(_script) - - return Hex.from(hash256).reverse().toString() +export function computeElectrumScriptHash(script: Hex): string { + return BitcoinHashUtils.computeSha256(script).reverse().toString() } diff --git a/typescript/test/lib/electrum.test.ts b/typescript/test/lib/electrum.test.ts index 76f521fc0..b54e50b1d 100644 --- a/typescript/test/lib/electrum.test.ts +++ b/typescript/test/lib/electrum.test.ts @@ -3,6 +3,7 @@ import { ElectrumCredentials, ElectrumClient, computeElectrumScriptHash, + Hex, } from "../../src" import { testnetAddress, @@ -224,7 +225,9 @@ describe("Electrum", () => { describe("computeElectrumScriptHash", () => { it("should convert Bitcoin script to an Electrum script hash correctly", () => { - const script = "00144b47c798d12edd17dfb4ea98e5447926f664731c" + const script = Hex.from( + "00144b47c798d12edd17dfb4ea98e5447926f664731c" + ) const expectedScriptHash = "cabdea0bfc10fb3521721dde503487dd1f0e41dd6609da228066757563f292ab" From 04ebcb3e0e5fa18230cb54dec956f7b20d8e5811 Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Tue, 17 Oct 2023 16:11:39 +0200 Subject: [PATCH 13/22] Used Hex for calculating deposit script --- typescript/src/services/deposits/deposit.ts | 10 +++++----- typescript/src/services/deposits/refund.ts | 2 +- typescript/src/services/maintenance/wallet-tx.ts | 5 +---- typescript/test/services/deposits.test.ts | 4 ++-- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/typescript/src/services/deposits/deposit.ts b/typescript/src/services/deposits/deposit.ts index ab066d287..a1f454eb0 100644 --- a/typescript/src/services/deposits/deposit.ts +++ b/typescript/src/services/deposits/deposit.ts @@ -185,14 +185,14 @@ export class DepositScript { // If witness script hash should be produced, SHA256 should be used. // Legacy script hash needs HASH160. return this.witness - ? BitcoinHashUtils.computeSha256(Hex.from(script)).toBuffer() - : BitcoinHashUtils.computeHash160(Hex.from(script)).toBuffer() + ? BitcoinHashUtils.computeSha256(script).toBuffer() + : BitcoinHashUtils.computeHash160(script).toBuffer() } /** - * @returns Plain-text deposit script as an un-prefixed hex string. + * @returns Plain-text deposit script as a hex string. */ - async getPlainText(): Promise { + async getPlainText(): Promise { const chunks: Stack = [] // All HEXes pushed to the script must be un-prefixed @@ -217,7 +217,7 @@ export class DepositScript { chunks.push(opcodes.OP_CHECKSIG) chunks.push(opcodes.OP_ENDIF) - return script.compile(chunks).toString("hex") + return Hex.from(script.compile(chunks)) } /** diff --git a/typescript/src/services/deposits/refund.ts b/typescript/src/services/deposits/refund.ts index edb232594..be678b63c 100644 --- a/typescript/src/services/deposits/refund.ts +++ b/typescript/src/services/deposits/refund.ts @@ -205,7 +205,7 @@ export class DepositRefund { throw new Error("Refunder public key must be compressed") } - return Buffer.from(await this.script.getPlainText(), "hex") + return (await this.script.getPlainText()).toBuffer() } /** diff --git a/typescript/src/services/maintenance/wallet-tx.ts b/typescript/src/services/maintenance/wallet-tx.ts index e170cacf6..dcf838a4d 100644 --- a/typescript/src/services/maintenance/wallet-tx.ts +++ b/typescript/src/services/maintenance/wallet-tx.ts @@ -486,10 +486,7 @@ class DepositSweep { throw new Error("Wallet public key must be compressed") } - return Buffer.from( - await DepositScript.fromReceipt(deposit).getPlainText(), - "hex" - ) + return (await DepositScript.fromReceipt(deposit).getPlainText()).toBuffer() } /** diff --git a/typescript/test/services/deposits.test.ts b/typescript/test/services/deposits.test.ts index 790b2996e..43b0e8561 100644 --- a/typescript/test/services/deposits.test.ts +++ b/typescript/test/services/deposits.test.ts @@ -537,14 +537,14 @@ describe("Deposits", () => { describe("DepositScript", () => { describe("getPlainText", () => { - let script: string + let script: Hex beforeEach(async () => { script = await DepositScript.fromReceipt(deposit).getPlainText() }) it("should return script with proper structure", async () => { - assertValidDepositScript(script) + assertValidDepositScript(script.toString()) }) }) From 7ae21468af9c809e28b94e3e492234b0c7a6775f Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Tue, 17 Oct 2023 17:15:42 +0200 Subject: [PATCH 14/22] Used Hex in services --- typescript/src/lib/bitcoin/ecdsa-key.ts | 8 ++++- typescript/src/lib/ethereum/bridge.ts | 2 +- typescript/src/services/deposits/refund.ts | 4 +-- typescript/src/services/maintenance/spv.ts | 4 +-- .../src/services/maintenance/wallet-tx.ts | 18 ++++++------ .../redemptions/redemptions-service.ts | 29 +++++++++---------- typescript/test/services/maintenance.test.ts | 4 +-- typescript/test/services/redemptions.test.ts | 25 ++++++++-------- 8 files changed, 50 insertions(+), 44 deletions(-) diff --git a/typescript/src/lib/bitcoin/ecdsa-key.ts b/typescript/src/lib/bitcoin/ecdsa-key.ts index 8ffbd9955..39de4e173 100644 --- a/typescript/src/lib/bitcoin/ecdsa-key.ts +++ b/typescript/src/lib/bitcoin/ecdsa-key.ts @@ -9,7 +9,13 @@ import { BitcoinNetwork, toBitcoinJsLibNetwork } from "./network" * @param publicKey - Public key that should be checked. * @returns True if the key is a compressed Bitcoin public key, false otherwise. */ -function isCompressedPublicKey(publicKey: string): boolean { +function isCompressedPublicKey(publicKey: string | Hex): boolean { + if (typeof publicKey === "string") { + publicKey = Hex.from(publicKey) + } + + publicKey = publicKey.toString() + // Must have 33 bytes and 02 or 03 prefix. return ( publicKey.length == 66 && diff --git a/typescript/src/lib/ethereum/bridge.ts b/typescript/src/lib/ethereum/bridge.ts index 25f059a0f..92dcbed73 100644 --- a/typescript/src/lib/ethereum/bridge.ts +++ b/typescript/src/lib/ethereum/bridge.ts @@ -196,7 +196,7 @@ export class EthereumBridge ["bytes32", "bytes20"], [ utils.solidityKeccak256(["bytes"], [prefixedRawRedeemerOutputScript]), - `0x${walletPublicKeyHash}`, + `0x${walletPublicKeyHash.toString()}`, ] ) } diff --git a/typescript/src/services/deposits/refund.ts b/typescript/src/services/deposits/refund.ts index be678b63c..ef9a4227b 100644 --- a/typescript/src/services/deposits/refund.ts +++ b/typescript/src/services/deposits/refund.ts @@ -189,10 +189,10 @@ export class DepositRefund { * @throws Error if there are discrepancies in values or key formats. */ private async prepareDepositScript(refunderKeyPair: Signer): Promise { - const refunderPublicKey = refunderKeyPair.publicKey.toString("hex") + const refunderPublicKey = Hex.from(refunderKeyPair.publicKey) if ( - !BitcoinHashUtils.computeHash160(Hex.from(refunderPublicKey)).equals( + !BitcoinHashUtils.computeHash160(refunderPublicKey).equals( this.script.receipt.refundPublicKeyHash ) ) { diff --git a/typescript/src/services/maintenance/spv.ts b/typescript/src/services/maintenance/spv.ts index 8f546330e..3dbd8341e 100644 --- a/typescript/src/services/maintenance/spv.ts +++ b/typescript/src/services/maintenance/spv.ts @@ -67,7 +67,7 @@ export class Spv { async submitRedemptionProof( transactionHash: BitcoinTxHash, mainUtxo: BitcoinUtxo, - walletPublicKey: string + walletPublicKey: Hex ): Promise { const confirmations = await this.tbtcContracts.bridge.txProofDifficultyFactor() @@ -85,7 +85,7 @@ export class Spv { rawTransactionVectors, proof, mainUtxo, - Hex.from(walletPublicKey) + walletPublicKey ) } } diff --git a/typescript/src/services/maintenance/wallet-tx.ts b/typescript/src/services/maintenance/wallet-tx.ts index dcf838a4d..595a19171 100644 --- a/typescript/src/services/maintenance/wallet-tx.ts +++ b/typescript/src/services/maintenance/wallet-tx.ts @@ -470,10 +470,10 @@ class DepositSweep { previousOutputValue: number, walletKeyPair: Signer ): Promise { - const walletPublicKey = walletKeyPair.publicKey.toString("hex") + const walletPublicKey = Hex.from(walletKeyPair.publicKey) if ( - !BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)).equals( + !BitcoinHashUtils.computeHash160(walletPublicKey).equals( deposit.walletPublicKeyHash ) ) { @@ -547,8 +547,8 @@ class Redemption { * @param mainUtxo - The main UTXO of the wallet. Must match the main UTXO * held by the on-chain Bridge contract * @param redeemerOutputScripts - The list of output scripts that the redeemed - * funds will be locked to. The output scripts must be un-prefixed and - * not prepended with length + * funds will be locked to. The output scripts must not be prepended + * with length * @returns The outcome consisting of: * - the redemption transaction hash, * - the optional new wallet's main UTXO produced by this transaction. @@ -556,7 +556,7 @@ class Redemption { async submitTransaction( walletPrivateKey: string, mainUtxo: BitcoinUtxo, - redeemerOutputScripts: string[] + redeemerOutputScripts: Hex[] ): Promise<{ transactionHash: BitcoinTxHash newMainUtxo?: BitcoinUtxo @@ -577,15 +577,15 @@ class Redemption { bitcoinNetwork ) - const walletPublicKey = walletKeyPair.publicKey.toString("hex") + const walletPublicKey = Hex.from(walletKeyPair.publicKey) const redemptionRequests: RedemptionRequest[] = [] for (const redeemerOutputScript of redeemerOutputScripts) { const redemptionRequest = await this.tbtcContracts.bridge.pendingRedemptions( - Hex.from(walletPublicKey), - Hex.from(redeemerOutputScript) + walletPublicKey, + redeemerOutputScript ) if (redemptionRequest.requestedAt == 0) { @@ -594,7 +594,7 @@ class Redemption { redemptionRequests.push({ ...redemptionRequest, - redeemerOutputScript: Hex.from(redeemerOutputScript), + redeemerOutputScript, }) } diff --git a/typescript/src/services/redemptions/redemptions-service.ts b/typescript/src/services/redemptions/redemptions-service.ts index 74b10b680..363f0454a 100644 --- a/typescript/src/services/redemptions/redemptions-service.ts +++ b/typescript/src/services/redemptions/redemptions-service.ts @@ -49,14 +49,14 @@ export class RedemptionsService { amount: BigNumber ): Promise<{ targetChainTxHash: Hex - walletPublicKey: string + walletPublicKey: Hex }> { const bitcoinNetwork = await this.bitcoinClient.getNetwork() const redeemerOutputScript = BitcoinAddressConverter.addressToOutputScript( bitcoinRedeemerAddress, bitcoinNetwork - ).toString() + ) // TODO: Validate the given script is supported for redemption. @@ -66,9 +66,9 @@ export class RedemptionsService { ) const txHash = await this.tbtcContracts.tbtcToken.requestRedemption( - Hex.from(walletPublicKey), + walletPublicKey, mainUtxo, - Hex.from(redeemerOutputScript), + redeemerOutputScript, amount ) @@ -82,16 +82,15 @@ export class RedemptionsService { * Finds the oldest live wallet that has enough BTC to handle a redemption * request. * @param redeemerOutputScript The redeemer output script the redeemed funds are - * supposed to be locked on. Must be un-prefixed and not prepended with - * length. + * supposed to be locked on. Must not be prepended with length. * @param amount The amount to be redeemed in satoshis. * @returns Promise with the wallet details needed to request a redemption. */ protected async findWalletForRedemption( - redeemerOutputScript: string, + redeemerOutputScript: Hex, amount: BigNumber ): Promise<{ - walletPublicKey: string + walletPublicKey: Hex mainUtxo: BitcoinUtxo }> { const wallets = @@ -99,7 +98,7 @@ export class RedemptionsService { let walletData: | { - walletPublicKey: string + walletPublicKey: Hex mainUtxo: BitcoinUtxo } | undefined = undefined @@ -141,7 +140,7 @@ export class RedemptionsService { const pendingRedemption = await this.tbtcContracts.bridge.pendingRedemptions( walletPublicKey, - Hex.from(redeemerOutputScript) + redeemerOutputScript ) if (pendingRedemption.requestedAt != 0) { @@ -149,7 +148,7 @@ export class RedemptionsService { `There is a pending redemption request from this wallet to the ` + `same Bitcoin address. Given wallet public key hash` + `(${walletPublicKeyHash.toString()}) and redeemer output script ` + - `(${redeemerOutputScript}) pair can be used for only one ` + + `(${redeemerOutputScript.toString()}) pair can be used for only one ` + `pending request at the same time. ` + `Continue the loop execution to the next wallet...` ) @@ -163,7 +162,7 @@ export class RedemptionsService { if (walletBTCBalance.gte(amount)) { walletData = { - walletPublicKey: walletPublicKey.toString(), + walletPublicKey, mainUtxo, } @@ -330,7 +329,7 @@ export class RedemptionsService { */ async getRedemptionRequests( bitcoinRedeemerAddress: string, - walletPublicKey: string, + walletPublicKey: Hex, type: "pending" | "timedOut" = "pending" ): Promise { const bitcoinNetwork = await this.bitcoinClient.getNetwork() @@ -345,14 +344,14 @@ export class RedemptionsService { switch (type) { case "pending": { redemptionRequest = await this.tbtcContracts.bridge.pendingRedemptions( - Hex.from(walletPublicKey), + walletPublicKey, redeemerOutputScript ) break } case "timedOut": { redemptionRequest = await this.tbtcContracts.bridge.timedOutRedemptions( - Hex.from(walletPublicKey), + walletPublicKey, redeemerOutputScript ) break diff --git a/typescript/test/services/maintenance.test.ts b/typescript/test/services/maintenance.test.ts index 3fabe2036..cbca52a78 100644 --- a/typescript/test/services/maintenance.test.ts +++ b/typescript/test/services/maintenance.test.ts @@ -1450,7 +1450,7 @@ describe("Maintenance", () => { it("should revert", async () => { const redeemerOutputScripts = data.pendingRedemptions.map( (redemption) => - redemption.pendingRedemption.redeemerOutputScript.toString() + redemption.pendingRedemption.redeemerOutputScript ) const walletTx = new WalletTx( @@ -2533,7 +2533,7 @@ describe("Maintenance", () => { await maintenanceService.spv.submitRedemptionProof( transactionHash, mainUtxo, - walletPublicKey.toString() + walletPublicKey ) }) diff --git a/typescript/test/services/redemptions.test.ts b/typescript/test/services/redemptions.test.ts index 1a974b9e4..c8dbd7344 100644 --- a/typescript/test/services/redemptions.test.ts +++ b/typescript/test/services/redemptions.test.ts @@ -155,7 +155,7 @@ describe("Redemptions", () => { redemptionRequest.redeemerOutputScript, BitcoinNetwork.Testnet ), - walletPublicKey.toString(), + walletPublicKey, "pending" ) @@ -193,7 +193,7 @@ describe("Redemptions", () => { redemptionRequest.redeemerOutputScript, BitcoinNetwork.Testnet ), - walletPublicKey.toString(), + walletPublicKey, "timedOut" ) @@ -205,10 +205,10 @@ describe("Redemptions", () => { describe("findWalletForRedemption", () => { class TestRedemptionsService extends RedemptionsService { public async findWalletForRedemption( - redeemerOutputScript: string, + redeemerOutputScript: Hex, amount: BigNumber ): Promise<{ - walletPublicKey: string + walletPublicKey: Hex mainUtxo: BitcoinUtxo }> { return super.findWalletForRedemption(redeemerOutputScript, amount) @@ -220,8 +220,9 @@ describe("Redemptions", () => { let redemptionsService: TestRedemptionsService // script for testnet P2WSH address // tb1qau95mxzh2249aa3y8exx76ltc2sq0e7kw8hj04936rdcmnynhswqqz02vv - const redeemerOutputScript = + const redeemerOutputScript = Hex.from( "0x220020ef0b4d985752aa5ef6243e4c6f6bebc2a007e7d671ef27d4b1d0db8dcc93bc1c" + ) context( "when there are no wallets in the network that can handle redemption", @@ -326,7 +327,7 @@ describe("Redemptions", () => { findWalletForRedemptionData.walletWithPendingRedemption.data expect(result).to.deep.eq({ - walletPublicKey: expectedWalletData.walletPublicKey.toString(), + walletPublicKey: expectedWalletData.walletPublicKey, mainUtxo: expectedWalletData.mainUtxo, }) }) @@ -386,7 +387,7 @@ describe("Redemptions", () => { tbtcContracts.bridge.setPendingRedemptions(pendingRedemptions) result = await redemptionsService.findWalletForRedemption( - redeemerOutputScript.toString(), + redeemerOutputScript, amount ) }) @@ -407,7 +408,7 @@ describe("Redemptions", () => { findWalletForRedemptionData.liveWallet.data expect(result).to.deep.eq({ - walletPublicKey: expectedWalletData.walletPublicKey.toString(), + walletPublicKey: expectedWalletData.walletPublicKey, mainUtxo: expectedWalletData.mainUtxo, }) }) @@ -439,7 +440,7 @@ describe("Redemptions", () => { findWalletForRedemptionData.liveWallet.data expect(result).to.deep.eq({ - walletPublicKey: expectedWalletData.walletPublicKey.toString(), + walletPublicKey: expectedWalletData.walletPublicKey, mainUtxo: expectedWalletData.mainUtxo, }) }) @@ -488,7 +489,7 @@ describe("Redemptions", () => { it("should throw an error", async () => { await expect( redemptionsService.findWalletForRedemption( - redeemerOutputScript.toString(), + redeemerOutputScript, amount ) ).to.be.rejectedWith( @@ -824,8 +825,8 @@ export async function runRedemptionScenario( ) ) - const redeemerOutputScripts = data.pendingRedemptions.map((redemption) => - redemption.pendingRedemption.redeemerOutputScript.toString() + const redeemerOutputScripts = data.pendingRedemptions.map( + (redemption) => redemption.pendingRedemption.redeemerOutputScript ) const walletTx = new WalletTx(tbtcContracts, bitcoinClient, data.witness) From 887d8ff687afae02fa30f6b169ea50d7e96bf536 Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Fri, 20 Oct 2023 16:32:59 +0200 Subject: [PATCH 15/22] Used Hex for SPV proofs --- typescript/src/index.ts | 3 - typescript/src/lib/bitcoin/address.ts | 2 +- typescript/src/lib/bitcoin/client.ts | 3 +- typescript/src/lib/bitcoin/header.ts | 11 +- typescript/src/lib/bitcoin/spv.ts | 33 +- typescript/src/lib/electrum/client.ts | 8 +- typescript/src/lib/ethereum/bridge.ts | 4 +- typescript/test/data/deposit-sweep.ts | 105 +++-- typescript/test/data/electrum.ts | 69 +-- typescript/test/data/proof.ts | 421 +++++++++++-------- typescript/test/data/redemption.ts | 101 +++-- typescript/test/lib/bitcoin.test.ts | 34 +- typescript/test/lib/ethereum.test.ts | 8 +- typescript/test/utils/mock-bitcoin-client.ts | 9 +- 14 files changed, 474 insertions(+), 337 deletions(-) diff --git a/typescript/src/index.ts b/typescript/src/index.ts index 628275200..2ee4bcafd 100644 --- a/typescript/src/index.ts +++ b/typescript/src/index.ts @@ -12,6 +12,3 @@ export * from "./services/redemptions" // Export the entrypoint module. export * from "./services/tbtc" - -// TODO: Replace all properties that are expected to be un-prefixed hexadecimal -// strings with a Hex type to increase API consistency. diff --git a/typescript/src/lib/bitcoin/address.ts b/typescript/src/lib/bitcoin/address.ts index 02149b8b4..865addbcb 100644 --- a/typescript/src/lib/bitcoin/address.ts +++ b/typescript/src/lib/bitcoin/address.ts @@ -79,7 +79,7 @@ function addressToPublicKeyHash( * Converts an address to the respective output script. * @param address BTC address. * @param bitcoinNetwork Bitcoin network corresponding to the address. - * @returns The un-prefixed and not prepended with length output script. + * @returns The output script not prepended with length. */ function addressToOutputScript( address: string, diff --git a/typescript/src/lib/bitcoin/client.ts b/typescript/src/lib/bitcoin/client.ts index 6e3d512fe..2df7e1147 100644 --- a/typescript/src/lib/bitcoin/client.ts +++ b/typescript/src/lib/bitcoin/client.ts @@ -1,6 +1,7 @@ import { BitcoinNetwork } from "./network" import { BitcoinRawTx, BitcoinTx, BitcoinTxHash, BitcoinUtxo } from "./tx" import { BitcoinTxMerkleBranch } from "./spv" +import { Hex } from "../../lib/utils" /** * Represents a Bitcoin client. @@ -66,7 +67,7 @@ export interface BitcoinClient { * block. * @return Concatenation of block headers in a hexadecimal format. */ - getHeadersChain(blockHeight: number, chainLength: number): Promise + getHeadersChain(blockHeight: number, chainLength: number): Promise /** * Get Merkle branch for a given transaction. diff --git a/typescript/src/lib/bitcoin/header.ts b/typescript/src/lib/bitcoin/header.ts index 99faa237a..99f8f10cf 100644 --- a/typescript/src/lib/bitcoin/header.ts +++ b/typescript/src/lib/bitcoin/header.ts @@ -89,16 +89,15 @@ function deserializeHeader(rawHeader: Hex): BitcoinHeader { * @param rawHeadersChain - Raw Bitcoin block headers chain. * @returns Deserialized Bitcoin block headers. */ -function deserializeHeadersChain(rawHeadersChain: string): BitcoinHeader[] { - if (rawHeadersChain.length % 160 !== 0) { +function deserializeHeadersChain(rawHeadersChain: Hex): BitcoinHeader[] { + const headersChain = rawHeadersChain.toString() + if (headersChain.length % 160 !== 0) { throw new Error("Incorrect length of Bitcoin headers") } const result: BitcoinHeader[] = [] - for (let i = 0; i < rawHeadersChain.length; i += 160) { - result.push( - deserializeHeader(Hex.from(rawHeadersChain.substring(i, i + 160))) - ) + for (let i = 0; i < headersChain.length; i += 160) { + result.push(deserializeHeader(Hex.from(headersChain.substring(i, i + 160)))) } return result diff --git a/typescript/src/lib/bitcoin/spv.ts b/typescript/src/lib/bitcoin/spv.ts index 4deb1cec4..596fd4056 100644 --- a/typescript/src/lib/bitcoin/spv.ts +++ b/typescript/src/lib/bitcoin/spv.ts @@ -15,10 +15,9 @@ import { BitcoinHashUtils } from "./hash" */ export interface BitcoinSpvProof { /** - * The merkle proof of transaction inclusion in a block, as an un-prefixed - * hex string. + * The merkle proof of transaction inclusion in a block. */ - merkleProof: string + merkleProof: Hex /** * Transaction index in the block (0-indexed). @@ -26,10 +25,10 @@ export interface BitcoinSpvProof { txIndexInBlock: number /** - * Single byte-string of 80-byte block headers, lowest height first, as an - * un-prefixed hex string. + * Concatenated block headers in hexadecimal format. Each block header is + * 80-byte-long. The block header with the lowest height is first. */ - bitcoinHeaders: string + bitcoinHeaders: Hex } /** @@ -46,7 +45,7 @@ export interface BitcoinTxMerkleBranch { * in order to trace up to obtain the merkle root of the including block, * the deepest pairing first. Each hash is an unprefixed hex string. */ - merkle: string[] + merkle: Hex[] /** * The 0-based index of the transaction's position in the block. @@ -117,12 +116,12 @@ export async function assembleBitcoinSpvProof( * @param txMerkleBranch - Branch of a Merkle tree leading to a transaction. * @returns Transaction inclusion proof in hexadecimal form. */ -function createMerkleProof(txMerkleBranch: BitcoinTxMerkleBranch): string { +function createMerkleProof(txMerkleBranch: BitcoinTxMerkleBranch): Hex { let proof = Buffer.from("") txMerkleBranch.merkle.forEach(function (item) { - proof = Buffer.concat([proof, Buffer.from(item, "hex").reverse()]) + proof = Buffer.concat([proof, item.toBuffer().reverse()]) }) - return proof.toString("hex") + return Hex.from(proof) } /** @@ -315,19 +314,21 @@ function validateMerkleTreeHashes( } /** - * Splits a given Merkle proof string into an array of intermediate node hashes. - * @param merkleProof A string representation of the Merkle proof. + * Splits a given concatenated Merkle proof into an array of intermediate node + * hashes. + * @param merkleProof A concatenated representation of the Merkle proof. * @returns An array of intermediate node hashes. * @throws {Error} If the length of the Merkle proof is not a multiple of 64. */ -function splitMerkleProof(merkleProof: string): Hex[] { - if (merkleProof.length % 64 != 0) { +function splitMerkleProof(merkleProof: Hex): Hex[] { + const merkleProofStr = merkleProof.toString() + if (merkleProofStr.length % 64 != 0) { throw new Error("Incorrect length of Merkle proof") } const intermediateNodeHashes: Hex[] = [] - for (let i = 0; i < merkleProof.length; i += 64) { - intermediateNodeHashes.push(Hex.from(merkleProof.slice(i, i + 64))) + for (let i = 0; i < merkleProofStr.length; i += 64) { + intermediateNodeHashes.push(Hex.from(merkleProofStr.slice(i, i + 64))) } return intermediateNodeHashes diff --git a/typescript/src/lib/electrum/client.ts b/typescript/src/lib/electrum/client.ts index f27b5f7d2..881f28564 100644 --- a/typescript/src/lib/electrum/client.ts +++ b/typescript/src/lib/electrum/client.ts @@ -518,8 +518,8 @@ export class ElectrumClient implements BitcoinClient { /** * @see {BitcoinClient#getHeadersChain} */ - getHeadersChain(blockHeight: number, chainLength: number): Promise { - return this.withElectrum(async (electrum: Electrum) => { + getHeadersChain(blockHeight: number, chainLength: number): Promise { + return this.withElectrum(async (electrum: Electrum) => { const { hex } = await this.withBackoffRetrier<{ hex: string }>()(async () => { @@ -529,7 +529,7 @@ export class ElectrumClient implements BitcoinClient { ) }) - return hex + return Hex.from(hex) }) } @@ -557,7 +557,7 @@ export class ElectrumClient implements BitcoinClient { return { blockHeight: merkle.block_height, - merkle: merkle.merkle, + merkle: merkle.merkle.map((m) => Hex.from(m)), position: merkle.pos, } } diff --git a/typescript/src/lib/ethereum/bridge.ts b/typescript/src/lib/ethereum/bridge.ts index 92dcbed73..0ca647525 100644 --- a/typescript/src/lib/ethereum/bridge.ts +++ b/typescript/src/lib/ethereum/bridge.ts @@ -279,9 +279,9 @@ export class EthereumBridge } const sweepProofParam = { - merkleProof: `0x${sweepProof.merkleProof}`, + merkleProof: sweepProof.merkleProof.toPrefixedString(), txIndexInBlock: sweepProof.txIndexInBlock, - bitcoinHeaders: `0x${sweepProof.bitcoinHeaders}`, + bitcoinHeaders: sweepProof.bitcoinHeaders.toPrefixedString(), } const mainUtxoParam = { diff --git a/typescript/test/data/deposit-sweep.ts b/typescript/test/data/deposit-sweep.ts index bfe6014a3..69bda0baf 100644 --- a/typescript/test/data/deposit-sweep.ts +++ b/typescript/test/data/deposit-sweep.ts @@ -428,7 +428,7 @@ export interface DepositSweepProofTestData { rawTransaction: BitcoinRawTx accumulatedTxConfirmations: number latestBlockHeight: number - headersChain: string + headersChain: Hex transactionMerkleBranch: BitcoinTxMerkleBranch } expectedSweepProof: { @@ -522,33 +522,44 @@ export const depositSweepProof: DepositSweepProofTestData = { "120fb077fbed8804e0250162b175ac6800000000", }, latestBlockHeight: 2164335, - headersChain: + headersChain: Hex.from( "04000020642125b3910fdaead521b57955e28893d89f8ce7fd3ba1dd6d0100000" + - "0000000f9e17a266a2267ee02d5ab82a75a76805db821a13abd2e80e0950d8833" + - "11e5355dc21c62ed3e031adefc02c4040000205b6de55e069be71b21a62cd140d" + - "c7031225f7258dc758f19ea01000000000000139966d27d9ed0c0c1ed9162c2fe" + - "a2ccf0ba212706f6bc421d0a2b6211de040d1ac41c62ed3e031a4726538f04e00" + - "0208475e15e0314635d32abf04c761fee528d6a3f2db3b3d13798000000000000" + - "002a3fa06fecd9dd4bf2e25e22a95d4f65435d5c5b42bcf498b4e756f9f4ea67c" + - "ea1c51c62ed3e031a9d7bf3ac000000203f16d450c51853a4cd9569d225028aa0" + - "8ab6139eee31f4f67a010000000000004cda79bc48b970de2fb29c3f38626eb9d" + - "70d8bae7b92aad09f2a0ad2d2f334d35bca1c62ffff001d048fc2170000002068" + - "7e487acbf5eb375c631a15127fbf7d80ca084461e7f26f92c509b6000000006fa" + - "d33bd7c8d651bd6dc86c286f0a99340b668f019b9e97a59fd392c36c4f46910cf" + - "1c62ffff001d407facaa0400002040f4c65610f26f06c4365305b956934501713" + - "e01c2fc08b919e0bc1b00000000e401a6a884ba015e83c6fe2cd363e877ef0398" + - "2e81eaff4e2c95af1e23a670f407d41c62ffff001d58c64d180400002038854bd" + - "62f802e1de14653eceeb7a80290f5e99b8e9db517e36f000000000000a494b803" + - "4039e7855b75563ab83c9410dd67e89bb58e6cd93b85290a885dd749f4d61c62e" + - "d3e031ad9a83746", + "0000000f9e17a266a2267ee02d5ab82a75a76805db821a13abd2e80e0950d8833" + + "11e5355dc21c62ed3e031adefc02c4040000205b6de55e069be71b21a62cd140d" + + "c7031225f7258dc758f19ea01000000000000139966d27d9ed0c0c1ed9162c2fe" + + "a2ccf0ba212706f6bc421d0a2b6211de040d1ac41c62ed3e031a4726538f04e00" + + "0208475e15e0314635d32abf04c761fee528d6a3f2db3b3d13798000000000000" + + "002a3fa06fecd9dd4bf2e25e22a95d4f65435d5c5b42bcf498b4e756f9f4ea67c" + + "ea1c51c62ed3e031a9d7bf3ac000000203f16d450c51853a4cd9569d225028aa0" + + "8ab6139eee31f4f67a010000000000004cda79bc48b970de2fb29c3f38626eb9d" + + "70d8bae7b92aad09f2a0ad2d2f334d35bca1c62ffff001d048fc2170000002068" + + "7e487acbf5eb375c631a15127fbf7d80ca084461e7f26f92c509b6000000006fa" + + "d33bd7c8d651bd6dc86c286f0a99340b668f019b9e97a59fd392c36c4f46910cf" + + "1c62ffff001d407facaa0400002040f4c65610f26f06c4365305b956934501713" + + "e01c2fc08b919e0bc1b00000000e401a6a884ba015e83c6fe2cd363e877ef0398" + + "2e81eaff4e2c95af1e23a670f407d41c62ffff001d58c64d180400002038854bd" + + "62f802e1de14653eceeb7a80290f5e99b8e9db517e36f000000000000a494b803" + + "4039e7855b75563ab83c9410dd67e89bb58e6cd93b85290a885dd749f4d61c62e" + + "d3e031ad9a83746" + ), transactionMerkleBranch: { blockHeight: 2164155, merkle: [ - "322cfdf3ca53cf597b6f08e93489b9a1cfa1f5958c3657474b0d8f5efb5ca92e", - "82aedffef6c9670375effee25740fecce143d21f8abf98307235b7ebd31ad4d1", - "837fa041b9a8f5b42353fdf8981e3b7a78c61858852e43058bfe6cacf9eab5a3", - "a51612d3f3f857e95803a4d86aa6dbbe2e756dc2ed6cc0e04630e8baf597e377", - "a00501650e0c4f8a1e07a5d6d5bc5e75e4c75de61a65f0410cce354bbae78686", + Hex.from( + "322cfdf3ca53cf597b6f08e93489b9a1cfa1f5958c3657474b0d8f5efb5ca92e" + ), + Hex.from( + "82aedffef6c9670375effee25740fecce143d21f8abf98307235b7ebd31ad4d1" + ), + Hex.from( + "837fa041b9a8f5b42353fdf8981e3b7a78c61858852e43058bfe6cacf9eab5a3" + ), + Hex.from( + "a51612d3f3f857e95803a4d86aa6dbbe2e756dc2ed6cc0e04630e8baf597e377" + ), + Hex.from( + "a00501650e0c4f8a1e07a5d6d5bc5e75e4c75de61a65f0410cce354bbae78686" + ), ], position: 6, }, @@ -573,31 +584,33 @@ export const depositSweepProof: DepositSweepProofTestData = { locktime: "00000000", }, sweepProof: { - merkleProof: + merkleProof: Hex.from( "2ea95cfb5e8f0d4b4757368c95f5a1cfa1b98934e9086f7b59cf53caf3fd2c32d1d" + - "41ad3ebb735723098bf8a1fd243e1ccfe4057e2feef750367c9f6fedfae82a3b5ea" + - "f9ac6cfe8b05432e855818c6787a3b1e98f8fd5323b4f5a8b941a07f8377e397f5b" + - "ae83046e0c06cedc26d752ebedba66ad8a40358e957f8f3d31216a58686e7ba4b35" + - "ce0c41f0651ae65dc7e4755ebcd5d6a5071e8a4f0c0e650105a0", + "41ad3ebb735723098bf8a1fd243e1ccfe4057e2feef750367c9f6fedfae82a3b5ea" + + "f9ac6cfe8b05432e855818c6787a3b1e98f8fd5323b4f5a8b941a07f8377e397f5b" + + "ae83046e0c06cedc26d752ebedba66ad8a40358e957f8f3d31216a58686e7ba4b35" + + "ce0c41f0651ae65dc7e4755ebcd5d6a5071e8a4f0c0e650105a0" + ), txIndexInBlock: 6, - bitcoinHeaders: + bitcoinHeaders: Hex.from( "04000020642125b3910fdaead521b57955e28893d89f8ce7fd3ba1dd6d010000000" + - "00000f9e17a266a2267ee02d5ab82a75a76805db821a13abd2e80e0950d883311e5" + - "355dc21c62ed3e031adefc02c4040000205b6de55e069be71b21a62cd140dc70312" + - "25f7258dc758f19ea01000000000000139966d27d9ed0c0c1ed9162c2fea2ccf0ba" + - "212706f6bc421d0a2b6211de040d1ac41c62ed3e031a4726538f04e000208475e15" + - "e0314635d32abf04c761fee528d6a3f2db3b3d13798000000000000002a3fa06fec" + - "d9dd4bf2e25e22a95d4f65435d5c5b42bcf498b4e756f9f4ea67cea1c51c62ed3e0" + - "31a9d7bf3ac000000203f16d450c51853a4cd9569d225028aa08ab6139eee31f4f6" + - "7a010000000000004cda79bc48b970de2fb29c3f38626eb9d70d8bae7b92aad09f2" + - "a0ad2d2f334d35bca1c62ffff001d048fc21700000020687e487acbf5eb375c631a" + - "15127fbf7d80ca084461e7f26f92c509b6000000006fad33bd7c8d651bd6dc86c28" + - "6f0a99340b668f019b9e97a59fd392c36c4f46910cf1c62ffff001d407facaa0400" + - "002040f4c65610f26f06c4365305b956934501713e01c2fc08b919e0bc1b0000000" + - "0e401a6a884ba015e83c6fe2cd363e877ef03982e81eaff4e2c95af1e23a670f407" + - "d41c62ffff001d58c64d180400002038854bd62f802e1de14653eceeb7a80290f5e" + - "99b8e9db517e36f000000000000a494b8034039e7855b75563ab83c9410dd67e89b" + - "b58e6cd93b85290a885dd749f4d61c62ed3e031ad9a83746", + "00000f9e17a266a2267ee02d5ab82a75a76805db821a13abd2e80e0950d883311e5" + + "355dc21c62ed3e031adefc02c4040000205b6de55e069be71b21a62cd140dc70312" + + "25f7258dc758f19ea01000000000000139966d27d9ed0c0c1ed9162c2fea2ccf0ba" + + "212706f6bc421d0a2b6211de040d1ac41c62ed3e031a4726538f04e000208475e15" + + "e0314635d32abf04c761fee528d6a3f2db3b3d13798000000000000002a3fa06fec" + + "d9dd4bf2e25e22a95d4f65435d5c5b42bcf498b4e756f9f4ea67cea1c51c62ed3e0" + + "31a9d7bf3ac000000203f16d450c51853a4cd9569d225028aa08ab6139eee31f4f6" + + "7a010000000000004cda79bc48b970de2fb29c3f38626eb9d70d8bae7b92aad09f2" + + "a0ad2d2f334d35bca1c62ffff001d048fc21700000020687e487acbf5eb375c631a" + + "15127fbf7d80ca084461e7f26f92c509b6000000006fad33bd7c8d651bd6dc86c28" + + "6f0a99340b668f019b9e97a59fd392c36c4f46910cf1c62ffff001d407facaa0400" + + "002040f4c65610f26f06c4365305b956934501713e01c2fc08b919e0bc1b0000000" + + "0e401a6a884ba015e83c6fe2cd363e877ef03982e81eaff4e2c95af1e23a670f407" + + "d41c62ffff001d58c64d180400002038854bd62f802e1de14653eceeb7a80290f5e" + + "99b8e9db517e36f000000000000a494b8034039e7855b75563ab83c9410dd67e89b" + + "b58e6cd93b85290a885dd749f4d61c62ed3e031ad9a83746" + ), }, mainUtxo: NO_MAIN_UTXO, }, diff --git a/typescript/test/data/electrum.ts b/typescript/test/data/electrum.ts index 22d930672..38c12becb 100644 --- a/typescript/test/data/electrum.ts +++ b/typescript/test/data/electrum.ts @@ -75,23 +75,24 @@ export const testnetUTXO: BitcoinUtxo = { export const testnetHeadersChain = { blockHeight: 1569342, headersChainLength: 6, - headersChain: + headersChain: Hex.from( "00000020a114bf2d1e930390044cc4e00dd2f490a36dcecb4b6bb702b50200000000000" + - "0583b7a45472123fac1003384cc60fce2129c8d7364969dfa35021ab26c0b0449bccc2e" + - "5dffff001d061013a10000ff3f3210404a744c3170cdd6ad7fc901194c913004faa87f2" + - "91cd3faac2b00000000ecc1620341eeee4881423cab631e6e4a0b003c05ffc2dfc132a2" + - "a902a45df2c573d02e5d148c031af7358d5f00e0ff3fd83c1e679a4766043e3dbc62287" + - "0e64ba4c2cacfa2f45563210100000000000071d244c45daecf0abf15c5f4e47f123109" + - "12918ca56b89c3dfb68103371ae6bf98d42e5d148c031aca5d525e00000020d2a6ad530" + - "4a5bbe4948666fd6775dc2cde9c0cef7060a471fe01000000000000597701d1165c140f" + - "471f2684f1f6b3e97765ee5492619582af5e6d192895e7d34cd92e5dffff001dbb34c42" + - "400000020b9b3fcbb515c899b10bf3889d432ca2782cfad01f9c2cf329fb60e00000000" + - "0048d580fbe9ccf1cadaffe0e780eab57ea401f6260f38bd459d32cc3eef6cbd33ffd92" + - "e5d148c031a3c4277f40000002024af4d64067c20a1ed5cb9fbd432a98fe659e3653378" + - "e6b9ed00000000000000fea85a41c80b307f9cdfd22ac52521ba89ea6467769206d8988" + - "9663cb7742e7358db2e5d148c031a7d30031a0000ff3f6418122efc0ddf2416189b01c0" + - "d98ab7e5072fe1e99c3e275401000000000000496c06f87b8d442db7c6bd36ff05e3a7a" + - "0edb3e0124d26c61d44c584ba1f8ff86bdc2e5d148c031a411e00ae", + "0583b7a45472123fac1003384cc60fce2129c8d7364969dfa35021ab26c0b0449bccc2e" + + "5dffff001d061013a10000ff3f3210404a744c3170cdd6ad7fc901194c913004faa87f2" + + "91cd3faac2b00000000ecc1620341eeee4881423cab631e6e4a0b003c05ffc2dfc132a2" + + "a902a45df2c573d02e5d148c031af7358d5f00e0ff3fd83c1e679a4766043e3dbc62287" + + "0e64ba4c2cacfa2f45563210100000000000071d244c45daecf0abf15c5f4e47f123109" + + "12918ca56b89c3dfb68103371ae6bf98d42e5d148c031aca5d525e00000020d2a6ad530" + + "4a5bbe4948666fd6775dc2cde9c0cef7060a471fe01000000000000597701d1165c140f" + + "471f2684f1f6b3e97765ee5492619582af5e6d192895e7d34cd92e5dffff001dbb34c42" + + "400000020b9b3fcbb515c899b10bf3889d432ca2782cfad01f9c2cf329fb60e00000000" + + "0048d580fbe9ccf1cadaffe0e780eab57ea401f6260f38bd459d32cc3eef6cbd33ffd92" + + "e5d148c031a3c4277f40000002024af4d64067c20a1ed5cb9fbd432a98fe659e3653378" + + "e6b9ed00000000000000fea85a41c80b307f9cdfd22ac52521ba89ea6467769206d8988" + + "9663cb7742e7358db2e5d148c031a7d30031a0000ff3f6418122efc0ddf2416189b01c0" + + "d98ab7e5072fe1e99c3e275401000000000000496c06f87b8d442db7c6bd36ff05e3a7a" + + "0edb3e0124d26c61d44c584ba1f8ff86bdc2e5d148c031a411e00ae" + ), } /** @@ -100,15 +101,33 @@ export const testnetHeadersChain = { export const testnetTransactionMerkleBranch: BitcoinTxMerkleBranch = { blockHeight: 1569342, merkle: [ - "8b5bbb5bdf6727bf70fad4f46fe4eaab04c98119ffbd2d95c29adf32d26f8452", - "53637bacb07965e4a8220836861d1b16c6da29f10ea9ab53fc4eca73074f98b9", - "0267e738108d094ceb05217e2942e9c2a4c6389ac47f476f572c9a319ce4dfbc", - "34e00deec50c48d99678ca2b52b82d6d5432326159c69e7233d0dde0924874b4", - "7a53435e6c86a3620cdbae510901f17958f0540314214379197874ed8ed7a913", - "6315dbb7ce350ceaa16cd4c35c5a147005e8b38ca1e9531bd7320629e8d17f5b", - "40380cdadc0206646208871e952af9dcfdff2f104305ce463aed5eeaf7725d2f", - "5d74bae6a71fd1cff2416865460583319a40343650bd4bb89de0a6ae82097037", - "296ddccfc659e0009aad117c8ed15fb6ff81c2bade73fbc89666a22708d233f9", + Hex.from( + "8b5bbb5bdf6727bf70fad4f46fe4eaab04c98119ffbd2d95c29adf32d26f8452" + ), + Hex.from( + "53637bacb07965e4a8220836861d1b16c6da29f10ea9ab53fc4eca73074f98b9" + ), + Hex.from( + "0267e738108d094ceb05217e2942e9c2a4c6389ac47f476f572c9a319ce4dfbc" + ), + Hex.from( + "34e00deec50c48d99678ca2b52b82d6d5432326159c69e7233d0dde0924874b4" + ), + Hex.from( + "7a53435e6c86a3620cdbae510901f17958f0540314214379197874ed8ed7a913" + ), + Hex.from( + "6315dbb7ce350ceaa16cd4c35c5a147005e8b38ca1e9531bd7320629e8d17f5b" + ), + Hex.from( + "40380cdadc0206646208871e952af9dcfdff2f104305ce463aed5eeaf7725d2f" + ), + Hex.from( + "5d74bae6a71fd1cff2416865460583319a40343650bd4bb89de0a6ae82097037" + ), + Hex.from( + "296ddccfc659e0009aad117c8ed15fb6ff81c2bade73fbc89666a22708d233f9" + ), ], position: 176, } diff --git a/typescript/test/data/proof.ts b/typescript/test/data/proof.ts index bbd94a853..6d3e114c0 100644 --- a/typescript/test/data/proof.ts +++ b/typescript/test/data/proof.ts @@ -18,7 +18,7 @@ export interface ProofTestData { rawTransaction: BitcoinRawTx accumulatedTxConfirmations: number latestBlockHeight: number - headersChain: string + headersChain: Hex transactionMerkleBranch: BitcoinTxMerkleBranch } expectedProof: BitcoinSpvProof & BitcoinTx @@ -68,35 +68,50 @@ export const singleInputProofTestData: ProofTestData = { }, accumulatedTxConfirmations: 50, latestBlockHeight: 2164335, - headersChain: + headersChain: Hex.from( "04e00020732d33ea35d62f9488cff5d64c0d702afd5d88092230ddfcc45f00000" + - "0000000196283ba24a3f5bad91ef95338aa6d214c934f2c1392e39a0447377fe5" + - "b0a04be7c01c62ffff001df0be0a27040000206c318b23e5c42e86ef3edd080e5" + - "0c9c233b9f0b6d186bd57e41300000000000021fb8cda200bff4fec1338d85a1e" + - "005bb4d729d908a7c5c232ecd0713231d0445ec11c62ed3e031a7b43466e04e00" + - "020f416898d79d4a46fa6c54f190ad3d502bad8aa3afdec0714aa000000000000" + - "000603a5cc15e5906cb4eac9f747869fdc9be856e76a110b4f87da90db20f9fbe" + - "28fc11c62ed3e031a15dfc3db04000020642125b3910fdaead521b57955e28893" + - "d89f8ce7fd3ba1dd6d01000000000000f9e17a266a2267ee02d5ab82a75a76805" + - "db821a13abd2e80e0950d883311e5355dc21c62ed3e031adefc02c4040000205b" + - "6de55e069be71b21a62cd140dc7031225f7258dc758f19ea01000000000000139" + - "966d27d9ed0c0c1ed9162c2fea2ccf0ba212706f6bc421d0a2b6211de040d1ac4" + - "1c62ed3e031a4726538f04e000208475e15e0314635d32abf04c761fee528d6a3" + - "f2db3b3d13798000000000000002a3fa06fecd9dd4bf2e25e22a95d4f65435d5c" + - "5b42bcf498b4e756f9f4ea67cea1c51c62ed3e031a9d7bf3ac000000203f16d45" + - "0c51853a4cd9569d225028aa08ab6139eee31f4f67a010000000000004cda79bc" + - "48b970de2fb29c3f38626eb9d70d8bae7b92aad09f2a0ad2d2f334d35bca1c62f" + - "fff001d048fc217", + "0000000196283ba24a3f5bad91ef95338aa6d214c934f2c1392e39a0447377fe5" + + "b0a04be7c01c62ffff001df0be0a27040000206c318b23e5c42e86ef3edd080e5" + + "0c9c233b9f0b6d186bd57e41300000000000021fb8cda200bff4fec1338d85a1e" + + "005bb4d729d908a7c5c232ecd0713231d0445ec11c62ed3e031a7b43466e04e00" + + "020f416898d79d4a46fa6c54f190ad3d502bad8aa3afdec0714aa000000000000" + + "000603a5cc15e5906cb4eac9f747869fdc9be856e76a110b4f87da90db20f9fbe" + + "28fc11c62ed3e031a15dfc3db04000020642125b3910fdaead521b57955e28893" + + "d89f8ce7fd3ba1dd6d01000000000000f9e17a266a2267ee02d5ab82a75a76805" + + "db821a13abd2e80e0950d883311e5355dc21c62ed3e031adefc02c4040000205b" + + "6de55e069be71b21a62cd140dc7031225f7258dc758f19ea01000000000000139" + + "966d27d9ed0c0c1ed9162c2fea2ccf0ba212706f6bc421d0a2b6211de040d1ac4" + + "1c62ed3e031a4726538f04e000208475e15e0314635d32abf04c761fee528d6a3" + + "f2db3b3d13798000000000000002a3fa06fecd9dd4bf2e25e22a95d4f65435d5c" + + "5b42bcf498b4e756f9f4ea67cea1c51c62ed3e031a9d7bf3ac000000203f16d45" + + "0c51853a4cd9569d225028aa08ab6139eee31f4f67a010000000000004cda79bc" + + "48b970de2fb29c3f38626eb9d70d8bae7b92aad09f2a0ad2d2f334d35bca1c62f" + + "fff001d048fc217" + ), transactionMerkleBranch: { blockHeight: 2164152, merkle: [ - "7bffaff2c61291861276da41cf6c3842fad555af97dd1ff98ce41c61a0072b12", - "7a5876ddee8e553ff0650c739b2ec66e192d8afe5fc0ce763bf810457aea330c", - "2d17b67d5519bc39fbef8650afd3fe11fdfb3f471434a5b551cfa9a41441901f", - "1376d102b677591ce2fa62553e2a57ab5919022b03036521facfce93a0338026", - "43ad3aadad675e398c59eb846a8e037cf7de8ba3b38f3388175f25d84b777c80", - "6969c227128793b3c9e99c05f20fb9b91fdb73458fd53151b5fe29d30c10cf9a", - "0a76bc4d8c3d532357be4d188ba89e9ae364a7d3c365e690e3cb07359b86129c", + Hex.from( + "7bffaff2c61291861276da41cf6c3842fad555af97dd1ff98ce41c61a0072b12" + ), + Hex.from( + "7a5876ddee8e553ff0650c739b2ec66e192d8afe5fc0ce763bf810457aea330c" + ), + Hex.from( + "2d17b67d5519bc39fbef8650afd3fe11fdfb3f471434a5b551cfa9a41441901f" + ), + Hex.from( + "1376d102b677591ce2fa62553e2a57ab5919022b03036521facfce93a0338026" + ), + Hex.from( + "43ad3aadad675e398c59eb846a8e037cf7de8ba3b38f3388175f25d84b777c80" + ), + Hex.from( + "6969c227128793b3c9e99c05f20fb9b91fdb73458fd53151b5fe29d30c10cf9a" + ), + Hex.from( + "0a76bc4d8c3d532357be4d188ba89e9ae364a7d3c365e690e3cb07359b86129c" + ), ], position: 11, }, @@ -121,33 +136,35 @@ export const singleInputProofTestData: ProofTestData = { scriptPubKey: Hex.from("00148db50eb52063ea9d98b3eac91489a90f738986f6"), }, ], - merkleProof: + merkleProof: Hex.from( "122b07a0611ce48cf91fdd97af55d5fa42386ccf41da7612869112c6f2afff7b0c" + - "33ea7a4510f83b76cec05ffe8a2d196ec62e9b730c65f03f558eeedd76587a1f90" + - "4114a4a9cf51b5a53414473ffbfd11fed3af5086effb39bc19557db6172d268033" + - "a093cecffa216503032b021959ab572a3e5562fae21c5977b602d17613807c774b" + - "d8255f1788338fb3a38bdef77c038e6a84eb598c395e67adad3aad439acf100cd3" + - "29feb55131d58f4573db1fb9b90ff2059ce9c9b393871227c269699c12869b3507" + - "cbe390e665c3d3a764e39a9ea88b184dbe5723533d8c4dbc760a", + "33ea7a4510f83b76cec05ffe8a2d196ec62e9b730c65f03f558eeedd76587a1f90" + + "4114a4a9cf51b5a53414473ffbfd11fed3af5086effb39bc19557db6172d268033" + + "a093cecffa216503032b021959ab572a3e5562fae21c5977b602d17613807c774b" + + "d8255f1788338fb3a38bdef77c038e6a84eb598c395e67adad3aad439acf100cd3" + + "29feb55131d58f4573db1fb9b90ff2059ce9c9b393871227c269699c12869b3507" + + "cbe390e665c3d3a764e39a9ea88b184dbe5723533d8c4dbc760a" + ), txIndexInBlock: 11, - bitcoinHeaders: + bitcoinHeaders: Hex.from( "04e00020732d33ea35d62f9488cff5d64c0d702afd5d88092230ddfcc45f000000" + - "000000196283ba24a3f5bad91ef95338aa6d214c934f2c1392e39a0447377fe5b0" + - "a04be7c01c62ffff001df0be0a27040000206c318b23e5c42e86ef3edd080e50c9" + - "c233b9f0b6d186bd57e41300000000000021fb8cda200bff4fec1338d85a1e005b" + - "b4d729d908a7c5c232ecd0713231d0445ec11c62ed3e031a7b43466e04e00020f4" + - "16898d79d4a46fa6c54f190ad3d502bad8aa3afdec0714aa000000000000000603" + - "a5cc15e5906cb4eac9f747869fdc9be856e76a110b4f87da90db20f9fbe28fc11c" + - "62ed3e031a15dfc3db04000020642125b3910fdaead521b57955e28893d89f8ce7" + - "fd3ba1dd6d01000000000000f9e17a266a2267ee02d5ab82a75a76805db821a13a" + - "bd2e80e0950d883311e5355dc21c62ed3e031adefc02c4040000205b6de55e069b" + - "e71b21a62cd140dc7031225f7258dc758f19ea01000000000000139966d27d9ed0" + - "c0c1ed9162c2fea2ccf0ba212706f6bc421d0a2b6211de040d1ac41c62ed3e031a" + - "4726538f04e000208475e15e0314635d32abf04c761fee528d6a3f2db3b3d13798" + - "000000000000002a3fa06fecd9dd4bf2e25e22a95d4f65435d5c5b42bcf498b4e7" + - "56f9f4ea67cea1c51c62ed3e031a9d7bf3ac000000203f16d450c51853a4cd9569" + - "d225028aa08ab6139eee31f4f67a010000000000004cda79bc48b970de2fb29c3f" + - "38626eb9d70d8bae7b92aad09f2a0ad2d2f334d35bca1c62ffff001d048fc217", + "000000196283ba24a3f5bad91ef95338aa6d214c934f2c1392e39a0447377fe5b0" + + "a04be7c01c62ffff001df0be0a27040000206c318b23e5c42e86ef3edd080e50c9" + + "c233b9f0b6d186bd57e41300000000000021fb8cda200bff4fec1338d85a1e005b" + + "b4d729d908a7c5c232ecd0713231d0445ec11c62ed3e031a7b43466e04e00020f4" + + "16898d79d4a46fa6c54f190ad3d502bad8aa3afdec0714aa000000000000000603" + + "a5cc15e5906cb4eac9f747869fdc9be856e76a110b4f87da90db20f9fbe28fc11c" + + "62ed3e031a15dfc3db04000020642125b3910fdaead521b57955e28893d89f8ce7" + + "fd3ba1dd6d01000000000000f9e17a266a2267ee02d5ab82a75a76805db821a13a" + + "bd2e80e0950d883311e5355dc21c62ed3e031adefc02c4040000205b6de55e069b" + + "e71b21a62cd140dc7031225f7258dc758f19ea01000000000000139966d27d9ed0" + + "c0c1ed9162c2fea2ccf0ba212706f6bc421d0a2b6211de040d1ac41c62ed3e031a" + + "4726538f04e000208475e15e0314635d32abf04c761fee528d6a3f2db3b3d13798" + + "000000000000002a3fa06fecd9dd4bf2e25e22a95d4f65435d5c5b42bcf498b4e7" + + "56f9f4ea67cea1c51c62ed3e031a9d7bf3ac000000203f16d450c51853a4cd9569" + + "d225028aa08ab6139eee31f4f67a010000000000004cda79bc48b970de2fb29c3f" + + "38626eb9d70d8bae7b92aad09f2a0ad2d2f334d35bca1c62ffff001d048fc217" + ), }, } @@ -237,33 +254,44 @@ export const multipleInputsProofTestData: ProofTestData = { "120fb077fbed8804e0250162b175ac6800000000", }, latestBlockHeight: 2164335, - headersChain: + headersChain: Hex.from( "04000020642125b3910fdaead521b57955e28893d89f8ce7fd3ba1dd6d0100000" + - "0000000f9e17a266a2267ee02d5ab82a75a76805db821a13abd2e80e0950d8833" + - "11e5355dc21c62ed3e031adefc02c4040000205b6de55e069be71b21a62cd140d" + - "c7031225f7258dc758f19ea01000000000000139966d27d9ed0c0c1ed9162c2fe" + - "a2ccf0ba212706f6bc421d0a2b6211de040d1ac41c62ed3e031a4726538f04e00" + - "0208475e15e0314635d32abf04c761fee528d6a3f2db3b3d13798000000000000" + - "002a3fa06fecd9dd4bf2e25e22a95d4f65435d5c5b42bcf498b4e756f9f4ea67c" + - "ea1c51c62ed3e031a9d7bf3ac000000203f16d450c51853a4cd9569d225028aa0" + - "8ab6139eee31f4f67a010000000000004cda79bc48b970de2fb29c3f38626eb9d" + - "70d8bae7b92aad09f2a0ad2d2f334d35bca1c62ffff001d048fc2170000002068" + - "7e487acbf5eb375c631a15127fbf7d80ca084461e7f26f92c509b6000000006fa" + - "d33bd7c8d651bd6dc86c286f0a99340b668f019b9e97a59fd392c36c4f46910cf" + - "1c62ffff001d407facaa0400002040f4c65610f26f06c4365305b956934501713" + - "e01c2fc08b919e0bc1b00000000e401a6a884ba015e83c6fe2cd363e877ef0398" + - "2e81eaff4e2c95af1e23a670f407d41c62ffff001d58c64d180400002038854bd" + - "62f802e1de14653eceeb7a80290f5e99b8e9db517e36f000000000000a494b803" + - "4039e7855b75563ab83c9410dd67e89bb58e6cd93b85290a885dd749f4d61c62e" + - "d3e031ad9a83746", + "0000000f9e17a266a2267ee02d5ab82a75a76805db821a13abd2e80e0950d8833" + + "11e5355dc21c62ed3e031adefc02c4040000205b6de55e069be71b21a62cd140d" + + "c7031225f7258dc758f19ea01000000000000139966d27d9ed0c0c1ed9162c2fe" + + "a2ccf0ba212706f6bc421d0a2b6211de040d1ac41c62ed3e031a4726538f04e00" + + "0208475e15e0314635d32abf04c761fee528d6a3f2db3b3d13798000000000000" + + "002a3fa06fecd9dd4bf2e25e22a95d4f65435d5c5b42bcf498b4e756f9f4ea67c" + + "ea1c51c62ed3e031a9d7bf3ac000000203f16d450c51853a4cd9569d225028aa0" + + "8ab6139eee31f4f67a010000000000004cda79bc48b970de2fb29c3f38626eb9d" + + "70d8bae7b92aad09f2a0ad2d2f334d35bca1c62ffff001d048fc2170000002068" + + "7e487acbf5eb375c631a15127fbf7d80ca084461e7f26f92c509b6000000006fa" + + "d33bd7c8d651bd6dc86c286f0a99340b668f019b9e97a59fd392c36c4f46910cf" + + "1c62ffff001d407facaa0400002040f4c65610f26f06c4365305b956934501713" + + "e01c2fc08b919e0bc1b00000000e401a6a884ba015e83c6fe2cd363e877ef0398" + + "2e81eaff4e2c95af1e23a670f407d41c62ffff001d58c64d180400002038854bd" + + "62f802e1de14653eceeb7a80290f5e99b8e9db517e36f000000000000a494b803" + + "4039e7855b75563ab83c9410dd67e89bb58e6cd93b85290a885dd749f4d61c62e" + + "d3e031ad9a83746" + ), transactionMerkleBranch: { blockHeight: 2164155, merkle: [ - "322cfdf3ca53cf597b6f08e93489b9a1cfa1f5958c3657474b0d8f5efb5ca92e", - "82aedffef6c9670375effee25740fecce143d21f8abf98307235b7ebd31ad4d1", - "837fa041b9a8f5b42353fdf8981e3b7a78c61858852e43058bfe6cacf9eab5a3", - "a51612d3f3f857e95803a4d86aa6dbbe2e756dc2ed6cc0e04630e8baf597e377", - "a00501650e0c4f8a1e07a5d6d5bc5e75e4c75de61a65f0410cce354bbae78686", + Hex.from( + "322cfdf3ca53cf597b6f08e93489b9a1cfa1f5958c3657474b0d8f5efb5ca92e" + ), + Hex.from( + "82aedffef6c9670375effee25740fecce143d21f8abf98307235b7ebd31ad4d1" + ), + Hex.from( + "837fa041b9a8f5b42353fdf8981e3b7a78c61858852e43058bfe6cacf9eab5a3" + ), + Hex.from( + "a51612d3f3f857e95803a4d86aa6dbbe2e756dc2ed6cc0e04630e8baf597e377" + ), + Hex.from( + "a00501650e0c4f8a1e07a5d6d5bc5e75e4c75de61a65f0410cce354bbae78686" + ), ], position: 6, }, @@ -309,31 +337,33 @@ export const multipleInputsProofTestData: ProofTestData = { scriptPubKey: Hex.from("00148db50eb52063ea9d98b3eac91489a90f738986f6"), }, ], - merkleProof: + merkleProof: Hex.from( "2ea95cfb5e8f0d4b4757368c95f5a1cfa1b98934e9086f7b59cf53caf3fd2c32d1d" + - "41ad3ebb735723098bf8a1fd243e1ccfe4057e2feef750367c9f6fedfae82a3b5ea" + - "f9ac6cfe8b05432e855818c6787a3b1e98f8fd5323b4f5a8b941a07f8377e397f5b" + - "ae83046e0c06cedc26d752ebedba66ad8a40358e957f8f3d31216a58686e7ba4b35" + - "ce0c41f0651ae65dc7e4755ebcd5d6a5071e8a4f0c0e650105a0", + "41ad3ebb735723098bf8a1fd243e1ccfe4057e2feef750367c9f6fedfae82a3b5ea" + + "f9ac6cfe8b05432e855818c6787a3b1e98f8fd5323b4f5a8b941a07f8377e397f5b" + + "ae83046e0c06cedc26d752ebedba66ad8a40358e957f8f3d31216a58686e7ba4b35" + + "ce0c41f0651ae65dc7e4755ebcd5d6a5071e8a4f0c0e650105a0" + ), txIndexInBlock: 6, - bitcoinHeaders: + bitcoinHeaders: Hex.from( "04000020642125b3910fdaead521b57955e28893d89f8ce7fd3ba1dd6d010000000" + - "00000f9e17a266a2267ee02d5ab82a75a76805db821a13abd2e80e0950d883311e5" + - "355dc21c62ed3e031adefc02c4040000205b6de55e069be71b21a62cd140dc70312" + - "25f7258dc758f19ea01000000000000139966d27d9ed0c0c1ed9162c2fea2ccf0ba" + - "212706f6bc421d0a2b6211de040d1ac41c62ed3e031a4726538f04e000208475e15" + - "e0314635d32abf04c761fee528d6a3f2db3b3d13798000000000000002a3fa06fec" + - "d9dd4bf2e25e22a95d4f65435d5c5b42bcf498b4e756f9f4ea67cea1c51c62ed3e0" + - "31a9d7bf3ac000000203f16d450c51853a4cd9569d225028aa08ab6139eee31f4f6" + - "7a010000000000004cda79bc48b970de2fb29c3f38626eb9d70d8bae7b92aad09f2" + - "a0ad2d2f334d35bca1c62ffff001d048fc21700000020687e487acbf5eb375c631a" + - "15127fbf7d80ca084461e7f26f92c509b6000000006fad33bd7c8d651bd6dc86c28" + - "6f0a99340b668f019b9e97a59fd392c36c4f46910cf1c62ffff001d407facaa0400" + - "002040f4c65610f26f06c4365305b956934501713e01c2fc08b919e0bc1b0000000" + - "0e401a6a884ba015e83c6fe2cd363e877ef03982e81eaff4e2c95af1e23a670f407" + - "d41c62ffff001d58c64d180400002038854bd62f802e1de14653eceeb7a80290f5e" + - "99b8e9db517e36f000000000000a494b8034039e7855b75563ab83c9410dd67e89b" + - "b58e6cd93b85290a885dd749f4d61c62ed3e031ad9a83746", + "00000f9e17a266a2267ee02d5ab82a75a76805db821a13abd2e80e0950d883311e5" + + "355dc21c62ed3e031adefc02c4040000205b6de55e069be71b21a62cd140dc70312" + + "25f7258dc758f19ea01000000000000139966d27d9ed0c0c1ed9162c2fea2ccf0ba" + + "212706f6bc421d0a2b6211de040d1ac41c62ed3e031a4726538f04e000208475e15" + + "e0314635d32abf04c761fee528d6a3f2db3b3d13798000000000000002a3fa06fec" + + "d9dd4bf2e25e22a95d4f65435d5c5b42bcf498b4e756f9f4ea67cea1c51c62ed3e0" + + "31a9d7bf3ac000000203f16d450c51853a4cd9569d225028aa08ab6139eee31f4f6" + + "7a010000000000004cda79bc48b970de2fb29c3f38626eb9d70d8bae7b92aad09f2" + + "a0ad2d2f334d35bca1c62ffff001d048fc21700000020687e487acbf5eb375c631a" + + "15127fbf7d80ca084461e7f26f92c509b6000000006fad33bd7c8d651bd6dc86c28" + + "6f0a99340b668f019b9e97a59fd392c36c4f46910cf1c62ffff001d407facaa0400" + + "002040f4c65610f26f06c4365305b956934501713e01c2fc08b919e0bc1b0000000" + + "0e401a6a884ba015e83c6fe2cd363e877ef03982e81eaff4e2c95af1e23a670f407" + + "d41c62ffff001d58c64d180400002038854bd62f802e1de14653eceeb7a80290f5e" + + "99b8e9db517e36f000000000000a494b8034039e7855b75563ab83c9410dd67e89b" + + "b58e6cd93b85290a885dd749f4d61c62ed3e031ad9a83746" + ), }, } @@ -346,7 +376,7 @@ export interface TransactionProofData { transaction: BitcoinTx accumulatedTxConfirmations: number latestBlockHeight: number - headersChain: string + headersChain: Hex transactionMerkleBranch: BitcoinTxMerkleBranch previousDifficulty: BigNumber currentDifficulty: BigNumber @@ -414,35 +444,58 @@ export const transactionConfirmationsInOneEpochData: TransactionProofData = { }, accumulatedTxConfirmations: 1798, latestBlockHeight: 777963, - headersChain: + headersChain: Hex.from( "00e0ff2f5ad9c09e1d8aae777a58bf29c41621eb629032598f7900000000000000000" + - "0004dea17724c3b7e67d4cf1ac41a4c7527b884f7406575eaf5b8efaf2fb12572ecb1" + - "ace86339300717760098100000ff3fd3ab40174610c286e569edd20fa713bd98bab53" + - "bee83050000000000000000002345f5ef807cf75de7b30ccfe493c46c6e07aca044aa" + - "2aa106141637f1bb8500a6ade863393007177fbbd4b300800120646d493817f0ac988" + - "6a0a194ca3a957f70c3eb642ffd05000000000000000000d95674b737f097f042eebe" + - "b970c09b274df7e72a9c202ff2292ed72b056ee90967aee863393007172e2bb92e006" + - "03b27a391d248c258ef628dfb8c710ce44c8017667a07941402000000000000000000" + - "35214e58eb018dea1efa7eaf1b7f19ff2d6f0310c122be6dc8c0258d9524ae9382aee" + - "863393007173e82b2000000002003c7003ff9a79f16d956fc764b43b35080efe3a820" + - "af050000000000000000007808e96809cd46d5898d86faabc8f28a8b6572eb8399796" + - "70b2851d78fc1f75f17b3e86339300717450f17650400e020fb9b6a28bb2e9cea36d3" + - "40588f19ffa4e944b050e73f03000000000000000000bbd7534f2550ee99f31efcd77" + - "564f1b5b3f3966a76847896a8d9f9ee964d670ba2b4e8633930071777b10cfc", + "0004dea17724c3b7e67d4cf1ac41a4c7527b884f7406575eaf5b8efaf2fb12572ecb1" + + "ace86339300717760098100000ff3fd3ab40174610c286e569edd20fa713bd98bab53" + + "bee83050000000000000000002345f5ef807cf75de7b30ccfe493c46c6e07aca044aa" + + "2aa106141637f1bb8500a6ade863393007177fbbd4b300800120646d493817f0ac988" + + "6a0a194ca3a957f70c3eb642ffd05000000000000000000d95674b737f097f042eebe" + + "b970c09b274df7e72a9c202ff2292ed72b056ee90967aee863393007172e2bb92e006" + + "03b27a391d248c258ef628dfb8c710ce44c8017667a07941402000000000000000000" + + "35214e58eb018dea1efa7eaf1b7f19ff2d6f0310c122be6dc8c0258d9524ae9382aee" + + "863393007173e82b2000000002003c7003ff9a79f16d956fc764b43b35080efe3a820" + + "af050000000000000000007808e96809cd46d5898d86faabc8f28a8b6572eb8399796" + + "70b2851d78fc1f75f17b3e86339300717450f17650400e020fb9b6a28bb2e9cea36d3" + + "40588f19ffa4e944b050e73f03000000000000000000bbd7534f2550ee99f31efcd77" + + "564f1b5b3f3966a76847896a8d9f9ee964d670ba2b4e8633930071777b10cfc" + ), transactionMerkleBranch: { blockHeight: 776166, merkle: [ - "f6ce0e34cc5b2a4b8cd4fd02a65d7cf62013206969e8e5cf1df18f994abcf1ff", - "08899ec43299b324583722f3e7d0938446a1f31a6ab34c8e24cb4ea9ba6cd384", - "9677b6075dfa2da8bcc98aa10ae7d30f81e6506215eadd3f3739a5d987e62b35", - "aa6712d8820c06ec8ce99f9c19d580ab54bb45f69b426935153b81e7d412ddba", - "b38be47e1dd9a7324ad81a395a133f26fc88cb736a4998dbba6cbabca10629a8", - "13bdefbf92421aa7861528e16e7046b569d25ee0f4b7649492e42e9ea2331c39", - "df429494c5eef971a7ab80c8a0f7f9cdfa30148afef706f07923bd93d5a7e22a", - "c8a3f1bc73146bd4a1a0e848f2b0b4a21be86e4930f239d856af8e9646014236", - "1f514df87fe2c400e508e01cd8967657ef76db9681f65dc82b0bc6d4004b575f", - "e463950c8efd9114237189f07ddf1cfdb72658bad23bce667c269652bd0ade3c", - "3d7ae6df787807320fdc397a7055e86c932a7c36ab1d1f942b92c53bf2a1d2f9", + Hex.from( + "f6ce0e34cc5b2a4b8cd4fd02a65d7cf62013206969e8e5cf1df18f994abcf1ff" + ), + Hex.from( + "08899ec43299b324583722f3e7d0938446a1f31a6ab34c8e24cb4ea9ba6cd384" + ), + Hex.from( + "9677b6075dfa2da8bcc98aa10ae7d30f81e6506215eadd3f3739a5d987e62b35" + ), + Hex.from( + "aa6712d8820c06ec8ce99f9c19d580ab54bb45f69b426935153b81e7d412ddba" + ), + Hex.from( + "b38be47e1dd9a7324ad81a395a133f26fc88cb736a4998dbba6cbabca10629a8" + ), + Hex.from( + "13bdefbf92421aa7861528e16e7046b569d25ee0f4b7649492e42e9ea2331c39" + ), + Hex.from( + "df429494c5eef971a7ab80c8a0f7f9cdfa30148afef706f07923bd93d5a7e22a" + ), + Hex.from( + "c8a3f1bc73146bd4a1a0e848f2b0b4a21be86e4930f239d856af8e9646014236" + ), + Hex.from( + "1f514df87fe2c400e508e01cd8967657ef76db9681f65dc82b0bc6d4004b575f" + ), + Hex.from( + "e463950c8efd9114237189f07ddf1cfdb72658bad23bce667c269652bd0ade3c" + ), + Hex.from( + "3d7ae6df787807320fdc397a7055e86c932a7c36ab1d1f942b92c53bf2a1d2f9" + ), ], position: 17, }, @@ -491,34 +544,55 @@ export const transactionConfirmationsInTwoEpochsData: TransactionProofData = { }, accumulatedTxConfirmations: 3838, latestBlockHeight: 777979, - headersChain: + headersChain: Hex.from( "0040f224871a401b605e02c475e05e147bd418e5e2ae9eb599e200000000000000000" + - "000193dc07aea4388a163ed0e3e5234ef54594cfc046bce727d2d6b3445d3ce0e8c44" + - "0dd663e27c07170c0d54de00e0682c9c27df3b2a1b011753c986c290ce22c60d09a05" + - "3707100000000000000000000ddf3b023ed6368bdac8578bd55d0c3fad7f234ae971b" + - "902b155bee7318bf0919b30dd663e27c0717be025f2b00000020514a9bd87c51caedd" + - "45a20c495f0ba1983b6f3f51639050000000000000000001f4c60a97f4127b4f90fbb" + - "7a6a1041881b10d4f7351340b6770301f62b36725ce10dd66320270717c11c5e7b002" + - "0002043e99cc906d52209796ecb37b252e4514f197d727ea701000000000000000000" + - "274ecaf37779be81c23748d33ef4a0cad36a8abd935a11f0e0a71640c6dd1deaf10dd" + - "66320270717846927aa0000c02090a4a88ab1ad55e235932fe0adc7b4c822b4322f58" + - "9305000000000000000000decc945dc9cdf595715ffeee3bffc0ec0c8c5ff77e43b8e" + - "91213e21a9975c99ddc10d663202707179f93251000203229e618c1eb9274a1acbb74" + - "d44bfe9a4ecfae236ea35e8b0300000000000000000029a9f7b4f6671dec5d6ba05ac" + - "b060fcd2ffc6e46a992189c6f60d770d9c5a5cda31cd66320270717542691a2", + "000193dc07aea4388a163ed0e3e5234ef54594cfc046bce727d2d6b3445d3ce0e8c44" + + "0dd663e27c07170c0d54de00e0682c9c27df3b2a1b011753c986c290ce22c60d09a05" + + "3707100000000000000000000ddf3b023ed6368bdac8578bd55d0c3fad7f234ae971b" + + "902b155bee7318bf0919b30dd663e27c0717be025f2b00000020514a9bd87c51caedd" + + "45a20c495f0ba1983b6f3f51639050000000000000000001f4c60a97f4127b4f90fbb" + + "7a6a1041881b10d4f7351340b6770301f62b36725ce10dd66320270717c11c5e7b002" + + "0002043e99cc906d52209796ecb37b252e4514f197d727ea701000000000000000000" + + "274ecaf37779be81c23748d33ef4a0cad36a8abd935a11f0e0a71640c6dd1deaf10dd" + + "66320270717846927aa0000c02090a4a88ab1ad55e235932fe0adc7b4c822b4322f58" + + "9305000000000000000000decc945dc9cdf595715ffeee3bffc0ec0c8c5ff77e43b8e" + + "91213e21a9975c99ddc10d663202707179f93251000203229e618c1eb9274a1acbb74" + + "d44bfe9a4ecfae236ea35e8b0300000000000000000029a9f7b4f6671dec5d6ba05ac" + + "b060fcd2ffc6e46a992189c6f60d770d9c5a5cda31cd66320270717542691a2" + ), transactionMerkleBranch: { blockHeight: 774142, merkle: [ - "e80f706f53d5abd77070ea6c8a60c141748400e09fc9b373d5cdb0129cbce5ec", - "20d22506199cf00caf2e32e240c77a23c226d5a74de4dc9150ccd6f5200b4dd7", - "8b446693fadaae7479725f0e98430c24f8bf8936f5a5cab7c725692cd78e61e3", - "93e61f1ac82cf6a66e321c60410ae4bdfcc0ab45b7efd50353d7b08104758403", - "1dc52561092701978f1e48a10bc4da5464e668f0f4b3a940853c941474ee52de", - "84aca5ec5b339b69a50b93d35c2fd7b146c037842ca76b33cbf835b9e6c86f0c", - "ebcd1bb7039d40ac0d477af58964b4582c6741d1c901ab4a2b0de15e600cba69", - "38d458a70805902a52342cfc552d374bdb217cd389e9550adfc4f86df6fdce82", - "07781ff50552aefea962f0f4972fe882cb38a281ebdd533c2886d5137b80fbeb", - "e7e530e181683d272293f19fe18a33f1dc05eded12ec27945b49311b2e14ee42", + Hex.from( + "e80f706f53d5abd77070ea6c8a60c141748400e09fc9b373d5cdb0129cbce5ec" + ), + Hex.from( + "20d22506199cf00caf2e32e240c77a23c226d5a74de4dc9150ccd6f5200b4dd7" + ), + Hex.from( + "8b446693fadaae7479725f0e98430c24f8bf8936f5a5cab7c725692cd78e61e3" + ), + Hex.from( + "93e61f1ac82cf6a66e321c60410ae4bdfcc0ab45b7efd50353d7b08104758403" + ), + Hex.from( + "1dc52561092701978f1e48a10bc4da5464e668f0f4b3a940853c941474ee52de" + ), + Hex.from( + "84aca5ec5b339b69a50b93d35c2fd7b146c037842ca76b33cbf835b9e6c86f0c" + ), + Hex.from( + "ebcd1bb7039d40ac0d477af58964b4582c6741d1c901ab4a2b0de15e600cba69" + ), + Hex.from( + "38d458a70805902a52342cfc552d374bdb217cd389e9550adfc4f86df6fdce82" + ), + Hex.from( + "07781ff50552aefea962f0f4972fe882cb38a281ebdd533c2886d5137b80fbeb" + ), + Hex.from( + "e7e530e181683d272293f19fe18a33f1dc05eded12ec27945b49311b2e14ee42" + ), ], position: 262, }, @@ -566,31 +640,46 @@ export const testnetTransactionData: TransactionProofData = { }, accumulatedTxConfirmations: 18, latestBlockHeight: 2421198, - headersChain: + headersChain: Hex.from( "000000203528cf6e8112d970a1adeb9743937d2e980afb43cb8ce3600100000000000" + - "0007bacd9aa2249c74fdba75dd651a16755e9b4dc3c1953f2baa01d657f317e3eb936" + - "62f763ffff001d7045e837000040207184a40ae97e64b2bce8fed41f967eac210e036" + - "9a66855bd2b37c86200000000fe261c184d19c15c7b66c284d5f65e79595f65d576cc" + - "40f20cccf0fcbae3c063a866f7639cde2c193ed763b904e000209885f5bb4bc96f8ff" + - "ed3bf31c6f526f1f71fc6dd3f9bb0ed0200000000000000720c67b13ee8805763110f" + - "b345cbfb5369836344e6a990e4ac0c363211362b2c6168f7639cde2c19294a1006000" + - "040200aafa9b9e947a9bd6fe2e9f04dece7753863d59b11e5c63b1500000000000000" + - "7a63f980ffc1f993c0d7dbe0670e71be2eeae8710a7906f758d3b400dd6a1e6b3c69f" + - "7639cde2c1940a3735000008020ba335b0d58de55cf227fdd35ba380a4a288d4f7926" + - "8be6a01800000000000000ffdc211cb41a97249e18a54aa4861a77f43093d6716995a" + - "9f659370ee1cf8aea406af7639cde2c19254197450000002069b318d3a7c7c154651f" + - "23ac4c3a51c7ec5158f40a62783c0400000000000000f452ef784d467c9f541331552" + - "32d005bdd0f2d323933646976ef2b7275206d7ff96ef763ffff001db18d224b", + "0007bacd9aa2249c74fdba75dd651a16755e9b4dc3c1953f2baa01d657f317e3eb936" + + "62f763ffff001d7045e837000040207184a40ae97e64b2bce8fed41f967eac210e036" + + "9a66855bd2b37c86200000000fe261c184d19c15c7b66c284d5f65e79595f65d576cc" + + "40f20cccf0fcbae3c063a866f7639cde2c193ed763b904e000209885f5bb4bc96f8ff" + + "ed3bf31c6f526f1f71fc6dd3f9bb0ed0200000000000000720c67b13ee8805763110f" + + "b345cbfb5369836344e6a990e4ac0c363211362b2c6168f7639cde2c19294a1006000" + + "040200aafa9b9e947a9bd6fe2e9f04dece7753863d59b11e5c63b1500000000000000" + + "7a63f980ffc1f993c0d7dbe0670e71be2eeae8710a7906f758d3b400dd6a1e6b3c69f" + + "7639cde2c1940a3735000008020ba335b0d58de55cf227fdd35ba380a4a288d4f7926" + + "8be6a01800000000000000ffdc211cb41a97249e18a54aa4861a77f43093d6716995a" + + "9f659370ee1cf8aea406af7639cde2c19254197450000002069b318d3a7c7c154651f" + + "23ac4c3a51c7ec5158f40a62783c0400000000000000f452ef784d467c9f541331552" + + "32d005bdd0f2d323933646976ef2b7275206d7ff96ef763ffff001db18d224b" + ), transactionMerkleBranch: { blockHeight: 2421181, merkle: [ - "33610df4f460e1338d9f6a055de18d5c694edf590722211b6feeec77a9479846", - "0fd7e0afdde99bdfbfdc0d0e6f5ccda4cd1873eee315bb989622fd58bd5c4446", - "2d4ab6c53cedc1a447e21ad2f38c6d9d0d9c761426975a65f83fe10f12e3c9e0", - "0eebd6daa03f6db4a27541a91bcf86612c97d100bc37c3eb321d64d943adb2a5", - "b25854f31fc046eb0f53cddbf2b6de3d54d52710acd79a796c78c3be235f031a", - "1fc5ab77039f59ac2494791fc05c75fb53e2dacf57a20f67e7d6727b38778825", - "5b0acfdbb89af64a583a88e92252b8634bd4da06ee102ecd34c2662955e9f1c7", + Hex.from( + "33610df4f460e1338d9f6a055de18d5c694edf590722211b6feeec77a9479846" + ), + Hex.from( + "0fd7e0afdde99bdfbfdc0d0e6f5ccda4cd1873eee315bb989622fd58bd5c4446" + ), + Hex.from( + "2d4ab6c53cedc1a447e21ad2f38c6d9d0d9c761426975a65f83fe10f12e3c9e0" + ), + Hex.from( + "0eebd6daa03f6db4a27541a91bcf86612c97d100bc37c3eb321d64d943adb2a5" + ), + Hex.from( + "b25854f31fc046eb0f53cddbf2b6de3d54d52710acd79a796c78c3be235f031a" + ), + Hex.from( + "1fc5ab77039f59ac2494791fc05c75fb53e2dacf57a20f67e7d6727b38778825" + ), + Hex.from( + "5b0acfdbb89af64a583a88e92252b8634bd4da06ee102ecd34c2662955e9f1c7" + ), ], position: 4, }, diff --git a/typescript/test/data/redemption.ts b/typescript/test/data/redemption.ts index 9bdec0dc2..a6c9be34d 100644 --- a/typescript/test/data/redemption.ts +++ b/typescript/test/data/redemption.ts @@ -544,7 +544,7 @@ export interface RedemptionProofTestData { rawTransaction: BitcoinRawTx accumulatedTxConfirmations: number latestBlockHeight: number - headersChain: string + headersChain: Hex transactionMerkleBranch: BitcoinTxMerkleBranch } expectedRedemptionProof: { @@ -627,31 +627,42 @@ export const redemptionProof: RedemptionProofTestData = { "b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d900000000", }, latestBlockHeight: 2226015, - headersChain: + headersChain: Hex.from( "04e000203d93e4b82b59ccaae5aff315b9319248c1119f8f848e421516000000000000" + - "00f28145109cd15498a2c4264dcda1c3d40d1ab1117f6365cc345e5bab9eb8e5a2f990" + - "5e62341f5c19adebd9480000c020a33f8505bae0c529af29b00741e2828e4b4ef2cf4d" + - "a2af790d00000000000000f1dad96fa7c65ae0b2582268ebf6e47b1af887ae9b5af064" + - "ff87b361259f9bb212915e62341f5c19913d8a790000002074ac47fe867411f520786b" + - "bb056d33cc5e412799355f22541600000000000000e428a225d38073c8e8584cf162b4" + - "cdc17eaf766f2fc1beae23f0ebac8b29964ec4955e62ffff001d5ec11e770000a020bc" + - "1e329ea2658a4e0dfe27cb80e2f9712d78e02c5428eb86db93c7e3000000006381e8dd" + - "f3245ddd74afb580b6d1e508273673d14b3620c098bde4c50bdbf65de1975e62341f5c" + - "195a29773400006020e7fc1afb505baced47a255d8a14cb7162b6f94d6aea6a89f4300" + - "000000000000ad26d482c0f48d0aeb1e1d9a8189df9f8dae693203c117a777c6c15522" + - "2da759ef975e62341f5c19595dff820000802004bdf8678a1fd09fd50987f884793410" + - "62e7f2ad11098bd00800000000000000add66b467729d264031adec83bc06e30781153" + - "0b98f49b095bd4c1fee2472e841d995e62341f5c19945d657200004020f8228183708c" + - "5f703e673f381ecee895a8642eed9f700b9c2b00000000000000465ec2f30447552a4a" + - "30ee63964aaebcb040649269eab449fb51823d58835a4aed9a5e62341f5c192fd94baa", + "00f28145109cd15498a2c4264dcda1c3d40d1ab1117f6365cc345e5bab9eb8e5a2f990" + + "5e62341f5c19adebd9480000c020a33f8505bae0c529af29b00741e2828e4b4ef2cf4d" + + "a2af790d00000000000000f1dad96fa7c65ae0b2582268ebf6e47b1af887ae9b5af064" + + "ff87b361259f9bb212915e62341f5c19913d8a790000002074ac47fe867411f520786b" + + "bb056d33cc5e412799355f22541600000000000000e428a225d38073c8e8584cf162b4" + + "cdc17eaf766f2fc1beae23f0ebac8b29964ec4955e62ffff001d5ec11e770000a020bc" + + "1e329ea2658a4e0dfe27cb80e2f9712d78e02c5428eb86db93c7e3000000006381e8dd" + + "f3245ddd74afb580b6d1e508273673d14b3620c098bde4c50bdbf65de1975e62341f5c" + + "195a29773400006020e7fc1afb505baced47a255d8a14cb7162b6f94d6aea6a89f4300" + + "000000000000ad26d482c0f48d0aeb1e1d9a8189df9f8dae693203c117a777c6c15522" + + "2da759ef975e62341f5c19595dff820000802004bdf8678a1fd09fd50987f884793410" + + "62e7f2ad11098bd00800000000000000add66b467729d264031adec83bc06e30781153" + + "0b98f49b095bd4c1fee2472e841d995e62341f5c19945d657200004020f8228183708c" + + "5f703e673f381ecee895a8642eed9f700b9c2b00000000000000465ec2f30447552a4a" + + "30ee63964aaebcb040649269eab449fb51823d58835a4aed9a5e62341f5c192fd94baa" + ), transactionMerkleBranch: { blockHeight: 2196313, merkle: [ - "2e89760feb82c022f9b6757c0a758f8fea953ffce9051cbe5a7cc20e0603c940", - "ad1cae6d060b5dac5d7ff1a933680f15dac822f52316c89e95363856b8a742ae", - "acf6ecc3da4654362678ac2bf0abf82aba1f2071e143718df2b079124e88fec7", - "65ea59172f35ee6db6e4194227bea23daedbda8299bea94710f21c97f3e9cc17", - "8c5b4ce089d0c450bf6125e7d342114246802bf4c9638d222aa9fcbe8e06024e", + Hex.from( + "2e89760feb82c022f9b6757c0a758f8fea953ffce9051cbe5a7cc20e0603c940" + ), + Hex.from( + "ad1cae6d060b5dac5d7ff1a933680f15dac822f52316c89e95363856b8a742ae" + ), + Hex.from( + "acf6ecc3da4654362678ac2bf0abf82aba1f2071e143718df2b079124e88fec7" + ), + Hex.from( + "65ea59172f35ee6db6e4194227bea23daedbda8299bea94710f21c97f3e9cc17" + ), + Hex.from( + "8c5b4ce089d0c450bf6125e7d342114246802bf4c9638d222aa9fcbe8e06024e" + ), ], position: 4, }, @@ -672,31 +683,33 @@ export const redemptionProof: RedemptionProofTestData = { locktime: "00000000", }, redemptionProof: { - merkleProof: + merkleProof: Hex.from( "40c903060ec27c5abe1c05e9fc3f95ea8f8f750a7c75b6f922c082eb0f76892eae4" + - "2a7b8563836959ec81623f522c8da150f6833a9f17f5dac5d0b066dae1cadc7fe88" + - "4e1279b0f28d7143e171201fba2af8abf02bac7826365446dac3ecf6ac17cce9f39" + - "71cf21047a9be9982dadbae3da2be274219e4b66dee352f1759ea654e02068ebefc" + - "a92a228d63c9f42b8046421142d3e72561bf50c4d089e04c5b8c", + "2a7b8563836959ec81623f522c8da150f6833a9f17f5dac5d0b066dae1cadc7fe88" + + "4e1279b0f28d7143e171201fba2af8abf02bac7826365446dac3ecf6ac17cce9f39" + + "71cf21047a9be9982dadbae3da2be274219e4b66dee352f1759ea654e02068ebefc" + + "a92a228d63c9f42b8046421142d3e72561bf50c4d089e04c5b8c" + ), txIndexInBlock: 4, - bitcoinHeaders: + bitcoinHeaders: Hex.from( "04e000203d93e4b82b59ccaae5aff315b9319248c1119f8f848e421516000000000" + - "00000f28145109cd15498a2c4264dcda1c3d40d1ab1117f6365cc345e5bab9eb8e5" + - "a2f9905e62341f5c19adebd9480000c020a33f8505bae0c529af29b00741e2828e4" + - "b4ef2cf4da2af790d00000000000000f1dad96fa7c65ae0b2582268ebf6e47b1af8" + - "87ae9b5af064ff87b361259f9bb212915e62341f5c19913d8a790000002074ac47f" + - "e867411f520786bbb056d33cc5e412799355f22541600000000000000e428a225d3" + - "8073c8e8584cf162b4cdc17eaf766f2fc1beae23f0ebac8b29964ec4955e62ffff0" + - "01d5ec11e770000a020bc1e329ea2658a4e0dfe27cb80e2f9712d78e02c5428eb86" + - "db93c7e3000000006381e8ddf3245ddd74afb580b6d1e508273673d14b3620c098b" + - "de4c50bdbf65de1975e62341f5c195a29773400006020e7fc1afb505baced47a255" + - "d8a14cb7162b6f94d6aea6a89f4300000000000000ad26d482c0f48d0aeb1e1d9a8" + - "189df9f8dae693203c117a777c6c155222da759ef975e62341f5c19595dff820000" + - "802004bdf8678a1fd09fd50987f88479341062e7f2ad11098bd0080000000000000" + - "0add66b467729d264031adec83bc06e307811530b98f49b095bd4c1fee2472e841d" + - "995e62341f5c19945d657200004020f8228183708c5f703e673f381ecee895a8642" + - "eed9f700b9c2b00000000000000465ec2f30447552a4a30ee63964aaebcb0406492" + - "69eab449fb51823d58835a4aed9a5e62341f5c192fd94baa", + "00000f28145109cd15498a2c4264dcda1c3d40d1ab1117f6365cc345e5bab9eb8e5" + + "a2f9905e62341f5c19adebd9480000c020a33f8505bae0c529af29b00741e2828e4" + + "b4ef2cf4da2af790d00000000000000f1dad96fa7c65ae0b2582268ebf6e47b1af8" + + "87ae9b5af064ff87b361259f9bb212915e62341f5c19913d8a790000002074ac47f" + + "e867411f520786bbb056d33cc5e412799355f22541600000000000000e428a225d3" + + "8073c8e8584cf162b4cdc17eaf766f2fc1beae23f0ebac8b29964ec4955e62ffff0" + + "01d5ec11e770000a020bc1e329ea2658a4e0dfe27cb80e2f9712d78e02c5428eb86" + + "db93c7e3000000006381e8ddf3245ddd74afb580b6d1e508273673d14b3620c098b" + + "de4c50bdbf65de1975e62341f5c195a29773400006020e7fc1afb505baced47a255" + + "d8a14cb7162b6f94d6aea6a89f4300000000000000ad26d482c0f48d0aeb1e1d9a8" + + "189df9f8dae693203c117a777c6c155222da759ef975e62341f5c19595dff820000" + + "802004bdf8678a1fd09fd50987f88479341062e7f2ad11098bd0080000000000000" + + "0add66b467729d264031adec83bc06e307811530b98f49b095bd4c1fee2472e841d" + + "995e62341f5c19945d657200004020f8228183708c5f703e673f381ecee895a8642" + + "eed9f700b9c2b00000000000000465ec2f30447552a4a30ee63964aaebcb0406492" + + "69eab449fb51823d58835a4aed9a5e62341f5c192fd94baa" + ), }, mainUtxo: { transactionHash: BitcoinTxHash.from( diff --git a/typescript/test/lib/bitcoin.test.ts b/typescript/test/lib/bitcoin.test.ts index b04831493..4684d98b2 100644 --- a/typescript/test/lib/bitcoin.test.ts +++ b/typescript/test/lib/bitcoin.test.ts @@ -898,7 +898,7 @@ describe("Bitcoin", () => { }) }) - describe("assembleTransactionProof", () => { + describe("assembleBitcoinSpvProof", () => { let bitcoinClient: MockBitcoinClient beforeEach(async () => { @@ -919,9 +919,9 @@ describe("Bitcoin", () => { ) expect(proof.inputs).to.deep.equal(expectedProof.inputs) expect(proof.outputs).to.deep.equal(expectedProof.outputs) - expect(proof.merkleProof).to.equal(expectedProof.merkleProof) + expect(proof.merkleProof).to.deep.equal(expectedProof.merkleProof) expect(proof.txIndexInBlock).to.equal(expectedProof.txIndexInBlock) - expect(proof.bitcoinHeaders).to.equal(expectedProof.bitcoinHeaders) + expect(proof.bitcoinHeaders).to.deep.equal(expectedProof.bitcoinHeaders) }) }) @@ -939,9 +939,9 @@ describe("Bitcoin", () => { ) expect(proof.inputs).to.deep.equal(expectedProof.inputs) expect(proof.outputs).to.deep.equal(expectedProof.outputs) - expect(proof.merkleProof).to.equal(expectedProof.merkleProof) + expect(proof.merkleProof).to.deep.equal(expectedProof.merkleProof) expect(proof.txIndexInBlock).to.equal(expectedProof.txIndexInBlock) - expect(proof.bitcoinHeaders).to.equal(expectedProof.bitcoinHeaders) + expect(proof.bitcoinHeaders).to.deep.equal(expectedProof.bitcoinHeaders) }) }) @@ -1042,9 +1042,10 @@ describe("Bitcoin", () => { ...transactionConfirmationsInOneEpochData, bitcoinChainData: { ...transactionConfirmationsInOneEpochData.bitcoinChainData, - headersChain: - transactionConfirmationsInOneEpochData.bitcoinChainData - .headersChain + "ff", + headersChain: Hex.from( + transactionConfirmationsInOneEpochData.bitcoinChainData.headersChain.toString() + + "ff" + ), }, } await expect( @@ -1062,9 +1063,10 @@ describe("Bitcoin", () => { ...transactionConfirmationsInOneEpochData, bitcoinChainData: { ...transactionConfirmationsInOneEpochData.bitcoinChainData, - headersChain: - transactionConfirmationsInOneEpochData.bitcoinChainData - .headersChain + "f".repeat(160), + headersChain: Hex.from( + transactionConfirmationsInOneEpochData.bitcoinChainData.headersChain.toString() + + "f".repeat(160) + ), }, } await expect( @@ -1081,7 +1083,9 @@ describe("Bitcoin", () => { ...transactionConfirmationsInOneEpochData.bitcoinChainData .transactionMerkleBranch.merkle, ] - merkle[merkle.length - 1] += "ff" + merkle[merkle.length - 1] = Hex.from( + merkle[merkle.length - 1].toString() + "ff" + ) const corruptedProofData: TransactionProofData = { ...transactionConfirmationsInOneEpochData, @@ -1131,7 +1135,7 @@ describe("Bitcoin", () => { .transactionMerkleBranch.merkle, ] - merkle[3] = "ff" + merkle[3].slice(2) + merkle[3] = Hex.from("ff" + merkle[3].toString().slice(2)) const corruptedProofData: TransactionProofData = { ...transactionConfirmationsInOneEpochData, @@ -1173,7 +1177,7 @@ describe("Bitcoin", () => { ...transactionConfirmationsInOneEpochData, bitcoinChainData: { ...transactionConfirmationsInOneEpochData.bitcoinChainData, - headersChain: corruptedHeadersChain, + headersChain: Hex.from(corruptedHeadersChain), }, } @@ -1201,7 +1205,7 @@ describe("Bitcoin", () => { ...transactionConfirmationsInOneEpochData, bitcoinChainData: { ...transactionConfirmationsInOneEpochData.bitcoinChainData, - headersChain: corruptedHeadersChain, + headersChain: Hex.from(corruptedHeadersChain), }, } diff --git a/typescript/test/lib/ethereum.test.ts b/typescript/test/lib/ethereum.test.ts index 88608f0e1..c7a69a2e9 100644 --- a/typescript/test/lib/ethereum.test.ts +++ b/typescript/test/lib/ethereum.test.ts @@ -198,9 +198,9 @@ describe("Ethereum", () => { locktime: "33333333", }, { - merkleProof: "44444444", + merkleProof: Hex.from("44444444"), txIndexInBlock: 5, - bitcoinHeaders: "66666666", + bitcoinHeaders: Hex.from("66666666"), }, { transactionHash: BitcoinTxHash.from( @@ -296,9 +296,9 @@ describe("Ethereum", () => { locktime: "33333333", }, { - merkleProof: "44444444", + merkleProof: Hex.from("44444444"), txIndexInBlock: 5, - bitcoinHeaders: "66666666", + bitcoinHeaders: Hex.from("66666666"), }, { transactionHash: BitcoinTxHash.from( diff --git a/typescript/test/utils/mock-bitcoin-client.ts b/typescript/test/utils/mock-bitcoin-client.ts index 96b01b249..69b55e212 100644 --- a/typescript/test/utils/mock-bitcoin-client.ts +++ b/typescript/test/utils/mock-bitcoin-client.ts @@ -7,6 +7,7 @@ import { BitcoinTx, BitcoinTxHash, } from "../../src/lib/bitcoin" +import { Hex } from "../../src/lib/utils" /** * Mock Bitcoin client used for test purposes. @@ -17,7 +18,7 @@ export class MockBitcoinClient implements BitcoinClient { private _transactions = new Map() private _confirmations = new Map() private _latestHeight = 0 - private _headersChain = "" + private _headersChain = Hex.from("") private _transactionMerkle: BitcoinTxMerkleBranch = { blockHeight: 0, merkle: [], @@ -46,7 +47,7 @@ export class MockBitcoinClient implements BitcoinClient { this._latestHeight = value } - set headersChain(value: string) { + set headersChain(value: Hex) { this._headersChain = value } @@ -116,8 +117,8 @@ export class MockBitcoinClient implements BitcoinClient { }) } - getHeadersChain(blockHeight: number, chainLength: number): Promise { - return new Promise((resolve, _) => { + getHeadersChain(blockHeight: number, chainLength: number): Promise { + return new Promise((resolve, _) => { resolve(this._headersChain) }) } From 4108de62cbe9bb2a6d89a3970b3ff95e8cf7f9f1 Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Fri, 20 Oct 2023 16:53:19 +0200 Subject: [PATCH 16/22] Used Hex for raw transaction vectors --- typescript/src/lib/bitcoin/tx.ts | 28 +++++++++++------------ typescript/src/lib/ethereum/bridge.ts | 16 +++++++------- typescript/test/data/deposit-sweep.ts | 32 ++++++++++++++------------- typescript/test/data/redemption.ts | 22 +++++++++--------- typescript/test/lib/bitcoin.test.ts | 8 +++---- typescript/test/lib/ethereum.test.ts | 24 ++++++++++---------- 6 files changed, 67 insertions(+), 63 deletions(-) diff --git a/typescript/src/lib/bitcoin/tx.ts b/typescript/src/lib/bitcoin/tx.ts index 2ad886155..da76eae56 100644 --- a/typescript/src/lib/bitcoin/tx.ts +++ b/typescript/src/lib/bitcoin/tx.ts @@ -102,26 +102,26 @@ export type BitcoinUtxo = BitcoinTxOutpoint & { */ export interface BitcoinRawTxVectors { /** - * Transaction version as an un-prefixed hex string. + * Transaction version as a hex string. */ - version: string + version: Hex /** * All transaction's inputs prepended by the number of transaction inputs, - * as an un-prefixed hex string. + * as a hex string. */ - inputs: string + inputs: Hex /** * All transaction's outputs prepended by the number of transaction outputs, - * as an un-prefixed hex string. + * as a hex string. */ - outputs: string + outputs: Hex /** - * Transaction locktime as an un-prefixed hex string. + * Transaction locktime as a hex string. */ - locktime: string + locktime: Hex } /** @@ -133,11 +133,11 @@ export interface BitcoinRawTxVectors { export function extractBitcoinRawTxVectors( rawTransaction: BitcoinRawTx ): BitcoinRawTxVectors { - const toHex = (bufferWriter: any): string => { - return bufferWriter.render().toString("hex") + const toHex = (bufferWriter: any): Hex => { + return Hex.from(bufferWriter.render()) } - const getTxInputVector = (tx: Tx): string => { + const getTxInputVector = (tx: Tx): Hex => { const buffer = bufio.write() buffer.writeVarint(tx.ins.length) tx.ins.forEach((input) => { @@ -149,7 +149,7 @@ export function extractBitcoinRawTxVectors( return toHex(buffer) } - const getTxOutputVector = (tx: Tx): string => { + const getTxOutputVector = (tx: Tx): Hex => { const buffer = bufio.write() buffer.writeVarint(tx.outs.length) tx.outs.forEach((output) => { @@ -159,13 +159,13 @@ export function extractBitcoinRawTxVectors( return toHex(buffer) } - const getTxVersion = (tx: Tx): string => { + const getTxVersion = (tx: Tx): Hex => { const buffer = bufio.write() buffer.writeU32(tx.version) return toHex(buffer) } - const getTxLocktime = (tx: Tx): string => { + const getTxLocktime = (tx: Tx): Hex => { const buffer = bufio.write() buffer.writeU32(tx.locktime) return toHex(buffer) diff --git a/typescript/src/lib/ethereum/bridge.ts b/typescript/src/lib/ethereum/bridge.ts index 0ca647525..fea20d000 100644 --- a/typescript/src/lib/ethereum/bridge.ts +++ b/typescript/src/lib/ethereum/bridge.ts @@ -234,18 +234,18 @@ export class EthereumBridge vault?: ChainIdentifier ): Promise { const depositTxParam = { - version: `0x${depositTx.version}`, - inputVector: `0x${depositTx.inputs}`, - outputVector: `0x${depositTx.outputs}`, - locktime: `0x${depositTx.locktime}`, + version: depositTx.version.toPrefixedString(), + inputVector: depositTx.inputs.toPrefixedString(), + outputVector: depositTx.outputs.toPrefixedString(), + locktime: depositTx.locktime.toPrefixedString(), } const revealParam = { fundingOutputIndex: depositOutputIndex, - blindingFactor: `0x${deposit.blindingFactor}`, - walletPubKeyHash: `0x${deposit.walletPublicKeyHash}`, - refundPubKeyHash: `0x${deposit.refundPublicKeyHash}`, - refundLocktime: `0x${deposit.refundLocktime}`, + blindingFactor: deposit.blindingFactor.toPrefixedString(), + walletPubKeyHash: deposit.walletPublicKeyHash.toPrefixedString(), + refundPubKeyHash: deposit.refundPublicKeyHash.toPrefixedString(), + refundLocktime: deposit.refundLocktime.toPrefixedString(), vault: vault ? `0x${vault.identifierHex}` : constants.AddressZero, } diff --git a/typescript/test/data/deposit-sweep.ts b/typescript/test/data/deposit-sweep.ts index 69bda0baf..35b551e43 100644 --- a/typescript/test/data/deposit-sweep.ts +++ b/typescript/test/data/deposit-sweep.ts @@ -566,22 +566,24 @@ export const depositSweepProof: DepositSweepProofTestData = { }, expectedSweepProof: { sweepTx: { - version: "01000000", - inputs: + version: Hex.from("01000000"), + inputs: Hex.from( "048f99b22593afdc4e3c08c7821151e801b2e9a16bf307c087a1b8c1f8459e4dea0" + - "0000000c9483045022100bb54f2717647b2f2c5370b5f12b55e27f97a6e2009dcd2" + - "1fca08527df949e1fd022058bc3cd1dd739b89b9e4cda43b13bc59cfb15663b80cb" + - "fa3edb4539107bba35d012103989d253b17a6a0f41838b84ff0d20e8898f9d7b1a9" + - "8f2564da4cc29dcf8581d94c5c14934b98637ca318a4d6e7ca6ffd1690b8e77df63" + - "77508f9f0c90d000395237576a9148db50eb52063ea9d98b3eac91489a90f738986" + - "f68763ac6776a914e257eccafbc07c381642ce6e7e55120fb077fbed8804e025016" + - "2b175ac68fffffffffd337f1abd32f17566e17a3606714d981bb8982339805ebb84" + - "c881174cff44c80000000000ffffffff73a486cf5ca706f513b6bf170ed0e7465d5" + - "bbe2968b4c2a9a207ac0ebc68c5440000000000ffffffff78439e510ac6b659b529" + - "a608611a77ca05f00ca050648212e16447460ec048f50000000000ffffffff", - outputs: - "01789b0000000000001600148db50eb52063ea9d98b3eac91489a90f738986f6", - locktime: "00000000", + "0000000c9483045022100bb54f2717647b2f2c5370b5f12b55e27f97a6e2009dcd2" + + "1fca08527df949e1fd022058bc3cd1dd739b89b9e4cda43b13bc59cfb15663b80cb" + + "fa3edb4539107bba35d012103989d253b17a6a0f41838b84ff0d20e8898f9d7b1a9" + + "8f2564da4cc29dcf8581d94c5c14934b98637ca318a4d6e7ca6ffd1690b8e77df63" + + "77508f9f0c90d000395237576a9148db50eb52063ea9d98b3eac91489a90f738986" + + "f68763ac6776a914e257eccafbc07c381642ce6e7e55120fb077fbed8804e025016" + + "2b175ac68fffffffffd337f1abd32f17566e17a3606714d981bb8982339805ebb84" + + "c881174cff44c80000000000ffffffff73a486cf5ca706f513b6bf170ed0e7465d5" + + "bbe2968b4c2a9a207ac0ebc68c5440000000000ffffffff78439e510ac6b659b529" + + "a608611a77ca05f00ca050648212e16447460ec048f50000000000ffffffff" + ), + outputs: Hex.from( + "01789b0000000000001600148db50eb52063ea9d98b3eac91489a90f738986f6" + ), + locktime: Hex.from("00000000"), }, sweepProof: { merkleProof: Hex.from( diff --git a/typescript/test/data/redemption.ts b/typescript/test/data/redemption.ts index a6c9be34d..7b0d6ef8a 100644 --- a/typescript/test/data/redemption.ts +++ b/typescript/test/data/redemption.ts @@ -669,18 +669,20 @@ export const redemptionProof: RedemptionProofTestData = { }, expectedRedemptionProof: { redemptionTx: { - version: "01000000", - inputs: + version: Hex.from("01000000"), + inputs: Hex.from( "01e30b907d077893bd0ed819c66644027b1dd30e4d3f68bc51da7933f75bbb283d0" + - "100000000ffffffff", - outputs: + "100000000ffffffff" + ), + outputs: Hex.from( "051c3e0000000000001976a9144130879211c54df460e484ddf9aac009cb38ee748" + - "8ac242c0000000000001600144130879211c54df460e484ddf9aac009cb38ee74ac" + - "2600000000000017a9143ec459d0f3c29286ae5df5fcc421e2786024277e8764320" + - "0000000000022002086a303cdd2e2eab1d1679f1a813835dc5a1b65321077cdccaf" + - "08f98cbf04ca96ccfb1400000000001600148db50eb52063ea9d98b3eac91489a90" + - "f738986f6", - locktime: "00000000", + "8ac242c0000000000001600144130879211c54df460e484ddf9aac009cb38ee74ac" + + "2600000000000017a9143ec459d0f3c29286ae5df5fcc421e2786024277e8764320" + + "0000000000022002086a303cdd2e2eab1d1679f1a813835dc5a1b65321077cdccaf" + + "08f98cbf04ca96ccfb1400000000001600148db50eb52063ea9d98b3eac91489a90" + + "f738986f6" + ), + locktime: Hex.from("00000000"), }, redemptionProof: { merkleProof: Hex.from( diff --git a/typescript/test/lib/bitcoin.test.ts b/typescript/test/lib/bitcoin.test.ts index 4684d98b2..5f54c4606 100644 --- a/typescript/test/lib/bitcoin.test.ts +++ b/typescript/test/lib/bitcoin.test.ts @@ -879,8 +879,8 @@ describe("Bitcoin", () => { depositSweepWithNoMainUtxoAndWitnessOutput.expectedSweep.transaction const decomposedTransaction = extractBitcoinRawTxVectors(rawTransaction) - expect(decomposedTransaction.version).to.be.equal("01000000") - expect(decomposedTransaction.inputs).to.be.equal( + expect(decomposedTransaction.version.toString()).to.be.equal("01000000") + expect(decomposedTransaction.inputs.toString()).to.be.equal( "02bc187be612bc3db8cfcdec56b75e9bc0262ab6eacfe27cc1a699bacd53e3d07400" + "000000c948304502210089a89aaf3fec97ac9ffa91cdff59829f0cb3ef852a468153" + "e2c0e2b473466d2e022072902bb923ef016ac52e941ced78f816bf27991c2b73211e" + @@ -891,10 +891,10 @@ describe("Bitcoin", () => { "68ffffffffdc557e737b6688c5712649b86f7757a722dc3d42786f23b2fa826394df" + "ec545c0000000000ffffffff" ) - expect(decomposedTransaction.outputs).to.be.equal( + expect(decomposedTransaction.outputs.toString()).to.be.equal( "01488a0000000000001600148db50eb52063ea9d98b3eac91489a90f738986f6" ) - expect(decomposedTransaction.locktime).to.be.equal("00000000") + expect(decomposedTransaction.locktime.toString()).to.be.equal("00000000") }) }) diff --git a/typescript/test/lib/ethereum.test.ts b/typescript/test/lib/ethereum.test.ts index c7a69a2e9..801e77fe8 100644 --- a/typescript/test/lib/ethereum.test.ts +++ b/typescript/test/lib/ethereum.test.ts @@ -143,10 +143,10 @@ describe("Ethereum", () => { await bridgeHandle.revealDeposit( // Just short byte strings for clarity. { - version: "00000000", - inputs: "11111111", - outputs: "22222222", - locktime: "33333333", + version: Hex.from("00000000"), + inputs: Hex.from("11111111"), + outputs: Hex.from("22222222"), + locktime: Hex.from("33333333"), }, 2, { @@ -192,10 +192,10 @@ describe("Ethereum", () => { await bridgeHandle.submitDepositSweepProof( { - version: "00000000", - inputs: "11111111", - outputs: "22222222", - locktime: "33333333", + version: Hex.from("00000000"), + inputs: Hex.from("11111111"), + outputs: Hex.from("22222222"), + locktime: Hex.from("33333333"), }, { merkleProof: Hex.from("44444444"), @@ -290,10 +290,10 @@ describe("Ethereum", () => { await bridgeHandle.submitRedemptionProof( { - version: "00000000", - inputs: "11111111", - outputs: "22222222", - locktime: "33333333", + version: Hex.from("00000000"), + inputs: Hex.from("11111111"), + outputs: Hex.from("22222222"), + locktime: Hex.from("33333333"), }, { merkleProof: Hex.from("44444444"), From c3213f04f60084838316f70cfd52d39c2af1bfc9 Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Fri, 20 Oct 2023 17:50:54 +0200 Subject: [PATCH 17/22] Updated refund script --- typescript/scripts/refund.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/typescript/scripts/refund.ts b/typescript/scripts/refund.ts index 11931b978..27a941b04 100644 --- a/typescript/scripts/refund.ts +++ b/typescript/scripts/refund.ts @@ -9,6 +9,7 @@ import { DepositScript, ElectrumClient, ElectrumCredentials, + Hex, } from "../src" program @@ -60,15 +61,15 @@ const depositJson = JSON.parse(fs.readFileSync(depositJsonPath, "utf-8")) const deposit: DepositReceipt = { depositor: depositJson.depositor, - walletPublicKeyHash: depositJson.walletPublicKeyHash, - refundPublicKeyHash: depositJson.refundPublicKeyHash, - blindingFactor: depositJson.blindingFactor, - refundLocktime: depositJson.refundLocktime, + walletPublicKeyHash: Hex.from(depositJson.walletPublicKeyHash), + refundPublicKeyHash: Hex.from(depositJson.refundPublicKeyHash), + blindingFactor: Hex.from(depositJson.blindingFactor), + refundLocktime: Hex.from(depositJson.refundLocktime), } const recoveryAddress = depositJson.btcRecoveryAddress console.log("======= refund provided data ========") -console.log("deposit JSON: ", deposit) +console.log("deposit JSON: ", depositJson) console.log("deposit recovery amount: ", refundAmount) console.log("deposit transaction ID: ", transactionId) console.log("deposit transaction index: ", transactionIndex) From b471fe5cbbb7ccf340413aedca2b7ef505ff595d Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Fri, 20 Oct 2023 18:17:13 +0200 Subject: [PATCH 18/22] Used Hex in mocked bridge --- typescript/test/data/redemption.ts | 7 ++-- typescript/test/services/maintenance.test.ts | 2 +- typescript/test/services/redemptions.test.ts | 13 +++---- typescript/test/utils/mock-bridge.ts | 38 ++++++++++---------- 4 files changed, 31 insertions(+), 29 deletions(-) diff --git a/typescript/test/data/redemption.ts b/typescript/test/data/redemption.ts index 7b0d6ef8a..deeea11a3 100644 --- a/typescript/test/data/redemption.ts +++ b/typescript/test/data/redemption.ts @@ -551,7 +551,7 @@ export interface RedemptionProofTestData { redemptionTx: BitcoinRawTxVectors redemptionProof: BitcoinSpvProof mainUtxo: BitcoinUtxo - walletPublicKey: string + walletPublicKey: Hex } } @@ -720,8 +720,9 @@ export const redemptionProof: RedemptionProofTestData = { outputIndex: 1, value: BigNumber.from(1429580), }, - walletPublicKey: - "03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9", + walletPublicKey: Hex.from( + "03989d253b17a6a0f41838b84ff0d20e8898f9d7b1a98f2564da4cc29dcf8581d9" + ), }, } diff --git a/typescript/test/services/maintenance.test.ts b/typescript/test/services/maintenance.test.ts index cbca52a78..8b0f3d7bd 100644 --- a/typescript/test/services/maintenance.test.ts +++ b/typescript/test/services/maintenance.test.ts @@ -2541,7 +2541,7 @@ describe("Maintenance", () => { const bridgeLog = tbtcContracts.bridge.redemptionProofLog expect(bridgeLog.length).to.equal(1) expect(bridgeLog[0].mainUtxo).to.equal(mainUtxo) - expect(bridgeLog[0].walletPublicKey).to.equal( + expect(bridgeLog[0].walletPublicKey).to.deep.equal( redemptionProof.expectedRedemptionProof.walletPublicKey ) expect(bridgeLog[0].redemptionTx).to.deep.equal( diff --git a/typescript/test/services/redemptions.test.ts b/typescript/test/services/redemptions.test.ts index c8dbd7344..2d429696f 100644 --- a/typescript/test/services/redemptions.test.ts +++ b/typescript/test/services/redemptions.test.ts @@ -376,8 +376,8 @@ describe("Redemptions", () => { >() const key = MockBridge.buildRedemptionKey( - walletPublicKeyHash.toString(), - redeemerOutputScript.toString() + walletPublicKeyHash, + redeemerOutputScript ) pendingRedemptions.set( @@ -465,13 +465,14 @@ describe("Redemptions", () => { >() const pendingRedemption1 = MockBridge.buildRedemptionKey( - walletPublicKeyHash.toString(), - redeemerOutputScript.toString() + walletPublicKeyHash, + redeemerOutputScript ) const pendingRedemption2 = MockBridge.buildRedemptionKey( - findWalletForRedemptionData.liveWallet.event.walletPublicKeyHash.toString(), - redeemerOutputScript.toString() + findWalletForRedemptionData.liveWallet.event + .walletPublicKeyHash, + redeemerOutputScript ) pendingRedemptions.set( diff --git a/typescript/test/utils/mock-bridge.ts b/typescript/test/utils/mock-bridge.ts index 31cb72365..43b1cc8d0 100644 --- a/typescript/test/utils/mock-bridge.ts +++ b/typescript/test/utils/mock-bridge.ts @@ -36,9 +36,9 @@ interface RevealDepositLogEntry { } interface RequestRedemptionLogEntry { - walletPublicKey: string + walletPublicKey: Hex mainUtxo: BitcoinUtxo - redeemerOutputScript: string + redeemerOutputScript: Hex amount: BigNumber } @@ -46,7 +46,7 @@ interface RedemptionProofLogEntry { redemptionTx: BitcoinRawTxVectors redemptionProof: BitcoinSpvProof mainUtxo: BitcoinUtxo - walletPublicKey: string + walletPublicKey: Hex } interface NewWalletRegisteredEventsLog { @@ -55,7 +55,7 @@ interface NewWalletRegisteredEventsLog { } interface WalletLog { - walletPublicKeyHash: string + walletPublicKeyHash: Hex } /** @@ -229,7 +229,7 @@ export class MockBridge implements Bridge { redemptionTx, redemptionProof, mainUtxo, - walletPublicKey: walletPublicKey.toString(), + walletPublicKey, }) return new Promise((resolve, _) => { resolve() @@ -243,9 +243,9 @@ export class MockBridge implements Bridge { amount: BigNumber ) { this._requestRedemptionLog.push({ - walletPublicKey: walletPublicKey.toString(), + walletPublicKey, mainUtxo, - redeemerOutputScript: redeemerOutputScript.toString(), + redeemerOutputScript, amount, }) return new Promise((resolve, _) => { @@ -266,8 +266,8 @@ export class MockBridge implements Bridge { return new Promise((resolve, _) => { resolve( this.redemptions( - walletPublicKey.toString(), - redeemerOutputScript.toString(), + walletPublicKey, + redeemerOutputScript, this._pendingRedemptions ) ) @@ -281,8 +281,8 @@ export class MockBridge implements Bridge { return new Promise((resolve, _) => { resolve( this.redemptions( - walletPublicKey.toString(), - redeemerOutputScript.toString(), + walletPublicKey, + redeemerOutputScript, this._timedOutRedemptions ) ) @@ -290,12 +290,12 @@ export class MockBridge implements Bridge { } private redemptions( - walletPublicKey: string, - redeemerOutputScript: string, + walletPublicKey: Hex, + redeemerOutputScript: Hex, redemptionsMap: Map ): RedemptionRequest { const redemptionKey = MockBridge.buildRedemptionKey( - BitcoinHashUtils.computeHash160(Hex.from(walletPublicKey)).toString(), + BitcoinHashUtils.computeHash160(walletPublicKey), redeemerOutputScript ) @@ -314,12 +314,12 @@ export class MockBridge implements Bridge { } static buildRedemptionKey( - walletPublicKeyHash: string, - redeemerOutputScript: string + walletPublicKeyHash: Hex, + redeemerOutputScript: Hex ): string { - const prefixedWalletPublicKeyHash = `0x${walletPublicKeyHash}` + const prefixedWalletPublicKeyHash = walletPublicKeyHash.toPrefixedString() - const rawOutputScript = Buffer.from(redeemerOutputScript, "hex") + const rawOutputScript = redeemerOutputScript.toBuffer() const prefixedOutputScript = `0x${Buffer.concat([ Buffer.from([rawOutputScript.length]), @@ -353,7 +353,7 @@ export class MockBridge implements Bridge { async wallets(walletPublicKeyHash: Hex): Promise { this._walletsLog.push({ - walletPublicKeyHash: walletPublicKeyHash.toPrefixedString(), + walletPublicKeyHash, }) const wallet = this._wallets.get(walletPublicKeyHash.toPrefixedString()) return wallet! From 527cdd99f9102ddcef800d91696a720c6602a092 Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Tue, 24 Oct 2023 17:24:13 +0200 Subject: [PATCH 19/22] Used Hex for functions dealing with compressed Bitcoin public keys --- typescript/src/lib/bitcoin/ecdsa-key.ts | 29 ++++++++++--------------- typescript/test/lib/bitcoin.test.ts | 16 ++++++++------ 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/typescript/src/lib/bitcoin/ecdsa-key.ts b/typescript/src/lib/bitcoin/ecdsa-key.ts index 39de4e173..ffde61f65 100644 --- a/typescript/src/lib/bitcoin/ecdsa-key.ts +++ b/typescript/src/lib/bitcoin/ecdsa-key.ts @@ -9,43 +9,36 @@ import { BitcoinNetwork, toBitcoinJsLibNetwork } from "./network" * @param publicKey - Public key that should be checked. * @returns True if the key is a compressed Bitcoin public key, false otherwise. */ -function isCompressedPublicKey(publicKey: string | Hex): boolean { - if (typeof publicKey === "string") { - publicKey = Hex.from(publicKey) - } - - publicKey = publicKey.toString() +function isCompressedPublicKey(publicKey: Hex): boolean { + const publicKeyStr = publicKey.toString() // Must have 33 bytes and 02 or 03 prefix. return ( - publicKey.length == 66 && - (publicKey.substring(0, 2) == "02" || publicKey.substring(0, 2) == "03") + publicKeyStr.length == 66 && + (publicKeyStr.substring(0, 2) == "02" || + publicKeyStr.substring(0, 2) == "03") ) } /** * Compresses the given uncompressed Bitcoin public key. - * @param publicKey Uncompressed 64-byte public key as an unprefixed hex string. + * @param publicKey Uncompressed 64-byte public key. * @returns Compressed 33-byte public key prefixed with 02 or 03. */ -function compressPublicKey(publicKey: string | Hex): string { - if (typeof publicKey === "string") { - publicKey = Hex.from(publicKey) - } - - publicKey = publicKey.toString() +function compressPublicKey(publicKey: Hex): string { + const publicKeyStr = publicKey.toString() // Must have 64 bytes and no prefix. - if (publicKey.length != 128) { + if (publicKeyStr.length != 128) { throw new Error( "The public key parameter must be 64-byte. Neither 0x nor 04 prefix is allowed" ) } // The X coordinate is the first 32 bytes. - const publicKeyX = publicKey.substring(0, 64) + const publicKeyX = publicKeyStr.substring(0, 64) // The Y coordinate is the next 32 bytes. - const publicKeyY = publicKey.substring(64) + const publicKeyY = publicKeyStr.substring(64) const prefix = BigNumber.from(`0x${publicKeyY}`).mod(2).eq(0) ? "02" : "03" diff --git a/typescript/test/lib/bitcoin.test.ts b/typescript/test/lib/bitcoin.test.ts index 5f54c4606..11dacfaac 100644 --- a/typescript/test/lib/bitcoin.test.ts +++ b/typescript/test/lib/bitcoin.test.ts @@ -106,9 +106,10 @@ describe("Bitcoin", () => { context("when public key parameter has a correct length", () => { context("when the Y coordinate is divisible by 2", () => { it("should compress the public key correctly", () => { - const uncompressedPublicKey = + const uncompressedPublicKey = Hex.from( "ff6e1857db52d6dba2bd4239fba722655622bc520709d38011f9adac8ea3477b" + - "45ae275b657f7bac7c1e3d146a564051aee1356895f01e4f29f333502416fa4a" + "45ae275b657f7bac7c1e3d146a564051aee1356895f01e4f29f333502416fa4a" + ) const compressedPublicKey = "02ff6e1857db52d6dba2bd4239fba722655622bc520709d38011f9adac8ea3477b" @@ -120,9 +121,10 @@ describe("Bitcoin", () => { context("when the Y coordinate is not divisible by 2", () => { it("should compress the public key correctly", () => { - const uncompressedPublicKey = + const uncompressedPublicKey = Hex.from( "474444cca71c678f5019d16782b6522735717a94602085b4adf707b465c36ca8" + - "7b5dff055ee1cc3a1fff4715dea2858ca4dd5bba0af30abcd881a6bda4fb70af" + "7b5dff055ee1cc3a1fff4715dea2858ca4dd5bba0af30abcd881a6bda4fb70af" + ) const compressedPublicKey = "03474444cca71c678f5019d16782b6522735717a94602085b4adf707b465c36ca8" @@ -135,10 +137,10 @@ describe("Bitcoin", () => { context("when public key parameter has an incorrect length", () => { it("should throw", () => { - const uncompressedPublicKey = + const uncompressedPublicKey = Hex.from( "04474444cca71c678f5019d16782b6522735717a94602085b4adf707b465c36ca8" + - "7b5dff055ee1cc3a1fff4715dea2858ca4dd5bba0af30abcd881a6bda4fb70af" - + "7b5dff055ee1cc3a1fff4715dea2858ca4dd5bba0af30abcd881a6bda4fb70af" + ) expect(() => compressPublicKey(uncompressedPublicKey)).to.throw( "The public key parameter must be 64-byte. Neither 0x nor 04 prefix is allowed" ) From d698946e8af08f8496c982902c5a47ddadfec330 Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Tue, 24 Oct 2023 17:27:30 +0200 Subject: [PATCH 20/22] Got rid of the dash in docstrings --- typescript/src/lib/bitcoin/hash.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/typescript/src/lib/bitcoin/hash.ts b/typescript/src/lib/bitcoin/hash.ts index 3299d1df9..12bfa698f 100644 --- a/typescript/src/lib/bitcoin/hash.ts +++ b/typescript/src/lib/bitcoin/hash.ts @@ -15,7 +15,7 @@ function computeHash160(text: Hex): Hex { /** * Computes the double SHA256 for the given text. - * @param text - Text the double SHA256 is computed for. + * @param text Text the double SHA256 is computed for. * @returns 32-byte-long hash. * @dev Do not confuse it with computeSha256 which computes single SHA256. */ @@ -37,7 +37,7 @@ function hashLEToBigNumber(hash: Hex): BigNumber { /** * Computes the single SHA256 for the given text. - * @param text - Text the single SHA256 is computed for. + * @param text Text the single SHA256 is computed for. * @returns 32-byte-long hash. * @dev Do not confuse it with computeHash256 which computes double SHA256. */ From 794b32c8871c0ee064c2b05b49c6f783fa405da4 Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Tue, 24 Oct 2023 17:30:09 +0200 Subject: [PATCH 21/22] Updated docstring --- typescript/src/lib/bitcoin/address.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typescript/src/lib/bitcoin/address.ts b/typescript/src/lib/bitcoin/address.ts index 865addbcb..e8dd25c5a 100644 --- a/typescript/src/lib/bitcoin/address.ts +++ b/typescript/src/lib/bitcoin/address.ts @@ -92,7 +92,7 @@ function addressToOutputScript( /** * Converts an output script to the respective network-specific address. - * @param script The unprefixed and not prepended with length output script. + * @param script The output script not prepended with length. * @param bitcoinNetwork Bitcoin network the address should be produced for. * @returns The Bitcoin address. */ From 995e166a4250cdd5abe66bf3cac8adcf68d3efa7 Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Tue, 24 Oct 2023 18:35:55 +0200 Subject: [PATCH 22/22] Used Hex to represent transaction hashes for contract functions --- typescript/src/lib/contracts/bridge.ts | 14 ++++---- typescript/src/lib/ethereum/bridge.ts | 22 +++++++----- typescript/src/services/deposits/deposit.ts | 2 +- typescript/test/utils/mock-bridge.ts | 40 ++++++++++++++------- 4 files changed, 51 insertions(+), 27 deletions(-) diff --git a/typescript/src/lib/contracts/bridge.ts b/typescript/src/lib/contracts/bridge.ts index 58c3dd786..ebf9f1bec 100644 --- a/typescript/src/lib/contracts/bridge.ts +++ b/typescript/src/lib/contracts/bridge.ts @@ -32,13 +32,14 @@ export interface Bridge { * @param mainUtxo - Data of the wallet's main UTXO. * @param vault - Optional identifier of the vault the swept deposits should * be routed in. + * @returns Transaction hash of the submit deposit sweep proof transaction. */ submitDepositSweepProof( sweepTx: BitcoinRawTxVectors, sweepProof: BitcoinSpvProof, mainUtxo: BitcoinUtxo, vault?: ChainIdentifier - ): Promise + ): Promise /** * Reveals a given deposit to the on-chain contract. @@ -48,14 +49,14 @@ export interface Bridge { * @param deposit - Data of the revealed deposit * @param vault - Optional parameter denoting the vault the given deposit * should be routed to - * @returns Transaction hash of the reveal deposit transaction as string + * @returns Transaction hash of the reveal deposit transaction. */ revealDeposit( depositTx: BitcoinRawTxVectors, depositOutputIndex: number, deposit: DepositReceipt, vault?: ChainIdentifier - ): Promise + ): Promise /** * Gets a revealed deposit from the on-chain contract. @@ -78,14 +79,14 @@ export interface Bridge { * @param redeemerOutputScript - The output script that the redeemed funds will * be locked to. Must not be prepended with length. * @param amount - The amount to be redeemed in satoshis. - * @returns Empty promise. + * @returns Transaction hash of the request redemption transaction. */ requestRedemption( walletPublicKey: Hex, mainUtxo: BitcoinUtxo, redeemerOutputScript: Hex, amount: BigNumber - ): Promise + ): Promise /** * Submits a redemption transaction proof to the on-chain contract. @@ -94,13 +95,14 @@ export interface Bridge { * @param mainUtxo - Data of the wallet's main UTXO * @param walletPublicKey - Bitcoin public key of the wallet. Must be in the * compressed form (33 bytes long with 02 or 03 prefix). + * @returns Transaction hash of the submit redemption proof transaction. */ submitRedemptionProof( redemptionTx: BitcoinRawTxVectors, redemptionProof: BitcoinSpvProof, mainUtxo: BitcoinUtxo, walletPublicKey: Hex - ): Promise + ): Promise /** * Gets transaction proof difficulty factor from the on-chain contract. diff --git a/typescript/src/lib/ethereum/bridge.ts b/typescript/src/lib/ethereum/bridge.ts index fea20d000..91c266265 100644 --- a/typescript/src/lib/ethereum/bridge.ts +++ b/typescript/src/lib/ethereum/bridge.ts @@ -232,7 +232,7 @@ export class EthereumBridge depositOutputIndex: number, deposit: DepositReceipt, vault?: ChainIdentifier - ): Promise { + ): Promise { const depositTxParam = { version: depositTx.version.toPrefixedString(), inputVector: depositTx.inputs.toPrefixedString(), @@ -258,7 +258,7 @@ export class EthereumBridge ["Deposit already revealed"] ) - return tx.hash + return Hex.from(tx.hash) } // eslint-disable-next-line valid-jsdoc @@ -270,7 +270,7 @@ export class EthereumBridge sweepProof: BitcoinSpvProof, mainUtxo: BitcoinUtxo, vault?: ChainIdentifier - ): Promise { + ): Promise { const sweepTxParam = { version: `0x${sweepTx.version}`, inputVector: `0x${sweepTx.inputs}`, @@ -296,7 +296,7 @@ export class EthereumBridge ? `0x${vault.identifierHex}` : constants.AddressZero - await EthersTransactionUtils.sendWithRetry( + const tx = await EthersTransactionUtils.sendWithRetry( async () => { return await this._instance.submitDepositSweepProof( sweepTxParam, @@ -307,6 +307,8 @@ export class EthereumBridge }, this._totalRetryAttempts ) + + return Hex.from(tx.hash) } // eslint-disable-next-line valid-jsdoc @@ -332,7 +334,7 @@ export class EthereumBridge mainUtxo: BitcoinUtxo, redeemerOutputScript: Hex, amount: BigNumber - ): Promise { + ): Promise { const walletPublicKeyHash = BitcoinHashUtils.computeHash160(walletPublicKey).toPrefixedString() @@ -352,7 +354,7 @@ export class EthereumBridge rawRedeemerOutputScript, ]).toString("hex")}` - await EthersTransactionUtils.sendWithRetry( + const tx = await EthersTransactionUtils.sendWithRetry( async () => { return await this._instance.requestRedemption( walletPublicKeyHash, @@ -363,6 +365,8 @@ export class EthereumBridge }, this._totalRetryAttempts ) + + return Hex.from(tx.hash) } // eslint-disable-next-line valid-jsdoc @@ -374,7 +378,7 @@ export class EthereumBridge redemptionProof: BitcoinSpvProof, mainUtxo: BitcoinUtxo, walletPublicKey: Hex - ): Promise { + ): Promise { const redemptionTxParam = { version: `0x${redemptionTx.version}`, inputVector: `0x${redemptionTx.inputs}`, @@ -399,7 +403,7 @@ export class EthereumBridge const walletPublicKeyHash = BitcoinHashUtils.computeHash160(walletPublicKey).toPrefixedString() - await EthersTransactionUtils.sendWithRetry( + const tx = await EthersTransactionUtils.sendWithRetry( async () => { return await this._instance.submitRedemptionProof( redemptionTxParam, @@ -410,6 +414,8 @@ export class EthereumBridge }, this._totalRetryAttempts ) + + return Hex.from(tx.hash) } // eslint-disable-next-line valid-jsdoc diff --git a/typescript/src/services/deposits/deposit.ts b/typescript/src/services/deposits/deposit.ts index a1f454eb0..71ed02467 100644 --- a/typescript/src/services/deposits/deposit.ts +++ b/typescript/src/services/deposits/deposit.ts @@ -111,7 +111,7 @@ export class Deposit { * initiate minting (both modes). */ // TODO: Cover auto funding outpoint detection with unit tests. - async initiateMinting(fundingOutpoint?: BitcoinTxOutpoint): Promise { + async initiateMinting(fundingOutpoint?: BitcoinTxOutpoint): Promise { let resolvedFundingOutpoint: BitcoinTxOutpoint if (typeof fundingOutpoint !== "undefined") { diff --git a/typescript/test/utils/mock-bridge.ts b/typescript/test/utils/mock-bridge.ts index 43b1cc8d0..a1340a892 100644 --- a/typescript/test/utils/mock-bridge.ts +++ b/typescript/test/utils/mock-bridge.ts @@ -159,10 +159,14 @@ export class MockBridge implements Bridge { sweepProof: BitcoinSpvProof, mainUtxo: BitcoinUtxo, vault?: ChainIdentifier - ): Promise { + ): Promise { this._depositSweepProofLog.push({ sweepTx, sweepProof, mainUtxo }) - return new Promise((resolve, _) => { - resolve() + return new Promise((resolve, _) => { + resolve( + Hex.from( + "01ee2a0061b6bd68b6f478c48b9625fac89a4401e73b49d3ee258f9a60c5e65f" + ) + ) }) } @@ -170,12 +174,14 @@ export class MockBridge implements Bridge { depositTx: BitcoinRawTxVectors, depositOutputIndex: number, deposit: DepositReceipt - ): Promise { + ): Promise { this._revealDepositLog.push({ depositTx, depositOutputIndex, deposit }) - return new Promise((resolve, _) => { + return new Promise((resolve, _) => { // random transaction hash resolve( - "2f952bdc206bf51bb745b967cb7166149becada878d3191ffe341155ebcd4883" + Hex.from( + "2f952bdc206bf51bb745b967cb7166149becada878d3191ffe341155ebcd4883" + ) ) }) } @@ -224,15 +230,20 @@ export class MockBridge implements Bridge { redemptionProof: BitcoinSpvProof, mainUtxo: BitcoinUtxo, walletPublicKey: Hex - ): Promise { + ): Promise { this._redemptionProofLog.push({ redemptionTx, redemptionProof, mainUtxo, walletPublicKey, }) - return new Promise((resolve, _) => { - resolve() + return new Promise((resolve, _) => { + // random transaction hash + resolve( + Hex.from( + "4f6ce6af47d547bb9821d28c21261026f21b72e52d506d17ab81502b8021537d" + ) + ) }) } @@ -241,15 +252,20 @@ export class MockBridge implements Bridge { mainUtxo: BitcoinUtxo, redeemerOutputScript: Hex, amount: BigNumber - ) { + ): Promise { this._requestRedemptionLog.push({ walletPublicKey, mainUtxo, redeemerOutputScript, amount, }) - return new Promise((resolve, _) => { - resolve() + return new Promise((resolve, _) => { + // random transaction hash + resolve( + Hex.from( + "bcbef136592feabdebcc68eb4222a49369a9cfeb7fc5f5ec84583313249025fd" + ) + ) }) }