@sky-mavis/ronin-dex 0.0.1

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/dist/index.mjs ADDED
@@ -0,0 +1,4835 @@
1
+ // src/internals/types/blockchain.ts
2
+ var Blockchain = /* @__PURE__ */ ((Blockchain2) => {
3
+ Blockchain2["EVM"] = "evm";
4
+ Blockchain2["SOLANA"] = "solana";
5
+ return Blockchain2;
6
+ })(Blockchain || {});
7
+ var EVMChainId = /* @__PURE__ */ ((EVMChainId2) => {
8
+ EVMChainId2[EVMChainId2["ETHEREUM"] = 1] = "ETHEREUM";
9
+ EVMChainId2[EVMChainId2["BSC"] = 56] = "BSC";
10
+ EVMChainId2[EVMChainId2["POLYGON"] = 137] = "POLYGON";
11
+ EVMChainId2[EVMChainId2["RONIN"] = 2020] = "RONIN";
12
+ EVMChainId2[EVMChainId2["ARBITRUM"] = 42161] = "ARBITRUM";
13
+ EVMChainId2[EVMChainId2["BASE"] = 8453] = "BASE";
14
+ EVMChainId2[EVMChainId2["GOERLI"] = 5] = "GOERLI";
15
+ EVMChainId2[EVMChainId2["SEPOLIA"] = 11155111] = "SEPOLIA";
16
+ EVMChainId2[EVMChainId2["SAIGON"] = 2021] = "SAIGON";
17
+ EVMChainId2[EVMChainId2["MUMBAI"] = 80001] = "MUMBAI";
18
+ EVMChainId2[EVMChainId2["BSC_TESTNET"] = 97] = "BSC_TESTNET";
19
+ EVMChainId2[EVMChainId2["BASE_SEPOLIA"] = 84532] = "BASE_SEPOLIA";
20
+ return EVMChainId2;
21
+ })(EVMChainId || {});
22
+ var NATIVE_ADDRESS = "0x0000000000000000000000000000000000000000";
23
+ var WalletType = /* @__PURE__ */ ((WalletType2) => {
24
+ WalletType2["SEED_PHRASE"] = "SEED_PHRASE";
25
+ WalletType2["PRIVATE_KEY"] = "PRIVATE_KEY";
26
+ WalletType2["TREZOR"] = "TREZOR";
27
+ WalletType2["LEDGER"] = "LEDGER";
28
+ WalletType2["MPC"] = "MPC";
29
+ WalletType2["ADDRESS"] = "ADDRESS";
30
+ WalletType2["OTHER"] = "OTHER";
31
+ return WalletType2;
32
+ })(WalletType || {});
33
+
34
+ // src/internals/utils/chain.ts
35
+ import BigNumber from "bignumber.js";
36
+ var chainIdToNumber = (chainId) => {
37
+ return new BigNumber(chainId.toString()).toNumber();
38
+ };
39
+
40
+ // src/internals/utils/signature-id.ts
41
+ var SEPARATOR = "_";
42
+ function createSignatureId(rpcUrl, tokenAddress) {
43
+ return `${rpcUrl}${SEPARATOR}${tokenAddress}`;
44
+ }
45
+ function parseSignatureId(sigil) {
46
+ const separatorIndex = sigil.indexOf(SEPARATOR);
47
+ if (separatorIndex === -1) {
48
+ throw new Error("Invalid sigil format");
49
+ }
50
+ const rpcUrl = sigil.substring(0, separatorIndex);
51
+ const tokenAddress = sigil.substring(separatorIndex + 1);
52
+ return [rpcUrl, tokenAddress];
53
+ }
54
+
55
+ // src/internals/lib/event-emitter/TypedEventEmitter.ts
56
+ var TypedEventEmitter = class {
57
+ events = {};
58
+ maxListeners = Infinity;
59
+ emit = (event, ...args) => {
60
+ if (this.events[event]) {
61
+ const len = this.events[event].length;
62
+ const events = Array.from(this.events[event]);
63
+ for (const e of events) {
64
+ e(...args);
65
+ }
66
+ return !!len;
67
+ }
68
+ return false;
69
+ };
70
+ on = (event, listener) => {
71
+ this.addListener(event, listener);
72
+ return this;
73
+ };
74
+ once = (event, listener) => {
75
+ const onceListener = ((...args) => {
76
+ listener(...args);
77
+ this.removeListener(event, onceListener);
78
+ });
79
+ this.addListener(event, onceListener);
80
+ return this;
81
+ };
82
+ addListener = (event, listener) => {
83
+ if (!(event in this.events)) {
84
+ this.events[event] = [listener];
85
+ } else {
86
+ this.events[event].push(listener);
87
+ }
88
+ if (this.maxListeners !== Infinity && this.maxListeners <= this.events[event].length) {
89
+ console.warn(`Maximum event listeners for "${String(event)}" event!`);
90
+ }
91
+ return this;
92
+ };
93
+ removeListener = (event, listener) => {
94
+ if (event in this.events) {
95
+ const i = this.events[event].indexOf(listener);
96
+ if (i !== -1) {
97
+ this.events[event].splice(i, 1);
98
+ }
99
+ }
100
+ return this;
101
+ };
102
+ hasListeners = (event) => {
103
+ return this.events[event] && !!this.events[event].length;
104
+ };
105
+ prependListener = (event, listener) => {
106
+ if (!(event in this.events)) {
107
+ this.events[event] = [listener];
108
+ } else {
109
+ this.events[event].unshift(listener);
110
+ }
111
+ return this;
112
+ };
113
+ prependOnceListener = (event, listener) => {
114
+ const onceListener = ((...args) => {
115
+ listener(...args);
116
+ this.removeListener(event, onceListener);
117
+ });
118
+ this.prependListener(event, onceListener);
119
+ return this;
120
+ };
121
+ off = (event, listener) => {
122
+ return this.removeListener(event, listener);
123
+ };
124
+ removeAllListeners = (event) => {
125
+ delete this.events[event];
126
+ return this;
127
+ };
128
+ setMaxListeners = (n) => {
129
+ this.maxListeners = n;
130
+ return this;
131
+ };
132
+ getMaxListeners = () => {
133
+ return this.maxListeners;
134
+ };
135
+ listeners = (event) => {
136
+ return [...this.events[event]];
137
+ };
138
+ rawListeners = (event) => {
139
+ return this.events[event];
140
+ };
141
+ eventNames = () => {
142
+ return Object.keys(this.events);
143
+ };
144
+ listenerCount = (type) => {
145
+ return this.events[type] && this.events[type].length || 0;
146
+ };
147
+ };
148
+
149
+ // src/internals/utils/zod.ts
150
+ function $safeArray(data, schema, options) {
151
+ try {
152
+ if (!Array.isArray(data)) {
153
+ return [];
154
+ }
155
+ return data.reduce((accumulator, item) => {
156
+ const parsed = schema.safeParse({ ...item, ...options?.modifier?.(item) });
157
+ if (!parsed.success && options?.debug) {
158
+ const message = options?.schemaName ? `[${options.schemaName}] parsing error: ` : "parsing error: ";
159
+ console.error(message, {
160
+ errorData: item,
161
+ error: parsed.error
162
+ });
163
+ return accumulator;
164
+ }
165
+ return accumulator.concat(parsed.data);
166
+ }, []);
167
+ } catch (error) {
168
+ options?.debug && console.error("$safeArray", error);
169
+ return [];
170
+ }
171
+ }
172
+
173
+ // src/internals/utils/fetch-mate/FetchMateResponse.ts
174
+ var FetchMateResponse = class _FetchMateResponse {
175
+ result;
176
+ constructor(result) {
177
+ this.result = result;
178
+ }
179
+ static success(data) {
180
+ return new _FetchMateResponse({ success: true, data });
181
+ }
182
+ static error(error) {
183
+ let errorInstance;
184
+ if (error instanceof Error) {
185
+ errorInstance = error;
186
+ } else if (typeof error === "string") {
187
+ errorInstance = new Error(error);
188
+ } else {
189
+ try {
190
+ const stringified = JSON.stringify(error);
191
+ errorInstance = new Error(stringified);
192
+ } catch {
193
+ errorInstance = new Error("An error occurred");
194
+ }
195
+ }
196
+ return new _FetchMateResponse({ success: false, error: errorInstance });
197
+ }
198
+ get data() {
199
+ return this.result.success ? this.result.data : void 0;
200
+ }
201
+ get error() {
202
+ return this.result.success ? void 0 : this.result.error;
203
+ }
204
+ isSuccess() {
205
+ return this.result.success;
206
+ }
207
+ isError() {
208
+ return !this.result.success;
209
+ }
210
+ unwrap() {
211
+ if (this.result.success) {
212
+ return this.result.data;
213
+ } else {
214
+ throw new Error(
215
+ "Called unwrap on an error result: " + String(this.result.error)
216
+ );
217
+ }
218
+ }
219
+ unwrapOr(defaultValue) {
220
+ return this.result.success ? this.result.data : defaultValue;
221
+ }
222
+ unwrapOrElse(fn) {
223
+ return this.result.success ? this.result.data : fn(this.result.error);
224
+ }
225
+ map(fn) {
226
+ if (this.result.success) {
227
+ return _FetchMateResponse.success(fn(this.result.data));
228
+ } else {
229
+ return _FetchMateResponse.error(
230
+ this.result.error
231
+ );
232
+ }
233
+ }
234
+ flatMap(fn) {
235
+ if (this.result.success) {
236
+ return fn(this.result.data);
237
+ } else {
238
+ return _FetchMateResponse.error(
239
+ this.result.error
240
+ );
241
+ }
242
+ }
243
+ };
244
+ var FetchMateResponse_default = FetchMateResponse;
245
+
246
+ // src/internals/utils/fetch-mate/FetchMate.ts
247
+ var FetchMate = class _FetchMate {
248
+ config;
249
+ constructor(config = {}) {
250
+ this.config = {
251
+ headers: { "Content-Type": "application/json" },
252
+ timeout: 3e4,
253
+ ...config
254
+ };
255
+ }
256
+ static create(config) {
257
+ return new _FetchMate(config);
258
+ }
259
+ buildUrl(url, params) {
260
+ const baseURL = this.config.baseUrl || "";
261
+ if (!url.startsWith("http")) url = `${baseURL}${url}`;
262
+ if (!params) return url;
263
+ const searchParams = new URLSearchParams();
264
+ Object.entries(params).forEach(([key, value]) => {
265
+ searchParams.append(key, String(value));
266
+ });
267
+ return `${url}${url.includes("?") ? "&" : "?"}${searchParams.toString()}`;
268
+ }
269
+ async request(method, url, body, options = {}) {
270
+ try {
271
+ const {
272
+ timeout = this.config.timeout,
273
+ params,
274
+ ...requestOptions
275
+ } = options;
276
+ const fullURL = this.buildUrl(url, params);
277
+ const requestInit = {
278
+ method,
279
+ headers: {
280
+ ...this.config.headers,
281
+ ...requestOptions.headers
282
+ },
283
+ credentials: this.config.credentials,
284
+ ...requestOptions
285
+ };
286
+ if (body !== void 0) {
287
+ if (typeof body === "object" && !(body instanceof FormData)) {
288
+ requestInit.body = JSON.stringify(body);
289
+ } else {
290
+ requestInit.body = body;
291
+ }
292
+ }
293
+ const controller = new AbortController();
294
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
295
+ try {
296
+ const response = await fetch(fullURL, {
297
+ ...requestInit,
298
+ signal: controller.signal
299
+ });
300
+ clearTimeout(timeoutId);
301
+ return FetchMateResponse_default.success(response);
302
+ } catch (error) {
303
+ clearTimeout(timeoutId);
304
+ if (error instanceof Error && error.name === "AbortError") {
305
+ return FetchMateResponse_default.error(
306
+ new Error(`Request timeout after ${timeout}ms`)
307
+ );
308
+ }
309
+ return FetchMateResponse_default.error(error);
310
+ }
311
+ } catch (error) {
312
+ return FetchMateResponse_default.error(error);
313
+ }
314
+ }
315
+ async requestJson(method, url, body, options = {}) {
316
+ const responseResult = await this.request(method, url, body, options);
317
+ if (responseResult.isError()) {
318
+ return responseResult;
319
+ }
320
+ const response = responseResult.unwrap();
321
+ if (!response.ok) {
322
+ return FetchMateResponse_default.error(
323
+ new Error(`HTTP ${response.status}: ${response.statusText}`)
324
+ );
325
+ }
326
+ try {
327
+ const data = await response.json();
328
+ return FetchMateResponse_default.success(data);
329
+ } catch (error) {
330
+ return FetchMateResponse_default.error(error);
331
+ }
332
+ }
333
+ // HTTP Methods - automatically parse JSON
334
+ async get(url, options) {
335
+ return this.requestJson("GET", url, void 0, options);
336
+ }
337
+ async post(url, body, options) {
338
+ return this.requestJson("POST", url, body, options);
339
+ }
340
+ async put(url, body, options) {
341
+ return this.requestJson("PUT", url, body, options);
342
+ }
343
+ async patch(url, body, options) {
344
+ return this.requestJson("PATCH", url, body, options);
345
+ }
346
+ async delete(url, options) {
347
+ return this.requestJson("DELETE", url, void 0, options);
348
+ }
349
+ async head(url, options) {
350
+ return this.requestJson("HEAD", url, void 0, options);
351
+ }
352
+ async options(url, options) {
353
+ return this.requestJson("OPTIONS", url, void 0, options);
354
+ }
355
+ // Raw response method (for cases where you need the Response object)
356
+ async raw(method, url, body, options) {
357
+ return this.request(method.toUpperCase(), url, body, options);
358
+ }
359
+ // Configuration methods
360
+ baseUrl(url) {
361
+ this.config.baseUrl = url;
362
+ }
363
+ header(key, value) {
364
+ if (!this.config.headers) {
365
+ this.config.headers = {};
366
+ }
367
+ this.config.headers[key] = value;
368
+ }
369
+ headers(headers) {
370
+ if (!this.config.headers) {
371
+ this.config.headers = {};
372
+ }
373
+ this.config.headers = { ...this.config.headers, ...headers };
374
+ }
375
+ timeout(timeout) {
376
+ this.config.timeout = timeout;
377
+ }
378
+ credentials(credentials) {
379
+ this.config.credentials = credentials;
380
+ }
381
+ };
382
+ var FetchMate_default = FetchMate;
383
+
384
+ // src/core/aggregator/schemas.ts
385
+ import { CurrencyAmount as CurrencyAmount3, Percent as Percent4 } from "@uniswap/sdk-core";
386
+ import BigNumber2 from "bignumber.js";
387
+ import { getAddress } from "ethers";
388
+ import JSBI3 from "jsbi";
389
+ import { z as z2 } from "zod";
390
+
391
+ // src/utils/common.ts
392
+ import { CurrencyAmount, Percent as Percent2 } from "@uniswap/sdk-core";
393
+ import JSBI from "jsbi";
394
+ import { v4 } from "uuid";
395
+
396
+ // src/configs/common.ts
397
+ import { Percent } from "@uniswap/sdk-core";
398
+
399
+ // src/types/common.ts
400
+ var Field = /* @__PURE__ */ ((Field2) => {
401
+ Field2["TokenIn"] = "tokenIn";
402
+ Field2["TokenOut"] = "tokenOut";
403
+ return Field2;
404
+ })(Field || {});
405
+ var WrapType = /* @__PURE__ */ ((WrapType2) => {
406
+ WrapType2["NOT_APPLICABLE"] = "not-applicable";
407
+ WrapType2["WRAP"] = "wrap";
408
+ WrapType2["UNWRAP"] = "unwrap";
409
+ return WrapType2;
410
+ })(WrapType || {});
411
+ var PriceImpactLevel = /* @__PURE__ */ ((PriceImpactLevel2) => {
412
+ PriceImpactLevel2[PriceImpactLevel2["LOW"] = 0] = "LOW";
413
+ PriceImpactLevel2[PriceImpactLevel2["MEDIUM"] = 3] = "MEDIUM";
414
+ PriceImpactLevel2[PriceImpactLevel2["HIGH"] = 5] = "HIGH";
415
+ PriceImpactLevel2[PriceImpactLevel2["BLOCKED"] = 15] = "BLOCKED";
416
+ return PriceImpactLevel2;
417
+ })(PriceImpactLevel || {});
418
+
419
+ // src/types/quote.ts
420
+ var AggregatedQuoteFeeType = /* @__PURE__ */ ((AggregatedQuoteFeeType2) => {
421
+ AggregatedQuoteFeeType2["DEVELOPMENT"] = "development";
422
+ AggregatedQuoteFeeType2["PROTOCOL"] = "protocol";
423
+ AggregatedQuoteFeeType2["NETWORK"] = "network";
424
+ return AggregatedQuoteFeeType2;
425
+ })(AggregatedQuoteFeeType || {});
426
+
427
+ // src/types/events.ts
428
+ var DexHandleQuoteState = /* @__PURE__ */ ((DexHandleQuoteState2) => {
429
+ DexHandleQuoteState2["Authorizing"] = "authorizing";
430
+ DexHandleQuoteState2["Authorized"] = "authorized";
431
+ DexHandleQuoteState2["AuthorizeFailed"] = "authorize-failed";
432
+ DexHandleQuoteState2["ApprovingToken"] = "approving-token";
433
+ DexHandleQuoteState2["ApprovedToken"] = "approved-token";
434
+ DexHandleQuoteState2["ApproveTokenFailed"] = "approve-token-failed";
435
+ DexHandleQuoteState2["SigningPermit"] = "signing-permit";
436
+ DexHandleQuoteState2["SignedPermit"] = "signed-permit";
437
+ DexHandleQuoteState2["SignPermitFailed"] = "sign-permit-failed";
438
+ DexHandleQuoteState2["Wrapping"] = "wrapping";
439
+ DexHandleQuoteState2["Wrapped"] = "wrapped";
440
+ DexHandleQuoteState2["Unwrapping"] = "unwrapping";
441
+ DexHandleQuoteState2["Unwrapped"] = "unwrapped";
442
+ DexHandleQuoteState2["PopulatingTransaction"] = "populating-transaction";
443
+ DexHandleQuoteState2["SigningTransaction"] = "signing-transaction";
444
+ DexHandleQuoteState2["SignedTransaction"] = "signed-transaction";
445
+ DexHandleQuoteState2["TransactionSubmitted"] = "transaction-submitted";
446
+ DexHandleQuoteState2["WaitingForNextTransaction"] = "waiting-for-next-transaction";
447
+ DexHandleQuoteState2["WaitingForReceipt"] = "waiting-for-receipt";
448
+ DexHandleQuoteState2["Computing"] = "computing";
449
+ DexHandleQuoteState2["Success"] = "success";
450
+ DexHandleQuoteState2["Failed"] = "failed";
451
+ return DexHandleQuoteState2;
452
+ })(DexHandleQuoteState || {});
453
+
454
+ // src/types/fee.ts
455
+ var NetworkFeeLevel = /* @__PURE__ */ ((NetworkFeeLevel3) => {
456
+ NetworkFeeLevel3["Low"] = "low";
457
+ NetworkFeeLevel3["Medium"] = "medium";
458
+ NetworkFeeLevel3["High"] = "high";
459
+ NetworkFeeLevel3["Custom"] = "custom";
460
+ return NetworkFeeLevel3;
461
+ })(NetworkFeeLevel || {});
462
+
463
+ // src/configs/common.ts
464
+ var NETWORK_PRIMITIVE_FEE_LEVELS = [
465
+ "low" /* Low */,
466
+ "medium" /* Medium */,
467
+ "high" /* High */
468
+ ];
469
+ var MIN_SLIPPAGE = new Percent(10, 1e4);
470
+ var DEFAULT_SLIPPAGE = new Percent(50, 1e4);
471
+ var MAX_SLIPPAGE = new Percent(30, 100);
472
+ var PORTION_BIPS = 50;
473
+ var BIPS_BASE = 1e4;
474
+ var DEFAULT_GAS_LIMIT = "21000";
475
+ var DEFAULT_SWAP_GAS_LIMIT = "300000";
476
+ var DEVELOPMENT_FEE_PERCENT = new Percent(PORTION_BIPS, BIPS_BASE);
477
+ var DEFAULT_DEADLINE_FROM_NOW = 60 * 30;
478
+ var MIN_FEE_FOR_GAS = {
479
+ [1 /* ETHEREUM */]: 10 ** 16,
480
+ [137 /* POLYGON */]: 10 ** 17,
481
+ [56 /* BSC */]: 10 ** 16,
482
+ [8453 /* BASE */]: 10 ** 14,
483
+ [2020 /* RONIN */]: 2 * 10 ** 16,
484
+ [42161 /* ARBITRUM */]: 10 ** 14
485
+ };
486
+ var ALLOWED_PRICE_IMPACT_LOW = new Percent(1, 100);
487
+ var ALLOWED_PRICE_IMPACT_MEDIUM = new Percent(3, 100);
488
+ var ALLOWED_PRICE_IMPACT_HIGH = new Percent(5, 100);
489
+ var BLOCKED_PRICE_IMPACT_NON_EXPERT = new Percent(15, 100);
490
+ var IMPACT_TIERS = [
491
+ BLOCKED_PRICE_IMPACT_NON_EXPERT,
492
+ ALLOWED_PRICE_IMPACT_HIGH,
493
+ ALLOWED_PRICE_IMPACT_MEDIUM,
494
+ ALLOWED_PRICE_IMPACT_LOW
495
+ ];
496
+
497
+ // src/configs/tokens.ts
498
+ import { Token, WETH9 } from "@uniswap/sdk-core";
499
+ var EVM_WETH9 = {
500
+ ...WETH9,
501
+ [2020 /* RONIN */]: new Token(
502
+ 2020 /* RONIN */,
503
+ "0xe514d9deb7966c8be0ca922de8a064264ea6bcd4",
504
+ 18,
505
+ "WRON",
506
+ "Wrapped RON"
507
+ ),
508
+ [2021 /* SAIGON */]: new Token(
509
+ 2021 /* SAIGON */,
510
+ "0xa959726154953bae111746e265e6d754f48570e6",
511
+ 18,
512
+ "WRON",
513
+ "Wrapped Ronin"
514
+ )
515
+ };
516
+
517
+ // src/configs/routers.ts
518
+ var MULTICALL3_ROUTER = "0xca11bde05977b3631167028862be2a173976ca11";
519
+ var UNIVERSAL_DEFAULT_ROUTERS = {
520
+ katana: "0x5f0acdd3ec767514ff1bf7e79949640bf94576bd",
521
+ kyberswap: "0x6131b5fae19ea4f9d964eac0408e4408b66337b5",
522
+ relay: void 0
523
+ };
524
+
525
+ // src/core/platform/wrap-tokens.ts
526
+ var WRAPPED_TOKENS = /* @__PURE__ */ new Map();
527
+
528
+ // src/utils/common.ts
529
+ import isNil from "lodash/isNil";
530
+ import get from "lodash/get";
531
+
532
+ // src/internals/utils/async.ts
533
+ function sleepAsync(ms) {
534
+ return new Promise((resolve) => setTimeout(resolve, ms));
535
+ }
536
+ var isReactNative = () => {
537
+ return typeof navigator !== "undefined" && navigator?.product === "ReactNative";
538
+ };
539
+
540
+ // src/utils/common.ts
541
+ var ZERO = JSBI.BigInt(0);
542
+ var SOLANA_MIN_FEE_LAMPORTS = 5e5;
543
+ function maxAmountSpend(currencyAmount) {
544
+ if (!currencyAmount) return void 0;
545
+ if (currencyAmount.currency.isToken) return currencyAmount;
546
+ let minForGas;
547
+ if (currencyAmount.currency?.symbol.toLowerCase() === "sol" && currencyAmount.currency?.decimals === 9) {
548
+ minForGas = SOLANA_MIN_FEE_LAMPORTS;
549
+ } else {
550
+ minForGas = MIN_FEE_FOR_GAS?.[currencyAmount.currency.chainId];
551
+ }
552
+ if (!minForGas) return void 0;
553
+ const subtractedGas = JSBI.subtract(
554
+ currencyAmount.quotient,
555
+ JSBI.BigInt(minForGas)
556
+ );
557
+ const maxSpend = JSBI.greaterThan(subtractedGas, ZERO) ? subtractedGas : ZERO;
558
+ return CurrencyAmount.fromRawAmount(currencyAmount.currency, maxSpend);
559
+ }
560
+ function getWrapType(currencyIn, currencyOut) {
561
+ try {
562
+ if (currencyIn.chainId !== currencyOut.chainId) {
563
+ return { type: "not-applicable" /* NOT_APPLICABLE */ };
564
+ }
565
+ const chainId = currencyIn.chainId;
566
+ const wrappedNative = WRAPPED_TOKENS.get(chainId);
567
+ if (currencyIn.isNative && wrappedNative?.equals(currencyOut)) {
568
+ return { type: "wrap" /* WRAP */, method: "wrap" };
569
+ }
570
+ if (currencyOut.isNative && wrappedNative?.equals(currencyIn)) {
571
+ return { type: "unwrap" /* UNWRAP */, method: "unwrap" };
572
+ }
573
+ return { type: "not-applicable" /* NOT_APPLICABLE */ };
574
+ } catch (error) {
575
+ console.error("getting wrap type error:", error);
576
+ return { type: "not-applicable" /* NOT_APPLICABLE */ };
577
+ }
578
+ }
579
+ function getQuoteUuid(quote) {
580
+ try {
581
+ const fragments = [
582
+ quote.provider,
583
+ quote.__origin.payload.direction,
584
+ quote.__origin.payload.amount,
585
+ String(quote.chainId),
586
+ quote.currencyIn.address,
587
+ quote.currencyOut.address
588
+ ].filter(Boolean);
589
+ return fragments.join("#");
590
+ } catch (error) {
591
+ return v4();
592
+ }
593
+ }
594
+ function formatPurePercent(value) {
595
+ value = typeof value === "string" ? parseFloat(value) : value;
596
+ if (isNaN(value)) throw new Error(`invalid percent: ${value}`);
597
+ const bips = Math.round(value * 100);
598
+ return new Percent2(JSBI.BigInt(bips), BIPS_BASE);
599
+ }
600
+ function sortQuotesByPriority(direction, computedQuotes) {
601
+ try {
602
+ if (computedQuotes.length === 0) {
603
+ throw new Error("No quotes found, skip sorting");
604
+ }
605
+ computedQuotes.sort((a, b) => {
606
+ const field = direction === "exactIn" ? "tokenOut" /* TokenOut */ : "tokenIn" /* TokenIn */;
607
+ const aAmount = a.amounts[field];
608
+ const bAmount = b.amounts[field];
609
+ if (aAmount && bAmount) {
610
+ if (!aAmount.equalTo(bAmount)) {
611
+ if (direction === "exactIn") {
612
+ return bAmount.greaterThan(aAmount) ? 1 : -1;
613
+ } else {
614
+ return aAmount.lessThan(bAmount) ? -1 : 1;
615
+ }
616
+ }
617
+ } else if (aAmount && !bAmount) {
618
+ return -1;
619
+ } else if (!aAmount && bAmount) {
620
+ return 1;
621
+ }
622
+ const aImpact = a.priceImpact?.value;
623
+ const bImpact = b.priceImpact?.value;
624
+ if (aImpact && bImpact) {
625
+ if (!aImpact.equalTo(bImpact)) return aImpact.lessThan(bImpact) ? -1 : 1;
626
+ } else if (aImpact && !bImpact) {
627
+ return -1;
628
+ } else if (!aImpact && bImpact) {
629
+ return 1;
630
+ }
631
+ return 0;
632
+ });
633
+ if (computedQuotes.length > 0 && computedQuotes[0]) {
634
+ computedQuotes[0].isBestTrade = true;
635
+ }
636
+ return computedQuotes;
637
+ } catch (issue) {
638
+ if (computedQuotes.length > 0 && computedQuotes[0]) {
639
+ computedQuotes[0].isBestTrade = true;
640
+ }
641
+ return computedQuotes;
642
+ }
643
+ }
644
+ function safetyKyberRouter(calldataBuilder) {
645
+ try {
646
+ const data = get(calldataBuilder, "data");
647
+ if (isNil(data)) throw "";
648
+ const origin = JSON.parse(data);
649
+ return get(origin, "routerAddress");
650
+ } catch (error) {
651
+ return get(UNIVERSAL_DEFAULT_ROUTERS, "kyberswap");
652
+ }
653
+ }
654
+ function getUniveralRouterAddress(provider, calldataBuilder) {
655
+ const router = get(UNIVERSAL_DEFAULT_ROUTERS, provider);
656
+ if (!router && provider === "kyberswap") {
657
+ return safetyKyberRouter(calldataBuilder);
658
+ }
659
+ return router;
660
+ }
661
+ function tradeMeaningfullyDiffers(quote, nextQuote) {
662
+ try {
663
+ const direction0 = get(quote, "__origin.payload.direction");
664
+ const direction1 = get(nextQuote, "__origin.payload.direction");
665
+ return direction0 !== direction1 || !quote.amountIn.currency.equals(nextQuote.amountIn.currency) || !quote.amountOut.currency.equals(nextQuote.amountOut.currency) || nextQuote.worstExecutionPrice.lessThan(quote.worstExecutionPrice);
666
+ } catch (error) {
667
+ console.error("error in comparing current and next quote:", error);
668
+ return false;
669
+ }
670
+ }
671
+
672
+ // src/utils/compute.ts
673
+ import { TradeType } from "@sky-mavis/katana-swap";
674
+ import { ZERO_PERCENT } from "@sky-mavis/katana-core";
675
+ import { CurrencyAmount as CurrencyAmount2, Fraction, Percent as Percent3 } from "@uniswap/sdk-core";
676
+ import { BigNumber as EthersBigNumber } from "@ethersproject/bignumber";
677
+ import { FeeAmount } from "@uniswap/v3-sdk";
678
+ import { Pair } from "@uniswap/v2-sdk";
679
+ import JSBI2 from "jsbi";
680
+ import isEmpty from "lodash/isEmpty";
681
+ import get2 from "lodash/get";
682
+ var WARNING_SEVERITY_CACHE = /* @__PURE__ */ new Map();
683
+ var MAX_CACHE_SIZE = 1e3;
684
+ function warningSeverity(priceImpact) {
685
+ if (!priceImpact) {
686
+ return 0;
687
+ }
688
+ if (priceImpact.lessThan(0)) {
689
+ return 0;
690
+ }
691
+ const key = `${priceImpact.numerator.toString()}-${priceImpact.denominator.toString()}`;
692
+ if (WARNING_SEVERITY_CACHE.has(key)) {
693
+ return WARNING_SEVERITY_CACHE.get(key);
694
+ }
695
+ let impact = IMPACT_TIERS.length;
696
+ for (const impactLevel of IMPACT_TIERS) {
697
+ if (impactLevel.lessThan(priceImpact)) {
698
+ if (WARNING_SEVERITY_CACHE.size >= MAX_CACHE_SIZE) {
699
+ const firstKey = WARNING_SEVERITY_CACHE.keys().next().value;
700
+ if (firstKey !== void 0) {
701
+ WARNING_SEVERITY_CACHE.delete(firstKey);
702
+ }
703
+ }
704
+ WARNING_SEVERITY_CACHE.set(key, impact);
705
+ return impact;
706
+ }
707
+ impact--;
708
+ }
709
+ WARNING_SEVERITY_CACHE.set(key, 0);
710
+ return 0;
711
+ }
712
+ var BI_1 = new Fraction(JSBI2.BigInt(1));
713
+ var computeMaximumAmountIn = (amountIn, slippageTolerance, tradeType = TradeType.EXACT_INPUT) => {
714
+ if (tradeType === TradeType.EXACT_INPUT) {
715
+ return amountIn;
716
+ }
717
+ const slippageAdjustedAmountIn = BI_1.add(slippageTolerance).multiply(
718
+ amountIn.quotient
719
+ ).quotient;
720
+ return CurrencyAmount2.fromRawAmount(
721
+ amountIn.currency,
722
+ slippageAdjustedAmountIn
723
+ );
724
+ };
725
+ var computeMinimumAmountOut = (amountOut, slippageTolerance, tradeType = TradeType.EXACT_INPUT) => {
726
+ if (tradeType === TradeType.EXACT_OUTPUT) {
727
+ return amountOut;
728
+ }
729
+ const slippageAdjustedAmountOut = BI_1.add(slippageTolerance).invert().multiply(amountOut.quotient).quotient;
730
+ return CurrencyAmount2.fromRawAmount(
731
+ amountOut.currency,
732
+ slippageAdjustedAmountOut
733
+ );
734
+ };
735
+ var MAX_PERCENTAGE = 1e4;
736
+ var THIRTY_BIPS_FEE = new Percent3(JSBI2.BigInt(30), MAX_PERCENTAGE);
737
+ var ONE_HUNDRED_PERCENT = new Percent3(MAX_PERCENTAGE, MAX_PERCENTAGE);
738
+ var INPUT_FRACTION_AFTER_FEE = ONE_HUNDRED_PERCENT.subtract(THIRTY_BIPS_FEE);
739
+ function computeNetworkCost(feeData, gasLimit) {
740
+ try {
741
+ let effectiveFee;
742
+ const isLegacy = "gasPrice" in feeData;
743
+ if (isLegacy) {
744
+ effectiveFee = EthersBigNumber.from(get2(feeData, "gasPrice"));
745
+ } else {
746
+ const baseFeePerGas = EthersBigNumber.from(get2(feeData, "baseFeePerGas"));
747
+ const maxFeePerGas = EthersBigNumber.from(get2(feeData, "maxFeePerGas"));
748
+ const maxPriorityFeePerGas = EthersBigNumber.from(
749
+ get2(feeData, "maxPriorityFeePerGas")
750
+ );
751
+ effectiveFee = baseFeePerGas.add(maxPriorityFeePerGas).gt(maxFeePerGas) ? maxFeePerGas : baseFeePerGas.add(maxPriorityFeePerGas);
752
+ }
753
+ if (!effectiveFee || isEmpty(effectiveFee)) {
754
+ throw new Error("invalid multiplier");
755
+ }
756
+ return EthersBigNumber.from(gasLimit).mul(effectiveFee);
757
+ } catch (error) {
758
+ console.error("compute network cost failed:", {
759
+ error,
760
+ origin: {
761
+ feeData,
762
+ gasLimit
763
+ }
764
+ });
765
+ return void 0;
766
+ }
767
+ }
768
+
769
+ // src/schema/common.ts
770
+ import { z } from "zod";
771
+
772
+ // src/model/Token.ts
773
+ import {
774
+ NativeCurrency as _NativeCurrency,
775
+ Token as Token2
776
+ } from "@uniswap/sdk-core";
777
+ import get3 from "lodash/get";
778
+ var NativeCurrency = class _NativeCurrency2 extends _NativeCurrency {
779
+ address;
780
+ logoUrl;
781
+ tags;
782
+ static #cache = {};
783
+ constructor(payload) {
784
+ super(payload.chainId, payload.decimals, payload.symbol, payload.name);
785
+ this.address = get3(payload, "address", NATIVE_ADDRESS);
786
+ this.logoUrl = get3(payload, "logoUrl");
787
+ this.tags = get3(payload, "tags");
788
+ }
789
+ get wrapped() {
790
+ const token = WRAPPED_TOKENS.get(this.chainId);
791
+ if (!token) throw new Error(`wrapped token unsupported: ${this.chainId}`);
792
+ return token;
793
+ }
794
+ equals(other) {
795
+ return other.isNative && other.chainId === this.chainId;
796
+ }
797
+ static onChain(payload) {
798
+ const cache = get3(this.#cache, payload.chainId);
799
+ if (cache) return cache;
800
+ const token = new _NativeCurrency2(payload);
801
+ this.#cache[payload.chainId] = token;
802
+ return token;
803
+ }
804
+ };
805
+ var DexToken = class extends Token2 {
806
+ logoUrl;
807
+ tags;
808
+ constructor(payload) {
809
+ super(
810
+ payload.chainId,
811
+ payload.address || NATIVE_ADDRESS,
812
+ payload.decimals,
813
+ payload.symbol,
814
+ payload.name,
815
+ payload.bypassChecksum,
816
+ payload.buyFeeBps,
817
+ payload.sellFeeBps
818
+ );
819
+ this.logoUrl = get3(payload, "logoUrl");
820
+ this.tags = get3(payload, "tags");
821
+ }
822
+ };
823
+ var SolanaDexToken = class extends DexToken {
824
+ constructor(payload) {
825
+ const solanaAddress = payload.address;
826
+ super({ ...payload, address: NATIVE_ADDRESS });
827
+ Object.defineProperty(this, "address", {
828
+ value: solanaAddress,
829
+ writable: false,
830
+ enumerable: true,
831
+ configurable: false
832
+ });
833
+ }
834
+ };
835
+
836
+ // src/schema/common.ts
837
+ var $chainId = z.number().int().positive().refine((val) => val > 0 && val <= 2147483647, {
838
+ message: "Invalid chain ID - must be a positive integer within valid range"
839
+ });
840
+ var $address = z.string();
841
+ var $nativeCurrency = z.instanceof(
842
+ NativeCurrency
843
+ );
844
+ var $dexCurrency = z.union([z.instanceof(DexToken), $nativeCurrency]);
845
+
846
+ // src/core/aggregator/schemas.ts
847
+ import camelCase from "lodash/camelCase";
848
+ import isNil2 from "lodash/isNil";
849
+ var $token = z2.object({
850
+ chain_id: $chainId,
851
+ address: $address,
852
+ decimal: z2.number().int(),
853
+ token_standard: z2.enum(["native", "erc20"]),
854
+ name: z2.string().nullish(),
855
+ symbol: z2.string().nullish(),
856
+ logo_uri: z2.string().nullish(),
857
+ tags: z2.array(z2.string()).nullish()
858
+ });
859
+ var $findRoutesPayload = z2.object({
860
+ amount: z2.string(),
861
+ account: $address,
862
+ currencyIn: $dexCurrency,
863
+ currencyOut: $dexCurrency,
864
+ direction: z2.enum(["exactIn", "exactOut"]),
865
+ slippageToleranceBps: z2.instanceof(Percent4)
866
+ });
867
+ var $calldataBuilder = z2.object({
868
+ strategy: z2.string(),
869
+ request_id: z2.string().nullish(),
870
+ data: z2.string()
871
+ });
872
+ var $gas = z2.object({
873
+ gas: z2.string().nullish(),
874
+ gas_price: z2.string().nullish(),
875
+ gas_usd: z2.string().nullish()
876
+ }).transform((data) => ({
877
+ gasLimit: data.gas,
878
+ gasPrice: data.gas_price,
879
+ gasUsd: data.gas_usd
880
+ }));
881
+ var $extraFee = z2.object({
882
+ token: $token,
883
+ recipient: $address.nullish(),
884
+ amount: z2.string().nullish(),
885
+ amount_usd: z2.string().nullish(),
886
+ percentage: z2.string().nullish()
887
+ }).transform((data) => {
888
+ let percentage;
889
+ try {
890
+ percentage = formatPurePercent(data.percentage);
891
+ } catch (error) {
892
+ console.error("extra fee percentage error:", error);
893
+ }
894
+ return {
895
+ token: data.token,
896
+ recipient: data.recipient,
897
+ amount: data.amount,
898
+ amountUsd: data.amount_usd,
899
+ percentage
900
+ };
901
+ });
902
+ var $baseQuote = z2.object({
903
+ // required fields
904
+ provider: z2.string(),
905
+ address_in: $address,
906
+ address_out: $address,
907
+ chain_id: z2.number(),
908
+ chain_id_out: z2.number().nullish(),
909
+ amount_in: z2.string(),
910
+ amount_out: z2.string(),
911
+ routes: z2.array(z2.unknown()),
912
+ token_in: $token,
913
+ token_out: $token,
914
+ calldata_builder: $calldataBuilder,
915
+ // optional fields
916
+ gas: $gas.nullish(),
917
+ extra_fee: $extraFee.nullish(),
918
+ amount_in_usd: z2.string().nullish(),
919
+ amount_out_usd: z2.string().nullish(),
920
+ price_impact: z2.string().nullish(),
921
+ permit2_address: $address.nullish(),
922
+ universal_router_address: $address.nullish(),
923
+ provider_route_id: z2.string().nullish(),
924
+ // custom fields
925
+ __origin: z2.object({ payload: $findRoutesPayload }),
926
+ create_dex_currency: z2.function().args(z2.any()).returns($dexCurrency)
927
+ });
928
+ var $quote = $baseQuote.transform((data) => {
929
+ const currencyIn = data.create_dex_currency({
930
+ chainId: data.token_in.chain_id,
931
+ address: data.token_in.address,
932
+ symbol: data.token_in.symbol,
933
+ name: data.token_in.name,
934
+ decimals: data.token_in.decimal,
935
+ standard: data.token_in.token_standard,
936
+ logoUrl: data.token_in.logo_uri,
937
+ tags: data.token_in.tags
938
+ });
939
+ const currencyOut = data.create_dex_currency({
940
+ chainId: data.token_out.chain_id,
941
+ address: data.token_out.address,
942
+ symbol: data.token_out.symbol,
943
+ name: data.token_out.name,
944
+ decimals: data.token_out.decimal,
945
+ standard: data.token_out.token_standard,
946
+ logoUrl: data.token_out.logo_uri,
947
+ tags: data.token_out.tags
948
+ });
949
+ const amountIn = CurrencyAmount3.fromRawAmount(
950
+ currencyIn,
951
+ JSBI3.BigInt(data.amount_in)
952
+ );
953
+ const amountInUsd = data.amount_in_usd && typeof parseFloat(data.amount_in_usd) === "number" ? new BigNumber2(data.amount_in_usd) : void 0;
954
+ const amountOut = CurrencyAmount3.fromRawAmount(
955
+ currencyOut,
956
+ JSBI3.BigInt(data.amount_out)
957
+ );
958
+ const amountOutUsd = data.amount_out_usd && typeof parseFloat(data.amount_out_usd) === "number" ? new BigNumber2(data.amount_out_usd) : void 0;
959
+ const priceImpactPercent = data.price_impact ? new Percent4(
960
+ JSBI3.BigInt(Math.round(parseFloat(data.price_impact) * 100)),
961
+ BIPS_BASE
962
+ ) : void 0;
963
+ const priceImpact = priceImpactPercent ? {
964
+ value: priceImpactPercent,
965
+ severity: warningSeverity(priceImpactPercent)
966
+ } : void 0;
967
+ const permit2Address = !isNil2(data.permit2_address) ? getAddress(data.permit2_address) : void 0;
968
+ const universalRouterAddress = !isNil2(data.universal_router_address) ? getAddress(data.universal_router_address) : getUniveralRouterAddress(data.provider, data.calldata_builder);
969
+ const chainId = data.chain_id !== currencyIn.chainId ? currencyIn.chainId : data.chain_id;
970
+ const chainIdOut = data.chain_id_out !== currencyOut.chainId ? currencyOut.chainId : data.chain_id_out;
971
+ return {
972
+ chainId,
973
+ chainIdOut,
974
+ amountIn,
975
+ amountInUsd,
976
+ amountOut,
977
+ amountOutUsd,
978
+ currencyIn,
979
+ currencyOut,
980
+ permit2Address,
981
+ universalRouterAddress,
982
+ priceImpact,
983
+ provider: data.provider,
984
+ addressIn: data.address_in,
985
+ addressOut: data.address_out,
986
+ calldataBuilder: data.calldata_builder,
987
+ routes: data.routes,
988
+ routeNotFound: data.routes.length === 0,
989
+ extraFee: data.extra_fee,
990
+ gas: data.gas,
991
+ __origin: data.__origin
992
+ };
993
+ });
994
+ var $buildRoutesPayload = z2.object({
995
+ chainId: $chainId,
996
+ chainIdOut: $chainId.nullish(),
997
+ provider: z2.string(),
998
+ sender: $address,
999
+ recipient: $address,
1000
+ calldataBuilder: $calldataBuilder,
1001
+ slippageToleranceBps: z2.instanceof(Percent4)
1002
+ });
1003
+ var $originBuiltRoutesCalldata = z2.record(z2.string(), z2.unknown());
1004
+ var $builtRoutesCalldata = $originBuiltRoutesCalldata.transform(
1005
+ (data) => Object.entries(data).reduce(
1006
+ (accumulator, [key, value]) => ({
1007
+ ...accumulator,
1008
+ [camelCase(key)]: value
1009
+ }),
1010
+ {}
1011
+ )
1012
+ );
1013
+
1014
+ // src/core/aggregator/Aggregator.ts
1015
+ import isNil3 from "lodash/isNil";
1016
+ import get4 from "lodash/get";
1017
+
1018
+ // src/core/CoreDexShared.ts
1019
+ var DependencyValidator = class {
1020
+ static validate(dependency, dependencyName, expectedType) {
1021
+ if (!dependency) {
1022
+ throw new Error(`${dependencyName} is required but was ${dependency}`);
1023
+ }
1024
+ if (expectedType && !(dependency instanceof expectedType)) {
1025
+ throw new Error(
1026
+ `Invalid ${dependencyName}. Expected instance of ${expectedType.name}`
1027
+ );
1028
+ }
1029
+ return dependency;
1030
+ }
1031
+ /**
1032
+ * Validates that a service has been properly initialized
1033
+ */
1034
+ static strict(dependency, serviceName, dependencyName) {
1035
+ if (!dependency) {
1036
+ throw new Error(
1037
+ `${serviceName} not initialized. Call use(${dependencyName}) first.`
1038
+ );
1039
+ }
1040
+ return dependency;
1041
+ }
1042
+ };
1043
+ var CoreDexShared = class {
1044
+ coredex;
1045
+ use(coredex) {
1046
+ this.coredex = DependencyValidator.validate(coredex, "CoreDex", CoreDex);
1047
+ return this;
1048
+ }
1049
+ useCoreDex() {
1050
+ return DependencyValidator.strict(
1051
+ this.coredex,
1052
+ this.constructor.name,
1053
+ "CoreDex"
1054
+ );
1055
+ }
1056
+ };
1057
+
1058
+ // src/core/aggregator/Aggregator.ts
1059
+ var Aggregator = class extends CoreDexShared {
1060
+ api = new FetchMate_default({
1061
+ headers: { "Content-Type": "application/json" }
1062
+ });
1063
+ constructor() {
1064
+ super();
1065
+ }
1066
+ use(coredex) {
1067
+ super.use(coredex);
1068
+ this.api.baseUrl(coredex.dependencies.apiUrl);
1069
+ return this;
1070
+ }
1071
+ getAccount = async (chainId, baseAddress) => {
1072
+ const platform = this.coredex.platform.fromChainId(chainId);
1073
+ return await platform.getAccount(baseAddress);
1074
+ };
1075
+ createDexCurrency = (payload) => {
1076
+ return this.coredex.platform.fromChainId(payload.chainId).createDexCurrency(payload);
1077
+ };
1078
+ async tokens(chainId, options) {
1079
+ const response = await this.api.get(
1080
+ "/proxy/v3/public/swap/tokens",
1081
+ { params: { chainId, ...options } }
1082
+ );
1083
+ const {
1084
+ data: { tokens, pagination }
1085
+ } = response.unwrap();
1086
+ const results = tokens.reduce(
1087
+ (accumulator, token) => {
1088
+ try {
1089
+ const sigil = this.coredex.createSignatureId(token.chain_id, token.address);
1090
+ const dexToken = this.createDexCurrency({
1091
+ chainId: token.chain_id,
1092
+ decimals: token.decimal,
1093
+ symbol: token.symbol,
1094
+ name: token.name,
1095
+ standard: token.token_standard,
1096
+ address: token.address,
1097
+ logoUrl: token.logo_uri,
1098
+ tags: token.tags
1099
+ });
1100
+ accumulator.ids.push(sigil);
1101
+ accumulator.data[sigil] = dexToken;
1102
+ return accumulator;
1103
+ } catch (error) {
1104
+ return accumulator;
1105
+ }
1106
+ },
1107
+ { ids: [], data: {} }
1108
+ );
1109
+ return { ...results, pagination };
1110
+ }
1111
+ async handleAddresses(ownerAddress, currencyIn, currencyOut) {
1112
+ const chainId = currencyIn.chainId;
1113
+ const addresses = {
1114
+ chain_id: chainId,
1115
+ user_address: ownerAddress
1116
+ };
1117
+ try {
1118
+ const chainIdOut = currencyOut.chainId;
1119
+ const isCrossChain = chainId !== chainIdOut;
1120
+ if (!isCrossChain) {
1121
+ const account = await this.getAccount(chainId, ownerAddress);
1122
+ Object.assign(addresses, { user_address: account.address });
1123
+ } else {
1124
+ const [account, destAccount] = await Promise.all([
1125
+ this.getAccount(chainId, ownerAddress),
1126
+ this.getAccount(chainIdOut, ownerAddress)
1127
+ ]);
1128
+ Object.assign(addresses, {
1129
+ chain_id: chainId,
1130
+ user_address: account.address,
1131
+ chain_id_out: chainIdOut,
1132
+ dest_user_address: destAccount.address
1133
+ });
1134
+ }
1135
+ } catch (error) {
1136
+ this.coredex.console.error("failed to get account", error);
1137
+ throw error;
1138
+ }
1139
+ return addresses;
1140
+ }
1141
+ async find(payload) {
1142
+ const addresses = await this.handleAddresses(
1143
+ payload.account,
1144
+ payload.currencyIn,
1145
+ payload.currencyOut
1146
+ );
1147
+ const body = {
1148
+ ...addresses,
1149
+ token_in: payload.currencyIn.address,
1150
+ token_out: payload.currencyOut.address,
1151
+ slippage_tolerance_bps: parseFloat(
1152
+ payload.slippageToleranceBps.numerator.toString()
1153
+ ),
1154
+ ...payload.direction === "exactIn" ? { amount_in: payload.amount } : { amount_out: payload.amount }
1155
+ };
1156
+ this.coredex.console.info("find quote payload >>>", body);
1157
+ const response = await this.api.post(
1158
+ "/proxy/v3/public/swap/routes/find",
1159
+ body
1160
+ );
1161
+ const { data } = response.unwrap();
1162
+ this.coredex.console.info("find quote response >>>", data);
1163
+ return $safeArray(data, $quote, {
1164
+ modifier: (item) => ({
1165
+ ...item,
1166
+ __origin: { payload },
1167
+ create_dex_currency: this.createDexCurrency
1168
+ }),
1169
+ debug: Boolean(this.coredex.dependencies.debug)
1170
+ }).filter((quote) => !isNil3(quote));
1171
+ }
1172
+ async build(payload) {
1173
+ const body = {
1174
+ chain_id: payload.chainId,
1175
+ sender: payload.sender,
1176
+ recipient: payload.recipient,
1177
+ provider: payload.provider,
1178
+ calldata_builder: payload.calldataBuilder,
1179
+ slippage_tolerance_bps: parseFloat(
1180
+ payload.slippageToleranceBps.numerator.toString()
1181
+ )
1182
+ };
1183
+ const account = await this.getAccount(payload.chainId, payload.sender);
1184
+ Object.assign(body, {
1185
+ sender: account.address,
1186
+ recipient: account.address
1187
+ });
1188
+ this.coredex.console.info("build quote body >>>", body);
1189
+ const response = await this.api.post(
1190
+ "/proxy/v3/public/swap/routes/build",
1191
+ body
1192
+ );
1193
+ this.coredex.console.info("build quote response >>>", response);
1194
+ const { data } = response.unwrap();
1195
+ return $safeArray(get4(data, "calldata"), $builtRoutesCalldata, {
1196
+ debug: Boolean(this.coredex.dependencies.debug)
1197
+ });
1198
+ }
1199
+ async getPrice(chain_id, address) {
1200
+ const response = await this.api.post("/proxy/v3/public/fiat/tokens", {
1201
+ tokens: [{ chain_id, address }]
1202
+ });
1203
+ return parseFloat(get4(response.unwrap(), "data.items.0.usd_price"));
1204
+ }
1205
+ };
1206
+
1207
+ // src/core/platform/EVM/AbstractedEVM.ts
1208
+ import { BigNumber as EthersBigNumber2 } from "@ethersproject/bignumber";
1209
+ import {
1210
+ isAddress as isAddress2,
1211
+ formatUnits
1212
+ } from "ethers";
1213
+ import BigNumber6 from "bignumber.js";
1214
+
1215
+ // src/contracts/typed/factories/AggregateRouter__factory.ts
1216
+ import { Contract, Interface } from "ethers";
1217
+
1218
+ // src/contracts/typed/factories/Erc1155__factory.ts
1219
+ import { Contract as Contract2, Interface as Interface2 } from "ethers";
1220
+
1221
+ // src/contracts/typed/factories/Erc20__factory.ts
1222
+ import { Contract as Contract3, Interface as Interface3 } from "ethers";
1223
+ var _abi = [
1224
+ {
1225
+ inputs: [],
1226
+ payable: false,
1227
+ stateMutability: "nonpayable",
1228
+ type: "constructor"
1229
+ },
1230
+ {
1231
+ anonymous: false,
1232
+ inputs: [
1233
+ {
1234
+ indexed: true,
1235
+ internalType: "address",
1236
+ name: "_oldAdmin",
1237
+ type: "address"
1238
+ },
1239
+ {
1240
+ indexed: true,
1241
+ internalType: "address",
1242
+ name: "_newAdmin",
1243
+ type: "address"
1244
+ }
1245
+ ],
1246
+ name: "AdminChanged",
1247
+ type: "event"
1248
+ },
1249
+ {
1250
+ anonymous: false,
1251
+ inputs: [
1252
+ {
1253
+ indexed: true,
1254
+ internalType: "address",
1255
+ name: "_oldAdmin",
1256
+ type: "address"
1257
+ }
1258
+ ],
1259
+ name: "AdminRemoved",
1260
+ type: "event"
1261
+ },
1262
+ {
1263
+ anonymous: false,
1264
+ inputs: [
1265
+ {
1266
+ indexed: true,
1267
+ internalType: "address",
1268
+ name: "_owner",
1269
+ type: "address"
1270
+ },
1271
+ {
1272
+ indexed: true,
1273
+ internalType: "address",
1274
+ name: "_spender",
1275
+ type: "address"
1276
+ },
1277
+ {
1278
+ indexed: false,
1279
+ internalType: "uint256",
1280
+ name: "_value",
1281
+ type: "uint256"
1282
+ }
1283
+ ],
1284
+ name: "Approval",
1285
+ type: "event"
1286
+ },
1287
+ {
1288
+ anonymous: false,
1289
+ inputs: [
1290
+ {
1291
+ indexed: true,
1292
+ internalType: "address",
1293
+ name: "_minter",
1294
+ type: "address"
1295
+ }
1296
+ ],
1297
+ name: "MinterAdded",
1298
+ type: "event"
1299
+ },
1300
+ {
1301
+ anonymous: false,
1302
+ inputs: [
1303
+ {
1304
+ indexed: true,
1305
+ internalType: "address",
1306
+ name: "_minter",
1307
+ type: "address"
1308
+ }
1309
+ ],
1310
+ name: "MinterRemoved",
1311
+ type: "event"
1312
+ },
1313
+ {
1314
+ anonymous: false,
1315
+ inputs: [],
1316
+ name: "Paused",
1317
+ type: "event"
1318
+ },
1319
+ {
1320
+ anonymous: false,
1321
+ inputs: [
1322
+ {
1323
+ indexed: true,
1324
+ internalType: "address",
1325
+ name: "_spender",
1326
+ type: "address"
1327
+ }
1328
+ ],
1329
+ name: "SpenderUnwhitelisted",
1330
+ type: "event"
1331
+ },
1332
+ {
1333
+ anonymous: false,
1334
+ inputs: [
1335
+ {
1336
+ indexed: true,
1337
+ internalType: "address",
1338
+ name: "_spender",
1339
+ type: "address"
1340
+ }
1341
+ ],
1342
+ name: "SpenderWhitelisted",
1343
+ type: "event"
1344
+ },
1345
+ {
1346
+ anonymous: false,
1347
+ inputs: [
1348
+ {
1349
+ indexed: true,
1350
+ internalType: "address",
1351
+ name: "_from",
1352
+ type: "address"
1353
+ },
1354
+ {
1355
+ indexed: true,
1356
+ internalType: "address",
1357
+ name: "_to",
1358
+ type: "address"
1359
+ },
1360
+ {
1361
+ indexed: false,
1362
+ internalType: "uint256",
1363
+ name: "_value",
1364
+ type: "uint256"
1365
+ }
1366
+ ],
1367
+ name: "Transfer",
1368
+ type: "event"
1369
+ },
1370
+ {
1371
+ anonymous: false,
1372
+ inputs: [],
1373
+ name: "Unpaused",
1374
+ type: "event"
1375
+ },
1376
+ {
1377
+ constant: false,
1378
+ inputs: [
1379
+ {
1380
+ internalType: "address[]",
1381
+ name: "_addedMinters",
1382
+ type: "address[]"
1383
+ }
1384
+ ],
1385
+ name: "addMinters",
1386
+ outputs: [],
1387
+ payable: false,
1388
+ stateMutability: "nonpayable",
1389
+ type: "function"
1390
+ },
1391
+ {
1392
+ constant: true,
1393
+ inputs: [],
1394
+ name: "admin",
1395
+ outputs: [
1396
+ {
1397
+ internalType: "address",
1398
+ name: "",
1399
+ type: "address"
1400
+ }
1401
+ ],
1402
+ payable: false,
1403
+ stateMutability: "view",
1404
+ type: "function"
1405
+ },
1406
+ {
1407
+ constant: true,
1408
+ inputs: [
1409
+ {
1410
+ internalType: "address",
1411
+ name: "_owner",
1412
+ type: "address"
1413
+ },
1414
+ {
1415
+ internalType: "address",
1416
+ name: "_spender",
1417
+ type: "address"
1418
+ }
1419
+ ],
1420
+ name: "allowance",
1421
+ outputs: [
1422
+ {
1423
+ internalType: "uint256",
1424
+ name: "_value",
1425
+ type: "uint256"
1426
+ }
1427
+ ],
1428
+ payable: false,
1429
+ stateMutability: "view",
1430
+ type: "function"
1431
+ },
1432
+ {
1433
+ constant: false,
1434
+ inputs: [
1435
+ {
1436
+ internalType: "address",
1437
+ name: "_spender",
1438
+ type: "address"
1439
+ },
1440
+ {
1441
+ internalType: "uint256",
1442
+ name: "_value",
1443
+ type: "uint256"
1444
+ }
1445
+ ],
1446
+ name: "approve",
1447
+ outputs: [
1448
+ {
1449
+ internalType: "bool",
1450
+ name: "_success",
1451
+ type: "bool"
1452
+ }
1453
+ ],
1454
+ payable: false,
1455
+ stateMutability: "nonpayable",
1456
+ type: "function"
1457
+ },
1458
+ {
1459
+ constant: true,
1460
+ inputs: [
1461
+ {
1462
+ internalType: "address",
1463
+ name: "",
1464
+ type: "address"
1465
+ }
1466
+ ],
1467
+ name: "balanceOf",
1468
+ outputs: [
1469
+ {
1470
+ internalType: "uint256",
1471
+ name: "",
1472
+ type: "uint256"
1473
+ }
1474
+ ],
1475
+ payable: false,
1476
+ stateMutability: "view",
1477
+ type: "function"
1478
+ },
1479
+ {
1480
+ constant: false,
1481
+ inputs: [
1482
+ {
1483
+ internalType: "uint256",
1484
+ name: "_value",
1485
+ type: "uint256"
1486
+ }
1487
+ ],
1488
+ name: "burn",
1489
+ outputs: [
1490
+ {
1491
+ internalType: "bool",
1492
+ name: "_success",
1493
+ type: "bool"
1494
+ }
1495
+ ],
1496
+ payable: false,
1497
+ stateMutability: "nonpayable",
1498
+ type: "function"
1499
+ },
1500
+ {
1501
+ constant: false,
1502
+ inputs: [
1503
+ {
1504
+ internalType: "address",
1505
+ name: "_from",
1506
+ type: "address"
1507
+ },
1508
+ {
1509
+ internalType: "uint256",
1510
+ name: "_value",
1511
+ type: "uint256"
1512
+ }
1513
+ ],
1514
+ name: "burnFrom",
1515
+ outputs: [
1516
+ {
1517
+ internalType: "bool",
1518
+ name: "_success",
1519
+ type: "bool"
1520
+ }
1521
+ ],
1522
+ payable: false,
1523
+ stateMutability: "nonpayable",
1524
+ type: "function"
1525
+ },
1526
+ {
1527
+ constant: true,
1528
+ inputs: [],
1529
+ name: "cappedSupply",
1530
+ outputs: [
1531
+ {
1532
+ internalType: "uint256",
1533
+ name: "",
1534
+ type: "uint256"
1535
+ }
1536
+ ],
1537
+ payable: false,
1538
+ stateMutability: "view",
1539
+ type: "function"
1540
+ },
1541
+ {
1542
+ constant: false,
1543
+ inputs: [
1544
+ {
1545
+ internalType: "address",
1546
+ name: "_newAdmin",
1547
+ type: "address"
1548
+ }
1549
+ ],
1550
+ name: "changeAdmin",
1551
+ outputs: [],
1552
+ payable: false,
1553
+ stateMutability: "nonpayable",
1554
+ type: "function"
1555
+ },
1556
+ {
1557
+ constant: true,
1558
+ inputs: [],
1559
+ name: "decimals",
1560
+ outputs: [
1561
+ {
1562
+ internalType: "uint8",
1563
+ name: "",
1564
+ type: "uint8"
1565
+ }
1566
+ ],
1567
+ payable: false,
1568
+ stateMutability: "view",
1569
+ type: "function"
1570
+ },
1571
+ {
1572
+ constant: true,
1573
+ inputs: [
1574
+ {
1575
+ internalType: "address",
1576
+ name: "_addr",
1577
+ type: "address"
1578
+ }
1579
+ ],
1580
+ name: "isMinter",
1581
+ outputs: [
1582
+ {
1583
+ internalType: "bool",
1584
+ name: "",
1585
+ type: "bool"
1586
+ }
1587
+ ],
1588
+ payable: false,
1589
+ stateMutability: "view",
1590
+ type: "function"
1591
+ },
1592
+ {
1593
+ constant: false,
1594
+ inputs: [
1595
+ {
1596
+ internalType: "address",
1597
+ name: "_to",
1598
+ type: "address"
1599
+ },
1600
+ {
1601
+ internalType: "uint256",
1602
+ name: "_value",
1603
+ type: "uint256"
1604
+ }
1605
+ ],
1606
+ name: "mint",
1607
+ outputs: [
1608
+ {
1609
+ internalType: "bool",
1610
+ name: "_success",
1611
+ type: "bool"
1612
+ }
1613
+ ],
1614
+ payable: false,
1615
+ stateMutability: "nonpayable",
1616
+ type: "function"
1617
+ },
1618
+ {
1619
+ constant: true,
1620
+ inputs: [
1621
+ {
1622
+ internalType: "address",
1623
+ name: "",
1624
+ type: "address"
1625
+ }
1626
+ ],
1627
+ name: "minter",
1628
+ outputs: [
1629
+ {
1630
+ internalType: "bool",
1631
+ name: "",
1632
+ type: "bool"
1633
+ }
1634
+ ],
1635
+ payable: false,
1636
+ stateMutability: "view",
1637
+ type: "function"
1638
+ },
1639
+ {
1640
+ constant: true,
1641
+ inputs: [
1642
+ {
1643
+ internalType: "uint256",
1644
+ name: "",
1645
+ type: "uint256"
1646
+ }
1647
+ ],
1648
+ name: "minters",
1649
+ outputs: [
1650
+ {
1651
+ internalType: "address",
1652
+ name: "",
1653
+ type: "address"
1654
+ }
1655
+ ],
1656
+ payable: false,
1657
+ stateMutability: "view",
1658
+ type: "function"
1659
+ },
1660
+ {
1661
+ constant: true,
1662
+ inputs: [],
1663
+ name: "name",
1664
+ outputs: [
1665
+ {
1666
+ internalType: "string",
1667
+ name: "",
1668
+ type: "string"
1669
+ }
1670
+ ],
1671
+ payable: false,
1672
+ stateMutability: "view",
1673
+ type: "function"
1674
+ },
1675
+ {
1676
+ constant: false,
1677
+ inputs: [],
1678
+ name: "pause",
1679
+ outputs: [],
1680
+ payable: false,
1681
+ stateMutability: "nonpayable",
1682
+ type: "function"
1683
+ },
1684
+ {
1685
+ constant: true,
1686
+ inputs: [],
1687
+ name: "paused",
1688
+ outputs: [
1689
+ {
1690
+ internalType: "bool",
1691
+ name: "",
1692
+ type: "bool"
1693
+ }
1694
+ ],
1695
+ payable: false,
1696
+ stateMutability: "view",
1697
+ type: "function"
1698
+ },
1699
+ {
1700
+ constant: false,
1701
+ inputs: [],
1702
+ name: "removeAdmin",
1703
+ outputs: [],
1704
+ payable: false,
1705
+ stateMutability: "nonpayable",
1706
+ type: "function"
1707
+ },
1708
+ {
1709
+ constant: false,
1710
+ inputs: [
1711
+ {
1712
+ internalType: "address[]",
1713
+ name: "_removedMinters",
1714
+ type: "address[]"
1715
+ }
1716
+ ],
1717
+ name: "removeMinters",
1718
+ outputs: [],
1719
+ payable: false,
1720
+ stateMutability: "nonpayable",
1721
+ type: "function"
1722
+ },
1723
+ {
1724
+ constant: true,
1725
+ inputs: [],
1726
+ name: "symbol",
1727
+ outputs: [
1728
+ {
1729
+ internalType: "string",
1730
+ name: "",
1731
+ type: "string"
1732
+ }
1733
+ ],
1734
+ payable: false,
1735
+ stateMutability: "view",
1736
+ type: "function"
1737
+ },
1738
+ {
1739
+ constant: true,
1740
+ inputs: [],
1741
+ name: "totalSupply",
1742
+ outputs: [
1743
+ {
1744
+ internalType: "uint256",
1745
+ name: "",
1746
+ type: "uint256"
1747
+ }
1748
+ ],
1749
+ payable: false,
1750
+ stateMutability: "view",
1751
+ type: "function"
1752
+ },
1753
+ {
1754
+ constant: false,
1755
+ inputs: [
1756
+ {
1757
+ internalType: "address",
1758
+ name: "_to",
1759
+ type: "address"
1760
+ },
1761
+ {
1762
+ internalType: "uint256",
1763
+ name: "_value",
1764
+ type: "uint256"
1765
+ }
1766
+ ],
1767
+ name: "transfer",
1768
+ outputs: [
1769
+ {
1770
+ internalType: "bool",
1771
+ name: "_success",
1772
+ type: "bool"
1773
+ }
1774
+ ],
1775
+ payable: false,
1776
+ stateMutability: "nonpayable",
1777
+ type: "function"
1778
+ },
1779
+ {
1780
+ constant: false,
1781
+ inputs: [
1782
+ {
1783
+ internalType: "address",
1784
+ name: "_from",
1785
+ type: "address"
1786
+ },
1787
+ {
1788
+ internalType: "address",
1789
+ name: "_to",
1790
+ type: "address"
1791
+ },
1792
+ {
1793
+ internalType: "uint256",
1794
+ name: "_value",
1795
+ type: "uint256"
1796
+ }
1797
+ ],
1798
+ name: "transferFrom",
1799
+ outputs: [
1800
+ {
1801
+ internalType: "bool",
1802
+ name: "_success",
1803
+ type: "bool"
1804
+ }
1805
+ ],
1806
+ payable: false,
1807
+ stateMutability: "nonpayable",
1808
+ type: "function"
1809
+ },
1810
+ {
1811
+ constant: false,
1812
+ inputs: [],
1813
+ name: "unpause",
1814
+ outputs: [],
1815
+ payable: false,
1816
+ stateMutability: "nonpayable",
1817
+ type: "function"
1818
+ },
1819
+ {
1820
+ constant: false,
1821
+ inputs: [
1822
+ {
1823
+ internalType: "address",
1824
+ name: "_spender",
1825
+ type: "address"
1826
+ }
1827
+ ],
1828
+ name: "unwhitelist",
1829
+ outputs: [],
1830
+ payable: false,
1831
+ stateMutability: "nonpayable",
1832
+ type: "function"
1833
+ },
1834
+ {
1835
+ constant: false,
1836
+ inputs: [
1837
+ {
1838
+ internalType: "address",
1839
+ name: "_spender",
1840
+ type: "address"
1841
+ }
1842
+ ],
1843
+ name: "whitelist",
1844
+ outputs: [],
1845
+ payable: false,
1846
+ stateMutability: "nonpayable",
1847
+ type: "function"
1848
+ },
1849
+ {
1850
+ constant: true,
1851
+ inputs: [
1852
+ {
1853
+ internalType: "address",
1854
+ name: "",
1855
+ type: "address"
1856
+ }
1857
+ ],
1858
+ name: "whitelisted",
1859
+ outputs: [
1860
+ {
1861
+ internalType: "bool",
1862
+ name: "",
1863
+ type: "bool"
1864
+ }
1865
+ ],
1866
+ payable: false,
1867
+ stateMutability: "view",
1868
+ type: "function"
1869
+ }
1870
+ ];
1871
+ var Erc20__factory = class {
1872
+ static abi = _abi;
1873
+ static createInterface() {
1874
+ return new Interface3(_abi);
1875
+ }
1876
+ static connect(address, runner) {
1877
+ return new Contract3(address, _abi, runner);
1878
+ }
1879
+ };
1880
+
1881
+ // src/contracts/typed/factories/Erc721__factory.ts
1882
+ import { Contract as Contract4, Interface as Interface4 } from "ethers";
1883
+
1884
+ // src/contracts/typed/factories/Multicall2__factory.ts
1885
+ import { Contract as Contract5, Interface as Interface5 } from "ethers";
1886
+ var _abi2 = [
1887
+ {
1888
+ inputs: [
1889
+ {
1890
+ components: [
1891
+ {
1892
+ internalType: "address",
1893
+ name: "target",
1894
+ type: "address"
1895
+ },
1896
+ {
1897
+ internalType: "bytes",
1898
+ name: "callData",
1899
+ type: "bytes"
1900
+ }
1901
+ ],
1902
+ internalType: "struct Multicall2.Call[]",
1903
+ name: "calls",
1904
+ type: "tuple[]"
1905
+ }
1906
+ ],
1907
+ name: "aggregate",
1908
+ outputs: [
1909
+ {
1910
+ internalType: "uint256",
1911
+ name: "blockNumber",
1912
+ type: "uint256"
1913
+ },
1914
+ {
1915
+ internalType: "bytes[]",
1916
+ name: "returnData",
1917
+ type: "bytes[]"
1918
+ }
1919
+ ],
1920
+ stateMutability: "nonpayable",
1921
+ type: "function"
1922
+ },
1923
+ {
1924
+ inputs: [
1925
+ {
1926
+ components: [
1927
+ {
1928
+ internalType: "address",
1929
+ name: "target",
1930
+ type: "address"
1931
+ },
1932
+ {
1933
+ internalType: "bytes",
1934
+ name: "callData",
1935
+ type: "bytes"
1936
+ }
1937
+ ],
1938
+ internalType: "struct Multicall2.Call[]",
1939
+ name: "calls",
1940
+ type: "tuple[]"
1941
+ }
1942
+ ],
1943
+ name: "blockAndAggregate",
1944
+ outputs: [
1945
+ {
1946
+ internalType: "uint256",
1947
+ name: "blockNumber",
1948
+ type: "uint256"
1949
+ },
1950
+ {
1951
+ internalType: "bytes32",
1952
+ name: "blockHash",
1953
+ type: "bytes32"
1954
+ },
1955
+ {
1956
+ components: [
1957
+ {
1958
+ internalType: "bool",
1959
+ name: "success",
1960
+ type: "bool"
1961
+ },
1962
+ {
1963
+ internalType: "bytes",
1964
+ name: "returnData",
1965
+ type: "bytes"
1966
+ }
1967
+ ],
1968
+ internalType: "struct Multicall2.Result[]",
1969
+ name: "returnData",
1970
+ type: "tuple[]"
1971
+ }
1972
+ ],
1973
+ stateMutability: "nonpayable",
1974
+ type: "function"
1975
+ },
1976
+ {
1977
+ inputs: [
1978
+ {
1979
+ internalType: "uint256",
1980
+ name: "blockNumber",
1981
+ type: "uint256"
1982
+ }
1983
+ ],
1984
+ name: "getBlockHash",
1985
+ outputs: [
1986
+ {
1987
+ internalType: "bytes32",
1988
+ name: "blockHash",
1989
+ type: "bytes32"
1990
+ }
1991
+ ],
1992
+ stateMutability: "view",
1993
+ type: "function"
1994
+ },
1995
+ {
1996
+ inputs: [],
1997
+ name: "getBlockNumber",
1998
+ outputs: [
1999
+ {
2000
+ internalType: "uint256",
2001
+ name: "blockNumber",
2002
+ type: "uint256"
2003
+ }
2004
+ ],
2005
+ stateMutability: "view",
2006
+ type: "function"
2007
+ },
2008
+ {
2009
+ inputs: [],
2010
+ name: "getCurrentBlockCoinbase",
2011
+ outputs: [
2012
+ {
2013
+ internalType: "address",
2014
+ name: "coinbase",
2015
+ type: "address"
2016
+ }
2017
+ ],
2018
+ stateMutability: "view",
2019
+ type: "function"
2020
+ },
2021
+ {
2022
+ inputs: [],
2023
+ name: "getCurrentBlockDifficulty",
2024
+ outputs: [
2025
+ {
2026
+ internalType: "uint256",
2027
+ name: "difficulty",
2028
+ type: "uint256"
2029
+ }
2030
+ ],
2031
+ stateMutability: "view",
2032
+ type: "function"
2033
+ },
2034
+ {
2035
+ inputs: [],
2036
+ name: "getCurrentBlockGasLimit",
2037
+ outputs: [
2038
+ {
2039
+ internalType: "uint256",
2040
+ name: "gaslimit",
2041
+ type: "uint256"
2042
+ }
2043
+ ],
2044
+ stateMutability: "view",
2045
+ type: "function"
2046
+ },
2047
+ {
2048
+ inputs: [],
2049
+ name: "getCurrentBlockTimestamp",
2050
+ outputs: [
2051
+ {
2052
+ internalType: "uint256",
2053
+ name: "timestamp",
2054
+ type: "uint256"
2055
+ }
2056
+ ],
2057
+ stateMutability: "view",
2058
+ type: "function"
2059
+ },
2060
+ {
2061
+ inputs: [
2062
+ {
2063
+ internalType: "address",
2064
+ name: "addr",
2065
+ type: "address"
2066
+ }
2067
+ ],
2068
+ name: "getRonBalance",
2069
+ outputs: [
2070
+ {
2071
+ internalType: "uint256",
2072
+ name: "balance",
2073
+ type: "uint256"
2074
+ }
2075
+ ],
2076
+ stateMutability: "view",
2077
+ type: "function"
2078
+ },
2079
+ {
2080
+ inputs: [],
2081
+ name: "getLastBlockHash",
2082
+ outputs: [
2083
+ {
2084
+ internalType: "bytes32",
2085
+ name: "blockHash",
2086
+ type: "bytes32"
2087
+ }
2088
+ ],
2089
+ stateMutability: "view",
2090
+ type: "function"
2091
+ },
2092
+ {
2093
+ inputs: [
2094
+ {
2095
+ internalType: "bool",
2096
+ name: "requireSuccess",
2097
+ type: "bool"
2098
+ },
2099
+ {
2100
+ components: [
2101
+ {
2102
+ internalType: "address",
2103
+ name: "target",
2104
+ type: "address"
2105
+ },
2106
+ {
2107
+ internalType: "bytes",
2108
+ name: "callData",
2109
+ type: "bytes"
2110
+ }
2111
+ ],
2112
+ internalType: "struct Multicall2.Call[]",
2113
+ name: "calls",
2114
+ type: "tuple[]"
2115
+ }
2116
+ ],
2117
+ name: "tryAggregate",
2118
+ outputs: [
2119
+ {
2120
+ components: [
2121
+ {
2122
+ internalType: "bool",
2123
+ name: "success",
2124
+ type: "bool"
2125
+ },
2126
+ {
2127
+ internalType: "bytes",
2128
+ name: "returnData",
2129
+ type: "bytes"
2130
+ }
2131
+ ],
2132
+ internalType: "struct Multicall2.Result[]",
2133
+ name: "returnData",
2134
+ type: "tuple[]"
2135
+ }
2136
+ ],
2137
+ stateMutability: "nonpayable",
2138
+ type: "function"
2139
+ },
2140
+ {
2141
+ inputs: [
2142
+ {
2143
+ internalType: "bool",
2144
+ name: "requireSuccess",
2145
+ type: "bool"
2146
+ },
2147
+ {
2148
+ components: [
2149
+ {
2150
+ internalType: "address",
2151
+ name: "target",
2152
+ type: "address"
2153
+ },
2154
+ {
2155
+ internalType: "bytes",
2156
+ name: "callData",
2157
+ type: "bytes"
2158
+ }
2159
+ ],
2160
+ internalType: "struct Multicall2.Call[]",
2161
+ name: "calls",
2162
+ type: "tuple[]"
2163
+ }
2164
+ ],
2165
+ name: "tryBlockAndAggregate",
2166
+ outputs: [
2167
+ {
2168
+ internalType: "uint256",
2169
+ name: "blockNumber",
2170
+ type: "uint256"
2171
+ },
2172
+ {
2173
+ internalType: "bytes32",
2174
+ name: "blockHash",
2175
+ type: "bytes32"
2176
+ },
2177
+ {
2178
+ components: [
2179
+ {
2180
+ internalType: "bool",
2181
+ name: "success",
2182
+ type: "bool"
2183
+ },
2184
+ {
2185
+ internalType: "bytes",
2186
+ name: "returnData",
2187
+ type: "bytes"
2188
+ }
2189
+ ],
2190
+ internalType: "struct Multicall2.Result[]",
2191
+ name: "returnData",
2192
+ type: "tuple[]"
2193
+ }
2194
+ ],
2195
+ stateMutability: "nonpayable",
2196
+ type: "function"
2197
+ }
2198
+ ];
2199
+ var Multicall2__factory = class {
2200
+ static abi = _abi2;
2201
+ static createInterface() {
2202
+ return new Interface5(_abi2);
2203
+ }
2204
+ static connect(address, runner) {
2205
+ return new Contract5(address, _abi2, runner);
2206
+ }
2207
+ };
2208
+
2209
+ // src/contracts/typed/factories/Permit2__factory.ts
2210
+ import { Contract as Contract6, Interface as Interface6 } from "ethers";
2211
+ var _abi3 = [
2212
+ {
2213
+ inputs: [
2214
+ {
2215
+ internalType: "address",
2216
+ name: "",
2217
+ type: "address"
2218
+ },
2219
+ {
2220
+ internalType: "address",
2221
+ name: "",
2222
+ type: "address"
2223
+ },
2224
+ {
2225
+ internalType: "address",
2226
+ name: "",
2227
+ type: "address"
2228
+ }
2229
+ ],
2230
+ name: "allowance",
2231
+ outputs: [
2232
+ {
2233
+ internalType: "uint160",
2234
+ name: "amount",
2235
+ type: "uint160"
2236
+ },
2237
+ {
2238
+ internalType: "uint48",
2239
+ name: "expiration",
2240
+ type: "uint48"
2241
+ },
2242
+ {
2243
+ internalType: "uint48",
2244
+ name: "nonce",
2245
+ type: "uint48"
2246
+ }
2247
+ ],
2248
+ stateMutability: "view",
2249
+ type: "function"
2250
+ },
2251
+ {
2252
+ inputs: [
2253
+ {
2254
+ internalType: "uint256",
2255
+ name: "wordPos",
2256
+ type: "uint256"
2257
+ },
2258
+ {
2259
+ internalType: "uint256",
2260
+ name: "mask",
2261
+ type: "uint256"
2262
+ }
2263
+ ],
2264
+ name: "invalidateUnorderedNonces",
2265
+ outputs: [],
2266
+ stateMutability: "nonpayable",
2267
+ type: "function"
2268
+ }
2269
+ ];
2270
+ var Permit2__factory = class {
2271
+ static abi = _abi3;
2272
+ static createInterface() {
2273
+ return new Interface6(_abi3);
2274
+ }
2275
+ static connect(address, runner) {
2276
+ return new Contract6(address, _abi3, runner);
2277
+ }
2278
+ };
2279
+
2280
+ // src/contracts/typed/factories/WrapToken__factory.ts
2281
+ import { Contract as Contract7, Interface as Interface7 } from "ethers";
2282
+ var _abi4 = [
2283
+ {
2284
+ constant: true,
2285
+ inputs: [],
2286
+ name: "name",
2287
+ outputs: [
2288
+ {
2289
+ name: "",
2290
+ type: "string"
2291
+ }
2292
+ ],
2293
+ payable: false,
2294
+ stateMutability: "view",
2295
+ type: "function"
2296
+ },
2297
+ {
2298
+ constant: false,
2299
+ inputs: [
2300
+ {
2301
+ name: "guy",
2302
+ type: "address"
2303
+ },
2304
+ {
2305
+ name: "wad",
2306
+ type: "uint256"
2307
+ }
2308
+ ],
2309
+ name: "approve",
2310
+ outputs: [
2311
+ {
2312
+ name: "",
2313
+ type: "bool"
2314
+ }
2315
+ ],
2316
+ payable: false,
2317
+ stateMutability: "nonpayable",
2318
+ type: "function"
2319
+ },
2320
+ {
2321
+ constant: true,
2322
+ inputs: [],
2323
+ name: "totalSupply",
2324
+ outputs: [
2325
+ {
2326
+ name: "",
2327
+ type: "uint256"
2328
+ }
2329
+ ],
2330
+ payable: false,
2331
+ stateMutability: "view",
2332
+ type: "function"
2333
+ },
2334
+ {
2335
+ constant: false,
2336
+ inputs: [
2337
+ {
2338
+ name: "src",
2339
+ type: "address"
2340
+ },
2341
+ {
2342
+ name: "dst",
2343
+ type: "address"
2344
+ },
2345
+ {
2346
+ name: "wad",
2347
+ type: "uint256"
2348
+ }
2349
+ ],
2350
+ name: "transferFrom",
2351
+ outputs: [
2352
+ {
2353
+ name: "",
2354
+ type: "bool"
2355
+ }
2356
+ ],
2357
+ payable: false,
2358
+ stateMutability: "nonpayable",
2359
+ type: "function"
2360
+ },
2361
+ {
2362
+ constant: false,
2363
+ inputs: [
2364
+ {
2365
+ name: "wad",
2366
+ type: "uint256"
2367
+ }
2368
+ ],
2369
+ name: "withdraw",
2370
+ outputs: [],
2371
+ payable: false,
2372
+ stateMutability: "nonpayable",
2373
+ type: "function"
2374
+ },
2375
+ {
2376
+ constant: true,
2377
+ inputs: [],
2378
+ name: "decimals",
2379
+ outputs: [
2380
+ {
2381
+ name: "",
2382
+ type: "uint8"
2383
+ }
2384
+ ],
2385
+ payable: false,
2386
+ stateMutability: "view",
2387
+ type: "function"
2388
+ },
2389
+ {
2390
+ constant: true,
2391
+ inputs: [
2392
+ {
2393
+ name: "",
2394
+ type: "address"
2395
+ }
2396
+ ],
2397
+ name: "balanceOf",
2398
+ outputs: [
2399
+ {
2400
+ name: "",
2401
+ type: "uint256"
2402
+ }
2403
+ ],
2404
+ payable: false,
2405
+ stateMutability: "view",
2406
+ type: "function"
2407
+ },
2408
+ {
2409
+ constant: true,
2410
+ inputs: [],
2411
+ name: "symbol",
2412
+ outputs: [
2413
+ {
2414
+ name: "",
2415
+ type: "string"
2416
+ }
2417
+ ],
2418
+ payable: false,
2419
+ stateMutability: "view",
2420
+ type: "function"
2421
+ },
2422
+ {
2423
+ constant: false,
2424
+ inputs: [
2425
+ {
2426
+ name: "dst",
2427
+ type: "address"
2428
+ },
2429
+ {
2430
+ name: "wad",
2431
+ type: "uint256"
2432
+ }
2433
+ ],
2434
+ name: "transfer",
2435
+ outputs: [
2436
+ {
2437
+ name: "",
2438
+ type: "bool"
2439
+ }
2440
+ ],
2441
+ payable: false,
2442
+ stateMutability: "nonpayable",
2443
+ type: "function"
2444
+ },
2445
+ {
2446
+ constant: false,
2447
+ inputs: [],
2448
+ name: "deposit",
2449
+ outputs: [],
2450
+ payable: true,
2451
+ stateMutability: "payable",
2452
+ type: "function"
2453
+ },
2454
+ {
2455
+ constant: true,
2456
+ inputs: [
2457
+ {
2458
+ name: "",
2459
+ type: "address"
2460
+ },
2461
+ {
2462
+ name: "",
2463
+ type: "address"
2464
+ }
2465
+ ],
2466
+ name: "allowance",
2467
+ outputs: [
2468
+ {
2469
+ name: "",
2470
+ type: "uint256"
2471
+ }
2472
+ ],
2473
+ payable: false,
2474
+ stateMutability: "view",
2475
+ type: "function"
2476
+ },
2477
+ {
2478
+ payable: true,
2479
+ stateMutability: "payable",
2480
+ type: "fallback"
2481
+ },
2482
+ {
2483
+ anonymous: false,
2484
+ inputs: [
2485
+ {
2486
+ indexed: true,
2487
+ name: "src",
2488
+ type: "address"
2489
+ },
2490
+ {
2491
+ indexed: true,
2492
+ name: "guy",
2493
+ type: "address"
2494
+ },
2495
+ {
2496
+ indexed: false,
2497
+ name: "wad",
2498
+ type: "uint256"
2499
+ }
2500
+ ],
2501
+ name: "Approval",
2502
+ type: "event"
2503
+ },
2504
+ {
2505
+ anonymous: false,
2506
+ inputs: [
2507
+ {
2508
+ indexed: true,
2509
+ name: "src",
2510
+ type: "address"
2511
+ },
2512
+ {
2513
+ indexed: true,
2514
+ name: "dst",
2515
+ type: "address"
2516
+ },
2517
+ {
2518
+ indexed: false,
2519
+ name: "wad",
2520
+ type: "uint256"
2521
+ }
2522
+ ],
2523
+ name: "Transfer",
2524
+ type: "event"
2525
+ },
2526
+ {
2527
+ anonymous: false,
2528
+ inputs: [
2529
+ {
2530
+ indexed: true,
2531
+ name: "dst",
2532
+ type: "address"
2533
+ },
2534
+ {
2535
+ indexed: false,
2536
+ name: "wad",
2537
+ type: "uint256"
2538
+ }
2539
+ ],
2540
+ name: "Deposit",
2541
+ type: "event"
2542
+ },
2543
+ {
2544
+ anonymous: false,
2545
+ inputs: [
2546
+ {
2547
+ indexed: true,
2548
+ name: "src",
2549
+ type: "address"
2550
+ },
2551
+ {
2552
+ indexed: false,
2553
+ name: "wad",
2554
+ type: "uint256"
2555
+ }
2556
+ ],
2557
+ name: "Withdrawal",
2558
+ type: "event"
2559
+ }
2560
+ ];
2561
+ var WrapToken__factory = class {
2562
+ static abi = _abi4;
2563
+ static createInterface() {
2564
+ return new Interface7(_abi4);
2565
+ }
2566
+ static connect(address, runner) {
2567
+ return new Contract7(address, _abi4, runner);
2568
+ }
2569
+ };
2570
+
2571
+ // src/contracts/index.ts
2572
+ var Erc20 = Erc20__factory.createInterface();
2573
+
2574
+ // src/core/platform/AbstractedPlatform.ts
2575
+ import { CurrencyAmount as CurrencyAmount4, Price } from "@uniswap/sdk-core";
2576
+ import get5 from "lodash/get";
2577
+ import isEmpty2 from "lodash/isEmpty";
2578
+ import BigNumber3 from "bignumber.js";
2579
+ import isNil4 from "lodash/isNil";
2580
+
2581
+ // src/internals/utils/address.ts
2582
+ var normalizeAddress = (address, blockchain) => {
2583
+ if (blockchain === "solana") {
2584
+ return address;
2585
+ }
2586
+ if (address.startsWith("0x")) {
2587
+ return address.toLowerCase();
2588
+ }
2589
+ return address;
2590
+ };
2591
+
2592
+ // src/core/platform/AbstractedPlatform.ts
2593
+ var Noop = () => Promise.resolve(void 0);
2594
+ var AbstractedPlatform = class extends CoreDexShared {
2595
+ tokenFactory = {
2596
+ ["evm" /* EVM */]: (payload) => new DexToken(payload),
2597
+ ["solana" /* SOLANA */]: (payload) => new SolanaDexToken(payload)
2598
+ };
2599
+ isCustom = false;
2600
+ constructor() {
2601
+ super();
2602
+ }
2603
+ use(coredex) {
2604
+ super.use(coredex);
2605
+ return this;
2606
+ }
2607
+ createDexCurrency(payload) {
2608
+ const _payload = { ...payload };
2609
+ if (payload.standard === "native" || this.isNativeAddress(get5(payload, "address", ""))) {
2610
+ _payload.address = this.nativeAddress;
2611
+ return NativeCurrency.onChain(_payload);
2612
+ }
2613
+ return this.tokenFactory[this.blockchain](_payload);
2614
+ }
2615
+ isNativeAddress(tokenAddress) {
2616
+ try {
2617
+ return tokenAddress === this.nativeAddress;
2618
+ } catch (error) {
2619
+ console.error(
2620
+ `failed to check if {${tokenAddress}/${this.nativeAddress}} is native address`,
2621
+ error
2622
+ );
2623
+ return false;
2624
+ }
2625
+ }
2626
+ getNativeCurrency(chainId) {
2627
+ const chainConfig = this.coredex.getChainConfig(chainId);
2628
+ return NativeCurrency.onChain({
2629
+ chainId,
2630
+ address: this.nativeAddress,
2631
+ decimals: chainConfig.nativeToken.decimals,
2632
+ symbol: chainConfig.nativeToken.symbol,
2633
+ name: chainConfig.nativeToken.name,
2634
+ standard: "native"
2635
+ });
2636
+ }
2637
+ async getAccount(baseAddress) {
2638
+ try {
2639
+ const accounts = await this.coredex.dependencies.getAccounts(baseAddress);
2640
+ if (!Array.isArray(accounts) || accounts.length === 0) {
2641
+ throw new Error(`cannot retrieve account list`);
2642
+ }
2643
+ const baseAccount = accounts.find(
2644
+ (account2) => normalizeAddress(account2.address) === normalizeAddress(baseAddress)
2645
+ );
2646
+ if (!baseAccount)
2647
+ throw new Error(
2648
+ `missing ${this.blockchain} account (baseAddress: ${baseAddress})`
2649
+ );
2650
+ if (baseAccount.type === "PRIVATE_KEY" /* PRIVATE_KEY */) {
2651
+ return baseAccount;
2652
+ }
2653
+ const account = accounts.find(
2654
+ (account2) => account2.index === baseAccount.index && account2.blockchain === this.blockchain
2655
+ );
2656
+ if (!account)
2657
+ throw new Error(
2658
+ `missing ${this.blockchain} account (baseAddress: ${baseAddress})`
2659
+ );
2660
+ return account;
2661
+ } catch (error) {
2662
+ console.error(
2663
+ `failed to get ${this.blockchain} account (baseAddress: ${baseAddress})`
2664
+ );
2665
+ throw error;
2666
+ }
2667
+ }
2668
+ async buildQuote(quote, _options) {
2669
+ const payload = quote.__origin.payload;
2670
+ const builts = await this.coredex.aggregator.build({
2671
+ chainId: payload.currencyIn.chainId,
2672
+ chainIdOut: payload.currencyOut.chainId,
2673
+ provider: quote.provider,
2674
+ sender: payload.account,
2675
+ recipient: payload.account,
2676
+ calldataBuilder: quote.calldataBuilder,
2677
+ slippageToleranceBps: payload.slippageToleranceBps
2678
+ });
2679
+ if (!Array.isArray(builts)) throw new Error("invalid built routes response");
2680
+ return builts;
2681
+ }
2682
+ async computeQuote(quote) {
2683
+ const params = quote.__origin.payload;
2684
+ const exactIn = params.direction === "exactIn";
2685
+ const exactOut = params.direction === "exactOut";
2686
+ const parsedAmount = CurrencyAmount4.fromRawAmount(
2687
+ exactIn ? params.currencyIn : params.currencyOut,
2688
+ params.amount
2689
+ );
2690
+ const amounts = {
2691
+ ["tokenIn" /* TokenIn */]: exactIn ? parsedAmount : quote.amountIn,
2692
+ ["tokenOut" /* TokenOut */]: exactOut ? parsedAmount : quote.amountOut
2693
+ };
2694
+ const maximumAmountIn = computeMaximumAmountIn(
2695
+ quote.amountIn,
2696
+ params.slippageToleranceBps
2697
+ );
2698
+ const minimumAmountOut = computeMinimumAmountOut(
2699
+ quote.amountOut,
2700
+ params.slippageToleranceBps
2701
+ );
2702
+ const executionPrice = new Price(
2703
+ quote.amountIn.currency,
2704
+ quote.amountOut.currency,
2705
+ quote.amountIn.quotient,
2706
+ quote.amountOut.quotient
2707
+ );
2708
+ const worstExecutionPrice = new Price(
2709
+ quote.amountIn.currency,
2710
+ quote.amountOut.currency,
2711
+ maximumAmountIn.quotient,
2712
+ minimumAmountOut.quotient
2713
+ );
2714
+ const aggregatedQuote = {
2715
+ amounts,
2716
+ maximumAmountIn,
2717
+ minimumAmountOut,
2718
+ executionPrice,
2719
+ worstExecutionPrice,
2720
+ ...this.getDefaultQuote(quote)
2721
+ };
2722
+ return Promise.resolve(aggregatedQuote);
2723
+ }
2724
+ getDefaultQuote(quote) {
2725
+ const defaultQuote = {
2726
+ __origin: quote.__origin,
2727
+ quoteId: "",
2728
+ chainId: quote.chainId,
2729
+ provider: quote.provider,
2730
+ addressIn: quote.addressIn,
2731
+ addressOut: quote.addressOut,
2732
+ currencyIn: quote.currencyIn,
2733
+ currencyOut: quote.currencyOut,
2734
+ amountIn: quote.amountIn,
2735
+ amountOut: quote.amountOut,
2736
+ amountInUsd: quote.amountInUsd,
2737
+ amountOutUsd: quote.amountOutUsd,
2738
+ calldataBuilder: quote.calldataBuilder,
2739
+ permit2Address: quote.permit2Address,
2740
+ universalRouterAddress: quote.universalRouterAddress,
2741
+ routes: quote.routes,
2742
+ priceImpact: quote.priceImpact,
2743
+ extraFee: quote.extraFee,
2744
+ getAllocatedFee: Noop,
2745
+ getNetworkFees: Noop
2746
+ };
2747
+ defaultQuote.quoteId = getQuoteUuid(quote);
2748
+ defaultQuote.getAllocatedFee = () => this.getAllocatedFee(defaultQuote);
2749
+ defaultQuote.getNetworkFees = () => this.getNetworkFees(defaultQuote);
2750
+ return defaultQuote;
2751
+ }
2752
+ async getAllocatedFee(quote) {
2753
+ const developmentFee = await this.computeDevelopmentFee(quote);
2754
+ const allocatedFee = {
2755
+ totalFeeUsd: developmentFee?.amountUsd,
2756
+ allocation: [developmentFee]
2757
+ };
2758
+ return allocatedFee;
2759
+ }
2760
+ computeDevelopmentFee(quote) {
2761
+ try {
2762
+ const extraFee = get5(quote, "extraFee");
2763
+ if (!extraFee || isEmpty2(extraFee)) throw new Error("invalid extra fee");
2764
+ const amount = get5(extraFee, "amount");
2765
+ if (!amount || isNil4(amount)) throw new Error("invalid amount");
2766
+ const amountUsd = get5(extraFee, "amountUsd");
2767
+ const totalFeeUsd = !isNil4(amountUsd) ? new BigNumber3(amountUsd) : void 0;
2768
+ const currency = this.createDexCurrency({
2769
+ chainId: quote.chainId,
2770
+ decimals: extraFee.token.decimal,
2771
+ symbol: extraFee.token.symbol,
2772
+ name: extraFee.token.name,
2773
+ standard: extraFee.token.token_standard,
2774
+ address: extraFee.token.address,
2775
+ logoUrl: extraFee.token.logo_uri,
2776
+ tags: extraFee.token.tags
2777
+ });
2778
+ return Promise.resolve({
2779
+ type: "development",
2780
+ percent: get5(extraFee, "percentage"),
2781
+ amountUsd: totalFeeUsd,
2782
+ amount: CurrencyAmount4.fromRawAmount(currency, amount)
2783
+ });
2784
+ } catch (error) {
2785
+ console.error("cannot compute development fee:", error);
2786
+ return Promise.resolve(void 0);
2787
+ }
2788
+ }
2789
+ };
2790
+ var AbstractedPlatform_default = AbstractedPlatform;
2791
+
2792
+ // src/core/platform/EVM/AbstractedEVM.ts
2793
+ import isNil5 from "lodash/isNil";
2794
+
2795
+ // src/internals/utils/ethers-error.ts
2796
+ import get6 from "lodash/get";
2797
+ import isEmpty3 from "lodash/isEmpty";
2798
+ var STRIP_PATTERN = / \([^)]*=/;
2799
+ function strip(message) {
2800
+ if (message === "") return message;
2801
+ const match = message.match(STRIP_PATTERN);
2802
+ if (match && match.index !== void 0) {
2803
+ message = message.slice(0, match.index);
2804
+ }
2805
+ const trimmed = message.trim();
2806
+ if (isEmpty3(trimmed)) return message;
2807
+ return trimmed.charAt(0).toUpperCase() + trimmed.slice(1);
2808
+ }
2809
+ function typedEtherError(error) {
2810
+ const code = get6(error, "code", "UNKNOWN_ERROR" /* UNKNOWN_ERROR */);
2811
+ const message = strip(get6(error, "message", ""));
2812
+ return { code, message, error };
2813
+ }
2814
+
2815
+ // src/core/platform/EVM/GasEstimator.ts
2816
+ import { isAddress } from "ethers";
2817
+ import BigNumber4 from "bignumber.js";
2818
+ import isEmpty4 from "lodash/isEmpty";
2819
+ import get7 from "lodash/get";
2820
+
2821
+ // src/schema/networkFee.ts
2822
+ import { z as z3 } from "zod";
2823
+ var $legacyFee = z3.object({ gas_price: z3.string().nullish() }).transform((data) => ({ gasPrice: data.gas_price }));
2824
+ var $eip1559 = z3.object({
2825
+ base_fee_per_gas: z3.string().nullish(),
2826
+ max_fee_per_gas: z3.string().nullish(),
2827
+ max_priority_fee_per_gas: z3.string().nullish()
2828
+ }).transform((data) => ({
2829
+ baseFeePerGas: data.base_fee_per_gas,
2830
+ maxFeePerGas: data.max_fee_per_gas,
2831
+ maxPriorityFeePerGas: data.max_priority_fee_per_gas
2832
+ }));
2833
+ var $sharedSuggestItemBase = z3.object({
2834
+ chain_name: z3.string(),
2835
+ exact_base_fee: z3.string().nullish(),
2836
+ base_fee_per_gas: z3.string().nullish()
2837
+ });
2838
+ var $networkFeeSuggestion = z3.discriminatedUnion("type", [
2839
+ z3.object({ type: z3.literal("legacy") }).merge(
2840
+ z3.object({
2841
+ low: $legacyFee.nullish(),
2842
+ medium: $legacyFee.nullish(),
2843
+ high: $legacyFee.nullish()
2844
+ })
2845
+ ).merge($sharedSuggestItemBase),
2846
+ z3.object({ type: z3.literal("eip-1559") }).merge(
2847
+ z3.object({
2848
+ low: $eip1559.nullish(),
2849
+ medium: $eip1559.nullish(),
2850
+ high: $eip1559.nullish()
2851
+ })
2852
+ ).merge($sharedSuggestItemBase)
2853
+ ]).transform(({ chain_name, exact_base_fee, base_fee_per_gas, ...data }) => {
2854
+ if (data.type === "eip-1559") {
2855
+ if (data.low) data.low.baseFeePerGas = base_fee_per_gas;
2856
+ if (data.medium) data.medium.baseFeePerGas = base_fee_per_gas;
2857
+ if (data.high) data.high.baseFeePerGas = base_fee_per_gas;
2858
+ }
2859
+ return {
2860
+ chainName: chain_name,
2861
+ exactBaseFee: exact_base_fee,
2862
+ ...data
2863
+ };
2864
+ });
2865
+
2866
+ // src/core/platform/EVM/GasEstimator.ts
2867
+ var DEFAULT_LEGACY_FEE_DATA = { gasPrice: "2000000000" };
2868
+ var GasEstimator = class {
2869
+ constructor(coredex) {
2870
+ this.coredex = coredex;
2871
+ }
2872
+ async compute(tx, options) {
2873
+ try {
2874
+ if (!tx.chainId) throw new Error("chainId is required");
2875
+ if (!tx.data) throw new Error("data is required");
2876
+ if (!isAddress(tx.from) || !isAddress(tx.to)) {
2877
+ throw new Error("from/to address is invalid");
2878
+ }
2879
+ const gasLimit = await this.estimate(tx);
2880
+ if (!isEmpty4(options?.networkFee)) {
2881
+ return { ...tx, ...options.networkFee, gasLimit };
2882
+ }
2883
+ const feeData = await this.getFeeData(Number(tx.chainId));
2884
+ return { ...tx, ...feeData, gasLimit };
2885
+ } catch (error) {
2886
+ console.error("error populating transaction: ", error);
2887
+ throw error;
2888
+ }
2889
+ }
2890
+ async estimate(tx, options) {
2891
+ try {
2892
+ delete tx.gasLimit;
2893
+ delete tx.gasPrice;
2894
+ delete tx.maxFeePerGas;
2895
+ delete tx.maxPriorityFeePerGas;
2896
+ const chainId = chainIdToNumber(tx.chainId);
2897
+ const provider = this.coredex.platform.fromChainId(chainId).getProvider(chainId);
2898
+ const gasLimit = await provider.estimateGas(tx);
2899
+ if (!gasLimit) throw new Error("invalid gas estimation");
2900
+ return gasLimit.toString();
2901
+ } catch (error) {
2902
+ const typedError = typedEtherError(error);
2903
+ if (typedError.code === "CALL_EXCEPTION" && options?.bypassApproval === true) {
2904
+ return await this.estimateWithApprovalBypass(tx);
2905
+ }
2906
+ console.error("estimating gas limit failed:", error);
2907
+ return DEFAULT_GAS_LIMIT;
2908
+ }
2909
+ }
2910
+ /**
2911
+ * Estimate gas limit with approval bypass for displaying network fee purpose
2912
+ * @param tx - Transaction request
2913
+ * @returns Bypassing approval estimation gas limit
2914
+ */
2915
+ async estimateWithApprovalBypass(tx) {
2916
+ try {
2917
+ const txData = tx.data || "0x";
2918
+ const dataLength = txData.length;
2919
+ let complexityMultiplier = 1;
2920
+ if (dataLength > 1e3) complexityMultiplier = 1.2;
2921
+ if (dataLength > 2e3) complexityMultiplier = 1.4;
2922
+ if (dataLength > 4e3) complexityMultiplier = 1.6;
2923
+ const estimatedGas = new BigNumber4(DEFAULT_SWAP_GAS_LIMIT).multipliedBy(complexityMultiplier).multipliedBy(1.1).toFixed(0);
2924
+ return estimatedGas;
2925
+ } catch (error) {
2926
+ console.error("enhanced estimation failed:", error);
2927
+ return DEFAULT_SWAP_GAS_LIMIT;
2928
+ }
2929
+ }
2930
+ async getFeeData(chainId, feeLevel = "medium" /* Medium */) {
2931
+ try {
2932
+ const data = await this.suggestion(chainId);
2933
+ return get7(data, feeLevel);
2934
+ } catch (error) {
2935
+ console.error("error getting fee suggestion: ", error);
2936
+ return this.getProviderFeeData(chainId);
2937
+ }
2938
+ }
2939
+ async suggestion(chainId) {
2940
+ const chainConfig = this.coredex.dependencies.providerManager.getChainConfigs().find((config) => config.chainId === chainId);
2941
+ if (!chainConfig) throw new Error("chain config not found");
2942
+ const response = await this.coredex.aggregator.api.get(
2943
+ `/proxy/public/v1/${chainConfig.chainName}/gas-suggestion`
2944
+ );
2945
+ const parsed = $networkFeeSuggestion.safeParse(response);
2946
+ if (!parsed.success) {
2947
+ console.error("invalid gas suggestion:", parsed.error);
2948
+ throw new Error("invalid gas suggestion");
2949
+ }
2950
+ return parsed.data;
2951
+ }
2952
+ async getProviderFeeData(chainId) {
2953
+ try {
2954
+ const provider = this.coredex.platform.fromChainId(chainId).getProvider(chainId);
2955
+ const feeData = await provider.getFeeData();
2956
+ if (feeData.gasPrice && !feeData.maxFeePerGas) {
2957
+ return { gasPrice: feeData.gasPrice.toString() };
2958
+ }
2959
+ if (feeData.maxFeePerGas) {
2960
+ const maxFeePerGas = feeData.maxFeePerGas.toString();
2961
+ const maxPriorityFeePerGas = feeData.maxPriorityFeePerGas?.toString() ?? "0";
2962
+ const baseFeePerGas = new BigNumber4(maxFeePerGas).minus(new BigNumber4(maxPriorityFeePerGas)).toString();
2963
+ return {
2964
+ maxFeePerGas,
2965
+ maxPriorityFeePerGas,
2966
+ baseFeePerGas
2967
+ };
2968
+ }
2969
+ return DEFAULT_LEGACY_FEE_DATA;
2970
+ } catch (error) {
2971
+ console.error("provider fee data failed: ", error);
2972
+ return DEFAULT_LEGACY_FEE_DATA;
2973
+ }
2974
+ }
2975
+ };
2976
+ var GasEstimator_default = GasEstimator;
2977
+
2978
+ // src/core/platform/EVM/Approval.ts
2979
+ import { createPermitObj } from "@sky-mavis/katana-swap";
2980
+ import { CurrencyAmount as CurrencyAmount5 } from "@uniswap/sdk-core";
2981
+ import { AllowanceTransfer } from "@uniswap/permit2-sdk";
2982
+ import { _TypedDataEncoder } from "@ethersproject/hash";
2983
+ import { BigNumber as BigNumber5 } from "@ethersproject/bignumber";
2984
+ import { MaxUint256 } from "ethers";
2985
+ import get8 from "lodash/get";
2986
+ var Approval = class {
2987
+ constructor(coredex) {
2988
+ this.coredex = coredex;
2989
+ }
2990
+ signatures = /* @__PURE__ */ new Map();
2991
+ async approve(quoteId, account, spender, token, amountInWei = MaxUint256.toString()) {
2992
+ try {
2993
+ const amount = CurrencyAmount5.fromRawAmount(token, amountInWei);
2994
+ this.coredex.notify(quoteId, {
2995
+ state: "approving-token" /* ApprovingToken */,
2996
+ data: { amount }
2997
+ });
2998
+ const chainId = amount.currency.chainId;
2999
+ const platform = this.coredex.platform.fromChainId(
3000
+ chainId
3001
+ );
3002
+ const signer = await platform.invokeSigner(
3003
+ amount.currency.chainId,
3004
+ account
3005
+ );
3006
+ const contract = Erc20__factory.connect(amount.currency.address, signer);
3007
+ const params = [spender, amount.quotient.toString()];
3008
+ const calldata = Erc20.encodeFunctionData("approve", params);
3009
+ const populatedTx = await platform.populateTransaction({
3010
+ chainId,
3011
+ from: account,
3012
+ to: amount.currency.address,
3013
+ data: calldata
3014
+ });
3015
+ const response = await contract.approve(...params, {
3016
+ gasLimit: populatedTx.gasLimit,
3017
+ maxFeePerGas: populatedTx.maxFeePerGas,
3018
+ maxPriorityFeePerGas: populatedTx.maxPriorityFeePerGas
3019
+ });
3020
+ if (response) {
3021
+ const confirmationBlocks = this.coredex.confirmationBlocks(chainId);
3022
+ const provider = platform.getProvider(chainId);
3023
+ const receipt = await provider?.waitForTransaction(
3024
+ response.hash,
3025
+ confirmationBlocks
3026
+ );
3027
+ const status = receipt ? get8(receipt, "status", 0) : 0;
3028
+ this.coredex.notify(quoteId, {
3029
+ state: status === 1 ? "approved-token" /* ApprovedToken */ : "approve-token-failed" /* ApproveTokenFailed */
3030
+ });
3031
+ }
3032
+ return response;
3033
+ } catch (error) {
3034
+ this.coredex.notify(quoteId, {
3035
+ state: "approve-token-failed" /* ApproveTokenFailed */,
3036
+ error: typedEtherError(error)
3037
+ });
3038
+ console.error("approve error: ", error);
3039
+ throw error;
3040
+ }
3041
+ }
3042
+ async allowance(account, amount, approveSpender) {
3043
+ try {
3044
+ const chainId = amount.currency.chainId;
3045
+ const tokenAddress = amount.currency.address;
3046
+ const platform = this.coredex.platform.fromChainId(
3047
+ chainId
3048
+ );
3049
+ const contract = Erc20__factory.connect(
3050
+ tokenAddress,
3051
+ platform.getProvider(chainId)
3052
+ );
3053
+ const rawAllowance = await contract.allowance(account, approveSpender);
3054
+ return CurrencyAmount5.fromRawAmount(
3055
+ amount.currency,
3056
+ rawAllowance.toString()
3057
+ );
3058
+ } catch (error) {
3059
+ console.error("get allowance error: ", error);
3060
+ throw error;
3061
+ }
3062
+ }
3063
+ async getPermitAllowance(chainId, account, amount, permitRouter, permitSpender) {
3064
+ const platform = this.coredex.platform.fromChainId(chainId);
3065
+ const contract = Permit2__factory.connect(
3066
+ permitRouter,
3067
+ platform.getProvider(chainId)
3068
+ );
3069
+ const [amountInWei, expiration, nonce] = await contract.allowance(
3070
+ account,
3071
+ amount.currency.address,
3072
+ permitSpender
3073
+ );
3074
+ return [
3075
+ CurrencyAmount5.fromRawAmount(amount.currency, amountInWei.toString()),
3076
+ BigNumber5.from(expiration).toNumber(),
3077
+ BigNumber5.from(nonce).toNumber()
3078
+ ];
3079
+ }
3080
+ async signPermitSignature(quote, amount, nonce) {
3081
+ try {
3082
+ const chainId = amount.currency.chainId;
3083
+ const tokenAddress = amount.currency.address;
3084
+ const platform = this.coredex.platform.fromChainId(
3085
+ chainId
3086
+ );
3087
+ const signer = await platform.invokeSigner(
3088
+ chainId,
3089
+ quote.__origin.payload.account
3090
+ );
3091
+ const permit = createPermitObj({
3092
+ chainId,
3093
+ token: tokenAddress,
3094
+ nonce,
3095
+ spender: quote.universalRouterAddress
3096
+ });
3097
+ const permitData = AllowanceTransfer.getPermitData(
3098
+ permit,
3099
+ quote.permit2Address,
3100
+ chainId
3101
+ );
3102
+ const populated = await _TypedDataEncoder.resolveNames(
3103
+ permitData.domain,
3104
+ permitData.types,
3105
+ permitData.values,
3106
+ (name) => signer.resolveName(name)
3107
+ );
3108
+ const message = JSON.stringify(
3109
+ _TypedDataEncoder.getPayload(
3110
+ populated.domain,
3111
+ permitData.types,
3112
+ populated.value
3113
+ )
3114
+ );
3115
+ this.coredex.notify(quote.quoteId, {
3116
+ state: "signing-permit" /* SigningPermit */,
3117
+ data: { message }
3118
+ });
3119
+ const signature = await signer.signTypedDataV4(message);
3120
+ const permitSignature = { ...permit, signature };
3121
+ this.signatures.set(
3122
+ this.createPermitSigId(quote.__origin.payload),
3123
+ permitSignature
3124
+ );
3125
+ this.coredex.notify(quote.quoteId, {
3126
+ state: "signed-permit" /* SignedPermit */
3127
+ });
3128
+ return permitSignature;
3129
+ } catch (error) {
3130
+ this.coredex.notify(quote.quoteId, {
3131
+ state: "sign-permit-failed" /* SignPermitFailed */,
3132
+ error
3133
+ });
3134
+ throw error;
3135
+ }
3136
+ }
3137
+ createPermitSigId(params) {
3138
+ return [
3139
+ params.account,
3140
+ params.currencyIn.chainId,
3141
+ params.currencyIn.address
3142
+ ].join("#");
3143
+ }
3144
+ getPermitSignature(quote) {
3145
+ const signatureId = this.createPermitSigId(quote.__origin.payload);
3146
+ return this.signatures.get(signatureId);
3147
+ }
3148
+ };
3149
+ var Approval_default = Approval;
3150
+
3151
+ // src/utils/error.ts
3152
+ function normalizeError(error) {
3153
+ if (error instanceof Error) {
3154
+ return error;
3155
+ }
3156
+ if (typeof error === "string") {
3157
+ return new Error(error);
3158
+ }
3159
+ if (error && typeof error === "object" && "message" in error && typeof error.message === "string") {
3160
+ return new Error(error.message);
3161
+ }
3162
+ return new Error(String(error));
3163
+ }
3164
+
3165
+ // src/core/platform/EVM/AbstractedEVM.ts
3166
+ var AVERAGE_RONIN_L1_BLOCK_TIME = 3e3;
3167
+ var AbstractedEVM = class extends AbstractedPlatform_default {
3168
+ blockchain = "evm" /* EVM */;
3169
+ name = `abstracted-${this.blockchain}`;
3170
+ nativeAddress = NATIVE_ADDRESS;
3171
+ approval;
3172
+ gas;
3173
+ constructor() {
3174
+ super();
3175
+ }
3176
+ use(coredex) {
3177
+ super.use(coredex);
3178
+ this.initiate();
3179
+ this.approval = new Approval_default(this.useCoreDex());
3180
+ this.gas = new GasEstimator_default(this.useCoreDex());
3181
+ return this;
3182
+ }
3183
+ _initiated = false;
3184
+ initiate() {
3185
+ try {
3186
+ if (this._initiated) return;
3187
+ for (const wrapToken of Object.values(EVM_WETH9)) {
3188
+ WRAPPED_TOKENS.set(
3189
+ wrapToken.chainId,
3190
+ new DexToken({
3191
+ chainId: wrapToken.chainId,
3192
+ address: wrapToken.address,
3193
+ decimals: wrapToken.decimals,
3194
+ symbol: wrapToken.symbol,
3195
+ name: wrapToken.name,
3196
+ standard: "erc20"
3197
+ })
3198
+ );
3199
+ }
3200
+ this._initiated = true;
3201
+ } catch (error) {
3202
+ console.error(
3203
+ `failed to initiate ${this.blockchain} wrapped tokens`,
3204
+ error
3205
+ );
3206
+ throw error;
3207
+ }
3208
+ }
3209
+ getProvider(chainId) {
3210
+ const provider = this.coredex.dependencies.providerManager.getProvider(
3211
+ chainId
3212
+ );
3213
+ if (!provider) throw new Error(`missing provider (chainId: ${chainId})`);
3214
+ return provider;
3215
+ }
3216
+ async getSigner(address) {
3217
+ const signer = await this.coredex.dependencies.getSignerForAddress(address);
3218
+ if (!signer) throw new Error(`missing signer (address: ${address})`);
3219
+ return signer;
3220
+ }
3221
+ async invokeSigner(chainId, fromAddress) {
3222
+ const signer = await this.getSigner(fromAddress);
3223
+ return signer.connect(this.getProvider(chainId));
3224
+ }
3225
+ async authorize(quote) {
3226
+ try {
3227
+ const amount = "maximumAmountIn" in quote && quote.maximumAmountIn?.currency.isToken ? quote.maximumAmountIn : "amounts" in quote && quote.amounts?.["tokenIn" /* TokenIn */]?.currency.isToken ? quote.amounts["tokenIn" /* TokenIn */] : void 0;
3228
+ if (!amount || !quote.permit2Address) {
3229
+ return Promise.resolve(void 0);
3230
+ }
3231
+ const chainId = amount.currency.chainId;
3232
+ if (amount.currency.isNative || amount.currency.address === NATIVE_ADDRESS) {
3233
+ this.coredex.notify(quote.quoteId, {
3234
+ state: "authorized" /* Authorized */
3235
+ });
3236
+ return Promise.resolve(void 0);
3237
+ }
3238
+ this.coredex.notify(quote.quoteId, {
3239
+ state: "authorizing" /* Authorizing */
3240
+ });
3241
+ const account = quote.__origin.payload.account;
3242
+ const allowance = await this.approval.allowance(
3243
+ account,
3244
+ amount,
3245
+ quote.permit2Address
3246
+ );
3247
+ const approved = allowance.greaterThan(amount) || allowance.equalTo(amount);
3248
+ let signed = false;
3249
+ let permitted = false;
3250
+ let signature = this.approval.getPermitSignature(quote);
3251
+ if (quote.provider !== "kyberswap") {
3252
+ const [permitAllowance, permitExpiration, nonce] = await this.approval.getPermitAllowance(
3253
+ chainId,
3254
+ account,
3255
+ amount,
3256
+ quote.permit2Address,
3257
+ quote.universalRouterAddress
3258
+ );
3259
+ const now = Math.floor(
3260
+ (Date.now() + AVERAGE_RONIN_L1_BLOCK_TIME) / 1e3
3261
+ );
3262
+ if (typeof signature === "object") {
3263
+ signed = signature.details.token === amount.currency.address && signature.spender === quote.universalRouterAddress && signature.sigDeadline >= now;
3264
+ }
3265
+ permitted = (permitAllowance.greaterThan(amount) || permitAllowance.equalTo(amount)) && permitExpiration >= now;
3266
+ if (!approved) {
3267
+ await this.approval.approve(
3268
+ quote.quoteId,
3269
+ account,
3270
+ quote.permit2Address,
3271
+ amount.currency
3272
+ );
3273
+ }
3274
+ const shouldSignPermit = !(permitted || signed);
3275
+ if (shouldSignPermit) {
3276
+ signature = await this.approval.signPermitSignature(
3277
+ quote,
3278
+ amount,
3279
+ nonce
3280
+ );
3281
+ signed = signature?.details?.token === amount.currency.address && signature?.spender === quote.universalRouterAddress && signature?.sigDeadline >= now;
3282
+ }
3283
+ } else if (!approved) {
3284
+ await this.approval.approve(
3285
+ quote.quoteId,
3286
+ account,
3287
+ quote.permit2Address,
3288
+ amount.currency
3289
+ );
3290
+ }
3291
+ this.coredex.notify(quote.quoteId, {
3292
+ state: "authorized" /* Authorized */
3293
+ });
3294
+ return !permitted && signed ? signature : void 0;
3295
+ } catch (error) {
3296
+ this.coredex.notify(quote.quoteId, {
3297
+ state: "authorize-failed" /* AuthorizeFailed */,
3298
+ error
3299
+ });
3300
+ console.error(`[${quote.provider}] authorize failed:`, error);
3301
+ throw error;
3302
+ }
3303
+ }
3304
+ async balanceOf(chainId, baseAddress, tokenAddress) {
3305
+ try {
3306
+ const account = await this.getAccount(baseAddress);
3307
+ if (this.isNativeAddress(tokenAddress)) {
3308
+ return await this.nativeBalanceOf(chainId, account.address);
3309
+ }
3310
+ const contract = Erc20__factory.connect(
3311
+ tokenAddress,
3312
+ this.getProvider(chainId)
3313
+ );
3314
+ return await contract.balanceOf(account.address);
3315
+ } catch (error) {
3316
+ console.error(`Error getting balance for ${tokenAddress}:`, error);
3317
+ throw error;
3318
+ }
3319
+ }
3320
+ async batchBalanceOf(chainId, account, tokenAddresses, callLimit = 100) {
3321
+ const results = {};
3322
+ const nativeTokens = tokenAddresses.filter(
3323
+ (address) => this.isNativeAddress(address)
3324
+ );
3325
+ const erc20Tokens = tokenAddresses.filter(
3326
+ (address) => !this.isNativeAddress(address)
3327
+ );
3328
+ if (nativeTokens.length > 0) {
3329
+ const nativeBalance = await this.nativeBalanceOf(chainId, account);
3330
+ for (const nativeToken of nativeTokens) {
3331
+ results[nativeToken] = nativeBalance;
3332
+ }
3333
+ }
3334
+ if (erc20Tokens.length > 0) {
3335
+ const erc20Balances = await this.multicallErc20Balances(
3336
+ chainId,
3337
+ account,
3338
+ erc20Tokens,
3339
+ callLimit
3340
+ );
3341
+ Object.assign(results, erc20Balances);
3342
+ }
3343
+ return results;
3344
+ }
3345
+ async buildQuote(quote) {
3346
+ await this.authorize(quote);
3347
+ const payload = quote.__origin.payload;
3348
+ const builts = await super.buildQuote(quote);
3349
+ return builts.map((built) => ({
3350
+ chainId: payload.currencyIn.chainId,
3351
+ from: payload.account,
3352
+ ...built
3353
+ }));
3354
+ }
3355
+ async populateTransaction(tx) {
3356
+ return await this.gas.compute(tx);
3357
+ }
3358
+ async getNetworkFees(quote, options) {
3359
+ try {
3360
+ const totalGasLimit = await this.estimateGasLimit(quote, {
3361
+ ...options,
3362
+ bypassApproval: true
3363
+ });
3364
+ const nativeCurrency = this.getNativeCurrency(quote.chainId);
3365
+ if (!nativeCurrency) throw new Error("cannot get native currency");
3366
+ const networkFees = [];
3367
+ const gasSuggestion = await this.gas.suggestion(quote.chainId);
3368
+ for (const [key, feeData] of Object.entries(gasSuggestion)) {
3369
+ if (!["low", "medium", "high"].includes(key) || isNil5(feeData)) {
3370
+ continue;
3371
+ }
3372
+ const networkCostInWei = computeNetworkCost(
3373
+ feeData,
3374
+ totalGasLimit.toString()
3375
+ );
3376
+ if (!networkCostInWei) {
3377
+ this.coredex.console.warn("cannot compute network cost:", {
3378
+ origin: {
3379
+ feeData,
3380
+ totalGasLimit
3381
+ }
3382
+ });
3383
+ continue;
3384
+ }
3385
+ const amount = new BigNumber6(
3386
+ formatUnits(networkCostInWei.toString(), nativeCurrency.decimals)
3387
+ );
3388
+ networkFees.push({
3389
+ amount,
3390
+ feeData,
3391
+ level: key,
3392
+ currency: nativeCurrency
3393
+ });
3394
+ }
3395
+ return networkFees;
3396
+ } catch (error) {
3397
+ console.error(
3398
+ `cannot get network fee (chainId: ${quote.chainId}):`,
3399
+ error
3400
+ );
3401
+ return void 0;
3402
+ }
3403
+ }
3404
+ async sendTransaction(chainId, from, txRequest, options) {
3405
+ try {
3406
+ const account = await this.getAccount(from);
3407
+ const fromAddress = account.address;
3408
+ if (!isAddress2(fromAddress)) throw new Error("invalid from address");
3409
+ const computedTx = await this.gas.compute(txRequest, {
3410
+ networkFee: options?.networkFee
3411
+ });
3412
+ this.coredex.console.info(
3413
+ `[${this.name}] sending transaction -> `,
3414
+ computedTx
3415
+ );
3416
+ const signer = await this.invokeSigner(chainId, fromAddress);
3417
+ const txResponse = await signer.sendTransaction(computedTx);
3418
+ options?.onSubmitted?.(txResponse);
3419
+ if (!options?.waitForReceipt) return txResponse;
3420
+ options?.onWaitingForReceipt?.(txResponse);
3421
+ const confirmationBlocks = this.coredex.confirmationBlocks(chainId);
3422
+ const provider = this.getProvider(chainId);
3423
+ const receipt = await provider?.waitForTransaction(
3424
+ txResponse.hash,
3425
+ confirmationBlocks
3426
+ );
3427
+ if (receipt && receipt.status === 1) options?.onSuccess?.(receipt);
3428
+ else
3429
+ throw new Error(
3430
+ `network cannot confirm transaction [${txResponse.hash}]`
3431
+ );
3432
+ return txResponse;
3433
+ } catch (error) {
3434
+ options?.onFailure?.(error);
3435
+ const normalizedError = normalizeError(error);
3436
+ const enhancedError = new Error(
3437
+ `Transaction failed: ${normalizedError.message}`
3438
+ );
3439
+ if (normalizedError instanceof Error && normalizedError.stack) {
3440
+ enhancedError.stack = normalizedError.stack;
3441
+ }
3442
+ throw enhancedError;
3443
+ }
3444
+ }
3445
+ async sendBatchTransaction(chainId, from, txRequests, { onSuccess, onFailure, ...options } = {}) {
3446
+ const responses = [];
3447
+ for (let index = 0; index < txRequests.length; index++) {
3448
+ try {
3449
+ const txRequest = txRequests[index];
3450
+ const isLastCall = index === txRequests.length - 1;
3451
+ const txResponse = await this.sendTransaction(
3452
+ chainId,
3453
+ from,
3454
+ txRequest,
3455
+ !isLastCall ? options : { ...options, onSuccess, onFailure }
3456
+ );
3457
+ responses.push(txResponse);
3458
+ } catch (error) {
3459
+ const normalizedError = normalizeError(error);
3460
+ const enhancedError = new Error(
3461
+ `Transaction ${index + 1}/${txRequests.length} failed: ${normalizedError.message}`
3462
+ );
3463
+ if (normalizedError instanceof Error && normalizedError.stack) {
3464
+ enhancedError.stack = normalizedError.stack;
3465
+ }
3466
+ throw enhancedError;
3467
+ }
3468
+ }
3469
+ return responses;
3470
+ }
3471
+ async multicallErc20Balances(chainId, baseAddress, tokenAddresses, callLimit) {
3472
+ const account = await this.getAccount(baseAddress);
3473
+ const multicallContract = Multicall2__factory.connect(
3474
+ MULTICALL3_ROUTER,
3475
+ this.getProvider(chainId)
3476
+ );
3477
+ const totalPages = Math.ceil(tokenAddresses.length / callLimit);
3478
+ const multicallPromises = [];
3479
+ for (let page = 0; page < totalPages; page++) {
3480
+ const pageTokens = tokenAddresses.slice(
3481
+ page * callLimit,
3482
+ (page + 1) * callLimit
3483
+ );
3484
+ const calls = pageTokens.map((tokenAddress) => ({
3485
+ target: tokenAddress,
3486
+ callData: Erc20.encodeFunctionData("balanceOf", [account.address])
3487
+ }));
3488
+ multicallPromises.push(
3489
+ multicallContract.tryAggregate.staticCall(false, calls)
3490
+ );
3491
+ }
3492
+ const multicallResults = await Promise.all(multicallPromises);
3493
+ const results = {};
3494
+ let tokenIndex = 0;
3495
+ for (const batchResults of multicallResults) {
3496
+ for (const result of batchResults) {
3497
+ const tokenAddress = tokenAddresses[tokenIndex];
3498
+ try {
3499
+ if (result.success && result.returnData && result.returnData !== "0x") {
3500
+ const decoded = Erc20.decodeFunctionResult(
3501
+ "balanceOf",
3502
+ result.returnData
3503
+ );
3504
+ results[tokenAddress] = decoded[0];
3505
+ } else {
3506
+ results[tokenAddress] = 0n;
3507
+ }
3508
+ } catch (error) {
3509
+ console.error(`Error decoding balance for ${tokenAddress}:`, error);
3510
+ results[tokenAddress] = 0n;
3511
+ }
3512
+ tokenIndex++;
3513
+ }
3514
+ }
3515
+ return results;
3516
+ }
3517
+ async gasSuggestion(chainId) {
3518
+ return await this.gas.suggestion(chainId);
3519
+ }
3520
+ async estimateGasLimit(quote, options) {
3521
+ try {
3522
+ const txs = await this.buildQuote(quote);
3523
+ const promises = txs.map((tx) => this.gas.estimate(tx, options));
3524
+ const gasLimits = await Promise.all(promises);
3525
+ return gasLimits.reduce(
3526
+ (accumulator, gasLimit) => accumulator.add(EthersBigNumber2.from(gasLimit)),
3527
+ EthersBigNumber2.from(0)
3528
+ );
3529
+ } catch (error) {
3530
+ this.coredex.console.warn("cannot estimate gas limit:", error);
3531
+ return EthersBigNumber2.from(DEFAULT_GAS_LIMIT);
3532
+ }
3533
+ }
3534
+ async nativeBalanceOf(chainId, baseAddress) {
3535
+ const account = await this.getAccount(baseAddress);
3536
+ return await this.getProvider(chainId).getBalance(account.address);
3537
+ }
3538
+ async wrap(baseAddress, amount, options) {
3539
+ try {
3540
+ options?.onHandling?.();
3541
+ const account = await this.getAccount(baseAddress);
3542
+ const wrappedToken = WRAPPED_TOKENS.get(amount.currency.chainId);
3543
+ const signer = await this.invokeSigner(
3544
+ amount.currency.chainId,
3545
+ account.address
3546
+ );
3547
+ const contract = WrapToken__factory.connect(wrappedToken.address, signer);
3548
+ const txRequest = {
3549
+ chainId: wrappedToken.chainId,
3550
+ from: account.address,
3551
+ to: wrappedToken.address,
3552
+ data: contract.interface.encodeFunctionData("deposit"),
3553
+ value: `0x${amount.quotient.toString(16)}`
3554
+ };
3555
+ const populatedTx = await this.gas.compute(txRequest);
3556
+ const txResponse = await contract.deposit({
3557
+ value: `0x${amount.quotient.toString(16)}`,
3558
+ gasLimit: populatedTx.gasLimit,
3559
+ maxFeePerGas: populatedTx.maxFeePerGas,
3560
+ maxPriorityFeePerGas: populatedTx.maxPriorityFeePerGas
3561
+ });
3562
+ const receipt = await this.getProvider(
3563
+ wrappedToken.chainId
3564
+ )?.waitForTransaction(txResponse.hash);
3565
+ if (receipt.status === 1) options?.onSuccess?.(receipt);
3566
+ return txResponse;
3567
+ } catch (error) {
3568
+ console.error("wrap error:", error);
3569
+ options?.onFailure?.(error);
3570
+ throw error;
3571
+ }
3572
+ }
3573
+ async unwrap(baseAddress, amount, options) {
3574
+ try {
3575
+ options?.onHandling?.();
3576
+ const account = await this.getAccount(baseAddress);
3577
+ const wrappedToken = WRAPPED_TOKENS.get(amount.currency.chainId);
3578
+ const signer = await this.invokeSigner(
3579
+ amount.currency.chainId,
3580
+ account.address
3581
+ );
3582
+ const contract = WrapToken__factory.connect(wrappedToken.address, signer);
3583
+ const value = `0x${amount.quotient.toString(16)}`;
3584
+ const txRequest = {
3585
+ to: wrappedToken.address,
3586
+ from: account.address,
3587
+ chainId: wrappedToken.chainId,
3588
+ data: contract.interface.encodeFunctionData("withdraw", [value])
3589
+ };
3590
+ const populatedTx = await this.gas.compute(txRequest);
3591
+ const txResponse = await contract.withdraw(value, {
3592
+ gasLimit: populatedTx.gasLimit,
3593
+ maxFeePerGas: populatedTx.maxFeePerGas,
3594
+ maxPriorityFeePerGas: populatedTx.maxPriorityFeePerGas
3595
+ });
3596
+ const receipt = await this.getProvider(
3597
+ wrappedToken.chainId
3598
+ ).waitForTransaction(txResponse.hash);
3599
+ if (receipt.status === 1) options?.onSuccess?.(receipt);
3600
+ return txResponse;
3601
+ } catch (error) {
3602
+ console.error("unwrap error:", error);
3603
+ options?.onFailure?.(error);
3604
+ throw error;
3605
+ }
3606
+ }
3607
+ };
3608
+ var AbstractedEVM_default = AbstractedEVM;
3609
+
3610
+ // src/core/platform/SVM/AbstractedSVM.ts
3611
+ import {
3612
+ PublicKey,
3613
+ Transaction,
3614
+ VersionedTransaction,
3615
+ SystemProgram,
3616
+ Keypair
3617
+ } from "@solana/web3.js";
3618
+
3619
+ // src/core/platform/SVM/@solana/spl-token.ts
3620
+ var splTokenLoader;
3621
+ var splToken;
3622
+ var loadSplToken = () => {
3623
+ if (!splTokenLoader) {
3624
+ splTokenLoader = import("@solana/spl-token").then((module) => {
3625
+ splToken = module;
3626
+ return module;
3627
+ }).catch((error) => {
3628
+ console.error("failed to import @solana/spl-token", error);
3629
+ throw error;
3630
+ });
3631
+ }
3632
+ return splTokenLoader;
3633
+ };
3634
+ loadSplToken();
3635
+ var get9 = () => {
3636
+ if (!splToken) {
3637
+ throw new Error(
3638
+ "@solana/spl-token is not loaded yet. Ensure the module is initialized before use."
3639
+ );
3640
+ }
3641
+ return splToken;
3642
+ };
3643
+ var NATIVE_MINT = () => get9().NATIVE_MINT;
3644
+ var TOKEN_PROGRAM_ID = () => get9().TOKEN_PROGRAM_ID;
3645
+ var TOKEN_2022_PROGRAM_ID = () => get9().TOKEN_2022_PROGRAM_ID;
3646
+ var getAssociatedTokenAddress = (mint, owner, allowOwnerOffCurve, programId, associatedTokenProgramId) => get9().getAssociatedTokenAddress(
3647
+ mint,
3648
+ owner,
3649
+ allowOwnerOffCurve,
3650
+ programId,
3651
+ associatedTokenProgramId
3652
+ );
3653
+ var createSyncNativeInstruction = (account, programId) => get9().createSyncNativeInstruction(account, programId);
3654
+ var createCloseAccountInstruction = (account, destination, authority, multiSigners, programId) => get9().createCloseAccountInstruction(
3655
+ account,
3656
+ destination,
3657
+ authority,
3658
+ multiSigners,
3659
+ programId
3660
+ );
3661
+ var createAssociatedTokenAccountInstruction = (payer, associatedToken, owner, mint, programId, associatedTokenProgramId) => get9().createAssociatedTokenAccountInstruction(
3662
+ payer,
3663
+ associatedToken,
3664
+ owner,
3665
+ mint,
3666
+ programId,
3667
+ associatedTokenProgramId
3668
+ );
3669
+ var createTransferInstruction = (source, destination, owner, amount, multiSigners, programId) => get9().createTransferInstruction(
3670
+ source,
3671
+ destination,
3672
+ owner,
3673
+ amount,
3674
+ multiSigners,
3675
+ programId
3676
+ );
3677
+
3678
+ // src/core/platform/SVM/AbstractedSVM.ts
3679
+ import get10 from "lodash/get";
3680
+ import BigNumber7 from "bignumber.js";
3681
+ var SVM_NATIVE_ADDRESS = "11111111111111111111111111111111";
3682
+ var WAIT_FOR_TX_MAX_RETRIES = 60;
3683
+ var RETRY_INTERVALMS = 1e3;
3684
+ var AbstractedSVM = class extends AbstractedPlatform_default {
3685
+ blockchain = "solana" /* SOLANA */;
3686
+ name = `abstracted-${this.blockchain}`;
3687
+ nativeAddress = SVM_NATIVE_ADDRESS;
3688
+ constructor() {
3689
+ super();
3690
+ }
3691
+ use(coredex) {
3692
+ super.use(coredex);
3693
+ this.initiate();
3694
+ return this;
3695
+ }
3696
+ _initiated = false;
3697
+ initiate() {
3698
+ try {
3699
+ if (this._initiated) return;
3700
+ const solConfig = this.coredex.getAllChainConfigs().find((config) => config.blockchain === "solana" /* SOLANA */);
3701
+ if (!solConfig) {
3702
+ throw new Error(`missing chain config (blockchain: ${this.blockchain})`);
3703
+ }
3704
+ this.nativeAddress = get10(
3705
+ solConfig,
3706
+ "nativeTokenAddress",
3707
+ SVM_NATIVE_ADDRESS
3708
+ );
3709
+ try {
3710
+ WRAPPED_TOKENS.set(
3711
+ solConfig.chainId,
3712
+ new SolanaDexToken({
3713
+ chainId: solConfig.chainId,
3714
+ address: NATIVE_MINT().toString(),
3715
+ decimals: solConfig.nativeToken.decimals,
3716
+ symbol: solConfig.nativeToken.symbol,
3717
+ name: solConfig.nativeToken.name,
3718
+ standard: "erc20"
3719
+ })
3720
+ );
3721
+ } catch (error) {
3722
+ if (error?.message?.includes("not loaded yet")) {
3723
+ loadSplToken().then(() => {
3724
+ try {
3725
+ WRAPPED_TOKENS.set(
3726
+ solConfig.chainId,
3727
+ new SolanaDexToken({
3728
+ chainId: solConfig.chainId,
3729
+ address: NATIVE_MINT().toString(),
3730
+ decimals: solConfig.nativeToken.decimals,
3731
+ symbol: solConfig.nativeToken.symbol,
3732
+ name: solConfig.nativeToken.name,
3733
+ standard: "erc20"
3734
+ })
3735
+ );
3736
+ } catch (err) {
3737
+ console.error(
3738
+ `failed to set wrapped token for ${this.blockchain} after module load`,
3739
+ err
3740
+ );
3741
+ }
3742
+ });
3743
+ } else {
3744
+ throw error;
3745
+ }
3746
+ }
3747
+ this._initiated = true;
3748
+ } catch (error) {
3749
+ console.error(`failed to initiate ${this.blockchain} platform`, error);
3750
+ throw error;
3751
+ }
3752
+ }
3753
+ getProvider(chainId) {
3754
+ if (!chainId) {
3755
+ const chainConfig = this.coredex.getAllChainConfigs().find((config) => config.blockchain === this.blockchain);
3756
+ if (!chainConfig) {
3757
+ throw new Error(`missing chain config (blockchain: ${this.blockchain})`);
3758
+ }
3759
+ chainId = chainConfig.chainId;
3760
+ }
3761
+ const provider = this.coredex.dependencies.providerManager.getProvider(chainId);
3762
+ if (!provider) throw new Error(`missing provider (chainId: ${chainId})`);
3763
+ return provider;
3764
+ }
3765
+ async getSigner(address) {
3766
+ const account = await this.getAccount(address);
3767
+ const signer = await this.coredex.dependencies.getSignerForAddress(
3768
+ account.address
3769
+ );
3770
+ if (!signer) throw new Error(`missing signer (address: ${address})`);
3771
+ return signer;
3772
+ }
3773
+ async invokeSigner(chainId, fromAddress) {
3774
+ const provider = this.getProvider(chainId);
3775
+ const signer = await this.getSigner(fromAddress);
3776
+ return signer.connect(provider);
3777
+ }
3778
+ async buildQuote(quote) {
3779
+ const builts = await super.buildQuote(quote);
3780
+ return builts.map((built) => this.populateTransaction(get10(built, "data")));
3781
+ }
3782
+ async wrap(baseAccount, amount, options) {
3783
+ try {
3784
+ options?.onHandling?.();
3785
+ const account = await this.getAccount(baseAccount);
3786
+ const signer = await this.invokeSigner(
3787
+ amount.currency.chainId,
3788
+ account.address
3789
+ );
3790
+ const ownerAccount = new PublicKey(account.address);
3791
+ const wSolAccount = await this.wSolAccount(account.address);
3792
+ const accountInfo = await this.getAccountInfo(wSolAccount);
3793
+ const lamports = BigInt(amount.quotient.toString());
3794
+ const transaction = new Transaction();
3795
+ if (!accountInfo) {
3796
+ transaction.add(
3797
+ createAssociatedTokenAccountInstruction(
3798
+ ownerAccount,
3799
+ wSolAccount,
3800
+ ownerAccount,
3801
+ NATIVE_MINT(),
3802
+ TOKEN_PROGRAM_ID()
3803
+ )
3804
+ );
3805
+ }
3806
+ transaction.add(
3807
+ SystemProgram.transfer({
3808
+ fromPubkey: ownerAccount,
3809
+ toPubkey: wSolAccount,
3810
+ lamports: Number(lamports)
3811
+ })
3812
+ );
3813
+ transaction.add(
3814
+ createSyncNativeInstruction(wSolAccount, TOKEN_PROGRAM_ID())
3815
+ );
3816
+ transaction.feePayer = ownerAccount;
3817
+ transaction.recentBlockhash = (await this.getLatestBlockhash(amount.currency.chainId)).blockhash;
3818
+ const txHash = await signer.sendTransaction(transaction);
3819
+ options?.onSubmitted?.(txHash);
3820
+ if (!options?.waitForReceipt) return txHash;
3821
+ options?.onWaitingForReceipt?.(txHash);
3822
+ const receipt = await this.waitForReceipt(txHash);
3823
+ this.coredex.console.info("receipt", receipt);
3824
+ if (receipt.value.err) {
3825
+ const errorMessage = JSON.stringify(receipt.value.err);
3826
+ throw new Error(`Transaction confirmation failed: ${errorMessage}`);
3827
+ }
3828
+ options?.onSuccess?.(txHash);
3829
+ return txHash;
3830
+ } catch (error) {
3831
+ console.error(`${this.name} wrap error:`, error);
3832
+ options?.onFailure?.(error);
3833
+ throw error;
3834
+ }
3835
+ }
3836
+ async unwrap(baseAccount, amount, options) {
3837
+ try {
3838
+ options?.onHandling?.();
3839
+ const account = await this.getAccount(baseAccount);
3840
+ const signer = await this.invokeSigner(
3841
+ amount.currency.chainId,
3842
+ account.address
3843
+ );
3844
+ const wSolAccount = await this.wSolAccount(account.address);
3845
+ const accountInfo = await this.getAccountInfo(wSolAccount);
3846
+ if (!accountInfo) {
3847
+ throw new Error("wSOL account does not exist. Nothing to unwrap.");
3848
+ }
3849
+ const currentBalance = await this.getWSolBalance(account.address);
3850
+ const currentWSol = BigInt(currentBalance.value.amount);
3851
+ const unwrapAmount = BigInt(amount.quotient.toString());
3852
+ if (unwrapAmount < currentWSol) {
3853
+ return await this.handlePartialUnwrap(
3854
+ amount.currency.chainId,
3855
+ account,
3856
+ amount,
3857
+ options
3858
+ );
3859
+ }
3860
+ const transaction = new Transaction();
3861
+ const ownerAccount = new PublicKey(account.address);
3862
+ transaction.add(
3863
+ createCloseAccountInstruction(
3864
+ wSolAccount,
3865
+ ownerAccount,
3866
+ ownerAccount,
3867
+ [],
3868
+ TOKEN_PROGRAM_ID()
3869
+ )
3870
+ );
3871
+ transaction.feePayer = ownerAccount;
3872
+ transaction.recentBlockhash = (await this.getLatestBlockhash(amount.currency.chainId)).blockhash;
3873
+ const txHash = await signer.sendTransaction(transaction);
3874
+ options?.onSubmitted?.(txHash);
3875
+ if (!options?.waitForReceipt) return txHash;
3876
+ options?.onWaitingForReceipt?.(txHash);
3877
+ const receipt = await this.waitForReceipt(txHash);
3878
+ this.coredex.console.info("receipt", receipt);
3879
+ if (receipt.value.err) {
3880
+ const errorMessage = JSON.stringify(receipt.value.err);
3881
+ throw new Error(`Transaction confirmation failed: ${errorMessage}`);
3882
+ }
3883
+ options?.onSuccess?.(txHash);
3884
+ return txHash;
3885
+ } catch (error) {
3886
+ console.error(`${this.name} unwrap error:`, error);
3887
+ options?.onFailure?.(error);
3888
+ throw error;
3889
+ }
3890
+ }
3891
+ async sendTransaction(chainId, from, txRequest, options) {
3892
+ try {
3893
+ const signer = await this.invokeSigner(chainId, from);
3894
+ const txHash = await signer.sendTransaction(txRequest);
3895
+ options?.onSubmitted?.(txHash);
3896
+ if (!options?.waitForReceipt) return txHash;
3897
+ options?.onWaitingForReceipt?.(txHash);
3898
+ const receipt = await this.waitForReceipt(txHash);
3899
+ this.coredex.console.info("receipt", receipt);
3900
+ if (receipt.value.err) {
3901
+ const errorMessage = JSON.stringify(receipt.value.err);
3902
+ throw new Error(`Transaction confirmation failed: ${errorMessage}`);
3903
+ }
3904
+ options?.onSuccess?.(txHash);
3905
+ return txHash;
3906
+ } catch (error) {
3907
+ options?.onFailure?.(error);
3908
+ const normalizedError = normalizeError(error);
3909
+ const enhancedError = new Error(
3910
+ `Transaction failed: ${normalizedError.message}`
3911
+ );
3912
+ if (normalizedError instanceof Error && normalizedError.stack) {
3913
+ enhancedError.stack = normalizedError.stack;
3914
+ }
3915
+ throw enhancedError;
3916
+ }
3917
+ }
3918
+ async sendBatchTransaction(chainId, from, txRequests, { onSuccess, onFailure, ...options } = {}) {
3919
+ const txHashes = [];
3920
+ for (let index = 0; index < txRequests.length; index++) {
3921
+ try {
3922
+ const txRequest = txRequests[index];
3923
+ const isLastCall = index === txRequests.length - 1;
3924
+ const txHash = await this.sendTransaction(
3925
+ chainId,
3926
+ from,
3927
+ txRequest,
3928
+ !isLastCall ? options : { ...options, onSuccess, onFailure }
3929
+ );
3930
+ txHashes.push(txHash);
3931
+ } catch (error) {
3932
+ const normalizedError = normalizeError(error);
3933
+ const enhancedError = new Error(
3934
+ `Transaction failed: ${normalizedError.message}`
3935
+ );
3936
+ if (normalizedError instanceof Error && normalizedError.stack) {
3937
+ enhancedError.stack = normalizedError.stack;
3938
+ }
3939
+ throw enhancedError;
3940
+ }
3941
+ }
3942
+ return txHashes;
3943
+ }
3944
+ async nativeBalanceOf(chainId, account) {
3945
+ const connection = this.getProvider(chainId);
3946
+ const publicKey = new PublicKey(account);
3947
+ const balance = await connection.getBalance(publicKey);
3948
+ return BigInt(balance);
3949
+ }
3950
+ async balanceOf(chainId, account, tokenAddress) {
3951
+ try {
3952
+ if (this.isNativeAddress(tokenAddress)) {
3953
+ return await this.nativeBalanceOf(chainId, account);
3954
+ }
3955
+ const connection = this.getProvider(chainId);
3956
+ const ownerPublicKey = new PublicKey(account);
3957
+ const mintPublicKey = new PublicKey(tokenAddress);
3958
+ const tokenProgramId = await this.getTokenProgramId(tokenAddress);
3959
+ const associatedTokenAddress = await getAssociatedTokenAddress(
3960
+ mintPublicKey,
3961
+ ownerPublicKey,
3962
+ false,
3963
+ tokenProgramId
3964
+ );
3965
+ const accountInfo = await connection.getAccountInfo(
3966
+ associatedTokenAddress
3967
+ );
3968
+ if (!accountInfo) {
3969
+ return 0n;
3970
+ }
3971
+ const tokenBalance = await connection.getTokenAccountBalance(
3972
+ associatedTokenAddress
3973
+ );
3974
+ return BigInt(tokenBalance.value.amount);
3975
+ } catch (error) {
3976
+ console.error(`Error getting balance for ${tokenAddress}:`, error);
3977
+ throw error;
3978
+ }
3979
+ }
3980
+ async batchBalanceOf(chainId, account, tokenAddresses) {
3981
+ const results = {};
3982
+ const nativeTokens = tokenAddresses.filter(
3983
+ (address) => this.isNativeAddress(address)
3984
+ );
3985
+ const splTokens = tokenAddresses.filter(
3986
+ (address) => !this.isNativeAddress(address)
3987
+ );
3988
+ if (nativeTokens.length > 0) {
3989
+ const nativeBalance = await this.nativeBalanceOf(chainId, account);
3990
+ for (const nativeToken of nativeTokens) {
3991
+ results[nativeToken] = nativeBalance;
3992
+ }
3993
+ }
3994
+ if (splTokens.length > 0) {
3995
+ const splBalances = await this.batchSplTokenBalances(
3996
+ chainId,
3997
+ account,
3998
+ splTokens
3999
+ );
4000
+ Object.assign(results, splBalances);
4001
+ }
4002
+ return results;
4003
+ }
4004
+ async getNetworkFees(quote) {
4005
+ try {
4006
+ const builts = await this.buildQuote(quote);
4007
+ if (!Array.isArray(builts)) {
4008
+ throw new Error("invalid built routes response");
4009
+ }
4010
+ const nativeCurrency = this.getNativeCurrency(quote.chainId);
4011
+ if (!nativeCurrency) throw new Error("cannot get native currency");
4012
+ const fees = await Promise.all(builts.map((tx) => this.computeTxFee(tx)));
4013
+ const totalFeeLamports = fees.reduce((sum, fee) => sum + (fee || 0), 0);
4014
+ this.coredex.console.info(
4015
+ `Total estimated fee: ${totalFeeLamports} lamports (${builts.length} transaction(s))`
4016
+ );
4017
+ const amount = new BigNumber7(totalFeeLamports).dividedBy(
4018
+ new BigNumber7(10).pow(nativeCurrency.decimals)
4019
+ );
4020
+ const networkFees = [
4021
+ {
4022
+ level: "medium" /* Medium */,
4023
+ amount,
4024
+ currency: nativeCurrency
4025
+ }
4026
+ ];
4027
+ return networkFees;
4028
+ } catch (error) {
4029
+ console.error(
4030
+ `cannot get network fee (chainId: ${quote.chainId}):`,
4031
+ error
4032
+ );
4033
+ return void 0;
4034
+ }
4035
+ }
4036
+ async getTransactionFeeFromTxHash(txHash) {
4037
+ try {
4038
+ const connection = this.getProvider();
4039
+ const parsedTx = await connection.getParsedTransaction(txHash, {
4040
+ maxSupportedTransactionVersion: 0
4041
+ });
4042
+ if (!parsedTx || !parsedTx.meta) {
4043
+ this.coredex.console.warn(
4044
+ `Transaction ${txHash} not found or has no meta`
4045
+ );
4046
+ return void 0;
4047
+ }
4048
+ return parsedTx.meta.fee;
4049
+ } catch (error) {
4050
+ console.error(`Error getting actual fee for tx ${txHash}:`, error);
4051
+ return void 0;
4052
+ }
4053
+ }
4054
+ async verifyNetworkFee(quote, txHash) {
4055
+ try {
4056
+ const estimatedFees = await this.getNetworkFees(quote);
4057
+ const estimatedFee = estimatedFees?.[0]?.amount;
4058
+ if (!estimatedFee) {
4059
+ throw new Error("Could not get estimated fee");
4060
+ }
4061
+ const actualFeeLamports = await this.getTransactionFeeFromTxHash(txHash);
4062
+ if (actualFeeLamports === void 0) {
4063
+ return {
4064
+ estimated: estimatedFee,
4065
+ actual: void 0,
4066
+ actualLamports: void 0,
4067
+ difference: void 0,
4068
+ match: false
4069
+ };
4070
+ }
4071
+ const nativeCurrency = this.getNativeCurrency(quote.chainId);
4072
+ if (!nativeCurrency) {
4073
+ throw new Error("cannot get native currency");
4074
+ }
4075
+ const actualFee = new BigNumber7(actualFeeLamports).dividedBy(
4076
+ new BigNumber7(10).pow(nativeCurrency.decimals)
4077
+ );
4078
+ const difference = estimatedFee.minus(actualFee);
4079
+ const match = difference.abs().isLessThan(new BigNumber7(1e-6));
4080
+ this.coredex.console.info("Fee verification:", {
4081
+ estimated: `${estimatedFee.toString()} SOL (${estimatedFee.multipliedBy(new BigNumber7(10).pow(nativeCurrency.decimals)).toString()} lamports)`,
4082
+ actual: `${actualFee.toString()} SOL (${actualFeeLamports} lamports)`,
4083
+ difference: `${difference.toString()} SOL`,
4084
+ match,
4085
+ txHash
4086
+ });
4087
+ return {
4088
+ estimated: estimatedFee,
4089
+ actual: actualFee,
4090
+ actualLamports: actualFeeLamports,
4091
+ difference,
4092
+ match
4093
+ };
4094
+ } catch (error) {
4095
+ console.error("Error verifying network fee:", error);
4096
+ throw error;
4097
+ }
4098
+ }
4099
+ async getAccountInfo(publicKey, commitmentOrConfig) {
4100
+ const connection = this.getProvider();
4101
+ return await connection.getAccountInfo(publicKey, commitmentOrConfig);
4102
+ }
4103
+ async wSolAccount(owner, targetMint = NATIVE_MINT()) {
4104
+ const wSolAccount = await getAssociatedTokenAddress(
4105
+ targetMint,
4106
+ new PublicKey(owner)
4107
+ );
4108
+ return wSolAccount;
4109
+ }
4110
+ async getWSolBalance(owner) {
4111
+ const connection = this.getProvider();
4112
+ const wSolAccount = await this.wSolAccount(owner);
4113
+ return await connection.getTokenAccountBalance(wSolAccount);
4114
+ }
4115
+ /**
4116
+ * Handle partial unwrap: create a temporary wSOL account, transfer the amount,
4117
+ * then close it to convert wSOL back to SOL.
4118
+ * This requires both the temporary owner and main owner to sign the transaction.
4119
+ */
4120
+ async handlePartialUnwrap(chainId, account, amount, options) {
4121
+ const partialUnwrapOwner = Keypair.generate();
4122
+ const partialWrapSolAccount = await getAssociatedTokenAddress(
4123
+ NATIVE_MINT(),
4124
+ partialUnwrapOwner.publicKey
4125
+ );
4126
+ const transaction = new Transaction();
4127
+ const connection = this.getProvider(chainId);
4128
+ const ownerAccount = new PublicKey(account.address);
4129
+ const rentLamports = await connection.getMinimumBalanceForRentExemption(0);
4130
+ transaction.add(
4131
+ SystemProgram.createAccount({
4132
+ fromPubkey: ownerAccount,
4133
+ newAccountPubkey: partialUnwrapOwner.publicKey,
4134
+ lamports: rentLamports,
4135
+ programId: SystemProgram.programId,
4136
+ space: 0
4137
+ })
4138
+ );
4139
+ const wSolAccount = await this.wSolAccount(
4140
+ account.address,
4141
+ new PublicKey(amount.currency.address)
4142
+ // "So11111111111111111111111111111111111111112"
4143
+ );
4144
+ transaction.add(
4145
+ createAssociatedTokenAccountInstruction(
4146
+ ownerAccount,
4147
+ partialWrapSolAccount,
4148
+ partialUnwrapOwner.publicKey,
4149
+ NATIVE_MINT(),
4150
+ TOKEN_PROGRAM_ID()
4151
+ )
4152
+ );
4153
+ transaction.add(
4154
+ createTransferInstruction(
4155
+ wSolAccount,
4156
+ partialWrapSolAccount,
4157
+ ownerAccount,
4158
+ BigInt(amount.quotient.toString()),
4159
+ [],
4160
+ TOKEN_PROGRAM_ID()
4161
+ )
4162
+ );
4163
+ transaction.add(
4164
+ createCloseAccountInstruction(
4165
+ partialWrapSolAccount,
4166
+ ownerAccount,
4167
+ // destination for the SOL
4168
+ partialUnwrapOwner.publicKey,
4169
+ // authority (owner of the token account)
4170
+ [],
4171
+ TOKEN_PROGRAM_ID()
4172
+ )
4173
+ );
4174
+ transaction.feePayer = ownerAccount;
4175
+ transaction.recentBlockhash = (await this.getLatestBlockhash(chainId)).blockhash;
4176
+ const bs58 = await import("bs58");
4177
+ const mainOwnerKeypair = Keypair.fromSecretKey(
4178
+ bs58.default.decode(account.privateKey)
4179
+ );
4180
+ transaction.sign(partialUnwrapOwner, mainOwnerKeypair);
4181
+ const txHash = await connection.sendRawTransaction(
4182
+ transaction.serialize(),
4183
+ { skipPreflight: false }
4184
+ );
4185
+ options?.onSubmitted?.(txHash);
4186
+ if (!options?.waitForReceipt) return txHash;
4187
+ options?.onWaitingForReceipt?.(txHash);
4188
+ const receipt = await this.waitForReceipt(txHash);
4189
+ this.coredex.console.info("receipt", receipt);
4190
+ if (receipt.value.err) {
4191
+ const errorMessage = JSON.stringify(receipt.value.err);
4192
+ throw new Error(`Transaction confirmation failed: ${errorMessage}`);
4193
+ }
4194
+ options?.onSuccess?.(txHash);
4195
+ return txHash;
4196
+ }
4197
+ async getLatestBlockhash(chainId) {
4198
+ const connection = this.getProvider(chainId);
4199
+ return await connection.getLatestBlockhash();
4200
+ }
4201
+ async getTokenProgramId(tokenAddress) {
4202
+ try {
4203
+ const accountInfo = await this.getAccountInfo(new PublicKey(tokenAddress));
4204
+ if (!accountInfo)
4205
+ throw new Error(`Token account not found for ${tokenAddress}`);
4206
+ const { owner } = accountInfo;
4207
+ if (owner.equals(TOKEN_PROGRAM_ID())) return TOKEN_PROGRAM_ID();
4208
+ if (owner.equals(TOKEN_2022_PROGRAM_ID())) return TOKEN_2022_PROGRAM_ID();
4209
+ return owner;
4210
+ } catch (error) {
4211
+ this.coredex.console.warn(
4212
+ `Error getting token program id for ${tokenAddress}:`,
4213
+ error
4214
+ );
4215
+ this.coredex.console.warn(
4216
+ `Using default token program id: ${TOKEN_PROGRAM_ID().toString()}`
4217
+ );
4218
+ return TOKEN_PROGRAM_ID();
4219
+ }
4220
+ }
4221
+ populateTransaction(signature) {
4222
+ if (!signature || typeof signature !== "string") {
4223
+ throw new Error(`invalid signature`);
4224
+ }
4225
+ const buffer = Buffer.from(signature, "base64");
4226
+ const uint8Array = new Uint8Array(buffer);
4227
+ try {
4228
+ return VersionedTransaction.deserialize(uint8Array);
4229
+ } catch (error) {
4230
+ return Transaction.from(buffer);
4231
+ }
4232
+ }
4233
+ async waitForReceipt(txHash) {
4234
+ const connection = this.getProvider();
4235
+ for (let attempt = 0; attempt < WAIT_FOR_TX_MAX_RETRIES; attempt++) {
4236
+ const response = await connection.getSignatureStatus(txHash, {
4237
+ searchTransactionHistory: true
4238
+ });
4239
+ const status = get10(response, "value");
4240
+ if (!status) {
4241
+ await sleepAsync(RETRY_INTERVALMS);
4242
+ continue;
4243
+ }
4244
+ if (status.err) {
4245
+ return { value: { err: status.err } };
4246
+ }
4247
+ if (status.confirmationStatus === "confirmed" || status.confirmationStatus === "finalized") {
4248
+ return { value: { status, err: null } };
4249
+ }
4250
+ await sleepAsync(RETRY_INTERVALMS);
4251
+ }
4252
+ throw new Error(
4253
+ `waitForReceipt timeout: signature ${txHash} was not confirmed within ${WAIT_FOR_TX_MAX_RETRIES * RETRY_INTERVALMS}ms`
4254
+ );
4255
+ }
4256
+ async computeTxFee(tx) {
4257
+ try {
4258
+ const connection = this.getProvider();
4259
+ if (tx instanceof VersionedTransaction && "message" in tx) {
4260
+ const fee2 = await connection.getFeeForMessage(tx.message);
4261
+ return fee2.value || 0;
4262
+ }
4263
+ const msg = tx.compileMessage();
4264
+ const fee = await connection.getFeeForMessage(msg);
4265
+ return fee.value || 0;
4266
+ } catch (error) {
4267
+ console.error("unable to compute tx fee", error);
4268
+ return 0;
4269
+ }
4270
+ }
4271
+ async batchSplTokenBalances(chainId, account, tokenAddresses) {
4272
+ const connection = this.getProvider(chainId);
4273
+ const ownerPublicKey = new PublicKey(account);
4274
+ const results = {};
4275
+ try {
4276
+ const associatedTokenAddresses = await Promise.all(
4277
+ tokenAddresses.map(async (tokenAddress) => {
4278
+ const mintPublicKey = new PublicKey(tokenAddress);
4279
+ const tokenProgramId = await this.getTokenProgramId(tokenAddress);
4280
+ return await getAssociatedTokenAddress(
4281
+ mintPublicKey,
4282
+ ownerPublicKey,
4283
+ false,
4284
+ tokenProgramId
4285
+ );
4286
+ })
4287
+ );
4288
+ const accountInfos = await connection.getMultipleAccountsInfo(
4289
+ associatedTokenAddresses
4290
+ );
4291
+ for (let i = 0; i < tokenAddresses.length; i++) {
4292
+ const tokenAddress = tokenAddresses[i];
4293
+ const accountInfo = accountInfos[i];
4294
+ try {
4295
+ if (!accountInfo) {
4296
+ results[tokenAddress] = 0n;
4297
+ } else {
4298
+ const tokenBalance = await connection.getTokenAccountBalance(
4299
+ associatedTokenAddresses[i]
4300
+ );
4301
+ results[tokenAddress] = BigInt(tokenBalance.value.amount);
4302
+ }
4303
+ } catch (error) {
4304
+ console.error(`Error decoding balance for ${tokenAddress}:`, error);
4305
+ results[tokenAddress] = 0n;
4306
+ }
4307
+ }
4308
+ } catch (error) {
4309
+ console.error("Error in batch SPL token balance fetch:", error);
4310
+ for (const tokenAddress of tokenAddresses) {
4311
+ try {
4312
+ results[tokenAddress] = await this.balanceOf(
4313
+ chainId,
4314
+ account,
4315
+ tokenAddress
4316
+ );
4317
+ } catch (err) {
4318
+ console.error(`Error getting balance for ${tokenAddress}:`, err);
4319
+ results[tokenAddress] = 0n;
4320
+ }
4321
+ }
4322
+ }
4323
+ return results;
4324
+ }
4325
+ };
4326
+ var AbstractedSVM_default = AbstractedSVM;
4327
+
4328
+ // src/core/platform/PlatformFactory.ts
4329
+ var PlatformFactory = class extends CoreDexShared {
4330
+ platform = /* @__PURE__ */ new Map();
4331
+ constructor() {
4332
+ super();
4333
+ }
4334
+ use(coredex) {
4335
+ super.use(coredex);
4336
+ const configuredBlockchains = new Set(
4337
+ this.coredex.getAllChainConfigs().map((c) => c.blockchain)
4338
+ );
4339
+ if (configuredBlockchains.has("evm" /* EVM */)) {
4340
+ if (!this.platform.has("evm" /* EVM */)) {
4341
+ this.platform.set("evm" /* EVM */, new AbstractedEVM_default());
4342
+ }
4343
+ }
4344
+ if (configuredBlockchains.has("solana" /* SOLANA */)) {
4345
+ if (!this.platform.has("solana" /* SOLANA */)) {
4346
+ this.platform.set("solana" /* SOLANA */, new AbstractedSVM_default());
4347
+ }
4348
+ }
4349
+ this.platform.forEach((platform) => platform.use(this.coredex));
4350
+ return this;
4351
+ }
4352
+ fromChainId(chainId) {
4353
+ const chainConfig = this.coredex.getChainConfig(chainId);
4354
+ const platform = this.platform.get(chainConfig.blockchain);
4355
+ if (!platform) {
4356
+ throw new Error(`missing platform (chainId: ${chainId})`);
4357
+ }
4358
+ return platform;
4359
+ }
4360
+ fromQuote(quote) {
4361
+ if (["katana" /* Katana */].includes(quote.provider) && quote.calldataBuilder.strategy === "uniswap_like") {
4362
+ return this.platform.get("katana" /* Katana */);
4363
+ }
4364
+ return this.fromChainId(quote.chainId);
4365
+ }
4366
+ };
4367
+ var PlatformFactory_default = PlatformFactory;
4368
+
4369
+ // src/core/CoreDex.ts
4370
+ import castArray from "lodash/castArray";
4371
+ import groupBy from "lodash/groupBy";
4372
+ import get11 from "lodash/get";
4373
+ var CoreDex = class {
4374
+ constructor(dependencies) {
4375
+ this.dependencies = dependencies;
4376
+ this.install_dependencies(dependencies);
4377
+ }
4378
+ aggregator = new Aggregator();
4379
+ platform = new PlatformFactory_default();
4380
+ updating = false;
4381
+ emitter = new TypedEventEmitter();
4382
+ install_dependencies(dependencies) {
4383
+ this.dependencies = dependencies;
4384
+ this.aggregator.use(this);
4385
+ this.platform.use(this);
4386
+ }
4387
+ async updateDependencies(dependencies) {
4388
+ this.updating = true;
4389
+ this.dependencies = { ...this.dependencies, ...dependencies };
4390
+ this.install_dependencies(this.dependencies);
4391
+ return Promise.resolve(this.updating = false);
4392
+ }
4393
+ getNativeAsset(chainId) {
4394
+ const chainConfigs = this.getChainConfig(chainId);
4395
+ return chainConfigs.nativeToken.symbol.toUpperCase();
4396
+ }
4397
+ getChainConfigId(chainConfig) {
4398
+ if (get11(chainConfig, "isCustom", false)) return chainConfig.rpcUrl;
4399
+ return String(chainConfig.chainId);
4400
+ }
4401
+ getAllChainConfigs() {
4402
+ return this.dependencies.providerManager.getChainConfigs();
4403
+ }
4404
+ getChainConfig(chainId) {
4405
+ const chainConfig = this.getAllChainConfigs().find(
4406
+ (chainConfig2) => chainConfig2.chainId === chainId
4407
+ );
4408
+ if (!chainConfig) throw new Error("chain config not found");
4409
+ return chainConfig;
4410
+ }
4411
+ createSignatureId(chainId, tokenAddress) {
4412
+ const chainConfig = this.getChainConfig(chainId);
4413
+ return createSignatureId(chainConfig.rpcUrl, tokenAddress);
4414
+ }
4415
+ confirmationBlocks(chainId) {
4416
+ if ([2020 /* RONIN */, 2021 /* SAIGON */].includes(chainId)) return 1;
4417
+ return void 0;
4418
+ }
4419
+ async mixedBalanceOf(ownerAddress, currencies) {
4420
+ const castedCurrencies = castArray(currencies);
4421
+ if (castedCurrencies.length === 1) {
4422
+ const chainId = castedCurrencies[0].chainId;
4423
+ const tokenAddress = castedCurrencies[0].address;
4424
+ const platform = this.platform.fromChainId(chainId);
4425
+ const account = await platform.getAccount(ownerAddress);
4426
+ const balance = await platform.balanceOf(
4427
+ chainId,
4428
+ account.address,
4429
+ tokenAddress
4430
+ );
4431
+ const singleBalance = {
4432
+ [chainId]: {
4433
+ [tokenAddress]: balance
4434
+ }
4435
+ };
4436
+ return singleBalance;
4437
+ }
4438
+ const groupedByChainId = Object.entries(
4439
+ groupBy(castedCurrencies, "chainId")
4440
+ );
4441
+ if (groupedByChainId.length === 0) {
4442
+ throw new Error("failed to batch balances (no currencies found)");
4443
+ }
4444
+ const balances = {};
4445
+ const promises = groupedByChainId.reduce(
4446
+ (accumulator, currency) => {
4447
+ try {
4448
+ const chainId = chainIdToNumber(get11(currency, "0"));
4449
+ const tokenAddresses = get11(currency, "1", []).map(
4450
+ (currency2) => currency2.address
4451
+ );
4452
+ if (tokenAddresses.length === 0) return accumulator;
4453
+ accumulator.push({
4454
+ chainId,
4455
+ getBalances: (address) => this.platform.fromChainId(chainId).batchBalanceOf(chainId, address, tokenAddresses)
4456
+ });
4457
+ return accumulator;
4458
+ } catch (error) {
4459
+ return accumulator;
4460
+ }
4461
+ },
4462
+ []
4463
+ );
4464
+ for await (const { chainId, getBalances } of promises) {
4465
+ const account = await this.platform.fromChainId(chainId).getAccount(ownerAddress);
4466
+ const rawBalances = await getBalances(account.address);
4467
+ balances[chainId] = rawBalances;
4468
+ }
4469
+ return balances;
4470
+ }
4471
+ notify(quoteId, event) {
4472
+ this.emitter.emit(quoteId, event);
4473
+ }
4474
+ get console() {
4475
+ const logger = {
4476
+ log: (..._args) => void 0,
4477
+ warn: (..._args) => void 0,
4478
+ info: (..._args) => void 0,
4479
+ error: (..._args) => void 0
4480
+ };
4481
+ if (!this.dependencies.debug) {
4482
+ return logger;
4483
+ }
4484
+ logger.log = (...args) => console.log(...args);
4485
+ logger.warn = (...args) => console.warn(...args);
4486
+ logger.info = (...args) => console.info(...args);
4487
+ logger.error = (...args) => console.error(...args);
4488
+ return logger;
4489
+ }
4490
+ };
4491
+
4492
+ // src/internals/types/signer.ts
4493
+ import { AbstractSigner } from "ethers";
4494
+
4495
+ // src/internals/types/provider.ts
4496
+ var TokenStandard = /* @__PURE__ */ ((TokenStandard2) => {
4497
+ TokenStandard2["ERC20"] = "erc20";
4498
+ TokenStandard2["NATIVE"] = "native";
4499
+ TokenStandard2["ERC721"] = "erc721";
4500
+ TokenStandard2["ERC1155"] = "erc1155";
4501
+ return TokenStandard2;
4502
+ })(TokenStandard || {});
4503
+
4504
+ // src/core/services/DexQuoteRacer.ts
4505
+ var DEFAULT_MAX_CONCURRENT_QUOTES = 5;
4506
+ var DEFAULT_QUOTE_TIMEOUT_MS = 1e4;
4507
+ var REACT_NATIVE_MAX_CONCURRENT_QUOTES = 3;
4508
+ var REACT_NATIVE_QUOTE_TIMEOUT_MS = 8e3;
4509
+ var getPlatformConfig = () => {
4510
+ const defaultConfig = {
4511
+ maxConcurrentQuotes: DEFAULT_MAX_CONCURRENT_QUOTES,
4512
+ quoteTimeoutMs: DEFAULT_QUOTE_TIMEOUT_MS,
4513
+ delayBetweenBatches: 0
4514
+ };
4515
+ if (isReactNative()) {
4516
+ defaultConfig.maxConcurrentQuotes = REACT_NATIVE_MAX_CONCURRENT_QUOTES;
4517
+ defaultConfig.quoteTimeoutMs = REACT_NATIVE_QUOTE_TIMEOUT_MS;
4518
+ }
4519
+ return defaultConfig;
4520
+ };
4521
+ var DexQuoteRacer = class {
4522
+ quoteTimeoutMs;
4523
+ maxConcurrentQuotes;
4524
+ delayBetweenBatches;
4525
+ constructor(config = getPlatformConfig()) {
4526
+ this.quoteTimeoutMs = config.quoteTimeoutMs;
4527
+ this.maxConcurrentQuotes = config.maxConcurrentQuotes;
4528
+ this.delayBetweenBatches = config.delayBetweenBatches;
4529
+ }
4530
+ async handle(items, processor, maxConcurrency = this.maxConcurrentQuotes) {
4531
+ const awaited = [];
4532
+ for (let i = 0; i < items.length; i += maxConcurrency) {
4533
+ const batch = items.slice(i, i + maxConcurrency);
4534
+ const promises = batch.map(
4535
+ (item, batchIndex) => this.raceAsync(processor(item, i + batchIndex), this.quoteTimeoutMs)
4536
+ );
4537
+ const results = await Promise.all(promises);
4538
+ awaited.push(...results);
4539
+ if (this.delayBetweenBatches > 0 && i + maxConcurrency < items.length) {
4540
+ await sleepAsync(this.delayBetweenBatches);
4541
+ }
4542
+ }
4543
+ return awaited;
4544
+ }
4545
+ raceAsync(promise, timeoutMs = this.quoteTimeoutMs, error = "operation timed out") {
4546
+ return Promise.race([
4547
+ promise,
4548
+ new Promise(
4549
+ (_, reject) => setTimeout(() => reject(new Error(error)), timeoutMs)
4550
+ )
4551
+ ]);
4552
+ }
4553
+ };
4554
+ var DexQuoteRacer_default = DexQuoteRacer;
4555
+
4556
+ // src/utils/simulate-wrap-quote.ts
4557
+ import { CurrencyAmount as CurrencyAmount6 } from "@uniswap/sdk-core";
4558
+ import isNil6 from "lodash/isNil";
4559
+ function simulateWrapQuote(payload) {
4560
+ try {
4561
+ const amountIn = CurrencyAmount6.fromRawAmount(
4562
+ payload.currencyIn,
4563
+ payload.amount
4564
+ );
4565
+ const amountOut = CurrencyAmount6.fromRawAmount(
4566
+ payload.currencyOut,
4567
+ payload.amount
4568
+ );
4569
+ const amounts = { ["tokenIn" /* TokenIn */]: amountIn, ["tokenOut" /* TokenOut */]: amountOut };
4570
+ const wrapInfo = getWrapType(payload.currencyIn, payload.currencyOut);
4571
+ const quote = {
4572
+ __origin: { payload },
4573
+ amounts,
4574
+ wrapInfo,
4575
+ quoteId: "",
4576
+ provider: "wrap",
4577
+ routes: [],
4578
+ chainId: payload.currencyIn.chainId,
4579
+ currencyIn: payload.currencyIn,
4580
+ currencyOut: payload.currencyOut,
4581
+ calldataBuilder: {},
4582
+ permit2Address: "",
4583
+ universalRouterAddress: "",
4584
+ isBestTrade: true,
4585
+ amountIn,
4586
+ amountOut,
4587
+ amountInUsd: void 0,
4588
+ amountOutUsd: void 0,
4589
+ priceImpact: void 0,
4590
+ extraFee: void 0,
4591
+ getAllocatedFee: async () => void 0,
4592
+ getNetworkFees: async () => void 0
4593
+ };
4594
+ quote.quoteId = getQuoteUuid(quote);
4595
+ return quote;
4596
+ } catch (error) {
4597
+ console.error("simulate wrap quote error: ", error);
4598
+ throw error;
4599
+ }
4600
+ }
4601
+ function shouldHandleWrap(quote) {
4602
+ return !isNil6(quote?.wrapInfo) && quote.wrapInfo.type !== "not-applicable" /* NOT_APPLICABLE */;
4603
+ }
4604
+
4605
+ // src/DexFactory.ts
4606
+ import castArray2 from "lodash/castArray";
4607
+ import groupBy2 from "lodash/groupBy";
4608
+ import isNil7 from "lodash/isNil";
4609
+ import get12 from "lodash/get";
4610
+ var DexFactory = class {
4611
+ constructor(coredex) {
4612
+ this.coredex = coredex;
4613
+ }
4614
+ racer = new DexQuoteRacer_default();
4615
+ setLocation(location) {
4616
+ this.coredex.aggregator.api.header("x-region-code", location);
4617
+ }
4618
+ async updateDeps(dependencies) {
4619
+ await this.coredex.updateDependencies(dependencies);
4620
+ }
4621
+ getCurrencySigil(currency) {
4622
+ return this.coredex.createSignatureId(currency.chainId, currency.address);
4623
+ }
4624
+ getNativeCurrency(chainId) {
4625
+ return this.coredex.platform.fromChainId(chainId).getNativeCurrency(chainId);
4626
+ }
4627
+ async balanceOf(account, currency) {
4628
+ const currencies = castArray2(currency);
4629
+ const groupedByChainId = Object.entries(groupBy2(currencies, "chainId"));
4630
+ if (groupedByChainId.length === 0) {
4631
+ throw new Error("no currencies provided");
4632
+ }
4633
+ const responses = await this.coredex.mixedBalanceOf(account, currencies);
4634
+ const flattened = Object.entries(responses);
4635
+ const ids = [];
4636
+ const data = {};
4637
+ for (const currency2 of currencies) {
4638
+ try {
4639
+ const sigil = this.coredex.createSignatureId(
4640
+ currency2.chainId,
4641
+ currency2.address
4642
+ );
4643
+ ids.push(sigil);
4644
+ const balances = flattened.find(
4645
+ ([chainId]) => chainIdToNumber(chainId) === currency2.chainId
4646
+ );
4647
+ data[sigil] = get12(balances, `1.${currency2.address}`, "0").toString();
4648
+ } catch (error) {
4649
+ console.error(error);
4650
+ continue;
4651
+ }
4652
+ }
4653
+ return { ids, data };
4654
+ }
4655
+ async getDexTokens(chainId, options) {
4656
+ return await this.coredex.aggregator.tokens(chainId, options);
4657
+ }
4658
+ async getQuotes(payload) {
4659
+ if (payload.slippageToleranceBps.lessThan(MIN_SLIPPAGE)) {
4660
+ throw new Error(
4661
+ "Slippage tolerance must be equal to or greater than 0.1%"
4662
+ );
4663
+ }
4664
+ if (payload.slippageToleranceBps.greaterThan(MAX_SLIPPAGE)) {
4665
+ throw new Error("Slippage tolerance must be equal to or less than 30%");
4666
+ }
4667
+ const wrapInfo = getWrapType(payload.currencyIn, payload.currencyOut);
4668
+ if (wrapInfo?.type !== "not-applicable" /* NOT_APPLICABLE */) {
4669
+ return Promise.resolve([simulateWrapQuote(payload)]);
4670
+ }
4671
+ const quotes = await this.coredex.aggregator.find(payload);
4672
+ const results = await this.racer.handle(quotes, async (quote) => {
4673
+ try {
4674
+ const platform = this.coredex.platform.fromQuote(quote);
4675
+ return await platform.computeQuote(quote);
4676
+ } catch (error) {
4677
+ console.error(error);
4678
+ return void 0;
4679
+ }
4680
+ });
4681
+ return sortQuotesByPriority(
4682
+ payload.direction,
4683
+ results.filter((result) => !isNil7(result))
4684
+ );
4685
+ }
4686
+ async build(quote, options) {
4687
+ return await this.coredex.platform.fromQuote(quote).buildQuote(quote, options);
4688
+ }
4689
+ async handle(quote, {
4690
+ waitForReceipt = true,
4691
+ ...options
4692
+ } = {}) {
4693
+ const getPayload = (response) => ({
4694
+ txHash: typeof response === "string" ? response : response.hash,
4695
+ amountIn: quote.amounts["tokenIn" /* TokenIn */],
4696
+ amountOut: quote.amounts["tokenOut" /* TokenOut */]
4697
+ });
4698
+ try {
4699
+ const platform = this.coredex.platform.fromQuote(quote);
4700
+ this.coredex.console.info(`[${platform.name}] handling transaction`);
4701
+ const handleOptions = {
4702
+ waitForReceipt,
4703
+ ...options
4704
+ };
4705
+ if (shouldHandleWrap(quote)) {
4706
+ const { method } = quote.wrapInfo;
4707
+ const amount = quote.amounts["tokenIn" /* TokenIn */];
4708
+ const response2 = await platform[method](
4709
+ quote.__origin.payload.account,
4710
+ amount,
4711
+ {
4712
+ ...handleOptions,
4713
+ onHandling: () => {
4714
+ this.coredex.notify(quote.quoteId, {
4715
+ state: quote.wrapInfo.type === "wrap" /* WRAP */ ? "wrapping" /* Wrapping */ : "unwrapping" /* Unwrapping */,
4716
+ data: { amount }
4717
+ });
4718
+ },
4719
+ onSuccess: () => {
4720
+ this.coredex.notify(quote.quoteId, {
4721
+ state: quote.wrapInfo.type === "wrap" /* WRAP */ ? "wrapped" /* Wrapped */ : "unwrapped" /* Unwrapped */,
4722
+ data: { amount }
4723
+ });
4724
+ }
4725
+ }
4726
+ );
4727
+ this.coredex.console.info("tx hash", get12(response2, "hash", response2));
4728
+ return response2;
4729
+ }
4730
+ this.coredex.notify(quote.quoteId, {
4731
+ state: "computing" /* Computing */
4732
+ });
4733
+ let permitSignature;
4734
+ if (platform instanceof AbstractedEVM_default && platform.blockchain === "evm" /* EVM */) {
4735
+ permitSignature = await platform.authorize(quote);
4736
+ }
4737
+ let response;
4738
+ const builts = await this.build(quote, { permitSignature });
4739
+ Object.assign(handleOptions, {
4740
+ onSubmitted: (response2) => {
4741
+ this.coredex.notify(quote.quoteId, {
4742
+ state: "transaction-submitted" /* TransactionSubmitted */,
4743
+ data: getPayload(response2)
4744
+ });
4745
+ },
4746
+ onWaitingForReceipt: (response2) => {
4747
+ this.coredex.notify(quote.quoteId, {
4748
+ state: "waiting-for-receipt" /* WaitingForReceipt */,
4749
+ data: getPayload(response2)
4750
+ });
4751
+ },
4752
+ onSuccess: (receipt) => {
4753
+ this.coredex.notify(quote.quoteId, {
4754
+ state: "success" /* Success */,
4755
+ data: getPayload(receipt)
4756
+ });
4757
+ },
4758
+ onFailure: (error) => {
4759
+ this.coredex.notify(quote.quoteId, {
4760
+ state: "failed" /* Failed */,
4761
+ error: typedEtherError(error),
4762
+ data: {
4763
+ amountIn: quote.amounts["tokenIn" /* TokenIn */],
4764
+ amountOut: quote.amounts["tokenOut" /* TokenOut */]
4765
+ }
4766
+ });
4767
+ }
4768
+ });
4769
+ if (builts.length === 1) {
4770
+ response = await platform.sendTransaction(
4771
+ quote.chainId,
4772
+ quote.__origin.payload.account,
4773
+ builts[0],
4774
+ handleOptions
4775
+ );
4776
+ } else {
4777
+ response = await platform.sendBatchTransaction(
4778
+ quote.chainId,
4779
+ quote.__origin.payload.account,
4780
+ builts,
4781
+ handleOptions
4782
+ );
4783
+ }
4784
+ this.coredex.console.info("tx hash", get12(response, "hash", response));
4785
+ return response;
4786
+ } catch (error) {
4787
+ this.coredex.notify(quote.quoteId, {
4788
+ state: "failed" /* Failed */,
4789
+ error: typedEtherError(error),
4790
+ data: getPayload(error)
4791
+ });
4792
+ throw error;
4793
+ } finally {
4794
+ this.coredex.emitter.removeAllListeners();
4795
+ }
4796
+ }
4797
+ createDexCurrency(payload) {
4798
+ return this.coredex.platform.fromChainId(payload.chainId).createDexCurrency(payload);
4799
+ }
4800
+ subscribe(quoteId, callback) {
4801
+ this.coredex.emitter.on(quoteId, callback);
4802
+ return () => this.coredex.emitter.off(quoteId, callback);
4803
+ }
4804
+ };
4805
+ export {
4806
+ AbstractedEVM_default as AbstractedEVM,
4807
+ AbstractedPlatform_default as AbstractedPlatform,
4808
+ AbstractedSVM_default as AbstractedSVM,
4809
+ AggregatedQuoteFeeType,
4810
+ BIPS_BASE,
4811
+ Blockchain as BlockchainEnum,
4812
+ CoreDex,
4813
+ DEFAULT_DEADLINE_FROM_NOW,
4814
+ DEFAULT_SLIPPAGE,
4815
+ DexHandleQuoteState,
4816
+ DexToken,
4817
+ EVMChainId as EVMChainIdEnum,
4818
+ Field,
4819
+ GasEstimator_default as GasEstimator,
4820
+ NATIVE_ADDRESS,
4821
+ NativeCurrency,
4822
+ NetworkFeeLevel,
4823
+ PlatformFactory_default as PlatformFactory,
4824
+ PriceImpactLevel,
4825
+ SolanaDexToken,
4826
+ TokenStandard as TokenStandardEnum,
4827
+ WalletType as WalletTypeEnum,
4828
+ WrapType,
4829
+ computeNetworkCost,
4830
+ createSignatureId,
4831
+ DexFactory as default,
4832
+ maxAmountSpend,
4833
+ parseSignatureId,
4834
+ tradeMeaningfullyDiffers
4835
+ };