Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

Commit

Permalink
refactor(experimental): use GraphQL lang for schema
Browse files Browse the repository at this point in the history
  • Loading branch information
buffalojoec committed Nov 11, 2023
1 parent 1b5ebd6 commit 970a3e3
Show file tree
Hide file tree
Showing 38 changed files with 3,341 additions and 5,892 deletions.
274 changes: 127 additions & 147 deletions packages/rpc-graphql/README.md

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion packages/rpc-graphql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,16 @@
"maintained node versions"
],
"dependencies": {
"@graphql-tools/schema": "^10.0.0",
"graphql": "^16.8.0"
},
"devDependencies": {
"@solana/addresses": "workspace:*",
"@solana/eslint-config-solana": "^1.0.2",
"@solana/keys": "workspace:*",
"@solana/rpc-core": "workspace:*",
"@solana/rpc-types": "workspace:*",
"@solana/rpc-transport": "workspace:*",
"@solana/rpc-types": "workspace:*",
"@solana/transactions": "workspace:*",
"@swc/jest": "^0.2.29",
"@types/jest": "^29.5.6",
Expand Down
148 changes: 102 additions & 46 deletions packages/rpc-graphql/src/__tests__/account-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ describe('account', () => {
// See scripts/fixtures/spl-token-token-account.json
const variableValues = {
address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',
commitment: 'confirmed',
};
it("can query an account's lamports balance", async () => {
expect.assertions(1);
Expand Down Expand Up @@ -252,14 +251,14 @@ describe('account', () => {
encoding: 'base64',
};
const source = `
query testQuery($address: String!, $encoding: AccountEncoding) {
account(address: $address, encoding: $encoding) {
... on AccountBase64 {
data
query testQuery($address: String!, $encoding: AccountEncoding) {
account(address: $address, encoding: $encoding) {
... on AccountBase64 {
data
}
}
}
}
`;
`;
const result = await rpcGraphQL.query(source, variableValues);
expect(result).toMatchObject({
data: {
Expand All @@ -276,43 +275,11 @@ describe('account', () => {
address: 'CcYNb7WqpjaMrNr7B1mapaNfWctZRH7LyAjWRLBGt1Fk',
encoding: 'base64Zstd',
};
const source = `
query testQuery($address: String!, $encoding: AccountEncoding) {
account(address: $address, encoding: $encoding) {
... on AccountBase64Zstd {
data
}
}
}
`;
const result = await rpcGraphQL.query(source, variableValues);
expect(result).toMatchObject({
data: {
account: {
data: 'KLUv/QBYSQAAdGVzdCBkYXRh',
},
},
});
});
});
describe('nested account data queries', () => {
it('can get nested account data as base64', async () => {
expect.assertions(1);
// See scripts/fixtures/spl-token-token-account.json
const variableValues = {
address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',
encoding: 'base64',
};
const source = `
query testQuery($address: String!, $encoding: AccountEncoding) {
account(address: $address, encoding: $encoding) {
... on AccountBase64 {
... on AccountBase64Zstd {
data
owner(encoding: $encoding) {
... on AccountBase64 {
data
}
}
}
}
}
Expand All @@ -321,15 +288,47 @@ describe('account', () => {
expect(result).toMatchObject({
data: {
account: {
data: '6Sg5VQll/9TWSsqvRtRd9zGOW09XyQxIfWBiXYKbg3tRbfSo3iE5g7lQFUZzej7dXNBFemsx9mHsHQF64UlEQ+BvnGLyhiMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
owner: {
data: expect.any(String),
},
data: 'KLUv/QBYSQAAdGVzdCBkYXRh',
},
},
});
});
});
// describe('nested account data queries', () => {
// it('can get nested account data as base64', async () => {
// expect.assertions(1);
// // See scripts/fixtures/spl-token-token-account.json
// const variableValues = {
// address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',
// encoding: 'base64',
// };
// const source = `
// query testQuery($address: String!, $encoding: AccountEncoding) {
// account(address: $address, encoding: $encoding) {
// ... on AccountBase64 {
// data
// owner(encoding: $encoding) {
// ... on AccountBase64 {
// data
// }
// }
// }
// }
// }
// `;
// const result = await rpcGraphQL.query(source, variableValues);
// expect(result).toMatchObject({
// data: {
// account: {
// data: '6Sg5VQll/9TWSsqvRtRd9zGOW09XyQxIfWBiXYKbg3tRbfSo3iE5g7lQFUZzej7dXNBFemsx9mHsHQF64UlEQ+BvnGLyhiMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
// owner: {
// data: expect.any(String),
// },
// },
// },
// });
// });
// });
describe('specific account type queries', () => {
it('can get a mint account', async () => {
expect.assertions(1);
Expand Down Expand Up @@ -393,7 +392,9 @@ describe('account', () => {
... on TokenAccount {
data {
isNative
mint
mint {
address
}
owner {
address
}
Expand All @@ -420,7 +421,9 @@ describe('account', () => {
account: {
data: {
isNative: expect.any(Boolean),
mint: expect.any(String),
mint: {
address: expect.any(String),
},
owner: {
address: '6UsGbaMgchgj4wiwKKuE1v5URHdcDfEiMSM25QpesKir',
},
Expand Down Expand Up @@ -786,4 +789,57 @@ describe('account', () => {
});
});
});
// describe('when querying only an address', () => {
// describe('in the first level', () => {
// it('will not call the RPC for only an address', async () => {
// expect.assertions(1);
// const source = `
// query testQuery {
// account(address: "AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca") {
// address
// }
// }
// `;
// await rpcGraphQL.query(source);
// expect(fetchMock).not.toHaveBeenCalled();
// });
// });
// describe('in the second level', () => {
// it('will not call the RPC for only an address', async () => {
// expect.assertions(1);
// const source = `
// query testQuery {
// account(address: "AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca") {
// address
// owner {
// address
// }
// }
// }
// `;
// await rpcGraphQL.query(source);
// expect(fetchMock).toHaveBeenCalledTimes(1);
// });
// });
// describe('in the third level', () => {
// it('will not call the RPC for only an address', async () => {
// expect.assertions(1);
// const source = `
// query testQuery {
// account(address: "AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca") {
// address
// owner {
// address
// owner {
// address
// }
// }
// }
// }
// `;
// await rpcGraphQL.query(source);
// expect(fetchMock).toHaveBeenCalledTimes(2);
// });
// });
// });
});
8 changes: 6 additions & 2 deletions packages/rpc-graphql/src/__tests__/program-accounts-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,9 @@ describe('programAccounts', () => {
... on TokenAccount {
data {
isNative
mint
mint {
address
}
owner {
address
}
Expand Down Expand Up @@ -293,7 +295,9 @@ describe('programAccounts', () => {
{
data: {
isNative: expect.any(Boolean),
mint: expect.any(String),
mint: {
address: expect.any(String),
},
owner: {
address: expect.any(String),
},
Expand Down
48 changes: 26 additions & 22 deletions packages/rpc-graphql/src/context.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,45 @@
import { SolanaRpcMethods } from '@solana/rpc-core';
import { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';
import { GraphQLResolveInfo } from 'graphql';

import { createGraphQLCache, GraphQLCache } from './cache';
import { resolveAccount } from './resolvers/account';
import { resolveBlock } from './resolvers/block';
import { resolveProgramAccounts } from './resolvers/program-accounts';
import { resolveTransaction } from './resolvers/transaction';
import { AccountQueryArgs } from './schema/account/query';
import { loadAccount } from './loaders/account';
import { loadBlock } from './loaders/block';
import { loadProgramAccounts } from './loaders/program-accounts';
import { loadTransaction } from './loaders/transaction';
import { createRpcGraphQL } from './rpc';
import { AccountQueryArgs } from './schema/account';
import { BlockQueryArgs } from './schema/block';
import { ProgramAccountsQueryArgs } from './schema/program-accounts';
import { TransactionQueryArgs } from './schema/transaction/query';
import { TransactionQueryArgs } from './schema/transaction';

export type Rpc = Parameters<typeof createRpcGraphQL>[0];

export interface RpcGraphQLContext {
cache: GraphQLCache;
resolveAccount(args: AccountQueryArgs, info?: GraphQLResolveInfo): ReturnType<typeof resolveAccount>;
resolveBlock(args: BlockQueryArgs): ReturnType<typeof resolveBlock>;
resolveProgramAccounts(args: ProgramAccountsQueryArgs): ReturnType<typeof resolveProgramAccounts>;
resolveTransaction(args: TransactionQueryArgs): ReturnType<typeof resolveTransaction>;
rpc: Rpc<SolanaRpcMethods>;
loadAccount(args: AccountQueryArgs, info?: GraphQLResolveInfo): ReturnType<typeof loadAccount>;
loadBlock(args: BlockQueryArgs, info?: GraphQLResolveInfo): ReturnType<typeof loadBlock>;
loadProgramAccounts(
args: ProgramAccountsQueryArgs,
info?: GraphQLResolveInfo
): ReturnType<typeof loadProgramAccounts>;
loadTransaction(args: TransactionQueryArgs, info?: GraphQLResolveInfo): ReturnType<typeof loadTransaction>;
rpc: Rpc;
}

export function createSolanaGraphQLContext(rpc: Rpc<SolanaRpcMethods>): RpcGraphQLContext {
export function createSolanaGraphQLContext(rpc: Rpc): RpcGraphQLContext {
const cache = createGraphQLCache();
return {
cache,
resolveAccount(args, info?) {
return resolveAccount(args, this.cache, this.rpc, info);
loadAccount(args, info?) {
return loadAccount(args, this.cache, this.rpc, info);
},
resolveBlock(args) {
return resolveBlock(args, this.cache, this.rpc);
loadBlock(args, info?) {
return loadBlock(args, this.cache, this.rpc, info);
},
resolveProgramAccounts(args) {
return resolveProgramAccounts(args, this.cache, this.rpc);
loadProgramAccounts(args, info?) {
return loadProgramAccounts(args, this.cache, this.rpc, info);
},
resolveTransaction(args) {
return resolveTransaction(args, this.cache, this.rpc);
loadTransaction(args, info?) {
return loadTransaction(args, this.cache, this.rpc, info);
},
rpc,
};
Expand Down
Loading

0 comments on commit 970a3e3

Please sign in to comment.