diff --git a/web3.js/module.flow.js b/web3.js/module.flow.js index f882810064..c5e4a5756f 100644 --- a/web3.js/module.flow.js +++ b/web3.js/module.flow.js @@ -255,4 +255,10 @@ declare module '@solana/web3.js' { transaction: Transaction, ...signers: Array ): Promise; + + // === src/util/send-and-confirm-raw-transaction.js === + declare export function sendAndConfirmRawTransaction( + connection: Connection, + wireTransaction: Buffer, + ): Promise; } diff --git a/web3.js/src/connection.js b/web3.js/src/connection.js index 364f3f54ca..db21598b72 100644 --- a/web3.js/src/connection.js +++ b/web3.js/src/connection.js @@ -142,7 +142,7 @@ const RequestAirdropRpcResult = jsonRpcResult('string'); /** * Expected JSON RPC response for the "sendTransaction" message */ -const SendTokensRpcResult = jsonRpcResult('string'); +const SendTransactionRpcResult = jsonRpcResult('string'); /** * Information describing an account @@ -429,12 +429,12 @@ export class Connection { * wire format */ async sendRawTransaction( - wireTransaction: Buffer, + rawTransaction: Buffer, ): Promise { const unsafeRes = await this._rpcRequest('sendTransaction', [ - [...wireTransaction], + [...rawTransaction], ]); - const res = SendTokensRpcResult(unsafeRes); + const res = SendTransactionRpcResult(unsafeRes); if (res.error) { throw new Error(res.error.message); } diff --git a/web3.js/src/index.js b/web3.js/src/index.js index 9620b7190d..6c67c54334 100644 --- a/web3.js/src/index.js +++ b/web3.js/src/index.js @@ -10,3 +10,6 @@ export {SystemProgram} from './system-program'; export {Token, TokenAmount} from './token-program'; export {Transaction, TransactionInstruction} from './transaction'; export {sendAndConfirmTransaction} from './util/send-and-confirm-transaction'; +export { + sendAndConfirmRawTransaction, +} from './util/send-and-confirm-raw-transaction'; diff --git a/web3.js/src/util/send-and-confirm-raw-transaction.js b/web3.js/src/util/send-and-confirm-raw-transaction.js new file mode 100644 index 0000000000..b4e0b6b44e --- /dev/null +++ b/web3.js/src/util/send-and-confirm-raw-transaction.js @@ -0,0 +1,42 @@ +// @flow + +import {Connection} from '../connection'; +import {sleep} from './sleep'; +import type {TransactionSignature} from '../transaction'; + +/** + * Sign, send and confirm a raw transaction + */ +export async function sendAndConfirmRawTransaction( + connection: Connection, + rawTransaction: Buffer, +): Promise { + const start = Date.now(); + let signature = await connection.sendRawTransaction(rawTransaction); + + // Wait up to a couple seconds for a confirmation + let status = ''; + let statusRetries = 4; + for (;;) { + status = await connection.getSignatureStatus(signature); + if (status !== 'SignatureNotFound') { + break; + } + + await sleep(500); + if (--statusRetries <= 0) { + const duration = (Date.now() - start) / 1000; + throw new Error( + `Raw Transaction '${signature}' was not confirmed in ${duration.toFixed( + 2, + )} seconds (${status})`, + ); + } + } + + if (status === 'Confirmed') { + return signature; + } + + throw new Error(`Raw transaction ${signature} failed (${status})`); +} diff --git a/web3.js/src/util/send-and-confirm-transaction.js b/web3.js/src/util/send-and-confirm-transaction.js index b2894068fc..f24d13cc46 100644 --- a/web3.js/src/util/send-and-confirm-transaction.js +++ b/web3.js/src/util/send-and-confirm-transaction.js @@ -1,5 +1,7 @@ // @flow +import invariant from 'assert'; + import {Connection} from '../connection'; import {Transaction} from '../transaction'; import {sleep} from './sleep'; @@ -13,7 +15,7 @@ export async function sendAndConfirmTransaction( connection: Connection, transaction: Transaction, ...signers: Array -): Promise { +): Promise { let sendRetries = 10; let signature; for (;;) { @@ -52,5 +54,6 @@ export async function sendAndConfirmTransaction( await sleep(Math.random() * 100); } + invariant(signature !== undefined); return signature; }