@usearete/sdk 0.6.0 → 0.7.1

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/index.cjs CHANGED
@@ -4252,6 +4252,9 @@ function sortAccountsByDependency(accountMetas) {
4252
4252
  deps.add(seed.accountName);
4253
4253
  }
4254
4254
  }
4255
+ if (meta.pdaConfig.program?.type === 'accountRef') {
4256
+ deps.add(meta.pdaConfig.program.accountName);
4257
+ }
4255
4258
  }
4256
4259
  pdaDeps.set(meta.name, deps);
4257
4260
  }
@@ -4345,9 +4348,19 @@ function resolveAccounts(accountMetas, args, options) {
4345
4348
  };
4346
4349
  }
4347
4350
  function resolveSingleAccount(meta, args, options, resolvedMap) {
4351
+ const explicit = options.accounts?.[meta.name];
4352
+ if (explicit !== undefined) {
4353
+ validateAccountAddress(meta.name, explicit);
4354
+ return {
4355
+ name: meta.name,
4356
+ address: explicit,
4357
+ isSigner: meta.isSigner,
4358
+ isWritable: meta.isWritable,
4359
+ };
4360
+ }
4348
4361
  switch (meta.category) {
4349
4362
  case 'signer':
4350
- return resolveSignerAccount(meta, options.accounts, options.wallet);
4363
+ return resolveSignerAccount(meta, options.wallet);
4351
4364
  case 'known':
4352
4365
  return resolveKnownAccount(meta);
4353
4366
  case 'pda':
@@ -4358,8 +4371,22 @@ function resolveSingleAccount(meta, args, options, resolvedMap) {
4358
4371
  return null;
4359
4372
  }
4360
4373
  }
4361
- function resolveSignerAccount(meta, accounts, wallet) {
4362
- const address = accounts?.[meta.name] ?? wallet?.publicKey;
4374
+ function validateAccountAddress(name, address) {
4375
+ let decoded;
4376
+ try {
4377
+ decoded = decodeBase58(address);
4378
+ }
4379
+ catch {
4380
+ throw new Error(`Invalid account override for "${name}": expected a base58 public key`);
4381
+ }
4382
+ if (decoded.length !== 32) {
4383
+ throw new Error(`Invalid account override for "${name}": expected a 32-byte public key, got ${decoded.length} bytes`);
4384
+ }
4385
+ }
4386
+ function resolveSignerAccount(meta, wallet) {
4387
+ // An IDL only tells us that an account signs; it cannot prove that the
4388
+ // account is the connected wallet. Wallet fallback is therefore opt-in.
4389
+ const address = meta.signerKind === 'wallet' ? wallet?.publicKey : undefined;
4363
4390
  if (!address) {
4364
4391
  return null;
4365
4392
  }
@@ -4386,7 +4413,7 @@ function resolvePdaAccount(meta, args, resolvedMap, programId, resolve) {
4386
4413
  return null;
4387
4414
  }
4388
4415
  // Determine which program to derive against
4389
- const pdaProgramId = meta.pdaConfig.programId || programId;
4416
+ const pdaProgramId = resolvePdaProgram(meta.pdaConfig, args, resolvedMap, programId, resolve);
4390
4417
  if (!pdaProgramId) {
4391
4418
  throw new Error('Cannot derive PDA for "' + meta.name + '": no programId specified. ' +
4392
4419
  'Either set pdaConfig.programId or pass programId in options.');
@@ -4433,6 +4460,24 @@ function resolvePdaAccount(meta, args, resolvedMap, programId, resolve) {
4433
4460
  isWritable: meta.isWritable,
4434
4461
  };
4435
4462
  }
4463
+ function resolvePdaProgram(config, args, resolvedMap, defaultProgramId, resolve) {
4464
+ if (config.program?.type === 'accountRef') {
4465
+ const account = resolvedMap[config.program.accountName];
4466
+ if (!account) {
4467
+ throw new Error('PDA program references unresolved account: ' + config.program.accountName);
4468
+ }
4469
+ return account.address;
4470
+ }
4471
+ if (config.program?.type === 'argRef') {
4472
+ const value = getValueByPath(args, config.program.argName)
4473
+ ?? getValueByPath(resolve, config.program.argName);
4474
+ if (typeof value !== 'string' || value.length === 0) {
4475
+ throw new Error('PDA program references missing or non-address argument: ' + config.program.argName);
4476
+ }
4477
+ return value;
4478
+ }
4479
+ return config.programId || defaultProgramId;
4480
+ }
4436
4481
  function resolveUserProvidedAccount(meta, accounts) {
4437
4482
  const address = accounts?.[meta.name];
4438
4483
  if (!address) {
@@ -5056,10 +5101,10 @@ function createInstructionHandler(config) {
5056
5101
  *
5057
5102
  * Keys matching a declared argument name are args; keys matching a declared
5058
5103
  * account name (with a string value) are account address overrides. This
5059
- * applies to signer slots too, allowing explicit signer addresses to override
5060
- * the wallet fallback. Anything else throws — a typo'd key silently dropped
5104
+ * applies to signer slots too, allowing explicit signer addresses to fill or
5105
+ * override those slots. Anything else throws — a typo'd key silently dropped
5061
5106
  * here would otherwise change the built instruction. `options.accounts` on
5062
- * {@link BuildOptions} remains an unvalidated escape hatch for advanced callers.
5107
+ * {@link BuildOptions} is the explicit override map and wins over merged params.
5063
5108
  */
5064
5109
  function splitParams(handler, params) {
5065
5110
  const argNameSet = new Set(handler.argNames);
@@ -5208,22 +5253,39 @@ function resolveSeeds(seeds, context) {
5208
5253
  }
5209
5254
  });
5210
5255
  }
5211
- function pda(programId, ...seeds) {
5256
+ function resolveProgram(selector, context) {
5257
+ if (typeof selector === 'string')
5258
+ return context.programId ?? selector;
5259
+ if (selector.type === 'accountRef') {
5260
+ const address = context.accounts?.[selector.accountName];
5261
+ if (!address)
5262
+ throw new Error(`Missing account for PDA program: ${selector.accountName}`);
5263
+ return address;
5264
+ }
5265
+ const value = getValueByPath(context.args, selector.argName)
5266
+ ?? getValueByPath(context.resolve, selector.argName);
5267
+ if (typeof value !== 'string' || value.length === 0) {
5268
+ throw new Error(`Missing argument for PDA program: ${selector.argName}`);
5269
+ }
5270
+ return value;
5271
+ }
5272
+ function pda(programSelector, ...seeds) {
5212
5273
  return {
5213
5274
  seeds,
5214
- programId,
5275
+ programId: typeof programSelector === 'string' ? programSelector : undefined,
5276
+ programSelector,
5215
5277
  program(newProgramId) {
5216
5278
  return pda(newProgramId, ...seeds);
5217
5279
  },
5218
5280
  async derive(context) {
5219
5281
  const resolvedSeeds = resolveSeeds(this.seeds, context);
5220
- const pid = context.programId ?? this.programId;
5282
+ const pid = resolveProgram(this.programSelector, context);
5221
5283
  const [address] = await findProgramAddress(resolvedSeeds, pid);
5222
5284
  return address;
5223
5285
  },
5224
5286
  deriveSync(context) {
5225
5287
  const resolvedSeeds = resolveSeeds(this.seeds, context);
5226
- const pid = context.programId ?? this.programId;
5288
+ const pid = resolveProgram(this.programSelector, context);
5227
5289
  const [address] = findProgramAddressSync(resolvedSeeds, pid);
5228
5290
  return address;
5229
5291
  },
@@ -5386,6 +5448,7 @@ function createPreparedTransactionBody(input) {
5386
5448
  name: input.name,
5387
5449
  instructions,
5388
5450
  requiredSignerAddresses: dedupe(input.requiredSignerAddresses ?? inferSignerAddresses(instructions)),
5451
+ signers: [...new Set(input.signers ?? [])],
5389
5452
  errors: [...(input.errors ?? [])],
5390
5453
  };
5391
5454
  }
@@ -5401,6 +5464,7 @@ function createPreparedInstruction(input) {
5401
5464
  name: input.name,
5402
5465
  instructions: [input.instruction],
5403
5466
  requiredSignerAddresses: input.requiredSignerAddresses,
5467
+ signers: input.signers,
5404
5468
  errors: input.errors,
5405
5469
  });
5406
5470
  return {
@@ -5431,6 +5495,10 @@ function createPreparedTransaction(input) {
5431
5495
  instructions: transactionParts.flatMap((part) => part.instructions),
5432
5496
  requiredSignerAddresses: input.requiredSignerAddresses
5433
5497
  ?? transactionParts.flatMap((part) => part.requiredSignerAddresses),
5498
+ signers: [
5499
+ ...transactionParts.flatMap((part) => part.signers),
5500
+ ...(input.signers ?? []),
5501
+ ],
5434
5502
  errors: input.errors ?? transactionParts.flatMap((part) => part.errors),
5435
5503
  });
5436
5504
  return {
@@ -5507,8 +5575,8 @@ function inferSignerAddress(value) {
5507
5575
  const publicKey = candidate.publicKey;
5508
5576
  return typeof publicKey?.toBase58 === 'function' ? publicKey.toBase58() : null;
5509
5577
  }
5510
- function validateTransactionSigners(transaction, host, options) {
5511
- const signerAddresses = (options.signers ?? []).map(inferSignerAddress);
5578
+ function validateTransactionSigners(transaction, host, options, signers) {
5579
+ const signerAddresses = signers.map(inferSignerAddress);
5512
5580
  const available = new Set(options.availableSignerAddresses ?? []);
5513
5581
  for (const address of options.signerRegistry?.addresses() ?? []) {
5514
5582
  available.add(address);
@@ -5594,15 +5662,16 @@ async function runOperationCallback(input, callbackErrors, onCallbackError) {
5594
5662
  async function executePreparedOperation(host, operation, options = {}) {
5595
5663
  const receipts = [];
5596
5664
  const callbackErrors = [];
5597
- const signers = [
5598
- ...new Set([
5599
- ...(options.signerRegistry?.values() ?? []),
5600
- ...(options.signers ?? []),
5601
- ]),
5602
- ];
5603
5665
  for (const [transactionIndex, transaction] of operation.plan.transactions.entries()) {
5666
+ const signers = [
5667
+ ...new Set([
5668
+ ...(transaction.signers ?? []),
5669
+ ...(options.signerRegistry?.values() ?? []),
5670
+ ...(options.signers ?? []),
5671
+ ]),
5672
+ ];
5604
5673
  try {
5605
- validateTransactionSigners(transaction, host, options);
5674
+ validateTransactionSigners(transaction, host, options, signers);
5606
5675
  }
5607
5676
  catch (cause) {
5608
5677
  throw new OperationExecutionError({