@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.js
CHANGED
|
@@ -2100,7 +2100,7 @@ var ABI2 = [
|
|
|
2100
2100
|
{ internalType: "bytes", name: "source", type: "bytes" },
|
|
2101
2101
|
{ internalType: "bytes", name: "dest", type: "bytes" },
|
|
2102
2102
|
{ internalType: "uint64", name: "nonce", type: "uint64" },
|
|
2103
|
-
{ internalType: "
|
|
2103
|
+
{ internalType: "bytes", name: "from", type: "bytes" },
|
|
2104
2104
|
{ internalType: "uint64", name: "timeoutTimestamp", type: "uint64" },
|
|
2105
2105
|
{ internalType: "bytes[]", name: "keys", type: "bytes[]" },
|
|
2106
2106
|
{ internalType: "uint64", name: "height", type: "uint64" },
|
|
@@ -2167,7 +2167,7 @@ var ABI2 = [
|
|
|
2167
2167
|
{ internalType: "bytes", name: "source", type: "bytes" },
|
|
2168
2168
|
{ internalType: "bytes", name: "dest", type: "bytes" },
|
|
2169
2169
|
{ internalType: "uint64", name: "nonce", type: "uint64" },
|
|
2170
|
-
{ internalType: "
|
|
2170
|
+
{ internalType: "bytes", name: "from", type: "bytes" },
|
|
2171
2171
|
{ internalType: "uint64", name: "timeoutTimestamp", type: "uint64" },
|
|
2172
2172
|
{ internalType: "bytes[]", name: "keys", type: "bytes[]" },
|
|
2173
2173
|
{ internalType: "uint64", name: "height", type: "uint64" },
|
|
@@ -6392,28 +6392,60 @@ var EvmChain = class _EvmChain {
|
|
|
6392
6392
|
}
|
|
6393
6393
|
/**
|
|
6394
6394
|
* Query and return the encoded storage proof for the provided keys at the given height.
|
|
6395
|
+
*
|
|
6396
|
+
* Keys may be either:
|
|
6397
|
+
* - 32-byte storage slots — read from `address` (or the host contract when omitted), or
|
|
6398
|
+
* - 52-byte cross-chain GET keys encoded as `address(20) || slot(32)`, where the target
|
|
6399
|
+
* contract is embedded in the key. These may span multiple contracts.
|
|
6400
|
+
*
|
|
6395
6401
|
* @param {bigint} at - The block height at which to query the storage proof.
|
|
6396
6402
|
* @param {HexString[]} keys - The keys for which to query the storage proof.
|
|
6397
|
-
* @param {HexString} address - Optional contract address
|
|
6403
|
+
* @param {HexString} address - Optional contract address; forces all keys to be read as slots
|
|
6404
|
+
* of this contract. Omit to let 52-byte keys carry their own contract address.
|
|
6398
6405
|
* @returns {Promise<HexString>} The encoded storage proof.
|
|
6399
6406
|
*/
|
|
6400
6407
|
async queryStateProof(at, keys, address) {
|
|
6401
|
-
const
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
|
|
6408
|
+
const slotsByContract = /* @__PURE__ */ new Map();
|
|
6409
|
+
for (const key of keys) {
|
|
6410
|
+
let contract;
|
|
6411
|
+
let slot;
|
|
6412
|
+
if (address) {
|
|
6413
|
+
contract = address.toLowerCase();
|
|
6414
|
+
slot = key;
|
|
6415
|
+
} else if ((key.length - 2) / 2 === 52) {
|
|
6416
|
+
contract = key.slice(0, 42).toLowerCase();
|
|
6417
|
+
slot = `0x${key.slice(42)}`;
|
|
6418
|
+
} else {
|
|
6419
|
+
contract = this.params.host.toLowerCase();
|
|
6420
|
+
slot = key;
|
|
6421
|
+
}
|
|
6422
|
+
const slots = slotsByContract.get(contract) ?? [];
|
|
6423
|
+
slots.push(slot);
|
|
6424
|
+
slotsByContract.set(contract, slots);
|
|
6425
|
+
}
|
|
6426
|
+
const contracts = Array.from(slotsByContract.entries());
|
|
6427
|
+
const proofs = await Promise.all(
|
|
6428
|
+
contracts.map(([contract, slots]) => {
|
|
6429
|
+
const config = { address: contract, storageKeys: slots };
|
|
6430
|
+
if (!at) {
|
|
6431
|
+
config.blockTag = "latest";
|
|
6432
|
+
} else {
|
|
6433
|
+
config.blockNumber = at;
|
|
6434
|
+
}
|
|
6435
|
+
return this.publicClient.getProof(config);
|
|
6436
|
+
})
|
|
6437
|
+
);
|
|
6438
|
+
const contractProof = Array.from(new Set(flatten(proofs.map((proof) => proof.accountProof))));
|
|
6439
|
+
const storageProof = contracts.map(([contract], i) => {
|
|
6440
|
+
const flattened = Array.from(new Set(flatten(proofs[i].storageProof.map((item) => item.proof))));
|
|
6441
|
+
return [
|
|
6442
|
+
Array.from(hexToBytes(contract)),
|
|
6443
|
+
flattened.map((item) => Array.from(hexToBytes(item)))
|
|
6444
|
+
];
|
|
6445
|
+
});
|
|
6412
6446
|
const encoded = EvmStateProof.enc({
|
|
6413
|
-
contractProof:
|
|
6414
|
-
storageProof
|
|
6415
|
-
[Array.from(hexToBytes(config.address)), flattenedProof.map((item) => Array.from(hexToBytes(item)))]
|
|
6416
|
-
]
|
|
6447
|
+
contractProof: contractProof.map((item) => Array.from(hexToBytes(item))),
|
|
6448
|
+
storageProof
|
|
6417
6449
|
});
|
|
6418
6450
|
return toHex(encoded);
|
|
6419
6451
|
}
|
|
@@ -6743,15 +6775,20 @@ var EvmChain = class _EvmChain {
|
|
|
6743
6775
|
async quoteNative(request, fee) {
|
|
6744
6776
|
const totalFee = await this.quote(request) + fee;
|
|
6745
6777
|
const feeToken = await this.getFeeTokenWithDecimals();
|
|
6746
|
-
|
|
6778
|
+
const hostRouter = await this.publicClient.readContract({
|
|
6779
|
+
address: this.params.host,
|
|
6780
|
+
abi: evmHost_default.ABI,
|
|
6781
|
+
functionName: "uniswapV2Router"
|
|
6782
|
+
});
|
|
6783
|
+
return this.getAmountsIn(totalFee, feeToken.address, request.source, hostRouter);
|
|
6747
6784
|
}
|
|
6748
6785
|
/**
|
|
6749
6786
|
* Given a desired output amount of a token, returns how much native is needed as input.
|
|
6750
|
-
* Uses the chain's Uniswap V2 router: WETH → tokenOut path.
|
|
6787
|
+
* Uses the chain's Uniswap V2 router (or `router` when provided): WETH → tokenOut path.
|
|
6751
6788
|
*/
|
|
6752
|
-
async getAmountsIn(amountOut, tokenOutForQuote, chain) {
|
|
6789
|
+
async getAmountsIn(amountOut, tokenOutForQuote, chain, router) {
|
|
6753
6790
|
const chainId = chain ?? `EVM-${this.params.chainId}`;
|
|
6754
|
-
const v2Router = this.configService.getUniswapRouterV2Address(chainId);
|
|
6791
|
+
const v2Router = router ?? this.configService.getUniswapRouterV2Address(chainId);
|
|
6755
6792
|
const WETH = this.configService.getWrappedNativeAssetWithDecimals(chainId).asset;
|
|
6756
6793
|
const v2AmountIn = await this.publicClient.simulateContract({
|
|
6757
6794
|
address: v2Router,
|
|
@@ -7135,6 +7172,49 @@ var SubstrateChain = class _SubstrateChain {
|
|
|
7135
7172
|
const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
|
|
7136
7173
|
return item;
|
|
7137
7174
|
}
|
|
7175
|
+
/**
|
|
7176
|
+
* Returns the storage key for a response receipt in the child trie.
|
|
7177
|
+
* A response receipt is keyed by the originating *request* commitment.
|
|
7178
|
+
* @param {HexString} key - The request commitment (0x-prefixed H256 hex string)
|
|
7179
|
+
* @returns {HexString} The storage key as a hex string
|
|
7180
|
+
*/
|
|
7181
|
+
responseReceiptKey(key) {
|
|
7182
|
+
const prefix = new TextEncoder().encode("ResponseReceipts");
|
|
7183
|
+
const keyBytes = hexToBytes(key);
|
|
7184
|
+
return bytesToHex(new Uint8Array([...prefix, ...keyBytes]));
|
|
7185
|
+
}
|
|
7186
|
+
/**
|
|
7187
|
+
* Queries the response receipt for a request commitment. For a GET, Hyperbridge
|
|
7188
|
+
* produces the response as it processes the request, so the presence of a response
|
|
7189
|
+
* receipt indicates the request has already been delivered and handled.
|
|
7190
|
+
* @param {HexString} commitment - The originating request commitment to query.
|
|
7191
|
+
* @returns {Promise<HexString | undefined>} The receipt data if present, otherwise undefined.
|
|
7192
|
+
*/
|
|
7193
|
+
async queryResponseReceipt(commitment) {
|
|
7194
|
+
const prefix = toHex(":child_storage:default:ISMP");
|
|
7195
|
+
const key = this.responseReceiptKey(commitment);
|
|
7196
|
+
const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
|
|
7197
|
+
return item;
|
|
7198
|
+
}
|
|
7199
|
+
/**
|
|
7200
|
+
* Queries the state-machine commitment Hyperbridge holds for a counterparty chain at an
|
|
7201
|
+
* exact height — the `BoundedStateCommitments` map that `state_machine_commitment` (and thus
|
|
7202
|
+
* proof verification) reads. Returns the committed `stateRoot`, or undefined if Hyperbridge
|
|
7203
|
+
* has not finalized that chain at exactly that height.
|
|
7204
|
+
* @param {StateMachineHeight} height - The counterparty state machine id + height.
|
|
7205
|
+
* @returns {Promise<HexString | undefined>} The committed state root, or undefined if absent.
|
|
7206
|
+
*/
|
|
7207
|
+
async queryStateMachineCommitment(height) {
|
|
7208
|
+
if (!this.api) throw new Error("API not initialized");
|
|
7209
|
+
const id = {
|
|
7210
|
+
stateId: height.id.stateId,
|
|
7211
|
+
// on-chain StateMachineId encodes consensusStateId as [u8; 4]
|
|
7212
|
+
consensusStateId: toHex(toBytes(height.id.consensusStateId))
|
|
7213
|
+
};
|
|
7214
|
+
const commitment = await this.api.query.ismp.boundedStateCommitments(id, Number(height.height));
|
|
7215
|
+
if (commitment.isNone) return void 0;
|
|
7216
|
+
return commitment.toJSON()?.stateRoot;
|
|
7217
|
+
}
|
|
7138
7218
|
/**
|
|
7139
7219
|
* Returns the current timestamp of the chain.
|
|
7140
7220
|
* @returns {Promise<bigint>} The current timestamp.
|
|
@@ -7762,6 +7842,23 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
7762
7842
|
} else if (result.status.isInBlock || result.status.isFinalized) {
|
|
7763
7843
|
resolved = true;
|
|
7764
7844
|
clearTimeout(timeoutId);
|
|
7845
|
+
const interrupted = result.events.find(
|
|
7846
|
+
({ event }) => event.section === "utility" && event.method === "BatchInterrupted"
|
|
7847
|
+
);
|
|
7848
|
+
if (interrupted) {
|
|
7849
|
+
const [indexCodec, dispatchError] = interrupted.event.data;
|
|
7850
|
+
if (Number(indexCodec.toString()) === 0) {
|
|
7851
|
+
let errorMsg;
|
|
7852
|
+
if (dispatchError?.isModule) {
|
|
7853
|
+
const decoded = this.api.registry.findMetaError(dispatchError.asModule);
|
|
7854
|
+
errorMsg = `Dispatch error: ${decoded.section}::${decoded.name}`;
|
|
7855
|
+
} else {
|
|
7856
|
+
errorMsg = `Dispatch error: batch interrupted (${dispatchError?.toString()})`;
|
|
7857
|
+
}
|
|
7858
|
+
resolve({ success: false, error: errorMsg });
|
|
7859
|
+
return;
|
|
7860
|
+
}
|
|
7861
|
+
}
|
|
7765
7862
|
resolve({
|
|
7766
7863
|
success: true,
|
|
7767
7864
|
blockHash: (result.status.isInBlock ? result.status.asInBlock : result.status.asFinalized).toHex(),
|
|
@@ -7821,10 +7918,19 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
7821
7918
|
}
|
|
7822
7919
|
}
|
|
7823
7920
|
/**
|
|
7824
|
-
*
|
|
7825
|
-
*
|
|
7826
|
-
*
|
|
7827
|
-
*
|
|
7921
|
+
* Places a new bid and retracts a previous one in a single transaction via utility.batch.
|
|
7922
|
+
*
|
|
7923
|
+
* The new bid is the primary operation, so `placeBid` MUST run first. `utility.batch` is
|
|
7924
|
+
* non-atomic: a failing call interrupts the batch (via a BatchInterrupted event) without
|
|
7925
|
+
* reverting the calls that already succeeded. Placing first guarantees the new bid lands even
|
|
7926
|
+
* when the retraction then fails — which it routinely does, because a previous commitment's bid
|
|
7927
|
+
* may already be gone (or was itself never placed), making `retractBid` return `BidNotFound`.
|
|
7928
|
+
*
|
|
7929
|
+
* Ordering retraction first (the previous behaviour) caused a self-sustaining cascade: a
|
|
7930
|
+
* `BidNotFound` on the leading retract skipped the trailing `placeBid`, so the current bid never
|
|
7931
|
+
* landed, so the *next* interval's retract of that never-placed commitment also failed, and so
|
|
7932
|
+
* on — silently, because the batch extrinsic itself reports success. The deposit reclaim is
|
|
7933
|
+
* best-effort; landing the bid is not.
|
|
7828
7934
|
*
|
|
7829
7935
|
* @param retractCommitment - The order commitment of the bid to retract (bytes32)
|
|
7830
7936
|
* @param bidCommitment - The order commitment of the new bid (bytes32)
|
|
@@ -7834,8 +7940,8 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
|
|
|
7834
7940
|
async submitBidWithRetraction(retractCommitment, bidCommitment, userOp) {
|
|
7835
7941
|
try {
|
|
7836
7942
|
const batch = this.api.tx.utility.batch([
|
|
7837
|
-
this.api.tx.intentsCoprocessor.
|
|
7838
|
-
this.api.tx.intentsCoprocessor.
|
|
7943
|
+
this.api.tx.intentsCoprocessor.placeBid(bidCommitment, userOp),
|
|
7944
|
+
this.api.tx.intentsCoprocessor.retractBid(retractCommitment)
|
|
7839
7945
|
]);
|
|
7840
7946
|
return await this.signAndSendExtrinsic(batch);
|
|
7841
7947
|
} catch (error) {
|
|
@@ -9941,6 +10047,7 @@ var GetRequestClient = class {
|
|
|
9941
10047
|
const latestMetadata = request.statuses[request.statuses.length - 1];
|
|
9942
10048
|
status = maxBy([status, latestMetadata.status], (item) => REQUEST_STATUS_WEIGHTS[item]);
|
|
9943
10049
|
if (!status) return;
|
|
10050
|
+
let sourceFinalizedHeight;
|
|
9944
10051
|
while (true) {
|
|
9945
10052
|
switch (status) {
|
|
9946
10053
|
case RequestStatus.SOURCE: {
|
|
@@ -9952,6 +10059,7 @@ var GetRequestClient = class {
|
|
|
9952
10059
|
chain: this.ctx.config.hyperbridge.config.stateMachineId
|
|
9953
10060
|
})
|
|
9954
10061
|
});
|
|
10062
|
+
sourceFinalizedHeight = BigInt(sourceUpdate.height);
|
|
9955
10063
|
yield {
|
|
9956
10064
|
status: RequestStatus.SOURCE_FINALIZED,
|
|
9957
10065
|
metadata: {
|
|
@@ -9965,6 +10073,15 @@ var GetRequestClient = class {
|
|
|
9965
10073
|
break;
|
|
9966
10074
|
}
|
|
9967
10075
|
case RequestStatus.SOURCE_FINALIZED: {
|
|
10076
|
+
if (request.source !== this.ctx.config.hyperbridge.config.stateMachineId && sourceFinalizedHeight !== void 0) {
|
|
10077
|
+
try {
|
|
10078
|
+
await this.deliverToHyperbridge(request, sourceFinalizedHeight);
|
|
10079
|
+
} catch (error) {
|
|
10080
|
+
this.logger.warn(
|
|
10081
|
+
`Self-delivery to Hyperbridge failed; waiting for a relayer instead: ${error instanceof Error ? error.message : error}`
|
|
10082
|
+
);
|
|
10083
|
+
}
|
|
10084
|
+
}
|
|
9968
10085
|
request = await waitOrAbort(this.ctx, {
|
|
9969
10086
|
signal,
|
|
9970
10087
|
promise: () => this.queries.queryGetRequest(hash),
|
|
@@ -9985,7 +10102,10 @@ var GetRequestClient = class {
|
|
|
9985
10102
|
}
|
|
9986
10103
|
case RequestStatus.HYPERBRIDGE_DELIVERED: {
|
|
9987
10104
|
if (request.source === this.ctx.config.hyperbridge.config.stateMachineId) return;
|
|
9988
|
-
const response = await this.
|
|
10105
|
+
const response = await waitOrAbort(this.ctx, {
|
|
10106
|
+
signal,
|
|
10107
|
+
promise: () => this.queries.queryResponseByRequestId(hash)
|
|
10108
|
+
});
|
|
9989
10109
|
yield await this.streamFinalized(signal, request, 1, response);
|
|
9990
10110
|
status = RequestStatus.HYPERBRIDGE_FINALIZED;
|
|
9991
10111
|
break;
|
|
@@ -10015,6 +10135,102 @@ var GetRequestClient = class {
|
|
|
10015
10135
|
}
|
|
10016
10136
|
}
|
|
10017
10137
|
}
|
|
10138
|
+
/**
|
|
10139
|
+
* Self-delivers a GET request to Hyperbridge — the request→Hyperbridge hop that would
|
|
10140
|
+
* otherwise require an external relayer.
|
|
10141
|
+
*
|
|
10142
|
+
* Mirrors the relayer path (and {@link OrderCanceller}): prove the request commitment on
|
|
10143
|
+
* the source chain at the Hyperbridge-finalized source height, prove the requested keys on
|
|
10144
|
+
* the destination chain at the request's height, wait out the source challenge period, then
|
|
10145
|
+
* submit an unsigned `GetRequest` message. Source and destination may each be EVM or
|
|
10146
|
+
* substrate — proofs are built via the chain-agnostic {@link IChain} methods.
|
|
10147
|
+
*
|
|
10148
|
+
* Idempotent: returns early if Hyperbridge already holds the response receipt. The caller
|
|
10149
|
+
* wraps this best-effort, so a failure leaves the stream observing as before.
|
|
10150
|
+
*/
|
|
10151
|
+
async deliverToHyperbridge(request, sourceFinalizedHeight) {
|
|
10152
|
+
const sourceChain = this.ctx.config.source;
|
|
10153
|
+
const destChain = this.ctx.config.dest;
|
|
10154
|
+
const hyperbridge = this.ctx.config.hyperbridge;
|
|
10155
|
+
const commitment = getRequestCommitment({ ...request, keys: [...request.keys] });
|
|
10156
|
+
const retry = { maxRetries: 5, backoffMs: 2e3 };
|
|
10157
|
+
if (await withRetry(this.ctx, () => hyperbridge.queryResponseReceipt(commitment), retry)) return;
|
|
10158
|
+
this.logger.info(
|
|
10159
|
+
`Delivering GET ${commitment} to Hyperbridge (${request.source}@${sourceFinalizedHeight} \u2192 ${request.dest}@${request.height})`
|
|
10160
|
+
);
|
|
10161
|
+
const sourceProof = {
|
|
10162
|
+
height: sourceFinalizedHeight,
|
|
10163
|
+
stateMachine: request.source,
|
|
10164
|
+
consensusStateId: sourceChain.config.consensusStateId,
|
|
10165
|
+
proof: await withRetry(
|
|
10166
|
+
this.ctx,
|
|
10167
|
+
() => sourceChain.queryProof(
|
|
10168
|
+
{ Requests: [commitment] },
|
|
10169
|
+
this.ctx.config.hyperbridge.config.stateMachineId,
|
|
10170
|
+
sourceFinalizedHeight
|
|
10171
|
+
),
|
|
10172
|
+
retry
|
|
10173
|
+
)
|
|
10174
|
+
};
|
|
10175
|
+
this.logger.info(` \u2713 built source proof: ${(sourceProof.proof.length - 2) / 2} bytes @ ${request.source}#${sourceFinalizedHeight}`);
|
|
10176
|
+
const destCommitment = await withRetry(
|
|
10177
|
+
this.ctx,
|
|
10178
|
+
() => hyperbridge.queryStateMachineCommitment({
|
|
10179
|
+
id: {
|
|
10180
|
+
stateId: parseStateMachineId(request.dest).stateId,
|
|
10181
|
+
consensusStateId: destChain.config.consensusStateId
|
|
10182
|
+
},
|
|
10183
|
+
height: request.height
|
|
10184
|
+
}),
|
|
10185
|
+
retry
|
|
10186
|
+
);
|
|
10187
|
+
if (!destCommitment) {
|
|
10188
|
+
throw new Error(`Hyperbridge has no state commitment for ${request.dest} at height ${request.height}`);
|
|
10189
|
+
}
|
|
10190
|
+
const responseProof = {
|
|
10191
|
+
height: request.height,
|
|
10192
|
+
stateMachine: request.dest,
|
|
10193
|
+
consensusStateId: destChain.config.consensusStateId,
|
|
10194
|
+
proof: await withRetry(this.ctx, () => destChain.queryStateProof(request.height, [...request.keys]), retry)
|
|
10195
|
+
};
|
|
10196
|
+
this.logger.info(
|
|
10197
|
+
` \u2713 built response proof: ${(responseProof.proof.length - 2) / 2} bytes (${request.keys.length} key(s) @ ${request.dest}#${request.height})`
|
|
10198
|
+
);
|
|
10199
|
+
await withRetry(
|
|
10200
|
+
this.ctx,
|
|
10201
|
+
() => waitForChallengePeriod(hyperbridge, {
|
|
10202
|
+
height: sourceFinalizedHeight,
|
|
10203
|
+
id: {
|
|
10204
|
+
stateId: parseStateMachineId(request.source).stateId,
|
|
10205
|
+
consensusStateId: sourceChain.config.consensusStateId
|
|
10206
|
+
}
|
|
10207
|
+
}),
|
|
10208
|
+
retry
|
|
10209
|
+
);
|
|
10210
|
+
const message = {
|
|
10211
|
+
kind: "GetRequest",
|
|
10212
|
+
requests: [
|
|
10213
|
+
{
|
|
10214
|
+
source: request.source,
|
|
10215
|
+
dest: request.dest,
|
|
10216
|
+
nonce: request.nonce,
|
|
10217
|
+
from: request.from,
|
|
10218
|
+
timeoutTimestamp: request.timeoutTimestamp,
|
|
10219
|
+
keys: [...request.keys],
|
|
10220
|
+
height: request.height,
|
|
10221
|
+
context: request.context
|
|
10222
|
+
}
|
|
10223
|
+
],
|
|
10224
|
+
source: sourceProof,
|
|
10225
|
+
response: responseProof,
|
|
10226
|
+
signer: pad("0x")
|
|
10227
|
+
};
|
|
10228
|
+
this.logger.info(" \u2192 submitting GetRequest message (source + response proofs) to Hyperbridge\u2026");
|
|
10229
|
+
const result = await withRetry(this.ctx, () => hyperbridge.submitUnsigned(message), retry);
|
|
10230
|
+
this.logger.info(
|
|
10231
|
+
` \u2713 delivered GET ${commitment} in Hyperbridge block #${result.blockNumber} (tx ${result.transactionHash})`
|
|
10232
|
+
);
|
|
10233
|
+
}
|
|
10018
10234
|
/**
|
|
10019
10235
|
* Snapshot helper: returns the `HYPERBRIDGE_FINALIZED` event with source-chain
|
|
10020
10236
|
* calldata if prerequisites are met, or `undefined` if we're still waiting
|
|
@@ -10028,7 +10244,7 @@ var GetRequestClient = class {
|
|
|
10028
10244
|
const finality = await this.queries.queryStateMachineUpdateByHeight({
|
|
10029
10245
|
statemachineId: config.stateMachineId,
|
|
10030
10246
|
height: hyperbridgeDelivered.metadata.blockNumber,
|
|
10031
|
-
chain:
|
|
10247
|
+
chain: request.source
|
|
10032
10248
|
});
|
|
10033
10249
|
if (finality) {
|
|
10034
10250
|
const proof = await hyperbridge.queryProof(
|
|
@@ -10099,14 +10315,19 @@ var GetRequestClient = class {
|
|
|
10099
10315
|
],
|
|
10100
10316
|
signer: pad("0x")
|
|
10101
10317
|
});
|
|
10318
|
+
const hyperbridgeFinality = await this.queries.queryStateMachineUpdateByHeight({
|
|
10319
|
+
statemachineId: config.stateMachineId,
|
|
10320
|
+
height: hyperbridgeDelivered.metadata.blockNumber,
|
|
10321
|
+
chain: config.stateMachineId
|
|
10322
|
+
});
|
|
10323
|
+
if (!hyperbridgeFinality) return void 0;
|
|
10102
10324
|
return {
|
|
10103
10325
|
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10104
10326
|
metadata: {
|
|
10105
|
-
blockHash:
|
|
10106
|
-
blockNumber:
|
|
10107
|
-
transactionHash:
|
|
10108
|
-
|
|
10109
|
-
timestamp: hyperbridgeDelivered.metadata.timestamp,
|
|
10327
|
+
blockHash: hyperbridgeFinality.blockHash,
|
|
10328
|
+
blockNumber: hyperbridgeFinality.height,
|
|
10329
|
+
transactionHash: hyperbridgeFinality.transactionHash,
|
|
10330
|
+
timestamp: hyperbridgeFinality.timestamp,
|
|
10110
10331
|
calldata
|
|
10111
10332
|
}
|
|
10112
10333
|
};
|
|
@@ -10126,12 +10347,44 @@ var GetRequestClient = class {
|
|
|
10126
10347
|
const hyperbridge = this.ctx.config.hyperbridge;
|
|
10127
10348
|
const stateMachineId = this.ctx.config.hyperbridge.config.stateMachineId;
|
|
10128
10349
|
const neededHeight = BigInt(request.statuses[hyperbridgeDeliveredIndex].metadata.blockNumber);
|
|
10350
|
+
const consensusStateId = this.ctx.config.hyperbridge.config.consensusStateId;
|
|
10351
|
+
const encodeGetResponse = (height, proof2) => sourceChain.encode({
|
|
10352
|
+
kind: "GetResponse",
|
|
10353
|
+
proof: { stateMachine: stateMachineId, consensusStateId, proof: proof2, height },
|
|
10354
|
+
responses: [
|
|
10355
|
+
{
|
|
10356
|
+
get: request,
|
|
10357
|
+
values: request.keys.map((key, index) => ({
|
|
10358
|
+
key,
|
|
10359
|
+
value: response?.values[index] || "0x"
|
|
10360
|
+
}))
|
|
10361
|
+
}
|
|
10362
|
+
],
|
|
10363
|
+
signer: pad("0x")
|
|
10364
|
+
});
|
|
10129
10365
|
let finality = await this.queries.queryStateMachineUpdateByHeight({
|
|
10130
10366
|
statemachineId: stateMachineId,
|
|
10131
10367
|
height: Number(neededHeight),
|
|
10132
|
-
chain:
|
|
10368
|
+
chain: request.source
|
|
10133
10369
|
});
|
|
10134
|
-
if (
|
|
10370
|
+
if (finality) {
|
|
10371
|
+
const proof2 = await hyperbridge.queryProof(
|
|
10372
|
+
{ Responses: [response?.commitment] },
|
|
10373
|
+
request.source,
|
|
10374
|
+
BigInt(finality.height)
|
|
10375
|
+
);
|
|
10376
|
+
return {
|
|
10377
|
+
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10378
|
+
metadata: {
|
|
10379
|
+
blockHash: finality.blockHash,
|
|
10380
|
+
blockNumber: finality.height,
|
|
10381
|
+
transactionHash: finality.transactionHash,
|
|
10382
|
+
timestamp: finality.timestamp,
|
|
10383
|
+
calldata: encodeGetResponse(BigInt(finality.height), proof2)
|
|
10384
|
+
}
|
|
10385
|
+
};
|
|
10386
|
+
}
|
|
10387
|
+
if (sourceChain instanceof EvmChain) {
|
|
10135
10388
|
const hyperbridgeSubstrate = hyperbridge;
|
|
10136
10389
|
const currentEpoch = await sourceChain.currentEpoch();
|
|
10137
10390
|
const consensusResult = await waitOrAbort(this.ctx, {
|
|
@@ -10143,12 +10396,12 @@ var GetRequestClient = class {
|
|
|
10143
10396
|
request.source,
|
|
10144
10397
|
consensusResult.provenHeight
|
|
10145
10398
|
);
|
|
10146
|
-
const
|
|
10399
|
+
const calldata = sourceChain.encode({
|
|
10147
10400
|
kind: "BatchConsensusAndGetResponse",
|
|
10148
10401
|
consensusProofs: consensusResult.proofs,
|
|
10149
10402
|
proof: {
|
|
10150
10403
|
stateMachine: stateMachineId,
|
|
10151
|
-
consensusStateId
|
|
10404
|
+
consensusStateId,
|
|
10152
10405
|
proof: proof2,
|
|
10153
10406
|
height: consensusResult.provenHeight
|
|
10154
10407
|
},
|
|
@@ -10163,20 +10416,7 @@ var GetRequestClient = class {
|
|
|
10163
10416
|
],
|
|
10164
10417
|
signer: pad("0x")
|
|
10165
10418
|
});
|
|
10166
|
-
|
|
10167
|
-
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10168
|
-
metadata: {
|
|
10169
|
-
blockHash: request.statuses[hyperbridgeDeliveredIndex].metadata.blockHash,
|
|
10170
|
-
blockNumber: Number(consensusResult.provenHeight),
|
|
10171
|
-
transactionHash: request.statuses[hyperbridgeDeliveredIndex].metadata.transactionHash,
|
|
10172
|
-
// @ts-ignore
|
|
10173
|
-
timestamp: request.statuses[hyperbridgeDeliveredIndex].metadata.timestamp,
|
|
10174
|
-
calldata: calldata2
|
|
10175
|
-
}
|
|
10176
|
-
};
|
|
10177
|
-
}
|
|
10178
|
-
if (!finality) {
|
|
10179
|
-
finality = await waitOrAbort(this.ctx, {
|
|
10419
|
+
const hyperbridgeFinality = await waitOrAbort(this.ctx, {
|
|
10180
10420
|
signal,
|
|
10181
10421
|
promise: () => this.queries.queryStateMachineUpdateByHeight({
|
|
10182
10422
|
statemachineId: stateMachineId,
|
|
@@ -10184,31 +10424,30 @@ var GetRequestClient = class {
|
|
|
10184
10424
|
chain: stateMachineId
|
|
10185
10425
|
})
|
|
10186
10426
|
});
|
|
10427
|
+
return {
|
|
10428
|
+
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10429
|
+
metadata: {
|
|
10430
|
+
blockHash: hyperbridgeFinality.blockHash,
|
|
10431
|
+
blockNumber: hyperbridgeFinality.height,
|
|
10432
|
+
transactionHash: hyperbridgeFinality.transactionHash,
|
|
10433
|
+
timestamp: hyperbridgeFinality.timestamp,
|
|
10434
|
+
calldata
|
|
10435
|
+
}
|
|
10436
|
+
};
|
|
10187
10437
|
}
|
|
10438
|
+
finality = await waitOrAbort(this.ctx, {
|
|
10439
|
+
signal,
|
|
10440
|
+
promise: () => this.queries.queryStateMachineUpdateByHeight({
|
|
10441
|
+
statemachineId: stateMachineId,
|
|
10442
|
+
height: Number(neededHeight),
|
|
10443
|
+
chain: request.source
|
|
10444
|
+
})
|
|
10445
|
+
});
|
|
10188
10446
|
const proof = await hyperbridge.queryProof(
|
|
10189
10447
|
{ Responses: [response?.commitment] },
|
|
10190
10448
|
request.source,
|
|
10191
10449
|
BigInt(finality.height)
|
|
10192
10450
|
);
|
|
10193
|
-
const calldata = sourceChain.encode({
|
|
10194
|
-
kind: "GetResponse",
|
|
10195
|
-
proof: {
|
|
10196
|
-
stateMachine: stateMachineId,
|
|
10197
|
-
consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
|
|
10198
|
-
proof,
|
|
10199
|
-
height: BigInt(finality.height)
|
|
10200
|
-
},
|
|
10201
|
-
responses: [
|
|
10202
|
-
{
|
|
10203
|
-
get: request,
|
|
10204
|
-
values: request.keys.map((key, index) => ({
|
|
10205
|
-
key,
|
|
10206
|
-
value: response?.values[index] || "0x"
|
|
10207
|
-
}))
|
|
10208
|
-
}
|
|
10209
|
-
],
|
|
10210
|
-
signer: pad("0x")
|
|
10211
|
-
});
|
|
10212
10451
|
return {
|
|
10213
10452
|
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10214
10453
|
metadata: {
|
|
@@ -10216,7 +10455,7 @@ var GetRequestClient = class {
|
|
|
10216
10455
|
blockNumber: finality.height,
|
|
10217
10456
|
transactionHash: finality.transactionHash,
|
|
10218
10457
|
timestamp: finality.timestamp,
|
|
10219
|
-
calldata
|
|
10458
|
+
calldata: encodeGetResponse(BigInt(finality.height), proof)
|
|
10220
10459
|
}
|
|
10221
10460
|
};
|
|
10222
10461
|
}
|
|
@@ -10719,7 +10958,7 @@ var PostRequestClient = class {
|
|
|
10719
10958
|
const finality = await this.queries.queryStateMachineUpdateByHeight({
|
|
10720
10959
|
statemachineId: config.stateMachineId,
|
|
10721
10960
|
height: hyperbridgeDelivered.metadata.blockNumber,
|
|
10722
|
-
chain:
|
|
10961
|
+
chain: request.dest
|
|
10723
10962
|
});
|
|
10724
10963
|
if (finality) {
|
|
10725
10964
|
const proof = await hyperbridge.queryProof(
|
|
@@ -10774,14 +11013,19 @@ var PostRequestClient = class {
|
|
|
10774
11013
|
requests: [request],
|
|
10775
11014
|
signer: pad("0x")
|
|
10776
11015
|
});
|
|
11016
|
+
const hyperbridgeFinality = await this.queries.queryStateMachineUpdateByHeight({
|
|
11017
|
+
statemachineId: config.stateMachineId,
|
|
11018
|
+
height: hyperbridgeDelivered.metadata.blockNumber,
|
|
11019
|
+
chain: config.stateMachineId
|
|
11020
|
+
});
|
|
11021
|
+
if (!hyperbridgeFinality) return void 0;
|
|
10777
11022
|
return {
|
|
10778
11023
|
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10779
11024
|
metadata: {
|
|
10780
|
-
blockHash:
|
|
10781
|
-
blockNumber:
|
|
10782
|
-
transactionHash:
|
|
10783
|
-
|
|
10784
|
-
timestamp: hyperbridgeDelivered.metadata.timestamp,
|
|
11025
|
+
blockHash: hyperbridgeFinality.blockHash,
|
|
11026
|
+
blockNumber: hyperbridgeFinality.height,
|
|
11027
|
+
transactionHash: hyperbridgeFinality.transactionHash,
|
|
11028
|
+
timestamp: hyperbridgeFinality.timestamp,
|
|
10785
11029
|
calldata
|
|
10786
11030
|
}
|
|
10787
11031
|
};
|
|
@@ -10804,7 +11048,7 @@ var PostRequestClient = class {
|
|
|
10804
11048
|
let finality = await this.queries.queryStateMachineUpdateByHeight({
|
|
10805
11049
|
statemachineId: stateMachineId,
|
|
10806
11050
|
height: Number(neededHeight),
|
|
10807
|
-
chain:
|
|
11051
|
+
chain: request.dest
|
|
10808
11052
|
});
|
|
10809
11053
|
if (!finality && destChain instanceof EvmChain) {
|
|
10810
11054
|
const hyperbridgeSubstrate = hyperbridge;
|
|
@@ -10832,14 +11076,21 @@ var PostRequestClient = class {
|
|
|
10832
11076
|
requests: [request],
|
|
10833
11077
|
signer: pad("0x")
|
|
10834
11078
|
});
|
|
11079
|
+
const hyperbridgeFinality = await waitOrAbort(this.ctx, {
|
|
11080
|
+
signal,
|
|
11081
|
+
promise: () => this.queries.queryStateMachineUpdateByHeight({
|
|
11082
|
+
statemachineId: stateMachineId,
|
|
11083
|
+
height: Number(neededHeight),
|
|
11084
|
+
chain: stateMachineId
|
|
11085
|
+
})
|
|
11086
|
+
});
|
|
10835
11087
|
return {
|
|
10836
11088
|
status: RequestStatus.HYPERBRIDGE_FINALIZED,
|
|
10837
11089
|
metadata: {
|
|
10838
|
-
blockHash:
|
|
10839
|
-
blockNumber:
|
|
10840
|
-
transactionHash:
|
|
10841
|
-
|
|
10842
|
-
timestamp: request.statuses[hyperbridgeDeliveredIndex].metadata.timestamp,
|
|
11090
|
+
blockHash: hyperbridgeFinality.blockHash,
|
|
11091
|
+
blockNumber: hyperbridgeFinality.height,
|
|
11092
|
+
transactionHash: hyperbridgeFinality.transactionHash,
|
|
11093
|
+
timestamp: hyperbridgeFinality.timestamp,
|
|
10843
11094
|
calldata: calldata2
|
|
10844
11095
|
}
|
|
10845
11096
|
};
|
|
@@ -10850,7 +11101,7 @@ var PostRequestClient = class {
|
|
|
10850
11101
|
promise: () => this.queries.queryStateMachineUpdateByHeight({
|
|
10851
11102
|
statemachineId: stateMachineId,
|
|
10852
11103
|
height: Number(neededHeight),
|
|
10853
|
-
chain:
|
|
11104
|
+
chain: request.dest
|
|
10854
11105
|
})
|
|
10855
11106
|
});
|
|
10856
11107
|
}
|
|
@@ -16742,9 +16993,9 @@ var GasEstimator = class {
|
|
|
16742
16993
|
from: this.ctx.source.configService.getIntentGatewayAddress(destChainId),
|
|
16743
16994
|
to: this.ctx.source.configService.getIntentGatewayAddress(sourceChainId)
|
|
16744
16995
|
};
|
|
16996
|
+
postRequestFeeInDestFeeToken = postRequestFeeInDestFeeToken * 1005n / 1000n;
|
|
16745
16997
|
let protocolFeeInNativeToken = await this.ctx.dest.quoteNative(postRequest, postRequestFeeInDestFeeToken).catch(() => 0n);
|
|
16746
16998
|
protocolFeeInNativeToken = protocolFeeInNativeToken * 1005n / 1000n;
|
|
16747
|
-
postRequestFeeInDestFeeToken = postRequestFeeInDestFeeToken * 1005n / 1000n;
|
|
16748
16999
|
return { postRequestFee: postRequestFeeInDestFeeToken, protocolFee: protocolFeeInNativeToken };
|
|
16749
17000
|
}
|
|
16750
17001
|
/**
|