diff --git a/src/transaction_builder.js b/src/transaction_builder.js index d2ca691..86dab81 100644 --- a/src/transaction_builder.js +++ b/src/transaction_builder.js @@ -56,10 +56,33 @@ class TransactionBuilder { return txb; } static fromPsbt(psbtBuffer, network) { - const { transaction } = bip174_1.extractTransaction({ + const { unsigned_transaction, inputs } = bip174_1.decodePsbt({ psbt: psbtBuffer.toString('hex'), }); - const tx = transaction_1.Transaction.fromHex(transaction); + const tx = transaction_1.Transaction.fromHex(unsigned_transaction); + inputs.forEach((input, vin) => { + if (input.final_scriptsig) { + tx.setInputScript(vin, Buffer.from(input.final_scriptsig, 'hex')); + } + if (input.final_scriptwitness) { + const finalScriptWitness = Buffer.from( + input.final_scriptwitness, + 'hex', + ); + const witnessElements = script_1 + .decompile(finalScriptWitness) + .map(chunk => { + if (!chunk) { + return Buffer.from([]); + } + if (Buffer.isBuffer(chunk)) { + return chunk; + } + return Buffer.from([chunk]); + }); + tx.setWitness(vin, script_1.decompile(witnessElements)); + } + }); return TransactionBuilder.fromTransaction(tx, network); } setLowR(setting) { diff --git a/test/fixtures/transaction_builder.json b/test/fixtures/transaction_builder.json index b1a1909..0a0b290 100644 --- a/test/fixtures/transaction_builder.json +++ b/test/fixtures/transaction_builder.json @@ -1497,10 +1497,10 @@ "txHex": "0200000000010258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd7500000000da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752aeffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d01000000232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f000400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00000000" }, { - "description": "PSBT w/ 1 unsigned P2PKH input. Outputs are empty", - "incomplete": false, + "description": "PSBT w/ 1 unsigned P2PKH input", + "incomplete": true, "psbt": "70736274ff0100750200000001268171371edff285e937adeea4b37b78000c0566cbb3ad64641713ca42171bf60000000000feffffff02d3dff505000000001976a914d0c59903c5bac2868760e90fd521a4665aa7652088ac00e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787b32e1300000100fda5010100000000010289a3c71eab4d20e0371bbba4cc698fa295c9463afa2e397f8533ccb62f9567e50100000017160014be18d152a9b012039daf3da7de4f53349eecb985ffffffff86f8aa43a71dff1448893a530a7237ef6b4608bbb2dd2d0171e63aec6a4890b40100000017160014fe3e9ef1a745e974d902c4355943abcb34bd5353ffffffff0200c2eb0b000000001976a91485cff1097fd9e008bb34af709c62197b38978a4888ac72fef84e2c00000017a914339725ba21efd62ac753a9bcd067d6c7a6a39d05870247304402202712be22e0270f394f568311dc7ca9a68970b8025fdd3b240229f07f8a5f3a240220018b38d7dcd314e734c9276bd6fb40f673325bc4baa144c800d2f2f02db2765c012103d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f210502483045022100d12b852d85dcd961d2f5f4ab660654df6eedcc794c0c33ce5cc309ffb5fce58d022067338a8e0e1725c197fb1a88af59f51e44e4255b20167c8684031c05d1f2592a01210223b72beef0965d10be0778efecd61fcac6f79a4ea169393380734464f84f2ab300000000000000", - "txHex": "don't know yet" + "txHex": "0200000001268171371edff285e937adeea4b37b78000c0566cbb3ad64641713ca42171bf60000000000feffffff02d3dff505000000001976a914d0c59903c5bac2868760e90fd521a4665aa7652088ac00e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787b32e1300" } ], "fromTransaction": [ diff --git a/ts_src/transaction_builder.ts b/ts_src/transaction_builder.ts index e18f68e..9cfc0e4 100644 --- a/ts_src/transaction_builder.ts +++ b/ts_src/transaction_builder.ts @@ -1,4 +1,4 @@ -import { extractTransaction } from 'bip174'; +import { decodePsbt } from 'bip174'; import * as baddress from './address'; import { reverseBuffer } from './bufferutils'; import * as classify from './classify'; @@ -10,7 +10,7 @@ import * as networks from './networks'; import { Payment } from './payments'; import * as payments from './payments'; import * as bscript from './script'; -import { OPS as ops } from './script'; +import { decompile, OPS as ops } from './script'; import { Output, Transaction } from './transaction'; import * as types from './types'; const typeforce = require('typeforce'); @@ -93,10 +93,40 @@ export class TransactionBuilder { } static fromPsbt(psbtBuffer: Buffer, network?: Network): TransactionBuilder { - const { transaction } = extractTransaction({ + const { unsigned_transaction, inputs } = decodePsbt({ psbt: psbtBuffer.toString('hex'), }); - const tx = Transaction.fromHex(transaction); + + const tx = Transaction.fromHex(unsigned_transaction!); + + inputs.forEach((input, vin) => { + if (input.final_scriptsig) { + tx.setInputScript(vin, Buffer.from(input.final_scriptsig, 'hex')); + } + + if (input.final_scriptwitness) { + const finalScriptWitness = Buffer.from( + input.final_scriptwitness, + 'hex', + ); + + const witnessElements = (decompile(finalScriptWitness) as []).map( + chunk => { + if (!chunk) { + return Buffer.from([]); + } + + if (Buffer.isBuffer(chunk)) { + return chunk; + } + + return Buffer.from([chunk]); + }, + ); + + tx.setWitness(vin, decompile(witnessElements) as []); + } + }); return TransactionBuilder.fromTransaction(tx, network); }