Modify for new BIP174 interface system
This commit is contained in:
parent
d790288048
commit
71ddd656a3
6 changed files with 231 additions and 389 deletions
5
package-lock.json
generated
5
package-lock.json
generated
|
@ -200,9 +200,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bip174": {
|
"bip174": {
|
||||||
"version": "0.0.15",
|
"version": "git+https://github.com/bitcoinjs/bip174.git#5137e367c7a3a4e281ee01574f88977cdd4be896",
|
||||||
"resolved": "https://registry.npmjs.org/bip174/-/bip174-0.0.15.tgz",
|
"from": "git+https://github.com/bitcoinjs/bip174.git#interface"
|
||||||
"integrity": "sha512-mK/s9p7i+PG7W2s2cAedNVk1NDZQn9wAoq1DlsS2+1zz5TXR3TRTzqRqm9BQtOXwbkxkhfLwlmsOjuiRdAYkdg=="
|
|
||||||
},
|
},
|
||||||
"bip32": {
|
"bip32": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "10.12.18",
|
"@types/node": "10.12.18",
|
||||||
"bech32": "^1.1.2",
|
"bech32": "^1.1.2",
|
||||||
"bip174": "0.0.15",
|
"bip174": "git+https://github.com/bitcoinjs/bip174.git#interface",
|
||||||
"bip32": "^2.0.3",
|
"bip32": "^2.0.3",
|
||||||
"bip66": "^1.1.0",
|
"bip66": "^1.1.0",
|
||||||
"bitcoin-ops": "^1.4.0",
|
"bitcoin-ops": "^1.4.0",
|
||||||
|
|
241
src/psbt.js
241
src/psbt.js
|
@ -16,7 +16,7 @@ const DEFAULT_OPTS = {
|
||||||
maximumFeeRate: 5000,
|
maximumFeeRate: 5000,
|
||||||
};
|
};
|
||||||
class Psbt {
|
class Psbt {
|
||||||
constructor(opts = {}, data = new bip174_1.Psbt()) {
|
constructor(opts = {}, data = new bip174_1.Psbt(new PsbtTransaction())) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
this.__CACHE = {
|
this.__CACHE = {
|
||||||
__NON_WITNESS_UTXO_TX_CACHE: [],
|
__NON_WITNESS_UTXO_TX_CACHE: [],
|
||||||
|
@ -27,11 +27,11 @@ class Psbt {
|
||||||
// set defaults
|
// set defaults
|
||||||
this.opts = Object.assign({}, DEFAULT_OPTS, opts);
|
this.opts = Object.assign({}, DEFAULT_OPTS, opts);
|
||||||
const c = this.__CACHE;
|
const c = this.__CACHE;
|
||||||
c.__TX = transaction_1.Transaction.fromBuffer(data.globalMap.unsignedTx);
|
c.__TX = this.data.globalMap.unsignedTx.tx;
|
||||||
if (this.data.inputs.length === 0) this.setVersion(2);
|
if (this.data.inputs.length === 0) this.setVersion(2);
|
||||||
// set cache
|
// set cache
|
||||||
delete data.globalMap.unsignedTx;
|
this.unsignedTx = Buffer.from([]);
|
||||||
Object.defineProperty(data.globalMap, 'unsignedTx', {
|
Object.defineProperty(this, 'unsignedTx', {
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
get() {
|
get() {
|
||||||
const buf = c.__TX_BUF_CACHE;
|
const buf = c.__TX_BUF_CACHE;
|
||||||
|
@ -56,24 +56,20 @@ class Psbt {
|
||||||
dpew(this, 'opts', false, true);
|
dpew(this, 'opts', false, true);
|
||||||
}
|
}
|
||||||
static fromTransaction(txBuf, opts = {}) {
|
static fromTransaction(txBuf, opts = {}) {
|
||||||
const tx = transaction_1.Transaction.fromBuffer(txBuf);
|
const tx = new PsbtTransaction(txBuf);
|
||||||
checkTxEmpty(tx);
|
checkTxEmpty(tx.tx);
|
||||||
const psbtBase = new bip174_1.Psbt();
|
const psbtBase = new bip174_1.Psbt(tx);
|
||||||
const psbt = new Psbt(opts, psbtBase);
|
const psbt = new Psbt(opts, psbtBase);
|
||||||
psbt.__CACHE.__TX = tx;
|
psbt.__CACHE.__TX = tx.tx;
|
||||||
checkTxForDupeIns(tx, psbt.__CACHE);
|
checkTxForDupeIns(tx.tx, psbt.__CACHE);
|
||||||
let inputCount = tx.ins.length;
|
let inputCount = tx.tx.ins.length;
|
||||||
let outputCount = tx.outs.length;
|
let outputCount = tx.tx.outs.length;
|
||||||
while (inputCount > 0) {
|
while (inputCount > 0) {
|
||||||
psbtBase.inputs.push({
|
psbtBase.inputs.push({});
|
||||||
unknownKeyVals: [],
|
|
||||||
});
|
|
||||||
inputCount--;
|
inputCount--;
|
||||||
}
|
}
|
||||||
while (outputCount > 0) {
|
while (outputCount > 0) {
|
||||||
psbtBase.outputs.push({
|
psbtBase.outputs.push({});
|
||||||
unknownKeyVals: [],
|
|
||||||
});
|
|
||||||
outputCount--;
|
outputCount--;
|
||||||
}
|
}
|
||||||
return psbt;
|
return psbt;
|
||||||
|
@ -87,16 +83,8 @@ class Psbt {
|
||||||
return this.fromBuffer(buffer, opts);
|
return this.fromBuffer(buffer, opts);
|
||||||
}
|
}
|
||||||
static fromBuffer(buffer, opts = {}) {
|
static fromBuffer(buffer, opts = {}) {
|
||||||
let tx;
|
const psbtBase = bip174_1.Psbt.fromBuffer(buffer, transactionFromBuffer);
|
||||||
const txCountGetter = txBuf => {
|
const tx = psbtBase.globalMap.unsignedTx.tx;
|
||||||
tx = transaction_1.Transaction.fromBuffer(txBuf);
|
|
||||||
checkTxEmpty(tx);
|
|
||||||
return {
|
|
||||||
inputCount: tx.ins.length,
|
|
||||||
outputCount: tx.outs.length,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
const psbtBase = bip174_1.Psbt.fromBuffer(buffer, txCountGetter);
|
|
||||||
const psbt = new Psbt(opts, psbtBase);
|
const psbt = new Psbt(opts, psbtBase);
|
||||||
psbt.__CACHE.__TX = tx;
|
psbt.__CACHE.__TX = tx;
|
||||||
checkTxForDupeIns(tx, psbt.__CACHE);
|
checkTxForDupeIns(tx, psbt.__CACHE);
|
||||||
|
@ -156,8 +144,9 @@ class Psbt {
|
||||||
addInput(inputData) {
|
addInput(inputData) {
|
||||||
checkInputsForPartialSig(this.data.inputs, 'addInput');
|
checkInputsForPartialSig(this.data.inputs, 'addInput');
|
||||||
const c = this.__CACHE;
|
const c = this.__CACHE;
|
||||||
const inputAdder = getInputAdder(c);
|
this.data.addInput(inputData);
|
||||||
this.data.addInput(inputData, inputAdder);
|
const txIn = c.__TX.ins[c.__TX.ins.length - 1];
|
||||||
|
checkTxInputCache(c, txIn);
|
||||||
const inputIndex = this.data.inputs.length - 1;
|
const inputIndex = this.data.inputs.length - 1;
|
||||||
const input = this.data.inputs[inputIndex];
|
const input = this.data.inputs[inputIndex];
|
||||||
if (input.nonWitnessUtxo) {
|
if (input.nonWitnessUtxo) {
|
||||||
|
@ -180,8 +169,7 @@ class Psbt {
|
||||||
outputData = Object.assign(outputData, { script });
|
outputData = Object.assign(outputData, { script });
|
||||||
}
|
}
|
||||||
const c = this.__CACHE;
|
const c = this.__CACHE;
|
||||||
const outputAdder = getOutputAdder(c);
|
this.data.addOutput(outputData);
|
||||||
this.data.addOutput(outputData, outputAdder, true);
|
|
||||||
c.__FEE_RATE = undefined;
|
c.__FEE_RATE = undefined;
|
||||||
c.__EXTRACTED_TX = undefined;
|
c.__EXTRACTED_TX = undefined;
|
||||||
return this;
|
return this;
|
||||||
|
@ -238,10 +226,9 @@ class Psbt {
|
||||||
isP2SH,
|
isP2SH,
|
||||||
isP2WSH,
|
isP2WSH,
|
||||||
);
|
);
|
||||||
if (finalScriptSig)
|
if (finalScriptSig) this.data.updateInput(inputIndex, { finalScriptSig });
|
||||||
this.data.addFinalScriptSigToInput(inputIndex, finalScriptSig);
|
|
||||||
if (finalScriptWitness)
|
if (finalScriptWitness)
|
||||||
this.data.addFinalScriptWitnessToInput(inputIndex, finalScriptWitness);
|
this.data.updateInput(inputIndex, { finalScriptWitness });
|
||||||
if (!finalScriptSig && !finalScriptWitness)
|
if (!finalScriptSig && !finalScriptWitness)
|
||||||
throw new Error(`Unknown error finalizing input #${inputIndex}`);
|
throw new Error(`Unknown error finalizing input #${inputIndex}`);
|
||||||
this.data.clearFinalizedInput(inputIndex);
|
this.data.clearFinalizedInput(inputIndex);
|
||||||
|
@ -349,11 +336,13 @@ class Psbt {
|
||||||
this.__CACHE,
|
this.__CACHE,
|
||||||
sighashTypes,
|
sighashTypes,
|
||||||
);
|
);
|
||||||
const partialSig = {
|
const partialSig = [
|
||||||
pubkey: keyPair.publicKey,
|
{
|
||||||
signature: bscript.signature.encode(keyPair.sign(hash), sighashType),
|
pubkey: keyPair.publicKey,
|
||||||
};
|
signature: bscript.signature.encode(keyPair.sign(hash), sighashType),
|
||||||
this.data.addPartialSigToInput(inputIndex, partialSig);
|
},
|
||||||
|
];
|
||||||
|
this.data.updateInput(inputIndex, { partialSig });
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
signInputAsync(
|
signInputAsync(
|
||||||
|
@ -372,11 +361,13 @@ class Psbt {
|
||||||
sighashTypes,
|
sighashTypes,
|
||||||
);
|
);
|
||||||
Promise.resolve(keyPair.sign(hash)).then(signature => {
|
Promise.resolve(keyPair.sign(hash)).then(signature => {
|
||||||
const partialSig = {
|
const partialSig = [
|
||||||
pubkey: keyPair.publicKey,
|
{
|
||||||
signature: bscript.signature.encode(signature, sighashType),
|
pubkey: keyPair.publicKey,
|
||||||
};
|
signature: bscript.signature.encode(signature, sighashType),
|
||||||
this.data.addPartialSigToInput(inputIndex, partialSig);
|
},
|
||||||
|
];
|
||||||
|
this.data.updateInput(inputIndex, { partialSig });
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -390,62 +381,23 @@ class Psbt {
|
||||||
toBase64() {
|
toBase64() {
|
||||||
return this.data.toBase64();
|
return this.data.toBase64();
|
||||||
}
|
}
|
||||||
addGlobalXpubToGlobal(globalXpub) {
|
updateGlobal(updateData) {
|
||||||
this.data.addGlobalXpubToGlobal(globalXpub);
|
this.data.updateGlobal(updateData);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
addNonWitnessUtxoToInput(inputIndex, nonWitnessUtxo) {
|
updateInput(inputIndex, updateData) {
|
||||||
this.data.addNonWitnessUtxoToInput(inputIndex, nonWitnessUtxo);
|
this.data.updateInput(inputIndex, updateData);
|
||||||
const input = this.data.inputs[inputIndex];
|
if (updateData.nonWitnessUtxo) {
|
||||||
addNonWitnessTxCache(this.__CACHE, input, inputIndex);
|
addNonWitnessTxCache(
|
||||||
|
this.__CACHE,
|
||||||
|
this.data.inputs[inputIndex],
|
||||||
|
inputIndex,
|
||||||
|
);
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
addWitnessUtxoToInput(inputIndex, witnessUtxo) {
|
updateOutput(outputIndex, updateData) {
|
||||||
this.data.addWitnessUtxoToInput(inputIndex, witnessUtxo);
|
this.data.updateOutput(outputIndex, updateData);
|
||||||
return this;
|
|
||||||
}
|
|
||||||
addPartialSigToInput(inputIndex, partialSig) {
|
|
||||||
this.data.addPartialSigToInput(inputIndex, partialSig);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
addSighashTypeToInput(inputIndex, sighashType) {
|
|
||||||
this.data.addSighashTypeToInput(inputIndex, sighashType);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
addRedeemScriptToInput(inputIndex, redeemScript) {
|
|
||||||
this.data.addRedeemScriptToInput(inputIndex, redeemScript);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
addWitnessScriptToInput(inputIndex, witnessScript) {
|
|
||||||
this.data.addWitnessScriptToInput(inputIndex, witnessScript);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
addBip32DerivationToInput(inputIndex, bip32Derivation) {
|
|
||||||
this.data.addBip32DerivationToInput(inputIndex, bip32Derivation);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
addFinalScriptSigToInput(inputIndex, finalScriptSig) {
|
|
||||||
this.data.addFinalScriptSigToInput(inputIndex, finalScriptSig);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
addFinalScriptWitnessToInput(inputIndex, finalScriptWitness) {
|
|
||||||
this.data.addFinalScriptWitnessToInput(inputIndex, finalScriptWitness);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
addPorCommitmentToInput(inputIndex, porCommitment) {
|
|
||||||
this.data.addPorCommitmentToInput(inputIndex, porCommitment);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
addRedeemScriptToOutput(outputIndex, redeemScript) {
|
|
||||||
this.data.addRedeemScriptToOutput(outputIndex, redeemScript);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
addWitnessScriptToOutput(outputIndex, witnessScript) {
|
|
||||||
this.data.addWitnessScriptToOutput(outputIndex, witnessScript);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
addBip32DerivationToOutput(outputIndex, bip32Derivation) {
|
|
||||||
this.data.addBip32DerivationToOutput(outputIndex, bip32Derivation);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
addUnknownKeyValToGlobal(keyVal) {
|
addUnknownKeyValToGlobal(keyVal) {
|
||||||
|
@ -466,6 +418,54 @@ class Psbt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.Psbt = Psbt;
|
exports.Psbt = Psbt;
|
||||||
|
const transactionFromBuffer = buffer => new PsbtTransaction(buffer);
|
||||||
|
class PsbtTransaction {
|
||||||
|
constructor(buffer = Buffer.from([2, 0, 0, 0, 0, 0, 0, 0, 0, 0])) {
|
||||||
|
this.tx = transaction_1.Transaction.fromBuffer(buffer);
|
||||||
|
if (this.tx.ins.some(input => input.script.length !== 0)) {
|
||||||
|
throw new Error('Format Error: Transaction ScriptSigs are not empty');
|
||||||
|
}
|
||||||
|
Object.defineProperty(this, 'tx', {
|
||||||
|
enumerable: false,
|
||||||
|
writable: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
getInputOutputCounts() {
|
||||||
|
return {
|
||||||
|
inputCount: this.tx.ins.length,
|
||||||
|
outputCount: this.tx.outs.length,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
addInput(input) {
|
||||||
|
if (
|
||||||
|
input.hash === undefined ||
|
||||||
|
input.index === undefined ||
|
||||||
|
(!Buffer.isBuffer(input.hash) && typeof input.hash !== 'string') ||
|
||||||
|
typeof input.index !== 'number'
|
||||||
|
) {
|
||||||
|
throw new Error('Error adding input.');
|
||||||
|
}
|
||||||
|
const hash =
|
||||||
|
typeof input.hash === 'string'
|
||||||
|
? bufferutils_1.reverseBuffer(Buffer.from(input.hash, 'hex'))
|
||||||
|
: input.hash;
|
||||||
|
this.tx.addInput(hash, input.index, input.sequence);
|
||||||
|
}
|
||||||
|
addOutput(output) {
|
||||||
|
if (
|
||||||
|
output.script === undefined ||
|
||||||
|
output.value === undefined ||
|
||||||
|
!Buffer.isBuffer(output.script) ||
|
||||||
|
typeof output.value !== 'number'
|
||||||
|
) {
|
||||||
|
throw new Error('Error adding output.');
|
||||||
|
}
|
||||||
|
this.tx.addOutput(output.script, output.value);
|
||||||
|
}
|
||||||
|
toBuffer() {
|
||||||
|
return this.tx.toBuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
function canFinalize(input, script, scriptType) {
|
function canFinalize(input, script, scriptType) {
|
||||||
switch (scriptType) {
|
switch (scriptType) {
|
||||||
case 'pubkey':
|
case 'pubkey':
|
||||||
|
@ -769,55 +769,6 @@ function getHashForSig(inputIndex, input, cache, sighashTypes) {
|
||||||
hash,
|
hash,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
function getInputAdder(cache) {
|
|
||||||
const selfCache = cache;
|
|
||||||
return (_inputData, txBuf) => {
|
|
||||||
if (
|
|
||||||
!txBuf ||
|
|
||||||
_inputData.hash === undefined ||
|
|
||||||
_inputData.index === undefined ||
|
|
||||||
(!Buffer.isBuffer(_inputData.hash) &&
|
|
||||||
typeof _inputData.hash !== 'string') ||
|
|
||||||
typeof _inputData.index !== 'number'
|
|
||||||
) {
|
|
||||||
throw new Error('Error adding input.');
|
|
||||||
}
|
|
||||||
const prevHash = Buffer.isBuffer(_inputData.hash)
|
|
||||||
? _inputData.hash
|
|
||||||
: bufferutils_1.reverseBuffer(Buffer.from(_inputData.hash, 'hex'));
|
|
||||||
// Check if input already exists in cache.
|
|
||||||
const input = { hash: prevHash, index: _inputData.index };
|
|
||||||
checkTxInputCache(selfCache, input);
|
|
||||||
selfCache.__TX.ins.push(
|
|
||||||
Object.assign({}, input, {
|
|
||||||
script: Buffer.alloc(0),
|
|
||||||
sequence:
|
|
||||||
_inputData.sequence || transaction_1.Transaction.DEFAULT_SEQUENCE,
|
|
||||||
witness: [],
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
return selfCache.__TX.toBuffer();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function getOutputAdder(cache) {
|
|
||||||
const selfCache = cache;
|
|
||||||
return (_outputData, txBuf) => {
|
|
||||||
if (
|
|
||||||
!txBuf ||
|
|
||||||
_outputData.script === undefined ||
|
|
||||||
_outputData.value === undefined ||
|
|
||||||
!Buffer.isBuffer(_outputData.script) ||
|
|
||||||
typeof _outputData.value !== 'number'
|
|
||||||
) {
|
|
||||||
throw new Error('Error adding output.');
|
|
||||||
}
|
|
||||||
selfCache.__TX.outs.push({
|
|
||||||
script: _outputData.script,
|
|
||||||
value: _outputData.value,
|
|
||||||
});
|
|
||||||
return selfCache.__TX.toBuffer();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function getPayment(script, scriptType, partialSig) {
|
function getPayment(script, scriptType, partialSig) {
|
||||||
let payment;
|
let payment;
|
||||||
switch (scriptType) {
|
switch (scriptType) {
|
||||||
|
|
28
test/psbt.js
28
test/psbt.js
|
@ -72,20 +72,8 @@ describe(`Psbt`, () => {
|
||||||
const fixtureData = f[`${inputOrOutput}Data`]
|
const fixtureData = f[`${inputOrOutput}Data`]
|
||||||
if (fixtureData) {
|
if (fixtureData) {
|
||||||
for (const [i, data] of fixtureData.entries()) {
|
for (const [i, data] of fixtureData.entries()) {
|
||||||
const attrs = Object.keys(data)
|
const txt = upperCaseFirstLetter(inputOrOutput)
|
||||||
for (const attr of attrs) {
|
psbt[`update${txt}`](i, data)
|
||||||
const upperAttr = upperCaseFirstLetter(attr)
|
|
||||||
let adder = psbt[`add${upperAttr}To${upperCaseFirstLetter(inputOrOutput)}`]
|
|
||||||
if (adder !== undefined) {
|
|
||||||
adder = adder.bind(psbt)
|
|
||||||
const arg = data[attr]
|
|
||||||
if (Array.isArray(arg)) {
|
|
||||||
arg.forEach(a => adder(i, a))
|
|
||||||
} else {
|
|
||||||
adder(i, arg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -309,9 +297,11 @@ describe(`Psbt`, () => {
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
psbt.finalizeAllInputs()
|
psbt.finalizeAllInputs()
|
||||||
}, new RegExp('No script found for input #0'))
|
}, new RegExp('No script found for input #0'))
|
||||||
psbt.addWitnessUtxoToInput(0, {
|
psbt.updateInput(0, {
|
||||||
script: Buffer.from('0014d85c2b71d0060b09c9886aeb815e50991dda124d', 'hex'),
|
witnessUtxo: {
|
||||||
value: 2e5
|
script: Buffer.from('0014d85c2b71d0060b09c9886aeb815e50991dda124d', 'hex'),
|
||||||
|
value: 2e5
|
||||||
|
}
|
||||||
})
|
})
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
psbt.finalizeAllInputs()
|
psbt.finalizeAllInputs()
|
||||||
|
@ -438,7 +428,7 @@ describe(`Psbt`, () => {
|
||||||
assert.strictEqual(clone.toBase64(), psbt.toBase64())
|
assert.strictEqual(clone.toBase64(), psbt.toBase64())
|
||||||
assert.strictEqual(clone.toBase64(), notAClone.toBase64())
|
assert.strictEqual(clone.toBase64(), notAClone.toBase64())
|
||||||
assert.strictEqual(psbt.toBase64(), notAClone.toBase64())
|
assert.strictEqual(psbt.toBase64(), notAClone.toBase64())
|
||||||
psbt.data.globalMap.unsignedTx[3] = 0xff
|
psbt.__CACHE.__TX.version |= 0xff0000
|
||||||
assert.notStrictEqual(clone.toBase64(), psbt.toBase64())
|
assert.notStrictEqual(clone.toBase64(), psbt.toBase64())
|
||||||
assert.notStrictEqual(clone.toBase64(), notAClone.toBase64())
|
assert.notStrictEqual(clone.toBase64(), notAClone.toBase64())
|
||||||
assert.strictEqual(psbt.toBase64(), notAClone.toBase64())
|
assert.strictEqual(psbt.toBase64(), notAClone.toBase64())
|
||||||
|
@ -565,7 +555,7 @@ describe(`Psbt`, () => {
|
||||||
assert.strictEqual(psbt.__CACHE.__NON_WITNESS_UTXO_BUF_CACHE[index], undefined)
|
assert.strictEqual(psbt.__CACHE.__NON_WITNESS_UTXO_BUF_CACHE[index], undefined)
|
||||||
|
|
||||||
// Cache is populated
|
// Cache is populated
|
||||||
psbt.addNonWitnessUtxoToInput(index, f.nonWitnessUtxo)
|
psbt.updateInput(index, { nonWitnessUtxo: f.nonWitnessUtxo })
|
||||||
const value = psbt.data.inputs[index].nonWitnessUtxo
|
const value = psbt.data.inputs[index].nonWitnessUtxo
|
||||||
assert.ok(psbt.__CACHE.__NON_WITNESS_UTXO_BUF_CACHE[index].equals(value))
|
assert.ok(psbt.__CACHE.__NON_WITNESS_UTXO_BUF_CACHE[index].equals(value))
|
||||||
assert.ok(psbt.__CACHE.__NON_WITNESS_UTXO_BUF_CACHE[index].equals(f.nonWitnessUtxo))
|
assert.ok(psbt.__CACHE.__NON_WITNESS_UTXO_BUF_CACHE[index].equals(f.nonWitnessUtxo))
|
||||||
|
|
324
ts_src/psbt.ts
324
ts_src/psbt.ts
|
@ -1,21 +1,16 @@
|
||||||
import { Psbt as PsbtBase } from 'bip174';
|
import { Psbt as PsbtBase } from 'bip174';
|
||||||
import * as varuint from 'bip174/src/lib/converter/varint';
|
import * as varuint from 'bip174/src/lib/converter/varint';
|
||||||
import {
|
import {
|
||||||
Bip32Derivation,
|
|
||||||
FinalScriptSig,
|
|
||||||
FinalScriptWitness,
|
|
||||||
GlobalXpub,
|
|
||||||
KeyValue,
|
KeyValue,
|
||||||
NonWitnessUtxo,
|
|
||||||
PartialSig,
|
PartialSig,
|
||||||
PorCommitment,
|
PsbtGlobalUpdate,
|
||||||
PsbtInput,
|
PsbtInput,
|
||||||
RedeemScript,
|
PsbtInputUpdate,
|
||||||
SighashType,
|
PsbtOutputUpdate,
|
||||||
|
Transaction as ITransaction,
|
||||||
|
TransactionFromBuffer,
|
||||||
TransactionInput,
|
TransactionInput,
|
||||||
TransactionOutput,
|
TransactionOutput,
|
||||||
WitnessScript,
|
|
||||||
WitnessUtxo,
|
|
||||||
} from 'bip174/src/lib/interfaces';
|
} from 'bip174/src/lib/interfaces';
|
||||||
import { checkForInput } from 'bip174/src/lib/utils';
|
import { checkForInput } from 'bip174/src/lib/utils';
|
||||||
import { toOutputScript } from './address';
|
import { toOutputScript } from './address';
|
||||||
|
@ -38,24 +33,20 @@ const DEFAULT_OPTS: PsbtOpts = {
|
||||||
|
|
||||||
export class Psbt {
|
export class Psbt {
|
||||||
static fromTransaction(txBuf: Buffer, opts: PsbtOptsOptional = {}): Psbt {
|
static fromTransaction(txBuf: Buffer, opts: PsbtOptsOptional = {}): Psbt {
|
||||||
const tx = Transaction.fromBuffer(txBuf);
|
const tx = new PsbtTransaction(txBuf);
|
||||||
checkTxEmpty(tx);
|
checkTxEmpty(tx.tx);
|
||||||
const psbtBase = new PsbtBase();
|
const psbtBase = new PsbtBase(tx);
|
||||||
const psbt = new Psbt(opts, psbtBase);
|
const psbt = new Psbt(opts, psbtBase);
|
||||||
psbt.__CACHE.__TX = tx;
|
psbt.__CACHE.__TX = tx.tx;
|
||||||
checkTxForDupeIns(tx, psbt.__CACHE);
|
checkTxForDupeIns(tx.tx, psbt.__CACHE);
|
||||||
let inputCount = tx.ins.length;
|
let inputCount = tx.tx.ins.length;
|
||||||
let outputCount = tx.outs.length;
|
let outputCount = tx.tx.outs.length;
|
||||||
while (inputCount > 0) {
|
while (inputCount > 0) {
|
||||||
psbtBase.inputs.push({
|
psbtBase.inputs.push({});
|
||||||
unknownKeyVals: [],
|
|
||||||
});
|
|
||||||
inputCount--;
|
inputCount--;
|
||||||
}
|
}
|
||||||
while (outputCount > 0) {
|
while (outputCount > 0) {
|
||||||
psbtBase.outputs.push({
|
psbtBase.outputs.push({});
|
||||||
unknownKeyVals: [],
|
|
||||||
});
|
|
||||||
outputCount--;
|
outputCount--;
|
||||||
}
|
}
|
||||||
return psbt;
|
return psbt;
|
||||||
|
@ -72,27 +63,16 @@ export class Psbt {
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromBuffer(buffer: Buffer, opts: PsbtOptsOptional = {}): Psbt {
|
static fromBuffer(buffer: Buffer, opts: PsbtOptsOptional = {}): Psbt {
|
||||||
let tx: Transaction | undefined;
|
const psbtBase = PsbtBase.fromBuffer(buffer, transactionFromBuffer);
|
||||||
const txCountGetter = (
|
const tx: Transaction = (psbtBase.globalMap.unsignedTx as PsbtTransaction)
|
||||||
txBuf: Buffer,
|
.tx;
|
||||||
): {
|
|
||||||
inputCount: number;
|
|
||||||
outputCount: number;
|
|
||||||
} => {
|
|
||||||
tx = Transaction.fromBuffer(txBuf);
|
|
||||||
checkTxEmpty(tx);
|
|
||||||
return {
|
|
||||||
inputCount: tx.ins.length,
|
|
||||||
outputCount: tx.outs.length,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
const psbtBase = PsbtBase.fromBuffer(buffer, txCountGetter);
|
|
||||||
const psbt = new Psbt(opts, psbtBase);
|
const psbt = new Psbt(opts, psbtBase);
|
||||||
psbt.__CACHE.__TX = tx!;
|
psbt.__CACHE.__TX = tx;
|
||||||
checkTxForDupeIns(tx!, psbt.__CACHE);
|
checkTxForDupeIns(tx, psbt.__CACHE);
|
||||||
return psbt;
|
return psbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsignedTx: Buffer;
|
||||||
private __CACHE: PsbtCache = {
|
private __CACHE: PsbtCache = {
|
||||||
__NON_WITNESS_UTXO_TX_CACHE: [],
|
__NON_WITNESS_UTXO_TX_CACHE: [],
|
||||||
__NON_WITNESS_UTXO_BUF_CACHE: [],
|
__NON_WITNESS_UTXO_BUF_CACHE: [],
|
||||||
|
@ -103,17 +83,17 @@ export class Psbt {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
opts: PsbtOptsOptional = {},
|
opts: PsbtOptsOptional = {},
|
||||||
readonly data: PsbtBase = new PsbtBase(),
|
readonly data: PsbtBase = new PsbtBase(new PsbtTransaction()),
|
||||||
) {
|
) {
|
||||||
// set defaults
|
// set defaults
|
||||||
this.opts = Object.assign({}, DEFAULT_OPTS, opts);
|
this.opts = Object.assign({}, DEFAULT_OPTS, opts);
|
||||||
const c = this.__CACHE;
|
const c = this.__CACHE;
|
||||||
c.__TX = Transaction.fromBuffer(data.globalMap.unsignedTx!);
|
c.__TX = (this.data.globalMap.unsignedTx as PsbtTransaction).tx;
|
||||||
if (this.data.inputs.length === 0) this.setVersion(2);
|
if (this.data.inputs.length === 0) this.setVersion(2);
|
||||||
|
|
||||||
// set cache
|
// set cache
|
||||||
delete data.globalMap.unsignedTx;
|
this.unsignedTx = Buffer.from([]);
|
||||||
Object.defineProperty(data.globalMap, 'unsignedTx', {
|
Object.defineProperty(this, 'unsignedTx', {
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
get(): Buffer {
|
get(): Buffer {
|
||||||
const buf = c.__TX_BUF_CACHE;
|
const buf = c.__TX_BUF_CACHE;
|
||||||
|
@ -206,8 +186,9 @@ export class Psbt {
|
||||||
addInput(inputData: TransactionInput): this {
|
addInput(inputData: TransactionInput): this {
|
||||||
checkInputsForPartialSig(this.data.inputs, 'addInput');
|
checkInputsForPartialSig(this.data.inputs, 'addInput');
|
||||||
const c = this.__CACHE;
|
const c = this.__CACHE;
|
||||||
const inputAdder = getInputAdder(c);
|
this.data.addInput(inputData);
|
||||||
this.data.addInput(inputData, inputAdder);
|
const txIn = c.__TX.ins[c.__TX.ins.length - 1];
|
||||||
|
checkTxInputCache(c, txIn);
|
||||||
|
|
||||||
const inputIndex = this.data.inputs.length - 1;
|
const inputIndex = this.data.inputs.length - 1;
|
||||||
const input = this.data.inputs[inputIndex];
|
const input = this.data.inputs[inputIndex];
|
||||||
|
@ -233,8 +214,7 @@ export class Psbt {
|
||||||
outputData = Object.assign(outputData, { script });
|
outputData = Object.assign(outputData, { script });
|
||||||
}
|
}
|
||||||
const c = this.__CACHE;
|
const c = this.__CACHE;
|
||||||
const outputAdder = getOutputAdder(c);
|
this.data.addOutput(outputData);
|
||||||
this.data.addOutput(outputData, outputAdder, true);
|
|
||||||
c.__FEE_RATE = undefined;
|
c.__FEE_RATE = undefined;
|
||||||
c.__EXTRACTED_TX = undefined;
|
c.__EXTRACTED_TX = undefined;
|
||||||
return this;
|
return this;
|
||||||
|
@ -299,10 +279,9 @@ export class Psbt {
|
||||||
isP2WSH,
|
isP2WSH,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (finalScriptSig)
|
if (finalScriptSig) this.data.updateInput(inputIndex, { finalScriptSig });
|
||||||
this.data.addFinalScriptSigToInput(inputIndex, finalScriptSig);
|
|
||||||
if (finalScriptWitness)
|
if (finalScriptWitness)
|
||||||
this.data.addFinalScriptWitnessToInput(inputIndex, finalScriptWitness);
|
this.data.updateInput(inputIndex, { finalScriptWitness });
|
||||||
if (!finalScriptSig && !finalScriptWitness)
|
if (!finalScriptSig && !finalScriptWitness)
|
||||||
throw new Error(`Unknown error finalizing input #${inputIndex}`);
|
throw new Error(`Unknown error finalizing input #${inputIndex}`);
|
||||||
|
|
||||||
|
@ -427,12 +406,14 @@ export class Psbt {
|
||||||
sighashTypes,
|
sighashTypes,
|
||||||
);
|
);
|
||||||
|
|
||||||
const partialSig = {
|
const partialSig = [
|
||||||
pubkey: keyPair.publicKey,
|
{
|
||||||
signature: bscript.signature.encode(keyPair.sign(hash), sighashType),
|
pubkey: keyPair.publicKey,
|
||||||
};
|
signature: bscript.signature.encode(keyPair.sign(hash), sighashType),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
this.data.addPartialSigToInput(inputIndex, partialSig);
|
this.data.updateInput(inputIndex, { partialSig });
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,12 +435,14 @@ export class Psbt {
|
||||||
);
|
);
|
||||||
|
|
||||||
Promise.resolve(keyPair.sign(hash)).then(signature => {
|
Promise.resolve(keyPair.sign(hash)).then(signature => {
|
||||||
const partialSig = {
|
const partialSig = [
|
||||||
pubkey: keyPair.publicKey,
|
{
|
||||||
signature: bscript.signature.encode(signature, sighashType),
|
pubkey: keyPair.publicKey,
|
||||||
};
|
signature: bscript.signature.encode(signature, sighashType),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
this.data.addPartialSigToInput(inputIndex, partialSig);
|
this.data.updateInput(inputIndex, { partialSig });
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -478,102 +461,25 @@ export class Psbt {
|
||||||
return this.data.toBase64();
|
return this.data.toBase64();
|
||||||
}
|
}
|
||||||
|
|
||||||
addGlobalXpubToGlobal(globalXpub: GlobalXpub): this {
|
updateGlobal(updateData: PsbtGlobalUpdate): this {
|
||||||
this.data.addGlobalXpubToGlobal(globalXpub);
|
this.data.updateGlobal(updateData);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
addNonWitnessUtxoToInput(
|
updateInput(inputIndex: number, updateData: PsbtInputUpdate): this {
|
||||||
inputIndex: number,
|
this.data.updateInput(inputIndex, updateData);
|
||||||
nonWitnessUtxo: NonWitnessUtxo,
|
if (updateData.nonWitnessUtxo) {
|
||||||
): this {
|
addNonWitnessTxCache(
|
||||||
this.data.addNonWitnessUtxoToInput(inputIndex, nonWitnessUtxo);
|
this.__CACHE,
|
||||||
const input = this.data.inputs[inputIndex];
|
this.data.inputs[inputIndex],
|
||||||
addNonWitnessTxCache(this.__CACHE, input, inputIndex);
|
inputIndex,
|
||||||
|
);
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
addWitnessUtxoToInput(inputIndex: number, witnessUtxo: WitnessUtxo): this {
|
updateOutput(outputIndex: number, updateData: PsbtOutputUpdate): this {
|
||||||
this.data.addWitnessUtxoToInput(inputIndex, witnessUtxo);
|
this.data.updateOutput(outputIndex, updateData);
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
addPartialSigToInput(inputIndex: number, partialSig: PartialSig): this {
|
|
||||||
this.data.addPartialSigToInput(inputIndex, partialSig);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
addSighashTypeToInput(inputIndex: number, sighashType: SighashType): this {
|
|
||||||
this.data.addSighashTypeToInput(inputIndex, sighashType);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
addRedeemScriptToInput(inputIndex: number, redeemScript: RedeemScript): this {
|
|
||||||
this.data.addRedeemScriptToInput(inputIndex, redeemScript);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
addWitnessScriptToInput(
|
|
||||||
inputIndex: number,
|
|
||||||
witnessScript: WitnessScript,
|
|
||||||
): this {
|
|
||||||
this.data.addWitnessScriptToInput(inputIndex, witnessScript);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
addBip32DerivationToInput(
|
|
||||||
inputIndex: number,
|
|
||||||
bip32Derivation: Bip32Derivation,
|
|
||||||
): this {
|
|
||||||
this.data.addBip32DerivationToInput(inputIndex, bip32Derivation);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
addFinalScriptSigToInput(
|
|
||||||
inputIndex: number,
|
|
||||||
finalScriptSig: FinalScriptSig,
|
|
||||||
): this {
|
|
||||||
this.data.addFinalScriptSigToInput(inputIndex, finalScriptSig);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
addFinalScriptWitnessToInput(
|
|
||||||
inputIndex: number,
|
|
||||||
finalScriptWitness: FinalScriptWitness,
|
|
||||||
): this {
|
|
||||||
this.data.addFinalScriptWitnessToInput(inputIndex, finalScriptWitness);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
addPorCommitmentToInput(
|
|
||||||
inputIndex: number,
|
|
||||||
porCommitment: PorCommitment,
|
|
||||||
): this {
|
|
||||||
this.data.addPorCommitmentToInput(inputIndex, porCommitment);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
addRedeemScriptToOutput(
|
|
||||||
outputIndex: number,
|
|
||||||
redeemScript: RedeemScript,
|
|
||||||
): this {
|
|
||||||
this.data.addRedeemScriptToOutput(outputIndex, redeemScript);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
addWitnessScriptToOutput(
|
|
||||||
outputIndex: number,
|
|
||||||
witnessScript: WitnessScript,
|
|
||||||
): this {
|
|
||||||
this.data.addWitnessScriptToOutput(outputIndex, witnessScript);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
addBip32DerivationToOutput(
|
|
||||||
outputIndex: number,
|
|
||||||
bip32Derivation: Bip32Derivation,
|
|
||||||
): this {
|
|
||||||
this.data.addBip32DerivationToOutput(outputIndex, bip32Derivation);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -618,6 +524,67 @@ interface PsbtOpts {
|
||||||
maximumFeeRate: number;
|
maximumFeeRate: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const transactionFromBuffer: TransactionFromBuffer = (
|
||||||
|
buffer: Buffer,
|
||||||
|
): ITransaction => new PsbtTransaction(buffer);
|
||||||
|
|
||||||
|
class PsbtTransaction implements ITransaction {
|
||||||
|
tx: Transaction;
|
||||||
|
constructor(buffer: Buffer = Buffer.from([2, 0, 0, 0, 0, 0, 0, 0, 0, 0])) {
|
||||||
|
this.tx = Transaction.fromBuffer(buffer);
|
||||||
|
if (this.tx.ins.some(input => input.script.length !== 0)) {
|
||||||
|
throw new Error('Format Error: Transaction ScriptSigs are not empty');
|
||||||
|
}
|
||||||
|
Object.defineProperty(this, 'tx', {
|
||||||
|
enumerable: false,
|
||||||
|
writable: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getInputOutputCounts(): {
|
||||||
|
inputCount: number;
|
||||||
|
outputCount: number;
|
||||||
|
} {
|
||||||
|
return {
|
||||||
|
inputCount: this.tx.ins.length,
|
||||||
|
outputCount: this.tx.outs.length,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
addInput(input: any): void {
|
||||||
|
if (
|
||||||
|
(input as any).hash === undefined ||
|
||||||
|
(input as any).index === undefined ||
|
||||||
|
(!Buffer.isBuffer((input as any).hash) &&
|
||||||
|
typeof (input as any).hash !== 'string') ||
|
||||||
|
typeof (input as any).index !== 'number'
|
||||||
|
) {
|
||||||
|
throw new Error('Error adding input.');
|
||||||
|
}
|
||||||
|
const hash =
|
||||||
|
typeof input.hash === 'string'
|
||||||
|
? reverseBuffer(Buffer.from(input.hash, 'hex'))
|
||||||
|
: input.hash;
|
||||||
|
this.tx.addInput(hash, input.index, input.sequence);
|
||||||
|
}
|
||||||
|
|
||||||
|
addOutput(output: any): void {
|
||||||
|
if (
|
||||||
|
(output as any).script === undefined ||
|
||||||
|
(output as any).value === undefined ||
|
||||||
|
!Buffer.isBuffer((output as any).script) ||
|
||||||
|
typeof (output as any).value !== 'number'
|
||||||
|
) {
|
||||||
|
throw new Error('Error adding output.');
|
||||||
|
}
|
||||||
|
this.tx.addOutput(output.script, output.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
toBuffer(): Buffer {
|
||||||
|
return this.tx.toBuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function canFinalize(
|
function canFinalize(
|
||||||
input: PsbtInput,
|
input: PsbtInput,
|
||||||
script: Buffer,
|
script: Buffer,
|
||||||
|
@ -979,61 +946,6 @@ function getHashForSig(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getInputAdder(
|
|
||||||
cache: PsbtCache,
|
|
||||||
): (_inputData: TransactionInput, txBuf: Buffer) => Buffer {
|
|
||||||
const selfCache = cache;
|
|
||||||
return (_inputData: TransactionInput, txBuf: Buffer): Buffer => {
|
|
||||||
if (
|
|
||||||
!txBuf ||
|
|
||||||
(_inputData as any).hash === undefined ||
|
|
||||||
(_inputData as any).index === undefined ||
|
|
||||||
(!Buffer.isBuffer((_inputData as any).hash) &&
|
|
||||||
typeof (_inputData as any).hash !== 'string') ||
|
|
||||||
typeof (_inputData as any).index !== 'number'
|
|
||||||
) {
|
|
||||||
throw new Error('Error adding input.');
|
|
||||||
}
|
|
||||||
const prevHash = Buffer.isBuffer(_inputData.hash)
|
|
||||||
? _inputData.hash
|
|
||||||
: reverseBuffer(Buffer.from(_inputData.hash, 'hex'));
|
|
||||||
|
|
||||||
// Check if input already exists in cache.
|
|
||||||
const input = { hash: prevHash, index: _inputData.index };
|
|
||||||
checkTxInputCache(selfCache, input);
|
|
||||||
|
|
||||||
selfCache.__TX.ins.push({
|
|
||||||
...input,
|
|
||||||
script: Buffer.alloc(0),
|
|
||||||
sequence: _inputData.sequence || Transaction.DEFAULT_SEQUENCE,
|
|
||||||
witness: [],
|
|
||||||
});
|
|
||||||
return selfCache.__TX.toBuffer();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function getOutputAdder(
|
|
||||||
cache: PsbtCache,
|
|
||||||
): (_outputData: TransactionOutput, txBuf: Buffer) => Buffer {
|
|
||||||
const selfCache = cache;
|
|
||||||
return (_outputData: TransactionOutput, txBuf: Buffer): Buffer => {
|
|
||||||
if (
|
|
||||||
!txBuf ||
|
|
||||||
(_outputData as any).script === undefined ||
|
|
||||||
(_outputData as any).value === undefined ||
|
|
||||||
!Buffer.isBuffer((_outputData as any).script) ||
|
|
||||||
typeof (_outputData as any).value !== 'number'
|
|
||||||
) {
|
|
||||||
throw new Error('Error adding output.');
|
|
||||||
}
|
|
||||||
selfCache.__TX.outs.push({
|
|
||||||
script: (_outputData as any).script!,
|
|
||||||
value: _outputData.value,
|
|
||||||
});
|
|
||||||
return selfCache.__TX.toBuffer();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPayment(
|
function getPayment(
|
||||||
script: Buffer,
|
script: Buffer,
|
||||||
scriptType: string,
|
scriptType: string,
|
||||||
|
|
20
types/psbt.d.ts
vendored
20
types/psbt.d.ts
vendored
|
@ -1,6 +1,6 @@
|
||||||
/// <reference types="node" />
|
/// <reference types="node" />
|
||||||
import { Psbt as PsbtBase } from 'bip174';
|
import { Psbt as PsbtBase } from 'bip174';
|
||||||
import { Bip32Derivation, FinalScriptSig, FinalScriptWitness, GlobalXpub, KeyValue, NonWitnessUtxo, PartialSig, PorCommitment, RedeemScript, SighashType, TransactionInput, TransactionOutput, WitnessScript, WitnessUtxo } from 'bip174/src/lib/interfaces';
|
import { KeyValue, PsbtGlobalUpdate, PsbtInputUpdate, PsbtOutputUpdate, TransactionInput, TransactionOutput } from 'bip174/src/lib/interfaces';
|
||||||
import { Signer, SignerAsync } from './ecpair';
|
import { Signer, SignerAsync } from './ecpair';
|
||||||
import { Network } from './networks';
|
import { Network } from './networks';
|
||||||
import { Transaction } from './transaction';
|
import { Transaction } from './transaction';
|
||||||
|
@ -10,6 +10,7 @@ export declare class Psbt {
|
||||||
static fromBase64(data: string, opts?: PsbtOptsOptional): Psbt;
|
static fromBase64(data: string, opts?: PsbtOptsOptional): Psbt;
|
||||||
static fromHex(data: string, opts?: PsbtOptsOptional): Psbt;
|
static fromHex(data: string, opts?: PsbtOptsOptional): Psbt;
|
||||||
static fromBuffer(buffer: Buffer, opts?: PsbtOptsOptional): Psbt;
|
static fromBuffer(buffer: Buffer, opts?: PsbtOptsOptional): Psbt;
|
||||||
|
unsignedTx: Buffer;
|
||||||
private __CACHE;
|
private __CACHE;
|
||||||
private opts;
|
private opts;
|
||||||
constructor(opts?: PsbtOptsOptional, data?: PsbtBase);
|
constructor(opts?: PsbtOptsOptional, data?: PsbtBase);
|
||||||
|
@ -37,20 +38,9 @@ export declare class Psbt {
|
||||||
toBuffer(): Buffer;
|
toBuffer(): Buffer;
|
||||||
toHex(): string;
|
toHex(): string;
|
||||||
toBase64(): string;
|
toBase64(): string;
|
||||||
addGlobalXpubToGlobal(globalXpub: GlobalXpub): this;
|
updateGlobal(updateData: PsbtGlobalUpdate): this;
|
||||||
addNonWitnessUtxoToInput(inputIndex: number, nonWitnessUtxo: NonWitnessUtxo): this;
|
updateInput(inputIndex: number, updateData: PsbtInputUpdate): this;
|
||||||
addWitnessUtxoToInput(inputIndex: number, witnessUtxo: WitnessUtxo): this;
|
updateOutput(outputIndex: number, updateData: PsbtOutputUpdate): this;
|
||||||
addPartialSigToInput(inputIndex: number, partialSig: PartialSig): this;
|
|
||||||
addSighashTypeToInput(inputIndex: number, sighashType: SighashType): this;
|
|
||||||
addRedeemScriptToInput(inputIndex: number, redeemScript: RedeemScript): this;
|
|
||||||
addWitnessScriptToInput(inputIndex: number, witnessScript: WitnessScript): this;
|
|
||||||
addBip32DerivationToInput(inputIndex: number, bip32Derivation: Bip32Derivation): this;
|
|
||||||
addFinalScriptSigToInput(inputIndex: number, finalScriptSig: FinalScriptSig): this;
|
|
||||||
addFinalScriptWitnessToInput(inputIndex: number, finalScriptWitness: FinalScriptWitness): this;
|
|
||||||
addPorCommitmentToInput(inputIndex: number, porCommitment: PorCommitment): this;
|
|
||||||
addRedeemScriptToOutput(outputIndex: number, redeemScript: RedeemScript): this;
|
|
||||||
addWitnessScriptToOutput(outputIndex: number, witnessScript: WitnessScript): this;
|
|
||||||
addBip32DerivationToOutput(outputIndex: number, bip32Derivation: Bip32Derivation): this;
|
|
||||||
addUnknownKeyValToGlobal(keyVal: KeyValue): this;
|
addUnknownKeyValToGlobal(keyVal: KeyValue): this;
|
||||||
addUnknownKeyValToInput(inputIndex: number, keyVal: KeyValue): this;
|
addUnknownKeyValToInput(inputIndex: number, keyVal: KeyValue): this;
|
||||||
addUnknownKeyValToOutput(outputIndex: number, keyVal: KeyValue): this;
|
addUnknownKeyValToOutput(outputIndex: number, keyVal: KeyValue): this;
|
||||||
|
|
Loading…
Reference in a new issue