hermes-swap 0.0.23 → 0.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.d.ts +17 -2
- package/dist/cjs/index.js +110 -9
- package/dist/cjs/types.d.ts +7 -0
- package/dist/cjs/types.js +13 -3
- package/dist/esm/index.d.ts +17 -2
- package/dist/esm/index.js +212 -59
- package/dist/esm/types.d.ts +7 -0
- package/dist/esm/types.js +11 -3
- package/package.json +1 -1
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { IExpectParams, ISwapParams, IBridgeParams, ISwapAndBridgeParams, IReceipt, IConfig, IExpectPayload, IRouterPath } from './types.js';
|
|
2
|
-
import { ChainNameEnum, AddressConst, DexType } from './types.js';
|
|
2
|
+
import { ChainNameEnum, AddressConst, DexType, BridgeType } from './types.js';
|
|
3
3
|
export type { IExpectParams, ISwapParams, IBridgeParams, ISwapAndBridgeParams, IReceipt, IConfig, IExpectPayload, IRouterPath };
|
|
4
|
-
export { ChainNameEnum, AddressConst, DexType };
|
|
4
|
+
export { ChainNameEnum, AddressConst, DexType, BridgeType };
|
|
5
5
|
declare class Hermes {
|
|
6
6
|
private config;
|
|
7
7
|
private providerMap;
|
|
@@ -11,9 +11,24 @@ declare class Hermes {
|
|
|
11
11
|
constructor(config: IConfig);
|
|
12
12
|
expect(params: IExpectParams): Promise<bigint>;
|
|
13
13
|
swap(params: ISwapParams): Promise<IReceipt>;
|
|
14
|
+
/**
|
|
15
|
+
* 生成 swap 的 calldata
|
|
16
|
+
*/
|
|
17
|
+
genSwapCalldata(params: ISwapParams): {
|
|
18
|
+
to: string;
|
|
19
|
+
data: string;
|
|
20
|
+
};
|
|
14
21
|
bridge(params: IBridgeParams): Promise<IReceipt>;
|
|
15
22
|
estimateBridgeFee(params: IBridgeParams): Promise<bigint>;
|
|
16
23
|
swapAndBridge(params: ISwapAndBridgeParams): Promise<IReceipt>;
|
|
24
|
+
/**
|
|
25
|
+
* 生成 swapAndBridge 的 calldata
|
|
26
|
+
*/
|
|
27
|
+
genSwapAndBridgeCalldata(params: ISwapAndBridgeParams): {
|
|
28
|
+
to: string;
|
|
29
|
+
data: string;
|
|
30
|
+
value: bigint;
|
|
31
|
+
};
|
|
17
32
|
private checkIsEnoughToken;
|
|
18
33
|
private validateParams;
|
|
19
34
|
private getQuoterAddress;
|
package/dist/cjs/index.js
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
var src_exports = {};
|
|
31
31
|
__export(src_exports, {
|
|
32
32
|
AddressConst: () => import_types.AddressConst,
|
|
33
|
+
BridgeType: () => import_types.BridgeType,
|
|
33
34
|
ChainNameEnum: () => import_types.ChainNameEnum,
|
|
34
35
|
DexType: () => import_types.DexType,
|
|
35
36
|
Hermes: () => Hermes,
|
|
@@ -79,8 +80,11 @@ var Hermes = class {
|
|
|
79
80
|
toCoin: p.toCoinAddress,
|
|
80
81
|
extra: p.extra || "0x"
|
|
81
82
|
}));
|
|
82
|
-
const amountOutList = await quoter.multiQuote(params.amountInWei, quoteParams);
|
|
83
|
-
|
|
83
|
+
const amountOutList = await quoter.multiQuote.staticCall(params.amountInWei, quoteParams, { from: wallet.address });
|
|
84
|
+
if (!amountOutList.length) {
|
|
85
|
+
throw new Error("No expect result return from smart contract");
|
|
86
|
+
}
|
|
87
|
+
return amountOutList[amountOutList.length - 1];
|
|
84
88
|
}
|
|
85
89
|
async swap(params) {
|
|
86
90
|
this.validateParams(params);
|
|
@@ -108,13 +112,11 @@ var Hermes = class {
|
|
|
108
112
|
throw new Error("Insufficient balance for swap");
|
|
109
113
|
}
|
|
110
114
|
const currentAllowance = await erc20.allowance(params.user, aggregatorAddress);
|
|
111
|
-
console.log(currentAllowance);
|
|
112
115
|
if (currentAllowance < params.amountInWei) {
|
|
113
116
|
throw new Error("Insufficient allowance token amount for swap");
|
|
114
117
|
}
|
|
115
118
|
try {
|
|
116
119
|
const gas = await aggregator.getFunction("swap").estimateGas(params.user, params.amountInWei, swapParams, params.minAmountOutList, { from: wallet.address });
|
|
117
|
-
console.log(`Estimated gas for swap: ${BigInt(gas).toString()}`);
|
|
118
120
|
} catch (error) {
|
|
119
121
|
console.warn("Aggregator estimateGas.swap failed", error);
|
|
120
122
|
throw error;
|
|
@@ -127,7 +129,6 @@ var Hermes = class {
|
|
|
127
129
|
throw error;
|
|
128
130
|
}
|
|
129
131
|
const receipt = await txResponse.wait();
|
|
130
|
-
console.log(`Swap transaction mined in block ${receipt.blockNumber} (tx: ${receipt.hash})`);
|
|
131
132
|
const iface = new import_ethers.ethers.Interface(import_aggregator.default);
|
|
132
133
|
let amountOut = params.amountInWei;
|
|
133
134
|
for (const log of receipt.logs) {
|
|
@@ -152,6 +153,29 @@ var Hermes = class {
|
|
|
152
153
|
logs: receipt.logs
|
|
153
154
|
};
|
|
154
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* 生成 swap 的 calldata
|
|
158
|
+
*/
|
|
159
|
+
genSwapCalldata(params) {
|
|
160
|
+
this.validateParams(params);
|
|
161
|
+
if (!params.path || params.path.length === 0) {
|
|
162
|
+
throw new Error("Swap path not provided");
|
|
163
|
+
}
|
|
164
|
+
const aggregatorAddress = this.getAggregatorAddress(params.chain);
|
|
165
|
+
const swapParams = params.path.map((pathItem) => ({
|
|
166
|
+
dexType: pathItem.dexType,
|
|
167
|
+
pool: pathItem.poolAddress,
|
|
168
|
+
fromCoin: pathItem.fromCoinAddress,
|
|
169
|
+
toCoin: pathItem.toCoinAddress,
|
|
170
|
+
extra: pathItem.extra ?? "0x"
|
|
171
|
+
}));
|
|
172
|
+
const iface = new import_ethers.ethers.Interface(import_aggregator.default);
|
|
173
|
+
const calldata = iface.encodeFunctionData("swap", [params.user, params.amountInWei, swapParams, params.minAmountOutList]);
|
|
174
|
+
return {
|
|
175
|
+
to: aggregatorAddress,
|
|
176
|
+
data: calldata
|
|
177
|
+
};
|
|
178
|
+
}
|
|
155
179
|
async bridge(params) {
|
|
156
180
|
this.validateParams(params);
|
|
157
181
|
const aggregatorAddress = this.getAggregatorAddress(params.chain);
|
|
@@ -235,17 +259,93 @@ var Hermes = class {
|
|
|
235
259
|
}
|
|
236
260
|
async swapAndBridge(params) {
|
|
237
261
|
this.validateParams(params);
|
|
262
|
+
const aggregatorAddress = this.getAggregatorAddress(params.chain);
|
|
263
|
+
const wallet = this.walletMap.get(params.chain);
|
|
264
|
+
if (!wallet) {
|
|
265
|
+
throw new Error(`Wallet not configured for chain: ${params.chain}`);
|
|
266
|
+
}
|
|
267
|
+
const fromCoinAddress = params.path[0].fromCoinAddress;
|
|
268
|
+
if (fromCoinAddress && fromCoinAddress !== import_ethers.ethers.ZeroAddress) {
|
|
269
|
+
await this.checkIsEnoughToken(fromCoinAddress, params.user, params.amountInWei, aggregatorAddress, wallet);
|
|
270
|
+
}
|
|
271
|
+
const swapParams = params.path.map((pathItem) => ({
|
|
272
|
+
dexType: pathItem.dexType,
|
|
273
|
+
pool: pathItem.poolAddress,
|
|
274
|
+
fromCoin: pathItem.fromCoinAddress,
|
|
275
|
+
toCoin: pathItem.toCoinAddress,
|
|
276
|
+
extra: pathItem.extra ?? "0x"
|
|
277
|
+
}));
|
|
278
|
+
const bridgeArgs = {
|
|
279
|
+
bridge: params.bridgeType,
|
|
280
|
+
token: params.tokenAddress,
|
|
281
|
+
amount: params.amountInWei,
|
|
282
|
+
bridgeAddress: params.bridgeAddress,
|
|
283
|
+
destChain: params.destChain,
|
|
284
|
+
destUser: params.destUser,
|
|
285
|
+
extra: params.extra ?? "0x"
|
|
286
|
+
};
|
|
287
|
+
const txOverrides = {
|
|
288
|
+
from: wallet.address,
|
|
289
|
+
value: params.bridgeFee
|
|
290
|
+
};
|
|
291
|
+
const aggregator = new import_ethers2.Contract(aggregatorAddress, import_aggregator.default, wallet);
|
|
292
|
+
try {
|
|
293
|
+
await aggregator.swapAndBridge.estimateGas(params.user, params.amountInWei, swapParams, params.minAmountOutList, bridgeArgs, txOverrides);
|
|
294
|
+
} catch (error) {
|
|
295
|
+
console.error("Bridge gas estimation reverted", error);
|
|
296
|
+
throw error;
|
|
297
|
+
}
|
|
298
|
+
let txResponse;
|
|
299
|
+
try {
|
|
300
|
+
txResponse = await aggregator.swapAndBridge(params.user, params.amountInWei, swapParams, params.minAmountOutList, bridgeArgs, txOverrides);
|
|
301
|
+
} catch (error) {
|
|
302
|
+
console.error("Aggregator swap and bridge transaction failed", error);
|
|
303
|
+
throw error;
|
|
304
|
+
}
|
|
238
305
|
const receipt = {
|
|
239
306
|
fromToken: params.path[0].fromCoinAddress,
|
|
240
307
|
toToken: params.path[params.path.length - 1].toCoinAddress,
|
|
241
308
|
amountOut: params.minAmountOutList[params.minAmountOutList.length - 1],
|
|
242
|
-
hash:
|
|
243
|
-
from:
|
|
244
|
-
to:
|
|
245
|
-
logs:
|
|
309
|
+
hash: txResponse.hash,
|
|
310
|
+
from: txResponse.from,
|
|
311
|
+
to: txResponse.to,
|
|
312
|
+
logs: txResponse.logs
|
|
246
313
|
};
|
|
247
314
|
return Promise.resolve(receipt);
|
|
248
315
|
}
|
|
316
|
+
/**
|
|
317
|
+
* 生成 swapAndBridge 的 calldata
|
|
318
|
+
*/
|
|
319
|
+
genSwapAndBridgeCalldata(params) {
|
|
320
|
+
this.validateParams(params);
|
|
321
|
+
if (!params.path || params.path.length === 0) {
|
|
322
|
+
throw new Error("Swap path not provided");
|
|
323
|
+
}
|
|
324
|
+
const aggregatorAddress = this.getAggregatorAddress(params.chain);
|
|
325
|
+
const swapParams = params.path.map((pathItem) => ({
|
|
326
|
+
dexType: pathItem.dexType,
|
|
327
|
+
pool: pathItem.poolAddress,
|
|
328
|
+
fromCoin: pathItem.fromCoinAddress,
|
|
329
|
+
toCoin: pathItem.toCoinAddress,
|
|
330
|
+
extra: pathItem.extra ?? "0x"
|
|
331
|
+
}));
|
|
332
|
+
const bridgeParam = {
|
|
333
|
+
bridge: params.bridgeType,
|
|
334
|
+
token: params.tokenAddress,
|
|
335
|
+
amount: params.amountInWei,
|
|
336
|
+
bridgeAddress: params.bridgeAddress,
|
|
337
|
+
destChain: params.destChain,
|
|
338
|
+
destUser: params.destUser,
|
|
339
|
+
extra: params.extra ?? "0x"
|
|
340
|
+
};
|
|
341
|
+
const iface = new import_ethers.ethers.Interface(import_aggregator.default);
|
|
342
|
+
const calldata = iface.encodeFunctionData("swapAndBridge", [params.user, params.amountInWei, swapParams, params.minAmountOutList, bridgeParam]);
|
|
343
|
+
return {
|
|
344
|
+
to: aggregatorAddress,
|
|
345
|
+
data: calldata,
|
|
346
|
+
value: params.bridgeFee
|
|
347
|
+
};
|
|
348
|
+
}
|
|
249
349
|
async checkIsEnoughToken(fromTokenAddress, userAddress, amountInWei, aggregatorAddress, wallet) {
|
|
250
350
|
const erc20 = new import_ethers2.Contract(fromTokenAddress, ["function balanceOf(address) view returns (uint256)", "function allowance(address, address) view returns (uint256)"], wallet);
|
|
251
351
|
const userBalance = await erc20.balanceOf(userAddress);
|
|
@@ -284,6 +384,7 @@ var src_default = Hermes;
|
|
|
284
384
|
// Annotate the CommonJS export names for ESM import in node:
|
|
285
385
|
0 && (module.exports = {
|
|
286
386
|
AddressConst,
|
|
387
|
+
BridgeType,
|
|
287
388
|
ChainNameEnum,
|
|
288
389
|
DexType,
|
|
289
390
|
Hermes
|
package/dist/cjs/types.d.ts
CHANGED
|
@@ -90,6 +90,10 @@ export declare enum DexType {
|
|
|
90
90
|
CURVE128 = "curve128",
|
|
91
91
|
CURVE256 = "curve256"
|
|
92
92
|
}
|
|
93
|
+
export declare enum BridgeType {
|
|
94
|
+
LAYERZEROV1 = "layerzero_v1",
|
|
95
|
+
LAYERZEROV2 = "layerzero_v2"
|
|
96
|
+
}
|
|
93
97
|
export declare enum ChainNameEnum {
|
|
94
98
|
ETH = "ETH",// Ethereum Mainnet
|
|
95
99
|
ARB = "ARB",// Arbitrum One
|
|
@@ -252,15 +256,18 @@ export interface IRpcConfig {
|
|
|
252
256
|
export declare const AddressConst: {
|
|
253
257
|
weth: {
|
|
254
258
|
eth: string;
|
|
259
|
+
arb: string;
|
|
255
260
|
};
|
|
256
261
|
usdt: {
|
|
257
262
|
eth: string;
|
|
258
263
|
};
|
|
259
264
|
feth: {
|
|
260
265
|
eth: string;
|
|
266
|
+
arb: string;
|
|
261
267
|
};
|
|
262
268
|
xeth: {
|
|
263
269
|
eth: string;
|
|
270
|
+
arb: string;
|
|
264
271
|
};
|
|
265
272
|
arb: {
|
|
266
273
|
arb: string;
|
package/dist/cjs/types.js
CHANGED
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
var types_exports = {};
|
|
21
21
|
__export(types_exports, {
|
|
22
22
|
AddressConst: () => AddressConst,
|
|
23
|
+
BridgeType: () => BridgeType,
|
|
23
24
|
ChainNameEnum: () => ChainNameEnum,
|
|
24
25
|
DexType: () => DexType
|
|
25
26
|
});
|
|
@@ -31,6 +32,11 @@ var DexType = /* @__PURE__ */ ((DexType2) => {
|
|
|
31
32
|
DexType2["CURVE256"] = "curve256";
|
|
32
33
|
return DexType2;
|
|
33
34
|
})(DexType || {});
|
|
35
|
+
var BridgeType = /* @__PURE__ */ ((BridgeType2) => {
|
|
36
|
+
BridgeType2["LAYERZEROV1"] = "layerzero_v1";
|
|
37
|
+
BridgeType2["LAYERZEROV2"] = "layerzero_v2";
|
|
38
|
+
return BridgeType2;
|
|
39
|
+
})(BridgeType || {});
|
|
34
40
|
var ChainNameEnum = /* @__PURE__ */ ((ChainNameEnum2) => {
|
|
35
41
|
ChainNameEnum2["ETH"] = "ETH";
|
|
36
42
|
ChainNameEnum2["ARB"] = "ARB";
|
|
@@ -189,17 +195,20 @@ var ChainNameEnum = /* @__PURE__ */ ((ChainNameEnum2) => {
|
|
|
189
195
|
})(ChainNameEnum || {});
|
|
190
196
|
var AddressConst = {
|
|
191
197
|
weth: {
|
|
192
|
-
eth: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
|
|
198
|
+
eth: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
|
199
|
+
arb: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"
|
|
193
200
|
},
|
|
194
201
|
usdt: {
|
|
195
202
|
eth: ""
|
|
196
203
|
},
|
|
197
204
|
// fx
|
|
198
205
|
feth: {
|
|
199
|
-
eth: "0x53805A76E1f5ebbFE7115F16f9c87C2f7e633726"
|
|
206
|
+
eth: "0x53805A76E1f5ebbFE7115F16f9c87C2f7e633726",
|
|
207
|
+
arb: "0xc608Dfb90A430Df79a8a1eDBC8be7f1A0Eb4E763"
|
|
200
208
|
},
|
|
201
209
|
xeth: {
|
|
202
|
-
eth: "0xe063F04f280c60aECa68b38341C2eEcBeC703ae2"
|
|
210
|
+
eth: "0xe063F04f280c60aECa68b38341C2eEcBeC703ae2",
|
|
211
|
+
arb: "0x55380fe7A1910dFf29A47B622057ab4139DA42C5"
|
|
203
212
|
},
|
|
204
213
|
arb: {
|
|
205
214
|
arb: "0x912CE59144191C1204E64559FE8253a0e49E6548"
|
|
@@ -211,6 +220,7 @@ var AddressConst = {
|
|
|
211
220
|
// Annotate the CommonJS export names for ESM import in node:
|
|
212
221
|
0 && (module.exports = {
|
|
213
222
|
AddressConst,
|
|
223
|
+
BridgeType,
|
|
214
224
|
ChainNameEnum,
|
|
215
225
|
DexType
|
|
216
226
|
});
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { IExpectParams, ISwapParams, IBridgeParams, ISwapAndBridgeParams, IReceipt, IConfig, IExpectPayload, IRouterPath } from './types.js';
|
|
2
|
-
import { ChainNameEnum, AddressConst, DexType } from './types.js';
|
|
2
|
+
import { ChainNameEnum, AddressConst, DexType, BridgeType } from './types.js';
|
|
3
3
|
export type { IExpectParams, ISwapParams, IBridgeParams, ISwapAndBridgeParams, IReceipt, IConfig, IExpectPayload, IRouterPath };
|
|
4
|
-
export { ChainNameEnum, AddressConst, DexType };
|
|
4
|
+
export { ChainNameEnum, AddressConst, DexType, BridgeType };
|
|
5
5
|
declare class Hermes {
|
|
6
6
|
private config;
|
|
7
7
|
private providerMap;
|
|
@@ -11,9 +11,24 @@ declare class Hermes {
|
|
|
11
11
|
constructor(config: IConfig);
|
|
12
12
|
expect(params: IExpectParams): Promise<bigint>;
|
|
13
13
|
swap(params: ISwapParams): Promise<IReceipt>;
|
|
14
|
+
/**
|
|
15
|
+
* 生成 swap 的 calldata
|
|
16
|
+
*/
|
|
17
|
+
genSwapCalldata(params: ISwapParams): {
|
|
18
|
+
to: string;
|
|
19
|
+
data: string;
|
|
20
|
+
};
|
|
14
21
|
bridge(params: IBridgeParams): Promise<IReceipt>;
|
|
15
22
|
estimateBridgeFee(params: IBridgeParams): Promise<bigint>;
|
|
16
23
|
swapAndBridge(params: ISwapAndBridgeParams): Promise<IReceipt>;
|
|
24
|
+
/**
|
|
25
|
+
* 生成 swapAndBridge 的 calldata
|
|
26
|
+
*/
|
|
27
|
+
genSwapAndBridgeCalldata(params: ISwapAndBridgeParams): {
|
|
28
|
+
to: string;
|
|
29
|
+
data: string;
|
|
30
|
+
value: bigint;
|
|
31
|
+
};
|
|
17
32
|
private checkIsEnoughToken;
|
|
18
33
|
private validateParams;
|
|
19
34
|
private getQuoterAddress;
|
package/dist/esm/index.js
CHANGED
|
@@ -15,7 +15,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
|
|
|
15
15
|
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
16
16
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
17
17
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
18
|
-
import { ChainNameEnum, AddressConst, DexType } from "./types.js";
|
|
18
|
+
import { ChainNameEnum, AddressConst, DexType, BridgeType } from "./types.js";
|
|
19
19
|
import { ethers } from 'ethers';
|
|
20
20
|
import { Contract } from 'ethers';
|
|
21
21
|
import QuoterAbi from "./abis/quoter.js";
|
|
@@ -23,7 +23,7 @@ import AggregatorAbi from "./abis/aggregator.js";
|
|
|
23
23
|
|
|
24
24
|
// 导出所有类型定义,方便用户使用
|
|
25
25
|
|
|
26
|
-
export { ChainNameEnum, AddressConst, DexType };
|
|
26
|
+
export { ChainNameEnum, AddressConst, DexType, BridgeType };
|
|
27
27
|
var Hermes = /*#__PURE__*/function () {
|
|
28
28
|
function Hermes(config) {
|
|
29
29
|
_classCallCheck(this, Hermes);
|
|
@@ -90,11 +90,19 @@ var Hermes = /*#__PURE__*/function () {
|
|
|
90
90
|
};
|
|
91
91
|
});
|
|
92
92
|
_context.next = 10;
|
|
93
|
-
return quoter.multiQuote(params.amountInWei, quoteParams
|
|
93
|
+
return quoter.multiQuote.staticCall(params.amountInWei, quoteParams, {
|
|
94
|
+
from: wallet.address
|
|
95
|
+
});
|
|
94
96
|
case 10:
|
|
95
97
|
amountOutList = _context.sent;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
+
if (amountOutList.length) {
|
|
99
|
+
_context.next = 13;
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
throw new Error('No expect result return from smart contract');
|
|
103
|
+
case 13:
|
|
104
|
+
return _context.abrupt("return", amountOutList[amountOutList.length - 1]);
|
|
105
|
+
case 14:
|
|
98
106
|
case "end":
|
|
99
107
|
return _context.stop();
|
|
100
108
|
}
|
|
@@ -156,93 +164,90 @@ var Hermes = /*#__PURE__*/function () {
|
|
|
156
164
|
return erc20.allowance(params.user, aggregatorAddress);
|
|
157
165
|
case 19:
|
|
158
166
|
currentAllowance = _context2.sent;
|
|
159
|
-
console.log(currentAllowance);
|
|
160
167
|
if (!(currentAllowance < params.amountInWei)) {
|
|
161
|
-
_context2.next =
|
|
168
|
+
_context2.next = 22;
|
|
162
169
|
break;
|
|
163
170
|
}
|
|
164
171
|
throw new Error('Insufficient allowance token amount for swap');
|
|
165
|
-
case
|
|
166
|
-
_context2.prev =
|
|
167
|
-
_context2.next =
|
|
172
|
+
case 22:
|
|
173
|
+
_context2.prev = 22;
|
|
174
|
+
_context2.next = 25;
|
|
168
175
|
return aggregator.getFunction('swap').estimateGas(params.user, params.amountInWei, swapParams, params.minAmountOutList, {
|
|
169
176
|
from: wallet.address
|
|
170
177
|
});
|
|
171
|
-
case
|
|
178
|
+
case 25:
|
|
172
179
|
gas = _context2.sent;
|
|
173
|
-
|
|
174
|
-
_context2.next = 34;
|
|
180
|
+
_context2.next = 32;
|
|
175
181
|
break;
|
|
176
|
-
case
|
|
177
|
-
_context2.prev =
|
|
178
|
-
_context2.t0 = _context2["catch"](
|
|
182
|
+
case 28:
|
|
183
|
+
_context2.prev = 28;
|
|
184
|
+
_context2.t0 = _context2["catch"](22);
|
|
179
185
|
console.warn('Aggregator estimateGas.swap failed', _context2.t0);
|
|
180
186
|
throw _context2.t0;
|
|
181
|
-
case
|
|
182
|
-
_context2.prev =
|
|
183
|
-
_context2.next =
|
|
187
|
+
case 32:
|
|
188
|
+
_context2.prev = 32;
|
|
189
|
+
_context2.next = 35;
|
|
184
190
|
return aggregator.getFunction('swap')(params.user, params.amountInWei, swapParams, params.minAmountOutList, {
|
|
185
191
|
from: wallet.address
|
|
186
192
|
});
|
|
187
|
-
case
|
|
193
|
+
case 35:
|
|
188
194
|
txResponse = _context2.sent;
|
|
189
|
-
_context2.next =
|
|
195
|
+
_context2.next = 42;
|
|
190
196
|
break;
|
|
191
|
-
case
|
|
192
|
-
_context2.prev =
|
|
193
|
-
_context2.t1 = _context2["catch"](
|
|
197
|
+
case 38:
|
|
198
|
+
_context2.prev = 38;
|
|
199
|
+
_context2.t1 = _context2["catch"](32);
|
|
194
200
|
console.error('Aggregator swap transaction failed', _context2.t1);
|
|
195
201
|
throw _context2.t1;
|
|
196
|
-
case
|
|
197
|
-
_context2.next =
|
|
202
|
+
case 42:
|
|
203
|
+
_context2.next = 44;
|
|
198
204
|
return txResponse.wait();
|
|
199
|
-
case
|
|
205
|
+
case 44:
|
|
200
206
|
receipt = _context2.sent;
|
|
201
|
-
console.log("Swap transaction mined in block ".concat(receipt.blockNumber, " (tx: ").concat(receipt.hash, ")"));
|
|
202
207
|
iface = new ethers.Interface(AggregatorAbi);
|
|
203
208
|
amountOut = params.amountInWei;
|
|
204
209
|
_iterator = _createForOfIteratorHelper(receipt.logs);
|
|
205
|
-
_context2.prev =
|
|
210
|
+
_context2.prev = 48;
|
|
206
211
|
_iterator.s();
|
|
207
|
-
case
|
|
212
|
+
case 50:
|
|
208
213
|
if ((_step = _iterator.n()).done) {
|
|
209
|
-
_context2.next =
|
|
214
|
+
_context2.next = 64;
|
|
210
215
|
break;
|
|
211
216
|
}
|
|
212
217
|
log = _step.value;
|
|
213
218
|
if (!(log.address.toLowerCase() === aggregatorAddress.toLowerCase())) {
|
|
214
|
-
_context2.next =
|
|
219
|
+
_context2.next = 62;
|
|
215
220
|
break;
|
|
216
221
|
}
|
|
217
|
-
_context2.prev =
|
|
222
|
+
_context2.prev = 53;
|
|
218
223
|
parsed = iface.parseLog(log);
|
|
219
224
|
if (!(parsed && parsed.name === 'Swapped' && parsed.args && parsed.args.amountOut !== undefined)) {
|
|
220
|
-
_context2.next =
|
|
225
|
+
_context2.next = 58;
|
|
221
226
|
break;
|
|
222
227
|
}
|
|
223
228
|
amountOut = parsed.args.amountOut;
|
|
224
|
-
return _context2.abrupt("break",
|
|
225
|
-
case
|
|
226
|
-
_context2.next =
|
|
229
|
+
return _context2.abrupt("break", 64);
|
|
230
|
+
case 58:
|
|
231
|
+
_context2.next = 62;
|
|
227
232
|
break;
|
|
228
|
-
case
|
|
229
|
-
_context2.prev =
|
|
230
|
-
_context2.t2 = _context2["catch"](
|
|
231
|
-
case
|
|
232
|
-
_context2.next =
|
|
233
|
+
case 60:
|
|
234
|
+
_context2.prev = 60;
|
|
235
|
+
_context2.t2 = _context2["catch"](53);
|
|
236
|
+
case 62:
|
|
237
|
+
_context2.next = 50;
|
|
233
238
|
break;
|
|
234
|
-
case
|
|
235
|
-
_context2.next =
|
|
239
|
+
case 64:
|
|
240
|
+
_context2.next = 69;
|
|
236
241
|
break;
|
|
242
|
+
case 66:
|
|
243
|
+
_context2.prev = 66;
|
|
244
|
+
_context2.t3 = _context2["catch"](48);
|
|
245
|
+
_iterator.e(_context2.t3);
|
|
237
246
|
case 69:
|
|
238
247
|
_context2.prev = 69;
|
|
239
|
-
_context2.t3 = _context2["catch"](51);
|
|
240
|
-
_iterator.e(_context2.t3);
|
|
241
|
-
case 72:
|
|
242
|
-
_context2.prev = 72;
|
|
243
248
|
_iterator.f();
|
|
244
|
-
return _context2.finish(
|
|
245
|
-
case
|
|
249
|
+
return _context2.finish(69);
|
|
250
|
+
case 72:
|
|
246
251
|
return _context2.abrupt("return", {
|
|
247
252
|
fromToken: fromTokenAddress,
|
|
248
253
|
toToken: toTokenAddress,
|
|
@@ -252,17 +257,50 @@ var Hermes = /*#__PURE__*/function () {
|
|
|
252
257
|
to: receipt.from,
|
|
253
258
|
logs: receipt.logs
|
|
254
259
|
});
|
|
255
|
-
case
|
|
260
|
+
case 73:
|
|
256
261
|
case "end":
|
|
257
262
|
return _context2.stop();
|
|
258
263
|
}
|
|
259
|
-
}, _callee2, this, [[
|
|
264
|
+
}, _callee2, this, [[22, 28], [32, 38], [48, 66, 69, 72], [53, 60]]);
|
|
260
265
|
}));
|
|
261
266
|
function swap(_x2) {
|
|
262
267
|
return _swap.apply(this, arguments);
|
|
263
268
|
}
|
|
264
269
|
return swap;
|
|
265
270
|
}()
|
|
271
|
+
/**
|
|
272
|
+
* 生成 swap 的 calldata
|
|
273
|
+
*/
|
|
274
|
+
}, {
|
|
275
|
+
key: "genSwapCalldata",
|
|
276
|
+
value: function genSwapCalldata(params) {
|
|
277
|
+
this.validateParams(params);
|
|
278
|
+
if (!params.path || params.path.length === 0) {
|
|
279
|
+
throw new Error('Swap path not provided');
|
|
280
|
+
}
|
|
281
|
+
var aggregatorAddress = this.getAggregatorAddress(params.chain);
|
|
282
|
+
|
|
283
|
+
// 准备 swap 参数
|
|
284
|
+
var swapParams = params.path.map(function (pathItem) {
|
|
285
|
+
var _pathItem$extra2;
|
|
286
|
+
return {
|
|
287
|
+
dexType: pathItem.dexType,
|
|
288
|
+
pool: pathItem.poolAddress,
|
|
289
|
+
fromCoin: pathItem.fromCoinAddress,
|
|
290
|
+
toCoin: pathItem.toCoinAddress,
|
|
291
|
+
extra: (_pathItem$extra2 = pathItem.extra) !== null && _pathItem$extra2 !== void 0 ? _pathItem$extra2 : '0x'
|
|
292
|
+
};
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
// 使用 ethers Interface 编码 calldata
|
|
296
|
+
// 参数顺序: user, amountIn, swapParams, minAmountOutList
|
|
297
|
+
var iface = new ethers.Interface(AggregatorAbi);
|
|
298
|
+
var calldata = iface.encodeFunctionData('swap', [params.user, params.amountInWei, swapParams, params.minAmountOutList]);
|
|
299
|
+
return {
|
|
300
|
+
to: aggregatorAddress,
|
|
301
|
+
data: calldata
|
|
302
|
+
};
|
|
303
|
+
}
|
|
266
304
|
}, {
|
|
267
305
|
key: "bridge",
|
|
268
306
|
value: function () {
|
|
@@ -427,32 +465,147 @@ var Hermes = /*#__PURE__*/function () {
|
|
|
427
465
|
key: "swapAndBridge",
|
|
428
466
|
value: function () {
|
|
429
467
|
var _swapAndBridge = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(params) {
|
|
430
|
-
var
|
|
468
|
+
var _params$extra3;
|
|
469
|
+
var aggregatorAddress, wallet, fromCoinAddress, swapParams, bridgeArgs, txOverrides, aggregator, txResponse, receipt;
|
|
431
470
|
return _regeneratorRuntime().wrap(function _callee5$(_context5) {
|
|
432
471
|
while (1) switch (_context5.prev = _context5.next) {
|
|
433
472
|
case 0:
|
|
434
473
|
this.validateParams(params);
|
|
474
|
+
|
|
475
|
+
// call the aggregator swap and bridge
|
|
476
|
+
aggregatorAddress = this.getAggregatorAddress(params.chain);
|
|
477
|
+
wallet = this.walletMap.get(params.chain);
|
|
478
|
+
if (wallet) {
|
|
479
|
+
_context5.next = 5;
|
|
480
|
+
break;
|
|
481
|
+
}
|
|
482
|
+
throw new Error("Wallet not configured for chain: ".concat(params.chain));
|
|
483
|
+
case 5:
|
|
484
|
+
fromCoinAddress = params.path[0].fromCoinAddress;
|
|
485
|
+
if (!(fromCoinAddress && fromCoinAddress !== ethers.ZeroAddress)) {
|
|
486
|
+
_context5.next = 9;
|
|
487
|
+
break;
|
|
488
|
+
}
|
|
489
|
+
_context5.next = 9;
|
|
490
|
+
return this.checkIsEnoughToken(fromCoinAddress, params.user, params.amountInWei, aggregatorAddress, wallet);
|
|
491
|
+
case 9:
|
|
492
|
+
// 准备合约参数
|
|
493
|
+
swapParams = params.path.map(function (pathItem) {
|
|
494
|
+
var _pathItem$extra3;
|
|
495
|
+
return {
|
|
496
|
+
dexType: pathItem.dexType,
|
|
497
|
+
pool: pathItem.poolAddress,
|
|
498
|
+
fromCoin: pathItem.fromCoinAddress,
|
|
499
|
+
toCoin: pathItem.toCoinAddress,
|
|
500
|
+
extra: (_pathItem$extra3 = pathItem.extra) !== null && _pathItem$extra3 !== void 0 ? _pathItem$extra3 : '0x'
|
|
501
|
+
};
|
|
502
|
+
});
|
|
503
|
+
bridgeArgs = {
|
|
504
|
+
bridge: params.bridgeType,
|
|
505
|
+
token: params.tokenAddress,
|
|
506
|
+
amount: params.amountInWei,
|
|
507
|
+
bridgeAddress: params.bridgeAddress,
|
|
508
|
+
destChain: params.destChain,
|
|
509
|
+
destUser: params.destUser,
|
|
510
|
+
extra: (_params$extra3 = params.extra) !== null && _params$extra3 !== void 0 ? _params$extra3 : '0x'
|
|
511
|
+
};
|
|
512
|
+
txOverrides = {
|
|
513
|
+
from: wallet.address,
|
|
514
|
+
value: params.bridgeFee
|
|
515
|
+
}; // simulate
|
|
516
|
+
aggregator = new Contract(aggregatorAddress, AggregatorAbi, wallet);
|
|
517
|
+
_context5.prev = 13;
|
|
518
|
+
_context5.next = 16;
|
|
519
|
+
return aggregator.swapAndBridge.estimateGas(params.user, params.amountInWei, swapParams, params.minAmountOutList, bridgeArgs, txOverrides);
|
|
520
|
+
case 16:
|
|
521
|
+
_context5.next = 22;
|
|
522
|
+
break;
|
|
523
|
+
case 18:
|
|
524
|
+
_context5.prev = 18;
|
|
525
|
+
_context5.t0 = _context5["catch"](13);
|
|
526
|
+
console.error('Bridge gas estimation reverted', _context5.t0);
|
|
527
|
+
throw _context5.t0;
|
|
528
|
+
case 22:
|
|
529
|
+
_context5.prev = 22;
|
|
530
|
+
_context5.next = 25;
|
|
531
|
+
return aggregator.swapAndBridge(params.user, params.amountInWei, swapParams, params.minAmountOutList, bridgeArgs, txOverrides);
|
|
532
|
+
case 25:
|
|
533
|
+
txResponse = _context5.sent;
|
|
534
|
+
_context5.next = 32;
|
|
535
|
+
break;
|
|
536
|
+
case 28:
|
|
537
|
+
_context5.prev = 28;
|
|
538
|
+
_context5.t1 = _context5["catch"](22);
|
|
539
|
+
console.error('Aggregator swap and bridge transaction failed', _context5.t1);
|
|
540
|
+
throw _context5.t1;
|
|
541
|
+
case 32:
|
|
435
542
|
receipt = {
|
|
436
543
|
fromToken: params.path[0].fromCoinAddress,
|
|
437
544
|
toToken: params.path[params.path.length - 1].toCoinAddress,
|
|
438
545
|
amountOut: params.minAmountOutList[params.minAmountOutList.length - 1],
|
|
439
|
-
hash:
|
|
440
|
-
from:
|
|
441
|
-
to:
|
|
442
|
-
logs:
|
|
546
|
+
hash: txResponse.hash,
|
|
547
|
+
from: txResponse.from,
|
|
548
|
+
to: txResponse.to,
|
|
549
|
+
logs: txResponse.logs
|
|
443
550
|
};
|
|
444
551
|
return _context5.abrupt("return", Promise.resolve(receipt));
|
|
445
|
-
case
|
|
552
|
+
case 34:
|
|
446
553
|
case "end":
|
|
447
554
|
return _context5.stop();
|
|
448
555
|
}
|
|
449
|
-
}, _callee5, this);
|
|
556
|
+
}, _callee5, this, [[13, 18], [22, 28]]);
|
|
450
557
|
}));
|
|
451
558
|
function swapAndBridge(_x5) {
|
|
452
559
|
return _swapAndBridge.apply(this, arguments);
|
|
453
560
|
}
|
|
454
561
|
return swapAndBridge;
|
|
455
562
|
}()
|
|
563
|
+
/**
|
|
564
|
+
* 生成 swapAndBridge 的 calldata
|
|
565
|
+
*/
|
|
566
|
+
}, {
|
|
567
|
+
key: "genSwapAndBridgeCalldata",
|
|
568
|
+
value: function genSwapAndBridgeCalldata(params) {
|
|
569
|
+
var _params$extra4;
|
|
570
|
+
this.validateParams(params);
|
|
571
|
+
if (!params.path || params.path.length === 0) {
|
|
572
|
+
throw new Error('Swap path not provided');
|
|
573
|
+
}
|
|
574
|
+
var aggregatorAddress = this.getAggregatorAddress(params.chain);
|
|
575
|
+
|
|
576
|
+
// 准备 swap 参数
|
|
577
|
+
var swapParams = params.path.map(function (pathItem) {
|
|
578
|
+
var _pathItem$extra4;
|
|
579
|
+
return {
|
|
580
|
+
dexType: pathItem.dexType,
|
|
581
|
+
pool: pathItem.poolAddress,
|
|
582
|
+
fromCoin: pathItem.fromCoinAddress,
|
|
583
|
+
toCoin: pathItem.toCoinAddress,
|
|
584
|
+
extra: (_pathItem$extra4 = pathItem.extra) !== null && _pathItem$extra4 !== void 0 ? _pathItem$extra4 : '0x'
|
|
585
|
+
};
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
// 准备 bridge 参数(对应合约中的 BridgeParam struct)
|
|
589
|
+
var bridgeParam = {
|
|
590
|
+
bridge: params.bridgeType,
|
|
591
|
+
token: params.tokenAddress,
|
|
592
|
+
amount: params.amountInWei,
|
|
593
|
+
bridgeAddress: params.bridgeAddress,
|
|
594
|
+
destChain: params.destChain,
|
|
595
|
+
destUser: params.destUser,
|
|
596
|
+
extra: (_params$extra4 = params.extra) !== null && _params$extra4 !== void 0 ? _params$extra4 : '0x'
|
|
597
|
+
};
|
|
598
|
+
|
|
599
|
+
// 使用 ethers Interface 编码 calldata
|
|
600
|
+
// 参数顺序: user, amountIn, swapParams, minAmountOutList, bridgeParam
|
|
601
|
+
var iface = new ethers.Interface(AggregatorAbi);
|
|
602
|
+
var calldata = iface.encodeFunctionData('swapAndBridge', [params.user, params.amountInWei, swapParams, params.minAmountOutList, bridgeParam]);
|
|
603
|
+
return {
|
|
604
|
+
to: aggregatorAddress,
|
|
605
|
+
data: calldata,
|
|
606
|
+
value: params.bridgeFee
|
|
607
|
+
};
|
|
608
|
+
}
|
|
456
609
|
}, {
|
|
457
610
|
key: "checkIsEnoughToken",
|
|
458
611
|
value: function () {
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -90,6 +90,10 @@ export declare enum DexType {
|
|
|
90
90
|
CURVE128 = "curve128",
|
|
91
91
|
CURVE256 = "curve256"
|
|
92
92
|
}
|
|
93
|
+
export declare enum BridgeType {
|
|
94
|
+
LAYERZEROV1 = "layerzero_v1",
|
|
95
|
+
LAYERZEROV2 = "layerzero_v2"
|
|
96
|
+
}
|
|
93
97
|
export declare enum ChainNameEnum {
|
|
94
98
|
ETH = "ETH",// Ethereum Mainnet
|
|
95
99
|
ARB = "ARB",// Arbitrum One
|
|
@@ -252,15 +256,18 @@ export interface IRpcConfig {
|
|
|
252
256
|
export declare const AddressConst: {
|
|
253
257
|
weth: {
|
|
254
258
|
eth: string;
|
|
259
|
+
arb: string;
|
|
255
260
|
};
|
|
256
261
|
usdt: {
|
|
257
262
|
eth: string;
|
|
258
263
|
};
|
|
259
264
|
feth: {
|
|
260
265
|
eth: string;
|
|
266
|
+
arb: string;
|
|
261
267
|
};
|
|
262
268
|
xeth: {
|
|
263
269
|
eth: string;
|
|
270
|
+
arb: string;
|
|
264
271
|
};
|
|
265
272
|
arb: {
|
|
266
273
|
arb: string;
|
package/dist/esm/types.js
CHANGED
|
@@ -5,6 +5,11 @@ export var DexType = /*#__PURE__*/function (DexType) {
|
|
|
5
5
|
DexType["CURVE256"] = "curve256";
|
|
6
6
|
return DexType;
|
|
7
7
|
}({});
|
|
8
|
+
export var BridgeType = /*#__PURE__*/function (BridgeType) {
|
|
9
|
+
BridgeType["LAYERZEROV1"] = "layerzero_v1";
|
|
10
|
+
BridgeType["LAYERZEROV2"] = "layerzero_v2";
|
|
11
|
+
return BridgeType;
|
|
12
|
+
}({});
|
|
8
13
|
export var ChainNameEnum = /*#__PURE__*/function (ChainNameEnum) {
|
|
9
14
|
ChainNameEnum["ETH"] = "ETH";
|
|
10
15
|
ChainNameEnum["ARB"] = "ARB";
|
|
@@ -163,17 +168,20 @@ export var ChainNameEnum = /*#__PURE__*/function (ChainNameEnum) {
|
|
|
163
168
|
}({}); // BEVM
|
|
164
169
|
export var AddressConst = {
|
|
165
170
|
weth: {
|
|
166
|
-
eth: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'
|
|
171
|
+
eth: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
|
|
172
|
+
arb: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1'
|
|
167
173
|
},
|
|
168
174
|
usdt: {
|
|
169
175
|
eth: ''
|
|
170
176
|
},
|
|
171
177
|
// fx
|
|
172
178
|
feth: {
|
|
173
|
-
eth: '0x53805A76E1f5ebbFE7115F16f9c87C2f7e633726'
|
|
179
|
+
eth: '0x53805A76E1f5ebbFE7115F16f9c87C2f7e633726',
|
|
180
|
+
arb: '0xc608Dfb90A430Df79a8a1eDBC8be7f1A0Eb4E763'
|
|
174
181
|
},
|
|
175
182
|
xeth: {
|
|
176
|
-
eth: '0xe063F04f280c60aECa68b38341C2eEcBeC703ae2'
|
|
183
|
+
eth: '0xe063F04f280c60aECa68b38341C2eEcBeC703ae2',
|
|
184
|
+
arb: '0x55380fe7A1910dFf29A47B622057ab4139DA42C5'
|
|
177
185
|
},
|
|
178
186
|
arb: {
|
|
179
187
|
arb: '0x912CE59144191C1204E64559FE8253a0e49E6548'
|