@coinlist-co/react 0.10.1 → 0.11.1-rc.10770e8

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 (38) hide show
  1. package/README.md +32 -0
  2. package/dist/chunk-7CTH4KPU.js +2399 -0
  3. package/dist/chunk-7CTH4KPU.js.map +1 -0
  4. package/dist/{chunk-AQVCOWOV.js → chunk-LSPZETDH.js} +249 -317
  5. package/dist/chunk-LSPZETDH.js.map +1 -0
  6. package/dist/chunk-UZUQALFY.js +279 -0
  7. package/dist/chunk-UZUQALFY.js.map +1 -0
  8. package/dist/client/index.cjs +13430 -3308
  9. package/dist/client/index.cjs.map +1 -1
  10. package/dist/client/index.d.cts +5486 -899
  11. package/dist/client/index.d.ts +5486 -899
  12. package/dist/client/index.js +11025 -2388
  13. package/dist/client/index.js.map +1 -1
  14. package/dist/collections-BBI_XydI.d.cts +116 -0
  15. package/dist/collections-BrX9rRWc.d.ts +116 -0
  16. package/dist/config-CMl1bR3F.d.cts +2959 -0
  17. package/dist/config-CMl1bR3F.d.ts +2959 -0
  18. package/dist/server/index.cjs +1768 -511
  19. package/dist/server/index.cjs.map +1 -1
  20. package/dist/server/index.d.cts +266 -162
  21. package/dist/server/index.d.ts +266 -162
  22. package/dist/server/index.js +235 -169
  23. package/dist/server/index.js.map +1 -1
  24. package/dist/shared/index.cjs +2423 -926
  25. package/dist/shared/index.cjs.map +1 -1
  26. package/dist/shared/index.d.cts +325 -132
  27. package/dist/shared/index.d.ts +325 -132
  28. package/dist/shared/index.js +112 -28
  29. package/package.json +12 -8
  30. package/dist/chunk-AQVCOWOV.js.map +0 -1
  31. package/dist/chunk-TBU3EBNM.js +0 -442
  32. package/dist/chunk-TBU3EBNM.js.map +0 -1
  33. package/dist/chunk-UOHD7US2.js +0 -855
  34. package/dist/chunk-UOHD7US2.js.map +0 -1
  35. package/dist/collections-Bv1Oxzu_.d.ts +0 -28
  36. package/dist/collections-DDyxbOPZ.d.cts +0 -28
  37. package/dist/requirement-oVZA1INj.d.cts +0 -1040
  38. package/dist/requirement-oVZA1INj.d.ts +0 -1040
@@ -32,20 +32,27 @@ __export(shared_exports, {
32
32
  Blockchain: () => Blockchain,
33
33
  BlockchainAmount: () => BlockchainAmount,
34
34
  Bps: () => Bps,
35
+ Chain: () => Chain,
35
36
  ClientCredentialsOAuth: () => ClientCredentialsOAuth,
36
37
  ClientId: () => ClientId,
37
38
  ClientSecret: () => ClientSecret,
38
39
  CodeChallenge: () => CodeChallenge,
39
40
  CodeVerifier: () => CodeVerifier,
41
+ CoinListTokenSaleNamespaceImpl: () => CoinListTokenSaleNamespaceImpl,
40
42
  ConnectExternalWalletParams: () => ConnectExternalWalletParams,
41
43
  CreateParticipationParams: () => CreateParticipationParams,
42
44
  CreateWalletOwnershipChallengeParams: () => CreateWalletOwnershipChallengeParams,
43
45
  Cursor: () => Cursor,
44
46
  DEFAULT_AMOUNT_TO_COMPUTE_PRICE: () => DEFAULT_AMOUNT_TO_COMPUTE_PRICE,
47
+ DEFAULT_ONDO_AMOUNT_TO_COMPUTE_PRICE: () => DEFAULT_ONDO_AMOUNT_TO_COMPUTE_PRICE,
48
+ DEFAULT_ONDO_SELL_TOKENS_TO_COMPUTE_PRICE: () => DEFAULT_ONDO_SELL_TOKENS_TO_COMPUTE_PRICE,
45
49
  DEFAULT_SLIPPAGE_BPS: () => DEFAULT_SLIPPAGE_BPS,
50
+ DecimalString: () => DecimalString,
46
51
  DocumentSubmission: () => DocumentSubmission,
47
52
  ERC20_ABI: () => ERC20_ABI,
53
+ ETHEREUM_CHAINS: () => ETHEREUM_CHAINS,
48
54
  Erc20NamespaceImpl: () => Erc20NamespaceImpl,
55
+ EthereumChain: () => EthereumChain,
49
56
  EvmContractAddress: () => EvmContractAddress,
50
57
  EvmWalletAddress: () => EvmWalletAddress,
51
58
  FaqItem: () => FaqItem,
@@ -53,17 +60,25 @@ __export(shared_exports, {
53
60
  FormattedAmountUi: () => FormattedAmountUi,
54
61
  FormattedPercentUi: () => FormattedPercentUi,
55
62
  HexEncodedTransactionData: () => HexEncodedTransactionData,
63
+ HttpError: () => HttpError,
64
+ InvariantError: () => InvariantError,
56
65
  Iso2CountryCode: () => Iso2CountryCode,
57
66
  KnownAssetSymbol: () => KnownAssetSymbol,
58
67
  KycToken: () => KycToken,
59
68
  Link: () => Link,
69
+ MAX_ASSET_DECIMALS: () => MAX_ASSET_DECIMALS,
60
70
  MAX_UINT_256: () => MAX_UINT_256,
71
+ MathError: () => MathError,
61
72
  Milestone: () => Milestone,
62
73
  NA_AMOUNT_ASSET_UI: () => NA_AMOUNT_ASSET_UI,
63
74
  NotAuthenticatedError: () => NotAuthenticatedError,
64
75
  NotImplementedError: () => NotImplementedError,
65
76
  OAuthRefreshToken: () => OAuthRefreshToken,
66
77
  OAuthSession: () => OAuthSession,
78
+ ONDO_POLL_INTERVAL_MS: () => ONDO_POLL_INTERVAL_MS,
79
+ ONDO_QUOTE_EXPIRY_THRESHOLD_MS: () => ONDO_QUOTE_EXPIRY_THRESHOLD_MS,
80
+ ONDO_SETTLEMENT_ASSET: () => ONDO_SETTLEMENT_ASSET,
81
+ ONDO_SUPPORTED_INPUT_ASSETS: () => ONDO_SUPPORTED_INPUT_ASSETS,
67
82
  Offer: () => Offer,
68
83
  OfferDetail: () => OfferDetail,
69
84
  OfferId: () => OfferId,
@@ -73,6 +88,13 @@ __export(shared_exports, {
73
88
  OfferOptionId: () => OfferOptionId,
74
89
  OfferOptionSlug: () => OfferOptionSlug,
75
90
  OfferSlug: () => OfferSlug,
91
+ OfferToken: () => OfferToken,
92
+ OffersNamespaceImpl: () => OffersNamespaceImpl,
93
+ OndoBuyTransaction: () => OndoBuyTransaction,
94
+ OndoNamespaceImpl: () => OndoNamespaceImpl,
95
+ OndoQuote: () => OndoQuote,
96
+ OndoSellTransaction: () => OndoSellTransaction,
97
+ OndoTradingStatus: () => OndoTradingStatus,
76
98
  PKCEState: () => PKCEState,
77
99
  PaginatedResponse: () => PaginatedResponse,
78
100
  PaginationParams: () => PaginationParams,
@@ -82,27 +104,37 @@ __export(shared_exports, {
82
104
  Pii: () => Pii,
83
105
  PiiAddress: () => PiiAddress,
84
106
  PiiJurisdiction: () => PiiJurisdiction,
107
+ RedactedWalletError: () => RedactedWalletError,
85
108
  RedirectUri: () => RedirectUri,
86
109
  Requirement: () => Requirement,
87
110
  RequirementId: () => RequirementId,
88
111
  RequirementStatusInfo: () => RequirementStatusInfo,
112
+ RequirementsNamespaceImpl: () => RequirementsNamespaceImpl,
89
113
  SLIPPAGE_OPTIONS_BPS: () => SLIPPAGE_OPTIONS_BPS,
114
+ SOLANA_CHAINS: () => SOLANA_CHAINS,
115
+ STABLE_DECIMALS: () => STABLE_DECIMALS,
116
+ SUPERSTATE_ISSUER_NAME: () => SUPERSTATE_ISSUER_NAME,
117
+ SUPERSTATE_SUPPORTED_INPUT_ASSETS: () => SUPERSTATE_SUPPORTED_INPUT_ASSETS,
90
118
  SUPERSTATE_SWAP_ABI: () => SUPERSTATE_SWAP_ABI,
91
119
  SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA: () => SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA,
92
- SUPERSTATE_TOS_URL: () => SUPERSTATE_TOS_URL,
93
120
  SWAP_POLL_INTERVAL_MS: () => SWAP_POLL_INTERVAL_MS,
94
121
  ShortenedWalletAddress: () => ShortenedWalletAddress,
122
+ SolanaChain: () => SolanaChain,
95
123
  StablecoinSymbol: () => StablecoinSymbol,
124
+ SuperstateSwapNamespaceImpl: () => SuperstateSwapNamespaceImpl,
96
125
  SwapAuthorization: () => SwapAuthorization,
97
- SwapNamespaceImpl: () => SwapNamespaceImpl,
98
126
  SwapPreview: () => SwapPreview,
99
127
  SwapQuote: () => SwapQuote,
100
128
  SwapStatus: () => SwapStatus,
101
129
  TOKEN_REGISTRY: () => TOKEN_REGISTRY,
102
130
  TermItem: () => TermItem,
131
+ Ticker: () => Ticker,
103
132
  TokenAllowance: () => TokenAllowance,
104
133
  TokenBalance: () => TokenBalance,
105
- TokenSaleNamespaceImpl: () => TokenSaleNamespaceImpl,
134
+ TokenLogo: () => TokenLogo,
135
+ TokenLogoUrl: () => TokenLogoUrl,
136
+ TokenMetadata: () => TokenMetadata,
137
+ TokensNamespaceImpl: () => TokensNamespaceImpl,
106
138
  TxExplorerUrl: () => TxExplorerUrl,
107
139
  USDC: () => USDC,
108
140
  USDC_SYMBOL: () => USDC_SYMBOL,
@@ -111,11 +143,18 @@ __export(shared_exports, {
111
143
  User: () => User,
112
144
  UserEmail: () => UserEmail,
113
145
  UserId: () => UserId,
146
+ ValidationError: () => ValidationError,
114
147
  WalletAddress: () => WalletAddress,
115
148
  WalletOwnershipChallenge: () => WalletOwnershipChallenge,
149
+ WalletsNamespaceImpl: () => WalletsNamespaceImpl,
150
+ apiErrorCode: () => apiErrorCode,
116
151
  applyBps: () => applyBps,
117
152
  assertUint256: () => assertUint256,
118
153
  assetAmount: () => assetAmount,
154
+ blockchainAmountFromRawOrThrow: () => blockchainAmountFromRawOrThrow,
155
+ chainFromId: () => chainFromId,
156
+ computeOndoBuyPrice: () => computeOndoBuyPrice,
157
+ computeOndoSellPrice: () => computeOndoSellPrice,
119
158
  computePrice: () => computePrice,
120
159
  computeSlip: () => computeSlip,
121
160
  decodeSwappedOutputAmount: () => decodeSwappedOutputAmount,
@@ -130,15 +169,182 @@ __export(shared_exports, {
130
169
  getChainId: () => getChainId,
131
170
  getNetworkName: () => getNetworkName,
132
171
  isStopped: () => isStopped,
172
+ ondoSwapContractAddress: () => ondoSwapContractAddress,
133
173
  parseBlockchainAmount: () => parseBlockchainAmount,
174
+ parseUint256: () => parseUint256,
134
175
  shortenAddress: () => shortenAddress,
176
+ superstateSwapContractAddress: () => superstateSwapContractAddress,
135
177
  txExplorerUrl: () => txExplorerUrl,
136
178
  usdAmount: () => usdAmount
137
179
  });
138
180
  module.exports = __toCommonJS(shared_exports);
139
181
 
182
+ // src/shared/api/http-attributes.ts
183
+ var empty = {};
184
+ var concat = (left, right) => ({
185
+ ...left,
186
+ ...right
187
+ });
188
+ var concatAll = (...items) => {
189
+ let result = empty;
190
+ for (const item of items) {
191
+ result = concat(result, item);
192
+ }
193
+ return result;
194
+ };
195
+ var protectedRequest = () => ({ protected: true });
196
+ var userAgent = () => ({ userAgent: true });
197
+ var idempotencyKey = () => ({
198
+ idempotencyKey: true
199
+ });
200
+ var clientCredentials = (credentials) => ({
201
+ clientCredentials: credentials
202
+ });
203
+ var retryAttempt = (attempt) => ({
204
+ retryAttempt: attempt
205
+ });
206
+ var renewAttempted = (value) => ({
207
+ renewAttempted: value
208
+ });
209
+ var requestId = (id) => ({ requestId: id });
210
+ var getRequestId = (attrs) => attrs?.requestId ?? null;
211
+ var isProtected = (attrs) => attrs?.protected === true;
212
+ var needUserAgent = (attrs) => attrs?.userAgent === true;
213
+ var isIdempotent = (attrs) => attrs?.idempotencyKey === true;
214
+ var getRetryAttempt = (attrs) => attrs?.retryAttempt ?? 0;
215
+ var wasRenewAttempted = (attrs) => attrs?.renewAttempted === true;
216
+ var getClientCredentials = (attrs) => attrs?.clientCredentials;
217
+ var Attributes = {
218
+ empty,
219
+ concat,
220
+ concatAll,
221
+ protected: protectedRequest,
222
+ isProtected,
223
+ userAgent,
224
+ needUserAgent,
225
+ idempotencyKey,
226
+ isIdempotent,
227
+ retryAttempt,
228
+ getRetryAttempt,
229
+ renewAttempted,
230
+ wasRenewAttempted,
231
+ clientCredentials,
232
+ getClientCredentials,
233
+ requestId,
234
+ getRequestId
235
+ };
236
+
237
+ // src/shared/api/http.ts
238
+ var HttpError = class extends Error {
239
+ constructor(response) {
240
+ super(`Request failed with ${response.status} status`);
241
+ this.name = "HttpError";
242
+ this.response = response;
243
+ }
244
+ /**
245
+ * Correlates this failure with the `[HTTP]` log lines for the same request,
246
+ * which carry the method, the URL, the duration and every retry. `null` when
247
+ * the response did not come from an {@link HttpClient}.
248
+ *
249
+ * Worth quoting in a bug report: it is what makes a log excerpt readable.
250
+ */
251
+ get requestId() {
252
+ return this.response.requestId ?? null;
253
+ }
254
+ };
255
+ function apiErrorCode(error) {
256
+ if (!(error instanceof HttpError)) return null;
257
+ const body = error.response.body;
258
+ if (typeof body !== "object" || body === null) return null;
259
+ const code = body.code;
260
+ return typeof code === "string" ? code : null;
261
+ }
262
+ async function makeRequest(request) {
263
+ const headers = {
264
+ Accept: "application/json",
265
+ ...request.method === "POST" && request.body !== void 0 ? { "Content-Type": "application/json" } : {},
266
+ ...request.headers ?? {}
267
+ };
268
+ const init = {
269
+ method: request.method,
270
+ headers,
271
+ ...request.redirect !== void 0 ? { redirect: request.redirect } : {}
272
+ };
273
+ if (request.method === "POST" && request.body !== void 0) {
274
+ init.body = JSON.stringify(request.body);
275
+ }
276
+ const response = await fetch(
277
+ buildUrlWithQueryParams(request.url, request.queryParams),
278
+ init
279
+ );
280
+ const responseHeaders = headersToRecord(response.headers);
281
+ if (response.status === 204 || response.status === 205) {
282
+ return {
283
+ status: response.status,
284
+ body: null,
285
+ headers: responseHeaders
286
+ };
287
+ }
288
+ if (response.status >= 300 && response.status < 400) {
289
+ await response.text();
290
+ return {
291
+ status: response.status,
292
+ body: null,
293
+ headers: responseHeaders
294
+ };
295
+ }
296
+ const text = await response.text();
297
+ let body;
298
+ try {
299
+ body = text ? JSON.parse(text) : null;
300
+ } catch (_) {
301
+ throw new HttpError({
302
+ status: response.status,
303
+ headers: responseHeaders,
304
+ body: text
305
+ });
306
+ }
307
+ return {
308
+ status: response.status,
309
+ body,
310
+ headers: responseHeaders
311
+ };
312
+ }
313
+ function buildUrlWithQueryParams(url, queryParams) {
314
+ if (!queryParams) {
315
+ return url;
316
+ }
317
+ const searchParams = new URLSearchParams();
318
+ for (const [key, value] of Object.entries(queryParams)) {
319
+ if (value === void 0 || value === null) {
320
+ continue;
321
+ }
322
+ if (Array.isArray(value)) {
323
+ for (const item of value) {
324
+ if (item === void 0 || item === null) {
325
+ continue;
326
+ }
327
+ searchParams.append(key, String(item));
328
+ }
329
+ continue;
330
+ }
331
+ searchParams.append(key, String(value));
332
+ }
333
+ const queryString = searchParams.toString();
334
+ if (!queryString) {
335
+ return url;
336
+ }
337
+ return url.includes("?") ? `${url}&${queryString}` : `${url}?${queryString}`;
338
+ }
339
+ function headersToRecord(headers) {
340
+ const record = {};
341
+ headers.forEach((value, key) => {
342
+ record[key.toLowerCase()] = value;
343
+ });
344
+ return record;
345
+ }
346
+
140
347
  // src/shared/api/pagination.ts
141
- var Cursor = (value) => value;
142
348
  async function fetchAllPages(fetchPage, baseParams) {
143
349
  const items = [];
144
350
  let cursor = null;
@@ -153,79 +359,315 @@ async function fetchAllPages(fetchPage, baseParams) {
153
359
  } while (cursor);
154
360
  return items;
155
361
  }
156
- var PaginatedResponse = {
157
- fromDto: (dto, itemMapper) => ({
158
- data: dto.data.map(itemMapper),
159
- startingAfter: dto.starting_after ? Cursor(dto.starting_after) : null,
160
- startingBefore: dto.starting_before ? Cursor(dto.starting_before) : null
161
- })
362
+
363
+ // src/shared/core/utils/crypto.ts
364
+ async function sha256(data) {
365
+ const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
366
+ const buffer = bytes.buffer.slice(
367
+ bytes.byteOffset,
368
+ bytes.byteOffset + bytes.byteLength
369
+ );
370
+ return crypto.subtle.digest("SHA-256", buffer);
371
+ }
372
+ function arrayBufferToBase64Url(buffer, padding = true) {
373
+ const bytes = new Uint8Array(buffer);
374
+ let binary = "";
375
+ for (let i = 0; i < bytes.length; i++) {
376
+ binary += String.fromCharCode(bytes[i]);
377
+ }
378
+ let base64 = btoa(binary);
379
+ base64 = base64.replace(/\+/g, "-").replace(/\//g, "_");
380
+ if (!padding) {
381
+ base64 = base64.replace(/=+$/, "");
382
+ }
383
+ return base64;
384
+ }
385
+ function generateSecureRandomBase64Url(byteLength) {
386
+ const bytes = new Uint8Array(byteLength);
387
+ crypto.getRandomValues(bytes);
388
+ const buffer = bytes.buffer;
389
+ return arrayBufferToBase64Url(buffer, false);
390
+ }
391
+ function notBlankStringOrNull(value) {
392
+ if (value?.trim()) {
393
+ return value;
394
+ } else {
395
+ return null;
396
+ }
397
+ }
398
+
399
+ // src/shared/types/oauth.ts
400
+ var AuthorizationCode = (value) => value;
401
+ var CodeVerifier = (value) => value;
402
+ var CodeChallenge = (value) => value;
403
+ var PKCEState = (value) => value;
404
+ var RedirectUri = (value) => value;
405
+ var ClientId = (value) => value;
406
+ var ClientSecret = (value) => value;
407
+
408
+ // src/shared/core/auth/pkce.ts
409
+ async function generatePKCEParams(config) {
410
+ const state = generateSecureRandomBase64Url(32);
411
+ const codeVerifier = generateSecureRandomBase64Url(32);
412
+ const codeChallengeRaw = await sha256(codeVerifier);
413
+ const codeChallenge = arrayBufferToBase64Url(codeChallengeRaw, false);
414
+ return {
415
+ clientId: config.clientId,
416
+ responseType: "code",
417
+ redirectUri: config.redirectUri,
418
+ codeChallenge: CodeChallenge(codeChallenge),
419
+ codeChallengeMethod: "S256",
420
+ state: PKCEState(state),
421
+ codeVerifier: CodeVerifier(codeVerifier)
422
+ };
423
+ }
424
+
425
+ // src/shared/types/errors.ts
426
+ var NotImplementedError = class extends Error {
427
+ constructor(message = "Not implemented yet") {
428
+ super(message);
429
+ this.name = "NotImplementedError";
430
+ }
162
431
  };
163
- var PaginationParams = {
164
- toQueryParams: (params) => {
165
- const queryParams = {};
166
- if (params.after) {
167
- queryParams.starting_after = params.after;
168
- }
169
- if (params.before) {
170
- queryParams.starting_before = params.before;
171
- }
172
- if (params.limit) {
173
- queryParams.limit = params.limit;
174
- }
175
- return queryParams;
432
+ var NotAuthenticatedError = class extends Error {
433
+ constructor(message = "The user is not authenticated. Go through the OAuth flow first!") {
434
+ super(message);
435
+ this.name = "NotAuthenticatedError";
436
+ }
437
+ };
438
+ var ValidationError = class extends Error {
439
+ constructor(message) {
440
+ super(message);
441
+ this.name = "ValidationError";
442
+ }
443
+ };
444
+ var InvariantError = class extends Error {
445
+ constructor(message) {
446
+ super(message);
447
+ this.name = "InvariantError";
448
+ }
449
+ };
450
+ var MathError = class extends Error {
451
+ constructor(message) {
452
+ super(message);
453
+ this.name = "MathError";
176
454
  }
177
455
  };
178
456
 
179
- // src/shared/core/blockchain/abis/erc20.ts
180
- var ERC20_ABI = [
181
- {
182
- type: "function",
183
- name: "allowance",
184
- inputs: [
185
- { name: "owner", type: "address" },
186
- { name: "spender", type: "address" }
187
- ],
188
- outputs: [{ name: "", type: "uint256" }],
189
- stateMutability: "view"
190
- },
191
- {
192
- type: "function",
193
- name: "approve",
194
- inputs: [
195
- { name: "spender", type: "address" },
196
- { name: "amount", type: "uint256" }
197
- ],
198
- outputs: [{ name: "", type: "bool" }],
199
- stateMutability: "nonpayable"
200
- },
201
- {
202
- type: "function",
203
- name: "balanceOf",
204
- inputs: [{ name: "account", type: "address" }],
205
- outputs: [{ name: "", type: "uint256" }],
206
- stateMutability: "view"
207
- },
208
- {
209
- type: "function",
210
- name: "decimals",
211
- inputs: [],
212
- outputs: [{ name: "", type: "uint8" }],
213
- stateMutability: "view"
214
- },
215
- {
216
- type: "function",
217
- name: "name",
218
- inputs: [],
219
- outputs: [{ name: "", type: "string" }],
220
- stateMutability: "view"
221
- },
457
+ // src/shared/types/blockchain/core.ts
458
+ var ETHEREUM_CHAINS = {
459
+ ethereum_mainnet: true,
460
+ ethereum_sepolia: true,
461
+ base_mainnet: true,
462
+ base_sepolia: true
463
+ };
464
+ var EthereumChain = (value) => {
465
+ if (!Object.keys(ETHEREUM_CHAINS).includes(value)) {
466
+ throw new ValidationError(`Unsupported Ethereum chain: "${value}"`);
467
+ }
468
+ return value;
469
+ };
470
+ var SOLANA_CHAINS = {
471
+ solana_mainnet: true,
472
+ solana_devnet: true
473
+ };
474
+ var SolanaChain = (value) => {
475
+ if (!Object.keys(SOLANA_CHAINS).includes(value)) {
476
+ throw new ValidationError(`Unsupported Solana chain: "${value}"`);
477
+ }
478
+ return value;
479
+ };
480
+ var Chain = (value) => {
481
+ if (!Object.keys(ETHEREUM_CHAINS).includes(value) && !Object.keys(SOLANA_CHAINS).includes(value)) {
482
+ throw new ValidationError(`Unsupported chain: "${value}"`);
483
+ }
484
+ return value;
485
+ };
486
+ var EvmWalletAddress = (value) => value;
487
+ var EvmContractAddress = (value) => value;
488
+ var HexEncodedTransactionData = (value) => value;
489
+ var MAX_ASSET_DECIMALS = 77;
490
+ var AssetDecimals = (value) => {
491
+ if (!Number.isInteger(value)) {
492
+ throw new ValidationError(`Asset decimals must be an integer: ${value}`);
493
+ }
494
+ if (value < 0 || value > MAX_ASSET_DECIMALS) {
495
+ throw new ValidationError(
496
+ `Asset decimals out of range [0, ${MAX_ASSET_DECIMALS}]: ${value}`
497
+ );
498
+ }
499
+ return value;
500
+ };
501
+ var STABLE_DECIMALS = AssetDecimals(6);
502
+ var DecimalString = (value) => value;
503
+ var MAX_UINT_256 = 2n ** 256n - 1n;
504
+ var assertUint256 = (value) => {
505
+ if (isUint256(value)) return value;
506
+ throw new InvariantError(`Value out of uint256 bounds: ${value}`);
507
+ };
508
+ var parseUint256 = (value, label) => {
509
+ if (isUint256(value)) return value;
510
+ throw new ValidationError(`${label}: out of uint256 bounds (${value})`);
511
+ };
512
+ var isUint256 = (value) => value >= 0n && value <= MAX_UINT_256;
513
+ var BlockchainAmount = Object.assign(
514
+ (value) => value,
222
515
  {
223
- type: "function",
224
- name: "symbol",
225
- inputs: [],
226
- outputs: [{ name: "", type: "string" }],
227
- stateMutability: "view"
228
- },
516
+ add: (a, b) => combineAmounts(a, b, (x, y) => x + y),
517
+ sub: (a, b) => combineAmounts(a, b, (x, y) => x - y),
518
+ mul: multiplyAmounts,
519
+ div: divideAmounts
520
+ }
521
+ );
522
+ function multiplyAmounts(a, b) {
523
+ const product = a.raw * b.raw;
524
+ return BlockchainAmount({
525
+ raw: product / 10n ** BigInt(b.decimals),
526
+ decimals: a.decimals
527
+ });
528
+ }
529
+ function divideAmounts(a, b) {
530
+ if (b.raw === 0n) {
531
+ throw new MathError("Cannot divide a BlockchainAmount by zero");
532
+ }
533
+ const scaled = a.raw * 10n ** BigInt(b.decimals);
534
+ return BlockchainAmount({ raw: scaled / b.raw, decimals: a.decimals });
535
+ }
536
+ function combineAmounts(a, b, op) {
537
+ if (a.decimals !== b.decimals) {
538
+ throw new InvariantError(
539
+ `Cannot combine BlockchainAmounts with different decimals: ${a.decimals} vs ${b.decimals}`
540
+ );
541
+ }
542
+ const raw = op(a.raw, b.raw);
543
+ if (raw < 0n || raw > MAX_UINT_256) {
544
+ throw new InvariantError(`BlockchainAmount out of uint256 bounds: ${raw}`);
545
+ }
546
+ return BlockchainAmount({ raw, decimals: a.decimals });
547
+ }
548
+ var AssetSymbol = (value) => value;
549
+ var StablecoinSymbol = (value) => value;
550
+ var KnownAssetSymbol = StablecoinSymbol;
551
+ var Bps = (value) => value;
552
+
553
+ // src/shared/core/blockchain/bps.ts
554
+ var BPS_DENOM = Bps(10000n);
555
+ function applyBps(amount, bps) {
556
+ return assertUint256(amount * bps / BPS_DENOM);
557
+ }
558
+
559
+ // src/shared/types/blockchain/ui.ts
560
+ var FormattedAmountUi = (value) => value;
561
+ var FormattedPercentUi = (value) => value;
562
+ var TxExplorerUrl = (value) => value;
563
+ var ShortenedWalletAddress = (value) => value;
564
+ var FormattedAmountAssetUi = (value) => value;
565
+ var AssetIconUrl = (value) => value;
566
+
567
+ // src/shared/core/blockchain/chain.ts
568
+ var CHAIN_IDS = {
569
+ ethereum_mainnet: 1,
570
+ ethereum_sepolia: 11155111,
571
+ base_mainnet: 8453,
572
+ base_sepolia: 84532
573
+ };
574
+ function getChainId(chain) {
575
+ return CHAIN_IDS[chain];
576
+ }
577
+ function chainFromId(chainId) {
578
+ const chains = Object.keys(CHAIN_IDS);
579
+ const chain = chains.find((c) => String(CHAIN_IDS[c]) === chainId);
580
+ if (!chain) {
581
+ throw new ValidationError(`Unsupported EIP-155 chain id: "${chainId}"`);
582
+ }
583
+ return chain;
584
+ }
585
+ function getNetworkName(chain) {
586
+ switch (chain) {
587
+ case "ethereum_mainnet":
588
+ return "Ethereum";
589
+ case "ethereum_sepolia":
590
+ return "Ethereum Sepolia";
591
+ case "base_mainnet":
592
+ return "Base";
593
+ case "base_sepolia":
594
+ return "Base Sepolia";
595
+ default: {
596
+ const _exhaustive = chain;
597
+ return _exhaustive;
598
+ }
599
+ }
600
+ }
601
+ function txExplorerUrl(chain, txHash) {
602
+ return TxExplorerUrl(`${explorerBaseUrl(chain)}/tx/${txHash}`);
603
+ }
604
+ function explorerBaseUrl(chain) {
605
+ switch (chain) {
606
+ case "ethereum_mainnet":
607
+ return "https://etherscan.io";
608
+ case "ethereum_sepolia":
609
+ return "https://sepolia.etherscan.io";
610
+ case "base_mainnet":
611
+ return "https://basescan.org";
612
+ case "base_sepolia":
613
+ return "https://sepolia-explorer.base.org";
614
+ default: {
615
+ const _exhaustive = chain;
616
+ return _exhaustive;
617
+ }
618
+ }
619
+ }
620
+
621
+ // src/shared/core/blockchain/erc20/abi.ts
622
+ var ERC20_ABI = [
623
+ {
624
+ type: "function",
625
+ name: "allowance",
626
+ inputs: [
627
+ { name: "owner", type: "address" },
628
+ { name: "spender", type: "address" }
629
+ ],
630
+ outputs: [{ name: "", type: "uint256" }],
631
+ stateMutability: "view"
632
+ },
633
+ {
634
+ type: "function",
635
+ name: "approve",
636
+ inputs: [
637
+ { name: "spender", type: "address" },
638
+ { name: "amount", type: "uint256" }
639
+ ],
640
+ outputs: [{ name: "", type: "bool" }],
641
+ stateMutability: "nonpayable"
642
+ },
643
+ {
644
+ type: "function",
645
+ name: "balanceOf",
646
+ inputs: [{ name: "account", type: "address" }],
647
+ outputs: [{ name: "", type: "uint256" }],
648
+ stateMutability: "view"
649
+ },
650
+ {
651
+ type: "function",
652
+ name: "decimals",
653
+ inputs: [],
654
+ outputs: [{ name: "", type: "uint8" }],
655
+ stateMutability: "view"
656
+ },
657
+ {
658
+ type: "function",
659
+ name: "name",
660
+ inputs: [],
661
+ outputs: [{ name: "", type: "string" }],
662
+ stateMutability: "view"
663
+ },
664
+ {
665
+ type: "function",
666
+ name: "symbol",
667
+ inputs: [],
668
+ outputs: [{ name: "", type: "string" }],
669
+ stateMutability: "view"
670
+ },
229
671
  {
230
672
  type: "function",
231
673
  name: "totalSupply",
@@ -274,9 +716,1185 @@ var ERC20_ABI = [
274
716
  ],
275
717
  anonymous: false
276
718
  }
277
- ];
719
+ ];
720
+
721
+ // src/shared/types/providers/superstate/swap.ts
722
+ var SwapAuthorization = {
723
+ fromDto: (dto) => ({
724
+ authorized: dto.authorized
725
+ })
726
+ };
727
+ var SwapPreview = {
728
+ fromDto: (dto) => ({
729
+ inputAmount: parseUint256(
730
+ BigInt(dto.pay_input_amount),
731
+ "SwapPreview.pay_input_amount"
732
+ ),
733
+ fee: parseUint256(BigInt(dto.fee), "SwapPreview.fee"),
734
+ outputAmount: parseUint256(
735
+ BigInt(dto.receive_output_amount),
736
+ "SwapPreview.receive_output_amount"
737
+ )
738
+ })
739
+ };
740
+ var SwapStatus = {
741
+ fromDto: (dto) => ({
742
+ stopped: parseUint256(BigInt(dto.stopped), "SwapStatus.stopped"),
743
+ swapLevel: parseUint256(BigInt(dto.swap_level), "SwapStatus.swap_level")
744
+ })
745
+ };
746
+ var TokenAllowance = {
747
+ fromDto: (dto) => ({
748
+ allowance: parseUint256(BigInt(dto.allowance), "TokenAllowance.allowance")
749
+ })
750
+ };
751
+ var TokenBalance = {
752
+ fromDto: (dto) => ({
753
+ balance: parseUint256(BigInt(dto.balance), "TokenBalance.balance")
754
+ })
755
+ };
756
+ var AllowWalletResponse = {
757
+ fromDto: (dto) => {
758
+ switch (dto.action) {
759
+ case "broadcast_transaction":
760
+ return {
761
+ action: "broadcast_transaction",
762
+ to: EvmContractAddress(dto.to),
763
+ data: HexEncodedTransactionData(dto.data)
764
+ };
765
+ case "none":
766
+ return {
767
+ action: "none",
768
+ alreadyAllowed: dto.already_allowed
769
+ };
770
+ default: {
771
+ const _exhaustive = dto;
772
+ return _exhaustive;
773
+ }
774
+ }
775
+ }
776
+ };
777
+
778
+ // src/shared/api/frontline/providers/superstate/swap.ts
779
+ async function getSwapAuthorization(api, params) {
780
+ const dto = await api.send({
781
+ method: "GET",
782
+ url: "/v1/wallet/authorized",
783
+ queryParams: {
784
+ chain: params.chain,
785
+ contract_address: params.contractAddress,
786
+ wallet_address: params.walletAddress
787
+ },
788
+ attributes: Attributes.protected()
789
+ });
790
+ return SwapAuthorization.fromDto(dto);
791
+ }
792
+ async function getSwapOutputToken(api, params) {
793
+ const dto = await api.send({
794
+ method: "GET",
795
+ url: "/v1/swap/output-token",
796
+ queryParams: {
797
+ chain: params.chain,
798
+ contract_address: params.contractAddress
799
+ },
800
+ attributes: Attributes.protected()
801
+ });
802
+ return toErc20Asset(dto);
803
+ }
804
+ async function getSwapPreview(api, params) {
805
+ const dto = await api.send({
806
+ method: "GET",
807
+ url: "/v1/swap/preview",
808
+ queryParams: {
809
+ chain: params.chain,
810
+ contract_address: params.contractAddress,
811
+ input_token: params.inputToken,
812
+ amount: params.amount.toString()
813
+ },
814
+ attributes: Attributes.protected()
815
+ });
816
+ return SwapPreview.fromDto(dto);
817
+ }
818
+ async function getSwapStatus(api, params) {
819
+ const dto = await api.send({
820
+ method: "GET",
821
+ url: "/v1/swap/status",
822
+ queryParams: {
823
+ chain: params.chain,
824
+ contract_address: params.contractAddress
825
+ },
826
+ attributes: Attributes.protected()
827
+ });
828
+ return SwapStatus.fromDto(dto);
829
+ }
830
+ async function getTokenAllowance(api, params) {
831
+ const dto = await api.send({
832
+ method: "GET",
833
+ url: "/v1/token/allowance",
834
+ queryParams: {
835
+ chain: params.chain,
836
+ token_address: params.tokenAddress,
837
+ owner: params.owner,
838
+ spender: params.spender
839
+ },
840
+ attributes: Attributes.protected()
841
+ });
842
+ return TokenAllowance.fromDto(dto);
843
+ }
844
+ async function getTokenBalance(api, params) {
845
+ const dto = await api.send({
846
+ method: "GET",
847
+ url: "/v1/token/balance",
848
+ queryParams: {
849
+ chain: params.chain,
850
+ token_address: params.tokenAddress,
851
+ owner: params.owner
852
+ },
853
+ attributes: Attributes.protected()
854
+ });
855
+ return TokenBalance.fromDto(dto);
856
+ }
857
+ async function allowWallet(api, params) {
858
+ const dto = await api.send({
859
+ method: "POST",
860
+ url: `/v1/offers/${encodeURIComponent(params.offerId)}/allow-wallet`,
861
+ body: {
862
+ wallet_address: params.walletAddress,
863
+ chain: params.chain,
864
+ signature: params.signature
865
+ },
866
+ attributes: Attributes.protected()
867
+ });
868
+ return AllowWalletResponse.fromDto(dto);
869
+ }
870
+ function toErc20Asset(dto) {
871
+ return {
872
+ name: dto.name,
873
+ symbol: AssetSymbol(dto.symbol),
874
+ decimals: AssetDecimals(dto.decimals)
875
+ };
876
+ }
877
+
878
+ // src/shared/core/observability/log-cause.ts
879
+ function classifyLogCause(error) {
880
+ if (error instanceof HttpError) {
881
+ return httpCause(error);
882
+ }
883
+ if (error instanceof ValidationError) {
884
+ return { type: "validation", message: error.message };
885
+ }
886
+ if (error instanceof InvariantError) {
887
+ return { type: "invariant", message: error.message };
888
+ }
889
+ if (error instanceof MathError) {
890
+ return { type: "math", message: error.message };
891
+ }
892
+ if (error instanceof NotAuthenticatedError) {
893
+ return { type: "not-authenticated" };
894
+ }
895
+ if (error instanceof NotImplementedError) {
896
+ return { type: "not-implemented" };
897
+ }
898
+ return { type: "generic-error", name: errorName(error) };
899
+ }
900
+ function describeErrorUnredacted(error) {
901
+ if (error instanceof HttpError) {
902
+ return describeHttpErrorRedacted(error);
903
+ }
904
+ if (error instanceof Error) {
905
+ return `${error.name}: ${error.message}`;
906
+ }
907
+ return `thrown non-error: ${stringifyUnredacted(error)}`;
908
+ }
909
+ function stringifyUnredacted(value) {
910
+ if (value === void 0) return "";
911
+ try {
912
+ return JSON.stringify(
913
+ value,
914
+ (_key, item) => typeof item === "bigint" ? `${item}` : item
915
+ ) ?? String(value);
916
+ } catch (_) {
917
+ return "<unserializable>";
918
+ }
919
+ }
920
+ function describeHttpErrorRedacted(error) {
921
+ const code = apiErrorCode(error);
922
+ const status = error.response.status;
923
+ return code === null ? `HttpError ${status}` : `HttpError ${status} (${code})`;
924
+ }
925
+ function errorName(error) {
926
+ return error instanceof Error ? error.name : `non-error ${typeof error}`;
927
+ }
928
+ function httpCause(error) {
929
+ return {
930
+ type: "http",
931
+ requestId: error.requestId,
932
+ status: error.response.status,
933
+ code: apiErrorCode(error),
934
+ eventId: apiErrorEventId(error)
935
+ };
936
+ }
937
+ function apiErrorEventId(error) {
938
+ const body = error.response.body;
939
+ if (typeof body !== "object" || body === null) return null;
940
+ const eventId = body.event_id;
941
+ return typeof eventId === "string" ? eventId : null;
942
+ }
943
+
944
+ // src/shared/core/observability/internal-logger.ts
945
+ function internalLogger(logger, scope) {
946
+ return logger ? scopedLogger(logger, scope, {}) : noopInternalLogger;
947
+ }
948
+ var LEVEL_RANK = {
949
+ none: 0,
950
+ error: 1,
951
+ warn: 2,
952
+ info: 3,
953
+ debug: 4
954
+ };
955
+ function scopedLogger(logger, scope, bindings) {
956
+ const admits = (level) => LEVEL_RANK[logger.level()] >= LEVEL_RANK[level];
957
+ const safe = (event) => ({
958
+ msg: event.msg,
959
+ scope,
960
+ bindings,
961
+ fields: event.fields ?? {},
962
+ ...event.cause === void 0 ? {} : { cause: event.cause }
963
+ });
964
+ const unredacted = (event) => ({
965
+ msg: event.msg,
966
+ scope,
967
+ bindings,
968
+ fields: event.fields ?? {}
969
+ });
970
+ const self = {
971
+ child: (binding) => scopedLogger(logger, scope, { ...bindings, ...binding }),
972
+ debug: (event) => {
973
+ if (admits("debug")) logger.debug(() => unredacted(event()));
974
+ },
975
+ info: (event) => {
976
+ if (admits("info")) logger.info(() => safe(event()));
977
+ },
978
+ warn: (event) => {
979
+ if (admits("warn")) logger.warn(() => safe(event()));
980
+ },
981
+ error: (event) => {
982
+ if (admits("error")) logger.error(() => safe(event()));
983
+ },
984
+ failure: (event, error) => {
985
+ if (admits("debug"))
986
+ logger.debug(() => unredacted(verbatim(event(), error)));
987
+ if (admits("error")) logger.error(() => safe(classified(event(), error)));
988
+ },
989
+ warning: (event, error) => {
990
+ if (admits("debug"))
991
+ logger.debug(() => unredacted(verbatim(event(), error)));
992
+ if (admits("warn")) logger.warn(() => safe(classified(event(), error)));
993
+ },
994
+ wrap: async (op, params, run) => {
995
+ const opLog = self.child({ op });
996
+ opLog.debug(() => ({ msg: "call", fields: { params } }));
997
+ try {
998
+ return await run();
999
+ } catch (error) {
1000
+ opLog.failure(() => ({ msg: "call failed" }), error);
1001
+ throw error;
1002
+ }
1003
+ }
1004
+ };
1005
+ return self;
1006
+ }
1007
+ function verbatim(event, error) {
1008
+ return {
1009
+ msg: event.msg,
1010
+ fields: { ...event.fields, error: describeErrorUnredacted(error) }
1011
+ };
1012
+ }
1013
+ function classified(event, error) {
1014
+ return { ...event, cause: event.cause ?? classifyLogCause(error) };
1015
+ }
1016
+ var noopInternalLogger = {
1017
+ child: () => noopInternalLogger,
1018
+ debug: () => void 0,
1019
+ info: () => void 0,
1020
+ warn: () => void 0,
1021
+ error: () => void 0,
1022
+ failure: () => void 0,
1023
+ warning: () => void 0,
1024
+ wrap: (_op, _params, run) => run()
1025
+ };
1026
+
1027
+ // src/shared/core/blockchain/erc20/erc20-namespace.ts
1028
+ var Erc20NamespaceImpl = class {
1029
+ constructor(ctx) {
1030
+ this.ctx = ctx;
1031
+ this.log = internalLogger(ctx.logger, "ERC20");
1032
+ }
1033
+ async getAllowance(params) {
1034
+ return this.log.wrap("getAllowance", params, async () => {
1035
+ await this.ctx.ensureUserAuthenticated();
1036
+ return getTokenAllowance(this.ctx.api, params);
1037
+ });
1038
+ }
1039
+ async getBalance(params) {
1040
+ return this.log.wrap("getBalance", params, async () => {
1041
+ await this.ctx.ensureUserAuthenticated();
1042
+ return getTokenBalance(this.ctx.api, params);
1043
+ });
1044
+ }
1045
+ };
1046
+
1047
+ // src/shared/core/blockchain/formatters.ts
1048
+ var import_viem = require("viem");
1049
+ function shortenAddress(address) {
1050
+ const short = address.length > 10 ? `${address.slice(0, 6)}\u2026${address.slice(-4)}` : address;
1051
+ return ShortenedWalletAddress(short);
1052
+ }
1053
+ function formatAmount(amount, locale, options) {
1054
+ const decimal = formatRawAmount(amount);
1055
+ let [integerPart, fractionPart = ""] = decimal.split(".");
1056
+ const maxFractionDigits = options?.maxFractionDigits;
1057
+ const minFractionDigits = maxFractionDigits !== void 0 ? Math.min(maxFractionDigits, amount.decimals) : Math.min(2, amount.decimals);
1058
+ if (maxFractionDigits !== void 0 && fractionPart.length > maxFractionDigits) {
1059
+ ({ integerPart, fractionPart } = roundFractionHalfUp(
1060
+ integerPart,
1061
+ fractionPart,
1062
+ maxFractionDigits
1063
+ ));
1064
+ }
1065
+ const fraction = minFractionDigits === 0 ? "" : fractionPart.padEnd(minFractionDigits, "0");
1066
+ const integerFormatted = BigInt(integerPart).toLocaleString(locale);
1067
+ if (minFractionDigits === 0 && fraction === "") {
1068
+ return FormattedAmountUi(integerFormatted);
1069
+ }
1070
+ const decimalSeparator = new Intl.NumberFormat(locale).formatToParts(1.1).find((p) => p.type === "decimal")?.value ?? ".";
1071
+ return FormattedAmountUi(`${integerFormatted}${decimalSeparator}${fraction}`);
1072
+ }
1073
+ function roundFractionHalfUp(integerPart, fractionPart, maxFractionDigits) {
1074
+ if (fractionPart.length <= maxFractionDigits) {
1075
+ return { integerPart, fractionPart };
1076
+ }
1077
+ if (maxFractionDigits === 0) {
1078
+ const roundUp = fractionPart[0] >= "5";
1079
+ const integer = BigInt(integerPart) + (roundUp ? 1n : 0n);
1080
+ return { integerPart: integer.toString(), fractionPart: "" };
1081
+ }
1082
+ const trimmed = fractionPart.slice(0, maxFractionDigits);
1083
+ if (fractionPart[maxFractionDigits] < "5") {
1084
+ return { integerPart, fractionPart: trimmed };
1085
+ }
1086
+ const digits = trimmed.split("").map((digit) => Number.parseInt(digit, 10));
1087
+ let carry = 1;
1088
+ for (let i = digits.length - 1; i >= 0 && carry > 0; i -= 1) {
1089
+ const sum = digits[i] + carry;
1090
+ if (sum === 10) {
1091
+ digits[i] = 0;
1092
+ carry = 1;
1093
+ } else {
1094
+ digits[i] = sum;
1095
+ carry = 0;
1096
+ }
1097
+ }
1098
+ return {
1099
+ integerPart: carry > 0 ? (BigInt(integerPart) + 1n).toString() : integerPart,
1100
+ fractionPart: digits.join("")
1101
+ };
1102
+ }
1103
+ function formatRawAmount(amount) {
1104
+ return (0, import_viem.formatUnits)(amount.raw, amount.decimals);
1105
+ }
1106
+ function formatCompactAmount(amount, locale) {
1107
+ const value = Number(formatRawAmount(amount));
1108
+ const formatted = new Intl.NumberFormat(locale, {
1109
+ notation: "compact",
1110
+ maximumFractionDigits: 2
1111
+ }).format(value);
1112
+ return FormattedAmountUi(formatted);
1113
+ }
1114
+ function formatBpsAsPercent(bps, locale) {
1115
+ const whole = bps / 100n;
1116
+ const fraction = bps % 100n;
1117
+ const wholeFormatted = whole.toLocaleString(locale);
1118
+ const decimalSeparator = new Intl.NumberFormat(locale).formatToParts(1.1).find((p) => p.type === "decimal")?.value ?? ".";
1119
+ if (fraction === 0n) {
1120
+ return FormattedPercentUi(`${wholeFormatted}%`);
1121
+ }
1122
+ const fractionFormatted = fraction.toString().padStart(2, "0").replace(/0+$/, "");
1123
+ return FormattedPercentUi(
1124
+ `${wholeFormatted}${decimalSeparator}${fractionFormatted}%`
1125
+ );
1126
+ }
1127
+ function usdAmount(amount) {
1128
+ return FormattedAmountAssetUi(`$${amount}`);
1129
+ }
1130
+ function assetAmount(amount, symbol) {
1131
+ return FormattedAmountAssetUi(`${amount} ${symbol}`);
1132
+ }
1133
+ var NA_AMOUNT_ASSET_UI = FormattedAmountAssetUi("-");
1134
+ var USD_FRACTION_DIGITS = AssetDecimals(2);
1135
+ function formattedUsdPrice(amount, locale) {
1136
+ if (!amount) return NA_AMOUNT_ASSET_UI;
1137
+ return usdAmount(
1138
+ formatAmount(amount, locale, { maxFractionDigits: USD_FRACTION_DIGITS })
1139
+ );
1140
+ }
1141
+
1142
+ // src/shared/core/blockchain/math.ts
1143
+ var import_viem2 = require("viem");
1144
+ function blockchainAmountFromRawOrThrow({
1145
+ label,
1146
+ raw,
1147
+ decimals
1148
+ }) {
1149
+ const trimmed = raw.trim();
1150
+ if (trimmed === "") {
1151
+ throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
1152
+ }
1153
+ let value;
1154
+ try {
1155
+ value = BigInt(trimmed);
1156
+ } catch {
1157
+ throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
1158
+ }
1159
+ try {
1160
+ return BlockchainAmount({ raw: assertUint256(value), decimals });
1161
+ } catch {
1162
+ throw new ValidationError(`${label}: out of uint256 bounds (${value})`);
1163
+ }
1164
+ }
1165
+ function parseBlockchainAmount(amount, decimals) {
1166
+ const trimmed = amount.trim();
1167
+ if (trimmed === "") return { valid: false, reason: { type: "empty" } };
1168
+ if (trimmed.startsWith("-")) {
1169
+ return { valid: false, reason: { type: "negative" } };
1170
+ }
1171
+ if (/[eE]/.test(trimmed)) {
1172
+ return { valid: false, reason: { type: "invalid-format" } };
1173
+ }
1174
+ if (!/^\d+(\.\d+)?$/.test(trimmed)) {
1175
+ return { valid: false, reason: { type: "invalid-format" } };
1176
+ }
1177
+ const [, fraction = ""] = trimmed.split(".");
1178
+ if (fraction.length > decimals) {
1179
+ return {
1180
+ valid: false,
1181
+ reason: { type: "too-many-decimals", maxDecimals: decimals }
1182
+ };
1183
+ }
1184
+ try {
1185
+ const raw = (0, import_viem2.parseUnits)(trimmed, decimals);
1186
+ if (raw > MAX_UINT_256) {
1187
+ return { valid: false, reason: { type: "overflow" } };
1188
+ }
1189
+ return {
1190
+ valid: true,
1191
+ amount: BlockchainAmount({ raw, decimals })
1192
+ };
1193
+ } catch {
1194
+ return { valid: false, reason: { type: "invalid-format" } };
1195
+ }
1196
+ }
1197
+
1198
+ // src/shared/core/blockchain/token-registry.ts
1199
+ var USDC_SYMBOL = StablecoinSymbol("USDC");
1200
+ var USDC = {
1201
+ name: "USD Coin",
1202
+ symbol: USDC_SYMBOL,
1203
+ decimals: AssetDecimals(6)
1204
+ };
1205
+ var USDT_SYMBOL = StablecoinSymbol("USDT");
1206
+ var USDT = {
1207
+ name: "Tether USD",
1208
+ symbol: USDT_SYMBOL,
1209
+ decimals: AssetDecimals(6)
1210
+ };
1211
+ var USDC_ADDRESSES = {
1212
+ ethereum_mainnet: EvmContractAddress(
1213
+ "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
1214
+ ),
1215
+ ethereum_sepolia: EvmContractAddress(
1216
+ "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"
1217
+ ),
1218
+ base_mainnet: EvmContractAddress(
1219
+ "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
1220
+ ),
1221
+ base_sepolia: EvmContractAddress(
1222
+ "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
1223
+ )
1224
+ };
1225
+ var USDT_ADDRESSES = {
1226
+ ethereum_mainnet: EvmContractAddress(
1227
+ "0xdac17f958d2ee523a2206206994597c13d831ec7"
1228
+ ),
1229
+ ethereum_sepolia: EvmContractAddress(
1230
+ "0x7169D38820dfd117C3FA1f22a697dBA58d90BA06"
1231
+ ),
1232
+ base_mainnet: EvmContractAddress(
1233
+ "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2"
1234
+ ),
1235
+ base_sepolia: null
1236
+ };
1237
+ var TOKEN_REGISTRY = {
1238
+ erc20: (symbol) => {
1239
+ switch (symbol) {
1240
+ case "USDC":
1241
+ return USDC;
1242
+ case "USDT":
1243
+ return USDT;
1244
+ default:
1245
+ throw new InvariantError(`Unknown asset symbol: ${symbol}`);
1246
+ }
1247
+ },
1248
+ /**
1249
+ * USDC's contract on `chain`. USDC is deployed on every chain the SDK
1250
+ * models, so the table is total and the answer is never `null`.
1251
+ */
1252
+ usdcAddress: (chain) => USDC_ADDRESSES[chain],
1253
+ /**
1254
+ * USDT's contract on `chain`, or `null` where Tether publishes none —
1255
+ * Base Sepolia today. The honest answer, never a fake address a balance
1256
+ * read would call.
1257
+ */
1258
+ usdtAddress: (chain) => USDT_ADDRESSES[chain]
1259
+ };
1260
+
1261
+ // src/shared/types/pagination.ts
1262
+ var Cursor = (value) => value;
1263
+ var PaginatedResponse = {
1264
+ fromDto: (dto, itemMapper) => ({
1265
+ data: dto.data.map(itemMapper),
1266
+ startingAfter: dto.starting_after ? Cursor(dto.starting_after) : null,
1267
+ startingBefore: dto.starting_before ? Cursor(dto.starting_before) : null
1268
+ })
1269
+ };
1270
+ var PaginationParams = {
1271
+ toQueryParams: (params) => {
1272
+ const queryParams = {};
1273
+ if (params.after) {
1274
+ queryParams.starting_after = params.after;
1275
+ }
1276
+ if (params.before) {
1277
+ queryParams.starting_before = params.before;
1278
+ }
1279
+ if (params.limit) {
1280
+ queryParams.limit = params.limit;
1281
+ }
1282
+ return queryParams;
1283
+ }
1284
+ };
1285
+
1286
+ // src/shared/types/asset.ts
1287
+ var AssetId = (value) => value;
1288
+ var AssetCode = (value) => value;
1289
+ var Asset = {
1290
+ fromDto: (dto) => ({
1291
+ id: AssetId(dto.id),
1292
+ code: AssetCode(dto.code),
1293
+ name: dto.name,
1294
+ fractionalDigits: dto.fractional_digits
1295
+ })
1296
+ };
1297
+
1298
+ // src/shared/types/offer.ts
1299
+ var OfferId = (value) => value;
1300
+ var OfferSlug = (value) => value;
1301
+ var Offer = {
1302
+ fromDto: (dto) => {
1303
+ if (!Array.isArray(dto.tokens)) {
1304
+ throw new ValidationError(
1305
+ `Offer.tokens: expected an array, got ${typeof dto.tokens}`
1306
+ );
1307
+ }
1308
+ return {
1309
+ id: OfferId(dto.id),
1310
+ slug: OfferSlug(dto.slug),
1311
+ type: dto.type,
1312
+ tagline: dto.tagline,
1313
+ bannerUrl: dto.banner_url,
1314
+ logoUrl: dto.logo_url,
1315
+ startsAt: new Date(dto.starts_at),
1316
+ endsAt: dto.ends_at ? new Date(dto.ends_at) : null,
1317
+ tokens: dto.tokens.map(OfferToken.fromDto)
1318
+ };
1319
+ }
1320
+ };
1321
+ var OfferToken = {
1322
+ fromDto: (dto) => ({
1323
+ role: dto.role,
1324
+ chain: Chain(dto.chain),
1325
+ address: EvmContractAddress(dto.address)
1326
+ })
1327
+ };
1328
+
1329
+ // src/shared/types/offer-detail.ts
1330
+ var OfferOptionId = (value) => value;
1331
+ var OfferOptionSlug = (value) => value;
1332
+ var OfferDetail = {
1333
+ fromDto: (dto) => {
1334
+ if (!Array.isArray(dto.funding_assets)) {
1335
+ throw new ValidationError(
1336
+ `OfferDetail.funding_assets: expected an array, got ${typeof dto.funding_assets}`
1337
+ );
1338
+ }
1339
+ if (!Array.isArray(dto.options)) {
1340
+ throw new ValidationError(
1341
+ `OfferDetail.options: expected an array, got ${typeof dto.options}`
1342
+ );
1343
+ }
1344
+ if (!Array.isArray(dto.terms)) {
1345
+ throw new ValidationError(
1346
+ `OfferDetail.terms: expected an array, got ${typeof dto.terms}`
1347
+ );
1348
+ }
1349
+ if (!Array.isArray(dto.links)) {
1350
+ throw new ValidationError(
1351
+ `OfferDetail.links: expected an array, got ${typeof dto.links}`
1352
+ );
1353
+ }
1354
+ if (!Array.isArray(dto.faqs)) {
1355
+ throw new ValidationError(
1356
+ `OfferDetail.faqs: expected an array, got ${typeof dto.faqs}`
1357
+ );
1358
+ }
1359
+ if (!Array.isArray(dto.milestones)) {
1360
+ throw new ValidationError(
1361
+ `OfferDetail.milestones: expected an array, got ${typeof dto.milestones}`
1362
+ );
1363
+ }
1364
+ if (!Array.isArray(dto.tokens)) {
1365
+ throw new ValidationError(
1366
+ `OfferDetail.tokens: expected an array, got ${typeof dto.tokens}`
1367
+ );
1368
+ }
1369
+ return {
1370
+ id: OfferId(dto.id),
1371
+ slug: OfferSlug(dto.slug),
1372
+ type: dto.type,
1373
+ name: dto.name,
1374
+ asset: Asset.fromDto(dto.asset),
1375
+ fundingAssets: dto.funding_assets.map(Asset.fromDto),
1376
+ tokens: dto.tokens.map(OfferToken.fromDto),
1377
+ about: notBlankStringOrNull(dto.about),
1378
+ tagline: dto.tagline,
1379
+ bannerUrl: dto.banner_url,
1380
+ logoUrl: dto.logo_url,
1381
+ category: dto.category,
1382
+ startsAt: new Date(dto.starts_at),
1383
+ endsAt: dto.ends_at ? new Date(dto.ends_at) : null,
1384
+ faqs: dto.faqs.map(FaqItem.fromDto),
1385
+ links: dto.links.map(Link.fromDto),
1386
+ milestones: dto.milestones.map(Milestone.fromDto),
1387
+ options: dto.options.map(OfferOption.fromDto),
1388
+ terms: dto.terms.map(TermItem.fromDto)
1389
+ };
1390
+ }
1391
+ };
1392
+ var OfferOption = {
1393
+ fromDto: (dto) => ({
1394
+ id: OfferOptionId(dto.id),
1395
+ slug: OfferOptionSlug(dto.slug),
1396
+ bidIncrement: dto.bid_increment,
1397
+ floorPriceUsd: dto.floor_price_usd,
1398
+ minimumPurchaseUsd: dto.minimum_purchase_usd,
1399
+ priceUsd: dto.price_usd,
1400
+ saleAgreementUrl: notBlankStringOrNull(dto.sale_agreement_url),
1401
+ totalTokenSupply: dto.total_token_supply
1402
+ })
1403
+ };
1404
+ var FaqItem = {
1405
+ fromDto: (dto) => ({
1406
+ question: notBlankStringOrNull(dto.question),
1407
+ answer: notBlankStringOrNull(dto.answer)
1408
+ })
1409
+ };
1410
+ var Link = {
1411
+ fromDto: (dto) => ({
1412
+ label: notBlankStringOrNull(dto.label),
1413
+ url: notBlankStringOrNull(dto.url)
1414
+ })
1415
+ };
1416
+ var TermItem = {
1417
+ fromDto: (dto) => ({
1418
+ key: notBlankStringOrNull(dto.key),
1419
+ value: notBlankStringOrNull(dto.value)
1420
+ })
1421
+ };
1422
+ var Milestone = {
1423
+ fromDto: (dto) => ({
1424
+ name: notBlankStringOrNull(dto.name),
1425
+ schedule: notBlankStringOrNull(dto.schedule),
1426
+ status: dto.status
1427
+ })
1428
+ };
1429
+
1430
+ // src/shared/types/providers/coin-list/token-sale.ts
1431
+ var ParticipationId = (value) => value;
1432
+ var Blockchain = (value) => value;
1433
+ var WalletAddress = (value) => value;
1434
+ var ParticipationsPaginationParams = {
1435
+ toQueryParams: (params) => {
1436
+ const queryParams = PaginationParams.toQueryParams(params);
1437
+ if (params.offerId) {
1438
+ queryParams["filters[0][field]"] = "offer_id";
1439
+ queryParams["filters[0][op]"] = "==";
1440
+ queryParams["filters[0][value]"] = params.offerId;
1441
+ }
1442
+ return queryParams;
1443
+ }
1444
+ };
1445
+ var Participation = {
1446
+ /** Maps API DTO shape into the SDK participation domain model. */
1447
+ fromDto: (dto) => {
1448
+ const walletAddress = notBlankStringOrNull(dto.wallet_address);
1449
+ return {
1450
+ id: ParticipationId(dto.id),
1451
+ offerId: OfferId(dto.offer_id),
1452
+ offerOptionId: OfferOptionId(dto.offer_option_id),
1453
+ status: dto.status,
1454
+ amount: dto.amount,
1455
+ displayAmount: dto.amount_string,
1456
+ asset: Asset.fromDto(dto.asset),
1457
+ chain: Blockchain(dto.chain),
1458
+ insertedAt: dto.inserted_at ? new Date(dto.inserted_at) : null,
1459
+ updatedAt: dto.updated_at ? new Date(dto.updated_at) : null,
1460
+ walletAddress: walletAddress ? WalletAddress(walletAddress) : null
1461
+ };
1462
+ }
1463
+ };
1464
+ var CreateParticipationParams = {
1465
+ /** Maps participation creation params into API DTO payload. */
1466
+ toDto: (params) => ({
1467
+ offer_id: params.offerId,
1468
+ offer_option_id: params.offerOptionId,
1469
+ chain: params.chain,
1470
+ wallet_address: params.walletAddress,
1471
+ amount: params.amount,
1472
+ asset_id: params.assetId,
1473
+ approval_transaction_hash: params.approvalTransactionHash
1474
+ })
1475
+ };
1476
+
1477
+ // src/shared/api/frontline/providers/coin-list/token-sale.ts
1478
+ async function fetchParticipations(api, offerId) {
1479
+ return fetchAllPages(
1480
+ (params) => fetchParticipationsPage(api, params),
1481
+ { offerId }
1482
+ );
1483
+ }
1484
+ async function fetchParticipationsPage(api, params) {
1485
+ const pageDto = await api.send({
1486
+ method: "GET",
1487
+ url: "/v1/participations",
1488
+ queryParams: ParticipationsPaginationParams.toQueryParams(params),
1489
+ attributes: Attributes.protected()
1490
+ });
1491
+ return PaginatedResponse.fromDto(pageDto, Participation.fromDto);
1492
+ }
1493
+ async function fetchParticipation(api, id) {
1494
+ const dto = await api.send({
1495
+ method: "GET",
1496
+ url: `/v1/participations/${id}`,
1497
+ attributes: Attributes.protected()
1498
+ });
1499
+ return Participation.fromDto(dto);
1500
+ }
1501
+ async function createParticipation(api, params) {
1502
+ const dto = await api.send({
1503
+ method: "POST",
1504
+ url: "/v1/participations",
1505
+ body: CreateParticipationParams.toDto(params),
1506
+ attributes: Attributes.protected()
1507
+ });
1508
+ return Participation.fromDto(dto);
1509
+ }
1510
+
1511
+ // src/shared/core/checkout/coin-list/token-sale-namespace.ts
1512
+ var CoinListTokenSaleNamespaceImpl = class {
1513
+ constructor(ctx) {
1514
+ this.ctx = ctx;
1515
+ this.log = internalLogger(ctx.logger, "TOKEN_SALE");
1516
+ }
1517
+ async list(offerId) {
1518
+ return this.log.wrap("list", offerId, async () => {
1519
+ await this.ctx.ensureUserAuthenticated();
1520
+ return fetchParticipations(this.ctx.api, offerId);
1521
+ });
1522
+ }
1523
+ async listPage(params) {
1524
+ return this.log.wrap("listPage", params, async () => {
1525
+ await this.ctx.ensureUserAuthenticated();
1526
+ return fetchParticipationsPage(this.ctx.api, params);
1527
+ });
1528
+ }
1529
+ async get(id) {
1530
+ return this.log.wrap("get", id, async () => {
1531
+ await this.ctx.ensureUserAuthenticated();
1532
+ return fetchParticipation(this.ctx.api, id);
1533
+ });
1534
+ }
1535
+ async createParticipation(params) {
1536
+ return this.log.wrap("createParticipation", params, async () => {
1537
+ await this.ctx.ensureUserAuthenticated();
1538
+ return createParticipation(this.ctx.api, params);
1539
+ });
1540
+ }
1541
+ };
1542
+
1543
+ // src/shared/core/checkout/ondo/constants.ts
1544
+ var ONDO_SWAP_CONTRACT_ADDRESSES = {
1545
+ ethereum_sepolia: EvmContractAddress(
1546
+ "0x7014019ed51Edab984a71D30F2707D2dB2316A7A"
1547
+ )
1548
+ };
1549
+ function ondoSwapContractAddress(chain) {
1550
+ return ONDO_SWAP_CONTRACT_ADDRESSES[chain] ?? null;
1551
+ }
1552
+ var ONDO_POLL_INTERVAL_MS = 15e3;
1553
+ var ONDO_QUOTE_EXPIRY_THRESHOLD_MS = 5e3;
1554
+ var DEFAULT_ONDO_AMOUNT_TO_COMPUTE_PRICE = DecimalString("1000");
1555
+ var ONDO_SETTLEMENT_ASSET = USDC_SYMBOL;
1556
+ var DEFAULT_ONDO_SELL_TOKENS_TO_COMPUTE_PRICE = 1;
1557
+ var ONDO_SUPPORTED_INPUT_ASSETS = [
1558
+ USDC_SYMBOL
1559
+ ];
1560
+
1561
+ // src/shared/core/checkout/ondo/math.ts
1562
+ function computeOndoBuyPrice(transaction) {
1563
+ const { notionalValue, receiveOutputAmount } = transaction;
1564
+ return pricePerShare({
1565
+ usd: notionalValue,
1566
+ shares: receiveOutputAmount
1567
+ });
1568
+ }
1569
+ function computeOndoSellPrice(transaction) {
1570
+ const { expected, spendInputAmount } = transaction;
1571
+ return pricePerShare({
1572
+ usd: grossProceeds(expected),
1573
+ shares: spendInputAmount
1574
+ });
1575
+ }
1576
+ function grossProceeds(expected) {
1577
+ const raw = expected.quantity.raw + expected.fee.raw;
1578
+ if (raw > MAX_UINT_256) {
1579
+ throw new MathError(`Ondo sell proceeds: out of uint256 bounds (${raw})`);
1580
+ }
1581
+ return BlockchainAmount.add(expected.quantity, expected.fee);
1582
+ }
1583
+ function pricePerShare({
1584
+ usd,
1585
+ shares
1586
+ }) {
1587
+ const price = BlockchainAmount.div(usd, shares);
1588
+ return BlockchainAmount({
1589
+ raw: assertPriceFits(price.raw),
1590
+ decimals: price.decimals
1591
+ });
1592
+ }
1593
+ function assertPriceFits(raw) {
1594
+ try {
1595
+ return assertUint256(raw);
1596
+ } catch {
1597
+ throw new MathError(`Ondo price: out of uint256 bounds (${raw})`);
1598
+ }
1599
+ }
1600
+
1601
+ // src/shared/types/trading.ts
1602
+ var Ticker = (value) => value;
1603
+
1604
+ // src/shared/types/providers/ondo/ondo.ts
1605
+ var OndoTradingStatus = {
1606
+ fromDto: (dto) => {
1607
+ if (!dto.tradable) return { type: "not-tradable", side: dto.side };
1608
+ return {
1609
+ type: "tradable",
1610
+ side: dto.side,
1611
+ grossMaxTokens: decimalOrNull(dto.gross_max_tokens),
1612
+ grossMaxNotionalValue: decimalOrNull(dto.gross_max_notional_value),
1613
+ grossMaxActiveNotionalValue: decimalOrNull(
1614
+ dto.gross_max_active_notional_value
1615
+ )
1616
+ };
1617
+ }
1618
+ };
1619
+ var decimalOrNull = (value) => value === null ? null : DecimalString(value);
1620
+ var OndoQuote = {
1621
+ fromDto: (dto) => {
1622
+ const assetDecimals = AssetDecimals(dto.asset_decimals);
1623
+ return {
1624
+ chain: chainFromId(dto.chain_id),
1625
+ ticker: Ticker(dto.ticker),
1626
+ assetAddress: EvmContractAddress(dto.asset_address),
1627
+ asset: {
1628
+ name: dto.ticker,
1629
+ symbol: AssetSymbol(dto.symbol),
1630
+ decimals: assetDecimals
1631
+ },
1632
+ side: dto.side,
1633
+ tokenBaseUnits: blockchainAmountFromRawOrThrow({
1634
+ label: "tokenBaseUnits",
1635
+ raw: dto.token_base_units,
1636
+ decimals: assetDecimals
1637
+ }),
1638
+ price: DecimalString(dto.price)
1639
+ };
1640
+ }
1641
+ };
1642
+ var OndoBuyTransaction = {
1643
+ fromDto: (dto) => {
1644
+ const spendDecimals = AssetDecimals(dto.spend_input_decimals);
1645
+ const outputDecimals = AssetDecimals(dto.receive_output_decimals);
1646
+ return {
1647
+ ...parseSwapCore(dto, spendDecimals),
1648
+ side: "buy",
1649
+ fee: blockchainAmountFromRawOrThrow({
1650
+ label: "fee",
1651
+ raw: dto.fee,
1652
+ decimals: spendDecimals
1653
+ }),
1654
+ notionalValue: blockchainAmountFromRawOrThrow({
1655
+ label: "notional_value",
1656
+ raw: dto.notional_value,
1657
+ decimals: spendDecimals
1658
+ }),
1659
+ receiveOutputAmount: parsePositiveAmount({
1660
+ label: "receive_output_amount",
1661
+ raw: dto.receive_output_amount,
1662
+ decimals: outputDecimals,
1663
+ // A transaction that yields nothing is not one to sign - the user
1664
+ // would pay the deposit and receive no asset - and frontline refuses
1665
+ // to emit one. A zero here is a changed encoding, not a small order.
1666
+ // Rejecting it at the boundary is also what lets `computeOndoBuyPrice`
1667
+ // divide by it without a fallible result: the failure surfaces as the
1668
+ // data hook's ERROR state rather than as a division during render.
1669
+ reason: "a buy that yields nothing is not fillable"
1670
+ })
1671
+ };
1672
+ }
1673
+ };
1674
+ var OndoSellTransaction = {
1675
+ fromDto: (dto) => {
1676
+ const spendDecimals = AssetDecimals(dto.spend_input_decimals);
1677
+ const outputDecimals = AssetDecimals(dto.receive_output_decimals);
1678
+ const expectedQuantity = parsePositiveAmount({
1679
+ label: "expected_quantity",
1680
+ raw: dto.expected_quantity,
1681
+ decimals: outputDecimals,
1682
+ reason: "a sale that yields nothing is not fillable"
1683
+ });
1684
+ return {
1685
+ ...parseSwapCore(dto, spendDecimals),
1686
+ side: "sell",
1687
+ expected: {
1688
+ quantity: expectedQuantity,
1689
+ fee: blockchainAmountFromRawOrThrow({
1690
+ label: "expected_fee",
1691
+ raw: dto.expected_fee,
1692
+ decimals: outputDecimals
1693
+ })
1694
+ },
1695
+ minimum: {
1696
+ quantity: parseMinimumQuantity(
1697
+ dto.minimum_quantity,
1698
+ outputDecimals,
1699
+ expectedQuantity
1700
+ ),
1701
+ fee: blockchainAmountFromRawOrThrow({
1702
+ label: "minimum_fee",
1703
+ raw: dto.minimum_fee,
1704
+ decimals: outputDecimals
1705
+ })
1706
+ }
1707
+ };
1708
+ }
1709
+ };
1710
+ function parseSwapCore(dto, spendDecimals) {
1711
+ return {
1712
+ tx: {
1713
+ to: EvmContractAddress(dto.to),
1714
+ data: HexEncodedTransactionData(dto.data)
1715
+ },
1716
+ expiresAt: parseExpiresAt(dto.expires_at),
1717
+ spendInputAmount: parsePositiveAmount({
1718
+ label: "spend_input_amount",
1719
+ raw: dto.spend_input_amount,
1720
+ decimals: spendDecimals,
1721
+ // A transaction that takes nothing from the wallet is not one to sign:
1722
+ // it would settle one leg of a trade and skip the other. Frontline
1723
+ // refuses an `amount` of zero whichever way the trade runs, so this is a
1724
+ // changed encoding rather than a small order.
1725
+ //
1726
+ // Guarded on both sides rather than on the sale alone, because which
1727
+ // amount becomes the divisor in the price flips with the direction: a
1728
+ // guard placed by that would be a rule about the arithmetic rather than
1729
+ // about the trade.
1730
+ reason: "a swap that spends nothing is not fillable"
1731
+ })
1732
+ };
1733
+ }
1734
+ function parseMinimumQuantity(raw, decimals, expectedQuantity) {
1735
+ const amount = parsePositiveAmount({
1736
+ label: "minimum_quantity",
1737
+ raw,
1738
+ decimals,
1739
+ reason: "a floor of zero guarantees nothing"
1740
+ });
1741
+ if (amount.raw > expectedQuantity.raw) {
1742
+ throw new ValidationError(
1743
+ `minimum_quantity: must not exceed expected_quantity ("${raw}" > "${expectedQuantity.raw}")`
1744
+ );
1745
+ }
1746
+ return amount;
1747
+ }
1748
+ function parsePositiveAmount({
1749
+ label,
1750
+ raw,
1751
+ decimals,
1752
+ reason
1753
+ }) {
1754
+ const amount = blockchainAmountFromRawOrThrow({ label, raw, decimals });
1755
+ if (amount.raw <= 0n) {
1756
+ throw new ValidationError(
1757
+ `${label}: must be greater than zero ("${raw}") - ${reason}`
1758
+ );
1759
+ }
1760
+ return amount;
1761
+ }
1762
+ function parseExpiresAt(value) {
1763
+ const date = new Date(value);
1764
+ if (Number.isNaN(date.getTime())) {
1765
+ throw new ValidationError(`expires_at: not a date ("${value}")`);
1766
+ }
1767
+ return date;
1768
+ }
1769
+
1770
+ // src/shared/api/frontline/providers/ondo/ondo.ts
1771
+ async function getOndoTradingStatus(api, params) {
1772
+ const dto = await api.send({
1773
+ method: "GET",
1774
+ url: "/v1/ondo/swap/trading-status",
1775
+ queryParams: { symbol: params.symbol, side: params.side },
1776
+ attributes: Attributes.protected()
1777
+ });
1778
+ return OndoTradingStatus.fromDto(dto);
1779
+ }
1780
+ async function getOndoQuote(api, params) {
1781
+ const dto = await api.send({
1782
+ method: "GET",
1783
+ url: "/v1/ondo/swap/quote",
1784
+ queryParams: {
1785
+ symbol: params.symbol,
1786
+ side: params.side,
1787
+ duration: params.duration,
1788
+ ...sizeParam(params)
1789
+ },
1790
+ attributes: Attributes.protected()
1791
+ });
1792
+ return OndoQuote.fromDto(dto);
1793
+ }
1794
+ async function buildOndoBuy(api, params) {
1795
+ const dto = await api.send({
1796
+ method: "POST",
1797
+ url: "/v1/ondo/swap/buy",
1798
+ body: swapBody(params),
1799
+ attributes: Attributes.protected()
1800
+ });
1801
+ assertSpendScaleAgrees({
1802
+ published: dto.spend_input_decimals,
1803
+ sized: params.amount,
1804
+ trade: "purchase"
1805
+ });
1806
+ return OndoBuyTransaction.fromDto(dto);
1807
+ }
1808
+ async function buildOndoSell(api, params) {
1809
+ const dto = await api.send({
1810
+ method: "POST",
1811
+ url: "/v1/ondo/swap/sell",
1812
+ body: swapBody(params),
1813
+ attributes: Attributes.protected()
1814
+ });
1815
+ assertSpendScaleAgrees({
1816
+ published: dto.spend_input_decimals,
1817
+ sized: params.amount,
1818
+ trade: "sale",
1819
+ // The two answers come from two chains, so on a testnet they can disagree
1820
+ // for a reason that is neither the caller's nor a corrupt response. Say so,
1821
+ // or a QA run reads as a puzzle rather than a diagnosis.
1822
+ note: "the quote resolves the asset on Ethereum mainnet while the swap executes on the chain requested, so these disagree until frontline serves a chain-scoped quote"
1823
+ });
1824
+ return OndoSellTransaction.fromDto(dto);
1825
+ }
1826
+ function swapBody(params) {
1827
+ return {
1828
+ symbol: params.symbol,
1829
+ chain: params.chain,
1830
+ wallet_address: params.walletAddress,
1831
+ amount: params.amount.raw.toString()
1832
+ };
1833
+ }
1834
+ function assertSpendScaleAgrees({
1835
+ published,
1836
+ sized,
1837
+ trade,
1838
+ note
1839
+ }) {
1840
+ if (published === sized.decimals) return;
1841
+ const because = note === void 0 ? "" : ` - ${note}`;
1842
+ throw new ValidationError(
1843
+ `spend_input_decimals: the ${trade} was priced in ${published} decimals but the order was sized in ${sized.decimals}${because}`
1844
+ );
1845
+ }
1846
+ function sizeParam(params) {
1847
+ const tokenAmount = "tokenAmount" in params ? params.tokenAmount : void 0;
1848
+ const notionalValue = "notionalValue" in params ? params.notionalValue : void 0;
1849
+ if (tokenAmount !== void 0) {
1850
+ if (notionalValue !== void 0) {
1851
+ throw new ValidationError(
1852
+ "An Ondo quote takes tokenAmount or notionalValue, not both"
1853
+ );
1854
+ }
1855
+ return { token_amount: formatRawAmount(tokenAmount) };
1856
+ }
1857
+ if (notionalValue === void 0) {
1858
+ throw new ValidationError(
1859
+ "An Ondo quote must be sized by tokenAmount or notionalValue"
1860
+ );
1861
+ }
1862
+ return { notional_value: notionalValue };
1863
+ }
1864
+
1865
+ // src/shared/core/checkout/ondo/ondo-namespace.ts
1866
+ var OndoNamespaceImpl = class {
1867
+ constructor(ctx) {
1868
+ this.ctx = ctx;
1869
+ this.log = internalLogger(ctx.logger, "ONDO");
1870
+ }
1871
+ async getTradingStatus(params) {
1872
+ return this.log.wrap("getTradingStatus", params, async () => {
1873
+ await this.ctx.ensureUserAuthenticated();
1874
+ return getOndoTradingStatus(this.ctx.api, params);
1875
+ });
1876
+ }
1877
+ async getQuote(params) {
1878
+ return this.log.wrap("getQuote", params, async () => {
1879
+ await this.ctx.ensureUserAuthenticated();
1880
+ return getOndoQuote(this.ctx.api, params);
1881
+ });
1882
+ }
1883
+ async buildBuyTransaction(params) {
1884
+ return this.log.wrap("buildBuyTransaction", params, async () => {
1885
+ await this.ctx.ensureUserAuthenticated();
1886
+ return buildOndoBuy(this.ctx.api, params);
1887
+ });
1888
+ }
1889
+ async buildSellTransaction(params) {
1890
+ return this.log.wrap("buildSellTransaction", params, async () => {
1891
+ await this.ctx.ensureUserAuthenticated();
1892
+ return buildOndoSell(this.ctx.api, params);
1893
+ });
1894
+ }
1895
+ };
278
1896
 
279
- // src/shared/core/blockchain/abis/superstate-swap.ts
1897
+ // src/shared/core/checkout/superstate/blockchain/abi.ts
280
1898
  var SUPERSTATE_SWAP_ABI = [
281
1899
  {
282
1900
  type: "function",
@@ -484,275 +2102,39 @@ var SUPERSTATE_SWAP_ABI = [
484
2102
  inputs: []
485
2103
  },
486
2104
  {
487
- type: "error",
488
- name: "InvalidAmount",
489
- inputs: []
490
- },
491
- {
492
- type: "error",
493
- name: "SwapFailed",
494
- inputs: [
495
- { name: "user", type: "address", internalType: "address" },
496
- { name: "token", type: "address", internalType: "address" }
497
- ]
498
- }
499
- ];
500
-
501
- // src/shared/types/blockchain/core.ts
502
- var EvmWalletAddress = (value) => value;
503
- var EvmContractAddress = (value) => value;
504
- var HexEncodedTransactionData = (value) => value;
505
- var AssetDecimals = (value) => value;
506
- var MAX_UINT_256 = 2n ** 256n - 1n;
507
- var assertUint256 = (value) => {
508
- if (value < 0n || value > MAX_UINT_256) {
509
- throw new Error(`Value out of uint256 bounds: ${value}`);
510
- }
511
- return value;
512
- };
513
- var BlockchainAmount = Object.assign(
514
- (value) => value,
515
- {
516
- add: (a, b) => combineAmounts(a, b, (x, y) => x + y),
517
- sub: (a, b) => combineAmounts(a, b, (x, y) => x - y)
518
- }
519
- );
520
- function combineAmounts(a, b, op) {
521
- if (a.decimals !== b.decimals) {
522
- throw new Error(
523
- `Cannot combine BlockchainAmounts with different decimals: ${a.decimals} vs ${b.decimals}`
524
- );
525
- }
526
- const raw = op(a.raw, b.raw);
527
- if (raw < 0n || raw > MAX_UINT_256) {
528
- throw new Error(`BlockchainAmount out of uint256 bounds: ${raw}`);
529
- }
530
- return BlockchainAmount({ raw, decimals: a.decimals });
531
- }
532
- var AssetSymbol = (value) => value;
533
- var StablecoinSymbol = (value) => value;
534
- var KnownAssetSymbol = StablecoinSymbol;
535
- var Bps = (value) => value;
536
-
537
- // src/shared/core/blockchain/bps.ts
538
- var BPS_DENOM = Bps(10000n);
539
- function applyBps(amount, bps) {
540
- return assertUint256(amount * bps / BPS_DENOM);
541
- }
542
-
543
- // src/shared/types/blockchain/ui.ts
544
- var FormattedAmountUi = (value) => value;
545
- var FormattedPercentUi = (value) => value;
546
- var TxExplorerUrl = (value) => value;
547
- var ShortenedWalletAddress = (value) => value;
548
- var FormattedAmountAssetUi = (value) => value;
549
- var AssetIconUrl = (value) => value;
550
-
551
- // src/shared/core/blockchain/chain.ts
552
- function getChainId(chain) {
553
- switch (chain) {
554
- case "ethereum_mainnet":
555
- return 1;
556
- case "ethereum_sepolia":
557
- return 11155111;
558
- default: {
559
- const _exhaustive = chain;
560
- return _exhaustive;
561
- }
562
- }
563
- }
564
- function getNetworkName(chain) {
565
- switch (chain) {
566
- case "ethereum_mainnet":
567
- return "Ethereum";
568
- case "ethereum_sepolia":
569
- return "Ethereum Sepolia";
570
- default: {
571
- const _exhaustive = chain;
572
- return _exhaustive;
573
- }
574
- }
575
- }
576
- function txExplorerUrl(chain, txHash) {
577
- return TxExplorerUrl(`${explorerBaseUrl(chain)}/tx/${txHash}`);
578
- }
579
- function explorerBaseUrl(chain) {
580
- switch (chain) {
581
- case "ethereum_mainnet":
582
- return "https://etherscan.io";
583
- case "ethereum_sepolia":
584
- return "https://sepolia.etherscan.io";
585
- default: {
586
- const _exhaustive = chain;
587
- return _exhaustive;
588
- }
589
- }
590
- }
591
-
592
- // src/shared/core/blockchain/formatters.ts
593
- var import_viem = require("viem");
594
-
595
- // src/shared/core/blockchain/swap/math.ts
596
- function computePrice({
597
- inputTokenAmount,
598
- outputTokenAmount
599
- }) {
600
- if (outputTokenAmount.raw === 0n) return null;
601
- const scale = 10n ** BigInt(outputTokenAmount.decimals);
602
- const raw = assertUint256(
603
- inputTokenAmount.raw * scale / outputTokenAmount.raw
604
- );
605
- return BlockchainAmount({ raw, decimals: inputTokenAmount.decimals });
606
- }
607
- function computeSlip(amount, slippage) {
608
- const retained = Bps(assertUint256(BPS_DENOM - slippage));
609
- const slipRaw = applyBps(amount.raw, retained);
610
- return BlockchainAmount({ raw: slipRaw, decimals: amount.decimals });
611
- }
612
-
613
- // src/shared/core/blockchain/formatters.ts
614
- function shortenAddress(address) {
615
- const short = address.length > 10 ? `${address.slice(0, 6)}\u2026${address.slice(-4)}` : address;
616
- return ShortenedWalletAddress(short);
617
- }
618
- function formatAmount(amount, locale, options) {
619
- const decimal = formatRawAmount(amount);
620
- let [integerPart, fractionPart = ""] = decimal.split(".");
621
- const maxFractionDigits = options?.maxFractionDigits;
622
- const minFractionDigits = maxFractionDigits !== void 0 ? Math.min(maxFractionDigits, amount.decimals) : Math.min(2, amount.decimals);
623
- if (maxFractionDigits !== void 0 && fractionPart.length > maxFractionDigits) {
624
- ({ integerPart, fractionPart } = roundFractionHalfUp(
625
- integerPart,
626
- fractionPart,
627
- maxFractionDigits
628
- ));
629
- }
630
- const fraction = minFractionDigits === 0 ? "" : fractionPart.padEnd(minFractionDigits, "0");
631
- const integerFormatted = BigInt(integerPart).toLocaleString(locale);
632
- if (minFractionDigits === 0 && fraction === "") {
633
- return FormattedAmountUi(integerFormatted);
634
- }
635
- const decimalSeparator = new Intl.NumberFormat(locale).formatToParts(1.1).find((p) => p.type === "decimal")?.value ?? ".";
636
- return FormattedAmountUi(`${integerFormatted}${decimalSeparator}${fraction}`);
637
- }
638
- function roundFractionHalfUp(integerPart, fractionPart, maxFractionDigits) {
639
- if (fractionPart.length <= maxFractionDigits) {
640
- return { integerPart, fractionPart };
641
- }
642
- if (maxFractionDigits === 0) {
643
- const roundUp = fractionPart[0] >= "5";
644
- const integer = BigInt(integerPart) + (roundUp ? 1n : 0n);
645
- return { integerPart: integer.toString(), fractionPart: "" };
646
- }
647
- const trimmed = fractionPart.slice(0, maxFractionDigits);
648
- if (fractionPart[maxFractionDigits] < "5") {
649
- return { integerPart, fractionPart: trimmed };
650
- }
651
- const digits = trimmed.split("").map((digit) => Number.parseInt(digit, 10));
652
- let carry = 1;
653
- for (let i = digits.length - 1; i >= 0 && carry > 0; i -= 1) {
654
- const sum = digits[i] + carry;
655
- if (sum === 10) {
656
- digits[i] = 0;
657
- carry = 1;
658
- } else {
659
- digits[i] = sum;
660
- carry = 0;
661
- }
662
- }
663
- return {
664
- integerPart: carry > 0 ? (BigInt(integerPart) + 1n).toString() : integerPart,
665
- fractionPart: digits.join("")
666
- };
667
- }
668
- function formatRawAmount(amount) {
669
- return (0, import_viem.formatUnits)(amount.raw, amount.decimals);
670
- }
671
- function formatCompactAmount(amount, locale) {
672
- const value = Number(formatRawAmount(amount));
673
- const formatted = new Intl.NumberFormat(locale, {
674
- notation: "compact",
675
- maximumFractionDigits: 2
676
- }).format(value);
677
- return FormattedAmountUi(formatted);
678
- }
679
- function formatBpsAsPercent(bps, locale) {
680
- const whole = bps / 100n;
681
- const fraction = bps % 100n;
682
- const wholeFormatted = whole.toLocaleString(locale);
683
- const decimalSeparator = new Intl.NumberFormat(locale).formatToParts(1.1).find((p) => p.type === "decimal")?.value ?? ".";
684
- if (fraction === 0n) {
685
- return FormattedPercentUi(`${wholeFormatted}%`);
686
- }
687
- const fractionFormatted = fraction.toString().padStart(2, "0").replace(/0+$/, "");
688
- return FormattedPercentUi(
689
- `${wholeFormatted}${decimalSeparator}${fractionFormatted}%`
690
- );
691
- }
692
- function usdAmount(amount) {
693
- return FormattedAmountAssetUi(`$${amount}`);
694
- }
695
- function assetAmount(amount, symbol) {
696
- return FormattedAmountAssetUi(`${amount} ${symbol}`);
697
- }
698
- var NA_AMOUNT_ASSET_UI = FormattedAmountAssetUi("-");
699
- var USD_FRACTION_DIGITS = AssetDecimals(2);
700
- function formattedUsdPrice(amount, locale) {
701
- if (!amount) return NA_AMOUNT_ASSET_UI;
702
- return usdAmount(
703
- formatAmount(amount, locale, { maxFractionDigits: USD_FRACTION_DIGITS })
704
- );
705
- }
706
- function formattedPricePerShare(quote, locale) {
707
- if (!quote) return NA_AMOUNT_ASSET_UI;
708
- return formattedUsdPrice(computePrice(quote), locale);
709
- }
710
-
711
- // src/shared/core/blockchain/math.ts
712
- var import_viem2 = require("viem");
713
- function parseBlockchainAmount(amount, decimals) {
714
- const trimmed = amount.trim();
715
- if (trimmed === "") return { valid: false, reason: { type: "empty" } };
716
- if (trimmed.startsWith("-")) {
717
- return { valid: false, reason: { type: "negative" } };
718
- }
719
- if (/[eE]/.test(trimmed)) {
720
- return { valid: false, reason: { type: "invalid-format" } };
721
- }
722
- if (!/^\d+(\.\d+)?$/.test(trimmed)) {
723
- return { valid: false, reason: { type: "invalid-format" } };
724
- }
725
- const [, fraction = ""] = trimmed.split(".");
726
- if (fraction.length > decimals) {
727
- return {
728
- valid: false,
729
- reason: { type: "too-many-decimals", maxDecimals: decimals }
730
- };
731
- }
732
- try {
733
- return {
734
- valid: true,
735
- amount: BlockchainAmount({
736
- raw: (0, import_viem2.parseUnits)(trimmed, decimals),
737
- decimals
738
- })
739
- };
740
- } catch {
741
- return { valid: false, reason: { type: "invalid-format" } };
2105
+ type: "error",
2106
+ name: "InvalidAmount",
2107
+ inputs: []
2108
+ },
2109
+ {
2110
+ type: "error",
2111
+ name: "SwapFailed",
2112
+ inputs: [
2113
+ { name: "user", type: "address", internalType: "address" },
2114
+ { name: "token", type: "address", internalType: "address" }
2115
+ ]
742
2116
  }
743
- }
2117
+ ];
744
2118
 
745
- // src/shared/core/blockchain/swap/constants.ts
746
- var SUPERSTATE_TOS_URL = "https://superstate.com/terms";
747
- var SWAP_POLL_INTERVAL_MS = 15e3;
748
- var DEFAULT_AMOUNT_TO_COMPUTE_PRICE = 1000000n;
749
- var SLIPPAGE_OPTIONS_BPS = [25n, 50n, 100n, 200n, 500n].map(
750
- (n) => Bps(n)
751
- );
752
- var DEFAULT_SLIPPAGE_BPS = Bps(50n);
753
- var SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA = EvmContractAddress("0x84f8e9a6C9Cc12fe911259372EfCa5582C4ae557");
2119
+ // src/shared/core/checkout/superstate/blockchain/math.ts
2120
+ function computePrice({
2121
+ inputTokenAmount,
2122
+ outputTokenAmount
2123
+ }) {
2124
+ if (outputTokenAmount.raw === 0n) return null;
2125
+ const scale = 10n ** BigInt(outputTokenAmount.decimals);
2126
+ const raw = assertUint256(
2127
+ inputTokenAmount.raw * scale / outputTokenAmount.raw
2128
+ );
2129
+ return BlockchainAmount({ raw, decimals: inputTokenAmount.decimals });
2130
+ }
2131
+ function computeSlip(amount, slippage) {
2132
+ const retained = Bps(assertUint256(BPS_DENOM - slippage));
2133
+ const slipRaw = applyBps(amount.raw, retained);
2134
+ return BlockchainAmount({ raw: slipRaw, decimals: amount.decimals });
2135
+ }
754
2136
 
755
- // src/shared/core/blockchain/swap/quote.ts
2137
+ // src/shared/core/checkout/superstate/blockchain/quote.ts
756
2138
  var SwapQuote = {
757
2139
  /**
758
2140
  * Assembles a {@link SwapQuote} from a raw contract {@link SwapPreview}. The
@@ -772,12 +2154,12 @@ var SwapQuote = {
772
2154
  })
773
2155
  };
774
2156
 
775
- // src/shared/core/blockchain/swap/status.ts
2157
+ // src/shared/core/checkout/superstate/blockchain/status.ts
776
2158
  function isStopped(status) {
777
2159
  return (status.stopped & status.swapLevel) !== 0n;
778
2160
  }
779
2161
 
780
- // src/shared/core/blockchain/swap/swapped-event.ts
2162
+ // src/shared/core/checkout/superstate/blockchain/swapped-event.ts
781
2163
  var import_viem3 = require("viem");
782
2164
  function decodeSwappedOutputAmount(receipt, outputDecimals) {
783
2165
  try {
@@ -795,420 +2177,658 @@ function decodeSwappedOutputAmount(receipt, outputDecimals) {
795
2177
  }
796
2178
  }
797
2179
 
798
- // src/shared/core/blockchain/token-registry.ts
799
- var USDC_SYMBOL = StablecoinSymbol("USDC");
800
- var USDC = {
801
- name: "USD Coin",
802
- symbol: USDC_SYMBOL,
803
- decimals: AssetDecimals(6)
804
- };
805
- var USDT_SYMBOL = StablecoinSymbol("USDT");
806
- var USDT = {
807
- name: "Tether USD",
808
- symbol: USDT_SYMBOL,
809
- decimals: AssetDecimals(6)
810
- };
811
- var USDC_ADDRESSES = {
812
- ethereum_mainnet: EvmContractAddress(
813
- "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
814
- ),
815
- ethereum_sepolia: EvmContractAddress(
816
- "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"
817
- )
818
- };
819
- var USDT_ADDRESSES = {
820
- ethereum_mainnet: EvmContractAddress(
821
- "0xdac17f958d2ee523a2206206994597c13d831ec7"
822
- ),
823
- ethereum_sepolia: EvmContractAddress(
824
- "0x7169D38820dfd117C3FA1f22a697dBA58d90BA06"
825
- )
826
- };
827
- var TOKEN_REGISTRY = {
828
- erc20: (symbol) => {
829
- switch (symbol) {
830
- case "USDC":
831
- return USDC;
832
- case "USDT":
833
- return USDT;
834
- default:
835
- throw new Error(`Unknown asset symbol: ${symbol}`);
836
- }
837
- },
838
- contractAddress: (symbol, chain) => {
839
- switch (symbol) {
840
- case "USDC":
841
- return USDC_ADDRESSES[chain];
842
- case "USDT":
843
- return USDT_ADDRESSES[chain];
844
- default:
845
- throw new Error(`Unknown asset symbol: ${symbol}`);
846
- }
847
- }
2180
+ // src/shared/core/checkout/superstate/constants.ts
2181
+ var SUPERSTATE_ISSUER_NAME = "Superstate";
2182
+ var SUPERSTATE_SUPPORTED_INPUT_ASSETS = [USDC_SYMBOL];
2183
+ var SWAP_POLL_INTERVAL_MS = 15e3;
2184
+ var DEFAULT_AMOUNT_TO_COMPUTE_PRICE = 1000000n;
2185
+ var SLIPPAGE_OPTIONS_BPS = [25n, 50n, 100n, 200n, 500n].map(
2186
+ (n) => Bps(n)
2187
+ );
2188
+ var DEFAULT_SLIPPAGE_BPS = Bps(50n);
2189
+ var SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA = EvmContractAddress("0x84f8e9a6C9Cc12fe911259372EfCa5582C4ae557");
2190
+ var SUPERSTATE_SWAP_CONTRACT_ADDRESSES = {
2191
+ ethereum_sepolia: SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA
848
2192
  };
2193
+ function superstateSwapContractAddress(chain) {
2194
+ return SUPERSTATE_SWAP_CONTRACT_ADDRESSES[chain] ?? null;
2195
+ }
849
2196
 
850
- // src/shared/api/http-attributes.ts
851
- var empty = {};
852
- var concat = (left, right) => ({
853
- ...left,
854
- ...right
855
- });
856
- var concatAll = (...items) => {
857
- let result = empty;
858
- for (const item of items) {
859
- result = concat(result, item);
860
- }
861
- return result;
862
- };
863
- var protectedRequest = () => ({ protected: true });
864
- var userAgent = () => ({ userAgent: true });
865
- var idempotencyKey = () => ({
866
- idempotencyKey: true
867
- });
868
- var clientCredentials = (credentials) => ({
869
- clientCredentials: credentials
870
- });
871
- var retryAttempt = (attempt) => ({
872
- retryAttempt: attempt
873
- });
874
- var renewAttempted = (value) => ({
875
- renewAttempted: value
876
- });
877
- var isProtected = (attrs) => attrs?.protected === true;
878
- var needUserAgent = (attrs) => attrs?.userAgent === true;
879
- var isIdempotent = (attrs) => attrs?.idempotencyKey === true;
880
- var getRetryAttempt = (attrs) => attrs?.retryAttempt ?? 0;
881
- var wasRenewAttempted = (attrs) => attrs?.renewAttempted === true;
882
- var getClientCredentials = (attrs) => attrs?.clientCredentials;
883
- var Attributes = {
884
- empty,
885
- concat,
886
- concatAll,
887
- protected: protectedRequest,
888
- isProtected,
889
- userAgent,
890
- needUserAgent,
891
- idempotencyKey,
892
- isIdempotent,
893
- retryAttempt,
894
- getRetryAttempt,
895
- renewAttempted,
896
- wasRenewAttempted,
897
- clientCredentials,
898
- getClientCredentials
899
- };
2197
+ // src/shared/core/checkout/superstate/formatters.ts
2198
+ function formattedPricePerShare(quote, locale) {
2199
+ if (!quote) return NA_AMOUNT_ASSET_UI;
2200
+ return formattedUsdPrice(computePrice(quote), locale);
2201
+ }
900
2202
 
901
- // src/shared/types/swap.ts
902
- var SwapAuthorization = {
903
- fromDto: (dto) => ({
904
- authorized: dto.authorized
905
- })
906
- };
907
- var SwapPreview = {
908
- fromDto: (dto) => ({
909
- inputAmount: assertUint256(BigInt(dto.pay_input_amount)),
910
- fee: assertUint256(BigInt(dto.fee)),
911
- outputAmount: assertUint256(BigInt(dto.receive_output_amount))
912
- })
913
- };
914
- var SwapStatus = {
915
- fromDto: (dto) => ({
916
- stopped: assertUint256(BigInt(dto.stopped)),
917
- swapLevel: assertUint256(BigInt(dto.swap_level))
918
- })
919
- };
920
- var TokenAllowance = {
921
- fromDto: (dto) => ({
922
- allowance: assertUint256(BigInt(dto.allowance))
923
- })
924
- };
925
- var TokenBalance = {
926
- fromDto: (dto) => ({
927
- balance: assertUint256(BigInt(dto.balance))
928
- })
929
- };
930
- var AllowWalletResponse = {
931
- fromDto: (dto) => {
932
- switch (dto.action) {
933
- case "broadcast_transaction":
934
- return {
935
- action: "broadcast_transaction",
936
- to: EvmContractAddress(dto.to),
937
- data: HexEncodedTransactionData(dto.data)
938
- };
939
- case "none":
940
- return {
941
- action: "none",
942
- alreadyAllowed: dto.already_allowed
943
- };
944
- default: {
945
- const _exhaustive = dto;
946
- return _exhaustive;
947
- }
948
- }
2203
+ // src/shared/core/checkout/superstate/swap-namespace.ts
2204
+ var SuperstateSwapNamespaceImpl = class {
2205
+ constructor(ctx) {
2206
+ this.ctx = ctx;
2207
+ this.log = internalLogger(ctx.logger, "SUPERSTATE");
2208
+ }
2209
+ async getAuthorization(params) {
2210
+ return this.log.wrap("getAuthorization", params, async () => {
2211
+ await this.ctx.ensureUserAuthenticated();
2212
+ return getSwapAuthorization(this.ctx.api, params);
2213
+ });
2214
+ }
2215
+ async getPreview(params) {
2216
+ return this.log.wrap("getPreview", params, async () => {
2217
+ await this.ctx.ensureUserAuthenticated();
2218
+ return getSwapPreview(this.ctx.api, params);
2219
+ });
2220
+ }
2221
+ async getStatus(params) {
2222
+ return this.log.wrap("getStatus", params, async () => {
2223
+ await this.ctx.ensureUserAuthenticated();
2224
+ return getSwapStatus(this.ctx.api, params);
2225
+ });
2226
+ }
2227
+ async getOutputToken(params) {
2228
+ return this.log.wrap("getOutputToken", params, async () => {
2229
+ await this.ctx.ensureUserAuthenticated();
2230
+ return getSwapOutputToken(this.ctx.api, params);
2231
+ });
2232
+ }
2233
+ async allowWallet(params) {
2234
+ return this.log.wrap("allowWallet", params, async () => {
2235
+ await this.ctx.ensureUserAuthenticated();
2236
+ return allowWallet(this.ctx.api, params);
2237
+ });
949
2238
  }
950
2239
  };
951
2240
 
952
- // src/shared/api/frontline/swap.ts
953
- async function getSwapAuthorization(api, params) {
954
- const dto = await api.send({
955
- method: "GET",
956
- url: "/v1/wallet/authorized",
957
- queryParams: {
958
- chain: params.chain,
959
- contract_address: params.contractAddress,
960
- wallet_address: params.walletAddress
961
- },
962
- attributes: Attributes.protected()
963
- });
964
- return SwapAuthorization.fromDto(dto);
965
- }
966
- async function getSwapOutputToken(api, params) {
967
- const dto = await api.send({
968
- method: "GET",
969
- url: "/v1/swap/output-token",
970
- queryParams: {
971
- chain: params.chain,
972
- contract_address: params.contractAddress
973
- },
974
- attributes: Attributes.protected()
975
- });
976
- return toErc20Asset(dto);
977
- }
978
- async function getSwapPreview(api, params) {
979
- const dto = await api.send({
980
- method: "GET",
981
- url: "/v1/swap/preview",
982
- queryParams: {
983
- chain: params.chain,
984
- contract_address: params.contractAddress,
985
- input_token: params.inputToken,
986
- amount: params.amount.toString()
987
- },
988
- attributes: Attributes.protected()
989
- });
990
- return SwapPreview.fromDto(dto);
2241
+ // src/shared/api/frontline/offers.ts
2242
+ async function fetchOffers(api, clientCreds) {
2243
+ return fetchAllPages((params) => fetchOffersPage(api, params, clientCreds));
991
2244
  }
992
- async function getSwapStatus(api, params) {
993
- const dto = await api.send({
2245
+ async function fetchOffersPage(api, params, clientCreds) {
2246
+ const queryParams = PaginationParams.toQueryParams(params);
2247
+ const pageDto = await api.send({
994
2248
  method: "GET",
995
- url: "/v1/swap/status",
996
- queryParams: {
997
- chain: params.chain,
998
- contract_address: params.contractAddress
999
- },
1000
- attributes: Attributes.protected()
2249
+ url: "/v1/offers",
2250
+ queryParams,
2251
+ attributes: Attributes.concat(
2252
+ Attributes.protected(),
2253
+ Attributes.clientCredentials(clientCreds)
2254
+ )
1001
2255
  });
1002
- return SwapStatus.fromDto(dto);
2256
+ return PaginatedResponse.fromDto(pageDto, Offer.fromDto);
1003
2257
  }
1004
- async function getTokenAllowance(api, params) {
2258
+ async function fetchOfferDetails(api, id, clientCreds) {
1005
2259
  const dto = await api.send({
1006
2260
  method: "GET",
1007
- url: "/v1/token/allowance",
1008
- queryParams: {
1009
- chain: params.chain,
1010
- token_address: params.tokenAddress,
1011
- owner: params.owner,
1012
- spender: params.spender
1013
- },
1014
- attributes: Attributes.protected()
2261
+ url: `/v1/offers/${id}`,
2262
+ attributes: Attributes.concat(
2263
+ Attributes.protected(),
2264
+ Attributes.clientCredentials(clientCreds)
2265
+ )
1015
2266
  });
1016
- return TokenAllowance.fromDto(dto);
2267
+ return OfferDetail.fromDto(dto);
1017
2268
  }
1018
- async function getTokenBalance(api, params) {
2269
+
2270
+ // src/shared/core/offers/offers-namespace.ts
2271
+ var OffersNamespaceImpl = class {
2272
+ constructor(ctx) {
2273
+ this.ctx = ctx;
2274
+ this.log = internalLogger(ctx.logger, "OFFERS");
2275
+ }
2276
+ async list() {
2277
+ return this.log.wrap("list", void 0, async () => {
2278
+ await this.ctx.ensureUserAuthenticated();
2279
+ return fetchOffers(this.ctx.api, void 0);
2280
+ });
2281
+ }
2282
+ async listPage(params) {
2283
+ return this.log.wrap("listPage", params, async () => {
2284
+ await this.ctx.ensureUserAuthenticated();
2285
+ return fetchOffersPage(this.ctx.api, params, void 0);
2286
+ });
2287
+ }
2288
+ async get(id) {
2289
+ return this.log.wrap("get", id, async () => {
2290
+ await this.ctx.ensureUserAuthenticated();
2291
+ return fetchOfferDetails(this.ctx.api, id, void 0);
2292
+ });
2293
+ }
2294
+ };
2295
+
2296
+ // src/shared/types/document-submission.ts
2297
+ var DocumentSubmission = {
2298
+ fromDto: (dto) => ({
2299
+ status: dto.status,
2300
+ formType: dto.form_type
2301
+ })
2302
+ };
2303
+
2304
+ // src/shared/api/frontline/documents.ts
2305
+ async function submitDocument(api, documentType, fields) {
1019
2306
  const dto = await api.send({
1020
- method: "GET",
1021
- url: "/v1/token/balance",
1022
- queryParams: {
1023
- chain: params.chain,
1024
- token_address: params.tokenAddress,
1025
- owner: params.owner
1026
- },
2307
+ method: "POST",
2308
+ url: `/v1/documents/${documentType}/submission`,
2309
+ body: fields,
1027
2310
  attributes: Attributes.protected()
1028
2311
  });
1029
- return TokenBalance.fromDto(dto);
2312
+ return DocumentSubmission.fromDto(dto);
1030
2313
  }
1031
- async function allowWallet(api, params) {
2314
+
2315
+ // src/shared/types/kyc.ts
2316
+ var KycToken = {
2317
+ fromDto: (dto) => ({
2318
+ token: dto.token
2319
+ })
2320
+ };
2321
+
2322
+ // src/shared/api/frontline/kyc.ts
2323
+ async function createKycToken(api, levelName, reset) {
1032
2324
  const dto = await api.send({
1033
2325
  method: "POST",
1034
- url: `/v1/offers/${encodeURIComponent(params.offerId)}/allow-wallet`,
2326
+ url: "/v1/kyc-token",
1035
2327
  body: {
1036
- wallet_address: params.walletAddress,
1037
- chain: params.chain,
1038
- signature: params.signature
2328
+ ...levelName === void 0 ? {} : { level_name: levelName },
2329
+ ...reset === void 0 ? {} : { reset }
1039
2330
  },
1040
2331
  attributes: Attributes.protected()
1041
2332
  });
1042
- return AllowWalletResponse.fromDto(dto);
1043
- }
1044
- function toErc20Asset(dto) {
1045
- return {
1046
- name: dto.name,
1047
- symbol: AssetSymbol(dto.symbol),
1048
- decimals: AssetDecimals(dto.decimals)
1049
- };
2333
+ return KycToken.fromDto(dto);
1050
2334
  }
1051
2335
 
1052
- // src/shared/core/erc20-namespace.ts
1053
- var Erc20NamespaceImpl = class {
1054
- constructor(ctx) {
1055
- this.ctx = ctx;
1056
- }
1057
- async getTokenAllowance(params) {
1058
- await this.ctx.ensureUserAuthenticated();
1059
- return getTokenAllowance(this.ctx.api, params);
1060
- }
1061
- async getTokenBalance(params) {
1062
- await this.ctx.ensureUserAuthenticated();
1063
- return getTokenBalance(this.ctx.api, params);
1064
- }
2336
+ // src/shared/types/pii.ts
2337
+ var Iso2CountryCode = (value) => value;
2338
+ var PiiJurisdiction = {
2339
+ fromDto: (dto) => ({
2340
+ iso2: Iso2CountryCode(dto.iso_2),
2341
+ name: dto.name
2342
+ })
1065
2343
  };
1066
-
1067
- // src/shared/types/asset.ts
1068
- var AssetId = (value) => value;
1069
- var AssetCode = (value) => value;
1070
- var Asset = {
2344
+ var PiiAddress = {
1071
2345
  fromDto: (dto) => ({
1072
- id: AssetId(dto.id),
1073
- code: AssetCode(dto.code),
1074
- name: dto.name,
1075
- fractionalDigits: dto.fractional_digits
2346
+ street: dto.street,
2347
+ city: dto.city,
2348
+ state: dto.state,
2349
+ postalCode: dto.postal_code,
2350
+ country: dto.country
2351
+ })
2352
+ };
2353
+ var Pii = {
2354
+ fromDto: (dto) => ({
2355
+ kind: dto.kind,
2356
+ fullLegalName: dto.full_legal_name,
2357
+ dateOfBirth: dto.date_of_birth,
2358
+ jurisdiction: dto.jurisdiction ? PiiJurisdiction.fromDto(dto.jurisdiction) : null,
2359
+ taxId: dto.tax_id,
2360
+ permanentAddress: PiiAddress.fromDto(dto.permanent_address)
1076
2361
  })
1077
2362
  };
1078
2363
 
1079
- // src/shared/types/offer.ts
1080
- var OfferId = (value) => value;
1081
- var OfferSlug = (value) => value;
1082
- var Offer = {
2364
+ // src/shared/api/frontline/pii.ts
2365
+ async function fetchPii(api) {
2366
+ const dto = await api.send({
2367
+ method: "GET",
2368
+ url: "/v1/pii",
2369
+ attributes: Attributes.protected()
2370
+ });
2371
+ return Pii.fromDto(dto);
2372
+ }
2373
+
2374
+ // src/shared/types/requirement.ts
2375
+ var RequirementId = (value) => value;
2376
+ var Requirement = {
1083
2377
  fromDto: (dto) => ({
1084
- id: OfferId(dto.id),
1085
- slug: OfferSlug(dto.slug),
2378
+ id: RequirementId(dto.id),
1086
2379
  type: dto.type,
1087
- tagline: dto.tagline,
1088
- bannerUrl: dto.banner_url,
1089
- logoUrl: dto.logo_url,
1090
- startsAt: new Date(dto.starts_at),
1091
- endsAt: dto.ends_at ? new Date(dto.ends_at) : null
2380
+ details: dto.details
1092
2381
  })
1093
2382
  };
2383
+ var RequirementStatusInfo = {
2384
+ fromStatusesDto: (dto) => Object.entries(dto.statuses).map(
2385
+ ([id, value]) => typeof value === "string" ? { id: RequirementId(id), status: value, action: null } : {
2386
+ id: RequirementId(id),
2387
+ status: value.status,
2388
+ action: value.action ?? null,
2389
+ kycLevel: value.kyc_level,
2390
+ kycReset: value.kyc_reset
2391
+ }
2392
+ )
2393
+ };
1094
2394
 
1095
- // src/shared/utils.ts
1096
- async function sha256(data) {
1097
- const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
1098
- const buffer = bytes.buffer.slice(
1099
- bytes.byteOffset,
1100
- bytes.byteOffset + bytes.byteLength
2395
+ // src/shared/api/frontline/requirements.ts
2396
+ async function fetchOfferRequirements(api, offerId, clientCreds) {
2397
+ const response = await api.send({
2398
+ method: "GET",
2399
+ url: `/v1/offers/${offerId}/requirements`,
2400
+ attributes: Attributes.concat(
2401
+ Attributes.protected(),
2402
+ Attributes.clientCredentials(clientCreds)
2403
+ )
2404
+ });
2405
+ return Object.fromEntries(
2406
+ Object.entries(response.options).map(([optionId, list]) => [
2407
+ optionId,
2408
+ list.data.map(Requirement.fromDto)
2409
+ ])
1101
2410
  );
1102
- return crypto.subtle.digest("SHA-256", buffer);
1103
2411
  }
1104
- function arrayBufferToBase64Url(buffer, padding = true) {
1105
- const bytes = new Uint8Array(buffer);
1106
- let binary = "";
1107
- for (let i = 0; i < bytes.length; i++) {
1108
- binary += String.fromCharCode(bytes[i]);
2412
+ async function fetchRequirementStatuses(api, offerId) {
2413
+ const response = await api.send({
2414
+ method: "GET",
2415
+ url: `/v1/offers/${offerId}/requirements/statuses`,
2416
+ attributes: Attributes.protected()
2417
+ });
2418
+ return RequirementStatusInfo.fromStatusesDto(response);
2419
+ }
2420
+
2421
+ // src/shared/core/requirements/requirements-namespace.ts
2422
+ var RequirementsNamespaceImpl = class {
2423
+ constructor(ctx) {
2424
+ this.ctx = ctx;
2425
+ this.log = internalLogger(ctx.logger, "REQUIREMENTS");
1109
2426
  }
1110
- let base64 = btoa(binary);
1111
- base64 = base64.replace(/\+/g, "-").replace(/\//g, "_");
1112
- if (!padding) {
1113
- base64 = base64.replace(/=+$/, "");
2427
+ async forOffer(offerId) {
2428
+ return this.log.wrap("forOffer", offerId, async () => {
2429
+ await this.ctx.ensureUserAuthenticated();
2430
+ return fetchOfferRequirements(
2431
+ this.ctx.api,
2432
+ offerId,
2433
+ void 0
2434
+ );
2435
+ });
1114
2436
  }
1115
- return base64;
1116
- }
1117
- function generateSecureRandomBase64Url(byteLength) {
1118
- const bytes = new Uint8Array(byteLength);
1119
- crypto.getRandomValues(bytes);
1120
- const buffer = bytes.buffer;
1121
- return arrayBufferToBase64Url(buffer, false);
1122
- }
1123
- function notBlankStringOrNull(value) {
1124
- if (value?.trim()) {
1125
- return value;
1126
- } else {
1127
- return null;
2437
+ async statuses(offerId) {
2438
+ return this.log.wrap("statuses", offerId, async () => {
2439
+ await this.ctx.ensureUserAuthenticated();
2440
+ return fetchRequirementStatuses(this.ctx.api, offerId);
2441
+ });
1128
2442
  }
1129
- }
2443
+ async createKycToken(params) {
2444
+ return this.log.wrap("createKycToken", params, async () => {
2445
+ await this.ctx.ensureUserAuthenticated();
2446
+ return createKycToken(
2447
+ this.ctx.api,
2448
+ params?.levelName,
2449
+ params?.reset
2450
+ );
2451
+ });
2452
+ }
2453
+ async getPii() {
2454
+ return this.log.wrap("getPii", void 0, async () => {
2455
+ await this.ctx.ensureUserAuthenticated();
2456
+ return fetchPii(this.ctx.api);
2457
+ });
2458
+ }
2459
+ async submitDocument(params) {
2460
+ return this.log.wrap("submitDocument", params, async () => {
2461
+ await this.ctx.ensureUserAuthenticated();
2462
+ return submitDocument(
2463
+ this.ctx.api,
2464
+ params.documentType,
2465
+ params.fields
2466
+ );
2467
+ });
2468
+ }
2469
+ };
1130
2470
 
1131
- // src/shared/types/offer-detail.ts
1132
- var OfferOptionId = (value) => value;
1133
- var OfferOptionSlug = (value) => value;
1134
- var OfferDetail = {
1135
- fromDto: (dto) => {
1136
- if (!Array.isArray(dto.funding_assets)) {
1137
- throw new Error(`funding_assets must be an array`);
1138
- }
1139
- if (!Array.isArray(dto.options)) {
1140
- throw new Error(`options must be an array`);
1141
- }
1142
- if (!Array.isArray(dto.terms)) {
1143
- throw new Error(`terms must be an array`);
2471
+ // src/shared/api/nabu/tokens.ts
2472
+ var import_viem4 = require("viem");
2473
+
2474
+ // src/shared/api/frontline/config.ts
2475
+ var HEADER_API_VERSION = "X-API-Version";
2476
+
2477
+ // src/shared/api/http-client.ts
2478
+ var HttpClient = class {
2479
+ constructor(config, middleware = {}, logger = null, options = {}) {
2480
+ this.config = config;
2481
+ this.middleware = middleware;
2482
+ this.log = internalLogger(logger, "HTTP");
2483
+ this.makeRequestId = options.makeRequestId ?? defaultMakeRequestId;
2484
+ }
2485
+ async send(request) {
2486
+ return this.runRequestWithAfterMiddleware(request);
2487
+ }
2488
+ /**
2489
+ * Runs beforeRequest, executeRequest, then the full afterRequest middleware
2490
+ * chain. Used by send() and by the retry() callback so that when a
2491
+ * middleware calls retry(), the retried response also goes through all
2492
+ * afterRequest middleware (e.g. session renewal, retry). Middleware
2493
+ * must use request.attributes.retryAttempt (or similar) to avoid infinite
2494
+ * recursion when they trigger retries.
2495
+ */
2496
+ async runRequestWithAfterMiddleware(request) {
2497
+ const preparedRequest = await this.runBeforeRequestMiddleware(
2498
+ this.withClientDefaults(request)
2499
+ );
2500
+ let response = await this.executeRequest(preparedRequest);
2501
+ for (const middleware of this.middleware.afterRequest ?? []) {
2502
+ response = await middleware({
2503
+ request: preparedRequest,
2504
+ response,
2505
+ retry: (nextRequest = preparedRequest) => this.runRequestWithAfterMiddleware(nextRequest)
2506
+ });
1144
2507
  }
1145
- if (!Array.isArray(dto.links)) {
1146
- throw new Error(`links must be an array`);
2508
+ return response;
2509
+ }
2510
+ withClientDefaults(request) {
2511
+ const url = this.resolveUrl(request.url);
2512
+ const headers = {
2513
+ ...request.headers ?? {},
2514
+ ...this.config.xApiVersion !== void 0 ? { [HEADER_API_VERSION]: this.config.xApiVersion } : {}
2515
+ };
2516
+ return {
2517
+ ...request,
2518
+ url,
2519
+ headers,
2520
+ // Only when absent: a retry or a post-renewal re-send arrives with the
2521
+ // first attempt's id already on it, and keeping it is the whole point.
2522
+ attributes: Attributes.getRequestId(request.attributes) === null ? Attributes.concat(
2523
+ request.attributes ?? Attributes.empty,
2524
+ Attributes.requestId(this.makeRequestId())
2525
+ ) : request.attributes
2526
+ };
2527
+ }
2528
+ /**
2529
+ * Resolves a request URL against the client's baseUrl.
2530
+ *
2531
+ * @internal Public only for testing. Do not use in application code; use
2532
+ * {@link HttpClient.send} with a path and the client will resolve the URL.
2533
+ */
2534
+ resolveUrl(url) {
2535
+ if (url.startsWith("http://") || url.startsWith("https://")) {
2536
+ return url;
1147
2537
  }
1148
- if (!Array.isArray(dto.faqs)) {
1149
- throw new Error(`faqs must be an array`);
2538
+ const base = this.config.baseUrl.replace(/\/$/, "");
2539
+ const path = url.startsWith("/") ? url : `/${url}`;
2540
+ return base + path;
2541
+ }
2542
+ async runBeforeRequestMiddleware(initialRequest) {
2543
+ let request = initialRequest;
2544
+ for (const middleware of this.middleware.beforeRequest ?? []) {
2545
+ request = await middleware(request);
1150
2546
  }
1151
- if (!Array.isArray(dto.milestones)) {
1152
- throw new Error(`milestones must be an array`);
2547
+ return request;
2548
+ }
2549
+ /**
2550
+ * One physical attempt, logged as one line.
2551
+ *
2552
+ * A non-2xx is a `warn` rather than an `error` because the wire does not
2553
+ * know whether it is a failure: the retry middleware may turn a 503 into a
2554
+ * success, and the token registry reads a 404 as "not listed". The namespace
2555
+ * above decides, and logs the `error` when it does.
2556
+ */
2557
+ async executeRequest(request) {
2558
+ const requestId2 = Attributes.getRequestId(request.attributes);
2559
+ const log = requestId2 === null ? this.log : this.log.child({ requestId: requestId2 });
2560
+ const attempt = Attributes.getRetryAttempt(request.attributes) + 1;
2561
+ const startedAt = Date.now();
2562
+ log.debug(() => ({
2563
+ msg: "request sent",
2564
+ fields: describeRequestUnredacted(request)
2565
+ }));
2566
+ try {
2567
+ const response = await makeRequest(request);
2568
+ const elapsed = Date.now() - startedAt;
2569
+ const outcome = () => ({
2570
+ msg: "request completed",
2571
+ fields: {
2572
+ ...identifyRequest(request),
2573
+ "http.response.status_code": response.status,
2574
+ duration_ms: elapsed,
2575
+ attempt
2576
+ }
2577
+ });
2578
+ if (response.status >= 200 && response.status < 300) {
2579
+ log.info(outcome);
2580
+ } else {
2581
+ log.warn(outcome);
2582
+ }
2583
+ log.debug(() => ({
2584
+ msg: "response received",
2585
+ fields: { body: response.body }
2586
+ }));
2587
+ return requestId2 === null ? response : { ...response, requestId: requestId2 };
2588
+ } catch (error) {
2589
+ const elapsed = Date.now() - startedAt;
2590
+ log.warning(
2591
+ () => ({
2592
+ msg: "request threw",
2593
+ fields: {
2594
+ ...identifyRequest(request),
2595
+ duration_ms: elapsed,
2596
+ attempt
2597
+ }
2598
+ }),
2599
+ error
2600
+ );
2601
+ throw error;
1153
2602
  }
1154
- return {
1155
- id: OfferId(dto.id),
1156
- slug: OfferSlug(dto.slug),
1157
- type: dto.type,
1158
- name: dto.name,
1159
- asset: Asset.fromDto(dto.asset),
1160
- fundingAssets: dto.funding_assets.map(Asset.fromDto),
1161
- about: notBlankStringOrNull(dto.about),
1162
- tagline: dto.tagline,
1163
- bannerUrl: dto.banner_url,
1164
- logoUrl: dto.logo_url,
1165
- category: dto.category,
1166
- startsAt: new Date(dto.starts_at),
1167
- endsAt: dto.ends_at ? new Date(dto.ends_at) : null,
1168
- faqs: dto.faqs.map(FaqItem.fromDto),
1169
- links: dto.links.map(Link.fromDto),
1170
- milestones: dto.milestones.map(Milestone.fromDto),
1171
- options: dto.options.map(OfferOption.fromDto),
1172
- terms: dto.terms.map(TermItem.fromDto)
1173
- };
1174
2603
  }
1175
2604
  };
1176
- var OfferOption = {
1177
- fromDto: (dto) => ({
1178
- id: OfferOptionId(dto.id),
1179
- slug: OfferOptionSlug(dto.slug),
1180
- bidIncrement: dto.bid_increment,
1181
- floorPriceUsd: dto.floor_price_usd,
1182
- minimumPurchaseUsd: dto.minimum_purchase_usd,
1183
- priceUsd: dto.price_usd,
1184
- saleAgreementUrl: notBlankStringOrNull(dto.sale_agreement_url),
1185
- totalTokenSupply: dto.total_token_supply
1186
- })
1187
- };
1188
- var FaqItem = {
1189
- fromDto: (dto) => ({
1190
- question: notBlankStringOrNull(dto.question),
1191
- answer: notBlankStringOrNull(dto.answer)
1192
- })
1193
- };
1194
- var Link = {
1195
- fromDto: (dto) => ({
1196
- label: notBlankStringOrNull(dto.label),
1197
- url: notBlankStringOrNull(dto.url)
1198
- })
2605
+ function identifyRequest(request) {
2606
+ const { host, path } = splitUrl(request.url);
2607
+ return {
2608
+ "http.request.method": request.method,
2609
+ "server.address": host,
2610
+ "url.path": path
2611
+ };
2612
+ }
2613
+ function splitUrl(url) {
2614
+ try {
2615
+ const parsed = new URL(url);
2616
+ return { host: parsed.host, path: parsed.pathname };
2617
+ } catch (_) {
2618
+ return { host: null, path: url };
2619
+ }
2620
+ }
2621
+ function defaultMakeRequestId() {
2622
+ return Math.random().toString(36).slice(2, 10).padEnd(8, "0");
2623
+ }
2624
+ function describeRequestUnredacted(request) {
2625
+ return {
2626
+ "http.request.method": request.method,
2627
+ "url.full": buildUrlWithQueryParams(request.url, request.queryParams),
2628
+ headers: request.headers,
2629
+ ...request.method === "POST" ? { body: request.body } : {}
2630
+ };
2631
+ }
2632
+
2633
+ // src/shared/types/token-metadata.ts
2634
+ var TokenLogoUrl = (value) => value;
2635
+ var TokenLogo = {
2636
+ /** `baseUrl` is the registry origin; registry URLs are root-relative. */
2637
+ fromDto: (dto, baseUrl) => dto.kind === "VECTOR" ? { kind: "VECTOR", url: resolveLogoUrl(dto.url, baseUrl) } : {
2638
+ kind: "RASTER",
2639
+ original: logoImageFromDto(dto.original, baseUrl),
2640
+ variants: dto.variants.map((v) => logoImageFromDto(v, baseUrl))
2641
+ }
1199
2642
  };
1200
- var TermItem = {
1201
- fromDto: (dto) => ({
1202
- key: notBlankStringOrNull(dto.key),
1203
- value: notBlankStringOrNull(dto.value)
1204
- })
2643
+ var TokenMetadata = {
2644
+ /** `baseUrl` is the registry origin; registry logo URLs are root-relative. */
2645
+ fromDto: (dto, baseUrl) => {
2646
+ assertSupportedSchemaVersion(dto.schema_version);
2647
+ return {
2648
+ identifier: {
2649
+ chain: EthereumChain(dto.chain),
2650
+ address: EvmContractAddress(dto.address)
2651
+ },
2652
+ name: dto.name,
2653
+ symbol: AssetSymbol(dto.symbol),
2654
+ decimals: AssetDecimals(dto.decimals),
2655
+ logo: TokenLogo.fromDto(dto.logo, baseUrl),
2656
+ logoDark: dto.logo_dark === void 0 ? null : TokenLogo.fromDto(dto.logo_dark, baseUrl)
2657
+ };
2658
+ },
2659
+ /**
2660
+ * Maps the complete registry snapshot to every token it lists across the
2661
+ * chains this SDK models, skipping native coins and chains outside
2662
+ * {@link EthereumChain} (e.g. Solana) rather than failing on them — the
2663
+ * registry may serve chains ahead of the SDK's type surface.
2664
+ */
2665
+ fromRegistryDto: (dto, baseUrl) => {
2666
+ assertSupportedSchemaVersion(dto.schema_version);
2667
+ return dto.chains.flatMap((chainDto) => {
2668
+ let chain;
2669
+ try {
2670
+ chain = EthereumChain(chainDto.chain);
2671
+ } catch {
2672
+ return [];
2673
+ }
2674
+ return tokensOfChain(chain, chainDto.assets, baseUrl);
2675
+ });
2676
+ },
2677
+ /**
2678
+ * Maps a chain snapshot to the tokens it lists, skipping the chain's native
2679
+ * coin (`kind: 'COIN'`, no contract address).
2680
+ */
2681
+ fromChainAssetsDto: (dto, baseUrl) => {
2682
+ assertSupportedSchemaVersion(dto.schema_version);
2683
+ return tokensOfChain(EthereumChain(dto.chain), dto.assets, baseUrl);
2684
+ }
1205
2685
  };
1206
- var Milestone = {
1207
- fromDto: (dto) => ({
1208
- name: notBlankStringOrNull(dto.name),
1209
- schedule: notBlankStringOrNull(dto.schedule),
1210
- status: dto.status
1211
- })
2686
+ function tokensOfChain(chain, assets, baseUrl) {
2687
+ return assets.filter((asset) => asset.kind === "TOKEN" && asset.address !== void 0).map((asset) => ({
2688
+ identifier: {
2689
+ chain,
2690
+ // The filter above cannot narrow `address` for the type checker.
2691
+ address: EvmContractAddress(asset.address)
2692
+ },
2693
+ name: asset.name,
2694
+ symbol: AssetSymbol(asset.symbol),
2695
+ decimals: AssetDecimals(asset.decimals),
2696
+ logo: TokenLogo.fromDto(asset.logo, baseUrl),
2697
+ logoDark: asset.logo_dark === void 0 ? null : TokenLogo.fromDto(asset.logo_dark, baseUrl)
2698
+ }));
2699
+ }
2700
+ function assertSupportedSchemaVersion(version) {
2701
+ if (version !== 1) {
2702
+ throw new ValidationError(
2703
+ `Unsupported token registry schema_version: ${version}`
2704
+ );
2705
+ }
2706
+ }
2707
+ var logoImageFromDto = (dto, baseUrl) => ({
2708
+ url: resolveLogoUrl(dto.url, baseUrl),
2709
+ width: dto.width,
2710
+ height: dto.height
2711
+ });
2712
+ var resolveLogoUrl = (url, baseUrl) => TokenLogoUrl(
2713
+ url.startsWith("http") ? url : `${baseUrl.replace(/\/$/, "")}${url}`
2714
+ );
2715
+
2716
+ // src/shared/api/nabu/tokens.ts
2717
+ function createNabuApiClient(baseUrl, logger = null) {
2718
+ return new HttpClient({ baseUrl }, {}, logger);
2719
+ }
2720
+ async function fetchTokenMetadata(client, token) {
2721
+ const address = checksummed(token.address);
2722
+ let response;
2723
+ try {
2724
+ response = await client.send({
2725
+ method: "GET",
2726
+ url: `/${token.chain}/token/${address}`
2727
+ });
2728
+ } catch (error) {
2729
+ if (isRegistryHtmlFallback(error)) {
2730
+ return null;
2731
+ }
2732
+ throw error;
2733
+ }
2734
+ if (response.status === 404) {
2735
+ return null;
2736
+ }
2737
+ assertOk(response);
2738
+ if (response.body === null) {
2739
+ throw new ValidationError(
2740
+ `Token registry returned an empty body for token "${address}" on "${token.chain}"`
2741
+ );
2742
+ }
2743
+ return TokenMetadata.fromDto(response.body, client.config.baseUrl);
2744
+ }
2745
+ async function fetchTokensMetadata(client, chain) {
2746
+ let response;
2747
+ try {
2748
+ response = await client.send({
2749
+ method: "GET",
2750
+ url: `/${chain}/assets.json`
2751
+ });
2752
+ } catch (error) {
2753
+ if (isRegistryHtmlFallback(error)) {
2754
+ throw new ValidationError(
2755
+ `Token registry returned non-JSON for the "${chain}" snapshot`
2756
+ );
2757
+ }
2758
+ throw error;
2759
+ }
2760
+ assertOk(response);
2761
+ if (response.body === null) {
2762
+ throw new ValidationError(
2763
+ `Token registry returned an empty "${chain}" snapshot`
2764
+ );
2765
+ }
2766
+ return TokenMetadata.fromChainAssetsDto(response.body, client.config.baseUrl);
2767
+ }
2768
+ async function fetchAllTokensMetadata(client) {
2769
+ let response;
2770
+ try {
2771
+ response = await client.send({
2772
+ method: "GET",
2773
+ url: `/assets.json`
2774
+ });
2775
+ } catch (error) {
2776
+ if (isRegistryHtmlFallback(error)) {
2777
+ throw new ValidationError(
2778
+ "Token registry returned non-JSON for the complete snapshot"
2779
+ );
2780
+ }
2781
+ throw error;
2782
+ }
2783
+ assertOk(response);
2784
+ if (response.body === null) {
2785
+ throw new ValidationError(
2786
+ "Token registry returned an empty complete snapshot"
2787
+ );
2788
+ }
2789
+ return TokenMetadata.fromRegistryDto(response.body, client.config.baseUrl);
2790
+ }
2791
+ function isRegistryHtmlFallback(error) {
2792
+ return error instanceof HttpError && error.response.status >= 200 && error.response.status < 300;
2793
+ }
2794
+ function assertOk(response) {
2795
+ if (response.status < 200 || response.status >= 300) {
2796
+ throw new HttpError(response);
2797
+ }
2798
+ }
2799
+ function checksummed(address) {
2800
+ try {
2801
+ return (0, import_viem4.getAddress)(address);
2802
+ } catch (_) {
2803
+ throw new ValidationError(`Invalid EVM contract address: "${address}"`);
2804
+ }
2805
+ }
2806
+
2807
+ // src/shared/core/tokens/tokens-namespace.ts
2808
+ var TokensNamespaceImpl = class {
2809
+ /**
2810
+ * Takes the registry origin rather than a `SharedNamespaceContext`: the
2811
+ * registry is unauthenticated and on its own host, so the frontline sender
2812
+ * and the auth check would both be dead weight here.
2813
+ */
2814
+ constructor(baseUrl, logger = null) {
2815
+ this.api = createNabuApiClient(baseUrl, logger);
2816
+ this.log = internalLogger(logger, "TOKENS");
2817
+ }
2818
+ get(token) {
2819
+ return this.log.wrap(
2820
+ "get",
2821
+ token,
2822
+ () => fetchTokenMetadata(this.api, token)
2823
+ );
2824
+ }
2825
+ list(chain) {
2826
+ return this.log.wrap(
2827
+ "list",
2828
+ chain,
2829
+ () => chain === void 0 ? fetchAllTokensMetadata(this.api) : fetchTokensMetadata(this.api, chain)
2830
+ );
2831
+ }
1212
2832
  };
1213
2833
 
1214
2834
  // src/shared/types/offer-option-address.ts
@@ -1282,195 +2902,79 @@ async function createWalletOwnershipChallenge(api, params) {
1282
2902
  });
1283
2903
  return WalletOwnershipChallenge.fromDto(dto);
1284
2904
  }
1285
-
1286
- // src/shared/core/swap-namespace.ts
1287
- var SwapNamespaceImpl = class {
1288
- constructor(ctx) {
1289
- this.ctx = ctx;
1290
- }
1291
- async getAuthorization(params) {
1292
- await this.ctx.ensureUserAuthenticated();
1293
- return getSwapAuthorization(this.ctx.api, params);
1294
- }
1295
- async getPreview(params) {
1296
- await this.ctx.ensureUserAuthenticated();
1297
- return getSwapPreview(this.ctx.api, params);
1298
- }
1299
- async getStatus(params) {
1300
- await this.ctx.ensureUserAuthenticated();
1301
- return getSwapStatus(this.ctx.api, params);
1302
- }
1303
- async getOutputToken(params) {
1304
- await this.ctx.ensureUserAuthenticated();
1305
- return getSwapOutputToken(this.ctx.api, params);
1306
- }
1307
- async requestWalletOwnershipChallenge(params) {
1308
- await this.ctx.ensureUserAuthenticated();
1309
- return createWalletOwnershipChallenge(this.ctx.api, params);
1310
- }
1311
- async allowWallet(params) {
1312
- await this.ctx.ensureUserAuthenticated();
1313
- return allowWallet(this.ctx.api, params);
1314
- }
1315
- };
1316
-
1317
- // src/shared/types/participation.ts
1318
- var ParticipationId = (value) => value;
1319
- var Blockchain = (value) => value;
1320
- var WalletAddress = (value) => value;
1321
- var ParticipationsPaginationParams = {
1322
- toQueryParams: (params) => {
1323
- const queryParams = PaginationParams.toQueryParams(params);
1324
- if (params.offerId) {
1325
- queryParams["filters[0][field]"] = "offer_id";
1326
- queryParams["filters[0][op]"] = "==";
1327
- queryParams["filters[0][value]"] = params.offerId;
1328
- }
1329
- return queryParams;
1330
- }
1331
- };
1332
- var Participation = {
1333
- /** Maps API DTO shape into the SDK participation domain model. */
1334
- fromDto: (dto) => {
1335
- const walletAddress = notBlankStringOrNull(dto.wallet_address);
1336
- return {
1337
- id: ParticipationId(dto.id),
1338
- offerId: OfferId(dto.offer_id),
1339
- offerOptionId: OfferOptionId(dto.offer_option_id),
1340
- status: dto.status,
1341
- amount: dto.amount,
1342
- displayAmount: dto.amount_string,
1343
- asset: Asset.fromDto(dto.asset),
1344
- chain: Blockchain(dto.chain),
1345
- insertedAt: dto.inserted_at ? new Date(dto.inserted_at) : null,
1346
- updatedAt: dto.updated_at ? new Date(dto.updated_at) : null,
1347
- walletAddress: walletAddress ? WalletAddress(walletAddress) : null
1348
- };
1349
- }
1350
- };
1351
- var CreateParticipationParams = {
1352
- /** Maps participation creation params into API DTO payload. */
1353
- toDto: (params) => ({
1354
- offer_id: params.offerId,
1355
- offer_option_id: params.offerOptionId,
1356
- chain: params.chain,
1357
- wallet_address: params.walletAddress,
1358
- amount: params.amount,
1359
- asset_id: params.assetId,
1360
- approval_transaction_hash: params.approvalTransactionHash
1361
- })
1362
- };
1363
-
1364
- // src/shared/api/frontline/participations.ts
1365
- async function fetchParticipations(api, offerId) {
1366
- return fetchAllPages(
1367
- (params) => fetchParticipationsPage(api, params),
1368
- { offerId }
1369
- );
1370
- }
1371
- async function fetchParticipationsPage(api, params) {
1372
- const pageDto = await api.send({
1373
- method: "GET",
1374
- url: "/v1/participations",
1375
- queryParams: ParticipationsPaginationParams.toQueryParams(params),
2905
+ async function connectExternalWallet(api, params) {
2906
+ const dto = await api.send({
2907
+ method: "POST",
2908
+ url: `/v1/offers/${params.offerId}/addresses`,
2909
+ body: ConnectExternalWalletParams.toDto(params),
1376
2910
  attributes: Attributes.protected()
1377
2911
  });
1378
- return PaginatedResponse.fromDto(pageDto, Participation.fromDto);
2912
+ return OfferOptionAddress.fromDto(dto);
1379
2913
  }
1380
- async function fetchParticipation(api, id) {
1381
- const dto = await api.send({
2914
+ async function listOptionAddresses(api, offerId, offerOptionId) {
2915
+ const { data } = await api.send({
1382
2916
  method: "GET",
1383
- url: `/v1/participations/${id}`,
2917
+ url: `/v1/offers/${offerId}/addresses`,
2918
+ queryParams: { offer_option_id: offerOptionId },
1384
2919
  attributes: Attributes.protected()
1385
2920
  });
1386
- return Participation.fromDto(dto);
2921
+ return data.map(OfferOptionAddress.fromDto);
1387
2922
  }
1388
- async function createParticipation(api, params) {
2923
+ async function removeOptionAddress(api, offerId, addressId) {
1389
2924
  const dto = await api.send({
1390
- method: "POST",
1391
- url: "/v1/participations",
1392
- body: CreateParticipationParams.toDto(params),
2925
+ method: "DELETE",
2926
+ url: `/v1/offers/${offerId}/addresses/${addressId}`,
1393
2927
  attributes: Attributes.protected()
1394
2928
  });
1395
- return Participation.fromDto(dto);
2929
+ return OfferOptionAddress.fromDto(dto);
1396
2930
  }
1397
2931
 
1398
- // src/shared/core/token-sale-namespace.ts
1399
- var TokenSaleNamespaceImpl = class {
2932
+ // src/shared/core/wallets/wallets-namespace.ts
2933
+ var WalletsNamespaceImpl = class {
1400
2934
  constructor(ctx) {
1401
2935
  this.ctx = ctx;
2936
+ this.log = internalLogger(ctx.logger, "WALLETS");
1402
2937
  }
1403
- async fetchParticipations(offerId) {
1404
- await this.ctx.ensureUserAuthenticated();
1405
- return fetchParticipations(this.ctx.api, offerId);
1406
- }
1407
- async fetchParticipationsPage(params) {
1408
- await this.ctx.ensureUserAuthenticated();
1409
- return fetchParticipationsPage(this.ctx.api, params);
1410
- }
1411
- async fetchParticipation(id) {
1412
- await this.ctx.ensureUserAuthenticated();
1413
- return fetchParticipation(this.ctx.api, id);
2938
+ async createOwnershipChallenge(params) {
2939
+ return this.log.wrap("createOwnershipChallenge", params, async () => {
2940
+ await this.ctx.ensureUserAuthenticated();
2941
+ return createWalletOwnershipChallenge(
2942
+ this.ctx.api,
2943
+ params
2944
+ );
2945
+ });
1414
2946
  }
1415
- async createParticipation(params) {
1416
- await this.ctx.ensureUserAuthenticated();
1417
- return createParticipation(this.ctx.api, params);
2947
+ async connectExternal(params) {
2948
+ return this.log.wrap("connectExternal", params, async () => {
2949
+ await this.ctx.ensureUserAuthenticated();
2950
+ return connectExternalWallet(this.ctx.api, params);
2951
+ });
1418
2952
  }
1419
- };
1420
-
1421
- // src/shared/types/oauth.ts
1422
- var AuthorizationCode = (value) => value;
1423
- var CodeVerifier = (value) => value;
1424
- var CodeChallenge = (value) => value;
1425
- var PKCEState = (value) => value;
1426
- var RedirectUri = (value) => value;
1427
- var ClientId = (value) => value;
1428
- var ClientSecret = (value) => value;
1429
-
1430
- // src/shared/pkce.ts
1431
- async function generatePKCEParams(config) {
1432
- const state = generateSecureRandomBase64Url(32);
1433
- const codeVerifier = generateSecureRandomBase64Url(32);
1434
- const codeChallengeRaw = await sha256(codeVerifier);
1435
- const codeChallenge = arrayBufferToBase64Url(codeChallengeRaw, false);
1436
- return {
1437
- clientId: config.clientId,
1438
- responseType: "code",
1439
- redirectUri: config.redirectUri,
1440
- codeChallenge: CodeChallenge(codeChallenge),
1441
- codeChallengeMethod: "S256",
1442
- state: PKCEState(state),
1443
- codeVerifier: CodeVerifier(codeVerifier)
1444
- };
1445
- }
1446
-
1447
- // src/shared/types/document-submission.ts
1448
- var DocumentSubmission = {
1449
- fromDto: (dto) => ({
1450
- status: dto.status,
1451
- formType: dto.form_type
1452
- })
1453
- };
1454
-
1455
- // src/shared/types/errors.ts
1456
- var NotImplementedError = class extends Error {
1457
- constructor(message = "Not implemented yet") {
1458
- super(message);
1459
- this.name = "NotImplementedError";
2953
+ async list(params) {
2954
+ return this.log.wrap("list", params, async () => {
2955
+ await this.ctx.ensureUserAuthenticated();
2956
+ return listOptionAddresses(
2957
+ this.ctx.api,
2958
+ params.offerId,
2959
+ params.offerOptionId
2960
+ );
2961
+ });
1460
2962
  }
1461
- };
1462
- var NotAuthenticatedError = class extends Error {
1463
- constructor(message = "The user is not authenticated. Go through the OAuth flow first!") {
1464
- super(message);
1465
- this.name = "NotAuthenticatedError";
2963
+ async remove(params) {
2964
+ return this.log.wrap("remove", params, async () => {
2965
+ await this.ctx.ensureUserAuthenticated();
2966
+ return removeOptionAddress(
2967
+ this.ctx.api,
2968
+ params.offerId,
2969
+ params.addressId
2970
+ );
2971
+ });
1466
2972
  }
1467
2973
  };
1468
2974
 
1469
- // src/shared/types/kyc.ts
1470
- var KycToken = {
1471
- fromDto: (dto) => ({
1472
- token: dto.token
1473
- })
2975
+ // src/shared/types/blockchain/wallet-error.ts
2976
+ var RedactedWalletError = {
2977
+ fromWalletError: (error) => error.type === "unknown" ? { type: "unknown" } : error
1474
2978
  };
1475
2979
 
1476
2980
  // src/shared/types/oauth-session.ts
@@ -1489,55 +2993,6 @@ var OAuthSession = {
1489
2993
  }
1490
2994
  };
1491
2995
 
1492
- // src/shared/types/pii.ts
1493
- var Iso2CountryCode = (value) => value;
1494
- var PiiJurisdiction = {
1495
- fromDto: (dto) => ({
1496
- iso2: Iso2CountryCode(dto.iso_2),
1497
- name: dto.name
1498
- })
1499
- };
1500
- var PiiAddress = {
1501
- fromDto: (dto) => ({
1502
- street: dto.street,
1503
- city: dto.city,
1504
- state: dto.state,
1505
- postalCode: dto.postal_code,
1506
- country: dto.country
1507
- })
1508
- };
1509
- var Pii = {
1510
- fromDto: (dto) => ({
1511
- kind: dto.kind,
1512
- fullLegalName: dto.full_legal_name,
1513
- dateOfBirth: dto.date_of_birth,
1514
- jurisdiction: dto.jurisdiction ? PiiJurisdiction.fromDto(dto.jurisdiction) : null,
1515
- taxId: dto.tax_id,
1516
- permanentAddress: PiiAddress.fromDto(dto.permanent_address)
1517
- })
1518
- };
1519
-
1520
- // src/shared/types/requirement.ts
1521
- var RequirementId = (value) => value;
1522
- var Requirement = {
1523
- fromDto: (dto) => ({
1524
- id: RequirementId(dto.id),
1525
- type: dto.type,
1526
- details: dto.details
1527
- })
1528
- };
1529
- var RequirementStatusInfo = {
1530
- fromStatusesDto: (dto) => Object.entries(dto.statuses).map(
1531
- ([id, value]) => typeof value === "string" ? { id: RequirementId(id), status: value, action: null } : {
1532
- id: RequirementId(id),
1533
- status: value.status,
1534
- action: value.action ?? null,
1535
- kycLevel: value.kyc_level,
1536
- kycReset: value.kyc_reset
1537
- }
1538
- )
1539
- };
1540
-
1541
2996
  // src/shared/types/user.ts
1542
2997
  var UserId = (value) => value;
1543
2998
  var UserEmail = (value) => value;
@@ -1561,20 +3016,27 @@ var User = {
1561
3016
  Blockchain,
1562
3017
  BlockchainAmount,
1563
3018
  Bps,
3019
+ Chain,
1564
3020
  ClientCredentialsOAuth,
1565
3021
  ClientId,
1566
3022
  ClientSecret,
1567
3023
  CodeChallenge,
1568
3024
  CodeVerifier,
3025
+ CoinListTokenSaleNamespaceImpl,
1569
3026
  ConnectExternalWalletParams,
1570
3027
  CreateParticipationParams,
1571
3028
  CreateWalletOwnershipChallengeParams,
1572
3029
  Cursor,
1573
3030
  DEFAULT_AMOUNT_TO_COMPUTE_PRICE,
3031
+ DEFAULT_ONDO_AMOUNT_TO_COMPUTE_PRICE,
3032
+ DEFAULT_ONDO_SELL_TOKENS_TO_COMPUTE_PRICE,
1574
3033
  DEFAULT_SLIPPAGE_BPS,
3034
+ DecimalString,
1575
3035
  DocumentSubmission,
1576
3036
  ERC20_ABI,
3037
+ ETHEREUM_CHAINS,
1577
3038
  Erc20NamespaceImpl,
3039
+ EthereumChain,
1578
3040
  EvmContractAddress,
1579
3041
  EvmWalletAddress,
1580
3042
  FaqItem,
@@ -1582,17 +3044,25 @@ var User = {
1582
3044
  FormattedAmountUi,
1583
3045
  FormattedPercentUi,
1584
3046
  HexEncodedTransactionData,
3047
+ HttpError,
3048
+ InvariantError,
1585
3049
  Iso2CountryCode,
1586
3050
  KnownAssetSymbol,
1587
3051
  KycToken,
1588
3052
  Link,
3053
+ MAX_ASSET_DECIMALS,
1589
3054
  MAX_UINT_256,
3055
+ MathError,
1590
3056
  Milestone,
1591
3057
  NA_AMOUNT_ASSET_UI,
1592
3058
  NotAuthenticatedError,
1593
3059
  NotImplementedError,
1594
3060
  OAuthRefreshToken,
1595
3061
  OAuthSession,
3062
+ ONDO_POLL_INTERVAL_MS,
3063
+ ONDO_QUOTE_EXPIRY_THRESHOLD_MS,
3064
+ ONDO_SETTLEMENT_ASSET,
3065
+ ONDO_SUPPORTED_INPUT_ASSETS,
1596
3066
  Offer,
1597
3067
  OfferDetail,
1598
3068
  OfferId,
@@ -1602,6 +3072,13 @@ var User = {
1602
3072
  OfferOptionId,
1603
3073
  OfferOptionSlug,
1604
3074
  OfferSlug,
3075
+ OfferToken,
3076
+ OffersNamespaceImpl,
3077
+ OndoBuyTransaction,
3078
+ OndoNamespaceImpl,
3079
+ OndoQuote,
3080
+ OndoSellTransaction,
3081
+ OndoTradingStatus,
1605
3082
  PKCEState,
1606
3083
  PaginatedResponse,
1607
3084
  PaginationParams,
@@ -1611,27 +3088,37 @@ var User = {
1611
3088
  Pii,
1612
3089
  PiiAddress,
1613
3090
  PiiJurisdiction,
3091
+ RedactedWalletError,
1614
3092
  RedirectUri,
1615
3093
  Requirement,
1616
3094
  RequirementId,
1617
3095
  RequirementStatusInfo,
3096
+ RequirementsNamespaceImpl,
1618
3097
  SLIPPAGE_OPTIONS_BPS,
3098
+ SOLANA_CHAINS,
3099
+ STABLE_DECIMALS,
3100
+ SUPERSTATE_ISSUER_NAME,
3101
+ SUPERSTATE_SUPPORTED_INPUT_ASSETS,
1619
3102
  SUPERSTATE_SWAP_ABI,
1620
3103
  SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA,
1621
- SUPERSTATE_TOS_URL,
1622
3104
  SWAP_POLL_INTERVAL_MS,
1623
3105
  ShortenedWalletAddress,
3106
+ SolanaChain,
1624
3107
  StablecoinSymbol,
3108
+ SuperstateSwapNamespaceImpl,
1625
3109
  SwapAuthorization,
1626
- SwapNamespaceImpl,
1627
3110
  SwapPreview,
1628
3111
  SwapQuote,
1629
3112
  SwapStatus,
1630
3113
  TOKEN_REGISTRY,
1631
3114
  TermItem,
3115
+ Ticker,
1632
3116
  TokenAllowance,
1633
3117
  TokenBalance,
1634
- TokenSaleNamespaceImpl,
3118
+ TokenLogo,
3119
+ TokenLogoUrl,
3120
+ TokenMetadata,
3121
+ TokensNamespaceImpl,
1635
3122
  TxExplorerUrl,
1636
3123
  USDC,
1637
3124
  USDC_SYMBOL,
@@ -1640,11 +3127,18 @@ var User = {
1640
3127
  User,
1641
3128
  UserEmail,
1642
3129
  UserId,
3130
+ ValidationError,
1643
3131
  WalletAddress,
1644
3132
  WalletOwnershipChallenge,
3133
+ WalletsNamespaceImpl,
3134
+ apiErrorCode,
1645
3135
  applyBps,
1646
3136
  assertUint256,
1647
3137
  assetAmount,
3138
+ blockchainAmountFromRawOrThrow,
3139
+ chainFromId,
3140
+ computeOndoBuyPrice,
3141
+ computeOndoSellPrice,
1648
3142
  computePrice,
1649
3143
  computeSlip,
1650
3144
  decodeSwappedOutputAmount,
@@ -1659,8 +3153,11 @@ var User = {
1659
3153
  getChainId,
1660
3154
  getNetworkName,
1661
3155
  isStopped,
3156
+ ondoSwapContractAddress,
1662
3157
  parseBlockchainAmount,
3158
+ parseUint256,
1663
3159
  shortenAddress,
3160
+ superstateSwapContractAddress,
1664
3161
  txExplorerUrl,
1665
3162
  usdAmount
1666
3163
  });