@hyperbridge/simplex 0.17.0 → 0.17.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 +1 -1
- package/dist/bin/simplex.js +234 -442
- package/dist/bin/simplex.js.map +1 -1
- package/dist/index.cjs +131 -170
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -7
- package/dist/index.d.ts +6 -7
- package/dist/index.js +119 -159
- package/dist/index.js.map +1 -1
- package/dist/ui/assets/{index-D8DLeEH0.js → index-BctI82KY.js} +31 -31
- package/dist/ui/index.html +1 -1
- package/package.json +2 -2
package/dist/bin/simplex.js
CHANGED
|
@@ -235283,31 +235283,73 @@ function userOperationLogs(logs, entryPoint, userOpHash) {
|
|
|
235283
235283
|
while (start >= 0 && !isBoundary(logs[start])) start--;
|
|
235284
235284
|
return logs.slice(start + 1, end);
|
|
235285
235285
|
}
|
|
235286
|
-
async function
|
|
235287
|
-
if (
|
|
235286
|
+
async function rundlerRequest(bundlerUrl, method, unsupported) {
|
|
235287
|
+
if (unsupported.has(bundlerUrl)) return null;
|
|
235288
235288
|
try {
|
|
235289
235289
|
const response = await fetch(bundlerUrl, {
|
|
235290
235290
|
method: "POST",
|
|
235291
235291
|
headers: { "Content-Type": "application/json" },
|
|
235292
|
-
body: JSON.stringify({
|
|
235293
|
-
jsonrpc: "2.0",
|
|
235294
|
-
id: 1,
|
|
235295
|
-
method: BundlerMethod.RUNDLER_MAX_PRIORITY_FEE_PER_GAS,
|
|
235296
|
-
params: []
|
|
235297
|
-
})
|
|
235292
|
+
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params: [] })
|
|
235298
235293
|
});
|
|
235299
235294
|
const { result, error } = await response.json();
|
|
235300
235295
|
if (error) {
|
|
235301
235296
|
if (error.code !== void 0 && UNSUPPORTED_REQUEST_CODES.has(error.code)) {
|
|
235302
|
-
|
|
235297
|
+
unsupported.add(bundlerUrl);
|
|
235303
235298
|
}
|
|
235304
235299
|
return null;
|
|
235305
235300
|
}
|
|
235301
|
+
return result ?? null;
|
|
235302
|
+
} catch {
|
|
235303
|
+
return null;
|
|
235304
|
+
}
|
|
235305
|
+
}
|
|
235306
|
+
async function fetchRundlerPriorityFee(bundlerUrl) {
|
|
235307
|
+
const result = await rundlerRequest(
|
|
235308
|
+
bundlerUrl,
|
|
235309
|
+
BundlerMethod.RUNDLER_MAX_PRIORITY_FEE_PER_GAS,
|
|
235310
|
+
bundlersWithoutRundlerFees
|
|
235311
|
+
);
|
|
235312
|
+
try {
|
|
235306
235313
|
return result == null ? null : BigInt(result);
|
|
235307
235314
|
} catch {
|
|
235308
235315
|
return null;
|
|
235309
235316
|
}
|
|
235310
235317
|
}
|
|
235318
|
+
async function fetchRundlerSuggestedFees(bundlerUrl) {
|
|
235319
|
+
const result = await rundlerRequest(
|
|
235320
|
+
bundlerUrl,
|
|
235321
|
+
BundlerMethod.RUNDLER_GET_USER_OPERATION_GAS_PRICE,
|
|
235322
|
+
bundlersWithoutRundlerGasPrice
|
|
235323
|
+
);
|
|
235324
|
+
const suggested = result?.suggested;
|
|
235325
|
+
if (suggested?.maxFeePerGas == null || suggested.maxPriorityFeePerGas == null) return null;
|
|
235326
|
+
try {
|
|
235327
|
+
return {
|
|
235328
|
+
maxFeePerGas: BigInt(suggested.maxFeePerGas),
|
|
235329
|
+
maxPriorityFeePerGas: BigInt(suggested.maxPriorityFeePerGas)
|
|
235330
|
+
};
|
|
235331
|
+
} catch {
|
|
235332
|
+
return null;
|
|
235333
|
+
}
|
|
235334
|
+
}
|
|
235335
|
+
async function rundlerUserOperationFees(bundlerUrl, fees4, params) {
|
|
235336
|
+
const { baseFeePerGas, priorityFeeBumpPercent, maxFeeBumpPercent } = params;
|
|
235337
|
+
const suggested = await fetchRundlerSuggestedFees(bundlerUrl);
|
|
235338
|
+
if (suggested) {
|
|
235339
|
+
return {
|
|
235340
|
+
maxFeePerGas: suggested.maxFeePerGas + suggested.maxFeePerGas * maxFeeBumpPercent / 100n,
|
|
235341
|
+
maxPriorityFeePerGas: suggested.maxPriorityFeePerGas + suggested.maxPriorityFeePerGas * priorityFeeBumpPercent / 100n
|
|
235342
|
+
};
|
|
235343
|
+
}
|
|
235344
|
+
const rundlerPriorityFee = await fetchRundlerPriorityFee(bundlerUrl);
|
|
235345
|
+
if (rundlerPriorityFee === null) return fees4;
|
|
235346
|
+
return applyRundlerPriorityFee(fees4, {
|
|
235347
|
+
rundlerPriorityFee,
|
|
235348
|
+
baseFeePerGas,
|
|
235349
|
+
priorityFeeBumpPercent,
|
|
235350
|
+
maxFeeBumpPercent
|
|
235351
|
+
});
|
|
235352
|
+
}
|
|
235311
235353
|
function applyRundlerPriorityFee(fees4, params) {
|
|
235312
235354
|
const { rundlerPriorityFee, baseFeePerGas, priorityFeeBumpPercent, maxFeeBumpPercent } = params;
|
|
235313
235355
|
const priorityFloor = rundlerPriorityFee + rundlerPriorityFee * priorityFeeBumpPercent / 100n;
|
|
@@ -235502,7 +235544,7 @@ function encodePhantomBidDeclaration(declaration) {
|
|
|
235502
235544
|
}
|
|
235503
235545
|
return u8aToHex(new Uint8Array(bytes5));
|
|
235504
235546
|
}
|
|
235505
|
-
var import_merge_race, __defProp3, __getOwnPropNames2, __esm2, __export2, node_exports, wasm, full_path, __dirname$1, cachedTextDecoder, cachedUint8ArrayMemory0, WASM_VECTOR_LEN, cachedTextEncoder, encodeString5, cachedDataViewMemory0, KeccakMergeFinalization, KeccakMerge, wasmPath, wasmBytes2, bindings, wasmModule, wasmInstance, __wasm, init_node11, RequestStatus, TimeoutStatus, IntentOrderStatus, ABI, evmHost_default, ABI2, handlerV2_default, polkadotAssetHubPaseo, polkadotHubMainnet, pharosMainnet, pharosAtlantic, tronNile, ENTRY_POINT_V08, ENTRY_POINT_V09, KNOWN_ENTRY_POINTS, chainConfigs, configsByStateMachineId, getConfigByStateMachineId, getChainId3, getViemChain, hyperbridgeAddress, ABI3, IntentGatewayV2_default, ChainConfigService, ABI4, uniswapRouterV2_default, chains, DEFAULT_ADDRESS, EvmChain, REQUEST_COMMITMENTS_SLOT, RESPONSE_COMMITMENTS_SLOT, REQUEST_RECEIPTS_SLOT, STATE_COMMITMENTS_SLOT, MISSING_CONSENSUS_UPDATE_TIME_MESSAGE, MissingConsensusUpdateTimeError, TokenBucket, BATCHES_NOT_SUPPORTED_CODE, TOO_BIG_BATCH_REQUEST_CODE, DEFAULT_MAX_BATCH_SIZE, _endpoint2, _headers3, _limiter, _maxBatchSize, _batchingSupported, _pending2, _flushTimer, _flushing, _nextId, __BatchingHttpProvider_instances, scheduleFlush_fn, flushNow_fn, flush_fn, post_fn, settleBatch_fn, settle_fn, handleBatchRefusal_fn, requeue_fn, _a5, BatchingHttpProvider, OFFCHAIN_BID_PREFIX, HYPERBRIDGE_TYPES_BUNDLE, BASE_TIP, HTTP_CONNECT_TIMEOUT_MS, INCLUSION_TIMEOUT_MS, DEFAULT_RPC_MAX_RPS, rpcLimiters, BidCodec, PackedUserOperationCodec, IntentsCoprocessor, ReviveContractInfo, ReviveAccountType, ReviveAccountInfo, H256, EvmStateProof, SubstrateHashing, SubstrateStateMachineProof, BasicProof, LeafIndexAndPos, MmrProof, ConsensusStateId, ConsensusMessage, FraudProofMessage, StateMachine, StateMachineId, StateMachineHeight, Proof, PostRequest, PostResponse, GetRequest, StorageValue, GetResponse, Request3, Response2, RequestMessage, RequestResponse, ResponseMessage, TimeoutMessage, GetRequestsWithProof, Message, DEFAULT_CHILD_STORAGE_PREFIX, PharosProofNodeCodec, SiblingLeftmostLeafProofCodec, NonExistenceProofCodec, AccountProofDataCodec, PharosStateProof, DEFAULT_POLL_INTERVAL, ADDRESS_ZERO2, DEFAULT_GRAFFITI, DEFAULT_LOGGER, REQUEST_STATUS_WEIGHTS, TIMEOUT_STATUS_WEIGHTS, COMBINED_STATUS_WEIGHTS, CHAIN_ID_TO_COINGECKO_NATIVE, TESTNET_CHAINS, ORDER_STATUS, loadDriver, detectEnvironment, STORAGE_KEYS, LEGACY_STORAGE_KEYS, ABI5, uniswapV3Quoter_default, UNISWAP_V4_QUOTER_ABI, ABI6, universalRouter_default, PERMIT2_ABI, UniswapQuoteEngine, COMMON_FEE_TIERS, Swap, ABI7, erc7281_default, DEFAULT_GRAFFITI2, ERC7821_BATCH_MODE, BundlerMethod, SELECT_SOLVER_TYPEHASH, LEGACY_SELECT_SOLVER_TYPEHASH, PACKED_USEROP_TYPEHASH, DOMAIN_TYPEHASH, CryptoUtils, FEE_TOKEN_CACHE_TTL_MS, OrderPlacer, TOKEN_KEYED_GATEWAY_ABI, keyingByClient, PARTIAL_FILLS_SLOT, USED_USEROPS_STORAGE_KEY, OrderExecutor, _a6, OrderCanceller, FILL_ORDER_SELECTOR, SUPPORTED_INTENTS_VERSION, TESTNET_INTENTS_VERSIONS, CONTRACT_VERSION_ABI, CANONICAL_EVM_TOKEN, formats, SELECTION_PARAMS_SLOT, SOLVER_SELECTION_CLEARED, SELECTION_FORMAT_BY_ENTRY_POINT, ENTRY_POINT_EVENT_ABI, BidImpl, BidManager, UNSUPPORTED_REQUEST_CODES, bundlersWithoutRundlerFees, RELAYER_MESSAGE_GAS, NO_BUNDLER_FILL_GAS_BASE, NO_BUNDLER_FILL_GAS_PER_OUTPUT, NO_BUNDLER_PAYMASTER_VERIFICATION_GAS, NO_BUNDLER_PAYMASTER_POST_OP_GAS, BID_PVG_ESTIMATION_ACCOUNT_CODE, BID_PVG_ESTIMATION_PAYMASTER_CODE, SELECTED_BID_SIGNATURE_BYTES, BID_PVG_HEADROOM_PERCENT, ESCROW_MAPPING_SLOT, GasEstimator, OrderStatusChecker, ORDERBOOK_URLS, ORDERBOOK_DECIMALS, ORDERBOOK_SCALE, OrderbookRequestError, RATE_FIELDS, TOP_OF_BOOK_QUERY, ROUTE_LIQUIDITY_QUERY, QUOTE_QUERY, QUOTE_PESSIMISTIC_QUERY, HyperFxOrderbook, UnsupportedLiquidityAssetError, UnsupportedLiquidityChainError, OrderbookQuoteNotConvergedError, MAX_EXACT_OUTPUT_ROUNDS, OrderbookMarket, ETHEREUM_ORDER_FEE_GAS_PRICE_BUMP_PERCENT, DEFAULT_ORDER_FEE_GAS_PRICE_BUMP_PERCENT, IntentGateway, DECLARATION_V1, DECLARATION_V2, PAYMASTER_ADDRESS_BYTES, PAYMASTER_GAS_LIMIT_BYTES, PAYMASTER_DATA_OFFSET, PERMIT2_DATA_BYTES, PERMIT2_SPONSORSHIP_BYTES, MAX_DECLARED_ENTRIES, MAX_TOKEN_ID_BYTES, TeleportParams, MultiAccount;
|
|
235547
|
+
var import_merge_race, __defProp3, __getOwnPropNames2, __esm2, __export2, node_exports, wasm, full_path, __dirname$1, cachedTextDecoder, cachedUint8ArrayMemory0, WASM_VECTOR_LEN, cachedTextEncoder, encodeString5, cachedDataViewMemory0, KeccakMergeFinalization, KeccakMerge, wasmPath, wasmBytes2, bindings, wasmModule, wasmInstance, __wasm, init_node11, RequestStatus, TimeoutStatus, IntentOrderStatus, ABI, evmHost_default, ABI2, handlerV2_default, polkadotAssetHubPaseo, polkadotHubMainnet, pharosMainnet, pharosAtlantic, tronNile, ENTRY_POINT_V08, ENTRY_POINT_V09, KNOWN_ENTRY_POINTS, chainConfigs, configsByStateMachineId, getConfigByStateMachineId, getChainId3, getViemChain, hyperbridgeAddress, ABI3, IntentGatewayV2_default, ChainConfigService, ABI4, uniswapRouterV2_default, chains, DEFAULT_ADDRESS, EvmChain, REQUEST_COMMITMENTS_SLOT, RESPONSE_COMMITMENTS_SLOT, REQUEST_RECEIPTS_SLOT, STATE_COMMITMENTS_SLOT, MISSING_CONSENSUS_UPDATE_TIME_MESSAGE, MissingConsensusUpdateTimeError, TokenBucket, BATCHES_NOT_SUPPORTED_CODE, TOO_BIG_BATCH_REQUEST_CODE, DEFAULT_MAX_BATCH_SIZE, _endpoint2, _headers3, _limiter, _maxBatchSize, _batchingSupported, _pending2, _flushTimer, _flushing, _nextId, __BatchingHttpProvider_instances, scheduleFlush_fn, flushNow_fn, flush_fn, post_fn, settleBatch_fn, settle_fn, handleBatchRefusal_fn, requeue_fn, _a5, BatchingHttpProvider, OFFCHAIN_BID_PREFIX, HYPERBRIDGE_TYPES_BUNDLE, BASE_TIP, HTTP_CONNECT_TIMEOUT_MS, INCLUSION_TIMEOUT_MS, DEFAULT_RPC_MAX_RPS, rpcLimiters, BidCodec, PackedUserOperationCodec, IntentsCoprocessor, ReviveContractInfo, ReviveAccountType, ReviveAccountInfo, H256, EvmStateProof, SubstrateHashing, SubstrateStateMachineProof, BasicProof, LeafIndexAndPos, MmrProof, ConsensusStateId, ConsensusMessage, FraudProofMessage, StateMachine, StateMachineId, StateMachineHeight, Proof, PostRequest, PostResponse, GetRequest, StorageValue, GetResponse, Request3, Response2, RequestMessage, RequestResponse, ResponseMessage, TimeoutMessage, GetRequestsWithProof, Message, DEFAULT_CHILD_STORAGE_PREFIX, PharosProofNodeCodec, SiblingLeftmostLeafProofCodec, NonExistenceProofCodec, AccountProofDataCodec, PharosStateProof, DEFAULT_POLL_INTERVAL, ADDRESS_ZERO2, DEFAULT_GRAFFITI, DEFAULT_LOGGER, REQUEST_STATUS_WEIGHTS, TIMEOUT_STATUS_WEIGHTS, COMBINED_STATUS_WEIGHTS, CHAIN_ID_TO_COINGECKO_NATIVE, TESTNET_CHAINS, ORDER_STATUS, loadDriver, detectEnvironment, STORAGE_KEYS, LEGACY_STORAGE_KEYS, ABI5, uniswapV3Quoter_default, UNISWAP_V4_QUOTER_ABI, ABI6, universalRouter_default, PERMIT2_ABI, UniswapQuoteEngine, COMMON_FEE_TIERS, Swap, ABI7, erc7281_default, DEFAULT_GRAFFITI2, ERC7821_BATCH_MODE, BundlerMethod, SELECT_SOLVER_TYPEHASH, LEGACY_SELECT_SOLVER_TYPEHASH, PACKED_USEROP_TYPEHASH, DOMAIN_TYPEHASH, CryptoUtils, FEE_TOKEN_CACHE_TTL_MS, OrderPlacer, TOKEN_KEYED_GATEWAY_ABI, keyingByClient, PARTIAL_FILLS_SLOT, USED_USEROPS_STORAGE_KEY, OrderExecutor, _a6, OrderCanceller, FILL_ORDER_SELECTOR, SUPPORTED_INTENTS_VERSION, TESTNET_INTENTS_VERSIONS, CONTRACT_VERSION_ABI, CANONICAL_EVM_TOKEN, formats, SELECTION_PARAMS_SLOT, SOLVER_SELECTION_CLEARED, SELECTION_FORMAT_BY_ENTRY_POINT, ENTRY_POINT_EVENT_ABI, BidImpl, BidManager, UNSUPPORTED_REQUEST_CODES, bundlersWithoutRundlerFees, bundlersWithoutRundlerGasPrice, RELAYER_MESSAGE_GAS, NO_BUNDLER_FILL_GAS_BASE, NO_BUNDLER_FILL_GAS_PER_OUTPUT, NO_BUNDLER_PAYMASTER_VERIFICATION_GAS, NO_BUNDLER_PAYMASTER_POST_OP_GAS, BID_PVG_ESTIMATION_ACCOUNT_CODE, BID_PVG_ESTIMATION_PAYMASTER_CODE, SELECTED_BID_SIGNATURE_BYTES, BID_PVG_HEADROOM_PERCENT, ESCROW_MAPPING_SLOT, GasEstimator, OrderStatusChecker, ORDERBOOK_URLS, ORDERBOOK_DECIMALS, ORDERBOOK_SCALE, OrderbookRequestError, RATE_FIELDS, TOP_OF_BOOK_QUERY, ROUTE_LIQUIDITY_QUERY, QUOTE_QUERY, QUOTE_PESSIMISTIC_QUERY, HyperFxOrderbook, UnsupportedLiquidityAssetError, UnsupportedLiquidityChainError, OrderbookQuoteNotConvergedError, MAX_EXACT_OUTPUT_ROUNDS, OrderbookMarket, ETHEREUM_ORDER_FEE_GAS_PRICE_BUMP_PERCENT, DEFAULT_ORDER_FEE_GAS_PRICE_BUMP_PERCENT, IntentGateway, DECLARATION_V1, DECLARATION_V2, PAYMASTER_ADDRESS_BYTES, PAYMASTER_GAS_LIMIT_BYTES, PAYMASTER_DATA_OFFSET, PERMIT2_DATA_BYTES, PERMIT2_SPONSORSHIP_BYTES, MAX_DECLARED_ENTRIES, MAX_TOKEN_ID_BYTES, TeleportParams, MultiAccount;
|
|
235506
235548
|
var init_node10 = __esm({
|
|
235507
235549
|
"../sdk/dist/node/index.js"() {
|
|
235508
235550
|
"use strict";
|
|
@@ -237897,6 +237939,7 @@ var init_node10 = __esm({
|
|
|
237897
237939
|
},
|
|
237898
237940
|
rpcEnvKey: "BSC_CHAPEL",
|
|
237899
237941
|
defaultRpcUrl: "https://bnb-testnet.api.onfinality.io/public",
|
|
237942
|
+
bundlerUrl: "https://bundler.polytope.technology/bsc-chapel",
|
|
237900
237943
|
consensusStateId: "BSC0",
|
|
237901
237944
|
coingeckoId: "binance-smart-chain",
|
|
237902
237945
|
popularTokens: [
|
|
@@ -238040,6 +238083,7 @@ var init_node10 = __esm({
|
|
|
238040
238083
|
},
|
|
238041
238084
|
rpcEnvKey: "ETH_MAINNET",
|
|
238042
238085
|
defaultRpcUrl: "https://eth-mainnet.g.alchemy.com/v2/demo",
|
|
238086
|
+
bundlerUrl: "https://bundler.polytope.technology/ethereum",
|
|
238043
238087
|
consensusStateId: "ETH0",
|
|
238044
238088
|
coingeckoId: "ethereum",
|
|
238045
238089
|
layerZeroEid: 30101,
|
|
@@ -238109,6 +238153,7 @@ var init_node10 = __esm({
|
|
|
238109
238153
|
},
|
|
238110
238154
|
rpcEnvKey: "BSC_MAINNET",
|
|
238111
238155
|
defaultRpcUrl: "https://bsc-rpc.publicnode.com",
|
|
238156
|
+
bundlerUrl: "https://bundler.polytope.technology/bsc",
|
|
238112
238157
|
consensusStateId: "BSC0",
|
|
238113
238158
|
coingeckoId: "binance-smart-chain",
|
|
238114
238159
|
erc4626Vaults: [
|
|
@@ -238171,6 +238216,7 @@ var init_node10 = __esm({
|
|
|
238171
238216
|
},
|
|
238172
238217
|
rpcEnvKey: "ARBITRUM_MAINNET",
|
|
238173
238218
|
defaultRpcUrl: "https://arbitrum-one.public.blastapi.io",
|
|
238219
|
+
bundlerUrl: "https://bundler.polytope.technology/arbitrum",
|
|
238174
238220
|
consensusStateId: "ETH0",
|
|
238175
238221
|
coingeckoId: "arbitrum-one",
|
|
238176
238222
|
layerZeroEid: 30110,
|
|
@@ -238246,6 +238292,7 @@ var init_node10 = __esm({
|
|
|
238246
238292
|
},
|
|
238247
238293
|
rpcEnvKey: "BASE_MAINNET",
|
|
238248
238294
|
defaultRpcUrl: "https://base-mainnet.public.blastapi.io",
|
|
238295
|
+
bundlerUrl: "https://bundler.polytope.technology/base",
|
|
238249
238296
|
consensusStateId: "ETH0",
|
|
238250
238297
|
coingeckoId: "base",
|
|
238251
238298
|
layerZeroEid: 30184,
|
|
@@ -238322,6 +238369,7 @@ var init_node10 = __esm({
|
|
|
238322
238369
|
},
|
|
238323
238370
|
rpcEnvKey: "POLYGON_MAINNET",
|
|
238324
238371
|
defaultRpcUrl: "https://polygon-bor-rpc.publicnode.com",
|
|
238372
|
+
bundlerUrl: "https://bundler.polytope.technology/polygon",
|
|
238325
238373
|
consensusStateId: "POLY",
|
|
238326
238374
|
coingeckoId: "polygon-pos",
|
|
238327
238375
|
layerZeroEid: 30109,
|
|
@@ -238400,6 +238448,7 @@ var init_node10 = __esm({
|
|
|
238400
238448
|
},
|
|
238401
238449
|
rpcEnvKey: "POLYGON_AMOY",
|
|
238402
238450
|
defaultRpcUrl: "https://rpc-amoy.polygon.technology",
|
|
238451
|
+
bundlerUrl: "https://bundler.polytope.technology/polygon-amoy",
|
|
238403
238452
|
consensusStateId: "POLY",
|
|
238404
238453
|
coingeckoId: "polygon-pos"
|
|
238405
238454
|
},
|
|
@@ -242145,7 +242194,7 @@ var init_node10 = __esm({
|
|
|
242145
242194
|
* This is the only public way to construct an `EvmChain` — the constructor is private.
|
|
242146
242195
|
*
|
|
242147
242196
|
* @param rpcUrl - HTTP(S) RPC URL of the EVM node
|
|
242148
|
-
* @param bundlerUrl - Optional ERC-4337 bundler URL for
|
|
242197
|
+
* @param bundlerUrl - Optional ERC-4337 bundler URL; defaults to Hyperbridge's bundler for the chain
|
|
242149
242198
|
* @returns A fully initialised `EvmChain` ready for use
|
|
242150
242199
|
* @throws If the chain ID returned by the RPC is not a known Hyperbridge deployment
|
|
242151
242200
|
*
|
|
@@ -242171,8 +242220,12 @@ var init_node10 = __esm({
|
|
|
242171
242220
|
get host() {
|
|
242172
242221
|
return this.params.host;
|
|
242173
242222
|
}
|
|
242223
|
+
/**
|
|
242224
|
+
* The bundler given to this chain, or else the one Hyperbridge runs for it.
|
|
242225
|
+
* Undefined on a chain Hyperbridge runs no bundler for.
|
|
242226
|
+
*/
|
|
242174
242227
|
get bundlerUrl() {
|
|
242175
|
-
return this.params.bundlerUrl;
|
|
242228
|
+
return this.params.bundlerUrl ?? chainConfigs[this.params.chainId]?.bundlerUrl;
|
|
242176
242229
|
}
|
|
242177
242230
|
get config() {
|
|
242178
242231
|
return {
|
|
@@ -246782,10 +246835,10 @@ query OrderStatus($commitment: String!) {
|
|
|
246782
246835
|
ETH_GET_USER_OPERATION_RECEIPT: "eth_getUserOperationReceipt",
|
|
246783
246836
|
/** Estimates gas limits for a UserOperation before submission. */
|
|
246784
246837
|
ETH_ESTIMATE_USER_OPERATION_GAS: "eth_estimateUserOperationGas",
|
|
246785
|
-
/**
|
|
246786
|
-
|
|
246787
|
-
/**
|
|
246788
|
-
|
|
246838
|
+
/** Rundler method returning the priority fee it requires of UserOperations. */
|
|
246839
|
+
RUNDLER_MAX_PRIORITY_FEE_PER_GAS: "rundler_maxPriorityFeePerGas",
|
|
246840
|
+
/** Rundler method returning the fees it requires and suggests for UserOperations. */
|
|
246841
|
+
RUNDLER_GET_USER_OPERATION_GAS_PRICE: "rundler_getUserOperationGasPrice"
|
|
246789
246842
|
};
|
|
246790
246843
|
SELECT_SOLVER_TYPEHASH = keccak2563(toHex3("SelectSolver(bytes32 commitment,bytes32 userOpHash)"));
|
|
246791
246844
|
LEGACY_SELECT_SOLVER_TYPEHASH = keccak2563(toHex3("SelectSolver(bytes32 commitment,address solver)"));
|
|
@@ -249066,6 +249119,7 @@ query OrderStatus($commitment: String!) {
|
|
|
249066
249119
|
};
|
|
249067
249120
|
UNSUPPORTED_REQUEST_CODES = /* @__PURE__ */ new Set([-32600, -32601, -32602]);
|
|
249068
249121
|
bundlersWithoutRundlerFees = /* @__PURE__ */ new Set();
|
|
249122
|
+
bundlersWithoutRundlerGasPrice = /* @__PURE__ */ new Set();
|
|
249069
249123
|
RELAYER_MESSAGE_GAS = 1000000n;
|
|
249070
249124
|
NO_BUNDLER_FILL_GAS_BASE = 700000n;
|
|
249071
249125
|
NO_BUNDLER_FILL_GAS_PER_OUTPUT = 150000n;
|
|
@@ -249106,11 +249160,9 @@ query OrderStatus($commitment: String!) {
|
|
|
249106
249160
|
* **Bundler path:** constructs a mock `PackedUserOperation` signed by an
|
|
249107
249161
|
* ephemeral keypair, applies state overrides, and calls
|
|
249108
249162
|
* `eth_estimateUserOperationGas`. Gas limits are bumped by 5-10% for
|
|
249109
|
-
* headroom.
|
|
249110
|
-
*
|
|
249111
|
-
*
|
|
249112
|
-
* `rundler_maxPriorityFeePerGas`, the fees are raised to at least that
|
|
249113
|
-
* priority fee (see {@link applyRundlerPriorityFee}). If the bundler rejects the estimate,
|
|
249163
|
+
* headroom. Fees are the rundler bundler's suggested fees raised by the bumps,
|
|
249164
|
+
* or the chain's gas price raised to the priority fee it requires where it
|
|
249165
|
+
* suggests none (see {@link rundlerUserOperationFees}). If the bundler rejects the estimate,
|
|
249114
249166
|
* fixed gas limits are returned in its place, or the call throws when
|
|
249115
249167
|
* `params.requireBundlerEstimate` is set.
|
|
249116
249168
|
*
|
|
@@ -249266,46 +249318,19 @@ query OrderStatus($commitment: String!) {
|
|
|
249266
249318
|
sessionSignature
|
|
249267
249319
|
]);
|
|
249268
249320
|
const bundlerUserOp = CryptoUtils.prepareBundlerCall(preliminaryUserOp);
|
|
249269
|
-
const
|
|
249270
|
-
|
|
249271
|
-
|
|
249272
|
-
const rundlerPriorityFeeRequest = isPimlico || isAlchemy ? Promise.resolve(null) : fetchRundlerPriorityFee(this.ctx.bundlerUrl);
|
|
249273
|
-
const bundlerRequests = [
|
|
249321
|
+
const rundlerFeesRequest = rundlerUserOperationFees(
|
|
249322
|
+
this.ctx.bundlerUrl,
|
|
249323
|
+
{ maxFeePerGas, maxPriorityFeePerGas },
|
|
249274
249324
|
{
|
|
249275
|
-
|
|
249276
|
-
|
|
249277
|
-
|
|
249278
|
-
];
|
|
249279
|
-
if (isPimlico) {
|
|
249280
|
-
bundlerRequests.push({
|
|
249281
|
-
method: BundlerMethod.PIMLICO_GET_USER_OPERATION_GAS_PRICE,
|
|
249282
|
-
params: []
|
|
249283
|
-
});
|
|
249284
|
-
}
|
|
249285
|
-
if (isAlchemy) {
|
|
249286
|
-
bundlerRequests.push({
|
|
249287
|
-
method: BundlerMethod.RUNDLER_MAX_PRIORITY_FEE_PER_GAS,
|
|
249288
|
-
params: []
|
|
249289
|
-
});
|
|
249290
|
-
}
|
|
249291
|
-
let gasEstimate;
|
|
249292
|
-
let pimlicoGasPrices = null;
|
|
249293
|
-
let alchemyMaxPriorityFee = null;
|
|
249294
|
-
try {
|
|
249295
|
-
const batchResults = await this.crypto.sendBundlerBatch(bundlerRequests);
|
|
249296
|
-
gasEstimate = batchResults[0];
|
|
249297
|
-
if (isPimlico && batchResults.length > 1) {
|
|
249298
|
-
pimlicoGasPrices = batchResults[1];
|
|
249325
|
+
baseFeePerGas,
|
|
249326
|
+
priorityFeeBumpPercent: BigInt(priorityFeeBumpPercent),
|
|
249327
|
+
maxFeeBumpPercent: BigInt(maxFeeBumpPercent)
|
|
249299
249328
|
}
|
|
249300
|
-
|
|
249301
|
-
|
|
249302
|
-
|
|
249303
|
-
|
|
249304
|
-
|
|
249305
|
-
BundlerMethod.ETH_ESTIMATE_USER_OPERATION_GAS,
|
|
249306
|
-
[bundlerUserOp, entryPointAddress, bundlerStateOverrides]
|
|
249307
|
-
);
|
|
249308
|
-
}
|
|
249329
|
+
);
|
|
249330
|
+
const gasEstimate = await this.crypto.sendBundler(
|
|
249331
|
+
BundlerMethod.ETH_ESTIMATE_USER_OPERATION_GAS,
|
|
249332
|
+
[bundlerUserOp, entryPointAddress, bundlerStateOverrides]
|
|
249333
|
+
);
|
|
249309
249334
|
callGasLimit = BigInt(gasEstimate.callGasLimit) * 160n / 100n;
|
|
249310
249335
|
verificationGasLimit = BigInt(gasEstimate.verificationGasLimit) * 105n / 100n;
|
|
249311
249336
|
preVerificationGas = BigInt(gasEstimate.preVerificationGas) * 105n / 100n;
|
|
@@ -249315,37 +249340,9 @@ query OrderStatus($commitment: String!) {
|
|
|
249315
249340
|
if (gasEstimate.paymasterPostOpGasLimit) {
|
|
249316
249341
|
paymasterPostOpGasLimit = BigInt(gasEstimate.paymasterPostOpGasLimit) * 105n / 100n;
|
|
249317
249342
|
}
|
|
249318
|
-
|
|
249319
|
-
|
|
249320
|
-
|
|
249321
|
-
const pimMaxFeePerGas = BigInt(level.maxFeePerGas);
|
|
249322
|
-
const pimMaxPriorityFeePerGas = BigInt(level.maxPriorityFeePerGas);
|
|
249323
|
-
maxFeePerGas = pimMaxFeePerGas + pimMaxFeePerGas * BigInt(maxFeeBumpPercent) / 100n;
|
|
249324
|
-
maxPriorityFeePerGas = pimMaxPriorityFeePerGas + pimMaxPriorityFeePerGas * BigInt(priorityFeeBumpPercent) / 100n;
|
|
249325
|
-
}
|
|
249326
|
-
}
|
|
249327
|
-
if (alchemyMaxPriorityFee) {
|
|
249328
|
-
const rundlerPriorityFee2 = BigInt(alchemyMaxPriorityFee);
|
|
249329
|
-
const isArbitrum = chainId === 42161n;
|
|
249330
|
-
const alchemyPrioBump = isArbitrum ? 0n : 25n;
|
|
249331
|
-
maxPriorityFeePerGas = rundlerPriorityFee2 + rundlerPriorityFee2 * alchemyPrioBump / 100n;
|
|
249332
|
-
const bufferedBaseFee = baseFeePerGas + baseFeePerGas * 50n / 100n;
|
|
249333
|
-
maxFeePerGas = bufferedBaseFee + maxPriorityFeePerGas;
|
|
249334
|
-
}
|
|
249335
|
-
const rundlerPriorityFee = await rundlerPriorityFeeRequest;
|
|
249336
|
-
if (rundlerPriorityFee !== null) {
|
|
249337
|
-
const rundlerFees = applyRundlerPriorityFee(
|
|
249338
|
-
{ maxFeePerGas, maxPriorityFeePerGas },
|
|
249339
|
-
{
|
|
249340
|
-
rundlerPriorityFee,
|
|
249341
|
-
baseFeePerGas,
|
|
249342
|
-
priorityFeeBumpPercent: BigInt(priorityFeeBumpPercent),
|
|
249343
|
-
maxFeeBumpPercent: BigInt(maxFeeBumpPercent)
|
|
249344
|
-
}
|
|
249345
|
-
);
|
|
249346
|
-
maxFeePerGas = rundlerFees.maxFeePerGas;
|
|
249347
|
-
maxPriorityFeePerGas = rundlerFees.maxPriorityFeePerGas;
|
|
249348
|
-
}
|
|
249343
|
+
const rundlerFees = await rundlerFeesRequest;
|
|
249344
|
+
maxFeePerGas = rundlerFees.maxFeePerGas;
|
|
249345
|
+
maxPriorityFeePerGas = rundlerFees.maxPriorityFeePerGas;
|
|
249349
249346
|
} catch (e4) {
|
|
249350
249347
|
if (params.requireBundlerEstimate) {
|
|
249351
249348
|
throw new Error(`Bundler gas estimation failed: ${e4 instanceof Error ? e4.message : String(e4)}`, {
|
|
@@ -250133,6 +250130,7 @@ query QuotePessimistic($route: RouteInput!, $amountIn: BigInt!) {
|
|
|
250133
250130
|
*
|
|
250134
250131
|
* The ERC-4337 bundler URL is read from `dest.bundlerUrl`, set when constructing
|
|
250135
250132
|
* the destination chain via {@link EvmChain.create} or {@link EvmChainParams.bundlerUrl}.
|
|
250133
|
+
* An `EvmChain` given none uses the bundler Hyperbridge runs for it.
|
|
250136
250134
|
*
|
|
250137
250135
|
* @param source - Source chain for order placement
|
|
250138
250136
|
* @param dest - Destination chain for order fulfillment
|
|
@@ -250822,6 +250820,27 @@ query QuotePessimistic($route: RouteInput!, $amountIn: BigInt!) {
|
|
|
250822
250820
|
}
|
|
250823
250821
|
});
|
|
250824
250822
|
|
|
250823
|
+
// src/config/bundlers.ts
|
|
250824
|
+
function hyperbridgeBundlerUrl(chainId) {
|
|
250825
|
+
return HYPERBRIDGE_BUNDLER_URLS[chainId];
|
|
250826
|
+
}
|
|
250827
|
+
var HYPERBRIDGE_BUNDLER_URLS;
|
|
250828
|
+
var init_bundlers = __esm({
|
|
250829
|
+
"src/config/bundlers.ts"() {
|
|
250830
|
+
"use strict";
|
|
250831
|
+
init_esm_shims();
|
|
250832
|
+
HYPERBRIDGE_BUNDLER_URLS = {
|
|
250833
|
+
1: "https://bundler.polytope.technology/ethereum",
|
|
250834
|
+
56: "https://bundler.polytope.technology/bsc",
|
|
250835
|
+
97: "https://bundler.polytope.technology/bsc-chapel",
|
|
250836
|
+
137: "https://bundler.polytope.technology/polygon",
|
|
250837
|
+
8453: "https://bundler.polytope.technology/base",
|
|
250838
|
+
42161: "https://bundler.polytope.technology/arbitrum",
|
|
250839
|
+
80002: "https://bundler.polytope.technology/polygon-amoy"
|
|
250840
|
+
};
|
|
250841
|
+
}
|
|
250842
|
+
});
|
|
250843
|
+
|
|
250825
250844
|
// src/services/FillerConfigService.ts
|
|
250826
250845
|
function validateRpcUrls(rpcUrls) {
|
|
250827
250846
|
if (rpcUrls.length === 0) {
|
|
@@ -250901,7 +250920,7 @@ async function resolveChainConfigs(chains2, options = {}) {
|
|
|
250901
250920
|
"RPC endpoint could not report its chainId at startup; keeping it for the quorum to judge per call"
|
|
250902
250921
|
);
|
|
250903
250922
|
}
|
|
250904
|
-
return { chainId: first3.chainId, rpcUrls, bundlerUrl:
|
|
250923
|
+
return { chainId: first3.chainId, rpcUrls, bundlerUrl: hyperbridgeBundlerUrl(first3.chainId) };
|
|
250905
250924
|
})
|
|
250906
250925
|
);
|
|
250907
250926
|
}
|
|
@@ -250912,6 +250931,7 @@ var init_FillerConfigService = __esm({
|
|
|
250912
250931
|
init_esm_shims();
|
|
250913
250932
|
init_Logger();
|
|
250914
250933
|
init_node10();
|
|
250934
|
+
init_bundlers();
|
|
250915
250935
|
DEFAULT_BLOCK_SCAN_INTERVAL_SECONDS = 3;
|
|
250916
250936
|
MIN_BLOCK_SCAN_INTERVAL_SECONDS = 0.1;
|
|
250917
250937
|
DEFAULT_MIN_ORDER_SIZE_USD = 20;
|
|
@@ -250980,12 +251000,6 @@ var init_FillerConfigService = __esm({
|
|
|
250980
251000
|
}
|
|
250981
251001
|
this.rpcOverrides.set(chainId, validateRpcUrls(rpcUrls));
|
|
250982
251002
|
}
|
|
250983
|
-
setBundlerUrl(chainId, bundlerUrl) {
|
|
250984
|
-
if (!this.rpcOverrides.has(chainId)) {
|
|
250985
|
-
throw new Error(`Chain ${chainId} is not configured`);
|
|
250986
|
-
}
|
|
250987
|
-
this.bundlerUrls.set(chainId, bundlerUrl);
|
|
250988
|
-
}
|
|
250989
251003
|
/** Replaces the rebalancing config at runtime; trigger checks read it live. */
|
|
250990
251004
|
setRebalancing(rebalancing) {
|
|
250991
251005
|
if (this.fillerConfig) this.fillerConfig.rebalancing = rebalancing;
|
|
@@ -251356,9 +251370,6 @@ function validateConfig(config5, cliWatchOnly = false) {
|
|
|
251356
251370
|
if (!Array.isArray(chain2.rpcUrls) || chain2.rpcUrls.length === 0 || chain2.rpcUrls.some((u6) => !u6)) {
|
|
251357
251371
|
throw new Error("Each chain configuration must have rpcUrls (a non-empty array of strings)");
|
|
251358
251372
|
}
|
|
251359
|
-
if (!chain2.bundlerUrl) {
|
|
251360
|
-
throw new Error("Each chain configuration must have bundlerUrl");
|
|
251361
|
-
}
|
|
251362
251373
|
}
|
|
251363
251374
|
const concurrent = config5.simplex.maxConcurrentOrders;
|
|
251364
251375
|
if (concurrent !== void 0) {
|
|
@@ -251606,7 +251617,7 @@ function nativeTokenSymbol(chainId) {
|
|
|
251606
251617
|
return CHAIN_NATIVE_SYMBOLS[chainId] ?? "ETH";
|
|
251607
251618
|
}
|
|
251608
251619
|
function chainsForNetwork(network) {
|
|
251609
|
-
return INIT_CHAINS.filter((chain2) => chain2.network === network);
|
|
251620
|
+
return INIT_CHAINS.filter((chain2) => chain2.network === network && chain2.hyperbridgeBundlerUrl);
|
|
251610
251621
|
}
|
|
251611
251622
|
function chainByChainId(chainId) {
|
|
251612
251623
|
return INIT_CHAINS.find((chain2) => chain2.chainId === chainId);
|
|
@@ -251614,12 +251625,13 @@ function chainByChainId(chainId) {
|
|
|
251614
251625
|
function chainByAlchemySubdomain(subdomain) {
|
|
251615
251626
|
return INIT_CHAINS.find((chain2) => chain2.alchemySubdomain === subdomain);
|
|
251616
251627
|
}
|
|
251617
|
-
var FREE_RPC_URLS,
|
|
251628
|
+
var FREE_RPC_URLS, CHAIN_NATIVE_SYMBOLS, INIT_CHAINS, HYPERBRIDGE_WS_DEFAULTS;
|
|
251618
251629
|
var init_chains2 = __esm({
|
|
251619
251630
|
"src/cli/init/chains.ts"() {
|
|
251620
251631
|
"use strict";
|
|
251621
251632
|
init_esm_shims();
|
|
251622
251633
|
init_external_links();
|
|
251634
|
+
init_bundlers();
|
|
251623
251635
|
FREE_RPC_URLS = {
|
|
251624
251636
|
1: [
|
|
251625
251637
|
"https://mainnet.gateway.tenderly.co",
|
|
@@ -251666,13 +251678,6 @@ var init_chains2 = __esm({
|
|
|
251666
251678
|
"https://arb1.arbitrum.io/rpc"
|
|
251667
251679
|
]
|
|
251668
251680
|
};
|
|
251669
|
-
HYPERBRIDGE_BUNDLER_URLS = {
|
|
251670
|
-
1: "https://bundler.polytope.technology/ethereum",
|
|
251671
|
-
56: "https://bundler.polytope.technology/bsc",
|
|
251672
|
-
137: "https://bundler.polytope.technology/polygon",
|
|
251673
|
-
8453: "https://bundler.polytope.technology/base",
|
|
251674
|
-
42161: "https://bundler.polytope.technology/arbitrum"
|
|
251675
|
-
};
|
|
251676
251681
|
CHAIN_NATIVE_SYMBOLS = {
|
|
251677
251682
|
1: "ETH",
|
|
251678
251683
|
56: "BNB",
|
|
@@ -251771,7 +251776,8 @@ var init_chains2 = __esm({
|
|
|
251771
251776
|
label: "Polygon Amoy",
|
|
251772
251777
|
network: "testnet",
|
|
251773
251778
|
alchemySubdomain: "polygon-amoy",
|
|
251774
|
-
explorerUrl: external_links_default.chainExplorers.polygonAmoy
|
|
251779
|
+
explorerUrl: external_links_default.chainExplorers.polygonAmoy,
|
|
251780
|
+
hyperbridgeBundlerUrl: HYPERBRIDGE_BUNDLER_URLS[80002]
|
|
251775
251781
|
},
|
|
251776
251782
|
{
|
|
251777
251783
|
chainId: 97,
|
|
@@ -251779,7 +251785,8 @@ var init_chains2 = __esm({
|
|
|
251779
251785
|
label: "BSC Chapel",
|
|
251780
251786
|
network: "testnet",
|
|
251781
251787
|
alchemySubdomain: "bnb-testnet",
|
|
251782
|
-
explorerUrl: external_links_default.chainExplorers.bnbChapel
|
|
251788
|
+
explorerUrl: external_links_default.chainExplorers.bnbChapel,
|
|
251789
|
+
hyperbridgeBundlerUrl: HYPERBRIDGE_BUNDLER_URLS[97]
|
|
251783
251790
|
}
|
|
251784
251791
|
];
|
|
251785
251792
|
HYPERBRIDGE_WS_DEFAULTS = {
|
|
@@ -252021,8 +252028,6 @@ function emitFillerToml(config5, options = {}) {
|
|
|
252021
252028
|
push("[[chains]]");
|
|
252022
252029
|
push("# List 2+ organisationally independent RPC providers to enable quorum log scanning.");
|
|
252023
252030
|
push(kv("rpcUrls", chain2.rpcUrls));
|
|
252024
|
-
push("# ERC-4337 bundler used to submit fill UserOperations on this chain.");
|
|
252025
|
-
push(kv("bundlerUrl", chain2.bundlerUrl));
|
|
252026
252031
|
push();
|
|
252027
252032
|
});
|
|
252028
252033
|
return `${out.join("\n").trimEnd()}
|
|
@@ -336953,9 +336958,6 @@ function parseAlchemyUrl(url2) {
|
|
|
336953
336958
|
if (!match) return null;
|
|
336954
336959
|
return { subdomain, apiKey: match[1] };
|
|
336955
336960
|
}
|
|
336956
|
-
function isAlchemyUrl(url2) {
|
|
336957
|
-
return parseAlchemyUrl(url2) !== null;
|
|
336958
|
-
}
|
|
336959
336961
|
function deriveAlchemyRpc(apiKey, chainId) {
|
|
336960
336962
|
const chain2 = chainByChainId(chainId);
|
|
336961
336963
|
if (!chain2?.alchemySubdomain) return null;
|
|
@@ -337806,10 +337808,9 @@ var init_help_text = __esm({
|
|
|
337806
337808
|
"use strict";
|
|
337807
337809
|
init_esm_shims();
|
|
337808
337810
|
WHY = {
|
|
337809
|
-
chains: "Simplex listens for orders and fills only on the chains you pick. Each chain needs its own RPC
|
|
337811
|
+
chains: "Simplex listens for orders and fills only on the chains you pick. Each chain needs its own RPC and funded balances (native gas + stablecoins); fills go through Hyperbridge's bundler.",
|
|
337810
337812
|
rpc: "The RPC is used to scan order events, read balances and simulate fills. Use a premium endpoint with archive access (Alchemy, Infura, QuickNode) \u2014 free tiers rate-limit and break event scanning.",
|
|
337811
337813
|
quorum: "Listing a second, organisationally independent RPC enables quorum log scanning: every event batch must match across providers, so one lying or compromised RPC can't feed you fake orders.",
|
|
337812
|
-
bundler: "Fills execute as ERC-4337 UserOperations; the bundler submits them on-chain. Hyperbridge runs no bundler for these chains, so use a provider such as Pimlico.",
|
|
337813
337814
|
signer: "This wallet signs every fill and holds your stablecoin float on each chain. It's the identity of your filler.",
|
|
337814
337815
|
secretPhrase: "A secret phrase is a BIP-39 mnemonic of 12 to 24 English words. The filler signs with the wallet at m/44'/60'/0'/0/0 unless you pick another account index. The phrase is written to the config file in plain text, protected only by the file's permissions, the same as a private key.",
|
|
337815
337816
|
substrateKey: "Solver-selection orders are won by submitting signed bids to Hyperbridge. This Substrate account signs those bid extrinsics and must hold BRIDGE tokens for fees \u2014 the fees are claimed back automatically after fills.",
|
|
@@ -337871,8 +337872,7 @@ function detectPrefillNetwork(prefill) {
|
|
|
337871
337872
|
if (!prefill) return void 0;
|
|
337872
337873
|
for (const chainId of prefill.chainIds) {
|
|
337873
337874
|
if (chainId === null) continue;
|
|
337874
|
-
|
|
337875
|
-
if (meta) return "testnet";
|
|
337875
|
+
if (chainByChainId(chainId)?.network === "testnet") return "testnet";
|
|
337876
337876
|
}
|
|
337877
337877
|
return "mainnet";
|
|
337878
337878
|
}
|
|
@@ -338066,122 +338066,6 @@ var init_chains3 = __esm({
|
|
|
338066
338066
|
}
|
|
338067
338067
|
});
|
|
338068
338068
|
|
|
338069
|
-
// src/cli/init/derive/pimlico.ts
|
|
338070
|
-
function parsePimlicoUrl(url2) {
|
|
338071
|
-
let parsed;
|
|
338072
|
-
try {
|
|
338073
|
-
parsed = new URL(url2);
|
|
338074
|
-
} catch {
|
|
338075
|
-
return null;
|
|
338076
|
-
}
|
|
338077
|
-
if (parsed.protocol !== "https:") return null;
|
|
338078
|
-
if (parsed.hostname !== "api.pimlico.io") return null;
|
|
338079
|
-
const match = parsed.pathname.match(/^\/v2\/([^/]+)\/rpc$/);
|
|
338080
|
-
if (!match) return null;
|
|
338081
|
-
const chainId = Number(match[1]);
|
|
338082
|
-
if (!Number.isInteger(chainId) || chainId <= 0) return null;
|
|
338083
|
-
const apiKey = parsed.searchParams.get("apikey");
|
|
338084
|
-
if (!apiKey) return null;
|
|
338085
|
-
return { chainId, apiKey };
|
|
338086
|
-
}
|
|
338087
|
-
function derivePimlicoBundler(apiKey, chainId) {
|
|
338088
|
-
return `https://api.pimlico.io/v2/${chainId}/rpc?apikey=${encodeURIComponent(apiKey)}`;
|
|
338089
|
-
}
|
|
338090
|
-
var init_pimlico = __esm({
|
|
338091
|
-
"src/cli/init/derive/pimlico.ts"() {
|
|
338092
|
-
"use strict";
|
|
338093
|
-
init_esm_shims();
|
|
338094
|
-
}
|
|
338095
|
-
});
|
|
338096
|
-
|
|
338097
|
-
// src/cli/init/steps/bundlers.ts
|
|
338098
|
-
async function stepBundlers(state, prefill) {
|
|
338099
|
-
for (const chain2 of state.chains) {
|
|
338100
|
-
if (chain2.meta.hyperbridgeBundlerUrl) chain2.bundlerUrl = chain2.meta.hyperbridgeBundlerUrl;
|
|
338101
|
-
}
|
|
338102
|
-
if (state.chains.every((chain2) => chain2.bundlerUrl)) return;
|
|
338103
|
-
why(WHY.bundler);
|
|
338104
|
-
const alchemyChains = state.chains.filter((chain2) => {
|
|
338105
|
-
if (chain2.bundlerUrl || !isAlchemyUrl(chain2.rpcUrls[0])) return false;
|
|
338106
|
-
const existing = prefillBundlerFor(chain2.meta.chainId, prefill);
|
|
338107
|
-
return !existing || existing === chain2.rpcUrls[0];
|
|
338108
|
-
});
|
|
338109
|
-
if (alchemyChains.length > 0) {
|
|
338110
|
-
const reuse = guard(
|
|
338111
|
-
await confirm({
|
|
338112
|
-
message: `Reuse the Alchemy RPC as the ERC-4337 bundler for ${alchemyChains.map((c6) => c6.meta.label).join(", ")}?`,
|
|
338113
|
-
initialValue: true
|
|
338114
|
-
})
|
|
338115
|
-
);
|
|
338116
|
-
if (reuse) {
|
|
338117
|
-
for (const chain2 of alchemyChains) chain2.bundlerUrl = chain2.rpcUrls[0];
|
|
338118
|
-
}
|
|
338119
|
-
}
|
|
338120
|
-
const alchemyCapable = state.chains.filter((chain2) => !chain2.bundlerUrl && chain2.meta.alchemySubdomain);
|
|
338121
|
-
if (alchemyCapable.length > 0) {
|
|
338122
|
-
const useKey = guard(
|
|
338123
|
-
await confirm({
|
|
338124
|
-
message: `Configure the bundler for ${alchemyCapable.map((c6) => c6.meta.label).join(", ")} from one Alchemy API key?`,
|
|
338125
|
-
initialValue: true
|
|
338126
|
-
})
|
|
338127
|
-
);
|
|
338128
|
-
if (useKey) {
|
|
338129
|
-
const apiKey = await askSecret("Alchemy API key");
|
|
338130
|
-
for (const chain2 of alchemyCapable) {
|
|
338131
|
-
const url2 = deriveAlchemyRpc(apiKey, chain2.meta.chainId);
|
|
338132
|
-
if (url2) chain2.bundlerUrl = url2;
|
|
338133
|
-
}
|
|
338134
|
-
}
|
|
338135
|
-
}
|
|
338136
|
-
const pimlico = new ProviderDerivation({
|
|
338137
|
-
detect: (url2) => parsePimlicoUrl(url2)?.apiKey ?? null,
|
|
338138
|
-
derive: derivePimlicoBundler,
|
|
338139
|
-
confirmMessage: (remaining) => `Pimlico key detected \u2014 derive bundler URLs for ${remaining} from the same key?`
|
|
338140
|
-
});
|
|
338141
|
-
for (const chain2 of state.chains) {
|
|
338142
|
-
if (chain2.bundlerUrl) continue;
|
|
338143
|
-
const existing = prefillBundlerFor(chain2.meta.chainId, prefill);
|
|
338144
|
-
const derived2 = pimlico.candidate(chain2.meta.chainId);
|
|
338145
|
-
const url2 = derived2 ? await askDerivedOrCustom(
|
|
338146
|
-
`Bundler for ${chain2.meta.label}`,
|
|
338147
|
-
derived2,
|
|
338148
|
-
"Use the derived Pimlico URL",
|
|
338149
|
-
() => askBundlerUrl(chain2.meta.label, existing)
|
|
338150
|
-
) : await askBundlerUrl(chain2.meta.label, existing);
|
|
338151
|
-
chain2.bundlerUrl = url2;
|
|
338152
|
-
const remaining = state.chains.filter((c6) => !c6.bundlerUrl);
|
|
338153
|
-
await pimlico.offer(
|
|
338154
|
-
url2,
|
|
338155
|
-
remaining.map((c6) => c6.meta.label)
|
|
338156
|
-
);
|
|
338157
|
-
}
|
|
338158
|
-
}
|
|
338159
|
-
function prefillBundlerFor(chainId, prefill) {
|
|
338160
|
-
if (!prefill) return void 0;
|
|
338161
|
-
const index3 = prefill.chainIds.indexOf(chainId);
|
|
338162
|
-
if (index3 === -1) return void 0;
|
|
338163
|
-
return prefill.config.chains[index3]?.bundlerUrl || void 0;
|
|
338164
|
-
}
|
|
338165
|
-
function askBundlerUrl(label, initial) {
|
|
338166
|
-
return askUrl(`ERC-4337 bundler URL for ${label}`, {
|
|
338167
|
-
initial,
|
|
338168
|
-
placeholder: "https://api.pimlico.io/v2/<chainId>/rpc?apikey=<your-key>",
|
|
338169
|
-
required: "Bundler URL is required \u2014 fills are submitted through it"
|
|
338170
|
-
});
|
|
338171
|
-
}
|
|
338172
|
-
var init_bundlers = __esm({
|
|
338173
|
-
"src/cli/init/steps/bundlers.ts"() {
|
|
338174
|
-
"use strict";
|
|
338175
|
-
init_esm_shims();
|
|
338176
|
-
init_dist11();
|
|
338177
|
-
init_alchemy();
|
|
338178
|
-
init_pimlico();
|
|
338179
|
-
init_derive_flow();
|
|
338180
|
-
init_prompt_utils();
|
|
338181
|
-
init_help_text();
|
|
338182
|
-
}
|
|
338183
|
-
});
|
|
338184
|
-
|
|
338185
338069
|
// src/cli/init/steps/signer.ts
|
|
338186
338070
|
async function stepSigner(state, prefill) {
|
|
338187
338071
|
why(WHY.signer);
|
|
@@ -338663,7 +338547,7 @@ function assembleConfig(state) {
|
|
|
338663
338547
|
// would otherwise shadow the fresh entry (last [[chains]] wins at load).
|
|
338664
338548
|
chains: [
|
|
338665
338549
|
...state.passthroughChains,
|
|
338666
|
-
...state.chains.map((chain2) => ({ rpcUrls: chain2.rpcUrls
|
|
338550
|
+
...state.chains.map((chain2) => ({ rpcUrls: chain2.rpcUrls }))
|
|
338667
338551
|
],
|
|
338668
338552
|
rebalancing,
|
|
338669
338553
|
vault: hasVault ? vault : void 0,
|
|
@@ -338685,10 +338569,7 @@ function chainComments(state) {
|
|
|
338685
338569
|
function showSummary(state, outputPath) {
|
|
338686
338570
|
const lines = [];
|
|
338687
338571
|
for (const chain2 of state.chains) {
|
|
338688
|
-
|
|
338689
|
-
lines.push(
|
|
338690
|
-
`${chain2.meta.label}: ${chain2.rpcUrls.length} RPC${chain2.rpcUrls.length > 1 ? "s (quorum)" : ""}, bundler ${bundlerHost2}`
|
|
338691
|
-
);
|
|
338572
|
+
lines.push(`${chain2.meta.label}: ${chain2.rpcUrls.length} RPC${chain2.rpcUrls.length > 1 ? "s (quorum)" : ""}`);
|
|
338692
338573
|
}
|
|
338693
338574
|
if (state.passthroughChains.length > 0) {
|
|
338694
338575
|
lines.push(`+ ${state.passthroughChains.length} unmanaged chain(s) kept from the previous config`);
|
|
@@ -338780,7 +338661,6 @@ async function runInit(options) {
|
|
|
338780
338661
|
const state = newWizardState();
|
|
338781
338662
|
state.prefillConfig = prefill?.config;
|
|
338782
338663
|
await stepChains(state, prefill);
|
|
338783
|
-
await stepBundlers(state, prefill);
|
|
338784
338664
|
await stepSigner(state, prefill);
|
|
338785
338665
|
await stepHyperbridge(state, prefill);
|
|
338786
338666
|
for (; ; ) {
|
|
@@ -338880,7 +338760,6 @@ var init_init3 = __esm({
|
|
|
338880
338760
|
init_migrate_legacy();
|
|
338881
338761
|
init_state();
|
|
338882
338762
|
init_chains3();
|
|
338883
|
-
init_bundlers();
|
|
338884
338763
|
init_signer2();
|
|
338885
338764
|
init_hyperbridge();
|
|
338886
338765
|
init_finetune();
|
|
@@ -339170,6 +339049,7 @@ init_dist4();
|
|
|
339170
339049
|
// src/services/server/UiServer.ts
|
|
339171
339050
|
init_esm_shims();
|
|
339172
339051
|
init_interpolated_curve();
|
|
339052
|
+
init_bundlers();
|
|
339173
339053
|
init_asset_registry();
|
|
339174
339054
|
init_pairs();
|
|
339175
339055
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
@@ -343586,86 +343466,6 @@ init_pairs();
|
|
|
343586
343466
|
init_interpolated_curve();
|
|
343587
343467
|
init_asset_registry();
|
|
343588
343468
|
init_FillerConfigService();
|
|
343589
|
-
|
|
343590
|
-
// src/services/bundler-preflight.ts
|
|
343591
|
-
init_esm_shims();
|
|
343592
|
-
init_chains2();
|
|
343593
|
-
init_interpolated_curve();
|
|
343594
|
-
init_Logger();
|
|
343595
|
-
var BUNDLER_PREFLIGHT_TIMEOUT_MS = 1e4;
|
|
343596
|
-
async function assertBundlersServeEntryPoint(chains2, configService, options = {}) {
|
|
343597
|
-
const timeoutMs = options.timeoutMs ?? BUNDLER_PREFLIGHT_TIMEOUT_MS;
|
|
343598
|
-
const logger8 = moduleLogger(configService.loggers, "bundler-preflight");
|
|
343599
|
-
const failures = await Promise.all(
|
|
343600
|
-
chains2.map(async ({ chainId, bundlerUrl }) => {
|
|
343601
|
-
if (options.watchOnly?.[chainId] === true) return void 0;
|
|
343602
|
-
if (!bundlerUrl?.trim()) return void 0;
|
|
343603
|
-
const entryPoint = configService.getEntryPointAddress(formatChainKey(chainId));
|
|
343604
|
-
if (!entryPoint) return void 0;
|
|
343605
|
-
return checkBundler(chainId, bundlerUrl.trim(), entryPoint, timeoutMs, logger8);
|
|
343606
|
-
})
|
|
343607
|
-
);
|
|
343608
|
-
const messages = failures.filter((failure) => failure !== void 0);
|
|
343609
|
-
if (messages.length > 0) throw new Error(messages.join("; "));
|
|
343610
|
-
}
|
|
343611
|
-
function servesEntryPoint(listed, entryPoint) {
|
|
343612
|
-
return Array.isArray(listed) && listed.some((address) => String(address).toLowerCase() === entryPoint.toLowerCase());
|
|
343613
|
-
}
|
|
343614
|
-
function describeEntryPoints(listed) {
|
|
343615
|
-
return Array.isArray(listed) && listed.length > 0 ? listed.map(String).join(", ") : "none";
|
|
343616
|
-
}
|
|
343617
|
-
function bundlerHost(url2) {
|
|
343618
|
-
try {
|
|
343619
|
-
return new URL(url2).host || "an unparseable URL";
|
|
343620
|
-
} catch {
|
|
343621
|
-
return "an unparseable URL";
|
|
343622
|
-
}
|
|
343623
|
-
}
|
|
343624
|
-
function chainName(chainId) {
|
|
343625
|
-
const label = chainByChainId(chainId)?.label;
|
|
343626
|
-
return label ? `${label} (${formatChainKey(chainId)})` : formatChainKey(chainId);
|
|
343627
|
-
}
|
|
343628
|
-
async function checkBundler(chainId, bundlerUrl, entryPoint, timeoutMs, logger8) {
|
|
343629
|
-
const host = bundlerHost(bundlerUrl);
|
|
343630
|
-
const subject = `Bundler ${host} for ${chainName(chainId)}`;
|
|
343631
|
-
const signal = AbortSignal.timeout(timeoutMs);
|
|
343632
|
-
let listed;
|
|
343633
|
-
try {
|
|
343634
|
-
listed = await supportedEntryPoints(bundlerUrl, signal);
|
|
343635
|
-
} catch (err) {
|
|
343636
|
-
const reason = signal.aborted ? `timed out after ${timeoutMs}ms` : errorReason(err);
|
|
343637
|
-
logger8.warn(
|
|
343638
|
-
{ chain: formatChainKey(chainId), bundler: host },
|
|
343639
|
-
`${subject} did not answer eth_supportedEntryPoints: ${reason.split(bundlerUrl).join(host)}. Continuing without confirming it serves EntryPoint ${entryPoint}`
|
|
343640
|
-
);
|
|
343641
|
-
return void 0;
|
|
343642
|
-
}
|
|
343643
|
-
if (servesEntryPoint(listed, entryPoint)) return void 0;
|
|
343644
|
-
return `${subject} does not support EntryPoint ${entryPoint}; it lists ${describeEntryPoints(listed)}`;
|
|
343645
|
-
}
|
|
343646
|
-
async function supportedEntryPoints(bundlerUrl, signal) {
|
|
343647
|
-
const response = await fetch(bundlerUrl, {
|
|
343648
|
-
method: "POST",
|
|
343649
|
-
headers: { "Content-Type": "application/json" },
|
|
343650
|
-
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_supportedEntryPoints", params: [] }),
|
|
343651
|
-
signal
|
|
343652
|
-
});
|
|
343653
|
-
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
343654
|
-
const json = await response.json();
|
|
343655
|
-
if (json.error) throw new Error(json.error.message ?? JSON.stringify(json.error));
|
|
343656
|
-
const { result } = json;
|
|
343657
|
-
if (!Array.isArray(result) || !result.every((address) => typeof address === "string")) {
|
|
343658
|
-
throw new Error("the result is not a list of addresses");
|
|
343659
|
-
}
|
|
343660
|
-
return result;
|
|
343661
|
-
}
|
|
343662
|
-
function errorReason(err) {
|
|
343663
|
-
if (!(err instanceof Error)) return String(err);
|
|
343664
|
-
const { cause } = err;
|
|
343665
|
-
return cause instanceof Error ? `${err.message} (${cause.message})` : err.message;
|
|
343666
|
-
}
|
|
343667
|
-
|
|
343668
|
-
// src/services/server/setup-api.ts
|
|
343669
343469
|
init_wallet3();
|
|
343670
343470
|
|
|
343671
343471
|
// src/services/substrate-key.ts
|
|
@@ -343781,8 +343581,6 @@ async function handleSetupRequest(server, setup, req, res, path2, method) {
|
|
|
343781
343581
|
return sendJson(res, 200, await validateAlchemyKey(body, deps));
|
|
343782
343582
|
case "validate-rpc":
|
|
343783
343583
|
return sendJson(res, 200, await validateRpc(body, deps));
|
|
343784
|
-
case "validate-bundler":
|
|
343785
|
-
return sendJson(res, 200, await validateBundler(body, deps));
|
|
343786
343584
|
case "validate-token":
|
|
343787
343585
|
return sendJson(res, 200, await validateToken(body));
|
|
343788
343586
|
case "derive-evm-address":
|
|
@@ -343815,9 +343613,7 @@ async function validateAlchemyKey(body, deps) {
|
|
|
343815
343613
|
stateMachineId: meta.stateMachineId,
|
|
343816
343614
|
label: meta.label,
|
|
343817
343615
|
note: meta.note,
|
|
343818
|
-
rpcUrl
|
|
343819
|
-
// Alchemy serves ERC-4337 bundler methods on the same endpoint.
|
|
343820
|
-
bundlerUrl: rpcUrl
|
|
343616
|
+
rpcUrl
|
|
343821
343617
|
};
|
|
343822
343618
|
});
|
|
343823
343619
|
const probe = chains2.find((c6) => c6.rpcUrl);
|
|
@@ -343855,40 +343651,6 @@ async function validateRpc(body, deps) {
|
|
|
343855
343651
|
);
|
|
343856
343652
|
return { ok: results.every((r7) => !r7.error), results };
|
|
343857
343653
|
}
|
|
343858
|
-
async function validateBundler(body, deps) {
|
|
343859
|
-
const url2 = String(body.url ?? "").trim();
|
|
343860
|
-
if (!url2) return { ok: false, warning: "Bundler URL is empty" };
|
|
343861
|
-
try {
|
|
343862
|
-
const entryPoints = await withTimeout3(
|
|
343863
|
-
deps.rpcRequest(url2, "eth_supportedEntryPoints", []),
|
|
343864
|
-
PROBE_TIMEOUT_MS,
|
|
343865
|
-
"Bundler probe"
|
|
343866
|
-
);
|
|
343867
|
-
const chainId = Number(body.chainId);
|
|
343868
|
-
const required2 = Number.isInteger(chainId) ? new ChainConfigService({}).getEntryPointAddress(formatChainKey(chainId)) : void 0;
|
|
343869
|
-
if (!required2) return { ok: true, entryPoints };
|
|
343870
|
-
if (!Array.isArray(entryPoints) || !entryPoints.every((address) => typeof address === "string")) {
|
|
343871
|
-
return {
|
|
343872
|
-
ok: true,
|
|
343873
|
-
entryPoints,
|
|
343874
|
-
warning: `Bundler's eth_supportedEntryPoints answer is not a list of addresses, so it could not be confirmed to support EntryPoint ${required2}, which this chain's solver account uses. Simplex will use it and warn.`
|
|
343875
|
-
};
|
|
343876
|
-
}
|
|
343877
|
-
if (!servesEntryPoint(entryPoints, required2)) {
|
|
343878
|
-
return {
|
|
343879
|
-
ok: true,
|
|
343880
|
-
entryPoints,
|
|
343881
|
-
warning: `Bundler does not support EntryPoint ${required2}, which this chain's solver account uses; it lists ${describeEntryPoints(entryPoints)}. Simplex will refuse to use it.`
|
|
343882
|
-
};
|
|
343883
|
-
}
|
|
343884
|
-
return { ok: true, entryPoints };
|
|
343885
|
-
} catch (err) {
|
|
343886
|
-
return {
|
|
343887
|
-
ok: true,
|
|
343888
|
-
warning: `Bundler did not answer eth_supportedEntryPoints: ${err instanceof Error ? err.message : err}`
|
|
343889
|
-
};
|
|
343890
|
-
}
|
|
343891
|
-
}
|
|
343892
343654
|
async function validateToken(body) {
|
|
343893
343655
|
const rpcUrl = String(body.rpcUrl ?? "").trim();
|
|
343894
343656
|
const address = String(body.address ?? "").trim();
|
|
@@ -344026,7 +343788,6 @@ function maskToml(config5, chainLabels) {
|
|
|
344026
343788
|
}
|
|
344027
343789
|
for (const chain2 of masked.chains) {
|
|
344028
343790
|
chain2.rpcUrls = chain2.rpcUrls.map(maskUrlKey);
|
|
344029
|
-
chain2.bundlerUrl = maskUrlKey(chain2.bundlerUrl);
|
|
344030
343791
|
}
|
|
344031
343792
|
return emitFillerToml(masked, { chainComments: chainLabels });
|
|
344032
343793
|
}
|
|
@@ -344100,12 +343861,7 @@ function openSseStream(req, res, clients) {
|
|
|
344100
343861
|
res.once("close", cleanup);
|
|
344101
343862
|
res.once("error", cleanup);
|
|
344102
343863
|
}
|
|
344103
|
-
var OPERATOR_PROBES = [
|
|
344104
|
-
"/api/setup/validate-token",
|
|
344105
|
-
"/api/setup/validate-rpc",
|
|
344106
|
-
"/api/setup/validate-bundler",
|
|
344107
|
-
"/api/setup/validate-alchemy-key"
|
|
344108
|
-
];
|
|
343864
|
+
var OPERATOR_PROBES = ["/api/setup/validate-token", "/api/setup/validate-rpc", "/api/setup/validate-alchemy-key"];
|
|
344109
343865
|
var LOGS_UNAVAILABLE = "Log capture is not enabled for this filler";
|
|
344110
343866
|
var MAX_LOG_STREAM_QUEUE = 5e3;
|
|
344111
343867
|
var MAX_LOG_PAGE = 2e3;
|
|
@@ -344555,9 +344311,6 @@ var UiServer = class {
|
|
|
344555
344311
|
const body = JSON.parse(await readBody(req));
|
|
344556
344312
|
if (path2 === "/api/setup/validate-rpc")
|
|
344557
344313
|
return sendJson(res, 200, await validateRpc(body, this.deps));
|
|
344558
|
-
if (path2 === "/api/setup/validate-bundler") {
|
|
344559
|
-
return sendJson(res, 200, await validateBundler(body, this.deps));
|
|
344560
|
-
}
|
|
344561
344314
|
if (path2 === "/api/setup/validate-alchemy-key") {
|
|
344562
344315
|
return sendJson(res, 200, await validateAlchemyKey(body, this.deps));
|
|
344563
344316
|
}
|
|
@@ -345273,7 +345026,7 @@ var UiServer = class {
|
|
|
345273
345026
|
stateMachineId: formatChainKey(chainId),
|
|
345274
345027
|
label: chainLabel(chainId),
|
|
345275
345028
|
rpcUrls: chain2.rpcUrls,
|
|
345276
|
-
bundlerUrl:
|
|
345029
|
+
bundlerUrl: hyperbridgeBundlerUrl(chainId) ?? "",
|
|
345277
345030
|
watchOnly: globalWatchOnly ? watchOnly : Boolean(watchOnly?.[String(chainId)]),
|
|
345278
345031
|
running: running.has(chainId)
|
|
345279
345032
|
};
|
|
@@ -345320,11 +345073,11 @@ var UiServer = class {
|
|
|
345320
345073
|
}
|
|
345321
345074
|
const rpcUrls = (Array.isArray(row.rpcUrls) ? row.rpcUrls : []).map((url2) => String(url2).trim()).filter(Boolean);
|
|
345322
345075
|
validateRpcUrls(rpcUrls);
|
|
345323
|
-
const
|
|
345324
|
-
if (!
|
|
345325
|
-
throw new Error(
|
|
345076
|
+
const watchOnly = row.watchOnly === true;
|
|
345077
|
+
if (!watchOnly && op.config.simplex.watchOnly !== true && !hyperbridgeBundlerUrl(chainId)) {
|
|
345078
|
+
throw new Error(`Hyperbridge runs no bundler for ${chainLabel(chainId)}, so it can only be watched`);
|
|
345326
345079
|
}
|
|
345327
|
-
rows.push({ chainId, rpcUrls,
|
|
345080
|
+
rows.push({ chainId, rpcUrls, watchOnly });
|
|
345328
345081
|
}
|
|
345329
345082
|
} catch (err) {
|
|
345330
345083
|
return sendJson(res, 400, { error: err instanceof Error ? err.message : String(err) });
|
|
@@ -345356,7 +345109,7 @@ var UiServer = class {
|
|
|
345356
345109
|
} catch (err) {
|
|
345357
345110
|
return sendJson(res, 400, { error: err instanceof Error ? err.message : String(err) });
|
|
345358
345111
|
}
|
|
345359
|
-
op.config.chains = rows.map(({ rpcUrls
|
|
345112
|
+
op.config.chains = rows.map(({ rpcUrls }) => ({ rpcUrls }));
|
|
345360
345113
|
if (Object.keys(confirmationPolicies).length > 0) op.config.confirmationPolicies = confirmationPolicies;
|
|
345361
345114
|
if (typeof op.config.simplex.watchOnly !== "boolean") {
|
|
345362
345115
|
const perChain = Object.fromEntries(rows.filter((r7) => r7.watchOnly).map((r7) => [String(r7.chainId), true]));
|
|
@@ -352242,7 +351995,7 @@ var UserOpSender = class {
|
|
|
352242
351995
|
let auth;
|
|
352243
351996
|
let fees4;
|
|
352244
351997
|
try {
|
|
352245
|
-
fees4 = await this.getGasPrice(bundlerUrl, publicClient
|
|
351998
|
+
fees4 = await this.getGasPrice(bundlerUrl, publicClient);
|
|
352246
351999
|
const gasForPrefund = gas ?? {
|
|
352247
352000
|
verificationGasLimit: FALLBACK_VERIFICATION_GAS_LIMIT,
|
|
352248
352001
|
callGasLimit: FALLBACK_CALL_GAS_LIMIT,
|
|
@@ -352397,48 +352150,26 @@ var UserOpSender = class {
|
|
|
352397
352150
|
return userOp;
|
|
352398
352151
|
}
|
|
352399
352152
|
/**
|
|
352400
|
-
*
|
|
352401
|
-
*
|
|
352402
|
-
* rundler bundler requires, when the bundler gives one.
|
|
352153
|
+
* Prices the op for the rundler bundler, as the fill path does: its suggested fees, or the
|
|
352154
|
+
* chain's gas price raised to the priority fee it requires where it suggests none.
|
|
352403
352155
|
*/
|
|
352404
|
-
async getGasPrice(bundlerUrl, publicClient
|
|
352405
|
-
const
|
|
352406
|
-
if (lower2.includes("pimlico.io")) {
|
|
352407
|
-
const res = await this.sendBundlerRpc(
|
|
352408
|
-
bundlerUrl,
|
|
352409
|
-
BundlerMethod.PIMLICO_GET_USER_OPERATION_GAS_PRICE,
|
|
352410
|
-
[]
|
|
352411
|
-
);
|
|
352412
|
-
return { maxFeePerGas: BigInt(res.fast.maxFeePerGas), maxPriorityFeePerGas: BigInt(res.fast.maxPriorityFeePerGas) };
|
|
352413
|
-
}
|
|
352414
|
-
if (lower2.includes("alchemy.com")) {
|
|
352415
|
-
const [rundlerPriorityFee2, latestBlock2] = await Promise.all([
|
|
352416
|
-
this.sendBundlerRpc(bundlerUrl, BundlerMethod.RUNDLER_MAX_PRIORITY_FEE_PER_GAS, []),
|
|
352417
|
-
publicClient.getBlock({ blockTag: "latest" })
|
|
352418
|
-
]);
|
|
352419
|
-
const baseFeePerGas = latestBlock2.baseFeePerGas ?? await publicClient.getGasPrice();
|
|
352420
|
-
const isArbitrum = BigInt(chainId) === 42161n;
|
|
352421
|
-
const prioBump = isArbitrum ? 0n : 25n;
|
|
352422
|
-
const maxPriorityFeePerGas = BigInt(rundlerPriorityFee2) + BigInt(rundlerPriorityFee2) * prioBump / 100n;
|
|
352423
|
-
const bufferedBaseFee = baseFeePerGas + baseFeePerGas * 50n / 100n;
|
|
352424
|
-
return { maxFeePerGas: bufferedBaseFee + maxPriorityFeePerGas, maxPriorityFeePerGas };
|
|
352425
|
-
}
|
|
352426
|
-
const [gasPrice, rundlerPriorityFee] = await Promise.all([
|
|
352156
|
+
async getGasPrice(bundlerUrl, publicClient) {
|
|
352157
|
+
const [gasPrice, latestBlock] = await Promise.all([
|
|
352427
352158
|
publicClient.getGasPrice(),
|
|
352428
|
-
|
|
352159
|
+
publicClient.getBlock({ blockTag: "latest" })
|
|
352429
352160
|
]);
|
|
352430
|
-
|
|
352431
|
-
|
|
352432
|
-
|
|
352433
|
-
|
|
352434
|
-
|
|
352435
|
-
|
|
352436
|
-
|
|
352437
|
-
|
|
352438
|
-
|
|
352439
|
-
|
|
352440
|
-
|
|
352441
|
-
|
|
352161
|
+
return rundlerUserOperationFees(
|
|
352162
|
+
bundlerUrl,
|
|
352163
|
+
{
|
|
352164
|
+
maxFeePerGas: gasPrice + gasPrice * MAX_FEE_BUMP_PERCENT / 100n,
|
|
352165
|
+
maxPriorityFeePerGas: gasPrice + gasPrice * PRIORITY_FEE_BUMP_PERCENT / 100n
|
|
352166
|
+
},
|
|
352167
|
+
{
|
|
352168
|
+
baseFeePerGas: latestBlock.baseFeePerGas ?? gasPrice,
|
|
352169
|
+
priorityFeeBumpPercent: PRIORITY_FEE_BUMP_PERCENT,
|
|
352170
|
+
maxFeeBumpPercent: MAX_FEE_BUMP_PERCENT
|
|
352171
|
+
}
|
|
352172
|
+
);
|
|
352442
352173
|
}
|
|
352443
352174
|
async sendBundlerRpc(bundlerUrl, method, params) {
|
|
352444
352175
|
const response = await fetch(bundlerUrl, {
|
|
@@ -386836,6 +386567,86 @@ init_FillerConfigService();
|
|
|
386836
386567
|
init_filler_toml();
|
|
386837
386568
|
init_defaults8();
|
|
386838
386569
|
|
|
386570
|
+
// src/services/bundler-preflight.ts
|
|
386571
|
+
init_esm_shims();
|
|
386572
|
+
init_chains2();
|
|
386573
|
+
init_interpolated_curve();
|
|
386574
|
+
init_Logger();
|
|
386575
|
+
var BUNDLER_PREFLIGHT_TIMEOUT_MS = 1e4;
|
|
386576
|
+
async function assertBundlersServeEntryPoint(chains2, configService, options = {}) {
|
|
386577
|
+
const timeoutMs = options.timeoutMs ?? BUNDLER_PREFLIGHT_TIMEOUT_MS;
|
|
386578
|
+
const logger8 = moduleLogger(configService.loggers, "bundler-preflight");
|
|
386579
|
+
const failures = await Promise.all(
|
|
386580
|
+
chains2.map(async ({ chainId, bundlerUrl }) => {
|
|
386581
|
+
if (options.watchOnly?.[chainId] === true) return void 0;
|
|
386582
|
+
if (!bundlerUrl?.trim()) {
|
|
386583
|
+
return `Hyperbridge runs no bundler for ${chainName(chainId)}, so simplex cannot fill there; set it watch-only`;
|
|
386584
|
+
}
|
|
386585
|
+
const entryPoint = configService.getEntryPointAddress(formatChainKey(chainId));
|
|
386586
|
+
if (!entryPoint) return void 0;
|
|
386587
|
+
return checkBundler(chainId, bundlerUrl.trim(), entryPoint, timeoutMs, logger8);
|
|
386588
|
+
})
|
|
386589
|
+
);
|
|
386590
|
+
const messages = failures.filter((failure) => failure !== void 0);
|
|
386591
|
+
if (messages.length > 0) throw new Error(messages.join("; "));
|
|
386592
|
+
}
|
|
386593
|
+
function servesEntryPoint(listed, entryPoint) {
|
|
386594
|
+
return Array.isArray(listed) && listed.some((address) => String(address).toLowerCase() === entryPoint.toLowerCase());
|
|
386595
|
+
}
|
|
386596
|
+
function describeEntryPoints(listed) {
|
|
386597
|
+
return Array.isArray(listed) && listed.length > 0 ? listed.map(String).join(", ") : "none";
|
|
386598
|
+
}
|
|
386599
|
+
function bundlerHost(url2) {
|
|
386600
|
+
try {
|
|
386601
|
+
return new URL(url2).host || "an unparseable URL";
|
|
386602
|
+
} catch {
|
|
386603
|
+
return "an unparseable URL";
|
|
386604
|
+
}
|
|
386605
|
+
}
|
|
386606
|
+
function chainName(chainId) {
|
|
386607
|
+
const label = chainByChainId(chainId)?.label;
|
|
386608
|
+
return label ? `${label} (${formatChainKey(chainId)})` : formatChainKey(chainId);
|
|
386609
|
+
}
|
|
386610
|
+
async function checkBundler(chainId, bundlerUrl, entryPoint, timeoutMs, logger8) {
|
|
386611
|
+
const host = bundlerHost(bundlerUrl);
|
|
386612
|
+
const subject = `Bundler ${host} for ${chainName(chainId)}`;
|
|
386613
|
+
const signal = AbortSignal.timeout(timeoutMs);
|
|
386614
|
+
let listed;
|
|
386615
|
+
try {
|
|
386616
|
+
listed = await supportedEntryPoints(bundlerUrl, signal);
|
|
386617
|
+
} catch (err) {
|
|
386618
|
+
const reason = signal.aborted ? `timed out after ${timeoutMs}ms` : errorReason(err);
|
|
386619
|
+
logger8.warn(
|
|
386620
|
+
{ chain: formatChainKey(chainId), bundler: host },
|
|
386621
|
+
`${subject} did not answer eth_supportedEntryPoints: ${reason.split(bundlerUrl).join(host)}. Continuing without confirming it serves EntryPoint ${entryPoint}`
|
|
386622
|
+
);
|
|
386623
|
+
return void 0;
|
|
386624
|
+
}
|
|
386625
|
+
if (servesEntryPoint(listed, entryPoint)) return void 0;
|
|
386626
|
+
return `${subject} does not support EntryPoint ${entryPoint}; it lists ${describeEntryPoints(listed)}`;
|
|
386627
|
+
}
|
|
386628
|
+
async function supportedEntryPoints(bundlerUrl, signal) {
|
|
386629
|
+
const response = await fetch(bundlerUrl, {
|
|
386630
|
+
method: "POST",
|
|
386631
|
+
headers: { "Content-Type": "application/json" },
|
|
386632
|
+
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_supportedEntryPoints", params: [] }),
|
|
386633
|
+
signal
|
|
386634
|
+
});
|
|
386635
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
386636
|
+
const json = await response.json();
|
|
386637
|
+
if (json.error) throw new Error(json.error.message ?? JSON.stringify(json.error));
|
|
386638
|
+
const { result } = json;
|
|
386639
|
+
if (!Array.isArray(result) || !result.every((address) => typeof address === "string")) {
|
|
386640
|
+
throw new Error("the result is not a list of addresses");
|
|
386641
|
+
}
|
|
386642
|
+
return result;
|
|
386643
|
+
}
|
|
386644
|
+
function errorReason(err) {
|
|
386645
|
+
if (!(err instanceof Error)) return String(err);
|
|
386646
|
+
const { cause } = err;
|
|
386647
|
+
return cause instanceof Error ? `${err.message} (${cause.message})` : err.message;
|
|
386648
|
+
}
|
|
386649
|
+
|
|
386839
386650
|
// src/orderbook/lifecycle.ts
|
|
386840
386651
|
init_esm_shims();
|
|
386841
386652
|
init_Logger();
|
|
@@ -388943,7 +388754,7 @@ var OrderScanner = class _OrderScanner {
|
|
|
388943
388754
|
async addChainNow(chain2) {
|
|
388944
388755
|
if (this.closed) throw new Error("This OrderScanner is closed");
|
|
388945
388756
|
const rpcUrls = validateRpcUrls(chain2.rpcUrls);
|
|
388946
|
-
const chainId = chain2.chainId ?? (await resolveChainConfigs([{ rpcUrls
|
|
388757
|
+
const chainId = chain2.chainId ?? (await resolveChainConfigs([{ rpcUrls }], {
|
|
388947
388758
|
loggers: this.loggers,
|
|
388948
388759
|
tolerateUnreachable: true
|
|
388949
388760
|
}))[0].chainId;
|
|
@@ -389376,10 +389187,7 @@ var ChainController = class {
|
|
|
389376
389187
|
async add(chain2) {
|
|
389377
389188
|
return this.serialise(async () => {
|
|
389378
389189
|
validateRpcUrls(chain2.rpcUrls);
|
|
389379
|
-
|
|
389380
|
-
throw new Error("A bundler URL is required to submit fill UserOperations");
|
|
389381
|
-
}
|
|
389382
|
-
const [resolved] = await resolveChainConfigs([{ rpcUrls: chain2.rpcUrls, bundlerUrl: chain2.bundlerUrl }]);
|
|
389190
|
+
const [resolved] = await resolveChainConfigs([{ rpcUrls: chain2.rpcUrls }]);
|
|
389383
389191
|
const { chainId } = resolved;
|
|
389384
389192
|
const { configService, config: config5, intentFiller } = this.runtime;
|
|
389385
389193
|
if (configService.getConfiguredChainIds().includes(chainId)) {
|
|
@@ -389408,7 +389216,7 @@ var ChainController = class {
|
|
|
389408
389216
|
if (watchOnly) intentFiller.setWatchOnly(chainId, true);
|
|
389409
389217
|
try {
|
|
389410
389218
|
if (!inScanner) {
|
|
389411
|
-
await this.scanner.addChain({ rpcUrls: chain2.rpcUrls,
|
|
389219
|
+
await this.scanner.addChain({ rpcUrls: chain2.rpcUrls, chainId });
|
|
389412
389220
|
}
|
|
389413
389221
|
this.runtime.chainClientManager.invalidate(formatChainKey(chainId));
|
|
389414
389222
|
await intentFiller.addChain(configService.getChainConfig(formatChainKey(chainId)));
|
|
@@ -389425,7 +389233,7 @@ var ChainController = class {
|
|
|
389425
389233
|
this.runtime.confirmationPolicy.adopt(chainId, resolvedPolicy);
|
|
389426
389234
|
}
|
|
389427
389235
|
this.runtime.resolvedChains.push(resolved);
|
|
389428
|
-
config5.chains = [...config5.chains, { rpcUrls: chain2.rpcUrls
|
|
389236
|
+
config5.chains = [...config5.chains, { rpcUrls: chain2.rpcUrls }];
|
|
389429
389237
|
if (Object.keys(confirmationPolicies).length > 0) config5.confirmationPolicies = confirmationPolicies;
|
|
389430
389238
|
this.syncWatchOnlyToConfig();
|
|
389431
389239
|
await this.persist();
|
|
@@ -389470,9 +389278,7 @@ var ChainController = class {
|
|
|
389470
389278
|
validateRpcUrls(rpcUrls);
|
|
389471
389279
|
const index3 = this.runtime.resolvedChains.findIndex((chain2) => chain2.chainId === chainId);
|
|
389472
389280
|
if (index3 < 0) throw new Error(`Chain ${chainId} is not configured`);
|
|
389473
|
-
const [probed] = await resolveChainConfigs([
|
|
389474
|
-
{ rpcUrls, bundlerUrl: this.runtime.resolvedChains[index3].bundlerUrl ?? "" }
|
|
389475
|
-
]);
|
|
389281
|
+
const [probed] = await resolveChainConfigs([{ rpcUrls }]);
|
|
389476
389282
|
if (probed.chainId !== chainId) {
|
|
389477
389283
|
throw new Error(`Those endpoints answer for chain ${probed.chainId}, not ${chainId}`);
|
|
389478
389284
|
}
|
|
@@ -389491,20 +389297,6 @@ var ChainController = class {
|
|
|
389491
389297
|
await this.persist();
|
|
389492
389298
|
});
|
|
389493
389299
|
}
|
|
389494
|
-
async setBundlerUrl(chainId, bundlerUrl) {
|
|
389495
|
-
return this.serialise(async () => {
|
|
389496
|
-
if (!bundlerUrl?.trim()) throw new Error("A bundler URL is required");
|
|
389497
|
-
const index3 = this.runtime.resolvedChains.findIndex((chain2) => chain2.chainId === chainId);
|
|
389498
|
-
if (index3 < 0) throw new Error(`Chain ${chainId} is not configured`);
|
|
389499
|
-
await assertBundlersServeEntryPoint([{ chainId, bundlerUrl }], this.runtime.configService, {
|
|
389500
|
-
watchOnly: this.runtime.intentFiller.getWatchOnly()
|
|
389501
|
-
});
|
|
389502
|
-
this.runtime.configService.setBundlerUrl(chainId, bundlerUrl);
|
|
389503
|
-
this.runtime.resolvedChains[index3].bundlerUrl = bundlerUrl;
|
|
389504
|
-
this.runtime.config.chains[index3].bundlerUrl = bundlerUrl;
|
|
389505
|
-
await this.persist();
|
|
389506
|
-
});
|
|
389507
|
-
}
|
|
389508
389300
|
/** Monitor without filling. Takes effect on the next order. */
|
|
389509
389301
|
async setWatchOnly(chainId, watchOnly) {
|
|
389510
389302
|
return this.serialise(async () => {
|