@coinlist-co/react 0.11.1-rc.e102bdb → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/{chunk-7CTH4KPU.js → chunk-6CQHDASY.js} +648 -620
  2. package/dist/chunk-6CQHDASY.js.map +1 -0
  3. package/dist/{chunk-UZUQALFY.js → chunk-F6WGUKZC.js} +9 -9
  4. package/dist/chunk-F6WGUKZC.js.map +1 -0
  5. package/dist/{chunk-LSPZETDH.js → chunk-ZFBEI3BW.js} +131 -134
  6. package/dist/chunk-ZFBEI3BW.js.map +1 -0
  7. package/dist/client/index.cjs +1489 -1346
  8. package/dist/client/index.cjs.map +1 -1
  9. package/dist/client/index.d.cts +395 -254
  10. package/dist/client/index.d.ts +395 -254
  11. package/dist/client/index.js +852 -739
  12. package/dist/client/index.js.map +1 -1
  13. package/dist/{collections-BBI_XydI.d.cts → collections-DOm9VKVm.d.cts} +1 -1
  14. package/dist/{collections-BrX9rRWc.d.ts → collections-aCv-Wr2a.d.ts} +1 -1
  15. package/dist/{config-CMl1bR3F.d.cts → config-DIaFzrMW.d.cts} +56 -13
  16. package/dist/{config-CMl1bR3F.d.ts → config-DIaFzrMW.d.ts} +56 -13
  17. package/dist/server/index.cjs +262 -236
  18. package/dist/server/index.cjs.map +1 -1
  19. package/dist/server/index.d.cts +4 -4
  20. package/dist/server/index.d.ts +4 -4
  21. package/dist/server/index.js +3 -3
  22. package/dist/server/index.js.map +1 -1
  23. package/dist/{shared → universal}/index.cjs +948 -919
  24. package/dist/universal/index.cjs.map +1 -0
  25. package/dist/{shared → universal}/index.d.cts +566 -536
  26. package/dist/{shared → universal}/index.d.ts +566 -536
  27. package/dist/{shared → universal}/index.js +9 -5
  28. package/package.json +23 -17
  29. package/dist/chunk-7CTH4KPU.js.map +0 -1
  30. package/dist/chunk-LSPZETDH.js.map +0 -1
  31. package/dist/chunk-UZUQALFY.js.map +0 -1
  32. package/dist/shared/index.cjs.map +0 -1
  33. /package/dist/{shared → universal}/index.js.map +0 -0
@@ -17,9 +17,9 @@ var __copyProps = (to, from, except, desc) => {
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
 
20
- // src/shared/index.ts
21
- var shared_exports = {};
22
- __export(shared_exports, {
20
+ // src/universal/index.ts
21
+ var universal_exports = {};
22
+ __export(universal_exports, {
23
23
  AllowWalletResponse: () => AllowWalletResponse,
24
24
  Asset: () => Asset,
25
25
  AssetCode: () => AssetCode,
@@ -88,6 +88,7 @@ __export(shared_exports, {
88
88
  OfferOptionId: () => OfferOptionId,
89
89
  OfferOptionSlug: () => OfferOptionSlug,
90
90
  OfferSlug: () => OfferSlug,
91
+ OfferSwapContract: () => OfferSwapContract,
91
92
  OfferToken: () => OfferToken,
92
93
  OffersNamespaceImpl: () => OffersNamespaceImpl,
93
94
  OndoBuyTransaction: () => OndoBuyTransaction,
@@ -168,18 +169,19 @@ __export(shared_exports, {
168
169
  generatePKCEParams: () => generatePKCEParams,
169
170
  getChainId: () => getChainId,
170
171
  getNetworkName: () => getNetworkName,
172
+ isChain: () => isChain,
171
173
  isStopped: () => isStopped,
172
- ondoSwapContractAddress: () => ondoSwapContractAddress,
173
174
  parseBlockchainAmount: () => parseBlockchainAmount,
174
175
  parseUint256: () => parseUint256,
175
176
  shortenAddress: () => shortenAddress,
176
177
  superstateSwapContractAddress: () => superstateSwapContractAddress,
178
+ swapSpender: () => swapSpender,
177
179
  txExplorerUrl: () => txExplorerUrl,
178
180
  usdAmount: () => usdAmount
179
181
  });
180
- module.exports = __toCommonJS(shared_exports);
182
+ module.exports = __toCommonJS(universal_exports);
181
183
 
182
- // src/shared/api/http-attributes.ts
184
+ // src/universal/api/http-attributes.ts
183
185
  var empty = {};
184
186
  var concat = (left, right) => ({
185
187
  ...left,
@@ -234,7 +236,7 @@ var Attributes = {
234
236
  getRequestId
235
237
  };
236
238
 
237
- // src/shared/api/http.ts
239
+ // src/universal/api/http.ts
238
240
  var HttpError = class extends Error {
239
241
  constructor(response) {
240
242
  super(`Request failed with ${response.status} status`);
@@ -344,7 +346,7 @@ function headersToRecord(headers) {
344
346
  return record;
345
347
  }
346
348
 
347
- // src/shared/api/pagination.ts
349
+ // src/universal/api/pagination.ts
348
350
  async function fetchAllPages(fetchPage, baseParams) {
349
351
  const items = [];
350
352
  let cursor = null;
@@ -360,7 +362,7 @@ async function fetchAllPages(fetchPage, baseParams) {
360
362
  return items;
361
363
  }
362
364
 
363
- // src/shared/core/utils/crypto.ts
365
+ // src/universal/core/shared/utils/crypto.ts
364
366
  async function sha256(data) {
365
367
  const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
366
368
  const buffer = bytes.buffer.slice(
@@ -396,7 +398,7 @@ function notBlankStringOrNull(value) {
396
398
  }
397
399
  }
398
400
 
399
- // src/shared/types/oauth.ts
401
+ // src/universal/types/oauth.ts
400
402
  var AuthorizationCode = (value) => value;
401
403
  var CodeVerifier = (value) => value;
402
404
  var CodeChallenge = (value) => value;
@@ -405,7 +407,7 @@ var RedirectUri = (value) => value;
405
407
  var ClientId = (value) => value;
406
408
  var ClientSecret = (value) => value;
407
409
 
408
- // src/shared/core/auth/pkce.ts
410
+ // src/universal/core/auth/pkce.ts
409
411
  async function generatePKCEParams(config) {
410
412
  const state = generateSecureRandomBase64Url(32);
411
413
  const codeVerifier = generateSecureRandomBase64Url(32);
@@ -422,7 +424,44 @@ async function generatePKCEParams(config) {
422
424
  };
423
425
  }
424
426
 
425
- // src/shared/types/errors.ts
427
+ // src/universal/types/pagination.ts
428
+ var Cursor = (value) => value;
429
+ var PaginatedResponse = {
430
+ fromDto: (dto, itemMapper) => ({
431
+ data: dto.data.map(itemMapper),
432
+ startingAfter: dto.starting_after ? Cursor(dto.starting_after) : null,
433
+ startingBefore: dto.starting_before ? Cursor(dto.starting_before) : null
434
+ })
435
+ };
436
+ var PaginationParams = {
437
+ toQueryParams: (params) => {
438
+ const queryParams = {};
439
+ if (params.after) {
440
+ queryParams.starting_after = params.after;
441
+ }
442
+ if (params.before) {
443
+ queryParams.starting_before = params.before;
444
+ }
445
+ if (params.limit) {
446
+ queryParams.limit = params.limit;
447
+ }
448
+ return queryParams;
449
+ }
450
+ };
451
+
452
+ // src/universal/types/asset.ts
453
+ var AssetId = (value) => value;
454
+ var AssetCode = (value) => value;
455
+ var Asset = {
456
+ fromDto: (dto) => ({
457
+ id: AssetId(dto.id),
458
+ code: AssetCode(dto.code),
459
+ name: dto.name,
460
+ fractionalDigits: dto.fractional_digits
461
+ })
462
+ };
463
+
464
+ // src/universal/types/errors.ts
426
465
  var NotImplementedError = class extends Error {
427
466
  constructor(message = "Not implemented yet") {
428
467
  super(message);
@@ -454,7 +493,7 @@ var MathError = class extends Error {
454
493
  }
455
494
  };
456
495
 
457
- // src/shared/types/blockchain/core.ts
496
+ // src/universal/types/blockchain/core.ts
458
497
  var ETHEREUM_CHAINS = {
459
498
  ethereum_mainnet: true,
460
499
  ethereum_sepolia: true,
@@ -477,8 +516,9 @@ var SolanaChain = (value) => {
477
516
  }
478
517
  return value;
479
518
  };
519
+ var isChain = (value) => Object.keys(ETHEREUM_CHAINS).includes(value) || Object.keys(SOLANA_CHAINS).includes(value);
480
520
  var Chain = (value) => {
481
- if (!Object.keys(ETHEREUM_CHAINS).includes(value) && !Object.keys(SOLANA_CHAINS).includes(value)) {
521
+ if (!isChain(value)) {
482
522
  throw new ValidationError(`Unsupported chain: "${value}"`);
483
523
  }
484
524
  return value;
@@ -550,785 +590,58 @@ var StablecoinSymbol = (value) => value;
550
590
  var KnownAssetSymbol = StablecoinSymbol;
551
591
  var Bps = (value) => value;
552
592
 
553
- // src/shared/core/blockchain/bps.ts
554
- var BPS_DENOM = Bps(10000n);
555
- function applyBps(amount, bps) {
556
- return assertUint256(amount * bps / BPS_DENOM);
557
- }
558
-
559
- // src/shared/types/blockchain/ui.ts
560
- var FormattedAmountUi = (value) => value;
561
- var FormattedPercentUi = (value) => value;
562
- var TxExplorerUrl = (value) => value;
563
- var ShortenedWalletAddress = (value) => value;
564
- var FormattedAmountAssetUi = (value) => value;
565
- var AssetIconUrl = (value) => value;
566
-
567
- // src/shared/core/blockchain/chain.ts
568
- var CHAIN_IDS = {
569
- ethereum_mainnet: 1,
570
- ethereum_sepolia: 11155111,
571
- base_mainnet: 8453,
572
- base_sepolia: 84532
573
- };
574
- function getChainId(chain) {
575
- return CHAIN_IDS[chain];
576
- }
577
- function chainFromId(chainId) {
578
- const chains = Object.keys(CHAIN_IDS);
579
- const chain = chains.find((c) => String(CHAIN_IDS[c]) === chainId);
580
- if (!chain) {
581
- throw new ValidationError(`Unsupported EIP-155 chain id: "${chainId}"`);
582
- }
583
- return chain;
584
- }
585
- function getNetworkName(chain) {
586
- switch (chain) {
587
- case "ethereum_mainnet":
588
- return "Ethereum";
589
- case "ethereum_sepolia":
590
- return "Ethereum Sepolia";
591
- case "base_mainnet":
592
- return "Base";
593
- case "base_sepolia":
594
- return "Base Sepolia";
595
- default: {
596
- const _exhaustive = chain;
597
- return _exhaustive;
598
- }
599
- }
600
- }
601
- function txExplorerUrl(chain, txHash) {
602
- return TxExplorerUrl(`${explorerBaseUrl(chain)}/tx/${txHash}`);
603
- }
604
- function explorerBaseUrl(chain) {
605
- switch (chain) {
606
- case "ethereum_mainnet":
607
- return "https://etherscan.io";
608
- case "ethereum_sepolia":
609
- return "https://sepolia.etherscan.io";
610
- case "base_mainnet":
611
- return "https://basescan.org";
612
- case "base_sepolia":
613
- return "https://sepolia-explorer.base.org";
614
- default: {
615
- const _exhaustive = chain;
616
- return _exhaustive;
593
+ // src/universal/types/offer.ts
594
+ var OfferId = (value) => value;
595
+ var OfferSlug = (value) => value;
596
+ var Offer = {
597
+ fromDto: (dto) => {
598
+ if (!Array.isArray(dto.tokens)) {
599
+ throw new ValidationError(
600
+ `Offer.tokens: expected an array, got ${typeof dto.tokens}`
601
+ );
617
602
  }
603
+ return {
604
+ id: OfferId(dto.id),
605
+ slug: OfferSlug(dto.slug),
606
+ type: dto.type,
607
+ tagline: dto.tagline,
608
+ bannerUrl: dto.banner_url,
609
+ logoUrl: dto.logo_url,
610
+ startsAt: new Date(dto.starts_at),
611
+ endsAt: dto.ends_at ? new Date(dto.ends_at) : null,
612
+ tokens: OfferToken.listFromDto(dto.tokens)
613
+ };
618
614
  }
619
- }
620
-
621
- // src/shared/core/blockchain/erc20/abi.ts
622
- var ERC20_ABI = [
623
- {
624
- type: "function",
625
- name: "allowance",
626
- inputs: [
627
- { name: "owner", type: "address" },
628
- { name: "spender", type: "address" }
629
- ],
630
- outputs: [{ name: "", type: "uint256" }],
631
- stateMutability: "view"
632
- },
633
- {
634
- type: "function",
635
- name: "approve",
636
- inputs: [
637
- { name: "spender", type: "address" },
638
- { name: "amount", type: "uint256" }
639
- ],
640
- outputs: [{ name: "", type: "bool" }],
641
- stateMutability: "nonpayable"
642
- },
643
- {
644
- type: "function",
645
- name: "balanceOf",
646
- inputs: [{ name: "account", type: "address" }],
647
- outputs: [{ name: "", type: "uint256" }],
648
- stateMutability: "view"
649
- },
650
- {
651
- type: "function",
652
- name: "decimals",
653
- inputs: [],
654
- outputs: [{ name: "", type: "uint8" }],
655
- stateMutability: "view"
656
- },
657
- {
658
- type: "function",
659
- name: "name",
660
- inputs: [],
661
- outputs: [{ name: "", type: "string" }],
662
- stateMutability: "view"
663
- },
664
- {
665
- type: "function",
666
- name: "symbol",
667
- inputs: [],
668
- outputs: [{ name: "", type: "string" }],
669
- stateMutability: "view"
670
- },
671
- {
672
- type: "function",
673
- name: "totalSupply",
674
- inputs: [],
675
- outputs: [{ name: "", type: "uint256" }],
676
- stateMutability: "view"
677
- },
678
- {
679
- type: "function",
680
- name: "transfer",
681
- inputs: [
682
- { name: "recipient", type: "address" },
683
- { name: "amount", type: "uint256" }
684
- ],
685
- outputs: [{ name: "", type: "bool" }],
686
- stateMutability: "nonpayable"
687
- },
688
- {
689
- type: "function",
690
- name: "transferFrom",
691
- inputs: [
692
- { name: "sender", type: "address" },
693
- { name: "recipient", type: "address" },
694
- { name: "amount", type: "uint256" }
695
- ],
696
- outputs: [{ name: "", type: "bool" }],
697
- stateMutability: "nonpayable"
698
- },
699
- {
700
- type: "event",
701
- name: "Approval",
702
- inputs: [
703
- { name: "owner", type: "address", indexed: true },
704
- { name: "spender", type: "address", indexed: true },
705
- { name: "value", type: "uint256", indexed: false }
706
- ],
707
- anonymous: false
708
- },
709
- {
710
- type: "event",
711
- name: "Transfer",
712
- inputs: [
713
- { name: "from", type: "address", indexed: true },
714
- { name: "to", type: "address", indexed: true },
715
- { name: "value", type: "uint256", indexed: false }
716
- ],
717
- anonymous: false
718
- }
719
- ];
720
-
721
- // src/shared/types/providers/superstate/swap.ts
722
- var SwapAuthorization = {
723
- fromDto: (dto) => ({
724
- authorized: dto.authorized
725
- })
726
- };
727
- var SwapPreview = {
728
- fromDto: (dto) => ({
729
- inputAmount: parseUint256(
730
- BigInt(dto.pay_input_amount),
731
- "SwapPreview.pay_input_amount"
732
- ),
733
- fee: parseUint256(BigInt(dto.fee), "SwapPreview.fee"),
734
- outputAmount: parseUint256(
735
- BigInt(dto.receive_output_amount),
736
- "SwapPreview.receive_output_amount"
737
- )
738
- })
739
615
  };
740
- var SwapStatus = {
741
- fromDto: (dto) => ({
742
- stopped: parseUint256(BigInt(dto.stopped), "SwapStatus.stopped"),
743
- swapLevel: parseUint256(BigInt(dto.swap_level), "SwapStatus.swap_level")
744
- })
745
- };
746
- var TokenAllowance = {
616
+ var OfferToken = {
747
617
  fromDto: (dto) => ({
748
- allowance: parseUint256(BigInt(dto.allowance), "TokenAllowance.allowance")
749
- })
618
+ role: dto.role,
619
+ chain: Chain(dto.chain),
620
+ address: EvmContractAddress(dto.address)
621
+ }),
622
+ /**
623
+ * Maps an offer's token list, dropping every token on a chain this SDK does
624
+ * not name. Frontline's chain registry runs ahead of {@link Chain}, and a
625
+ * plain `.map` would throw out of `Offer.fromDto` and, through
626
+ * `PaginatedResponse.fromDto`, reject the whole offers page - which is how
627
+ * one Base token blanked production's offers list. Dropping costs that
628
+ * token's metadata alone: `coinlist.tokens.get` takes an `EthereumChain`,
629
+ * so nobody could have looked it up anyway.
630
+ *
631
+ * Same shape as `TokenMetadata.fromRegistryDto`.
632
+ */
633
+ listFromDto: (dtos) => dtos.filter((dto) => isChain(dto.chain)).map(OfferToken.fromDto)
750
634
  };
751
- var TokenBalance = {
635
+
636
+ // src/universal/types/offer-detail.ts
637
+ var OfferOptionId = (value) => value;
638
+ var OfferOptionSlug = (value) => value;
639
+ var OfferSwapContract = {
752
640
  fromDto: (dto) => ({
753
- balance: parseUint256(BigInt(dto.balance), "TokenBalance.balance")
641
+ chain: Chain(dto.chain),
642
+ address: EvmContractAddress(dto.address)
754
643
  })
755
644
  };
756
- var AllowWalletResponse = {
757
- fromDto: (dto) => {
758
- switch (dto.action) {
759
- case "broadcast_transaction":
760
- return {
761
- action: "broadcast_transaction",
762
- to: EvmContractAddress(dto.to),
763
- data: HexEncodedTransactionData(dto.data)
764
- };
765
- case "none":
766
- return {
767
- action: "none",
768
- alreadyAllowed: dto.already_allowed
769
- };
770
- default: {
771
- const _exhaustive = dto;
772
- return _exhaustive;
773
- }
774
- }
775
- }
776
- };
777
-
778
- // src/shared/api/frontline/providers/superstate/swap.ts
779
- async function getSwapAuthorization(api, params) {
780
- const dto = await api.send({
781
- method: "GET",
782
- url: "/v1/wallet/authorized",
783
- queryParams: {
784
- chain: params.chain,
785
- contract_address: params.contractAddress,
786
- wallet_address: params.walletAddress
787
- },
788
- attributes: Attributes.protected()
789
- });
790
- return SwapAuthorization.fromDto(dto);
791
- }
792
- async function getSwapOutputToken(api, params) {
793
- const dto = await api.send({
794
- method: "GET",
795
- url: "/v1/swap/output-token",
796
- queryParams: {
797
- chain: params.chain,
798
- contract_address: params.contractAddress
799
- },
800
- attributes: Attributes.protected()
801
- });
802
- return toErc20Asset(dto);
803
- }
804
- async function getSwapPreview(api, params) {
805
- const dto = await api.send({
806
- method: "GET",
807
- url: "/v1/swap/preview",
808
- queryParams: {
809
- chain: params.chain,
810
- contract_address: params.contractAddress,
811
- input_token: params.inputToken,
812
- amount: params.amount.toString()
813
- },
814
- attributes: Attributes.protected()
815
- });
816
- return SwapPreview.fromDto(dto);
817
- }
818
- async function getSwapStatus(api, params) {
819
- const dto = await api.send({
820
- method: "GET",
821
- url: "/v1/swap/status",
822
- queryParams: {
823
- chain: params.chain,
824
- contract_address: params.contractAddress
825
- },
826
- attributes: Attributes.protected()
827
- });
828
- return SwapStatus.fromDto(dto);
829
- }
830
- async function getTokenAllowance(api, params) {
831
- const dto = await api.send({
832
- method: "GET",
833
- url: "/v1/token/allowance",
834
- queryParams: {
835
- chain: params.chain,
836
- token_address: params.tokenAddress,
837
- owner: params.owner,
838
- spender: params.spender
839
- },
840
- attributes: Attributes.protected()
841
- });
842
- return TokenAllowance.fromDto(dto);
843
- }
844
- async function getTokenBalance(api, params) {
845
- const dto = await api.send({
846
- method: "GET",
847
- url: "/v1/token/balance",
848
- queryParams: {
849
- chain: params.chain,
850
- token_address: params.tokenAddress,
851
- owner: params.owner
852
- },
853
- attributes: Attributes.protected()
854
- });
855
- return TokenBalance.fromDto(dto);
856
- }
857
- async function allowWallet(api, params) {
858
- const dto = await api.send({
859
- method: "POST",
860
- url: `/v1/offers/${encodeURIComponent(params.offerId)}/allow-wallet`,
861
- body: {
862
- wallet_address: params.walletAddress,
863
- chain: params.chain,
864
- signature: params.signature
865
- },
866
- attributes: Attributes.protected()
867
- });
868
- return AllowWalletResponse.fromDto(dto);
869
- }
870
- function toErc20Asset(dto) {
871
- return {
872
- name: dto.name,
873
- symbol: AssetSymbol(dto.symbol),
874
- decimals: AssetDecimals(dto.decimals)
875
- };
876
- }
877
-
878
- // src/shared/core/observability/log-cause.ts
879
- function classifyLogCause(error) {
880
- if (error instanceof HttpError) {
881
- return httpCause(error);
882
- }
883
- if (error instanceof ValidationError) {
884
- return { type: "validation", message: error.message };
885
- }
886
- if (error instanceof InvariantError) {
887
- return { type: "invariant", message: error.message };
888
- }
889
- if (error instanceof MathError) {
890
- return { type: "math", message: error.message };
891
- }
892
- if (error instanceof NotAuthenticatedError) {
893
- return { type: "not-authenticated" };
894
- }
895
- if (error instanceof NotImplementedError) {
896
- return { type: "not-implemented" };
897
- }
898
- return { type: "generic-error", name: errorName(error) };
899
- }
900
- function describeErrorUnredacted(error) {
901
- if (error instanceof HttpError) {
902
- return describeHttpErrorRedacted(error);
903
- }
904
- if (error instanceof Error) {
905
- return `${error.name}: ${error.message}`;
906
- }
907
- return `thrown non-error: ${stringifyUnredacted(error)}`;
908
- }
909
- function stringifyUnredacted(value) {
910
- if (value === void 0) return "";
911
- try {
912
- return JSON.stringify(
913
- value,
914
- (_key, item) => typeof item === "bigint" ? `${item}` : item
915
- ) ?? String(value);
916
- } catch (_) {
917
- return "<unserializable>";
918
- }
919
- }
920
- function describeHttpErrorRedacted(error) {
921
- const code = apiErrorCode(error);
922
- const status = error.response.status;
923
- return code === null ? `HttpError ${status}` : `HttpError ${status} (${code})`;
924
- }
925
- function errorName(error) {
926
- return error instanceof Error ? error.name : `non-error ${typeof error}`;
927
- }
928
- function httpCause(error) {
929
- return {
930
- type: "http",
931
- requestId: error.requestId,
932
- status: error.response.status,
933
- code: apiErrorCode(error),
934
- eventId: apiErrorEventId(error)
935
- };
936
- }
937
- function apiErrorEventId(error) {
938
- const body = error.response.body;
939
- if (typeof body !== "object" || body === null) return null;
940
- const eventId = body.event_id;
941
- return typeof eventId === "string" ? eventId : null;
942
- }
943
-
944
- // src/shared/core/observability/internal-logger.ts
945
- function internalLogger(logger, scope) {
946
- return logger ? scopedLogger(logger, scope, {}) : noopInternalLogger;
947
- }
948
- var LEVEL_RANK = {
949
- none: 0,
950
- error: 1,
951
- warn: 2,
952
- info: 3,
953
- debug: 4
954
- };
955
- function scopedLogger(logger, scope, bindings) {
956
- const admits = (level) => LEVEL_RANK[logger.level()] >= LEVEL_RANK[level];
957
- const safe = (event) => ({
958
- msg: event.msg,
959
- scope,
960
- bindings,
961
- fields: event.fields ?? {},
962
- ...event.cause === void 0 ? {} : { cause: event.cause }
963
- });
964
- const unredacted = (event) => ({
965
- msg: event.msg,
966
- scope,
967
- bindings,
968
- fields: event.fields ?? {}
969
- });
970
- const self = {
971
- child: (binding) => scopedLogger(logger, scope, { ...bindings, ...binding }),
972
- debug: (event) => {
973
- if (admits("debug")) logger.debug(() => unredacted(event()));
974
- },
975
- info: (event) => {
976
- if (admits("info")) logger.info(() => safe(event()));
977
- },
978
- warn: (event) => {
979
- if (admits("warn")) logger.warn(() => safe(event()));
980
- },
981
- error: (event) => {
982
- if (admits("error")) logger.error(() => safe(event()));
983
- },
984
- failure: (event, error) => {
985
- if (admits("debug"))
986
- logger.debug(() => unredacted(verbatim(event(), error)));
987
- if (admits("error")) logger.error(() => safe(classified(event(), error)));
988
- },
989
- warning: (event, error) => {
990
- if (admits("debug"))
991
- logger.debug(() => unredacted(verbatim(event(), error)));
992
- if (admits("warn")) logger.warn(() => safe(classified(event(), error)));
993
- },
994
- wrap: async (op, params, run) => {
995
- const opLog = self.child({ op });
996
- opLog.debug(() => ({ msg: "call", fields: { params } }));
997
- try {
998
- return await run();
999
- } catch (error) {
1000
- opLog.failure(() => ({ msg: "call failed" }), error);
1001
- throw error;
1002
- }
1003
- }
1004
- };
1005
- return self;
1006
- }
1007
- function verbatim(event, error) {
1008
- return {
1009
- msg: event.msg,
1010
- fields: { ...event.fields, error: describeErrorUnredacted(error) }
1011
- };
1012
- }
1013
- function classified(event, error) {
1014
- return { ...event, cause: event.cause ?? classifyLogCause(error) };
1015
- }
1016
- var noopInternalLogger = {
1017
- child: () => noopInternalLogger,
1018
- debug: () => void 0,
1019
- info: () => void 0,
1020
- warn: () => void 0,
1021
- error: () => void 0,
1022
- failure: () => void 0,
1023
- warning: () => void 0,
1024
- wrap: (_op, _params, run) => run()
1025
- };
1026
-
1027
- // src/shared/core/blockchain/erc20/erc20-namespace.ts
1028
- var Erc20NamespaceImpl = class {
1029
- constructor(ctx) {
1030
- this.ctx = ctx;
1031
- this.log = internalLogger(ctx.logger, "ERC20");
1032
- }
1033
- async getAllowance(params) {
1034
- return this.log.wrap("getAllowance", params, async () => {
1035
- await this.ctx.ensureUserAuthenticated();
1036
- return getTokenAllowance(this.ctx.api, params);
1037
- });
1038
- }
1039
- async getBalance(params) {
1040
- return this.log.wrap("getBalance", params, async () => {
1041
- await this.ctx.ensureUserAuthenticated();
1042
- return getTokenBalance(this.ctx.api, params);
1043
- });
1044
- }
1045
- };
1046
-
1047
- // src/shared/core/blockchain/formatters.ts
1048
- var import_viem = require("viem");
1049
- function shortenAddress(address) {
1050
- const short = address.length > 10 ? `${address.slice(0, 6)}\u2026${address.slice(-4)}` : address;
1051
- return ShortenedWalletAddress(short);
1052
- }
1053
- function formatAmount(amount, locale, options) {
1054
- const decimal = formatRawAmount(amount);
1055
- let [integerPart, fractionPart = ""] = decimal.split(".");
1056
- const maxFractionDigits = options?.maxFractionDigits;
1057
- const minFractionDigits = maxFractionDigits !== void 0 ? Math.min(maxFractionDigits, amount.decimals) : Math.min(2, amount.decimals);
1058
- if (maxFractionDigits !== void 0 && fractionPart.length > maxFractionDigits) {
1059
- ({ integerPart, fractionPart } = roundFractionHalfUp(
1060
- integerPart,
1061
- fractionPart,
1062
- maxFractionDigits
1063
- ));
1064
- }
1065
- const fraction = minFractionDigits === 0 ? "" : fractionPart.padEnd(minFractionDigits, "0");
1066
- const integerFormatted = BigInt(integerPart).toLocaleString(locale);
1067
- if (minFractionDigits === 0 && fraction === "") {
1068
- return FormattedAmountUi(integerFormatted);
1069
- }
1070
- const decimalSeparator = new Intl.NumberFormat(locale).formatToParts(1.1).find((p) => p.type === "decimal")?.value ?? ".";
1071
- return FormattedAmountUi(`${integerFormatted}${decimalSeparator}${fraction}`);
1072
- }
1073
- function roundFractionHalfUp(integerPart, fractionPart, maxFractionDigits) {
1074
- if (fractionPart.length <= maxFractionDigits) {
1075
- return { integerPart, fractionPart };
1076
- }
1077
- if (maxFractionDigits === 0) {
1078
- const roundUp = fractionPart[0] >= "5";
1079
- const integer = BigInt(integerPart) + (roundUp ? 1n : 0n);
1080
- return { integerPart: integer.toString(), fractionPart: "" };
1081
- }
1082
- const trimmed = fractionPart.slice(0, maxFractionDigits);
1083
- if (fractionPart[maxFractionDigits] < "5") {
1084
- return { integerPart, fractionPart: trimmed };
1085
- }
1086
- const digits = trimmed.split("").map((digit) => Number.parseInt(digit, 10));
1087
- let carry = 1;
1088
- for (let i = digits.length - 1; i >= 0 && carry > 0; i -= 1) {
1089
- const sum = digits[i] + carry;
1090
- if (sum === 10) {
1091
- digits[i] = 0;
1092
- carry = 1;
1093
- } else {
1094
- digits[i] = sum;
1095
- carry = 0;
1096
- }
1097
- }
1098
- return {
1099
- integerPart: carry > 0 ? (BigInt(integerPart) + 1n).toString() : integerPart,
1100
- fractionPart: digits.join("")
1101
- };
1102
- }
1103
- function formatRawAmount(amount) {
1104
- return (0, import_viem.formatUnits)(amount.raw, amount.decimals);
1105
- }
1106
- function formatCompactAmount(amount, locale) {
1107
- const value = Number(formatRawAmount(amount));
1108
- const formatted = new Intl.NumberFormat(locale, {
1109
- notation: "compact",
1110
- maximumFractionDigits: 2
1111
- }).format(value);
1112
- return FormattedAmountUi(formatted);
1113
- }
1114
- function formatBpsAsPercent(bps, locale) {
1115
- const whole = bps / 100n;
1116
- const fraction = bps % 100n;
1117
- const wholeFormatted = whole.toLocaleString(locale);
1118
- const decimalSeparator = new Intl.NumberFormat(locale).formatToParts(1.1).find((p) => p.type === "decimal")?.value ?? ".";
1119
- if (fraction === 0n) {
1120
- return FormattedPercentUi(`${wholeFormatted}%`);
1121
- }
1122
- const fractionFormatted = fraction.toString().padStart(2, "0").replace(/0+$/, "");
1123
- return FormattedPercentUi(
1124
- `${wholeFormatted}${decimalSeparator}${fractionFormatted}%`
1125
- );
1126
- }
1127
- function usdAmount(amount) {
1128
- return FormattedAmountAssetUi(`$${amount}`);
1129
- }
1130
- function assetAmount(amount, symbol) {
1131
- return FormattedAmountAssetUi(`${amount} ${symbol}`);
1132
- }
1133
- var NA_AMOUNT_ASSET_UI = FormattedAmountAssetUi("-");
1134
- var USD_FRACTION_DIGITS = AssetDecimals(2);
1135
- function formattedUsdPrice(amount, locale) {
1136
- if (!amount) return NA_AMOUNT_ASSET_UI;
1137
- return usdAmount(
1138
- formatAmount(amount, locale, { maxFractionDigits: USD_FRACTION_DIGITS })
1139
- );
1140
- }
1141
-
1142
- // src/shared/core/blockchain/math.ts
1143
- var import_viem2 = require("viem");
1144
- function blockchainAmountFromRawOrThrow({
1145
- label,
1146
- raw,
1147
- decimals
1148
- }) {
1149
- const trimmed = raw.trim();
1150
- if (trimmed === "") {
1151
- throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
1152
- }
1153
- let value;
1154
- try {
1155
- value = BigInt(trimmed);
1156
- } catch {
1157
- throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
1158
- }
1159
- try {
1160
- return BlockchainAmount({ raw: assertUint256(value), decimals });
1161
- } catch {
1162
- throw new ValidationError(`${label}: out of uint256 bounds (${value})`);
1163
- }
1164
- }
1165
- function parseBlockchainAmount(amount, decimals) {
1166
- const trimmed = amount.trim();
1167
- if (trimmed === "") return { valid: false, reason: { type: "empty" } };
1168
- if (trimmed.startsWith("-")) {
1169
- return { valid: false, reason: { type: "negative" } };
1170
- }
1171
- if (/[eE]/.test(trimmed)) {
1172
- return { valid: false, reason: { type: "invalid-format" } };
1173
- }
1174
- if (!/^\d+(\.\d+)?$/.test(trimmed)) {
1175
- return { valid: false, reason: { type: "invalid-format" } };
1176
- }
1177
- const [, fraction = ""] = trimmed.split(".");
1178
- if (fraction.length > decimals) {
1179
- return {
1180
- valid: false,
1181
- reason: { type: "too-many-decimals", maxDecimals: decimals }
1182
- };
1183
- }
1184
- try {
1185
- const raw = (0, import_viem2.parseUnits)(trimmed, decimals);
1186
- if (raw > MAX_UINT_256) {
1187
- return { valid: false, reason: { type: "overflow" } };
1188
- }
1189
- return {
1190
- valid: true,
1191
- amount: BlockchainAmount({ raw, decimals })
1192
- };
1193
- } catch {
1194
- return { valid: false, reason: { type: "invalid-format" } };
1195
- }
1196
- }
1197
-
1198
- // src/shared/core/blockchain/token-registry.ts
1199
- var USDC_SYMBOL = StablecoinSymbol("USDC");
1200
- var USDC = {
1201
- name: "USD Coin",
1202
- symbol: USDC_SYMBOL,
1203
- decimals: AssetDecimals(6)
1204
- };
1205
- var USDT_SYMBOL = StablecoinSymbol("USDT");
1206
- var USDT = {
1207
- name: "Tether USD",
1208
- symbol: USDT_SYMBOL,
1209
- decimals: AssetDecimals(6)
1210
- };
1211
- var USDC_ADDRESSES = {
1212
- ethereum_mainnet: EvmContractAddress(
1213
- "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
1214
- ),
1215
- ethereum_sepolia: EvmContractAddress(
1216
- "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"
1217
- ),
1218
- base_mainnet: EvmContractAddress(
1219
- "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
1220
- ),
1221
- base_sepolia: EvmContractAddress(
1222
- "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
1223
- )
1224
- };
1225
- var USDT_ADDRESSES = {
1226
- ethereum_mainnet: EvmContractAddress(
1227
- "0xdac17f958d2ee523a2206206994597c13d831ec7"
1228
- ),
1229
- ethereum_sepolia: EvmContractAddress(
1230
- "0x7169D38820dfd117C3FA1f22a697dBA58d90BA06"
1231
- ),
1232
- base_mainnet: EvmContractAddress(
1233
- "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2"
1234
- ),
1235
- base_sepolia: null
1236
- };
1237
- var TOKEN_REGISTRY = {
1238
- erc20: (symbol) => {
1239
- switch (symbol) {
1240
- case "USDC":
1241
- return USDC;
1242
- case "USDT":
1243
- return USDT;
1244
- default:
1245
- throw new InvariantError(`Unknown asset symbol: ${symbol}`);
1246
- }
1247
- },
1248
- /**
1249
- * USDC's contract on `chain`. USDC is deployed on every chain the SDK
1250
- * models, so the table is total and the answer is never `null`.
1251
- */
1252
- usdcAddress: (chain) => USDC_ADDRESSES[chain],
1253
- /**
1254
- * USDT's contract on `chain`, or `null` where Tether publishes none —
1255
- * Base Sepolia today. The honest answer, never a fake address a balance
1256
- * read would call.
1257
- */
1258
- usdtAddress: (chain) => USDT_ADDRESSES[chain]
1259
- };
1260
-
1261
- // src/shared/types/pagination.ts
1262
- var Cursor = (value) => value;
1263
- var PaginatedResponse = {
1264
- fromDto: (dto, itemMapper) => ({
1265
- data: dto.data.map(itemMapper),
1266
- startingAfter: dto.starting_after ? Cursor(dto.starting_after) : null,
1267
- startingBefore: dto.starting_before ? Cursor(dto.starting_before) : null
1268
- })
1269
- };
1270
- var PaginationParams = {
1271
- toQueryParams: (params) => {
1272
- const queryParams = {};
1273
- if (params.after) {
1274
- queryParams.starting_after = params.after;
1275
- }
1276
- if (params.before) {
1277
- queryParams.starting_before = params.before;
1278
- }
1279
- if (params.limit) {
1280
- queryParams.limit = params.limit;
1281
- }
1282
- return queryParams;
1283
- }
1284
- };
1285
-
1286
- // src/shared/types/asset.ts
1287
- var AssetId = (value) => value;
1288
- var AssetCode = (value) => value;
1289
- var Asset = {
1290
- fromDto: (dto) => ({
1291
- id: AssetId(dto.id),
1292
- code: AssetCode(dto.code),
1293
- name: dto.name,
1294
- fractionalDigits: dto.fractional_digits
1295
- })
1296
- };
1297
-
1298
- // src/shared/types/offer.ts
1299
- var OfferId = (value) => value;
1300
- var OfferSlug = (value) => value;
1301
- var Offer = {
1302
- fromDto: (dto) => {
1303
- if (!Array.isArray(dto.tokens)) {
1304
- throw new ValidationError(
1305
- `Offer.tokens: expected an array, got ${typeof dto.tokens}`
1306
- );
1307
- }
1308
- return {
1309
- id: OfferId(dto.id),
1310
- slug: OfferSlug(dto.slug),
1311
- type: dto.type,
1312
- tagline: dto.tagline,
1313
- bannerUrl: dto.banner_url,
1314
- logoUrl: dto.logo_url,
1315
- startsAt: new Date(dto.starts_at),
1316
- endsAt: dto.ends_at ? new Date(dto.ends_at) : null,
1317
- tokens: dto.tokens.map(OfferToken.fromDto)
1318
- };
1319
- }
1320
- };
1321
- var OfferToken = {
1322
- fromDto: (dto) => ({
1323
- role: dto.role,
1324
- chain: Chain(dto.chain),
1325
- address: EvmContractAddress(dto.address)
1326
- })
1327
- };
1328
-
1329
- // src/shared/types/offer-detail.ts
1330
- var OfferOptionId = (value) => value;
1331
- var OfferOptionSlug = (value) => value;
1332
645
  var OfferDetail = {
1333
646
  fromDto: (dto) => {
1334
647
  if (!Array.isArray(dto.funding_assets)) {
@@ -1366,6 +679,12 @@ var OfferDetail = {
1366
679
  `OfferDetail.tokens: expected an array, got ${typeof dto.tokens}`
1367
680
  );
1368
681
  }
682
+ const swapContracts = dto.swap_contracts === void 0 ? [] : dto.swap_contracts;
683
+ if (!Array.isArray(swapContracts)) {
684
+ throw new ValidationError(
685
+ `OfferDetail.swap_contracts: expected an array, got ${typeof swapContracts}`
686
+ );
687
+ }
1369
688
  return {
1370
689
  id: OfferId(dto.id),
1371
690
  slug: OfferSlug(dto.slug),
@@ -1373,7 +692,8 @@ var OfferDetail = {
1373
692
  name: dto.name,
1374
693
  asset: Asset.fromDto(dto.asset),
1375
694
  fundingAssets: dto.funding_assets.map(Asset.fromDto),
1376
- tokens: dto.tokens.map(OfferToken.fromDto),
695
+ tokens: OfferToken.listFromDto(dto.tokens),
696
+ swapContracts: swapContracts.map(OfferSwapContract.fromDto),
1377
697
  about: notBlankStringOrNull(dto.about),
1378
698
  tagline: dto.tagline,
1379
699
  bannerUrl: dto.banner_url,
@@ -1427,7 +747,7 @@ var Milestone = {
1427
747
  })
1428
748
  };
1429
749
 
1430
- // src/shared/types/providers/coin-list/token-sale.ts
750
+ // src/universal/types/providers/coin-list/token-sale.ts
1431
751
  var ParticipationId = (value) => value;
1432
752
  var Blockchain = (value) => value;
1433
753
  var WalletAddress = (value) => value;
@@ -1474,7 +794,7 @@ var CreateParticipationParams = {
1474
794
  })
1475
795
  };
1476
796
 
1477
- // src/shared/api/frontline/providers/coin-list/token-sale.ts
797
+ // src/universal/api/frontline/providers/coin-list/token-sale.ts
1478
798
  async function fetchParticipations(api, offerId) {
1479
799
  return fetchAllPages(
1480
800
  (params) => fetchParticipationsPage(api, params),
@@ -1496,19 +816,168 @@ async function fetchParticipation(api, id) {
1496
816
  url: `/v1/participations/${id}`,
1497
817
  attributes: Attributes.protected()
1498
818
  });
1499
- return Participation.fromDto(dto);
819
+ return Participation.fromDto(dto);
820
+ }
821
+ async function createParticipation(api, params) {
822
+ const dto = await api.send({
823
+ method: "POST",
824
+ url: "/v1/participations",
825
+ body: CreateParticipationParams.toDto(params),
826
+ attributes: Attributes.protected()
827
+ });
828
+ return Participation.fromDto(dto);
829
+ }
830
+
831
+ // src/universal/core/shared/observability/log-cause.ts
832
+ function classifyLogCause(error) {
833
+ if (error instanceof HttpError) {
834
+ return httpCause(error);
835
+ }
836
+ if (error instanceof ValidationError) {
837
+ return { type: "validation", message: error.message };
838
+ }
839
+ if (error instanceof InvariantError) {
840
+ return { type: "invariant", message: error.message };
841
+ }
842
+ if (error instanceof MathError) {
843
+ return { type: "math", message: error.message };
844
+ }
845
+ if (error instanceof NotAuthenticatedError) {
846
+ return { type: "not-authenticated" };
847
+ }
848
+ if (error instanceof NotImplementedError) {
849
+ return { type: "not-implemented" };
850
+ }
851
+ return { type: "generic-error", name: errorName(error) };
852
+ }
853
+ function describeErrorUnredacted(error) {
854
+ if (error instanceof HttpError) {
855
+ return describeHttpErrorRedacted(error);
856
+ }
857
+ if (error instanceof Error) {
858
+ return `${error.name}: ${error.message}`;
859
+ }
860
+ return `thrown non-error: ${stringifyUnredacted(error)}`;
861
+ }
862
+ function stringifyUnredacted(value) {
863
+ if (value === void 0) return "";
864
+ try {
865
+ return JSON.stringify(
866
+ value,
867
+ (_key, item) => typeof item === "bigint" ? `${item}` : item
868
+ ) ?? String(value);
869
+ } catch (_) {
870
+ return "<unserializable>";
871
+ }
872
+ }
873
+ function describeHttpErrorRedacted(error) {
874
+ const code = apiErrorCode(error);
875
+ const status = error.response.status;
876
+ return code === null ? `HttpError ${status}` : `HttpError ${status} (${code})`;
877
+ }
878
+ function errorName(error) {
879
+ return error instanceof Error ? error.name : `non-error ${typeof error}`;
880
+ }
881
+ function httpCause(error) {
882
+ return {
883
+ type: "http",
884
+ requestId: error.requestId,
885
+ status: error.response.status,
886
+ code: apiErrorCode(error),
887
+ eventId: apiErrorEventId(error)
888
+ };
889
+ }
890
+ function apiErrorEventId(error) {
891
+ const body = error.response.body;
892
+ if (typeof body !== "object" || body === null) return null;
893
+ const eventId = body.event_id;
894
+ return typeof eventId === "string" ? eventId : null;
895
+ }
896
+
897
+ // src/universal/core/shared/observability/internal-logger.ts
898
+ function internalLogger(logger, scope) {
899
+ return logger ? scopedLogger(logger, scope, {}) : noopInternalLogger;
900
+ }
901
+ var LEVEL_RANK = {
902
+ none: 0,
903
+ error: 1,
904
+ warn: 2,
905
+ info: 3,
906
+ debug: 4
907
+ };
908
+ function scopedLogger(logger, scope, bindings) {
909
+ const admits = (level) => LEVEL_RANK[logger.level()] >= LEVEL_RANK[level];
910
+ const safe = (event) => ({
911
+ msg: event.msg,
912
+ scope,
913
+ bindings,
914
+ fields: event.fields ?? {},
915
+ ...event.cause === void 0 ? {} : { cause: event.cause }
916
+ });
917
+ const unredacted = (event) => ({
918
+ msg: event.msg,
919
+ scope,
920
+ bindings,
921
+ fields: event.fields ?? {}
922
+ });
923
+ const self = {
924
+ child: (binding) => scopedLogger(logger, scope, { ...bindings, ...binding }),
925
+ debug: (event) => {
926
+ if (admits("debug")) logger.debug(() => unredacted(event()));
927
+ },
928
+ info: (event) => {
929
+ if (admits("info")) logger.info(() => safe(event()));
930
+ },
931
+ warn: (event) => {
932
+ if (admits("warn")) logger.warn(() => safe(event()));
933
+ },
934
+ error: (event) => {
935
+ if (admits("error")) logger.error(() => safe(event()));
936
+ },
937
+ failure: (event, error) => {
938
+ if (admits("debug"))
939
+ logger.debug(() => unredacted(verbatim(event(), error)));
940
+ if (admits("error")) logger.error(() => safe(classified(event(), error)));
941
+ },
942
+ warning: (event, error) => {
943
+ if (admits("debug"))
944
+ logger.debug(() => unredacted(verbatim(event(), error)));
945
+ if (admits("warn")) logger.warn(() => safe(classified(event(), error)));
946
+ },
947
+ wrap: async (op, params, run) => {
948
+ const opLog = self.child({ op });
949
+ opLog.debug(() => ({ msg: "call", fields: { params } }));
950
+ try {
951
+ return await run();
952
+ } catch (error) {
953
+ opLog.failure(() => ({ msg: "call failed" }), error);
954
+ throw error;
955
+ }
956
+ }
957
+ };
958
+ return self;
1500
959
  }
1501
- async function createParticipation(api, params) {
1502
- const dto = await api.send({
1503
- method: "POST",
1504
- url: "/v1/participations",
1505
- body: CreateParticipationParams.toDto(params),
1506
- attributes: Attributes.protected()
1507
- });
1508
- return Participation.fromDto(dto);
960
+ function verbatim(event, error) {
961
+ return {
962
+ msg: event.msg,
963
+ fields: { ...event.fields, error: describeErrorUnredacted(error) }
964
+ };
965
+ }
966
+ function classified(event, error) {
967
+ return { ...event, cause: event.cause ?? classifyLogCause(error) };
1509
968
  }
969
+ var noopInternalLogger = {
970
+ child: () => noopInternalLogger,
971
+ debug: () => void 0,
972
+ info: () => void 0,
973
+ warn: () => void 0,
974
+ error: () => void 0,
975
+ failure: () => void 0,
976
+ warning: () => void 0,
977
+ wrap: (_op, _params, run) => run()
978
+ };
1510
979
 
1511
- // src/shared/core/checkout/coin-list/token-sale-namespace.ts
980
+ // src/universal/core/checkout/coin-list/token-sale-namespace.ts
1512
981
  var CoinListTokenSaleNamespaceImpl = class {
1513
982
  constructor(ctx) {
1514
983
  this.ctx = ctx;
@@ -1538,70 +1007,340 @@ var CoinListTokenSaleNamespaceImpl = class {
1538
1007
  return createParticipation(this.ctx.api, params);
1539
1008
  });
1540
1009
  }
1541
- };
1010
+ };
1011
+
1012
+ // src/universal/core/shared/blockchain/token-registry.ts
1013
+ var USDC_SYMBOL = StablecoinSymbol("USDC");
1014
+ var USDC = {
1015
+ name: "USD Coin",
1016
+ symbol: USDC_SYMBOL,
1017
+ decimals: AssetDecimals(6)
1018
+ };
1019
+ var USDT_SYMBOL = StablecoinSymbol("USDT");
1020
+ var USDT = {
1021
+ name: "Tether USD",
1022
+ symbol: USDT_SYMBOL,
1023
+ decimals: AssetDecimals(6)
1024
+ };
1025
+ var USDC_ADDRESSES = {
1026
+ ethereum_mainnet: EvmContractAddress(
1027
+ "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
1028
+ ),
1029
+ ethereum_sepolia: EvmContractAddress(
1030
+ "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"
1031
+ ),
1032
+ base_mainnet: EvmContractAddress(
1033
+ "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
1034
+ ),
1035
+ base_sepolia: EvmContractAddress(
1036
+ "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
1037
+ )
1038
+ };
1039
+ var USDT_ADDRESSES = {
1040
+ ethereum_mainnet: EvmContractAddress(
1041
+ "0xdac17f958d2ee523a2206206994597c13d831ec7"
1042
+ ),
1043
+ ethereum_sepolia: EvmContractAddress(
1044
+ "0x7169D38820dfd117C3FA1f22a697dBA58d90BA06"
1045
+ ),
1046
+ base_mainnet: EvmContractAddress(
1047
+ "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2"
1048
+ ),
1049
+ base_sepolia: null
1050
+ };
1051
+ var TOKEN_REGISTRY = {
1052
+ erc20: (symbol) => {
1053
+ switch (symbol) {
1054
+ case "USDC":
1055
+ return USDC;
1056
+ case "USDT":
1057
+ return USDT;
1058
+ default:
1059
+ throw new InvariantError(`Unknown asset symbol: ${symbol}`);
1060
+ }
1061
+ },
1062
+ /**
1063
+ * USDC's contract on `chain`. USDC is deployed on every chain the SDK
1064
+ * models, so the table is total and the answer is never `null`.
1065
+ */
1066
+ usdcAddress: (chain) => USDC_ADDRESSES[chain],
1067
+ /**
1068
+ * USDT's contract on `chain`, or `null` where Tether publishes none —
1069
+ * Base Sepolia today. The honest answer, never a fake address a balance
1070
+ * read would call.
1071
+ */
1072
+ usdtAddress: (chain) => USDT_ADDRESSES[chain]
1073
+ };
1074
+
1075
+ // src/universal/core/checkout/ondo/constants.ts
1076
+ var ONDO_POLL_INTERVAL_MS = 15e3;
1077
+ var ONDO_QUOTE_EXPIRY_THRESHOLD_MS = 5e3;
1078
+ var DEFAULT_ONDO_AMOUNT_TO_COMPUTE_PRICE = DecimalString("1000");
1079
+ var ONDO_SETTLEMENT_ASSET = USDC_SYMBOL;
1080
+ var DEFAULT_ONDO_SELL_TOKENS_TO_COMPUTE_PRICE = 1;
1081
+ var ONDO_SUPPORTED_INPUT_ASSETS = [
1082
+ USDC_SYMBOL
1083
+ ];
1084
+
1085
+ // src/universal/core/checkout/ondo/math.ts
1086
+ function computeOndoBuyPrice(transaction) {
1087
+ const { notionalValue, receiveOutputAmount } = transaction;
1088
+ return pricePerShare({
1089
+ usd: notionalValue,
1090
+ shares: receiveOutputAmount
1091
+ });
1092
+ }
1093
+ function computeOndoSellPrice(transaction) {
1094
+ const { expected, spendInputAmount } = transaction;
1095
+ return pricePerShare({
1096
+ usd: grossProceeds(expected),
1097
+ shares: spendInputAmount
1098
+ });
1099
+ }
1100
+ function grossProceeds(expected) {
1101
+ const raw = expected.quantity.raw + expected.fee.raw;
1102
+ if (raw > MAX_UINT_256) {
1103
+ throw new MathError(`Ondo sell proceeds: out of uint256 bounds (${raw})`);
1104
+ }
1105
+ return BlockchainAmount.add(expected.quantity, expected.fee);
1106
+ }
1107
+ function pricePerShare({
1108
+ usd,
1109
+ shares
1110
+ }) {
1111
+ const price = BlockchainAmount.div(usd, shares);
1112
+ return BlockchainAmount({
1113
+ raw: assertPriceFits(price.raw),
1114
+ decimals: price.decimals
1115
+ });
1116
+ }
1117
+ function assertPriceFits(raw) {
1118
+ try {
1119
+ return assertUint256(raw);
1120
+ } catch {
1121
+ throw new MathError(`Ondo price: out of uint256 bounds (${raw})`);
1122
+ }
1123
+ }
1124
+
1125
+ // src/universal/core/shared/blockchain/formatters.ts
1126
+ var import_viem = require("viem");
1127
+
1128
+ // src/universal/types/blockchain/ui.ts
1129
+ var FormattedAmountUi = (value) => value;
1130
+ var FormattedPercentUi = (value) => value;
1131
+ var TxExplorerUrl = (value) => value;
1132
+ var ShortenedWalletAddress = (value) => value;
1133
+ var FormattedAmountAssetUi = (value) => value;
1134
+ var AssetIconUrl = (value) => value;
1135
+
1136
+ // src/universal/core/shared/blockchain/formatters.ts
1137
+ function shortenAddress(address) {
1138
+ const short = address.length > 10 ? `${address.slice(0, 6)}\u2026${address.slice(-4)}` : address;
1139
+ return ShortenedWalletAddress(short);
1140
+ }
1141
+ function formatAmount(amount, locale, options) {
1142
+ const decimal = formatRawAmount(amount);
1143
+ let [integerPart, fractionPart = ""] = decimal.split(".");
1144
+ const maxFractionDigits = options?.maxFractionDigits;
1145
+ const minFractionDigits = maxFractionDigits !== void 0 ? Math.min(maxFractionDigits, amount.decimals) : Math.min(2, amount.decimals);
1146
+ if (maxFractionDigits !== void 0 && fractionPart.length > maxFractionDigits) {
1147
+ ({ integerPart, fractionPart } = roundFractionHalfUp(
1148
+ integerPart,
1149
+ fractionPart,
1150
+ maxFractionDigits
1151
+ ));
1152
+ }
1153
+ const fraction = minFractionDigits === 0 ? "" : fractionPart.padEnd(minFractionDigits, "0");
1154
+ const integerFormatted = BigInt(integerPart).toLocaleString(locale);
1155
+ if (minFractionDigits === 0 && fraction === "") {
1156
+ return FormattedAmountUi(integerFormatted);
1157
+ }
1158
+ const decimalSeparator = new Intl.NumberFormat(locale).formatToParts(1.1).find((p) => p.type === "decimal")?.value ?? ".";
1159
+ return FormattedAmountUi(`${integerFormatted}${decimalSeparator}${fraction}`);
1160
+ }
1161
+ function roundFractionHalfUp(integerPart, fractionPart, maxFractionDigits) {
1162
+ if (fractionPart.length <= maxFractionDigits) {
1163
+ return { integerPart, fractionPart };
1164
+ }
1165
+ if (maxFractionDigits === 0) {
1166
+ const roundUp = fractionPart[0] >= "5";
1167
+ const integer = BigInt(integerPart) + (roundUp ? 1n : 0n);
1168
+ return { integerPart: integer.toString(), fractionPart: "" };
1169
+ }
1170
+ const trimmed = fractionPart.slice(0, maxFractionDigits);
1171
+ if (fractionPart[maxFractionDigits] < "5") {
1172
+ return { integerPart, fractionPart: trimmed };
1173
+ }
1174
+ const digits = trimmed.split("").map((digit) => Number.parseInt(digit, 10));
1175
+ let carry = 1;
1176
+ for (let i = digits.length - 1; i >= 0 && carry > 0; i -= 1) {
1177
+ const sum = digits[i] + carry;
1178
+ if (sum === 10) {
1179
+ digits[i] = 0;
1180
+ carry = 1;
1181
+ } else {
1182
+ digits[i] = sum;
1183
+ carry = 0;
1184
+ }
1185
+ }
1186
+ return {
1187
+ integerPart: carry > 0 ? (BigInt(integerPart) + 1n).toString() : integerPart,
1188
+ fractionPart: digits.join("")
1189
+ };
1190
+ }
1191
+ function formatRawAmount(amount) {
1192
+ return (0, import_viem.formatUnits)(amount.raw, amount.decimals);
1193
+ }
1194
+ function formatCompactAmount(amount, locale) {
1195
+ const value = Number(formatRawAmount(amount));
1196
+ const formatted = new Intl.NumberFormat(locale, {
1197
+ notation: "compact",
1198
+ maximumFractionDigits: 2
1199
+ }).format(value);
1200
+ return FormattedAmountUi(formatted);
1201
+ }
1202
+ function formatBpsAsPercent(bps, locale) {
1203
+ const whole = bps / 100n;
1204
+ const fraction = bps % 100n;
1205
+ const wholeFormatted = whole.toLocaleString(locale);
1206
+ const decimalSeparator = new Intl.NumberFormat(locale).formatToParts(1.1).find((p) => p.type === "decimal")?.value ?? ".";
1207
+ if (fraction === 0n) {
1208
+ return FormattedPercentUi(`${wholeFormatted}%`);
1209
+ }
1210
+ const fractionFormatted = fraction.toString().padStart(2, "0").replace(/0+$/, "");
1211
+ return FormattedPercentUi(
1212
+ `${wholeFormatted}${decimalSeparator}${fractionFormatted}%`
1213
+ );
1214
+ }
1215
+ function usdAmount(amount) {
1216
+ return FormattedAmountAssetUi(`$${amount}`);
1217
+ }
1218
+ function assetAmount(amount, symbol) {
1219
+ return FormattedAmountAssetUi(`${amount} ${symbol}`);
1220
+ }
1221
+ var NA_AMOUNT_ASSET_UI = FormattedAmountAssetUi("-");
1222
+ var USD_FRACTION_DIGITS = AssetDecimals(2);
1223
+ function formattedUsdPrice(amount, locale) {
1224
+ if (!amount) return NA_AMOUNT_ASSET_UI;
1225
+ return usdAmount(
1226
+ formatAmount(amount, locale, { maxFractionDigits: USD_FRACTION_DIGITS })
1227
+ );
1228
+ }
1542
1229
 
1543
- // src/shared/core/checkout/ondo/constants.ts
1544
- var ONDO_SWAP_CONTRACT_ADDRESSES = {
1545
- ethereum_sepolia: EvmContractAddress(
1546
- "0x7014019ed51Edab984a71D30F2707D2dB2316A7A"
1547
- )
1230
+ // src/universal/core/shared/blockchain/chain.ts
1231
+ var CHAIN_IDS = {
1232
+ ethereum_mainnet: 1,
1233
+ ethereum_sepolia: 11155111,
1234
+ base_mainnet: 8453,
1235
+ base_sepolia: 84532
1548
1236
  };
1549
- function ondoSwapContractAddress(chain) {
1550
- return ONDO_SWAP_CONTRACT_ADDRESSES[chain] ?? null;
1237
+ function getChainId(chain) {
1238
+ return CHAIN_IDS[chain];
1551
1239
  }
1552
- var ONDO_POLL_INTERVAL_MS = 15e3;
1553
- var ONDO_QUOTE_EXPIRY_THRESHOLD_MS = 5e3;
1554
- var DEFAULT_ONDO_AMOUNT_TO_COMPUTE_PRICE = DecimalString("1000");
1555
- var ONDO_SETTLEMENT_ASSET = USDC_SYMBOL;
1556
- var DEFAULT_ONDO_SELL_TOKENS_TO_COMPUTE_PRICE = 1;
1557
- var ONDO_SUPPORTED_INPUT_ASSETS = [
1558
- USDC_SYMBOL
1559
- ];
1560
-
1561
- // src/shared/core/checkout/ondo/math.ts
1562
- function computeOndoBuyPrice(transaction) {
1563
- const { notionalValue, receiveOutputAmount } = transaction;
1564
- return pricePerShare({
1565
- usd: notionalValue,
1566
- shares: receiveOutputAmount
1567
- });
1240
+ function chainFromId(chainId) {
1241
+ const chains = Object.keys(CHAIN_IDS);
1242
+ const chain = chains.find((c) => String(CHAIN_IDS[c]) === chainId);
1243
+ if (!chain) {
1244
+ throw new ValidationError(`Unsupported EIP-155 chain id: "${chainId}"`);
1245
+ }
1246
+ return chain;
1568
1247
  }
1569
- function computeOndoSellPrice(transaction) {
1570
- const { expected, spendInputAmount } = transaction;
1571
- return pricePerShare({
1572
- usd: grossProceeds(expected),
1573
- shares: spendInputAmount
1574
- });
1248
+ function getNetworkName(chain) {
1249
+ switch (chain) {
1250
+ case "ethereum_mainnet":
1251
+ return "Ethereum";
1252
+ case "ethereum_sepolia":
1253
+ return "Ethereum Sepolia";
1254
+ case "base_mainnet":
1255
+ return "Base";
1256
+ case "base_sepolia":
1257
+ return "Base Sepolia";
1258
+ default: {
1259
+ const _exhaustive = chain;
1260
+ return _exhaustive;
1261
+ }
1262
+ }
1575
1263
  }
1576
- function grossProceeds(expected) {
1577
- const raw = expected.quantity.raw + expected.fee.raw;
1578
- if (raw > MAX_UINT_256) {
1579
- throw new MathError(`Ondo sell proceeds: out of uint256 bounds (${raw})`);
1264
+ function txExplorerUrl(chain, txHash) {
1265
+ return TxExplorerUrl(`${explorerBaseUrl(chain)}/tx/${txHash}`);
1266
+ }
1267
+ function explorerBaseUrl(chain) {
1268
+ switch (chain) {
1269
+ case "ethereum_mainnet":
1270
+ return "https://etherscan.io";
1271
+ case "ethereum_sepolia":
1272
+ return "https://sepolia.etherscan.io";
1273
+ case "base_mainnet":
1274
+ return "https://basescan.org";
1275
+ case "base_sepolia":
1276
+ return "https://sepolia-explorer.base.org";
1277
+ default: {
1278
+ const _exhaustive = chain;
1279
+ return _exhaustive;
1280
+ }
1580
1281
  }
1581
- return BlockchainAmount.add(expected.quantity, expected.fee);
1582
1282
  }
1583
- function pricePerShare({
1584
- usd,
1585
- shares
1283
+
1284
+ // src/universal/core/shared/blockchain/math.ts
1285
+ var import_viem2 = require("viem");
1286
+ function blockchainAmountFromRawOrThrow({
1287
+ label,
1288
+ raw,
1289
+ decimals
1586
1290
  }) {
1587
- const price = BlockchainAmount.div(usd, shares);
1588
- return BlockchainAmount({
1589
- raw: assertPriceFits(price.raw),
1590
- decimals: price.decimals
1591
- });
1291
+ const trimmed = raw.trim();
1292
+ if (trimmed === "") {
1293
+ throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
1294
+ }
1295
+ let value;
1296
+ try {
1297
+ value = BigInt(trimmed);
1298
+ } catch {
1299
+ throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
1300
+ }
1301
+ try {
1302
+ return BlockchainAmount({ raw: assertUint256(value), decimals });
1303
+ } catch {
1304
+ throw new ValidationError(`${label}: out of uint256 bounds (${value})`);
1305
+ }
1592
1306
  }
1593
- function assertPriceFits(raw) {
1307
+ function parseBlockchainAmount(amount, decimals) {
1308
+ const trimmed = amount.trim();
1309
+ if (trimmed === "") return { valid: false, reason: { type: "empty" } };
1310
+ if (trimmed.startsWith("-")) {
1311
+ return { valid: false, reason: { type: "negative" } };
1312
+ }
1313
+ if (/[eE]/.test(trimmed)) {
1314
+ return { valid: false, reason: { type: "invalid-format" } };
1315
+ }
1316
+ if (!/^\d+(\.\d+)?$/.test(trimmed)) {
1317
+ return { valid: false, reason: { type: "invalid-format" } };
1318
+ }
1319
+ const [, fraction = ""] = trimmed.split(".");
1320
+ if (fraction.length > decimals) {
1321
+ return {
1322
+ valid: false,
1323
+ reason: { type: "too-many-decimals", maxDecimals: decimals }
1324
+ };
1325
+ }
1594
1326
  try {
1595
- return assertUint256(raw);
1327
+ const raw = (0, import_viem2.parseUnits)(trimmed, decimals);
1328
+ if (raw > MAX_UINT_256) {
1329
+ return { valid: false, reason: { type: "overflow" } };
1330
+ }
1331
+ return {
1332
+ valid: true,
1333
+ amount: BlockchainAmount({ raw, decimals })
1334
+ };
1596
1335
  } catch {
1597
- throw new MathError(`Ondo price: out of uint256 bounds (${raw})`);
1336
+ return { valid: false, reason: { type: "invalid-format" } };
1598
1337
  }
1599
1338
  }
1600
1339
 
1601
- // src/shared/types/trading.ts
1340
+ // src/universal/types/trading.ts
1602
1341
  var Ticker = (value) => value;
1603
1342
 
1604
- // src/shared/types/providers/ondo/ondo.ts
1343
+ // src/universal/types/providers/ondo/ondo.ts
1605
1344
  var OndoTradingStatus = {
1606
1345
  fromDto: (dto) => {
1607
1346
  if (!dto.tradable) return { type: "not-tradable", side: dto.side };
@@ -1767,7 +1506,7 @@ function parseExpiresAt(value) {
1767
1506
  return date;
1768
1507
  }
1769
1508
 
1770
- // src/shared/api/frontline/providers/ondo/ondo.ts
1509
+ // src/universal/api/frontline/providers/ondo/ondo.ts
1771
1510
  async function getOndoTradingStatus(api, params) {
1772
1511
  const dto = await api.send({
1773
1512
  method: "GET",
@@ -1862,7 +1601,7 @@ function sizeParam(params) {
1862
1601
  return { notional_value: notionalValue };
1863
1602
  }
1864
1603
 
1865
- // src/shared/core/checkout/ondo/ondo-namespace.ts
1604
+ // src/universal/core/checkout/ondo/ondo-namespace.ts
1866
1605
  var OndoNamespaceImpl = class {
1867
1606
  constructor(ctx) {
1868
1607
  this.ctx = ctx;
@@ -1894,7 +1633,7 @@ var OndoNamespaceImpl = class {
1894
1633
  }
1895
1634
  };
1896
1635
 
1897
- // src/shared/core/checkout/superstate/blockchain/abi.ts
1636
+ // src/universal/core/checkout/superstate/blockchain/abi.ts
1898
1637
  var SUPERSTATE_SWAP_ABI = [
1899
1638
  {
1900
1639
  type: "function",
@@ -2116,7 +1855,13 @@ var SUPERSTATE_SWAP_ABI = [
2116
1855
  }
2117
1856
  ];
2118
1857
 
2119
- // src/shared/core/checkout/superstate/blockchain/math.ts
1858
+ // src/universal/core/shared/blockchain/bps.ts
1859
+ var BPS_DENOM = Bps(10000n);
1860
+ function applyBps(amount, bps) {
1861
+ return assertUint256(amount * bps / BPS_DENOM);
1862
+ }
1863
+
1864
+ // src/universal/core/checkout/superstate/blockchain/math.ts
2120
1865
  function computePrice({
2121
1866
  inputTokenAmount,
2122
1867
  outputTokenAmount
@@ -2134,7 +1879,7 @@ function computeSlip(amount, slippage) {
2134
1879
  return BlockchainAmount({ raw: slipRaw, decimals: amount.decimals });
2135
1880
  }
2136
1881
 
2137
- // src/shared/core/checkout/superstate/blockchain/quote.ts
1882
+ // src/universal/core/checkout/superstate/blockchain/quote.ts
2138
1883
  var SwapQuote = {
2139
1884
  /**
2140
1885
  * Assembles a {@link SwapQuote} from a raw contract {@link SwapPreview}. The
@@ -2154,53 +1899,210 @@ var SwapQuote = {
2154
1899
  })
2155
1900
  };
2156
1901
 
2157
- // src/shared/core/checkout/superstate/blockchain/status.ts
2158
- function isStopped(status) {
2159
- return (status.stopped & status.swapLevel) !== 0n;
1902
+ // src/universal/core/checkout/superstate/blockchain/status.ts
1903
+ function isStopped(status) {
1904
+ return (status.stopped & status.swapLevel) !== 0n;
1905
+ }
1906
+
1907
+ // src/universal/core/checkout/superstate/blockchain/swapped-event.ts
1908
+ var import_viem3 = require("viem");
1909
+ function decodeSwappedOutputAmount(receipt, outputDecimals) {
1910
+ try {
1911
+ const [swapped] = (0, import_viem3.parseEventLogs)({
1912
+ abi: SUPERSTATE_SWAP_ABI,
1913
+ eventName: "Swapped",
1914
+ logs: receipt.logs
1915
+ });
1916
+ if (!swapped) return null;
1917
+ const raw = swapped.args.outputAmount;
1918
+ if (raw < 0n || raw > MAX_UINT_256) return null;
1919
+ return BlockchainAmount({ raw, decimals: outputDecimals });
1920
+ } catch {
1921
+ return null;
1922
+ }
1923
+ }
1924
+
1925
+ // src/universal/core/checkout/superstate/constants.ts
1926
+ var SUPERSTATE_ISSUER_NAME = "Superstate";
1927
+ var SUPERSTATE_SUPPORTED_INPUT_ASSETS = [USDC_SYMBOL];
1928
+ var SWAP_POLL_INTERVAL_MS = 15e3;
1929
+ var DEFAULT_AMOUNT_TO_COMPUTE_PRICE = 1000000n;
1930
+ var SLIPPAGE_OPTIONS_BPS = [25n, 50n, 100n, 200n, 500n].map(
1931
+ (n) => Bps(n)
1932
+ );
1933
+ var DEFAULT_SLIPPAGE_BPS = Bps(50n);
1934
+ var SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA = EvmContractAddress("0x84f8e9a6C9Cc12fe911259372EfCa5582C4ae557");
1935
+ var SUPERSTATE_SWAP_CONTRACT_ADDRESSES = {
1936
+ ethereum_sepolia: SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA
1937
+ };
1938
+ function superstateSwapContractAddress(chain) {
1939
+ return SUPERSTATE_SWAP_CONTRACT_ADDRESSES[chain] ?? null;
1940
+ }
1941
+
1942
+ // src/universal/core/checkout/superstate/formatters.ts
1943
+ function formattedPricePerShare(quote, locale) {
1944
+ if (!quote) return NA_AMOUNT_ASSET_UI;
1945
+ return formattedUsdPrice(computePrice(quote), locale);
1946
+ }
1947
+
1948
+ // src/universal/types/providers/superstate/swap.ts
1949
+ var SwapAuthorization = {
1950
+ fromDto: (dto) => ({
1951
+ authorized: dto.authorized
1952
+ })
1953
+ };
1954
+ var SwapPreview = {
1955
+ fromDto: (dto) => ({
1956
+ inputAmount: parseUint256(
1957
+ BigInt(dto.pay_input_amount),
1958
+ "SwapPreview.pay_input_amount"
1959
+ ),
1960
+ fee: parseUint256(BigInt(dto.fee), "SwapPreview.fee"),
1961
+ outputAmount: parseUint256(
1962
+ BigInt(dto.receive_output_amount),
1963
+ "SwapPreview.receive_output_amount"
1964
+ )
1965
+ })
1966
+ };
1967
+ var SwapStatus = {
1968
+ fromDto: (dto) => ({
1969
+ stopped: parseUint256(BigInt(dto.stopped), "SwapStatus.stopped"),
1970
+ swapLevel: parseUint256(BigInt(dto.swap_level), "SwapStatus.swap_level")
1971
+ })
1972
+ };
1973
+ var TokenAllowance = {
1974
+ fromDto: (dto) => ({
1975
+ allowance: parseUint256(BigInt(dto.allowance), "TokenAllowance.allowance")
1976
+ })
1977
+ };
1978
+ var TokenBalance = {
1979
+ fromDto: (dto) => ({
1980
+ balance: parseUint256(BigInt(dto.balance), "TokenBalance.balance")
1981
+ })
1982
+ };
1983
+ var AllowWalletResponse = {
1984
+ fromDto: (dto) => {
1985
+ switch (dto.action) {
1986
+ case "broadcast_transaction":
1987
+ return {
1988
+ action: "broadcast_transaction",
1989
+ to: EvmContractAddress(dto.to),
1990
+ data: HexEncodedTransactionData(dto.data)
1991
+ };
1992
+ case "none":
1993
+ return {
1994
+ action: "none",
1995
+ alreadyAllowed: dto.already_allowed
1996
+ };
1997
+ default: {
1998
+ const _exhaustive = dto;
1999
+ return _exhaustive;
2000
+ }
2001
+ }
2002
+ }
2003
+ };
2004
+
2005
+ // src/universal/api/frontline/providers/superstate/swap.ts
2006
+ async function getSwapAuthorization(api, params) {
2007
+ const dto = await api.send({
2008
+ method: "GET",
2009
+ url: "/v1/wallet/authorized",
2010
+ queryParams: {
2011
+ chain: params.chain,
2012
+ contract_address: params.contractAddress,
2013
+ wallet_address: params.walletAddress
2014
+ },
2015
+ attributes: Attributes.protected()
2016
+ });
2017
+ return SwapAuthorization.fromDto(dto);
2160
2018
  }
2161
-
2162
- // src/shared/core/checkout/superstate/blockchain/swapped-event.ts
2163
- var import_viem3 = require("viem");
2164
- function decodeSwappedOutputAmount(receipt, outputDecimals) {
2165
- try {
2166
- const [swapped] = (0, import_viem3.parseEventLogs)({
2167
- abi: SUPERSTATE_SWAP_ABI,
2168
- eventName: "Swapped",
2169
- logs: receipt.logs
2170
- });
2171
- if (!swapped) return null;
2172
- const raw = swapped.args.outputAmount;
2173
- if (raw < 0n || raw > MAX_UINT_256) return null;
2174
- return BlockchainAmount({ raw, decimals: outputDecimals });
2175
- } catch {
2176
- return null;
2177
- }
2019
+ async function getSwapOutputToken(api, params) {
2020
+ const dto = await api.send({
2021
+ method: "GET",
2022
+ url: "/v1/swap/output-token",
2023
+ queryParams: {
2024
+ chain: params.chain,
2025
+ contract_address: params.contractAddress
2026
+ },
2027
+ attributes: Attributes.protected()
2028
+ });
2029
+ return toErc20Asset(dto);
2178
2030
  }
2179
-
2180
- // src/shared/core/checkout/superstate/constants.ts
2181
- var SUPERSTATE_ISSUER_NAME = "Superstate";
2182
- var SUPERSTATE_SUPPORTED_INPUT_ASSETS = [USDC_SYMBOL];
2183
- var SWAP_POLL_INTERVAL_MS = 15e3;
2184
- var DEFAULT_AMOUNT_TO_COMPUTE_PRICE = 1000000n;
2185
- var SLIPPAGE_OPTIONS_BPS = [25n, 50n, 100n, 200n, 500n].map(
2186
- (n) => Bps(n)
2187
- );
2188
- var DEFAULT_SLIPPAGE_BPS = Bps(50n);
2189
- var SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA = EvmContractAddress("0x84f8e9a6C9Cc12fe911259372EfCa5582C4ae557");
2190
- var SUPERSTATE_SWAP_CONTRACT_ADDRESSES = {
2191
- ethereum_sepolia: SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA
2192
- };
2193
- function superstateSwapContractAddress(chain) {
2194
- return SUPERSTATE_SWAP_CONTRACT_ADDRESSES[chain] ?? null;
2031
+ async function getSwapPreview(api, params) {
2032
+ const dto = await api.send({
2033
+ method: "GET",
2034
+ url: "/v1/swap/preview",
2035
+ queryParams: {
2036
+ chain: params.chain,
2037
+ contract_address: params.contractAddress,
2038
+ input_token: params.inputToken,
2039
+ amount: params.amount.toString()
2040
+ },
2041
+ attributes: Attributes.protected()
2042
+ });
2043
+ return SwapPreview.fromDto(dto);
2195
2044
  }
2196
-
2197
- // src/shared/core/checkout/superstate/formatters.ts
2198
- function formattedPricePerShare(quote, locale) {
2199
- if (!quote) return NA_AMOUNT_ASSET_UI;
2200
- return formattedUsdPrice(computePrice(quote), locale);
2045
+ async function getSwapStatus(api, params) {
2046
+ const dto = await api.send({
2047
+ method: "GET",
2048
+ url: "/v1/swap/status",
2049
+ queryParams: {
2050
+ chain: params.chain,
2051
+ contract_address: params.contractAddress
2052
+ },
2053
+ attributes: Attributes.protected()
2054
+ });
2055
+ return SwapStatus.fromDto(dto);
2056
+ }
2057
+ async function getTokenAllowance(api, params) {
2058
+ const dto = await api.send({
2059
+ method: "GET",
2060
+ url: "/v1/token/allowance",
2061
+ queryParams: {
2062
+ chain: params.chain,
2063
+ token_address: params.tokenAddress,
2064
+ owner: params.owner,
2065
+ spender: params.spender
2066
+ },
2067
+ attributes: Attributes.protected()
2068
+ });
2069
+ return TokenAllowance.fromDto(dto);
2070
+ }
2071
+ async function getTokenBalance(api, params) {
2072
+ const dto = await api.send({
2073
+ method: "GET",
2074
+ url: "/v1/token/balance",
2075
+ queryParams: {
2076
+ chain: params.chain,
2077
+ token_address: params.tokenAddress,
2078
+ owner: params.owner
2079
+ },
2080
+ attributes: Attributes.protected()
2081
+ });
2082
+ return TokenBalance.fromDto(dto);
2083
+ }
2084
+ async function allowWallet(api, params) {
2085
+ const dto = await api.send({
2086
+ method: "POST",
2087
+ url: `/v1/offers/${encodeURIComponent(params.offerId)}/allow-wallet`,
2088
+ body: {
2089
+ wallet_address: params.walletAddress,
2090
+ chain: params.chain,
2091
+ signature: params.signature
2092
+ },
2093
+ attributes: Attributes.protected()
2094
+ });
2095
+ return AllowWalletResponse.fromDto(dto);
2096
+ }
2097
+ function toErc20Asset(dto) {
2098
+ return {
2099
+ name: dto.name,
2100
+ symbol: AssetSymbol(dto.symbol),
2101
+ decimals: AssetDecimals(dto.decimals)
2102
+ };
2201
2103
  }
2202
2104
 
2203
- // src/shared/core/checkout/superstate/swap-namespace.ts
2105
+ // src/universal/core/checkout/superstate/swap-namespace.ts
2204
2106
  var SuperstateSwapNamespaceImpl = class {
2205
2107
  constructor(ctx) {
2206
2108
  this.ctx = ctx;
@@ -2238,7 +2140,7 @@ var SuperstateSwapNamespaceImpl = class {
2238
2140
  }
2239
2141
  };
2240
2142
 
2241
- // src/shared/api/frontline/offers.ts
2143
+ // src/universal/api/frontline/offers.ts
2242
2144
  async function fetchOffers(api, clientCreds) {
2243
2145
  return fetchAllPages((params) => fetchOffersPage(api, params, clientCreds));
2244
2146
  }
@@ -2267,7 +2169,7 @@ async function fetchOfferDetails(api, id, clientCreds) {
2267
2169
  return OfferDetail.fromDto(dto);
2268
2170
  }
2269
2171
 
2270
- // src/shared/core/offers/offers-namespace.ts
2172
+ // src/universal/core/offers/offers-namespace.ts
2271
2173
  var OffersNamespaceImpl = class {
2272
2174
  constructor(ctx) {
2273
2175
  this.ctx = ctx;
@@ -2293,7 +2195,12 @@ var OffersNamespaceImpl = class {
2293
2195
  }
2294
2196
  };
2295
2197
 
2296
- // src/shared/types/document-submission.ts
2198
+ // src/universal/core/offers/swap-contracts.ts
2199
+ function swapSpender(swapContracts, chain) {
2200
+ return swapContracts.find((contract) => contract.chain === chain)?.address ?? null;
2201
+ }
2202
+
2203
+ // src/universal/types/document-submission.ts
2297
2204
  var DocumentSubmission = {
2298
2205
  fromDto: (dto) => ({
2299
2206
  status: dto.status,
@@ -2301,7 +2208,7 @@ var DocumentSubmission = {
2301
2208
  })
2302
2209
  };
2303
2210
 
2304
- // src/shared/api/frontline/documents.ts
2211
+ // src/universal/api/frontline/documents.ts
2305
2212
  async function submitDocument(api, documentType, fields) {
2306
2213
  const dto = await api.send({
2307
2214
  method: "POST",
@@ -2312,14 +2219,14 @@ async function submitDocument(api, documentType, fields) {
2312
2219
  return DocumentSubmission.fromDto(dto);
2313
2220
  }
2314
2221
 
2315
- // src/shared/types/kyc.ts
2222
+ // src/universal/types/kyc.ts
2316
2223
  var KycToken = {
2317
2224
  fromDto: (dto) => ({
2318
2225
  token: dto.token
2319
2226
  })
2320
2227
  };
2321
2228
 
2322
- // src/shared/api/frontline/kyc.ts
2229
+ // src/universal/api/frontline/kyc.ts
2323
2230
  async function createKycToken(api, levelName, reset) {
2324
2231
  const dto = await api.send({
2325
2232
  method: "POST",
@@ -2333,7 +2240,7 @@ async function createKycToken(api, levelName, reset) {
2333
2240
  return KycToken.fromDto(dto);
2334
2241
  }
2335
2242
 
2336
- // src/shared/types/pii.ts
2243
+ // src/universal/types/pii.ts
2337
2244
  var Iso2CountryCode = (value) => value;
2338
2245
  var PiiJurisdiction = {
2339
2246
  fromDto: (dto) => ({
@@ -2361,7 +2268,7 @@ var Pii = {
2361
2268
  })
2362
2269
  };
2363
2270
 
2364
- // src/shared/api/frontline/pii.ts
2271
+ // src/universal/api/frontline/pii.ts
2365
2272
  async function fetchPii(api) {
2366
2273
  const dto = await api.send({
2367
2274
  method: "GET",
@@ -2371,7 +2278,7 @@ async function fetchPii(api) {
2371
2278
  return Pii.fromDto(dto);
2372
2279
  }
2373
2280
 
2374
- // src/shared/types/requirement.ts
2281
+ // src/universal/types/requirement.ts
2375
2282
  var RequirementId = (value) => value;
2376
2283
  var Requirement = {
2377
2284
  fromDto: (dto) => ({
@@ -2392,7 +2299,7 @@ var RequirementStatusInfo = {
2392
2299
  )
2393
2300
  };
2394
2301
 
2395
- // src/shared/api/frontline/requirements.ts
2302
+ // src/universal/api/frontline/requirements.ts
2396
2303
  async function fetchOfferRequirements(api, offerId, clientCreds) {
2397
2304
  const response = await api.send({
2398
2305
  method: "GET",
@@ -2418,7 +2325,7 @@ async function fetchRequirementStatuses(api, offerId) {
2418
2325
  return RequirementStatusInfo.fromStatusesDto(response);
2419
2326
  }
2420
2327
 
2421
- // src/shared/core/requirements/requirements-namespace.ts
2328
+ // src/universal/core/requirements/requirements-namespace.ts
2422
2329
  var RequirementsNamespaceImpl = class {
2423
2330
  constructor(ctx) {
2424
2331
  this.ctx = ctx;
@@ -2468,13 +2375,133 @@ var RequirementsNamespaceImpl = class {
2468
2375
  }
2469
2376
  };
2470
2377
 
2471
- // src/shared/api/nabu/tokens.ts
2378
+ // src/universal/core/shared/blockchain/erc20/abi.ts
2379
+ var ERC20_ABI = [
2380
+ {
2381
+ type: "function",
2382
+ name: "allowance",
2383
+ inputs: [
2384
+ { name: "owner", type: "address" },
2385
+ { name: "spender", type: "address" }
2386
+ ],
2387
+ outputs: [{ name: "", type: "uint256" }],
2388
+ stateMutability: "view"
2389
+ },
2390
+ {
2391
+ type: "function",
2392
+ name: "approve",
2393
+ inputs: [
2394
+ { name: "spender", type: "address" },
2395
+ { name: "amount", type: "uint256" }
2396
+ ],
2397
+ outputs: [{ name: "", type: "bool" }],
2398
+ stateMutability: "nonpayable"
2399
+ },
2400
+ {
2401
+ type: "function",
2402
+ name: "balanceOf",
2403
+ inputs: [{ name: "account", type: "address" }],
2404
+ outputs: [{ name: "", type: "uint256" }],
2405
+ stateMutability: "view"
2406
+ },
2407
+ {
2408
+ type: "function",
2409
+ name: "decimals",
2410
+ inputs: [],
2411
+ outputs: [{ name: "", type: "uint8" }],
2412
+ stateMutability: "view"
2413
+ },
2414
+ {
2415
+ type: "function",
2416
+ name: "name",
2417
+ inputs: [],
2418
+ outputs: [{ name: "", type: "string" }],
2419
+ stateMutability: "view"
2420
+ },
2421
+ {
2422
+ type: "function",
2423
+ name: "symbol",
2424
+ inputs: [],
2425
+ outputs: [{ name: "", type: "string" }],
2426
+ stateMutability: "view"
2427
+ },
2428
+ {
2429
+ type: "function",
2430
+ name: "totalSupply",
2431
+ inputs: [],
2432
+ outputs: [{ name: "", type: "uint256" }],
2433
+ stateMutability: "view"
2434
+ },
2435
+ {
2436
+ type: "function",
2437
+ name: "transfer",
2438
+ inputs: [
2439
+ { name: "recipient", type: "address" },
2440
+ { name: "amount", type: "uint256" }
2441
+ ],
2442
+ outputs: [{ name: "", type: "bool" }],
2443
+ stateMutability: "nonpayable"
2444
+ },
2445
+ {
2446
+ type: "function",
2447
+ name: "transferFrom",
2448
+ inputs: [
2449
+ { name: "sender", type: "address" },
2450
+ { name: "recipient", type: "address" },
2451
+ { name: "amount", type: "uint256" }
2452
+ ],
2453
+ outputs: [{ name: "", type: "bool" }],
2454
+ stateMutability: "nonpayable"
2455
+ },
2456
+ {
2457
+ type: "event",
2458
+ name: "Approval",
2459
+ inputs: [
2460
+ { name: "owner", type: "address", indexed: true },
2461
+ { name: "spender", type: "address", indexed: true },
2462
+ { name: "value", type: "uint256", indexed: false }
2463
+ ],
2464
+ anonymous: false
2465
+ },
2466
+ {
2467
+ type: "event",
2468
+ name: "Transfer",
2469
+ inputs: [
2470
+ { name: "from", type: "address", indexed: true },
2471
+ { name: "to", type: "address", indexed: true },
2472
+ { name: "value", type: "uint256", indexed: false }
2473
+ ],
2474
+ anonymous: false
2475
+ }
2476
+ ];
2477
+
2478
+ // src/universal/core/shared/blockchain/erc20/erc20-namespace.ts
2479
+ var Erc20NamespaceImpl = class {
2480
+ constructor(ctx) {
2481
+ this.ctx = ctx;
2482
+ this.log = internalLogger(ctx.logger, "ERC20");
2483
+ }
2484
+ async getAllowance(params) {
2485
+ return this.log.wrap("getAllowance", params, async () => {
2486
+ await this.ctx.ensureUserAuthenticated();
2487
+ return getTokenAllowance(this.ctx.api, params);
2488
+ });
2489
+ }
2490
+ async getBalance(params) {
2491
+ return this.log.wrap("getBalance", params, async () => {
2492
+ await this.ctx.ensureUserAuthenticated();
2493
+ return getTokenBalance(this.ctx.api, params);
2494
+ });
2495
+ }
2496
+ };
2497
+
2498
+ // src/universal/api/nabu/tokens.ts
2472
2499
  var import_viem4 = require("viem");
2473
2500
 
2474
- // src/shared/api/frontline/config.ts
2501
+ // src/universal/api/frontline/config.ts
2475
2502
  var HEADER_API_VERSION = "X-API-Version";
2476
2503
 
2477
- // src/shared/api/http-client.ts
2504
+ // src/universal/api/http-client.ts
2478
2505
  var HttpClient = class {
2479
2506
  constructor(config, middleware = {}, logger = null, options = {}) {
2480
2507
  this.config = config;
@@ -2630,7 +2657,7 @@ function describeRequestUnredacted(request) {
2630
2657
  };
2631
2658
  }
2632
2659
 
2633
- // src/shared/types/token-metadata.ts
2660
+ // src/universal/types/token-metadata.ts
2634
2661
  var TokenLogoUrl = (value) => value;
2635
2662
  var TokenLogo = {
2636
2663
  /** `baseUrl` is the registry origin; registry URLs are root-relative. */
@@ -2713,7 +2740,7 @@ var resolveLogoUrl = (url, baseUrl) => TokenLogoUrl(
2713
2740
  url.startsWith("http") ? url : `${baseUrl.replace(/\/$/, "")}${url}`
2714
2741
  );
2715
2742
 
2716
- // src/shared/api/nabu/tokens.ts
2743
+ // src/universal/api/nabu/tokens.ts
2717
2744
  function createNabuApiClient(baseUrl, logger = null) {
2718
2745
  return new HttpClient({ baseUrl }, {}, logger);
2719
2746
  }
@@ -2804,10 +2831,10 @@ function checksummed(address) {
2804
2831
  }
2805
2832
  }
2806
2833
 
2807
- // src/shared/core/tokens/tokens-namespace.ts
2834
+ // src/universal/core/tokens/tokens-namespace.ts
2808
2835
  var TokensNamespaceImpl = class {
2809
2836
  /**
2810
- * Takes the registry origin rather than a `SharedNamespaceContext`: the
2837
+ * Takes the registry origin rather than a `UniversalNamespaceContext`: the
2811
2838
  * registry is unauthenticated and on its own host, so the frontline sender
2812
2839
  * and the auth check would both be dead weight here.
2813
2840
  */
@@ -2831,7 +2858,7 @@ var TokensNamespaceImpl = class {
2831
2858
  }
2832
2859
  };
2833
2860
 
2834
- // src/shared/types/offer-option-address.ts
2861
+ // src/universal/types/offer-option-address.ts
2835
2862
  var OfferOptionAddressId = (value) => value;
2836
2863
  var OfferOptionAddress = {
2837
2864
  /** Maps the API DTO into the SDK offer-option-address domain model. */
@@ -2853,7 +2880,7 @@ var ConnectExternalWalletParams = {
2853
2880
  })
2854
2881
  };
2855
2882
 
2856
- // src/shared/types/wallet-ownership-challenge.ts
2883
+ // src/universal/types/wallet-ownership-challenge.ts
2857
2884
  var WalletOwnershipChallenge = {
2858
2885
  /** Maps the API DTO into the SDK wallet-ownership-challenge domain model. */
2859
2886
  fromDto: (dto) => ({
@@ -2892,7 +2919,7 @@ var CreateWalletOwnershipChallengeParams = {
2892
2919
  }
2893
2920
  };
2894
2921
 
2895
- // src/shared/api/frontline/wallet-connect.ts
2922
+ // src/universal/api/frontline/wallet-connect.ts
2896
2923
  async function createWalletOwnershipChallenge(api, params) {
2897
2924
  const dto = await api.send({
2898
2925
  method: "POST",
@@ -2929,7 +2956,7 @@ async function removeOptionAddress(api, offerId, addressId) {
2929
2956
  return OfferOptionAddress.fromDto(dto);
2930
2957
  }
2931
2958
 
2932
- // src/shared/core/wallets/wallets-namespace.ts
2959
+ // src/universal/core/wallets/wallets-namespace.ts
2933
2960
  var WalletsNamespaceImpl = class {
2934
2961
  constructor(ctx) {
2935
2962
  this.ctx = ctx;
@@ -2972,12 +2999,12 @@ var WalletsNamespaceImpl = class {
2972
2999
  }
2973
3000
  };
2974
3001
 
2975
- // src/shared/types/blockchain/wallet-error.ts
3002
+ // src/universal/types/blockchain/wallet-error.ts
2976
3003
  var RedactedWalletError = {
2977
3004
  fromWalletError: (error) => error.type === "unknown" ? { type: "unknown" } : error
2978
3005
  };
2979
3006
 
2980
- // src/shared/types/oauth-session.ts
3007
+ // src/universal/types/oauth-session.ts
2981
3008
  var ClientCredentialsOAuth = (value) => value;
2982
3009
  var OAuthRefreshToken = (value) => value;
2983
3010
  var OAuthSession = {
@@ -2993,7 +3020,7 @@ var OAuthSession = {
2993
3020
  }
2994
3021
  };
2995
3022
 
2996
- // src/shared/types/user.ts
3023
+ // src/universal/types/user.ts
2997
3024
  var UserId = (value) => value;
2998
3025
  var UserEmail = (value) => value;
2999
3026
  var User = {
@@ -3072,6 +3099,7 @@ var User = {
3072
3099
  OfferOptionId,
3073
3100
  OfferOptionSlug,
3074
3101
  OfferSlug,
3102
+ OfferSwapContract,
3075
3103
  OfferToken,
3076
3104
  OffersNamespaceImpl,
3077
3105
  OndoBuyTransaction,
@@ -3152,12 +3180,13 @@ var User = {
3152
3180
  generatePKCEParams,
3153
3181
  getChainId,
3154
3182
  getNetworkName,
3183
+ isChain,
3155
3184
  isStopped,
3156
- ondoSwapContractAddress,
3157
3185
  parseBlockchainAmount,
3158
3186
  parseUint256,
3159
3187
  shortenAddress,
3160
3188
  superstateSwapContractAddress,
3189
+ swapSpender,
3161
3190
  txExplorerUrl,
3162
3191
  usdAmount
3163
3192
  });