@codama/dynamic-instructions 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.
Files changed (39) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +97 -0
  3. package/dist/index.browser.cjs +752 -0
  4. package/dist/index.browser.cjs.map +1 -0
  5. package/dist/index.browser.mjs +741 -0
  6. package/dist/index.browser.mjs.map +1 -0
  7. package/dist/index.node.cjs +752 -0
  8. package/dist/index.node.cjs.map +1 -0
  9. package/dist/index.node.mjs +741 -0
  10. package/dist/index.node.mjs.map +1 -0
  11. package/dist/index.react-native.mjs +741 -0
  12. package/dist/index.react-native.mjs.map +1 -0
  13. package/dist/types/accounts/create-account-meta.d.ts +11 -0
  14. package/dist/types/accounts/create-account-meta.d.ts.map +1 -0
  15. package/dist/types/accounts/index.d.ts +3 -0
  16. package/dist/types/accounts/index.d.ts.map +1 -0
  17. package/dist/types/accounts/validate-accounts-input.d.ts +9 -0
  18. package/dist/types/accounts/validate-accounts-input.d.ts.map +1 -0
  19. package/dist/types/arguments/encode-instruction-arguments.d.ts +13 -0
  20. package/dist/types/arguments/encode-instruction-arguments.d.ts.map +1 -0
  21. package/dist/types/arguments/index.d.ts +4 -0
  22. package/dist/types/arguments/index.d.ts.map +1 -0
  23. package/dist/types/arguments/resolve-argument-from-custom-resolvers.d.ts +9 -0
  24. package/dist/types/arguments/resolve-argument-from-custom-resolvers.d.ts.map +1 -0
  25. package/dist/types/arguments/shared.d.ts +4 -0
  26. package/dist/types/arguments/shared.d.ts.map +1 -0
  27. package/dist/types/arguments/validate-arguments-input.d.ts +11 -0
  28. package/dist/types/arguments/validate-arguments-input.d.ts.map +1 -0
  29. package/dist/types/index.d.ts +6 -0
  30. package/dist/types/index.d.ts.map +1 -0
  31. package/dist/types/instructions-builder.d.ts +18 -0
  32. package/dist/types/instructions-builder.d.ts.map +1 -0
  33. package/dist/types/shared/types.d.ts +15 -0
  34. package/dist/types/shared/types.d.ts.map +1 -0
  35. package/dist/types/shared/util.d.ts +14 -0
  36. package/dist/types/shared/util.d.ts.map +1 -0
  37. package/dist/types/validators.d.ts +16 -0
  38. package/dist/types/validators.d.ts.map +1 -0
  39. package/package.json +76 -0
@@ -0,0 +1,752 @@
1
+ 'use strict';
2
+
3
+ var dynamicAddressResolution = require('@codama/dynamic-address-resolution');
4
+ var errors = require('@codama/errors');
5
+ var instructions = require('@solana/instructions');
6
+ var codama = require('codama');
7
+ var superstruct = require('superstruct');
8
+ var addresses = require('@solana/addresses');
9
+ var codecs = require('@solana/codecs');
10
+ var dynamicCodecs = require('@codama/dynamic-codecs');
11
+
12
+ // src/accounts/create-account-meta.ts
13
+
14
+ // src/shared/util.ts
15
+ function isObjectRecord(value) {
16
+ return typeof value === "object" && value !== null && Object.getPrototypeOf(value) === Object.prototype;
17
+ }
18
+ function getMaybeNodeKind(node) {
19
+ if (!isObjectRecord(node)) return null;
20
+ return node.kind ?? null;
21
+ }
22
+ function formatValueType(value) {
23
+ if (value === null) return "null";
24
+ if (Array.isArray(value)) return `array (length ${value.length})`;
25
+ if (value instanceof Uint8Array) return `Uint8Array (length ${value.length})`;
26
+ if (typeof value === "object") return "object";
27
+ return typeof value;
28
+ }
29
+ function safeStringify(value) {
30
+ try {
31
+ return JSON.stringify(value, (_key, v) => typeof v === "bigint" ? String(v) : v);
32
+ } catch {
33
+ return `non-serializable ${formatValueType(value)}`;
34
+ }
35
+ }
36
+
37
+ // src/accounts/create-account-meta.ts
38
+ async function createAccountMeta(root, ixNode, argumentsInput, accountsInput, signers = [], resolversInput) {
39
+ const programAddress = dynamicAddressResolution.toAddress(root.program.publicKey);
40
+ const resolvedAccounts = await Promise.all(
41
+ ixNode.accounts.map(async (ixAccountNode) => {
42
+ const finalAddress = await dynamicAddressResolution.resolveInstructionAccountAddress({
43
+ accountsInput,
44
+ argumentsInput,
45
+ ixAccountNode,
46
+ ixNode,
47
+ resolversInput,
48
+ root
49
+ });
50
+ const accountAddressInput = accountsInput?.[ixAccountNode.name];
51
+ const isAccountProvided = accountAddressInput !== void 0 && accountAddressInput !== null;
52
+ const role = ixAccountNode.isOptional && !isAccountProvided && ixNode.optionalAccountStrategy === "programId" && finalAddress === programAddress ? getReadonlyAccountRole(ixAccountNode, signers) : getAccountRole(ixAccountNode, signers);
53
+ return {
54
+ address: finalAddress,
55
+ optional: Boolean(ixAccountNode.isOptional),
56
+ role
57
+ };
58
+ })
59
+ );
60
+ const accountMetas = resolvedAccounts.filter((acc) => acc.address !== null).map((acc) => ({
61
+ address: acc.address,
62
+ role: acc.role
63
+ }));
64
+ for (const remainingNode of ixNode.remainingAccounts ?? []) {
65
+ if (!codama.isNode(remainingNode.value, "argumentValueNode")) {
66
+ throw new errors.CodamaError(errors.CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
67
+ expectedKinds: ["argumentValueNode"],
68
+ kind: remainingNode.value.kind,
69
+ node: remainingNode.value
70
+ });
71
+ }
72
+ const addresses = argumentsInput?.[remainingNode.value.name];
73
+ if (addresses === void 0) {
74
+ if (!remainingNode.isOptional) {
75
+ throw new errors.CodamaError(errors.CODAMA_ERROR__DYNAMIC_CLIENT__ARGUMENT_MISSING, {
76
+ argumentName: remainingNode.value.name,
77
+ instructionName: ixNode.name
78
+ });
79
+ }
80
+ continue;
81
+ }
82
+ if (!Array.isArray(addresses)) {
83
+ throw new errors.CodamaError(errors.CODAMA_ERROR__DYNAMIC_CLIENT__INVALID_ARGUMENT_INPUT, {
84
+ argumentName: remainingNode.value.name,
85
+ expectedType: "Address[]",
86
+ value: safeStringify(addresses)
87
+ });
88
+ }
89
+ const role = getRemainingAccountRole(remainingNode.isSigner, remainingNode.isWritable);
90
+ for (let i = 0; i < addresses.length; i++) {
91
+ const addr = addresses[i];
92
+ if (!dynamicAddressResolution.isAddressConvertible(addr)) {
93
+ throw new errors.CodamaError(errors.CODAMA_ERROR__DYNAMIC_CLIENT__UNEXPECTED_ADDRESS_TYPE, {
94
+ accountName: `${remainingNode.value.name}[${i}]`,
95
+ actualType: formatValueType(addr),
96
+ expectedType: "Address | PublicKey"
97
+ });
98
+ }
99
+ accountMetas.push({ address: dynamicAddressResolution.toAddress(addr), role });
100
+ }
101
+ }
102
+ return accountMetas;
103
+ }
104
+ function getRemainingAccountRole(isSigner, isWritable) {
105
+ const signer = isSigner === true || isSigner === "either";
106
+ const writable = isWritable === true;
107
+ if (writable && signer) return instructions.AccountRole.WRITABLE_SIGNER;
108
+ if (writable) return instructions.AccountRole.WRITABLE;
109
+ if (signer) return instructions.AccountRole.READONLY_SIGNER;
110
+ return instructions.AccountRole.READONLY;
111
+ }
112
+ function getAccountRole(acc, signers) {
113
+ const isSigner = isSignerAccount(acc, signers ?? []);
114
+ if (acc.isWritable && isSigner) {
115
+ return instructions.AccountRole.WRITABLE_SIGNER;
116
+ }
117
+ if (acc.isWritable) {
118
+ return instructions.AccountRole.WRITABLE;
119
+ }
120
+ if (isSigner) {
121
+ return instructions.AccountRole.READONLY_SIGNER;
122
+ }
123
+ return instructions.AccountRole.READONLY;
124
+ }
125
+ function getReadonlyAccountRole(acc, signers) {
126
+ const isSigner = isSignerAccount(acc, signers ?? []);
127
+ return isSigner ? instructions.AccountRole.READONLY_SIGNER : instructions.AccountRole.READONLY;
128
+ }
129
+ function isSignerAccount(acc, signers) {
130
+ if (acc.isSigner === "either") {
131
+ return signers.includes(acc.name);
132
+ }
133
+ return acc.isSigner === true;
134
+ }
135
+ function createIxAccountsValidator(ixAccountNodes) {
136
+ const shape = ixAccountNodes.reduce((acc, node) => {
137
+ acc[node.name] = node.isOptional || node.defaultValue ? OptionalSolanaAddressValidator : SolanaAddressValidator;
138
+ return acc;
139
+ }, {});
140
+ return superstruct.object(shape);
141
+ }
142
+ function createIxArgumentsValidator(ixNodeName, ixArgumentNodes, definedTypes) {
143
+ const shape = ixArgumentNodes.reduce((acc, argumentNode, index) => {
144
+ if (!argumentNode.type) {
145
+ throw new Error(`Argument ${argumentNode.name} of instruction ${ixNodeName} does not have a type`);
146
+ }
147
+ acc[argumentNode.name] = createValidatorForTypeNode(
148
+ `${ixNodeName}_${argumentNode.name}_${index}`,
149
+ argumentNode.type,
150
+ definedTypes
151
+ );
152
+ return acc;
153
+ }, {});
154
+ return superstruct.object(shape);
155
+ }
156
+ function createValidatorForTypeNode(nodeName, node, definedTypes) {
157
+ if (!node) {
158
+ throw new Error(
159
+ `Node ${nodeName} is not defined. ${definedTypes.length} defined types were provided: ${definedTypes.map((t) => t.name).join(", ")}`
160
+ );
161
+ }
162
+ switch (node.kind) {
163
+ case "arrayTypeNode": {
164
+ return ArrayValidator(`${nodeName}_array`, node, definedTypes);
165
+ }
166
+ case "booleanTypeNode": {
167
+ return superstruct.boolean();
168
+ }
169
+ case "numberTypeNode": {
170
+ const format = node.format;
171
+ if (format === "u64" || format === "u128" || format === "i64" || format === "i128") {
172
+ return NumberOrBigintValidator;
173
+ }
174
+ return superstruct.number();
175
+ }
176
+ case "publicKeyTypeNode": {
177
+ return SolanaAddressValidator;
178
+ }
179
+ case "setTypeNode": {
180
+ return superstruct.intersection([
181
+ UniqueItemsValidator,
182
+ ArrayValidator(`${nodeName}_set`, node, definedTypes)
183
+ ]);
184
+ }
185
+ case "stringTypeNode": {
186
+ return superstruct.string();
187
+ }
188
+ case "fixedSizeTypeNode": {
189
+ if (node.type.kind === "stringTypeNode") {
190
+ return StringValidatorForFixedSize(node.size);
191
+ }
192
+ if (node.type.kind === "bytesTypeNode") {
193
+ return BytesWithSizeValidator(node.size);
194
+ }
195
+ return createValidatorForTypeNode(`${nodeName}_fixed_size`, node.type, definedTypes);
196
+ }
197
+ case "bytesTypeNode": {
198
+ return BytesLikeValidator;
199
+ }
200
+ case "dateTimeTypeNode": {
201
+ return createValidatorForTypeNode(`${nodeName}_date_time`, node.number, definedTypes);
202
+ }
203
+ case "definedTypeLinkNode": {
204
+ const definedType = definedTypes.find((d) => d.name === node.name);
205
+ if (!definedType) {
206
+ throw new Error(`Undefined type: ${node.name} ${node.kind}`);
207
+ }
208
+ return createValidatorForTypeNode(`${nodeName}_defined_type`, definedType.type, definedTypes);
209
+ }
210
+ case "mapTypeNode": {
211
+ const keyValidator = createValidatorForTypeNode(
212
+ `${nodeName}_map_key_${node.key.kind}`,
213
+ node.key,
214
+ definedTypes
215
+ );
216
+ const valueValidator = createValidatorForTypeNode(
217
+ `${nodeName}_map_value_${node.value.kind}`,
218
+ node.value,
219
+ definedTypes
220
+ );
221
+ const sizeValidator = MapCountValidator(node.count);
222
+ const keyValueValidator = KeyValueValidator(nodeName, keyValidator, valueValidator);
223
+ if (sizeValidator) {
224
+ return superstruct.intersection([keyValueValidator, sizeValidator]);
225
+ }
226
+ return keyValueValidator;
227
+ }
228
+ case "structTypeNode": {
229
+ const structShape = node.fields.reduce((acc, field) => {
230
+ acc[field.name] = createValidatorForTypeNode(
231
+ `${nodeName}_struct_${field.name}`,
232
+ field.type,
233
+ definedTypes
234
+ );
235
+ return acc;
236
+ }, {});
237
+ return superstruct.object(structShape);
238
+ }
239
+ case "tupleTypeNode": {
240
+ const validators = node.items.map(
241
+ (typeNode, index) => createValidatorForTypeNode(`${nodeName}_tuple${typeNode.kind}_${index}`, typeNode, definedTypes)
242
+ );
243
+ return superstruct.tuple(validators);
244
+ }
245
+ case "zeroableOptionTypeNode": {
246
+ const innerValidator = createValidatorForTypeNode(
247
+ `${nodeName}_zeroable_option_item`,
248
+ node.item,
249
+ definedTypes
250
+ );
251
+ return ZeroableOptionValidator(`${nodeName}_zeroable_option`, innerValidator);
252
+ }
253
+ case "optionTypeNode": {
254
+ const SomeValueValidator = createValidatorForTypeNode(`${nodeName}_option_item`, node.item, definedTypes);
255
+ return OptionValueValidator(`${nodeName}_option`, SomeValueValidator);
256
+ }
257
+ case "remainderOptionTypeNode": {
258
+ const innerValidator = RemainderOptionTypeItemValidator(
259
+ `${nodeName}_remainder_option_item`,
260
+ node.item,
261
+ definedTypes
262
+ );
263
+ return OptionValueValidator(`${nodeName}_remainder_option`, innerValidator);
264
+ }
265
+ case "hiddenPrefixTypeNode":
266
+ case "hiddenSuffixTypeNode":
267
+ case "sentinelTypeNode":
268
+ case "postOffsetTypeNode":
269
+ case "preOffsetTypeNode":
270
+ case "sizePrefixTypeNode": {
271
+ return createValidatorForTypeNode(`${nodeName}_size_prefix`, node.type, definedTypes);
272
+ }
273
+ case "enumTypeNode": {
274
+ return EnumVariantValidator(nodeName, node.variants, definedTypes);
275
+ }
276
+ case "amountTypeNode": {
277
+ return AmountTypeValidator(nodeName);
278
+ }
279
+ case "solAmountTypeNode": {
280
+ return AmountTypeValidator(nodeName);
281
+ }
282
+ default: {
283
+ node["kind"];
284
+ throw new Error(`Validator for TypeNode "${nodeName}" kind: ${getMaybeNodeKind(node)} is not implemented!`);
285
+ }
286
+ }
287
+ }
288
+ function RemainderOptionTypeItemValidator(nodeName, itemNode, definedTypes) {
289
+ if (itemNode.kind === "fixedSizeTypeNode" && itemNode.type.kind === "stringTypeNode") {
290
+ return StringValidatorForFixedSize(itemNode.size);
291
+ }
292
+ if (itemNode.kind === "definedTypeLinkNode") {
293
+ const definedType = definedTypes.find((d) => d.name === itemNode.name);
294
+ if (definedType?.type.kind === "fixedSizeTypeNode" && definedType.type.type.kind === "stringTypeNode") {
295
+ return StringValidatorForFixedSize(definedType.type.size);
296
+ }
297
+ }
298
+ return createValidatorForTypeNode(nodeName, itemNode, definedTypes);
299
+ }
300
+ function StringValidatorForFixedSize(maxSize) {
301
+ return superstruct.define(`StringForFixedSize_max_${maxSize}`, (value) => {
302
+ if (typeof value !== "string") {
303
+ return `Expected a string, received: ${formatValueType(value)}`;
304
+ }
305
+ const encoder = codecs.getUtf8Encoder();
306
+ const bytes = encoder.encode(value);
307
+ return bytes.length <= maxSize || `String exceeds max size: ${bytes.length} bytes (UTF-8), limit is ${maxSize} bytes`;
308
+ });
309
+ }
310
+ function EnumVariantValidator(nodeName, variants, definedTypes) {
311
+ const variantMap = new Map(variants.map((v) => [v.name, v]));
312
+ const variantNames = Array.from(variantMap.keys());
313
+ const variantValidators = /* @__PURE__ */ new Map();
314
+ for (const variant of variants) {
315
+ if (variant.kind === "enumStructVariantTypeNode") {
316
+ variantValidators.set(
317
+ variant.name,
318
+ createValidatorForTypeNode(`${nodeName}_${variant.name}`, variant.struct, definedTypes)
319
+ );
320
+ } else if (variant.kind === "enumTupleVariantTypeNode") {
321
+ variantValidators.set(
322
+ variant.name,
323
+ createValidatorForTypeNode(`${nodeName}_${variant.name}`, variant.tuple, definedTypes)
324
+ );
325
+ }
326
+ }
327
+ return superstruct.define(`${nodeName}_EnumVariant`, (value) => {
328
+ if (typeof value === "string")
329
+ return variantMap.has(value) || `Invalid enum value "${value}". Expected one of: ${variantNames.join(", ")}`;
330
+ if (typeof value === "object" && value !== null && "__kind" in value) {
331
+ const kind = value["__kind"];
332
+ if (typeof kind !== "string") {
333
+ return `Expected __kind to be a string, received: ${formatValueType(kind)}`;
334
+ }
335
+ const variant = variantMap.get(kind);
336
+ if (!variant) {
337
+ return `Invalid enum variant "${kind}". Expected one of: ${variantNames.join(", ")}`;
338
+ }
339
+ if (variant.kind === "enumEmptyVariantTypeNode") {
340
+ return true;
341
+ }
342
+ const { __kind: _, ...rest } = value;
343
+ const payloadValidator = variantValidators.get(kind);
344
+ if (!payloadValidator) {
345
+ return true;
346
+ }
347
+ if (variant.kind === "enumStructVariantTypeNode") {
348
+ const [structError] = payloadValidator.validate(rest);
349
+ return structError ? formatErrorForEnumTypeNode(kind, structError) : true;
350
+ }
351
+ if (variant.kind === "enumTupleVariantTypeNode") {
352
+ const fields = rest.fields;
353
+ const [structError] = payloadValidator.validate(fields);
354
+ return structError ? formatErrorForEnumTypeNode(kind, structError) : true;
355
+ }
356
+ }
357
+ return `Expected an enum variant (string or object with __kind), received: ${formatValueType(value)}`;
358
+ });
359
+ }
360
+ function formatErrorForEnumTypeNode(enumVariantKind, error) {
361
+ const failures = error.failures();
362
+ const first = failures?.[0];
363
+ if (first) {
364
+ return `Enum variant "${enumVariantKind}" has invalid "${String(first.key)}"`;
365
+ }
366
+ return `Enum variant "${enumVariantKind}" has invalid payload`;
367
+ }
368
+ var SolanaAddressValidator = /* @__PURE__ */ superstruct.define("SolanaAddress", (value) => {
369
+ if (typeof value === "string") {
370
+ return addresses.isAddress(value) || `Expected a valid Solana address (base58), received string: "${value}"`;
371
+ }
372
+ if (dynamicAddressResolution.isPublicKeyLike(value)) {
373
+ return addresses.isAddress(value.toBase58()) || "Expected a valid Solana address, received an invalid PublicKey";
374
+ }
375
+ return `Expected a Solana address (base58 string or PublicKey), received: ${formatValueType(value)}`;
376
+ });
377
+ var OptionalSolanaAddressValidator = /* @__PURE__ */ superstruct.define(
378
+ "OptionalSolanaAddress",
379
+ (value) => {
380
+ if (value === void 0 || value === null) return true;
381
+ const [error] = SolanaAddressValidator.validate(value);
382
+ if (!error) return true;
383
+ return error.failures()[0]?.message ?? "Expected a valid Solana address or null/undefined";
384
+ }
385
+ );
386
+ var NumberOrBigintValidator = /* @__PURE__ */ superstruct.define("NumberOrBigint", (value) => {
387
+ if (typeof value === "number") {
388
+ return Number.isSafeInteger(value) || `Expected a safe integer, received unsafe number: ${value}`;
389
+ }
390
+ if (typeof value === "bigint") return true;
391
+ return `Expected a number or bigint, received: ${formatValueType(value)}`;
392
+ });
393
+ var BytesLikeValidator = /* @__PURE__ */ superstruct.define("BytesLike", (value) => {
394
+ if (value instanceof Uint8Array) return true;
395
+ if (!Array.isArray(value)) {
396
+ return `Expected a Uint8Array or number[] (bytes 0-255), received: ${formatValueType(value)}`;
397
+ }
398
+ const invalidIndex = value.findIndex((n) => typeof n !== "number" || !Number.isInteger(n) || n < 0 || n > 255);
399
+ if (invalidIndex !== -1) {
400
+ return `Expected byte values (integers 0-255), invalid element at index ${invalidIndex}: ${String(value[invalidIndex])}`;
401
+ }
402
+ return true;
403
+ });
404
+ function BytesWithSizeValidator(exactSize) {
405
+ return superstruct.define(`BytesWithSize_${exactSize}`, (value) => {
406
+ if (value instanceof Uint8Array) {
407
+ return value.length === exactSize || `Expected exactly ${exactSize} bytes, received ${value.length} bytes`;
408
+ }
409
+ if (!Array.isArray(value)) {
410
+ return `Expected a Uint8Array or number[] of exactly ${exactSize} bytes, received: ${formatValueType(value)}`;
411
+ }
412
+ if (value.length !== exactSize) {
413
+ return `Expected exactly ${exactSize} bytes, received ${value.length} elements`;
414
+ }
415
+ const invalidIndex = value.findIndex((n) => typeof n !== "number" || !Number.isInteger(n) || n < 0 || n > 255);
416
+ if (invalidIndex !== -1) {
417
+ return `Expected byte values (integers 0-255), invalid element at index ${invalidIndex}: ${String(value[invalidIndex])}`;
418
+ }
419
+ return true;
420
+ });
421
+ }
422
+ function OptionValueValidator(name, SomeValueValidator) {
423
+ return superstruct.define(`${name}_OptionValueValidator`, (value) => {
424
+ if (value === null || value === void 0) return true;
425
+ const [error] = SomeValueValidator.validate(value);
426
+ if (!error) return true;
427
+ return error.failures()[0]?.message ?? "Invalid value for optional field";
428
+ });
429
+ }
430
+ function ZeroableOptionValidator(name, innerValidator) {
431
+ return superstruct.define(name, (value) => {
432
+ if (value == null) return true;
433
+ const [error] = innerValidator.validate(value);
434
+ if (!error) return true;
435
+ return error.failures()[0]?.message ?? "Expected a valid value or null for zeroable option";
436
+ });
437
+ }
438
+ var UniqueItemsValidator = /* @__PURE__ */ superstruct.define("UniqueItems", (value) => {
439
+ if (!Array.isArray(value)) {
440
+ return `Expected an array with unique items, received: ${formatValueType(value)}`;
441
+ }
442
+ const unique = /* @__PURE__ */ new Map();
443
+ for (let i = 0; i < value.length; i++) {
444
+ const key = safeStringify(value[i]);
445
+ const index = unique.get(key);
446
+ if (index !== void 0) {
447
+ return `Expected all items to be unique, found duplicate at indices ${index} and ${i}`;
448
+ }
449
+ unique.set(key, i);
450
+ }
451
+ return true;
452
+ });
453
+ function KeyValueValidator(name, KeyValidator, ValueValidator) {
454
+ return superstruct.define(`${name}_KeyValueValidator`, (value) => {
455
+ if (typeof value !== "object" || value === null) {
456
+ return `Expected a map (object), received: ${formatValueType(value)}`;
457
+ }
458
+ const record = value;
459
+ const invalidKeys = [];
460
+ const invalidValues = [];
461
+ for (const key of Object.keys(record)) {
462
+ if (KeyValidator.validate(key)[0]) invalidKeys.push(key);
463
+ if (ValueValidator.validate(record[key])[0]) invalidValues.push(key);
464
+ }
465
+ if (!invalidKeys.length && !invalidValues.length) return true;
466
+ const parts = [];
467
+ if (invalidKeys.length) parts.push(`invalid keys: ${invalidKeys.join(", ")}`);
468
+ if (invalidValues.length) parts.push(`invalid values: ${invalidValues.join(", ")}`);
469
+ return `Map validation failed: ${parts.join("; ")}`;
470
+ });
471
+ }
472
+ function MapCountValidator(node) {
473
+ switch (node.kind) {
474
+ case "fixedCountNode":
475
+ return KeysLengthValidator(node.value);
476
+ case "remainderCountNode":
477
+ case "prefixedCountNode":
478
+ return null;
479
+ // the number of items is unknown or arbitrary, like vec![]
480
+ default:
481
+ throw new Error(`Unsupported map count type: ${getMaybeNodeKind(node)}`);
482
+ }
483
+ }
484
+ function KeysLengthValidator(count) {
485
+ return superstruct.define(`KeysLengthValidator_len_${count}`, (value) => {
486
+ if (typeof value !== "object" || value === null) {
487
+ return `Expected a map with exactly ${count} entries, received: ${formatValueType(value)}`;
488
+ }
489
+ const actual = Object.keys(value).length;
490
+ return actual === count || `Expected exactly ${count} map entries, received ${actual}`;
491
+ });
492
+ }
493
+ function ArrayValidator(nodeName, node, definedTypes) {
494
+ const itemValidator = createValidatorForTypeNode(nodeName, node.item, definedTypes);
495
+ switch (node.count.kind) {
496
+ case "fixedCountNode": {
497
+ return superstruct.size(superstruct.array(itemValidator), node.count.value);
498
+ }
499
+ case "remainderCountNode":
500
+ case "prefixedCountNode": {
501
+ return superstruct.array(itemValidator);
502
+ }
503
+ default: {
504
+ throw new Error(`Node: ${nodeName}. Unsupported array count type`);
505
+ }
506
+ }
507
+ }
508
+ function AmountTypeValidator(nodeName) {
509
+ return superstruct.define(`AmountType_${nodeName}`, (value) => {
510
+ if (typeof value === "number") {
511
+ return Number.isSafeInteger(value) || `Expected a safe integer, received unsafe number: ${value}`;
512
+ }
513
+ if (typeof value === "bigint") {
514
+ return true;
515
+ }
516
+ return `Expected a number or bigint, received: ${formatValueType(value)}`;
517
+ });
518
+ }
519
+
520
+ // src/accounts/validate-accounts-input.ts
521
+ function createAccountsInputValidator(ixNode) {
522
+ const validator = ixNode.accounts.length ? createIxAccountsValidator(ixNode.accounts) : null;
523
+ return (accountsInput = {}) => {
524
+ if (!validator) return;
525
+ try {
526
+ superstruct.assert(accountsInput, validator);
527
+ } catch (error) {
528
+ if (error instanceof superstruct.StructError) {
529
+ const key = error.key;
530
+ const value = error.value;
531
+ if (value == null) {
532
+ throw new errors.CodamaError(errors.CODAMA_ERROR__DYNAMIC_CLIENT__ACCOUNT_MISSING, {
533
+ accountName: codama.camelCase(key),
534
+ instructionName: ixNode.name
535
+ });
536
+ } else {
537
+ throw new errors.CodamaError(errors.CODAMA_ERROR__DYNAMIC_CLIENT__INVALID_ACCOUNT_ADDRESS, {
538
+ accountName: codama.camelCase(key),
539
+ value: safeStringify(value)
540
+ });
541
+ }
542
+ }
543
+ throw new errors.CodamaError(errors.CODAMA_ERROR__DYNAMIC_CLIENT__FAILED_TO_VALIDATE_INPUT, {
544
+ cause: error,
545
+ message: "Unexpected validation error"
546
+ });
547
+ }
548
+ };
549
+ }
550
+ function isOmittedArgument(node) {
551
+ return node.defaultValueStrategy === "omitted";
552
+ }
553
+ function isOptionalArgument(ixArgumentNode, input) {
554
+ return dynamicAddressResolution.OPTIONAL_NODE_KINDS.includes(ixArgumentNode.type.kind) && (input === null || input === void 0);
555
+ }
556
+
557
+ // src/arguments/encode-instruction-arguments.ts
558
+ function encodeInstructionArguments(root, ix, argumentsInput) {
559
+ const chunks = ix.arguments.map((ixArgumentNode) => {
560
+ const input = argumentsInput?.[ixArgumentNode.name];
561
+ const nodeCodec = dynamicCodecs.getNodeCodec([root, root.program, ix, ixArgumentNode]);
562
+ if (isOmittedArgument(ixArgumentNode)) {
563
+ return encodeOmittedArgument(ix, ixArgumentNode, nodeCodec);
564
+ } else if (isOptionalArgument(ixArgumentNode, input)) {
565
+ return encodeOptionalArgument(ix, ixArgumentNode, nodeCodec);
566
+ } else {
567
+ return encodeRequiredArgument(root, ix, ixArgumentNode, input, nodeCodec);
568
+ }
569
+ });
570
+ return codecs.mergeBytes(chunks.map((chunk) => Uint8Array.from(chunk)));
571
+ }
572
+ function encodeOmittedArgument(ix, ixArgumentNode, nodeCodec) {
573
+ const defaultValue = ixArgumentNode.defaultValue;
574
+ if (defaultValue === void 0) {
575
+ throw new errors.CodamaError(errors.CODAMA_ERROR__DYNAMIC_CLIENT__DEFAULT_VALUE_MISSING, {
576
+ argumentName: ixArgumentNode.name,
577
+ instructionName: ix.name
578
+ });
579
+ }
580
+ const visitor = dynamicAddressResolution.createDefaultValueEncoderVisitor(nodeCodec);
581
+ return codama.visitOrElse(defaultValue, visitor, (node) => {
582
+ throw new errors.CodamaError(errors.CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
583
+ expectedKinds: [...dynamicAddressResolution.DEFAULT_VALUE_ENCODER_SUPPORTED_NODE_KINDS],
584
+ kind: node.kind,
585
+ node
586
+ });
587
+ });
588
+ }
589
+ function encodeOptionalArgument(ix, ixArgumentNode, nodeCodec) {
590
+ try {
591
+ return nodeCodec.encode(null);
592
+ } catch (error) {
593
+ throw new errors.CodamaError(errors.CODAMA_ERROR__DYNAMIC_CLIENT__FAILED_TO_ENCODE_ARGUMENT, {
594
+ argumentName: ixArgumentNode.name,
595
+ cause: error,
596
+ instructionName: ix.name
597
+ });
598
+ }
599
+ }
600
+ function encodeRequiredArgument(root, ix, ixArgumentNode, input, nodeCodec) {
601
+ if (input === void 0) {
602
+ throw new errors.CodamaError(errors.CODAMA_ERROR__DYNAMIC_CLIENT__ARGUMENT_MISSING, {
603
+ argumentName: ixArgumentNode.name,
604
+ instructionName: ix.name
605
+ });
606
+ }
607
+ const transformer = dynamicAddressResolution.createCodecInputTransformer(ixArgumentNode.type, root, {
608
+ bytesEncoding: "base16"
609
+ });
610
+ const transformedInput = transformer(input);
611
+ try {
612
+ return nodeCodec.encode(transformedInput);
613
+ } catch (error) {
614
+ throw new errors.CodamaError(errors.CODAMA_ERROR__DYNAMIC_CLIENT__FAILED_TO_ENCODE_ARGUMENT, {
615
+ argumentName: ixArgumentNode.name,
616
+ cause: error,
617
+ instructionName: ix.name
618
+ });
619
+ }
620
+ }
621
+ function createArgumentsInputValidator(root, ixNode) {
622
+ const requiredArguments = ixNode.arguments.filter((arg) => arg?.defaultValueStrategy !== "omitted");
623
+ const validator = requiredArguments.length ? createIxArgumentsValidator(ixNode.name, requiredArguments, root.program.definedTypes) : null;
624
+ return (argumentsInput = {}) => {
625
+ validateOmittedArguments(ixNode, argumentsInput);
626
+ if (!validator) return;
627
+ const filteredInput = filterRemainingAccountArguments(ixNode, argumentsInput);
628
+ try {
629
+ superstruct.assert(filteredInput, validator);
630
+ } catch (error) {
631
+ if (!(error instanceof superstruct.StructError)) {
632
+ throw new errors.CodamaError(errors.CODAMA_ERROR__DYNAMIC_CLIENT__FAILED_TO_VALIDATE_INPUT, {
633
+ cause: error,
634
+ message: "Unexpected validation error"
635
+ });
636
+ }
637
+ const formattedMessage = error.failures().map((failure) => {
638
+ const fieldPath = formatFailurePath(failure);
639
+ const value = formatFailureValue(failure.value);
640
+ return `Invalid argument "${fieldPath}", value: ${value}. ${failure.message}
641
+ `;
642
+ });
643
+ throw new errors.CodamaError(errors.CODAMA_ERROR__DYNAMIC_CLIENT__FAILED_TO_VALIDATE_INPUT, {
644
+ cause: error,
645
+ message: formattedMessage.join("")
646
+ });
647
+ }
648
+ };
649
+ }
650
+ function formatFailurePath(failure) {
651
+ const path = failure.path;
652
+ if (!path || path.length === 0) return String(failure.key ?? "");
653
+ return path.map((segment, i) => {
654
+ if (typeof segment === "number") {
655
+ return `[${segment}]`;
656
+ }
657
+ return `${i === 0 ? "" : "."}${String(segment)}`;
658
+ }).join("");
659
+ }
660
+ var MAX_VALUE_LENGTH = 120;
661
+ function formatFailureValue(value) {
662
+ const raw = typeof value === "object" ? safeStringify(value) : String(value);
663
+ return raw.length > MAX_VALUE_LENGTH ? `${raw.slice(0, MAX_VALUE_LENGTH)}...` : raw;
664
+ }
665
+ function validateOmittedArguments(ixNode, argumentsInput = {}) {
666
+ ixNode.arguments.filter(isOmittedArgument).forEach((ixArgumentNode) => {
667
+ if (Object.hasOwn(argumentsInput, ixArgumentNode.name)) {
668
+ throw new errors.CodamaError(errors.CODAMA_ERROR__DYNAMIC_CLIENT__FAILED_TO_VALIDATE_INPUT, {
669
+ message: "Omitted argument must not be provided"
670
+ });
671
+ }
672
+ });
673
+ }
674
+ function getRemainingAccountArgNames(ixNode) {
675
+ return (ixNode.remainingAccounts ?? []).filter((node) => node.value.kind === "argumentValueNode").map((node) => node.value.name);
676
+ }
677
+ function filterRemainingAccountArguments(ixNode, argumentsInput) {
678
+ const remainingAccountArgNames = getRemainingAccountArgNames(ixNode);
679
+ if (!remainingAccountArgNames.length) {
680
+ return argumentsInput;
681
+ }
682
+ const remainingAccountArgNamesSet = new Set(remainingAccountArgNames);
683
+ return Object.fromEntries(Object.entries(argumentsInput).filter(([key]) => !remainingAccountArgNamesSet.has(key)));
684
+ }
685
+ async function resolveArgumentDefaultsFromCustomResolvers(ixNode, argumentsInput, accountsInput, resolversInput) {
686
+ const resolvedArgumentsInput = { ...argumentsInput };
687
+ const allArguments = [...ixNode.arguments, ...ixNode.extraArguments ?? []];
688
+ for (const argumentNode of allArguments) {
689
+ if (resolvedArgumentsInput[argumentNode.name] !== void 0) continue;
690
+ if (isOmittedArgument(argumentNode)) continue;
691
+ if (!codama.isNode(argumentNode.defaultValue, "resolverValueNode")) continue;
692
+ const resolverFn = resolversInput?.[argumentNode.defaultValue.name];
693
+ if (!resolverFn) continue;
694
+ try {
695
+ resolvedArgumentsInput[argumentNode.name] = await resolverFn(
696
+ resolvedArgumentsInput,
697
+ accountsInput ?? {}
698
+ );
699
+ } catch (error) {
700
+ throw new errors.CodamaError(errors.CODAMA_ERROR__DYNAMIC_CLIENT__FAILED_TO_EXECUTE_RESOLVER, {
701
+ cause: error,
702
+ resolverName: argumentNode.defaultValue.name,
703
+ targetKind: "instructionArgumentNode",
704
+ targetName: argumentNode.name
705
+ });
706
+ }
707
+ }
708
+ return resolvedArgumentsInput;
709
+ }
710
+ function createInstructionsBuilder(root, ixNode) {
711
+ const programAddress = addresses.address(root.program.publicKey);
712
+ const validateArguments = createArgumentsInputValidator(root, ixNode);
713
+ const validateAccounts = createAccountsInputValidator(ixNode);
714
+ return async (argumentsInput, accountsInput, signers, resolversInput) => {
715
+ validateArguments(argumentsInput);
716
+ validateAccounts(accountsInput);
717
+ const enrichedArgumentsInput = await resolveArgumentDefaultsFromCustomResolvers(
718
+ ixNode,
719
+ argumentsInput,
720
+ accountsInput,
721
+ resolversInput
722
+ );
723
+ const argumentsData = encodeInstructionArguments(root, ixNode, enrichedArgumentsInput);
724
+ const accountsData = await createAccountMeta(
725
+ root,
726
+ ixNode,
727
+ enrichedArgumentsInput,
728
+ accountsInput,
729
+ signers,
730
+ resolversInput
731
+ );
732
+ return {
733
+ accounts: accountsData,
734
+ data: argumentsData,
735
+ programAddress
736
+ };
737
+ };
738
+ }
739
+
740
+ Object.defineProperty(exports, "isPublicKeyLike", {
741
+ enumerable: true,
742
+ get: function () { return dynamicAddressResolution.isPublicKeyLike; }
743
+ });
744
+ Object.defineProperty(exports, "toAddress", {
745
+ enumerable: true,
746
+ get: function () { return dynamicAddressResolution.toAddress; }
747
+ });
748
+ exports.createAccountMeta = createAccountMeta;
749
+ exports.createInstructionsBuilder = createInstructionsBuilder;
750
+ exports.encodeInstructionArguments = encodeInstructionArguments;
751
+ //# sourceMappingURL=index.browser.cjs.map
752
+ //# sourceMappingURL=index.browser.cjs.map