hermes-swap 0.0.31 → 0.0.33

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.
@@ -1,7 +1,8 @@
1
1
  import type { IExpectParams, ISwapParams, IBridgeParams, ISwapAndBridgeParams, IReceipt, IConfig, IExpectPayload, IRouterPath, SupportContracts } from './types.js';
2
- import { ChainNameEnum, AddressConst, DexType, BridgeType, IEstimateType } from './types.js';
2
+ import { ChainNameEnum, AddressConst, DexType, BridgeType, IEstimateType, LayerZeroV1ChainIdMap, LayerZeroV1ChainNameMap, LayerZeroV2ChainIdMap, LayerZeroV2ChainNameMap } from './types.js';
3
+ import { TransactionRequest } from 'ethers';
3
4
  export type { IExpectParams, ISwapParams, IBridgeParams, ISwapAndBridgeParams, IReceipt, IConfig, IExpectPayload, IRouterPath, SupportContracts };
4
- export { ChainNameEnum, AddressConst, DexType, BridgeType, IEstimateType };
5
+ export { ChainNameEnum, AddressConst, DexType, BridgeType, IEstimateType, LayerZeroV1ChainIdMap, LayerZeroV1ChainNameMap, LayerZeroV2ChainIdMap, LayerZeroV2ChainNameMap };
5
6
  declare class Hermes {
6
7
  private config;
7
8
  private providerMap;
@@ -10,7 +11,7 @@ declare class Hermes {
10
11
  private aggregatorAddressMap;
11
12
  constructor(config: IConfig);
12
13
  expect(params: IExpectParams): Promise<bigint>;
13
- swap(params: ISwapParams): Promise<IReceipt>;
14
+ swap(params: ISwapParams, txReq?: TransactionRequest): Promise<IReceipt>;
14
15
  /**
15
16
  * 生成 swap 的 calldata
16
17
  */
@@ -18,9 +19,9 @@ declare class Hermes {
18
19
  to: string;
19
20
  data: string;
20
21
  };
21
- bridge(params: IBridgeParams): Promise<IReceipt>;
22
+ bridge(params: IBridgeParams, txReq?: TransactionRequest): Promise<IReceipt>;
22
23
  estimateBridgeFee(params: IBridgeParams): Promise<bigint>;
23
- swapAndBridge(params: ISwapAndBridgeParams): Promise<IReceipt>;
24
+ swapAndBridge(params: ISwapAndBridgeParams, txReq?: TransactionRequest): Promise<IReceipt>;
24
25
  estimateGas(estimateType: IEstimateType, params: IBridgeParams | ISwapParams | ISwapAndBridgeParams): Promise<bigint>;
25
26
  getAggregatorSupportContracts(chain: ChainNameEnum): Promise<SupportContracts[]>;
26
27
  getQuoterSupportContracts(chain: ChainNameEnum): Promise<SupportContracts[]>;
@@ -32,6 +33,10 @@ declare class Hermes {
32
33
  data: string;
33
34
  value: bigint;
34
35
  };
36
+ private resolveGasLimit;
37
+ private resolveNonce;
38
+ private resolvePricing;
39
+ private sanitizePricing;
35
40
  private checkIsEnoughToken;
36
41
  private validateParams;
37
42
  private getQuoterAddress;
package/dist/cjs/index.js CHANGED
@@ -35,12 +35,15 @@ __export(src_exports, {
35
35
  DexType: () => import_types.DexType,
36
36
  Hermes: () => Hermes,
37
37
  IEstimateType: () => import_types.IEstimateType,
38
+ LayerZeroV1ChainIdMap: () => import_types.LayerZeroV1ChainIdMap,
39
+ LayerZeroV1ChainNameMap: () => import_types.LayerZeroV1ChainNameMap,
40
+ LayerZeroV2ChainIdMap: () => import_types.LayerZeroV2ChainIdMap,
41
+ LayerZeroV2ChainNameMap: () => import_types.LayerZeroV2ChainNameMap,
38
42
  default: () => src_default
39
43
  });
40
44
  module.exports = __toCommonJS(src_exports);
41
45
  var import_types = require("./types.js");
42
46
  var import_ethers = require("ethers");
43
- var import_ethers2 = require("ethers");
44
47
  var import_quoter = __toESM(require("./abis/quoter.js"));
45
48
  var import_aggregator = __toESM(require("./abis/aggregator.js"));
46
49
  var Hermes = class {
@@ -73,7 +76,7 @@ var Hermes = class {
73
76
  if (!address) {
74
77
  throw new Error(`Quoter address not found for chain: ${params.chain}`);
75
78
  }
76
- const quoter = new import_ethers2.Contract(address, import_quoter.default, wallet);
79
+ const quoter = new import_ethers.Contract(address, import_quoter.default, wallet);
77
80
  const quoteParams = params.path.map((p) => ({
78
81
  dexType: p.dexType,
79
82
  pool: p.poolAddress,
@@ -87,7 +90,7 @@ var Hermes = class {
87
90
  }
88
91
  return amountOutList[amountOutList.length - 1];
89
92
  }
90
- async swap(params) {
93
+ async swap(params, txReq = {}) {
91
94
  this.validateParams(params);
92
95
  if (!params.path.length) {
93
96
  throw new Error("Swap path not provided");
@@ -99,7 +102,7 @@ var Hermes = class {
99
102
  if (!wallet) {
100
103
  throw new Error(`Wallet not configured for chain: ${params.chain}`);
101
104
  }
102
- const aggregator = new import_ethers2.Contract(aggregatorAddress, import_aggregator.default, wallet);
105
+ const aggregator = new import_ethers.Contract(aggregatorAddress, import_aggregator.default, wallet);
103
106
  const swapParams = params.path.map((pathItem) => ({
104
107
  dexType: pathItem.dexType,
105
108
  pool: pathItem.poolAddress,
@@ -107,7 +110,7 @@ var Hermes = class {
107
110
  toCoin: pathItem.toCoinAddress,
108
111
  extra: pathItem.extra ?? "0x"
109
112
  }));
110
- const erc20 = new import_ethers2.Contract(fromTokenAddress, ["function balanceOf(address) view returns (uint256)", "function allowance(address, address) view returns (uint256)"], wallet);
113
+ const erc20 = new import_ethers.Contract(fromTokenAddress, ["function balanceOf(address) view returns (uint256)", "function allowance(address, address) view returns (uint256)"], wallet);
111
114
  const userBalance = await erc20.balanceOf(params.user);
112
115
  if (userBalance < params.amountInWei) {
113
116
  throw new Error("Insufficient balance for swap");
@@ -116,22 +119,21 @@ var Hermes = class {
116
119
  if (currentAllowance < params.amountInWei) {
117
120
  throw new Error("Insufficient allowance token amount for swap");
118
121
  }
122
+ let estimateGas;
123
+ const { gasLimit: _ignore, ...estimationOverrides } = txReq;
119
124
  try {
120
- const gas = await aggregator.getFunction("swap").estimateGas(params.user, params.amountInWei, swapParams, params.minAmountOutList, { from: wallet.address });
125
+ estimateGas = await aggregator.swap.estimateGas(params.user, params.amountInWei, swapParams, params.minAmountOutList, estimationOverrides);
121
126
  } catch (error) {
122
127
  console.warn("Aggregator estimateGas.swap failed", error);
123
128
  throw error;
124
129
  }
125
- let txResponse;
126
- try {
127
- txResponse = await aggregator.getFunction("swap")(params.user, params.amountInWei, swapParams, params.minAmountOutList, { from: wallet.address });
128
- } catch (error) {
129
- console.error("Aggregator swap transaction failed", error);
130
- throw error;
131
- }
130
+ txReq = this.resolveGasLimit(txReq, estimateGas);
131
+ txReq = await this.resolveNonce(wallet.provider, wallet.address, txReq);
132
+ txReq = await this.resolvePricing(wallet.provider, txReq);
133
+ let txResponse = await aggregator.swap(params.user, params.amountInWei, swapParams, params.minAmountOutList, txReq);
132
134
  const receipt = await txResponse.wait();
133
135
  const iface = new import_ethers.ethers.Interface(import_aggregator.default);
134
- let amountOut = params.amountInWei;
136
+ let amountOut = null;
135
137
  for (const log of receipt.logs) {
136
138
  if (log.address.toLowerCase() === aggregatorAddress.toLowerCase()) {
137
139
  try {
@@ -144,6 +146,9 @@ var Hermes = class {
144
146
  }
145
147
  }
146
148
  }
149
+ if (!amountOut) {
150
+ throw new Error(`Swapped event not found: ${receipt.hash}`);
151
+ }
147
152
  return {
148
153
  fromToken: fromTokenAddress,
149
154
  toToken: toTokenAddress,
@@ -178,7 +183,7 @@ var Hermes = class {
178
183
  data: calldata
179
184
  };
180
185
  }
181
- async bridge(params) {
186
+ async bridge(params, txReq = {}) {
182
187
  this.validateParams(params);
183
188
  const aggregatorAddress = this.getAggregatorAddress(params.chain);
184
189
  const wallet = this.walletMap.get(params.chain);
@@ -198,7 +203,7 @@ var Hermes = class {
198
203
  throw new Error("Insufficient native balance for bridge fee");
199
204
  }
200
205
  }
201
- const aggregator = new import_ethers2.Contract(aggregatorAddress, import_aggregator.default, wallet);
206
+ const aggregator = new import_ethers.Contract(aggregatorAddress, import_aggregator.default, wallet);
202
207
  const bridgeArgs = {
203
208
  bridge: params.bridgeType,
204
209
  token: params.tokenAddress,
@@ -208,33 +213,31 @@ var Hermes = class {
208
213
  destUser: params.destUser,
209
214
  extra: params.extra ?? "0x"
210
215
  };
211
- const txOverrides = {
212
- from: wallet.address,
213
- value: params.bridgeFee
214
- };
215
- try {
216
- await aggregator.bridge.estimateGas(params.user, bridgeArgs, txOverrides);
217
- } catch (error) {
218
- console.error("Bridge gas estimation reverted", error);
219
- throw error;
216
+ if (txReq.value == null) {
217
+ txReq = { ...txReq, value: params.bridgeFee };
220
218
  }
221
- let txResponse;
219
+ let estimateGas;
220
+ const { gasLimit: _ignore, ...estimationOverrides } = txReq;
222
221
  try {
223
- txResponse = await aggregator.bridge(params.user, bridgeArgs, txOverrides);
222
+ estimateGas = await aggregator.bridge.estimateGas(params.user, bridgeArgs, estimationOverrides);
224
223
  } catch (error) {
225
- console.error("Aggregator swap transaction failed", error);
224
+ console.error("Bridge gas estimation reverted", error);
226
225
  throw error;
227
226
  }
228
- const receipt = {
227
+ txReq = this.resolveGasLimit(txReq, estimateGas);
228
+ txReq = await this.resolveNonce(wallet.provider, wallet.address, txReq);
229
+ txReq = await this.resolvePricing(wallet.provider, txReq);
230
+ let response = await aggregator.bridge(params.user, bridgeArgs, txReq);
231
+ const txReceipt = await response.wait();
232
+ return {
229
233
  fromToken: params.tokenAddress,
230
234
  toToken: params.tokenAddress,
231
235
  amountOut: params.amountInWei,
232
- hash: txResponse.hash,
233
- from: txResponse.from,
234
- to: txResponse.to,
235
- logs: txResponse.logs
236
+ hash: txReceipt.hash,
237
+ from: txReceipt.from,
238
+ to: txReceipt.to,
239
+ logs: txReceipt.logs
236
240
  };
237
- return Promise.resolve(receipt);
238
241
  }
239
242
  async estimateBridgeFee(params) {
240
243
  this.validateParams(params);
@@ -246,7 +249,7 @@ var Hermes = class {
246
249
  if (!address) {
247
250
  throw new Error(`Quoter address not found for chain: ${params.chain}`);
248
251
  }
249
- const quoter = new import_ethers2.Contract(address, import_quoter.default, wallet);
252
+ const quoter = new import_ethers.Contract(address, import_quoter.default, wallet);
250
253
  const bridgeArgs = {
251
254
  bridge: params.bridgeType,
252
255
  token: params.tokenAddress,
@@ -259,7 +262,7 @@ var Hermes = class {
259
262
  const bridgeFee = await quoter.quoteBridge.staticCall(bridgeArgs, { from: wallet.address });
260
263
  return bridgeFee;
261
264
  }
262
- async swapAndBridge(params) {
265
+ async swapAndBridge(params, txReq = {}) {
263
266
  this.validateParams(params);
264
267
  const aggregatorAddress = this.getAggregatorAddress(params.chain);
265
268
  const wallet = this.walletMap.get(params.chain);
@@ -286,40 +289,49 @@ var Hermes = class {
286
289
  destUser: params.destUser,
287
290
  extra: params.extra ?? "0x"
288
291
  };
289
- const txOverrides = {
290
- from: wallet.address,
291
- value: params.bridgeFee
292
- };
293
- const aggregator = new import_ethers2.Contract(aggregatorAddress, import_aggregator.default, wallet);
294
- try {
295
- await aggregator.swapAndBridge.estimateGas(params.user, params.amountInWei, swapParams, params.minAmountOutList, bridgeArgs, txOverrides);
296
- } catch (error) {
297
- console.error("Bridge gas estimation reverted", error);
298
- throw error;
292
+ if (txReq.value == null) {
293
+ txReq = { ...txReq, value: params.bridgeFee };
294
+ }
295
+ const { gasLimit: _ignore, ...estimationOverrides } = txReq;
296
+ const aggregator = new import_ethers.Contract(aggregatorAddress, import_aggregator.default, wallet);
297
+ let estimateGas = await aggregator.swapAndBridge.estimateGas(params.user, params.amountInWei, swapParams, params.minAmountOutList, bridgeArgs, estimationOverrides);
298
+ txReq = this.resolveGasLimit(txReq, estimateGas);
299
+ txReq = await this.resolveNonce(wallet.provider, wallet.address, txReq);
300
+ txReq = await this.resolvePricing(wallet.provider, txReq);
301
+ let response = await aggregator.swapAndBridge(params.user, params.amountInWei, swapParams, params.minAmountOutList, bridgeArgs, txReq);
302
+ const txReceipt = await response.wait();
303
+ const iface = new import_ethers.ethers.Interface(import_aggregator.default);
304
+ let outputAmountWei = null;
305
+ for (const log of txReceipt.logs) {
306
+ if (log.address.toLowerCase() === aggregatorAddress.toLowerCase()) {
307
+ try {
308
+ const parsed = iface.parseLog(log);
309
+ if (parsed && parsed.name === "SwapAndBridge" && parsed.args && parsed.args.amountOut !== void 0) {
310
+ outputAmountWei = parsed.args.amountOut;
311
+ break;
312
+ }
313
+ } catch {
314
+ }
315
+ }
299
316
  }
300
- let txResponse;
301
- try {
302
- txResponse = await aggregator.swapAndBridge(params.user, params.amountInWei, swapParams, params.minAmountOutList, bridgeArgs, txOverrides);
303
- } catch (error) {
304
- console.error("Aggregator swap and bridge transaction failed", error);
305
- throw error;
317
+ if (!outputAmountWei) {
318
+ throw new Error(`SwapAndBridge event not found: ${txReceipt.hash}`);
306
319
  }
307
- const receipt = {
320
+ return {
308
321
  fromToken: params.path[0].fromCoinAddress,
309
322
  toToken: params.path[params.path.length - 1].toCoinAddress,
310
- amountOut: params.minAmountOutList[params.minAmountOutList.length - 1],
311
- hash: txResponse.hash,
312
- from: txResponse.from,
313
- to: txResponse.to,
314
- logs: txResponse.logs
323
+ amountOut: outputAmountWei,
324
+ hash: txReceipt.hash,
325
+ from: txReceipt.from,
326
+ to: txReceipt.to,
327
+ logs: txReceipt.logs
315
328
  };
316
- return Promise.resolve(receipt);
317
329
  }
318
330
  async estimateGas(estimateType, params) {
319
331
  this.validateParams(params);
320
332
  const aggregatorAddress = this.getAggregatorAddress(params.chain);
321
333
  const wallet = this.walletMap.get(params.chain);
322
- const aggregator = new import_ethers2.Contract(aggregatorAddress, import_aggregator.default, wallet);
334
+ const aggregator = new import_ethers.Contract(aggregatorAddress, import_aggregator.default, wallet);
323
335
  if (!wallet) {
324
336
  throw new Error(`Wallet not configured for chain: ${params.chain}`);
325
337
  }
@@ -396,7 +408,7 @@ var Hermes = class {
396
408
  if (!provider) {
397
409
  throw new Error(`Provider not configured for chain: ${chain}`);
398
410
  }
399
- const aggregator = new import_ethers2.Contract(aggregatorAddress, import_aggregator.default, provider);
411
+ const aggregator = new import_ethers.Contract(aggregatorAddress, import_aggregator.default, provider);
400
412
  const addressList = await aggregator.getAddressList();
401
413
  if (!addressList.length) {
402
414
  return [];
@@ -418,7 +430,7 @@ var Hermes = class {
418
430
  if (!provider) {
419
431
  throw new Error(`Provider not configured for chain: ${chain}`);
420
432
  }
421
- const quoter = new import_ethers2.Contract(quoterAddress, import_quoter.default, provider);
433
+ const quoter = new import_ethers.Contract(quoterAddress, import_quoter.default, provider);
422
434
  const addressList = await quoter.getAddressList();
423
435
  if (!addressList.length) {
424
436
  return [];
@@ -468,14 +480,54 @@ var Hermes = class {
468
480
  value: params.bridgeFee
469
481
  };
470
482
  }
483
+ resolveGasLimit(txReq, estimateGas) {
484
+ if (txReq.gasLimit != null) {
485
+ return txReq;
486
+ }
487
+ return {
488
+ ...txReq,
489
+ gasLimit: estimateGas * 130n / 100n
490
+ // 上浮30%
491
+ };
492
+ }
493
+ async resolveNonce(provider, from, tx) {
494
+ if (tx.nonce != null)
495
+ return tx;
496
+ const nonce = await provider.getTransactionCount(from, "latest");
497
+ return { ...tx, nonce };
498
+ }
499
+ async resolvePricing(provider, tx) {
500
+ if (tx.gasPrice != null || tx.maxFeePerGas != null || tx.maxPriorityFeePerGas != null) {
501
+ return this.sanitizePricing(tx);
502
+ }
503
+ const fd = await provider.getFeeData();
504
+ if (fd.maxFeePerGas != null && fd.maxPriorityFeePerGas != null) {
505
+ return {
506
+ ...tx,
507
+ maxFeePerGas: fd.maxFeePerGas * 150n / 100n,
508
+ // 上浮50%
509
+ maxPriorityFeePerGas: fd.maxPriorityFeePerGas
510
+ };
511
+ }
512
+ if (fd.gasPrice != null) {
513
+ return { ...tx, gasPrice: fd.gasPrice };
514
+ }
515
+ return tx;
516
+ }
517
+ sanitizePricing(tx) {
518
+ if (tx.maxFeePerGas != null || tx.maxPriorityFeePerGas != null) {
519
+ const { gasPrice, ...rest } = tx;
520
+ return rest;
521
+ }
522
+ return tx;
523
+ }
471
524
  async checkIsEnoughToken(fromTokenAddress, userAddress, amountInWei, aggregatorAddress, wallet) {
472
- const erc20 = new import_ethers2.Contract(fromTokenAddress, ["function balanceOf(address) view returns (uint256)", "function allowance(address, address) view returns (uint256)"], wallet);
525
+ const erc20 = new import_ethers.Contract(fromTokenAddress, ["function balanceOf(address) view returns (uint256)", "function allowance(address, address) view returns (uint256)"], wallet);
473
526
  const userBalance = await erc20.balanceOf(userAddress);
474
527
  if (userBalance < amountInWei) {
475
528
  throw new Error("Insufficient balance token amount");
476
529
  }
477
530
  const currentAllowance = await erc20.allowance(userAddress, aggregatorAddress);
478
- console.log(currentAllowance);
479
531
  if (currentAllowance < amountInWei) {
480
532
  throw new Error("Insufficient allowance token amount");
481
533
  }
@@ -510,5 +562,9 @@ var src_default = Hermes;
510
562
  ChainNameEnum,
511
563
  DexType,
512
564
  Hermes,
513
- IEstimateType
565
+ IEstimateType,
566
+ LayerZeroV1ChainIdMap,
567
+ LayerZeroV1ChainNameMap,
568
+ LayerZeroV2ChainIdMap,
569
+ LayerZeroV2ChainNameMap
514
570
  });
@@ -109,7 +109,11 @@ export declare enum DexType {
109
109
  VSDCRVWITHDRAW = "vsdCRV_withdraw",
110
110
  VSDCRVDEPOSIT = "vsdCRV_deposit",
111
111
  ASDCRVWITHDRAW = "asdCRV_withdraw",
112
- ASDCRVDEPOSIT = "asdCRV_deposit"
112
+ ASDCRVDEPOSIT = "asdCRV_deposit",
113
+ SHADOWV3 = "shadowv3",
114
+ FRAXSWAPV2 = "fraxswapv2",
115
+ AERODROMEV2 = "aerodromev2",
116
+ SHADOWV2 = "shadowv2"
113
117
  }
114
118
  export declare enum IEstimateType {
115
119
  BRIDGE = "bridge",
@@ -122,7 +126,13 @@ export declare enum BridgeType {
122
126
  LAYERZEROV1ADADEQEMPTY = "layerzero_v1_adapter_eq_empty",
123
127
  LAYERZEROV1PKG = "layerzero_v1_pkg",
124
128
  LAYERZEROV1PKGNOMIN = "layerzero_v1_pkg_no_min",
125
- LAYERZEROV1OHM = "layerzero_v1_ohm"
129
+ LAYERZEROV1OHM = "layerzero_v1_ohm",
130
+ ARBETHBRIDGE = "arb_eth_bridge",
131
+ ETHARBBRIDGE = "eth_arb_bridge",
132
+ ORIGINALTOKENBRIDGE = "original_token_bridge",
133
+ WRAPPEDTOKENBRIDGE = "wrapped_token_bridge",
134
+ CCIPBRIDGE = "ccip_bridge",
135
+ WORMHOLEBRIDGE = "wormhole_bridge"
126
136
  }
127
137
  export declare enum ChainNameEnum {
128
138
  ETH = "ETH",// Ethereum Mainnet
@@ -288,23 +298,46 @@ export declare const AddressConst: {
288
298
  eth: string;
289
299
  arb: string;
290
300
  base: string;
301
+ etherlink: string;
302
+ };
303
+ wfrax: {
304
+ fraxtal: string;
305
+ };
306
+ frxusd: {
307
+ fraxtal: string;
291
308
  };
292
309
  seth: {
293
310
  eth: string;
294
311
  };
295
312
  wbtc: {
296
313
  eth: string;
314
+ etherlink: string;
315
+ arb: string;
316
+ base: string;
317
+ };
318
+ fluid: {
319
+ arb: string;
297
320
  };
298
321
  usdt: {
299
322
  eth: string;
323
+ base: string;
324
+ };
325
+ drv: {
326
+ eth: string;
300
327
  };
301
328
  feth: {
302
329
  eth: string;
303
330
  arb: string;
304
331
  };
332
+ msq: {
333
+ pol: string;
334
+ };
305
335
  sdcrv: {
306
336
  eth: string;
307
337
  };
338
+ tlos: {
339
+ eth: string;
340
+ };
308
341
  crv: {
309
342
  eth: string;
310
343
  };
@@ -318,20 +351,41 @@ export declare const AddressConst: {
318
351
  asdcrv: {
319
352
  eth: string;
320
353
  };
354
+ allo: {
355
+ base: string;
356
+ };
321
357
  emp: {
322
358
  base: string;
323
359
  };
360
+ order: {
361
+ base: string;
362
+ };
363
+ eul: {
364
+ sonic: string;
365
+ };
324
366
  arb: {
325
367
  arb: string;
326
368
  };
369
+ usde: {
370
+ eth: string;
371
+ };
327
372
  usdc: {
328
373
  arb: string;
329
374
  eth: string;
375
+ sonic: string;
376
+ etherlink: string;
377
+ };
378
+ link: {
379
+ eth: string;
330
380
  };
331
381
  ohm: {
332
382
  arb: string;
333
383
  };
334
384
  };
385
+ export declare const LayerZeroV1ChainIdMap: Record<number, ChainNameEnum>;
386
+ export declare const LayerZeroV1ChainNameMap: Record<ChainNameEnum, number>;
387
+ export declare const LayerZeroV2ChainIdMap: Record<number, ChainNameEnum>;
388
+ export declare const LayerZeroV2ChainNameMap: Record<ChainNameEnum, number>;
335
389
  export interface IExpectPayload {
336
390
  }
337
391
  export interface IRouterPath {