@circle-fin/app-kit 1.15.3 → 1.17.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 (60) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/README.md +5 -2
  3. package/borrow.cjs +28146 -0
  4. package/borrow.cjs.map +1 -0
  5. package/borrow.d.cts +10752 -0
  6. package/borrow.d.mts +10752 -0
  7. package/borrow.d.ts +10752 -0
  8. package/borrow.mjs +28118 -0
  9. package/borrow.mjs.map +1 -0
  10. package/bridge.cjs +2084 -328
  11. package/bridge.d.cts +121 -18
  12. package/bridge.d.mts +121 -18
  13. package/bridge.d.ts +121 -18
  14. package/bridge.mjs +2084 -328
  15. package/chains.cjs +78 -7
  16. package/chains.d.cts +2 -0
  17. package/chains.d.mts +2 -0
  18. package/chains.d.ts +2 -0
  19. package/chains.mjs +78 -7
  20. package/context.cjs +1 -0
  21. package/context.d.cts +121 -18
  22. package/context.d.mts +121 -18
  23. package/context.d.ts +121 -18
  24. package/context.mjs +1 -0
  25. package/earn.cjs +5322 -3219
  26. package/earn.d.cts +1149 -984
  27. package/earn.d.mts +1149 -984
  28. package/earn.d.ts +1149 -984
  29. package/earn.mjs +5322 -3219
  30. package/estimateBridge.cjs +2082 -326
  31. package/estimateBridge.d.cts +121 -18
  32. package/estimateBridge.d.mts +121 -18
  33. package/estimateBridge.d.ts +121 -18
  34. package/estimateBridge.mjs +2082 -326
  35. package/estimateSwap.cjs +8817 -6974
  36. package/estimateSwap.d.cts +169 -18
  37. package/estimateSwap.d.mts +169 -18
  38. package/estimateSwap.d.ts +169 -18
  39. package/estimateSwap.mjs +8822 -6979
  40. package/index.cjs +33149 -20719
  41. package/index.d.cts +23174 -2736
  42. package/index.d.mts +23174 -2736
  43. package/index.d.ts +23174 -2736
  44. package/index.mjs +33090 -20713
  45. package/package.json +17 -7
  46. package/server.cjs +133 -12
  47. package/server.d.cts +29 -10
  48. package/server.d.mts +29 -10
  49. package/server.d.ts +29 -10
  50. package/server.mjs +133 -12
  51. package/swap.cjs +8817 -6974
  52. package/swap.d.cts +169 -18
  53. package/swap.d.mts +169 -18
  54. package/swap.d.ts +169 -18
  55. package/swap.mjs +8822 -6979
  56. package/unifiedBalance.cjs +528 -138
  57. package/unifiedBalance.d.cts +108 -11
  58. package/unifiedBalance.d.mts +108 -11
  59. package/unifiedBalance.d.ts +108 -11
  60. package/unifiedBalance.mjs +528 -138
@@ -1341,6 +1341,34 @@ let activeRedactor = defaultMessageRedactor;
1341
1341
  return redactErrorMessage(String(error));
1342
1342
  }
1343
1343
 
1344
+ /**
1345
+ * Render an object value for an error message without letting the rendering
1346
+ * itself throw.
1347
+ *
1348
+ * `JSON.stringify` rejects `BigInt` and circular structures, and a rejected
1349
+ * value is exactly the kind of thing a validation error is built from: an
1350
+ * on-chain read or a receipt log carries `bigint` fields, so serializing one
1351
+ * naively replaces the intended error with a `TypeError`.
1352
+ *
1353
+ * @param value - The value to render.
1354
+ * @returns A JSON string with `bigint` fields stringified, or
1355
+ * `'[unserializable object]'` if serialization still fails.
1356
+ * @throws Never; serialization failures are caught and rendered as a fallback string.
1357
+ * @example
1358
+ * ```typescript
1359
+ * import { describeObjectValue } from '@core/errors'
1360
+ *
1361
+ * describeObjectValue({ amount: 1n })
1362
+ * // '{"amount":"1"}'
1363
+ * ```
1364
+ */ function describeObjectValue(value) {
1365
+ try {
1366
+ return JSON.stringify(value, (_key, entry)=>typeof entry === 'bigint' ? entry.toString() : entry);
1367
+ } catch {
1368
+ return '[unserializable object]';
1369
+ }
1370
+ }
1371
+
1344
1372
  /**
1345
1373
  * Creates error for network type mismatch between source and destination.
1346
1374
  *
@@ -1569,7 +1597,7 @@ let activeRedactor = defaultMessageRedactor;
1569
1597
  * // Message: "Validation failed for 'chainId': 999 - Unsupported chain ID"
1570
1598
  *
1571
1599
  * throw createValidationFailedError('config', { invalid: true }, 'Missing required properties')
1572
- * // Message: "Validation failed for 'config': [object Object] - Missing required properties"
1600
+ * // Message: "Validation failed for 'config': {"invalid":true} - Missing required properties"
1573
1601
  * ```
1574
1602
  */ function createValidationFailedError$1(field, value, reason) {
1575
1603
  // Convert value to string for display, handling different types appropriately
@@ -1577,7 +1605,7 @@ let activeRedactor = defaultMessageRedactor;
1577
1605
  if (typeof value === 'string') {
1578
1606
  valueString = `'${value}'`;
1579
1607
  } else if (typeof value === 'object' && value !== null) {
1580
- valueString = JSON.stringify(value);
1608
+ valueString = describeObjectValue(value);
1581
1609
  } else {
1582
1610
  valueString = String(value);
1583
1611
  }
@@ -2383,22 +2411,73 @@ let activeRedactor = defaultMessageRedactor;
2383
2411
  '0x9147d463': 'Final balance is less than the initial balance',
2384
2412
  '0xf4b3b1bc': 'Native token transfer to the beneficiary failed'
2385
2413
  };
2414
+ /**
2415
+ * Matches revert data: a 4-byte selector followed by whole ABI-encoded bytes.
2416
+ */ const REVERT_DATA_PATTERN = /^0x[0-9a-f]{8}(?:[0-9a-f]{2})*$/i;
2417
+ /**
2418
+ * Returns the revert data held by one error in a `cause` chain.
2419
+ *
2420
+ * Browser wallets (EIP-1193) wrap the node's error, so the revert data sits
2421
+ * one level down as `data.data`. viem's `getContractError` reads it the same
2422
+ * way, then keeps it on `ContractFunctionRevertedError.raw` and drops the
2423
+ * node's error from the chain.
2424
+ *
2425
+ * @param link - One error in the `cause` chain
2426
+ * @returns The `raw` or `data` string, or undefined if there is none
2427
+ */ function getRevertData(link) {
2428
+ if ('raw' in link && typeof link.raw === 'string' && REVERT_DATA_PATTERN.test(link.raw)) {
2429
+ return link.raw;
2430
+ }
2431
+ if (!('data' in link)) {
2432
+ return undefined;
2433
+ }
2434
+ const { data } = link;
2435
+ if (typeof data === 'string') {
2436
+ return data;
2437
+ }
2438
+ if (data !== null && typeof data === 'object' && 'data' in data && typeof data.data === 'string') {
2439
+ return data.data;
2440
+ }
2441
+ return undefined;
2442
+ }
2443
+ /**
2444
+ * Finds the first revert data on the error or in its `cause` chain that
2445
+ * `accept` takes.
2446
+ *
2447
+ * viem keeps the node's revert data on an inner `RpcRequestError`, not on
2448
+ * the error it throws. The `seen` set stops a self-referencing `cause` chain.
2449
+ *
2450
+ * @param error - The error object
2451
+ * @param accept - Returns true for the data shape the caller wants
2452
+ * @returns The data as written on the error, or undefined if not found
2453
+ */ function findRevertData(error, accept) {
2454
+ const seen = new Set();
2455
+ let current = error;
2456
+ while(current !== null && typeof current === 'object' && !seen.has(current)){
2457
+ seen.add(current);
2458
+ const data = getRevertData(current);
2459
+ if (data !== undefined && accept(data)) {
2460
+ return data;
2461
+ }
2462
+ current = 'cause' in current ? current.cause : undefined;
2463
+ }
2464
+ return undefined;
2465
+ }
2386
2466
  /**
2387
2467
  * Attempts to extract an error selector from an error object or message.
2388
2468
  *
2389
2469
  * Checks multiple sources in priority order:
2390
- * 1. `error.data` field
2470
+ * 1. `raw` or `data` field (or nested `data.data`) on the error or anywhere
2471
+ * in its `cause` chain
2391
2472
  * 2. Message pattern: "custom error 0x8baa579f"
2392
2473
  *
2393
2474
  * @param msg - The error message
2394
2475
  * @param error - The error object (optional)
2395
2476
  * @returns The 4 bytes selector , or undefined if not found
2396
2477
  */ function extractErrorSelector(msg, error) {
2397
- // Check error.data field
2398
- if (error !== null && typeof error === 'object' && 'data' in error) {
2399
- if (typeof error.data === 'string' && /^0x[0-9a-f]{8}$/i.test(error.data)) {
2400
- return error.data.toLowerCase();
2401
- }
2478
+ const data = findRevertData(error, (value)=>/^0x[0-9a-f]{8}$/i.test(value));
2479
+ if (data !== undefined) {
2480
+ return data.toLowerCase();
2402
2481
  }
2403
2482
  // Check for "custom error 0x8baa579f" in the message
2404
2483
  const match = /custom error (0x[0-9a-f]{8})\b/i.exec(msg);
@@ -2976,6 +3055,105 @@ let activeRedactor = defaultMessageRedactor;
2976
3055
  return chain;
2977
3056
  }
2978
3057
 
3058
+ /**
3059
+ * Extracts the HTTP status code from an error message.
3060
+ *
3061
+ * Attempts to parse HTTP status codes from common error message formats,
3062
+ * such as "HTTP 404" or "Status: 500".
3063
+ *
3064
+ * Shared by `parseApiError` and the backend-error-code parsers that route on
3065
+ * status when no backend code is available, so all of them recognise the same
3066
+ * message shapes.
3067
+ *
3068
+ * @param msg - The error message to extract from
3069
+ * @returns The extracted HTTP status code, or null if not found
3070
+ *
3071
+ * @example
3072
+ * ```typescript
3073
+ * const code = extractHttpStatusCode('HTTP 404')
3074
+ * // Returns: 404
3075
+ * ```
3076
+ *
3077
+ * @example
3078
+ * ```typescript
3079
+ * const code = extractHttpStatusCode('Status: 500 Internal Server Error')
3080
+ * // Returns: 500
3081
+ * ```
3082
+ *
3083
+ * @internal
3084
+ */ function extractHttpStatusCode(msg) {
3085
+ // Pattern: "HTTP 404" or "HTTP 404 - some message" or "Status: 404"
3086
+ const patterns = [
3087
+ /HTTP (\d{3})/i,
3088
+ /Status:\s*(\d{3})/i,
3089
+ /^(\d{3}) -/
3090
+ ];
3091
+ for (const pattern of patterns){
3092
+ const match = pattern.exec(msg);
3093
+ const codeStr = match?.at(1);
3094
+ if (codeStr !== undefined) {
3095
+ const code = Number.parseInt(codeStr, 10);
3096
+ // Validate it's a valid HTTP status code
3097
+ if (code >= 100 && code < 600) {
3098
+ return code;
3099
+ }
3100
+ }
3101
+ }
3102
+ return null;
3103
+ }
3104
+
3105
+ /**
3106
+ * Type guard that narrows an unknown error to one carrying a non-null
3107
+ * object `responseBody` property (attached by `makeApiRequest`).
3108
+ *
3109
+ * Shared by backend-error-code parsers (`parseEarnApiError`,
3110
+ * `parseBorrowApiError`) so the narrowing logic lives in one place.
3111
+ *
3112
+ * @param error - The raw error from the HTTP layer
3113
+ * @returns `true` when `error.responseBody` is a non-null object
3114
+ * @internal
3115
+ */ function hasResponseBody(error) {
3116
+ return typeof error === 'object' && error !== null && 'responseBody' in error && typeof error['responseBody'] === 'object' && error['responseBody'] !== null;
3117
+ }
3118
+ /**
3119
+ * Narrow an unknown value to a non-null object.
3120
+ *
3121
+ * @param value - The value to check
3122
+ * @returns `true` when `value` is a non-null object
3123
+ * @internal
3124
+ */ function isRecord(value) {
3125
+ return typeof value === 'object' && value !== null;
3126
+ }
3127
+ /**
3128
+ * Read the machine-readable error fields (`code`, `message`,
3129
+ * `externalMessage`) that a Circle service attaches to an HTTP error body.
3130
+ *
3131
+ * `platform-common-go` serializes app-thrown errors under a nested envelope —
3132
+ * `{ response: { status: { code, message, externalMessage } } }` — for every
3133
+ * HTTP status, so this returns that inner `response.status` object when
3134
+ * present. It otherwise falls back to the top-level body so a flattened shape
3135
+ * (e.g. the stablecoin-kits-proxy) is still read. Callers read
3136
+ * `code` / `message` / `externalMessage` off the returned object uniformly.
3137
+ *
3138
+ * @param error - The raw error from the HTTP layer
3139
+ * @returns The error-status fields, or `undefined` when the error carries no
3140
+ * response body
3141
+ * @internal
3142
+ */ function extractResponseBody$1(error) {
3143
+ if (!hasResponseBody(error)) {
3144
+ return undefined;
3145
+ }
3146
+ const body = error.responseBody;
3147
+ const response = body['response'];
3148
+ if (isRecord(response)) {
3149
+ const status = response['status'];
3150
+ if (isRecord(status)) {
3151
+ return status;
3152
+ }
3153
+ }
3154
+ return body;
3155
+ }
3156
+
2979
3157
  /**
2980
3158
  * Proxy-specific structured error codes carried in `responseBody.code`.
2981
3159
  *
@@ -3276,29 +3454,22 @@ let activeRedactor = defaultMessageRedactor;
3276
3454
  });
3277
3455
  }
3278
3456
  /**
3279
- * Type guard that narrows an unknown error to one carrying a non-null
3280
- * object `responseBody` property (attached by `makeApiRequest`).
3457
+ * Extract the machine-readable error fields that `makeApiRequest` attaches to
3458
+ * HTTP error instances.
3281
3459
  *
3282
- * @param error - The raw error from the HTTP layer
3283
- * @returns `true` when `error.responseBody` is a non-null object
3284
- * @internal
3285
- */ function hasResponseBody(error) {
3286
- return typeof error === 'object' && error !== null && 'responseBody' in error && typeof error['responseBody'] === 'object' && error['responseBody'] !== null;
3287
- }
3288
- /**
3289
- * Extract the `responseBody` property that `makeApiRequest` attaches to
3290
- * HTTP error instances when the server returns a JSON body.
3460
+ * Delegates to the shared extractor so this fall-through path reads the same
3461
+ * shape as the backend-code parsers: it unwraps the nested
3462
+ * `{ response: { status } }` envelope when present, otherwise returns the
3463
+ * top-level body. Routing both halves through one extractor keeps an
3464
+ * unmapped-code error from losing the server's `externalMessage`.
3291
3465
  *
3292
3466
  * @param error - The raw error from the HTTP layer
3293
- * @returns The parsed body cast to {@link ApiErrorResponseBody}, or undefined
3467
+ * @returns The parsed body as {@link ApiErrorResponseBody}, or undefined
3294
3468
  * @throws Never. Returns `undefined` when the error does not carry a valid
3295
3469
  * `responseBody`.
3296
3470
  * @internal
3297
3471
  */ function extractResponseBody(error) {
3298
- if (!hasResponseBody(error)) {
3299
- return undefined;
3300
- }
3301
- return error.responseBody;
3472
+ return extractResponseBody$1(error);
3302
3473
  }
3303
3474
  /**
3304
3475
  * Extract a field name from an {@link ApiFieldError}.
@@ -3407,46 +3578,6 @@ let activeRedactor = defaultMessageRedactor;
3407
3578
  }
3408
3579
  return topMessage ?? fieldDetail;
3409
3580
  }
3410
- /**
3411
- * Extracts the HTTP status code from an error message.
3412
- *
3413
- * Attempts to parse HTTP status codes from common error message formats,
3414
- * such as "HTTP 404" or "Status: 500".
3415
- *
3416
- * @param msg - The error message to extract from
3417
- * @returns The extracted HTTP status code, or null if not found
3418
- *
3419
- * @example
3420
- * ```typescript
3421
- * const code = extractHttpStatusCode('HTTP 404')
3422
- * // Returns: 404
3423
- * ```
3424
- *
3425
- * @example
3426
- * ```typescript
3427
- * const code = extractHttpStatusCode('Status: 500 Internal Server Error')
3428
- * // Returns: 500
3429
- * ```
3430
- */ function extractHttpStatusCode(msg) {
3431
- // Pattern: "HTTP 404" or "HTTP 404 - some message" or "Status: 404"
3432
- const patterns = [
3433
- /HTTP (\d{3})/i,
3434
- /Status:\s*(\d{3})/i,
3435
- /^(\d{3}) -/
3436
- ];
3437
- for (const pattern of patterns){
3438
- const match = pattern.exec(msg);
3439
- const codeStr = match?.at(1);
3440
- if (codeStr !== undefined) {
3441
- const code = Number.parseInt(codeStr, 10);
3442
- // Validate it's a valid HTTP status code
3443
- if (code >= 100 && code < 600) {
3444
- return code;
3445
- }
3446
- }
3447
- }
3448
- return null;
3449
- }
3450
3581
 
3451
3582
  /**
3452
3583
  * @packageDocumentation
@@ -3571,6 +3702,8 @@ var SwapChain;
3571
3702
  SwapChain["HyperEVM"] = "HyperEVM";
3572
3703
  SwapChain["Monad"] = "Monad";
3573
3704
  SwapChain["Arc"] = "Arc";
3705
+ SwapChain["Cronos"] = "Cronos";
3706
+ SwapChain["Morph"] = "Morph";
3574
3707
  // Testnet chains with swap support
3575
3708
  SwapChain["Arc_Testnet"] = "Arc_Testnet";
3576
3709
  })(SwapChain || (SwapChain = {}));
@@ -3702,6 +3835,11 @@ var EarnChain;
3702
3835
  "Arc",
3703
3836
  "Arc_Testnet"
3704
3837
  ];
3838
+ var BorrowChain;
3839
+ (function(BorrowChain) {
3840
+ BorrowChain["Arc"] = "Arc";
3841
+ BorrowChain["Arc_Testnet"] = "Arc_Testnet";
3842
+ })(BorrowChain || (BorrowChain = {}));
3705
3843
 
3706
3844
  /**
3707
3845
  * Helper function to define a chain with proper TypeScript typing.
@@ -4044,6 +4182,29 @@ var EarnChain;
4044
4182
  * on EVM-compatible testnet chains. Use this address for testnet adapter
4045
4183
  * integrations (e.g., Arc Testnet).
4046
4184
  */ const ADAPTER_CONTRACT_EVM_TESTNET = '0xBBD70b01a1CAbc96d5b7b129Ae1AAabdf50dd40b';
4185
+ /**
4186
+ * The sender-preserving batching contract on Arc (`Multicall3From`).
4187
+ *
4188
+ * This predeploy batches calls like the ubiquitous Multicall3, but routes each
4189
+ * subcall through Arc's `CallFrom` precompile
4190
+ * (`0x1800000000000000000000000000000000000003`), which executes on behalf of
4191
+ * the transaction's original sender. Every target therefore sees the calling
4192
+ * EOA as `msg.sender`, which is what makes a plain, un-upgraded EOA capable of
4193
+ * an atomic batch on Arc.
4194
+ *
4195
+ * Deployed at the same address on Arc Testnet and Arc Mainnet.
4196
+ *
4197
+ * @see https://docs.arc.io/arc/concepts/batched-transactions
4198
+ */ const BATCHER_CONTRACT_ARC_TESTNET = '0x522fAf9A91c41c443c66765030741e4AaCe147D0';
4199
+ /**
4200
+ * The sender-preserving batching contract on Arc Mainnet (`Multicall3From`).
4201
+ *
4202
+ * See {@link BATCHER_CONTRACT_ARC_TESTNET} for how this contract works.
4203
+ * Requires Arc's Zero7 hardfork, which activates the `CallFrom` precompile
4204
+ * this contract depends on.
4205
+ *
4206
+ * @see https://docs.arc.io/arc/concepts/batched-transactions
4207
+ */ const BATCHER_CONTRACT_ARC_MAINNET = '0x522fAf9A91c41c443c66765030741e4AaCe147D0';
4047
4208
  /**
4048
4209
  * The GatewayWallet contract address for EVM mainnet networks.
4049
4210
  *
@@ -4193,7 +4354,10 @@ var EarnChain;
4193
4354
  },
4194
4355
  kitContracts: {
4195
4356
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
4196
- adapter: ADAPTER_CONTRACT_EVM_MAINNET
4357
+ adapter: ADAPTER_CONTRACT_EVM_MAINNET,
4358
+ // Arc is the only chain with a sender-preserving batcher, because it
4359
+ // takes a precompile rather than an ordinary contract to build one.
4360
+ senderPreservingBatcher: BATCHER_CONTRACT_ARC_MAINNET
4197
4361
  },
4198
4362
  gateway: {
4199
4363
  domain: 26,
@@ -4264,7 +4428,10 @@ var EarnChain;
4264
4428
  },
4265
4429
  kitContracts: {
4266
4430
  bridge: BRIDGE_CONTRACT_EVM_TESTNET,
4267
- adapter: ADAPTER_CONTRACT_EVM_TESTNET
4431
+ adapter: ADAPTER_CONTRACT_EVM_TESTNET,
4432
+ // Arc is the only chain with a sender-preserving batcher, because it
4433
+ // takes a precompile rather than an ordinary contract to build one.
4434
+ senderPreservingBatcher: BATCHER_CONTRACT_ARC_TESTNET
4268
4435
  },
4269
4436
  gateway: {
4270
4437
  domain: 26,
@@ -4879,7 +5046,8 @@ var EarnChain;
4879
5046
  }
4880
5047
  },
4881
5048
  kitContracts: {
4882
- bridge: BRIDGE_CONTRACT_EVM_MAINNET
5049
+ bridge: BRIDGE_CONTRACT_EVM_MAINNET,
5050
+ adapter: ADAPTER_CONTRACT_EVM_MAINNET
4883
5051
  }
4884
5052
  });
4885
5053
 
@@ -5748,7 +5916,8 @@ var EarnChain;
5748
5916
  }
5749
5917
  },
5750
5918
  kitContracts: {
5751
- bridge: BRIDGE_CONTRACT_EVM_MAINNET
5919
+ bridge: BRIDGE_CONTRACT_EVM_MAINNET,
5920
+ adapter: ADAPTER_CONTRACT_EVM_MAINNET
5752
5921
  }
5753
5922
  });
5754
5923
 
@@ -7939,7 +8108,8 @@ var Chains = {
7939
8108
  cctpx: zod.z.any().optional(),
7940
8109
  kitContracts: zod.z.object({
7941
8110
  bridge: zod.z.string().optional(),
7942
- adapter: zod.z.string().optional()
8111
+ adapter: zod.z.string().optional(),
8112
+ senderPreservingBatcher: zod.z.string().optional()
7943
8113
  }).optional(),
7944
8114
  gateway: gatewayConfigSchema.optional()
7945
8115
  });
@@ -8050,8 +8220,8 @@ var Chains = {
8050
8220
  * Zod schema for validating swap-specific chain identifiers.
8051
8221
  *
8052
8222
  * Validates chains based on:
8053
- * - CCTPv2 support (adapter contract deployed)
8054
- * - Mainnet only (no testnets)
8223
+ * - Membership in the SwapChain enum
8224
+ * - Mainnet or explicitly allowlisted testnet
8055
8225
  * - At least one supported token available
8056
8226
  *
8057
8227
  */ zod.z.union([
@@ -8135,6 +8305,38 @@ var Chains = {
8135
8305
  message: `"${chain.chain}" is not a supported earn chain. ` + `Supported chains: ${Object.values(EarnChain).join(', ')}`
8136
8306
  }))
8137
8307
  ]);
8308
+ /**
8309
+ * Zod schema for validating Borrow-specific chain identifiers.
8310
+ *
8311
+ * Validate that the provided chain is supported for Borrow Kit's loan
8312
+ * operations. Unlike {@link earnChainIdentifierSchema}, this includes Arc
8313
+ * mainnet as well as Arc Testnet.
8314
+ *
8315
+ * Accept a BorrowChain enum value, a matching string literal, or a
8316
+ * ChainDefinition for a supported chain.
8317
+ *
8318
+ * @example
8319
+ * ```typescript
8320
+ * import { borrowChainIdentifierSchema } from '@core/chains'
8321
+ * import { Arc, BorrowChain } from '@core/chains'
8322
+ *
8323
+ * // Valid
8324
+ * borrowChainIdentifierSchema.parse(BorrowChain.Arc)
8325
+ * borrowChainIdentifierSchema.parse('Arc')
8326
+ * borrowChainIdentifierSchema.parse(Arc)
8327
+ *
8328
+ * // Invalid (throws ZodError)
8329
+ * borrowChainIdentifierSchema.parse('Solana')
8330
+ * ```
8331
+ */ zod.z.union([
8332
+ zod.z.string().refine((val)=>val in BorrowChain, (val)=>({
8333
+ message: `"${val}" is not a supported borrow chain. ` + `Supported chains: ${Object.values(BorrowChain).join(', ')}`
8334
+ })),
8335
+ zod.z.nativeEnum(BorrowChain),
8336
+ chainDefinitionSchema$2.refine((chain)=>chain.chain in BorrowChain, (chain)=>({
8337
+ message: `"${chain.chain}" is not a supported borrow chain. ` + `Supported chains: ${Object.values(BorrowChain).join(', ')}`
8338
+ }))
8339
+ ]);
8138
8340
  // Widened views so `.includes()` accepts arbitrary strings under strict TS.
8139
8341
  const EARN_BRIDGE_SOURCE_CHAIN_VALUES = EARN_BRIDGE_SOURCE_BLOCKCHAINS;
8140
8342
  const EARN_BRIDGE_DESTINATION_CHAIN_VALUES = EARN_BRIDGE_DESTINATION_BLOCKCHAINS;
@@ -8389,8 +8591,13 @@ const swapTokenEnumSchema = zod.z.enum([
8389
8591
  */ function resolveChainName(value) {
8390
8592
  if (value == null) return undefined;
8391
8593
  if (typeof value === 'string') return value;
8392
- if (typeof value === 'object' && 'chain' in value && typeof value.chain === 'string') {
8393
- return value.chain;
8594
+ try {
8595
+ if (typeof value === 'object' && 'chain' in value) {
8596
+ const chain = value.chain;
8597
+ if (typeof chain === 'string') return chain;
8598
+ }
8599
+ } catch {
8600
+ return undefined;
8394
8601
  }
8395
8602
  return undefined;
8396
8603
  }
@@ -8999,6 +9206,7 @@ const swapTokenEnumSchema = zod.z.enum([
8999
9206
  * - Retries on rate limiting (429)
9000
9207
  * - Does not retry on client errors (4xx, except 429)
9001
9208
  * - Does not retry on validation failures
9209
+ * - Does not retry when `config.isTerminalError` marks the error terminal
9002
9210
  *
9003
9211
  * Each HTTP request is given a configurable timeout before it is aborted.
9004
9212
  * Between retry attempts the wait depends on the `backoff` strategy. The
@@ -9078,7 +9286,10 @@ const swapTokenEnumSchema = zod.z.enum([
9078
9286
  return await makeApiRequest(url, method, isValidType, effectiveConfig, body);
9079
9287
  } catch (err) {
9080
9288
  const error = err instanceof Error ? err : new Error(String(err));
9081
- if (!isRetryableError(error)) {
9289
+ // A caller-supplied predicate can mark an error terminal (e.g. a
9290
+ // deterministic 404) so it is surfaced immediately instead of burning
9291
+ // the retry budget on a non-transient answer.
9292
+ if (effectiveConfig.isTerminalError?.(error) === true || !isRetryableError(error)) {
9082
9293
  throw error;
9083
9294
  }
9084
9295
  lastError = error;
@@ -9162,7 +9373,24 @@ const swapTokenEnumSchema = zod.z.enum([
9162
9373
  * // After this call, TypeScript knows params is of type BridgeParams
9163
9374
  * ```
9164
9375
  */ function validate(value, schema, context) {
9165
- const result = schema.safeParse(value);
9376
+ let result;
9377
+ try {
9378
+ result = schema.safeParse(value);
9379
+ } catch (error) {
9380
+ throw new KitError({
9381
+ ...InputError.VALIDATION_FAILED,
9382
+ recoverability: 'FATAL',
9383
+ message: `Invalid ${context}: reading a property threw`,
9384
+ cause: {
9385
+ trace: {
9386
+ validationErrors: [
9387
+ 'Reading a property of the value threw'
9388
+ ],
9389
+ originalError: error
9390
+ }
9391
+ }
9392
+ });
9393
+ }
9166
9394
  if (!result.success) {
9167
9395
  throw createValidationErrorFromZod(result.error, context);
9168
9396
  }
@@ -9890,11 +10118,13 @@ function parseOrThrow(value, schema, context) {
9890
10118
  [Blockchain.Arbitrum]: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9',
9891
10119
  [Blockchain.Avalanche]: '0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7',
9892
10120
  [Blockchain.Celo]: '0x48065fbBE25f71C9282ddf5e1cD6D6A887483D5e',
10121
+ [Blockchain.Cronos]: '0x66e428c3f67a68878562e79A0234c1F83c208770',
9893
10122
  [Blockchain.Ethereum]: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
9894
10123
  [Blockchain.HyperEVM]: '0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb',
9895
10124
  [Blockchain.Ink]: '0x0200C29006150606B650577BBE7B6248F58470c1',
9896
10125
  [Blockchain.Linea]: '0xA219439258ca9da29E9Cc4cE5596924745e12B93',
9897
10126
  [Blockchain.Monad]: '0xe7cd86e13AC4309349F30B3435a9d337750fC82D',
10127
+ [Blockchain.Morph]: '0xe7cd86e13AC4309349F30B3435a9d337750fC82D',
9898
10128
  [Blockchain.NEAR]: 'usdt.tether-token.near',
9899
10129
  [Blockchain.Optimism]: '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58',
9900
10130
  [Blockchain.Polkadot_Asset_Hub]: '1984',
@@ -9953,6 +10183,7 @@ function parseOrThrow(value, schema, context) {
9953
10183
  [Blockchain.Arbitrum]: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1',
9954
10184
  [Blockchain.Avalanche]: '0xd586E7F844cEa2F87f50152665BCbc2C279D8d70',
9955
10185
  [Blockchain.Base]: '0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb',
10186
+ [Blockchain.Cronos]: '0xF2001B145b43032AAF5Ee2884e456CCd805F677D',
9956
10187
  [Blockchain.Ethereum]: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
9957
10188
  [Blockchain.Linea]: '0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5',
9958
10189
  [Blockchain.Optimism]: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1',
@@ -10015,7 +10246,9 @@ function parseOrThrow(value, schema, context) {
10015
10246
  [Blockchain.Arbitrum]: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1',
10016
10247
  [Blockchain.Avalanche]: '0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB',
10017
10248
  [Blockchain.Base]: '0x4200000000000000000000000000000000000006',
10249
+ [Blockchain.Cronos]: '0xe44Fd7fCb2b1581822D0c862B68222998a0c299a',
10018
10250
  [Blockchain.Ethereum]: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
10251
+ [Blockchain.Morph]: '0x5300000000000000000000000000000000000011',
10019
10252
  [Blockchain.Optimism]: '0x4200000000000000000000000000000000000006',
10020
10253
  [Blockchain.Polygon]: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619',
10021
10254
  [Blockchain.Solana]: '7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs'
@@ -10034,6 +10267,7 @@ function parseOrThrow(value, schema, context) {
10034
10267
  locators: {
10035
10268
  [Blockchain.Ethereum]: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
10036
10269
  [Blockchain.Arbitrum]: '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f',
10270
+ [Blockchain.Cronos]: '0x062E66477Faf219F25D27dCED647BF57C3107d52',
10037
10271
  [Blockchain.Avalanche]: '0x50b7545627a5162F82A992c33b87aDc75187B218'
10038
10272
  }
10039
10273
  };
@@ -11724,7 +11958,7 @@ function resolveOptions(options) {
11724
11958
  }
11725
11959
 
11726
11960
  var name = "@circle-fin/unified-balance-kit";
11727
- var version$1 = "1.7.0";
11961
+ var version$1 = "1.8.1";
11728
11962
  var pkg$1 = {
11729
11963
  name: name,
11730
11964
  version: version$1};
@@ -12433,6 +12667,12 @@ const READ_ACTION_KEY_SET = new Set(READ_ACTION_KEYS);
12433
12667
  /** EIP-2612 standard permit */ PermitType[PermitType["EIP2612"] = 1] = "EIP2612";
12434
12668
  })(PermitType || (PermitType = {}));
12435
12669
 
12670
+ var BorrowPermitType;
12671
+ (function(BorrowPermitType) {
12672
+ /** Tokens must be approved separately. */ BorrowPermitType[BorrowPermitType["NONE"] = 0] = "NONE";
12673
+ /** EIP-2612 permit calldata accompanies the token input. */ BorrowPermitType[BorrowPermitType["EIP2612"] = 1] = "EIP2612";
12674
+ })(BorrowPermitType || (BorrowPermitType = {}));
12675
+
12436
12676
  /**
12437
12677
  * Default clock implementation.
12438
12678
  *
@@ -17200,7 +17440,7 @@ const abiParameterSchema = zod.z.object({
17200
17440
  * const result = evmPreparedChainRequestParamsSchema.safeParse(params)
17201
17441
  * ```
17202
17442
  */ zod.z.object({
17203
- type: zod.z.literal('evm'),
17443
+ type: zod.z.literal('evm').optional(),
17204
17444
  abi: abiSchema,
17205
17445
  address: evmAddressSchema$1,
17206
17446
  functionName: zod.z.string({
@@ -18501,7 +18741,7 @@ function groupKey(alloc) {
18501
18741
  }
18502
18742
  }
18503
18743
 
18504
- const hexBytesSchema = zod.z.string().regex(/^0x([0-9a-fA-F]{2})*$/, {
18744
+ const hexBytesSchema$1 = zod.z.string().regex(/^0x([0-9a-fA-F]{2})*$/, {
18505
18745
  message: 'value must be a 0x-prefixed even-length hex string'
18506
18746
  }).transform((value)=>value);
18507
18747
  zod.z.object({
@@ -18513,6 +18753,53 @@ zod.z.object({
18513
18753
  amount: zod.z.bigint().refine((value)=>value >= 0n, {
18514
18754
  message: 'amount must be a non-negative bigint'
18515
18755
  }),
18756
+ permitCalldata: hexBytesSchema$1
18757
+ }))
18758
+ }).passthrough();
18759
+
18760
+ const hexBytesSchema = zod.z.string().regex(/^0x([0-9a-fA-F]{2})*$/, {
18761
+ message: 'value must be a 0x-prefixed even-length hex string'
18762
+ }).transform((value)=>value);
18763
+ function isNonNegativeBigIntLike(value) {
18764
+ try {
18765
+ return BigInt(value) >= 0n;
18766
+ } catch {
18767
+ return false;
18768
+ }
18769
+ }
18770
+ const uint256LikeSchema = zod.z.union([
18771
+ zod.z.string(),
18772
+ zod.z.bigint()
18773
+ ]).refine(isNonNegativeBigIntLike, {
18774
+ message: 'value must be a non-negative bigint-compatible string or bigint'
18775
+ });
18776
+ const borrowExecutionParamsSchema = zod.z.object({
18777
+ instructions: zod.z.array(zod.z.object({
18778
+ target: evmAddressSchema$1,
18779
+ data: hexBytesSchema,
18780
+ value: uint256LikeSchema,
18781
+ tokenIn: evmAddressSchema$1,
18782
+ amountToApprove: uint256LikeSchema,
18783
+ tokenOut: evmAddressSchema$1,
18784
+ minTokenOut: uint256LikeSchema
18785
+ }).passthrough()).min(1),
18786
+ tokens: zod.z.array(zod.z.object({
18787
+ token: evmAddressSchema$1,
18788
+ beneficiary: evmAddressSchema$1
18789
+ }).passthrough()),
18790
+ execId: uint256LikeSchema,
18791
+ deadline: uint256LikeSchema,
18792
+ metadata: hexBytesSchema
18793
+ }).passthrough();
18794
+ zod.z.object({
18795
+ executeParams: borrowExecutionParamsSchema,
18796
+ signature: evmSignatureSchema,
18797
+ tokenInputs: zod.z.array(zod.z.object({
18798
+ permitType: zod.z.nativeEnum(BorrowPermitType),
18799
+ token: evmAddressSchema$1,
18800
+ amount: zod.z.bigint().refine((value)=>value >= 0n, {
18801
+ message: 'amount must be a non-negative bigint'
18802
+ }),
18516
18803
  permitCalldata: hexBytesSchema
18517
18804
  }))
18518
18805
  }).passthrough();
@@ -29018,7 +29305,7 @@ const mockAttestationMessage = {
29018
29305
  return step;
29019
29306
  }
29020
29307
 
29021
- var version = "1.14.0";
29308
+ var version = "1.14.2";
29022
29309
  var pkg = {
29023
29310
  version: version};
29024
29311
 
@@ -31354,9 +31641,9 @@ const allowanceStrategySchema = zod.z.enum([
31354
31641
  /**
31355
31642
  * Schema for validating estimateDeposit parameters.
31356
31643
  *
31357
- * Validates `from` (adapter + chain), `amount`, required `to.chain`,
31358
- * optional `token`, `config.transferSpeed`, `depositAccount`, and
31359
- * `allowanceStrategy`.
31644
+ * Validates `from` (adapter + chain), `amount`, optional `to.chain`
31645
+ * (defaults to Arc / Arc_Testnet for FAST), optional `token`,
31646
+ * `config.transferSpeed`, `depositAccount`, and `allowanceStrategy`.
31360
31647
  *
31361
31648
  * @example
31362
31649
  * ```typescript
@@ -31457,12 +31744,12 @@ const allowanceStrategySchema = zod.z.enum([
31457
31744
  */ function validateDepositTransferConfig(params) {
31458
31745
  const { from, to, config, quote, allowanceStrategy } = params;
31459
31746
  const transferSpeed = config?.transferSpeed ?? 'STANDARD';
31460
- if (to !== undefined && allowanceStrategy !== undefined) {
31461
- throw createValidationFailedError$1('allowanceStrategy', allowanceStrategy, 'cannot be set when to is provided; FAST deposits do not use an ' + 'allowance strategy');
31747
+ if (transferSpeed === 'FAST' && allowanceStrategy !== undefined) {
31748
+ throw createValidationFailedError$1('allowanceStrategy', allowanceStrategy, 'cannot be set for FAST cross-chain deposits');
31462
31749
  }
31463
31750
  if (transferSpeed === 'FAST') {
31464
31751
  if (to === undefined) {
31465
- throw createValidationFailedError$1('to', undefined, 'required when transferSpeed is FAST');
31752
+ throw createValidationFailedError$1('to', undefined, 'required when transferSpeed is FAST and no default destination ' + 'can be derived from from.chain');
31466
31753
  }
31467
31754
  const dstChain = resolveChainIdentifier(to.chain);
31468
31755
  if (!isGatewayFastDepositDestination(dstChain)) {
@@ -31521,8 +31808,9 @@ const allowanceStrategySchema = zod.z.enum([
31521
31808
  }
31522
31809
  /**
31523
31810
  * Run all validations required for estimateDeposit: from context, amount,
31524
- * required `to.chain`, optional token, config, depositAccount, and
31525
- * allowanceStrategy.
31811
+ * optional `to.chain`, optional token, config, depositAccount, and
31812
+ * allowanceStrategy. FAST params must already have the default destination
31813
+ * applied (see `applyDefaultFastDepositDestination`).
31526
31814
  *
31527
31815
  * @param params - The raw estimateDeposit params.
31528
31816
  * @returns Nothing; throws on invalid params.
@@ -31595,6 +31883,90 @@ const allowanceStrategySchema = zod.z.enum([
31595
31883
  }
31596
31884
  }
31597
31885
 
31886
+ /**
31887
+ * Default destination chain for FAST cross-chain deposits, keyed by the
31888
+ * network of the source chain. Used when `config.transferSpeed` is `'FAST'`
31889
+ * and `to` is omitted.
31890
+ */ const DEFAULT_FAST_DEPOSIT_DESTINATION = {
31891
+ mainnet: Blockchain.Arc,
31892
+ testnet: Blockchain.Arc_Testnet
31893
+ };
31894
+ /**
31895
+ * Resolve the destination chain for a deposit.
31896
+ *
31897
+ * Return `to` unchanged when it is set or when the transfer speed is not
31898
+ * `'FAST'`. Otherwise return the default FAST deposit destination for the
31899
+ * source chain's network — `Arc` for mainnet sources and `Arc_Testnet` for
31900
+ * testnet sources.
31901
+ *
31902
+ * @param params - Deposit params with `from`, optional `to`, and optional
31903
+ * `config`. `from.chain` must already be validated.
31904
+ * @returns The explicit or defaulted destination, or `undefined` for
31905
+ * STANDARD deposits.
31906
+ * @throws KitError If `from.chain` cannot be resolved.
31907
+ *
31908
+ * @example
31909
+ * ```typescript
31910
+ * const to = resolveFastDepositDestination({
31911
+ * from: { chain: 'Ethereum_Sepolia' },
31912
+ * config: { transferSpeed: 'FAST' },
31913
+ * })
31914
+ * // to → { chain: 'Arc_Testnet' }
31915
+ * ```
31916
+ */ function resolveFastDepositDestination(params) {
31917
+ const { from, to, config } = params;
31918
+ if (to !== undefined || config?.transferSpeed !== 'FAST') {
31919
+ return to;
31920
+ }
31921
+ const srcChain = resolveChainIdentifier(from.chain);
31922
+ return {
31923
+ chain: srcChain.isTestnet ? DEFAULT_FAST_DEPOSIT_DESTINATION.testnet : DEFAULT_FAST_DEPOSIT_DESTINATION.mainnet
31924
+ };
31925
+ }
31926
+ /**
31927
+ * Return deposit params with the default FAST deposit destination applied.
31928
+ *
31929
+ * Call this at the top of every deposit entry point, before validation, so
31930
+ * all downstream logic (validation, routing, telemetry, and the estimate
31931
+ * result) sees an explicit `to` for every FAST deposit.
31932
+ *
31933
+ * When {@link resolveFastDepositDestination} yields a destination and `to`
31934
+ * is not set, return a shallow copy with `to` filled in. Otherwise return
31935
+ * the params unchanged. Safe to call more than once.
31936
+ *
31937
+ * Runs before validation, so it never throws: when `from.chain` cannot be
31938
+ * resolved (or `params` is malformed plain-JS input) the params are returned
31939
+ * unchanged and schema validation reports the error.
31940
+ *
31941
+ * @typeParam T - The deposit, depositFor, or estimateDeposit params type.
31942
+ * @param params - Raw (unvalidated) deposit params.
31943
+ * @returns Params with `to` set for every resolvable FAST deposit.
31944
+ *
31945
+ * @example
31946
+ * ```typescript
31947
+ * const resolved = applyDefaultFastDepositDestination({
31948
+ * from: { adapter, chain: 'Base' },
31949
+ * amount: '10',
31950
+ * config: { transferSpeed: 'FAST' },
31951
+ * })
31952
+ * // resolved.to → { chain: 'Arc' }
31953
+ * ```
31954
+ */ function applyDefaultFastDepositDestination(params) {
31955
+ let to;
31956
+ try {
31957
+ to = resolveFastDepositDestination(params);
31958
+ } catch {
31959
+ // Unresolvable source chain — leave params as-is for validation to reject.
31960
+ return params;
31961
+ }
31962
+ if (to === undefined || to === params.to) {
31963
+ return params;
31964
+ }
31965
+ return {
31966
+ ...params,
31967
+ to
31968
+ };
31969
+ }
31598
31970
  async function resolveDepositParams(params) {
31599
31971
  const chain = resolveChainIdentifier(params.from.chain);
31600
31972
  params.from.adapter.validateChainSupport(chain);
@@ -31853,7 +32225,9 @@ function resolveGatewayExecutorContracts(srcChain, dstChain) {
31853
32225
  * covers the amount) → burn → relay wait.
31854
32226
  *
31855
32227
  * @param context - Kit context (used for analytics telemetry emissions).
31856
- * @param params - Deposit params (must have `to` set and `to.chain` differ from `from.chain`).
32228
+ * @param params - Deposit params with `to` set (explicitly or via
32229
+ * `applyDefaultFastDepositDestination`) and `to.chain` differing from
32230
+ * `from.chain`.
31857
32231
  * @param depositAccount - Destination Gateway account to credit. When omitted
31858
32232
  * (i.e. called from `deposit()`), the signer's own address is used.
31859
32233
  * @returns Settled deposit result after Circle's relay has confirmed the mint.
@@ -32114,7 +32488,8 @@ function resolveGatewayExecutorContracts(srcChain, dstChain) {
32114
32488
  * (token → `'USDC'`, allowanceStrategy → `'authorize'`), finds a provider,
32115
32489
  * and delegates to the provider's deposit operation.
32116
32490
  *
32117
- * For cross-chain (FAST) deposits (when `to` is set): fetches or validates a
32491
+ * For cross-chain (FAST) deposits (when `config.transferSpeed` is `'FAST'`;
32492
+ * `to` defaults to Arc / Arc_Testnet when omitted): fetches or validates a
32118
32493
  * fee quote, runs a preflight affordability check, submits the prepaid-FORWARD
32119
32494
  * burn on the source chain, and waits for Circle's relay to confirm the mint
32120
32495
  * on the destination. The caller's Gateway account is credited on the
@@ -32153,11 +32528,12 @@ function resolveGatewayExecutorContracts(srcChain, dstChain) {
32153
32528
  * const crossResult = await deposit(context, { ...estimate, from: { adapter, chain: 'Ethereum_Sepolia' } })
32154
32529
  * ```
32155
32530
  */ async function deposit(context, params) {
32156
- assertDepositParams(params);
32157
- if (params.to !== undefined) {
32158
- return depositFastCrossChain(context, params);
32531
+ const normalizedParams = applyDefaultFastDepositDestination(params);
32532
+ assertDepositParams(normalizedParams);
32533
+ if (normalizedParams.to !== undefined) {
32534
+ return depositFastCrossChain(context, normalizedParams);
32159
32535
  }
32160
- const resolvedParams = await resolveDepositParams(params);
32536
+ const resolvedParams = await resolveDepositParams(normalizedParams);
32161
32537
  const chain = resolvedParams.from.chain;
32162
32538
  if (!isGatewayV1Supported(chain)) {
32163
32539
  throw createUnsupportedRouteError(chain.name, chain.name);
@@ -32172,7 +32548,8 @@ function resolveGatewayExecutorContracts(srcChain, dstChain) {
32172
32548
  * (token → `'USDC'`, allowanceStrategy → `'approve'`), finds a provider,
32173
32549
  * and delegates to the provider's depositFor operation.
32174
32550
  *
32175
- * For cross-chain (FAST) deposits (when `to` is set): fetches or validates a
32551
+ * For cross-chain (FAST) deposits (when `config.transferSpeed` is `'FAST'`;
32552
+ * `to` defaults to Arc / Arc_Testnet when omitted): fetches or validates a
32176
32553
  * fee quote, runs a preflight affordability check, submits the prepaid-FORWARD
32177
32554
  * burn on the source chain, and waits for Circle's relay to confirm the mint.
32178
32555
  * The `depositAccount` is credited on the destination chain.
@@ -32216,11 +32593,12 @@ function resolveGatewayExecutorContracts(srcChain, dstChain) {
32216
32593
  * })
32217
32594
  * ```
32218
32595
  */ async function depositFor(context, params) {
32219
- assertDepositForParams(params);
32220
- if (params.to !== undefined) {
32221
- return depositFastCrossChain(context, params, params.depositAccount);
32596
+ const normalizedParams = applyDefaultFastDepositDestination(params);
32597
+ assertDepositForParams(normalizedParams);
32598
+ if (normalizedParams.to !== undefined) {
32599
+ return depositFastCrossChain(context, normalizedParams, normalizedParams.depositAccount);
32222
32600
  }
32223
- const resolvedParams = await resolveDepositParams(params);
32601
+ const resolvedParams = await resolveDepositParams(normalizedParams);
32224
32602
  const chain = resolvedParams.from.chain;
32225
32603
  if (!isGatewayV1Supported(chain)) {
32226
32604
  throw createUnsupportedRouteError(chain.name, chain.name);
@@ -32279,7 +32657,8 @@ async function estimateDepositImpl(context, params) {
32279
32657
  fee: depositTotalGasFee
32280
32658
  }, srcChain));
32281
32659
  } else {
32282
- // assertEstimateDepositParams guarantees params.to is set on the FAST path
32660
+ // applyDefaultFastDepositDestination + assertEstimateDepositParams
32661
+ // guarantee params.to is set on the FAST path
32283
32662
  const { to } = params;
32284
32663
  if (to === undefined) {
32285
32664
  /* v8 ignore next 6 -- assertEstimateDepositParams guarantees to is set on the FAST path */ throw createValidationFailedError$1('to', undefined, 'required for FAST transfers');
@@ -32430,7 +32809,8 @@ async function estimateDepositImpl(context, params) {
32430
32809
  *
32431
32810
  * @param context - Kit context (used for analytics telemetry emissions).
32432
32811
  * @param params - The estimate parameters: source context, amount, destination
32433
- * chain, optional token, transfer speed, and allowance strategy.
32812
+ * chain (defaults to Arc / Arc_Testnet for FAST), optional token, transfer
32813
+ * speed, and allowance strategy.
32434
32814
  * @returns Promise resolving to an itemized fee estimate with an optional
32435
32815
  * quote for FAST cross-chain transfers.
32436
32816
  * @throws KitError If the wallet address cannot be resolved — wallet not connected
@@ -32463,8 +32843,9 @@ async function estimateDepositImpl(context, params) {
32463
32843
  * const result = await deposit(context, { ...estimate, from: { adapter, chain: 'Ethereum_Sepolia' } })
32464
32844
  * ```
32465
32845
  */ async function estimateDeposit(context, params) {
32466
- assertEstimateDepositParams(params);
32467
- return estimateDepositImpl(context, params);
32846
+ const normalizedParams = applyDefaultFastDepositDestination(params);
32847
+ assertEstimateDepositParams(normalizedParams);
32848
+ return estimateDepositImpl(context, normalizedParams);
32468
32849
  }
32469
32850
 
32470
32851
  // The `as never` cast is required because `unifiedBalanceChainIdentifierSchema`
@@ -34038,6 +34419,10 @@ const removeFundParamsSchema = zod.z.object({
34038
34419
  * All three telemetry call sites use this helper to keep the classification
34039
34420
  * consistent.
34040
34421
  *
34422
+ * Callers must pass params that have been through
34423
+ * `applyDefaultFastDepositDestination`, which sets `to` to Arc / Arc_Testnet
34424
+ * for FAST deposits that omit it.
34425
+ *
34041
34426
  * @param params - Deposit or estimate-deposit params to inspect.
34042
34427
  * @returns `true` when the transfer is a FAST cross-chain deposit.
34043
34428
  */ function isFastDeposit(params) {
@@ -34177,21 +34562,22 @@ const removeFundParamsSchema = zod.z.object({
34177
34562
  *
34178
34563
  * @see UnifiedBalanceKit.depositFor to deposit into another account.
34179
34564
  */ async deposit(params) {
34180
- if (isFastDeposit(params)) {
34181
- return withErrorTelemetry(async ()=>deposit(this.context, params), EVENT_TYPES.FAST_DEPOSIT, this.telemetryConfig, {
34182
- sourceChain: resolveChainName(params.from?.chain),
34183
- destinationChain: resolveChainName(params.to?.chain),
34184
- tokenIn: params.token ?? 'USDC',
34185
- amountIn: Number.parseFloat(params.amount),
34186
- ...params.quote !== undefined && {
34187
- correlationId: hashSignedQuote(params.quote)
34565
+ const normalizedParams = applyDefaultFastDepositDestination(params);
34566
+ if (isFastDeposit(normalizedParams)) {
34567
+ return withErrorTelemetry(async ()=>deposit(this.context, normalizedParams), EVENT_TYPES.FAST_DEPOSIT, this.telemetryConfig, {
34568
+ sourceChain: resolveChainName(normalizedParams.from?.chain),
34569
+ destinationChain: resolveChainName(normalizedParams.to?.chain),
34570
+ tokenIn: normalizedParams.token ?? 'USDC',
34571
+ amountIn: Number.parseFloat(normalizedParams.amount),
34572
+ ...normalizedParams.quote !== undefined && {
34573
+ correlationId: hashSignedQuote(normalizedParams.quote)
34188
34574
  }
34189
34575
  });
34190
34576
  }
34191
- return withErrorTelemetry(async ()=>deposit(this.context, params), EVENT_TYPES.DEPOSIT, this.telemetryConfig, {
34192
- sourceChain: resolveChainName(params.from?.chain),
34193
- tokenIn: params.token ?? 'USDC',
34194
- amountIn: Number.parseFloat(params.amount)
34577
+ return withErrorTelemetry(async ()=>deposit(this.context, normalizedParams), EVENT_TYPES.DEPOSIT, this.telemetryConfig, {
34578
+ sourceChain: resolveChainName(normalizedParams.from?.chain),
34579
+ tokenIn: normalizedParams.token ?? 'USDC',
34580
+ amountIn: Number.parseFloat(normalizedParams.amount)
34195
34581
  });
34196
34582
  }
34197
34583
  /**
@@ -34203,24 +34589,25 @@ const removeFundParamsSchema = zod.z.object({
34203
34589
  *
34204
34590
  * @see UnifiedBalanceKit.deposit to deposit into your own account.
34205
34591
  */ async depositFor(params) {
34206
- if (isFastDeposit(params)) {
34592
+ const normalizedParams = applyDefaultFastDepositDestination(params);
34593
+ if (isFastDeposit(normalizedParams)) {
34207
34594
  // Fast depositFor shares FAST_DEPOSIT event type with fast deposit — the
34208
34595
  // success-path emitter in depositFastCrossChain uses a single event type
34209
34596
  // for both entry points, so error telemetry mirrors that here.
34210
- return withErrorTelemetry(async ()=>depositFor(this.context, params), EVENT_TYPES.FAST_DEPOSIT, this.telemetryConfig, {
34211
- sourceChain: resolveChainName(params.from?.chain),
34212
- destinationChain: resolveChainName(params.to?.chain),
34213
- tokenIn: params.token ?? 'USDC',
34214
- amountIn: Number.parseFloat(params.amount),
34215
- ...params.quote !== undefined && {
34216
- correlationId: hashSignedQuote(params.quote)
34597
+ return withErrorTelemetry(async ()=>depositFor(this.context, normalizedParams), EVENT_TYPES.FAST_DEPOSIT, this.telemetryConfig, {
34598
+ sourceChain: resolveChainName(normalizedParams.from?.chain),
34599
+ destinationChain: resolveChainName(normalizedParams.to?.chain),
34600
+ tokenIn: normalizedParams.token ?? 'USDC',
34601
+ amountIn: Number.parseFloat(normalizedParams.amount),
34602
+ ...normalizedParams.quote !== undefined && {
34603
+ correlationId: hashSignedQuote(normalizedParams.quote)
34217
34604
  }
34218
34605
  });
34219
34606
  }
34220
- return withErrorTelemetry(async ()=>depositFor(this.context, params), EVENT_TYPES.DEPOSIT_FOR, this.telemetryConfig, {
34221
- sourceChain: resolveChainName(params.from?.chain),
34222
- tokenIn: params.token ?? 'USDC',
34223
- amountIn: Number.parseFloat(params.amount)
34607
+ return withErrorTelemetry(async ()=>depositFor(this.context, normalizedParams), EVENT_TYPES.DEPOSIT_FOR, this.telemetryConfig, {
34608
+ sourceChain: resolveChainName(normalizedParams.from?.chain),
34609
+ tokenIn: normalizedParams.token ?? 'USDC',
34610
+ amountIn: Number.parseFloat(normalizedParams.amount)
34224
34611
  });
34225
34612
  }
34226
34613
  /**
@@ -34235,23 +34622,25 @@ const removeFundParamsSchema = zod.z.object({
34235
34622
  * ```
34236
34623
  *
34237
34624
  * @param params - The estimate parameters including source context, amount,
34238
- * destination chain, optional transfer speed, and optional allowance strategy.
34625
+ * destination chain (defaults to Arc / Arc_Testnet for FAST), optional
34626
+ * transfer speed, and optional allowance strategy.
34239
34627
  * @returns Promise resolving to an itemised fee breakdown.
34240
34628
  *
34241
34629
  * @see UnifiedBalanceKit.deposit to execute after estimating.
34242
34630
  */ async estimateDeposit(params) {
34243
- if (isFastDeposit(params)) {
34244
- return withErrorTelemetry(async ()=>estimateDeposit(this.context, params), EVENT_TYPES.ESTIMATE_FAST_DEPOSIT, this.telemetryConfig, {
34245
- sourceChain: resolveChainName(params.from?.chain),
34246
- destinationChain: resolveChainName(params.to?.chain),
34247
- tokenIn: params.token ?? 'USDC',
34248
- amountIn: Number.parseFloat(params.amount)
34631
+ const normalizedParams = applyDefaultFastDepositDestination(params);
34632
+ if (isFastDeposit(normalizedParams)) {
34633
+ return withErrorTelemetry(async ()=>estimateDeposit(this.context, normalizedParams), EVENT_TYPES.ESTIMATE_FAST_DEPOSIT, this.telemetryConfig, {
34634
+ sourceChain: resolveChainName(normalizedParams.from?.chain),
34635
+ destinationChain: resolveChainName(normalizedParams.to?.chain),
34636
+ tokenIn: normalizedParams.token ?? 'USDC',
34637
+ amountIn: Number.parseFloat(normalizedParams.amount)
34249
34638
  });
34250
34639
  }
34251
- return withErrorTelemetry(async ()=>estimateDeposit(this.context, params), EVENT_TYPES.ESTIMATE_DEPOSIT, this.telemetryConfig, {
34252
- sourceChain: resolveChainName(params.from?.chain),
34253
- tokenIn: params.token ?? 'USDC',
34254
- amountIn: Number.parseFloat(params.amount)
34640
+ return withErrorTelemetry(async ()=>estimateDeposit(this.context, normalizedParams), EVENT_TYPES.ESTIMATE_DEPOSIT, this.telemetryConfig, {
34641
+ sourceChain: resolveChainName(normalizedParams.from?.chain),
34642
+ tokenIn: normalizedParams.token ?? 'USDC',
34643
+ amountIn: Number.parseFloat(normalizedParams.amount)
34255
34644
  });
34256
34645
  }
34257
34646
  /**
@@ -34620,7 +35009,8 @@ registerKit(`${pkg$1.name}/${pkg$1.version}`);
34620
35009
  * {@link AppKitUnifiedBalance.depositFor}.
34621
35010
  *
34622
35011
  * @param params - Estimate details including the depositor context, amount,
34623
- * destination chain, and optional transfer speed.
35012
+ * destination chain (defaults to Arc / Arc_Testnet for FAST), and optional
35013
+ * transfer speed.
34624
35014
  * @returns Promise resolving to the itemised fee estimate.
34625
35015
  * @throws {KitError} If the estimate parameters are invalid or the route is
34626
35016
  * unsupported.