From 2261c066f3cc7b6013c945b268c0388f34a57a13 Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Thu, 6 Aug 2020 12:17:29 +0800 Subject: [PATCH] fix: update token API handling --- web3.js/module.d.ts | 25 +++------ web3.js/module.flow.js | 25 +++------ web3.js/src/connection.js | 90 ++++++++++----------------------- web3.js/test/connection.test.js | 21 +++----- 4 files changed, 48 insertions(+), 113 deletions(-) diff --git a/web3.js/module.d.ts b/web3.js/module.d.ts index e4d06982b0..bb755820b8 100644 --- a/web3.js/module.d.ts +++ b/web3.js/module.d.ts @@ -158,21 +158,10 @@ declare module '@solana/web3.js' { root: number; }; - export type TokenAccountInfo = { - mint: PublicKey; - owner: PublicKey; - amount: number; - delegate: null | PublicKey; - delegatedAmount: number; - isInitialized: boolean; - isNative: boolean; - }; - - export type TokenAccount = { - executable: boolean; - owner: PublicKey; - lamports: number; - data: TokenAccountInfo; + export type TokenAmount = { + uiAmount: number; + decimals: number; + amount: string; }; export type AccountChangeCallback = ( @@ -267,17 +256,17 @@ declare module '@solana/web3.js' { getTokenSupply( tokenMintAddress: PublicKey, commitment?: Commitment, - ): Promise>; + ): Promise>; getTokenAccountBalance( tokenAddress: PublicKey, commitment?: Commitment, - ): Promise>; + ): Promise>; getTokenAccountsByOwner( ownerAddress: PublicKey, filter: TokenAccountsFilter, commitment?: Commitment, ): Promise< - RpcResponseAndContext> + RpcResponseAndContext> >; getLargestAccounts( config?: GetLargestAccountsConfig, diff --git a/web3.js/module.flow.js b/web3.js/module.flow.js index 0717b5f749..50aaed0119 100644 --- a/web3.js/module.flow.js +++ b/web3.js/module.flow.js @@ -174,21 +174,10 @@ declare module '@solana/web3.js' { root: number, }; - declare export type TokenAccountInfo = { - mint: PublicKey, - owner: PublicKey, - amount: number, - delegate: null | PublicKey, - delegatedAmount: number, - isInitialized: boolean, - isNative: boolean, - }; - - declare export type TokenAccount = { - executable: boolean, - owner: PublicKey, - lamports: number, - data: TokenAccountInfo, + declare export type TokenAmount = { + uiAmount: number, + decimals: number, + amount: string, }; declare type AccountChangeCallback = ( @@ -283,17 +272,17 @@ declare module '@solana/web3.js' { getTokenSupply( tokenMintAddress: PublicKey, commitment: ?Commitment, - ): Promise>; + ): Promise>; getTokenAccountBalance( tokenAddress: PublicKey, commitment: ?Commitment, - ): Promise>; + ): Promise>; getTokenAccountsByOwner( ownerAddress: PublicKey, filter: TokenAccountsFilter, commitment: ?Commitment, ): Promise< - RpcResponseAndContext>, + RpcResponseAndContext>, >; getLargestAccounts( config: ?GetLargestAccountsConfig, diff --git a/web3.js/src/connection.js b/web3.js/src/connection.js index b57807c7ac..a4d2d294c4 100644 --- a/web3.js/src/connection.js +++ b/web3.js/src/connection.js @@ -508,58 +508,30 @@ const GetSupplyRpcResult = jsonRpcResultAndContext( }), ); -/** - * Information describing a token account - */ -type TokenAccountInfo = {| - mint: PublicKey, - owner: PublicKey, - amount: number, - delegate: null | PublicKey, - delegatedAmount: number, - isInitialized: boolean, - isNative: boolean, -|}; - -/** - * Information describing an account with token account data - * - * @typedef {Object} TokenAccount - * @property {number} lamports Number of lamports assigned to the account - * @property {PublicKey} owner Identifier of the program that owns the account - * @property {TokenAccountInfo} data Token account data - * @property {boolean} executable `true` if this account's data contains a loaded program - */ -type TokenAccount = { - executable: boolean, - owner: PublicKey, - lamports: number, - data: TokenAccountInfo, +type TokenAmount = { + amount: string, + decimals: 2, + uiAmount: number, }; -const TokenAccountResult = struct({ - token: struct({ - account: struct({ - mint: 'string', - owner: 'string', - amount: 'number', - delegate: struct.union(['string', 'null']), - delegatedAmount: 'number', - isInitialized: 'boolean', - isNative: 'boolean', - }), - }), +/** + * Expected JSON RPC structure for token amounts + */ +const TokenAmountResult = struct({ + amount: 'string', + uiAmount: 'number', + decimals: 'number', }); /** * Expected JSON RPC response for the "getTokenAccountBalance" message */ -const GetTokenAccountBalance = jsonRpcResultAndContext('number'); +const GetTokenAccountBalance = jsonRpcResultAndContext(TokenAmountResult); /** * Expected JSON RPC response for the "getTokenSupply" message */ -const GetTokenSupplyRpcResult = jsonRpcResultAndContext('number'); +const GetTokenSupplyRpcResult = jsonRpcResultAndContext(TokenAmountResult); /** * Expected JSON RPC response for the "getTokenAccountsByOwner" message @@ -572,7 +544,7 @@ const GetTokenAccountsByOwner = jsonRpcResultAndContext( executable: 'boolean', owner: 'string', lamports: 'number', - data: TokenAccountResult, + data: 'any', rentEpoch: 'number?', }), }), @@ -1270,7 +1242,7 @@ export class Connection { async getTokenSupply( tokenMintAddress: PublicKey, commitment: ?Commitment, - ): Promise> { + ): Promise> { const args = this._argsWithCommitment( [tokenMintAddress.toBase58()], commitment, @@ -1290,7 +1262,7 @@ export class Connection { async getTokenAccountBalance( tokenAddress: PublicKey, commitment: ?Commitment, - ): Promise> { + ): Promise> { const args = this._argsWithCommitment( [tokenAddress.toBase58()], commitment, @@ -1309,14 +1281,14 @@ export class Connection { /** * Fetch all the token accounts owned by the specified account * - * @return {Promise>>} + * @return {Promise>>} */ async getTokenAccountsByOwner( ownerAddress: PublicKey, filter: TokenAccountsFilter, commitment: ?Commitment, ): Promise< - RpcResponseAndContext>, + RpcResponseAndContext>, > { let _args = [ownerAddress.toBase58()]; @@ -1347,23 +1319,15 @@ export class Connection { return { context, - value: value.map(result => { - const data = result.account.data.token.account; - return { - pubkey: new PublicKey(result.pubkey), - account: { - executable: result.account.executable, - owner: new PublicKey(result.account.owner), - lamports: result.account.lamports, - data: { - ...data, - mint: new PublicKey(data.mint), - owner: new PublicKey(data.owner), - delegate: data.delegate ? new PublicKey(data.delegate) : null, - }, - }, - }; - }), + value: value.map(result => ({ + pubkey: result.pubkey, + account: { + executable: result.account.executable, + owner: new PublicKey(result.account.owner), + lamports: result.account.lamports, + data: bs58.decode(result.account.data), + }, + })), }; } diff --git a/web3.js/test/connection.test.js b/web3.js/test/connection.test.js index 7dc4fafadc..714c1715f8 100644 --- a/web3.js/test/connection.test.js +++ b/web3.js/test/connection.test.js @@ -1286,7 +1286,7 @@ test('token methods', async () => { payerAccount, mintOwner.publicKey, accountOwner.publicKey, - new u64(10000), + new u64(11111), 2, TOKEN_PROGRAM_ID, false, @@ -1314,7 +1314,9 @@ test('token methods', async () => { const supply = (await connection.getTokenSupply(token.publicKey, 'recent')) .value; - expect(supply).toEqual(10000); + expect(supply.uiAmount).toEqual(111.11); + expect(supply.decimals).toEqual(2); + expect(supply.amount).toEqual('11111'); const newAccount = new Account(); await expect( @@ -1324,7 +1326,9 @@ test('token methods', async () => { const balance = ( await connection.getTokenAccountBalance(tokenAccount, 'recent') ).value; - expect(balance).toEqual(9999); + expect(balance.amount).toEqual('11110'); + expect(balance.decimals).toEqual(2); + expect(balance.uiAmount).toEqual(111.1); await expect( connection.getTokenAccountBalance(newAccount.publicKey, 'recent'), @@ -1338,12 +1342,6 @@ test('token methods', async () => { ) ).value; expect(accountsWithMintFilter.length).toEqual(2); - for (const {account} of accountsWithMintFilter) { - expect(account.data.mint.toBase58()).toEqual(token.publicKey.toBase58()); - expect(account.data.owner.toBase58()).toEqual( - accountOwner.publicKey.toBase58(), - ); - } const accountsWithProgramFilter = ( await connection.getTokenAccountsByOwner( @@ -1353,11 +1351,6 @@ test('token methods', async () => { ) ).value; expect(accountsWithProgramFilter.length).toEqual(3); - for (const {account} of accountsWithProgramFilter) { - expect(account.data.owner.toBase58()).toEqual( - accountOwner.publicKey.toBase58(), - ); - } const noAccounts = ( await connection.getTokenAccountsByOwner(