@coinlist-co/react 0.10.1 → 0.11.0
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.
- package/README.md +32 -0
- package/dist/{chunk-AQVCOWOV.js → chunk-B2HCVPCQ.js} +202 -318
- package/dist/chunk-B2HCVPCQ.js.map +1 -0
- package/dist/chunk-KDGNDAHA.js +146 -0
- package/dist/chunk-KDGNDAHA.js.map +1 -0
- package/dist/chunk-UIIXXLA7.js +1863 -0
- package/dist/chunk-UIIXXLA7.js.map +1 -0
- package/dist/client/index.cjs +10382 -3262
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +4219 -862
- package/dist/client/index.d.ts +4219 -862
- package/dist/client/index.js +8727 -2369
- package/dist/client/index.js.map +1 -1
- package/dist/collections-BhDkYmzV.d.cts +65 -0
- package/dist/collections-CZhHoQHr.d.ts +65 -0
- package/dist/config-B5mwS_2l.d.cts +1926 -0
- package/dist/config-B5mwS_2l.d.ts +1926 -0
- package/dist/server/index.cjs +981 -464
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +190 -163
- package/dist/server/index.d.ts +190 -163
- package/dist/server/index.js +151 -154
- package/dist/server/index.js.map +1 -1
- package/dist/shared/index.cjs +1810 -907
- package/dist/shared/index.cjs.map +1 -1
- package/dist/shared/index.d.cts +243 -132
- package/dist/shared/index.d.ts +243 -132
- package/dist/shared/index.js +96 -28
- package/package.json +10 -7
- package/dist/chunk-AQVCOWOV.js.map +0 -1
- package/dist/chunk-TBU3EBNM.js +0 -442
- package/dist/chunk-TBU3EBNM.js.map +0 -1
- package/dist/chunk-UOHD7US2.js +0 -855
- package/dist/chunk-UOHD7US2.js.map +0 -1
- package/dist/collections-Bv1Oxzu_.d.ts +0 -28
- package/dist/collections-DDyxbOPZ.d.cts +0 -28
- package/dist/requirement-oVZA1INj.d.cts +0 -1040
- package/dist/requirement-oVZA1INj.d.ts +0 -1040
package/dist/shared/index.cjs
CHANGED
|
@@ -32,20 +32,26 @@ __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,
|
|
45
48
|
DEFAULT_SLIPPAGE_BPS: () => DEFAULT_SLIPPAGE_BPS,
|
|
49
|
+
DecimalString: () => DecimalString,
|
|
46
50
|
DocumentSubmission: () => DocumentSubmission,
|
|
47
51
|
ERC20_ABI: () => ERC20_ABI,
|
|
52
|
+
ETHEREUM_CHAINS: () => ETHEREUM_CHAINS,
|
|
48
53
|
Erc20NamespaceImpl: () => Erc20NamespaceImpl,
|
|
54
|
+
EthereumChain: () => EthereumChain,
|
|
49
55
|
EvmContractAddress: () => EvmContractAddress,
|
|
50
56
|
EvmWalletAddress: () => EvmWalletAddress,
|
|
51
57
|
FaqItem: () => FaqItem,
|
|
@@ -53,10 +59,12 @@ __export(shared_exports, {
|
|
|
53
59
|
FormattedAmountUi: () => FormattedAmountUi,
|
|
54
60
|
FormattedPercentUi: () => FormattedPercentUi,
|
|
55
61
|
HexEncodedTransactionData: () => HexEncodedTransactionData,
|
|
62
|
+
HttpError: () => HttpError,
|
|
56
63
|
Iso2CountryCode: () => Iso2CountryCode,
|
|
57
64
|
KnownAssetSymbol: () => KnownAssetSymbol,
|
|
58
65
|
KycToken: () => KycToken,
|
|
59
66
|
Link: () => Link,
|
|
67
|
+
MAX_ASSET_DECIMALS: () => MAX_ASSET_DECIMALS,
|
|
60
68
|
MAX_UINT_256: () => MAX_UINT_256,
|
|
61
69
|
Milestone: () => Milestone,
|
|
62
70
|
NA_AMOUNT_ASSET_UI: () => NA_AMOUNT_ASSET_UI,
|
|
@@ -64,6 +72,9 @@ __export(shared_exports, {
|
|
|
64
72
|
NotImplementedError: () => NotImplementedError,
|
|
65
73
|
OAuthRefreshToken: () => OAuthRefreshToken,
|
|
66
74
|
OAuthSession: () => OAuthSession,
|
|
75
|
+
ONDO_POLL_INTERVAL_MS: () => ONDO_POLL_INTERVAL_MS,
|
|
76
|
+
ONDO_QUOTE_EXPIRY_THRESHOLD_MS: () => ONDO_QUOTE_EXPIRY_THRESHOLD_MS,
|
|
77
|
+
ONDO_SUPPORTED_INPUT_ASSETS: () => ONDO_SUPPORTED_INPUT_ASSETS,
|
|
67
78
|
Offer: () => Offer,
|
|
68
79
|
OfferDetail: () => OfferDetail,
|
|
69
80
|
OfferId: () => OfferId,
|
|
@@ -73,6 +84,12 @@ __export(shared_exports, {
|
|
|
73
84
|
OfferOptionId: () => OfferOptionId,
|
|
74
85
|
OfferOptionSlug: () => OfferOptionSlug,
|
|
75
86
|
OfferSlug: () => OfferSlug,
|
|
87
|
+
OfferToken: () => OfferToken,
|
|
88
|
+
OffersNamespaceImpl: () => OffersNamespaceImpl,
|
|
89
|
+
OndoNamespaceImpl: () => OndoNamespaceImpl,
|
|
90
|
+
OndoQuote: () => OndoQuote,
|
|
91
|
+
OndoSwapTransaction: () => OndoSwapTransaction,
|
|
92
|
+
OndoTradingStatus: () => OndoTradingStatus,
|
|
76
93
|
PKCEState: () => PKCEState,
|
|
77
94
|
PaginatedResponse: () => PaginatedResponse,
|
|
78
95
|
PaginationParams: () => PaginationParams,
|
|
@@ -86,23 +103,32 @@ __export(shared_exports, {
|
|
|
86
103
|
Requirement: () => Requirement,
|
|
87
104
|
RequirementId: () => RequirementId,
|
|
88
105
|
RequirementStatusInfo: () => RequirementStatusInfo,
|
|
106
|
+
RequirementsNamespaceImpl: () => RequirementsNamespaceImpl,
|
|
89
107
|
SLIPPAGE_OPTIONS_BPS: () => SLIPPAGE_OPTIONS_BPS,
|
|
108
|
+
SOLANA_CHAINS: () => SOLANA_CHAINS,
|
|
109
|
+
STABLE_DECIMALS: () => STABLE_DECIMALS,
|
|
110
|
+
SUPERSTATE_ISSUER_NAME: () => SUPERSTATE_ISSUER_NAME,
|
|
111
|
+
SUPERSTATE_SUPPORTED_INPUT_ASSETS: () => SUPERSTATE_SUPPORTED_INPUT_ASSETS,
|
|
90
112
|
SUPERSTATE_SWAP_ABI: () => SUPERSTATE_SWAP_ABI,
|
|
91
113
|
SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA: () => SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA,
|
|
92
|
-
SUPERSTATE_TOS_URL: () => SUPERSTATE_TOS_URL,
|
|
93
114
|
SWAP_POLL_INTERVAL_MS: () => SWAP_POLL_INTERVAL_MS,
|
|
94
115
|
ShortenedWalletAddress: () => ShortenedWalletAddress,
|
|
116
|
+
SolanaChain: () => SolanaChain,
|
|
95
117
|
StablecoinSymbol: () => StablecoinSymbol,
|
|
118
|
+
SuperstateSwapNamespaceImpl: () => SuperstateSwapNamespaceImpl,
|
|
96
119
|
SwapAuthorization: () => SwapAuthorization,
|
|
97
|
-
SwapNamespaceImpl: () => SwapNamespaceImpl,
|
|
98
120
|
SwapPreview: () => SwapPreview,
|
|
99
121
|
SwapQuote: () => SwapQuote,
|
|
100
122
|
SwapStatus: () => SwapStatus,
|
|
101
123
|
TOKEN_REGISTRY: () => TOKEN_REGISTRY,
|
|
102
124
|
TermItem: () => TermItem,
|
|
125
|
+
Ticker: () => Ticker,
|
|
103
126
|
TokenAllowance: () => TokenAllowance,
|
|
104
127
|
TokenBalance: () => TokenBalance,
|
|
105
|
-
|
|
128
|
+
TokenLogo: () => TokenLogo,
|
|
129
|
+
TokenLogoUrl: () => TokenLogoUrl,
|
|
130
|
+
TokenMetadata: () => TokenMetadata,
|
|
131
|
+
TokensNamespaceImpl: () => TokensNamespaceImpl,
|
|
106
132
|
TxExplorerUrl: () => TxExplorerUrl,
|
|
107
133
|
USDC: () => USDC,
|
|
108
134
|
USDC_SYMBOL: () => USDC_SYMBOL,
|
|
@@ -111,11 +137,17 @@ __export(shared_exports, {
|
|
|
111
137
|
User: () => User,
|
|
112
138
|
UserEmail: () => UserEmail,
|
|
113
139
|
UserId: () => UserId,
|
|
140
|
+
ValidationError: () => ValidationError,
|
|
114
141
|
WalletAddress: () => WalletAddress,
|
|
115
142
|
WalletOwnershipChallenge: () => WalletOwnershipChallenge,
|
|
143
|
+
WalletsNamespaceImpl: () => WalletsNamespaceImpl,
|
|
144
|
+
apiErrorCode: () => apiErrorCode,
|
|
116
145
|
applyBps: () => applyBps,
|
|
117
146
|
assertUint256: () => assertUint256,
|
|
118
147
|
assetAmount: () => assetAmount,
|
|
148
|
+
blockchainAmountFromRawOrThrow: () => blockchainAmountFromRawOrThrow,
|
|
149
|
+
chainFromId: () => chainFromId,
|
|
150
|
+
computeOndoPrice: () => computeOndoPrice,
|
|
119
151
|
computePrice: () => computePrice,
|
|
120
152
|
computeSlip: () => computeSlip,
|
|
121
153
|
decodeSwappedOutputAmount: () => decodeSwappedOutputAmount,
|
|
@@ -130,15 +162,167 @@ __export(shared_exports, {
|
|
|
130
162
|
getChainId: () => getChainId,
|
|
131
163
|
getNetworkName: () => getNetworkName,
|
|
132
164
|
isStopped: () => isStopped,
|
|
165
|
+
ondoSwapContractAddress: () => ondoSwapContractAddress,
|
|
133
166
|
parseBlockchainAmount: () => parseBlockchainAmount,
|
|
134
167
|
shortenAddress: () => shortenAddress,
|
|
168
|
+
superstateSwapContractAddress: () => superstateSwapContractAddress,
|
|
135
169
|
txExplorerUrl: () => txExplorerUrl,
|
|
136
170
|
usdAmount: () => usdAmount
|
|
137
171
|
});
|
|
138
172
|
module.exports = __toCommonJS(shared_exports);
|
|
139
173
|
|
|
174
|
+
// src/shared/api/http-attributes.ts
|
|
175
|
+
var empty = {};
|
|
176
|
+
var concat = (left, right) => ({
|
|
177
|
+
...left,
|
|
178
|
+
...right
|
|
179
|
+
});
|
|
180
|
+
var concatAll = (...items) => {
|
|
181
|
+
let result = empty;
|
|
182
|
+
for (const item of items) {
|
|
183
|
+
result = concat(result, item);
|
|
184
|
+
}
|
|
185
|
+
return result;
|
|
186
|
+
};
|
|
187
|
+
var protectedRequest = () => ({ protected: true });
|
|
188
|
+
var userAgent = () => ({ userAgent: true });
|
|
189
|
+
var idempotencyKey = () => ({
|
|
190
|
+
idempotencyKey: true
|
|
191
|
+
});
|
|
192
|
+
var clientCredentials = (credentials) => ({
|
|
193
|
+
clientCredentials: credentials
|
|
194
|
+
});
|
|
195
|
+
var retryAttempt = (attempt) => ({
|
|
196
|
+
retryAttempt: attempt
|
|
197
|
+
});
|
|
198
|
+
var renewAttempted = (value) => ({
|
|
199
|
+
renewAttempted: value
|
|
200
|
+
});
|
|
201
|
+
var isProtected = (attrs) => attrs?.protected === true;
|
|
202
|
+
var needUserAgent = (attrs) => attrs?.userAgent === true;
|
|
203
|
+
var isIdempotent = (attrs) => attrs?.idempotencyKey === true;
|
|
204
|
+
var getRetryAttempt = (attrs) => attrs?.retryAttempt ?? 0;
|
|
205
|
+
var wasRenewAttempted = (attrs) => attrs?.renewAttempted === true;
|
|
206
|
+
var getClientCredentials = (attrs) => attrs?.clientCredentials;
|
|
207
|
+
var Attributes = {
|
|
208
|
+
empty,
|
|
209
|
+
concat,
|
|
210
|
+
concatAll,
|
|
211
|
+
protected: protectedRequest,
|
|
212
|
+
isProtected,
|
|
213
|
+
userAgent,
|
|
214
|
+
needUserAgent,
|
|
215
|
+
idempotencyKey,
|
|
216
|
+
isIdempotent,
|
|
217
|
+
retryAttempt,
|
|
218
|
+
getRetryAttempt,
|
|
219
|
+
renewAttempted,
|
|
220
|
+
wasRenewAttempted,
|
|
221
|
+
clientCredentials,
|
|
222
|
+
getClientCredentials
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
// src/shared/api/http.ts
|
|
226
|
+
var HttpError = class extends Error {
|
|
227
|
+
constructor(response) {
|
|
228
|
+
super(`Request failed with ${response.status} status`);
|
|
229
|
+
this.name = "HttpError";
|
|
230
|
+
this.response = response;
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
function apiErrorCode(error) {
|
|
234
|
+
if (!(error instanceof HttpError)) return null;
|
|
235
|
+
const body = error.response.body;
|
|
236
|
+
if (typeof body !== "object" || body === null) return null;
|
|
237
|
+
const code = body.code;
|
|
238
|
+
return typeof code === "string" ? code : null;
|
|
239
|
+
}
|
|
240
|
+
async function makeRequest(request) {
|
|
241
|
+
const headers = {
|
|
242
|
+
Accept: "application/json",
|
|
243
|
+
...request.method === "POST" && request.body !== void 0 ? { "Content-Type": "application/json" } : {},
|
|
244
|
+
...request.headers ?? {}
|
|
245
|
+
};
|
|
246
|
+
const init = {
|
|
247
|
+
method: request.method,
|
|
248
|
+
headers,
|
|
249
|
+
...request.redirect !== void 0 ? { redirect: request.redirect } : {}
|
|
250
|
+
};
|
|
251
|
+
if (request.method === "POST" && request.body !== void 0) {
|
|
252
|
+
init.body = JSON.stringify(request.body);
|
|
253
|
+
}
|
|
254
|
+
const response = await fetch(
|
|
255
|
+
buildUrlWithQueryParams(request.url, request.queryParams),
|
|
256
|
+
init
|
|
257
|
+
);
|
|
258
|
+
const responseHeaders = headersToRecord(response.headers);
|
|
259
|
+
if (response.status === 204 || response.status === 205) {
|
|
260
|
+
return {
|
|
261
|
+
status: response.status,
|
|
262
|
+
body: null,
|
|
263
|
+
headers: responseHeaders
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
if (response.status >= 300 && response.status < 400) {
|
|
267
|
+
await response.text();
|
|
268
|
+
return {
|
|
269
|
+
status: response.status,
|
|
270
|
+
body: null,
|
|
271
|
+
headers: responseHeaders
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
const text = await response.text();
|
|
275
|
+
let body;
|
|
276
|
+
try {
|
|
277
|
+
body = text ? JSON.parse(text) : null;
|
|
278
|
+
} catch (_) {
|
|
279
|
+
throw new HttpError({
|
|
280
|
+
status: response.status,
|
|
281
|
+
headers: responseHeaders,
|
|
282
|
+
body: text
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
return {
|
|
286
|
+
status: response.status,
|
|
287
|
+
body,
|
|
288
|
+
headers: responseHeaders
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
function buildUrlWithQueryParams(url, queryParams) {
|
|
292
|
+
if (!queryParams) {
|
|
293
|
+
return url;
|
|
294
|
+
}
|
|
295
|
+
const searchParams = new URLSearchParams();
|
|
296
|
+
for (const [key, value] of Object.entries(queryParams)) {
|
|
297
|
+
if (value === void 0 || value === null) {
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
if (Array.isArray(value)) {
|
|
301
|
+
for (const item of value) {
|
|
302
|
+
if (item === void 0 || item === null) {
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
searchParams.append(key, String(item));
|
|
306
|
+
}
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
searchParams.append(key, String(value));
|
|
310
|
+
}
|
|
311
|
+
const queryString = searchParams.toString();
|
|
312
|
+
if (!queryString) {
|
|
313
|
+
return url;
|
|
314
|
+
}
|
|
315
|
+
return url.includes("?") ? `${url}&${queryString}` : `${url}?${queryString}`;
|
|
316
|
+
}
|
|
317
|
+
function headersToRecord(headers) {
|
|
318
|
+
const record = {};
|
|
319
|
+
headers.forEach((value, key) => {
|
|
320
|
+
record[key.toLowerCase()] = value;
|
|
321
|
+
});
|
|
322
|
+
return record;
|
|
323
|
+
}
|
|
324
|
+
|
|
140
325
|
// src/shared/api/pagination.ts
|
|
141
|
-
var Cursor = (value) => value;
|
|
142
326
|
async function fetchAllPages(fetchPage, baseParams) {
|
|
143
327
|
const items = [];
|
|
144
328
|
let cursor = null;
|
|
@@ -153,84 +337,277 @@ async function fetchAllPages(fetchPage, baseParams) {
|
|
|
153
337
|
} while (cursor);
|
|
154
338
|
return items;
|
|
155
339
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
340
|
+
|
|
341
|
+
// src/shared/core/utils/crypto.ts
|
|
342
|
+
async function sha256(data) {
|
|
343
|
+
const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
|
|
344
|
+
const buffer = bytes.buffer.slice(
|
|
345
|
+
bytes.byteOffset,
|
|
346
|
+
bytes.byteOffset + bytes.byteLength
|
|
347
|
+
);
|
|
348
|
+
return crypto.subtle.digest("SHA-256", buffer);
|
|
349
|
+
}
|
|
350
|
+
function arrayBufferToBase64Url(buffer, padding = true) {
|
|
351
|
+
const bytes = new Uint8Array(buffer);
|
|
352
|
+
let binary = "";
|
|
353
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
354
|
+
binary += String.fromCharCode(bytes[i]);
|
|
355
|
+
}
|
|
356
|
+
let base64 = btoa(binary);
|
|
357
|
+
base64 = base64.replace(/\+/g, "-").replace(/\//g, "_");
|
|
358
|
+
if (!padding) {
|
|
359
|
+
base64 = base64.replace(/=+$/, "");
|
|
360
|
+
}
|
|
361
|
+
return base64;
|
|
362
|
+
}
|
|
363
|
+
function generateSecureRandomBase64Url(byteLength) {
|
|
364
|
+
const bytes = new Uint8Array(byteLength);
|
|
365
|
+
crypto.getRandomValues(bytes);
|
|
366
|
+
const buffer = bytes.buffer;
|
|
367
|
+
return arrayBufferToBase64Url(buffer, false);
|
|
368
|
+
}
|
|
369
|
+
function notBlankStringOrNull(value) {
|
|
370
|
+
if (value?.trim()) {
|
|
371
|
+
return value;
|
|
372
|
+
} else {
|
|
373
|
+
return null;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// src/shared/types/oauth.ts
|
|
378
|
+
var AuthorizationCode = (value) => value;
|
|
379
|
+
var CodeVerifier = (value) => value;
|
|
380
|
+
var CodeChallenge = (value) => value;
|
|
381
|
+
var PKCEState = (value) => value;
|
|
382
|
+
var RedirectUri = (value) => value;
|
|
383
|
+
var ClientId = (value) => value;
|
|
384
|
+
var ClientSecret = (value) => value;
|
|
385
|
+
|
|
386
|
+
// src/shared/core/auth/pkce.ts
|
|
387
|
+
async function generatePKCEParams(config) {
|
|
388
|
+
const state = generateSecureRandomBase64Url(32);
|
|
389
|
+
const codeVerifier = generateSecureRandomBase64Url(32);
|
|
390
|
+
const codeChallengeRaw = await sha256(codeVerifier);
|
|
391
|
+
const codeChallenge = arrayBufferToBase64Url(codeChallengeRaw, false);
|
|
392
|
+
return {
|
|
393
|
+
clientId: config.clientId,
|
|
394
|
+
responseType: "code",
|
|
395
|
+
redirectUri: config.redirectUri,
|
|
396
|
+
codeChallenge: CodeChallenge(codeChallenge),
|
|
397
|
+
codeChallengeMethod: "S256",
|
|
398
|
+
state: PKCEState(state),
|
|
399
|
+
codeVerifier: CodeVerifier(codeVerifier)
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// src/shared/types/errors.ts
|
|
404
|
+
var NotImplementedError = class extends Error {
|
|
405
|
+
constructor(message = "Not implemented yet") {
|
|
406
|
+
super(message);
|
|
407
|
+
this.name = "NotImplementedError";
|
|
408
|
+
}
|
|
162
409
|
};
|
|
163
|
-
var
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
queryParams.limit = params.limit;
|
|
174
|
-
}
|
|
175
|
-
return queryParams;
|
|
410
|
+
var NotAuthenticatedError = class extends Error {
|
|
411
|
+
constructor(message = "The user is not authenticated. Go through the OAuth flow first!") {
|
|
412
|
+
super(message);
|
|
413
|
+
this.name = "NotAuthenticatedError";
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
var ValidationError = class extends Error {
|
|
417
|
+
constructor(message) {
|
|
418
|
+
super(message);
|
|
419
|
+
this.name = "ValidationError";
|
|
176
420
|
}
|
|
177
421
|
};
|
|
178
422
|
|
|
179
|
-
// src/shared/
|
|
180
|
-
var
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
{
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
423
|
+
// src/shared/types/blockchain/core.ts
|
|
424
|
+
var ETHEREUM_CHAINS = {
|
|
425
|
+
ethereum_mainnet: true,
|
|
426
|
+
ethereum_sepolia: true
|
|
427
|
+
};
|
|
428
|
+
var EthereumChain = (value) => {
|
|
429
|
+
if (!Object.keys(ETHEREUM_CHAINS).includes(value)) {
|
|
430
|
+
throw new ValidationError(`Unsupported Ethereum chain: "${value}"`);
|
|
431
|
+
}
|
|
432
|
+
return value;
|
|
433
|
+
};
|
|
434
|
+
var SOLANA_CHAINS = {
|
|
435
|
+
solana_mainnet: true,
|
|
436
|
+
solana_devnet: true
|
|
437
|
+
};
|
|
438
|
+
var SolanaChain = (value) => {
|
|
439
|
+
if (!Object.keys(SOLANA_CHAINS).includes(value)) {
|
|
440
|
+
throw new ValidationError(`Unsupported Solana chain: "${value}"`);
|
|
441
|
+
}
|
|
442
|
+
return value;
|
|
443
|
+
};
|
|
444
|
+
var Chain = (value) => {
|
|
445
|
+
if (!Object.keys(ETHEREUM_CHAINS).includes(value) && !Object.keys(SOLANA_CHAINS).includes(value)) {
|
|
446
|
+
throw new ValidationError(`Unsupported chain: "${value}"`);
|
|
447
|
+
}
|
|
448
|
+
return value;
|
|
449
|
+
};
|
|
450
|
+
var EvmWalletAddress = (value) => value;
|
|
451
|
+
var EvmContractAddress = (value) => value;
|
|
452
|
+
var HexEncodedTransactionData = (value) => value;
|
|
453
|
+
var MAX_ASSET_DECIMALS = 77;
|
|
454
|
+
var AssetDecimals = (value) => {
|
|
455
|
+
if (!Number.isInteger(value)) {
|
|
456
|
+
throw new ValidationError(`Asset decimals must be an integer: ${value}`);
|
|
457
|
+
}
|
|
458
|
+
if (value < 0 || value > MAX_ASSET_DECIMALS) {
|
|
459
|
+
throw new ValidationError(
|
|
460
|
+
`Asset decimals out of range [0, ${MAX_ASSET_DECIMALS}]: ${value}`
|
|
461
|
+
);
|
|
462
|
+
}
|
|
463
|
+
return value;
|
|
464
|
+
};
|
|
465
|
+
var STABLE_DECIMALS = AssetDecimals(6);
|
|
466
|
+
var DecimalString = (value) => value;
|
|
467
|
+
var MAX_UINT_256 = 2n ** 256n - 1n;
|
|
468
|
+
var assertUint256 = (value) => {
|
|
469
|
+
if (value < 0n || value > MAX_UINT_256) {
|
|
470
|
+
throw new Error(`Value out of uint256 bounds: ${value}`);
|
|
471
|
+
}
|
|
472
|
+
return value;
|
|
473
|
+
};
|
|
474
|
+
var BlockchainAmount = Object.assign(
|
|
475
|
+
(value) => value,
|
|
229
476
|
{
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
477
|
+
add: (a, b) => combineAmounts(a, b, (x, y) => x + y),
|
|
478
|
+
sub: (a, b) => combineAmounts(a, b, (x, y) => x - y)
|
|
479
|
+
}
|
|
480
|
+
);
|
|
481
|
+
function combineAmounts(a, b, op) {
|
|
482
|
+
if (a.decimals !== b.decimals) {
|
|
483
|
+
throw new Error(
|
|
484
|
+
`Cannot combine BlockchainAmounts with different decimals: ${a.decimals} vs ${b.decimals}`
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
const raw = op(a.raw, b.raw);
|
|
488
|
+
if (raw < 0n || raw > MAX_UINT_256) {
|
|
489
|
+
throw new Error(`BlockchainAmount out of uint256 bounds: ${raw}`);
|
|
490
|
+
}
|
|
491
|
+
return BlockchainAmount({ raw, decimals: a.decimals });
|
|
492
|
+
}
|
|
493
|
+
var AssetSymbol = (value) => value;
|
|
494
|
+
var StablecoinSymbol = (value) => value;
|
|
495
|
+
var KnownAssetSymbol = StablecoinSymbol;
|
|
496
|
+
var Bps = (value) => value;
|
|
497
|
+
|
|
498
|
+
// src/shared/core/blockchain/bps.ts
|
|
499
|
+
var BPS_DENOM = Bps(10000n);
|
|
500
|
+
function applyBps(amount, bps) {
|
|
501
|
+
return assertUint256(amount * bps / BPS_DENOM);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// src/shared/types/blockchain/ui.ts
|
|
505
|
+
var FormattedAmountUi = (value) => value;
|
|
506
|
+
var FormattedPercentUi = (value) => value;
|
|
507
|
+
var TxExplorerUrl = (value) => value;
|
|
508
|
+
var ShortenedWalletAddress = (value) => value;
|
|
509
|
+
var FormattedAmountAssetUi = (value) => value;
|
|
510
|
+
var AssetIconUrl = (value) => value;
|
|
511
|
+
|
|
512
|
+
// src/shared/core/blockchain/chain.ts
|
|
513
|
+
var CHAIN_IDS = {
|
|
514
|
+
ethereum_mainnet: 1,
|
|
515
|
+
ethereum_sepolia: 11155111
|
|
516
|
+
};
|
|
517
|
+
function getChainId(chain) {
|
|
518
|
+
return CHAIN_IDS[chain];
|
|
519
|
+
}
|
|
520
|
+
function chainFromId(chainId) {
|
|
521
|
+
const chains = Object.keys(CHAIN_IDS);
|
|
522
|
+
const chain = chains.find((c) => String(CHAIN_IDS[c]) === chainId);
|
|
523
|
+
if (!chain) {
|
|
524
|
+
throw new ValidationError(`Unsupported EIP-155 chain id: "${chainId}"`);
|
|
525
|
+
}
|
|
526
|
+
return chain;
|
|
527
|
+
}
|
|
528
|
+
function getNetworkName(chain) {
|
|
529
|
+
switch (chain) {
|
|
530
|
+
case "ethereum_mainnet":
|
|
531
|
+
return "Ethereum";
|
|
532
|
+
case "ethereum_sepolia":
|
|
533
|
+
return "Ethereum Sepolia";
|
|
534
|
+
default: {
|
|
535
|
+
const _exhaustive = chain;
|
|
536
|
+
return _exhaustive;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
function txExplorerUrl(chain, txHash) {
|
|
541
|
+
return TxExplorerUrl(`${explorerBaseUrl(chain)}/tx/${txHash}`);
|
|
542
|
+
}
|
|
543
|
+
function explorerBaseUrl(chain) {
|
|
544
|
+
switch (chain) {
|
|
545
|
+
case "ethereum_mainnet":
|
|
546
|
+
return "https://etherscan.io";
|
|
547
|
+
case "ethereum_sepolia":
|
|
548
|
+
return "https://sepolia.etherscan.io";
|
|
549
|
+
default: {
|
|
550
|
+
const _exhaustive = chain;
|
|
551
|
+
return _exhaustive;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// src/shared/core/blockchain/erc20/abi.ts
|
|
557
|
+
var ERC20_ABI = [
|
|
558
|
+
{
|
|
559
|
+
type: "function",
|
|
560
|
+
name: "allowance",
|
|
561
|
+
inputs: [
|
|
562
|
+
{ name: "owner", type: "address" },
|
|
563
|
+
{ name: "spender", type: "address" }
|
|
564
|
+
],
|
|
565
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
566
|
+
stateMutability: "view"
|
|
567
|
+
},
|
|
568
|
+
{
|
|
569
|
+
type: "function",
|
|
570
|
+
name: "approve",
|
|
571
|
+
inputs: [
|
|
572
|
+
{ name: "spender", type: "address" },
|
|
573
|
+
{ name: "amount", type: "uint256" }
|
|
574
|
+
],
|
|
575
|
+
outputs: [{ name: "", type: "bool" }],
|
|
576
|
+
stateMutability: "nonpayable"
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
type: "function",
|
|
580
|
+
name: "balanceOf",
|
|
581
|
+
inputs: [{ name: "account", type: "address" }],
|
|
582
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
583
|
+
stateMutability: "view"
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
type: "function",
|
|
587
|
+
name: "decimals",
|
|
588
|
+
inputs: [],
|
|
589
|
+
outputs: [{ name: "", type: "uint8" }],
|
|
590
|
+
stateMutability: "view"
|
|
591
|
+
},
|
|
592
|
+
{
|
|
593
|
+
type: "function",
|
|
594
|
+
name: "name",
|
|
595
|
+
inputs: [],
|
|
596
|
+
outputs: [{ name: "", type: "string" }],
|
|
597
|
+
stateMutability: "view"
|
|
598
|
+
},
|
|
599
|
+
{
|
|
600
|
+
type: "function",
|
|
601
|
+
name: "symbol",
|
|
602
|
+
inputs: [],
|
|
603
|
+
outputs: [{ name: "", type: "string" }],
|
|
604
|
+
stateMutability: "view"
|
|
605
|
+
},
|
|
606
|
+
{
|
|
607
|
+
type: "function",
|
|
608
|
+
name: "totalSupply",
|
|
609
|
+
inputs: [],
|
|
610
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
234
611
|
stateMutability: "view"
|
|
235
612
|
},
|
|
236
613
|
{
|
|
@@ -274,9 +651,846 @@ var ERC20_ABI = [
|
|
|
274
651
|
],
|
|
275
652
|
anonymous: false
|
|
276
653
|
}
|
|
277
|
-
];
|
|
654
|
+
];
|
|
655
|
+
|
|
656
|
+
// src/shared/types/providers/superstate/swap.ts
|
|
657
|
+
var SwapAuthorization = {
|
|
658
|
+
fromDto: (dto) => ({
|
|
659
|
+
authorized: dto.authorized
|
|
660
|
+
})
|
|
661
|
+
};
|
|
662
|
+
var SwapPreview = {
|
|
663
|
+
fromDto: (dto) => ({
|
|
664
|
+
inputAmount: assertUint256(BigInt(dto.pay_input_amount)),
|
|
665
|
+
fee: assertUint256(BigInt(dto.fee)),
|
|
666
|
+
outputAmount: assertUint256(BigInt(dto.receive_output_amount))
|
|
667
|
+
})
|
|
668
|
+
};
|
|
669
|
+
var SwapStatus = {
|
|
670
|
+
fromDto: (dto) => ({
|
|
671
|
+
stopped: assertUint256(BigInt(dto.stopped)),
|
|
672
|
+
swapLevel: assertUint256(BigInt(dto.swap_level))
|
|
673
|
+
})
|
|
674
|
+
};
|
|
675
|
+
var TokenAllowance = {
|
|
676
|
+
fromDto: (dto) => ({
|
|
677
|
+
allowance: assertUint256(BigInt(dto.allowance))
|
|
678
|
+
})
|
|
679
|
+
};
|
|
680
|
+
var TokenBalance = {
|
|
681
|
+
fromDto: (dto) => ({
|
|
682
|
+
balance: assertUint256(BigInt(dto.balance))
|
|
683
|
+
})
|
|
684
|
+
};
|
|
685
|
+
var AllowWalletResponse = {
|
|
686
|
+
fromDto: (dto) => {
|
|
687
|
+
switch (dto.action) {
|
|
688
|
+
case "broadcast_transaction":
|
|
689
|
+
return {
|
|
690
|
+
action: "broadcast_transaction",
|
|
691
|
+
to: EvmContractAddress(dto.to),
|
|
692
|
+
data: HexEncodedTransactionData(dto.data)
|
|
693
|
+
};
|
|
694
|
+
case "none":
|
|
695
|
+
return {
|
|
696
|
+
action: "none",
|
|
697
|
+
alreadyAllowed: dto.already_allowed
|
|
698
|
+
};
|
|
699
|
+
default: {
|
|
700
|
+
const _exhaustive = dto;
|
|
701
|
+
return _exhaustive;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
};
|
|
706
|
+
|
|
707
|
+
// src/shared/api/frontline/providers/superstate/swap.ts
|
|
708
|
+
async function getSwapAuthorization(api, params) {
|
|
709
|
+
const dto = await api.send({
|
|
710
|
+
method: "GET",
|
|
711
|
+
url: "/v1/wallet/authorized",
|
|
712
|
+
queryParams: {
|
|
713
|
+
chain: params.chain,
|
|
714
|
+
contract_address: params.contractAddress,
|
|
715
|
+
wallet_address: params.walletAddress
|
|
716
|
+
},
|
|
717
|
+
attributes: Attributes.protected()
|
|
718
|
+
});
|
|
719
|
+
return SwapAuthorization.fromDto(dto);
|
|
720
|
+
}
|
|
721
|
+
async function getSwapOutputToken(api, params) {
|
|
722
|
+
const dto = await api.send({
|
|
723
|
+
method: "GET",
|
|
724
|
+
url: "/v1/swap/output-token",
|
|
725
|
+
queryParams: {
|
|
726
|
+
chain: params.chain,
|
|
727
|
+
contract_address: params.contractAddress
|
|
728
|
+
},
|
|
729
|
+
attributes: Attributes.protected()
|
|
730
|
+
});
|
|
731
|
+
return toErc20Asset(dto);
|
|
732
|
+
}
|
|
733
|
+
async function getSwapPreview(api, params) {
|
|
734
|
+
const dto = await api.send({
|
|
735
|
+
method: "GET",
|
|
736
|
+
url: "/v1/swap/preview",
|
|
737
|
+
queryParams: {
|
|
738
|
+
chain: params.chain,
|
|
739
|
+
contract_address: params.contractAddress,
|
|
740
|
+
input_token: params.inputToken,
|
|
741
|
+
amount: params.amount.toString()
|
|
742
|
+
},
|
|
743
|
+
attributes: Attributes.protected()
|
|
744
|
+
});
|
|
745
|
+
return SwapPreview.fromDto(dto);
|
|
746
|
+
}
|
|
747
|
+
async function getSwapStatus(api, params) {
|
|
748
|
+
const dto = await api.send({
|
|
749
|
+
method: "GET",
|
|
750
|
+
url: "/v1/swap/status",
|
|
751
|
+
queryParams: {
|
|
752
|
+
chain: params.chain,
|
|
753
|
+
contract_address: params.contractAddress
|
|
754
|
+
},
|
|
755
|
+
attributes: Attributes.protected()
|
|
756
|
+
});
|
|
757
|
+
return SwapStatus.fromDto(dto);
|
|
758
|
+
}
|
|
759
|
+
async function getTokenAllowance(api, params) {
|
|
760
|
+
const dto = await api.send({
|
|
761
|
+
method: "GET",
|
|
762
|
+
url: "/v1/token/allowance",
|
|
763
|
+
queryParams: {
|
|
764
|
+
chain: params.chain,
|
|
765
|
+
token_address: params.tokenAddress,
|
|
766
|
+
owner: params.owner,
|
|
767
|
+
spender: params.spender
|
|
768
|
+
},
|
|
769
|
+
attributes: Attributes.protected()
|
|
770
|
+
});
|
|
771
|
+
return TokenAllowance.fromDto(dto);
|
|
772
|
+
}
|
|
773
|
+
async function getTokenBalance(api, params) {
|
|
774
|
+
const dto = await api.send({
|
|
775
|
+
method: "GET",
|
|
776
|
+
url: "/v1/token/balance",
|
|
777
|
+
queryParams: {
|
|
778
|
+
chain: params.chain,
|
|
779
|
+
token_address: params.tokenAddress,
|
|
780
|
+
owner: params.owner
|
|
781
|
+
},
|
|
782
|
+
attributes: Attributes.protected()
|
|
783
|
+
});
|
|
784
|
+
return TokenBalance.fromDto(dto);
|
|
785
|
+
}
|
|
786
|
+
async function allowWallet(api, params) {
|
|
787
|
+
const dto = await api.send({
|
|
788
|
+
method: "POST",
|
|
789
|
+
url: `/v1/offers/${encodeURIComponent(params.offerId)}/allow-wallet`,
|
|
790
|
+
body: {
|
|
791
|
+
wallet_address: params.walletAddress,
|
|
792
|
+
chain: params.chain,
|
|
793
|
+
signature: params.signature
|
|
794
|
+
},
|
|
795
|
+
attributes: Attributes.protected()
|
|
796
|
+
});
|
|
797
|
+
return AllowWalletResponse.fromDto(dto);
|
|
798
|
+
}
|
|
799
|
+
function toErc20Asset(dto) {
|
|
800
|
+
return {
|
|
801
|
+
name: dto.name,
|
|
802
|
+
symbol: AssetSymbol(dto.symbol),
|
|
803
|
+
decimals: AssetDecimals(dto.decimals)
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
// src/shared/core/blockchain/erc20/erc20-namespace.ts
|
|
808
|
+
var Erc20NamespaceImpl = class {
|
|
809
|
+
constructor(ctx) {
|
|
810
|
+
this.ctx = ctx;
|
|
811
|
+
}
|
|
812
|
+
async getAllowance(params) {
|
|
813
|
+
await this.ctx.ensureUserAuthenticated();
|
|
814
|
+
return getTokenAllowance(this.ctx.api, params);
|
|
815
|
+
}
|
|
816
|
+
async getBalance(params) {
|
|
817
|
+
await this.ctx.ensureUserAuthenticated();
|
|
818
|
+
return getTokenBalance(this.ctx.api, params);
|
|
819
|
+
}
|
|
820
|
+
};
|
|
821
|
+
|
|
822
|
+
// src/shared/core/blockchain/formatters.ts
|
|
823
|
+
var import_viem = require("viem");
|
|
824
|
+
function shortenAddress(address) {
|
|
825
|
+
const short = address.length > 10 ? `${address.slice(0, 6)}\u2026${address.slice(-4)}` : address;
|
|
826
|
+
return ShortenedWalletAddress(short);
|
|
827
|
+
}
|
|
828
|
+
function formatAmount(amount, locale, options) {
|
|
829
|
+
const decimal = formatRawAmount(amount);
|
|
830
|
+
let [integerPart, fractionPart = ""] = decimal.split(".");
|
|
831
|
+
const maxFractionDigits = options?.maxFractionDigits;
|
|
832
|
+
const minFractionDigits = maxFractionDigits !== void 0 ? Math.min(maxFractionDigits, amount.decimals) : Math.min(2, amount.decimals);
|
|
833
|
+
if (maxFractionDigits !== void 0 && fractionPart.length > maxFractionDigits) {
|
|
834
|
+
({ integerPart, fractionPart } = roundFractionHalfUp(
|
|
835
|
+
integerPart,
|
|
836
|
+
fractionPart,
|
|
837
|
+
maxFractionDigits
|
|
838
|
+
));
|
|
839
|
+
}
|
|
840
|
+
const fraction = minFractionDigits === 0 ? "" : fractionPart.padEnd(minFractionDigits, "0");
|
|
841
|
+
const integerFormatted = BigInt(integerPart).toLocaleString(locale);
|
|
842
|
+
if (minFractionDigits === 0 && fraction === "") {
|
|
843
|
+
return FormattedAmountUi(integerFormatted);
|
|
844
|
+
}
|
|
845
|
+
const decimalSeparator = new Intl.NumberFormat(locale).formatToParts(1.1).find((p) => p.type === "decimal")?.value ?? ".";
|
|
846
|
+
return FormattedAmountUi(`${integerFormatted}${decimalSeparator}${fraction}`);
|
|
847
|
+
}
|
|
848
|
+
function roundFractionHalfUp(integerPart, fractionPart, maxFractionDigits) {
|
|
849
|
+
if (fractionPart.length <= maxFractionDigits) {
|
|
850
|
+
return { integerPart, fractionPart };
|
|
851
|
+
}
|
|
852
|
+
if (maxFractionDigits === 0) {
|
|
853
|
+
const roundUp = fractionPart[0] >= "5";
|
|
854
|
+
const integer = BigInt(integerPart) + (roundUp ? 1n : 0n);
|
|
855
|
+
return { integerPart: integer.toString(), fractionPart: "" };
|
|
856
|
+
}
|
|
857
|
+
const trimmed = fractionPart.slice(0, maxFractionDigits);
|
|
858
|
+
if (fractionPart[maxFractionDigits] < "5") {
|
|
859
|
+
return { integerPart, fractionPart: trimmed };
|
|
860
|
+
}
|
|
861
|
+
const digits = trimmed.split("").map((digit) => Number.parseInt(digit, 10));
|
|
862
|
+
let carry = 1;
|
|
863
|
+
for (let i = digits.length - 1; i >= 0 && carry > 0; i -= 1) {
|
|
864
|
+
const sum = digits[i] + carry;
|
|
865
|
+
if (sum === 10) {
|
|
866
|
+
digits[i] = 0;
|
|
867
|
+
carry = 1;
|
|
868
|
+
} else {
|
|
869
|
+
digits[i] = sum;
|
|
870
|
+
carry = 0;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
return {
|
|
874
|
+
integerPart: carry > 0 ? (BigInt(integerPart) + 1n).toString() : integerPart,
|
|
875
|
+
fractionPart: digits.join("")
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
function formatRawAmount(amount) {
|
|
879
|
+
return (0, import_viem.formatUnits)(amount.raw, amount.decimals);
|
|
880
|
+
}
|
|
881
|
+
function formatCompactAmount(amount, locale) {
|
|
882
|
+
const value = Number(formatRawAmount(amount));
|
|
883
|
+
const formatted = new Intl.NumberFormat(locale, {
|
|
884
|
+
notation: "compact",
|
|
885
|
+
maximumFractionDigits: 2
|
|
886
|
+
}).format(value);
|
|
887
|
+
return FormattedAmountUi(formatted);
|
|
888
|
+
}
|
|
889
|
+
function formatBpsAsPercent(bps, locale) {
|
|
890
|
+
const whole = bps / 100n;
|
|
891
|
+
const fraction = bps % 100n;
|
|
892
|
+
const wholeFormatted = whole.toLocaleString(locale);
|
|
893
|
+
const decimalSeparator = new Intl.NumberFormat(locale).formatToParts(1.1).find((p) => p.type === "decimal")?.value ?? ".";
|
|
894
|
+
if (fraction === 0n) {
|
|
895
|
+
return FormattedPercentUi(`${wholeFormatted}%`);
|
|
896
|
+
}
|
|
897
|
+
const fractionFormatted = fraction.toString().padStart(2, "0").replace(/0+$/, "");
|
|
898
|
+
return FormattedPercentUi(
|
|
899
|
+
`${wholeFormatted}${decimalSeparator}${fractionFormatted}%`
|
|
900
|
+
);
|
|
901
|
+
}
|
|
902
|
+
function usdAmount(amount) {
|
|
903
|
+
return FormattedAmountAssetUi(`$${amount}`);
|
|
904
|
+
}
|
|
905
|
+
function assetAmount(amount, symbol) {
|
|
906
|
+
return FormattedAmountAssetUi(`${amount} ${symbol}`);
|
|
907
|
+
}
|
|
908
|
+
var NA_AMOUNT_ASSET_UI = FormattedAmountAssetUi("-");
|
|
909
|
+
var USD_FRACTION_DIGITS = AssetDecimals(2);
|
|
910
|
+
function formattedUsdPrice(amount, locale) {
|
|
911
|
+
if (!amount) return NA_AMOUNT_ASSET_UI;
|
|
912
|
+
return usdAmount(
|
|
913
|
+
formatAmount(amount, locale, { maxFractionDigits: USD_FRACTION_DIGITS })
|
|
914
|
+
);
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
// src/shared/core/blockchain/math.ts
|
|
918
|
+
var import_viem2 = require("viem");
|
|
919
|
+
function blockchainAmountFromRawOrThrow({
|
|
920
|
+
label,
|
|
921
|
+
raw,
|
|
922
|
+
decimals
|
|
923
|
+
}) {
|
|
924
|
+
const trimmed = raw.trim();
|
|
925
|
+
if (trimmed === "") {
|
|
926
|
+
throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
|
|
927
|
+
}
|
|
928
|
+
let value;
|
|
929
|
+
try {
|
|
930
|
+
value = BigInt(trimmed);
|
|
931
|
+
} catch {
|
|
932
|
+
throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
|
|
933
|
+
}
|
|
934
|
+
try {
|
|
935
|
+
return BlockchainAmount({ raw: assertUint256(value), decimals });
|
|
936
|
+
} catch {
|
|
937
|
+
throw new ValidationError(`${label}: out of uint256 bounds (${value})`);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
function parseBlockchainAmount(amount, decimals) {
|
|
941
|
+
const trimmed = amount.trim();
|
|
942
|
+
if (trimmed === "") return { valid: false, reason: { type: "empty" } };
|
|
943
|
+
if (trimmed.startsWith("-")) {
|
|
944
|
+
return { valid: false, reason: { type: "negative" } };
|
|
945
|
+
}
|
|
946
|
+
if (/[eE]/.test(trimmed)) {
|
|
947
|
+
return { valid: false, reason: { type: "invalid-format" } };
|
|
948
|
+
}
|
|
949
|
+
if (!/^\d+(\.\d+)?$/.test(trimmed)) {
|
|
950
|
+
return { valid: false, reason: { type: "invalid-format" } };
|
|
951
|
+
}
|
|
952
|
+
const [, fraction = ""] = trimmed.split(".");
|
|
953
|
+
if (fraction.length > decimals) {
|
|
954
|
+
return {
|
|
955
|
+
valid: false,
|
|
956
|
+
reason: { type: "too-many-decimals", maxDecimals: decimals }
|
|
957
|
+
};
|
|
958
|
+
}
|
|
959
|
+
try {
|
|
960
|
+
const raw = (0, import_viem2.parseUnits)(trimmed, decimals);
|
|
961
|
+
if (raw > MAX_UINT_256) {
|
|
962
|
+
return { valid: false, reason: { type: "overflow" } };
|
|
963
|
+
}
|
|
964
|
+
return {
|
|
965
|
+
valid: true,
|
|
966
|
+
amount: BlockchainAmount({ raw, decimals })
|
|
967
|
+
};
|
|
968
|
+
} catch {
|
|
969
|
+
return { valid: false, reason: { type: "invalid-format" } };
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
// src/shared/core/blockchain/token-registry.ts
|
|
974
|
+
var USDC_SYMBOL = StablecoinSymbol("USDC");
|
|
975
|
+
var USDC = {
|
|
976
|
+
name: "USD Coin",
|
|
977
|
+
symbol: USDC_SYMBOL,
|
|
978
|
+
decimals: AssetDecimals(6)
|
|
979
|
+
};
|
|
980
|
+
var USDT_SYMBOL = StablecoinSymbol("USDT");
|
|
981
|
+
var USDT = {
|
|
982
|
+
name: "Tether USD",
|
|
983
|
+
symbol: USDT_SYMBOL,
|
|
984
|
+
decimals: AssetDecimals(6)
|
|
985
|
+
};
|
|
986
|
+
var USDC_ADDRESSES = {
|
|
987
|
+
ethereum_mainnet: EvmContractAddress(
|
|
988
|
+
"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
|
|
989
|
+
),
|
|
990
|
+
ethereum_sepolia: EvmContractAddress(
|
|
991
|
+
"0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"
|
|
992
|
+
)
|
|
993
|
+
};
|
|
994
|
+
var USDT_ADDRESSES = {
|
|
995
|
+
ethereum_mainnet: EvmContractAddress(
|
|
996
|
+
"0xdac17f958d2ee523a2206206994597c13d831ec7"
|
|
997
|
+
),
|
|
998
|
+
ethereum_sepolia: EvmContractAddress(
|
|
999
|
+
"0x7169D38820dfd117C3FA1f22a697dBA58d90BA06"
|
|
1000
|
+
)
|
|
1001
|
+
};
|
|
1002
|
+
var TOKEN_REGISTRY = {
|
|
1003
|
+
erc20: (symbol) => {
|
|
1004
|
+
switch (symbol) {
|
|
1005
|
+
case "USDC":
|
|
1006
|
+
return USDC;
|
|
1007
|
+
case "USDT":
|
|
1008
|
+
return USDT;
|
|
1009
|
+
default:
|
|
1010
|
+
throw new Error(`Unknown asset symbol: ${symbol}`);
|
|
1011
|
+
}
|
|
1012
|
+
},
|
|
1013
|
+
contractAddress: (symbol, chain) => {
|
|
1014
|
+
switch (symbol) {
|
|
1015
|
+
case "USDC":
|
|
1016
|
+
return USDC_ADDRESSES[chain];
|
|
1017
|
+
case "USDT":
|
|
1018
|
+
return USDT_ADDRESSES[chain];
|
|
1019
|
+
default:
|
|
1020
|
+
throw new Error(`Unknown asset symbol: ${symbol}`);
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
};
|
|
1024
|
+
|
|
1025
|
+
// src/shared/types/pagination.ts
|
|
1026
|
+
var Cursor = (value) => value;
|
|
1027
|
+
var PaginatedResponse = {
|
|
1028
|
+
fromDto: (dto, itemMapper) => ({
|
|
1029
|
+
data: dto.data.map(itemMapper),
|
|
1030
|
+
startingAfter: dto.starting_after ? Cursor(dto.starting_after) : null,
|
|
1031
|
+
startingBefore: dto.starting_before ? Cursor(dto.starting_before) : null
|
|
1032
|
+
})
|
|
1033
|
+
};
|
|
1034
|
+
var PaginationParams = {
|
|
1035
|
+
toQueryParams: (params) => {
|
|
1036
|
+
const queryParams = {};
|
|
1037
|
+
if (params.after) {
|
|
1038
|
+
queryParams.starting_after = params.after;
|
|
1039
|
+
}
|
|
1040
|
+
if (params.before) {
|
|
1041
|
+
queryParams.starting_before = params.before;
|
|
1042
|
+
}
|
|
1043
|
+
if (params.limit) {
|
|
1044
|
+
queryParams.limit = params.limit;
|
|
1045
|
+
}
|
|
1046
|
+
return queryParams;
|
|
1047
|
+
}
|
|
1048
|
+
};
|
|
1049
|
+
|
|
1050
|
+
// src/shared/types/asset.ts
|
|
1051
|
+
var AssetId = (value) => value;
|
|
1052
|
+
var AssetCode = (value) => value;
|
|
1053
|
+
var Asset = {
|
|
1054
|
+
fromDto: (dto) => ({
|
|
1055
|
+
id: AssetId(dto.id),
|
|
1056
|
+
code: AssetCode(dto.code),
|
|
1057
|
+
name: dto.name,
|
|
1058
|
+
fractionalDigits: dto.fractional_digits
|
|
1059
|
+
})
|
|
1060
|
+
};
|
|
1061
|
+
|
|
1062
|
+
// src/shared/types/offer.ts
|
|
1063
|
+
var OfferId = (value) => value;
|
|
1064
|
+
var OfferSlug = (value) => value;
|
|
1065
|
+
var Offer = {
|
|
1066
|
+
fromDto: (dto) => ({
|
|
1067
|
+
id: OfferId(dto.id),
|
|
1068
|
+
slug: OfferSlug(dto.slug),
|
|
1069
|
+
type: dto.type,
|
|
1070
|
+
tagline: dto.tagline,
|
|
1071
|
+
bannerUrl: dto.banner_url,
|
|
1072
|
+
logoUrl: dto.logo_url,
|
|
1073
|
+
startsAt: new Date(dto.starts_at),
|
|
1074
|
+
endsAt: dto.ends_at ? new Date(dto.ends_at) : null
|
|
1075
|
+
})
|
|
1076
|
+
};
|
|
1077
|
+
|
|
1078
|
+
// src/shared/types/offer-detail.ts
|
|
1079
|
+
var OfferOptionId = (value) => value;
|
|
1080
|
+
var OfferOptionSlug = (value) => value;
|
|
1081
|
+
var OfferDetail = {
|
|
1082
|
+
fromDto: (dto) => {
|
|
1083
|
+
if (!Array.isArray(dto.funding_assets)) {
|
|
1084
|
+
throw new Error(`funding_assets must be an array`);
|
|
1085
|
+
}
|
|
1086
|
+
if (!Array.isArray(dto.options)) {
|
|
1087
|
+
throw new Error(`options must be an array`);
|
|
1088
|
+
}
|
|
1089
|
+
if (!Array.isArray(dto.terms)) {
|
|
1090
|
+
throw new Error(`terms must be an array`);
|
|
1091
|
+
}
|
|
1092
|
+
if (!Array.isArray(dto.links)) {
|
|
1093
|
+
throw new Error(`links must be an array`);
|
|
1094
|
+
}
|
|
1095
|
+
if (!Array.isArray(dto.faqs)) {
|
|
1096
|
+
throw new Error(`faqs must be an array`);
|
|
1097
|
+
}
|
|
1098
|
+
if (!Array.isArray(dto.milestones)) {
|
|
1099
|
+
throw new Error(`milestones must be an array`);
|
|
1100
|
+
}
|
|
1101
|
+
if (!Array.isArray(dto.tokens)) {
|
|
1102
|
+
throw new Error(`tokens must be an array`);
|
|
1103
|
+
}
|
|
1104
|
+
return {
|
|
1105
|
+
id: OfferId(dto.id),
|
|
1106
|
+
slug: OfferSlug(dto.slug),
|
|
1107
|
+
type: dto.type,
|
|
1108
|
+
name: dto.name,
|
|
1109
|
+
asset: Asset.fromDto(dto.asset),
|
|
1110
|
+
fundingAssets: dto.funding_assets.map(Asset.fromDto),
|
|
1111
|
+
tokens: dto.tokens.map(OfferToken.fromDto),
|
|
1112
|
+
about: notBlankStringOrNull(dto.about),
|
|
1113
|
+
tagline: dto.tagline,
|
|
1114
|
+
bannerUrl: dto.banner_url,
|
|
1115
|
+
logoUrl: dto.logo_url,
|
|
1116
|
+
category: dto.category,
|
|
1117
|
+
startsAt: new Date(dto.starts_at),
|
|
1118
|
+
endsAt: dto.ends_at ? new Date(dto.ends_at) : null,
|
|
1119
|
+
faqs: dto.faqs.map(FaqItem.fromDto),
|
|
1120
|
+
links: dto.links.map(Link.fromDto),
|
|
1121
|
+
milestones: dto.milestones.map(Milestone.fromDto),
|
|
1122
|
+
options: dto.options.map(OfferOption.fromDto),
|
|
1123
|
+
terms: dto.terms.map(TermItem.fromDto)
|
|
1124
|
+
};
|
|
1125
|
+
}
|
|
1126
|
+
};
|
|
1127
|
+
var OfferOption = {
|
|
1128
|
+
fromDto: (dto) => ({
|
|
1129
|
+
id: OfferOptionId(dto.id),
|
|
1130
|
+
slug: OfferOptionSlug(dto.slug),
|
|
1131
|
+
bidIncrement: dto.bid_increment,
|
|
1132
|
+
floorPriceUsd: dto.floor_price_usd,
|
|
1133
|
+
minimumPurchaseUsd: dto.minimum_purchase_usd,
|
|
1134
|
+
priceUsd: dto.price_usd,
|
|
1135
|
+
saleAgreementUrl: notBlankStringOrNull(dto.sale_agreement_url),
|
|
1136
|
+
totalTokenSupply: dto.total_token_supply
|
|
1137
|
+
})
|
|
1138
|
+
};
|
|
1139
|
+
var FaqItem = {
|
|
1140
|
+
fromDto: (dto) => ({
|
|
1141
|
+
question: notBlankStringOrNull(dto.question),
|
|
1142
|
+
answer: notBlankStringOrNull(dto.answer)
|
|
1143
|
+
})
|
|
1144
|
+
};
|
|
1145
|
+
var Link = {
|
|
1146
|
+
fromDto: (dto) => ({
|
|
1147
|
+
label: notBlankStringOrNull(dto.label),
|
|
1148
|
+
url: notBlankStringOrNull(dto.url)
|
|
1149
|
+
})
|
|
1150
|
+
};
|
|
1151
|
+
var TermItem = {
|
|
1152
|
+
fromDto: (dto) => ({
|
|
1153
|
+
key: notBlankStringOrNull(dto.key),
|
|
1154
|
+
value: notBlankStringOrNull(dto.value)
|
|
1155
|
+
})
|
|
1156
|
+
};
|
|
1157
|
+
var Milestone = {
|
|
1158
|
+
fromDto: (dto) => ({
|
|
1159
|
+
name: notBlankStringOrNull(dto.name),
|
|
1160
|
+
schedule: notBlankStringOrNull(dto.schedule),
|
|
1161
|
+
status: dto.status
|
|
1162
|
+
})
|
|
1163
|
+
};
|
|
1164
|
+
var OfferToken = {
|
|
1165
|
+
fromDto: (dto) => ({
|
|
1166
|
+
role: dto.role,
|
|
1167
|
+
chain: Chain(dto.chain),
|
|
1168
|
+
address: EvmContractAddress(dto.address)
|
|
1169
|
+
})
|
|
1170
|
+
};
|
|
1171
|
+
|
|
1172
|
+
// src/shared/types/providers/coin-list/token-sale.ts
|
|
1173
|
+
var ParticipationId = (value) => value;
|
|
1174
|
+
var Blockchain = (value) => value;
|
|
1175
|
+
var WalletAddress = (value) => value;
|
|
1176
|
+
var ParticipationsPaginationParams = {
|
|
1177
|
+
toQueryParams: (params) => {
|
|
1178
|
+
const queryParams = PaginationParams.toQueryParams(params);
|
|
1179
|
+
if (params.offerId) {
|
|
1180
|
+
queryParams["filters[0][field]"] = "offer_id";
|
|
1181
|
+
queryParams["filters[0][op]"] = "==";
|
|
1182
|
+
queryParams["filters[0][value]"] = params.offerId;
|
|
1183
|
+
}
|
|
1184
|
+
return queryParams;
|
|
1185
|
+
}
|
|
1186
|
+
};
|
|
1187
|
+
var Participation = {
|
|
1188
|
+
/** Maps API DTO shape into the SDK participation domain model. */
|
|
1189
|
+
fromDto: (dto) => {
|
|
1190
|
+
const walletAddress = notBlankStringOrNull(dto.wallet_address);
|
|
1191
|
+
return {
|
|
1192
|
+
id: ParticipationId(dto.id),
|
|
1193
|
+
offerId: OfferId(dto.offer_id),
|
|
1194
|
+
offerOptionId: OfferOptionId(dto.offer_option_id),
|
|
1195
|
+
status: dto.status,
|
|
1196
|
+
amount: dto.amount,
|
|
1197
|
+
displayAmount: dto.amount_string,
|
|
1198
|
+
asset: Asset.fromDto(dto.asset),
|
|
1199
|
+
chain: Blockchain(dto.chain),
|
|
1200
|
+
insertedAt: dto.inserted_at ? new Date(dto.inserted_at) : null,
|
|
1201
|
+
updatedAt: dto.updated_at ? new Date(dto.updated_at) : null,
|
|
1202
|
+
walletAddress: walletAddress ? WalletAddress(walletAddress) : null
|
|
1203
|
+
};
|
|
1204
|
+
}
|
|
1205
|
+
};
|
|
1206
|
+
var CreateParticipationParams = {
|
|
1207
|
+
/** Maps participation creation params into API DTO payload. */
|
|
1208
|
+
toDto: (params) => ({
|
|
1209
|
+
offer_id: params.offerId,
|
|
1210
|
+
offer_option_id: params.offerOptionId,
|
|
1211
|
+
chain: params.chain,
|
|
1212
|
+
wallet_address: params.walletAddress,
|
|
1213
|
+
amount: params.amount,
|
|
1214
|
+
asset_id: params.assetId,
|
|
1215
|
+
approval_transaction_hash: params.approvalTransactionHash
|
|
1216
|
+
})
|
|
1217
|
+
};
|
|
1218
|
+
|
|
1219
|
+
// src/shared/api/frontline/providers/coin-list/token-sale.ts
|
|
1220
|
+
async function fetchParticipations(api, offerId) {
|
|
1221
|
+
return fetchAllPages(
|
|
1222
|
+
(params) => fetchParticipationsPage(api, params),
|
|
1223
|
+
{ offerId }
|
|
1224
|
+
);
|
|
1225
|
+
}
|
|
1226
|
+
async function fetchParticipationsPage(api, params) {
|
|
1227
|
+
const pageDto = await api.send({
|
|
1228
|
+
method: "GET",
|
|
1229
|
+
url: "/v1/participations",
|
|
1230
|
+
queryParams: ParticipationsPaginationParams.toQueryParams(params),
|
|
1231
|
+
attributes: Attributes.protected()
|
|
1232
|
+
});
|
|
1233
|
+
return PaginatedResponse.fromDto(pageDto, Participation.fromDto);
|
|
1234
|
+
}
|
|
1235
|
+
async function fetchParticipation(api, id) {
|
|
1236
|
+
const dto = await api.send({
|
|
1237
|
+
method: "GET",
|
|
1238
|
+
url: `/v1/participations/${id}`,
|
|
1239
|
+
attributes: Attributes.protected()
|
|
1240
|
+
});
|
|
1241
|
+
return Participation.fromDto(dto);
|
|
1242
|
+
}
|
|
1243
|
+
async function createParticipation(api, params) {
|
|
1244
|
+
const dto = await api.send({
|
|
1245
|
+
method: "POST",
|
|
1246
|
+
url: "/v1/participations",
|
|
1247
|
+
body: CreateParticipationParams.toDto(params),
|
|
1248
|
+
attributes: Attributes.protected()
|
|
1249
|
+
});
|
|
1250
|
+
return Participation.fromDto(dto);
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
// src/shared/core/checkout/coin-list/token-sale-namespace.ts
|
|
1254
|
+
var CoinListTokenSaleNamespaceImpl = class {
|
|
1255
|
+
constructor(ctx) {
|
|
1256
|
+
this.ctx = ctx;
|
|
1257
|
+
}
|
|
1258
|
+
async list(offerId) {
|
|
1259
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1260
|
+
return fetchParticipations(this.ctx.api, offerId);
|
|
1261
|
+
}
|
|
1262
|
+
async listPage(params) {
|
|
1263
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1264
|
+
return fetchParticipationsPage(this.ctx.api, params);
|
|
1265
|
+
}
|
|
1266
|
+
async get(id) {
|
|
1267
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1268
|
+
return fetchParticipation(this.ctx.api, id);
|
|
1269
|
+
}
|
|
1270
|
+
async createParticipation(params) {
|
|
1271
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1272
|
+
return createParticipation(this.ctx.api, params);
|
|
1273
|
+
}
|
|
1274
|
+
};
|
|
1275
|
+
|
|
1276
|
+
// src/shared/core/checkout/ondo/constants.ts
|
|
1277
|
+
var ONDO_SWAP_CONTRACT_ADDRESSES = {
|
|
1278
|
+
ethereum_sepolia: EvmContractAddress(
|
|
1279
|
+
"0xFF9c5Ade32d9B4102469Bd5F3817CB0061b25feC"
|
|
1280
|
+
)
|
|
1281
|
+
};
|
|
1282
|
+
function ondoSwapContractAddress(chain) {
|
|
1283
|
+
return ONDO_SWAP_CONTRACT_ADDRESSES[chain] ?? null;
|
|
1284
|
+
}
|
|
1285
|
+
var ONDO_POLL_INTERVAL_MS = 15e3;
|
|
1286
|
+
var ONDO_QUOTE_EXPIRY_THRESHOLD_MS = 5e3;
|
|
1287
|
+
var DEFAULT_ONDO_AMOUNT_TO_COMPUTE_PRICE = DecimalString("1000");
|
|
1288
|
+
var ONDO_SUPPORTED_INPUT_ASSETS = [
|
|
1289
|
+
USDC_SYMBOL
|
|
1290
|
+
];
|
|
1291
|
+
|
|
1292
|
+
// src/shared/core/checkout/ondo/math.ts
|
|
1293
|
+
function computeOndoPrice(transaction) {
|
|
1294
|
+
const { notionalValue, receiveOutputAmount } = transaction;
|
|
1295
|
+
if (receiveOutputAmount.raw <= 0n) {
|
|
1296
|
+
throw new ValidationError(
|
|
1297
|
+
"Ondo price: receiveOutputAmount must be greater than zero"
|
|
1298
|
+
);
|
|
1299
|
+
}
|
|
1300
|
+
const scaled = notionalValue.raw * 10n ** BigInt(receiveOutputAmount.decimals);
|
|
1301
|
+
const raw = scaled / receiveOutputAmount.raw;
|
|
1302
|
+
return BlockchainAmount({
|
|
1303
|
+
raw: assertPriceFits(raw),
|
|
1304
|
+
decimals: notionalValue.decimals
|
|
1305
|
+
});
|
|
1306
|
+
}
|
|
1307
|
+
function assertPriceFits(raw) {
|
|
1308
|
+
try {
|
|
1309
|
+
return assertUint256(raw);
|
|
1310
|
+
} catch {
|
|
1311
|
+
throw new ValidationError(`Ondo price: out of uint256 bounds (${raw})`);
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
// src/shared/types/trading.ts
|
|
1316
|
+
var Ticker = (value) => value;
|
|
1317
|
+
|
|
1318
|
+
// src/shared/types/providers/ondo/ondo.ts
|
|
1319
|
+
var OndoTradingStatus = {
|
|
1320
|
+
fromDto: (dto) => {
|
|
1321
|
+
if (!dto.tradable) return { type: "not-tradable", side: dto.side };
|
|
1322
|
+
return {
|
|
1323
|
+
type: "tradable",
|
|
1324
|
+
side: dto.side,
|
|
1325
|
+
grossMaxTokens: decimalOrNull(dto.gross_max_tokens),
|
|
1326
|
+
grossMaxNotionalValue: decimalOrNull(dto.gross_max_notional_value),
|
|
1327
|
+
grossMaxActiveNotionalValue: decimalOrNull(
|
|
1328
|
+
dto.gross_max_active_notional_value
|
|
1329
|
+
)
|
|
1330
|
+
};
|
|
1331
|
+
}
|
|
1332
|
+
};
|
|
1333
|
+
var decimalOrNull = (value) => value === null ? null : DecimalString(value);
|
|
1334
|
+
var OndoQuote = {
|
|
1335
|
+
fromDto: (dto) => {
|
|
1336
|
+
const assetDecimals = AssetDecimals(dto.asset_decimals);
|
|
1337
|
+
return {
|
|
1338
|
+
chain: chainFromId(dto.chain_id),
|
|
1339
|
+
ticker: Ticker(dto.ticker),
|
|
1340
|
+
assetAddress: EvmContractAddress(dto.asset_address),
|
|
1341
|
+
asset: {
|
|
1342
|
+
name: dto.ticker,
|
|
1343
|
+
symbol: AssetSymbol(dto.symbol),
|
|
1344
|
+
decimals: assetDecimals
|
|
1345
|
+
},
|
|
1346
|
+
side: dto.side,
|
|
1347
|
+
tokenBaseUnits: blockchainAmountFromRawOrThrow({
|
|
1348
|
+
label: "tokenBaseUnits",
|
|
1349
|
+
raw: dto.token_base_units,
|
|
1350
|
+
decimals: assetDecimals
|
|
1351
|
+
}),
|
|
1352
|
+
price: DecimalString(dto.price)
|
|
1353
|
+
};
|
|
1354
|
+
}
|
|
1355
|
+
};
|
|
1356
|
+
var OndoSwapTransaction = {
|
|
1357
|
+
fromDto: (dto) => {
|
|
1358
|
+
const inputDecimals = AssetDecimals(dto.pay_input_decimals);
|
|
1359
|
+
const outputDecimals = AssetDecimals(dto.receive_output_decimals);
|
|
1360
|
+
return {
|
|
1361
|
+
tx: {
|
|
1362
|
+
to: EvmContractAddress(dto.to),
|
|
1363
|
+
data: HexEncodedTransactionData(dto.data)
|
|
1364
|
+
},
|
|
1365
|
+
expiresAt: parseExpiresAt(dto.expires_at),
|
|
1366
|
+
payInputAmount: blockchainAmountFromRawOrThrow({
|
|
1367
|
+
label: "pay_input_amount",
|
|
1368
|
+
raw: dto.pay_input_amount,
|
|
1369
|
+
decimals: inputDecimals
|
|
1370
|
+
}),
|
|
1371
|
+
fee: blockchainAmountFromRawOrThrow({
|
|
1372
|
+
label: "fee",
|
|
1373
|
+
raw: dto.fee,
|
|
1374
|
+
decimals: inputDecimals
|
|
1375
|
+
}),
|
|
1376
|
+
notionalValue: blockchainAmountFromRawOrThrow({
|
|
1377
|
+
label: "notional_value",
|
|
1378
|
+
raw: dto.notional_value,
|
|
1379
|
+
decimals: inputDecimals
|
|
1380
|
+
}),
|
|
1381
|
+
receiveOutputAmount: parseReceiveOutputAmount(
|
|
1382
|
+
dto.receive_output_amount,
|
|
1383
|
+
outputDecimals
|
|
1384
|
+
)
|
|
1385
|
+
};
|
|
1386
|
+
}
|
|
1387
|
+
};
|
|
1388
|
+
function parseReceiveOutputAmount(raw, decimals) {
|
|
1389
|
+
const amount = blockchainAmountFromRawOrThrow({
|
|
1390
|
+
label: "receive_output_amount",
|
|
1391
|
+
raw,
|
|
1392
|
+
decimals
|
|
1393
|
+
});
|
|
1394
|
+
if (amount.raw <= 0n) {
|
|
1395
|
+
throw new ValidationError(
|
|
1396
|
+
`receive_output_amount: must be greater than zero ("${raw}")`
|
|
1397
|
+
);
|
|
1398
|
+
}
|
|
1399
|
+
return amount;
|
|
1400
|
+
}
|
|
1401
|
+
function parseExpiresAt(value) {
|
|
1402
|
+
const date = new Date(value);
|
|
1403
|
+
if (Number.isNaN(date.getTime())) {
|
|
1404
|
+
throw new ValidationError(`expires_at: not a date ("${value}")`);
|
|
1405
|
+
}
|
|
1406
|
+
return date;
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1409
|
+
// src/shared/api/frontline/providers/ondo/ondo.ts
|
|
1410
|
+
async function getOndoTradingStatus(api, params) {
|
|
1411
|
+
const dto = await api.send({
|
|
1412
|
+
method: "GET",
|
|
1413
|
+
url: "/v1/ondo/swap/trading-status",
|
|
1414
|
+
queryParams: { symbol: params.symbol, side: params.side },
|
|
1415
|
+
attributes: Attributes.protected()
|
|
1416
|
+
});
|
|
1417
|
+
return OndoTradingStatus.fromDto(dto);
|
|
1418
|
+
}
|
|
1419
|
+
async function getOndoQuote(api, params) {
|
|
1420
|
+
const dto = await api.send({
|
|
1421
|
+
method: "GET",
|
|
1422
|
+
url: "/v1/ondo/swap/quote",
|
|
1423
|
+
queryParams: {
|
|
1424
|
+
symbol: params.symbol,
|
|
1425
|
+
side: params.side,
|
|
1426
|
+
duration: params.duration,
|
|
1427
|
+
...sizeParam(params)
|
|
1428
|
+
},
|
|
1429
|
+
attributes: Attributes.protected()
|
|
1430
|
+
});
|
|
1431
|
+
return OndoQuote.fromDto(dto);
|
|
1432
|
+
}
|
|
1433
|
+
async function buildOndoSwapTransaction(api, params) {
|
|
1434
|
+
const dto = await api.send({
|
|
1435
|
+
method: "POST",
|
|
1436
|
+
url: "/v1/ondo/swap/transaction",
|
|
1437
|
+
body: {
|
|
1438
|
+
symbol: params.symbol,
|
|
1439
|
+
chain: params.chain,
|
|
1440
|
+
wallet_address: params.walletAddress,
|
|
1441
|
+
amount: params.amount.raw.toString()
|
|
1442
|
+
},
|
|
1443
|
+
attributes: Attributes.protected()
|
|
1444
|
+
});
|
|
1445
|
+
assertFundingScaleAgrees(dto, params);
|
|
1446
|
+
return OndoSwapTransaction.fromDto(dto);
|
|
1447
|
+
}
|
|
1448
|
+
function assertFundingScaleAgrees(dto, params) {
|
|
1449
|
+
if (dto.pay_input_decimals !== params.amount.decimals) {
|
|
1450
|
+
throw new ValidationError(
|
|
1451
|
+
`pay_input_decimals: the swap was priced in ${dto.pay_input_decimals} decimals but the order was sized in ${params.amount.decimals}`
|
|
1452
|
+
);
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
function sizeParam(params) {
|
|
1456
|
+
const tokenAmount = "tokenAmount" in params ? params.tokenAmount : void 0;
|
|
1457
|
+
const notionalValue = "notionalValue" in params ? params.notionalValue : void 0;
|
|
1458
|
+
if (tokenAmount !== void 0) {
|
|
1459
|
+
if (notionalValue !== void 0) {
|
|
1460
|
+
throw new ValidationError(
|
|
1461
|
+
"An Ondo quote takes tokenAmount or notionalValue, not both"
|
|
1462
|
+
);
|
|
1463
|
+
}
|
|
1464
|
+
return { token_amount: formatRawAmount(tokenAmount) };
|
|
1465
|
+
}
|
|
1466
|
+
if (notionalValue === void 0) {
|
|
1467
|
+
throw new ValidationError(
|
|
1468
|
+
"An Ondo quote must be sized by tokenAmount or notionalValue"
|
|
1469
|
+
);
|
|
1470
|
+
}
|
|
1471
|
+
return { notional_value: notionalValue };
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
// src/shared/core/checkout/ondo/ondo-namespace.ts
|
|
1475
|
+
var OndoNamespaceImpl = class {
|
|
1476
|
+
constructor(ctx) {
|
|
1477
|
+
this.ctx = ctx;
|
|
1478
|
+
}
|
|
1479
|
+
async getTradingStatus(params) {
|
|
1480
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1481
|
+
return getOndoTradingStatus(this.ctx.api, params);
|
|
1482
|
+
}
|
|
1483
|
+
async getQuote(params) {
|
|
1484
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1485
|
+
return getOndoQuote(this.ctx.api, params);
|
|
1486
|
+
}
|
|
1487
|
+
async buildSwapTransaction(params) {
|
|
1488
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1489
|
+
return buildOndoSwapTransaction(this.ctx.api, params);
|
|
1490
|
+
}
|
|
1491
|
+
};
|
|
278
1492
|
|
|
279
|
-
// src/shared/core/blockchain/
|
|
1493
|
+
// src/shared/core/checkout/superstate/blockchain/abi.ts
|
|
280
1494
|
var SUPERSTATE_SWAP_ABI = [
|
|
281
1495
|
{
|
|
282
1496
|
type: "function",
|
|
@@ -498,101 +1712,7 @@ var SUPERSTATE_SWAP_ABI = [
|
|
|
498
1712
|
}
|
|
499
1713
|
];
|
|
500
1714
|
|
|
501
|
-
// src/shared/
|
|
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
|
|
1715
|
+
// src/shared/core/checkout/superstate/blockchain/math.ts
|
|
596
1716
|
function computePrice({
|
|
597
1717
|
inputTokenAmount,
|
|
598
1718
|
outputTokenAmount
|
|
@@ -608,151 +1728,9 @@ function computeSlip(amount, slippage) {
|
|
|
608
1728
|
const retained = Bps(assertUint256(BPS_DENOM - slippage));
|
|
609
1729
|
const slipRaw = applyBps(amount.raw, retained);
|
|
610
1730
|
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" } };
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
|
|
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");
|
|
1731
|
+
}
|
|
754
1732
|
|
|
755
|
-
// src/shared/core/blockchain/
|
|
1733
|
+
// src/shared/core/checkout/superstate/blockchain/quote.ts
|
|
756
1734
|
var SwapQuote = {
|
|
757
1735
|
/**
|
|
758
1736
|
* Assembles a {@link SwapQuote} from a raw contract {@link SwapPreview}. The
|
|
@@ -772,12 +1750,12 @@ var SwapQuote = {
|
|
|
772
1750
|
})
|
|
773
1751
|
};
|
|
774
1752
|
|
|
775
|
-
// src/shared/core/blockchain/
|
|
1753
|
+
// src/shared/core/checkout/superstate/blockchain/status.ts
|
|
776
1754
|
function isStopped(status) {
|
|
777
1755
|
return (status.stopped & status.swapLevel) !== 0n;
|
|
778
1756
|
}
|
|
779
1757
|
|
|
780
|
-
// src/shared/core/blockchain/
|
|
1758
|
+
// src/shared/core/checkout/superstate/blockchain/swapped-event.ts
|
|
781
1759
|
var import_viem3 = require("viem");
|
|
782
1760
|
function decodeSwappedOutputAmount(receipt, outputDecimals) {
|
|
783
1761
|
try {
|
|
@@ -795,420 +1773,490 @@ function decodeSwappedOutputAmount(receipt, outputDecimals) {
|
|
|
795
1773
|
}
|
|
796
1774
|
}
|
|
797
1775
|
|
|
798
|
-
// src/shared/core/
|
|
799
|
-
var
|
|
800
|
-
var
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
var
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
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
|
-
}
|
|
1776
|
+
// src/shared/core/checkout/superstate/constants.ts
|
|
1777
|
+
var SUPERSTATE_ISSUER_NAME = "Superstate";
|
|
1778
|
+
var SUPERSTATE_SUPPORTED_INPUT_ASSETS = [USDC_SYMBOL];
|
|
1779
|
+
var SWAP_POLL_INTERVAL_MS = 15e3;
|
|
1780
|
+
var DEFAULT_AMOUNT_TO_COMPUTE_PRICE = 1000000n;
|
|
1781
|
+
var SLIPPAGE_OPTIONS_BPS = [25n, 50n, 100n, 200n, 500n].map(
|
|
1782
|
+
(n) => Bps(n)
|
|
1783
|
+
);
|
|
1784
|
+
var DEFAULT_SLIPPAGE_BPS = Bps(50n);
|
|
1785
|
+
var SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA = EvmContractAddress("0x84f8e9a6C9Cc12fe911259372EfCa5582C4ae557");
|
|
1786
|
+
var SUPERSTATE_SWAP_CONTRACT_ADDRESSES = {
|
|
1787
|
+
ethereum_sepolia: SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA
|
|
848
1788
|
};
|
|
1789
|
+
function superstateSwapContractAddress(chain) {
|
|
1790
|
+
return SUPERSTATE_SWAP_CONTRACT_ADDRESSES[chain] ?? null;
|
|
1791
|
+
}
|
|
849
1792
|
|
|
850
|
-
// src/shared/
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
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
|
-
};
|
|
1793
|
+
// src/shared/core/checkout/superstate/formatters.ts
|
|
1794
|
+
function formattedPricePerShare(quote, locale) {
|
|
1795
|
+
if (!quote) return NA_AMOUNT_ASSET_UI;
|
|
1796
|
+
return formattedUsdPrice(computePrice(quote), locale);
|
|
1797
|
+
}
|
|
900
1798
|
|
|
901
|
-
// src/shared/
|
|
902
|
-
var
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
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
|
-
}
|
|
1799
|
+
// src/shared/core/checkout/superstate/swap-namespace.ts
|
|
1800
|
+
var SuperstateSwapNamespaceImpl = class {
|
|
1801
|
+
constructor(ctx) {
|
|
1802
|
+
this.ctx = ctx;
|
|
1803
|
+
}
|
|
1804
|
+
async getAuthorization(params) {
|
|
1805
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1806
|
+
return getSwapAuthorization(this.ctx.api, params);
|
|
1807
|
+
}
|
|
1808
|
+
async getPreview(params) {
|
|
1809
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1810
|
+
return getSwapPreview(this.ctx.api, params);
|
|
1811
|
+
}
|
|
1812
|
+
async getStatus(params) {
|
|
1813
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1814
|
+
return getSwapStatus(this.ctx.api, params);
|
|
1815
|
+
}
|
|
1816
|
+
async getOutputToken(params) {
|
|
1817
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1818
|
+
return getSwapOutputToken(this.ctx.api, params);
|
|
1819
|
+
}
|
|
1820
|
+
async allowWallet(params) {
|
|
1821
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1822
|
+
return allowWallet(this.ctx.api, params);
|
|
949
1823
|
}
|
|
950
1824
|
};
|
|
951
1825
|
|
|
952
|
-
// src/shared/api/frontline/
|
|
953
|
-
async function
|
|
954
|
-
|
|
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);
|
|
991
|
-
}
|
|
992
|
-
async function getSwapStatus(api, params) {
|
|
993
|
-
const dto = await api.send({
|
|
994
|
-
method: "GET",
|
|
995
|
-
url: "/v1/swap/status",
|
|
996
|
-
queryParams: {
|
|
997
|
-
chain: params.chain,
|
|
998
|
-
contract_address: params.contractAddress
|
|
999
|
-
},
|
|
1000
|
-
attributes: Attributes.protected()
|
|
1001
|
-
});
|
|
1002
|
-
return SwapStatus.fromDto(dto);
|
|
1003
|
-
}
|
|
1004
|
-
async function getTokenAllowance(api, params) {
|
|
1005
|
-
const dto = await api.send({
|
|
1006
|
-
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()
|
|
1015
|
-
});
|
|
1016
|
-
return TokenAllowance.fromDto(dto);
|
|
1826
|
+
// src/shared/api/frontline/offers.ts
|
|
1827
|
+
async function fetchOffers(api, clientCreds) {
|
|
1828
|
+
return fetchAllPages((params) => fetchOffersPage(api, params, clientCreds));
|
|
1017
1829
|
}
|
|
1018
|
-
async function
|
|
1019
|
-
const
|
|
1830
|
+
async function fetchOffersPage(api, params, clientCreds) {
|
|
1831
|
+
const queryParams = PaginationParams.toQueryParams(params);
|
|
1832
|
+
const pageDto = await api.send({
|
|
1020
1833
|
method: "GET",
|
|
1021
|
-
url: "/v1/
|
|
1022
|
-
queryParams
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
attributes: Attributes.protected()
|
|
1834
|
+
url: "/v1/offers",
|
|
1835
|
+
queryParams,
|
|
1836
|
+
attributes: Attributes.concat(
|
|
1837
|
+
Attributes.protected(),
|
|
1838
|
+
Attributes.clientCredentials(clientCreds)
|
|
1839
|
+
)
|
|
1028
1840
|
});
|
|
1029
|
-
return
|
|
1841
|
+
return PaginatedResponse.fromDto(pageDto, Offer.fromDto);
|
|
1030
1842
|
}
|
|
1031
|
-
async function
|
|
1843
|
+
async function fetchOfferDetails(api, id, clientCreds) {
|
|
1032
1844
|
const dto = await api.send({
|
|
1033
|
-
method: "
|
|
1034
|
-
url: `/v1/offers/${
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
},
|
|
1040
|
-
attributes: Attributes.protected()
|
|
1845
|
+
method: "GET",
|
|
1846
|
+
url: `/v1/offers/${id}`,
|
|
1847
|
+
attributes: Attributes.concat(
|
|
1848
|
+
Attributes.protected(),
|
|
1849
|
+
Attributes.clientCredentials(clientCreds)
|
|
1850
|
+
)
|
|
1041
1851
|
});
|
|
1042
|
-
return
|
|
1043
|
-
}
|
|
1044
|
-
function toErc20Asset(dto) {
|
|
1045
|
-
return {
|
|
1046
|
-
name: dto.name,
|
|
1047
|
-
symbol: AssetSymbol(dto.symbol),
|
|
1048
|
-
decimals: AssetDecimals(dto.decimals)
|
|
1049
|
-
};
|
|
1852
|
+
return OfferDetail.fromDto(dto);
|
|
1050
1853
|
}
|
|
1051
1854
|
|
|
1052
|
-
// src/shared/core/
|
|
1053
|
-
var
|
|
1855
|
+
// src/shared/core/offers/offers-namespace.ts
|
|
1856
|
+
var OffersNamespaceImpl = class {
|
|
1054
1857
|
constructor(ctx) {
|
|
1055
1858
|
this.ctx = ctx;
|
|
1056
1859
|
}
|
|
1057
|
-
async
|
|
1860
|
+
async list() {
|
|
1058
1861
|
await this.ctx.ensureUserAuthenticated();
|
|
1059
|
-
return
|
|
1862
|
+
return fetchOffers(this.ctx.api, void 0);
|
|
1060
1863
|
}
|
|
1061
|
-
async
|
|
1864
|
+
async listPage(params) {
|
|
1062
1865
|
await this.ctx.ensureUserAuthenticated();
|
|
1063
|
-
return
|
|
1866
|
+
return fetchOffersPage(this.ctx.api, params, void 0);
|
|
1867
|
+
}
|
|
1868
|
+
async get(id) {
|
|
1869
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1870
|
+
return fetchOfferDetails(this.ctx.api, id, void 0);
|
|
1064
1871
|
}
|
|
1065
1872
|
};
|
|
1066
1873
|
|
|
1067
|
-
// src/shared/types/
|
|
1068
|
-
var
|
|
1069
|
-
var AssetCode = (value) => value;
|
|
1070
|
-
var Asset = {
|
|
1874
|
+
// src/shared/types/document-submission.ts
|
|
1875
|
+
var DocumentSubmission = {
|
|
1071
1876
|
fromDto: (dto) => ({
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
name: dto.name,
|
|
1075
|
-
fractionalDigits: dto.fractional_digits
|
|
1877
|
+
status: dto.status,
|
|
1878
|
+
formType: dto.form_type
|
|
1076
1879
|
})
|
|
1077
1880
|
};
|
|
1078
1881
|
|
|
1079
|
-
// src/shared/
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1882
|
+
// src/shared/api/frontline/documents.ts
|
|
1883
|
+
async function submitDocument(api, documentType, fields) {
|
|
1884
|
+
const dto = await api.send({
|
|
1885
|
+
method: "POST",
|
|
1886
|
+
url: `/v1/documents/${documentType}/submission`,
|
|
1887
|
+
body: fields,
|
|
1888
|
+
attributes: Attributes.protected()
|
|
1889
|
+
});
|
|
1890
|
+
return DocumentSubmission.fromDto(dto);
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
// src/shared/types/kyc.ts
|
|
1894
|
+
var KycToken = {
|
|
1083
1895
|
fromDto: (dto) => ({
|
|
1084
|
-
|
|
1085
|
-
slug: OfferSlug(dto.slug),
|
|
1086
|
-
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
|
|
1896
|
+
token: dto.token
|
|
1092
1897
|
})
|
|
1093
1898
|
};
|
|
1094
1899
|
|
|
1095
|
-
// src/shared/
|
|
1096
|
-
async function
|
|
1097
|
-
const
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
for (let i = 0; i < bytes.length; i++) {
|
|
1108
|
-
binary += String.fromCharCode(bytes[i]);
|
|
1109
|
-
}
|
|
1110
|
-
let base64 = btoa(binary);
|
|
1111
|
-
base64 = base64.replace(/\+/g, "-").replace(/\//g, "_");
|
|
1112
|
-
if (!padding) {
|
|
1113
|
-
base64 = base64.replace(/=+$/, "");
|
|
1114
|
-
}
|
|
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;
|
|
1128
|
-
}
|
|
1900
|
+
// src/shared/api/frontline/kyc.ts
|
|
1901
|
+
async function createKycToken(api, levelName, reset) {
|
|
1902
|
+
const dto = await api.send({
|
|
1903
|
+
method: "POST",
|
|
1904
|
+
url: "/v1/kyc-token",
|
|
1905
|
+
body: {
|
|
1906
|
+
...levelName === void 0 ? {} : { level_name: levelName },
|
|
1907
|
+
...reset === void 0 ? {} : { reset }
|
|
1908
|
+
},
|
|
1909
|
+
attributes: Attributes.protected()
|
|
1910
|
+
});
|
|
1911
|
+
return KycToken.fromDto(dto);
|
|
1129
1912
|
}
|
|
1130
1913
|
|
|
1131
|
-
// src/shared/types/
|
|
1132
|
-
var
|
|
1133
|
-
var
|
|
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`);
|
|
1144
|
-
}
|
|
1145
|
-
if (!Array.isArray(dto.links)) {
|
|
1146
|
-
throw new Error(`links must be an array`);
|
|
1147
|
-
}
|
|
1148
|
-
if (!Array.isArray(dto.faqs)) {
|
|
1149
|
-
throw new Error(`faqs must be an array`);
|
|
1150
|
-
}
|
|
1151
|
-
if (!Array.isArray(dto.milestones)) {
|
|
1152
|
-
throw new Error(`milestones must be an array`);
|
|
1153
|
-
}
|
|
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
|
-
}
|
|
1175
|
-
};
|
|
1176
|
-
var OfferOption = {
|
|
1914
|
+
// src/shared/types/pii.ts
|
|
1915
|
+
var Iso2CountryCode = (value) => value;
|
|
1916
|
+
var PiiJurisdiction = {
|
|
1177
1917
|
fromDto: (dto) => ({
|
|
1178
|
-
|
|
1179
|
-
|
|
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
|
|
1918
|
+
iso2: Iso2CountryCode(dto.iso_2),
|
|
1919
|
+
name: dto.name
|
|
1186
1920
|
})
|
|
1187
1921
|
};
|
|
1188
|
-
var
|
|
1922
|
+
var PiiAddress = {
|
|
1189
1923
|
fromDto: (dto) => ({
|
|
1190
|
-
|
|
1191
|
-
|
|
1924
|
+
street: dto.street,
|
|
1925
|
+
city: dto.city,
|
|
1926
|
+
state: dto.state,
|
|
1927
|
+
postalCode: dto.postal_code,
|
|
1928
|
+
country: dto.country
|
|
1192
1929
|
})
|
|
1193
1930
|
};
|
|
1194
|
-
var
|
|
1931
|
+
var Pii = {
|
|
1195
1932
|
fromDto: (dto) => ({
|
|
1196
|
-
|
|
1197
|
-
|
|
1933
|
+
kind: dto.kind,
|
|
1934
|
+
fullLegalName: dto.full_legal_name,
|
|
1935
|
+
dateOfBirth: dto.date_of_birth,
|
|
1936
|
+
jurisdiction: dto.jurisdiction ? PiiJurisdiction.fromDto(dto.jurisdiction) : null,
|
|
1937
|
+
taxId: dto.tax_id,
|
|
1938
|
+
permanentAddress: PiiAddress.fromDto(dto.permanent_address)
|
|
1198
1939
|
})
|
|
1199
1940
|
};
|
|
1200
|
-
|
|
1941
|
+
|
|
1942
|
+
// src/shared/api/frontline/pii.ts
|
|
1943
|
+
async function fetchPii(api) {
|
|
1944
|
+
const dto = await api.send({
|
|
1945
|
+
method: "GET",
|
|
1946
|
+
url: "/v1/pii",
|
|
1947
|
+
attributes: Attributes.protected()
|
|
1948
|
+
});
|
|
1949
|
+
return Pii.fromDto(dto);
|
|
1950
|
+
}
|
|
1951
|
+
|
|
1952
|
+
// src/shared/types/requirement.ts
|
|
1953
|
+
var RequirementId = (value) => value;
|
|
1954
|
+
var Requirement = {
|
|
1201
1955
|
fromDto: (dto) => ({
|
|
1202
|
-
|
|
1203
|
-
|
|
1956
|
+
id: RequirementId(dto.id),
|
|
1957
|
+
type: dto.type,
|
|
1958
|
+
details: dto.details
|
|
1204
1959
|
})
|
|
1205
1960
|
};
|
|
1206
|
-
var
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1961
|
+
var RequirementStatusInfo = {
|
|
1962
|
+
fromStatusesDto: (dto) => Object.entries(dto.statuses).map(
|
|
1963
|
+
([id, value]) => typeof value === "string" ? { id: RequirementId(id), status: value, action: null } : {
|
|
1964
|
+
id: RequirementId(id),
|
|
1965
|
+
status: value.status,
|
|
1966
|
+
action: value.action ?? null,
|
|
1967
|
+
kycLevel: value.kyc_level,
|
|
1968
|
+
kycReset: value.kyc_reset
|
|
1969
|
+
}
|
|
1970
|
+
)
|
|
1971
|
+
};
|
|
1972
|
+
|
|
1973
|
+
// src/shared/api/frontline/requirements.ts
|
|
1974
|
+
async function fetchOfferRequirements(api, offerId, clientCreds) {
|
|
1975
|
+
const response = await api.send({
|
|
1976
|
+
method: "GET",
|
|
1977
|
+
url: `/v1/offers/${offerId}/requirements`,
|
|
1978
|
+
attributes: Attributes.concat(
|
|
1979
|
+
Attributes.protected(),
|
|
1980
|
+
Attributes.clientCredentials(clientCreds)
|
|
1981
|
+
)
|
|
1982
|
+
});
|
|
1983
|
+
return Object.fromEntries(
|
|
1984
|
+
Object.entries(response.options).map(([optionId, list]) => [
|
|
1985
|
+
optionId,
|
|
1986
|
+
list.data.map(Requirement.fromDto)
|
|
1987
|
+
])
|
|
1988
|
+
);
|
|
1989
|
+
}
|
|
1990
|
+
async function fetchRequirementStatuses(api, offerId) {
|
|
1991
|
+
const response = await api.send({
|
|
1992
|
+
method: "GET",
|
|
1993
|
+
url: `/v1/offers/${offerId}/requirements/statuses`,
|
|
1994
|
+
attributes: Attributes.protected()
|
|
1995
|
+
});
|
|
1996
|
+
return RequirementStatusInfo.fromStatusesDto(response);
|
|
1997
|
+
}
|
|
1998
|
+
|
|
1999
|
+
// src/shared/core/requirements/requirements-namespace.ts
|
|
2000
|
+
var RequirementsNamespaceImpl = class {
|
|
2001
|
+
constructor(ctx) {
|
|
2002
|
+
this.ctx = ctx;
|
|
2003
|
+
}
|
|
2004
|
+
async forOffer(offerId) {
|
|
2005
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2006
|
+
return fetchOfferRequirements(
|
|
2007
|
+
this.ctx.api,
|
|
2008
|
+
offerId,
|
|
2009
|
+
void 0
|
|
2010
|
+
);
|
|
2011
|
+
}
|
|
2012
|
+
async statuses(offerId) {
|
|
2013
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2014
|
+
return fetchRequirementStatuses(this.ctx.api, offerId);
|
|
2015
|
+
}
|
|
2016
|
+
async createKycToken(params) {
|
|
2017
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2018
|
+
return createKycToken(
|
|
2019
|
+
this.ctx.api,
|
|
2020
|
+
params?.levelName,
|
|
2021
|
+
params?.reset
|
|
2022
|
+
);
|
|
2023
|
+
}
|
|
2024
|
+
async getPii() {
|
|
2025
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2026
|
+
return fetchPii(this.ctx.api);
|
|
2027
|
+
}
|
|
2028
|
+
async submitDocument(params) {
|
|
2029
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2030
|
+
return submitDocument(
|
|
2031
|
+
this.ctx.api,
|
|
2032
|
+
params.documentType,
|
|
2033
|
+
params.fields
|
|
2034
|
+
);
|
|
2035
|
+
}
|
|
2036
|
+
};
|
|
2037
|
+
|
|
2038
|
+
// src/shared/api/nabu/tokens.ts
|
|
2039
|
+
var import_viem4 = require("viem");
|
|
2040
|
+
|
|
2041
|
+
// src/shared/api/frontline/config.ts
|
|
2042
|
+
var HEADER_API_VERSION = "X-API-Version";
|
|
2043
|
+
|
|
2044
|
+
// src/shared/api/http-client.ts
|
|
2045
|
+
var HttpClient = class {
|
|
2046
|
+
constructor(config, middleware = {}) {
|
|
2047
|
+
this.config = config;
|
|
2048
|
+
this.middleware = middleware;
|
|
2049
|
+
}
|
|
2050
|
+
async send(request) {
|
|
2051
|
+
return this.runRequestWithAfterMiddleware(request);
|
|
2052
|
+
}
|
|
2053
|
+
/**
|
|
2054
|
+
* Runs beforeRequest, executeRequest, then the full afterRequest middleware
|
|
2055
|
+
* chain. Used by send() and by the retry() callback so that when a
|
|
2056
|
+
* middleware calls retry(), the retried response also goes through all
|
|
2057
|
+
* afterRequest middleware (e.g. session renewal, retry). Middleware
|
|
2058
|
+
* must use request.attributes.retryAttempt (or similar) to avoid infinite
|
|
2059
|
+
* recursion when they trigger retries.
|
|
2060
|
+
*/
|
|
2061
|
+
async runRequestWithAfterMiddleware(request) {
|
|
2062
|
+
const preparedRequest = await this.runBeforeRequestMiddleware(
|
|
2063
|
+
this.withClientDefaults(request)
|
|
2064
|
+
);
|
|
2065
|
+
let response = await this.executeRequest(preparedRequest);
|
|
2066
|
+
for (const middleware of this.middleware.afterRequest ?? []) {
|
|
2067
|
+
response = await middleware({
|
|
2068
|
+
request: preparedRequest,
|
|
2069
|
+
response,
|
|
2070
|
+
retry: (nextRequest = preparedRequest) => this.runRequestWithAfterMiddleware(nextRequest)
|
|
2071
|
+
});
|
|
2072
|
+
}
|
|
2073
|
+
return response;
|
|
2074
|
+
}
|
|
2075
|
+
withClientDefaults(request) {
|
|
2076
|
+
const url = this.resolveUrl(request.url);
|
|
2077
|
+
const headers = {
|
|
2078
|
+
...request.headers ?? {},
|
|
2079
|
+
...this.config.xApiVersion !== void 0 ? { [HEADER_API_VERSION]: this.config.xApiVersion } : {}
|
|
2080
|
+
};
|
|
2081
|
+
return {
|
|
2082
|
+
...request,
|
|
2083
|
+
url,
|
|
2084
|
+
headers
|
|
2085
|
+
};
|
|
2086
|
+
}
|
|
2087
|
+
/**
|
|
2088
|
+
* Resolves a request URL against the client's baseUrl.
|
|
2089
|
+
*
|
|
2090
|
+
* @internal Public only for testing. Do not use in application code; use
|
|
2091
|
+
* {@link HttpClient.send} with a path and the client will resolve the URL.
|
|
2092
|
+
*/
|
|
2093
|
+
resolveUrl(url) {
|
|
2094
|
+
if (url.startsWith("http://") || url.startsWith("https://")) {
|
|
2095
|
+
return url;
|
|
2096
|
+
}
|
|
2097
|
+
const base = this.config.baseUrl.replace(/\/$/, "");
|
|
2098
|
+
const path = url.startsWith("/") ? url : `/${url}`;
|
|
2099
|
+
return base + path;
|
|
2100
|
+
}
|
|
2101
|
+
async runBeforeRequestMiddleware(initialRequest) {
|
|
2102
|
+
let request = initialRequest;
|
|
2103
|
+
for (const middleware of this.middleware.beforeRequest ?? []) {
|
|
2104
|
+
request = await middleware(request);
|
|
2105
|
+
}
|
|
2106
|
+
return request;
|
|
2107
|
+
}
|
|
2108
|
+
executeRequest(request) {
|
|
2109
|
+
return makeRequest(request);
|
|
2110
|
+
}
|
|
2111
|
+
};
|
|
2112
|
+
|
|
2113
|
+
// src/shared/types/token-metadata.ts
|
|
2114
|
+
var TokenLogoUrl = (value) => value;
|
|
2115
|
+
var TokenLogo = {
|
|
2116
|
+
/** `baseUrl` is the registry origin; registry URLs are root-relative. */
|
|
2117
|
+
fromDto: (dto, baseUrl) => dto.kind === "VECTOR" ? { kind: "VECTOR", url: resolveLogoUrl(dto.url, baseUrl) } : {
|
|
2118
|
+
kind: "RASTER",
|
|
2119
|
+
original: logoImageFromDto(dto.original, baseUrl),
|
|
2120
|
+
variants: dto.variants.map((v) => logoImageFromDto(v, baseUrl))
|
|
2121
|
+
}
|
|
2122
|
+
};
|
|
2123
|
+
var TokenMetadata = {
|
|
2124
|
+
/** `baseUrl` is the registry origin; registry logo URLs are root-relative. */
|
|
2125
|
+
fromDto: (dto, baseUrl) => {
|
|
2126
|
+
assertSupportedSchemaVersion(dto.schema_version);
|
|
2127
|
+
return {
|
|
2128
|
+
identifier: {
|
|
2129
|
+
chain: EthereumChain(dto.chain),
|
|
2130
|
+
address: EvmContractAddress(dto.address)
|
|
2131
|
+
},
|
|
2132
|
+
name: dto.name,
|
|
2133
|
+
symbol: AssetSymbol(dto.symbol),
|
|
2134
|
+
decimals: AssetDecimals(dto.decimals),
|
|
2135
|
+
logo: TokenLogo.fromDto(dto.logo, baseUrl),
|
|
2136
|
+
logoDark: dto.logo_dark === void 0 ? null : TokenLogo.fromDto(dto.logo_dark, baseUrl)
|
|
2137
|
+
};
|
|
2138
|
+
},
|
|
2139
|
+
/**
|
|
2140
|
+
* Maps a chain snapshot to the tokens it lists, skipping the chain's native
|
|
2141
|
+
* coin (`kind: 'COIN'`, no contract address).
|
|
2142
|
+
*/
|
|
2143
|
+
fromChainAssetsDto: (dto, baseUrl) => {
|
|
2144
|
+
assertSupportedSchemaVersion(dto.schema_version);
|
|
2145
|
+
const chain = EthereumChain(dto.chain);
|
|
2146
|
+
return dto.assets.filter((asset) => asset.kind === "TOKEN" && asset.address !== void 0).map((asset) => ({
|
|
2147
|
+
identifier: {
|
|
2148
|
+
chain,
|
|
2149
|
+
// The filter above cannot narrow `address` for the type checker.
|
|
2150
|
+
address: EvmContractAddress(asset.address)
|
|
2151
|
+
},
|
|
2152
|
+
name: asset.name,
|
|
2153
|
+
symbol: AssetSymbol(asset.symbol),
|
|
2154
|
+
decimals: AssetDecimals(asset.decimals),
|
|
2155
|
+
logo: TokenLogo.fromDto(asset.logo, baseUrl),
|
|
2156
|
+
logoDark: asset.logo_dark === void 0 ? null : TokenLogo.fromDto(asset.logo_dark, baseUrl)
|
|
2157
|
+
}));
|
|
2158
|
+
}
|
|
2159
|
+
};
|
|
2160
|
+
function assertSupportedSchemaVersion(version) {
|
|
2161
|
+
if (version !== 1) {
|
|
2162
|
+
throw new ValidationError(
|
|
2163
|
+
`Unsupported token registry schema_version: ${version}`
|
|
2164
|
+
);
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
var logoImageFromDto = (dto, baseUrl) => ({
|
|
2168
|
+
url: resolveLogoUrl(dto.url, baseUrl),
|
|
2169
|
+
width: dto.width,
|
|
2170
|
+
height: dto.height
|
|
2171
|
+
});
|
|
2172
|
+
var resolveLogoUrl = (url, baseUrl) => TokenLogoUrl(
|
|
2173
|
+
url.startsWith("http") ? url : `${baseUrl.replace(/\/$/, "")}${url}`
|
|
2174
|
+
);
|
|
2175
|
+
|
|
2176
|
+
// src/shared/api/nabu/tokens.ts
|
|
2177
|
+
function createNabuApiClient(baseUrl) {
|
|
2178
|
+
return new HttpClient({ baseUrl });
|
|
2179
|
+
}
|
|
2180
|
+
async function fetchTokenMetadata(client, token) {
|
|
2181
|
+
const address = checksummed(token.address);
|
|
2182
|
+
let response;
|
|
2183
|
+
try {
|
|
2184
|
+
response = await client.send({
|
|
2185
|
+
method: "GET",
|
|
2186
|
+
url: `/${token.chain}/token/${address}`
|
|
2187
|
+
});
|
|
2188
|
+
} catch (error) {
|
|
2189
|
+
if (isRegistryHtmlFallback(error)) {
|
|
2190
|
+
return null;
|
|
2191
|
+
}
|
|
2192
|
+
throw error;
|
|
2193
|
+
}
|
|
2194
|
+
if (response.status === 404) {
|
|
2195
|
+
return null;
|
|
2196
|
+
}
|
|
2197
|
+
assertOk(response);
|
|
2198
|
+
if (response.body === null) {
|
|
2199
|
+
throw new ValidationError(
|
|
2200
|
+
`Token registry returned an empty body for token "${address}" on "${token.chain}"`
|
|
2201
|
+
);
|
|
2202
|
+
}
|
|
2203
|
+
return TokenMetadata.fromDto(response.body, client.config.baseUrl);
|
|
2204
|
+
}
|
|
2205
|
+
async function fetchTokensMetadata(client, chain) {
|
|
2206
|
+
let response;
|
|
2207
|
+
try {
|
|
2208
|
+
response = await client.send({
|
|
2209
|
+
method: "GET",
|
|
2210
|
+
url: `/${chain}/assets.json`
|
|
2211
|
+
});
|
|
2212
|
+
} catch (error) {
|
|
2213
|
+
if (isRegistryHtmlFallback(error)) {
|
|
2214
|
+
throw new ValidationError(
|
|
2215
|
+
`Token registry returned non-JSON for the "${chain}" snapshot`
|
|
2216
|
+
);
|
|
2217
|
+
}
|
|
2218
|
+
throw error;
|
|
2219
|
+
}
|
|
2220
|
+
assertOk(response);
|
|
2221
|
+
if (response.body === null) {
|
|
2222
|
+
throw new ValidationError(
|
|
2223
|
+
`Token registry returned an empty "${chain}" snapshot`
|
|
2224
|
+
);
|
|
2225
|
+
}
|
|
2226
|
+
return TokenMetadata.fromChainAssetsDto(response.body, client.config.baseUrl);
|
|
2227
|
+
}
|
|
2228
|
+
function isRegistryHtmlFallback(error) {
|
|
2229
|
+
return error instanceof HttpError && error.response.status >= 200 && error.response.status < 300;
|
|
2230
|
+
}
|
|
2231
|
+
function assertOk(response) {
|
|
2232
|
+
if (response.status < 200 || response.status >= 300) {
|
|
2233
|
+
throw new HttpError(response);
|
|
2234
|
+
}
|
|
2235
|
+
}
|
|
2236
|
+
function checksummed(address) {
|
|
2237
|
+
try {
|
|
2238
|
+
return (0, import_viem4.getAddress)(address);
|
|
2239
|
+
} catch (_) {
|
|
2240
|
+
throw new ValidationError(`Invalid EVM contract address: "${address}"`);
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
|
|
2244
|
+
// src/shared/core/tokens/tokens-namespace.ts
|
|
2245
|
+
var TokensNamespaceImpl = class {
|
|
2246
|
+
/**
|
|
2247
|
+
* Takes the registry origin rather than a `SharedNamespaceContext`: the
|
|
2248
|
+
* registry is unauthenticated and on its own host, so the frontline sender
|
|
2249
|
+
* and the auth check would both be dead weight here.
|
|
2250
|
+
*/
|
|
2251
|
+
constructor(baseUrl) {
|
|
2252
|
+
this.api = createNabuApiClient(baseUrl);
|
|
2253
|
+
}
|
|
2254
|
+
get(token) {
|
|
2255
|
+
return fetchTokenMetadata(this.api, token);
|
|
2256
|
+
}
|
|
2257
|
+
list(chain) {
|
|
2258
|
+
return fetchTokensMetadata(this.api, chain);
|
|
2259
|
+
}
|
|
1212
2260
|
};
|
|
1213
2261
|
|
|
1214
2262
|
// src/shared/types/offer-option-address.ts
|
|
@@ -1282,197 +2330,67 @@ async function createWalletOwnershipChallenge(api, params) {
|
|
|
1282
2330
|
});
|
|
1283
2331
|
return WalletOwnershipChallenge.fromDto(dto);
|
|
1284
2332
|
}
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
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),
|
|
2333
|
+
async function connectExternalWallet(api, params) {
|
|
2334
|
+
const dto = await api.send({
|
|
2335
|
+
method: "POST",
|
|
2336
|
+
url: `/v1/offers/${params.offerId}/addresses`,
|
|
2337
|
+
body: ConnectExternalWalletParams.toDto(params),
|
|
1376
2338
|
attributes: Attributes.protected()
|
|
1377
2339
|
});
|
|
1378
|
-
return
|
|
2340
|
+
return OfferOptionAddress.fromDto(dto);
|
|
1379
2341
|
}
|
|
1380
|
-
async function
|
|
1381
|
-
const
|
|
2342
|
+
async function listOptionAddresses(api, offerId, offerOptionId) {
|
|
2343
|
+
const { data } = await api.send({
|
|
1382
2344
|
method: "GET",
|
|
1383
|
-
url: `/v1/
|
|
2345
|
+
url: `/v1/offers/${offerId}/addresses`,
|
|
2346
|
+
queryParams: { offer_option_id: offerOptionId },
|
|
1384
2347
|
attributes: Attributes.protected()
|
|
1385
2348
|
});
|
|
1386
|
-
return
|
|
2349
|
+
return data.map(OfferOptionAddress.fromDto);
|
|
1387
2350
|
}
|
|
1388
|
-
async function
|
|
2351
|
+
async function removeOptionAddress(api, offerId, addressId) {
|
|
1389
2352
|
const dto = await api.send({
|
|
1390
|
-
method: "
|
|
1391
|
-
url:
|
|
1392
|
-
body: CreateParticipationParams.toDto(params),
|
|
2353
|
+
method: "DELETE",
|
|
2354
|
+
url: `/v1/offers/${offerId}/addresses/${addressId}`,
|
|
1393
2355
|
attributes: Attributes.protected()
|
|
1394
2356
|
});
|
|
1395
|
-
return
|
|
2357
|
+
return OfferOptionAddress.fromDto(dto);
|
|
1396
2358
|
}
|
|
1397
2359
|
|
|
1398
|
-
// src/shared/core/
|
|
1399
|
-
var
|
|
2360
|
+
// src/shared/core/wallets/wallets-namespace.ts
|
|
2361
|
+
var WalletsNamespaceImpl = class {
|
|
1400
2362
|
constructor(ctx) {
|
|
1401
2363
|
this.ctx = ctx;
|
|
1402
2364
|
}
|
|
1403
|
-
async
|
|
2365
|
+
async createOwnershipChallenge(params) {
|
|
1404
2366
|
await this.ctx.ensureUserAuthenticated();
|
|
1405
|
-
return
|
|
2367
|
+
return createWalletOwnershipChallenge(
|
|
2368
|
+
this.ctx.api,
|
|
2369
|
+
params
|
|
2370
|
+
);
|
|
1406
2371
|
}
|
|
1407
|
-
async
|
|
2372
|
+
async connectExternal(params) {
|
|
1408
2373
|
await this.ctx.ensureUserAuthenticated();
|
|
1409
|
-
return
|
|
2374
|
+
return connectExternalWallet(this.ctx.api, params);
|
|
1410
2375
|
}
|
|
1411
|
-
async
|
|
2376
|
+
async list(params) {
|
|
1412
2377
|
await this.ctx.ensureUserAuthenticated();
|
|
1413
|
-
return
|
|
2378
|
+
return listOptionAddresses(
|
|
2379
|
+
this.ctx.api,
|
|
2380
|
+
params.offerId,
|
|
2381
|
+
params.offerOptionId
|
|
2382
|
+
);
|
|
1414
2383
|
}
|
|
1415
|
-
async
|
|
2384
|
+
async remove(params) {
|
|
1416
2385
|
await this.ctx.ensureUserAuthenticated();
|
|
1417
|
-
return
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
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";
|
|
1460
|
-
}
|
|
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";
|
|
2386
|
+
return removeOptionAddress(
|
|
2387
|
+
this.ctx.api,
|
|
2388
|
+
params.offerId,
|
|
2389
|
+
params.addressId
|
|
2390
|
+
);
|
|
1466
2391
|
}
|
|
1467
2392
|
};
|
|
1468
2393
|
|
|
1469
|
-
// src/shared/types/kyc.ts
|
|
1470
|
-
var KycToken = {
|
|
1471
|
-
fromDto: (dto) => ({
|
|
1472
|
-
token: dto.token
|
|
1473
|
-
})
|
|
1474
|
-
};
|
|
1475
|
-
|
|
1476
2394
|
// src/shared/types/oauth-session.ts
|
|
1477
2395
|
var ClientCredentialsOAuth = (value) => value;
|
|
1478
2396
|
var OAuthRefreshToken = (value) => value;
|
|
@@ -1489,55 +2407,6 @@ var OAuthSession = {
|
|
|
1489
2407
|
}
|
|
1490
2408
|
};
|
|
1491
2409
|
|
|
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
2410
|
// src/shared/types/user.ts
|
|
1542
2411
|
var UserId = (value) => value;
|
|
1543
2412
|
var UserEmail = (value) => value;
|
|
@@ -1561,20 +2430,26 @@ var User = {
|
|
|
1561
2430
|
Blockchain,
|
|
1562
2431
|
BlockchainAmount,
|
|
1563
2432
|
Bps,
|
|
2433
|
+
Chain,
|
|
1564
2434
|
ClientCredentialsOAuth,
|
|
1565
2435
|
ClientId,
|
|
1566
2436
|
ClientSecret,
|
|
1567
2437
|
CodeChallenge,
|
|
1568
2438
|
CodeVerifier,
|
|
2439
|
+
CoinListTokenSaleNamespaceImpl,
|
|
1569
2440
|
ConnectExternalWalletParams,
|
|
1570
2441
|
CreateParticipationParams,
|
|
1571
2442
|
CreateWalletOwnershipChallengeParams,
|
|
1572
2443
|
Cursor,
|
|
1573
2444
|
DEFAULT_AMOUNT_TO_COMPUTE_PRICE,
|
|
2445
|
+
DEFAULT_ONDO_AMOUNT_TO_COMPUTE_PRICE,
|
|
1574
2446
|
DEFAULT_SLIPPAGE_BPS,
|
|
2447
|
+
DecimalString,
|
|
1575
2448
|
DocumentSubmission,
|
|
1576
2449
|
ERC20_ABI,
|
|
2450
|
+
ETHEREUM_CHAINS,
|
|
1577
2451
|
Erc20NamespaceImpl,
|
|
2452
|
+
EthereumChain,
|
|
1578
2453
|
EvmContractAddress,
|
|
1579
2454
|
EvmWalletAddress,
|
|
1580
2455
|
FaqItem,
|
|
@@ -1582,10 +2457,12 @@ var User = {
|
|
|
1582
2457
|
FormattedAmountUi,
|
|
1583
2458
|
FormattedPercentUi,
|
|
1584
2459
|
HexEncodedTransactionData,
|
|
2460
|
+
HttpError,
|
|
1585
2461
|
Iso2CountryCode,
|
|
1586
2462
|
KnownAssetSymbol,
|
|
1587
2463
|
KycToken,
|
|
1588
2464
|
Link,
|
|
2465
|
+
MAX_ASSET_DECIMALS,
|
|
1589
2466
|
MAX_UINT_256,
|
|
1590
2467
|
Milestone,
|
|
1591
2468
|
NA_AMOUNT_ASSET_UI,
|
|
@@ -1593,6 +2470,9 @@ var User = {
|
|
|
1593
2470
|
NotImplementedError,
|
|
1594
2471
|
OAuthRefreshToken,
|
|
1595
2472
|
OAuthSession,
|
|
2473
|
+
ONDO_POLL_INTERVAL_MS,
|
|
2474
|
+
ONDO_QUOTE_EXPIRY_THRESHOLD_MS,
|
|
2475
|
+
ONDO_SUPPORTED_INPUT_ASSETS,
|
|
1596
2476
|
Offer,
|
|
1597
2477
|
OfferDetail,
|
|
1598
2478
|
OfferId,
|
|
@@ -1602,6 +2482,12 @@ var User = {
|
|
|
1602
2482
|
OfferOptionId,
|
|
1603
2483
|
OfferOptionSlug,
|
|
1604
2484
|
OfferSlug,
|
|
2485
|
+
OfferToken,
|
|
2486
|
+
OffersNamespaceImpl,
|
|
2487
|
+
OndoNamespaceImpl,
|
|
2488
|
+
OndoQuote,
|
|
2489
|
+
OndoSwapTransaction,
|
|
2490
|
+
OndoTradingStatus,
|
|
1605
2491
|
PKCEState,
|
|
1606
2492
|
PaginatedResponse,
|
|
1607
2493
|
PaginationParams,
|
|
@@ -1615,23 +2501,32 @@ var User = {
|
|
|
1615
2501
|
Requirement,
|
|
1616
2502
|
RequirementId,
|
|
1617
2503
|
RequirementStatusInfo,
|
|
2504
|
+
RequirementsNamespaceImpl,
|
|
1618
2505
|
SLIPPAGE_OPTIONS_BPS,
|
|
2506
|
+
SOLANA_CHAINS,
|
|
2507
|
+
STABLE_DECIMALS,
|
|
2508
|
+
SUPERSTATE_ISSUER_NAME,
|
|
2509
|
+
SUPERSTATE_SUPPORTED_INPUT_ASSETS,
|
|
1619
2510
|
SUPERSTATE_SWAP_ABI,
|
|
1620
2511
|
SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA,
|
|
1621
|
-
SUPERSTATE_TOS_URL,
|
|
1622
2512
|
SWAP_POLL_INTERVAL_MS,
|
|
1623
2513
|
ShortenedWalletAddress,
|
|
2514
|
+
SolanaChain,
|
|
1624
2515
|
StablecoinSymbol,
|
|
2516
|
+
SuperstateSwapNamespaceImpl,
|
|
1625
2517
|
SwapAuthorization,
|
|
1626
|
-
SwapNamespaceImpl,
|
|
1627
2518
|
SwapPreview,
|
|
1628
2519
|
SwapQuote,
|
|
1629
2520
|
SwapStatus,
|
|
1630
2521
|
TOKEN_REGISTRY,
|
|
1631
2522
|
TermItem,
|
|
2523
|
+
Ticker,
|
|
1632
2524
|
TokenAllowance,
|
|
1633
2525
|
TokenBalance,
|
|
1634
|
-
|
|
2526
|
+
TokenLogo,
|
|
2527
|
+
TokenLogoUrl,
|
|
2528
|
+
TokenMetadata,
|
|
2529
|
+
TokensNamespaceImpl,
|
|
1635
2530
|
TxExplorerUrl,
|
|
1636
2531
|
USDC,
|
|
1637
2532
|
USDC_SYMBOL,
|
|
@@ -1640,11 +2535,17 @@ var User = {
|
|
|
1640
2535
|
User,
|
|
1641
2536
|
UserEmail,
|
|
1642
2537
|
UserId,
|
|
2538
|
+
ValidationError,
|
|
1643
2539
|
WalletAddress,
|
|
1644
2540
|
WalletOwnershipChallenge,
|
|
2541
|
+
WalletsNamespaceImpl,
|
|
2542
|
+
apiErrorCode,
|
|
1645
2543
|
applyBps,
|
|
1646
2544
|
assertUint256,
|
|
1647
2545
|
assetAmount,
|
|
2546
|
+
blockchainAmountFromRawOrThrow,
|
|
2547
|
+
chainFromId,
|
|
2548
|
+
computeOndoPrice,
|
|
1648
2549
|
computePrice,
|
|
1649
2550
|
computeSlip,
|
|
1650
2551
|
decodeSwappedOutputAmount,
|
|
@@ -1659,8 +2560,10 @@ var User = {
|
|
|
1659
2560
|
getChainId,
|
|
1660
2561
|
getNetworkName,
|
|
1661
2562
|
isStopped,
|
|
2563
|
+
ondoSwapContractAddress,
|
|
1662
2564
|
parseBlockchainAmount,
|
|
1663
2565
|
shortenAddress,
|
|
2566
|
+
superstateSwapContractAddress,
|
|
1664
2567
|
txExplorerUrl,
|
|
1665
2568
|
usdAmount
|
|
1666
2569
|
});
|