@coinlist-co/react 0.11.0 → 0.11.1-rc.22d81d4

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-AQIHCFW4.js +279 -0
  2. package/dist/chunk-AQIHCFW4.js.map +1 -0
  3. package/dist/{chunk-B2HCVPCQ.js → chunk-PRG3EDQJ.js} +25 -10
  4. package/dist/chunk-PRG3EDQJ.js.map +1 -0
  5. package/dist/{chunk-UIIXXLA7.js → chunk-ZVB6KWZ2.js} +484 -141
  6. package/dist/chunk-ZVB6KWZ2.js.map +1 -0
  7. package/dist/client/index.cjs +1307 -461
  8. package/dist/client/index.cjs.map +1 -1
  9. package/dist/client/index.d.cts +216 -211
  10. package/dist/client/index.d.ts +216 -211
  11. package/dist/client/index.js +464 -108
  12. package/dist/client/index.js.map +1 -1
  13. package/dist/collections-DrJFEDHl.d.cts +116 -0
  14. package/dist/collections-pLtrj6fw.d.ts +116 -0
  15. package/dist/{config-B5mwS_2l.d.cts → config-C6vlghJY.d.cts} +713 -22
  16. package/dist/{config-B5mwS_2l.d.ts → config-C6vlghJY.d.ts} +713 -22
  17. package/dist/server/index.cjs +766 -209
  18. package/dist/server/index.cjs.map +1 -1
  19. package/dist/server/index.d.cts +80 -3
  20. package/dist/server/index.d.ts +80 -3
  21. package/dist/server/index.js +120 -51
  22. package/dist/server/index.js.map +1 -1
  23. package/dist/shared/index.cjs +486 -123
  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
@@ -24,7 +24,9 @@ __export(server_exports, {
24
24
  ServerOffersNamespaceImpl: () => ServerOffersNamespaceImpl,
25
25
  ServerRequirementsNamespaceImpl: () => ServerRequirementsNamespaceImpl,
26
26
  WritableSessionStoreRequiredError: () => WritableSessionStoreRequiredError,
27
- createCoinListServer: () => createCoinListServer
27
+ createCoinListServer: () => createCoinListServer,
28
+ emptySessionStore: () => emptySessionStore,
29
+ pinoServerLogger: () => pinoServerLogger
28
30
  });
29
31
  module.exports = __toCommonJS(server_exports);
30
32
 
@@ -55,6 +57,8 @@ var retryAttempt = (attempt) => ({
55
57
  var renewAttempted = (value) => ({
56
58
  renewAttempted: value
57
59
  });
60
+ var requestId = (id) => ({ requestId: id });
61
+ var getRequestId = (attrs) => attrs?.requestId ?? null;
58
62
  var isProtected = (attrs) => attrs?.protected === true;
59
63
  var needUserAgent = (attrs) => attrs?.userAgent === true;
60
64
  var isIdempotent = (attrs) => attrs?.idempotencyKey === true;
@@ -76,7 +80,9 @@ var Attributes = {
76
80
  renewAttempted,
77
81
  wasRenewAttempted,
78
82
  clientCredentials,
79
- getClientCredentials
83
+ getClientCredentials,
84
+ requestId,
85
+ getRequestId
80
86
  };
81
87
 
82
88
  // src/shared/api/http.ts
@@ -86,7 +92,24 @@ var HttpError = class extends Error {
86
92
  this.name = "HttpError";
87
93
  this.response = response;
88
94
  }
95
+ /**
96
+ * Correlates this failure with the `[HTTP]` log lines for the same request,
97
+ * which carry the method, the URL, the duration and every retry. `null` when
98
+ * the response did not come from an {@link HttpClient}.
99
+ *
100
+ * Worth quoting in a bug report: it is what makes a log excerpt readable.
101
+ */
102
+ get requestId() {
103
+ return this.response.requestId ?? null;
104
+ }
89
105
  };
106
+ function apiErrorCode(error) {
107
+ if (!(error instanceof HttpError)) return null;
108
+ const body = error.response.body;
109
+ if (typeof body !== "object" || body === null) return null;
110
+ const code = body.code;
111
+ return typeof code === "string" ? code : null;
112
+ }
90
113
  async function makeRequest(request) {
91
114
  const headers = {
92
115
  Accept: "application/json",
@@ -192,11 +215,185 @@ var HEADER_API_VERSION = "X-API-Version";
192
215
  var HEADER_IDEMPOTENCY_KEY = "Idempotency-Key";
193
216
  var API_VERSION = "2025-10-17";
194
217
 
218
+ // src/shared/types/errors.ts
219
+ var NotImplementedError = class extends Error {
220
+ constructor(message = "Not implemented yet") {
221
+ super(message);
222
+ this.name = "NotImplementedError";
223
+ }
224
+ };
225
+ var NotAuthenticatedError = class extends Error {
226
+ constructor(message = "The user is not authenticated. Go through the OAuth flow first!") {
227
+ super(message);
228
+ this.name = "NotAuthenticatedError";
229
+ }
230
+ };
231
+ var ValidationError = class extends Error {
232
+ constructor(message) {
233
+ super(message);
234
+ this.name = "ValidationError";
235
+ }
236
+ };
237
+ var InvariantError = class extends Error {
238
+ constructor(message) {
239
+ super(message);
240
+ this.name = "InvariantError";
241
+ }
242
+ };
243
+
244
+ // src/shared/core/observability/log-cause.ts
245
+ function classifyLogCause(error) {
246
+ if (error instanceof HttpError) {
247
+ return httpCause(error);
248
+ }
249
+ if (error instanceof ValidationError) {
250
+ return { type: "validation", message: error.message };
251
+ }
252
+ if (error instanceof InvariantError) {
253
+ return { type: "invariant", message: error.message };
254
+ }
255
+ if (error instanceof NotAuthenticatedError) {
256
+ return { type: "not-authenticated" };
257
+ }
258
+ if (error instanceof NotImplementedError) {
259
+ return { type: "not-implemented" };
260
+ }
261
+ return { type: "generic-error", name: errorName(error) };
262
+ }
263
+ function describeErrorUnredacted(error) {
264
+ if (error instanceof HttpError) {
265
+ return describeHttpErrorRedacted(error);
266
+ }
267
+ if (error instanceof Error) {
268
+ return `${error.name}: ${error.message}`;
269
+ }
270
+ return `thrown non-error: ${stringifyUnredacted(error)}`;
271
+ }
272
+ function stringifyUnredacted(value) {
273
+ if (value === void 0) return "";
274
+ try {
275
+ return JSON.stringify(
276
+ value,
277
+ (_key, item) => typeof item === "bigint" ? `${item}` : item
278
+ ) ?? String(value);
279
+ } catch (_) {
280
+ return "<unserializable>";
281
+ }
282
+ }
283
+ function describeHttpErrorRedacted(error) {
284
+ const code = apiErrorCode(error);
285
+ const status = error.response.status;
286
+ return code === null ? `HttpError ${status}` : `HttpError ${status} (${code})`;
287
+ }
288
+ function errorName(error) {
289
+ return error instanceof Error ? error.name : `non-error ${typeof error}`;
290
+ }
291
+ function httpCause(error) {
292
+ return {
293
+ type: "http",
294
+ requestId: error.requestId,
295
+ status: error.response.status,
296
+ code: apiErrorCode(error),
297
+ eventId: apiErrorEventId(error)
298
+ };
299
+ }
300
+ function apiErrorEventId(error) {
301
+ const body = error.response.body;
302
+ if (typeof body !== "object" || body === null) return null;
303
+ const eventId = body.event_id;
304
+ return typeof eventId === "string" ? eventId : null;
305
+ }
306
+
307
+ // src/shared/core/observability/internal-logger.ts
308
+ function internalLogger(logger, scope) {
309
+ return logger ? scopedLogger(logger, scope, {}) : noopInternalLogger;
310
+ }
311
+ var LEVEL_RANK = {
312
+ none: 0,
313
+ error: 1,
314
+ warn: 2,
315
+ info: 3,
316
+ debug: 4
317
+ };
318
+ function scopedLogger(logger, scope, bindings) {
319
+ const admits = (level) => LEVEL_RANK[logger.level()] >= LEVEL_RANK[level];
320
+ const safe = (event) => ({
321
+ msg: event.msg,
322
+ scope,
323
+ bindings,
324
+ fields: event.fields ?? {},
325
+ ...event.cause === void 0 ? {} : { cause: event.cause }
326
+ });
327
+ const unredacted = (event) => ({
328
+ msg: event.msg,
329
+ scope,
330
+ bindings,
331
+ fields: event.fields ?? {}
332
+ });
333
+ const self = {
334
+ child: (binding) => scopedLogger(logger, scope, { ...bindings, ...binding }),
335
+ debug: (event) => {
336
+ if (admits("debug")) logger.debug(() => unredacted(event()));
337
+ },
338
+ info: (event) => {
339
+ if (admits("info")) logger.info(() => safe(event()));
340
+ },
341
+ warn: (event) => {
342
+ if (admits("warn")) logger.warn(() => safe(event()));
343
+ },
344
+ error: (event) => {
345
+ if (admits("error")) logger.error(() => safe(event()));
346
+ },
347
+ failure: (event, error) => {
348
+ if (admits("debug"))
349
+ logger.debug(() => unredacted(verbatim(event(), error)));
350
+ if (admits("error")) logger.error(() => safe(classified(event(), error)));
351
+ },
352
+ warning: (event, error) => {
353
+ if (admits("debug"))
354
+ logger.debug(() => unredacted(verbatim(event(), error)));
355
+ if (admits("warn")) logger.warn(() => safe(classified(event(), error)));
356
+ },
357
+ wrap: async (op, params, run) => {
358
+ const opLog = self.child({ op });
359
+ opLog.debug(() => ({ msg: "call", fields: { params } }));
360
+ try {
361
+ return await run();
362
+ } catch (error) {
363
+ opLog.failure(() => ({ msg: "call failed" }), error);
364
+ throw error;
365
+ }
366
+ }
367
+ };
368
+ return self;
369
+ }
370
+ function verbatim(event, error) {
371
+ return {
372
+ msg: event.msg,
373
+ fields: { ...event.fields, error: describeErrorUnredacted(error) }
374
+ };
375
+ }
376
+ function classified(event, error) {
377
+ return { ...event, cause: event.cause ?? classifyLogCause(error) };
378
+ }
379
+ var noopInternalLogger = {
380
+ child: () => noopInternalLogger,
381
+ debug: () => void 0,
382
+ info: () => void 0,
383
+ warn: () => void 0,
384
+ error: () => void 0,
385
+ failure: () => void 0,
386
+ warning: () => void 0,
387
+ wrap: (_op, _params, run) => run()
388
+ };
389
+
195
390
  // src/shared/api/http-client.ts
196
391
  var HttpClient = class {
197
- constructor(config, middleware = {}) {
392
+ constructor(config, middleware = {}, logger = null, options = {}) {
198
393
  this.config = config;
199
394
  this.middleware = middleware;
395
+ this.log = internalLogger(logger, "HTTP");
396
+ this.makeRequestId = options.makeRequestId ?? defaultMakeRequestId;
200
397
  }
201
398
  async send(request) {
202
399
  return this.runRequestWithAfterMiddleware(request);
@@ -232,7 +429,13 @@ var HttpClient = class {
232
429
  return {
233
430
  ...request,
234
431
  url,
235
- headers
432
+ headers,
433
+ // Only when absent: a retry or a post-renewal re-send arrives with the
434
+ // first attempt's id already on it, and keeping it is the whole point.
435
+ attributes: Attributes.getRequestId(request.attributes) === null ? Attributes.concat(
436
+ request.attributes ?? Attributes.empty,
437
+ Attributes.requestId(this.makeRequestId())
438
+ ) : request.attributes
236
439
  };
237
440
  }
238
441
  /**
@@ -256,10 +459,89 @@ var HttpClient = class {
256
459
  }
257
460
  return request;
258
461
  }
259
- executeRequest(request) {
260
- return makeRequest(request);
462
+ /**
463
+ * One physical attempt, logged as one line.
464
+ *
465
+ * A non-2xx is a `warn` rather than an `error` because the wire does not
466
+ * know whether it is a failure: the retry middleware may turn a 503 into a
467
+ * success, and the token registry reads a 404 as "not listed". The namespace
468
+ * above decides, and logs the `error` when it does.
469
+ */
470
+ async executeRequest(request) {
471
+ const requestId2 = Attributes.getRequestId(request.attributes);
472
+ const log = requestId2 === null ? this.log : this.log.child({ requestId: requestId2 });
473
+ const attempt = Attributes.getRetryAttempt(request.attributes) + 1;
474
+ const startedAt = Date.now();
475
+ log.debug(() => ({
476
+ msg: "request sent",
477
+ fields: describeRequestUnredacted(request)
478
+ }));
479
+ try {
480
+ const response = await makeRequest(request);
481
+ const elapsed = Date.now() - startedAt;
482
+ const outcome = () => ({
483
+ msg: "request completed",
484
+ fields: {
485
+ ...identifyRequest(request),
486
+ "http.response.status_code": response.status,
487
+ duration_ms: elapsed,
488
+ attempt
489
+ }
490
+ });
491
+ if (response.status >= 200 && response.status < 300) {
492
+ log.info(outcome);
493
+ } else {
494
+ log.warn(outcome);
495
+ }
496
+ log.debug(() => ({
497
+ msg: "response received",
498
+ fields: { body: response.body }
499
+ }));
500
+ return requestId2 === null ? response : { ...response, requestId: requestId2 };
501
+ } catch (error) {
502
+ const elapsed = Date.now() - startedAt;
503
+ log.warning(
504
+ () => ({
505
+ msg: "request threw",
506
+ fields: {
507
+ ...identifyRequest(request),
508
+ duration_ms: elapsed,
509
+ attempt
510
+ }
511
+ }),
512
+ error
513
+ );
514
+ throw error;
515
+ }
261
516
  }
262
517
  };
518
+ function identifyRequest(request) {
519
+ const { host, path } = splitUrl(request.url);
520
+ return {
521
+ "http.request.method": request.method,
522
+ "server.address": host,
523
+ "url.path": path
524
+ };
525
+ }
526
+ function splitUrl(url) {
527
+ try {
528
+ const parsed = new URL(url);
529
+ return { host: parsed.host, path: parsed.pathname };
530
+ } catch (_) {
531
+ return { host: null, path: url };
532
+ }
533
+ }
534
+ function defaultMakeRequestId() {
535
+ return Math.random().toString(36).slice(2, 10).padEnd(8, "0");
536
+ }
537
+ function describeRequestUnredacted(request) {
538
+ return {
539
+ "http.request.method": request.method,
540
+ "url.full": buildUrlWithQueryParams(request.url, request.queryParams),
541
+ headers: request.headers,
542
+ ...request.method === "POST" ? { body: request.body } : {}
543
+ };
544
+ }
263
545
 
264
546
  // src/shared/api/middleware/attach-session-middleware.ts
265
547
  function attachSessionMiddleware(fetchAccessToken) {
@@ -390,18 +672,22 @@ function renewSessionMiddleware(fetchAccessToken) {
390
672
 
391
673
  // src/shared/api/authenticated-api-client.ts
392
674
  var AuthenticatedApiClient = class {
393
- constructor(config, fetchAccessToken, additionalBeforeRequest = []) {
394
- this.httpClient = new HttpClient(config, {
395
- beforeRequest: [
396
- attachSessionMiddleware(fetchAccessToken),
397
- ...additionalBeforeRequest,
398
- idempotencyKeyMiddleware
399
- ],
400
- afterRequest: [
401
- renewSessionMiddleware(fetchAccessToken),
402
- requestRetryMiddleware
403
- ]
404
- });
675
+ constructor(config, fetchAccessToken, additionalBeforeRequest = [], logger = null) {
676
+ this.httpClient = new HttpClient(
677
+ config,
678
+ {
679
+ beforeRequest: [
680
+ attachSessionMiddleware(fetchAccessToken),
681
+ ...additionalBeforeRequest,
682
+ idempotencyKeyMiddleware
683
+ ],
684
+ afterRequest: [
685
+ renewSessionMiddleware(fetchAccessToken),
686
+ requestRetryMiddleware
687
+ ]
688
+ },
689
+ logger
690
+ );
405
691
  }
406
692
  async send(request) {
407
693
  const response = await this.httpClient.send(request);
@@ -415,8 +701,13 @@ var AuthenticatedApiClient = class {
415
701
 
416
702
  // src/server/core/api/api-client.ts
417
703
  var ApiClient = class {
418
- constructor(config, fetchAccessToken) {
419
- this.client = new AuthenticatedApiClient(config, fetchAccessToken);
704
+ constructor(config, fetchAccessToken, logger = null) {
705
+ this.client = new AuthenticatedApiClient(
706
+ config,
707
+ fetchAccessToken,
708
+ [],
709
+ logger
710
+ );
420
711
  }
421
712
  async send(request) {
422
713
  return this.client.send(request);
@@ -448,33 +739,43 @@ var OAuthSession = {
448
739
  };
449
740
 
450
741
  // src/server/core/server-auth-namespace.ts
742
+ function emptySessionStore() {
743
+ return { getSession: async () => null };
744
+ }
451
745
  var ServerAuthNamespaceImpl = class {
452
746
  constructor(api, config) {
453
747
  this.api = api;
454
748
  this.config = config;
749
+ this.log = internalLogger(config.logger ?? null, "AUTH");
455
750
  }
456
- async completeOAuth({
457
- code,
458
- codeVerifier
459
- }) {
460
- const setSession = this.writableSessionStore();
461
- const sessionDto = await this.api.send({
462
- method: "POST",
463
- url: `/oauth/token`,
464
- body: {
465
- grant_type: "authorization_code",
466
- code,
467
- redirect_uri: this.config.redirectUri,
468
- client_id: this.config.clientId,
469
- client_secret: this.config.clientSecret,
470
- code_verifier: codeVerifier
471
- }
751
+ async completeOAuth(params) {
752
+ return this.log.wrap("completeOAuth", void 0, async () => {
753
+ const setSession = this.writableSessionStore();
754
+ const sessionDto = await this.api.send({
755
+ method: "POST",
756
+ url: `/oauth/token`,
757
+ body: {
758
+ grant_type: "authorization_code",
759
+ code: params.code,
760
+ redirect_uri: this.config.redirectUri,
761
+ client_id: this.config.clientId,
762
+ client_secret: this.config.clientSecret,
763
+ code_verifier: params.codeVerifier
764
+ }
765
+ });
766
+ const session = OAuthSession.fromDto(sessionDto);
767
+ await setSession(session);
768
+ return session;
472
769
  });
473
- const session = OAuthSession.fromDto(sessionDto);
474
- await setSession(session);
475
- return session;
476
770
  }
477
771
  async getAccessToken() {
772
+ return this.log.wrap(
773
+ "getAccessToken",
774
+ void 0,
775
+ () => this.readAccessToken()
776
+ );
777
+ }
778
+ async readAccessToken() {
478
779
  const sessionStore = this.config.sessionStore;
479
780
  const session = await sessionStore.getSession();
480
781
  if (session == null) return null;
@@ -486,12 +787,19 @@ var ServerAuthNamespaceImpl = class {
486
787
  }
487
788
  const setSession = sessionStore.setSession?.bind(sessionStore);
488
789
  if (!setSession) {
790
+ this.log.child({ op: "getAccessToken" }).warn(() => ({
791
+ msg: "serving an expired token: the session store is read-only, so it cannot be refreshed"
792
+ }));
489
793
  return session.accessToken;
490
794
  }
491
795
  return this.refreshSession(session.refreshToken, setSession);
492
796
  }
493
797
  async refreshSession(refreshToken, setSession) {
798
+ const log = this.log.child({ op: "refresh" });
494
799
  if (!refreshToken) {
800
+ log.warn(() => ({
801
+ msg: "clearing the session: it carries no refresh token"
802
+ }));
495
803
  await setSession(null);
496
804
  return null;
497
805
  }
@@ -508,26 +816,36 @@ var ServerAuthNamespaceImpl = class {
508
816
  });
509
817
  const newSession = OAuthSession.fromDto(sessionDto);
510
818
  await setSession(newSession);
819
+ log.info(() => ({ msg: "session renewed" }));
511
820
  return newSession.accessToken;
512
- } catch {
821
+ } catch (error) {
822
+ log.failure(
823
+ () => ({ msg: "refresh failed; clearing the session" }),
824
+ error
825
+ );
513
826
  await setSession(null);
514
827
  return null;
515
828
  }
516
829
  }
517
830
  async clientCredentials() {
518
- const sessionDto = await this.api.send({
519
- method: "POST",
520
- url: `/oauth/token`,
521
- body: {
522
- grant_type: "client_credentials",
523
- client_id: this.config.clientId,
524
- client_secret: this.config.clientSecret
525
- }
831
+ return this.log.wrap("clientCredentials", void 0, async () => {
832
+ const sessionDto = await this.api.send({
833
+ method: "POST",
834
+ url: `/oauth/token`,
835
+ body: {
836
+ grant_type: "client_credentials",
837
+ client_id: this.config.clientId,
838
+ client_secret: this.config.clientSecret
839
+ }
840
+ });
841
+ const session = OAuthSession.fromDto(sessionDto);
842
+ return ClientCredentialsOAuth(session.accessToken);
526
843
  });
527
- const session = OAuthSession.fromDto(sessionDto);
528
- return ClientCredentialsOAuth(session.accessToken);
529
844
  }
530
845
  async logout() {
846
+ return this.log.wrap("logout", void 0, () => this.revokeAndClear());
847
+ }
848
+ async revokeAndClear() {
531
849
  const setSession = this.writableSessionStore();
532
850
  const session = await this.config.sessionStore.getSession();
533
851
  if (session == null) return;
@@ -545,6 +863,9 @@ var ServerAuthNamespaceImpl = class {
545
863
  if (!(err instanceof HttpError) || this.config.strict) {
546
864
  throw err;
547
865
  }
866
+ this.log.child({ op: "logout" }).warn(() => ({
867
+ msg: "the token was not revoked upstream; the local session is cleared regardless"
868
+ }));
548
869
  }
549
870
  await setSession(null);
550
871
  }
@@ -578,48 +899,6 @@ async function fetchAllPages(fetchPage, baseParams) {
578
899
  return items;
579
900
  }
580
901
 
581
- // src/shared/types/offer.ts
582
- var OfferId = (value) => value;
583
- var OfferSlug = (value) => value;
584
- var Offer = {
585
- fromDto: (dto) => ({
586
- id: OfferId(dto.id),
587
- slug: OfferSlug(dto.slug),
588
- type: dto.type,
589
- tagline: dto.tagline,
590
- bannerUrl: dto.banner_url,
591
- logoUrl: dto.logo_url,
592
- startsAt: new Date(dto.starts_at),
593
- endsAt: dto.ends_at ? new Date(dto.ends_at) : null
594
- })
595
- };
596
-
597
- // src/shared/types/asset.ts
598
- var AssetId = (value) => value;
599
- var AssetCode = (value) => value;
600
- var Asset = {
601
- fromDto: (dto) => ({
602
- id: AssetId(dto.id),
603
- code: AssetCode(dto.code),
604
- name: dto.name,
605
- fractionalDigits: dto.fractional_digits
606
- })
607
- };
608
-
609
- // src/shared/types/errors.ts
610
- var NotAuthenticatedError = class extends Error {
611
- constructor(message = "The user is not authenticated. Go through the OAuth flow first!") {
612
- super(message);
613
- this.name = "NotAuthenticatedError";
614
- }
615
- };
616
- var ValidationError = class extends Error {
617
- constructor(message) {
618
- super(message);
619
- this.name = "ValidationError";
620
- }
621
- };
622
-
623
902
  // src/shared/types/blockchain/core.ts
624
903
  var ETHEREUM_CHAINS = {
625
904
  ethereum_mainnet: true,
@@ -660,11 +939,14 @@ var STABLE_DECIMALS = AssetDecimals(6);
660
939
  var DecimalString = (value) => value;
661
940
  var MAX_UINT_256 = 2n ** 256n - 1n;
662
941
  var assertUint256 = (value) => {
663
- if (value < 0n || value > MAX_UINT_256) {
664
- throw new Error(`Value out of uint256 bounds: ${value}`);
665
- }
666
- return value;
942
+ if (isUint256(value)) return value;
943
+ throw new InvariantError(`Value out of uint256 bounds: ${value}`);
667
944
  };
945
+ var parseUint256 = (value, label) => {
946
+ if (isUint256(value)) return value;
947
+ throw new ValidationError(`${label}: out of uint256 bounds (${value})`);
948
+ };
949
+ var isUint256 = (value) => value >= 0n && value <= MAX_UINT_256;
668
950
  var BlockchainAmount = Object.assign(
669
951
  (value) => value,
670
952
  {
@@ -674,43 +956,100 @@ var BlockchainAmount = Object.assign(
674
956
  );
675
957
  function combineAmounts(a, b, op) {
676
958
  if (a.decimals !== b.decimals) {
677
- throw new Error(
959
+ throw new InvariantError(
678
960
  `Cannot combine BlockchainAmounts with different decimals: ${a.decimals} vs ${b.decimals}`
679
961
  );
680
962
  }
681
963
  const raw = op(a.raw, b.raw);
682
964
  if (raw < 0n || raw > MAX_UINT_256) {
683
- throw new Error(`BlockchainAmount out of uint256 bounds: ${raw}`);
965
+ throw new InvariantError(`BlockchainAmount out of uint256 bounds: ${raw}`);
684
966
  }
685
967
  return BlockchainAmount({ raw, decimals: a.decimals });
686
968
  }
687
969
  var AssetSymbol = (value) => value;
688
970
 
971
+ // src/shared/types/offer.ts
972
+ var OfferId = (value) => value;
973
+ var OfferSlug = (value) => value;
974
+ var Offer = {
975
+ fromDto: (dto) => {
976
+ if (!Array.isArray(dto.tokens)) {
977
+ throw new ValidationError(
978
+ `Offer.tokens: expected an array, got ${typeof dto.tokens}`
979
+ );
980
+ }
981
+ return {
982
+ id: OfferId(dto.id),
983
+ slug: OfferSlug(dto.slug),
984
+ type: dto.type,
985
+ tagline: dto.tagline,
986
+ bannerUrl: dto.banner_url,
987
+ logoUrl: dto.logo_url,
988
+ startsAt: new Date(dto.starts_at),
989
+ endsAt: dto.ends_at ? new Date(dto.ends_at) : null,
990
+ tokens: dto.tokens.map(OfferToken.fromDto)
991
+ };
992
+ }
993
+ };
994
+ var OfferToken = {
995
+ fromDto: (dto) => ({
996
+ role: dto.role,
997
+ chain: Chain(dto.chain),
998
+ address: EvmContractAddress(dto.address)
999
+ })
1000
+ };
1001
+
1002
+ // src/shared/types/asset.ts
1003
+ var AssetId = (value) => value;
1004
+ var AssetCode = (value) => value;
1005
+ var Asset = {
1006
+ fromDto: (dto) => ({
1007
+ id: AssetId(dto.id),
1008
+ code: AssetCode(dto.code),
1009
+ name: dto.name,
1010
+ fractionalDigits: dto.fractional_digits
1011
+ })
1012
+ };
1013
+
689
1014
  // src/shared/types/offer-detail.ts
690
1015
  var OfferOptionId = (value) => value;
691
1016
  var OfferOptionSlug = (value) => value;
692
1017
  var OfferDetail = {
693
1018
  fromDto: (dto) => {
694
1019
  if (!Array.isArray(dto.funding_assets)) {
695
- throw new Error(`funding_assets must be an array`);
1020
+ throw new ValidationError(
1021
+ `OfferDetail.funding_assets: expected an array, got ${typeof dto.funding_assets}`
1022
+ );
696
1023
  }
697
1024
  if (!Array.isArray(dto.options)) {
698
- throw new Error(`options must be an array`);
1025
+ throw new ValidationError(
1026
+ `OfferDetail.options: expected an array, got ${typeof dto.options}`
1027
+ );
699
1028
  }
700
1029
  if (!Array.isArray(dto.terms)) {
701
- throw new Error(`terms must be an array`);
1030
+ throw new ValidationError(
1031
+ `OfferDetail.terms: expected an array, got ${typeof dto.terms}`
1032
+ );
702
1033
  }
703
1034
  if (!Array.isArray(dto.links)) {
704
- throw new Error(`links must be an array`);
1035
+ throw new ValidationError(
1036
+ `OfferDetail.links: expected an array, got ${typeof dto.links}`
1037
+ );
705
1038
  }
706
1039
  if (!Array.isArray(dto.faqs)) {
707
- throw new Error(`faqs must be an array`);
1040
+ throw new ValidationError(
1041
+ `OfferDetail.faqs: expected an array, got ${typeof dto.faqs}`
1042
+ );
708
1043
  }
709
1044
  if (!Array.isArray(dto.milestones)) {
710
- throw new Error(`milestones must be an array`);
1045
+ throw new ValidationError(
1046
+ `OfferDetail.milestones: expected an array, got ${typeof dto.milestones}`
1047
+ );
711
1048
  }
712
1049
  if (!Array.isArray(dto.tokens)) {
713
- throw new Error(`tokens must be an array`);
1050
+ throw new ValidationError(
1051
+ `OfferDetail.tokens: expected an array, got ${typeof dto.tokens}`
1052
+ );
714
1053
  }
715
1054
  return {
716
1055
  id: OfferId(dto.id),
@@ -772,13 +1111,6 @@ var Milestone = {
772
1111
  status: dto.status
773
1112
  })
774
1113
  };
775
- var OfferToken = {
776
- fromDto: (dto) => ({
777
- role: dto.role,
778
- chain: Chain(dto.chain),
779
- address: EvmContractAddress(dto.address)
780
- })
781
- };
782
1114
 
783
1115
  // src/shared/types/pagination.ts
784
1116
  var Cursor = (value) => value;
@@ -838,18 +1170,25 @@ async function fetchOfferDetails(api, id, clientCreds) {
838
1170
  var ServerOffersNamespaceImpl = class {
839
1171
  constructor(ctx) {
840
1172
  this.ctx = ctx;
1173
+ this.log = internalLogger(ctx.logger, "OFFERS");
841
1174
  }
842
1175
  async list(clientCreds) {
843
- await this.ctx.ensureAuthenticated(clientCreds);
844
- return fetchOffers(this.ctx.api, clientCreds);
1176
+ return this.log.wrap("list", clientCreds, async () => {
1177
+ await this.ctx.ensureAuthenticated(clientCreds);
1178
+ return fetchOffers(this.ctx.api, clientCreds);
1179
+ });
845
1180
  }
846
1181
  async listPage(params, clientCreds) {
847
- await this.ctx.ensureAuthenticated(clientCreds);
848
- return fetchOffersPage(this.ctx.api, params, clientCreds);
1182
+ return this.log.wrap("listPage", { params, clientCreds }, async () => {
1183
+ await this.ctx.ensureAuthenticated(clientCreds);
1184
+ return fetchOffersPage(this.ctx.api, params, clientCreds);
1185
+ });
849
1186
  }
850
1187
  async get(id, clientCreds) {
851
- await this.ctx.ensureAuthenticated(clientCreds);
852
- return fetchOfferDetails(this.ctx.api, id, clientCreds);
1188
+ return this.log.wrap("get", { id, clientCreds }, async () => {
1189
+ await this.ctx.ensureAuthenticated(clientCreds);
1190
+ return fetchOfferDetails(this.ctx.api, id, clientCreds);
1191
+ });
853
1192
  }
854
1193
  };
855
1194
 
@@ -982,38 +1321,49 @@ async function fetchPii(api) {
982
1321
  var RequirementsNamespaceImpl = class {
983
1322
  constructor(ctx) {
984
1323
  this.ctx = ctx;
1324
+ this.log = internalLogger(ctx.logger, "REQUIREMENTS");
985
1325
  }
986
1326
  async forOffer(offerId) {
987
- await this.ctx.ensureUserAuthenticated();
988
- return fetchOfferRequirements(
989
- this.ctx.api,
990
- offerId,
991
- void 0
992
- );
1327
+ return this.log.wrap("forOffer", offerId, async () => {
1328
+ await this.ctx.ensureUserAuthenticated();
1329
+ return fetchOfferRequirements(
1330
+ this.ctx.api,
1331
+ offerId,
1332
+ void 0
1333
+ );
1334
+ });
993
1335
  }
994
1336
  async statuses(offerId) {
995
- await this.ctx.ensureUserAuthenticated();
996
- return fetchRequirementStatuses(this.ctx.api, offerId);
1337
+ return this.log.wrap("statuses", offerId, async () => {
1338
+ await this.ctx.ensureUserAuthenticated();
1339
+ return fetchRequirementStatuses(this.ctx.api, offerId);
1340
+ });
997
1341
  }
998
1342
  async createKycToken(params) {
999
- await this.ctx.ensureUserAuthenticated();
1000
- return createKycToken(
1001
- this.ctx.api,
1002
- params?.levelName,
1003
- params?.reset
1004
- );
1343
+ return this.log.wrap("createKycToken", params, async () => {
1344
+ await this.ctx.ensureUserAuthenticated();
1345
+ return createKycToken(
1346
+ this.ctx.api,
1347
+ params?.levelName,
1348
+ params?.reset
1349
+ );
1350
+ });
1005
1351
  }
1006
1352
  async getPii() {
1007
- await this.ctx.ensureUserAuthenticated();
1008
- return fetchPii(this.ctx.api);
1353
+ return this.log.wrap("getPii", void 0, async () => {
1354
+ await this.ctx.ensureUserAuthenticated();
1355
+ return fetchPii(this.ctx.api);
1356
+ });
1009
1357
  }
1010
1358
  async submitDocument(params) {
1011
- await this.ctx.ensureUserAuthenticated();
1012
- return submitDocument(
1013
- this.ctx.api,
1014
- params.documentType,
1015
- params.fields
1016
- );
1359
+ return this.log.wrap("submitDocument", params, async () => {
1360
+ await this.ctx.ensureUserAuthenticated();
1361
+ return submitDocument(
1362
+ this.ctx.api,
1363
+ params.documentType,
1364
+ params.fields
1365
+ );
1366
+ });
1017
1367
  }
1018
1368
  };
1019
1369
 
@@ -1024,12 +1374,14 @@ var ServerRequirementsNamespaceImpl = class extends RequirementsNamespaceImpl {
1024
1374
  this.serverCtx = serverCtx;
1025
1375
  }
1026
1376
  async forOffer(offerId, clientCreds) {
1027
- await this.serverCtx.ensureAuthenticated(clientCreds);
1028
- return fetchOfferRequirements(
1029
- this.serverCtx.api,
1030
- offerId,
1031
- clientCreds
1032
- );
1377
+ return this.log.wrap("forOffer", { offerId, clientCreds }, async () => {
1378
+ await this.serverCtx.ensureAuthenticated(clientCreds);
1379
+ return fetchOfferRequirements(
1380
+ this.serverCtx.api,
1381
+ offerId,
1382
+ clientCreds
1383
+ );
1384
+ });
1033
1385
  }
1034
1386
  };
1035
1387
 
@@ -1044,25 +1396,31 @@ var SwapAuthorization = {
1044
1396
  };
1045
1397
  var SwapPreview = {
1046
1398
  fromDto: (dto) => ({
1047
- inputAmount: assertUint256(BigInt(dto.pay_input_amount)),
1048
- fee: assertUint256(BigInt(dto.fee)),
1049
- outputAmount: assertUint256(BigInt(dto.receive_output_amount))
1399
+ inputAmount: parseUint256(
1400
+ BigInt(dto.pay_input_amount),
1401
+ "SwapPreview.pay_input_amount"
1402
+ ),
1403
+ fee: parseUint256(BigInt(dto.fee), "SwapPreview.fee"),
1404
+ outputAmount: parseUint256(
1405
+ BigInt(dto.receive_output_amount),
1406
+ "SwapPreview.receive_output_amount"
1407
+ )
1050
1408
  })
1051
1409
  };
1052
1410
  var SwapStatus = {
1053
1411
  fromDto: (dto) => ({
1054
- stopped: assertUint256(BigInt(dto.stopped)),
1055
- swapLevel: assertUint256(BigInt(dto.swap_level))
1412
+ stopped: parseUint256(BigInt(dto.stopped), "SwapStatus.stopped"),
1413
+ swapLevel: parseUint256(BigInt(dto.swap_level), "SwapStatus.swap_level")
1056
1414
  })
1057
1415
  };
1058
1416
  var TokenAllowance = {
1059
1417
  fromDto: (dto) => ({
1060
- allowance: assertUint256(BigInt(dto.allowance))
1418
+ allowance: parseUint256(BigInt(dto.allowance), "TokenAllowance.allowance")
1061
1419
  })
1062
1420
  };
1063
1421
  var TokenBalance = {
1064
1422
  fromDto: (dto) => ({
1065
- balance: assertUint256(BigInt(dto.balance))
1423
+ balance: parseUint256(BigInt(dto.balance), "TokenBalance.balance")
1066
1424
  })
1067
1425
  };
1068
1426
  var AllowWalletResponse = {
@@ -1191,14 +1549,19 @@ function toErc20Asset(dto) {
1191
1549
  var Erc20NamespaceImpl = class {
1192
1550
  constructor(ctx) {
1193
1551
  this.ctx = ctx;
1552
+ this.log = internalLogger(ctx.logger, "ERC20");
1194
1553
  }
1195
1554
  async getAllowance(params) {
1196
- await this.ctx.ensureUserAuthenticated();
1197
- return getTokenAllowance(this.ctx.api, params);
1555
+ return this.log.wrap("getAllowance", params, async () => {
1556
+ await this.ctx.ensureUserAuthenticated();
1557
+ return getTokenAllowance(this.ctx.api, params);
1558
+ });
1198
1559
  }
1199
1560
  async getBalance(params) {
1200
- await this.ctx.ensureUserAuthenticated();
1201
- return getTokenBalance(this.ctx.api, params);
1561
+ return this.log.wrap("getBalance", params, async () => {
1562
+ await this.ctx.ensureUserAuthenticated();
1563
+ return getTokenBalance(this.ctx.api, params);
1564
+ });
1202
1565
  }
1203
1566
  };
1204
1567
 
@@ -1287,22 +1650,31 @@ async function createParticipation(api, params) {
1287
1650
  var CoinListTokenSaleNamespaceImpl = class {
1288
1651
  constructor(ctx) {
1289
1652
  this.ctx = ctx;
1653
+ this.log = internalLogger(ctx.logger, "TOKEN_SALE");
1290
1654
  }
1291
1655
  async list(offerId) {
1292
- await this.ctx.ensureUserAuthenticated();
1293
- return fetchParticipations(this.ctx.api, offerId);
1656
+ return this.log.wrap("list", offerId, async () => {
1657
+ await this.ctx.ensureUserAuthenticated();
1658
+ return fetchParticipations(this.ctx.api, offerId);
1659
+ });
1294
1660
  }
1295
1661
  async listPage(params) {
1296
- await this.ctx.ensureUserAuthenticated();
1297
- return fetchParticipationsPage(this.ctx.api, params);
1662
+ return this.log.wrap("listPage", params, async () => {
1663
+ await this.ctx.ensureUserAuthenticated();
1664
+ return fetchParticipationsPage(this.ctx.api, params);
1665
+ });
1298
1666
  }
1299
1667
  async get(id) {
1300
- await this.ctx.ensureUserAuthenticated();
1301
- return fetchParticipation(this.ctx.api, id);
1668
+ return this.log.wrap("get", id, async () => {
1669
+ await this.ctx.ensureUserAuthenticated();
1670
+ return fetchParticipation(this.ctx.api, id);
1671
+ });
1302
1672
  }
1303
1673
  async createParticipation(params) {
1304
- await this.ctx.ensureUserAuthenticated();
1305
- return createParticipation(this.ctx.api, params);
1674
+ return this.log.wrap("createParticipation", params, async () => {
1675
+ await this.ctx.ensureUserAuthenticated();
1676
+ return createParticipation(this.ctx.api, params);
1677
+ });
1306
1678
  }
1307
1679
  };
1308
1680
 
@@ -1520,18 +1892,25 @@ function sizeParam(params) {
1520
1892
  var OndoNamespaceImpl = class {
1521
1893
  constructor(ctx) {
1522
1894
  this.ctx = ctx;
1895
+ this.log = internalLogger(ctx.logger, "ONDO");
1523
1896
  }
1524
1897
  async getTradingStatus(params) {
1525
- await this.ctx.ensureUserAuthenticated();
1526
- return getOndoTradingStatus(this.ctx.api, params);
1898
+ return this.log.wrap("getTradingStatus", params, async () => {
1899
+ await this.ctx.ensureUserAuthenticated();
1900
+ return getOndoTradingStatus(this.ctx.api, params);
1901
+ });
1527
1902
  }
1528
1903
  async getQuote(params) {
1529
- await this.ctx.ensureUserAuthenticated();
1530
- return getOndoQuote(this.ctx.api, params);
1904
+ return this.log.wrap("getQuote", params, async () => {
1905
+ await this.ctx.ensureUserAuthenticated();
1906
+ return getOndoQuote(this.ctx.api, params);
1907
+ });
1531
1908
  }
1532
1909
  async buildSwapTransaction(params) {
1533
- await this.ctx.ensureUserAuthenticated();
1534
- return buildOndoSwapTransaction(this.ctx.api, params);
1910
+ return this.log.wrap("buildSwapTransaction", params, async () => {
1911
+ await this.ctx.ensureUserAuthenticated();
1912
+ return buildOndoSwapTransaction(this.ctx.api, params);
1913
+ });
1535
1914
  }
1536
1915
  };
1537
1916
 
@@ -1539,26 +1918,37 @@ var OndoNamespaceImpl = class {
1539
1918
  var SuperstateSwapNamespaceImpl = class {
1540
1919
  constructor(ctx) {
1541
1920
  this.ctx = ctx;
1921
+ this.log = internalLogger(ctx.logger, "SUPERSTATE");
1542
1922
  }
1543
1923
  async getAuthorization(params) {
1544
- await this.ctx.ensureUserAuthenticated();
1545
- return getSwapAuthorization(this.ctx.api, params);
1924
+ return this.log.wrap("getAuthorization", params, async () => {
1925
+ await this.ctx.ensureUserAuthenticated();
1926
+ return getSwapAuthorization(this.ctx.api, params);
1927
+ });
1546
1928
  }
1547
1929
  async getPreview(params) {
1548
- await this.ctx.ensureUserAuthenticated();
1549
- return getSwapPreview(this.ctx.api, params);
1930
+ return this.log.wrap("getPreview", params, async () => {
1931
+ await this.ctx.ensureUserAuthenticated();
1932
+ return getSwapPreview(this.ctx.api, params);
1933
+ });
1550
1934
  }
1551
1935
  async getStatus(params) {
1552
- await this.ctx.ensureUserAuthenticated();
1553
- return getSwapStatus(this.ctx.api, params);
1936
+ return this.log.wrap("getStatus", params, async () => {
1937
+ await this.ctx.ensureUserAuthenticated();
1938
+ return getSwapStatus(this.ctx.api, params);
1939
+ });
1554
1940
  }
1555
1941
  async getOutputToken(params) {
1556
- await this.ctx.ensureUserAuthenticated();
1557
- return getSwapOutputToken(this.ctx.api, params);
1942
+ return this.log.wrap("getOutputToken", params, async () => {
1943
+ await this.ctx.ensureUserAuthenticated();
1944
+ return getSwapOutputToken(this.ctx.api, params);
1945
+ });
1558
1946
  }
1559
1947
  async allowWallet(params) {
1560
- await this.ctx.ensureUserAuthenticated();
1561
- return allowWallet(this.ctx.api, params);
1948
+ return this.log.wrap("allowWallet", params, async () => {
1949
+ await this.ctx.ensureUserAuthenticated();
1950
+ return allowWallet(this.ctx.api, params);
1951
+ });
1562
1952
  }
1563
1953
  };
1564
1954
 
@@ -1629,8 +2019,8 @@ var resolveLogoUrl = (url, baseUrl) => TokenLogoUrl(
1629
2019
  );
1630
2020
 
1631
2021
  // src/shared/api/nabu/tokens.ts
1632
- function createNabuApiClient(baseUrl) {
1633
- return new HttpClient({ baseUrl });
2022
+ function createNabuApiClient(baseUrl, logger = null) {
2023
+ return new HttpClient({ baseUrl }, {}, logger);
1634
2024
  }
1635
2025
  async function fetchTokenMetadata(client, token) {
1636
2026
  const address = checksummed(token.address);
@@ -1703,14 +2093,23 @@ var TokensNamespaceImpl = class {
1703
2093
  * registry is unauthenticated and on its own host, so the frontline sender
1704
2094
  * and the auth check would both be dead weight here.
1705
2095
  */
1706
- constructor(baseUrl) {
1707
- this.api = createNabuApiClient(baseUrl);
2096
+ constructor(baseUrl, logger = null) {
2097
+ this.api = createNabuApiClient(baseUrl, logger);
2098
+ this.log = internalLogger(logger, "TOKENS");
1708
2099
  }
1709
2100
  get(token) {
1710
- return fetchTokenMetadata(this.api, token);
2101
+ return this.log.wrap(
2102
+ "get",
2103
+ token,
2104
+ () => fetchTokenMetadata(this.api, token)
2105
+ );
1711
2106
  }
1712
2107
  list(chain) {
1713
- return fetchTokensMetadata(this.api, chain);
2108
+ return this.log.wrap(
2109
+ "list",
2110
+ chain,
2111
+ () => fetchTokensMetadata(this.api, chain)
2112
+ );
1714
2113
  }
1715
2114
  };
1716
2115
 
@@ -1816,33 +2215,42 @@ async function removeOptionAddress(api, offerId, addressId) {
1816
2215
  var WalletsNamespaceImpl = class {
1817
2216
  constructor(ctx) {
1818
2217
  this.ctx = ctx;
2218
+ this.log = internalLogger(ctx.logger, "WALLETS");
1819
2219
  }
1820
2220
  async createOwnershipChallenge(params) {
1821
- await this.ctx.ensureUserAuthenticated();
1822
- return createWalletOwnershipChallenge(
1823
- this.ctx.api,
1824
- params
1825
- );
2221
+ return this.log.wrap("createOwnershipChallenge", params, async () => {
2222
+ await this.ctx.ensureUserAuthenticated();
2223
+ return createWalletOwnershipChallenge(
2224
+ this.ctx.api,
2225
+ params
2226
+ );
2227
+ });
1826
2228
  }
1827
2229
  async connectExternal(params) {
1828
- await this.ctx.ensureUserAuthenticated();
1829
- return connectExternalWallet(this.ctx.api, params);
2230
+ return this.log.wrap("connectExternal", params, async () => {
2231
+ await this.ctx.ensureUserAuthenticated();
2232
+ return connectExternalWallet(this.ctx.api, params);
2233
+ });
1830
2234
  }
1831
2235
  async list(params) {
1832
- await this.ctx.ensureUserAuthenticated();
1833
- return listOptionAddresses(
1834
- this.ctx.api,
1835
- params.offerId,
1836
- params.offerOptionId
1837
- );
2236
+ return this.log.wrap("list", params, async () => {
2237
+ await this.ctx.ensureUserAuthenticated();
2238
+ return listOptionAddresses(
2239
+ this.ctx.api,
2240
+ params.offerId,
2241
+ params.offerOptionId
2242
+ );
2243
+ });
1838
2244
  }
1839
2245
  async remove(params) {
1840
- await this.ctx.ensureUserAuthenticated();
1841
- return removeOptionAddress(
1842
- this.ctx.api,
1843
- params.offerId,
1844
- params.addressId
1845
- );
2246
+ return this.log.wrap("remove", params, async () => {
2247
+ await this.ctx.ensureUserAuthenticated();
2248
+ return removeOptionAddress(
2249
+ this.ctx.api,
2250
+ params.offerId,
2251
+ params.addressId
2252
+ );
2253
+ });
1846
2254
  }
1847
2255
  };
1848
2256
 
@@ -1851,6 +2259,7 @@ var ACCESS_TOKEN_EXPIRY_BUFFER_SECONDS = 60;
1851
2259
  var CoinListServerImpl = class {
1852
2260
  constructor(_config) {
1853
2261
  this._config = _config;
2262
+ const logger = _config.logger ?? null;
1854
2263
  this.api = new ApiClient(
1855
2264
  {
1856
2265
  baseUrl: _config.baseUrl ?? PUBLIC_API_BASE_URL,
@@ -1860,7 +2269,8 @@ var CoinListServerImpl = class {
1860
2269
  // fresh token. A read-only store cannot persist a new session, so return
1861
2270
  // null immediately — this tells the middleware to skip the retry rather
1862
2271
  // than re-sending with the same expired token and wasting a round-trip.
1863
- (refresh) => refresh && !this._config.sessionStore.setSession ? Promise.resolve(null) : this.auth.getAccessToken()
2272
+ (refresh) => refresh && !this._config.sessionStore.setSession ? Promise.resolve(null) : this.auth.getAccessToken(),
2273
+ logger
1864
2274
  );
1865
2275
  this.auth = new ServerAuthNamespaceImpl(this.api, {
1866
2276
  ..._config,
@@ -1869,6 +2279,7 @@ var CoinListServerImpl = class {
1869
2279
  });
1870
2280
  const ctx = {
1871
2281
  api: this.api,
2282
+ logger,
1872
2283
  ensureUserAuthenticated: () => this.ensureAuthenticated(void 0),
1873
2284
  ensureAuthenticated: (clientCreds) => this.ensureAuthenticated(clientCreds)
1874
2285
  };
@@ -1880,7 +2291,8 @@ var CoinListServerImpl = class {
1880
2291
  this.superstate = new SuperstateSwapNamespaceImpl(ctx);
1881
2292
  this.ondo = new OndoNamespaceImpl(ctx);
1882
2293
  this.tokens = new TokensNamespaceImpl(
1883
- _config.tokensBaseUrl ?? NABU_BASE_URL
2294
+ _config.tokensBaseUrl ?? NABU_BASE_URL,
2295
+ logger
1884
2296
  );
1885
2297
  }
1886
2298
  /**
@@ -1898,12 +2310,157 @@ var CoinListServerImpl = class {
1898
2310
  function createCoinListServer(config) {
1899
2311
  return new CoinListServerImpl(config);
1900
2312
  }
2313
+
2314
+ // src/server/core/observability/pino-server-logger.ts
2315
+ var import_pino = require("pino");
2316
+
2317
+ // src/shared/core/observability/pino-logger.ts
2318
+ function toPinoRecord(event) {
2319
+ try {
2320
+ const record = {};
2321
+ for (const key of ownKeys(event.fields)) {
2322
+ record[key] = readProperty(event.fields, key, 0, /* @__PURE__ */ new WeakSet());
2323
+ }
2324
+ const cause = "cause" in event ? event.cause : void 0;
2325
+ if (cause !== void 0) {
2326
+ record.cause = sanitize(cause, 0, /* @__PURE__ */ new WeakSet());
2327
+ }
2328
+ return { ...record, scope: event.scope, ...event.bindings };
2329
+ } catch (_) {
2330
+ return { "log.render": "<unrenderable event>" };
2331
+ }
2332
+ }
2333
+ var PINO_LEVEL = {
2334
+ none: "silent",
2335
+ error: "error",
2336
+ warn: "warn",
2337
+ info: "info",
2338
+ debug: "debug"
2339
+ };
2340
+ var MAX_DEPTH = 8;
2341
+ function sanitize(value, depth, seen) {
2342
+ switch (typeof value) {
2343
+ case "string":
2344
+ case "boolean":
2345
+ return value;
2346
+ case "number":
2347
+ return Number.isFinite(value) ? value : String(value);
2348
+ case "bigint":
2349
+ return value.toString();
2350
+ case "undefined":
2351
+ return "<undefined>";
2352
+ case "function":
2353
+ return "<function>";
2354
+ case "symbol":
2355
+ return value.toString();
2356
+ case "object":
2357
+ return value === null ? null : sanitizeObject(value, depth, seen);
2358
+ default:
2359
+ return "<unrenderable>";
2360
+ }
2361
+ }
2362
+ function sanitizeObject(value, depth, seen) {
2363
+ if (seen.has(value)) return "<circular>";
2364
+ if (depth >= MAX_DEPTH) return "<max depth>";
2365
+ if (value instanceof Error) return describeError(value);
2366
+ if (value instanceof Date) return describeDate(value);
2367
+ seen.add(value);
2368
+ try {
2369
+ if (Array.isArray(value)) {
2370
+ return value.map(
2371
+ (_item, index) => readProperty(value, String(index), depth, seen)
2372
+ );
2373
+ }
2374
+ const out = {};
2375
+ for (const key of ownKeys(value)) {
2376
+ out[key] = readProperty(value, key, depth, seen);
2377
+ }
2378
+ return out;
2379
+ } finally {
2380
+ seen.delete(value);
2381
+ }
2382
+ }
2383
+ function readProperty(owner, key, depth, seen) {
2384
+ try {
2385
+ return sanitize(owner[key], depth + 1, seen);
2386
+ } catch (_) {
2387
+ return "<unreadable>";
2388
+ }
2389
+ }
2390
+ function ownKeys(value) {
2391
+ try {
2392
+ return Object.keys(value);
2393
+ } catch (_) {
2394
+ return [];
2395
+ }
2396
+ }
2397
+ function describeError(error) {
2398
+ return {
2399
+ name: safeRead(() => error.name),
2400
+ message: safeRead(() => error.message),
2401
+ stack: safeRead(() => error.stack)
2402
+ };
2403
+ }
2404
+ function describeDate(date) {
2405
+ return safeRead(() => date.toISOString());
2406
+ }
2407
+ function safeRead(read) {
2408
+ try {
2409
+ const value = read();
2410
+ return typeof value === "string" ? value : "<unreadable>";
2411
+ } catch (_) {
2412
+ return "<unreadable>";
2413
+ }
2414
+ }
2415
+ var SDK_LOGGER_NAME = "@coinlist-co/react";
2416
+ function loggerOverPino(sink, level) {
2417
+ return {
2418
+ level: () => level,
2419
+ debug: (event) => emit(sink, "debug", event),
2420
+ info: (event) => emit(sink, "info", event),
2421
+ warn: (event) => emit(sink, "warn", event),
2422
+ error: (event) => emit(sink, "error", event)
2423
+ };
2424
+ }
2425
+ function emit(sink, method, event) {
2426
+ try {
2427
+ const value = event();
2428
+ sink[method](toPinoRecord(value), value.msg);
2429
+ } catch (error) {
2430
+ reportRenderFailure(sink, error);
2431
+ }
2432
+ }
2433
+ function reportRenderFailure(sink, error) {
2434
+ try {
2435
+ sink.error(
2436
+ { "error.type": error instanceof Error ? error.name : typeof error },
2437
+ "log event failed to render"
2438
+ );
2439
+ } catch (_) {
2440
+ }
2441
+ }
2442
+
2443
+ // src/server/core/observability/pino-server-logger.ts
2444
+ function pinoServerLogger(options) {
2445
+ return loggerOverPino(
2446
+ // `name` as a child binding rather than pino's `name` option: the option
2447
+ // is honoured by pino's node build and silently dropped by its browser
2448
+ // build, so a binding is the only spelling that identifies the SDK in
2449
+ // both environments.
2450
+ (0, import_pino.pino)({
2451
+ level: PINO_LEVEL[options.level]
2452
+ }).child({ name: SDK_LOGGER_NAME }),
2453
+ options.level
2454
+ );
2455
+ }
1901
2456
  // Annotate the CommonJS export names for ESM import in node:
1902
2457
  0 && (module.exports = {
1903
2458
  ServerAuthNamespaceImpl,
1904
2459
  ServerOffersNamespaceImpl,
1905
2460
  ServerRequirementsNamespaceImpl,
1906
2461
  WritableSessionStoreRequiredError,
1907
- createCoinListServer
2462
+ createCoinListServer,
2463
+ emptySessionStore,
2464
+ pinoServerLogger
1908
2465
  });
1909
2466
  //# sourceMappingURL=index.cjs.map