@hyperbridge/sdk 2.8.2 → 2.8.3
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/dist/browser/index.d.ts +237 -15
- package/dist/browser/index.js +388 -74
- package/dist/browser/index.js.map +1 -1
- package/dist/node/index.cjs +389 -72
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.d.cts +46 -6
- package/dist/node/index.d.ts +46 -6
- package/dist/node/index.js +388 -74
- package/dist/node/index.js.map +1 -1
- package/dist/node/{intents-helpers-D_km9I2f.d.cts → intents-helpers-CxCDx-hH.d.cts} +226 -13
- package/dist/node/{intents-helpers-D_km9I2f.d.ts → intents-helpers-CxCDx-hH.d.ts} +226 -13
- package/dist/node/intents-helpers.cjs +384 -39
- package/dist/node/intents-helpers.cjs.map +1 -1
- package/dist/node/intents-helpers.d.cts +1 -1
- package/dist/node/intents-helpers.d.ts +1 -1
- package/dist/node/intents-helpers.js +383 -40
- package/dist/node/intents-helpers.js.map +1 -1
- package/package.json +1 -1
package/dist/node/index.cjs
CHANGED
|
@@ -2767,18 +2767,25 @@ var chainConfigs = {
|
|
|
2767
2767
|
DAI: "0x1af3f329e8be154074d8769d1ffa4ee058b1dbc3",
|
|
2768
2768
|
USDC: "0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d",
|
|
2769
2769
|
USDT: "0x55d398326f99059ff775485246999027b3197955",
|
|
2770
|
-
EXT: "0x7C8c11ADb8EF7cd3CFa718008Ea048445C6E7209"
|
|
2770
|
+
EXT: "0x7C8c11ADb8EF7cd3CFa718008Ea048445C6E7209",
|
|
2771
|
+
cNGN: "0xa8AEA66B361a8d53e8865c62D142167Af28Af058"
|
|
2771
2772
|
},
|
|
2772
2773
|
tokenDecimals: {
|
|
2773
2774
|
USDC: 18,
|
|
2774
2775
|
USDT: 18,
|
|
2776
|
+
// 6, not 18 — cNGN keeps the same decimals it has on every other chain, unlike the
|
|
2777
|
+
// Binance-pegged stables above. Every phantom standard_amount and pool rate divides
|
|
2778
|
+
// by this, so the divergence from its neighbours here is load-bearing, not a typo.
|
|
2779
|
+
cNGN: 6,
|
|
2775
2780
|
EXT: 18
|
|
2776
2781
|
},
|
|
2777
2782
|
tokenStorageSlots: {
|
|
2778
2783
|
USDT: { balanceSlot: 1, allowanceSlot: 2 },
|
|
2779
2784
|
USDC: { balanceSlot: 1, allowanceSlot: 2 },
|
|
2780
2785
|
WETH: { balanceSlot: 3, allowanceSlot: 4 },
|
|
2781
|
-
DAI: { balanceSlot: 0, allowanceSlot: 0 }
|
|
2786
|
+
DAI: { balanceSlot: 0, allowanceSlot: 0 },
|
|
2787
|
+
cNGN: { balanceSlot: 201, allowanceSlot: 202 }
|
|
2788
|
+
// custom upgradeable layout, as on Base
|
|
2782
2789
|
},
|
|
2783
2790
|
addresses: {
|
|
2784
2791
|
IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
|
|
@@ -7810,6 +7817,27 @@ function encodeISMPMessage(message) {
|
|
|
7810
7817
|
}
|
|
7811
7818
|
var OFFCHAIN_BID_PREFIX = new TextEncoder().encode("intents::bid::");
|
|
7812
7819
|
var OFFCHAIN_PHANTOM_PREFIX = new TextEncoder().encode("intents::phantom::order::");
|
|
7820
|
+
var HYPERBRIDGE_TYPES_BUNDLE = {
|
|
7821
|
+
spec: {
|
|
7822
|
+
nexus: { hasher: utilCrypto.keccakAsU8a },
|
|
7823
|
+
gargantua: { hasher: utilCrypto.keccakAsU8a }
|
|
7824
|
+
}
|
|
7825
|
+
};
|
|
7826
|
+
var BASE_TIP = 1000000000n;
|
|
7827
|
+
var HTTP_CONNECT_TIMEOUT_MS = 2e4;
|
|
7828
|
+
var PHANTOM_POLL_INTERVAL_MS = 15e3;
|
|
7829
|
+
var GARGANTUA_PHANTOM_POLL_INTERVAL_MS = 6e3;
|
|
7830
|
+
function rejectAfter(ms, message) {
|
|
7831
|
+
return new Promise((_resolve, reject) => {
|
|
7832
|
+
const timer = setTimeout(() => reject(new Error(message)), ms);
|
|
7833
|
+
timer.unref?.();
|
|
7834
|
+
});
|
|
7835
|
+
}
|
|
7836
|
+
function deriveHttpUrl(wsUrl) {
|
|
7837
|
+
if (wsUrl.startsWith("wss://")) return `https://${wsUrl.slice("wss://".length)}`;
|
|
7838
|
+
if (wsUrl.startsWith("ws://")) return `http://${wsUrl.slice("ws://".length)}`;
|
|
7839
|
+
throw new Error(`Cannot derive an HTTP endpoint from a non-websocket url: ${wsUrl}`);
|
|
7840
|
+
}
|
|
7813
7841
|
var BidCodec = scaleTs.Struct({ filler: scaleTs.Bytes(32), user_op: scaleTs.Vector(scaleTs.u8) });
|
|
7814
7842
|
var PackedUserOperationCodec = scaleTs.Struct({
|
|
7815
7843
|
sender: scaleTs.Bytes(20),
|
|
@@ -7870,6 +7898,8 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
7870
7898
|
ownsConnection;
|
|
7871
7899
|
/** Cached result of whether the node exposes intents_* RPC methods */
|
|
7872
7900
|
hasIntentsRpc = null;
|
|
7901
|
+
/** The HTTP-backed api, connected on first use. Cleared after a failed attempt so it retries. */
|
|
7902
|
+
httpApi = null;
|
|
7873
7903
|
// Serialises every extrinsic submission on this instance's substrate account. All submit/retract
|
|
7874
7904
|
// methods funnel through signAndSendExtrinsic, each using the API's auto-nonce; fired in parallel
|
|
7875
7905
|
// (bids for orders on different chains, or several phantom orders in one interval) they would grab
|
|
@@ -7886,12 +7916,7 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
7886
7916
|
static async connect(wsUrl, substratePrivateKey) {
|
|
7887
7917
|
const api$1 = await api.ApiPromise.create({
|
|
7888
7918
|
provider: new api.WsProvider(wsUrl),
|
|
7889
|
-
typesBundle:
|
|
7890
|
-
spec: {
|
|
7891
|
-
nexus: { hasher: utilCrypto.keccakAsU8a },
|
|
7892
|
-
gargantua: { hasher: utilCrypto.keccakAsU8a }
|
|
7893
|
-
}
|
|
7894
|
-
}
|
|
7919
|
+
typesBundle: HYPERBRIDGE_TYPES_BUNDLE
|
|
7895
7920
|
});
|
|
7896
7921
|
return new _IntentsCoprocessor(api$1, substratePrivateKey, true);
|
|
7897
7922
|
}
|
|
@@ -7917,15 +7942,85 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
7917
7942
|
static fromApi(api, substratePrivateKey) {
|
|
7918
7943
|
return new _IntentsCoprocessor(api, substratePrivateKey, false);
|
|
7919
7944
|
}
|
|
7945
|
+
/**
|
|
7946
|
+
* The API every RPC query runs on: HTTP, connected to the same node as the websocket. Exposed so
|
|
7947
|
+
* callers query through this connection rather than opening one of their own.
|
|
7948
|
+
*
|
|
7949
|
+
* The split is by what each transport is for. Queries are one-shot request/response, which HTTP
|
|
7950
|
+
* serves without holding any state that can silently rot between calls. The websocket earns its
|
|
7951
|
+
* keep only where subscriptions do — watching a submitted extrinsic to inclusion.
|
|
7952
|
+
*/
|
|
7953
|
+
async queryApi() {
|
|
7954
|
+
return await this.http();
|
|
7955
|
+
}
|
|
7956
|
+
/**
|
|
7957
|
+
* The websocket API, exposed so callers share this one connection instead of opening a second
|
|
7958
|
+
* socket to the same node. Only needed for subscriptions; use {@link queryApi} to read.
|
|
7959
|
+
*/
|
|
7960
|
+
get apiConnection() {
|
|
7961
|
+
return this.api;
|
|
7962
|
+
}
|
|
7920
7963
|
/**
|
|
7921
7964
|
* Disconnects the underlying API connection if this instance owns it.
|
|
7922
|
-
* Only disconnects if created via `connect()`, not when using shared connections.
|
|
7965
|
+
* Only disconnects the websocket if created via `connect()`, not when using shared connections.
|
|
7966
|
+
* The HTTP api is always created here, so it is always ours to close.
|
|
7923
7967
|
*/
|
|
7924
7968
|
async disconnect() {
|
|
7969
|
+
const http4 = this.httpApi;
|
|
7970
|
+
this.httpApi = null;
|
|
7971
|
+
if (http4) {
|
|
7972
|
+
await http4.then((api) => api.disconnect()).catch(() => {
|
|
7973
|
+
});
|
|
7974
|
+
}
|
|
7925
7975
|
if (this.ownsConnection) {
|
|
7926
7976
|
await this.api.disconnect();
|
|
7927
7977
|
}
|
|
7928
7978
|
}
|
|
7979
|
+
/**
|
|
7980
|
+
* The HTTP api for this node, connected on first use. Every coprocessor has one — the endpoint
|
|
7981
|
+
* is derived from the websocket's own endpoint, so there is nothing to configure and nothing to
|
|
7982
|
+
* be absent.
|
|
7983
|
+
*
|
|
7984
|
+
* The connection attempt is bounded on both sides. `isReadyOrError` rejects on a failed
|
|
7985
|
+
* handshake, where plain `isReady` would simply never resolve, and the timeout covers an
|
|
7986
|
+
* endpoint that accepts the request and then goes quiet. An unbounded wait here would hang the
|
|
7987
|
+
* poll tick awaiting it, which is precisely the silent stall that polling exists to avoid. A
|
|
7988
|
+
* failed attempt is not cached, so the next call tries again.
|
|
7989
|
+
*/
|
|
7990
|
+
async http() {
|
|
7991
|
+
if (!this.httpApi) {
|
|
7992
|
+
const httpUrl = deriveHttpUrl(this.wsEndpoint());
|
|
7993
|
+
const api$1 = new api.ApiPromise({
|
|
7994
|
+
provider: new api.HttpProvider(httpUrl),
|
|
7995
|
+
typesBundle: HYPERBRIDGE_TYPES_BUNDLE,
|
|
7996
|
+
// A second connection to the node the ws api already reported on; its init warnings
|
|
7997
|
+
// would just be duplicates.
|
|
7998
|
+
noInitWarn: true
|
|
7999
|
+
});
|
|
8000
|
+
this.httpApi = Promise.race([
|
|
8001
|
+
api$1.isReadyOrError,
|
|
8002
|
+
rejectAfter(HTTP_CONNECT_TIMEOUT_MS, `HTTP RPC ${httpUrl} did not become ready`)
|
|
8003
|
+
]).catch(async (err) => {
|
|
8004
|
+
await api$1.disconnect().catch(() => {
|
|
8005
|
+
});
|
|
8006
|
+
this.httpApi = null;
|
|
8007
|
+
throw new Error(`HTTP RPC ${httpUrl} is unavailable: ${err instanceof Error ? err.message : err}`);
|
|
8008
|
+
});
|
|
8009
|
+
}
|
|
8010
|
+
return await this.httpApi;
|
|
8011
|
+
}
|
|
8012
|
+
/**
|
|
8013
|
+
* The endpoint the websocket provider is connected to. Read from the provider rather than
|
|
8014
|
+
* remembered from a constructor argument, so it is the one endpoint in use no matter which
|
|
8015
|
+
* factory built this instance.
|
|
8016
|
+
*/
|
|
8017
|
+
wsEndpoint() {
|
|
8018
|
+
const endpoint = this.api._rpcCore?.provider?.endpoint;
|
|
8019
|
+
if (!endpoint) {
|
|
8020
|
+
throw new Error("Cannot determine the Hyperbridge websocket endpoint to derive an HTTP endpoint from");
|
|
8021
|
+
}
|
|
8022
|
+
return endpoint;
|
|
8023
|
+
}
|
|
7929
8024
|
/**
|
|
7930
8025
|
* Creates a Substrate keypair from the configured private key.
|
|
7931
8026
|
* Supports hex seed (with or without 0x), mnemonic phrases, and URI derivation paths (//Alice).
|
|
@@ -7950,13 +8045,45 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
7950
8045
|
* concurrent calls never collide on the substrate account nonce — each extrinsic reaches a block
|
|
7951
8046
|
* (or is confirmed still pooled and returned as `pending`) before the next is signed; auto-nonce
|
|
7952
8047
|
* via `system.accountNextIndex` counts pooled extrinsics, so a pending one is never re-used.
|
|
8048
|
+
*
|
|
8049
|
+
* The extrinsic is built rather than passed in because the api it is built on decides where it
|
|
8050
|
+
* is signed and sent: a websocket that is down when the queue reaches this submission diverts it
|
|
8051
|
+
* to {@link sendViaHttp}, which needs the call bound to the HTTP api instead.
|
|
7953
8052
|
*/
|
|
7954
|
-
async signAndSendExtrinsic(
|
|
7955
|
-
const result = await this.submissionQueue.add(
|
|
7956
|
-
(
|
|
7957
|
-
|
|
8053
|
+
async signAndSendExtrinsic(build, maxRetries = 3, timeoutMs = 3e4) {
|
|
8054
|
+
const result = await this.submissionQueue.add(async () => {
|
|
8055
|
+
if (!this.api.isConnected) {
|
|
8056
|
+
try {
|
|
8057
|
+
return await this.sendViaHttp(await this.http(), build);
|
|
8058
|
+
} catch (err) {
|
|
8059
|
+
return { success: false, error: err instanceof Error ? err.message : String(err) };
|
|
8060
|
+
}
|
|
8061
|
+
}
|
|
8062
|
+
return await this.sendExtrinsicWithRetries(build(this.api), maxRetries, timeoutMs);
|
|
8063
|
+
});
|
|
7958
8064
|
return result ?? { success: false, error: "Submission queue returned no result" };
|
|
7959
8065
|
}
|
|
8066
|
+
/**
|
|
8067
|
+
* Last-resort submission for when the websocket is down at signing time. A bid is only worth
|
|
8068
|
+
* anything inside its window, so waiting for a reconnect usually means not bidding at all.
|
|
8069
|
+
*
|
|
8070
|
+
* HTTP has no subscriptions, so this is `author_submitExtrinsic`: the node accepts the extrinsic
|
|
8071
|
+
* into its pool and returns its hash, and nothing further is observable from here. That is
|
|
8072
|
+
* exactly the `pending` contract — in flight, outcome unknown, do not re-sign — so the result
|
|
8073
|
+
* says so rather than claiming a success it cannot see.
|
|
8074
|
+
*
|
|
8075
|
+
* Only reached when the socket was already down before signing. A submission that got as far as
|
|
8076
|
+
* the pool over the websocket is never retried here: that is the duplicate-nonce race the
|
|
8077
|
+
* `pending` result exists to prevent.
|
|
8078
|
+
*/
|
|
8079
|
+
async sendViaHttp(api, build) {
|
|
8080
|
+
try {
|
|
8081
|
+
const hash = await build(api).signAndSend(this.getKeyPair(), { tip: BASE_TIP });
|
|
8082
|
+
return { success: false, pending: true, extrinsicHash: hash.toHex() };
|
|
8083
|
+
} catch (err) {
|
|
8084
|
+
return this.classifySubmissionError(err instanceof Error ? err : new Error(String(err)));
|
|
8085
|
+
}
|
|
8086
|
+
}
|
|
7960
8087
|
/**
|
|
7961
8088
|
* Signs and sends an extrinsic, handling status updates and errors.
|
|
7962
8089
|
* Implements retry logic with progressive tip increases for stuck transactions.
|
|
@@ -7970,10 +8097,9 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
7970
8097
|
*/
|
|
7971
8098
|
async sendExtrinsicWithRetries(extrinsic, maxRetries, timeoutMs) {
|
|
7972
8099
|
const keyPair = this.getKeyPair();
|
|
7973
|
-
const baseTip = 1000000000n;
|
|
7974
8100
|
let attempt = 0;
|
|
7975
8101
|
while (attempt < maxRetries) {
|
|
7976
|
-
const currentTip =
|
|
8102
|
+
const currentTip = BASE_TIP * BigInt(2 ** attempt);
|
|
7977
8103
|
attempt++;
|
|
7978
8104
|
try {
|
|
7979
8105
|
const result = await this.sendWithTimeout(extrinsic, keyPair, currentTip, timeoutMs);
|
|
@@ -8039,16 +8165,9 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
8039
8165
|
if (result.dispatchError && (result.status.isInBlock || result.status.isFinalized)) {
|
|
8040
8166
|
resolved = true;
|
|
8041
8167
|
clearTimeout(timeoutId);
|
|
8042
|
-
let errorMsg;
|
|
8043
|
-
if (result.dispatchError.isModule) {
|
|
8044
|
-
const decoded = this.api.registry.findMetaError(result.dispatchError.asModule);
|
|
8045
|
-
errorMsg = `Dispatch error: ${decoded.section}::${decoded.name}`;
|
|
8046
|
-
} else {
|
|
8047
|
-
errorMsg = `Dispatch error: ${result.dispatchError.toString()}`;
|
|
8048
|
-
}
|
|
8049
8168
|
resolve({
|
|
8050
8169
|
success: false,
|
|
8051
|
-
error:
|
|
8170
|
+
error: `Dispatch error: ${this.describeDispatchError(result.dispatchError)}`
|
|
8052
8171
|
});
|
|
8053
8172
|
} else if (result.status.isDropped || result.status.isInvalid || result.status.isUsurped || result.status.isFinalityTimeout) {
|
|
8054
8173
|
resolved = true;
|
|
@@ -8066,21 +8185,19 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
8066
8185
|
if (interrupted) {
|
|
8067
8186
|
const [indexCodec, dispatchError] = interrupted.event.data;
|
|
8068
8187
|
if (Number(indexCodec.toString()) === 0) {
|
|
8069
|
-
|
|
8070
|
-
|
|
8071
|
-
|
|
8072
|
-
|
|
8073
|
-
} else {
|
|
8074
|
-
errorMsg = `Dispatch error: batch interrupted (${dispatchError?.toString()})`;
|
|
8075
|
-
}
|
|
8076
|
-
resolve({ success: false, error: errorMsg });
|
|
8188
|
+
resolve({
|
|
8189
|
+
success: false,
|
|
8190
|
+
error: `Dispatch error: ${this.describeDispatchError(dispatchError)}`
|
|
8191
|
+
});
|
|
8077
8192
|
return;
|
|
8078
8193
|
}
|
|
8079
8194
|
}
|
|
8080
8195
|
resolve({
|
|
8081
8196
|
success: true,
|
|
8082
8197
|
blockHash: (result.status.isInBlock ? result.status.asInBlock : result.status.asFinalized).toHex(),
|
|
8083
|
-
extrinsicHash: extrinsic.hash.toHex()
|
|
8198
|
+
extrinsicHash: extrinsic.hash.toHex(),
|
|
8199
|
+
// Carried so a batch caller can attribute each item's outcome.
|
|
8200
|
+
events: result.events
|
|
8084
8201
|
});
|
|
8085
8202
|
}
|
|
8086
8203
|
}).then((unsub) => {
|
|
@@ -8107,8 +8224,7 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
8107
8224
|
*/
|
|
8108
8225
|
async submitBid(commitment, userOp) {
|
|
8109
8226
|
try {
|
|
8110
|
-
|
|
8111
|
-
return await this.signAndSendExtrinsic(extrinsic);
|
|
8227
|
+
return await this.signAndSendExtrinsic((api) => api.tx.intentsCoprocessor.placeBid(commitment, userOp));
|
|
8112
8228
|
} catch (error) {
|
|
8113
8229
|
return {
|
|
8114
8230
|
success: false,
|
|
@@ -8126,8 +8242,7 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
8126
8242
|
*/
|
|
8127
8243
|
async retractBid(commitment) {
|
|
8128
8244
|
try {
|
|
8129
|
-
|
|
8130
|
-
return await this.signAndSendExtrinsic(extrinsic);
|
|
8245
|
+
return await this.signAndSendExtrinsic((api) => api.tx.intentsCoprocessor.retractBid(commitment));
|
|
8131
8246
|
} catch (error) {
|
|
8132
8247
|
return {
|
|
8133
8248
|
success: false,
|
|
@@ -8157,11 +8272,12 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
8157
8272
|
*/
|
|
8158
8273
|
async submitBidWithRetraction(retractCommitment, bidCommitment, userOp) {
|
|
8159
8274
|
try {
|
|
8160
|
-
|
|
8161
|
-
|
|
8162
|
-
|
|
8163
|
-
|
|
8164
|
-
|
|
8275
|
+
return await this.signAndSendExtrinsic(
|
|
8276
|
+
(api) => api.tx.utility.batch([
|
|
8277
|
+
api.tx.intentsCoprocessor.placeBid(bidCommitment, userOp),
|
|
8278
|
+
api.tx.intentsCoprocessor.retractBid(retractCommitment)
|
|
8279
|
+
])
|
|
8280
|
+
);
|
|
8165
8281
|
} catch (error) {
|
|
8166
8282
|
return {
|
|
8167
8283
|
success: false,
|
|
@@ -8169,6 +8285,98 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
8169
8285
|
};
|
|
8170
8286
|
}
|
|
8171
8287
|
}
|
|
8288
|
+
/**
|
|
8289
|
+
* Places every phantom bid of one interval in a single extrinsic, retracting each chain's
|
|
8290
|
+
* previous bid alongside it.
|
|
8291
|
+
*
|
|
8292
|
+
* The pallet registers one phantom order per configured chain in the same block, so this is the
|
|
8293
|
+
* whole interval's set. Submitting them one at a time costs a block per chain: submissions are
|
|
8294
|
+
* serialised on the account nonce and each waits for inclusion, so the last chain's bid is many
|
|
8295
|
+
* blocks behind the first, against a bid window measured in tens of blocks. Batched, every bid
|
|
8296
|
+
* lands in the same block.
|
|
8297
|
+
*
|
|
8298
|
+
* Uses `utility.force_batch`, not `utility.batch`. `batch` stops at the first failing call, so
|
|
8299
|
+
* one rejected bid — a closed window, a duplicate, an insufficient deposit — would silently
|
|
8300
|
+
* drop every bid after it. `force_batch` runs them all and reports each outcome. It needs no
|
|
8301
|
+
* special origin: any signed account may call it, exactly like `batch`.
|
|
8302
|
+
*
|
|
8303
|
+
* @param bids - The bids to place; an empty list is a no-op
|
|
8304
|
+
* @returns Per-bid outcomes, in the order given
|
|
8305
|
+
*/
|
|
8306
|
+
async submitPhantomBids(bids) {
|
|
8307
|
+
if (bids.length === 0) return { bids: [] };
|
|
8308
|
+
const placeIndexByBid = [];
|
|
8309
|
+
let callCount = 0;
|
|
8310
|
+
for (const bid of bids) {
|
|
8311
|
+
placeIndexByBid.push(callCount);
|
|
8312
|
+
callCount += bid.retractCommitment ? 2 : 1;
|
|
8313
|
+
}
|
|
8314
|
+
const outcome = await this.signAndSendExtrinsic(
|
|
8315
|
+
(api) => api.tx.utility.forceBatch(
|
|
8316
|
+
bids.flatMap((bid) => {
|
|
8317
|
+
const calls = [api.tx.intentsCoprocessor.placeBid(bid.commitment, bid.userOp)];
|
|
8318
|
+
if (bid.retractCommitment) {
|
|
8319
|
+
calls.push(api.tx.intentsCoprocessor.retractBid(bid.retractCommitment));
|
|
8320
|
+
}
|
|
8321
|
+
return calls;
|
|
8322
|
+
})
|
|
8323
|
+
)
|
|
8324
|
+
);
|
|
8325
|
+
if (!outcome.success) {
|
|
8326
|
+
return {
|
|
8327
|
+
bids: bids.map((bid) => ({ commitment: bid.commitment, success: false, error: outcome.error })),
|
|
8328
|
+
pending: outcome.pending,
|
|
8329
|
+
extrinsicHash: outcome.extrinsicHash,
|
|
8330
|
+
error: outcome.error
|
|
8331
|
+
};
|
|
8332
|
+
}
|
|
8333
|
+
const items = this.readForceBatchItems(outcome.events ?? [], callCount);
|
|
8334
|
+
return {
|
|
8335
|
+
bids: bids.map((bid, index) => {
|
|
8336
|
+
const error = items.errors[placeIndexByBid[index]];
|
|
8337
|
+
return { commitment: bid.commitment, success: !error, error };
|
|
8338
|
+
}),
|
|
8339
|
+
blockHash: outcome.blockHash,
|
|
8340
|
+
extrinsicHash: outcome.extrinsicHash,
|
|
8341
|
+
error: items.error
|
|
8342
|
+
};
|
|
8343
|
+
}
|
|
8344
|
+
/**
|
|
8345
|
+
* Reads one outcome per call out of a force_batch's events.
|
|
8346
|
+
*
|
|
8347
|
+
* `ItemFailed` carries no index — pallet-utility emits exactly one `ItemCompleted` or
|
|
8348
|
+
* `ItemFailed` per call, in call order, so the k-th item event belongs to call k.
|
|
8349
|
+
*
|
|
8350
|
+
* A count that does not match the calls submitted means the events are not the ones assumed
|
|
8351
|
+
* here, and every attribution after the discrepancy would be off by one. The bids are then
|
|
8352
|
+
* reported as placed: a bid wrongly recorded as landed is retracted next interval and the
|
|
8353
|
+
* retraction harmlessly fails with `BidNotFound`, whereas one wrongly recorded as failed is
|
|
8354
|
+
* never retracted at all and leaves its deposit reserved.
|
|
8355
|
+
*/
|
|
8356
|
+
readForceBatchItems(events, callCount) {
|
|
8357
|
+
const errors = [];
|
|
8358
|
+
for (const { event } of events) {
|
|
8359
|
+
if (event.section !== "utility") continue;
|
|
8360
|
+
if (event.method === "ItemCompleted") errors.push(void 0);
|
|
8361
|
+
else if (event.method === "ItemFailed") errors.push(this.describeDispatchError(event.data[0]));
|
|
8362
|
+
}
|
|
8363
|
+
if (errors.length !== callCount) {
|
|
8364
|
+
return {
|
|
8365
|
+
errors: new Array(callCount).fill(void 0),
|
|
8366
|
+
error: `force_batch reported ${errors.length} item events for ${callCount} calls; outcomes not attributed`
|
|
8367
|
+
};
|
|
8368
|
+
}
|
|
8369
|
+
return { errors };
|
|
8370
|
+
}
|
|
8371
|
+
/** Renders a DispatchError as `pallet::Error`, falling back to its raw form. */
|
|
8372
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8373
|
+
describeDispatchError(dispatchError) {
|
|
8374
|
+
if (dispatchError?.isModule) {
|
|
8375
|
+
const decoded = this.api.registry.findMetaError(dispatchError.asModule);
|
|
8376
|
+
return `${decoded.section}::${decoded.name}`;
|
|
8377
|
+
}
|
|
8378
|
+
return dispatchError?.toString() ?? "unknown dispatch error";
|
|
8379
|
+
}
|
|
8172
8380
|
/**
|
|
8173
8381
|
* Fetches all bid storage entries for a given order commitment.
|
|
8174
8382
|
* Returns the on-chain data only (filler addresses and deposits).
|
|
@@ -8177,7 +8385,8 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
8177
8385
|
* @returns Array of BidStorageEntry objects
|
|
8178
8386
|
*/
|
|
8179
8387
|
async getBidStorageEntries(commitment) {
|
|
8180
|
-
const
|
|
8388
|
+
const api = await this.http();
|
|
8389
|
+
const entries = await api.query.intentsCoprocessor.bids.entries(commitment);
|
|
8181
8390
|
return entries.map(([storageKey, depositValue]) => ({
|
|
8182
8391
|
commitment,
|
|
8183
8392
|
filler: storageKey.args[1].toString(),
|
|
@@ -8207,9 +8416,8 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
8207
8416
|
* Single round-trip but does not include deposit amounts.
|
|
8208
8417
|
*/
|
|
8209
8418
|
async getBidsViaRpc(commitment) {
|
|
8210
|
-
const
|
|
8211
|
-
|
|
8212
|
-
]);
|
|
8419
|
+
const api$1 = await this.http();
|
|
8420
|
+
const result = await api$1._rpcCore.provider.send("intents_getBidsForOrder", [commitment]);
|
|
8213
8421
|
return result.map((entry) => {
|
|
8214
8422
|
const userOp = decodeUserOpScale(entry.user_op);
|
|
8215
8423
|
const filler = new api.Keyring({ type: "sr25519" }).encodeAddress(util.hexToU8a(entry.filler));
|
|
@@ -8221,7 +8429,8 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
8221
8429
|
* Slower but works on all nodes and includes deposit amounts.
|
|
8222
8430
|
*/
|
|
8223
8431
|
async getBidsViaStorage(commitment) {
|
|
8224
|
-
const
|
|
8432
|
+
const api = await this.http();
|
|
8433
|
+
const entries = await api.query.intentsCoprocessor.bids.entries(commitment);
|
|
8225
8434
|
if (entries.length === 0) return [];
|
|
8226
8435
|
const bidPromises = entries.map(async ([storageKey, depositValue]) => {
|
|
8227
8436
|
try {
|
|
@@ -8229,7 +8438,7 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
8229
8438
|
const deposit = BigInt(depositValue.toString());
|
|
8230
8439
|
const offchainKey = this.buildOffchainBidKey(commitment, filler);
|
|
8231
8440
|
const offchainKeyHex = util.u8aToHex(offchainKey);
|
|
8232
|
-
const offchainResult = await
|
|
8441
|
+
const offchainResult = await api.rpc.offchain.localStorageGet("PERSISTENT", offchainKeyHex);
|
|
8233
8442
|
if (!offchainResult || offchainResult.isNone) return null;
|
|
8234
8443
|
const bidData = offchainResult.unwrap().toHex();
|
|
8235
8444
|
const decoded = this.decodeBid(bidData);
|
|
@@ -8263,7 +8472,8 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
8263
8472
|
*/
|
|
8264
8473
|
async fetchPhantomOrder(commitment) {
|
|
8265
8474
|
const key = util.u8aConcat(OFFCHAIN_PHANTOM_PREFIX, util.hexToU8a(commitment));
|
|
8266
|
-
const
|
|
8475
|
+
const api = await this.http();
|
|
8476
|
+
const result = await api.rpc.offchain.localStorageGet("PERSISTENT", util.u8aToHex(key));
|
|
8267
8477
|
if (!result || result.isNone) return null;
|
|
8268
8478
|
const rawHex = result.unwrap().toHex();
|
|
8269
8479
|
if (rawHex === "0x" || rawHex === "0x00") return null;
|
|
@@ -8307,8 +8517,9 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
8307
8517
|
* Reads the PhantomOrderRegistered events emitted in a single block.
|
|
8308
8518
|
*/
|
|
8309
8519
|
async getPhantomOrdersInBlock(blockNumber) {
|
|
8310
|
-
const
|
|
8311
|
-
const
|
|
8520
|
+
const api = await this.http();
|
|
8521
|
+
const blockHash = await api.rpc.chain.getBlockHash(blockNumber);
|
|
8522
|
+
const apiAt = await api.at(blockHash);
|
|
8312
8523
|
const records = await apiAt.query.system.events();
|
|
8313
8524
|
const orders = [];
|
|
8314
8525
|
for (const { event } of records) {
|
|
@@ -8329,7 +8540,13 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
8329
8540
|
return orders;
|
|
8330
8541
|
}
|
|
8331
8542
|
/**
|
|
8332
|
-
* Polls for newly registered phantom orders, invoking the callback once per
|
|
8543
|
+
* Polls for newly registered phantom orders, invoking the callback once per block that carries
|
|
8544
|
+
* any, with all of that block's orders.
|
|
8545
|
+
*
|
|
8546
|
+
* Per block rather than per order because that is how the pallet writes them: one order per
|
|
8547
|
+
* configured chain, all registered in the same `on_initialize`. Delivering them together lets a
|
|
8548
|
+
* caller bid on the whole interval in one extrinsic (see {@link submitPhantomBids}) instead of
|
|
8549
|
+
* one per chain.
|
|
8333
8550
|
*
|
|
8334
8551
|
* Each tick reads the current head and scans every block between the last one processed and that
|
|
8335
8552
|
* head, so the block cursor — not the connection — determines what has been seen. This replaced a
|
|
@@ -8342,10 +8559,16 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
8342
8559
|
* cannot drop them, because the cursor only advances past a block whose events were actually
|
|
8343
8560
|
* read. Recovery replays the backlog.
|
|
8344
8561
|
*
|
|
8562
|
+
* Every read here goes over HTTP, never the websocket. Polling is a sequence of independent
|
|
8563
|
+
* one-shot requests with no state to lose between them, which is exactly what a stateless
|
|
8564
|
+
* transport does well: a request either answers or fails loudly on this tick, instead of a
|
|
8565
|
+
* socket that looks alive while delivering nothing. It also means a websocket outage does not
|
|
8566
|
+
* pause phantom bidding at all — the two transports fail independently.
|
|
8567
|
+
*
|
|
8345
8568
|
* Returns a function that stops polling.
|
|
8346
8569
|
*/
|
|
8347
8570
|
pollPhantomOrders(callback, options = {}) {
|
|
8348
|
-
const { intervalMs
|
|
8571
|
+
const { intervalMs, maxBlocksPerPoll = 500, lookbackBlocks = 0, onError } = options;
|
|
8349
8572
|
let cursor = null;
|
|
8350
8573
|
let inFlight = false;
|
|
8351
8574
|
let stopped = false;
|
|
@@ -8353,7 +8576,7 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
8353
8576
|
if (inFlight || stopped) return;
|
|
8354
8577
|
inFlight = true;
|
|
8355
8578
|
try {
|
|
8356
|
-
const head = (await this.
|
|
8579
|
+
const head = (await (await this.http()).rpc.chain.getHeader()).number.toNumber();
|
|
8357
8580
|
if (cursor === null) {
|
|
8358
8581
|
cursor = Math.max(head - 1 - lookbackBlocks, -1);
|
|
8359
8582
|
}
|
|
@@ -8362,7 +8585,7 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
8362
8585
|
for (let blockNumber = cursor + 1; blockNumber <= to; blockNumber++) {
|
|
8363
8586
|
if (stopped) return;
|
|
8364
8587
|
const orders = await this.getPhantomOrdersInBlock(blockNumber);
|
|
8365
|
-
|
|
8588
|
+
if (orders.length > 0) callback(orders);
|
|
8366
8589
|
cursor = blockNumber;
|
|
8367
8590
|
}
|
|
8368
8591
|
} catch (err) {
|
|
@@ -8372,12 +8595,31 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
8372
8595
|
}
|
|
8373
8596
|
};
|
|
8374
8597
|
void tick();
|
|
8375
|
-
|
|
8598
|
+
let timer = null;
|
|
8599
|
+
const startTimer = (ms) => {
|
|
8600
|
+
if (stopped) return;
|
|
8601
|
+
timer = setInterval(() => void tick(), ms);
|
|
8602
|
+
};
|
|
8603
|
+
if (intervalMs !== void 0) startTimer(intervalMs);
|
|
8604
|
+
else void this.phantomPollIntervalMs().then(startTimer);
|
|
8376
8605
|
return () => {
|
|
8377
8606
|
stopped = true;
|
|
8378
|
-
clearInterval(timer);
|
|
8607
|
+
if (timer) clearInterval(timer);
|
|
8379
8608
|
};
|
|
8380
8609
|
}
|
|
8610
|
+
/**
|
|
8611
|
+
* The poll cadence for the runtime this instance is connected to: Gargantua polls every block,
|
|
8612
|
+
* everything else every 15s. Falls back to the slower cadence if the runtime cannot be read,
|
|
8613
|
+
* since an unreachable node is the poll's problem to report, not the cadence lookup's.
|
|
8614
|
+
*/
|
|
8615
|
+
async phantomPollIntervalMs() {
|
|
8616
|
+
try {
|
|
8617
|
+
const specName = (await this.http()).runtimeVersion.specName.toString();
|
|
8618
|
+
return specName === "gargantua" ? GARGANTUA_PHANTOM_POLL_INTERVAL_MS : PHANTOM_POLL_INTERVAL_MS;
|
|
8619
|
+
} catch {
|
|
8620
|
+
return PHANTOM_POLL_INTERVAL_MS;
|
|
8621
|
+
}
|
|
8622
|
+
}
|
|
8381
8623
|
};
|
|
8382
8624
|
var TronChain = class _TronChain {
|
|
8383
8625
|
constructor(params, evm) {
|
|
@@ -15179,6 +15421,12 @@ var CryptoUtils = class _CryptoUtils {
|
|
|
15179
15421
|
* signing infrastructure (hardware wallets, MPC/TEE policy engines) instead
|
|
15180
15422
|
* of an opaque 32-byte digest.
|
|
15181
15423
|
*
|
|
15424
|
+
* The payload must be a standard self-describing `eth_signTypedData_v4`
|
|
15425
|
+
* payload — `EIP712Domain` listed in `types`, `chainId` as a JSON number —
|
|
15426
|
+
* because some signing backends (e.g. MPC Vault) hash it server-side from
|
|
15427
|
+
* the JSON rather than locally via viem. viem ignores both details when
|
|
15428
|
+
* hashing, so the digest is unchanged for local signers.
|
|
15429
|
+
*
|
|
15182
15430
|
* @param userOp - The packed UserOperation to sign (signature field ignored).
|
|
15183
15431
|
* @param entryPoint - Address of the EntryPoint v0.8 contract.
|
|
15184
15432
|
* @param chainId - Chain ID of the network on which the operation will execute.
|
|
@@ -15189,10 +15437,22 @@ var CryptoUtils = class _CryptoUtils {
|
|
|
15189
15437
|
domain: {
|
|
15190
15438
|
name: "ERC4337",
|
|
15191
15439
|
version: "1",
|
|
15192
|
-
chainId
|
|
15440
|
+
// Runtime number so JSON.stringify emits a canonical v4 numeric chainId for
|
|
15441
|
+
// server-side hashers; viem's uint256 type mapping wants bigint but its
|
|
15442
|
+
// runtime accepts numbers, hence the cast.
|
|
15443
|
+
chainId: Number(chainId),
|
|
15193
15444
|
verifyingContract: entryPoint
|
|
15194
15445
|
},
|
|
15446
|
+
// `as const`: viem derives the domain's TYPE from `types.EIP712Domain`, so the
|
|
15447
|
+
// entries must stay string literals — widened `string` fields make viem's
|
|
15448
|
+
// typed-data generics reject the payload at every call site.
|
|
15195
15449
|
types: {
|
|
15450
|
+
EIP712Domain: [
|
|
15451
|
+
{ name: "name", type: "string" },
|
|
15452
|
+
{ name: "version", type: "string" },
|
|
15453
|
+
{ name: "chainId", type: "uint256" },
|
|
15454
|
+
{ name: "verifyingContract", type: "address" }
|
|
15455
|
+
],
|
|
15196
15456
|
PackedUserOperation: [
|
|
15197
15457
|
{ name: "sender", type: "address" },
|
|
15198
15458
|
{ name: "nonce", type: "uint256" },
|
|
@@ -19210,14 +19470,34 @@ var IntentGateway = class _IntentGateway {
|
|
|
19210
19470
|
}
|
|
19211
19471
|
}
|
|
19212
19472
|
};
|
|
19473
|
+
|
|
19474
|
+
// src/protocols/intents/phantom-aggregation.ts
|
|
19213
19475
|
var FILL_ORDER_ABI = IntentGatewayV2_default.ABI;
|
|
19214
|
-
var
|
|
19215
|
-
var
|
|
19216
|
-
|
|
19217
|
-
|
|
19218
|
-
|
|
19476
|
+
var DECLARATION_V1 = 1;
|
|
19477
|
+
var DECLARATION_V2 = 2;
|
|
19478
|
+
var MAX_DECLARED_ENTRIES = 255;
|
|
19479
|
+
var MAX_TOKEN_ID_BYTES = 32;
|
|
19480
|
+
function tokenIdToBytes(tokenId) {
|
|
19481
|
+
if (tokenId < 0n) throw new Error(`Uniswap V4 tokenId cannot be negative: ${tokenId}`);
|
|
19482
|
+
const bytes = [];
|
|
19483
|
+
let rest = tokenId;
|
|
19484
|
+
while (rest > 0n) {
|
|
19485
|
+
bytes.unshift(Number(rest & 0xffn));
|
|
19486
|
+
rest >>= 8n;
|
|
19487
|
+
}
|
|
19488
|
+
return bytes.length > 0 ? bytes : [0];
|
|
19489
|
+
}
|
|
19490
|
+
function encodePhantomBidDeclaration(declaration) {
|
|
19491
|
+
const chains2 = declaration.acceptedSourceChains ?? [];
|
|
19492
|
+
const positions = declaration.uniswapV4Positions ?? [];
|
|
19493
|
+
if (chains2.length > MAX_DECLARED_ENTRIES) {
|
|
19494
|
+
throw new Error(`Cannot declare more than ${MAX_DECLARED_ENTRIES} source chains`);
|
|
19495
|
+
}
|
|
19496
|
+
if (positions.length > MAX_DECLARED_ENTRIES) {
|
|
19497
|
+
throw new Error(`Cannot declare more than ${MAX_DECLARED_ENTRIES} Uniswap V4 positions`);
|
|
19219
19498
|
}
|
|
19220
|
-
const
|
|
19499
|
+
const version = positions.length > 0 ? DECLARATION_V2 : DECLARATION_V1;
|
|
19500
|
+
const bytes = [version, chains2.length];
|
|
19221
19501
|
for (const chain of chains2) {
|
|
19222
19502
|
const encoded = util.stringToU8a(chain);
|
|
19223
19503
|
if (encoded.length === 0 || encoded.length > 255) {
|
|
@@ -19225,25 +19505,59 @@ function encodeAcceptedSourceChains(chains2) {
|
|
|
19225
19505
|
}
|
|
19226
19506
|
bytes.push(encoded.length, ...encoded);
|
|
19227
19507
|
}
|
|
19508
|
+
if (version === DECLARATION_V2) {
|
|
19509
|
+
bytes.push(positions.length);
|
|
19510
|
+
for (const tokenId of positions) {
|
|
19511
|
+
const encoded = tokenIdToBytes(tokenId);
|
|
19512
|
+
if (encoded.length > MAX_TOKEN_ID_BYTES) {
|
|
19513
|
+
throw new Error(`Uniswap V4 tokenId exceeds uint256: ${tokenId}`);
|
|
19514
|
+
}
|
|
19515
|
+
bytes.push(encoded.length, ...encoded);
|
|
19516
|
+
}
|
|
19517
|
+
}
|
|
19228
19518
|
return util.u8aToHex(new Uint8Array(bytes));
|
|
19229
19519
|
}
|
|
19230
|
-
function
|
|
19231
|
-
|
|
19520
|
+
function decodePhantomBidDeclaration(paymasterAndData) {
|
|
19521
|
+
const absent = { acceptedSources: null, uniswapV4Positions: [] };
|
|
19522
|
+
if (!paymasterAndData || !util.isHex(paymasterAndData)) return absent;
|
|
19232
19523
|
const bytes = util.hexToU8a(paymasterAndData);
|
|
19233
|
-
if (bytes.length < 2
|
|
19234
|
-
const
|
|
19524
|
+
if (bytes.length < 2) return absent;
|
|
19525
|
+
const version = bytes[0];
|
|
19526
|
+
if (version !== DECLARATION_V1 && version !== DECLARATION_V2) return absent;
|
|
19235
19527
|
const chains2 = [];
|
|
19236
19528
|
let offset = 2;
|
|
19237
|
-
for (let entry = 0; entry <
|
|
19238
|
-
if (offset >= bytes.length) return
|
|
19529
|
+
for (let entry = 0; entry < bytes[1]; entry++) {
|
|
19530
|
+
if (offset >= bytes.length) return absent;
|
|
19239
19531
|
const length = bytes[offset];
|
|
19240
19532
|
offset += 1;
|
|
19241
|
-
if (length === 0 || offset + length > bytes.length) return
|
|
19533
|
+
if (length === 0 || offset + length > bytes.length) return absent;
|
|
19242
19534
|
chains2.push(util.u8aToString(bytes.subarray(offset, offset + length)));
|
|
19243
19535
|
offset += length;
|
|
19244
19536
|
}
|
|
19245
|
-
|
|
19246
|
-
|
|
19537
|
+
const positions = [];
|
|
19538
|
+
if (version === DECLARATION_V2) {
|
|
19539
|
+
if (offset >= bytes.length) return absent;
|
|
19540
|
+
const count = bytes[offset];
|
|
19541
|
+
offset += 1;
|
|
19542
|
+
for (let entry = 0; entry < count; entry++) {
|
|
19543
|
+
if (offset >= bytes.length) return absent;
|
|
19544
|
+
const length = bytes[offset];
|
|
19545
|
+
offset += 1;
|
|
19546
|
+
if (length === 0 || length > MAX_TOKEN_ID_BYTES || offset + length > bytes.length) return absent;
|
|
19547
|
+
let tokenId = 0n;
|
|
19548
|
+
for (const byte of bytes.subarray(offset, offset + length)) tokenId = tokenId << 8n | BigInt(byte);
|
|
19549
|
+
positions.push(tokenId);
|
|
19550
|
+
offset += length;
|
|
19551
|
+
}
|
|
19552
|
+
}
|
|
19553
|
+
if (offset !== bytes.length) return absent;
|
|
19554
|
+
return { acceptedSources: chains2, uniswapV4Positions: positions };
|
|
19555
|
+
}
|
|
19556
|
+
function encodeAcceptedSourceChains(chains2) {
|
|
19557
|
+
return encodePhantomBidDeclaration({ acceptedSourceChains: chains2 });
|
|
19558
|
+
}
|
|
19559
|
+
function decodeAcceptedSourceChains(paymasterAndData) {
|
|
19560
|
+
return decodePhantomBidDeclaration(paymasterAndData).acceptedSources;
|
|
19247
19561
|
}
|
|
19248
19562
|
FILL_ORDER_ABI.find(
|
|
19249
19563
|
(item) => item?.type === "function" && item?.name === "fillOrder"
|
|
@@ -23789,10 +24103,13 @@ exports.createEvmChain = createEvmChain;
|
|
|
23789
24103
|
exports.createQueryClient = createQueryClient;
|
|
23790
24104
|
exports.decodeAcceptedSourceChains = decodeAcceptedSourceChains;
|
|
23791
24105
|
exports.decodeERC7821ExecuteBatch = decodeERC7821ExecuteBatch;
|
|
24106
|
+
exports.decodePhantomBidDeclaration = decodePhantomBidDeclaration;
|
|
23792
24107
|
exports.decodeUserOpScale = decodeUserOpScale;
|
|
24108
|
+
exports.deriveHttpUrl = deriveHttpUrl;
|
|
23793
24109
|
exports.encodeAcceptedSourceChains = encodeAcceptedSourceChains;
|
|
23794
24110
|
exports.encodeERC7821ExecuteBatch = encodeERC7821ExecuteBatch;
|
|
23795
24111
|
exports.encodeISMPMessage = encodeISMPMessage;
|
|
24112
|
+
exports.encodePhantomBidDeclaration = encodePhantomBidDeclaration;
|
|
23796
24113
|
exports.encodeStateMachineId = encodeStateMachineId;
|
|
23797
24114
|
exports.encodeUserOpScale = encodeUserOpScale;
|
|
23798
24115
|
exports.encodeWithdrawalRequest = encodeWithdrawalRequest;
|