@circle-fin/app-kit 1.12.0 → 1.12.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/swap.mjs CHANGED
@@ -8755,6 +8755,7 @@ const swapTokenEnumSchema = z.enum([
8755
8755
  [Blockchain.Arbitrum_Sepolia]: '0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d',
8756
8756
  [Blockchain.Avalanche_Fuji]: '0x5425890298aed601595a70AB815c96711a31Bc65',
8757
8757
  [Blockchain.Base_Sepolia]: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',
8758
+ [Blockchain.Celo_Alfajores_Testnet]: '0x2F25deB3848C207fc8E0c34035B3Ba7fC157602B',
8758
8759
  [Blockchain.Codex_Testnet]: '0x6d7f141b6819C2c9CC2f818e6ad549E7Ca090F8f',
8759
8760
  [Blockchain.Cronos_Testnet]: '0xEb33dc5fac03833e132593659e1dE7256aB59794',
8760
8761
  [Blockchain.Edge_Testnet]: '0x2d9F7CAD728051AA35Ecdc472a14cf8cDF5CFD6B',
@@ -10122,6 +10123,44 @@ var pkg$2 = {
10122
10123
  }
10123
10124
  });
10124
10125
 
10126
+ /**
10127
+ * Canonical list of actions that do not prepare or submit transactions.
10128
+ *
10129
+ * @internal
10130
+ */ const READ_ACTION_KEYS = [
10131
+ 'token.allowance',
10132
+ 'token.balanceOf',
10133
+ 'token.name',
10134
+ 'native.balanceOf',
10135
+ 'usdc.allowance',
10136
+ 'usdc.balanceOf',
10137
+ 'usdc.name',
10138
+ 'gateway.v1.isDelegate',
10139
+ 'gateway.v1.withdrawingBalance',
10140
+ 'gateway.v1.withdrawalBlock',
10141
+ 'gateway.v1.signBurnIntents'
10142
+ ];
10143
+ const READ_ACTION_KEY_SET = new Set(READ_ACTION_KEYS);
10144
+ /**
10145
+ * Check whether a runtime value identifies a read action.
10146
+ *
10147
+ * @param action - The value to classify.
10148
+ * @returns Whether the value is a registered read-action key.
10149
+ *
10150
+ * @example
10151
+ * ```typescript
10152
+ * import { isReadActionKey } from '@core/adapter'
10153
+ *
10154
+ * if (isReadActionKey(value)) {
10155
+ * await adapter.readAction(value, params, context)
10156
+ * }
10157
+ * ```
10158
+ *
10159
+ * @internal
10160
+ */ function isReadActionKey(action) {
10161
+ return typeof action === 'string' && READ_ACTION_KEY_SET.has(action);
10162
+ }
10163
+
10125
10164
  /**
10126
10165
  * Resolves an operation context into concrete chain and address values.
10127
10166
  *
@@ -10201,6 +10240,141 @@ var pkg$2 = {
10201
10240
  };
10202
10241
  }
10203
10242
 
10243
+ /**
10244
+ * Create the standard error for a missing or non-read action.
10245
+ *
10246
+ * @param action - The unsupported action value.
10247
+ * @returns A fatal unsupported-action error.
10248
+ *
10249
+ * @internal
10250
+ */ function createUnsupportedReadActionError(action) {
10251
+ return new KitError({
10252
+ ...InputError.UNSUPPORTED_ACTION,
10253
+ recoverability: 'FATAL',
10254
+ message: `Read action "${String(action)}" is not registered in this adapter.`
10255
+ });
10256
+ }
10257
+ /**
10258
+ * Execute a read through the adapter's dedicated read seam when available.
10259
+ *
10260
+ * @remarks
10261
+ * Fall back to the legacy `prepareAction().execute()` contract so providers
10262
+ * remain runtime-compatible with adapter versions released before `readAction`.
10263
+ * Consumers must upgrade their adapter package for reads to bypass custom
10264
+ * `prepareAction` wrappers.
10265
+ *
10266
+ * @typeParam TAdapterCapabilities - The adapter capabilities type.
10267
+ * @typeParam TActionKey - The read action key.
10268
+ * @param adapter - The adapter that owns the read action.
10269
+ * @param action - The read action to execute.
10270
+ * @param params - The parameters for the read action.
10271
+ * @param ctx - The operation context.
10272
+ * @returns The raw read-action result.
10273
+ * @throws {KitError} When `action` is not a supported read-action key.
10274
+ *
10275
+ * @example
10276
+ * ```typescript
10277
+ * import { executeAdapterReadAction } from '@core/adapter'
10278
+ * import { Ethereum } from '@core/chains'
10279
+ *
10280
+ * const allowance = await executeAdapterReadAction(
10281
+ * adapter,
10282
+ * 'token.allowance',
10283
+ * { tokenAddress, delegate },
10284
+ * { chain: Ethereum },
10285
+ * )
10286
+ * ```
10287
+ *
10288
+ * @internal
10289
+ */ async function executeAdapterReadAction(adapter, action, params, ctx) {
10290
+ if (!isReadActionKey(action)) {
10291
+ throw createUnsupportedReadActionError(action);
10292
+ }
10293
+ const runtimeAdapter = adapter;
10294
+ if (typeof runtimeAdapter.readAction === 'function') {
10295
+ return runtimeAdapter.readAction(action, params, ctx);
10296
+ }
10297
+ let request;
10298
+ try {
10299
+ request = await adapter.prepareAction(action, params, ctx);
10300
+ } catch (error) {
10301
+ if (error instanceof Error && error.message === `Action ${action} is not supported`) {
10302
+ throw createUnsupportedReadActionError(action);
10303
+ }
10304
+ throw error;
10305
+ }
10306
+ return request.execute();
10307
+ }
10308
+ /**
10309
+ * Read and parse a token allowance while supporting older adapter versions.
10310
+ *
10311
+ * @remarks
10312
+ * Prefer the adapter's dedicated read seam and fall back to the legacy
10313
+ * `prepareAction().execute()` contract when the runtime adapter predates it.
10314
+ *
10315
+ * @typeParam TAdapterCapabilities - The adapter capabilities type.
10316
+ * @param adapter - The adapter that owns the allowance action.
10317
+ * @param params - The token and delegate whose allowance is being read.
10318
+ * @param ctx - The operation context.
10319
+ * @returns The non-negative allowance in token base units.
10320
+ * @throws {KitError} When the action is unsupported or its response is malformed.
10321
+ *
10322
+ * @example
10323
+ * ```typescript
10324
+ * import { readTokenAllowance } from '@core/adapter'
10325
+ * import { Ethereum } from '@core/chains'
10326
+ *
10327
+ * const allowance = await readTokenAllowance(
10328
+ * adapter,
10329
+ * { tokenAddress, delegate },
10330
+ * { chain: Ethereum },
10331
+ * )
10332
+ * ```
10333
+ *
10334
+ * @internal
10335
+ */ async function readTokenAllowance(adapter, params, ctx) {
10336
+ return parseAllowanceResponse(await executeAdapterReadAction(adapter, 'token.allowance', params, ctx));
10337
+ }
10338
+ /**
10339
+ * Parse a raw token allowance response into base units.
10340
+ *
10341
+ * @param allowanceRaw - The adapter response, optionally wrapped as an Amount output.
10342
+ * @returns The non-negative allowance as a bigint, or zero for a missing value.
10343
+ * @throws {KitError} When the response cannot represent a non-negative bigint.
10344
+ *
10345
+ * @example
10346
+ * ```typescript
10347
+ * import { parseAllowanceResponse } from '@core/adapter'
10348
+ *
10349
+ * const allowance = parseAllowanceResponse({ amount: { raw: 1000000n } })
10350
+ * ```
10351
+ */ function parseAllowanceResponse(allowanceRaw) {
10352
+ let value = allowanceRaw;
10353
+ if (typeof value === 'object' && value !== null && 'amount' in value) {
10354
+ const amount = value.amount;
10355
+ if (typeof amount === 'object' && amount !== null && 'raw' in amount) {
10356
+ value = amount.raw;
10357
+ }
10358
+ }
10359
+ if (value === undefined || value === null) {
10360
+ return 0n;
10361
+ }
10362
+ let allowance;
10363
+ if (typeof value === 'bigint') {
10364
+ allowance = value;
10365
+ } else if (typeof value === 'string') {
10366
+ try {
10367
+ allowance = BigInt(value);
10368
+ } catch {
10369
+ allowance = undefined;
10370
+ }
10371
+ }
10372
+ if (allowance === undefined || allowance < 0n) {
10373
+ throw createValidationFailedError$1('token.allowance', value, 'token.allowance response must be a non-negative bigint-compatible string or bigint');
10374
+ }
10375
+ return allowance;
10376
+ }
10377
+
10204
10378
  /**
10205
10379
  * Schema for validating hexadecimal strings with '0x' prefix.
10206
10380
  *
@@ -10978,7 +11152,7 @@ var TransferSpeed;
10978
11152
  registerKit(`${pkg$2.name}/${pkg$2.version}`);
10979
11153
 
10980
11154
  var name$1 = "@circle-fin/swap-kit";
10981
- var version$1 = "1.5.1";
11155
+ var version$1 = "1.5.2";
10982
11156
  var pkg$1 = {
10983
11157
  name: name$1,
10984
11158
  version: version$1};
@@ -15298,14 +15472,13 @@ const TOKEN_REGISTRY$2 = createTokenRegistry();
15298
15472
  return;
15299
15473
  }
15300
15474
  // For non-native tokens (SPL tokens, ERC-20 tokens), check the token balance
15301
- const balancePrepared = await adapter.prepareAction('token.balanceOf', {
15475
+ const balance = await executeAdapterReadAction(adapter, 'token.balanceOf', {
15302
15476
  tokenAddress: tokenInAddress,
15303
15477
  walletAddress
15304
15478
  }, context);
15305
- const balance = await balancePrepared.execute();
15306
15479
  // Compare balances
15307
15480
  const requiredAmount = BigInt(amount);
15308
- const currentBalance = BigInt(balance);
15481
+ const currentBalance = BigInt(String(balance));
15309
15482
  if (currentBalance < requiredAmount) {
15310
15483
  throw new KitError({
15311
15484
  ...BalanceError.INSUFFICIENT_TOKEN,
@@ -16466,11 +16639,10 @@ async function fetchSameChainStatusSnapshot({ isCrossChainSwap, txHash, chain, a
16466
16639
  * @throws Error if the adapter fails to prepare or execute approval transactions
16467
16640
  * @throws Error if transaction confirmation fails or times out
16468
16641
  */ async handleUsdtApproval(adapter, chain, executionCtx, adapterContractAddress, resolvedContext, executedTransactions) {
16469
- const allowanceRequest = await adapter.prepareAction('token.allowance', {
16642
+ const current = await readTokenAllowance(adapter, {
16470
16643
  tokenAddress: executionCtx.tokenInAddress,
16471
16644
  delegate: adapterContractAddress
16472
16645
  }, resolvedContext);
16473
- const current = BigInt(await allowanceRequest.execute());
16474
16646
  const required = BigInt(executionCtx.amount);
16475
16647
  if (current >= required) {
16476
16648
  // Sufficient allowance - proceed to swap
@@ -21244,7 +21416,7 @@ registerKit(`${pkg$1.name}/${pkg$1.version}`);
21244
21416
  };
21245
21417
 
21246
21418
  var name = "@circle-fin/earn-kit";
21247
- var version = "1.5.0";
21419
+ var version = "1.5.1";
21248
21420
  var pkg = {
21249
21421
  name: name,
21250
21422
  version: version};
@@ -664,6 +664,11 @@ class KitError extends Error {
664
664
  name: 'INPUT_UNSUPPORTED_TOKEN',
665
665
  type: 'INPUT'
666
666
  },
667
+ /** Action not supported by this adapter / ecosystem */ UNSUPPORTED_ACTION: {
668
+ code: 1008,
669
+ name: 'INPUT_UNSUPPORTED_ACTION',
670
+ type: 'INPUT'
671
+ },
667
672
  /** No route satisfies the slippage or minimum-output constraint */ SLIPPAGE_CONSTRAINT_NOT_MET: {
668
673
  code: 1009,
669
674
  name: 'INPUT_SLIPPAGE_CONSTRAINT_NOT_MET',
@@ -7995,6 +8000,7 @@ function parseOrThrow(value, schema, context) {
7995
8000
  [Blockchain.Arbitrum_Sepolia]: '0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d',
7996
8001
  [Blockchain.Avalanche_Fuji]: '0x5425890298aed601595a70AB815c96711a31Bc65',
7997
8002
  [Blockchain.Base_Sepolia]: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',
8003
+ [Blockchain.Celo_Alfajores_Testnet]: '0x2F25deB3848C207fc8E0c34035B3Ba7fC157602B',
7998
8004
  [Blockchain.Codex_Testnet]: '0x6d7f141b6819C2c9CC2f818e6ad549E7Ca090F8f',
7999
8005
  [Blockchain.Cronos_Testnet]: '0xEb33dc5fac03833e132593659e1dE7256aB59794',
8000
8006
  [Blockchain.Edge_Testnet]: '0x2d9F7CAD728051AA35Ecdc472a14cf8cDF5CFD6B',
@@ -8887,7 +8893,7 @@ function parseOrThrow(value, schema, context) {
8887
8893
  }
8888
8894
 
8889
8895
  var name = "@circle-fin/unified-balance-kit";
8890
- var version = "1.4.0";
8896
+ var version = "1.4.1";
8891
8897
  var pkg = {
8892
8898
  name: name,
8893
8899
  version: version};
@@ -9170,6 +9176,110 @@ var pkg = {
9170
9176
  * ```
9171
9177
  */ const USDC_DECIMALS$1 = 6;
9172
9178
 
9179
+ /**
9180
+ * Canonical list of actions that do not prepare or submit transactions.
9181
+ *
9182
+ * @internal
9183
+ */ const READ_ACTION_KEYS = [
9184
+ 'token.allowance',
9185
+ 'token.balanceOf',
9186
+ 'token.name',
9187
+ 'native.balanceOf',
9188
+ 'usdc.allowance',
9189
+ 'usdc.balanceOf',
9190
+ 'usdc.name',
9191
+ 'gateway.v1.isDelegate',
9192
+ 'gateway.v1.withdrawingBalance',
9193
+ 'gateway.v1.withdrawalBlock',
9194
+ 'gateway.v1.signBurnIntents'
9195
+ ];
9196
+ const READ_ACTION_KEY_SET = new Set(READ_ACTION_KEYS);
9197
+ /**
9198
+ * Check whether a runtime value identifies a read action.
9199
+ *
9200
+ * @param action - The value to classify.
9201
+ * @returns Whether the value is a registered read-action key.
9202
+ *
9203
+ * @example
9204
+ * ```typescript
9205
+ * import { isReadActionKey } from '@core/adapter'
9206
+ *
9207
+ * if (isReadActionKey(value)) {
9208
+ * await adapter.readAction(value, params, context)
9209
+ * }
9210
+ * ```
9211
+ *
9212
+ * @internal
9213
+ */ function isReadActionKey(action) {
9214
+ return typeof action === 'string' && READ_ACTION_KEY_SET.has(action);
9215
+ }
9216
+
9217
+ /**
9218
+ * Create the standard error for a missing or non-read action.
9219
+ *
9220
+ * @param action - The unsupported action value.
9221
+ * @returns A fatal unsupported-action error.
9222
+ *
9223
+ * @internal
9224
+ */ function createUnsupportedReadActionError(action) {
9225
+ return new KitError({
9226
+ ...InputError.UNSUPPORTED_ACTION,
9227
+ recoverability: 'FATAL',
9228
+ message: `Read action "${String(action)}" is not registered in this adapter.`
9229
+ });
9230
+ }
9231
+ /**
9232
+ * Execute a read through the adapter's dedicated read seam when available.
9233
+ *
9234
+ * @remarks
9235
+ * Fall back to the legacy `prepareAction().execute()` contract so providers
9236
+ * remain runtime-compatible with adapter versions released before `readAction`.
9237
+ * Consumers must upgrade their adapter package for reads to bypass custom
9238
+ * `prepareAction` wrappers.
9239
+ *
9240
+ * @typeParam TAdapterCapabilities - The adapter capabilities type.
9241
+ * @typeParam TActionKey - The read action key.
9242
+ * @param adapter - The adapter that owns the read action.
9243
+ * @param action - The read action to execute.
9244
+ * @param params - The parameters for the read action.
9245
+ * @param ctx - The operation context.
9246
+ * @returns The raw read-action result.
9247
+ * @throws {KitError} When `action` is not a supported read-action key.
9248
+ *
9249
+ * @example
9250
+ * ```typescript
9251
+ * import { executeAdapterReadAction } from '@core/adapter'
9252
+ * import { Ethereum } from '@core/chains'
9253
+ *
9254
+ * const allowance = await executeAdapterReadAction(
9255
+ * adapter,
9256
+ * 'token.allowance',
9257
+ * { tokenAddress, delegate },
9258
+ * { chain: Ethereum },
9259
+ * )
9260
+ * ```
9261
+ *
9262
+ * @internal
9263
+ */ async function executeAdapterReadAction(adapter, action, params, ctx) {
9264
+ if (!isReadActionKey(action)) {
9265
+ throw createUnsupportedReadActionError(action);
9266
+ }
9267
+ const runtimeAdapter = adapter;
9268
+ if (typeof runtimeAdapter.readAction === 'function') {
9269
+ return runtimeAdapter.readAction(action, params, ctx);
9270
+ }
9271
+ let request;
9272
+ try {
9273
+ request = await adapter.prepareAction(action, params, ctx);
9274
+ } catch (error) {
9275
+ if (error instanceof Error && error.message === `Action ${action} is not supported`) {
9276
+ throw createUnsupportedReadActionError(action);
9277
+ }
9278
+ throw error;
9279
+ }
9280
+ return request.execute();
9281
+ }
9282
+
9173
9283
  /**
9174
9284
  * Schema for validating hexadecimal strings with '0x' prefix.
9175
9285
  *
@@ -9379,16 +9489,15 @@ var pkg = {
9379
9489
  * ```
9380
9490
  */ const validateBalanceForTransaction = async (params)=>{
9381
9491
  const { amount, adapter, token, tokenAddress, operationContext } = params;
9382
- const balancePrepared = await adapter.prepareAction('usdc.balanceOf', {
9492
+ const balance = await executeAdapterReadAction(adapter, 'usdc.balanceOf', {
9383
9493
  walletAddress: operationContext.address
9384
9494
  }, operationContext);
9385
- const balance = await balancePrepared.execute();
9386
- if (BigInt(balance) < BigInt(amount)) {
9495
+ if (BigInt(String(balance)) < BigInt(amount)) {
9387
9496
  // Extract chain name from operationContext
9388
9497
  const chainName = extractChainInfo(operationContext.chain).name;
9389
9498
  // Create KitError with rich context in trace
9390
9499
  throw createInsufficientTokenBalanceError(chainName, token, {
9391
- balance: balance.toString(),
9500
+ balance: String(balance),
9392
9501
  amount,
9393
9502
  tokenAddress,
9394
9503
  walletAddress: operationContext.address
@@ -18382,8 +18491,7 @@ function assertNotSelfDelegation(chain, signerAddress, delegateAddress, action)
18382
18491
  chain
18383
18492
  };
18384
18493
  // Step 1: Quick check at latest block (no HTTP call)
18385
- const latestRequest = await adapter.prepareAction('gateway.v1.isDelegate', baseActionParams, operationContext);
18386
- const latestResult = await latestRequest.execute();
18494
+ const latestResult = await executeAdapterReadAction(adapter, 'gateway.v1.isDelegate', baseActionParams, operationContext);
18387
18495
  if (String(latestResult).toLowerCase() !== 'true') {
18388
18496
  return 'none';
18389
18497
  }
@@ -18392,13 +18500,12 @@ function assertNotSelfDelegation(chain, signerAddress, delegateAddress, action)
18392
18500
  // Solana uses confirmed vs finalized commitment as a proxy for
18393
18501
  // Gateway finality. This is conservative — can only over-report
18394
18502
  // 'pending', never falsely report 'ready'.
18395
- const finalizedRequest = await adapter.prepareAction('gateway.v1.isDelegate', {
18396
- ...baseActionParams,
18397
- commitment: 'finalized'
18398
- }, operationContext);
18399
18503
  let finalizedResult;
18400
18504
  try {
18401
- finalizedResult = await finalizedRequest.execute();
18505
+ finalizedResult = await executeAdapterReadAction(adapter, 'gateway.v1.isDelegate', {
18506
+ ...baseActionParams,
18507
+ commitment: 'finalized'
18508
+ }, operationContext);
18402
18509
  } catch (error) {
18403
18510
  if (isBlockRangeError(error)) {
18404
18511
  return 'pending';
@@ -18409,10 +18516,6 @@ function assertNotSelfDelegation(chain, signerAddress, delegateAddress, action)
18409
18516
  }
18410
18517
  // EVM: use processedHeight from /v1/info
18411
18518
  const processedHeight = await getProcessedHeight(chain.isTestnet, chain.gateway.domain);
18412
- const finalizedRequest = await adapter.prepareAction('gateway.v1.isDelegate', {
18413
- ...baseActionParams,
18414
- blockNumber: processedHeight
18415
- }, operationContext);
18416
18519
  // If the RPC node lags Gateway's indexer view, the historical read at
18417
18520
  // processedHeight may throw a block-range error. This is safe to treat
18418
18521
  // as 'pending' because processedHeight comes from Gateway's /v1/info
@@ -18421,7 +18524,10 @@ function assertNotSelfDelegation(chain, signerAddress, delegateAddress, action)
18421
18524
  // Re-throw structural errors to avoid masking real bugs.
18422
18525
  let finalizedResult;
18423
18526
  try {
18424
- finalizedResult = await finalizedRequest.execute();
18527
+ finalizedResult = await executeAdapterReadAction(adapter, 'gateway.v1.isDelegate', {
18528
+ ...baseActionParams,
18529
+ blockNumber: processedHeight
18530
+ }, operationContext);
18425
18531
  } catch (error) {
18426
18532
  if (isBlockRangeError(error)) {
18427
18533
  return 'pending';
@@ -18482,8 +18588,8 @@ function parseAmountSafe(amount) {
18482
18588
  chain
18483
18589
  };
18484
18590
  const [withdrawingRaw, withdrawalBlockRaw] = await Promise.all([
18485
- adapter.prepareAction('gateway.v1.withdrawingBalance', readParams, operationContext).then(async (req)=>req.execute()),
18486
- adapter.prepareAction('gateway.v1.withdrawalBlock', readParams, operationContext).then(async (req)=>req.execute())
18591
+ executeAdapterReadAction(adapter, 'gateway.v1.withdrawingBalance', readParams, operationContext),
18592
+ executeAdapterReadAction(adapter, 'gateway.v1.withdrawalBlock', readParams, operationContext)
18487
18593
  ]);
18488
18594
  const withdrawingValue = safeBigInt(String(withdrawingRaw), 'withdrawingBalance');
18489
18595
  const withdrawalBlockValue = safeBigInt(String(withdrawalBlockRaw), 'withdrawalBlock');
@@ -18523,12 +18629,11 @@ function parseAmountSafe(amount) {
18523
18629
  const tokenAddress = getTokenAddress(chain, params.token);
18524
18630
  // Read the pending balance before withdrawing — the contract resets it to 0
18525
18631
  // after withdraw() executes, so this is the only way to capture the amount.
18526
- const withdrawingBalanceReq = await adapter.prepareAction('gateway.v1.withdrawingBalance', {
18632
+ const withdrawingRaw = await executeAdapterReadAction(adapter, 'gateway.v1.withdrawingBalance', {
18527
18633
  token: tokenAddress,
18528
18634
  depositor: signerAddress,
18529
18635
  chain
18530
18636
  }, operationContext);
18531
- const withdrawingRaw = await withdrawingBalanceReq.execute();
18532
18637
  const withdrawingValue = safeBigInt(String(withdrawingRaw), 'withdrawingBalance');
18533
18638
  if (withdrawingValue === 0n) {
18534
18639
  throw new KitError({
@@ -2604,6 +2604,18 @@ interface TokenActionMap {
2604
2604
  */
2605
2605
  walletAddress?: string | undefined;
2606
2606
  };
2607
+ /**
2608
+ * Get the on-chain name of the token contract.
2609
+ *
2610
+ * This is a read-only operation. For USDC the value is also the EIP-712
2611
+ * domain name, which permit and authorize signing flows need.
2612
+ */
2613
+ name: ActionParameters & {
2614
+ /**
2615
+ * The contract address of the token.
2616
+ */
2617
+ tokenAddress: string;
2618
+ };
2607
2619
  }
2608
2620
 
2609
2621
  /**
@@ -3433,6 +3445,30 @@ declare class ActionRegistry {
3433
3445
  executeAction<TActionKey extends ActionKeys>(action: TActionKey, params: ActionPayload<TActionKey>, context: ResolvedOperationContext): Promise<PreparedChainRequest>;
3434
3446
  }
3435
3447
 
3448
+ /**
3449
+ * Canonical list of actions that do not prepare or submit transactions.
3450
+ *
3451
+ * @internal
3452
+ */
3453
+ declare const READ_ACTION_KEYS: readonly ["token.allowance", "token.balanceOf", "token.name", "native.balanceOf", "usdc.allowance", "usdc.balanceOf", "usdc.name", "gateway.v1.isDelegate", "gateway.v1.withdrawingBalance", "gateway.v1.withdrawalBlock", "gateway.v1.signBurnIntents"];
3454
+ /**
3455
+ * Action keys that execute without preparing or submitting a transaction.
3456
+ *
3457
+ * @remarks
3458
+ * Derive this type from the canonical runtime list so compile-time and runtime
3459
+ * classification cannot drift. `gateway.v1.signBurnIntents` is included
3460
+ * because the action system models off-chain signing as a read action: it does
3461
+ * not prepare a chain request.
3462
+ *
3463
+ * @example
3464
+ * ```typescript
3465
+ * import type { ReadActionKey } from '@core/adapter'
3466
+ *
3467
+ * const action: ReadActionKey = 'token.allowance'
3468
+ * ```
3469
+ */
3470
+ type ReadActionKey = (typeof READ_ACTION_KEYS)[number];
3471
+
3436
3472
  /**
3437
3473
  * Defines the capabilities of an adapter, including address handling patterns and supported chains.
3438
3474
  *
@@ -3601,6 +3637,69 @@ declare abstract class Adapter<TAdapterCapabilities extends AdapterCapabilities
3601
3637
  * ```
3602
3638
  */
3603
3639
  prepareAction<TActionKey extends ActionKeys>(action: TActionKey, params: ActionPayload<TActionKey>, ctx: OperationContext<TAdapterCapabilities>): Promise<PreparedChainRequest>;
3640
+ /**
3641
+ * Execute a non-transaction action without routing through transaction preparation.
3642
+ *
3643
+ * @remarks
3644
+ * Use this seam for balance, allowance, contract-state, and other actions
3645
+ * classified as reads. It never calls {@link Adapter.prepareAction}, so
3646
+ * transaction authorization wrappers only observe actions that can produce a
3647
+ * signable chain request.
3648
+ *
3649
+ * @typeParam TActionKey - The read action key.
3650
+ * @param action - The read action to execute.
3651
+ * @param params - The parameters for the read action.
3652
+ * @param ctx - The operation context.
3653
+ * @returns The raw action response.
3654
+ * @throws {KitError} When the key is not a read action or no handler is registered.
3655
+ * @throws Error When the operation context or action handler fails.
3656
+ *
3657
+ * @example
3658
+ * ```typescript
3659
+ * import { Ethereum } from '@core/chains'
3660
+ *
3661
+ * const balance = await adapter.readAction(
3662
+ * 'token.balanceOf',
3663
+ * { tokenAddress, walletAddress },
3664
+ * { chain: Ethereum },
3665
+ * )
3666
+ * ```
3667
+ *
3668
+ * @internal
3669
+ */
3670
+ readAction<TActionKey extends ReadActionKey>(action: TActionKey, params: ActionPayload<TActionKey>, ctx: OperationContext<TAdapterCapabilities>): Promise<unknown>;
3671
+ /**
3672
+ * Read the current token allowance a delegate holds over an owner's tokens.
3673
+ *
3674
+ * @remarks
3675
+ * Perform a network read through {@link Adapter.readAction}. This method
3676
+ * never routes through {@link Adapter.prepareAction}. On chains without an
3677
+ * allowance model, such as Solana, return the maximum uint256 value.
3678
+ *
3679
+ * @param params - The token to query and the delegate whose allowance is being read.
3680
+ * @param ctx - Operation context with compile-time validated address requirements.
3681
+ * @returns A promise resolving to the current allowance in the token's base units.
3682
+ * @throws {KitError} When the adapter does not register a `token.allowance` handler.
3683
+ * @throws Error When the operation context or action handler fails.
3684
+ *
3685
+ * @example
3686
+ * ```typescript
3687
+ * import type { Adapter } from '@core/adapter'
3688
+ * import { Ethereum } from '@core/chains'
3689
+ *
3690
+ * declare const adapter: Adapter
3691
+ *
3692
+ * const allowance = await adapter.getTokenAllowance(
3693
+ * {
3694
+ * tokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
3695
+ * delegate: '0x1111111111111111111111111111111111111111',
3696
+ * },
3697
+ * { chain: Ethereum },
3698
+ * )
3699
+ * console.log(allowance) // 1000000n
3700
+ * ```
3701
+ */
3702
+ getTokenAllowance(params: ActionPayload<'token.allowance'>, ctx: OperationContext<TAdapterCapabilities>): Promise<bigint>;
3604
3703
  /**
3605
3704
  * Prepares a transaction for future gas estimation and execution.
3606
3705
  *
@@ -3787,6 +3886,37 @@ declare abstract class Adapter<TAdapterCapabilities extends AdapterCapabilities
3787
3886
  abstract getTokenDecimals(tokenAddress: string, chain: ChainDefinition): Promise<number>;
3788
3887
  }
3789
3888
 
3889
+ /**
3890
+ * Simplified error information structure for logging and events.
3891
+ *
3892
+ * @remarks
3893
+ * This lightweight type is used for error reporting in events, logs, and
3894
+ * observability systems. It provides essential error context without the
3895
+ * full ErrorDetails structure. Used across retry mechanisms, adapters,
3896
+ * and other subsystems that need to record error information.
3897
+ *
3898
+ * @example
3899
+ * ```typescript
3900
+ * import { ErrorInfo } from '@core/errors'
3901
+ *
3902
+ * const info: ErrorInfo = {
3903
+ * name: 'NETWORK_TIMEOUT',
3904
+ * message: 'Request timed out after 5000ms',
3905
+ * code: 3002
3906
+ * }
3907
+ * ```
3908
+ */
3909
+ interface ErrorInfo {
3910
+ /** Error name (e.g., 'TypeError', 'KitError', 'NETWORK_TIMEOUT'). */
3911
+ name: string;
3912
+ /** Error message describing what went wrong. */
3913
+ message: string;
3914
+ /** Optional error code if the error has one (e.g., KitError codes). */
3915
+ code?: number;
3916
+ /** Error category (e.g., INPUT, RPC, ONCHAIN, BALANCE, NETWORK, UNKNOWN). Only set for KitError instances. */
3917
+ type?: string;
3918
+ }
3919
+
3790
3920
  /**
3791
3921
  * A type-safe event emitter for managing action-based event subscriptions.
3792
3922
  *
@@ -4027,37 +4157,6 @@ declare module './types' {
4027
4157
  }
4028
4158
  }
4029
4159
 
4030
- /**
4031
- * Simplified error information structure for logging and events.
4032
- *
4033
- * @remarks
4034
- * This lightweight type is used for error reporting in events, logs, and
4035
- * observability systems. It provides essential error context without the
4036
- * full ErrorDetails structure. Used across retry mechanisms, adapters,
4037
- * and other subsystems that need to record error information.
4038
- *
4039
- * @example
4040
- * ```typescript
4041
- * import { ErrorInfo } from '@core/errors'
4042
- *
4043
- * const info: ErrorInfo = {
4044
- * name: 'NETWORK_TIMEOUT',
4045
- * message: 'Request timed out after 5000ms',
4046
- * code: 3002
4047
- * }
4048
- * ```
4049
- */
4050
- interface ErrorInfo {
4051
- /** Error name (e.g., 'TypeError', 'KitError', 'NETWORK_TIMEOUT'). */
4052
- name: string;
4053
- /** Error message describing what went wrong. */
4054
- message: string;
4055
- /** Optional error code if the error has one (e.g., KitError codes). */
4056
- code?: number;
4057
- /** Error category (e.g., INPUT, RPC, ONCHAIN, BALANCE, NETWORK, UNKNOWN). Only set for KitError instances. */
4058
- type?: string;
4059
- }
4060
-
4061
4160
  /**
4062
4161
  * Runtime array of token identifiers supported by the Gateway v1 provider.
4063
4162
  *