@circle-fin/app-kit 1.16.0 → 1.18.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 (52) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/borrow.cjs +150 -32
  3. package/borrow.d.cts +38 -9
  4. package/borrow.d.mts +38 -9
  5. package/borrow.d.ts +38 -9
  6. package/borrow.mjs +150 -32
  7. package/bridge.cjs +454 -53
  8. package/bridge.d.cts +38 -9
  9. package/bridge.d.mts +38 -9
  10. package/bridge.d.ts +38 -9
  11. package/bridge.mjs +454 -53
  12. package/chains.cjs +10 -6
  13. package/chains.d.cts +1 -1
  14. package/chains.d.mts +1 -1
  15. package/chains.d.ts +1 -1
  16. package/chains.mjs +10 -6
  17. package/context.d.cts +38 -9
  18. package/context.d.mts +38 -9
  19. package/context.d.ts +38 -9
  20. package/earn.cjs +830 -43
  21. package/earn.d.cts +38 -9
  22. package/earn.d.mts +38 -9
  23. package/earn.d.ts +38 -9
  24. package/earn.mjs +830 -43
  25. package/estimateBridge.cjs +454 -53
  26. package/estimateBridge.d.cts +38 -9
  27. package/estimateBridge.d.mts +38 -9
  28. package/estimateBridge.d.ts +38 -9
  29. package/estimateBridge.mjs +454 -53
  30. package/estimateSwap.cjs +265 -45
  31. package/estimateSwap.d.cts +86 -9
  32. package/estimateSwap.d.mts +86 -9
  33. package/estimateSwap.d.ts +86 -9
  34. package/estimateSwap.mjs +265 -45
  35. package/index.cjs +1019 -73
  36. package/index.d.cts +373 -210
  37. package/index.d.mts +373 -210
  38. package/index.d.ts +373 -210
  39. package/index.mjs +1019 -73
  40. package/package.json +8 -8
  41. package/server.cjs +35 -9
  42. package/server.d.cts +29 -10
  43. package/server.d.mts +29 -10
  44. package/server.d.ts +29 -10
  45. package/server.mjs +35 -9
  46. package/swap.cjs +265 -45
  47. package/swap.d.cts +86 -9
  48. package/swap.d.mts +86 -9
  49. package/swap.d.ts +86 -9
  50. package/swap.mjs +265 -45
  51. package/unifiedBalance.cjs +139 -20
  52. package/unifiedBalance.mjs +139 -20
package/CHANGELOG.md CHANGED
@@ -1,5 +1,84 @@
1
1
  # @circle-fin/app-kit
2
2
 
3
+ ## 1.18.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Bridge Kit now sends a success analytics event when `bridge()` or `retry()`
8
+ completes a transfer. The event includes the source and destination chains,
9
+ the token, the amount, and the source transaction hash (the CCTP burn or the
10
+ CCTPx transfer). It never includes wallet addresses or keys, and a failed
11
+ telemetry request never changes the bridge result.
12
+
13
+ - Set `disableAnalytics: true` on `BridgeKit` to opt out. It is separate from
14
+ `disableErrorReporting`, which still controls error telemetry only.
15
+ - App Kit's existing `disableAnalytics` option now also covers bridge
16
+ operations.
17
+
18
+ - Support same-chain deposits into Veda vaults.
19
+
20
+ A Veda vault mints its shares straight to the depositing wallet, so the Earn Service only builds a Veda deposit for a wallet that signed a `DepositIntent` for it. `deposit()` now looks up the vault first. When the vault is a Veda vault, the wallet signs an EIP-712 `DepositIntent` (wallet, vault, amount, deadline) during the `fetchParams` step, and the SDK sends the signature with the deposit request. Deposits into other vaults do not show an extra signature prompt. If the vault lookup fails (an error, or the vault listed in the lookup's `errors`), the deposit continues without an intent, so deposits into other vaults work as before; a Veda deposit then fails with the lookup error (for example, a retryable rate-limit error) instead of a signature rejection.
21
+
22
+ A Veda deposit needs an adapter that can sign typed data, and an amount with no more decimal places than the vault asset. Otherwise it fails with `InputError.VALIDATION_FAILED` before the signature prompt. When the Earn Service rejects the intent (error `380418`), the SDK reports `EarnError.SIGNATURE_REJECTED`. The intent is valid for 240 seconds from the signature prompt, so a wallet that signs slowly can submit an expired intent; the error message says so, and calling `deposit()` again signs a new intent.
23
+
24
+ Known limitations:
25
+
26
+ - Cross-chain deposits into Veda vaults are not supported. The Earn Service rejects them with `UNSUPPORTED_VAULT`.
27
+ - An application that configures an `onBeforeAuthorize` hook on its adapter cannot deposit into a Veda vault yet: the authorization review cannot decode the Veda deposit bundle, so the deposit fails before anything is signed. Applications without the hook are not affected. Support for the hook is planned.
28
+
29
+ ### Patch Changes
30
+
31
+ - Arc Testnet calls no longer fail with `HTTP request failed` when no custom RPC is configured. The default Arc Testnet RPC endpoint is now `https://rpc.testnet.arc.io`, replacing the retired `https://rpc.testnet.arc.network/` host. Apps that already pass their own Arc Testnet RPC URL or transport are unaffected.
32
+ - Forwarded transfers to Solana (`useForwarder: true`) now include the cost of
33
+ creating the recipient's USDC token account in the forwarder fee, so Circle's
34
+ Forwarding Service can always complete the mint. At current prices this adds
35
+ about 0.16 USDC to the forwarder fee for Solana destinations. Transfers to EVM
36
+ chains are unchanged.
37
+
38
+ - If you set `config.maxFee` yourself for these transfers, it must cover the
39
+ higher fee, or the transfer can stall after the burn and need a manual mint.
40
+ Use the `forwarder` fee from `estimate()`, or leave `maxFee` unset.
41
+ - Forwarded transfers to Solana whose amount does not exceed the fee now fail
42
+ before any transaction is sent, with an `INPUT_INVALID_AMOUNT` error.
43
+
44
+ ## 1.17.0
45
+
46
+ ### Minor Changes
47
+
48
+ - Add Cronos and Morph as swap networks. Cronos supports the native CRO, USDC,
49
+ EURC, USDT, WETH, DAI, and WBTC aliases. Morph supports the native ETH, USDC,
50
+ USDT, and WETH aliases.
51
+ - Update the Borrow Kit dependency to the release that adds the `@circle-fin/borrow-kit/chains` subpath. No changes are needed for `kit.borrow` calls: `@circle-fin/app-kit/chains` already exports `Arc` and `ArcTestnet`.
52
+ - Show how a swap is routed, and which fees the route charges.
53
+
54
+ - Swap estimates and results include an optional `route`: the provider that routed the swap (for example `lifi` or `circle`) and each swap or bridge step, with its tool, tokens, and amounts. Types: `SwapRoute`, `SwapRouteStep`, `SwapRouteStepEstimate`, `SwapRouteToken`.
55
+ - Treat `route.provider` as an opaque string. New providers can appear without an SDK update.
56
+ - Provider-specific details are on the optional `metadata` field of the route and of each step. For example, Circle CCTP steps include the source and destination domains.
57
+ - Route details are for display only. If the SDK does not recognise a step, `steps` is empty rather than incomplete, and an unrecognised route is omitted. The estimate or swap still succeeds.
58
+ - Each entry in `fees` can include `component`, the provider's name for the fee (for example `FORWARD` or `PRE_FINALITY`), and `chain`, the chain where it is charged.
59
+ - Estimates for direct Circle CCTP routes now show an approximate gas fee instead of zero. The actual gas is still estimated when the swap runs.
60
+ - `getSwapStatus` and `waitForSwap` track Circle-routed swaps with no code changes.
61
+
62
+ - Add `EarnError.SHARES_LOCKED` (`EARN_SHARES_LOCKED`, code 1107). Earn
63
+ operations throw it when a Veda vault rejects the call because the vault
64
+ shares are still inside the share lock period after a deposit. The error is
65
+ not retryable right away: wait for the lock period to end, then try again.
66
+
67
+ Veda vault reverts now give readable messages instead of raw error
68
+ selectors. For example, a revert now says that the vault is paused or that
69
+ the deposit would exceed the vault deposit cap. This works with both the
70
+ default and `/next` adapter entries, and with browser wallets.
71
+
72
+ - Add `batchTransactions` to `SwapConfig`. Swaps that need an ERC-20 approval send the approval and the swap as one atomic batch when the connected wallet supports it, which is the default. Set `config: { batchTransactions: false }` to send them as two transactions instead, approval first. Use this if your wallet rejects batched calls or under-estimates gas on complex routes. Non-boolean values are now rejected with a validation error.
73
+
74
+ ### Patch Changes
75
+
76
+ - Respect Circle's per-route availability for CCTPx. When Circle disables CCTPx for a token on a source or destination chain:
77
+
78
+ - `supportsRoute` returns `false` for that route, so the kit no longer selects CCTPx for a transfer the service would refuse to quote.
79
+ - A quote request for that route throws a `FATAL` `InputError.UNSUPPORTED_ROUTE` instead of a `RETRYABLE` `ServiceError.INTERNAL_ERROR`, so retry loops stop instead of waiting for a recovery that will not come.
80
+ - `CCTPXTokenDeployment` exposes an optional `enabled?: boolean` field, so custom UIs can show whether a deployment is available. Responses that omit the field are treated as enabled.
81
+
3
82
  ## 1.16.0
4
83
 
5
84
  ### Minor Changes
package/borrow.cjs CHANGED
@@ -3181,6 +3181,8 @@ var SwapChain;
3181
3181
  SwapChain["HyperEVM"] = "HyperEVM";
3182
3182
  SwapChain["Monad"] = "Monad";
3183
3183
  SwapChain["Arc"] = "Arc";
3184
+ SwapChain["Cronos"] = "Cronos";
3185
+ SwapChain["Morph"] = "Morph";
3184
3186
  // Testnet chains with swap support
3185
3187
  SwapChain["Arc_Testnet"] = "Arc_Testnet";
3186
3188
  })(SwapChain || (SwapChain = {}));
@@ -3861,14 +3863,14 @@ var BorrowChain;
3861
3863
  symbol: 'USDC',
3862
3864
  // Arc uses native USDC with 18 decimals for gas payments (EVM standard).
3863
3865
  // Note: The ERC-20 USDC contract at usdcAddress uses 6 decimals.
3864
- // See: https://docs.arc.network/arc/references/contract-addresses
3866
+ // See: https://docs.arc.io/arc/references/contract-addresses
3865
3867
  decimals: 18
3866
3868
  },
3867
3869
  chainId: 5042002,
3868
3870
  isTestnet: true,
3869
3871
  explorerUrl: 'https://testnet.arcscan.app/tx/{hash}',
3870
3872
  rpcEndpoints: [
3871
- 'https://rpc.testnet.arc.network/'
3873
+ 'https://rpc.testnet.arc.io'
3872
3874
  ],
3873
3875
  eurcAddress: '0x89B50855Aa3bE2F677cD6303Cec089B5F319D72a',
3874
3876
  usdcAddress: '0x3600000000000000000000000000000000000000',
@@ -4513,7 +4515,8 @@ var BorrowChain;
4513
4515
  }
4514
4516
  },
4515
4517
  kitContracts: {
4516
- bridge: BRIDGE_CONTRACT_EVM_MAINNET
4518
+ bridge: BRIDGE_CONTRACT_EVM_MAINNET,
4519
+ adapter: ADAPTER_CONTRACT_EVM_MAINNET
4517
4520
  }
4518
4521
  });
4519
4522
 
@@ -5382,7 +5385,8 @@ var BorrowChain;
5382
5385
  }
5383
5386
  },
5384
5387
  kitContracts: {
5385
- bridge: BRIDGE_CONTRACT_EVM_MAINNET
5388
+ bridge: BRIDGE_CONTRACT_EVM_MAINNET,
5389
+ adapter: ADAPTER_CONTRACT_EVM_MAINNET
5386
5390
  }
5387
5391
  });
5388
5392
 
@@ -7272,6 +7276,56 @@ var Chains = {
7272
7276
  Blockchain.World_Chain_Sepolia
7273
7277
  ]);
7274
7278
 
7279
+ /**
7280
+ * Check if a chain supports a specific type of custom smart contract logic.
7281
+ *
7282
+ * This function examines a chain definition to determine if it has a specific
7283
+ * contract type configured. When a chain has custom contract support, it can
7284
+ * use enhanced features and custom business logic in addition to the standard
7285
+ * CCTP approve/burn/mint flow.
7286
+ *
7287
+ * @param chain - The chain definition to examine for custom contract support.
7288
+ * @param contractType - The type of contract to check for (e.g., 'bridge').
7289
+ * @returns True if the chain supports the specified contract type with a valid address configured.
7290
+ *
7291
+ * @example
7292
+ * ```typescript
7293
+ * import { hasCustomContractSupport, Ethereum } from '@core/chains'
7294
+ *
7295
+ * // Check if a chain supports bridge contracts
7296
+ * if (hasCustomContractSupport(Ethereum, 'bridge')) {
7297
+ * // Runtime validation confirmed kitContracts.bridge exists
7298
+ * console.log('Bridge contract:', Ethereum.kitContracts?.bridge)
7299
+ * return executeCustomFlow(Ethereum.kitContracts?.bridge!, params)
7300
+ * } else {
7301
+ * console.log('Using standard CCTP flow')
7302
+ * return executeStandardFlow(params)
7303
+ * }
7304
+ * ```
7305
+ *
7306
+ * @example
7307
+ * ```typescript
7308
+ * // Usage in flow determination
7309
+ * function determineBridgingFlow(chain: ChainDefinition, params: BridgeParams) {
7310
+ * if (hasCustomContractSupport(chain, 'bridge')) {
7311
+ * return 'custom'
7312
+ * } else if (isCCTPV2Supported(chain)) {
7313
+ * return 'standard'
7314
+ * } else {
7315
+ * throw new Error(`Chain ${chain.name} is not supported for bridging`)
7316
+ * }
7317
+ * }
7318
+ *
7319
+ * // Future usage with other contract types (when added to KitContractType)
7320
+ * // if (hasCustomContractSupport(someChain, 'customType')) {
7321
+ * // console.log('Custom contract:', someChain.kitContracts?.customType)
7322
+ * // }
7323
+ * ```
7324
+ */ function hasCustomContractSupport(chain, contractType) {
7325
+ const contractAddress = chain.kitContracts?.[contractType];
7326
+ return typeof contractAddress === 'string' && contractAddress.trim().length > 0;
7327
+ }
7328
+
7275
7329
  /**
7276
7330
  * Temporary allowlist of chains permitted to initiate Gateway fast deposits.
7277
7331
  * Only chains keyed here are eligible; all others are rejected. Using the
@@ -7525,8 +7579,8 @@ var Chains = {
7525
7579
  * Zod schema for validating swap-specific chain identifiers.
7526
7580
  *
7527
7581
  * Validates chains based on:
7528
- * - CCTPv2 support (adapter contract deployed)
7529
- * - Mainnet only (no testnets)
7582
+ * - Membership in the SwapChain enum
7583
+ * - Mainnet or explicitly allowlisted testnet
7530
7584
  * - At least one supported token available
7531
7585
  *
7532
7586
  */ const swapChainIdentifierSchema = zod.z.union([
@@ -7931,7 +7985,7 @@ const swapTokenEnumSchema = zod.z.enum([
7931
7985
  *
7932
7986
  * A chain supports swaps if ALL conditions are met:
7933
7987
  * 1. Is a member of the {@link SwapChain} enum
7934
- * 2. Has CCTPv2 support (adapter contract deployed)
7988
+ * 2. Has an Adapter contract configured directly or through CCTP v2
7935
7989
  *
7936
7990
  * Testnets are allowed only when explicitly listed in the
7937
7991
  * {@link SwapChain} enum (e.g., Arc_Testnet).
@@ -7952,14 +8006,14 @@ const swapTokenEnumSchema = zod.z.enum([
7952
8006
  * @remarks
7953
8007
  * Chains automatically become swap-enabled when:
7954
8008
  * - Added to the {@link SwapChain} enum
7955
- * - Adapter contract is deployed (CCTPv2)
8009
+ * - An Adapter contract is deployed and configured
7956
8010
  *
7957
8011
  * No code changes needed when new chains are added!
7958
8012
  */ function isSwapSupportedChain(chain) {
7959
8013
  if (!(chain.chain in SwapChain)) {
7960
8014
  return false;
7961
8015
  }
7962
- if (!isCCTPV2Supported(chain)) {
8016
+ if (!isCCTPV2Supported(chain) && !hasCustomContractSupport(chain, 'adapter')) {
7963
8017
  return false;
7964
8018
  }
7965
8019
  return true;
@@ -7970,7 +8024,7 @@ const swapTokenEnumSchema = zod.z.enum([
7970
8024
  *
7971
8025
  * Dynamically filter chain definitions to include only those that:
7972
8026
  * - Are members of the {@link SwapChain} enum
7973
- * - Have CCTPv2 support
8027
+ * - Have an Adapter contract configured directly or through CCTP v2
7974
8028
  *
7975
8029
  * This function is pure and accepts chains as parameter to avoid
7976
8030
  * circular dependencies.
@@ -8905,11 +8959,13 @@ function parseOrThrow(value, schema, context) {
8905
8959
  [Blockchain.Arbitrum]: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9',
8906
8960
  [Blockchain.Avalanche]: '0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7',
8907
8961
  [Blockchain.Celo]: '0x48065fbBE25f71C9282ddf5e1cD6D6A887483D5e',
8962
+ [Blockchain.Cronos]: '0x66e428c3f67a68878562e79A0234c1F83c208770',
8908
8963
  [Blockchain.Ethereum]: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
8909
8964
  [Blockchain.HyperEVM]: '0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb',
8910
8965
  [Blockchain.Ink]: '0x0200C29006150606B650577BBE7B6248F58470c1',
8911
8966
  [Blockchain.Linea]: '0xA219439258ca9da29E9Cc4cE5596924745e12B93',
8912
8967
  [Blockchain.Monad]: '0xe7cd86e13AC4309349F30B3435a9d337750fC82D',
8968
+ [Blockchain.Morph]: '0xe7cd86e13AC4309349F30B3435a9d337750fC82D',
8913
8969
  [Blockchain.NEAR]: 'usdt.tether-token.near',
8914
8970
  [Blockchain.Optimism]: '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58',
8915
8971
  [Blockchain.Polkadot_Asset_Hub]: '1984',
@@ -8968,6 +9024,7 @@ function parseOrThrow(value, schema, context) {
8968
9024
  [Blockchain.Arbitrum]: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1',
8969
9025
  [Blockchain.Avalanche]: '0xd586E7F844cEa2F87f50152665BCbc2C279D8d70',
8970
9026
  [Blockchain.Base]: '0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb',
9027
+ [Blockchain.Cronos]: '0xF2001B145b43032AAF5Ee2884e456CCd805F677D',
8971
9028
  [Blockchain.Ethereum]: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
8972
9029
  [Blockchain.Linea]: '0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5',
8973
9030
  [Blockchain.Optimism]: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1',
@@ -9030,7 +9087,9 @@ function parseOrThrow(value, schema, context) {
9030
9087
  [Blockchain.Arbitrum]: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1',
9031
9088
  [Blockchain.Avalanche]: '0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB',
9032
9089
  [Blockchain.Base]: '0x4200000000000000000000000000000000000006',
9090
+ [Blockchain.Cronos]: '0xe44Fd7fCb2b1581822D0c862B68222998a0c299a',
9033
9091
  [Blockchain.Ethereum]: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
9092
+ [Blockchain.Morph]: '0x5300000000000000000000000000000000000011',
9034
9093
  [Blockchain.Optimism]: '0x4200000000000000000000000000000000000006',
9035
9094
  [Blockchain.Polygon]: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619',
9036
9095
  [Blockchain.Solana]: '7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs'
@@ -9049,6 +9108,7 @@ function parseOrThrow(value, schema, context) {
9049
9108
  locators: {
9050
9109
  [Blockchain.Ethereum]: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
9051
9110
  [Blockchain.Arbitrum]: '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f',
9111
+ [Blockchain.Cronos]: '0x062E66477Faf219F25D27dCED647BF57C3107d52',
9052
9112
  [Blockchain.Avalanche]: '0x50b7545627a5162F82A992c33b87aDc75187B218'
9053
9113
  }
9054
9114
  };
@@ -10145,7 +10205,7 @@ function resolveOptions(options) {
10145
10205
  }
10146
10206
 
10147
10207
  var name$3 = "@circle-fin/bridge-kit";
10148
- var version$3 = "1.15.2";
10208
+ var version$3 = "1.16.0";
10149
10209
  var pkg$3 = {
10150
10210
  name: name$3,
10151
10211
  version: version$3};
@@ -12224,7 +12284,7 @@ const validateQuoteItemSchema = zod.z.object({
12224
12284
  registerKit(`${pkg$3.name}/${pkg$3.version}`);
12225
12285
 
12226
12286
  var name$2 = "@circle-fin/swap-kit";
12227
- var version$2 = "1.7.1";
12287
+ var version$2 = "1.8.1";
12228
12288
  var pkg$2 = {
12229
12289
  name: name$2,
12230
12290
  version: version$2};
@@ -12566,6 +12626,64 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
12566
12626
  }, {
12567
12627
  message: 'fee amount must be non-negative (>= 0)'
12568
12628
  });
12629
+ /**
12630
+ * Parses a display-only field leniently: a value `schema` rejects is replaced
12631
+ * with `fallback` instead of failing the response that carries it.
12632
+ * Implemented with `preprocess` rather than Zod's `.catch()` because static
12633
+ * analysis misreads `.catch` on the schema chain as an unhandled Promise
12634
+ * (S7785).
12635
+ */ const withFallback = (schema, fallback)=>zod.z.preprocess((value)=>schema.safeParse(value).success ? value : fallback, schema);
12636
+ const swapRouteTokenSchema = zod.z.object({
12637
+ symbol: zod.z.string(),
12638
+ address: zod.z.string(),
12639
+ decimals: zod.z.number()
12640
+ });
12641
+ const swapRouteMetadataSchema = zod.z.record(zod.z.unknown()).optional();
12642
+ const swapRouteStepSchema = zod.z.object({
12643
+ type: zod.z.string(),
12644
+ tool: zod.z.string(),
12645
+ toolName: zod.z.string(),
12646
+ fromToken: swapRouteTokenSchema,
12647
+ toToken: swapRouteTokenSchema,
12648
+ estimate: zod.z.object({
12649
+ fromAmount: zod.z.string(),
12650
+ toAmount: zod.z.string(),
12651
+ gasCostUSD: zod.z.string().optional()
12652
+ }),
12653
+ metadata: swapRouteMetadataSchema
12654
+ });
12655
+ /**
12656
+ * Strict schema for a `SwapRoute`. Module-private: service responses
12657
+ * parse routes leniently through {@link responseSwapRouteSchema}.
12658
+ */ const swapRouteSchema = zod.z.object({
12659
+ provider: zod.z.string().min(1, 'provider must be a non-empty string'),
12660
+ steps: zod.z.array(swapRouteStepSchema),
12661
+ metadata: swapRouteMetadataSchema
12662
+ });
12663
+ /**
12664
+ * Route details are display-only, so service responses parse them leniently:
12665
+ * steps or metadata in a shape the SDK does not know are dropped rather than
12666
+ * failing the quote or swap they describe. Steps are all-or-nothing: if any
12667
+ * step is malformed, `steps` is empty, so a route never silently loses a hop.
12668
+ */ const responseSwapRouteSchema = swapRouteSchema.extend({
12669
+ steps: withFallback(swapRouteSchema.shape.steps, []),
12670
+ metadata: withFallback(swapRouteMetadataSchema, undefined)
12671
+ });
12672
+ const createSwapFeeItemSchema = zod.z.object({
12673
+ token: zod.z.string({
12674
+ required_error: 'fee token is required',
12675
+ invalid_type_error: 'fee token must be a string'
12676
+ }).min(1, 'fee token must be a non-empty string'),
12677
+ amount: feeAmountSchema,
12678
+ decimals: zod.z.number().int('fee token decimals must be an integer').nonnegative('fee token decimals must be a non-negative integer').optional(),
12679
+ symbol: zod.z.string({
12680
+ invalid_type_error: 'fee token symbol must be a string'
12681
+ }).min(1, 'fee token symbol must be a non-empty string').optional(),
12682
+ // Descriptive metadata: a value the SDK cannot use is dropped rather than
12683
+ // failing the response that carries the fee.
12684
+ type: withFallback(zod.z.string().min(1).optional(), undefined),
12685
+ chain: withFallback(zod.z.string().min(1).optional(), undefined)
12686
+ });
12569
12687
  /**
12570
12688
  * Zod schema for validating API keys.
12571
12689
  *
@@ -12651,10 +12769,7 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
12651
12769
  /** Quote information with estimated amounts and route */ quote: zod.z.object({
12652
12770
  /** Estimated output amount (base units) */ estimatedAmount: zod.z.string().min(1, 'estimatedAmount must be a non-empty string').regex(/^\d+$/, 'estimatedAmount must be a numeric string'),
12653
12771
  /** Guaranteed minimum output amount (base units) */ minAmount: zod.z.string().min(1, 'minAmount must be a non-empty string').regex(/^\d+$/, 'minAmount must be a numeric string'),
12654
- /** Route information from DEX aggregator */ route: zod.z.object({
12655
- provider: zod.z.string().min(1, 'provider must be a non-empty string'),
12656
- steps: zod.z.array(zod.z.unknown())
12657
- })
12772
+ /** Route information from DEX aggregator */ route: responseSwapRouteSchema
12658
12773
  }),
12659
12774
  /** Fee context indicating where fees should be collected */ feeContext: quoteFeeContextSchema
12660
12775
  });
@@ -12870,19 +12985,6 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12870
12985
  }).min(1, 'toChain must be a non-empty string if provided').optional(),
12871
12986
  apiKey: apiKeySchema.optional()
12872
12987
  });
12873
- /**
12874
- * Zod schema for validating CreateSwapResponse payloads.
12875
- */ const createSwapFeeItemSchema = zod.z.object({
12876
- token: zod.z.string({
12877
- required_error: 'fee token is required',
12878
- invalid_type_error: 'fee token must be a string'
12879
- }).min(1, 'fee token must be a non-empty string'),
12880
- amount: feeAmountSchema,
12881
- decimals: zod.z.number().int('fee token decimals must be an integer').nonnegative('fee token decimals must be a non-negative integer').optional(),
12882
- symbol: zod.z.string({
12883
- invalid_type_error: 'fee token symbol must be a string'
12884
- }).min(1, 'fee token symbol must be a non-empty string').optional()
12885
- });
12886
12988
  /**
12887
12989
  * Developer fee item schema with basis field.
12888
12990
  */ const createSwapDeveloperFeeItemSchema = createSwapFeeItemSchema.extend({
@@ -13020,6 +13122,8 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
13020
13122
  correlationId: zod.z.preprocess((value)=>zod.z.string().uuid().safeParse(value).success ? value : undefined, zod.z.string().optional()),
13021
13123
  config: createSwapRequestBaseSchema.shape.config.optional(),
13022
13124
  fees: createSwapFeesSchema.optional(),
13125
+ // A route the SDK cannot parse is dropped instead of failing the swap.
13126
+ route: withFallback(responseSwapRouteSchema.optional(), undefined),
13023
13127
  transaction: createSwapTransactionSchema
13024
13128
  });
13025
13129
 
@@ -16262,6 +16366,16 @@ createTokenRegistry();
16262
16366
  name: 'USDC',
16263
16367
  version: '2'
16264
16368
  },
16369
+ Cronos: {
16370
+ chainId: Cronos.chainId,
16371
+ name: 'USDC',
16372
+ version: '2'
16373
+ },
16374
+ Morph: {
16375
+ chainId: Morph.chainId,
16376
+ name: 'USDC',
16377
+ version: '2'
16378
+ },
16265
16379
  Arc_Testnet: {
16266
16380
  chainId: ArcTestnet.chainId,
16267
16381
  name: 'USDC',
@@ -16350,6 +16464,7 @@ const optionalSwapChainIdentifierField = swapChainIdentifierField.optional();
16350
16464
  * - customFee: Optional fee configuration
16351
16465
  * - apiKey: Optional credential string
16352
16466
  * - kitKey: Optional credential string (deprecated alias for apiKey)
16467
+ * - batchTransactions: Optional boolean to opt out of atomic batching
16353
16468
  */ const swapConfigSchema = zod.z.object({
16354
16469
  allowanceStrategy: allowanceStrategySchema.optional(),
16355
16470
  slippageBps: zod.z.number().int().min(0).optional(),
@@ -16360,7 +16475,10 @@ const optionalSwapChainIdentifierField = swapChainIdentifierField.optional();
16360
16475
  })(zod.z.string())).optional(),
16361
16476
  customFee: swapCustomFeeSchema.optional(),
16362
16477
  apiKey: zod.z.string().optional(),
16363
- kitKey: zod.z.string().optional()
16478
+ kitKey: zod.z.string().optional(),
16479
+ batchTransactions: zod.z.boolean({
16480
+ invalid_type_error: 'batchTransactions must be a boolean'
16481
+ }).optional()
16364
16482
  });
16365
16483
  const swapDestinationSchema = zod.z.object({
16366
16484
  chain: optionalSwapChainIdentifierField,
@@ -16553,7 +16671,7 @@ new Set(Object.values(Blockchain));
16553
16671
  registerKit(`${pkg$2.name}/${pkg$2.version}`);
16554
16672
 
16555
16673
  var name$1 = "@circle-fin/earn-kit";
16556
- var version$1 = "1.8.1";
16674
+ var version$1 = "1.10.0";
16557
16675
  var pkg$1 = {
16558
16676
  name: name$1,
16559
16677
  version: version$1};
@@ -18057,7 +18175,7 @@ registerKit(`${pkg$1.name}/${pkg$1.version}`);
18057
18175
  };
18058
18176
 
18059
18177
  var name = "@circle-fin/borrow-kit";
18060
- var version = "1.0.0";
18178
+ var version = "1.1.1";
18061
18179
  var pkg = {
18062
18180
  name: name,
18063
18181
  version: version};
package/borrow.d.cts CHANGED
@@ -899,10 +899,10 @@ declare enum Blockchain {
899
899
  *
900
900
  * Unlike the full {@link Blockchain} enum, SwapChain includes mainnet
901
901
  * networks and explicitly whitelisted testnets (e.g., {@link Arc_Testnet})
902
- * where adapter contracts are deployed (CCTPv2 support).
902
+ * where Adapter contracts are deployed.
903
903
  *
904
904
  * Dynamic validation via {@link isSwapSupportedChain} ensures chains
905
- * automatically work when adapter contracts and supported tokens are deployed.
905
+ * automatically work when Adapter contracts and supported tokens are deployed.
906
906
  *
907
907
  * @example
908
908
  * ```typescript
@@ -942,20 +942,22 @@ declare enum SwapChain {
942
942
  HyperEVM = "HyperEVM",
943
943
  Monad = "Monad",
944
944
  Arc = "Arc",
945
+ Cronos = "Cronos",
946
+ Morph = "Morph",
945
947
  Arc_Testnet = "Arc_Testnet"
946
948
  }
947
949
  /**
948
950
  * Chain definition that supports swap operations.
949
951
  *
950
952
  * @remarks
951
- * Expanded from 4 to ~18 supported chains based on:
952
- * - CCTPv2 support (adapter contract deployed)
953
+ * Expanded from 4 to supported mainnets and whitelisted testnets based on:
954
+ * - A deployed Adapter contract, configured directly or through CCTP v2
953
955
  * - Mainnet chains plus whitelisted testnets (e.g., Arc Testnet)
954
956
  *
955
957
  * Use `isSwapSupportedChain()` for runtime validation.
956
958
  */
957
959
  type SwapChainDefinition = ChainDefinition & {
958
- chain: Blockchain.Ethereum | Blockchain.Base | Blockchain.Polygon | Blockchain.Solana | Blockchain.Arbitrum | Blockchain.Optimism | Blockchain.Avalanche | Blockchain.Linea | Blockchain.Ink | Blockchain.World_Chain | Blockchain.Unichain | Blockchain.Plume | Blockchain.Sei | Blockchain.Sonic | Blockchain.XDC | Blockchain.HyperEVM | Blockchain.Monad | Blockchain.Arc | Blockchain.Arc_Testnet;
960
+ chain: Blockchain.Ethereum | Blockchain.Base | Blockchain.Polygon | Blockchain.Solana | Blockchain.Arbitrum | Blockchain.Optimism | Blockchain.Avalanche | Blockchain.Linea | Blockchain.Ink | Blockchain.World_Chain | Blockchain.Unichain | Blockchain.Plume | Blockchain.Sei | Blockchain.Sonic | Blockchain.XDC | Blockchain.HyperEVM | Blockchain.Monad | Blockchain.Arc | Blockchain.Cronos | Blockchain.Morph | Blockchain.Arc_Testnet;
959
961
  };
960
962
  /**
961
963
  * Chain identifier accepted by swap operations.
@@ -8667,7 +8669,7 @@ interface ServiceSwapConfig {
8667
8669
  *
8668
8670
  * @defaultValue true
8669
8671
  */
8670
- batchTransactions?: boolean;
8672
+ batchTransactions?: boolean | undefined;
8671
8673
  }
8672
8674
  /**
8673
8675
  * Parameters for initiating a swap operation through the Stablecoin Service.
@@ -9131,6 +9133,33 @@ interface SwapConfig {
9131
9133
  * `apiKey` is omitted, and `apiKey` takes precedence when both are set.
9132
9134
  */
9133
9135
  kitKey?: string;
9136
+ /**
9137
+ * Enable or disable atomic batched execution of the approval and swap.
9138
+ *
9139
+ * When `true` (or omitted), an EVM swap that needs an on-chain ERC-20
9140
+ * approval submits the approval and the swap as one atomic batch if the
9141
+ * connected wallet supports it (EIP-5792, or a signing strategy that
9142
+ * declares atomic batching). Set to `false` to force the sequential
9143
+ * approve-then-swap flow.
9144
+ *
9145
+ * @remarks
9146
+ * Has no effect on the gasless permit path, native-token swaps, or Solana,
9147
+ * which already execute as a single transaction. USDT input always uses the
9148
+ * sequential path because its allowance must be reset to zero first. The
9149
+ * batched path relies on the wallet's own gas estimation for the swap call;
9150
+ * set `false` if your wallet under-estimates gas for complex routes or
9151
+ * rejects batched calls.
9152
+ *
9153
+ * @defaultValue `undefined` (batching attempted when the wallet supports it)
9154
+ *
9155
+ * @example
9156
+ * ```typescript
9157
+ * const config: SwapConfig = {
9158
+ * batchTransactions: false, // force sequential approve → swap
9159
+ * }
9160
+ * ```
9161
+ */
9162
+ batchTransactions?: boolean | undefined;
9134
9163
  }
9135
9164
  /**
9136
9165
  * Resolved parameters for swap operations after validation and normalization.
@@ -10117,11 +10146,11 @@ interface AppKitContext {
10117
10146
  */
10118
10147
  actions: Record<'bridge' | 'earn' | 'borrow', Record<string, ((payload: unknown) => void)[]>>;
10119
10148
  /**
10120
- * Disable success analytics for the underlying EarnKit, SwapKit,
10149
+ * Disable success analytics for the underlying BridgeKit, EarnKit, SwapKit,
10121
10150
  * BorrowKit, and UnifiedBalanceKit.
10122
10151
  *
10123
- * When `true`, completed earn, swap, borrow, and unified balance operations
10124
- * will not POST analytics events. This does not disable error reporting; use
10152
+ * When `true`, completed bridge, earn, swap, borrow, and unified balance
10153
+ * operations will not POST analytics events. This does not disable error reporting; use
10125
10154
  * {@link AppKitContext.disableErrorReporting} for that. Defaults to `false`.
10126
10155
  *
10127
10156
  * @defaultValue false
package/borrow.d.mts CHANGED
@@ -899,10 +899,10 @@ declare enum Blockchain {
899
899
  *
900
900
  * Unlike the full {@link Blockchain} enum, SwapChain includes mainnet
901
901
  * networks and explicitly whitelisted testnets (e.g., {@link Arc_Testnet})
902
- * where adapter contracts are deployed (CCTPv2 support).
902
+ * where Adapter contracts are deployed.
903
903
  *
904
904
  * Dynamic validation via {@link isSwapSupportedChain} ensures chains
905
- * automatically work when adapter contracts and supported tokens are deployed.
905
+ * automatically work when Adapter contracts and supported tokens are deployed.
906
906
  *
907
907
  * @example
908
908
  * ```typescript
@@ -942,20 +942,22 @@ declare enum SwapChain {
942
942
  HyperEVM = "HyperEVM",
943
943
  Monad = "Monad",
944
944
  Arc = "Arc",
945
+ Cronos = "Cronos",
946
+ Morph = "Morph",
945
947
  Arc_Testnet = "Arc_Testnet"
946
948
  }
947
949
  /**
948
950
  * Chain definition that supports swap operations.
949
951
  *
950
952
  * @remarks
951
- * Expanded from 4 to ~18 supported chains based on:
952
- * - CCTPv2 support (adapter contract deployed)
953
+ * Expanded from 4 to supported mainnets and whitelisted testnets based on:
954
+ * - A deployed Adapter contract, configured directly or through CCTP v2
953
955
  * - Mainnet chains plus whitelisted testnets (e.g., Arc Testnet)
954
956
  *
955
957
  * Use `isSwapSupportedChain()` for runtime validation.
956
958
  */
957
959
  type SwapChainDefinition = ChainDefinition & {
958
- chain: Blockchain.Ethereum | Blockchain.Base | Blockchain.Polygon | Blockchain.Solana | Blockchain.Arbitrum | Blockchain.Optimism | Blockchain.Avalanche | Blockchain.Linea | Blockchain.Ink | Blockchain.World_Chain | Blockchain.Unichain | Blockchain.Plume | Blockchain.Sei | Blockchain.Sonic | Blockchain.XDC | Blockchain.HyperEVM | Blockchain.Monad | Blockchain.Arc | Blockchain.Arc_Testnet;
960
+ chain: Blockchain.Ethereum | Blockchain.Base | Blockchain.Polygon | Blockchain.Solana | Blockchain.Arbitrum | Blockchain.Optimism | Blockchain.Avalanche | Blockchain.Linea | Blockchain.Ink | Blockchain.World_Chain | Blockchain.Unichain | Blockchain.Plume | Blockchain.Sei | Blockchain.Sonic | Blockchain.XDC | Blockchain.HyperEVM | Blockchain.Monad | Blockchain.Arc | Blockchain.Cronos | Blockchain.Morph | Blockchain.Arc_Testnet;
959
961
  };
960
962
  /**
961
963
  * Chain identifier accepted by swap operations.
@@ -8667,7 +8669,7 @@ interface ServiceSwapConfig {
8667
8669
  *
8668
8670
  * @defaultValue true
8669
8671
  */
8670
- batchTransactions?: boolean;
8672
+ batchTransactions?: boolean | undefined;
8671
8673
  }
8672
8674
  /**
8673
8675
  * Parameters for initiating a swap operation through the Stablecoin Service.
@@ -9131,6 +9133,33 @@ interface SwapConfig {
9131
9133
  * `apiKey` is omitted, and `apiKey` takes precedence when both are set.
9132
9134
  */
9133
9135
  kitKey?: string;
9136
+ /**
9137
+ * Enable or disable atomic batched execution of the approval and swap.
9138
+ *
9139
+ * When `true` (or omitted), an EVM swap that needs an on-chain ERC-20
9140
+ * approval submits the approval and the swap as one atomic batch if the
9141
+ * connected wallet supports it (EIP-5792, or a signing strategy that
9142
+ * declares atomic batching). Set to `false` to force the sequential
9143
+ * approve-then-swap flow.
9144
+ *
9145
+ * @remarks
9146
+ * Has no effect on the gasless permit path, native-token swaps, or Solana,
9147
+ * which already execute as a single transaction. USDT input always uses the
9148
+ * sequential path because its allowance must be reset to zero first. The
9149
+ * batched path relies on the wallet's own gas estimation for the swap call;
9150
+ * set `false` if your wallet under-estimates gas for complex routes or
9151
+ * rejects batched calls.
9152
+ *
9153
+ * @defaultValue `undefined` (batching attempted when the wallet supports it)
9154
+ *
9155
+ * @example
9156
+ * ```typescript
9157
+ * const config: SwapConfig = {
9158
+ * batchTransactions: false, // force sequential approve → swap
9159
+ * }
9160
+ * ```
9161
+ */
9162
+ batchTransactions?: boolean | undefined;
9134
9163
  }
9135
9164
  /**
9136
9165
  * Resolved parameters for swap operations after validation and normalization.
@@ -10117,11 +10146,11 @@ interface AppKitContext {
10117
10146
  */
10118
10147
  actions: Record<'bridge' | 'earn' | 'borrow', Record<string, ((payload: unknown) => void)[]>>;
10119
10148
  /**
10120
- * Disable success analytics for the underlying EarnKit, SwapKit,
10149
+ * Disable success analytics for the underlying BridgeKit, EarnKit, SwapKit,
10121
10150
  * BorrowKit, and UnifiedBalanceKit.
10122
10151
  *
10123
- * When `true`, completed earn, swap, borrow, and unified balance operations
10124
- * will not POST analytics events. This does not disable error reporting; use
10152
+ * When `true`, completed bridge, earn, swap, borrow, and unified balance
10153
+ * operations will not POST analytics events. This does not disable error reporting; use
10125
10154
  * {@link AppKitContext.disableErrorReporting} for that. Defaults to `false`.
10126
10155
  *
10127
10156
  * @defaultValue false