feat: add getTokenLargestAccounts method
This commit is contained in:
committed by
Justin Starry
parent
177c9c3aec
commit
e1dc05fae0
11
web3.js/module.d.ts
vendored
11
web3.js/module.d.ts
vendored
@ -215,6 +215,13 @@ declare module '@solana/web3.js' {
|
|||||||
amount: string;
|
amount: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type TokenAccountBalancePair = {
|
||||||
|
address: PublicKey;
|
||||||
|
amount: string;
|
||||||
|
decimals: number;
|
||||||
|
uiAmount: number;
|
||||||
|
};
|
||||||
|
|
||||||
export type AccountChangeCallback = (
|
export type AccountChangeCallback = (
|
||||||
accountInfo: AccountInfo<Buffer>,
|
accountInfo: AccountInfo<Buffer>,
|
||||||
context: Context,
|
context: Context,
|
||||||
@ -343,6 +350,10 @@ declare module '@solana/web3.js' {
|
|||||||
getLargestAccounts(
|
getLargestAccounts(
|
||||||
config?: GetLargestAccountsConfig,
|
config?: GetLargestAccountsConfig,
|
||||||
): Promise<RpcResponseAndContext<Array<AccountBalancePair>>>;
|
): Promise<RpcResponseAndContext<Array<AccountBalancePair>>>;
|
||||||
|
getTokenLargestAccounts(
|
||||||
|
mintAddress: PublicKey,
|
||||||
|
commitment?: Commitment,
|
||||||
|
): Promise<RpcResponseAndContext<Array<TokenAccountBalancePair>>>;
|
||||||
getClusterNodes(): Promise<Array<ContactInfo>>;
|
getClusterNodes(): Promise<Array<ContactInfo>>;
|
||||||
getConfirmedBlock(slot: number): Promise<ConfirmedBlock>;
|
getConfirmedBlock(slot: number): Promise<ConfirmedBlock>;
|
||||||
getConfirmedTransaction(
|
getConfirmedTransaction(
|
||||||
|
@ -237,6 +237,13 @@ declare module '@solana/web3.js' {
|
|||||||
amount: string,
|
amount: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
declare export type TokenAccountBalancePair = {
|
||||||
|
address: PublicKey,
|
||||||
|
amount: string,
|
||||||
|
decimals: number,
|
||||||
|
uiAmount: number,
|
||||||
|
};
|
||||||
|
|
||||||
declare type AccountChangeCallback = (
|
declare type AccountChangeCallback = (
|
||||||
accountInfo: AccountInfo<Buffer>,
|
accountInfo: AccountInfo<Buffer>,
|
||||||
context: Context,
|
context: Context,
|
||||||
@ -356,6 +363,10 @@ declare module '@solana/web3.js' {
|
|||||||
getLargestAccounts(
|
getLargestAccounts(
|
||||||
config: ?GetLargestAccountsConfig,
|
config: ?GetLargestAccountsConfig,
|
||||||
): Promise<RpcResponseAndContext<Array<AccountBalancePair>>>;
|
): Promise<RpcResponseAndContext<Array<AccountBalancePair>>>;
|
||||||
|
getTokenLargestAccounts(
|
||||||
|
mintAddress: PublicKey,
|
||||||
|
commitment: ?Commitment,
|
||||||
|
): Promise<RpcResponseAndContext<Array<TokenAccountBalancePair>>>;
|
||||||
getClusterNodes(): Promise<Array<ContactInfo>>;
|
getClusterNodes(): Promise<Array<ContactInfo>>;
|
||||||
getConfirmedBlock(slot: number): Promise<ConfirmedBlock>;
|
getConfirmedBlock(slot: number): Promise<ConfirmedBlock>;
|
||||||
getConfirmedTransaction(
|
getConfirmedTransaction(
|
||||||
|
@ -616,21 +616,60 @@ const GetSupplyRpcResult = jsonRpcResultAndContext(
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Token amount object which returns a token amount in different formats
|
||||||
|
* for various client use cases.
|
||||||
|
*
|
||||||
|
* @typedef {Object} TokenAmount
|
||||||
|
* @property {string} amount Raw amount of tokens as string ignoring decimals
|
||||||
|
* @property {number} decimals Number of decimals configured for token's mint
|
||||||
|
* @property {number} uiAmount Token account as float, accounts for decimals
|
||||||
|
*/
|
||||||
type TokenAmount = {
|
type TokenAmount = {
|
||||||
amount: string,
|
amount: string,
|
||||||
decimals: 2,
|
decimals: number,
|
||||||
uiAmount: number,
|
uiAmount: number,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expected JSON RPC structure for token amounts
|
* Expected JSON RPC structure for token amounts
|
||||||
*/
|
*/
|
||||||
const TokenAmountResult = struct({
|
const TokenAmountResult = struct.object({
|
||||||
amount: 'string',
|
amount: 'string',
|
||||||
uiAmount: 'number',
|
uiAmount: 'number',
|
||||||
decimals: 'number',
|
decimals: 'number',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Token address and balance.
|
||||||
|
*
|
||||||
|
* @typedef {Object} TokenAccountBalancePair
|
||||||
|
* @property {PublicKey} address Address of the token account
|
||||||
|
* @property {string} amount Raw amount of tokens as string ignoring decimals
|
||||||
|
* @property {number} decimals Number of decimals configured for token's mint
|
||||||
|
* @property {number} uiAmount Token account as float, accounts for decimals
|
||||||
|
*/
|
||||||
|
type TokenAccountBalancePair = {
|
||||||
|
address: PublicKey,
|
||||||
|
amount: string,
|
||||||
|
decimals: number,
|
||||||
|
uiAmount: number,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expected JSON RPC response for the "getTokenLargestAccounts" message
|
||||||
|
*/
|
||||||
|
const GetTokenLargestAccountsResult = jsonRpcResultAndContext(
|
||||||
|
struct.array([
|
||||||
|
struct.pick({
|
||||||
|
address: 'string',
|
||||||
|
amount: 'string',
|
||||||
|
uiAmount: 'number',
|
||||||
|
decimals: 'number',
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expected JSON RPC response for the "getTokenAccountBalance" message
|
* Expected JSON RPC response for the "getTokenAccountBalance" message
|
||||||
*/
|
*/
|
||||||
@ -1653,6 +1692,30 @@ export class Connection {
|
|||||||
return res.result;
|
return res.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the 20 largest token accounts with their current balances
|
||||||
|
* for a given mint.
|
||||||
|
*/
|
||||||
|
async getTokenLargestAccounts(
|
||||||
|
mintAddress: PublicKey,
|
||||||
|
commitment: ?Commitment,
|
||||||
|
): Promise<RpcResponseAndContext<Array<TokenAccountBalancePair>>> {
|
||||||
|
const args = this._buildArgs([mintAddress.toBase58()], commitment);
|
||||||
|
const unsafeRes = await this._rpcRequest('getTokenLargestAccounts', args);
|
||||||
|
const res = GetTokenLargestAccountsResult(unsafeRes);
|
||||||
|
if (res.error) {
|
||||||
|
throw new Error(
|
||||||
|
'failed to get token largest accounts: ' + res.error.message,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
assert(typeof res.result !== 'undefined');
|
||||||
|
res.result.value = res.result.value.map(pair => ({
|
||||||
|
...pair,
|
||||||
|
address: new PublicKey(pair.address),
|
||||||
|
}));
|
||||||
|
return res.result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch all the account info for the specified public key, return with context
|
* Fetch all the account info for the specified public key, return with context
|
||||||
*/
|
*/
|
||||||
|
@ -1399,6 +1399,23 @@ describe('token methods', () => {
|
|||||||
await expect(connection.getTokenSupply(newAccount)).rejects.toThrow();
|
await expect(connection.getTokenSupply(newAccount)).rejects.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('get token largest accounts', async () => {
|
||||||
|
const largestAccounts = (
|
||||||
|
await connection.getTokenLargestAccounts(testToken.publicKey)
|
||||||
|
).value;
|
||||||
|
|
||||||
|
expect(largestAccounts.length).toEqual(2);
|
||||||
|
const largestAccount = largestAccounts[0];
|
||||||
|
expect(largestAccount.address.equals(testTokenAccount)).toBe(true);
|
||||||
|
expect(largestAccount.amount).toEqual('11110');
|
||||||
|
expect(largestAccount.decimals).toEqual(2);
|
||||||
|
expect(largestAccount.uiAmount).toEqual(111.1);
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
connection.getTokenLargestAccounts(newAccount),
|
||||||
|
).rejects.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
test('get confirmed token transaction', async () => {
|
test('get confirmed token transaction', async () => {
|
||||||
const parsedTx = await connection.getParsedConfirmedTransaction(
|
const parsedTx = await connection.getParsedConfirmedTransaction(
|
||||||
testSignature,
|
testSignature,
|
||||||
|
Reference in New Issue
Block a user