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

Commit

Permalink
refactor(experimental): revise transactions schema (Part 1)
Browse files Browse the repository at this point in the history
This PR introduces a revised transaction schema for GraphQL.

⚠️ ‼️ Note: This is only a _light_ revision to the transaction schema. It will be _massively_ easier to review schema changes once the next PR in this stack is merged, and the types are written in pure GraphQL lang.
  • Loading branch information
buffalojoec authored Nov 11, 2023
1 parent e6fc977 commit e662875
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 236 deletions.
132 changes: 62 additions & 70 deletions packages/rpc-graphql/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -754,19 +754,17 @@ const source = `
... on TransactionJsonParsed {
transaction {
message {
... on TransactionMessageParsed {
accountKeys {
pubkey
signer
source
writable
}
instructions {
... on PartiallyDecodedInstruction {
accounts
data
programId
}
accountKeys {
pubkey
signer
source
writable
}
instructions {
... on PartiallyDecodedInstruction {
accounts
data
programId
}
}
}
Expand Down Expand Up @@ -829,16 +827,14 @@ const source = `
... on TransactionJsonParsed {
transaction {
message {
... on TransactionMessageParsed {
instructions {
... on CreateAccountInstruction {
parsed {
info {
lamports
space
}
program
instructions {
... on CreateAccountInstruction {
parsed {
info {
lamports
space
}
program
}
}
}
Expand Down Expand Up @@ -934,57 +930,55 @@ const source = `
... on TransactionJsonParsed {
transaction {
message {
... on TransactionMessageParsed {
instructions {
... on SplTokenTransferInstruction {
parsed {
info {
amount
authority {
address
lamports
}
destination {
... on TokenAccount {
data {
address
mint {
... on MintAccount {
data {
address
decimals
}
instructions {
... on SplTokenTransferInstruction {
parsed {
info {
amount
authority {
address
lamports
}
destination {
... on TokenAccount {
data {
address
mint {
... on MintAccount {
data {
address
decimals
}
}
owner {
address
lamports
}
}
owner {
address
lamports
}
}
}
source {
... on TokenAccount {
data {
address
mint {
... on MintAccount {
data {
address
decimals
}
}
source {
... on TokenAccount {
data {
address
mint {
... on MintAccount {
data {
address
decimals
}
}
owner {
address
lamports
}
}
owner {
address
lamports
}
}
}
}
program
}
program
}
}
}
Expand Down Expand Up @@ -1080,16 +1074,14 @@ const source = `
... on TransactionJsonParsed {
transaction {
message {
... on TransactionMessageParsed {
instructions {
... on CreateAccountInstruction {
parsed {
info {
lamports
space
}
program
instructions {
... on CreateAccountInstruction {
parsed {
info {
lamports
space
}
program
}
}
}
Expand Down
71 changes: 2 additions & 69 deletions packages/rpc-graphql/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ 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 { BlockQueryArgs } from './schema/block';
import { ProgramAccountsQueryArgs } from './schema/program-accounts';
Expand All @@ -19,75 +21,6 @@ export interface RpcGraphQLContext {
rpc: Rpc<SolanaRpcMethods>;
}

async function resolveBlock(
{ slot, encoding = 'jsonParsed', ...config }: BlockQueryArgs,
cache: GraphQLCache,
rpc: Rpc<SolanaRpcMethods>
) {
const requestConfig = { encoding, ...config };

const cached = cache.get(slot, config);
if (cached !== null) {
return cached;
}

const block = await rpc.getBlock(slot, requestConfig as Parameters<SolanaRpcMethods['getBlock']>[1]).send();

if (block === null) {
return null;
}

cache.insert(slot, config, block);

return block;
}

async function resolveTransaction(
{ signature, encoding = 'jsonParsed', ...config }: TransactionQueryArgs,
cache: GraphQLCache,
rpc: Rpc<SolanaRpcMethods>
) {
const requestConfig = { encoding, ...config };

const cached = cache.get(signature, requestConfig);
if (cached !== null) {
return cached;
}

const transaction = await rpc
.getTransaction(signature, requestConfig as Parameters<SolanaRpcMethods['getTransaction']>[1])
.send();

if (transaction === null) {
return null;
}

const [transactionData, responseEncoding, responseFormat] = Array.isArray(transaction.transaction)
? encoding === 'jsonParsed'
? [transaction.transaction[0], 'base64', 'unparsed']
: [transaction.transaction[0], encoding, 'unparsed']
: encoding === 'jsonParsed'
? [transaction.transaction, encoding, 'parsed']
: [transaction.transaction, encoding, 'unparsed'];
if (transaction.meta) {
// Ugly, but tells TypeScript what's happening
(transaction.meta as { format?: string } & { [key: string]: unknown })['format'] = responseFormat;
}
if (transactionData.message) {
// Ugly, but tells TypeScript what's happening
(transactionData.message as { format?: string } & { [key: string]: unknown })['format'] = responseFormat;
}
const queryResponse = {
...transaction,
encoding: responseEncoding,
transaction: transactionData,
};

cache.insert(signature, requestConfig, queryResponse);

return queryResponse;
}

export function createSolanaGraphQLContext(rpc: Rpc<SolanaRpcMethods>): RpcGraphQLContext {
const cache = createGraphQLCache();
return {
Expand Down
30 changes: 30 additions & 0 deletions packages/rpc-graphql/src/resolvers/block.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { SolanaRpcMethods } from '@solana/rpc-core';
import { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';

import { GraphQLCache } from '../cache';
import { BlockQueryArgs } from '../schema/block';

export async function resolveBlock(
{ slot, encoding = 'jsonParsed', ...config }: BlockQueryArgs,
cache: GraphQLCache,
rpc: Rpc<SolanaRpcMethods>
) {
const requestConfig = { encoding, ...config };

const cached = cache.get(slot, config);
if (cached !== null) {
return cached;
}

const block = await rpc
.getBlock(slot, requestConfig as unknown as Parameters<SolanaRpcMethods['getBlock']>[1])
.send();

if (block === null) {
return null;
}

cache.insert(slot, config, block);

return block;
}
51 changes: 51 additions & 0 deletions packages/rpc-graphql/src/resolvers/transaction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { SolanaRpcMethods } from '@solana/rpc-core';
import { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';

import { GraphQLCache } from '../cache';
import { TransactionQueryArgs } from '../schema/transaction';

export async function resolveTransaction(
{ signature, encoding = 'jsonParsed', ...config }: TransactionQueryArgs,
cache: GraphQLCache,
rpc: Rpc<SolanaRpcMethods>
) {
const requestConfig = { encoding, ...config };

const cached = cache.get(signature, requestConfig);
if (cached !== null) {
return cached;
}

const transaction = await rpc
.getTransaction(signature, requestConfig as unknown as Parameters<SolanaRpcMethods['getTransaction']>[1])
.send();

if (transaction === null) {
return null;
}

const [transactionData, responseEncoding, responseFormat] = Array.isArray(transaction.transaction)
? encoding === 'jsonParsed'
? [transaction.transaction[0], 'base64', 'unparsed']
: [transaction.transaction[0], encoding, 'unparsed']
: encoding === 'jsonParsed'
? [transaction.transaction, encoding, 'parsed']
: [transaction.transaction, encoding, 'unparsed'];
if (transaction.meta) {
// Ugly, but tells TypeScript what's happening
(transaction.meta as { format?: string } & { [key: string]: unknown })['format'] = responseFormat;
}
if (transactionData.message) {
// Ugly, but tells TypeScript what's happening
(transactionData.message as { format?: string } & { [key: string]: unknown })['format'] = responseFormat;
}
const queryResponse = {
...transaction,
encoding: responseEncoding,
transaction: transactionData,
};

cache.insert(signature, requestConfig, queryResponse);

return queryResponse;
}
2 changes: 1 addition & 1 deletion packages/rpc-graphql/src/schema/block/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { blockInterface } from './types';
export type BlockQueryArgs = {
slot: Slot;
commitment?: Commitment;
encoding?: 'base58' | 'base64' | 'json' | 'jsonParsed';
encoding?: 'base58' | 'base64' | 'jsonParsed';
maxSupportedTransactionVersion?: Exclude<TransactionVersion, 'legacy'>;
rewards?: boolean;
transactionDetails?: 'accounts' | 'full' | 'none' | 'signatures';
Expand Down
3 changes: 0 additions & 3 deletions packages/rpc-graphql/src/schema/inputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,6 @@ export const transactionEncodingInputType = () => {
base64: {
value: 'base64',
},
json: {
value: 'json',
},
jsonParsed: {
value: 'jsonParsed',
},
Expand Down
2 changes: 1 addition & 1 deletion packages/rpc-graphql/src/schema/transaction/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { transactionInterface } from './types';
export type TransactionQueryArgs = {
signature: Signature;
commitment?: Commitment;
encoding?: 'base58' | 'base64' | 'json' | 'jsonParsed';
encoding?: 'base58' | 'base64' | 'jsonParsed';
maxSupportedTransactionVersion?: Exclude<TransactionVersion, 'legacy'>;
};

Expand Down
Loading

0 comments on commit e662875

Please sign in to comment.