@circle-fin/app-kit 1.8.0 → 1.9.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@circle-fin/app-kit",
3
- "version": "1.8.0",
3
+ "version": "1.9.0",
4
4
  "description": "A one-stop Circle SDK solution for building stablecoin (e.g. USDC) applications, with bridging, swapping, and more on-chain operations",
5
5
  "keywords": [
6
6
  "circle",
@@ -36,12 +36,18 @@
36
36
  "module": "./index.mjs",
37
37
  "types": "./index.d.cts",
38
38
  "dependencies": {
39
- "@circle-fin/unified-balance-kit": "1.2.0",
40
- "@circle-fin/provider-gateway-v1": "1.1.0",
41
- "@circle-fin/earn-kit": "1.2.0",
42
- "@circle-fin/bridge-kit": "1.11.0",
43
- "@circle-fin/swap-kit": "1.3.0",
39
+ "@circle-fin/unified-balance-kit": "1.2.2",
40
+ "@circle-fin/provider-gateway-v1": "1.1.2",
41
+ "@circle-fin/earn-kit": "1.2.2",
42
+ "@circle-fin/bridge-kit": "1.12.0",
43
+ "@circle-fin/swap-kit": "1.3.2",
44
+ "@coral-xyz/anchor": "^0.31.1",
45
+ "@noble/curves": "1.4.2",
46
+ "bn.js": "^5.2.3",
47
+ "@ethersproject/keccak256": "^5.8.0",
48
+ "pino": "10.1.0",
44
49
  "zod": "3.25.67",
50
+ "@ethersproject/abi": "^5.8.0",
45
51
  "@ethersproject/address": "^5.8.0",
46
52
  "@ethersproject/bytes": "^5.8.0",
47
53
  "@ethersproject/units": "^5.8.0",
package/swap.cjs CHANGED
@@ -2901,6 +2901,8 @@ class KitError extends Error {
2901
2901
  Blockchain["Celo_Alfajores_Testnet"] = "Celo_Alfajores_Testnet";
2902
2902
  Blockchain["Codex"] = "Codex";
2903
2903
  Blockchain["Codex_Testnet"] = "Codex_Testnet";
2904
+ Blockchain["Cronos"] = "Cronos";
2905
+ Blockchain["Cronos_Testnet"] = "Cronos_Testnet";
2904
2906
  Blockchain["Edge"] = "Edge";
2905
2907
  Blockchain["Edge_Testnet"] = "Edge_Testnet";
2906
2908
  Blockchain["Ethereum"] = "Ethereum";
@@ -2983,6 +2985,7 @@ var BridgeChain;
2983
2985
  BridgeChain["Avalanche"] = "Avalanche";
2984
2986
  BridgeChain["Base"] = "Base";
2985
2987
  BridgeChain["Codex"] = "Codex";
2988
+ BridgeChain["Cronos"] = "Cronos";
2986
2989
  BridgeChain["Edge"] = "Edge";
2987
2990
  BridgeChain["Ethereum"] = "Ethereum";
2988
2991
  BridgeChain["HyperEVM"] = "HyperEVM";
@@ -3007,6 +3010,7 @@ var BridgeChain;
3007
3010
  BridgeChain["Avalanche_Fuji"] = "Avalanche_Fuji";
3008
3011
  BridgeChain["Base_Sepolia"] = "Base_Sepolia";
3009
3012
  BridgeChain["Codex_Testnet"] = "Codex_Testnet";
3013
+ BridgeChain["Cronos_Testnet"] = "Cronos_Testnet";
3010
3014
  BridgeChain["Edge_Testnet"] = "Edge_Testnet";
3011
3015
  BridgeChain["Ethereum_Sepolia"] = "Ethereum_Sepolia";
3012
3016
  BridgeChain["HyperEVM_Testnet"] = "HyperEVM_Testnet";
@@ -4063,6 +4067,96 @@ var EarnChain;
4063
4067
  }
4064
4068
  });
4065
4069
 
4070
+ /**
4071
+ * Cronos Mainnet chain definition
4072
+ * @remarks
4073
+ * This represents the official production network for the Cronos blockchain.
4074
+ * Cronos is an EVM-compatible blockchain.
4075
+ */ const Cronos = defineChain({
4076
+ type: 'evm',
4077
+ chain: Blockchain.Cronos,
4078
+ name: 'Cronos',
4079
+ title: 'Cronos Mainnet',
4080
+ nativeCurrency: {
4081
+ name: 'Cronos',
4082
+ symbol: 'CRO',
4083
+ decimals: 18
4084
+ },
4085
+ chainId: 25,
4086
+ isTestnet: false,
4087
+ explorerUrl: 'https://cronoscan.com/tx/{hash}',
4088
+ rpcEndpoints: [
4089
+ 'https://evm.cronos.org'
4090
+ ],
4091
+ eurcAddress: '0xA6dE01a2d62C6B5f3525d768f34d276652C554c8',
4092
+ usdcAddress: '0x3D7F2C478aAfdB65542BCB44bCeeC05849999d2D',
4093
+ usdtAddress: null,
4094
+ cctp: {
4095
+ domain: 32,
4096
+ contracts: {
4097
+ v2: {
4098
+ type: 'split',
4099
+ tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4100
+ messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4101
+ confirmations: 1,
4102
+ fastConfirmations: 1
4103
+ }
4104
+ },
4105
+ forwarderSupported: {
4106
+ source: false,
4107
+ destination: false
4108
+ }
4109
+ },
4110
+ kitContracts: {
4111
+ bridge: BRIDGE_CONTRACT_EVM_MAINNET
4112
+ }
4113
+ });
4114
+
4115
+ /**
4116
+ * Cronos Testnet chain definition
4117
+ * @remarks
4118
+ * This represents the official test network for the Cronos blockchain.
4119
+ * Cronos is an EVM-compatible blockchain.
4120
+ */ const CronosTestnet = defineChain({
4121
+ type: 'evm',
4122
+ chain: Blockchain.Cronos_Testnet,
4123
+ name: 'Cronos Testnet',
4124
+ title: 'Cronos Testnet',
4125
+ nativeCurrency: {
4126
+ name: 'CRO',
4127
+ symbol: 'tCRO',
4128
+ decimals: 18
4129
+ },
4130
+ chainId: 338,
4131
+ isTestnet: true,
4132
+ explorerUrl: 'https://explorer.cronos.org/testnet/tx/{hash}',
4133
+ rpcEndpoints: [
4134
+ 'https://evm-t3.cronos.org'
4135
+ ],
4136
+ eurcAddress: '0x31f7538adb53cF16350e6B0c89d03D91b7D12c46',
4137
+ usdcAddress: '0xEb33dc5fac03833e132593659e1dE7256aB59794',
4138
+ usdtAddress: null,
4139
+ cctp: {
4140
+ domain: 32,
4141
+ contracts: {
4142
+ v2: {
4143
+ type: 'split',
4144
+ tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
4145
+ messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
4146
+ confirmations: 1,
4147
+ fastConfirmations: 1
4148
+ }
4149
+ },
4150
+ forwarderSupported: {
4151
+ source: false,
4152
+ destination: false
4153
+ }
4154
+ },
4155
+ kitContracts: {
4156
+ bridge: BRIDGE_CONTRACT_EVM_TESTNET
4157
+ }
4158
+ });
4159
+
4066
4160
  /**
4067
4161
  * Edge Mainnet chain definition
4068
4162
  * @remarks
@@ -6414,6 +6508,8 @@ var Chains = {
6414
6508
  CeloAlfajoresTestnet: CeloAlfajoresTestnet,
6415
6509
  Codex: Codex,
6416
6510
  CodexTestnet: CodexTestnet,
6511
+ Cronos: Cronos,
6512
+ CronosTestnet: CronosTestnet,
6417
6513
  Edge: Edge,
6418
6514
  EdgeTestnet: EdgeTestnet,
6419
6515
  Ethereum: Ethereum,
@@ -8463,6 +8559,7 @@ const swapTokenEnumSchema = zod.z.enum([
8463
8559
  [Blockchain.Base]: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
8464
8560
  [Blockchain.Celo]: '0xcebA9300f2b948710d2653dD7B07f33A8B32118C',
8465
8561
  [Blockchain.Codex]: '0xd996633a415985DBd7D6D12f4A4343E31f5037cf',
8562
+ [Blockchain.Cronos]: '0x3D7F2C478aAfdB65542BCB44bCeeC05849999d2D',
8466
8563
  [Blockchain.Edge]: '0x98d2919b9A214E6Fa5384AC81E6864bA686Ad74c',
8467
8564
  [Blockchain.Ethereum]: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
8468
8565
  [Blockchain.Hedera]: '0.0.456858',
@@ -8496,6 +8593,7 @@ const swapTokenEnumSchema = zod.z.enum([
8496
8593
  [Blockchain.Avalanche_Fuji]: '0x5425890298aed601595a70AB815c96711a31Bc65',
8497
8594
  [Blockchain.Base_Sepolia]: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',
8498
8595
  [Blockchain.Codex_Testnet]: '0x6d7f141b6819C2c9CC2f818e6ad549E7Ca090F8f',
8596
+ [Blockchain.Cronos_Testnet]: '0xEb33dc5fac03833e132593659e1dE7256aB59794',
8499
8597
  [Blockchain.Edge_Testnet]: '0x2d9F7CAD728051AA35Ecdc472a14cf8cDF5CFD6B',
8500
8598
  [Blockchain.Ethereum_Sepolia]: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',
8501
8599
  [Blockchain.Hedera_Testnet]: '0.0.429274',
@@ -8563,13 +8661,22 @@ const swapTokenEnumSchema = zod.z.enum([
8563
8661
  symbol: 'EURC',
8564
8662
  decimals: 6,
8565
8663
  locators: {
8664
+ // =========================================================================
8665
+ // Mainnets
8666
+ // =========================================================================
8566
8667
  [Blockchain.Avalanche]: '0xc891EB4cbdEFf6e073e859e987815Ed1505c2ACD',
8567
8668
  [Blockchain.Base]: '0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42',
8669
+ [Blockchain.Cronos]: '0xA6dE01a2d62C6B5f3525d768f34d276652C554c8',
8568
8670
  [Blockchain.Ethereum]: '0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c',
8569
8671
  [Blockchain.Solana]: 'HzwqbKZw8HxMN6bF2yFZNrht3c2iXXzpKcFu7uBEDKtr',
8570
8672
  [Blockchain.World_Chain]: '0x1C60ba0A0eD1019e8Eb035E6daF4155A5cE2380B',
8673
+ // =========================================================================
8571
8674
  // Testnets
8572
- [Blockchain.Arc_Testnet]: '0x89B50855Aa3bE2F677cD6303Cec089B5F319D72a'
8675
+ // =========================================================================
8676
+ [Blockchain.Arc_Testnet]: '0x89B50855Aa3bE2F677cD6303Cec089B5F319D72a',
8677
+ [Blockchain.Base_Sepolia]: '0x808456652fdb597867f38412077A9182bf77359F',
8678
+ [Blockchain.Cronos_Testnet]: '0x31f7538adb53cF16350e6B0c89d03D91b7D12c46',
8679
+ [Blockchain.Ethereum_Sepolia]: '0x08210F9170F89Ab7658F0B5E3fF39b0E03C594D4'
8573
8680
  }
8574
8681
  };
8575
8682
 
@@ -8779,8 +8886,7 @@ const swapTokenEnumSchema = zod.z.enum([
8779
8886
  * cirBTC (Circle Bitcoin) token definition with addresses and metadata.
8780
8887
  *
8781
8888
  * @remarks
8782
- * Built-in cirBTC definition for the TokenRegistry. Currently deployed
8783
- * on Arc Testnet.
8889
+ * Built-in cirBTC definition for the TokenRegistry.
8784
8890
  *
8785
8891
  * @example
8786
8892
  * ```typescript
@@ -8796,7 +8902,15 @@ const swapTokenEnumSchema = zod.z.enum([
8796
8902
  symbol: 'cirBTC',
8797
8903
  decimals: 8,
8798
8904
  locators: {
8799
- [Blockchain.Arc_Testnet]: '0xf0C4a4CE82A5746AbAAd9425360Ab04fbBA432BF'
8905
+ // =========================================================================
8906
+ // Mainnets
8907
+ // =========================================================================
8908
+ [Blockchain.Ethereum]: '0x72DFB2E44f59C5AD2bAFE84314E5b99a7cd5075E',
8909
+ // =========================================================================
8910
+ // Testnets
8911
+ // =========================================================================
8912
+ [Blockchain.Arc_Testnet]: '0xf0C4a4CE82A5746AbAAd9425360Ab04fbBA432BF',
8913
+ [Blockchain.Ethereum_Sepolia]: '0x3a3fe695F684Bf9b9e43CF43C2b895Ea5e392bB3'
8800
8914
  }
8801
8915
  };
8802
8916
 
@@ -9748,7 +9862,7 @@ const swapTokenEnumSchema = zod.z.enum([
9748
9862
  }
9749
9863
 
9750
9864
  var name$2 = "@circle-fin/bridge-kit";
9751
- var version$2 = "1.11.0";
9865
+ var version$2 = "1.12.0";
9752
9866
  var pkg$2 = {
9753
9867
  name: name$2,
9754
9868
  version: version$2};
@@ -10638,7 +10752,7 @@ var TransferSpeed;
10638
10752
  registerKit(`${pkg$2.name}/${pkg$2.version}`);
10639
10753
 
10640
10754
  var name$1 = "@circle-fin/swap-kit";
10641
- var version$1 = "1.3.0";
10755
+ var version$1 = "1.3.2";
10642
10756
  var pkg$1 = {
10643
10757
  name: name$1,
10644
10758
  version: version$1};
@@ -15044,6 +15158,19 @@ const TOKEN_REGISTRY = createTokenRegistry();
15044
15158
  *
15045
15159
  * @internal
15046
15160
  */ const SUPPORTED_CHAINS = getSwapSupportedChains(Chains);
15161
+ /**
15162
+ * Inter-poll delays (ms) for the same-chain `amountOut` enrichment loop.
15163
+ *
15164
+ * A same-chain swap is already terminal `DONE` once its source transaction
15165
+ * confirms; this short, escalating budget (~5s total across up to four polls)
15166
+ * gives the service a brief window to resolve the output amount before
15167
+ * `swap()` returns. The loop exits the instant `amountOut` is available.
15168
+ */ const SAME_CHAIN_AMOUNT_OUT_POLL_DELAYS_MS = [
15169
+ 1_000,
15170
+ 2_000,
15171
+ 2_000
15172
+ ];
15173
+ const sleep$2 = async (ms)=>new Promise((resolve)=>setTimeout(resolve, ms));
15047
15174
  function buildSwapProgress(statusResult) {
15048
15175
  return {
15049
15176
  status: statusResult.status,
@@ -15063,29 +15190,46 @@ async function fetchSameChainStatusSnapshot({ isCrossChainSwap, txHash, chain, a
15063
15190
  }
15064
15191
  };
15065
15192
  }
15066
- try {
15067
- const statusResult = await getSwapStatus$1({
15068
- txHash,
15069
- chain: chain.chain,
15070
- apiKey
15071
- });
15072
- const progress = buildSwapProgress(statusResult);
15073
- if (statusResult.status === 'DONE' && statusResult.amountOut !== undefined) {
15193
+ // A same-chain swap completes atomically in the source transaction, which
15194
+ // has already been confirmed (and receipt-checked for revert) by the time we
15195
+ // get here. Its terminal status is therefore `DONE`. We briefly poll the
15196
+ // status endpoint to enrich `amountOut`, which the service usually resolves
15197
+ // within a few seconds. A non-DONE/erroneous peek never downgrades the
15198
+ // status — once the short budget is exhausted we return `DONE` without
15199
+ // `amountOut`, and the caller can fetch it later via `getSwapStatus`.
15200
+ for(let attempt = 0;; attempt += 1){
15201
+ try {
15202
+ const statusResult = await getSwapStatus$1({
15203
+ txHash,
15204
+ chain: chain.chain,
15205
+ apiKey
15206
+ });
15207
+ if (statusResult.status === 'DONE' && statusResult.amountOut !== undefined) {
15208
+ return {
15209
+ progress: buildSwapProgress(statusResult),
15210
+ amountOut: statusResult.amountOut
15211
+ };
15212
+ }
15213
+ } catch {
15214
+ // Reachability/parse failure during enrichment — non-fatal; the swap
15215
+ // already succeeded on-chain. `getSwapStatus` already retried transient
15216
+ // network errors internally, so further polling is unlikely to help.
15074
15217
  return {
15075
- progress,
15076
- amountOut: statusResult.amountOut
15218
+ progress: {
15219
+ status: 'DONE'
15220
+ }
15077
15221
  };
15078
15222
  }
15079
- return {
15080
- progress
15081
- };
15082
- } catch {
15083
- // Non-fatal — the swap already succeeded on-chain. status stays PENDING.
15084
- return {
15085
- progress: {
15086
- status: 'PENDING'
15087
- }
15088
- };
15223
+ const delayMs = SAME_CHAIN_AMOUNT_OUT_POLL_DELAYS_MS[attempt];
15224
+ if (delayMs === undefined) {
15225
+ // Budget exhausted — terminal `DONE`, `amountOut` not yet available.
15226
+ return {
15227
+ progress: {
15228
+ status: 'DONE'
15229
+ }
15230
+ };
15231
+ }
15232
+ await sleep$2(delayMs);
15089
15233
  }
15090
15234
  }
15091
15235
  /**
@@ -15963,14 +16107,14 @@ async function fetchSameChainStatusSnapshot({ isCrossChainSwap, txHash, chain, a
15963
16107
  }
15964
16108
  // Build swap fees with adapter-backed formatting for unregistered tokens
15965
16109
  const swapResultFees = serviceResponse.fees ? await this.buildFormattedFees(serviceResponse.fees, chain, destinationChain, adapter, config?.customFee?.recipientAddress) : undefined;
15966
- // Best-effort enrichment: fetch amountOut and provider-reported status.
15967
- // Only performed for same-chain swaps they typically reach DONE within
15968
- // a few seconds of source-tx confirmation, so the peek is useful UX and
15969
- // adds minimal latency. Cross-chain swaps are skipped because the
15970
- // destination mint takes minutes (CCTPv2 attestation), meaning the peek
15971
- // would always return PENDING/WAIT_DESTINATION_TRANSACTION while still
15972
- // burning up to 30s of the load balancer's server-side wait. Callers
15973
- // should use `kit.getSwapStatus()` to poll cross-chain swaps to DONE.
16110
+ // Best-effort enrichment: briefly poll for amountOut on same-chain swaps.
16111
+ // They complete atomically in the (already-confirmed) source tx, so the
16112
+ // result is terminal `DONE` regardless; the short poll only adds amountOut
16113
+ // once the service has resolved it. Cross-chain swaps are skipped because
16114
+ // the destination mint takes minutes (CCTPv2 attestation), so polling would
16115
+ // always return PENDING/WAIT_DESTINATION_TRANSACTION while burning the
16116
+ // budget. Callers should use `kit.getSwapStatus()` to poll cross-chain
16117
+ // swaps to DONE.
15974
16118
  const statusSnapshot = await fetchSameChainStatusSnapshot({
15975
16119
  isCrossChainSwap,
15976
16120
  txHash,
@@ -20272,7 +20416,7 @@ registerKit(`${pkg$1.name}/${pkg$1.version}`);
20272
20416
  };
20273
20417
 
20274
20418
  var name = "@circle-fin/earn-kit";
20275
- var version = "1.2.0";
20419
+ var version = "1.2.2";
20276
20420
  var pkg = {
20277
20421
  name: name,
20278
20422
  version: version};
@@ -20311,20 +20455,7 @@ var pkg = {
20311
20455
  */ ({
20312
20456
  [Blockchain.Arc_Testnet]: CHAIN_TO_API[Blockchain.Arc_Testnet]
20313
20457
  });
20314
- /**
20315
- * Expected EIP-712 domain of the ERC-3009 authorization token per source
20316
- * chain.
20317
- *
20318
- * Cross-chain Earn deposits are USDC-only, but USDC deployments differ on the
20319
- * EIP-712 domain name: newer deployments use `USDC` while older ones (for
20320
- * example Arbitrum Sepolia) kept `USD Coin` from the FiatToken V2 upgrade.
20321
- * These values mirror the bridge service's per-chain domain table and the
20322
- * on-chain `DOMAIN_SEPARATOR` inputs. Asserted before signing so a tampered
20323
- * prepare response cannot point the signature at another token. The
20324
- * `satisfies` check forces a domain entry whenever a source chain is added.
20325
- *
20326
- * @internal
20327
- */ ({
20458
+ ({
20328
20459
  [Blockchain.Arbitrum_Sepolia]: {
20329
20460
  },
20330
20461
  [Blockchain.Base_Sepolia]: {
@@ -20360,6 +20491,7 @@ const hexSignatureSchema = evmSignatureSchema;
20360
20491
  const hexAddressSchema = evmAddressSchema;
20361
20492
  // '0x' prefix + 32 bytes * 2 hex chars.
20362
20493
  const BYTES32_HEX_LENGTH = 66;
20494
+ const bridgeFeeTokenSchema = hexAddressSchema;
20363
20495
  /**
20364
20496
  * Zod schema for a non-negative uint256-like value.
20365
20497
  *
@@ -20646,14 +20778,12 @@ const eip712DomainSchema = eip712DomainSchema$1.extend({
20646
20778
  *
20647
20779
  * The bridge prepare path returns one item per collected source fee (e.g.
20648
20780
  * `PRE_FINALITY` for the fast-burn fee and `FORWARD` for the destination
20649
- * forward fee), all denominated in the shared `feeToken`. The signed
20650
- * authorization `value` is `principal + sum(items[].amount)`, so the pre-sign
20651
- * guard parses these to recompute the expected value. Each item's `amount` is
20652
- * a base-unit decimal string in `feeToken` units.
20781
+ * forward fee), all denominated in the shared `feeToken`. Each item's `amount`
20782
+ * is a base-unit decimal string in `feeToken` units.
20653
20783
  *
20654
20784
  * @internal
20655
20785
  */ const bridgeFeeQuoteSchema = zod.z.object({
20656
- feeToken: hexAddressSchema,
20786
+ feeToken: bridgeFeeTokenSchema,
20657
20787
  items: zod.z.array(zod.z.object({
20658
20788
  type: zod.z.string(),
20659
20789
  amount: uint256LikeSchema
@@ -20669,6 +20799,12 @@ const eip712DomainSchema = eip712DomainSchema$1.extend({
20669
20799
  erc3009TypedData: erc3009TypedDataSchema,
20670
20800
  feeQuote: bridgeFeeQuoteSchema
20671
20801
  }).passthrough();
20802
+ const bridgeDepositPrepareReviewSchema = zod.z.object({
20803
+ sourceChain: zod.z.string(),
20804
+ destinationChain: zod.z.string(),
20805
+ amount: amountJsonSchema,
20806
+ vaultAddress: hexAddressSchema
20807
+ }).passthrough();
20672
20808
  /**
20673
20809
  * Zod schema for the bridge deposit prepare payload.
20674
20810
  *
@@ -20680,7 +20816,7 @@ const eip712DomainSchema = eip712DomainSchema$1.extend({
20680
20816
  execId: bridgeDepositExecIdSchema,
20681
20817
  erc3009TypedData: bridgeDepositPreparedBundleSchema,
20682
20818
  expiresAt: zod.z.string().datetime(),
20683
- review: zod.z.unknown().optional()
20819
+ review: bridgeDepositPrepareReviewSchema
20684
20820
  });
20685
20821
  /**
20686
20822
  * Zod schema for the `POST /v1/earnKit/bridge/deposit/prepare` API response.
@@ -20805,10 +20941,11 @@ const eip712DomainSchema = eip712DomainSchema$1.extend({
20805
20941
  * Zod schema for a fee entry in an EarnKit API response.
20806
20942
  *
20807
20943
  * Shared across deposit and withdrawal responses (and reusable for real
20808
- * charged fees, not just quote estimates). `type` identifies the fee category
20809
- * for cross-chain deposit quotes this is the kits-proxy fee-quote item type
20810
- * (e.g. `'FORWARD'`, `'PRE_FINALITY'`). `status` qualifies the fee (e.g.
20811
- * `'estimated'` for a pre-sign cross-chain fee). Both are omitted on plain fees.
20944
+ * charged fees, not just quote estimates). `type` identifies the fee category.
20945
+ * For cross-chain deposit quotes this is the kits-proxy fee-quote item type
20946
+ * (e.g. `'FORWARD'`, `'PRE_FINALITY'`). For withdrawal quotes, Circle fees use
20947
+ * `type: 'circle'`. `status` qualifies the fee (e.g. `'estimated'` for a
20948
+ * pre-sign cross-chain fee). Both are omitted on plain fees.
20812
20949
  *
20813
20950
  * @internal
20814
20951
  */ const feeSchema = zod.z.object({
@@ -20959,6 +21096,10 @@ const eip712DomainSchema = eip712DomainSchema$1.extend({
20959
21096
  data: exploreVaultsPayloadSchema
20960
21097
  });
20961
21098
 
21099
+ // Intentionally built-ins-only: Earn bridge support is limited to SDK-known
21100
+ // token contracts plus the explicit ERC-3009 domain allowlist below.
21101
+ createTokenRegistry();
21102
+
20962
21103
  /**
20963
21104
  * Shared UTF-8 encoder for building the keccak input in
20964
21105
  * {@link isValidEip55Checksum}, hoisted to module scope to avoid allocating a
@@ -21081,10 +21222,9 @@ const sourceAdapterContextSchema = zod.z.object({
21081
21222
  * Schema for validating human-readable decimal amount strings.
21082
21223
  *
21083
21224
  * Accept positive decimal strings like '100', '100.50', '0.001'. Reject
21084
- * zero, negative, non-numeric, and non-canonical strings. EarnKit
21085
- * same-chain amounts are USDC/EURC (6 decimals), so precision is capped at
21086
- * 6 to match the Earn Service and fail fast locally instead of leaking
21087
- * 7+ decimal-place inputs to the server.
21225
+ * zero, negative, non-numeric, and non-canonical strings. Same-chain
21226
+ * EarnKit vaults can use different asset precisions, so the service enforces
21227
+ * the vault-specific decimal cap after resolving the vault asset.
21088
21228
  *
21089
21229
  * @internal
21090
21230
  */ const amountSchema = zod.z.string({
@@ -21093,32 +21233,15 @@ const sourceAdapterContextSchema = zod.z.object({
21093
21233
  allowZero: false,
21094
21234
  regexMessage: AMOUNT_FORMAT_ERROR_MESSAGE,
21095
21235
  attributeName: 'amount',
21096
- maxDecimals: 6
21097
- })(zod.z.string())).refine((value)=>CANONICAL_AMOUNT_REGEX.test(value), AMOUNT_FORMAT_ERROR_MESSAGE);
21098
- /**
21099
- * Schema for cross-chain deposit amount strings.
21100
- *
21101
- * Cross-chain Earn deposits are USDC-only, and the signed ERC-3009 value is
21102
- * denominated in USDC's 6 decimals. Reject more precise inputs up front so
21103
- * the signed value always equals the requested amount instead of a silent
21104
- * truncation. Non-canonical forms (leading dot, leading zeros) are rejected
21105
- * too, matching the Earn Service.
21106
- *
21107
- * @internal
21108
- */ const crossChainAmountSchema = zod.z.string({
21109
- required_error: 'amount is required'
21110
- }).min(1, 'amount is required').pipe(createDecimalStringValidator({
21111
- allowZero: false,
21112
- regexMessage: AMOUNT_FORMAT_ERROR_MESSAGE,
21113
- attributeName: 'amount',
21114
- maxDecimals: 6
21236
+ maxDecimals: 18
21115
21237
  })(zod.z.string())).refine((value)=>CANONICAL_AMOUNT_REGEX.test(value), AMOUNT_FORMAT_ERROR_MESSAGE);
21116
21238
  /**
21117
21239
  * Schema for cross-chain source fee caps.
21118
21240
  *
21119
- * Cross-chain source fees are denominated in USDC base units. Zero is valid
21120
- * when the quote contains no source-collected fees; otherwise the cap should be
21121
- * the caller-accepted total from a recent quote.
21241
+ * Cross-chain source fees are denominated in the quote's fee token. Zero is
21242
+ * valid when the quote contains no source-collected fees; otherwise the cap
21243
+ * should be the caller-accepted total from a recent quote. The provider
21244
+ * enforces the prepared bundle's fee-token precision before signing.
21122
21245
  *
21123
21246
  * @internal
21124
21247
  */ const crossChainMaxFeeSchema = zod.z.string({
@@ -21127,7 +21250,7 @@ const sourceAdapterContextSchema = zod.z.object({
21127
21250
  allowZero: true,
21128
21251
  regexMessage: AMOUNT_FORMAT_ERROR_MESSAGE,
21129
21252
  attributeName: 'maxFee',
21130
- maxDecimals: 6
21253
+ maxDecimals: 18
21131
21254
  })(zod.z.string())).refine((value)=>CANONICAL_AMOUNT_REGEX.test(value), AMOUNT_FORMAT_ERROR_MESSAGE);
21132
21255
  /**
21133
21256
  * Build a schema for an optional non-negative decimal filter string.
@@ -21288,7 +21411,7 @@ const crossChainDepositDestinationSchema = zod.z.object({
21288
21411
  from: sourceAdapterContextSchema,
21289
21412
  to: crossChainDepositDestinationSchema,
21290
21413
  vaultAddress: vaultAddressSchema,
21291
- amount: crossChainAmountSchema,
21414
+ amount: amountSchema,
21292
21415
  maxFee: crossChainMaxFeeSchema,
21293
21416
  transferSpeed: zod.z.enum([
21294
21417
  'FAST',
package/swap.d.cts CHANGED
@@ -659,6 +659,8 @@ declare enum Blockchain {
659
659
  Celo_Alfajores_Testnet = "Celo_Alfajores_Testnet",
660
660
  Codex = "Codex",
661
661
  Codex_Testnet = "Codex_Testnet",
662
+ Cronos = "Cronos",
663
+ Cronos_Testnet = "Cronos_Testnet",
662
664
  Edge = "Edge",
663
665
  Edge_Testnet = "Edge_Testnet",
664
666
  Ethereum = "Ethereum",
@@ -900,6 +902,7 @@ declare enum BridgeChain {
900
902
  Avalanche = "Avalanche",
901
903
  Base = "Base",
902
904
  Codex = "Codex",
905
+ Cronos = "Cronos",
903
906
  Edge = "Edge",
904
907
  Ethereum = "Ethereum",
905
908
  HyperEVM = "HyperEVM",
@@ -923,6 +926,7 @@ declare enum BridgeChain {
923
926
  Avalanche_Fuji = "Avalanche_Fuji",
924
927
  Base_Sepolia = "Base_Sepolia",
925
928
  Codex_Testnet = "Codex_Testnet",
929
+ Cronos_Testnet = "Cronos_Testnet",
926
930
  Edge_Testnet = "Edge_Testnet",
927
931
  Ethereum_Sepolia = "Ethereum_Sepolia",
928
932
  HyperEVM_Testnet = "HyperEVM_Testnet",
@@ -6283,8 +6287,8 @@ interface CrossChainDepositParams<TFromAdapterCapabilities extends AdapterCapabi
6283
6287
  */
6284
6288
  readonly amount: string;
6285
6289
  /**
6286
- * Maximum source-collected bridge fee the caller is willing to sign for, in
6287
- * human-readable source token units.
6290
+ * Maximum source-collected bridge fee the caller is willing to accept, in
6291
+ * human-readable fee token units from the quote.
6288
6292
  *
6289
6293
  * Derive this from a recent cross-chain deposit quote by summing
6290
6294
  * `quote.fees[].amount`. The prepared bridge bundle must not exceed this cap
@@ -6677,6 +6681,16 @@ interface AppKitContext {
6677
6681
  * @defaultValue false
6678
6682
  */
6679
6683
  disableErrorReporting?: boolean;
6684
+ /**
6685
+ * Custom HTTP headers forwarded with the underlying CCTP provider's
6686
+ * attestation (Iris) API requests made by bridge operations.
6687
+ *
6688
+ * @remarks
6689
+ * Headers are merged on top of the SDK defaults (such as `Content-Type`)
6690
+ * rather than replacing them. The header is forwarded as-is to Circle's API;
6691
+ * the SDK does not interpret it.
6692
+ */
6693
+ headers?: Record<string, string>;
6680
6694
  }
6681
6695
 
6682
6696
  /**
package/swap.d.mts CHANGED
@@ -659,6 +659,8 @@ declare enum Blockchain {
659
659
  Celo_Alfajores_Testnet = "Celo_Alfajores_Testnet",
660
660
  Codex = "Codex",
661
661
  Codex_Testnet = "Codex_Testnet",
662
+ Cronos = "Cronos",
663
+ Cronos_Testnet = "Cronos_Testnet",
662
664
  Edge = "Edge",
663
665
  Edge_Testnet = "Edge_Testnet",
664
666
  Ethereum = "Ethereum",
@@ -900,6 +902,7 @@ declare enum BridgeChain {
900
902
  Avalanche = "Avalanche",
901
903
  Base = "Base",
902
904
  Codex = "Codex",
905
+ Cronos = "Cronos",
903
906
  Edge = "Edge",
904
907
  Ethereum = "Ethereum",
905
908
  HyperEVM = "HyperEVM",
@@ -923,6 +926,7 @@ declare enum BridgeChain {
923
926
  Avalanche_Fuji = "Avalanche_Fuji",
924
927
  Base_Sepolia = "Base_Sepolia",
925
928
  Codex_Testnet = "Codex_Testnet",
929
+ Cronos_Testnet = "Cronos_Testnet",
926
930
  Edge_Testnet = "Edge_Testnet",
927
931
  Ethereum_Sepolia = "Ethereum_Sepolia",
928
932
  HyperEVM_Testnet = "HyperEVM_Testnet",
@@ -6283,8 +6287,8 @@ interface CrossChainDepositParams<TFromAdapterCapabilities extends AdapterCapabi
6283
6287
  */
6284
6288
  readonly amount: string;
6285
6289
  /**
6286
- * Maximum source-collected bridge fee the caller is willing to sign for, in
6287
- * human-readable source token units.
6290
+ * Maximum source-collected bridge fee the caller is willing to accept, in
6291
+ * human-readable fee token units from the quote.
6288
6292
  *
6289
6293
  * Derive this from a recent cross-chain deposit quote by summing
6290
6294
  * `quote.fees[].amount`. The prepared bridge bundle must not exceed this cap
@@ -6677,6 +6681,16 @@ interface AppKitContext {
6677
6681
  * @defaultValue false
6678
6682
  */
6679
6683
  disableErrorReporting?: boolean;
6684
+ /**
6685
+ * Custom HTTP headers forwarded with the underlying CCTP provider's
6686
+ * attestation (Iris) API requests made by bridge operations.
6687
+ *
6688
+ * @remarks
6689
+ * Headers are merged on top of the SDK defaults (such as `Content-Type`)
6690
+ * rather than replacing them. The header is forwarded as-is to Circle's API;
6691
+ * the SDK does not interpret it.
6692
+ */
6693
+ headers?: Record<string, string>;
6680
6694
  }
6681
6695
 
6682
6696
  /**