diff --git a/test/fixtures/psbt.json b/test/fixtures/psbt.json index aeed39d..61ab114 100644 --- a/test/fixtures/psbt.json +++ b/test/fixtures/psbt.json @@ -314,7 +314,7 @@ "exception": "Error adding input." }, { - "description": "checks for hash and index", + "description": "should be equal", "inputData": { "hash": "Buffer.from('000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f', 'hex')", "index": 2 @@ -326,12 +326,19 @@ "addOutput": { "checks": [ { - "description": "checks for hash and index", + "description": "Checks value is number", "outputData": { "address": "1P2NFEBp32V2arRwZNww6tgXEV58FG94mr", "value": "xyz" }, "exception": "Error adding output." + }, + { + "description": "Adds output normally", + "outputData": { + "address": "1P2NFEBp32V2arRwZNww6tgXEV58FG94mr", + "value": 42 + } } ] }, @@ -446,8 +453,8 @@ }, { "type": "P2WPKH", - "psbt": "cHNidP8BAFUCAAAAAQgW434j2ReNazU0B0+Wa45cPWyUkrl6beWc1ZA6s7qYAAAAAAD/////AYA4AQAAAAAAGXapFC6fT3nay4TXcKcXnM8ZZ89Pmi8xiKwAAAAAAAEAvAIAAAABX6KFQJqSuzjln4vq33jes8S/HAJw/W8fB2hmYJvF95AAAAAAakcwRAIgBfylcQEFaoyuzZcVT1AG3nU3FxDE2ZRNSQbH0Pb38pkCIBh+SztZRlITl/WbdA/Z7SVsVqApPeT1HmzpiLcunN4yASECHwUJGd/AygUjfs6zraDrLcjE5arbSBzHCVX/DQD3tuf/////AZBfAQAAAAAAFgAU2gkxRpZzSTR+etKYJ+B243D+sbYAAAAAIgIDV7l7X08dWtzMR2saPXJo782Tot5+PQBMZZOm3GGTUHpIMEUCIQDxPCn2fwfxoYgGVyi5++mXNAmCX2wWRS7LuJB2qQkMVQIgHsxylMEWd7ladApdSpnEtSwWb4/QJGOnsDGZCPxvfucBAAA=", - "result": "cHNidP8BAFUCAAAAAQgW434j2ReNazU0B0+Wa45cPWyUkrl6beWc1ZA6s7qYAAAAAAD/////AYA4AQAAAAAAGXapFC6fT3nay4TXcKcXnM8ZZ89Pmi8xiKwAAAAAAAEAvAIAAAABX6KFQJqSuzjln4vq33jes8S/HAJw/W8fB2hmYJvF95AAAAAAakcwRAIgBfylcQEFaoyuzZcVT1AG3nU3FxDE2ZRNSQbH0Pb38pkCIBh+SztZRlITl/WbdA/Z7SVsVqApPeT1HmzpiLcunN4yASECHwUJGd/AygUjfs6zraDrLcjE5arbSBzHCVX/DQD3tuf/////AZBfAQAAAAAAFgAU2gkxRpZzSTR+etKYJ+B243D+sbYAAAAAAQcAAAA=" + "psbt": "cHNidP8BAFICAAAAAb5UIQFSoXPjqxSmuiSZkM5PjaycnrXQ6VB+u2+MzbSGAAAAAAD/////ASBOAAAAAAAAFgAUXsVBEaHSlhycDORbHHtBKwDo4zIAAAAAAAEBHzB1AAAAAAAAFgAUvIgag7HZu7Rjd/ugmJC/MHlZmAYiAgLN1zezMD4c4uegTbgfJ1GCtN5/hlJYaJt7e8mt1BVzIEcwRAIgXhgL5G81tXP7MAaKJtA0QaFu17bLocOGqxXmDoIfYUACIAOIynpoPS/dTz9Omg2h7v5kiql7ab0SPzWDdxpvpsUcAQAA", + "result": "cHNidP8BAFICAAAAAb5UIQFSoXPjqxSmuiSZkM5PjaycnrXQ6VB+u2+MzbSGAAAAAAD/////ASBOAAAAAAAAFgAUXsVBEaHSlhycDORbHHtBKwDo4zIAAAAAAAEBHzB1AAAAAAAAFgAUvIgag7HZu7Rjd/ugmJC/MHlZmAYBCGsCRzBEAiBeGAvkbzW1c/swBoom0DRBoW7Xtsuhw4arFeYOgh9hQAIgA4jKemg9L91PP06aDaHu/mSKqXtpvRI/NYN3Gm+mxRwBIQLN1zezMD4c4uegTbgfJ1GCtN5/hlJYaJt7e8mt1BVzIAAA" }, { "type": "P2WSH-P2PK", @@ -478,5 +485,8 @@ "nonWitnessUtxo": "Buffer.from('0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f618765000000', 'hex')", "inputIndex": 0 } + }, + "clone": { + "psbt": "cHNidP8BAKYCAAAAAlwKQ3suPWwEJ/zQ9sZsIioOcHKU1KoLMxlMNSXVIkEWAAAAAAD/////YYDJMap+mYgbTrCNAdpWHN+EkKvl+XYao/6co/EQfwMAAAAAAP////8CkF8BAAAAAAAWABRnPBAmVHz2HL+8/1U+QG5L2thjmjhKAAAAAAAAIgAg700yfFRyhWzQnPHIUb/XQqsjlpf4A0uw682pCVWuQ8IAAAAAAAEBKzB1AAAAAAAAIgAgth9oE4cDfC5aV58VgkW5CptHsIxppYzJV8C5kT6aTo8iAgNfNgnFnEPS9s4PY/I5bezpWiAEzQ4DRTASgdSdeMM06UgwRQIhALO0xRpuqP3aVkm+DPykrtqe6fPNSgNblp9K9MAwmtHJAiAHV5ZvZN8Vi49n/o9ISFyvtHsPXXPKqBxC9m2m2HlpYgEBBSMhA182CcWcQ9L2zg9j8jlt7OlaIATNDgNFMBKB1J14wzTprAABASuAOAEAAAAAACIAILYfaBOHA3wuWlefFYJFuQqbR7CMaaWMyVfAuZE+mk6PIgIDXzYJxZxD0vbOD2PyOW3s6VogBM0OA0UwEoHUnXjDNOlIMEUCIQC6XN6tpo9mYlZej4BXSSh5D1K6aILBfQ4WBWXUrISx6wIgVaxFUsz8y59xJ1V4sZ1qarHX9pZ+MJmLKbl2ZSadisoBAQUjIQNfNgnFnEPS9s4PY/I5bezpWiAEzQ4DRTASgdSdeMM06awAAAA=" } } diff --git a/test/psbt.js b/test/psbt.js index 0ccd8ef..99bd9c1 100644 --- a/test/psbt.js +++ b/test/psbt.js @@ -28,7 +28,7 @@ describe(`Psbt`, () => { it(`Invalid: ${f.description}`, () => { assert.throws(() => { Psbt.fromBase64(f.psbt) - }, {message: f.errorMessage}) + }, new RegExp(f.errorMessage)) }) }) @@ -46,7 +46,7 @@ describe(`Psbt`, () => { const psbt = Psbt.fromBase64(f.psbt) assert.throws(() => { psbt.signInput(f.inputToCheck, keyPair) - }, {message: f.errorMessage}) + }, new RegExp(f.errorMessage)) }) }) @@ -181,7 +181,7 @@ describe(`Psbt`, () => { f.shouldThrow.inputToCheck, ECPair.fromWIF(f.shouldThrow.WIF), ) - }, {message: f.shouldThrow.errorMessage}) + }, new RegExp(f.shouldThrow.errorMessage)) assert.rejects(async () => { await psbtThatShouldThrow.signInputAsync( f.shouldThrow.inputToCheck, @@ -208,7 +208,7 @@ describe(`Psbt`, () => { f.shouldThrow.inputToCheck, ECPair.fromWIF(f.shouldThrow.WIF), ) - }, {message: f.shouldThrow.errorMessage}) + }, new RegExp(f.shouldThrow.errorMessage)) assert.throws(() => { psbtThatShouldThrow.signInput( f.shouldThrow.inputToCheck, @@ -276,6 +276,23 @@ describe(`Psbt`, () => { assert.strictEqual(psbt.toBase64(), f.result) }) }) + it('fails if no script found', () => { + const psbt = new Psbt() + psbt.addInput({ + hash: '0000000000000000000000000000000000000000000000000000000000000000', + index: 0 + }) + assert.throws(() => { + psbt.finalizeAllInputs() + }, new RegExp('No script found for input #0')) + psbt.addWitnessUtxoToInput(0, { + script: Buffer.from('0014d85c2b71d0060b09c9886aeb815e50991dda124d', 'hex'), + value: 2e5 + }) + assert.throws(() => { + psbt.finalizeAllInputs() + }, new RegExp('Can not finalize input #0')) + }) }) describe('fromTransaction', () => { @@ -289,9 +306,6 @@ describe(`Psbt`, () => { describe('addInput', () => { fixtures.addInput.checks.forEach(f => { - for (const attr of Object.keys(f.inputData)) { - f.inputData[attr] = f.inputData[attr] - } it(f.description, () => { const psbt = new Psbt() @@ -299,13 +313,14 @@ describe(`Psbt`, () => { assert.throws(() => { psbt.addInput(f.inputData) }, new RegExp(f.exception)) + assert.throws(() => { + psbt.addInputs([f.inputData]) + }, new RegExp(f.exception)) } else { assert.doesNotThrow(() => { - psbt.addInput(f.inputData) + psbt.addInputs([f.inputData]) if (f.equals) { assert.strictEqual(psbt.toBase64(), f.equals) - } else { - console.log(psbt.toBase64()) } }) assert.throws(() => { @@ -318,9 +333,6 @@ describe(`Psbt`, () => { describe('addOutput', () => { fixtures.addOutput.checks.forEach(f => { - for (const attr of Object.keys(f.outputData)) { - f.outputData[attr] = f.outputData[attr] - } it(f.description, () => { const psbt = new Psbt() @@ -328,10 +340,15 @@ describe(`Psbt`, () => { assert.throws(() => { psbt.addOutput(f.outputData) }, new RegExp(f.exception)) + assert.throws(() => { + psbt.addOutputs([f.outputData]) + }, new RegExp(f.exception)) } else { assert.doesNotThrow(() => { psbt.addOutput(f.outputData) - console.log(psbt.toBase64()) + }) + assert.doesNotThrow(() => { + psbt.addOutputs([f.outputData]) }) } }) @@ -381,7 +398,26 @@ describe(`Psbt`, () => { assert.throws(() => { psbt.setSequence(1, 0) - }, {message: 'Input index too high'}) + }, new RegExp('Input index too high')) + }) + }) + + describe('clone', () => { + it('Should clone a psbt exactly with no reference', () => { + const f = fixtures.clone + const psbt = Psbt.fromBase64(f.psbt) + const notAClone = Object.assign(new Psbt(), psbt) // references still active + const clone = psbt.clone() + + assert.strictEqual(psbt.validateAllSignatures(), true) + + assert.strictEqual(clone.toBase64(), psbt.toBase64()) + assert.strictEqual(clone.toBase64(), notAClone.toBase64()) + assert.strictEqual(psbt.toBase64(), notAClone.toBase64()) + psbt.globalMap.unsignedTx[3] = 0xff + assert.notStrictEqual(clone.toBase64(), psbt.toBase64()) + assert.notStrictEqual(clone.toBase64(), notAClone.toBase64()) + assert.strictEqual(psbt.toBase64(), notAClone.toBase64()) }) }) @@ -427,6 +463,8 @@ describe(`Psbt`, () => { psbt.finalizeAllInputs() assert.strictEqual(psbt.getFeeRate(), f.fee) + psbt.__CACHE.__FEE_RATE = undefined + assert.strictEqual(psbt.getFeeRate(), f.fee) }) })