fix: expose getProgramAccounts RPC method

This commit is contained in:
Tyera Eulberg 2019-06-28 19:28:06 -06:00 committed by Michael Vines
parent c14a44b8b4
commit 0e7c8cd01f
5 changed files with 100 additions and 6 deletions

View File

@ -87,6 +87,9 @@ declare module '@solana/web3.js' {
declare export class Connection {
constructor(endpoint: string): Connection;
getAccountInfo(publicKey: PublicKey): Promise<AccountInfo>;
getProgramAccounts(
programId: PublicKey,
): Promise<Array<[PublicKey, AccountInfo]>>;
getBalance(publicKey: PublicKey): Promise<number>;
getClusterNodes(): Promise<Array<ContactInfo>>;
getEpochVoteAccounts(): Promise<Array<VoteAccountInfo>>;

View File

@ -6561,7 +6561,7 @@
"dependencies": {
"marked": {
"version": "0.3.19",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz",
"resolved": "http://registry.npmjs.org/marked/-/marked-0.3.19.tgz",
"integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==",
"dev": true
},
@ -6825,7 +6825,7 @@
},
"marked": {
"version": "0.3.19",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz",
"resolved": "http://registry.npmjs.org/marked/-/marked-0.3.19.tgz",
"integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==",
"dev": true
},
@ -13022,7 +13022,7 @@
},
"minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
@ -17988,7 +17988,7 @@
"dependencies": {
"minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
}

View File

@ -55,7 +55,7 @@
"localnet:logs": "bin/localnet.sh logs -f",
"localnet:up": "bin/localnet.sh up $npm_package_testnetDefaultChannel",
"localnet:update": "bin/localnet.sh update $npm_package_testnetDefaultChannel",
"ok": "run-s --serial lint flow test doc",
"ok": "run-s lint flow test doc",
"prepare": "run-s clean bpf-sdk:install bpf-sdk:remove-symlinks build",
"pretty": "prettier --write '{,{examples,src,test}/**/}*.js'",
"re": "semantic-release --repository-url git@github.com:solana-labs/solana-web3.js.git",

View File

@ -148,6 +148,13 @@ const ProgramAccountNotificationResult = struct({
result: ProgramAccountInfoResult,
});
/**
* Expected JSON RPC response for the "getProgramAccounts" message
*/
const GetProgramAccountsRpcResult = jsonRpcResult(
struct.list([ProgramAccountInfoResult]),
);
/**
* Expected JSON RPC response for the "confirmTransaction" message
*/
@ -338,6 +345,11 @@ export type TransactionError = {|
*/
type BlockhashAndFeeCalculator = [Blockhash, FeeCalculator]; // This type exists to workaround an esdoc parse error
/**
* @ignore
*/
type PublicKeyAndAccount = [PublicKey, AccountInfo]; // This type exists to workaround an esdoc parse error
/**
* A connection to a fullnode JSON RPC endpoint
*/
@ -435,6 +447,36 @@ export class Connection {
};
}
/**
* Fetch all the accounts owned by the specified program id
*/
async getProgramAccounts(
programId: PublicKey,
): Promise<Array<PublicKeyAndAccount>> {
const unsafeRes = await this._rpcRequest('getProgramAccounts', [
programId.toBase58(),
]);
const res = GetProgramAccountsRpcResult(unsafeRes);
if (res.error) {
throw new Error(res.error.message);
}
const {result} = res;
assert(typeof result !== 'undefined');
return result.map(result => {
return [
result[0],
{
executable: result[1].executable,
owner: new PublicKey(result[1].owner),
lamports: result[1].lamports,
data: Buffer.from(result[1].data),
},
];
});
}
/**
* Confirm the transaction identified by the specified signature
*/

View File

@ -1,5 +1,12 @@
// @flow
import {Account, Connection, BpfLoader, Loader, SystemProgram} from '../src';
import {
Account,
Connection,
BpfLoader,
Loader,
SystemProgram,
sendAndConfirmTransaction,
} from '../src';
import {DEFAULT_TICKS_PER_SLOT, NUM_TICKS_PER_SECOND} from '../src/timing';
import {mockRpc, mockRpcEnabled} from './__mocks__/node-fetch';
import {mockGetRecentBlockhash} from './mockrpc/get-recent-blockhash';
@ -37,6 +44,48 @@ test('get account info - error', () => {
);
});
test('get program accounts', async () => {
if (mockRpcEnabled) {
console.log('non-live test skipped');
return;
}
const connection = new Connection(url);
const account0 = new Account();
const account1 = new Account();
const programId = new Account();
await connection.requestAirdrop(account0.publicKey, 42);
await connection.requestAirdrop(account1.publicKey, 84);
let transaction = SystemProgram.assign(
account0.publicKey,
programId.publicKey,
);
await sendAndConfirmTransaction(connection, transaction, account0);
transaction = SystemProgram.assign(account1.publicKey, programId.publicKey);
await sendAndConfirmTransaction(connection, transaction, account1);
const [, feeCalculator] = await connection.getRecentBlockhash();
const programAccounts = await connection.getProgramAccounts(
programId.publicKey,
);
expect(programAccounts.length).toBe(2);
programAccounts.forEach(function(element) {
expect([
account0.publicKey.toBase58(),
account1.publicKey.toBase58(),
]).toEqual(expect.arrayContaining([element[0]]));
if (element[0] == account0.publicKey) {
expect(element[1].lamports).toBe(42 - feeCalculator.lamportsPerSignature);
} else {
expect(element[1].lamports).toBe(84 - feeCalculator.lamportsPerSignature);
}
});
});
test('fullnodeExit', async () => {
if (!mockRpcEnabled) {
console.log('fullnodeExit skipped on live node');