diff --git a/es/chain/index.js b/es/chain/index.js index fec996b422..578ccfe876 100644 --- a/es/chain/index.js +++ b/es/chain/index.js @@ -43,7 +43,7 @@ const Chain = Oracle.compose({ Ae: { methods: [ 'sendTransaction', 'height', 'awaitHeight', 'poll', 'balance', 'getBalance', 'tx', - 'mempool', 'topBlock', 'getTxInfo', 'txDryRun', 'getName', 'getNodeInfo', 'getAccount', 'getContractByteCode', 'getContract' + 'mempool', 'topBlock', 'getTxInfo', 'txDryRun', 'getName', 'getNodeInfo', 'getAccount', 'getContractByteCode', 'getContract', 'waitForTxConfirm' ] } } @@ -190,6 +190,19 @@ const Chain = Oracle.compose({ * @return {Object} Generation */ +/** + * Wait for transaction confirmation + * @function waitForTxConfirm + * @instance + * @abstract + * @category async + * @rtype (txHash: String, { confirm: Number | Boolean } = { confirm: 3 }) => Promise + * @param {String} txHash - Generation hash or height + * @param {String} [options={}] - options + * @param {String} [options.confirm=3] - Block confirmation count + * @return {Promise} Current Height + */ + /** * Get micro block transactions * @function getMicroBlockTransactions diff --git a/es/chain/node.js b/es/chain/node.js index 8d204b68b3..75e8f81698 100644 --- a/es/chain/node.js +++ b/es/chain/node.js @@ -47,7 +47,16 @@ async function sendTransaction (tx, options = {}) { try { const { txHash } = await this.api.postTransaction({ tx }) - return waitMined ? { ...(await this.poll(txHash, options)), rawTx: tx } : { hash: txHash, rawTx: tx } + + if (waitMined) { + const txData = { ...(await this.poll(txHash, options)), rawTx: tx } + // wait for transaction confirmation + if (options.confirm) { + return { ...txData, confirmationHeight: await this.waitForTxConfirm(txHash, options) } + } + return txData + } + return { hash: txHash, rawTx: tx } } catch (e) { throw Object.assign( (new Error(e.message)), @@ -59,6 +68,12 @@ async function sendTransaction (tx, options = {}) { } } +async function waitForTxConfirm (txHash, options = { confirm: 3 }) { + options.confirm = typeof options.confirm === 'boolean' && options.confirm ? 3 : options.confirm + const { blockHeight } = await this.tx(txHash) + return this.awaitHeight(blockHeight + options.confirm, options) +} + async function getAccount (address, { height, hash } = {}) { if (height) return this.api.getAccountByPubkeyAndHeight(address, height) if (hash) return this.api.getAccountByPubkeyAndHash(address, hash) @@ -227,7 +242,8 @@ const ChainNode = Chain.compose(Oracle, TransactionValidator, NodePool, { txDryRun, getContractByteCode, getContract, - getName + getName, + waitForTxConfirm } }) diff --git a/test/integration/chain.js b/test/integration/chain.js index a47585808e..2d3250ab51 100644 --- a/test/integration/chain.js +++ b/test/integration/chain.js @@ -92,4 +92,15 @@ describe('Node Chain', function () { await client.poll(txHash).should.eventually.be.fulfilled return client.poll('th_xxx', { blocks: 1 }).should.eventually.be.rejected }) + + it('Wait for transaction confirmation', async () => { + const txData = await client.spend(1000, await client.address(), { confirm: true }) + const isConfirmed = (await client.height()) >= txData.blockHeight + 3 + + isConfirmed.should.be.equal(true) + + const txData2 = await client.spend(1000, await client.address(), { confirm: 4 }) + const isConfirmed2 = (await client.height()) >= txData2.blockHeight + 4 + isConfirmed2.should.be.equal(true) + }) })