feat: add getLargestAccounts rpc api
This commit is contained in:
parent
9c677c7d3d
commit
1b8fe71230
|
@ -48,6 +48,13 @@ declare module '@solana/web3.js' {
|
|||
|
||||
export type Commitment = 'max' | 'recent' | 'root' | 'single';
|
||||
|
||||
export type LargestAccountsFilter = 'circulating' | 'nonCirculating';
|
||||
|
||||
export type GetLargestAccountsConfig = {
|
||||
commitment?: Commitment;
|
||||
filter?: LargestAccountsFilter;
|
||||
};
|
||||
|
||||
export type SignatureStatusConfig = {
|
||||
searchTransactionHistory: boolean;
|
||||
};
|
||||
|
@ -180,6 +187,11 @@ declare module '@solana/web3.js' {
|
|||
nonCirculatingAccounts: Array<PublicKey>;
|
||||
};
|
||||
|
||||
export type AccountBalancePair = {
|
||||
address: PublicKey;
|
||||
lamports: number;
|
||||
};
|
||||
|
||||
export type VoteAccountStatus = {
|
||||
current: Array<VoteAccountInfo>;
|
||||
delinquent: Array<VoteAccountInfo>;
|
||||
|
@ -208,6 +220,9 @@ declare module '@solana/web3.js' {
|
|||
getBlockTime(slot: number): Promise<number | null>;
|
||||
getMinimumLedgerSlot(): Promise<number>;
|
||||
getSupply(commitment?: Commitment): Promise<RpcResponseAndContext<Supply>>;
|
||||
getLargestAccounts(
|
||||
config?: GetLargestAccountsConfig,
|
||||
): Promise<RpcResponseAndContext<Array<AccountBalancePair>>>;
|
||||
getClusterNodes(): Promise<Array<ContactInfo>>;
|
||||
getConfirmedBlock(slot: number): Promise<ConfirmedBlock>;
|
||||
getConfirmedTransaction(
|
||||
|
|
|
@ -61,6 +61,13 @@ declare module '@solana/web3.js' {
|
|||
|
||||
declare export type Commitment = 'max' | 'recent' | 'root' | 'single';
|
||||
|
||||
declare export type LargestAccountsFilter = 'circulating' | 'nonCirculating';
|
||||
|
||||
declare export type GetLargestAccountsConfig = {
|
||||
commitment: ?Commitment,
|
||||
filter: ?LargestAccountsFilter,
|
||||
};
|
||||
|
||||
declare export type SignatureStatusConfig = {
|
||||
searchTransactionHistory: boolean,
|
||||
};
|
||||
|
@ -193,6 +200,11 @@ declare module '@solana/web3.js' {
|
|||
nonCirculatingAccounts: Array<PublicKey>,
|
||||
};
|
||||
|
||||
declare export type AccountBalancePair = {
|
||||
address: PublicKey,
|
||||
lamports: number,
|
||||
};
|
||||
|
||||
declare export type VoteAccountStatus = {
|
||||
current: Array<VoteAccountInfo>,
|
||||
delinquent: Array<VoteAccountInfo>,
|
||||
|
@ -221,6 +233,9 @@ declare module '@solana/web3.js' {
|
|||
getBlockTime(slot: number): Promise<number | null>;
|
||||
getMinimumLedgerSlot(): Promise<number>;
|
||||
getSupply(commitment: ?Commitment): Promise<RpcResponseAndContext<Supply>>;
|
||||
getLargestAccounts(
|
||||
config: ?GetLargestAccountsConfig,
|
||||
): Promise<RpcResponseAndContext<Array<AccountBalancePair>>>;
|
||||
getClusterNodes(): Promise<Array<ContactInfo>>;
|
||||
getConfirmedBlock(slot: number): Promise<ConfirmedBlock>;
|
||||
getConfirmedTransaction(
|
||||
|
|
|
@ -100,6 +100,29 @@ function notificationResultAndContext(resultDescription: any) {
|
|||
*/
|
||||
export type Commitment = 'max' | 'recent' | 'root' | 'single';
|
||||
|
||||
/**
|
||||
* Filter for largest accounts query
|
||||
* <pre>
|
||||
* 'circulating': Return the largest accounts that are part of the circulating supply
|
||||
* 'nonCirculating': Return the largest accounts that are not part of the circulating supply
|
||||
* </pre>
|
||||
*
|
||||
* @typedef {'circulating' | 'nonCirculating'} LargestAccountsFilter
|
||||
*/
|
||||
export type LargestAccountsFilter = 'circulating' | 'nonCirculating';
|
||||
|
||||
/**
|
||||
* Configuration object for changing `getLargestAccounts` query behavior
|
||||
*
|
||||
* @typedef {Object} GetLargestAccountsConfig
|
||||
* @property {Commitment|undefined} commitment The level of commitment desired
|
||||
* @property {LargestAccountsFilter|undefined} filter Filter largest accounts by whether they are part of the circulating supply
|
||||
*/
|
||||
type GetLargestAccountsConfig = {
|
||||
commitment: ?Commitment,
|
||||
filter: ?LargestAccountsFilter,
|
||||
};
|
||||
|
||||
/**
|
||||
* Configuration object for changing query behavior
|
||||
*
|
||||
|
@ -431,6 +454,30 @@ const GetSupplyRpcResult = jsonRpcResultAndContext(
|
|||
}),
|
||||
);
|
||||
|
||||
/**
|
||||
* Pair of an account address and its balance
|
||||
*
|
||||
* @typedef {Object} AccountBalancePair
|
||||
* @property {PublicKey} address
|
||||
* @property {number} lamports
|
||||
*/
|
||||
type AccountBalancePair = {
|
||||
address: PublicKey,
|
||||
lamports: number,
|
||||
};
|
||||
|
||||
/**
|
||||
* Expected JSON RPC response for the "getLargestAccounts" message
|
||||
*/
|
||||
const GetLargestAccountsRpcResult = jsonRpcResultAndContext(
|
||||
struct.array([
|
||||
struct({
|
||||
lamports: 'number',
|
||||
address: 'string',
|
||||
}),
|
||||
]),
|
||||
);
|
||||
|
||||
/**
|
||||
* Expected JSON RPC response for the "getVersion" message
|
||||
*/
|
||||
|
@ -1063,6 +1110,30 @@ export class Connection {
|
|||
return res.result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the 20 largest accounts with their current balances
|
||||
*/
|
||||
async getLargestAccounts(
|
||||
config: ?GetLargestAccountsConfig,
|
||||
): Promise<RpcResponseAndContext<Array<AccountBalancePair>>> {
|
||||
const arg = {
|
||||
...config,
|
||||
commitment: (config && config.commitment) || this.commitment,
|
||||
};
|
||||
const args = arg.filter || arg.commitment ? [arg] : [];
|
||||
const unsafeRes = await this._rpcRequest('getLargestAccounts', args);
|
||||
const res = GetLargestAccountsRpcResult(unsafeRes);
|
||||
if (res.error) {
|
||||
throw new Error('failed to get largest accounts: ' + res.error.message);
|
||||
}
|
||||
assert(typeof res.result !== 'undefined');
|
||||
res.result.value = res.result.value.map(({address, lamports}) => ({
|
||||
address: new PublicKey(address),
|
||||
lamports,
|
||||
}));
|
||||
return res.result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all the account info for the specified public key, return with context
|
||||
*/
|
||||
|
|
|
@ -1141,6 +1141,33 @@ test('get supply', async () => {
|
|||
expect(supply.nonCirculatingAccounts.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test('get largest accounts', async () => {
|
||||
const connection = new Connection(url);
|
||||
|
||||
mockRpc.push([
|
||||
url,
|
||||
{
|
||||
method: 'getLargestAccounts',
|
||||
params: [],
|
||||
},
|
||||
{
|
||||
error: null,
|
||||
result: {
|
||||
context: {
|
||||
slot: 1,
|
||||
},
|
||||
value: new Array(20).fill(0).map(() => ({
|
||||
address: new Account().publicKey.toBase58(),
|
||||
lamports: 1000,
|
||||
})),
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
const largestAccounts = (await connection.getLargestAccounts()).value;
|
||||
expect(largestAccounts.length).toEqual(20);
|
||||
});
|
||||
|
||||
test('getVersion', async () => {
|
||||
const connection = new Connection(url);
|
||||
|
||||
|
|
Loading…
Reference in New Issue