diff --git a/web3.js/examples/budget-timestamp.js b/web3.js/examples/budget-timestamp.js index 9595383893..6331b606ac 100644 --- a/web3.js/examples/budget-timestamp.js +++ b/web3.js/examples/budget-timestamp.js @@ -35,10 +35,10 @@ function showBalance() { function confirmTransaction(signature) { console.log('Confirming transaction:', signature); - return connection.confirmTransaction(signature) + return connection.getSignatureStatus(signature) .then((confirmation) => { - if (!confirmation) { - throw new Error('Transaction was not confirmed'); + if (confirmation !== 'Confirmed') { + throw new Error(`Transaction was not confirmed (${confirmation})`); } console.log('Transaction confirmed'); }); diff --git a/web3.js/examples/budget-two-approvers.js b/web3.js/examples/budget-two-approvers.js index e8e3d1baaa..2b595af455 100644 --- a/web3.js/examples/budget-two-approvers.js +++ b/web3.js/examples/budget-two-approvers.js @@ -36,10 +36,10 @@ function showBalance() { function confirmTransaction(signature) { console.log('Confirming transaction:', signature); - return connection.confirmTransaction(signature) + return connection.getSignatureStatus(signature) .then((confirmation) => { - if (!confirmation) { - throw new Error('Transaction was not confirmed'); + if (confirmation !== 'Confirmed') { + throw new Error(`Transaction was not confirmed (${confirmation})`); } console.log('Transaction confirmed'); }); diff --git a/web3.js/package.json b/web3.js/package.json index 9fa297e470..30b6255b23 100644 --- a/web3.js/package.json +++ b/web3.js/package.json @@ -27,10 +27,10 @@ "build": "cross-env NODE_ENV=production rollup -c", "doc": "esdoc; node -p '\"\\nDocumentation coverage: \" + require(\"./doc/coverage.json\").coverage'", "doc:watch": "watch 'npm run doc' . --wait=1 --ignoreDirectoryPattern=/doc/", - "test": "cross-env NODE_ENV=test jest", - "test:live": "cross-env NODE_ENV=test DOITLIVE=1 jest", - "test:watch": "cross-env NODE_ENV=test jest --watch", - "test:cover": "cross-env NODE_ENV=test jest --coverage", + "test": "cross-env NODE_ENV=test jest --useStderr", + "test:live": "cross-env NODE_ENV=test DOITLIVE=1 jest --useStderr", + "test:watch": "cross-env NODE_ENV=test jest --watch --useStderr", + "test:cover": "cross-env NODE_ENV=test jest --coverage --useStderr", "codecov": "npm run test:cover && cat ./coverage/lcov.info | codecov", "flow": "flow-typed install jest@22 && flow", "flow:watch": "watch 'flow' . --wait=1 --ignoreDirectoryPattern=/doc/", diff --git a/web3.js/src/connection.js b/web3.js/src/connection.js index 9962e988da..cb9515901d 100644 --- a/web3.js/src/connection.js +++ b/web3.js/src/connection.js @@ -83,6 +83,21 @@ const ConfirmTransactionRpcResult = struct({ result: 'boolean?', }); +/** + * Expected JSON RPC response for the "getSignatureStatus" message + */ +const GetSignatureStatusRpcResult = struct({ + jsonrpc: struct.literal('2.0'), + id: 'string', + error: 'any?', + result: struct.optional(struct.enum([ + 'Confirmed', + 'SignatureNotFound', + 'ProgramRuntimeError', + 'GenericFailure', + ])), +}); + /** * Expected JSON RPC response for the "getTransactionCount" message */ @@ -147,6 +162,13 @@ type AccountInfo = { userdata: Buffer | null, } +/** + * Possible signature status values + * + * @typedef {string} SignatureStatus + */ +type SignatureStatus = 'Confirmed' | 'SignatureNotFound' | 'ProgramRuntimeError' | 'GenericFailure'; + /** * A connection to a fullnode JSON RPC endpoint */ @@ -224,6 +246,20 @@ export class Connection { return res.result; } + /** + * Fetch the current transaction count of the network + */ + async getSignatureStatus(signature: TransactionSignature): Promise { + const unsafeRes = await this._rpcRequest('getSignatureStatus', [signature]); + const res = GetSignatureStatusRpcResult(unsafeRes); + if (res.error) { + throw new Error(res.error.message); + } + assert(typeof res.result !== 'undefined'); + return res.result; + } + + /** * Fetch the current transaction count of the network */ diff --git a/web3.js/test/connection.test.js b/web3.js/test/connection.test.js index 5a8c6cbd1a..7480aa1839 100644 --- a/web3.js/test/connection.test.js +++ b/web3.js/test/connection.test.js @@ -90,8 +90,22 @@ test('confirm transaction - error', () => { expect(connection.confirmTransaction(badTransactionSignature)) .rejects.toThrow(errorMessage); + + mockRpc.push([ + url, + { + method: 'getSignatureStatus', + params: [badTransactionSignature], + }, + errorResponse, + ] + ); + + expect(connection.getSignatureStatus(badTransactionSignature)) + .rejects.toThrow(errorMessage); }); + test('get transaction count', async () => { const connection = new Connection(url); @@ -341,6 +355,22 @@ test('transaction', async () => { ); expect(connection.confirmTransaction(signature)).resolves.toBe(true); + mockRpc.push([ + url, + { + method: 'getSignatureStatus', + params: [ + '3WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk' + ], + }, + { + error: null, + result: 'Confirmed', + } + ] + ); + expect(connection.getSignatureStatus(signature)).resolves.toBe('Confirmed'); + mockRpc.push([ url, {