@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/README.md +53 -0
- package/dist/index.d.mts +2091 -0
- package/dist/index.d.ts +2091 -0
- package/dist/index.js +4887 -0
- package/dist/index.mjs +4835 -0
- package/package.json +64 -0
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
|
+
});
|