@moonbeam-network/mrl 4.1.3 → 4.2.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.
package/build/index.d.ts CHANGED
@@ -28,18 +28,22 @@ interface TransferParams {
28
28
  statusCallback?: (status: ISubmittableResult) => void;
29
29
  sendOnlyRemoteExecution?: boolean;
30
30
  }
31
- interface MrlOtherFees {
32
- /** Protocol bridge fee (e.g., Snowbridge) - deducted from transfer amount */
33
- protocol?: AssetAmount;
34
- /** Relayer service fee for automatic execution - only applies when isAutomatic=true */
35
- relayer?: AssetAmount;
31
+ interface FeeWithBalance {
32
+ fee: AssetAmount;
33
+ balance: AssetAmount;
34
+ }
35
+ interface MrlExtraFees {
36
+ /** Deducted from source balance */
37
+ local?: FeeWithBalance;
38
+ /** Deducted from transfer amount*/
39
+ remote?: FeeWithBalance;
36
40
  }
37
41
  interface SourceTransferData extends SourceChainTransferData {
38
42
  destinationFeeBalance: AssetAmount;
39
43
  bridgeChainFeeBalance?: AssetAmount;
40
44
  feeBalance: AssetAmount;
41
45
  max: AssetAmount;
42
- otherFees: MrlOtherFees;
46
+ extraFees: MrlExtraFees;
43
47
  }
44
48
  interface DestinationTransferData extends ChainTransferData {
45
49
  }
@@ -88,4 +92,4 @@ declare function Mrl(options?: MrlOptions): {
88
92
  getExecuteTransferData({ txId, chain }: WormholeExecuteTransferParams): Promise<ExecuteTransferData>;
89
93
  };
90
94
 
91
- export { type BridgeChainTransferData, type ChainTransferData, type DestinationTransferData, type ExecuteTransferData, Mrl, type MrlOptions, type MrlOtherFees, type Signers, type SourceTransferData, type TransferData, type TransferParams };
95
+ export { type BridgeChainTransferData, type ChainTransferData, type DestinationTransferData, type ExecuteTransferData, type FeeWithBalance, Mrl, type MrlExtraFees, type MrlOptions, type Signers, type SourceTransferData, type TransferData, type TransferParams };
package/build/index.mjs CHANGED
@@ -16795,7 +16795,7 @@ import {
16795
16795
  import {
16796
16796
  AssetAmount as AssetAmount3,
16797
16797
  EvmChain as EvmChain3,
16798
- EvmParachain as EvmParachain4
16798
+ EvmParachain as EvmParachain3
16799
16799
  } from "@moonbeam-network/xcm-types";
16800
16800
  import { toBigInt as toBigInt3 } from "@moonbeam-network/xcm-utils";
16801
16801
  import Big2 from "big.js";
@@ -16808,6 +16808,7 @@ import {
16808
16808
  } from "@moonbeam-network/xcm-builder";
16809
16809
  import { EvmService as EvmService2 } from "@moonbeam-network/xcm-sdk";
16810
16810
  import { EvmChain } from "@moonbeam-network/xcm-types";
16811
+ import { isEthAddress } from "@moonbeam-network/xcm-utils";
16811
16812
  import { u8aToHex } from "@polkadot/util";
16812
16813
  import { decodeAddress } from "@polkadot/util-crypto";
16813
16814
  import { encodeFunctionData } from "viem";
@@ -16869,18 +16870,16 @@ var SnowbridgeService = class _SnowbridgeService {
16869
16870
  destinationAddress,
16870
16871
  destinationParaId,
16871
16872
  amount,
16872
- bridgeFeeAmount,
16873
- requiresApproval
16873
+ bridgeChainFee,
16874
+ value
16874
16875
  } = args;
16875
- const value = requiresApproval ? bridgeFeeAmount : amount + bridgeFeeAmount;
16876
+ const isEthereumDestination = isEthAddress(destinationAddress);
16877
+ const destination = isEthereumDestination ? { kind: 2, data: destinationAddress } : { kind: 1, data: u8aToHex(decodeAddress(destinationAddress)) };
16876
16878
  const contractArgs = [
16877
16879
  tokenAddress,
16878
16880
  destinationParaId,
16879
- {
16880
- kind: 1,
16881
- data: u8aToHex(decodeAddress(destinationAddress))
16882
- },
16883
- 0n,
16881
+ destination,
16882
+ bridgeChainFee,
16884
16883
  amount
16885
16884
  ];
16886
16885
  return new ContractConfig({
@@ -16961,7 +16960,10 @@ var SnowbridgeService = class _SnowbridgeService {
16961
16960
  // src/getTransferData/getBridgeChainData.ts
16962
16961
  import { getBalance, getDestinationFee } from "@moonbeam-network/xcm-sdk";
16963
16962
  import { EvmParachain, Parachain } from "@moonbeam-network/xcm-types";
16964
- import { getMultilocationDerivedAddresses } from "@moonbeam-network/xcm-utils";
16963
+ import {
16964
+ getMultilocationDerivedAddresses,
16965
+ isEthAddress as isEthAddress2
16966
+ } from "@moonbeam-network/xcm-utils";
16965
16967
  import { evmToAddress } from "@polkadot/util-crypto";
16966
16968
  async function getBridgeChainData({
16967
16969
  route,
@@ -17018,6 +17020,10 @@ function getBridgeChainAddress({
17018
17020
  const isDestinationBridgeChain = bridgeChain.isEqual(destination);
17019
17021
  const isSourceBridgeChain = bridgeChain.isEqual(source);
17020
17022
  let bridgeChainAddress = isDestinationBridgeChain ? destinationAddress : sourceAddress;
17023
+ if (Parachain.isExactly(bridgeChain) && isEthAddress2(bridgeChainAddress)) {
17024
+ bridgeChainAddress = evmToAddress(bridgeChainAddress);
17025
+ return bridgeChainAddress;
17026
+ }
17021
17027
  if (Parachain.is(source) && !isSourceBridgeChain) {
17022
17028
  const isSourceEvmSigner = EvmParachain.is(source) && source.isEvmSigner;
17023
17029
  const { address20: computedOriginAccount } = getMultilocationDerivedAddresses({
@@ -17047,13 +17053,11 @@ import {
17047
17053
  getDestinationFeeBalance,
17048
17054
  getExistentialDeposit,
17049
17055
  getExtrinsicFee,
17050
- getMax,
17051
17056
  PolkadotService as PolkadotService2
17052
17057
  } from "@moonbeam-network/xcm-sdk";
17053
17058
  import {
17054
17059
  AssetAmount as AssetAmount2,
17055
- EvmChain as EvmChain2,
17056
- EvmParachain as EvmParachain3
17060
+ EvmChain as EvmChain2
17057
17061
  } from "@moonbeam-network/xcm-types";
17058
17062
  import { toBigInt as toBigInt2 } from "@moonbeam-network/xcm-utils";
17059
17063
 
@@ -17071,6 +17075,7 @@ import {
17071
17075
  } from "@moonbeam-network/xcm-config";
17072
17076
  import {
17073
17077
  convertToChainDecimals,
17078
+ getMax,
17074
17079
  getMin,
17075
17080
  PolkadotService
17076
17081
  } from "@moonbeam-network/xcm-sdk";
@@ -17123,7 +17128,7 @@ function getMrlMin({
17123
17128
  bridgeChainData,
17124
17129
  sourceData
17125
17130
  });
17126
- const relayerFee = sourceData.otherFees?.relayer?.amount ? sourceData.otherFees.relayer.toBig() : Big(0);
17131
+ const relayerFee = sourceData.extraFees?.remote?.fee.amount ? sourceData.extraFees.remote?.fee.toBig() : Big(0);
17127
17132
  return min.copyWith({
17128
17133
  amount: BigInt(min.toBig().add(bridgeChainFee).add(relayerFee).toFixed())
17129
17134
  });
@@ -17152,6 +17157,7 @@ async function buildTransfer(params) {
17152
17157
  async function getMrlBuilderParams({
17153
17158
  asset,
17154
17159
  protocolFee,
17160
+ bridgeChainFee,
17155
17161
  destinationAddress,
17156
17162
  feeAsset,
17157
17163
  isAutomatic,
@@ -17175,6 +17181,7 @@ async function getMrlBuilderParams({
17175
17181
  return {
17176
17182
  asset,
17177
17183
  protocolFee,
17184
+ bridgeChainFee,
17178
17185
  destination,
17179
17186
  destinationAddress,
17180
17187
  destinationApi,
@@ -17267,10 +17274,33 @@ async function getBridgeChainGasLimit(params) {
17267
17274
  return gasEstimation * 110n / 100n;
17268
17275
  }
17269
17276
  function getAmountForTransferSimulation(balance, protocolFee) {
17277
+ if (!protocolFee || !balance.isSame(protocolFee)) {
17278
+ return balance;
17279
+ }
17270
17280
  return balance.copyWith({
17271
17281
  amount: balance.amount - protocolFee.amount > 0 ? balance.amount - protocolFee.amount : 0n
17272
17282
  });
17273
17283
  }
17284
+ function getMrlMax({
17285
+ balance,
17286
+ existentialDeposit,
17287
+ fee,
17288
+ min,
17289
+ extraFees
17290
+ }) {
17291
+ const xcmMax = getMax({
17292
+ balance,
17293
+ existentialDeposit,
17294
+ fee,
17295
+ min
17296
+ });
17297
+ const result = xcmMax.toBig().minus(
17298
+ extraFees?.local && balance.isSame(extraFees.local.fee) ? extraFees.local.fee.toBig() : Big(0)
17299
+ );
17300
+ return balance.copyWith({
17301
+ amount: result.lt(0) ? 0n : BigInt(result.toFixed())
17302
+ });
17303
+ }
17274
17304
 
17275
17305
  // src/getTransferData/getSourceData.ts
17276
17306
  async function getSourceData({
@@ -17278,7 +17308,8 @@ async function getSourceData({
17278
17308
  route,
17279
17309
  destinationAddress,
17280
17310
  destinationFee,
17281
- sourceAddress
17311
+ sourceAddress,
17312
+ bridgeChainData
17282
17313
  }) {
17283
17314
  if (!route.mrl) {
17284
17315
  throw new Error(
@@ -17287,6 +17318,7 @@ async function getSourceData({
17287
17318
  }
17288
17319
  const source = route.source.chain;
17289
17320
  const destination = route.destination.chain;
17321
+ const bridgeChain = route.mrl.bridgeChain.chain;
17290
17322
  const asset = source.getChainAsset(route.source.asset);
17291
17323
  const feeAsset = route.source.fee ? source.getChainAsset(route.source.fee.asset) : asset;
17292
17324
  const balance = await getBalance2({
@@ -17326,11 +17358,14 @@ async function getSourceData({
17326
17358
  feeAsset,
17327
17359
  balance,
17328
17360
  protocolFee: route.source.protocolFee,
17329
- address: destinationAddress
17361
+ address: destinationAddress,
17362
+ bridgeChain,
17363
+ bridgeChainFee: bridgeChainData.fee
17330
17364
  });
17331
17365
  const transfer = await buildTransfer({
17332
17366
  asset: getAmountForTransferSimulation(balance, protocolFee),
17333
17367
  protocolFee,
17368
+ bridgeChainFee: bridgeChainData.fee,
17334
17369
  destinationAddress,
17335
17370
  feeAsset: feeBalance,
17336
17371
  isAutomatic,
@@ -17346,7 +17381,7 @@ async function getSourceData({
17346
17381
  feeConfig: route.source.fee,
17347
17382
  sourceAddress
17348
17383
  });
17349
- const relayerFee = await getRelayerFee({
17384
+ const extraFees = await getExtraFees({
17350
17385
  chain: source,
17351
17386
  transfer,
17352
17387
  asset: balance,
@@ -17354,13 +17389,16 @@ async function getSourceData({
17354
17389
  isAutomatic,
17355
17390
  destinationAddress,
17356
17391
  route,
17357
- sourceAddress
17392
+ sourceAddress,
17393
+ bridgeChainFee: bridgeChainData.fee,
17394
+ protocolFee
17358
17395
  });
17359
- const max = getMax({
17396
+ const max = getMrlMax({
17360
17397
  balance,
17361
17398
  existentialDeposit,
17362
17399
  fee,
17363
- min
17400
+ min,
17401
+ extraFees
17364
17402
  });
17365
17403
  return {
17366
17404
  balance,
@@ -17373,10 +17411,7 @@ async function getSourceData({
17373
17411
  feeBalance,
17374
17412
  max,
17375
17413
  min,
17376
- otherFees: {
17377
- protocol: protocolFee,
17378
- relayer: relayerFee?.amount ? relayerFee : void 0
17379
- }
17414
+ extraFees
17380
17415
  };
17381
17416
  }
17382
17417
  async function getFee({
@@ -17438,7 +17473,8 @@ async function getRelayerFee({
17438
17473
  isAutomatic,
17439
17474
  route,
17440
17475
  sourceAddress,
17441
- transfer
17476
+ transfer,
17477
+ bridgeChainFee
17442
17478
  }) {
17443
17479
  if (route.mrl.transfer.provider === Provider2.Snowbridge || SnowbridgeConfig.is(transfer)) {
17444
17480
  return void 0;
@@ -17453,7 +17489,8 @@ async function getRelayerFee({
17453
17489
  feeAsset,
17454
17490
  isAutomatic,
17455
17491
  route,
17456
- sourceAddress
17492
+ sourceAddress,
17493
+ bridgeChainFee
17457
17494
  });
17458
17495
  const wormholeConfig = MrlBuilder3().wormhole().wormhole().tokenTransfer().build(builderParams);
17459
17496
  return getWormholeFee({ asset, chain: chain2, config: wormholeConfig });
@@ -17505,24 +17542,30 @@ async function getBridgeChainFeeBalance({
17505
17542
  async function getProtocolFee({
17506
17543
  address,
17507
17544
  asset,
17508
- feeAsset,
17509
17545
  balance,
17510
17546
  protocolFee,
17511
17547
  destination,
17512
- source
17548
+ source,
17549
+ bridgeChain,
17550
+ bridgeChainFee
17513
17551
  }) {
17514
- if (typeof protocolFee === "number") {
17515
- return AssetAmount2.fromChainAsset(feeAsset, {
17516
- amount: protocolFee
17552
+ if (!protocolFee) {
17553
+ return void 0;
17554
+ }
17555
+ const protocolFeeAsset = source.getChainAsset(protocolFee.asset);
17556
+ if (typeof protocolFee.amount === "number") {
17557
+ return AssetAmount2.fromChainAsset(protocolFeeAsset, {
17558
+ amount: protocolFee.amount
17517
17559
  });
17518
17560
  }
17519
- const config = protocolFee?.build({
17561
+ const config = protocolFee?.amount?.build({
17520
17562
  address,
17521
17563
  asset,
17522
- feeAsset,
17564
+ feeAsset: protocolFeeAsset,
17523
17565
  balance,
17524
17566
  destination,
17525
- source
17567
+ source,
17568
+ bridgeChainFee
17526
17569
  });
17527
17570
  if (ContractConfig2.is(config) && EvmChain2.is(source)) {
17528
17571
  const evm = EvmService3.create(source);
@@ -17532,21 +17575,58 @@ async function getProtocolFee({
17532
17575
  `Error getting bridge fee: expected bigint from contract call, but received ${typeof amount}. `
17533
17576
  );
17534
17577
  }
17535
- return AssetAmount2.fromChainAsset(feeAsset, {
17578
+ return AssetAmount2.fromChainAsset(protocolFeeAsset, {
17536
17579
  amount
17537
17580
  });
17538
17581
  }
17539
- if (SubstrateQueryConfig.is(config) && EvmParachain3.isAnyParachain(source)) {
17540
- const polkadot = await PolkadotService2.create(source);
17582
+ if (SubstrateQueryConfig.is(config)) {
17583
+ const polkadot = await PolkadotService2.create(bridgeChain);
17541
17584
  const amount = await polkadot.query(config);
17542
- return AssetAmount2.fromChainAsset(feeAsset, {
17585
+ return AssetAmount2.fromChainAsset(protocolFeeAsset, {
17543
17586
  amount
17544
17587
  });
17545
17588
  }
17546
- return AssetAmount2.fromChainAsset(feeAsset, {
17589
+ return AssetAmount2.fromChainAsset(protocolFeeAsset, {
17547
17590
  amount: 0n
17548
17591
  });
17549
17592
  }
17593
+ async function getExtraFees({
17594
+ asset,
17595
+ chain: chain2,
17596
+ destinationAddress,
17597
+ feeAsset,
17598
+ isAutomatic,
17599
+ route,
17600
+ sourceAddress,
17601
+ transfer,
17602
+ bridgeChainFee,
17603
+ protocolFee
17604
+ }) {
17605
+ const relayerFee = await getRelayerFee({
17606
+ chain: chain2,
17607
+ transfer,
17608
+ asset,
17609
+ feeAsset,
17610
+ isAutomatic,
17611
+ destinationAddress,
17612
+ route,
17613
+ sourceAddress,
17614
+ bridgeChainFee
17615
+ });
17616
+ const protocolFeeConfig = route.source.protocolFee;
17617
+ const protocolFeeBalance = protocolFeeConfig ? await getBalance2({
17618
+ address: sourceAddress,
17619
+ asset: chain2.getChainAsset(protocolFeeConfig.asset),
17620
+ builder: protocolFeeConfig.balance,
17621
+ chain: chain2
17622
+ }) : void 0;
17623
+ const localFee = protocolFee && protocolFeeBalance ? { fee: protocolFee, balance: protocolFeeBalance } : void 0;
17624
+ const remoteFee = relayerFee ? { fee: relayerFee, balance: feeAsset } : void 0;
17625
+ return {
17626
+ local: localFee,
17627
+ remote: remoteFee
17628
+ };
17629
+ }
17550
17630
 
17551
17631
  // src/getTransferData/getTransferData.ts
17552
17632
  async function getTransferData({
@@ -17568,17 +17648,18 @@ async function getTransferData({
17568
17648
  asset: destinationData.fee,
17569
17649
  target: route.getDestinationFeeAssetOnSource()
17570
17650
  });
17651
+ const bridgeChainData = await getBridgeChainData({
17652
+ route,
17653
+ sourceAddress,
17654
+ destinationAddress
17655
+ });
17571
17656
  const sourceData = await getSourceData({
17572
17657
  isAutomatic: route.mrl.isAutomaticPossible && isAutomatic,
17573
17658
  route,
17574
17659
  destinationAddress,
17575
17660
  destinationFee,
17576
- sourceAddress
17577
- });
17578
- const bridgeChainData = await getBridgeChainData({
17579
- route,
17580
17661
  sourceAddress,
17581
- destinationAddress
17662
+ bridgeChainData
17582
17663
  });
17583
17664
  return {
17584
17665
  destination: destinationData,
@@ -17594,7 +17675,7 @@ async function getTransferData({
17594
17675
  });
17595
17676
  const result = bigAmount.minus(
17596
17677
  isSameAssetPayingDestinationFee ? destinationFee.toBig() : Big2(0)
17597
- ).minus(fee).minus(sourceData.otherFees?.relayer?.toBig() || Big2(0));
17678
+ ).minus(fee).minus(sourceData.extraFees.remote?.fee.toBig() || Big2(0));
17598
17679
  return sourceData.balance.copyWith({
17599
17680
  amount: result.lt(0) ? 0n : BigInt(result.toFixed())
17600
17681
  });
@@ -17629,7 +17710,8 @@ async function getTransferData({
17629
17710
  );
17630
17711
  const transfer = await buildTransfer({
17631
17712
  asset,
17632
- protocolFee: sourceData.otherFees?.protocol,
17713
+ protocolFee: sourceData.extraFees.local?.fee,
17714
+ bridgeChainFee: bridgeChainData.fee,
17633
17715
  destinationAddress,
17634
17716
  feeAsset,
17635
17717
  isAutomatic: isAutomatic2,
@@ -17637,7 +17719,7 @@ async function getTransferData({
17637
17719
  sendOnlyRemoteExecution,
17638
17720
  sourceAddress
17639
17721
  });
17640
- if (ContractConfig3.is(transfer) && (EvmChain3.is(source) || EvmParachain4.is(source))) {
17722
+ if (ContractConfig3.is(transfer) && (EvmChain3.is(source) || EvmParachain3.is(source))) {
17641
17723
  if (!evmSigner) {
17642
17724
  throw new Error("EVM Signer must be provided");
17643
17725
  }
@@ -17645,7 +17727,7 @@ async function getTransferData({
17645
17727
  const hash = await evm.transfer(evmSigner, transfer);
17646
17728
  return [hash];
17647
17729
  }
17648
- if (ExtrinsicConfig.is(transfer) && EvmParachain4.isAnyParachain(source)) {
17730
+ if (ExtrinsicConfig.is(transfer) && EvmParachain3.isAnyParachain(source)) {
17649
17731
  if (!polkadotSigner) {
17650
17732
  throw new Error("Polkadot signer must be provided");
17651
17733
  }
@@ -17658,14 +17740,14 @@ async function getTransferData({
17658
17740
  );
17659
17741
  return [hash];
17660
17742
  }
17661
- if (WormholeConfig2.is(transfer) && (EvmChain3.is(source) || EvmParachain4.is(source))) {
17743
+ if (WormholeConfig2.is(transfer) && (EvmChain3.is(source) || EvmParachain3.is(source))) {
17662
17744
  if (!evmSigner) {
17663
17745
  throw new Error("EVM Signer must be provided");
17664
17746
  }
17665
17747
  const wh = WormholeService.create(source);
17666
17748
  return wh.transfer(evmSigner, transfer);
17667
17749
  }
17668
- if (SnowbridgeConfig2.is(transfer) && (EvmChain3.is(source) || EvmParachain4.is(source))) {
17750
+ if (SnowbridgeConfig2.is(transfer) && (EvmChain3.is(source) || EvmParachain3.is(source))) {
17669
17751
  if (!evmSigner) {
17670
17752
  throw new Error("EVM Signer must be provided");
17671
17753
  }