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

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 (31) hide show
  1. package/dist/{chunk-DCW7NQXH.js → chunk-2HCSM3FB.js} +52 -19
  2. package/dist/chunk-2HCSM3FB.js.map +1 -0
  3. package/dist/{chunk-VH34YC3Q.js → chunk-OUFI3D3Q.js} +84 -4
  4. package/dist/chunk-OUFI3D3Q.js.map +1 -0
  5. package/dist/{chunk-MOE5S6CE.js → chunk-YMDYLYL3.js} +954 -441
  6. package/dist/chunk-YMDYLYL3.js.map +1 -0
  7. package/dist/client/index.cjs +12477 -8512
  8. package/dist/client/index.cjs.map +1 -1
  9. package/dist/client/index.d.cts +1965 -229
  10. package/dist/client/index.d.ts +1965 -229
  11. package/dist/client/index.js +9118 -5742
  12. package/dist/client/index.js.map +1 -1
  13. package/dist/server/index.cjs +844 -142
  14. package/dist/server/index.cjs.map +1 -1
  15. package/dist/server/index.d.cts +72 -41
  16. package/dist/server/index.d.ts +72 -41
  17. package/dist/server/index.js +323 -65
  18. package/dist/server/index.js.map +1 -1
  19. package/dist/{tokens-namespace-CIWBtgt2.d.cts → time-DJU6E8KK.d.cts} +943 -192
  20. package/dist/{tokens-namespace-CIWBtgt2.d.ts → time-DJU6E8KK.d.ts} +943 -192
  21. package/dist/{token-registry-snapshot-CqI6dXM_.d.cts → token-registry-snapshot-B0xCp3GD.d.cts} +74 -8
  22. package/dist/{token-registry-snapshot-BNBNuDu1.d.ts → token-registry-snapshot-DGG5N27C.d.ts} +74 -8
  23. package/dist/universal/index.cjs +1036 -439
  24. package/dist/universal/index.cjs.map +1 -1
  25. package/dist/universal/index.d.cts +105 -5
  26. package/dist/universal/index.d.ts +105 -5
  27. package/dist/universal/index.js +48 -2
  28. package/package.json +1 -1
  29. package/dist/chunk-DCW7NQXH.js.map +0 -1
  30. package/dist/chunk-MOE5S6CE.js.map +0 -1
  31. package/dist/chunk-VH34YC3Q.js.map +0 -1
@@ -1,3 +1,27 @@
1
+ // src/universal/api/internal-access-token-source.ts
2
+ var SentWith = {
3
+ userToken: (token) => ({
4
+ type: "user-token",
5
+ token
6
+ }),
7
+ noUserToken: { type: "no-user-token" }
8
+ };
9
+ var TokenTrigger = {
10
+ beforeRequest: { type: "before-request" },
11
+ after401: (rejected) => ({
12
+ type: "after-401",
13
+ rejected
14
+ })
15
+ };
16
+ function isRejectedToken(token, rejected) {
17
+ switch (rejected.type) {
18
+ case "user-token":
19
+ return rejected.token.value === token.value;
20
+ case "no-user-token":
21
+ return false;
22
+ }
23
+ }
24
+
1
25
  // src/universal/api/http-attributes.ts
2
26
  var empty = {};
3
27
  var concat = (left, right) => ({
@@ -25,6 +49,10 @@ var retryAttempt = (attempt) => ({
25
49
  var renewAttempted = (value) => ({
26
50
  renewAttempted: value
27
51
  });
52
+ var notRetryable = () => ({ retryable: false });
53
+ var sentWith = (token) => ({
54
+ sentWith: token
55
+ });
28
56
  var requestId = (id) => ({ requestId: id });
29
57
  var getRequestId = (attrs) => attrs?.requestId ?? null;
30
58
  var isProtected = (attrs) => attrs?.protected === true;
@@ -32,6 +60,8 @@ var needUserAgent = (attrs) => attrs?.userAgent === true;
32
60
  var isIdempotent = (attrs) => attrs?.idempotencyKey === true;
33
61
  var getRetryAttempt = (attrs) => attrs?.retryAttempt ?? 0;
34
62
  var wasRenewAttempted = (attrs) => attrs?.renewAttempted === true;
63
+ var isRetryable = (attrs) => attrs?.retryable !== false;
64
+ var getSentWith = (attrs) => attrs?.sentWith === void 0 ? SentWith.noUserToken : SentWith.userToken(attrs.sentWith);
35
65
  var getClientCredentials = (attrs) => attrs?.clientCredentials;
36
66
  var Attributes = {
37
67
  empty,
@@ -47,6 +77,10 @@ var Attributes = {
47
77
  getRetryAttempt,
48
78
  renewAttempted,
49
79
  wasRenewAttempted,
80
+ notRetryable,
81
+ isRetryable,
82
+ sentWith,
83
+ getSentWith,
50
84
  clientCredentials,
51
85
  getClientCredentials,
52
86
  requestId,
@@ -209,6 +243,54 @@ var MathError = class extends Error {
209
243
  }
210
244
  };
211
245
 
246
+ // src/universal/types/time.ts
247
+ var MAX_EPOCH_MILLIS = 864e13;
248
+ var EpochMillis = {
249
+ /**
250
+ * @throws {@link ValidationError} unless `value` is an integer a `Date` can
251
+ * represent: at most {@link MAX_EPOCH_MILLIS} either side of the epoch.
252
+ */
253
+ of: (value) => {
254
+ if (!Number.isInteger(value) || Math.abs(value) > MAX_EPOCH_MILLIS) {
255
+ throw new ValidationError(
256
+ `EpochMillis must be an integer within \xB1${MAX_EPOCH_MILLIS}, got ${value}`
257
+ );
258
+ }
259
+ return value;
260
+ },
261
+ /** The wall clock. Code that needs the time takes a `TimeEff` instead. */
262
+ now: () => EpochMillis.of(Date.now()),
263
+ /** @throws {@link ValidationError} for an invalid `Date`. */
264
+ fromDate: (date) => EpochMillis.of(date.getTime()),
265
+ /** How long after `from` the instant `to` is; negative if it is before. */
266
+ elapsed: (from, to) => Millis.of(to - from),
267
+ plus: (at, duration) => EpochMillis.of(at + duration)
268
+ };
269
+ var Millis = {
270
+ of: (value) => value
271
+ };
272
+ var Seconds = {
273
+ /**
274
+ * @throws {@link ValidationError} unless `value` is a non-negative integer.
275
+ */
276
+ of: (value) => {
277
+ if (!Number.isInteger(value) || value < 0) {
278
+ throw new ValidationError(
279
+ `Seconds must be a non-negative integer, got ${value}`
280
+ );
281
+ }
282
+ return value;
283
+ },
284
+ toMillis: (value) => Millis.of(value * 1e3)
285
+ };
286
+ function isExpired({
287
+ expiresAt,
288
+ now,
289
+ buffer = Millis.of(0)
290
+ }) {
291
+ return now >= expiresAt - buffer;
292
+ }
293
+
212
294
  // src/universal/core/shared/blockchain/erc20/abi.ts
213
295
  var ERC20_ABI = [
214
296
  {
@@ -309,66 +391,6 @@ var ERC20_ABI = [
309
391
  }
310
392
  ];
311
393
 
312
- // src/universal/api/pagination.ts
313
- async function fetchAllPages(fetchPage, baseParams) {
314
- const items = [];
315
- let cursor = null;
316
- do {
317
- const params = {
318
- ...baseParams ?? {},
319
- after: cursor ?? void 0
320
- };
321
- const page = await fetchPage(params);
322
- items.push(...page.data);
323
- cursor = page.startingAfter;
324
- } while (cursor);
325
- return items;
326
- }
327
-
328
- // src/universal/types/pagination.ts
329
- var Cursor = (value) => value;
330
- var PaginatedResponse = {
331
- fromDto: (dto, itemMapper) => PaginatedResponse.fromDtoPage(dto, (items) => items.map(itemMapper)),
332
- /**
333
- * For a mapper that decides the page as a whole - one that drops items it
334
- * cannot map, such as `Offer.listFromDto` - rather than item by item. The
335
- * cursors are the wire's either way: dropping an item changes what the
336
- * page holds, not where the next page starts.
337
- */
338
- fromDtoPage: (dto, pageMapper) => ({
339
- data: pageMapper(dto.data),
340
- startingAfter: dto.starting_after ? Cursor(dto.starting_after) : null,
341
- startingBefore: dto.starting_before ? Cursor(dto.starting_before) : null
342
- })
343
- };
344
- var PaginationParams = {
345
- toQueryParams: (params) => {
346
- const queryParams = {};
347
- if (params.after) {
348
- queryParams.starting_after = params.after;
349
- }
350
- if (params.before) {
351
- queryParams.starting_before = params.before;
352
- }
353
- if (params.limit) {
354
- queryParams.limit = params.limit;
355
- }
356
- return queryParams;
357
- }
358
- };
359
-
360
- // src/universal/types/asset.ts
361
- var AssetId = (value) => value;
362
- var AssetCode = (value) => value;
363
- var Asset = {
364
- fromDto: (dto) => ({
365
- id: AssetId(dto.id),
366
- code: AssetCode(dto.code),
367
- name: dto.name,
368
- fractionalDigits: dto.fractional_digits
369
- })
370
- };
371
-
372
394
  // src/universal/types/blockchain/core.ts
373
395
  var ETHEREUM_CHAINS = {
374
396
  ethereum_mainnet: true,
@@ -466,6 +488,66 @@ var StablecoinSymbol = (value) => value;
466
488
  var KnownAssetSymbol = StablecoinSymbol;
467
489
  var Bps = (value) => value;
468
490
 
491
+ // src/universal/core/shared/blockchain/math.ts
492
+ import { parseUnits } from "viem";
493
+ function blockchainAmountFromRawOrThrow({
494
+ label,
495
+ raw,
496
+ decimals
497
+ }) {
498
+ const trimmed = raw.trim();
499
+ if (trimmed === "") {
500
+ throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
501
+ }
502
+ let value;
503
+ try {
504
+ value = BigInt(trimmed);
505
+ } catch {
506
+ throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
507
+ }
508
+ try {
509
+ return BlockchainAmount({ raw: assertUint256(value), decimals });
510
+ } catch {
511
+ throw new ValidationError(`${label}: out of uint256 bounds (${value})`);
512
+ }
513
+ }
514
+ function parseBlockchainAmount(amount, decimals) {
515
+ const trimmed = amount.trim();
516
+ if (trimmed === "") return { valid: false, reason: { type: "empty" } };
517
+ if (trimmed.startsWith("-")) {
518
+ return { valid: false, reason: { type: "negative" } };
519
+ }
520
+ if (/[eE]/.test(trimmed)) {
521
+ return { valid: false, reason: { type: "invalid-format" } };
522
+ }
523
+ if (trimmed === ".") {
524
+ return { valid: false, reason: { type: "invalid-format" } };
525
+ }
526
+ const normalised = trimmed.replace(/^\./, "0.").replace(/\.$/, "");
527
+ if (!/^\d+(\.\d+)?$/.test(normalised)) {
528
+ return { valid: false, reason: { type: "invalid-format" } };
529
+ }
530
+ const [, fraction = ""] = normalised.split(".");
531
+ if (fraction.length > decimals) {
532
+ return {
533
+ valid: false,
534
+ reason: { type: "too-many-decimals", maxDecimals: decimals }
535
+ };
536
+ }
537
+ try {
538
+ const raw = parseUnits(normalised, decimals);
539
+ if (raw > MAX_UINT_256) {
540
+ return { valid: false, reason: { type: "overflow" } };
541
+ }
542
+ return {
543
+ valid: true,
544
+ amount: BlockchainAmount({ raw, decimals })
545
+ };
546
+ } catch {
547
+ return { valid: false, reason: { type: "invalid-format" } };
548
+ }
549
+ }
550
+
469
551
  // src/universal/core/shared/utils/crypto.ts
470
552
  async function sha256(data) {
471
553
  const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
@@ -541,6 +623,12 @@ function requiredDate(value, field) {
541
623
  }
542
624
  return date;
543
625
  }
626
+ function dateOrNull(value, field) {
627
+ return value === null ? null : requiredDate(value, field);
628
+ }
629
+ function decimalOrNull(value) {
630
+ return value === null ? null : DecimalString(value);
631
+ }
544
632
  function requiredArray(value, field) {
545
633
  if (!Array.isArray(value)) {
546
634
  throw new ValidationError(
@@ -550,78 +638,658 @@ function requiredArray(value, field) {
550
638
  return value;
551
639
  }
552
640
 
553
- // src/universal/types/offer.ts
554
- var OfferId = (value) => value;
555
- var OfferSlug = (value) => value;
556
- var OFFER_TYPES = {
557
- "coinlist::token_sale": true,
558
- "superstate::swap": true,
559
- "ondo::swap": true
641
+ // src/universal/types/providers/centrifuge/centrifuge.ts
642
+ var CentrifugeVaultQuote = {
643
+ fromDto: (dto) => {
644
+ const spendDecimals = AssetDecimals(dto.spend_input_decimals);
645
+ const shareDecimals = AssetDecimals(dto.share_decimals);
646
+ return {
647
+ chain: EthereumChain(dto.chain),
648
+ symbol: AssetSymbol(dto.symbol),
649
+ spendInputAmount: blockchainAmountFromRawOrThrow({
650
+ label: "spend_input_amount",
651
+ raw: dto.spend_input_amount,
652
+ decimals: spendDecimals
653
+ }),
654
+ estimatedShares: blockchainAmountFromRawOrThrow({
655
+ label: "estimated_shares",
656
+ raw: dto.estimated_shares,
657
+ decimals: shareDecimals
658
+ }),
659
+ indicativePrice: decimalOrNull(dto.indicative_price),
660
+ minimumInputAmount: dto.minimum_input_amount === null ? null : blockchainAmountFromRawOrThrow({
661
+ label: "minimum_input_amount",
662
+ raw: dto.minimum_input_amount,
663
+ decimals: spendDecimals
664
+ }),
665
+ orderability: parseOrderability(
666
+ dto.can_order,
667
+ dto.reasons,
668
+ "CentrifugeVaultQuote"
669
+ )
670
+ };
671
+ }
560
672
  };
561
- var isOfferType = (value) => Object.keys(OFFER_TYPES).includes(value);
562
- var OfferEditorial = {
563
- /**
564
- * `model` prefixes the field in the error (`'Offer'`, `'OfferDetail'`), so
565
- * the same three checks name the payload that failed them.
566
- */
567
- fromDto: (dto, model) => ({
568
- tagline: requiredString(dto.tagline, `${model}.tagline`),
569
- bannerUrl: requiredString(dto.banner_url, `${model}.banner_url`),
570
- startsAt: requiredDate(dto.starts_at, `${model}.starts_at`)
673
+ var CentrifugeVaultStatus = {
674
+ fromDto: (dto) => ({
675
+ chain: EthereumChain(dto.chain),
676
+ symbol: AssetSymbol(dto.symbol),
677
+ vaultAddress: EvmContractAddress(dto.vault_address),
678
+ linked: dto.linked,
679
+ permissioned: dto.permissioned,
680
+ membershipValidUntil: dateOrNull(
681
+ dto.membership_valid_until,
682
+ "CentrifugeVaultStatus.membership_valid_until"
683
+ ),
684
+ halted: dto.halted,
685
+ priceUpdatedAt: dateOrNull(
686
+ dto.price_updated_at,
687
+ "CentrifugeVaultStatus.price_updated_at"
688
+ ),
689
+ orderability: parseOrderability(
690
+ dto.can_order,
691
+ dto.reasons,
692
+ "CentrifugeVaultStatus"
693
+ ),
694
+ asOf: requiredDate(dto.as_of, "CentrifugeVaultStatus.as_of")
571
695
  })
572
696
  };
573
- var Offer = {
697
+ var CentrifugeVaultBuyTransaction = {
574
698
  fromDto: (dto) => {
575
- const tokens = requiredArray(dto.tokens, "Offer.tokens");
576
- const base2 = {
577
- id: OfferId(dto.id),
578
- slug: OfferSlug(dto.slug),
579
- endsAt: dto.ends_at ? new Date(dto.ends_at) : null,
580
- tokens: OfferToken.listFromDto(tokens)
581
- };
582
- switch (dto.type) {
583
- case "coinlist::token_sale":
584
- return {
585
- ...base2,
586
- ...OfferEditorial.fromDto(dto, "Offer"),
587
- type: dto.type,
588
- logoUrl: requiredString(dto.logo_url, "Offer.logo_url")
589
- };
590
- case "superstate::swap":
591
- return {
592
- ...base2,
593
- ...OfferEditorial.fromDto(dto, "Offer"),
594
- type: dto.type,
595
- logoUrl: notBlankStringOrNull(dto.logo_url)
596
- };
597
- // `tagline`, `banner_url` and `starts_at` arrive as `null` and are left
598
- // on the wire: copying them would hand every consumer a `startsAt` that
599
- // is 1970 for one variant and a date for the others.
600
- case "ondo::swap":
601
- return {
602
- ...base2,
603
- type: dto.type,
604
- logoUrl: notBlankStringOrNull(dto.logo_url)
605
- };
606
- default:
607
- return unknownTypeError(dto, "Offer");
699
+ const spendInputAmount = blockchainAmountFromRawOrThrow({
700
+ label: "spend_input_amount",
701
+ raw: dto.spend_input_amount,
702
+ decimals: AssetDecimals(dto.spend_input_decimals)
703
+ });
704
+ if (spendInputAmount.raw <= 0n) {
705
+ throw new ValidationError(
706
+ `spend_input_amount: must be greater than zero ("${dto.spend_input_amount}") - a deposit of nothing is not a request`
707
+ );
608
708
  }
609
- },
709
+ return {
710
+ ...parseTransactionCore(dto, "CentrifugeVaultBuyTransaction"),
711
+ spendInputAmount,
712
+ estimatedShares: blockchainAmountFromRawOrThrow({
713
+ label: "estimated_shares",
714
+ raw: dto.estimated_shares,
715
+ decimals: AssetDecimals(dto.share_decimals)
716
+ })
717
+ };
718
+ }
719
+ };
720
+ var CentrifugeVaultClaimTransaction = {
721
+ fromDto: (dto) => ({
722
+ ...parseTransactionCore(dto, "CentrifugeVaultClaimTransaction"),
723
+ claimableShares: blockchainAmountFromRawOrThrow({
724
+ label: "claimable_shares",
725
+ raw: dto.claimable_shares,
726
+ decimals: AssetDecimals(dto.share_decimals)
727
+ })
728
+ })
729
+ };
730
+ var CentrifugeVaultPosition = {
731
+ fromDto: (dto) => {
732
+ const assetDecimals = AssetDecimals(dto.asset_decimals);
733
+ const shareDecimals = AssetDecimals(dto.share_decimals);
734
+ const asset = (label, raw) => blockchainAmountFromRawOrThrow({ label, raw, decimals: assetDecimals });
735
+ const shares = (label, raw) => blockchainAmountFromRawOrThrow({ label, raw, decimals: shareDecimals });
736
+ return {
737
+ chain: EthereumChain(dto.chain),
738
+ symbol: AssetSymbol(dto.symbol),
739
+ walletAddress: EvmWalletAddress(dto.wallet_address),
740
+ status: dto.status,
741
+ requested: asset("requested", dto.requested),
742
+ pending: asset("pending", dto.pending),
743
+ filledAssets: asset("filled_assets", dto.filled_assets),
744
+ earnedShares: shares("earned_shares", dto.earned_shares),
745
+ claimedShares: shares("claimed_shares", dto.claimed_shares),
746
+ claimableShares: shares("claimable_shares", dto.claimable_shares),
747
+ shareBalance: shares("share_balance", dto.share_balance),
748
+ averagePrice: decimalOrNull(dto.average_price),
749
+ frozen: dto.frozen,
750
+ asOf: requiredDate(dto.as_of, "CentrifugeVaultPosition.as_of")
751
+ };
752
+ }
753
+ };
754
+ var CentrifugeVaultRedeemPosition = {
755
+ fromDto: (dto) => ({
756
+ chain: EthereumChain(dto.chain),
757
+ symbol: AssetSymbol(dto.symbol),
758
+ walletAddress: EvmWalletAddress(dto.wallet_address),
759
+ status: dto.status,
760
+ pending: blockchainAmountFromRawOrThrow({
761
+ label: "pending",
762
+ raw: dto.pending,
763
+ decimals: AssetDecimals(dto.share_decimals)
764
+ }),
765
+ claimableAssets: blockchainAmountFromRawOrThrow({
766
+ label: "claimable_assets",
767
+ raw: dto.claimable_assets,
768
+ decimals: AssetDecimals(dto.asset_decimals)
769
+ }),
770
+ frozen: dto.frozen,
771
+ asOf: requiredDate(dto.as_of, "CentrifugeVaultRedeemPosition.as_of")
772
+ })
773
+ };
774
+ var CentrifugeVaultLeg = {
610
775
  /**
611
- * Maps a page of offers, dropping every offer whose `type` this SDK does not
612
- * name. The same reasoning as {@link OfferToken.listFromDto}: a plain `.map`
613
- * would throw out of `fromDto` and, through `PaginatedResponse.fromDto`,
614
- * reject the whole page, so one offer of an unknown type would blank the
615
- * grid for every offer beside it. A single offer fetched by id still
616
- * throws, because there is nothing beside it to keep.
776
+ * What a claim on the leg would collect: shares for `invest`, the funding
777
+ * token for `redeem`.
617
778
  */
618
- listFromDto: (dtos) => dtos.filter((dto) => isOfferType(dto.type)).map(Offer.fromDto)
779
+ claimable: (leg) => {
780
+ switch (leg.direction) {
781
+ case "invest":
782
+ return leg.position.claimableShares;
783
+ case "redeem":
784
+ return leg.position.claimableAssets;
785
+ default: {
786
+ const exhaustive = leg;
787
+ return exhaustive;
788
+ }
789
+ }
790
+ },
791
+ /** Whether the leg has anything queued or anything ready to claim. */
792
+ isActive: (leg) => leg.position.pending.raw > 0n || CentrifugeVaultLeg.claimable(leg).raw > 0n
619
793
  };
620
- var OfferToken = {
794
+ var CentrifugeVaultLegId = {
795
+ /** Addresses compare case-insensitively: frontline echoes them lower case. */
796
+ of: (leg) => [
797
+ leg.direction,
798
+ leg.position.chain,
799
+ leg.position.walletAddress.toLowerCase()
800
+ ].join(":")
801
+ };
802
+ var CentrifugeVaultClaimProceedsTransaction = {
621
803
  fromDto: (dto) => ({
622
- role: dto.role,
623
- chain: Chain(dto.chain),
624
- address: EvmContractAddress(dto.address)
804
+ ...parseTransactionCore(dto, "CentrifugeVaultClaimProceedsTransaction"),
805
+ claimableAssets: blockchainAmountFromRawOrThrow({
806
+ label: "claimable_assets",
807
+ raw: dto.claimable_assets,
808
+ decimals: AssetDecimals(dto.asset_decimals)
809
+ })
810
+ })
811
+ };
812
+ function parseOrderability(canOrder, reasons, model) {
813
+ const [first, ...rest] = reasons;
814
+ if (canOrder) {
815
+ if (first !== void 0) {
816
+ throw new ValidationError(
817
+ `${model}.reasons: expected none when can_order is true, got ${JSON.stringify(reasons)}`
818
+ );
819
+ }
820
+ return { type: "orderable" };
821
+ }
822
+ if (first === void 0) {
823
+ throw new ValidationError(
824
+ `${model}.reasons: expected at least one when can_order is false`
825
+ );
826
+ }
827
+ return { type: "blocked", reasons: [first, ...rest] };
828
+ }
829
+ function parseTransactionCore(dto, model) {
830
+ return {
831
+ tx: {
832
+ to: EvmContractAddress(dto.to),
833
+ data: HexEncodedTransactionData(dto.data)
834
+ },
835
+ expiresAt: dateOrNull(dto.expires_at, `${model}.expires_at`)
836
+ };
837
+ }
838
+
839
+ // src/universal/api/frontline/providers/centrifuge/centrifuge.ts
840
+ async function getCentrifugeVaultQuote(api, params) {
841
+ const dto = await api.send({
842
+ method: "GET",
843
+ url: "/v1/centrifuge/vault/quote",
844
+ queryParams: {
845
+ symbol: params.symbol,
846
+ chain: params.chain,
847
+ amount: params.amount.raw.toString()
848
+ },
849
+ attributes: Attributes.protected()
850
+ });
851
+ return CentrifugeVaultQuote.fromDto(dto);
852
+ }
853
+ async function getCentrifugeVaultStatus(api, params) {
854
+ const dto = await api.send({
855
+ method: "GET",
856
+ url: "/v1/centrifuge/vault/status",
857
+ queryParams: {
858
+ symbol: params.symbol,
859
+ chain: params.chain
860
+ },
861
+ attributes: Attributes.protected()
862
+ });
863
+ return CentrifugeVaultStatus.fromDto(dto);
864
+ }
865
+ async function buildCentrifugeVaultBuy(api, params) {
866
+ const dto = await api.send({
867
+ method: "POST",
868
+ url: "/v1/centrifuge/vault/invest",
869
+ body: {
870
+ ...walletFields(params),
871
+ amount: params.amount.raw.toString()
872
+ },
873
+ attributes: Attributes.protected()
874
+ });
875
+ if (dto.spend_input_decimals !== params.amount.decimals) {
876
+ throw new ValidationError(
877
+ `spend_input_decimals: the request was priced in ${dto.spend_input_decimals} decimals but the deposit was sized in ${params.amount.decimals}`
878
+ );
879
+ }
880
+ return CentrifugeVaultBuyTransaction.fromDto(dto);
881
+ }
882
+ async function getCentrifugeVaultPosition(api, params) {
883
+ const dto = await api.send({
884
+ method: "GET",
885
+ url: "/v1/centrifuge/vault/position",
886
+ queryParams: walletFields(params),
887
+ attributes: Attributes.protected()
888
+ });
889
+ return CentrifugeVaultPosition.fromDto(dto);
890
+ }
891
+ async function getCentrifugeVaultRedeemPosition(api, params) {
892
+ const dto = await api.send({
893
+ method: "GET",
894
+ url: "/v1/centrifuge/vault/redeem-position",
895
+ queryParams: walletFields(params),
896
+ attributes: Attributes.protected()
897
+ });
898
+ return CentrifugeVaultRedeemPosition.fromDto(dto);
899
+ }
900
+ async function createCentrifugeVaultClaim(api, params) {
901
+ const dto = await api.send({
902
+ method: "POST",
903
+ url: "/v1/centrifuge/vault/claim",
904
+ body: walletFields(params),
905
+ attributes: Attributes.protected()
906
+ });
907
+ return CentrifugeVaultClaimTransaction.fromDto(dto);
908
+ }
909
+ async function createCentrifugeVaultClaimProceeds(api, params) {
910
+ const dto = await api.send({
911
+ method: "POST",
912
+ url: "/v1/centrifuge/vault/claim-proceeds",
913
+ body: walletFields(params),
914
+ attributes: Attributes.protected()
915
+ });
916
+ return CentrifugeVaultClaimProceedsTransaction.fromDto(dto);
917
+ }
918
+ function walletFields(params) {
919
+ return {
920
+ symbol: params.symbol,
921
+ chain: params.chain,
922
+ wallet_address: params.walletAddress
923
+ };
924
+ }
925
+
926
+ // src/universal/core/shared/observability/log-cause.ts
927
+ import {
928
+ BaseError,
929
+ ContractFunctionExecutionError,
930
+ ContractFunctionRevertedError,
931
+ HttpRequestError,
932
+ RpcError,
933
+ SocketClosedError,
934
+ TimeoutError,
935
+ WebSocketRequestError
936
+ } from "viem";
937
+ function classifyLogCause(error) {
938
+ if (error instanceof HttpError) {
939
+ return httpCause(error);
940
+ }
941
+ if (error instanceof ValidationError) {
942
+ return { type: "validation", message: error.message };
943
+ }
944
+ if (error instanceof InvariantError) {
945
+ return { type: "invariant", message: error.message };
946
+ }
947
+ if (error instanceof MathError) {
948
+ return { type: "math", message: error.message };
949
+ }
950
+ if (error instanceof NotAuthenticatedError) {
951
+ return { type: "not-authenticated" };
952
+ }
953
+ if (error instanceof NotImplementedError) {
954
+ return { type: "not-implemented" };
955
+ }
956
+ if (error instanceof BaseError) {
957
+ const http = error.walk((e) => e instanceof HttpError);
958
+ if (http instanceof HttpError) {
959
+ return httpCause(http);
960
+ }
961
+ return { type: "rpc", reason: rpcFailureReason(error) };
962
+ }
963
+ return { type: "generic-error", name: errorName(error) };
964
+ }
965
+ function rpcFailureReason(error) {
966
+ if (error.walk((e) => e instanceof ContractFunctionRevertedError)) {
967
+ return "reverted";
968
+ }
969
+ if (error.walk((e) => e instanceof RpcError)) {
970
+ return "node-rejected";
971
+ }
972
+ if (error.walk(
973
+ (e) => e instanceof HttpRequestError || e instanceof WebSocketRequestError || e instanceof SocketClosedError || e instanceof TimeoutError
974
+ )) {
975
+ return "transport";
976
+ }
977
+ if (error instanceof ContractFunctionExecutionError) {
978
+ return "malformed-response";
979
+ }
980
+ return "unknown";
981
+ }
982
+ function describeErrorUnredacted(error) {
983
+ if (error instanceof HttpError) {
984
+ return describeHttpErrorRedacted(error);
985
+ }
986
+ if (error instanceof Error) {
987
+ return `${error.name}: ${error.message}`;
988
+ }
989
+ return `thrown non-error: ${stringifyUnredacted(error)}`;
990
+ }
991
+ function stringifyUnredacted(value) {
992
+ if (value === void 0) return "";
993
+ try {
994
+ return JSON.stringify(
995
+ value,
996
+ (_key, item) => typeof item === "bigint" ? `${item}` : item
997
+ ) ?? String(value);
998
+ } catch (_) {
999
+ return "<unserializable>";
1000
+ }
1001
+ }
1002
+ function describeHttpErrorRedacted(error) {
1003
+ const code = apiErrorCode(error);
1004
+ const status = error.response.status;
1005
+ return code === null ? `HttpError ${status}` : `HttpError ${status} (${code})`;
1006
+ }
1007
+ function errorName(error) {
1008
+ return error instanceof Error ? error.name : `non-error ${typeof error}`;
1009
+ }
1010
+ function httpCause(error) {
1011
+ return {
1012
+ type: "http",
1013
+ requestId: error.requestId,
1014
+ status: error.response.status,
1015
+ code: apiErrorCode(error),
1016
+ eventId: apiErrorEventId(error)
1017
+ };
1018
+ }
1019
+ function apiErrorEventId(error) {
1020
+ const body = error.response.body;
1021
+ if (typeof body !== "object" || body === null) return null;
1022
+ const eventId = body.event_id;
1023
+ return typeof eventId === "string" ? eventId : null;
1024
+ }
1025
+
1026
+ // src/universal/core/shared/observability/internal-logger.ts
1027
+ function internalLogger(logger, scope) {
1028
+ return logger ? scopedLogger(logger, scope, {}) : noopInternalLogger;
1029
+ }
1030
+ var LEVEL_RANK = {
1031
+ none: 0,
1032
+ error: 1,
1033
+ warn: 2,
1034
+ info: 3,
1035
+ debug: 4
1036
+ };
1037
+ function scopedLogger(logger, scope, bindings) {
1038
+ const admits = (level) => LEVEL_RANK[logger.level()] >= LEVEL_RANK[level];
1039
+ const safe = (event) => ({
1040
+ msg: event.msg,
1041
+ scope,
1042
+ bindings,
1043
+ fields: event.fields ?? {},
1044
+ ...event.cause === void 0 ? {} : { cause: event.cause }
1045
+ });
1046
+ const unredacted = (event) => ({
1047
+ msg: event.msg,
1048
+ scope,
1049
+ bindings,
1050
+ fields: event.fields ?? {}
1051
+ });
1052
+ const self = {
1053
+ child: (binding) => scopedLogger(logger, scope, { ...bindings, ...binding }),
1054
+ debug: (event) => {
1055
+ if (admits("debug")) logger.debug(() => unredacted(event()));
1056
+ },
1057
+ info: (event) => {
1058
+ if (admits("info")) logger.info(() => safe(event()));
1059
+ },
1060
+ warn: (event) => {
1061
+ if (admits("warn")) logger.warn(() => safe(event()));
1062
+ },
1063
+ error: (event) => {
1064
+ if (admits("error")) logger.error(() => safe(event()));
1065
+ },
1066
+ failure: (event, error) => {
1067
+ if (admits("debug"))
1068
+ logger.debug(() => unredacted(verbatim(event(), error)));
1069
+ if (admits("error")) logger.error(() => safe(classified(event(), error)));
1070
+ },
1071
+ warning: (event, error) => {
1072
+ if (admits("debug"))
1073
+ logger.debug(() => unredacted(verbatim(event(), error)));
1074
+ if (admits("warn")) logger.warn(() => safe(classified(event(), error)));
1075
+ },
1076
+ wrap: async (op, params, run) => {
1077
+ const opLog = self.child({ op });
1078
+ opLog.debug(() => ({ msg: "call", fields: { params } }));
1079
+ try {
1080
+ return await run();
1081
+ } catch (error) {
1082
+ opLog.failure(() => ({ msg: "call failed" }), error);
1083
+ throw error;
1084
+ }
1085
+ }
1086
+ };
1087
+ return self;
1088
+ }
1089
+ function verbatim(event, error) {
1090
+ return {
1091
+ msg: event.msg,
1092
+ fields: { ...event.fields, error: describeErrorUnredacted(error) }
1093
+ };
1094
+ }
1095
+ function classified(event, error) {
1096
+ return { ...event, cause: event.cause ?? classifyLogCause(error) };
1097
+ }
1098
+ var noopInternalLogger = {
1099
+ child: () => noopInternalLogger,
1100
+ debug: () => void 0,
1101
+ info: () => void 0,
1102
+ warn: () => void 0,
1103
+ error: () => void 0,
1104
+ failure: () => void 0,
1105
+ warning: () => void 0,
1106
+ wrap: (_op, _params, run) => run()
1107
+ };
1108
+
1109
+ // src/universal/core/checkout/centrifuge/centrifuge-namespace.ts
1110
+ var CentrifugeNamespaceImpl = class {
1111
+ constructor(ctx) {
1112
+ this.ctx = ctx;
1113
+ this.log = internalLogger(ctx.logger, "CENTRIFUGE");
1114
+ }
1115
+ async getQuote(params) {
1116
+ return this.log.wrap("getQuote", params, async () => {
1117
+ await this.ctx.ensureUserAuthenticated();
1118
+ return getCentrifugeVaultQuote(this.ctx.api, params);
1119
+ });
1120
+ }
1121
+ async getVaultStatus(params) {
1122
+ return this.log.wrap("getVaultStatus", params, async () => {
1123
+ await this.ctx.ensureUserAuthenticated();
1124
+ return getCentrifugeVaultStatus(this.ctx.api, params);
1125
+ });
1126
+ }
1127
+ async getPosition(params) {
1128
+ return this.log.wrap("getPosition", params, async () => {
1129
+ await this.ctx.ensureUserAuthenticated();
1130
+ return getCentrifugeVaultPosition(this.ctx.api, params);
1131
+ });
1132
+ }
1133
+ async getRedeemPosition(params) {
1134
+ return this.log.wrap("getRedeemPosition", params, async () => {
1135
+ await this.ctx.ensureUserAuthenticated();
1136
+ return getCentrifugeVaultRedeemPosition(this.ctx.api, params);
1137
+ });
1138
+ }
1139
+ async createClaim(params) {
1140
+ return this.log.wrap("createClaim", params, async () => {
1141
+ await this.ctx.ensureUserAuthenticated();
1142
+ return createCentrifugeVaultClaim(this.ctx.api, params);
1143
+ });
1144
+ }
1145
+ async createClaimProceeds(params) {
1146
+ return this.log.wrap("createClaimProceeds", params, async () => {
1147
+ await this.ctx.ensureUserAuthenticated();
1148
+ return createCentrifugeVaultClaimProceeds(this.ctx.api, params);
1149
+ });
1150
+ }
1151
+ async buildBuyTransaction(params) {
1152
+ return this.log.wrap("buildBuyTransaction", params, async () => {
1153
+ await this.ctx.ensureUserAuthenticated();
1154
+ return buildCentrifugeVaultBuy(this.ctx.api, params);
1155
+ });
1156
+ }
1157
+ };
1158
+
1159
+ // src/universal/api/pagination.ts
1160
+ async function fetchAllPages(fetchPage, baseParams) {
1161
+ const items = [];
1162
+ let cursor = null;
1163
+ do {
1164
+ const params = {
1165
+ ...baseParams ?? {},
1166
+ after: cursor ?? void 0
1167
+ };
1168
+ const page = await fetchPage(params);
1169
+ items.push(...page.data);
1170
+ cursor = page.startingAfter;
1171
+ } while (cursor);
1172
+ return items;
1173
+ }
1174
+
1175
+ // src/universal/types/pagination.ts
1176
+ var Cursor = (value) => value;
1177
+ var PaginatedResponse = {
1178
+ fromDto: (dto, itemMapper) => PaginatedResponse.fromDtoPage(dto, (items) => items.map(itemMapper)),
1179
+ /**
1180
+ * For a mapper that decides the page as a whole - one that drops items it
1181
+ * cannot map, such as `Offer.listFromDto` - rather than item by item. The
1182
+ * cursors are the wire's either way: dropping an item changes what the
1183
+ * page holds, not where the next page starts.
1184
+ */
1185
+ fromDtoPage: (dto, pageMapper) => ({
1186
+ data: pageMapper(dto.data),
1187
+ startingAfter: dto.starting_after ? Cursor(dto.starting_after) : null,
1188
+ startingBefore: dto.starting_before ? Cursor(dto.starting_before) : null
1189
+ })
1190
+ };
1191
+ var PaginationParams = {
1192
+ toQueryParams: (params) => {
1193
+ const queryParams = {};
1194
+ if (params.after) {
1195
+ queryParams.starting_after = params.after;
1196
+ }
1197
+ if (params.before) {
1198
+ queryParams.starting_before = params.before;
1199
+ }
1200
+ if (params.limit) {
1201
+ queryParams.limit = params.limit;
1202
+ }
1203
+ return queryParams;
1204
+ }
1205
+ };
1206
+
1207
+ // src/universal/types/asset.ts
1208
+ var AssetId = (value) => value;
1209
+ var AssetCode = (value) => value;
1210
+ var Asset = {
1211
+ fromDto: (dto) => ({
1212
+ id: AssetId(dto.id),
1213
+ code: AssetCode(dto.code),
1214
+ name: dto.name,
1215
+ fractionalDigits: dto.fractional_digits
1216
+ })
1217
+ };
1218
+
1219
+ // src/universal/types/offer.ts
1220
+ var OfferId = (value) => value;
1221
+ var OfferSlug = (value) => value;
1222
+ var OFFER_TYPES = {
1223
+ "coinlist::token_sale": true,
1224
+ "superstate::swap": true,
1225
+ "ondo::swap": true,
1226
+ "centrifuge::vault": true
1227
+ };
1228
+ var isOfferType = (value) => Object.keys(OFFER_TYPES).includes(value);
1229
+ var OfferEditorial = {
1230
+ /**
1231
+ * `model` prefixes the field in the error (`'Offer'`, `'OfferDetail'`), so
1232
+ * the same three checks name the payload that failed them.
1233
+ */
1234
+ fromDto: (dto, model) => ({
1235
+ tagline: requiredString(dto.tagline, `${model}.tagline`),
1236
+ bannerUrl: requiredString(dto.banner_url, `${model}.banner_url`),
1237
+ startsAt: requiredDate(dto.starts_at, `${model}.starts_at`)
1238
+ })
1239
+ };
1240
+ var Offer = {
1241
+ fromDto: (dto) => {
1242
+ const tokens = requiredArray(dto.tokens, "Offer.tokens");
1243
+ const base2 = {
1244
+ id: OfferId(dto.id),
1245
+ slug: OfferSlug(dto.slug),
1246
+ endsAt: dto.ends_at ? new Date(dto.ends_at) : null,
1247
+ tokens: OfferToken.listFromDto(tokens)
1248
+ };
1249
+ switch (dto.type) {
1250
+ case "coinlist::token_sale":
1251
+ return {
1252
+ ...base2,
1253
+ ...OfferEditorial.fromDto(dto, "Offer"),
1254
+ type: dto.type,
1255
+ logoUrl: requiredString(dto.logo_url, "Offer.logo_url")
1256
+ };
1257
+ case "superstate::swap":
1258
+ return {
1259
+ ...base2,
1260
+ ...OfferEditorial.fromDto(dto, "Offer"),
1261
+ type: dto.type,
1262
+ logoUrl: notBlankStringOrNull(dto.logo_url)
1263
+ };
1264
+ // `tagline`, `banner_url` and `starts_at` arrive as `null` and are left
1265
+ // on the wire: copying them would hand every consumer a `startsAt` that
1266
+ // is 1970 for one variant and a date for the others.
1267
+ case "ondo::swap":
1268
+ case "centrifuge::vault":
1269
+ return {
1270
+ ...base2,
1271
+ type: dto.type,
1272
+ logoUrl: notBlankStringOrNull(dto.logo_url)
1273
+ };
1274
+ default:
1275
+ return unknownTypeError(dto, "Offer");
1276
+ }
1277
+ },
1278
+ /**
1279
+ * Maps a page of offers, dropping every offer whose `type` this SDK does not
1280
+ * name. The same reasoning as {@link OfferToken.listFromDto}: a plain `.map`
1281
+ * would throw out of `fromDto` and, through `PaginatedResponse.fromDto`,
1282
+ * reject the whole page, so one offer of an unknown type would blank the
1283
+ * grid for every offer beside it. A single offer fetched by id still
1284
+ * throws, because there is nothing beside it to keep.
1285
+ */
1286
+ listFromDto: (dtos) => dtos.filter((dto) => isOfferType(dto.type)).map(Offer.fromDto)
1287
+ };
1288
+ var OfferToken = {
1289
+ fromDto: (dto) => ({
1290
+ role: dto.role,
1291
+ chain: Chain(dto.chain),
1292
+ address: EvmContractAddress(dto.address)
625
1293
  }),
626
1294
  /**
627
1295
  * Maps an offer's token list, dropping every token on a chain this SDK does
@@ -642,6 +1310,30 @@ var Ticker = (value) => value;
642
1310
  var Isin = (value) => value;
643
1311
 
644
1312
  // src/universal/types/offer-detail.ts
1313
+ var AsyncOfferDetail = {
1314
+ /**
1315
+ * Narrows an offer fetched generically, e.g. on an offer page, to one with
1316
+ * something to claim.
1317
+ *
1318
+ * An exhaustive `switch` rather than a list of async types, so a new offer
1319
+ * type is a compile error here until someone decides whether it settles
1320
+ * later.
1321
+ */
1322
+ is: (offer) => {
1323
+ switch (offer.type) {
1324
+ case "centrifuge::vault":
1325
+ return true;
1326
+ case "ondo::swap":
1327
+ case "superstate::swap":
1328
+ case "coinlist::token_sale":
1329
+ return false;
1330
+ default: {
1331
+ const exhaustive = offer;
1332
+ return exhaustive;
1333
+ }
1334
+ }
1335
+ }
1336
+ };
645
1337
  var OfferOptionId = (value) => value;
646
1338
  var OfferOptionSlug = (value) => value;
647
1339
  var OfferSwapContract = {
@@ -650,6 +1342,19 @@ var OfferSwapContract = {
650
1342
  address: EvmContractAddress(dto.address)
651
1343
  })
652
1344
  };
1345
+ var OfferVaultContract = {
1346
+ fromDto: (dto) => ({
1347
+ chain: Chain(dto.chain),
1348
+ address: EvmContractAddress(dto.address)
1349
+ }),
1350
+ /**
1351
+ * Drops every proxy on a chain this SDK does not name, as
1352
+ * `OfferToken.listFromDto` does: frontline publishes the full offer-token
1353
+ * chain list, which runs ahead of {@link Chain}, and one unmodelled chain
1354
+ * should not throw away the proxies the SDK can use.
1355
+ */
1356
+ listFromDto: (dtos) => dtos.filter((dto) => isChain(dto.chain)).map(OfferVaultContract.fromDto)
1357
+ };
653
1358
  var OfferDetail = {
654
1359
  fromDto: (dto) => {
655
1360
  const fundingAssets = requiredArray(
@@ -712,6 +1417,18 @@ var OfferDetail = {
712
1417
  "OfferDetail.swap_contracts"
713
1418
  ).map(OfferSwapContract.fromDto)
714
1419
  };
1420
+ // No editorial, as for Ondo. `[]` is fine and a missing key is not, for
1421
+ // the same reason as `swap_contracts`: this is the spender a user
1422
+ // approves.
1423
+ case "centrifuge::vault":
1424
+ return {
1425
+ ...base2,
1426
+ type: dto.type,
1427
+ logoUrl: notBlankStringOrNull(dto.logo_url),
1428
+ vaultContracts: OfferVaultContract.listFromDto(
1429
+ requiredArray(dto.vault_contracts, "OfferDetail.vault_contracts")
1430
+ )
1431
+ };
715
1432
  default:
716
1433
  return unknownTypeError(dto, "OfferDetail");
717
1434
  }
@@ -766,258 +1483,75 @@ var ParticipationsPaginationParams = {
766
1483
  queryParams["filters[0][field]"] = "offer_id";
767
1484
  queryParams["filters[0][op]"] = "==";
768
1485
  queryParams["filters[0][value]"] = params.offerId;
769
- }
770
- return queryParams;
771
- }
772
- };
773
- var Participation = {
774
- /** Maps API DTO shape into the SDK participation domain model. */
775
- fromDto: (dto) => {
776
- const walletAddress = notBlankStringOrNull(dto.wallet_address);
777
- return {
778
- id: ParticipationId(dto.id),
779
- offerId: OfferId(dto.offer_id),
780
- offerOptionId: OfferOptionId(dto.offer_option_id),
781
- status: dto.status,
782
- amount: dto.amount,
783
- displayAmount: dto.amount_string,
784
- asset: Asset.fromDto(dto.asset),
785
- chain: Blockchain(dto.chain),
786
- insertedAt: dto.inserted_at ? new Date(dto.inserted_at) : null,
787
- updatedAt: dto.updated_at ? new Date(dto.updated_at) : null,
788
- walletAddress: walletAddress ? WalletAddress(walletAddress) : null
789
- };
790
- }
791
- };
792
- var CreateParticipationParams = {
793
- /** Maps participation creation params into API DTO payload. */
794
- toDto: (params) => ({
795
- offer_id: params.offerId,
796
- offer_option_id: params.offerOptionId,
797
- chain: params.chain,
798
- wallet_address: params.walletAddress,
799
- amount: params.amount,
800
- asset_id: params.assetId,
801
- approval_transaction_hash: params.approvalTransactionHash
802
- })
803
- };
804
-
805
- // src/universal/api/frontline/providers/coin-list/token-sale.ts
806
- async function fetchParticipations(api, offerId) {
807
- return fetchAllPages(
808
- (params) => fetchParticipationsPage(api, params),
809
- { offerId }
810
- );
811
- }
812
- async function fetchParticipationsPage(api, params) {
813
- const pageDto = await api.send({
814
- method: "GET",
815
- url: "/v1/participations",
816
- queryParams: ParticipationsPaginationParams.toQueryParams(params),
817
- attributes: Attributes.protected()
818
- });
819
- return PaginatedResponse.fromDto(pageDto, Participation.fromDto);
820
- }
821
- async function fetchParticipation(api, id) {
822
- const dto = await api.send({
823
- method: "GET",
824
- url: `/v1/participations/${id}`,
825
- attributes: Attributes.protected()
826
- });
827
- return Participation.fromDto(dto);
828
- }
829
- async function createParticipation(api, params) {
830
- const dto = await api.send({
831
- method: "POST",
832
- url: "/v1/participations",
833
- body: CreateParticipationParams.toDto(params),
834
- attributes: Attributes.protected()
835
- });
836
- return Participation.fromDto(dto);
837
- }
838
-
839
- // src/universal/core/shared/observability/log-cause.ts
840
- import {
841
- BaseError,
842
- ContractFunctionExecutionError,
843
- ContractFunctionRevertedError,
844
- HttpRequestError,
845
- RpcError,
846
- SocketClosedError,
847
- TimeoutError,
848
- WebSocketRequestError
849
- } from "viem";
850
- function classifyLogCause(error) {
851
- if (error instanceof HttpError) {
852
- return httpCause(error);
853
- }
854
- if (error instanceof ValidationError) {
855
- return { type: "validation", message: error.message };
856
- }
857
- if (error instanceof InvariantError) {
858
- return { type: "invariant", message: error.message };
859
- }
860
- if (error instanceof MathError) {
861
- return { type: "math", message: error.message };
862
- }
863
- if (error instanceof NotAuthenticatedError) {
864
- return { type: "not-authenticated" };
865
- }
866
- if (error instanceof NotImplementedError) {
867
- return { type: "not-implemented" };
868
- }
869
- if (error instanceof BaseError) {
870
- const http = error.walk((e) => e instanceof HttpError);
871
- if (http instanceof HttpError) {
872
- return httpCause(http);
873
- }
874
- return { type: "rpc", reason: rpcFailureReason(error) };
875
- }
876
- return { type: "generic-error", name: errorName(error) };
877
- }
878
- function rpcFailureReason(error) {
879
- if (error.walk((e) => e instanceof ContractFunctionRevertedError)) {
880
- return "reverted";
881
- }
882
- if (error.walk((e) => e instanceof RpcError)) {
883
- return "node-rejected";
884
- }
885
- if (error.walk(
886
- (e) => e instanceof HttpRequestError || e instanceof WebSocketRequestError || e instanceof SocketClosedError || e instanceof TimeoutError
887
- )) {
888
- return "transport";
889
- }
890
- if (error instanceof ContractFunctionExecutionError) {
891
- return "malformed-response";
892
- }
893
- return "unknown";
894
- }
895
- function describeErrorUnredacted(error) {
896
- if (error instanceof HttpError) {
897
- return describeHttpErrorRedacted(error);
898
- }
899
- if (error instanceof Error) {
900
- return `${error.name}: ${error.message}`;
1486
+ }
1487
+ return queryParams;
901
1488
  }
902
- return `thrown non-error: ${stringifyUnredacted(error)}`;
903
- }
904
- function stringifyUnredacted(value) {
905
- if (value === void 0) return "";
906
- try {
907
- return JSON.stringify(
908
- value,
909
- (_key, item) => typeof item === "bigint" ? `${item}` : item
910
- ) ?? String(value);
911
- } catch (_) {
912
- return "<unserializable>";
1489
+ };
1490
+ var Participation = {
1491
+ /** Maps API DTO shape into the SDK participation domain model. */
1492
+ fromDto: (dto) => {
1493
+ const walletAddress = notBlankStringOrNull(dto.wallet_address);
1494
+ return {
1495
+ id: ParticipationId(dto.id),
1496
+ offerId: OfferId(dto.offer_id),
1497
+ offerOptionId: OfferOptionId(dto.offer_option_id),
1498
+ status: dto.status,
1499
+ amount: dto.amount,
1500
+ displayAmount: dto.amount_string,
1501
+ asset: Asset.fromDto(dto.asset),
1502
+ chain: Blockchain(dto.chain),
1503
+ insertedAt: dto.inserted_at ? new Date(dto.inserted_at) : null,
1504
+ updatedAt: dto.updated_at ? new Date(dto.updated_at) : null,
1505
+ walletAddress: walletAddress ? WalletAddress(walletAddress) : null
1506
+ };
913
1507
  }
914
- }
915
- function describeHttpErrorRedacted(error) {
916
- const code = apiErrorCode(error);
917
- const status = error.response.status;
918
- return code === null ? `HttpError ${status}` : `HttpError ${status} (${code})`;
919
- }
920
- function errorName(error) {
921
- return error instanceof Error ? error.name : `non-error ${typeof error}`;
922
- }
923
- function httpCause(error) {
924
- return {
925
- type: "http",
926
- requestId: error.requestId,
927
- status: error.response.status,
928
- code: apiErrorCode(error),
929
- eventId: apiErrorEventId(error)
930
- };
931
- }
932
- function apiErrorEventId(error) {
933
- const body = error.response.body;
934
- if (typeof body !== "object" || body === null) return null;
935
- const eventId = body.event_id;
936
- return typeof eventId === "string" ? eventId : null;
937
- }
1508
+ };
1509
+ var CreateParticipationParams = {
1510
+ /** Maps participation creation params into API DTO payload. */
1511
+ toDto: (params) => ({
1512
+ offer_id: params.offerId,
1513
+ offer_option_id: params.offerOptionId,
1514
+ chain: params.chain,
1515
+ wallet_address: params.walletAddress,
1516
+ amount: params.amount,
1517
+ asset_id: params.assetId,
1518
+ approval_transaction_hash: params.approvalTransactionHash
1519
+ })
1520
+ };
938
1521
 
939
- // src/universal/core/shared/observability/internal-logger.ts
940
- function internalLogger(logger, scope) {
941
- return logger ? scopedLogger(logger, scope, {}) : noopInternalLogger;
1522
+ // src/universal/api/frontline/providers/coin-list/token-sale.ts
1523
+ async function fetchParticipations(api, offerId) {
1524
+ return fetchAllPages(
1525
+ (params) => fetchParticipationsPage(api, params),
1526
+ { offerId }
1527
+ );
942
1528
  }
943
- var LEVEL_RANK = {
944
- none: 0,
945
- error: 1,
946
- warn: 2,
947
- info: 3,
948
- debug: 4
949
- };
950
- function scopedLogger(logger, scope, bindings) {
951
- const admits = (level) => LEVEL_RANK[logger.level()] >= LEVEL_RANK[level];
952
- const safe = (event) => ({
953
- msg: event.msg,
954
- scope,
955
- bindings,
956
- fields: event.fields ?? {},
957
- ...event.cause === void 0 ? {} : { cause: event.cause }
958
- });
959
- const unredacted = (event) => ({
960
- msg: event.msg,
961
- scope,
962
- bindings,
963
- fields: event.fields ?? {}
1529
+ async function fetchParticipationsPage(api, params) {
1530
+ const pageDto = await api.send({
1531
+ method: "GET",
1532
+ url: "/v1/participations",
1533
+ queryParams: ParticipationsPaginationParams.toQueryParams(params),
1534
+ attributes: Attributes.protected()
964
1535
  });
965
- const self = {
966
- child: (binding) => scopedLogger(logger, scope, { ...bindings, ...binding }),
967
- debug: (event) => {
968
- if (admits("debug")) logger.debug(() => unredacted(event()));
969
- },
970
- info: (event) => {
971
- if (admits("info")) logger.info(() => safe(event()));
972
- },
973
- warn: (event) => {
974
- if (admits("warn")) logger.warn(() => safe(event()));
975
- },
976
- error: (event) => {
977
- if (admits("error")) logger.error(() => safe(event()));
978
- },
979
- failure: (event, error) => {
980
- if (admits("debug"))
981
- logger.debug(() => unredacted(verbatim(event(), error)));
982
- if (admits("error")) logger.error(() => safe(classified(event(), error)));
983
- },
984
- warning: (event, error) => {
985
- if (admits("debug"))
986
- logger.debug(() => unredacted(verbatim(event(), error)));
987
- if (admits("warn")) logger.warn(() => safe(classified(event(), error)));
988
- },
989
- wrap: async (op, params, run) => {
990
- const opLog = self.child({ op });
991
- opLog.debug(() => ({ msg: "call", fields: { params } }));
992
- try {
993
- return await run();
994
- } catch (error) {
995
- opLog.failure(() => ({ msg: "call failed" }), error);
996
- throw error;
997
- }
998
- }
999
- };
1000
- return self;
1536
+ return PaginatedResponse.fromDto(pageDto, Participation.fromDto);
1001
1537
  }
1002
- function verbatim(event, error) {
1003
- return {
1004
- msg: event.msg,
1005
- fields: { ...event.fields, error: describeErrorUnredacted(error) }
1006
- };
1538
+ async function fetchParticipation(api, id) {
1539
+ const dto = await api.send({
1540
+ method: "GET",
1541
+ url: `/v1/participations/${id}`,
1542
+ attributes: Attributes.protected()
1543
+ });
1544
+ return Participation.fromDto(dto);
1007
1545
  }
1008
- function classified(event, error) {
1009
- return { ...event, cause: event.cause ?? classifyLogCause(error) };
1546
+ async function createParticipation(api, params) {
1547
+ const dto = await api.send({
1548
+ method: "POST",
1549
+ url: "/v1/participations",
1550
+ body: CreateParticipationParams.toDto(params),
1551
+ attributes: Attributes.protected()
1552
+ });
1553
+ return Participation.fromDto(dto);
1010
1554
  }
1011
- var noopInternalLogger = {
1012
- child: () => noopInternalLogger,
1013
- debug: () => void 0,
1014
- info: () => void 0,
1015
- warn: () => void 0,
1016
- error: () => void 0,
1017
- failure: () => void 0,
1018
- warning: () => void 0,
1019
- wrap: (_op, _params, run) => run()
1020
- };
1021
1555
 
1022
1556
  // src/universal/core/checkout/coin-list/token-sale-namespace.ts
1023
1557
  var CoinListTokenSaleNamespaceImpl = class {
@@ -1069,7 +1603,11 @@ function formatAmount(amount, locale, options) {
1069
1603
  const decimal = formatRawAmount(amount);
1070
1604
  let [integerPart, fractionPart = ""] = decimal.split(".");
1071
1605
  const maxFractionDigits = options?.maxFractionDigits;
1072
- const minFractionDigits = maxFractionDigits !== void 0 ? Math.min(maxFractionDigits, amount.decimals) : Math.min(2, amount.decimals);
1606
+ const minFractionDigits = Math.min(
1607
+ options?.minFractionDigits ?? (maxFractionDigits !== void 0 ? maxFractionDigits : 2),
1608
+ maxFractionDigits ?? amount.decimals,
1609
+ amount.decimals
1610
+ );
1073
1611
  if (maxFractionDigits !== void 0 && fractionPart.length > maxFractionDigits) {
1074
1612
  ({ integerPart, fractionPart } = roundFractionHalfUp(
1075
1613
  integerPart,
@@ -1077,7 +1615,8 @@ function formatAmount(amount, locale, options) {
1077
1615
  maxFractionDigits
1078
1616
  ));
1079
1617
  }
1080
- const fraction = minFractionDigits === 0 ? "" : fractionPart.padEnd(minFractionDigits, "0");
1618
+ const trimmed = fractionPart.replace(/0+$/, "");
1619
+ const fraction = trimmed.padEnd(minFractionDigits, "0");
1081
1620
  const integerFormatted = BigInt(integerPart).toLocaleString(locale);
1082
1621
  if (minFractionDigits === 0 && fraction === "") {
1083
1622
  return FormattedAmountUi(integerFormatted);
@@ -1146,6 +1685,14 @@ function assetAmount(amount, symbol) {
1146
1685
  return FormattedAmountAssetUi(`${amount} ${symbol}`);
1147
1686
  }
1148
1687
  var NA_AMOUNT_ASSET_UI = FormattedAmountAssetUi("-");
1688
+ var SHARE_MAX_FRACTION_DIGITS = AssetDecimals(6);
1689
+ var SHARE_MIN_FRACTION_DIGITS = AssetDecimals(2);
1690
+ function formatShareAmount(amount, locale) {
1691
+ return formatAmount(amount, locale, {
1692
+ maxFractionDigits: SHARE_MAX_FRACTION_DIGITS,
1693
+ minFractionDigits: SHARE_MIN_FRACTION_DIGITS
1694
+ });
1695
+ }
1149
1696
  var USD_FRACTION_DIGITS = AssetDecimals(2);
1150
1697
  function formattedUsdPrice(amount, locale) {
1151
1698
  if (!amount) return NA_AMOUNT_ASSET_UI;
@@ -1212,66 +1759,6 @@ function explorerBaseUrl(chain) {
1212
1759
  }
1213
1760
  }
1214
1761
 
1215
- // src/universal/core/shared/blockchain/math.ts
1216
- import { parseUnits } from "viem";
1217
- function blockchainAmountFromRawOrThrow({
1218
- label,
1219
- raw,
1220
- decimals
1221
- }) {
1222
- const trimmed = raw.trim();
1223
- if (trimmed === "") {
1224
- throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
1225
- }
1226
- let value;
1227
- try {
1228
- value = BigInt(trimmed);
1229
- } catch {
1230
- throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
1231
- }
1232
- try {
1233
- return BlockchainAmount({ raw: assertUint256(value), decimals });
1234
- } catch {
1235
- throw new ValidationError(`${label}: out of uint256 bounds (${value})`);
1236
- }
1237
- }
1238
- function parseBlockchainAmount(amount, decimals) {
1239
- const trimmed = amount.trim();
1240
- if (trimmed === "") return { valid: false, reason: { type: "empty" } };
1241
- if (trimmed.startsWith("-")) {
1242
- return { valid: false, reason: { type: "negative" } };
1243
- }
1244
- if (/[eE]/.test(trimmed)) {
1245
- return { valid: false, reason: { type: "invalid-format" } };
1246
- }
1247
- if (trimmed === ".") {
1248
- return { valid: false, reason: { type: "invalid-format" } };
1249
- }
1250
- const normalised = trimmed.replace(/^\./, "0.").replace(/\.$/, "");
1251
- if (!/^\d+(\.\d+)?$/.test(normalised)) {
1252
- return { valid: false, reason: { type: "invalid-format" } };
1253
- }
1254
- const [, fraction = ""] = normalised.split(".");
1255
- if (fraction.length > decimals) {
1256
- return {
1257
- valid: false,
1258
- reason: { type: "too-many-decimals", maxDecimals: decimals }
1259
- };
1260
- }
1261
- try {
1262
- const raw = parseUnits(normalised, decimals);
1263
- if (raw > MAX_UINT_256) {
1264
- return { valid: false, reason: { type: "overflow" } };
1265
- }
1266
- return {
1267
- valid: true,
1268
- amount: BlockchainAmount({ raw, decimals })
1269
- };
1270
- } catch {
1271
- return { valid: false, reason: { type: "invalid-format" } };
1272
- }
1273
- }
1274
-
1275
1762
  // src/universal/types/providers/ondo/ondo.ts
1276
1763
  var OndoTradingStatus = {
1277
1764
  fromDto: (dto) => {
@@ -1287,7 +1774,6 @@ var OndoTradingStatus = {
1287
1774
  };
1288
1775
  }
1289
1776
  };
1290
- var decimalOrNull = (value) => value === null ? null : DecimalString(value);
1291
1777
  var OndoQuote = {
1292
1778
  fromDto: (dto) => {
1293
1779
  const assetDecimals = AssetDecimals(dto.asset_decimals);
@@ -2944,11 +3430,18 @@ var HttpClient = class {
2944
3430
  );
2945
3431
  let response = await this.executeRequest(preparedRequest);
2946
3432
  for (const middleware of this.middleware.afterRequest ?? []) {
3433
+ let retried = false;
2947
3434
  response = await middleware({
2948
3435
  request: preparedRequest,
2949
3436
  response,
2950
- retry: (nextRequest = preparedRequest) => this.runRequestWithAfterMiddleware(nextRequest)
3437
+ retry: (nextRequest = preparedRequest) => {
3438
+ retried = true;
3439
+ return this.runRequestWithAfterMiddleware(nextRequest);
3440
+ }
2951
3441
  });
3442
+ if (retried) {
3443
+ return response;
3444
+ }
2952
3445
  }
2953
3446
  return response;
2954
3447
  }
@@ -3394,6 +3887,9 @@ export {
3394
3887
  VERIFY_IDENTITY_PATH,
3395
3888
  VERIFY_IDENTITY_ACCREDITATION_PATH,
3396
3889
  WALLET_PATH,
3890
+ SentWith,
3891
+ TokenTrigger,
3892
+ isRejectedToken,
3397
3893
  Attributes,
3398
3894
  HttpError,
3399
3895
  apiErrorCode,
@@ -3406,14 +3902,11 @@ export {
3406
3902
  describeErrorUnredacted,
3407
3903
  internalLogger,
3408
3904
  HttpClient,
3905
+ EpochMillis,
3906
+ Millis,
3907
+ Seconds,
3908
+ isExpired,
3409
3909
  ERC20_ABI,
3410
- fetchAllPages,
3411
- Cursor,
3412
- PaginatedResponse,
3413
- PaginationParams,
3414
- AssetId,
3415
- AssetCode,
3416
- Asset,
3417
3910
  ETHEREUM_CHAINS,
3418
3911
  EthereumChain,
3419
3912
  SOLANA_CHAINS,
@@ -3435,6 +3928,25 @@ export {
3435
3928
  StablecoinSymbol,
3436
3929
  KnownAssetSymbol,
3437
3930
  Bps,
3931
+ blockchainAmountFromRawOrThrow,
3932
+ parseBlockchainAmount,
3933
+ CentrifugeVaultQuote,
3934
+ CentrifugeVaultStatus,
3935
+ CentrifugeVaultBuyTransaction,
3936
+ CentrifugeVaultClaimTransaction,
3937
+ CentrifugeVaultPosition,
3938
+ CentrifugeVaultRedeemPosition,
3939
+ CentrifugeVaultLeg,
3940
+ CentrifugeVaultLegId,
3941
+ CentrifugeVaultClaimProceedsTransaction,
3942
+ CentrifugeNamespaceImpl,
3943
+ fetchAllPages,
3944
+ Cursor,
3945
+ PaginatedResponse,
3946
+ PaginationParams,
3947
+ AssetId,
3948
+ AssetCode,
3949
+ Asset,
3438
3950
  OfferId,
3439
3951
  OfferSlug,
3440
3952
  isOfferType,
@@ -3443,9 +3955,11 @@ export {
3443
3955
  OfferToken,
3444
3956
  Ticker,
3445
3957
  Isin,
3958
+ AsyncOfferDetail,
3446
3959
  OfferOptionId,
3447
3960
  OfferOptionSlug,
3448
3961
  OfferSwapContract,
3962
+ OfferVaultContract,
3449
3963
  OfferDetail,
3450
3964
  OfferOption,
3451
3965
  FaqItem,
@@ -3473,14 +3987,13 @@ export {
3473
3987
  usdAmount,
3474
3988
  assetAmount,
3475
3989
  NA_AMOUNT_ASSET_UI,
3990
+ formatShareAmount,
3476
3991
  formattedUsdPrice,
3477
3992
  viemChain,
3478
3993
  getChainId,
3479
3994
  chainFromId,
3480
3995
  getNetworkName,
3481
3996
  txExplorerUrl,
3482
- blockchainAmountFromRawOrThrow,
3483
- parseBlockchainAmount,
3484
3997
  OndoTradingStatus,
3485
3998
  OndoQuote,
3486
3999
  OndoBuyTransaction,
@@ -3521,4 +4034,4 @@ export {
3521
4034
  OAuthRefreshToken,
3522
4035
  OAuthSession
3523
4036
  };
3524
- //# sourceMappingURL=chunk-MOE5S6CE.js.map
4037
+ //# sourceMappingURL=chunk-YMDYLYL3.js.map