Browse Source

Build transction from unsigned PSBT transaction and then add input script / witness data

psbt-support
Luke Childs 6 years ago
parent
commit
582df7463a
  1. 27
      src/transaction_builder.js
  2. 6
      test/fixtures/transaction_builder.json
  3. 38
      ts_src/transaction_builder.ts

27
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) {

6
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": [

38
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);
}

Loading…
Cancel
Save