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