@hyperbridge/sdk 2.5.0 → 2.6.0

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.
@@ -910,6 +910,10 @@ interface ChainConfigData {
910
910
  USDT: string;
911
911
  cNGN?: string;
912
912
  EXT?: string;
913
+ ZARP?: string;
914
+ EURC?: string;
915
+ XSGD?: string;
916
+ TRYB?: string;
913
917
  };
914
918
  tokenDecimals?: {
915
919
  USDC: number;
@@ -1010,6 +1014,13 @@ declare class ChainConfigService {
1010
1014
  getUsdcDecimals(chain: string): number;
1011
1015
  getUsdtDecimals(chain: string): number;
1012
1016
  getCNgnAsset(chain: string): HexString | undefined;
1017
+ /**
1018
+ * Address of `symbol` on `chain` from the per-chain asset table, matched
1019
+ * case-insensitively ("cNGN" ≡ "CNGN"). This table is the single source of
1020
+ * truth for token addresses — the simplex asset registry resolves through
1021
+ * it, so a new asset is added once in `chain.ts` and nowhere else.
1022
+ */
1023
+ getAssetBySymbol(chain: string, symbol: string): HexString | undefined;
1013
1024
  getCNgnDecimals(chain: string): number | undefined;
1014
1025
  getExtAsset(chain: string): HexString | undefined;
1015
1026
  getExtDecimals(chain: string): number | undefined;
@@ -3588,6 +3599,13 @@ interface FillOrderEstimate {
3588
3599
  maxPriorityFeePerGas: bigint;
3589
3600
  totalGasCostWei: bigint;
3590
3601
  totalGasInFeeToken: bigint;
3602
+ /**
3603
+ * Relayer fee for the cross-chain settlement message, denominated in the
3604
+ * SOURCE fee token (same unit as `Order.fees`). This is `RELAYER_MESSAGE_GAS`
3605
+ * priced on the source chain; it is 0 for same-chain fills. A filler's
3606
+ * `order.fees` must cover `totalGasInFeeToken + relayerFeeInSourceFeeToken`.
3607
+ */
3608
+ relayerFeeInSourceFeeToken: bigint;
3591
3609
  }
3592
3610
  /**
3593
3611
  * Result of submitting a bid to Hyperbridge
@@ -4967,10 +4985,12 @@ declare class IntentGateway {
4967
4985
  * placement, fee estimation, bid collection, and execution.
4968
4986
  *
4969
4987
  * **Yield/receive protocol:**
4970
- * 1. If `order.fees` is unset or zero, estimates gas on an internal copy and sets
4971
- * same-chain fees to twice the estimate. Cross-chain orders retain a 1% buffer
4972
- * and include an additional 600k-gas fee uplift, while the wei cost used for
4973
- * the `value` field receives a 2% buffer.
4988
+ * 1. If `order.fees` is unset or zero, estimates gas on an internal copy and
4989
+ * sets same-chain fees to twice the estimate. Cross-chain orders attach
4990
+ * (fill gas + a settlement-message uplift of `RELAYER_MESSAGE_GAS`, the
4991
+ * same gas budget the solver's relayer fee uses) with a 5% buffer over
4992
+ * the whole sum — strictly above the solver's unpadded requirement. The
4993
+ * wei cost used for the `value` field receives a 2% buffer.
4974
4994
  * 2. Yields `AWAITING_PLACE_ORDER` with `{ to, data, value, sessionPrivateKey }`.
4975
4995
  * The caller must sign the transaction and pass it back via `gen.next(signedTx)`.
4976
4996
  * 3. Yields `ORDER_PLACED` with the finalised order and transaction hash once
@@ -2728,7 +2728,11 @@ var chainConfigs = {
2728
2728
  DAI: "0x6b175474e89094c44da98b954eedeac495271d0f",
2729
2729
  USDC: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
2730
2730
  USDT: "0xdac17f958d2ee523a2206206994597c13d831ec7",
2731
- cNGN: "0x17CDB2a01e7a34CbB3DD4b83260B05d0274C8dab"
2731
+ cNGN: "0x17CDB2a01e7a34CbB3DD4b83260B05d0274C8dab",
2732
+ ZARP: "0xb755506531786C8aC63B756BaB1ac387bACB0C04",
2733
+ EURC: "0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c",
2734
+ XSGD: "0x70e8dE73cE538DA2bEEd35d14187F6959a8ecA96",
2735
+ TRYB: "0x2C537E5624e4af88A7ae4060C022609376C8D0EB"
2732
2736
  },
2733
2737
  tokenDecimals: {
2734
2738
  USDC: 6,
@@ -2898,7 +2902,9 @@ var chainConfigs = {
2898
2902
  USDC: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
2899
2903
  USDT: "0xfde4c96c8593536e31f229ea8f37b2ada2699bb2",
2900
2904
  EXT: "0x0e668E5127087e236578893a0e01E41837A28469",
2901
- cNGN: "0x46C85152bFe9f96829aA94755D9f915F9B10EF5F"
2905
+ cNGN: "0x46C85152bFe9f96829aA94755D9f915F9B10EF5F",
2906
+ ZARP: "0xb755506531786C8aC63B756BaB1ac387bACB0C04",
2907
+ EURC: "0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42"
2902
2908
  },
2903
2909
  tokenDecimals: {
2904
2910
  USDC: 6,
@@ -2958,7 +2964,9 @@ var chainConfigs = {
2958
2964
  USDC: "0x3c499c542cef5e3811e1192ce70d8cc03d5c3359",
2959
2965
  USDT: "0xc2132d05d31c914a87c6611c10748aeb04b58e8f",
2960
2966
  EXT: "0x7C8c11ADb8EF7cd3CFa718008Ea048445C6E7209",
2961
- cNGN: "0x52828daa48C1a9A06F37500882b42daf0bE04C3B"
2967
+ cNGN: "0x52828daa48C1a9A06F37500882b42daf0bE04C3B",
2968
+ ZARP: "0xb755506531786C8aC63B756BaB1ac387bACB0C04",
2969
+ XSGD: "0xDC3326e71D45186F113a2F448984CA0e8D201995"
2962
2970
  },
2963
2971
  tokenDecimals: {
2964
2972
  USDC: 6,
@@ -5195,6 +5203,21 @@ var ChainConfigService = class {
5195
5203
  getCNgnAsset(chain) {
5196
5204
  return this.getConfig(chain)?.assets?.cNGN;
5197
5205
  }
5206
+ /**
5207
+ * Address of `symbol` on `chain` from the per-chain asset table, matched
5208
+ * case-insensitively ("cNGN" ≡ "CNGN"). This table is the single source of
5209
+ * truth for token addresses — the simplex asset registry resolves through
5210
+ * it, so a new asset is added once in `chain.ts` and nowhere else.
5211
+ */
5212
+ getAssetBySymbol(chain, symbol) {
5213
+ const assets = this.getConfig(chain)?.assets;
5214
+ if (!assets) return void 0;
5215
+ const target = symbol.trim().toUpperCase();
5216
+ for (const [key, address] of Object.entries(assets)) {
5217
+ if (key.toUpperCase() === target) return address;
5218
+ }
5219
+ return void 0;
5220
+ }
5198
5221
  getCNgnDecimals(chain) {
5199
5222
  return this.getConfig(chain)?.tokenDecimals?.cNGN;
5200
5223
  }
@@ -17301,6 +17324,7 @@ var BidManager = class {
17301
17324
  }
17302
17325
  }
17303
17326
  };
17327
+ var RELAYER_MESSAGE_GAS = 1000000n;
17304
17328
  var GasEstimator = class {
17305
17329
  /**
17306
17330
  * @param ctx - Shared IntentsV2 context providing the source and destination
@@ -17321,7 +17345,12 @@ var GasEstimator = class {
17321
17345
  *
17322
17346
  * **Cross-chain orders:** also estimates the ISMP POST request fee required
17323
17347
  * for the solver to trigger source-chain escrow redemption after filling, and
17324
- * includes it in `fillOptions.relayerFee` and `fillOptions.nativeDispatchFee`.
17348
+ * includes it in `fillOptions.relayerFee`. The dispatch is always paid in the
17349
+ * fee token — `nativeDispatchFee` is fixed at 0. The native rail would draw
17350
+ * from the solver account's native balance, which nothing guarantees, and a
17351
+ * shortfall is invisible to estimation (the account balance is overridden
17352
+ * during simulation) — it would only surface as a reverted execution that
17353
+ * still bills the paymaster.
17325
17354
  *
17326
17355
  * **Bundler path:** constructs a mock `PackedUserOperation` signed by an
17327
17356
  * ephemeral keypair, applies state overrides, and calls
@@ -17370,24 +17399,19 @@ var GasEstimator = class {
17370
17399
  intentGatewayV2Address,
17371
17400
  entryPointAddress
17372
17401
  }),
17373
- isSameChain ? Promise.resolve({ postRequestFee: 0n, protocolFee: 0n }) : this.estimateCrossChainFees(
17374
- sourceFeeToken,
17375
- destFeeToken,
17376
- souceStateMachineId,
17377
- destStateMachineId,
17378
- order
17379
- )
17402
+ isSameChain ? Promise.resolve({ postRequestFee: 0n, relayerFeeInSourceFeeToken: 0n }) : this.estimateCrossChainFees(sourceFeeToken, destFeeToken, souceStateMachineId)
17380
17403
  ]);
17381
17404
  const { viem: stateOverrides, bundler: bundlerStateOverrides } = stateOverridesResult;
17382
17405
  const fillOptions = {
17383
17406
  relayerFee: crossChainFees.postRequestFee,
17384
- nativeDispatchFee: crossChainFees.protocolFee,
17407
+ // Always dispatch with the fee token (see the method docs).
17408
+ nativeDispatchFee: 0n,
17385
17409
  outputs: order.output.assets.map((asset) => ({
17386
17410
  ...asset,
17387
17411
  token: normalizeAddressForEvmBytes32(asset.token)
17388
17412
  }))
17389
17413
  };
17390
- const totalNativeValue = totalEthValue + fillOptions.nativeDispatchFee;
17414
+ const totalNativeValue = totalEthValue;
17391
17415
  const priorityFeeBumpPercent = params.maxPriorityFeePerGasBumpPercent ?? 8;
17392
17416
  const maxFeeBumpPercent = params.maxFeePerGasBumpPercent ?? 10;
17393
17417
  let maxPriorityFeePerGas = gasPrice + gasPrice * BigInt(priorityFeeBumpPercent) / 100n;
@@ -17554,37 +17578,32 @@ var GasEstimator = class {
17554
17578
  maxPriorityFeePerGas,
17555
17579
  totalGasCostWei,
17556
17580
  totalGasInFeeToken: totalGasInSourceFeeToken,
17581
+ relayerFeeInSourceFeeToken: crossChainFees.relayerFeeInSourceFeeToken,
17557
17582
  fillOptions
17558
17583
  };
17559
17584
  }
17560
17585
  /**
17561
- * Estimates cross-chain ISMP POST request fees by running the gas-to-fee-token
17562
- * conversion and host nonce fetch in parallel, then quoting the native dispatch cost.
17563
- */
17564
- async estimateCrossChainFees(sourceFeeToken, destFeeToken, sourceChainId, destChainId, order) {
17565
- const postRequestGas = 400000n;
17566
- const [postRequestFeeInSourceFeeToken, nonce] = await Promise.all([
17567
- convertGasToFeeToken(this.ctx, postRequestGas, "source", sourceChainId),
17568
- this.ctx.dest.getHostNonce()
17569
- ]);
17570
- let postRequestFeeInDestFeeToken = adjustDecimals(
17586
+ * Estimates the cross-chain ISMP POST request fee (the relayer fee for the
17587
+ * RedeemEscrow message), in both the source and destination fee tokens.
17588
+ * The dispatch is always paid in the fee token — the native rail was
17589
+ * removed because it silently drew on a native balance nothing guarantees.
17590
+ */
17591
+ async estimateCrossChainFees(sourceFeeToken, destFeeToken, sourceChainId) {
17592
+ const postRequestFeeInSourceFeeToken = await convertGasToFeeToken(
17593
+ this.ctx,
17594
+ RELAYER_MESSAGE_GAS,
17595
+ "source",
17596
+ sourceChainId
17597
+ );
17598
+ const postRequestFeeInDestFeeToken = adjustDecimals(
17571
17599
  postRequestFeeInSourceFeeToken,
17572
17600
  sourceFeeToken.decimals,
17573
17601
  destFeeToken.decimals
17574
17602
  );
17575
- const postRequest = {
17576
- source: destChainId,
17577
- dest: sourceChainId,
17578
- body: constructRedeemEscrowRequestBody({ ...order, id: orderCommitment(order) }, MOCK_ADDRESS),
17579
- timeoutTimestamp: 0n,
17580
- nonce,
17581
- from: this.ctx.source.configService.getIntentGatewayAddress(destChainId),
17582
- to: this.ctx.source.configService.getIntentGatewayAddress(sourceChainId)
17603
+ return {
17604
+ postRequestFee: postRequestFeeInDestFeeToken,
17605
+ relayerFeeInSourceFeeToken: postRequestFeeInSourceFeeToken
17583
17606
  };
17584
- postRequestFeeInDestFeeToken = postRequestFeeInDestFeeToken * 1005n / 1000n;
17585
- let protocolFeeInNativeToken = await this.ctx.dest.quoteNative(postRequest, postRequestFeeInDestFeeToken).catch(() => 0n);
17586
- protocolFeeInNativeToken = protocolFeeInNativeToken * 1005n / 1000n;
17587
- return { postRequestFee: postRequestFeeInDestFeeToken, protocolFee: protocolFeeInNativeToken };
17588
17607
  }
17589
17608
  /**
17590
17609
  * Builds EVM state override objects for gas estimation of the `fillOrder`
@@ -18344,7 +18363,6 @@ function isConfiguredAddress(address) {
18344
18363
  }
18345
18364
 
18346
18365
  // src/protocols/intents/IntentGateway.ts
18347
- var CROSS_CHAIN_ORDER_FEE_GAS_BUMP = 600000n;
18348
18366
  var IntentGateway = class _IntentGateway {
18349
18367
  /** EVM chain on which orders are placed and escrowed. */
18350
18368
  source;
@@ -18531,10 +18549,12 @@ var IntentGateway = class _IntentGateway {
18531
18549
  * placement, fee estimation, bid collection, and execution.
18532
18550
  *
18533
18551
  * **Yield/receive protocol:**
18534
- * 1. If `order.fees` is unset or zero, estimates gas on an internal copy and sets
18535
- * same-chain fees to twice the estimate. Cross-chain orders retain a 1% buffer
18536
- * and include an additional 600k-gas fee uplift, while the wei cost used for
18537
- * the `value` field receives a 2% buffer.
18552
+ * 1. If `order.fees` is unset or zero, estimates gas on an internal copy and
18553
+ * sets same-chain fees to twice the estimate. Cross-chain orders attach
18554
+ * (fill gas + a settlement-message uplift of `RELAYER_MESSAGE_GAS`, the
18555
+ * same gas budget the solver's relayer fee uses) with a 5% buffer over
18556
+ * the whole sum — strictly above the solver's unpadded requirement. The
18557
+ * wei cost used for the `value` field receives a 2% buffer.
18538
18558
  * 2. Yields `AWAITING_PLACE_ORDER` with `{ to, data, value, sessionPrivateKey }`.
18539
18559
  * The caller must sign the transaction and pass it back via `gen.next(signedTx)`.
18540
18560
  * 3. Yields `ORDER_PLACED` with the finalised order and transaction hash once
@@ -18571,11 +18591,11 @@ var IntentGateway = class _IntentGateway {
18571
18591
  value = estimate.totalGasCostWei + estimate.totalGasCostWei * 2n / 100n;
18572
18592
  const crossChainFeeBump = isSameChain ? 0n : await convertGasToFeeToken(
18573
18593
  this.ctx,
18574
- CROSS_CHAIN_ORDER_FEE_GAS_BUMP,
18594
+ RELAYER_MESSAGE_GAS,
18575
18595
  "source",
18576
18596
  this.source.config.stateMachineId
18577
18597
  );
18578
- executionOrder.fees = isSameChain ? estimate.totalGasInFeeToken * 2n : estimate.totalGasInFeeToken + (crossChainFeeBump + estimate.totalGasInFeeToken * 1n / 100n);
18598
+ executionOrder.fees = isSameChain ? estimate.totalGasInFeeToken * 2n : (estimate.totalGasInFeeToken + crossChainFeeBump) * 105n / 100n;
18579
18599
  }
18580
18600
  const placeOrderGen = this.orderPlacer.placeOrder(executionOrder, graffiti);
18581
18601
  const placeOrderFirst = await placeOrderGen.next();