@codama/dynamic-address-resolution 0.2.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/LICENSE +22 -0
- package/README.md +155 -0
- package/dist/index.browser.cjs +1288 -0
- package/dist/index.browser.cjs.map +1 -0
- package/dist/index.browser.mjs +1278 -0
- package/dist/index.browser.mjs.map +1 -0
- package/dist/index.node.cjs +1288 -0
- package/dist/index.node.cjs.map +1 -0
- package/dist/index.node.mjs +1278 -0
- package/dist/index.node.mjs.map +1 -0
- package/dist/index.react-native.mjs +1278 -0
- package/dist/index.react-native.mjs.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/resolvers/index.d.ts +9 -0
- package/dist/types/resolvers/index.d.ts.map +1 -0
- package/dist/types/resolvers/resolve-account-address.d.ts +13 -0
- package/dist/types/resolvers/resolve-account-address.d.ts.map +1 -0
- package/dist/types/resolvers/resolve-account-value-node-address.d.ts +15 -0
- package/dist/types/resolvers/resolve-account-value-node-address.d.ts.map +1 -0
- package/dist/types/resolvers/resolve-conditional.d.ts +13 -0
- package/dist/types/resolvers/resolve-conditional.d.ts.map +1 -0
- package/dist/types/resolvers/resolve-instruction-account-address.d.ts +13 -0
- package/dist/types/resolvers/resolve-instruction-account-address.d.ts.map +1 -0
- package/dist/types/resolvers/resolve-pda-address.d.ts +13 -0
- package/dist/types/resolvers/resolve-pda-address.d.ts.map +1 -0
- package/dist/types/resolvers/resolve-standalone-pda.d.ts +8 -0
- package/dist/types/resolvers/resolve-standalone-pda.d.ts.map +1 -0
- package/dist/types/resolvers/types.d.ts +16 -0
- package/dist/types/resolvers/types.d.ts.map +1 -0
- package/dist/types/shared/address.d.ts +13 -0
- package/dist/types/shared/address.d.ts.map +1 -0
- package/dist/types/shared/bytes-encoding.d.ts +15 -0
- package/dist/types/shared/bytes-encoding.d.ts.map +1 -0
- package/dist/types/shared/codecs.d.ts +9 -0
- package/dist/types/shared/codecs.d.ts.map +1 -0
- package/dist/types/shared/nodes.d.ts +2 -0
- package/dist/types/shared/nodes.d.ts.map +1 -0
- package/dist/types/shared/types.d.ts +13 -0
- package/dist/types/shared/types.d.ts.map +1 -0
- package/dist/types/shared/util.d.ts +15 -0
- package/dist/types/shared/util.d.ts.map +1 -0
- package/dist/types/visitors/account-default-value.d.ts +16 -0
- package/dist/types/visitors/account-default-value.d.ts.map +1 -0
- package/dist/types/visitors/codec-input-transformer.d.ts +37 -0
- package/dist/types/visitors/codec-input-transformer.d.ts.map +1 -0
- package/dist/types/visitors/condition-node-value.d.ts +12 -0
- package/dist/types/visitors/condition-node-value.d.ts.map +1 -0
- package/dist/types/visitors/default-value-encoder.d.ts +16 -0
- package/dist/types/visitors/default-value-encoder.d.ts.map +1 -0
- package/dist/types/visitors/index.d.ts +7 -0
- package/dist/types/visitors/index.d.ts.map +1 -0
- package/dist/types/visitors/pda-seed-value.d.ts +20 -0
- package/dist/types/visitors/pda-seed-value.d.ts.map +1 -0
- package/dist/types/visitors/value-node-value.d.ts +14 -0
- package/dist/types/visitors/value-node-value.d.ts.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,1278 @@
|
|
|
1
|
+
import { CodamaError, CODAMA_ERROR__DYNAMIC_CLIENT__CANNOT_CONVERT_TO_ADDRESS, CODAMA_ERROR__DYNAMIC_CLIENT__ACCOUNT_MISSING, CODAMA_ERROR__UNRECOGNIZED_NODE_KIND, CODAMA_ERROR__UNEXPECTED_NODE_KIND, CODAMA_ERROR__DYNAMIC_CLIENT__ARGUMENT_MISSING, CODAMA_ERROR__DYNAMIC_CLIENT__UNEXPECTED_ARGUMENT_TYPE, CODAMA_ERROR__DYNAMIC_CLIENT__INVARIANT_VIOLATION, CODAMA_ERROR__DYNAMIC_CLIENT__NODE_REFERENCE_NOT_FOUND, CODAMA_ERROR__DYNAMIC_CLIENT__FAILED_TO_DERIVE_PDA, CODAMA_ERROR__LINKED_NODE_NOT_FOUND, CODAMA_ERROR__DYNAMIC_CLIENT__UNSUPPORTED_OPTIONAL_ACCOUNT_STRATEGY, CODAMA_ERROR__DYNAMIC_CLIENT__ACCOUNT_RESOLVER_MISSING, CODAMA_ERROR__DYNAMIC_CLIENT__FAILED_TO_EXECUTE_RESOLVER, CODAMA_ERROR__DYNAMIC_CLIENT__INVALID_ACCOUNT_ADDRESS, CODAMA_ERROR__DYNAMIC_CLIENT__UNEXPECTED_ADDRESS_TYPE, CODAMA_ERROR__DYNAMIC_CLIENT__UNSUPPORTED_NODE, CODAMA_ERROR__UNRECOGNIZED_BYTES_ENCODING, CODAMA_ERROR__DYNAMIC_CLIENT__CIRCULAR_ACCOUNT_DEPENDENCY } from '@codama/errors';
|
|
2
|
+
import { visitOrElse, isNode, camelCase, pascalCase } from 'codama';
|
|
3
|
+
import { address, isAddress, getProgramDerivedAddress, getAddressEncoder } from '@solana/addresses';
|
|
4
|
+
import { getNodeCodec } from '@codama/dynamic-codecs';
|
|
5
|
+
import { getUtf8Encoder, getUtf8Codec, getBooleanEncoder, getBase64Codec, getBase58Codec, getBase16Codec } from '@solana/codecs';
|
|
6
|
+
|
|
7
|
+
// src/resolvers/resolve-account-address.ts
|
|
8
|
+
|
|
9
|
+
// src/shared/util.ts
|
|
10
|
+
function isObjectRecord(value) {
|
|
11
|
+
return typeof value === "object" && value !== null && Object.getPrototypeOf(value) === Object.prototype;
|
|
12
|
+
}
|
|
13
|
+
function getMaybeNodeKind(node) {
|
|
14
|
+
if (!isObjectRecord(node)) return null;
|
|
15
|
+
return node.kind ?? null;
|
|
16
|
+
}
|
|
17
|
+
function formatValueType(value) {
|
|
18
|
+
if (value === null) return "null";
|
|
19
|
+
if (Array.isArray(value)) return `array (length ${value.length})`;
|
|
20
|
+
if (value instanceof Uint8Array) return `Uint8Array (length ${value.length})`;
|
|
21
|
+
if (typeof value === "object") return "object";
|
|
22
|
+
return typeof value;
|
|
23
|
+
}
|
|
24
|
+
function safeStringify(value) {
|
|
25
|
+
try {
|
|
26
|
+
return JSON.stringify(value, (_key, v) => typeof v === "bigint" ? String(v) : v);
|
|
27
|
+
} catch {
|
|
28
|
+
return `non-serializable ${formatValueType(value)}`;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// src/shared/address.ts
|
|
33
|
+
function isPublicKeyLike(value) {
|
|
34
|
+
const obj = value;
|
|
35
|
+
return typeof value === "object" && value !== null && "toBase58" in obj && typeof obj.toBase58 === "function";
|
|
36
|
+
}
|
|
37
|
+
function toAddress(input) {
|
|
38
|
+
if (isPublicKeyLike(input)) return address(input.toBase58());
|
|
39
|
+
if (typeof input === "string" && isAddress(input)) return address(input);
|
|
40
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__CANNOT_CONVERT_TO_ADDRESS, {
|
|
41
|
+
value: safeStringify(input)
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function isAddressConvertible(value) {
|
|
45
|
+
if (value == null) return false;
|
|
46
|
+
return isPublicKeyLike(value) || typeof value === "string" && isAddress(value);
|
|
47
|
+
}
|
|
48
|
+
async function resolveAccountValueNodeAddress(node, ctx) {
|
|
49
|
+
const { accountsInput, ixNode, resolutionPath } = ctx;
|
|
50
|
+
const providedAddress = accountsInput?.[node.name];
|
|
51
|
+
if (providedAddress !== void 0 && providedAddress !== null) {
|
|
52
|
+
return toAddress(providedAddress);
|
|
53
|
+
}
|
|
54
|
+
const referencedIxAccountNode = ixNode.accounts.find((acc) => acc.name === node.name);
|
|
55
|
+
if (!referencedIxAccountNode) {
|
|
56
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__NODE_REFERENCE_NOT_FOUND, {
|
|
57
|
+
instructionName: ixNode.name,
|
|
58
|
+
referencedName: node.name
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
detectCircularDependency(node.name, resolutionPath);
|
|
62
|
+
return await resolveAccountAddress({
|
|
63
|
+
accountsInput: ctx.accountsInput,
|
|
64
|
+
argumentsInput: ctx.argumentsInput,
|
|
65
|
+
ixAccountNode: referencedIxAccountNode,
|
|
66
|
+
ixNode,
|
|
67
|
+
resolutionPath: [...resolutionPath, node.name],
|
|
68
|
+
resolversInput: ctx.resolversInput,
|
|
69
|
+
root: ctx.root
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function detectCircularDependency(nodeName, resolutionPath) {
|
|
73
|
+
if (resolutionPath.includes(nodeName)) {
|
|
74
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__CIRCULAR_ACCOUNT_DEPENDENCY, {
|
|
75
|
+
chain: [...resolutionPath, nodeName].join(" -> ")
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
var CONDITION_NODE_SUPPORTED_NODE_KINDS = [
|
|
80
|
+
"accountValueNode",
|
|
81
|
+
"argumentValueNode",
|
|
82
|
+
"resolverValueNode"
|
|
83
|
+
];
|
|
84
|
+
function createConditionNodeValueVisitor(ctx) {
|
|
85
|
+
const { root, ixNode, argumentsInput, accountsInput, resolutionPath, resolversInput } = ctx;
|
|
86
|
+
return {
|
|
87
|
+
visitAccountValue: async (node) => {
|
|
88
|
+
const accountAddressInput = accountsInput?.[node.name];
|
|
89
|
+
if (accountAddressInput === null) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
return await resolveAccountValueNodeAddress(node, {
|
|
93
|
+
accountsInput,
|
|
94
|
+
argumentsInput,
|
|
95
|
+
ixNode,
|
|
96
|
+
resolutionPath,
|
|
97
|
+
resolversInput,
|
|
98
|
+
root
|
|
99
|
+
});
|
|
100
|
+
},
|
|
101
|
+
visitArgumentValue: async (node) => {
|
|
102
|
+
const argInput = argumentsInput?.[node.name];
|
|
103
|
+
return await Promise.resolve(argInput);
|
|
104
|
+
},
|
|
105
|
+
visitResolverValue: async (node) => {
|
|
106
|
+
const resolverFn = resolversInput?.[node.name];
|
|
107
|
+
if (!resolverFn) {
|
|
108
|
+
return void 0;
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
return await resolverFn(argumentsInput ?? {}, accountsInput ?? {});
|
|
112
|
+
} catch (error) {
|
|
113
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__FAILED_TO_EXECUTE_RESOLVER, {
|
|
114
|
+
cause: error,
|
|
115
|
+
resolverName: node.name,
|
|
116
|
+
targetKind: "conditionalValueNode",
|
|
117
|
+
targetName: node.name
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
var VALUE_NODE_SUPPORTED_NODE_KINDS = [
|
|
124
|
+
"arrayValueNode",
|
|
125
|
+
"booleanValueNode",
|
|
126
|
+
"bytesValueNode",
|
|
127
|
+
"constantValueNode",
|
|
128
|
+
"enumValueNode",
|
|
129
|
+
"mapValueNode",
|
|
130
|
+
"noneValueNode",
|
|
131
|
+
"numberValueNode",
|
|
132
|
+
"publicKeyValueNode",
|
|
133
|
+
"setValueNode",
|
|
134
|
+
"someValueNode",
|
|
135
|
+
"stringValueNode",
|
|
136
|
+
"structValueNode",
|
|
137
|
+
"tupleValueNode"
|
|
138
|
+
];
|
|
139
|
+
function createValueNodeVisitor() {
|
|
140
|
+
const visitor = {
|
|
141
|
+
visitArrayValue: (node) => ({
|
|
142
|
+
kind: node.kind,
|
|
143
|
+
value: node.items.map(
|
|
144
|
+
(item) => visitOrElse(item, visitor, (n) => {
|
|
145
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
146
|
+
expectedKinds: [...VALUE_NODE_SUPPORTED_NODE_KINDS],
|
|
147
|
+
kind: n.kind,
|
|
148
|
+
node: n
|
|
149
|
+
});
|
|
150
|
+
})
|
|
151
|
+
)
|
|
152
|
+
}),
|
|
153
|
+
visitBooleanValue: (node) => ({
|
|
154
|
+
kind: node.kind,
|
|
155
|
+
value: node.boolean
|
|
156
|
+
}),
|
|
157
|
+
visitBytesValue: (node) => ({
|
|
158
|
+
encoding: node.encoding,
|
|
159
|
+
kind: node.kind,
|
|
160
|
+
value: node.data
|
|
161
|
+
}),
|
|
162
|
+
visitConstantValue: (node) => {
|
|
163
|
+
return visitOrElse(node.value, visitor, (innerNode) => {
|
|
164
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
165
|
+
expectedKinds: [...VALUE_NODE_SUPPORTED_NODE_KINDS],
|
|
166
|
+
kind: innerNode.kind,
|
|
167
|
+
node: innerNode
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
},
|
|
171
|
+
visitEnumValue: (node) => ({
|
|
172
|
+
kind: node.kind,
|
|
173
|
+
value: node.variant
|
|
174
|
+
}),
|
|
175
|
+
visitMapValue: (node) => ({
|
|
176
|
+
kind: node.kind,
|
|
177
|
+
value: node.entries.map((entry) => ({
|
|
178
|
+
key: visitOrElse(entry.key, visitor, (n) => {
|
|
179
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
180
|
+
expectedKinds: [...VALUE_NODE_SUPPORTED_NODE_KINDS],
|
|
181
|
+
kind: n.kind,
|
|
182
|
+
node: n
|
|
183
|
+
});
|
|
184
|
+
}),
|
|
185
|
+
value: visitOrElse(entry.value, visitor, (n) => {
|
|
186
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
187
|
+
expectedKinds: [...VALUE_NODE_SUPPORTED_NODE_KINDS],
|
|
188
|
+
kind: n.kind,
|
|
189
|
+
node: n
|
|
190
|
+
});
|
|
191
|
+
})
|
|
192
|
+
}))
|
|
193
|
+
}),
|
|
194
|
+
visitNoneValue: (node) => ({
|
|
195
|
+
kind: node.kind,
|
|
196
|
+
value: null
|
|
197
|
+
}),
|
|
198
|
+
visitNumberValue: (node) => ({
|
|
199
|
+
kind: node.kind,
|
|
200
|
+
value: node.number
|
|
201
|
+
}),
|
|
202
|
+
visitPublicKeyValue: (node) => ({
|
|
203
|
+
kind: node.kind,
|
|
204
|
+
value: address(node.publicKey)
|
|
205
|
+
}),
|
|
206
|
+
visitSetValue: (node) => ({
|
|
207
|
+
kind: node.kind,
|
|
208
|
+
value: node.items.map(
|
|
209
|
+
(item) => visitOrElse(item, visitor, (n) => {
|
|
210
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
211
|
+
expectedKinds: [...VALUE_NODE_SUPPORTED_NODE_KINDS],
|
|
212
|
+
kind: n.kind,
|
|
213
|
+
node: n
|
|
214
|
+
});
|
|
215
|
+
})
|
|
216
|
+
)
|
|
217
|
+
}),
|
|
218
|
+
visitSomeValue: (node) => {
|
|
219
|
+
return visitOrElse(node.value, visitor, (innerNode) => {
|
|
220
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
221
|
+
expectedKinds: [...VALUE_NODE_SUPPORTED_NODE_KINDS],
|
|
222
|
+
kind: innerNode.kind,
|
|
223
|
+
node: innerNode
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
},
|
|
227
|
+
visitStringValue: (node) => ({
|
|
228
|
+
kind: node.kind,
|
|
229
|
+
value: node.string
|
|
230
|
+
}),
|
|
231
|
+
visitStructValue: (node) => ({
|
|
232
|
+
kind: node.kind,
|
|
233
|
+
value: Object.fromEntries(
|
|
234
|
+
node.fields.map((field) => [
|
|
235
|
+
field.name,
|
|
236
|
+
visitOrElse(field.value, visitor, (n) => {
|
|
237
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
238
|
+
expectedKinds: [...VALUE_NODE_SUPPORTED_NODE_KINDS],
|
|
239
|
+
kind: n.kind,
|
|
240
|
+
node: n
|
|
241
|
+
});
|
|
242
|
+
})
|
|
243
|
+
])
|
|
244
|
+
)
|
|
245
|
+
}),
|
|
246
|
+
visitTupleValue: (node) => ({
|
|
247
|
+
kind: node.kind,
|
|
248
|
+
value: node.items.map(
|
|
249
|
+
(item) => visitOrElse(item, visitor, (n) => {
|
|
250
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
251
|
+
expectedKinds: [...VALUE_NODE_SUPPORTED_NODE_KINDS],
|
|
252
|
+
kind: n.kind,
|
|
253
|
+
node: n
|
|
254
|
+
});
|
|
255
|
+
})
|
|
256
|
+
)
|
|
257
|
+
})
|
|
258
|
+
};
|
|
259
|
+
return visitor;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// src/resolvers/resolve-conditional.ts
|
|
263
|
+
async function resolveConditionalValueNodeCondition({
|
|
264
|
+
root,
|
|
265
|
+
ixNode,
|
|
266
|
+
ixAccountNode,
|
|
267
|
+
conditionalValueNode,
|
|
268
|
+
argumentsInput,
|
|
269
|
+
accountsInput,
|
|
270
|
+
resolutionPath,
|
|
271
|
+
resolversInput
|
|
272
|
+
}) {
|
|
273
|
+
if (!isNode(conditionalValueNode, "conditionalValueNode")) {
|
|
274
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
275
|
+
expectedKinds: ["conditionalValueNode"],
|
|
276
|
+
kind: getMaybeNodeKind(conditionalValueNode),
|
|
277
|
+
node: conditionalValueNode
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
const { condition, value: expectedValueNode, ifTrue, ifFalse } = conditionalValueNode;
|
|
281
|
+
if (!expectedValueNode && !ifTrue && !ifFalse) {
|
|
282
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__INVARIANT_VIOLATION, {
|
|
283
|
+
message: `Invalid conditionalValueNode: missing value and branches for account ${ixAccountNode.name} in ${ixNode.name}`
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
const conditionVisitor = createConditionNodeValueVisitor({
|
|
287
|
+
accountsInput,
|
|
288
|
+
argumentsInput,
|
|
289
|
+
ixNode,
|
|
290
|
+
resolutionPath,
|
|
291
|
+
resolversInput,
|
|
292
|
+
root
|
|
293
|
+
});
|
|
294
|
+
const actualProvidedValue = await visitOrElse(condition, conditionVisitor, (condNode) => {
|
|
295
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
296
|
+
expectedKinds: [...CONDITION_NODE_SUPPORTED_NODE_KINDS],
|
|
297
|
+
kind: condNode.kind,
|
|
298
|
+
node: condNode
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
if (!expectedValueNode) {
|
|
302
|
+
return actualProvidedValue ? ifTrue : ifFalse;
|
|
303
|
+
}
|
|
304
|
+
const valueVisitor = createValueNodeVisitor();
|
|
305
|
+
const expectedValue = visitOrElse(expectedValueNode, valueVisitor, (valueNode) => {
|
|
306
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
307
|
+
expectedKinds: [...VALUE_NODE_SUPPORTED_NODE_KINDS],
|
|
308
|
+
kind: valueNode.kind,
|
|
309
|
+
node: valueNode
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
if (typeof expectedValue.value === "object" || typeof actualProvidedValue === "object") {
|
|
313
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__INVARIANT_VIOLATION, {
|
|
314
|
+
message: "Deep equality comparison not yet supported for conditional value"
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
return actualProvidedValue === expectedValue.value ? ifTrue : ifFalse;
|
|
318
|
+
}
|
|
319
|
+
var addressEncoder;
|
|
320
|
+
function getMemoizedAddressEncoder() {
|
|
321
|
+
if (!addressEncoder) addressEncoder = getAddressEncoder();
|
|
322
|
+
return addressEncoder;
|
|
323
|
+
}
|
|
324
|
+
var utf8Encoder;
|
|
325
|
+
function getMemoizedUtf8Encoder() {
|
|
326
|
+
if (!utf8Encoder) utf8Encoder = getUtf8Encoder();
|
|
327
|
+
return utf8Encoder;
|
|
328
|
+
}
|
|
329
|
+
var booleanEncoder;
|
|
330
|
+
function getMemoizedBooleanEncoder() {
|
|
331
|
+
if (!booleanEncoder) booleanEncoder = getBooleanEncoder();
|
|
332
|
+
return booleanEncoder;
|
|
333
|
+
}
|
|
334
|
+
var utf8Codec;
|
|
335
|
+
function getMemoizedUtf8Codec() {
|
|
336
|
+
if (!utf8Codec) utf8Codec = getUtf8Codec();
|
|
337
|
+
return utf8Codec;
|
|
338
|
+
}
|
|
339
|
+
var base16Codec;
|
|
340
|
+
function getMemoizedBase16Codec() {
|
|
341
|
+
if (!base16Codec) base16Codec = getBase16Codec();
|
|
342
|
+
return base16Codec;
|
|
343
|
+
}
|
|
344
|
+
var base58Codec;
|
|
345
|
+
function getMemoizedBase58Codec() {
|
|
346
|
+
if (!base58Codec) base58Codec = getBase58Codec();
|
|
347
|
+
return base58Codec;
|
|
348
|
+
}
|
|
349
|
+
var base64Codec;
|
|
350
|
+
function getMemoizedBase64Codec() {
|
|
351
|
+
if (!base64Codec) base64Codec = getBase64Codec();
|
|
352
|
+
return base64Codec;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// src/shared/bytes-encoding.ts
|
|
356
|
+
function uint8ArrayToEncodedString(bytes, encoding) {
|
|
357
|
+
const codec = getCodecFromBytesEncoding(encoding);
|
|
358
|
+
return codec.decode(bytes);
|
|
359
|
+
}
|
|
360
|
+
function getCodecFromBytesEncoding(encoding) {
|
|
361
|
+
switch (encoding) {
|
|
362
|
+
case "base16":
|
|
363
|
+
return getMemoizedBase16Codec();
|
|
364
|
+
case "base58":
|
|
365
|
+
return getMemoizedBase58Codec();
|
|
366
|
+
case "base64":
|
|
367
|
+
return getMemoizedBase64Codec();
|
|
368
|
+
case "utf8":
|
|
369
|
+
return getMemoizedUtf8Codec();
|
|
370
|
+
default:
|
|
371
|
+
throw new CodamaError(CODAMA_ERROR__UNRECOGNIZED_BYTES_ENCODING, {
|
|
372
|
+
encoding: safeStringify(encoding)
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
function isUint8Array(value) {
|
|
377
|
+
return value instanceof Uint8Array;
|
|
378
|
+
}
|
|
379
|
+
var CODEC_INPUT_TRANSFORMER_SUPPORTED_NODE_KINDS = [
|
|
380
|
+
"amountTypeNode",
|
|
381
|
+
"arrayTypeNode",
|
|
382
|
+
"booleanTypeNode",
|
|
383
|
+
"bytesTypeNode",
|
|
384
|
+
"dateTimeTypeNode",
|
|
385
|
+
"definedTypeLinkNode",
|
|
386
|
+
"enumTypeNode",
|
|
387
|
+
"fixedSizeTypeNode",
|
|
388
|
+
"hiddenPrefixTypeNode",
|
|
389
|
+
"hiddenSuffixTypeNode",
|
|
390
|
+
"mapTypeNode",
|
|
391
|
+
"numberTypeNode",
|
|
392
|
+
"optionTypeNode",
|
|
393
|
+
"postOffsetTypeNode",
|
|
394
|
+
"preOffsetTypeNode",
|
|
395
|
+
"publicKeyTypeNode",
|
|
396
|
+
"remainderOptionTypeNode",
|
|
397
|
+
"sentinelTypeNode",
|
|
398
|
+
"setTypeNode",
|
|
399
|
+
"sizePrefixTypeNode",
|
|
400
|
+
"solAmountTypeNode",
|
|
401
|
+
"stringTypeNode",
|
|
402
|
+
"structFieldTypeNode",
|
|
403
|
+
"structTypeNode",
|
|
404
|
+
"tupleTypeNode",
|
|
405
|
+
"zeroableOptionTypeNode"
|
|
406
|
+
];
|
|
407
|
+
function unexpectedNodeFallback(node) {
|
|
408
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
409
|
+
expectedKinds: [...CODEC_INPUT_TRANSFORMER_SUPPORTED_NODE_KINDS],
|
|
410
|
+
kind: node.kind,
|
|
411
|
+
node
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
function createCodecInputTransformerVisitor(root, options = {}) {
|
|
415
|
+
const bytesEncoding = options.bytesEncoding ?? "base16";
|
|
416
|
+
const visitor = {
|
|
417
|
+
visitAmountType(node) {
|
|
418
|
+
return visitOrElse(node.number, visitor, unexpectedNodeFallback);
|
|
419
|
+
},
|
|
420
|
+
visitArrayType(node) {
|
|
421
|
+
const itemTransform = visitOrElse(node.item, visitor, unexpectedNodeFallback);
|
|
422
|
+
return (input) => {
|
|
423
|
+
if (!Array.isArray(input)) {
|
|
424
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__UNEXPECTED_ARGUMENT_TYPE, {
|
|
425
|
+
actualType: formatValueType(input),
|
|
426
|
+
expectedType: "array",
|
|
427
|
+
nodeKind: "arrayTypeNode"
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
return input.map(itemTransform);
|
|
431
|
+
};
|
|
432
|
+
},
|
|
433
|
+
visitBooleanType() {
|
|
434
|
+
return (input) => input;
|
|
435
|
+
},
|
|
436
|
+
visitBytesType() {
|
|
437
|
+
return (input) => {
|
|
438
|
+
if (isUint8Array(input)) {
|
|
439
|
+
return [bytesEncoding, uint8ArrayToEncodedString(input, bytesEncoding)];
|
|
440
|
+
}
|
|
441
|
+
if (Array.isArray(input) && input.every((item) => typeof item === "number")) {
|
|
442
|
+
return [bytesEncoding, uint8ArrayToEncodedString(new Uint8Array(input), bytesEncoding)];
|
|
443
|
+
}
|
|
444
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__UNEXPECTED_ARGUMENT_TYPE, {
|
|
445
|
+
actualType: formatValueType(input),
|
|
446
|
+
expectedType: "Uint8Array | number[]",
|
|
447
|
+
nodeKind: "bytesTypeNode"
|
|
448
|
+
});
|
|
449
|
+
};
|
|
450
|
+
},
|
|
451
|
+
visitDateTimeType(node) {
|
|
452
|
+
return visitOrElse(node.number, visitor, unexpectedNodeFallback);
|
|
453
|
+
},
|
|
454
|
+
visitDefinedTypeLink(node) {
|
|
455
|
+
const definedType = root.program.definedTypes.find((dt) => dt.name === node.name);
|
|
456
|
+
if (!definedType) {
|
|
457
|
+
throw new CodamaError(CODAMA_ERROR__LINKED_NODE_NOT_FOUND, {
|
|
458
|
+
kind: "definedTypeLinkNode",
|
|
459
|
+
linkNode: node,
|
|
460
|
+
name: node.name,
|
|
461
|
+
path: []
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
return visitOrElse(definedType.type, visitor, unexpectedNodeFallback);
|
|
465
|
+
},
|
|
466
|
+
visitEnumType(node) {
|
|
467
|
+
return (input) => {
|
|
468
|
+
if (typeof input === "number" || typeof input === "string") {
|
|
469
|
+
return input;
|
|
470
|
+
}
|
|
471
|
+
if (!isObjectRecord(input)) {
|
|
472
|
+
return input;
|
|
473
|
+
}
|
|
474
|
+
if (!("__kind" in input)) {
|
|
475
|
+
return input;
|
|
476
|
+
}
|
|
477
|
+
const { __kind, ...rest } = input;
|
|
478
|
+
const kindObj = { __kind: pascalCase(String(__kind)) };
|
|
479
|
+
const variantNode = node.variants.find((v) => v.name === __kind);
|
|
480
|
+
if (!variantNode) {
|
|
481
|
+
const availableVariants = node.variants.map((v) => v.name).join(", ");
|
|
482
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__UNEXPECTED_ARGUMENT_TYPE, {
|
|
483
|
+
actualType: `variant '${String(__kind)}'`,
|
|
484
|
+
expectedType: `one of [${availableVariants}]`,
|
|
485
|
+
nodeKind: "enumTypeNode"
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
if (isNode(variantNode, "enumEmptyVariantTypeNode")) {
|
|
489
|
+
return { ...input, ...kindObj };
|
|
490
|
+
}
|
|
491
|
+
if (isNode(variantNode, "enumStructVariantTypeNode")) {
|
|
492
|
+
const structTransform = visitOrElse(variantNode.struct, visitor, unexpectedNodeFallback);
|
|
493
|
+
const transformedFields = structTransform(rest);
|
|
494
|
+
if (!isObjectRecord(transformedFields)) {
|
|
495
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__UNEXPECTED_ARGUMENT_TYPE, {
|
|
496
|
+
actualType: formatValueType(transformedFields),
|
|
497
|
+
expectedType: "object",
|
|
498
|
+
nodeKind: "enumStructVariantTypeNode"
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
return { ...kindObj, ...transformedFields };
|
|
502
|
+
}
|
|
503
|
+
if (isNode(variantNode, "enumTupleVariantTypeNode")) {
|
|
504
|
+
const tupleTransform = visitOrElse(variantNode.tuple, visitor, unexpectedNodeFallback);
|
|
505
|
+
if (!("fields" in rest) || !Array.isArray(rest.fields)) {
|
|
506
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__UNEXPECTED_ARGUMENT_TYPE, {
|
|
507
|
+
actualType: formatValueType(rest.fields ?? rest),
|
|
508
|
+
expectedType: "array (fields)",
|
|
509
|
+
nodeKind: "enumTupleVariantTypeNode"
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
return { ...kindObj, fields: tupleTransform(rest.fields) };
|
|
513
|
+
}
|
|
514
|
+
return input;
|
|
515
|
+
};
|
|
516
|
+
},
|
|
517
|
+
visitFixedSizeType(node) {
|
|
518
|
+
return visitOrElse(node.type, visitor, unexpectedNodeFallback);
|
|
519
|
+
},
|
|
520
|
+
visitHiddenPrefixType(node) {
|
|
521
|
+
return visitOrElse(node.type, visitor, unexpectedNodeFallback);
|
|
522
|
+
},
|
|
523
|
+
visitHiddenSuffixType(node) {
|
|
524
|
+
return visitOrElse(node.type, visitor, unexpectedNodeFallback);
|
|
525
|
+
},
|
|
526
|
+
visitMapType(node) {
|
|
527
|
+
const valueTransform = visitOrElse(node.value, visitor, unexpectedNodeFallback);
|
|
528
|
+
return (input) => {
|
|
529
|
+
if (!isObjectRecord(input)) {
|
|
530
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__UNEXPECTED_ARGUMENT_TYPE, {
|
|
531
|
+
actualType: formatValueType(input),
|
|
532
|
+
expectedType: "object",
|
|
533
|
+
nodeKind: "mapTypeNode"
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
const result = {};
|
|
537
|
+
for (const [key, value] of Object.entries(input)) {
|
|
538
|
+
result[key] = valueTransform(value);
|
|
539
|
+
}
|
|
540
|
+
return result;
|
|
541
|
+
};
|
|
542
|
+
},
|
|
543
|
+
// Primitive types (pass through)
|
|
544
|
+
visitNumberType() {
|
|
545
|
+
return (input) => input;
|
|
546
|
+
},
|
|
547
|
+
visitOptionType(node) {
|
|
548
|
+
const innerTransform = visitOrElse(node.item, visitor, unexpectedNodeFallback);
|
|
549
|
+
return (input) => {
|
|
550
|
+
if (input === null || input === void 0) return input;
|
|
551
|
+
return innerTransform(input);
|
|
552
|
+
};
|
|
553
|
+
},
|
|
554
|
+
visitPostOffsetType(node) {
|
|
555
|
+
return visitOrElse(node.type, visitor, unexpectedNodeFallback);
|
|
556
|
+
},
|
|
557
|
+
visitPreOffsetType(node) {
|
|
558
|
+
return visitOrElse(node.type, visitor, unexpectedNodeFallback);
|
|
559
|
+
},
|
|
560
|
+
visitPublicKeyType() {
|
|
561
|
+
return (input) => input;
|
|
562
|
+
},
|
|
563
|
+
visitRemainderOptionType(node) {
|
|
564
|
+
const innerTransform = visitOrElse(node.item, visitor, unexpectedNodeFallback);
|
|
565
|
+
return (input) => {
|
|
566
|
+
if (input === null || input === void 0) return input;
|
|
567
|
+
return innerTransform(input);
|
|
568
|
+
};
|
|
569
|
+
},
|
|
570
|
+
visitSentinelType(node) {
|
|
571
|
+
return visitOrElse(node.type, visitor, unexpectedNodeFallback);
|
|
572
|
+
},
|
|
573
|
+
visitSetType(node) {
|
|
574
|
+
const itemTransform = visitOrElse(node.item, visitor, unexpectedNodeFallback);
|
|
575
|
+
return (input) => {
|
|
576
|
+
if (!Array.isArray(input)) {
|
|
577
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__UNEXPECTED_ARGUMENT_TYPE, {
|
|
578
|
+
actualType: formatValueType(input),
|
|
579
|
+
expectedType: "array",
|
|
580
|
+
nodeKind: "setTypeNode"
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
return input.map(itemTransform);
|
|
584
|
+
};
|
|
585
|
+
},
|
|
586
|
+
visitSizePrefixType(node) {
|
|
587
|
+
return visitOrElse(node.type, visitor, unexpectedNodeFallback);
|
|
588
|
+
},
|
|
589
|
+
visitSolAmountType(node) {
|
|
590
|
+
return visitOrElse(node.number, visitor, unexpectedNodeFallback);
|
|
591
|
+
},
|
|
592
|
+
visitStringType() {
|
|
593
|
+
return (input) => input;
|
|
594
|
+
},
|
|
595
|
+
visitStructFieldType(node) {
|
|
596
|
+
return visitOrElse(node.type, visitor, unexpectedNodeFallback);
|
|
597
|
+
},
|
|
598
|
+
visitStructType(node) {
|
|
599
|
+
const fieldTransformers = node.fields.map((field) => {
|
|
600
|
+
const transform = visitOrElse(field, visitor, unexpectedNodeFallback);
|
|
601
|
+
return { name: field.name, transform };
|
|
602
|
+
});
|
|
603
|
+
return (input) => {
|
|
604
|
+
if (!isObjectRecord(input)) {
|
|
605
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__UNEXPECTED_ARGUMENT_TYPE, {
|
|
606
|
+
actualType: formatValueType(input),
|
|
607
|
+
expectedType: "object",
|
|
608
|
+
nodeKind: "structTypeNode"
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
const result = { ...input };
|
|
612
|
+
for (const { name, transform } of fieldTransformers) {
|
|
613
|
+
if (name in result) {
|
|
614
|
+
result[name] = transform(result[name]);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
return result;
|
|
618
|
+
};
|
|
619
|
+
},
|
|
620
|
+
visitTupleType(node) {
|
|
621
|
+
const itemTransforms = node.items.map((item) => visitOrElse(item, visitor, unexpectedNodeFallback));
|
|
622
|
+
return (input) => {
|
|
623
|
+
if (!Array.isArray(input)) {
|
|
624
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__UNEXPECTED_ARGUMENT_TYPE, {
|
|
625
|
+
actualType: formatValueType(input),
|
|
626
|
+
expectedType: "array",
|
|
627
|
+
nodeKind: "tupleTypeNode"
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
if (input.length !== itemTransforms.length) {
|
|
631
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__UNEXPECTED_ARGUMENT_TYPE, {
|
|
632
|
+
actualType: `array(length:${input.length})`,
|
|
633
|
+
expectedType: `array(length:${itemTransforms.length})`,
|
|
634
|
+
nodeKind: "tupleTypeNode"
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
return input.map((value, index) => itemTransforms[index](value));
|
|
638
|
+
};
|
|
639
|
+
},
|
|
640
|
+
visitZeroableOptionType(node) {
|
|
641
|
+
const innerTransform = visitOrElse(node.item, visitor, unexpectedNodeFallback);
|
|
642
|
+
return (input) => {
|
|
643
|
+
if (input === null || input === void 0) return input;
|
|
644
|
+
return innerTransform(input);
|
|
645
|
+
};
|
|
646
|
+
}
|
|
647
|
+
};
|
|
648
|
+
return visitor;
|
|
649
|
+
}
|
|
650
|
+
function createCodecInputTransformer(typeNode, root, options) {
|
|
651
|
+
const visitor = createCodecInputTransformerVisitor(root, options);
|
|
652
|
+
return visitOrElse(typeNode, visitor, unexpectedNodeFallback);
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
// src/visitors/pda-seed-value.ts
|
|
656
|
+
var PDA_SEED_VALUE_SUPPORTED_NODE_KINDS = [
|
|
657
|
+
"accountValueNode",
|
|
658
|
+
"argumentValueNode",
|
|
659
|
+
"booleanValueNode",
|
|
660
|
+
"bytesValueNode",
|
|
661
|
+
"constantValueNode",
|
|
662
|
+
"noneValueNode",
|
|
663
|
+
"numberValueNode",
|
|
664
|
+
"programIdValueNode",
|
|
665
|
+
"publicKeyValueNode",
|
|
666
|
+
"someValueNode",
|
|
667
|
+
"stringValueNode"
|
|
668
|
+
];
|
|
669
|
+
function createPdaSeedValueVisitor(ctx) {
|
|
670
|
+
const { root, ixNode, programId, seedTypeNode, resolversInput, resolutionPath } = ctx;
|
|
671
|
+
const accountsInput = ctx.accountsInput ?? {};
|
|
672
|
+
const argumentsInput = ctx.argumentsInput ?? {};
|
|
673
|
+
return {
|
|
674
|
+
visitAccountValue: async (node) => {
|
|
675
|
+
const resolvedAddress = await resolveAccountValueNodeAddress(node, {
|
|
676
|
+
accountsInput,
|
|
677
|
+
argumentsInput,
|
|
678
|
+
ixNode,
|
|
679
|
+
resolutionPath,
|
|
680
|
+
resolversInput,
|
|
681
|
+
root
|
|
682
|
+
});
|
|
683
|
+
if (resolvedAddress === null) {
|
|
684
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__FAILED_TO_DERIVE_PDA, {
|
|
685
|
+
accountName: node.name
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
return getMemoizedAddressEncoder().encode(resolvedAddress);
|
|
689
|
+
},
|
|
690
|
+
visitArgumentValue: async (node) => {
|
|
691
|
+
const ixArgumentNode = ixNode.arguments.find((arg) => arg.name === node.name);
|
|
692
|
+
if (!ixArgumentNode) {
|
|
693
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__NODE_REFERENCE_NOT_FOUND, {
|
|
694
|
+
instructionName: ixNode.name,
|
|
695
|
+
referencedName: node.name
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
const argInput = argumentsInput[node.name];
|
|
699
|
+
const typeNode = seedTypeNode ?? ixArgumentNode.type;
|
|
700
|
+
if (argInput === void 0 || argInput === null) {
|
|
701
|
+
if (isNode(typeNode, "remainderOptionTypeNode")) {
|
|
702
|
+
return new Uint8Array(0);
|
|
703
|
+
}
|
|
704
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__ARGUMENT_MISSING, {
|
|
705
|
+
argumentName: node.name,
|
|
706
|
+
instructionName: ixNode.name
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
const codec = getNodeCodec([root, root.program, ixNode, { ...ixArgumentNode, type: typeNode }]);
|
|
710
|
+
const transformer = createCodecInputTransformer(typeNode, root, {
|
|
711
|
+
bytesEncoding: "base16"
|
|
712
|
+
});
|
|
713
|
+
const transformedInput = transformer(argInput);
|
|
714
|
+
return await Promise.resolve(codec.encode(transformedInput));
|
|
715
|
+
},
|
|
716
|
+
visitBooleanValue: async (node) => await Promise.resolve(getMemoizedBooleanEncoder().encode(node.boolean)),
|
|
717
|
+
visitBytesValue: async (node) => {
|
|
718
|
+
const encodedValue = getCodecFromBytesEncoding(node.encoding).encode(node.data);
|
|
719
|
+
return await Promise.resolve(encodedValue);
|
|
720
|
+
},
|
|
721
|
+
visitConstantValue: async (node) => {
|
|
722
|
+
const innerVisitor = createPdaSeedValueVisitor(ctx);
|
|
723
|
+
return await visitOrElse(node.value, innerVisitor, (innerNode) => {
|
|
724
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
725
|
+
expectedKinds: [...PDA_SEED_VALUE_SUPPORTED_NODE_KINDS],
|
|
726
|
+
kind: innerNode.kind,
|
|
727
|
+
node: innerNode
|
|
728
|
+
});
|
|
729
|
+
});
|
|
730
|
+
},
|
|
731
|
+
visitNoneValue: async (_node) => await Promise.resolve(new Uint8Array(0)),
|
|
732
|
+
visitNumberValue: async (node) => {
|
|
733
|
+
if (!Number.isInteger(node.number) || node.number < 0 || node.number > 255) {
|
|
734
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__INVARIANT_VIOLATION, {
|
|
735
|
+
message: `NumberValueNode PDA seed is out of range: must be a valid u8 (0\u2013255), got ${node.number}`
|
|
736
|
+
});
|
|
737
|
+
}
|
|
738
|
+
return await Promise.resolve(new Uint8Array([node.number]));
|
|
739
|
+
},
|
|
740
|
+
visitProgramIdValue: async (_node) => {
|
|
741
|
+
return await Promise.resolve(getMemoizedAddressEncoder().encode(toAddress(programId)));
|
|
742
|
+
},
|
|
743
|
+
visitPublicKeyValue: async (node) => {
|
|
744
|
+
return await Promise.resolve(getMemoizedAddressEncoder().encode(toAddress(node.publicKey)));
|
|
745
|
+
},
|
|
746
|
+
visitSomeValue: async (node) => {
|
|
747
|
+
const innerVisitor = createPdaSeedValueVisitor(ctx);
|
|
748
|
+
return await visitOrElse(node.value, innerVisitor, (innerNode) => {
|
|
749
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
750
|
+
expectedKinds: [...PDA_SEED_VALUE_SUPPORTED_NODE_KINDS],
|
|
751
|
+
kind: innerNode.kind,
|
|
752
|
+
node: innerNode
|
|
753
|
+
});
|
|
754
|
+
});
|
|
755
|
+
},
|
|
756
|
+
visitStringValue: async (node) => await Promise.resolve(getMemoizedUtf8Codec().encode(node.string))
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
// src/resolvers/resolve-pda-address.ts
|
|
761
|
+
async function resolvePDAAddress({
|
|
762
|
+
root,
|
|
763
|
+
ixNode,
|
|
764
|
+
argumentsInput,
|
|
765
|
+
accountsInput,
|
|
766
|
+
pdaValueNode,
|
|
767
|
+
resolutionPath,
|
|
768
|
+
resolversInput
|
|
769
|
+
}) {
|
|
770
|
+
if (!isNode(pdaValueNode, "pdaValueNode")) {
|
|
771
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
772
|
+
expectedKinds: ["pdaValueNode"],
|
|
773
|
+
kind: getMaybeNodeKind(pdaValueNode),
|
|
774
|
+
node: pdaValueNode
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
const pdaNode = resolvePdaNode(pdaValueNode, root.program.pdas);
|
|
778
|
+
const programId = address(pdaNode.programId || root.program.publicKey);
|
|
779
|
+
const seedValues = await Promise.all(
|
|
780
|
+
pdaNode.seeds.map(async (seedNode) => {
|
|
781
|
+
if (seedNode.kind === "constantPdaSeedNode") {
|
|
782
|
+
return await resolveConstantPdaSeed({
|
|
783
|
+
accountsInput,
|
|
784
|
+
argumentsInput,
|
|
785
|
+
ixNode,
|
|
786
|
+
programId,
|
|
787
|
+
resolutionPath,
|
|
788
|
+
resolversInput,
|
|
789
|
+
root,
|
|
790
|
+
seedNode
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
if (seedNode.kind === "variablePdaSeedNode") {
|
|
794
|
+
const variableSeedValueNodes = pdaValueNode.seeds;
|
|
795
|
+
const seedName = seedNode.name;
|
|
796
|
+
const variableSeedValueNode = variableSeedValueNodes.find((node) => node.name === seedName);
|
|
797
|
+
if (!variableSeedValueNode) {
|
|
798
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__NODE_REFERENCE_NOT_FOUND, {
|
|
799
|
+
instructionName: ixNode.name,
|
|
800
|
+
referencedName: seedName
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
return await resolveVariablePdaSeed({
|
|
804
|
+
accountsInput,
|
|
805
|
+
argumentsInput,
|
|
806
|
+
ixNode,
|
|
807
|
+
programId,
|
|
808
|
+
resolutionPath,
|
|
809
|
+
resolversInput,
|
|
810
|
+
root,
|
|
811
|
+
seedNode,
|
|
812
|
+
variableSeedValueNode
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
throw new CodamaError(CODAMA_ERROR__UNRECOGNIZED_NODE_KIND, {
|
|
816
|
+
kind: getMaybeNodeKind(seedNode) ?? "unknown"
|
|
817
|
+
});
|
|
818
|
+
})
|
|
819
|
+
);
|
|
820
|
+
return await getProgramDerivedAddress({
|
|
821
|
+
programAddress: programId,
|
|
822
|
+
seeds: seedValues
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
function resolvePdaNode(pdaDefaultValue, pdas) {
|
|
826
|
+
if (isNode(pdaDefaultValue.pda, "pdaLinkNode")) {
|
|
827
|
+
const linkedPda = pdas.find((p) => p.name === pdaDefaultValue.pda.name);
|
|
828
|
+
if (!linkedPda) {
|
|
829
|
+
throw new CodamaError(CODAMA_ERROR__LINKED_NODE_NOT_FOUND, {
|
|
830
|
+
kind: "pdaLinkNode",
|
|
831
|
+
linkNode: pdaDefaultValue.pda,
|
|
832
|
+
name: pdaDefaultValue.pda.name,
|
|
833
|
+
path: []
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
return linkedPda;
|
|
837
|
+
}
|
|
838
|
+
if (isNode(pdaDefaultValue.pda, "pdaNode")) {
|
|
839
|
+
return pdaDefaultValue.pda;
|
|
840
|
+
}
|
|
841
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
842
|
+
expectedKinds: ["pdaLinkNode", "pdaNode"],
|
|
843
|
+
kind: getMaybeNodeKind(pdaDefaultValue.pda),
|
|
844
|
+
node: pdaDefaultValue.pda
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
function resolveVariablePdaSeed({
|
|
848
|
+
accountsInput,
|
|
849
|
+
argumentsInput,
|
|
850
|
+
ixNode,
|
|
851
|
+
programId,
|
|
852
|
+
resolutionPath,
|
|
853
|
+
resolversInput,
|
|
854
|
+
root,
|
|
855
|
+
seedNode,
|
|
856
|
+
variableSeedValueNode
|
|
857
|
+
}) {
|
|
858
|
+
if (!isNode(variableSeedValueNode, "pdaSeedValueNode")) {
|
|
859
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
860
|
+
expectedKinds: ["pdaSeedValueNode"],
|
|
861
|
+
kind: getMaybeNodeKind(variableSeedValueNode),
|
|
862
|
+
node: variableSeedValueNode
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
if (seedNode.name !== variableSeedValueNode.name) {
|
|
866
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__INVARIANT_VIOLATION, {
|
|
867
|
+
message: `Mismatched PDA seed names: expected [${seedNode.name}], got [${variableSeedValueNode.name}]`
|
|
868
|
+
});
|
|
869
|
+
}
|
|
870
|
+
const visitor = createPdaSeedValueVisitor({
|
|
871
|
+
accountsInput,
|
|
872
|
+
argumentsInput,
|
|
873
|
+
ixNode,
|
|
874
|
+
programId,
|
|
875
|
+
resolutionPath,
|
|
876
|
+
resolversInput,
|
|
877
|
+
root,
|
|
878
|
+
seedTypeNode: seedNode.type
|
|
879
|
+
});
|
|
880
|
+
return visitOrElse(variableSeedValueNode.value, visitor, (node) => {
|
|
881
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
882
|
+
expectedKinds: [...PDA_SEED_VALUE_SUPPORTED_NODE_KINDS],
|
|
883
|
+
kind: node.kind,
|
|
884
|
+
node
|
|
885
|
+
});
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
function resolveConstantPdaSeed({
|
|
889
|
+
accountsInput,
|
|
890
|
+
argumentsInput,
|
|
891
|
+
ixNode,
|
|
892
|
+
programId,
|
|
893
|
+
resolutionPath,
|
|
894
|
+
resolversInput,
|
|
895
|
+
root,
|
|
896
|
+
seedNode
|
|
897
|
+
}) {
|
|
898
|
+
if (!isNode(seedNode, "constantPdaSeedNode")) {
|
|
899
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
900
|
+
expectedKinds: ["constantPdaSeedNode"],
|
|
901
|
+
kind: seedNode.kind,
|
|
902
|
+
node: seedNode
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
const visitor = createPdaSeedValueVisitor({
|
|
906
|
+
accountsInput,
|
|
907
|
+
argumentsInput,
|
|
908
|
+
ixNode,
|
|
909
|
+
programId,
|
|
910
|
+
resolutionPath,
|
|
911
|
+
resolversInput,
|
|
912
|
+
root,
|
|
913
|
+
seedTypeNode: seedNode.type
|
|
914
|
+
});
|
|
915
|
+
return visitOrElse(seedNode.value, visitor, (node) => {
|
|
916
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
917
|
+
expectedKinds: [...PDA_SEED_VALUE_SUPPORTED_NODE_KINDS],
|
|
918
|
+
kind: node.kind,
|
|
919
|
+
node
|
|
920
|
+
});
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
// src/visitors/account-default-value.ts
|
|
925
|
+
var ACCOUNT_DEFAULT_VALUE_SUPPORTED_NODE_KINDS = [
|
|
926
|
+
"accountBumpValueNode",
|
|
927
|
+
"accountValueNode",
|
|
928
|
+
"argumentValueNode",
|
|
929
|
+
"conditionalValueNode",
|
|
930
|
+
"identityValueNode",
|
|
931
|
+
"payerValueNode",
|
|
932
|
+
"pdaValueNode",
|
|
933
|
+
"programIdValueNode",
|
|
934
|
+
"publicKeyValueNode",
|
|
935
|
+
"resolverValueNode"
|
|
936
|
+
];
|
|
937
|
+
function createAccountDefaultValueVisitor(ctx) {
|
|
938
|
+
const { root, ixNode, ixAccountNode, argumentsInput, accountsInput, resolversInput, resolutionPath } = ctx;
|
|
939
|
+
const accountAddressInput = accountsInput?.[ixAccountNode.name];
|
|
940
|
+
return {
|
|
941
|
+
visitAccountBumpValue: async (_node) => {
|
|
942
|
+
return await Promise.reject(
|
|
943
|
+
new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__UNSUPPORTED_NODE, {
|
|
944
|
+
nodeKind: "accountBumpValueNode"
|
|
945
|
+
})
|
|
946
|
+
);
|
|
947
|
+
},
|
|
948
|
+
visitAccountValue: async (node) => {
|
|
949
|
+
return await resolveAccountValueNodeAddress(node, {
|
|
950
|
+
accountsInput,
|
|
951
|
+
argumentsInput,
|
|
952
|
+
ixNode,
|
|
953
|
+
resolutionPath,
|
|
954
|
+
resolversInput,
|
|
955
|
+
root
|
|
956
|
+
});
|
|
957
|
+
},
|
|
958
|
+
visitArgumentValue: async (node) => {
|
|
959
|
+
const argValue = argumentsInput?.[node.name];
|
|
960
|
+
if (argValue === void 0 || argValue === null) {
|
|
961
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__ARGUMENT_MISSING, {
|
|
962
|
+
argumentName: node.name,
|
|
963
|
+
instructionName: ixNode.name
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
if (!isAddressConvertible(argValue)) {
|
|
967
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__UNEXPECTED_ADDRESS_TYPE, {
|
|
968
|
+
accountName: ixAccountNode.name,
|
|
969
|
+
actualType: formatValueType(argValue),
|
|
970
|
+
expectedType: "Address | PublicKey"
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
return await Promise.resolve(toAddress(argValue));
|
|
974
|
+
},
|
|
975
|
+
visitConditionalValue: async (conditionalValueNode) => {
|
|
976
|
+
const resolvedInputValueNode = await resolveConditionalValueNodeCondition({
|
|
977
|
+
accountsInput,
|
|
978
|
+
argumentsInput,
|
|
979
|
+
conditionalValueNode,
|
|
980
|
+
ixAccountNode,
|
|
981
|
+
ixNode,
|
|
982
|
+
resolutionPath,
|
|
983
|
+
resolversInput,
|
|
984
|
+
root
|
|
985
|
+
});
|
|
986
|
+
if (resolvedInputValueNode === void 0) {
|
|
987
|
+
if (ixAccountNode.isOptional) {
|
|
988
|
+
return null;
|
|
989
|
+
}
|
|
990
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__ACCOUNT_MISSING, {
|
|
991
|
+
accountName: ixAccountNode.name,
|
|
992
|
+
instructionName: ixNode.name
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
const visitor = createAccountDefaultValueVisitor(ctx);
|
|
996
|
+
const addressValue = await visitOrElse(resolvedInputValueNode, visitor, (innerNode) => {
|
|
997
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
998
|
+
expectedKinds: [...ACCOUNT_DEFAULT_VALUE_SUPPORTED_NODE_KINDS],
|
|
999
|
+
kind: innerNode.kind,
|
|
1000
|
+
node: innerNode
|
|
1001
|
+
});
|
|
1002
|
+
});
|
|
1003
|
+
return addressValue;
|
|
1004
|
+
},
|
|
1005
|
+
visitIdentityValue: async (_node) => {
|
|
1006
|
+
if (accountAddressInput === void 0 || accountAddressInput === null) {
|
|
1007
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__ACCOUNT_MISSING, {
|
|
1008
|
+
accountName: ixAccountNode.name,
|
|
1009
|
+
instructionName: ixNode.name
|
|
1010
|
+
});
|
|
1011
|
+
}
|
|
1012
|
+
return await Promise.resolve(toAddress(accountAddressInput));
|
|
1013
|
+
},
|
|
1014
|
+
visitPayerValue: async (_node) => {
|
|
1015
|
+
if (accountAddressInput === void 0 || accountAddressInput === null) {
|
|
1016
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__ACCOUNT_MISSING, {
|
|
1017
|
+
accountName: ixAccountNode.name,
|
|
1018
|
+
instructionName: ixNode.name
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
1021
|
+
return await Promise.resolve(toAddress(accountAddressInput));
|
|
1022
|
+
},
|
|
1023
|
+
visitPdaValue: async (node) => {
|
|
1024
|
+
const pda = await resolvePDAAddress({
|
|
1025
|
+
accountsInput,
|
|
1026
|
+
argumentsInput,
|
|
1027
|
+
ixNode,
|
|
1028
|
+
pdaValueNode: node,
|
|
1029
|
+
resolutionPath,
|
|
1030
|
+
resolversInput,
|
|
1031
|
+
root
|
|
1032
|
+
});
|
|
1033
|
+
if (pda === null) {
|
|
1034
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__FAILED_TO_DERIVE_PDA, {
|
|
1035
|
+
accountName: ixAccountNode.name
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
return pda[0];
|
|
1039
|
+
},
|
|
1040
|
+
visitProgramIdValue: async (_node) => {
|
|
1041
|
+
return await Promise.resolve(address(root.program.publicKey));
|
|
1042
|
+
},
|
|
1043
|
+
visitPublicKeyValue: async (node) => {
|
|
1044
|
+
return await Promise.resolve(address(node.publicKey));
|
|
1045
|
+
},
|
|
1046
|
+
visitResolverValue: async (node) => {
|
|
1047
|
+
const resolverFn = resolversInput?.[node.name];
|
|
1048
|
+
if (!resolverFn) {
|
|
1049
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__ACCOUNT_RESOLVER_MISSING, {
|
|
1050
|
+
accountName: ixAccountNode.name,
|
|
1051
|
+
resolverName: node.name
|
|
1052
|
+
});
|
|
1053
|
+
}
|
|
1054
|
+
let result;
|
|
1055
|
+
try {
|
|
1056
|
+
result = await resolverFn(argumentsInput ?? {}, accountsInput ?? {});
|
|
1057
|
+
} catch (error) {
|
|
1058
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__FAILED_TO_EXECUTE_RESOLVER, {
|
|
1059
|
+
cause: error,
|
|
1060
|
+
resolverName: node.name,
|
|
1061
|
+
targetKind: "instructionAccountNode",
|
|
1062
|
+
targetName: ixAccountNode.name
|
|
1063
|
+
});
|
|
1064
|
+
}
|
|
1065
|
+
if (!isAddressConvertible(result)) {
|
|
1066
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__INVALID_ACCOUNT_ADDRESS, {
|
|
1067
|
+
accountName: ixAccountNode.name,
|
|
1068
|
+
value: safeStringify(result)
|
|
1069
|
+
});
|
|
1070
|
+
}
|
|
1071
|
+
return toAddress(result);
|
|
1072
|
+
}
|
|
1073
|
+
};
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
// src/resolvers/resolve-account-address.ts
|
|
1077
|
+
async function resolveAccountAddress({
|
|
1078
|
+
root,
|
|
1079
|
+
ixNode,
|
|
1080
|
+
ixAccountNode,
|
|
1081
|
+
argumentsInput,
|
|
1082
|
+
accountsInput,
|
|
1083
|
+
resolutionPath,
|
|
1084
|
+
resolversInput
|
|
1085
|
+
}) {
|
|
1086
|
+
const accountAddressInput = accountsInput?.[ixAccountNode.name];
|
|
1087
|
+
if (accountAddressInput === null && ixAccountNode.isOptional) {
|
|
1088
|
+
return resolveOptionalAccountWithStrategy(root, ixNode, ixAccountNode);
|
|
1089
|
+
}
|
|
1090
|
+
if (ixAccountNode.defaultValue) {
|
|
1091
|
+
const visitor = createAccountDefaultValueVisitor({
|
|
1092
|
+
accountsInput,
|
|
1093
|
+
argumentsInput,
|
|
1094
|
+
ixAccountNode,
|
|
1095
|
+
ixNode,
|
|
1096
|
+
resolutionPath,
|
|
1097
|
+
resolversInput,
|
|
1098
|
+
root
|
|
1099
|
+
});
|
|
1100
|
+
const addressValue = await visitOrElse(ixAccountNode.defaultValue, visitor, (node) => {
|
|
1101
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
1102
|
+
expectedKinds: [...ACCOUNT_DEFAULT_VALUE_SUPPORTED_NODE_KINDS],
|
|
1103
|
+
kind: node.kind,
|
|
1104
|
+
node
|
|
1105
|
+
});
|
|
1106
|
+
});
|
|
1107
|
+
if (addressValue === null && ixAccountNode.isOptional) {
|
|
1108
|
+
return resolveOptionalAccountWithStrategy(root, ixNode, ixAccountNode);
|
|
1109
|
+
}
|
|
1110
|
+
return addressValue;
|
|
1111
|
+
}
|
|
1112
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__ACCOUNT_MISSING, {
|
|
1113
|
+
accountName: ixAccountNode.name,
|
|
1114
|
+
instructionName: ixNode.name
|
|
1115
|
+
});
|
|
1116
|
+
}
|
|
1117
|
+
function resolveOptionalAccountWithStrategy(root, ixNode, ixAccountNode) {
|
|
1118
|
+
if (!ixAccountNode.isOptional) {
|
|
1119
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__INVARIANT_VIOLATION, {
|
|
1120
|
+
message: `resolveOptionalAccountWithStrategy called for non-optional account: ${ixAccountNode.name}`
|
|
1121
|
+
});
|
|
1122
|
+
}
|
|
1123
|
+
switch (ixNode.optionalAccountStrategy) {
|
|
1124
|
+
case "omitted":
|
|
1125
|
+
return null;
|
|
1126
|
+
case "programId":
|
|
1127
|
+
return toAddress(root.program.publicKey);
|
|
1128
|
+
default:
|
|
1129
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__UNSUPPORTED_OPTIONAL_ACCOUNT_STRATEGY, {
|
|
1130
|
+
accountName: ixAccountNode.name,
|
|
1131
|
+
instructionName: ixNode.name,
|
|
1132
|
+
strategy: safeStringify(ixNode.optionalAccountStrategy)
|
|
1133
|
+
});
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
async function resolveInstructionAccountAddress({
|
|
1137
|
+
accountsInput,
|
|
1138
|
+
argumentsInput,
|
|
1139
|
+
ixAccountNode,
|
|
1140
|
+
ixNode,
|
|
1141
|
+
resolversInput,
|
|
1142
|
+
root
|
|
1143
|
+
}) {
|
|
1144
|
+
const accountAddressInput = accountsInput?.[ixAccountNode.name];
|
|
1145
|
+
const isAccountProvided = accountAddressInput !== void 0 && accountAddressInput !== null;
|
|
1146
|
+
const canAutoResolve = !!ixAccountNode.defaultValue || ixAccountNode.isOptional && accountAddressInput === null;
|
|
1147
|
+
if (!isAccountProvided && !canAutoResolve) {
|
|
1148
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__ACCOUNT_MISSING, {
|
|
1149
|
+
accountName: ixAccountNode.name,
|
|
1150
|
+
instructionName: ixNode.name
|
|
1151
|
+
});
|
|
1152
|
+
}
|
|
1153
|
+
if (isAccountProvided) {
|
|
1154
|
+
return toAddress(accountAddressInput);
|
|
1155
|
+
}
|
|
1156
|
+
return await resolveAccountAddress({
|
|
1157
|
+
accountsInput,
|
|
1158
|
+
argumentsInput,
|
|
1159
|
+
ixAccountNode,
|
|
1160
|
+
ixNode,
|
|
1161
|
+
resolutionPath: [],
|
|
1162
|
+
resolversInput,
|
|
1163
|
+
root
|
|
1164
|
+
});
|
|
1165
|
+
}
|
|
1166
|
+
var STANDALONE_IX_NODE = {
|
|
1167
|
+
accounts: [],
|
|
1168
|
+
arguments: [],
|
|
1169
|
+
kind: "instructionNode",
|
|
1170
|
+
name: "__standalone__"
|
|
1171
|
+
};
|
|
1172
|
+
async function resolveStandalonePda(root, pdaNode, seedInputs = {}) {
|
|
1173
|
+
const programAddress = toAddress(pdaNode.programId || root.program.publicKey);
|
|
1174
|
+
const seedValues = await Promise.all(
|
|
1175
|
+
pdaNode.seeds.map(async (seedNode) => {
|
|
1176
|
+
if (seedNode.kind === "constantPdaSeedNode") {
|
|
1177
|
+
return await resolveStandaloneConstantSeed(root, programAddress, seedNode);
|
|
1178
|
+
}
|
|
1179
|
+
if (seedNode.kind === "variablePdaSeedNode") {
|
|
1180
|
+
return await resolveStandaloneVariableSeed(root, seedNode, seedInputs);
|
|
1181
|
+
}
|
|
1182
|
+
throw new CodamaError(CODAMA_ERROR__UNRECOGNIZED_NODE_KIND, {
|
|
1183
|
+
kind: getMaybeNodeKind(seedNode) ?? "unknown"
|
|
1184
|
+
});
|
|
1185
|
+
})
|
|
1186
|
+
);
|
|
1187
|
+
return await getProgramDerivedAddress({ programAddress, seeds: seedValues });
|
|
1188
|
+
}
|
|
1189
|
+
function resolveStandaloneConstantSeed(root, programAddress, seedNode) {
|
|
1190
|
+
if (!isNode(seedNode, "constantPdaSeedNode")) {
|
|
1191
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
1192
|
+
expectedKinds: ["constantPdaSeedNode"],
|
|
1193
|
+
kind: seedNode.kind,
|
|
1194
|
+
node: seedNode
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
1197
|
+
const visitor = createPdaSeedValueVisitor({
|
|
1198
|
+
accountsInput: void 0,
|
|
1199
|
+
argumentsInput: void 0,
|
|
1200
|
+
ixNode: STANDALONE_IX_NODE,
|
|
1201
|
+
programId: programAddress,
|
|
1202
|
+
resolutionPath: [],
|
|
1203
|
+
resolversInput: void 0,
|
|
1204
|
+
root
|
|
1205
|
+
});
|
|
1206
|
+
return visitOrElse(seedNode.value, visitor, (node) => {
|
|
1207
|
+
throw new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
|
|
1208
|
+
expectedKinds: Array.from(PDA_SEED_VALUE_SUPPORTED_NODE_KINDS),
|
|
1209
|
+
kind: node.kind,
|
|
1210
|
+
node
|
|
1211
|
+
});
|
|
1212
|
+
});
|
|
1213
|
+
}
|
|
1214
|
+
function resolveStandaloneVariableSeed(root, seedNode, seedInputs) {
|
|
1215
|
+
const input = seedInputs[seedNode.name];
|
|
1216
|
+
const typeNode = seedNode.type;
|
|
1217
|
+
if (input === void 0 || input === null) {
|
|
1218
|
+
if (isNode(typeNode, "remainderOptionTypeNode")) {
|
|
1219
|
+
return Promise.resolve(new Uint8Array(0));
|
|
1220
|
+
}
|
|
1221
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__ARGUMENT_MISSING, {
|
|
1222
|
+
argumentName: seedNode.name,
|
|
1223
|
+
instructionName: camelCase("standaloneSeedNode")
|
|
1224
|
+
});
|
|
1225
|
+
}
|
|
1226
|
+
if (isNode(typeNode, "stringTypeNode")) {
|
|
1227
|
+
if (typeof input !== "string") {
|
|
1228
|
+
throw new CodamaError(CODAMA_ERROR__DYNAMIC_CLIENT__UNEXPECTED_ARGUMENT_TYPE, {
|
|
1229
|
+
actualType: formatValueType(input),
|
|
1230
|
+
expectedType: "string",
|
|
1231
|
+
nodeKind: "stringTypeNode"
|
|
1232
|
+
});
|
|
1233
|
+
}
|
|
1234
|
+
return Promise.resolve(getMemoizedUtf8Encoder().encode(input));
|
|
1235
|
+
}
|
|
1236
|
+
const syntheticArgNode = createSyntheticArgNode(seedNode);
|
|
1237
|
+
const codec = getNodeCodec([root, root.program, syntheticArgNode]);
|
|
1238
|
+
const transformer = createCodecInputTransformer(typeNode, root, { bytesEncoding: "base16" });
|
|
1239
|
+
const transformedInput = transformer(input);
|
|
1240
|
+
return Promise.resolve(codec.encode(transformedInput));
|
|
1241
|
+
}
|
|
1242
|
+
function createSyntheticArgNode(seedNode) {
|
|
1243
|
+
return {
|
|
1244
|
+
docs: [],
|
|
1245
|
+
kind: "instructionArgumentNode",
|
|
1246
|
+
name: seedNode.name,
|
|
1247
|
+
type: seedNode.type
|
|
1248
|
+
};
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
// src/visitors/default-value-encoder.ts
|
|
1252
|
+
var DEFAULT_VALUE_ENCODER_SUPPORTED_NODE_KINDS = [
|
|
1253
|
+
"booleanValueNode",
|
|
1254
|
+
"bytesValueNode",
|
|
1255
|
+
"enumValueNode",
|
|
1256
|
+
"noneValueNode",
|
|
1257
|
+
"numberValueNode",
|
|
1258
|
+
"publicKeyValueNode",
|
|
1259
|
+
"stringValueNode"
|
|
1260
|
+
];
|
|
1261
|
+
function createDefaultValueEncoderVisitor(codec) {
|
|
1262
|
+
return {
|
|
1263
|
+
visitBooleanValue: (node) => codec.encode(node.boolean),
|
|
1264
|
+
visitBytesValue: (node) => codec.encode([node.encoding, node.data]),
|
|
1265
|
+
visitEnumValue: (node) => codec.encode(node.variant),
|
|
1266
|
+
visitNoneValue: () => codec.encode(null),
|
|
1267
|
+
visitNumberValue: (node) => codec.encode(node.number),
|
|
1268
|
+
visitPublicKeyValue: (node) => codec.encode(node.publicKey),
|
|
1269
|
+
visitStringValue: (node) => codec.encode(node.string)
|
|
1270
|
+
};
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
// src/shared/nodes.ts
|
|
1274
|
+
var OPTIONAL_NODE_KINDS = ["optionTypeNode", "zeroableOptionTypeNode", "remainderOptionTypeNode"];
|
|
1275
|
+
|
|
1276
|
+
export { DEFAULT_VALUE_ENCODER_SUPPORTED_NODE_KINDS, OPTIONAL_NODE_KINDS, createCodecInputTransformer, createDefaultValueEncoderVisitor, isAddressConvertible, isPublicKeyLike, resolveInstructionAccountAddress, resolveStandalonePda, toAddress };
|
|
1277
|
+
//# sourceMappingURL=index.node.mjs.map
|
|
1278
|
+
//# sourceMappingURL=index.node.mjs.map
|