@coinlist-co/react 0.12.2-rc.4851c6a → 0.12.2-rc.4cc3d7e

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.
@@ -1,93 +1,4 @@
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
-
25
- // src/universal/api/http-attributes.ts
26
- var empty = {};
27
- var concat = (left, right) => ({
28
- ...left,
29
- ...right
30
- });
31
- var concatAll = (...items) => {
32
- let result = empty;
33
- for (const item of items) {
34
- result = concat(result, item);
35
- }
36
- return result;
37
- };
38
- var protectedRequest = () => ({ protected: true });
39
- var userAgent = () => ({ userAgent: true });
40
- var idempotencyKey = () => ({
41
- idempotencyKey: true
42
- });
43
- var clientCredentials = (credentials) => ({
44
- clientCredentials: credentials
45
- });
46
- var retryAttempt = (attempt) => ({
47
- retryAttempt: attempt
48
- });
49
- var renewAttempted = (value) => ({
50
- renewAttempted: value
51
- });
52
- var notRetryable = () => ({ retryable: false });
53
- var sentWith = (token) => ({
54
- sentWith: token
55
- });
56
- var requestId = (id) => ({ requestId: id });
57
- var getRequestId = (attrs) => attrs?.requestId ?? null;
58
- var isProtected = (attrs) => attrs?.protected === true;
59
- var needUserAgent = (attrs) => attrs?.userAgent === true;
60
- var isIdempotent = (attrs) => attrs?.idempotencyKey === true;
61
- var getRetryAttempt = (attrs) => attrs?.retryAttempt ?? 0;
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);
65
- var getClientCredentials = (attrs) => attrs?.clientCredentials;
66
- var Attributes = {
67
- empty,
68
- concat,
69
- concatAll,
70
- protected: protectedRequest,
71
- isProtected,
72
- userAgent,
73
- needUserAgent,
74
- idempotencyKey,
75
- isIdempotent,
76
- retryAttempt,
77
- getRetryAttempt,
78
- renewAttempted,
79
- wasRenewAttempted,
80
- notRetryable,
81
- isRetryable,
82
- sentWith,
83
- getSentWith,
84
- clientCredentials,
85
- getClientCredentials,
86
- requestId,
87
- getRequestId
88
- };
89
-
90
- // src/universal/api/http.ts
1
+ // src/universal/types/http.ts
91
2
  var HttpError = class extends Error {
92
3
  constructor(response) {
93
4
  super(`Request failed with ${response.status} status`);
@@ -112,104 +23,6 @@ function apiErrorCode(error) {
112
23
  const code = body.code;
113
24
  return typeof code === "string" ? code : null;
114
25
  }
115
- async function makeRequest(request) {
116
- const headers = {
117
- Accept: "application/json",
118
- ...request.method === "POST" && request.body !== void 0 ? { "Content-Type": "application/json" } : {},
119
- ...request.headers ?? {}
120
- };
121
- const init = {
122
- method: request.method,
123
- headers,
124
- ...request.redirect !== void 0 ? { redirect: request.redirect } : {}
125
- };
126
- if (request.method === "POST" && request.body !== void 0) {
127
- init.body = JSON.stringify(request.body);
128
- }
129
- const response = await fetch(
130
- buildUrlWithQueryParams(request.url, request.queryParams),
131
- init
132
- );
133
- const responseHeaders = headersToRecord(response.headers);
134
- if (response.status === 204 || response.status === 205) {
135
- return {
136
- status: response.status,
137
- body: null,
138
- headers: responseHeaders
139
- };
140
- }
141
- if (response.status >= 300 && response.status < 400) {
142
- await response.text();
143
- return {
144
- status: response.status,
145
- body: null,
146
- headers: responseHeaders
147
- };
148
- }
149
- const text = await response.text();
150
- let body;
151
- try {
152
- body = text ? JSON.parse(text) : null;
153
- } catch (_) {
154
- throw new HttpError({
155
- status: response.status,
156
- headers: responseHeaders,
157
- body: text
158
- });
159
- }
160
- return {
161
- status: response.status,
162
- body,
163
- headers: responseHeaders
164
- };
165
- }
166
- function buildUrlWithQueryParams(url, queryParams) {
167
- if (!queryParams) {
168
- return url;
169
- }
170
- const searchParams = new URLSearchParams();
171
- for (const [key, value] of Object.entries(queryParams)) {
172
- if (value === void 0 || value === null) {
173
- continue;
174
- }
175
- if (Array.isArray(value)) {
176
- for (const item of value) {
177
- if (item === void 0 || item === null) {
178
- continue;
179
- }
180
- searchParams.append(key, String(item));
181
- }
182
- continue;
183
- }
184
- searchParams.append(key, String(value));
185
- }
186
- const queryString = searchParams.toString();
187
- if (!queryString) {
188
- return url;
189
- }
190
- return url.includes("?") ? `${url}&${queryString}` : `${url}?${queryString}`;
191
- }
192
- function headersToRecord(headers) {
193
- const record = {};
194
- headers.forEach((value, key) => {
195
- record[key.toLowerCase()] = value;
196
- });
197
- return record;
198
- }
199
- function concatAttributes(request, attrs) {
200
- const nextAttributes = Attributes.concat(
201
- request.attributes ?? Attributes.empty,
202
- attrs
203
- );
204
- const nextRequest = {
205
- ...request,
206
- attributes: nextAttributes
207
- };
208
- return nextRequest;
209
- }
210
- var Request = {
211
- concatAttributes
212
- };
213
26
 
214
27
  // src/universal/types/errors.ts
215
28
  var NotImplementedError = class extends Error {
@@ -291,6 +104,75 @@ function isExpired({
291
104
  return now >= expiresAt - buffer;
292
105
  }
293
106
 
107
+ // src/universal/types/blockchain/ui.ts
108
+ var FormattedAmountUi = (value) => value;
109
+ var FormattedPercentUi = (value) => value;
110
+ var TxExplorerUrl = (value) => value;
111
+ var ShortenedWalletAddress = (value) => value;
112
+ var FormattedAmountAssetUi = (value) => value;
113
+ var AssetIconUrl = (value) => value;
114
+
115
+ // src/universal/core/shared/blockchain/chain.ts
116
+ import { base, baseSepolia, mainnet, sepolia } from "viem/chains";
117
+ var VIEM_CHAINS = {
118
+ ethereum_mainnet: mainnet,
119
+ ethereum_sepolia: sepolia,
120
+ base_mainnet: base,
121
+ base_sepolia: baseSepolia
122
+ };
123
+ function viemChain(chain) {
124
+ return VIEM_CHAINS[chain];
125
+ }
126
+ function getChainId(chain) {
127
+ return VIEM_CHAINS[chain].id;
128
+ }
129
+ function chainFromId(chainId) {
130
+ const chains = Object.keys(VIEM_CHAINS);
131
+ const chain = chains.find((c) => String(VIEM_CHAINS[c].id) === chainId);
132
+ if (!chain) {
133
+ throw new ValidationError(`Unsupported EIP-155 chain id: "${chainId}"`);
134
+ }
135
+ return chain;
136
+ }
137
+ function contractOn(contracts, chain) {
138
+ return contracts.find((contract) => contract.chain === chain)?.address ?? null;
139
+ }
140
+ function getNetworkName(chain) {
141
+ switch (chain) {
142
+ case "ethereum_mainnet":
143
+ return "Ethereum";
144
+ case "ethereum_sepolia":
145
+ return "Ethereum Sepolia";
146
+ case "base_mainnet":
147
+ return "Base";
148
+ case "base_sepolia":
149
+ return "Base Sepolia";
150
+ default: {
151
+ const _exhaustive = chain;
152
+ return _exhaustive;
153
+ }
154
+ }
155
+ }
156
+ function txExplorerUrl(chain, txHash) {
157
+ return TxExplorerUrl(`${explorerBaseUrl(chain)}/tx/${txHash}`);
158
+ }
159
+ function explorerBaseUrl(chain) {
160
+ switch (chain) {
161
+ case "ethereum_mainnet":
162
+ return "https://etherscan.io";
163
+ case "ethereum_sepolia":
164
+ return "https://sepolia.etherscan.io";
165
+ case "base_mainnet":
166
+ return "https://basescan.org";
167
+ case "base_sepolia":
168
+ return "https://sepolia-explorer.base.org";
169
+ default: {
170
+ const _exhaustive = chain;
171
+ return _exhaustive;
172
+ }
173
+ }
174
+ }
175
+
294
176
  // src/universal/types/blockchain/core.ts
295
177
  var ETHEREUM_CHAINS = {
296
178
  ethereum_mainnet: true,
@@ -421,6 +303,36 @@ function blockchainAmountFromRawOrThrow({
421
303
  throw new ValidationError(`${label}: out of uint256 bounds (${value})`);
422
304
  }
423
305
  }
306
+ function positiveAmountFromRawOrThrow({
307
+ label,
308
+ raw,
309
+ decimals,
310
+ reason
311
+ }) {
312
+ const amount = blockchainAmountFromRawOrThrow({ label, raw, decimals });
313
+ if (amount.raw === 0n) {
314
+ throw new ValidationError(
315
+ `${label}: must be greater than zero ("${raw}") - ${reason}`
316
+ );
317
+ }
318
+ return amount;
319
+ }
320
+ function pricePerShare({
321
+ usd,
322
+ shares
323
+ }) {
324
+ const price = BlockchainAmount.div(usd, shares);
325
+ return BlockchainAmount({
326
+ raw: assertPriceFits(price.raw),
327
+ decimals: price.decimals
328
+ });
329
+ }
330
+ function assertPriceFits(raw) {
331
+ if (raw > MAX_UINT_256) {
332
+ throw new MathError(`Price per share: out of uint256 bounds (${raw})`);
333
+ }
334
+ return raw;
335
+ }
424
336
  function parseBlockchainAmount(amount, decimals) {
425
337
  const trimmed = amount.trim();
426
338
  if (trimmed === "") return { valid: false, reason: { type: "empty" } };
@@ -534,10 +446,13 @@ function requiredDate(value, field) {
534
446
  return date;
535
447
  }
536
448
  function dateOrNull(value, field) {
537
- return value === null ? null : requiredDate(value, field);
449
+ return mapNullish(value, (date) => requiredDate(date, field));
538
450
  }
539
451
  function decimalOrNull(value) {
540
- return value === null ? null : DecimalString(value);
452
+ return mapNullish(value, DecimalString);
453
+ }
454
+ function mapNullish(value, parse) {
455
+ return value === null || value === void 0 ? null : parse(value);
541
456
  }
542
457
  function requiredArray(value, field) {
543
458
  if (!Array.isArray(value)) {
@@ -547,6 +462,12 @@ function requiredArray(value, field) {
547
462
  }
548
463
  return value;
549
464
  }
465
+ function txFromWire(wire) {
466
+ return {
467
+ to: EvmContractAddress(wire.to),
468
+ data: HexEncodedTransactionData(wire.data)
469
+ };
470
+ }
550
471
 
551
472
  // src/universal/types/providers/centrifuge/centrifuge.ts
552
473
  var CentrifugeVaultStatus = {
@@ -575,19 +496,16 @@ var CentrifugeVaultStatus = {
575
496
  };
576
497
  var CentrifugeVaultBuyTransaction = {
577
498
  fromDto: (dto) => {
578
- const spendInputAmount = blockchainAmountFromRawOrThrow({
579
- label: "spend_input_amount",
580
- raw: dto.spend_input_amount,
581
- decimals: AssetDecimals(dto.spend_input_decimals)
582
- });
583
- if (spendInputAmount.raw <= 0n) {
584
- throw new ValidationError(
585
- `spend_input_amount: must be greater than zero ("${dto.spend_input_amount}") - a deposit of nothing is not a request`
586
- );
587
- }
588
499
  return {
589
500
  ...parseTransactionCore(dto, "CentrifugeVaultBuyTransaction"),
590
- spendInputAmount
501
+ spendInputAmount: positiveAmountFromRawOrThrow({
502
+ label: "spend_input_amount",
503
+ raw: dto.spend_input_amount,
504
+ decimals: AssetDecimals(dto.spend_input_decimals),
505
+ // Frontline refuses an `amount` of zero, so a zero here is a changed
506
+ // encoding, not a small deposit - and not calldata worth signing.
507
+ reason: "a deposit of nothing is not a request"
508
+ })
591
509
  };
592
510
  }
593
511
  };
@@ -601,72 +519,41 @@ var CentrifugeVaultClaimTransaction = {
601
519
  })
602
520
  })
603
521
  };
604
- var CentrifugeVaultPosition = {
605
- fromDto: (dto) => {
606
- const assetDecimals = AssetDecimals(dto.asset_decimals);
607
- const shareDecimals = AssetDecimals(dto.share_decimals);
608
- const asset = (label, raw) => blockchainAmountFromRawOrThrow({ label, raw, decimals: assetDecimals });
609
- const shares = (label, raw) => blockchainAmountFromRawOrThrow({ label, raw, decimals: shareDecimals });
522
+ var CentrifugeAssets = (amount) => amount;
523
+ var CentrifugeShares = (amount) => amount;
524
+ var CentrifugeDepositPosition = {
525
+ fromContract: (raw, context) => {
526
+ const assets = (label, value) => CentrifugeAssets(contractAmount(label, value, context.assetDecimals));
610
527
  return {
611
- chain: EthereumChain(dto.chain),
612
- symbol: AssetSymbol(dto.symbol),
613
- walletAddress: EvmWalletAddress(dto.wallet_address),
614
- status: dto.status,
615
- requested: asset("requested", dto.requested),
616
- pending: asset("pending", dto.pending),
617
- filledAssets: asset("filled_assets", dto.filled_assets),
618
- earnedShares: shares("earned_shares", dto.earned_shares),
619
- claimedShares: shares("claimed_shares", dto.claimed_shares),
620
- claimableShares: shares("claimable_shares", dto.claimable_shares),
621
- shareBalance: shares("share_balance", dto.share_balance),
622
- averagePrice: decimalOrNull(dto.average_price),
623
- frozen: dto.frozen,
624
- asOf: requiredDate(dto.as_of, "CentrifugeVaultPosition.as_of")
528
+ chain: context.chain,
529
+ proxy: context.proxy,
530
+ walletAddress: context.walletAddress,
531
+ pending: assets("pendingDepositRequest", raw.pendingDepositRequest),
532
+ claimable: assets("claimableDepositRequest", raw.claimableDepositRequest)
625
533
  };
626
534
  }
627
535
  };
628
- var CentrifugeVaultRedeemPosition = {
629
- fromDto: (dto) => ({
630
- chain: EthereumChain(dto.chain),
631
- symbol: AssetSymbol(dto.symbol),
632
- walletAddress: EvmWalletAddress(dto.wallet_address),
633
- status: dto.status,
634
- pending: blockchainAmountFromRawOrThrow({
635
- label: "pending",
636
- raw: dto.pending,
637
- decimals: AssetDecimals(dto.share_decimals)
638
- }),
639
- claimableAssets: blockchainAmountFromRawOrThrow({
640
- label: "claimable_assets",
641
- raw: dto.claimable_assets,
642
- decimals: AssetDecimals(dto.asset_decimals)
643
- }),
644
- frozen: dto.frozen,
645
- asOf: requiredDate(dto.as_of, "CentrifugeVaultRedeemPosition.as_of")
646
- })
536
+ var CentrifugeRedeemPosition = {
537
+ fromContract: (raw, context) => {
538
+ const shares = (label, value) => CentrifugeShares(contractAmount(label, value, context.shareDecimals));
539
+ return {
540
+ chain: context.chain,
541
+ proxy: context.proxy,
542
+ walletAddress: context.walletAddress,
543
+ pending: shares("pendingRedeemRequest", raw.pendingRedeemRequest),
544
+ claimable: shares("claimableRedeemRequest", raw.claimableRedeemRequest)
545
+ };
546
+ }
647
547
  };
648
548
  var CentrifugeVaultLeg = {
649
- /**
650
- * What a claim on the leg would collect: shares for `invest`, the funding
651
- * token for `redeem`.
652
- */
653
- claimable: (leg) => {
654
- switch (leg.direction) {
655
- case "invest":
656
- return leg.position.claimableShares;
657
- case "redeem":
658
- return leg.position.claimableAssets;
659
- default: {
660
- const exhaustive = leg;
661
- return exhaustive;
662
- }
663
- }
664
- },
665
549
  /** Whether the leg has anything queued or anything ready to claim. */
666
- isActive: (leg) => leg.position.pending.raw > 0n || CentrifugeVaultLeg.claimable(leg).raw > 0n
550
+ isActive: (leg) => leg.position.pending.raw > 0n || leg.position.claimable.raw > 0n
667
551
  };
552
+ function contractAmount(label, value, decimals) {
553
+ return BlockchainAmount({ raw: parseUint256(value, label), decimals });
554
+ }
668
555
  var CentrifugeVaultLegId = {
669
- /** Addresses compare case-insensitively: frontline echoes them lower case. */
556
+ /** Addresses compare case-insensitively: a host may pass either case. */
670
557
  of: (leg) => [
671
558
  leg.direction,
672
559
  leg.position.chain,
@@ -702,14 +589,114 @@ function parseOrderability(canOrder, reasons, model) {
702
589
  }
703
590
  function parseTransactionCore(dto, model) {
704
591
  return {
705
- tx: {
706
- to: EvmContractAddress(dto.to),
707
- data: HexEncodedTransactionData(dto.data)
708
- },
592
+ tx: txFromWire(dto),
709
593
  expiresAt: dateOrNull(dto.expires_at, `${model}.expires_at`)
710
594
  };
711
595
  }
712
596
 
597
+ // src/universal/api/frontline/providers/shared/spend-scale.ts
598
+ function assertSpendScaleAgrees({
599
+ published,
600
+ sized,
601
+ trade,
602
+ note
603
+ }) {
604
+ if (published === sized.decimals) return;
605
+ const because = note === void 0 ? "" : ` - ${note}`;
606
+ throw new ValidationError(
607
+ `spend_input_decimals: the ${trade} was priced in ${published} decimals but the order was sized in ${sized.decimals}${because}`
608
+ );
609
+ }
610
+
611
+ // src/universal/types/access-token-source.ts
612
+ var SentWith = {
613
+ userToken: (token) => ({
614
+ type: "user-token",
615
+ token
616
+ }),
617
+ noUserToken: { type: "no-user-token" }
618
+ };
619
+ var TokenTrigger = {
620
+ beforeRequest: { type: "before-request" },
621
+ after401: (rejected) => ({
622
+ type: "after-401",
623
+ rejected
624
+ })
625
+ };
626
+ function isRejectedToken(token, rejected) {
627
+ switch (rejected.type) {
628
+ case "user-token":
629
+ return rejected.token.value === token.value;
630
+ case "no-user-token":
631
+ return false;
632
+ }
633
+ }
634
+
635
+ // src/universal/api/http-attributes.ts
636
+ var empty = {};
637
+ var concat = (left, right) => ({
638
+ ...left,
639
+ ...right
640
+ });
641
+ var concatAll = (...items) => {
642
+ let result = empty;
643
+ for (const item of items) {
644
+ result = concat(result, item);
645
+ }
646
+ return result;
647
+ };
648
+ var protectedRequest = () => ({ protected: true });
649
+ var userAgent = () => ({ userAgent: true });
650
+ var idempotencyKey = () => ({
651
+ idempotencyKey: true
652
+ });
653
+ var clientCredentials = (credentials) => ({
654
+ clientCredentials: credentials
655
+ });
656
+ var retryAttempt = (attempt) => ({
657
+ retryAttempt: attempt
658
+ });
659
+ var renewAttempted = (value) => ({
660
+ renewAttempted: value
661
+ });
662
+ var notRetryable = () => ({ retryable: false });
663
+ var sentWith = (token) => ({
664
+ sentWith: token
665
+ });
666
+ var requestId = (id) => ({ requestId: id });
667
+ var getRequestId = (attrs) => attrs?.requestId ?? null;
668
+ var isProtected = (attrs) => attrs?.protected === true;
669
+ var needUserAgent = (attrs) => attrs?.userAgent === true;
670
+ var isIdempotent = (attrs) => attrs?.idempotencyKey === true;
671
+ var getRetryAttempt = (attrs) => attrs?.retryAttempt ?? 0;
672
+ var wasRenewAttempted = (attrs) => attrs?.renewAttempted === true;
673
+ var isRetryable = (attrs) => attrs?.retryable !== false;
674
+ var getSentWith = (attrs) => attrs?.sentWith === void 0 ? SentWith.noUserToken : SentWith.userToken(attrs.sentWith);
675
+ var getClientCredentials = (attrs) => attrs?.clientCredentials;
676
+ var Attributes = {
677
+ empty,
678
+ concat,
679
+ concatAll,
680
+ protected: protectedRequest,
681
+ isProtected,
682
+ userAgent,
683
+ needUserAgent,
684
+ idempotencyKey,
685
+ isIdempotent,
686
+ retryAttempt,
687
+ getRetryAttempt,
688
+ renewAttempted,
689
+ wasRenewAttempted,
690
+ notRetryable,
691
+ isRetryable,
692
+ sentWith,
693
+ getSentWith,
694
+ clientCredentials,
695
+ getClientCredentials,
696
+ requestId,
697
+ getRequestId
698
+ };
699
+
713
700
  // src/universal/api/frontline/providers/centrifuge/centrifuge.ts
714
701
  async function getCentrifugeVaultStatus(api, params) {
715
702
  const dto = await api.send({
@@ -733,30 +720,12 @@ async function buildCentrifugeVaultBuy(api, params) {
733
720
  },
734
721
  attributes: Attributes.protected()
735
722
  });
736
- if (dto.spend_input_decimals !== params.amount.decimals) {
737
- throw new ValidationError(
738
- `spend_input_decimals: the request was priced in ${dto.spend_input_decimals} decimals but the deposit was sized in ${params.amount.decimals}`
739
- );
740
- }
741
- return CentrifugeVaultBuyTransaction.fromDto(dto);
742
- }
743
- async function getCentrifugeVaultPosition(api, params) {
744
- const dto = await api.send({
745
- method: "GET",
746
- url: "/v1/centrifuge/vault/position",
747
- queryParams: walletFields(params),
748
- attributes: Attributes.protected()
749
- });
750
- return CentrifugeVaultPosition.fromDto(dto);
751
- }
752
- async function getCentrifugeVaultRedeemPosition(api, params) {
753
- const dto = await api.send({
754
- method: "GET",
755
- url: "/v1/centrifuge/vault/redeem-position",
756
- queryParams: walletFields(params),
757
- attributes: Attributes.protected()
723
+ assertSpendScaleAgrees({
724
+ published: dto.spend_input_decimals,
725
+ sized: params.amount,
726
+ trade: "deposit"
758
727
  });
759
- return CentrifugeVaultRedeemPosition.fromDto(dto);
728
+ return CentrifugeVaultBuyTransaction.fromDto(dto);
760
729
  }
761
730
  async function createCentrifugeVaultClaim(api, params) {
762
731
  const dto = await api.send({
@@ -784,6 +753,86 @@ function walletFields(params) {
784
753
  };
785
754
  }
786
755
 
756
+ // src/universal/core/providers/centrifuge/blockchain/abi.ts
757
+ var CENTRIFUGE_PROXY_ABI = [
758
+ {
759
+ type: "function",
760
+ name: "pendingDepositRequest",
761
+ inputs: [{ name: "investor", type: "address" }],
762
+ outputs: [{ name: "", type: "uint256" }],
763
+ stateMutability: "view"
764
+ },
765
+ {
766
+ type: "function",
767
+ name: "claimableDepositRequest",
768
+ inputs: [{ name: "investor", type: "address" }],
769
+ outputs: [{ name: "", type: "uint256" }],
770
+ stateMutability: "view"
771
+ },
772
+ {
773
+ type: "function",
774
+ name: "pendingRedeemRequest",
775
+ inputs: [{ name: "investor", type: "address" }],
776
+ outputs: [{ name: "", type: "uint256" }],
777
+ stateMutability: "view"
778
+ },
779
+ {
780
+ type: "function",
781
+ name: "claimableRedeemRequest",
782
+ inputs: [{ name: "investor", type: "address" }],
783
+ outputs: [{ name: "", type: "uint256" }],
784
+ stateMutability: "view"
785
+ }
786
+ ];
787
+
788
+ // src/universal/api/rpc/providers/centrifuge/position.ts
789
+ async function readCentrifugeDepositPosition(clients, params) {
790
+ const client = clients(params.vault.chain);
791
+ const proxy = proxyOf(params);
792
+ const wallet = params.walletAddress;
793
+ const [pendingDepositRequest, claimableDepositRequest] = await client.multicall({
794
+ allowFailure: false,
795
+ contracts: [
796
+ { ...proxy, functionName: "pendingDepositRequest", args: [wallet] },
797
+ { ...proxy, functionName: "claimableDepositRequest", args: [wallet] }
798
+ ]
799
+ });
800
+ return CentrifugeDepositPosition.fromContract(
801
+ { pendingDepositRequest, claimableDepositRequest },
802
+ contextOf(params)
803
+ );
804
+ }
805
+ async function readCentrifugeRedeemPosition(clients, params) {
806
+ const client = clients(params.vault.chain);
807
+ const proxy = proxyOf(params);
808
+ const wallet = params.walletAddress;
809
+ const [pendingRedeemRequest, claimableRedeemRequest] = await client.multicall(
810
+ {
811
+ allowFailure: false,
812
+ contracts: [
813
+ { ...proxy, functionName: "pendingRedeemRequest", args: [wallet] },
814
+ { ...proxy, functionName: "claimableRedeemRequest", args: [wallet] }
815
+ ]
816
+ }
817
+ );
818
+ return CentrifugeRedeemPosition.fromContract(
819
+ { pendingRedeemRequest, claimableRedeemRequest },
820
+ contextOf(params)
821
+ );
822
+ }
823
+ function proxyOf(params) {
824
+ return { address: params.vault.proxy, abi: CENTRIFUGE_PROXY_ABI };
825
+ }
826
+ function contextOf(params) {
827
+ return {
828
+ chain: params.vault.chain,
829
+ proxy: params.vault.proxy,
830
+ walletAddress: params.walletAddress,
831
+ assetDecimals: params.vault.funding.decimals,
832
+ shareDecimals: params.vault.share.decimals
833
+ };
834
+ }
835
+
787
836
  // src/universal/core/shared/observability/log-cause.ts
788
837
  import {
789
838
  BaseError,
@@ -967,7 +1016,7 @@ var noopInternalLogger = {
967
1016
  wrap: (_op, _params, run) => run()
968
1017
  };
969
1018
 
970
- // src/universal/core/checkout/centrifuge/centrifuge-namespace.ts
1019
+ // src/universal/core/providers/centrifuge/centrifuge-namespace.ts
971
1020
  var CentrifugeNamespaceImpl = class {
972
1021
  constructor(ctx) {
973
1022
  this.ctx = ctx;
@@ -979,17 +1028,19 @@ var CentrifugeNamespaceImpl = class {
979
1028
  return getCentrifugeVaultStatus(this.ctx.api, params);
980
1029
  });
981
1030
  }
982
- async getPosition(params) {
983
- return this.log.wrap("getPosition", params, async () => {
984
- await this.ctx.ensureUserAuthenticated();
985
- return getCentrifugeVaultPosition(this.ctx.api, params);
986
- });
1031
+ async readDepositPosition(params) {
1032
+ return this.log.wrap(
1033
+ "readDepositPosition",
1034
+ params,
1035
+ () => readCentrifugeDepositPosition(this.ctx.rpc, params)
1036
+ );
987
1037
  }
988
- async getRedeemPosition(params) {
989
- return this.log.wrap("getRedeemPosition", params, async () => {
990
- await this.ctx.ensureUserAuthenticated();
991
- return getCentrifugeVaultRedeemPosition(this.ctx.api, params);
992
- });
1038
+ async readRedeemPosition(params) {
1039
+ return this.log.wrap(
1040
+ "readRedeemPosition",
1041
+ params,
1042
+ () => readCentrifugeRedeemPosition(this.ctx.rpc, params)
1043
+ );
993
1044
  }
994
1045
  async createClaim(params) {
995
1046
  return this.log.wrap("createClaim", params, async () => {
@@ -1011,14 +1062,6 @@ var CentrifugeNamespaceImpl = class {
1011
1062
  }
1012
1063
  };
1013
1064
 
1014
- // src/universal/types/blockchain/ui.ts
1015
- var FormattedAmountUi = (value) => value;
1016
- var FormattedPercentUi = (value) => value;
1017
- var TxExplorerUrl = (value) => value;
1018
- var ShortenedWalletAddress = (value) => value;
1019
- var FormattedAmountAssetUi = (value) => value;
1020
- var AssetIconUrl = (value) => value;
1021
-
1022
1065
  // src/universal/core/shared/blockchain/formatters.ts
1023
1066
  import { formatUnits } from "viem";
1024
1067
  function shortenAddress(address) {
@@ -1127,6 +1170,38 @@ function formattedUsdPrice(amount, locale) {
1127
1170
  );
1128
1171
  }
1129
1172
 
1173
+ // src/universal/types/pagination.ts
1174
+ var Cursor = (value) => value;
1175
+ var PaginatedResponse = {
1176
+ fromDto: (dto, itemMapper) => PaginatedResponse.fromDtoPage(dto, (items) => items.map(itemMapper)),
1177
+ /**
1178
+ * For a mapper that decides the page as a whole - one that drops items it
1179
+ * cannot map, such as `Offer.listFromDto` - rather than item by item. The
1180
+ * cursors are the wire's either way: dropping an item changes what the
1181
+ * page holds, not where the next page starts.
1182
+ */
1183
+ fromDtoPage: (dto, pageMapper) => ({
1184
+ data: pageMapper(dto.data),
1185
+ startingAfter: dto.starting_after ? Cursor(dto.starting_after) : null,
1186
+ startingBefore: dto.starting_before ? Cursor(dto.starting_before) : null
1187
+ })
1188
+ };
1189
+ var PaginationParams = {
1190
+ toQueryParams: (params) => {
1191
+ const queryParams = {};
1192
+ if (params.after) {
1193
+ queryParams.starting_after = params.after;
1194
+ }
1195
+ if (params.before) {
1196
+ queryParams.starting_before = params.before;
1197
+ }
1198
+ if (params.limit) {
1199
+ queryParams.limit = params.limit;
1200
+ }
1201
+ return queryParams;
1202
+ }
1203
+ };
1204
+
1130
1205
  // src/universal/types/asset.ts
1131
1206
  var AssetId = (value) => value;
1132
1207
  var AssetCode = (value) => value;
@@ -1278,6 +1353,17 @@ var OfferVaultContract = {
1278
1353
  */
1279
1354
  listFromDto: (dtos) => dtos.filter((dto) => isChain(dto.chain)).map(OfferVaultContract.fromDto)
1280
1355
  };
1356
+ var OfferFundingContract = {
1357
+ fromDto: (dto) => ({
1358
+ chain: Chain(dto.chain),
1359
+ address: EvmContractAddress(dto.address)
1360
+ }),
1361
+ /**
1362
+ * Drops every contract on a chain this SDK does not name, as
1363
+ * {@link OfferVaultContract.listFromDto} does.
1364
+ */
1365
+ listFromDto: (dtos) => dtos.filter((dto) => isChain(dto.chain)).map(OfferFundingContract.fromDto)
1366
+ };
1281
1367
  var OfferDetail = {
1282
1368
  fromDto: (dto) => {
1283
1369
  const fundingAssets = requiredArray(
@@ -1319,7 +1405,15 @@ var OfferDetail = {
1319
1405
  ...base2,
1320
1406
  ...OfferEditorial.fromDto(dto, "OfferDetail"),
1321
1407
  type: dto.type,
1322
- logoUrl: requiredString(dto.logo_url, "OfferDetail.logo_url")
1408
+ logoUrl: requiredString(dto.logo_url, "OfferDetail.logo_url"),
1409
+ // `[]` is fine and a missing key is not, as for `swap_contracts`:
1410
+ // this is the spender a participation's approval names.
1411
+ fundingContracts: OfferFundingContract.listFromDto(
1412
+ requiredArray(
1413
+ dto.funding_contracts,
1414
+ "OfferDetail.funding_contracts"
1415
+ )
1416
+ )
1323
1417
  };
1324
1418
  case "superstate::swap":
1325
1419
  return {
@@ -1390,47 +1484,13 @@ var TermItem = {
1390
1484
  var Milestone = {
1391
1485
  fromDto: (dto) => ({
1392
1486
  name: notBlankStringOrNull(dto.name),
1393
- schedule: notBlankStringOrNull(dto.schedule),
1394
- status: dto.status
1395
- })
1396
- };
1397
-
1398
- // src/universal/types/pagination.ts
1399
- var Cursor = (value) => value;
1400
- var PaginatedResponse = {
1401
- fromDto: (dto, itemMapper) => PaginatedResponse.fromDtoPage(dto, (items) => items.map(itemMapper)),
1402
- /**
1403
- * For a mapper that decides the page as a whole - one that drops items it
1404
- * cannot map, such as `Offer.listFromDto` - rather than item by item. The
1405
- * cursors are the wire's either way: dropping an item changes what the
1406
- * page holds, not where the next page starts.
1407
- */
1408
- fromDtoPage: (dto, pageMapper) => ({
1409
- data: pageMapper(dto.data),
1410
- startingAfter: dto.starting_after ? Cursor(dto.starting_after) : null,
1411
- startingBefore: dto.starting_before ? Cursor(dto.starting_before) : null
1487
+ schedule: notBlankStringOrNull(dto.schedule),
1488
+ status: dto.status
1412
1489
  })
1413
1490
  };
1414
- var PaginationParams = {
1415
- toQueryParams: (params) => {
1416
- const queryParams = {};
1417
- if (params.after) {
1418
- queryParams.starting_after = params.after;
1419
- }
1420
- if (params.before) {
1421
- queryParams.starting_before = params.before;
1422
- }
1423
- if (params.limit) {
1424
- queryParams.limit = params.limit;
1425
- }
1426
- return queryParams;
1427
- }
1428
- };
1429
1491
 
1430
1492
  // src/universal/types/providers/coin-list/token-sale.ts
1431
1493
  var ParticipationId = (value) => value;
1432
- var Blockchain = (value) => value;
1433
- var WalletAddress = (value) => value;
1434
1494
  var ParticipationsPaginationParams = {
1435
1495
  toQueryParams: (params) => {
1436
1496
  const queryParams = PaginationParams.toQueryParams(params);
@@ -1454,10 +1514,10 @@ var Participation = {
1454
1514
  amount: dto.amount,
1455
1515
  displayAmount: dto.amount_string,
1456
1516
  asset: Asset.fromDto(dto.asset),
1457
- chain: Blockchain(dto.chain),
1517
+ chain: isChain(dto.chain) ? dto.chain : null,
1458
1518
  insertedAt: dto.inserted_at ? new Date(dto.inserted_at) : null,
1459
1519
  updatedAt: dto.updated_at ? new Date(dto.updated_at) : null,
1460
- walletAddress: walletAddress ? WalletAddress(walletAddress) : null
1520
+ walletAddress: walletAddress ? EvmWalletAddress(walletAddress) : null
1461
1521
  };
1462
1522
  }
1463
1523
  };
@@ -1524,7 +1584,7 @@ async function createParticipation(api, params) {
1524
1584
  return Participation.fromDto(dto);
1525
1585
  }
1526
1586
 
1527
- // src/universal/core/checkout/coin-list/token-sale-namespace.ts
1587
+ // src/universal/core/providers/coin-list/token-sale-namespace.ts
1528
1588
  var CoinListTokenSaleNamespaceImpl = class {
1529
1589
  constructor(ctx) {
1530
1590
  this.ctx = ctx;
@@ -1556,64 +1616,6 @@ var CoinListTokenSaleNamespaceImpl = class {
1556
1616
  }
1557
1617
  };
1558
1618
 
1559
- // src/universal/core/shared/blockchain/chain.ts
1560
- import { base, baseSepolia, mainnet, sepolia } from "viem/chains";
1561
- var VIEM_CHAINS = {
1562
- ethereum_mainnet: mainnet,
1563
- ethereum_sepolia: sepolia,
1564
- base_mainnet: base,
1565
- base_sepolia: baseSepolia
1566
- };
1567
- function viemChain(chain) {
1568
- return VIEM_CHAINS[chain];
1569
- }
1570
- function getChainId(chain) {
1571
- return VIEM_CHAINS[chain].id;
1572
- }
1573
- function chainFromId(chainId) {
1574
- const chains = Object.keys(VIEM_CHAINS);
1575
- const chain = chains.find((c) => String(VIEM_CHAINS[c].id) === chainId);
1576
- if (!chain) {
1577
- throw new ValidationError(`Unsupported EIP-155 chain id: "${chainId}"`);
1578
- }
1579
- return chain;
1580
- }
1581
- function getNetworkName(chain) {
1582
- switch (chain) {
1583
- case "ethereum_mainnet":
1584
- return "Ethereum";
1585
- case "ethereum_sepolia":
1586
- return "Ethereum Sepolia";
1587
- case "base_mainnet":
1588
- return "Base";
1589
- case "base_sepolia":
1590
- return "Base Sepolia";
1591
- default: {
1592
- const _exhaustive = chain;
1593
- return _exhaustive;
1594
- }
1595
- }
1596
- }
1597
- function txExplorerUrl(chain, txHash) {
1598
- return TxExplorerUrl(`${explorerBaseUrl(chain)}/tx/${txHash}`);
1599
- }
1600
- function explorerBaseUrl(chain) {
1601
- switch (chain) {
1602
- case "ethereum_mainnet":
1603
- return "https://etherscan.io";
1604
- case "ethereum_sepolia":
1605
- return "https://sepolia.etherscan.io";
1606
- case "base_mainnet":
1607
- return "https://basescan.org";
1608
- case "base_sepolia":
1609
- return "https://sepolia-explorer.base.org";
1610
- default: {
1611
- const _exhaustive = chain;
1612
- return _exhaustive;
1613
- }
1614
- }
1615
- }
1616
-
1617
1619
  // src/universal/types/providers/ondo/ondo.ts
1618
1620
  var OndoTradingStatus = {
1619
1621
  fromDto: (dto) => {
@@ -1668,7 +1670,7 @@ var OndoBuyTransaction = {
1668
1670
  raw: dto.notional_value,
1669
1671
  decimals: spendDecimals
1670
1672
  }),
1671
- receiveOutputAmount: parsePositiveAmount({
1673
+ receiveOutputAmount: positiveAmountFromRawOrThrow({
1672
1674
  label: "receive_output_amount",
1673
1675
  raw: dto.receive_output_amount,
1674
1676
  decimals: outputDecimals,
@@ -1687,7 +1689,7 @@ var OndoSellTransaction = {
1687
1689
  fromDto: (dto) => {
1688
1690
  const spendDecimals = AssetDecimals(dto.spend_input_decimals);
1689
1691
  const outputDecimals = AssetDecimals(dto.receive_output_decimals);
1690
- const expectedQuantity = parsePositiveAmount({
1692
+ const expectedQuantity = positiveAmountFromRawOrThrow({
1691
1693
  label: "expected_quantity",
1692
1694
  raw: dto.expected_quantity,
1693
1695
  decimals: outputDecimals,
@@ -1721,12 +1723,12 @@ var OndoSellTransaction = {
1721
1723
  };
1722
1724
  function parseSwapCore(dto, spendDecimals) {
1723
1725
  return {
1724
- tx: {
1725
- to: EvmContractAddress(dto.to),
1726
- data: HexEncodedTransactionData(dto.data)
1727
- },
1728
- expiresAt: parseExpiresAt(dto.expires_at),
1729
- spendInputAmount: parsePositiveAmount({
1726
+ tx: txFromWire(dto),
1727
+ // A transaction whose expiry cannot be read is not safely fillable - the
1728
+ // deadline is encoded in the calldata either way, so broadcasting against
1729
+ // an unknown one only spends gas on a revert.
1730
+ expiresAt: requiredDate(dto.expires_at, "expires_at"),
1731
+ spendInputAmount: positiveAmountFromRawOrThrow({
1730
1732
  label: "spend_input_amount",
1731
1733
  raw: dto.spend_input_amount,
1732
1734
  decimals: spendDecimals,
@@ -1744,7 +1746,7 @@ function parseSwapCore(dto, spendDecimals) {
1744
1746
  };
1745
1747
  }
1746
1748
  function parseMinimumQuantity(raw, decimals, expectedQuantity) {
1747
- const amount = parsePositiveAmount({
1749
+ const amount = positiveAmountFromRawOrThrow({
1748
1750
  label: "minimum_quantity",
1749
1751
  raw,
1750
1752
  decimals,
@@ -1757,27 +1759,6 @@ function parseMinimumQuantity(raw, decimals, expectedQuantity) {
1757
1759
  }
1758
1760
  return amount;
1759
1761
  }
1760
- function parsePositiveAmount({
1761
- label,
1762
- raw,
1763
- decimals,
1764
- reason
1765
- }) {
1766
- const amount = blockchainAmountFromRawOrThrow({ label, raw, decimals });
1767
- if (amount.raw <= 0n) {
1768
- throw new ValidationError(
1769
- `${label}: must be greater than zero ("${raw}") - ${reason}`
1770
- );
1771
- }
1772
- return amount;
1773
- }
1774
- function parseExpiresAt(value) {
1775
- const date = new Date(value);
1776
- if (Number.isNaN(date.getTime())) {
1777
- throw new ValidationError(`expires_at: not a date ("${value}")`);
1778
- }
1779
- return date;
1780
- }
1781
1762
 
1782
1763
  // src/universal/api/frontline/providers/ondo/ondo.ts
1783
1764
  async function getOndoTradingStatus(api, params) {
@@ -1843,18 +1824,6 @@ function swapBody(params) {
1843
1824
  amount: params.amount.raw.toString()
1844
1825
  };
1845
1826
  }
1846
- function assertSpendScaleAgrees({
1847
- published,
1848
- sized,
1849
- trade,
1850
- note
1851
- }) {
1852
- if (published === sized.decimals) return;
1853
- const because = note === void 0 ? "" : ` - ${note}`;
1854
- throw new ValidationError(
1855
- `spend_input_decimals: the ${trade} was priced in ${published} decimals but the order was sized in ${sized.decimals}${because}`
1856
- );
1857
- }
1858
1827
  function sizeParam(params) {
1859
1828
  const tokenAmount = "tokenAmount" in params ? params.tokenAmount : void 0;
1860
1829
  const notionalValue = "notionalValue" in params ? params.notionalValue : void 0;
@@ -1874,7 +1843,7 @@ function sizeParam(params) {
1874
1843
  return { notional_value: notionalValue };
1875
1844
  }
1876
1845
 
1877
- // src/universal/core/checkout/ondo/ondo-namespace.ts
1846
+ // src/universal/core/providers/ondo/ondo-namespace.ts
1878
1847
  var OndoNamespaceImpl = class {
1879
1848
  constructor(ctx) {
1880
1849
  this.ctx = ctx;
@@ -1950,8 +1919,7 @@ var AllowWalletResponse = {
1950
1919
  case "broadcast_transaction":
1951
1920
  return {
1952
1921
  action: "broadcast_transaction",
1953
- to: EvmContractAddress(dto.to),
1954
- data: HexEncodedTransactionData(dto.data)
1922
+ tx: txFromWire(dto)
1955
1923
  };
1956
1924
  case "none":
1957
1925
  return {
@@ -1966,7 +1934,7 @@ var AllowWalletResponse = {
1966
1934
  }
1967
1935
  };
1968
1936
 
1969
- // src/universal/core/checkout/superstate/blockchain/quote.ts
1937
+ // src/universal/core/providers/superstate/blockchain/quote.ts
1970
1938
  var SwapQuote = {
1971
1939
  /**
1972
1940
  * Assembles a {@link SwapQuote} from a raw contract {@link SwapPreview}. The
@@ -2001,7 +1969,7 @@ async function allowWallet(api, params) {
2001
1969
  return AllowWalletResponse.fromDto(dto);
2002
1970
  }
2003
1971
 
2004
- // src/universal/core/checkout/superstate/blockchain/abi.ts
1972
+ // src/universal/core/providers/superstate/blockchain/abi.ts
2005
1973
  var SUPERSTATE_SWAP_ABI = [
2006
1974
  {
2007
1975
  type: "function",
@@ -3022,7 +2990,7 @@ async function getSwapOutputToken(clients, params) {
3022
2990
  };
3023
2991
  }
3024
2992
 
3025
- // src/universal/core/checkout/superstate/swap-namespace.ts
2993
+ // src/universal/core/providers/superstate/superstate-namespace.ts
3026
2994
  var SuperstateSwapNamespaceImpl = class {
3027
2995
  constructor(ctx) {
3028
2996
  this.ctx = ctx;
@@ -3394,6 +3362,61 @@ var WalletsNamespaceImpl = class {
3394
3362
  }
3395
3363
  };
3396
3364
 
3365
+ // src/universal/api/frontline/offers.ts
3366
+ async function fetchOffers(api, clientCreds) {
3367
+ return fetchAllPages((params) => fetchOffersPage(api, params, clientCreds));
3368
+ }
3369
+ async function fetchOffersPage(api, params, clientCreds) {
3370
+ const queryParams = PaginationParams.toQueryParams(params);
3371
+ const pageDto = await api.send({
3372
+ method: "GET",
3373
+ url: "/v1/offers",
3374
+ queryParams,
3375
+ attributes: Attributes.concat(
3376
+ Attributes.protected(),
3377
+ Attributes.clientCredentials(clientCreds)
3378
+ )
3379
+ });
3380
+ return PaginatedResponse.fromDtoPage(pageDto, Offer.listFromDto);
3381
+ }
3382
+ async function fetchOfferDetails(api, id, clientCreds) {
3383
+ const dto = await api.send({
3384
+ method: "GET",
3385
+ url: `/v1/offers/${id}`,
3386
+ attributes: Attributes.concat(
3387
+ Attributes.protected(),
3388
+ Attributes.clientCredentials(clientCreds)
3389
+ )
3390
+ });
3391
+ return OfferDetail.fromDto(dto);
3392
+ }
3393
+
3394
+ // src/universal/core/offers/offers-namespace.ts
3395
+ var OffersNamespaceImpl = class {
3396
+ constructor(ctx) {
3397
+ this.ctx = ctx;
3398
+ this.log = internalLogger(ctx.logger, "OFFERS");
3399
+ }
3400
+ async list() {
3401
+ return this.log.wrap("list", void 0, async () => {
3402
+ await this.ctx.ensureUserAuthenticated();
3403
+ return fetchOffers(this.ctx.api, void 0);
3404
+ });
3405
+ }
3406
+ async listPage(params) {
3407
+ return this.log.wrap("listPage", params, async () => {
3408
+ await this.ctx.ensureUserAuthenticated();
3409
+ return fetchOffersPage(this.ctx.api, params, void 0);
3410
+ });
3411
+ }
3412
+ async get(id) {
3413
+ return this.log.wrap("get", id, async () => {
3414
+ await this.ctx.ensureUserAuthenticated();
3415
+ return fetchOfferDetails(this.ctx.api, id, void 0);
3416
+ });
3417
+ }
3418
+ };
3419
+
3397
3420
  // src/universal/api/rpc/erc20.ts
3398
3421
  async function getTokenAllowance(clients, params) {
3399
3422
  const allowance = await clients(params.chain).readContract({
@@ -3521,187 +3544,6 @@ var resolveLogoUrl = (url, baseUrl) => TokenLogoUrl(
3521
3544
 
3522
3545
  // src/universal/api/nabu/tokens.ts
3523
3546
  import { getAddress } from "viem";
3524
-
3525
- // src/universal/api/frontline/config.ts
3526
- var PUBLIC_API_BASE_URL = "https://api.coinlist.co";
3527
- var HEADER_API_VERSION = "X-API-Version";
3528
- var HEADER_USER_AGENT = "User-Agent";
3529
- var HEADER_IDEMPOTENCY_KEY = "Idempotency-Key";
3530
- var API_VERSION = "2025-10-17";
3531
- var COINLIST_BASE_URL = "https://coinlist.co";
3532
- var OAUTH_PAGE_PATH = "/oauth/authorize";
3533
- var SUPPORT_NEW_TICKET_URL = "https://support.coinlist.co/support/tickets/new";
3534
- var VERIFY_IDENTITY_PATH = "/verify-identity";
3535
- var VERIFY_IDENTITY_ACCREDITATION_PATH = "/verify-identity/accreditation_full";
3536
- var WALLET_PATH = "/wallet";
3537
-
3538
- // src/universal/api/http-client.ts
3539
- var HttpClient = class {
3540
- constructor(config, middleware = {}, logger = null, options = {}) {
3541
- this.config = config;
3542
- this.middleware = middleware;
3543
- this.log = internalLogger(logger, "HTTP");
3544
- this.makeRequestId = options.makeRequestId ?? defaultMakeRequestId;
3545
- }
3546
- async send(request) {
3547
- return this.runRequestWithAfterMiddleware(request);
3548
- }
3549
- /**
3550
- * Runs beforeRequest, executeRequest, then the full afterRequest middleware
3551
- * chain. Used by send() and by the retry() callback so that when a
3552
- * middleware calls retry(), the retried response also goes through all
3553
- * afterRequest middleware (e.g. session renewal, retry). Middleware
3554
- * must use request.attributes.retryAttempt (or similar) to avoid infinite
3555
- * recursion when they trigger retries.
3556
- */
3557
- async runRequestWithAfterMiddleware(request) {
3558
- const preparedRequest = await this.runBeforeRequestMiddleware(
3559
- this.withClientDefaults(request)
3560
- );
3561
- let response = await this.executeRequest(preparedRequest);
3562
- for (const middleware of this.middleware.afterRequest ?? []) {
3563
- let retried = false;
3564
- response = await middleware({
3565
- request: preparedRequest,
3566
- response,
3567
- retry: (nextRequest = preparedRequest) => {
3568
- retried = true;
3569
- return this.runRequestWithAfterMiddleware(nextRequest);
3570
- }
3571
- });
3572
- if (retried) {
3573
- return response;
3574
- }
3575
- }
3576
- return response;
3577
- }
3578
- withClientDefaults(request) {
3579
- const url = this.resolveUrl(request.url);
3580
- const headers = {
3581
- ...request.headers ?? {},
3582
- ...this.config.xApiVersion !== void 0 ? { [HEADER_API_VERSION]: this.config.xApiVersion } : {}
3583
- };
3584
- return {
3585
- ...request,
3586
- url,
3587
- headers,
3588
- // Only when absent: a retry or a post-renewal re-send arrives with the
3589
- // first attempt's id already on it, and keeping it is the whole point.
3590
- attributes: Attributes.getRequestId(request.attributes) === null ? Attributes.concat(
3591
- request.attributes ?? Attributes.empty,
3592
- Attributes.requestId(this.makeRequestId())
3593
- ) : request.attributes
3594
- };
3595
- }
3596
- /**
3597
- * Resolves a request URL against the client's baseUrl.
3598
- *
3599
- * @internal Public only for testing. Do not use in application code; use
3600
- * {@link HttpClient.send} with a path and the client will resolve the URL.
3601
- */
3602
- resolveUrl(url) {
3603
- if (url.startsWith("http://") || url.startsWith("https://")) {
3604
- return url;
3605
- }
3606
- const base2 = this.config.baseUrl.replace(/\/$/, "");
3607
- const path = url.startsWith("/") ? url : `/${url}`;
3608
- return base2 + path;
3609
- }
3610
- async runBeforeRequestMiddleware(initialRequest) {
3611
- let request = initialRequest;
3612
- for (const middleware of this.middleware.beforeRequest ?? []) {
3613
- request = await middleware(request);
3614
- }
3615
- return request;
3616
- }
3617
- /**
3618
- * One physical attempt, logged as one line.
3619
- *
3620
- * A non-2xx is a `warn` rather than an `error` because the wire does not
3621
- * know whether it is a failure: the retry middleware may turn a 503 into a
3622
- * success, and the token registry reads a 404 as "not listed". The namespace
3623
- * above decides, and logs the `error` when it does.
3624
- */
3625
- async executeRequest(request) {
3626
- const requestId2 = Attributes.getRequestId(request.attributes);
3627
- const log = requestId2 === null ? this.log : this.log.child({ requestId: requestId2 });
3628
- const attempt = Attributes.getRetryAttempt(request.attributes) + 1;
3629
- const startedAt = Date.now();
3630
- log.debug(() => ({
3631
- msg: "request sent",
3632
- fields: describeRequestUnredacted(request)
3633
- }));
3634
- try {
3635
- const response = await makeRequest(request);
3636
- const elapsed = Date.now() - startedAt;
3637
- const outcome = () => ({
3638
- msg: "request completed",
3639
- fields: {
3640
- ...identifyRequest(request),
3641
- "http.response.status_code": response.status,
3642
- duration_ms: elapsed,
3643
- attempt
3644
- }
3645
- });
3646
- if (response.status >= 200 && response.status < 300) {
3647
- log.info(outcome);
3648
- } else {
3649
- log.warn(outcome);
3650
- }
3651
- log.debug(() => ({
3652
- msg: "response received",
3653
- fields: { body: response.body }
3654
- }));
3655
- return requestId2 === null ? response : { ...response, requestId: requestId2 };
3656
- } catch (error) {
3657
- const elapsed = Date.now() - startedAt;
3658
- log.warning(
3659
- () => ({
3660
- msg: "request threw",
3661
- fields: {
3662
- ...identifyRequest(request),
3663
- duration_ms: elapsed,
3664
- attempt
3665
- }
3666
- }),
3667
- error
3668
- );
3669
- throw error;
3670
- }
3671
- }
3672
- };
3673
- function identifyRequest(request) {
3674
- const { host, path } = splitUrl(request.url);
3675
- return {
3676
- "http.request.method": request.method,
3677
- "server.address": host,
3678
- "url.path": path
3679
- };
3680
- }
3681
- function splitUrl(url) {
3682
- try {
3683
- const parsed = new URL(url);
3684
- return { host: parsed.host, path: parsed.pathname };
3685
- } catch (_) {
3686
- return { host: null, path: url };
3687
- }
3688
- }
3689
- function defaultMakeRequestId() {
3690
- return Math.random().toString(36).slice(2, 10).padEnd(8, "0");
3691
- }
3692
- function describeRequestUnredacted(request) {
3693
- return {
3694
- "http.request.method": request.method,
3695
- "url.full": buildUrlWithQueryParams(request.url, request.queryParams),
3696
- headers: request.headers,
3697
- ...request.method === "POST" ? { body: request.body } : {}
3698
- };
3699
- }
3700
-
3701
- // src/universal/api/nabu/tokens.ts
3702
- function createNabuApiClient(baseUrl, logger = null) {
3703
- return new HttpClient({ baseUrl }, {}, logger);
3704
- }
3705
3547
  async function fetchTokenMetadata(client, token) {
3706
3548
  const address = checksummed(token.address);
3707
3549
  let response;
@@ -3789,97 +3631,64 @@ function checksummed(address) {
3789
3631
  }
3790
3632
  }
3791
3633
 
3792
- // src/universal/core/tokens/tokens-namespace.ts
3634
+ // src/universal/core/shared/blockchain/tokens/tokens-namespace.ts
3793
3635
  var TokensNamespaceImpl = class {
3794
- /**
3795
- * Takes the registry origin rather than a `UniversalNamespaceContext`: the
3796
- * registry is unauthenticated and on its own host, so the frontline sender
3797
- * and the auth check would both be dead weight here.
3798
- */
3799
- constructor(baseUrl, logger = null) {
3800
- this.api = createNabuApiClient(baseUrl, logger);
3801
- this.log = internalLogger(logger, "TOKENS");
3636
+ constructor(ctx) {
3637
+ this.ctx = ctx;
3638
+ this.log = internalLogger(ctx.logger, "TOKENS");
3802
3639
  }
3803
3640
  get(token) {
3804
3641
  return this.log.wrap(
3805
3642
  "get",
3806
3643
  token,
3807
- () => fetchTokenMetadata(this.api, token)
3644
+ () => fetchTokenMetadata(this.ctx.nabu, token)
3808
3645
  );
3809
3646
  }
3810
3647
  list(chain) {
3811
3648
  return this.log.wrap(
3812
3649
  "list",
3813
3650
  chain,
3814
- () => chain === void 0 ? fetchAllTokensMetadata(this.api) : fetchTokensMetadata(this.api, chain)
3651
+ () => chain === void 0 ? fetchAllTokensMetadata(this.ctx.nabu) : fetchTokensMetadata(this.ctx.nabu, chain)
3815
3652
  );
3816
3653
  }
3817
3654
  };
3818
3655
 
3819
- // src/universal/api/frontline/offers.ts
3820
- async function fetchOffers(api, clientCreds) {
3821
- return fetchAllPages((params) => fetchOffersPage(api, params, clientCreds));
3822
- }
3823
- async function fetchOffersPage(api, params, clientCreds) {
3824
- const queryParams = PaginationParams.toQueryParams(params);
3825
- const pageDto = await api.send({
3826
- method: "GET",
3827
- url: "/v1/offers",
3828
- queryParams,
3829
- attributes: Attributes.concat(
3830
- Attributes.protected(),
3831
- Attributes.clientCredentials(clientCreds)
3832
- )
3833
- });
3834
- return PaginatedResponse.fromDtoPage(pageDto, Offer.listFromDto);
3835
- }
3836
- async function fetchOfferDetails(api, id, clientCreds) {
3837
- const dto = await api.send({
3838
- method: "GET",
3839
- url: `/v1/offers/${id}`,
3840
- attributes: Attributes.concat(
3841
- Attributes.protected(),
3842
- Attributes.clientCredentials(clientCreds)
3843
- )
3844
- });
3845
- return OfferDetail.fromDto(dto);
3846
- }
3847
-
3848
3656
  export {
3849
3657
  sha256,
3850
3658
  arrayBufferToBase64Url,
3851
3659
  generateSecureRandomBase64Url,
3852
3660
  getUUIDv4,
3853
- PUBLIC_API_BASE_URL,
3854
- HEADER_USER_AGENT,
3855
- HEADER_IDEMPOTENCY_KEY,
3856
- API_VERSION,
3857
- COINLIST_BASE_URL,
3858
- OAUTH_PAGE_PATH,
3859
- SUPPORT_NEW_TICKET_URL,
3860
- VERIFY_IDENTITY_PATH,
3861
- VERIFY_IDENTITY_ACCREDITATION_PATH,
3862
- WALLET_PATH,
3863
3661
  SentWith,
3864
3662
  TokenTrigger,
3865
3663
  isRejectedToken,
3866
3664
  Attributes,
3867
3665
  HttpError,
3868
3666
  apiErrorCode,
3869
- Request,
3870
3667
  NotImplementedError,
3871
3668
  NotAuthenticatedError,
3872
3669
  ValidationError,
3873
3670
  InvariantError,
3874
3671
  MathError,
3672
+ classifyLogCause,
3875
3673
  describeErrorUnredacted,
3876
3674
  internalLogger,
3877
- HttpClient,
3878
3675
  EpochMillis,
3879
3676
  Millis,
3880
3677
  Seconds,
3881
3678
  isExpired,
3882
3679
  ERC20_ABI,
3680
+ FormattedAmountUi,
3681
+ FormattedPercentUi,
3682
+ TxExplorerUrl,
3683
+ ShortenedWalletAddress,
3684
+ FormattedAmountAssetUi,
3685
+ AssetIconUrl,
3686
+ viemChain,
3687
+ getChainId,
3688
+ chainFromId,
3689
+ contractOn,
3690
+ getNetworkName,
3691
+ txExplorerUrl,
3883
3692
  ETHEREUM_CHAINS,
3884
3693
  EthereumChain,
3885
3694
  SOLANA_CHAINS,
@@ -3902,22 +3711,20 @@ export {
3902
3711
  KnownAssetSymbol,
3903
3712
  Bps,
3904
3713
  blockchainAmountFromRawOrThrow,
3714
+ positiveAmountFromRawOrThrow,
3715
+ pricePerShare,
3905
3716
  parseBlockchainAmount,
3906
3717
  CentrifugeVaultStatus,
3907
3718
  CentrifugeVaultBuyTransaction,
3908
3719
  CentrifugeVaultClaimTransaction,
3909
- CentrifugeVaultPosition,
3910
- CentrifugeVaultRedeemPosition,
3720
+ CentrifugeAssets,
3721
+ CentrifugeShares,
3722
+ CentrifugeDepositPosition,
3723
+ CentrifugeRedeemPosition,
3911
3724
  CentrifugeVaultLeg,
3912
3725
  CentrifugeVaultLegId,
3913
3726
  CentrifugeVaultClaimProceedsTransaction,
3914
3727
  CentrifugeNamespaceImpl,
3915
- FormattedAmountUi,
3916
- FormattedPercentUi,
3917
- TxExplorerUrl,
3918
- ShortenedWalletAddress,
3919
- FormattedAmountAssetUi,
3920
- AssetIconUrl,
3921
3728
  shortenAddress,
3922
3729
  formatAmount,
3923
3730
  formatRawAmount,
@@ -3928,6 +3735,9 @@ export {
3928
3735
  NA_AMOUNT_ASSET_UI,
3929
3736
  formatShareAmount,
3930
3737
  formattedUsdPrice,
3738
+ Cursor,
3739
+ PaginatedResponse,
3740
+ PaginationParams,
3931
3741
  AssetId,
3932
3742
  AssetCode,
3933
3743
  Asset,
@@ -3944,27 +3754,18 @@ export {
3944
3754
  OfferOptionSlug,
3945
3755
  OfferSwapContract,
3946
3756
  OfferVaultContract,
3757
+ OfferFundingContract,
3947
3758
  OfferDetail,
3948
3759
  OfferOption,
3949
3760
  FaqItem,
3950
3761
  Link,
3951
3762
  TermItem,
3952
3763
  Milestone,
3953
- Cursor,
3954
- PaginatedResponse,
3955
- PaginationParams,
3956
3764
  ParticipationId,
3957
- Blockchain,
3958
- WalletAddress,
3959
3765
  ParticipationsPaginationParams,
3960
3766
  Participation,
3961
3767
  CreateParticipationParams,
3962
3768
  CoinListTokenSaleNamespaceImpl,
3963
- viemChain,
3964
- getChainId,
3965
- chainFromId,
3966
- getNetworkName,
3967
- txExplorerUrl,
3968
3769
  OndoTradingStatus,
3969
3770
  OndoQuote,
3970
3771
  OndoBuyTransaction,
@@ -3997,10 +3798,11 @@ export {
3997
3798
  fetchOffers,
3998
3799
  fetchOffersPage,
3999
3800
  fetchOfferDetails,
3801
+ OffersNamespaceImpl,
4000
3802
  Erc20NamespaceImpl,
4001
3803
  TokenLogoUrl,
4002
3804
  TokenLogo,
4003
3805
  TokenMetadata,
4004
3806
  TokensNamespaceImpl
4005
3807
  };
4006
- //# sourceMappingURL=chunk-GOUUYOPZ.js.map
3808
+ //# sourceMappingURL=chunk-ANPPXFXD.js.map