diff --git a/packages/library-legacy/src/connection.ts b/packages/library-legacy/src/connection.ts index 50fb608798a..c3aca0a6beb 100644 --- a/packages/library-legacy/src/connection.ts +++ b/packages/library-legacy/src/connection.ts @@ -2685,8 +2685,16 @@ export type GetProgramAccountsConfig = { filters?: GetProgramAccountsFilter[]; /** The minimum slot that the request can be evaluated at */ minContextSlot?: number; + /** wrap the result in an RpcResponse JSON object */ + withContext?: boolean; }; +export type GetProgramAccountsResponse = readonly Readonly<{ + account: AccountInfo; + /** the account Pubkey as base-58 encoded string */ + pubkey: PublicKey; +}>[]; + /** * Configuration object for getParsedProgramAccounts */ @@ -3336,17 +3344,13 @@ export class Connection { /** * Fetch all the token accounts owned by the specified account * - * @return {Promise}>>>} + * @return {Promise} */ async getTokenAccountsByOwner( ownerAddress: PublicKey, filter: TokenAccountsFilter, commitmentOrConfig?: Commitment | GetTokenAccountsByOwnerConfig, - ): Promise< - RpcResponseAndContext< - Array<{pubkey: PublicKey; account: AccountInfo}> - > - > { + ): Promise> { const {commitment, config} = extractCommitmentFromConfig(commitmentOrConfig); let _args: any[] = [ownerAddress.toBase58()]; @@ -3621,10 +3625,24 @@ export class Connection { * * @return {Promise}>>} */ + async getProgramAccounts( + programId: PublicKey, + configOrCommitment?: GetProgramAccountsConfig & + Readonly<{withContext: true}>, + ): Promise>; + // eslint-disable-next-line no-dupe-class-members async getProgramAccounts( programId: PublicKey, configOrCommitment?: GetProgramAccountsConfig | Commitment, - ): Promise}>> { + ): Promise; + // eslint-disable-next-line no-dupe-class-members + async getProgramAccounts( + programId: PublicKey, + configOrCommitment?: GetProgramAccountsConfig | Commitment, + ): Promise< + | GetProgramAccountsResponse + | RpcResponseAndContext + > { const {commitment, config} = extractCommitmentFromConfig(configOrCommitment); const {encoding, ...configWithoutEncoding} = config || {}; @@ -3635,7 +3653,11 @@ export class Connection { configWithoutEncoding, ); const unsafeRes = await this._rpcRequest('getProgramAccounts', args); - const res = create(unsafeRes, jsonRpcResult(array(KeyedAccountInfoResult))); + const baseSchema = array(KeyedAccountInfoResult); + const res = + configWithoutEncoding.withContext === true + ? create(unsafeRes, jsonRpcResultAndContext(baseSchema)) + : create(unsafeRes, jsonRpcResult(baseSchema)); if ('error' in res) { throw new SolanaJSONRPCError( res.error, diff --git a/packages/library-legacy/test/connection.test.ts b/packages/library-legacy/test/connection.test.ts index e43d3a70a20..44deaf8d6c0 100644 --- a/packages/library-legacy/test/connection.test.ts +++ b/packages/library-legacy/test/connection.test.ts @@ -749,6 +749,36 @@ describe('Connection', function () { }); expect(programAccountsDoMatchFilter).to.have.length(2); } + + { + await mockRpcResponse({ + method: 'getProgramAccounts', + params: [ + programId.publicKey.toBase58(), + { + commitment: 'confirmed', + withContext: true, + }, + ], + value: { + context: { + slot: 11, + }, + value: [], + }, + }); + const programAccountsWithContext = await connection.getProgramAccounts( + programId.publicKey, + { + commitment: 'confirmed', + withContext: true, + }, + ); + expect(programAccountsWithContext).to.have.nested.property( + 'context.slot', + ); + expect(programAccountsWithContext).to.have.property('value'); + } }).timeout(30 * 1000); it('get balance', async () => {