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

refactor(experimental): revise transactions schema (Part 1) #1818

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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