diff --git a/README.md b/README.md index edb0bcc..93d4265 100644 --- a/README.md +++ b/README.md @@ -426,6 +426,238 @@ const state = false; const result = await client.setnetworkactive({ state }); ``` +### Rawtransactions + +- [`analyzepsbt`](https://bitcoin.org/en/developer-reference#analyzepsbt) + +```javascript +const psbt = + "cHNidP8BAJoCAAAAAtVSFGEYzcJX2qwhy8iJGI1Y/zeIqBQtH/OBC9WJ4mx7AQAAAAD9////azacULIhtk9GXF6tde7aC4T3RzVoDa6v6Jtyc/2Pdf8AAAAAAP3///8C2EcDAAAAAAAWABRvcJGDvHZHgYiyMl8u5pLowEPLj6CGAQAAAAAAFgAUtxN9/tGP/jlvvgsWeGCM691FsesBAAAAAAAAAAA="; +const result = await client.analyzepsbt({ psbt }); +``` + +- [`combinepsbt`](https://bitcoin.org/en/developer-reference#combinepsbt) + +```javascript +const txs = [ + "cHNidP8BAHsCAAAAAn+RFbuIDPiBkN5ua0vnUVZwwvbnnDZ8Ca4Z6y3vQyqnAAAAAAD9////KUVYeBVxQc4IZCvsc2WohVhZanD54jy11Gxxn4YRtpYBAAAAAP3///8BYII7AAAAAAAWABSANbyZwTJ0B7qPqpWSolEEKYbIFQEAAAAAAQEfIAMAAAAAAAAWABRCHnul3Lf2vUn4GUU9mrnGLnTHsQEIawJHMEQCIAenBxHwiJAo9Mt/0B0gsflruKfe90W0OUaW/gMqT13hAiBrcsvglEZvxDWKKhMLArU52ndMb6cAangC/u6mowwjGAEhAoNFASSjynZOTTIf6bOnANXURu5zQ9eGpUAcB1x569/qAAAA", + "cHNidP8BAHsCAAAAAn+RFbuIDPiBkN5ua0vnUVZwwvbnnDZ8Ca4Z6y3vQyqnAAAAAAD9////KUVYeBVxQc4IZCvsc2WohVhZanD54jy11Gxxn4YRtpYBAAAAAP3///8BYII7AAAAAAAWABSANbyZwTJ0B7qPqpWSolEEKYbIFQEAAAAAAQEfIAMAAAAAAAAWABRCHnul3Lf2vUn4GUU9mrnGLnTHsQABAR/HgTsAAAAAABYAFDNBVvuJV65T//o2rr6AhKSwDPt9AQhrAkcwRAIgWyFL8FdWh0kB8CbKL2GsVPQU2Wgb9E4YvOwJ9KLseMgCIHBdaP/zuYg7Y4cL5B+gjsOUB4PFss6+dnACpn/+U9UjASEDTi3KTyZW9vKWtxYxflo5B7l1PHSqn0GUlf8AsXkGfvQAAA==" +]; +const result = await client.combinepsbt({ txs }); +``` + +- [`combinerawtransaction`](https://bitcoin.org/en/developer-reference#combinerawtransaction) + +```javascript +const txs = [ + "020000000001029a2b645e97cfde604d0b65aa174fb4747f8b99152f581d12d42055f3388c123e0000000000fdffffff9a2b645e97cfde604d0b65aa174fb4747f8b99152f581d12d42055f3388c123e0100000000fdffffff0180250000000000001600143d366a85a8c07a44b5eed0a622197d6784c07e69000247304402201596d19c0eec785d301dad21ecc8bad1d808d4bd15615df1a5a1b9e930404066022038126c82743ccf5bc225b61a38ddd7ae651f12d27a730817de79279df8fd0ab88121028cc283639d0254c3f3091659d66f7681189de1ade326d36eefa50217956b057b00000000", + "020000000001029a2b645e97cfde604d0b65aa174fb4747f8b99152f581d12d42055f3388c123e0000000000fdffffff9a2b645e97cfde604d0b65aa174fb4747f8b99152f581d12d42055f3388c123e0100000000fdffffff0180250000000000001600143d366a85a8c07a44b5eed0a622197d6784c07e69024730440220451546bae0bc61270eec966f1ca0a5cb16a93c5f88a800094240e61fb3f6fdd7022021a0065ec25e06f9e0b3a4d87b06d13adc2bd620dd8f2ecf7a40366ceaa93e998121039a3d49d8d6a2ca7ff2ea6657d3c8c19ba20ab67f529edb522030928b5f4894d20000000000" +]; +const result = await client.combinerawtransaction({ txs }); +``` + +- [`converttopsbt`](https://bitcoin.org/en/developer-reference#converttopsbt) + +```javascript +const hexstring = + "020000000122647b4fc186385b15a01cc6cd6d7864399b4ff536f370f86ecc5e2f4281d7d50000000000ffffffff017b000000000000001976a914394e47d5a2d723e34b38b05e257c6ab69be3b59988ac00000000"; +const permitsigdata = true; +const iswitness = true; +const result = await client.converttopsbt({ + hexstring, + permitsigdata, + iswitness +}); +``` + +- [`createpsbt`](https://bitcoin.org/en/developer-reference#createpsbt) + +```javascript +const inputs = [ + { + txid: "7b6ce289d50b81f31f2d14a88837ff588d1889c8cb21acda57c2cd18611452d5", + vout: 1 + }, + { + txid: "ff758ffd73729be8afae0d683547f7840bdaee75ad5e5c464fb621b2509c366b", + vout: 0 + } +]; +const outputs = [ + { + tb1qdacfrqauwercrz9jxf0jae5jarqy8ju0ywt8su: 0.00215 + }, + { + tb1qkufhmlk33llrjma7pvt8scyva0w5tv0tvuy6zs: 0.001 + } +]; +const locktime = 1; +const replaceable = true; +const result = await client.createpsbt({ + inputs, + outputs, + locktime, + replaceable +}); +``` + +- [`createrawtransaction`](https://bitcoin.org/en/developer-reference#createrawtransaction) + +```javascript +const inputs = [ + { + txid: "7b6ce289d50b81f31f2d14a88837ff588d1889c8cb21acda57c2cd18611452d5", + vout: 1 + }, + { + txid: "ff758ffd73729be8afae0d683547f7840bdaee75ad5e5c464fb621b2509c366b", + vout: 0 + } +]; +const outputs = [ + { + tb1qdacfrqauwercrz9jxf0jae5jarqy8ju0ywt8su: 0.00215 + }, + { + tb1qkufhmlk33llrjma7pvt8scyva0w5tv0tvuy6zs: 0.001 + } +]; +const locktime = 1; +const replaceable = true; +const result = await client.createrawtransaction({ + inputs, + outputs, + locktime, + replaceable +}); +``` + +- [`decodepsbt`](https://bitcoin.org/en/developer-reference#decodepsbt) + +```javascript +const psbt = + "cHNidP8BAJoCAAAAAtVSFGEYzcJX2qwhy8iJGI1Y/zeIqBQtH/OBC9WJ4mx7AQAAAAD9////azacULIhtk9GXF6tde7aC4T3RzVoDa6v6Jtyc/2Pdf8AAAAAAP3///8C2EcDAAAAAAAWABRvcJGDvHZHgYiyMl8u5pLowEPLj6CGAQAAAAAAFgAUtxN9/tGP/jlvvgsWeGCM691FsesBAAAAAAAAAAA="; +const result = await client.decodepsbt({ psbt }); +``` + +- [`decoderawtransaction`](https://bitcoin.org/en/developer-reference#decoderawtransaction) + +```javascript +const hexstring = + "0200000002d552146118cdc257daac21cbc889188d58ff3788a8142d1ff3810bd589e26c7b0100000000fdffffff6b369c50b221b64f465c5ead75eeda0b84f74735680daeafe89b7273fd8f75ff0000000000fdffffff02d8470300000000001600146f709183bc76478188b2325f2ee692e8c043cb8fa086010000000000160014b7137dfed18ffe396fbe0b1678608cebdd45b1eb01000000"; +const iswitness = true; +const result = await client.decoderawtransaction({ hexstring, iswitness }); +``` + +- [`decodescript`](https://bitcoin.org/en/developer-reference#decodescript) + +```javascript +const hexstring = + "5221031e925dbe43ca87bce874f4fb77ac0d6bb2dc1a9db93868fa27611b687775bd0b2102ffb8b66ba266797f1e33e5d177a6f9c72839992ccf11e97837054a8d3a8284bc21025bf696347321a5276aad08dfefff19dd09d3717bfc2ce521060f4247d31c37b553ae"; +const result = await client.decodescript({ hexstring }); +``` + +- [`finalizepsbt`](https://bitcoin.org/en/developer-reference#finalizepsbt) + +```javascript +const psbt = + "cHNidP8BAHsCAAAAAn+RFbuIDPiBkN5ua0vnUVZwwvbnnDZ8Ca4Z6y3vQyqnAAAAAAD9////KUVYeBVxQc4IZCvsc2WohVhZanD54jy11Gxxn4YRtpYBAAAAAP3///8BYII7AAAAAAAWABSANbyZwTJ0B7qPqpWSolEEKYbIFQEAAAAAAQEfIAMAAAAAAAAWABRCHnul3Lf2vUn4GUU9mrnGLnTHsQEIawJHMEQCIAenBxHwiJAo9Mt/0B0gsflruKfe90W0OUaW/gMqT13hAiBrcsvglEZvxDWKKhMLArU52ndMb6cAangC/u6mowwjGAEhAoNFASSjynZOTTIf6bOnANXURu5zQ9eGpUAcB1x569/qAAEBH8eBOwAAAAAAFgAUM0FW+4lXrlP/+jauvoCEpLAM+30BCGsCRzBEAiBbIUvwV1aHSQHwJsovYaxU9BTZaBv0Thi87An0oux4yAIgcF1o//O5iDtjhwvkH6COw5QHg8Wyzr52cAKmf/5T1SMBIQNOLcpPJlb28pa3FjF+WjkHuXU8dKqfQZSV/wCxeQZ+9AAA"; +const extract = true; +const result = await client.finalizepsbt({ psbt, extract }); +``` + +- [`fundrawtransaction`](https://bitcoin.org/en/developer-reference#fundrawtransaction) + +```javascript +const hexstring = + "020000000129455878157141ce08642bec7365a88558596a70f9e23cb5d46c719f8611b6960000000000fdffffff0140420f00000000001600148470e04e616ab6552d72e8284a32a293ff8a959b00000000"; +const includeWatching = true; +const feeRate = 0.0002; +const replaceable = true; +const changeAddress = "tb1q80h3kvp98fgkz293we3p75hs0aq4cecz3qtgkg"; +const wallet = "bitcoin-core-wallet.dat"; +const options = { includeWatching, feeRate, replaceable, changeAddress }; +const iswitness = true; +const result = await client.fundrawtransaction( + { + hexstring, + options, + iswitness + }, + wallet +); +``` + +- [`getrawtransaction`](https://bitcoin.org/en/developer-reference#getrawtransaction) + +```javascript +const txid = "a32ddaed3387a2bc0bb9a4f90bc6e84e5589335b97142848ad144efd38420eb2"; +const verbose = true; +const blockhash = + "00000000480351c0fc7047af37756bbae30996a018e94d9ca8156dccea032018"; +const result = await client.getrawtransaction({ txid, verbose, blockhash }); +``` + +- [`joinpsbts`](https://bitcoin.org/en/developer-reference#joinpsbts) + +```javascript +const txs = [ + "cHNidP8BAFICAAAAAdVSFGEYzcJX2qwhy8iJGI1Y/zeIqBQtH/OBC9WJ4mx7AQAAAAD9////AdhHAwAAAAAAFgAUb3CRg7x2R4GIsjJfLuaS6MBDy48BAAAAAAAA", + "cHNidP8BAFICAAAAAWs2nFCyIbZPRlxerXXu2guE90c1aA2ur+ibcnP9j3X/AAAAAAD9////AaCGAQAAAAAAFgAUtxN9/tGP/jlvvgsWeGCM691FsesBAAAAAAAA" +]; +const result = await client.joinpsbts({ txs }); +``` + +- [`sendrawtransaction`](https://bitcoin.org/en/developer-reference#sendrawtransaction) + +```javascript +const hexstring = + "020000000001027f9115bb880cf88190de6e6b4be7515670c2f6e79c367c09ae19eb2def432aa70000000000fdffffff29455878157141ce08642bec7365a88558596a70f9e23cb5d46c719f8611b6960100000000fdffffff0160823b00000000001600148035bc99c1327407ba8faa9592a251042986c81502473044022007a70711f0889028f4cb7fd01d20b1f96bb8a7def745b4394696fe032a4f5de102206b72cbe094466fc4358a2a130b02b539da774c6fa7006a7802feeea6a30c231801210283450124a3ca764e4d321fe9b3a700d5d446ee7343d786a5401c075c79ebdfea0247304402205b214bf05756874901f026ca2f61ac54f414d9681bf44e18bcec09f4a2ec78c80220705d68fff3b9883b63870be41fa08ec3940783c5b2cebe767002a67ffe53d5230121034e2dca4f2656f6f296b716317e5a3907b9753c74aa9f419495ff00b179067ef401000000"; +const allowhighfees = true; +const result = await client.sendrawtransaction({ hexstring, allowhighfees }); +``` + +- [`signrawtransactionwithkey`](https://bitcoin.org/en/developer-reference#signrawtransactionwithkey) + +```javascript +const hexstring = + "0200000002d552146118cdc257daac21cbc889188d58ff3788a8142d1ff3810bd589e26c7b0000000000fdffffff6dd6a088fda2de4c1f25912f5c6f53fdafd54abf6557d888af5ceac704a26d050100000000fdffffff0200093d0000000000160014fc8e119e52776678cc05cab6b024eb77cea2f11620cc0400000000001600141ca68ece7a876e66d377c0a1bc5d45251513c20800000000"; +const privkeys = ["privkey1", "privkey2"]; +const prevtxs = [ + { + txid: "cc21b8cb612f7b451e4283f08b3fa96ccdc141441697c499366f42514b3bdd15", + vout: 0, + scriptPubKey: "00141ca68ece7a876e66d377c0a1bc5d45251513c208", + amount: 0.001 + } +]; +const sighashtype = "ALL|ANYONECANPAY"; +const result = await client.signrawtransactionwithkey({ + hexstring, + privkeys, + prevtxs, + sighashtype +}); +``` + +- [`testmempoolaccept`](https://bitcoin.org/en/developer-reference#testmempoolaccept) + +```javascript +const rawtxs = [ + "020000000001027f9115bb880cf88190de6e6b4be7515670c2f6e79c367c09ae19eb2def432aa70000000000fdffffff29455878157141ce08642bec7365a88558596a70f9e23cb5d46c719f8611b6960100000000fdffffff0160823b00000000001600148035bc99c1327407ba8faa9592a251042986c81502473044022007a70711f0889028f4cb7fd01d20b1f96bb8a7def745b4394696fe032a4f5de102206b72cbe094466fc4358a2a130b02b539da774c6fa7006a7802feeea6a30c231801210283450124a3ca764e4d321fe9b3a700d5d446ee7343d786a5401c075c79ebdfea0247304402205b214bf05756874901f026ca2f61ac54f414d9681bf44e18bcec09f4a2ec78c80220705d68fff3b9883b63870be41fa08ec3940783c5b2cebe767002a67ffe53d5230121034e2dca4f2656f6f296b716317e5a3907b9753c74aa9f419495ff00b179067ef401000000" +]; +const allowhighfees = true; +const result = await client.testmempoolaccept({ rawtxs, allowhighfees }); +``` + +- [`utxoupdatepsbt`](https://bitcoin.org/en/developer-reference#utxoupdatepsbt) + +```javascript +const psbt = + "cHNidP8BAHsCAAAAAn+RFbuIDPiBkN5ua0vnUVZwwvbnnDZ8Ca4Z6y3vQyqnAAAAAAD9////KUVYeBVxQc4IZCvsc2WohVhZanD54jy11Gxxn4YRtpYBAAAAAP3///8BYII7AAAAAAAWABSANbyZwTJ0B7qPqpWSolEEKYbIFQEAAAAAAQEfIAMAAAAAAAAWABRCHnul3Lf2vUn4GUU9mrnGLnTHsQEIawJHMEQCIAenBxHwiJAo9Mt/0B0gsflruKfe90W0OUaW/gMqT13hAiBrcsvglEZvxDWKKhMLArU52ndMb6cAangC/u6mowwjGAEhAoNFASSjynZOTTIf6bOnANXURu5zQ9eGpUAcB1x569/qAAAA"; +const result = await client.utxoupdatepsbt({ psbt }); +``` + ### Util - [`createmultisig`](https://bitcoin.org/en/developer-reference#createmultisig) diff --git a/package-lock.json b/package-lock.json index 88b0fc1..a15fd15 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "rpc-bitcoin", - "version": "1.8.0", + "version": "1.9.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -181,10 +181,13 @@ "dev": true }, "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.2.1.tgz", + "integrity": "sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q==", + "dev": true, + "requires": { + "type-fest": "^0.5.2" + } }, "ansi-regex": { "version": "3.0.0", @@ -347,12 +350,12 @@ "dev": true }, "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, "requires": { - "restore-cursor": "^2.0.0" + "restore-cursor": "^3.1.0" } }, "cli-width": { @@ -558,9 +561,9 @@ "dev": true }, "eslint": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.5.1.tgz", - "integrity": "sha512-32h99BoLYStT1iq1v2P9uwpyznQ4M2jRiFB6acitKz52Gqn+vPaMDUTB1bYi1WN4Nquj2w+t+bimYUG83DC55A==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.6.0.tgz", + "integrity": "sha512-PpEBq7b6qY/qrOmpYQ/jTMDYfuQMELR4g4WI1M/NaSDDD/bdcMb+dj4Hgks7p41kW2caXsPsEZAEAyAgjVVC0g==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -570,9 +573,9 @@ "debug": "^4.0.1", "doctrine": "^3.0.0", "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.2", + "eslint-utils": "^1.4.3", "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.1", + "espree": "^6.1.2", "esquery": "^1.0.1", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", @@ -582,7 +585,7 @@ "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^6.4.1", + "inquirer": "^7.0.0", "is-glob": "^4.0.0", "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", @@ -712,9 +715,9 @@ "dev": true }, "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", + "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" @@ -951,24 +954,49 @@ "dev": true }, "inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.0.tgz", + "integrity": "sha512-rSdC7zelHdRQFkWnhsMu2+2SO41mpv2oF2zy4tMhmiLWkcKbOAs87fWAJhVXttKVwhdZvymvnuM95EyEXg2/tQ==", "dev": true, "requires": { - "ansi-escapes": "^3.2.0", + "ansi-escapes": "^4.2.1", "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", + "cli-cursor": "^3.1.0", "cli-width": "^2.0.0", "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", "run-async": "^2.2.0", "rxjs": "^6.4.0", - "string-width": "^2.1.0", + "string-width": "^4.1.0", "strip-ansi": "^5.1.0", "through": "^2.3.6" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.1.0.tgz", + "integrity": "sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^5.2.0" + } + } } }, "is-buffer": { @@ -1163,9 +1191,9 @@ } }, "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, "minimatch": { @@ -1282,9 +1310,9 @@ "dev": true }, "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, "natural-compare": { @@ -1380,12 +1408,12 @@ } }, "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", "dev": true, "requires": { - "mimic-fn": "^1.0.0" + "mimic-fn": "^2.1.0" } }, "optionator": { @@ -1591,12 +1619,12 @@ "dev": true }, "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, "requires": { - "onetime": "^2.0.0", + "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, @@ -1925,6 +1953,12 @@ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, + "type-fest": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz", + "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==", + "dev": true + }, "typescript": { "version": "3.6.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz", diff --git a/package.json b/package.json index 1a1cbdd..340d1c9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rpc-bitcoin", - "version": "1.8.0", + "version": "1.9.0", "description": "A TypeScript library to make RPC and HTTP REST requests to Bitcoin Core", "main": "build/index.js", "type": "module", @@ -35,7 +35,7 @@ "@types/mocha": "^5.2.7", "@typescript-eslint/eslint-plugin": "^2.5.0", "@typescript-eslint/parser": "^2.5.0", - "eslint": "^6.5.1", + "eslint": "^6.6.0", "mocha": "^6.2.2", "nock": "^11.6.0", "prettier": "^1.18.2", diff --git a/src/rpc.ts b/src/rpc.ts index 00dbf82..594dfba 100644 --- a/src/rpc.ts +++ b/src/rpc.ts @@ -134,6 +134,80 @@ export type VerifyMessageParams = { message: string; }; +export type HexString = { hexstring: string }; + +export type ConvertToPsbtParams = HexString & { + permitsigdata?: boolean; + iswitness?: boolean; +}; + +export type TransactionInput = { + txid: string; + vout: number; + sequence?: number; +}; + +export type TransactionOutput = + | { [address: string]: string | number } + | { data: string }; + +export type CreateTransactionParams = { + inputs: TransactionInput[]; + outputs: TransactionOutput[]; + locktime?: number; + replaceable?: boolean; +}; + +export type DecodeRawTransactionParams = HexString & { iswitness?: boolean }; + +export type FinalizePsbtParams = { psbt: string; extract?: boolean }; + +export type FundRawTransactionParams = HexString & { + options?: { + changeAddress?: string; + changePosition?: number; + change_type?: string; + includeWatching?: boolean; + lockUnspents?: boolean; + feeRate?: number | string; + subtractFeeFromOutputs?: number[]; + replaceable?: boolean; + conf_target?: number; + estimate_mode?: "UNSET" | "ECONOMICAL" | "CONSERVATIVE"; + }; + iswitness?: boolean; +}; + +export type GetRawTransactionParams = TxId & Verbose & { blockhash?: string }; + +export type SendRawTransactionParams = HexString & { allowhighfees?: boolean }; + +export type PrevTx = { + txid: string; + vout: number; + scriptPubKey: string; + redeemScript?: string; + witnessScript?: string; + amount: number | string; +}; + +export type SignRawTransactionWithKeyParams = HexString & { + privkeys: string[]; + prevtxs?: PrevTx[]; + sighashtype?: + | "ALL" + | "NONE" + | "SINGLE" + | "ALL|ANYONECANPAY" + | "NONE|ANYONECANPAY" + | "SINGLE|ANYONECANPAY"; +}; + +export type TestmemPoolAcceptParams = { + rawtxs: string[]; + allowhighfees?: boolean; +}; + export class RPCClient extends RESTClient { wallet?: string; fullResponse?: boolean; @@ -541,6 +615,187 @@ export class RPCClient extends RESTClient { return this.rpc("setnetworkactive", { state }); } + /** + * @description Analyzes and provides information about the current status of a PSBT and its inputs + */ + async analyzepsbt({ psbt }: { psbt: string }) { + return this.rpc("analyzepsbt", { psbt }); + } + + /** + * @description Combine multiple partially signed Bitcoin transactions into one transaction. + */ + async combinepsbt({ txs }: { txs: string[] }) { + return this.rpc("combinepsbt", { txs }); + } + + /** + * @description Combine multiple partially signed transactions into one transaction. + */ + async combinerawtransaction({ txs }: { txs: string[] }) { + return this.rpc("combinerawtransaction", { txs }); + } + + /** + * @description Converts a network serialized transaction to a PSBT. + */ + async converttopsbt({ + hexstring, + permitsigdata = false, + iswitness + }: ConvertToPsbtParams) { + return this.rpc("converttopsbt", { + hexstring, + permitsigdata, + iswitness + }); + } + + /** + * @description Creates a transaction in the Partially Signed Transaction format. + */ + async createpsbt({ + inputs, + outputs, + locktime = 0, + replaceable = false + }: CreateTransactionParams) { + return this.rpc("createpsbt", { + inputs, + outputs, + locktime, + replaceable + }); + } + + /** + * @description Create a transaction spending the given inputs and creating new outputs. + */ + async createrawtransaction({ + inputs, + outputs, + locktime = 0, + replaceable = false + }: CreateTransactionParams) { + return this.rpc("createrawtransaction", { + inputs, + outputs, + locktime, + replaceable + }); + } + + /** + * @description Return a JSON object representing the serialized, base64-encoded partially signed Bitcoin transaction. + */ + async decodepsbt({ psbt }: { psbt: string }) { + return this.rpc("decodepsbt", { psbt }); + } + + /** + * @description Return a JSON object representing the serialized, hex-encoded transaction. + */ + async decoderawtransaction({ + hexstring, + iswitness + }: DecodeRawTransactionParams) { + return this.rpc("decoderawtransaction", { hexstring, iswitness }); + } + + /** + * @description Decode a hex-encoded script. + */ + async decodescript({ hexstring }: HexString) { + return this.rpc("decodescript", { hexstring }); + } + + /** + * @description Finalize the inputs of a PSBT. + */ + async finalizepsbt({ psbt, extract = false }: FinalizePsbtParams) { + return this.rpc("finalizepsbt", { psbt, extract }); + } + + /** + * @description Add inputs to a transaction until it has enough in value to meet its out value. + */ + async fundrawtransaction( + { hexstring, options, iswitness }: FundRawTransactionParams, + wallet?: string + ) { + return this.rpc( + "fundrawtransaction", + { + hexstring, + options, + iswitness + }, + wallet || this.wallet + ); + } + + /** + * @description Return the raw transaction data. + */ + async getrawtransaction({ + txid, + verbose = false, + blockhash + }: GetRawTransactionParams) { + return this.rpc("getrawtransaction", { txid, verbose, blockhash }); + } + + /** + * @description Joins multiple distinct PSBTs with different inputs and outputs into one PSBT with inputs and outputs from all of the PSBTs. + */ + async joinpsbts({ txs }: { txs: string[] }) { + return this.rpc("joinpsbts", { txs }); + } + + /** + * @description Submits raw transaction (serialized, hex-encoded) to local node and network. + */ + async sendrawtransaction({ + hexstring, + allowhighfees = false + }: SendRawTransactionParams) { + return this.rpc("sendrawtransaction", { hexstring, allowhighfees }); + } + + /** + * @description Sign inputs for raw transaction + */ + async signrawtransactionwithkey({ + hexstring, + privkeys, + prevtxs, + sighashtype = "ALL" + }: SignRawTransactionWithKeyParams) { + return this.rpc("signrawtransactionwithkey", { + hexstring, + privkeys, + prevtxs, + sighashtype + }); + } + + /** + * @description Returns result of mempool acceptance tests indicating if raw transaction (serialized, hex-encoded) would be accepted by mempool. + */ + async testmempoolaccept({ + rawtxs, + allowhighfees = false + }: TestmemPoolAcceptParams) { + return this.rpc("testmempoolaccept", { rawtxs, allowhighfees }); + } + + /** + * @description Updates a PSBT with witness UTXOs retrieved from the UTXO set or the mempool. + */ + async utxoupdatepsbt({ psbt }: { psbt: string }) { + return this.rpc("utxoupdatepsbt", { psbt }); + } + /** * @description Creates a multi-signature address with n signature of m keys required. */ diff --git a/test/rpc.spec.ts b/test/rpc.spec.ts index c3dba6a..a3bc20c 100644 --- a/test/rpc.spec.ts +++ b/test/rpc.spec.ts @@ -1582,6 +1582,539 @@ suite("RPCClient", () => { }); }); + suite("Rawtransactions", () => { + test(".analyzepsbt()", async () => { + const psbt = + "cHNidP8BAJoCAAAAAtVSFGEYzcJX2qwhy8iJGI1Y/zeIqBQtH/OBC9WJ4mx7AQAAAAD9////azacULIhtk9GXF6tde7aC4T3RzVoDa6v6Jtyc/2Pdf8AAAAAAP3///8C2EcDAAAAAAAWABRvcJGDvHZHgYiyMl8u5pLowEPLj6CGAQAAAAAAFgAUtxN9/tGP/jlvvgsWeGCM691FsesBAAAAAAAAAAA="; + const params = { psbt }; + const request = { params, method: "analyzepsbt", id, jsonrpc }; + const result = { + inputs: [ + { has_utxo: false, is_final: false, next: "updater" }, + { has_utxo: false, is_final: false, next: "updater" } + ], + next: "updater" + }; + nock(uri) + .post("/", request) + .times(1) + .basicAuth(auth) + .reply(200, { result, error, id }); + const data = await client.analyzepsbt(params); + assert.deepStrictEqual(data, result); + }); + + test(".combinepsbt()", async () => { + const txs = [ + "cHNidP8BAHsCAAAAAn+RFbuIDPiBkN5ua0vnUVZwwvbnnDZ8Ca4Z6y3vQyqnAAAAAAD9////KUVYeBVxQc4IZCvsc2WohVhZanD54jy11Gxxn4YRtpYBAAAAAP3///8BYII7AAAAAAAWABSANbyZwTJ0B7qPqpWSolEEKYbIFQEAAAAAAQEfIAMAAAAAAAAWABRCHnul3Lf2vUn4GUU9mrnGLnTHsQEIawJHMEQCIAenBxHwiJAo9Mt/0B0gsflruKfe90W0OUaW/gMqT13hAiBrcsvglEZvxDWKKhMLArU52ndMb6cAangC/u6mowwjGAEhAoNFASSjynZOTTIf6bOnANXURu5zQ9eGpUAcB1x569/qAAAA", + "cHNidP8BAHsCAAAAAn+RFbuIDPiBkN5ua0vnUVZwwvbnnDZ8Ca4Z6y3vQyqnAAAAAAD9////KUVYeBVxQc4IZCvsc2WohVhZanD54jy11Gxxn4YRtpYBAAAAAP3///8BYII7AAAAAAAWABSANbyZwTJ0B7qPqpWSolEEKYbIFQEAAAAAAQEfIAMAAAAAAAAWABRCHnul3Lf2vUn4GUU9mrnGLnTHsQABAR/HgTsAAAAAABYAFDNBVvuJV65T//o2rr6AhKSwDPt9AQhrAkcwRAIgWyFL8FdWh0kB8CbKL2GsVPQU2Wgb9E4YvOwJ9KLseMgCIHBdaP/zuYg7Y4cL5B+gjsOUB4PFss6+dnACpn/+U9UjASEDTi3KTyZW9vKWtxYxflo5B7l1PHSqn0GUlf8AsXkGfvQAAA==" + ]; + const params = { txs }; + const request = { params, method: "combinepsbt", id, jsonrpc }; + const result = + "cHNidP8BAHsCAAAAAn+RFbuIDPiBkN5ua0vnUVZwwvbnnDZ8Ca4Z6y3vQyqnAAAAAAD9////KUVYeBVxQc4IZCvsc2WohVhZanD54jy11Gxxn4YRtpYBAAAAAP3///8BYII7AAAAAAAWABSANbyZwTJ0B7qPqpWSolEEKYbIFQEAAAAAAQEfIAMAAAAAAAAWABRCHnul3Lf2vUn4GUU9mrnGLnTHsQEIawJHMEQCIAenBxHwiJAo9Mt/0B0gsflruKfe90W0OUaW/gMqT13hAiBrcsvglEZvxDWKKhMLArU52ndMb6cAangC/u6mowwjGAEhAoNFASSjynZOTTIf6bOnANXURu5zQ9eGpUAcB1x569/qAAEBH8eBOwAAAAAAFgAUM0FW+4lXrlP/+jauvoCEpLAM+30BCGsCRzBEAiBbIUvwV1aHSQHwJsovYaxU9BTZaBv0Thi87An0oux4yAIgcF1o//O5iDtjhwvkH6COw5QHg8Wyzr52cAKmf/5T1SMBIQNOLcpPJlb28pa3FjF+WjkHuXU8dKqfQZSV/wCxeQZ+9AAA"; + nock(uri) + .post("/", request) + .times(1) + .basicAuth(auth) + .reply(200, { result, error, id }); + const data = await client.combinepsbt(params); + assert.deepStrictEqual(data, result); + }); + + test(".combinerawtransaction()", async () => { + const txs = [ + "020000000001029a2b645e97cfde604d0b65aa174fb4747f8b99152f581d12d42055f3388c123e0000000000fdffffff9a2b645e97cfde604d0b65aa174fb4747f8b99152f581d12d42055f3388c123e0100000000fdffffff0180250000000000001600143d366a85a8c07a44b5eed0a622197d6784c07e69000247304402201596d19c0eec785d301dad21ecc8bad1d808d4bd15615df1a5a1b9e930404066022038126c82743ccf5bc225b61a38ddd7ae651f12d27a730817de79279df8fd0ab88121028cc283639d0254c3f3091659d66f7681189de1ade326d36eefa50217956b057b00000000", + "020000000001029a2b645e97cfde604d0b65aa174fb4747f8b99152f581d12d42055f3388c123e0000000000fdffffff9a2b645e97cfde604d0b65aa174fb4747f8b99152f581d12d42055f3388c123e0100000000fdffffff0180250000000000001600143d366a85a8c07a44b5eed0a622197d6784c07e69024730440220451546bae0bc61270eec966f1ca0a5cb16a93c5f88a800094240e61fb3f6fdd7022021a0065ec25e06f9e0b3a4d87b06d13adc2bd620dd8f2ecf7a40366ceaa93e998121039a3d49d8d6a2ca7ff2ea6657d3c8c19ba20ab67f529edb522030928b5f4894d20000000000" + ]; + const params = { txs }; + const request = { params, method: "combinerawtransaction", id, jsonrpc }; + const result = + "020000000001029a2b645e97cfde604d0b65aa174fb4747f8b99152f581d12d42055f3388c123e0000000000fdffffff9a2b645e97cfde604d0b65aa174fb4747f8b99152f581d12d42055f3388c123e0100000000fdffffff0180250000000000001600143d366a85a8c07a44b5eed0a622197d6784c07e69024730440220451546bae0bc61270eec966f1ca0a5cb16a93c5f88a800094240e61fb3f6fdd7022021a0065ec25e06f9e0b3a4d87b06d13adc2bd620dd8f2ecf7a40366ceaa93e998121039a3d49d8d6a2ca7ff2ea6657d3c8c19ba20ab67f529edb522030928b5f4894d20247304402201596d19c0eec785d301dad21ecc8bad1d808d4bd15615df1a5a1b9e930404066022038126c82743ccf5bc225b61a38ddd7ae651f12d27a730817de79279df8fd0ab88121028cc283639d0254c3f3091659d66f7681189de1ade326d36eefa50217956b057b00000000"; + nock(uri) + .post("/", request) + .times(1) + .basicAuth(auth) + .reply(200, { result, error, id }); + const data = await client.combinerawtransaction(params); + assert.deepStrictEqual(data, result); + }); + + test(".converttopsbt()", async () => { + const hexstring = + "0200000002d552146118cdc257daac21cbc889188d58ff3788a8142d1ff3810bd589e26c7b0100000000fdffffff6b369c50b221b64f465c5ead75eeda0b84f74735680daeafe89b7273fd8f75ff0000000000fdffffff02d8470300000000001600146f709183bc76478188b2325f2ee692e8c043cb8fa086010000000000160014b7137dfed18ffe396fbe0b1678608cebdd45b1eb01000000"; + const permitsigdata = true; + const iswitness = true; + const params = { hexstring, permitsigdata, iswitness }; + const request = { params, method: "converttopsbt", id, jsonrpc }; + const result = + "cHNidP8BAJoCAAAAAtVSFGEYzcJX2qwhy8iJGI1Y/zeIqBQtH/OBC9WJ4mx7AQAAAAD9////azacULIhtk9GXF6tde7aC4T3RzVoDa6v6Jtyc/2Pdf8AAAAAAP3///8C2EcDAAAAAAAWABRvcJGDvHZHgYiyMl8u5pLowEPLj6CGAQAAAAAAFgAUtxN9/tGP/jlvvgsWeGCM691FsesBAAAAAAAAAAA="; + nock(uri) + .post("/", request) + .times(1) + .basicAuth(auth) + .reply(200, { result, error, id }); + const data = await client.converttopsbt(params); + assert.deepStrictEqual(data, result); + }); + + test(".createpsbt()", async () => { + const inputs = [ + { + txid: + "7b6ce289d50b81f31f2d14a88837ff588d1889c8cb21acda57c2cd18611452d5", + vout: 1 + }, + { + txid: + "ff758ffd73729be8afae0d683547f7840bdaee75ad5e5c464fb621b2509c366b", + vout: 0 + } + ]; + const out1: { [address: string]: number } = { + tb1qdacfrqauwercrz9jxf0jae5jarqy8ju0ywt8su: 0.00215 + }; + const out2: { [address: string]: number } = { + tb1qkufhmlk33llrjma7pvt8scyva0w5tv0tvuy6zs: 0.001 + }; + const outputs = [out1, out2]; + const locktime = 1; + const replaceable = true; + const params = { inputs, outputs, locktime, replaceable }; + const request = { params, method: "createpsbt", id, jsonrpc }; + const result = + "cHNidP8BAJoCAAAAAtVSFGEYzcJX2qwhy8iJGI1Y/zeIqBQtH/OBC9WJ4mx7AQAAAAD9////azacULIhtk9GXF6tde7aC4T3RzVoDa6v6Jtyc/2Pdf8AAAAAAP3///8C2EcDAAAAAAAWABRvcJGDvHZHgYiyMl8u5pLowEPLj6CGAQAAAAAAFgAUtxN9/tGP/jlvvgsWeGCM691FsesBAAAAAAAAAAA="; + nock(uri) + .post("/", request) + .times(1) + .basicAuth(auth) + .reply(200, { result, error, id }); + const data = await client.createpsbt(params); + assert.deepStrictEqual(data, result); + }); + + test(".createrawtransaction()", async () => { + const inputs = [ + { + txid: + "7b6ce289d50b81f31f2d14a88837ff588d1889c8cb21acda57c2cd18611452d5", + vout: 1 + }, + { + txid: + "ff758ffd73729be8afae0d683547f7840bdaee75ad5e5c464fb621b2509c366b", + vout: 0 + } + ]; + const out1: { [address: string]: number } = { + tb1qdacfrqauwercrz9jxf0jae5jarqy8ju0ywt8su: 0.00215 + }; + const out2: { [address: string]: number } = { + tb1qkufhmlk33llrjma7pvt8scyva0w5tv0tvuy6zs: 0.001 + }; + const outputs = [out1, out2]; + const locktime = 1; + const replaceable = true; + const params = { inputs, outputs, locktime, replaceable }; + const request = { params, method: "createrawtransaction", id, jsonrpc }; + const result = + "0200000002d552146118cdc257daac21cbc889188d58ff3788a8142d1ff3810bd589e26c7b0100000000fdffffff6b369c50b221b64f465c5ead75eeda0b84f74735680daeafe89b7273fd8f75ff0000000000fdffffff02d8470300000000001600146f709183bc76478188b2325f2ee692e8c043cb8fa086010000000000160014b7137dfed18ffe396fbe0b1678608cebdd45b1eb01000000"; + nock(uri) + .post("/", request) + .times(1) + .basicAuth(auth) + .reply(200, { result, error, id }); + const data = await client.createrawtransaction(params); + assert.deepStrictEqual(data, result); + }); + + test(".decodepsbt()", async () => { + const psbt = + "cHNidP8BAJoCAAAAAtVSFGEYzcJX2qwhy8iJGI1Y/zeIqBQtH/OBC9WJ4mx7AQAAAAD9////azacULIhtk9GXF6tde7aC4T3RzVoDa6v6Jtyc/2Pdf8AAAAAAP3///8C2EcDAAAAAAAWABRvcJGDvHZHgYiyMl8u5pLowEPLj6CGAQAAAAAAFgAUtxN9/tGP/jlvvgsWeGCM691FsesBAAAAAAAAAAA="; + const params = { psbt }; + const request = { params, method: "decodepsbt", id, jsonrpc }; + const result = { + tx: { + txid: + "22ff139b2aaa971e3d8ed94dc8a70d82097b59ddc8f35d0e744461e96a4e9f1d", + hash: + "22ff139b2aaa971e3d8ed94dc8a70d82097b59ddc8f35d0e744461e96a4e9f1d", + version: 2, + size: 154, + vsize: 154, + weight: 616, + locktime: 1, + vin: [ + { + txid: + "7b6ce289d50b81f31f2d14a88837ff588d1889c8cb21acda57c2cd18611452d5", + vout: 1, + scriptSig: { asm: "", hex: "" }, + sequence: 4294967293 + }, + { + txid: + "ff758ffd73729be8afae0d683547f7840bdaee75ad5e5c464fb621b2509c366b", + vout: 0, + scriptSig: { asm: "", hex: "" }, + sequence: 4294967293 + } + ], + vout: [ + { + value: 0.00215, + n: 0, + scriptPubKey: { + asm: "0 6f709183bc76478188b2325f2ee692e8c043cb8f", + hex: "00146f709183bc76478188b2325f2ee692e8c043cb8f", + reqSigs: 1, + type: "witness_v0_keyhash", + addresses: ["tb1qdacfrqauwercrz9jxf0jae5jarqy8ju0ywt8su"] + } + }, + { + value: 0.001, + n: 1, + scriptPubKey: { + asm: "0 b7137dfed18ffe396fbe0b1678608cebdd45b1eb", + hex: "0014b7137dfed18ffe396fbe0b1678608cebdd45b1eb", + reqSigs: 1, + type: "witness_v0_keyhash", + addresses: ["tb1qkufhmlk33llrjma7pvt8scyva0w5tv0tvuy6zs"] + } + } + ] + }, + unknown: {}, + inputs: [{}, {}], + outputs: [{}, {}] + }; + nock(uri) + .post("/", request) + .times(1) + .basicAuth(auth) + .reply(200, { result, error, id }); + const data = await client.decodepsbt(params); + assert.deepStrictEqual(data, result); + }); + + test(".decoderawtransaction()", async () => { + const hexstring = + "0200000002d552146118cdc257daac21cbc889188d58ff3788a8142d1ff3810bd589e26c7b0100000000fdffffff6b369c50b221b64f465c5ead75eeda0b84f74735680daeafe89b7273fd8f75ff0000000000fdffffff02d8470300000000001600146f709183bc76478188b2325f2ee692e8c043cb8fa086010000000000160014b7137dfed18ffe396fbe0b1678608cebdd45b1eb01000000"; + const iswitness = true; + const params = { hexstring, iswitness }; + const request = { params, method: "decoderawtransaction", id, jsonrpc }; + const result = { + txid: + "22ff139b2aaa971e3d8ed94dc8a70d82097b59ddc8f35d0e744461e96a4e9f1d", + hash: + "22ff139b2aaa971e3d8ed94dc8a70d82097b59ddc8f35d0e744461e96a4e9f1d", + version: 2, + size: 154, + vsize: 154, + weight: 616, + locktime: 1, + vin: [ + { + txid: + "7b6ce289d50b81f31f2d14a88837ff588d1889c8cb21acda57c2cd18611452d5", + vout: 1, + scriptSig: { asm: "", hex: "" }, + sequence: 4294967293 + }, + { + txid: + "ff758ffd73729be8afae0d683547f7840bdaee75ad5e5c464fb621b2509c366b", + vout: 0, + scriptSig: { asm: "", hex: "" }, + sequence: 4294967293 + } + ], + vout: [ + { + value: 0.00215, + n: 0, + scriptPubKey: { + asm: "0 6f709183bc76478188b2325f2ee692e8c043cb8f", + hex: "00146f709183bc76478188b2325f2ee692e8c043cb8f", + reqSigs: 1, + type: "witness_v0_keyhash", + addresses: ["tb1qdacfrqauwercrz9jxf0jae5jarqy8ju0ywt8su"] + } + }, + { + value: 0.001, + n: 1, + scriptPubKey: { + asm: "0 b7137dfed18ffe396fbe0b1678608cebdd45b1eb", + hex: "0014b7137dfed18ffe396fbe0b1678608cebdd45b1eb", + reqSigs: 1, + type: "witness_v0_keyhash", + addresses: ["tb1qkufhmlk33llrjma7pvt8scyva0w5tv0tvuy6zs"] + } + } + ] + }; + nock(uri) + .post("/", request) + .times(1) + .basicAuth(auth) + .reply(200, { result, error, id }); + const data = await client.decoderawtransaction(params); + assert.deepStrictEqual(data, result); + }); + + test(".decodescript()", async () => { + const hexstring = + "5221031e925dbe43ca87bce874f4fb77ac0d6bb2dc1a9db93868fa27611b687775bd0b2102ffb8b66ba266797f1e33e5d177a6f9c72839992ccf11e97837054a8d3a8284bc21025bf696347321a5276aad08dfefff19dd09d3717bfc2ce521060f4247d31c37b553ae"; + const params = { hexstring }; + const request = { params, method: "decodescript", id, jsonrpc }; + const result = { + asm: + "2 031e925dbe43ca87bce874f4fb77ac0d6bb2dc1a9db93868fa27611b687775bd0b 02ffb8b66ba266797f1e33e5d177a6f9c72839992ccf11e97837054a8d3a8284bc 025bf696347321a5276aad08dfefff19dd09d3717bfc2ce521060f4247d31c37b5 3 OP_CHECKMULTISIG", + reqSigs: 2, + type: "multisig", + addresses: [ + "miY4Gn8gzbU7SMNzTqRMgU78FVaLCEUnrd", + "mkeLiKDk5MZX19e8P2CrKA2mwNgWLwzUoW", + "mucT5ReiLujp3bA1mRSud7eAF6aRfS3v3D" + ], + p2sh: "2NFnZXZPkTfKPmBbDY6EhmVZc4tNK3eyLcr", + segwit: { + asm: + "0 cc753b00fe0605f9f01bacd56c716c14d12676f40ec9e46e2de742b1d9175517", + hex: + "0020cc753b00fe0605f9f01bacd56c716c14d12676f40ec9e46e2de742b1d9175517", + reqSigs: 1, + type: "witness_v0_scripthash", + addresses: [ + "tb1qe36nkq87qczlnuqm4n2kcutvzngjvah5pmy7gm3duaptrkgh25ts0p4m5w" + ], + "p2sh-segwit": "2Mzt4Uc77wz8rGk3Yad2kgJuj47ax5soMCJ" + } + }; + nock(uri) + .post("/", request) + .times(1) + .basicAuth(auth) + .reply(200, { result, error, id }); + const data = await client.decodescript(params); + assert.deepStrictEqual(data, result); + }); + + test(".finalizepsbt()", async () => { + const psbt = + "cHNidP8BAHsCAAAAAn+RFbuIDPiBkN5ua0vnUVZwwvbnnDZ8Ca4Z6y3vQyqnAAAAAAD9////KUVYeBVxQc4IZCvsc2WohVhZanD54jy11Gxxn4YRtpYBAAAAAP3///8BYII7AAAAAAAWABSANbyZwTJ0B7qPqpWSolEEKYbIFQEAAAAAAQEfIAMAAAAAAAAWABRCHnul3Lf2vUn4GUU9mrnGLnTHsQEIawJHMEQCIAenBxHwiJAo9Mt/0B0gsflruKfe90W0OUaW/gMqT13hAiBrcsvglEZvxDWKKhMLArU52ndMb6cAangC/u6mowwjGAEhAoNFASSjynZOTTIf6bOnANXURu5zQ9eGpUAcB1x569/qAAEBH8eBOwAAAAAAFgAUM0FW+4lXrlP/+jauvoCEpLAM+30BCGsCRzBEAiBbIUvwV1aHSQHwJsovYaxU9BTZaBv0Thi87An0oux4yAIgcF1o//O5iDtjhwvkH6COw5QHg8Wyzr52cAKmf/5T1SMBIQNOLcpPJlb28pa3FjF+WjkHuXU8dKqfQZSV/wCxeQZ+9AAA"; + const extract = true; + const params = { psbt, extract }; + const request = { params, method: "finalizepsbt", id, jsonrpc }; + const result = { + hex: + "020000000001027f9115bb880cf88190de6e6b4be7515670c2f6e79c367c09ae19eb2def432aa70000000000fdffffff29455878157141ce08642bec7365a88558596a70f9e23cb5d46c719f8611b6960100000000fdffffff0160823b00000000001600148035bc99c1327407ba8faa9592a251042986c81502473044022007a70711f0889028f4cb7fd01d20b1f96bb8a7def745b4394696fe032a4f5de102206b72cbe094466fc4358a2a130b02b539da774c6fa7006a7802feeea6a30c231801210283450124a3ca764e4d321fe9b3a700d5d446ee7343d786a5401c075c79ebdfea0247304402205b214bf05756874901f026ca2f61ac54f414d9681bf44e18bcec09f4a2ec78c80220705d68fff3b9883b63870be41fa08ec3940783c5b2cebe767002a67ffe53d5230121034e2dca4f2656f6f296b716317e5a3907b9753c74aa9f419495ff00b179067ef401000000", + complete: true + }; + nock(uri) + .post("/", request) + .times(1) + .basicAuth(auth) + .reply(200, { result, error, id }); + const data = await client.finalizepsbt(params); + assert.deepStrictEqual(data, result); + }); + + test(".fundrawtransaction()", async () => { + const hexstring = + "020000000129455878157141ce08642bec7365a88558596a70f9e23cb5d46c719f8611b6960000000000fdffffff0140420f00000000001600148470e04e616ab6552d72e8284a32a293ff8a959b00000000"; + const replaceable = true; + const changeAddress = "tb1q80h3kvp98fgkz293we3p75hs0aq4cecz3qtgkg"; + const options = { replaceable, changeAddress }; + const iswitness = true; + const wallet = "wallet123.dat"; + const params = { hexstring, options, iswitness }; + const request = { params, method: "fundrawtransaction", id, jsonrpc }; + const result = { + hex: + "020000000229455878157141ce08642bec7365a88558596a70f9e23cb5d46c719f8611b6960000000000fdffffffa95716e643eed9055510fb925eb59b536ff496c642b2904ed5260c03574751d10000000000fdffffff02d4c52d00000000001600143bef1b30253a516128b176621f52f07f415c670240420f00000000001600148470e04e616ab6552d72e8284a32a293ff8a959b00000000", + fee: 0.00000236, + changepos: 0 + }; + nock(uri) + .post("/wallet/" + wallet, request) + .times(1) + .basicAuth(auth) + .reply(200, { result, error, id }); + const data = await client.fundrawtransaction(params, wallet); + assert.deepStrictEqual(data, result); + }); + + test(".getrawtransaction()", async () => { + const txid = + "a32ddaed3387a2bc0bb9a4f90bc6e84e5589335b97142848ad144efd38420eb2"; + const verbose = true; + const blockhash = + "00000000480351c0fc7047af37756bbae30996a018e94d9ca8156dccea032018"; + const params = { txid, verbose, blockhash }; + const request = { params, method: "getrawtransaction", id, jsonrpc }; + const result = { + in_active_chain: true, + txid: + "a32ddaed3387a2bc0bb9a4f90bc6e84e5589335b97142848ad144efd38420eb2", + hash: + "a32ddaed3387a2bc0bb9a4f90bc6e84e5589335b97142848ad144efd38420eb2", + version: 1, + size: 190, + vsize: 190, + weight: 760, + locktime: 0, + vin: [ + { + txid: + "2250db8ac157f4523e18ec9521bfb3c3249752d112dab14d4742ddce4ceb3189", + vout: 1, + scriptSig: { + asm: + "3045022100d21fffc9343da1b2ec190c7084f8a69d201adcd88b880beb013fa4e0ab4158ad02205e0c362f844cc63539467b37d583128c7d2f7754864d08efe29cef98272688e2[ALL] 039c17e0e4ebd61c753fda99392658a692dbfdab430399b1e12221da6a4cda5dd9", + hex: + "483045022100d21fffc9343da1b2ec190c7084f8a69d201adcd88b880beb013fa4e0ab4158ad02205e0c362f844cc63539467b37d583128c7d2f7754864d08efe29cef98272688e20121039c17e0e4ebd61c753fda99392658a692dbfdab430399b1e12221da6a4cda5dd9" + }, + sequence: 4294967295 + } + ], + vout: [ + { + value: 0.53015771, + n: 0, + scriptPubKey: { + asm: + "OP_HASH160 5629021f7668d4ec310ac5e99701a6d6cf95eb8f OP_EQUAL", + hex: "a9145629021f7668d4ec310ac5e99701a6d6cf95eb8f87", + reqSigs: 1, + type: "scripthash", + addresses: ["2N16oE62ZjAPup985dFBQYAuy5zpDraH7Hk"] + } + } + ], + hex: + "01000000018931eb4ccedd42474db1da12d1529724c3b3bf2195ec183e52f457c18adb5022010000006b483045022100d21fffc9343da1b2ec190c7084f8a69d201adcd88b880beb013fa4e0ab4158ad02205e0c362f844cc63539467b37d583128c7d2f7754864d08efe29cef98272688e20121039c17e0e4ebd61c753fda99392658a692dbfdab430399b1e12221da6a4cda5dd9ffffffff01dbf428030000000017a9145629021f7668d4ec310ac5e99701a6d6cf95eb8f8700000000", + blockhash: + "00000000480351c0fc7047af37756bbae30996a018e94d9ca8156dccea032018", + confirmations: 3204, + time: 1570540739, + blocktime: 1570540739 + }; + nock(uri) + .post("/", request) + .times(1) + .basicAuth(auth) + .reply(200, { result, error, id }); + const data = await client.getrawtransaction(params); + assert.deepStrictEqual(data, result); + }); + + test(".joinpsbts()", async () => { + const txs = [ + "cHNidP8BAFICAAAAAdVSFGEYzcJX2qwhy8iJGI1Y/zeIqBQtH/OBC9WJ4mx7AQAAAAD9////AdhHAwAAAAAAFgAUb3CRg7x2R4GIsjJfLuaS6MBDy48BAAAAAAAA", + "cHNidP8BAFICAAAAAWs2nFCyIbZPRlxerXXu2guE90c1aA2ur+ibcnP9j3X/AAAAAAD9////AaCGAQAAAAAAFgAUtxN9/tGP/jlvvgsWeGCM691FsesBAAAAAAAA" + ]; + const params = { txs }; + const request = { params, method: "joinpsbts", id, jsonrpc }; + const result = + "cHNidP8BAJoCAAAAAtVSFGEYzcJX2qwhy8iJGI1Y/zeIqBQtH/OBC9WJ4mx7AQAAAAD9////azacULIhtk9GXF6tde7aC4T3RzVoDa6v6Jtyc/2Pdf8AAAAAAP3///8C2EcDAAAAAAAWABRvcJGDvHZHgYiyMl8u5pLowEPLj6CGAQAAAAAAFgAUtxN9/tGP/jlvvgsWeGCM691FsesBAAAAAAAAAAA="; + nock(uri) + .post("/", request) + .times(1) + .basicAuth(auth) + .reply(200, { result, error, id }); + const data = await client.joinpsbts(params); + assert.deepStrictEqual(data, result); + }); + + test(".sendrawtransaction()", async () => { + const hexstring = + "020000000001027f9115bb880cf88190de6e6b4be7515670c2f6e79c367c09ae19eb2def432aa70000000000fdffffff29455878157141ce08642bec7365a88558596a70f9e23cb5d46c719f8611b6960100000000fdffffff0160823b00000000001600148035bc99c1327407ba8faa9592a251042986c81502473044022007a70711f0889028f4cb7fd01d20b1f96bb8a7def745b4394696fe032a4f5de102206b72cbe094466fc4358a2a130b02b539da774c6fa7006a7802feeea6a30c231801210283450124a3ca764e4d321fe9b3a700d5d446ee7343d786a5401c075c79ebdfea0247304402205b214bf05756874901f026ca2f61ac54f414d9681bf44e18bcec09f4a2ec78c80220705d68fff3b9883b63870be41fa08ec3940783c5b2cebe767002a67ffe53d5230121034e2dca4f2656f6f296b716317e5a3907b9753c74aa9f419495ff00b179067ef401000000"; + const allowhighfees = true; + const params = { hexstring, allowhighfees }; + const request = { params, method: "sendrawtransaction", id, jsonrpc }; + const result = + "d1514757030c26d54e90b242c696f46f539bb55e92fb105505d9ee43e61657a9"; + nock(uri) + .post("/", request) + .times(1) + .basicAuth(auth) + .reply(200, { result, error, id }); + const data = await client.sendrawtransaction(params); + assert.deepStrictEqual(data, result); + }); + + test(".signrawtransactionwithkey()", async () => { + const hexstring = + "02000000029a2b645e97cfde604d0b65aa174fb4747f8b99152f581d12d42055f3388c123e0000000000fdffffff9a2b645e97cfde604d0b65aa174fb4747f8b99152f581d12d42055f3388c123e0100000000fdffffff0180250000000000001600143d366a85a8c07a44b5eed0a622197d6784c07e6900000000"; + const privkeys = [ + "cSo9pNKNPhPhebybLJaE2BdqAtYjMGJHpxujScKd2ZTrgxCD28r6", + "cQeGBYp4NiFj2L2d1ivgan4UMsba3oWQKiBf98tq1QXjPiKQMQeB" + ]; + const sighashtype: "ALL|ANYONECANPAY" = "ALL|ANYONECANPAY"; + const params = { hexstring, privkeys, sighashtype }; + const request = { + params, + method: "signrawtransactionwithkey", + id, + jsonrpc + }; + const result = { + hex: + "020000000001029a2b645e97cfde604d0b65aa174fb4747f8b99152f581d12d42055f3388c123e0000000000fdffffff9a2b645e97cfde604d0b65aa174fb4747f8b99152f581d12d42055f3388c123e0100000000fdffffff0180250000000000001600143d366a85a8c07a44b5eed0a622197d6784c07e69024730440220451546bae0bc61270eec966f1ca0a5cb16a93c5f88a800094240e61fb3f6fdd7022021a0065ec25e06f9e0b3a4d87b06d13adc2bd620dd8f2ecf7a40366ceaa93e998121039a3d49d8d6a2ca7ff2ea6657d3c8c19ba20ab67f529edb522030928b5f4894d20247304402201596d19c0eec785d301dad21ecc8bad1d808d4bd15615df1a5a1b9e930404066022038126c82743ccf5bc225b61a38ddd7ae651f12d27a730817de79279df8fd0ab88121028cc283639d0254c3f3091659d66f7681189de1ade326d36eefa50217956b057b00000000", + complete: true + }; + nock(uri) + .post("/", request) + .times(1) + .basicAuth(auth) + .reply(200, { result, error, id }); + const data = await client.signrawtransactionwithkey(params); + assert.deepStrictEqual(data, result); + }); + + test(".testmempoolaccept()", async () => { + const rawtxs = [ + "020000000001027f9115bb880cf88190de6e6b4be7515670c2f6e79c367c09ae19eb2def432aa70000000000fdffffff29455878157141ce08642bec7365a88558596a70f9e23cb5d46c719f8611b6960100000000fdffffff0160823b00000000001600148035bc99c1327407ba8faa9592a251042986c81502473044022007a70711f0889028f4cb7fd01d20b1f96bb8a7def745b4394696fe032a4f5de102206b72cbe094466fc4358a2a130b02b539da774c6fa7006a7802feeea6a30c231801210283450124a3ca764e4d321fe9b3a700d5d446ee7343d786a5401c075c79ebdfea0247304402205b214bf05756874901f026ca2f61ac54f414d9681bf44e18bcec09f4a2ec78c80220705d68fff3b9883b63870be41fa08ec3940783c5b2cebe767002a67ffe53d5230121034e2dca4f2656f6f296b716317e5a3907b9753c74aa9f419495ff00b179067ef401000000" + ]; + const allowhighfees = true; + const params = { rawtxs, allowhighfees }; + const request = { params, method: "testmempoolaccept", id, jsonrpc }; + const result = [ + { + txid: + "d1514757030c26d54e90b242c696f46f539bb55e92fb105505d9ee43e61657a9", + allowed: true + } + ]; + nock(uri) + .post("/", request) + .times(1) + .basicAuth(auth) + .reply(200, { result, error, id }); + const data = await client.testmempoolaccept(params); + assert.deepStrictEqual(data, result); + }); + + test(".utxoupdatepsbt()", async () => { + const psbt = + "cHNidP8BAHsCAAAAAn+RFbuIDPiBkN5ua0vnUVZwwvbnnDZ8Ca4Z6y3vQyqnAAAAAAD9////KUVYeBVxQc4IZCvsc2WohVhZanD54jy11Gxxn4YRtpYBAAAAAP3///8BYII7AAAAAAAWABSANbyZwTJ0B7qPqpWSolEEKYbIFQEAAAAAAQEfIAMAAAAAAAAWABRCHnul3Lf2vUn4GUU9mrnGLnTHsQEIawJHMEQCIAenBxHwiJAo9Mt/0B0gsflruKfe90W0OUaW/gMqT13hAiBrcsvglEZvxDWKKhMLArU52ndMb6cAangC/u6mowwjGAEhAoNFASSjynZOTTIf6bOnANXURu5zQ9eGpUAcB1x569/qAAAA"; + const params = { psbt }; + const request = { params, method: "utxoupdatepsbt", id, jsonrpc }; + const result = + "cHNidP8BAHsCAAAAAn+RFbuIDPiBkN5ua0vnUVZwwvbnnDZ8Ca4Z6y3vQyqnAAAAAAD9////KUVYeBVxQc4IZCvsc2WohVhZanD54jy11Gxxn4YRtpYBAAAAAP3///8BYII7AAAAAAAWABSANbyZwTJ0B7qPqpWSolEEKYbIFQEAAAAAAQEfIAMAAAAAAAAWABRCHnul3Lf2vUn4GUU9mrnGLnTHsQEIawJHMEQCIAenBxHwiJAo9Mt/0B0gsflruKfe90W0OUaW/gMqT13hAiBrcsvglEZvxDWKKhMLArU52ndMb6cAangC/u6mowwjGAEhAoNFASSjynZOTTIf6bOnANXURu5zQ9eGpUAcB1x569/qAAEBH8eBOwAAAAAAFgAUM0FW+4lXrlP/+jauvoCEpLAM+30AAA=="; + nock(uri) + .post("/", request) + .times(1) + .basicAuth(auth) + .reply(200, { result, error, id }); + const data = await client.utxoupdatepsbt(params); + assert.deepStrictEqual(data, result); + }); + }); + suite("Util", () => { test(".createmultisig()", async () => { const nrequired = 2;