@coinlist-co/react 0.10.1 → 0.11.1-rc.22d81d4
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-AQIHCFW4.js +279 -0
- package/dist/chunk-AQIHCFW4.js.map +1 -0
- package/dist/{chunk-AQVCOWOV.js → chunk-PRG3EDQJ.js} +216 -317
- package/dist/chunk-PRG3EDQJ.js.map +1 -0
- package/dist/chunk-ZVB6KWZ2.js +2206 -0
- package/dist/chunk-ZVB6KWZ2.js.map +1 -0
- package/dist/client/index.cjs +11285 -3319
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +4243 -881
- package/dist/client/index.d.ts +4243 -881
- package/dist/client/index.js +9103 -2389
- package/dist/client/index.js.map +1 -1
- package/dist/collections-DrJFEDHl.d.cts +116 -0
- package/dist/collections-pLtrj6fw.d.ts +116 -0
- package/dist/config-C6vlghJY.d.cts +2617 -0
- package/dist/config-C6vlghJY.d.ts +2617 -0
- package/dist/server/index.cjs +1588 -514
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +266 -162
- package/dist/server/index.d.ts +266 -162
- package/dist/server/index.js +235 -169
- package/dist/server/index.js.map +1 -1
- package/dist/shared/index.cjs +2203 -937
- package/dist/shared/index.cjs.map +1 -1
- package/dist/shared/index.d.cts +256 -132
- package/dist/shared/index.d.ts +256 -132
- package/dist/shared/index.js +102 -28
- package/package.json +12 -8
- 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,13 @@ __export(shared_exports, {
|
|
|
53
59
|
FormattedAmountUi: () => FormattedAmountUi,
|
|
54
60
|
FormattedPercentUi: () => FormattedPercentUi,
|
|
55
61
|
HexEncodedTransactionData: () => HexEncodedTransactionData,
|
|
62
|
+
HttpError: () => HttpError,
|
|
63
|
+
InvariantError: () => InvariantError,
|
|
56
64
|
Iso2CountryCode: () => Iso2CountryCode,
|
|
57
65
|
KnownAssetSymbol: () => KnownAssetSymbol,
|
|
58
66
|
KycToken: () => KycToken,
|
|
59
67
|
Link: () => Link,
|
|
68
|
+
MAX_ASSET_DECIMALS: () => MAX_ASSET_DECIMALS,
|
|
60
69
|
MAX_UINT_256: () => MAX_UINT_256,
|
|
61
70
|
Milestone: () => Milestone,
|
|
62
71
|
NA_AMOUNT_ASSET_UI: () => NA_AMOUNT_ASSET_UI,
|
|
@@ -64,6 +73,9 @@ __export(shared_exports, {
|
|
|
64
73
|
NotImplementedError: () => NotImplementedError,
|
|
65
74
|
OAuthRefreshToken: () => OAuthRefreshToken,
|
|
66
75
|
OAuthSession: () => OAuthSession,
|
|
76
|
+
ONDO_POLL_INTERVAL_MS: () => ONDO_POLL_INTERVAL_MS,
|
|
77
|
+
ONDO_QUOTE_EXPIRY_THRESHOLD_MS: () => ONDO_QUOTE_EXPIRY_THRESHOLD_MS,
|
|
78
|
+
ONDO_SUPPORTED_INPUT_ASSETS: () => ONDO_SUPPORTED_INPUT_ASSETS,
|
|
67
79
|
Offer: () => Offer,
|
|
68
80
|
OfferDetail: () => OfferDetail,
|
|
69
81
|
OfferId: () => OfferId,
|
|
@@ -73,6 +85,12 @@ __export(shared_exports, {
|
|
|
73
85
|
OfferOptionId: () => OfferOptionId,
|
|
74
86
|
OfferOptionSlug: () => OfferOptionSlug,
|
|
75
87
|
OfferSlug: () => OfferSlug,
|
|
88
|
+
OfferToken: () => OfferToken,
|
|
89
|
+
OffersNamespaceImpl: () => OffersNamespaceImpl,
|
|
90
|
+
OndoNamespaceImpl: () => OndoNamespaceImpl,
|
|
91
|
+
OndoQuote: () => OndoQuote,
|
|
92
|
+
OndoSwapTransaction: () => OndoSwapTransaction,
|
|
93
|
+
OndoTradingStatus: () => OndoTradingStatus,
|
|
76
94
|
PKCEState: () => PKCEState,
|
|
77
95
|
PaginatedResponse: () => PaginatedResponse,
|
|
78
96
|
PaginationParams: () => PaginationParams,
|
|
@@ -82,27 +100,37 @@ __export(shared_exports, {
|
|
|
82
100
|
Pii: () => Pii,
|
|
83
101
|
PiiAddress: () => PiiAddress,
|
|
84
102
|
PiiJurisdiction: () => PiiJurisdiction,
|
|
103
|
+
RedactedWalletError: () => RedactedWalletError,
|
|
85
104
|
RedirectUri: () => RedirectUri,
|
|
86
105
|
Requirement: () => Requirement,
|
|
87
106
|
RequirementId: () => RequirementId,
|
|
88
107
|
RequirementStatusInfo: () => RequirementStatusInfo,
|
|
108
|
+
RequirementsNamespaceImpl: () => RequirementsNamespaceImpl,
|
|
89
109
|
SLIPPAGE_OPTIONS_BPS: () => SLIPPAGE_OPTIONS_BPS,
|
|
110
|
+
SOLANA_CHAINS: () => SOLANA_CHAINS,
|
|
111
|
+
STABLE_DECIMALS: () => STABLE_DECIMALS,
|
|
112
|
+
SUPERSTATE_ISSUER_NAME: () => SUPERSTATE_ISSUER_NAME,
|
|
113
|
+
SUPERSTATE_SUPPORTED_INPUT_ASSETS: () => SUPERSTATE_SUPPORTED_INPUT_ASSETS,
|
|
90
114
|
SUPERSTATE_SWAP_ABI: () => SUPERSTATE_SWAP_ABI,
|
|
91
115
|
SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA: () => SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA,
|
|
92
|
-
SUPERSTATE_TOS_URL: () => SUPERSTATE_TOS_URL,
|
|
93
116
|
SWAP_POLL_INTERVAL_MS: () => SWAP_POLL_INTERVAL_MS,
|
|
94
117
|
ShortenedWalletAddress: () => ShortenedWalletAddress,
|
|
118
|
+
SolanaChain: () => SolanaChain,
|
|
95
119
|
StablecoinSymbol: () => StablecoinSymbol,
|
|
120
|
+
SuperstateSwapNamespaceImpl: () => SuperstateSwapNamespaceImpl,
|
|
96
121
|
SwapAuthorization: () => SwapAuthorization,
|
|
97
|
-
SwapNamespaceImpl: () => SwapNamespaceImpl,
|
|
98
122
|
SwapPreview: () => SwapPreview,
|
|
99
123
|
SwapQuote: () => SwapQuote,
|
|
100
124
|
SwapStatus: () => SwapStatus,
|
|
101
125
|
TOKEN_REGISTRY: () => TOKEN_REGISTRY,
|
|
102
126
|
TermItem: () => TermItem,
|
|
127
|
+
Ticker: () => Ticker,
|
|
103
128
|
TokenAllowance: () => TokenAllowance,
|
|
104
129
|
TokenBalance: () => TokenBalance,
|
|
105
|
-
|
|
130
|
+
TokenLogo: () => TokenLogo,
|
|
131
|
+
TokenLogoUrl: () => TokenLogoUrl,
|
|
132
|
+
TokenMetadata: () => TokenMetadata,
|
|
133
|
+
TokensNamespaceImpl: () => TokensNamespaceImpl,
|
|
106
134
|
TxExplorerUrl: () => TxExplorerUrl,
|
|
107
135
|
USDC: () => USDC,
|
|
108
136
|
USDC_SYMBOL: () => USDC_SYMBOL,
|
|
@@ -111,11 +139,17 @@ __export(shared_exports, {
|
|
|
111
139
|
User: () => User,
|
|
112
140
|
UserEmail: () => UserEmail,
|
|
113
141
|
UserId: () => UserId,
|
|
142
|
+
ValidationError: () => ValidationError,
|
|
114
143
|
WalletAddress: () => WalletAddress,
|
|
115
144
|
WalletOwnershipChallenge: () => WalletOwnershipChallenge,
|
|
145
|
+
WalletsNamespaceImpl: () => WalletsNamespaceImpl,
|
|
146
|
+
apiErrorCode: () => apiErrorCode,
|
|
116
147
|
applyBps: () => applyBps,
|
|
117
148
|
assertUint256: () => assertUint256,
|
|
118
149
|
assetAmount: () => assetAmount,
|
|
150
|
+
blockchainAmountFromRawOrThrow: () => blockchainAmountFromRawOrThrow,
|
|
151
|
+
chainFromId: () => chainFromId,
|
|
152
|
+
computeOndoPrice: () => computeOndoPrice,
|
|
119
153
|
computePrice: () => computePrice,
|
|
120
154
|
computeSlip: () => computeSlip,
|
|
121
155
|
decodeSwappedOutputAmount: () => decodeSwappedOutputAmount,
|
|
@@ -130,15 +164,182 @@ __export(shared_exports, {
|
|
|
130
164
|
getChainId: () => getChainId,
|
|
131
165
|
getNetworkName: () => getNetworkName,
|
|
132
166
|
isStopped: () => isStopped,
|
|
167
|
+
ondoSwapContractAddress: () => ondoSwapContractAddress,
|
|
133
168
|
parseBlockchainAmount: () => parseBlockchainAmount,
|
|
169
|
+
parseUint256: () => parseUint256,
|
|
134
170
|
shortenAddress: () => shortenAddress,
|
|
171
|
+
superstateSwapContractAddress: () => superstateSwapContractAddress,
|
|
135
172
|
txExplorerUrl: () => txExplorerUrl,
|
|
136
173
|
usdAmount: () => usdAmount
|
|
137
174
|
});
|
|
138
175
|
module.exports = __toCommonJS(shared_exports);
|
|
139
176
|
|
|
177
|
+
// src/shared/api/http-attributes.ts
|
|
178
|
+
var empty = {};
|
|
179
|
+
var concat = (left, right) => ({
|
|
180
|
+
...left,
|
|
181
|
+
...right
|
|
182
|
+
});
|
|
183
|
+
var concatAll = (...items) => {
|
|
184
|
+
let result = empty;
|
|
185
|
+
for (const item of items) {
|
|
186
|
+
result = concat(result, item);
|
|
187
|
+
}
|
|
188
|
+
return result;
|
|
189
|
+
};
|
|
190
|
+
var protectedRequest = () => ({ protected: true });
|
|
191
|
+
var userAgent = () => ({ userAgent: true });
|
|
192
|
+
var idempotencyKey = () => ({
|
|
193
|
+
idempotencyKey: true
|
|
194
|
+
});
|
|
195
|
+
var clientCredentials = (credentials) => ({
|
|
196
|
+
clientCredentials: credentials
|
|
197
|
+
});
|
|
198
|
+
var retryAttempt = (attempt) => ({
|
|
199
|
+
retryAttempt: attempt
|
|
200
|
+
});
|
|
201
|
+
var renewAttempted = (value) => ({
|
|
202
|
+
renewAttempted: value
|
|
203
|
+
});
|
|
204
|
+
var requestId = (id) => ({ requestId: id });
|
|
205
|
+
var getRequestId = (attrs) => attrs?.requestId ?? null;
|
|
206
|
+
var isProtected = (attrs) => attrs?.protected === true;
|
|
207
|
+
var needUserAgent = (attrs) => attrs?.userAgent === true;
|
|
208
|
+
var isIdempotent = (attrs) => attrs?.idempotencyKey === true;
|
|
209
|
+
var getRetryAttempt = (attrs) => attrs?.retryAttempt ?? 0;
|
|
210
|
+
var wasRenewAttempted = (attrs) => attrs?.renewAttempted === true;
|
|
211
|
+
var getClientCredentials = (attrs) => attrs?.clientCredentials;
|
|
212
|
+
var Attributes = {
|
|
213
|
+
empty,
|
|
214
|
+
concat,
|
|
215
|
+
concatAll,
|
|
216
|
+
protected: protectedRequest,
|
|
217
|
+
isProtected,
|
|
218
|
+
userAgent,
|
|
219
|
+
needUserAgent,
|
|
220
|
+
idempotencyKey,
|
|
221
|
+
isIdempotent,
|
|
222
|
+
retryAttempt,
|
|
223
|
+
getRetryAttempt,
|
|
224
|
+
renewAttempted,
|
|
225
|
+
wasRenewAttempted,
|
|
226
|
+
clientCredentials,
|
|
227
|
+
getClientCredentials,
|
|
228
|
+
requestId,
|
|
229
|
+
getRequestId
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
// src/shared/api/http.ts
|
|
233
|
+
var HttpError = class extends Error {
|
|
234
|
+
constructor(response) {
|
|
235
|
+
super(`Request failed with ${response.status} status`);
|
|
236
|
+
this.name = "HttpError";
|
|
237
|
+
this.response = response;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Correlates this failure with the `[HTTP]` log lines for the same request,
|
|
241
|
+
* which carry the method, the URL, the duration and every retry. `null` when
|
|
242
|
+
* the response did not come from an {@link HttpClient}.
|
|
243
|
+
*
|
|
244
|
+
* Worth quoting in a bug report: it is what makes a log excerpt readable.
|
|
245
|
+
*/
|
|
246
|
+
get requestId() {
|
|
247
|
+
return this.response.requestId ?? null;
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
function apiErrorCode(error) {
|
|
251
|
+
if (!(error instanceof HttpError)) return null;
|
|
252
|
+
const body = error.response.body;
|
|
253
|
+
if (typeof body !== "object" || body === null) return null;
|
|
254
|
+
const code = body.code;
|
|
255
|
+
return typeof code === "string" ? code : null;
|
|
256
|
+
}
|
|
257
|
+
async function makeRequest(request) {
|
|
258
|
+
const headers = {
|
|
259
|
+
Accept: "application/json",
|
|
260
|
+
...request.method === "POST" && request.body !== void 0 ? { "Content-Type": "application/json" } : {},
|
|
261
|
+
...request.headers ?? {}
|
|
262
|
+
};
|
|
263
|
+
const init = {
|
|
264
|
+
method: request.method,
|
|
265
|
+
headers,
|
|
266
|
+
...request.redirect !== void 0 ? { redirect: request.redirect } : {}
|
|
267
|
+
};
|
|
268
|
+
if (request.method === "POST" && request.body !== void 0) {
|
|
269
|
+
init.body = JSON.stringify(request.body);
|
|
270
|
+
}
|
|
271
|
+
const response = await fetch(
|
|
272
|
+
buildUrlWithQueryParams(request.url, request.queryParams),
|
|
273
|
+
init
|
|
274
|
+
);
|
|
275
|
+
const responseHeaders = headersToRecord(response.headers);
|
|
276
|
+
if (response.status === 204 || response.status === 205) {
|
|
277
|
+
return {
|
|
278
|
+
status: response.status,
|
|
279
|
+
body: null,
|
|
280
|
+
headers: responseHeaders
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
if (response.status >= 300 && response.status < 400) {
|
|
284
|
+
await response.text();
|
|
285
|
+
return {
|
|
286
|
+
status: response.status,
|
|
287
|
+
body: null,
|
|
288
|
+
headers: responseHeaders
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
const text = await response.text();
|
|
292
|
+
let body;
|
|
293
|
+
try {
|
|
294
|
+
body = text ? JSON.parse(text) : null;
|
|
295
|
+
} catch (_) {
|
|
296
|
+
throw new HttpError({
|
|
297
|
+
status: response.status,
|
|
298
|
+
headers: responseHeaders,
|
|
299
|
+
body: text
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
return {
|
|
303
|
+
status: response.status,
|
|
304
|
+
body,
|
|
305
|
+
headers: responseHeaders
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
function buildUrlWithQueryParams(url, queryParams) {
|
|
309
|
+
if (!queryParams) {
|
|
310
|
+
return url;
|
|
311
|
+
}
|
|
312
|
+
const searchParams = new URLSearchParams();
|
|
313
|
+
for (const [key, value] of Object.entries(queryParams)) {
|
|
314
|
+
if (value === void 0 || value === null) {
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
if (Array.isArray(value)) {
|
|
318
|
+
for (const item of value) {
|
|
319
|
+
if (item === void 0 || item === null) {
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
searchParams.append(key, String(item));
|
|
323
|
+
}
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
searchParams.append(key, String(value));
|
|
327
|
+
}
|
|
328
|
+
const queryString = searchParams.toString();
|
|
329
|
+
if (!queryString) {
|
|
330
|
+
return url;
|
|
331
|
+
}
|
|
332
|
+
return url.includes("?") ? `${url}&${queryString}` : `${url}?${queryString}`;
|
|
333
|
+
}
|
|
334
|
+
function headersToRecord(headers) {
|
|
335
|
+
const record = {};
|
|
336
|
+
headers.forEach((value, key) => {
|
|
337
|
+
record[key.toLowerCase()] = value;
|
|
338
|
+
});
|
|
339
|
+
return record;
|
|
340
|
+
}
|
|
341
|
+
|
|
140
342
|
// src/shared/api/pagination.ts
|
|
141
|
-
var Cursor = (value) => value;
|
|
142
343
|
async function fetchAllPages(fetchPage, baseParams) {
|
|
143
344
|
const items = [];
|
|
144
345
|
let cursor = null;
|
|
@@ -153,82 +354,284 @@ async function fetchAllPages(fetchPage, baseParams) {
|
|
|
153
354
|
} while (cursor);
|
|
154
355
|
return items;
|
|
155
356
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
357
|
+
|
|
358
|
+
// src/shared/core/utils/crypto.ts
|
|
359
|
+
async function sha256(data) {
|
|
360
|
+
const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
|
|
361
|
+
const buffer = bytes.buffer.slice(
|
|
362
|
+
bytes.byteOffset,
|
|
363
|
+
bytes.byteOffset + bytes.byteLength
|
|
364
|
+
);
|
|
365
|
+
return crypto.subtle.digest("SHA-256", buffer);
|
|
366
|
+
}
|
|
367
|
+
function arrayBufferToBase64Url(buffer, padding = true) {
|
|
368
|
+
const bytes = new Uint8Array(buffer);
|
|
369
|
+
let binary = "";
|
|
370
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
371
|
+
binary += String.fromCharCode(bytes[i]);
|
|
372
|
+
}
|
|
373
|
+
let base64 = btoa(binary);
|
|
374
|
+
base64 = base64.replace(/\+/g, "-").replace(/\//g, "_");
|
|
375
|
+
if (!padding) {
|
|
376
|
+
base64 = base64.replace(/=+$/, "");
|
|
377
|
+
}
|
|
378
|
+
return base64;
|
|
379
|
+
}
|
|
380
|
+
function generateSecureRandomBase64Url(byteLength) {
|
|
381
|
+
const bytes = new Uint8Array(byteLength);
|
|
382
|
+
crypto.getRandomValues(bytes);
|
|
383
|
+
const buffer = bytes.buffer;
|
|
384
|
+
return arrayBufferToBase64Url(buffer, false);
|
|
385
|
+
}
|
|
386
|
+
function notBlankStringOrNull(value) {
|
|
387
|
+
if (value?.trim()) {
|
|
388
|
+
return value;
|
|
389
|
+
} else {
|
|
390
|
+
return null;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// src/shared/types/oauth.ts
|
|
395
|
+
var AuthorizationCode = (value) => value;
|
|
396
|
+
var CodeVerifier = (value) => value;
|
|
397
|
+
var CodeChallenge = (value) => value;
|
|
398
|
+
var PKCEState = (value) => value;
|
|
399
|
+
var RedirectUri = (value) => value;
|
|
400
|
+
var ClientId = (value) => value;
|
|
401
|
+
var ClientSecret = (value) => value;
|
|
402
|
+
|
|
403
|
+
// src/shared/core/auth/pkce.ts
|
|
404
|
+
async function generatePKCEParams(config) {
|
|
405
|
+
const state = generateSecureRandomBase64Url(32);
|
|
406
|
+
const codeVerifier = generateSecureRandomBase64Url(32);
|
|
407
|
+
const codeChallengeRaw = await sha256(codeVerifier);
|
|
408
|
+
const codeChallenge = arrayBufferToBase64Url(codeChallengeRaw, false);
|
|
409
|
+
return {
|
|
410
|
+
clientId: config.clientId,
|
|
411
|
+
responseType: "code",
|
|
412
|
+
redirectUri: config.redirectUri,
|
|
413
|
+
codeChallenge: CodeChallenge(codeChallenge),
|
|
414
|
+
codeChallengeMethod: "S256",
|
|
415
|
+
state: PKCEState(state),
|
|
416
|
+
codeVerifier: CodeVerifier(codeVerifier)
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// src/shared/types/errors.ts
|
|
421
|
+
var NotImplementedError = class extends Error {
|
|
422
|
+
constructor(message = "Not implemented yet") {
|
|
423
|
+
super(message);
|
|
424
|
+
this.name = "NotImplementedError";
|
|
425
|
+
}
|
|
162
426
|
};
|
|
163
|
-
var
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
427
|
+
var NotAuthenticatedError = class extends Error {
|
|
428
|
+
constructor(message = "The user is not authenticated. Go through the OAuth flow first!") {
|
|
429
|
+
super(message);
|
|
430
|
+
this.name = "NotAuthenticatedError";
|
|
431
|
+
}
|
|
432
|
+
};
|
|
433
|
+
var ValidationError = class extends Error {
|
|
434
|
+
constructor(message) {
|
|
435
|
+
super(message);
|
|
436
|
+
this.name = "ValidationError";
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
var InvariantError = class extends Error {
|
|
440
|
+
constructor(message) {
|
|
441
|
+
super(message);
|
|
442
|
+
this.name = "InvariantError";
|
|
176
443
|
}
|
|
177
444
|
};
|
|
178
445
|
|
|
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
|
-
|
|
446
|
+
// src/shared/types/blockchain/core.ts
|
|
447
|
+
var ETHEREUM_CHAINS = {
|
|
448
|
+
ethereum_mainnet: true,
|
|
449
|
+
ethereum_sepolia: true
|
|
450
|
+
};
|
|
451
|
+
var EthereumChain = (value) => {
|
|
452
|
+
if (!Object.keys(ETHEREUM_CHAINS).includes(value)) {
|
|
453
|
+
throw new ValidationError(`Unsupported Ethereum chain: "${value}"`);
|
|
454
|
+
}
|
|
455
|
+
return value;
|
|
456
|
+
};
|
|
457
|
+
var SOLANA_CHAINS = {
|
|
458
|
+
solana_mainnet: true,
|
|
459
|
+
solana_devnet: true
|
|
460
|
+
};
|
|
461
|
+
var SolanaChain = (value) => {
|
|
462
|
+
if (!Object.keys(SOLANA_CHAINS).includes(value)) {
|
|
463
|
+
throw new ValidationError(`Unsupported Solana chain: "${value}"`);
|
|
464
|
+
}
|
|
465
|
+
return value;
|
|
466
|
+
};
|
|
467
|
+
var Chain = (value) => {
|
|
468
|
+
if (!Object.keys(ETHEREUM_CHAINS).includes(value) && !Object.keys(SOLANA_CHAINS).includes(value)) {
|
|
469
|
+
throw new ValidationError(`Unsupported chain: "${value}"`);
|
|
470
|
+
}
|
|
471
|
+
return value;
|
|
472
|
+
};
|
|
473
|
+
var EvmWalletAddress = (value) => value;
|
|
474
|
+
var EvmContractAddress = (value) => value;
|
|
475
|
+
var HexEncodedTransactionData = (value) => value;
|
|
476
|
+
var MAX_ASSET_DECIMALS = 77;
|
|
477
|
+
var AssetDecimals = (value) => {
|
|
478
|
+
if (!Number.isInteger(value)) {
|
|
479
|
+
throw new ValidationError(`Asset decimals must be an integer: ${value}`);
|
|
480
|
+
}
|
|
481
|
+
if (value < 0 || value > MAX_ASSET_DECIMALS) {
|
|
482
|
+
throw new ValidationError(
|
|
483
|
+
`Asset decimals out of range [0, ${MAX_ASSET_DECIMALS}]: ${value}`
|
|
484
|
+
);
|
|
485
|
+
}
|
|
486
|
+
return value;
|
|
487
|
+
};
|
|
488
|
+
var STABLE_DECIMALS = AssetDecimals(6);
|
|
489
|
+
var DecimalString = (value) => value;
|
|
490
|
+
var MAX_UINT_256 = 2n ** 256n - 1n;
|
|
491
|
+
var assertUint256 = (value) => {
|
|
492
|
+
if (isUint256(value)) return value;
|
|
493
|
+
throw new InvariantError(`Value out of uint256 bounds: ${value}`);
|
|
494
|
+
};
|
|
495
|
+
var parseUint256 = (value, label) => {
|
|
496
|
+
if (isUint256(value)) return value;
|
|
497
|
+
throw new ValidationError(`${label}: out of uint256 bounds (${value})`);
|
|
498
|
+
};
|
|
499
|
+
var isUint256 = (value) => value >= 0n && value <= MAX_UINT_256;
|
|
500
|
+
var BlockchainAmount = Object.assign(
|
|
501
|
+
(value) => value,
|
|
229
502
|
{
|
|
230
|
-
|
|
231
|
-
|
|
503
|
+
add: (a, b) => combineAmounts(a, b, (x, y) => x + y),
|
|
504
|
+
sub: (a, b) => combineAmounts(a, b, (x, y) => x - y)
|
|
505
|
+
}
|
|
506
|
+
);
|
|
507
|
+
function combineAmounts(a, b, op) {
|
|
508
|
+
if (a.decimals !== b.decimals) {
|
|
509
|
+
throw new InvariantError(
|
|
510
|
+
`Cannot combine BlockchainAmounts with different decimals: ${a.decimals} vs ${b.decimals}`
|
|
511
|
+
);
|
|
512
|
+
}
|
|
513
|
+
const raw = op(a.raw, b.raw);
|
|
514
|
+
if (raw < 0n || raw > MAX_UINT_256) {
|
|
515
|
+
throw new InvariantError(`BlockchainAmount out of uint256 bounds: ${raw}`);
|
|
516
|
+
}
|
|
517
|
+
return BlockchainAmount({ raw, decimals: a.decimals });
|
|
518
|
+
}
|
|
519
|
+
var AssetSymbol = (value) => value;
|
|
520
|
+
var StablecoinSymbol = (value) => value;
|
|
521
|
+
var KnownAssetSymbol = StablecoinSymbol;
|
|
522
|
+
var Bps = (value) => value;
|
|
523
|
+
|
|
524
|
+
// src/shared/core/blockchain/bps.ts
|
|
525
|
+
var BPS_DENOM = Bps(10000n);
|
|
526
|
+
function applyBps(amount, bps) {
|
|
527
|
+
return assertUint256(amount * bps / BPS_DENOM);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// src/shared/types/blockchain/ui.ts
|
|
531
|
+
var FormattedAmountUi = (value) => value;
|
|
532
|
+
var FormattedPercentUi = (value) => value;
|
|
533
|
+
var TxExplorerUrl = (value) => value;
|
|
534
|
+
var ShortenedWalletAddress = (value) => value;
|
|
535
|
+
var FormattedAmountAssetUi = (value) => value;
|
|
536
|
+
var AssetIconUrl = (value) => value;
|
|
537
|
+
|
|
538
|
+
// src/shared/core/blockchain/chain.ts
|
|
539
|
+
var CHAIN_IDS = {
|
|
540
|
+
ethereum_mainnet: 1,
|
|
541
|
+
ethereum_sepolia: 11155111
|
|
542
|
+
};
|
|
543
|
+
function getChainId(chain) {
|
|
544
|
+
return CHAIN_IDS[chain];
|
|
545
|
+
}
|
|
546
|
+
function chainFromId(chainId) {
|
|
547
|
+
const chains = Object.keys(CHAIN_IDS);
|
|
548
|
+
const chain = chains.find((c) => String(CHAIN_IDS[c]) === chainId);
|
|
549
|
+
if (!chain) {
|
|
550
|
+
throw new ValidationError(`Unsupported EIP-155 chain id: "${chainId}"`);
|
|
551
|
+
}
|
|
552
|
+
return chain;
|
|
553
|
+
}
|
|
554
|
+
function getNetworkName(chain) {
|
|
555
|
+
switch (chain) {
|
|
556
|
+
case "ethereum_mainnet":
|
|
557
|
+
return "Ethereum";
|
|
558
|
+
case "ethereum_sepolia":
|
|
559
|
+
return "Ethereum Sepolia";
|
|
560
|
+
default: {
|
|
561
|
+
const _exhaustive = chain;
|
|
562
|
+
return _exhaustive;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
function txExplorerUrl(chain, txHash) {
|
|
567
|
+
return TxExplorerUrl(`${explorerBaseUrl(chain)}/tx/${txHash}`);
|
|
568
|
+
}
|
|
569
|
+
function explorerBaseUrl(chain) {
|
|
570
|
+
switch (chain) {
|
|
571
|
+
case "ethereum_mainnet":
|
|
572
|
+
return "https://etherscan.io";
|
|
573
|
+
case "ethereum_sepolia":
|
|
574
|
+
return "https://sepolia.etherscan.io";
|
|
575
|
+
default: {
|
|
576
|
+
const _exhaustive = chain;
|
|
577
|
+
return _exhaustive;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// src/shared/core/blockchain/erc20/abi.ts
|
|
583
|
+
var ERC20_ABI = [
|
|
584
|
+
{
|
|
585
|
+
type: "function",
|
|
586
|
+
name: "allowance",
|
|
587
|
+
inputs: [
|
|
588
|
+
{ name: "owner", type: "address" },
|
|
589
|
+
{ name: "spender", type: "address" }
|
|
590
|
+
],
|
|
591
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
592
|
+
stateMutability: "view"
|
|
593
|
+
},
|
|
594
|
+
{
|
|
595
|
+
type: "function",
|
|
596
|
+
name: "approve",
|
|
597
|
+
inputs: [
|
|
598
|
+
{ name: "spender", type: "address" },
|
|
599
|
+
{ name: "amount", type: "uint256" }
|
|
600
|
+
],
|
|
601
|
+
outputs: [{ name: "", type: "bool" }],
|
|
602
|
+
stateMutability: "nonpayable"
|
|
603
|
+
},
|
|
604
|
+
{
|
|
605
|
+
type: "function",
|
|
606
|
+
name: "balanceOf",
|
|
607
|
+
inputs: [{ name: "account", type: "address" }],
|
|
608
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
609
|
+
stateMutability: "view"
|
|
610
|
+
},
|
|
611
|
+
{
|
|
612
|
+
type: "function",
|
|
613
|
+
name: "decimals",
|
|
614
|
+
inputs: [],
|
|
615
|
+
outputs: [{ name: "", type: "uint8" }],
|
|
616
|
+
stateMutability: "view"
|
|
617
|
+
},
|
|
618
|
+
{
|
|
619
|
+
type: "function",
|
|
620
|
+
name: "name",
|
|
621
|
+
inputs: [],
|
|
622
|
+
outputs: [{ name: "", type: "string" }],
|
|
623
|
+
stateMutability: "view"
|
|
624
|
+
},
|
|
625
|
+
{
|
|
626
|
+
type: "function",
|
|
627
|
+
name: "symbol",
|
|
628
|
+
inputs: [],
|
|
629
|
+
outputs: [{ name: "", type: "string" }],
|
|
630
|
+
stateMutability: "view"
|
|
631
|
+
},
|
|
632
|
+
{
|
|
633
|
+
type: "function",
|
|
634
|
+
name: "totalSupply",
|
|
232
635
|
inputs: [],
|
|
233
636
|
outputs: [{ name: "", type: "uint256" }],
|
|
234
637
|
stateMutability: "view"
|
|
@@ -274,9 +677,1041 @@ var ERC20_ABI = [
|
|
|
274
677
|
],
|
|
275
678
|
anonymous: false
|
|
276
679
|
}
|
|
277
|
-
];
|
|
680
|
+
];
|
|
681
|
+
|
|
682
|
+
// src/shared/types/providers/superstate/swap.ts
|
|
683
|
+
var SwapAuthorization = {
|
|
684
|
+
fromDto: (dto) => ({
|
|
685
|
+
authorized: dto.authorized
|
|
686
|
+
})
|
|
687
|
+
};
|
|
688
|
+
var SwapPreview = {
|
|
689
|
+
fromDto: (dto) => ({
|
|
690
|
+
inputAmount: parseUint256(
|
|
691
|
+
BigInt(dto.pay_input_amount),
|
|
692
|
+
"SwapPreview.pay_input_amount"
|
|
693
|
+
),
|
|
694
|
+
fee: parseUint256(BigInt(dto.fee), "SwapPreview.fee"),
|
|
695
|
+
outputAmount: parseUint256(
|
|
696
|
+
BigInt(dto.receive_output_amount),
|
|
697
|
+
"SwapPreview.receive_output_amount"
|
|
698
|
+
)
|
|
699
|
+
})
|
|
700
|
+
};
|
|
701
|
+
var SwapStatus = {
|
|
702
|
+
fromDto: (dto) => ({
|
|
703
|
+
stopped: parseUint256(BigInt(dto.stopped), "SwapStatus.stopped"),
|
|
704
|
+
swapLevel: parseUint256(BigInt(dto.swap_level), "SwapStatus.swap_level")
|
|
705
|
+
})
|
|
706
|
+
};
|
|
707
|
+
var TokenAllowance = {
|
|
708
|
+
fromDto: (dto) => ({
|
|
709
|
+
allowance: parseUint256(BigInt(dto.allowance), "TokenAllowance.allowance")
|
|
710
|
+
})
|
|
711
|
+
};
|
|
712
|
+
var TokenBalance = {
|
|
713
|
+
fromDto: (dto) => ({
|
|
714
|
+
balance: parseUint256(BigInt(dto.balance), "TokenBalance.balance")
|
|
715
|
+
})
|
|
716
|
+
};
|
|
717
|
+
var AllowWalletResponse = {
|
|
718
|
+
fromDto: (dto) => {
|
|
719
|
+
switch (dto.action) {
|
|
720
|
+
case "broadcast_transaction":
|
|
721
|
+
return {
|
|
722
|
+
action: "broadcast_transaction",
|
|
723
|
+
to: EvmContractAddress(dto.to),
|
|
724
|
+
data: HexEncodedTransactionData(dto.data)
|
|
725
|
+
};
|
|
726
|
+
case "none":
|
|
727
|
+
return {
|
|
728
|
+
action: "none",
|
|
729
|
+
alreadyAllowed: dto.already_allowed
|
|
730
|
+
};
|
|
731
|
+
default: {
|
|
732
|
+
const _exhaustive = dto;
|
|
733
|
+
return _exhaustive;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
};
|
|
738
|
+
|
|
739
|
+
// src/shared/api/frontline/providers/superstate/swap.ts
|
|
740
|
+
async function getSwapAuthorization(api, params) {
|
|
741
|
+
const dto = await api.send({
|
|
742
|
+
method: "GET",
|
|
743
|
+
url: "/v1/wallet/authorized",
|
|
744
|
+
queryParams: {
|
|
745
|
+
chain: params.chain,
|
|
746
|
+
contract_address: params.contractAddress,
|
|
747
|
+
wallet_address: params.walletAddress
|
|
748
|
+
},
|
|
749
|
+
attributes: Attributes.protected()
|
|
750
|
+
});
|
|
751
|
+
return SwapAuthorization.fromDto(dto);
|
|
752
|
+
}
|
|
753
|
+
async function getSwapOutputToken(api, params) {
|
|
754
|
+
const dto = await api.send({
|
|
755
|
+
method: "GET",
|
|
756
|
+
url: "/v1/swap/output-token",
|
|
757
|
+
queryParams: {
|
|
758
|
+
chain: params.chain,
|
|
759
|
+
contract_address: params.contractAddress
|
|
760
|
+
},
|
|
761
|
+
attributes: Attributes.protected()
|
|
762
|
+
});
|
|
763
|
+
return toErc20Asset(dto);
|
|
764
|
+
}
|
|
765
|
+
async function getSwapPreview(api, params) {
|
|
766
|
+
const dto = await api.send({
|
|
767
|
+
method: "GET",
|
|
768
|
+
url: "/v1/swap/preview",
|
|
769
|
+
queryParams: {
|
|
770
|
+
chain: params.chain,
|
|
771
|
+
contract_address: params.contractAddress,
|
|
772
|
+
input_token: params.inputToken,
|
|
773
|
+
amount: params.amount.toString()
|
|
774
|
+
},
|
|
775
|
+
attributes: Attributes.protected()
|
|
776
|
+
});
|
|
777
|
+
return SwapPreview.fromDto(dto);
|
|
778
|
+
}
|
|
779
|
+
async function getSwapStatus(api, params) {
|
|
780
|
+
const dto = await api.send({
|
|
781
|
+
method: "GET",
|
|
782
|
+
url: "/v1/swap/status",
|
|
783
|
+
queryParams: {
|
|
784
|
+
chain: params.chain,
|
|
785
|
+
contract_address: params.contractAddress
|
|
786
|
+
},
|
|
787
|
+
attributes: Attributes.protected()
|
|
788
|
+
});
|
|
789
|
+
return SwapStatus.fromDto(dto);
|
|
790
|
+
}
|
|
791
|
+
async function getTokenAllowance(api, params) {
|
|
792
|
+
const dto = await api.send({
|
|
793
|
+
method: "GET",
|
|
794
|
+
url: "/v1/token/allowance",
|
|
795
|
+
queryParams: {
|
|
796
|
+
chain: params.chain,
|
|
797
|
+
token_address: params.tokenAddress,
|
|
798
|
+
owner: params.owner,
|
|
799
|
+
spender: params.spender
|
|
800
|
+
},
|
|
801
|
+
attributes: Attributes.protected()
|
|
802
|
+
});
|
|
803
|
+
return TokenAllowance.fromDto(dto);
|
|
804
|
+
}
|
|
805
|
+
async function getTokenBalance(api, params) {
|
|
806
|
+
const dto = await api.send({
|
|
807
|
+
method: "GET",
|
|
808
|
+
url: "/v1/token/balance",
|
|
809
|
+
queryParams: {
|
|
810
|
+
chain: params.chain,
|
|
811
|
+
token_address: params.tokenAddress,
|
|
812
|
+
owner: params.owner
|
|
813
|
+
},
|
|
814
|
+
attributes: Attributes.protected()
|
|
815
|
+
});
|
|
816
|
+
return TokenBalance.fromDto(dto);
|
|
817
|
+
}
|
|
818
|
+
async function allowWallet(api, params) {
|
|
819
|
+
const dto = await api.send({
|
|
820
|
+
method: "POST",
|
|
821
|
+
url: `/v1/offers/${encodeURIComponent(params.offerId)}/allow-wallet`,
|
|
822
|
+
body: {
|
|
823
|
+
wallet_address: params.walletAddress,
|
|
824
|
+
chain: params.chain,
|
|
825
|
+
signature: params.signature
|
|
826
|
+
},
|
|
827
|
+
attributes: Attributes.protected()
|
|
828
|
+
});
|
|
829
|
+
return AllowWalletResponse.fromDto(dto);
|
|
830
|
+
}
|
|
831
|
+
function toErc20Asset(dto) {
|
|
832
|
+
return {
|
|
833
|
+
name: dto.name,
|
|
834
|
+
symbol: AssetSymbol(dto.symbol),
|
|
835
|
+
decimals: AssetDecimals(dto.decimals)
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
// src/shared/core/observability/log-cause.ts
|
|
840
|
+
function classifyLogCause(error) {
|
|
841
|
+
if (error instanceof HttpError) {
|
|
842
|
+
return httpCause(error);
|
|
843
|
+
}
|
|
844
|
+
if (error instanceof ValidationError) {
|
|
845
|
+
return { type: "validation", message: error.message };
|
|
846
|
+
}
|
|
847
|
+
if (error instanceof InvariantError) {
|
|
848
|
+
return { type: "invariant", message: error.message };
|
|
849
|
+
}
|
|
850
|
+
if (error instanceof NotAuthenticatedError) {
|
|
851
|
+
return { type: "not-authenticated" };
|
|
852
|
+
}
|
|
853
|
+
if (error instanceof NotImplementedError) {
|
|
854
|
+
return { type: "not-implemented" };
|
|
855
|
+
}
|
|
856
|
+
return { type: "generic-error", name: errorName(error) };
|
|
857
|
+
}
|
|
858
|
+
function describeErrorUnredacted(error) {
|
|
859
|
+
if (error instanceof HttpError) {
|
|
860
|
+
return describeHttpErrorRedacted(error);
|
|
861
|
+
}
|
|
862
|
+
if (error instanceof Error) {
|
|
863
|
+
return `${error.name}: ${error.message}`;
|
|
864
|
+
}
|
|
865
|
+
return `thrown non-error: ${stringifyUnredacted(error)}`;
|
|
866
|
+
}
|
|
867
|
+
function stringifyUnredacted(value) {
|
|
868
|
+
if (value === void 0) return "";
|
|
869
|
+
try {
|
|
870
|
+
return JSON.stringify(
|
|
871
|
+
value,
|
|
872
|
+
(_key, item) => typeof item === "bigint" ? `${item}` : item
|
|
873
|
+
) ?? String(value);
|
|
874
|
+
} catch (_) {
|
|
875
|
+
return "<unserializable>";
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
function describeHttpErrorRedacted(error) {
|
|
879
|
+
const code = apiErrorCode(error);
|
|
880
|
+
const status = error.response.status;
|
|
881
|
+
return code === null ? `HttpError ${status}` : `HttpError ${status} (${code})`;
|
|
882
|
+
}
|
|
883
|
+
function errorName(error) {
|
|
884
|
+
return error instanceof Error ? error.name : `non-error ${typeof error}`;
|
|
885
|
+
}
|
|
886
|
+
function httpCause(error) {
|
|
887
|
+
return {
|
|
888
|
+
type: "http",
|
|
889
|
+
requestId: error.requestId,
|
|
890
|
+
status: error.response.status,
|
|
891
|
+
code: apiErrorCode(error),
|
|
892
|
+
eventId: apiErrorEventId(error)
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
function apiErrorEventId(error) {
|
|
896
|
+
const body = error.response.body;
|
|
897
|
+
if (typeof body !== "object" || body === null) return null;
|
|
898
|
+
const eventId = body.event_id;
|
|
899
|
+
return typeof eventId === "string" ? eventId : null;
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
// src/shared/core/observability/internal-logger.ts
|
|
903
|
+
function internalLogger(logger, scope) {
|
|
904
|
+
return logger ? scopedLogger(logger, scope, {}) : noopInternalLogger;
|
|
905
|
+
}
|
|
906
|
+
var LEVEL_RANK = {
|
|
907
|
+
none: 0,
|
|
908
|
+
error: 1,
|
|
909
|
+
warn: 2,
|
|
910
|
+
info: 3,
|
|
911
|
+
debug: 4
|
|
912
|
+
};
|
|
913
|
+
function scopedLogger(logger, scope, bindings) {
|
|
914
|
+
const admits = (level) => LEVEL_RANK[logger.level()] >= LEVEL_RANK[level];
|
|
915
|
+
const safe = (event) => ({
|
|
916
|
+
msg: event.msg,
|
|
917
|
+
scope,
|
|
918
|
+
bindings,
|
|
919
|
+
fields: event.fields ?? {},
|
|
920
|
+
...event.cause === void 0 ? {} : { cause: event.cause }
|
|
921
|
+
});
|
|
922
|
+
const unredacted = (event) => ({
|
|
923
|
+
msg: event.msg,
|
|
924
|
+
scope,
|
|
925
|
+
bindings,
|
|
926
|
+
fields: event.fields ?? {}
|
|
927
|
+
});
|
|
928
|
+
const self = {
|
|
929
|
+
child: (binding) => scopedLogger(logger, scope, { ...bindings, ...binding }),
|
|
930
|
+
debug: (event) => {
|
|
931
|
+
if (admits("debug")) logger.debug(() => unredacted(event()));
|
|
932
|
+
},
|
|
933
|
+
info: (event) => {
|
|
934
|
+
if (admits("info")) logger.info(() => safe(event()));
|
|
935
|
+
},
|
|
936
|
+
warn: (event) => {
|
|
937
|
+
if (admits("warn")) logger.warn(() => safe(event()));
|
|
938
|
+
},
|
|
939
|
+
error: (event) => {
|
|
940
|
+
if (admits("error")) logger.error(() => safe(event()));
|
|
941
|
+
},
|
|
942
|
+
failure: (event, error) => {
|
|
943
|
+
if (admits("debug"))
|
|
944
|
+
logger.debug(() => unredacted(verbatim(event(), error)));
|
|
945
|
+
if (admits("error")) logger.error(() => safe(classified(event(), error)));
|
|
946
|
+
},
|
|
947
|
+
warning: (event, error) => {
|
|
948
|
+
if (admits("debug"))
|
|
949
|
+
logger.debug(() => unredacted(verbatim(event(), error)));
|
|
950
|
+
if (admits("warn")) logger.warn(() => safe(classified(event(), error)));
|
|
951
|
+
},
|
|
952
|
+
wrap: async (op, params, run) => {
|
|
953
|
+
const opLog = self.child({ op });
|
|
954
|
+
opLog.debug(() => ({ msg: "call", fields: { params } }));
|
|
955
|
+
try {
|
|
956
|
+
return await run();
|
|
957
|
+
} catch (error) {
|
|
958
|
+
opLog.failure(() => ({ msg: "call failed" }), error);
|
|
959
|
+
throw error;
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
};
|
|
963
|
+
return self;
|
|
964
|
+
}
|
|
965
|
+
function verbatim(event, error) {
|
|
966
|
+
return {
|
|
967
|
+
msg: event.msg,
|
|
968
|
+
fields: { ...event.fields, error: describeErrorUnredacted(error) }
|
|
969
|
+
};
|
|
970
|
+
}
|
|
971
|
+
function classified(event, error) {
|
|
972
|
+
return { ...event, cause: event.cause ?? classifyLogCause(error) };
|
|
973
|
+
}
|
|
974
|
+
var noopInternalLogger = {
|
|
975
|
+
child: () => noopInternalLogger,
|
|
976
|
+
debug: () => void 0,
|
|
977
|
+
info: () => void 0,
|
|
978
|
+
warn: () => void 0,
|
|
979
|
+
error: () => void 0,
|
|
980
|
+
failure: () => void 0,
|
|
981
|
+
warning: () => void 0,
|
|
982
|
+
wrap: (_op, _params, run) => run()
|
|
983
|
+
};
|
|
984
|
+
|
|
985
|
+
// src/shared/core/blockchain/erc20/erc20-namespace.ts
|
|
986
|
+
var Erc20NamespaceImpl = class {
|
|
987
|
+
constructor(ctx) {
|
|
988
|
+
this.ctx = ctx;
|
|
989
|
+
this.log = internalLogger(ctx.logger, "ERC20");
|
|
990
|
+
}
|
|
991
|
+
async getAllowance(params) {
|
|
992
|
+
return this.log.wrap("getAllowance", params, async () => {
|
|
993
|
+
await this.ctx.ensureUserAuthenticated();
|
|
994
|
+
return getTokenAllowance(this.ctx.api, params);
|
|
995
|
+
});
|
|
996
|
+
}
|
|
997
|
+
async getBalance(params) {
|
|
998
|
+
return this.log.wrap("getBalance", params, async () => {
|
|
999
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1000
|
+
return getTokenBalance(this.ctx.api, params);
|
|
1001
|
+
});
|
|
1002
|
+
}
|
|
1003
|
+
};
|
|
1004
|
+
|
|
1005
|
+
// src/shared/core/blockchain/formatters.ts
|
|
1006
|
+
var import_viem = require("viem");
|
|
1007
|
+
function shortenAddress(address) {
|
|
1008
|
+
const short = address.length > 10 ? `${address.slice(0, 6)}\u2026${address.slice(-4)}` : address;
|
|
1009
|
+
return ShortenedWalletAddress(short);
|
|
1010
|
+
}
|
|
1011
|
+
function formatAmount(amount, locale, options) {
|
|
1012
|
+
const decimal = formatRawAmount(amount);
|
|
1013
|
+
let [integerPart, fractionPart = ""] = decimal.split(".");
|
|
1014
|
+
const maxFractionDigits = options?.maxFractionDigits;
|
|
1015
|
+
const minFractionDigits = maxFractionDigits !== void 0 ? Math.min(maxFractionDigits, amount.decimals) : Math.min(2, amount.decimals);
|
|
1016
|
+
if (maxFractionDigits !== void 0 && fractionPart.length > maxFractionDigits) {
|
|
1017
|
+
({ integerPart, fractionPart } = roundFractionHalfUp(
|
|
1018
|
+
integerPart,
|
|
1019
|
+
fractionPart,
|
|
1020
|
+
maxFractionDigits
|
|
1021
|
+
));
|
|
1022
|
+
}
|
|
1023
|
+
const fraction = minFractionDigits === 0 ? "" : fractionPart.padEnd(minFractionDigits, "0");
|
|
1024
|
+
const integerFormatted = BigInt(integerPart).toLocaleString(locale);
|
|
1025
|
+
if (minFractionDigits === 0 && fraction === "") {
|
|
1026
|
+
return FormattedAmountUi(integerFormatted);
|
|
1027
|
+
}
|
|
1028
|
+
const decimalSeparator = new Intl.NumberFormat(locale).formatToParts(1.1).find((p) => p.type === "decimal")?.value ?? ".";
|
|
1029
|
+
return FormattedAmountUi(`${integerFormatted}${decimalSeparator}${fraction}`);
|
|
1030
|
+
}
|
|
1031
|
+
function roundFractionHalfUp(integerPart, fractionPart, maxFractionDigits) {
|
|
1032
|
+
if (fractionPart.length <= maxFractionDigits) {
|
|
1033
|
+
return { integerPart, fractionPart };
|
|
1034
|
+
}
|
|
1035
|
+
if (maxFractionDigits === 0) {
|
|
1036
|
+
const roundUp = fractionPart[0] >= "5";
|
|
1037
|
+
const integer = BigInt(integerPart) + (roundUp ? 1n : 0n);
|
|
1038
|
+
return { integerPart: integer.toString(), fractionPart: "" };
|
|
1039
|
+
}
|
|
1040
|
+
const trimmed = fractionPart.slice(0, maxFractionDigits);
|
|
1041
|
+
if (fractionPart[maxFractionDigits] < "5") {
|
|
1042
|
+
return { integerPart, fractionPart: trimmed };
|
|
1043
|
+
}
|
|
1044
|
+
const digits = trimmed.split("").map((digit) => Number.parseInt(digit, 10));
|
|
1045
|
+
let carry = 1;
|
|
1046
|
+
for (let i = digits.length - 1; i >= 0 && carry > 0; i -= 1) {
|
|
1047
|
+
const sum = digits[i] + carry;
|
|
1048
|
+
if (sum === 10) {
|
|
1049
|
+
digits[i] = 0;
|
|
1050
|
+
carry = 1;
|
|
1051
|
+
} else {
|
|
1052
|
+
digits[i] = sum;
|
|
1053
|
+
carry = 0;
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
return {
|
|
1057
|
+
integerPart: carry > 0 ? (BigInt(integerPart) + 1n).toString() : integerPart,
|
|
1058
|
+
fractionPart: digits.join("")
|
|
1059
|
+
};
|
|
1060
|
+
}
|
|
1061
|
+
function formatRawAmount(amount) {
|
|
1062
|
+
return (0, import_viem.formatUnits)(amount.raw, amount.decimals);
|
|
1063
|
+
}
|
|
1064
|
+
function formatCompactAmount(amount, locale) {
|
|
1065
|
+
const value = Number(formatRawAmount(amount));
|
|
1066
|
+
const formatted = new Intl.NumberFormat(locale, {
|
|
1067
|
+
notation: "compact",
|
|
1068
|
+
maximumFractionDigits: 2
|
|
1069
|
+
}).format(value);
|
|
1070
|
+
return FormattedAmountUi(formatted);
|
|
1071
|
+
}
|
|
1072
|
+
function formatBpsAsPercent(bps, locale) {
|
|
1073
|
+
const whole = bps / 100n;
|
|
1074
|
+
const fraction = bps % 100n;
|
|
1075
|
+
const wholeFormatted = whole.toLocaleString(locale);
|
|
1076
|
+
const decimalSeparator = new Intl.NumberFormat(locale).formatToParts(1.1).find((p) => p.type === "decimal")?.value ?? ".";
|
|
1077
|
+
if (fraction === 0n) {
|
|
1078
|
+
return FormattedPercentUi(`${wholeFormatted}%`);
|
|
1079
|
+
}
|
|
1080
|
+
const fractionFormatted = fraction.toString().padStart(2, "0").replace(/0+$/, "");
|
|
1081
|
+
return FormattedPercentUi(
|
|
1082
|
+
`${wholeFormatted}${decimalSeparator}${fractionFormatted}%`
|
|
1083
|
+
);
|
|
1084
|
+
}
|
|
1085
|
+
function usdAmount(amount) {
|
|
1086
|
+
return FormattedAmountAssetUi(`$${amount}`);
|
|
1087
|
+
}
|
|
1088
|
+
function assetAmount(amount, symbol) {
|
|
1089
|
+
return FormattedAmountAssetUi(`${amount} ${symbol}`);
|
|
1090
|
+
}
|
|
1091
|
+
var NA_AMOUNT_ASSET_UI = FormattedAmountAssetUi("-");
|
|
1092
|
+
var USD_FRACTION_DIGITS = AssetDecimals(2);
|
|
1093
|
+
function formattedUsdPrice(amount, locale) {
|
|
1094
|
+
if (!amount) return NA_AMOUNT_ASSET_UI;
|
|
1095
|
+
return usdAmount(
|
|
1096
|
+
formatAmount(amount, locale, { maxFractionDigits: USD_FRACTION_DIGITS })
|
|
1097
|
+
);
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
// src/shared/core/blockchain/math.ts
|
|
1101
|
+
var import_viem2 = require("viem");
|
|
1102
|
+
function blockchainAmountFromRawOrThrow({
|
|
1103
|
+
label,
|
|
1104
|
+
raw,
|
|
1105
|
+
decimals
|
|
1106
|
+
}) {
|
|
1107
|
+
const trimmed = raw.trim();
|
|
1108
|
+
if (trimmed === "") {
|
|
1109
|
+
throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
|
|
1110
|
+
}
|
|
1111
|
+
let value;
|
|
1112
|
+
try {
|
|
1113
|
+
value = BigInt(trimmed);
|
|
1114
|
+
} catch {
|
|
1115
|
+
throw new ValidationError(`${label}: not a uint256 integer ("${raw}")`);
|
|
1116
|
+
}
|
|
1117
|
+
try {
|
|
1118
|
+
return BlockchainAmount({ raw: assertUint256(value), decimals });
|
|
1119
|
+
} catch {
|
|
1120
|
+
throw new ValidationError(`${label}: out of uint256 bounds (${value})`);
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
function parseBlockchainAmount(amount, decimals) {
|
|
1124
|
+
const trimmed = amount.trim();
|
|
1125
|
+
if (trimmed === "") return { valid: false, reason: { type: "empty" } };
|
|
1126
|
+
if (trimmed.startsWith("-")) {
|
|
1127
|
+
return { valid: false, reason: { type: "negative" } };
|
|
1128
|
+
}
|
|
1129
|
+
if (/[eE]/.test(trimmed)) {
|
|
1130
|
+
return { valid: false, reason: { type: "invalid-format" } };
|
|
1131
|
+
}
|
|
1132
|
+
if (!/^\d+(\.\d+)?$/.test(trimmed)) {
|
|
1133
|
+
return { valid: false, reason: { type: "invalid-format" } };
|
|
1134
|
+
}
|
|
1135
|
+
const [, fraction = ""] = trimmed.split(".");
|
|
1136
|
+
if (fraction.length > decimals) {
|
|
1137
|
+
return {
|
|
1138
|
+
valid: false,
|
|
1139
|
+
reason: { type: "too-many-decimals", maxDecimals: decimals }
|
|
1140
|
+
};
|
|
1141
|
+
}
|
|
1142
|
+
try {
|
|
1143
|
+
const raw = (0, import_viem2.parseUnits)(trimmed, decimals);
|
|
1144
|
+
if (raw > MAX_UINT_256) {
|
|
1145
|
+
return { valid: false, reason: { type: "overflow" } };
|
|
1146
|
+
}
|
|
1147
|
+
return {
|
|
1148
|
+
valid: true,
|
|
1149
|
+
amount: BlockchainAmount({ raw, decimals })
|
|
1150
|
+
};
|
|
1151
|
+
} catch {
|
|
1152
|
+
return { valid: false, reason: { type: "invalid-format" } };
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
// src/shared/core/blockchain/token-registry.ts
|
|
1157
|
+
var USDC_SYMBOL = StablecoinSymbol("USDC");
|
|
1158
|
+
var USDC = {
|
|
1159
|
+
name: "USD Coin",
|
|
1160
|
+
symbol: USDC_SYMBOL,
|
|
1161
|
+
decimals: AssetDecimals(6)
|
|
1162
|
+
};
|
|
1163
|
+
var USDT_SYMBOL = StablecoinSymbol("USDT");
|
|
1164
|
+
var USDT = {
|
|
1165
|
+
name: "Tether USD",
|
|
1166
|
+
symbol: USDT_SYMBOL,
|
|
1167
|
+
decimals: AssetDecimals(6)
|
|
1168
|
+
};
|
|
1169
|
+
var USDC_ADDRESSES = {
|
|
1170
|
+
ethereum_mainnet: EvmContractAddress(
|
|
1171
|
+
"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
|
|
1172
|
+
),
|
|
1173
|
+
ethereum_sepolia: EvmContractAddress(
|
|
1174
|
+
"0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"
|
|
1175
|
+
)
|
|
1176
|
+
};
|
|
1177
|
+
var USDT_ADDRESSES = {
|
|
1178
|
+
ethereum_mainnet: EvmContractAddress(
|
|
1179
|
+
"0xdac17f958d2ee523a2206206994597c13d831ec7"
|
|
1180
|
+
),
|
|
1181
|
+
ethereum_sepolia: EvmContractAddress(
|
|
1182
|
+
"0x7169D38820dfd117C3FA1f22a697dBA58d90BA06"
|
|
1183
|
+
)
|
|
1184
|
+
};
|
|
1185
|
+
var TOKEN_REGISTRY = {
|
|
1186
|
+
erc20: (symbol) => {
|
|
1187
|
+
switch (symbol) {
|
|
1188
|
+
case "USDC":
|
|
1189
|
+
return USDC;
|
|
1190
|
+
case "USDT":
|
|
1191
|
+
return USDT;
|
|
1192
|
+
default:
|
|
1193
|
+
throw new InvariantError(`Unknown asset symbol: ${symbol}`);
|
|
1194
|
+
}
|
|
1195
|
+
},
|
|
1196
|
+
contractAddress: (symbol, chain) => {
|
|
1197
|
+
switch (symbol) {
|
|
1198
|
+
case "USDC":
|
|
1199
|
+
return USDC_ADDRESSES[chain];
|
|
1200
|
+
case "USDT":
|
|
1201
|
+
return USDT_ADDRESSES[chain];
|
|
1202
|
+
default:
|
|
1203
|
+
throw new InvariantError(`Unknown asset symbol: ${symbol}`);
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
};
|
|
1207
|
+
|
|
1208
|
+
// src/shared/types/pagination.ts
|
|
1209
|
+
var Cursor = (value) => value;
|
|
1210
|
+
var PaginatedResponse = {
|
|
1211
|
+
fromDto: (dto, itemMapper) => ({
|
|
1212
|
+
data: dto.data.map(itemMapper),
|
|
1213
|
+
startingAfter: dto.starting_after ? Cursor(dto.starting_after) : null,
|
|
1214
|
+
startingBefore: dto.starting_before ? Cursor(dto.starting_before) : null
|
|
1215
|
+
})
|
|
1216
|
+
};
|
|
1217
|
+
var PaginationParams = {
|
|
1218
|
+
toQueryParams: (params) => {
|
|
1219
|
+
const queryParams = {};
|
|
1220
|
+
if (params.after) {
|
|
1221
|
+
queryParams.starting_after = params.after;
|
|
1222
|
+
}
|
|
1223
|
+
if (params.before) {
|
|
1224
|
+
queryParams.starting_before = params.before;
|
|
1225
|
+
}
|
|
1226
|
+
if (params.limit) {
|
|
1227
|
+
queryParams.limit = params.limit;
|
|
1228
|
+
}
|
|
1229
|
+
return queryParams;
|
|
1230
|
+
}
|
|
1231
|
+
};
|
|
1232
|
+
|
|
1233
|
+
// src/shared/types/asset.ts
|
|
1234
|
+
var AssetId = (value) => value;
|
|
1235
|
+
var AssetCode = (value) => value;
|
|
1236
|
+
var Asset = {
|
|
1237
|
+
fromDto: (dto) => ({
|
|
1238
|
+
id: AssetId(dto.id),
|
|
1239
|
+
code: AssetCode(dto.code),
|
|
1240
|
+
name: dto.name,
|
|
1241
|
+
fractionalDigits: dto.fractional_digits
|
|
1242
|
+
})
|
|
1243
|
+
};
|
|
1244
|
+
|
|
1245
|
+
// src/shared/types/offer.ts
|
|
1246
|
+
var OfferId = (value) => value;
|
|
1247
|
+
var OfferSlug = (value) => value;
|
|
1248
|
+
var Offer = {
|
|
1249
|
+
fromDto: (dto) => {
|
|
1250
|
+
if (!Array.isArray(dto.tokens)) {
|
|
1251
|
+
throw new ValidationError(
|
|
1252
|
+
`Offer.tokens: expected an array, got ${typeof dto.tokens}`
|
|
1253
|
+
);
|
|
1254
|
+
}
|
|
1255
|
+
return {
|
|
1256
|
+
id: OfferId(dto.id),
|
|
1257
|
+
slug: OfferSlug(dto.slug),
|
|
1258
|
+
type: dto.type,
|
|
1259
|
+
tagline: dto.tagline,
|
|
1260
|
+
bannerUrl: dto.banner_url,
|
|
1261
|
+
logoUrl: dto.logo_url,
|
|
1262
|
+
startsAt: new Date(dto.starts_at),
|
|
1263
|
+
endsAt: dto.ends_at ? new Date(dto.ends_at) : null,
|
|
1264
|
+
tokens: dto.tokens.map(OfferToken.fromDto)
|
|
1265
|
+
};
|
|
1266
|
+
}
|
|
1267
|
+
};
|
|
1268
|
+
var OfferToken = {
|
|
1269
|
+
fromDto: (dto) => ({
|
|
1270
|
+
role: dto.role,
|
|
1271
|
+
chain: Chain(dto.chain),
|
|
1272
|
+
address: EvmContractAddress(dto.address)
|
|
1273
|
+
})
|
|
1274
|
+
};
|
|
1275
|
+
|
|
1276
|
+
// src/shared/types/offer-detail.ts
|
|
1277
|
+
var OfferOptionId = (value) => value;
|
|
1278
|
+
var OfferOptionSlug = (value) => value;
|
|
1279
|
+
var OfferDetail = {
|
|
1280
|
+
fromDto: (dto) => {
|
|
1281
|
+
if (!Array.isArray(dto.funding_assets)) {
|
|
1282
|
+
throw new ValidationError(
|
|
1283
|
+
`OfferDetail.funding_assets: expected an array, got ${typeof dto.funding_assets}`
|
|
1284
|
+
);
|
|
1285
|
+
}
|
|
1286
|
+
if (!Array.isArray(dto.options)) {
|
|
1287
|
+
throw new ValidationError(
|
|
1288
|
+
`OfferDetail.options: expected an array, got ${typeof dto.options}`
|
|
1289
|
+
);
|
|
1290
|
+
}
|
|
1291
|
+
if (!Array.isArray(dto.terms)) {
|
|
1292
|
+
throw new ValidationError(
|
|
1293
|
+
`OfferDetail.terms: expected an array, got ${typeof dto.terms}`
|
|
1294
|
+
);
|
|
1295
|
+
}
|
|
1296
|
+
if (!Array.isArray(dto.links)) {
|
|
1297
|
+
throw new ValidationError(
|
|
1298
|
+
`OfferDetail.links: expected an array, got ${typeof dto.links}`
|
|
1299
|
+
);
|
|
1300
|
+
}
|
|
1301
|
+
if (!Array.isArray(dto.faqs)) {
|
|
1302
|
+
throw new ValidationError(
|
|
1303
|
+
`OfferDetail.faqs: expected an array, got ${typeof dto.faqs}`
|
|
1304
|
+
);
|
|
1305
|
+
}
|
|
1306
|
+
if (!Array.isArray(dto.milestones)) {
|
|
1307
|
+
throw new ValidationError(
|
|
1308
|
+
`OfferDetail.milestones: expected an array, got ${typeof dto.milestones}`
|
|
1309
|
+
);
|
|
1310
|
+
}
|
|
1311
|
+
if (!Array.isArray(dto.tokens)) {
|
|
1312
|
+
throw new ValidationError(
|
|
1313
|
+
`OfferDetail.tokens: expected an array, got ${typeof dto.tokens}`
|
|
1314
|
+
);
|
|
1315
|
+
}
|
|
1316
|
+
return {
|
|
1317
|
+
id: OfferId(dto.id),
|
|
1318
|
+
slug: OfferSlug(dto.slug),
|
|
1319
|
+
type: dto.type,
|
|
1320
|
+
name: dto.name,
|
|
1321
|
+
asset: Asset.fromDto(dto.asset),
|
|
1322
|
+
fundingAssets: dto.funding_assets.map(Asset.fromDto),
|
|
1323
|
+
tokens: dto.tokens.map(OfferToken.fromDto),
|
|
1324
|
+
about: notBlankStringOrNull(dto.about),
|
|
1325
|
+
tagline: dto.tagline,
|
|
1326
|
+
bannerUrl: dto.banner_url,
|
|
1327
|
+
logoUrl: dto.logo_url,
|
|
1328
|
+
category: dto.category,
|
|
1329
|
+
startsAt: new Date(dto.starts_at),
|
|
1330
|
+
endsAt: dto.ends_at ? new Date(dto.ends_at) : null,
|
|
1331
|
+
faqs: dto.faqs.map(FaqItem.fromDto),
|
|
1332
|
+
links: dto.links.map(Link.fromDto),
|
|
1333
|
+
milestones: dto.milestones.map(Milestone.fromDto),
|
|
1334
|
+
options: dto.options.map(OfferOption.fromDto),
|
|
1335
|
+
terms: dto.terms.map(TermItem.fromDto)
|
|
1336
|
+
};
|
|
1337
|
+
}
|
|
1338
|
+
};
|
|
1339
|
+
var OfferOption = {
|
|
1340
|
+
fromDto: (dto) => ({
|
|
1341
|
+
id: OfferOptionId(dto.id),
|
|
1342
|
+
slug: OfferOptionSlug(dto.slug),
|
|
1343
|
+
bidIncrement: dto.bid_increment,
|
|
1344
|
+
floorPriceUsd: dto.floor_price_usd,
|
|
1345
|
+
minimumPurchaseUsd: dto.minimum_purchase_usd,
|
|
1346
|
+
priceUsd: dto.price_usd,
|
|
1347
|
+
saleAgreementUrl: notBlankStringOrNull(dto.sale_agreement_url),
|
|
1348
|
+
totalTokenSupply: dto.total_token_supply
|
|
1349
|
+
})
|
|
1350
|
+
};
|
|
1351
|
+
var FaqItem = {
|
|
1352
|
+
fromDto: (dto) => ({
|
|
1353
|
+
question: notBlankStringOrNull(dto.question),
|
|
1354
|
+
answer: notBlankStringOrNull(dto.answer)
|
|
1355
|
+
})
|
|
1356
|
+
};
|
|
1357
|
+
var Link = {
|
|
1358
|
+
fromDto: (dto) => ({
|
|
1359
|
+
label: notBlankStringOrNull(dto.label),
|
|
1360
|
+
url: notBlankStringOrNull(dto.url)
|
|
1361
|
+
})
|
|
1362
|
+
};
|
|
1363
|
+
var TermItem = {
|
|
1364
|
+
fromDto: (dto) => ({
|
|
1365
|
+
key: notBlankStringOrNull(dto.key),
|
|
1366
|
+
value: notBlankStringOrNull(dto.value)
|
|
1367
|
+
})
|
|
1368
|
+
};
|
|
1369
|
+
var Milestone = {
|
|
1370
|
+
fromDto: (dto) => ({
|
|
1371
|
+
name: notBlankStringOrNull(dto.name),
|
|
1372
|
+
schedule: notBlankStringOrNull(dto.schedule),
|
|
1373
|
+
status: dto.status
|
|
1374
|
+
})
|
|
1375
|
+
};
|
|
1376
|
+
|
|
1377
|
+
// src/shared/types/providers/coin-list/token-sale.ts
|
|
1378
|
+
var ParticipationId = (value) => value;
|
|
1379
|
+
var Blockchain = (value) => value;
|
|
1380
|
+
var WalletAddress = (value) => value;
|
|
1381
|
+
var ParticipationsPaginationParams = {
|
|
1382
|
+
toQueryParams: (params) => {
|
|
1383
|
+
const queryParams = PaginationParams.toQueryParams(params);
|
|
1384
|
+
if (params.offerId) {
|
|
1385
|
+
queryParams["filters[0][field]"] = "offer_id";
|
|
1386
|
+
queryParams["filters[0][op]"] = "==";
|
|
1387
|
+
queryParams["filters[0][value]"] = params.offerId;
|
|
1388
|
+
}
|
|
1389
|
+
return queryParams;
|
|
1390
|
+
}
|
|
1391
|
+
};
|
|
1392
|
+
var Participation = {
|
|
1393
|
+
/** Maps API DTO shape into the SDK participation domain model. */
|
|
1394
|
+
fromDto: (dto) => {
|
|
1395
|
+
const walletAddress = notBlankStringOrNull(dto.wallet_address);
|
|
1396
|
+
return {
|
|
1397
|
+
id: ParticipationId(dto.id),
|
|
1398
|
+
offerId: OfferId(dto.offer_id),
|
|
1399
|
+
offerOptionId: OfferOptionId(dto.offer_option_id),
|
|
1400
|
+
status: dto.status,
|
|
1401
|
+
amount: dto.amount,
|
|
1402
|
+
displayAmount: dto.amount_string,
|
|
1403
|
+
asset: Asset.fromDto(dto.asset),
|
|
1404
|
+
chain: Blockchain(dto.chain),
|
|
1405
|
+
insertedAt: dto.inserted_at ? new Date(dto.inserted_at) : null,
|
|
1406
|
+
updatedAt: dto.updated_at ? new Date(dto.updated_at) : null,
|
|
1407
|
+
walletAddress: walletAddress ? WalletAddress(walletAddress) : null
|
|
1408
|
+
};
|
|
1409
|
+
}
|
|
1410
|
+
};
|
|
1411
|
+
var CreateParticipationParams = {
|
|
1412
|
+
/** Maps participation creation params into API DTO payload. */
|
|
1413
|
+
toDto: (params) => ({
|
|
1414
|
+
offer_id: params.offerId,
|
|
1415
|
+
offer_option_id: params.offerOptionId,
|
|
1416
|
+
chain: params.chain,
|
|
1417
|
+
wallet_address: params.walletAddress,
|
|
1418
|
+
amount: params.amount,
|
|
1419
|
+
asset_id: params.assetId,
|
|
1420
|
+
approval_transaction_hash: params.approvalTransactionHash
|
|
1421
|
+
})
|
|
1422
|
+
};
|
|
1423
|
+
|
|
1424
|
+
// src/shared/api/frontline/providers/coin-list/token-sale.ts
|
|
1425
|
+
async function fetchParticipations(api, offerId) {
|
|
1426
|
+
return fetchAllPages(
|
|
1427
|
+
(params) => fetchParticipationsPage(api, params),
|
|
1428
|
+
{ offerId }
|
|
1429
|
+
);
|
|
1430
|
+
}
|
|
1431
|
+
async function fetchParticipationsPage(api, params) {
|
|
1432
|
+
const pageDto = await api.send({
|
|
1433
|
+
method: "GET",
|
|
1434
|
+
url: "/v1/participations",
|
|
1435
|
+
queryParams: ParticipationsPaginationParams.toQueryParams(params),
|
|
1436
|
+
attributes: Attributes.protected()
|
|
1437
|
+
});
|
|
1438
|
+
return PaginatedResponse.fromDto(pageDto, Participation.fromDto);
|
|
1439
|
+
}
|
|
1440
|
+
async function fetchParticipation(api, id) {
|
|
1441
|
+
const dto = await api.send({
|
|
1442
|
+
method: "GET",
|
|
1443
|
+
url: `/v1/participations/${id}`,
|
|
1444
|
+
attributes: Attributes.protected()
|
|
1445
|
+
});
|
|
1446
|
+
return Participation.fromDto(dto);
|
|
1447
|
+
}
|
|
1448
|
+
async function createParticipation(api, params) {
|
|
1449
|
+
const dto = await api.send({
|
|
1450
|
+
method: "POST",
|
|
1451
|
+
url: "/v1/participations",
|
|
1452
|
+
body: CreateParticipationParams.toDto(params),
|
|
1453
|
+
attributes: Attributes.protected()
|
|
1454
|
+
});
|
|
1455
|
+
return Participation.fromDto(dto);
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
// src/shared/core/checkout/coin-list/token-sale-namespace.ts
|
|
1459
|
+
var CoinListTokenSaleNamespaceImpl = class {
|
|
1460
|
+
constructor(ctx) {
|
|
1461
|
+
this.ctx = ctx;
|
|
1462
|
+
this.log = internalLogger(ctx.logger, "TOKEN_SALE");
|
|
1463
|
+
}
|
|
1464
|
+
async list(offerId) {
|
|
1465
|
+
return this.log.wrap("list", offerId, async () => {
|
|
1466
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1467
|
+
return fetchParticipations(this.ctx.api, offerId);
|
|
1468
|
+
});
|
|
1469
|
+
}
|
|
1470
|
+
async listPage(params) {
|
|
1471
|
+
return this.log.wrap("listPage", params, async () => {
|
|
1472
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1473
|
+
return fetchParticipationsPage(this.ctx.api, params);
|
|
1474
|
+
});
|
|
1475
|
+
}
|
|
1476
|
+
async get(id) {
|
|
1477
|
+
return this.log.wrap("get", id, async () => {
|
|
1478
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1479
|
+
return fetchParticipation(this.ctx.api, id);
|
|
1480
|
+
});
|
|
1481
|
+
}
|
|
1482
|
+
async createParticipation(params) {
|
|
1483
|
+
return this.log.wrap("createParticipation", params, async () => {
|
|
1484
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1485
|
+
return createParticipation(this.ctx.api, params);
|
|
1486
|
+
});
|
|
1487
|
+
}
|
|
1488
|
+
};
|
|
1489
|
+
|
|
1490
|
+
// src/shared/core/checkout/ondo/constants.ts
|
|
1491
|
+
var ONDO_SWAP_CONTRACT_ADDRESSES = {
|
|
1492
|
+
ethereum_sepolia: EvmContractAddress(
|
|
1493
|
+
"0xFF9c5Ade32d9B4102469Bd5F3817CB0061b25feC"
|
|
1494
|
+
)
|
|
1495
|
+
};
|
|
1496
|
+
function ondoSwapContractAddress(chain) {
|
|
1497
|
+
return ONDO_SWAP_CONTRACT_ADDRESSES[chain] ?? null;
|
|
1498
|
+
}
|
|
1499
|
+
var ONDO_POLL_INTERVAL_MS = 15e3;
|
|
1500
|
+
var ONDO_QUOTE_EXPIRY_THRESHOLD_MS = 5e3;
|
|
1501
|
+
var DEFAULT_ONDO_AMOUNT_TO_COMPUTE_PRICE = DecimalString("1000");
|
|
1502
|
+
var ONDO_SUPPORTED_INPUT_ASSETS = [
|
|
1503
|
+
USDC_SYMBOL
|
|
1504
|
+
];
|
|
1505
|
+
|
|
1506
|
+
// src/shared/core/checkout/ondo/math.ts
|
|
1507
|
+
function computeOndoPrice(transaction) {
|
|
1508
|
+
const { notionalValue, receiveOutputAmount } = transaction;
|
|
1509
|
+
if (receiveOutputAmount.raw <= 0n) {
|
|
1510
|
+
throw new ValidationError(
|
|
1511
|
+
"Ondo price: receiveOutputAmount must be greater than zero"
|
|
1512
|
+
);
|
|
1513
|
+
}
|
|
1514
|
+
const scaled = notionalValue.raw * 10n ** BigInt(receiveOutputAmount.decimals);
|
|
1515
|
+
const raw = scaled / receiveOutputAmount.raw;
|
|
1516
|
+
return BlockchainAmount({
|
|
1517
|
+
raw: assertPriceFits(raw),
|
|
1518
|
+
decimals: notionalValue.decimals
|
|
1519
|
+
});
|
|
1520
|
+
}
|
|
1521
|
+
function assertPriceFits(raw) {
|
|
1522
|
+
try {
|
|
1523
|
+
return assertUint256(raw);
|
|
1524
|
+
} catch {
|
|
1525
|
+
throw new ValidationError(`Ondo price: out of uint256 bounds (${raw})`);
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
// src/shared/types/trading.ts
|
|
1530
|
+
var Ticker = (value) => value;
|
|
1531
|
+
|
|
1532
|
+
// src/shared/types/providers/ondo/ondo.ts
|
|
1533
|
+
var OndoTradingStatus = {
|
|
1534
|
+
fromDto: (dto) => {
|
|
1535
|
+
if (!dto.tradable) return { type: "not-tradable", side: dto.side };
|
|
1536
|
+
return {
|
|
1537
|
+
type: "tradable",
|
|
1538
|
+
side: dto.side,
|
|
1539
|
+
grossMaxTokens: decimalOrNull(dto.gross_max_tokens),
|
|
1540
|
+
grossMaxNotionalValue: decimalOrNull(dto.gross_max_notional_value),
|
|
1541
|
+
grossMaxActiveNotionalValue: decimalOrNull(
|
|
1542
|
+
dto.gross_max_active_notional_value
|
|
1543
|
+
)
|
|
1544
|
+
};
|
|
1545
|
+
}
|
|
1546
|
+
};
|
|
1547
|
+
var decimalOrNull = (value) => value === null ? null : DecimalString(value);
|
|
1548
|
+
var OndoQuote = {
|
|
1549
|
+
fromDto: (dto) => {
|
|
1550
|
+
const assetDecimals = AssetDecimals(dto.asset_decimals);
|
|
1551
|
+
return {
|
|
1552
|
+
chain: chainFromId(dto.chain_id),
|
|
1553
|
+
ticker: Ticker(dto.ticker),
|
|
1554
|
+
assetAddress: EvmContractAddress(dto.asset_address),
|
|
1555
|
+
asset: {
|
|
1556
|
+
name: dto.ticker,
|
|
1557
|
+
symbol: AssetSymbol(dto.symbol),
|
|
1558
|
+
decimals: assetDecimals
|
|
1559
|
+
},
|
|
1560
|
+
side: dto.side,
|
|
1561
|
+
tokenBaseUnits: blockchainAmountFromRawOrThrow({
|
|
1562
|
+
label: "tokenBaseUnits",
|
|
1563
|
+
raw: dto.token_base_units,
|
|
1564
|
+
decimals: assetDecimals
|
|
1565
|
+
}),
|
|
1566
|
+
price: DecimalString(dto.price)
|
|
1567
|
+
};
|
|
1568
|
+
}
|
|
1569
|
+
};
|
|
1570
|
+
var OndoSwapTransaction = {
|
|
1571
|
+
fromDto: (dto) => {
|
|
1572
|
+
const inputDecimals = AssetDecimals(dto.pay_input_decimals);
|
|
1573
|
+
const outputDecimals = AssetDecimals(dto.receive_output_decimals);
|
|
1574
|
+
return {
|
|
1575
|
+
tx: {
|
|
1576
|
+
to: EvmContractAddress(dto.to),
|
|
1577
|
+
data: HexEncodedTransactionData(dto.data)
|
|
1578
|
+
},
|
|
1579
|
+
expiresAt: parseExpiresAt(dto.expires_at),
|
|
1580
|
+
payInputAmount: blockchainAmountFromRawOrThrow({
|
|
1581
|
+
label: "pay_input_amount",
|
|
1582
|
+
raw: dto.pay_input_amount,
|
|
1583
|
+
decimals: inputDecimals
|
|
1584
|
+
}),
|
|
1585
|
+
fee: blockchainAmountFromRawOrThrow({
|
|
1586
|
+
label: "fee",
|
|
1587
|
+
raw: dto.fee,
|
|
1588
|
+
decimals: inputDecimals
|
|
1589
|
+
}),
|
|
1590
|
+
notionalValue: blockchainAmountFromRawOrThrow({
|
|
1591
|
+
label: "notional_value",
|
|
1592
|
+
raw: dto.notional_value,
|
|
1593
|
+
decimals: inputDecimals
|
|
1594
|
+
}),
|
|
1595
|
+
receiveOutputAmount: parseReceiveOutputAmount(
|
|
1596
|
+
dto.receive_output_amount,
|
|
1597
|
+
outputDecimals
|
|
1598
|
+
)
|
|
1599
|
+
};
|
|
1600
|
+
}
|
|
1601
|
+
};
|
|
1602
|
+
function parseReceiveOutputAmount(raw, decimals) {
|
|
1603
|
+
const amount = blockchainAmountFromRawOrThrow({
|
|
1604
|
+
label: "receive_output_amount",
|
|
1605
|
+
raw,
|
|
1606
|
+
decimals
|
|
1607
|
+
});
|
|
1608
|
+
if (amount.raw <= 0n) {
|
|
1609
|
+
throw new ValidationError(
|
|
1610
|
+
`receive_output_amount: must be greater than zero ("${raw}")`
|
|
1611
|
+
);
|
|
1612
|
+
}
|
|
1613
|
+
return amount;
|
|
1614
|
+
}
|
|
1615
|
+
function parseExpiresAt(value) {
|
|
1616
|
+
const date = new Date(value);
|
|
1617
|
+
if (Number.isNaN(date.getTime())) {
|
|
1618
|
+
throw new ValidationError(`expires_at: not a date ("${value}")`);
|
|
1619
|
+
}
|
|
1620
|
+
return date;
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1623
|
+
// src/shared/api/frontline/providers/ondo/ondo.ts
|
|
1624
|
+
async function getOndoTradingStatus(api, params) {
|
|
1625
|
+
const dto = await api.send({
|
|
1626
|
+
method: "GET",
|
|
1627
|
+
url: "/v1/ondo/swap/trading-status",
|
|
1628
|
+
queryParams: { symbol: params.symbol, side: params.side },
|
|
1629
|
+
attributes: Attributes.protected()
|
|
1630
|
+
});
|
|
1631
|
+
return OndoTradingStatus.fromDto(dto);
|
|
1632
|
+
}
|
|
1633
|
+
async function getOndoQuote(api, params) {
|
|
1634
|
+
const dto = await api.send({
|
|
1635
|
+
method: "GET",
|
|
1636
|
+
url: "/v1/ondo/swap/quote",
|
|
1637
|
+
queryParams: {
|
|
1638
|
+
symbol: params.symbol,
|
|
1639
|
+
side: params.side,
|
|
1640
|
+
duration: params.duration,
|
|
1641
|
+
...sizeParam(params)
|
|
1642
|
+
},
|
|
1643
|
+
attributes: Attributes.protected()
|
|
1644
|
+
});
|
|
1645
|
+
return OndoQuote.fromDto(dto);
|
|
1646
|
+
}
|
|
1647
|
+
async function buildOndoSwapTransaction(api, params) {
|
|
1648
|
+
const dto = await api.send({
|
|
1649
|
+
method: "POST",
|
|
1650
|
+
url: "/v1/ondo/swap/transaction",
|
|
1651
|
+
body: {
|
|
1652
|
+
symbol: params.symbol,
|
|
1653
|
+
chain: params.chain,
|
|
1654
|
+
wallet_address: params.walletAddress,
|
|
1655
|
+
amount: params.amount.raw.toString()
|
|
1656
|
+
},
|
|
1657
|
+
attributes: Attributes.protected()
|
|
1658
|
+
});
|
|
1659
|
+
assertFundingScaleAgrees(dto, params);
|
|
1660
|
+
return OndoSwapTransaction.fromDto(dto);
|
|
1661
|
+
}
|
|
1662
|
+
function assertFundingScaleAgrees(dto, params) {
|
|
1663
|
+
if (dto.pay_input_decimals !== params.amount.decimals) {
|
|
1664
|
+
throw new ValidationError(
|
|
1665
|
+
`pay_input_decimals: the swap was priced in ${dto.pay_input_decimals} decimals but the order was sized in ${params.amount.decimals}`
|
|
1666
|
+
);
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
function sizeParam(params) {
|
|
1670
|
+
const tokenAmount = "tokenAmount" in params ? params.tokenAmount : void 0;
|
|
1671
|
+
const notionalValue = "notionalValue" in params ? params.notionalValue : void 0;
|
|
1672
|
+
if (tokenAmount !== void 0) {
|
|
1673
|
+
if (notionalValue !== void 0) {
|
|
1674
|
+
throw new ValidationError(
|
|
1675
|
+
"An Ondo quote takes tokenAmount or notionalValue, not both"
|
|
1676
|
+
);
|
|
1677
|
+
}
|
|
1678
|
+
return { token_amount: formatRawAmount(tokenAmount) };
|
|
1679
|
+
}
|
|
1680
|
+
if (notionalValue === void 0) {
|
|
1681
|
+
throw new ValidationError(
|
|
1682
|
+
"An Ondo quote must be sized by tokenAmount or notionalValue"
|
|
1683
|
+
);
|
|
1684
|
+
}
|
|
1685
|
+
return { notional_value: notionalValue };
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
// src/shared/core/checkout/ondo/ondo-namespace.ts
|
|
1689
|
+
var OndoNamespaceImpl = class {
|
|
1690
|
+
constructor(ctx) {
|
|
1691
|
+
this.ctx = ctx;
|
|
1692
|
+
this.log = internalLogger(ctx.logger, "ONDO");
|
|
1693
|
+
}
|
|
1694
|
+
async getTradingStatus(params) {
|
|
1695
|
+
return this.log.wrap("getTradingStatus", params, async () => {
|
|
1696
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1697
|
+
return getOndoTradingStatus(this.ctx.api, params);
|
|
1698
|
+
});
|
|
1699
|
+
}
|
|
1700
|
+
async getQuote(params) {
|
|
1701
|
+
return this.log.wrap("getQuote", params, async () => {
|
|
1702
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1703
|
+
return getOndoQuote(this.ctx.api, params);
|
|
1704
|
+
});
|
|
1705
|
+
}
|
|
1706
|
+
async buildSwapTransaction(params) {
|
|
1707
|
+
return this.log.wrap("buildSwapTransaction", params, async () => {
|
|
1708
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1709
|
+
return buildOndoSwapTransaction(this.ctx.api, params);
|
|
1710
|
+
});
|
|
1711
|
+
}
|
|
1712
|
+
};
|
|
278
1713
|
|
|
279
|
-
// src/shared/core/blockchain/
|
|
1714
|
+
// src/shared/core/checkout/superstate/blockchain/abi.ts
|
|
280
1715
|
var SUPERSTATE_SWAP_ABI = [
|
|
281
1716
|
{
|
|
282
1717
|
type: "function",
|
|
@@ -478,281 +1913,45 @@ var SUPERSTATE_SWAP_ABI = [
|
|
|
478
1913
|
name: "InvalidAddress",
|
|
479
1914
|
inputs: []
|
|
480
1915
|
},
|
|
481
|
-
{
|
|
482
|
-
type: "error",
|
|
483
|
-
name: "InsufficientAmount",
|
|
484
|
-
inputs: []
|
|
485
|
-
},
|
|
486
|
-
{
|
|
487
|
-
type: "error",
|
|
488
|
-
name: "InvalidAmount",
|
|
489
|
-
inputs: []
|
|
490
|
-
},
|
|
491
|
-
{
|
|
492
|
-
type: "error",
|
|
493
|
-
name: "SwapFailed",
|
|
494
|
-
inputs: [
|
|
495
|
-
{ name: "user", type: "address", internalType: "address" },
|
|
496
|
-
{ name: "token", type: "address", internalType: "address" }
|
|
497
|
-
]
|
|
498
|
-
}
|
|
499
|
-
];
|
|
500
|
-
|
|
501
|
-
// src/shared/types/blockchain/core.ts
|
|
502
|
-
var EvmWalletAddress = (value) => value;
|
|
503
|
-
var EvmContractAddress = (value) => value;
|
|
504
|
-
var HexEncodedTransactionData = (value) => value;
|
|
505
|
-
var AssetDecimals = (value) => value;
|
|
506
|
-
var MAX_UINT_256 = 2n ** 256n - 1n;
|
|
507
|
-
var assertUint256 = (value) => {
|
|
508
|
-
if (value < 0n || value > MAX_UINT_256) {
|
|
509
|
-
throw new Error(`Value out of uint256 bounds: ${value}`);
|
|
510
|
-
}
|
|
511
|
-
return value;
|
|
512
|
-
};
|
|
513
|
-
var BlockchainAmount = Object.assign(
|
|
514
|
-
(value) => value,
|
|
515
|
-
{
|
|
516
|
-
add: (a, b) => combineAmounts(a, b, (x, y) => x + y),
|
|
517
|
-
sub: (a, b) => combineAmounts(a, b, (x, y) => x - y)
|
|
518
|
-
}
|
|
519
|
-
);
|
|
520
|
-
function combineAmounts(a, b, op) {
|
|
521
|
-
if (a.decimals !== b.decimals) {
|
|
522
|
-
throw new Error(
|
|
523
|
-
`Cannot combine BlockchainAmounts with different decimals: ${a.decimals} vs ${b.decimals}`
|
|
524
|
-
);
|
|
525
|
-
}
|
|
526
|
-
const raw = op(a.raw, b.raw);
|
|
527
|
-
if (raw < 0n || raw > MAX_UINT_256) {
|
|
528
|
-
throw new Error(`BlockchainAmount out of uint256 bounds: ${raw}`);
|
|
529
|
-
}
|
|
530
|
-
return BlockchainAmount({ raw, decimals: a.decimals });
|
|
531
|
-
}
|
|
532
|
-
var AssetSymbol = (value) => value;
|
|
533
|
-
var StablecoinSymbol = (value) => value;
|
|
534
|
-
var KnownAssetSymbol = StablecoinSymbol;
|
|
535
|
-
var Bps = (value) => value;
|
|
536
|
-
|
|
537
|
-
// src/shared/core/blockchain/bps.ts
|
|
538
|
-
var BPS_DENOM = Bps(10000n);
|
|
539
|
-
function applyBps(amount, bps) {
|
|
540
|
-
return assertUint256(amount * bps / BPS_DENOM);
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
// src/shared/types/blockchain/ui.ts
|
|
544
|
-
var FormattedAmountUi = (value) => value;
|
|
545
|
-
var FormattedPercentUi = (value) => value;
|
|
546
|
-
var TxExplorerUrl = (value) => value;
|
|
547
|
-
var ShortenedWalletAddress = (value) => value;
|
|
548
|
-
var FormattedAmountAssetUi = (value) => value;
|
|
549
|
-
var AssetIconUrl = (value) => value;
|
|
550
|
-
|
|
551
|
-
// src/shared/core/blockchain/chain.ts
|
|
552
|
-
function getChainId(chain) {
|
|
553
|
-
switch (chain) {
|
|
554
|
-
case "ethereum_mainnet":
|
|
555
|
-
return 1;
|
|
556
|
-
case "ethereum_sepolia":
|
|
557
|
-
return 11155111;
|
|
558
|
-
default: {
|
|
559
|
-
const _exhaustive = chain;
|
|
560
|
-
return _exhaustive;
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
function getNetworkName(chain) {
|
|
565
|
-
switch (chain) {
|
|
566
|
-
case "ethereum_mainnet":
|
|
567
|
-
return "Ethereum";
|
|
568
|
-
case "ethereum_sepolia":
|
|
569
|
-
return "Ethereum Sepolia";
|
|
570
|
-
default: {
|
|
571
|
-
const _exhaustive = chain;
|
|
572
|
-
return _exhaustive;
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
function txExplorerUrl(chain, txHash) {
|
|
577
|
-
return TxExplorerUrl(`${explorerBaseUrl(chain)}/tx/${txHash}`);
|
|
578
|
-
}
|
|
579
|
-
function explorerBaseUrl(chain) {
|
|
580
|
-
switch (chain) {
|
|
581
|
-
case "ethereum_mainnet":
|
|
582
|
-
return "https://etherscan.io";
|
|
583
|
-
case "ethereum_sepolia":
|
|
584
|
-
return "https://sepolia.etherscan.io";
|
|
585
|
-
default: {
|
|
586
|
-
const _exhaustive = chain;
|
|
587
|
-
return _exhaustive;
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
// src/shared/core/blockchain/formatters.ts
|
|
593
|
-
var import_viem = require("viem");
|
|
594
|
-
|
|
595
|
-
// src/shared/core/blockchain/swap/math.ts
|
|
596
|
-
function computePrice({
|
|
597
|
-
inputTokenAmount,
|
|
598
|
-
outputTokenAmount
|
|
599
|
-
}) {
|
|
600
|
-
if (outputTokenAmount.raw === 0n) return null;
|
|
601
|
-
const scale = 10n ** BigInt(outputTokenAmount.decimals);
|
|
602
|
-
const raw = assertUint256(
|
|
603
|
-
inputTokenAmount.raw * scale / outputTokenAmount.raw
|
|
604
|
-
);
|
|
605
|
-
return BlockchainAmount({ raw, decimals: inputTokenAmount.decimals });
|
|
606
|
-
}
|
|
607
|
-
function computeSlip(amount, slippage) {
|
|
608
|
-
const retained = Bps(assertUint256(BPS_DENOM - slippage));
|
|
609
|
-
const slipRaw = applyBps(amount.raw, retained);
|
|
610
|
-
return BlockchainAmount({ raw: slipRaw, decimals: amount.decimals });
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
// src/shared/core/blockchain/formatters.ts
|
|
614
|
-
function shortenAddress(address) {
|
|
615
|
-
const short = address.length > 10 ? `${address.slice(0, 6)}\u2026${address.slice(-4)}` : address;
|
|
616
|
-
return ShortenedWalletAddress(short);
|
|
617
|
-
}
|
|
618
|
-
function formatAmount(amount, locale, options) {
|
|
619
|
-
const decimal = formatRawAmount(amount);
|
|
620
|
-
let [integerPart, fractionPart = ""] = decimal.split(".");
|
|
621
|
-
const maxFractionDigits = options?.maxFractionDigits;
|
|
622
|
-
const minFractionDigits = maxFractionDigits !== void 0 ? Math.min(maxFractionDigits, amount.decimals) : Math.min(2, amount.decimals);
|
|
623
|
-
if (maxFractionDigits !== void 0 && fractionPart.length > maxFractionDigits) {
|
|
624
|
-
({ integerPart, fractionPart } = roundFractionHalfUp(
|
|
625
|
-
integerPart,
|
|
626
|
-
fractionPart,
|
|
627
|
-
maxFractionDigits
|
|
628
|
-
));
|
|
629
|
-
}
|
|
630
|
-
const fraction = minFractionDigits === 0 ? "" : fractionPart.padEnd(minFractionDigits, "0");
|
|
631
|
-
const integerFormatted = BigInt(integerPart).toLocaleString(locale);
|
|
632
|
-
if (minFractionDigits === 0 && fraction === "") {
|
|
633
|
-
return FormattedAmountUi(integerFormatted);
|
|
634
|
-
}
|
|
635
|
-
const decimalSeparator = new Intl.NumberFormat(locale).formatToParts(1.1).find((p) => p.type === "decimal")?.value ?? ".";
|
|
636
|
-
return FormattedAmountUi(`${integerFormatted}${decimalSeparator}${fraction}`);
|
|
637
|
-
}
|
|
638
|
-
function roundFractionHalfUp(integerPart, fractionPart, maxFractionDigits) {
|
|
639
|
-
if (fractionPart.length <= maxFractionDigits) {
|
|
640
|
-
return { integerPart, fractionPart };
|
|
641
|
-
}
|
|
642
|
-
if (maxFractionDigits === 0) {
|
|
643
|
-
const roundUp = fractionPart[0] >= "5";
|
|
644
|
-
const integer = BigInt(integerPart) + (roundUp ? 1n : 0n);
|
|
645
|
-
return { integerPart: integer.toString(), fractionPart: "" };
|
|
646
|
-
}
|
|
647
|
-
const trimmed = fractionPart.slice(0, maxFractionDigits);
|
|
648
|
-
if (fractionPart[maxFractionDigits] < "5") {
|
|
649
|
-
return { integerPart, fractionPart: trimmed };
|
|
650
|
-
}
|
|
651
|
-
const digits = trimmed.split("").map((digit) => Number.parseInt(digit, 10));
|
|
652
|
-
let carry = 1;
|
|
653
|
-
for (let i = digits.length - 1; i >= 0 && carry > 0; i -= 1) {
|
|
654
|
-
const sum = digits[i] + carry;
|
|
655
|
-
if (sum === 10) {
|
|
656
|
-
digits[i] = 0;
|
|
657
|
-
carry = 1;
|
|
658
|
-
} else {
|
|
659
|
-
digits[i] = sum;
|
|
660
|
-
carry = 0;
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
return {
|
|
664
|
-
integerPart: carry > 0 ? (BigInt(integerPart) + 1n).toString() : integerPart,
|
|
665
|
-
fractionPart: digits.join("")
|
|
666
|
-
};
|
|
667
|
-
}
|
|
668
|
-
function formatRawAmount(amount) {
|
|
669
|
-
return (0, import_viem.formatUnits)(amount.raw, amount.decimals);
|
|
670
|
-
}
|
|
671
|
-
function formatCompactAmount(amount, locale) {
|
|
672
|
-
const value = Number(formatRawAmount(amount));
|
|
673
|
-
const formatted = new Intl.NumberFormat(locale, {
|
|
674
|
-
notation: "compact",
|
|
675
|
-
maximumFractionDigits: 2
|
|
676
|
-
}).format(value);
|
|
677
|
-
return FormattedAmountUi(formatted);
|
|
678
|
-
}
|
|
679
|
-
function formatBpsAsPercent(bps, locale) {
|
|
680
|
-
const whole = bps / 100n;
|
|
681
|
-
const fraction = bps % 100n;
|
|
682
|
-
const wholeFormatted = whole.toLocaleString(locale);
|
|
683
|
-
const decimalSeparator = new Intl.NumberFormat(locale).formatToParts(1.1).find((p) => p.type === "decimal")?.value ?? ".";
|
|
684
|
-
if (fraction === 0n) {
|
|
685
|
-
return FormattedPercentUi(`${wholeFormatted}%`);
|
|
686
|
-
}
|
|
687
|
-
const fractionFormatted = fraction.toString().padStart(2, "0").replace(/0+$/, "");
|
|
688
|
-
return FormattedPercentUi(
|
|
689
|
-
`${wholeFormatted}${decimalSeparator}${fractionFormatted}%`
|
|
690
|
-
);
|
|
691
|
-
}
|
|
692
|
-
function usdAmount(amount) {
|
|
693
|
-
return FormattedAmountAssetUi(`$${amount}`);
|
|
694
|
-
}
|
|
695
|
-
function assetAmount(amount, symbol) {
|
|
696
|
-
return FormattedAmountAssetUi(`${amount} ${symbol}`);
|
|
697
|
-
}
|
|
698
|
-
var NA_AMOUNT_ASSET_UI = FormattedAmountAssetUi("-");
|
|
699
|
-
var USD_FRACTION_DIGITS = AssetDecimals(2);
|
|
700
|
-
function formattedUsdPrice(amount, locale) {
|
|
701
|
-
if (!amount) return NA_AMOUNT_ASSET_UI;
|
|
702
|
-
return usdAmount(
|
|
703
|
-
formatAmount(amount, locale, { maxFractionDigits: USD_FRACTION_DIGITS })
|
|
704
|
-
);
|
|
705
|
-
}
|
|
706
|
-
function formattedPricePerShare(quote, locale) {
|
|
707
|
-
if (!quote) return NA_AMOUNT_ASSET_UI;
|
|
708
|
-
return formattedUsdPrice(computePrice(quote), locale);
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
// src/shared/core/blockchain/math.ts
|
|
712
|
-
var import_viem2 = require("viem");
|
|
713
|
-
function parseBlockchainAmount(amount, decimals) {
|
|
714
|
-
const trimmed = amount.trim();
|
|
715
|
-
if (trimmed === "") return { valid: false, reason: { type: "empty" } };
|
|
716
|
-
if (trimmed.startsWith("-")) {
|
|
717
|
-
return { valid: false, reason: { type: "negative" } };
|
|
718
|
-
}
|
|
719
|
-
if (/[eE]/.test(trimmed)) {
|
|
720
|
-
return { valid: false, reason: { type: "invalid-format" } };
|
|
721
|
-
}
|
|
722
|
-
if (!/^\d+(\.\d+)?$/.test(trimmed)) {
|
|
723
|
-
return { valid: false, reason: { type: "invalid-format" } };
|
|
724
|
-
}
|
|
725
|
-
const [, fraction = ""] = trimmed.split(".");
|
|
726
|
-
if (fraction.length > decimals) {
|
|
727
|
-
return {
|
|
728
|
-
valid: false,
|
|
729
|
-
reason: { type: "too-many-decimals", maxDecimals: decimals }
|
|
730
|
-
};
|
|
731
|
-
}
|
|
732
|
-
try {
|
|
733
|
-
return {
|
|
734
|
-
valid: true,
|
|
735
|
-
amount: BlockchainAmount({
|
|
736
|
-
raw: (0, import_viem2.parseUnits)(trimmed, decimals),
|
|
737
|
-
decimals
|
|
738
|
-
})
|
|
739
|
-
};
|
|
740
|
-
} catch {
|
|
741
|
-
return { valid: false, reason: { type: "invalid-format" } };
|
|
1916
|
+
{
|
|
1917
|
+
type: "error",
|
|
1918
|
+
name: "InsufficientAmount",
|
|
1919
|
+
inputs: []
|
|
1920
|
+
},
|
|
1921
|
+
{
|
|
1922
|
+
type: "error",
|
|
1923
|
+
name: "InvalidAmount",
|
|
1924
|
+
inputs: []
|
|
1925
|
+
},
|
|
1926
|
+
{
|
|
1927
|
+
type: "error",
|
|
1928
|
+
name: "SwapFailed",
|
|
1929
|
+
inputs: [
|
|
1930
|
+
{ name: "user", type: "address", internalType: "address" },
|
|
1931
|
+
{ name: "token", type: "address", internalType: "address" }
|
|
1932
|
+
]
|
|
742
1933
|
}
|
|
743
|
-
|
|
1934
|
+
];
|
|
744
1935
|
|
|
745
|
-
// src/shared/core/blockchain/
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
(
|
|
751
|
-
);
|
|
752
|
-
|
|
753
|
-
|
|
1936
|
+
// src/shared/core/checkout/superstate/blockchain/math.ts
|
|
1937
|
+
function computePrice({
|
|
1938
|
+
inputTokenAmount,
|
|
1939
|
+
outputTokenAmount
|
|
1940
|
+
}) {
|
|
1941
|
+
if (outputTokenAmount.raw === 0n) return null;
|
|
1942
|
+
const scale = 10n ** BigInt(outputTokenAmount.decimals);
|
|
1943
|
+
const raw = assertUint256(
|
|
1944
|
+
inputTokenAmount.raw * scale / outputTokenAmount.raw
|
|
1945
|
+
);
|
|
1946
|
+
return BlockchainAmount({ raw, decimals: inputTokenAmount.decimals });
|
|
1947
|
+
}
|
|
1948
|
+
function computeSlip(amount, slippage) {
|
|
1949
|
+
const retained = Bps(assertUint256(BPS_DENOM - slippage));
|
|
1950
|
+
const slipRaw = applyBps(amount.raw, retained);
|
|
1951
|
+
return BlockchainAmount({ raw: slipRaw, decimals: amount.decimals });
|
|
1952
|
+
}
|
|
754
1953
|
|
|
755
|
-
// src/shared/core/blockchain/
|
|
1954
|
+
// src/shared/core/checkout/superstate/blockchain/quote.ts
|
|
756
1955
|
var SwapQuote = {
|
|
757
1956
|
/**
|
|
758
1957
|
* Assembles a {@link SwapQuote} from a raw contract {@link SwapPreview}. The
|
|
@@ -772,12 +1971,12 @@ var SwapQuote = {
|
|
|
772
1971
|
})
|
|
773
1972
|
};
|
|
774
1973
|
|
|
775
|
-
// src/shared/core/blockchain/
|
|
1974
|
+
// src/shared/core/checkout/superstate/blockchain/status.ts
|
|
776
1975
|
function isStopped(status) {
|
|
777
1976
|
return (status.stopped & status.swapLevel) !== 0n;
|
|
778
1977
|
}
|
|
779
1978
|
|
|
780
|
-
// src/shared/core/blockchain/
|
|
1979
|
+
// src/shared/core/checkout/superstate/blockchain/swapped-event.ts
|
|
781
1980
|
var import_viem3 = require("viem");
|
|
782
1981
|
function decodeSwappedOutputAmount(receipt, outputDecimals) {
|
|
783
1982
|
try {
|
|
@@ -795,420 +1994,615 @@ function decodeSwappedOutputAmount(receipt, outputDecimals) {
|
|
|
795
1994
|
}
|
|
796
1995
|
}
|
|
797
1996
|
|
|
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
|
-
}
|
|
1997
|
+
// src/shared/core/checkout/superstate/constants.ts
|
|
1998
|
+
var SUPERSTATE_ISSUER_NAME = "Superstate";
|
|
1999
|
+
var SUPERSTATE_SUPPORTED_INPUT_ASSETS = [USDC_SYMBOL];
|
|
2000
|
+
var SWAP_POLL_INTERVAL_MS = 15e3;
|
|
2001
|
+
var DEFAULT_AMOUNT_TO_COMPUTE_PRICE = 1000000n;
|
|
2002
|
+
var SLIPPAGE_OPTIONS_BPS = [25n, 50n, 100n, 200n, 500n].map(
|
|
2003
|
+
(n) => Bps(n)
|
|
2004
|
+
);
|
|
2005
|
+
var DEFAULT_SLIPPAGE_BPS = Bps(50n);
|
|
2006
|
+
var SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA = EvmContractAddress("0x84f8e9a6C9Cc12fe911259372EfCa5582C4ae557");
|
|
2007
|
+
var SUPERSTATE_SWAP_CONTRACT_ADDRESSES = {
|
|
2008
|
+
ethereum_sepolia: SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA
|
|
848
2009
|
};
|
|
2010
|
+
function superstateSwapContractAddress(chain) {
|
|
2011
|
+
return SUPERSTATE_SWAP_CONTRACT_ADDRESSES[chain] ?? null;
|
|
2012
|
+
}
|
|
849
2013
|
|
|
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
|
-
};
|
|
2014
|
+
// src/shared/core/checkout/superstate/formatters.ts
|
|
2015
|
+
function formattedPricePerShare(quote, locale) {
|
|
2016
|
+
if (!quote) return NA_AMOUNT_ASSET_UI;
|
|
2017
|
+
return formattedUsdPrice(computePrice(quote), locale);
|
|
2018
|
+
}
|
|
900
2019
|
|
|
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
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
};
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
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
|
-
}
|
|
2020
|
+
// src/shared/core/checkout/superstate/swap-namespace.ts
|
|
2021
|
+
var SuperstateSwapNamespaceImpl = class {
|
|
2022
|
+
constructor(ctx) {
|
|
2023
|
+
this.ctx = ctx;
|
|
2024
|
+
this.log = internalLogger(ctx.logger, "SUPERSTATE");
|
|
2025
|
+
}
|
|
2026
|
+
async getAuthorization(params) {
|
|
2027
|
+
return this.log.wrap("getAuthorization", params, async () => {
|
|
2028
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2029
|
+
return getSwapAuthorization(this.ctx.api, params);
|
|
2030
|
+
});
|
|
2031
|
+
}
|
|
2032
|
+
async getPreview(params) {
|
|
2033
|
+
return this.log.wrap("getPreview", params, async () => {
|
|
2034
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2035
|
+
return getSwapPreview(this.ctx.api, params);
|
|
2036
|
+
});
|
|
2037
|
+
}
|
|
2038
|
+
async getStatus(params) {
|
|
2039
|
+
return this.log.wrap("getStatus", params, async () => {
|
|
2040
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2041
|
+
return getSwapStatus(this.ctx.api, params);
|
|
2042
|
+
});
|
|
2043
|
+
}
|
|
2044
|
+
async getOutputToken(params) {
|
|
2045
|
+
return this.log.wrap("getOutputToken", params, async () => {
|
|
2046
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2047
|
+
return getSwapOutputToken(this.ctx.api, params);
|
|
2048
|
+
});
|
|
2049
|
+
}
|
|
2050
|
+
async allowWallet(params) {
|
|
2051
|
+
return this.log.wrap("allowWallet", params, async () => {
|
|
2052
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2053
|
+
return allowWallet(this.ctx.api, params);
|
|
2054
|
+
});
|
|
949
2055
|
}
|
|
950
2056
|
};
|
|
951
2057
|
|
|
952
|
-
// src/shared/api/frontline/
|
|
953
|
-
async function
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
attributes: Attributes.
|
|
963
|
-
|
|
964
|
-
|
|
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()
|
|
2058
|
+
// src/shared/api/frontline/offers.ts
|
|
2059
|
+
async function fetchOffers(api, clientCreds) {
|
|
2060
|
+
return fetchAllPages((params) => fetchOffersPage(api, params, clientCreds));
|
|
2061
|
+
}
|
|
2062
|
+
async function fetchOffersPage(api, params, clientCreds) {
|
|
2063
|
+
const queryParams = PaginationParams.toQueryParams(params);
|
|
2064
|
+
const pageDto = await api.send({
|
|
2065
|
+
method: "GET",
|
|
2066
|
+
url: "/v1/offers",
|
|
2067
|
+
queryParams,
|
|
2068
|
+
attributes: Attributes.concat(
|
|
2069
|
+
Attributes.protected(),
|
|
2070
|
+
Attributes.clientCredentials(clientCreds)
|
|
2071
|
+
)
|
|
1001
2072
|
});
|
|
1002
|
-
return
|
|
2073
|
+
return PaginatedResponse.fromDto(pageDto, Offer.fromDto);
|
|
1003
2074
|
}
|
|
1004
|
-
async function
|
|
2075
|
+
async function fetchOfferDetails(api, id, clientCreds) {
|
|
1005
2076
|
const dto = await api.send({
|
|
1006
2077
|
method: "GET",
|
|
1007
|
-
url:
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
spender: params.spender
|
|
1013
|
-
},
|
|
1014
|
-
attributes: Attributes.protected()
|
|
2078
|
+
url: `/v1/offers/${id}`,
|
|
2079
|
+
attributes: Attributes.concat(
|
|
2080
|
+
Attributes.protected(),
|
|
2081
|
+
Attributes.clientCredentials(clientCreds)
|
|
2082
|
+
)
|
|
1015
2083
|
});
|
|
1016
|
-
return
|
|
2084
|
+
return OfferDetail.fromDto(dto);
|
|
1017
2085
|
}
|
|
1018
|
-
|
|
2086
|
+
|
|
2087
|
+
// src/shared/core/offers/offers-namespace.ts
|
|
2088
|
+
var OffersNamespaceImpl = class {
|
|
2089
|
+
constructor(ctx) {
|
|
2090
|
+
this.ctx = ctx;
|
|
2091
|
+
this.log = internalLogger(ctx.logger, "OFFERS");
|
|
2092
|
+
}
|
|
2093
|
+
async list() {
|
|
2094
|
+
return this.log.wrap("list", void 0, async () => {
|
|
2095
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2096
|
+
return fetchOffers(this.ctx.api, void 0);
|
|
2097
|
+
});
|
|
2098
|
+
}
|
|
2099
|
+
async listPage(params) {
|
|
2100
|
+
return this.log.wrap("listPage", params, async () => {
|
|
2101
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2102
|
+
return fetchOffersPage(this.ctx.api, params, void 0);
|
|
2103
|
+
});
|
|
2104
|
+
}
|
|
2105
|
+
async get(id) {
|
|
2106
|
+
return this.log.wrap("get", id, async () => {
|
|
2107
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2108
|
+
return fetchOfferDetails(this.ctx.api, id, void 0);
|
|
2109
|
+
});
|
|
2110
|
+
}
|
|
2111
|
+
};
|
|
2112
|
+
|
|
2113
|
+
// src/shared/types/document-submission.ts
|
|
2114
|
+
var DocumentSubmission = {
|
|
2115
|
+
fromDto: (dto) => ({
|
|
2116
|
+
status: dto.status,
|
|
2117
|
+
formType: dto.form_type
|
|
2118
|
+
})
|
|
2119
|
+
};
|
|
2120
|
+
|
|
2121
|
+
// src/shared/api/frontline/documents.ts
|
|
2122
|
+
async function submitDocument(api, documentType, fields) {
|
|
1019
2123
|
const dto = await api.send({
|
|
1020
|
-
method: "
|
|
1021
|
-
url:
|
|
1022
|
-
|
|
1023
|
-
chain: params.chain,
|
|
1024
|
-
token_address: params.tokenAddress,
|
|
1025
|
-
owner: params.owner
|
|
1026
|
-
},
|
|
2124
|
+
method: "POST",
|
|
2125
|
+
url: `/v1/documents/${documentType}/submission`,
|
|
2126
|
+
body: fields,
|
|
1027
2127
|
attributes: Attributes.protected()
|
|
1028
2128
|
});
|
|
1029
|
-
return
|
|
2129
|
+
return DocumentSubmission.fromDto(dto);
|
|
1030
2130
|
}
|
|
1031
|
-
|
|
2131
|
+
|
|
2132
|
+
// src/shared/types/kyc.ts
|
|
2133
|
+
var KycToken = {
|
|
2134
|
+
fromDto: (dto) => ({
|
|
2135
|
+
token: dto.token
|
|
2136
|
+
})
|
|
2137
|
+
};
|
|
2138
|
+
|
|
2139
|
+
// src/shared/api/frontline/kyc.ts
|
|
2140
|
+
async function createKycToken(api, levelName, reset) {
|
|
1032
2141
|
const dto = await api.send({
|
|
1033
2142
|
method: "POST",
|
|
1034
|
-
url:
|
|
2143
|
+
url: "/v1/kyc-token",
|
|
1035
2144
|
body: {
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
signature: params.signature
|
|
2145
|
+
...levelName === void 0 ? {} : { level_name: levelName },
|
|
2146
|
+
...reset === void 0 ? {} : { reset }
|
|
1039
2147
|
},
|
|
1040
2148
|
attributes: Attributes.protected()
|
|
1041
2149
|
});
|
|
1042
|
-
return
|
|
1043
|
-
}
|
|
1044
|
-
function toErc20Asset(dto) {
|
|
1045
|
-
return {
|
|
1046
|
-
name: dto.name,
|
|
1047
|
-
symbol: AssetSymbol(dto.symbol),
|
|
1048
|
-
decimals: AssetDecimals(dto.decimals)
|
|
1049
|
-
};
|
|
2150
|
+
return KycToken.fromDto(dto);
|
|
1050
2151
|
}
|
|
1051
2152
|
|
|
1052
|
-
// src/shared/
|
|
1053
|
-
var
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
return getTokenAllowance(this.ctx.api, params);
|
|
1060
|
-
}
|
|
1061
|
-
async getTokenBalance(params) {
|
|
1062
|
-
await this.ctx.ensureUserAuthenticated();
|
|
1063
|
-
return getTokenBalance(this.ctx.api, params);
|
|
1064
|
-
}
|
|
2153
|
+
// src/shared/types/pii.ts
|
|
2154
|
+
var Iso2CountryCode = (value) => value;
|
|
2155
|
+
var PiiJurisdiction = {
|
|
2156
|
+
fromDto: (dto) => ({
|
|
2157
|
+
iso2: Iso2CountryCode(dto.iso_2),
|
|
2158
|
+
name: dto.name
|
|
2159
|
+
})
|
|
1065
2160
|
};
|
|
1066
|
-
|
|
1067
|
-
// src/shared/types/asset.ts
|
|
1068
|
-
var AssetId = (value) => value;
|
|
1069
|
-
var AssetCode = (value) => value;
|
|
1070
|
-
var Asset = {
|
|
2161
|
+
var PiiAddress = {
|
|
1071
2162
|
fromDto: (dto) => ({
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
2163
|
+
street: dto.street,
|
|
2164
|
+
city: dto.city,
|
|
2165
|
+
state: dto.state,
|
|
2166
|
+
postalCode: dto.postal_code,
|
|
2167
|
+
country: dto.country
|
|
2168
|
+
})
|
|
2169
|
+
};
|
|
2170
|
+
var Pii = {
|
|
2171
|
+
fromDto: (dto) => ({
|
|
2172
|
+
kind: dto.kind,
|
|
2173
|
+
fullLegalName: dto.full_legal_name,
|
|
2174
|
+
dateOfBirth: dto.date_of_birth,
|
|
2175
|
+
jurisdiction: dto.jurisdiction ? PiiJurisdiction.fromDto(dto.jurisdiction) : null,
|
|
2176
|
+
taxId: dto.tax_id,
|
|
2177
|
+
permanentAddress: PiiAddress.fromDto(dto.permanent_address)
|
|
1076
2178
|
})
|
|
1077
2179
|
};
|
|
1078
2180
|
|
|
1079
|
-
// src/shared/
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
2181
|
+
// src/shared/api/frontline/pii.ts
|
|
2182
|
+
async function fetchPii(api) {
|
|
2183
|
+
const dto = await api.send({
|
|
2184
|
+
method: "GET",
|
|
2185
|
+
url: "/v1/pii",
|
|
2186
|
+
attributes: Attributes.protected()
|
|
2187
|
+
});
|
|
2188
|
+
return Pii.fromDto(dto);
|
|
2189
|
+
}
|
|
2190
|
+
|
|
2191
|
+
// src/shared/types/requirement.ts
|
|
2192
|
+
var RequirementId = (value) => value;
|
|
2193
|
+
var Requirement = {
|
|
1083
2194
|
fromDto: (dto) => ({
|
|
1084
|
-
id:
|
|
1085
|
-
slug: OfferSlug(dto.slug),
|
|
2195
|
+
id: RequirementId(dto.id),
|
|
1086
2196
|
type: dto.type,
|
|
1087
|
-
|
|
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
|
|
2197
|
+
details: dto.details
|
|
1092
2198
|
})
|
|
1093
2199
|
};
|
|
2200
|
+
var RequirementStatusInfo = {
|
|
2201
|
+
fromStatusesDto: (dto) => Object.entries(dto.statuses).map(
|
|
2202
|
+
([id, value]) => typeof value === "string" ? { id: RequirementId(id), status: value, action: null } : {
|
|
2203
|
+
id: RequirementId(id),
|
|
2204
|
+
status: value.status,
|
|
2205
|
+
action: value.action ?? null,
|
|
2206
|
+
kycLevel: value.kyc_level,
|
|
2207
|
+
kycReset: value.kyc_reset
|
|
2208
|
+
}
|
|
2209
|
+
)
|
|
2210
|
+
};
|
|
1094
2211
|
|
|
1095
|
-
// src/shared/
|
|
1096
|
-
async function
|
|
1097
|
-
const
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
2212
|
+
// src/shared/api/frontline/requirements.ts
|
|
2213
|
+
async function fetchOfferRequirements(api, offerId, clientCreds) {
|
|
2214
|
+
const response = await api.send({
|
|
2215
|
+
method: "GET",
|
|
2216
|
+
url: `/v1/offers/${offerId}/requirements`,
|
|
2217
|
+
attributes: Attributes.concat(
|
|
2218
|
+
Attributes.protected(),
|
|
2219
|
+
Attributes.clientCredentials(clientCreds)
|
|
2220
|
+
)
|
|
2221
|
+
});
|
|
2222
|
+
return Object.fromEntries(
|
|
2223
|
+
Object.entries(response.options).map(([optionId, list]) => [
|
|
2224
|
+
optionId,
|
|
2225
|
+
list.data.map(Requirement.fromDto)
|
|
2226
|
+
])
|
|
1101
2227
|
);
|
|
1102
|
-
return crypto.subtle.digest("SHA-256", buffer);
|
|
1103
2228
|
}
|
|
1104
|
-
function
|
|
1105
|
-
const
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
2229
|
+
async function fetchRequirementStatuses(api, offerId) {
|
|
2230
|
+
const response = await api.send({
|
|
2231
|
+
method: "GET",
|
|
2232
|
+
url: `/v1/offers/${offerId}/requirements/statuses`,
|
|
2233
|
+
attributes: Attributes.protected()
|
|
2234
|
+
});
|
|
2235
|
+
return RequirementStatusInfo.fromStatusesDto(response);
|
|
2236
|
+
}
|
|
2237
|
+
|
|
2238
|
+
// src/shared/core/requirements/requirements-namespace.ts
|
|
2239
|
+
var RequirementsNamespaceImpl = class {
|
|
2240
|
+
constructor(ctx) {
|
|
2241
|
+
this.ctx = ctx;
|
|
2242
|
+
this.log = internalLogger(ctx.logger, "REQUIREMENTS");
|
|
1109
2243
|
}
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
2244
|
+
async forOffer(offerId) {
|
|
2245
|
+
return this.log.wrap("forOffer", offerId, async () => {
|
|
2246
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2247
|
+
return fetchOfferRequirements(
|
|
2248
|
+
this.ctx.api,
|
|
2249
|
+
offerId,
|
|
2250
|
+
void 0
|
|
2251
|
+
);
|
|
2252
|
+
});
|
|
1114
2253
|
}
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
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;
|
|
2254
|
+
async statuses(offerId) {
|
|
2255
|
+
return this.log.wrap("statuses", offerId, async () => {
|
|
2256
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2257
|
+
return fetchRequirementStatuses(this.ctx.api, offerId);
|
|
2258
|
+
});
|
|
1128
2259
|
}
|
|
1129
|
-
|
|
2260
|
+
async createKycToken(params) {
|
|
2261
|
+
return this.log.wrap("createKycToken", params, async () => {
|
|
2262
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2263
|
+
return createKycToken(
|
|
2264
|
+
this.ctx.api,
|
|
2265
|
+
params?.levelName,
|
|
2266
|
+
params?.reset
|
|
2267
|
+
);
|
|
2268
|
+
});
|
|
2269
|
+
}
|
|
2270
|
+
async getPii() {
|
|
2271
|
+
return this.log.wrap("getPii", void 0, async () => {
|
|
2272
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2273
|
+
return fetchPii(this.ctx.api);
|
|
2274
|
+
});
|
|
2275
|
+
}
|
|
2276
|
+
async submitDocument(params) {
|
|
2277
|
+
return this.log.wrap("submitDocument", params, async () => {
|
|
2278
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2279
|
+
return submitDocument(
|
|
2280
|
+
this.ctx.api,
|
|
2281
|
+
params.documentType,
|
|
2282
|
+
params.fields
|
|
2283
|
+
);
|
|
2284
|
+
});
|
|
2285
|
+
}
|
|
2286
|
+
};
|
|
1130
2287
|
|
|
1131
|
-
// src/shared/
|
|
1132
|
-
var
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
2288
|
+
// src/shared/api/nabu/tokens.ts
|
|
2289
|
+
var import_viem4 = require("viem");
|
|
2290
|
+
|
|
2291
|
+
// src/shared/api/frontline/config.ts
|
|
2292
|
+
var HEADER_API_VERSION = "X-API-Version";
|
|
2293
|
+
|
|
2294
|
+
// src/shared/api/http-client.ts
|
|
2295
|
+
var HttpClient = class {
|
|
2296
|
+
constructor(config, middleware = {}, logger = null, options = {}) {
|
|
2297
|
+
this.config = config;
|
|
2298
|
+
this.middleware = middleware;
|
|
2299
|
+
this.log = internalLogger(logger, "HTTP");
|
|
2300
|
+
this.makeRequestId = options.makeRequestId ?? defaultMakeRequestId;
|
|
2301
|
+
}
|
|
2302
|
+
async send(request) {
|
|
2303
|
+
return this.runRequestWithAfterMiddleware(request);
|
|
2304
|
+
}
|
|
2305
|
+
/**
|
|
2306
|
+
* Runs beforeRequest, executeRequest, then the full afterRequest middleware
|
|
2307
|
+
* chain. Used by send() and by the retry() callback so that when a
|
|
2308
|
+
* middleware calls retry(), the retried response also goes through all
|
|
2309
|
+
* afterRequest middleware (e.g. session renewal, retry). Middleware
|
|
2310
|
+
* must use request.attributes.retryAttempt (or similar) to avoid infinite
|
|
2311
|
+
* recursion when they trigger retries.
|
|
2312
|
+
*/
|
|
2313
|
+
async runRequestWithAfterMiddleware(request) {
|
|
2314
|
+
const preparedRequest = await this.runBeforeRequestMiddleware(
|
|
2315
|
+
this.withClientDefaults(request)
|
|
2316
|
+
);
|
|
2317
|
+
let response = await this.executeRequest(preparedRequest);
|
|
2318
|
+
for (const middleware of this.middleware.afterRequest ?? []) {
|
|
2319
|
+
response = await middleware({
|
|
2320
|
+
request: preparedRequest,
|
|
2321
|
+
response,
|
|
2322
|
+
retry: (nextRequest = preparedRequest) => this.runRequestWithAfterMiddleware(nextRequest)
|
|
2323
|
+
});
|
|
1144
2324
|
}
|
|
1145
|
-
|
|
1146
|
-
|
|
2325
|
+
return response;
|
|
2326
|
+
}
|
|
2327
|
+
withClientDefaults(request) {
|
|
2328
|
+
const url = this.resolveUrl(request.url);
|
|
2329
|
+
const headers = {
|
|
2330
|
+
...request.headers ?? {},
|
|
2331
|
+
...this.config.xApiVersion !== void 0 ? { [HEADER_API_VERSION]: this.config.xApiVersion } : {}
|
|
2332
|
+
};
|
|
2333
|
+
return {
|
|
2334
|
+
...request,
|
|
2335
|
+
url,
|
|
2336
|
+
headers,
|
|
2337
|
+
// Only when absent: a retry or a post-renewal re-send arrives with the
|
|
2338
|
+
// first attempt's id already on it, and keeping it is the whole point.
|
|
2339
|
+
attributes: Attributes.getRequestId(request.attributes) === null ? Attributes.concat(
|
|
2340
|
+
request.attributes ?? Attributes.empty,
|
|
2341
|
+
Attributes.requestId(this.makeRequestId())
|
|
2342
|
+
) : request.attributes
|
|
2343
|
+
};
|
|
2344
|
+
}
|
|
2345
|
+
/**
|
|
2346
|
+
* Resolves a request URL against the client's baseUrl.
|
|
2347
|
+
*
|
|
2348
|
+
* @internal Public only for testing. Do not use in application code; use
|
|
2349
|
+
* {@link HttpClient.send} with a path and the client will resolve the URL.
|
|
2350
|
+
*/
|
|
2351
|
+
resolveUrl(url) {
|
|
2352
|
+
if (url.startsWith("http://") || url.startsWith("https://")) {
|
|
2353
|
+
return url;
|
|
1147
2354
|
}
|
|
1148
|
-
|
|
1149
|
-
|
|
2355
|
+
const base = this.config.baseUrl.replace(/\/$/, "");
|
|
2356
|
+
const path = url.startsWith("/") ? url : `/${url}`;
|
|
2357
|
+
return base + path;
|
|
2358
|
+
}
|
|
2359
|
+
async runBeforeRequestMiddleware(initialRequest) {
|
|
2360
|
+
let request = initialRequest;
|
|
2361
|
+
for (const middleware of this.middleware.beforeRequest ?? []) {
|
|
2362
|
+
request = await middleware(request);
|
|
1150
2363
|
}
|
|
1151
|
-
|
|
1152
|
-
|
|
2364
|
+
return request;
|
|
2365
|
+
}
|
|
2366
|
+
/**
|
|
2367
|
+
* One physical attempt, logged as one line.
|
|
2368
|
+
*
|
|
2369
|
+
* A non-2xx is a `warn` rather than an `error` because the wire does not
|
|
2370
|
+
* know whether it is a failure: the retry middleware may turn a 503 into a
|
|
2371
|
+
* success, and the token registry reads a 404 as "not listed". The namespace
|
|
2372
|
+
* above decides, and logs the `error` when it does.
|
|
2373
|
+
*/
|
|
2374
|
+
async executeRequest(request) {
|
|
2375
|
+
const requestId2 = Attributes.getRequestId(request.attributes);
|
|
2376
|
+
const log = requestId2 === null ? this.log : this.log.child({ requestId: requestId2 });
|
|
2377
|
+
const attempt = Attributes.getRetryAttempt(request.attributes) + 1;
|
|
2378
|
+
const startedAt = Date.now();
|
|
2379
|
+
log.debug(() => ({
|
|
2380
|
+
msg: "request sent",
|
|
2381
|
+
fields: describeRequestUnredacted(request)
|
|
2382
|
+
}));
|
|
2383
|
+
try {
|
|
2384
|
+
const response = await makeRequest(request);
|
|
2385
|
+
const elapsed = Date.now() - startedAt;
|
|
2386
|
+
const outcome = () => ({
|
|
2387
|
+
msg: "request completed",
|
|
2388
|
+
fields: {
|
|
2389
|
+
...identifyRequest(request),
|
|
2390
|
+
"http.response.status_code": response.status,
|
|
2391
|
+
duration_ms: elapsed,
|
|
2392
|
+
attempt
|
|
2393
|
+
}
|
|
2394
|
+
});
|
|
2395
|
+
if (response.status >= 200 && response.status < 300) {
|
|
2396
|
+
log.info(outcome);
|
|
2397
|
+
} else {
|
|
2398
|
+
log.warn(outcome);
|
|
2399
|
+
}
|
|
2400
|
+
log.debug(() => ({
|
|
2401
|
+
msg: "response received",
|
|
2402
|
+
fields: { body: response.body }
|
|
2403
|
+
}));
|
|
2404
|
+
return requestId2 === null ? response : { ...response, requestId: requestId2 };
|
|
2405
|
+
} catch (error) {
|
|
2406
|
+
const elapsed = Date.now() - startedAt;
|
|
2407
|
+
log.warning(
|
|
2408
|
+
() => ({
|
|
2409
|
+
msg: "request threw",
|
|
2410
|
+
fields: {
|
|
2411
|
+
...identifyRequest(request),
|
|
2412
|
+
duration_ms: elapsed,
|
|
2413
|
+
attempt
|
|
2414
|
+
}
|
|
2415
|
+
}),
|
|
2416
|
+
error
|
|
2417
|
+
);
|
|
2418
|
+
throw error;
|
|
1153
2419
|
}
|
|
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
2420
|
}
|
|
1175
2421
|
};
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
};
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
2422
|
+
function identifyRequest(request) {
|
|
2423
|
+
const { host, path } = splitUrl(request.url);
|
|
2424
|
+
return {
|
|
2425
|
+
"http.request.method": request.method,
|
|
2426
|
+
"server.address": host,
|
|
2427
|
+
"url.path": path
|
|
2428
|
+
};
|
|
2429
|
+
}
|
|
2430
|
+
function splitUrl(url) {
|
|
2431
|
+
try {
|
|
2432
|
+
const parsed = new URL(url);
|
|
2433
|
+
return { host: parsed.host, path: parsed.pathname };
|
|
2434
|
+
} catch (_) {
|
|
2435
|
+
return { host: null, path: url };
|
|
2436
|
+
}
|
|
2437
|
+
}
|
|
2438
|
+
function defaultMakeRequestId() {
|
|
2439
|
+
return Math.random().toString(36).slice(2, 10).padEnd(8, "0");
|
|
2440
|
+
}
|
|
2441
|
+
function describeRequestUnredacted(request) {
|
|
2442
|
+
return {
|
|
2443
|
+
"http.request.method": request.method,
|
|
2444
|
+
"url.full": buildUrlWithQueryParams(request.url, request.queryParams),
|
|
2445
|
+
headers: request.headers,
|
|
2446
|
+
...request.method === "POST" ? { body: request.body } : {}
|
|
2447
|
+
};
|
|
2448
|
+
}
|
|
2449
|
+
|
|
2450
|
+
// src/shared/types/token-metadata.ts
|
|
2451
|
+
var TokenLogoUrl = (value) => value;
|
|
2452
|
+
var TokenLogo = {
|
|
2453
|
+
/** `baseUrl` is the registry origin; registry URLs are root-relative. */
|
|
2454
|
+
fromDto: (dto, baseUrl) => dto.kind === "VECTOR" ? { kind: "VECTOR", url: resolveLogoUrl(dto.url, baseUrl) } : {
|
|
2455
|
+
kind: "RASTER",
|
|
2456
|
+
original: logoImageFromDto(dto.original, baseUrl),
|
|
2457
|
+
variants: dto.variants.map((v) => logoImageFromDto(v, baseUrl))
|
|
2458
|
+
}
|
|
1199
2459
|
};
|
|
1200
|
-
var
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
2460
|
+
var TokenMetadata = {
|
|
2461
|
+
/** `baseUrl` is the registry origin; registry logo URLs are root-relative. */
|
|
2462
|
+
fromDto: (dto, baseUrl) => {
|
|
2463
|
+
assertSupportedSchemaVersion(dto.schema_version);
|
|
2464
|
+
return {
|
|
2465
|
+
identifier: {
|
|
2466
|
+
chain: EthereumChain(dto.chain),
|
|
2467
|
+
address: EvmContractAddress(dto.address)
|
|
2468
|
+
},
|
|
2469
|
+
name: dto.name,
|
|
2470
|
+
symbol: AssetSymbol(dto.symbol),
|
|
2471
|
+
decimals: AssetDecimals(dto.decimals),
|
|
2472
|
+
logo: TokenLogo.fromDto(dto.logo, baseUrl),
|
|
2473
|
+
logoDark: dto.logo_dark === void 0 ? null : TokenLogo.fromDto(dto.logo_dark, baseUrl)
|
|
2474
|
+
};
|
|
2475
|
+
},
|
|
2476
|
+
/**
|
|
2477
|
+
* Maps a chain snapshot to the tokens it lists, skipping the chain's native
|
|
2478
|
+
* coin (`kind: 'COIN'`, no contract address).
|
|
2479
|
+
*/
|
|
2480
|
+
fromChainAssetsDto: (dto, baseUrl) => {
|
|
2481
|
+
assertSupportedSchemaVersion(dto.schema_version);
|
|
2482
|
+
const chain = EthereumChain(dto.chain);
|
|
2483
|
+
return dto.assets.filter((asset) => asset.kind === "TOKEN" && asset.address !== void 0).map((asset) => ({
|
|
2484
|
+
identifier: {
|
|
2485
|
+
chain,
|
|
2486
|
+
// The filter above cannot narrow `address` for the type checker.
|
|
2487
|
+
address: EvmContractAddress(asset.address)
|
|
2488
|
+
},
|
|
2489
|
+
name: asset.name,
|
|
2490
|
+
symbol: AssetSymbol(asset.symbol),
|
|
2491
|
+
decimals: AssetDecimals(asset.decimals),
|
|
2492
|
+
logo: TokenLogo.fromDto(asset.logo, baseUrl),
|
|
2493
|
+
logoDark: asset.logo_dark === void 0 ? null : TokenLogo.fromDto(asset.logo_dark, baseUrl)
|
|
2494
|
+
}));
|
|
2495
|
+
}
|
|
1205
2496
|
};
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
}
|
|
2497
|
+
function assertSupportedSchemaVersion(version) {
|
|
2498
|
+
if (version !== 1) {
|
|
2499
|
+
throw new ValidationError(
|
|
2500
|
+
`Unsupported token registry schema_version: ${version}`
|
|
2501
|
+
);
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
var logoImageFromDto = (dto, baseUrl) => ({
|
|
2505
|
+
url: resolveLogoUrl(dto.url, baseUrl),
|
|
2506
|
+
width: dto.width,
|
|
2507
|
+
height: dto.height
|
|
2508
|
+
});
|
|
2509
|
+
var resolveLogoUrl = (url, baseUrl) => TokenLogoUrl(
|
|
2510
|
+
url.startsWith("http") ? url : `${baseUrl.replace(/\/$/, "")}${url}`
|
|
2511
|
+
);
|
|
2512
|
+
|
|
2513
|
+
// src/shared/api/nabu/tokens.ts
|
|
2514
|
+
function createNabuApiClient(baseUrl, logger = null) {
|
|
2515
|
+
return new HttpClient({ baseUrl }, {}, logger);
|
|
2516
|
+
}
|
|
2517
|
+
async function fetchTokenMetadata(client, token) {
|
|
2518
|
+
const address = checksummed(token.address);
|
|
2519
|
+
let response;
|
|
2520
|
+
try {
|
|
2521
|
+
response = await client.send({
|
|
2522
|
+
method: "GET",
|
|
2523
|
+
url: `/${token.chain}/token/${address}`
|
|
2524
|
+
});
|
|
2525
|
+
} catch (error) {
|
|
2526
|
+
if (isRegistryHtmlFallback(error)) {
|
|
2527
|
+
return null;
|
|
2528
|
+
}
|
|
2529
|
+
throw error;
|
|
2530
|
+
}
|
|
2531
|
+
if (response.status === 404) {
|
|
2532
|
+
return null;
|
|
2533
|
+
}
|
|
2534
|
+
assertOk(response);
|
|
2535
|
+
if (response.body === null) {
|
|
2536
|
+
throw new ValidationError(
|
|
2537
|
+
`Token registry returned an empty body for token "${address}" on "${token.chain}"`
|
|
2538
|
+
);
|
|
2539
|
+
}
|
|
2540
|
+
return TokenMetadata.fromDto(response.body, client.config.baseUrl);
|
|
2541
|
+
}
|
|
2542
|
+
async function fetchTokensMetadata(client, chain) {
|
|
2543
|
+
let response;
|
|
2544
|
+
try {
|
|
2545
|
+
response = await client.send({
|
|
2546
|
+
method: "GET",
|
|
2547
|
+
url: `/${chain}/assets.json`
|
|
2548
|
+
});
|
|
2549
|
+
} catch (error) {
|
|
2550
|
+
if (isRegistryHtmlFallback(error)) {
|
|
2551
|
+
throw new ValidationError(
|
|
2552
|
+
`Token registry returned non-JSON for the "${chain}" snapshot`
|
|
2553
|
+
);
|
|
2554
|
+
}
|
|
2555
|
+
throw error;
|
|
2556
|
+
}
|
|
2557
|
+
assertOk(response);
|
|
2558
|
+
if (response.body === null) {
|
|
2559
|
+
throw new ValidationError(
|
|
2560
|
+
`Token registry returned an empty "${chain}" snapshot`
|
|
2561
|
+
);
|
|
2562
|
+
}
|
|
2563
|
+
return TokenMetadata.fromChainAssetsDto(response.body, client.config.baseUrl);
|
|
2564
|
+
}
|
|
2565
|
+
function isRegistryHtmlFallback(error) {
|
|
2566
|
+
return error instanceof HttpError && error.response.status >= 200 && error.response.status < 300;
|
|
2567
|
+
}
|
|
2568
|
+
function assertOk(response) {
|
|
2569
|
+
if (response.status < 200 || response.status >= 300) {
|
|
2570
|
+
throw new HttpError(response);
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2573
|
+
function checksummed(address) {
|
|
2574
|
+
try {
|
|
2575
|
+
return (0, import_viem4.getAddress)(address);
|
|
2576
|
+
} catch (_) {
|
|
2577
|
+
throw new ValidationError(`Invalid EVM contract address: "${address}"`);
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2580
|
+
|
|
2581
|
+
// src/shared/core/tokens/tokens-namespace.ts
|
|
2582
|
+
var TokensNamespaceImpl = class {
|
|
2583
|
+
/**
|
|
2584
|
+
* Takes the registry origin rather than a `SharedNamespaceContext`: the
|
|
2585
|
+
* registry is unauthenticated and on its own host, so the frontline sender
|
|
2586
|
+
* and the auth check would both be dead weight here.
|
|
2587
|
+
*/
|
|
2588
|
+
constructor(baseUrl, logger = null) {
|
|
2589
|
+
this.api = createNabuApiClient(baseUrl, logger);
|
|
2590
|
+
this.log = internalLogger(logger, "TOKENS");
|
|
2591
|
+
}
|
|
2592
|
+
get(token) {
|
|
2593
|
+
return this.log.wrap(
|
|
2594
|
+
"get",
|
|
2595
|
+
token,
|
|
2596
|
+
() => fetchTokenMetadata(this.api, token)
|
|
2597
|
+
);
|
|
2598
|
+
}
|
|
2599
|
+
list(chain) {
|
|
2600
|
+
return this.log.wrap(
|
|
2601
|
+
"list",
|
|
2602
|
+
chain,
|
|
2603
|
+
() => fetchTokensMetadata(this.api, chain)
|
|
2604
|
+
);
|
|
2605
|
+
}
|
|
1212
2606
|
};
|
|
1213
2607
|
|
|
1214
2608
|
// src/shared/types/offer-option-address.ts
|
|
@@ -1282,195 +2676,79 @@ async function createWalletOwnershipChallenge(api, params) {
|
|
|
1282
2676
|
});
|
|
1283
2677
|
return WalletOwnershipChallenge.fromDto(dto);
|
|
1284
2678
|
}
|
|
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),
|
|
2679
|
+
async function connectExternalWallet(api, params) {
|
|
2680
|
+
const dto = await api.send({
|
|
2681
|
+
method: "POST",
|
|
2682
|
+
url: `/v1/offers/${params.offerId}/addresses`,
|
|
2683
|
+
body: ConnectExternalWalletParams.toDto(params),
|
|
1376
2684
|
attributes: Attributes.protected()
|
|
1377
2685
|
});
|
|
1378
|
-
return
|
|
2686
|
+
return OfferOptionAddress.fromDto(dto);
|
|
1379
2687
|
}
|
|
1380
|
-
async function
|
|
1381
|
-
const
|
|
2688
|
+
async function listOptionAddresses(api, offerId, offerOptionId) {
|
|
2689
|
+
const { data } = await api.send({
|
|
1382
2690
|
method: "GET",
|
|
1383
|
-
url: `/v1/
|
|
2691
|
+
url: `/v1/offers/${offerId}/addresses`,
|
|
2692
|
+
queryParams: { offer_option_id: offerOptionId },
|
|
1384
2693
|
attributes: Attributes.protected()
|
|
1385
2694
|
});
|
|
1386
|
-
return
|
|
2695
|
+
return data.map(OfferOptionAddress.fromDto);
|
|
1387
2696
|
}
|
|
1388
|
-
async function
|
|
2697
|
+
async function removeOptionAddress(api, offerId, addressId) {
|
|
1389
2698
|
const dto = await api.send({
|
|
1390
|
-
method: "
|
|
1391
|
-
url:
|
|
1392
|
-
body: CreateParticipationParams.toDto(params),
|
|
2699
|
+
method: "DELETE",
|
|
2700
|
+
url: `/v1/offers/${offerId}/addresses/${addressId}`,
|
|
1393
2701
|
attributes: Attributes.protected()
|
|
1394
2702
|
});
|
|
1395
|
-
return
|
|
2703
|
+
return OfferOptionAddress.fromDto(dto);
|
|
1396
2704
|
}
|
|
1397
2705
|
|
|
1398
|
-
// src/shared/core/
|
|
1399
|
-
var
|
|
2706
|
+
// src/shared/core/wallets/wallets-namespace.ts
|
|
2707
|
+
var WalletsNamespaceImpl = class {
|
|
1400
2708
|
constructor(ctx) {
|
|
1401
2709
|
this.ctx = ctx;
|
|
2710
|
+
this.log = internalLogger(ctx.logger, "WALLETS");
|
|
1402
2711
|
}
|
|
1403
|
-
async
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
async fetchParticipation(id) {
|
|
1412
|
-
await this.ctx.ensureUserAuthenticated();
|
|
1413
|
-
return fetchParticipation(this.ctx.api, id);
|
|
2712
|
+
async createOwnershipChallenge(params) {
|
|
2713
|
+
return this.log.wrap("createOwnershipChallenge", params, async () => {
|
|
2714
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2715
|
+
return createWalletOwnershipChallenge(
|
|
2716
|
+
this.ctx.api,
|
|
2717
|
+
params
|
|
2718
|
+
);
|
|
2719
|
+
});
|
|
1414
2720
|
}
|
|
1415
|
-
async
|
|
1416
|
-
|
|
1417
|
-
|
|
2721
|
+
async connectExternal(params) {
|
|
2722
|
+
return this.log.wrap("connectExternal", params, async () => {
|
|
2723
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2724
|
+
return connectExternalWallet(this.ctx.api, params);
|
|
2725
|
+
});
|
|
1418
2726
|
}
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
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";
|
|
2727
|
+
async list(params) {
|
|
2728
|
+
return this.log.wrap("list", params, async () => {
|
|
2729
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2730
|
+
return listOptionAddresses(
|
|
2731
|
+
this.ctx.api,
|
|
2732
|
+
params.offerId,
|
|
2733
|
+
params.offerOptionId
|
|
2734
|
+
);
|
|
2735
|
+
});
|
|
1460
2736
|
}
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
2737
|
+
async remove(params) {
|
|
2738
|
+
return this.log.wrap("remove", params, async () => {
|
|
2739
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2740
|
+
return removeOptionAddress(
|
|
2741
|
+
this.ctx.api,
|
|
2742
|
+
params.offerId,
|
|
2743
|
+
params.addressId
|
|
2744
|
+
);
|
|
2745
|
+
});
|
|
1466
2746
|
}
|
|
1467
2747
|
};
|
|
1468
2748
|
|
|
1469
|
-
// src/shared/types/
|
|
1470
|
-
var
|
|
1471
|
-
|
|
1472
|
-
token: dto.token
|
|
1473
|
-
})
|
|
2749
|
+
// src/shared/types/blockchain/wallet-error.ts
|
|
2750
|
+
var RedactedWalletError = {
|
|
2751
|
+
fromWalletError: (error) => error.type === "unknown" ? { type: "unknown" } : error
|
|
1474
2752
|
};
|
|
1475
2753
|
|
|
1476
2754
|
// src/shared/types/oauth-session.ts
|
|
@@ -1489,55 +2767,6 @@ var OAuthSession = {
|
|
|
1489
2767
|
}
|
|
1490
2768
|
};
|
|
1491
2769
|
|
|
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
2770
|
// src/shared/types/user.ts
|
|
1542
2771
|
var UserId = (value) => value;
|
|
1543
2772
|
var UserEmail = (value) => value;
|
|
@@ -1561,20 +2790,26 @@ var User = {
|
|
|
1561
2790
|
Blockchain,
|
|
1562
2791
|
BlockchainAmount,
|
|
1563
2792
|
Bps,
|
|
2793
|
+
Chain,
|
|
1564
2794
|
ClientCredentialsOAuth,
|
|
1565
2795
|
ClientId,
|
|
1566
2796
|
ClientSecret,
|
|
1567
2797
|
CodeChallenge,
|
|
1568
2798
|
CodeVerifier,
|
|
2799
|
+
CoinListTokenSaleNamespaceImpl,
|
|
1569
2800
|
ConnectExternalWalletParams,
|
|
1570
2801
|
CreateParticipationParams,
|
|
1571
2802
|
CreateWalletOwnershipChallengeParams,
|
|
1572
2803
|
Cursor,
|
|
1573
2804
|
DEFAULT_AMOUNT_TO_COMPUTE_PRICE,
|
|
2805
|
+
DEFAULT_ONDO_AMOUNT_TO_COMPUTE_PRICE,
|
|
1574
2806
|
DEFAULT_SLIPPAGE_BPS,
|
|
2807
|
+
DecimalString,
|
|
1575
2808
|
DocumentSubmission,
|
|
1576
2809
|
ERC20_ABI,
|
|
2810
|
+
ETHEREUM_CHAINS,
|
|
1577
2811
|
Erc20NamespaceImpl,
|
|
2812
|
+
EthereumChain,
|
|
1578
2813
|
EvmContractAddress,
|
|
1579
2814
|
EvmWalletAddress,
|
|
1580
2815
|
FaqItem,
|
|
@@ -1582,10 +2817,13 @@ var User = {
|
|
|
1582
2817
|
FormattedAmountUi,
|
|
1583
2818
|
FormattedPercentUi,
|
|
1584
2819
|
HexEncodedTransactionData,
|
|
2820
|
+
HttpError,
|
|
2821
|
+
InvariantError,
|
|
1585
2822
|
Iso2CountryCode,
|
|
1586
2823
|
KnownAssetSymbol,
|
|
1587
2824
|
KycToken,
|
|
1588
2825
|
Link,
|
|
2826
|
+
MAX_ASSET_DECIMALS,
|
|
1589
2827
|
MAX_UINT_256,
|
|
1590
2828
|
Milestone,
|
|
1591
2829
|
NA_AMOUNT_ASSET_UI,
|
|
@@ -1593,6 +2831,9 @@ var User = {
|
|
|
1593
2831
|
NotImplementedError,
|
|
1594
2832
|
OAuthRefreshToken,
|
|
1595
2833
|
OAuthSession,
|
|
2834
|
+
ONDO_POLL_INTERVAL_MS,
|
|
2835
|
+
ONDO_QUOTE_EXPIRY_THRESHOLD_MS,
|
|
2836
|
+
ONDO_SUPPORTED_INPUT_ASSETS,
|
|
1596
2837
|
Offer,
|
|
1597
2838
|
OfferDetail,
|
|
1598
2839
|
OfferId,
|
|
@@ -1602,6 +2843,12 @@ var User = {
|
|
|
1602
2843
|
OfferOptionId,
|
|
1603
2844
|
OfferOptionSlug,
|
|
1604
2845
|
OfferSlug,
|
|
2846
|
+
OfferToken,
|
|
2847
|
+
OffersNamespaceImpl,
|
|
2848
|
+
OndoNamespaceImpl,
|
|
2849
|
+
OndoQuote,
|
|
2850
|
+
OndoSwapTransaction,
|
|
2851
|
+
OndoTradingStatus,
|
|
1605
2852
|
PKCEState,
|
|
1606
2853
|
PaginatedResponse,
|
|
1607
2854
|
PaginationParams,
|
|
@@ -1611,27 +2858,37 @@ var User = {
|
|
|
1611
2858
|
Pii,
|
|
1612
2859
|
PiiAddress,
|
|
1613
2860
|
PiiJurisdiction,
|
|
2861
|
+
RedactedWalletError,
|
|
1614
2862
|
RedirectUri,
|
|
1615
2863
|
Requirement,
|
|
1616
2864
|
RequirementId,
|
|
1617
2865
|
RequirementStatusInfo,
|
|
2866
|
+
RequirementsNamespaceImpl,
|
|
1618
2867
|
SLIPPAGE_OPTIONS_BPS,
|
|
2868
|
+
SOLANA_CHAINS,
|
|
2869
|
+
STABLE_DECIMALS,
|
|
2870
|
+
SUPERSTATE_ISSUER_NAME,
|
|
2871
|
+
SUPERSTATE_SUPPORTED_INPUT_ASSETS,
|
|
1619
2872
|
SUPERSTATE_SWAP_ABI,
|
|
1620
2873
|
SUPERSTATE_SWAP_CONTRACT_ADDRESS_SEPOLIA,
|
|
1621
|
-
SUPERSTATE_TOS_URL,
|
|
1622
2874
|
SWAP_POLL_INTERVAL_MS,
|
|
1623
2875
|
ShortenedWalletAddress,
|
|
2876
|
+
SolanaChain,
|
|
1624
2877
|
StablecoinSymbol,
|
|
2878
|
+
SuperstateSwapNamespaceImpl,
|
|
1625
2879
|
SwapAuthorization,
|
|
1626
|
-
SwapNamespaceImpl,
|
|
1627
2880
|
SwapPreview,
|
|
1628
2881
|
SwapQuote,
|
|
1629
2882
|
SwapStatus,
|
|
1630
2883
|
TOKEN_REGISTRY,
|
|
1631
2884
|
TermItem,
|
|
2885
|
+
Ticker,
|
|
1632
2886
|
TokenAllowance,
|
|
1633
2887
|
TokenBalance,
|
|
1634
|
-
|
|
2888
|
+
TokenLogo,
|
|
2889
|
+
TokenLogoUrl,
|
|
2890
|
+
TokenMetadata,
|
|
2891
|
+
TokensNamespaceImpl,
|
|
1635
2892
|
TxExplorerUrl,
|
|
1636
2893
|
USDC,
|
|
1637
2894
|
USDC_SYMBOL,
|
|
@@ -1640,11 +2897,17 @@ var User = {
|
|
|
1640
2897
|
User,
|
|
1641
2898
|
UserEmail,
|
|
1642
2899
|
UserId,
|
|
2900
|
+
ValidationError,
|
|
1643
2901
|
WalletAddress,
|
|
1644
2902
|
WalletOwnershipChallenge,
|
|
2903
|
+
WalletsNamespaceImpl,
|
|
2904
|
+
apiErrorCode,
|
|
1645
2905
|
applyBps,
|
|
1646
2906
|
assertUint256,
|
|
1647
2907
|
assetAmount,
|
|
2908
|
+
blockchainAmountFromRawOrThrow,
|
|
2909
|
+
chainFromId,
|
|
2910
|
+
computeOndoPrice,
|
|
1648
2911
|
computePrice,
|
|
1649
2912
|
computeSlip,
|
|
1650
2913
|
decodeSwappedOutputAmount,
|
|
@@ -1659,8 +2922,11 @@ var User = {
|
|
|
1659
2922
|
getChainId,
|
|
1660
2923
|
getNetworkName,
|
|
1661
2924
|
isStopped,
|
|
2925
|
+
ondoSwapContractAddress,
|
|
1662
2926
|
parseBlockchainAmount,
|
|
2927
|
+
parseUint256,
|
|
1663
2928
|
shortenAddress,
|
|
2929
|
+
superstateSwapContractAddress,
|
|
1664
2930
|
txExplorerUrl,
|
|
1665
2931
|
usdAmount
|
|
1666
2932
|
});
|