@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
@@ -25,6 +25,8 @@ var retryAttempt = (attempt) => ({
25
25
  var renewAttempted = (value) => ({
26
26
  renewAttempted: value
27
27
  });
28
+ var requestId = (id) => ({ requestId: id });
29
+ var getRequestId = (attrs) => attrs?.requestId ?? null;
28
30
  var isProtected = (attrs) => attrs?.protected === true;
29
31
  var needUserAgent = (attrs) => attrs?.userAgent === true;
30
32
  var isIdempotent = (attrs) => attrs?.idempotencyKey === true;
@@ -46,7 +48,9 @@ var Attributes = {
46
48
  renewAttempted,
47
49
  wasRenewAttempted,
48
50
  clientCredentials,
49
- getClientCredentials
51
+ getClientCredentials,
52
+ requestId,
53
+ getRequestId
50
54
  };
51
55
 
52
56
  // src/shared/api/http.ts
@@ -56,6 +60,16 @@ var HttpError = class extends Error {
56
60
  this.name = "HttpError";
57
61
  this.response = response;
58
62
  }
63
+ /**
64
+ * Correlates this failure with the `[HTTP]` log lines for the same request,
65
+ * which carry the method, the URL, the duration and every retry. `null` when
66
+ * the response did not come from an {@link HttpClient}.
67
+ *
68
+ * Worth quoting in a bug report: it is what makes a log excerpt readable.
69
+ */
70
+ get requestId() {
71
+ return this.response.requestId ?? null;
72
+ }
59
73
  };
60
74
  function apiErrorCode(error) {
61
75
  if (!(error instanceof HttpError)) return null;
@@ -163,22 +177,6 @@ var Request = {
163
177
  concatAttributes
164
178
  };
165
179
 
166
- // src/shared/api/pagination.ts
167
- async function fetchAllPages(fetchPage, baseParams) {
168
- const items = [];
169
- let cursor = null;
170
- do {
171
- const params = {
172
- ...baseParams ?? {},
173
- after: cursor ?? void 0
174
- };
175
- const page = await fetchPage(params);
176
- items.push(...page.data);
177
- cursor = page.startingAfter;
178
- } while (cursor);
179
- return items;
180
- }
181
-
182
180
  // src/shared/types/errors.ts
183
181
  var NotImplementedError = class extends Error {
184
182
  constructor(message = "Not implemented yet") {
@@ -198,6 +196,28 @@ var ValidationError = class extends Error {
198
196
  this.name = "ValidationError";
199
197
  }
200
198
  };
199
+ var InvariantError = class extends Error {
200
+ constructor(message) {
201
+ super(message);
202
+ this.name = "InvariantError";
203
+ }
204
+ };
205
+
206
+ // src/shared/api/pagination.ts
207
+ async function fetchAllPages(fetchPage, baseParams) {
208
+ const items = [];
209
+ let cursor = null;
210
+ do {
211
+ const params = {
212
+ ...baseParams ?? {},
213
+ after: cursor ?? void 0
214
+ };
215
+ const page = await fetchPage(params);
216
+ items.push(...page.data);
217
+ cursor = page.startingAfter;
218
+ } while (cursor);
219
+ return items;
220
+ }
201
221
 
202
222
  // src/shared/types/blockchain/core.ts
203
223
  var ETHEREUM_CHAINS = {
@@ -245,11 +265,14 @@ var STABLE_DECIMALS = AssetDecimals(6);
245
265
  var DecimalString = (value) => value;
246
266
  var MAX_UINT_256 = 2n ** 256n - 1n;
247
267
  var assertUint256 = (value) => {
248
- if (value < 0n || value > MAX_UINT_256) {
249
- throw new Error(`Value out of uint256 bounds: ${value}`);
250
- }
251
- return value;
268
+ if (isUint256(value)) return value;
269
+ throw new InvariantError(`Value out of uint256 bounds: ${value}`);
252
270
  };
271
+ var parseUint256 = (value, label) => {
272
+ if (isUint256(value)) return value;
273
+ throw new ValidationError(`${label}: out of uint256 bounds (${value})`);
274
+ };
275
+ var isUint256 = (value) => value >= 0n && value <= MAX_UINT_256;
253
276
  var BlockchainAmount = Object.assign(
254
277
  (value) => value,
255
278
  {
@@ -259,13 +282,13 @@ var BlockchainAmount = Object.assign(
259
282
  );
260
283
  function combineAmounts(a, b, op) {
261
284
  if (a.decimals !== b.decimals) {
262
- throw new Error(
285
+ throw new InvariantError(
263
286
  `Cannot combine BlockchainAmounts with different decimals: ${a.decimals} vs ${b.decimals}`
264
287
  );
265
288
  }
266
289
  const raw = op(a.raw, b.raw);
267
290
  if (raw < 0n || raw > MAX_UINT_256) {
268
- throw new Error(`BlockchainAmount out of uint256 bounds: ${raw}`);
291
+ throw new InvariantError(`BlockchainAmount out of uint256 bounds: ${raw}`);
269
292
  }
270
293
  return BlockchainAmount({ raw, decimals: a.decimals });
271
294
  }
@@ -334,25 +357,31 @@ var SwapAuthorization = {
334
357
  };
335
358
  var SwapPreview = {
336
359
  fromDto: (dto) => ({
337
- inputAmount: assertUint256(BigInt(dto.pay_input_amount)),
338
- fee: assertUint256(BigInt(dto.fee)),
339
- outputAmount: assertUint256(BigInt(dto.receive_output_amount))
360
+ inputAmount: parseUint256(
361
+ BigInt(dto.pay_input_amount),
362
+ "SwapPreview.pay_input_amount"
363
+ ),
364
+ fee: parseUint256(BigInt(dto.fee), "SwapPreview.fee"),
365
+ outputAmount: parseUint256(
366
+ BigInt(dto.receive_output_amount),
367
+ "SwapPreview.receive_output_amount"
368
+ )
340
369
  })
341
370
  };
342
371
  var SwapStatus = {
343
372
  fromDto: (dto) => ({
344
- stopped: assertUint256(BigInt(dto.stopped)),
345
- swapLevel: assertUint256(BigInt(dto.swap_level))
373
+ stopped: parseUint256(BigInt(dto.stopped), "SwapStatus.stopped"),
374
+ swapLevel: parseUint256(BigInt(dto.swap_level), "SwapStatus.swap_level")
346
375
  })
347
376
  };
348
377
  var TokenAllowance = {
349
378
  fromDto: (dto) => ({
350
- allowance: assertUint256(BigInt(dto.allowance))
379
+ allowance: parseUint256(BigInt(dto.allowance), "TokenAllowance.allowance")
351
380
  })
352
381
  };
353
382
  var TokenBalance = {
354
383
  fromDto: (dto) => ({
355
- balance: assertUint256(BigInt(dto.balance))
384
+ balance: parseUint256(BigInt(dto.balance), "TokenBalance.balance")
356
385
  })
357
386
  };
358
387
  var AllowWalletResponse = {
@@ -477,18 +506,169 @@ function toErc20Asset(dto) {
477
506
  };
478
507
  }
479
508
 
509
+ // src/shared/core/observability/log-cause.ts
510
+ function classifyLogCause(error) {
511
+ if (error instanceof HttpError) {
512
+ return httpCause(error);
513
+ }
514
+ if (error instanceof ValidationError) {
515
+ return { type: "validation", message: error.message };
516
+ }
517
+ if (error instanceof InvariantError) {
518
+ return { type: "invariant", message: error.message };
519
+ }
520
+ if (error instanceof NotAuthenticatedError) {
521
+ return { type: "not-authenticated" };
522
+ }
523
+ if (error instanceof NotImplementedError) {
524
+ return { type: "not-implemented" };
525
+ }
526
+ return { type: "generic-error", name: errorName(error) };
527
+ }
528
+ function describeErrorUnredacted(error) {
529
+ if (error instanceof HttpError) {
530
+ return describeHttpErrorRedacted(error);
531
+ }
532
+ if (error instanceof Error) {
533
+ return `${error.name}: ${error.message}`;
534
+ }
535
+ return `thrown non-error: ${stringifyUnredacted(error)}`;
536
+ }
537
+ function stringifyUnredacted(value) {
538
+ if (value === void 0) return "";
539
+ try {
540
+ return JSON.stringify(
541
+ value,
542
+ (_key, item) => typeof item === "bigint" ? `${item}` : item
543
+ ) ?? String(value);
544
+ } catch (_) {
545
+ return "<unserializable>";
546
+ }
547
+ }
548
+ function describeHttpErrorRedacted(error) {
549
+ const code = apiErrorCode(error);
550
+ const status = error.response.status;
551
+ return code === null ? `HttpError ${status}` : `HttpError ${status} (${code})`;
552
+ }
553
+ function errorName(error) {
554
+ return error instanceof Error ? error.name : `non-error ${typeof error}`;
555
+ }
556
+ function httpCause(error) {
557
+ return {
558
+ type: "http",
559
+ requestId: error.requestId,
560
+ status: error.response.status,
561
+ code: apiErrorCode(error),
562
+ eventId: apiErrorEventId(error)
563
+ };
564
+ }
565
+ function apiErrorEventId(error) {
566
+ const body = error.response.body;
567
+ if (typeof body !== "object" || body === null) return null;
568
+ const eventId = body.event_id;
569
+ return typeof eventId === "string" ? eventId : null;
570
+ }
571
+
572
+ // src/shared/core/observability/internal-logger.ts
573
+ function internalLogger(logger, scope) {
574
+ return logger ? scopedLogger(logger, scope, {}) : noopInternalLogger;
575
+ }
576
+ var LEVEL_RANK = {
577
+ none: 0,
578
+ error: 1,
579
+ warn: 2,
580
+ info: 3,
581
+ debug: 4
582
+ };
583
+ function scopedLogger(logger, scope, bindings) {
584
+ const admits = (level) => LEVEL_RANK[logger.level()] >= LEVEL_RANK[level];
585
+ const safe = (event) => ({
586
+ msg: event.msg,
587
+ scope,
588
+ bindings,
589
+ fields: event.fields ?? {},
590
+ ...event.cause === void 0 ? {} : { cause: event.cause }
591
+ });
592
+ const unredacted = (event) => ({
593
+ msg: event.msg,
594
+ scope,
595
+ bindings,
596
+ fields: event.fields ?? {}
597
+ });
598
+ const self = {
599
+ child: (binding) => scopedLogger(logger, scope, { ...bindings, ...binding }),
600
+ debug: (event) => {
601
+ if (admits("debug")) logger.debug(() => unredacted(event()));
602
+ },
603
+ info: (event) => {
604
+ if (admits("info")) logger.info(() => safe(event()));
605
+ },
606
+ warn: (event) => {
607
+ if (admits("warn")) logger.warn(() => safe(event()));
608
+ },
609
+ error: (event) => {
610
+ if (admits("error")) logger.error(() => safe(event()));
611
+ },
612
+ failure: (event, error) => {
613
+ if (admits("debug"))
614
+ logger.debug(() => unredacted(verbatim(event(), error)));
615
+ if (admits("error")) logger.error(() => safe(classified(event(), error)));
616
+ },
617
+ warning: (event, error) => {
618
+ if (admits("debug"))
619
+ logger.debug(() => unredacted(verbatim(event(), error)));
620
+ if (admits("warn")) logger.warn(() => safe(classified(event(), error)));
621
+ },
622
+ wrap: async (op, params, run) => {
623
+ const opLog = self.child({ op });
624
+ opLog.debug(() => ({ msg: "call", fields: { params } }));
625
+ try {
626
+ return await run();
627
+ } catch (error) {
628
+ opLog.failure(() => ({ msg: "call failed" }), error);
629
+ throw error;
630
+ }
631
+ }
632
+ };
633
+ return self;
634
+ }
635
+ function verbatim(event, error) {
636
+ return {
637
+ msg: event.msg,
638
+ fields: { ...event.fields, error: describeErrorUnredacted(error) }
639
+ };
640
+ }
641
+ function classified(event, error) {
642
+ return { ...event, cause: event.cause ?? classifyLogCause(error) };
643
+ }
644
+ var noopInternalLogger = {
645
+ child: () => noopInternalLogger,
646
+ debug: () => void 0,
647
+ info: () => void 0,
648
+ warn: () => void 0,
649
+ error: () => void 0,
650
+ failure: () => void 0,
651
+ warning: () => void 0,
652
+ wrap: (_op, _params, run) => run()
653
+ };
654
+
480
655
  // src/shared/core/blockchain/erc20/erc20-namespace.ts
481
656
  var Erc20NamespaceImpl = class {
482
657
  constructor(ctx) {
483
658
  this.ctx = ctx;
659
+ this.log = internalLogger(ctx.logger, "ERC20");
484
660
  }
485
661
  async getAllowance(params) {
486
- await this.ctx.ensureUserAuthenticated();
487
- return getTokenAllowance(this.ctx.api, params);
662
+ return this.log.wrap("getAllowance", params, async () => {
663
+ await this.ctx.ensureUserAuthenticated();
664
+ return getTokenAllowance(this.ctx.api, params);
665
+ });
488
666
  }
489
667
  async getBalance(params) {
490
- await this.ctx.ensureUserAuthenticated();
491
- return getTokenBalance(this.ctx.api, params);
668
+ return this.log.wrap("getBalance", params, async () => {
669
+ await this.ctx.ensureUserAuthenticated();
670
+ return getTokenBalance(this.ctx.api, params);
671
+ });
492
672
  }
493
673
  };
494
674
 
@@ -684,15 +864,30 @@ var Asset = {
684
864
  var OfferId = (value) => value;
685
865
  var OfferSlug = (value) => value;
686
866
  var Offer = {
867
+ fromDto: (dto) => {
868
+ if (!Array.isArray(dto.tokens)) {
869
+ throw new ValidationError(
870
+ `Offer.tokens: expected an array, got ${typeof dto.tokens}`
871
+ );
872
+ }
873
+ return {
874
+ id: OfferId(dto.id),
875
+ slug: OfferSlug(dto.slug),
876
+ type: dto.type,
877
+ tagline: dto.tagline,
878
+ bannerUrl: dto.banner_url,
879
+ logoUrl: dto.logo_url,
880
+ startsAt: new Date(dto.starts_at),
881
+ endsAt: dto.ends_at ? new Date(dto.ends_at) : null,
882
+ tokens: dto.tokens.map(OfferToken.fromDto)
883
+ };
884
+ }
885
+ };
886
+ var OfferToken = {
687
887
  fromDto: (dto) => ({
688
- id: OfferId(dto.id),
689
- slug: OfferSlug(dto.slug),
690
- type: dto.type,
691
- tagline: dto.tagline,
692
- bannerUrl: dto.banner_url,
693
- logoUrl: dto.logo_url,
694
- startsAt: new Date(dto.starts_at),
695
- endsAt: dto.ends_at ? new Date(dto.ends_at) : null
888
+ role: dto.role,
889
+ chain: Chain(dto.chain),
890
+ address: EvmContractAddress(dto.address)
696
891
  })
697
892
  };
698
893
 
@@ -752,25 +947,39 @@ var OfferOptionSlug = (value) => value;
752
947
  var OfferDetail = {
753
948
  fromDto: (dto) => {
754
949
  if (!Array.isArray(dto.funding_assets)) {
755
- throw new Error(`funding_assets must be an array`);
950
+ throw new ValidationError(
951
+ `OfferDetail.funding_assets: expected an array, got ${typeof dto.funding_assets}`
952
+ );
756
953
  }
757
954
  if (!Array.isArray(dto.options)) {
758
- throw new Error(`options must be an array`);
955
+ throw new ValidationError(
956
+ `OfferDetail.options: expected an array, got ${typeof dto.options}`
957
+ );
759
958
  }
760
959
  if (!Array.isArray(dto.terms)) {
761
- throw new Error(`terms must be an array`);
960
+ throw new ValidationError(
961
+ `OfferDetail.terms: expected an array, got ${typeof dto.terms}`
962
+ );
762
963
  }
763
964
  if (!Array.isArray(dto.links)) {
764
- throw new Error(`links must be an array`);
965
+ throw new ValidationError(
966
+ `OfferDetail.links: expected an array, got ${typeof dto.links}`
967
+ );
765
968
  }
766
969
  if (!Array.isArray(dto.faqs)) {
767
- throw new Error(`faqs must be an array`);
970
+ throw new ValidationError(
971
+ `OfferDetail.faqs: expected an array, got ${typeof dto.faqs}`
972
+ );
768
973
  }
769
974
  if (!Array.isArray(dto.milestones)) {
770
- throw new Error(`milestones must be an array`);
975
+ throw new ValidationError(
976
+ `OfferDetail.milestones: expected an array, got ${typeof dto.milestones}`
977
+ );
771
978
  }
772
979
  if (!Array.isArray(dto.tokens)) {
773
- throw new Error(`tokens must be an array`);
980
+ throw new ValidationError(
981
+ `OfferDetail.tokens: expected an array, got ${typeof dto.tokens}`
982
+ );
774
983
  }
775
984
  return {
776
985
  id: OfferId(dto.id),
@@ -832,13 +1041,6 @@ var Milestone = {
832
1041
  status: dto.status
833
1042
  })
834
1043
  };
835
- var OfferToken = {
836
- fromDto: (dto) => ({
837
- role: dto.role,
838
- chain: Chain(dto.chain),
839
- address: EvmContractAddress(dto.address)
840
- })
841
- };
842
1044
 
843
1045
  // src/shared/types/providers/coin-list/token-sale.ts
844
1046
  var ParticipationId = (value) => value;
@@ -925,22 +1127,31 @@ async function createParticipation(api, params) {
925
1127
  var CoinListTokenSaleNamespaceImpl = class {
926
1128
  constructor(ctx) {
927
1129
  this.ctx = ctx;
1130
+ this.log = internalLogger(ctx.logger, "TOKEN_SALE");
928
1131
  }
929
1132
  async list(offerId) {
930
- await this.ctx.ensureUserAuthenticated();
931
- return fetchParticipations(this.ctx.api, offerId);
1133
+ return this.log.wrap("list", offerId, async () => {
1134
+ await this.ctx.ensureUserAuthenticated();
1135
+ return fetchParticipations(this.ctx.api, offerId);
1136
+ });
932
1137
  }
933
1138
  async listPage(params) {
934
- await this.ctx.ensureUserAuthenticated();
935
- return fetchParticipationsPage(this.ctx.api, params);
1139
+ return this.log.wrap("listPage", params, async () => {
1140
+ await this.ctx.ensureUserAuthenticated();
1141
+ return fetchParticipationsPage(this.ctx.api, params);
1142
+ });
936
1143
  }
937
1144
  async get(id) {
938
- await this.ctx.ensureUserAuthenticated();
939
- return fetchParticipation(this.ctx.api, id);
1145
+ return this.log.wrap("get", id, async () => {
1146
+ await this.ctx.ensureUserAuthenticated();
1147
+ return fetchParticipation(this.ctx.api, id);
1148
+ });
940
1149
  }
941
1150
  async createParticipation(params) {
942
- await this.ctx.ensureUserAuthenticated();
943
- return createParticipation(this.ctx.api, params);
1151
+ return this.log.wrap("createParticipation", params, async () => {
1152
+ await this.ctx.ensureUserAuthenticated();
1153
+ return createParticipation(this.ctx.api, params);
1154
+ });
944
1155
  }
945
1156
  };
946
1157
 
@@ -1107,18 +1318,25 @@ function sizeParam(params) {
1107
1318
  var OndoNamespaceImpl = class {
1108
1319
  constructor(ctx) {
1109
1320
  this.ctx = ctx;
1321
+ this.log = internalLogger(ctx.logger, "ONDO");
1110
1322
  }
1111
1323
  async getTradingStatus(params) {
1112
- await this.ctx.ensureUserAuthenticated();
1113
- return getOndoTradingStatus(this.ctx.api, params);
1324
+ return this.log.wrap("getTradingStatus", params, async () => {
1325
+ await this.ctx.ensureUserAuthenticated();
1326
+ return getOndoTradingStatus(this.ctx.api, params);
1327
+ });
1114
1328
  }
1115
1329
  async getQuote(params) {
1116
- await this.ctx.ensureUserAuthenticated();
1117
- return getOndoQuote(this.ctx.api, params);
1330
+ return this.log.wrap("getQuote", params, async () => {
1331
+ await this.ctx.ensureUserAuthenticated();
1332
+ return getOndoQuote(this.ctx.api, params);
1333
+ });
1118
1334
  }
1119
1335
  async buildSwapTransaction(params) {
1120
- await this.ctx.ensureUserAuthenticated();
1121
- return buildOndoSwapTransaction(this.ctx.api, params);
1336
+ return this.log.wrap("buildSwapTransaction", params, async () => {
1337
+ await this.ctx.ensureUserAuthenticated();
1338
+ return buildOndoSwapTransaction(this.ctx.api, params);
1339
+ });
1122
1340
  }
1123
1341
  };
1124
1342
 
@@ -1126,26 +1344,37 @@ var OndoNamespaceImpl = class {
1126
1344
  var SuperstateSwapNamespaceImpl = class {
1127
1345
  constructor(ctx) {
1128
1346
  this.ctx = ctx;
1347
+ this.log = internalLogger(ctx.logger, "SUPERSTATE");
1129
1348
  }
1130
1349
  async getAuthorization(params) {
1131
- await this.ctx.ensureUserAuthenticated();
1132
- return getSwapAuthorization(this.ctx.api, params);
1350
+ return this.log.wrap("getAuthorization", params, async () => {
1351
+ await this.ctx.ensureUserAuthenticated();
1352
+ return getSwapAuthorization(this.ctx.api, params);
1353
+ });
1133
1354
  }
1134
1355
  async getPreview(params) {
1135
- await this.ctx.ensureUserAuthenticated();
1136
- return getSwapPreview(this.ctx.api, params);
1356
+ return this.log.wrap("getPreview", params, async () => {
1357
+ await this.ctx.ensureUserAuthenticated();
1358
+ return getSwapPreview(this.ctx.api, params);
1359
+ });
1137
1360
  }
1138
1361
  async getStatus(params) {
1139
- await this.ctx.ensureUserAuthenticated();
1140
- return getSwapStatus(this.ctx.api, params);
1362
+ return this.log.wrap("getStatus", params, async () => {
1363
+ await this.ctx.ensureUserAuthenticated();
1364
+ return getSwapStatus(this.ctx.api, params);
1365
+ });
1141
1366
  }
1142
1367
  async getOutputToken(params) {
1143
- await this.ctx.ensureUserAuthenticated();
1144
- return getSwapOutputToken(this.ctx.api, params);
1368
+ return this.log.wrap("getOutputToken", params, async () => {
1369
+ await this.ctx.ensureUserAuthenticated();
1370
+ return getSwapOutputToken(this.ctx.api, params);
1371
+ });
1145
1372
  }
1146
1373
  async allowWallet(params) {
1147
- await this.ctx.ensureUserAuthenticated();
1148
- return allowWallet(this.ctx.api, params);
1374
+ return this.log.wrap("allowWallet", params, async () => {
1375
+ await this.ctx.ensureUserAuthenticated();
1376
+ return allowWallet(this.ctx.api, params);
1377
+ });
1149
1378
  }
1150
1379
  };
1151
1380
 
@@ -1278,38 +1507,49 @@ async function fetchRequirementStatuses(api, offerId) {
1278
1507
  var RequirementsNamespaceImpl = class {
1279
1508
  constructor(ctx) {
1280
1509
  this.ctx = ctx;
1510
+ this.log = internalLogger(ctx.logger, "REQUIREMENTS");
1281
1511
  }
1282
1512
  async forOffer(offerId) {
1283
- await this.ctx.ensureUserAuthenticated();
1284
- return fetchOfferRequirements(
1285
- this.ctx.api,
1286
- offerId,
1287
- void 0
1288
- );
1513
+ return this.log.wrap("forOffer", offerId, async () => {
1514
+ await this.ctx.ensureUserAuthenticated();
1515
+ return fetchOfferRequirements(
1516
+ this.ctx.api,
1517
+ offerId,
1518
+ void 0
1519
+ );
1520
+ });
1289
1521
  }
1290
1522
  async statuses(offerId) {
1291
- await this.ctx.ensureUserAuthenticated();
1292
- return fetchRequirementStatuses(this.ctx.api, offerId);
1523
+ return this.log.wrap("statuses", offerId, async () => {
1524
+ await this.ctx.ensureUserAuthenticated();
1525
+ return fetchRequirementStatuses(this.ctx.api, offerId);
1526
+ });
1293
1527
  }
1294
1528
  async createKycToken(params) {
1295
- await this.ctx.ensureUserAuthenticated();
1296
- return createKycToken(
1297
- this.ctx.api,
1298
- params?.levelName,
1299
- params?.reset
1300
- );
1529
+ return this.log.wrap("createKycToken", params, async () => {
1530
+ await this.ctx.ensureUserAuthenticated();
1531
+ return createKycToken(
1532
+ this.ctx.api,
1533
+ params?.levelName,
1534
+ params?.reset
1535
+ );
1536
+ });
1301
1537
  }
1302
1538
  async getPii() {
1303
- await this.ctx.ensureUserAuthenticated();
1304
- return fetchPii(this.ctx.api);
1539
+ return this.log.wrap("getPii", void 0, async () => {
1540
+ await this.ctx.ensureUserAuthenticated();
1541
+ return fetchPii(this.ctx.api);
1542
+ });
1305
1543
  }
1306
1544
  async submitDocument(params) {
1307
- await this.ctx.ensureUserAuthenticated();
1308
- return submitDocument(
1309
- this.ctx.api,
1310
- params.documentType,
1311
- params.fields
1312
- );
1545
+ return this.log.wrap("submitDocument", params, async () => {
1546
+ await this.ctx.ensureUserAuthenticated();
1547
+ return submitDocument(
1548
+ this.ctx.api,
1549
+ params.documentType,
1550
+ params.fields
1551
+ );
1552
+ });
1313
1553
  }
1314
1554
  };
1315
1555
 
@@ -1339,27 +1579,47 @@ var TokenMetadata = {
1339
1579
  logoDark: dto.logo_dark === void 0 ? null : TokenLogo.fromDto(dto.logo_dark, baseUrl)
1340
1580
  };
1341
1581
  },
1582
+ /**
1583
+ * Maps the complete registry snapshot to every token it lists across the
1584
+ * chains this SDK models, skipping native coins and chains outside
1585
+ * {@link EthereumChain} (e.g. Solana) rather than failing on them — the
1586
+ * registry may serve chains ahead of the SDK's type surface.
1587
+ */
1588
+ fromRegistryDto: (dto, baseUrl) => {
1589
+ assertSupportedSchemaVersion(dto.schema_version);
1590
+ return dto.chains.flatMap((chainDto) => {
1591
+ let chain;
1592
+ try {
1593
+ chain = EthereumChain(chainDto.chain);
1594
+ } catch {
1595
+ return [];
1596
+ }
1597
+ return tokensOfChain(chain, chainDto.assets, baseUrl);
1598
+ });
1599
+ },
1342
1600
  /**
1343
1601
  * Maps a chain snapshot to the tokens it lists, skipping the chain's native
1344
1602
  * coin (`kind: 'COIN'`, no contract address).
1345
1603
  */
1346
1604
  fromChainAssetsDto: (dto, baseUrl) => {
1347
1605
  assertSupportedSchemaVersion(dto.schema_version);
1348
- const chain = EthereumChain(dto.chain);
1349
- return dto.assets.filter((asset) => asset.kind === "TOKEN" && asset.address !== void 0).map((asset) => ({
1350
- identifier: {
1351
- chain,
1352
- // The filter above cannot narrow `address` for the type checker.
1353
- address: EvmContractAddress(asset.address)
1354
- },
1355
- name: asset.name,
1356
- symbol: AssetSymbol(asset.symbol),
1357
- decimals: AssetDecimals(asset.decimals),
1358
- logo: TokenLogo.fromDto(asset.logo, baseUrl),
1359
- logoDark: asset.logo_dark === void 0 ? null : TokenLogo.fromDto(asset.logo_dark, baseUrl)
1360
- }));
1606
+ return tokensOfChain(EthereumChain(dto.chain), dto.assets, baseUrl);
1361
1607
  }
1362
1608
  };
1609
+ function tokensOfChain(chain, assets, baseUrl) {
1610
+ return assets.filter((asset) => asset.kind === "TOKEN" && asset.address !== void 0).map((asset) => ({
1611
+ identifier: {
1612
+ chain,
1613
+ // The filter above cannot narrow `address` for the type checker.
1614
+ address: EvmContractAddress(asset.address)
1615
+ },
1616
+ name: asset.name,
1617
+ symbol: AssetSymbol(asset.symbol),
1618
+ decimals: AssetDecimals(asset.decimals),
1619
+ logo: TokenLogo.fromDto(asset.logo, baseUrl),
1620
+ logoDark: asset.logo_dark === void 0 ? null : TokenLogo.fromDto(asset.logo_dark, baseUrl)
1621
+ }));
1622
+ }
1363
1623
  function assertSupportedSchemaVersion(version) {
1364
1624
  if (version !== 1) {
1365
1625
  throw new ValidationError(
@@ -1389,17 +1649,16 @@ var COINLIST_BASE_URL = "https://coinlist.co";
1389
1649
  var OAUTH_PAGE_PATH = "/oauth/authorize";
1390
1650
  var SUPPORT_NEW_TICKET_URL = "https://support.coinlist.co/support/tickets/new";
1391
1651
  var VERIFY_IDENTITY_PATH = "/verify-identity";
1392
- var VERIFY_IDENTITY_VERIFIED_PATH = "/verify-identity/identity_verified";
1393
- var VERIFY_IDENTITY_PROOF_OF_ADDRESS_PATH = "/verify-identity/proof_of_address";
1394
- var VERIFY_IDENTITY_SOURCE_OF_FUNDS_PATH = "/verify-identity/source_of_funds";
1395
1652
  var VERIFY_IDENTITY_ACCREDITATION_PATH = "/verify-identity/accreditation_full";
1396
1653
  var WALLET_PATH = "/wallet";
1397
1654
 
1398
1655
  // src/shared/api/http-client.ts
1399
1656
  var HttpClient = class {
1400
- constructor(config, middleware = {}) {
1657
+ constructor(config, middleware = {}, logger = null, options = {}) {
1401
1658
  this.config = config;
1402
1659
  this.middleware = middleware;
1660
+ this.log = internalLogger(logger, "HTTP");
1661
+ this.makeRequestId = options.makeRequestId ?? defaultMakeRequestId;
1403
1662
  }
1404
1663
  async send(request) {
1405
1664
  return this.runRequestWithAfterMiddleware(request);
@@ -1435,7 +1694,13 @@ var HttpClient = class {
1435
1694
  return {
1436
1695
  ...request,
1437
1696
  url,
1438
- headers
1697
+ headers,
1698
+ // Only when absent: a retry or a post-renewal re-send arrives with the
1699
+ // first attempt's id already on it, and keeping it is the whole point.
1700
+ attributes: Attributes.getRequestId(request.attributes) === null ? Attributes.concat(
1701
+ request.attributes ?? Attributes.empty,
1702
+ Attributes.requestId(this.makeRequestId())
1703
+ ) : request.attributes
1439
1704
  };
1440
1705
  }
1441
1706
  /**
@@ -1459,14 +1724,93 @@ var HttpClient = class {
1459
1724
  }
1460
1725
  return request;
1461
1726
  }
1462
- executeRequest(request) {
1463
- return makeRequest(request);
1727
+ /**
1728
+ * One physical attempt, logged as one line.
1729
+ *
1730
+ * A non-2xx is a `warn` rather than an `error` because the wire does not
1731
+ * know whether it is a failure: the retry middleware may turn a 503 into a
1732
+ * success, and the token registry reads a 404 as "not listed". The namespace
1733
+ * above decides, and logs the `error` when it does.
1734
+ */
1735
+ async executeRequest(request) {
1736
+ const requestId2 = Attributes.getRequestId(request.attributes);
1737
+ const log = requestId2 === null ? this.log : this.log.child({ requestId: requestId2 });
1738
+ const attempt = Attributes.getRetryAttempt(request.attributes) + 1;
1739
+ const startedAt = Date.now();
1740
+ log.debug(() => ({
1741
+ msg: "request sent",
1742
+ fields: describeRequestUnredacted(request)
1743
+ }));
1744
+ try {
1745
+ const response = await makeRequest(request);
1746
+ const elapsed = Date.now() - startedAt;
1747
+ const outcome = () => ({
1748
+ msg: "request completed",
1749
+ fields: {
1750
+ ...identifyRequest(request),
1751
+ "http.response.status_code": response.status,
1752
+ duration_ms: elapsed,
1753
+ attempt
1754
+ }
1755
+ });
1756
+ if (response.status >= 200 && response.status < 300) {
1757
+ log.info(outcome);
1758
+ } else {
1759
+ log.warn(outcome);
1760
+ }
1761
+ log.debug(() => ({
1762
+ msg: "response received",
1763
+ fields: { body: response.body }
1764
+ }));
1765
+ return requestId2 === null ? response : { ...response, requestId: requestId2 };
1766
+ } catch (error) {
1767
+ const elapsed = Date.now() - startedAt;
1768
+ log.warning(
1769
+ () => ({
1770
+ msg: "request threw",
1771
+ fields: {
1772
+ ...identifyRequest(request),
1773
+ duration_ms: elapsed,
1774
+ attempt
1775
+ }
1776
+ }),
1777
+ error
1778
+ );
1779
+ throw error;
1780
+ }
1464
1781
  }
1465
1782
  };
1783
+ function identifyRequest(request) {
1784
+ const { host, path } = splitUrl(request.url);
1785
+ return {
1786
+ "http.request.method": request.method,
1787
+ "server.address": host,
1788
+ "url.path": path
1789
+ };
1790
+ }
1791
+ function splitUrl(url) {
1792
+ try {
1793
+ const parsed = new URL(url);
1794
+ return { host: parsed.host, path: parsed.pathname };
1795
+ } catch (_) {
1796
+ return { host: null, path: url };
1797
+ }
1798
+ }
1799
+ function defaultMakeRequestId() {
1800
+ return Math.random().toString(36).slice(2, 10).padEnd(8, "0");
1801
+ }
1802
+ function describeRequestUnredacted(request) {
1803
+ return {
1804
+ "http.request.method": request.method,
1805
+ "url.full": buildUrlWithQueryParams(request.url, request.queryParams),
1806
+ headers: request.headers,
1807
+ ...request.method === "POST" ? { body: request.body } : {}
1808
+ };
1809
+ }
1466
1810
 
1467
1811
  // src/shared/api/nabu/tokens.ts
1468
- function createNabuApiClient(baseUrl) {
1469
- return new HttpClient({ baseUrl });
1812
+ function createNabuApiClient(baseUrl, logger = null) {
1813
+ return new HttpClient({ baseUrl }, {}, logger);
1470
1814
  }
1471
1815
  async function fetchTokenMetadata(client, token) {
1472
1816
  const address = checksummed(token.address);
@@ -1516,6 +1860,29 @@ async function fetchTokensMetadata(client, chain) {
1516
1860
  }
1517
1861
  return TokenMetadata.fromChainAssetsDto(response.body, client.config.baseUrl);
1518
1862
  }
1863
+ async function fetchAllTokensMetadata(client) {
1864
+ let response;
1865
+ try {
1866
+ response = await client.send({
1867
+ method: "GET",
1868
+ url: `/assets.json`
1869
+ });
1870
+ } catch (error) {
1871
+ if (isRegistryHtmlFallback(error)) {
1872
+ throw new ValidationError(
1873
+ "Token registry returned non-JSON for the complete snapshot"
1874
+ );
1875
+ }
1876
+ throw error;
1877
+ }
1878
+ assertOk(response);
1879
+ if (response.body === null) {
1880
+ throw new ValidationError(
1881
+ "Token registry returned an empty complete snapshot"
1882
+ );
1883
+ }
1884
+ return TokenMetadata.fromRegistryDto(response.body, client.config.baseUrl);
1885
+ }
1519
1886
  function isRegistryHtmlFallback(error) {
1520
1887
  return error instanceof HttpError && error.response.status >= 200 && error.response.status < 300;
1521
1888
  }
@@ -1539,14 +1906,23 @@ var TokensNamespaceImpl = class {
1539
1906
  * registry is unauthenticated and on its own host, so the frontline sender
1540
1907
  * and the auth check would both be dead weight here.
1541
1908
  */
1542
- constructor(baseUrl) {
1543
- this.api = createNabuApiClient(baseUrl);
1909
+ constructor(baseUrl, logger = null) {
1910
+ this.api = createNabuApiClient(baseUrl, logger);
1911
+ this.log = internalLogger(logger, "TOKENS");
1544
1912
  }
1545
1913
  get(token) {
1546
- return fetchTokenMetadata(this.api, token);
1914
+ return this.log.wrap(
1915
+ "get",
1916
+ token,
1917
+ () => fetchTokenMetadata(this.api, token)
1918
+ );
1547
1919
  }
1548
1920
  list(chain) {
1549
- return fetchTokensMetadata(this.api, chain);
1921
+ return this.log.wrap(
1922
+ "list",
1923
+ chain,
1924
+ () => chain === void 0 ? fetchAllTokensMetadata(this.api) : fetchTokensMetadata(this.api, chain)
1925
+ );
1550
1926
  }
1551
1927
  };
1552
1928
 
@@ -1652,33 +2028,42 @@ async function removeOptionAddress(api, offerId, addressId) {
1652
2028
  var WalletsNamespaceImpl = class {
1653
2029
  constructor(ctx) {
1654
2030
  this.ctx = ctx;
2031
+ this.log = internalLogger(ctx.logger, "WALLETS");
1655
2032
  }
1656
2033
  async createOwnershipChallenge(params) {
1657
- await this.ctx.ensureUserAuthenticated();
1658
- return createWalletOwnershipChallenge(
1659
- this.ctx.api,
1660
- params
1661
- );
2034
+ return this.log.wrap("createOwnershipChallenge", params, async () => {
2035
+ await this.ctx.ensureUserAuthenticated();
2036
+ return createWalletOwnershipChallenge(
2037
+ this.ctx.api,
2038
+ params
2039
+ );
2040
+ });
1662
2041
  }
1663
2042
  async connectExternal(params) {
1664
- await this.ctx.ensureUserAuthenticated();
1665
- return connectExternalWallet(this.ctx.api, params);
2043
+ return this.log.wrap("connectExternal", params, async () => {
2044
+ await this.ctx.ensureUserAuthenticated();
2045
+ return connectExternalWallet(this.ctx.api, params);
2046
+ });
1666
2047
  }
1667
2048
  async list(params) {
1668
- await this.ctx.ensureUserAuthenticated();
1669
- return listOptionAddresses(
1670
- this.ctx.api,
1671
- params.offerId,
1672
- params.offerOptionId
1673
- );
2049
+ return this.log.wrap("list", params, async () => {
2050
+ await this.ctx.ensureUserAuthenticated();
2051
+ return listOptionAddresses(
2052
+ this.ctx.api,
2053
+ params.offerId,
2054
+ params.offerOptionId
2055
+ );
2056
+ });
1674
2057
  }
1675
2058
  async remove(params) {
1676
- await this.ctx.ensureUserAuthenticated();
1677
- return removeOptionAddress(
1678
- this.ctx.api,
1679
- params.offerId,
1680
- params.addressId
1681
- );
2059
+ return this.log.wrap("remove", params, async () => {
2060
+ await this.ctx.ensureUserAuthenticated();
2061
+ return removeOptionAddress(
2062
+ this.ctx.api,
2063
+ params.offerId,
2064
+ params.addressId
2065
+ );
2066
+ });
1682
2067
  }
1683
2068
  };
1684
2069
 
@@ -1740,20 +2125,20 @@ export {
1740
2125
  OAUTH_PAGE_PATH,
1741
2126
  SUPPORT_NEW_TICKET_URL,
1742
2127
  VERIFY_IDENTITY_PATH,
1743
- VERIFY_IDENTITY_VERIFIED_PATH,
1744
- VERIFY_IDENTITY_PROOF_OF_ADDRESS_PATH,
1745
- VERIFY_IDENTITY_SOURCE_OF_FUNDS_PATH,
1746
2128
  VERIFY_IDENTITY_ACCREDITATION_PATH,
1747
2129
  WALLET_PATH,
1748
2130
  Attributes,
1749
2131
  HttpError,
1750
2132
  apiErrorCode,
1751
2133
  Request,
1752
- HttpClient,
1753
- fetchAllPages,
1754
2134
  NotImplementedError,
1755
2135
  NotAuthenticatedError,
1756
2136
  ValidationError,
2137
+ InvariantError,
2138
+ describeErrorUnredacted,
2139
+ internalLogger,
2140
+ HttpClient,
2141
+ fetchAllPages,
1757
2142
  ETHEREUM_CHAINS,
1758
2143
  EthereumChain,
1759
2144
  SOLANA_CHAINS,
@@ -1768,6 +2153,7 @@ export {
1768
2153
  DecimalString,
1769
2154
  MAX_UINT_256,
1770
2155
  assertUint256,
2156
+ parseUint256,
1771
2157
  BlockchainAmount,
1772
2158
  AssetSymbol,
1773
2159
  StablecoinSymbol,
@@ -1810,6 +2196,7 @@ export {
1810
2196
  OfferId,
1811
2197
  OfferSlug,
1812
2198
  Offer,
2199
+ OfferToken,
1813
2200
  OfferOptionId,
1814
2201
  OfferOptionSlug,
1815
2202
  OfferDetail,
@@ -1818,7 +2205,6 @@ export {
1818
2205
  Link,
1819
2206
  TermItem,
1820
2207
  Milestone,
1821
- OfferToken,
1822
2208
  ParticipationId,
1823
2209
  Blockchain,
1824
2210
  WalletAddress,
@@ -1860,4 +2246,4 @@ export {
1860
2246
  OAuthRefreshToken,
1861
2247
  OAuthSession
1862
2248
  };
1863
- //# sourceMappingURL=chunk-UIIXXLA7.js.map
2249
+ //# sourceMappingURL=chunk-3Z4PLLV7.js.map