@coinlist-co/react 0.11.0 → 0.11.1-rc.209af8d

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/{chunk-UIIXXLA7.js → chunk-3Z4PLLV7.js} +540 -154
  2. package/dist/chunk-3Z4PLLV7.js.map +1 -0
  3. package/dist/{chunk-B2HCVPCQ.js → chunk-T4ANQVQA.js} +26 -11
  4. package/dist/chunk-T4ANQVQA.js.map +1 -0
  5. package/dist/chunk-YPFS2SAD.js +279 -0
  6. package/dist/chunk-YPFS2SAD.js.map +1 -0
  7. package/dist/client/index.cjs +1364 -475
  8. package/dist/client/index.cjs.map +1 -1
  9. package/dist/client/index.d.cts +217 -212
  10. package/dist/client/index.d.ts +217 -212
  11. package/dist/client/index.js +464 -108
  12. package/dist/client/index.js.map +1 -1
  13. package/dist/collections-B0nu_6q5.d.ts +116 -0
  14. package/dist/collections-DdLA4_GN.d.cts +116 -0
  15. package/dist/{config-B5mwS_2l.d.cts → config-D0r6GyPL.d.cts} +743 -31
  16. package/dist/{config-B5mwS_2l.d.ts → config-D0r6GyPL.d.ts} +743 -31
  17. package/dist/server/index.cjs +822 -222
  18. package/dist/server/index.cjs.map +1 -1
  19. package/dist/server/index.d.cts +81 -4
  20. package/dist/server/index.d.ts +81 -4
  21. package/dist/server/index.js +120 -51
  22. package/dist/server/index.js.map +1 -1
  23. package/dist/shared/index.cjs +543 -137
  24. package/dist/shared/index.cjs.map +1 -1
  25. package/dist/shared/index.d.cts +18 -5
  26. package/dist/shared/index.d.ts +18 -5
  27. package/dist/shared/index.js +8 -2
  28. package/package.json +3 -2
  29. package/dist/chunk-B2HCVPCQ.js.map +0 -1
  30. package/dist/chunk-KDGNDAHA.js +0 -146
  31. package/dist/chunk-KDGNDAHA.js.map +0 -1
  32. package/dist/chunk-UIIXXLA7.js.map +0 -1
  33. package/dist/collections-BhDkYmzV.d.cts +0 -65
  34. package/dist/collections-CZhHoQHr.d.ts +0 -65
@@ -68,6 +68,7 @@ __export(client_exports, {
68
68
  OndoReviewView: () => OndoReviewView,
69
69
  OndoSidebarView: () => OndoSidebarView,
70
70
  OndoWalletSelectView: () => OndoWalletSelectView,
71
+ RedactedWalletError: () => RedactedWalletError,
71
72
  RequirementItem: () => RequirementItem,
72
73
  RequirementItemUi: () => RequirementItemUi,
73
74
  RequirementStatus: () => RequirementStatus,
@@ -100,6 +101,7 @@ __export(client_exports, {
100
101
  formatMonthYear: () => formatMonthYear,
101
102
  offerIconUrl: () => offerIconUrl,
102
103
  ondoLoadErrorReason: () => ondoLoadErrorReason,
104
+ pinoClientLogger: () => pinoClientLogger,
103
105
  prepareOndoSwap: () => prepareOndoSwap,
104
106
  quoteIsStale: () => quoteIsStale,
105
107
  quoteOverAsks: () => quoteOverAsks,
@@ -145,7 +147,7 @@ __export(client_exports, {
145
147
  module.exports = __toCommonJS(client_exports);
146
148
 
147
149
  // src/client/CoinListProvider.tsx
148
- var import_react2 = require("react");
150
+ var import_react3 = require("react");
149
151
 
150
152
  // src/shared/core/utils/crypto.ts
151
153
  async function sha256(data) {
@@ -218,9 +220,6 @@ var COINLIST_BASE_URL = "https://coinlist.co";
218
220
  var OAUTH_PAGE_PATH = "/oauth/authorize";
219
221
  var SUPPORT_NEW_TICKET_URL = "https://support.coinlist.co/support/tickets/new";
220
222
  var VERIFY_IDENTITY_PATH = "/verify-identity";
221
- var VERIFY_IDENTITY_VERIFIED_PATH = "/verify-identity/identity_verified";
222
- var VERIFY_IDENTITY_PROOF_OF_ADDRESS_PATH = "/verify-identity/proof_of_address";
223
- var VERIFY_IDENTITY_SOURCE_OF_FUNDS_PATH = "/verify-identity/source_of_funds";
224
223
  var VERIFY_IDENTITY_ACCREDITATION_PATH = "/verify-identity/accreditation_full";
225
224
  var WALLET_PATH = "/wallet";
226
225
 
@@ -251,6 +250,8 @@ var retryAttempt = (attempt) => ({
251
250
  var renewAttempted = (value) => ({
252
251
  renewAttempted: value
253
252
  });
253
+ var requestId = (id) => ({ requestId: id });
254
+ var getRequestId = (attrs) => attrs?.requestId ?? null;
254
255
  var isProtected = (attrs) => attrs?.protected === true;
255
256
  var needUserAgent = (attrs) => attrs?.userAgent === true;
256
257
  var isIdempotent = (attrs) => attrs?.idempotencyKey === true;
@@ -272,7 +273,9 @@ var Attributes = {
272
273
  renewAttempted,
273
274
  wasRenewAttempted,
274
275
  clientCredentials,
275
- getClientCredentials
276
+ getClientCredentials,
277
+ requestId,
278
+ getRequestId
276
279
  };
277
280
 
278
281
  // src/client/core/api/middleware/user-agent.ts
@@ -306,6 +309,16 @@ var HttpError = class extends Error {
306
309
  this.name = "HttpError";
307
310
  this.response = response;
308
311
  }
312
+ /**
313
+ * Correlates this failure with the `[HTTP]` log lines for the same request,
314
+ * which carry the method, the URL, the duration and every retry. `null` when
315
+ * the response did not come from an {@link HttpClient}.
316
+ *
317
+ * Worth quoting in a bug report: it is what makes a log excerpt readable.
318
+ */
319
+ get requestId() {
320
+ return this.response.requestId ?? null;
321
+ }
309
322
  };
310
323
  function apiErrorCode(error) {
311
324
  if (!(error instanceof HttpError)) return null;
@@ -413,11 +426,185 @@ var Request = {
413
426
  concatAttributes
414
427
  };
415
428
 
429
+ // src/shared/types/errors.ts
430
+ var NotImplementedError = class extends Error {
431
+ constructor(message = "Not implemented yet") {
432
+ super(message);
433
+ this.name = "NotImplementedError";
434
+ }
435
+ };
436
+ var NotAuthenticatedError = class extends Error {
437
+ constructor(message = "The user is not authenticated. Go through the OAuth flow first!") {
438
+ super(message);
439
+ this.name = "NotAuthenticatedError";
440
+ }
441
+ };
442
+ var ValidationError = class extends Error {
443
+ constructor(message) {
444
+ super(message);
445
+ this.name = "ValidationError";
446
+ }
447
+ };
448
+ var InvariantError = class extends Error {
449
+ constructor(message) {
450
+ super(message);
451
+ this.name = "InvariantError";
452
+ }
453
+ };
454
+
455
+ // src/shared/core/observability/log-cause.ts
456
+ function classifyLogCause(error) {
457
+ if (error instanceof HttpError) {
458
+ return httpCause(error);
459
+ }
460
+ if (error instanceof ValidationError) {
461
+ return { type: "validation", message: error.message };
462
+ }
463
+ if (error instanceof InvariantError) {
464
+ return { type: "invariant", message: error.message };
465
+ }
466
+ if (error instanceof NotAuthenticatedError) {
467
+ return { type: "not-authenticated" };
468
+ }
469
+ if (error instanceof NotImplementedError) {
470
+ return { type: "not-implemented" };
471
+ }
472
+ return { type: "generic-error", name: errorName(error) };
473
+ }
474
+ function describeErrorUnredacted(error) {
475
+ if (error instanceof HttpError) {
476
+ return describeHttpErrorRedacted(error);
477
+ }
478
+ if (error instanceof Error) {
479
+ return `${error.name}: ${error.message}`;
480
+ }
481
+ return `thrown non-error: ${stringifyUnredacted(error)}`;
482
+ }
483
+ function stringifyUnredacted(value) {
484
+ if (value === void 0) return "";
485
+ try {
486
+ return JSON.stringify(
487
+ value,
488
+ (_key, item) => typeof item === "bigint" ? `${item}` : item
489
+ ) ?? String(value);
490
+ } catch (_) {
491
+ return "<unserializable>";
492
+ }
493
+ }
494
+ function describeHttpErrorRedacted(error) {
495
+ const code = apiErrorCode(error);
496
+ const status = error.response.status;
497
+ return code === null ? `HttpError ${status}` : `HttpError ${status} (${code})`;
498
+ }
499
+ function errorName(error) {
500
+ return error instanceof Error ? error.name : `non-error ${typeof error}`;
501
+ }
502
+ function httpCause(error) {
503
+ return {
504
+ type: "http",
505
+ requestId: error.requestId,
506
+ status: error.response.status,
507
+ code: apiErrorCode(error),
508
+ eventId: apiErrorEventId(error)
509
+ };
510
+ }
511
+ function apiErrorEventId(error) {
512
+ const body = error.response.body;
513
+ if (typeof body !== "object" || body === null) return null;
514
+ const eventId = body.event_id;
515
+ return typeof eventId === "string" ? eventId : null;
516
+ }
517
+
518
+ // src/shared/core/observability/internal-logger.ts
519
+ function internalLogger(logger, scope) {
520
+ return logger ? scopedLogger(logger, scope, {}) : noopInternalLogger;
521
+ }
522
+ var LEVEL_RANK = {
523
+ none: 0,
524
+ error: 1,
525
+ warn: 2,
526
+ info: 3,
527
+ debug: 4
528
+ };
529
+ function scopedLogger(logger, scope, bindings) {
530
+ const admits = (level) => LEVEL_RANK[logger.level()] >= LEVEL_RANK[level];
531
+ const safe = (event) => ({
532
+ msg: event.msg,
533
+ scope,
534
+ bindings,
535
+ fields: event.fields ?? {},
536
+ ...event.cause === void 0 ? {} : { cause: event.cause }
537
+ });
538
+ const unredacted = (event) => ({
539
+ msg: event.msg,
540
+ scope,
541
+ bindings,
542
+ fields: event.fields ?? {}
543
+ });
544
+ const self = {
545
+ child: (binding) => scopedLogger(logger, scope, { ...bindings, ...binding }),
546
+ debug: (event) => {
547
+ if (admits("debug")) logger.debug(() => unredacted(event()));
548
+ },
549
+ info: (event) => {
550
+ if (admits("info")) logger.info(() => safe(event()));
551
+ },
552
+ warn: (event) => {
553
+ if (admits("warn")) logger.warn(() => safe(event()));
554
+ },
555
+ error: (event) => {
556
+ if (admits("error")) logger.error(() => safe(event()));
557
+ },
558
+ failure: (event, error) => {
559
+ if (admits("debug"))
560
+ logger.debug(() => unredacted(verbatim(event(), error)));
561
+ if (admits("error")) logger.error(() => safe(classified(event(), error)));
562
+ },
563
+ warning: (event, error) => {
564
+ if (admits("debug"))
565
+ logger.debug(() => unredacted(verbatim(event(), error)));
566
+ if (admits("warn")) logger.warn(() => safe(classified(event(), error)));
567
+ },
568
+ wrap: async (op, params, run) => {
569
+ const opLog = self.child({ op });
570
+ opLog.debug(() => ({ msg: "call", fields: { params } }));
571
+ try {
572
+ return await run();
573
+ } catch (error) {
574
+ opLog.failure(() => ({ msg: "call failed" }), error);
575
+ throw error;
576
+ }
577
+ }
578
+ };
579
+ return self;
580
+ }
581
+ function verbatim(event, error) {
582
+ return {
583
+ msg: event.msg,
584
+ fields: { ...event.fields, error: describeErrorUnredacted(error) }
585
+ };
586
+ }
587
+ function classified(event, error) {
588
+ return { ...event, cause: event.cause ?? classifyLogCause(error) };
589
+ }
590
+ var noopInternalLogger = {
591
+ child: () => noopInternalLogger,
592
+ debug: () => void 0,
593
+ info: () => void 0,
594
+ warn: () => void 0,
595
+ error: () => void 0,
596
+ failure: () => void 0,
597
+ warning: () => void 0,
598
+ wrap: (_op, _params, run) => run()
599
+ };
600
+
416
601
  // src/shared/api/http-client.ts
417
602
  var HttpClient = class {
418
- constructor(config, middleware = {}) {
603
+ constructor(config, middleware = {}, logger = null, options = {}) {
419
604
  this.config = config;
420
605
  this.middleware = middleware;
606
+ this.log = internalLogger(logger, "HTTP");
607
+ this.makeRequestId = options.makeRequestId ?? defaultMakeRequestId;
421
608
  }
422
609
  async send(request) {
423
610
  return this.runRequestWithAfterMiddleware(request);
@@ -453,7 +640,13 @@ var HttpClient = class {
453
640
  return {
454
641
  ...request,
455
642
  url,
456
- headers
643
+ headers,
644
+ // Only when absent: a retry or a post-renewal re-send arrives with the
645
+ // first attempt's id already on it, and keeping it is the whole point.
646
+ attributes: Attributes.getRequestId(request.attributes) === null ? Attributes.concat(
647
+ request.attributes ?? Attributes.empty,
648
+ Attributes.requestId(this.makeRequestId())
649
+ ) : request.attributes
457
650
  };
458
651
  }
459
652
  /**
@@ -477,10 +670,89 @@ var HttpClient = class {
477
670
  }
478
671
  return request;
479
672
  }
480
- executeRequest(request) {
481
- return makeRequest(request);
673
+ /**
674
+ * One physical attempt, logged as one line.
675
+ *
676
+ * A non-2xx is a `warn` rather than an `error` because the wire does not
677
+ * know whether it is a failure: the retry middleware may turn a 503 into a
678
+ * success, and the token registry reads a 404 as "not listed". The namespace
679
+ * above decides, and logs the `error` when it does.
680
+ */
681
+ async executeRequest(request) {
682
+ const requestId2 = Attributes.getRequestId(request.attributes);
683
+ const log = requestId2 === null ? this.log : this.log.child({ requestId: requestId2 });
684
+ const attempt = Attributes.getRetryAttempt(request.attributes) + 1;
685
+ const startedAt = Date.now();
686
+ log.debug(() => ({
687
+ msg: "request sent",
688
+ fields: describeRequestUnredacted(request)
689
+ }));
690
+ try {
691
+ const response = await makeRequest(request);
692
+ const elapsed = Date.now() - startedAt;
693
+ const outcome = () => ({
694
+ msg: "request completed",
695
+ fields: {
696
+ ...identifyRequest(request),
697
+ "http.response.status_code": response.status,
698
+ duration_ms: elapsed,
699
+ attempt
700
+ }
701
+ });
702
+ if (response.status >= 200 && response.status < 300) {
703
+ log.info(outcome);
704
+ } else {
705
+ log.warn(outcome);
706
+ }
707
+ log.debug(() => ({
708
+ msg: "response received",
709
+ fields: { body: response.body }
710
+ }));
711
+ return requestId2 === null ? response : { ...response, requestId: requestId2 };
712
+ } catch (error) {
713
+ const elapsed = Date.now() - startedAt;
714
+ log.warning(
715
+ () => ({
716
+ msg: "request threw",
717
+ fields: {
718
+ ...identifyRequest(request),
719
+ duration_ms: elapsed,
720
+ attempt
721
+ }
722
+ }),
723
+ error
724
+ );
725
+ throw error;
726
+ }
482
727
  }
483
728
  };
729
+ function identifyRequest(request) {
730
+ const { host, path } = splitUrl(request.url);
731
+ return {
732
+ "http.request.method": request.method,
733
+ "server.address": host,
734
+ "url.path": path
735
+ };
736
+ }
737
+ function splitUrl(url) {
738
+ try {
739
+ const parsed = new URL(url);
740
+ return { host: parsed.host, path: parsed.pathname };
741
+ } catch (_) {
742
+ return { host: null, path: url };
743
+ }
744
+ }
745
+ function defaultMakeRequestId() {
746
+ return Math.random().toString(36).slice(2, 10).padEnd(8, "0");
747
+ }
748
+ function describeRequestUnredacted(request) {
749
+ return {
750
+ "http.request.method": request.method,
751
+ "url.full": buildUrlWithQueryParams(request.url, request.queryParams),
752
+ headers: request.headers,
753
+ ...request.method === "POST" ? { body: request.body } : {}
754
+ };
755
+ }
484
756
 
485
757
  // src/shared/api/middleware/attach-session-middleware.ts
486
758
  function attachSessionMiddleware(fetchAccessToken) {
@@ -588,18 +860,22 @@ function renewSessionMiddleware(fetchAccessToken) {
588
860
 
589
861
  // src/shared/api/authenticated-api-client.ts
590
862
  var AuthenticatedApiClient = class {
591
- constructor(config, fetchAccessToken, additionalBeforeRequest = []) {
592
- this.httpClient = new HttpClient(config, {
593
- beforeRequest: [
594
- attachSessionMiddleware(fetchAccessToken),
595
- ...additionalBeforeRequest,
596
- idempotencyKeyMiddleware
597
- ],
598
- afterRequest: [
599
- renewSessionMiddleware(fetchAccessToken),
600
- requestRetryMiddleware
601
- ]
602
- });
863
+ constructor(config, fetchAccessToken, additionalBeforeRequest = [], logger = null) {
864
+ this.httpClient = new HttpClient(
865
+ config,
866
+ {
867
+ beforeRequest: [
868
+ attachSessionMiddleware(fetchAccessToken),
869
+ ...additionalBeforeRequest,
870
+ idempotencyKeyMiddleware
871
+ ],
872
+ afterRequest: [
873
+ renewSessionMiddleware(fetchAccessToken),
874
+ requestRetryMiddleware
875
+ ]
876
+ },
877
+ logger
878
+ );
603
879
  }
604
880
  async send(request) {
605
881
  const response = await this.httpClient.send(request);
@@ -613,10 +889,13 @@ var AuthenticatedApiClient = class {
613
889
 
614
890
  // src/client/core/api/api-client.ts
615
891
  var ApiClient = class {
616
- constructor(config, fetchAccessToken) {
617
- this.client = new AuthenticatedApiClient(config, fetchAccessToken, [
618
- userAgentMiddleware
619
- ]);
892
+ constructor(config, fetchAccessToken, logger = null) {
893
+ this.client = new AuthenticatedApiClient(
894
+ config,
895
+ fetchAccessToken,
896
+ [userAgentMiddleware],
897
+ logger
898
+ );
620
899
  }
621
900
  async send(request) {
622
901
  return this.client.send(request);
@@ -653,11 +932,15 @@ var ClientAuthNamespaceImpl = class {
653
932
  constructor(config, session) {
654
933
  this.config = config;
655
934
  this.session = session;
935
+ this.log = internalLogger(config.logger ?? null, "AUTH");
656
936
  }
657
937
  getState() {
658
938
  return this.session.getState();
659
939
  }
660
940
  async startOAuth() {
941
+ return this.log.wrap("startOAuth", void 0, () => this.redirectToOAuth());
942
+ }
943
+ async redirectToOAuth() {
661
944
  const pkceParams = await generatePKCEParams(this.config);
662
945
  sessionStorage.setItem(OAUTH_STATE_KEY, pkceParams.state);
663
946
  sessionStorage.setItem(OAUTH_CODE_VERIFIER_KEY, pkceParams.codeVerifier);
@@ -670,9 +953,37 @@ var ClientAuthNamespaceImpl = class {
670
953
  state: pkceParams.state
671
954
  });
672
955
  const baseUrl = this.config.coinlistBaseUrl ?? COINLIST_BASE_URL;
956
+ this.log.child({ op: "startOAuth" }).info(() => ({ msg: "redirecting to CoinList", fields: { baseUrl } }));
673
957
  window.location.href = `${baseUrl}${OAUTH_PAGE_PATH}?${params.toString()}`;
674
958
  }
959
+ /**
960
+ * Every failure here is silent from the browser's side - a state mismatch
961
+ * and a missing verifier both just leave the user logged out - so the
962
+ * reason is logged rather than left for the host to infer from a callback.
963
+ */
675
964
  completeOAuth() {
965
+ const result = this.readOauthCallback();
966
+ switch (result.type) {
967
+ case "error":
968
+ this.log.child({ op: "completeOAuth" }).error(() => ({
969
+ msg: "oauth callback rejected",
970
+ fields: { reason: result.reason }
971
+ }));
972
+ return result;
973
+ case "ok":
974
+ this.log.child({ op: "completeOAuth" }).info(() => ({ msg: "authorization code received" }));
975
+ return result;
976
+ default: {
977
+ const _exhaustive = result;
978
+ return result;
979
+ }
980
+ }
981
+ }
982
+ logout() {
983
+ this.log.child({ op: "logout" }).info(() => ({ msg: "access token cleared" }));
984
+ this.session.clearAccessToken();
985
+ }
986
+ readOauthCallback() {
676
987
  const params = new URLSearchParams(window.location.search);
677
988
  const coinlistError = params.get("error");
678
989
  if (coinlistError) {
@@ -700,28 +1011,36 @@ var ClientAuthNamespaceImpl = class {
700
1011
  codeVerifier: CodeVerifier(codeVerifierValue)
701
1012
  };
702
1013
  }
703
- logout() {
704
- this.session.clearAccessToken();
705
- }
706
1014
  };
707
1015
 
708
1016
  // src/client/core/blockchain/wallet-error.ts
709
1017
  var import_viem = require("viem");
710
1018
  function classifyWalletError(error, ctx) {
711
- if (error instanceof import_viem.UserRejectedRequestError) {
1019
+ if (causeOf(error, import_viem.UserRejectedRequestError)) {
712
1020
  return { type: "user_rejected" };
713
1021
  }
714
- if (error instanceof import_viem.InsufficientFundsError) {
1022
+ if (causeOf(error, import_viem.InsufficientFundsError)) {
715
1023
  return { type: "insufficient_funds" };
716
1024
  }
717
- if (error instanceof import_viem.ContractFunctionRevertedError) {
718
- return { type: "contract_reverted", reason: error.reason ?? error.message };
1025
+ const reverted = causeOf(error, import_viem.ContractFunctionRevertedError);
1026
+ if (reverted) {
1027
+ return { type: "contract_reverted", reason: revertReason(reverted) };
719
1028
  }
720
- if (error instanceof import_viem.WaitForTransactionReceiptTimeoutError && ctx?.hash) {
1029
+ if (causeOf(error, import_viem.WaitForTransactionReceiptTimeoutError) && ctx?.hash) {
721
1030
  return { type: "timeout", hash: ctx.hash };
722
1031
  }
723
1032
  return { type: "unknown", cause: error };
724
1033
  }
1034
+ function causeOf(error, errorClass) {
1035
+ if (error instanceof errorClass) return error;
1036
+ if (!(error instanceof import_viem.BaseError)) return null;
1037
+ const found = error.walk((cause) => cause instanceof errorClass);
1038
+ return found instanceof errorClass ? found : null;
1039
+ }
1040
+ function revertReason(error) {
1041
+ if (!error.raw || error.raw === "0x") return null;
1042
+ return error.reason ?? error.data?.errorName ?? error.signature ?? null;
1043
+ }
725
1044
 
726
1045
  // src/shared/core/blockchain/erc20/abi.ts
727
1046
  var ERC20_ABI = [
@@ -833,8 +1152,8 @@ async function ensureErc20Allowance({
833
1152
  spender,
834
1153
  onProgress
835
1154
  }) {
836
- const emit = (phase) => onProgress?.(phase);
837
- emit("checking-allowance");
1155
+ const emit2 = (phase) => onProgress?.(phase);
1156
+ emit2("checking-allowance");
838
1157
  let allowance;
839
1158
  try {
840
1159
  allowance = await erc20.getAllowance({
@@ -856,7 +1175,7 @@ async function ensureErc20Allowance({
856
1175
  value: 0n,
857
1176
  pending: "resetting-allowance",
858
1177
  confirming: "confirming-allowance-reset",
859
- emit
1178
+ emit: emit2
860
1179
  });
861
1180
  if (reset.type === "error") return { type: "error", error: reset.error };
862
1181
  }
@@ -868,7 +1187,7 @@ async function ensureErc20Allowance({
868
1187
  value: amount.raw,
869
1188
  pending: "approving",
870
1189
  confirming: "confirming-approval",
871
- emit
1190
+ emit: emit2
872
1191
  });
873
1192
  if (approve.type === "error") {
874
1193
  return { type: "error", error: approve.error };
@@ -887,9 +1206,9 @@ async function submitErc20Approval(args) {
887
1206
  value,
888
1207
  pending,
889
1208
  confirming,
890
- emit
1209
+ emit: emit2
891
1210
  } = args;
892
- emit(pending);
1211
+ emit2(pending);
893
1212
  let hash;
894
1213
  try {
895
1214
  hash = await wallet.writeContract({
@@ -905,7 +1224,7 @@ async function submitErc20Approval(args) {
905
1224
  error: { step: "approval", cause: classifyWalletError(error) }
906
1225
  };
907
1226
  }
908
- emit(confirming);
1227
+ emit2(confirming);
909
1228
  let receipt;
910
1229
  try {
911
1230
  receipt = await wallet.awaitTx(hash, chain);
@@ -937,20 +1256,6 @@ async function fetchAllPages(fetchPage, baseParams) {
937
1256
  return items;
938
1257
  }
939
1258
 
940
- // src/shared/types/errors.ts
941
- var NotAuthenticatedError = class extends Error {
942
- constructor(message = "The user is not authenticated. Go through the OAuth flow first!") {
943
- super(message);
944
- this.name = "NotAuthenticatedError";
945
- }
946
- };
947
- var ValidationError = class extends Error {
948
- constructor(message) {
949
- super(message);
950
- this.name = "ValidationError";
951
- }
952
- };
953
-
954
1259
  // src/shared/types/blockchain/core.ts
955
1260
  var ETHEREUM_CHAINS = {
956
1261
  ethereum_mainnet: true,
@@ -991,11 +1296,14 @@ var STABLE_DECIMALS = AssetDecimals(6);
991
1296
  var DecimalString = (value) => value;
992
1297
  var MAX_UINT_256 = 2n ** 256n - 1n;
993
1298
  var assertUint256 = (value) => {
994
- if (value < 0n || value > MAX_UINT_256) {
995
- throw new Error(`Value out of uint256 bounds: ${value}`);
996
- }
997
- return value;
1299
+ if (isUint256(value)) return value;
1300
+ throw new InvariantError(`Value out of uint256 bounds: ${value}`);
1301
+ };
1302
+ var parseUint256 = (value, label) => {
1303
+ if (isUint256(value)) return value;
1304
+ throw new ValidationError(`${label}: out of uint256 bounds (${value})`);
998
1305
  };
1306
+ var isUint256 = (value) => value >= 0n && value <= MAX_UINT_256;
999
1307
  var BlockchainAmount = Object.assign(
1000
1308
  (value) => value,
1001
1309
  {
@@ -1005,13 +1313,13 @@ var BlockchainAmount = Object.assign(
1005
1313
  );
1006
1314
  function combineAmounts(a, b, op) {
1007
1315
  if (a.decimals !== b.decimals) {
1008
- throw new Error(
1316
+ throw new InvariantError(
1009
1317
  `Cannot combine BlockchainAmounts with different decimals: ${a.decimals} vs ${b.decimals}`
1010
1318
  );
1011
1319
  }
1012
1320
  const raw = op(a.raw, b.raw);
1013
1321
  if (raw < 0n || raw > MAX_UINT_256) {
1014
- throw new Error(`BlockchainAmount out of uint256 bounds: ${raw}`);
1322
+ throw new InvariantError(`BlockchainAmount out of uint256 bounds: ${raw}`);
1015
1323
  }
1016
1324
  return BlockchainAmount({ raw, decimals: a.decimals });
1017
1325
  }
@@ -1082,25 +1390,31 @@ var SwapAuthorization = {
1082
1390
  };
1083
1391
  var SwapPreview = {
1084
1392
  fromDto: (dto) => ({
1085
- inputAmount: assertUint256(BigInt(dto.pay_input_amount)),
1086
- fee: assertUint256(BigInt(dto.fee)),
1087
- outputAmount: assertUint256(BigInt(dto.receive_output_amount))
1393
+ inputAmount: parseUint256(
1394
+ BigInt(dto.pay_input_amount),
1395
+ "SwapPreview.pay_input_amount"
1396
+ ),
1397
+ fee: parseUint256(BigInt(dto.fee), "SwapPreview.fee"),
1398
+ outputAmount: parseUint256(
1399
+ BigInt(dto.receive_output_amount),
1400
+ "SwapPreview.receive_output_amount"
1401
+ )
1088
1402
  })
1089
1403
  };
1090
1404
  var SwapStatus = {
1091
1405
  fromDto: (dto) => ({
1092
- stopped: assertUint256(BigInt(dto.stopped)),
1093
- swapLevel: assertUint256(BigInt(dto.swap_level))
1406
+ stopped: parseUint256(BigInt(dto.stopped), "SwapStatus.stopped"),
1407
+ swapLevel: parseUint256(BigInt(dto.swap_level), "SwapStatus.swap_level")
1094
1408
  })
1095
1409
  };
1096
1410
  var TokenAllowance = {
1097
1411
  fromDto: (dto) => ({
1098
- allowance: assertUint256(BigInt(dto.allowance))
1412
+ allowance: parseUint256(BigInt(dto.allowance), "TokenAllowance.allowance")
1099
1413
  })
1100
1414
  };
1101
1415
  var TokenBalance = {
1102
1416
  fromDto: (dto) => ({
1103
- balance: assertUint256(BigInt(dto.balance))
1417
+ balance: parseUint256(BigInt(dto.balance), "TokenBalance.balance")
1104
1418
  })
1105
1419
  };
1106
1420
  var AllowWalletResponse = {
@@ -1229,14 +1543,19 @@ function toErc20Asset(dto) {
1229
1543
  var Erc20NamespaceImpl = class {
1230
1544
  constructor(ctx) {
1231
1545
  this.ctx = ctx;
1546
+ this.log = internalLogger(ctx.logger, "ERC20");
1232
1547
  }
1233
1548
  async getAllowance(params) {
1234
- await this.ctx.ensureUserAuthenticated();
1235
- return getTokenAllowance(this.ctx.api, params);
1549
+ return this.log.wrap("getAllowance", params, async () => {
1550
+ await this.ctx.ensureUserAuthenticated();
1551
+ return getTokenAllowance(this.ctx.api, params);
1552
+ });
1236
1553
  }
1237
1554
  async getBalance(params) {
1238
- await this.ctx.ensureUserAuthenticated();
1239
- return getTokenBalance(this.ctx.api, params);
1555
+ return this.log.wrap("getBalance", params, async () => {
1556
+ await this.ctx.ensureUserAuthenticated();
1557
+ return getTokenBalance(this.ctx.api, params);
1558
+ });
1240
1559
  }
1241
1560
  };
1242
1561
 
@@ -1420,7 +1739,7 @@ var TOKEN_REGISTRY = {
1420
1739
  case "USDT":
1421
1740
  return USDT;
1422
1741
  default:
1423
- throw new Error(`Unknown asset symbol: ${symbol}`);
1742
+ throw new InvariantError(`Unknown asset symbol: ${symbol}`);
1424
1743
  }
1425
1744
  },
1426
1745
  contractAddress: (symbol, chain) => {
@@ -1430,7 +1749,7 @@ var TOKEN_REGISTRY = {
1430
1749
  case "USDT":
1431
1750
  return USDT_ADDRESSES[chain];
1432
1751
  default:
1433
- throw new Error(`Unknown asset symbol: ${symbol}`);
1752
+ throw new InvariantError(`Unknown asset symbol: ${symbol}`);
1434
1753
  }
1435
1754
  }
1436
1755
  };
@@ -1476,15 +1795,30 @@ var Asset = {
1476
1795
  var OfferId = (value) => value;
1477
1796
  var OfferSlug = (value) => value;
1478
1797
  var Offer = {
1798
+ fromDto: (dto) => {
1799
+ if (!Array.isArray(dto.tokens)) {
1800
+ throw new ValidationError(
1801
+ `Offer.tokens: expected an array, got ${typeof dto.tokens}`
1802
+ );
1803
+ }
1804
+ return {
1805
+ id: OfferId(dto.id),
1806
+ slug: OfferSlug(dto.slug),
1807
+ type: dto.type,
1808
+ tagline: dto.tagline,
1809
+ bannerUrl: dto.banner_url,
1810
+ logoUrl: dto.logo_url,
1811
+ startsAt: new Date(dto.starts_at),
1812
+ endsAt: dto.ends_at ? new Date(dto.ends_at) : null,
1813
+ tokens: dto.tokens.map(OfferToken.fromDto)
1814
+ };
1815
+ }
1816
+ };
1817
+ var OfferToken = {
1479
1818
  fromDto: (dto) => ({
1480
- id: OfferId(dto.id),
1481
- slug: OfferSlug(dto.slug),
1482
- type: dto.type,
1483
- tagline: dto.tagline,
1484
- bannerUrl: dto.banner_url,
1485
- logoUrl: dto.logo_url,
1486
- startsAt: new Date(dto.starts_at),
1487
- endsAt: dto.ends_at ? new Date(dto.ends_at) : null
1819
+ role: dto.role,
1820
+ chain: Chain(dto.chain),
1821
+ address: EvmContractAddress(dto.address)
1488
1822
  })
1489
1823
  };
1490
1824
 
@@ -1494,25 +1828,39 @@ var OfferOptionSlug = (value) => value;
1494
1828
  var OfferDetail = {
1495
1829
  fromDto: (dto) => {
1496
1830
  if (!Array.isArray(dto.funding_assets)) {
1497
- throw new Error(`funding_assets must be an array`);
1831
+ throw new ValidationError(
1832
+ `OfferDetail.funding_assets: expected an array, got ${typeof dto.funding_assets}`
1833
+ );
1498
1834
  }
1499
1835
  if (!Array.isArray(dto.options)) {
1500
- throw new Error(`options must be an array`);
1836
+ throw new ValidationError(
1837
+ `OfferDetail.options: expected an array, got ${typeof dto.options}`
1838
+ );
1501
1839
  }
1502
1840
  if (!Array.isArray(dto.terms)) {
1503
- throw new Error(`terms must be an array`);
1841
+ throw new ValidationError(
1842
+ `OfferDetail.terms: expected an array, got ${typeof dto.terms}`
1843
+ );
1504
1844
  }
1505
1845
  if (!Array.isArray(dto.links)) {
1506
- throw new Error(`links must be an array`);
1846
+ throw new ValidationError(
1847
+ `OfferDetail.links: expected an array, got ${typeof dto.links}`
1848
+ );
1507
1849
  }
1508
1850
  if (!Array.isArray(dto.faqs)) {
1509
- throw new Error(`faqs must be an array`);
1851
+ throw new ValidationError(
1852
+ `OfferDetail.faqs: expected an array, got ${typeof dto.faqs}`
1853
+ );
1510
1854
  }
1511
1855
  if (!Array.isArray(dto.milestones)) {
1512
- throw new Error(`milestones must be an array`);
1856
+ throw new ValidationError(
1857
+ `OfferDetail.milestones: expected an array, got ${typeof dto.milestones}`
1858
+ );
1513
1859
  }
1514
1860
  if (!Array.isArray(dto.tokens)) {
1515
- throw new Error(`tokens must be an array`);
1861
+ throw new ValidationError(
1862
+ `OfferDetail.tokens: expected an array, got ${typeof dto.tokens}`
1863
+ );
1516
1864
  }
1517
1865
  return {
1518
1866
  id: OfferId(dto.id),
@@ -1574,13 +1922,6 @@ var Milestone = {
1574
1922
  status: dto.status
1575
1923
  })
1576
1924
  };
1577
- var OfferToken = {
1578
- fromDto: (dto) => ({
1579
- role: dto.role,
1580
- chain: Chain(dto.chain),
1581
- address: EvmContractAddress(dto.address)
1582
- })
1583
- };
1584
1925
 
1585
1926
  // src/shared/types/providers/coin-list/token-sale.ts
1586
1927
  var ParticipationId = (value) => value;
@@ -1667,29 +2008,38 @@ async function createParticipation(api, params) {
1667
2008
  var CoinListTokenSaleNamespaceImpl = class {
1668
2009
  constructor(ctx) {
1669
2010
  this.ctx = ctx;
2011
+ this.log = internalLogger(ctx.logger, "TOKEN_SALE");
1670
2012
  }
1671
2013
  async list(offerId) {
1672
- await this.ctx.ensureUserAuthenticated();
1673
- return fetchParticipations(this.ctx.api, offerId);
2014
+ return this.log.wrap("list", offerId, async () => {
2015
+ await this.ctx.ensureUserAuthenticated();
2016
+ return fetchParticipations(this.ctx.api, offerId);
2017
+ });
1674
2018
  }
1675
2019
  async listPage(params) {
1676
- await this.ctx.ensureUserAuthenticated();
1677
- return fetchParticipationsPage(this.ctx.api, params);
2020
+ return this.log.wrap("listPage", params, async () => {
2021
+ await this.ctx.ensureUserAuthenticated();
2022
+ return fetchParticipationsPage(this.ctx.api, params);
2023
+ });
1678
2024
  }
1679
2025
  async get(id) {
1680
- await this.ctx.ensureUserAuthenticated();
1681
- return fetchParticipation(this.ctx.api, id);
2026
+ return this.log.wrap("get", id, async () => {
2027
+ await this.ctx.ensureUserAuthenticated();
2028
+ return fetchParticipation(this.ctx.api, id);
2029
+ });
1682
2030
  }
1683
2031
  async createParticipation(params) {
1684
- await this.ctx.ensureUserAuthenticated();
1685
- return createParticipation(this.ctx.api, params);
2032
+ return this.log.wrap("createParticipation", params, async () => {
2033
+ await this.ctx.ensureUserAuthenticated();
2034
+ return createParticipation(this.ctx.api, params);
2035
+ });
1686
2036
  }
1687
2037
  };
1688
2038
 
1689
2039
  // src/shared/core/checkout/ondo/constants.ts
1690
2040
  var ONDO_SWAP_CONTRACT_ADDRESSES = {
1691
2041
  ethereum_sepolia: EvmContractAddress(
1692
- "0xFF9c5Ade32d9B4102469Bd5F3817CB0061b25feC"
2042
+ "0x7014019ed51Edab984a71D30F2707D2dB2316A7A"
1693
2043
  )
1694
2044
  };
1695
2045
  function ondoSwapContractAddress(chain) {
@@ -1888,18 +2238,25 @@ function sizeParam(params) {
1888
2238
  var OndoNamespaceImpl = class {
1889
2239
  constructor(ctx) {
1890
2240
  this.ctx = ctx;
2241
+ this.log = internalLogger(ctx.logger, "ONDO");
1891
2242
  }
1892
2243
  async getTradingStatus(params) {
1893
- await this.ctx.ensureUserAuthenticated();
1894
- return getOndoTradingStatus(this.ctx.api, params);
2244
+ return this.log.wrap("getTradingStatus", params, async () => {
2245
+ await this.ctx.ensureUserAuthenticated();
2246
+ return getOndoTradingStatus(this.ctx.api, params);
2247
+ });
1895
2248
  }
1896
2249
  async getQuote(params) {
1897
- await this.ctx.ensureUserAuthenticated();
1898
- return getOndoQuote(this.ctx.api, params);
2250
+ return this.log.wrap("getQuote", params, async () => {
2251
+ await this.ctx.ensureUserAuthenticated();
2252
+ return getOndoQuote(this.ctx.api, params);
2253
+ });
1899
2254
  }
1900
2255
  async buildSwapTransaction(params) {
1901
- await this.ctx.ensureUserAuthenticated();
1902
- return buildOndoSwapTransaction(this.ctx.api, params);
2256
+ return this.log.wrap("buildSwapTransaction", params, async () => {
2257
+ await this.ctx.ensureUserAuthenticated();
2258
+ return buildOndoSwapTransaction(this.ctx.api, params);
2259
+ });
1903
2260
  }
1904
2261
  };
1905
2262
 
@@ -2213,26 +2570,37 @@ function formattedPricePerShare(quote, locale) {
2213
2570
  var SuperstateSwapNamespaceImpl = class {
2214
2571
  constructor(ctx) {
2215
2572
  this.ctx = ctx;
2573
+ this.log = internalLogger(ctx.logger, "SUPERSTATE");
2216
2574
  }
2217
2575
  async getAuthorization(params) {
2218
- await this.ctx.ensureUserAuthenticated();
2219
- return getSwapAuthorization(this.ctx.api, params);
2576
+ return this.log.wrap("getAuthorization", params, async () => {
2577
+ await this.ctx.ensureUserAuthenticated();
2578
+ return getSwapAuthorization(this.ctx.api, params);
2579
+ });
2220
2580
  }
2221
2581
  async getPreview(params) {
2222
- await this.ctx.ensureUserAuthenticated();
2223
- return getSwapPreview(this.ctx.api, params);
2582
+ return this.log.wrap("getPreview", params, async () => {
2583
+ await this.ctx.ensureUserAuthenticated();
2584
+ return getSwapPreview(this.ctx.api, params);
2585
+ });
2224
2586
  }
2225
2587
  async getStatus(params) {
2226
- await this.ctx.ensureUserAuthenticated();
2227
- return getSwapStatus(this.ctx.api, params);
2588
+ return this.log.wrap("getStatus", params, async () => {
2589
+ await this.ctx.ensureUserAuthenticated();
2590
+ return getSwapStatus(this.ctx.api, params);
2591
+ });
2228
2592
  }
2229
2593
  async getOutputToken(params) {
2230
- await this.ctx.ensureUserAuthenticated();
2231
- return getSwapOutputToken(this.ctx.api, params);
2594
+ return this.log.wrap("getOutputToken", params, async () => {
2595
+ await this.ctx.ensureUserAuthenticated();
2596
+ return getSwapOutputToken(this.ctx.api, params);
2597
+ });
2232
2598
  }
2233
2599
  async allowWallet(params) {
2234
- await this.ctx.ensureUserAuthenticated();
2235
- return allowWallet(this.ctx.api, params);
2600
+ return this.log.wrap("allowWallet", params, async () => {
2601
+ await this.ctx.ensureUserAuthenticated();
2602
+ return allowWallet(this.ctx.api, params);
2603
+ });
2236
2604
  }
2237
2605
  };
2238
2606
 
@@ -2269,18 +2637,25 @@ async function fetchOfferDetails(api, id, clientCreds) {
2269
2637
  var OffersNamespaceImpl = class {
2270
2638
  constructor(ctx) {
2271
2639
  this.ctx = ctx;
2640
+ this.log = internalLogger(ctx.logger, "OFFERS");
2272
2641
  }
2273
2642
  async list() {
2274
- await this.ctx.ensureUserAuthenticated();
2275
- return fetchOffers(this.ctx.api, void 0);
2643
+ return this.log.wrap("list", void 0, async () => {
2644
+ await this.ctx.ensureUserAuthenticated();
2645
+ return fetchOffers(this.ctx.api, void 0);
2646
+ });
2276
2647
  }
2277
2648
  async listPage(params) {
2278
- await this.ctx.ensureUserAuthenticated();
2279
- return fetchOffersPage(this.ctx.api, params, void 0);
2649
+ return this.log.wrap("listPage", params, async () => {
2650
+ await this.ctx.ensureUserAuthenticated();
2651
+ return fetchOffersPage(this.ctx.api, params, void 0);
2652
+ });
2280
2653
  }
2281
2654
  async get(id) {
2282
- await this.ctx.ensureUserAuthenticated();
2283
- return fetchOfferDetails(this.ctx.api, id, void 0);
2655
+ return this.log.wrap("get", id, async () => {
2656
+ await this.ctx.ensureUserAuthenticated();
2657
+ return fetchOfferDetails(this.ctx.api, id, void 0);
2658
+ });
2284
2659
  }
2285
2660
  };
2286
2661
 
@@ -2413,38 +2788,49 @@ async function fetchRequirementStatuses(api, offerId) {
2413
2788
  var RequirementsNamespaceImpl = class {
2414
2789
  constructor(ctx) {
2415
2790
  this.ctx = ctx;
2791
+ this.log = internalLogger(ctx.logger, "REQUIREMENTS");
2416
2792
  }
2417
2793
  async forOffer(offerId) {
2418
- await this.ctx.ensureUserAuthenticated();
2419
- return fetchOfferRequirements(
2420
- this.ctx.api,
2421
- offerId,
2422
- void 0
2423
- );
2794
+ return this.log.wrap("forOffer", offerId, async () => {
2795
+ await this.ctx.ensureUserAuthenticated();
2796
+ return fetchOfferRequirements(
2797
+ this.ctx.api,
2798
+ offerId,
2799
+ void 0
2800
+ );
2801
+ });
2424
2802
  }
2425
2803
  async statuses(offerId) {
2426
- await this.ctx.ensureUserAuthenticated();
2427
- return fetchRequirementStatuses(this.ctx.api, offerId);
2804
+ return this.log.wrap("statuses", offerId, async () => {
2805
+ await this.ctx.ensureUserAuthenticated();
2806
+ return fetchRequirementStatuses(this.ctx.api, offerId);
2807
+ });
2428
2808
  }
2429
2809
  async createKycToken(params) {
2430
- await this.ctx.ensureUserAuthenticated();
2431
- return createKycToken(
2432
- this.ctx.api,
2433
- params?.levelName,
2434
- params?.reset
2435
- );
2810
+ return this.log.wrap("createKycToken", params, async () => {
2811
+ await this.ctx.ensureUserAuthenticated();
2812
+ return createKycToken(
2813
+ this.ctx.api,
2814
+ params?.levelName,
2815
+ params?.reset
2816
+ );
2817
+ });
2436
2818
  }
2437
2819
  async getPii() {
2438
- await this.ctx.ensureUserAuthenticated();
2439
- return fetchPii(this.ctx.api);
2820
+ return this.log.wrap("getPii", void 0, async () => {
2821
+ await this.ctx.ensureUserAuthenticated();
2822
+ return fetchPii(this.ctx.api);
2823
+ });
2440
2824
  }
2441
2825
  async submitDocument(params) {
2442
- await this.ctx.ensureUserAuthenticated();
2443
- return submitDocument(
2444
- this.ctx.api,
2445
- params.documentType,
2446
- params.fields
2447
- );
2826
+ return this.log.wrap("submitDocument", params, async () => {
2827
+ await this.ctx.ensureUserAuthenticated();
2828
+ return submitDocument(
2829
+ this.ctx.api,
2830
+ params.documentType,
2831
+ params.fields
2832
+ );
2833
+ });
2448
2834
  }
2449
2835
  };
2450
2836
 
@@ -2477,27 +2863,47 @@ var TokenMetadata = {
2477
2863
  logoDark: dto.logo_dark === void 0 ? null : TokenLogo.fromDto(dto.logo_dark, baseUrl)
2478
2864
  };
2479
2865
  },
2866
+ /**
2867
+ * Maps the complete registry snapshot to every token it lists across the
2868
+ * chains this SDK models, skipping native coins and chains outside
2869
+ * {@link EthereumChain} (e.g. Solana) rather than failing on them — the
2870
+ * registry may serve chains ahead of the SDK's type surface.
2871
+ */
2872
+ fromRegistryDto: (dto, baseUrl) => {
2873
+ assertSupportedSchemaVersion(dto.schema_version);
2874
+ return dto.chains.flatMap((chainDto) => {
2875
+ let chain;
2876
+ try {
2877
+ chain = EthereumChain(chainDto.chain);
2878
+ } catch {
2879
+ return [];
2880
+ }
2881
+ return tokensOfChain(chain, chainDto.assets, baseUrl);
2882
+ });
2883
+ },
2480
2884
  /**
2481
2885
  * Maps a chain snapshot to the tokens it lists, skipping the chain's native
2482
2886
  * coin (`kind: 'COIN'`, no contract address).
2483
2887
  */
2484
2888
  fromChainAssetsDto: (dto, baseUrl) => {
2485
2889
  assertSupportedSchemaVersion(dto.schema_version);
2486
- const chain = EthereumChain(dto.chain);
2487
- return dto.assets.filter((asset) => asset.kind === "TOKEN" && asset.address !== void 0).map((asset) => ({
2488
- identifier: {
2489
- chain,
2490
- // The filter above cannot narrow `address` for the type checker.
2491
- address: EvmContractAddress(asset.address)
2492
- },
2493
- name: asset.name,
2494
- symbol: AssetSymbol(asset.symbol),
2495
- decimals: AssetDecimals(asset.decimals),
2496
- logo: TokenLogo.fromDto(asset.logo, baseUrl),
2497
- logoDark: asset.logo_dark === void 0 ? null : TokenLogo.fromDto(asset.logo_dark, baseUrl)
2498
- }));
2890
+ return tokensOfChain(EthereumChain(dto.chain), dto.assets, baseUrl);
2499
2891
  }
2500
2892
  };
2893
+ function tokensOfChain(chain, assets, baseUrl) {
2894
+ return assets.filter((asset) => asset.kind === "TOKEN" && asset.address !== void 0).map((asset) => ({
2895
+ identifier: {
2896
+ chain,
2897
+ // The filter above cannot narrow `address` for the type checker.
2898
+ address: EvmContractAddress(asset.address)
2899
+ },
2900
+ name: asset.name,
2901
+ symbol: AssetSymbol(asset.symbol),
2902
+ decimals: AssetDecimals(asset.decimals),
2903
+ logo: TokenLogo.fromDto(asset.logo, baseUrl),
2904
+ logoDark: asset.logo_dark === void 0 ? null : TokenLogo.fromDto(asset.logo_dark, baseUrl)
2905
+ }));
2906
+ }
2501
2907
  function assertSupportedSchemaVersion(version) {
2502
2908
  if (version !== 1) {
2503
2909
  throw new ValidationError(
@@ -2515,8 +2921,8 @@ var resolveLogoUrl = (url, baseUrl) => TokenLogoUrl(
2515
2921
  );
2516
2922
 
2517
2923
  // src/shared/api/nabu/tokens.ts
2518
- function createNabuApiClient(baseUrl) {
2519
- return new HttpClient({ baseUrl });
2924
+ function createNabuApiClient(baseUrl, logger = null) {
2925
+ return new HttpClient({ baseUrl }, {}, logger);
2520
2926
  }
2521
2927
  async function fetchTokenMetadata(client, token) {
2522
2928
  const address = checksummed(token.address);
@@ -2566,6 +2972,29 @@ async function fetchTokensMetadata(client, chain) {
2566
2972
  }
2567
2973
  return TokenMetadata.fromChainAssetsDto(response.body, client.config.baseUrl);
2568
2974
  }
2975
+ async function fetchAllTokensMetadata(client) {
2976
+ let response;
2977
+ try {
2978
+ response = await client.send({
2979
+ method: "GET",
2980
+ url: `/assets.json`
2981
+ });
2982
+ } catch (error) {
2983
+ if (isRegistryHtmlFallback(error)) {
2984
+ throw new ValidationError(
2985
+ "Token registry returned non-JSON for the complete snapshot"
2986
+ );
2987
+ }
2988
+ throw error;
2989
+ }
2990
+ assertOk(response);
2991
+ if (response.body === null) {
2992
+ throw new ValidationError(
2993
+ "Token registry returned an empty complete snapshot"
2994
+ );
2995
+ }
2996
+ return TokenMetadata.fromRegistryDto(response.body, client.config.baseUrl);
2997
+ }
2569
2998
  function isRegistryHtmlFallback(error) {
2570
2999
  return error instanceof HttpError && error.response.status >= 200 && error.response.status < 300;
2571
3000
  }
@@ -2589,14 +3018,23 @@ var TokensNamespaceImpl = class {
2589
3018
  * registry is unauthenticated and on its own host, so the frontline sender
2590
3019
  * and the auth check would both be dead weight here.
2591
3020
  */
2592
- constructor(baseUrl) {
2593
- this.api = createNabuApiClient(baseUrl);
3021
+ constructor(baseUrl, logger = null) {
3022
+ this.api = createNabuApiClient(baseUrl, logger);
3023
+ this.log = internalLogger(logger, "TOKENS");
2594
3024
  }
2595
3025
  get(token) {
2596
- return fetchTokenMetadata(this.api, token);
3026
+ return this.log.wrap(
3027
+ "get",
3028
+ token,
3029
+ () => fetchTokenMetadata(this.api, token)
3030
+ );
2597
3031
  }
2598
3032
  list(chain) {
2599
- return fetchTokensMetadata(this.api, chain);
3033
+ return this.log.wrap(
3034
+ "list",
3035
+ chain,
3036
+ () => chain === void 0 ? fetchAllTokensMetadata(this.api) : fetchTokensMetadata(this.api, chain)
3037
+ );
2600
3038
  }
2601
3039
  };
2602
3040
 
@@ -2702,36 +3140,50 @@ async function removeOptionAddress(api, offerId, addressId) {
2702
3140
  var WalletsNamespaceImpl = class {
2703
3141
  constructor(ctx) {
2704
3142
  this.ctx = ctx;
3143
+ this.log = internalLogger(ctx.logger, "WALLETS");
2705
3144
  }
2706
3145
  async createOwnershipChallenge(params) {
2707
- await this.ctx.ensureUserAuthenticated();
2708
- return createWalletOwnershipChallenge(
2709
- this.ctx.api,
2710
- params
2711
- );
3146
+ return this.log.wrap("createOwnershipChallenge", params, async () => {
3147
+ await this.ctx.ensureUserAuthenticated();
3148
+ return createWalletOwnershipChallenge(
3149
+ this.ctx.api,
3150
+ params
3151
+ );
3152
+ });
2712
3153
  }
2713
3154
  async connectExternal(params) {
2714
- await this.ctx.ensureUserAuthenticated();
2715
- return connectExternalWallet(this.ctx.api, params);
3155
+ return this.log.wrap("connectExternal", params, async () => {
3156
+ await this.ctx.ensureUserAuthenticated();
3157
+ return connectExternalWallet(this.ctx.api, params);
3158
+ });
2716
3159
  }
2717
3160
  async list(params) {
2718
- await this.ctx.ensureUserAuthenticated();
2719
- return listOptionAddresses(
2720
- this.ctx.api,
2721
- params.offerId,
2722
- params.offerOptionId
2723
- );
3161
+ return this.log.wrap("list", params, async () => {
3162
+ await this.ctx.ensureUserAuthenticated();
3163
+ return listOptionAddresses(
3164
+ this.ctx.api,
3165
+ params.offerId,
3166
+ params.offerOptionId
3167
+ );
3168
+ });
2724
3169
  }
2725
3170
  async remove(params) {
2726
- await this.ctx.ensureUserAuthenticated();
2727
- return removeOptionAddress(
2728
- this.ctx.api,
2729
- params.offerId,
2730
- params.addressId
2731
- );
3171
+ return this.log.wrap("remove", params, async () => {
3172
+ await this.ctx.ensureUserAuthenticated();
3173
+ return removeOptionAddress(
3174
+ this.ctx.api,
3175
+ params.offerId,
3176
+ params.addressId
3177
+ );
3178
+ });
2732
3179
  }
2733
3180
  };
2734
3181
 
3182
+ // src/shared/types/blockchain/wallet-error.ts
3183
+ var RedactedWalletError = {
3184
+ fromWalletError: (error) => error.type === "unknown" ? { type: "unknown" } : error
3185
+ };
3186
+
2735
3187
  // src/client/core/checkout/coin-list/token-sale-flows.ts
2736
3188
  async function executeTokenSale(params) {
2737
3189
  const {
@@ -2747,8 +3199,8 @@ async function executeTokenSale(params) {
2747
3199
  amount,
2748
3200
  onProgress
2749
3201
  } = params;
2750
- const emit = (phase) => onProgress?.(phase);
2751
- emit("checking-allowance");
3202
+ const emit2 = (phase) => onProgress?.(phase);
3203
+ emit2("checking-allowance");
2752
3204
  let currentAllowance;
2753
3205
  try {
2754
3206
  const allowance = await erc20.getAllowance({
@@ -2770,7 +3222,7 @@ async function executeTokenSale(params) {
2770
3222
  value: 0n,
2771
3223
  pending: "resetting-allowance",
2772
3224
  confirming: "confirming-allowance-reset",
2773
- emit
3225
+ emit: emit2
2774
3226
  });
2775
3227
  if (reset.type === "error") {
2776
3228
  return {
@@ -2787,13 +3239,13 @@ async function executeTokenSale(params) {
2787
3239
  value: amount.raw,
2788
3240
  pending: "approving",
2789
3241
  confirming: "confirming-approval",
2790
- emit
3242
+ emit: emit2
2791
3243
  });
2792
3244
  if (approve.type === "error") {
2793
3245
  return { type: "error", error: approve.error };
2794
3246
  }
2795
3247
  const approvalTxHash = approve.txHash;
2796
- emit("recording-participation");
3248
+ emit2("recording-participation");
2797
3249
  let participation;
2798
3250
  try {
2799
3251
  participation = await tokenSale.createParticipation({
@@ -2811,6 +3263,72 @@ async function executeTokenSale(params) {
2811
3263
  return { type: "success", participation, approvalTxHash };
2812
3264
  }
2813
3265
 
3266
+ // src/client/core/observability/flow-logging.ts
3267
+ async function withFlowLogging(log, flow, onProgress, run) {
3268
+ const flowLog = log.child({ flow });
3269
+ flowLog.info(() => ({ msg: "flow started" }));
3270
+ try {
3271
+ const result = await run((phase) => {
3272
+ flowLog.info(() => ({ msg: "flow advanced", fields: { phase } }));
3273
+ onProgress?.(phase);
3274
+ });
3275
+ logOutcome(flowLog, result);
3276
+ return result;
3277
+ } catch (error) {
3278
+ flowLog.failure(
3279
+ () => ({ msg: "flow threw instead of returning a step" }),
3280
+ error
3281
+ );
3282
+ throw error;
3283
+ }
3284
+ }
3285
+ function logOutcome(log, outcome) {
3286
+ switch (outcome.type) {
3287
+ case "success":
3288
+ log.info(() => ({ msg: "flow succeeded" }));
3289
+ return;
3290
+ case "error":
3291
+ log.debug(() => ({
3292
+ msg: "flow failed",
3293
+ fields: {
3294
+ step: outcome.error.step,
3295
+ error: describeErrorUnredacted(outcome.error.cause)
3296
+ }
3297
+ }));
3298
+ log.error(() => ({
3299
+ msg: "flow failed",
3300
+ fields: { step: outcome.error.step },
3301
+ ...walletCause(outcome.error.cause)
3302
+ }));
3303
+ return;
3304
+ default: {
3305
+ const _exhaustive = outcome;
3306
+ return;
3307
+ }
3308
+ }
3309
+ }
3310
+ function walletCause(cause) {
3311
+ if (!isWalletError(cause)) return {};
3312
+ return {
3313
+ cause: {
3314
+ type: "wallet",
3315
+ error: RedactedWalletError.fromWalletError(cause)
3316
+ }
3317
+ };
3318
+ }
3319
+ var WALLET_ERROR_TYPES = /* @__PURE__ */ new Set([
3320
+ "user_rejected",
3321
+ "insufficient_funds",
3322
+ "contract_reverted",
3323
+ "timeout",
3324
+ "unknown"
3325
+ ]);
3326
+ function isWalletError(value) {
3327
+ if (typeof value !== "object" || value === null) return false;
3328
+ const type = value.type;
3329
+ return typeof type === "string" && WALLET_ERROR_TYPES.has(type);
3330
+ }
3331
+
2814
3332
  // src/client/core/checkout/coin-list/client-token-sale-namespace.ts
2815
3333
  var ClientCoinListTokenSaleNamespaceImpl = class extends CoinListTokenSaleNamespaceImpl {
2816
3334
  constructor(ctx, erc20) {
@@ -2818,7 +3336,17 @@ var ClientCoinListTokenSaleNamespaceImpl = class extends CoinListTokenSaleNamesp
2818
3336
  this.erc20 = erc20;
2819
3337
  }
2820
3338
  execute(params) {
2821
- return executeTokenSale({ ...params, erc20: this.erc20, tokenSale: this });
3339
+ return withFlowLogging(
3340
+ this.log,
3341
+ "execute",
3342
+ params.onProgress,
3343
+ (onProgress) => executeTokenSale({
3344
+ ...params,
3345
+ onProgress,
3346
+ erc20: this.erc20,
3347
+ tokenSale: this
3348
+ })
3349
+ );
2822
3350
  }
2823
3351
  };
2824
3352
 
@@ -2844,7 +3372,7 @@ async function prepareOndoSwap(params) {
2844
3372
  amount,
2845
3373
  onProgress
2846
3374
  } = params;
2847
- const emit = (phase) => onProgress?.(phase);
3375
+ const emit2 = (phase) => onProgress?.(phase);
2848
3376
  const spender = ondoSwapContractAddress(chain);
2849
3377
  if (spender === null) {
2850
3378
  return { type: "error", error: { step: "unsupported-chain", chain } };
@@ -2856,10 +3384,10 @@ async function prepareOndoSwap(params) {
2856
3384
  amount,
2857
3385
  wallet,
2858
3386
  spender,
2859
- onProgress: emit
3387
+ onProgress: emit2
2860
3388
  });
2861
3389
  if (allowance.type === "error") return allowance;
2862
- emit("building-transaction");
3390
+ emit2("building-transaction");
2863
3391
  try {
2864
3392
  const transaction = await ondo.buildSwapTransaction({
2865
3393
  symbol,
@@ -2878,7 +3406,7 @@ async function prepareOndoSwap(params) {
2878
3406
  var INSUFFICIENT_ALLOWANCE_CODE = "insufficient_allowance";
2879
3407
  async function executeOndoSwap(params) {
2880
3408
  const { wallet, transaction, chain, now = /* @__PURE__ */ new Date(), onProgress } = params;
2881
- const emit = (phase) => onProgress?.(phase);
3409
+ const emit2 = (phase) => onProgress?.(phase);
2882
3410
  if (now.getTime() >= transaction.expiresAt.getTime()) {
2883
3411
  return { type: "error", error: { step: "quote-expired" } };
2884
3412
  }
@@ -2892,7 +3420,7 @@ async function executeOndoSwap(params) {
2892
3420
  }
2893
3421
  };
2894
3422
  }
2895
- emit("broadcasting-swap");
3423
+ emit2("broadcasting-swap");
2896
3424
  let txHash;
2897
3425
  try {
2898
3426
  txHash = await wallet.broadcastRawTx({
@@ -2906,7 +3434,7 @@ async function executeOndoSwap(params) {
2906
3434
  error: { step: "swap", cause: classifyWalletError(error) }
2907
3435
  };
2908
3436
  }
2909
- emit("confirming-swap");
3437
+ emit2("confirming-swap");
2910
3438
  let receipt;
2911
3439
  try {
2912
3440
  receipt = await wallet.awaitTx(txHash, chain);
@@ -2932,10 +3460,25 @@ var ClientOndoNamespaceImpl = class extends OndoNamespaceImpl {
2932
3460
  this.erc20 = erc20;
2933
3461
  }
2934
3462
  prepareSwap(params) {
2935
- return prepareOndoSwap({ ...params, ondo: this, erc20: this.erc20 });
3463
+ return withFlowLogging(
3464
+ this.log,
3465
+ "prepareSwap",
3466
+ params.onProgress,
3467
+ (onProgress) => prepareOndoSwap({
3468
+ ...params,
3469
+ onProgress,
3470
+ ondo: this,
3471
+ erc20: this.erc20
3472
+ })
3473
+ );
2936
3474
  }
2937
3475
  executeSwap(params) {
2938
- return executeOndoSwap(params);
3476
+ return withFlowLogging(
3477
+ this.log,
3478
+ "executeSwap",
3479
+ params.onProgress,
3480
+ (onProgress) => executeOndoSwap({ ...params, onProgress })
3481
+ );
2939
3482
  }
2940
3483
  };
2941
3484
 
@@ -2952,10 +3495,10 @@ async function executeSwap(params) {
2952
3495
  slippageBps,
2953
3496
  onProgress
2954
3497
  } = params;
2955
- const emit = (phase) => onProgress?.(phase);
3498
+ const emit2 = (phase) => onProgress?.(phase);
2956
3499
  const inputAmount = BlockchainAmount.add(quote.inputTokenAmount, quote.fee);
2957
3500
  const minOut = computeSlip(quote.outputTokenAmount, slippageBps).raw;
2958
- emit("checking-status");
3501
+ emit2("checking-status");
2959
3502
  let status;
2960
3503
  try {
2961
3504
  status = await swap.getStatus({ contractAddress, chain });
@@ -2972,12 +3515,12 @@ async function executeSwap(params) {
2972
3515
  amount: inputAmount,
2973
3516
  wallet,
2974
3517
  spender: contractAddress,
2975
- onProgress: emit
3518
+ onProgress: emit2
2976
3519
  });
2977
3520
  if (allowanceRes.type === "error") {
2978
3521
  return allowanceRes;
2979
3522
  }
2980
- emit("swapping");
3523
+ emit2("swapping");
2981
3524
  let swapTxHash;
2982
3525
  try {
2983
3526
  swapTxHash = await wallet.writeContract({
@@ -2993,7 +3536,7 @@ async function executeSwap(params) {
2993
3536
  error: { step: "swap", cause: classifyWalletError(error) }
2994
3537
  };
2995
3538
  }
2996
- emit("confirming-swap");
3539
+ emit2("confirming-swap");
2997
3540
  let receipt;
2998
3541
  try {
2999
3542
  receipt = await wallet.awaitTx(swapTxHash, chain);
@@ -3028,9 +3571,9 @@ async function executeSwap(params) {
3028
3571
  }
3029
3572
  async function authorizeWallet(params) {
3030
3573
  const { swap, wallets, wallet, offerId, contractAddress, chain, onProgress } = params;
3031
- const emit = (phase) => onProgress?.(phase);
3574
+ const emit2 = (phase) => onProgress?.(phase);
3032
3575
  const walletAddress = wallet.address;
3033
- emit("checking-authorization");
3576
+ emit2("checking-authorization");
3034
3577
  let auth;
3035
3578
  try {
3036
3579
  auth = await swap.getAuthorization({
@@ -3042,7 +3585,7 @@ async function authorizeWallet(params) {
3042
3585
  return { type: "error", error: { step: "authorization-check" } };
3043
3586
  }
3044
3587
  if (auth.authorized) return { type: "success" };
3045
- emit("requesting-challenge");
3588
+ emit2("requesting-challenge");
3046
3589
  let challenge;
3047
3590
  try {
3048
3591
  challenge = await wallets.createOwnershipChallenge({
@@ -3053,7 +3596,7 @@ async function authorizeWallet(params) {
3053
3596
  } catch {
3054
3597
  return { type: "error", error: { step: "challenge-request" } };
3055
3598
  }
3056
- emit("signing-message");
3599
+ emit2("signing-message");
3057
3600
  let signature;
3058
3601
  try {
3059
3602
  signature = await wallet.signMessage(challenge.message);
@@ -3063,7 +3606,7 @@ async function authorizeWallet(params) {
3063
3606
  error: { step: "signing", cause: classifyWalletError(error) }
3064
3607
  };
3065
3608
  }
3066
- emit("submitting-signature");
3609
+ emit2("submitting-signature");
3067
3610
  let allow;
3068
3611
  try {
3069
3612
  allow = await swap.allowWallet({
@@ -3076,7 +3619,7 @@ async function authorizeWallet(params) {
3076
3619
  return { type: "error", error: { step: "allow-wallet" } };
3077
3620
  }
3078
3621
  if (allow.action === "broadcast_transaction") {
3079
- emit("broadcasting-transaction");
3622
+ emit2("broadcasting-transaction");
3080
3623
  let hash;
3081
3624
  try {
3082
3625
  hash = await wallet.broadcastRawTx({
@@ -3090,7 +3633,7 @@ async function authorizeWallet(params) {
3090
3633
  error: { step: "broadcast", cause: classifyWalletError(error) }
3091
3634
  };
3092
3635
  }
3093
- emit("awaiting-confirmation");
3636
+ emit2("awaiting-confirmation");
3094
3637
  try {
3095
3638
  await wallet.awaitTx(hash, chain);
3096
3639
  } catch (error) {
@@ -3103,7 +3646,7 @@ async function authorizeWallet(params) {
3103
3646
  };
3104
3647
  }
3105
3648
  }
3106
- emit("verifying-authorization");
3649
+ emit2("verifying-authorization");
3107
3650
  let reCheck;
3108
3651
  try {
3109
3652
  reCheck = await swap.getAuthorization({
@@ -3128,10 +3671,25 @@ var ClientSuperstateSwapNamespaceImpl = class extends SuperstateSwapNamespaceImp
3128
3671
  this.wallets = wallets;
3129
3672
  }
3130
3673
  execute(params) {
3131
- return executeSwap({ ...params, swap: this, erc20: this.erc20 });
3674
+ return withFlowLogging(
3675
+ this.log,
3676
+ "execute",
3677
+ params.onProgress,
3678
+ (onProgress) => executeSwap({ ...params, onProgress, swap: this, erc20: this.erc20 })
3679
+ );
3132
3680
  }
3133
3681
  authorizeWallet(params) {
3134
- return authorizeWallet({ ...params, swap: this, wallets: this.wallets });
3682
+ return withFlowLogging(
3683
+ this.log,
3684
+ "authorizeWallet",
3685
+ params.onProgress,
3686
+ (onProgress) => authorizeWallet({
3687
+ ...params,
3688
+ onProgress,
3689
+ swap: this,
3690
+ wallets: this.wallets
3691
+ })
3692
+ );
3135
3693
  }
3136
3694
  };
3137
3695
 
@@ -3157,12 +3715,6 @@ function requirementPath(requirement) {
3157
3715
  switch (requirement.type) {
3158
3716
  case "kyc_approved":
3159
3717
  return VERIFY_IDENTITY_PATH;
3160
- case "identity_verified":
3161
- return VERIFY_IDENTITY_VERIFIED_PATH;
3162
- case "proof_of_address":
3163
- return VERIFY_IDENTITY_PROOF_OF_ADDRESS_PATH;
3164
- case "source_of_funds":
3165
- return VERIFY_IDENTITY_SOURCE_OF_FUNDS_PATH;
3166
3718
  case "accreditation":
3167
3719
  return VERIFY_IDENTITY_ACCREDITATION_PATH;
3168
3720
  case "external_wallet":
@@ -3187,7 +3739,14 @@ function requirementPath(requirement) {
3187
3739
 
3188
3740
  // src/client/core/support/client-support-namespace.ts
3189
3741
  var ClientSupportNamespaceImpl = class {
3742
+ constructor(logger = null) {
3743
+ this.log = internalLogger(logger, "SUPPORT");
3744
+ }
3190
3745
  contact() {
3746
+ this.log.child({ op: "contact" }).info(() => ({
3747
+ msg: "opening the support ticket page",
3748
+ fields: { supportUrl: SUPPORT_NEW_TICKET_URL }
3749
+ }));
3191
3750
  openInNewTab(SUPPORT_NEW_TICKET_URL);
3192
3751
  }
3193
3752
  };
@@ -3201,15 +3760,18 @@ var CoinListClientImpl = class {
3201
3760
  this._config = _config;
3202
3761
  /** Cached access token: undefined = loading, null = no token, AccessToken = logged in */
3203
3762
  this._accessToken = void 0;
3763
+ const logger = _config.logger ?? null;
3204
3764
  this.api = new ApiClient(
3205
3765
  {
3206
3766
  baseUrl: _config.baseUrl || PUBLIC_API_BASE_URL,
3207
3767
  xApiVersion: API_VERSION
3208
3768
  },
3209
- this.fetchAccessToken.bind(this)
3769
+ this.fetchAccessToken.bind(this),
3770
+ logger
3210
3771
  );
3211
3772
  const ctx = {
3212
3773
  api: this.api,
3774
+ logger,
3213
3775
  ensureUserAuthenticated: async () => this.ensureAuthenticated()
3214
3776
  };
3215
3777
  this.auth = new ClientAuthNamespaceImpl(_config, {
@@ -3233,9 +3795,10 @@ var CoinListClientImpl = class {
3233
3795
  );
3234
3796
  this.ondo = new ClientOndoNamespaceImpl(ctx, this.erc20);
3235
3797
  this.tokens = new TokensNamespaceImpl(
3236
- _config.tokensBaseUrl ?? NABU_BASE_URL
3798
+ _config.tokensBaseUrl ?? NABU_BASE_URL,
3799
+ logger
3237
3800
  );
3238
- this.support = new ClientSupportNamespaceImpl();
3801
+ this.support = new ClientSupportNamespaceImpl(logger);
3239
3802
  }
3240
3803
  async init() {
3241
3804
  await this.fetchAccessToken(true);
@@ -3276,17 +3839,28 @@ function useLocale() {
3276
3839
  return (0, import_react.useContext)(CoinListLocaleContext);
3277
3840
  }
3278
3841
 
3842
+ // src/client/hooks/shared/useLogger.ts
3843
+ var import_react2 = require("react");
3844
+ var CoinListLoggerContext = (0, import_react2.createContext)(null);
3845
+ function useLogger(hook) {
3846
+ const logger = (0, import_react2.useContext)(CoinListLoggerContext);
3847
+ return (0, import_react2.useMemo)(
3848
+ () => internalLogger(logger, "HOOKS").child({ hook }),
3849
+ [logger, hook]
3850
+ );
3851
+ }
3852
+
3279
3853
  // src/client/CoinListProvider.tsx
3280
3854
  var import_jsx_runtime = require("react/jsx-runtime");
3281
- var CoinListContext = (0, import_react2.createContext)(null);
3855
+ var CoinListContext = (0, import_react3.createContext)(null);
3282
3856
  function CoinListContextProvider({
3283
3857
  config,
3284
3858
  locale,
3285
3859
  children
3286
3860
  }) {
3287
- const [isReady, setIsReady] = (0, import_react2.useState)(false);
3288
- const coinlist = (0, import_react2.useMemo)(() => createCoinListClient(config), [config]);
3289
- (0, import_react2.useEffect)(() => {
3861
+ const [isReady, setIsReady] = (0, import_react3.useState)(false);
3862
+ const coinlist = (0, import_react3.useMemo)(() => createCoinListClient(config), [config]);
3863
+ (0, import_react3.useEffect)(() => {
3290
3864
  let isCancelled = false;
3291
3865
  if (coinlist.auth.getState() === "unknown") {
3292
3866
  coinlist.init().then(() => {
@@ -3305,22 +3879,23 @@ function CoinListContextProvider({
3305
3879
  isCancelled = true;
3306
3880
  };
3307
3881
  }, [coinlist]);
3308
- const value = (0, import_react2.useMemo)(() => ({ coinlist, isReady }), [coinlist, isReady]);
3309
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CoinListContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CoinListLocaleContext.Provider, { value: locale ?? DEFAULT_LOCALE, children }) });
3882
+ const value = (0, import_react3.useMemo)(() => ({ coinlist, isReady }), [coinlist, isReady]);
3883
+ const logger = config.logger ?? null;
3884
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CoinListContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CoinListLocaleContext.Provider, { value: locale ?? DEFAULT_LOCALE, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CoinListLoggerContext.Provider, { value: logger, children }) }) });
3310
3885
  }
3311
3886
  var CoinListProvider = CoinListContextProvider;
3312
3887
 
3313
3888
  // src/client/CoinListStyleScope.tsx
3314
- var import_react3 = require("react");
3889
+ var import_react4 = require("react");
3315
3890
 
3316
3891
  // src/client/generated/sdk-styles.gen.ts
3317
3892
  var sdkStyles = '/*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--clcosdk-font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--clcosdk-color-red-400:oklch(70.4% .191 22.216);--clcosdk-color-red-500:oklch(63.7% .237 25.331);--clcosdk-color-amber-500:oklch(76.9% .188 70.08);--clcosdk-color-gray-400:oklch(70.7% .022 261.325);--clcosdk-color-gray-500:oklch(55.1% .027 264.364);--clcosdk-color-black:#000;--clcosdk-spacing:.25rem;--clcosdk-container-sm:24rem;--clcosdk-container-md:28rem;--clcosdk-container-xl:36rem;--clcosdk-text-xs:.75rem;--clcosdk-text-xs--line-height:calc(1 / .75);--clcosdk-text-sm:.875rem;--clcosdk-text-sm--line-height:calc(1.25 / .875);--clcosdk-text-base:1rem;--clcosdk-text-base--line-height:calc(1.5 / 1);--clcosdk-text-lg:1.125rem;--clcosdk-text-lg--line-height:calc(1.75 / 1.125);--clcosdk-font-weight-normal:400;--clcosdk-font-weight-medium:500;--clcosdk-font-weight-semibold:600;--clcosdk-radius-md:.375rem;--clcosdk-radius-lg:.5rem;--clcosdk-radius-xl:.75rem;--clcosdk-radius-2xl:1rem;--clcosdk-ease-in-out:cubic-bezier(.4, 0, .2, 1);--clcosdk-animate-spin:spin 1s linear infinite;--clcosdk-animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--clcosdk-color-brand-primary:var(--color-brand-primary)}}@layer base{.clco-sdk-root{--color-brand-primary:#171717;--color-brand-primary-hover:#000;--color-brand-primary-active:#262626;--color-accent:#2b3a67;--color-accent-hover:#243057;--color-accent-active:#1d2647;--color-accent-focus:#c7d2fe;--color-accent-subtle:#eef1f8;--color-text-primary:#171717;--color-text-secondary:#8c8c8c;--color-text-disabled:#d1d1d1;--color-text-inverse:#fff;--color-background:#fff;--color-surface:#fafafa;--color-section:#f3f3f3;--color-border:#e5e5e5;--color-divider:#ececec;--color-overlay:#00000080;--color-positive:#15803d;--color-positive-subtle:#dcfce7;--color-negative:#dc2626;--color-negative-subtle:#fee2e2;--color-success:#2c8c5e;--color-success-subtle:#e6f4ec;--color-success-border:#cfe9db;--color-warning:#e08a1a;--color-warning-subtle:#fff7ed;--color-warning-border:#fdead7;--color-error:#b42318;--color-error-subtle:#feeceb;--color-error-border:#fbd5d2;--shadow-step-active:0px 0px 10px 0px #0000001a;--shadow-dialog:0px 8px 32px 0px #0000001a;--btn-primary-gradient:linear-gradient(180deg, #262626 0%, #1c1c1c 50%, #0f0f0f 100%);--btn-primary-shadow:inset 0px -1px 3px 0px #00000059, inset 0px 1px 2px 0px #ffffff2e, inset 0px 1px 0px 0px #ffffff1a}@media (prefers-color-scheme:dark){.clco-sdk-root:not(:where(.light,.light *)){--color-brand-primary:#f4f4f5;--color-brand-primary-hover:#fff;--color-brand-primary-active:#e4e4e7;--color-accent:#6f82c9;--color-accent-hover:#8799e4;--color-accent-active:#5b6fcf;--color-accent-focus:#6f82c959;--color-accent-subtle:#6f82c91f;--color-text-primary:#f4f4f5;--color-text-secondary:#a1a1aa;--color-text-disabled:#71717a;--color-text-inverse:#171717;--color-background:#0f1115;--color-surface:#161a20;--color-section:#20242c;--color-border:#2a2e35;--color-divider:#323741;--color-overlay:#000000b3;--color-positive:#22c55e;--color-positive-subtle:#22c55e1f;--color-negative:#ef4444;--color-negative-subtle:#ef44441f;--color-success:#34d399;--color-success-subtle:#34d3991f;--color-success-border:#34d39940;--color-warning:#f59e0b;--color-warning-subtle:#f59e0b1f;--color-warning-border:#f59e0b40;--color-error:#f87171;--color-error-subtle:#f871711f;--color-error-border:#f8717140;--shadow-step-active:0px 0px 10px 0px #00000080;--shadow-dialog:0px 8px 32px 0px #0009;--btn-primary-gradient:linear-gradient(180deg, #fafafa 0%, #f0f0f0 50%, #e4e4e7 100%);--btn-primary-shadow:inset 0px -1px 3px 0px #0000001f, inset 0px 1px 2px 0px #fff9, inset 0px 1px 0px 0px #fff6}}:where(.dark,.dark *) .clco-sdk-root{--color-brand-primary:#f4f4f5;--color-brand-primary-hover:#fff;--color-brand-primary-active:#e4e4e7;--color-accent:#6f82c9;--color-accent-hover:#8799e4;--color-accent-active:#5b6fcf;--color-accent-focus:#6f82c959;--color-accent-subtle:#6f82c91f;--color-text-primary:#f4f4f5;--color-text-secondary:#a1a1aa;--color-text-disabled:#71717a;--color-text-inverse:#171717;--color-background:#0f1115;--color-surface:#161a20;--color-section:#20242c;--color-border:#2a2e35;--color-divider:#323741;--color-overlay:#000000b3;--color-positive:#22c55e;--color-positive-subtle:#22c55e1f;--color-negative:#ef4444;--color-negative-subtle:#ef44441f;--color-success:#34d399;--color-success-subtle:#34d3991f;--color-success-border:#34d39940;--color-warning:#f59e0b;--color-warning-subtle:#f59e0b1f;--color-warning-border:#f59e0b40;--color-error:#f87171;--color-error-subtle:#f871711f;--color-error-border:#f8717140;--shadow-step-active:0px 0px 10px 0px #00000080;--shadow-dialog:0px 8px 32px 0px #0009;--btn-primary-gradient:linear-gradient(180deg, #fafafa 0%, #f0f0f0 50%, #e4e4e7 100%);--btn-primary-shadow:inset 0px -1px 3px 0px #0000001f, inset 0px 1px 2px 0px #fff9, inset 0px 1px 0px 0px #fff6}.clco-sdk-root{color:var(--color-text-primary);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:Inter,sans-serif}.clco-sdk-root *,.clco-sdk-root :before,.clco-sdk-root :after{box-sizing:border-box}.clco-sdk-root button{appearance:none;cursor:pointer;font:inherit;color:inherit;background:0 0;border:none;padding:0}.clco-sdk-root input,.clco-sdk-root textarea,.clco-sdk-root select{font:inherit;color:inherit;background:0 0;border:none;border-radius:0;padding:0}.clco-sdk-root a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}.clco-sdk-root ul,.clco-sdk-root ol{margin:0;padding:0;list-style:none}.clco-sdk-root h1,.clco-sdk-root h2,.clco-sdk-root h3,.clco-sdk-root h4,.clco-sdk-root h5,.clco-sdk-root h6,.clco-sdk-root p,.clco-sdk-root figure,.clco-sdk-root blockquote,.clco-sdk-root dl,.clco-sdk-root dd,.clco-sdk-root pre{margin:0}.clco-sdk-root img,.clco-sdk-root svg{max-width:100%;display:block}}@layer components;@layer utilities{.clcosdk\\:pointer-events-none{pointer-events:none}.clcosdk\\:sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.clcosdk\\:absolute{position:absolute}.clcosdk\\:fixed{position:fixed}.clcosdk\\:relative{position:relative}.clcosdk\\:inset-0{inset:calc(var(--clcosdk-spacing) * 0)}.clcosdk\\:top-4{top:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:top-full{top:100%}.clcosdk\\:-right-0\\.5{right:calc(var(--clcosdk-spacing) * -.5)}.clcosdk\\:right-4{right:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:-bottom-0\\.5{bottom:calc(var(--clcosdk-spacing) * -.5)}.clcosdk\\:bottom-full{bottom:100%}.clcosdk\\:left-1\\/2{left:50%}.clcosdk\\:z-50{z-index:50}.clcosdk\\:order-1{order:1}.clcosdk\\:order-2{order:2}.clcosdk\\:mt-2{margin-top:calc(var(--clcosdk-spacing) * 2)}.clcosdk\\:mt-4{margin-top:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:mb-2{margin-bottom:calc(var(--clcosdk-spacing) * 2)}.clcosdk\\:mb-6{margin-bottom:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:flex{display:flex}.clcosdk\\:grid{display:grid}.clcosdk\\:inline-flex{display:inline-flex}.clcosdk\\:size-2{width:calc(var(--clcosdk-spacing) * 2);height:calc(var(--clcosdk-spacing) * 2)}.clcosdk\\:size-3{width:calc(var(--clcosdk-spacing) * 3);height:calc(var(--clcosdk-spacing) * 3)}.clcosdk\\:size-3\\.5{width:calc(var(--clcosdk-spacing) * 3.5);height:calc(var(--clcosdk-spacing) * 3.5)}.clcosdk\\:size-4{width:calc(var(--clcosdk-spacing) * 4);height:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:size-5{width:calc(var(--clcosdk-spacing) * 5);height:calc(var(--clcosdk-spacing) * 5)}.clcosdk\\:size-10{width:calc(var(--clcosdk-spacing) * 10);height:calc(var(--clcosdk-spacing) * 10)}.clcosdk\\:size-16{width:calc(var(--clcosdk-spacing) * 16);height:calc(var(--clcosdk-spacing) * 16)}.clcosdk\\:size-24{width:calc(var(--clcosdk-spacing) * 24);height:calc(var(--clcosdk-spacing) * 24)}.clcosdk\\:size-full{width:100%;height:100%}.clcosdk\\:h-1{height:calc(var(--clcosdk-spacing) * 1)}.clcosdk\\:h-3{height:calc(var(--clcosdk-spacing) * 3)}.clcosdk\\:h-4{height:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:h-5{height:calc(var(--clcosdk-spacing) * 5)}.clcosdk\\:h-6{height:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:h-8{height:calc(var(--clcosdk-spacing) * 8)}.clcosdk\\:h-9{height:calc(var(--clcosdk-spacing) * 9)}.clcosdk\\:h-10{height:calc(var(--clcosdk-spacing) * 10)}.clcosdk\\:h-11{height:calc(var(--clcosdk-spacing) * 11)}.clcosdk\\:h-12{height:calc(var(--clcosdk-spacing) * 12)}.clcosdk\\:h-14{height:calc(var(--clcosdk-spacing) * 14)}.clcosdk\\:h-28{height:calc(var(--clcosdk-spacing) * 28)}.clcosdk\\:h-52{height:calc(var(--clcosdk-spacing) * 52)}.clcosdk\\:h-\\[18px\\]{height:18px}.clcosdk\\:h-\\[54px\\]{height:54px}.clcosdk\\:h-auto{height:auto}.clcosdk\\:h-full{height:100%}.clcosdk\\:h-px{height:1px}.clcosdk\\:max-h-\\[92vh\\]{max-height:92vh}.clcosdk\\:max-h-full{max-height:100%}.clcosdk\\:min-h-0{min-height:calc(var(--clcosdk-spacing) * 0)}.clcosdk\\:min-h-9{min-height:calc(var(--clcosdk-spacing) * 9)}.clcosdk\\:min-h-40{min-height:calc(var(--clcosdk-spacing) * 40)}.clcosdk\\:min-h-\\[2\\.4rem\\]{min-height:2.4rem}.clcosdk\\:min-h-screen{min-height:100vh}.clcosdk\\:w-1{width:calc(var(--clcosdk-spacing) * 1)}.clcosdk\\:w-4{width:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:w-5{width:calc(var(--clcosdk-spacing) * 5)}.clcosdk\\:w-6{width:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:w-12{width:calc(var(--clcosdk-spacing) * 12)}.clcosdk\\:w-16{width:calc(var(--clcosdk-spacing) * 16)}.clcosdk\\:w-20{width:calc(var(--clcosdk-spacing) * 20)}.clcosdk\\:w-24{width:calc(var(--clcosdk-spacing) * 24)}.clcosdk\\:w-28{width:calc(var(--clcosdk-spacing) * 28)}.clcosdk\\:w-32{width:calc(var(--clcosdk-spacing) * 32)}.clcosdk\\:w-40{width:calc(var(--clcosdk-spacing) * 40)}.clcosdk\\:w-48{width:calc(var(--clcosdk-spacing) * 48)}.clcosdk\\:w-80{width:calc(var(--clcosdk-spacing) * 80)}.clcosdk\\:w-96{width:calc(var(--clcosdk-spacing) * 96)}.clcosdk\\:w-\\[16px\\]{width:16px}.clcosdk\\:w-\\[448px\\]{width:448px}.clcosdk\\:w-auto{width:auto}.clcosdk\\:w-component{width:448px}.clcosdk\\:w-fit{width:fit-content}.clcosdk\\:w-full{width:100%}.clcosdk\\:w-max{width:max-content}.clcosdk\\:max-w-\\[16rem\\]{max-width:16rem}.clcosdk\\:max-w-\\[22rem\\]{max-width:22rem}.clcosdk\\:max-w-\\[28rem\\]{max-width:28rem}.clcosdk\\:max-w-\\[30rem\\]{max-width:30rem}.clcosdk\\:max-w-\\[760px\\]{max-width:760px}.clcosdk\\:max-w-\\[1200px\\]{max-width:1200px}.clcosdk\\:max-w-full{max-width:100%}.clcosdk\\:max-w-md{max-width:var(--clcosdk-container-md)}.clcosdk\\:max-w-sm{max-width:var(--clcosdk-container-sm)}.clcosdk\\:max-w-xl{max-width:var(--clcosdk-container-xl)}.clcosdk\\:min-w-0{min-width:calc(var(--clcosdk-spacing) * 0)}.clcosdk\\:flex-1{flex:1}.clcosdk\\:shrink-0{flex-shrink:0}.clcosdk\\:-translate-x-1\\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.clcosdk\\:rotate-90{rotate:90deg}.clcosdk\\:rotate-180{rotate:180deg}.clcosdk\\:animate-pulse{animation:var(--clcosdk-animate-pulse)}.clcosdk\\:animate-spin{animation:var(--clcosdk-animate-spin)}.clcosdk\\:cursor-pointer{cursor:pointer}.clcosdk\\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.clcosdk\\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.clcosdk\\:grid-rows-\\[0fr\\]{grid-template-rows:0fr}.clcosdk\\:grid-rows-\\[1fr\\]{grid-template-rows:1fr}.clcosdk\\:flex-col{flex-direction:column}.clcosdk\\:flex-wrap{flex-wrap:wrap}.clcosdk\\:items-center{align-items:center}.clcosdk\\:items-end{align-items:flex-end}.clcosdk\\:items-start{align-items:flex-start}.clcosdk\\:justify-between{justify-content:space-between}.clcosdk\\:justify-center{justify-content:center}.clcosdk\\:justify-end{justify-content:flex-end}.clcosdk\\:gap-1{gap:calc(var(--clcosdk-spacing) * 1)}.clcosdk\\:gap-1\\.5{gap:calc(var(--clcosdk-spacing) * 1.5)}.clcosdk\\:gap-2{gap:calc(var(--clcosdk-spacing) * 2)}.clcosdk\\:gap-3{gap:calc(var(--clcosdk-spacing) * 3)}.clcosdk\\:gap-4{gap:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:gap-5{gap:calc(var(--clcosdk-spacing) * 5)}.clcosdk\\:gap-6{gap:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:gap-8{gap:calc(var(--clcosdk-spacing) * 8)}.clcosdk\\:gap-\\[5px\\]{gap:5px}:where(.clcosdk\\:space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--clcosdk-spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--clcosdk-spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.clcosdk\\:space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--clcosdk-spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--clcosdk-spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.clcosdk\\:divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.clcosdk\\:divide-border>:not(:last-child)){border-color:var(--color-border)}:where(.clcosdk\\:divide-divider>:not(:last-child)){border-color:var(--color-divider)}.clcosdk\\:self-start{align-self:flex-start}.clcosdk\\:truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.clcosdk\\:overflow-hidden{overflow:hidden}.clcosdk\\:overflow-y-auto{overflow-y:auto}.clcosdk\\:rounded{border-radius:.25rem}.clcosdk\\:rounded-2xl{border-radius:var(--clcosdk-radius-2xl)}.clcosdk\\:rounded-btn{border-radius:12px}.clcosdk\\:rounded-card{border-radius:24px}.clcosdk\\:rounded-full{border-radius:3.40282e38px}.clcosdk\\:rounded-lg{border-radius:var(--clcosdk-radius-lg)}.clcosdk\\:rounded-md{border-radius:var(--clcosdk-radius-md)}.clcosdk\\:rounded-xl{border-radius:var(--clcosdk-radius-xl)}.clcosdk\\:border{border-style:var(--tw-border-style);border-width:1px}.clcosdk\\:border-2{border-style:var(--tw-border-style);border-width:2px}.clcosdk\\:border-\\[1\\.5px\\]{border-style:var(--tw-border-style);border-width:1.5px}.clcosdk\\:border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.clcosdk\\:border-dashed{--tw-border-style:dashed;border-style:dashed}.clcosdk\\:border-accent\\/50{border-color:var(--color-accent)}@supports (color:color-mix(in lab, red, red)){.clcosdk\\:border-accent\\/50{border-color:color-mix(in oklab, var(--color-accent) 50%, transparent)}}.clcosdk\\:border-accent\\/60{border-color:var(--color-accent)}@supports (color:color-mix(in lab, red, red)){.clcosdk\\:border-accent\\/60{border-color:color-mix(in oklab, var(--color-accent) 60%, transparent)}}.clcosdk\\:border-amber-500{border-color:var(--clcosdk-color-amber-500)}.clcosdk\\:border-background{border-color:var(--color-background)}.clcosdk\\:border-border,.clcosdk\\:border-border\\/60{border-color:var(--color-border)}@supports (color:color-mix(in lab, red, red)){.clcosdk\\:border-border\\/60{border-color:color-mix(in oklab, var(--color-border) 60%, transparent)}}.clcosdk\\:border-brand-primary{border-color:var(--color-brand-primary)}.clcosdk\\:border-current{border-color:currentColor}.clcosdk\\:border-divider{border-color:var(--color-divider)}.clcosdk\\:border-error-border{border-color:var(--color-error-border)}.clcosdk\\:border-success-border{border-color:var(--color-success-border)}.clcosdk\\:border-warning-border{border-color:var(--color-warning-border)}.clcosdk\\:border-t-transparent{border-top-color:#0000}.clcosdk\\:bg-accent\\/10{background-color:var(--color-accent)}@supports (color:color-mix(in lab, red, red)){.clcosdk\\:bg-accent\\/10{background-color:color-mix(in oklab, var(--color-accent) 10%, transparent)}}.clcosdk\\:bg-background{background-color:var(--color-background)}.clcosdk\\:bg-black\\/50{background-color:var(--clcosdk-color-black)}@supports (color:color-mix(in lab, red, red)){.clcosdk\\:bg-black\\/50{background-color:color-mix(in oklab, var(--clcosdk-color-black) 50%, transparent)}}.clcosdk\\:bg-brand-primary{background-color:var(--color-brand-primary)}.clcosdk\\:bg-divider{background-color:var(--color-divider)}.clcosdk\\:bg-error-subtle{background-color:var(--color-error-subtle)}.clcosdk\\:bg-overlay{background-color:var(--color-overlay)}.clcosdk\\:bg-positive{background-color:var(--color-positive)}.clcosdk\\:bg-positive-subtle{background-color:var(--color-positive-subtle)}.clcosdk\\:bg-section{background-color:var(--color-section)}.clcosdk\\:bg-success-subtle{background-color:var(--color-success-subtle)}.clcosdk\\:bg-surface{background-color:var(--color-surface)}.clcosdk\\:bg-text-disabled{background-color:var(--color-text-disabled)}.clcosdk\\:bg-text-primary{background-color:var(--color-text-primary)}.clcosdk\\:bg-transparent{background-color:#0000}.clcosdk\\:bg-warning-subtle{background-color:var(--color-warning-subtle)}.clcosdk\\:bg-gradient-to-b{--tw-gradient-position:to bottom in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.clcosdk\\:bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.clcosdk\\:bg-\\[image\\:var\\(--btn-primary-gradient\\)\\]{background-image:var(--btn-primary-gradient)}.clcosdk\\:from-surface{--tw-gradient-from:var(--color-surface);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.clcosdk\\:from-transparent{--tw-gradient-from:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.clcosdk\\:via-section{--tw-gradient-via:var(--color-section);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.clcosdk\\:via-transparent{--tw-gradient-via:transparent;--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.clcosdk\\:to-background{--tw-gradient-to:var(--color-background);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.clcosdk\\:to-overlay\\/35{--tw-gradient-to:var(--color-overlay)}@supports (color:color-mix(in lab, red, red)){.clcosdk\\:to-overlay\\/35{--tw-gradient-to:color-mix(in oklab, var(--color-overlay) 35%, transparent)}}.clcosdk\\:to-overlay\\/35{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.clcosdk\\:object-contain{object-fit:contain}.clcosdk\\:object-cover{object-fit:cover}.clcosdk\\:p-0{padding:calc(var(--clcosdk-spacing) * 0)}.clcosdk\\:p-1\\.5{padding:calc(var(--clcosdk-spacing) * 1.5)}.clcosdk\\:p-3{padding:calc(var(--clcosdk-spacing) * 3)}.clcosdk\\:p-3\\.5{padding:calc(var(--clcosdk-spacing) * 3.5)}.clcosdk\\:p-4{padding:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:p-6{padding:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:p-8{padding:calc(var(--clcosdk-spacing) * 8)}.clcosdk\\:p-16{padding:calc(var(--clcosdk-spacing) * 16)}.clcosdk\\:px-2{padding-inline:calc(var(--clcosdk-spacing) * 2)}.clcosdk\\:px-3{padding-inline:calc(var(--clcosdk-spacing) * 3)}.clcosdk\\:px-4{padding-inline:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:px-5{padding-inline:calc(var(--clcosdk-spacing) * 5)}.clcosdk\\:px-6{padding-inline:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:py-1\\.5{padding-block:calc(var(--clcosdk-spacing) * 1.5)}.clcosdk\\:py-2{padding-block:calc(var(--clcosdk-spacing) * 2)}.clcosdk\\:py-3{padding-block:calc(var(--clcosdk-spacing) * 3)}.clcosdk\\:py-8{padding-block:calc(var(--clcosdk-spacing) * 8)}.clcosdk\\:py-12{padding-block:calc(var(--clcosdk-spacing) * 12)}.clcosdk\\:pt-1{padding-top:calc(var(--clcosdk-spacing) * 1)}.clcosdk\\:pt-4{padding-top:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:pt-14{padding-top:calc(var(--clcosdk-spacing) * 14)}.clcosdk\\:pr-4{padding-right:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:pb-4{padding-bottom:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:pl-3{padding-left:calc(var(--clcosdk-spacing) * 3)}.clcosdk\\:text-center{text-align:center}.clcosdk\\:text-left{text-align:left}.clcosdk\\:text-right{text-align:right}.clcosdk\\:font-mono{font-family:var(--clcosdk-font-mono)}.clcosdk\\:text-base{font-size:var(--clcosdk-text-base);line-height:var(--tw-leading,var(--clcosdk-text-base--line-height))}.clcosdk\\:text-lg{font-size:var(--clcosdk-text-lg);line-height:var(--tw-leading,var(--clcosdk-text-lg--line-height))}.clcosdk\\:text-sm{font-size:var(--clcosdk-text-sm);line-height:var(--tw-leading,var(--clcosdk-text-sm--line-height))}.clcosdk\\:text-xs{font-size:var(--clcosdk-text-xs);line-height:var(--tw-leading,var(--clcosdk-text-xs--line-height))}.clcosdk\\:text-\\[11px\\]{font-size:11px}.clcosdk\\:text-\\[12px\\]{font-size:12px}.clcosdk\\:text-\\[14px\\]{font-size:14px}.clcosdk\\:text-\\[15px\\]{font-size:15px}.clcosdk\\:text-\\[16px\\]{font-size:16px}.clcosdk\\:text-\\[18px\\]{font-size:18px}.clcosdk\\:text-\\[22px\\]{font-size:22px}.clcosdk\\:text-\\[28px\\]{font-size:28px}.clcosdk\\:text-\\[36px\\]{font-size:36px}.clcosdk\\:text-\\[48px\\]{font-size:48px}.clcosdk\\:text-\\[64px\\]{font-size:64px}.clcosdk\\:leading-\\[110\\%\\]{--tw-leading:110%;line-height:110%}.clcosdk\\:leading-\\[120\\%\\]{--tw-leading:120%;line-height:120%}.clcosdk\\:leading-\\[125\\%\\]{--tw-leading:125%;line-height:125%}.clcosdk\\:leading-\\[130\\%\\]{--tw-leading:130%;line-height:130%}.clcosdk\\:leading-\\[135\\%\\]{--tw-leading:135%;line-height:135%}.clcosdk\\:leading-\\[140\\%\\]{--tw-leading:140%;line-height:140%}.clcosdk\\:leading-\\[150\\%\\]{--tw-leading:150%;line-height:150%}.clcosdk\\:leading-\\[160\\%\\]{--tw-leading:160%;line-height:160%}.clcosdk\\:font-medium{--tw-font-weight:var(--clcosdk-font-weight-medium);font-weight:var(--clcosdk-font-weight-medium)}.clcosdk\\:font-normal{--tw-font-weight:var(--clcosdk-font-weight-normal);font-weight:var(--clcosdk-font-weight-normal)}.clcosdk\\:font-semibold{--tw-font-weight:var(--clcosdk-font-weight-semibold);font-weight:var(--clcosdk-font-weight-semibold)}.clcosdk\\:tracking-\\[0\\.12px\\]{--tw-tracking:.12px;letter-spacing:.12px}.clcosdk\\:tracking-\\[0\\.28px\\]{--tw-tracking:.28px;letter-spacing:.28px}.clcosdk\\:break-words{overflow-wrap:break-word}.clcosdk\\:whitespace-nowrap{white-space:nowrap}.clcosdk\\:text-background{color:var(--color-background)}.clcosdk\\:text-brand-primary{color:var(--color-brand-primary)}.clcosdk\\:text-error{color:var(--color-error)}.clcosdk\\:text-positive{color:var(--color-positive)}.clcosdk\\:text-success{color:var(--color-success)}.clcosdk\\:text-text-disabled{color:var(--color-text-disabled)}.clcosdk\\:text-text-inverse{color:var(--color-text-inverse)}.clcosdk\\:text-text-primary{color:var(--color-text-primary)}.clcosdk\\:text-text-secondary{color:var(--color-text-secondary)}.clcosdk\\:text-warning{color:var(--color-warning)}.clcosdk\\:capitalize{text-transform:capitalize}.clcosdk\\:tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.clcosdk\\:no-underline{text-decoration-line:none}.clcosdk\\:underline{text-decoration-line:underline}.clcosdk\\:underline-offset-2{text-underline-offset:2px}.clcosdk\\:underline-offset-4{text-underline-offset:4px}.clcosdk\\:opacity-0{opacity:0}.clcosdk\\:opacity-60{opacity:.6}.clcosdk\\:shadow-\\[0_0_0_3px_rgba\\(59\\,130\\,246\\,0\\.2\\)\\]{--tw-shadow:0 0 0 3px var(--tw-shadow-color,#3b82f633);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:shadow-\\[0_0_0_3px_rgba\\(59\\,130\\,246\\,0\\.18\\)\\]{--tw-shadow:0 0 0 3px var(--tw-shadow-color,#3b82f62e);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:shadow-\\[0_0_0_3px_rgba\\(59\\,130\\,246\\,0\\.25\\)\\]{--tw-shadow:0 0 0 3px var(--tw-shadow-color,#3b82f640);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:shadow-\\[0_10px_24px_rgba\\(0\\,0\\,0\\,0\\.18\\)\\]{--tw-shadow:0 10px 24px var(--tw-shadow-color,#0000002e);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:shadow-\\[0_10px_24px_rgba\\(0\\,0\\,0\\,0\\.25\\)\\]{--tw-shadow:0 10px 24px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:shadow-\\[var\\(--btn-primary-shadow\\)\\]{--tw-shadow:var(--btn-primary-shadow);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:shadow-card{--tw-shadow:0px 4px 6px -2px var(--tw-shadow-color,#0000000d), 0px 12px 24px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:shadow-dialog{--tw-shadow:var(--shadow-dialog);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:shadow-step-active{--tw-shadow:var(--shadow-step-active);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:transition-\\[grid-template-rows\\]{transition-property:grid-template-rows;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.clcosdk\\:transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.clcosdk\\:transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.clcosdk\\:transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.clcosdk\\:transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.clcosdk\\:duration-200{--tw-duration:.2s;transition-duration:.2s}.clcosdk\\:duration-300{--tw-duration:.3s;transition-duration:.3s}.clcosdk\\:ease-in-out{--tw-ease:var(--clcosdk-ease-in-out);transition-timing-function:var(--clcosdk-ease-in-out)}.clcosdk\\:outline-none{--tw-outline-style:none;outline-style:none}.clcosdk\\:group-focus-within\\:opacity-100:is(:where(.clcosdk\\:group):focus-within *){opacity:1}@media (hover:hover){.clcosdk\\:group-hover\\:opacity-100:is(:where(.clcosdk\\:group):hover *){opacity:1}}.clcosdk\\:placeholder\\:text-text-disabled::placeholder{color:var(--color-text-disabled)}@media (hover:hover){.clcosdk\\:hover\\:-translate-y-0\\.5:hover{--tw-translate-y:calc(var(--clcosdk-spacing) * -.5);translate:var(--tw-translate-x) var(--tw-translate-y)}.clcosdk\\:hover\\:border-divider:hover{border-color:var(--color-divider)}.clcosdk\\:hover\\:border-text-disabled:hover{border-color:var(--color-text-disabled)}.clcosdk\\:hover\\:bg-\\[\\#fcdcd8\\]:hover{background-color:#fcdcd8}.clcosdk\\:hover\\:bg-border:hover{background-color:var(--color-border)}.clcosdk\\:hover\\:bg-brand-primary:hover{background-color:var(--color-brand-primary)}.clcosdk\\:hover\\:bg-brand-primary-hover:hover{background-color:var(--color-brand-primary-hover)}.clcosdk\\:hover\\:bg-section:hover{background-color:var(--color-section)}.clcosdk\\:hover\\:bg-surface:hover{background-color:var(--color-surface)}.clcosdk\\:hover\\:text-\\[\\#8b1a13\\]:hover{color:#8b1a13}.clcosdk\\:hover\\:text-text-primary:hover{color:var(--color-text-primary)}.clcosdk\\:hover\\:underline:hover{text-decoration-line:underline}.clcosdk\\:hover\\:opacity-80:hover{opacity:.8}.clcosdk\\:hover\\:opacity-90:hover{opacity:.9}.clcosdk\\:hover\\:shadow-\\[0px_14px_32px_-10px_rgba\\(0\\,0\\,0\\,0\\.35\\)\\]:hover{--tw-shadow:0px 14px 32px -10px var(--tw-shadow-color,#00000059);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}}.clcosdk\\:focus-visible\\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.clcosdk\\:focus-visible\\:ring-accent-focus:focus-visible{--tw-ring-color:var(--color-accent-focus)}.clcosdk\\:focus-visible\\:ring-gray-400:focus-visible{--tw-ring-color:var(--clcosdk-color-gray-400)}.clcosdk\\:focus-visible\\:ring-gray-500:focus-visible{--tw-ring-color:var(--clcosdk-color-gray-500)}.clcosdk\\:focus-visible\\:ring-red-400:focus-visible{--tw-ring-color:var(--clcosdk-color-red-400)}.clcosdk\\:focus-visible\\:ring-red-500:focus-visible{--tw-ring-color:var(--clcosdk-color-red-500)}.clcosdk\\:focus-visible\\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.clcosdk\\:focus-visible\\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.clcosdk\\:active\\:bg-\\[\\#d9d9d9\\]:active{background-color:#d9d9d9}.clcosdk\\:active\\:bg-\\[\\#f9c9c4\\]:active{background-color:#f9c9c4}.clcosdk\\:active\\:bg-border:active{background-color:var(--color-border)}.clcosdk\\:active\\:bg-brand-primary-active:active{background-color:var(--color-brand-primary-active)}.clcosdk\\:active\\:text-\\[\\#6d1510\\]:active{color:#6d1510}.clcosdk\\:active\\:opacity-80:active{opacity:.8}.clcosdk\\:disabled\\:pointer-events-none:disabled{pointer-events:none}.clcosdk\\:disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.clcosdk\\:disabled\\:opacity-40:disabled{opacity:.4}.clcosdk\\:disabled\\:opacity-50:disabled{opacity:.5}.clcosdk\\:aria-disabled\\:cursor-not-allowed[aria-disabled=true]{cursor:not-allowed}.clcosdk\\:aria-disabled\\:opacity-50[aria-disabled=true]{opacity:.5}@media not all and (min-width:48rem){.clcosdk\\:max-md\\:hidden{display:none}.clcosdk\\:max-md\\:w-full{width:100%}.clcosdk\\:max-md\\:justify-start{justify-content:flex-start}.clcosdk\\:max-md\\:gap-4{gap:calc(var(--clcosdk-spacing) * 4)}.clcosdk\\:max-md\\:rounded-none{border-radius:0}.clcosdk\\:max-md\\:border-0{border-style:var(--tw-border-style);border-width:0}.clcosdk\\:max-md\\:bg-transparent{background-color:#0000}.clcosdk\\:max-md\\:p-0{padding:calc(var(--clcosdk-spacing) * 0)}}@media (min-width:40rem){.clcosdk\\:sm\\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:48rem){.clcosdk\\:md\\:order-1{order:1}.clcosdk\\:md\\:order-2{order:2}.clcosdk\\:md\\:hidden{display:none}.clcosdk\\:md\\:grid-cols-\\[minmax\\(0\\,11fr\\)_minmax\\(0\\,8fr\\)\\]{grid-template-columns:minmax(0,11fr) minmax(0,8fr)}.clcosdk\\:md\\:flex-row{flex-direction:row}.clcosdk\\:md\\:items-center{align-items:center}.clcosdk\\:md\\:items-end{align-items:flex-end}.clcosdk\\:md\\:justify-between{justify-content:space-between}.clcosdk\\:md\\:justify-end{justify-content:flex-end}.clcosdk\\:md\\:gap-6{gap:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:md\\:gap-x-12{column-gap:calc(var(--clcosdk-spacing) * 12)}.clcosdk\\:md\\:self-end{align-self:flex-end}.clcosdk\\:md\\:rounded-card{border-radius:24px}.clcosdk\\:md\\:rounded-dialog{border-radius:32px}.clcosdk\\:md\\:p-6{padding:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:md\\:px-6{padding-inline:calc(var(--clcosdk-spacing) * 6)}.clcosdk\\:md\\:px-8{padding-inline:calc(var(--clcosdk-spacing) * 8)}}@media (prefers-color-scheme:dark){@media (hover:hover){.clcosdk\\:dark\\:hover\\:bg-\\[rgba\\(248\\,113\\,113\\,0\\.20\\)\\]:not(:where(.light,.light *)):hover{background-color:#f8717133}}}@media (hover:hover){.clcosdk\\:dark\\:hover\\:bg-\\[rgba\\(248\\,113\\,113\\,0\\.20\\)\\]:where(.dark,.dark *):hover{background-color:#f8717133}}@media (prefers-color-scheme:dark){@media (hover:hover){.clcosdk\\:dark\\:hover\\:text-\\[\\#fca5a5\\]:not(:where(.light,.light *)):hover{color:#fca5a5}}}@media (hover:hover){.clcosdk\\:dark\\:hover\\:text-\\[\\#fca5a5\\]:where(.dark,.dark *):hover{color:#fca5a5}}@media (prefers-color-scheme:dark){.clcosdk\\:dark\\:active\\:bg-\\[rgba\\(248\\,113\\,113\\,0\\.30\\)\\]:not(:where(.light,.light *)):active{background-color:#f871714d}}.clcosdk\\:dark\\:active\\:bg-\\[rgba\\(248\\,113\\,113\\,0\\.30\\)\\]:where(.dark,.dark *):active{background-color:#f871714d}@media (prefers-color-scheme:dark){.clcosdk\\:dark\\:active\\:bg-divider:not(:where(.light,.light *)):active{background-color:var(--color-divider)}}.clcosdk\\:dark\\:active\\:bg-divider:where(.dark,.dark *):active{background-color:var(--color-divider)}@media (prefers-color-scheme:dark){.clcosdk\\:dark\\:active\\:text-\\[\\#f87171\\]:not(:where(.light,.light *)):active{color:#f87171}}.clcosdk\\:dark\\:active\\:text-\\[\\#f87171\\]:where(.dark,.dark *):active{color:#f87171}.clcosdk\\:\\[\\&_circle\\]\\:fill-error-subtle circle{fill:var(--color-error-subtle)}.clcosdk\\:\\[\\&_circle\\]\\:fill-success-subtle circle{fill:var(--color-success-subtle)}.clcosdk\\:\\[\\&_circle\\]\\:fill-warning-subtle circle{fill:var(--color-warning-subtle)}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}';
3318
3893
 
3319
3894
  // src/client/CoinListStyleScope.tsx
3320
3895
  var import_jsx_runtime2 = require("react/jsx-runtime");
3321
- var ScopeContext = (0, import_react3.createContext)(false);
3896
+ var ScopeContext = (0, import_react4.createContext)(false);
3322
3897
  function CoinListStyleScope({ children }) {
3323
- const alreadyScoped = (0, import_react3.useContext)(ScopeContext);
3898
+ const alreadyScoped = (0, import_react4.useContext)(ScopeContext);
3324
3899
  if (alreadyScoped) {
3325
3900
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children });
3326
3901
  }
@@ -3357,7 +3932,7 @@ function CoinListStyleScope({ children }) {
3357
3932
 
3358
3933
  // src/client/components/design-system/ClButton.tsx
3359
3934
  var import_class_variance_authority = require("class-variance-authority");
3360
- var import_react4 = require("react");
3935
+ var import_react5 = require("react");
3361
3936
 
3362
3937
  // src/client/components/design-system/utils.ts
3363
3938
  var import_clsx = require("clsx");
@@ -3424,7 +3999,7 @@ var buttonVariants = (0, import_class_variance_authority.cva)(
3424
3999
  }
3425
4000
  }
3426
4001
  );
3427
- var ClButton = (0, import_react4.forwardRef)(
4002
+ var ClButton = (0, import_react5.forwardRef)(
3428
4003
  ({
3429
4004
  className,
3430
4005
  variant,
@@ -3768,12 +4343,12 @@ function CoinListSignInCardView({
3768
4343
  }
3769
4344
 
3770
4345
  // src/client/hooks/auth/useCoinListSignInCardViewModel.ts
3771
- var import_react6 = require("react");
4346
+ var import_react7 = require("react");
3772
4347
 
3773
4348
  // src/client/hooks/useCoinList.ts
3774
- var import_react5 = require("react");
4349
+ var import_react6 = require("react");
3775
4350
  function useCoinList() {
3776
- const context = (0, import_react5.useContext)(CoinListContext);
4351
+ const context = (0, import_react6.useContext)(CoinListContext);
3777
4352
  if (context === null) {
3778
4353
  throw new CoinListClientInitializationError();
3779
4354
  }
@@ -3794,11 +4369,11 @@ var ERROR_MESSAGE = "Error signing in. Please try again.";
3794
4369
  function useCoinListSignInCardViewModel(options = {}) {
3795
4370
  const { status = "idle", onSignIn, onClose } = options;
3796
4371
  const { coinlist } = useCoinList();
3797
- const state = (0, import_react6.useMemo)(() => {
4372
+ const state = (0, import_react7.useMemo)(() => {
3798
4373
  const closable = onClose !== void 0;
3799
4374
  return status === "error" ? { type: "error", message: ERROR_MESSAGE, closable } : { type: "idle", closable };
3800
4375
  }, [status, onClose]);
3801
- const onEvent = (0, import_react6.useCallback)(
4376
+ const onEvent = (0, import_react7.useCallback)(
3802
4377
  (event) => {
3803
4378
  switch (event.type) {
3804
4379
  case "ON_SIGN_IN":
@@ -3846,7 +4421,7 @@ function CoinListSignInCardContainer({
3846
4421
  }
3847
4422
 
3848
4423
  // src/client/components/checkout/shared/amount/CheckoutAmountInput.tsx
3849
- var import_react7 = require("react");
4424
+ var import_react8 = require("react");
3850
4425
  var import_jsx_runtime12 = require("react/jsx-runtime");
3851
4426
  function CheckoutAmountInput({
3852
4427
  label,
@@ -3856,12 +4431,13 @@ function CheckoutAmountInput({
3856
4431
  invalid = false,
3857
4432
  disabled = false,
3858
4433
  prefix,
3859
- suffix,
4434
+ prefixTone = "primary",
3860
4435
  action,
3861
4436
  className
3862
4437
  }) {
3863
- const inputId = (0, import_react7.useId)();
4438
+ const inputId = (0, import_react8.useId)();
3864
4439
  const toneClass = invalid ? "clcosdk:text-error" : "clcosdk:text-text-primary";
4440
+ const prefixToneClass = prefixTone === "muted" ? "clcosdk:text-text-secondary" : toneClass;
3865
4441
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CoinListStyleScope, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
3866
4442
  "div",
3867
4443
  {
@@ -3891,7 +4467,7 @@ function CheckoutAmountInput({
3891
4467
  className: cn(
3892
4468
  typeClasses.h4,
3893
4469
  "clcosdk:shrink-0 clcosdk:font-medium",
3894
- toneClass
4470
+ prefixToneClass
3895
4471
  ),
3896
4472
  children: prefix
3897
4473
  }
@@ -3915,16 +4491,6 @@ function CheckoutAmountInput({
3915
4491
  toneClass
3916
4492
  )
3917
4493
  }
3918
- ),
3919
- suffix && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3920
- "span",
3921
- {
3922
- className: cn(
3923
- typeClasses.h4,
3924
- "clcosdk:shrink-0 clcosdk:font-medium clcosdk:text-text-secondary"
3925
- ),
3926
- children: suffix
3927
- }
3928
4494
  )
3929
4495
  ] }),
3930
4496
  action
@@ -4284,7 +4850,8 @@ function ActiveView({
4284
4850
  placeholder: AMOUNT_PLACEHOLDER,
4285
4851
  invalid: state.error !== null,
4286
4852
  disabled: isLoading,
4287
- suffix: selectedAsset?.symbol,
4853
+ prefix: selectedAsset?.symbol,
4854
+ prefixTone: "muted",
4288
4855
  action: selectedAsset && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4289
4856
  MaxButton,
4290
4857
  {
@@ -4489,13 +5056,13 @@ function CheckoutDetailList({
4489
5056
  }
4490
5057
 
4491
5058
  // src/client/components/design-system/Modal.tsx
4492
- var import_react8 = require("react");
5059
+ var import_react9 = require("react");
4493
5060
  var import_jsx_runtime21 = require("react/jsx-runtime");
4494
5061
  function Modal({ label, onClose, children, className }) {
4495
- const surfaceRef = (0, import_react8.useRef)(null);
4496
- const onCloseRef = (0, import_react8.useRef)(onClose);
5062
+ const surfaceRef = (0, import_react9.useRef)(null);
5063
+ const onCloseRef = (0, import_react9.useRef)(onClose);
4497
5064
  onCloseRef.current = onClose;
4498
- (0, import_react8.useEffect)(() => {
5065
+ (0, import_react9.useEffect)(() => {
4499
5066
  const previouslyFocused = document.activeElement;
4500
5067
  surfaceRef.current?.focus();
4501
5068
  const onKeyDown = (event) => {
@@ -4775,7 +5342,7 @@ function Skeleton({ variant = "text", className }) {
4775
5342
  }
4776
5343
 
4777
5344
  // src/client/components/design-system/Tooltip.tsx
4778
- var import_react9 = require("react");
5345
+ var import_react10 = require("react");
4779
5346
  var import_jsx_runtime26 = require("react/jsx-runtime");
4780
5347
  var positionClasses = {
4781
5348
  top: "clcosdk:bottom-full clcosdk:mb-2",
@@ -4787,7 +5354,7 @@ function Tooltip({
4787
5354
  children,
4788
5355
  className
4789
5356
  }) {
4790
- const tooltipId = (0, import_react9.useId)();
5357
+ const tooltipId = (0, import_react10.useId)();
4791
5358
  return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
4792
5359
  "span",
4793
5360
  {
@@ -4919,7 +5486,8 @@ function ActiveView2({
4919
5486
  }
4920
5487
  )
4921
5488
  ] }),
4922
- state.error ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(QuoteLine, { tone: "error", children: state.error }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(QuoteStatusLine, { quote: state.quote, onEvent }),
5489
+ state.error !== null && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(QuoteLine, { tone: "error", children: state.error }),
5490
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(QuoteStatusLine, { quote: state.quote, onEvent }),
4923
5491
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4924
5492
  ClButton,
4925
5493
  {
@@ -5143,7 +5711,7 @@ function StatusIndicator({ status, className }) {
5143
5711
 
5144
5712
  // src/client/components/checkout/shared/sidebar/CheckoutSidebarCard.tsx
5145
5713
  var import_lucide_react5 = require("lucide-react");
5146
- var import_react10 = require("react");
5714
+ var import_react11 = require("react");
5147
5715
 
5148
5716
  // src/client/components/checkout/shared/common/CheckoutCard.tsx
5149
5717
  var import_jsx_runtime29 = require("react/jsx-runtime");
@@ -5173,8 +5741,8 @@ function CheckoutSidebarCard({
5173
5741
  hideDetailsLabel,
5174
5742
  className
5175
5743
  }) {
5176
- const [expanded, setExpanded] = (0, import_react10.useState)(false);
5177
- const rowsId = (0, import_react10.useId)();
5744
+ const [expanded, setExpanded] = (0, import_react11.useState)(false);
5745
+ const rowsId = (0, import_react11.useId)();
5178
5746
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(CoinListStyleScope, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
5179
5747
  CheckoutCard,
5180
5748
  {
@@ -5321,7 +5889,7 @@ function PriceCaption({ price }) {
5321
5889
  var import_lucide_react6 = require("lucide-react");
5322
5890
 
5323
5891
  // src/client/components/checkout/shared/selection/SelectableOptionRow.tsx
5324
- var import_react11 = require("react");
5892
+ var import_react12 = require("react");
5325
5893
  var import_jsx_runtime32 = require("react/jsx-runtime");
5326
5894
  function SelectableOptionRow({
5327
5895
  selected,
@@ -5405,10 +5973,10 @@ function RadioCircle({ selected }) {
5405
5973
  );
5406
5974
  }
5407
5975
  function OptionMetaRow({ children }) {
5408
- const items = import_react11.Children.toArray(children).filter(Boolean);
5976
+ const items = import_react12.Children.toArray(children).filter(Boolean);
5409
5977
  return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "clcosdk:flex clcosdk:min-w-0 clcosdk:items-center clcosdk:gap-1.5", children: items.map((item, index) => (
5410
5978
  // biome-ignore lint/suspicious/noArrayIndexKey: positional separators, and the list is caller-authored JSX.
5411
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_react11.Fragment, { children: [
5979
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_react12.Fragment, { children: [
5412
5980
  index > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MetaDot, {}),
5413
5981
  item
5414
5982
  ] }, index)
@@ -6006,7 +6574,7 @@ var SUPERSTATE_TOS_URL = "https://superstate.com/terms";
6006
6574
 
6007
6575
  // src/client/components/checkout/superstate/swap/review/SlippagePicker.tsx
6008
6576
  var import_lucide_react8 = require("lucide-react");
6009
- var import_react12 = require("react");
6577
+ var import_react13 = require("react");
6010
6578
  var import_jsx_runtime37 = require("react/jsx-runtime");
6011
6579
  function SlippagePicker({
6012
6580
  slippage,
@@ -6015,7 +6583,7 @@ function SlippagePicker({
6015
6583
  onSelect,
6016
6584
  className
6017
6585
  }) {
6018
- const optionsId = (0, import_react12.useId)();
6586
+ const optionsId = (0, import_react13.useId)();
6019
6587
  return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(CoinListStyleScope, { children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
6020
6588
  "div",
6021
6589
  {
@@ -6874,10 +7442,10 @@ function ErrorView3({
6874
7442
  }
6875
7443
 
6876
7444
  // src/client/hooks/checkout/ondo/buy/useOndoBuyCheckoutViewModel.ts
6877
- var import_react21 = require("react");
7445
+ var import_react22 = require("react");
6878
7446
 
6879
7447
  // src/client/hooks/checkout/ondo/buy/amount/useOndoAmountViewModel.ts
6880
- var import_react14 = require("react");
7448
+ var import_react15 = require("react");
6881
7449
 
6882
7450
  // src/client/ui/format/asset-icon.ts
6883
7451
  var USDC_ICON_URL = AssetIconUrl(
@@ -6950,7 +7518,7 @@ var CheckoutAssetUi = {
6950
7518
  };
6951
7519
 
6952
7520
  // src/client/hooks/shared/erc20/useErc20TokenBalances.ts
6953
- var import_react13 = require("react");
7521
+ var import_react14 = require("react");
6954
7522
  var ERC20_BALANCE_POLL_INTERVAL_MS = 15e3;
6955
7523
  function useErc20TokenBalances(options) {
6956
7524
  const {
@@ -6961,12 +7529,12 @@ function useErc20TokenBalances(options) {
6961
7529
  enabled
6962
7530
  } = options;
6963
7531
  const { coinlist, isReady } = useCoinList();
6964
- const [balances, setBalances] = (0, import_react13.useState)(/* @__PURE__ */ new Map());
6965
- const [isLoading, setIsLoading] = (0, import_react13.useState)(true);
6966
- const fetchIdRef = (0, import_react13.useRef)(0);
6967
- const isFetchingRef = (0, import_react13.useRef)(false);
7532
+ const [balances, setBalances] = (0, import_react14.useState)(/* @__PURE__ */ new Map());
7533
+ const [isLoading, setIsLoading] = (0, import_react14.useState)(true);
7534
+ const fetchIdRef = (0, import_react14.useRef)(0);
7535
+ const isFetchingRef = (0, import_react14.useRef)(false);
6968
7536
  const assetsKey = assets.join(",");
6969
- (0, import_react13.useEffect)(() => {
7537
+ (0, import_react14.useEffect)(() => {
6970
7538
  if (!isReady) return;
6971
7539
  if (!enabled) {
6972
7540
  setIsLoading(false);
@@ -7031,13 +7599,13 @@ function useOndoAmountViewModel({
7031
7599
  }) {
7032
7600
  const { coinlist } = useCoinList();
7033
7601
  const locale = useLocale();
7034
- const [amountInput, setAmountInput] = (0, import_react14.useState)("");
7035
- const [selectedAsset, setSelectedAsset] = (0, import_react14.useState)(
7602
+ const [amountInput, setAmountInput] = (0, import_react15.useState)("");
7603
+ const [selectedAsset, setSelectedAsset] = (0, import_react15.useState)(
7036
7604
  ONDO_SUPPORTED_INPUT_ASSETS[0]
7037
7605
  );
7038
- const [error, setError] = (0, import_react14.useState)(null);
7039
- const [phase, setPhase] = (0, import_react14.useState)(null);
7040
- const preparationIdRef = (0, import_react14.useRef)(0);
7606
+ const [error, setError] = (0, import_react15.useState)(null);
7607
+ const [phase, setPhase] = (0, import_react15.useState)(null);
7608
+ const preparationIdRef = (0, import_react15.useRef)(0);
7041
7609
  const isActive = stepInput.type === "active";
7042
7610
  const networkName = getNetworkName(chain);
7043
7611
  const marketClosed = isActive && stepInput.tradingStatus?.type === "not-tradable";
@@ -7047,7 +7615,7 @@ function useOndoAmountViewModel({
7047
7615
  assets: ONDO_SUPPORTED_INPUT_ASSETS,
7048
7616
  enabled: isActive
7049
7617
  });
7050
- (0, import_react14.useEffect)(() => {
7618
+ (0, import_react15.useEffect)(() => {
7051
7619
  if (stepInput.type === "incomplete") {
7052
7620
  ++preparationIdRef.current;
7053
7621
  setAmountInput("");
@@ -7325,10 +7893,10 @@ function toInputAssetUi({
7325
7893
  }
7326
7894
 
7327
7895
  // src/client/hooks/checkout/ondo/buy/review/useOndoReviewViewModel.ts
7328
- var import_react17 = require("react");
7896
+ var import_react18 = require("react");
7329
7897
 
7330
7898
  // src/client/hooks/checkout/ondo/shared/data/useOndoSwapTransaction.ts
7331
- var import_react15 = require("react");
7899
+ var import_react16 = require("react");
7332
7900
 
7333
7901
  // src/client/hooks/checkout/ondo/shared/data/ondo-load-error.ts
7334
7902
  function ondoLoadErrorReason(error) {
@@ -7339,7 +7907,8 @@ function ondoLoadErrorReason(error) {
7339
7907
  function useOndoSwapTransaction(options) {
7340
7908
  const { request, data, enabled } = options;
7341
7909
  const { coinlist, isReady } = useCoinList();
7342
- const [state, setState] = (0, import_react15.useState)(
7910
+ const log = useLogger("useOndoSwapTransaction");
7911
+ const [state, setState] = (0, import_react16.useState)(
7343
7912
  () => data === void 0 ? { type: "LOADING" } : {
7344
7913
  type: "CONTENT",
7345
7914
  transaction: data,
@@ -7347,12 +7916,12 @@ function useOndoSwapTransaction(options) {
7347
7916
  refreshError: null
7348
7917
  }
7349
7918
  );
7350
- const fetchIdRef = (0, import_react15.useRef)(0);
7351
- const isFetchingRef = (0, import_react15.useRef)(false);
7919
+ const fetchIdRef = (0, import_react16.useRef)(0);
7920
+ const isFetchingRef = (0, import_react16.useRef)(false);
7352
7921
  const requestKey = request === null ? null : stableKey(request);
7353
- const requestRef = (0, import_react15.useRef)(request);
7922
+ const requestRef = (0, import_react16.useRef)(request);
7354
7923
  requestRef.current = request;
7355
- const build = (0, import_react15.useCallback)(async () => {
7924
+ const build = (0, import_react16.useCallback)(async () => {
7356
7925
  const params = requestRef.current;
7357
7926
  if (!isReady || !enabled || params === null) return;
7358
7927
  if (isFetchingRef.current) return;
@@ -7364,6 +7933,10 @@ function useOndoSwapTransaction(options) {
7364
7933
  try {
7365
7934
  const transaction = await coinlist.ondo.buildSwapTransaction(params);
7366
7935
  if (currentFetchId !== fetchIdRef.current) return;
7936
+ log.debug(() => ({
7937
+ msg: "settled",
7938
+ fields: { state: "CONTENT" }
7939
+ }));
7367
7940
  setState({
7368
7941
  type: "CONTENT",
7369
7942
  transaction,
@@ -7373,14 +7946,18 @@ function useOndoSwapTransaction(options) {
7373
7946
  } catch (error) {
7374
7947
  if (currentFetchId !== fetchIdRef.current) return;
7375
7948
  const reason = ondoLoadErrorReason(error);
7949
+ log.failure(
7950
+ () => ({ msg: "settled", fields: { state: "ERROR", reason } }),
7951
+ error
7952
+ );
7376
7953
  setState(
7377
7954
  (previous) => previous.type === "CONTENT" ? { ...previous, isRefreshing: false, refreshError: reason } : { type: "ERROR", reason }
7378
7955
  );
7379
7956
  } finally {
7380
7957
  isFetchingRef.current = false;
7381
7958
  }
7382
- }, [coinlist, isReady, enabled]);
7383
- (0, import_react15.useEffect)(() => {
7959
+ }, [coinlist, isReady, enabled, log]);
7960
+ (0, import_react16.useEffect)(() => {
7384
7961
  if (data === void 0) return;
7385
7962
  ++fetchIdRef.current;
7386
7963
  setState({
@@ -7391,14 +7968,14 @@ function useOndoSwapTransaction(options) {
7391
7968
  });
7392
7969
  }, [data]);
7393
7970
  const hasSeed = data !== void 0;
7394
- (0, import_react15.useEffect)(() => {
7971
+ (0, import_react16.useEffect)(() => {
7395
7972
  if (hasSeed || requestKey === null) return;
7396
7973
  build();
7397
7974
  return () => {
7398
7975
  ++fetchIdRef.current;
7399
7976
  };
7400
7977
  }, [build, requestKey, hasSeed]);
7401
- const refetch = (0, import_react15.useCallback)(() => {
7978
+ const refetch = (0, import_react16.useCallback)(() => {
7402
7979
  build();
7403
7980
  }, [build]);
7404
7981
  return { state, refetch };
@@ -7414,7 +7991,7 @@ function stableKey(request) {
7414
7991
  }
7415
7992
 
7416
7993
  // src/client/ui/hooks/useCountdown.ts
7417
- var import_react16 = require("react");
7994
+ var import_react17 = require("react");
7418
7995
  var DEFAULT_TICK_MS = 1e3;
7419
7996
  function useCountdown({
7420
7997
  until,
@@ -7422,8 +7999,8 @@ function useCountdown({
7422
7999
  enabled = true
7423
8000
  }) {
7424
8001
  const untilMs = until?.getTime() ?? null;
7425
- const [, tick] = (0, import_react16.useReducer)(nextTick, 0);
7426
- (0, import_react16.useEffect)(() => {
8002
+ const [, tick] = (0, import_react17.useReducer)(nextTick, 0);
8003
+ (0, import_react17.useEffect)(() => {
7427
8004
  if (untilMs === null || !enabled || remainingSeconds(untilMs) === 0) return;
7428
8005
  const interval = setInterval(() => {
7429
8006
  tick();
@@ -7451,8 +8028,8 @@ function useOndoReviewViewModel({
7451
8028
  }) {
7452
8029
  const { coinlist } = useCoinList();
7453
8030
  const locale = useLocale();
7454
- const [phase, setPhase] = (0, import_react17.useState)(null);
7455
- const [error, setError] = (0, import_react17.useState)(null);
8031
+ const [phase, setPhase] = (0, import_react18.useState)(null);
8032
+ const [error, setError] = (0, import_react18.useState)(null);
7456
8033
  const isActive = stepInput.type === "active";
7457
8034
  const { state: transactionState, refetch } = useOndoSwapTransaction({
7458
8035
  request: isActive ? {
@@ -7464,7 +8041,7 @@ function useOndoReviewViewModel({
7464
8041
  data: isActive ? stepInput.transaction : void 0,
7465
8042
  enabled: isActive
7466
8043
  });
7467
- (0, import_react17.useEffect)(() => {
8044
+ (0, import_react18.useEffect)(() => {
7468
8045
  if (stepInput.type === "incomplete") setError(null);
7469
8046
  }, [stepInput.type]);
7470
8047
  const transaction = transactionState.type === "CONTENT" ? transactionState.transaction : null;
@@ -7708,7 +8285,7 @@ function toMarketUi(state) {
7708
8285
  }
7709
8286
 
7710
8287
  // src/client/hooks/checkout/ondo/buy/wallet/useOndoWalletSelectViewModel.ts
7711
- var import_react18 = require("react");
8288
+ var import_react19 = require("react");
7712
8289
  var CONNECT_FAILED = "Could not connect that wallet. Please try again.";
7713
8290
  function useOndoWalletSelectViewModel({
7714
8291
  stepInput,
@@ -7717,8 +8294,9 @@ function useOndoWalletSelectViewModel({
7717
8294
  onComplete,
7718
8295
  onEdit
7719
8296
  }) {
7720
- const [selected, setSelected] = (0, import_react18.useState)(null);
7721
- const [error, setError] = (0, import_react18.useState)(null);
8297
+ const log = useLogger("useOndoWalletSelectViewModel");
8298
+ const [selected, setSelected] = (0, import_react19.useState)(null);
8299
+ const [error, setError] = (0, import_react19.useState)(null);
7722
8300
  const networkName = getNetworkName(chain);
7723
8301
  const selectedWallet = resolveWallet(wallets, selected);
7724
8302
  const uiState = () => {
@@ -7761,7 +8339,11 @@ function useOndoWalletSelectViewModel({
7761
8339
  setError(null);
7762
8340
  try {
7763
8341
  await wallets.connectExternal();
7764
- } catch {
8342
+ } catch (error2) {
8343
+ log.failure(
8344
+ () => ({ msg: "the host connectExternal handler threw" }),
8345
+ error2
8346
+ );
7765
8347
  setError(CONNECT_FAILED);
7766
8348
  return;
7767
8349
  }
@@ -7844,7 +8426,7 @@ function toConfirmedWalletUi(wallets, wallet) {
7844
8426
  }
7845
8427
 
7846
8428
  // src/client/hooks/checkout/ondo/shared/data/useOndoPrice.ts
7847
- var import_react19 = require("react");
8429
+ var import_react20 = require("react");
7848
8430
  var LOADING = { type: "LOADING" };
7849
8431
  function useOndoPrice(options) {
7850
8432
  const {
@@ -7856,13 +8438,15 @@ function useOndoPrice(options) {
7856
8438
  enabled
7857
8439
  } = options;
7858
8440
  const { coinlist, isReady } = useCoinList();
7859
- const [state, setState] = (0, import_react19.useState)(
8441
+ const log = useLogger("useOndoPrice");
8442
+ const [state, setState] = (0, import_react20.useState)(
7860
8443
  () => data === void 0 ? LOADING : { type: "CONTENT", quote: data, isRefreshing: false }
7861
8444
  );
7862
- const fetchIdRef = (0, import_react19.useRef)(0);
7863
- const isFetchingRef = (0, import_react19.useRef)(false);
8445
+ const fetchIdRef = (0, import_react20.useRef)(0);
8446
+ const isFetchingRef = (0, import_react20.useRef)(false);
8447
+ const hasQuoteRef = (0, import_react20.useRef)(data !== void 0);
7864
8448
  const sizeKey = quoteSizeKey(size);
7865
- (0, import_react19.useEffect)(() => {
8449
+ (0, import_react20.useEffect)(() => {
7866
8450
  if (!isReady || !enabled) return;
7867
8451
  const size2 = quoteSizeFromKey(sizeKey);
7868
8452
  const currentFetchId = ++fetchIdRef.current;
@@ -7876,11 +8460,31 @@ function useOndoPrice(options) {
7876
8460
  try {
7877
8461
  const quote = await coinlist.ondo.getQuote({ symbol, side, ...size2 });
7878
8462
  if (currentFetchId !== fetchIdRef.current) return;
8463
+ log.debug(() => ({
8464
+ msg: "settled",
8465
+ fields: { state: "CONTENT" }
8466
+ }));
8467
+ hasQuoteRef.current = true;
7879
8468
  setState({ type: "CONTENT", quote, isRefreshing: false });
7880
8469
  } catch (error) {
7881
8470
  if (currentFetchId !== fetchIdRef.current) return;
8471
+ const reason = ondoLoadErrorReason(error);
8472
+ if (hasQuoteRef.current) {
8473
+ log.warning(
8474
+ () => ({
8475
+ msg: "poll failed; keeping the last quote",
8476
+ fields: { reason }
8477
+ }),
8478
+ error
8479
+ );
8480
+ } else {
8481
+ log.failure(
8482
+ () => ({ msg: "settled", fields: { state: "ERROR", reason } }),
8483
+ error
8484
+ );
8485
+ }
7882
8486
  setState(
7883
- (previous) => previous.type === "CONTENT" ? { ...previous, isRefreshing: false } : { type: "ERROR", reason: ondoLoadErrorReason(error) }
8487
+ (previous) => previous.type === "CONTENT" ? { ...previous, isRefreshing: false } : { type: "ERROR", reason }
7884
8488
  );
7885
8489
  } finally {
7886
8490
  if (currentFetchId === fetchIdRef.current) {
@@ -7894,7 +8498,7 @@ function useOndoPrice(options) {
7894
8498
  clearInterval(interval);
7895
8499
  ++fetchIdRef.current;
7896
8500
  };
7897
- }, [coinlist, isReady, enabled, symbol, side, sizeKey, pollIntervalMs]);
8501
+ }, [coinlist, isReady, enabled, symbol, side, sizeKey, pollIntervalMs, log]);
7898
8502
  return { state };
7899
8503
  }
7900
8504
  function quoteSizeKey(size) {
@@ -7915,7 +8519,7 @@ function quoteSizeFromKey(key) {
7915
8519
  }
7916
8520
 
7917
8521
  // src/client/hooks/checkout/ondo/shared/data/useOndoTradingStatus.ts
7918
- var import_react20 = require("react");
8522
+ var import_react21 = require("react");
7919
8523
  var LOADING2 = { type: "LOADING" };
7920
8524
  function useOndoTradingStatus(options) {
7921
8525
  const {
@@ -7926,12 +8530,14 @@ function useOndoTradingStatus(options) {
7926
8530
  enabled
7927
8531
  } = options;
7928
8532
  const { coinlist, isReady } = useCoinList();
7929
- const [state, setState] = (0, import_react20.useState)(
8533
+ const log = useLogger("useOndoTradingStatus");
8534
+ const [state, setState] = (0, import_react21.useState)(
7930
8535
  () => data === void 0 ? LOADING2 : { type: "CONTENT", status: data }
7931
8536
  );
7932
- const fetchIdRef = (0, import_react20.useRef)(0);
7933
- const isFetchingRef = (0, import_react20.useRef)(false);
7934
- (0, import_react20.useEffect)(() => {
8537
+ const fetchIdRef = (0, import_react21.useRef)(0);
8538
+ const isFetchingRef = (0, import_react21.useRef)(false);
8539
+ const hasStatusRef = (0, import_react21.useRef)(data !== void 0);
8540
+ (0, import_react21.useEffect)(() => {
7935
8541
  if (!isReady || !enabled) return;
7936
8542
  const currentFetchId = ++fetchIdRef.current;
7937
8543
  isFetchingRef.current = false;
@@ -7941,11 +8547,31 @@ function useOndoTradingStatus(options) {
7941
8547
  try {
7942
8548
  const status = await coinlist.ondo.getTradingStatus({ symbol, side });
7943
8549
  if (currentFetchId !== fetchIdRef.current) return;
8550
+ log.debug(() => ({
8551
+ msg: "settled",
8552
+ fields: { state: "CONTENT", status: status.type }
8553
+ }));
8554
+ hasStatusRef.current = true;
7944
8555
  setState({ type: "CONTENT", status });
7945
8556
  } catch (error) {
7946
8557
  if (currentFetchId !== fetchIdRef.current) return;
8558
+ const reason = ondoLoadErrorReason(error);
8559
+ if (hasStatusRef.current) {
8560
+ log.warning(
8561
+ () => ({
8562
+ msg: "poll failed; keeping the last status",
8563
+ fields: { reason }
8564
+ }),
8565
+ error
8566
+ );
8567
+ } else {
8568
+ log.failure(
8569
+ () => ({ msg: "settled", fields: { state: "ERROR", reason } }),
8570
+ error
8571
+ );
8572
+ }
7947
8573
  setState(
7948
- (previous) => previous.type === "CONTENT" ? previous : { type: "ERROR", reason: ondoLoadErrorReason(error) }
8574
+ (previous) => previous.type === "CONTENT" ? previous : { type: "ERROR", reason }
7949
8575
  );
7950
8576
  } finally {
7951
8577
  if (currentFetchId === fetchIdRef.current) {
@@ -7959,7 +8585,7 @@ function useOndoTradingStatus(options) {
7959
8585
  clearInterval(interval);
7960
8586
  ++fetchIdRef.current;
7961
8587
  };
7962
- }, [coinlist, isReady, enabled, symbol, side, pollIntervalMs]);
8588
+ }, [coinlist, isReady, enabled, symbol, side, pollIntervalMs, log]);
7963
8589
  return { state };
7964
8590
  }
7965
8591
 
@@ -7973,8 +8599,8 @@ function useOndoBuyCheckoutViewModel({
7973
8599
  onOrderConfirmed
7974
8600
  }) {
7975
8601
  const locale = useLocale();
7976
- const [step, setStep] = (0, import_react21.useState)({ type: "wallet" });
7977
- const [orderConfirmed, setOrderConfirmed] = (0, import_react21.useState)({ type: "hidden" });
8602
+ const [step, setStep] = (0, import_react22.useState)({ type: "wallet" });
8603
+ const [orderConfirmed, setOrderConfirmed] = (0, import_react22.useState)({ type: "hidden" });
7978
8604
  const { state: priceState } = useOndoPrice({
7979
8605
  symbol: ondoSymbol,
7980
8606
  side: "buy",
@@ -8161,10 +8787,10 @@ function toOrderConfirmedUi({
8161
8787
  }
8162
8788
 
8163
8789
  // src/client/hooks/checkout/superstate/swap/useSuperstateSwapCheckoutViewModel.ts
8164
- var import_react27 = require("react");
8790
+ var import_react28 = require("react");
8165
8791
 
8166
8792
  // src/client/hooks/checkout/superstate/swap/amount/useSuperstateAmountViewModel.ts
8167
- var import_react22 = require("react");
8793
+ var import_react23 = require("react");
8168
8794
  var NO_WALLET2 = EvmWalletAddress(
8169
8795
  "0x0000000000000000000000000000000000000000"
8170
8796
  );
@@ -8178,11 +8804,11 @@ function useSuperstateAmountViewModel({
8178
8804
  enabled = true
8179
8805
  }) {
8180
8806
  const locale = useLocale();
8181
- const [amountInput, setAmountInput] = (0, import_react22.useState)("");
8182
- const [selectedAsset, setSelectedAsset] = (0, import_react22.useState)(
8807
+ const [amountInput, setAmountInput] = (0, import_react23.useState)("");
8808
+ const [selectedAsset, setSelectedAsset] = (0, import_react23.useState)(
8183
8809
  SUPERSTATE_SUPPORTED_INPUT_ASSETS[0]
8184
8810
  );
8185
- const [error, setError] = (0, import_react22.useState)(null);
8811
+ const [error, setError] = (0, import_react23.useState)(null);
8186
8812
  const isActive = stepInput.type === "active";
8187
8813
  const networkName = getNetworkName(chain);
8188
8814
  const { balances, isLoading: balancesLoading } = useErc20TokenBalances({
@@ -8195,7 +8821,7 @@ function useSuperstateAmountViewModel({
8195
8821
  // on this step satisfies the first and not the second.
8196
8822
  enabled: enabled && isActive
8197
8823
  });
8198
- (0, import_react22.useEffect)(() => {
8824
+ (0, import_react23.useEffect)(() => {
8199
8825
  if (stepInput.type === "incomplete") {
8200
8826
  setAmountInput("");
8201
8827
  setSelectedAsset(SUPERSTATE_SUPPORTED_INPUT_ASSETS[0]);
@@ -8366,19 +8992,20 @@ function toInputAssetUi2({
8366
8992
  }
8367
8993
 
8368
8994
  // src/client/hooks/checkout/superstate/swap/data/useSwapOutputToken.ts
8369
- var import_react23 = require("react");
8995
+ var import_react24 = require("react");
8370
8996
  var LOADING_STATE = { type: "LOADING" };
8371
8997
  function useSwapOutputToken(options) {
8372
8998
  const { contractAddress, chain, enabled } = options;
8373
8999
  const { coinlist, isReady } = useCoinList();
8374
- const [outputTokenState, setOutputTokenState] = (0, import_react23.useState)(LOADING_STATE);
8375
- const [retryCount, setRetryCount] = (0, import_react23.useState)(0);
8376
- const fetchIdRef = (0, import_react23.useRef)(0);
8377
- const refetch = (0, import_react23.useCallback)(() => {
9000
+ const log = useLogger("useSwapOutputToken");
9001
+ const [outputTokenState, setOutputTokenState] = (0, import_react24.useState)(LOADING_STATE);
9002
+ const [retryCount, setRetryCount] = (0, import_react24.useState)(0);
9003
+ const fetchIdRef = (0, import_react24.useRef)(0);
9004
+ const refetch = (0, import_react24.useCallback)(() => {
8378
9005
  setOutputTokenState(LOADING_STATE);
8379
9006
  setRetryCount((count) => count + 1);
8380
9007
  }, []);
8381
- (0, import_react23.useEffect)(() => {
9008
+ (0, import_react24.useEffect)(() => {
8382
9009
  if (!enabled || !isReady) return;
8383
9010
  const currentFetchId = ++fetchIdRef.current;
8384
9011
  const load = async () => {
@@ -8388,9 +9015,17 @@ function useSwapOutputToken(options) {
8388
9015
  chain
8389
9016
  });
8390
9017
  if (currentFetchId !== fetchIdRef.current) return;
9018
+ log.debug(() => ({
9019
+ msg: "settled",
9020
+ fields: { state: "CONTENT", symbol: outputToken.symbol }
9021
+ }));
8391
9022
  setOutputTokenState({ type: "CONTENT", outputToken });
8392
- } catch {
9023
+ } catch (error) {
8393
9024
  if (currentFetchId !== fetchIdRef.current) return;
9025
+ log.failure(
9026
+ () => ({ msg: "settled", fields: { state: "ERROR" } }),
9027
+ error
9028
+ );
8394
9029
  setOutputTokenState({ type: "ERROR" });
8395
9030
  }
8396
9031
  };
@@ -8398,12 +9033,12 @@ function useSwapOutputToken(options) {
8398
9033
  return () => {
8399
9034
  ++fetchIdRef.current;
8400
9035
  };
8401
- }, [coinlist, isReady, contractAddress, chain, enabled, retryCount]);
9036
+ }, [coinlist, isReady, contractAddress, chain, enabled, retryCount, log]);
8402
9037
  return { outputTokenState, refetch };
8403
9038
  }
8404
9039
 
8405
9040
  // src/client/hooks/checkout/superstate/swap/data/useSwapQuote.ts
8406
- var import_react24 = require("react");
9041
+ var import_react25 = require("react");
8407
9042
  function useSwapQuote(options) {
8408
9043
  const {
8409
9044
  contractAddress,
@@ -8415,13 +9050,14 @@ function useSwapQuote(options) {
8415
9050
  enabled
8416
9051
  } = options;
8417
9052
  const { coinlist, isReady } = useCoinList();
8418
- const [quote, setQuote] = (0, import_react24.useState)(null);
8419
- const [isLoading, setIsLoading] = (0, import_react24.useState)(true);
8420
- const [isRefreshing, setIsRefreshing] = (0, import_react24.useState)(false);
8421
- const isFetchingRef = (0, import_react24.useRef)(false);
8422
- const hasQuoteRef = (0, import_react24.useRef)(false);
8423
- const fetchIdRef = (0, import_react24.useRef)(0);
8424
- (0, import_react24.useEffect)(() => {
9053
+ const log = useLogger("useSwapQuote");
9054
+ const [quote, setQuote] = (0, import_react25.useState)(null);
9055
+ const [isLoading, setIsLoading] = (0, import_react25.useState)(true);
9056
+ const [isRefreshing, setIsRefreshing] = (0, import_react25.useState)(false);
9057
+ const isFetchingRef = (0, import_react25.useRef)(false);
9058
+ const hasQuoteRef = (0, import_react25.useRef)(false);
9059
+ const fetchIdRef = (0, import_react25.useRef)(0);
9060
+ (0, import_react25.useEffect)(() => {
8425
9061
  if (!isReady) return;
8426
9062
  if (!enabled) {
8427
9063
  setIsLoading(false);
@@ -8455,7 +9091,11 @@ function useSwapQuote(options) {
8455
9091
  hasQuoteRef.current = true;
8456
9092
  setIsLoading(false);
8457
9093
  }
8458
- } catch {
9094
+ } catch (error) {
9095
+ log.warning(
9096
+ () => ({ msg: "poll failed; retrying on the next tick" }),
9097
+ error
9098
+ );
8459
9099
  } finally {
8460
9100
  if (currentFetchId === fetchIdRef.current) {
8461
9101
  isFetchingRef.current = false;
@@ -8480,13 +9120,14 @@ function useSwapQuote(options) {
8480
9120
  inputTokenAddress,
8481
9121
  outputTokenDecimals,
8482
9122
  pollIntervalMs,
8483
- enabled
9123
+ enabled,
9124
+ log
8484
9125
  ]);
8485
9126
  return { quote, isLoading, isRefreshing };
8486
9127
  }
8487
9128
 
8488
9129
  // src/client/hooks/checkout/superstate/swap/review/useSuperstateReviewViewModel.ts
8489
- var import_react25 = require("react");
9130
+ var import_react26 = require("react");
8490
9131
  function useSuperstateReviewViewModel({
8491
9132
  stepInput,
8492
9133
  contractAddress,
@@ -8496,11 +9137,11 @@ function useSuperstateReviewViewModel({
8496
9137
  }) {
8497
9138
  const { coinlist, isReady } = useCoinList();
8498
9139
  const locale = useLocale();
8499
- const [slippageBps, setSlippageBps] = (0, import_react25.useState)(DEFAULT_SLIPPAGE_BPS);
8500
- const [slippageExpanded, setSlippageExpanded] = (0, import_react25.useState)(false);
8501
- const [phase, setPhase] = (0, import_react25.useState)(null);
8502
- const [error, setError] = (0, import_react25.useState)(null);
8503
- (0, import_react25.useEffect)(() => {
9140
+ const [slippageBps, setSlippageBps] = (0, import_react26.useState)(DEFAULT_SLIPPAGE_BPS);
9141
+ const [slippageExpanded, setSlippageExpanded] = (0, import_react26.useState)(false);
9142
+ const [phase, setPhase] = (0, import_react26.useState)(null);
9143
+ const [error, setError] = (0, import_react26.useState)(null);
9144
+ (0, import_react26.useEffect)(() => {
8504
9145
  if (stepInput.type === "incomplete") {
8505
9146
  setSlippageBps(DEFAULT_SLIPPAGE_BPS);
8506
9147
  setSlippageExpanded(false);
@@ -8817,7 +9458,7 @@ function priceUi(quote, outputToken, locale) {
8817
9458
  }
8818
9459
 
8819
9460
  // src/client/hooks/checkout/superstate/swap/wallet/useSuperstateWalletViewModel.ts
8820
- var import_react26 = require("react");
9461
+ var import_react27 = require("react");
8821
9462
  var CONNECT_FAILED2 = "Could not connect that wallet. Please try again.";
8822
9463
  function useSuperstateWalletViewModel({
8823
9464
  stepInput,
@@ -8829,12 +9470,13 @@ function useSuperstateWalletViewModel({
8829
9470
  onEdit
8830
9471
  }) {
8831
9472
  const { coinlist, isReady } = useCoinList();
8832
- const [selected, setSelected] = (0, import_react26.useState)(null);
8833
- const [phase, setPhase] = (0, import_react26.useState)(null);
8834
- const [error, setError] = (0, import_react26.useState)(null);
9473
+ const log = useLogger("useSuperstateWalletViewModel");
9474
+ const [selected, setSelected] = (0, import_react27.useState)(null);
9475
+ const [phase, setPhase] = (0, import_react27.useState)(null);
9476
+ const [error, setError] = (0, import_react27.useState)(null);
8835
9477
  const networkName = getNetworkName(chain);
8836
9478
  const selectedWallet = resolveWallet2(wallets, selected);
8837
- (0, import_react26.useEffect)(() => {
9479
+ (0, import_react27.useEffect)(() => {
8838
9480
  if (stepInput.type === "completed") {
8839
9481
  setPhase(null);
8840
9482
  setError(null);
@@ -8909,7 +9551,11 @@ function useSuperstateWalletViewModel({
8909
9551
  setError(null);
8910
9552
  try {
8911
9553
  await wallets.connectExternal();
8912
- } catch {
9554
+ } catch (error2) {
9555
+ log.failure(
9556
+ () => ({ msg: "the host connectExternal handler threw" }),
9557
+ error2
9558
+ );
8913
9559
  setError(CONNECT_FAILED2);
8914
9560
  return;
8915
9561
  }
@@ -9050,8 +9696,8 @@ function useSuperstateSwapCheckoutViewModel({
9050
9696
  const locale = useLocale();
9051
9697
  const contractAddress = superstateSwapContractAddress(chain);
9052
9698
  const assetIconUrl = offerIconUrl(offer);
9053
- const [step, setStep] = (0, import_react27.useState)({ type: "wallet" });
9054
- const [orderConfirmed, setOrderConfirmed] = (0, import_react27.useState)({ type: "hidden" });
9699
+ const [step, setStep] = (0, import_react28.useState)({ type: "wallet" });
9700
+ const [orderConfirmed, setOrderConfirmed] = (0, import_react28.useState)({ type: "hidden" });
9055
9701
  const live = enabled && contractAddress !== null;
9056
9702
  const contract = contractAddress ?? NO_CONTRACT;
9057
9703
  const { outputTokenState, refetch: refetchOutputToken } = useSwapOutputToken({
@@ -9606,18 +10252,19 @@ function EmptyState() {
9606
10252
  }
9607
10253
 
9608
10254
  // src/client/hooks/offers/grid/useOffersGridViewModel.ts
9609
- var import_react29 = require("react");
10255
+ var import_react30 = require("react");
9610
10256
 
9611
10257
  // src/client/hooks/offers/data/useOffers.ts
9612
- var import_react28 = require("react");
10258
+ var import_react29 = require("react");
9613
10259
  var LOADING_STATE2 = { type: "LOADING" };
9614
10260
  function useOffers(options = {}) {
9615
10261
  const { coinlist, isReady } = useCoinList();
10262
+ const log = useLogger("useOffers");
9616
10263
  const { data: serverOffers } = options;
9617
- const [offersState, setOffersState] = (0, import_react28.useState)(
10264
+ const [offersState, setOffersState] = (0, import_react29.useState)(
9618
10265
  serverOffers !== void 0 ? { type: "CONTENT", offers: serverOffers } : LOADING_STATE2
9619
10266
  );
9620
- (0, import_react28.useEffect)(() => {
10267
+ (0, import_react29.useEffect)(() => {
9621
10268
  let isCancelled = false;
9622
10269
  if (!isReady) {
9623
10270
  if (serverOffers === void 0) {
@@ -9635,18 +10282,26 @@ function useOffers(options = {}) {
9635
10282
  setOffersState(LOADING_STATE2);
9636
10283
  coinlist.offers.list().then((offers) => {
9637
10284
  if (!isCancelled) {
10285
+ log.debug(() => ({
10286
+ msg: "settled",
10287
+ fields: { state: "CONTENT", count: offers.length }
10288
+ }));
9638
10289
  setOffersState({ type: "CONTENT", offers });
9639
10290
  }
9640
10291
  }).catch((error) => {
9641
10292
  if (!isCancelled) {
9642
10293
  const reason = error instanceof NotAuthenticatedError ? "not-authenticated" : "generic-error";
10294
+ log.failure(
10295
+ () => ({ msg: "settled", fields: { state: "ERROR", reason } }),
10296
+ error
10297
+ );
9643
10298
  setOffersState({ type: "ERROR", reason });
9644
10299
  }
9645
10300
  });
9646
10301
  return () => {
9647
10302
  isCancelled = true;
9648
10303
  };
9649
- }, [coinlist, isReady, serverOffers]);
10304
+ }, [coinlist, isReady, serverOffers, log]);
9650
10305
  return { offersState };
9651
10306
  }
9652
10307
 
@@ -9678,11 +10333,11 @@ function useOffersGridViewModel(options = {}) {
9678
10333
  const { data, onOfferClick } = options;
9679
10334
  const { offersState } = useOffers({ data });
9680
10335
  const locale = useLocale();
9681
- const state = (0, import_react29.useMemo)(
10336
+ const state = (0, import_react30.useMemo)(
9682
10337
  () => toUiState(offersState, locale, onOfferClick !== void 0),
9683
10338
  [offersState, locale, onOfferClick]
9684
10339
  );
9685
- const onEvent = (0, import_react29.useCallback)(
10340
+ const onEvent = (0, import_react30.useCallback)(
9686
10341
  (event) => {
9687
10342
  switch (event.type) {
9688
10343
  case "ON_OFFER_CLICK": {
@@ -9745,13 +10400,13 @@ function OffersGridContainer({
9745
10400
  }
9746
10401
 
9747
10402
  // src/client/components/requirements/checklist/ConnectedWalletList.tsx
9748
- var import_react30 = require("react");
10403
+ var import_react31 = require("react");
9749
10404
  var import_jsx_runtime48 = require("react/jsx-runtime");
9750
10405
  function ConnectedWalletRow({
9751
10406
  wallet,
9752
10407
  onRemove
9753
10408
  }) {
9754
- const [state, setState] = (0, import_react30.useState)("idle");
10409
+ const [state, setState] = (0, import_react31.useState)("idle");
9755
10410
  const remove = async () => {
9756
10411
  if (!onRemove) return;
9757
10412
  setState("removing");
@@ -10321,23 +10976,24 @@ function toError(error) {
10321
10976
  }
10322
10977
 
10323
10978
  // src/client/hooks/requirements/identity-verification/useIdentityVerificationViewModel.ts
10324
- var import_react32 = require("react");
10979
+ var import_react33 = require("react");
10325
10980
 
10326
10981
  // src/client/hooks/requirements/data/useKycToken.ts
10327
- var import_react31 = require("react");
10982
+ var import_react32 = require("react");
10328
10983
  var IDLE_STATE = { type: "IDLE" };
10329
10984
  var LOADING_STATE3 = { type: "LOADING" };
10330
10985
  function useKycToken(levelName, reset) {
10331
10986
  const { coinlist } = useCoinList();
10332
- const [kycTokenState, setKycTokenState] = (0, import_react31.useState)(IDLE_STATE);
10333
- const resetPendingRef = (0, import_react31.useRef)(reset === true);
10334
- const tokenIssuedRef = (0, import_react31.useRef)(false);
10335
- (0, import_react31.useEffect)(() => {
10987
+ const log = useLogger("useKycToken");
10988
+ const [kycTokenState, setKycTokenState] = (0, import_react32.useState)(IDLE_STATE);
10989
+ const resetPendingRef = (0, import_react32.useRef)(reset === true);
10990
+ const tokenIssuedRef = (0, import_react32.useRef)(false);
10991
+ (0, import_react32.useEffect)(() => {
10336
10992
  if (!tokenIssuedRef.current) {
10337
10993
  resetPendingRef.current = reset === true;
10338
10994
  }
10339
10995
  }, [reset]);
10340
- const fetchToken = (0, import_react31.useCallback)(async () => {
10996
+ const fetchToken = (0, import_react32.useCallback)(async () => {
10341
10997
  setKycTokenState(LOADING_STATE3);
10342
10998
  try {
10343
10999
  const kycToken = await coinlist.requirements.createKycToken({
@@ -10346,14 +11002,22 @@ function useKycToken(levelName, reset) {
10346
11002
  });
10347
11003
  resetPendingRef.current = false;
10348
11004
  tokenIssuedRef.current = true;
11005
+ log.debug(() => ({
11006
+ msg: "settled",
11007
+ fields: { state: "CONTENT" }
11008
+ }));
10349
11009
  setKycTokenState({ type: "CONTENT", token: kycToken.token });
10350
11010
  return kycToken.token;
10351
11011
  } catch (error) {
10352
11012
  const reason = error instanceof NotAuthenticatedError ? "not-authenticated" : "generic-error";
11013
+ log.failure(
11014
+ () => ({ msg: "settled", fields: { state: "ERROR", reason } }),
11015
+ error
11016
+ );
10353
11017
  setKycTokenState({ type: "ERROR", reason });
10354
11018
  throw error;
10355
11019
  }
10356
- }, [coinlist, levelName]);
11020
+ }, [coinlist, levelName, log]);
10357
11021
  return { kycTokenState, fetchToken };
10358
11022
  }
10359
11023
 
@@ -10363,8 +11027,8 @@ var GENERIC_ERROR_MESSAGE2 = "Unable to start identity verification right now. P
10363
11027
  function useIdentityVerificationViewModel(options = {}) {
10364
11028
  const { levelName, reset, locale, onSubmitted, onError } = options;
10365
11029
  const { kycTokenState, fetchToken } = useKycToken(levelName, reset);
10366
- const fetchedRef = (0, import_react32.useRef)(false);
10367
- (0, import_react32.useEffect)(() => {
11030
+ const fetchedRef = (0, import_react33.useRef)(false);
11031
+ (0, import_react33.useEffect)(() => {
10368
11032
  if (fetchedRef.current) {
10369
11033
  return;
10370
11034
  }
@@ -10372,7 +11036,7 @@ function useIdentityVerificationViewModel(options = {}) {
10372
11036
  fetchToken().catch(() => {
10373
11037
  });
10374
11038
  }, [fetchToken]);
10375
- const state = (0, import_react32.useMemo)(() => {
11039
+ const state = (0, import_react33.useMemo)(() => {
10376
11040
  switch (kycTokenState.type) {
10377
11041
  case "IDLE":
10378
11042
  case "LOADING":
@@ -10398,7 +11062,7 @@ function useIdentityVerificationViewModel(options = {}) {
10398
11062
  }
10399
11063
  }
10400
11064
  }, [kycTokenState, locale, fetchToken]);
10401
- const onEvent = (0, import_react32.useCallback)(
11065
+ const onEvent = (0, import_react33.useCallback)(
10402
11066
  (event) => {
10403
11067
  switch (event.type) {
10404
11068
  case "ON_RETRY":
@@ -10660,10 +11324,10 @@ function SignOnlyScreen({
10660
11324
  }
10661
11325
 
10662
11326
  // src/client/hooks/requirements/tax-document/useTaxDocumentModalViewModel.ts
10663
- var import_react34 = require("react");
11327
+ var import_react35 = require("react");
10664
11328
 
10665
11329
  // src/client/hooks/requirements/data/useTaxDocument.ts
10666
- var import_react33 = require("react");
11330
+ var import_react34 = require("react");
10667
11331
  var IDLE_SIGN = { type: "idle", error: null };
10668
11332
  var LOADING_STATE4 = { type: "LOADING" };
10669
11333
  var SIGN_FAILED_MESSAGE = "Unable to sign document. Please try again.";
@@ -10737,8 +11401,9 @@ function useTaxDocument({
10737
11401
  isOpen
10738
11402
  }) {
10739
11403
  const { coinlist, isReady } = useCoinList();
10740
- const [state, setState] = (0, import_react33.useState)(LOADING_STATE4);
10741
- (0, import_react33.useEffect)(() => {
11404
+ const log = useLogger("useTaxDocument");
11405
+ const [state, setState] = (0, import_react34.useState)(LOADING_STATE4);
11406
+ (0, import_react34.useEffect)(() => {
10742
11407
  let isCancelled = false;
10743
11408
  if (!isOpen) {
10744
11409
  return () => {
@@ -10768,16 +11433,18 @@ function useTaxDocument({
10768
11433
  });
10769
11434
  }).catch((error) => {
10770
11435
  if (isCancelled) return;
10771
- setState({
10772
- type: "ERROR",
10773
- reason: error instanceof NotAuthenticatedError ? "not-authenticated" : "generic-error"
10774
- });
11436
+ const reason = error instanceof NotAuthenticatedError ? "not-authenticated" : "generic-error";
11437
+ log.failure(
11438
+ () => ({ msg: "settled", fields: { state: "ERROR", reason } }),
11439
+ error
11440
+ );
11441
+ setState({ type: "ERROR", reason });
10775
11442
  });
10776
11443
  return () => {
10777
11444
  isCancelled = true;
10778
11445
  };
10779
- }, [coinlist, isReady, isOpen]);
10780
- const onEditField = (0, import_react33.useCallback)(
11446
+ }, [coinlist, isReady, isOpen, log]);
11447
+ const onEditField = (0, import_react34.useCallback)(
10781
11448
  (field, value) => {
10782
11449
  setState(
10783
11450
  (prev) => prev.type === "EDITING" ? { ...prev, fields: { ...prev.fields, [field]: value } } : prev
@@ -10785,7 +11452,7 @@ function useTaxDocument({
10785
11452
  },
10786
11453
  []
10787
11454
  );
10788
- const onStartEdit = (0, import_react33.useCallback)(() => {
11455
+ const onStartEdit = (0, import_react34.useCallback)(() => {
10789
11456
  setState(
10790
11457
  (prev) => prev.type === "REVIEW" ? {
10791
11458
  type: "EDITING",
@@ -10796,7 +11463,7 @@ function useTaxDocument({
10796
11463
  } : prev
10797
11464
  );
10798
11465
  }, []);
10799
- const onSaveEdit = (0, import_react33.useCallback)(() => {
11466
+ const onSaveEdit = (0, import_react34.useCallback)(() => {
10800
11467
  setState(
10801
11468
  (prev) => prev.type === "EDITING" ? {
10802
11469
  type: "REVIEW",
@@ -10807,7 +11474,7 @@ function useTaxDocument({
10807
11474
  } : prev
10808
11475
  );
10809
11476
  }, []);
10810
- const onCancelEdit = (0, import_react33.useCallback)(() => {
11477
+ const onCancelEdit = (0, import_react34.useCallback)(() => {
10811
11478
  setState(
10812
11479
  (prev) => prev.type === "EDITING" ? {
10813
11480
  type: "REVIEW",
@@ -10818,7 +11485,7 @@ function useTaxDocument({
10818
11485
  } : prev
10819
11486
  );
10820
11487
  }, []);
10821
- const onSign = (0, import_react33.useCallback)(() => {
11488
+ const onSign = (0, import_react34.useCallback)(() => {
10822
11489
  if (state.type !== "REVIEW" && state.type !== "SIGN_ONLY") return;
10823
11490
  if (state.type === "REVIEW" && state.fields.dob.trim() !== "" && !isValidUsDate(state.fields.dob)) {
10824
11491
  setState({
@@ -10833,12 +11500,13 @@ function useTaxDocument({
10833
11500
  fields: state.type === "REVIEW" ? toSubmissionFields(state.fields, state.addressParts) : {}
10834
11501
  }).then((submission) => {
10835
11502
  setState({ type: "SUBMITTED", submission });
10836
- }).catch(() => {
11503
+ }).catch((error) => {
11504
+ log.failure(() => ({ msg: "signing the tax document failed" }), error);
10837
11505
  setState(
10838
11506
  (prev) => prev.type === "REVIEW" || prev.type === "SIGN_ONLY" ? { ...prev, sign: { type: "idle", error: SIGN_FAILED_MESSAGE } } : prev
10839
11507
  );
10840
11508
  });
10841
- }, [state, coinlist]);
11509
+ }, [state, coinlist, log]);
10842
11510
  return { state, onEditField, onStartEdit, onSaveEdit, onCancelEdit, onSign };
10843
11511
  }
10844
11512
 
@@ -10859,19 +11527,19 @@ function useTaxDocumentModalViewModel({
10859
11527
  onSubmitted
10860
11528
  }) {
10861
11529
  const { state, onEditField, onStartEdit, onSaveEdit, onCancelEdit, onSign } = useTaxDocument({ isOpen });
10862
- (0, import_react34.useEffect)(() => {
11530
+ (0, import_react35.useEffect)(() => {
10863
11531
  if (state.type === "SUBMITTED") {
10864
11532
  onSubmitted?.(state.submission);
10865
11533
  onClose();
10866
11534
  }
10867
11535
  }, [state]);
10868
- const uiState = (0, import_react34.useMemo)(() => {
11536
+ const uiState = (0, import_react35.useMemo)(() => {
10869
11537
  if (!isOpen || state.type === "SUBMITTED") {
10870
11538
  return { type: "hidden" };
10871
11539
  }
10872
11540
  return { type: "content", title: toTitle(state), screen: toScreen(state) };
10873
11541
  }, [isOpen, state]);
10874
- const onEvent = (0, import_react34.useCallback)(
11542
+ const onEvent = (0, import_react35.useCallback)(
10875
11543
  (event) => {
10876
11544
  switch (event.type) {
10877
11545
  case "ON_CLOSE":
@@ -10977,14 +11645,14 @@ function TaxDocumentModalContainer({
10977
11645
  }
10978
11646
 
10979
11647
  // src/client/components/requirements/wallet/ConnectWalletModalView.tsx
10980
- var import_react35 = require("react");
11648
+ var import_react36 = require("react");
10981
11649
  var import_jsx_runtime57 = require("react/jsx-runtime");
10982
11650
  function ConnectWalletModalView({
10983
11651
  state,
10984
11652
  onEvent,
10985
11653
  className
10986
11654
  }) {
10987
- const titleId = (0, import_react35.useId)();
11655
+ const titleId = (0, import_react36.useId)();
10988
11656
  if (state.type === "hidden") {
10989
11657
  return null;
10990
11658
  }
@@ -11087,10 +11755,10 @@ function Screen2({
11087
11755
  }
11088
11756
 
11089
11757
  // src/client/hooks/requirements/wallet/useConnectWalletModalViewModel.ts
11090
- var import_react37 = require("react");
11758
+ var import_react38 = require("react");
11091
11759
 
11092
11760
  // src/client/hooks/requirements/data/useConnectWallet.ts
11093
- var import_react36 = require("react");
11761
+ var import_react37 = require("react");
11094
11762
 
11095
11763
  // src/client/core/wallets/connect-external-wallet.ts
11096
11764
  var DEFAULT_STATEMENT = "Sign this message to prove you own this wallet. This does not cost gas or move funds.";
@@ -11158,9 +11826,9 @@ async function connectExternalWalletFlow(params) {
11158
11826
  isCancelled,
11159
11827
  onProgress
11160
11828
  } = params;
11161
- const emit = (phase) => onProgress?.(phase);
11829
+ const emit2 = (phase) => onProgress?.(phase);
11162
11830
  const cancelled = () => isCancelled?.() ?? false;
11163
- emit("requesting-challenge");
11831
+ emit2("requesting-challenge");
11164
11832
  let challenge;
11165
11833
  try {
11166
11834
  challenge = await coinlist.wallets.createOwnershipChallenge(
@@ -11170,7 +11838,7 @@ async function connectExternalWalletFlow(params) {
11170
11838
  return { type: "error", error: classifyApiError(error) };
11171
11839
  }
11172
11840
  if (cancelled()) return { type: "cancelled" };
11173
- emit("signing-message");
11841
+ emit2("signing-message");
11174
11842
  let signature;
11175
11843
  try {
11176
11844
  signature = await wallet.signMessage(challenge.message);
@@ -11181,7 +11849,7 @@ async function connectExternalWalletFlow(params) {
11181
11849
  return { type: "error", error: flowError("unknown") };
11182
11850
  }
11183
11851
  if (cancelled()) return { type: "cancelled" };
11184
- emit("submitting-signature");
11852
+ emit2("submitting-signature");
11185
11853
  try {
11186
11854
  const binding = await coinlist.wallets.connectExternal({
11187
11855
  offerId,
@@ -11221,24 +11889,24 @@ function useConnectWallet({
11221
11889
  statement
11222
11890
  }) {
11223
11891
  const { coinlist } = useCoinList();
11224
- const [state, setState] = (0, import_react36.useState)(
11892
+ const [state, setState] = (0, import_react37.useState)(
11225
11893
  () => wallet ? { type: "READY", address: wallet.address, sign: IDLE_SIGN2 } : { type: "NEEDS_WALLET" }
11226
11894
  );
11227
- const attempt = (0, import_react36.useRef)(0);
11228
- (0, import_react36.useEffect)(() => {
11895
+ const attempt = (0, import_react37.useRef)(0);
11896
+ (0, import_react37.useEffect)(() => {
11229
11897
  attempt.current += 1;
11230
11898
  if (!isOpen) return;
11231
11899
  setState(
11232
11900
  wallet ? { type: "READY", address: wallet.address, sign: IDLE_SIGN2 } : { type: "NEEDS_WALLET" }
11233
11901
  );
11234
11902
  }, [isOpen, wallet?.address]);
11235
- (0, import_react36.useEffect)(
11903
+ (0, import_react37.useEffect)(
11236
11904
  () => () => {
11237
11905
  attempt.current += 1;
11238
11906
  },
11239
11907
  []
11240
11908
  );
11241
- const onSign = (0, import_react36.useCallback)(() => {
11909
+ const onSign = (0, import_react37.useCallback)(() => {
11242
11910
  if (!wallet || state.type !== "READY") return;
11243
11911
  attempt.current += 1;
11244
11912
  const gen = attempt.current;
@@ -11300,13 +11968,13 @@ function useConnectWalletModalViewModel({
11300
11968
  challengeType,
11301
11969
  statement
11302
11970
  });
11303
- (0, import_react37.useEffect)(() => {
11971
+ (0, import_react38.useEffect)(() => {
11304
11972
  if (state.type === "CONNECTED") {
11305
11973
  onConnected?.(state.binding);
11306
11974
  onClose();
11307
11975
  }
11308
11976
  }, [state]);
11309
- const uiState = (0, import_react37.useMemo)(() => {
11977
+ const uiState = (0, import_react38.useMemo)(() => {
11310
11978
  if (!isOpen || state.type === "CONNECTED") {
11311
11979
  return { type: "hidden" };
11312
11980
  }
@@ -11331,7 +11999,7 @@ function useConnectWalletModalViewModel({
11331
11999
  canRequestConnect
11332
12000
  };
11333
12001
  }, [isOpen, state, onRequestConnect]);
11334
- const onEvent = (0, import_react37.useCallback)(
12002
+ const onEvent = (0, import_react38.useCallback)(
11335
12003
  (event) => {
11336
12004
  switch (event.type) {
11337
12005
  case "ON_CLOSE":
@@ -11372,7 +12040,7 @@ function ConnectWalletModalContainer({
11372
12040
  }
11373
12041
 
11374
12042
  // src/client/hooks/requirements/checklist/useRequirementsChecklistViewModel.ts
11375
- var import_react40 = require("react");
12043
+ var import_react41 = require("react");
11376
12044
 
11377
12045
  // src/client/hooks/requirements/checklist/useRequirementsChecklistViewModel.types.ts
11378
12046
  var RequirementItemUi = {
@@ -11426,7 +12094,7 @@ var ChecklistStatus = {
11426
12094
  };
11427
12095
 
11428
12096
  // src/client/hooks/requirements/data/useOptionAddresses.ts
11429
- var import_react38 = require("react");
12097
+ var import_react39 = require("react");
11430
12098
  var LOADING_STATE5 = { type: "LOADING" };
11431
12099
  var EMPTY_STATE = {
11432
12100
  type: "CONTENT",
@@ -11434,20 +12102,21 @@ var EMPTY_STATE = {
11434
12102
  };
11435
12103
  function useOptionAddresses(offerId, offerOptionId, options = {}) {
11436
12104
  const { coinlist, isReady } = useCoinList();
12105
+ const log = useLogger("useOptionAddresses");
11437
12106
  const { data, enabled = true } = options;
11438
- const [addressesState, setAddressesState] = (0, import_react38.useState)(
12107
+ const [addressesState, setAddressesState] = (0, import_react39.useState)(
11439
12108
  data !== void 0 ? { type: "CONTENT", addresses: data } : LOADING_STATE5
11440
12109
  );
11441
- const [fetchKey, setFetchKey] = (0, import_react38.useState)(0);
11442
- const refetch = (0, import_react38.useCallback)(() => setFetchKey((k) => k + 1), []);
11443
- const disconnect = (0, import_react38.useCallback)(
12110
+ const [fetchKey, setFetchKey] = (0, import_react39.useState)(0);
12111
+ const refetch = (0, import_react39.useCallback)(() => setFetchKey((k) => k + 1), []);
12112
+ const disconnect = (0, import_react39.useCallback)(
11444
12113
  async (addressId) => {
11445
12114
  await coinlist.wallets.remove({ offerId, addressId });
11446
12115
  refetch();
11447
12116
  },
11448
12117
  [coinlist, offerId, refetch]
11449
12118
  );
11450
- (0, import_react38.useEffect)(() => {
12119
+ (0, import_react39.useEffect)(() => {
11451
12120
  let isCancelled = false;
11452
12121
  if (!enabled) {
11453
12122
  setAddressesState(
@@ -11479,33 +12148,42 @@ function useOptionAddresses(offerId, offerOptionId, options = {}) {
11479
12148
  setAddressesState(LOADING_STATE5);
11480
12149
  coinlist.wallets.list({ offerId, offerOptionId }).then((addresses) => {
11481
12150
  if (!isCancelled) {
12151
+ log.debug(() => ({
12152
+ msg: "settled",
12153
+ fields: { state: "CONTENT", count: addresses.length }
12154
+ }));
11482
12155
  setAddressesState({ type: "CONTENT", addresses });
11483
12156
  }
11484
12157
  }).catch((error) => {
11485
12158
  if (!isCancelled) {
11486
12159
  const reason = error instanceof NotAuthenticatedError ? "not-authenticated" : "generic-error";
12160
+ log.failure(
12161
+ () => ({ msg: "settled", fields: { state: "ERROR", reason } }),
12162
+ error
12163
+ );
11487
12164
  setAddressesState({ type: "ERROR", reason });
11488
12165
  }
11489
12166
  });
11490
12167
  return () => {
11491
12168
  isCancelled = true;
11492
12169
  };
11493
- }, [coinlist, isReady, enabled, offerId, offerOptionId, fetchKey]);
12170
+ }, [coinlist, isReady, enabled, offerId, offerOptionId, fetchKey, log]);
11494
12171
  return { addressesState, refetch, disconnect };
11495
12172
  }
11496
12173
 
11497
12174
  // src/client/hooks/requirements/data/useRequirements.ts
11498
- var import_react39 = require("react");
12175
+ var import_react40 = require("react");
11499
12176
  var LOADING_STATE6 = { type: "LOADING" };
11500
12177
  function useRequirements(offerId, options = {}) {
11501
12178
  const { coinlist, isReady } = useCoinList();
12179
+ const log = useLogger("useRequirements");
11502
12180
  const { data } = options;
11503
- const [requirementsState, setRequirementsState] = (0, import_react39.useState)(
12181
+ const [requirementsState, setRequirementsState] = (0, import_react40.useState)(
11504
12182
  data !== void 0 ? { type: "CONTENT", ...data } : LOADING_STATE6
11505
12183
  );
11506
- const [fetchKey, setFetchKey] = (0, import_react39.useState)(0);
11507
- const refetch = (0, import_react39.useCallback)(() => setFetchKey((k) => k + 1), []);
11508
- (0, import_react39.useEffect)(() => {
12184
+ const [fetchKey, setFetchKey] = (0, import_react40.useState)(0);
12185
+ const refetch = (0, import_react40.useCallback)(() => setFetchKey((k) => k + 1), []);
12186
+ (0, import_react40.useEffect)(() => {
11509
12187
  let isCancelled = false;
11510
12188
  if (!isReady) {
11511
12189
  if (data === void 0) {
@@ -11532,6 +12210,14 @@ function useRequirements(offerId, options = {}) {
11532
12210
  coinlist.requirements.statuses(offerId)
11533
12211
  ]).then(([requirementsByOptionId, statuses]) => {
11534
12212
  if (!isCancelled) {
12213
+ log.debug(() => ({
12214
+ msg: "settled",
12215
+ fields: {
12216
+ state: "CONTENT",
12217
+ options: Object.keys(requirementsByOptionId).length,
12218
+ statuses: statuses.length
12219
+ }
12220
+ }));
11535
12221
  setRequirementsState({
11536
12222
  type: "CONTENT",
11537
12223
  requirements: requirementsByOptionId,
@@ -11541,22 +12227,23 @@ function useRequirements(offerId, options = {}) {
11541
12227
  }).catch((error) => {
11542
12228
  if (!isCancelled) {
11543
12229
  const reason = error instanceof NotAuthenticatedError ? "not-authenticated" : "generic-error";
12230
+ log.failure(
12231
+ () => ({ msg: "settled", fields: { state: "ERROR", reason } }),
12232
+ error
12233
+ );
11544
12234
  setRequirementsState({ type: "ERROR", reason });
11545
12235
  }
11546
12236
  });
11547
12237
  return () => {
11548
12238
  isCancelled = true;
11549
12239
  };
11550
- }, [coinlist, isReady, offerId, fetchKey]);
12240
+ }, [coinlist, isReady, offerId, fetchKey, log]);
11551
12241
  return { requirementsState, refetch };
11552
12242
  }
11553
12243
 
11554
12244
  // src/client/hooks/requirements/checklist/useRequirementsChecklistViewModel.ts
11555
12245
  var DEFAULT_LABELS = {
11556
12246
  kyc_approved: "KYC Verification",
11557
- identity_verified: "Identity Verification",
11558
- proof_of_address: "Proof of Address",
11559
- source_of_funds: "Source of Funds",
11560
12247
  external_wallet: "External Wallet",
11561
12248
  whitelisted_wallet: "Whitelisted Wallet",
11562
12249
  jurisdiction: "Jurisdiction Check",
@@ -11565,9 +12252,6 @@ var DEFAULT_LABELS = {
11565
12252
  };
11566
12253
  var DEFAULT_DESCRIPTIONS = {
11567
12254
  kyc_approved: "Complete Know Your Customer verification.",
11568
- identity_verified: "Verify your identity.",
11569
- proof_of_address: "Provide proof of your residential address.",
11570
- source_of_funds: "Provide documentation for your source of funds.",
11571
12255
  external_wallet: "Connect an external wallet.",
11572
12256
  whitelisted_wallet: "Connect a whitelisted wallet.",
11573
12257
  jurisdiction: "Confirm your jurisdiction eligibility.",
@@ -11596,21 +12280,22 @@ function useRequirementsChecklistViewModel(options) {
11596
12280
  data,
11597
12281
  identityVerificationOptions
11598
12282
  } = options;
12283
+ const log = useLogger("useRequirementsChecklistViewModel");
11599
12284
  const { coinlist } = useCoinList();
11600
12285
  const { requirementsState, refetch } = useRequirements(offerId, { data });
11601
- const [expandedId, setExpandedId] = (0, import_react40.useState)(null);
11602
- const [taxDocumentOpen, setTaxDocumentOpen] = (0, import_react40.useState)(false);
11603
- const [connectWalletOpen, setConnectWalletOpen] = (0, import_react40.useState)(false);
11604
- const [verifyingRequirementId, setVerifyingRequirementId] = (0, import_react40.useState)(null);
11605
- const isMountedRef = (0, import_react40.useRef)(true);
11606
- (0, import_react40.useEffect)(() => {
12286
+ const [expandedId, setExpandedId] = (0, import_react41.useState)(null);
12287
+ const [taxDocumentOpen, setTaxDocumentOpen] = (0, import_react41.useState)(false);
12288
+ const [connectWalletOpen, setConnectWalletOpen] = (0, import_react41.useState)(false);
12289
+ const [verifyingRequirementId, setVerifyingRequirementId] = (0, import_react41.useState)(null);
12290
+ const isMountedRef = (0, import_react41.useRef)(true);
12291
+ (0, import_react41.useEffect)(() => {
11607
12292
  isMountedRef.current = true;
11608
12293
  return () => {
11609
12294
  isMountedRef.current = false;
11610
12295
  };
11611
12296
  }, []);
11612
- const [hasWalletRequirement, setHasWalletRequirement] = (0, import_react40.useState)(false);
11613
- (0, import_react40.useEffect)(() => {
12297
+ const [hasWalletRequirement, setHasWalletRequirement] = (0, import_react41.useState)(false);
12298
+ (0, import_react41.useEffect)(() => {
11614
12299
  if (requirementsState.type === "CONTENT") {
11615
12300
  setHasWalletRequirement(
11616
12301
  (requirementsState.requirements[optionId] ?? []).some(
@@ -11626,14 +12311,14 @@ function useRequirementsChecklistViewModel(options) {
11626
12311
  } = useOptionAddresses(offerId, optionId, {
11627
12312
  enabled: hasWalletRequirement
11628
12313
  });
11629
- const removeWallet = (0, import_react40.useCallback)(
12314
+ const removeWallet = (0, import_react41.useCallback)(
11630
12315
  async (addressId) => {
11631
12316
  await disconnect(OfferOptionAddressId(addressId));
11632
12317
  refetch();
11633
12318
  },
11634
12319
  [disconnect, refetch]
11635
12320
  );
11636
- const awaitVerificationResult = (0, import_react40.useCallback)(
12321
+ const awaitVerificationResult = (0, import_react41.useCallback)(
11637
12322
  (requirementId, statusBeforeSubmit) => {
11638
12323
  void (async () => {
11639
12324
  const deadline = Date.now() + VERIFICATION_POLL_TIMEOUT_MS;
@@ -11647,6 +12332,9 @@ function useRequirementsChecklistViewModel(options) {
11647
12332
  )?.status;
11648
12333
  if (current !== void 0 && current !== statusBeforeSubmit) break;
11649
12334
  } catch (_) {
12335
+ log.debug(() => ({
12336
+ msg: "status poll tick failed; retrying until deadline"
12337
+ }));
11650
12338
  }
11651
12339
  }
11652
12340
  if (isMountedRef.current) {
@@ -11655,13 +12343,13 @@ function useRequirementsChecklistViewModel(options) {
11655
12343
  }
11656
12344
  })();
11657
12345
  },
11658
- [coinlist, offerId, refetch]
12346
+ [coinlist, offerId, refetch, log]
11659
12347
  );
11660
- const requirements = (0, import_react40.useMemo)(
12348
+ const requirements = (0, import_react41.useMemo)(
11661
12349
  () => requirementsState.type === "CONTENT" ? requirementsState.requirements[optionId] ?? [] : [],
11662
12350
  [requirementsState, optionId]
11663
12351
  );
11664
- const statusById = (0, import_react40.useMemo)(() => {
12352
+ const statusById = (0, import_react41.useMemo)(() => {
11665
12353
  if (requirementsState.type !== "CONTENT") {
11666
12354
  return /* @__PURE__ */ new Map();
11667
12355
  }
@@ -11670,7 +12358,7 @@ function useRequirementsChecklistViewModel(options) {
11670
12358
  requirementsState.statuses.filter((s) => ids.has(s.id)).map((s) => [s.id, s])
11671
12359
  );
11672
12360
  }, [requirementsState, requirements]);
11673
- const state = (0, import_react40.useMemo)(() => {
12361
+ const state = (0, import_react41.useMemo)(() => {
11674
12362
  switch (requirementsState.type) {
11675
12363
  case "LOADING":
11676
12364
  return { type: "loading" };
@@ -11739,7 +12427,7 @@ function useRequirementsChecklistViewModel(options) {
11739
12427
  identityVerificationOptions,
11740
12428
  removeWallet
11741
12429
  ]);
11742
- const handleRequirementAction = (0, import_react40.useCallback)(
12430
+ const handleRequirementAction = (0, import_react41.useCallback)(
11743
12431
  (requirement) => {
11744
12432
  const inlineVerification = statusById.get(requirement.id)?.kycLevel !== void 0 && onRequirementActionOverride === void 0;
11745
12433
  if (inlineVerification) {
@@ -11771,7 +12459,7 @@ function useRequirementsChecklistViewModel(options) {
11771
12459
  coinlist
11772
12460
  ]
11773
12461
  );
11774
- const onEvent = (0, import_react40.useCallback)(
12462
+ const onEvent = (0, import_react41.useCallback)(
11775
12463
  (event) => {
11776
12464
  switch (event.type) {
11777
12465
  case "ON_TOGGLE_ITEM":
@@ -11934,26 +12622,179 @@ function RequirementsChecklistContainer({
11934
12622
  ] });
11935
12623
  }
11936
12624
 
12625
+ // src/client/core/observability/pino-client-logger.ts
12626
+ var import_pino = require("pino");
12627
+
12628
+ // src/shared/core/observability/pino-logger.ts
12629
+ function toPinoRecord(event) {
12630
+ try {
12631
+ const record = {};
12632
+ for (const key of ownKeys(event.fields)) {
12633
+ record[key] = readProperty(event.fields, key, 0, /* @__PURE__ */ new WeakSet());
12634
+ }
12635
+ const cause = "cause" in event ? event.cause : void 0;
12636
+ if (cause !== void 0) {
12637
+ record.cause = sanitize(cause, 0, /* @__PURE__ */ new WeakSet());
12638
+ }
12639
+ return { ...record, scope: event.scope, ...event.bindings };
12640
+ } catch (_) {
12641
+ return { "log.render": "<unrenderable event>" };
12642
+ }
12643
+ }
12644
+ var PINO_LEVEL = {
12645
+ none: "silent",
12646
+ error: "error",
12647
+ warn: "warn",
12648
+ info: "info",
12649
+ debug: "debug"
12650
+ };
12651
+ var MAX_DEPTH = 8;
12652
+ function sanitize(value, depth, seen) {
12653
+ switch (typeof value) {
12654
+ case "string":
12655
+ case "boolean":
12656
+ return value;
12657
+ case "number":
12658
+ return Number.isFinite(value) ? value : String(value);
12659
+ case "bigint":
12660
+ return value.toString();
12661
+ case "undefined":
12662
+ return "<undefined>";
12663
+ case "function":
12664
+ return "<function>";
12665
+ case "symbol":
12666
+ return value.toString();
12667
+ case "object":
12668
+ return value === null ? null : sanitizeObject(value, depth, seen);
12669
+ default:
12670
+ return "<unrenderable>";
12671
+ }
12672
+ }
12673
+ function sanitizeObject(value, depth, seen) {
12674
+ if (seen.has(value)) return "<circular>";
12675
+ if (depth >= MAX_DEPTH) return "<max depth>";
12676
+ if (value instanceof Error) return describeError(value);
12677
+ if (value instanceof Date) return describeDate(value);
12678
+ seen.add(value);
12679
+ try {
12680
+ if (Array.isArray(value)) {
12681
+ return value.map(
12682
+ (_item, index) => readProperty(value, String(index), depth, seen)
12683
+ );
12684
+ }
12685
+ const out = {};
12686
+ for (const key of ownKeys(value)) {
12687
+ out[key] = readProperty(value, key, depth, seen);
12688
+ }
12689
+ return out;
12690
+ } finally {
12691
+ seen.delete(value);
12692
+ }
12693
+ }
12694
+ function readProperty(owner, key, depth, seen) {
12695
+ try {
12696
+ return sanitize(owner[key], depth + 1, seen);
12697
+ } catch (_) {
12698
+ return "<unreadable>";
12699
+ }
12700
+ }
12701
+ function ownKeys(value) {
12702
+ try {
12703
+ return Object.keys(value);
12704
+ } catch (_) {
12705
+ return [];
12706
+ }
12707
+ }
12708
+ function describeError(error) {
12709
+ return {
12710
+ name: safeRead(() => error.name),
12711
+ message: safeRead(() => error.message),
12712
+ stack: safeRead(() => error.stack)
12713
+ };
12714
+ }
12715
+ function describeDate(date) {
12716
+ return safeRead(() => date.toISOString());
12717
+ }
12718
+ function safeRead(read) {
12719
+ try {
12720
+ const value = read();
12721
+ return typeof value === "string" ? value : "<unreadable>";
12722
+ } catch (_) {
12723
+ return "<unreadable>";
12724
+ }
12725
+ }
12726
+ var SDK_LOGGER_NAME = "@coinlist-co/react";
12727
+ function loggerOverPino(sink, level) {
12728
+ return {
12729
+ level: () => level,
12730
+ debug: (event) => emit(sink, "debug", event),
12731
+ info: (event) => emit(sink, "info", event),
12732
+ warn: (event) => emit(sink, "warn", event),
12733
+ error: (event) => emit(sink, "error", event)
12734
+ };
12735
+ }
12736
+ function emit(sink, method, event) {
12737
+ try {
12738
+ const value = event();
12739
+ sink[method](toPinoRecord(value), value.msg);
12740
+ } catch (error) {
12741
+ reportRenderFailure(sink, error);
12742
+ }
12743
+ }
12744
+ function reportRenderFailure(sink, error) {
12745
+ try {
12746
+ sink.error(
12747
+ { "error.type": error instanceof Error ? error.name : typeof error },
12748
+ "log event failed to render"
12749
+ );
12750
+ } catch (_) {
12751
+ }
12752
+ }
12753
+
12754
+ // src/client/core/observability/pino-client-logger.ts
12755
+ function pinoClientLogger(options) {
12756
+ return loggerOverPino(
12757
+ // `name` as a child binding rather than pino's `name` option: the option
12758
+ // is honoured by pino's node build and silently dropped by its browser
12759
+ // build, so a binding is the only spelling that identifies the SDK in
12760
+ // both environments.
12761
+ (0, import_pino.pino)({
12762
+ level: PINO_LEVEL[options.level],
12763
+ browser: { asObject: true }
12764
+ }).child({ name: SDK_LOGGER_NAME }),
12765
+ options.level
12766
+ );
12767
+ }
12768
+
11937
12769
  // src/client/hooks/auth/useCompleteOAuth.ts
11938
- var import_react41 = require("react");
12770
+ var import_react42 = require("react");
11939
12771
  function useCompleteOAuth(options) {
11940
12772
  const { coinlist } = useCoinList();
11941
- const postOAuthCompleteRef = (0, import_react41.useRef)(options.postOAuthComplete);
11942
- const onFailureRef = (0, import_react41.useRef)(options.onFailure);
11943
- const onSuccessRef = (0, import_react41.useRef)(options.onSuccess);
12773
+ const log = useLogger("useCompleteOAuth");
12774
+ const postOAuthCompleteRef = (0, import_react42.useRef)(options.postOAuthComplete);
12775
+ const onFailureRef = (0, import_react42.useRef)(options.onFailure);
12776
+ const onSuccessRef = (0, import_react42.useRef)(options.onSuccess);
11944
12777
  postOAuthCompleteRef.current = options.postOAuthComplete;
11945
12778
  onFailureRef.current = options.onFailure;
11946
12779
  onSuccessRef.current = options.onSuccess;
11947
- const hasStartedExchangeRef = (0, import_react41.useRef)(false);
11948
- (0, import_react41.useEffect)(() => {
12780
+ const hasStartedExchangeRef = (0, import_react42.useRef)(false);
12781
+ (0, import_react42.useEffect)(() => {
11949
12782
  if (typeof window === "undefined") return;
11950
12783
  const params = new URLSearchParams(window.location.search);
11951
12784
  if (!params.has("code") && !params.has("error")) return;
11952
12785
  if (hasStartedExchangeRef.current) return;
11953
12786
  const oauthResult = coinlist.auth.completeOAuth();
11954
12787
  if (oauthResult.type === "error") {
12788
+ log.error(() => ({
12789
+ msg: "oauth callback rejected",
12790
+ fields: { reason: oauthResult.reason }
12791
+ }));
11955
12792
  void Promise.resolve(onFailureRef.current(oauthResult.reason)).catch(
11956
- () => {
12793
+ (error) => {
12794
+ log.failure(
12795
+ () => ({ msg: "the host onFailure handler threw" }),
12796
+ error
12797
+ );
11957
12798
  }
11958
12799
  );
11959
12800
  return;
@@ -11968,15 +12809,27 @@ function useCompleteOAuth(options) {
11968
12809
  });
11969
12810
  if (cancelled) return;
11970
12811
  if (!ok) {
12812
+ log.error(() => ({
12813
+ msg: "the host postOAuthComplete handler reported failure",
12814
+ fields: { reason: "complete_request_failed" }
12815
+ }));
11971
12816
  hasStartedExchangeRef.current = false;
11972
12817
  await onFailureRef.current("complete_request_failed");
11973
12818
  return;
11974
12819
  }
11975
12820
  await coinlist.init();
11976
12821
  if (cancelled) return;
12822
+ log.info(() => ({ msg: "session established" }));
11977
12823
  await onSuccessRef.current();
11978
- } catch {
12824
+ } catch (error) {
11979
12825
  if (cancelled) return;
12826
+ log.failure(
12827
+ () => ({
12828
+ msg: "settled",
12829
+ fields: { state: "ERROR", reason: "complete_request_failed" }
12830
+ }),
12831
+ error
12832
+ );
11980
12833
  hasStartedExchangeRef.current = false;
11981
12834
  await onFailureRef.current("complete_request_failed");
11982
12835
  }
@@ -11985,19 +12838,20 @@ function useCompleteOAuth(options) {
11985
12838
  cancelled = true;
11986
12839
  hasStartedExchangeRef.current = false;
11987
12840
  };
11988
- }, [coinlist]);
12841
+ }, [coinlist, log]);
11989
12842
  }
11990
12843
 
11991
12844
  // src/client/hooks/checkout/coin-list/token-sale/data/useParticipations.ts
11992
- var import_react42 = require("react");
12845
+ var import_react43 = require("react");
11993
12846
  var LOADING_STATE7 = { type: "LOADING" };
11994
12847
  function useParticipations(offerId, options = {}) {
11995
12848
  const { coinlist, isReady } = useCoinList();
12849
+ const log = useLogger("useParticipations");
11996
12850
  const { data } = options;
11997
- const [participationsState, setParticipationsState] = (0, import_react42.useState)(
12851
+ const [participationsState, setParticipationsState] = (0, import_react43.useState)(
11998
12852
  data !== void 0 ? { type: "CONTENT", participations: data } : LOADING_STATE7
11999
12853
  );
12000
- (0, import_react42.useEffect)(() => {
12854
+ (0, import_react43.useEffect)(() => {
12001
12855
  let isCancelled = false;
12002
12856
  if (!isReady) {
12003
12857
  if (data === void 0) {
@@ -12015,31 +12869,40 @@ function useParticipations(offerId, options = {}) {
12015
12869
  setParticipationsState(LOADING_STATE7);
12016
12870
  coinlist.tokenSale.list(offerId).then((participations) => {
12017
12871
  if (!isCancelled) {
12872
+ log.debug(() => ({
12873
+ msg: "settled",
12874
+ fields: { state: "CONTENT", count: participations.length }
12875
+ }));
12018
12876
  setParticipationsState({ type: "CONTENT", participations });
12019
12877
  }
12020
12878
  }).catch((error) => {
12021
12879
  if (!isCancelled) {
12022
12880
  const reason = error instanceof NotAuthenticatedError ? "not-authenticated" : "generic-error";
12881
+ log.failure(
12882
+ () => ({ msg: "settled", fields: { state: "ERROR", reason } }),
12883
+ error
12884
+ );
12023
12885
  setParticipationsState({ type: "ERROR", reason });
12024
12886
  }
12025
12887
  });
12026
12888
  return () => {
12027
12889
  isCancelled = true;
12028
12890
  };
12029
- }, [coinlist, isReady, offerId, data]);
12891
+ }, [coinlist, isReady, offerId, data, log]);
12030
12892
  return { participationsState };
12031
12893
  }
12032
12894
 
12033
12895
  // src/client/hooks/offers/data/useOfferDetails.ts
12034
- var import_react43 = require("react");
12896
+ var import_react44 = require("react");
12035
12897
  var LOADING_STATE8 = { type: "LOADING" };
12036
12898
  function useOfferDetails(offerId, options = {}) {
12037
12899
  const { coinlist, isReady } = useCoinList();
12900
+ const log = useLogger("useOfferDetails");
12038
12901
  const { data } = options;
12039
- const [offerDetailsState, setOfferDetailsState] = (0, import_react43.useState)(
12902
+ const [offerDetailsState, setOfferDetailsState] = (0, import_react44.useState)(
12040
12903
  data !== void 0 ? { type: "CONTENT", offerDetail: data } : LOADING_STATE8
12041
12904
  );
12042
- (0, import_react43.useEffect)(() => {
12905
+ (0, import_react44.useEffect)(() => {
12043
12906
  let isCancelled = false;
12044
12907
  if (!isReady) {
12045
12908
  if (data === void 0) {
@@ -12057,36 +12920,45 @@ function useOfferDetails(offerId, options = {}) {
12057
12920
  setOfferDetailsState(LOADING_STATE8);
12058
12921
  coinlist.offers.get(offerId).then((offerDetail) => {
12059
12922
  if (!isCancelled) {
12923
+ log.debug(() => ({
12924
+ msg: "settled",
12925
+ fields: { state: "CONTENT", offerId: offerDetail.id }
12926
+ }));
12060
12927
  setOfferDetailsState({ type: "CONTENT", offerDetail });
12061
12928
  }
12062
12929
  }).catch((error) => {
12063
12930
  if (!isCancelled) {
12064
12931
  const reason = error instanceof NotAuthenticatedError ? "not-authenticated" : "generic-error";
12932
+ log.failure(
12933
+ () => ({ msg: "settled", fields: { state: "ERROR", reason } }),
12934
+ error
12935
+ );
12065
12936
  setOfferDetailsState({ type: "ERROR", reason });
12066
12937
  }
12067
12938
  });
12068
12939
  return () => {
12069
12940
  isCancelled = true;
12070
12941
  };
12071
- }, [coinlist, isReady, offerId, data]);
12942
+ }, [coinlist, isReady, offerId, data, log]);
12072
12943
  return { offerDetailsState };
12073
12944
  }
12074
12945
 
12075
12946
  // src/client/hooks/tokens/data/useTokenMetadata.ts
12076
- var import_react44 = require("react");
12947
+ var import_react45 = require("react");
12077
12948
  var DISABLED_STATE = { type: "DISABLED" };
12078
12949
  var LOADING_STATE9 = { type: "LOADING" };
12079
12950
  function useTokenMetadata(options) {
12080
12951
  const { chain, address, data, enabled = true } = options;
12081
12952
  const { coinlist, isReady } = useCoinList();
12082
- const [state, setState] = (0, import_react44.useState)(
12953
+ const log = useLogger("useTokenMetadata");
12954
+ const [state, setState] = (0, import_react45.useState)(
12083
12955
  () => data !== void 0 ? { type: "CONTENT", tokenMetadata: data } : LOADING_STATE9
12084
12956
  );
12085
- const [refetchCount, setRefetchCount] = (0, import_react44.useState)(0);
12086
- const refetch = (0, import_react44.useCallback)(() => {
12957
+ const [refetchCount, setRefetchCount] = (0, import_react45.useState)(0);
12958
+ const refetch = (0, import_react45.useCallback)(() => {
12087
12959
  setRefetchCount((count) => count + 1);
12088
12960
  }, []);
12089
- (0, import_react44.useEffect)(() => {
12961
+ (0, import_react45.useEffect)(() => {
12090
12962
  let isCancelled = false;
12091
12963
  const seedActive = data !== void 0 && refetchCount === 0;
12092
12964
  if (!isReady || !enabled || seedActive) {
@@ -12097,17 +12969,32 @@ function useTokenMetadata(options) {
12097
12969
  setState(LOADING_STATE9);
12098
12970
  coinlist.tokens.get({ chain, address }).then((tokenMetadata) => {
12099
12971
  if (!isCancelled) {
12972
+ log.debug(() => ({
12973
+ msg: "settled",
12974
+ fields: {
12975
+ state: "CONTENT",
12976
+ listed: tokenMetadata !== null,
12977
+ symbol: tokenMetadata?.symbol ?? null
12978
+ }
12979
+ }));
12100
12980
  setState({ type: "CONTENT", tokenMetadata });
12101
12981
  }
12102
- }).catch(() => {
12982
+ }).catch((error) => {
12103
12983
  if (!isCancelled) {
12984
+ log.failure(
12985
+ () => ({
12986
+ msg: "settled",
12987
+ fields: { state: "ERROR", reason: "generic-error" }
12988
+ }),
12989
+ error
12990
+ );
12104
12991
  setState({ type: "ERROR", reason: "generic-error" });
12105
12992
  }
12106
12993
  });
12107
12994
  return () => {
12108
12995
  isCancelled = true;
12109
12996
  };
12110
- }, [coinlist, isReady, enabled, chain, address, data, refetchCount]);
12997
+ }, [coinlist, isReady, enabled, chain, address, data, refetchCount, log]);
12111
12998
  return {
12112
12999
  // LOADING would be a lie while disabled: nothing is in flight and nothing
12113
13000
  // will replace it. Settled states (a seed, a previous answer) survive.
@@ -12155,6 +13042,7 @@ function useTokenMetadata(options) {
12155
13042
  OndoReviewView,
12156
13043
  OndoSidebarView,
12157
13044
  OndoWalletSelectView,
13045
+ RedactedWalletError,
12158
13046
  RequirementItem,
12159
13047
  RequirementItemUi,
12160
13048
  RequirementStatus,
@@ -12187,6 +13075,7 @@ function useTokenMetadata(options) {
12187
13075
  formatMonthYear,
12188
13076
  offerIconUrl,
12189
13077
  ondoLoadErrorReason,
13078
+ pinoClientLogger,
12190
13079
  prepareOndoSwap,
12191
13080
  quoteIsStale,
12192
13081
  quoteOverAsks,