@circle-fin/app-kit 1.8.1 → 1.10.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 (48) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/README.md +3 -3
  3. package/bridge.cjs +1102 -260
  4. package/bridge.d.cts +161 -10
  5. package/bridge.d.mts +161 -10
  6. package/bridge.d.ts +161 -10
  7. package/bridge.mjs +1102 -260
  8. package/chains.cjs +102 -2
  9. package/chains.d.cts +3 -0
  10. package/chains.d.mts +3 -0
  11. package/chains.d.ts +3 -0
  12. package/chains.mjs +102 -2
  13. package/context.cjs +1 -0
  14. package/context.d.cts +166 -12
  15. package/context.d.mts +166 -12
  16. package/context.d.ts +166 -12
  17. package/context.mjs +1 -0
  18. package/earn.cjs +1074 -454
  19. package/earn.d.cts +546 -99
  20. package/earn.d.mts +546 -99
  21. package/earn.d.ts +546 -99
  22. package/earn.mjs +1074 -455
  23. package/estimateBridge.cjs +1102 -260
  24. package/estimateBridge.d.cts +161 -10
  25. package/estimateBridge.d.mts +161 -10
  26. package/estimateBridge.d.ts +161 -10
  27. package/estimateBridge.mjs +1102 -260
  28. package/estimateSwap.cjs +915 -96
  29. package/estimateSwap.d.cts +161 -10
  30. package/estimateSwap.d.mts +161 -10
  31. package/estimateSwap.d.ts +161 -10
  32. package/estimateSwap.mjs +915 -96
  33. package/index.cjs +3029 -862
  34. package/index.d.cts +1277 -143
  35. package/index.d.mts +1277 -143
  36. package/index.d.ts +1277 -143
  37. package/index.mjs +3029 -862
  38. package/package.json +12 -6
  39. package/swap.cjs +915 -96
  40. package/swap.d.cts +161 -10
  41. package/swap.d.mts +161 -10
  42. package/swap.d.ts +161 -10
  43. package/swap.mjs +915 -96
  44. package/unifiedBalance.cjs +822 -115
  45. package/unifiedBalance.d.cts +224 -4
  46. package/unifiedBalance.d.mts +224 -4
  47. package/unifiedBalance.d.ts +224 -4
  48. package/unifiedBalance.mjs +822 -115
package/CHANGELOG.md CHANGED
@@ -1,5 +1,64 @@
1
1
  # @circle-fin/app-kit
2
2
 
3
+ ## 1.10.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Emit earn step events from `AppKit.on()` / `off()` and add `kit.earn.retry()` for resumable multi-phase earn failures.
8
+ - Add `setFeeRecipients()` / `removeFeeRecipients()` on `appKit.unifiedBalance`. Declare fee recipient addresses per chain type (`{ evm, solana }`) instead of writing per-chain branching logic in a `resolveFeeRecipientAddress` callback. Mirrors the same methods added to `@circle-fin/unified-balance-kit`.
9
+ - Surface bridge quote metadata and quote-expired errors for cross-chain Earn deposits.
10
+
11
+ Cross-chain deposit results now include optional `quoteIssuedAt` and `quoteExpiry` metadata so applications can display quote validity and refresh before expiration. Expired quotes are surfaced as fatal `EarnError.BRIDGE_QUOTE_EXPIRED` errors, signaling that callers should start a new prepare/deposit flow instead of retrying stale prepared data.
12
+
13
+ - Swap no longer requires a Stablecoin Service kit key. You can now call `swap`, `estimateSwap`, `getSwapStatus`, `getTokenRates`, and `waitForSwap` without one — unblocking client-side and browser apps that can't safely ship a secret key.
14
+
15
+ This is non-breaking: if you already pass a `kitKey` it keeps working unchanged (and an invalid key is still rejected). To go keyless, omit `kitKey` from your config.
16
+
17
+ ### Patch Changes
18
+
19
+ - Deposit and withdrawal quotes now report the gas-fee estimate provided by the Earn Service instead of estimating it in the SDK. Previously the SDK estimated gas locally by simulating each action against current on-chain state, so the deposit or withdrawal entry could come back as `fees: null` with a revert error whenever a token approval had not yet been made — the Earn Service estimates gas for those actions, so quotes now return a usable gas fee in that case. Claim-rewards quotes do not carry a gas estimate (the service does not provide one), so their `gasFees` is now always empty. The response shape is unchanged (`EarnGasFeeEstimate[]`).
20
+ - Format cross-chain swap fees against the chain the fee token is denominated on. Swap, provider, and developer fees paid in the destination (output) token were resolved against the source chain, so the token symbol and decimals could not be found and the amount was returned as raw base units. This was most visible for Solana → any-chain swaps (e.g. a swap fee paid in EURC on Base surfaced as `'13202'` instead of `'0.013202'`). Fees now prefer the `decimals`/`symbol` the service supplies on each fee item, and otherwise resolve against whichever of the source or destination chain recognises the fee token, so amounts are consistently human-readable.
21
+ - Fix automatic allocation (`amountIn`) sometimes failing with an insufficient-balance error even when your balance was sufficient.
22
+
23
+ When you let the SDK choose which chains to draw from (passing `amountIn` instead of explicit `allocations`), a transfer could be rejected with `BALANCE_INSUFFICIENT_TOKEN` (9001) even though you held enough USDC, and topping up did not help.
24
+
25
+ Auto-allocation now accounts for the network's actual gas fee before submitting, so these transfers go through. If your balance genuinely cannot cover the amount plus gas, you now get a clear `BALANCE_INSUFFICIENT_GAS` (9002) error naming the affected chain and the shortfall, instead of an opaque rejection — reduce the amount or add USDC on that chain. Transfers with explicit `allocations` are unchanged, and there is no extra latency unless a correction is actually needed.
26
+
27
+ - Swaps that require an ERC-20 approval now submit the approval and the swap as a single atomic batch when your wallet supports it — one signing prompt instead of two for smart-contract wallets. Native-token and gasless permit swaps are unchanged.
28
+
29
+ ## 1.9.0
30
+
31
+ ### Minor Changes
32
+
33
+ - Add support for bridging USDC to and from Cronos (mainnet and testnet) via CCTP v2.
34
+ - Support `token: 'EURC'` in App Kit `send()` and `estimateSend()`.
35
+
36
+ `EURC` is now a recognized token alias alongside `USDC`, `USDT`, and `NATIVE`.
37
+ On chains where EURC is deployed (the chain definition's `eurcAddress` is set,
38
+ e.g. Arc Testnet), `send({ token: 'EURC', ... })` resolves the EURC contract
39
+ address and routes the transfer through the generic token transfer action with
40
+ 6 decimals. On chains without an `eurcAddress`, `EURC` is rejected with an
41
+ `INPUT_UNSUPPORTED_TOKEN` error.
42
+
43
+ Previously `send()` rejected `token: 'EURC'` outright — even on chains where
44
+ EURC was configured — because `EURC` was not in the send token alias list.
45
+
46
+ - Add a `headers` config option to forward custom HTTP headers with CCTP
47
+ attestation API requests.
48
+
49
+ `CCTPV2Config`, `BridgeKitConfig`, and the AppKit context now accept an optional
50
+ `headers` map. The headers are sent with every Circle attestation (Iris) API
51
+ request the CCTP v2 provider makes — attestation fetch, re-attestation, and
52
+ relayer mint status polling — and are merged on top of the SDK defaults (such
53
+ as `Content-Type`) rather than replacing them.
54
+
55
+ ### Patch Changes
56
+
57
+ - Fix withdrawal fee metadata being dropped, and correctly surface errors for pending profit-and-loss (PnL) calculations.
58
+ - Fix a missing runtime dependency (`@coral-xyz/anchor`, `@noble/curves`, `bn.js`,
59
+ `@ethersproject/keccak256`, and `pino`) that could cause `Could not find package`
60
+ errors under strict module resolvers (Deno, Supabase Edge Runtime, pnpm).
61
+
3
62
  ## 1.8.1
4
63
 
5
64
  ### Patch Changes
@@ -68,6 +127,7 @@
68
127
 
69
128
  - Enable Circle's Forwarding Service as a destination for Solana (mainnet and devnet). A Gateway `spend` with `useForwarder: true` to a Solana destination is now accepted instead of being rejected.
70
129
  - Add cross-chain swap support to SwapKit, AppKit, and the Stablecoin Service swap provider.
130
+
71
131
  - `swap` and `estimate` can now route the output token to another supported chain with `to.chain`.
72
132
  - Cross-chain swaps can send the output to a recipient on the destination chain with `to.recipientAddress`.
73
133
  - `getSwapStatus` and `waitForSwap` can now track cross-chain swaps until they finish, including progress details for source and destination activity.
@@ -75,6 +135,7 @@
75
135
  - Invalid transaction hashes or unsupported chain values are reported as structured validation errors before a status request is sent.
76
136
 
77
137
  - Add `getTokenRates` to SwapKit and AppKit for fetching USD rates for tokens on a chain.
138
+
78
139
  - Look up rates by registered token symbol, native token alias (`NATIVE`, `ETH`, `POL`, etc.), raw EVM token address, or Solana mint.
79
140
  - Token symbols are resolved through the kit token registry for the requested chain.
80
141
  - Native tokens are normalized to the service native-token address before the request is sent.
@@ -88,6 +149,7 @@
88
149
  | Code | Name | Type | Recoverability |
89
150
  | ------ | ------------- | --------- | -------------- |
90
151
  | `8104` | `EARN_PAUSED` | `SERVICE` | `RETRYABLE` |
152
+
91
153
  - `@circle-fin/earn-kit` / `@circle-fin/app-kit`: the publicly re-exported
92
154
  `EarnError` registry now includes `EARN_PAUSED`. Consumers that branch on
93
155
  `EarnError` (or on `recoverability`) gain this value and can detect the
@@ -133,6 +195,7 @@
133
195
  A cross-chain `deposit()` returns an `execId` while the bridge (source burn ->
134
196
  CCTP attestation -> destination mint) is still settling. Two new kit methods let
135
197
  you follow it:
198
+
136
199
  - `kit.getCrossChainDepositStatus({ execId })` - read the deposit's current
137
200
  bridge status (source, CCTP, and destination hops) once.
138
201
  - `kit.waitForCrossChainDeposit({ execId, pollIntervalMs?, maxWaitMs?, signal? })`
@@ -150,6 +213,7 @@
150
213
  - Surface the source-collected bridge fees in cross-chain Earn deposit quotes, and let callers pick the CCTP transfer speed.
151
214
 
152
215
  New:
216
+
153
217
  - `getDepositQuote` now accepts a cross-chain variant: pass a destination `chain` and `address` that differ from `from.chain` (same `SameChain` / `CrossChain` discriminator pattern as `deposit()`). Same-chain quotes are unchanged.
154
218
  - Cross-chain quotes return the source-collected bridge fees in `EarnDepositQuoteInfo.fees` as one entry per fee item. Each entry carries its own `type` (e.g. `'FORWARD'`, `'PRE_FINALITY'`) and `status` (e.g. `'estimated'` for a pre-sign estimate). Same-chain quotes return `fees: []`.
155
219
  - Cross-chain `deposit()` and `getDepositQuote()` accept an optional `transferSpeed` (`'FAST'` | `'SLOW'`), forwarded to the bridge prepare request so the quote prices — and the deposit burns — the chosen CCTP finality path.
@@ -159,6 +223,7 @@
159
223
  - The cross-chain pre-sign value guard is now fee-aware: the prepared bundle's `feeQuote` (`feeToken` + `items[]`) is parsed, the fee token is pinned to the source token contract, and the signed authorization `value` is checked against `principal + sum(feeQuote.items[].amount)` rather than the principal alone, so fee-bearing deposits are accepted while any other value tampering is still rejected before signing.
160
224
 
161
225
  Notes:
226
+
162
227
  - The cross-chain fees are pre-sign **estimates** sourced from the bridge prepare path; the value shown at quote time may differ from the amount locked at deposit/sign. This is signalled per fee via `status: 'estimated'`.
163
228
  - Existing same-chain `getDepositQuote` callers are unaffected — the response shape is unchanged for same-chain quotes.
164
229
 
@@ -167,6 +232,7 @@
167
232
  Cross-chain deposits use the same nested `from`/`to` input shape as the other kits: `from: { adapter, chain }` is the source signer and `to: { chain, recipientAddress }` is the Earn destination. `from.chain` and `to.chain` are constrained at compile time to the supported route (Ethereum Sepolia, Arbitrum Sepolia, or Base Sepolia as sources; Arc Testnet as the destination), the source adapter must support `signTypedData`, and amounts accept at most 6 decimal places (USDC precision). Cross-chain results report the bridge `execId`, an API-defined bridge lifecycle `status`, `sourceChain`/`destinationChain`, and the prepared bundle expiry.
168
233
 
169
234
  Every published name keeps its existing shape; cross-chain support lands under new names:
235
+
170
236
  - `EarnDepositOutcome` is the new union of `EarnSameChainDepositResult | EarnCrossChainDepositResult`. Narrow with `result.kind === 'cross-chain'` — `kind` is always set at runtime, but optional on the same-chain member so the pre-cross-chain result shape remains assignable.
171
237
  - `AnyDepositParams` (kit) and `AnyDepositServiceParams` (provider) are the new param unions of the same-chain and cross-chain variants; `anyDepositParamsSchema` is the matching validation schema.
172
238
  - `deposit()` gains overloads: same-chain params resolve to `EarnSameChainDepositResult`, cross-chain params to `EarnCrossChainDepositResult`, so existing same-chain call sites keep their narrow result type.
@@ -174,11 +240,13 @@
174
240
  - `EarningProvider` gains an **optional** `supportsCrossChainDeposit(source, destination)` method (mirroring swap-kit's route-aware `supportsRoute`). The kit only routes cross-chain deposits to providers that implement it and return `true`; existing provider implementations keep compiling and never receive cross-chain params.
175
241
 
176
242
  Deprecations (existing aliases keep working):
243
+
177
244
  - `EarnDepositResult` — use `EarnSameChainDepositResult`, or `EarnDepositOutcome` for cross-chain-aware code. This alias may repoint to `EarnDepositOutcome` in the next major.
178
245
  - `DepositParams` / `DepositServiceParams` — use `SameChainDepositParams` / `SameChainDepositServiceParams`, or the `Any*` unions for cross-chain-aware code.
179
246
  - `depositParamsSchema` — use `anyDepositParamsSchema`, which also accepts cross-chain deposit params.
180
247
 
181
248
  Type changes (diagnostic types only):
249
+
182
250
  - `EarnErrorTrace`: the deposit variant's `params` is now `AnyDepositServiceParams`, and `steps` may include `EarnBridgeDepositStep` entries for cross-chain deposits.
183
251
  - `EarningProvider.retry()` and `EarnKit.retry()` may now resolve to `EarnCrossChainDepositResult` when resuming a cross-chain deposit.
184
252
  - `EarnActionName` gains `'crossChainDeposit'`.
@@ -192,6 +260,7 @@
192
260
  - EarnKit now validates amount precision and format locally to match the Earn
193
261
  Service, so malformed amounts fail fast with a clear SDK error instead of a
194
262
  server round-trip.
263
+
195
264
  - Same-chain deposit/withdraw/quote amounts are now capped at 6 decimal places
196
265
  (USDC/EURC), matching the server and the existing cross-chain amount schema.
197
266
  Previously up to 18 decimal places passed local validation and only the
@@ -329,6 +398,7 @@
329
398
  ### Major Changes
330
399
 
331
400
  - Introducing AppKit — a unified SDK for stablecoin operations combining bridging, swapping, and token transfers in one interface.
401
+
332
402
  - `kit.bridge()` — cross-chain USDC transfers via CCTP v2 across 35+ supported chains
333
403
  - `kit.swap()` — same-chain token swaps with smart routing across DEX liquidity sources
334
404
  - `kit.send()` — same-chain transfers for USDC, USDT, native tokens, and any ERC-20/SPL token by contract address
@@ -336,6 +406,7 @@
336
406
  Each operation has a corresponding estimate method (`estimateBridge`, `estimateSwap`, `estimateSend`) to preview fees and output amounts before executing.
337
407
 
338
408
  Additional features:
409
+
339
410
  - Unified developer fee configuration across all operations
340
411
  - Action event system for monitoring operation lifecycle
341
412
  - Tree-shakeable subpath imports (`/bridge`, `/swap`, `/chains`, `/context`)
package/README.md CHANGED
@@ -65,9 +65,9 @@ The App Kit provides a **unified interface** for cross-chain transfers, same-cha
65
65
  - **🔧 Bring your own infrastructure**: Seamlessly integrate with your existing setup when needed
66
66
  - **🔒 Production-ready security**: Leverages Circle's CCTPv2 for bridging and trusted swap providers
67
67
  - **🚀 Developer experience**: Complete TypeScript support, comprehensive validation, and instant connectivity
68
- - **🌍 Multi-chain support**: Bridge across **45 chains** with **968 total bridge routes** through Circle's CCTPv2
69
- - **Mainnet (22 chains)**: Arbitrum, Avalanche, Base, Codex, Edge, Ethereum, HyperEVM, Injective, Ink, Linea, Monad, Morph, OP Mainnet, Pharos, Plume, Polygon PoS, Sei, Solana, Sonic, Unichain, World Chain, XDC
70
- - **Testnet (23 chains)**: Arc Testnet, Arbitrum Sepolia, Avalanche Fuji, Base Sepolia, Codex Testnet, Edge Testnet, Ethereum Sepolia, HyperEVM Testnet, Injective Testnet, Ink Testnet, Linea Sepolia, Monad Testnet, Morph Testnet, OP Sepolia, Pharos Atlantic, Plume Testnet, Polygon PoS Amoy, Sei Testnet, Solana Devnet, Sonic Testnet, Unichain Sepolia, World Chain Sepolia, XDC Apothem
68
+ - **🌍 Multi-chain support**: Bridge across **47 chains** with **1058 total bridge routes** through Circle's CCTPv2
69
+ - **Mainnet (23 chains)**: Arbitrum, Avalanche, Base, Codex, Cronos, Edge, Ethereum, HyperEVM, Injective, Ink, Linea, Monad, Morph, OP Mainnet, Pharos, Plume, Polygon PoS, Sei, Solana, Sonic, Unichain, World Chain, XDC
70
+ - **Testnet (24 chains)**: Arc Testnet, Arbitrum Sepolia, Avalanche Fuji, Base Sepolia, Codex Testnet, Cronos Testnet, Edge Testnet, Ethereum Sepolia, HyperEVM Testnet, Injective Testnet, Ink Testnet, Linea Sepolia, Monad Testnet, Morph Testnet, OP Sepolia, Pharos Atlantic, Plume Testnet, Polygon PoS Amoy, Sei Testnet, Solana Devnet, Sonic Testnet, Unichain Sepolia, World Chain Sepolia, XDC Apothem
71
71
  - **🔄 Swap support**: Same-chain token swaps powered by Circle's Stablecoin Service
72
72
  - **🏦 Earn support**: DeFi lending vault deposits, withdrawals, and reward claims via `kit.earn`
73
73
  - **🎯 Flexible adapters**: Supporting EVM (Viem, Ethers) and Solana (@solana/web3)