From 0d81717fade918ec337093e3dc4c3862662d20c3 Mon Sep 17 00:00:00 2001 From: buck Date: Thu, 6 Jun 2024 14:18:45 -0500 Subject: [PATCH] Spend to Taproot (#91) * adds new methods in @caravan/psbt to use bitcoinjs-lib v6 to support spending to taproot outputs * uses these new functions in caravan coordinator and caravan wallets Other fixes include: * don't polyfill process env for trezor environment variables in @caravan/wallets * cleanup some dependencies in @caravan/wallets * remove unexported PSBTv0 modules from @caravan/psbt * some hidden regtest support via configs * jest and other tooling cleanup --- .changeset/bright-dogs-divide.md | 5 + .changeset/calm-adults-own.md | 5 + .changeset/cyan-queens-enjoy.md | 5 + .changeset/happy-rivers-pump.md | 5 + .changeset/light-plants-remember.md | 5 + .changeset/perfect-panthers-chew.md | 5 + .changeset/twelve-kids-provide.md | 6 + .changeset/wet-cougars-sin.md | 5 + apps/coordinator/README.md | 4 + apps/coordinator/jest.config.json | 25 - apps/coordinator/jest.config.ts | 27 + apps/coordinator/jest.setup.ts | 1 + apps/coordinator/package.json | 4 +- .../ScriptExplorer/SignatureImporter.jsx | 33 +- .../components/ScriptExplorer/Transaction.jsx | 48 +- .../src/components/Wallet/index.jsx | 6 +- .../src/reducers/transactionReducer.js | 26 +- .../src/reducers/transactionReducer.test.js | 1 + apps/coordinator/src/tests/addresses.jsx | 7 +- apps/coordinator/src/tests/registration.jsx | 6 +- apps/coordinator/src/tests/signing.jsx | 2 +- apps/coordinator/tsconfig.json | 1 + apps/coordinator/vite.config.ts | 3 + package-lock.json | 3600 ++-- package.json | 1 - packages/caravan-bitcoin/.prettierrc | 4 + packages/caravan-bitcoin/README.md | 10 + packages/caravan-bitcoin/package.json | 4 +- .../caravan-bitcoin/src/addresses.test.ts | 26 +- packages/caravan-bitcoin/src/addresses.ts | 26 +- packages/caravan-bitcoin/src/braid.ts | 22 +- packages/caravan-bitcoin/src/fixtures.ts | 54 +- packages/caravan-bitcoin/src/keys.ts | 2 +- packages/caravan-bitcoin/src/multisig.ts | 2 +- packages/caravan-bitcoin/src/networks.test.ts | 2 +- packages/caravan-bitcoin/src/networks.ts | 6 +- packages/caravan-bitcoin/src/psbt.ts | 27 +- packages/caravan-bitcoin/src/psbtv2.test.ts | 23 +- packages/caravan-bitcoin/src/psbtv2.ts | 2 +- packages/caravan-bitcoin/src/script.ts | 2 +- packages/caravan-bitcoin/src/signatures.ts | 31 +- .../caravan-bitcoin/src/transactions.test.ts | 46 +- packages/caravan-bitcoin/src/transactions.ts | 13 +- packages/caravan-bitcoin/src/types/braid.ts | 20 - packages/caravan-bitcoin/src/types/index.ts | 1 - packages/caravan-bitcoin/src/utils.ts | 2 +- packages/caravan-psbt/README.md | 131 +- packages/caravan-psbt/jest.config.ts | 14 + packages/caravan-psbt/jest.setup.ts | 1 + packages/caravan-psbt/package.json | 33 +- packages/caravan-psbt/src/constants.ts | 3 + packages/caravan-psbt/src/functions.test.ts | 28 + packages/caravan-psbt/src/functions.ts | 22 + packages/caravan-psbt/src/index.ts | 3 +- packages/caravan-psbt/src/psbt.test.ts | 338 - packages/caravan-psbt/src/psbt.ts | 440 - packages/caravan-psbt/src/psbtv0/index.ts | 3 + packages/caravan-psbt/src/psbtv0/psbt.test.ts | 94 + packages/caravan-psbt/src/psbtv0/psbt.ts | 267 + packages/caravan-psbt/src/psbtv0/utils.ts | 159 + packages/caravan-psbt/src/psbtv2/functions.ts | 31 +- .../caravan-psbt/src/psbtv2/psbtv2.test.ts | 10 +- packages/caravan-psbt/src/psbtv2/psbtv2.ts | 5 +- .../caravan-psbt/src/psbtv2/psbtv2maps.ts | 5 +- packages/caravan-psbt/src/psbtv2/values.ts | 2 +- packages/caravan-psbt/tsconfig.json | 14 +- packages/caravan-psbt/tsup.config.ts | 11 +- .../vendor/tiny-secp256k1-asmjs/LICENSE | 21 + .../vendor/tiny-secp256k1-asmjs/README.md | 364 + .../tiny-secp256k1-asmjs/lib/cjs/index.cjs | 387 + .../lib/cjs/rand.browser.cjs | 20 + .../tiny-secp256k1-asmjs/lib/cjs/rand.cjs | 8 + .../lib/cjs/secp256k1.asm.cjs | 17705 ++++++++++++++++ .../tiny-secp256k1-asmjs/lib/cjs/validate.cjs | 145 + .../lib/cjs/validate_error.cjs | 26 + .../lib/cjs/wasm_loader.cjs | 7 + .../lib/cjs/wasm_path_cjs.cjs | 12 + .../tiny-secp256k1-asmjs/lib/index.d.ts | 33 + .../vendor/tiny-secp256k1-asmjs/lib/index.js | 361 + .../lib/rand.browser.d.ts | 1 + .../tiny-secp256k1-asmjs/lib/rand.browser.js | 16 + .../vendor/tiny-secp256k1-asmjs/lib/rand.d.ts | 1 + .../vendor/tiny-secp256k1-asmjs/lib/rand.js | 4 + .../tiny-secp256k1-asmjs/lib/secp256k1.asm.js | 17705 ++++++++++++++++ .../tiny-secp256k1-asmjs/lib/validate.d.ts | 25 + .../tiny-secp256k1-asmjs/lib/validate.js | 125 + .../lib/validate_error.d.ts | 9 + .../lib/validate_error.js | 22 + .../tiny-secp256k1-asmjs/lib/wasm_loader.d.ts | 41 + .../tiny-secp256k1-asmjs/lib/wasm_loader.js | 5 + .../tiny-secp256k1-asmjs/lib/wasm_path.d.ts | 1 + .../tiny-secp256k1-asmjs/lib/wasm_path.js | 5 + .../vendor/tiny-secp256k1-asmjs/package.json | 63 + packages/caravan-wallets/jest.config.js | 8 - packages/caravan-wallets/jest.config.ts | 22 + packages/caravan-wallets/jest.setup.ts | 4 + packages/caravan-wallets/package.json | 6 +- packages/caravan-wallets/src/coldcard.ts | 21 +- packages/caravan-wallets/src/custom.ts | 14 +- packages/caravan-wallets/src/index.ts | 26 +- packages/caravan-wallets/src/ledger.test.ts | 9 +- packages/caravan-wallets/src/ledger.ts | 7 +- packages/caravan-wallets/src/policy.test.ts | 4 +- packages/caravan-wallets/src/policy.ts | 3 +- packages/caravan-wallets/src/trezor.ts | 2 +- packages/caravan-wallets/src/types/index.ts | 9 - packages/caravan-wallets/tsup.config.ts | 6 +- packages/eslint-config/next.js | 35 - packages/eslint-config/package.json | 6 +- packages/multisig/.eslintrc.cjs | 7 + packages/multisig/.prettierrc | 1 + packages/multisig/README.md | 4 + .../{caravan-psbt => multisig}/jest.config.js | 0 packages/multisig/package.json | 48 + packages/multisig/src/index.ts | 2 + packages/multisig/src/types.ts | 116 + packages/multisig/src/utils.test.ts | 18 + packages/multisig/src/utils.ts | 19 + packages/multisig/tsconfig.json | 3 + packages/multisig/tsup.config.js | 6 + packages/typescript-config/base.json | 2 +- .../{.eslintrc.js.hbs => .eslintrc.cjs.hbs} | 0 turbo/generators/templates/package.json.hbs | 22 +- 123 files changed, 40811 insertions(+), 2506 deletions(-) create mode 100644 .changeset/bright-dogs-divide.md create mode 100644 .changeset/calm-adults-own.md create mode 100644 .changeset/cyan-queens-enjoy.md create mode 100644 .changeset/happy-rivers-pump.md create mode 100644 .changeset/light-plants-remember.md create mode 100644 .changeset/perfect-panthers-chew.md create mode 100644 .changeset/twelve-kids-provide.md create mode 100644 .changeset/wet-cougars-sin.md delete mode 100644 apps/coordinator/jest.config.json create mode 100644 apps/coordinator/jest.config.ts create mode 100644 apps/coordinator/jest.setup.ts create mode 100644 packages/caravan-bitcoin/.prettierrc delete mode 100644 packages/caravan-bitcoin/src/types/braid.ts create mode 100644 packages/caravan-psbt/jest.config.ts create mode 100644 packages/caravan-psbt/jest.setup.ts create mode 100644 packages/caravan-psbt/src/constants.ts create mode 100644 packages/caravan-psbt/src/functions.test.ts create mode 100644 packages/caravan-psbt/src/functions.ts delete mode 100644 packages/caravan-psbt/src/psbt.test.ts delete mode 100644 packages/caravan-psbt/src/psbt.ts create mode 100644 packages/caravan-psbt/src/psbtv0/index.ts create mode 100644 packages/caravan-psbt/src/psbtv0/psbt.test.ts create mode 100644 packages/caravan-psbt/src/psbtv0/psbt.ts create mode 100644 packages/caravan-psbt/src/psbtv0/utils.ts create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/LICENSE create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/README.md create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/cjs/index.cjs create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/cjs/rand.browser.cjs create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/cjs/rand.cjs create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/cjs/secp256k1.asm.cjs create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/cjs/validate.cjs create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/cjs/validate_error.cjs create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/cjs/wasm_loader.cjs create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/cjs/wasm_path_cjs.cjs create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/index.d.ts create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/index.js create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/rand.browser.d.ts create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/rand.browser.js create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/rand.d.ts create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/rand.js create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/secp256k1.asm.js create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/validate.d.ts create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/validate.js create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/validate_error.d.ts create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/validate_error.js create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/wasm_loader.d.ts create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/wasm_loader.js create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/wasm_path.d.ts create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/lib/wasm_path.js create mode 100644 packages/caravan-psbt/vendor/tiny-secp256k1-asmjs/package.json delete mode 100644 packages/caravan-wallets/jest.config.js create mode 100644 packages/caravan-wallets/jest.config.ts create mode 100644 packages/caravan-wallets/jest.setup.ts delete mode 100644 packages/eslint-config/next.js create mode 100644 packages/multisig/.eslintrc.cjs create mode 100644 packages/multisig/.prettierrc create mode 100644 packages/multisig/README.md rename packages/{caravan-psbt => multisig}/jest.config.js (100%) create mode 100644 packages/multisig/package.json create mode 100644 packages/multisig/src/index.ts create mode 100644 packages/multisig/src/types.ts create mode 100644 packages/multisig/src/utils.test.ts create mode 100644 packages/multisig/src/utils.ts create mode 100644 packages/multisig/tsconfig.json create mode 100644 packages/multisig/tsup.config.js rename turbo/generators/templates/{.eslintrc.js.hbs => .eslintrc.cjs.hbs} (100%) diff --git a/.changeset/bright-dogs-divide.md b/.changeset/bright-dogs-divide.md new file mode 100644 index 00000000..3c8ea4f3 --- /dev/null +++ b/.changeset/bright-dogs-divide.md @@ -0,0 +1,5 @@ +--- +"@caravan/psbt": minor +--- + +export of new utils for psbt v0 handling. Primarily adds support for taproot outputs by upgrading to bitcoinjs-lib v6 depedency. Upgrades to a new API from legacy utils from caravan/bitcoin and includes some utilities and types for handling conversions. diff --git a/.changeset/calm-adults-own.md b/.changeset/calm-adults-own.md new file mode 100644 index 00000000..906adc70 --- /dev/null +++ b/.changeset/calm-adults-own.md @@ -0,0 +1,5 @@ +--- +"@caravan/bitcoin": minor +--- + +export signature utilities from caravan/bitcoin to support new psbt tooling diff --git a/.changeset/cyan-queens-enjoy.md b/.changeset/cyan-queens-enjoy.md new file mode 100644 index 00000000..b0bea8e4 --- /dev/null +++ b/.changeset/cyan-queens-enjoy.md @@ -0,0 +1,5 @@ +--- +"@caravan/wallets": minor +--- + +upgrading psbt generation to support taproot outputs and new caravan/psbt utils diff --git a/.changeset/happy-rivers-pump.md b/.changeset/happy-rivers-pump.md new file mode 100644 index 00000000..2ed4e7d4 --- /dev/null +++ b/.changeset/happy-rivers-pump.md @@ -0,0 +1,5 @@ +--- +"@caravan/multisig": major +--- + +New package for multisig wallet utilities and types to share across other packages diff --git a/.changeset/light-plants-remember.md b/.changeset/light-plants-remember.md new file mode 100644 index 00000000..054f5401 --- /dev/null +++ b/.changeset/light-plants-remember.md @@ -0,0 +1,5 @@ +--- +"@caravan/bitcoin": minor +--- + +transaction parser was stripping out network information from global xpubs being added to psbt. global xpubs will now respect the network and include appropriate prefix diff --git a/.changeset/perfect-panthers-chew.md b/.changeset/perfect-panthers-chew.md new file mode 100644 index 00000000..1275c8b8 --- /dev/null +++ b/.changeset/perfect-panthers-chew.md @@ -0,0 +1,5 @@ +--- +"caravan-coordinator": minor +--- + +upgrade tx processing utils to use new psbt utils for taproot output support diff --git a/.changeset/twelve-kids-provide.md b/.changeset/twelve-kids-provide.md new file mode 100644 index 00000000..4e4a3fd6 --- /dev/null +++ b/.changeset/twelve-kids-provide.md @@ -0,0 +1,6 @@ +--- +"@caravan/wallets": patch +"caravan-coordinator": patch +--- + +fixes an issue where esbuild was polyfilling process.env which breaks the ability to override trezor connect settings and pass other env vars at run time in dependent applications diff --git a/.changeset/wet-cougars-sin.md b/.changeset/wet-cougars-sin.md new file mode 100644 index 00000000..067bddf7 --- /dev/null +++ b/.changeset/wet-cougars-sin.md @@ -0,0 +1,5 @@ +--- +"@caravan/eslint-config": patch +--- + +initiliazing package, upgrading deps. need to improve shared config before major release diff --git a/apps/coordinator/README.md b/apps/coordinator/README.md index b78a650d..03312c52 100644 --- a/apps/coordinator/README.md +++ b/apps/coordinator/README.md @@ -139,6 +139,10 @@ By default, Caravan uses a free API provided by information about the bitcoin blockchain or to broadcast transactions. Blockstream.info is also available as a fallback option for a public API. +Mainnet and Testnet are available options for connecting to any of the available +consensus client options. Regtest can be available through an uploaded wallet +configuration file, but only for the private client backend. + ### Bitcoind client You can also ask Caravan to use your own private [bitcoind full diff --git a/apps/coordinator/jest.config.json b/apps/coordinator/jest.config.json deleted file mode 100644 index d15cd5b8..00000000 --- a/apps/coordinator/jest.config.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "testEnvironment": "jsdom", - "transform": { - "\\.[jt]sx?$": "babel-jest" - }, - "transformIgnorePatterns": [ - "[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$", - "^.+\\.module\\.(css|sass|scss)$" - ], - "moduleNameMapper": { - "^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy" - }, - "moduleFileExtensions": [ - "web.cjs", - "js", - "web.ts", - "ts", - "web.tsx", - "tsx", - "json", - "web.cjsx", - "jsx", - "node" - ] -} diff --git a/apps/coordinator/jest.config.ts b/apps/coordinator/jest.config.ts new file mode 100644 index 00000000..e901df97 --- /dev/null +++ b/apps/coordinator/jest.config.ts @@ -0,0 +1,27 @@ +import type { JestConfigWithTsJest } from "ts-jest"; + +const config: JestConfigWithTsJest = { + testEnvironment: "jsdom", + transform: { + "\\.[jt]sx?$": "babel-jest", + }, + transformIgnorePatterns: ["^.+\\.module\\.(css|sass|scss)$"], + moduleNameMapper: { + "^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy", + }, + moduleFileExtensions: [ + "web.cjs", + "js", + "web.ts", + "ts", + "web.tsx", + "tsx", + "json", + "web.cjsx", + "jsx", + "node", + ], + setupFilesAfterEnv: ["/jest.setup.ts"], +}; + +export default config; diff --git a/apps/coordinator/jest.setup.ts b/apps/coordinator/jest.setup.ts new file mode 100644 index 00000000..b0bd26f6 --- /dev/null +++ b/apps/coordinator/jest.setup.ts @@ -0,0 +1 @@ +import "@inrupt/jest-jsdom-polyfills"; diff --git a/apps/coordinator/package.json b/apps/coordinator/package.json index 9552a431..d251b65b 100644 --- a/apps/coordinator/package.json +++ b/apps/coordinator/package.json @@ -31,6 +31,7 @@ "@babel/preset-env": "^7.20.2", "@babel/preset-react": "^7.18.6", "@babel/preset-typescript": "^7.21.0", + "@inrupt/jest-jsdom-polyfills": "^3.2.1", "@testing-library/jest-dom": "^5.6.0", "@testing-library/react": "^10.0.4", "@types/history": "^5.0.0", @@ -95,8 +96,9 @@ "dependencies": { "@caravan/bitcoin": "*", "@caravan/clients": "*", - "@caravan/descriptors": "^0.0.6", + "@caravan/descriptors": "^0.1.1", "@caravan/eslint-config": "*", + "@caravan/psbt": "*", "@caravan/typescript-config": "*", "@caravan/wallets": "*", "@emotion/react": "^11.10.6", diff --git a/apps/coordinator/src/components/ScriptExplorer/SignatureImporter.jsx b/apps/coordinator/src/components/ScriptExplorer/SignatureImporter.jsx index fca52669..7a0f3266 100644 --- a/apps/coordinator/src/components/ScriptExplorer/SignatureImporter.jsx +++ b/apps/coordinator/src/components/ScriptExplorer/SignatureImporter.jsx @@ -3,7 +3,6 @@ import PropTypes from "prop-types"; import { connect } from "react-redux"; import { validateHex, - validateMultisigSignature, multisigBIP32Path, multisigBIP32Root, validateBIP32Path, @@ -38,6 +37,12 @@ import { } from "../../actions/signatureImporterActions"; import { setSigningKey as setSigningKeyAction } from "../../actions/transactionActions"; import { downloadFile } from "../../utils"; +import { + convertLegacyInput, + convertLegacyOutput, + getUnsignedMultisigPsbtV0, + validateMultisigPsbtSignature, +} from "@caravan/psbt"; const TEXT = "text"; const UNKNOWN = "unknown"; @@ -389,12 +394,17 @@ class SignatureImporter extends React.Component { let publicKey; try { - publicKey = validateMultisigSignature( + const args = { network, - inputs, - outputs, + inputs: inputs.map(convertLegacyInput), + outputs: outputs.map(convertLegacyOutput), + }; + const psbt = getUnsignedMultisigPsbtV0(args); + publicKey = validateMultisigPsbtSignature( + psbt.toBase64(), inputIndex, inputSignature, + inputs[inputIndex].amountSats, ); } catch (e) { errback(`Signature for input ${inputNumber} is invalid.`); @@ -482,13 +492,17 @@ class SignatureImporter extends React.Component { return; } try { - // This returns false if it completes with no error - publicKey = validateMultisigSignature( + const args = { network, - inputs, - outputs, + inputs: inputs.map(convertLegacyInput), + outputs: outputs.map(convertLegacyOutput), + }; + const psbt = getUnsignedMultisigPsbtV0(args); + publicKey = validateMultisigPsbtSignature( + psbt.toBase64(), inputIndex, inputSignature, + inputs[inputIndex].amountSats, ); } catch (e) { // eslint-disable-next-line no-console @@ -579,7 +593,8 @@ SignatureImporter.propTypes = { }), ).isRequired, fee: PropTypes.string.isRequired, - inputs: PropTypes.arrayOf(PropTypes.shape({})).isRequired, + inputs: PropTypes.arrayOf(PropTypes.shape({ amountSats: PropTypes.string })) + .isRequired, inputsTotalSats: PropTypes.shape({}).isRequired, isWallet: PropTypes.bool.isRequired, network: PropTypes.string.isRequired, diff --git a/apps/coordinator/src/components/ScriptExplorer/Transaction.jsx b/apps/coordinator/src/components/ScriptExplorer/Transaction.jsx index 5c8fe36d..c9d67590 100644 --- a/apps/coordinator/src/components/ScriptExplorer/Transaction.jsx +++ b/apps/coordinator/src/components/ScriptExplorer/Transaction.jsx @@ -2,8 +2,8 @@ import React from "react"; import PropTypes from "prop-types"; import { connect } from "react-redux"; import { - signedMultisigTransaction, blockExplorerTransactionURL, + addSignaturesToPSBT, } from "@caravan/bitcoin"; import { @@ -21,6 +21,13 @@ import { updateBlockchainClient } from "../../actions/clientActions"; import Copyable from "../Copyable"; import { externalLink } from "utils/ExternalLink"; import { setTXID } from "../../actions/transactionActions"; +import { + convertLegacyInput, + convertLegacyOutput, + getUnsignedMultisigPsbtV0, +} from "@caravan/psbt"; +import { Psbt } from "bitcoinjs-lib"; +import { Buffer } from "buffer"; class Transaction extends React.Component { constructor(props) { @@ -34,14 +41,30 @@ class Transaction extends React.Component { buildSignedTransaction = () => { const { network, inputs, outputs, signatureImporters } = this.props; - return signedMultisigTransaction( + const args = { network, - inputs, - outputs, - Object.values(signatureImporters).map( - (signatureImporter) => signatureImporter.signature, - ), - ); + inputs: inputs.map(convertLegacyInput), + outputs: outputs.map(convertLegacyOutput), + }; + const psbt = getUnsignedMultisigPsbtV0(args); + let partiallySignedTransaction = psbt.toBase64(); + for (const signatureImporter of Object.values(signatureImporters)) { + partiallySignedTransaction = addSignaturesToPSBT( + network, + partiallySignedTransaction, + signatureImporter.publicKeys.map((pubkey) => + Buffer.from(pubkey, "hex"), + ), + signatureImporter.signature.map((signature) => + Buffer.from(signature, "hex"), + ), + ); + } + + return Psbt.fromBase64(partiallySignedTransaction) + .finalizeAllInputs() + .extractTransaction() + .toHex(); }; handleBroadcast = async () => { @@ -52,7 +75,7 @@ class Transaction extends React.Component { let txid = ""; this.setState({ broadcasting: true }); try { - txid = await client.broadcastTransaction(signedTransaction.toHex()); + txid = await client.broadcastTransaction(signedTransaction); } catch (e) { // eslint-disable-next-line no-console console.error(e); @@ -71,14 +94,13 @@ class Transaction extends React.Component { render() { const { error, broadcasting, txid } = this.state; - const signedTransaction = this.buildSignedTransaction(); - const signedTransactionHex = signedTransaction.toHex(); + const signedTransactionHex = this.buildSignedTransaction(); return (
- {signedTransaction && ( + {signedTransactionHex && ( Signed Transaction @@ -89,7 +111,7 @@ class Transaction extends React.Component {