@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/node/index.cjs
CHANGED
|
@@ -2111,7 +2111,7 @@ var ABI2 = [
|
|
|
2111
2111
|
{ internalType: "bytes", name: "source", type: "bytes" },
|
|
2112
2112
|
{ internalType: "bytes", name: "dest", type: "bytes" },
|
|
2113
2113
|
{ internalType: "uint64", name: "nonce", type: "uint64" },
|
|
2114
|
-
{ internalType: "
|
|
2114
|
+
{ internalType: "bytes", name: "from", type: "bytes" },
|
|
2115
2115
|
{ internalType: "uint64", name: "timeoutTimestamp", type: "uint64" },
|
|
2116
2116
|
{ internalType: "bytes[]", name: "keys", type: "bytes[]" },
|
|
2117
2117
|
{ internalType: "uint64", name: "height", type: "uint64" },
|
|
@@ -2178,7 +2178,7 @@ var ABI2 = [
|
|
|
2178
2178
|
{ internalType: "bytes", name: "source", type: "bytes" },
|
|
2179
2179
|
{ internalType: "bytes", name: "dest", type: "bytes" },
|
|
2180
2180
|
{ internalType: "uint64", name: "nonce", type: "uint64" },
|
|
2181
|
-
{ internalType: "
|
|
2181
|
+
{ internalType: "bytes", name: "from", type: "bytes" },
|
|
2182
2182
|
{ internalType: "uint64", name: "timeoutTimestamp", type: "uint64" },
|
|
2183
2183
|
{ internalType: "bytes[]", name: "keys", type: "bytes[]" },
|
|
2184
2184
|
{ internalType: "uint64", name: "height", type: "uint64" },
|
|
@@ -6403,28 +6403,60 @@ var EvmChain = class _EvmChain {
|
|
|
6403
6403
|
}
|
|
6404
6404
|
/**
|
|
6405
6405
|
* Query and return the encoded storage proof for the provided keys at the given height.
|
|
6406
|
+
*
|
|
6407
|
+
* Keys may be either:
|
|
6408
|
+
* - 32-byte storage slots — read from `address` (or the host contract when omitted), or
|
|
6409
|
+
* - 52-byte cross-chain GET keys encoded as `address(20) || slot(32)`, where the target
|
|
6410
|
+
* contract is embedded in the key. These may span multiple contracts.
|
|
6411
|
+
*
|
|
6406
6412
|
* @param {bigint} at - The block height at which to query the storage proof.
|
|
6407
6413
|
* @param {HexString[]} keys - The keys for which to query the storage proof.
|
|
6408
|
-
* @param {HexString} address - Optional contract address
|
|
6414
|
+
* @param {HexString} address - Optional contract address; forces all keys to be read as slots
|
|
6415
|
+
* of this contract. Omit to let 52-byte keys carry their own contract address.
|
|
6409
6416
|
* @returns {Promise<HexString>} The encoded storage proof.
|
|
6410
6417
|
*/
|
|
6411
6418
|
async queryStateProof(at, keys, address) {
|
|
6412
|
-
const
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
|
|
6419
|
-
|
|
6420
|
-
|
|
6421
|
-
|
|
6422
|
-
|
|
6419
|
+
const slotsByContract = /* @__PURE__ */ new Map();
|
|
6420
|
+
for (const key of keys) {
|
|
6421
|
+
let contract;
|
|
6422
|
+
let slot;
|
|
6423
|
+
if (address) {
|
|
6424
|
+
contract = address.toLowerCase();
|
|
6425
|
+
slot = key;
|
|
6426
|
+
} else if ((key.length - 2) / 2 === 52) {
|
|
6427
|
+
contract = key.slice(0, 42).toLowerCase();
|
|
6428
|
+
slot = `0x${key.slice(42)}`;
|
|
6429
|
+
} else {
|
|
6430
|
+
contract = this.params.host.toLowerCase();
|
|
6431
|
+
slot = key;
|
|
6432
|
+
}
|
|
6433
|
+
const slots = slotsByContract.get(contract) ?? [];
|
|
6434
|
+
slots.push(slot);
|
|
6435
|
+
slotsByContract.set(contract, slots);
|
|
6436
|
+
}
|
|
6437
|
+
const contracts = Array.from(slotsByContract.entries());
|
|
6438
|
+
const proofs = await Promise.all(
|
|
6439
|
+
contracts.map(([contract, slots]) => {
|
|
6440
|
+
const config = { address: contract, storageKeys: slots };
|
|
6441
|
+
if (!at) {
|
|
6442
|
+
config.blockTag = "latest";
|
|
6443
|
+
} else {
|
|
6444
|
+
config.blockNumber = at;
|
|
6445
|
+
}
|
|
6446
|
+
return this.publicClient.getProof(config);
|
|
6447
|
+
})
|
|
6448
|
+
);
|
|
6449
|
+
const contractProof = Array.from(new Set(lodashEs.flatten(proofs.map((proof) => proof.accountProof))));
|
|
6450
|
+
const storageProof = contracts.map(([contract], i) => {
|
|
6451
|
+
const flattened = Array.from(new Set(lodashEs.flatten(proofs[i].storageProof.map((item) => item.proof))));
|
|
6452
|
+
return [
|
|
6453
|
+
Array.from(viem.hexToBytes(contract)),
|
|
6454
|
+
flattened.map((item) => Array.from(viem.hexToBytes(item)))
|
|
6455
|
+
];
|
|
6456
|
+
});
|
|
6423
6457
|
const encoded = EvmStateProof.enc({
|
|
6424
|
-
contractProof:
|
|
6425
|
-
storageProof
|
|
6426
|
-
[Array.from(viem.hexToBytes(config.address)), flattenedProof.map((item) => Array.from(viem.hexToBytes(item)))]
|
|
6427
|
-
]
|
|
6458
|
+
contractProof: contractProof.map((item) => Array.from(viem.hexToBytes(item))),
|
|
6459
|
+
storageProof
|
|
6428
6460
|
});
|
|
6429
6461
|
return viem.toHex(encoded);
|
|
6430
6462
|
}
|
|
@@ -6754,15 +6786,20 @@ var EvmChain = class _EvmChain {
|
|
|
6754
6786
|
async quoteNative(request, fee) {
|
|
6755
6787
|
const totalFee = await this.quote(request) + fee;
|
|
6756
6788
|
const feeToken = await this.getFeeTokenWithDecimals();
|
|
6757
|
-
|
|
6789
|
+
const hostRouter = await this.publicClient.readContract({
|
|
6790
|
+
address: this.params.host,
|
|
6791
|
+
abi: evmHost_default.ABI,
|
|
6792
|
+
functionName: "uniswapV2Router"
|
|
6793
|
+
});
|
|
6794
|
+
return this.getAmountsIn(totalFee, feeToken.address, request.source, hostRouter);
|
|
6758
6795
|
}
|
|
6759
6796
|
/**
|
|
6760
6797
|
* Given a desired output amount of a token, returns how much native is needed as input.
|
|
6761
|
-
* Uses the chain's Uniswap V2 router: WETH → tokenOut path.
|
|
6798
|
+
* Uses the chain's Uniswap V2 router (or `router` when provided): WETH → tokenOut path.
|
|
6762
6799
|
*/
|
|
6763
|
-
async getAmountsIn(amountOut, tokenOutForQuote, chain) {
|
|
6800
|
+
async getAmountsIn(amountOut, tokenOutForQuote, chain, router) {
|
|
6764
6801
|
const chainId = chain ?? `EVM-${this.params.chainId}`;
|
|
6765
|
-
const v2Router = this.configService.getUniswapRouterV2Address(chainId);
|
|
6802
|
+
const v2Router = router ?? this.configService.getUniswapRouterV2Address(chainId);
|
|
6766
6803
|
const WETH = this.configService.getWrappedNativeAssetWithDecimals(chainId).asset;
|
|
6767
6804
|
const v2AmountIn = await this.publicClient.simulateContract({
|
|
6768
6805
|
address: v2Router,
|
|
@@ -7146,6 +7183,49 @@ var SubstrateChain = class _SubstrateChain {
|
|
|
7146
7183
|
const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
|
|
7147
7184
|
return item;
|
|
7148
7185
|
}
|
|
7186
|
+
/**
|
|
7187
|
+
* Returns the storage key for a response receipt in the child trie.
|
|
7188
|
+
* A response receipt is keyed by the originating *request* commitment.
|
|
7189
|
+
* @param {HexString} key - The request commitment (0x-prefixed H256 hex string)
|
|
7190
|
+
* @returns {HexString} The storage key as a hex string
|
|
7191
|
+
*/
|
|
7192
|
+
responseReceiptKey(key) {
|
|
7193
|
+
const prefix = new TextEncoder().encode("ResponseReceipts");
|
|
7194
|
+
const keyBytes = viem.hexToBytes(key);
|
|
7195
|
+
return viem.bytesToHex(new Uint8Array([...prefix, ...keyBytes]));
|
|
7196
|
+
}
|
|
7197
|
+
/**
|
|
7198
|
+
* Queries the response receipt for a request commitment. For a GET, Hyperbridge
|
|
7199
|
+
* produces the response as it processes the request, so the presence of a response
|
|
7200
|
+
* receipt indicates the request has already been delivered and handled.
|
|
7201
|
+
* @param {HexString} commitment - The originating request commitment to query.
|
|
7202
|
+
* @returns {Promise<HexString | undefined>} The receipt data if present, otherwise undefined.
|
|
7203
|
+
*/
|
|
7204
|
+
async queryResponseReceipt(commitment) {
|
|
7205
|
+
const prefix = viem.toHex(":child_storage:default:ISMP");
|
|
7206
|
+
const key = this.responseReceiptKey(commitment);
|
|
7207
|
+
const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
|
|
7208
|
+
return item;
|
|
7209
|
+
}
|
|
7210
|
+
/**
|
|
7211
|
+
* Queries the state-machine commitment Hyperbridge holds for a counterparty chain at an
|
|
7212
|
+
* exact height — the `BoundedStateCommitments` map that `state_machine_commitment` (and thus
|
|
7213
|
+
* proof verification) reads. Returns the committed `stateRoot`, or undefined if Hyperbridge
|
|
7214
|
+
* has not finalized that chain at exactly that height.
|
|
7215
|
+
* @param {StateMachineHeight} height - The counterparty state machine id + height.
|
|
7216
|
+
* @returns {Promise<HexString | undefined>} The committed state root, or undefined if absent.
|
|
7217
|
+
*/
|
|
7218
|
+
async queryStateMachineCommitment(height) {
|
|
7219
|
+
if (!this.api) throw new Error("API not initialized");
|
|
7220
|
+
const id = {
|
|
7221
|
+
stateId: height.id.stateId,
|
|
7222
|
+
// on-chain StateMachineId encodes consensusStateId as [u8; 4]
|
|
7223
|
+
consensusStateId: viem.toHex(viem.toBytes(height.id.consensusStateId))
|
|
7224
|
+
};
|
|
7225
|
+
const commitment = await this.api.query.ismp.boundedStateCommitments(id, Number(height.height));
|
|
7226
|
+
if (commitment.isNone) return void 0;
|
|
7227
|
+
return commitment.toJSON()?.stateRoot;
|
|
7228
|
+
}
|
|
7149
7229
|
/**
|
|
7150
7230
|
* Returns the current timestamp of the chain.
|
|
7151
7231
|
* @returns {Promise<bigint>} The current timestamp.
|
|
@@ -7773,6 +7853,23 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
7773
7853
|
} else if (result.status.isInBlock || result.status.isFinalized) {
|
|
7774
7854
|
resolved = true;
|
|
7775
7855
|
clearTimeout(timeoutId);
|
|
7856
|
+
const interrupted = result.events.find(
|
|
7857
|
+
({ event }) => event.section === "utility" && event.method === "BatchInterrupted"
|
|
7858
|
+
);
|
|
7859
|
+
if (interrupted) {
|
|
7860
|
+
const [indexCodec, dispatchError] = interrupted.event.data;
|
|
7861
|
+
if (Number(indexCodec.toString()) === 0) {
|
|
7862
|
+
let errorMsg;
|
|
7863
|
+
if (dispatchError?.isModule) {
|
|
7864
|
+
const decoded = this.api.registry.findMetaError(dispatchError.asModule);
|
|
7865
|
+
errorMsg = `Dispatch error: ${decoded.section}::${decoded.name}`;
|
|
7866
|
+
} else {
|
|
7867
|
+
errorMsg = `Dispatch error: batch interrupted (${dispatchError?.toString()})`;
|
|
7868
|
+
}
|
|
7869
|
+
resolve({ success: false, error: errorMsg });
|
|
7870
|
+
return;
|
|
7871
|
+
}
|
|
7872
|
+
}
|
|
7776
7873
|
resolve({
|
|
7777
7874
|
success: true,
|
|
7778
7875
|
blockHash: (result.status.isInBlock ? result.status.asInBlock : result.status.asFinalized).toHex(),
|
|
@@ -7832,10 +7929,19 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
7832
7929
|
}
|
|
7833
7930
|
}
|
|
7834
7931
|
/**
|
|
7835
|
-
*
|
|
7836
|
-
*
|
|
7837
|
-
*
|
|
7838
|
-
*
|
|
7932
|
+
* Places a new bid and retracts a previous one in a single transaction via utility.batch.
|
|
7933
|
+
*
|
|
7934
|
+
* The new bid is the primary operation, so `placeBid` MUST run first. `utility.batch` is
|
|
7935
|
+
* non-atomic: a failing call interrupts the batch (via a BatchInterrupted event) without
|
|
7936
|
+
* reverting the calls that already succeeded. Placing first guarantees the new bid lands even
|
|
7937
|
+
* when the retraction then fails — which it routinely does, because a previous commitment's bid
|
|
7938
|
+
* may already be gone (or was itself never placed), making `retractBid` return `BidNotFound`.
|
|
7939
|
+
*
|
|
7940
|
+
* Ordering retraction first (the previous behaviour) caused a self-sustaining cascade: a
|
|
7941
|
+
* `BidNotFound` on the leading retract skipped the trailing `placeBid`, so the current bid never
|
|
7942
|
+
* landed, so the *next* interval's retract of that never-placed commitment also failed, and so
|
|
7943
|
+
* on — silently, because the batch extrinsic itself reports success. The deposit reclaim is
|
|
7944
|
+
* best-effort; landing the bid is not.
|
|
7839
7945
|
*
|
|
7840
7946
|
* @param retractCommitment - The order commitment of the bid to retract (bytes32)
|
|
7841
7947
|
* @param bidCommitment - The order commitment of the new bid (bytes32)
|
|
@@ -7845,8 +7951,8 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
7845
7951
|
async submitBidWithRetraction(retractCommitment, bidCommitment, userOp) {
|
|
7846
7952
|
try {
|
|
7847
7953
|
const batch = this.api.tx.utility.batch([
|
|
7848
|
-
this.api.tx.intentsCoprocessor.
|
|
7849
|
-
this.api.tx.intentsCoprocessor.
|
|
7954
|
+
this.api.tx.intentsCoprocessor.placeBid(bidCommitment, userOp),
|
|
7955
|
+
this.api.tx.intentsCoprocessor.retractBid(retractCommitment)
|
|
7850
7956
|
]);
|
|
7851
7957
|
return await this.signAndSendExtrinsic(batch);
|
|
7852
7958
|
} catch (error) {
|
|
@@ -9952,6 +10058,7 @@ var GetRequestClient = class {
|
|
|
9952
10058
|
const latestMetadata = request.statuses[request.statuses.length - 1];
|
|
9953
10059
|
status = lodashEs.maxBy([status, latestMetadata.status], (item) => REQUEST_STATUS_WEIGHTS[item]);
|
|
9954
10060
|
if (!status) return;
|
|
10061
|
+
let sourceFinalizedHeight;
|
|
9955
10062
|
while (true) {
|
|
9956
10063
|
switch (status) {
|
|
9957
10064
|
case RequestStatus.SOURCE: {
|
|
@@ -9963,6 +10070,7 @@ var GetRequestClient = class {
|
|
|
9963
10070
|
chain: this.ctx.config.hyperbridge.config.stateMachineId
|
|
9964
10071
|
})
|
|
9965
10072
|
});
|
|
10073
|
+
sourceFinalizedHeight = BigInt(sourceUpdate.height);
|
|
9966
10074
|
yield {
|
|
9967
10075
|
status: RequestStatus.SOURCE_FINALIZED,
|
|
9968
10076
|
metadata: {
|
|
@@ -9976,6 +10084,15 @@ var GetRequestClient = class {
|
|
|
9976
10084
|
break;
|
|
9977
10085
|
}
|
|
9978
10086
|
case RequestStatus.SOURCE_FINALIZED: {
|
|
10087
|
+
if (request.source !== this.ctx.config.hyperbridge.config.stateMachineId && sourceFinalizedHeight !== void 0) {
|
|
10088
|
+
try {
|
|
10089
|
+
await this.deliverToHyperbridge(request, sourceFinalizedHeight);
|
|
10090
|
+
} catch (error) {
|
|
10091
|
+
this.logger.warn(
|
|
10092
|
+
`Self-delivery to Hyperbridge failed; waiting for a relayer instead: ${error instanceof Error ? error.message : error}`
|
|
10093
|
+
);
|
|
10094
|
+
}
|
|
10095
|
+
}
|
|
9979
10096
|
request = await waitOrAbort(this.ctx, {
|
|
9980
10097
|
signal,
|
|
9981
10098
|
promise: () => this.queries.queryGetRequest(hash),
|
|
@@ -9996,7 +10113,10 @@ var GetRequestClient = class {
|
|
|
9996
10113
|
}
|
|
9997
10114
|
case RequestStatus.HYPERBRIDGE_DELIVERED: {
|
|
9998
10115
|
if (request.source === this.ctx.config.hyperbridge.config.stateMachineId) return;
|
|
9999
|
-
const response = await this.
|
|
10116
|
+
const response = await waitOrAbort(this.ctx, {
|
|
10117
|
+
signal,
|
|
10118
|
+
promise: () => this.queries.queryResponseByRequestId(hash)
|
|
10119
|
+
});
|
|
10000
10120
|
yield await this.streamFinalized(signal, request, 1, response);
|
|
10001
10121
|
status = RequestStatus.HYPERBRIDGE_FINALIZED;
|
|
10002
10122
|
break;
|
|
@@ -10026,6 +10146,102 @@ var GetRequestClient = class {
|
|
|
10026
10146
|
}
|
|
10027
10147
|
}
|
|
10028
10148
|
}
|
|
10149
|
+
/**
|
|
10150
|
+
* Self-delivers a GET request to Hyperbridge — the request→Hyperbridge hop that would
|
|
10151
|
+
* otherwise require an external relayer.
|
|
10152
|
+
*
|
|
10153
|
+
* Mirrors the relayer path (and {@link OrderCanceller}): prove the request commitment on
|
|
10154
|
+
* the source chain at the Hyperbridge-finalized source height, prove the requested keys on
|
|
10155
|
+
* the destination chain at the request's height, wait out the source challenge period, then
|
|
10156
|
+
* submit an unsigned `GetRequest` message. Source and destination may each be EVM or
|
|
10157
|
+
* substrate — proofs are built via the chain-agnostic {@link IChain} methods.
|
|
10158
|
+
*
|
|
10159
|
+
* Idempotent: returns early if Hyperbridge already holds the response receipt. The caller
|
|
10160
|
+
* wraps this best-effort, so a failure leaves the stream observing as before.
|
|
10161
|
+
*/
|
|
10162
|
+
async deliverToHyperbridge(request, sourceFinalizedHeight) {
|
|
10163
|
+
const sourceChain = this.ctx.config.source;
|
|
10164
|
+
const destChain = this.ctx.config.dest;
|
|
10165
|
+
const hyperbridge = this.ctx.config.hyperbridge;
|
|
10166
|
+
const commitment = getRequestCommitment({ ...request, keys: [...request.keys] });
|
|
10167
|
+
const retry = { maxRetries: 5, backoffMs: 2e3 };
|
|
10168
|
+
if (await withRetry(this.ctx, () => hyperbridge.queryResponseReceipt(commitment), retry)) return;
|
|
10169
|
+
this.logger.info(
|
|
10170
|
+
`Delivering GET ${commitment} to Hyperbridge (${request.source}@${sourceFinalizedHeight} \u2192 ${request.dest}@${request.height})`
|
|
10171
|
+
);
|
|
10172
|
+
const sourceProof = {
|
|
10173
|
+
height: sourceFinalizedHeight,
|
|
10174
|
+
stateMachine: request.source,
|
|
10175
|
+
consensusStateId: sourceChain.config.consensusStateId,
|
|
10176
|
+
proof: await withRetry(
|
|
10177
|
+
this.ctx,
|
|
10178
|
+
() => sourceChain.queryProof(
|
|
10179
|
+
{ Requests: [commitment] },
|
|
10180
|
+
this.ctx.config.hyperbridge.config.stateMachineId,
|
|
10181
|
+
sourceFinalizedHeight
|
|
10182
|
+
),
|
|
10183
|
+
retry
|
|
10184
|
+
)
|
|
10185
|
+
};
|
|
10186
|
+
this.logger.info(` \u2713 built source proof: ${(sourceProof.proof.length - 2) / 2} bytes @ ${request.source}#${sourceFinalizedHeight}`);
|
|
10187
|
+
const destCommitment = await withRetry(
|
|
10188
|
+
this.ctx,
|
|
10189
|
+
() => hyperbridge.queryStateMachineCommitment({
|
|
10190
|
+
id: {
|
|
10191
|
+
stateId: parseStateMachineId(request.dest).stateId,
|
|
10192
|
+
consensusStateId: destChain.config.consensusStateId
|
|
10193
|
+
},
|
|
10194
|
+
height: request.height
|
|
10195
|
+
}),
|
|
10196
|
+
retry
|
|
10197
|
+
);
|
|
10198
|
+
if (!destCommitment) {
|
|
10199
|
+
throw new Error(`Hyperbridge has no state commitment for ${request.dest} at height ${request.height}`);
|
|
10200
|
+
}
|
|
10201
|
+
const responseProof = {
|
|
10202
|
+
height: request.height,
|
|
10203
|
+
stateMachine: request.dest,
|
|
10204
|
+
consensusStateId: destChain.config.consensusStateId,
|
|
10205
|
+
proof: await withRetry(this.ctx, () => destChain.queryStateProof(request.height, [...request.keys]), retry)
|
|
10206
|
+
};
|
|
10207
|
+
this.logger.info(
|
|
10208
|
+
` \u2713 built response proof: ${(responseProof.proof.length - 2) / 2} bytes (${request.keys.length} key(s) @ ${request.dest}#${request.height})`
|
|
10209
|
+
);
|
|
10210
|
+
await withRetry(
|
|
10211
|
+
this.ctx,
|
|
10212
|
+
() => waitForChallengePeriod(hyperbridge, {
|
|
10213
|
+
height: sourceFinalizedHeight,
|
|
10214
|
+
id: {
|
|
10215
|
+
stateId: parseStateMachineId(request.source).stateId,
|
|
10216
|
+
consensusStateId: sourceChain.config.consensusStateId
|
|
10217
|
+
}
|
|
10218
|
+
}),
|
|
10219
|
+
retry
|
|
10220
|
+
);
|
|
10221
|
+
const message = {
|
|
10222
|
+
kind: "GetRequest",
|
|
10223
|
+
requests: [
|
|
10224
|
+
{
|
|
10225
|
+
source: request.source,
|
|
10226
|
+
dest: request.dest,
|
|
10227
|
+
nonce: request.nonce,
|
|
10228
|
+
from: request.from,
|
|
10229
|
+
timeoutTimestamp: request.timeoutTimestamp,
|
|
10230
|
+
keys: [...request.keys],
|
|
10231
|
+
height: request.height,
|
|
10232
|
+
context: request.context
|
|
10233
|
+
}
|
|
10234
|
+
],
|
|
10235
|
+
source: sourceProof,
|
|
10236
|
+
response: responseProof,
|
|
10237
|
+
signer: viem.pad("0x")
|
|
10238
|
+
};
|
|
10239
|
+
this.logger.info(" \u2192 submitting GetRequest message (source + response proofs) to Hyperbridge\u2026");
|
|
10240
|
+
const result = await withRetry(this.ctx, () => hyperbridge.submitUnsigned(message), retry);
|
|
10241
|
+
this.logger.info(
|
|
10242
|
+
` \u2713 delivered GET ${commitment} in Hyperbridge block #${result.blockNumber} (tx ${result.transactionHash})`
|
|
10243
|
+
);
|
|
10244
|
+
}
|
|
10029
10245
|
/**
|
|
10030
10246
|
* Snapshot helper: returns the `HYPERBRIDGE_FINALIZED` event with source-chain
|
|
10031
10247
|
* calldata if prerequisites are met, or `undefined` if we're still waiting
|
|
@@ -10039,7 +10255,7 @@ var GetRequestClient = class {
|
|
|
10039
10255
|
const finality = await this.queries.queryStateMachineUpdateByHeight({
|
|
10040
10256
|
statemachineId: config.stateMachineId,
|
|
10041
10257
|
height: hyperbridgeDelivered.metadata.blockNumber,
|
|
10042
|
-
chain:
|
|
10258
|
+
chain: request.source
|
|
10043
10259
|
});
|
|
10044
10260
|
if (finality) {
|
|
10045
10261
|
const proof = await hyperbridge.queryProof(
|
|
@@ -10110,14 +10326,19 @@ var GetRequestClient = class {
|
|
|
10110
10326
|
],
|
|
10111
10327
|
signer: viem.pad("0x")
|
|
10112
10328
|
});
|
|
10329
|
+
const hyperbridgeFinality = await this.queries.queryStateMachineUpdateByHeight({
|
|
10330
|
+
statemachineId: config.stateMachineId,
|
|
10331
|
+
height: hyperbridgeDelivered.metadata.blockNumber,
|
|
10332
|
+
chain: config.stateMachineId
|
|
10333
|
+
});
|
|
10334
|
+
if (!hyperbridgeFinality) return void 0;
|
|
10113
10335
|
return {
|
|
10114
10336
|
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10115
10337
|
metadata: {
|
|
10116
|
-
blockHash:
|
|
10117
|
-
blockNumber:
|
|
10118
|
-
transactionHash:
|
|
10119
|
-
|
|
10120
|
-
timestamp: hyperbridgeDelivered.metadata.timestamp,
|
|
10338
|
+
blockHash: hyperbridgeFinality.blockHash,
|
|
10339
|
+
blockNumber: hyperbridgeFinality.height,
|
|
10340
|
+
transactionHash: hyperbridgeFinality.transactionHash,
|
|
10341
|
+
timestamp: hyperbridgeFinality.timestamp,
|
|
10121
10342
|
calldata
|
|
10122
10343
|
}
|
|
10123
10344
|
};
|
|
@@ -10137,12 +10358,44 @@ var GetRequestClient = class {
|
|
|
10137
10358
|
const hyperbridge = this.ctx.config.hyperbridge;
|
|
10138
10359
|
const stateMachineId = this.ctx.config.hyperbridge.config.stateMachineId;
|
|
10139
10360
|
const neededHeight = BigInt(request.statuses[hyperbridgeDeliveredIndex].metadata.blockNumber);
|
|
10361
|
+
const consensusStateId = this.ctx.config.hyperbridge.config.consensusStateId;
|
|
10362
|
+
const encodeGetResponse = (height, proof2) => sourceChain.encode({
|
|
10363
|
+
kind: "GetResponse",
|
|
10364
|
+
proof: { stateMachine: stateMachineId, consensusStateId, proof: proof2, height },
|
|
10365
|
+
responses: [
|
|
10366
|
+
{
|
|
10367
|
+
get: request,
|
|
10368
|
+
values: request.keys.map((key, index) => ({
|
|
10369
|
+
key,
|
|
10370
|
+
value: response?.values[index] || "0x"
|
|
10371
|
+
}))
|
|
10372
|
+
}
|
|
10373
|
+
],
|
|
10374
|
+
signer: viem.pad("0x")
|
|
10375
|
+
});
|
|
10140
10376
|
let finality = await this.queries.queryStateMachineUpdateByHeight({
|
|
10141
10377
|
statemachineId: stateMachineId,
|
|
10142
10378
|
height: Number(neededHeight),
|
|
10143
|
-
chain:
|
|
10379
|
+
chain: request.source
|
|
10144
10380
|
});
|
|
10145
|
-
if (
|
|
10381
|
+
if (finality) {
|
|
10382
|
+
const proof2 = await hyperbridge.queryProof(
|
|
10383
|
+
{ Responses: [response?.commitment] },
|
|
10384
|
+
request.source,
|
|
10385
|
+
BigInt(finality.height)
|
|
10386
|
+
);
|
|
10387
|
+
return {
|
|
10388
|
+
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10389
|
+
metadata: {
|
|
10390
|
+
blockHash: finality.blockHash,
|
|
10391
|
+
blockNumber: finality.height,
|
|
10392
|
+
transactionHash: finality.transactionHash,
|
|
10393
|
+
timestamp: finality.timestamp,
|
|
10394
|
+
calldata: encodeGetResponse(BigInt(finality.height), proof2)
|
|
10395
|
+
}
|
|
10396
|
+
};
|
|
10397
|
+
}
|
|
10398
|
+
if (sourceChain instanceof EvmChain) {
|
|
10146
10399
|
const hyperbridgeSubstrate = hyperbridge;
|
|
10147
10400
|
const currentEpoch = await sourceChain.currentEpoch();
|
|
10148
10401
|
const consensusResult = await waitOrAbort(this.ctx, {
|
|
@@ -10154,12 +10407,12 @@ var GetRequestClient = class {
|
|
|
10154
10407
|
request.source,
|
|
10155
10408
|
consensusResult.provenHeight
|
|
10156
10409
|
);
|
|
10157
|
-
const
|
|
10410
|
+
const calldata = sourceChain.encode({
|
|
10158
10411
|
kind: "BatchConsensusAndGetResponse",
|
|
10159
10412
|
consensusProofs: consensusResult.proofs,
|
|
10160
10413
|
proof: {
|
|
10161
10414
|
stateMachine: stateMachineId,
|
|
10162
|
-
consensusStateId
|
|
10415
|
+
consensusStateId,
|
|
10163
10416
|
proof: proof2,
|
|
10164
10417
|
height: consensusResult.provenHeight
|
|
10165
10418
|
},
|
|
@@ -10174,20 +10427,7 @@ var GetRequestClient = class {
|
|
|
10174
10427
|
],
|
|
10175
10428
|
signer: viem.pad("0x")
|
|
10176
10429
|
});
|
|
10177
|
-
|
|
10178
|
-
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10179
|
-
metadata: {
|
|
10180
|
-
blockHash: request.statuses[hyperbridgeDeliveredIndex].metadata.blockHash,
|
|
10181
|
-
blockNumber: Number(consensusResult.provenHeight),
|
|
10182
|
-
transactionHash: request.statuses[hyperbridgeDeliveredIndex].metadata.transactionHash,
|
|
10183
|
-
// @ts-ignore
|
|
10184
|
-
timestamp: request.statuses[hyperbridgeDeliveredIndex].metadata.timestamp,
|
|
10185
|
-
calldata: calldata2
|
|
10186
|
-
}
|
|
10187
|
-
};
|
|
10188
|
-
}
|
|
10189
|
-
if (!finality) {
|
|
10190
|
-
finality = await waitOrAbort(this.ctx, {
|
|
10430
|
+
const hyperbridgeFinality = await waitOrAbort(this.ctx, {
|
|
10191
10431
|
signal,
|
|
10192
10432
|
promise: () => this.queries.queryStateMachineUpdateByHeight({
|
|
10193
10433
|
statemachineId: stateMachineId,
|
|
@@ -10195,31 +10435,30 @@ var GetRequestClient = class {
|
|
|
10195
10435
|
chain: stateMachineId
|
|
10196
10436
|
})
|
|
10197
10437
|
});
|
|
10438
|
+
return {
|
|
10439
|
+
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10440
|
+
metadata: {
|
|
10441
|
+
blockHash: hyperbridgeFinality.blockHash,
|
|
10442
|
+
blockNumber: hyperbridgeFinality.height,
|
|
10443
|
+
transactionHash: hyperbridgeFinality.transactionHash,
|
|
10444
|
+
timestamp: hyperbridgeFinality.timestamp,
|
|
10445
|
+
calldata
|
|
10446
|
+
}
|
|
10447
|
+
};
|
|
10198
10448
|
}
|
|
10449
|
+
finality = await waitOrAbort(this.ctx, {
|
|
10450
|
+
signal,
|
|
10451
|
+
promise: () => this.queries.queryStateMachineUpdateByHeight({
|
|
10452
|
+
statemachineId: stateMachineId,
|
|
10453
|
+
height: Number(neededHeight),
|
|
10454
|
+
chain: request.source
|
|
10455
|
+
})
|
|
10456
|
+
});
|
|
10199
10457
|
const proof = await hyperbridge.queryProof(
|
|
10200
10458
|
{ Responses: [response?.commitment] },
|
|
10201
10459
|
request.source,
|
|
10202
10460
|
BigInt(finality.height)
|
|
10203
10461
|
);
|
|
10204
|
-
const calldata = sourceChain.encode({
|
|
10205
|
-
kind: "GetResponse",
|
|
10206
|
-
proof: {
|
|
10207
|
-
stateMachine: stateMachineId,
|
|
10208
|
-
consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
|
|
10209
|
-
proof,
|
|
10210
|
-
height: BigInt(finality.height)
|
|
10211
|
-
},
|
|
10212
|
-
responses: [
|
|
10213
|
-
{
|
|
10214
|
-
get: request,
|
|
10215
|
-
values: request.keys.map((key, index) => ({
|
|
10216
|
-
key,
|
|
10217
|
-
value: response?.values[index] || "0x"
|
|
10218
|
-
}))
|
|
10219
|
-
}
|
|
10220
|
-
],
|
|
10221
|
-
signer: viem.pad("0x")
|
|
10222
|
-
});
|
|
10223
10462
|
return {
|
|
10224
10463
|
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10225
10464
|
metadata: {
|
|
@@ -10227,7 +10466,7 @@ var GetRequestClient = class {
|
|
|
10227
10466
|
blockNumber: finality.height,
|
|
10228
10467
|
transactionHash: finality.transactionHash,
|
|
10229
10468
|
timestamp: finality.timestamp,
|
|
10230
|
-
calldata
|
|
10469
|
+
calldata: encodeGetResponse(BigInt(finality.height), proof)
|
|
10231
10470
|
}
|
|
10232
10471
|
};
|
|
10233
10472
|
}
|
|
@@ -10730,7 +10969,7 @@ var PostRequestClient = class {
|
|
|
10730
10969
|
const finality = await this.queries.queryStateMachineUpdateByHeight({
|
|
10731
10970
|
statemachineId: config.stateMachineId,
|
|
10732
10971
|
height: hyperbridgeDelivered.metadata.blockNumber,
|
|
10733
|
-
chain:
|
|
10972
|
+
chain: request.dest
|
|
10734
10973
|
});
|
|
10735
10974
|
if (finality) {
|
|
10736
10975
|
const proof = await hyperbridge.queryProof(
|
|
@@ -10785,14 +11024,19 @@ var PostRequestClient = class {
|
|
|
10785
11024
|
requests: [request],
|
|
10786
11025
|
signer: viem.pad("0x")
|
|
10787
11026
|
});
|
|
11027
|
+
const hyperbridgeFinality = await this.queries.queryStateMachineUpdateByHeight({
|
|
11028
|
+
statemachineId: config.stateMachineId,
|
|
11029
|
+
height: hyperbridgeDelivered.metadata.blockNumber,
|
|
11030
|
+
chain: config.stateMachineId
|
|
11031
|
+
});
|
|
11032
|
+
if (!hyperbridgeFinality) return void 0;
|
|
10788
11033
|
return {
|
|
10789
11034
|
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10790
11035
|
metadata: {
|
|
10791
|
-
blockHash:
|
|
10792
|
-
blockNumber:
|
|
10793
|
-
transactionHash:
|
|
10794
|
-
|
|
10795
|
-
timestamp: hyperbridgeDelivered.metadata.timestamp,
|
|
11036
|
+
blockHash: hyperbridgeFinality.blockHash,
|
|
11037
|
+
blockNumber: hyperbridgeFinality.height,
|
|
11038
|
+
transactionHash: hyperbridgeFinality.transactionHash,
|
|
11039
|
+
timestamp: hyperbridgeFinality.timestamp,
|
|
10796
11040
|
calldata
|
|
10797
11041
|
}
|
|
10798
11042
|
};
|
|
@@ -10815,7 +11059,7 @@ var PostRequestClient = class {
|
|
|
10815
11059
|
let finality = await this.queries.queryStateMachineUpdateByHeight({
|
|
10816
11060
|
statemachineId: stateMachineId,
|
|
10817
11061
|
height: Number(neededHeight),
|
|
10818
|
-
chain:
|
|
11062
|
+
chain: request.dest
|
|
10819
11063
|
});
|
|
10820
11064
|
if (!finality && destChain instanceof EvmChain) {
|
|
10821
11065
|
const hyperbridgeSubstrate = hyperbridge;
|
|
@@ -10843,14 +11087,21 @@ var PostRequestClient = class {
|
|
|
10843
11087
|
requests: [request],
|
|
10844
11088
|
signer: viem.pad("0x")
|
|
10845
11089
|
});
|
|
11090
|
+
const hyperbridgeFinality = await waitOrAbort(this.ctx, {
|
|
11091
|
+
signal,
|
|
11092
|
+
promise: () => this.queries.queryStateMachineUpdateByHeight({
|
|
11093
|
+
statemachineId: stateMachineId,
|
|
11094
|
+
height: Number(neededHeight),
|
|
11095
|
+
chain: stateMachineId
|
|
11096
|
+
})
|
|
11097
|
+
});
|
|
10846
11098
|
return {
|
|
10847
11099
|
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10848
11100
|
metadata: {
|
|
10849
|
-
blockHash:
|
|
10850
|
-
blockNumber:
|
|
10851
|
-
transactionHash:
|
|
10852
|
-
|
|
10853
|
-
timestamp: request.statuses[hyperbridgeDeliveredIndex].metadata.timestamp,
|
|
11101
|
+
blockHash: hyperbridgeFinality.blockHash,
|
|
11102
|
+
blockNumber: hyperbridgeFinality.height,
|
|
11103
|
+
transactionHash: hyperbridgeFinality.transactionHash,
|
|
11104
|
+
timestamp: hyperbridgeFinality.timestamp,
|
|
10854
11105
|
calldata: calldata2
|
|
10855
11106
|
}
|
|
10856
11107
|
};
|
|
@@ -10861,7 +11112,7 @@ var PostRequestClient = class {
|
|
|
10861
11112
|
promise: () => this.queries.queryStateMachineUpdateByHeight({
|
|
10862
11113
|
statemachineId: stateMachineId,
|
|
10863
11114
|
height: Number(neededHeight),
|
|
10864
|
-
chain:
|
|
11115
|
+
chain: request.dest
|
|
10865
11116
|
})
|
|
10866
11117
|
});
|
|
10867
11118
|
}
|
|
@@ -16753,9 +17004,9 @@ var GasEstimator = class {
|
|
|
16753
17004
|
from: this.ctx.source.configService.getIntentGatewayAddress(destChainId),
|
|
16754
17005
|
to: this.ctx.source.configService.getIntentGatewayAddress(sourceChainId)
|
|
16755
17006
|
};
|
|
17007
|
+
postRequestFeeInDestFeeToken = postRequestFeeInDestFeeToken * 1005n / 1000n;
|
|
16756
17008
|
let protocolFeeInNativeToken = await this.ctx.dest.quoteNative(postRequest, postRequestFeeInDestFeeToken).catch(() => 0n);
|
|
16757
17009
|
protocolFeeInNativeToken = protocolFeeInNativeToken * 1005n / 1000n;
|
|
16758
|
-
postRequestFeeInDestFeeToken = postRequestFeeInDestFeeToken * 1005n / 1000n;
|
|
16759
17010
|
return { postRequestFee: postRequestFeeInDestFeeToken, protocolFee: protocolFeeInNativeToken };
|
|
16760
17011
|
}
|
|
16761
17012
|
/**
|