@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/index.cjs
CHANGED
|
@@ -625,6 +625,20 @@ var ConfirmationPolicy = class {
|
|
|
625
625
|
// src/core/filler.ts
|
|
626
626
|
var import_p_queue = __toESM(require("p-queue"), 1);
|
|
627
627
|
|
|
628
|
+
// src/config/bundlers.ts
|
|
629
|
+
var HYPERBRIDGE_BUNDLER_URLS = {
|
|
630
|
+
1: "https://bundler.polytope.technology/ethereum",
|
|
631
|
+
56: "https://bundler.polytope.technology/bsc",
|
|
632
|
+
97: "https://bundler.polytope.technology/bsc-chapel",
|
|
633
|
+
137: "https://bundler.polytope.technology/polygon",
|
|
634
|
+
8453: "https://bundler.polytope.technology/base",
|
|
635
|
+
42161: "https://bundler.polytope.technology/arbitrum",
|
|
636
|
+
80002: "https://bundler.polytope.technology/polygon-amoy"
|
|
637
|
+
};
|
|
638
|
+
function hyperbridgeBundlerUrl(chainId) {
|
|
639
|
+
return HYPERBRIDGE_BUNDLER_URLS[chainId];
|
|
640
|
+
}
|
|
641
|
+
|
|
628
642
|
// src/config/asset-registry.ts
|
|
629
643
|
var import_viem = require("viem");
|
|
630
644
|
var BUILTIN_ASSETS = {
|
|
@@ -1245,7 +1259,7 @@ async function resolveChainConfigs(chains, options = {}) {
|
|
|
1245
1259
|
"RPC endpoint could not report its chainId at startup; keeping it for the quorum to judge per call"
|
|
1246
1260
|
);
|
|
1247
1261
|
}
|
|
1248
|
-
return { chainId: first.chainId, rpcUrls, bundlerUrl:
|
|
1262
|
+
return { chainId: first.chainId, rpcUrls, bundlerUrl: hyperbridgeBundlerUrl(first.chainId) };
|
|
1249
1263
|
})
|
|
1250
1264
|
);
|
|
1251
1265
|
}
|
|
@@ -1314,12 +1328,6 @@ var FillerConfigService = class {
|
|
|
1314
1328
|
}
|
|
1315
1329
|
this.rpcOverrides.set(chainId, validateRpcUrls(rpcUrls));
|
|
1316
1330
|
}
|
|
1317
|
-
setBundlerUrl(chainId, bundlerUrl) {
|
|
1318
|
-
if (!this.rpcOverrides.has(chainId)) {
|
|
1319
|
-
throw new Error(`Chain ${chainId} is not configured`);
|
|
1320
|
-
}
|
|
1321
|
-
this.bundlerUrls.set(chainId, bundlerUrl);
|
|
1322
|
-
}
|
|
1323
1331
|
/** Replaces the rebalancing config at runtime; trigger checks read it live. */
|
|
1324
1332
|
setRebalancing(rebalancing) {
|
|
1325
1333
|
if (this.fillerConfig) this.fillerConfig.rebalancing = rebalancing;
|
|
@@ -1681,9 +1689,6 @@ function validateConfig(config, cliWatchOnly = false) {
|
|
|
1681
1689
|
if (!Array.isArray(chain.rpcUrls) || chain.rpcUrls.length === 0 || chain.rpcUrls.some((u) => !u)) {
|
|
1682
1690
|
throw new Error("Each chain configuration must have rpcUrls (a non-empty array of strings)");
|
|
1683
1691
|
}
|
|
1684
|
-
if (!chain.bundlerUrl) {
|
|
1685
|
-
throw new Error("Each chain configuration must have bundlerUrl");
|
|
1686
|
-
}
|
|
1687
1692
|
}
|
|
1688
1693
|
const concurrent = config.simplex.maxConcurrentOrders;
|
|
1689
1694
|
if (concurrent !== void 0) {
|
|
@@ -2545,13 +2550,6 @@ var FREE_RPC_URLS = {
|
|
|
2545
2550
|
"https://arb1.arbitrum.io/rpc"
|
|
2546
2551
|
]
|
|
2547
2552
|
};
|
|
2548
|
-
var HYPERBRIDGE_BUNDLER_URLS = {
|
|
2549
|
-
1: "https://bundler.polytope.technology/ethereum",
|
|
2550
|
-
56: "https://bundler.polytope.technology/bsc",
|
|
2551
|
-
137: "https://bundler.polytope.technology/polygon",
|
|
2552
|
-
8453: "https://bundler.polytope.technology/base",
|
|
2553
|
-
42161: "https://bundler.polytope.technology/arbitrum"
|
|
2554
|
-
};
|
|
2555
2553
|
var CHAIN_NATIVE_SYMBOLS = {
|
|
2556
2554
|
1: "ETH",
|
|
2557
2555
|
56: "BNB",
|
|
@@ -2653,7 +2651,8 @@ var INIT_CHAINS = [
|
|
|
2653
2651
|
label: "Polygon Amoy",
|
|
2654
2652
|
network: "testnet",
|
|
2655
2653
|
alchemySubdomain: "polygon-amoy",
|
|
2656
|
-
explorerUrl: external_links_default.chainExplorers.polygonAmoy
|
|
2654
|
+
explorerUrl: external_links_default.chainExplorers.polygonAmoy,
|
|
2655
|
+
hyperbridgeBundlerUrl: HYPERBRIDGE_BUNDLER_URLS[80002]
|
|
2657
2656
|
},
|
|
2658
2657
|
{
|
|
2659
2658
|
chainId: 97,
|
|
@@ -2661,7 +2660,8 @@ var INIT_CHAINS = [
|
|
|
2661
2660
|
label: "BSC Chapel",
|
|
2662
2661
|
network: "testnet",
|
|
2663
2662
|
alchemySubdomain: "bnb-testnet",
|
|
2664
|
-
explorerUrl: external_links_default.chainExplorers.bnbChapel
|
|
2663
|
+
explorerUrl: external_links_default.chainExplorers.bnbChapel,
|
|
2664
|
+
hyperbridgeBundlerUrl: HYPERBRIDGE_BUNDLER_URLS[97]
|
|
2665
2665
|
}
|
|
2666
2666
|
];
|
|
2667
2667
|
function chainByChainId(chainId) {
|
|
@@ -4458,80 +4458,6 @@ async function patchRuntimeState(store, patch) {
|
|
|
4458
4458
|
return next;
|
|
4459
4459
|
}
|
|
4460
4460
|
|
|
4461
|
-
// src/services/bundler-preflight.ts
|
|
4462
|
-
var BUNDLER_PREFLIGHT_TIMEOUT_MS = 1e4;
|
|
4463
|
-
async function assertBundlersServeEntryPoint(chains, configService, options = {}) {
|
|
4464
|
-
const timeoutMs = options.timeoutMs ?? BUNDLER_PREFLIGHT_TIMEOUT_MS;
|
|
4465
|
-
const logger = moduleLogger(configService.loggers, "bundler-preflight");
|
|
4466
|
-
const failures = await Promise.all(
|
|
4467
|
-
chains.map(async ({ chainId, bundlerUrl }) => {
|
|
4468
|
-
if (options.watchOnly?.[chainId] === true) return void 0;
|
|
4469
|
-
if (!bundlerUrl?.trim()) return void 0;
|
|
4470
|
-
const entryPoint = configService.getEntryPointAddress(formatChainKey(chainId));
|
|
4471
|
-
if (!entryPoint) return void 0;
|
|
4472
|
-
return checkBundler(chainId, bundlerUrl.trim(), entryPoint, timeoutMs, logger);
|
|
4473
|
-
})
|
|
4474
|
-
);
|
|
4475
|
-
const messages = failures.filter((failure) => failure !== void 0);
|
|
4476
|
-
if (messages.length > 0) throw new Error(messages.join("; "));
|
|
4477
|
-
}
|
|
4478
|
-
function servesEntryPoint(listed, entryPoint) {
|
|
4479
|
-
return Array.isArray(listed) && listed.some((address) => String(address).toLowerCase() === entryPoint.toLowerCase());
|
|
4480
|
-
}
|
|
4481
|
-
function describeEntryPoints(listed) {
|
|
4482
|
-
return Array.isArray(listed) && listed.length > 0 ? listed.map(String).join(", ") : "none";
|
|
4483
|
-
}
|
|
4484
|
-
function bundlerHost(url) {
|
|
4485
|
-
try {
|
|
4486
|
-
return new URL(url).host || "an unparseable URL";
|
|
4487
|
-
} catch {
|
|
4488
|
-
return "an unparseable URL";
|
|
4489
|
-
}
|
|
4490
|
-
}
|
|
4491
|
-
function chainName(chainId) {
|
|
4492
|
-
const label = chainByChainId(chainId)?.label;
|
|
4493
|
-
return label ? `${label} (${formatChainKey(chainId)})` : formatChainKey(chainId);
|
|
4494
|
-
}
|
|
4495
|
-
async function checkBundler(chainId, bundlerUrl, entryPoint, timeoutMs, logger) {
|
|
4496
|
-
const host = bundlerHost(bundlerUrl);
|
|
4497
|
-
const subject = `Bundler ${host} for ${chainName(chainId)}`;
|
|
4498
|
-
const signal = AbortSignal.timeout(timeoutMs);
|
|
4499
|
-
let listed;
|
|
4500
|
-
try {
|
|
4501
|
-
listed = await supportedEntryPoints(bundlerUrl, signal);
|
|
4502
|
-
} catch (err) {
|
|
4503
|
-
const reason = signal.aborted ? `timed out after ${timeoutMs}ms` : errorReason(err);
|
|
4504
|
-
logger.warn(
|
|
4505
|
-
{ chain: formatChainKey(chainId), bundler: host },
|
|
4506
|
-
`${subject} did not answer eth_supportedEntryPoints: ${reason.split(bundlerUrl).join(host)}. Continuing without confirming it serves EntryPoint ${entryPoint}`
|
|
4507
|
-
);
|
|
4508
|
-
return void 0;
|
|
4509
|
-
}
|
|
4510
|
-
if (servesEntryPoint(listed, entryPoint)) return void 0;
|
|
4511
|
-
return `${subject} does not support EntryPoint ${entryPoint}; it lists ${describeEntryPoints(listed)}`;
|
|
4512
|
-
}
|
|
4513
|
-
async function supportedEntryPoints(bundlerUrl, signal) {
|
|
4514
|
-
const response = await fetch(bundlerUrl, {
|
|
4515
|
-
method: "POST",
|
|
4516
|
-
headers: { "Content-Type": "application/json" },
|
|
4517
|
-
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_supportedEntryPoints", params: [] }),
|
|
4518
|
-
signal
|
|
4519
|
-
});
|
|
4520
|
-
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
4521
|
-
const json = await response.json();
|
|
4522
|
-
if (json.error) throw new Error(json.error.message ?? JSON.stringify(json.error));
|
|
4523
|
-
const { result } = json;
|
|
4524
|
-
if (!Array.isArray(result) || !result.every((address) => typeof address === "string")) {
|
|
4525
|
-
throw new Error("the result is not a list of addresses");
|
|
4526
|
-
}
|
|
4527
|
-
return result;
|
|
4528
|
-
}
|
|
4529
|
-
function errorReason(err) {
|
|
4530
|
-
if (!(err instanceof Error)) return String(err);
|
|
4531
|
-
const { cause } = err;
|
|
4532
|
-
return cause instanceof Error ? `${err.message} (${cause.message})` : err.message;
|
|
4533
|
-
}
|
|
4534
|
-
|
|
4535
4461
|
// src/services/wallet/mpcvault.ts
|
|
4536
4462
|
var import_viem7 = require("viem");
|
|
4537
4463
|
var grpc = __toESM(require("@grpc/grpc-js"), 1);
|
|
@@ -19996,7 +19922,7 @@ var UserOpSender = class {
|
|
|
19996
19922
|
let auth;
|
|
19997
19923
|
let fees;
|
|
19998
19924
|
try {
|
|
19999
|
-
fees = await this.getGasPrice(bundlerUrl, publicClient
|
|
19925
|
+
fees = await this.getGasPrice(bundlerUrl, publicClient);
|
|
20000
19926
|
const gasForPrefund = gas ?? {
|
|
20001
19927
|
verificationGasLimit: FALLBACK_VERIFICATION_GAS_LIMIT,
|
|
20002
19928
|
callGasLimit: FALLBACK_CALL_GAS_LIMIT,
|
|
@@ -20151,48 +20077,26 @@ var UserOpSender = class {
|
|
|
20151
20077
|
return userOp;
|
|
20152
20078
|
}
|
|
20153
20079
|
/**
|
|
20154
|
-
*
|
|
20155
|
-
*
|
|
20156
|
-
* rundler bundler requires, when the bundler gives one.
|
|
20080
|
+
* Prices the op for the rundler bundler, as the fill path does: its suggested fees, or the
|
|
20081
|
+
* chain's gas price raised to the priority fee it requires where it suggests none.
|
|
20157
20082
|
*/
|
|
20158
|
-
async getGasPrice(bundlerUrl, publicClient
|
|
20159
|
-
const
|
|
20160
|
-
if (lower.includes("pimlico.io")) {
|
|
20161
|
-
const res = await this.sendBundlerRpc(
|
|
20162
|
-
bundlerUrl,
|
|
20163
|
-
import_sdk8.BundlerMethod.PIMLICO_GET_USER_OPERATION_GAS_PRICE,
|
|
20164
|
-
[]
|
|
20165
|
-
);
|
|
20166
|
-
return { maxFeePerGas: BigInt(res.fast.maxFeePerGas), maxPriorityFeePerGas: BigInt(res.fast.maxPriorityFeePerGas) };
|
|
20167
|
-
}
|
|
20168
|
-
if (lower.includes("alchemy.com")) {
|
|
20169
|
-
const [rundlerPriorityFee2, latestBlock2] = await Promise.all([
|
|
20170
|
-
this.sendBundlerRpc(bundlerUrl, import_sdk8.BundlerMethod.RUNDLER_MAX_PRIORITY_FEE_PER_GAS, []),
|
|
20171
|
-
publicClient.getBlock({ blockTag: "latest" })
|
|
20172
|
-
]);
|
|
20173
|
-
const baseFeePerGas = latestBlock2.baseFeePerGas ?? await publicClient.getGasPrice();
|
|
20174
|
-
const isArbitrum = BigInt(chainId) === 42161n;
|
|
20175
|
-
const prioBump = isArbitrum ? 0n : 25n;
|
|
20176
|
-
const maxPriorityFeePerGas = BigInt(rundlerPriorityFee2) + BigInt(rundlerPriorityFee2) * prioBump / 100n;
|
|
20177
|
-
const bufferedBaseFee = baseFeePerGas + baseFeePerGas * 50n / 100n;
|
|
20178
|
-
return { maxFeePerGas: bufferedBaseFee + maxPriorityFeePerGas, maxPriorityFeePerGas };
|
|
20179
|
-
}
|
|
20180
|
-
const [gasPrice, rundlerPriorityFee] = await Promise.all([
|
|
20083
|
+
async getGasPrice(bundlerUrl, publicClient) {
|
|
20084
|
+
const [gasPrice, latestBlock] = await Promise.all([
|
|
20181
20085
|
publicClient.getGasPrice(),
|
|
20182
|
-
(
|
|
20086
|
+
publicClient.getBlock({ blockTag: "latest" })
|
|
20183
20087
|
]);
|
|
20184
|
-
|
|
20185
|
-
|
|
20186
|
-
|
|
20187
|
-
|
|
20188
|
-
|
|
20189
|
-
|
|
20190
|
-
|
|
20191
|
-
|
|
20192
|
-
|
|
20193
|
-
|
|
20194
|
-
|
|
20195
|
-
|
|
20088
|
+
return (0, import_sdk8.rundlerUserOperationFees)(
|
|
20089
|
+
bundlerUrl,
|
|
20090
|
+
{
|
|
20091
|
+
maxFeePerGas: gasPrice + gasPrice * MAX_FEE_BUMP_PERCENT / 100n,
|
|
20092
|
+
maxPriorityFeePerGas: gasPrice + gasPrice * PRIORITY_FEE_BUMP_PERCENT / 100n
|
|
20093
|
+
},
|
|
20094
|
+
{
|
|
20095
|
+
baseFeePerGas: latestBlock.baseFeePerGas ?? gasPrice,
|
|
20096
|
+
priorityFeeBumpPercent: PRIORITY_FEE_BUMP_PERCENT,
|
|
20097
|
+
maxFeeBumpPercent: MAX_FEE_BUMP_PERCENT
|
|
20098
|
+
}
|
|
20099
|
+
);
|
|
20196
20100
|
}
|
|
20197
20101
|
async sendBundlerRpc(bundlerUrl, method, params) {
|
|
20198
20102
|
const response = await fetch(bundlerUrl, {
|
|
@@ -21004,7 +20908,7 @@ var BinanceRebalancer = class {
|
|
|
21004
20908
|
// src/services/rebalancers/cctp.ts
|
|
21005
20909
|
var import_bridge_kit = require("@circle-fin/bridge-kit");
|
|
21006
20910
|
var import_adapter_viem_v2 = require("@circle-fin/adapter-viem-v2");
|
|
21007
|
-
var
|
|
20911
|
+
var import_chains = require("@circle-fin/bridge-kit/chains");
|
|
21008
20912
|
var import_sdk11 = require("@hyperbridge/sdk");
|
|
21009
20913
|
var CHAIN_ID_TO_CCTP = {
|
|
21010
20914
|
1: "Ethereum",
|
|
@@ -21057,18 +20961,18 @@ var CctpRebalancer = class {
|
|
|
21057
20961
|
{
|
|
21058
20962
|
addressContext: "user-controlled",
|
|
21059
20963
|
supportedChains: [
|
|
21060
|
-
|
|
21061
|
-
|
|
21062
|
-
|
|
21063
|
-
|
|
21064
|
-
|
|
21065
|
-
|
|
21066
|
-
|
|
21067
|
-
|
|
21068
|
-
|
|
21069
|
-
|
|
21070
|
-
|
|
21071
|
-
|
|
20964
|
+
import_chains.Ethereum,
|
|
20965
|
+
import_chains.EthereumSepolia,
|
|
20966
|
+
import_chains.Arbitrum,
|
|
20967
|
+
import_chains.ArbitrumSepolia,
|
|
20968
|
+
import_chains.Base,
|
|
20969
|
+
import_chains.BaseSepolia,
|
|
20970
|
+
import_chains.Optimism,
|
|
20971
|
+
import_chains.OptimismSepolia,
|
|
20972
|
+
import_chains.Polygon,
|
|
20973
|
+
import_chains.PolygonAmoy,
|
|
20974
|
+
import_chains.Unichain,
|
|
20975
|
+
import_chains.UnichainSepolia
|
|
21072
20976
|
]
|
|
21073
20977
|
}
|
|
21074
20978
|
);
|
|
@@ -23913,6 +23817,82 @@ var TokenSender = class {
|
|
|
23913
23817
|
}
|
|
23914
23818
|
};
|
|
23915
23819
|
|
|
23820
|
+
// src/services/bundler-preflight.ts
|
|
23821
|
+
var BUNDLER_PREFLIGHT_TIMEOUT_MS = 1e4;
|
|
23822
|
+
async function assertBundlersServeEntryPoint(chains, configService, options = {}) {
|
|
23823
|
+
const timeoutMs = options.timeoutMs ?? BUNDLER_PREFLIGHT_TIMEOUT_MS;
|
|
23824
|
+
const logger = moduleLogger(configService.loggers, "bundler-preflight");
|
|
23825
|
+
const failures = await Promise.all(
|
|
23826
|
+
chains.map(async ({ chainId, bundlerUrl }) => {
|
|
23827
|
+
if (options.watchOnly?.[chainId] === true) return void 0;
|
|
23828
|
+
if (!bundlerUrl?.trim()) {
|
|
23829
|
+
return `Hyperbridge runs no bundler for ${chainName(chainId)}, so simplex cannot fill there; set it watch-only`;
|
|
23830
|
+
}
|
|
23831
|
+
const entryPoint = configService.getEntryPointAddress(formatChainKey(chainId));
|
|
23832
|
+
if (!entryPoint) return void 0;
|
|
23833
|
+
return checkBundler(chainId, bundlerUrl.trim(), entryPoint, timeoutMs, logger);
|
|
23834
|
+
})
|
|
23835
|
+
);
|
|
23836
|
+
const messages = failures.filter((failure) => failure !== void 0);
|
|
23837
|
+
if (messages.length > 0) throw new Error(messages.join("; "));
|
|
23838
|
+
}
|
|
23839
|
+
function servesEntryPoint(listed, entryPoint) {
|
|
23840
|
+
return Array.isArray(listed) && listed.some((address) => String(address).toLowerCase() === entryPoint.toLowerCase());
|
|
23841
|
+
}
|
|
23842
|
+
function describeEntryPoints(listed) {
|
|
23843
|
+
return Array.isArray(listed) && listed.length > 0 ? listed.map(String).join(", ") : "none";
|
|
23844
|
+
}
|
|
23845
|
+
function bundlerHost(url) {
|
|
23846
|
+
try {
|
|
23847
|
+
return new URL(url).host || "an unparseable URL";
|
|
23848
|
+
} catch {
|
|
23849
|
+
return "an unparseable URL";
|
|
23850
|
+
}
|
|
23851
|
+
}
|
|
23852
|
+
function chainName(chainId) {
|
|
23853
|
+
const label = chainByChainId(chainId)?.label;
|
|
23854
|
+
return label ? `${label} (${formatChainKey(chainId)})` : formatChainKey(chainId);
|
|
23855
|
+
}
|
|
23856
|
+
async function checkBundler(chainId, bundlerUrl, entryPoint, timeoutMs, logger) {
|
|
23857
|
+
const host = bundlerHost(bundlerUrl);
|
|
23858
|
+
const subject = `Bundler ${host} for ${chainName(chainId)}`;
|
|
23859
|
+
const signal = AbortSignal.timeout(timeoutMs);
|
|
23860
|
+
let listed;
|
|
23861
|
+
try {
|
|
23862
|
+
listed = await supportedEntryPoints(bundlerUrl, signal);
|
|
23863
|
+
} catch (err) {
|
|
23864
|
+
const reason = signal.aborted ? `timed out after ${timeoutMs}ms` : errorReason(err);
|
|
23865
|
+
logger.warn(
|
|
23866
|
+
{ chain: formatChainKey(chainId), bundler: host },
|
|
23867
|
+
`${subject} did not answer eth_supportedEntryPoints: ${reason.split(bundlerUrl).join(host)}. Continuing without confirming it serves EntryPoint ${entryPoint}`
|
|
23868
|
+
);
|
|
23869
|
+
return void 0;
|
|
23870
|
+
}
|
|
23871
|
+
if (servesEntryPoint(listed, entryPoint)) return void 0;
|
|
23872
|
+
return `${subject} does not support EntryPoint ${entryPoint}; it lists ${describeEntryPoints(listed)}`;
|
|
23873
|
+
}
|
|
23874
|
+
async function supportedEntryPoints(bundlerUrl, signal) {
|
|
23875
|
+
const response = await fetch(bundlerUrl, {
|
|
23876
|
+
method: "POST",
|
|
23877
|
+
headers: { "Content-Type": "application/json" },
|
|
23878
|
+
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_supportedEntryPoints", params: [] }),
|
|
23879
|
+
signal
|
|
23880
|
+
});
|
|
23881
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
23882
|
+
const json = await response.json();
|
|
23883
|
+
if (json.error) throw new Error(json.error.message ?? JSON.stringify(json.error));
|
|
23884
|
+
const { result } = json;
|
|
23885
|
+
if (!Array.isArray(result) || !result.every((address) => typeof address === "string")) {
|
|
23886
|
+
throw new Error("the result is not a list of addresses");
|
|
23887
|
+
}
|
|
23888
|
+
return result;
|
|
23889
|
+
}
|
|
23890
|
+
function errorReason(err) {
|
|
23891
|
+
if (!(err instanceof Error)) return String(err);
|
|
23892
|
+
const { cause } = err;
|
|
23893
|
+
return cause instanceof Error ? `${err.message} (${cause.message})` : err.message;
|
|
23894
|
+
}
|
|
23895
|
+
|
|
23916
23896
|
// src/orderbook/lifecycle.ts
|
|
23917
23897
|
var EXPIRY_SWEEP_MS = 3e4;
|
|
23918
23898
|
var LimitOrderLifecycle = class {
|
|
@@ -25989,7 +25969,7 @@ var OrderScanner = class _OrderScanner {
|
|
|
25989
25969
|
async addChainNow(chain) {
|
|
25990
25970
|
if (this.closed) throw new Error("This OrderScanner is closed");
|
|
25991
25971
|
const rpcUrls = validateRpcUrls(chain.rpcUrls);
|
|
25992
|
-
const chainId = chain.chainId ?? (await resolveChainConfigs([{ rpcUrls
|
|
25972
|
+
const chainId = chain.chainId ?? (await resolveChainConfigs([{ rpcUrls }], {
|
|
25993
25973
|
loggers: this.loggers,
|
|
25994
25974
|
tolerateUnreachable: true
|
|
25995
25975
|
}))[0].chainId;
|
|
@@ -26421,10 +26401,7 @@ var ChainController = class {
|
|
|
26421
26401
|
async add(chain) {
|
|
26422
26402
|
return this.serialise(async () => {
|
|
26423
26403
|
validateRpcUrls(chain.rpcUrls);
|
|
26424
|
-
|
|
26425
|
-
throw new Error("A bundler URL is required to submit fill UserOperations");
|
|
26426
|
-
}
|
|
26427
|
-
const [resolved] = await resolveChainConfigs([{ rpcUrls: chain.rpcUrls, bundlerUrl: chain.bundlerUrl }]);
|
|
26404
|
+
const [resolved] = await resolveChainConfigs([{ rpcUrls: chain.rpcUrls }]);
|
|
26428
26405
|
const { chainId } = resolved;
|
|
26429
26406
|
const { configService, config, intentFiller } = this.runtime;
|
|
26430
26407
|
if (configService.getConfiguredChainIds().includes(chainId)) {
|
|
@@ -26453,7 +26430,7 @@ var ChainController = class {
|
|
|
26453
26430
|
if (watchOnly) intentFiller.setWatchOnly(chainId, true);
|
|
26454
26431
|
try {
|
|
26455
26432
|
if (!inScanner) {
|
|
26456
|
-
await this.scanner.addChain({ rpcUrls: chain.rpcUrls,
|
|
26433
|
+
await this.scanner.addChain({ rpcUrls: chain.rpcUrls, chainId });
|
|
26457
26434
|
}
|
|
26458
26435
|
this.runtime.chainClientManager.invalidate(formatChainKey(chainId));
|
|
26459
26436
|
await intentFiller.addChain(configService.getChainConfig(formatChainKey(chainId)));
|
|
@@ -26470,7 +26447,7 @@ var ChainController = class {
|
|
|
26470
26447
|
this.runtime.confirmationPolicy.adopt(chainId, resolvedPolicy);
|
|
26471
26448
|
}
|
|
26472
26449
|
this.runtime.resolvedChains.push(resolved);
|
|
26473
|
-
config.chains = [...config.chains, { rpcUrls: chain.rpcUrls
|
|
26450
|
+
config.chains = [...config.chains, { rpcUrls: chain.rpcUrls }];
|
|
26474
26451
|
if (Object.keys(confirmationPolicies).length > 0) config.confirmationPolicies = confirmationPolicies;
|
|
26475
26452
|
this.syncWatchOnlyToConfig();
|
|
26476
26453
|
await this.persist();
|
|
@@ -26515,9 +26492,7 @@ var ChainController = class {
|
|
|
26515
26492
|
validateRpcUrls(rpcUrls);
|
|
26516
26493
|
const index = this.runtime.resolvedChains.findIndex((chain) => chain.chainId === chainId);
|
|
26517
26494
|
if (index < 0) throw new Error(`Chain ${chainId} is not configured`);
|
|
26518
|
-
const [probed] = await resolveChainConfigs([
|
|
26519
|
-
{ rpcUrls, bundlerUrl: this.runtime.resolvedChains[index].bundlerUrl ?? "" }
|
|
26520
|
-
]);
|
|
26495
|
+
const [probed] = await resolveChainConfigs([{ rpcUrls }]);
|
|
26521
26496
|
if (probed.chainId !== chainId) {
|
|
26522
26497
|
throw new Error(`Those endpoints answer for chain ${probed.chainId}, not ${chainId}`);
|
|
26523
26498
|
}
|
|
@@ -26536,20 +26511,6 @@ var ChainController = class {
|
|
|
26536
26511
|
await this.persist();
|
|
26537
26512
|
});
|
|
26538
26513
|
}
|
|
26539
|
-
async setBundlerUrl(chainId, bundlerUrl) {
|
|
26540
|
-
return this.serialise(async () => {
|
|
26541
|
-
if (!bundlerUrl?.trim()) throw new Error("A bundler URL is required");
|
|
26542
|
-
const index = this.runtime.resolvedChains.findIndex((chain) => chain.chainId === chainId);
|
|
26543
|
-
if (index < 0) throw new Error(`Chain ${chainId} is not configured`);
|
|
26544
|
-
await assertBundlersServeEntryPoint([{ chainId, bundlerUrl }], this.runtime.configService, {
|
|
26545
|
-
watchOnly: this.runtime.intentFiller.getWatchOnly()
|
|
26546
|
-
});
|
|
26547
|
-
this.runtime.configService.setBundlerUrl(chainId, bundlerUrl);
|
|
26548
|
-
this.runtime.resolvedChains[index].bundlerUrl = bundlerUrl;
|
|
26549
|
-
this.runtime.config.chains[index].bundlerUrl = bundlerUrl;
|
|
26550
|
-
await this.persist();
|
|
26551
|
-
});
|
|
26552
|
-
}
|
|
26553
26514
|
/** Monitor without filling. Takes effect on the next order. */
|
|
26554
26515
|
async setWatchOnly(chainId, watchOnly) {
|
|
26555
26516
|
return this.serialise(async () => {
|