Skip to content

Commit

Permalink
feat: add withContext flag to getProgramAccounts (#1311)
Browse files Browse the repository at this point in the history
## Summary

This was missing. When supplied, the RPC wraps the result in a context object.

Fixes #1285.

## Test Plan

```
pnpm test:live-with-test-validator
pnpm test:unit:node
```
  • Loading branch information
steveluscher authored May 24, 2023
1 parent 20e2b21 commit d2e0117
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 8 deletions.
38 changes: 30 additions & 8 deletions packages/library-legacy/src/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<Buffer>;
/** the account Pubkey as base-58 encoded string */
pubkey: PublicKey;
}>[];

/**
* Configuration object for getParsedProgramAccounts
*/
Expand Down Expand Up @@ -3336,17 +3344,13 @@ export class Connection {
/**
* Fetch all the token accounts owned by the specified account
*
* @return {Promise<RpcResponseAndContext<Array<{pubkey: PublicKey, account: AccountInfo<Buffer>}>>>}
* @return {Promise<RpcResponseAndContext<GetProgramAccountsResponse>}
*/
async getTokenAccountsByOwner(
ownerAddress: PublicKey,
filter: TokenAccountsFilter,
commitmentOrConfig?: Commitment | GetTokenAccountsByOwnerConfig,
): Promise<
RpcResponseAndContext<
Array<{pubkey: PublicKey; account: AccountInfo<Buffer>}>
>
> {
): Promise<RpcResponseAndContext<GetProgramAccountsResponse>> {
const {commitment, config} =
extractCommitmentFromConfig(commitmentOrConfig);
let _args: any[] = [ownerAddress.toBase58()];
Expand Down Expand Up @@ -3621,10 +3625,24 @@ export class Connection {
*
* @return {Promise<Array<{pubkey: PublicKey, account: AccountInfo<Buffer>}>>}
*/
async getProgramAccounts(
programId: PublicKey,
configOrCommitment?: GetProgramAccountsConfig &
Readonly<{withContext: true}>,
): Promise<RpcResponseAndContext<GetProgramAccountsResponse>>;
// eslint-disable-next-line no-dupe-class-members
async getProgramAccounts(
programId: PublicKey,
configOrCommitment?: GetProgramAccountsConfig | Commitment,
): Promise<Array<{pubkey: PublicKey; account: AccountInfo<Buffer>}>> {
): Promise<GetProgramAccountsResponse>;
// eslint-disable-next-line no-dupe-class-members
async getProgramAccounts(
programId: PublicKey,
configOrCommitment?: GetProgramAccountsConfig | Commitment,
): Promise<
| GetProgramAccountsResponse
| RpcResponseAndContext<GetProgramAccountsResponse>
> {
const {commitment, config} =
extractCommitmentFromConfig(configOrCommitment);
const {encoding, ...configWithoutEncoding} = config || {};
Expand All @@ -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,
Expand Down
30 changes: 30 additions & 0 deletions packages/library-legacy/test/connection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand Down

0 comments on commit d2e0117

Please sign in to comment.