@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
@@ -1334,6 +1334,34 @@ let activeRedactor = defaultMessageRedactor;
1334
1334
  return redactErrorMessage(String(error));
1335
1335
  }
1336
1336
 
1337
+ /**
1338
+ * Render an object value for an error message without letting the rendering
1339
+ * itself throw.
1340
+ *
1341
+ * `JSON.stringify` rejects `BigInt` and circular structures, and a rejected
1342
+ * value is exactly the kind of thing a validation error is built from: an
1343
+ * on-chain read or a receipt log carries `bigint` fields, so serializing one
1344
+ * naively replaces the intended error with a `TypeError`.
1345
+ *
1346
+ * @param value - The value to render.
1347
+ * @returns A JSON string with `bigint` fields stringified, or
1348
+ * `'[unserializable object]'` if serialization still fails.
1349
+ * @throws Never; serialization failures are caught and rendered as a fallback string.
1350
+ * @example
1351
+ * ```typescript
1352
+ * import { describeObjectValue } from '@core/errors'
1353
+ *
1354
+ * describeObjectValue({ amount: 1n })
1355
+ * // '{"amount":"1"}'
1356
+ * ```
1357
+ */ function describeObjectValue(value) {
1358
+ try {
1359
+ return JSON.stringify(value, (_key, entry)=>typeof entry === 'bigint' ? entry.toString() : entry);
1360
+ } catch {
1361
+ return '[unserializable object]';
1362
+ }
1363
+ }
1364
+
1337
1365
  /**
1338
1366
  * Creates error for network type mismatch between source and destination.
1339
1367
  *
@@ -1562,7 +1590,7 @@ let activeRedactor = defaultMessageRedactor;
1562
1590
  * // Message: "Validation failed for 'chainId': 999 - Unsupported chain ID"
1563
1591
  *
1564
1592
  * throw createValidationFailedError('config', { invalid: true }, 'Missing required properties')
1565
- * // Message: "Validation failed for 'config': [object Object] - Missing required properties"
1593
+ * // Message: "Validation failed for 'config': {"invalid":true} - Missing required properties"
1566
1594
  * ```
1567
1595
  */ function createValidationFailedError$1(field, value, reason) {
1568
1596
  // Convert value to string for display, handling different types appropriately
@@ -1570,7 +1598,7 @@ let activeRedactor = defaultMessageRedactor;
1570
1598
  if (typeof value === 'string') {
1571
1599
  valueString = `'${value}'`;
1572
1600
  } else if (typeof value === 'object' && value !== null) {
1573
- valueString = JSON.stringify(value);
1601
+ valueString = describeObjectValue(value);
1574
1602
  } else {
1575
1603
  valueString = String(value);
1576
1604
  }
@@ -2376,22 +2404,73 @@ let activeRedactor = defaultMessageRedactor;
2376
2404
  '0x9147d463': 'Final balance is less than the initial balance',
2377
2405
  '0xf4b3b1bc': 'Native token transfer to the beneficiary failed'
2378
2406
  };
2407
+ /**
2408
+ * Matches revert data: a 4-byte selector followed by whole ABI-encoded bytes.
2409
+ */ const REVERT_DATA_PATTERN = /^0x[0-9a-f]{8}(?:[0-9a-f]{2})*$/i;
2410
+ /**
2411
+ * Returns the revert data held by one error in a `cause` chain.
2412
+ *
2413
+ * Browser wallets (EIP-1193) wrap the node's error, so the revert data sits
2414
+ * one level down as `data.data`. viem's `getContractError` reads it the same
2415
+ * way, then keeps it on `ContractFunctionRevertedError.raw` and drops the
2416
+ * node's error from the chain.
2417
+ *
2418
+ * @param link - One error in the `cause` chain
2419
+ * @returns The `raw` or `data` string, or undefined if there is none
2420
+ */ function getRevertData(link) {
2421
+ if ('raw' in link && typeof link.raw === 'string' && REVERT_DATA_PATTERN.test(link.raw)) {
2422
+ return link.raw;
2423
+ }
2424
+ if (!('data' in link)) {
2425
+ return undefined;
2426
+ }
2427
+ const { data } = link;
2428
+ if (typeof data === 'string') {
2429
+ return data;
2430
+ }
2431
+ if (data !== null && typeof data === 'object' && 'data' in data && typeof data.data === 'string') {
2432
+ return data.data;
2433
+ }
2434
+ return undefined;
2435
+ }
2436
+ /**
2437
+ * Finds the first revert data on the error or in its `cause` chain that
2438
+ * `accept` takes.
2439
+ *
2440
+ * viem keeps the node's revert data on an inner `RpcRequestError`, not on
2441
+ * the error it throws. The `seen` set stops a self-referencing `cause` chain.
2442
+ *
2443
+ * @param error - The error object
2444
+ * @param accept - Returns true for the data shape the caller wants
2445
+ * @returns The data as written on the error, or undefined if not found
2446
+ */ function findRevertData(error, accept) {
2447
+ const seen = new Set();
2448
+ let current = error;
2449
+ while(current !== null && typeof current === 'object' && !seen.has(current)){
2450
+ seen.add(current);
2451
+ const data = getRevertData(current);
2452
+ if (data !== undefined && accept(data)) {
2453
+ return data;
2454
+ }
2455
+ current = 'cause' in current ? current.cause : undefined;
2456
+ }
2457
+ return undefined;
2458
+ }
2379
2459
  /**
2380
2460
  * Attempts to extract an error selector from an error object or message.
2381
2461
  *
2382
2462
  * Checks multiple sources in priority order:
2383
- * 1. `error.data` field
2463
+ * 1. `raw` or `data` field (or nested `data.data`) on the error or anywhere
2464
+ * in its `cause` chain
2384
2465
  * 2. Message pattern: "custom error 0x8baa579f"
2385
2466
  *
2386
2467
  * @param msg - The error message
2387
2468
  * @param error - The error object (optional)
2388
2469
  * @returns The 4 bytes selector , or undefined if not found
2389
2470
  */ function extractErrorSelector(msg, error) {
2390
- // Check error.data field
2391
- if (error !== null && typeof error === 'object' && 'data' in error) {
2392
- if (typeof error.data === 'string' && /^0x[0-9a-f]{8}$/i.test(error.data)) {
2393
- return error.data.toLowerCase();
2394
- }
2471
+ const data = findRevertData(error, (value)=>/^0x[0-9a-f]{8}$/i.test(value));
2472
+ if (data !== undefined) {
2473
+ return data.toLowerCase();
2395
2474
  }
2396
2475
  // Check for "custom error 0x8baa579f" in the message
2397
2476
  const match = /custom error (0x[0-9a-f]{8})\b/i.exec(msg);
@@ -2969,6 +3048,105 @@ let activeRedactor = defaultMessageRedactor;
2969
3048
  return chain;
2970
3049
  }
2971
3050
 
3051
+ /**
3052
+ * Extracts the HTTP status code from an error message.
3053
+ *
3054
+ * Attempts to parse HTTP status codes from common error message formats,
3055
+ * such as "HTTP 404" or "Status: 500".
3056
+ *
3057
+ * Shared by `parseApiError` and the backend-error-code parsers that route on
3058
+ * status when no backend code is available, so all of them recognise the same
3059
+ * message shapes.
3060
+ *
3061
+ * @param msg - The error message to extract from
3062
+ * @returns The extracted HTTP status code, or null if not found
3063
+ *
3064
+ * @example
3065
+ * ```typescript
3066
+ * const code = extractHttpStatusCode('HTTP 404')
3067
+ * // Returns: 404
3068
+ * ```
3069
+ *
3070
+ * @example
3071
+ * ```typescript
3072
+ * const code = extractHttpStatusCode('Status: 500 Internal Server Error')
3073
+ * // Returns: 500
3074
+ * ```
3075
+ *
3076
+ * @internal
3077
+ */ function extractHttpStatusCode(msg) {
3078
+ // Pattern: "HTTP 404" or "HTTP 404 - some message" or "Status: 404"
3079
+ const patterns = [
3080
+ /HTTP (\d{3})/i,
3081
+ /Status:\s*(\d{3})/i,
3082
+ /^(\d{3}) -/
3083
+ ];
3084
+ for (const pattern of patterns){
3085
+ const match = pattern.exec(msg);
3086
+ const codeStr = match?.at(1);
3087
+ if (codeStr !== undefined) {
3088
+ const code = Number.parseInt(codeStr, 10);
3089
+ // Validate it's a valid HTTP status code
3090
+ if (code >= 100 && code < 600) {
3091
+ return code;
3092
+ }
3093
+ }
3094
+ }
3095
+ return null;
3096
+ }
3097
+
3098
+ /**
3099
+ * Type guard that narrows an unknown error to one carrying a non-null
3100
+ * object `responseBody` property (attached by `makeApiRequest`).
3101
+ *
3102
+ * Shared by backend-error-code parsers (`parseEarnApiError`,
3103
+ * `parseBorrowApiError`) so the narrowing logic lives in one place.
3104
+ *
3105
+ * @param error - The raw error from the HTTP layer
3106
+ * @returns `true` when `error.responseBody` is a non-null object
3107
+ * @internal
3108
+ */ function hasResponseBody(error) {
3109
+ return typeof error === 'object' && error !== null && 'responseBody' in error && typeof error['responseBody'] === 'object' && error['responseBody'] !== null;
3110
+ }
3111
+ /**
3112
+ * Narrow an unknown value to a non-null object.
3113
+ *
3114
+ * @param value - The value to check
3115
+ * @returns `true` when `value` is a non-null object
3116
+ * @internal
3117
+ */ function isRecord(value) {
3118
+ return typeof value === 'object' && value !== null;
3119
+ }
3120
+ /**
3121
+ * Read the machine-readable error fields (`code`, `message`,
3122
+ * `externalMessage`) that a Circle service attaches to an HTTP error body.
3123
+ *
3124
+ * `platform-common-go` serializes app-thrown errors under a nested envelope —
3125
+ * `{ response: { status: { code, message, externalMessage } } }` — for every
3126
+ * HTTP status, so this returns that inner `response.status` object when
3127
+ * present. It otherwise falls back to the top-level body so a flattened shape
3128
+ * (e.g. the stablecoin-kits-proxy) is still read. Callers read
3129
+ * `code` / `message` / `externalMessage` off the returned object uniformly.
3130
+ *
3131
+ * @param error - The raw error from the HTTP layer
3132
+ * @returns The error-status fields, or `undefined` when the error carries no
3133
+ * response body
3134
+ * @internal
3135
+ */ function extractResponseBody$1(error) {
3136
+ if (!hasResponseBody(error)) {
3137
+ return undefined;
3138
+ }
3139
+ const body = error.responseBody;
3140
+ const response = body['response'];
3141
+ if (isRecord(response)) {
3142
+ const status = response['status'];
3143
+ if (isRecord(status)) {
3144
+ return status;
3145
+ }
3146
+ }
3147
+ return body;
3148
+ }
3149
+
2972
3150
  /**
2973
3151
  * Proxy-specific structured error codes carried in `responseBody.code`.
2974
3152
  *
@@ -3269,29 +3447,22 @@ let activeRedactor = defaultMessageRedactor;
3269
3447
  });
3270
3448
  }
3271
3449
  /**
3272
- * Type guard that narrows an unknown error to one carrying a non-null
3273
- * object `responseBody` property (attached by `makeApiRequest`).
3450
+ * Extract the machine-readable error fields that `makeApiRequest` attaches to
3451
+ * HTTP error instances.
3274
3452
  *
3275
- * @param error - The raw error from the HTTP layer
3276
- * @returns `true` when `error.responseBody` is a non-null object
3277
- * @internal
3278
- */ function hasResponseBody(error) {
3279
- return typeof error === 'object' && error !== null && 'responseBody' in error && typeof error['responseBody'] === 'object' && error['responseBody'] !== null;
3280
- }
3281
- /**
3282
- * Extract the `responseBody` property that `makeApiRequest` attaches to
3283
- * HTTP error instances when the server returns a JSON body.
3453
+ * Delegates to the shared extractor so this fall-through path reads the same
3454
+ * shape as the backend-code parsers: it unwraps the nested
3455
+ * `{ response: { status } }` envelope when present, otherwise returns the
3456
+ * top-level body. Routing both halves through one extractor keeps an
3457
+ * unmapped-code error from losing the server's `externalMessage`.
3284
3458
  *
3285
3459
  * @param error - The raw error from the HTTP layer
3286
- * @returns The parsed body cast to {@link ApiErrorResponseBody}, or undefined
3460
+ * @returns The parsed body as {@link ApiErrorResponseBody}, or undefined
3287
3461
  * @throws Never. Returns `undefined` when the error does not carry a valid
3288
3462
  * `responseBody`.
3289
3463
  * @internal
3290
3464
  */ function extractResponseBody(error) {
3291
- if (!hasResponseBody(error)) {
3292
- return undefined;
3293
- }
3294
- return error.responseBody;
3465
+ return extractResponseBody$1(error);
3295
3466
  }
3296
3467
  /**
3297
3468
  * Extract a field name from an {@link ApiFieldError}.
@@ -3400,46 +3571,6 @@ let activeRedactor = defaultMessageRedactor;
3400
3571
  }
3401
3572
  return topMessage ?? fieldDetail;
3402
3573
  }
3403
- /**
3404
- * Extracts the HTTP status code from an error message.
3405
- *
3406
- * Attempts to parse HTTP status codes from common error message formats,
3407
- * such as "HTTP 404" or "Status: 500".
3408
- *
3409
- * @param msg - The error message to extract from
3410
- * @returns The extracted HTTP status code, or null if not found
3411
- *
3412
- * @example
3413
- * ```typescript
3414
- * const code = extractHttpStatusCode('HTTP 404')
3415
- * // Returns: 404
3416
- * ```
3417
- *
3418
- * @example
3419
- * ```typescript
3420
- * const code = extractHttpStatusCode('Status: 500 Internal Server Error')
3421
- * // Returns: 500
3422
- * ```
3423
- */ function extractHttpStatusCode(msg) {
3424
- // Pattern: "HTTP 404" or "HTTP 404 - some message" or "Status: 404"
3425
- const patterns = [
3426
- /HTTP (\d{3})/i,
3427
- /Status:\s*(\d{3})/i,
3428
- /^(\d{3}) -/
3429
- ];
3430
- for (const pattern of patterns){
3431
- const match = pattern.exec(msg);
3432
- const codeStr = match?.at(1);
3433
- if (codeStr !== undefined) {
3434
- const code = Number.parseInt(codeStr, 10);
3435
- // Validate it's a valid HTTP status code
3436
- if (code >= 100 && code < 600) {
3437
- return code;
3438
- }
3439
- }
3440
- }
3441
- return null;
3442
- }
3443
3574
 
3444
3575
  /**
3445
3576
  * @packageDocumentation
@@ -3564,6 +3695,8 @@ var SwapChain;
3564
3695
  SwapChain["HyperEVM"] = "HyperEVM";
3565
3696
  SwapChain["Monad"] = "Monad";
3566
3697
  SwapChain["Arc"] = "Arc";
3698
+ SwapChain["Cronos"] = "Cronos";
3699
+ SwapChain["Morph"] = "Morph";
3567
3700
  // Testnet chains with swap support
3568
3701
  SwapChain["Arc_Testnet"] = "Arc_Testnet";
3569
3702
  })(SwapChain || (SwapChain = {}));
@@ -3695,6 +3828,11 @@ var EarnChain;
3695
3828
  "Arc",
3696
3829
  "Arc_Testnet"
3697
3830
  ];
3831
+ var BorrowChain;
3832
+ (function(BorrowChain) {
3833
+ BorrowChain["Arc"] = "Arc";
3834
+ BorrowChain["Arc_Testnet"] = "Arc_Testnet";
3835
+ })(BorrowChain || (BorrowChain = {}));
3698
3836
 
3699
3837
  /**
3700
3838
  * Helper function to define a chain with proper TypeScript typing.
@@ -4037,6 +4175,29 @@ var EarnChain;
4037
4175
  * on EVM-compatible testnet chains. Use this address for testnet adapter
4038
4176
  * integrations (e.g., Arc Testnet).
4039
4177
  */ const ADAPTER_CONTRACT_EVM_TESTNET = '0xBBD70b01a1CAbc96d5b7b129Ae1AAabdf50dd40b';
4178
+ /**
4179
+ * The sender-preserving batching contract on Arc (`Multicall3From`).
4180
+ *
4181
+ * This predeploy batches calls like the ubiquitous Multicall3, but routes each
4182
+ * subcall through Arc's `CallFrom` precompile
4183
+ * (`0x1800000000000000000000000000000000000003`), which executes on behalf of
4184
+ * the transaction's original sender. Every target therefore sees the calling
4185
+ * EOA as `msg.sender`, which is what makes a plain, un-upgraded EOA capable of
4186
+ * an atomic batch on Arc.
4187
+ *
4188
+ * Deployed at the same address on Arc Testnet and Arc Mainnet.
4189
+ *
4190
+ * @see https://docs.arc.io/arc/concepts/batched-transactions
4191
+ */ const BATCHER_CONTRACT_ARC_TESTNET = '0x522fAf9A91c41c443c66765030741e4AaCe147D0';
4192
+ /**
4193
+ * The sender-preserving batching contract on Arc Mainnet (`Multicall3From`).
4194
+ *
4195
+ * See {@link BATCHER_CONTRACT_ARC_TESTNET} for how this contract works.
4196
+ * Requires Arc's Zero7 hardfork, which activates the `CallFrom` precompile
4197
+ * this contract depends on.
4198
+ *
4199
+ * @see https://docs.arc.io/arc/concepts/batched-transactions
4200
+ */ const BATCHER_CONTRACT_ARC_MAINNET = '0x522fAf9A91c41c443c66765030741e4AaCe147D0';
4040
4201
  /**
4041
4202
  * The GatewayWallet contract address for EVM mainnet networks.
4042
4203
  *
@@ -4186,7 +4347,10 @@ var EarnChain;
4186
4347
  },
4187
4348
  kitContracts: {
4188
4349
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
4189
- adapter: ADAPTER_CONTRACT_EVM_MAINNET
4350
+ adapter: ADAPTER_CONTRACT_EVM_MAINNET,
4351
+ // Arc is the only chain with a sender-preserving batcher, because it
4352
+ // takes a precompile rather than an ordinary contract to build one.
4353
+ senderPreservingBatcher: BATCHER_CONTRACT_ARC_MAINNET
4190
4354
  },
4191
4355
  gateway: {
4192
4356
  domain: 26,
@@ -4257,7 +4421,10 @@ var EarnChain;
4257
4421
  },
4258
4422
  kitContracts: {
4259
4423
  bridge: BRIDGE_CONTRACT_EVM_TESTNET,
4260
- adapter: ADAPTER_CONTRACT_EVM_TESTNET
4424
+ adapter: ADAPTER_CONTRACT_EVM_TESTNET,
4425
+ // Arc is the only chain with a sender-preserving batcher, because it
4426
+ // takes a precompile rather than an ordinary contract to build one.
4427
+ senderPreservingBatcher: BATCHER_CONTRACT_ARC_TESTNET
4261
4428
  },
4262
4429
  gateway: {
4263
4430
  domain: 26,
@@ -4872,7 +5039,8 @@ var EarnChain;
4872
5039
  }
4873
5040
  },
4874
5041
  kitContracts: {
4875
- bridge: BRIDGE_CONTRACT_EVM_MAINNET
5042
+ bridge: BRIDGE_CONTRACT_EVM_MAINNET,
5043
+ adapter: ADAPTER_CONTRACT_EVM_MAINNET
4876
5044
  }
4877
5045
  });
4878
5046
 
@@ -5741,7 +5909,8 @@ var EarnChain;
5741
5909
  }
5742
5910
  },
5743
5911
  kitContracts: {
5744
- bridge: BRIDGE_CONTRACT_EVM_MAINNET
5912
+ bridge: BRIDGE_CONTRACT_EVM_MAINNET,
5913
+ adapter: ADAPTER_CONTRACT_EVM_MAINNET
5745
5914
  }
5746
5915
  });
5747
5916
 
@@ -7932,7 +8101,8 @@ var Chains = /*#__PURE__*/Object.freeze({
7932
8101
  cctpx: z.any().optional(),
7933
8102
  kitContracts: z.object({
7934
8103
  bridge: z.string().optional(),
7935
- adapter: z.string().optional()
8104
+ adapter: z.string().optional(),
8105
+ senderPreservingBatcher: z.string().optional()
7936
8106
  }).optional(),
7937
8107
  gateway: gatewayConfigSchema.optional()
7938
8108
  });
@@ -8043,8 +8213,8 @@ var Chains = /*#__PURE__*/Object.freeze({
8043
8213
  * Zod schema for validating swap-specific chain identifiers.
8044
8214
  *
8045
8215
  * Validates chains based on:
8046
- * - CCTPv2 support (adapter contract deployed)
8047
- * - Mainnet only (no testnets)
8216
+ * - Membership in the SwapChain enum
8217
+ * - Mainnet or explicitly allowlisted testnet
8048
8218
  * - At least one supported token available
8049
8219
  *
8050
8220
  */ z.union([
@@ -8128,6 +8298,38 @@ var Chains = /*#__PURE__*/Object.freeze({
8128
8298
  message: `"${chain.chain}" is not a supported earn chain. ` + `Supported chains: ${Object.values(EarnChain).join(', ')}`
8129
8299
  }))
8130
8300
  ]);
8301
+ /**
8302
+ * Zod schema for validating Borrow-specific chain identifiers.
8303
+ *
8304
+ * Validate that the provided chain is supported for Borrow Kit's loan
8305
+ * operations. Unlike {@link earnChainIdentifierSchema}, this includes Arc
8306
+ * mainnet as well as Arc Testnet.
8307
+ *
8308
+ * Accept a BorrowChain enum value, a matching string literal, or a
8309
+ * ChainDefinition for a supported chain.
8310
+ *
8311
+ * @example
8312
+ * ```typescript
8313
+ * import { borrowChainIdentifierSchema } from '@core/chains'
8314
+ * import { Arc, BorrowChain } from '@core/chains'
8315
+ *
8316
+ * // Valid
8317
+ * borrowChainIdentifierSchema.parse(BorrowChain.Arc)
8318
+ * borrowChainIdentifierSchema.parse('Arc')
8319
+ * borrowChainIdentifierSchema.parse(Arc)
8320
+ *
8321
+ * // Invalid (throws ZodError)
8322
+ * borrowChainIdentifierSchema.parse('Solana')
8323
+ * ```
8324
+ */ z.union([
8325
+ z.string().refine((val)=>val in BorrowChain, (val)=>({
8326
+ message: `"${val}" is not a supported borrow chain. ` + `Supported chains: ${Object.values(BorrowChain).join(', ')}`
8327
+ })),
8328
+ z.nativeEnum(BorrowChain),
8329
+ chainDefinitionSchema$2.refine((chain)=>chain.chain in BorrowChain, (chain)=>({
8330
+ message: `"${chain.chain}" is not a supported borrow chain. ` + `Supported chains: ${Object.values(BorrowChain).join(', ')}`
8331
+ }))
8332
+ ]);
8131
8333
  // Widened views so `.includes()` accepts arbitrary strings under strict TS.
8132
8334
  const EARN_BRIDGE_SOURCE_CHAIN_VALUES = EARN_BRIDGE_SOURCE_BLOCKCHAINS;
8133
8335
  const EARN_BRIDGE_DESTINATION_CHAIN_VALUES = EARN_BRIDGE_DESTINATION_BLOCKCHAINS;
@@ -8382,8 +8584,13 @@ const swapTokenEnumSchema = z.enum([
8382
8584
  */ function resolveChainName(value) {
8383
8585
  if (value == null) return undefined;
8384
8586
  if (typeof value === 'string') return value;
8385
- if (typeof value === 'object' && 'chain' in value && typeof value.chain === 'string') {
8386
- return value.chain;
8587
+ try {
8588
+ if (typeof value === 'object' && 'chain' in value) {
8589
+ const chain = value.chain;
8590
+ if (typeof chain === 'string') return chain;
8591
+ }
8592
+ } catch {
8593
+ return undefined;
8387
8594
  }
8388
8595
  return undefined;
8389
8596
  }
@@ -8992,6 +9199,7 @@ const swapTokenEnumSchema = z.enum([
8992
9199
  * - Retries on rate limiting (429)
8993
9200
  * - Does not retry on client errors (4xx, except 429)
8994
9201
  * - Does not retry on validation failures
9202
+ * - Does not retry when `config.isTerminalError` marks the error terminal
8995
9203
  *
8996
9204
  * Each HTTP request is given a configurable timeout before it is aborted.
8997
9205
  * Between retry attempts the wait depends on the `backoff` strategy. The
@@ -9071,7 +9279,10 @@ const swapTokenEnumSchema = z.enum([
9071
9279
  return await makeApiRequest(url, method, isValidType, effectiveConfig, body);
9072
9280
  } catch (err) {
9073
9281
  const error = err instanceof Error ? err : new Error(String(err));
9074
- if (!isRetryableError(error)) {
9282
+ // A caller-supplied predicate can mark an error terminal (e.g. a
9283
+ // deterministic 404) so it is surfaced immediately instead of burning
9284
+ // the retry budget on a non-transient answer.
9285
+ if (effectiveConfig.isTerminalError?.(error) === true || !isRetryableError(error)) {
9075
9286
  throw error;
9076
9287
  }
9077
9288
  lastError = error;
@@ -9155,7 +9366,24 @@ const swapTokenEnumSchema = z.enum([
9155
9366
  * // After this call, TypeScript knows params is of type BridgeParams
9156
9367
  * ```
9157
9368
  */ function validate(value, schema, context) {
9158
- const result = schema.safeParse(value);
9369
+ let result;
9370
+ try {
9371
+ result = schema.safeParse(value);
9372
+ } catch (error) {
9373
+ throw new KitError({
9374
+ ...InputError.VALIDATION_FAILED,
9375
+ recoverability: 'FATAL',
9376
+ message: `Invalid ${context}: reading a property threw`,
9377
+ cause: {
9378
+ trace: {
9379
+ validationErrors: [
9380
+ 'Reading a property of the value threw'
9381
+ ],
9382
+ originalError: error
9383
+ }
9384
+ }
9385
+ });
9386
+ }
9159
9387
  if (!result.success) {
9160
9388
  throw createValidationErrorFromZod(result.error, context);
9161
9389
  }
@@ -9883,11 +10111,13 @@ function parseOrThrow(value, schema, context) {
9883
10111
  [Blockchain.Arbitrum]: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9',
9884
10112
  [Blockchain.Avalanche]: '0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7',
9885
10113
  [Blockchain.Celo]: '0x48065fbBE25f71C9282ddf5e1cD6D6A887483D5e',
10114
+ [Blockchain.Cronos]: '0x66e428c3f67a68878562e79A0234c1F83c208770',
9886
10115
  [Blockchain.Ethereum]: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
9887
10116
  [Blockchain.HyperEVM]: '0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb',
9888
10117
  [Blockchain.Ink]: '0x0200C29006150606B650577BBE7B6248F58470c1',
9889
10118
  [Blockchain.Linea]: '0xA219439258ca9da29E9Cc4cE5596924745e12B93',
9890
10119
  [Blockchain.Monad]: '0xe7cd86e13AC4309349F30B3435a9d337750fC82D',
10120
+ [Blockchain.Morph]: '0xe7cd86e13AC4309349F30B3435a9d337750fC82D',
9891
10121
  [Blockchain.NEAR]: 'usdt.tether-token.near',
9892
10122
  [Blockchain.Optimism]: '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58',
9893
10123
  [Blockchain.Polkadot_Asset_Hub]: '1984',
@@ -9946,6 +10176,7 @@ function parseOrThrow(value, schema, context) {
9946
10176
  [Blockchain.Arbitrum]: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1',
9947
10177
  [Blockchain.Avalanche]: '0xd586E7F844cEa2F87f50152665BCbc2C279D8d70',
9948
10178
  [Blockchain.Base]: '0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb',
10179
+ [Blockchain.Cronos]: '0xF2001B145b43032AAF5Ee2884e456CCd805F677D',
9949
10180
  [Blockchain.Ethereum]: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
9950
10181
  [Blockchain.Linea]: '0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5',
9951
10182
  [Blockchain.Optimism]: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1',
@@ -10008,7 +10239,9 @@ function parseOrThrow(value, schema, context) {
10008
10239
  [Blockchain.Arbitrum]: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1',
10009
10240
  [Blockchain.Avalanche]: '0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB',
10010
10241
  [Blockchain.Base]: '0x4200000000000000000000000000000000000006',
10242
+ [Blockchain.Cronos]: '0xe44Fd7fCb2b1581822D0c862B68222998a0c299a',
10011
10243
  [Blockchain.Ethereum]: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
10244
+ [Blockchain.Morph]: '0x5300000000000000000000000000000000000011',
10012
10245
  [Blockchain.Optimism]: '0x4200000000000000000000000000000000000006',
10013
10246
  [Blockchain.Polygon]: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619',
10014
10247
  [Blockchain.Solana]: '7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs'
@@ -10027,6 +10260,7 @@ function parseOrThrow(value, schema, context) {
10027
10260
  locators: {
10028
10261
  [Blockchain.Ethereum]: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
10029
10262
  [Blockchain.Arbitrum]: '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f',
10263
+ [Blockchain.Cronos]: '0x062E66477Faf219F25D27dCED647BF57C3107d52',
10030
10264
  [Blockchain.Avalanche]: '0x50b7545627a5162F82A992c33b87aDc75187B218'
10031
10265
  }
10032
10266
  };
@@ -11717,7 +11951,7 @@ function resolveOptions(options) {
11717
11951
  }
11718
11952
 
11719
11953
  var name = "@circle-fin/unified-balance-kit";
11720
- var version$1 = "1.7.0";
11954
+ var version$1 = "1.8.1";
11721
11955
  var pkg$1 = {
11722
11956
  name: name,
11723
11957
  version: version$1};
@@ -12426,6 +12660,12 @@ const READ_ACTION_KEY_SET = new Set(READ_ACTION_KEYS);
12426
12660
  /** EIP-2612 standard permit */ PermitType[PermitType["EIP2612"] = 1] = "EIP2612";
12427
12661
  })(PermitType || (PermitType = {}));
12428
12662
 
12663
+ var BorrowPermitType;
12664
+ (function(BorrowPermitType) {
12665
+ /** Tokens must be approved separately. */ BorrowPermitType[BorrowPermitType["NONE"] = 0] = "NONE";
12666
+ /** EIP-2612 permit calldata accompanies the token input. */ BorrowPermitType[BorrowPermitType["EIP2612"] = 1] = "EIP2612";
12667
+ })(BorrowPermitType || (BorrowPermitType = {}));
12668
+
12429
12669
  /**
12430
12670
  * Default clock implementation.
12431
12671
  *
@@ -17193,7 +17433,7 @@ const abiParameterSchema = z.object({
17193
17433
  * const result = evmPreparedChainRequestParamsSchema.safeParse(params)
17194
17434
  * ```
17195
17435
  */ z.object({
17196
- type: z.literal('evm'),
17436
+ type: z.literal('evm').optional(),
17197
17437
  abi: abiSchema,
17198
17438
  address: evmAddressSchema$1,
17199
17439
  functionName: z.string({
@@ -18494,7 +18734,7 @@ function groupKey(alloc) {
18494
18734
  }
18495
18735
  }
18496
18736
 
18497
- const hexBytesSchema = z.string().regex(/^0x([0-9a-fA-F]{2})*$/, {
18737
+ const hexBytesSchema$1 = z.string().regex(/^0x([0-9a-fA-F]{2})*$/, {
18498
18738
  message: 'value must be a 0x-prefixed even-length hex string'
18499
18739
  }).transform((value)=>value);
18500
18740
  z.object({
@@ -18506,6 +18746,53 @@ z.object({
18506
18746
  amount: z.bigint().refine((value)=>value >= 0n, {
18507
18747
  message: 'amount must be a non-negative bigint'
18508
18748
  }),
18749
+ permitCalldata: hexBytesSchema$1
18750
+ }))
18751
+ }).passthrough();
18752
+
18753
+ const hexBytesSchema = z.string().regex(/^0x([0-9a-fA-F]{2})*$/, {
18754
+ message: 'value must be a 0x-prefixed even-length hex string'
18755
+ }).transform((value)=>value);
18756
+ function isNonNegativeBigIntLike(value) {
18757
+ try {
18758
+ return BigInt(value) >= 0n;
18759
+ } catch {
18760
+ return false;
18761
+ }
18762
+ }
18763
+ const uint256LikeSchema = z.union([
18764
+ z.string(),
18765
+ z.bigint()
18766
+ ]).refine(isNonNegativeBigIntLike, {
18767
+ message: 'value must be a non-negative bigint-compatible string or bigint'
18768
+ });
18769
+ const borrowExecutionParamsSchema = z.object({
18770
+ instructions: z.array(z.object({
18771
+ target: evmAddressSchema$1,
18772
+ data: hexBytesSchema,
18773
+ value: uint256LikeSchema,
18774
+ tokenIn: evmAddressSchema$1,
18775
+ amountToApprove: uint256LikeSchema,
18776
+ tokenOut: evmAddressSchema$1,
18777
+ minTokenOut: uint256LikeSchema
18778
+ }).passthrough()).min(1),
18779
+ tokens: z.array(z.object({
18780
+ token: evmAddressSchema$1,
18781
+ beneficiary: evmAddressSchema$1
18782
+ }).passthrough()),
18783
+ execId: uint256LikeSchema,
18784
+ deadline: uint256LikeSchema,
18785
+ metadata: hexBytesSchema
18786
+ }).passthrough();
18787
+ z.object({
18788
+ executeParams: borrowExecutionParamsSchema,
18789
+ signature: evmSignatureSchema,
18790
+ tokenInputs: z.array(z.object({
18791
+ permitType: z.nativeEnum(BorrowPermitType),
18792
+ token: evmAddressSchema$1,
18793
+ amount: z.bigint().refine((value)=>value >= 0n, {
18794
+ message: 'amount must be a non-negative bigint'
18795
+ }),
18509
18796
  permitCalldata: hexBytesSchema
18510
18797
  }))
18511
18798
  }).passthrough();
@@ -29011,7 +29298,7 @@ const mockAttestationMessage = {
29011
29298
  return step;
29012
29299
  }
29013
29300
 
29014
- var version = "1.14.0";
29301
+ var version = "1.14.2";
29015
29302
  var pkg = {
29016
29303
  version: version};
29017
29304
 
@@ -31347,9 +31634,9 @@ const allowanceStrategySchema = z.enum([
31347
31634
  /**
31348
31635
  * Schema for validating estimateDeposit parameters.
31349
31636
  *
31350
- * Validates `from` (adapter + chain), `amount`, required `to.chain`,
31351
- * optional `token`, `config.transferSpeed`, `depositAccount`, and
31352
- * `allowanceStrategy`.
31637
+ * Validates `from` (adapter + chain), `amount`, optional `to.chain`
31638
+ * (defaults to Arc / Arc_Testnet for FAST), optional `token`,
31639
+ * `config.transferSpeed`, `depositAccount`, and `allowanceStrategy`.
31353
31640
  *
31354
31641
  * @example
31355
31642
  * ```typescript
@@ -31450,12 +31737,12 @@ const allowanceStrategySchema = z.enum([
31450
31737
  */ function validateDepositTransferConfig(params) {
31451
31738
  const { from, to, config, quote, allowanceStrategy } = params;
31452
31739
  const transferSpeed = config?.transferSpeed ?? 'STANDARD';
31453
- if (to !== undefined && allowanceStrategy !== undefined) {
31454
- throw createValidationFailedError$1('allowanceStrategy', allowanceStrategy, 'cannot be set when to is provided; FAST deposits do not use an ' + 'allowance strategy');
31740
+ if (transferSpeed === 'FAST' && allowanceStrategy !== undefined) {
31741
+ throw createValidationFailedError$1('allowanceStrategy', allowanceStrategy, 'cannot be set for FAST cross-chain deposits');
31455
31742
  }
31456
31743
  if (transferSpeed === 'FAST') {
31457
31744
  if (to === undefined) {
31458
- throw createValidationFailedError$1('to', undefined, 'required when transferSpeed is FAST');
31745
+ throw createValidationFailedError$1('to', undefined, 'required when transferSpeed is FAST and no default destination ' + 'can be derived from from.chain');
31459
31746
  }
31460
31747
  const dstChain = resolveChainIdentifier(to.chain);
31461
31748
  if (!isGatewayFastDepositDestination(dstChain)) {
@@ -31514,8 +31801,9 @@ const allowanceStrategySchema = z.enum([
31514
31801
  }
31515
31802
  /**
31516
31803
  * Run all validations required for estimateDeposit: from context, amount,
31517
- * required `to.chain`, optional token, config, depositAccount, and
31518
- * allowanceStrategy.
31804
+ * optional `to.chain`, optional token, config, depositAccount, and
31805
+ * allowanceStrategy. FAST params must already have the default destination
31806
+ * applied (see `applyDefaultFastDepositDestination`).
31519
31807
  *
31520
31808
  * @param params - The raw estimateDeposit params.
31521
31809
  * @returns Nothing; throws on invalid params.
@@ -31588,6 +31876,90 @@ const allowanceStrategySchema = z.enum([
31588
31876
  }
31589
31877
  }
31590
31878
 
31879
+ /**
31880
+ * Default destination chain for FAST cross-chain deposits, keyed by the
31881
+ * network of the source chain. Used when `config.transferSpeed` is `'FAST'`
31882
+ * and `to` is omitted.
31883
+ */ const DEFAULT_FAST_DEPOSIT_DESTINATION = {
31884
+ mainnet: Blockchain.Arc,
31885
+ testnet: Blockchain.Arc_Testnet
31886
+ };
31887
+ /**
31888
+ * Resolve the destination chain for a deposit.
31889
+ *
31890
+ * Return `to` unchanged when it is set or when the transfer speed is not
31891
+ * `'FAST'`. Otherwise return the default FAST deposit destination for the
31892
+ * source chain's network — `Arc` for mainnet sources and `Arc_Testnet` for
31893
+ * testnet sources.
31894
+ *
31895
+ * @param params - Deposit params with `from`, optional `to`, and optional
31896
+ * `config`. `from.chain` must already be validated.
31897
+ * @returns The explicit or defaulted destination, or `undefined` for
31898
+ * STANDARD deposits.
31899
+ * @throws KitError If `from.chain` cannot be resolved.
31900
+ *
31901
+ * @example
31902
+ * ```typescript
31903
+ * const to = resolveFastDepositDestination({
31904
+ * from: { chain: 'Ethereum_Sepolia' },
31905
+ * config: { transferSpeed: 'FAST' },
31906
+ * })
31907
+ * // to → { chain: 'Arc_Testnet' }
31908
+ * ```
31909
+ */ function resolveFastDepositDestination(params) {
31910
+ const { from, to, config } = params;
31911
+ if (to !== undefined || config?.transferSpeed !== 'FAST') {
31912
+ return to;
31913
+ }
31914
+ const srcChain = resolveChainIdentifier(from.chain);
31915
+ return {
31916
+ chain: srcChain.isTestnet ? DEFAULT_FAST_DEPOSIT_DESTINATION.testnet : DEFAULT_FAST_DEPOSIT_DESTINATION.mainnet
31917
+ };
31918
+ }
31919
+ /**
31920
+ * Return deposit params with the default FAST deposit destination applied.
31921
+ *
31922
+ * Call this at the top of every deposit entry point, before validation, so
31923
+ * all downstream logic (validation, routing, telemetry, and the estimate
31924
+ * result) sees an explicit `to` for every FAST deposit.
31925
+ *
31926
+ * When {@link resolveFastDepositDestination} yields a destination and `to`
31927
+ * is not set, return a shallow copy with `to` filled in. Otherwise return
31928
+ * the params unchanged. Safe to call more than once.
31929
+ *
31930
+ * Runs before validation, so it never throws: when `from.chain` cannot be
31931
+ * resolved (or `params` is malformed plain-JS input) the params are returned
31932
+ * unchanged and schema validation reports the error.
31933
+ *
31934
+ * @typeParam T - The deposit, depositFor, or estimateDeposit params type.
31935
+ * @param params - Raw (unvalidated) deposit params.
31936
+ * @returns Params with `to` set for every resolvable FAST deposit.
31937
+ *
31938
+ * @example
31939
+ * ```typescript
31940
+ * const resolved = applyDefaultFastDepositDestination({
31941
+ * from: { adapter, chain: 'Base' },
31942
+ * amount: '10',
31943
+ * config: { transferSpeed: 'FAST' },
31944
+ * })
31945
+ * // resolved.to → { chain: 'Arc' }
31946
+ * ```
31947
+ */ function applyDefaultFastDepositDestination(params) {
31948
+ let to;
31949
+ try {
31950
+ to = resolveFastDepositDestination(params);
31951
+ } catch {
31952
+ // Unresolvable source chain — leave params as-is for validation to reject.
31953
+ return params;
31954
+ }
31955
+ if (to === undefined || to === params.to) {
31956
+ return params;
31957
+ }
31958
+ return {
31959
+ ...params,
31960
+ to
31961
+ };
31962
+ }
31591
31963
  async function resolveDepositParams(params) {
31592
31964
  const chain = resolveChainIdentifier(params.from.chain);
31593
31965
  params.from.adapter.validateChainSupport(chain);
@@ -31846,7 +32218,9 @@ function resolveGatewayExecutorContracts(srcChain, dstChain) {
31846
32218
  * covers the amount) → burn → relay wait.
31847
32219
  *
31848
32220
  * @param context - Kit context (used for analytics telemetry emissions).
31849
- * @param params - Deposit params (must have `to` set and `to.chain` differ from `from.chain`).
32221
+ * @param params - Deposit params with `to` set (explicitly or via
32222
+ * `applyDefaultFastDepositDestination`) and `to.chain` differing from
32223
+ * `from.chain`.
31850
32224
  * @param depositAccount - Destination Gateway account to credit. When omitted
31851
32225
  * (i.e. called from `deposit()`), the signer's own address is used.
31852
32226
  * @returns Settled deposit result after Circle's relay has confirmed the mint.
@@ -32107,7 +32481,8 @@ function resolveGatewayExecutorContracts(srcChain, dstChain) {
32107
32481
  * (token → `'USDC'`, allowanceStrategy → `'authorize'`), finds a provider,
32108
32482
  * and delegates to the provider's deposit operation.
32109
32483
  *
32110
- * For cross-chain (FAST) deposits (when `to` is set): fetches or validates a
32484
+ * For cross-chain (FAST) deposits (when `config.transferSpeed` is `'FAST'`;
32485
+ * `to` defaults to Arc / Arc_Testnet when omitted): fetches or validates a
32111
32486
  * fee quote, runs a preflight affordability check, submits the prepaid-FORWARD
32112
32487
  * burn on the source chain, and waits for Circle's relay to confirm the mint
32113
32488
  * on the destination. The caller's Gateway account is credited on the
@@ -32146,11 +32521,12 @@ function resolveGatewayExecutorContracts(srcChain, dstChain) {
32146
32521
  * const crossResult = await deposit(context, { ...estimate, from: { adapter, chain: 'Ethereum_Sepolia' } })
32147
32522
  * ```
32148
32523
  */ async function deposit(context, params) {
32149
- assertDepositParams(params);
32150
- if (params.to !== undefined) {
32151
- return depositFastCrossChain(context, params);
32524
+ const normalizedParams = applyDefaultFastDepositDestination(params);
32525
+ assertDepositParams(normalizedParams);
32526
+ if (normalizedParams.to !== undefined) {
32527
+ return depositFastCrossChain(context, normalizedParams);
32152
32528
  }
32153
- const resolvedParams = await resolveDepositParams(params);
32529
+ const resolvedParams = await resolveDepositParams(normalizedParams);
32154
32530
  const chain = resolvedParams.from.chain;
32155
32531
  if (!isGatewayV1Supported(chain)) {
32156
32532
  throw createUnsupportedRouteError(chain.name, chain.name);
@@ -32165,7 +32541,8 @@ function resolveGatewayExecutorContracts(srcChain, dstChain) {
32165
32541
  * (token → `'USDC'`, allowanceStrategy → `'approve'`), finds a provider,
32166
32542
  * and delegates to the provider's depositFor operation.
32167
32543
  *
32168
- * For cross-chain (FAST) deposits (when `to` is set): fetches or validates a
32544
+ * For cross-chain (FAST) deposits (when `config.transferSpeed` is `'FAST'`;
32545
+ * `to` defaults to Arc / Arc_Testnet when omitted): fetches or validates a
32169
32546
  * fee quote, runs a preflight affordability check, submits the prepaid-FORWARD
32170
32547
  * burn on the source chain, and waits for Circle's relay to confirm the mint.
32171
32548
  * The `depositAccount` is credited on the destination chain.
@@ -32209,11 +32586,12 @@ function resolveGatewayExecutorContracts(srcChain, dstChain) {
32209
32586
  * })
32210
32587
  * ```
32211
32588
  */ async function depositFor(context, params) {
32212
- assertDepositForParams(params);
32213
- if (params.to !== undefined) {
32214
- return depositFastCrossChain(context, params, params.depositAccount);
32589
+ const normalizedParams = applyDefaultFastDepositDestination(params);
32590
+ assertDepositForParams(normalizedParams);
32591
+ if (normalizedParams.to !== undefined) {
32592
+ return depositFastCrossChain(context, normalizedParams, normalizedParams.depositAccount);
32215
32593
  }
32216
- const resolvedParams = await resolveDepositParams(params);
32594
+ const resolvedParams = await resolveDepositParams(normalizedParams);
32217
32595
  const chain = resolvedParams.from.chain;
32218
32596
  if (!isGatewayV1Supported(chain)) {
32219
32597
  throw createUnsupportedRouteError(chain.name, chain.name);
@@ -32272,7 +32650,8 @@ async function estimateDepositImpl(context, params) {
32272
32650
  fee: depositTotalGasFee
32273
32651
  }, srcChain));
32274
32652
  } else {
32275
- // assertEstimateDepositParams guarantees params.to is set on the FAST path
32653
+ // applyDefaultFastDepositDestination + assertEstimateDepositParams
32654
+ // guarantee params.to is set on the FAST path
32276
32655
  const { to } = params;
32277
32656
  if (to === undefined) {
32278
32657
  /* v8 ignore next 6 -- assertEstimateDepositParams guarantees to is set on the FAST path */ throw createValidationFailedError$1('to', undefined, 'required for FAST transfers');
@@ -32423,7 +32802,8 @@ async function estimateDepositImpl(context, params) {
32423
32802
  *
32424
32803
  * @param context - Kit context (used for analytics telemetry emissions).
32425
32804
  * @param params - The estimate parameters: source context, amount, destination
32426
- * chain, optional token, transfer speed, and allowance strategy.
32805
+ * chain (defaults to Arc / Arc_Testnet for FAST), optional token, transfer
32806
+ * speed, and allowance strategy.
32427
32807
  * @returns Promise resolving to an itemized fee estimate with an optional
32428
32808
  * quote for FAST cross-chain transfers.
32429
32809
  * @throws KitError If the wallet address cannot be resolved — wallet not connected
@@ -32456,8 +32836,9 @@ async function estimateDepositImpl(context, params) {
32456
32836
  * const result = await deposit(context, { ...estimate, from: { adapter, chain: 'Ethereum_Sepolia' } })
32457
32837
  * ```
32458
32838
  */ async function estimateDeposit(context, params) {
32459
- assertEstimateDepositParams(params);
32460
- return estimateDepositImpl(context, params);
32839
+ const normalizedParams = applyDefaultFastDepositDestination(params);
32840
+ assertEstimateDepositParams(normalizedParams);
32841
+ return estimateDepositImpl(context, normalizedParams);
32461
32842
  }
32462
32843
 
32463
32844
  // The `as never` cast is required because `unifiedBalanceChainIdentifierSchema`
@@ -34031,6 +34412,10 @@ const removeFundParamsSchema = z.object({
34031
34412
  * All three telemetry call sites use this helper to keep the classification
34032
34413
  * consistent.
34033
34414
  *
34415
+ * Callers must pass params that have been through
34416
+ * `applyDefaultFastDepositDestination`, which sets `to` to Arc / Arc_Testnet
34417
+ * for FAST deposits that omit it.
34418
+ *
34034
34419
  * @param params - Deposit or estimate-deposit params to inspect.
34035
34420
  * @returns `true` when the transfer is a FAST cross-chain deposit.
34036
34421
  */ function isFastDeposit(params) {
@@ -34170,21 +34555,22 @@ const removeFundParamsSchema = z.object({
34170
34555
  *
34171
34556
  * @see UnifiedBalanceKit.depositFor to deposit into another account.
34172
34557
  */ async deposit(params) {
34173
- if (isFastDeposit(params)) {
34174
- return withErrorTelemetry(async ()=>deposit(this.context, params), EVENT_TYPES.FAST_DEPOSIT, this.telemetryConfig, {
34175
- sourceChain: resolveChainName(params.from?.chain),
34176
- destinationChain: resolveChainName(params.to?.chain),
34177
- tokenIn: params.token ?? 'USDC',
34178
- amountIn: Number.parseFloat(params.amount),
34179
- ...params.quote !== undefined && {
34180
- correlationId: hashSignedQuote(params.quote)
34558
+ const normalizedParams = applyDefaultFastDepositDestination(params);
34559
+ if (isFastDeposit(normalizedParams)) {
34560
+ return withErrorTelemetry(async ()=>deposit(this.context, normalizedParams), EVENT_TYPES.FAST_DEPOSIT, this.telemetryConfig, {
34561
+ sourceChain: resolveChainName(normalizedParams.from?.chain),
34562
+ destinationChain: resolveChainName(normalizedParams.to?.chain),
34563
+ tokenIn: normalizedParams.token ?? 'USDC',
34564
+ amountIn: Number.parseFloat(normalizedParams.amount),
34565
+ ...normalizedParams.quote !== undefined && {
34566
+ correlationId: hashSignedQuote(normalizedParams.quote)
34181
34567
  }
34182
34568
  });
34183
34569
  }
34184
- return withErrorTelemetry(async ()=>deposit(this.context, params), EVENT_TYPES.DEPOSIT, this.telemetryConfig, {
34185
- sourceChain: resolveChainName(params.from?.chain),
34186
- tokenIn: params.token ?? 'USDC',
34187
- amountIn: Number.parseFloat(params.amount)
34570
+ return withErrorTelemetry(async ()=>deposit(this.context, normalizedParams), EVENT_TYPES.DEPOSIT, this.telemetryConfig, {
34571
+ sourceChain: resolveChainName(normalizedParams.from?.chain),
34572
+ tokenIn: normalizedParams.token ?? 'USDC',
34573
+ amountIn: Number.parseFloat(normalizedParams.amount)
34188
34574
  });
34189
34575
  }
34190
34576
  /**
@@ -34196,24 +34582,25 @@ const removeFundParamsSchema = z.object({
34196
34582
  *
34197
34583
  * @see UnifiedBalanceKit.deposit to deposit into your own account.
34198
34584
  */ async depositFor(params) {
34199
- if (isFastDeposit(params)) {
34585
+ const normalizedParams = applyDefaultFastDepositDestination(params);
34586
+ if (isFastDeposit(normalizedParams)) {
34200
34587
  // Fast depositFor shares FAST_DEPOSIT event type with fast deposit — the
34201
34588
  // success-path emitter in depositFastCrossChain uses a single event type
34202
34589
  // for both entry points, so error telemetry mirrors that here.
34203
- return withErrorTelemetry(async ()=>depositFor(this.context, params), EVENT_TYPES.FAST_DEPOSIT, this.telemetryConfig, {
34204
- sourceChain: resolveChainName(params.from?.chain),
34205
- destinationChain: resolveChainName(params.to?.chain),
34206
- tokenIn: params.token ?? 'USDC',
34207
- amountIn: Number.parseFloat(params.amount),
34208
- ...params.quote !== undefined && {
34209
- correlationId: hashSignedQuote(params.quote)
34590
+ return withErrorTelemetry(async ()=>depositFor(this.context, normalizedParams), EVENT_TYPES.FAST_DEPOSIT, this.telemetryConfig, {
34591
+ sourceChain: resolveChainName(normalizedParams.from?.chain),
34592
+ destinationChain: resolveChainName(normalizedParams.to?.chain),
34593
+ tokenIn: normalizedParams.token ?? 'USDC',
34594
+ amountIn: Number.parseFloat(normalizedParams.amount),
34595
+ ...normalizedParams.quote !== undefined && {
34596
+ correlationId: hashSignedQuote(normalizedParams.quote)
34210
34597
  }
34211
34598
  });
34212
34599
  }
34213
- return withErrorTelemetry(async ()=>depositFor(this.context, params), EVENT_TYPES.DEPOSIT_FOR, this.telemetryConfig, {
34214
- sourceChain: resolveChainName(params.from?.chain),
34215
- tokenIn: params.token ?? 'USDC',
34216
- amountIn: Number.parseFloat(params.amount)
34600
+ return withErrorTelemetry(async ()=>depositFor(this.context, normalizedParams), EVENT_TYPES.DEPOSIT_FOR, this.telemetryConfig, {
34601
+ sourceChain: resolveChainName(normalizedParams.from?.chain),
34602
+ tokenIn: normalizedParams.token ?? 'USDC',
34603
+ amountIn: Number.parseFloat(normalizedParams.amount)
34217
34604
  });
34218
34605
  }
34219
34606
  /**
@@ -34228,23 +34615,25 @@ const removeFundParamsSchema = z.object({
34228
34615
  * ```
34229
34616
  *
34230
34617
  * @param params - The estimate parameters including source context, amount,
34231
- * destination chain, optional transfer speed, and optional allowance strategy.
34618
+ * destination chain (defaults to Arc / Arc_Testnet for FAST), optional
34619
+ * transfer speed, and optional allowance strategy.
34232
34620
  * @returns Promise resolving to an itemised fee breakdown.
34233
34621
  *
34234
34622
  * @see UnifiedBalanceKit.deposit to execute after estimating.
34235
34623
  */ async estimateDeposit(params) {
34236
- if (isFastDeposit(params)) {
34237
- return withErrorTelemetry(async ()=>estimateDeposit(this.context, params), EVENT_TYPES.ESTIMATE_FAST_DEPOSIT, this.telemetryConfig, {
34238
- sourceChain: resolveChainName(params.from?.chain),
34239
- destinationChain: resolveChainName(params.to?.chain),
34240
- tokenIn: params.token ?? 'USDC',
34241
- amountIn: Number.parseFloat(params.amount)
34624
+ const normalizedParams = applyDefaultFastDepositDestination(params);
34625
+ if (isFastDeposit(normalizedParams)) {
34626
+ return withErrorTelemetry(async ()=>estimateDeposit(this.context, normalizedParams), EVENT_TYPES.ESTIMATE_FAST_DEPOSIT, this.telemetryConfig, {
34627
+ sourceChain: resolveChainName(normalizedParams.from?.chain),
34628
+ destinationChain: resolveChainName(normalizedParams.to?.chain),
34629
+ tokenIn: normalizedParams.token ?? 'USDC',
34630
+ amountIn: Number.parseFloat(normalizedParams.amount)
34242
34631
  });
34243
34632
  }
34244
- return withErrorTelemetry(async ()=>estimateDeposit(this.context, params), EVENT_TYPES.ESTIMATE_DEPOSIT, this.telemetryConfig, {
34245
- sourceChain: resolveChainName(params.from?.chain),
34246
- tokenIn: params.token ?? 'USDC',
34247
- amountIn: Number.parseFloat(params.amount)
34633
+ return withErrorTelemetry(async ()=>estimateDeposit(this.context, normalizedParams), EVENT_TYPES.ESTIMATE_DEPOSIT, this.telemetryConfig, {
34634
+ sourceChain: resolveChainName(normalizedParams.from?.chain),
34635
+ tokenIn: normalizedParams.token ?? 'USDC',
34636
+ amountIn: Number.parseFloat(normalizedParams.amount)
34248
34637
  });
34249
34638
  }
34250
34639
  /**
@@ -34613,7 +35002,8 @@ registerKit(`${pkg$1.name}/${pkg$1.version}`);
34613
35002
  * {@link AppKitUnifiedBalance.depositFor}.
34614
35003
  *
34615
35004
  * @param params - Estimate details including the depositor context, amount,
34616
- * destination chain, and optional transfer speed.
35005
+ * destination chain (defaults to Arc / Arc_Testnet for FAST), and optional
35006
+ * transfer speed.
34617
35007
  * @returns Promise resolving to the itemised fee estimate.
34618
35008
  * @throws {KitError} If the estimate parameters are invalid or the route is
34619
35009
  * unsupported.