@hyperbridge/sdk 2.3.0 → 2.3.2
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 +65 -11
- package/dist/browser/index.js +338 -87
- package/dist/browser/index.js.map +1 -1
- package/dist/node/{IntentGatewayV2-C55Aitcb.d.cts → IntentGatewayV2-SB851bZs.d.cts} +41 -8
- package/dist/node/{IntentGatewayV2-C55Aitcb.d.ts → IntentGatewayV2-SB851bZs.d.ts} +41 -8
- package/dist/node/index.cjs +338 -87
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.d.cts +26 -5
- package/dist/node/index.d.ts +26 -5
- package/dist/node/index.js +338 -87
- package/dist/node/index.js.map +1 -1
- 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.map +1 -1
- package/package.json +2 -1
package/dist/browser/index.js
CHANGED
|
@@ -2150,7 +2150,7 @@ var ABI2 = [
|
|
|
2150
2150
|
{ internalType: "bytes", name: "source", type: "bytes" },
|
|
2151
2151
|
{ internalType: "bytes", name: "dest", type: "bytes" },
|
|
2152
2152
|
{ internalType: "uint64", name: "nonce", type: "uint64" },
|
|
2153
|
-
{ internalType: "
|
|
2153
|
+
{ internalType: "bytes", name: "from", type: "bytes" },
|
|
2154
2154
|
{ internalType: "uint64", name: "timeoutTimestamp", type: "uint64" },
|
|
2155
2155
|
{ internalType: "bytes[]", name: "keys", type: "bytes[]" },
|
|
2156
2156
|
{ internalType: "uint64", name: "height", type: "uint64" },
|
|
@@ -2217,7 +2217,7 @@ var ABI2 = [
|
|
|
2217
2217
|
{ internalType: "bytes", name: "source", type: "bytes" },
|
|
2218
2218
|
{ internalType: "bytes", name: "dest", type: "bytes" },
|
|
2219
2219
|
{ internalType: "uint64", name: "nonce", type: "uint64" },
|
|
2220
|
-
{ internalType: "
|
|
2220
|
+
{ internalType: "bytes", name: "from", type: "bytes" },
|
|
2221
2221
|
{ internalType: "uint64", name: "timeoutTimestamp", type: "uint64" },
|
|
2222
2222
|
{ internalType: "bytes[]", name: "keys", type: "bytes[]" },
|
|
2223
2223
|
{ internalType: "uint64", name: "height", type: "uint64" },
|
|
@@ -6442,28 +6442,60 @@ var EvmChain = class _EvmChain {
|
|
|
6442
6442
|
}
|
|
6443
6443
|
/**
|
|
6444
6444
|
* Query and return the encoded storage proof for the provided keys at the given height.
|
|
6445
|
+
*
|
|
6446
|
+
* Keys may be either:
|
|
6447
|
+
* - 32-byte storage slots — read from `address` (or the host contract when omitted), or
|
|
6448
|
+
* - 52-byte cross-chain GET keys encoded as `address(20) || slot(32)`, where the target
|
|
6449
|
+
* contract is embedded in the key. These may span multiple contracts.
|
|
6450
|
+
*
|
|
6445
6451
|
* @param {bigint} at - The block height at which to query the storage proof.
|
|
6446
6452
|
* @param {HexString[]} keys - The keys for which to query the storage proof.
|
|
6447
|
-
* @param {HexString} address - Optional contract address
|
|
6453
|
+
* @param {HexString} address - Optional contract address; forces all keys to be read as slots
|
|
6454
|
+
* of this contract. Omit to let 52-byte keys carry their own contract address.
|
|
6448
6455
|
* @returns {Promise<HexString>} The encoded storage proof.
|
|
6449
6456
|
*/
|
|
6450
6457
|
async queryStateProof(at, keys, address) {
|
|
6451
|
-
const
|
|
6452
|
-
|
|
6453
|
-
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
|
|
6460
|
-
|
|
6461
|
-
|
|
6458
|
+
const slotsByContract = /* @__PURE__ */ new Map();
|
|
6459
|
+
for (const key of keys) {
|
|
6460
|
+
let contract;
|
|
6461
|
+
let slot;
|
|
6462
|
+
if (address) {
|
|
6463
|
+
contract = address.toLowerCase();
|
|
6464
|
+
slot = key;
|
|
6465
|
+
} else if ((key.length - 2) / 2 === 52) {
|
|
6466
|
+
contract = key.slice(0, 42).toLowerCase();
|
|
6467
|
+
slot = `0x${key.slice(42)}`;
|
|
6468
|
+
} else {
|
|
6469
|
+
contract = this.params.host.toLowerCase();
|
|
6470
|
+
slot = key;
|
|
6471
|
+
}
|
|
6472
|
+
const slots = slotsByContract.get(contract) ?? [];
|
|
6473
|
+
slots.push(slot);
|
|
6474
|
+
slotsByContract.set(contract, slots);
|
|
6475
|
+
}
|
|
6476
|
+
const contracts = Array.from(slotsByContract.entries());
|
|
6477
|
+
const proofs = await Promise.all(
|
|
6478
|
+
contracts.map(([contract, slots]) => {
|
|
6479
|
+
const config = { address: contract, storageKeys: slots };
|
|
6480
|
+
if (!at) {
|
|
6481
|
+
config.blockTag = "latest";
|
|
6482
|
+
} else {
|
|
6483
|
+
config.blockNumber = at;
|
|
6484
|
+
}
|
|
6485
|
+
return this.publicClient.getProof(config);
|
|
6486
|
+
})
|
|
6487
|
+
);
|
|
6488
|
+
const contractProof = Array.from(new Set(flatten(proofs.map((proof) => proof.accountProof))));
|
|
6489
|
+
const storageProof = contracts.map(([contract], i) => {
|
|
6490
|
+
const flattened = Array.from(new Set(flatten(proofs[i].storageProof.map((item) => item.proof))));
|
|
6491
|
+
return [
|
|
6492
|
+
Array.from(hexToBytes(contract)),
|
|
6493
|
+
flattened.map((item) => Array.from(hexToBytes(item)))
|
|
6494
|
+
];
|
|
6495
|
+
});
|
|
6462
6496
|
const encoded = EvmStateProof.enc({
|
|
6463
|
-
contractProof:
|
|
6464
|
-
storageProof
|
|
6465
|
-
[Array.from(hexToBytes(config.address)), flattenedProof.map((item) => Array.from(hexToBytes(item)))]
|
|
6466
|
-
]
|
|
6497
|
+
contractProof: contractProof.map((item) => Array.from(hexToBytes(item))),
|
|
6498
|
+
storageProof
|
|
6467
6499
|
});
|
|
6468
6500
|
return toHex(encoded);
|
|
6469
6501
|
}
|
|
@@ -6793,15 +6825,20 @@ var EvmChain = class _EvmChain {
|
|
|
6793
6825
|
async quoteNative(request, fee) {
|
|
6794
6826
|
const totalFee = await this.quote(request) + fee;
|
|
6795
6827
|
const feeToken = await this.getFeeTokenWithDecimals();
|
|
6796
|
-
|
|
6828
|
+
const hostRouter = await this.publicClient.readContract({
|
|
6829
|
+
address: this.params.host,
|
|
6830
|
+
abi: evmHost_default.ABI,
|
|
6831
|
+
functionName: "uniswapV2Router"
|
|
6832
|
+
});
|
|
6833
|
+
return this.getAmountsIn(totalFee, feeToken.address, request.source, hostRouter);
|
|
6797
6834
|
}
|
|
6798
6835
|
/**
|
|
6799
6836
|
* Given a desired output amount of a token, returns how much native is needed as input.
|
|
6800
|
-
* Uses the chain's Uniswap V2 router: WETH → tokenOut path.
|
|
6837
|
+
* Uses the chain's Uniswap V2 router (or `router` when provided): WETH → tokenOut path.
|
|
6801
6838
|
*/
|
|
6802
|
-
async getAmountsIn(amountOut, tokenOutForQuote, chain) {
|
|
6839
|
+
async getAmountsIn(amountOut, tokenOutForQuote, chain, router) {
|
|
6803
6840
|
const chainId = chain ?? `EVM-${this.params.chainId}`;
|
|
6804
|
-
const v2Router = this.configService.getUniswapRouterV2Address(chainId);
|
|
6841
|
+
const v2Router = router ?? this.configService.getUniswapRouterV2Address(chainId);
|
|
6805
6842
|
const WETH = this.configService.getWrappedNativeAssetWithDecimals(chainId).asset;
|
|
6806
6843
|
const v2AmountIn = await this.publicClient.simulateContract({
|
|
6807
6844
|
address: v2Router,
|
|
@@ -7185,6 +7222,49 @@ var SubstrateChain = class _SubstrateChain {
|
|
|
7185
7222
|
const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
|
|
7186
7223
|
return item;
|
|
7187
7224
|
}
|
|
7225
|
+
/**
|
|
7226
|
+
* Returns the storage key for a response receipt in the child trie.
|
|
7227
|
+
* A response receipt is keyed by the originating *request* commitment.
|
|
7228
|
+
* @param {HexString} key - The request commitment (0x-prefixed H256 hex string)
|
|
7229
|
+
* @returns {HexString} The storage key as a hex string
|
|
7230
|
+
*/
|
|
7231
|
+
responseReceiptKey(key) {
|
|
7232
|
+
const prefix = new TextEncoder().encode("ResponseReceipts");
|
|
7233
|
+
const keyBytes = hexToBytes(key);
|
|
7234
|
+
return bytesToHex(new Uint8Array([...prefix, ...keyBytes]));
|
|
7235
|
+
}
|
|
7236
|
+
/**
|
|
7237
|
+
* Queries the response receipt for a request commitment. For a GET, Hyperbridge
|
|
7238
|
+
* produces the response as it processes the request, so the presence of a response
|
|
7239
|
+
* receipt indicates the request has already been delivered and handled.
|
|
7240
|
+
* @param {HexString} commitment - The originating request commitment to query.
|
|
7241
|
+
* @returns {Promise<HexString | undefined>} The receipt data if present, otherwise undefined.
|
|
7242
|
+
*/
|
|
7243
|
+
async queryResponseReceipt(commitment) {
|
|
7244
|
+
const prefix = toHex(":child_storage:default:ISMP");
|
|
7245
|
+
const key = this.responseReceiptKey(commitment);
|
|
7246
|
+
const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
|
|
7247
|
+
return item;
|
|
7248
|
+
}
|
|
7249
|
+
/**
|
|
7250
|
+
* Queries the state-machine commitment Hyperbridge holds for a counterparty chain at an
|
|
7251
|
+
* exact height — the `BoundedStateCommitments` map that `state_machine_commitment` (and thus
|
|
7252
|
+
* proof verification) reads. Returns the committed `stateRoot`, or undefined if Hyperbridge
|
|
7253
|
+
* has not finalized that chain at exactly that height.
|
|
7254
|
+
* @param {StateMachineHeight} height - The counterparty state machine id + height.
|
|
7255
|
+
* @returns {Promise<HexString | undefined>} The committed state root, or undefined if absent.
|
|
7256
|
+
*/
|
|
7257
|
+
async queryStateMachineCommitment(height) {
|
|
7258
|
+
if (!this.api) throw new Error("API not initialized");
|
|
7259
|
+
const id = {
|
|
7260
|
+
stateId: height.id.stateId,
|
|
7261
|
+
// on-chain StateMachineId encodes consensusStateId as [u8; 4]
|
|
7262
|
+
consensusStateId: toHex(toBytes(height.id.consensusStateId))
|
|
7263
|
+
};
|
|
7264
|
+
const commitment = await this.api.query.ismp.boundedStateCommitments(id, Number(height.height));
|
|
7265
|
+
if (commitment.isNone) return void 0;
|
|
7266
|
+
return commitment.toJSON()?.stateRoot;
|
|
7267
|
+
}
|
|
7188
7268
|
/**
|
|
7189
7269
|
* Returns the current timestamp of the chain.
|
|
7190
7270
|
* @returns {Promise<bigint>} The current timestamp.
|
|
@@ -7812,6 +7892,23 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
7812
7892
|
} else if (result.status.isInBlock || result.status.isFinalized) {
|
|
7813
7893
|
resolved = true;
|
|
7814
7894
|
clearTimeout(timeoutId);
|
|
7895
|
+
const interrupted = result.events.find(
|
|
7896
|
+
({ event }) => event.section === "utility" && event.method === "BatchInterrupted"
|
|
7897
|
+
);
|
|
7898
|
+
if (interrupted) {
|
|
7899
|
+
const [indexCodec, dispatchError] = interrupted.event.data;
|
|
7900
|
+
if (Number(indexCodec.toString()) === 0) {
|
|
7901
|
+
let errorMsg;
|
|
7902
|
+
if (dispatchError?.isModule) {
|
|
7903
|
+
const decoded = this.api.registry.findMetaError(dispatchError.asModule);
|
|
7904
|
+
errorMsg = `Dispatch error: ${decoded.section}::${decoded.name}`;
|
|
7905
|
+
} else {
|
|
7906
|
+
errorMsg = `Dispatch error: batch interrupted (${dispatchError?.toString()})`;
|
|
7907
|
+
}
|
|
7908
|
+
resolve({ success: false, error: errorMsg });
|
|
7909
|
+
return;
|
|
7910
|
+
}
|
|
7911
|
+
}
|
|
7815
7912
|
resolve({
|
|
7816
7913
|
success: true,
|
|
7817
7914
|
blockHash: (result.status.isInBlock ? result.status.asInBlock : result.status.asFinalized).toHex(),
|
|
@@ -7871,10 +7968,19 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
7871
7968
|
}
|
|
7872
7969
|
}
|
|
7873
7970
|
/**
|
|
7874
|
-
*
|
|
7875
|
-
*
|
|
7876
|
-
*
|
|
7877
|
-
*
|
|
7971
|
+
* Places a new bid and retracts a previous one in a single transaction via utility.batch.
|
|
7972
|
+
*
|
|
7973
|
+
* The new bid is the primary operation, so `placeBid` MUST run first. `utility.batch` is
|
|
7974
|
+
* non-atomic: a failing call interrupts the batch (via a BatchInterrupted event) without
|
|
7975
|
+
* reverting the calls that already succeeded. Placing first guarantees the new bid lands even
|
|
7976
|
+
* when the retraction then fails — which it routinely does, because a previous commitment's bid
|
|
7977
|
+
* may already be gone (or was itself never placed), making `retractBid` return `BidNotFound`.
|
|
7978
|
+
*
|
|
7979
|
+
* Ordering retraction first (the previous behaviour) caused a self-sustaining cascade: a
|
|
7980
|
+
* `BidNotFound` on the leading retract skipped the trailing `placeBid`, so the current bid never
|
|
7981
|
+
* landed, so the *next* interval's retract of that never-placed commitment also failed, and so
|
|
7982
|
+
* on — silently, because the batch extrinsic itself reports success. The deposit reclaim is
|
|
7983
|
+
* best-effort; landing the bid is not.
|
|
7878
7984
|
*
|
|
7879
7985
|
* @param retractCommitment - The order commitment of the bid to retract (bytes32)
|
|
7880
7986
|
* @param bidCommitment - The order commitment of the new bid (bytes32)
|
|
@@ -7884,8 +7990,8 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
7884
7990
|
async submitBidWithRetraction(retractCommitment, bidCommitment, userOp) {
|
|
7885
7991
|
try {
|
|
7886
7992
|
const batch = this.api.tx.utility.batch([
|
|
7887
|
-
this.api.tx.intentsCoprocessor.
|
|
7888
|
-
this.api.tx.intentsCoprocessor.
|
|
7993
|
+
this.api.tx.intentsCoprocessor.placeBid(bidCommitment, userOp),
|
|
7994
|
+
this.api.tx.intentsCoprocessor.retractBid(retractCommitment)
|
|
7889
7995
|
]);
|
|
7890
7996
|
return await this.signAndSendExtrinsic(batch);
|
|
7891
7997
|
} catch (error) {
|
|
@@ -9991,6 +10097,7 @@ var GetRequestClient = class {
|
|
|
9991
10097
|
const latestMetadata = request.statuses[request.statuses.length - 1];
|
|
9992
10098
|
status = maxBy([status, latestMetadata.status], (item) => REQUEST_STATUS_WEIGHTS[item]);
|
|
9993
10099
|
if (!status) return;
|
|
10100
|
+
let sourceFinalizedHeight;
|
|
9994
10101
|
while (true) {
|
|
9995
10102
|
switch (status) {
|
|
9996
10103
|
case RequestStatus.SOURCE: {
|
|
@@ -10002,6 +10109,7 @@ var GetRequestClient = class {
|
|
|
10002
10109
|
chain: this.ctx.config.hyperbridge.config.stateMachineId
|
|
10003
10110
|
})
|
|
10004
10111
|
});
|
|
10112
|
+
sourceFinalizedHeight = BigInt(sourceUpdate.height);
|
|
10005
10113
|
yield {
|
|
10006
10114
|
status: RequestStatus.SOURCE_FINALIZED,
|
|
10007
10115
|
metadata: {
|
|
@@ -10015,6 +10123,15 @@ var GetRequestClient = class {
|
|
|
10015
10123
|
break;
|
|
10016
10124
|
}
|
|
10017
10125
|
case RequestStatus.SOURCE_FINALIZED: {
|
|
10126
|
+
if (request.source !== this.ctx.config.hyperbridge.config.stateMachineId && sourceFinalizedHeight !== void 0) {
|
|
10127
|
+
try {
|
|
10128
|
+
await this.deliverToHyperbridge(request, sourceFinalizedHeight);
|
|
10129
|
+
} catch (error) {
|
|
10130
|
+
this.logger.warn(
|
|
10131
|
+
`Self-delivery to Hyperbridge failed; waiting for a relayer instead: ${error instanceof Error ? error.message : error}`
|
|
10132
|
+
);
|
|
10133
|
+
}
|
|
10134
|
+
}
|
|
10018
10135
|
request = await waitOrAbort(this.ctx, {
|
|
10019
10136
|
signal,
|
|
10020
10137
|
promise: () => this.queries.queryGetRequest(hash),
|
|
@@ -10035,7 +10152,10 @@ var GetRequestClient = class {
|
|
|
10035
10152
|
}
|
|
10036
10153
|
case RequestStatus.HYPERBRIDGE_DELIVERED: {
|
|
10037
10154
|
if (request.source === this.ctx.config.hyperbridge.config.stateMachineId) return;
|
|
10038
|
-
const response = await this.
|
|
10155
|
+
const response = await waitOrAbort(this.ctx, {
|
|
10156
|
+
signal,
|
|
10157
|
+
promise: () => this.queries.queryResponseByRequestId(hash)
|
|
10158
|
+
});
|
|
10039
10159
|
yield await this.streamFinalized(signal, request, 1, response);
|
|
10040
10160
|
status = RequestStatus.HYPERBRIDGE_FINALIZED;
|
|
10041
10161
|
break;
|
|
@@ -10065,6 +10185,102 @@ var GetRequestClient = class {
|
|
|
10065
10185
|
}
|
|
10066
10186
|
}
|
|
10067
10187
|
}
|
|
10188
|
+
/**
|
|
10189
|
+
* Self-delivers a GET request to Hyperbridge — the request→Hyperbridge hop that would
|
|
10190
|
+
* otherwise require an external relayer.
|
|
10191
|
+
*
|
|
10192
|
+
* Mirrors the relayer path (and {@link OrderCanceller}): prove the request commitment on
|
|
10193
|
+
* the source chain at the Hyperbridge-finalized source height, prove the requested keys on
|
|
10194
|
+
* the destination chain at the request's height, wait out the source challenge period, then
|
|
10195
|
+
* submit an unsigned `GetRequest` message. Source and destination may each be EVM or
|
|
10196
|
+
* substrate — proofs are built via the chain-agnostic {@link IChain} methods.
|
|
10197
|
+
*
|
|
10198
|
+
* Idempotent: returns early if Hyperbridge already holds the response receipt. The caller
|
|
10199
|
+
* wraps this best-effort, so a failure leaves the stream observing as before.
|
|
10200
|
+
*/
|
|
10201
|
+
async deliverToHyperbridge(request, sourceFinalizedHeight) {
|
|
10202
|
+
const sourceChain = this.ctx.config.source;
|
|
10203
|
+
const destChain = this.ctx.config.dest;
|
|
10204
|
+
const hyperbridge = this.ctx.config.hyperbridge;
|
|
10205
|
+
const commitment = getRequestCommitment({ ...request, keys: [...request.keys] });
|
|
10206
|
+
const retry = { maxRetries: 5, backoffMs: 2e3 };
|
|
10207
|
+
if (await withRetry(this.ctx, () => hyperbridge.queryResponseReceipt(commitment), retry)) return;
|
|
10208
|
+
this.logger.info(
|
|
10209
|
+
`Delivering GET ${commitment} to Hyperbridge (${request.source}@${sourceFinalizedHeight} \u2192 ${request.dest}@${request.height})`
|
|
10210
|
+
);
|
|
10211
|
+
const sourceProof = {
|
|
10212
|
+
height: sourceFinalizedHeight,
|
|
10213
|
+
stateMachine: request.source,
|
|
10214
|
+
consensusStateId: sourceChain.config.consensusStateId,
|
|
10215
|
+
proof: await withRetry(
|
|
10216
|
+
this.ctx,
|
|
10217
|
+
() => sourceChain.queryProof(
|
|
10218
|
+
{ Requests: [commitment] },
|
|
10219
|
+
this.ctx.config.hyperbridge.config.stateMachineId,
|
|
10220
|
+
sourceFinalizedHeight
|
|
10221
|
+
),
|
|
10222
|
+
retry
|
|
10223
|
+
)
|
|
10224
|
+
};
|
|
10225
|
+
this.logger.info(` \u2713 built source proof: ${(sourceProof.proof.length - 2) / 2} bytes @ ${request.source}#${sourceFinalizedHeight}`);
|
|
10226
|
+
const destCommitment = await withRetry(
|
|
10227
|
+
this.ctx,
|
|
10228
|
+
() => hyperbridge.queryStateMachineCommitment({
|
|
10229
|
+
id: {
|
|
10230
|
+
stateId: parseStateMachineId(request.dest).stateId,
|
|
10231
|
+
consensusStateId: destChain.config.consensusStateId
|
|
10232
|
+
},
|
|
10233
|
+
height: request.height
|
|
10234
|
+
}),
|
|
10235
|
+
retry
|
|
10236
|
+
);
|
|
10237
|
+
if (!destCommitment) {
|
|
10238
|
+
throw new Error(`Hyperbridge has no state commitment for ${request.dest} at height ${request.height}`);
|
|
10239
|
+
}
|
|
10240
|
+
const responseProof = {
|
|
10241
|
+
height: request.height,
|
|
10242
|
+
stateMachine: request.dest,
|
|
10243
|
+
consensusStateId: destChain.config.consensusStateId,
|
|
10244
|
+
proof: await withRetry(this.ctx, () => destChain.queryStateProof(request.height, [...request.keys]), retry)
|
|
10245
|
+
};
|
|
10246
|
+
this.logger.info(
|
|
10247
|
+
` \u2713 built response proof: ${(responseProof.proof.length - 2) / 2} bytes (${request.keys.length} key(s) @ ${request.dest}#${request.height})`
|
|
10248
|
+
);
|
|
10249
|
+
await withRetry(
|
|
10250
|
+
this.ctx,
|
|
10251
|
+
() => waitForChallengePeriod(hyperbridge, {
|
|
10252
|
+
height: sourceFinalizedHeight,
|
|
10253
|
+
id: {
|
|
10254
|
+
stateId: parseStateMachineId(request.source).stateId,
|
|
10255
|
+
consensusStateId: sourceChain.config.consensusStateId
|
|
10256
|
+
}
|
|
10257
|
+
}),
|
|
10258
|
+
retry
|
|
10259
|
+
);
|
|
10260
|
+
const message = {
|
|
10261
|
+
kind: "GetRequest",
|
|
10262
|
+
requests: [
|
|
10263
|
+
{
|
|
10264
|
+
source: request.source,
|
|
10265
|
+
dest: request.dest,
|
|
10266
|
+
nonce: request.nonce,
|
|
10267
|
+
from: request.from,
|
|
10268
|
+
timeoutTimestamp: request.timeoutTimestamp,
|
|
10269
|
+
keys: [...request.keys],
|
|
10270
|
+
height: request.height,
|
|
10271
|
+
context: request.context
|
|
10272
|
+
}
|
|
10273
|
+
],
|
|
10274
|
+
source: sourceProof,
|
|
10275
|
+
response: responseProof,
|
|
10276
|
+
signer: pad("0x")
|
|
10277
|
+
};
|
|
10278
|
+
this.logger.info(" \u2192 submitting GetRequest message (source + response proofs) to Hyperbridge\u2026");
|
|
10279
|
+
const result = await withRetry(this.ctx, () => hyperbridge.submitUnsigned(message), retry);
|
|
10280
|
+
this.logger.info(
|
|
10281
|
+
` \u2713 delivered GET ${commitment} in Hyperbridge block #${result.blockNumber} (tx ${result.transactionHash})`
|
|
10282
|
+
);
|
|
10283
|
+
}
|
|
10068
10284
|
/**
|
|
10069
10285
|
* Snapshot helper: returns the `HYPERBRIDGE_FINALIZED` event with source-chain
|
|
10070
10286
|
* calldata if prerequisites are met, or `undefined` if we're still waiting
|
|
@@ -10078,7 +10294,7 @@ var GetRequestClient = class {
|
|
|
10078
10294
|
const finality = await this.queries.queryStateMachineUpdateByHeight({
|
|
10079
10295
|
statemachineId: config.stateMachineId,
|
|
10080
10296
|
height: hyperbridgeDelivered.metadata.blockNumber,
|
|
10081
|
-
chain:
|
|
10297
|
+
chain: request.source
|
|
10082
10298
|
});
|
|
10083
10299
|
if (finality) {
|
|
10084
10300
|
const proof = await hyperbridge.queryProof(
|
|
@@ -10149,14 +10365,19 @@ var GetRequestClient = class {
|
|
|
10149
10365
|
],
|
|
10150
10366
|
signer: pad("0x")
|
|
10151
10367
|
});
|
|
10368
|
+
const hyperbridgeFinality = await this.queries.queryStateMachineUpdateByHeight({
|
|
10369
|
+
statemachineId: config.stateMachineId,
|
|
10370
|
+
height: hyperbridgeDelivered.metadata.blockNumber,
|
|
10371
|
+
chain: config.stateMachineId
|
|
10372
|
+
});
|
|
10373
|
+
if (!hyperbridgeFinality) return void 0;
|
|
10152
10374
|
return {
|
|
10153
10375
|
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10154
10376
|
metadata: {
|
|
10155
|
-
blockHash:
|
|
10156
|
-
blockNumber:
|
|
10157
|
-
transactionHash:
|
|
10158
|
-
|
|
10159
|
-
timestamp: hyperbridgeDelivered.metadata.timestamp,
|
|
10377
|
+
blockHash: hyperbridgeFinality.blockHash,
|
|
10378
|
+
blockNumber: hyperbridgeFinality.height,
|
|
10379
|
+
transactionHash: hyperbridgeFinality.transactionHash,
|
|
10380
|
+
timestamp: hyperbridgeFinality.timestamp,
|
|
10160
10381
|
calldata
|
|
10161
10382
|
}
|
|
10162
10383
|
};
|
|
@@ -10176,12 +10397,44 @@ var GetRequestClient = class {
|
|
|
10176
10397
|
const hyperbridge = this.ctx.config.hyperbridge;
|
|
10177
10398
|
const stateMachineId = this.ctx.config.hyperbridge.config.stateMachineId;
|
|
10178
10399
|
const neededHeight = BigInt(request.statuses[hyperbridgeDeliveredIndex].metadata.blockNumber);
|
|
10400
|
+
const consensusStateId = this.ctx.config.hyperbridge.config.consensusStateId;
|
|
10401
|
+
const encodeGetResponse = (height, proof2) => sourceChain.encode({
|
|
10402
|
+
kind: "GetResponse",
|
|
10403
|
+
proof: { stateMachine: stateMachineId, consensusStateId, proof: proof2, height },
|
|
10404
|
+
responses: [
|
|
10405
|
+
{
|
|
10406
|
+
get: request,
|
|
10407
|
+
values: request.keys.map((key, index) => ({
|
|
10408
|
+
key,
|
|
10409
|
+
value: response?.values[index] || "0x"
|
|
10410
|
+
}))
|
|
10411
|
+
}
|
|
10412
|
+
],
|
|
10413
|
+
signer: pad("0x")
|
|
10414
|
+
});
|
|
10179
10415
|
let finality = await this.queries.queryStateMachineUpdateByHeight({
|
|
10180
10416
|
statemachineId: stateMachineId,
|
|
10181
10417
|
height: Number(neededHeight),
|
|
10182
|
-
chain:
|
|
10418
|
+
chain: request.source
|
|
10183
10419
|
});
|
|
10184
|
-
if (
|
|
10420
|
+
if (finality) {
|
|
10421
|
+
const proof2 = await hyperbridge.queryProof(
|
|
10422
|
+
{ Responses: [response?.commitment] },
|
|
10423
|
+
request.source,
|
|
10424
|
+
BigInt(finality.height)
|
|
10425
|
+
);
|
|
10426
|
+
return {
|
|
10427
|
+
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10428
|
+
metadata: {
|
|
10429
|
+
blockHash: finality.blockHash,
|
|
10430
|
+
blockNumber: finality.height,
|
|
10431
|
+
transactionHash: finality.transactionHash,
|
|
10432
|
+
timestamp: finality.timestamp,
|
|
10433
|
+
calldata: encodeGetResponse(BigInt(finality.height), proof2)
|
|
10434
|
+
}
|
|
10435
|
+
};
|
|
10436
|
+
}
|
|
10437
|
+
if (sourceChain instanceof EvmChain) {
|
|
10185
10438
|
const hyperbridgeSubstrate = hyperbridge;
|
|
10186
10439
|
const currentEpoch = await sourceChain.currentEpoch();
|
|
10187
10440
|
const consensusResult = await waitOrAbort(this.ctx, {
|
|
@@ -10193,12 +10446,12 @@ var GetRequestClient = class {
|
|
|
10193
10446
|
request.source,
|
|
10194
10447
|
consensusResult.provenHeight
|
|
10195
10448
|
);
|
|
10196
|
-
const
|
|
10449
|
+
const calldata = sourceChain.encode({
|
|
10197
10450
|
kind: "BatchConsensusAndGetResponse",
|
|
10198
10451
|
consensusProofs: consensusResult.proofs,
|
|
10199
10452
|
proof: {
|
|
10200
10453
|
stateMachine: stateMachineId,
|
|
10201
|
-
consensusStateId
|
|
10454
|
+
consensusStateId,
|
|
10202
10455
|
proof: proof2,
|
|
10203
10456
|
height: consensusResult.provenHeight
|
|
10204
10457
|
},
|
|
@@ -10213,20 +10466,7 @@ var GetRequestClient = class {
|
|
|
10213
10466
|
],
|
|
10214
10467
|
signer: pad("0x")
|
|
10215
10468
|
});
|
|
10216
|
-
|
|
10217
|
-
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10218
|
-
metadata: {
|
|
10219
|
-
blockHash: request.statuses[hyperbridgeDeliveredIndex].metadata.blockHash,
|
|
10220
|
-
blockNumber: Number(consensusResult.provenHeight),
|
|
10221
|
-
transactionHash: request.statuses[hyperbridgeDeliveredIndex].metadata.transactionHash,
|
|
10222
|
-
// @ts-ignore
|
|
10223
|
-
timestamp: request.statuses[hyperbridgeDeliveredIndex].metadata.timestamp,
|
|
10224
|
-
calldata: calldata2
|
|
10225
|
-
}
|
|
10226
|
-
};
|
|
10227
|
-
}
|
|
10228
|
-
if (!finality) {
|
|
10229
|
-
finality = await waitOrAbort(this.ctx, {
|
|
10469
|
+
const hyperbridgeFinality = await waitOrAbort(this.ctx, {
|
|
10230
10470
|
signal,
|
|
10231
10471
|
promise: () => this.queries.queryStateMachineUpdateByHeight({
|
|
10232
10472
|
statemachineId: stateMachineId,
|
|
@@ -10234,31 +10474,30 @@ var GetRequestClient = class {
|
|
|
10234
10474
|
chain: stateMachineId
|
|
10235
10475
|
})
|
|
10236
10476
|
});
|
|
10477
|
+
return {
|
|
10478
|
+
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10479
|
+
metadata: {
|
|
10480
|
+
blockHash: hyperbridgeFinality.blockHash,
|
|
10481
|
+
blockNumber: hyperbridgeFinality.height,
|
|
10482
|
+
transactionHash: hyperbridgeFinality.transactionHash,
|
|
10483
|
+
timestamp: hyperbridgeFinality.timestamp,
|
|
10484
|
+
calldata
|
|
10485
|
+
}
|
|
10486
|
+
};
|
|
10237
10487
|
}
|
|
10488
|
+
finality = await waitOrAbort(this.ctx, {
|
|
10489
|
+
signal,
|
|
10490
|
+
promise: () => this.queries.queryStateMachineUpdateByHeight({
|
|
10491
|
+
statemachineId: stateMachineId,
|
|
10492
|
+
height: Number(neededHeight),
|
|
10493
|
+
chain: request.source
|
|
10494
|
+
})
|
|
10495
|
+
});
|
|
10238
10496
|
const proof = await hyperbridge.queryProof(
|
|
10239
10497
|
{ Responses: [response?.commitment] },
|
|
10240
10498
|
request.source,
|
|
10241
10499
|
BigInt(finality.height)
|
|
10242
10500
|
);
|
|
10243
|
-
const calldata = sourceChain.encode({
|
|
10244
|
-
kind: "GetResponse",
|
|
10245
|
-
proof: {
|
|
10246
|
-
stateMachine: stateMachineId,
|
|
10247
|
-
consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
|
|
10248
|
-
proof,
|
|
10249
|
-
height: BigInt(finality.height)
|
|
10250
|
-
},
|
|
10251
|
-
responses: [
|
|
10252
|
-
{
|
|
10253
|
-
get: request,
|
|
10254
|
-
values: request.keys.map((key, index) => ({
|
|
10255
|
-
key,
|
|
10256
|
-
value: response?.values[index] || "0x"
|
|
10257
|
-
}))
|
|
10258
|
-
}
|
|
10259
|
-
],
|
|
10260
|
-
signer: pad("0x")
|
|
10261
|
-
});
|
|
10262
10501
|
return {
|
|
10263
10502
|
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10264
10503
|
metadata: {
|
|
@@ -10266,7 +10505,7 @@ var GetRequestClient = class {
|
|
|
10266
10505
|
blockNumber: finality.height,
|
|
10267
10506
|
transactionHash: finality.transactionHash,
|
|
10268
10507
|
timestamp: finality.timestamp,
|
|
10269
|
-
calldata
|
|
10508
|
+
calldata: encodeGetResponse(BigInt(finality.height), proof)
|
|
10270
10509
|
}
|
|
10271
10510
|
};
|
|
10272
10511
|
}
|
|
@@ -10769,7 +11008,7 @@ var PostRequestClient = class {
|
|
|
10769
11008
|
const finality = await this.queries.queryStateMachineUpdateByHeight({
|
|
10770
11009
|
statemachineId: config.stateMachineId,
|
|
10771
11010
|
height: hyperbridgeDelivered.metadata.blockNumber,
|
|
10772
|
-
chain:
|
|
11011
|
+
chain: request.dest
|
|
10773
11012
|
});
|
|
10774
11013
|
if (finality) {
|
|
10775
11014
|
const proof = await hyperbridge.queryProof(
|
|
@@ -10824,14 +11063,19 @@ var PostRequestClient = class {
|
|
|
10824
11063
|
requests: [request],
|
|
10825
11064
|
signer: pad("0x")
|
|
10826
11065
|
});
|
|
11066
|
+
const hyperbridgeFinality = await this.queries.queryStateMachineUpdateByHeight({
|
|
11067
|
+
statemachineId: config.stateMachineId,
|
|
11068
|
+
height: hyperbridgeDelivered.metadata.blockNumber,
|
|
11069
|
+
chain: config.stateMachineId
|
|
11070
|
+
});
|
|
11071
|
+
if (!hyperbridgeFinality) return void 0;
|
|
10827
11072
|
return {
|
|
10828
11073
|
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10829
11074
|
metadata: {
|
|
10830
|
-
blockHash:
|
|
10831
|
-
blockNumber:
|
|
10832
|
-
transactionHash:
|
|
10833
|
-
|
|
10834
|
-
timestamp: hyperbridgeDelivered.metadata.timestamp,
|
|
11075
|
+
blockHash: hyperbridgeFinality.blockHash,
|
|
11076
|
+
blockNumber: hyperbridgeFinality.height,
|
|
11077
|
+
transactionHash: hyperbridgeFinality.transactionHash,
|
|
11078
|
+
timestamp: hyperbridgeFinality.timestamp,
|
|
10835
11079
|
calldata
|
|
10836
11080
|
}
|
|
10837
11081
|
};
|
|
@@ -10854,7 +11098,7 @@ var PostRequestClient = class {
|
|
|
10854
11098
|
let finality = await this.queries.queryStateMachineUpdateByHeight({
|
|
10855
11099
|
statemachineId: stateMachineId,
|
|
10856
11100
|
height: Number(neededHeight),
|
|
10857
|
-
chain:
|
|
11101
|
+
chain: request.dest
|
|
10858
11102
|
});
|
|
10859
11103
|
if (!finality && destChain instanceof EvmChain) {
|
|
10860
11104
|
const hyperbridgeSubstrate = hyperbridge;
|
|
@@ -10882,14 +11126,21 @@ var PostRequestClient = class {
|
|
|
10882
11126
|
requests: [request],
|
|
10883
11127
|
signer: pad("0x")
|
|
10884
11128
|
});
|
|
11129
|
+
const hyperbridgeFinality = await waitOrAbort(this.ctx, {
|
|
11130
|
+
signal,
|
|
11131
|
+
promise: () => this.queries.queryStateMachineUpdateByHeight({
|
|
11132
|
+
statemachineId: stateMachineId,
|
|
11133
|
+
height: Number(neededHeight),
|
|
11134
|
+
chain: stateMachineId
|
|
11135
|
+
})
|
|
11136
|
+
});
|
|
10885
11137
|
return {
|
|
10886
11138
|
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10887
11139
|
metadata: {
|
|
10888
|
-
blockHash:
|
|
10889
|
-
blockNumber:
|
|
10890
|
-
transactionHash:
|
|
10891
|
-
|
|
10892
|
-
timestamp: request.statuses[hyperbridgeDeliveredIndex].metadata.timestamp,
|
|
11140
|
+
blockHash: hyperbridgeFinality.blockHash,
|
|
11141
|
+
blockNumber: hyperbridgeFinality.height,
|
|
11142
|
+
transactionHash: hyperbridgeFinality.transactionHash,
|
|
11143
|
+
timestamp: hyperbridgeFinality.timestamp,
|
|
10893
11144
|
calldata: calldata2
|
|
10894
11145
|
}
|
|
10895
11146
|
};
|
|
@@ -10900,7 +11151,7 @@ var PostRequestClient = class {
|
|
|
10900
11151
|
promise: () => this.queries.queryStateMachineUpdateByHeight({
|
|
10901
11152
|
statemachineId: stateMachineId,
|
|
10902
11153
|
height: Number(neededHeight),
|
|
10903
|
-
chain:
|
|
11154
|
+
chain: request.dest
|
|
10904
11155
|
})
|
|
10905
11156
|
});
|
|
10906
11157
|
}
|
|
@@ -16802,9 +17053,9 @@ var GasEstimator = class {
|
|
|
16802
17053
|
from: this.ctx.source.configService.getIntentGatewayAddress(destChainId),
|
|
16803
17054
|
to: this.ctx.source.configService.getIntentGatewayAddress(sourceChainId)
|
|
16804
17055
|
};
|
|
17056
|
+
postRequestFeeInDestFeeToken = postRequestFeeInDestFeeToken * 1005n / 1000n;
|
|
16805
17057
|
let protocolFeeInNativeToken = await this.ctx.dest.quoteNative(postRequest, postRequestFeeInDestFeeToken).catch(() => 0n);
|
|
16806
17058
|
protocolFeeInNativeToken = protocolFeeInNativeToken * 1005n / 1000n;
|
|
16807
|
-
postRequestFeeInDestFeeToken = postRequestFeeInDestFeeToken * 1005n / 1000n;
|
|
16808
17059
|
return { postRequestFee: postRequestFeeInDestFeeToken, protocolFee: protocolFeeInNativeToken };
|
|
16809
17060
|
}
|
|
16810
17061
|
/**
|