From 7104fc792c83d290bbb5fc063b44cc76589938a0 Mon Sep 17 00:00:00 2001 From: Micah Riggan Date: Thu, 7 Nov 2019 14:14:31 -0500 Subject: [PATCH] Refactor rpc so all methods async, sendRawTransaction handles arrays --- .../src/modules/ethereum/api/csp.ts | 19 +++-- .../chain-state/internal/internal.ts | 16 ++-- packages/bitcore-node/src/rpc.ts | 74 +++++++++---------- .../types/namespaces/ChainStateProvider.ts | 2 +- 4 files changed, 54 insertions(+), 57 deletions(-) diff --git a/packages/bitcore-node/src/modules/ethereum/api/csp.ts b/packages/bitcore-node/src/modules/ethereum/api/csp.ts index 0c6c6bd2a8d..050134329f5 100644 --- a/packages/bitcore-node/src/modules/ethereum/api/csp.ts +++ b/packages/bitcore-node/src/modules/ethereum/api/csp.ts @@ -160,12 +160,19 @@ export class ETHStateProvider extends InternalStateProvider implements CSP.IChai async broadcastTransaction(params: CSP.BroadcastTransactionParams) { const { network, rawTx } = params; const web3 = await this.getWeb3(network); - return new Promise((resolve, reject) => { - web3.eth - .sendSignedTransaction(rawTx) - .on('transactionHash', resolve) - .on('error', reject); - }); + const rawTxs = typeof rawTx === 'string' ? [rawTx] : rawTx; + const txids = new Array(); + for (const tx of rawTxs) { + const txid = await new Promise((resolve, reject) => { + web3.eth + .sendSignedTransaction(tx) + .on('transactionHash', resolve) + .on('error', reject) + .catch(e => reject(e)); + }); + txids.push(txid); + } + return txids.length === 1 ? txids[0] : txids; } async getWalletAddresses(walletId: ObjectID) { diff --git a/packages/bitcore-node/src/providers/chain-state/internal/internal.ts b/packages/bitcore-node/src/providers/chain-state/internal/internal.ts index be7386995ef..0e67eadc541 100644 --- a/packages/bitcore-node/src/providers/chain-state/internal/internal.ts +++ b/packages/bitcore-node/src/providers/chain-state/internal/internal.ts @@ -425,15 +425,13 @@ export class InternalStateProvider implements CSP.IChainStateService { async broadcastTransaction(params: CSP.BroadcastTransactionParams) { const { chain, network, rawTx } = params; - return new Promise((resolve, reject) => { - this.getRPC(chain, network).sendTransaction(rawTx, (err: any, result: any) => { - if (err) { - reject(err); - } else { - resolve(result); - } - }); - }); + const txids = new Array(); + const rawTxs = typeof rawTx === 'string' ? [rawTx] : rawTx; + for (const tx of rawTxs) { + const txid = await this.getRPC(chain, network).sendTransaction(tx); + txids.push(txid); + } + return txids.length === 1 ? txids[0] : txids; } async getCoinsForTx({ chain, network, txid }: { chain: string; network: string; txid: string }) { diff --git a/packages/bitcore-node/src/rpc.ts b/packages/bitcore-node/src/rpc.ts index ebeb22a475d..c8395677e89 100644 --- a/packages/bitcore-node/src/rpc.ts +++ b/packages/bitcore-node/src/rpc.ts @@ -39,8 +39,8 @@ export class RPC { ); } - async asyncCall(method: string, params: any[]) { - return new Promise((resolve, reject) => { + async asyncCall(method: string, params: any[]) { + return new Promise((resolve, reject) => { this.callMethod(method, params, (err, data) => { if (err) { return reject(err); @@ -50,59 +50,52 @@ export class RPC { }); } - getChainTip(callback: CallbackType) { - this.callMethod('getchaintips', [], (err, result) => { - if (err) { - return callback(err); - } - return callback(null, result[0]); - }); + async getChainTip() { + const tips = await this.asyncCall<{ + height: number; + hash: string; + branchlen: number; + status: string; + }>('getchaintips', []); + return tips[0]; } - getBestBlockHash(callback: CallbackType) { - this.callMethod('getbestblockhash', [], callback); + getBestBlockHash() { + return this.asyncCall('getbestblockhash', []); } - getBlockHeight(callback: CallbackType) { - this.callMethod('getblockcount', [], callback); + getBlockHeight() { + return this.asyncCall('getblockcount', []); } - getBlock(hash: string, verbose: boolean, callback: CallbackType) { - this.callMethod('getblock', [hash, verbose], callback); + getBlock(hash: string, verbose: boolean) { + return this.asyncCall('getblock', [hash, verbose]); } - getBlockHash(height: number, callback: CallbackType) { - this.callMethod('getblockhash', [height], callback); + getBlockHash(height: number) { + return this.asyncCall('getblockhash', [height]); } - getBlockByHeight(height: number, callback: CallbackType) { - this.getBlockHash(height, (err, hash) => { - if (err) { - return callback(err); - } - this.getBlock(hash, false, callback); - }); + async getBlockByHeight(height: number) { + const hash = await this.getBlockHash(height); + return this.getBlock(hash, false); } - getTransaction(txid: string, callback: CallbackType) { - this.callMethod('getrawtransaction', [txid, true], (err, result) => { - if (err) { - return callback(err); - } - return callback(null, result); - }); + getTransaction(txid: string) { + return this.asyncCall('getrawtransaction', [txid, true]); } - sendTransaction(rawTx: string, callback: CallbackType) { - this.callMethod('sendrawtransaction', [rawTx], callback); + sendTransaction(rawTx: string | Array) { + const txs = typeof rawTx === 'string' ? [rawTx] : rawTx; + return this.asyncCall('sendrawtransaction', txs); } - decodeScript(hex: string, callback: CallbackType) { - this.callMethod('decodescript', [hex], callback); + decodeScript(hex: string) { + return this.asyncCall('decodescript', [hex]); } - getWalletAddresses(account: string, callback: CallbackType) { - this.callMethod('getaddressesbyaccount', [account], callback); + getWalletAddresses(account: string) { + return this.asyncCall('getaddressesbyaccount', [account]); } async getEstimateSmartFee(target: number) { @@ -147,14 +140,13 @@ export class AsyncRPC { async signrawtx(txs: string): Promise { try { - const ret = await this.call('signrawtransactionwithwallet', [txs]); + const ret = await this.call('signrawtransactionwithwallet', [txs]); return ret; } catch (e) { if (!e.code || e.code != -32601) return Promise.reject(e); - return await this.call('signrawtransaction', [txs]); + return await this.call('signrawtransaction', [txs]); } - }; - + } async transaction(txid: string, block?: string): Promise { const args = [txid, true]; diff --git a/packages/bitcore-node/src/types/namespaces/ChainStateProvider.ts b/packages/bitcore-node/src/types/namespaces/ChainStateProvider.ts index 1b949688ade..4f8cc5113ca 100644 --- a/packages/bitcore-node/src/types/namespaces/ChainStateProvider.ts +++ b/packages/bitcore-node/src/types/namespaces/ChainStateProvider.ts @@ -49,7 +49,7 @@ export declare namespace CSP { target: number; }; export type BroadcastTransactionParams = ChainNetwork & { - rawTx: string; + rawTx: string | Array; }; export type CreateWalletParams = IWallet; export type GetWalletParams = ChainNetwork & PubKey;