diff --git a/web3.js/flow-typed/superstruct.js b/web3.js/flow-typed/superstruct.js index e323ea0d2c..0384daf593 100644 --- a/web3.js/flow-typed/superstruct.js +++ b/web3.js/flow-typed/superstruct.js @@ -5,6 +5,7 @@ declare module 'superstruct' { array(schema: any): any; literal(schema: any): any; tuple(schema: any): any; + pick(schema: any): any; }; declare module.exports: { diff --git a/web3.js/module.d.ts b/web3.js/module.d.ts index 7f3cbb6f30..db0cec087f 100644 --- a/web3.js/module.d.ts +++ b/web3.js/module.d.ts @@ -50,7 +50,7 @@ declare module '@solana/web3.js' { export type SignatureStatus = { slot: number; - status: SignatureSuccess | TransactionError; + err: TransactionError | null; confirmations: number | null; }; @@ -89,8 +89,8 @@ declare module '@solana/web3.js' { fee: number; preBalances: Array; postBalances: Array; - status?: SignatureSuccess | TransactionError; - }; + err: TransactionError | null; + } | null; }>; }; @@ -126,16 +126,14 @@ declare module '@solana/web3.js' { ) => void; export type SlotChangeCallback = (slotInfo: SlotInfo) => void; export type SignatureResultCallback = ( - signatureResult: SignatureSuccess | TransactionError, + signatureResult: SignatureResult, context: Context, ) => void; export type RootChangeCallback = (root: number) => void; - export type SignatureSuccess = { - Ok: null; - }; - export type TransactionError = { - Err: object; + export type TransactionError = object; + export type SignatureResult = { + err: TransactionError | null; }; export type Inflation = { diff --git a/web3.js/module.flow.js b/web3.js/module.flow.js index cb7e83aed4..7a74c17455 100644 --- a/web3.js/module.flow.js +++ b/web3.js/module.flow.js @@ -19,7 +19,7 @@ declare module '@solana/web3.js' { constructor( value: number | string | Buffer | Uint8Array | Array, ): PublicKey; - static isPublicKey(o: Object): boolean; + static isPublicKey(o: {}): boolean; static createWithSeed( fromPublicKey: PublicKey, seed: string, @@ -63,7 +63,7 @@ declare module '@solana/web3.js' { declare export type SignatureStatus = { slot: number, - status: SignatureSuccess | TransactionError, + err: TransactionError | null, confirmations: number | null, }; @@ -102,8 +102,8 @@ declare module '@solana/web3.js' { fee: number, preBalances: Array, postBalances: Array, - status: SignatureSuccess | TransactionError | null, - }, + err: TransactionError | null, + } | null, }>, }; @@ -139,16 +139,14 @@ declare module '@solana/web3.js' { ) => void; declare type SlotChangeCallback = (slotInfo: SlotInfo) => void; declare type SignatureResultCallback = ( - signatureResult: SignatureSuccess | TransactionError, + signatureResult: SignatureResult, context: Context, ) => void; declare type RootChangeCallback = (root: number) => void; - declare export type SignatureSuccess = {| - Ok: null, - |}; - declare export type TransactionError = {| - Err: Object, + declare export type TransactionError = {}; + declare export type SignatureResult = {| + err: TransactionError | null, |}; declare export type Inflation = { @@ -331,10 +329,7 @@ declare module '@solana/web3.js' { layout: typeof BufferLayout, |}; - declare export function encodeData( - type: InstructionType, - fields: Object, - ): Buffer; + declare export function encodeData(type: InstructionType, fields: {}): Buffer; // === src/transaction.js === declare export type TransactionSignature = string; diff --git a/web3.js/src/connection.js b/web3.js/src/connection.js index 8dac8c64f9..d4d0302375 100644 --- a/web3.js/src/connection.js +++ b/web3.js/src/connection.js @@ -203,13 +203,15 @@ const GetEpochScheduleResult = struct({ firstNormalSlot: 'number', }); +/** + * Transaction error or null + */ +const TransactionErrorResult = struct.union(['null', 'object']); + /** * Signature status for a transaction */ -const SignatureStatusResult = struct.union([ - struct({Ok: 'null'}), - struct({Err: 'object'}), -]); +const SignatureStatusResult = struct({err: TransactionErrorResult}); /** * Version info for a node @@ -241,8 +243,8 @@ type ConfirmedBlock = { fee: number, preBalances: Array, postBalances: Array, - status?: SignatureSuccess | TransactionError, - }, + err: {} | null, + } | null, }>, rewards: Array<{ pubkey: string, @@ -483,10 +485,10 @@ const GetSignatureStatusesRpcResult = jsonRpcResultAndContext( struct.array([ struct.union([ 'null', - struct({ + struct.pick({ slot: 'number', confirmations: struct.union(['number', 'null']), - status: SignatureStatusResult, + err: TransactionErrorResult, }), ]), ]), @@ -543,8 +545,8 @@ export const GetConfirmedBlockRpcResult = jsonRpcResult( }), meta: struct.union([ 'null', - struct({ - status: struct.union(['null', SignatureStatusResult]), + struct.pick({ + err: TransactionErrorResult, fee: 'number', preBalances: struct.array(['number']), postBalances: struct.array(['number']), @@ -685,7 +687,7 @@ type SlotSubscriptionInfo = { * Callback function for signature notifications */ export type SignatureResultCallback = ( - signatureResult: SignatureSuccess | TransactionError, + signatureResult: SignatureResult, context: Context, ) => void; @@ -712,22 +714,20 @@ type RootSubscriptionInfo = { }; /** - * Signature status: Success + * Signature result * - * @typedef {Object} SignatureSuccess + * @typedef {Object} SignatureResult */ -export type SignatureSuccess = {| - Ok: null, +export type SignatureResult = {| + err: TransactionError | null, |}; /** - * Signature status: TransactionError + * Transaction error * * @typedef {Object} TransactionError */ -export type TransactionError = {| - Err: Object, -|}; +export type TransactionError = {}; /** * Signature status @@ -735,12 +735,12 @@ export type TransactionError = {| * @typedef {Object} SignatureStatus * @property {number} slot when the transaction was processed * @property {number | null} confirmations the number of blocks that have been confirmed and voted on in the fork containing `slot` (TODO) - * @property {SignatureStatus | TransactionError} status success or error + * @property {TransactionError | null} err error, if any */ export type SignatureStatus = { slot: number, confirmations: number | null, - status: SignatureSuccess | TransactionError, + err: TransactionError | null, }; /** diff --git a/web3.js/src/util/send-and-confirm-raw-transaction.js b/web3.js/src/util/send-and-confirm-raw-transaction.js index be3b6d28d0..3d980dc6f9 100644 --- a/web3.js/src/util/send-and-confirm-raw-transaction.js +++ b/web3.js/src/util/send-and-confirm-raw-transaction.js @@ -39,7 +39,7 @@ export async function sendAndConfirmRawTransaction( } } - if (status && status.status && 'Ok' in status.status) { + if (status && !status.err) { return signature; } diff --git a/web3.js/src/util/send-and-confirm-transaction.js b/web3.js/src/util/send-and-confirm-transaction.js index aebf6996e8..b0ee04b70e 100644 --- a/web3.js/src/util/send-and-confirm-transaction.js +++ b/web3.js/src/util/send-and-confirm-transaction.js @@ -66,9 +66,16 @@ async function _sendAndConfirmTransaction( await sleep((500 * DEFAULT_TICKS_PER_SLOT) / NUM_TICKS_PER_SECOND); } - if (status && 'Ok' in status.status) { - break; + if (status) { + if (!status.err) { + break; + } else if (!('AccountInUse' in status.err)) { + throw new Error( + `Transaction ${signature} failed (${JSON.stringify(status)})`, + ); + } } + if (--sendRetries <= 0) { const duration = (Date.now() - start) / 1000; throw new Error( @@ -78,12 +85,6 @@ async function _sendAndConfirmTransaction( ); } - if (status && status.status.Err && !('AccountInUse' in status.status.Err)) { - throw new Error( - `Transaction ${signature} failed (${JSON.stringify(status)})`, - ); - } - // Retry in 0..100ms to try to avoid another AccountInUse collision await sleep(Math.random() * 100); } diff --git a/web3.js/test/connection.test.js b/web3.js/test/connection.test.js index 2a7f8aeb5a..b6c3080cc2 100644 --- a/web3.js/test/connection.test.js +++ b/web3.js/test/connection.test.js @@ -117,6 +117,7 @@ test('get program accounts', async () => { slot: 0, confirmations: 11, status: {Ok: null}, + err: null, }, ], }, @@ -161,6 +162,7 @@ test('get program accounts', async () => { slot: 0, confirmations: 11, status: {Ok: null}, + err: null, }, ], }, @@ -627,6 +629,7 @@ test('get confirmed block', async () => { postBalances: [499260347380, 15298080, 1, 1, 1], preBalances: [499260357380, 15298080, 1, 1, 1], status: {Ok: null}, + err: null, }, transaction: { message: { @@ -906,6 +909,7 @@ test('request airdrop - max commitment', async () => { slot: 0, confirmations: null, status: {Ok: null}, + err: null, }, ], }, @@ -1100,6 +1104,7 @@ test('transaction', async () => { slot: 0, confirmations: 11, status: {Ok: null}, + err: null, }, ], }, @@ -1118,7 +1123,7 @@ test('transaction', async () => { return; } - expect(response.status).toEqual({Ok: null}); + expect(response.err).toBeNull(); expect(response.slot).toBeGreaterThanOrEqual(0); expect(responseConfirmations).toBeGreaterThan(0); @@ -1147,6 +1152,7 @@ test('transaction', async () => { slot: 0, confirmations: 11, status: {Ok: null}, + err: null, }, null, ], @@ -1168,7 +1174,7 @@ test('transaction', async () => { } expect(firstResponse.slot).toBeGreaterThanOrEqual(response.slot); - expect(firstResponse.status).toEqual(response.status); + expect(firstResponse.err).toEqual(response.err); if (typeof firstResponse.confirmations !== 'number') { expect(typeof firstResponse.confirmations).toEqual('number'); @@ -1279,7 +1285,7 @@ test('multi-instruction transaction', async () => { const response = (await connection.getSignatureStatus(signature)).value; if (response !== null) { expect(typeof response.slot).toEqual('number'); - expect(response.status).toEqual({Ok: null}); + expect(response.err).toBeNull(); } else { expect(response).not.toBeNull(); } diff --git a/web3.js/test/get-confirmed-block.test.js b/web3.js/test/get-confirmed-block.test.js index 60c890e0a9..4031476b8b 100644 --- a/web3.js/test/get-confirmed-block.test.js +++ b/web3.js/test/get-confirmed-block.test.js @@ -39,7 +39,8 @@ test('verify getConfirmedBlock', () => { fee: 0, preBalances: [100000, 100000, 1, 1, 1], postBalances: [99877, 100123, 1, 1, 1], - status: {Ok: 'null'}, + status: {Ok: null}, + err: null, }, }, { @@ -48,7 +49,8 @@ test('verify getConfirmedBlock', () => { fee: 0, preBalances: [100000, 100000, 1, 1, 1], postBalances: [99544, 100456, 1, 1, 1], - status: {Ok: 'null'}, + status: {Ok: null}, + err: null, }, }, ], diff --git a/web3.js/test/transaction-payer.test.js b/web3.js/test/transaction-payer.test.js index 8bf5037d6d..629d87e79c 100644 --- a/web3.js/test/transaction-payer.test.js +++ b/web3.js/test/transaction-payer.test.js @@ -165,6 +165,7 @@ test('transaction-payer', async () => { slot: 0, confirmations: 11, status: {Ok: null}, + err: null, }, ], }, @@ -173,7 +174,7 @@ test('transaction-payer', async () => { const {value} = await connection.getSignatureStatus(signature); if (value !== null) { expect(typeof value.slot).toEqual('number'); - expect(value.status).toEqual({Ok: null}); + expect(value.err).toBeNull(); } else { expect(value).not.toBeNull(); }