@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@circle-fin/app-kit",
3
- "version": "1.15.3",
3
+ "version": "1.17.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,13 @@
36
36
  "module": "./index.mjs",
37
37
  "types": "./index.d.cts",
38
38
  "dependencies": {
39
- "@circle-fin/onramp-kit": "1.0.2",
40
- "@circle-fin/unified-balance-kit": "1.7.0",
41
- "@circle-fin/provider-gateway-v1": "1.5.0",
42
- "@circle-fin/earn-kit": "1.8.0",
43
- "@circle-fin/bridge-kit": "1.15.1",
44
- "@circle-fin/swap-kit": "1.7.0",
39
+ "@circle-fin/onramp-kit": "1.0.4",
40
+ "@circle-fin/unified-balance-kit": "1.8.1",
41
+ "@circle-fin/provider-gateway-v1": "1.5.2",
42
+ "@circle-fin/earn-kit": "1.9.0",
43
+ "@circle-fin/borrow-kit": "1.1.0",
44
+ "@circle-fin/bridge-kit": "1.15.3",
45
+ "@circle-fin/swap-kit": "1.8.0",
45
46
  "@coral-xyz/anchor": "^0.31.1",
46
47
  "@noble/curves": "1.4.2",
47
48
  "bn.js": "^5.2.3",
@@ -117,6 +118,14 @@
117
118
  "import": "./earn.mjs",
118
119
  "require": "./earn.cjs"
119
120
  },
121
+ "./borrow": {
122
+ "types": {
123
+ "import": "./borrow.d.mts",
124
+ "require": "./borrow.d.cts"
125
+ },
126
+ "import": "./borrow.mjs",
127
+ "require": "./borrow.cjs"
128
+ },
120
129
  "./estimateSwap": {
121
130
  "types": {
122
131
  "import": "./estimateSwap.d.mts",
@@ -152,6 +161,7 @@
152
161
  "estimateSwap.*",
153
162
  "unifiedBalance.*",
154
163
  "earn.*",
164
+ "borrow.*",
155
165
  "index.*",
156
166
  "server.*",
157
167
  "README.md",
package/server.cjs CHANGED
@@ -639,6 +639,34 @@ class KitError extends Error {
639
639
  }
640
640
  };
641
641
 
642
+ /**
643
+ * Render an object value for an error message without letting the rendering
644
+ * itself throw.
645
+ *
646
+ * `JSON.stringify` rejects `BigInt` and circular structures, and a rejected
647
+ * value is exactly the kind of thing a validation error is built from: an
648
+ * on-chain read or a receipt log carries `bigint` fields, so serializing one
649
+ * naively replaces the intended error with a `TypeError`.
650
+ *
651
+ * @param value - The value to render.
652
+ * @returns A JSON string with `bigint` fields stringified, or
653
+ * `'[unserializable object]'` if serialization still fails.
654
+ * @throws Never; serialization failures are caught and rendered as a fallback string.
655
+ * @example
656
+ * ```typescript
657
+ * import { describeObjectValue } from '@core/errors'
658
+ *
659
+ * describeObjectValue({ amount: 1n })
660
+ * // '{"amount":"1"}'
661
+ * ```
662
+ */ function describeObjectValue(value) {
663
+ try {
664
+ return JSON.stringify(value, (_key, entry)=>typeof entry === 'bigint' ? entry.toString() : entry);
665
+ } catch {
666
+ return '[unserializable object]';
667
+ }
668
+ }
669
+
642
670
  /**
643
671
  * Creates error for general validation failure.
644
672
  *
@@ -661,7 +689,7 @@ class KitError extends Error {
661
689
  * // Message: "Validation failed for 'chainId': 999 - Unsupported chain ID"
662
690
  *
663
691
  * throw createValidationFailedError('config', { invalid: true }, 'Missing required properties')
664
- * // Message: "Validation failed for 'config': [object Object] - Missing required properties"
692
+ * // Message: "Validation failed for 'config': {"invalid":true} - Missing required properties"
665
693
  * ```
666
694
  */ function createValidationFailedError(field, value, reason) {
667
695
  // Convert value to string for display, handling different types appropriately
@@ -669,7 +697,7 @@ class KitError extends Error {
669
697
  if (typeof value === 'string') {
670
698
  valueString = `'${value}'`;
671
699
  } else if (typeof value === 'object' && value !== null) {
672
- valueString = JSON.stringify(value);
700
+ valueString = describeObjectValue(value);
673
701
  } else {
674
702
  valueString = String(value);
675
703
  }
@@ -1190,6 +1218,8 @@ var SwapChain;
1190
1218
  SwapChain["HyperEVM"] = "HyperEVM";
1191
1219
  SwapChain["Monad"] = "Monad";
1192
1220
  SwapChain["Arc"] = "Arc";
1221
+ SwapChain["Cronos"] = "Cronos";
1222
+ SwapChain["Morph"] = "Morph";
1193
1223
  // Testnet chains with swap support
1194
1224
  SwapChain["Arc_Testnet"] = "Arc_Testnet";
1195
1225
  })(SwapChain || (SwapChain = {}));
@@ -1321,6 +1351,11 @@ var EarnChain;
1321
1351
  "Arc",
1322
1352
  "Arc_Testnet"
1323
1353
  ];
1354
+ var BorrowChain;
1355
+ (function(BorrowChain) {
1356
+ BorrowChain["Arc"] = "Arc";
1357
+ BorrowChain["Arc_Testnet"] = "Arc_Testnet";
1358
+ })(BorrowChain || (BorrowChain = {}));
1324
1359
 
1325
1360
  /**
1326
1361
  * Helper function to define a chain with proper TypeScript typing.
@@ -1663,6 +1698,29 @@ var EarnChain;
1663
1698
  * on EVM-compatible testnet chains. Use this address for testnet adapter
1664
1699
  * integrations (e.g., Arc Testnet).
1665
1700
  */ const ADAPTER_CONTRACT_EVM_TESTNET = '0xBBD70b01a1CAbc96d5b7b129Ae1AAabdf50dd40b';
1701
+ /**
1702
+ * The sender-preserving batching contract on Arc (`Multicall3From`).
1703
+ *
1704
+ * This predeploy batches calls like the ubiquitous Multicall3, but routes each
1705
+ * subcall through Arc's `CallFrom` precompile
1706
+ * (`0x1800000000000000000000000000000000000003`), which executes on behalf of
1707
+ * the transaction's original sender. Every target therefore sees the calling
1708
+ * EOA as `msg.sender`, which is what makes a plain, un-upgraded EOA capable of
1709
+ * an atomic batch on Arc.
1710
+ *
1711
+ * Deployed at the same address on Arc Testnet and Arc Mainnet.
1712
+ *
1713
+ * @see https://docs.arc.io/arc/concepts/batched-transactions
1714
+ */ const BATCHER_CONTRACT_ARC_TESTNET = '0x522fAf9A91c41c443c66765030741e4AaCe147D0';
1715
+ /**
1716
+ * The sender-preserving batching contract on Arc Mainnet (`Multicall3From`).
1717
+ *
1718
+ * See {@link BATCHER_CONTRACT_ARC_TESTNET} for how this contract works.
1719
+ * Requires Arc's Zero7 hardfork, which activates the `CallFrom` precompile
1720
+ * this contract depends on.
1721
+ *
1722
+ * @see https://docs.arc.io/arc/concepts/batched-transactions
1723
+ */ const BATCHER_CONTRACT_ARC_MAINNET = '0x522fAf9A91c41c443c66765030741e4AaCe147D0';
1666
1724
  /**
1667
1725
  * The GatewayWallet contract address for EVM mainnet networks.
1668
1726
  *
@@ -1802,7 +1860,10 @@ var EarnChain;
1802
1860
  },
1803
1861
  kitContracts: {
1804
1862
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
1805
- adapter: ADAPTER_CONTRACT_EVM_MAINNET
1863
+ adapter: ADAPTER_CONTRACT_EVM_MAINNET,
1864
+ // Arc is the only chain with a sender-preserving batcher, because it
1865
+ // takes a precompile rather than an ordinary contract to build one.
1866
+ senderPreservingBatcher: BATCHER_CONTRACT_ARC_MAINNET
1806
1867
  },
1807
1868
  gateway: {
1808
1869
  domain: 26,
@@ -1873,7 +1934,10 @@ var EarnChain;
1873
1934
  },
1874
1935
  kitContracts: {
1875
1936
  bridge: BRIDGE_CONTRACT_EVM_TESTNET,
1876
- adapter: ADAPTER_CONTRACT_EVM_TESTNET
1937
+ adapter: ADAPTER_CONTRACT_EVM_TESTNET,
1938
+ // Arc is the only chain with a sender-preserving batcher, because it
1939
+ // takes a precompile rather than an ordinary contract to build one.
1940
+ senderPreservingBatcher: BATCHER_CONTRACT_ARC_TESTNET
1877
1941
  },
1878
1942
  gateway: {
1879
1943
  domain: 26,
@@ -2488,7 +2552,8 @@ var EarnChain;
2488
2552
  }
2489
2553
  },
2490
2554
  kitContracts: {
2491
- bridge: BRIDGE_CONTRACT_EVM_MAINNET
2555
+ bridge: BRIDGE_CONTRACT_EVM_MAINNET,
2556
+ adapter: ADAPTER_CONTRACT_EVM_MAINNET
2492
2557
  }
2493
2558
  });
2494
2559
 
@@ -3357,7 +3422,8 @@ var EarnChain;
3357
3422
  }
3358
3423
  },
3359
3424
  kitContracts: {
3360
- bridge: BRIDGE_CONTRACT_EVM_MAINNET
3425
+ bridge: BRIDGE_CONTRACT_EVM_MAINNET,
3426
+ adapter: ADAPTER_CONTRACT_EVM_MAINNET
3361
3427
  }
3362
3428
  });
3363
3429
 
@@ -5291,7 +5357,8 @@ var EarnChain;
5291
5357
  cctpx: zod.z.any().optional(),
5292
5358
  kitContracts: zod.z.object({
5293
5359
  bridge: zod.z.string().optional(),
5294
- adapter: zod.z.string().optional()
5360
+ adapter: zod.z.string().optional(),
5361
+ senderPreservingBatcher: zod.z.string().optional()
5295
5362
  }).optional(),
5296
5363
  gateway: gatewayConfigSchema.optional()
5297
5364
  });
@@ -5402,8 +5469,8 @@ var EarnChain;
5402
5469
  * Zod schema for validating swap-specific chain identifiers.
5403
5470
  *
5404
5471
  * Validates chains based on:
5405
- * - CCTPv2 support (adapter contract deployed)
5406
- * - Mainnet only (no testnets)
5472
+ * - Membership in the SwapChain enum
5473
+ * - Mainnet or explicitly allowlisted testnet
5407
5474
  * - At least one supported token available
5408
5475
  *
5409
5476
  */ zod.z.union([
@@ -5487,6 +5554,38 @@ var EarnChain;
5487
5554
  message: `"${chain.chain}" is not a supported earn chain. ` + `Supported chains: ${Object.values(EarnChain).join(', ')}`
5488
5555
  }))
5489
5556
  ]);
5557
+ /**
5558
+ * Zod schema for validating Borrow-specific chain identifiers.
5559
+ *
5560
+ * Validate that the provided chain is supported for Borrow Kit's loan
5561
+ * operations. Unlike {@link earnChainIdentifierSchema}, this includes Arc
5562
+ * mainnet as well as Arc Testnet.
5563
+ *
5564
+ * Accept a BorrowChain enum value, a matching string literal, or a
5565
+ * ChainDefinition for a supported chain.
5566
+ *
5567
+ * @example
5568
+ * ```typescript
5569
+ * import { borrowChainIdentifierSchema } from '@core/chains'
5570
+ * import { Arc, BorrowChain } from '@core/chains'
5571
+ *
5572
+ * // Valid
5573
+ * borrowChainIdentifierSchema.parse(BorrowChain.Arc)
5574
+ * borrowChainIdentifierSchema.parse('Arc')
5575
+ * borrowChainIdentifierSchema.parse(Arc)
5576
+ *
5577
+ * // Invalid (throws ZodError)
5578
+ * borrowChainIdentifierSchema.parse('Solana')
5579
+ * ```
5580
+ */ zod.z.union([
5581
+ zod.z.string().refine((val)=>val in BorrowChain, (val)=>({
5582
+ message: `"${val}" is not a supported borrow chain. ` + `Supported chains: ${Object.values(BorrowChain).join(', ')}`
5583
+ })),
5584
+ zod.z.nativeEnum(BorrowChain),
5585
+ chainDefinitionSchema.refine((chain)=>chain.chain in BorrowChain, (chain)=>({
5586
+ message: `"${chain.chain}" is not a supported borrow chain. ` + `Supported chains: ${Object.values(BorrowChain).join(', ')}`
5587
+ }))
5588
+ ]);
5490
5589
  // Widened views so `.includes()` accepts arbitrary strings under strict TS.
5491
5590
  const EARN_BRIDGE_SOURCE_CHAIN_VALUES = EARN_BRIDGE_SOURCE_BLOCKCHAINS;
5492
5591
  const EARN_BRIDGE_DESTINATION_CHAIN_VALUES = EARN_BRIDGE_DESTINATION_BLOCKCHAINS;
@@ -6108,11 +6207,13 @@ const swapTokenEnumSchema = zod.z.enum([
6108
6207
  [Blockchain.Arbitrum]: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9',
6109
6208
  [Blockchain.Avalanche]: '0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7',
6110
6209
  [Blockchain.Celo]: '0x48065fbBE25f71C9282ddf5e1cD6D6A887483D5e',
6210
+ [Blockchain.Cronos]: '0x66e428c3f67a68878562e79A0234c1F83c208770',
6111
6211
  [Blockchain.Ethereum]: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
6112
6212
  [Blockchain.HyperEVM]: '0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb',
6113
6213
  [Blockchain.Ink]: '0x0200C29006150606B650577BBE7B6248F58470c1',
6114
6214
  [Blockchain.Linea]: '0xA219439258ca9da29E9Cc4cE5596924745e12B93',
6115
6215
  [Blockchain.Monad]: '0xe7cd86e13AC4309349F30B3435a9d337750fC82D',
6216
+ [Blockchain.Morph]: '0xe7cd86e13AC4309349F30B3435a9d337750fC82D',
6116
6217
  [Blockchain.NEAR]: 'usdt.tether-token.near',
6117
6218
  [Blockchain.Optimism]: '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58',
6118
6219
  [Blockchain.Polkadot_Asset_Hub]: '1984',
@@ -6171,6 +6272,7 @@ const swapTokenEnumSchema = zod.z.enum([
6171
6272
  [Blockchain.Arbitrum]: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1',
6172
6273
  [Blockchain.Avalanche]: '0xd586E7F844cEa2F87f50152665BCbc2C279D8d70',
6173
6274
  [Blockchain.Base]: '0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb',
6275
+ [Blockchain.Cronos]: '0xF2001B145b43032AAF5Ee2884e456CCd805F677D',
6174
6276
  [Blockchain.Ethereum]: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
6175
6277
  [Blockchain.Linea]: '0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5',
6176
6278
  [Blockchain.Optimism]: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1',
@@ -6233,7 +6335,9 @@ const swapTokenEnumSchema = zod.z.enum([
6233
6335
  [Blockchain.Arbitrum]: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1',
6234
6336
  [Blockchain.Avalanche]: '0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB',
6235
6337
  [Blockchain.Base]: '0x4200000000000000000000000000000000000006',
6338
+ [Blockchain.Cronos]: '0xe44Fd7fCb2b1581822D0c862B68222998a0c299a',
6236
6339
  [Blockchain.Ethereum]: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
6340
+ [Blockchain.Morph]: '0x5300000000000000000000000000000000000011',
6237
6341
  [Blockchain.Optimism]: '0x4200000000000000000000000000000000000006',
6238
6342
  [Blockchain.Polygon]: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619',
6239
6343
  [Blockchain.Solana]: '7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs'
@@ -6252,6 +6356,7 @@ const swapTokenEnumSchema = zod.z.enum([
6252
6356
  locators: {
6253
6357
  [Blockchain.Ethereum]: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
6254
6358
  [Blockchain.Arbitrum]: '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f',
6359
+ [Blockchain.Cronos]: '0x062E66477Faf219F25D27dCED647BF57C3107d52',
6255
6360
  [Blockchain.Avalanche]: '0x50b7545627a5162F82A992c33b87aDc75187B218'
6256
6361
  }
6257
6362
  };
@@ -8650,7 +8755,7 @@ const swapTokenEnumSchema = zod.z.enum([
8650
8755
  return kit;
8651
8756
  }
8652
8757
 
8653
- var version = "1.0.2";
8758
+ var version = "1.0.4";
8654
8759
  var pkg = {
8655
8760
  version: version};
8656
8761
 
@@ -9286,7 +9391,7 @@ function isAbortLikeError(err) {
9286
9391
  currency: zod.z.string().min(1).optional(),
9287
9392
  email: zod.z.string().email().optional(),
9288
9393
  assets: onrampAssetSelectionSchema.optional(),
9289
- metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
9394
+ metadata: zod.z.record(zod.z.string(), zod.z.string()).optional()
9290
9395
  });
9291
9396
 
9292
9397
  /**
@@ -9448,7 +9553,7 @@ function isAbortLikeError(err) {
9448
9553
  const widgetUrl = mergeAssetParams(existingWidgetUrl, composedWidgetUrl, assetParams);
9449
9554
  const traceId = typeof session['traceId'] === 'string' ? session['traceId'] : ctx.invocation.traceId;
9450
9555
  // Outbound allow-list. We deliberately rebuild the result from the
9451
- // exact fields the client kit consumes rather than spreading
9556
+ // exact fields the host and client kit consume rather than spreading
9452
9557
  // `...session`. Inbound parsing stays schema-free for forward-compat
9453
9558
  // (an additive upstream field must never break minting), but the
9454
9559
  // server→browser hop is a trust boundary: any internal identifier,
@@ -9467,6 +9572,11 @@ function isAbortLikeError(err) {
9467
9572
  if (typeof session['expiresAt'] === 'string') {
9468
9573
  normalised['expiresAt'] = session['expiresAt'];
9469
9574
  }
9575
+ // From the response only. No fallback to `params.metadata`.
9576
+ const metadata = readMetadataEcho(session['metadata']);
9577
+ if (metadata !== undefined) {
9578
+ normalised['metadata'] = metadata;
9579
+ }
9470
9580
  if (widgetUrl === undefined) {
9471
9581
  // `widgetUrl` is required on `MintedOnrampSession` (guaranteed
9472
9582
  // present). If neither the API returned one nor a `sessionToken`
@@ -9503,6 +9613,17 @@ function isAbortLikeError(err) {
9503
9613
  }
9504
9614
  return url.toString();
9505
9615
  }
9616
+ /**
9617
+ * Copy a plain-object, string-valued `metadata` echo, or drop it whole.
9618
+ *
9619
+ * @internal
9620
+ */ function readMetadataEcho(value) {
9621
+ if (value === null || typeof value !== 'object' || Object.getPrototypeOf(value) !== Object.prototype) {
9622
+ return undefined;
9623
+ }
9624
+ const entries = Object.entries(value);
9625
+ return entries.every(([, entry])=>typeof entry === 'string') ? Object.fromEntries(entries) : undefined;
9626
+ }
9506
9627
  /**
9507
9628
  * Translate the SDK parameter shape into the wallets-api request body.
9508
9629
  *
package/server.d.cts CHANGED
@@ -1801,6 +1801,8 @@ interface KitEventSubscription<M extends EventMap = KitEventMap> {
1801
1801
  * re-mint.
1802
1802
  * - `traceId` — the trace id the server stamped when minting. Echoed
1803
1803
  * back so the client can tag widget events with the same id.
1804
+ * - `metadata`: string map echoed on the create response, when the API
1805
+ * sends one. Forwarded to the browser with the rest of the session.
1804
1806
  */
1805
1807
  interface OnrampSession {
1806
1808
  /**
@@ -1854,6 +1856,18 @@ interface OnrampSession {
1854
1856
  * id.
1855
1857
  */
1856
1858
  readonly traceId?: string;
1859
+ /**
1860
+ * Request `metadata` as the Onramp API echoed it on the create response.
1861
+ *
1862
+ * @remarks
1863
+ * Present only for a well-formed echo, never copied from the request
1864
+ * params, so absence means the API did not echo it. Returned once: not
1865
+ * sealed into the session token or delivered on later events. A host
1866
+ * that forwards the session to the browser (including via
1867
+ * `createSessionRouteHandler`) also forwards this field, so do not put
1868
+ * server-only values in it.
1869
+ */
1870
+ readonly metadata?: Readonly<Record<string, string>>;
1857
1871
  /**
1858
1872
  * Index signature keeping the type tolerant of additive fields.
1859
1873
  *
@@ -1898,9 +1912,8 @@ interface MintedOnrampSession extends OnrampSession {
1898
1912
  * contract.
1899
1913
  *
1900
1914
  * Validation is intentionally conservative: only the fields the kit
1901
- * actually consumes (or rejects on shape grounds) are checked. Free-
1902
- * form fields like `metadata` pass through so wallets-api can layer
1903
- * its own validation on top without the SDK lagging behind.
1915
+ * actually consumes (or rejects on shape grounds) are checked.
1916
+ * `metadata` is a string map. The Onramp API owns its limits.
1904
1917
  *
1905
1918
  * @packageDocumentation
1906
1919
  */
@@ -1943,7 +1956,7 @@ declare const onrampSessionRequestSchema: z.ZodObject<{
1943
1956
  chain: string;
1944
1957
  }[] | undefined;
1945
1958
  }>>;
1946
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1959
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
1947
1960
  }, "strip", z.ZodTypeAny, {
1948
1961
  appUserId: string;
1949
1962
  destinationAddress: string;
@@ -1959,7 +1972,7 @@ declare const onrampSessionRequestSchema: z.ZodObject<{
1959
1972
  chain: string;
1960
1973
  }[] | undefined;
1961
1974
  } | undefined;
1962
- metadata?: Record<string, unknown> | undefined;
1975
+ metadata?: Record<string, string> | undefined;
1963
1976
  }, {
1964
1977
  appUserId: string;
1965
1978
  destinationAddress: string;
@@ -1975,7 +1988,7 @@ declare const onrampSessionRequestSchema: z.ZodObject<{
1975
1988
  chain: string;
1976
1989
  }[] | undefined;
1977
1990
  } | undefined;
1978
- metadata?: Record<string, unknown> | undefined;
1991
+ metadata?: Record<string, string> | undefined;
1979
1992
  }>;
1980
1993
  /**
1981
1994
  * The wire-format request body accepted by the onramp `createSession`
@@ -1999,8 +2012,11 @@ declare const onrampSessionRequestSchema: z.ZodObject<{
1999
2012
  * - `assets`: optional host-app scoping for the asset selector (which
2000
2013
  * token/chain pairs the widget offers). See {@link OnrampAssetSelection}.
2001
2014
  * Baked into the launch URL at mint time; never forwarded to wallets-api.
2002
- * - `metadata`: free-form passthrough — useful for re-stitching the
2003
- * session back to the host's order ledger.
2015
+ * - `metadata`: optional string map. The Onramp API rejects more than 20
2016
+ * keys, keys over 64 characters, values over 1024 characters, and
2017
+ * control characters. It is echoed once on the create response (see
2018
+ * {@link OnrampSession.metadata}) and is not delivered on later widget
2019
+ * events, so use `appUserId` to correlate the user.
2004
2020
  *
2005
2021
  * Note: the embedding-domain allowlist entry (`referrerDomain`) is **not**
2006
2022
  * part of this request. It is a server-only concern configured on
@@ -2030,8 +2046,11 @@ type OnrampSessionRequest = z.infer<typeof onrampSessionRequestSchema>;
2030
2046
  * wallets-api. Pass to pre-select a chain in the widget.
2031
2047
  * - `amount`, `currency`: optional pre-fills.
2032
2048
  * - `email`: optional KYC routing hint.
2033
- * - `metadata`: free-form passthrough — useful for re-stitching the
2034
- * session back to the host's order ledger.
2049
+ * - `metadata`: optional string map. The Onramp API rejects more than 20
2050
+ * keys, keys over 64 characters, values over 1024 characters, and
2051
+ * control characters. It is echoed once on the create response (see
2052
+ * {@link OnrampSession.metadata}) and is not delivered on later widget
2053
+ * events, so use `appUserId` to correlate the user.
2035
2054
  */
2036
2055
  type CreateSessionParams = OnrampSessionRequest;
2037
2056
  /**
package/server.d.mts CHANGED
@@ -1801,6 +1801,8 @@ interface KitEventSubscription<M extends EventMap = KitEventMap> {
1801
1801
  * re-mint.
1802
1802
  * - `traceId` — the trace id the server stamped when minting. Echoed
1803
1803
  * back so the client can tag widget events with the same id.
1804
+ * - `metadata`: string map echoed on the create response, when the API
1805
+ * sends one. Forwarded to the browser with the rest of the session.
1804
1806
  */
1805
1807
  interface OnrampSession {
1806
1808
  /**
@@ -1854,6 +1856,18 @@ interface OnrampSession {
1854
1856
  * id.
1855
1857
  */
1856
1858
  readonly traceId?: string;
1859
+ /**
1860
+ * Request `metadata` as the Onramp API echoed it on the create response.
1861
+ *
1862
+ * @remarks
1863
+ * Present only for a well-formed echo, never copied from the request
1864
+ * params, so absence means the API did not echo it. Returned once: not
1865
+ * sealed into the session token or delivered on later events. A host
1866
+ * that forwards the session to the browser (including via
1867
+ * `createSessionRouteHandler`) also forwards this field, so do not put
1868
+ * server-only values in it.
1869
+ */
1870
+ readonly metadata?: Readonly<Record<string, string>>;
1857
1871
  /**
1858
1872
  * Index signature keeping the type tolerant of additive fields.
1859
1873
  *
@@ -1898,9 +1912,8 @@ interface MintedOnrampSession extends OnrampSession {
1898
1912
  * contract.
1899
1913
  *
1900
1914
  * Validation is intentionally conservative: only the fields the kit
1901
- * actually consumes (or rejects on shape grounds) are checked. Free-
1902
- * form fields like `metadata` pass through so wallets-api can layer
1903
- * its own validation on top without the SDK lagging behind.
1915
+ * actually consumes (or rejects on shape grounds) are checked.
1916
+ * `metadata` is a string map. The Onramp API owns its limits.
1904
1917
  *
1905
1918
  * @packageDocumentation
1906
1919
  */
@@ -1943,7 +1956,7 @@ declare const onrampSessionRequestSchema: z.ZodObject<{
1943
1956
  chain: string;
1944
1957
  }[] | undefined;
1945
1958
  }>>;
1946
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1959
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
1947
1960
  }, "strip", z.ZodTypeAny, {
1948
1961
  appUserId: string;
1949
1962
  destinationAddress: string;
@@ -1959,7 +1972,7 @@ declare const onrampSessionRequestSchema: z.ZodObject<{
1959
1972
  chain: string;
1960
1973
  }[] | undefined;
1961
1974
  } | undefined;
1962
- metadata?: Record<string, unknown> | undefined;
1975
+ metadata?: Record<string, string> | undefined;
1963
1976
  }, {
1964
1977
  appUserId: string;
1965
1978
  destinationAddress: string;
@@ -1975,7 +1988,7 @@ declare const onrampSessionRequestSchema: z.ZodObject<{
1975
1988
  chain: string;
1976
1989
  }[] | undefined;
1977
1990
  } | undefined;
1978
- metadata?: Record<string, unknown> | undefined;
1991
+ metadata?: Record<string, string> | undefined;
1979
1992
  }>;
1980
1993
  /**
1981
1994
  * The wire-format request body accepted by the onramp `createSession`
@@ -1999,8 +2012,11 @@ declare const onrampSessionRequestSchema: z.ZodObject<{
1999
2012
  * - `assets`: optional host-app scoping for the asset selector (which
2000
2013
  * token/chain pairs the widget offers). See {@link OnrampAssetSelection}.
2001
2014
  * Baked into the launch URL at mint time; never forwarded to wallets-api.
2002
- * - `metadata`: free-form passthrough — useful for re-stitching the
2003
- * session back to the host's order ledger.
2015
+ * - `metadata`: optional string map. The Onramp API rejects more than 20
2016
+ * keys, keys over 64 characters, values over 1024 characters, and
2017
+ * control characters. It is echoed once on the create response (see
2018
+ * {@link OnrampSession.metadata}) and is not delivered on later widget
2019
+ * events, so use `appUserId` to correlate the user.
2004
2020
  *
2005
2021
  * Note: the embedding-domain allowlist entry (`referrerDomain`) is **not**
2006
2022
  * part of this request. It is a server-only concern configured on
@@ -2030,8 +2046,11 @@ type OnrampSessionRequest = z.infer<typeof onrampSessionRequestSchema>;
2030
2046
  * wallets-api. Pass to pre-select a chain in the widget.
2031
2047
  * - `amount`, `currency`: optional pre-fills.
2032
2048
  * - `email`: optional KYC routing hint.
2033
- * - `metadata`: free-form passthrough — useful for re-stitching the
2034
- * session back to the host's order ledger.
2049
+ * - `metadata`: optional string map. The Onramp API rejects more than 20
2050
+ * keys, keys over 64 characters, values over 1024 characters, and
2051
+ * control characters. It is echoed once on the create response (see
2052
+ * {@link OnrampSession.metadata}) and is not delivered on later widget
2053
+ * events, so use `appUserId` to correlate the user.
2035
2054
  */
2036
2055
  type CreateSessionParams = OnrampSessionRequest;
2037
2056
  /**
package/server.d.ts CHANGED
@@ -1801,6 +1801,8 @@ interface KitEventSubscription<M extends EventMap = KitEventMap> {
1801
1801
  * re-mint.
1802
1802
  * - `traceId` — the trace id the server stamped when minting. Echoed
1803
1803
  * back so the client can tag widget events with the same id.
1804
+ * - `metadata`: string map echoed on the create response, when the API
1805
+ * sends one. Forwarded to the browser with the rest of the session.
1804
1806
  */
1805
1807
  interface OnrampSession {
1806
1808
  /**
@@ -1854,6 +1856,18 @@ interface OnrampSession {
1854
1856
  * id.
1855
1857
  */
1856
1858
  readonly traceId?: string;
1859
+ /**
1860
+ * Request `metadata` as the Onramp API echoed it on the create response.
1861
+ *
1862
+ * @remarks
1863
+ * Present only for a well-formed echo, never copied from the request
1864
+ * params, so absence means the API did not echo it. Returned once: not
1865
+ * sealed into the session token or delivered on later events. A host
1866
+ * that forwards the session to the browser (including via
1867
+ * `createSessionRouteHandler`) also forwards this field, so do not put
1868
+ * server-only values in it.
1869
+ */
1870
+ readonly metadata?: Readonly<Record<string, string>>;
1857
1871
  /**
1858
1872
  * Index signature keeping the type tolerant of additive fields.
1859
1873
  *
@@ -1898,9 +1912,8 @@ interface MintedOnrampSession extends OnrampSession {
1898
1912
  * contract.
1899
1913
  *
1900
1914
  * Validation is intentionally conservative: only the fields the kit
1901
- * actually consumes (or rejects on shape grounds) are checked. Free-
1902
- * form fields like `metadata` pass through so wallets-api can layer
1903
- * its own validation on top without the SDK lagging behind.
1915
+ * actually consumes (or rejects on shape grounds) are checked.
1916
+ * `metadata` is a string map. The Onramp API owns its limits.
1904
1917
  *
1905
1918
  * @packageDocumentation
1906
1919
  */
@@ -1943,7 +1956,7 @@ declare const onrampSessionRequestSchema: z.ZodObject<{
1943
1956
  chain: string;
1944
1957
  }[] | undefined;
1945
1958
  }>>;
1946
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1959
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
1947
1960
  }, "strip", z.ZodTypeAny, {
1948
1961
  appUserId: string;
1949
1962
  destinationAddress: string;
@@ -1959,7 +1972,7 @@ declare const onrampSessionRequestSchema: z.ZodObject<{
1959
1972
  chain: string;
1960
1973
  }[] | undefined;
1961
1974
  } | undefined;
1962
- metadata?: Record<string, unknown> | undefined;
1975
+ metadata?: Record<string, string> | undefined;
1963
1976
  }, {
1964
1977
  appUserId: string;
1965
1978
  destinationAddress: string;
@@ -1975,7 +1988,7 @@ declare const onrampSessionRequestSchema: z.ZodObject<{
1975
1988
  chain: string;
1976
1989
  }[] | undefined;
1977
1990
  } | undefined;
1978
- metadata?: Record<string, unknown> | undefined;
1991
+ metadata?: Record<string, string> | undefined;
1979
1992
  }>;
1980
1993
  /**
1981
1994
  * The wire-format request body accepted by the onramp `createSession`
@@ -1999,8 +2012,11 @@ declare const onrampSessionRequestSchema: z.ZodObject<{
1999
2012
  * - `assets`: optional host-app scoping for the asset selector (which
2000
2013
  * token/chain pairs the widget offers). See {@link OnrampAssetSelection}.
2001
2014
  * Baked into the launch URL at mint time; never forwarded to wallets-api.
2002
- * - `metadata`: free-form passthrough — useful for re-stitching the
2003
- * session back to the host's order ledger.
2015
+ * - `metadata`: optional string map. The Onramp API rejects more than 20
2016
+ * keys, keys over 64 characters, values over 1024 characters, and
2017
+ * control characters. It is echoed once on the create response (see
2018
+ * {@link OnrampSession.metadata}) and is not delivered on later widget
2019
+ * events, so use `appUserId` to correlate the user.
2004
2020
  *
2005
2021
  * Note: the embedding-domain allowlist entry (`referrerDomain`) is **not**
2006
2022
  * part of this request. It is a server-only concern configured on
@@ -2030,8 +2046,11 @@ type OnrampSessionRequest = z.infer<typeof onrampSessionRequestSchema>;
2030
2046
  * wallets-api. Pass to pre-select a chain in the widget.
2031
2047
  * - `amount`, `currency`: optional pre-fills.
2032
2048
  * - `email`: optional KYC routing hint.
2033
- * - `metadata`: free-form passthrough — useful for re-stitching the
2034
- * session back to the host's order ledger.
2049
+ * - `metadata`: optional string map. The Onramp API rejects more than 20
2050
+ * keys, keys over 64 characters, values over 1024 characters, and
2051
+ * control characters. It is echoed once on the create response (see
2052
+ * {@link OnrampSession.metadata}) and is not delivered on later widget
2053
+ * events, so use `appUserId` to correlate the user.
2035
2054
  */
2036
2055
  type CreateSessionParams = OnrampSessionRequest;
2037
2056
  /**