@coinlist-co/react 0.12.2-rc.726778a → 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-C6F5FOFP.js → chunk-2HCSM3FB.js} +52 -19
  2. package/dist/chunk-2HCSM3FB.js.map +1 -0
  3. package/dist/{chunk-3UQPCAU4.js → chunk-OUFI3D3Q.js} +84 -4
  4. package/dist/chunk-OUFI3D3Q.js.map +1 -0
  5. package/dist/{chunk-IRV5YU42.js → chunk-YMDYLYL3.js} +941 -442
  6. package/dist/chunk-YMDYLYL3.js.map +1 -0
  7. package/dist/client/index.cjs +12358 -8385
  8. package/dist/client/index.cjs.map +1 -1
  9. package/dist/client/index.d.cts +1965 -227
  10. package/dist/client/index.d.ts +1965 -227
  11. package/dist/client/index.js +8766 -5370
  12. package/dist/client/index.js.map +1 -1
  13. package/dist/server/index.cjs +842 -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 +1022 -440
  24. package/dist/universal/index.cjs.map +1 -1
  25. package/dist/universal/index.d.cts +88 -5
  26. package/dist/universal/index.d.ts +88 -5
  27. package/dist/universal/index.js +46 -2
  28. package/package.json +1 -1
  29. package/dist/chunk-3UQPCAU4.js.map +0 -1
  30. package/dist/chunk-C6F5FOFP.js.map +0 -1
  31. package/dist/chunk-IRV5YU42.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
  }
@@ -763,261 +1480,78 @@ var ParticipationsPaginationParams = {
763
1480
  toQueryParams: (params) => {
764
1481
  const queryParams = PaginationParams.toQueryParams(params);
765
1482
  if (params.offerId) {
766
- queryParams["filters[0][field]"] = "offer_id";
767
- queryParams["filters[0][op]"] = "==";
768
- 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}`;
1483
+ queryParams["filters[0][field]"] = "offer_id";
1484
+ queryParams["filters[0][op]"] = "==";
1485
+ queryParams["filters[0][value]"] = params.offerId;
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 {
@@ -1225,66 +1759,6 @@ function explorerBaseUrl(chain) {
1225
1759
  }
1226
1760
  }
1227
1761
 
1228
- // src/universal/core/shared/blockchain/math.ts
1229
- import { parseUnits } from "viem";
1230
- function blockchainAmountFromRawOrThrow({
1231
- label,
1232
- raw,
1233
- decimals
1234
- }) {
1235
- const trimmed = raw.trim();
1236
- if (trimmed === "") {
1237
- throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
1238
- }
1239
- let value;
1240
- try {
1241
- value = BigInt(trimmed);
1242
- } catch {
1243
- throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
1244
- }
1245
- try {
1246
- return BlockchainAmount({ raw: assertUint256(value), decimals });
1247
- } catch {
1248
- throw new ValidationError(`${label}: out of uint256 bounds (${value})`);
1249
- }
1250
- }
1251
- function parseBlockchainAmount(amount, decimals) {
1252
- const trimmed = amount.trim();
1253
- if (trimmed === "") return { valid: false, reason: { type: "empty" } };
1254
- if (trimmed.startsWith("-")) {
1255
- return { valid: false, reason: { type: "negative" } };
1256
- }
1257
- if (/[eE]/.test(trimmed)) {
1258
- return { valid: false, reason: { type: "invalid-format" } };
1259
- }
1260
- if (trimmed === ".") {
1261
- return { valid: false, reason: { type: "invalid-format" } };
1262
- }
1263
- const normalised = trimmed.replace(/^\./, "0.").replace(/\.$/, "");
1264
- if (!/^\d+(\.\d+)?$/.test(normalised)) {
1265
- return { valid: false, reason: { type: "invalid-format" } };
1266
- }
1267
- const [, fraction = ""] = normalised.split(".");
1268
- if (fraction.length > decimals) {
1269
- return {
1270
- valid: false,
1271
- reason: { type: "too-many-decimals", maxDecimals: decimals }
1272
- };
1273
- }
1274
- try {
1275
- const raw = parseUnits(normalised, decimals);
1276
- if (raw > MAX_UINT_256) {
1277
- return { valid: false, reason: { type: "overflow" } };
1278
- }
1279
- return {
1280
- valid: true,
1281
- amount: BlockchainAmount({ raw, decimals })
1282
- };
1283
- } catch {
1284
- return { valid: false, reason: { type: "invalid-format" } };
1285
- }
1286
- }
1287
-
1288
1762
  // src/universal/types/providers/ondo/ondo.ts
1289
1763
  var OndoTradingStatus = {
1290
1764
  fromDto: (dto) => {
@@ -1300,7 +1774,6 @@ var OndoTradingStatus = {
1300
1774
  };
1301
1775
  }
1302
1776
  };
1303
- var decimalOrNull = (value) => value === null ? null : DecimalString(value);
1304
1777
  var OndoQuote = {
1305
1778
  fromDto: (dto) => {
1306
1779
  const assetDecimals = AssetDecimals(dto.asset_decimals);
@@ -2957,11 +3430,18 @@ var HttpClient = class {
2957
3430
  );
2958
3431
  let response = await this.executeRequest(preparedRequest);
2959
3432
  for (const middleware of this.middleware.afterRequest ?? []) {
3433
+ let retried = false;
2960
3434
  response = await middleware({
2961
3435
  request: preparedRequest,
2962
3436
  response,
2963
- retry: (nextRequest = preparedRequest) => this.runRequestWithAfterMiddleware(nextRequest)
3437
+ retry: (nextRequest = preparedRequest) => {
3438
+ retried = true;
3439
+ return this.runRequestWithAfterMiddleware(nextRequest);
3440
+ }
2964
3441
  });
3442
+ if (retried) {
3443
+ return response;
3444
+ }
2965
3445
  }
2966
3446
  return response;
2967
3447
  }
@@ -3407,6 +3887,9 @@ export {
3407
3887
  VERIFY_IDENTITY_PATH,
3408
3888
  VERIFY_IDENTITY_ACCREDITATION_PATH,
3409
3889
  WALLET_PATH,
3890
+ SentWith,
3891
+ TokenTrigger,
3892
+ isRejectedToken,
3410
3893
  Attributes,
3411
3894
  HttpError,
3412
3895
  apiErrorCode,
@@ -3419,14 +3902,11 @@ export {
3419
3902
  describeErrorUnredacted,
3420
3903
  internalLogger,
3421
3904
  HttpClient,
3905
+ EpochMillis,
3906
+ Millis,
3907
+ Seconds,
3908
+ isExpired,
3422
3909
  ERC20_ABI,
3423
- fetchAllPages,
3424
- Cursor,
3425
- PaginatedResponse,
3426
- PaginationParams,
3427
- AssetId,
3428
- AssetCode,
3429
- Asset,
3430
3910
  ETHEREUM_CHAINS,
3431
3911
  EthereumChain,
3432
3912
  SOLANA_CHAINS,
@@ -3448,6 +3928,25 @@ export {
3448
3928
  StablecoinSymbol,
3449
3929
  KnownAssetSymbol,
3450
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,
3451
3950
  OfferId,
3452
3951
  OfferSlug,
3453
3952
  isOfferType,
@@ -3456,9 +3955,11 @@ export {
3456
3955
  OfferToken,
3457
3956
  Ticker,
3458
3957
  Isin,
3958
+ AsyncOfferDetail,
3459
3959
  OfferOptionId,
3460
3960
  OfferOptionSlug,
3461
3961
  OfferSwapContract,
3962
+ OfferVaultContract,
3462
3963
  OfferDetail,
3463
3964
  OfferOption,
3464
3965
  FaqItem,
@@ -3493,8 +3994,6 @@ export {
3493
3994
  chainFromId,
3494
3995
  getNetworkName,
3495
3996
  txExplorerUrl,
3496
- blockchainAmountFromRawOrThrow,
3497
- parseBlockchainAmount,
3498
3997
  OndoTradingStatus,
3499
3998
  OndoQuote,
3500
3999
  OndoBuyTransaction,
@@ -3535,4 +4034,4 @@ export {
3535
4034
  OAuthRefreshToken,
3536
4035
  OAuthSession
3537
4036
  };
3538
- //# sourceMappingURL=chunk-IRV5YU42.js.map
4037
+ //# sourceMappingURL=chunk-YMDYLYL3.js.map