feat: add getConfirmedTransaction and getConfirmedSignaturesForAddress
This commit is contained in:
		
				
					committed by
					
						 Michael Vines
						Michael Vines
					
				
			
			
				
	
			
			
			
						parent
						
							7f182d22cd
						
					
				
				
					commit
					ae53742e1a
				
			
							
								
								
									
										19
									
								
								web3.js/module.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								web3.js/module.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -98,6 +98,17 @@ declare module '@solana/web3.js' { | ||||
|     }>; | ||||
|   }; | ||||
|  | ||||
|   export type ConfirmedTransaction = { | ||||
|     slot: number; | ||||
|     transaction: Transaction; | ||||
|     meta: { | ||||
|       fee: number; | ||||
|       preBalances: Array<number>; | ||||
|       postBalances: Array<number>; | ||||
|       err: TransactionError | null; | ||||
|     } | null; | ||||
|   }; | ||||
|  | ||||
|   export type KeyedAccountInfo = { | ||||
|     accountId: PublicKey; | ||||
|     accountInfo: AccountInfo; | ||||
| @@ -184,6 +195,14 @@ declare module '@solana/web3.js' { | ||||
|     getBalance(publicKey: PublicKey, commitment?: Commitment): Promise<number>; | ||||
|     getClusterNodes(): Promise<Array<ContactInfo>>; | ||||
|     getConfirmedBlock(slot: number): Promise<ConfirmedBlock>; | ||||
|     getConfirmedTransaction( | ||||
|       signature: TransactionSignature, | ||||
|     ): Promise<ConfirmedTransaction | null>; | ||||
|     getConfirmedSignaturesForAddress( | ||||
|       address: PublicKey, | ||||
|       startSlot: number, | ||||
|       endSlot: number, | ||||
|     ): Promise<Array<TransactionSignature>>; | ||||
|     getVoteAccounts(commitment?: Commitment): Promise<VoteAccountStatus>; | ||||
|     confirmTransactionAndContext( | ||||
|       signature: TransactionSignature, | ||||
|   | ||||
| @@ -111,6 +111,17 @@ declare module '@solana/web3.js' { | ||||
|     }>, | ||||
|   }; | ||||
|  | ||||
|   declare export type ConfirmedTransaction = { | ||||
|     slot: number, | ||||
|     transaction: Transaction, | ||||
|     meta: { | ||||
|       fee: number, | ||||
|       preBalances: Array<number>, | ||||
|       postBalances: Array<number>, | ||||
|       err: TransactionError | null, | ||||
|     } | null, | ||||
|   }; | ||||
|  | ||||
|   declare export type KeyedAccountInfo = { | ||||
|     accountId: PublicKey, | ||||
|     accountInfo: AccountInfo, | ||||
| @@ -197,6 +208,14 @@ declare module '@solana/web3.js' { | ||||
|     getBalance(publicKey: PublicKey, commitment: ?Commitment): Promise<number>; | ||||
|     getClusterNodes(): Promise<Array<ContactInfo>>; | ||||
|     getConfirmedBlock(slot: number): Promise<ConfirmedBlock>; | ||||
|     getConfirmedTransaction( | ||||
|       signature: TransactionSignature, | ||||
|     ): Promise<ConfirmedTransaction | null>; | ||||
|     getConfirmedSignaturesForAddress( | ||||
|       address: PublicKey, | ||||
|       startSlot: number, | ||||
|       endSlot: number, | ||||
|     ): Promise<Array<TransactionSignature>>; | ||||
|     getVoteAccounts(commitment: ?Commitment): Promise<VoteAccountStatus>; | ||||
|     confirmTransactionAndContext( | ||||
|       signature: TransactionSignature, | ||||
|   | ||||
| @@ -233,6 +233,25 @@ const Version = struct({ | ||||
|   'solana-core': 'string', | ||||
| }); | ||||
|  | ||||
| /** | ||||
|  * A confirmed transaction on the ledger | ||||
|  * | ||||
|  * @typedef {Object} ConfirmedTransaction | ||||
|  * @property {number} slot The slot during which the transaction was processed | ||||
|  * @property {Transaction} transaction The details of the transaction | ||||
|  * @property {object} meta Slot index of this block's parent | ||||
|  */ | ||||
| type ConfirmedTransaction = { | ||||
|   slot: number, | ||||
|   transaction: Transaction, | ||||
|   meta: { | ||||
|     fee: number, | ||||
|     err: TransactionError | null, | ||||
|     preBalances: Array<number>, | ||||
|     postBalances: Array<number>, | ||||
|   } | null, | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * A ConfirmedBlock on the ledger | ||||
|  * | ||||
| @@ -357,6 +376,13 @@ const GetAccountInfoAndContextRpcResult = jsonRpcResultAndContext( | ||||
|   struct.union(['null', AccountInfoResult]), | ||||
| ); | ||||
|  | ||||
| /** | ||||
|  * @private | ||||
|  */ | ||||
| const GetConfirmedSignaturesForAddressRpcResult = jsonRpcResult( | ||||
|   struct.array(['string']), | ||||
| ); | ||||
|  | ||||
| /*** | ||||
|  * Expected JSON RPC response for the "accountNotification" message | ||||
|  */ | ||||
| @@ -519,6 +545,45 @@ const GetTotalSupplyRpcResult = jsonRpcResult('number'); | ||||
|  */ | ||||
| const GetMinimumBalanceForRentExemptionRpcResult = jsonRpcResult('number'); | ||||
|  | ||||
| /** | ||||
|  * @private | ||||
|  */ | ||||
| const ConfirmedTransactionResult = struct({ | ||||
|   signatures: struct.array(['string']), | ||||
|   message: struct({ | ||||
|     accountKeys: struct.array(['string']), | ||||
|     header: struct({ | ||||
|       numRequiredSignatures: 'number', | ||||
|       numReadonlySignedAccounts: 'number', | ||||
|       numReadonlyUnsignedAccounts: 'number', | ||||
|     }), | ||||
|     instructions: struct.array([ | ||||
|       struct.union([ | ||||
|         struct.array(['number']), | ||||
|         struct({ | ||||
|           accounts: struct.array(['number']), | ||||
|           data: 'string', | ||||
|           programIdIndex: 'number', | ||||
|         }), | ||||
|       ]), | ||||
|     ]), | ||||
|     recentBlockhash: 'string', | ||||
|   }), | ||||
| }); | ||||
|  | ||||
| /** | ||||
|  * @private | ||||
|  */ | ||||
| const ConfirmedTransactionMetaResult = struct.union([ | ||||
|   'null', | ||||
|   struct.pick({ | ||||
|     err: TransactionErrorResult, | ||||
|     fee: 'number', | ||||
|     preBalances: struct.array(['number']), | ||||
|     postBalances: struct.array(['number']), | ||||
|   }), | ||||
| ]); | ||||
|  | ||||
| /** | ||||
|  * Expected JSON RPC response for the "getConfirmedBlock" message | ||||
|  */ | ||||
| @@ -531,37 +596,8 @@ export const GetConfirmedBlockRpcResult = jsonRpcResult( | ||||
|       parentSlot: 'number', | ||||
|       transactions: struct.array([ | ||||
|         struct({ | ||||
|           transaction: struct({ | ||||
|             signatures: struct.array(['string']), | ||||
|             message: struct({ | ||||
|               accountKeys: struct.array(['string']), | ||||
|               header: struct({ | ||||
|                 numRequiredSignatures: 'number', | ||||
|                 numReadonlySignedAccounts: 'number', | ||||
|                 numReadonlyUnsignedAccounts: 'number', | ||||
|               }), | ||||
|               instructions: struct.array([ | ||||
|                 struct.union([ | ||||
|                   struct.array(['number']), | ||||
|                   struct({ | ||||
|                     accounts: struct.array(['number']), | ||||
|                     data: 'string', | ||||
|                     programIdIndex: 'number', | ||||
|                   }), | ||||
|                 ]), | ||||
|               ]), | ||||
|               recentBlockhash: 'string', | ||||
|             }), | ||||
|           }), | ||||
|           meta: struct.union([ | ||||
|             'null', | ||||
|             struct.pick({ | ||||
|               err: TransactionErrorResult, | ||||
|               fee: 'number', | ||||
|               preBalances: struct.array(['number']), | ||||
|               postBalances: struct.array(['number']), | ||||
|             }), | ||||
|           ]), | ||||
|           transaction: ConfirmedTransactionResult, | ||||
|           meta: ConfirmedTransactionMetaResult, | ||||
|         }), | ||||
|       ]), | ||||
|       rewards: struct.union([ | ||||
| @@ -577,6 +613,20 @@ export const GetConfirmedBlockRpcResult = jsonRpcResult( | ||||
|   ]), | ||||
| ); | ||||
|  | ||||
| /** | ||||
|  * Expected JSON RPC response for the "getConfirmedTransaction" message | ||||
|  */ | ||||
| const GetConfirmedTransactionRpcResult = jsonRpcResult( | ||||
|   struct.union([ | ||||
|     'null', | ||||
|     struct({ | ||||
|       slot: 'number', | ||||
|       transaction: ConfirmedTransactionResult, | ||||
|       meta: ConfirmedTransactionMetaResult, | ||||
|     }), | ||||
|   ]), | ||||
| ); | ||||
|  | ||||
| /** | ||||
|  * Expected JSON RPC response for the "getRecentBlockhash" message | ||||
|  */ | ||||
| @@ -1266,6 +1316,59 @@ export class Connection { | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Fetch a transaction details for a confirmed transaction | ||||
|    */ | ||||
|   async getConfirmedTransaction( | ||||
|     signature: TransactionSignature, | ||||
|   ): Promise<ConfirmedTransaction | null> { | ||||
|     const unsafeRes = await this._rpcRequest('getConfirmedTransaction', [ | ||||
|       signature, | ||||
|     ]); | ||||
|     const {result, error} = GetConfirmedTransactionRpcResult(unsafeRes); | ||||
|     if (error) { | ||||
|       throw new Error('failed to get confirmed transaction: ' + error.message); | ||||
|     } | ||||
|     assert(typeof result !== 'undefined'); | ||||
|     if (result === null) { | ||||
|       return result; | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|       slot: result.slot, | ||||
|       transaction: Transaction.fromRpcResult(result.transaction), | ||||
|       meta: result.meta, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Fetch a list of all the confirmed signatures for transactions involving an address | ||||
|    * within a specified slot range. Max range allowed is 10,000 slots. | ||||
|    * | ||||
|    * @param address queried address | ||||
|    * @param startSlot start slot, inclusive | ||||
|    * @param endSlot end slot, inclusive | ||||
|    */ | ||||
|   async getConfirmedSignaturesForAddress( | ||||
|     address: PublicKey, | ||||
|     startSlot: number, | ||||
|     endSlot: number, | ||||
|   ): Promise<Array<TransactionSignature>> { | ||||
|     const unsafeRes = await this._rpcRequest( | ||||
|       'getConfirmedSignaturesForAddress', | ||||
|       [address.toBase58(), startSlot, endSlot], | ||||
|     ); | ||||
|     const result = GetConfirmedSignaturesForAddressRpcResult(unsafeRes); | ||||
|     if (result.error) { | ||||
|       throw new Error( | ||||
|         'failed to get confirmed signatures for address: ' + | ||||
|           result.error.message, | ||||
|       ); | ||||
|     } | ||||
|     assert(typeof result.result !== 'undefined'); | ||||
|     return result.result; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Fetch the contents of a Nonce account from the cluster, return with context | ||||
|    */ | ||||
|   | ||||
| @@ -1,10 +1,13 @@ | ||||
| // @flow | ||||
| import bs58 from 'bs58'; | ||||
|  | ||||
| import { | ||||
|   Account, | ||||
|   Connection, | ||||
|   SystemProgram, | ||||
|   sendAndConfirmTransaction, | ||||
|   LAMPORTS_PER_SOL, | ||||
|   PublicKey, | ||||
| } from '../src'; | ||||
| import {DEFAULT_TICKS_PER_SLOT, NUM_TICKS_PER_SECOND} from '../src/timing'; | ||||
| import {mockRpc, mockRpcEnabled} from './__mocks__/node-fetch'; | ||||
| @@ -570,6 +573,331 @@ test('get minimum balance for rent exemption', async () => { | ||||
|   expect(count).toBeGreaterThanOrEqual(0); | ||||
| }); | ||||
|  | ||||
| test('get confirmed signatures for address', async () => { | ||||
|   const connection = new Connection(url); | ||||
|  | ||||
|   mockRpc.push([ | ||||
|     url, | ||||
|     { | ||||
|       method: 'getSlot', | ||||
|       params: [], | ||||
|     }, | ||||
|     { | ||||
|       error: null, | ||||
|       result: 1, | ||||
|     }, | ||||
|   ]); | ||||
|  | ||||
|   while ((await connection.getSlot()) <= 0) { | ||||
|     continue; | ||||
|   } | ||||
|  | ||||
|   mockRpc.push([ | ||||
|     url, | ||||
|     { | ||||
|       method: 'getConfirmedBlock', | ||||
|       params: [1], | ||||
|     }, | ||||
|     { | ||||
|       error: null, | ||||
|       result: { | ||||
|         blockhash: '57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy', | ||||
|         previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo', | ||||
|         parentSlot: 0, | ||||
|         transactions: [ | ||||
|           { | ||||
|             meta: { | ||||
|               fee: 10000, | ||||
|               postBalances: [499260347380, 15298080, 1, 1, 1], | ||||
|               preBalances: [499260357380, 15298080, 1, 1, 1], | ||||
|               status: {Ok: null}, | ||||
|               err: null, | ||||
|             }, | ||||
|             transaction: { | ||||
|               message: { | ||||
|                 accountKeys: [ | ||||
|                   'va12u4o9DipLEB2z4fuoHszroq1U9NcAB9aooFDPJSf', | ||||
|                   '57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy', | ||||
|                   'SysvarS1otHashes111111111111111111111111111', | ||||
|                   'SysvarC1ock11111111111111111111111111111111', | ||||
|                   'Vote111111111111111111111111111111111111111', | ||||
|                 ], | ||||
|                 header: { | ||||
|                   numReadonlySignedAccounts: 0, | ||||
|                   numReadonlyUnsignedAccounts: 3, | ||||
|                   numRequiredSignatures: 2, | ||||
|                 }, | ||||
|                 instructions: [ | ||||
|                   { | ||||
|                     accounts: [1, 2, 3], | ||||
|                     data: | ||||
|                       '37u9WtQpcm6ULa3VtWDFAWoQc1hUvybPrA3dtx99tgHvvcE7pKRZjuGmn7VX2tC3JmYDYGG7', | ||||
|                     programIdIndex: 4, | ||||
|                   }, | ||||
|                 ], | ||||
|                 recentBlockhash: 'GeyAFFRY3WGpmam2hbgrKw4rbU2RKzfVLm5QLSeZwTZE', | ||||
|               }, | ||||
|               signatures: [ | ||||
|                 'w2Zeq8YkpyB463DttvfzARD7k9ZxGEwbsEw4boEK7jDp3pfoxZbTdLFSsEPhzXhpCcjGi2kHtHFobgX49MMhbWt', | ||||
|                 '4oCEqwGrMdBeMxpzuWiukCYqSfV4DsSKXSiVVCh1iJ6pS772X7y219JZP3mgqBz5PhsvprpKyhzChjYc3VSBQXzG', | ||||
|               ], | ||||
|             }, | ||||
|           }, | ||||
|         ], | ||||
|       }, | ||||
|     }, | ||||
|   ]); | ||||
|  | ||||
|   // Find a block that has a transaction, usually Block 1 | ||||
|   let slot = 0; | ||||
|   let address: ?PublicKey; | ||||
|   let expectedSignature: ?string; | ||||
|   while (!address || !expectedSignature) { | ||||
|     slot++; | ||||
|     const block = await connection.getConfirmedBlock(slot); | ||||
|     if (block.transactions.length > 0) { | ||||
|       const { | ||||
|         signature, | ||||
|         publicKey, | ||||
|       } = block.transactions[0].transaction.signatures[0]; | ||||
|       if (signature) { | ||||
|         address = publicKey; | ||||
|         expectedSignature = bs58.encode(signature); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   mockRpc.push([ | ||||
|     url, | ||||
|     { | ||||
|       method: 'getConfirmedSignaturesForAddress', | ||||
|       params: [address.toBase58(), slot, slot + 1], | ||||
|     }, | ||||
|     { | ||||
|       error: null, | ||||
|       result: [expectedSignature], | ||||
|     }, | ||||
|   ]); | ||||
|  | ||||
|   const confirmedSignatures = await connection.getConfirmedSignaturesForAddress( | ||||
|     address, | ||||
|     slot, | ||||
|     slot + 1, | ||||
|   ); | ||||
|   expect(confirmedSignatures.includes(expectedSignature)).toBe(true); | ||||
|  | ||||
|   const badSlot = Number.MAX_SAFE_INTEGER - 1; | ||||
|   mockRpc.push([ | ||||
|     url, | ||||
|     { | ||||
|       method: 'getConfirmedSignaturesForAddress', | ||||
|       params: [address.toBase58(), badSlot, badSlot + 1], | ||||
|     }, | ||||
|     { | ||||
|       error: null, | ||||
|       result: [], | ||||
|     }, | ||||
|   ]); | ||||
|  | ||||
|   const emptySignatures = await connection.getConfirmedSignaturesForAddress( | ||||
|     address, | ||||
|     badSlot, | ||||
|     badSlot + 1, | ||||
|   ); | ||||
|   expect(emptySignatures.length).toBe(0); | ||||
| }); | ||||
|  | ||||
| test('get confirmed transaction', async () => { | ||||
|   const connection = new Connection(url); | ||||
|  | ||||
|   mockRpc.push([ | ||||
|     url, | ||||
|     { | ||||
|       method: 'getSlot', | ||||
|       params: [], | ||||
|     }, | ||||
|     { | ||||
|       error: null, | ||||
|       result: 1, | ||||
|     }, | ||||
|   ]); | ||||
|  | ||||
|   while ((await connection.getSlot()) <= 0) { | ||||
|     continue; | ||||
|   } | ||||
|  | ||||
|   mockRpc.push([ | ||||
|     url, | ||||
|     { | ||||
|       method: 'getConfirmedBlock', | ||||
|       params: [1], | ||||
|     }, | ||||
|     { | ||||
|       error: null, | ||||
|       result: { | ||||
|         blockhash: '57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy', | ||||
|         previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo', | ||||
|         parentSlot: 0, | ||||
|         transactions: [ | ||||
|           { | ||||
|             meta: { | ||||
|               fee: 10000, | ||||
|               postBalances: [499260347380, 15298080, 1, 1, 1], | ||||
|               preBalances: [499260357380, 15298080, 1, 1, 1], | ||||
|               status: {Ok: null}, | ||||
|               err: null, | ||||
|             }, | ||||
|             transaction: { | ||||
|               message: { | ||||
|                 accountKeys: [ | ||||
|                   'va12u4o9DipLEB2z4fuoHszroq1U9NcAB9aooFDPJSf', | ||||
|                   '57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy', | ||||
|                   'SysvarS1otHashes111111111111111111111111111', | ||||
|                   'SysvarC1ock11111111111111111111111111111111', | ||||
|                   'Vote111111111111111111111111111111111111111', | ||||
|                 ], | ||||
|                 header: { | ||||
|                   numReadonlySignedAccounts: 0, | ||||
|                   numReadonlyUnsignedAccounts: 3, | ||||
|                   numRequiredSignatures: 2, | ||||
|                 }, | ||||
|                 instructions: [ | ||||
|                   { | ||||
|                     accounts: [1, 2, 3], | ||||
|                     data: | ||||
|                       '37u9WtQpcm6ULa3VtWDFAWoQc1hUvybPrA3dtx99tgHvvcE7pKRZjuGmn7VX2tC3JmYDYGG7', | ||||
|                     programIdIndex: 4, | ||||
|                   }, | ||||
|                 ], | ||||
|                 recentBlockhash: 'GeyAFFRY3WGpmam2hbgrKw4rbU2RKzfVLm5QLSeZwTZE', | ||||
|               }, | ||||
|               signatures: [ | ||||
|                 'w2Zeq8YkpyB463DttvfzARD7k9ZxGEwbsEw4boEK7jDp3pfoxZbTdLFSsEPhzXhpCcjGi2kHtHFobgX49MMhbWt', | ||||
|                 '4oCEqwGrMdBeMxpzuWiukCYqSfV4DsSKXSiVVCh1iJ6pS772X7y219JZP3mgqBz5PhsvprpKyhzChjYc3VSBQXzG', | ||||
|               ], | ||||
|             }, | ||||
|           }, | ||||
|         ], | ||||
|       }, | ||||
|     }, | ||||
|   ]); | ||||
|  | ||||
|   // Find a block that has a transaction, usually Block 1 | ||||
|   let slot = 0; | ||||
|   let confirmedTransaction: ?string; | ||||
|   while (!confirmedTransaction) { | ||||
|     slot++; | ||||
|     const block = await connection.getConfirmedBlock(slot); | ||||
|     for (const tx of block.transactions) { | ||||
|       if (tx.transaction.signature) { | ||||
|         confirmedTransaction = bs58.encode(tx.transaction.signature); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   mockRpc.push([ | ||||
|     url, | ||||
|     { | ||||
|       method: 'getConfirmedTransaction', | ||||
|       params: [confirmedTransaction], | ||||
|     }, | ||||
|     { | ||||
|       error: null, | ||||
|       result: { | ||||
|         slot, | ||||
|         transaction: { | ||||
|           message: { | ||||
|             accountKeys: [ | ||||
|               'va12u4o9DipLEB2z4fuoHszroq1U9NcAB9aooFDPJSf', | ||||
|               '57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy', | ||||
|               'SysvarS1otHashes111111111111111111111111111', | ||||
|               'SysvarC1ock11111111111111111111111111111111', | ||||
|               'Vote111111111111111111111111111111111111111', | ||||
|             ], | ||||
|             header: { | ||||
|               numReadonlySignedAccounts: 0, | ||||
|               numReadonlyUnsignedAccounts: 3, | ||||
|               numRequiredSignatures: 2, | ||||
|             }, | ||||
|             instructions: [ | ||||
|               { | ||||
|                 accounts: [1, 2, 3], | ||||
|                 data: | ||||
|                   '37u9WtQpcm6ULa3VtWDFAWoQc1hUvybPrA3dtx99tgHvvcE7pKRZjuGmn7VX2tC3JmYDYGG7', | ||||
|                 programIdIndex: 4, | ||||
|               }, | ||||
|             ], | ||||
|             recentBlockhash: 'GeyAFFRY3WGpmam2hbgrKw4rbU2RKzfVLm5QLSeZwTZE', | ||||
|           }, | ||||
|           signatures: [ | ||||
|             'w2Zeq8YkpyB463DttvfzARD7k9ZxGEwbsEw4boEK7jDp3pfoxZbTdLFSsEPhzXhpCcjGi2kHtHFobgX49MMhbWt', | ||||
|             '4oCEqwGrMdBeMxpzuWiukCYqSfV4DsSKXSiVVCh1iJ6pS772X7y219JZP3mgqBz5PhsvprpKyhzChjYc3VSBQXzG', | ||||
|           ], | ||||
|         }, | ||||
|         meta: { | ||||
|           fee: 10000, | ||||
|           postBalances: [499260347380, 15298080, 1, 1, 1], | ||||
|           preBalances: [499260357380, 15298080, 1, 1, 1], | ||||
|           status: {Ok: null}, | ||||
|           err: null, | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|   ]); | ||||
|  | ||||
|   const result = await connection.getConfirmedTransaction(confirmedTransaction); | ||||
|  | ||||
|   if (!result) { | ||||
|     expect(result).toBeDefined(); | ||||
|     expect(result).not.toBeNull(); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   if (result.transaction.signature === null) { | ||||
|     expect(result.transaction.signature).not.toBeNull(); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   const resultSignature = bs58.encode(result.transaction.signature); | ||||
|   expect(resultSignature).toEqual(confirmedTransaction); | ||||
|  | ||||
|   const newAddress = new Account().publicKey; | ||||
|   mockRpc.push([ | ||||
|     url, | ||||
|     { | ||||
|       method: 'requestAirdrop', | ||||
|       params: [newAddress.toBase58(), 1, {commitment: 'recent'}], | ||||
|     }, | ||||
|     { | ||||
|       error: null, | ||||
|       result: | ||||
|         '1WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk', | ||||
|     }, | ||||
|   ]); | ||||
|  | ||||
|   const recentSignature = await connection.requestAirdrop( | ||||
|     newAddress, | ||||
|     1, | ||||
|     'recent', | ||||
|   ); | ||||
|   mockRpc.push([ | ||||
|     url, | ||||
|     { | ||||
|       method: 'getConfirmedTransaction', | ||||
|       params: [recentSignature], | ||||
|     }, | ||||
|     { | ||||
|       error: null, | ||||
|       result: null, | ||||
|     }, | ||||
|   ]); | ||||
|  | ||||
|   const nullResponse = await connection.getConfirmedTransaction( | ||||
|     recentSignature, | ||||
|   ); | ||||
|   expect(nullResponse).toBeNull(); | ||||
| }); | ||||
|  | ||||
| test('get confirmed block', async () => { | ||||
|   const connection = new Connection(url); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user