@hyperbridge/sdk 2.3.1 → 2.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/index.d.ts +2 -2
- package/dist/browser/index.js +101 -56
- package/dist/browser/index.js.map +1 -1
- package/dist/node/index.cjs +101 -56
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.d.cts +2 -2
- package/dist/node/index.d.ts +2 -2
- package/dist/node/index.js +101 -56
- package/dist/node/index.js.map +1 -1
- package/package.json +1 -1
package/dist/node/index.d.cts
CHANGED
|
@@ -175,9 +175,9 @@ declare class EvmChain implements IChain {
|
|
|
175
175
|
quoteNative(request: IPostRequest | IGetRequest, fee: bigint): Promise<bigint>;
|
|
176
176
|
/**
|
|
177
177
|
* Given a desired output amount of a token, returns how much native is needed as input.
|
|
178
|
-
* Uses the chain's Uniswap V2 router: WETH → tokenOut path.
|
|
178
|
+
* Uses the chain's Uniswap V2 router (or `router` when provided): WETH → tokenOut path.
|
|
179
179
|
*/
|
|
180
|
-
getAmountsIn(amountOut: bigint, tokenOutForQuote: HexString, chain?: string): Promise<bigint>;
|
|
180
|
+
getAmountsIn(amountOut: bigint, tokenOutForQuote: HexString, chain?: string, router?: HexString): Promise<bigint>;
|
|
181
181
|
/**
|
|
182
182
|
* Given an input amount of native token, returns how much of the output token you get.
|
|
183
183
|
* Uses the chain's Uniswap V2 router: WETH → tokenOut path.
|
package/dist/node/index.d.ts
CHANGED
|
@@ -175,9 +175,9 @@ declare class EvmChain implements IChain {
|
|
|
175
175
|
quoteNative(request: IPostRequest | IGetRequest, fee: bigint): Promise<bigint>;
|
|
176
176
|
/**
|
|
177
177
|
* Given a desired output amount of a token, returns how much native is needed as input.
|
|
178
|
-
* Uses the chain's Uniswap V2 router: WETH → tokenOut path.
|
|
178
|
+
* Uses the chain's Uniswap V2 router (or `router` when provided): WETH → tokenOut path.
|
|
179
179
|
*/
|
|
180
|
-
getAmountsIn(amountOut: bigint, tokenOutForQuote: HexString, chain?: string): Promise<bigint>;
|
|
180
|
+
getAmountsIn(amountOut: bigint, tokenOutForQuote: HexString, chain?: string, router?: HexString): Promise<bigint>;
|
|
181
181
|
/**
|
|
182
182
|
* Given an input amount of native token, returns how much of the output token you get.
|
|
183
183
|
* Uses the chain's Uniswap V2 router: WETH → tokenOut path.
|
package/dist/node/index.js
CHANGED
|
@@ -6775,15 +6775,20 @@ var EvmChain = class _EvmChain {
|
|
|
6775
6775
|
async quoteNative(request, fee) {
|
|
6776
6776
|
const totalFee = await this.quote(request) + fee;
|
|
6777
6777
|
const feeToken = await this.getFeeTokenWithDecimals();
|
|
6778
|
-
|
|
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);
|
|
6779
6784
|
}
|
|
6780
6785
|
/**
|
|
6781
6786
|
* Given a desired output amount of a token, returns how much native is needed as input.
|
|
6782
|
-
* 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.
|
|
6783
6788
|
*/
|
|
6784
|
-
async getAmountsIn(amountOut, tokenOutForQuote, chain) {
|
|
6789
|
+
async getAmountsIn(amountOut, tokenOutForQuote, chain, router) {
|
|
6785
6790
|
const chainId = chain ?? `EVM-${this.params.chainId}`;
|
|
6786
|
-
const v2Router = this.configService.getUniswapRouterV2Address(chainId);
|
|
6791
|
+
const v2Router = router ?? this.configService.getUniswapRouterV2Address(chainId);
|
|
6787
6792
|
const WETH = this.configService.getWrappedNativeAssetWithDecimals(chainId).asset;
|
|
6788
6793
|
const v2AmountIn = await this.publicClient.simulateContract({
|
|
6789
6794
|
address: v2Router,
|
|
@@ -7028,6 +7033,11 @@ var ExpectedError = class _ExpectedError extends Error {
|
|
|
7028
7033
|
return error instanceof _ExpectedError;
|
|
7029
7034
|
}
|
|
7030
7035
|
};
|
|
7036
|
+
|
|
7037
|
+
// src/configs/constants.ts
|
|
7038
|
+
var ISMP_PREFIX = ":child_storage:default:ISMPv2";
|
|
7039
|
+
|
|
7040
|
+
// src/chains/substrate.ts
|
|
7031
7041
|
var HttpRpcClient = class {
|
|
7032
7042
|
constructor(url) {
|
|
7033
7043
|
this.url = url;
|
|
@@ -7151,7 +7161,7 @@ var SubstrateChain = class _SubstrateChain {
|
|
|
7151
7161
|
* @returns {Promise<HexString | undefined>} The commitment data if found, undefined otherwise.
|
|
7152
7162
|
*/
|
|
7153
7163
|
async queryRequestCommitment(commitment) {
|
|
7154
|
-
const prefix = toHex(
|
|
7164
|
+
const prefix = toHex(ISMP_PREFIX);
|
|
7155
7165
|
const key = this.requestCommitmentKey(commitment);
|
|
7156
7166
|
const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
|
|
7157
7167
|
return item;
|
|
@@ -7162,7 +7172,7 @@ var SubstrateChain = class _SubstrateChain {
|
|
|
7162
7172
|
* @returns {Promise<HexString | undefined>} The relayer address responsible for delivering the request.
|
|
7163
7173
|
*/
|
|
7164
7174
|
async queryRequestReceipt(commitment) {
|
|
7165
|
-
const prefix = toHex(
|
|
7175
|
+
const prefix = toHex(ISMP_PREFIX);
|
|
7166
7176
|
const key = this.requestReceiptKey(commitment);
|
|
7167
7177
|
const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
|
|
7168
7178
|
return item;
|
|
@@ -7186,7 +7196,7 @@ var SubstrateChain = class _SubstrateChain {
|
|
|
7186
7196
|
* @returns {Promise<HexString | undefined>} The receipt data if present, otherwise undefined.
|
|
7187
7197
|
*/
|
|
7188
7198
|
async queryResponseReceipt(commitment) {
|
|
7189
|
-
const prefix = toHex(
|
|
7199
|
+
const prefix = toHex(ISMP_PREFIX);
|
|
7190
7200
|
const key = this.responseReceiptKey(commitment);
|
|
7191
7201
|
const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
|
|
7192
7202
|
return item;
|
|
@@ -15294,7 +15304,11 @@ var OrderExecutor = class {
|
|
|
15294
15304
|
*/
|
|
15295
15305
|
async fetchBids(params) {
|
|
15296
15306
|
const { commitment, solver, solverLockStartTime } = params;
|
|
15297
|
-
const
|
|
15307
|
+
const intentsCoprocessor = this.ctx.intentsCoprocessor;
|
|
15308
|
+
if (!intentsCoprocessor) {
|
|
15309
|
+
throw new Error("IntentsCoprocessor required for order execution");
|
|
15310
|
+
}
|
|
15311
|
+
const fetchedBids = await intentsCoprocessor.getBidsForOrder(commitment);
|
|
15298
15312
|
if (solver) {
|
|
15299
15313
|
const { address, timeoutMs } = solver;
|
|
15300
15314
|
const solverLockActive = Date.now() - solverLockStartTime < timeoutMs;
|
|
@@ -15383,7 +15397,7 @@ var OrderExecutor = class {
|
|
|
15383
15397
|
* → (`FILLED` | `PARTIAL_FILL`)* → (`FILLED` | `EXPIRED`)
|
|
15384
15398
|
*
|
|
15385
15399
|
* **Cross-chain:** `AWAITING_BIDS` → `BIDS_RECEIVED` → `BID_SELECTED`
|
|
15386
|
-
*
|
|
15400
|
+
* → `FILLED`
|
|
15387
15401
|
*/
|
|
15388
15402
|
async *executeOrder(options) {
|
|
15389
15403
|
const { order, sessionPrivateKey, auctionTimeMs, pollIntervalMs = DEFAULT_POLL_INTERVAL, solver } = options;
|
|
@@ -15522,7 +15536,13 @@ var OrderExecutor = class {
|
|
|
15522
15536
|
userOp: result.userOp,
|
|
15523
15537
|
transactionHash: result.txnHash
|
|
15524
15538
|
};
|
|
15525
|
-
const fill = this.processFillResult(
|
|
15539
|
+
const fill = this.processFillResult(
|
|
15540
|
+
result,
|
|
15541
|
+
commitment,
|
|
15542
|
+
targetAssets,
|
|
15543
|
+
totalFilledAssets,
|
|
15544
|
+
remainingAssets
|
|
15545
|
+
);
|
|
15526
15546
|
totalFilledAssets = fill.totalFilledAssets;
|
|
15527
15547
|
remainingAssets = fill.remainingAssets;
|
|
15528
15548
|
if (fill.update) {
|
|
@@ -15548,6 +15568,10 @@ var OrderCanceller = class {
|
|
|
15548
15568
|
this.ctx = ctx;
|
|
15549
15569
|
}
|
|
15550
15570
|
ctx;
|
|
15571
|
+
logger = createConsola({
|
|
15572
|
+
level: LogLevels.info,
|
|
15573
|
+
formatOptions: { columns: 80, colors: true, compact: true, date: false }
|
|
15574
|
+
}).withTag("[OrderCanceller]");
|
|
15551
15575
|
/**
|
|
15552
15576
|
* Returns both the native token cost and the relayer fee for cancelling an
|
|
15553
15577
|
* order. Frontends can use `relayerFee` to approve the ERC-20 spend before
|
|
@@ -15963,32 +15987,55 @@ var OrderCanceller = class {
|
|
|
15963
15987
|
}
|
|
15964
15988
|
/**
|
|
15965
15989
|
* Submits an unsigned GET request message to Hyperbridge and waits until
|
|
15966
|
-
* the
|
|
15990
|
+
* the GET response receipt is confirmed on-chain.
|
|
15967
15991
|
*
|
|
15968
|
-
*
|
|
15969
|
-
*
|
|
15992
|
+
* GET handling on Hyperbridge creates a response receipt keyed by the
|
|
15993
|
+
* request commitment. That receipt is the durable delivery signal, so a
|
|
15994
|
+
* duplicate unsigned submission is considered successful only if the
|
|
15995
|
+
* response receipt can be observed.
|
|
15970
15996
|
*
|
|
15971
15997
|
* @param hyperbridge - Hyperbridge Substrate chain client.
|
|
15972
15998
|
* @param commitment - The GET request commitment hash used to poll for the receipt.
|
|
15973
15999
|
* @param message - The fully constructed GET request message to submit.
|
|
15974
16000
|
*/
|
|
15975
16001
|
async submitAndConfirmReceipt(hyperbridge, commitment, message) {
|
|
15976
|
-
|
|
15977
|
-
if (
|
|
15978
|
-
|
|
15979
|
-
|
|
15980
|
-
|
|
15981
|
-
|
|
16002
|
+
this.logger.info(`Checking GET response receipt before Hyperbridge delivery (${commitment})`);
|
|
16003
|
+
if (await this.queryDeliveredReceipt(hyperbridge, commitment)) {
|
|
16004
|
+
this.logger.info(`GET ${commitment} already delivered to Hyperbridge; skipping unsigned submission`);
|
|
16005
|
+
return;
|
|
16006
|
+
}
|
|
16007
|
+
try {
|
|
16008
|
+
this.logger.info(`Submitting unsigned GET ${commitment} to Hyperbridge`);
|
|
16009
|
+
await hyperbridge.submitUnsigned(message);
|
|
16010
|
+
this.logger.info(`Unsigned GET ${commitment} submitted; waiting for Hyperbridge response receipt`);
|
|
15982
16011
|
await sleep(3e4);
|
|
15983
|
-
|
|
15984
|
-
|
|
15985
|
-
|
|
15986
|
-
if (!value) throw new Error("Receipt not found");
|
|
15987
|
-
return value;
|
|
15988
|
-
},
|
|
15989
|
-
{ maxRetries: 10, backoffMs: 5e3, logMessage: "Checking for receipt" }
|
|
16012
|
+
} catch (error) {
|
|
16013
|
+
this.logger.warn(
|
|
16014
|
+
`Unsigned GET submit failed for ${commitment}; polling response receipt before failing: ${String(error)}`
|
|
15990
16015
|
);
|
|
15991
16016
|
}
|
|
16017
|
+
try {
|
|
16018
|
+
await this.pollDeliveredReceipt(hyperbridge, commitment);
|
|
16019
|
+
this.logger.info(`Confirmed Hyperbridge GET delivery for ${commitment}`);
|
|
16020
|
+
} catch (error) {
|
|
16021
|
+
const message2 = `Failed to deliver GET request to Hyperbridge; no response receipt found for ${commitment}: ${String(error)}`;
|
|
16022
|
+
this.logger.error(message2);
|
|
16023
|
+
throw new Error(message2);
|
|
16024
|
+
}
|
|
16025
|
+
}
|
|
16026
|
+
async queryDeliveredReceipt(hyperbridge, commitment) {
|
|
16027
|
+
return hyperbridge.queryResponseReceipt(commitment);
|
|
16028
|
+
}
|
|
16029
|
+
async pollDeliveredReceipt(hyperbridge, commitment) {
|
|
16030
|
+
this.logger.info(`Polling Hyperbridge GET response receipt for ${commitment}`);
|
|
16031
|
+
return retryPromise(
|
|
16032
|
+
async () => {
|
|
16033
|
+
const value = await this.queryDeliveredReceipt(hyperbridge, commitment);
|
|
16034
|
+
if (!value) throw new Error(`GET response receipt not found for ${commitment}`);
|
|
16035
|
+
return value;
|
|
16036
|
+
},
|
|
16037
|
+
{ maxRetries: 10, backoffMs: 5e3, logMessage: `Checking GET response receipt ${commitment}` }
|
|
16038
|
+
);
|
|
15992
16039
|
}
|
|
15993
16040
|
/**
|
|
15994
16041
|
* Estimates the relayer fee for delivering a POST from dest to source.
|
|
@@ -16059,7 +16106,7 @@ var BidImpl = class {
|
|
|
16059
16106
|
const sessionKeyAddress = this.order.session;
|
|
16060
16107
|
const sessionKeyData = this.sessionPrivateKey ? { privateKey: this.sessionPrivateKey } : await this.ctx.sessionKeyStorage.getSessionKeyByAddress(sessionKeyAddress);
|
|
16061
16108
|
if (!sessionKeyData) {
|
|
16062
|
-
throw new Error(
|
|
16109
|
+
throw new Error(`SessionKey not found for commitment: ${commitment}`);
|
|
16063
16110
|
}
|
|
16064
16111
|
const signature = await CryptoUtils.signSolverSelection(
|
|
16065
16112
|
commitment,
|
|
@@ -16119,8 +16166,8 @@ var BidImpl = class {
|
|
|
16119
16166
|
/**
|
|
16120
16167
|
* Signs the `SelectSolver` message with the session key, appends it to the
|
|
16121
16168
|
* solver's existing UserOp signature, and submits the UserOperation to the
|
|
16122
|
-
* bundler.
|
|
16123
|
-
*
|
|
16169
|
+
* bundler. Waits for the receipt and reads `OrderFilled` / `PartialFill`
|
|
16170
|
+
* logs to determine fill status.
|
|
16124
16171
|
*
|
|
16125
16172
|
* @returns A {@link SelectBidResult} with the submitted UserOperation, its hash,
|
|
16126
16173
|
* the solver address, transaction hash, and fill status.
|
|
@@ -16160,33 +16207,31 @@ var BidImpl = class {
|
|
|
16160
16207
|
{ maxRetries: 5, backoffMs: 2e3, logMessage: "Fetching user operation receipt" }
|
|
16161
16208
|
);
|
|
16162
16209
|
txnHash = receipt.receipt.transactionHash;
|
|
16163
|
-
|
|
16164
|
-
|
|
16165
|
-
|
|
16166
|
-
|
|
16167
|
-
|
|
16168
|
-
|
|
16169
|
-
|
|
16170
|
-
|
|
16171
|
-
|
|
16172
|
-
|
|
16173
|
-
|
|
16174
|
-
|
|
16175
|
-
|
|
16176
|
-
|
|
16177
|
-
|
|
16178
|
-
|
|
16179
|
-
|
|
16180
|
-
|
|
16181
|
-
|
|
16182
|
-
|
|
16183
|
-
|
|
16184
|
-
|
|
16185
|
-
filledAssets = matched.args.outputs ?? [];
|
|
16186
|
-
}
|
|
16187
|
-
} catch {
|
|
16188
|
-
throw new Error("Failed to determine fill status from logs");
|
|
16210
|
+
try {
|
|
16211
|
+
const chainReceipt = await this.ctx.dest.client.waitForTransactionReceipt({
|
|
16212
|
+
hash: txnHash,
|
|
16213
|
+
confirmations: 1
|
|
16214
|
+
});
|
|
16215
|
+
const events = parseEventLogs({
|
|
16216
|
+
abi: ABI3,
|
|
16217
|
+
logs: chainReceipt.logs,
|
|
16218
|
+
eventName: ["OrderFilled", "PartialFill"]
|
|
16219
|
+
});
|
|
16220
|
+
const matched = events.find((e) => {
|
|
16221
|
+
if (e.eventName === "OrderFilled")
|
|
16222
|
+
return e.args.commitment.toLowerCase() === commitment.toLowerCase();
|
|
16223
|
+
if (e.eventName === "PartialFill")
|
|
16224
|
+
return e.args.commitment.toLowerCase() === commitment.toLowerCase();
|
|
16225
|
+
return false;
|
|
16226
|
+
});
|
|
16227
|
+
if (matched?.eventName === "OrderFilled") {
|
|
16228
|
+
fillStatus = "full";
|
|
16229
|
+
} else if (matched?.eventName === "PartialFill") {
|
|
16230
|
+
fillStatus = "partial";
|
|
16231
|
+
filledAssets = matched.args.outputs ?? [];
|
|
16189
16232
|
}
|
|
16233
|
+
} catch {
|
|
16234
|
+
throw new Error("Failed to determine fill status from logs");
|
|
16190
16235
|
}
|
|
16191
16236
|
} catch (err) {
|
|
16192
16237
|
throw new Error(`Failed to execute bid: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -16988,9 +17033,9 @@ var GasEstimator = class {
|
|
|
16988
17033
|
from: this.ctx.source.configService.getIntentGatewayAddress(destChainId),
|
|
16989
17034
|
to: this.ctx.source.configService.getIntentGatewayAddress(sourceChainId)
|
|
16990
17035
|
};
|
|
17036
|
+
postRequestFeeInDestFeeToken = postRequestFeeInDestFeeToken * 1005n / 1000n;
|
|
16991
17037
|
let protocolFeeInNativeToken = await this.ctx.dest.quoteNative(postRequest, postRequestFeeInDestFeeToken).catch(() => 0n);
|
|
16992
17038
|
protocolFeeInNativeToken = protocolFeeInNativeToken * 1005n / 1000n;
|
|
16993
|
-
postRequestFeeInDestFeeToken = postRequestFeeInDestFeeToken * 1005n / 1000n;
|
|
16994
17039
|
return { postRequestFee: postRequestFeeInDestFeeToken, protocolFee: protocolFeeInNativeToken };
|
|
16995
17040
|
}
|
|
16996
17041
|
/**
|