-
Notifications
You must be signed in to change notification settings - Fork 772
/
transaction.ts
88 lines (80 loc) · 3.16 KB
/
transaction.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import { Signature } from '@solana/keys';
import { Commitment, Slot } from '@solana/rpc-types';
import { ArgumentNode, GraphQLResolveInfo } from 'graphql';
import { BlockLoaderArgs, TransactionLoaderArgs } from '../../loaders';
import { injectableRootVisitor } from './visitor';
function findArgumentNodeByName(argumentNodes: readonly ArgumentNode[], name: string): ArgumentNode | undefined {
return argumentNodes.find(argumentNode => argumentNode.name.value === name);
}
function parseTransactionEncodingArgument(
argumentNodes: readonly ArgumentNode[],
variableValues: {
[variable: string]: unknown;
},
): TransactionLoaderArgs['encoding'] | undefined {
const argumentNode = findArgumentNodeByName(argumentNodes, 'encoding');
if (argumentNode) {
if (argumentNode.value.kind === 'EnumValue') {
if (argumentNode.value.value === 'BASE_58') {
return 'base58';
}
if (argumentNode.value.value === 'BASE_64') {
return 'base64';
}
}
if (argumentNode.value.kind === 'Variable') {
return variableValues[argumentNode.value.name.value] as TransactionLoaderArgs['encoding'];
}
} else {
return undefined;
}
}
export function buildTransactionArgSetWithVisitor<TArgs extends BlockLoaderArgs | TransactionLoaderArgs>(
args: TArgs,
info: GraphQLResolveInfo,
): TArgs[] {
const argSet = [args];
function buildArgSetWithVisitor(root: Parameters<typeof injectableRootVisitor>[1]) {
injectableRootVisitor(info, root, {
fieldNodeOperation(info, node) {
if (node.name.value === 'message' || node.name.value === 'meta') {
argSet.push({ ...args, encoding: 'jsonParsed' });
} else if (node.name.value === 'data') {
// At least `encoding` is required on the `data` field.
if (node.arguments) {
const { variableValues } = info;
const encoding: TransactionLoaderArgs['encoding'] = parseTransactionEncodingArgument(
node.arguments,
variableValues,
);
argSet.push({ ...args, encoding });
}
}
},
fragmentSpreadNodeOperation(_info, fragment) {
buildArgSetWithVisitor(fragment);
},
inlineFragmentNodeOperation(_info, _node) {
// Transaction schema doesn't support inline fragments at the
// root level.
return;
},
});
}
buildArgSetWithVisitor(null);
return argSet;
}
/**
* Build a set of transaction loader args by inspecting which fields have
* been requested in the query (ie. `data` or inline fragments).
*/
export function buildTransactionLoaderArgSetFromResolveInfo(
args: {
commitment?: Omit<Commitment, 'processed'>;
minContextSlot?: Slot;
signature: Signature;
},
info: GraphQLResolveInfo,
): TransactionLoaderArgs[] {
return buildTransactionArgSetWithVisitor(args, info);
}