@coinlist-co/react 0.12.2-rc.7b430dd → 0.12.2-rc.abd9d38

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-DCW7NQXH.js → chunk-45LAPB7U.js} +52 -19
  2. package/dist/chunk-45LAPB7U.js.map +1 -0
  3. package/dist/{chunk-MOE5S6CE.js → chunk-HDJEDOS4.js} +114 -4
  4. package/dist/chunk-HDJEDOS4.js.map +1 -0
  5. package/dist/{chunk-VH34YC3Q.js → chunk-M7WDZZPX.js} +11 -2
  6. package/dist/chunk-M7WDZZPX.js.map +1 -0
  7. package/dist/client/index.cjs +396 -107
  8. package/dist/client/index.cjs.map +1 -1
  9. package/dist/client/index.d.cts +102 -34
  10. package/dist/client/index.d.ts +102 -34
  11. package/dist/client/index.js +292 -113
  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-BOCS1TbH.d.cts +50 -0
  20. package/dist/time-C7mhO5_a.d.ts +50 -0
  21. package/dist/{token-registry-snapshot-BNBNuDu1.d.ts → token-registry-snapshot-C-Qs3Lgs.d.ts} +1 -1
  22. package/dist/{token-registry-snapshot-CqI6dXM_.d.cts → token-registry-snapshot-CpzLmsc2.d.cts} +1 -1
  23. package/dist/{tokens-namespace-CIWBtgt2.d.cts → tokens-namespace-DrwRi0AQ.d.cts} +64 -1
  24. package/dist/{tokens-namespace-CIWBtgt2.d.ts → tokens-namespace-DrwRi0AQ.d.ts} +64 -1
  25. package/dist/universal/index.cjs +110 -3
  26. package/dist/universal/index.cjs.map +1 -1
  27. package/dist/universal/index.d.cts +43 -5
  28. package/dist/universal/index.d.ts +43 -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-VH34YC3Q.js.map +0 -1
@@ -71,6 +71,7 @@ __export(client_exports, {
71
71
  OndoBuyOrderConfirmed: () => OndoBuyOrderConfirmed,
72
72
  OndoBuyReviewView: () => OndoBuyReviewView,
73
73
  OndoCheckoutError: () => OndoCheckoutError,
74
+ OndoCheckoutErrorReason: () => OndoCheckoutErrorReason,
74
75
  OndoSellAmountView: () => OndoSellAmountView,
75
76
  OndoSellCheckoutContainer: () => OndoSellCheckoutContainer,
76
77
  OndoSellCheckoutView: () => OndoSellCheckoutView,
@@ -110,6 +111,7 @@ __export(client_exports, {
110
111
  formatCountdown: () => formatCountdown,
111
112
  formatMonthYear: () => formatMonthYear,
112
113
  formatSaleCardCountdown: () => formatSaleCardCountdown,
114
+ isNotTradable: () => isNotTradable,
113
115
  offerAssetIconUrl: () => offerAssetIconUrl,
114
116
  offerIconUrl: () => offerIconUrl,
115
117
  offerTokenIdentifier: () => offerTokenIdentifier,
@@ -248,6 +250,30 @@ var VERIFY_IDENTITY_PATH = "/verify-identity";
248
250
  var VERIFY_IDENTITY_ACCREDITATION_PATH = "/verify-identity/accreditation_full";
249
251
  var WALLET_PATH = "/wallet";
250
252
 
253
+ // src/universal/api/internal-access-token-source.ts
254
+ var SentWith = {
255
+ userToken: (token) => ({
256
+ type: "user-token",
257
+ token
258
+ }),
259
+ noUserToken: { type: "no-user-token" }
260
+ };
261
+ var TokenTrigger = {
262
+ beforeRequest: { type: "before-request" },
263
+ after401: (rejected) => ({
264
+ type: "after-401",
265
+ rejected
266
+ })
267
+ };
268
+ function isRejectedToken(token, rejected) {
269
+ switch (rejected.type) {
270
+ case "user-token":
271
+ return rejected.token.value === token.value;
272
+ case "no-user-token":
273
+ return false;
274
+ }
275
+ }
276
+
251
277
  // src/universal/api/http-attributes.ts
252
278
  var empty = {};
253
279
  var concat = (left, right) => ({
@@ -275,6 +301,10 @@ var retryAttempt = (attempt) => ({
275
301
  var renewAttempted = (value) => ({
276
302
  renewAttempted: value
277
303
  });
304
+ var notRetryable = () => ({ retryable: false });
305
+ var sentWith = (token) => ({
306
+ sentWith: token
307
+ });
278
308
  var requestId = (id) => ({ requestId: id });
279
309
  var getRequestId = (attrs) => attrs?.requestId ?? null;
280
310
  var isProtected = (attrs) => attrs?.protected === true;
@@ -282,6 +312,8 @@ var needUserAgent = (attrs) => attrs?.userAgent === true;
282
312
  var isIdempotent = (attrs) => attrs?.idempotencyKey === true;
283
313
  var getRetryAttempt = (attrs) => attrs?.retryAttempt ?? 0;
284
314
  var wasRenewAttempted = (attrs) => attrs?.renewAttempted === true;
315
+ var isRetryable = (attrs) => attrs?.retryable !== false;
316
+ var getSentWith = (attrs) => attrs?.sentWith === void 0 ? SentWith.noUserToken : SentWith.userToken(attrs.sentWith);
285
317
  var getClientCredentials = (attrs) => attrs?.clientCredentials;
286
318
  var Attributes = {
287
319
  empty,
@@ -297,6 +329,10 @@ var Attributes = {
297
329
  getRetryAttempt,
298
330
  renewAttempted,
299
331
  wasRenewAttempted,
332
+ notRetryable,
333
+ isRetryable,
334
+ sentWith,
335
+ getSentWith,
300
336
  clientCredentials,
301
337
  getClientCredentials,
302
338
  requestId,
@@ -684,11 +720,18 @@ var HttpClient = class {
684
720
  );
685
721
  let response = await this.executeRequest(preparedRequest);
686
722
  for (const middleware of this.middleware.afterRequest ?? []) {
723
+ let retried = false;
687
724
  response = await middleware({
688
725
  request: preparedRequest,
689
726
  response,
690
- retry: (nextRequest = preparedRequest) => this.runRequestWithAfterMiddleware(nextRequest)
727
+ retry: (nextRequest = preparedRequest) => {
728
+ retried = true;
729
+ return this.runRequestWithAfterMiddleware(nextRequest);
730
+ }
691
731
  });
732
+ if (retried) {
733
+ return response;
734
+ }
692
735
  }
693
736
  return response;
694
737
  }
@@ -821,23 +864,33 @@ function attachSessionMiddleware(fetchAccessToken) {
821
864
  if (!Attributes.isProtected(request.attributes)) {
822
865
  return request;
823
866
  }
824
- let accessToken = await fetchAccessToken(false);
825
- if (!accessToken) {
826
- const clientCreds = Attributes.getClientCredentials(request.attributes);
827
- if (clientCreds) {
828
- accessToken = clientCreds;
829
- }
867
+ const userToken = await fetchAccessToken(TokenTrigger.beforeRequest);
868
+ if (userToken !== null) {
869
+ return withBearer(
870
+ {
871
+ ...request,
872
+ attributes: Attributes.concat(
873
+ request.attributes ?? Attributes.empty,
874
+ Attributes.sentWith(userToken)
875
+ )
876
+ },
877
+ userToken.value
878
+ );
830
879
  }
831
- if (accessToken === null) {
832
- return request;
880
+ const clientCreds = Attributes.getClientCredentials(request.attributes);
881
+ if (clientCreds) {
882
+ return withBearer(request, clientCreds.value);
883
+ }
884
+ return request;
885
+ };
886
+ }
887
+ function withBearer(request, token) {
888
+ return {
889
+ ...request,
890
+ headers: {
891
+ ...request.headers ?? {},
892
+ Authorization: `Bearer ${token}`
833
893
  }
834
- return {
835
- ...request,
836
- headers: {
837
- ...request.headers ?? {},
838
- Authorization: `Bearer ${accessToken.value}`
839
- }
840
- };
841
894
  };
842
895
  }
843
896
 
@@ -873,7 +926,7 @@ function getRetryDelayMs(attempt) {
873
926
  function createRequestRetryMiddleware(options = {}) {
874
927
  const delayFn = options.delayFn ?? defaultDelay;
875
928
  return async ({ request, response, retry }) => {
876
- if (!isRetryableStatus(response.status)) {
929
+ if (!isRetryableStatus(response.status) || !Attributes.isRetryable(request.attributes)) {
877
930
  return response;
878
931
  }
879
932
  const currentAttempt = Attributes.getRetryAttempt(request.attributes);
@@ -906,7 +959,9 @@ function renewSessionMiddleware(fetchAccessToken) {
906
959
  if (Attributes.wasRenewAttempted(request.attributes)) {
907
960
  return response;
908
961
  }
909
- const newToken = await fetchAccessToken(true);
962
+ const newToken = await fetchAccessToken(
963
+ TokenTrigger.after401(Attributes.getSentWith(request.attributes))
964
+ );
910
965
  if (newToken) {
911
966
  const nextRequest = Request.concatAttributes(
912
967
  request,
@@ -963,6 +1018,196 @@ var ApiClient = class {
963
1018
  }
964
1019
  };
965
1020
 
1021
+ // src/universal/core/auth/session-expired.ts
1022
+ function notifySessionExpired(onSessionExpired, log) {
1023
+ if (onSessionExpired === void 0) {
1024
+ return;
1025
+ }
1026
+ Promise.resolve().then(onSessionExpired).catch(
1027
+ (error) => log.failure(() => ({ msg: "onSessionExpired threw" }), error)
1028
+ );
1029
+ }
1030
+
1031
+ // src/universal/types/time.ts
1032
+ var MAX_EPOCH_MILLIS = 864e13;
1033
+ var EpochMillis = {
1034
+ /**
1035
+ * @throws {@link ValidationError} unless `value` is an integer a `Date` can
1036
+ * represent: at most {@link MAX_EPOCH_MILLIS} either side of the epoch.
1037
+ */
1038
+ of: (value) => {
1039
+ if (!Number.isInteger(value) || Math.abs(value) > MAX_EPOCH_MILLIS) {
1040
+ throw new ValidationError(
1041
+ `EpochMillis must be an integer within \xB1${MAX_EPOCH_MILLIS}, got ${value}`
1042
+ );
1043
+ }
1044
+ return value;
1045
+ },
1046
+ /** The wall clock. Code that needs the time takes a `TimeEff` instead. */
1047
+ now: () => EpochMillis.of(Date.now()),
1048
+ /** @throws {@link ValidationError} for an invalid `Date`. */
1049
+ fromDate: (date) => EpochMillis.of(date.getTime()),
1050
+ /** How long after `from` the instant `to` is; negative if it is before. */
1051
+ elapsed: (from, to) => Millis.of(to - from),
1052
+ plus: (at, duration) => EpochMillis.of(at + duration)
1053
+ };
1054
+ var Millis = {
1055
+ of: (value) => value
1056
+ };
1057
+
1058
+ // src/client/core/auth/client-access-token.ts
1059
+ var CONFIRM_DELAY = Millis.of(1e3);
1060
+ var Generation = {
1061
+ initial: 0,
1062
+ next: (generation) => generation + 1
1063
+ };
1064
+ var ClientAccessToken = class {
1065
+ constructor(env) {
1066
+ this.env = env;
1067
+ this.state = { type: "unknown" };
1068
+ this.hostCall = null;
1069
+ /**
1070
+ * Bumped by {@link clear}. A host call that started before a logout must not
1071
+ * log the user back in when it lands, so every write checks it first. A 401
1072
+ * that arrives after the logout never starts one: `'logged-out'` refuses it.
1073
+ */
1074
+ this.generation = Generation.initial;
1075
+ this.log = internalLogger(env.logger, "AUTH").child({
1076
+ op: "getAccessToken"
1077
+ });
1078
+ }
1079
+ authState() {
1080
+ return this.state.type;
1081
+ }
1082
+ /**
1083
+ * Asks the host for the current token, whatever is cached.
1084
+ *
1085
+ * Never answers from a host call already in flight: one started before a
1086
+ * login (the mount's `init()`, racing the OAuth callback's) would hand back
1087
+ * the answer from before the session cookie existed. It waits for that call
1088
+ * to settle instead, so that call's verdict still lands, then asks afresh.
1089
+ * A logout while it waits still wins.
1090
+ *
1091
+ * @throws whatever the host's `getAccessToken` throws.
1092
+ */
1093
+ async load() {
1094
+ const generation = this.generation;
1095
+ if (this.hostCall !== null) {
1096
+ await this.hostCall.catch(() => null);
1097
+ }
1098
+ await this.ask(SentWith.noUserToken, generation);
1099
+ return this.authState();
1100
+ }
1101
+ /**
1102
+ * The HTTP pipeline's token source: see {@link TokenTrigger}.
1103
+ *
1104
+ * @throws whatever the host's `getAccessToken` throws.
1105
+ */
1106
+ async get(trigger) {
1107
+ const decision = decideToken(this.state, trigger);
1108
+ switch (decision.type) {
1109
+ case "serve":
1110
+ return decision.token;
1111
+ case "ask":
1112
+ return this.ask(decision.rejected, this.generation);
1113
+ }
1114
+ }
1115
+ /** Forgets the token: `auth.logout()`. Never an expiry, so never notifies. */
1116
+ clear() {
1117
+ this.generation = Generation.next(this.generation);
1118
+ this.hostCall = null;
1119
+ this.state = { type: "logged-out" };
1120
+ }
1121
+ /**
1122
+ * A request that carried no user token was not refused for a token, so the
1123
+ * host's first answer stands. One that was is confirmed before it is
1124
+ * believed.
1125
+ */
1126
+ async ask(rejected, generation) {
1127
+ if (generation !== this.generation) {
1128
+ return currentToken(this.state);
1129
+ }
1130
+ const first = await this.callHost();
1131
+ switch (rejected.type) {
1132
+ case "no-user-token":
1133
+ return this.commit(first, generation);
1134
+ case "user-token":
1135
+ return isFresh(first, rejected) ? this.commit(first, generation) : this.confirm(rejected, generation);
1136
+ }
1137
+ }
1138
+ async confirm(rejected, generation) {
1139
+ this.log.warn(() => ({
1140
+ msg: "host returned no fresh token; asking again before signing out"
1141
+ }));
1142
+ await this.env.delay(CONFIRM_DELAY);
1143
+ const second = await this.callHost();
1144
+ return isFresh(second, rejected) ? this.commit(second, generation) : this.expire(generation);
1145
+ }
1146
+ /** The host's `getAccessToken`, joining a call already in flight. */
1147
+ callHost() {
1148
+ if (this.hostCall !== null) {
1149
+ this.log.debug(() => ({ msg: "joined a host call already in flight" }));
1150
+ return this.hostCall;
1151
+ }
1152
+ const call = (async () => this.env.getAccessToken())().finally(() => {
1153
+ if (this.hostCall === call) {
1154
+ this.hostCall = null;
1155
+ }
1156
+ });
1157
+ this.hostCall = call;
1158
+ return call;
1159
+ }
1160
+ commit(token, generation) {
1161
+ if (generation !== this.generation) {
1162
+ return currentToken(this.state);
1163
+ }
1164
+ this.state = token === null ? { type: "logged-out" } : { type: "logged-in", token };
1165
+ return token;
1166
+ }
1167
+ expire(generation) {
1168
+ if (generation !== this.generation) {
1169
+ return null;
1170
+ }
1171
+ const wasLoggedIn = this.state.type === "logged-in";
1172
+ this.state = { type: "logged-out" };
1173
+ if (wasLoggedIn) {
1174
+ this.log.info(() => ({ msg: "session expired" }));
1175
+ notifySessionExpired(this.env.onSessionExpired, this.log);
1176
+ }
1177
+ return null;
1178
+ }
1179
+ };
1180
+ function decideToken(state, trigger) {
1181
+ switch (trigger.type) {
1182
+ case "before-request":
1183
+ return state.type === "unknown" ? { type: "ask", rejected: SentWith.noUserToken } : { type: "serve", token: currentToken(state) };
1184
+ case "after-401":
1185
+ switch (state.type) {
1186
+ // A logout or an expiry verdict: only `load()` may log back in, so a
1187
+ // 401 to a request sent before it must not ask the host again.
1188
+ case "logged-out":
1189
+ return { type: "serve", token: null };
1190
+ // Another request may already have renewed since this one was sent.
1191
+ case "logged-in":
1192
+ return isRejectedToken(state.token, trigger.rejected) ? { type: "ask", rejected: trigger.rejected } : { type: "serve", token: state.token };
1193
+ case "unknown":
1194
+ return { type: "ask", rejected: trigger.rejected };
1195
+ }
1196
+ }
1197
+ }
1198
+ function currentToken(state) {
1199
+ switch (state.type) {
1200
+ case "logged-in":
1201
+ return state.token;
1202
+ case "unknown":
1203
+ case "logged-out":
1204
+ return null;
1205
+ }
1206
+ }
1207
+ function isFresh(token, rejected) {
1208
+ return token !== null && !isRejectedToken(token, rejected);
1209
+ }
1210
+
966
1211
  // src/universal/types/oauth.ts
967
1212
  var AuthorizationCode = (value) => value;
968
1213
  var CodeVerifier = (value) => value;
@@ -1919,6 +2164,12 @@ function assertPriceFits(raw) {
1919
2164
  }
1920
2165
  }
1921
2166
 
2167
+ // src/universal/core/checkout/ondo/not-tradable.ts
2168
+ var ONDO_NOT_TRADABLE_CODE = "not_tradable";
2169
+ function isOndoNotTradableError(error) {
2170
+ return apiErrorCode(error) === ONDO_NOT_TRADABLE_CODE;
2171
+ }
2172
+
1922
2173
  // src/universal/core/shared/blockchain/formatters.ts
1923
2174
  var import_viem3 = require("viem");
1924
2175
 
@@ -1939,7 +2190,11 @@ function formatAmount(amount, locale, options) {
1939
2190
  const decimal = formatRawAmount(amount);
1940
2191
  let [integerPart, fractionPart = ""] = decimal.split(".");
1941
2192
  const maxFractionDigits = options?.maxFractionDigits;
1942
- const minFractionDigits = maxFractionDigits !== void 0 ? Math.min(maxFractionDigits, amount.decimals) : Math.min(2, amount.decimals);
2193
+ const minFractionDigits = Math.min(
2194
+ options?.minFractionDigits ?? (maxFractionDigits !== void 0 ? maxFractionDigits : 2),
2195
+ maxFractionDigits ?? amount.decimals,
2196
+ amount.decimals
2197
+ );
1943
2198
  if (maxFractionDigits !== void 0 && fractionPart.length > maxFractionDigits) {
1944
2199
  ({ integerPart, fractionPart } = roundFractionHalfUp(
1945
2200
  integerPart,
@@ -1947,7 +2202,8 @@ function formatAmount(amount, locale, options) {
1947
2202
  maxFractionDigits
1948
2203
  ));
1949
2204
  }
1950
- const fraction = minFractionDigits === 0 ? "" : fractionPart.padEnd(minFractionDigits, "0");
2205
+ const trimmed = fractionPart.replace(/0+$/, "");
2206
+ const fraction = trimmed.padEnd(minFractionDigits, "0");
1951
2207
  const integerFormatted = BigInt(integerPart).toLocaleString(locale);
1952
2208
  if (minFractionDigits === 0 && fraction === "") {
1953
2209
  return FormattedAmountUi(integerFormatted);
@@ -2008,6 +2264,14 @@ function assetAmount(amount, symbol) {
2008
2264
  return FormattedAmountAssetUi(`${amount} ${symbol}`);
2009
2265
  }
2010
2266
  var NA_AMOUNT_ASSET_UI = FormattedAmountAssetUi("-");
2267
+ var SHARE_MAX_FRACTION_DIGITS = AssetDecimals(6);
2268
+ var SHARE_MIN_FRACTION_DIGITS = AssetDecimals(2);
2269
+ function formatShareAmount(amount, locale) {
2270
+ return formatAmount(amount, locale, {
2271
+ maxFractionDigits: SHARE_MAX_FRACTION_DIGITS,
2272
+ minFractionDigits: SHARE_MIN_FRACTION_DIGITS
2273
+ });
2274
+ }
2011
2275
  var USD_FRACTION_DIGITS = AssetDecimals(2);
2012
2276
  function formattedUsdPrice(amount, locale) {
2013
2277
  if (!amount) return NA_AMOUNT_ASSET_UI;
@@ -4951,37 +5215,46 @@ function transportFor(api, override, chain, logger) {
4951
5215
  return typeof override === "string" ? (0, import_viem8.http)(override) : override;
4952
5216
  }
4953
5217
 
5218
+ // src/universal/core/shared/effects.ts
5219
+ var systemTime = { time: { now: EpochMillis.now } };
5220
+ var systemDelay = {
5221
+ delay: (duration) => new Promise((resolve) => setTimeout(resolve, duration))
5222
+ };
5223
+
4954
5224
  // src/client/core/coinlist-client.ts
4955
5225
  var CoinListClientImpl = class {
4956
- constructor(_config) {
4957
- this._config = _config;
4958
- /** Cached access token: undefined = loading, null = no token, AccessToken = logged in */
4959
- this._accessToken = void 0;
4960
- const logger = _config.logger ?? null;
5226
+ constructor(config) {
5227
+ this.config = config;
5228
+ const logger = config.logger ?? null;
5229
+ const accessToken = new ClientAccessToken({
5230
+ getAccessToken: () => config.getAccessToken(),
5231
+ onSessionExpired: config.onSessionExpired,
5232
+ logger,
5233
+ ...systemDelay
5234
+ });
5235
+ this.accessToken = accessToken;
4961
5236
  this.api = new ApiClient(
4962
5237
  {
4963
- baseUrl: _config.baseUrl || PUBLIC_API_BASE_URL,
5238
+ baseUrl: config.baseUrl || PUBLIC_API_BASE_URL,
4964
5239
  xApiVersion: API_VERSION
4965
5240
  },
4966
- this.fetchAccessToken.bind(this),
5241
+ (trigger) => accessToken.get(trigger),
4967
5242
  logger
4968
5243
  );
4969
5244
  const ctx = {
4970
5245
  api: this.api,
4971
- rpc: publicClients(this.api, _config.rpc, _config.logger ?? null),
5246
+ rpc: publicClients(this.api, config.rpc, config.logger ?? null),
4972
5247
  logger,
4973
5248
  ensureUserAuthenticated: async () => this.ensureAuthenticated()
4974
5249
  };
4975
- this.auth = new ClientAuthNamespaceImpl(_config, {
4976
- getState: () => this.getAuthState(),
4977
- clearAccessToken: () => {
4978
- this._accessToken = null;
4979
- }
5250
+ this.auth = new ClientAuthNamespaceImpl(config, {
5251
+ getState: () => accessToken.authState(),
5252
+ clearAccessToken: () => accessToken.clear()
4980
5253
  });
4981
5254
  this.offers = new OffersNamespaceImpl(ctx);
4982
5255
  this.requirements = new ClientRequirementsNamespaceImpl(
4983
5256
  ctx,
4984
- _config.coinlistBaseUrl
5257
+ config.coinlistBaseUrl
4985
5258
  );
4986
5259
  this.wallets = new WalletsNamespaceImpl(ctx);
4987
5260
  this.erc20 = new Erc20NamespaceImpl(ctx);
@@ -4993,34 +5266,16 @@ var CoinListClientImpl = class {
4993
5266
  );
4994
5267
  this.ondo = new ClientOndoNamespaceImpl(ctx, this.erc20);
4995
5268
  this.tokens = new TokensNamespaceImpl(
4996
- _config.tokensBaseUrl ?? NABU_BASE_URL,
5269
+ config.tokensBaseUrl ?? NABU_BASE_URL,
4997
5270
  logger
4998
5271
  );
4999
5272
  this.support = new ClientSupportNamespaceImpl(logger);
5000
5273
  }
5001
5274
  async init() {
5002
- await this.fetchAccessToken(true);
5003
- return this.getAuthState();
5004
- }
5005
- async fetchAccessToken(refresh) {
5006
- if (!refresh && this._accessToken !== void 0) return this._accessToken;
5007
- try {
5008
- const accessToken = await this._config.getAccessToken();
5009
- this._accessToken = accessToken;
5010
- return accessToken;
5011
- } catch (_) {
5012
- this._accessToken = null;
5013
- return null;
5014
- }
5015
- }
5016
- getAuthState() {
5017
- if (this._accessToken === void 0) {
5018
- return "unknown";
5019
- }
5020
- return this._accessToken !== null ? "logged-in" : "logged-out";
5275
+ return this.accessToken.load();
5021
5276
  }
5022
5277
  ensureAuthenticated() {
5023
- if (this.getAuthState() !== "logged-in") {
5278
+ if (this.accessToken.authState() !== "logged-in") {
5024
5279
  throw new NotAuthenticatedError();
5025
5280
  }
5026
5281
  }
@@ -6299,10 +6554,7 @@ function CheckoutConfirmationDialog({
6299
6554
  }
6300
6555
  )
6301
6556
  ] }),
6302
- header && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
6303
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Divider, {}),
6304
- header
6305
- ] }),
6557
+ header,
6306
6558
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Divider, {}),
6307
6559
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CheckoutDetailList, { rows }),
6308
6560
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-3", children: actions })
@@ -6319,6 +6571,7 @@ function AssetSummaryRow({
6319
6571
  iconSize = 48,
6320
6572
  value,
6321
6573
  caption,
6574
+ wrapIdentity = false,
6322
6575
  className
6323
6576
  }) {
6324
6577
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CoinListStyleScope, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
@@ -6337,7 +6590,8 @@ function AssetSummaryRow({
6337
6590
  {
6338
6591
  className: cn(
6339
6592
  typeClasses.h4,
6340
- "clcosdk:truncate clcosdk:text-text-primary"
6593
+ "clcosdk:text-text-primary",
6594
+ wrapIdentity ? "clcosdk:break-words" : "clcosdk:truncate"
6341
6595
  ),
6342
6596
  children: asset.name
6343
6597
  }
@@ -6347,7 +6601,8 @@ function AssetSummaryRow({
6347
6601
  {
6348
6602
  className: cn(
6349
6603
  typeClasses.subhead,
6350
- "clcosdk:truncate clcosdk:text-text-secondary"
6604
+ "clcosdk:text-text-secondary",
6605
+ wrapIdentity ? "clcosdk:break-words" : "clcosdk:truncate"
6351
6606
  ),
6352
6607
  children: asset.symbol
6353
6608
  }
@@ -6392,7 +6647,7 @@ function AssetSummaryRow({
6392
6647
  // src/client/components/checkout/ondo/buy/confirmation/OndoBuyOrderConfirmed.tsx
6393
6648
  var import_jsx_runtime22 = require("react/jsx-runtime");
6394
6649
  var TITLE2 = "Order confirmed";
6395
- var SHARES_RECEIVED_CAPTION = "shares received";
6650
+ var SHARES_RECEIVED_LABEL = "Shares received";
6396
6651
  var TOTAL_COST_LABEL = "Total cost";
6397
6652
  var PRICE_PER_SHARE_LABEL = "Price per share";
6398
6653
  var DELIVERED_TO_LABEL = "Delivered to";
@@ -6414,14 +6669,7 @@ function OndoBuyOrderConfirmed({
6414
6669
  icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SuccessGlyph, {}),
6415
6670
  title: TITLE2,
6416
6671
  subtitle: subtitle(state.outputAsset.symbol),
6417
- header: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6418
- AssetSummaryRow,
6419
- {
6420
- asset: state.outputAsset,
6421
- value: state.outputAmount,
6422
- caption: SHARES_RECEIVED_CAPTION
6423
- }
6424
- ),
6672
+ header: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(AssetSummaryRow, { asset: state.outputAsset, wrapIdentity: true }),
6425
6673
  rows: detailRows(state),
6426
6674
  actions: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
6427
6675
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ClButton, { variant: "gradient", fullWidth: true, onClick: onClose, children: DONE_LABEL }),
@@ -6434,6 +6682,7 @@ function OndoBuyOrderConfirmed({
6434
6682
  }
6435
6683
  function detailRows(state) {
6436
6684
  return [
6685
+ { label: SHARES_RECEIVED_LABEL, value: state.outputAmount },
6437
6686
  { label: TOTAL_COST_LABEL, value: state.totalCost },
6438
6687
  { label: PRICE_PER_SHARE_LABEL, value: state.pricePerShare },
6439
6688
  { label: DELIVERED_TO_LABEL, value: state.recipientAddress }
@@ -6874,6 +7123,8 @@ function InfoIcon() {
6874
7123
  var import_jsx_runtime26 = require("react/jsx-runtime");
6875
7124
  var UNSUPPORTED_CHAIN_TITLE = "Not available on this network";
6876
7125
  var UNSUPPORTED_CHAIN_DESCRIPTION = "Ondo orders cannot be placed on the selected network.";
7126
+ var NOT_TRADABLE_TITLE = "Trading is closed right now";
7127
+ var NOT_TRADABLE_DESCRIPTION = "This asset cannot be traded at the moment. Come back when the market opens.";
6877
7128
  function OndoCheckoutError({
6878
7129
  reason,
6879
7130
  className
@@ -6915,6 +7166,8 @@ function title(reason) {
6915
7166
  switch (reason) {
6916
7167
  case "unsupported-chain":
6917
7168
  return UNSUPPORTED_CHAIN_TITLE;
7169
+ case "not-tradable":
7170
+ return NOT_TRADABLE_TITLE;
6918
7171
  default: {
6919
7172
  const exhaustive = reason;
6920
7173
  return exhaustive;
@@ -6925,6 +7178,8 @@ function description(reason) {
6925
7178
  switch (reason) {
6926
7179
  case "unsupported-chain":
6927
7180
  return UNSUPPORTED_CHAIN_DESCRIPTION;
7181
+ case "not-tradable":
7182
+ return NOT_TRADABLE_DESCRIPTION;
6928
7183
  default: {
6929
7184
  const exhaustive = reason;
6930
7185
  return exhaustive;
@@ -8053,7 +8308,9 @@ var import_react15 = require("react");
8053
8308
 
8054
8309
  // src/client/hooks/checkout/ondo/shared/data/ondo-load-error.ts
8055
8310
  function ondoLoadErrorReason(error) {
8056
- return error instanceof NotAuthenticatedError ? "not-authenticated" : "generic-error";
8311
+ if (error instanceof NotAuthenticatedError) return "not-authenticated";
8312
+ if (isOndoNotTradableError(error)) return "not-tradable";
8313
+ return "generic-error";
8057
8314
  }
8058
8315
 
8059
8316
  // src/client/hooks/checkout/ondo/buy/data/useOndoBuyTransaction.ts
@@ -8238,7 +8495,7 @@ function useOndoBuyReviewViewModel({
8238
8495
  tokenMetadata: outputTokenMetadata
8239
8496
  }),
8240
8497
  outputAmount: assetAmount(
8241
- formatAmount(built.receiveOutputAmount, locale),
8498
+ formatShareAmount(built.receiveOutputAmount, locale),
8242
8499
  ondoSymbol
8243
8500
  ),
8244
8501
  recipientAddress: shortenAddress(active.wallet.address),
@@ -8358,6 +8615,8 @@ function refreshErrorMessage(reason) {
8358
8615
  switch (reason) {
8359
8616
  case "not-authenticated":
8360
8617
  return "Sign in to refresh this quote.";
8618
+ case "not-tradable":
8619
+ return "Trading is paused for this asset. Try again when the market opens.";
8361
8620
  case "generic-error":
8362
8621
  return "Could not refresh the quote.";
8363
8622
  default: {
@@ -8485,6 +8744,9 @@ function quoteSizeFromKey(key) {
8485
8744
 
8486
8745
  // src/client/hooks/checkout/ondo/shared/data/useOndoTradingStatus.ts
8487
8746
  var import_react19 = require("react");
8747
+ function isNotTradable(state) {
8748
+ return state.type === "CONTENT" && state.status.type === "not-tradable";
8749
+ }
8488
8750
  var LOADING2 = { type: "LOADING" };
8489
8751
  function useOndoTradingStatus(options) {
8490
8752
  const {
@@ -8554,6 +8816,30 @@ function useOndoTradingStatus(options) {
8554
8816
  return { state };
8555
8817
  }
8556
8818
 
8819
+ // src/client/hooks/checkout/ondo/shared/ondo-checkout-error.types.ts
8820
+ var OndoCheckoutErrorReason = {
8821
+ /**
8822
+ * Which reason, if any, replaces the whole checkout. `null` means the steps
8823
+ * render.
8824
+ *
8825
+ * `unsupported-chain` wins because it is settled at mount: no market state
8826
+ * can make a chain with no contract tradable. `not-tradable` needs both a
8827
+ * market *known* to be closed and a user still at the start of the flow,
8828
+ * with no order confirmation on screen. Past the first step a pause belongs
8829
+ * to the step it interrupts, and a just-placed order's dialog must not be
8830
+ * hidden by a market that closed after it filled.
8831
+ */
8832
+ of: ({
8833
+ swappableHere,
8834
+ notTradable,
8835
+ atEntry
8836
+ }) => {
8837
+ if (!swappableHere) return "unsupported-chain";
8838
+ if (notTradable && atEntry) return "not-tradable";
8839
+ return null;
8840
+ }
8841
+ };
8842
+
8557
8843
  // src/client/hooks/checkout/ondo/shared/sidebar/useOndoSidebarViewModel.ts
8558
8844
  var MARKET_OPEN = "Market open";
8559
8845
  var MARKET_CLOSED2 = "Market closed";
@@ -8872,18 +9158,19 @@ function useOndoBuyCheckoutViewModel({
8872
9158
  const [orderConfirmed, setOrderConfirmed] = (0, import_react22.useState)(null);
8873
9159
  const swappableHere = swapSpender(offer.swapContracts, chain) !== null;
8874
9160
  const live = enabled && swappableHere;
8875
- const { state: priceState } = useOndoPrice({
9161
+ const { state: tradingStatusState } = useOndoTradingStatus({
8876
9162
  symbol: ondoSymbol,
8877
9163
  side: "buy",
8878
- size: priceSize(step),
8879
9164
  pollIntervalMs: ONDO_POLL_INTERVAL_MS,
8880
9165
  enabled: live
8881
9166
  });
8882
- const { state: tradingStatusState } = useOndoTradingStatus({
9167
+ const notTradable = isNotTradable(tradingStatusState);
9168
+ const { state: priceState } = useOndoPrice({
8883
9169
  symbol: ondoSymbol,
8884
9170
  side: "buy",
9171
+ size: priceSize(step),
8885
9172
  pollIntervalMs: ONDO_POLL_INTERVAL_MS,
8886
- enabled: live
9173
+ enabled: live && !notTradable
8887
9174
  });
8888
9175
  const { state: outputTokenMetadataState } = useCheckoutOfferTokenMetadata({
8889
9176
  offer,
@@ -8961,7 +9248,12 @@ function useOndoBuyCheckoutViewModel({
8961
9248
  priceState,
8962
9249
  tradingStatusState
8963
9250
  });
8964
- const state = !swappableHere ? { type: "error", reason: "unsupported-chain" } : {
9251
+ const errorReason = OndoCheckoutErrorReason.of({
9252
+ swappableHere,
9253
+ notTradable,
9254
+ atEntry: step.type === "wallet" && orderConfirmed === null
9255
+ });
9256
+ const state = errorReason !== null ? { type: "error", reason: errorReason } : {
8965
9257
  type: "content",
8966
9258
  wallet: walletState,
8967
9259
  amount: amountState,
@@ -9057,7 +9349,7 @@ function toOrderConfirmedUi({
9057
9349
  tokenMetadata: outputTokenMetadata
9058
9350
  }),
9059
9351
  outputAmount: assetAmount(
9060
- formatAmount(order.transaction.receiveOutputAmount, locale),
9352
+ formatShareAmount(order.transaction.receiveOutputAmount, locale),
9061
9353
  ondoSymbol
9062
9354
  ),
9063
9355
  totalCost: assetAmount(
@@ -9309,7 +9601,7 @@ function MaxButton2({
9309
9601
  var import_lucide_react7 = require("lucide-react");
9310
9602
  var import_jsx_runtime36 = require("react/jsx-runtime");
9311
9603
  var TITLE7 = "Order confirmed";
9312
- var SHARES_SOLD_CAPTION = "shares sold";
9604
+ var SHARES_SOLD_LABEL = "Shares sold";
9313
9605
  var RECEIVED_LABEL = "Received";
9314
9606
  var PRICE_PER_SHARE_LABEL3 = "Price per share";
9315
9607
  var DELIVERED_TO_LABEL2 = "Delivered to";
@@ -9332,18 +9624,9 @@ function OndoSellOrderConfirmed({
9332
9624
  title: TITLE7,
9333
9625
  subtitle: subtitle2(state.soldAsset.symbol, state.proceedsSymbol),
9334
9626
  header: (
9335
- // The asset row leads with what was *sold*, where the buy dialog
9336
- // leads with what arrived. The proceeds are a detail row below,
9337
- // because the position that changed is the thing the user is looking
9338
- // for.
9339
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
9340
- AssetSummaryRow,
9341
- {
9342
- asset: state.soldAsset,
9343
- value: state.soldAmount,
9344
- caption: SHARES_SOLD_CAPTION
9345
- }
9346
- )
9627
+ // The header names what was sold. The quantity is a detail row, so a
9628
+ // long fund name and a long share count each get the full width.
9629
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(AssetSummaryRow, { asset: state.soldAsset, wrapIdentity: true })
9347
9630
  ),
9348
9631
  rows: detailRows3(state),
9349
9632
  actions: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
@@ -9357,6 +9640,7 @@ function OndoSellOrderConfirmed({
9357
9640
  }
9358
9641
  function detailRows3(state) {
9359
9642
  return [
9643
+ { label: SHARES_SOLD_LABEL, value: state.soldAmount },
9360
9644
  { label: RECEIVED_LABEL, value: state.proceeds },
9361
9645
  { label: PRICE_PER_SHARE_LABEL3, value: state.pricePerShare },
9362
9646
  { label: DELIVERED_TO_LABEL2, value: state.recipientAddress }
@@ -10426,6 +10710,8 @@ function refreshErrorMessage2(reason) {
10426
10710
  switch (reason) {
10427
10711
  case "not-authenticated":
10428
10712
  return "Sign in to refresh this quote.";
10713
+ case "not-tradable":
10714
+ return "Trading is paused for this asset. Try again when the market opens.";
10429
10715
  case "generic-error":
10430
10716
  return "Could not refresh the quote.";
10431
10717
  default: {
@@ -10479,18 +10765,19 @@ function useOndoSellCheckoutViewModel({
10479
10765
  const [orderConfirmed, setOrderConfirmed] = (0, import_react27.useState)(null);
10480
10766
  const swappableHere = swapSpender(offer.swapContracts, chain) !== null;
10481
10767
  const live = enabled && swappableHere;
10482
- const { state: priceState } = useOndoPrice({
10768
+ const { state: tradingStatusState } = useOndoTradingStatus({
10483
10769
  symbol: ondoSymbol,
10484
10770
  side: "sell",
10485
- size: priceSize2(step),
10486
10771
  pollIntervalMs: ONDO_POLL_INTERVAL_MS,
10487
10772
  enabled: live
10488
10773
  });
10489
- const { state: tradingStatusState } = useOndoTradingStatus({
10774
+ const notTradable = isNotTradable(tradingStatusState);
10775
+ const { state: priceState } = useOndoPrice({
10490
10776
  symbol: ondoSymbol,
10491
10777
  side: "sell",
10778
+ size: priceSize2(step),
10492
10779
  pollIntervalMs: ONDO_POLL_INTERVAL_MS,
10493
- enabled: live
10780
+ enabled: live && !notTradable
10494
10781
  });
10495
10782
  const { state: inputTokenMetadataState } = useCheckoutOfferTokenMetadata({
10496
10783
  offer,
@@ -10568,7 +10855,14 @@ function useOndoSellCheckoutViewModel({
10568
10855
  priceState,
10569
10856
  tradingStatusState
10570
10857
  });
10571
- const state = !swappableHere ? { type: "error", reason: "unsupported-chain" } : {
10858
+ const errorReason = OndoCheckoutErrorReason.of({
10859
+ swappableHere,
10860
+ notTradable,
10861
+ // The step the flow opened on, which for a preselected wallet is the
10862
+ // amount rather than a wallet step it never had.
10863
+ atEntry: step.type === initialStep.type && orderConfirmed === null
10864
+ });
10865
+ const state = errorReason !== null ? { type: "error", reason: errorReason } : {
10572
10866
  type: "content",
10573
10867
  wallet: hasWalletStep ? walletState : null,
10574
10868
  amount: amountState,
@@ -10678,7 +10972,7 @@ function toOrderConfirmedUi2({
10678
10972
  tokenMetadata: inputTokenMetadata
10679
10973
  }),
10680
10974
  soldAmount: assetAmount(
10681
- formatAmount(order.transaction.spendInputAmount, locale),
10975
+ formatShareAmount(order.transaction.spendInputAmount, locale),
10682
10976
  ondoSymbol
10683
10977
  ),
10684
10978
  // The expected proceeds rather than the floor: this dialog reports a sale
@@ -10917,7 +11211,7 @@ var import_lucide_react9 = require("lucide-react");
10917
11211
  var import_jsx_runtime41 = require("react/jsx-runtime");
10918
11212
  var TITLE10 = "Order confirmed";
10919
11213
  var TOTAL_COST_LABEL2 = "Total cost";
10920
- var SHARES_RECEIVED_LABEL = "Shares received";
11214
+ var SHARES_RECEIVED_LABEL2 = "Shares received";
10921
11215
  var SHARES_RECEIVED_ESTIMATED_LABEL = "Shares received (estimated)";
10922
11216
  var PRICE_PER_SHARE_LABEL5 = "Price per share";
10923
11217
  var PRICE_PER_SHARE_ESTIMATED_LABEL = "Price per share (estimated)";
@@ -10940,13 +11234,7 @@ function SuperstateOrderConfirmed({
10940
11234
  icon: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(SuccessGlyph3, {}),
10941
11235
  title: TITLE10,
10942
11236
  subtitle: subtitle3(state.asset.symbol),
10943
- header: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
10944
- AssetSummaryRow,
10945
- {
10946
- asset: state.asset,
10947
- caption: `Issued by ${state.issuer}`
10948
- }
10949
- ),
11237
+ header: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(AssetSummaryRow, { asset: state.asset, wrapIdentity: true }),
10950
11238
  rows: detailRows4(state),
10951
11239
  actions: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
10952
11240
  /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(ClButton, { variant: "gradient", fullWidth: true, onClick: onClose, children: DONE_LABEL3 }),
@@ -10962,7 +11250,7 @@ function detailRows4(state) {
10962
11250
  return [
10963
11251
  { label: TOTAL_COST_LABEL2, value: state.totalCost },
10964
11252
  {
10965
- label: confirmed ? SHARES_RECEIVED_LABEL : SHARES_RECEIVED_ESTIMATED_LABEL,
11253
+ label: confirmed ? SHARES_RECEIVED_LABEL2 : SHARES_RECEIVED_ESTIMATED_LABEL,
10966
11254
  value: state.outputAmount
10967
11255
  },
10968
11256
  {
@@ -13034,7 +13322,6 @@ function toOrderConfirmedUi3({
13034
13322
  networkName: getNetworkName(chain),
13035
13323
  iconUrl: assetIconUrl
13036
13324
  }),
13037
- issuer: SUPERSTATE_ISSUER_NAME,
13038
13325
  outputAmount: assetAmount(
13039
13326
  formatAmount(order.outputAmount, locale),
13040
13327
  order.outputAsset.symbol
@@ -16708,6 +16995,7 @@ function formatMonthYear(date, locale) {
16708
16995
  OndoBuyOrderConfirmed,
16709
16996
  OndoBuyReviewView,
16710
16997
  OndoCheckoutError,
16998
+ OndoCheckoutErrorReason,
16711
16999
  OndoSellAmountView,
16712
17000
  OndoSellCheckoutContainer,
16713
17001
  OndoSellCheckoutView,
@@ -16747,6 +17035,7 @@ function formatMonthYear(date, locale) {
16747
17035
  formatCountdown,
16748
17036
  formatMonthYear,
16749
17037
  formatSaleCardCountdown,
17038
+ isNotTradable,
16750
17039
  offerAssetIconUrl,
16751
17040
  offerIconUrl,
16752
17041
  offerTokenIdentifier,