@coinlist-co/react 0.12.1-rc.a230abc → 0.12.1-rc.b902290

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 (34) hide show
  1. package/dist/{chunk-GFLU5OMP.js → chunk-2YEJXE2V.js} +1907 -894
  2. package/dist/chunk-2YEJXE2V.js.map +1 -0
  3. package/dist/{chunk-HLL7IBIS.js → chunk-DOSABR7Q.js} +136 -10
  4. package/dist/chunk-DOSABR7Q.js.map +1 -0
  5. package/dist/chunk-DX4VTV7L.js +357 -0
  6. package/dist/chunk-DX4VTV7L.js.map +1 -0
  7. package/dist/client/index.cjs +2558 -1698
  8. package/dist/client/index.cjs.map +1 -1
  9. package/dist/client/index.d.cts +239 -165
  10. package/dist/client/index.d.ts +239 -165
  11. package/dist/client/index.js +489 -444
  12. package/dist/client/index.js.map +1 -1
  13. package/dist/{collections-CAfs2Eww.d.cts → collections-C6b-rJpx.d.ts} +1 -1
  14. package/dist/{collections-DZZFrizd.d.ts → collections-UYVlXbEh.d.cts} +1 -1
  15. package/dist/server/index.cjs +1404 -279
  16. package/dist/server/index.cjs.map +1 -1
  17. package/dist/server/index.d.cts +4 -4
  18. package/dist/server/index.d.ts +4 -4
  19. package/dist/server/index.js +6 -4
  20. package/dist/server/index.js.map +1 -1
  21. package/dist/{config-D19ktBr0.d.cts → tokens-namespace-C-BxcYMj.d.cts} +374 -200
  22. package/dist/{config-D19ktBr0.d.ts → tokens-namespace-C-BxcYMj.d.ts} +374 -200
  23. package/dist/{shared → universal}/index.cjs +1613 -917
  24. package/dist/universal/index.cjs.map +1 -0
  25. package/dist/{shared → universal}/index.d.cts +932 -550
  26. package/dist/{shared → universal}/index.d.ts +932 -550
  27. package/dist/{shared → universal}/index.js +16 -14
  28. package/package.json +6 -5
  29. package/dist/chunk-GFLU5OMP.js.map +0 -1
  30. package/dist/chunk-HLL7IBIS.js.map +0 -1
  31. package/dist/chunk-RPE7XIBV.js +0 -667
  32. package/dist/chunk-RPE7XIBV.js.map +0 -1
  33. package/dist/shared/index.cjs.map +0 -1
  34. /package/dist/{shared → universal}/index.js.map +0 -0
@@ -1,4 +1,4 @@
1
- // src/shared/api/http-attributes.ts
1
+ // src/universal/api/http-attributes.ts
2
2
  var empty = {};
3
3
  var concat = (left, right) => ({
4
4
  ...left,
@@ -53,7 +53,7 @@ var Attributes = {
53
53
  getRequestId
54
54
  };
55
55
 
56
- // src/shared/api/http.ts
56
+ // src/universal/api/http.ts
57
57
  var HttpError = class extends Error {
58
58
  constructor(response) {
59
59
  super(`Request failed with ${response.status} status`);
@@ -177,7 +177,7 @@ var Request = {
177
177
  concatAttributes
178
178
  };
179
179
 
180
- // src/shared/types/errors.ts
180
+ // src/universal/types/errors.ts
181
181
  var NotImplementedError = class extends Error {
182
182
  constructor(message = "Not implemented yet") {
183
183
  super(message);
@@ -209,7 +209,107 @@ var MathError = class extends Error {
209
209
  }
210
210
  };
211
211
 
212
- // src/shared/api/pagination.ts
212
+ // src/universal/core/shared/blockchain/erc20/abi.ts
213
+ var ERC20_ABI = [
214
+ {
215
+ type: "function",
216
+ name: "allowance",
217
+ inputs: [
218
+ { name: "owner", type: "address" },
219
+ { name: "spender", type: "address" }
220
+ ],
221
+ outputs: [{ name: "", type: "uint256" }],
222
+ stateMutability: "view"
223
+ },
224
+ {
225
+ type: "function",
226
+ name: "approve",
227
+ inputs: [
228
+ { name: "spender", type: "address" },
229
+ { name: "amount", type: "uint256" }
230
+ ],
231
+ outputs: [{ name: "", type: "bool" }],
232
+ stateMutability: "nonpayable"
233
+ },
234
+ {
235
+ type: "function",
236
+ name: "balanceOf",
237
+ inputs: [{ name: "account", type: "address" }],
238
+ outputs: [{ name: "", type: "uint256" }],
239
+ stateMutability: "view"
240
+ },
241
+ {
242
+ type: "function",
243
+ name: "decimals",
244
+ inputs: [],
245
+ outputs: [{ name: "", type: "uint8" }],
246
+ stateMutability: "view"
247
+ },
248
+ {
249
+ type: "function",
250
+ name: "name",
251
+ inputs: [],
252
+ outputs: [{ name: "", type: "string" }],
253
+ stateMutability: "view"
254
+ },
255
+ {
256
+ type: "function",
257
+ name: "symbol",
258
+ inputs: [],
259
+ outputs: [{ name: "", type: "string" }],
260
+ stateMutability: "view"
261
+ },
262
+ {
263
+ type: "function",
264
+ name: "totalSupply",
265
+ inputs: [],
266
+ outputs: [{ name: "", type: "uint256" }],
267
+ stateMutability: "view"
268
+ },
269
+ {
270
+ type: "function",
271
+ name: "transfer",
272
+ inputs: [
273
+ { name: "recipient", type: "address" },
274
+ { name: "amount", type: "uint256" }
275
+ ],
276
+ outputs: [{ name: "", type: "bool" }],
277
+ stateMutability: "nonpayable"
278
+ },
279
+ {
280
+ type: "function",
281
+ name: "transferFrom",
282
+ inputs: [
283
+ { name: "sender", type: "address" },
284
+ { name: "recipient", type: "address" },
285
+ { name: "amount", type: "uint256" }
286
+ ],
287
+ outputs: [{ name: "", type: "bool" }],
288
+ stateMutability: "nonpayable"
289
+ },
290
+ {
291
+ type: "event",
292
+ name: "Approval",
293
+ inputs: [
294
+ { name: "owner", type: "address", indexed: true },
295
+ { name: "spender", type: "address", indexed: true },
296
+ { name: "value", type: "uint256", indexed: false }
297
+ ],
298
+ anonymous: false
299
+ },
300
+ {
301
+ type: "event",
302
+ name: "Transfer",
303
+ inputs: [
304
+ { name: "from", type: "address", indexed: true },
305
+ { name: "to", type: "address", indexed: true },
306
+ { name: "value", type: "uint256", indexed: false }
307
+ ],
308
+ anonymous: false
309
+ }
310
+ ];
311
+
312
+ // src/universal/api/pagination.ts
213
313
  async function fetchAllPages(fetchPage, baseParams) {
214
314
  const items = [];
215
315
  let cursor = null;
@@ -225,7 +325,44 @@ async function fetchAllPages(fetchPage, baseParams) {
225
325
  return items;
226
326
  }
227
327
 
228
- // src/shared/types/blockchain/core.ts
328
+ // src/universal/types/pagination.ts
329
+ var Cursor = (value) => value;
330
+ var PaginatedResponse = {
331
+ fromDto: (dto, itemMapper) => ({
332
+ data: dto.data.map(itemMapper),
333
+ startingAfter: dto.starting_after ? Cursor(dto.starting_after) : null,
334
+ startingBefore: dto.starting_before ? Cursor(dto.starting_before) : null
335
+ })
336
+ };
337
+ var PaginationParams = {
338
+ toQueryParams: (params) => {
339
+ const queryParams = {};
340
+ if (params.after) {
341
+ queryParams.starting_after = params.after;
342
+ }
343
+ if (params.before) {
344
+ queryParams.starting_before = params.before;
345
+ }
346
+ if (params.limit) {
347
+ queryParams.limit = params.limit;
348
+ }
349
+ return queryParams;
350
+ }
351
+ };
352
+
353
+ // src/universal/types/asset.ts
354
+ var AssetId = (value) => value;
355
+ var AssetCode = (value) => value;
356
+ var Asset = {
357
+ fromDto: (dto) => ({
358
+ id: AssetId(dto.id),
359
+ code: AssetCode(dto.code),
360
+ name: dto.name,
361
+ fractionalDigits: dto.fractional_digits
362
+ })
363
+ };
364
+
365
+ // src/universal/types/blockchain/core.ts
229
366
  var ETHEREUM_CHAINS = {
230
367
  ethereum_mainnet: true,
231
368
  ethereum_sepolia: true,
@@ -322,226 +459,316 @@ var StablecoinSymbol = (value) => value;
322
459
  var KnownAssetSymbol = StablecoinSymbol;
323
460
  var Bps = (value) => value;
324
461
 
325
- // src/shared/types/blockchain/ui.ts
326
- var FormattedAmountUi = (value) => value;
327
- var FormattedPercentUi = (value) => value;
328
- var TxExplorerUrl = (value) => value;
329
- var ShortenedWalletAddress = (value) => value;
330
- var FormattedAmountAssetUi = (value) => value;
331
- var AssetIconUrl = (value) => value;
332
-
333
- // src/shared/core/blockchain/chain.ts
334
- var CHAIN_IDS = {
335
- ethereum_mainnet: 1,
336
- ethereum_sepolia: 11155111,
337
- base_mainnet: 8453,
338
- base_sepolia: 84532
462
+ // src/universal/types/offer.ts
463
+ var OfferId = (value) => value;
464
+ var OfferSlug = (value) => value;
465
+ var Offer = {
466
+ fromDto: (dto) => {
467
+ if (!Array.isArray(dto.tokens)) {
468
+ throw new ValidationError(
469
+ `Offer.tokens: expected an array, got ${typeof dto.tokens}`
470
+ );
471
+ }
472
+ return {
473
+ id: OfferId(dto.id),
474
+ slug: OfferSlug(dto.slug),
475
+ type: dto.type,
476
+ tagline: dto.tagline,
477
+ bannerUrl: dto.banner_url,
478
+ logoUrl: dto.logo_url,
479
+ startsAt: new Date(dto.starts_at),
480
+ endsAt: dto.ends_at ? new Date(dto.ends_at) : null,
481
+ tokens: OfferToken.listFromDto(dto.tokens)
482
+ };
483
+ }
339
484
  };
340
- function getChainId(chain) {
341
- return CHAIN_IDS[chain];
485
+ var OfferToken = {
486
+ fromDto: (dto) => ({
487
+ role: dto.role,
488
+ chain: Chain(dto.chain),
489
+ address: EvmContractAddress(dto.address)
490
+ }),
491
+ /**
492
+ * Maps an offer's token list, dropping every token on a chain this SDK does
493
+ * not name. Frontline's chain registry runs ahead of {@link Chain}, and a
494
+ * plain `.map` would throw out of `Offer.fromDto` and, through
495
+ * `PaginatedResponse.fromDto`, reject the whole offers page - which is how
496
+ * one Base token blanked production's offers list. Dropping costs that
497
+ * token's metadata alone: `coinlist.tokens.get` takes an `EthereumChain`,
498
+ * so nobody could have looked it up anyway.
499
+ *
500
+ * Same shape as `TokenMetadata.fromRegistryDto`.
501
+ */
502
+ listFromDto: (dtos) => dtos.filter((dto) => isChain(dto.chain)).map(OfferToken.fromDto)
503
+ };
504
+
505
+ // src/universal/types/trading.ts
506
+ var Ticker = (value) => value;
507
+ var Isin = (value) => value;
508
+
509
+ // src/universal/core/shared/utils/crypto.ts
510
+ async function sha256(data) {
511
+ const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
512
+ const buffer = bytes.buffer.slice(
513
+ bytes.byteOffset,
514
+ bytes.byteOffset + bytes.byteLength
515
+ );
516
+ return crypto.subtle.digest("SHA-256", buffer);
342
517
  }
343
- function chainFromId(chainId) {
344
- const chains = Object.keys(CHAIN_IDS);
345
- const chain = chains.find((c) => String(CHAIN_IDS[c]) === chainId);
346
- if (!chain) {
347
- throw new ValidationError(`Unsupported EIP-155 chain id: "${chainId}"`);
518
+ function arrayBufferToBase64Url(buffer, padding = true) {
519
+ const bytes = new Uint8Array(buffer);
520
+ let binary = "";
521
+ for (let i = 0; i < bytes.length; i++) {
522
+ binary += String.fromCharCode(bytes[i]);
348
523
  }
349
- return chain;
350
- }
351
- function getNetworkName(chain) {
352
- switch (chain) {
353
- case "ethereum_mainnet":
354
- return "Ethereum";
355
- case "ethereum_sepolia":
356
- return "Ethereum Sepolia";
357
- case "base_mainnet":
358
- return "Base";
359
- case "base_sepolia":
360
- return "Base Sepolia";
361
- default: {
362
- const _exhaustive = chain;
363
- return _exhaustive;
364
- }
524
+ let base64 = btoa(binary);
525
+ base64 = base64.replace(/\+/g, "-").replace(/\//g, "_");
526
+ if (!padding) {
527
+ base64 = base64.replace(/=+$/, "");
365
528
  }
529
+ return base64;
366
530
  }
367
- function txExplorerUrl(chain, txHash) {
368
- return TxExplorerUrl(`${explorerBaseUrl(chain)}/tx/${txHash}`);
531
+ function generateSecureRandomBase64Url(byteLength) {
532
+ const bytes = new Uint8Array(byteLength);
533
+ crypto.getRandomValues(bytes);
534
+ const buffer = bytes.buffer;
535
+ return arrayBufferToBase64Url(buffer, false);
369
536
  }
370
- function explorerBaseUrl(chain) {
371
- switch (chain) {
372
- case "ethereum_mainnet":
373
- return "https://etherscan.io";
374
- case "ethereum_sepolia":
375
- return "https://sepolia.etherscan.io";
376
- case "base_mainnet":
377
- return "https://basescan.org";
378
- case "base_sepolia":
379
- return "https://sepolia-explorer.base.org";
380
- default: {
381
- const _exhaustive = chain;
382
- return _exhaustive;
383
- }
537
+ function getUUIDv4() {
538
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
539
+ return crypto.randomUUID();
540
+ }
541
+ if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
542
+ const bytes = new Uint8Array(16);
543
+ crypto.getRandomValues(bytes);
544
+ bytes[6] = bytes[6] & 15 | 64;
545
+ bytes[8] = bytes[8] & 63 | 128;
546
+ const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0"));
547
+ return `${hex.slice(0, 4).join("")}-${hex.slice(4, 6).join("")}-${hex.slice(6, 8).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10, 16).join("")}`;
548
+ }
549
+ return `${Date.now()}-${Math.random().toString(36).slice(2, 12)}`;
550
+ }
551
+ function notBlankStringOrNull(value) {
552
+ if (value?.trim()) {
553
+ return value;
554
+ } else {
555
+ return null;
384
556
  }
385
557
  }
386
558
 
387
- // src/shared/types/providers/superstate/swap.ts
388
- var SwapAuthorization = {
389
- fromDto: (dto) => ({
390
- authorized: dto.authorized
391
- })
392
- };
393
- var SwapPreview = {
394
- fromDto: (dto) => ({
395
- inputAmount: parseUint256(
396
- BigInt(dto.pay_input_amount),
397
- "SwapPreview.pay_input_amount"
398
- ),
399
- fee: parseUint256(BigInt(dto.fee), "SwapPreview.fee"),
400
- outputAmount: parseUint256(
401
- BigInt(dto.receive_output_amount),
402
- "SwapPreview.receive_output_amount"
403
- )
404
- })
405
- };
406
- var SwapStatus = {
407
- fromDto: (dto) => ({
408
- stopped: parseUint256(BigInt(dto.stopped), "SwapStatus.stopped"),
409
- swapLevel: parseUint256(BigInt(dto.swap_level), "SwapStatus.swap_level")
410
- })
411
- };
412
- var TokenAllowance = {
413
- fromDto: (dto) => ({
414
- allowance: parseUint256(BigInt(dto.allowance), "TokenAllowance.allowance")
415
- })
416
- };
417
- var TokenBalance = {
559
+ // src/universal/types/offer-detail.ts
560
+ var OfferOptionId = (value) => value;
561
+ var OfferOptionSlug = (value) => value;
562
+ var OfferSwapContract = {
418
563
  fromDto: (dto) => ({
419
- balance: parseUint256(BigInt(dto.balance), "TokenBalance.balance")
564
+ chain: Chain(dto.chain),
565
+ address: EvmContractAddress(dto.address)
420
566
  })
421
567
  };
422
- var AllowWalletResponse = {
568
+ var OfferDetail = {
423
569
  fromDto: (dto) => {
424
- switch (dto.action) {
425
- case "broadcast_transaction":
426
- return {
427
- action: "broadcast_transaction",
428
- to: EvmContractAddress(dto.to),
429
- data: HexEncodedTransactionData(dto.data)
430
- };
431
- case "none":
432
- return {
433
- action: "none",
434
- alreadyAllowed: dto.already_allowed
435
- };
436
- default: {
437
- const _exhaustive = dto;
438
- return _exhaustive;
439
- }
570
+ if (!Array.isArray(dto.funding_assets)) {
571
+ throw new ValidationError(
572
+ `OfferDetail.funding_assets: expected an array, got ${typeof dto.funding_assets}`
573
+ );
440
574
  }
441
- }
442
- };
443
-
444
- // src/shared/api/frontline/providers/superstate/swap.ts
445
- async function getSwapAuthorization(api, params) {
446
- const dto = await api.send({
447
- method: "GET",
448
- url: "/v1/wallet/authorized",
449
- queryParams: {
450
- chain: params.chain,
451
- contract_address: params.contractAddress,
452
- wallet_address: params.walletAddress
453
- },
454
- attributes: Attributes.protected()
455
- });
456
- return SwapAuthorization.fromDto(dto);
457
- }
458
- async function getSwapOutputToken(api, params) {
459
- const dto = await api.send({
460
- method: "GET",
461
- url: "/v1/swap/output-token",
462
- queryParams: {
463
- chain: params.chain,
464
- contract_address: params.contractAddress
465
- },
466
- attributes: Attributes.protected()
467
- });
468
- return toErc20Asset(dto);
469
- }
470
- async function getSwapPreview(api, params) {
471
- const dto = await api.send({
472
- method: "GET",
473
- url: "/v1/swap/preview",
474
- queryParams: {
475
- chain: params.chain,
476
- contract_address: params.contractAddress,
477
- input_token: params.inputToken,
478
- amount: params.amount.toString()
479
- },
480
- attributes: Attributes.protected()
481
- });
482
- return SwapPreview.fromDto(dto);
483
- }
484
- async function getSwapStatus(api, params) {
485
- const dto = await api.send({
486
- method: "GET",
487
- url: "/v1/swap/status",
488
- queryParams: {
489
- chain: params.chain,
490
- contract_address: params.contractAddress
491
- },
492
- attributes: Attributes.protected()
493
- });
494
- return SwapStatus.fromDto(dto);
575
+ if (!Array.isArray(dto.options)) {
576
+ throw new ValidationError(
577
+ `OfferDetail.options: expected an array, got ${typeof dto.options}`
578
+ );
579
+ }
580
+ if (!Array.isArray(dto.terms)) {
581
+ throw new ValidationError(
582
+ `OfferDetail.terms: expected an array, got ${typeof dto.terms}`
583
+ );
584
+ }
585
+ if (!Array.isArray(dto.links)) {
586
+ throw new ValidationError(
587
+ `OfferDetail.links: expected an array, got ${typeof dto.links}`
588
+ );
589
+ }
590
+ if (!Array.isArray(dto.faqs)) {
591
+ throw new ValidationError(
592
+ `OfferDetail.faqs: expected an array, got ${typeof dto.faqs}`
593
+ );
594
+ }
595
+ if (!Array.isArray(dto.milestones)) {
596
+ throw new ValidationError(
597
+ `OfferDetail.milestones: expected an array, got ${typeof dto.milestones}`
598
+ );
599
+ }
600
+ if (!Array.isArray(dto.tokens)) {
601
+ throw new ValidationError(
602
+ `OfferDetail.tokens: expected an array, got ${typeof dto.tokens}`
603
+ );
604
+ }
605
+ const swapContracts = dto.swap_contracts === void 0 ? [] : dto.swap_contracts;
606
+ if (!Array.isArray(swapContracts)) {
607
+ throw new ValidationError(
608
+ `OfferDetail.swap_contracts: expected an array, got ${typeof swapContracts}`
609
+ );
610
+ }
611
+ const isin = notBlankStringOrNull(dto.isin);
612
+ const ticker = notBlankStringOrNull(dto.ticker);
613
+ return {
614
+ id: OfferId(dto.id),
615
+ slug: OfferSlug(dto.slug),
616
+ type: dto.type,
617
+ name: dto.name,
618
+ asset: Asset.fromDto(dto.asset),
619
+ fundingAssets: dto.funding_assets.map(Asset.fromDto),
620
+ tokens: OfferToken.listFromDto(dto.tokens),
621
+ swapContracts: swapContracts.map(OfferSwapContract.fromDto),
622
+ about: notBlankStringOrNull(dto.about),
623
+ tagline: dto.tagline,
624
+ bannerUrl: dto.banner_url,
625
+ logoUrl: dto.logo_url,
626
+ category: dto.category,
627
+ issuer: notBlankStringOrNull(dto.issuer),
628
+ isin: isin === null ? null : Isin(isin),
629
+ ticker: ticker === null ? null : Ticker(ticker),
630
+ instrumentType: notBlankStringOrNull(dto.instrument_type),
631
+ listingVenue: notBlankStringOrNull(dto.listing_venue),
632
+ startsAt: new Date(dto.starts_at),
633
+ endsAt: dto.ends_at ? new Date(dto.ends_at) : null,
634
+ faqs: dto.faqs.map(FaqItem.fromDto),
635
+ links: dto.links.map(Link.fromDto),
636
+ milestones: dto.milestones.map(Milestone.fromDto),
637
+ options: dto.options.map(OfferOption.fromDto),
638
+ terms: dto.terms.map(TermItem.fromDto)
639
+ };
640
+ }
641
+ };
642
+ var OfferOption = {
643
+ fromDto: (dto) => ({
644
+ id: OfferOptionId(dto.id),
645
+ slug: OfferOptionSlug(dto.slug),
646
+ bidIncrement: dto.bid_increment,
647
+ floorPriceUsd: dto.floor_price_usd,
648
+ minimumPurchaseUsd: dto.minimum_purchase_usd,
649
+ priceUsd: dto.price_usd,
650
+ saleAgreementUrl: notBlankStringOrNull(dto.sale_agreement_url),
651
+ totalTokenSupply: dto.total_token_supply
652
+ })
653
+ };
654
+ var FaqItem = {
655
+ fromDto: (dto) => ({
656
+ question: notBlankStringOrNull(dto.question),
657
+ answer: notBlankStringOrNull(dto.answer)
658
+ })
659
+ };
660
+ var Link = {
661
+ fromDto: (dto) => ({
662
+ label: notBlankStringOrNull(dto.label),
663
+ url: notBlankStringOrNull(dto.url)
664
+ })
665
+ };
666
+ var TermItem = {
667
+ fromDto: (dto) => ({
668
+ key: notBlankStringOrNull(dto.key),
669
+ value: notBlankStringOrNull(dto.value)
670
+ })
671
+ };
672
+ var Milestone = {
673
+ fromDto: (dto) => ({
674
+ name: notBlankStringOrNull(dto.name),
675
+ schedule: notBlankStringOrNull(dto.schedule),
676
+ status: dto.status
677
+ })
678
+ };
679
+
680
+ // src/universal/types/providers/coin-list/token-sale.ts
681
+ var ParticipationId = (value) => value;
682
+ var Blockchain = (value) => value;
683
+ var WalletAddress = (value) => value;
684
+ var ParticipationsPaginationParams = {
685
+ toQueryParams: (params) => {
686
+ const queryParams = PaginationParams.toQueryParams(params);
687
+ if (params.offerId) {
688
+ queryParams["filters[0][field]"] = "offer_id";
689
+ queryParams["filters[0][op]"] = "==";
690
+ queryParams["filters[0][value]"] = params.offerId;
691
+ }
692
+ return queryParams;
693
+ }
694
+ };
695
+ var Participation = {
696
+ /** Maps API DTO shape into the SDK participation domain model. */
697
+ fromDto: (dto) => {
698
+ const walletAddress = notBlankStringOrNull(dto.wallet_address);
699
+ return {
700
+ id: ParticipationId(dto.id),
701
+ offerId: OfferId(dto.offer_id),
702
+ offerOptionId: OfferOptionId(dto.offer_option_id),
703
+ status: dto.status,
704
+ amount: dto.amount,
705
+ displayAmount: dto.amount_string,
706
+ asset: Asset.fromDto(dto.asset),
707
+ chain: Blockchain(dto.chain),
708
+ insertedAt: dto.inserted_at ? new Date(dto.inserted_at) : null,
709
+ updatedAt: dto.updated_at ? new Date(dto.updated_at) : null,
710
+ walletAddress: walletAddress ? WalletAddress(walletAddress) : null
711
+ };
712
+ }
713
+ };
714
+ var CreateParticipationParams = {
715
+ /** Maps participation creation params into API DTO payload. */
716
+ toDto: (params) => ({
717
+ offer_id: params.offerId,
718
+ offer_option_id: params.offerOptionId,
719
+ chain: params.chain,
720
+ wallet_address: params.walletAddress,
721
+ amount: params.amount,
722
+ asset_id: params.assetId,
723
+ approval_transaction_hash: params.approvalTransactionHash
724
+ })
725
+ };
726
+
727
+ // src/universal/api/frontline/providers/coin-list/token-sale.ts
728
+ async function fetchParticipations(api, offerId) {
729
+ return fetchAllPages(
730
+ (params) => fetchParticipationsPage(api, params),
731
+ { offerId }
732
+ );
495
733
  }
496
- async function getTokenAllowance(api, params) {
497
- const dto = await api.send({
734
+ async function fetchParticipationsPage(api, params) {
735
+ const pageDto = await api.send({
498
736
  method: "GET",
499
- url: "/v1/token/allowance",
500
- queryParams: {
501
- chain: params.chain,
502
- token_address: params.tokenAddress,
503
- owner: params.owner,
504
- spender: params.spender
505
- },
737
+ url: "/v1/participations",
738
+ queryParams: ParticipationsPaginationParams.toQueryParams(params),
506
739
  attributes: Attributes.protected()
507
740
  });
508
- return TokenAllowance.fromDto(dto);
741
+ return PaginatedResponse.fromDto(pageDto, Participation.fromDto);
509
742
  }
510
- async function getTokenBalance(api, params) {
743
+ async function fetchParticipation(api, id) {
511
744
  const dto = await api.send({
512
745
  method: "GET",
513
- url: "/v1/token/balance",
514
- queryParams: {
515
- chain: params.chain,
516
- token_address: params.tokenAddress,
517
- owner: params.owner
518
- },
746
+ url: `/v1/participations/${id}`,
519
747
  attributes: Attributes.protected()
520
748
  });
521
- return TokenBalance.fromDto(dto);
749
+ return Participation.fromDto(dto);
522
750
  }
523
- async function allowWallet(api, params) {
751
+ async function createParticipation(api, params) {
524
752
  const dto = await api.send({
525
753
  method: "POST",
526
- url: `/v1/offers/${encodeURIComponent(params.offerId)}/allow-wallet`,
527
- body: {
528
- wallet_address: params.walletAddress,
529
- chain: params.chain,
530
- signature: params.signature
531
- },
754
+ url: "/v1/participations",
755
+ body: CreateParticipationParams.toDto(params),
532
756
  attributes: Attributes.protected()
533
757
  });
534
- return AllowWalletResponse.fromDto(dto);
535
- }
536
- function toErc20Asset(dto) {
537
- return {
538
- name: dto.name,
539
- symbol: AssetSymbol(dto.symbol),
540
- decimals: AssetDecimals(dto.decimals)
541
- };
758
+ return Participation.fromDto(dto);
542
759
  }
543
760
 
544
- // src/shared/core/observability/log-cause.ts
761
+ // src/universal/core/shared/observability/log-cause.ts
762
+ import {
763
+ BaseError,
764
+ ContractFunctionExecutionError,
765
+ ContractFunctionRevertedError,
766
+ HttpRequestError,
767
+ RpcError,
768
+ SocketClosedError,
769
+ TimeoutError,
770
+ WebSocketRequestError
771
+ } from "viem";
545
772
  function classifyLogCause(error) {
546
773
  if (error instanceof HttpError) {
547
774
  return httpCause(error);
@@ -561,8 +788,32 @@ function classifyLogCause(error) {
561
788
  if (error instanceof NotImplementedError) {
562
789
  return { type: "not-implemented" };
563
790
  }
791
+ if (error instanceof BaseError) {
792
+ const http = error.walk((e) => e instanceof HttpError);
793
+ if (http instanceof HttpError) {
794
+ return httpCause(http);
795
+ }
796
+ return { type: "rpc", reason: rpcFailureReason(error) };
797
+ }
564
798
  return { type: "generic-error", name: errorName(error) };
565
799
  }
800
+ function rpcFailureReason(error) {
801
+ if (error.walk((e) => e instanceof ContractFunctionRevertedError)) {
802
+ return "reverted";
803
+ }
804
+ if (error.walk((e) => e instanceof RpcError)) {
805
+ return "node-rejected";
806
+ }
807
+ if (error.walk(
808
+ (e) => e instanceof HttpRequestError || e instanceof WebSocketRequestError || e instanceof SocketClosedError || e instanceof TimeoutError
809
+ )) {
810
+ return "transport";
811
+ }
812
+ if (error instanceof ContractFunctionExecutionError) {
813
+ return "malformed-response";
814
+ }
815
+ return "unknown";
816
+ }
566
817
  function describeErrorUnredacted(error) {
567
818
  if (error instanceof HttpError) {
568
819
  return describeHttpErrorRedacted(error);
@@ -607,7 +858,7 @@ function apiErrorEventId(error) {
607
858
  return typeof eventId === "string" ? eventId : null;
608
859
  }
609
860
 
610
- // src/shared/core/observability/internal-logger.ts
861
+ // src/universal/core/shared/observability/internal-logger.ts
611
862
  function internalLogger(logger, scope) {
612
863
  return logger ? scopedLogger(logger, scope, {}) : noopInternalLogger;
613
864
  }
@@ -690,27 +941,47 @@ var noopInternalLogger = {
690
941
  wrap: (_op, _params, run) => run()
691
942
  };
692
943
 
693
- // src/shared/core/blockchain/erc20/erc20-namespace.ts
694
- var Erc20NamespaceImpl = class {
944
+ // src/universal/core/checkout/coin-list/token-sale-namespace.ts
945
+ var CoinListTokenSaleNamespaceImpl = class {
695
946
  constructor(ctx) {
696
947
  this.ctx = ctx;
697
- this.log = internalLogger(ctx.logger, "ERC20");
948
+ this.log = internalLogger(ctx.logger, "TOKEN_SALE");
698
949
  }
699
- async getAllowance(params) {
700
- return this.log.wrap("getAllowance", params, async () => {
950
+ async list(offerId) {
951
+ return this.log.wrap("list", offerId, async () => {
701
952
  await this.ctx.ensureUserAuthenticated();
702
- return getTokenAllowance(this.ctx.api, params);
953
+ return fetchParticipations(this.ctx.api, offerId);
703
954
  });
704
955
  }
705
- async getBalance(params) {
706
- return this.log.wrap("getBalance", params, async () => {
956
+ async listPage(params) {
957
+ return this.log.wrap("listPage", params, async () => {
958
+ await this.ctx.ensureUserAuthenticated();
959
+ return fetchParticipationsPage(this.ctx.api, params);
960
+ });
961
+ }
962
+ async get(id) {
963
+ return this.log.wrap("get", id, async () => {
707
964
  await this.ctx.ensureUserAuthenticated();
708
- return getTokenBalance(this.ctx.api, params);
965
+ return fetchParticipation(this.ctx.api, id);
966
+ });
967
+ }
968
+ async createParticipation(params) {
969
+ return this.log.wrap("createParticipation", params, async () => {
970
+ await this.ctx.ensureUserAuthenticated();
971
+ return createParticipation(this.ctx.api, params);
709
972
  });
710
973
  }
711
974
  };
712
975
 
713
- // src/shared/core/blockchain/formatters.ts
976
+ // src/universal/types/blockchain/ui.ts
977
+ var FormattedAmountUi = (value) => value;
978
+ var FormattedPercentUi = (value) => value;
979
+ var TxExplorerUrl = (value) => value;
980
+ var ShortenedWalletAddress = (value) => value;
981
+ var FormattedAmountAssetUi = (value) => value;
982
+ var AssetIconUrl = (value) => value;
983
+
984
+ // src/universal/core/shared/blockchain/formatters.ts
714
985
  import { formatUnits } from "viem";
715
986
  function shortenAddress(address) {
716
987
  const short = address.length > 10 ? `${address.slice(0, 6)}\u2026${address.slice(-4)}` : address;
@@ -805,37 +1076,95 @@ function formattedUsdPrice(amount, locale) {
805
1076
  );
806
1077
  }
807
1078
 
808
- // src/shared/core/blockchain/math.ts
809
- import { parseUnits } from "viem";
810
- function blockchainAmountFromRawOrThrow({
811
- label,
812
- raw,
813
- decimals
814
- }) {
815
- const trimmed = raw.trim();
816
- if (trimmed === "") {
817
- throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
818
- }
819
- let value;
820
- try {
821
- value = BigInt(trimmed);
822
- } catch {
823
- throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
824
- }
825
- try {
826
- return BlockchainAmount({ raw: assertUint256(value), decimals });
827
- } catch {
828
- throw new ValidationError(`${label}: out of uint256 bounds (${value})`);
829
- }
1079
+ // src/universal/core/shared/blockchain/chain.ts
1080
+ import { base, baseSepolia, mainnet, sepolia } from "viem/chains";
1081
+ var VIEM_CHAINS = {
1082
+ ethereum_mainnet: mainnet,
1083
+ ethereum_sepolia: sepolia,
1084
+ base_mainnet: base,
1085
+ base_sepolia: baseSepolia
1086
+ };
1087
+ function viemChain(chain) {
1088
+ return VIEM_CHAINS[chain];
830
1089
  }
831
- function parseBlockchainAmount(amount, decimals) {
832
- const trimmed = amount.trim();
833
- if (trimmed === "") return { valid: false, reason: { type: "empty" } };
834
- if (trimmed.startsWith("-")) {
835
- return { valid: false, reason: { type: "negative" } };
1090
+ function getChainId(chain) {
1091
+ return VIEM_CHAINS[chain].id;
1092
+ }
1093
+ function chainFromId(chainId) {
1094
+ const chains = Object.keys(VIEM_CHAINS);
1095
+ const chain = chains.find((c) => String(VIEM_CHAINS[c].id) === chainId);
1096
+ if (!chain) {
1097
+ throw new ValidationError(`Unsupported EIP-155 chain id: "${chainId}"`);
836
1098
  }
837
- if (/[eE]/.test(trimmed)) {
838
- return { valid: false, reason: { type: "invalid-format" } };
1099
+ return chain;
1100
+ }
1101
+ function getNetworkName(chain) {
1102
+ switch (chain) {
1103
+ case "ethereum_mainnet":
1104
+ return "Ethereum";
1105
+ case "ethereum_sepolia":
1106
+ return "Ethereum Sepolia";
1107
+ case "base_mainnet":
1108
+ return "Base";
1109
+ case "base_sepolia":
1110
+ return "Base Sepolia";
1111
+ default: {
1112
+ const _exhaustive = chain;
1113
+ return _exhaustive;
1114
+ }
1115
+ }
1116
+ }
1117
+ function txExplorerUrl(chain, txHash) {
1118
+ return TxExplorerUrl(`${explorerBaseUrl(chain)}/tx/${txHash}`);
1119
+ }
1120
+ function explorerBaseUrl(chain) {
1121
+ switch (chain) {
1122
+ case "ethereum_mainnet":
1123
+ return "https://etherscan.io";
1124
+ case "ethereum_sepolia":
1125
+ return "https://sepolia.etherscan.io";
1126
+ case "base_mainnet":
1127
+ return "https://basescan.org";
1128
+ case "base_sepolia":
1129
+ return "https://sepolia-explorer.base.org";
1130
+ default: {
1131
+ const _exhaustive = chain;
1132
+ return _exhaustive;
1133
+ }
1134
+ }
1135
+ }
1136
+
1137
+ // src/universal/core/shared/blockchain/math.ts
1138
+ import { parseUnits } from "viem";
1139
+ function blockchainAmountFromRawOrThrow({
1140
+ label,
1141
+ raw,
1142
+ decimals
1143
+ }) {
1144
+ const trimmed = raw.trim();
1145
+ if (trimmed === "") {
1146
+ throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
1147
+ }
1148
+ let value;
1149
+ try {
1150
+ value = BigInt(trimmed);
1151
+ } catch {
1152
+ throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
1153
+ }
1154
+ try {
1155
+ return BlockchainAmount({ raw: assertUint256(value), decimals });
1156
+ } catch {
1157
+ throw new ValidationError(`${label}: out of uint256 bounds (${value})`);
1158
+ }
1159
+ }
1160
+ function parseBlockchainAmount(amount, decimals) {
1161
+ const trimmed = amount.trim();
1162
+ if (trimmed === "") return { valid: false, reason: { type: "empty" } };
1163
+ if (trimmed.startsWith("-")) {
1164
+ return { valid: false, reason: { type: "negative" } };
1165
+ }
1166
+ if (/[eE]/.test(trimmed)) {
1167
+ return { valid: false, reason: { type: "invalid-format" } };
839
1168
  }
840
1169
  if (!/^\d+(\.\d+)?$/.test(trimmed)) {
841
1170
  return { valid: false, reason: { type: "invalid-format" } };
@@ -861,688 +1190,1328 @@ function parseBlockchainAmount(amount, decimals) {
861
1190
  }
862
1191
  }
863
1192
 
864
- // src/shared/types/pagination.ts
865
- var Cursor = (value) => value;
866
- var PaginatedResponse = {
867
- fromDto: (dto, itemMapper) => ({
868
- data: dto.data.map(itemMapper),
869
- startingAfter: dto.starting_after ? Cursor(dto.starting_after) : null,
870
- startingBefore: dto.starting_before ? Cursor(dto.starting_before) : null
871
- })
872
- };
873
- var PaginationParams = {
874
- toQueryParams: (params) => {
875
- const queryParams = {};
876
- if (params.after) {
877
- queryParams.starting_after = params.after;
878
- }
879
- if (params.before) {
880
- queryParams.starting_before = params.before;
881
- }
882
- if (params.limit) {
883
- queryParams.limit = params.limit;
884
- }
885
- return queryParams;
1193
+ // src/universal/types/providers/ondo/ondo.ts
1194
+ var OndoTradingStatus = {
1195
+ fromDto: (dto) => {
1196
+ if (!dto.tradable) return { type: "not-tradable", side: dto.side };
1197
+ return {
1198
+ type: "tradable",
1199
+ side: dto.side,
1200
+ grossMaxTokens: decimalOrNull(dto.gross_max_tokens),
1201
+ grossMaxNotionalValue: decimalOrNull(dto.gross_max_notional_value),
1202
+ grossMaxActiveNotionalValue: decimalOrNull(
1203
+ dto.gross_max_active_notional_value
1204
+ )
1205
+ };
886
1206
  }
887
1207
  };
888
-
889
- // src/shared/types/asset.ts
890
- var AssetId = (value) => value;
891
- var AssetCode = (value) => value;
892
- var Asset = {
893
- fromDto: (dto) => ({
894
- id: AssetId(dto.id),
895
- code: AssetCode(dto.code),
896
- name: dto.name,
897
- fractionalDigits: dto.fractional_digits
898
- })
899
- };
900
-
901
- // src/shared/types/offer.ts
902
- var OfferId = (value) => value;
903
- var OfferSlug = (value) => value;
904
- var Offer = {
1208
+ var decimalOrNull = (value) => value === null ? null : DecimalString(value);
1209
+ var OndoQuote = {
905
1210
  fromDto: (dto) => {
906
- if (!Array.isArray(dto.tokens)) {
907
- throw new ValidationError(
908
- `Offer.tokens: expected an array, got ${typeof dto.tokens}`
909
- );
910
- }
1211
+ const assetDecimals = AssetDecimals(dto.asset_decimals);
911
1212
  return {
912
- id: OfferId(dto.id),
913
- slug: OfferSlug(dto.slug),
914
- type: dto.type,
915
- tagline: dto.tagline,
916
- bannerUrl: dto.banner_url,
917
- logoUrl: dto.logo_url,
918
- startsAt: new Date(dto.starts_at),
919
- endsAt: dto.ends_at ? new Date(dto.ends_at) : null,
920
- tokens: OfferToken.listFromDto(dto.tokens)
1213
+ chain: chainFromId(dto.chain_id),
1214
+ ticker: Ticker(dto.ticker),
1215
+ assetAddress: EvmContractAddress(dto.asset_address),
1216
+ asset: {
1217
+ name: dto.ticker,
1218
+ symbol: AssetSymbol(dto.symbol),
1219
+ decimals: assetDecimals
1220
+ },
1221
+ side: dto.side,
1222
+ tokenBaseUnits: blockchainAmountFromRawOrThrow({
1223
+ label: "tokenBaseUnits",
1224
+ raw: dto.token_base_units,
1225
+ decimals: assetDecimals
1226
+ }),
1227
+ price: DecimalString(dto.price)
921
1228
  };
922
1229
  }
923
1230
  };
924
- var OfferToken = {
925
- fromDto: (dto) => ({
926
- role: dto.role,
927
- chain: Chain(dto.chain),
928
- address: EvmContractAddress(dto.address)
929
- }),
930
- /**
931
- * Maps an offer's token list, dropping every token on a chain this SDK does
932
- * not name. Frontline's chain registry runs ahead of {@link Chain}, and a
933
- * plain `.map` would throw out of `Offer.fromDto` and, through
934
- * `PaginatedResponse.fromDto`, reject the whole offers page - which is how
935
- * one Base token blanked production's offers list. Dropping costs that
936
- * token's metadata alone: `coinlist.tokens.get` takes an `EthereumChain`,
937
- * so nobody could have looked it up anyway.
938
- *
939
- * Same shape as `TokenMetadata.fromRegistryDto`.
940
- */
941
- listFromDto: (dtos) => dtos.filter((dto) => isChain(dto.chain)).map(OfferToken.fromDto)
942
- };
943
-
944
- // src/shared/core/utils/crypto.ts
945
- async function sha256(data) {
946
- const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
947
- const buffer = bytes.buffer.slice(
948
- bytes.byteOffset,
949
- bytes.byteOffset + bytes.byteLength
950
- );
951
- return crypto.subtle.digest("SHA-256", buffer);
952
- }
953
- function arrayBufferToBase64Url(buffer, padding = true) {
954
- const bytes = new Uint8Array(buffer);
955
- let binary = "";
956
- for (let i = 0; i < bytes.length; i++) {
957
- binary += String.fromCharCode(bytes[i]);
958
- }
959
- let base64 = btoa(binary);
960
- base64 = base64.replace(/\+/g, "-").replace(/\//g, "_");
961
- if (!padding) {
962
- base64 = base64.replace(/=+$/, "");
963
- }
964
- return base64;
965
- }
966
- function generateSecureRandomBase64Url(byteLength) {
967
- const bytes = new Uint8Array(byteLength);
968
- crypto.getRandomValues(bytes);
969
- const buffer = bytes.buffer;
970
- return arrayBufferToBase64Url(buffer, false);
971
- }
972
- function getUUIDv4() {
973
- if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
974
- return crypto.randomUUID();
975
- }
976
- if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
977
- const bytes = new Uint8Array(16);
978
- crypto.getRandomValues(bytes);
979
- bytes[6] = bytes[6] & 15 | 64;
980
- bytes[8] = bytes[8] & 63 | 128;
981
- const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0"));
982
- return `${hex.slice(0, 4).join("")}-${hex.slice(4, 6).join("")}-${hex.slice(6, 8).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10, 16).join("")}`;
983
- }
984
- return `${Date.now()}-${Math.random().toString(36).slice(2, 12)}`;
985
- }
986
- function notBlankStringOrNull(value) {
987
- if (value?.trim()) {
988
- return value;
989
- } else {
990
- return null;
1231
+ var OndoBuyTransaction = {
1232
+ fromDto: (dto) => {
1233
+ const spendDecimals = AssetDecimals(dto.spend_input_decimals);
1234
+ const outputDecimals = AssetDecimals(dto.receive_output_decimals);
1235
+ return {
1236
+ ...parseSwapCore(dto, spendDecimals),
1237
+ side: "buy",
1238
+ fee: blockchainAmountFromRawOrThrow({
1239
+ label: "fee",
1240
+ raw: dto.fee,
1241
+ decimals: spendDecimals
1242
+ }),
1243
+ notionalValue: blockchainAmountFromRawOrThrow({
1244
+ label: "notional_value",
1245
+ raw: dto.notional_value,
1246
+ decimals: spendDecimals
1247
+ }),
1248
+ receiveOutputAmount: parsePositiveAmount({
1249
+ label: "receive_output_amount",
1250
+ raw: dto.receive_output_amount,
1251
+ decimals: outputDecimals,
1252
+ // A transaction that yields nothing is not one to sign - the user
1253
+ // would pay the deposit and receive no asset - and frontline refuses
1254
+ // to emit one. A zero here is a changed encoding, not a small order.
1255
+ // Rejecting it at the boundary is also what lets `computeOndoBuyPrice`
1256
+ // divide by it without a fallible result: the failure surfaces as the
1257
+ // data hook's ERROR state rather than as a division during render.
1258
+ reason: "a buy that yields nothing is not fillable"
1259
+ })
1260
+ };
991
1261
  }
992
- }
993
-
994
- // src/shared/types/offer-detail.ts
995
- var OfferOptionId = (value) => value;
996
- var OfferOptionSlug = (value) => value;
997
- var OfferSwapContract = {
998
- fromDto: (dto) => ({
999
- chain: Chain(dto.chain),
1000
- address: EvmContractAddress(dto.address)
1001
- })
1002
1262
  };
1003
- var OfferDetail = {
1263
+ var OndoSellTransaction = {
1004
1264
  fromDto: (dto) => {
1005
- if (!Array.isArray(dto.funding_assets)) {
1006
- throw new ValidationError(
1007
- `OfferDetail.funding_assets: expected an array, got ${typeof dto.funding_assets}`
1008
- );
1009
- }
1010
- if (!Array.isArray(dto.options)) {
1011
- throw new ValidationError(
1012
- `OfferDetail.options: expected an array, got ${typeof dto.options}`
1013
- );
1014
- }
1015
- if (!Array.isArray(dto.terms)) {
1016
- throw new ValidationError(
1017
- `OfferDetail.terms: expected an array, got ${typeof dto.terms}`
1018
- );
1019
- }
1020
- if (!Array.isArray(dto.links)) {
1021
- throw new ValidationError(
1022
- `OfferDetail.links: expected an array, got ${typeof dto.links}`
1023
- );
1024
- }
1025
- if (!Array.isArray(dto.faqs)) {
1026
- throw new ValidationError(
1027
- `OfferDetail.faqs: expected an array, got ${typeof dto.faqs}`
1028
- );
1029
- }
1030
- if (!Array.isArray(dto.milestones)) {
1031
- throw new ValidationError(
1032
- `OfferDetail.milestones: expected an array, got ${typeof dto.milestones}`
1033
- );
1034
- }
1035
- if (!Array.isArray(dto.tokens)) {
1036
- throw new ValidationError(
1037
- `OfferDetail.tokens: expected an array, got ${typeof dto.tokens}`
1038
- );
1039
- }
1040
- const swapContracts = dto.swap_contracts === void 0 ? [] : dto.swap_contracts;
1041
- if (!Array.isArray(swapContracts)) {
1042
- throw new ValidationError(
1043
- `OfferDetail.swap_contracts: expected an array, got ${typeof swapContracts}`
1044
- );
1045
- }
1265
+ const spendDecimals = AssetDecimals(dto.spend_input_decimals);
1266
+ const outputDecimals = AssetDecimals(dto.receive_output_decimals);
1267
+ const expectedQuantity = parsePositiveAmount({
1268
+ label: "expected_quantity",
1269
+ raw: dto.expected_quantity,
1270
+ decimals: outputDecimals,
1271
+ reason: "a sale that yields nothing is not fillable"
1272
+ });
1046
1273
  return {
1047
- id: OfferId(dto.id),
1048
- slug: OfferSlug(dto.slug),
1049
- type: dto.type,
1050
- name: dto.name,
1051
- asset: Asset.fromDto(dto.asset),
1052
- fundingAssets: dto.funding_assets.map(Asset.fromDto),
1053
- tokens: OfferToken.listFromDto(dto.tokens),
1054
- swapContracts: swapContracts.map(OfferSwapContract.fromDto),
1055
- about: notBlankStringOrNull(dto.about),
1056
- tagline: dto.tagline,
1057
- bannerUrl: dto.banner_url,
1058
- logoUrl: dto.logo_url,
1059
- category: dto.category,
1060
- startsAt: new Date(dto.starts_at),
1061
- endsAt: dto.ends_at ? new Date(dto.ends_at) : null,
1062
- faqs: dto.faqs.map(FaqItem.fromDto),
1063
- links: dto.links.map(Link.fromDto),
1064
- milestones: dto.milestones.map(Milestone.fromDto),
1065
- options: dto.options.map(OfferOption.fromDto),
1066
- terms: dto.terms.map(TermItem.fromDto)
1274
+ ...parseSwapCore(dto, spendDecimals),
1275
+ side: "sell",
1276
+ expected: {
1277
+ quantity: expectedQuantity,
1278
+ fee: blockchainAmountFromRawOrThrow({
1279
+ label: "expected_fee",
1280
+ raw: dto.expected_fee,
1281
+ decimals: outputDecimals
1282
+ })
1283
+ },
1284
+ minimum: {
1285
+ quantity: parseMinimumQuantity(
1286
+ dto.minimum_quantity,
1287
+ outputDecimals,
1288
+ expectedQuantity
1289
+ ),
1290
+ fee: blockchainAmountFromRawOrThrow({
1291
+ label: "minimum_fee",
1292
+ raw: dto.minimum_fee,
1293
+ decimals: outputDecimals
1294
+ })
1295
+ }
1067
1296
  };
1068
1297
  }
1069
1298
  };
1070
- var OfferOption = {
1071
- fromDto: (dto) => ({
1072
- id: OfferOptionId(dto.id),
1073
- slug: OfferOptionSlug(dto.slug),
1074
- bidIncrement: dto.bid_increment,
1075
- floorPriceUsd: dto.floor_price_usd,
1076
- minimumPurchaseUsd: dto.minimum_purchase_usd,
1077
- priceUsd: dto.price_usd,
1078
- saleAgreementUrl: notBlankStringOrNull(dto.sale_agreement_url),
1079
- totalTokenSupply: dto.total_token_supply
1080
- })
1081
- };
1082
- var FaqItem = {
1083
- fromDto: (dto) => ({
1084
- question: notBlankStringOrNull(dto.question),
1085
- answer: notBlankStringOrNull(dto.answer)
1086
- })
1087
- };
1088
- var Link = {
1089
- fromDto: (dto) => ({
1090
- label: notBlankStringOrNull(dto.label),
1091
- url: notBlankStringOrNull(dto.url)
1092
- })
1093
- };
1094
- var TermItem = {
1095
- fromDto: (dto) => ({
1096
- key: notBlankStringOrNull(dto.key),
1097
- value: notBlankStringOrNull(dto.value)
1098
- })
1099
- };
1100
- var Milestone = {
1101
- fromDto: (dto) => ({
1102
- name: notBlankStringOrNull(dto.name),
1103
- schedule: notBlankStringOrNull(dto.schedule),
1104
- status: dto.status
1105
- })
1106
- };
1107
-
1108
- // src/shared/types/providers/coin-list/token-sale.ts
1109
- var ParticipationId = (value) => value;
1110
- var Blockchain = (value) => value;
1111
- var WalletAddress = (value) => value;
1112
- var ParticipationsPaginationParams = {
1113
- toQueryParams: (params) => {
1114
- const queryParams = PaginationParams.toQueryParams(params);
1115
- if (params.offerId) {
1116
- queryParams["filters[0][field]"] = "offer_id";
1117
- queryParams["filters[0][op]"] = "==";
1118
- queryParams["filters[0][value]"] = params.offerId;
1119
- }
1120
- return queryParams;
1299
+ function parseSwapCore(dto, spendDecimals) {
1300
+ return {
1301
+ tx: {
1302
+ to: EvmContractAddress(dto.to),
1303
+ data: HexEncodedTransactionData(dto.data)
1304
+ },
1305
+ expiresAt: parseExpiresAt(dto.expires_at),
1306
+ spendInputAmount: parsePositiveAmount({
1307
+ label: "spend_input_amount",
1308
+ raw: dto.spend_input_amount,
1309
+ decimals: spendDecimals,
1310
+ // A transaction that takes nothing from the wallet is not one to sign:
1311
+ // it would settle one leg of a trade and skip the other. Frontline
1312
+ // refuses an `amount` of zero whichever way the trade runs, so this is a
1313
+ // changed encoding rather than a small order.
1314
+ //
1315
+ // Guarded on both sides rather than on the sale alone, because which
1316
+ // amount becomes the divisor in the price flips with the direction: a
1317
+ // guard placed by that would be a rule about the arithmetic rather than
1318
+ // about the trade.
1319
+ reason: "a swap that spends nothing is not fillable"
1320
+ })
1321
+ };
1322
+ }
1323
+ function parseMinimumQuantity(raw, decimals, expectedQuantity) {
1324
+ const amount = parsePositiveAmount({
1325
+ label: "minimum_quantity",
1326
+ raw,
1327
+ decimals,
1328
+ reason: "a floor of zero guarantees nothing"
1329
+ });
1330
+ if (amount.raw > expectedQuantity.raw) {
1331
+ throw new ValidationError(
1332
+ `minimum_quantity: must not exceed expected_quantity ("${raw}" > "${expectedQuantity.raw}")`
1333
+ );
1121
1334
  }
1122
- };
1123
- var Participation = {
1124
- /** Maps API DTO shape into the SDK participation domain model. */
1125
- fromDto: (dto) => {
1126
- const walletAddress = notBlankStringOrNull(dto.wallet_address);
1127
- return {
1128
- id: ParticipationId(dto.id),
1129
- offerId: OfferId(dto.offer_id),
1130
- offerOptionId: OfferOptionId(dto.offer_option_id),
1131
- status: dto.status,
1132
- amount: dto.amount,
1133
- displayAmount: dto.amount_string,
1134
- asset: Asset.fromDto(dto.asset),
1135
- chain: Blockchain(dto.chain),
1136
- insertedAt: dto.inserted_at ? new Date(dto.inserted_at) : null,
1137
- updatedAt: dto.updated_at ? new Date(dto.updated_at) : null,
1138
- walletAddress: walletAddress ? WalletAddress(walletAddress) : null
1139
- };
1335
+ return amount;
1336
+ }
1337
+ function parsePositiveAmount({
1338
+ label,
1339
+ raw,
1340
+ decimals,
1341
+ reason
1342
+ }) {
1343
+ const amount = blockchainAmountFromRawOrThrow({ label, raw, decimals });
1344
+ if (amount.raw <= 0n) {
1345
+ throw new ValidationError(
1346
+ `${label}: must be greater than zero ("${raw}") - ${reason}`
1347
+ );
1140
1348
  }
1141
- };
1142
- var CreateParticipationParams = {
1143
- /** Maps participation creation params into API DTO payload. */
1144
- toDto: (params) => ({
1145
- offer_id: params.offerId,
1146
- offer_option_id: params.offerOptionId,
1147
- chain: params.chain,
1148
- wallet_address: params.walletAddress,
1149
- amount: params.amount,
1150
- asset_id: params.assetId,
1151
- approval_transaction_hash: params.approvalTransactionHash
1152
- })
1153
- };
1154
-
1155
- // src/shared/api/frontline/providers/coin-list/token-sale.ts
1156
- async function fetchParticipations(api, offerId) {
1157
- return fetchAllPages(
1158
- (params) => fetchParticipationsPage(api, params),
1159
- { offerId }
1160
- );
1349
+ return amount;
1161
1350
  }
1162
- async function fetchParticipationsPage(api, params) {
1163
- const pageDto = await api.send({
1351
+ function parseExpiresAt(value) {
1352
+ const date = new Date(value);
1353
+ if (Number.isNaN(date.getTime())) {
1354
+ throw new ValidationError(`expires_at: not a date ("${value}")`);
1355
+ }
1356
+ return date;
1357
+ }
1358
+
1359
+ // src/universal/api/frontline/providers/ondo/ondo.ts
1360
+ async function getOndoTradingStatus(api, params) {
1361
+ const dto = await api.send({
1164
1362
  method: "GET",
1165
- url: "/v1/participations",
1166
- queryParams: ParticipationsPaginationParams.toQueryParams(params),
1363
+ url: "/v1/ondo/swap/trading-status",
1364
+ queryParams: { symbol: params.symbol, side: params.side },
1167
1365
  attributes: Attributes.protected()
1168
1366
  });
1169
- return PaginatedResponse.fromDto(pageDto, Participation.fromDto);
1367
+ return OndoTradingStatus.fromDto(dto);
1170
1368
  }
1171
- async function fetchParticipation(api, id) {
1369
+ async function getOndoQuote(api, params) {
1172
1370
  const dto = await api.send({
1173
1371
  method: "GET",
1174
- url: `/v1/participations/${id}`,
1372
+ url: "/v1/ondo/swap/quote",
1373
+ queryParams: {
1374
+ symbol: params.symbol,
1375
+ side: params.side,
1376
+ duration: params.duration,
1377
+ ...sizeParam(params)
1378
+ },
1175
1379
  attributes: Attributes.protected()
1176
1380
  });
1177
- return Participation.fromDto(dto);
1381
+ return OndoQuote.fromDto(dto);
1178
1382
  }
1179
- async function createParticipation(api, params) {
1383
+ async function buildOndoBuy(api, params) {
1180
1384
  const dto = await api.send({
1181
1385
  method: "POST",
1182
- url: "/v1/participations",
1183
- body: CreateParticipationParams.toDto(params),
1386
+ url: "/v1/ondo/swap/buy",
1387
+ body: swapBody(params),
1184
1388
  attributes: Attributes.protected()
1185
1389
  });
1186
- return Participation.fromDto(dto);
1390
+ assertSpendScaleAgrees({
1391
+ published: dto.spend_input_decimals,
1392
+ sized: params.amount,
1393
+ trade: "purchase"
1394
+ });
1395
+ return OndoBuyTransaction.fromDto(dto);
1396
+ }
1397
+ async function buildOndoSell(api, params) {
1398
+ const dto = await api.send({
1399
+ method: "POST",
1400
+ url: "/v1/ondo/swap/sell",
1401
+ body: swapBody(params),
1402
+ attributes: Attributes.protected()
1403
+ });
1404
+ assertSpendScaleAgrees({
1405
+ published: dto.spend_input_decimals,
1406
+ sized: params.amount,
1407
+ trade: "sale",
1408
+ // The two answers come from two chains, so on a testnet they can disagree
1409
+ // for a reason that is neither the caller's nor a corrupt response. Say so,
1410
+ // or a QA run reads as a puzzle rather than a diagnosis.
1411
+ note: "the quote resolves the asset on Ethereum mainnet while the swap executes on the chain requested, so these disagree until frontline serves a chain-scoped quote"
1412
+ });
1413
+ return OndoSellTransaction.fromDto(dto);
1414
+ }
1415
+ function swapBody(params) {
1416
+ return {
1417
+ symbol: params.symbol,
1418
+ chain: params.chain,
1419
+ wallet_address: params.walletAddress,
1420
+ amount: params.amount.raw.toString()
1421
+ };
1422
+ }
1423
+ function assertSpendScaleAgrees({
1424
+ published,
1425
+ sized,
1426
+ trade,
1427
+ note
1428
+ }) {
1429
+ if (published === sized.decimals) return;
1430
+ const because = note === void 0 ? "" : ` - ${note}`;
1431
+ throw new ValidationError(
1432
+ `spend_input_decimals: the ${trade} was priced in ${published} decimals but the order was sized in ${sized.decimals}${because}`
1433
+ );
1434
+ }
1435
+ function sizeParam(params) {
1436
+ const tokenAmount = "tokenAmount" in params ? params.tokenAmount : void 0;
1437
+ const notionalValue = "notionalValue" in params ? params.notionalValue : void 0;
1438
+ if (tokenAmount !== void 0) {
1439
+ if (notionalValue !== void 0) {
1440
+ throw new ValidationError(
1441
+ "An Ondo quote takes tokenAmount or notionalValue, not both"
1442
+ );
1443
+ }
1444
+ return { token_amount: formatRawAmount(tokenAmount) };
1445
+ }
1446
+ if (notionalValue === void 0) {
1447
+ throw new ValidationError(
1448
+ "An Ondo quote must be sized by tokenAmount or notionalValue"
1449
+ );
1450
+ }
1451
+ return { notional_value: notionalValue };
1187
1452
  }
1188
1453
 
1189
- // src/shared/core/checkout/coin-list/token-sale-namespace.ts
1190
- var CoinListTokenSaleNamespaceImpl = class {
1454
+ // src/universal/core/checkout/ondo/ondo-namespace.ts
1455
+ var OndoNamespaceImpl = class {
1191
1456
  constructor(ctx) {
1192
1457
  this.ctx = ctx;
1193
- this.log = internalLogger(ctx.logger, "TOKEN_SALE");
1458
+ this.log = internalLogger(ctx.logger, "ONDO");
1194
1459
  }
1195
- async list(offerId) {
1196
- return this.log.wrap("list", offerId, async () => {
1460
+ async getTradingStatus(params) {
1461
+ return this.log.wrap("getTradingStatus", params, async () => {
1197
1462
  await this.ctx.ensureUserAuthenticated();
1198
- return fetchParticipations(this.ctx.api, offerId);
1463
+ return getOndoTradingStatus(this.ctx.api, params);
1199
1464
  });
1200
1465
  }
1201
- async listPage(params) {
1202
- return this.log.wrap("listPage", params, async () => {
1466
+ async getQuote(params) {
1467
+ return this.log.wrap("getQuote", params, async () => {
1203
1468
  await this.ctx.ensureUserAuthenticated();
1204
- return fetchParticipationsPage(this.ctx.api, params);
1469
+ return getOndoQuote(this.ctx.api, params);
1205
1470
  });
1206
1471
  }
1207
- async get(id) {
1208
- return this.log.wrap("get", id, async () => {
1472
+ async buildBuyTransaction(params) {
1473
+ return this.log.wrap("buildBuyTransaction", params, async () => {
1209
1474
  await this.ctx.ensureUserAuthenticated();
1210
- return fetchParticipation(this.ctx.api, id);
1475
+ return buildOndoBuy(this.ctx.api, params);
1211
1476
  });
1212
1477
  }
1213
- async createParticipation(params) {
1214
- return this.log.wrap("createParticipation", params, async () => {
1478
+ async buildSellTransaction(params) {
1479
+ return this.log.wrap("buildSellTransaction", params, async () => {
1215
1480
  await this.ctx.ensureUserAuthenticated();
1216
- return createParticipation(this.ctx.api, params);
1481
+ return buildOndoSell(this.ctx.api, params);
1217
1482
  });
1218
1483
  }
1219
1484
  };
1220
1485
 
1221
- // src/shared/types/trading.ts
1222
- var Ticker = (value) => value;
1223
-
1224
- // src/shared/types/providers/ondo/ondo.ts
1225
- var OndoTradingStatus = {
1226
- fromDto: (dto) => {
1227
- if (!dto.tradable) return { type: "not-tradable", side: dto.side };
1228
- return {
1229
- type: "tradable",
1230
- side: dto.side,
1231
- grossMaxTokens: decimalOrNull(dto.gross_max_tokens),
1232
- grossMaxNotionalValue: decimalOrNull(dto.gross_max_notional_value),
1233
- grossMaxActiveNotionalValue: decimalOrNull(
1234
- dto.gross_max_active_notional_value
1235
- )
1236
- };
1237
- }
1238
- };
1239
- var decimalOrNull = (value) => value === null ? null : DecimalString(value);
1240
- var OndoQuote = {
1241
- fromDto: (dto) => {
1242
- const assetDecimals = AssetDecimals(dto.asset_decimals);
1243
- return {
1244
- chain: chainFromId(dto.chain_id),
1245
- ticker: Ticker(dto.ticker),
1246
- assetAddress: EvmContractAddress(dto.asset_address),
1247
- asset: {
1248
- name: dto.ticker,
1249
- symbol: AssetSymbol(dto.symbol),
1250
- decimals: assetDecimals
1486
+ // src/universal/core/checkout/superstate/blockchain/abi.ts
1487
+ var SUPERSTATE_SWAP_ABI = [
1488
+ {
1489
+ type: "function",
1490
+ name: "KIND",
1491
+ inputs: [],
1492
+ outputs: [
1493
+ {
1494
+ name: "",
1495
+ type: "uint16",
1496
+ internalType: "uint16"
1497
+ }
1498
+ ],
1499
+ stateMutability: "view"
1500
+ },
1501
+ {
1502
+ type: "function",
1503
+ name: "ONE_HUNDRED_P",
1504
+ inputs: [],
1505
+ outputs: [
1506
+ {
1507
+ name: "",
1508
+ type: "uint256",
1509
+ internalType: "uint256"
1510
+ }
1511
+ ],
1512
+ stateMutability: "view"
1513
+ },
1514
+ {
1515
+ type: "function",
1516
+ name: "SWAP_LEVEL",
1517
+ inputs: [],
1518
+ outputs: [
1519
+ {
1520
+ name: "",
1521
+ type: "uint32",
1522
+ internalType: "uint32"
1523
+ }
1524
+ ],
1525
+ stateMutability: "view"
1526
+ },
1527
+ {
1528
+ type: "function",
1529
+ name: "VERSION",
1530
+ inputs: [],
1531
+ outputs: [
1532
+ {
1533
+ name: "",
1534
+ type: "uint16",
1535
+ internalType: "uint16"
1536
+ }
1537
+ ],
1538
+ stateMutability: "view"
1539
+ },
1540
+ {
1541
+ type: "function",
1542
+ name: "authorized",
1543
+ inputs: [
1544
+ {
1545
+ name: "user",
1546
+ type: "address",
1547
+ internalType: "address"
1548
+ }
1549
+ ],
1550
+ outputs: [
1551
+ {
1552
+ name: "",
1553
+ type: "bool",
1554
+ internalType: "bool"
1555
+ }
1556
+ ],
1557
+ stateMutability: "view"
1558
+ },
1559
+ {
1560
+ type: "function",
1561
+ name: "bpp",
1562
+ inputs: [
1563
+ {
1564
+ name: "amount",
1565
+ type: "uint256",
1566
+ internalType: "uint256"
1567
+ }
1568
+ ],
1569
+ outputs: [
1570
+ {
1571
+ name: "",
1572
+ type: "uint256",
1573
+ internalType: "uint256"
1574
+ }
1575
+ ],
1576
+ stateMutability: "view"
1577
+ },
1578
+ {
1579
+ type: "function",
1580
+ name: "bps",
1581
+ inputs: [],
1582
+ outputs: [
1583
+ {
1584
+ name: "",
1585
+ type: "uint256",
1586
+ internalType: "uint256"
1587
+ }
1588
+ ],
1589
+ stateMutability: "view"
1590
+ },
1591
+ {
1592
+ type: "function",
1593
+ name: "cancelOwnershipHandover",
1594
+ inputs: [],
1595
+ outputs: [],
1596
+ stateMutability: "payable"
1597
+ },
1598
+ {
1599
+ type: "function",
1600
+ name: "completeOwnershipHandover",
1601
+ inputs: [
1602
+ {
1603
+ name: "pendingOwner",
1604
+ type: "address",
1605
+ internalType: "address"
1606
+ }
1607
+ ],
1608
+ outputs: [],
1609
+ stateMutability: "payable"
1610
+ },
1611
+ {
1612
+ type: "function",
1613
+ name: "fee",
1614
+ inputs: [
1615
+ {
1616
+ name: "amount",
1617
+ type: "uint256",
1618
+ internalType: "uint256"
1619
+ }
1620
+ ],
1621
+ outputs: [
1622
+ {
1623
+ name: "",
1624
+ type: "uint256",
1625
+ internalType: "uint256"
1251
1626
  },
1252
- side: dto.side,
1253
- tokenBaseUnits: blockchainAmountFromRawOrThrow({
1254
- label: "tokenBaseUnits",
1255
- raw: dto.token_base_units,
1256
- decimals: assetDecimals
1257
- }),
1258
- price: DecimalString(dto.price)
1259
- };
1260
- }
1261
- };
1262
- var OndoBuyTransaction = {
1263
- fromDto: (dto) => {
1264
- const spendDecimals = AssetDecimals(dto.spend_input_decimals);
1265
- const outputDecimals = AssetDecimals(dto.receive_output_decimals);
1266
- return {
1267
- ...parseSwapCore(dto, spendDecimals),
1268
- side: "buy",
1269
- fee: blockchainAmountFromRawOrThrow({
1270
- label: "fee",
1271
- raw: dto.fee,
1272
- decimals: spendDecimals
1273
- }),
1274
- notionalValue: blockchainAmountFromRawOrThrow({
1275
- label: "notional_value",
1276
- raw: dto.notional_value,
1277
- decimals: spendDecimals
1278
- }),
1279
- receiveOutputAmount: parsePositiveAmount({
1280
- label: "receive_output_amount",
1281
- raw: dto.receive_output_amount,
1282
- decimals: outputDecimals,
1283
- // A transaction that yields nothing is not one to sign - the user
1284
- // would pay the deposit and receive no asset - and frontline refuses
1285
- // to emit one. A zero here is a changed encoding, not a small order.
1286
- // Rejecting it at the boundary is also what lets `computeOndoBuyPrice`
1287
- // divide by it without a fallible result: the failure surfaces as the
1288
- // data hook's ERROR state rather than as a division during render.
1289
- reason: "a buy that yields nothing is not fillable"
1290
- })
1291
- };
1292
- }
1293
- };
1294
- var OndoSellTransaction = {
1295
- fromDto: (dto) => {
1296
- const spendDecimals = AssetDecimals(dto.spend_input_decimals);
1297
- const outputDecimals = AssetDecimals(dto.receive_output_decimals);
1298
- const expectedQuantity = parsePositiveAmount({
1299
- label: "expected_quantity",
1300
- raw: dto.expected_quantity,
1301
- decimals: outputDecimals,
1302
- reason: "a sale that yields nothing is not fillable"
1303
- });
1304
- return {
1305
- ...parseSwapCore(dto, spendDecimals),
1306
- side: "sell",
1307
- expected: {
1308
- quantity: expectedQuantity,
1309
- fee: blockchainAmountFromRawOrThrow({
1310
- label: "expected_fee",
1311
- raw: dto.expected_fee,
1312
- decimals: outputDecimals
1313
- })
1627
+ {
1628
+ name: "",
1629
+ type: "uint256",
1630
+ internalType: "uint256"
1631
+ }
1632
+ ],
1633
+ stateMutability: "view"
1634
+ },
1635
+ {
1636
+ type: "function",
1637
+ name: "id",
1638
+ inputs: [],
1639
+ outputs: [
1640
+ {
1641
+ name: "",
1642
+ type: "bytes32",
1643
+ internalType: "bytes32"
1644
+ }
1645
+ ],
1646
+ stateMutability: "view"
1647
+ },
1648
+ {
1649
+ type: "function",
1650
+ name: "inputTokens",
1651
+ inputs: [
1652
+ {
1653
+ name: "",
1654
+ type: "address",
1655
+ internalType: "address"
1656
+ }
1657
+ ],
1658
+ outputs: [
1659
+ {
1660
+ name: "",
1661
+ type: "bool",
1662
+ internalType: "bool"
1663
+ }
1664
+ ],
1665
+ stateMutability: "view"
1666
+ },
1667
+ {
1668
+ type: "function",
1669
+ name: "outputToken",
1670
+ inputs: [],
1671
+ outputs: [
1672
+ {
1673
+ name: "",
1674
+ type: "address",
1675
+ internalType: "address"
1676
+ }
1677
+ ],
1678
+ stateMutability: "view"
1679
+ },
1680
+ {
1681
+ type: "function",
1682
+ name: "outputTokenBalance",
1683
+ inputs: [],
1684
+ outputs: [
1685
+ {
1686
+ name: "",
1687
+ type: "uint256",
1688
+ internalType: "uint256"
1689
+ }
1690
+ ],
1691
+ stateMutability: "view"
1692
+ },
1693
+ {
1694
+ type: "function",
1695
+ name: "owner",
1696
+ inputs: [],
1697
+ outputs: [
1698
+ {
1699
+ name: "result",
1700
+ type: "address",
1701
+ internalType: "address"
1702
+ }
1703
+ ],
1704
+ stateMutability: "view"
1705
+ },
1706
+ {
1707
+ type: "function",
1708
+ name: "ownershipHandoverExpiresAt",
1709
+ inputs: [
1710
+ {
1711
+ name: "pendingOwner",
1712
+ type: "address",
1713
+ internalType: "address"
1714
+ }
1715
+ ],
1716
+ outputs: [
1717
+ {
1718
+ name: "result",
1719
+ type: "uint256",
1720
+ internalType: "uint256"
1721
+ }
1722
+ ],
1723
+ stateMutability: "view"
1724
+ },
1725
+ {
1726
+ type: "function",
1727
+ name: "pause",
1728
+ inputs: [
1729
+ {
1730
+ name: "level",
1731
+ type: "uint32",
1732
+ internalType: "uint32"
1733
+ }
1734
+ ],
1735
+ outputs: [
1736
+ {
1737
+ name: "",
1738
+ type: "bool",
1739
+ internalType: "bool"
1740
+ }
1741
+ ],
1742
+ stateMutability: "nonpayable"
1743
+ },
1744
+ {
1745
+ type: "function",
1746
+ name: "paused",
1747
+ inputs: [],
1748
+ outputs: [
1749
+ {
1750
+ name: "",
1751
+ type: "uint32",
1752
+ internalType: "uint32"
1753
+ }
1754
+ ],
1755
+ stateMutability: "view"
1756
+ },
1757
+ {
1758
+ type: "function",
1759
+ name: "preview",
1760
+ inputs: [
1761
+ {
1762
+ name: "token",
1763
+ type: "address",
1764
+ internalType: "address"
1314
1765
  },
1315
- minimum: {
1316
- quantity: parseMinimumQuantity(
1317
- dto.minimum_quantity,
1318
- outputDecimals,
1319
- expectedQuantity
1320
- ),
1321
- fee: blockchainAmountFromRawOrThrow({
1322
- label: "minimum_fee",
1323
- raw: dto.minimum_fee,
1324
- decimals: outputDecimals
1325
- })
1766
+ {
1767
+ name: "amount",
1768
+ type: "uint256",
1769
+ internalType: "uint256"
1326
1770
  }
1327
- };
1771
+ ],
1772
+ outputs: [
1773
+ {
1774
+ name: "",
1775
+ type: "tuple",
1776
+ internalType: "struct Preview",
1777
+ components: [
1778
+ {
1779
+ name: "input",
1780
+ type: "uint256",
1781
+ internalType: "uint256"
1782
+ },
1783
+ {
1784
+ name: "fee",
1785
+ type: "uint256",
1786
+ internalType: "uint256"
1787
+ },
1788
+ {
1789
+ name: "output",
1790
+ type: "uint256",
1791
+ internalType: "uint256"
1792
+ }
1793
+ ]
1794
+ }
1795
+ ],
1796
+ stateMutability: "view"
1797
+ },
1798
+ {
1799
+ type: "function",
1800
+ name: "renounceOwnership",
1801
+ inputs: [],
1802
+ outputs: [],
1803
+ stateMutability: "payable"
1804
+ },
1805
+ {
1806
+ type: "function",
1807
+ name: "requestOwnershipHandover",
1808
+ inputs: [],
1809
+ outputs: [],
1810
+ stateMutability: "payable"
1811
+ },
1812
+ {
1813
+ type: "function",
1814
+ name: "setBps",
1815
+ inputs: [
1816
+ {
1817
+ name: "points",
1818
+ type: "uint256",
1819
+ internalType: "uint256"
1820
+ }
1821
+ ],
1822
+ outputs: [
1823
+ {
1824
+ name: "",
1825
+ type: "bool",
1826
+ internalType: "bool"
1827
+ }
1828
+ ],
1829
+ stateMutability: "nonpayable"
1830
+ },
1831
+ {
1832
+ type: "function",
1833
+ name: "setInputToken",
1834
+ inputs: [
1835
+ {
1836
+ name: "token",
1837
+ type: "address",
1838
+ internalType: "address"
1839
+ },
1840
+ {
1841
+ name: "val",
1842
+ type: "bool",
1843
+ internalType: "bool"
1844
+ }
1845
+ ],
1846
+ outputs: [
1847
+ {
1848
+ name: "",
1849
+ type: "bool",
1850
+ internalType: "bool"
1851
+ }
1852
+ ],
1853
+ stateMutability: "nonpayable"
1854
+ },
1855
+ {
1856
+ type: "function",
1857
+ name: "status",
1858
+ inputs: [],
1859
+ outputs: [
1860
+ {
1861
+ name: "",
1862
+ type: "tuple",
1863
+ internalType: "struct Status",
1864
+ components: [
1865
+ {
1866
+ name: "flags",
1867
+ type: "uint32",
1868
+ internalType: "uint32"
1869
+ },
1870
+ {
1871
+ name: "state",
1872
+ type: "uint8",
1873
+ internalType: "enum State"
1874
+ }
1875
+ ]
1876
+ }
1877
+ ],
1878
+ stateMutability: "view"
1879
+ },
1880
+ {
1881
+ type: "function",
1882
+ name: "stop",
1883
+ inputs: [],
1884
+ outputs: [
1885
+ {
1886
+ name: "",
1887
+ type: "bool",
1888
+ internalType: "bool"
1889
+ }
1890
+ ],
1891
+ stateMutability: "nonpayable"
1892
+ },
1893
+ {
1894
+ type: "function",
1895
+ name: "stopped",
1896
+ inputs: [],
1897
+ outputs: [
1898
+ {
1899
+ name: "",
1900
+ type: "bool",
1901
+ internalType: "bool"
1902
+ }
1903
+ ],
1904
+ stateMutability: "view"
1905
+ },
1906
+ {
1907
+ type: "function",
1908
+ name: "swap",
1909
+ inputs: [
1910
+ {
1911
+ name: "token",
1912
+ type: "address",
1913
+ internalType: "address"
1914
+ },
1915
+ {
1916
+ name: "amount",
1917
+ type: "uint256",
1918
+ internalType: "uint256"
1919
+ },
1920
+ {
1921
+ name: "slip",
1922
+ type: "uint256",
1923
+ internalType: "uint256"
1924
+ }
1925
+ ],
1926
+ outputs: [
1927
+ {
1928
+ name: "",
1929
+ type: "uint256",
1930
+ internalType: "uint256"
1931
+ }
1932
+ ],
1933
+ stateMutability: "nonpayable"
1934
+ },
1935
+ {
1936
+ type: "function",
1937
+ name: "tokenBalance",
1938
+ inputs: [
1939
+ {
1940
+ name: "token",
1941
+ type: "address",
1942
+ internalType: "address"
1943
+ }
1944
+ ],
1945
+ outputs: [
1946
+ {
1947
+ name: "",
1948
+ type: "uint256",
1949
+ internalType: "uint256"
1950
+ }
1951
+ ],
1952
+ stateMutability: "view"
1953
+ },
1954
+ {
1955
+ type: "function",
1956
+ name: "totals",
1957
+ inputs: [
1958
+ {
1959
+ name: "user",
1960
+ type: "address",
1961
+ internalType: "address"
1962
+ },
1963
+ {
1964
+ name: "token",
1965
+ type: "address",
1966
+ internalType: "address"
1967
+ }
1968
+ ],
1969
+ outputs: [
1970
+ {
1971
+ name: "",
1972
+ type: "tuple",
1973
+ internalType: "struct SwapTotal",
1974
+ components: [
1975
+ {
1976
+ name: "inputSum",
1977
+ type: "uint256",
1978
+ internalType: "uint256"
1979
+ },
1980
+ {
1981
+ name: "feeSum",
1982
+ type: "uint256",
1983
+ internalType: "uint256"
1984
+ },
1985
+ {
1986
+ name: "outputSum",
1987
+ type: "uint256",
1988
+ internalType: "uint256"
1989
+ },
1990
+ {
1991
+ name: "count",
1992
+ type: "uint256",
1993
+ internalType: "uint256"
1994
+ }
1995
+ ]
1996
+ }
1997
+ ],
1998
+ stateMutability: "view"
1999
+ },
2000
+ {
2001
+ type: "function",
2002
+ name: "totals",
2003
+ inputs: [
2004
+ {
2005
+ name: "token",
2006
+ type: "address",
2007
+ internalType: "address"
2008
+ }
2009
+ ],
2010
+ outputs: [
2011
+ {
2012
+ name: "",
2013
+ type: "tuple",
2014
+ internalType: "struct SwapTotal",
2015
+ components: [
2016
+ {
2017
+ name: "inputSum",
2018
+ type: "uint256",
2019
+ internalType: "uint256"
2020
+ },
2021
+ {
2022
+ name: "feeSum",
2023
+ type: "uint256",
2024
+ internalType: "uint256"
2025
+ },
2026
+ {
2027
+ name: "outputSum",
2028
+ type: "uint256",
2029
+ internalType: "uint256"
2030
+ },
2031
+ {
2032
+ name: "count",
2033
+ type: "uint256",
2034
+ internalType: "uint256"
2035
+ }
2036
+ ]
2037
+ }
2038
+ ],
2039
+ stateMutability: "view"
2040
+ },
2041
+ {
2042
+ type: "function",
2043
+ name: "transfer",
2044
+ inputs: [
2045
+ {
2046
+ name: "to",
2047
+ type: "address",
2048
+ internalType: "address"
2049
+ },
2050
+ {
2051
+ name: "amount",
2052
+ type: "uint256",
2053
+ internalType: "uint256"
2054
+ }
2055
+ ],
2056
+ outputs: [
2057
+ {
2058
+ name: "",
2059
+ type: "bool",
2060
+ internalType: "bool"
2061
+ }
2062
+ ],
2063
+ stateMutability: "nonpayable"
2064
+ },
2065
+ {
2066
+ type: "function",
2067
+ name: "transfer",
2068
+ inputs: [
2069
+ {
2070
+ name: "to",
2071
+ type: "address",
2072
+ internalType: "address"
2073
+ },
2074
+ {
2075
+ name: "token",
2076
+ type: "address",
2077
+ internalType: "address"
2078
+ },
2079
+ {
2080
+ name: "amount",
2081
+ type: "uint256",
2082
+ internalType: "uint256"
2083
+ }
2084
+ ],
2085
+ outputs: [
2086
+ {
2087
+ name: "",
2088
+ type: "bool",
2089
+ internalType: "bool"
2090
+ }
2091
+ ],
2092
+ stateMutability: "nonpayable"
2093
+ },
2094
+ {
2095
+ type: "function",
2096
+ name: "transferOwnership",
2097
+ inputs: [
2098
+ {
2099
+ name: "newOwner",
2100
+ type: "address",
2101
+ internalType: "address"
2102
+ }
2103
+ ],
2104
+ outputs: [],
2105
+ stateMutability: "payable"
2106
+ },
2107
+ {
2108
+ type: "event",
2109
+ name: "BpsUpdated",
2110
+ inputs: [
2111
+ {
2112
+ name: "prev",
2113
+ type: "uint256",
2114
+ indexed: false,
2115
+ internalType: "uint256"
2116
+ },
2117
+ {
2118
+ name: "next",
2119
+ type: "uint256",
2120
+ indexed: false,
2121
+ internalType: "uint256"
2122
+ }
2123
+ ],
2124
+ anonymous: false
2125
+ },
2126
+ {
2127
+ type: "event",
2128
+ name: "InputTokenUpdated",
2129
+ inputs: [
2130
+ {
2131
+ name: "token",
2132
+ type: "address",
2133
+ indexed: true,
2134
+ internalType: "address"
2135
+ },
2136
+ {
2137
+ name: "prev",
2138
+ type: "bool",
2139
+ indexed: false,
2140
+ internalType: "bool"
2141
+ },
2142
+ {
2143
+ name: "next",
2144
+ type: "bool",
2145
+ indexed: false,
2146
+ internalType: "bool"
2147
+ }
2148
+ ],
2149
+ anonymous: false
2150
+ },
2151
+ {
2152
+ type: "event",
2153
+ name: "OwnershipHandoverCanceled",
2154
+ inputs: [
2155
+ {
2156
+ name: "pendingOwner",
2157
+ type: "address",
2158
+ indexed: true,
2159
+ internalType: "address"
2160
+ }
2161
+ ],
2162
+ anonymous: false
2163
+ },
2164
+ {
2165
+ type: "event",
2166
+ name: "OwnershipHandoverRequested",
2167
+ inputs: [
2168
+ {
2169
+ name: "pendingOwner",
2170
+ type: "address",
2171
+ indexed: true,
2172
+ internalType: "address"
2173
+ }
2174
+ ],
2175
+ anonymous: false
2176
+ },
2177
+ {
2178
+ type: "event",
2179
+ name: "OwnershipTransferred",
2180
+ inputs: [
2181
+ {
2182
+ name: "oldOwner",
2183
+ type: "address",
2184
+ indexed: true,
2185
+ internalType: "address"
2186
+ },
2187
+ {
2188
+ name: "newOwner",
2189
+ type: "address",
2190
+ indexed: true,
2191
+ internalType: "address"
2192
+ }
2193
+ ],
2194
+ anonymous: false
2195
+ },
2196
+ {
2197
+ type: "event",
2198
+ name: "Paused",
2199
+ inputs: [
2200
+ {
2201
+ name: "previous",
2202
+ type: "uint32",
2203
+ indexed: false,
2204
+ internalType: "uint32"
2205
+ },
2206
+ {
2207
+ name: "next",
2208
+ type: "uint32",
2209
+ indexed: false,
2210
+ internalType: "uint32"
2211
+ }
2212
+ ],
2213
+ anonymous: false
2214
+ },
2215
+ {
2216
+ type: "event",
2217
+ name: "Stopped",
2218
+ inputs: [],
2219
+ anonymous: false
2220
+ },
2221
+ {
2222
+ type: "event",
2223
+ name: "Swapped",
2224
+ inputs: [
2225
+ {
2226
+ name: "user",
2227
+ type: "address",
2228
+ indexed: true,
2229
+ internalType: "address"
2230
+ },
2231
+ {
2232
+ name: "inputToken",
2233
+ type: "address",
2234
+ indexed: true,
2235
+ internalType: "address"
2236
+ },
2237
+ {
2238
+ name: "outputToken",
2239
+ type: "address",
2240
+ indexed: true,
2241
+ internalType: "address"
2242
+ },
2243
+ {
2244
+ name: "inputAmount",
2245
+ type: "uint256",
2246
+ indexed: false,
2247
+ internalType: "uint256"
2248
+ },
2249
+ {
2250
+ name: "fee",
2251
+ type: "uint256",
2252
+ indexed: false,
2253
+ internalType: "uint256"
2254
+ },
2255
+ {
2256
+ name: "outputAmount",
2257
+ type: "uint256",
2258
+ indexed: false,
2259
+ internalType: "uint256"
2260
+ }
2261
+ ],
2262
+ anonymous: false
2263
+ },
2264
+ {
2265
+ type: "event",
2266
+ name: "Transferred",
2267
+ inputs: [
2268
+ {
2269
+ name: "to",
2270
+ type: "address",
2271
+ indexed: true,
2272
+ internalType: "address"
2273
+ },
2274
+ {
2275
+ name: "token",
2276
+ type: "address",
2277
+ indexed: true,
2278
+ internalType: "address"
2279
+ },
2280
+ {
2281
+ name: "amount",
2282
+ type: "uint256",
2283
+ indexed: false,
2284
+ internalType: "uint256"
2285
+ }
2286
+ ],
2287
+ anonymous: false
2288
+ },
2289
+ {
2290
+ type: "error",
2291
+ name: "AlreadyInitialized",
2292
+ inputs: []
2293
+ },
2294
+ {
2295
+ type: "error",
2296
+ name: "InsufficientAmount",
2297
+ inputs: []
2298
+ },
2299
+ {
2300
+ type: "error",
2301
+ name: "InvalidAddress",
2302
+ inputs: []
2303
+ },
2304
+ {
2305
+ type: "error",
2306
+ name: "InvalidAmount",
2307
+ inputs: []
2308
+ },
2309
+ {
2310
+ type: "error",
2311
+ name: "IsPaused",
2312
+ inputs: [
2313
+ {
2314
+ name: "level",
2315
+ type: "uint32",
2316
+ internalType: "uint32"
2317
+ }
2318
+ ]
2319
+ },
2320
+ {
2321
+ type: "error",
2322
+ name: "IsStopped",
2323
+ inputs: []
2324
+ },
2325
+ {
2326
+ type: "error",
2327
+ name: "NewOwnerIsZeroAddress",
2328
+ inputs: []
2329
+ },
2330
+ {
2331
+ type: "error",
2332
+ name: "NoHandoverRequest",
2333
+ inputs: []
2334
+ },
2335
+ {
2336
+ type: "error",
2337
+ name: "SwapFailed",
2338
+ inputs: [
2339
+ {
2340
+ name: "user",
2341
+ type: "address",
2342
+ internalType: "address"
2343
+ },
2344
+ {
2345
+ name: "token",
2346
+ type: "address",
2347
+ internalType: "address"
2348
+ }
2349
+ ]
2350
+ },
2351
+ {
2352
+ type: "error",
2353
+ name: "Unauthorized",
2354
+ inputs: []
1328
2355
  }
2356
+ ];
2357
+
2358
+ // src/universal/types/providers/superstate/swap.ts
2359
+ var SwapPreview = {
2360
+ /** Maps the contract's `Preview { input, fee, output }` struct. */
2361
+ fromContract: (preview) => ({
2362
+ inputAmount: parseUint256(preview.input, "SwapPreview.input"),
2363
+ fee: parseUint256(preview.fee, "SwapPreview.fee"),
2364
+ outputAmount: parseUint256(preview.output, "SwapPreview.output")
2365
+ })
1329
2366
  };
1330
- function parseSwapCore(dto, spendDecimals) {
1331
- return {
1332
- tx: {
1333
- to: EvmContractAddress(dto.to),
1334
- data: HexEncodedTransactionData(dto.data)
1335
- },
1336
- expiresAt: parseExpiresAt(dto.expires_at),
1337
- spendInputAmount: parsePositiveAmount({
1338
- label: "spend_input_amount",
1339
- raw: dto.spend_input_amount,
1340
- decimals: spendDecimals,
1341
- // A transaction that takes nothing from the wallet is not one to sign:
1342
- // it would settle one leg of a trade and skip the other. Frontline
1343
- // refuses an `amount` of zero whichever way the trade runs, so this is a
1344
- // changed encoding rather than a small order.
1345
- //
1346
- // Guarded on both sides rather than on the sale alone, because which
1347
- // amount becomes the divisor in the price flips with the direction: a
1348
- // guard placed by that would be a rule about the arithmetic rather than
1349
- // about the trade.
1350
- reason: "a swap that spends nothing is not fillable"
1351
- })
1352
- };
1353
- }
1354
- function parseMinimumQuantity(raw, decimals, expectedQuantity) {
1355
- const amount = parsePositiveAmount({
1356
- label: "minimum_quantity",
1357
- raw,
1358
- decimals,
1359
- reason: "a floor of zero guarantees nothing"
1360
- });
1361
- if (amount.raw > expectedQuantity.raw) {
1362
- throw new ValidationError(
1363
- `minimum_quantity: must not exceed expected_quantity ("${raw}" > "${expectedQuantity.raw}")`
1364
- );
1365
- }
1366
- return amount;
1367
- }
1368
- function parsePositiveAmount({
1369
- label,
1370
- raw,
1371
- decimals,
1372
- reason
1373
- }) {
1374
- const amount = blockchainAmountFromRawOrThrow({ label, raw, decimals });
1375
- if (amount.raw <= 0n) {
1376
- throw new ValidationError(
1377
- `${label}: must be greater than zero ("${raw}") - ${reason}`
1378
- );
2367
+ var PauseFlags = (value) => value;
2368
+ var SwapStatus = {
2369
+ /**
2370
+ * Maps the contract's `Status { uint32 flags; State state }` struct, where
2371
+ * `State` is `0 = Active | 1 = Paused | 2 = Stopped`.
2372
+ *
2373
+ * `flags` is carried onto the `paused` arm only. On the other two the
2374
+ * contract sets it to a self-identifying marker rather than to information -
2375
+ * so repeating it would invite a caller to read meaning into a constant.
2376
+ *
2377
+ * @throws ValidationError on a `state` outside the enum. A contract that has
2378
+ * grown a fourth state is one the SDK does not model, and guessing `active`
2379
+ * would let a halted swap read as a live one.
2380
+ */
2381
+ fromContract: (status) => {
2382
+ switch (status.state) {
2383
+ case 0:
2384
+ return { state: "active" };
2385
+ case 1:
2386
+ return { state: "paused", pausedLevels: PauseFlags(status.flags) };
2387
+ case 2:
2388
+ return { state: "stopped" };
2389
+ default:
2390
+ throw new ValidationError(
2391
+ `SwapStatus.state: unknown contract state (${status.state})`
2392
+ );
2393
+ }
1379
2394
  }
1380
- return amount;
1381
- }
1382
- function parseExpiresAt(value) {
1383
- const date = new Date(value);
1384
- if (Number.isNaN(date.getTime())) {
1385
- throw new ValidationError(`expires_at: not a date ("${value}")`);
2395
+ };
2396
+ var AllowWalletResponse = {
2397
+ fromDto: (dto) => {
2398
+ switch (dto.action) {
2399
+ case "broadcast_transaction":
2400
+ return {
2401
+ action: "broadcast_transaction",
2402
+ to: EvmContractAddress(dto.to),
2403
+ data: HexEncodedTransactionData(dto.data)
2404
+ };
2405
+ case "none":
2406
+ return {
2407
+ action: "none",
2408
+ alreadyAllowed: dto.already_allowed
2409
+ };
2410
+ default: {
2411
+ const _exhaustive = dto;
2412
+ return _exhaustive;
2413
+ }
2414
+ }
1386
2415
  }
1387
- return date;
1388
- }
2416
+ };
1389
2417
 
1390
- // src/shared/api/frontline/providers/ondo/ondo.ts
1391
- async function getOndoTradingStatus(api, params) {
1392
- const dto = await api.send({
1393
- method: "GET",
1394
- url: "/v1/ondo/swap/trading-status",
1395
- queryParams: { symbol: params.symbol, side: params.side },
1396
- attributes: Attributes.protected()
1397
- });
1398
- return OndoTradingStatus.fromDto(dto);
1399
- }
1400
- async function getOndoQuote(api, params) {
2418
+ // src/universal/api/frontline/providers/superstate/swap.ts
2419
+ async function allowWallet(api, params) {
1401
2420
  const dto = await api.send({
1402
- method: "GET",
1403
- url: "/v1/ondo/swap/quote",
1404
- queryParams: {
1405
- symbol: params.symbol,
1406
- side: params.side,
1407
- duration: params.duration,
1408
- ...sizeParam(params)
2421
+ method: "POST",
2422
+ url: `/v1/offers/${encodeURIComponent(params.offerId)}/allow-wallet`,
2423
+ body: {
2424
+ wallet_address: params.walletAddress,
2425
+ chain: params.chain,
2426
+ signature: params.signature
1409
2427
  },
1410
2428
  attributes: Attributes.protected()
1411
2429
  });
1412
- return OndoQuote.fromDto(dto);
2430
+ return AllowWalletResponse.fromDto(dto);
1413
2431
  }
1414
- async function buildOndoBuy(api, params) {
1415
- const dto = await api.send({
1416
- method: "POST",
1417
- url: "/v1/ondo/swap/buy",
1418
- body: swapBody(params),
1419
- attributes: Attributes.protected()
2432
+
2433
+ // src/universal/api/rpc/providers/superstate/swap.ts
2434
+ async function getSwapAuthorization(clients, params) {
2435
+ return clients(params.chain).readContract({
2436
+ address: params.contractAddress,
2437
+ abi: SUPERSTATE_SWAP_ABI,
2438
+ functionName: "authorized",
2439
+ args: [params.walletAddress]
1420
2440
  });
1421
- assertSpendScaleAgrees({
1422
- published: dto.spend_input_decimals,
1423
- sized: params.amount,
1424
- trade: "purchase"
2441
+ }
2442
+ async function getSwapPreview(clients, params) {
2443
+ const preview = await clients(params.chain).readContract({
2444
+ address: params.contractAddress,
2445
+ abi: SUPERSTATE_SWAP_ABI,
2446
+ functionName: "preview",
2447
+ args: [params.inputToken, params.amount]
1425
2448
  });
1426
- return OndoBuyTransaction.fromDto(dto);
2449
+ return SwapPreview.fromContract(preview);
1427
2450
  }
1428
- async function buildOndoSell(api, params) {
1429
- const dto = await api.send({
1430
- method: "POST",
1431
- url: "/v1/ondo/swap/sell",
1432
- body: swapBody(params),
1433
- attributes: Attributes.protected()
2451
+ async function getSwapStatus(clients, params) {
2452
+ const status = await clients(params.chain).readContract({
2453
+ address: params.contractAddress,
2454
+ abi: SUPERSTATE_SWAP_ABI,
2455
+ functionName: "status"
1434
2456
  });
1435
- assertSpendScaleAgrees({
1436
- published: dto.spend_input_decimals,
1437
- sized: params.amount,
1438
- trade: "sale",
1439
- // The two answers come from two chains, so on a testnet they can disagree
1440
- // for a reason that is neither the caller's nor a corrupt response. Say so,
1441
- // or a QA run reads as a puzzle rather than a diagnosis.
1442
- note: "the quote resolves the asset on Ethereum mainnet while the swap executes on the chain requested, so these disagree until frontline serves a chain-scoped quote"
2457
+ return SwapStatus.fromContract(status);
2458
+ }
2459
+ async function getSwapOutputToken(clients, params) {
2460
+ const client = clients(params.chain);
2461
+ const tokenAddress = await client.readContract({
2462
+ address: params.contractAddress,
2463
+ abi: SUPERSTATE_SWAP_ABI,
2464
+ functionName: "outputToken"
2465
+ });
2466
+ const token = { address: EvmContractAddress(tokenAddress), abi: ERC20_ABI };
2467
+ const [name, symbol, decimals] = await client.multicall({
2468
+ contracts: [
2469
+ { ...token, functionName: "name" },
2470
+ { ...token, functionName: "symbol" },
2471
+ { ...token, functionName: "decimals" }
2472
+ ],
2473
+ allowFailure: false
1443
2474
  });
1444
- return OndoSellTransaction.fromDto(dto);
1445
- }
1446
- function swapBody(params) {
1447
2475
  return {
1448
- symbol: params.symbol,
1449
- chain: params.chain,
1450
- wallet_address: params.walletAddress,
1451
- amount: params.amount.raw.toString()
2476
+ name,
2477
+ symbol: AssetSymbol(symbol),
2478
+ decimals: AssetDecimals(decimals)
1452
2479
  };
1453
2480
  }
1454
- function assertSpendScaleAgrees({
1455
- published,
1456
- sized,
1457
- trade,
1458
- note
1459
- }) {
1460
- if (published === sized.decimals) return;
1461
- const because = note === void 0 ? "" : ` - ${note}`;
1462
- throw new ValidationError(
1463
- `spend_input_decimals: the ${trade} was priced in ${published} decimals but the order was sized in ${sized.decimals}${because}`
1464
- );
1465
- }
1466
- function sizeParam(params) {
1467
- const tokenAmount = "tokenAmount" in params ? params.tokenAmount : void 0;
1468
- const notionalValue = "notionalValue" in params ? params.notionalValue : void 0;
1469
- if (tokenAmount !== void 0) {
1470
- if (notionalValue !== void 0) {
1471
- throw new ValidationError(
1472
- "An Ondo quote takes tokenAmount or notionalValue, not both"
1473
- );
1474
- }
1475
- return { token_amount: formatRawAmount(tokenAmount) };
1476
- }
1477
- if (notionalValue === void 0) {
1478
- throw new ValidationError(
1479
- "An Ondo quote must be sized by tokenAmount or notionalValue"
1480
- );
1481
- }
1482
- return { notional_value: notionalValue };
1483
- }
1484
-
1485
- // src/shared/core/checkout/ondo/ondo-namespace.ts
1486
- var OndoNamespaceImpl = class {
1487
- constructor(ctx) {
1488
- this.ctx = ctx;
1489
- this.log = internalLogger(ctx.logger, "ONDO");
1490
- }
1491
- async getTradingStatus(params) {
1492
- return this.log.wrap("getTradingStatus", params, async () => {
1493
- await this.ctx.ensureUserAuthenticated();
1494
- return getOndoTradingStatus(this.ctx.api, params);
1495
- });
1496
- }
1497
- async getQuote(params) {
1498
- return this.log.wrap("getQuote", params, async () => {
1499
- await this.ctx.ensureUserAuthenticated();
1500
- return getOndoQuote(this.ctx.api, params);
1501
- });
1502
- }
1503
- async buildBuyTransaction(params) {
1504
- return this.log.wrap("buildBuyTransaction", params, async () => {
1505
- await this.ctx.ensureUserAuthenticated();
1506
- return buildOndoBuy(this.ctx.api, params);
1507
- });
1508
- }
1509
- async buildSellTransaction(params) {
1510
- return this.log.wrap("buildSellTransaction", params, async () => {
1511
- await this.ctx.ensureUserAuthenticated();
1512
- return buildOndoSell(this.ctx.api, params);
1513
- });
1514
- }
1515
- };
1516
2481
 
1517
- // src/shared/core/checkout/superstate/swap-namespace.ts
2482
+ // src/universal/core/checkout/superstate/swap-namespace.ts
1518
2483
  var SuperstateSwapNamespaceImpl = class {
1519
2484
  constructor(ctx) {
1520
2485
  this.ctx = ctx;
1521
2486
  this.log = internalLogger(ctx.logger, "SUPERSTATE");
1522
2487
  }
1523
2488
  async getAuthorization(params) {
1524
- return this.log.wrap("getAuthorization", params, async () => {
1525
- await this.ctx.ensureUserAuthenticated();
1526
- return getSwapAuthorization(this.ctx.api, params);
1527
- });
2489
+ return this.log.wrap(
2490
+ "getAuthorization",
2491
+ params,
2492
+ async () => getSwapAuthorization(this.ctx.rpc, params)
2493
+ );
1528
2494
  }
1529
2495
  async getPreview(params) {
1530
- return this.log.wrap("getPreview", params, async () => {
1531
- await this.ctx.ensureUserAuthenticated();
1532
- return getSwapPreview(this.ctx.api, params);
1533
- });
2496
+ return this.log.wrap(
2497
+ "getPreview",
2498
+ params,
2499
+ async () => getSwapPreview(this.ctx.rpc, params)
2500
+ );
1534
2501
  }
1535
2502
  async getStatus(params) {
1536
- return this.log.wrap("getStatus", params, async () => {
1537
- await this.ctx.ensureUserAuthenticated();
1538
- return getSwapStatus(this.ctx.api, params);
1539
- });
2503
+ return this.log.wrap(
2504
+ "getStatus",
2505
+ params,
2506
+ async () => getSwapStatus(this.ctx.rpc, params)
2507
+ );
1540
2508
  }
1541
2509
  async getOutputToken(params) {
1542
- return this.log.wrap("getOutputToken", params, async () => {
1543
- await this.ctx.ensureUserAuthenticated();
1544
- return getSwapOutputToken(this.ctx.api, params);
1545
- });
2510
+ return this.log.wrap(
2511
+ "getOutputToken",
2512
+ params,
2513
+ async () => getSwapOutputToken(this.ctx.rpc, params)
2514
+ );
1546
2515
  }
1547
2516
  async allowWallet(params) {
1548
2517
  return this.log.wrap("allowWallet", params, async () => {
@@ -1552,7 +2521,7 @@ var SuperstateSwapNamespaceImpl = class {
1552
2521
  }
1553
2522
  };
1554
2523
 
1555
- // src/shared/types/document-submission.ts
2524
+ // src/universal/types/document-submission.ts
1556
2525
  var DocumentSubmission = {
1557
2526
  fromDto: (dto) => ({
1558
2527
  status: dto.status,
@@ -1560,14 +2529,14 @@ var DocumentSubmission = {
1560
2529
  })
1561
2530
  };
1562
2531
 
1563
- // src/shared/types/kyc.ts
2532
+ // src/universal/types/kyc.ts
1564
2533
  var KycToken = {
1565
2534
  fromDto: (dto) => ({
1566
2535
  token: dto.token
1567
2536
  })
1568
2537
  };
1569
2538
 
1570
- // src/shared/types/pii.ts
2539
+ // src/universal/types/pii.ts
1571
2540
  var Iso2CountryCode = (value) => value;
1572
2541
  var PiiJurisdiction = {
1573
2542
  fromDto: (dto) => ({
@@ -1595,7 +2564,7 @@ var Pii = {
1595
2564
  })
1596
2565
  };
1597
2566
 
1598
- // src/shared/types/requirement.ts
2567
+ // src/universal/types/requirement.ts
1599
2568
  var RequirementId = (value) => value;
1600
2569
  var Requirement = {
1601
2570
  fromDto: (dto) => ({
@@ -1616,7 +2585,7 @@ var RequirementStatusInfo = {
1616
2585
  )
1617
2586
  };
1618
2587
 
1619
- // src/shared/api/frontline/documents.ts
2588
+ // src/universal/api/frontline/documents.ts
1620
2589
  async function submitDocument(api, documentType, fields) {
1621
2590
  const dto = await api.send({
1622
2591
  method: "POST",
@@ -1627,7 +2596,7 @@ async function submitDocument(api, documentType, fields) {
1627
2596
  return DocumentSubmission.fromDto(dto);
1628
2597
  }
1629
2598
 
1630
- // src/shared/api/frontline/kyc.ts
2599
+ // src/universal/api/frontline/kyc.ts
1631
2600
  async function createKycToken(api, levelName, reset) {
1632
2601
  const dto = await api.send({
1633
2602
  method: "POST",
@@ -1641,7 +2610,7 @@ async function createKycToken(api, levelName, reset) {
1641
2610
  return KycToken.fromDto(dto);
1642
2611
  }
1643
2612
 
1644
- // src/shared/api/frontline/pii.ts
2613
+ // src/universal/api/frontline/pii.ts
1645
2614
  async function fetchPii(api) {
1646
2615
  const dto = await api.send({
1647
2616
  method: "GET",
@@ -1651,7 +2620,7 @@ async function fetchPii(api) {
1651
2620
  return Pii.fromDto(dto);
1652
2621
  }
1653
2622
 
1654
- // src/shared/api/frontline/requirements.ts
2623
+ // src/universal/api/frontline/requirements.ts
1655
2624
  async function fetchOfferRequirements(api, offerId, clientCreds) {
1656
2625
  const response = await api.send({
1657
2626
  method: "GET",
@@ -1677,7 +2646,7 @@ async function fetchRequirementStatuses(api, offerId) {
1677
2646
  return RequirementStatusInfo.fromStatusesDto(response);
1678
2647
  }
1679
2648
 
1680
- // src/shared/core/requirements/requirements-namespace.ts
2649
+ // src/universal/core/requirements/requirements-namespace.ts
1681
2650
  var RequirementsNamespaceImpl = class {
1682
2651
  constructor(ctx) {
1683
2652
  this.ctx = ctx;
@@ -1727,7 +2696,49 @@ var RequirementsNamespaceImpl = class {
1727
2696
  }
1728
2697
  };
1729
2698
 
1730
- // src/shared/types/token-metadata.ts
2699
+ // src/universal/api/rpc/erc20.ts
2700
+ async function getTokenAllowance(clients, params) {
2701
+ const allowance = await clients(params.chain).readContract({
2702
+ address: params.tokenAddress,
2703
+ abi: ERC20_ABI,
2704
+ functionName: "allowance",
2705
+ args: [params.owner, params.spender]
2706
+ });
2707
+ return parseUint256(allowance, "allowance");
2708
+ }
2709
+ async function getTokenBalance(clients, params) {
2710
+ const balance = await clients(params.chain).readContract({
2711
+ address: params.tokenAddress,
2712
+ abi: ERC20_ABI,
2713
+ functionName: "balanceOf",
2714
+ args: [params.owner]
2715
+ });
2716
+ return parseUint256(balance, "balanceOf");
2717
+ }
2718
+
2719
+ // src/universal/core/shared/blockchain/erc20/erc20-namespace.ts
2720
+ var Erc20NamespaceImpl = class {
2721
+ constructor(ctx) {
2722
+ this.ctx = ctx;
2723
+ this.log = internalLogger(ctx.logger, "ERC20");
2724
+ }
2725
+ async getAllowance(params) {
2726
+ return this.log.wrap(
2727
+ "getAllowance",
2728
+ params,
2729
+ async () => getTokenAllowance(this.ctx.rpc, params)
2730
+ );
2731
+ }
2732
+ async getBalance(params) {
2733
+ return this.log.wrap(
2734
+ "getBalance",
2735
+ params,
2736
+ async () => getTokenBalance(this.ctx.rpc, params)
2737
+ );
2738
+ }
2739
+ };
2740
+
2741
+ // src/universal/types/token-metadata.ts
1731
2742
  var TokenLogoUrl = (value) => value;
1732
2743
  var TokenLogo = {
1733
2744
  /** `baseUrl` is the registry origin; registry URLs are root-relative. */
@@ -1810,10 +2821,10 @@ var resolveLogoUrl = (url, baseUrl) => TokenLogoUrl(
1810
2821
  url.startsWith("http") ? url : `${baseUrl.replace(/\/$/, "")}${url}`
1811
2822
  );
1812
2823
 
1813
- // src/shared/api/nabu/tokens.ts
2824
+ // src/universal/api/nabu/tokens.ts
1814
2825
  import { getAddress } from "viem";
1815
2826
 
1816
- // src/shared/api/frontline/config.ts
2827
+ // src/universal/api/frontline/config.ts
1817
2828
  var PUBLIC_API_BASE_URL = "https://api.coinlist.co";
1818
2829
  var HEADER_API_VERSION = "X-API-Version";
1819
2830
  var HEADER_USER_AGENT = "User-Agent";
@@ -1826,7 +2837,7 @@ var VERIFY_IDENTITY_PATH = "/verify-identity";
1826
2837
  var VERIFY_IDENTITY_ACCREDITATION_PATH = "/verify-identity/accreditation_full";
1827
2838
  var WALLET_PATH = "/wallet";
1828
2839
 
1829
- // src/shared/api/http-client.ts
2840
+ // src/universal/api/http-client.ts
1830
2841
  var HttpClient = class {
1831
2842
  constructor(config, middleware = {}, logger = null, options = {}) {
1832
2843
  this.config = config;
@@ -1887,9 +2898,9 @@ var HttpClient = class {
1887
2898
  if (url.startsWith("http://") || url.startsWith("https://")) {
1888
2899
  return url;
1889
2900
  }
1890
- const base = this.config.baseUrl.replace(/\/$/, "");
2901
+ const base2 = this.config.baseUrl.replace(/\/$/, "");
1891
2902
  const path = url.startsWith("/") ? url : `/${url}`;
1892
- return base + path;
2903
+ return base2 + path;
1893
2904
  }
1894
2905
  async runBeforeRequestMiddleware(initialRequest) {
1895
2906
  let request = initialRequest;
@@ -1982,7 +2993,7 @@ function describeRequestUnredacted(request) {
1982
2993
  };
1983
2994
  }
1984
2995
 
1985
- // src/shared/api/nabu/tokens.ts
2996
+ // src/universal/api/nabu/tokens.ts
1986
2997
  function createNabuApiClient(baseUrl, logger = null) {
1987
2998
  return new HttpClient({ baseUrl }, {}, logger);
1988
2999
  }
@@ -2073,10 +3084,10 @@ function checksummed(address) {
2073
3084
  }
2074
3085
  }
2075
3086
 
2076
- // src/shared/core/tokens/tokens-namespace.ts
3087
+ // src/universal/core/tokens/tokens-namespace.ts
2077
3088
  var TokensNamespaceImpl = class {
2078
3089
  /**
2079
- * Takes the registry origin rather than a `SharedNamespaceContext`: the
3090
+ * Takes the registry origin rather than a `UniversalNamespaceContext`: the
2080
3091
  * registry is unauthenticated and on its own host, so the frontline sender
2081
3092
  * and the auth check would both be dead weight here.
2082
3093
  */
@@ -2100,7 +3111,7 @@ var TokensNamespaceImpl = class {
2100
3111
  }
2101
3112
  };
2102
3113
 
2103
- // src/shared/types/offer-option-address.ts
3114
+ // src/universal/types/offer-option-address.ts
2104
3115
  var OfferOptionAddressId = (value) => value;
2105
3116
  var OfferOptionAddress = {
2106
3117
  /** Maps the API DTO into the SDK offer-option-address domain model. */
@@ -2122,7 +3133,7 @@ var ConnectExternalWalletParams = {
2122
3133
  })
2123
3134
  };
2124
3135
 
2125
- // src/shared/types/wallet-ownership-challenge.ts
3136
+ // src/universal/types/wallet-ownership-challenge.ts
2126
3137
  var WalletOwnershipChallenge = {
2127
3138
  /** Maps the API DTO into the SDK wallet-ownership-challenge domain model. */
2128
3139
  fromDto: (dto) => ({
@@ -2161,7 +3172,7 @@ var CreateWalletOwnershipChallengeParams = {
2161
3172
  }
2162
3173
  };
2163
3174
 
2164
- // src/shared/api/frontline/wallet-connect.ts
3175
+ // src/universal/api/frontline/wallet-connect.ts
2165
3176
  async function createWalletOwnershipChallenge(api, params) {
2166
3177
  const dto = await api.send({
2167
3178
  method: "POST",
@@ -2198,7 +3209,7 @@ async function removeOptionAddress(api, offerId, addressId) {
2198
3209
  return OfferOptionAddress.fromDto(dto);
2199
3210
  }
2200
3211
 
2201
- // src/shared/core/wallets/wallets-namespace.ts
3212
+ // src/universal/core/wallets/wallets-namespace.ts
2202
3213
  var WalletsNamespaceImpl = class {
2203
3214
  constructor(ctx) {
2204
3215
  this.ctx = ctx;
@@ -2241,7 +3252,7 @@ var WalletsNamespaceImpl = class {
2241
3252
  }
2242
3253
  };
2243
3254
 
2244
- // src/shared/types/oauth-session.ts
3255
+ // src/universal/types/oauth-session.ts
2245
3256
  var ClientCredentialsOAuth = (value) => value;
2246
3257
  var OAuthRefreshToken = (value) => value;
2247
3258
  var OAuthSession = {
@@ -2257,7 +3268,7 @@ var OAuthSession = {
2257
3268
  }
2258
3269
  };
2259
3270
 
2260
- // src/shared/api/frontline/offers.ts
3271
+ // src/universal/api/frontline/offers.ts
2261
3272
  async function fetchOffers(api, clientCreds) {
2262
3273
  return fetchAllPages((params) => fetchOffersPage(api, params, clientCreds));
2263
3274
  }
@@ -2313,7 +3324,14 @@ export {
2313
3324
  describeErrorUnredacted,
2314
3325
  internalLogger,
2315
3326
  HttpClient,
3327
+ ERC20_ABI,
2316
3328
  fetchAllPages,
3329
+ Cursor,
3330
+ PaginatedResponse,
3331
+ PaginationParams,
3332
+ AssetId,
3333
+ AssetCode,
3334
+ Asset,
2317
3335
  ETHEREUM_CHAINS,
2318
3336
  EthereumChain,
2319
3337
  SOLANA_CHAINS,
@@ -2335,44 +3353,12 @@ export {
2335
3353
  StablecoinSymbol,
2336
3354
  KnownAssetSymbol,
2337
3355
  Bps,
2338
- FormattedAmountUi,
2339
- FormattedPercentUi,
2340
- TxExplorerUrl,
2341
- ShortenedWalletAddress,
2342
- FormattedAmountAssetUi,
2343
- AssetIconUrl,
2344
- getChainId,
2345
- chainFromId,
2346
- getNetworkName,
2347
- txExplorerUrl,
2348
- SwapAuthorization,
2349
- SwapPreview,
2350
- SwapStatus,
2351
- TokenAllowance,
2352
- TokenBalance,
2353
- AllowWalletResponse,
2354
- Erc20NamespaceImpl,
2355
- shortenAddress,
2356
- formatAmount,
2357
- formatRawAmount,
2358
- formatCompactAmount,
2359
- formatBpsAsPercent,
2360
- usdAmount,
2361
- assetAmount,
2362
- NA_AMOUNT_ASSET_UI,
2363
- formattedUsdPrice,
2364
- blockchainAmountFromRawOrThrow,
2365
- parseBlockchainAmount,
2366
- Cursor,
2367
- PaginatedResponse,
2368
- PaginationParams,
2369
- AssetId,
2370
- AssetCode,
2371
- Asset,
2372
3356
  OfferId,
2373
3357
  OfferSlug,
2374
3358
  Offer,
2375
3359
  OfferToken,
3360
+ Ticker,
3361
+ Isin,
2376
3362
  OfferOptionId,
2377
3363
  OfferOptionSlug,
2378
3364
  OfferSwapContract,
@@ -2389,12 +3375,38 @@ export {
2389
3375
  Participation,
2390
3376
  CreateParticipationParams,
2391
3377
  CoinListTokenSaleNamespaceImpl,
2392
- Ticker,
3378
+ FormattedAmountUi,
3379
+ FormattedPercentUi,
3380
+ TxExplorerUrl,
3381
+ ShortenedWalletAddress,
3382
+ FormattedAmountAssetUi,
3383
+ AssetIconUrl,
3384
+ shortenAddress,
3385
+ formatAmount,
3386
+ formatRawAmount,
3387
+ formatCompactAmount,
3388
+ formatBpsAsPercent,
3389
+ usdAmount,
3390
+ assetAmount,
3391
+ NA_AMOUNT_ASSET_UI,
3392
+ formattedUsdPrice,
3393
+ viemChain,
3394
+ getChainId,
3395
+ chainFromId,
3396
+ getNetworkName,
3397
+ txExplorerUrl,
3398
+ blockchainAmountFromRawOrThrow,
3399
+ parseBlockchainAmount,
2393
3400
  OndoTradingStatus,
2394
3401
  OndoQuote,
2395
3402
  OndoBuyTransaction,
2396
3403
  OndoSellTransaction,
2397
3404
  OndoNamespaceImpl,
3405
+ SUPERSTATE_SWAP_ABI,
3406
+ SwapPreview,
3407
+ PauseFlags,
3408
+ SwapStatus,
3409
+ AllowWalletResponse,
2398
3410
  SuperstateSwapNamespaceImpl,
2399
3411
  fetchOffers,
2400
3412
  fetchOffersPage,
@@ -2410,6 +3422,7 @@ export {
2410
3422
  RequirementStatusInfo,
2411
3423
  fetchOfferRequirements,
2412
3424
  RequirementsNamespaceImpl,
3425
+ Erc20NamespaceImpl,
2413
3426
  TokenLogoUrl,
2414
3427
  TokenLogo,
2415
3428
  TokenMetadata,
@@ -2424,4 +3437,4 @@ export {
2424
3437
  OAuthRefreshToken,
2425
3438
  OAuthSession
2426
3439
  };
2427
- //# sourceMappingURL=chunk-GFLU5OMP.js.map
3440
+ //# sourceMappingURL=chunk-2YEJXE2V.js.map