@hyperbridge/simplex 0.16.13 → 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 +829 -536
- package/dist/bin/simplex.js.map +1 -1
- package/dist/index.cjs +334 -121
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +61 -17
- package/dist/index.d.ts +61 -17
- package/dist/index.js +340 -123
- package/dist/index.js.map +1 -1
- package/dist/sqlite.cjs +8 -1
- package/dist/sqlite.cjs.map +1 -1
- package/dist/sqlite.d.cts +1 -1
- package/dist/sqlite.d.ts +1 -1
- package/dist/sqlite.js +8 -1
- package/dist/sqlite.js.map +1 -1
- package/dist/{types-BISgqJhM.d.cts → types-BPyUX8qu.d.cts} +7 -0
- package/dist/{types-BISgqJhM.d.ts → types-BPyUX8qu.d.ts} +7 -0
- package/dist/ui/assets/{index-DShjZe_c.js → index-BctI82KY.js} +17 -17
- package/dist/ui/index.html +1 -1
- package/package.json +3 -3
package/dist/bin/simplex.js
CHANGED
|
@@ -30656,7 +30656,8 @@ var init_asset_registry = __esm({
|
|
|
30656
30656
|
ZARP: { resolve: (r7, chain2) => r7.getAssetBySymbol(chain2, "ZARP") },
|
|
30657
30657
|
EURC: { resolve: (r7, chain2) => r7.getAssetBySymbol(chain2, "EURC") },
|
|
30658
30658
|
XSGD: { resolve: (r7, chain2) => r7.getAssetBySymbol(chain2, "XSGD") },
|
|
30659
|
-
TRYB: { resolve: (r7, chain2) => r7.getAssetBySymbol(chain2, "TRYB") }
|
|
30659
|
+
TRYB: { resolve: (r7, chain2) => r7.getAssetBySymbol(chain2, "TRYB") },
|
|
30660
|
+
BRIDGE: { resolve: (r7, chain2) => r7.getAssetBySymbol(chain2, "BRIDGE") }
|
|
30660
30661
|
};
|
|
30661
30662
|
USD_STABLE_SYMBOLS = /* @__PURE__ */ new Set(["USDC", "USDT", "DAI"]);
|
|
30662
30663
|
ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
@@ -30755,7 +30756,7 @@ function assertPairSymbolsResolve(pairs, registry, chainNames) {
|
|
|
30755
30756
|
const pairSymbols = new Set(pairs.flatMap((pair) => [pair.token0, pair.token1]));
|
|
30756
30757
|
for (const pair of pairs) {
|
|
30757
30758
|
for (const symbol3 of [pair.token0, pair.token1]) {
|
|
30758
|
-
const resolvesSomewhere = chainNames.some((
|
|
30759
|
+
const resolvesSomewhere = chainNames.some((chainName2) => registry.getAddress(symbol3, chainName2) !== null);
|
|
30759
30760
|
if (!resolvesSomewhere) {
|
|
30760
30761
|
throw new Error(
|
|
30761
30762
|
`pairs.${pair.token0}/${pair.token1}: '${symbol3}' does not resolve to a deployed contract on any configured chain`
|
|
@@ -30763,15 +30764,15 @@ function assertPairSymbolsResolve(pairs, registry, chainNames) {
|
|
|
30763
30764
|
}
|
|
30764
30765
|
}
|
|
30765
30766
|
}
|
|
30766
|
-
for (const
|
|
30767
|
+
for (const chainName2 of chainNames) {
|
|
30767
30768
|
const addressOwner = /* @__PURE__ */ new Map();
|
|
30768
30769
|
for (const symbol3 of pairSymbols) {
|
|
30769
|
-
const address = registry.getAddress(symbol3,
|
|
30770
|
+
const address = registry.getAddress(symbol3, chainName2)?.toLowerCase();
|
|
30770
30771
|
if (!address) continue;
|
|
30771
30772
|
const owner = addressOwner.get(address);
|
|
30772
30773
|
if (owner && normalizeSymbol(owner) !== normalizeSymbol(symbol3)) {
|
|
30773
30774
|
throw new Error(
|
|
30774
|
-
`assets: '${symbol3}' and '${owner}' both resolve to ${address} on ${
|
|
30775
|
+
`assets: '${symbol3}' and '${owner}' both resolve to ${address} on ${chainName2} \u2014 symbols must map to distinct contracts`
|
|
30775
30776
|
);
|
|
30776
30777
|
}
|
|
30777
30778
|
addressOwner.set(address, symbol3);
|
|
@@ -48802,11 +48803,11 @@ var init_esm2 = __esm({
|
|
|
48802
48803
|
init_encodeFunctionData2();
|
|
48803
48804
|
init_encodePacked2();
|
|
48804
48805
|
init_parseEventLogs2();
|
|
48805
|
-
init_isAddress2();
|
|
48806
48806
|
init_defineChain2();
|
|
48807
48807
|
init_concat2();
|
|
48808
48808
|
init_isHex2();
|
|
48809
48809
|
init_pad2();
|
|
48810
|
+
init_slice2();
|
|
48810
48811
|
init_fromBytes2();
|
|
48811
48812
|
init_fromHex2();
|
|
48812
48813
|
init_toBytes2();
|
|
@@ -48814,6 +48815,7 @@ var init_esm2 = __esm({
|
|
|
48814
48815
|
init_keccak2562();
|
|
48815
48816
|
init_toEventSelector2();
|
|
48816
48817
|
init_toFunctionSelector2();
|
|
48818
|
+
init_recoverAddress2();
|
|
48817
48819
|
init_formatUnits2();
|
|
48818
48820
|
init_parseUnits2();
|
|
48819
48821
|
}
|
|
@@ -135098,21 +135100,21 @@ var init_upgrades = __esm({
|
|
|
135098
135100
|
});
|
|
135099
135101
|
|
|
135100
135102
|
// ../../node_modules/.pnpm/@polkadot+types-known@16.5.6/node_modules/@polkadot/types-known/util.js
|
|
135101
|
-
function withNames(
|
|
135102
|
-
return fn(
|
|
135103
|
+
function withNames(chainName2, specName, fn) {
|
|
135104
|
+
return fn(chainName2.toString(), specName.toString());
|
|
135103
135105
|
}
|
|
135104
135106
|
function filterVersions(versions = [], specVersion) {
|
|
135105
135107
|
return versions.filter(({ minmax: [min2, max3] }) => (min2 === void 0 || min2 === null || specVersion >= min2) && (max3 === void 0 || max3 === null || specVersion <= max3)).reduce((result, { types: types4 }) => ({ ...result, ...types4 }), {});
|
|
135106
135108
|
}
|
|
135107
|
-
function getSpecExtensions({ knownTypes: knownTypes2 },
|
|
135108
|
-
return withNames(
|
|
135109
|
+
function getSpecExtensions({ knownTypes: knownTypes2 }, chainName2, specName) {
|
|
135110
|
+
return withNames(chainName2, specName, (c6, s4) => ({
|
|
135109
135111
|
...knownTypes2.typesBundle?.spec?.[s4]?.signedExtensions ?? {},
|
|
135110
135112
|
...knownTypes2.typesBundle?.chain?.[c6]?.signedExtensions ?? {}
|
|
135111
135113
|
}));
|
|
135112
135114
|
}
|
|
135113
|
-
function getSpecTypes({ knownTypes: knownTypes2 },
|
|
135115
|
+
function getSpecTypes({ knownTypes: knownTypes2 }, chainName2, specName, specVersion) {
|
|
135114
135116
|
const _specVersion = bnToBn(specVersion).toNumber();
|
|
135115
|
-
return withNames(
|
|
135117
|
+
return withNames(chainName2, specName, (c6, s4) => ({
|
|
135116
135118
|
// The order here is always, based on -
|
|
135117
135119
|
// - spec then chain
|
|
135118
135120
|
// - typesBundle takes higher precedence
|
|
@@ -135126,23 +135128,23 @@ function getSpecTypes({ knownTypes: knownTypes2 }, chainName, specName, specVers
|
|
|
135126
135128
|
...knownTypes2.types ?? {}
|
|
135127
135129
|
}));
|
|
135128
135130
|
}
|
|
135129
|
-
function getSpecHasher({ knownTypes: knownTypes2 },
|
|
135130
|
-
return withNames(
|
|
135131
|
+
function getSpecHasher({ knownTypes: knownTypes2 }, chainName2, specName) {
|
|
135132
|
+
return withNames(chainName2, specName, (c6, s4) => knownTypes2.hasher || knownTypes2.typesBundle?.chain?.[c6]?.hasher || knownTypes2.typesBundle?.spec?.[s4]?.hasher || null);
|
|
135131
135133
|
}
|
|
135132
|
-
function getSpecRpc({ knownTypes: knownTypes2 },
|
|
135133
|
-
return withNames(
|
|
135134
|
+
function getSpecRpc({ knownTypes: knownTypes2 }, chainName2, specName) {
|
|
135135
|
+
return withNames(chainName2, specName, (c6, s4) => ({
|
|
135134
135136
|
...knownTypes2.typesBundle?.spec?.[s4]?.rpc ?? {},
|
|
135135
135137
|
...knownTypes2.typesBundle?.chain?.[c6]?.rpc ?? {}
|
|
135136
135138
|
}));
|
|
135137
135139
|
}
|
|
135138
|
-
function getSpecRuntime({ knownTypes: knownTypes2 },
|
|
135139
|
-
return withNames(
|
|
135140
|
+
function getSpecRuntime({ knownTypes: knownTypes2 }, chainName2, specName) {
|
|
135141
|
+
return withNames(chainName2, specName, (c6, s4) => ({
|
|
135140
135142
|
...knownTypes2.typesBundle?.spec?.[s4]?.runtime ?? {},
|
|
135141
135143
|
...knownTypes2.typesBundle?.chain?.[c6]?.runtime ?? {}
|
|
135142
135144
|
}));
|
|
135143
135145
|
}
|
|
135144
|
-
function getSpecAlias({ knownTypes: knownTypes2 },
|
|
135145
|
-
return withNames(
|
|
135146
|
+
function getSpecAlias({ knownTypes: knownTypes2 }, chainName2, specName) {
|
|
135147
|
+
return withNames(chainName2, specName, (c6, s4) => ({
|
|
135146
135148
|
// as per versions, first spec, then chain then finally non-versioned
|
|
135147
135149
|
...knownTypes2.typesBundle?.spec?.[s4]?.alias ?? {},
|
|
135148
135150
|
...knownTypes2.typesBundle?.chain?.[c6]?.alias ?? {},
|
|
@@ -156390,7 +156392,7 @@ var require_isTime = __commonJS({
|
|
|
156390
156392
|
hourFormat: "hour24",
|
|
156391
156393
|
mode: "default"
|
|
156392
156394
|
};
|
|
156393
|
-
var
|
|
156395
|
+
var formats2 = {
|
|
156394
156396
|
hour24: {
|
|
156395
156397
|
default: /^([01]?[0-9]|2[0-3]):([0-5][0-9])$/,
|
|
156396
156398
|
withSeconds: /^([01]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/,
|
|
@@ -156405,7 +156407,7 @@ var require_isTime = __commonJS({
|
|
|
156405
156407
|
function isTime(input, options) {
|
|
156406
156408
|
options = (0, _merge.default)(options, default_time_options);
|
|
156407
156409
|
if (typeof input !== "string") return false;
|
|
156408
|
-
return
|
|
156410
|
+
return formats2[options.hourFormat][options.mode].test(input);
|
|
156409
156411
|
}
|
|
156410
156412
|
module2.exports = exports2.default;
|
|
156411
156413
|
module2.exports.default = exports2.default;
|
|
@@ -234901,6 +234903,10 @@ function createSessionKeyStorage(options = {}) {
|
|
|
234901
234903
|
listSessionKeys
|
|
234902
234904
|
});
|
|
234903
234905
|
}
|
|
234906
|
+
async function signTypedDigest(domainSeparator2, structHash, privateKey) {
|
|
234907
|
+
const digest = keccak2563(concat3(["0x1901", domainSeparator2, structHash]));
|
|
234908
|
+
return privateKeyToAccount(privateKey).sign({ hash: digest });
|
|
234909
|
+
}
|
|
234904
234910
|
function encodeERC7821ExecuteBatch(calls) {
|
|
234905
234911
|
const executionData = encodeAbiParameters2(
|
|
234906
234912
|
[{ type: "tuple[]", components: erc7281_default.ABI[1].components }],
|
|
@@ -235162,6 +235168,9 @@ function cancelFromSourceContext(order, commitment) {
|
|
|
235162
235168
|
]
|
|
235163
235169
|
);
|
|
235164
235170
|
}
|
|
235171
|
+
function supportedReleases(stateMachineId) {
|
|
235172
|
+
return TESTNET_CHAINS.has(stateMachineId) ? TESTNET_INTENTS_VERSIONS : [SUPPORTED_INTENTS_VERSION];
|
|
235173
|
+
}
|
|
235165
235174
|
async function readContractVersion(client, address) {
|
|
235166
235175
|
try {
|
|
235167
235176
|
return await client.readContract({ address, abi: CONTRACT_VERSION_ABI, functionName: "version" });
|
|
@@ -235170,14 +235179,17 @@ async function readContractVersion(client, address) {
|
|
|
235170
235179
|
throw error;
|
|
235171
235180
|
}
|
|
235172
235181
|
}
|
|
235173
|
-
async function supportsRateFills(client, gateway) {
|
|
235174
|
-
|
|
235182
|
+
async function supportsRateFills(client, gateway, stateMachineId) {
|
|
235183
|
+
const version17 = await readContractVersion(client, gateway);
|
|
235184
|
+
return supportedReleases(stateMachineId).some((release) => release === version17);
|
|
235175
235185
|
}
|
|
235176
|
-
async function assertGatewayRelease(client, gateway) {
|
|
235186
|
+
async function assertGatewayRelease(client, gateway, stateMachineId) {
|
|
235187
|
+
const supported = supportedReleases(stateMachineId);
|
|
235177
235188
|
const version17 = await readContractVersion(client, gateway);
|
|
235178
|
-
if (
|
|
235189
|
+
if (supported.some((release) => release === version17)) return;
|
|
235190
|
+
const required2 = supported.join(" or ");
|
|
235179
235191
|
throw new Error(
|
|
235180
|
-
version17 === void 0 ? `IntentGateway ${gateway} reports no version(); this SDK requires release ${
|
|
235192
|
+
version17 === void 0 ? `IntentGateway ${gateway} reports no version(); this SDK requires release ${required2}` : `IntentGateway ${gateway} reports release ${String(version17)}; this SDK requires release ${required2}`
|
|
235181
235193
|
);
|
|
235182
235194
|
}
|
|
235183
235195
|
function isCanonicalEvmToken(token) {
|
|
@@ -235219,6 +235231,40 @@ function decodeFillOrder(data4) {
|
|
|
235219
235231
|
return null;
|
|
235220
235232
|
}
|
|
235221
235233
|
}
|
|
235234
|
+
function readSelectionFormat(client, chainId, gateway) {
|
|
235235
|
+
const key = `${chainId}:${gateway.toLowerCase()}`;
|
|
235236
|
+
const cached = formats.get(key);
|
|
235237
|
+
if (cached) return cached;
|
|
235238
|
+
const format2 = client.readContract({ address: gateway, abi: ABI3, functionName: "SELECT_SOLVER_TYPEHASH" }).then((typehash) => {
|
|
235239
|
+
switch (typehash.toLowerCase()) {
|
|
235240
|
+
case SELECT_SOLVER_TYPEHASH:
|
|
235241
|
+
return "userOpHash";
|
|
235242
|
+
case LEGACY_SELECT_SOLVER_TYPEHASH:
|
|
235243
|
+
return "address";
|
|
235244
|
+
default:
|
|
235245
|
+
throw new Error(
|
|
235246
|
+
`IntentGatewayV2 ${gateway} on chain ${chainId} has unknown SELECT_SOLVER_TYPEHASH ${typehash}`
|
|
235247
|
+
);
|
|
235248
|
+
}
|
|
235249
|
+
});
|
|
235250
|
+
formats.set(key, format2);
|
|
235251
|
+
format2.catch(() => {
|
|
235252
|
+
if (formats.get(key) === format2) formats.delete(key);
|
|
235253
|
+
});
|
|
235254
|
+
return format2;
|
|
235255
|
+
}
|
|
235256
|
+
function refreshSelectionFormat(client, chainId, gateway, stale) {
|
|
235257
|
+
const key = `${chainId}:${gateway.toLowerCase()}`;
|
|
235258
|
+
if (formats.get(key) === stale) formats.delete(key);
|
|
235259
|
+
return readSelectionFormat(client, chainId, gateway);
|
|
235260
|
+
}
|
|
235261
|
+
async function selectionOffStateDiff(client, gateway) {
|
|
235262
|
+
const word = await client.getStorageAt({ address: gateway, slot: SELECTION_PARAMS_SLOT });
|
|
235263
|
+
return {
|
|
235264
|
+
slot: SELECTION_PARAMS_SLOT,
|
|
235265
|
+
value: toHex3(hexToBigInt2(word ?? "0x0") & SOLVER_SELECTION_CLEARED, { size: 32 })
|
|
235266
|
+
};
|
|
235267
|
+
}
|
|
235222
235268
|
function userOperationLogs(logs, entryPoint, userOpHash) {
|
|
235223
235269
|
const [beforeExecution, userOperationEvent] = ENTRY_POINT_EVENT_ABI.map((event) => toEventSelector2(event));
|
|
235224
235270
|
const isBoundary = (log4) => log4.address.toLowerCase() === entryPoint.toLowerCase() && (log4.topics[0] === beforeExecution || log4.topics[0] === userOperationEvent);
|
|
@@ -235237,6 +235283,82 @@ function userOperationLogs(logs, entryPoint, userOpHash) {
|
|
|
235237
235283
|
while (start >= 0 && !isBoundary(logs[start])) start--;
|
|
235238
235284
|
return logs.slice(start + 1, end);
|
|
235239
235285
|
}
|
|
235286
|
+
async function rundlerRequest(bundlerUrl, method, unsupported) {
|
|
235287
|
+
if (unsupported.has(bundlerUrl)) return null;
|
|
235288
|
+
try {
|
|
235289
|
+
const response = await fetch(bundlerUrl, {
|
|
235290
|
+
method: "POST",
|
|
235291
|
+
headers: { "Content-Type": "application/json" },
|
|
235292
|
+
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params: [] })
|
|
235293
|
+
});
|
|
235294
|
+
const { result, error } = await response.json();
|
|
235295
|
+
if (error) {
|
|
235296
|
+
if (error.code !== void 0 && UNSUPPORTED_REQUEST_CODES.has(error.code)) {
|
|
235297
|
+
unsupported.add(bundlerUrl);
|
|
235298
|
+
}
|
|
235299
|
+
return null;
|
|
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 {
|
|
235313
|
+
return result == null ? null : BigInt(result);
|
|
235314
|
+
} catch {
|
|
235315
|
+
return null;
|
|
235316
|
+
}
|
|
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
|
+
}
|
|
235353
|
+
function applyRundlerPriorityFee(fees4, params) {
|
|
235354
|
+
const { rundlerPriorityFee, baseFeePerGas, priorityFeeBumpPercent, maxFeeBumpPercent } = params;
|
|
235355
|
+
const priorityFloor = rundlerPriorityFee + rundlerPriorityFee * priorityFeeBumpPercent / 100n;
|
|
235356
|
+
const maxFeeFloor = baseFeePerGas + baseFeePerGas * maxFeeBumpPercent / 100n + priorityFloor;
|
|
235357
|
+
return {
|
|
235358
|
+
maxPriorityFeePerGas: fees4.maxPriorityFeePerGas > priorityFloor ? fees4.maxPriorityFeePerGas : priorityFloor,
|
|
235359
|
+
maxFeePerGas: fees4.maxFeePerGas > maxFeeFloor ? fees4.maxFeePerGas : maxFeeFloor
|
|
235360
|
+
};
|
|
235361
|
+
}
|
|
235240
235362
|
function escrowSlot(commitment, leg) {
|
|
235241
235363
|
const byCommitment = keccak2563(
|
|
235242
235364
|
encodeAbiParameters2([{ type: "bytes32" }, { type: "uint256" }], [commitment, ESCROW_MAPPING_SLOT])
|
|
@@ -235422,7 +235544,7 @@ function encodePhantomBidDeclaration(declaration) {
|
|
|
235422
235544
|
}
|
|
235423
235545
|
return u8aToHex(new Uint8Array(bytes5));
|
|
235424
235546
|
}
|
|
235425
|
-
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, 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, 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, CONTRACT_VERSION_ABI, CANONICAL_EVM_TOKEN, ENTRY_POINT_EVENT_ABI, BidImpl, BidManager, 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, 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;
|
|
235426
235548
|
var init_node10 = __esm({
|
|
235427
235549
|
"../sdk/dist/node/index.js"() {
|
|
235428
235550
|
"use strict";
|
|
@@ -237775,6 +237897,9 @@ var init_node10 = __esm({
|
|
|
237775
237897
|
default: { name: "Nile Tronscan", url: "https://nile.tronscan.org" }
|
|
237776
237898
|
}
|
|
237777
237899
|
});
|
|
237900
|
+
ENTRY_POINT_V08 = "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108";
|
|
237901
|
+
ENTRY_POINT_V09 = "0x433709009B8330FDa32311DF1C2AFA402eD8D009";
|
|
237902
|
+
KNOWN_ENTRY_POINTS = [ENTRY_POINT_V09, ENTRY_POINT_V08];
|
|
237778
237903
|
chainConfigs = {
|
|
237779
237904
|
97: {
|
|
237780
237905
|
chainId: 97,
|
|
@@ -237807,11 +237932,14 @@ var init_node10 = __esm({
|
|
|
237807
237932
|
UniversalRouter: "0xcc6d5ece3d4a57245bf5a2f64f3ed9179b81f714",
|
|
237808
237933
|
UniswapV3Quoter: "0x0000000000000000000000000000000000000000",
|
|
237809
237934
|
UniswapV4Quoter: "0x0000000000000000000000000000000000000000",
|
|
237810
|
-
|
|
237811
|
-
|
|
237935
|
+
Permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
|
|
237936
|
+
EntryPoint: "0x433709009B8330FDa32311DF1C2AFA402eD8D009",
|
|
237937
|
+
SolverAccount: "0x7484C6Ff790b898bf7e6960Ffc82f63330445Dc2",
|
|
237938
|
+
SimplexPaymaster: "0x9f4a6F1254f27373C2aca5bDd0e48FbA45EA3aeC"
|
|
237812
237939
|
},
|
|
237813
237940
|
rpcEnvKey: "BSC_CHAPEL",
|
|
237814
237941
|
defaultRpcUrl: "https://bnb-testnet.api.onfinality.io/public",
|
|
237942
|
+
bundlerUrl: "https://bundler.polytope.technology/bsc-chapel",
|
|
237815
237943
|
consensusStateId: "BSC0",
|
|
237816
237944
|
coingeckoId: "binance-smart-chain",
|
|
237817
237945
|
popularTokens: [
|
|
@@ -237843,7 +237971,7 @@ var init_node10 = __esm({
|
|
|
237843
237971
|
UniswapRouter02: "0x0000000000000000000000000000000000000000",
|
|
237844
237972
|
UniswapV2Factory: "0x0000000000000000000000000000000000000000",
|
|
237845
237973
|
UniswapV3Factory: "0x0000000000000000000000000000000000000000",
|
|
237846
|
-
|
|
237974
|
+
EntryPoint: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
|
|
237847
237975
|
},
|
|
237848
237976
|
rpcEnvKey: "GNOSIS_CHIADO",
|
|
237849
237977
|
defaultRpcUrl: "https://gnosis-chiado-rpc.publicnode.com",
|
|
@@ -237883,7 +238011,7 @@ var init_node10 = __esm({
|
|
|
237883
238011
|
UniswapV2Factory: "0x0000000000000000000000000000000000000000",
|
|
237884
238012
|
UniswapV3Factory: "0x0000000000000000000000000000000000000000",
|
|
237885
238013
|
Calldispatcher: "0xC7f13b6D03A0A7F3239d38897503E90553ABe155",
|
|
237886
|
-
|
|
238014
|
+
EntryPoint: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
|
|
237887
238015
|
},
|
|
237888
238016
|
rpcEnvKey: "SEPOLIA",
|
|
237889
238017
|
defaultRpcUrl: "https://1rpc.io/sepolia",
|
|
@@ -237934,7 +238062,7 @@ var init_node10 = __esm({
|
|
|
237934
238062
|
},
|
|
237935
238063
|
addresses: {
|
|
237936
238064
|
IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
|
|
237937
|
-
SolverAccount: "
|
|
238065
|
+
SolverAccount: "0xaAd062555800a97Af062795189e32a3CBd045612",
|
|
237938
238066
|
TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
|
|
237939
238067
|
Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
|
|
237940
238068
|
UniswapRouter02: "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D",
|
|
@@ -237948,13 +238076,14 @@ var init_node10 = __esm({
|
|
|
237948
238076
|
UniswapV4StateView: "0x7ffe42c4a5deea5b0fec41c94c136cf115597227",
|
|
237949
238077
|
Calldispatcher: "0xc71251c8b3e7b02697a84363eef6dce8dfbdf333",
|
|
237950
238078
|
Permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
|
|
237951
|
-
|
|
238079
|
+
EntryPoint: "0x433709009B8330FDa32311DF1C2AFA402eD8D009",
|
|
237952
238080
|
CirclePaymaster: "0x0578cFB241215b77442a541325d6A4E6dFE700Ec",
|
|
237953
238081
|
SimplexPaymaster: "0xD4340d7466e040626383cb9cda9307ba8E081149",
|
|
237954
238082
|
Usdt0Oft: "0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee"
|
|
237955
238083
|
},
|
|
237956
238084
|
rpcEnvKey: "ETH_MAINNET",
|
|
237957
238085
|
defaultRpcUrl: "https://eth-mainnet.g.alchemy.com/v2/demo",
|
|
238086
|
+
bundlerUrl: "https://bundler.polytope.technology/ethereum",
|
|
237958
238087
|
consensusStateId: "ETH0",
|
|
237959
238088
|
coingeckoId: "ethereum",
|
|
237960
238089
|
layerZeroEid: 30101,
|
|
@@ -237980,7 +238109,8 @@ var init_node10 = __esm({
|
|
|
237980
238109
|
USDC: "0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d",
|
|
237981
238110
|
USDT: "0x55d398326f99059ff775485246999027b3197955",
|
|
237982
238111
|
EXT: "0x7C8c11ADb8EF7cd3CFa718008Ea048445C6E7209",
|
|
237983
|
-
cNGN: "0xa8AEA66B361a8d53e8865c62D142167Af28Af058"
|
|
238112
|
+
cNGN: "0xa8AEA66B361a8d53e8865c62D142167Af28Af058",
|
|
238113
|
+
BRIDGE: "0x5b0c50fDd52ECC0d4c682c441eaBaD41FfDEABBB"
|
|
237984
238114
|
},
|
|
237985
238115
|
tokenDecimals: {
|
|
237986
238116
|
USDC: 18,
|
|
@@ -237989,19 +238119,21 @@ var init_node10 = __esm({
|
|
|
237989
238119
|
// Binance-pegged stables above. Every phantom standard_amount and pool rate divides
|
|
237990
238120
|
// by this, so the divergence from its neighbours here is load-bearing, not a typo.
|
|
237991
238121
|
cNGN: 6,
|
|
237992
|
-
EXT: 18
|
|
238122
|
+
EXT: 18,
|
|
238123
|
+
BRIDGE: 18
|
|
237993
238124
|
},
|
|
237994
238125
|
tokenStorageSlots: {
|
|
237995
238126
|
USDT: { balanceSlot: 1, allowanceSlot: 2 },
|
|
237996
238127
|
USDC: { balanceSlot: 1, allowanceSlot: 2 },
|
|
237997
238128
|
WETH: { balanceSlot: 3, allowanceSlot: 4 },
|
|
237998
238129
|
DAI: { balanceSlot: 0, allowanceSlot: 0 },
|
|
237999
|
-
cNGN: { balanceSlot: 201, allowanceSlot: 202 }
|
|
238130
|
+
cNGN: { balanceSlot: 201, allowanceSlot: 202 },
|
|
238000
238131
|
// custom upgradeable layout, as on Base
|
|
238132
|
+
BRIDGE: { balanceSlot: 0, allowanceSlot: 1 }
|
|
238001
238133
|
},
|
|
238002
238134
|
addresses: {
|
|
238003
238135
|
IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
|
|
238004
|
-
SolverAccount: "
|
|
238136
|
+
SolverAccount: "0xaAd062555800a97Af062795189e32a3CBd045612",
|
|
238005
238137
|
TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
|
|
238006
238138
|
Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
|
|
238007
238139
|
UniswapRouter02: "0x10ED43C718714eb63d5aA57B78B54704E256024E",
|
|
@@ -238015,12 +238147,13 @@ var init_node10 = __esm({
|
|
|
238015
238147
|
UniswapV4StateView: "0xd13dd3d6e93f276fafc9db9e6bb47c1180aee0c4",
|
|
238016
238148
|
Calldispatcher: "0xc71251c8b3e7b02697a84363eef6dce8dfbdf333",
|
|
238017
238149
|
Permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
|
|
238018
|
-
|
|
238150
|
+
EntryPoint: "0x433709009B8330FDa32311DF1C2AFA402eD8D009",
|
|
238019
238151
|
SimplexPaymaster: "0xeD02f9f0df8F562B89cC5b25867Ad3C2d61252A9"
|
|
238020
238152
|
// "Usdt0Oft": Not available on BSC
|
|
238021
238153
|
},
|
|
238022
238154
|
rpcEnvKey: "BSC_MAINNET",
|
|
238023
238155
|
defaultRpcUrl: "https://bsc-rpc.publicnode.com",
|
|
238156
|
+
bundlerUrl: "https://bundler.polytope.technology/bsc",
|
|
238024
238157
|
consensusStateId: "BSC0",
|
|
238025
238158
|
coingeckoId: "binance-smart-chain",
|
|
238026
238159
|
erc4626Vaults: [
|
|
@@ -238062,7 +238195,7 @@ var init_node10 = __esm({
|
|
|
238062
238195
|
},
|
|
238063
238196
|
addresses: {
|
|
238064
238197
|
IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
|
|
238065
|
-
SolverAccount: "
|
|
238198
|
+
SolverAccount: "0xaAd062555800a97Af062795189e32a3CBd045612",
|
|
238066
238199
|
TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
|
|
238067
238200
|
Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
|
|
238068
238201
|
UniswapRouter02: "0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24",
|
|
@@ -238076,13 +238209,14 @@ var init_node10 = __esm({
|
|
|
238076
238209
|
UniswapV4StateView: "0x76fd297e2d437cd7f76d50f01afe6160f86e9990",
|
|
238077
238210
|
Calldispatcher: "0xc71251c8b3e7b02697a84363eef6dce8dfbdf333",
|
|
238078
238211
|
Permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
|
|
238079
|
-
|
|
238212
|
+
EntryPoint: "0x433709009B8330FDa32311DF1C2AFA402eD8D009",
|
|
238080
238213
|
CirclePaymaster: "0x0578cFB241215b77442a541325d6A4E6dFE700Ec",
|
|
238081
238214
|
SimplexPaymaster: "0x7281Bccb4f0BCE44F3B8542d1fC5e51c2F5fC08C",
|
|
238082
238215
|
Usdt0Oft: "0x14E4A1B13bf7F943c8ff7C51fb60FA964A298D92"
|
|
238083
238216
|
},
|
|
238084
238217
|
rpcEnvKey: "ARBITRUM_MAINNET",
|
|
238085
238218
|
defaultRpcUrl: "https://arbitrum-one.public.blastapi.io",
|
|
238219
|
+
bundlerUrl: "https://bundler.polytope.technology/arbitrum",
|
|
238086
238220
|
consensusStateId: "ETH0",
|
|
238087
238221
|
coingeckoId: "arbitrum-one",
|
|
238088
238222
|
layerZeroEid: 30110,
|
|
@@ -238136,7 +238270,7 @@ var init_node10 = __esm({
|
|
|
238136
238270
|
},
|
|
238137
238271
|
addresses: {
|
|
238138
238272
|
IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
|
|
238139
|
-
SolverAccount: "
|
|
238273
|
+
SolverAccount: "0xaAd062555800a97Af062795189e32a3CBd045612",
|
|
238140
238274
|
TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
|
|
238141
238275
|
Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
|
|
238142
238276
|
UniswapRouter02: "0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24",
|
|
@@ -238147,7 +238281,7 @@ var init_node10 = __esm({
|
|
|
238147
238281
|
UniswapV4Quoter: "0x0d5e0f971ed27fbff6c2837bf31316121532048d",
|
|
238148
238282
|
Calldispatcher: "0xc71251c8b3e7b02697a84363eef6dce8dfbdf333",
|
|
238149
238283
|
Permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
|
|
238150
|
-
|
|
238284
|
+
EntryPoint: "0x433709009B8330FDa32311DF1C2AFA402eD8D009",
|
|
238151
238285
|
CirclePaymaster: "0x0578cFB241215b77442a541325d6A4E6dFE700Ec",
|
|
238152
238286
|
SimplexPaymaster: "0x15b3B03C870c7ef252029c35A12d3b339F5c8d7f",
|
|
238153
238287
|
AerodromeRouter: "0xcF77a3Ba9A5CA399B7c97c74d54e5b1Beb874E43",
|
|
@@ -238158,6 +238292,7 @@ var init_node10 = __esm({
|
|
|
238158
238292
|
},
|
|
238159
238293
|
rpcEnvKey: "BASE_MAINNET",
|
|
238160
238294
|
defaultRpcUrl: "https://base-mainnet.public.blastapi.io",
|
|
238295
|
+
bundlerUrl: "https://bundler.polytope.technology/base",
|
|
238161
238296
|
consensusStateId: "ETH0",
|
|
238162
238297
|
coingeckoId: "base",
|
|
238163
238298
|
layerZeroEid: 30184,
|
|
@@ -238186,7 +238321,8 @@ var init_node10 = __esm({
|
|
|
238186
238321
|
cNGN: "0x52828daa48C1a9A06F37500882b42daf0bE04C3B",
|
|
238187
238322
|
ZARP: "0xb755506531786C8aC63B756BaB1ac387bACB0C04",
|
|
238188
238323
|
XSGD: "0xDC3326e71D45186F113a2F448984CA0e8D201995",
|
|
238189
|
-
USDR: "0x3B5F2810fB2168FfA9C73160F97BF9f2461fFa5c"
|
|
238324
|
+
USDR: "0x3B5F2810fB2168FfA9C73160F97BF9f2461fFa5c",
|
|
238325
|
+
BRIDGE: "0x5b0c50fDd52ECC0d4c682c441eaBaD41FfDEABBB"
|
|
238190
238326
|
},
|
|
238191
238327
|
tokenDecimals: {
|
|
238192
238328
|
USDC: 6,
|
|
@@ -238195,7 +238331,8 @@ var init_node10 = __esm({
|
|
|
238195
238331
|
cNGN: 6,
|
|
238196
238332
|
ZARP: 18,
|
|
238197
238333
|
XSGD: 6,
|
|
238198
|
-
USDR: 6
|
|
238334
|
+
USDR: 6,
|
|
238335
|
+
BRIDGE: 18
|
|
238199
238336
|
},
|
|
238200
238337
|
tokenStorageSlots: {
|
|
238201
238338
|
USDT: { balanceSlot: 0, allowanceSlot: 1 },
|
|
@@ -238206,11 +238343,12 @@ var init_node10 = __esm({
|
|
|
238206
238343
|
// custom upgradeable layout
|
|
238207
238344
|
ZARP: { balanceSlot: 51, allowanceSlot: 52 },
|
|
238208
238345
|
XSGD: { balanceSlot: 7, allowanceSlot: 8 },
|
|
238209
|
-
USDR: { balanceSlot: 51, allowanceSlot: 52 }
|
|
238346
|
+
USDR: { balanceSlot: 51, allowanceSlot: 52 },
|
|
238347
|
+
BRIDGE: { balanceSlot: 0, allowanceSlot: 1 }
|
|
238210
238348
|
},
|
|
238211
238349
|
addresses: {
|
|
238212
238350
|
IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
|
|
238213
|
-
SolverAccount: "
|
|
238351
|
+
SolverAccount: "0xaAd062555800a97Af062795189e32a3CBd045612",
|
|
238214
238352
|
TokenGateway: "0x8b536105b6Fae2aE9199f5146D3C57Dfe53b614E",
|
|
238215
238353
|
Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
|
|
238216
238354
|
UniswapRouter02: "0xd2f9496824951D5237cC71245D659E48d0d5f9E8",
|
|
@@ -238224,13 +238362,14 @@ var init_node10 = __esm({
|
|
|
238224
238362
|
UniswapV4StateView: "0x5ea1bd7974c8a611cbab0bdcafcb1d9cc9b3ba5a",
|
|
238225
238363
|
Calldispatcher: "0xc71251c8b3e7b02697a84363eef6dce8dfbdf333",
|
|
238226
238364
|
Permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
|
|
238227
|
-
|
|
238365
|
+
EntryPoint: "0x433709009B8330FDa32311DF1C2AFA402eD8D009",
|
|
238228
238366
|
CirclePaymaster: "0x0578cFB241215b77442a541325d6A4E6dFE700Ec",
|
|
238229
238367
|
SimplexPaymaster: "0xe99acFe0f5fC4C8ea54A187D8D3b05f136150095",
|
|
238230
238368
|
Usdt0Oft: "0x6BA10300f0DC58B7a1e4c0e41f5daBb7D7829e13"
|
|
238231
238369
|
},
|
|
238232
238370
|
rpcEnvKey: "POLYGON_MAINNET",
|
|
238233
238371
|
defaultRpcUrl: "https://polygon-bor-rpc.publicnode.com",
|
|
238372
|
+
bundlerUrl: "https://bundler.polytope.technology/polygon",
|
|
238234
238373
|
consensusStateId: "POLY",
|
|
238235
238374
|
coingeckoId: "polygon-pos",
|
|
238236
238375
|
layerZeroEid: 30109,
|
|
@@ -238303,11 +238442,13 @@ var init_node10 = __esm({
|
|
|
238303
238442
|
Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
|
|
238304
238443
|
Calldispatcher: "0x876F1891982E260026630c233A4897160A281Fb8",
|
|
238305
238444
|
Permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
|
|
238306
|
-
|
|
238307
|
-
SolverAccount: "
|
|
238445
|
+
EntryPoint: "0x433709009B8330FDa32311DF1C2AFA402eD8D009",
|
|
238446
|
+
SolverAccount: "0x7484C6Ff790b898bf7e6960Ffc82f63330445Dc2",
|
|
238447
|
+
SimplexPaymaster: "0x6085a14078B7d26259145a894140f7C8361e02ae"
|
|
238308
238448
|
},
|
|
238309
238449
|
rpcEnvKey: "POLYGON_AMOY",
|
|
238310
238450
|
defaultRpcUrl: "https://rpc-amoy.polygon.technology",
|
|
238451
|
+
bundlerUrl: "https://bundler.polytope.technology/polygon-amoy",
|
|
238311
238452
|
consensusStateId: "POLY",
|
|
238312
238453
|
coingeckoId: "polygon-pos"
|
|
238313
238454
|
},
|
|
@@ -238336,7 +238477,7 @@ var init_node10 = __esm({
|
|
|
238336
238477
|
UniswapV3Factory: "0x1F98431c8aD98523631AE4a59f267346ea31F984",
|
|
238337
238478
|
Calldispatcher: "0xC71251c8b3e7B02697A84363Eef6DcE8DfBdF333",
|
|
238338
238479
|
Permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
|
|
238339
|
-
|
|
238480
|
+
EntryPoint: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
|
|
238340
238481
|
CirclePaymaster: "0x0578cFB241215b77442a541325d6A4E6dFE700Ec",
|
|
238341
238482
|
UniswapV4PositionManager: "0x3c3ea4b57a46241e54610e5f022e5c45859a1017",
|
|
238342
238483
|
UniswapV4PoolManager: "0x9a13f98cb987694c9f086b1f5eb990eea8264ec3"
|
|
@@ -238370,7 +238511,7 @@ var init_node10 = __esm({
|
|
|
238370
238511
|
// Mocked
|
|
238371
238512
|
UniswapV2Factory: "0x0000000000000000000000000000000000000000",
|
|
238372
238513
|
Calldispatcher: "0xC71251c8b3e7B02697A84363Eef6DcE8DfBdF333",
|
|
238373
|
-
|
|
238514
|
+
EntryPoint: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
|
|
238374
238515
|
},
|
|
238375
238516
|
defaultRpcUrl: "https://rpc.gnosischain.com",
|
|
238376
238517
|
consensusStateId: "GNO0",
|
|
@@ -238395,7 +238536,7 @@ var init_node10 = __esm({
|
|
|
238395
238536
|
addresses: {
|
|
238396
238537
|
TokenGateway: "0xCe304770236f39F9911BfCC51afBdfF3b8635718",
|
|
238397
238538
|
Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
|
|
238398
|
-
|
|
238539
|
+
EntryPoint: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
|
|
238399
238540
|
UniswapV4PositionManager: "0x1b35d13a2e2528f192637f14b05f0dc0e7deb566",
|
|
238400
238541
|
UniswapV4PoolManager: "0x360e68faccca8ca495c1b759fd9eee466db9fb32"
|
|
238401
238542
|
},
|
|
@@ -238421,7 +238562,7 @@ var init_node10 = __esm({
|
|
|
238421
238562
|
addresses: {
|
|
238422
238563
|
TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
|
|
238423
238564
|
Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
|
|
238424
|
-
|
|
238565
|
+
EntryPoint: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
|
|
238425
238566
|
},
|
|
238426
238567
|
defaultRpcUrl: "https://sepolia-rollup.arbitrum.io/rpc",
|
|
238427
238568
|
consensusStateId: "ETH0",
|
|
@@ -238445,7 +238586,7 @@ var init_node10 = __esm({
|
|
|
238445
238586
|
addresses: {
|
|
238446
238587
|
TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
|
|
238447
238588
|
Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
|
|
238448
|
-
|
|
238589
|
+
EntryPoint: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
|
|
238449
238590
|
},
|
|
238450
238591
|
defaultRpcUrl: "https://sepolia.optimism.io",
|
|
238451
238592
|
consensusStateId: "ETH0",
|
|
@@ -238469,7 +238610,7 @@ var init_node10 = __esm({
|
|
|
238469
238610
|
addresses: {
|
|
238470
238611
|
TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
|
|
238471
238612
|
Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
|
|
238472
|
-
|
|
238613
|
+
EntryPoint: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
|
|
238473
238614
|
},
|
|
238474
238615
|
defaultRpcUrl: "https://sepolia.base.org",
|
|
238475
238616
|
consensusStateId: "ETH0",
|
|
@@ -238495,7 +238636,7 @@ var init_node10 = __esm({
|
|
|
238495
238636
|
IntentGateway: "0x606ba811aa6cb424ce2108e8977c5284686f0d1f",
|
|
238496
238637
|
TokenGateway: "0x1c1e5be83df4a54c7a2230c337e4a3e8b7354b1c",
|
|
238497
238638
|
Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
|
|
238498
|
-
|
|
238639
|
+
EntryPoint: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
|
|
238499
238640
|
},
|
|
238500
238641
|
defaultRpcUrl: "https://testnet-asset-hub-eth-rpc.polkadot.io",
|
|
238501
238642
|
consensusStateId: "PAS0",
|
|
@@ -238519,7 +238660,7 @@ var init_node10 = __esm({
|
|
|
238519
238660
|
},
|
|
238520
238661
|
addresses: {
|
|
238521
238662
|
IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
|
|
238522
|
-
SolverAccount: "
|
|
238663
|
+
SolverAccount: "0xaAd062555800a97Af062795189e32a3CBd045612",
|
|
238523
238664
|
Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
|
|
238524
238665
|
Calldispatcher: "0xE2C7e576E26E0bE7aC97c6fE925bcDAbD87c4bEd"
|
|
238525
238666
|
},
|
|
@@ -239924,9 +240065,9 @@ var init_node10 = __esm({
|
|
|
239924
240065
|
internalType: "bytes32"
|
|
239925
240066
|
},
|
|
239926
240067
|
{
|
|
239927
|
-
name: "
|
|
239928
|
-
type: "
|
|
239929
|
-
internalType: "
|
|
240068
|
+
name: "userOpHash",
|
|
240069
|
+
type: "bytes32",
|
|
240070
|
+
internalType: "bytes32"
|
|
239930
240071
|
},
|
|
239931
240072
|
{
|
|
239932
240073
|
name: "signature",
|
|
@@ -240972,8 +241113,8 @@ var init_node10 = __esm({
|
|
|
240972
241113
|
getPopularTokens(chain2) {
|
|
240973
241114
|
return this.getConfig(chain2)?.popularTokens ?? [];
|
|
240974
241115
|
}
|
|
240975
|
-
|
|
240976
|
-
return this.getConfig(chain2)?.addresses.
|
|
241116
|
+
getEntryPointAddress(chain2) {
|
|
241117
|
+
return this.getConfig(chain2)?.addresses.EntryPoint;
|
|
240977
241118
|
}
|
|
240978
241119
|
getCirclePaymasterAddress(chain2) {
|
|
240979
241120
|
return this.getConfig(chain2)?.addresses.CirclePaymaster;
|
|
@@ -242053,7 +242194,7 @@ var init_node10 = __esm({
|
|
|
242053
242194
|
* This is the only public way to construct an `EvmChain` — the constructor is private.
|
|
242054
242195
|
*
|
|
242055
242196
|
* @param rpcUrl - HTTP(S) RPC URL of the EVM node
|
|
242056
|
-
* @param bundlerUrl - Optional ERC-4337 bundler URL for
|
|
242197
|
+
* @param bundlerUrl - Optional ERC-4337 bundler URL; defaults to Hyperbridge's bundler for the chain
|
|
242057
242198
|
* @returns A fully initialised `EvmChain` ready for use
|
|
242058
242199
|
* @throws If the chain ID returned by the RPC is not a known Hyperbridge deployment
|
|
242059
242200
|
*
|
|
@@ -242079,8 +242220,12 @@ var init_node10 = __esm({
|
|
|
242079
242220
|
get host() {
|
|
242080
242221
|
return this.params.host;
|
|
242081
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
|
+
*/
|
|
242082
242227
|
get bundlerUrl() {
|
|
242083
|
-
return this.params.bundlerUrl;
|
|
242228
|
+
return this.params.bundlerUrl ?? chainConfigs[this.params.chainId]?.bundlerUrl;
|
|
242084
242229
|
}
|
|
242085
242230
|
get config() {
|
|
242086
242231
|
return {
|
|
@@ -243235,6 +243380,9 @@ Failed HTTP Request: ${JSON.stringify(
|
|
|
243235
243380
|
* fails on-chain, and a second `retractBid` that pulls the bid just placed. When the signed nonce
|
|
243236
243381
|
* cannot be read, the stalled result is returned rather than guessed at.
|
|
243237
243382
|
*
|
|
243383
|
+
* A stall in `Future` first fills the missing nonce below it ({@link fillNonceGap}), so the
|
|
243384
|
+
* replacement can land.
|
|
243385
|
+
*
|
|
243238
243386
|
* A rejection that bounced off a copy already pooled (1013/1014) is likewise left alone: that
|
|
243239
243387
|
* copy is in flight and its outcome is unknown here, so the `pending` result goes back to the
|
|
243240
243388
|
* caller to confirm later.
|
|
@@ -243259,6 +243407,7 @@ Failed HTTP Request: ${JSON.stringify(
|
|
|
243259
243407
|
stalled = result;
|
|
243260
243408
|
nonce ?? (nonce = this.signedNonce(extrinsic));
|
|
243261
243409
|
if (nonce === void 0) return result;
|
|
243410
|
+
if (result.future) await this.fillNonceGap(keyPair, nonce, timeoutMs);
|
|
243262
243411
|
continue;
|
|
243263
243412
|
}
|
|
243264
243413
|
if (result.pending) return stalled ?? result;
|
|
@@ -243298,19 +243447,6 @@ Failed HTTP Request: ${JSON.stringify(
|
|
|
243298
243447
|
const inFlight = code === 1013 || code === 1014 || /already imported|already in the pool|priority is too low/i.test(err.message);
|
|
243299
243448
|
return { success: false, pending: inFlight || void 0, error: err.message };
|
|
243300
243449
|
}
|
|
243301
|
-
/**
|
|
243302
|
-
* Sends an extrinsic with a timeout.
|
|
243303
|
-
*
|
|
243304
|
-
* A timeout is only a failure when the extrinsic never made it into the transaction pool.
|
|
243305
|
-
* Once a pool-entry status (Future/Ready/Broadcast/Retracted) has been seen, the extrinsic is
|
|
243306
|
-
* in flight and may well execute after the watch is abandoned — the result is then `pending`
|
|
243307
|
-
* and `stalled`, telling the caller to replace it under the same nonce or confirm it later,
|
|
243308
|
-
* never to re-sign the same call under a fresh one.
|
|
243309
|
-
*
|
|
243310
|
-
* `nonce` pins the submission to a specific account nonce, which is what makes a retry a pool
|
|
243311
|
-
* replacement rather than a second extrinsic queued behind the first. Left undefined on the
|
|
243312
|
-
* first attempt, where the api's auto-nonce is correct.
|
|
243313
|
-
*/
|
|
243314
243450
|
/**
|
|
243315
243451
|
* The nonce the next submission signs with, or undefined when the node cannot be asked.
|
|
243316
243452
|
*
|
|
@@ -243327,6 +243463,7 @@ Failed HTTP Request: ${JSON.stringify(
|
|
|
243327
243463
|
* queued as future, or simply not counted yet — is covered by `lastPooledNonce` instead, which
|
|
243328
243464
|
* is the highest nonce this instance has put into the pool. The two are combined rather than
|
|
243329
243465
|
* trusted separately, so a burst never reuses a nonce and a restart still picks up the chain's.
|
|
243466
|
+
* A nonce left missing by an extrinsic the node dropped is filled by {@link fillNonceGap}.
|
|
243330
243467
|
*/
|
|
243331
243468
|
async nextNonce(api) {
|
|
243332
243469
|
try {
|
|
@@ -243340,11 +243477,53 @@ Failed HTTP Request: ${JSON.stringify(
|
|
|
243340
243477
|
return void 0;
|
|
243341
243478
|
}
|
|
243342
243479
|
}
|
|
243480
|
+
/**
|
|
243481
|
+
* A stall in `Future` means the node is missing a lower nonce of this account's, one whose
|
|
243482
|
+
* extrinsic it dropped, and everything signed above that nonce waits behind it. This fills the
|
|
243483
|
+
* lowest missing nonce, which `system_accountNextIndex` reports on the same node, with a
|
|
243484
|
+
* `system.remark` rather than the next call, so the calls already pooled above it land in the
|
|
243485
|
+
* order they were signed. One nonce per stall; a further gap shows up as the next `Future` stall.
|
|
243486
|
+
*
|
|
243487
|
+
* The remark carries no tip, so on any node or pool view that still holds a live call of ours at
|
|
243488
|
+
* that nonce, the call outranks it and the remark only ever fills a real gap.
|
|
243489
|
+
*
|
|
243490
|
+
* It runs inside the submission queue, so it submits directly rather than enqueueing, and gives
|
|
243491
|
+
* up after `timeoutMs` so a silent socket cannot hold the queue. A failure or timeout is logged
|
|
243492
|
+
* and left to the next stall.
|
|
243493
|
+
*/
|
|
243494
|
+
async fillNonceGap(keyPair, nonce, timeoutMs) {
|
|
243495
|
+
const fill = async () => {
|
|
243496
|
+
const accountNextIndex = this.api.rpc?.system?.accountNextIndex;
|
|
243497
|
+
if (!accountNextIndex) return;
|
|
243498
|
+
const missing = Number((await accountNextIndex(keyPair.address)).toString());
|
|
243499
|
+
if (!Number.isFinite(missing) || missing >= nonce) return;
|
|
243500
|
+
await this.api.tx.system.remark("0x").signAndSend(keyPair, { tip: 0n, nonce: missing });
|
|
243501
|
+
};
|
|
243502
|
+
try {
|
|
243503
|
+
await Promise.race([fill(), rejectAfter(timeoutMs, `Timed out after ${timeoutMs}ms`)]);
|
|
243504
|
+
} catch (err) {
|
|
243505
|
+
console.warn(`Could not fill the nonce gap below ${nonce}:`, err);
|
|
243506
|
+
}
|
|
243507
|
+
}
|
|
243508
|
+
/**
|
|
243509
|
+
* Sends an extrinsic with a timeout.
|
|
243510
|
+
*
|
|
243511
|
+
* A timeout is only a failure when the extrinsic never made it into the transaction pool.
|
|
243512
|
+
* Once a pool-entry status (Future/Ready/Broadcast/Retracted) has been seen, the extrinsic is
|
|
243513
|
+
* in flight and may well execute after the watch is abandoned — the result is then `pending`
|
|
243514
|
+
* and `stalled`, telling the caller to replace it under the same nonce or confirm it later,
|
|
243515
|
+
* never to re-sign the same call under a fresh one.
|
|
243516
|
+
*
|
|
243517
|
+
* `nonce` pins the submission to a specific account nonce, which is what makes a retry a pool
|
|
243518
|
+
* replacement rather than a second extrinsic queued behind the first. Left undefined on the
|
|
243519
|
+
* first attempt, where the api's auto-nonce is correct.
|
|
243520
|
+
*/
|
|
243343
243521
|
async sendWithTimeout(extrinsic, keyPair, tip, timeoutMs, nonce) {
|
|
243344
243522
|
return new Promise((resolve12) => {
|
|
243345
243523
|
let resolved = false;
|
|
243346
243524
|
let unsubscribe = null;
|
|
243347
243525
|
let enteredPool = false;
|
|
243526
|
+
let inFuture = false;
|
|
243348
243527
|
const timeoutId = setTimeout(() => {
|
|
243349
243528
|
if (!resolved) {
|
|
243350
243529
|
resolved = true;
|
|
@@ -243355,6 +243534,7 @@ Failed HTTP Request: ${JSON.stringify(
|
|
|
243355
243534
|
success: false,
|
|
243356
243535
|
pending: enteredPool || void 0,
|
|
243357
243536
|
stalled: enteredPool || void 0,
|
|
243537
|
+
future: enteredPool && inFuture || void 0,
|
|
243358
243538
|
extrinsicHash: enteredPool ? extrinsic.hash.toHex() : void 0,
|
|
243359
243539
|
error: `Transaction timed out after ${timeoutMs}ms${enteredPool ? " while in the transaction pool" : ""}`
|
|
243360
243540
|
});
|
|
@@ -243364,6 +243544,7 @@ Failed HTTP Request: ${JSON.stringify(
|
|
|
243364
243544
|
if (resolved) return;
|
|
243365
243545
|
if (result.status.isFuture || result.status.isReady || result.status.isBroadcast || result.status.isRetracted) {
|
|
243366
243546
|
enteredPool = true;
|
|
243547
|
+
inFuture = result.status.isFuture;
|
|
243367
243548
|
}
|
|
243368
243549
|
if (result.dispatchError && (result.status.isInBlock || result.status.isFinalized)) {
|
|
243369
243550
|
resolved = true;
|
|
@@ -246654,12 +246835,13 @@ query OrderStatus($commitment: String!) {
|
|
|
246654
246835
|
ETH_GET_USER_OPERATION_RECEIPT: "eth_getUserOperationReceipt",
|
|
246655
246836
|
/** Estimates gas limits for a UserOperation before submission. */
|
|
246656
246837
|
ETH_ESTIMATE_USER_OPERATION_GAS: "eth_estimateUserOperationGas",
|
|
246657
|
-
/**
|
|
246658
|
-
|
|
246659
|
-
/**
|
|
246660
|
-
|
|
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"
|
|
246661
246842
|
};
|
|
246662
|
-
SELECT_SOLVER_TYPEHASH = keccak2563(toHex3("SelectSolver(bytes32 commitment,
|
|
246843
|
+
SELECT_SOLVER_TYPEHASH = keccak2563(toHex3("SelectSolver(bytes32 commitment,bytes32 userOpHash)"));
|
|
246844
|
+
LEGACY_SELECT_SOLVER_TYPEHASH = keccak2563(toHex3("SelectSolver(bytes32 commitment,address solver)"));
|
|
246663
246845
|
PACKED_USEROP_TYPEHASH = keccak2563(
|
|
246664
246846
|
toHex3(
|
|
246665
246847
|
"PackedUserOperation(address sender,uint256 nonce,bytes initCode,bytes callData,bytes32 accountGasLimits,uint256 preVerificationGas,bytes32 gasFees,bytes paymasterAndData)"
|
|
@@ -246698,29 +246880,50 @@ query OrderStatus($commitment: String!) {
|
|
|
246698
246880
|
);
|
|
246699
246881
|
}
|
|
246700
246882
|
/**
|
|
246701
|
-
* Signs
|
|
246883
|
+
* Signs `SelectSolver(bytes32 commitment,bytes32 userOpHash)` with the
|
|
246884
|
+
* order's session key, for gateways whose `SELECT_SOLVER_TYPEHASH` is
|
|
246885
|
+
* {@link SELECT_SOLVER_TYPEHASH}.
|
|
246702
246886
|
*
|
|
246703
|
-
* The
|
|
246704
|
-
*
|
|
246705
|
-
* solver's UserOperation signature before bundle submission.
|
|
246887
|
+
* The signature selects one bid UserOperation for the order and is appended
|
|
246888
|
+
* to that operation's signature before it is sent to the bundler.
|
|
246706
246889
|
*
|
|
246707
|
-
* @param commitment - The order commitment
|
|
246708
|
-
* @param
|
|
246709
|
-
* @param domainSeparator - EIP-712 domain separator
|
|
246710
|
-
* @param privateKey -
|
|
246711
|
-
* @returns The ECDSA signature
|
|
246890
|
+
* @param commitment - The order commitment.
|
|
246891
|
+
* @param userOpHash - EntryPoint userOpHash of the selected bid UserOperation.
|
|
246892
|
+
* @param domainSeparator - EIP-712 domain separator of the IntentGatewayV2 contract.
|
|
246893
|
+
* @param privateKey - Private key of the order's session key.
|
|
246894
|
+
* @returns The 65-byte ECDSA signature.
|
|
246712
246895
|
*/
|
|
246713
|
-
static async
|
|
246714
|
-
const
|
|
246896
|
+
static async signUserOpHashSelection(commitment, userOpHash, domainSeparator2, privateKey) {
|
|
246897
|
+
const structHash = keccak2563(
|
|
246898
|
+
encodeAbiParameters2(
|
|
246899
|
+
[{ type: "bytes32" }, { type: "bytes32" }, { type: "bytes32" }],
|
|
246900
|
+
[SELECT_SOLVER_TYPEHASH, commitment, userOpHash]
|
|
246901
|
+
)
|
|
246902
|
+
);
|
|
246903
|
+
return signTypedDigest(domainSeparator2, structHash, privateKey);
|
|
246904
|
+
}
|
|
246905
|
+
/**
|
|
246906
|
+
* Signs `SelectSolver(bytes32 commitment,address solver)` with the order's
|
|
246907
|
+
* session key, for gateways whose `SELECT_SOLVER_TYPEHASH` is
|
|
246908
|
+
* {@link LEGACY_SELECT_SOLVER_TYPEHASH}.
|
|
246909
|
+
*
|
|
246910
|
+
* The signature selects a solver account for the order and is appended to
|
|
246911
|
+
* that solver's bid UserOperation signature before it is sent to the bundler.
|
|
246912
|
+
*
|
|
246913
|
+
* @param commitment - The order commitment.
|
|
246914
|
+
* @param solverAddress - Address of the selected solver account.
|
|
246915
|
+
* @param domainSeparator - EIP-712 domain separator of the IntentGatewayV2 contract.
|
|
246916
|
+
* @param privateKey - Private key of the order's session key.
|
|
246917
|
+
* @returns The 65-byte ECDSA signature.
|
|
246918
|
+
*/
|
|
246919
|
+
static async signLegacySolverSelection(commitment, solverAddress, domainSeparator2, privateKey) {
|
|
246715
246920
|
const structHash = keccak2563(
|
|
246716
246921
|
encodeAbiParameters2(
|
|
246717
246922
|
[{ type: "bytes32" }, { type: "bytes32" }, { type: "address" }],
|
|
246718
|
-
[
|
|
246923
|
+
[LEGACY_SELECT_SOLVER_TYPEHASH, commitment, solverAddress]
|
|
246719
246924
|
)
|
|
246720
246925
|
);
|
|
246721
|
-
|
|
246722
|
-
const signature = await account5.sign({ hash: digest });
|
|
246723
|
-
return signature;
|
|
246926
|
+
return signTypedDigest(domainSeparator2, structHash, privateKey);
|
|
246724
246927
|
}
|
|
246725
246928
|
/**
|
|
246726
246929
|
* Computes the EIP-712 hash of a `PackedUserOperation` as defined by
|
|
@@ -247247,16 +247450,13 @@ query OrderStatus($commitment: String!) {
|
|
|
247247
247450
|
}
|
|
247248
247451
|
/**
|
|
247249
247452
|
* Creates a closure that computes the deduplication hash key for a
|
|
247250
|
-
* UserOperation, pre-bound to the
|
|
247453
|
+
* UserOperation, pre-bound to the destination chain.
|
|
247251
247454
|
*/
|
|
247252
|
-
createUserOpHasher(
|
|
247253
|
-
const entryPointAddress = this.ctx.dest.configService.getEntryPointV08Address(
|
|
247254
|
-
normalizeStateMachineId(order.destination)
|
|
247255
|
-
);
|
|
247455
|
+
createUserOpHasher() {
|
|
247256
247456
|
const chainId = BigInt(
|
|
247257
247457
|
this.ctx.dest.client.chain?.id ?? Number.parseInt(this.ctx.dest.config.stateMachineId.split("-")[1])
|
|
247258
247458
|
);
|
|
247259
|
-
return (userOp) => CryptoUtils.computeUserOpHash(userOp,
|
|
247459
|
+
return (userOp) => CryptoUtils.computeUserOpHash(userOp, ENTRY_POINT_V08, chainId);
|
|
247260
247460
|
}
|
|
247261
247461
|
/**
|
|
247262
247462
|
* Fetches bids from the coprocessor for a given order commitment.
|
|
@@ -247372,7 +247572,7 @@ query OrderStatus($commitment: String!) {
|
|
|
247372
247572
|
return;
|
|
247373
247573
|
}
|
|
247374
247574
|
const usedUserOps = await this.loadUsedUserOps(commitment);
|
|
247375
|
-
const userOpHashKey = this.createUserOpHasher(
|
|
247575
|
+
const userOpHashKey = this.createUserOpHasher();
|
|
247376
247576
|
const targetAssets = order.output.assets.map((a6) => ({ token: a6.token, amount: a6.amount }));
|
|
247377
247577
|
let initial;
|
|
247378
247578
|
try {
|
|
@@ -248236,7 +248436,8 @@ query OrderStatus($commitment: String!) {
|
|
|
248236
248436
|
}, __publicField(_a6, "DEFAULT_MAX_RECOVERY_RESTARTS", 1), __publicField(_a6, "PROOF_FRESHNESS_MAX_RETRIES", 3), __publicField(_a6, "PROOF_FRESHNESS_BACKOFF_MS", 500), /** Gas budgets used to price cancellation delivery on the source chain. */
|
|
248237
248437
|
__publicField(_a6, "SOURCE_GET_RESPONSE_GAS", 1000000n), __publicField(_a6, "REFUND_POST_GAS", 1000000n), _a6);
|
|
248238
248438
|
FILL_ORDER_SELECTOR = "0x68ddf058";
|
|
248239
|
-
SUPPORTED_INTENTS_VERSION =
|
|
248439
|
+
SUPPORTED_INTENTS_VERSION = 4n;
|
|
248440
|
+
TESTNET_INTENTS_VERSIONS = [3n, SUPPORTED_INTENTS_VERSION];
|
|
248240
248441
|
CONTRACT_VERSION_ABI = [
|
|
248241
248442
|
{
|
|
248242
248443
|
type: "function",
|
|
@@ -248247,6 +248448,13 @@ query OrderStatus($commitment: String!) {
|
|
|
248247
248448
|
}
|
|
248248
248449
|
];
|
|
248249
248450
|
CANONICAL_EVM_TOKEN = /^0x0{24}[0-9a-fA-F]{40}$/;
|
|
248451
|
+
formats = /* @__PURE__ */ new Map();
|
|
248452
|
+
SELECTION_PARAMS_SLOT = pad4(toHex3(5n), { size: 32 });
|
|
248453
|
+
SOLVER_SELECTION_CLEARED = maxUint2563 ^ 0xffn << 160n;
|
|
248454
|
+
SELECTION_FORMAT_BY_ENTRY_POINT = /* @__PURE__ */ new Map([
|
|
248455
|
+
[ENTRY_POINT_V09.toLowerCase(), "userOpHash"],
|
|
248456
|
+
[ENTRY_POINT_V08.toLowerCase(), "address"]
|
|
248457
|
+
]);
|
|
248250
248458
|
ENTRY_POINT_EVENT_ABI = [
|
|
248251
248459
|
{ type: "event", name: "BeforeExecution", inputs: [] },
|
|
248252
248460
|
{
|
|
@@ -248281,6 +248489,8 @@ query OrderStatus($commitment: String!) {
|
|
|
248281
248489
|
__publicField(this, "domainSeparator");
|
|
248282
248490
|
/** Cached session-key signature over the `SelectSolver` message. */
|
|
248283
248491
|
__publicField(this, "cachedSignature");
|
|
248492
|
+
/** Cached result of {@link route}. */
|
|
248493
|
+
__publicField(this, "cachedRoute");
|
|
248284
248494
|
this.ctx = params.ctx;
|
|
248285
248495
|
this.crypto = params.crypto;
|
|
248286
248496
|
this.order = params.order;
|
|
@@ -248310,69 +248520,117 @@ query OrderStatus($commitment: String!) {
|
|
|
248310
248520
|
);
|
|
248311
248521
|
}
|
|
248312
248522
|
/**
|
|
248313
|
-
*
|
|
248314
|
-
*
|
|
248523
|
+
* Finds the EntryPoint this bid's solver signed it for and checks that the
|
|
248524
|
+
* destination gateway's selection format pairs with it, reading the format
|
|
248525
|
+
* again before refusing a bid in case the gateway was upgraded since it was
|
|
248526
|
+
* cached. Caches the result.
|
|
248527
|
+
*
|
|
248528
|
+
* @throws If the solver's signature recovers under no known EntryPoint, the
|
|
248529
|
+
* EntryPoint does not pair with the gateway's selection format, or the
|
|
248530
|
+
* format cannot be read.
|
|
248531
|
+
*/
|
|
248532
|
+
async route() {
|
|
248533
|
+
if (this.cachedRoute) return this.cachedRoute;
|
|
248534
|
+
const chainId = this.chainId();
|
|
248535
|
+
let signed;
|
|
248536
|
+
for (const entryPoint of KNOWN_ENTRY_POINTS) {
|
|
248537
|
+
const userOpHash = CryptoUtils.computeUserOpHash(this.userOp, entryPoint, chainId);
|
|
248538
|
+
if (await this.signedBySolver(userOpHash)) {
|
|
248539
|
+
signed = { entryPoint, userOpHash };
|
|
248540
|
+
break;
|
|
248541
|
+
}
|
|
248542
|
+
}
|
|
248543
|
+
if (!signed) {
|
|
248544
|
+
throw new Error(`Bid from solver=${this.solverAddress} is not signed for a known EntryPoint`);
|
|
248545
|
+
}
|
|
248546
|
+
const pairsWith = SELECTION_FORMAT_BY_ENTRY_POINT.get(signed.entryPoint.toLowerCase());
|
|
248547
|
+
const cached = readSelectionFormat(this.ctx.dest.client, chainId, this.intentGatewayV2Address);
|
|
248548
|
+
let format2 = await cached;
|
|
248549
|
+
if (pairsWith !== format2) {
|
|
248550
|
+
format2 = await refreshSelectionFormat(this.ctx.dest.client, chainId, this.intentGatewayV2Address, cached);
|
|
248551
|
+
}
|
|
248552
|
+
if (pairsWith !== format2) {
|
|
248553
|
+
throw new Error(
|
|
248554
|
+
`Bid from solver=${this.solverAddress} is signed for EntryPoint ${signed.entryPoint}, which the destination gateway's ${format2} selection does not pair with`
|
|
248555
|
+
);
|
|
248556
|
+
}
|
|
248557
|
+
this.cachedRoute = { ...signed, format: format2 };
|
|
248558
|
+
return this.cachedRoute;
|
|
248559
|
+
}
|
|
248560
|
+
/**
|
|
248561
|
+
* Whether the solver's signature in the bid, `signature[32:97]` after the order
|
|
248562
|
+
* commitment, recovers to the solver over `userOpHash`.
|
|
248563
|
+
*/
|
|
248564
|
+
async signedBySolver(userOpHash) {
|
|
248565
|
+
try {
|
|
248566
|
+
const recovered = await recoverAddress3({
|
|
248567
|
+
hash: userOpHash,
|
|
248568
|
+
signature: slice4(this.userOp.signature, 32, 97)
|
|
248569
|
+
});
|
|
248570
|
+
return recovered.toLowerCase() === this.solverAddress.toLowerCase();
|
|
248571
|
+
} catch {
|
|
248572
|
+
return false;
|
|
248573
|
+
}
|
|
248574
|
+
}
|
|
248575
|
+
/**
|
|
248576
|
+
* Resolves the session key, signs the `SelectSolver` message for this bid in
|
|
248577
|
+
* the destination gateway's selection format, and caches the signature. Signs
|
|
248578
|
+
* at most once per bid.
|
|
248315
248579
|
*
|
|
248316
|
-
* @throws If the session key is missing
|
|
248580
|
+
* @throws If the bid cannot be routed, or the session key is missing.
|
|
248317
248581
|
*/
|
|
248318
248582
|
async signSelection() {
|
|
248319
248583
|
if (this.cachedSignature) return this.cachedSignature;
|
|
248584
|
+
const { format: format2, userOpHash } = await this.route();
|
|
248320
248585
|
const commitment = this.order.id;
|
|
248321
248586
|
const sessionKeyAddress = this.order.session;
|
|
248322
248587
|
const sessionKeyData = this.sessionPrivateKey ? { privateKey: this.sessionPrivateKey } : await this.ctx.sessionKeyStorage.getSessionKeyByAddress(sessionKeyAddress);
|
|
248323
248588
|
if (!sessionKeyData) {
|
|
248324
248589
|
throw new Error(`SessionKey not found for commitment: ${commitment}`);
|
|
248325
248590
|
}
|
|
248326
|
-
|
|
248591
|
+
this.cachedSignature = format2 === "userOpHash" ? await CryptoUtils.signUserOpHashSelection(
|
|
248592
|
+
commitment,
|
|
248593
|
+
userOpHash,
|
|
248594
|
+
this.domainSeparator,
|
|
248595
|
+
sessionKeyData.privateKey
|
|
248596
|
+
) : await CryptoUtils.signLegacySolverSelection(
|
|
248327
248597
|
commitment,
|
|
248328
248598
|
this.solverAddress,
|
|
248329
248599
|
this.domainSeparator,
|
|
248330
248600
|
sessionKeyData.privateKey
|
|
248331
248601
|
);
|
|
248332
|
-
|
|
248333
|
-
throw new Error("Failed to sign solver selection");
|
|
248334
|
-
}
|
|
248335
|
-
this.cachedSignature = signature;
|
|
248336
|
-
return signature;
|
|
248602
|
+
return this.cachedSignature;
|
|
248337
248603
|
}
|
|
248338
248604
|
/**
|
|
248339
|
-
* Simulates this bid on-chain
|
|
248340
|
-
*
|
|
248341
|
-
*
|
|
248605
|
+
* Simulates this bid on-chain with an `eth_call` of its calldata from the
|
|
248606
|
+
* solver's account, after checking that the bid can be routed.
|
|
248607
|
+
*
|
|
248608
|
+
* The gateway's solver selection is turned off for the call with
|
|
248609
|
+
* {@link selectionOffStateDiff} and no `select` is made: a gateway that selects
|
|
248610
|
+
* by userOpHash checks the selection against the EntryPoint's current
|
|
248611
|
+
* operation, which only exists inside a bundle. The session's selection is
|
|
248612
|
+
* therefore not part of the simulation.
|
|
248342
248613
|
*
|
|
248343
248614
|
* The native value forwarded to the simulation is the sum of any native-token
|
|
248344
248615
|
* (`address(0)`) output amounts plus the Hyperbridge dispatch fee.
|
|
248345
248616
|
*
|
|
248346
|
-
* @throws If the `eth_call` simulation reverts or errors.
|
|
248617
|
+
* @throws If the bid cannot be routed, or the `eth_call` simulation reverts or errors.
|
|
248347
248618
|
*/
|
|
248348
248619
|
async simulate() {
|
|
248349
|
-
|
|
248350
|
-
const selectOptions = {
|
|
248351
|
-
commitment: this.order.id,
|
|
248352
|
-
solver: this.solverAddress,
|
|
248353
|
-
signature
|
|
248354
|
-
};
|
|
248620
|
+
await this.route();
|
|
248355
248621
|
const nativeOutputs = this.fillOptions.outputs.reduce(
|
|
248356
248622
|
(acc, o6) => bytes32ToBytes20(o6.token) === ADDRESS_ZERO2 ? acc + o6.amount : acc,
|
|
248357
248623
|
0n
|
|
248358
248624
|
);
|
|
248359
248625
|
const simulationValue = nativeOutputs + this.fillOptions.nativeDispatchFee;
|
|
248360
|
-
const selectCalldata = encodeFunctionData2({
|
|
248361
|
-
abi: ABI3,
|
|
248362
|
-
functionName: "select",
|
|
248363
|
-
args: [selectOptions]
|
|
248364
|
-
});
|
|
248365
|
-
const calls = [
|
|
248366
|
-
{ target: this.intentGatewayV2Address, value: 0n, data: selectCalldata },
|
|
248367
|
-
{ target: this.solverAddress, value: simulationValue, data: this.userOp.callData }
|
|
248368
|
-
];
|
|
248369
|
-
const batchedCalldata = this.crypto.encodeERC7821Execute(calls);
|
|
248370
248626
|
try {
|
|
248627
|
+
const selectionOff = await selectionOffStateDiff(this.ctx.dest.client, this.intentGatewayV2Address);
|
|
248371
248628
|
await this.ctx.dest.client.call({
|
|
248372
248629
|
account: this.solverAddress,
|
|
248373
248630
|
to: this.solverAddress,
|
|
248374
|
-
data:
|
|
248375
|
-
value: simulationValue
|
|
248631
|
+
data: this.userOp.callData,
|
|
248632
|
+
value: simulationValue,
|
|
248633
|
+
stateOverride: [{ address: this.intentGatewayV2Address, stateDiff: [selectionOff] }]
|
|
248376
248634
|
});
|
|
248377
248635
|
} catch (e4) {
|
|
248378
248636
|
throw new Error(`Simulation failed: ${e4 instanceof Error ? e4.message : String(e4)}`);
|
|
@@ -248381,31 +248639,29 @@ query OrderStatus($commitment: String!) {
|
|
|
248381
248639
|
/**
|
|
248382
248640
|
* Signs the `SelectSolver` message with the session key, appends it to the
|
|
248383
248641
|
* solver's existing UserOp signature, and submits the UserOperation to the
|
|
248384
|
-
* bundler. Waits for the receipt and
|
|
248385
|
-
* logs to determine fill status.
|
|
248642
|
+
* bundler on the EntryPoint the bid was signed for. Waits for the receipt and
|
|
248643
|
+
* reads `OrderFilled` / `PartialFill` logs to determine fill status.
|
|
248386
248644
|
*
|
|
248387
248645
|
* @returns A {@link SelectBidResult} with the submitted UserOperation, its hash,
|
|
248388
248646
|
* the solver address, transaction hash, and fill status.
|
|
248389
|
-
* @throws If the bundler is not configured, the
|
|
248390
|
-
* bundler rejects the UserOperation.
|
|
248647
|
+
* @throws If the bundler is not configured, the bid cannot be routed, the
|
|
248648
|
+
* session key is missing, or the bundler rejects the UserOperation.
|
|
248391
248649
|
*/
|
|
248392
248650
|
async execute() {
|
|
248393
248651
|
const commitment = this.order.id;
|
|
248394
248652
|
if (!this.ctx.bundlerUrl) {
|
|
248395
248653
|
throw new Error("Bundler URL not configured");
|
|
248396
248654
|
}
|
|
248655
|
+
const { entryPoint } = await this.route();
|
|
248397
248656
|
const sessionSignature = await this.signSelection();
|
|
248398
248657
|
const finalSignature = concat3([this.userOp.signature, sessionSignature]);
|
|
248399
248658
|
const signedUserOp = {
|
|
248400
248659
|
...this.userOp,
|
|
248401
248660
|
signature: finalSignature
|
|
248402
248661
|
};
|
|
248403
|
-
const entryPointAddress = this.ctx.dest.configService.getEntryPointV08Address(
|
|
248404
|
-
normalizeStateMachineId(this.order.destination)
|
|
248405
|
-
);
|
|
248406
248662
|
const userOpHash = await this.crypto.sendBundler(BundlerMethod.ETH_SEND_USER_OPERATION, [
|
|
248407
248663
|
CryptoUtils.prepareBundlerCall(signedUserOp),
|
|
248408
|
-
|
|
248664
|
+
entryPoint
|
|
248409
248665
|
]);
|
|
248410
248666
|
let txnHash;
|
|
248411
248667
|
let fillStatus;
|
|
@@ -248431,7 +248687,7 @@ query OrderStatus($commitment: String!) {
|
|
|
248431
248687
|
);
|
|
248432
248688
|
const fills = parseEventLogs2({
|
|
248433
248689
|
abi: ABI3,
|
|
248434
|
-
logs: userOperationLogs(chainReceipt.logs,
|
|
248690
|
+
logs: userOperationLogs(chainReceipt.logs, entryPoint, userOpHash),
|
|
248435
248691
|
eventName: ["OrderFilled", "PartialFill"]
|
|
248436
248692
|
}).filter(
|
|
248437
248693
|
(event) => event.address.toLowerCase() === gateway.toLowerCase() && event.args.commitment.toLowerCase() === commitment.toLowerCase()
|
|
@@ -248483,12 +248739,15 @@ query OrderStatus($commitment: String!) {
|
|
|
248483
248739
|
* Constructs a signed `PackedUserOperation` that a solver can submit to the
|
|
248484
248740
|
* Hyperbridge coprocessor as a bid to fill an order.
|
|
248485
248741
|
*
|
|
248486
|
-
* The solver signs the operation as
|
|
248487
|
-
* whose digest is
|
|
248488
|
-
* the
|
|
248489
|
-
*
|
|
248490
|
-
*
|
|
248491
|
-
*
|
|
248742
|
+
* The solver signs the operation as EIP-712 typed data for
|
|
248743
|
+
* `entryPointAddress`, whose digest is that EntryPoint's userOpHash. It must
|
|
248744
|
+
* be the EntryPoint the solver's `SolverAccount` accepts: the user's SDK
|
|
248745
|
+
* recovers it from this signature and executes the bid there. The binding
|
|
248746
|
+
* to the order lives in the operation itself: the 4337 nonce key must derive
|
|
248747
|
+
* from the order commitment, the session key and the calldata
|
|
248748
|
+
* (`SolverAccount` enforces this during validation), and the callData
|
|
248749
|
+
* carries the order. This keeps the signed payload fully transparent to
|
|
248750
|
+
* signing infrastructure instead of an opaque digest.
|
|
248492
248751
|
*
|
|
248493
248752
|
* @param options - Parameters describing the solver account, gas limits, fee
|
|
248494
248753
|
* market values, and pre-built `callData` for the fill operation.
|
|
@@ -248521,7 +248780,7 @@ query OrderStatus($commitment: String!) {
|
|
|
248521
248780
|
}
|
|
248522
248781
|
const chain2 = normalizeStateMachineId(order.destination);
|
|
248523
248782
|
const gateway = this.ctx.dest.configService.getIntentGatewayAddress(chain2);
|
|
248524
|
-
if (!await supportsRateFills(this.ctx.dest.client, gateway)) {
|
|
248783
|
+
if (!await supportsRateFills(this.ctx.dest.client, gateway, chain2)) {
|
|
248525
248784
|
throw new Error("Fills are not supported by the destination gateway");
|
|
248526
248785
|
}
|
|
248527
248786
|
const chainId = BigInt(
|
|
@@ -248561,6 +248820,11 @@ query OrderStatus($commitment: String!) {
|
|
|
248561
248820
|
* silently dropped with a warning. The returned `Bid` instances are ready to
|
|
248562
248821
|
* be ranked, simulated, and executed by the consumer.
|
|
248563
248822
|
*
|
|
248823
|
+
* A bid signed for no known EntryPoint, or for one the destination gateway's
|
|
248824
|
+
* selection format does not pair with, is kept here and fails
|
|
248825
|
+
* {@link Bid.simulate} and {@link Bid.execute}, so {@link selectAndExecuteBest}
|
|
248826
|
+
* skips it.
|
|
248827
|
+
*
|
|
248564
248828
|
* @param order - The placed order the bids are competing to fill.
|
|
248565
248829
|
* @param bids - Raw filler bids fetched from the coprocessor.
|
|
248566
248830
|
* @param sessionPrivateKey - Optional session-key override; looked up from
|
|
@@ -248853,12 +249117,16 @@ query OrderStatus($commitment: String!) {
|
|
|
248853
249117
|
}
|
|
248854
249118
|
}
|
|
248855
249119
|
};
|
|
249120
|
+
UNSUPPORTED_REQUEST_CODES = /* @__PURE__ */ new Set([-32600, -32601, -32602]);
|
|
249121
|
+
bundlersWithoutRundlerFees = /* @__PURE__ */ new Set();
|
|
249122
|
+
bundlersWithoutRundlerGasPrice = /* @__PURE__ */ new Set();
|
|
248856
249123
|
RELAYER_MESSAGE_GAS = 1000000n;
|
|
248857
249124
|
NO_BUNDLER_FILL_GAS_BASE = 700000n;
|
|
248858
249125
|
NO_BUNDLER_FILL_GAS_PER_OUTPUT = 150000n;
|
|
248859
249126
|
NO_BUNDLER_PAYMASTER_VERIFICATION_GAS = 250000n;
|
|
248860
249127
|
NO_BUNDLER_PAYMASTER_POST_OP_GAS = 100000n;
|
|
248861
249128
|
BID_PVG_ESTIMATION_ACCOUNT_CODE = "0x60003560e01c631626ba7e1460145760206000f35b631626ba7e60e01b60005260206000f3";
|
|
249129
|
+
BID_PVG_ESTIMATION_PAYMASTER_CODE = "0x604060005260606000f3";
|
|
248862
249130
|
SELECTED_BID_SIGNATURE_BYTES = 32 + 65 + 65;
|
|
248863
249131
|
BID_PVG_HEADROOM_PERCENT = 10n;
|
|
248864
249132
|
ESCROW_MAPPING_SLOT = 9n;
|
|
@@ -248872,8 +249140,6 @@ query OrderStatus($commitment: String!) {
|
|
|
248872
249140
|
constructor(ctx, crypto10) {
|
|
248873
249141
|
__publicField(this, "ctx");
|
|
248874
249142
|
__publicField(this, "crypto");
|
|
248875
|
-
/** Call dispatchers read from a gateway, for chains whose config carries none. */
|
|
248876
|
-
__publicField(this, "dispatchers", /* @__PURE__ */ new Map());
|
|
248877
249143
|
this.ctx = ctx;
|
|
248878
249144
|
this.crypto = crypto10;
|
|
248879
249145
|
}
|
|
@@ -248894,8 +249160,9 @@ query OrderStatus($commitment: String!) {
|
|
|
248894
249160
|
* **Bundler path:** constructs a mock `PackedUserOperation` signed by an
|
|
248895
249161
|
* ephemeral keypair, applies state overrides, and calls
|
|
248896
249162
|
* `eth_estimateUserOperationGas`. Gas limits are bumped by 5-10% for
|
|
248897
|
-
* headroom.
|
|
248898
|
-
*
|
|
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,
|
|
248899
249166
|
* fixed gas limits are returned in its place, or the call throws when
|
|
248900
249167
|
* `params.requireBundlerEstimate` is set.
|
|
248901
249168
|
*
|
|
@@ -248930,7 +249197,7 @@ query OrderStatus($commitment: String!) {
|
|
|
248930
249197
|
const souceStateMachineId = isHex3(order.source) ? hexToString2(order.source) : order.source;
|
|
248931
249198
|
const destStateMachineId = isHex3(order.destination) ? hexToString2(order.destination) : order.destination;
|
|
248932
249199
|
const intentGatewayV2Address = this.ctx.dest.configService.getIntentGatewayAddress(destStateMachineId);
|
|
248933
|
-
const entryPointAddress = this.ctx.dest.configService.
|
|
249200
|
+
const entryPointAddress = this.ctx.dest.configService.getEntryPointAddress(destStateMachineId);
|
|
248934
249201
|
const chainId = BigInt(Number.parseInt(destStateMachineId.split("-")[1]));
|
|
248935
249202
|
const totalEthValue = quotedOutputs.filter((output3) => bytes32ToBytes20(output3.token) === ADDRESS_ZERO2).reduce((sum2, output3) => sum2 + output3.amount, 0n);
|
|
248936
249203
|
const [sourceFeeToken, destFeeToken, gasPrice, latestBlock] = await Promise.all([
|
|
@@ -248992,7 +249259,7 @@ query OrderStatus($commitment: String!) {
|
|
|
248992
249259
|
const maxFeeBumpPercent = params.maxFeePerGasBumpPercent ?? 10;
|
|
248993
249260
|
let maxPriorityFeePerGas = gasPrice + gasPrice * BigInt(priorityFeeBumpPercent) / 100n;
|
|
248994
249261
|
let maxFeePerGas = gasPrice + gasPrice * BigInt(maxFeeBumpPercent) / 100n;
|
|
248995
|
-
await assertGatewayRelease(this.ctx.dest.client, intentGatewayV2Address);
|
|
249262
|
+
await assertGatewayRelease(this.ctx.dest.client, intentGatewayV2Address, destStateMachineId);
|
|
248996
249263
|
const fillOrderCalldata = encodeFillOrder(transformOrderForContract(order), fillOptions);
|
|
248997
249264
|
let callGasLimit = 500000n;
|
|
248998
249265
|
let verificationGasLimit = 100000n;
|
|
@@ -249001,6 +249268,7 @@ query OrderStatus($commitment: String!) {
|
|
|
249001
249268
|
let paymasterPostOpGasLimit = 0n;
|
|
249002
249269
|
if (this.ctx.bundlerUrl) {
|
|
249003
249270
|
try {
|
|
249271
|
+
if (!entryPointAddress) throw new Error(`No EntryPoint configured for ${destStateMachineId}`);
|
|
249004
249272
|
const callData = this.crypto.encodeERC7821Execute([
|
|
249005
249273
|
...params.prependCalls ?? [],
|
|
249006
249274
|
{ target: intentGatewayV2Address, value: totalNativeValue, data: fillOrderCalldata }
|
|
@@ -249033,7 +249301,13 @@ query OrderStatus($commitment: String!) {
|
|
|
249033
249301
|
chainId,
|
|
249034
249302
|
intentGatewayV2Address
|
|
249035
249303
|
);
|
|
249036
|
-
const
|
|
249304
|
+
const selectionFormat = await readSelectionFormat(this.ctx.dest.client, chainId, intentGatewayV2Address);
|
|
249305
|
+
const sessionSignature = selectionFormat === "userOpHash" ? await CryptoUtils.signUserOpHashSelection(
|
|
249306
|
+
commitment,
|
|
249307
|
+
userOpHash,
|
|
249308
|
+
domainSeparator2,
|
|
249309
|
+
solverPrivateKey
|
|
249310
|
+
) : await CryptoUtils.signLegacySolverSelection(
|
|
249037
249311
|
commitment,
|
|
249038
249312
|
solverAccountAddress,
|
|
249039
249313
|
domainSeparator2,
|
|
@@ -249044,45 +249318,19 @@ query OrderStatus($commitment: String!) {
|
|
|
249044
249318
|
sessionSignature
|
|
249045
249319
|
]);
|
|
249046
249320
|
const bundlerUserOp = CryptoUtils.prepareBundlerCall(preliminaryUserOp);
|
|
249047
|
-
const
|
|
249048
|
-
|
|
249049
|
-
|
|
249050
|
-
const bundlerRequests = [
|
|
249321
|
+
const rundlerFeesRequest = rundlerUserOperationFees(
|
|
249322
|
+
this.ctx.bundlerUrl,
|
|
249323
|
+
{ maxFeePerGas, maxPriorityFeePerGas },
|
|
249051
249324
|
{
|
|
249052
|
-
|
|
249053
|
-
|
|
249054
|
-
|
|
249055
|
-
];
|
|
249056
|
-
if (isPimlico) {
|
|
249057
|
-
bundlerRequests.push({
|
|
249058
|
-
method: BundlerMethod.PIMLICO_GET_USER_OPERATION_GAS_PRICE,
|
|
249059
|
-
params: []
|
|
249060
|
-
});
|
|
249061
|
-
}
|
|
249062
|
-
if (isAlchemy) {
|
|
249063
|
-
bundlerRequests.push({
|
|
249064
|
-
method: BundlerMethod.RUNDLER_MAX_PRIORITY_FEE_PER_GAS,
|
|
249065
|
-
params: []
|
|
249066
|
-
});
|
|
249067
|
-
}
|
|
249068
|
-
let gasEstimate;
|
|
249069
|
-
let pimlicoGasPrices = null;
|
|
249070
|
-
let alchemyMaxPriorityFee = null;
|
|
249071
|
-
try {
|
|
249072
|
-
const batchResults = await this.crypto.sendBundlerBatch(bundlerRequests);
|
|
249073
|
-
gasEstimate = batchResults[0];
|
|
249074
|
-
if (isPimlico && batchResults.length > 1) {
|
|
249075
|
-
pimlicoGasPrices = batchResults[1];
|
|
249076
|
-
}
|
|
249077
|
-
if (isAlchemy && batchResults.length > 1) {
|
|
249078
|
-
alchemyMaxPriorityFee = batchResults[1];
|
|
249325
|
+
baseFeePerGas,
|
|
249326
|
+
priorityFeeBumpPercent: BigInt(priorityFeeBumpPercent),
|
|
249327
|
+
maxFeeBumpPercent: BigInt(maxFeeBumpPercent)
|
|
249079
249328
|
}
|
|
249080
|
-
|
|
249081
|
-
|
|
249082
|
-
|
|
249083
|
-
|
|
249084
|
-
|
|
249085
|
-
}
|
|
249329
|
+
);
|
|
249330
|
+
const gasEstimate = await this.crypto.sendBundler(
|
|
249331
|
+
BundlerMethod.ETH_ESTIMATE_USER_OPERATION_GAS,
|
|
249332
|
+
[bundlerUserOp, entryPointAddress, bundlerStateOverrides]
|
|
249333
|
+
);
|
|
249086
249334
|
callGasLimit = BigInt(gasEstimate.callGasLimit) * 160n / 100n;
|
|
249087
249335
|
verificationGasLimit = BigInt(gasEstimate.verificationGasLimit) * 105n / 100n;
|
|
249088
249336
|
preVerificationGas = BigInt(gasEstimate.preVerificationGas) * 105n / 100n;
|
|
@@ -249092,23 +249340,9 @@ query OrderStatus($commitment: String!) {
|
|
|
249092
249340
|
if (gasEstimate.paymasterPostOpGasLimit) {
|
|
249093
249341
|
paymasterPostOpGasLimit = BigInt(gasEstimate.paymasterPostOpGasLimit) * 105n / 100n;
|
|
249094
249342
|
}
|
|
249095
|
-
|
|
249096
|
-
|
|
249097
|
-
|
|
249098
|
-
const pimMaxFeePerGas = BigInt(level.maxFeePerGas);
|
|
249099
|
-
const pimMaxPriorityFeePerGas = BigInt(level.maxPriorityFeePerGas);
|
|
249100
|
-
maxFeePerGas = pimMaxFeePerGas + pimMaxFeePerGas * BigInt(maxFeeBumpPercent) / 100n;
|
|
249101
|
-
maxPriorityFeePerGas = pimMaxPriorityFeePerGas + pimMaxPriorityFeePerGas * BigInt(priorityFeeBumpPercent) / 100n;
|
|
249102
|
-
}
|
|
249103
|
-
}
|
|
249104
|
-
if (alchemyMaxPriorityFee) {
|
|
249105
|
-
const rundlerPriorityFee = BigInt(alchemyMaxPriorityFee);
|
|
249106
|
-
const isArbitrum = chainId === 42161n;
|
|
249107
|
-
const alchemyPrioBump = isArbitrum ? 0n : 25n;
|
|
249108
|
-
maxPriorityFeePerGas = rundlerPriorityFee + rundlerPriorityFee * alchemyPrioBump / 100n;
|
|
249109
|
-
const bufferedBaseFee = baseFeePerGas + baseFeePerGas * 50n / 100n;
|
|
249110
|
-
maxFeePerGas = bufferedBaseFee + maxPriorityFeePerGas;
|
|
249111
|
-
}
|
|
249343
|
+
const rundlerFees = await rundlerFeesRequest;
|
|
249344
|
+
maxFeePerGas = rundlerFees.maxFeePerGas;
|
|
249345
|
+
maxPriorityFeePerGas = rundlerFees.maxPriorityFeePerGas;
|
|
249112
249346
|
} catch (e4) {
|
|
249113
249347
|
if (params.requireBundlerEstimate) {
|
|
249114
249348
|
throw new Error(`Bundler gas estimation failed: ${e4 instanceof Error ? e4.message : String(e4)}`, {
|
|
@@ -249149,27 +249383,6 @@ query OrderStatus($commitment: String!) {
|
|
|
249149
249383
|
inputs
|
|
249150
249384
|
};
|
|
249151
249385
|
}
|
|
249152
|
-
/**
|
|
249153
|
-
* The call dispatcher the gateway on `chain` uses: the configured address, or the one
|
|
249154
|
-
* the gateway reports when the chain's config carries none.
|
|
249155
|
-
*
|
|
249156
|
-
* {@link buildStateOverride} writes it back into the gateway's params slot. Without an
|
|
249157
|
-
* address that value is 12 bytes instead of 32, and the bundler rejects the whole
|
|
249158
|
-
* estimate as `Invalid params`.
|
|
249159
|
-
*/
|
|
249160
|
-
async callDispatcher(chain2, gateway) {
|
|
249161
|
-
const configured = this.ctx.dest.configService.getCalldispatcherAddress(chain2);
|
|
249162
|
-
if (isAddress2(configured)) return configured;
|
|
249163
|
-
const known3 = this.dispatchers.get(chain2);
|
|
249164
|
-
if (known3) return known3;
|
|
249165
|
-
const params = await this.ctx.dest.client.readContract({
|
|
249166
|
-
abi: ABI3,
|
|
249167
|
-
address: gateway,
|
|
249168
|
-
functionName: "params"
|
|
249169
|
-
});
|
|
249170
|
-
this.dispatchers.set(chain2, params.dispatcher);
|
|
249171
|
-
return params.dispatcher;
|
|
249172
|
-
}
|
|
249173
249386
|
/**
|
|
249174
249387
|
* Asks the bundler for the `preVerificationGas` of the bid UserOperation that will
|
|
249175
249388
|
* actually be signed, with every funding call, approval and signature byte in it.
|
|
@@ -249183,7 +249396,9 @@ query OrderStatus($commitment: String!) {
|
|
|
249183
249396
|
* `maxFeePerGas`.
|
|
249184
249397
|
*
|
|
249185
249398
|
* The solver account's code is overridden with {@link BID_PVG_ESTIMATION_ACCOUNT_CODE}
|
|
249186
|
-
*
|
|
249399
|
+
* and the paymaster's, if the bid has one, with {@link BID_PVG_ESTIMATION_PAYMASTER_CODE}
|
|
249400
|
+
* for the call, so only the bytes are priced and neither the fill nor the paymaster's
|
|
249401
|
+
* validation is simulated.
|
|
249187
249402
|
*
|
|
249188
249403
|
* @param params - The bid's fields as they will be signed.
|
|
249189
249404
|
* @returns The `preVerificationGas` to sign, with {@link BID_PVG_HEADROOM_PERCENT} added.
|
|
@@ -249207,13 +249422,15 @@ query OrderStatus($commitment: String!) {
|
|
|
249207
249422
|
paymasterAndData: params.paymasterAndData ?? "0x",
|
|
249208
249423
|
signature: `0x${"ff".repeat(SELECTED_BID_SIGNATURE_BYTES)}`
|
|
249209
249424
|
};
|
|
249425
|
+
const stateOverride = {
|
|
249426
|
+
[solverAccount]: { code: BID_PVG_ESTIMATION_ACCOUNT_CODE }
|
|
249427
|
+
};
|
|
249428
|
+
if (userOp.paymasterAndData.length >= 42) {
|
|
249429
|
+
stateOverride[userOp.paymasterAndData.slice(0, 42)] = { code: BID_PVG_ESTIMATION_PAYMASTER_CODE };
|
|
249430
|
+
}
|
|
249210
249431
|
const estimate = await this.crypto.sendBundler(
|
|
249211
249432
|
BundlerMethod.ETH_ESTIMATE_USER_OPERATION_GAS,
|
|
249212
|
-
[
|
|
249213
|
-
CryptoUtils.prepareBundlerCall(userOp),
|
|
249214
|
-
params.entryPointAddress,
|
|
249215
|
-
{ [solverAccount]: { code: BID_PVG_ESTIMATION_ACCOUNT_CODE } }
|
|
249216
|
-
]
|
|
249433
|
+
[CryptoUtils.prepareBundlerCall(userOp), params.entryPointAddress, stateOverride]
|
|
249217
249434
|
);
|
|
249218
249435
|
return BigInt(estimate.preVerificationGas) * (100n + BID_PVG_HEADROOM_PERCENT) / 100n;
|
|
249219
249436
|
}
|
|
@@ -249261,9 +249478,8 @@ query OrderStatus($commitment: String!) {
|
|
|
249261
249478
|
* slots should be overridden.
|
|
249262
249479
|
* @param params.spenderAddress - Address that needs allowance from the solver
|
|
249263
249480
|
* account (i.e. the IntentGatewayV2 contract).
|
|
249264
|
-
* @param params.intentGatewayV2Address - If provided,
|
|
249265
|
-
*
|
|
249266
|
-
* succeed during estimation.
|
|
249481
|
+
* @param params.intentGatewayV2Address - If provided, turns the gateway's
|
|
249482
|
+
* solver selection off with {@link selectionOffStateDiff}.
|
|
249267
249483
|
* @param params.entryPointAddress - If provided, overrides the EntryPoint
|
|
249268
249484
|
* deposit mapping to give the solver account a large deposit.
|
|
249269
249485
|
* @returns An object with `viem` and `bundler` state-override collections.
|
|
@@ -249282,10 +249498,7 @@ query OrderStatus($commitment: String!) {
|
|
|
249282
249498
|
const viemOverrides = [];
|
|
249283
249499
|
const bundlerOverrides = {};
|
|
249284
249500
|
if (intentGatewayV2Address) {
|
|
249285
|
-
const
|
|
249286
|
-
const dispatcherAddress = await this.callDispatcher(chain2, intentGatewayV2Address);
|
|
249287
|
-
const newSlot5Value = "0x" + "0".repeat(22) + "00" + dispatcherAddress.slice(2).toLowerCase();
|
|
249288
|
-
const gatewayDiffs = [{ slot: paramsSlot5, value: newSlot5Value }];
|
|
249501
|
+
const gatewayDiffs = [await selectionOffStateDiff(this.ctx.dest.client, intentGatewayV2Address)];
|
|
249289
249502
|
for (const [leg, input] of (escrow?.inputs ?? []).entries()) {
|
|
249290
249503
|
gatewayDiffs.push({
|
|
249291
249504
|
slot: escrowSlot(escrow.commitment, leg),
|
|
@@ -249917,6 +250130,7 @@ query QuotePessimistic($route: RouteInput!, $amountIn: BigInt!) {
|
|
|
249917
250130
|
*
|
|
249918
250131
|
* The ERC-4337 bundler URL is read from `dest.bundlerUrl`, set when constructing
|
|
249919
250132
|
* the destination chain via {@link EvmChain.create} or {@link EvmChainParams.bundlerUrl}.
|
|
250133
|
+
* An `EvmChain` given none uses the bundler Hyperbridge runs for it.
|
|
249920
250134
|
*
|
|
249921
250135
|
* @param source - Source chain for order placement
|
|
249922
250136
|
* @param dest - Destination chain for order fulfillment
|
|
@@ -250606,6 +250820,27 @@ query QuotePessimistic($route: RouteInput!, $amountIn: BigInt!) {
|
|
|
250606
250820
|
}
|
|
250607
250821
|
});
|
|
250608
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
|
+
|
|
250609
250844
|
// src/services/FillerConfigService.ts
|
|
250610
250845
|
function validateRpcUrls(rpcUrls) {
|
|
250611
250846
|
if (rpcUrls.length === 0) {
|
|
@@ -250685,7 +250920,7 @@ async function resolveChainConfigs(chains2, options = {}) {
|
|
|
250685
250920
|
"RPC endpoint could not report its chainId at startup; keeping it for the quorum to judge per call"
|
|
250686
250921
|
);
|
|
250687
250922
|
}
|
|
250688
|
-
return { chainId: first3.chainId, rpcUrls, bundlerUrl:
|
|
250923
|
+
return { chainId: first3.chainId, rpcUrls, bundlerUrl: hyperbridgeBundlerUrl(first3.chainId) };
|
|
250689
250924
|
})
|
|
250690
250925
|
);
|
|
250691
250926
|
}
|
|
@@ -250696,6 +250931,7 @@ var init_FillerConfigService = __esm({
|
|
|
250696
250931
|
init_esm_shims();
|
|
250697
250932
|
init_Logger();
|
|
250698
250933
|
init_node10();
|
|
250934
|
+
init_bundlers();
|
|
250699
250935
|
DEFAULT_BLOCK_SCAN_INTERVAL_SECONDS = 3;
|
|
250700
250936
|
MIN_BLOCK_SCAN_INTERVAL_SECONDS = 0.1;
|
|
250701
250937
|
DEFAULT_MIN_ORDER_SIZE_USD = 20;
|
|
@@ -250764,12 +251000,6 @@ var init_FillerConfigService = __esm({
|
|
|
250764
251000
|
}
|
|
250765
251001
|
this.rpcOverrides.set(chainId, validateRpcUrls(rpcUrls));
|
|
250766
251002
|
}
|
|
250767
|
-
setBundlerUrl(chainId, bundlerUrl) {
|
|
250768
|
-
if (!this.rpcOverrides.has(chainId)) {
|
|
250769
|
-
throw new Error(`Chain ${chainId} is not configured`);
|
|
250770
|
-
}
|
|
250771
|
-
this.bundlerUrls.set(chainId, bundlerUrl);
|
|
250772
|
-
}
|
|
250773
251003
|
/** Replaces the rebalancing config at runtime; trigger checks read it live. */
|
|
250774
251004
|
setRebalancing(rebalancing) {
|
|
250775
251005
|
if (this.fillerConfig) this.fillerConfig.rebalancing = rebalancing;
|
|
@@ -250946,7 +251176,7 @@ var init_FillerConfigService = __esm({
|
|
|
250946
251176
|
return this.fillerConfig?.substratePrivateKey;
|
|
250947
251177
|
}
|
|
250948
251178
|
getEntryPointAddress(chain2) {
|
|
250949
|
-
return this.chainConfigService.
|
|
251179
|
+
return this.chainConfigService.getEntryPointAddress(chain2);
|
|
250950
251180
|
}
|
|
250951
251181
|
getSolverAccountContractAddress(chain2) {
|
|
250952
251182
|
return this.chainConfigService.getSolverAccountAddress(chain2);
|
|
@@ -251140,9 +251370,6 @@ function validateConfig(config5, cliWatchOnly = false) {
|
|
|
251140
251370
|
if (!Array.isArray(chain2.rpcUrls) || chain2.rpcUrls.length === 0 || chain2.rpcUrls.some((u6) => !u6)) {
|
|
251141
251371
|
throw new Error("Each chain configuration must have rpcUrls (a non-empty array of strings)");
|
|
251142
251372
|
}
|
|
251143
|
-
if (!chain2.bundlerUrl) {
|
|
251144
|
-
throw new Error("Each chain configuration must have bundlerUrl");
|
|
251145
|
-
}
|
|
251146
251373
|
}
|
|
251147
251374
|
const concurrent = config5.simplex.maxConcurrentOrders;
|
|
251148
251375
|
if (concurrent !== void 0) {
|
|
@@ -251390,7 +251617,7 @@ function nativeTokenSymbol(chainId) {
|
|
|
251390
251617
|
return CHAIN_NATIVE_SYMBOLS[chainId] ?? "ETH";
|
|
251391
251618
|
}
|
|
251392
251619
|
function chainsForNetwork(network) {
|
|
251393
|
-
return INIT_CHAINS.filter((chain2) => chain2.network === network);
|
|
251620
|
+
return INIT_CHAINS.filter((chain2) => chain2.network === network && chain2.hyperbridgeBundlerUrl);
|
|
251394
251621
|
}
|
|
251395
251622
|
function chainByChainId(chainId) {
|
|
251396
251623
|
return INIT_CHAINS.find((chain2) => chain2.chainId === chainId);
|
|
@@ -251404,6 +251631,7 @@ var init_chains2 = __esm({
|
|
|
251404
251631
|
"use strict";
|
|
251405
251632
|
init_esm_shims();
|
|
251406
251633
|
init_external_links();
|
|
251634
|
+
init_bundlers();
|
|
251407
251635
|
FREE_RPC_URLS = {
|
|
251408
251636
|
1: [
|
|
251409
251637
|
"https://mainnet.gateway.tenderly.co",
|
|
@@ -251475,7 +251703,8 @@ var init_chains2 = __esm({
|
|
|
251475
251703
|
network: "mainnet",
|
|
251476
251704
|
alchemySubdomain: "eth-mainnet",
|
|
251477
251705
|
explorerUrl: external_links_default.chainExplorers.ethereum,
|
|
251478
|
-
defaultRpcUrls: FREE_RPC_URLS[1]
|
|
251706
|
+
defaultRpcUrls: FREE_RPC_URLS[1],
|
|
251707
|
+
hyperbridgeBundlerUrl: HYPERBRIDGE_BUNDLER_URLS[1]
|
|
251479
251708
|
},
|
|
251480
251709
|
{
|
|
251481
251710
|
chainId: 42161,
|
|
@@ -251484,7 +251713,8 @@ var init_chains2 = __esm({
|
|
|
251484
251713
|
network: "mainnet",
|
|
251485
251714
|
alchemySubdomain: "arb-mainnet",
|
|
251486
251715
|
explorerUrl: external_links_default.chainExplorers.arbitrum,
|
|
251487
|
-
defaultRpcUrls: FREE_RPC_URLS[42161]
|
|
251716
|
+
defaultRpcUrls: FREE_RPC_URLS[42161],
|
|
251717
|
+
hyperbridgeBundlerUrl: HYPERBRIDGE_BUNDLER_URLS[42161]
|
|
251488
251718
|
},
|
|
251489
251719
|
{
|
|
251490
251720
|
chainId: 8453,
|
|
@@ -251493,7 +251723,8 @@ var init_chains2 = __esm({
|
|
|
251493
251723
|
network: "mainnet",
|
|
251494
251724
|
alchemySubdomain: "base-mainnet",
|
|
251495
251725
|
explorerUrl: external_links_default.chainExplorers.base,
|
|
251496
|
-
defaultRpcUrls: FREE_RPC_URLS[8453]
|
|
251726
|
+
defaultRpcUrls: FREE_RPC_URLS[8453],
|
|
251727
|
+
hyperbridgeBundlerUrl: HYPERBRIDGE_BUNDLER_URLS[8453]
|
|
251497
251728
|
},
|
|
251498
251729
|
{
|
|
251499
251730
|
chainId: 137,
|
|
@@ -251502,7 +251733,8 @@ var init_chains2 = __esm({
|
|
|
251502
251733
|
network: "mainnet",
|
|
251503
251734
|
alchemySubdomain: "polygon-mainnet",
|
|
251504
251735
|
explorerUrl: external_links_default.chainExplorers.polygon,
|
|
251505
|
-
defaultRpcUrls: FREE_RPC_URLS[137]
|
|
251736
|
+
defaultRpcUrls: FREE_RPC_URLS[137],
|
|
251737
|
+
hyperbridgeBundlerUrl: HYPERBRIDGE_BUNDLER_URLS[137]
|
|
251506
251738
|
},
|
|
251507
251739
|
{
|
|
251508
251740
|
chainId: 56,
|
|
@@ -251511,7 +251743,8 @@ var init_chains2 = __esm({
|
|
|
251511
251743
|
network: "mainnet",
|
|
251512
251744
|
alchemySubdomain: "bnb-mainnet",
|
|
251513
251745
|
explorerUrl: external_links_default.chainExplorers.bnb,
|
|
251514
|
-
defaultRpcUrls: FREE_RPC_URLS[56]
|
|
251746
|
+
defaultRpcUrls: FREE_RPC_URLS[56],
|
|
251747
|
+
hyperbridgeBundlerUrl: HYPERBRIDGE_BUNDLER_URLS[56]
|
|
251515
251748
|
},
|
|
251516
251749
|
{
|
|
251517
251750
|
chainId: 11155111,
|
|
@@ -251543,7 +251776,8 @@ var init_chains2 = __esm({
|
|
|
251543
251776
|
label: "Polygon Amoy",
|
|
251544
251777
|
network: "testnet",
|
|
251545
251778
|
alchemySubdomain: "polygon-amoy",
|
|
251546
|
-
explorerUrl: external_links_default.chainExplorers.polygonAmoy
|
|
251779
|
+
explorerUrl: external_links_default.chainExplorers.polygonAmoy,
|
|
251780
|
+
hyperbridgeBundlerUrl: HYPERBRIDGE_BUNDLER_URLS[80002]
|
|
251547
251781
|
},
|
|
251548
251782
|
{
|
|
251549
251783
|
chainId: 97,
|
|
@@ -251551,7 +251785,8 @@ var init_chains2 = __esm({
|
|
|
251551
251785
|
label: "BSC Chapel",
|
|
251552
251786
|
network: "testnet",
|
|
251553
251787
|
alchemySubdomain: "bnb-testnet",
|
|
251554
|
-
explorerUrl: external_links_default.chainExplorers.bnbChapel
|
|
251788
|
+
explorerUrl: external_links_default.chainExplorers.bnbChapel,
|
|
251789
|
+
hyperbridgeBundlerUrl: HYPERBRIDGE_BUNDLER_URLS[97]
|
|
251555
251790
|
}
|
|
251556
251791
|
];
|
|
251557
251792
|
HYPERBRIDGE_WS_DEFAULTS = {
|
|
@@ -251793,8 +252028,6 @@ function emitFillerToml(config5, options = {}) {
|
|
|
251793
252028
|
push("[[chains]]");
|
|
251794
252029
|
push("# List 2+ organisationally independent RPC providers to enable quorum log scanning.");
|
|
251795
252030
|
push(kv("rpcUrls", chain2.rpcUrls));
|
|
251796
|
-
push("# ERC-4337 bundler used to submit fill UserOperations on this chain.");
|
|
251797
|
-
push(kv("bundlerUrl", chain2.bundlerUrl));
|
|
251798
252031
|
push();
|
|
251799
252032
|
});
|
|
251800
252033
|
return `${out.join("\n").trimEnd()}
|
|
@@ -336725,9 +336958,6 @@ function parseAlchemyUrl(url2) {
|
|
|
336725
336958
|
if (!match) return null;
|
|
336726
336959
|
return { subdomain, apiKey: match[1] };
|
|
336727
336960
|
}
|
|
336728
|
-
function isAlchemyUrl(url2) {
|
|
336729
|
-
return parseAlchemyUrl(url2) !== null;
|
|
336730
|
-
}
|
|
336731
336961
|
function deriveAlchemyRpc(apiKey, chainId) {
|
|
336732
336962
|
const chain2 = chainByChainId(chainId);
|
|
336733
336963
|
if (!chain2?.alchemySubdomain) return null;
|
|
@@ -337578,10 +337808,9 @@ var init_help_text = __esm({
|
|
|
337578
337808
|
"use strict";
|
|
337579
337809
|
init_esm_shims();
|
|
337580
337810
|
WHY = {
|
|
337581
|
-
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.",
|
|
337582
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.",
|
|
337583
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.",
|
|
337584
|
-
bundler: "Fills execute as ERC-4337 UserOperations; the bundler submits them on-chain. Alchemy RPC endpoints double as bundlers, or use a dedicated provider like Pimlico.",
|
|
337585
337814
|
signer: "This wallet signs every fill and holds your stablecoin float on each chain. It's the identity of your filler.",
|
|
337586
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.",
|
|
337587
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.",
|
|
@@ -337643,8 +337872,7 @@ function detectPrefillNetwork(prefill) {
|
|
|
337643
337872
|
if (!prefill) return void 0;
|
|
337644
337873
|
for (const chainId of prefill.chainIds) {
|
|
337645
337874
|
if (chainId === null) continue;
|
|
337646
|
-
|
|
337647
|
-
if (meta) return "testnet";
|
|
337875
|
+
if (chainByChainId(chainId)?.network === "testnet") return "testnet";
|
|
337648
337876
|
}
|
|
337649
337877
|
return "mainnet";
|
|
337650
337878
|
}
|
|
@@ -337838,118 +338066,6 @@ var init_chains3 = __esm({
|
|
|
337838
338066
|
}
|
|
337839
338067
|
});
|
|
337840
338068
|
|
|
337841
|
-
// src/cli/init/derive/pimlico.ts
|
|
337842
|
-
function parsePimlicoUrl(url2) {
|
|
337843
|
-
let parsed;
|
|
337844
|
-
try {
|
|
337845
|
-
parsed = new URL(url2);
|
|
337846
|
-
} catch {
|
|
337847
|
-
return null;
|
|
337848
|
-
}
|
|
337849
|
-
if (parsed.protocol !== "https:") return null;
|
|
337850
|
-
if (parsed.hostname !== "api.pimlico.io") return null;
|
|
337851
|
-
const match = parsed.pathname.match(/^\/v2\/([^/]+)\/rpc$/);
|
|
337852
|
-
if (!match) return null;
|
|
337853
|
-
const chainId = Number(match[1]);
|
|
337854
|
-
if (!Number.isInteger(chainId) || chainId <= 0) return null;
|
|
337855
|
-
const apiKey = parsed.searchParams.get("apikey");
|
|
337856
|
-
if (!apiKey) return null;
|
|
337857
|
-
return { chainId, apiKey };
|
|
337858
|
-
}
|
|
337859
|
-
function derivePimlicoBundler(apiKey, chainId) {
|
|
337860
|
-
return `https://api.pimlico.io/v2/${chainId}/rpc?apikey=${encodeURIComponent(apiKey)}`;
|
|
337861
|
-
}
|
|
337862
|
-
var init_pimlico = __esm({
|
|
337863
|
-
"src/cli/init/derive/pimlico.ts"() {
|
|
337864
|
-
"use strict";
|
|
337865
|
-
init_esm_shims();
|
|
337866
|
-
}
|
|
337867
|
-
});
|
|
337868
|
-
|
|
337869
|
-
// src/cli/init/steps/bundlers.ts
|
|
337870
|
-
async function stepBundlers(state, prefill) {
|
|
337871
|
-
why(WHY.bundler);
|
|
337872
|
-
const alchemyChains = state.chains.filter((chain2) => {
|
|
337873
|
-
if (chain2.bundlerUrl || !isAlchemyUrl(chain2.rpcUrls[0])) return false;
|
|
337874
|
-
const existing = prefillBundlerFor(chain2.meta.chainId, prefill);
|
|
337875
|
-
return !existing || existing === chain2.rpcUrls[0];
|
|
337876
|
-
});
|
|
337877
|
-
if (alchemyChains.length > 0) {
|
|
337878
|
-
const reuse = guard(
|
|
337879
|
-
await confirm({
|
|
337880
|
-
message: `Reuse the Alchemy RPC as the ERC-4337 bundler for ${alchemyChains.map((c6) => c6.meta.label).join(", ")}?`,
|
|
337881
|
-
initialValue: true
|
|
337882
|
-
})
|
|
337883
|
-
);
|
|
337884
|
-
if (reuse) {
|
|
337885
|
-
for (const chain2 of alchemyChains) chain2.bundlerUrl = chain2.rpcUrls[0];
|
|
337886
|
-
}
|
|
337887
|
-
}
|
|
337888
|
-
const alchemyCapable = state.chains.filter((chain2) => !chain2.bundlerUrl && chain2.meta.alchemySubdomain);
|
|
337889
|
-
if (alchemyCapable.length > 0) {
|
|
337890
|
-
const useKey = guard(
|
|
337891
|
-
await confirm({
|
|
337892
|
-
message: `Configure the bundler for ${alchemyCapable.map((c6) => c6.meta.label).join(", ")} from one Alchemy API key?`,
|
|
337893
|
-
initialValue: true
|
|
337894
|
-
})
|
|
337895
|
-
);
|
|
337896
|
-
if (useKey) {
|
|
337897
|
-
const apiKey = await askSecret("Alchemy API key");
|
|
337898
|
-
for (const chain2 of alchemyCapable) {
|
|
337899
|
-
const url2 = deriveAlchemyRpc(apiKey, chain2.meta.chainId);
|
|
337900
|
-
if (url2) chain2.bundlerUrl = url2;
|
|
337901
|
-
}
|
|
337902
|
-
}
|
|
337903
|
-
}
|
|
337904
|
-
const pimlico = new ProviderDerivation({
|
|
337905
|
-
detect: (url2) => parsePimlicoUrl(url2)?.apiKey ?? null,
|
|
337906
|
-
derive: derivePimlicoBundler,
|
|
337907
|
-
confirmMessage: (remaining) => `Pimlico key detected \u2014 derive bundler URLs for ${remaining} from the same key?`
|
|
337908
|
-
});
|
|
337909
|
-
for (const chain2 of state.chains) {
|
|
337910
|
-
if (chain2.bundlerUrl) continue;
|
|
337911
|
-
const existing = prefillBundlerFor(chain2.meta.chainId, prefill);
|
|
337912
|
-
const derived2 = pimlico.candidate(chain2.meta.chainId);
|
|
337913
|
-
const url2 = derived2 ? await askDerivedOrCustom(
|
|
337914
|
-
`Bundler for ${chain2.meta.label}`,
|
|
337915
|
-
derived2,
|
|
337916
|
-
"Use the derived Pimlico URL",
|
|
337917
|
-
() => askBundlerUrl(chain2.meta.label, existing)
|
|
337918
|
-
) : await askBundlerUrl(chain2.meta.label, existing);
|
|
337919
|
-
chain2.bundlerUrl = url2;
|
|
337920
|
-
const remaining = state.chains.filter((c6) => !c6.bundlerUrl);
|
|
337921
|
-
await pimlico.offer(
|
|
337922
|
-
url2,
|
|
337923
|
-
remaining.map((c6) => c6.meta.label)
|
|
337924
|
-
);
|
|
337925
|
-
}
|
|
337926
|
-
}
|
|
337927
|
-
function prefillBundlerFor(chainId, prefill) {
|
|
337928
|
-
if (!prefill) return void 0;
|
|
337929
|
-
const index3 = prefill.chainIds.indexOf(chainId);
|
|
337930
|
-
if (index3 === -1) return void 0;
|
|
337931
|
-
return prefill.config.chains[index3]?.bundlerUrl || void 0;
|
|
337932
|
-
}
|
|
337933
|
-
function askBundlerUrl(label, initial) {
|
|
337934
|
-
return askUrl(`ERC-4337 bundler URL for ${label}`, {
|
|
337935
|
-
initial,
|
|
337936
|
-
placeholder: "https://api.pimlico.io/v2/<chainId>/rpc?apikey=<your-key>",
|
|
337937
|
-
required: "Bundler URL is required \u2014 fills are submitted through it"
|
|
337938
|
-
});
|
|
337939
|
-
}
|
|
337940
|
-
var init_bundlers = __esm({
|
|
337941
|
-
"src/cli/init/steps/bundlers.ts"() {
|
|
337942
|
-
"use strict";
|
|
337943
|
-
init_esm_shims();
|
|
337944
|
-
init_dist11();
|
|
337945
|
-
init_alchemy();
|
|
337946
|
-
init_pimlico();
|
|
337947
|
-
init_derive_flow();
|
|
337948
|
-
init_prompt_utils();
|
|
337949
|
-
init_help_text();
|
|
337950
|
-
}
|
|
337951
|
-
});
|
|
337952
|
-
|
|
337953
338069
|
// src/cli/init/steps/signer.ts
|
|
337954
338070
|
async function stepSigner(state, prefill) {
|
|
337955
338071
|
why(WHY.signer);
|
|
@@ -338431,7 +338547,7 @@ function assembleConfig(state) {
|
|
|
338431
338547
|
// would otherwise shadow the fresh entry (last [[chains]] wins at load).
|
|
338432
338548
|
chains: [
|
|
338433
338549
|
...state.passthroughChains,
|
|
338434
|
-
...state.chains.map((chain2) => ({ rpcUrls: chain2.rpcUrls
|
|
338550
|
+
...state.chains.map((chain2) => ({ rpcUrls: chain2.rpcUrls }))
|
|
338435
338551
|
],
|
|
338436
338552
|
rebalancing,
|
|
338437
338553
|
vault: hasVault ? vault : void 0,
|
|
@@ -338453,10 +338569,7 @@ function chainComments(state) {
|
|
|
338453
338569
|
function showSummary(state, outputPath) {
|
|
338454
338570
|
const lines = [];
|
|
338455
338571
|
for (const chain2 of state.chains) {
|
|
338456
|
-
|
|
338457
|
-
lines.push(
|
|
338458
|
-
`${chain2.meta.label}: ${chain2.rpcUrls.length} RPC${chain2.rpcUrls.length > 1 ? "s (quorum)" : ""}, bundler ${bundlerHost}`
|
|
338459
|
-
);
|
|
338572
|
+
lines.push(`${chain2.meta.label}: ${chain2.rpcUrls.length} RPC${chain2.rpcUrls.length > 1 ? "s (quorum)" : ""}`);
|
|
338460
338573
|
}
|
|
338461
338574
|
if (state.passthroughChains.length > 0) {
|
|
338462
338575
|
lines.push(`+ ${state.passthroughChains.length} unmanaged chain(s) kept from the previous config`);
|
|
@@ -338548,7 +338661,6 @@ async function runInit(options) {
|
|
|
338548
338661
|
const state = newWizardState();
|
|
338549
338662
|
state.prefillConfig = prefill?.config;
|
|
338550
338663
|
await stepChains(state, prefill);
|
|
338551
|
-
await stepBundlers(state, prefill);
|
|
338552
338664
|
await stepSigner(state, prefill);
|
|
338553
338665
|
await stepHyperbridge(state, prefill);
|
|
338554
338666
|
for (; ; ) {
|
|
@@ -338648,7 +338760,6 @@ var init_init3 = __esm({
|
|
|
338648
338760
|
init_migrate_legacy();
|
|
338649
338761
|
init_state();
|
|
338650
338762
|
init_chains3();
|
|
338651
|
-
init_bundlers();
|
|
338652
338763
|
init_signer2();
|
|
338653
338764
|
init_hyperbridge();
|
|
338654
338765
|
init_finetune();
|
|
@@ -338938,6 +339049,7 @@ init_dist4();
|
|
|
338938
339049
|
// src/services/server/UiServer.ts
|
|
338939
339050
|
init_esm_shims();
|
|
338940
339051
|
init_interpolated_curve();
|
|
339052
|
+
init_bundlers();
|
|
338941
339053
|
init_asset_registry();
|
|
338942
339054
|
init_pairs();
|
|
338943
339055
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
@@ -340701,6 +340813,8 @@ var LimitOrderService = class {
|
|
|
340701
340813
|
this.delegationService = delegationService;
|
|
340702
340814
|
this.startingNonce = startingNonce;
|
|
340703
340815
|
this.vaultBalances = vaultBalances;
|
|
340816
|
+
/** Re-signs in flight, by order id. A fill's resize waits one out rather than reposting alongside it. */
|
|
340817
|
+
this.resigning = /* @__PURE__ */ new Map();
|
|
340704
340818
|
this.logger = loggers.get("limit-orders");
|
|
340705
340819
|
}
|
|
340706
340820
|
/**
|
|
@@ -340794,6 +340908,7 @@ var LimitOrderService = class {
|
|
|
340794
340908
|
bookExpiresAt: null,
|
|
340795
340909
|
bookPrice: null,
|
|
340796
340910
|
orderNonce: order.orderNonce,
|
|
340911
|
+
entryPoint: null,
|
|
340797
340912
|
status: "cancelled",
|
|
340798
340913
|
lastError: null
|
|
340799
340914
|
}),
|
|
@@ -341060,24 +341175,32 @@ var LimitOrderService = class {
|
|
|
341060
341175
|
async resize(remaining, delivered) {
|
|
341061
341176
|
const id2 = remaining.id;
|
|
341062
341177
|
const floor2 = await this.dustFloor(remaining);
|
|
341063
|
-
|
|
341178
|
+
for (let resigning = this.resigning.get(id2); resigning; resigning = this.resigning.get(id2)) await resigning;
|
|
341179
|
+
const order = await this.store.setStatus(id2, "resizing", null, POSTABLE);
|
|
341180
|
+
if (!order) return null;
|
|
341181
|
+
if (BigInt(order.remaining) < floor2) {
|
|
341064
341182
|
this.logger.info(
|
|
341065
|
-
{ id: id2, remaining:
|
|
341183
|
+
{ id: id2, remaining: order.remaining, floor: floor2.toString() },
|
|
341066
341184
|
"Limit order worked down past the dust floor; closing it"
|
|
341067
341185
|
);
|
|
341068
|
-
if (
|
|
341069
|
-
const closed = await this.store.setPosting(
|
|
341070
|
-
|
|
341071
|
-
|
|
341072
|
-
|
|
341073
|
-
|
|
341074
|
-
|
|
341075
|
-
|
|
341076
|
-
|
|
341186
|
+
if (order.commitment) await this.withdraw(order.commitment);
|
|
341187
|
+
const closed = await this.store.setPosting(
|
|
341188
|
+
id2,
|
|
341189
|
+
{
|
|
341190
|
+
commitment: null,
|
|
341191
|
+
bookExpiresAt: null,
|
|
341192
|
+
bookPrice: null,
|
|
341193
|
+
orderNonce: order.orderNonce,
|
|
341194
|
+
entryPoint: null,
|
|
341195
|
+
status: "filled",
|
|
341196
|
+
lastError: null
|
|
341197
|
+
},
|
|
341198
|
+
POSTABLE
|
|
341199
|
+
);
|
|
341077
341200
|
if (closed) this.report({ kind: "filled", order: closed });
|
|
341078
341201
|
return closed;
|
|
341079
341202
|
}
|
|
341080
|
-
const resized = await this.repost(
|
|
341203
|
+
const resized = await this.repost(order);
|
|
341081
341204
|
if (resized) this.report({ kind: "resized", order: resized, delivered });
|
|
341082
341205
|
return resized;
|
|
341083
341206
|
}
|
|
@@ -341090,7 +341213,7 @@ var LimitOrderService = class {
|
|
|
341090
341213
|
*/
|
|
341091
341214
|
async repost(order) {
|
|
341092
341215
|
if (!order) return null;
|
|
341093
|
-
if (isLocal(order)) return this.store.setStatus(order.id, "open");
|
|
341216
|
+
if (isLocal(order)) return this.store.setStatus(order.id, "open", null, POSTABLE);
|
|
341094
341217
|
if (hasExpired(order.expiresAt, /* @__PURE__ */ new Date())) return this.retire(order);
|
|
341095
341218
|
if (order.commitment) {
|
|
341096
341219
|
const withdrawn = await this.withdraw(order.commitment);
|
|
@@ -341101,10 +341224,13 @@ var LimitOrderService = class {
|
|
|
341101
341224
|
{ id: order.id, commitment: order.commitment, err: message },
|
|
341102
341225
|
"Could not clear the old entry; leaving the posting alone rather than adding a second"
|
|
341103
341226
|
);
|
|
341104
|
-
return this.store.setStatus(order.id, "open", message);
|
|
341227
|
+
return this.store.setStatus(order.id, "open", message, POSTABLE);
|
|
341105
341228
|
}
|
|
341106
341229
|
}
|
|
341107
|
-
await this.store.setStatus(order.id, "resizing")
|
|
341230
|
+
if (!await this.store.setStatus(order.id, "resizing", null, POSTABLE)) {
|
|
341231
|
+
this.logger.info({ id: order.id }, "Limit order closed while it was being reposted; leaving it closed");
|
|
341232
|
+
return null;
|
|
341233
|
+
}
|
|
341108
341234
|
const nonce = (BigInt(order.orderNonce) + 1n).toString();
|
|
341109
341235
|
return (await this.post({ ...order, commitment: null, orderNonce: nonce })).order;
|
|
341110
341236
|
}
|
|
@@ -341147,7 +341273,9 @@ var LimitOrderService = class {
|
|
|
341147
341273
|
* They drift apart when a request never got an answer or the process died
|
|
341148
341274
|
* between two of them: an entry the orderbook still lists that nothing here
|
|
341149
341275
|
* owns, an order here whose entry has gone, or an entry the orderbook has cut
|
|
341150
|
-
* down because the solver cannot cover what it quoted.
|
|
341276
|
+
* down because the solver cannot cover what it quoted. A posted op is also
|
|
341277
|
+
* signed over one EntryPoint, so when the fill chain moves to another, every
|
|
341278
|
+
* entry signed before the move is withdrawn and posted again.
|
|
341151
341279
|
*/
|
|
341152
341280
|
async reconcile(now = /* @__PURE__ */ new Date()) {
|
|
341153
341281
|
const [entries, live] = await Promise.all([this.postedOrders(), this.live()]);
|
|
@@ -341174,7 +341302,17 @@ var LimitOrderService = class {
|
|
|
341174
341302
|
}
|
|
341175
341303
|
for (const order of live) {
|
|
341176
341304
|
if (isLocal(order)) continue;
|
|
341177
|
-
if (order.commitment && found.has(order.commitment.toLowerCase()))
|
|
341305
|
+
if (order.commitment && found.has(order.commitment.toLowerCase())) {
|
|
341306
|
+
try {
|
|
341307
|
+
if (await this.resign(order)) report.reposted++;
|
|
341308
|
+
} catch (err) {
|
|
341309
|
+
this.logger.error(
|
|
341310
|
+
{ id: order.id, err },
|
|
341311
|
+
"Could not sign the limit order again for its chain's EntryPoint"
|
|
341312
|
+
);
|
|
341313
|
+
}
|
|
341314
|
+
continue;
|
|
341315
|
+
}
|
|
341178
341316
|
if (sinceMs(order.updatedAt, now) < POST_GRACE_MS) continue;
|
|
341179
341317
|
this.logger.warn({ id: order.id }, "Limit order has no entry on the orderbook; posting it again");
|
|
341180
341318
|
try {
|
|
@@ -341186,6 +341324,45 @@ var LimitOrderService = class {
|
|
|
341186
341324
|
}
|
|
341187
341325
|
return report;
|
|
341188
341326
|
}
|
|
341327
|
+
/**
|
|
341328
|
+
* Withdraws a posting signed for an EntryPoint its fill chain no longer uses,
|
|
341329
|
+
* and posts it again signed for the one it uses now. Answers whether a new
|
|
341330
|
+
* posting landed.
|
|
341331
|
+
*
|
|
341332
|
+
* The row is read again and claimed out of `open` first: a fill can have worked
|
|
341333
|
+
* it down or started its own repost since reconciliation listed it, and that
|
|
341334
|
+
* write is the one to follow. A fill that lands once the claim is taken waits
|
|
341335
|
+
* in `resize` for this to finish. The EntryPoint is only written with a posting
|
|
341336
|
+
* that landed, so a pass cut short anywhere leaves a row the next pass still
|
|
341337
|
+
* reads as stale, or as having no entry, and finishes the job.
|
|
341338
|
+
*/
|
|
341339
|
+
async resign(listed) {
|
|
341340
|
+
const entryPoint = this.configService.getEntryPointAddress(listed.fillChain);
|
|
341341
|
+
if (!entryPoint || sameAddress(signedFor(listed), entryPoint)) return false;
|
|
341342
|
+
const order = await this.store.get(listed.id);
|
|
341343
|
+
if (!order || order.status !== "open" || order.commitment !== listed.commitment) return false;
|
|
341344
|
+
if (sameAddress(signedFor(order), entryPoint) || this.resigning.has(order.id)) return false;
|
|
341345
|
+
const resigned = this.signAgain(order, entryPoint);
|
|
341346
|
+
this.resigning.set(
|
|
341347
|
+
order.id,
|
|
341348
|
+
resigned.catch(() => false)
|
|
341349
|
+
);
|
|
341350
|
+
try {
|
|
341351
|
+
return await resigned;
|
|
341352
|
+
} finally {
|
|
341353
|
+
this.resigning.delete(order.id);
|
|
341354
|
+
}
|
|
341355
|
+
}
|
|
341356
|
+
async signAgain(order, entryPoint) {
|
|
341357
|
+
const claimed = await this.store.setStatus(order.id, "resizing", null, ["open"]);
|
|
341358
|
+
if (!claimed) return false;
|
|
341359
|
+
this.logger.warn(
|
|
341360
|
+
{ id: order.id, commitment: order.commitment, signedFor: signedFor(order), entryPoint },
|
|
341361
|
+
"Limit order was signed for an EntryPoint its chain no longer uses; signing it again"
|
|
341362
|
+
);
|
|
341363
|
+
const posted = await this.repost(claimed);
|
|
341364
|
+
return !!posted?.commitment && sameAddress(signedFor(posted), entryPoint);
|
|
341365
|
+
}
|
|
341189
341366
|
/**
|
|
341190
341367
|
* Lowers every open order's `remaining` to what the solver's account will still
|
|
341191
341368
|
* pay for it, and puts the order back on the book at that size.
|
|
@@ -341267,6 +341444,7 @@ var LimitOrderService = class {
|
|
|
341267
341444
|
bookExpiresAt: null,
|
|
341268
341445
|
bookPrice: null,
|
|
341269
341446
|
orderNonce: order.orderNonce,
|
|
341447
|
+
entryPoint: null,
|
|
341270
341448
|
status: "expired",
|
|
341271
341449
|
lastError: null
|
|
341272
341450
|
});
|
|
@@ -341323,11 +341501,11 @@ var LimitOrderService = class {
|
|
|
341323
341501
|
}
|
|
341324
341502
|
/** Builds and submits the posting, then writes the orderbook's answer onto the row. */
|
|
341325
341503
|
async post(order) {
|
|
341326
|
-
const { result, orderNonce } = await this.submit(order);
|
|
341504
|
+
const { result, orderNonce, entryPoint } = await this.submit(order);
|
|
341327
341505
|
if (result.kind === "accepted" || result.kind === "unchanged") {
|
|
341328
341506
|
const posted = result.order;
|
|
341329
341507
|
this.logger.info(
|
|
341330
|
-
{ id: order.id, commitment: posted.commitment, price: posted.price },
|
|
341508
|
+
{ id: order.id, commitment: posted.commitment, price: posted.price, entryPoint },
|
|
341331
341509
|
"Limit order posted to the orderbook"
|
|
341332
341510
|
);
|
|
341333
341511
|
const stored = await this.store.setPosting(
|
|
@@ -341337,6 +341515,10 @@ var LimitOrderService = class {
|
|
|
341337
341515
|
bookExpiresAt: posted.expiresAt,
|
|
341338
341516
|
bookPrice: posted.price,
|
|
341339
341517
|
orderNonce: orderNonce.toString(),
|
|
341518
|
+
// An entry the orderbook already held was signed by an earlier attempt,
|
|
341519
|
+
// for whichever EntryPoint was current then. Recorded as unknown, which
|
|
341520
|
+
// reconciliation reads as v0.8 and signs again once the chain is past it.
|
|
341521
|
+
entryPoint: result.kind === "accepted" ? entryPoint : null,
|
|
341340
341522
|
status: "open",
|
|
341341
341523
|
lastError: null
|
|
341342
341524
|
},
|
|
@@ -341366,6 +341548,7 @@ var LimitOrderService = class {
|
|
|
341366
341548
|
bookExpiresAt: null,
|
|
341367
341549
|
bookPrice: null,
|
|
341368
341550
|
orderNonce: orderNonce.toString(),
|
|
341551
|
+
entryPoint: null,
|
|
341369
341552
|
status: "open",
|
|
341370
341553
|
lastError: message
|
|
341371
341554
|
}),
|
|
@@ -341388,22 +341571,30 @@ var LimitOrderService = class {
|
|
|
341388
341571
|
* only the second one.
|
|
341389
341572
|
*/
|
|
341390
341573
|
async submit(order) {
|
|
341574
|
+
const entryPoint = this.entryPointFor(order.fillChain);
|
|
341391
341575
|
const orderNonce = BigInt(order.orderNonce);
|
|
341392
|
-
const attempt = await this.buildAndSubmit(order, orderNonce);
|
|
341576
|
+
const attempt = await this.buildAndSubmit(order, orderNonce, entryPoint);
|
|
341393
341577
|
const first3 = attempt.result;
|
|
341394
341578
|
if (first3.kind !== "rejected" || first3.code !== "REPLAYED" && first3.code !== "ORDER_EXISTS") {
|
|
341395
|
-
return { result: first3, orderNonce };
|
|
341579
|
+
return { result: first3, orderNonce, entryPoint };
|
|
341396
341580
|
}
|
|
341397
341581
|
if (first3.code === "ORDER_EXISTS" && attempt.commitment) {
|
|
341398
341582
|
const live = await this.entryAt(order, attempt.commitment);
|
|
341399
341583
|
if (live) {
|
|
341400
341584
|
this.logger.info({ id: order.id, commitment: live.commitment }, "This posting is already on the orderbook");
|
|
341401
|
-
return { result: { kind: "unchanged", order: live }, orderNonce };
|
|
341585
|
+
return { result: { kind: "unchanged", order: live }, orderNonce, entryPoint };
|
|
341402
341586
|
}
|
|
341403
341587
|
}
|
|
341404
341588
|
this.logger.warn({ id: order.id, code: first3.code }, "Orderbook has seen this op before; reposting on a new nonce");
|
|
341405
341589
|
const retried = orderNonce + 1n;
|
|
341406
|
-
|
|
341590
|
+
const { result } = await this.buildAndSubmit(order, retried, entryPoint);
|
|
341591
|
+
return { result, orderNonce: retried, entryPoint };
|
|
341592
|
+
}
|
|
341593
|
+
/** The EntryPoint a posting on `chain` is signed for now. */
|
|
341594
|
+
entryPointFor(chain2) {
|
|
341595
|
+
const entryPoint = this.configService.getEntryPointAddress(chain2);
|
|
341596
|
+
if (!entryPoint) throw new LimitOrderValidationError(`No EntryPoint is configured for ${chain2}`);
|
|
341597
|
+
return entryPoint;
|
|
341407
341598
|
}
|
|
341408
341599
|
/**
|
|
341409
341600
|
* The entry the orderbook holds at `commitment`, if it holds one. A lookup that
|
|
@@ -341419,8 +341610,8 @@ var LimitOrderService = class {
|
|
|
341419
341610
|
}
|
|
341420
341611
|
}
|
|
341421
341612
|
/** The orderbook's answer, and the commitment the op we sent hashes to. */
|
|
341422
|
-
async buildAndSubmit(order, orderNonce) {
|
|
341423
|
-
const { commitment, userOp } = await this.buildUserOp(order, orderNonce);
|
|
341613
|
+
async buildAndSubmit(order, orderNonce, entryPoint) {
|
|
341614
|
+
const { commitment, userOp } = await this.buildUserOp(order, orderNonce, entryPoint);
|
|
341424
341615
|
try {
|
|
341425
341616
|
return { result: await this.client.submitOrder(userOp), commitment };
|
|
341426
341617
|
} catch (err) {
|
|
@@ -341430,7 +341621,7 @@ var LimitOrderService = class {
|
|
|
341430
341621
|
throw err;
|
|
341431
341622
|
}
|
|
341432
341623
|
}
|
|
341433
|
-
async buildUserOp(order, orderNonce) {
|
|
341624
|
+
async buildUserOp(order, orderNonce, entryPointAddress) {
|
|
341434
341625
|
const baseToken = this.assetRegistry.getAddress(order.base, order.fillChain);
|
|
341435
341626
|
const quoteToken = this.assetRegistry.getAddress(order.quote, order.fillChain);
|
|
341436
341627
|
const [baseDecimals, quoteDecimals] = await Promise.all([
|
|
@@ -341445,10 +341636,6 @@ var LimitOrderService = class {
|
|
|
341445
341636
|
baseDecimals,
|
|
341446
341637
|
quoteDecimals
|
|
341447
341638
|
});
|
|
341448
|
-
const entryPointAddress = this.configService.getEntryPointAddress(order.fillChain);
|
|
341449
|
-
if (!entryPointAddress) {
|
|
341450
|
-
throw new LimitOrderValidationError(`No EntryPoint is configured for ${order.fillChain}`);
|
|
341451
|
-
}
|
|
341452
341639
|
return this.contractService.prepareLimitOrderUserOp({
|
|
341453
341640
|
fillChain: order.fillChain,
|
|
341454
341641
|
entryPointAddress,
|
|
@@ -341479,6 +341666,12 @@ function hasExpired(expiresAt, now) {
|
|
|
341479
341666
|
const at = Date.parse(expiresAt);
|
|
341480
341667
|
return !Number.isNaN(at) && at <= now.getTime();
|
|
341481
341668
|
}
|
|
341669
|
+
function signedFor(order) {
|
|
341670
|
+
return order.entryPoint ?? ENTRY_POINT_V08;
|
|
341671
|
+
}
|
|
341672
|
+
function sameAddress(a6, b5) {
|
|
341673
|
+
return a6.toLowerCase() === b5.toLowerCase();
|
|
341674
|
+
}
|
|
341482
341675
|
function sinceMs(updatedAt, now) {
|
|
341483
341676
|
const written = Date.parse(`${updatedAt.replace(" ", "T")}Z`);
|
|
341484
341677
|
return Number.isNaN(written) ? Number.POSITIVE_INFINITY : now.getTime() - written;
|
|
@@ -343388,8 +343581,6 @@ async function handleSetupRequest(server, setup, req, res, path2, method) {
|
|
|
343388
343581
|
return sendJson(res, 200, await validateAlchemyKey(body, deps));
|
|
343389
343582
|
case "validate-rpc":
|
|
343390
343583
|
return sendJson(res, 200, await validateRpc(body, deps));
|
|
343391
|
-
case "validate-bundler":
|
|
343392
|
-
return sendJson(res, 200, await validateBundler(body, deps));
|
|
343393
343584
|
case "validate-token":
|
|
343394
343585
|
return sendJson(res, 200, await validateToken(body));
|
|
343395
343586
|
case "derive-evm-address":
|
|
@@ -343422,9 +343613,7 @@ async function validateAlchemyKey(body, deps) {
|
|
|
343422
343613
|
stateMachineId: meta.stateMachineId,
|
|
343423
343614
|
label: meta.label,
|
|
343424
343615
|
note: meta.note,
|
|
343425
|
-
rpcUrl
|
|
343426
|
-
// Alchemy serves ERC-4337 bundler methods on the same endpoint.
|
|
343427
|
-
bundlerUrl: rpcUrl
|
|
343616
|
+
rpcUrl
|
|
343428
343617
|
};
|
|
343429
343618
|
});
|
|
343430
343619
|
const probe = chains2.find((c6) => c6.rpcUrl);
|
|
@@ -343462,23 +343651,6 @@ async function validateRpc(body, deps) {
|
|
|
343462
343651
|
);
|
|
343463
343652
|
return { ok: results.every((r7) => !r7.error), results };
|
|
343464
343653
|
}
|
|
343465
|
-
async function validateBundler(body, deps) {
|
|
343466
|
-
const url2 = String(body.url ?? "").trim();
|
|
343467
|
-
if (!url2) return { ok: false, warning: "Bundler URL is empty" };
|
|
343468
|
-
try {
|
|
343469
|
-
const entryPoints = await withTimeout3(
|
|
343470
|
-
deps.rpcRequest(url2, "eth_supportedEntryPoints", []),
|
|
343471
|
-
PROBE_TIMEOUT_MS,
|
|
343472
|
-
"Bundler probe"
|
|
343473
|
-
);
|
|
343474
|
-
return { ok: true, entryPoints };
|
|
343475
|
-
} catch (err) {
|
|
343476
|
-
return {
|
|
343477
|
-
ok: true,
|
|
343478
|
-
warning: `Bundler did not answer eth_supportedEntryPoints: ${err instanceof Error ? err.message : err}`
|
|
343479
|
-
};
|
|
343480
|
-
}
|
|
343481
|
-
}
|
|
343482
343654
|
async function validateToken(body) {
|
|
343483
343655
|
const rpcUrl = String(body.rpcUrl ?? "").trim();
|
|
343484
343656
|
const address = String(body.address ?? "").trim();
|
|
@@ -343616,7 +343788,6 @@ function maskToml(config5, chainLabels) {
|
|
|
343616
343788
|
}
|
|
343617
343789
|
for (const chain2 of masked.chains) {
|
|
343618
343790
|
chain2.rpcUrls = chain2.rpcUrls.map(maskUrlKey);
|
|
343619
|
-
chain2.bundlerUrl = maskUrlKey(chain2.bundlerUrl);
|
|
343620
343791
|
}
|
|
343621
343792
|
return emitFillerToml(masked, { chainComments: chainLabels });
|
|
343622
343793
|
}
|
|
@@ -343690,12 +343861,7 @@ function openSseStream(req, res, clients) {
|
|
|
343690
343861
|
res.once("close", cleanup);
|
|
343691
343862
|
res.once("error", cleanup);
|
|
343692
343863
|
}
|
|
343693
|
-
var OPERATOR_PROBES = [
|
|
343694
|
-
"/api/setup/validate-token",
|
|
343695
|
-
"/api/setup/validate-rpc",
|
|
343696
|
-
"/api/setup/validate-bundler",
|
|
343697
|
-
"/api/setup/validate-alchemy-key"
|
|
343698
|
-
];
|
|
343864
|
+
var OPERATOR_PROBES = ["/api/setup/validate-token", "/api/setup/validate-rpc", "/api/setup/validate-alchemy-key"];
|
|
343699
343865
|
var LOGS_UNAVAILABLE = "Log capture is not enabled for this filler";
|
|
343700
343866
|
var MAX_LOG_STREAM_QUEUE = 5e3;
|
|
343701
343867
|
var MAX_LOG_PAGE = 2e3;
|
|
@@ -344145,9 +344311,6 @@ var UiServer = class {
|
|
|
344145
344311
|
const body = JSON.parse(await readBody(req));
|
|
344146
344312
|
if (path2 === "/api/setup/validate-rpc")
|
|
344147
344313
|
return sendJson(res, 200, await validateRpc(body, this.deps));
|
|
344148
|
-
if (path2 === "/api/setup/validate-bundler") {
|
|
344149
|
-
return sendJson(res, 200, await validateBundler(body, this.deps));
|
|
344150
|
-
}
|
|
344151
344314
|
if (path2 === "/api/setup/validate-alchemy-key") {
|
|
344152
344315
|
return sendJson(res, 200, await validateAlchemyKey(body, this.deps));
|
|
344153
344316
|
}
|
|
@@ -344863,7 +345026,7 @@ var UiServer = class {
|
|
|
344863
345026
|
stateMachineId: formatChainKey(chainId),
|
|
344864
345027
|
label: chainLabel(chainId),
|
|
344865
345028
|
rpcUrls: chain2.rpcUrls,
|
|
344866
|
-
bundlerUrl:
|
|
345029
|
+
bundlerUrl: hyperbridgeBundlerUrl(chainId) ?? "",
|
|
344867
345030
|
watchOnly: globalWatchOnly ? watchOnly : Boolean(watchOnly?.[String(chainId)]),
|
|
344868
345031
|
running: running.has(chainId)
|
|
344869
345032
|
};
|
|
@@ -344910,11 +345073,11 @@ var UiServer = class {
|
|
|
344910
345073
|
}
|
|
344911
345074
|
const rpcUrls = (Array.isArray(row.rpcUrls) ? row.rpcUrls : []).map((url2) => String(url2).trim()).filter(Boolean);
|
|
344912
345075
|
validateRpcUrls(rpcUrls);
|
|
344913
|
-
const
|
|
344914
|
-
if (!
|
|
344915
|
-
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`);
|
|
344916
345079
|
}
|
|
344917
|
-
rows.push({ chainId, rpcUrls,
|
|
345080
|
+
rows.push({ chainId, rpcUrls, watchOnly });
|
|
344918
345081
|
}
|
|
344919
345082
|
} catch (err) {
|
|
344920
345083
|
return sendJson(res, 400, { error: err instanceof Error ? err.message : String(err) });
|
|
@@ -344946,7 +345109,7 @@ var UiServer = class {
|
|
|
344946
345109
|
} catch (err) {
|
|
344947
345110
|
return sendJson(res, 400, { error: err instanceof Error ? err.message : String(err) });
|
|
344948
345111
|
}
|
|
344949
|
-
op.config.chains = rows.map(({ rpcUrls
|
|
345112
|
+
op.config.chains = rows.map(({ rpcUrls }) => ({ rpcUrls }));
|
|
344950
345113
|
if (Object.keys(confirmationPolicies).length > 0) op.config.confirmationPolicies = confirmationPolicies;
|
|
344951
345114
|
if (typeof op.config.simplex.watchOnly !== "boolean") {
|
|
344952
345115
|
const perChain = Object.fromEntries(rows.filter((r7) => r7.watchOnly).map((r7) => [String(r7.chainId), true]));
|
|
@@ -349514,9 +349677,9 @@ var INTENT_GATEWAY_V2_ABI = [
|
|
|
349514
349677
|
internalType: "bytes32"
|
|
349515
349678
|
},
|
|
349516
349679
|
{
|
|
349517
|
-
name: "
|
|
349518
|
-
type: "
|
|
349519
|
-
internalType: "
|
|
349680
|
+
name: "userOpHash",
|
|
349681
|
+
type: "bytes32",
|
|
349682
|
+
internalType: "bytes32"
|
|
349520
349683
|
},
|
|
349521
349684
|
{
|
|
349522
349685
|
name: "signature",
|
|
@@ -350904,10 +351067,13 @@ var LIMIT_ORDER_CALL_GAS_LIMIT = 500000n;
|
|
|
350904
351067
|
var LIMIT_ORDER_VERIFICATION_GAS_LIMIT = 150000n;
|
|
350905
351068
|
var LIMIT_ORDER_PRE_VERIFICATION_GAS = 50000n;
|
|
350906
351069
|
var BID_DISCOVERY_PAD_SECONDS = 30;
|
|
351070
|
+
var BLOCK_TIME_SAMPLE_BLOCKS = 1000n;
|
|
351071
|
+
var FALLBACK_BLOCK_TIME_SECONDS = 2;
|
|
350907
351072
|
var ContractInteractionService = class {
|
|
350908
351073
|
constructor(clientManager, configService, signer, sharedCacheService) {
|
|
350909
351074
|
this.clientManager = clientManager;
|
|
350910
351075
|
this.sdkHelperCache = /* @__PURE__ */ new Map();
|
|
351076
|
+
this.blockTimes = /* @__PURE__ */ new Map();
|
|
350911
351077
|
this.logger = moduleLogger(configService.loggers, "contract-service");
|
|
350912
351078
|
this.configService = configService;
|
|
350913
351079
|
this.cacheService = sharedCacheService || new CacheService();
|
|
@@ -350967,11 +351133,20 @@ var ContractInteractionService = class {
|
|
|
350967
351133
|
try {
|
|
350968
351134
|
const chainIds = this.configService.getConfiguredChainIds();
|
|
350969
351135
|
const chainNames = chainIds.map((id2) => `EVM-${id2}`);
|
|
350970
|
-
|
|
351136
|
+
await Promise.all(
|
|
351137
|
+
chainNames.map(async (chainName2) => {
|
|
351138
|
+
try {
|
|
351139
|
+
await this.blockTimeSeconds(chainName2);
|
|
351140
|
+
} catch (err) {
|
|
351141
|
+
this.logger.warn({ err, chain: chainName2 }, "Could not measure the block time at startup");
|
|
351142
|
+
}
|
|
351143
|
+
})
|
|
351144
|
+
);
|
|
351145
|
+
for (const chainName2 of chainNames) {
|
|
350971
351146
|
try {
|
|
350972
|
-
await this.getFeeTokenWithDecimals(
|
|
351147
|
+
await this.getFeeTokenWithDecimals(chainName2);
|
|
350973
351148
|
} catch (err) {
|
|
350974
|
-
this.logger.warn({ err, chain:
|
|
351149
|
+
this.logger.warn({ err, chain: chainName2 }, "Could not prewarm fee token decimals");
|
|
350975
351150
|
}
|
|
350976
351151
|
}
|
|
350977
351152
|
for (const destChain of chainNames) {
|
|
@@ -351556,18 +351731,59 @@ var ContractInteractionService = class {
|
|
|
351556
351731
|
*
|
|
351557
351732
|
* Operators configure seconds because that is the unit the risk is actually in, but the
|
|
351558
351733
|
* contract compares against block numbers so `order.deadline` and this read the same
|
|
351559
|
-
* clock. The conversion uses the chain's
|
|
351560
|
-
* up, since erring long costs a slightly stale quote while erring
|
|
351561
|
-
* winnable bids.
|
|
351734
|
+
* clock. The conversion uses the chain's block time from {@link blockTimeSeconds}; it is
|
|
351735
|
+
* deliberately rounded up, since erring long costs a slightly stale quote while erring
|
|
351736
|
+
* short silently drops winnable bids.
|
|
351562
351737
|
*/
|
|
351563
351738
|
async bidValidUntilBlock(chain2) {
|
|
351564
351739
|
const client = this.clientManager.getPublicClient(chain2);
|
|
351565
|
-
const currentBlock = await client.getBlockNumber();
|
|
351566
|
-
const blockTimeMs = client.chain?.blockTime;
|
|
351567
|
-
const blockTimeSec = blockTimeMs ? blockTimeMs / 1e3 : 2;
|
|
351740
|
+
const [currentBlock, blockTimeSec] = await Promise.all([client.getBlockNumber(), this.blockTimeSeconds(chain2)]);
|
|
351568
351741
|
const windowSec = this.configService.getBidValiditySeconds() + BID_DISCOVERY_PAD_SECONDS;
|
|
351569
351742
|
return currentBlock + BigInt(Math.ceil(windowSec / blockTimeSec));
|
|
351570
351743
|
}
|
|
351744
|
+
/**
|
|
351745
|
+
* Seconds per block on `chain`. Measured once, when simplex starts ({@link initCache}), and
|
|
351746
|
+
* kept until it stops. A chain with no measurement yet, because it was added later or its
|
|
351747
|
+
* blocks could not be read at startup, is measured at its first bid.
|
|
351748
|
+
*
|
|
351749
|
+
* The nominal `Chain.blockTime` cannot be relied on alone: it goes stale when a chain
|
|
351750
|
+
* speeds up (BSC makes a block every 0.45s against a declared 0.75s) and some chains
|
|
351751
|
+
* declare none. Converting at a slower block time than the chain's ends a bid early, so
|
|
351752
|
+
* the faster of the measured and the declared figure is used, and a stalled or idle
|
|
351753
|
+
* stretch in the sample never shortens a bid.
|
|
351754
|
+
*
|
|
351755
|
+
* Blocks that cannot be read fall back to the declared figure, then to
|
|
351756
|
+
* {@link FALLBACK_BLOCK_TIME_SECONDS}. That answer is not kept.
|
|
351757
|
+
*/
|
|
351758
|
+
blockTimeSeconds(chain2) {
|
|
351759
|
+
const known3 = this.blockTimes.get(chain2);
|
|
351760
|
+
if (known3) return known3;
|
|
351761
|
+
const client = this.clientManager.getPublicClient(chain2);
|
|
351762
|
+
const declaredMs = client.chain?.blockTime;
|
|
351763
|
+
const declared = declaredMs ? declaredMs / 1e3 : void 0;
|
|
351764
|
+
const seconds = this.measureBlockTimeSeconds(client).then((measured) => declared ? Math.min(measured, declared) : measured).catch((err) => {
|
|
351765
|
+
this.blockTimes.delete(chain2);
|
|
351766
|
+
const fallback2 = declared ?? FALLBACK_BLOCK_TIME_SECONDS;
|
|
351767
|
+
this.logger.warn(
|
|
351768
|
+
{ err, chain: chain2, seconds: fallback2 },
|
|
351769
|
+
"Could not measure the block time; using the declared one"
|
|
351770
|
+
);
|
|
351771
|
+
return fallback2;
|
|
351772
|
+
});
|
|
351773
|
+
this.blockTimes.set(chain2, seconds);
|
|
351774
|
+
return seconds;
|
|
351775
|
+
}
|
|
351776
|
+
/** The average block time over the chain's last {@link BLOCK_TIME_SAMPLE_BLOCKS} blocks, in seconds. */
|
|
351777
|
+
async measureBlockTimeSeconds(client) {
|
|
351778
|
+
const head = await client.getBlock({ blockTag: "latest" });
|
|
351779
|
+
const span = head.number < BLOCK_TIME_SAMPLE_BLOCKS ? head.number : BLOCK_TIME_SAMPLE_BLOCKS;
|
|
351780
|
+
const tail = await client.getBlock({ blockNumber: head.number - span });
|
|
351781
|
+
const measured = Number(head.timestamp - tail.timestamp) / Number(span);
|
|
351782
|
+
if (!Number.isFinite(measured) || measured <= 0) {
|
|
351783
|
+
throw new Error(`${span} blocks span ${head.timestamp - tail.timestamp}s`);
|
|
351784
|
+
}
|
|
351785
|
+
return measured;
|
|
351786
|
+
}
|
|
351571
351787
|
/**
|
|
351572
351788
|
* Builds the signed, never-executed UserOperation that carries one limit order
|
|
351573
351789
|
* to the HyperFX orderbook.
|
|
@@ -351751,6 +351967,8 @@ init_Logger();
|
|
|
351751
351967
|
var FALLBACK_VERIFICATION_GAS_LIMIT = 250000n;
|
|
351752
351968
|
var FALLBACK_CALL_GAS_LIMIT = 1500000n;
|
|
351753
351969
|
var FALLBACK_PRE_VERIFICATION_GAS = 150000n;
|
|
351970
|
+
var PRIORITY_FEE_BUMP_PERCENT = 8n;
|
|
351971
|
+
var MAX_FEE_BUMP_PERCENT = 10n;
|
|
351754
351972
|
var UserOpSender = class {
|
|
351755
351973
|
constructor(clientManager, configService, signer) {
|
|
351756
351974
|
this.clientManager = clientManager;
|
|
@@ -351777,7 +351995,7 @@ var UserOpSender = class {
|
|
|
351777
351995
|
let auth;
|
|
351778
351996
|
let fees4;
|
|
351779
351997
|
try {
|
|
351780
|
-
fees4 = await this.getGasPrice(bundlerUrl, publicClient
|
|
351998
|
+
fees4 = await this.getGasPrice(bundlerUrl, publicClient);
|
|
351781
351999
|
const gasForPrefund = gas ?? {
|
|
351782
352000
|
verificationGasLimit: FALLBACK_VERIFICATION_GAS_LIMIT,
|
|
351783
352001
|
callGasLimit: FALLBACK_CALL_GAS_LIMIT,
|
|
@@ -351931,31 +352149,27 @@ var UserOpSender = class {
|
|
|
351931
352149
|
);
|
|
351932
352150
|
return userOp;
|
|
351933
352151
|
}
|
|
351934
|
-
/**
|
|
351935
|
-
|
|
351936
|
-
|
|
351937
|
-
|
|
351938
|
-
|
|
351939
|
-
|
|
351940
|
-
|
|
351941
|
-
|
|
351942
|
-
|
|
351943
|
-
|
|
351944
|
-
|
|
351945
|
-
|
|
351946
|
-
|
|
351947
|
-
|
|
351948
|
-
|
|
351949
|
-
|
|
351950
|
-
|
|
351951
|
-
|
|
351952
|
-
|
|
351953
|
-
|
|
351954
|
-
|
|
351955
|
-
return { maxFeePerGas: bufferedBaseFee + maxPriorityFeePerGas, maxPriorityFeePerGas };
|
|
351956
|
-
}
|
|
351957
|
-
const gasPrice = await publicClient.getGasPrice();
|
|
351958
|
-
return { maxFeePerGas: gasPrice + gasPrice * 10n / 100n, maxPriorityFeePerGas: gasPrice + gasPrice * 8n / 100n };
|
|
352152
|
+
/**
|
|
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.
|
|
352155
|
+
*/
|
|
352156
|
+
async getGasPrice(bundlerUrl, publicClient) {
|
|
352157
|
+
const [gasPrice, latestBlock] = await Promise.all([
|
|
352158
|
+
publicClient.getGasPrice(),
|
|
352159
|
+
publicClient.getBlock({ blockTag: "latest" })
|
|
352160
|
+
]);
|
|
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
|
+
);
|
|
351959
352173
|
}
|
|
351960
352174
|
async sendBundlerRpc(bundlerUrl, method, params) {
|
|
351961
352175
|
const response = await fetch(bundlerUrl, {
|
|
@@ -367374,8 +367588,8 @@ var validateBalanceForTransaction = async (params) => {
|
|
|
367374
367588
|
}, operationContext);
|
|
367375
367589
|
const balance = await balancePrepared.execute();
|
|
367376
367590
|
if (BigInt(balance) < BigInt(amount)) {
|
|
367377
|
-
const
|
|
367378
|
-
throw createInsufficientTokenBalanceError(
|
|
367591
|
+
const chainName2 = extractChainInfo(operationContext.chain).name;
|
|
367592
|
+
throw createInsufficientTokenBalanceError(chainName2, token, {
|
|
367379
367593
|
balance: balance.toString(),
|
|
367380
367594
|
amount,
|
|
367381
367595
|
tokenAddress,
|
|
@@ -367390,8 +367604,8 @@ var validateNativeBalanceForTransaction = async (params) => {
|
|
|
367390
367604
|
}, operationContext);
|
|
367391
367605
|
const balance = await balancePrepared.execute();
|
|
367392
367606
|
if (BigInt(balance) === 0n) {
|
|
367393
|
-
const
|
|
367394
|
-
throw createInsufficientGasError(
|
|
367607
|
+
const chainName2 = extractChainInfo(operationContext.chain).name;
|
|
367608
|
+
throw createInsufficientGasError(chainName2, {
|
|
367395
367609
|
balance: "0",
|
|
367396
367610
|
walletAddress: operationContext.address
|
|
367397
367611
|
});
|
|
@@ -386353,6 +386567,86 @@ init_FillerConfigService();
|
|
|
386353
386567
|
init_filler_toml();
|
|
386354
386568
|
init_defaults8();
|
|
386355
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
|
+
|
|
386356
386650
|
// src/orderbook/lifecycle.ts
|
|
386357
386651
|
init_esm_shims();
|
|
386358
386652
|
init_Logger();
|
|
@@ -387178,8 +387472,8 @@ async function bootFiller(config5, options) {
|
|
|
387178
387472
|
};
|
|
387179
387473
|
const configService = new FillerConfigService(resolvedChains, fillerConfigForService, options.loggers);
|
|
387180
387474
|
const chainConfigs2 = resolvedChains.map((chain2) => {
|
|
387181
|
-
const
|
|
387182
|
-
return configService.getChainConfig(
|
|
387475
|
+
const chainName2 = `EVM-${chain2.chainId}`;
|
|
387476
|
+
return configService.getChainConfig(chainName2);
|
|
387183
387477
|
});
|
|
387184
387478
|
let watchOnlyConfig;
|
|
387185
387479
|
const globalWatchOnly = options.watchOnlyOverride === true || config5.simplex.watchOnly === true;
|
|
@@ -387217,6 +387511,8 @@ async function bootFiller(config5, options) {
|
|
|
387217
387511
|
"A signer is required unless every chain is watch-only: pass `signer` to Simplex.start (privateKeySigner, secretPhraseSigner, turnkeySigner, mpcVaultSigner, viemSigner, or your own Signer implementation). Running the binary? Configure it under [simplex.signer]."
|
|
387218
387512
|
);
|
|
387219
387513
|
}
|
|
387514
|
+
logger8.info("Checking each bundler serves its chain's EntryPoint...");
|
|
387515
|
+
await assertBundlersServeEntryPoint(resolvedChains, configService, { watchOnly: watchOnlyConfig });
|
|
387220
387516
|
const chainClientManager = new ChainClientManager(configService, options.signer);
|
|
387221
387517
|
const runtimeSigner = chainClientManager.getSigner();
|
|
387222
387518
|
if (options.signer) {
|
|
@@ -387407,10 +387703,10 @@ async function bootFiller(config5, options) {
|
|
|
387407
387703
|
const token1 = {};
|
|
387408
387704
|
for (const pair of config5.pairs ?? []) {
|
|
387409
387705
|
if (normalizeSymbol(pair.token0) === normalizeSymbol(pair.token1)) continue;
|
|
387410
|
-
for (const
|
|
387411
|
-
const address = assetRegistry.getAddress(pair.token1,
|
|
387706
|
+
for (const chainName2 of configuredChainNames) {
|
|
387707
|
+
const address = assetRegistry.getAddress(pair.token1, chainName2);
|
|
387412
387708
|
if (!address) continue;
|
|
387413
|
-
const list = token1[
|
|
387709
|
+
const list = token1[chainName2] ?? (token1[chainName2] = []);
|
|
387414
387710
|
if (!list.includes(address)) list.push(address);
|
|
387415
387711
|
}
|
|
387416
387712
|
}
|
|
@@ -387815,6 +388111,7 @@ var MemoryLimitOrderStore = class {
|
|
|
387815
388111
|
status: "open",
|
|
387816
388112
|
commitment: null,
|
|
387817
388113
|
orderNonce: order.orderNonce ?? "0",
|
|
388114
|
+
entryPoint: null,
|
|
387818
388115
|
bookExpiresAt: null,
|
|
387819
388116
|
bookPrice: null,
|
|
387820
388117
|
lastError: null,
|
|
@@ -388457,7 +388754,7 @@ var OrderScanner = class _OrderScanner {
|
|
|
388457
388754
|
async addChainNow(chain2) {
|
|
388458
388755
|
if (this.closed) throw new Error("This OrderScanner is closed");
|
|
388459
388756
|
const rpcUrls = validateRpcUrls(chain2.rpcUrls);
|
|
388460
|
-
const chainId = chain2.chainId ?? (await resolveChainConfigs([{ rpcUrls
|
|
388757
|
+
const chainId = chain2.chainId ?? (await resolveChainConfigs([{ rpcUrls }], {
|
|
388461
388758
|
loggers: this.loggers,
|
|
388462
388759
|
tolerateUnreachable: true
|
|
388463
388760
|
}))[0].chainId;
|
|
@@ -388808,10 +389105,10 @@ var PairController = class {
|
|
|
388808
389105
|
if (assets && Object.keys(assets).length > 0) config5.assets = nextAssets;
|
|
388809
389106
|
if (normalizeSymbol(pair.token0) !== normalizeSymbol(pair.token1)) {
|
|
388810
389107
|
for (const chain2 of this.runtime.resolvedChains) {
|
|
388811
|
-
const
|
|
388812
|
-
const address = assetRegistry.getAddress(pair.token1,
|
|
389108
|
+
const chainName2 = formatChainKey(chain2.chainId);
|
|
389109
|
+
const address = assetRegistry.getAddress(pair.token1, chainName2);
|
|
388813
389110
|
if (!address) continue;
|
|
388814
|
-
const list = balanceTokens[
|
|
389111
|
+
const list = balanceTokens[chainName2] ?? (balanceTokens[chainName2] = []);
|
|
388815
389112
|
if (!list.includes(address)) list.push(address);
|
|
388816
389113
|
}
|
|
388817
389114
|
}
|
|
@@ -388890,10 +389187,7 @@ var ChainController = class {
|
|
|
388890
389187
|
async add(chain2) {
|
|
388891
389188
|
return this.serialise(async () => {
|
|
388892
389189
|
validateRpcUrls(chain2.rpcUrls);
|
|
388893
|
-
|
|
388894
|
-
throw new Error("A bundler URL is required to submit fill UserOperations");
|
|
388895
|
-
}
|
|
388896
|
-
const [resolved] = await resolveChainConfigs([{ rpcUrls: chain2.rpcUrls, bundlerUrl: chain2.bundlerUrl }]);
|
|
389190
|
+
const [resolved] = await resolveChainConfigs([{ rpcUrls: chain2.rpcUrls }]);
|
|
388897
389191
|
const { chainId } = resolved;
|
|
388898
389192
|
const { configService, config: config5, intentFiller } = this.runtime;
|
|
388899
389193
|
if (configService.getConfiguredChainIds().includes(chainId)) {
|
|
@@ -388916,12 +389210,13 @@ var ChainController = class {
|
|
|
388916
389210
|
`Chain ${chainId} cannot be added as filling: this solver was started without a signer. Restart with \`signer\` to fill.`
|
|
388917
389211
|
);
|
|
388918
389212
|
}
|
|
388919
|
-
configService.addChain(resolved);
|
|
388920
389213
|
const watchOnly = chain2.watchOnly ?? (this.runtime.signerless || this.runtime.globalWatchOnly);
|
|
389214
|
+
await assertBundlersServeEntryPoint([resolved], configService, { watchOnly: { [chainId]: watchOnly } });
|
|
389215
|
+
configService.addChain(resolved);
|
|
388921
389216
|
if (watchOnly) intentFiller.setWatchOnly(chainId, true);
|
|
388922
389217
|
try {
|
|
388923
389218
|
if (!inScanner) {
|
|
388924
|
-
await this.scanner.addChain({ rpcUrls: chain2.rpcUrls,
|
|
389219
|
+
await this.scanner.addChain({ rpcUrls: chain2.rpcUrls, chainId });
|
|
388925
389220
|
}
|
|
388926
389221
|
this.runtime.chainClientManager.invalidate(formatChainKey(chainId));
|
|
388927
389222
|
await intentFiller.addChain(configService.getChainConfig(formatChainKey(chainId)));
|
|
@@ -388938,7 +389233,7 @@ var ChainController = class {
|
|
|
388938
389233
|
this.runtime.confirmationPolicy.adopt(chainId, resolvedPolicy);
|
|
388939
389234
|
}
|
|
388940
389235
|
this.runtime.resolvedChains.push(resolved);
|
|
388941
|
-
config5.chains = [...config5.chains, { rpcUrls: chain2.rpcUrls
|
|
389236
|
+
config5.chains = [...config5.chains, { rpcUrls: chain2.rpcUrls }];
|
|
388942
389237
|
if (Object.keys(confirmationPolicies).length > 0) config5.confirmationPolicies = confirmationPolicies;
|
|
388943
389238
|
this.syncWatchOnlyToConfig();
|
|
388944
389239
|
await this.persist();
|
|
@@ -388983,9 +389278,7 @@ var ChainController = class {
|
|
|
388983
389278
|
validateRpcUrls(rpcUrls);
|
|
388984
389279
|
const index3 = this.runtime.resolvedChains.findIndex((chain2) => chain2.chainId === chainId);
|
|
388985
389280
|
if (index3 < 0) throw new Error(`Chain ${chainId} is not configured`);
|
|
388986
|
-
const [probed] = await resolveChainConfigs([
|
|
388987
|
-
{ rpcUrls, bundlerUrl: this.runtime.resolvedChains[index3].bundlerUrl ?? "" }
|
|
388988
|
-
]);
|
|
389281
|
+
const [probed] = await resolveChainConfigs([{ rpcUrls }]);
|
|
388989
389282
|
if (probed.chainId !== chainId) {
|
|
388990
389283
|
throw new Error(`Those endpoints answer for chain ${probed.chainId}, not ${chainId}`);
|
|
388991
389284
|
}
|
|
@@ -389004,17 +389297,6 @@ var ChainController = class {
|
|
|
389004
389297
|
await this.persist();
|
|
389005
389298
|
});
|
|
389006
389299
|
}
|
|
389007
|
-
async setBundlerUrl(chainId, bundlerUrl) {
|
|
389008
|
-
return this.serialise(async () => {
|
|
389009
|
-
if (!bundlerUrl?.trim()) throw new Error("A bundler URL is required");
|
|
389010
|
-
const index3 = this.runtime.resolvedChains.findIndex((chain2) => chain2.chainId === chainId);
|
|
389011
|
-
if (index3 < 0) throw new Error(`Chain ${chainId} is not configured`);
|
|
389012
|
-
this.runtime.configService.setBundlerUrl(chainId, bundlerUrl);
|
|
389013
|
-
this.runtime.resolvedChains[index3].bundlerUrl = bundlerUrl;
|
|
389014
|
-
this.runtime.config.chains[index3].bundlerUrl = bundlerUrl;
|
|
389015
|
-
await this.persist();
|
|
389016
|
-
});
|
|
389017
|
-
}
|
|
389018
389300
|
/** Monitor without filling. Takes effect on the next order. */
|
|
389019
389301
|
async setWatchOnly(chainId, watchOnly) {
|
|
389020
389302
|
return this.serialise(async () => {
|
|
@@ -389023,6 +389305,10 @@ var ChainController = class {
|
|
|
389023
389305
|
"Watch-only cannot be disabled: this solver was started without a signer. Restart with `signer` to fill."
|
|
389024
389306
|
);
|
|
389025
389307
|
}
|
|
389308
|
+
if (!watchOnly) {
|
|
389309
|
+
const chain2 = this.runtime.resolvedChains.find((resolved) => resolved.chainId === chainId);
|
|
389310
|
+
if (chain2) await assertBundlersServeEntryPoint([chain2], this.runtime.configService);
|
|
389311
|
+
}
|
|
389026
389312
|
this.runtime.intentFiller.setWatchOnly(chainId, watchOnly);
|
|
389027
389313
|
this.syncWatchOnlyToConfig();
|
|
389028
389314
|
await this.persist();
|
|
@@ -389891,6 +390177,7 @@ var LIMIT_ORDER_COLUMNS = `
|
|
|
389891
390177
|
status,
|
|
389892
390178
|
commitment,
|
|
389893
390179
|
order_nonce as orderNonce,
|
|
390180
|
+
entry_point as entryPoint,
|
|
389894
390181
|
book_expires_at as bookExpiresAt,
|
|
389895
390182
|
book_price as bookPrice,
|
|
389896
390183
|
last_error as lastError,
|
|
@@ -389927,6 +390214,7 @@ var SqliteLimitOrderStore = class {
|
|
|
389927
390214
|
status TEXT NOT NULL,
|
|
389928
390215
|
commitment TEXT,
|
|
389929
390216
|
order_nonce TEXT NOT NULL DEFAULT '0',
|
|
390217
|
+
entry_point TEXT,
|
|
389930
390218
|
book_expires_at TEXT,
|
|
389931
390219
|
book_price TEXT,
|
|
389932
390220
|
last_error TEXT,
|
|
@@ -389951,6 +390239,10 @@ var SqliteLimitOrderStore = class {
|
|
|
389951
390239
|
|
|
389952
390240
|
CREATE INDEX IF NOT EXISTS idx_limit_order_fills_order ON limit_order_fills(limit_order_id);
|
|
389953
390241
|
`);
|
|
390242
|
+
if (!columnNames(this.db, "limit_orders").has("entry_point")) {
|
|
390243
|
+
this.db.exec("ALTER TABLE limit_orders ADD COLUMN entry_point TEXT");
|
|
390244
|
+
this.logger.info({ column: "entry_point" }, "Migrated limit order storage schema");
|
|
390245
|
+
}
|
|
389954
390246
|
if (!columnNames(this.db, "limit_order_fills").has("amount_in")) {
|
|
389955
390247
|
this.db.exec("ALTER TABLE limit_order_fills ADD COLUMN amount_in TEXT");
|
|
389956
390248
|
this.logger.info({ column: "amount_in" }, "Migrated limit order fill schema");
|
|
@@ -390015,13 +390307,14 @@ var SqliteLimitOrderStore = class {
|
|
|
390015
390307
|
const result = this.db.prepare(`
|
|
390016
390308
|
UPDATE limit_orders
|
|
390017
390309
|
SET commitment = ?, book_expires_at = ?, book_price = ?, order_nonce = ?,
|
|
390018
|
-
status = ?, last_error = ?, updated_at = datetime('now')
|
|
390310
|
+
entry_point = ?, status = ?, last_error = ?, updated_at = datetime('now')
|
|
390019
390311
|
WHERE id = ?${statusGuard(only)}
|
|
390020
390312
|
`).run(
|
|
390021
390313
|
posting.commitment,
|
|
390022
390314
|
posting.bookExpiresAt,
|
|
390023
390315
|
posting.bookPrice,
|
|
390024
390316
|
posting.orderNonce,
|
|
390317
|
+
posting.entryPoint,
|
|
390025
390318
|
posting.status,
|
|
390026
390319
|
posting.lastError,
|
|
390027
390320
|
id2,
|