feat: add token methods (#11303)
This commit is contained in:
46
web3.js/flow-typed/npm/@solana/spl-token_vx.x.x.js
vendored
Normal file
46
web3.js/flow-typed/npm/@solana/spl-token_vx.x.x.js
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// flow-typed signature: 069c76ac6f0b539483367fd95c435241
|
||||||
|
// flow-typed version: <<STUB>>/@solana/spl-token_v0.0.4/flow_v0.130.0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is an autogenerated libdef stub for:
|
||||||
|
*
|
||||||
|
* '@solana/spl-token'
|
||||||
|
*
|
||||||
|
* Fill this stub out by replacing all the `any` types.
|
||||||
|
*
|
||||||
|
* Once filled out, we encourage you to share your work with the
|
||||||
|
* community by sending a pull request to:
|
||||||
|
* https://github.com/flowtype/flow-typed
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare module '@solana/spl-token' {
|
||||||
|
declare module.exports: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We include stubs for each file inside this npm package in case you need to
|
||||||
|
* require those files directly. Feel free to delete any files that aren't
|
||||||
|
* needed.
|
||||||
|
*/
|
||||||
|
declare module '@solana/spl-token/lib/index.cjs' {
|
||||||
|
declare module.exports: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '@solana/spl-token/lib/index.esm' {
|
||||||
|
declare module.exports: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '@solana/spl-token/module.flow' {
|
||||||
|
declare module.exports: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filename aliases
|
||||||
|
declare module '@solana/spl-token/lib/index.cjs.js' {
|
||||||
|
declare module.exports: $Exports<'@solana/spl-token/lib/index.cjs'>;
|
||||||
|
}
|
||||||
|
declare module '@solana/spl-token/lib/index.esm.js' {
|
||||||
|
declare module.exports: $Exports<'@solana/spl-token/lib/index.esm'>;
|
||||||
|
}
|
||||||
|
declare module '@solana/spl-token/module.flow.js' {
|
||||||
|
declare module.exports: $Exports<'@solana/spl-token/module.flow'>;
|
||||||
|
}
|
40
web3.js/module.d.ts
vendored
40
web3.js/module.d.ts
vendored
@ -50,6 +50,14 @@ declare module '@solana/web3.js' {
|
|||||||
skipPreflight?: boolean;
|
skipPreflight?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type TokenAccountsFilter =
|
||||||
|
| {
|
||||||
|
mint: PublicKey;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
programId: PublicKey;
|
||||||
|
};
|
||||||
|
|
||||||
export type RpcResponseAndContext<T> = {
|
export type RpcResponseAndContext<T> = {
|
||||||
context: Context;
|
context: Context;
|
||||||
value: T;
|
value: T;
|
||||||
@ -150,6 +158,23 @@ declare module '@solana/web3.js' {
|
|||||||
root: number;
|
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 AccountChangeCallback = (
|
export type AccountChangeCallback = (
|
||||||
accountInfo: AccountInfo,
|
accountInfo: AccountInfo,
|
||||||
context: Context,
|
context: Context,
|
||||||
@ -239,6 +264,21 @@ declare module '@solana/web3.js' {
|
|||||||
getMinimumLedgerSlot(): Promise<number>;
|
getMinimumLedgerSlot(): Promise<number>;
|
||||||
getFirstAvailableBlock(): Promise<number>;
|
getFirstAvailableBlock(): Promise<number>;
|
||||||
getSupply(commitment?: Commitment): Promise<RpcResponseAndContext<Supply>>;
|
getSupply(commitment?: Commitment): Promise<RpcResponseAndContext<Supply>>;
|
||||||
|
getTokenSupply(
|
||||||
|
tokenMintAddress: PublicKey,
|
||||||
|
commitment?: Commitment,
|
||||||
|
): Promise<RpcResponseAndContext<number>>;
|
||||||
|
getTokenAccountBalance(
|
||||||
|
tokenAddress: PublicKey,
|
||||||
|
commitment?: Commitment,
|
||||||
|
): Promise<RpcResponseAndContext<number>>;
|
||||||
|
getTokenAccountsByOwner(
|
||||||
|
ownerAddress: PublicKey,
|
||||||
|
filter: TokenAccountsFilter,
|
||||||
|
commitment?: Commitment,
|
||||||
|
): Promise<
|
||||||
|
RpcResponseAndContext<Array<{pubkey: PublicKey; account: TokenAccount}>>
|
||||||
|
>;
|
||||||
getLargestAccounts(
|
getLargestAccounts(
|
||||||
config?: GetLargestAccountsConfig,
|
config?: GetLargestAccountsConfig,
|
||||||
): Promise<RpcResponseAndContext<Array<AccountBalancePair>>>;
|
): Promise<RpcResponseAndContext<Array<AccountBalancePair>>>;
|
||||||
|
@ -66,6 +66,14 @@ declare module '@solana/web3.js' {
|
|||||||
skipPreflight: ?boolean,
|
skipPreflight: ?boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
declare export type TokenAccountsFilter =
|
||||||
|
| {
|
||||||
|
mint: PublicKey,
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
programId: PublicKey,
|
||||||
|
};
|
||||||
|
|
||||||
declare export type RpcResponseAndContext<T> = {
|
declare export type RpcResponseAndContext<T> = {
|
||||||
context: Context,
|
context: Context,
|
||||||
value: T,
|
value: T,
|
||||||
@ -166,6 +174,23 @@ declare module '@solana/web3.js' {
|
|||||||
root: number,
|
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 type AccountChangeCallback = (
|
declare type AccountChangeCallback = (
|
||||||
accountInfo: AccountInfo,
|
accountInfo: AccountInfo,
|
||||||
context: Context,
|
context: Context,
|
||||||
@ -255,6 +280,21 @@ declare module '@solana/web3.js' {
|
|||||||
getMinimumLedgerSlot(): Promise<number>;
|
getMinimumLedgerSlot(): Promise<number>;
|
||||||
getFirstAvailableBlock(): Promise<number>;
|
getFirstAvailableBlock(): Promise<number>;
|
||||||
getSupply(commitment: ?Commitment): Promise<RpcResponseAndContext<Supply>>;
|
getSupply(commitment: ?Commitment): Promise<RpcResponseAndContext<Supply>>;
|
||||||
|
getTokenSupply(
|
||||||
|
tokenMintAddress: PublicKey,
|
||||||
|
commitment: ?Commitment,
|
||||||
|
): Promise<RpcResponseAndContext<number>>;
|
||||||
|
getTokenAccountBalance(
|
||||||
|
tokenAddress: PublicKey,
|
||||||
|
commitment: ?Commitment,
|
||||||
|
): Promise<RpcResponseAndContext<number>>;
|
||||||
|
getTokenAccountsByOwner(
|
||||||
|
ownerAddress: PublicKey,
|
||||||
|
filter: TokenAccountsFilter,
|
||||||
|
commitment: ?Commitment,
|
||||||
|
): Promise<
|
||||||
|
RpcResponseAndContext<Array<{pubkey: PublicKey, account: TokenAccount}>>,
|
||||||
|
>;
|
||||||
getLargestAccounts(
|
getLargestAccounts(
|
||||||
config: ?GetLargestAccountsConfig,
|
config: ?GetLargestAccountsConfig,
|
||||||
): Promise<RpcResponseAndContext<Array<AccountBalancePair>>>;
|
): Promise<RpcResponseAndContext<Array<AccountBalancePair>>>;
|
||||||
|
75
web3.js/package-lock.json
generated
75
web3.js/package-lock.json
generated
@ -4742,6 +4742,44 @@
|
|||||||
"@sinonjs/commons": "^1.7.0"
|
"@sinonjs/commons": "^1.7.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@solana/spl-token": {
|
||||||
|
"version": "0.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.0.4.tgz",
|
||||||
|
"integrity": "sha512-zYoZ6iYMKxGYbouunEkWdf6vWRJyEPOkAjvlNVjww9oPKMkIeM9VzgGtjZ/kKMelao1QEohH4JN9qXO4+LwfRA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.10.5",
|
||||||
|
"@solana/web3.js": "^0.63.2",
|
||||||
|
"bn.js": "^5.0.0",
|
||||||
|
"buffer-layout": "^1.2.0",
|
||||||
|
"dotenv": "8.2.0",
|
||||||
|
"json-to-pretty-yaml": "^1.2.2",
|
||||||
|
"mkdirp-promise": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@solana/web3.js": {
|
||||||
|
"version": "0.63.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-0.63.2.tgz",
|
||||||
|
"integrity": "sha512-4jd8U1U/eFTEemr+jCzQCDepKnkttV4dxWsjMloifb82x1d6KgCzP+Jd6D9kr8f1MFj2i/AnG++97tlHAGTOkA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.3.1",
|
||||||
|
"bn.js": "^5.0.0",
|
||||||
|
"bs58": "^4.0.1",
|
||||||
|
"buffer": "^5.4.3",
|
||||||
|
"buffer-layout": "^1.2.0",
|
||||||
|
"crypto-hash": "^1.2.2",
|
||||||
|
"esdoc-inject-style-plugin": "^1.0.0",
|
||||||
|
"jayson": "^3.0.1",
|
||||||
|
"mz": "^2.7.0",
|
||||||
|
"node-fetch": "^2.2.0",
|
||||||
|
"npm-run-all": "^4.1.5",
|
||||||
|
"rpc-websockets": "^5.0.8",
|
||||||
|
"superstruct": "^0.8.3",
|
||||||
|
"tweetnacl": "^1.0.0",
|
||||||
|
"ws": "^7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@szmarczak/http-timer": {
|
"@szmarczak/http-timer": {
|
||||||
"version": "4.0.5",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz",
|
||||||
@ -8274,6 +8312,12 @@
|
|||||||
"is-obj": "^1.0.0"
|
"is-obj": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dotenv": {
|
||||||
|
"version": "8.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
|
||||||
|
"integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"duplexer2": {
|
"duplexer2": {
|
||||||
"version": "0.1.4",
|
"version": "0.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
|
||||||
@ -14170,6 +14214,16 @@
|
|||||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||||
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
|
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
|
||||||
},
|
},
|
||||||
|
"json-to-pretty-yaml": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-to-pretty-yaml/-/json-to-pretty-yaml-1.2.2.tgz",
|
||||||
|
"integrity": "sha1-9M0L0KXo/h3yWq9boRiwmf2ZLVs=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"remedial": "^1.0.7",
|
||||||
|
"remove-trailing-spaces": "^1.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"json5": {
|
"json5": {
|
||||||
"version": "0.5.1",
|
"version": "0.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
|
||||||
@ -15150,6 +15204,15 @@
|
|||||||
"minimist": "0.0.8"
|
"minimist": "0.0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mkdirp-promise": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz",
|
||||||
|
"integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"mkdirp": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"modify-values": {
|
"modify-values": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz",
|
||||||
@ -20096,12 +20159,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"remedial": {
|
||||||
|
"version": "1.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/remedial/-/remedial-1.0.8.tgz",
|
||||||
|
"integrity": "sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"remove-trailing-separator": {
|
"remove-trailing-separator": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
|
||||||
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
|
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"remove-trailing-spaces": {
|
||||||
|
"version": "1.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/remove-trailing-spaces/-/remove-trailing-spaces-1.0.7.tgz",
|
||||||
|
"integrity": "sha512-wjM17CJ2kk0SgoGyJ7ZMzRRCuTq+V8YhMwpZ5XEWX0uaked2OUq6utvHXGNBQrfkUzUUABFMyxlKn+85hMv4dg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"repeat-element": {
|
"repeat-element": {
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
|
||||||
|
@ -97,6 +97,7 @@
|
|||||||
"@babel/preset-flow": "^7.0.0",
|
"@babel/preset-flow": "^7.0.0",
|
||||||
"@commitlint/config-conventional": "^9.0.1",
|
"@commitlint/config-conventional": "^9.0.1",
|
||||||
"@commitlint/travis-cli": "^9.0.1",
|
"@commitlint/travis-cli": "^9.0.1",
|
||||||
|
"@solana/spl-token": "^0.0.4",
|
||||||
"@typescript-eslint/eslint-plugin": "^2.18.0",
|
"@typescript-eslint/eslint-plugin": "^2.18.0",
|
||||||
"@typescript-eslint/parser": "^2.18.0",
|
"@typescript-eslint/parser": "^2.18.0",
|
||||||
"acorn": "^7.0.0",
|
"acorn": "^7.0.0",
|
||||||
|
@ -24,6 +24,14 @@ export const BLOCKHASH_CACHE_TIMEOUT_MS = 30 * 1000;
|
|||||||
|
|
||||||
type RpcRequest = (methodName: string, args: Array<any>) => any;
|
type RpcRequest = (methodName: string, args: Array<any>) => any;
|
||||||
|
|
||||||
|
type TokenAccountsFilter =
|
||||||
|
| {
|
||||||
|
mint: PublicKey,
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
programId: PublicKey,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extra contextual information for RPC responses
|
* Extra contextual information for RPC responses
|
||||||
*
|
*
|
||||||
@ -500,6 +508,77 @@ 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,
|
||||||
|
};
|
||||||
|
|
||||||
|
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 response for the "getTokenAccountBalance" message
|
||||||
|
*/
|
||||||
|
const GetTokenAccountBalance = jsonRpcResultAndContext('number');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expected JSON RPC response for the "getTokenSupply" message
|
||||||
|
*/
|
||||||
|
const GetTokenSupplyRpcResult = jsonRpcResultAndContext('number');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expected JSON RPC response for the "getTokenAccountsByOwner" message
|
||||||
|
*/
|
||||||
|
const GetTokenAccountsByOwner = jsonRpcResultAndContext(
|
||||||
|
struct.array([
|
||||||
|
struct({
|
||||||
|
pubkey: 'string',
|
||||||
|
account: struct({
|
||||||
|
executable: 'boolean',
|
||||||
|
owner: 'string',
|
||||||
|
lamports: 'number',
|
||||||
|
data: TokenAccountResult,
|
||||||
|
rentEpoch: 'number?',
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pair of an account address and its balance
|
* Pair of an account address and its balance
|
||||||
*
|
*
|
||||||
@ -541,7 +620,7 @@ const AccountInfoResult = struct({
|
|||||||
executable: 'boolean',
|
executable: 'boolean',
|
||||||
owner: 'string',
|
owner: 'string',
|
||||||
lamports: 'number',
|
lamports: 'number',
|
||||||
data: 'string',
|
data: 'any',
|
||||||
rentEpoch: 'number?',
|
rentEpoch: 'number?',
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1185,6 +1264,109 @@ export class Connection {
|
|||||||
return res.result;
|
return res.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the current supply of a token mint
|
||||||
|
*/
|
||||||
|
async getTokenSupply(
|
||||||
|
tokenMintAddress: PublicKey,
|
||||||
|
commitment: ?Commitment,
|
||||||
|
): Promise<RpcResponseAndContext<number>> {
|
||||||
|
const args = this._argsWithCommitment(
|
||||||
|
[tokenMintAddress.toBase58()],
|
||||||
|
commitment,
|
||||||
|
);
|
||||||
|
const unsafeRes = await this._rpcRequest('getTokenSupply', args);
|
||||||
|
const res = GetTokenSupplyRpcResult(unsafeRes);
|
||||||
|
if (res.error) {
|
||||||
|
throw new Error('failed to get token supply: ' + res.error.message);
|
||||||
|
}
|
||||||
|
assert(typeof res.result !== 'undefined');
|
||||||
|
return res.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the current balance of a token account
|
||||||
|
*/
|
||||||
|
async getTokenAccountBalance(
|
||||||
|
tokenAddress: PublicKey,
|
||||||
|
commitment: ?Commitment,
|
||||||
|
): Promise<RpcResponseAndContext<number>> {
|
||||||
|
const args = this._argsWithCommitment(
|
||||||
|
[tokenAddress.toBase58()],
|
||||||
|
commitment,
|
||||||
|
);
|
||||||
|
const unsafeRes = await this._rpcRequest('getTokenAccountBalance', args);
|
||||||
|
const res = GetTokenAccountBalance(unsafeRes);
|
||||||
|
if (res.error) {
|
||||||
|
throw new Error(
|
||||||
|
'failed to get token account balance: ' + res.error.message,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
assert(typeof res.result !== 'undefined');
|
||||||
|
return res.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch all the token accounts owned by the specified account
|
||||||
|
*
|
||||||
|
* @return {Promise<RpcResponseAndContext<Array<{pubkey: PublicKey, account: TokenAccount}>>>}
|
||||||
|
*/
|
||||||
|
async getTokenAccountsByOwner(
|
||||||
|
ownerAddress: PublicKey,
|
||||||
|
filter: TokenAccountsFilter,
|
||||||
|
commitment: ?Commitment,
|
||||||
|
): Promise<
|
||||||
|
RpcResponseAndContext<Array<{pubkey: PublicKey, account: TokenAccount}>>,
|
||||||
|
> {
|
||||||
|
let _args = [ownerAddress.toBase58()];
|
||||||
|
|
||||||
|
// Strip flow types to make flow happy
|
||||||
|
((filter: any) => {
|
||||||
|
if ('mint' in filter) {
|
||||||
|
_args.push({mint: filter.mint.toBase58()});
|
||||||
|
} else {
|
||||||
|
_args.push({programId: filter.programId.toBase58()});
|
||||||
|
}
|
||||||
|
})(filter);
|
||||||
|
|
||||||
|
const args = this._argsWithCommitment(_args, commitment);
|
||||||
|
const unsafeRes = await this._rpcRequest('getTokenAccountsByOwner', args);
|
||||||
|
const res = GetTokenAccountsByOwner(unsafeRes);
|
||||||
|
if (res.error) {
|
||||||
|
throw new Error(
|
||||||
|
'failed to get token accounts owned by account ' +
|
||||||
|
ownerAddress.toBase58() +
|
||||||
|
': ' +
|
||||||
|
res.error.message,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const {result} = res;
|
||||||
|
const {context, value} = result;
|
||||||
|
assert(typeof result !== 'undefined');
|
||||||
|
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch the 20 largest accounts with their current balances
|
* Fetch the 20 largest accounts with their current balances
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import bs58 from 'bs58';
|
import bs58 from 'bs58';
|
||||||
|
import {Token, u64} from '@solana/spl-token';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Account,
|
Account,
|
||||||
@ -1261,6 +1262,129 @@ test('get supply', async () => {
|
|||||||
expect(supply.nonCirculatingAccounts.length).toBeGreaterThan(0);
|
expect(supply.nonCirculatingAccounts.length).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const TOKEN_PROGRAM_ID = new PublicKey(
|
||||||
|
'TokenSVp5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o',
|
||||||
|
);
|
||||||
|
|
||||||
|
test('token methods', async () => {
|
||||||
|
if (mockRpcEnabled) {
|
||||||
|
console.log('non-live test skipped');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const connection = new Connection(url);
|
||||||
|
const payerAccount = new Account();
|
||||||
|
await connection.confirmTransaction(
|
||||||
|
await connection.requestAirdrop(payerAccount.publicKey, 100000000000),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
|
const mintOwner = new Account();
|
||||||
|
const accountOwner = new Account();
|
||||||
|
const [token, tokenAccount] = await Token.createMint(
|
||||||
|
connection,
|
||||||
|
payerAccount,
|
||||||
|
mintOwner.publicKey,
|
||||||
|
accountOwner.publicKey,
|
||||||
|
new u64(10000),
|
||||||
|
2,
|
||||||
|
TOKEN_PROGRAM_ID,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
await Token.createMint(
|
||||||
|
connection,
|
||||||
|
payerAccount,
|
||||||
|
mintOwner.publicKey,
|
||||||
|
accountOwner.publicKey,
|
||||||
|
new u64(10000),
|
||||||
|
2,
|
||||||
|
TOKEN_PROGRAM_ID,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
const tokenAccountDest = await token.createAccount(accountOwner.publicKey);
|
||||||
|
await token.transfer(
|
||||||
|
tokenAccount,
|
||||||
|
tokenAccountDest,
|
||||||
|
accountOwner,
|
||||||
|
[],
|
||||||
|
new u64(1),
|
||||||
|
);
|
||||||
|
|
||||||
|
const supply = (await connection.getTokenSupply(token.publicKey, 'recent'))
|
||||||
|
.value;
|
||||||
|
expect(supply).toEqual(10000);
|
||||||
|
|
||||||
|
const newAccount = new Account();
|
||||||
|
await expect(
|
||||||
|
connection.getTokenSupply(newAccount.publicKey, 'recent'),
|
||||||
|
).rejects.toThrow();
|
||||||
|
|
||||||
|
const balance = (
|
||||||
|
await connection.getTokenAccountBalance(tokenAccount, 'recent')
|
||||||
|
).value;
|
||||||
|
expect(balance).toEqual(9999);
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
connection.getTokenAccountBalance(newAccount.publicKey, 'recent'),
|
||||||
|
).rejects.toThrow();
|
||||||
|
|
||||||
|
const accountsWithMintFilter = (
|
||||||
|
await connection.getTokenAccountsByOwner(
|
||||||
|
accountOwner.publicKey,
|
||||||
|
{mint: token.publicKey},
|
||||||
|
'recent',
|
||||||
|
)
|
||||||
|
).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(
|
||||||
|
accountOwner.publicKey,
|
||||||
|
{programId: TOKEN_PROGRAM_ID},
|
||||||
|
'recent',
|
||||||
|
)
|
||||||
|
).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(
|
||||||
|
newAccount.publicKey,
|
||||||
|
{mint: token.publicKey},
|
||||||
|
'recent',
|
||||||
|
)
|
||||||
|
).value;
|
||||||
|
expect(noAccounts.length).toEqual(0);
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
connection.getTokenAccountsByOwner(
|
||||||
|
accountOwner.publicKey,
|
||||||
|
{mint: newAccount.publicKey},
|
||||||
|
'recent',
|
||||||
|
),
|
||||||
|
).rejects.toThrow();
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
connection.getTokenAccountsByOwner(
|
||||||
|
accountOwner.publicKey,
|
||||||
|
{programId: newAccount.publicKey},
|
||||||
|
'recent',
|
||||||
|
),
|
||||||
|
).rejects.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
test('get largest accounts', async () => {
|
test('get largest accounts', async () => {
|
||||||
const connection = new Connection(url);
|
const connection = new Connection(url);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user