Merge pull request #30 from Permissionless-Software-Foundation/broacast-tx

Add Electrumx Broadcast TX method
This commit is contained in:
Chris Troutner
2020-10-09 11:35:12 -07:00
committed by GitHub
5 changed files with 114 additions and 4 deletions
+40
View File
@@ -543,6 +543,46 @@ class ElectrumX {
else throw error
}
}
/**
* @api Electrumx.broadcast() broadcast()
* @apiName ElectrumX Broadcast
* @apiGroup ElectrumX
* @apiDescription Broadcast a raw transaction and return the transaction ID on success or error on failure.
*
* (async () => {
* try {
* const txHex = "020000000265d13ef402840c8a51f39779afb7ae4d49e4b0a3c24a3d0e7742038f2c679667010000006441dd1dd72770cadede1a7fd0363574846c48468a398ddfa41a9677c74cac8d2652b682743725a3b08c6c2021a629011e11a264d9036e9d5311e35b5f4937ca7b4e4121020797d8fd4d2fa6fd7cdeabe2526bfea2b90525d6e8ad506ec4ee3c53885aa309ffffffff65d13ef402840c8a51f39779afb7ae4d49e4b0a3c24a3d0e7742038f2c679667000000006441347d7f218c11c04487c1ad8baac28928fb10e5054cd4494b94d078cfa04ccf68e064fb188127ff656c0b98e9ce87f036d183925d0d0860605877d61e90375f774121028a53f95eb631b460854fc836b2e5d31cad16364b4dc3d970babfbdcc3f2e4954ffffffff035ac355000000000017a914189ce02e332548f4804bac65cba68202c9dbf822878dfd0800000000001976a914285bb350881b21ac89724c6fb6dc914d096cd53b88acf9ef3100000000001976a91445f1f1c4a9b9419a5088a3e9c24a293d7a150e6488ac00000000"
* let result = await bchjs.Electrumx.broadcast(txHex)
* console.log(result);
* } catch(error) {
* console.error(error)
* }
* })()
*
* result = {
* "success": true,
* "txid": "..."
* }
*/
async broadcast(txHex) {
try {
if (typeof txHex === "string") {
const response = await axios.post(
`${this.restURL}electrumx/tx/broadcast`,
{ txHex },
_this.axiosOptions
)
return response.data
}
throw new Error(`Input txHex must be a string.`)
} catch (error) {
if (error.response && error.response.data) throw error.response.data
else throw error
}
}
}
module.exports = ElectrumX
+22 -3
View File
@@ -271,7 +271,8 @@ describe(`#ElectrumX`, () => {
describe(`#txData`, () => {
it(`should GET details for a single transaction`, async () => {
const txid = "4db095f34d632a4daf942142c291f1f2abb5ba2e1ccac919d85bdc2f671fb251"
const txid =
"4db095f34d632a4daf942142c291f1f2abb5ba2e1ccac919d85bdc2f671fb251"
const result = await bchjs.Electrumx.txData(txid)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
@@ -318,8 +319,11 @@ describe(`#ElectrumX`, () => {
it(`should throw error on array size rate limit`, async () => {
try {
const txids = []
for (let i = 0; i < 25; i++)
txids.push("4db095f34d632a4daf942142c291f1f2abb5ba2e1ccac919d85bdc2f671fb251")
for (let i = 0; i < 25; i++) {
txids.push(
"4db095f34d632a4daf942142c291f1f2abb5ba2e1ccac919d85bdc2f671fb251"
)
}
await bchjs.Electrumx.txData(txids)
@@ -331,4 +335,19 @@ describe(`#ElectrumX`, () => {
}
})
})
describe(`#broadcast`, () => {
it(`should broadcast a single transaction`, async () => {
const txHex =
"020000000265d13ef402840c8a51f39779afb7ae4d49e4b0a3c24a3d0e7742038f2c679667010000006441dd1dd72770cadede1a7fd0363574846c48468a398ddfa41a9677c74cac8d2652b682743725a3b08c6c2021a629011e11a264d9036e9d5311e35b5f4937ca7b4e4121020797d8fd4d2fa6fd7cdeabe2526bfea2b90525d6e8ad506ec4ee3c53885aa309ffffffff65d13ef402840c8a51f39779afb7ae4d49e4b0a3c24a3d0e7742038f2c679667000000006441347d7f218c11c04487c1ad8baac28928fb10e5054cd4494b94d078cfa04ccf68e064fb188127ff656c0b98e9ce87f036d183925d0d0860605877d61e90375f774121028a53f95eb631b460854fc836b2e5d31cad16364b4dc3d970babfbdcc3f2e4954ffffffff035ac355000000000017a914189ce02e332548f4804bac65cba68202c9dbf822878dfd0800000000001976a914285bb350881b21ac89724c6fb6dc914d096cd53b88acf9ef3100000000001976a91445f1f1c4a9b9419a5088a3e9c24a293d7a150e6488ac00000000"
try {
await bchjs.Electrumx.broadcast(txHex)
} catch (err) {
assert.property(err, "success")
assert.equal(err.success, false)
assert.include(err.error, "Missing inputs")
}
})
})
})
+14
View File
@@ -335,4 +335,18 @@ describe(`#ElectrumX`, () => {
}
})
})
describe(`#broadcast`, () => {
it(`should broadcast a single transaction`, async () => {
const txHex = "020000000265d13ef402840c8a51f39779afb7ae4d49e4b0a3c24a3d0e7742038f2c679667010000006441dd1dd72770cadede1a7fd0363574846c48468a398ddfa41a9677c74cac8d2652b682743725a3b08c6c2021a629011e11a264d9036e9d5311e35b5f4937ca7b4e4121020797d8fd4d2fa6fd7cdeabe2526bfea2b90525d6e8ad506ec4ee3c53885aa309ffffffff65d13ef402840c8a51f39779afb7ae4d49e4b0a3c24a3d0e7742038f2c679667000000006441347d7f218c11c04487c1ad8baac28928fb10e5054cd4494b94d078cfa04ccf68e064fb188127ff656c0b98e9ce87f036d183925d0d0860605877d61e90375f774121028a53f95eb631b460854fc836b2e5d31cad16364b4dc3d970babfbdcc3f2e4954ffffffff035ac355000000000017a914189ce02e332548f4804bac65cba68202c9dbf822878dfd0800000000001976a914285bb350881b21ac89724c6fb6dc914d096cd53b88acf9ef3100000000001976a91445f1f1c4a9b9419a5088a3e9c24a293d7a150e6488ac00000000"
try {
await bchjs.Electrumx.broadcast(txHex)
} catch (err) {
assert.property(err, "success")
assert.equal(err.success, false)
assert.include(err.error, "Missing inputs")
}
})
})
})
+31
View File
@@ -368,4 +368,35 @@ describe(`#ElectrumX`, () => {
assert.equal(result.transactions.length, 2, "2 outputs for 2 inputs")
})
})
describe(`#broadcast`, () => {
it(`should throw an error for improper input`, async () => {
try {
const txHex = 12345
await bchjs.Electrumx.broadcast(txHex)
assert.equal(true, false, "Unexpected result!")
} catch (err) {
// console.log(`err: `, err)
assert.include(
err.message,
`Input txHex must be a string.`
)
}
})
it(`should broadcast a single transaction`, async () => {
// Stub the network call.
sandbox.stub(axios, "post").resolves({ data: mockData.broadcast })
const tx = mockData.details
const txid = tx.details.txid
const result = await bchjs.Electrumx.broadcast(tx.details.hex)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, "success")
assert.equal(result.success, true)
assert.property(result, "txid")
assert.equal(result.txid, txid)
})
})
})
+7 -1
View File
@@ -250,6 +250,11 @@ const detailsArray = {
]
}
const broadcast = {
success: true,
txid: txDetails.txid
}
module.exports = {
utxo,
utxos,
@@ -261,5 +266,6 @@ module.exports = {
unconfirmedArray,
blockHeaders,
details,
detailsArray
detailsArray,
broadcast
}