@coinlist-co/react 0.12.2-rc.0fda52c → 0.12.2-rc.5f2ca48

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 (32) hide show
  1. package/dist/{chunk-STAHYDLY.js → chunk-6NCNF5GF.js} +2 -2
  2. package/dist/{chunk-KRA6EM2L.js → chunk-VUIDJYHY.js} +18 -3
  3. package/dist/chunk-VUIDJYHY.js.map +1 -0
  4. package/dist/{chunk-BNMF2HMW.js → chunk-XCRU3YE2.js} +628 -402
  5. package/dist/chunk-XCRU3YE2.js.map +1 -0
  6. package/dist/client/index.cjs +605 -160
  7. package/dist/client/index.cjs.map +1 -1
  8. package/dist/client/index.d.cts +271 -29
  9. package/dist/client/index.d.ts +271 -29
  10. package/dist/client/index.js +294 -21
  11. package/dist/client/index.js.map +1 -1
  12. package/dist/server/index.cjs +216 -62
  13. package/dist/server/index.cjs.map +1 -1
  14. package/dist/server/index.d.cts +10 -2
  15. package/dist/server/index.d.ts +10 -2
  16. package/dist/server/index.js +4 -2
  17. package/dist/server/index.js.map +1 -1
  18. package/dist/{time-B5YOQxuh.d.ts → time-CTuVDTx6.d.ts} +1 -1
  19. package/dist/{time-BY3apBpc.d.cts → time-Dv1dejVB.d.cts} +1 -1
  20. package/dist/{token-registry-snapshot-DyjrA32p.d.cts → token-registry-snapshot-CX5YiSHp.d.cts} +9 -7
  21. package/dist/{token-registry-snapshot-C1NxdBmF.d.ts → token-registry-snapshot-CzJd2VYU.d.ts} +9 -7
  22. package/dist/{tokens-namespace-BJfFeowE.d.cts → tokens-namespace-CcvHrw-k.d.cts} +462 -20
  23. package/dist/{tokens-namespace-BJfFeowE.d.ts → tokens-namespace-CcvHrw-k.d.ts} +462 -20
  24. package/dist/universal/index.cjs +568 -316
  25. package/dist/universal/index.cjs.map +1 -1
  26. package/dist/universal/index.d.cts +38 -6
  27. package/dist/universal/index.d.ts +38 -6
  28. package/dist/universal/index.js +22 -2
  29. package/package.json +1 -1
  30. package/dist/chunk-BNMF2HMW.js.map +0 -1
  31. package/dist/chunk-KRA6EM2L.js.map +0 -1
  32. /package/dist/{chunk-STAHYDLY.js.map → chunk-6NCNF5GF.js.map} +0 -0
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/client/index.ts
31
31
  var client_exports = {};
32
32
  __export(client_exports, {
33
+ CENTRIFUGE_VAULT_ORDER_REASON_MESSAGES: () => CENTRIFUGE_VAULT_ORDER_REASON_MESSAGES,
33
34
  ChecklistStatus: () => ChecklistStatus,
34
35
  CheckoutAssetUi: () => CheckoutAssetUi,
35
36
  CheckoutContainer: () => CheckoutContainer,
@@ -71,6 +72,7 @@ __export(client_exports, {
71
72
  OndoBuyOrderConfirmed: () => OndoBuyOrderConfirmed,
72
73
  OndoBuyReviewView: () => OndoBuyReviewView,
73
74
  OndoCheckoutError: () => OndoCheckoutError,
75
+ OndoCheckoutErrorReason: () => OndoCheckoutErrorReason,
74
76
  OndoSellAmountView: () => OndoSellAmountView,
75
77
  OndoSellCheckoutContainer: () => OndoSellCheckoutContainer,
76
78
  OndoSellCheckoutView: () => OndoSellCheckoutView,
@@ -99,6 +101,9 @@ __export(client_exports, {
99
101
  USDT_ICON_URL: () => USDT_ICON_URL,
100
102
  VerificationOverlay: () => VerificationOverlay,
101
103
  authorizeWallet: () => authorizeWallet,
104
+ centrifugeLoadErrorReason: () => centrifugeLoadErrorReason,
105
+ centrifugeVaultOrderReasonMessage: () => centrifugeVaultOrderReasonMessage,
106
+ centrifugeVaultOrderingMessage: () => centrifugeVaultOrderingMessage,
102
107
  classifyWalletError: () => classifyWalletError,
103
108
  connectExternalWalletFlow: () => connectExternalWalletFlow,
104
109
  createCoinListClient: () => createCoinListClient,
@@ -110,6 +115,7 @@ __export(client_exports, {
110
115
  formatCountdown: () => formatCountdown,
111
116
  formatMonthYear: () => formatMonthYear,
112
117
  formatSaleCardCountdown: () => formatSaleCardCountdown,
118
+ isNotTradable: () => isNotTradable,
113
119
  offerAssetIconUrl: () => offerAssetIconUrl,
114
120
  offerIconUrl: () => offerIconUrl,
115
121
  offerTokenIdentifier: () => offerTokenIdentifier,
@@ -117,6 +123,7 @@ __export(client_exports, {
117
123
  pinoClientLogger: () => pinoClientLogger,
118
124
  prepareOndoBuy: () => prepareOndoBuy,
119
125
  prepareOndoSell: () => prepareOndoSell,
126
+ primaryCentrifugeVaultOrderReason: () => primaryCentrifugeVaultOrderReason,
120
127
  quoteIsStale: () => quoteIsStale,
121
128
  quoteOverAsks: () => quoteOverAsks,
122
129
  stablecoinIconUrl: () => stablecoinIconUrl,
@@ -124,6 +131,8 @@ __export(client_exports, {
124
131
  tokenLogoSrcSet: () => tokenLogoSrcSet,
125
132
  tokenLogoUrl: () => tokenLogoUrl,
126
133
  tokenMetadataOf: () => tokenMetadataOf,
134
+ useCentrifugeQuote: () => useCentrifugeQuote,
135
+ useCentrifugeVaultStatus: () => useCentrifugeVaultStatus,
127
136
  useCheckoutOfferTokenMetadata: () => useCheckoutOfferTokenMetadata,
128
137
  useCoinList: () => useCoinList,
129
138
  useCoinListSignInCardViewModel: () => useCoinListSignInCardViewModel,
@@ -1560,83 +1569,8 @@ async function fetchAllPages(fetchPage, baseParams) {
1560
1569
  return items;
1561
1570
  }
1562
1571
 
1563
- // src/universal/types/pagination.ts
1564
- var Cursor = (value) => value;
1565
- var PaginatedResponse = {
1566
- fromDto: (dto, itemMapper) => PaginatedResponse.fromDtoPage(dto, (items) => items.map(itemMapper)),
1567
- /**
1568
- * For a mapper that decides the page as a whole - one that drops items it
1569
- * cannot map, such as `Offer.listFromDto` - rather than item by item. The
1570
- * cursors are the wire's either way: dropping an item changes what the
1571
- * page holds, not where the next page starts.
1572
- */
1573
- fromDtoPage: (dto, pageMapper) => ({
1574
- data: pageMapper(dto.data),
1575
- startingAfter: dto.starting_after ? Cursor(dto.starting_after) : null,
1576
- startingBefore: dto.starting_before ? Cursor(dto.starting_before) : null
1577
- })
1578
- };
1579
- var PaginationParams = {
1580
- toQueryParams: (params) => {
1581
- const queryParams = {};
1582
- if (params.after) {
1583
- queryParams.starting_after = params.after;
1584
- }
1585
- if (params.before) {
1586
- queryParams.starting_before = params.before;
1587
- }
1588
- if (params.limit) {
1589
- queryParams.limit = params.limit;
1590
- }
1591
- return queryParams;
1592
- }
1593
- };
1594
-
1595
- // src/universal/types/asset.ts
1596
- var AssetId = (value) => value;
1597
- var AssetCode = (value) => value;
1598
- var Asset = {
1599
- fromDto: (dto) => ({
1600
- id: AssetId(dto.id),
1601
- code: AssetCode(dto.code),
1602
- name: dto.name,
1603
- fractionalDigits: dto.fractional_digits
1604
- })
1605
- };
1606
-
1607
- // src/universal/core/shared/utils/wire.ts
1608
- function unknownTypeError(dto, model) {
1609
- const type = dto.type;
1610
- throw new ValidationError(
1611
- `${model}.type: unknown type ${JSON.stringify(type)}`
1612
- );
1613
- }
1614
- function requiredString(value, field) {
1615
- const text = notBlankStringOrNull(value);
1616
- if (text === null) {
1617
- throw new ValidationError(
1618
- `${field}: expected a non-blank string, got ${typeof value === "string" ? "a blank string" : String(value)}`
1619
- );
1620
- }
1621
- return text;
1622
- }
1623
- function requiredDate(value, field) {
1624
- const date = typeof value === "string" ? new Date(value) : null;
1625
- if (date === null || Number.isNaN(date.getTime())) {
1626
- throw new ValidationError(
1627
- `${field}: expected a date, got ${JSON.stringify(value)}`
1628
- );
1629
- }
1630
- return date;
1631
- }
1632
- function requiredArray(value, field) {
1633
- if (!Array.isArray(value)) {
1634
- throw new ValidationError(
1635
- `${field}: expected an array, got ${typeof value}`
1636
- );
1637
- }
1638
- return value;
1639
- }
1572
+ // src/universal/core/shared/blockchain/math.ts
1573
+ var import_viem3 = require("viem");
1640
1574
 
1641
1575
  // src/universal/types/blockchain/core.ts
1642
1576
  var ETHEREUM_CHAINS = {
@@ -1728,13 +1662,281 @@ var AssetSymbol = (value) => value;
1728
1662
  var StablecoinSymbol = (value) => value;
1729
1663
  var Bps = (value) => value;
1730
1664
 
1665
+ // src/universal/core/shared/blockchain/math.ts
1666
+ function blockchainAmountFromRawOrThrow({
1667
+ label,
1668
+ raw,
1669
+ decimals
1670
+ }) {
1671
+ const trimmed = raw.trim();
1672
+ if (trimmed === "") {
1673
+ throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
1674
+ }
1675
+ let value;
1676
+ try {
1677
+ value = BigInt(trimmed);
1678
+ } catch {
1679
+ throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
1680
+ }
1681
+ try {
1682
+ return BlockchainAmount({ raw: assertUint256(value), decimals });
1683
+ } catch {
1684
+ throw new ValidationError(`${label}: out of uint256 bounds (${value})`);
1685
+ }
1686
+ }
1687
+ function parseBlockchainAmount(amount, decimals) {
1688
+ const trimmed = amount.trim();
1689
+ if (trimmed === "") return { valid: false, reason: { type: "empty" } };
1690
+ if (trimmed.startsWith("-")) {
1691
+ return { valid: false, reason: { type: "negative" } };
1692
+ }
1693
+ if (/[eE]/.test(trimmed)) {
1694
+ return { valid: false, reason: { type: "invalid-format" } };
1695
+ }
1696
+ if (trimmed === ".") {
1697
+ return { valid: false, reason: { type: "invalid-format" } };
1698
+ }
1699
+ const normalised = trimmed.replace(/^\./, "0.").replace(/\.$/, "");
1700
+ if (!/^\d+(\.\d+)?$/.test(normalised)) {
1701
+ return { valid: false, reason: { type: "invalid-format" } };
1702
+ }
1703
+ const [, fraction = ""] = normalised.split(".");
1704
+ if (fraction.length > decimals) {
1705
+ return {
1706
+ valid: false,
1707
+ reason: { type: "too-many-decimals", maxDecimals: decimals }
1708
+ };
1709
+ }
1710
+ try {
1711
+ const raw = (0, import_viem3.parseUnits)(normalised, decimals);
1712
+ if (raw > MAX_UINT_256) {
1713
+ return { valid: false, reason: { type: "overflow" } };
1714
+ }
1715
+ return {
1716
+ valid: true,
1717
+ amount: BlockchainAmount({ raw, decimals })
1718
+ };
1719
+ } catch {
1720
+ return { valid: false, reason: { type: "invalid-format" } };
1721
+ }
1722
+ }
1723
+
1724
+ // src/universal/core/shared/utils/wire.ts
1725
+ function unknownTypeError(dto, model) {
1726
+ const type = dto.type;
1727
+ throw new ValidationError(
1728
+ `${model}.type: unknown type ${JSON.stringify(type)}`
1729
+ );
1730
+ }
1731
+ function requiredString(value, field) {
1732
+ const text = notBlankStringOrNull(value);
1733
+ if (text === null) {
1734
+ throw new ValidationError(
1735
+ `${field}: expected a non-blank string, got ${typeof value === "string" ? "a blank string" : String(value)}`
1736
+ );
1737
+ }
1738
+ return text;
1739
+ }
1740
+ function requiredDate(value, field) {
1741
+ const date = typeof value === "string" ? new Date(value) : null;
1742
+ if (date === null || Number.isNaN(date.getTime())) {
1743
+ throw new ValidationError(
1744
+ `${field}: expected a date, got ${JSON.stringify(value)}`
1745
+ );
1746
+ }
1747
+ return date;
1748
+ }
1749
+ function dateOrNull(value, field) {
1750
+ return value === null ? null : requiredDate(value, field);
1751
+ }
1752
+ function decimalOrNull(value) {
1753
+ return value === null ? null : DecimalString(value);
1754
+ }
1755
+ function requiredArray(value, field) {
1756
+ if (!Array.isArray(value)) {
1757
+ throw new ValidationError(
1758
+ `${field}: expected an array, got ${typeof value}`
1759
+ );
1760
+ }
1761
+ return value;
1762
+ }
1763
+
1764
+ // src/universal/types/providers/centrifuge/centrifuge.ts
1765
+ var CentrifugeVaultQuote = {
1766
+ fromDto: (dto) => {
1767
+ const spendDecimals = AssetDecimals(dto.spend_input_decimals);
1768
+ const shareDecimals = AssetDecimals(dto.share_decimals);
1769
+ return {
1770
+ chain: EthereumChain(dto.chain),
1771
+ symbol: AssetSymbol(dto.symbol),
1772
+ spendInputAmount: blockchainAmountFromRawOrThrow({
1773
+ label: "spend_input_amount",
1774
+ raw: dto.spend_input_amount,
1775
+ decimals: spendDecimals
1776
+ }),
1777
+ estimatedShares: blockchainAmountFromRawOrThrow({
1778
+ label: "estimated_shares",
1779
+ raw: dto.estimated_shares,
1780
+ decimals: shareDecimals
1781
+ }),
1782
+ indicativePrice: decimalOrNull(dto.indicative_price),
1783
+ minimumInputAmount: dto.minimum_input_amount === null ? null : blockchainAmountFromRawOrThrow({
1784
+ label: "minimum_input_amount",
1785
+ raw: dto.minimum_input_amount,
1786
+ decimals: spendDecimals
1787
+ }),
1788
+ orderability: parseOrderability(
1789
+ dto.can_order,
1790
+ dto.reasons,
1791
+ "CentrifugeVaultQuote"
1792
+ )
1793
+ };
1794
+ }
1795
+ };
1796
+ var CentrifugeVaultStatus = {
1797
+ fromDto: (dto) => ({
1798
+ chain: EthereumChain(dto.chain),
1799
+ symbol: AssetSymbol(dto.symbol),
1800
+ vaultAddress: EvmContractAddress(dto.vault_address),
1801
+ linked: dto.linked,
1802
+ permissioned: dto.permissioned,
1803
+ membershipValidUntil: dateOrNull(
1804
+ dto.membership_valid_until,
1805
+ "CentrifugeVaultStatus.membership_valid_until"
1806
+ ),
1807
+ halted: dto.halted,
1808
+ priceUpdatedAt: dateOrNull(
1809
+ dto.price_updated_at,
1810
+ "CentrifugeVaultStatus.price_updated_at"
1811
+ ),
1812
+ orderability: parseOrderability(
1813
+ dto.can_order,
1814
+ dto.reasons,
1815
+ "CentrifugeVaultStatus"
1816
+ ),
1817
+ asOf: requiredDate(dto.as_of, "CentrifugeVaultStatus.as_of")
1818
+ })
1819
+ };
1820
+ function parseOrderability(canOrder, reasons, model) {
1821
+ const [first, ...rest] = reasons;
1822
+ if (canOrder) {
1823
+ if (first !== void 0) {
1824
+ throw new ValidationError(
1825
+ `${model}.reasons: expected none when can_order is true, got ${JSON.stringify(reasons)}`
1826
+ );
1827
+ }
1828
+ return { type: "orderable" };
1829
+ }
1830
+ if (first === void 0) {
1831
+ throw new ValidationError(
1832
+ `${model}.reasons: expected at least one when can_order is false`
1833
+ );
1834
+ }
1835
+ return { type: "blocked", reasons: [first, ...rest] };
1836
+ }
1837
+
1838
+ // src/universal/api/frontline/providers/centrifuge/centrifuge.ts
1839
+ async function getCentrifugeVaultQuote(api, params) {
1840
+ const dto = await api.send({
1841
+ method: "GET",
1842
+ url: "/v1/centrifuge/vault/quote",
1843
+ queryParams: {
1844
+ symbol: params.symbol,
1845
+ chain: params.chain,
1846
+ amount: params.amount.raw.toString()
1847
+ },
1848
+ attributes: Attributes.protected()
1849
+ });
1850
+ return CentrifugeVaultQuote.fromDto(dto);
1851
+ }
1852
+ async function getCentrifugeVaultStatus(api, params) {
1853
+ const dto = await api.send({
1854
+ method: "GET",
1855
+ url: "/v1/centrifuge/vault/status",
1856
+ queryParams: {
1857
+ symbol: params.symbol,
1858
+ chain: params.chain
1859
+ },
1860
+ attributes: Attributes.protected()
1861
+ });
1862
+ return CentrifugeVaultStatus.fromDto(dto);
1863
+ }
1864
+
1865
+ // src/universal/core/checkout/centrifuge/centrifuge-namespace.ts
1866
+ var CentrifugeNamespaceImpl = class {
1867
+ constructor(ctx) {
1868
+ this.ctx = ctx;
1869
+ this.log = internalLogger(ctx.logger, "CENTRIFUGE");
1870
+ }
1871
+ async getQuote(params) {
1872
+ return this.log.wrap("getQuote", params, async () => {
1873
+ await this.ctx.ensureUserAuthenticated();
1874
+ return getCentrifugeVaultQuote(this.ctx.api, params);
1875
+ });
1876
+ }
1877
+ async getVaultStatus(params) {
1878
+ return this.log.wrap("getVaultStatus", params, async () => {
1879
+ await this.ctx.ensureUserAuthenticated();
1880
+ return getCentrifugeVaultStatus(this.ctx.api, params);
1881
+ });
1882
+ }
1883
+ };
1884
+
1885
+ // src/universal/core/checkout/centrifuge/constants.ts
1886
+ var CENTRIFUGE_POLL_INTERVAL_MS = 15e3;
1887
+
1888
+ // src/universal/types/pagination.ts
1889
+ var Cursor = (value) => value;
1890
+ var PaginatedResponse = {
1891
+ fromDto: (dto, itemMapper) => PaginatedResponse.fromDtoPage(dto, (items) => items.map(itemMapper)),
1892
+ /**
1893
+ * For a mapper that decides the page as a whole - one that drops items it
1894
+ * cannot map, such as `Offer.listFromDto` - rather than item by item. The
1895
+ * cursors are the wire's either way: dropping an item changes what the
1896
+ * page holds, not where the next page starts.
1897
+ */
1898
+ fromDtoPage: (dto, pageMapper) => ({
1899
+ data: pageMapper(dto.data),
1900
+ startingAfter: dto.starting_after ? Cursor(dto.starting_after) : null,
1901
+ startingBefore: dto.starting_before ? Cursor(dto.starting_before) : null
1902
+ })
1903
+ };
1904
+ var PaginationParams = {
1905
+ toQueryParams: (params) => {
1906
+ const queryParams = {};
1907
+ if (params.after) {
1908
+ queryParams.starting_after = params.after;
1909
+ }
1910
+ if (params.before) {
1911
+ queryParams.starting_before = params.before;
1912
+ }
1913
+ if (params.limit) {
1914
+ queryParams.limit = params.limit;
1915
+ }
1916
+ return queryParams;
1917
+ }
1918
+ };
1919
+
1920
+ // src/universal/types/asset.ts
1921
+ var AssetId = (value) => value;
1922
+ var AssetCode = (value) => value;
1923
+ var Asset = {
1924
+ fromDto: (dto) => ({
1925
+ id: AssetId(dto.id),
1926
+ code: AssetCode(dto.code),
1927
+ name: dto.name,
1928
+ fractionalDigits: dto.fractional_digits
1929
+ })
1930
+ };
1931
+
1731
1932
  // src/universal/types/offer.ts
1732
1933
  var OfferId = (value) => value;
1733
1934
  var OfferSlug = (value) => value;
1734
1935
  var OFFER_TYPES = {
1735
1936
  "coinlist::token_sale": true,
1736
1937
  "superstate::swap": true,
1737
- "ondo::swap": true
1938
+ "ondo::swap": true,
1939
+ "centrifuge::vault": true
1738
1940
  };
1739
1941
  var isOfferType = (value) => Object.keys(OFFER_TYPES).includes(value);
1740
1942
  var OfferEditorial = {
@@ -1776,6 +1978,7 @@ var Offer = {
1776
1978
  // on the wire: copying them would hand every consumer a `startsAt` that
1777
1979
  // is 1970 for one variant and a date for the others.
1778
1980
  case "ondo::swap":
1981
+ case "centrifuge::vault":
1779
1982
  return {
1780
1983
  ...base2,
1781
1984
  type: dto.type,
@@ -1828,6 +2031,19 @@ var OfferSwapContract = {
1828
2031
  address: EvmContractAddress(dto.address)
1829
2032
  })
1830
2033
  };
2034
+ var OfferVaultContract = {
2035
+ fromDto: (dto) => ({
2036
+ chain: Chain(dto.chain),
2037
+ address: EvmContractAddress(dto.address)
2038
+ }),
2039
+ /**
2040
+ * Drops every proxy on a chain this SDK does not name, as
2041
+ * `OfferToken.listFromDto` does: frontline publishes the full offer-token
2042
+ * chain list, which runs ahead of {@link Chain}, and one unmodelled chain
2043
+ * should not throw away the proxies the SDK can use.
2044
+ */
2045
+ listFromDto: (dtos) => dtos.filter((dto) => isChain(dto.chain)).map(OfferVaultContract.fromDto)
2046
+ };
1831
2047
  var OfferDetail = {
1832
2048
  fromDto: (dto) => {
1833
2049
  const fundingAssets = requiredArray(
@@ -1890,6 +2106,18 @@ var OfferDetail = {
1890
2106
  "OfferDetail.swap_contracts"
1891
2107
  ).map(OfferSwapContract.fromDto)
1892
2108
  };
2109
+ // No editorial, as for Ondo. `[]` is fine and a missing key is not, for
2110
+ // the same reason as `swap_contracts`: this is the spender a user
2111
+ // approves.
2112
+ case "centrifuge::vault":
2113
+ return {
2114
+ ...base2,
2115
+ type: dto.type,
2116
+ logoUrl: notBlankStringOrNull(dto.logo_url),
2117
+ vaultContracts: OfferVaultContract.listFromDto(
2118
+ requiredArray(dto.vault_contracts, "OfferDetail.vault_contracts")
2119
+ )
2120
+ };
1893
2121
  default:
1894
2122
  return unknownTypeError(dto, "OfferDetail");
1895
2123
  }
@@ -2162,8 +2390,14 @@ function assertPriceFits(raw) {
2162
2390
  }
2163
2391
  }
2164
2392
 
2393
+ // src/universal/core/checkout/ondo/not-tradable.ts
2394
+ var ONDO_NOT_TRADABLE_CODE = "not_tradable";
2395
+ function isOndoNotTradableError(error) {
2396
+ return apiErrorCode(error) === ONDO_NOT_TRADABLE_CODE;
2397
+ }
2398
+
2165
2399
  // src/universal/core/shared/blockchain/formatters.ts
2166
- var import_viem3 = require("viem");
2400
+ var import_viem4 = require("viem");
2167
2401
 
2168
2402
  // src/universal/types/blockchain/ui.ts
2169
2403
  var FormattedAmountUi = (value) => value;
@@ -2234,7 +2468,7 @@ function roundFractionHalfUp(integerPart, fractionPart, maxFractionDigits) {
2234
2468
  };
2235
2469
  }
2236
2470
  function formatRawAmount(amount) {
2237
- return (0, import_viem3.formatUnits)(amount.raw, amount.decimals);
2471
+ return (0, import_viem4.formatUnits)(amount.raw, amount.decimals);
2238
2472
  }
2239
2473
  function formatBpsAsPercent(bps, locale) {
2240
2474
  const whole = bps / 100n;
@@ -2327,66 +2561,6 @@ function explorerBaseUrl(chain) {
2327
2561
  }
2328
2562
  }
2329
2563
 
2330
- // src/universal/core/shared/blockchain/math.ts
2331
- var import_viem4 = require("viem");
2332
- function blockchainAmountFromRawOrThrow({
2333
- label,
2334
- raw,
2335
- decimals
2336
- }) {
2337
- const trimmed = raw.trim();
2338
- if (trimmed === "") {
2339
- throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
2340
- }
2341
- let value;
2342
- try {
2343
- value = BigInt(trimmed);
2344
- } catch {
2345
- throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
2346
- }
2347
- try {
2348
- return BlockchainAmount({ raw: assertUint256(value), decimals });
2349
- } catch {
2350
- throw new ValidationError(`${label}: out of uint256 bounds (${value})`);
2351
- }
2352
- }
2353
- function parseBlockchainAmount(amount, decimals) {
2354
- const trimmed = amount.trim();
2355
- if (trimmed === "") return { valid: false, reason: { type: "empty" } };
2356
- if (trimmed.startsWith("-")) {
2357
- return { valid: false, reason: { type: "negative" } };
2358
- }
2359
- if (/[eE]/.test(trimmed)) {
2360
- return { valid: false, reason: { type: "invalid-format" } };
2361
- }
2362
- if (trimmed === ".") {
2363
- return { valid: false, reason: { type: "invalid-format" } };
2364
- }
2365
- const normalised = trimmed.replace(/^\./, "0.").replace(/\.$/, "");
2366
- if (!/^\d+(\.\d+)?$/.test(normalised)) {
2367
- return { valid: false, reason: { type: "invalid-format" } };
2368
- }
2369
- const [, fraction = ""] = normalised.split(".");
2370
- if (fraction.length > decimals) {
2371
- return {
2372
- valid: false,
2373
- reason: { type: "too-many-decimals", maxDecimals: decimals }
2374
- };
2375
- }
2376
- try {
2377
- const raw = (0, import_viem4.parseUnits)(normalised, decimals);
2378
- if (raw > MAX_UINT_256) {
2379
- return { valid: false, reason: { type: "overflow" } };
2380
- }
2381
- return {
2382
- valid: true,
2383
- amount: BlockchainAmount({ raw, decimals })
2384
- };
2385
- } catch {
2386
- return { valid: false, reason: { type: "invalid-format" } };
2387
- }
2388
- }
2389
-
2390
2564
  // src/universal/types/providers/ondo/ondo.ts
2391
2565
  var OndoTradingStatus = {
2392
2566
  fromDto: (dto) => {
@@ -2402,7 +2576,6 @@ var OndoTradingStatus = {
2402
2576
  };
2403
2577
  }
2404
2578
  };
2405
- var decimalOrNull = (value) => value === null ? null : DecimalString(value);
2406
2579
  var OndoQuote = {
2407
2580
  fromDto: (dto) => {
2408
2581
  const assetDecimals = AssetDecimals(dto.asset_decimals);
@@ -4133,7 +4306,9 @@ var TokenRegistrySnapshot = {
4133
4306
  }
4134
4307
  };
4135
4308
  function offerDisplayTokens(offer) {
4136
- const swaps = offer.tokens.filter((token) => token.role === "swap");
4309
+ const swaps = offer.tokens.filter(
4310
+ (token) => token.role === "swap" || token.role === "vault"
4311
+ );
4137
4312
  const distributions = offer.tokens.filter(
4138
4313
  (token) => token.role === "distribution"
4139
4314
  );
@@ -5257,6 +5432,7 @@ var CoinListClientImpl = class {
5257
5432
  this.wallets
5258
5433
  );
5259
5434
  this.ondo = new ClientOndoNamespaceImpl(ctx, this.erc20);
5435
+ this.centrifuge = new CentrifugeNamespaceImpl(ctx);
5260
5436
  this.tokens = new TokensNamespaceImpl(
5261
5437
  config.tokensBaseUrl ?? NABU_BASE_URL,
5262
5438
  logger
@@ -7115,6 +7291,8 @@ function InfoIcon() {
7115
7291
  var import_jsx_runtime26 = require("react/jsx-runtime");
7116
7292
  var UNSUPPORTED_CHAIN_TITLE = "Not available on this network";
7117
7293
  var UNSUPPORTED_CHAIN_DESCRIPTION = "Ondo orders cannot be placed on the selected network.";
7294
+ var NOT_TRADABLE_TITLE = "Trading is closed right now";
7295
+ var NOT_TRADABLE_DESCRIPTION = "This asset cannot be traded at the moment. Come back when the market opens.";
7118
7296
  function OndoCheckoutError({
7119
7297
  reason,
7120
7298
  className
@@ -7156,6 +7334,8 @@ function title(reason) {
7156
7334
  switch (reason) {
7157
7335
  case "unsupported-chain":
7158
7336
  return UNSUPPORTED_CHAIN_TITLE;
7337
+ case "not-tradable":
7338
+ return NOT_TRADABLE_TITLE;
7159
7339
  default: {
7160
7340
  const exhaustive = reason;
7161
7341
  return exhaustive;
@@ -7166,6 +7346,8 @@ function description(reason) {
7166
7346
  switch (reason) {
7167
7347
  case "unsupported-chain":
7168
7348
  return UNSUPPORTED_CHAIN_DESCRIPTION;
7349
+ case "not-tradable":
7350
+ return NOT_TRADABLE_DESCRIPTION;
7169
7351
  default: {
7170
7352
  const exhaustive = reason;
7171
7353
  return exhaustive;
@@ -8294,7 +8476,9 @@ var import_react15 = require("react");
8294
8476
 
8295
8477
  // src/client/hooks/checkout/ondo/shared/data/ondo-load-error.ts
8296
8478
  function ondoLoadErrorReason(error) {
8297
- return error instanceof NotAuthenticatedError ? "not-authenticated" : "generic-error";
8479
+ if (error instanceof NotAuthenticatedError) return "not-authenticated";
8480
+ if (isOndoNotTradableError(error)) return "not-tradable";
8481
+ return "generic-error";
8298
8482
  }
8299
8483
 
8300
8484
  // src/client/hooks/checkout/ondo/buy/data/useOndoBuyTransaction.ts
@@ -8599,6 +8783,8 @@ function refreshErrorMessage(reason) {
8599
8783
  switch (reason) {
8600
8784
  case "not-authenticated":
8601
8785
  return "Sign in to refresh this quote.";
8786
+ case "not-tradable":
8787
+ return "Trading is paused for this asset. Try again when the market opens.";
8602
8788
  case "generic-error":
8603
8789
  return "Could not refresh the quote.";
8604
8790
  default: {
@@ -8726,6 +8912,9 @@ function quoteSizeFromKey(key) {
8726
8912
 
8727
8913
  // src/client/hooks/checkout/ondo/shared/data/useOndoTradingStatus.ts
8728
8914
  var import_react19 = require("react");
8915
+ function isNotTradable(state) {
8916
+ return state.type === "CONTENT" && state.status.type === "not-tradable";
8917
+ }
8729
8918
  var LOADING2 = { type: "LOADING" };
8730
8919
  function useOndoTradingStatus(options) {
8731
8920
  const {
@@ -8795,6 +8984,30 @@ function useOndoTradingStatus(options) {
8795
8984
  return { state };
8796
8985
  }
8797
8986
 
8987
+ // src/client/hooks/checkout/ondo/shared/ondo-checkout-error.types.ts
8988
+ var OndoCheckoutErrorReason = {
8989
+ /**
8990
+ * Which reason, if any, replaces the whole checkout. `null` means the steps
8991
+ * render.
8992
+ *
8993
+ * `unsupported-chain` wins because it is settled at mount: no market state
8994
+ * can make a chain with no contract tradable. `not-tradable` needs both a
8995
+ * market *known* to be closed and a user still at the start of the flow,
8996
+ * with no order confirmation on screen. Past the first step a pause belongs
8997
+ * to the step it interrupts, and a just-placed order's dialog must not be
8998
+ * hidden by a market that closed after it filled.
8999
+ */
9000
+ of: ({
9001
+ swappableHere,
9002
+ notTradable,
9003
+ atEntry
9004
+ }) => {
9005
+ if (!swappableHere) return "unsupported-chain";
9006
+ if (notTradable && atEntry) return "not-tradable";
9007
+ return null;
9008
+ }
9009
+ };
9010
+
8798
9011
  // src/client/hooks/checkout/ondo/shared/sidebar/useOndoSidebarViewModel.ts
8799
9012
  var MARKET_OPEN = "Market open";
8800
9013
  var MARKET_CLOSED2 = "Market closed";
@@ -9113,18 +9326,19 @@ function useOndoBuyCheckoutViewModel({
9113
9326
  const [orderConfirmed, setOrderConfirmed] = (0, import_react22.useState)(null);
9114
9327
  const swappableHere = swapSpender(offer.swapContracts, chain) !== null;
9115
9328
  const live = enabled && swappableHere;
9116
- const { state: priceState } = useOndoPrice({
9329
+ const { state: tradingStatusState } = useOndoTradingStatus({
9117
9330
  symbol: ondoSymbol,
9118
9331
  side: "buy",
9119
- size: priceSize(step),
9120
9332
  pollIntervalMs: ONDO_POLL_INTERVAL_MS,
9121
9333
  enabled: live
9122
9334
  });
9123
- const { state: tradingStatusState } = useOndoTradingStatus({
9335
+ const notTradable = isNotTradable(tradingStatusState);
9336
+ const { state: priceState } = useOndoPrice({
9124
9337
  symbol: ondoSymbol,
9125
9338
  side: "buy",
9339
+ size: priceSize(step),
9126
9340
  pollIntervalMs: ONDO_POLL_INTERVAL_MS,
9127
- enabled: live
9341
+ enabled: live && !notTradable
9128
9342
  });
9129
9343
  const { state: outputTokenMetadataState } = useCheckoutOfferTokenMetadata({
9130
9344
  offer,
@@ -9202,7 +9416,12 @@ function useOndoBuyCheckoutViewModel({
9202
9416
  priceState,
9203
9417
  tradingStatusState
9204
9418
  });
9205
- const state = !swappableHere ? { type: "error", reason: "unsupported-chain" } : {
9419
+ const errorReason = OndoCheckoutErrorReason.of({
9420
+ swappableHere,
9421
+ notTradable,
9422
+ atEntry: step.type === "wallet" && orderConfirmed === null
9423
+ });
9424
+ const state = errorReason !== null ? { type: "error", reason: errorReason } : {
9206
9425
  type: "content",
9207
9426
  wallet: walletState,
9208
9427
  amount: amountState,
@@ -10659,6 +10878,8 @@ function refreshErrorMessage2(reason) {
10659
10878
  switch (reason) {
10660
10879
  case "not-authenticated":
10661
10880
  return "Sign in to refresh this quote.";
10881
+ case "not-tradable":
10882
+ return "Trading is paused for this asset. Try again when the market opens.";
10662
10883
  case "generic-error":
10663
10884
  return "Could not refresh the quote.";
10664
10885
  default: {
@@ -10712,18 +10933,19 @@ function useOndoSellCheckoutViewModel({
10712
10933
  const [orderConfirmed, setOrderConfirmed] = (0, import_react27.useState)(null);
10713
10934
  const swappableHere = swapSpender(offer.swapContracts, chain) !== null;
10714
10935
  const live = enabled && swappableHere;
10715
- const { state: priceState } = useOndoPrice({
10936
+ const { state: tradingStatusState } = useOndoTradingStatus({
10716
10937
  symbol: ondoSymbol,
10717
10938
  side: "sell",
10718
- size: priceSize2(step),
10719
10939
  pollIntervalMs: ONDO_POLL_INTERVAL_MS,
10720
10940
  enabled: live
10721
10941
  });
10722
- const { state: tradingStatusState } = useOndoTradingStatus({
10942
+ const notTradable = isNotTradable(tradingStatusState);
10943
+ const { state: priceState } = useOndoPrice({
10723
10944
  symbol: ondoSymbol,
10724
10945
  side: "sell",
10946
+ size: priceSize2(step),
10725
10947
  pollIntervalMs: ONDO_POLL_INTERVAL_MS,
10726
- enabled: live
10948
+ enabled: live && !notTradable
10727
10949
  });
10728
10950
  const { state: inputTokenMetadataState } = useCheckoutOfferTokenMetadata({
10729
10951
  offer,
@@ -10801,7 +11023,14 @@ function useOndoSellCheckoutViewModel({
10801
11023
  priceState,
10802
11024
  tradingStatusState
10803
11025
  });
10804
- const state = !swappableHere ? { type: "error", reason: "unsupported-chain" } : {
11026
+ const errorReason = OndoCheckoutErrorReason.of({
11027
+ swappableHere,
11028
+ notTradable,
11029
+ // The step the flow opened on, which for a preselected wallet is the
11030
+ // amount rather than a wallet step it never had.
11031
+ atEntry: step.type === initialStep.type && orderConfirmed === null
11032
+ });
11033
+ const state = errorReason !== null ? { type: "error", reason: errorReason } : {
10805
11034
  type: "content",
10806
11035
  wallet: hasWalletStep ? walletState : null,
10807
11036
  amount: amountState,
@@ -13338,7 +13567,8 @@ function CheckoutContainer({
13338
13567
  className
13339
13568
  }
13340
13569
  ),
13341
- tokenSale: (tokenSaleOffer) => config["coinlist::token_sale"].render(tokenSaleOffer)
13570
+ tokenSale: (tokenSaleOffer) => config["coinlist::token_sale"].render(tokenSaleOffer),
13571
+ centrifugeVault: (vaultOffer) => config["centrifuge::vault"].render(vaultOffer)
13342
13572
  });
13343
13573
  }
13344
13574
  function OndoCheckoutContainer({
@@ -13386,6 +13616,8 @@ function renderOffer(offer, branches) {
13386
13616
  return branches.superstate(offer);
13387
13617
  case "coinlist::token_sale":
13388
13618
  return branches.tokenSale(offer);
13619
+ case "centrifuge::vault":
13620
+ return branches.centrifugeVault(offer);
13389
13621
  default: {
13390
13622
  const exhaustive = offer;
13391
13623
  return exhaustive;
@@ -13987,6 +14219,7 @@ function saleWindow(offer) {
13987
14219
  case "superstate::swap":
13988
14220
  return { tagline: offer.tagline, startsAt: offer.startsAt };
13989
14221
  case "ondo::swap":
14222
+ case "centrifuge::vault":
13990
14223
  return { tagline: null, startsAt: null };
13991
14224
  default: {
13992
14225
  const exhaustive = offer;
@@ -16749,17 +16982,220 @@ function useCompleteOAuth(options) {
16749
16982
  }, [coinlist, log]);
16750
16983
  }
16751
16984
 
16752
- // src/client/hooks/checkout/coin-list/token-sale/data/useParticipations.ts
16985
+ // src/client/hooks/checkout/centrifuge/shared/centrifuge-order-reason.ts
16986
+ var CENTRIFUGE_VAULT_ORDER_REASON_MESSAGES = {
16987
+ vault_unlinked: "This vault is no longer available on this network.",
16988
+ vault_halted: "Investing in this vault is paused.",
16989
+ proxy_not_permissioned: "This vault cannot accept investments right now.",
16990
+ price_unavailable: "A price is not available for this vault right now.",
16991
+ below_minimum: "Enter at least the minimum amount to invest."
16992
+ };
16993
+ var ORDER_REASON_SEVERITY = {
16994
+ vault_unlinked: 0,
16995
+ vault_halted: 1,
16996
+ proxy_not_permissioned: 2,
16997
+ price_unavailable: 3,
16998
+ below_minimum: 4
16999
+ };
17000
+ function centrifugeVaultOrderReasonMessage(reason) {
17001
+ return CENTRIFUGE_VAULT_ORDER_REASON_MESSAGES[reason];
17002
+ }
17003
+ function primaryCentrifugeVaultOrderReason(reasons) {
17004
+ if (reasons.length === 0) return null;
17005
+ return reasons.reduce(
17006
+ (best, reason) => ORDER_REASON_SEVERITY[reason] < ORDER_REASON_SEVERITY[best] ? reason : best
17007
+ );
17008
+ }
17009
+ function centrifugeVaultOrderingMessage(orderability) {
17010
+ if (orderability.type === "orderable") return null;
17011
+ const reason = primaryCentrifugeVaultOrderReason(orderability.reasons);
17012
+ return reason === null ? null : centrifugeVaultOrderReasonMessage(reason);
17013
+ }
17014
+
17015
+ // src/client/hooks/checkout/centrifuge/shared/data/centrifuge-load-error.ts
17016
+ function centrifugeLoadErrorReason(error) {
17017
+ return error instanceof NotAuthenticatedError ? "not-authenticated" : "generic-error";
17018
+ }
17019
+
17020
+ // src/client/hooks/checkout/centrifuge/shared/data/useCentrifugeQuote.ts
16753
17021
  var import_react51 = require("react");
17022
+ var LOADING3 = { type: "LOADING" };
17023
+ function useCentrifugeQuote(options) {
17024
+ const {
17025
+ symbol,
17026
+ chain,
17027
+ amount,
17028
+ pollIntervalMs = CENTRIFUGE_POLL_INTERVAL_MS,
17029
+ data,
17030
+ enabled
17031
+ } = options;
17032
+ const { coinlist, isReady } = useCoinList();
17033
+ const log = useLogger("useCentrifugeQuote");
17034
+ const [state, setState] = (0, import_react51.useState)(
17035
+ () => data === void 0 ? LOADING3 : { type: "CONTENT", quote: data, isRefreshing: false }
17036
+ );
17037
+ const fetchIdRef = (0, import_react51.useRef)(0);
17038
+ const isFetchingRef = (0, import_react51.useRef)(false);
17039
+ const hasQuoteRef = (0, import_react51.useRef)(data !== void 0);
17040
+ (0, import_react51.useEffect)(() => {
17041
+ if (!isReady || !enabled) return;
17042
+ const currentFetchId = ++fetchIdRef.current;
17043
+ isFetchingRef.current = false;
17044
+ const load = async () => {
17045
+ if (isFetchingRef.current) return;
17046
+ isFetchingRef.current = true;
17047
+ setState(
17048
+ (previous) => previous.type === "CONTENT" ? { ...previous, isRefreshing: true } : previous
17049
+ );
17050
+ try {
17051
+ const quote = await coinlist.centrifuge.getQuote({
17052
+ symbol,
17053
+ chain,
17054
+ // Rebuilt from primitives the effect depends on, so an inline
17055
+ // `amount` from the checkout viewmodel does not restart the poll.
17056
+ amount: BlockchainAmount({
17057
+ raw: amount.raw,
17058
+ decimals: amount.decimals
17059
+ })
17060
+ });
17061
+ if (currentFetchId !== fetchIdRef.current) return;
17062
+ log.debug(() => ({
17063
+ msg: "settled",
17064
+ fields: { state: "CONTENT" }
17065
+ }));
17066
+ hasQuoteRef.current = true;
17067
+ setState({ type: "CONTENT", quote, isRefreshing: false });
17068
+ } catch (error) {
17069
+ if (currentFetchId !== fetchIdRef.current) return;
17070
+ const reason = centrifugeLoadErrorReason(error);
17071
+ if (hasQuoteRef.current) {
17072
+ log.warning(
17073
+ () => ({
17074
+ msg: "poll failed; keeping the last quote",
17075
+ fields: { reason }
17076
+ }),
17077
+ error
17078
+ );
17079
+ } else {
17080
+ log.failure(
17081
+ () => ({ msg: "settled", fields: { state: "ERROR", reason } }),
17082
+ error
17083
+ );
17084
+ }
17085
+ setState(
17086
+ (previous) => previous.type === "CONTENT" ? { ...previous, isRefreshing: false } : { type: "ERROR", reason }
17087
+ );
17088
+ } finally {
17089
+ if (currentFetchId === fetchIdRef.current) {
17090
+ isFetchingRef.current = false;
17091
+ }
17092
+ }
17093
+ };
17094
+ load();
17095
+ const interval = setInterval(load, pollIntervalMs);
17096
+ return () => {
17097
+ clearInterval(interval);
17098
+ ++fetchIdRef.current;
17099
+ };
17100
+ }, [
17101
+ coinlist,
17102
+ isReady,
17103
+ enabled,
17104
+ symbol,
17105
+ chain,
17106
+ amount.raw,
17107
+ amount.decimals,
17108
+ pollIntervalMs,
17109
+ log
17110
+ ]);
17111
+ return { state };
17112
+ }
17113
+
17114
+ // src/client/hooks/checkout/centrifuge/shared/data/useCentrifugeVaultStatus.ts
17115
+ var import_react52 = require("react");
17116
+ var LOADING4 = { type: "LOADING" };
17117
+ function useCentrifugeVaultStatus(options) {
17118
+ const {
17119
+ symbol,
17120
+ chain,
17121
+ pollIntervalMs = CENTRIFUGE_POLL_INTERVAL_MS,
17122
+ data,
17123
+ enabled
17124
+ } = options;
17125
+ const { coinlist, isReady } = useCoinList();
17126
+ const log = useLogger("useCentrifugeVaultStatus");
17127
+ const [state, setState] = (0, import_react52.useState)(
17128
+ () => data === void 0 ? LOADING4 : { type: "CONTENT", status: data }
17129
+ );
17130
+ const fetchIdRef = (0, import_react52.useRef)(0);
17131
+ const isFetchingRef = (0, import_react52.useRef)(false);
17132
+ const hasStatusRef = (0, import_react52.useRef)(data !== void 0);
17133
+ (0, import_react52.useEffect)(() => {
17134
+ if (!isReady || !enabled) return;
17135
+ const currentFetchId = ++fetchIdRef.current;
17136
+ isFetchingRef.current = false;
17137
+ const load = async () => {
17138
+ if (isFetchingRef.current) return;
17139
+ isFetchingRef.current = true;
17140
+ try {
17141
+ const status = await coinlist.centrifuge.getVaultStatus({
17142
+ symbol,
17143
+ chain
17144
+ });
17145
+ if (currentFetchId !== fetchIdRef.current) return;
17146
+ log.debug(() => ({
17147
+ msg: "settled",
17148
+ fields: { state: "CONTENT", orderability: status.orderability.type }
17149
+ }));
17150
+ hasStatusRef.current = true;
17151
+ setState({ type: "CONTENT", status });
17152
+ } catch (error) {
17153
+ if (currentFetchId !== fetchIdRef.current) return;
17154
+ const reason = centrifugeLoadErrorReason(error);
17155
+ if (hasStatusRef.current) {
17156
+ log.warning(
17157
+ () => ({
17158
+ msg: "poll failed; keeping the last status",
17159
+ fields: { reason }
17160
+ }),
17161
+ error
17162
+ );
17163
+ } else {
17164
+ log.failure(
17165
+ () => ({ msg: "settled", fields: { state: "ERROR", reason } }),
17166
+ error
17167
+ );
17168
+ }
17169
+ setState(
17170
+ (previous) => previous.type === "CONTENT" ? previous : { type: "ERROR", reason }
17171
+ );
17172
+ } finally {
17173
+ if (currentFetchId === fetchIdRef.current) {
17174
+ isFetchingRef.current = false;
17175
+ }
17176
+ }
17177
+ };
17178
+ load();
17179
+ const interval = setInterval(load, pollIntervalMs);
17180
+ return () => {
17181
+ clearInterval(interval);
17182
+ ++fetchIdRef.current;
17183
+ };
17184
+ }, [coinlist, isReady, enabled, symbol, chain, pollIntervalMs, log]);
17185
+ return { state };
17186
+ }
17187
+
17188
+ // src/client/hooks/checkout/coin-list/token-sale/data/useParticipations.ts
17189
+ var import_react53 = require("react");
16754
17190
  var LOADING_STATE9 = { type: "LOADING" };
16755
17191
  function useParticipations(offerId, options = {}) {
16756
17192
  const { coinlist, isReady } = useCoinList();
16757
17193
  const log = useLogger("useParticipations");
16758
17194
  const { data, enabled = true } = options;
16759
- const [participationsState, setParticipationsState] = (0, import_react51.useState)(
17195
+ const [participationsState, setParticipationsState] = (0, import_react53.useState)(
16760
17196
  data !== void 0 ? { type: "CONTENT", participations: data } : LOADING_STATE9
16761
17197
  );
16762
- (0, import_react51.useEffect)(() => {
17198
+ (0, import_react53.useEffect)(() => {
16763
17199
  let isCancelled = false;
16764
17200
  if (!enabled) {
16765
17201
  return () => {
@@ -16806,16 +17242,16 @@ function useParticipations(offerId, options = {}) {
16806
17242
  }
16807
17243
 
16808
17244
  // src/client/hooks/offers/data/useOfferDetails.ts
16809
- var import_react52 = require("react");
17245
+ var import_react54 = require("react");
16810
17246
  var LOADING_STATE10 = { type: "LOADING" };
16811
17247
  function useOfferDetails(offerId, options = {}) {
16812
17248
  const { coinlist, isReady } = useCoinList();
16813
17249
  const log = useLogger("useOfferDetails");
16814
17250
  const { data, enabled = true } = options;
16815
- const [offerDetailsState, setOfferDetailsState] = (0, import_react52.useState)(
17251
+ const [offerDetailsState, setOfferDetailsState] = (0, import_react54.useState)(
16816
17252
  data !== void 0 ? { type: "CONTENT", offerDetail: data } : LOADING_STATE10
16817
17253
  );
16818
- (0, import_react52.useEffect)(() => {
17254
+ (0, import_react54.useEffect)(() => {
16819
17255
  let isCancelled = false;
16820
17256
  if (!enabled) {
16821
17257
  return () => {
@@ -16893,6 +17329,7 @@ function formatMonthYear(date, locale) {
16893
17329
  }
16894
17330
  // Annotate the CommonJS export names for ESM import in node:
16895
17331
  0 && (module.exports = {
17332
+ CENTRIFUGE_VAULT_ORDER_REASON_MESSAGES,
16896
17333
  ChecklistStatus,
16897
17334
  CheckoutAssetUi,
16898
17335
  CheckoutContainer,
@@ -16934,6 +17371,7 @@ function formatMonthYear(date, locale) {
16934
17371
  OndoBuyOrderConfirmed,
16935
17372
  OndoBuyReviewView,
16936
17373
  OndoCheckoutError,
17374
+ OndoCheckoutErrorReason,
16937
17375
  OndoSellAmountView,
16938
17376
  OndoSellCheckoutContainer,
16939
17377
  OndoSellCheckoutView,
@@ -16962,6 +17400,9 @@ function formatMonthYear(date, locale) {
16962
17400
  USDT_ICON_URL,
16963
17401
  VerificationOverlay,
16964
17402
  authorizeWallet,
17403
+ centrifugeLoadErrorReason,
17404
+ centrifugeVaultOrderReasonMessage,
17405
+ centrifugeVaultOrderingMessage,
16965
17406
  classifyWalletError,
16966
17407
  connectExternalWalletFlow,
16967
17408
  createCoinListClient,
@@ -16973,6 +17414,7 @@ function formatMonthYear(date, locale) {
16973
17414
  formatCountdown,
16974
17415
  formatMonthYear,
16975
17416
  formatSaleCardCountdown,
17417
+ isNotTradable,
16976
17418
  offerAssetIconUrl,
16977
17419
  offerIconUrl,
16978
17420
  offerTokenIdentifier,
@@ -16980,6 +17422,7 @@ function formatMonthYear(date, locale) {
16980
17422
  pinoClientLogger,
16981
17423
  prepareOndoBuy,
16982
17424
  prepareOndoSell,
17425
+ primaryCentrifugeVaultOrderReason,
16983
17426
  quoteIsStale,
16984
17427
  quoteOverAsks,
16985
17428
  stablecoinIconUrl,
@@ -16987,6 +17430,8 @@ function formatMonthYear(date, locale) {
16987
17430
  tokenLogoSrcSet,
16988
17431
  tokenLogoUrl,
16989
17432
  tokenMetadataOf,
17433
+ useCentrifugeQuote,
17434
+ useCentrifugeVaultStatus,
16990
17435
  useCheckoutOfferTokenMetadata,
16991
17436
  useCoinList,
16992
17437
  useCoinListSignInCardViewModel,