@metaplex-foundation/kinobi 0.6.0 → 0.7.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/nodes/InstructionNode.js +53 -15
- package/dist/cjs/nodes/InstructionNode.js.map +1 -1
- package/dist/cjs/renderers/js/GetJavaScriptRenderMapVisitor.js +77 -27
- package/dist/cjs/renderers/js/GetJavaScriptRenderMapVisitor.js.map +1 -1
- package/dist/cjs/renderers/js/GetJavaScriptTypeManifestVisitor.js +3 -0
- package/dist/cjs/renderers/js/GetJavaScriptTypeManifestVisitor.js.map +1 -1
- package/dist/cjs/renderers/js/GetJavaScriptValidatorBagVisitor.js +2 -0
- package/dist/cjs/renderers/js/GetJavaScriptValidatorBagVisitor.js.map +1 -1
- package/dist/cjs/renderers/js/templates/instructionsPage.njk +11 -24
- package/dist/cjs/renderers/js/templates/instructionsPageAccountMetas.njk +8 -51
- package/dist/cjs/renderers/js/templates/instructionsPageArgs.njk +34 -5
- package/dist/cjs/renderers/js/templates/instructionsPageResolvedInputs.njk +63 -0
- package/dist/cjs/visitors/BaseNodeOrNullVisitor.js +6 -1
- package/dist/cjs/visitors/BaseNodeOrNullVisitor.js.map +1 -1
- package/dist/cjs/visitors/BaseNodeVisitor.js +6 -1
- package/dist/cjs/visitors/BaseNodeVisitor.js.map +1 -1
- package/dist/cjs/visitors/BaseVoidVisitor.js +2 -0
- package/dist/cjs/visitors/BaseVoidVisitor.js.map +1 -1
- package/dist/cjs/visitors/aggregators/GetDefaultValidatorBagVisitor.js +32 -2
- package/dist/cjs/visitors/aggregators/GetDefaultValidatorBagVisitor.js.map +1 -1
- package/dist/cjs/visitors/aggregators/GetNodeInlineStringVisitor.js +4 -2
- package/dist/cjs/visitors/aggregators/GetNodeInlineStringVisitor.js.map +1 -1
- package/dist/cjs/visitors/aggregators/GetNodeTreeStringVisitor.js +6 -0
- package/dist/cjs/visitors/aggregators/GetNodeTreeStringVisitor.js.map +1 -1
- package/dist/cjs/visitors/aggregators/GetResolvedInstructionInputsVisitor.js +201 -0
- package/dist/cjs/visitors/aggregators/GetResolvedInstructionInputsVisitor.js.map +1 -0
- package/dist/cjs/visitors/aggregators/index.js +1 -1
- package/dist/cjs/visitors/aggregators/index.js.map +1 -1
- package/dist/cjs/visitors/transformers/AutoSetAnchorDiscriminatorsVisitor.js +1 -1
- package/dist/cjs/visitors/transformers/AutoSetAnchorDiscriminatorsVisitor.js.map +1 -1
- package/dist/cjs/visitors/transformers/CreateSubInstructionsFromEnumArgsVisitor.js +2 -2
- package/dist/cjs/visitors/transformers/CreateSubInstructionsFromEnumArgsVisitor.js.map +1 -1
- package/dist/cjs/visitors/transformers/FlattenInstructionArgsStructVisitor.js +1 -1
- package/dist/cjs/visitors/transformers/FlattenInstructionArgsStructVisitor.js.map +1 -1
- package/dist/cjs/visitors/transformers/SetInstructionAccountDefaultValuesVisitor.js +1 -1
- package/dist/cjs/visitors/transformers/SetInstructionAccountDefaultValuesVisitor.js.map +1 -1
- package/dist/cjs/visitors/transformers/SetInstructionDiscriminatorsVisitor.js +1 -1
- package/dist/cjs/visitors/transformers/SetInstructionDiscriminatorsVisitor.js.map +1 -1
- package/dist/cjs/visitors/transformers/UpdateInstructionsVisitor.js +8 -5
- package/dist/cjs/visitors/transformers/UpdateInstructionsVisitor.js.map +1 -1
- package/dist/cjs/visitors/transformers/UseCustomInstructionSerializerVisitor.js +1 -1
- package/dist/cjs/visitors/transformers/UseCustomInstructionSerializerVisitor.js.map +1 -1
- package/dist/types/idl/IdlInstruction.d.ts +0 -1
- package/dist/types/nodes/InstructionNode.d.ts +53 -14
- package/dist/types/renderers/js/GetJavaScriptRenderMapVisitor.d.ts +10 -2
- package/dist/types/renderers/js/GetJavaScriptTypeManifestVisitor.d.ts +1 -0
- package/dist/types/visitors/aggregators/GetResolvedInstructionInputsVisitor.d.ts +41 -0
- package/dist/types/visitors/aggregators/index.d.ts +1 -1
- package/dist/types/visitors/transformers/UpdateInstructionsVisitor.d.ts +7 -2
- package/package.json +1 -1
- package/src/idl/IdlInstruction.ts +0 -1
- package/src/nodes/InstructionNode.ts +99 -21
- package/src/renderers/js/GetJavaScriptRenderMapVisitor.ts +99 -36
- package/src/renderers/js/GetJavaScriptTypeManifestVisitor.ts +6 -0
- package/src/renderers/js/GetJavaScriptValidatorBagVisitor.ts +2 -0
- package/src/renderers/js/templates/instructionsPage.njk +11 -24
- package/src/renderers/js/templates/instructionsPageAccountMetas.njk +8 -51
- package/src/renderers/js/templates/instructionsPageArgs.njk +34 -5
- package/src/renderers/js/templates/instructionsPageResolvedInputs.njk +63 -0
- package/src/visitors/BaseNodeOrNullVisitor.ts +5 -0
- package/src/visitors/BaseNodeVisitor.ts +5 -0
- package/src/visitors/BaseVoidVisitor.ts +1 -0
- package/src/visitors/aggregators/GetDefaultValidatorBagVisitor.ts +48 -2
- package/src/visitors/aggregators/GetNodeInlineStringVisitor.ts +3 -2
- package/src/visitors/aggregators/GetNodeTreeStringVisitor.ts +6 -0
- package/src/visitors/aggregators/GetResolvedInstructionInputsVisitor.ts +275 -0
- package/src/visitors/aggregators/index.ts +1 -1
- package/src/visitors/transformers/AutoSetAnchorDiscriminatorsVisitor.ts +1 -0
- package/src/visitors/transformers/CreateSubInstructionsFromEnumArgsVisitor.ts +2 -0
- package/src/visitors/transformers/FlattenInstructionArgsStructVisitor.ts +1 -0
- package/src/visitors/transformers/SetInstructionAccountDefaultValuesVisitor.ts +1 -0
- package/src/visitors/transformers/SetInstructionDiscriminatorsVisitor.ts +1 -0
- package/src/visitors/transformers/UpdateInstructionsVisitor.ts +19 -14
- package/src/visitors/transformers/UseCustomInstructionSerializerVisitor.ts +1 -0
- package/dist/cjs/visitors/aggregators/GetResolvedInstructionAccountsVisitor.js +0 -123
- package/dist/cjs/visitors/aggregators/GetResolvedInstructionAccountsVisitor.js.map +0 -1
- package/dist/types/visitors/aggregators/GetResolvedInstructionAccountsVisitor.d.ts +0 -18
- package/src/visitors/aggregators/GetResolvedInstructionAccountsVisitor.ts +0 -155
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type * as nodes from '../../nodes';
|
|
2
|
+
import { BaseThrowVisitor } from '../BaseThrowVisitor';
|
|
3
|
+
type InstructionNodeInput = ({
|
|
4
|
+
kind: 'arg';
|
|
5
|
+
} & InstructionNodeArg) | ({
|
|
6
|
+
kind: 'account';
|
|
7
|
+
} & nodes.InstructionNodeAccount);
|
|
8
|
+
type InstructionNodeArg = {
|
|
9
|
+
name: string;
|
|
10
|
+
defaultsTo: nodes.InstructionNodeArgDefaults;
|
|
11
|
+
};
|
|
12
|
+
export type ResolvedInstructionAccount = nodes.InstructionNodeAccount & {
|
|
13
|
+
kind: 'account';
|
|
14
|
+
isPda: boolean;
|
|
15
|
+
dependsOn: nodes.InstructionNodeInputDependency[];
|
|
16
|
+
resolvedIsSigner: boolean | 'either';
|
|
17
|
+
resolvedIsOptional: boolean;
|
|
18
|
+
};
|
|
19
|
+
export type ResolvedInstructionArg = InstructionNodeArg & {
|
|
20
|
+
kind: 'arg';
|
|
21
|
+
dependsOn: nodes.InstructionNodeInputDependency[];
|
|
22
|
+
};
|
|
23
|
+
export type ResolvedInstructionInput = ResolvedInstructionAccount | ResolvedInstructionArg;
|
|
24
|
+
export declare class GetResolvedInstructionInputsVisitor extends BaseThrowVisitor<ResolvedInstructionInput[]> {
|
|
25
|
+
protected stack: InstructionNodeInput[];
|
|
26
|
+
protected resolved: ResolvedInstructionInput[];
|
|
27
|
+
protected visitedAccounts: Map<string, ResolvedInstructionAccount>;
|
|
28
|
+
protected visitedArgs: Map<string, ResolvedInstructionArg>;
|
|
29
|
+
protected error: string | null;
|
|
30
|
+
getError(): string | null;
|
|
31
|
+
visitInstruction(instruction: nodes.InstructionNode): ResolvedInstructionInput[];
|
|
32
|
+
resolveInstructionInput(instruction: nodes.InstructionNode, input: InstructionNodeInput): void;
|
|
33
|
+
resolveInstructionAccount(instruction: nodes.InstructionNode, account: nodes.InstructionNodeAccount & {
|
|
34
|
+
kind: 'account';
|
|
35
|
+
}): ResolvedInstructionAccount;
|
|
36
|
+
resolveInstructionArg(instruction: nodes.InstructionNode, arg: InstructionNodeArg & {
|
|
37
|
+
kind: 'arg';
|
|
38
|
+
}): ResolvedInstructionArg;
|
|
39
|
+
resolveInstructionDependencies(instruction: nodes.InstructionNode, parent: InstructionNodeInput, dependencies: nodes.InstructionNodeInputDependency[]): void;
|
|
40
|
+
}
|
|
41
|
+
export {};
|
|
@@ -3,4 +3,4 @@ export * from './GetDefaultValidatorBagVisitor';
|
|
|
3
3
|
export * from './GetDefinedTypeHistogramVisitor';
|
|
4
4
|
export * from './GetNodeInlineStringVisitor';
|
|
5
5
|
export * from './GetNodeTreeStringVisitor';
|
|
6
|
-
export * from './
|
|
6
|
+
export * from './GetResolvedInstructionInputsVisitor';
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as nodes from '../../nodes';
|
|
2
|
+
import { Dependency } from '../Dependency';
|
|
2
3
|
import { InstructionNodeAccountDefaultsInput } from './SetInstructionAccountDefaultValuesVisitor';
|
|
3
4
|
import { NodeTransformer, TransformNodesVisitor } from './TransformNodesVisitor';
|
|
4
5
|
export type InstructionUpdates = NodeTransformer<nodes.InstructionNode> | {
|
|
5
6
|
delete: true;
|
|
6
7
|
} | (InstructionMetadataUpdates & {
|
|
7
|
-
accounts?: InstructionAccountUpdates;
|
|
8
8
|
args?: Record<string, string>;
|
|
9
|
+
extraArgs?: nodes.TypeStructNode | nodes.TypeDefinedLinkNode | null;
|
|
9
10
|
});
|
|
10
11
|
export type InstructionMetadataUpdates = Partial<Omit<nodes.InstructionNodeMetadata, 'bytesCreatedOnChain'> & {
|
|
11
12
|
bytesCreatedOnChain: InstructionNodeBytesCreatedOnChainInput | null;
|
|
@@ -25,8 +26,12 @@ type InstructionNodeBytesCreatedOnChainInput = {
|
|
|
25
26
|
} | {
|
|
26
27
|
kind: 'account';
|
|
27
28
|
name: string;
|
|
28
|
-
dependency?:
|
|
29
|
+
dependency?: Dependency;
|
|
29
30
|
includeHeader?: boolean;
|
|
31
|
+
} | {
|
|
32
|
+
kind: 'resolver';
|
|
33
|
+
name: string;
|
|
34
|
+
dependency?: Dependency;
|
|
30
35
|
};
|
|
31
36
|
export declare class UpdateInstructionsVisitor extends TransformNodesVisitor {
|
|
32
37
|
readonly map: Record<string, InstructionUpdates>;
|
package/package.json
CHANGED
|
@@ -17,6 +17,7 @@ export type InstructionNodeMetadata = {
|
|
|
17
17
|
docs: string[];
|
|
18
18
|
internal: boolean;
|
|
19
19
|
bytesCreatedOnChain: InstructionNodeBytesCreatedOnChain | null;
|
|
20
|
+
argDefaults: Record<string, InstructionNodeArgDefaults>;
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
export type InstructionNodeAccount = {
|
|
@@ -26,10 +27,28 @@ export type InstructionNodeAccount = {
|
|
|
26
27
|
isOptional: boolean;
|
|
27
28
|
description: string;
|
|
28
29
|
defaultsTo: InstructionNodeAccountDefaults | null;
|
|
29
|
-
pdaBumpArg: string | null;
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
+
export type InstructionNodeInputDependency = {
|
|
33
|
+
kind: 'account' | 'arg';
|
|
34
|
+
name: string;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type InstructionNodeArgDefaults =
|
|
38
|
+
| { kind: 'arg'; name: string }
|
|
39
|
+
| { kind: 'account'; name: string }
|
|
40
|
+
| { kind: 'accountBump'; name: string }
|
|
41
|
+
| { kind: 'value'; value: ValueNode }
|
|
42
|
+
| {
|
|
43
|
+
kind: 'resolver';
|
|
44
|
+
name: string;
|
|
45
|
+
dependency: Dependency;
|
|
46
|
+
dependsOn: InstructionNodeInputDependency[];
|
|
47
|
+
};
|
|
48
|
+
|
|
32
49
|
export type InstructionNodeAccountDefaults =
|
|
50
|
+
| { kind: 'programId' }
|
|
51
|
+
| { kind: 'program'; program: { name: string; publicKey: string } }
|
|
33
52
|
| { kind: 'publicKey'; publicKey: string }
|
|
34
53
|
| { kind: 'account'; name: string }
|
|
35
54
|
| { kind: 'identity' }
|
|
@@ -40,8 +59,14 @@ export type InstructionNodeAccountDefaults =
|
|
|
40
59
|
dependency: Dependency;
|
|
41
60
|
seeds: Record<string, InstructionNodeAccountDefaultsSeed>;
|
|
42
61
|
}
|
|
43
|
-
| {
|
|
44
|
-
|
|
62
|
+
| {
|
|
63
|
+
kind: 'resolver';
|
|
64
|
+
name: string;
|
|
65
|
+
dependency: Dependency;
|
|
66
|
+
resolvedIsSigner: boolean | 'either';
|
|
67
|
+
resolvedIsOptional: boolean;
|
|
68
|
+
dependsOn: InstructionNodeInputDependency[];
|
|
69
|
+
};
|
|
45
70
|
|
|
46
71
|
export type InstructionNodeAccountDefaultsSeed =
|
|
47
72
|
| { kind: 'account'; name: string }
|
|
@@ -54,9 +79,10 @@ export type InstructionNodeBytesCreatedOnChain =
|
|
|
54
79
|
| {
|
|
55
80
|
kind: 'account';
|
|
56
81
|
name: string;
|
|
57
|
-
dependency:
|
|
82
|
+
dependency: Dependency;
|
|
58
83
|
includeHeader: boolean;
|
|
59
|
-
}
|
|
84
|
+
}
|
|
85
|
+
| { kind: 'resolver'; name: string; dependency: Dependency };
|
|
60
86
|
|
|
61
87
|
export class InstructionNode implements Visitable {
|
|
62
88
|
readonly nodeClass = 'InstructionNode' as const;
|
|
@@ -67,12 +93,15 @@ export class InstructionNode implements Visitable {
|
|
|
67
93
|
|
|
68
94
|
readonly args: TypeStructNode | TypeDefinedLinkNode;
|
|
69
95
|
|
|
96
|
+
readonly extraArgs: TypeStructNode | TypeDefinedLinkNode | null;
|
|
97
|
+
|
|
70
98
|
readonly subInstructions: InstructionNode[];
|
|
71
99
|
|
|
72
100
|
constructor(
|
|
73
101
|
metadata: InstructionNodeMetadata,
|
|
74
102
|
accounts: InstructionNodeAccount[],
|
|
75
103
|
args: InstructionNode['args'],
|
|
104
|
+
extraArgs: InstructionNode['extraArgs'],
|
|
76
105
|
subInstructions: InstructionNode[]
|
|
77
106
|
) {
|
|
78
107
|
const bytes = metadata.bytesCreatedOnChain;
|
|
@@ -83,6 +112,21 @@ export class InstructionNode implements Visitable {
|
|
|
83
112
|
bytes && 'name' in bytes
|
|
84
113
|
? { ...bytes, name: mainCase(bytes.name) }
|
|
85
114
|
: bytes,
|
|
115
|
+
argDefaults: Object.fromEntries(
|
|
116
|
+
Object.entries(metadata.argDefaults).map(([key, value]) => {
|
|
117
|
+
const newValue = { ...value };
|
|
118
|
+
if ('name' in newValue) {
|
|
119
|
+
newValue.name = mainCase(newValue.name);
|
|
120
|
+
}
|
|
121
|
+
if (newValue.kind === 'resolver') {
|
|
122
|
+
newValue.dependsOn = newValue.dependsOn.map((dep) => ({
|
|
123
|
+
...dep,
|
|
124
|
+
name: mainCase(dep.name),
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
127
|
+
return [mainCase(key), newValue];
|
|
128
|
+
})
|
|
129
|
+
),
|
|
86
130
|
};
|
|
87
131
|
this.accounts = accounts.map((account) => {
|
|
88
132
|
const { defaultsTo } = account;
|
|
@@ -100,10 +144,17 @@ export class InstructionNode implements Visitable {
|
|
|
100
144
|
: { ...seed, name: mainCase(seed.name) },
|
|
101
145
|
])
|
|
102
146
|
);
|
|
147
|
+
} else if (defaultsTo?.kind === 'resolver') {
|
|
148
|
+
defaultsTo.name = mainCase(defaultsTo.name);
|
|
149
|
+
defaultsTo.dependsOn = defaultsTo.dependsOn.map((dep) => ({
|
|
150
|
+
...dep,
|
|
151
|
+
name: mainCase(dep.name),
|
|
152
|
+
}));
|
|
103
153
|
}
|
|
104
154
|
return { ...account, name: mainCase(account.name), defaultsTo };
|
|
105
155
|
});
|
|
106
156
|
this.args = args;
|
|
157
|
+
this.extraArgs = extraArgs;
|
|
107
158
|
this.subInstructions = subInstructions;
|
|
108
159
|
}
|
|
109
160
|
|
|
@@ -118,6 +169,7 @@ export class InstructionNode implements Visitable {
|
|
|
118
169
|
docs: idl.docs ?? [],
|
|
119
170
|
internal: false,
|
|
120
171
|
bytesCreatedOnChain: null,
|
|
172
|
+
argDefaults: {},
|
|
121
173
|
};
|
|
122
174
|
|
|
123
175
|
const accounts = (idl.accounts ?? []).map(
|
|
@@ -135,7 +187,6 @@ export class InstructionNode implements Visitable {
|
|
|
135
187
|
isOptional && useProgramIdForOptionalAccounts
|
|
136
188
|
? { kind: 'programId' }
|
|
137
189
|
: null,
|
|
138
|
-
pdaBumpArg: account.pdaBumpArg ?? null,
|
|
139
190
|
};
|
|
140
191
|
}
|
|
141
192
|
);
|
|
@@ -164,7 +215,7 @@ export class InstructionNode implements Visitable {
|
|
|
164
215
|
]);
|
|
165
216
|
}
|
|
166
217
|
|
|
167
|
-
return new InstructionNode(metadata, accounts, args, []);
|
|
218
|
+
return new InstructionNode(metadata, accounts, args, null, []);
|
|
168
219
|
}
|
|
169
220
|
|
|
170
221
|
accept<T>(visitor: Visitor<T>): T {
|
|
@@ -186,20 +237,16 @@ export class InstructionNode implements Visitable {
|
|
|
186
237
|
return this.metadata.docs;
|
|
187
238
|
}
|
|
188
239
|
|
|
189
|
-
get
|
|
240
|
+
get hasLinkedArgs(): boolean {
|
|
190
241
|
return isTypeDefinedLinkNode(this.args);
|
|
191
242
|
}
|
|
192
243
|
|
|
193
|
-
get
|
|
194
|
-
return this.
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
get pdaAccounts(): InstructionNodeAccount[] {
|
|
198
|
-
return this.accounts.filter((account) => account.pdaBumpArg !== null);
|
|
244
|
+
get hasLinkedExtraArgs(): boolean {
|
|
245
|
+
return isTypeDefinedLinkNode(this.extraArgs);
|
|
199
246
|
}
|
|
200
247
|
|
|
201
|
-
get
|
|
202
|
-
return this.
|
|
248
|
+
get hasAccounts(): boolean {
|
|
249
|
+
return this.accounts.length > 0;
|
|
203
250
|
}
|
|
204
251
|
|
|
205
252
|
get hasData(): boolean {
|
|
@@ -215,12 +262,43 @@ export class InstructionNode implements Visitable {
|
|
|
215
262
|
return nonOmittedFields.length > 0;
|
|
216
263
|
}
|
|
217
264
|
|
|
218
|
-
get
|
|
219
|
-
if (isTypeDefinedLinkNode(this.
|
|
220
|
-
const
|
|
221
|
-
|
|
265
|
+
get hasExtraArgs(): boolean {
|
|
266
|
+
if (isTypeDefinedLinkNode(this.extraArgs)) return true;
|
|
267
|
+
const nonOmittedFields =
|
|
268
|
+
this.extraArgs?.fields.filter(
|
|
269
|
+
(field) => field.metadata.defaultsTo?.strategy !== 'omitted'
|
|
270
|
+
) ?? [];
|
|
271
|
+
return nonOmittedFields.length > 0;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
get hasAnyArgs(): boolean {
|
|
275
|
+
return this.hasArgs || this.hasExtraArgs;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
get hasArgDefaults(): boolean {
|
|
279
|
+
return Object.keys(this.metadata.argDefaults).length > 0;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
get hasArgResolvers(): boolean {
|
|
283
|
+
return Object.values(this.metadata.argDefaults).some(
|
|
284
|
+
({ kind }) => kind === 'resolver'
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
get hasAccountResolvers(): boolean {
|
|
289
|
+
return this.accounts.some(
|
|
290
|
+
({ defaultsTo }) => defaultsTo?.kind === 'resolver'
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
get hasByteResolver(): boolean {
|
|
295
|
+
return this.metadata.bytesCreatedOnChain?.kind === 'resolver';
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
get hasResolvers(): boolean {
|
|
299
|
+
return (
|
|
300
|
+
this.hasArgResolvers || this.hasAccountResolvers || this.hasByteResolver
|
|
222
301
|
);
|
|
223
|
-
return requiredFields.length > 0;
|
|
224
302
|
}
|
|
225
303
|
}
|
|
226
304
|
|
|
@@ -6,9 +6,10 @@ import { camelCase, pascalCase } from '../../utils';
|
|
|
6
6
|
import {
|
|
7
7
|
Visitor,
|
|
8
8
|
BaseThrowVisitor,
|
|
9
|
-
|
|
10
|
-
ResolvedInstructionAccount,
|
|
9
|
+
GetResolvedInstructionInputsVisitor,
|
|
11
10
|
Dependency,
|
|
11
|
+
ResolvedInstructionInput,
|
|
12
|
+
ResolvedInstructionAccount,
|
|
12
13
|
} from '../../visitors';
|
|
13
14
|
import { RenderMap } from '../RenderMap';
|
|
14
15
|
import { resolveTemplate } from '../utils';
|
|
@@ -38,6 +39,9 @@ export type GetJavaScriptRenderMapOptions = {
|
|
|
38
39
|
setImportStrategy: (
|
|
39
40
|
importStrategy: 'all' | 'looseOnly' | 'strictOnly'
|
|
40
41
|
) => void;
|
|
42
|
+
setDefinedName: (
|
|
43
|
+
definedName: { strict: string; loose: string } | null
|
|
44
|
+
) => void;
|
|
41
45
|
};
|
|
42
46
|
};
|
|
43
47
|
|
|
@@ -46,9 +50,7 @@ export class GetJavaScriptRenderMapVisitor extends BaseThrowVisitor<RenderMap> {
|
|
|
46
50
|
|
|
47
51
|
private program: nodes.ProgramNode | null = null;
|
|
48
52
|
|
|
49
|
-
private
|
|
50
|
-
ResolvedInstructionAccount[]
|
|
51
|
-
>;
|
|
53
|
+
private resolvedInstructionInputVisitor: Visitor<ResolvedInstructionInput[]>;
|
|
52
54
|
|
|
53
55
|
constructor(options: GetJavaScriptRenderMapOptions = {}) {
|
|
54
56
|
super();
|
|
@@ -72,8 +74,8 @@ export class GetJavaScriptRenderMapVisitor extends BaseThrowVisitor<RenderMap> {
|
|
|
72
74
|
typeManifestVisitor:
|
|
73
75
|
options.typeManifestVisitor ?? new GetJavaScriptTypeManifestVisitor(),
|
|
74
76
|
};
|
|
75
|
-
this.
|
|
76
|
-
new
|
|
77
|
+
this.resolvedInstructionInputVisitor =
|
|
78
|
+
new GetResolvedInstructionInputsVisitor();
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
visitRoot(root: nodes.RootNode): RenderMap {
|
|
@@ -305,28 +307,42 @@ export class GetJavaScriptRenderMapVisitor extends BaseThrowVisitor<RenderMap> {
|
|
|
305
307
|
'transactionBuilder',
|
|
306
308
|
]);
|
|
307
309
|
|
|
308
|
-
//
|
|
309
|
-
const
|
|
310
|
-
.accept(this.
|
|
311
|
-
.map((
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
const { seeds } = account.defaultsTo;
|
|
310
|
+
// Resolved inputs.
|
|
311
|
+
const resolvedInputs = instruction
|
|
312
|
+
.accept(this.resolvedInstructionInputVisitor)
|
|
313
|
+
.map((input: ResolvedInstructionInput) => {
|
|
314
|
+
if (input.kind === 'account' && input.defaultsTo?.kind === 'pda') {
|
|
315
|
+
const { seeds } = input.defaultsTo;
|
|
315
316
|
Object.keys(seeds).forEach((seed: string) => {
|
|
316
317
|
const seedValue = seeds[seed];
|
|
317
318
|
if (seedValue.kind !== 'value') return;
|
|
318
|
-
const
|
|
319
|
-
(seedValue as any).render =
|
|
320
|
-
imports.mergeWith(
|
|
319
|
+
const valueManifest = renderJavaScriptValueNode(seedValue.value);
|
|
320
|
+
(seedValue as any).render = valueManifest.render;
|
|
321
|
+
imports.mergeWith(valueManifest.imports);
|
|
321
322
|
});
|
|
322
323
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
}
|
|
324
|
+
if (input.kind === 'arg' && input.defaultsTo.kind === 'value') {
|
|
325
|
+
const { defaultsTo } = input;
|
|
326
|
+
const valueManifest = renderJavaScriptValueNode(defaultsTo.value);
|
|
327
|
+
(defaultsTo as any).render = valueManifest.render;
|
|
328
|
+
imports.mergeWith(valueManifest.imports);
|
|
329
|
+
}
|
|
330
|
+
return input;
|
|
329
331
|
});
|
|
332
|
+
|
|
333
|
+
// Accounts.
|
|
334
|
+
const accounts = instruction.accounts.map((account) => {
|
|
335
|
+
const hasDefaultValue = !!account.defaultsTo;
|
|
336
|
+
const resolvedAccount = resolvedInputs.find(
|
|
337
|
+
(input) => input.kind === 'account' && input.name === account.name
|
|
338
|
+
) as ResolvedInstructionAccount;
|
|
339
|
+
return {
|
|
340
|
+
...resolvedAccount,
|
|
341
|
+
type: this.getInstructionAccountType(resolvedAccount),
|
|
342
|
+
optionalSign: hasDefaultValue || account.isOptional ? '?' : '',
|
|
343
|
+
hasDefaultValue,
|
|
344
|
+
};
|
|
345
|
+
});
|
|
330
346
|
imports.mergeWith(this.getInstructionAccountImports(accounts));
|
|
331
347
|
if (accounts.length > 0) {
|
|
332
348
|
imports
|
|
@@ -334,16 +350,41 @@ export class GetJavaScriptRenderMapVisitor extends BaseThrowVisitor<RenderMap> {
|
|
|
334
350
|
.addAlias('core', 'checkForIsWritableOverride', 'isWritable');
|
|
335
351
|
}
|
|
336
352
|
|
|
337
|
-
//
|
|
338
|
-
const
|
|
339
|
-
imports.mergeWith(
|
|
353
|
+
// Args.
|
|
354
|
+
const argManifest = instruction.accept(this.typeManifestVisitor);
|
|
355
|
+
imports.mergeWith(argManifest.imports);
|
|
340
356
|
if (!nodes.isTypeDefinedLinkNode(instruction.args) && instruction.hasData) {
|
|
341
357
|
imports.add('core', ['Serializer']);
|
|
342
358
|
}
|
|
343
359
|
|
|
360
|
+
// Extra args.
|
|
361
|
+
let extraArgManifest: JavaScriptTypeManifest | null = null;
|
|
362
|
+
if (instruction.extraArgs) {
|
|
363
|
+
this.typeManifestVisitor.setDefinedName({
|
|
364
|
+
strict: `${pascalCase(instruction.name)}InstructionExtra`,
|
|
365
|
+
loose: `${pascalCase(instruction.name)}InstructionExtraArgs`,
|
|
366
|
+
});
|
|
367
|
+
if (nodes.isTypeDefinedLinkNode(instruction.extraArgs)) {
|
|
368
|
+
this.typeManifestVisitor.setImportStrategy('looseOnly');
|
|
369
|
+
}
|
|
370
|
+
extraArgManifest = instruction.extraArgs.accept(this.typeManifestVisitor);
|
|
371
|
+
this.typeManifestVisitor.setDefinedName(null);
|
|
372
|
+
this.typeManifestVisitor.setImportStrategy('all');
|
|
373
|
+
imports.mergeWith(extraArgManifest.imports);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Arg defaults.
|
|
377
|
+
const argDefaultKeys = Object.keys(instruction.metadata.argDefaults);
|
|
378
|
+
const argDefaults = Object.values(instruction.metadata.argDefaults);
|
|
379
|
+
argDefaults.forEach((argDefault) => {
|
|
380
|
+
if (argDefault.kind === 'resolver') {
|
|
381
|
+
imports.add(argDefault.dependency, camelCase(argDefault.name));
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
|
|
344
385
|
// Bytes created on chain.
|
|
345
386
|
const bytes = instruction.metadata.bytesCreatedOnChain;
|
|
346
|
-
if (bytes && bytes.includeHeader) {
|
|
387
|
+
if (bytes && 'includeHeader' in bytes && bytes.includeHeader) {
|
|
347
388
|
imports.add('core', 'ACCOUNT_HEADER_SIZE');
|
|
348
389
|
}
|
|
349
390
|
if (bytes?.kind === 'account') {
|
|
@@ -353,6 +394,8 @@ export class GetJavaScriptRenderMapVisitor extends BaseThrowVisitor<RenderMap> {
|
|
|
353
394
|
? 'generatedAccounts'
|
|
354
395
|
: bytes.dependency;
|
|
355
396
|
imports.add(dependency, `get${accountName}Size`);
|
|
397
|
+
} else if (bytes?.kind === 'resolver') {
|
|
398
|
+
imports.add(bytes.dependency, camelCase(bytes.name));
|
|
356
399
|
}
|
|
357
400
|
|
|
358
401
|
// Remove imports from the same module.
|
|
@@ -364,7 +407,10 @@ export class GetJavaScriptRenderMapVisitor extends BaseThrowVisitor<RenderMap> {
|
|
|
364
407
|
|
|
365
408
|
// canMergeAccountsAndArgs
|
|
366
409
|
let canMergeAccountsAndArgs = false;
|
|
367
|
-
if (
|
|
410
|
+
if (
|
|
411
|
+
!nodes.isTypeDefinedLinkNode(instruction.args) &&
|
|
412
|
+
!nodes.isTypeDefinedLinkNode(instruction.extraArgs)
|
|
413
|
+
) {
|
|
368
414
|
const accountsAndArgsConflicts =
|
|
369
415
|
this.getMergeConflictsForInstructionAccountsAndArgs(instruction);
|
|
370
416
|
if (accountsAndArgsConflicts.length > 0) {
|
|
@@ -380,17 +426,25 @@ export class GetJavaScriptRenderMapVisitor extends BaseThrowVisitor<RenderMap> {
|
|
|
380
426
|
canMergeAccountsAndArgs = accountsAndArgsConflicts.length === 0;
|
|
381
427
|
}
|
|
382
428
|
|
|
429
|
+
const hasAccountDefaultKinds = (
|
|
430
|
+
kinds: Array<nodes.InstructionNodeAccountDefaults['kind']>
|
|
431
|
+
) =>
|
|
432
|
+
accounts.some((a) => a.defaultsTo && kinds.includes(a.defaultsTo.kind));
|
|
433
|
+
|
|
383
434
|
return new RenderMap().add(
|
|
384
435
|
`instructions/${camelCase(instruction.name)}.ts`,
|
|
385
436
|
this.render('instructionsPage.njk', {
|
|
386
437
|
instruction,
|
|
387
438
|
imports: imports.toString(this.options.dependencyMap),
|
|
388
439
|
program: this.program,
|
|
440
|
+
resolvedInputs,
|
|
389
441
|
accounts,
|
|
390
|
-
needsEddsa:
|
|
391
|
-
needsIdentity:
|
|
392
|
-
needsPayer:
|
|
393
|
-
|
|
442
|
+
needsEddsa: hasAccountDefaultKinds(['pda', 'resolver']),
|
|
443
|
+
needsIdentity: hasAccountDefaultKinds(['identity', 'resolver']),
|
|
444
|
+
needsPayer: hasAccountDefaultKinds(['payer', 'resolver']),
|
|
445
|
+
argDefaultKeys,
|
|
446
|
+
argManifest,
|
|
447
|
+
extraArgManifest,
|
|
394
448
|
canMergeAccountsAndArgs,
|
|
395
449
|
})
|
|
396
450
|
);
|
|
@@ -423,7 +477,7 @@ export class GetJavaScriptRenderMapVisitor extends BaseThrowVisitor<RenderMap> {
|
|
|
423
477
|
protected getInstructionAccountType(
|
|
424
478
|
account: ResolvedInstructionAccount
|
|
425
479
|
): string {
|
|
426
|
-
if (account.
|
|
480
|
+
if (account.isPda && account.isSigner === false) return 'Pda';
|
|
427
481
|
if (account.isSigner === 'either') return 'PublicKey | Signer';
|
|
428
482
|
return account.isSigner ? 'Signer' : 'PublicKey';
|
|
429
483
|
}
|
|
@@ -433,13 +487,12 @@ export class GetJavaScriptRenderMapVisitor extends BaseThrowVisitor<RenderMap> {
|
|
|
433
487
|
): JavaScriptImportMap {
|
|
434
488
|
const imports = new JavaScriptImportMap();
|
|
435
489
|
accounts.forEach((account) => {
|
|
436
|
-
if (account.
|
|
490
|
+
if (account.isPda && account.isSigner === false) {
|
|
437
491
|
imports.add('core', 'Pda');
|
|
438
492
|
}
|
|
439
493
|
if (account.defaultsTo?.kind === 'publicKey') {
|
|
440
494
|
imports.add('core', 'publicKey');
|
|
441
|
-
}
|
|
442
|
-
if (account.defaultsTo?.kind === 'pda') {
|
|
495
|
+
} else if (account.defaultsTo?.kind === 'pda') {
|
|
443
496
|
const pdaAccount = pascalCase(account.defaultsTo.pdaAccount);
|
|
444
497
|
const dependency =
|
|
445
498
|
account.defaultsTo.dependency === 'generated'
|
|
@@ -451,6 +504,11 @@ export class GetJavaScriptRenderMapVisitor extends BaseThrowVisitor<RenderMap> {
|
|
|
451
504
|
imports.add('core', 'publicKey');
|
|
452
505
|
}
|
|
453
506
|
});
|
|
507
|
+
} else if (account.defaultsTo?.kind === 'resolver') {
|
|
508
|
+
imports.add(
|
|
509
|
+
account.defaultsTo.dependency,
|
|
510
|
+
camelCase(account.defaultsTo.name)
|
|
511
|
+
);
|
|
454
512
|
}
|
|
455
513
|
if (account.resolvedIsSigner === 'either') {
|
|
456
514
|
imports.add('core', ['PublicKey', 'publicKey', 'Signer', 'isSigner']);
|
|
@@ -467,9 +525,14 @@ export class GetJavaScriptRenderMapVisitor extends BaseThrowVisitor<RenderMap> {
|
|
|
467
525
|
instruction: nodes.InstructionNode
|
|
468
526
|
): string[] {
|
|
469
527
|
nodes.assertTypeStructNode(instruction.args);
|
|
528
|
+
let extraArgsFields: nodes.TypeStructFieldNode[] = [];
|
|
529
|
+
if (nodes.isTypeStructNode(instruction.extraArgs)) {
|
|
530
|
+
extraArgsFields = instruction.extraArgs.fields;
|
|
531
|
+
}
|
|
470
532
|
const allNames = [
|
|
471
533
|
...instruction.accounts.map((account) => account.name),
|
|
472
534
|
...instruction.args.fields.map((field) => field.name),
|
|
535
|
+
...extraArgsFields.map((field) => field.name),
|
|
473
536
|
];
|
|
474
537
|
const duplicates = allNames.filter((e, i, a) => a.indexOf(e) !== i);
|
|
475
538
|
return [...new Set(duplicates)];
|
|
@@ -31,6 +31,12 @@ export class GetJavaScriptTypeManifestVisitor
|
|
|
31
31
|
this.importStrategy = strategy;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
setDefinedName(
|
|
35
|
+
definedName: GetJavaScriptTypeManifestVisitor['definedName']
|
|
36
|
+
): void {
|
|
37
|
+
this.definedName = definedName;
|
|
38
|
+
}
|
|
39
|
+
|
|
34
40
|
visitRoot(): JavaScriptTypeManifest {
|
|
35
41
|
throw new Error(
|
|
36
42
|
'Cannot get type manifest for root node. Please select a child node.'
|
|
@@ -86,6 +86,8 @@ export class GetJavaScriptValidatorBagVisitor extends GetDefaultValidatorBagVisi
|
|
|
86
86
|
[`${pascalCaseName}InstructionData`]: 'type',
|
|
87
87
|
[`${pascalCaseName}InstructionDataArgs`]: 'type',
|
|
88
88
|
[`get${pascalCaseName}InstructionDataSerializer`]: 'function',
|
|
89
|
+
[`${pascalCaseName}InstructionExtraArgs`]: 'type',
|
|
90
|
+
[`${pascalCaseName}InstructionArgs`]: 'type',
|
|
89
91
|
}),
|
|
90
92
|
]);
|
|
91
93
|
}
|
|
@@ -17,25 +17,15 @@ export function {{ instruction.name | camelCase }}(
|
|
|
17
17
|
{{- '| \'payer\'' if needsPayer else '' }}
|
|
18
18
|
>,
|
|
19
19
|
{% set accountsType = instruction.name | pascalCase + 'InstructionAccounts' %}
|
|
20
|
-
{%
|
|
21
|
-
{% set argsType %}
|
|
22
|
-
Omit<{{ instruction.name | pascalCase + 'InstructionDataArgs' }},
|
|
23
|
-
{%- for account in instruction.pdaAccounts -%}
|
|
24
|
-
"{{ account.pdaBumpArg }}"{% if not loop.last %} | {% endif %}
|
|
25
|
-
{%- endfor -%}
|
|
26
|
-
>
|
|
27
|
-
{% endset %}
|
|
28
|
-
{% else %}
|
|
29
|
-
{% set argsType = instruction.name | pascalCase + 'InstructionDataArgs' %}
|
|
30
|
-
{% endif %}
|
|
20
|
+
{% set argsType = instruction.name | pascalCase + 'InstructionArgs' %}
|
|
31
21
|
{% if canMergeAccountsAndArgs %}
|
|
32
22
|
{% set accountsObj = 'input' %}
|
|
33
23
|
{% set argsObj = 'input' %}
|
|
34
|
-
{% if instruction.hasAccounts and instruction.
|
|
24
|
+
{% if instruction.hasAccounts and instruction.hasAnyArgs %}
|
|
35
25
|
input: {{ accountsType }} & {{ argsType }},
|
|
36
26
|
{% elif instruction.hasAccounts %}
|
|
37
27
|
input: {{ accountsType }},
|
|
38
|
-
{% elif instruction.
|
|
28
|
+
{% elif instruction.hasAnyArgs %}
|
|
39
29
|
input: {{ argsType }},
|
|
40
30
|
{% endif %}
|
|
41
31
|
{% else %}
|
|
@@ -44,7 +34,7 @@ export function {{ instruction.name | camelCase }}(
|
|
|
44
34
|
{% if instruction.hasAccounts %}
|
|
45
35
|
accounts: {{ accountsType }},
|
|
46
36
|
{% endif %}
|
|
47
|
-
{% if instruction.
|
|
37
|
+
{% if instruction.hasAnyArgs %}
|
|
48
38
|
args: {{ argsType }},
|
|
49
39
|
{% endif %}
|
|
50
40
|
{% endif %}
|
|
@@ -53,20 +43,15 @@ export function {{ instruction.name | camelCase }}(
|
|
|
53
43
|
const keys: AccountMeta[] = [];
|
|
54
44
|
|
|
55
45
|
// Program ID.
|
|
56
|
-
const programId = context.programs.getPublicKey('{{ program.name | camelCase }}', '{{ program.metadata.publicKey }}');
|
|
46
|
+
const programId = { ...context.programs.getPublicKey('{{ program.name | camelCase }}', '{{ program.metadata.publicKey }}'), isWritable: false };
|
|
47
|
+
|
|
48
|
+
{% include "instructionsPageResolvedInputs.njk" %}
|
|
57
49
|
|
|
58
50
|
{% include "instructionsPageAccountMetas.njk" -%}
|
|
59
51
|
|
|
60
52
|
// Data.
|
|
61
|
-
{% if instruction.hasArgs
|
|
62
|
-
const data = get{{ instruction.name | pascalCase }}InstructionDataSerializer(context).serialize(
|
|
63
|
-
...{{ argsObj }},
|
|
64
|
-
{% for account in instruction.pdaAccounts %}
|
|
65
|
-
{{ account.pdaBumpArg }}: {{ account.name | camelCase }}Account.bump,
|
|
66
|
-
{% endfor %}
|
|
67
|
-
});
|
|
68
|
-
{% elif instruction.hasArgs %}
|
|
69
|
-
const data = get{{ instruction.name | pascalCase }}InstructionDataSerializer(context).serialize({{ argsObj }});
|
|
53
|
+
{% if instruction.hasArgs %}
|
|
54
|
+
const data = get{{ instruction.name | pascalCase }}InstructionDataSerializer(context).serialize(resolvedArgs);
|
|
70
55
|
{% elif instruction.hasData %}
|
|
71
56
|
const data = get{{ instruction.name | pascalCase }}InstructionDataSerializer(context).serialize({});
|
|
72
57
|
{% else %}
|
|
@@ -81,6 +66,8 @@ export function {{ instruction.name | camelCase }}(
|
|
|
81
66
|
const bytesCreatedOnChain = Number({{ argsObj }}.{{ bytes.name }}){% if bytes.includeHeader %} + ACCOUNT_HEADER_SIZE{% endif %};
|
|
82
67
|
{% elif bytes.kind === 'account' %}
|
|
83
68
|
const bytesCreatedOnChain = get{{ bytes.name | pascalCase }}Size(){% if bytes.includeHeader %} + ACCOUNT_HEADER_SIZE{% endif %};
|
|
69
|
+
{% elif bytes.kind === 'resolver' %}
|
|
70
|
+
const bytesCreatedOnChain = {{ bytes.name | camelCase }}(context, resolvedAccounts, resolvedArgs, programId);
|
|
84
71
|
{% else %}
|
|
85
72
|
const bytesCreatedOnChain = 0;
|
|
86
73
|
{% endif %}
|