@coinlist-co/react 0.12.1-rc.f51a0c2 → 0.12.2-rc.0fda52c

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-MOE5S6CE.js → chunk-BNMF2HMW.js} +114 -4
  2. package/dist/chunk-BNMF2HMW.js.map +1 -0
  3. package/dist/{chunk-QIAM2VUU.js → chunk-KRA6EM2L.js} +50 -2
  4. package/dist/chunk-KRA6EM2L.js.map +1 -0
  5. package/dist/{chunk-DCW7NQXH.js → chunk-STAHYDLY.js} +52 -19
  6. package/dist/chunk-STAHYDLY.js.map +1 -0
  7. package/dist/client/index.cjs +1718 -1127
  8. package/dist/client/index.cjs.map +1 -1
  9. package/dist/client/index.d.cts +320 -132
  10. package/dist/client/index.d.ts +320 -132
  11. package/dist/client/index.js +1535 -1094
  12. package/dist/client/index.js.map +1 -1
  13. package/dist/server/index.cjs +442 -80
  14. package/dist/server/index.cjs.map +1 -1
  15. package/dist/server/index.d.cts +65 -41
  16. package/dist/server/index.d.ts +65 -41
  17. package/dist/server/index.js +321 -65
  18. package/dist/server/index.js.map +1 -1
  19. package/dist/time-B5YOQxuh.d.ts +50 -0
  20. package/dist/time-BY3apBpc.d.cts +50 -0
  21. package/dist/{collections-Biy3pQQL.d.cts → token-registry-snapshot-C1NxdBmF.d.ts} +65 -2
  22. package/dist/{collections-JfNDG8Tc.d.ts → token-registry-snapshot-DyjrA32p.d.cts} +65 -2
  23. package/dist/{tokens-namespace-CIWBtgt2.d.cts → tokens-namespace-BJfFeowE.d.cts} +53 -1
  24. package/dist/{tokens-namespace-CIWBtgt2.d.ts → tokens-namespace-BJfFeowE.d.ts} +53 -1
  25. package/dist/universal/index.cjs +150 -3
  26. package/dist/universal/index.cjs.map +1 -1
  27. package/dist/universal/index.d.cts +23 -5
  28. package/dist/universal/index.d.ts +23 -5
  29. package/dist/universal/index.js +16 -2
  30. package/package.json +1 -1
  31. package/dist/chunk-DCW7NQXH.js.map +0 -1
  32. package/dist/chunk-MOE5S6CE.js.map +0 -1
  33. package/dist/chunk-QIAM2VUU.js.map +0 -1
@@ -873,6 +873,19 @@ type HttpRequestAttributes = {
873
873
  /** Zero-based attempt index: 0 = first request, 1 = first retry, etc. */
874
874
  retryAttempt?: number;
875
875
  renewAttempted?: boolean;
876
+ /**
877
+ * `false` opts a request out of `requestRetryMiddleware`. For exchanges
878
+ * that must never be replayed: a refresh token is single-use, so re-sending
879
+ * one whose first attempt reached the server presents a token that has
880
+ * already been rotated away.
881
+ */
882
+ retryable?: boolean;
883
+ /**
884
+ * The user access token `attachSessionMiddleware` put on this request, so
885
+ * that a 401 can say *which* token was refused. Absent when the request
886
+ * went out with no user token.
887
+ */
888
+ sentWith?: OAuthAccessToken;
876
889
  clientCredentials?: ClientCredentialsOAuth;
877
890
  };
878
891
 
@@ -1061,6 +1074,45 @@ interface Config {
1061
1074
  * See {@link RpcConfig}.
1062
1075
  */
1063
1076
  readonly rpc?: RpcConfig;
1077
+ /**
1078
+ * Called when the SDK has **confirmed** that the user's CoinList session is
1079
+ * gone - its refresh token expired or was revoked - so you can clear your
1080
+ * own state and show a sign-in entry point.
1081
+ *
1082
+ * Confirmed, because the backend answers "rotated a moment ago by a
1083
+ * concurrent request" and "dead" identically. A single rejection is only a
1084
+ * suspicion: the SDK acts on it only once the same session is rejected again
1085
+ * after a settle window, so a lost refresh race never signs a user out.
1086
+ *
1087
+ * Each environment reports what it confirmed itself, so it fires in the
1088
+ * one that drove the confirmation:
1089
+ *
1090
+ * - **`CoinListClient`**: fires when the SDK moves from `'logged-in'` to
1091
+ * `'logged-out'` because your `getAccessToken` answered `null` (or the
1092
+ * very token the API just refused) twice, a second apart.
1093
+ * - **`CoinListServer`**: fires when the same process sees a refresh token
1094
+ * rejected twice, 5 to 60 seconds apart, or an expired session that
1095
+ * carries no refresh token. The SDK clears the session from your
1096
+ * `SessionStore` just before. The browser's confirmation, through your
1097
+ * `getAccessToken` endpoint, comes a second after the first rejection, so
1098
+ * it does not reach this verdict: when the browser drives renewal, expect
1099
+ * the `CoinListClient` callback, and this one only if a later request
1100
+ * presents the dead session 5 to 60 seconds on.
1101
+ *
1102
+ * It never fires on `auth.logout()`, on a 5xx, a timeout or a network
1103
+ * failure - those mean the SDK could not find out, not that the session
1104
+ * ended. Per environment it fires at most once per session, within a
1105
+ * 60-second memory: the server remembers a verdict for 60 seconds per
1106
+ * process (per JavaScript module instance, so Next.js middleware and route
1107
+ * handlers count separately). The same dead session presented again after
1108
+ * that, or to another instance, can be reported again, so make your handler
1109
+ * idempotent.
1110
+ *
1111
+ * It is called on the next microtask and not awaited. A rejection is
1112
+ * logged and dropped, so it cannot fail or delay the request that
1113
+ * discovered the expiry. A synchronous handler is written `async () => {}`.
1114
+ */
1115
+ readonly onSessionExpired?: () => Promise<void>;
1064
1116
  }
1065
1117
 
1066
1118
  /**
@@ -3298,4 +3350,4 @@ declare class TokensNamespaceImpl implements TokensNamespace {
3298
3350
  list(chain?: EthereumChain): Promise<TokenMetadata[]>;
3299
3351
  }
3300
3352
 
3301
- export { OndoTradingStatus as $, AuthorizationCode as A, BlockchainAmount as B, CodeVerifier as C, TokenMetadata as D, type Erc20Namespace as E, type OfferType as F, type OndoSwapOfferDetail as G, type CoinListTokenSaleOfferDetail as H, type SuperstateSwapOfferDetail as I, Offer as J, RequirementStatusInfo as K, type Logger as L, type RequirementType as M, type RequirementStatusValue as N, OfferId as O, Participation as P, OfferOptionAddress as Q, type RequirementsNamespace as R, type SuperstateSwapNamespace as S, type TokensNamespace as T, type UniversalNamespaceContext as U, RequirementId as V, type WalletError as W, type KycLevelName as X, DocumentSubmission as Y, type WalletChallengeType as Z, type PinoLoggerOptions as _, EthereumChain as a, type GetTokenBalanceParams as a$, AssetDecimals as a0, type BuildOndoBuyParams as a1, type BuildOndoSellParams as a2, OndoQuote as a3, type OndoQuoteSize as a4, type TokenIdentifier as a5, OfferOptionAddressId as a6, TokenLogo as a7, type DebugEvent as a8, type FrontlineEventId as a9, type Newtype as aA, type AllowWalletParams as aB, AllowWalletResponse as aC, Asset as aD, AssetCode as aE, Blockchain as aF, type BuildOndoSwapParamsCore as aG, Chain as aH, ClientId as aI, CodeChallenge as aJ, type CoinListTokenSaleOffer as aK, ConnectExternalWalletParams as aL, type CreateKycTokenParams as aM, CreateParticipationParams as aN, CreateWalletOwnershipChallengeParams as aO, Cursor as aP, type DocumentFormType as aQ, type DocumentSubmissionStatus as aR, type DocumentType as aS, ETHEREUM_CHAINS as aT, Erc20NamespaceImpl as aU, FaqItem as aV, type GetOndoQuoteParams as aW, type GetOndoTradingStatusParams as aX, type GetSwapAuthorizationParams as aY, type GetSwapPreviewParams as aZ, type GetTokenAllowanceParams as a_, HttpError as aa, type HttpResponse as ab, KycToken as ac, type LogBinding as ad, type LogBindings as ae, type LogCause as af, type LogLevel as ag, type LogScope as ah, type LogValue as ai, type ProductionLogLevel as aj, RedactedWalletError as ak, type RequestId as al, type RpcFailureReason as am, type SafeEvent as an, type SafeFields as ao, type UnredactedFields as ap, OAuthSession as aq, ClientCredentialsOAuth as ar, ClientSecret as as, type Sender as at, PaginationParams as au, PaginatedResponse as av, DecimalString as aw, SwapStatus as ax, type Uint256 as ay, KnownAssetSymbol as az, EvmContractAddress as b, HexEncodedTransactionData as b0, Isin as b1, Iso2CountryCode as b2, Link as b3, type ListOptionAddressesParams as b4, MAX_ASSET_DECIMALS as b5, MAX_UINT_256 as b6, Milestone as b7, OAuthRefreshToken as b8, type OfferBase as b9, SOLANA_CHAINS as bA, STABLE_DECIMALS as bB, SolanaChain as bC, type SubmitDocumentParams as bD, type SuperstateSwapOffer as bE, type SwapContractRef as bF, SwapPreview as bG, TermItem as bH, Ticker as bI, type TokenLogoImage as bJ, TokenLogoUrl as bK, type TokenRole as bL, TokensNamespaceImpl as bM, type Tx as bN, WalletAddress as bO, WalletOwnershipChallenge as bP, type WalletProtocol as bQ, WalletsNamespaceImpl as bR, apiErrorCode as bS, assertUint256 as bT, isChain as bU, isOfferType as bV, parseUint256 as bW, type OfferDetailBase as ba, OfferEditorial as bb, OfferOption as bc, OfferOptionSlug as bd, OfferSlug as be, OfferToken as bf, OffersNamespaceImpl as bg, type OndoQuoteDuration as bh, type OndoSellOutcome as bi, type OndoSwapOffer as bj, PKCEState as bk, type PaginatedResponseDto as bl, ParticipationId as bm, type ParticipationStatus as bn, ParticipationsPaginationParams as bo, PauseFlags as bp, Pii as bq, PiiAddress as br, PiiJurisdiction as bs, type PiiKind as bt, type QueryParamValue as bu, type QueryParamValues as bv, RedirectUri as bw, type RemoveOptionAddressParams as bx, type RequirementActionNeededReason as by, type RpcConfig as bz, type CoinListTokenSaleNamespace as c, OfferOptionId as d, AssetId as e, CoinListTokenSaleNamespaceImpl as f, type OndoNamespace as g, AssetSymbol as h, OfferSwapContract as i, OndoBuyTransaction as j, OndoSellTransaction as k, type OndoSwapTransactionCore as l, type OrderBookSide as m, OndoNamespaceImpl as n, type WalletsNamespace as o, Bps as p, EvmWalletAddress as q, SuperstateSwapNamespaceImpl as r, Requirement as s, RequirementsNamespaceImpl as t, type Config as u, type OAuthAccessToken as v, type OffersNamespace as w, StablecoinSymbol as x, type Erc20Asset as y, OfferDetail as z };
3353
+ export { OndoTradingStatus as $, AuthorizationCode as A, BlockchainAmount as B, CodeVerifier as C, TokenMetadata as D, type Erc20Namespace as E, type OfferType as F, type OndoSwapOfferDetail as G, type CoinListTokenSaleOfferDetail as H, type SuperstateSwapOfferDetail as I, Offer as J, RequirementStatusInfo as K, type Logger as L, type RequirementType as M, type RequirementStatusValue as N, OfferId as O, Participation as P, OfferOptionAddress as Q, type RequirementsNamespace as R, type SuperstateSwapNamespace as S, type TokensNamespace as T, type UniversalNamespaceContext as U, RequirementId as V, type WalletError as W, type KycLevelName as X, DocumentSubmission as Y, type WalletChallengeType as Z, type PinoLoggerOptions as _, EthereumChain as a, type GetTokenBalanceParams as a$, AssetDecimals as a0, type BuildOndoBuyParams as a1, type BuildOndoSellParams as a2, OndoQuote as a3, type OndoQuoteSize as a4, type TokenIdentifier as a5, OfferOptionAddressId as a6, TokenLogo as a7, type DebugEvent as a8, type FrontlineEventId as a9, type Newtype as aA, type AllowWalletParams as aB, AllowWalletResponse as aC, Asset as aD, AssetCode as aE, Blockchain as aF, type BuildOndoSwapParamsCore as aG, Chain as aH, ClientId as aI, CodeChallenge as aJ, type CoinListTokenSaleOffer as aK, ConnectExternalWalletParams as aL, type CreateKycTokenParams as aM, CreateParticipationParams as aN, CreateWalletOwnershipChallengeParams as aO, Cursor as aP, type DocumentFormType as aQ, type DocumentSubmissionStatus as aR, type DocumentType as aS, ETHEREUM_CHAINS as aT, Erc20NamespaceImpl as aU, FaqItem as aV, type GetOndoQuoteParams as aW, type GetOndoTradingStatusParams as aX, type GetSwapAuthorizationParams as aY, type GetSwapPreviewParams as aZ, type GetTokenAllowanceParams as a_, HttpError as aa, type HttpResponse as ab, KycToken as ac, type LogBinding as ad, type LogBindings as ae, type LogCause as af, type LogLevel as ag, type LogScope as ah, type LogValue as ai, type ProductionLogLevel as aj, RedactedWalletError as ak, type RequestId as al, type RpcFailureReason as am, type SafeEvent as an, type SafeFields as ao, type UnredactedFields as ap, OAuthSession as aq, ClientCredentialsOAuth as ar, type Sender as as, PaginationParams as at, PaginatedResponse as au, ClientSecret as av, DecimalString as aw, SwapStatus as ax, type Uint256 as ay, KnownAssetSymbol as az, EvmContractAddress as b, HexEncodedTransactionData as b0, Isin as b1, Iso2CountryCode as b2, Link as b3, type ListOptionAddressesParams as b4, MAX_ASSET_DECIMALS as b5, MAX_UINT_256 as b6, Milestone as b7, OAuthRefreshToken as b8, type OfferBase as b9, SOLANA_CHAINS as bA, STABLE_DECIMALS as bB, SolanaChain as bC, type SubmitDocumentParams as bD, type SuperstateSwapOffer as bE, type SwapContractRef as bF, SwapPreview as bG, TermItem as bH, Ticker as bI, type TokenLogoImage as bJ, TokenLogoUrl as bK, type TokenRole as bL, TokensNamespaceImpl as bM, type Tx as bN, WalletAddress as bO, WalletOwnershipChallenge as bP, type WalletProtocol as bQ, WalletsNamespaceImpl as bR, apiErrorCode as bS, assertUint256 as bT, isChain as bU, isOfferType as bV, parseUint256 as bW, type OfferDetailBase as ba, OfferEditorial as bb, OfferOption as bc, OfferOptionSlug as bd, OfferSlug as be, OfferToken as bf, OffersNamespaceImpl as bg, type OndoQuoteDuration as bh, type OndoSellOutcome as bi, type OndoSwapOffer as bj, PKCEState as bk, type PaginatedResponseDto as bl, ParticipationId as bm, type ParticipationStatus as bn, ParticipationsPaginationParams as bo, PauseFlags as bp, Pii as bq, PiiAddress as br, PiiJurisdiction as bs, type PiiKind as bt, type QueryParamValue as bu, type QueryParamValues as bv, RedirectUri as bw, type RemoveOptionAddressParams as bx, type RequirementActionNeededReason as by, type RpcConfig as bz, type CoinListTokenSaleNamespace as c, OfferOptionId as d, AssetId as e, CoinListTokenSaleNamespaceImpl as f, type OndoNamespace as g, AssetSymbol as h, OfferSwapContract as i, OndoBuyTransaction as j, OndoSellTransaction as k, type OndoSwapTransactionCore as l, type OrderBookSide as m, OndoNamespaceImpl as n, type WalletsNamespace as o, Bps as p, EvmWalletAddress as q, SuperstateSwapNamespaceImpl as r, Requirement as s, RequirementsNamespaceImpl as t, type Config as u, type OAuthAccessToken as v, type OffersNamespace as w, StablecoinSymbol as x, type Erc20Asset as y, OfferDetail as z };
@@ -51,6 +51,7 @@ __export(universal_exports, {
51
51
  DocumentSubmission: () => DocumentSubmission,
52
52
  ERC20_ABI: () => ERC20_ABI,
53
53
  ETHEREUM_CHAINS: () => ETHEREUM_CHAINS,
54
+ EpochMillis: () => EpochMillis,
54
55
  Erc20NamespaceImpl: () => Erc20NamespaceImpl,
55
56
  EthereumChain: () => EthereumChain,
56
57
  EvmContractAddress: () => EvmContractAddress,
@@ -71,6 +72,7 @@ __export(universal_exports, {
71
72
  MAX_UINT_256: () => MAX_UINT_256,
72
73
  MathError: () => MathError,
73
74
  Milestone: () => Milestone,
75
+ Millis: () => Millis,
74
76
  NA_AMOUNT_ASSET_UI: () => NA_AMOUNT_ASSET_UI,
75
77
  NotAuthenticatedError: () => NotAuthenticatedError,
76
78
  NotImplementedError: () => NotImplementedError,
@@ -123,6 +125,7 @@ __export(universal_exports, {
123
125
  SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA: () => SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA,
124
126
  SWAP_LEVEL: () => SWAP_LEVEL,
125
127
  SWAP_POLL_INTERVAL_MS: () => SWAP_POLL_INTERVAL_MS,
128
+ Seconds: () => Seconds,
126
129
  ShortenedWalletAddress: () => ShortenedWalletAddress,
127
130
  SolanaChain: () => SolanaChain,
128
131
  StablecoinSymbol: () => StablecoinSymbol,
@@ -136,6 +139,7 @@ __export(universal_exports, {
136
139
  TokenLogo: () => TokenLogo,
137
140
  TokenLogoUrl: () => TokenLogoUrl,
138
141
  TokenMetadata: () => TokenMetadata,
142
+ TokenRegistrySnapshot: () => TokenRegistrySnapshot,
139
143
  TokensNamespaceImpl: () => TokensNamespaceImpl,
140
144
  TxExplorerUrl: () => TxExplorerUrl,
141
145
  USDC: () => USDC,
@@ -165,14 +169,17 @@ __export(universal_exports, {
165
169
  formatBpsAsPercent: () => formatBpsAsPercent,
166
170
  formatCompactAmount: () => formatCompactAmount,
167
171
  formatRawAmount: () => formatRawAmount,
172
+ formatShareAmount: () => formatShareAmount,
168
173
  formattedPricePerShare: () => formattedPricePerShare,
169
174
  formattedUsdPrice: () => formattedUsdPrice,
170
175
  generatePKCEParams: () => generatePKCEParams,
171
176
  getChainId: () => getChainId,
172
177
  getNetworkName: () => getNetworkName,
173
178
  isChain: () => isChain,
179
+ isExpired: () => isExpired,
174
180
  isOfferType: () => isOfferType,
175
181
  isSwapAvailable: () => isSwapAvailable,
182
+ offerDisplayTokens: () => offerDisplayTokens,
176
183
  ondoQuoteOfferDeadline: () => ondoQuoteOfferDeadline,
177
184
  parseBlockchainAmount: () => parseBlockchainAmount,
178
185
  parseUint256: () => parseUint256,
@@ -185,6 +192,15 @@ __export(universal_exports, {
185
192
  });
186
193
  module.exports = __toCommonJS(universal_exports);
187
194
 
195
+ // src/universal/api/internal-access-token-source.ts
196
+ var SentWith = {
197
+ userToken: (token) => ({
198
+ type: "user-token",
199
+ token
200
+ }),
201
+ noUserToken: { type: "no-user-token" }
202
+ };
203
+
188
204
  // src/universal/api/http-attributes.ts
189
205
  var empty = {};
190
206
  var concat = (left, right) => ({
@@ -212,6 +228,10 @@ var retryAttempt = (attempt) => ({
212
228
  var renewAttempted = (value) => ({
213
229
  renewAttempted: value
214
230
  });
231
+ var notRetryable = () => ({ retryable: false });
232
+ var sentWith = (token) => ({
233
+ sentWith: token
234
+ });
215
235
  var requestId = (id) => ({ requestId: id });
216
236
  var getRequestId = (attrs) => attrs?.requestId ?? null;
217
237
  var isProtected = (attrs) => attrs?.protected === true;
@@ -219,6 +239,8 @@ var needUserAgent = (attrs) => attrs?.userAgent === true;
219
239
  var isIdempotent = (attrs) => attrs?.idempotencyKey === true;
220
240
  var getRetryAttempt = (attrs) => attrs?.retryAttempt ?? 0;
221
241
  var wasRenewAttempted = (attrs) => attrs?.renewAttempted === true;
242
+ var isRetryable = (attrs) => attrs?.retryable !== false;
243
+ var getSentWith = (attrs) => attrs?.sentWith === void 0 ? SentWith.noUserToken : SentWith.userToken(attrs.sentWith);
222
244
  var getClientCredentials = (attrs) => attrs?.clientCredentials;
223
245
  var Attributes = {
224
246
  empty,
@@ -234,6 +256,10 @@ var Attributes = {
234
256
  getRetryAttempt,
235
257
  renewAttempted,
236
258
  wasRenewAttempted,
259
+ notRetryable,
260
+ isRetryable,
261
+ sentWith,
262
+ getSentWith,
237
263
  clientCredentials,
238
264
  getClientCredentials,
239
265
  requestId,
@@ -1263,7 +1289,11 @@ function formatAmount(amount, locale, options) {
1263
1289
  const decimal = formatRawAmount(amount);
1264
1290
  let [integerPart, fractionPart = ""] = decimal.split(".");
1265
1291
  const maxFractionDigits = options?.maxFractionDigits;
1266
- const minFractionDigits = maxFractionDigits !== void 0 ? Math.min(maxFractionDigits, amount.decimals) : Math.min(2, amount.decimals);
1292
+ const minFractionDigits = Math.min(
1293
+ options?.minFractionDigits ?? (maxFractionDigits !== void 0 ? maxFractionDigits : 2),
1294
+ maxFractionDigits ?? amount.decimals,
1295
+ amount.decimals
1296
+ );
1267
1297
  if (maxFractionDigits !== void 0 && fractionPart.length > maxFractionDigits) {
1268
1298
  ({ integerPart, fractionPart } = roundFractionHalfUp(
1269
1299
  integerPart,
@@ -1271,7 +1301,8 @@ function formatAmount(amount, locale, options) {
1271
1301
  maxFractionDigits
1272
1302
  ));
1273
1303
  }
1274
- const fraction = minFractionDigits === 0 ? "" : fractionPart.padEnd(minFractionDigits, "0");
1304
+ const trimmed = fractionPart.replace(/0+$/, "");
1305
+ const fraction = trimmed.padEnd(minFractionDigits, "0");
1275
1306
  const integerFormatted = BigInt(integerPart).toLocaleString(locale);
1276
1307
  if (minFractionDigits === 0 && fraction === "") {
1277
1308
  return FormattedAmountUi(integerFormatted);
@@ -1340,6 +1371,14 @@ function assetAmount(amount, symbol) {
1340
1371
  return FormattedAmountAssetUi(`${amount} ${symbol}`);
1341
1372
  }
1342
1373
  var NA_AMOUNT_ASSET_UI = FormattedAmountAssetUi("-");
1374
+ var SHARE_MAX_FRACTION_DIGITS = AssetDecimals(6);
1375
+ var SHARE_MIN_FRACTION_DIGITS = AssetDecimals(2);
1376
+ function formatShareAmount(amount, locale) {
1377
+ return formatAmount(amount, locale, {
1378
+ maxFractionDigits: SHARE_MAX_FRACTION_DIGITS,
1379
+ minFractionDigits: SHARE_MIN_FRACTION_DIGITS
1380
+ });
1381
+ }
1343
1382
  var USD_FRACTION_DIGITS = AssetDecimals(2);
1344
1383
  function formattedUsdPrice(amount, locale) {
1345
1384
  if (!amount) return NA_AMOUNT_ASSET_UI;
@@ -3276,6 +3315,52 @@ var Erc20NamespaceImpl = class {
3276
3315
  }
3277
3316
  };
3278
3317
 
3318
+ // src/universal/core/tokens/token-registry-snapshot.ts
3319
+ var TokenRegistrySnapshot = {
3320
+ /** Indexes a `tokens.list()` result. `[]` is a valid, empty snapshot. */
3321
+ fromTokens: (tokens) => ({
3322
+ tokens,
3323
+ byKey: new Map(
3324
+ tokens.map((token) => [registryKey(token.identifier), token])
3325
+ )
3326
+ }),
3327
+ /**
3328
+ * The registry's entry for one token, or `null` when it lists none. The
3329
+ * registry is curated, so `null` is an ordinary answer rather than an
3330
+ * error, and callers fall back to their own display defaults.
3331
+ */
3332
+ get: (snapshot, token) => snapshot.byKey.get(registryKey(token)) ?? null,
3333
+ /**
3334
+ * The registry's entry for the token an offer is *about*, or `null` when
3335
+ * it lists none of them.
3336
+ *
3337
+ * Resolution follows {@link offerDisplayTokens}: the token a sale
3338
+ * distributes or a swap hands over, never the funding token the user pays
3339
+ * with. An offer deployed on several chains carries one such token per
3340
+ * chain, and the first the registry knows wins - they are the same asset,
3341
+ * so any listed one answers for the offer.
3342
+ */
3343
+ forOffer: (snapshot, offer) => {
3344
+ for (const token of offerDisplayTokens(offer)) {
3345
+ const metadata = TokenRegistrySnapshot.get(snapshot, token);
3346
+ if (metadata !== null) {
3347
+ return metadata;
3348
+ }
3349
+ }
3350
+ return null;
3351
+ }
3352
+ };
3353
+ function offerDisplayTokens(offer) {
3354
+ const swaps = offer.tokens.filter((token) => token.role === "swap");
3355
+ const distributions = offer.tokens.filter(
3356
+ (token) => token.role === "distribution"
3357
+ );
3358
+ return [...swaps, ...distributions];
3359
+ }
3360
+ function registryKey(token) {
3361
+ return `${token.chain}:${token.address.toLowerCase()}`;
3362
+ }
3363
+
3279
3364
  // src/universal/api/nabu/tokens.ts
3280
3365
  var import_viem5 = require("viem");
3281
3366
 
@@ -3307,11 +3392,18 @@ var HttpClient = class {
3307
3392
  );
3308
3393
  let response = await this.executeRequest(preparedRequest);
3309
3394
  for (const middleware of this.middleware.afterRequest ?? []) {
3395
+ let retried = false;
3310
3396
  response = await middleware({
3311
3397
  request: preparedRequest,
3312
3398
  response,
3313
- retry: (nextRequest = preparedRequest) => this.runRequestWithAfterMiddleware(nextRequest)
3399
+ retry: (nextRequest = preparedRequest) => {
3400
+ retried = true;
3401
+ return this.runRequestWithAfterMiddleware(nextRequest);
3402
+ }
3314
3403
  });
3404
+ if (retried) {
3405
+ return response;
3406
+ }
3315
3407
  }
3316
3408
  return response;
3317
3409
  }
@@ -3801,6 +3893,54 @@ var OAuthSession = {
3801
3893
  }
3802
3894
  };
3803
3895
 
3896
+ // src/universal/types/time.ts
3897
+ var MAX_EPOCH_MILLIS = 864e13;
3898
+ var EpochMillis = {
3899
+ /**
3900
+ * @throws {@link ValidationError} unless `value` is an integer a `Date` can
3901
+ * represent: at most {@link MAX_EPOCH_MILLIS} either side of the epoch.
3902
+ */
3903
+ of: (value) => {
3904
+ if (!Number.isInteger(value) || Math.abs(value) > MAX_EPOCH_MILLIS) {
3905
+ throw new ValidationError(
3906
+ `EpochMillis must be an integer within \xB1${MAX_EPOCH_MILLIS}, got ${value}`
3907
+ );
3908
+ }
3909
+ return value;
3910
+ },
3911
+ /** The wall clock. Code that needs the time takes a `TimeEff` instead. */
3912
+ now: () => EpochMillis.of(Date.now()),
3913
+ /** @throws {@link ValidationError} for an invalid `Date`. */
3914
+ fromDate: (date) => EpochMillis.of(date.getTime()),
3915
+ /** How long after `from` the instant `to` is; negative if it is before. */
3916
+ elapsed: (from, to) => Millis.of(to - from),
3917
+ plus: (at, duration) => EpochMillis.of(at + duration)
3918
+ };
3919
+ var Millis = {
3920
+ of: (value) => value
3921
+ };
3922
+ var Seconds = {
3923
+ /**
3924
+ * @throws {@link ValidationError} unless `value` is a non-negative integer.
3925
+ */
3926
+ of: (value) => {
3927
+ if (!Number.isInteger(value) || value < 0) {
3928
+ throw new ValidationError(
3929
+ `Seconds must be a non-negative integer, got ${value}`
3930
+ );
3931
+ }
3932
+ return value;
3933
+ },
3934
+ toMillis: (value) => Millis.of(value * 1e3)
3935
+ };
3936
+ function isExpired({
3937
+ expiresAt,
3938
+ now,
3939
+ buffer = Millis.of(0)
3940
+ }) {
3941
+ return now >= expiresAt - buffer;
3942
+ }
3943
+
3804
3944
  // src/universal/types/user.ts
3805
3945
  var UserId = (value) => value;
3806
3946
  var UserEmail = (value) => value;
@@ -3843,6 +3983,7 @@ var User = {
3843
3983
  DocumentSubmission,
3844
3984
  ERC20_ABI,
3845
3985
  ETHEREUM_CHAINS,
3986
+ EpochMillis,
3846
3987
  Erc20NamespaceImpl,
3847
3988
  EthereumChain,
3848
3989
  EvmContractAddress,
@@ -3863,6 +4004,7 @@ var User = {
3863
4004
  MAX_UINT_256,
3864
4005
  MathError,
3865
4006
  Milestone,
4007
+ Millis,
3866
4008
  NA_AMOUNT_ASSET_UI,
3867
4009
  NotAuthenticatedError,
3868
4010
  NotImplementedError,
@@ -3915,6 +4057,7 @@ var User = {
3915
4057
  SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA,
3916
4058
  SWAP_LEVEL,
3917
4059
  SWAP_POLL_INTERVAL_MS,
4060
+ Seconds,
3918
4061
  ShortenedWalletAddress,
3919
4062
  SolanaChain,
3920
4063
  StablecoinSymbol,
@@ -3928,6 +4071,7 @@ var User = {
3928
4071
  TokenLogo,
3929
4072
  TokenLogoUrl,
3930
4073
  TokenMetadata,
4074
+ TokenRegistrySnapshot,
3931
4075
  TokensNamespaceImpl,
3932
4076
  TxExplorerUrl,
3933
4077
  USDC,
@@ -3957,14 +4101,17 @@ var User = {
3957
4101
  formatBpsAsPercent,
3958
4102
  formatCompactAmount,
3959
4103
  formatRawAmount,
4104
+ formatShareAmount,
3960
4105
  formattedPricePerShare,
3961
4106
  formattedUsdPrice,
3962
4107
  generatePKCEParams,
3963
4108
  getChainId,
3964
4109
  getNetworkName,
3965
4110
  isChain,
4111
+ isExpired,
3966
4112
  isOfferType,
3967
4113
  isSwapAvailable,
4114
+ offerDisplayTokens,
3968
4115
  ondoQuoteOfferDeadline,
3969
4116
  parseBlockchainAmount,
3970
4117
  parseUint256,