hermes-swap 0.6.6 → 0.6.8

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.
@@ -877,8 +877,19 @@ var _Aggregator = class {
877
877
  static isBenignBroadcastError(message) {
878
878
  return message.includes("already known") || message.includes("nonce too low") || message.includes("nonce has already been used") || message.includes("ALREADY_EXISTS") || message.includes("NONCE_EXPIRED");
879
879
  }
880
- async waitForBundleInclusion(provider, txHash, maxTargetBlock, signal) {
881
- const deadline = Date.now() + _Aggregator.BUNDLE_INCLUSION_TIMEOUT_MS;
880
+ async blockContainsTxHash(provider, blockNumber, txHash) {
881
+ try {
882
+ const block = await provider.getBlock(blockNumber, true);
883
+ if (!block)
884
+ return false;
885
+ if (block.transactions.some((hash) => hash === txHash))
886
+ return true;
887
+ return block.prefetchedTransactions.some((tx) => tx.hash === txHash);
888
+ } catch {
889
+ return false;
890
+ }
891
+ }
892
+ async waitForReceipt(provider, txHash, deadline, signal) {
882
893
  while (Date.now() < deadline) {
883
894
  if (signal == null ? void 0 : signal.aborted)
884
895
  return null;
@@ -888,12 +899,119 @@ var _Aggregator = class {
888
899
  return receipt;
889
900
  } catch {
890
901
  }
891
- const currentBlock = await provider.getBlockNumber().catch(() => 0);
892
- if (currentBlock > maxTargetBlock + 1)
893
- return null;
894
- await new Promise((r) => setTimeout(r, _Aggregator.BUNDLE_POLL_INTERVAL_MS));
902
+ await new Promise((r) => setTimeout(r, 200));
895
903
  }
896
- return null;
904
+ try {
905
+ const receipt = await provider.getTransactionReceipt(txHash);
906
+ return receipt ? receipt : null;
907
+ } catch {
908
+ return null;
909
+ }
910
+ }
911
+ async waitForBundleInclusion(provider, txHash, targetBlocks, signal) {
912
+ const deadline = Date.now() + _Aggregator.BUNDLE_INCLUSION_TIMEOUT_MS;
913
+ const sortedTargetBlocks = [...targetBlocks].sort((a, b) => a - b);
914
+ const targetBlockSet = new Set(sortedTargetBlocks);
915
+ const maxTargetBlock = sortedTargetBlocks[sortedTargetBlocks.length - 1];
916
+ return new Promise((resolve) => {
917
+ let settled = false;
918
+ let lastObservedBlock = sortedTargetBlocks[0] - 1;
919
+ const checkedBlocks = /* @__PURE__ */ new Set();
920
+ let matchedTargetBlock = false;
921
+ let inspectionChain = Promise.resolve();
922
+ const cleanup = () => {
923
+ clearTimeout(timer);
924
+ provider.off("block", onBlock);
925
+ };
926
+ const finish = (receipt) => {
927
+ if (settled)
928
+ return;
929
+ settled = true;
930
+ cleanup();
931
+ resolve(receipt);
932
+ };
933
+ const scheduleInspect = (fromBlock, toBlock) => {
934
+ if (fromBlock > toBlock) {
935
+ if (checkedBlocks.size === targetBlockSet.size && lastObservedBlock >= maxTargetBlock) {
936
+ finish(null);
937
+ }
938
+ return;
939
+ }
940
+ inspectionChain = inspectionChain.then(() => inspectTargetBlocks(fromBlock, toBlock)).catch(() => {
941
+ });
942
+ };
943
+ const inspectTargetBlocks = async (fromBlock, toBlock) => {
944
+ if (settled || (signal == null ? void 0 : signal.aborted)) {
945
+ finish(null);
946
+ return;
947
+ }
948
+ for (let blockNumber = fromBlock; blockNumber <= toBlock; blockNumber++) {
949
+ if (settled || (signal == null ? void 0 : signal.aborted)) {
950
+ finish(null);
951
+ return;
952
+ }
953
+ if (!targetBlockSet.has(blockNumber) || checkedBlocks.has(blockNumber))
954
+ continue;
955
+ checkedBlocks.add(blockNumber);
956
+ const matched = await this.blockContainsTxHash(provider, blockNumber, txHash);
957
+ if (!matched)
958
+ continue;
959
+ matchedTargetBlock = true;
960
+ clearTimeout(timer);
961
+ const receipt = await this.waitForReceipt(provider, txHash, Date.now() + _Aggregator.TX_CONFIRM_TIMEOUT_MS, signal);
962
+ finish(receipt);
963
+ return;
964
+ }
965
+ if (checkedBlocks.size === targetBlockSet.size && lastObservedBlock >= maxTargetBlock) {
966
+ finish(null);
967
+ }
968
+ };
969
+ const onBlock = (blockNumber) => {
970
+ if (settled)
971
+ return;
972
+ const fromBlock = Math.max(lastObservedBlock + 1, sortedTargetBlocks[0]);
973
+ const toBlock = Math.min(blockNumber, maxTargetBlock);
974
+ if (blockNumber > lastObservedBlock) {
975
+ lastObservedBlock = blockNumber;
976
+ }
977
+ if (fromBlock > toBlock) {
978
+ if (checkedBlocks.size === targetBlockSet.size && lastObservedBlock >= maxTargetBlock) {
979
+ finish(null);
980
+ }
981
+ return;
982
+ }
983
+ scheduleInspect(fromBlock, toBlock);
984
+ };
985
+ const timer = setTimeout(async () => {
986
+ if (settled)
987
+ return;
988
+ if (matchedTargetBlock)
989
+ return;
990
+ const latestBlock = await provider.getBlockNumber().catch(() => lastObservedBlock);
991
+ if (latestBlock > lastObservedBlock) {
992
+ lastObservedBlock = latestBlock;
993
+ }
994
+ const toBlock = Math.min(latestBlock, maxTargetBlock);
995
+ scheduleInspect(sortedTargetBlocks[0], toBlock);
996
+ await inspectionChain;
997
+ finish(null);
998
+ }, _Aggregator.BUNDLE_INCLUSION_TIMEOUT_MS);
999
+ provider.on("block", onBlock);
1000
+ provider.getBlockNumber().then(
1001
+ (currentBlock) => {
1002
+ if (settled)
1003
+ return;
1004
+ lastObservedBlock = currentBlock;
1005
+ const fromBlock = sortedTargetBlocks[0];
1006
+ const toBlock = Math.min(currentBlock, maxTargetBlock);
1007
+ if (fromBlock <= toBlock) {
1008
+ scheduleInspect(fromBlock, toBlock);
1009
+ }
1010
+ },
1011
+ () => {
1012
+ }
1013
+ );
1014
+ });
897
1015
  }
898
1016
  async sendSignedTxToChannels(chain, signedTx, txHash, channels) {
899
1017
  const results = await Promise.all(
@@ -1141,8 +1259,7 @@ var _Aggregator = class {
1141
1259
  });
1142
1260
  });
1143
1261
  const abortController = new AbortController();
1144
- const maxTargetBlock = Math.max(...targetBlocks);
1145
- const inclusionPromise = this.waitForBundleInclusion(provider, txHash, maxTargetBlock, abortController.signal);
1262
+ const inclusionPromise = this.waitForBundleInclusion(provider, txHash, targetBlocks, abortController.signal);
1146
1263
  const waitTs = Date.now();
1147
1264
  const [receipt] = await Promise.all([
1148
1265
  inclusionPromise,
@@ -1313,7 +1430,6 @@ Aggregator.SEQUENCER_CHAINS = new Set(
1313
1430
  Object.keys(_Aggregator.DEFAULT_SEQUENCER_RPC_BY_CHAIN)
1314
1431
  );
1315
1432
  Aggregator.TX_CONFIRM_TIMEOUT_MS = 12e4;
1316
- Aggregator.BUNDLE_POLL_INTERVAL_MS = 500;
1317
1433
  Aggregator.BUNDLE_INCLUSION_TIMEOUT_MS = 3e4;
1318
1434
  var aggregator_default = Aggregator;
1319
1435
  // Annotate the CommonJS export names for ESM import in node:
@@ -55,9 +55,10 @@ declare class Aggregator {
55
55
  estimateGas(estimateType: IEstimateType, params: IBridgeParams | ISwapByPathParams | ISwapAndBridgeParams | IBatchMultiSwapParams): Promise<bigint>;
56
56
  getAggregatorSupportContracts(chain: ChainNameEnum): Promise<SupportContracts[]>;
57
57
  private static readonly TX_CONFIRM_TIMEOUT_MS;
58
- private static readonly BUNDLE_POLL_INTERVAL_MS;
59
58
  private static readonly BUNDLE_INCLUSION_TIMEOUT_MS;
60
59
  private static isBenignBroadcastError;
60
+ private blockContainsTxHash;
61
+ private waitForReceipt;
61
62
  private waitForBundleInclusion;
62
63
  private sendSignedTxToChannels;
63
64
  private raceForReceipt;
@@ -1,7 +1,7 @@
1
- import type { HermesTxRequest, IBatchMultiSwapParams, IBatchExpectParams, ISwapByPathParams, IExpectSplitOrderParams, IExpectSplitOrderResp, IBridgeParams, IBatchReceipt, IMultiSwapParams, IBatchMultiSwapAndBridgeParams, ISwapAndBridgeParams, IReceipt, IConfig, IBuilderConfig, IExpectPayload, IRouterPath, SupportContracts, IExpectByPathParams, IHermesSignalResponse, IHermesSignalRoute } from './types.js';
1
+ import type { HermesTxRequest, IBatchMultiSwapParams, IBatchExpectParams, ISwapByPathParams, IExpectSplitOrderParams, IExpectSplitOrderResp, IBridgeParams, IBatchReceipt, IMultiSwapParams, IBatchMultiSwapAndBridgeParams, ISwapAndBridgeParams, IReceipt, IConfig, IBuilderConfig, IExpectPayload, IRouterPath, SupportContracts, IExpectByPathParams, IHermesSignalResponse, IHermesSignalQuoteBestData, IHermesSignalRoute } from './types.js';
2
2
  import { ChainNameEnum, AddressConst, DexType, BridgeType, IEstimateType, LayerZeroV1ChainIdMap, LayerZeroV1ChainNameMap, LayerZeroV2ChainIdMap, LayerZeroV2ChainNameMap } from './types.js';
3
3
  import { TransactionRequest } from 'ethers';
4
- export type { HermesTxRequest, IBatchMultiSwapAndBridgeParams, IExpectSplitOrderParams, IExpectSplitOrderResp, IMultiSwapParams, IBatchMultiSwapParams, IBatchExpectParams, IBatchReceipt, ISwapByPathParams as ISwapParams, IBridgeParams, ISwapAndBridgeParams, IReceipt, IConfig, IBuilderConfig, IExpectPayload, IRouterPath, SupportContracts, IHermesSignalResponse, IHermesSignalRoute, };
4
+ export type { HermesTxRequest, IBatchMultiSwapAndBridgeParams, IExpectSplitOrderParams, IExpectSplitOrderResp, IMultiSwapParams, IBatchMultiSwapParams, IBatchExpectParams, IBatchReceipt, ISwapByPathParams as ISwapParams, IBridgeParams, ISwapAndBridgeParams, IReceipt, IConfig, IBuilderConfig, IExpectPayload, IRouterPath, SupportContracts, IHermesSignalResponse, IHermesSignalQuoteBestData, IHermesSignalRoute, };
5
5
  import { BundleNotIncludedError, TransactionRevertedError } from './types.js';
6
6
  export { ChainNameEnum, AddressConst, DexType, BridgeType, IEstimateType, LayerZeroV1ChainIdMap, LayerZeroV1ChainNameMap, LayerZeroV2ChainIdMap, LayerZeroV2ChainNameMap, BundleNotIncludedError, TransactionRevertedError };
7
7
  declare class Hermes {
@@ -32,6 +32,7 @@ var Provider = class {
32
32
  for (const [chainName, rpc] of Object.entries(this.config.rpc)) {
33
33
  const chain = chainName;
34
34
  const provider = new import_ethers.ethers.JsonRpcProvider(rpc.url);
35
+ provider.pollingInterval = 500;
35
36
  this.providerMap.set(chain, provider);
36
37
  if (rpc.privateKey) {
37
38
  this.walletMap.set(chain, new import_ethers.ethers.Wallet(rpc.privateKey, provider));
@@ -88,7 +88,7 @@ var Quoter = class {
88
88
  if (raw.code !== 200) {
89
89
  throw new Error(`Hermes Signal API 错误 [${raw.code}]`);
90
90
  }
91
- const allocations = (_a = raw.data) == null ? void 0 : _a.allocations;
91
+ const allocations = (_a = raw.data) == null ? void 0 : _a.route_allocation;
92
92
  if (!Array.isArray(allocations)) {
93
93
  throw new Error(`Invalid response data: ${JSON.stringify(raw.data)}`);
94
94
  }
@@ -149,10 +149,11 @@ export interface IHermesSignalResponse<T> {
149
149
  data: T;
150
150
  }
151
151
  export interface IHermesSignalRoute {
152
- chain: 'ETH';
152
+ chain: string;
153
153
  poolStepConfig: Array<{
154
154
  dexType: string;
155
155
  poolAddress: string;
156
+ poolId?: string;
156
157
  fromCoinAddress: string;
157
158
  toCoinAddress: string;
158
159
  extra?: string;
@@ -161,6 +162,13 @@ export interface IHermesSignalRoute {
161
162
  amountOutWei: string;
162
163
  blockNumber: number;
163
164
  }
165
+ export interface IHermesSignalQuoteBestData {
166
+ amount_in: string;
167
+ amount_out: string;
168
+ route_allocation: IHermesSignalRoute[];
169
+ allocations: IHermesSignalRoute[];
170
+ elapsed_ms: number;
171
+ }
164
172
  export declare enum DexType {
165
173
  FX = "f(x)",
166
174
  UNISWAPV2 = "uniswapv2",
@@ -55,9 +55,10 @@ declare class Aggregator {
55
55
  estimateGas(estimateType: IEstimateType, params: IBridgeParams | ISwapByPathParams | ISwapAndBridgeParams | IBatchMultiSwapParams): Promise<bigint>;
56
56
  getAggregatorSupportContracts(chain: ChainNameEnum): Promise<SupportContracts[]>;
57
57
  private static readonly TX_CONFIRM_TIMEOUT_MS;
58
- private static readonly BUNDLE_POLL_INTERVAL_MS;
59
58
  private static readonly BUNDLE_INCLUSION_TIMEOUT_MS;
60
59
  private static isBenignBroadcastError;
60
+ private blockContainsTxHash;
61
+ private waitForReceipt;
61
62
  private waitForBundleInclusion;
62
63
  private sendSignedTxToChannels;
63
64
  private raceForReceipt;