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