@moonbeam-network/mrl 1.0.0-dev.264 → 1.0.0-dev.266

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.mjs CHANGED
@@ -16755,34 +16755,191 @@ async function getExecuteTransferData({
16755
16755
 
16756
16756
  // src/getTransferData/getTransferData.ts
16757
16757
  import {
16758
- ContractConfig as ContractConfig2,
16758
+ ContractConfig as ContractConfig3,
16759
16759
  ExtrinsicConfig,
16760
+ SnowbridgeConfig as SnowbridgeConfig2,
16760
16761
  WormholeConfig as WormholeConfig2
16761
16762
  } from "@moonbeam-network/xcm-builder";
16762
16763
  import {
16763
16764
  convertToChainDecimals as convertToChainDecimals2,
16764
- EvmService as EvmService2,
16765
+ EvmService as EvmService4,
16765
16766
  getDestinationData,
16766
- PolkadotService as PolkadotService2
16767
+ PolkadotService as PolkadotService3
16767
16768
  } from "@moonbeam-network/xcm-sdk";
16768
16769
  import {
16769
16770
  AssetAmount as AssetAmount3,
16770
- EvmChain,
16771
- EvmParachain as EvmParachain3
16771
+ EvmChain as EvmChain2,
16772
+ EvmParachain as EvmParachain4
16772
16773
  } from "@moonbeam-network/xcm-types";
16773
16774
  import { toBigInt as toBigInt3 } from "@moonbeam-network/xcm-utils";
16774
16775
  import Big2 from "big.js";
16775
16776
 
16776
- // src/getTransferData/getMoonChainData.ts
16777
- import { getMoonChain } from "@moonbeam-network/xcm-config";
16778
- import { getBalance, getDestinationFee } from "@moonbeam-network/xcm-sdk";
16777
+ // src/services/snowbridge/SnowbridgeService.ts
16779
16778
  import {
16780
- EvmParachain,
16781
- Parachain
16782
- } from "@moonbeam-network/xcm-types";
16779
+ ContractConfig,
16780
+ ERC20_ABI,
16781
+ GATEWAY_ABI,
16782
+ GATEWAY_CONTRACT_ADDRESS
16783
+ } from "@moonbeam-network/xcm-builder";
16784
+ import { EvmService as EvmService2 } from "@moonbeam-network/xcm-sdk";
16785
+ import { u8aToHex } from "@polkadot/util";
16786
+ import { decodeAddress } from "@polkadot/util-crypto";
16787
+ import { encodeFunctionData } from "viem";
16788
+ var SnowbridgeService = class _SnowbridgeService {
16789
+ chain;
16790
+ #evmService;
16791
+ static create(chain2) {
16792
+ return new _SnowbridgeService(chain2);
16793
+ }
16794
+ constructor(chain2) {
16795
+ this.chain = chain2;
16796
+ this.#evmService = EvmService2.create(chain2);
16797
+ }
16798
+ async checkAllowance(ownerAddress, tokenAddress, spenderAddress) {
16799
+ const allowance = await this.#evmService.client.readContract({
16800
+ abi: ERC20_ABI,
16801
+ address: tokenAddress,
16802
+ args: [ownerAddress, spenderAddress],
16803
+ functionName: "allowance"
16804
+ });
16805
+ if (typeof allowance !== "bigint") {
16806
+ throw new Error(
16807
+ `Could not get allowance on ${this.chain.name} for token ${tokenAddress}`
16808
+ );
16809
+ }
16810
+ return allowance;
16811
+ }
16812
+ async transfer(signer, transfer) {
16813
+ const { args } = transfer;
16814
+ const { tokenAddress, amount, requiresApproval } = args;
16815
+ if (!signer.account) {
16816
+ throw new Error("Signer account is required");
16817
+ }
16818
+ const contract = this.buildContractConfig(transfer);
16819
+ if (!requiresApproval) {
16820
+ return await this.#evmService.transfer(signer, contract);
16821
+ }
16822
+ const currentAllowance = await this.checkAllowance(
16823
+ signer.account.address,
16824
+ tokenAddress,
16825
+ GATEWAY_CONTRACT_ADDRESS
16826
+ );
16827
+ console.log("currentAllowance", currentAllowance);
16828
+ if (currentAllowance < amount) {
16829
+ await this.approve(
16830
+ signer,
16831
+ tokenAddress,
16832
+ GATEWAY_CONTRACT_ADDRESS,
16833
+ amount
16834
+ );
16835
+ }
16836
+ return await this.#evmService.transfer(signer, contract);
16837
+ }
16838
+ buildContractConfig(transfer) {
16839
+ const { args } = transfer;
16840
+ const {
16841
+ tokenAddress,
16842
+ destinationAddress,
16843
+ destinationParaId,
16844
+ amount,
16845
+ bridgeFeeAmount,
16846
+ requiresApproval
16847
+ } = args;
16848
+ const value = requiresApproval ? bridgeFeeAmount : amount + bridgeFeeAmount;
16849
+ const contractArgs = [
16850
+ tokenAddress,
16851
+ destinationParaId,
16852
+ {
16853
+ kind: 1,
16854
+ data: u8aToHex(decodeAddress(destinationAddress))
16855
+ },
16856
+ 0n,
16857
+ amount
16858
+ ];
16859
+ return new ContractConfig({
16860
+ address: GATEWAY_CONTRACT_ADDRESS,
16861
+ abi: GATEWAY_ABI,
16862
+ args: contractArgs,
16863
+ func: "sendToken",
16864
+ value,
16865
+ module: "Gateway"
16866
+ });
16867
+ }
16868
+ async approve(signer, tokenAddress, spenderAddress, amount) {
16869
+ const { request } = await this.#evmService.client.simulateContract({
16870
+ abi: ERC20_ABI,
16871
+ account: signer.account,
16872
+ address: tokenAddress,
16873
+ functionName: "approve",
16874
+ args: [spenderAddress, amount]
16875
+ });
16876
+ const hash = await signer.writeContract(request);
16877
+ await this.#evmService.client.waitForTransactionReceipt({
16878
+ hash
16879
+ });
16880
+ return hash;
16881
+ }
16882
+ async getFee(address, transfer) {
16883
+ const { args } = transfer;
16884
+ const { tokenAddress, amount, requiresApproval } = args;
16885
+ const contract = this.buildContractConfig(transfer);
16886
+ if (!requiresApproval) {
16887
+ return await this.#evmService.getFee(address, contract);
16888
+ }
16889
+ const currentAllowance = await this.checkAllowance(
16890
+ address,
16891
+ tokenAddress,
16892
+ GATEWAY_CONTRACT_ADDRESS
16893
+ );
16894
+ if (currentAllowance >= amount) {
16895
+ return await this.#evmService.getFee(address, contract);
16896
+ }
16897
+ return await this.estimateApproveAndSendFee(address, transfer);
16898
+ }
16899
+ async estimateApproveAndSendFee(address, transfer) {
16900
+ const { args } = transfer;
16901
+ const { tokenAddress, amount } = args;
16902
+ const contract = this.buildContractConfig(transfer);
16903
+ try {
16904
+ const approveData = encodeFunctionData({
16905
+ abi: ERC20_ABI,
16906
+ functionName: "approve",
16907
+ args: [GATEWAY_CONTRACT_ADDRESS, amount]
16908
+ });
16909
+ const approveGas = await this.#evmService.client.estimateGas({
16910
+ account: address,
16911
+ to: tokenAddress,
16912
+ data: approveData
16913
+ });
16914
+ const sendData = encodeFunctionData({
16915
+ abi: contract.abi,
16916
+ functionName: contract.func,
16917
+ args: contract.args
16918
+ });
16919
+ const sendGas = await this.#evmService.client.estimateGas({
16920
+ account: address,
16921
+ to: contract.address,
16922
+ data: sendData,
16923
+ value: contract.value
16924
+ });
16925
+ const gasPrice = await this.#evmService.client.getGasPrice();
16926
+ console.log("gasPrice", gasPrice);
16927
+ console.log("approveGas", approveGas);
16928
+ console.log("sendGas", sendGas);
16929
+ return (approveGas + sendGas) * gasPrice;
16930
+ } catch (error) {
16931
+ console.error("Error estimating approve + send fee:", error);
16932
+ return 0n;
16933
+ }
16934
+ }
16935
+ };
16936
+
16937
+ // src/getTransferData/getBridgeChainData.ts
16938
+ import { getBalance, getDestinationFee } from "@moonbeam-network/xcm-sdk";
16939
+ import { EvmParachain, Parachain } from "@moonbeam-network/xcm-types";
16783
16940
  import { getMultilocationDerivedAddresses } from "@moonbeam-network/xcm-utils";
16784
16941
  import { evmToAddress } from "@polkadot/util-crypto";
16785
- async function getMoonChainData({
16942
+ async function getBridgeChainData({
16786
16943
  route,
16787
16944
  sourceAddress,
16788
16945
  destinationAddress
@@ -16792,80 +16949,86 @@ async function getMoonChainData({
16792
16949
  `MRL config is not defined for source chain ${route.source.chain.name} and asset ${route.source.asset.originSymbol}`
16793
16950
  );
16794
16951
  }
16795
- const moonChain = getMoonChain(route.source.chain);
16796
- const moonChainAddress = getMoonChainAddress({
16797
- source: route.source.chain,
16798
- destination: route.destination.chain,
16952
+ const bridgeChain = route.mrl.bridgeChain.chain;
16953
+ const bridgeChainAddress = getBridgeChainAddress({
16954
+ route,
16799
16955
  sourceAddress,
16800
16956
  destinationAddress
16801
16957
  });
16802
16958
  const fee = await getDestinationFee({
16803
- address: moonChainAddress,
16959
+ address: bridgeChainAddress,
16804
16960
  asset: route.source.asset,
16805
- destination: moonChain,
16806
- fee: route.mrl.moonChain.fee.amount,
16807
- feeAsset: route.mrl.moonChain.fee.asset,
16961
+ destination: bridgeChain,
16962
+ fee: route.mrl.bridgeChain.fee.amount,
16963
+ feeAsset: route.mrl.bridgeChain.fee.asset,
16808
16964
  source: route.source.chain
16809
16965
  });
16810
16966
  const balance = await getBalance({
16811
- address: moonChainAddress,
16812
- asset: moonChain.getChainAsset(route.mrl.moonChain.asset),
16813
- builder: route.mrl.moonChain.balance,
16814
- chain: moonChain
16967
+ address: bridgeChainAddress,
16968
+ asset: bridgeChain.getChainAsset(route.mrl.bridgeChain.asset),
16969
+ builder: route.mrl.bridgeChain.balance,
16970
+ chain: bridgeChain
16815
16971
  });
16816
16972
  const feeBalance = await getBalance({
16817
- address: moonChainAddress,
16818
- asset: moonChain.getChainAsset(route.mrl.moonChain.fee.asset),
16819
- builder: route.mrl.moonChain.fee.balance,
16820
- chain: moonChain
16973
+ address: bridgeChainAddress,
16974
+ asset: bridgeChain.getChainAsset(route.mrl.bridgeChain.fee.asset),
16975
+ builder: route.mrl.bridgeChain.fee.balance,
16976
+ chain: bridgeChain
16821
16977
  });
16822
16978
  return {
16823
- address: moonChainAddress,
16979
+ address: bridgeChainAddress,
16824
16980
  balance,
16825
16981
  feeBalance,
16826
- chain: moonChain,
16982
+ chain: bridgeChain,
16827
16983
  fee
16828
16984
  };
16829
16985
  }
16830
- function getMoonChainAddress({
16831
- source,
16832
- destination,
16986
+ function getBridgeChainAddress({
16987
+ route,
16833
16988
  sourceAddress,
16834
16989
  destinationAddress
16835
16990
  }) {
16836
- const moonChain = getMoonChain(source);
16837
- const isDestinationMoonChain = moonChain.isEqual(destination);
16838
- const isSourceMoonChain = moonChain.isEqual(source);
16839
- let moonChainAddress = isDestinationMoonChain ? destinationAddress : sourceAddress;
16840
- if (Parachain.is(source) && !isSourceMoonChain) {
16991
+ const source = route.source.chain;
16992
+ const destination = route.destination.chain;
16993
+ const bridgeChain = route.mrl.bridgeChain.chain;
16994
+ const isDestinationBridgeChain = bridgeChain.isEqual(destination);
16995
+ const isSourceBridgeChain = bridgeChain.isEqual(source);
16996
+ let bridgeChainAddress = isDestinationBridgeChain ? destinationAddress : sourceAddress;
16997
+ if (Parachain.is(source) && !isSourceBridgeChain) {
16841
16998
  const isSourceEvmSigner = EvmParachain.is(source) && source.isEvmSigner;
16842
16999
  const { address20: computedOriginAccount } = getMultilocationDerivedAddresses({
16843
17000
  address: isSourceEvmSigner ? evmToAddress(sourceAddress) : sourceAddress,
16844
17001
  paraId: source.parachainId,
16845
17002
  isParents: true
16846
17003
  });
16847
- moonChainAddress = computedOriginAccount;
17004
+ bridgeChainAddress = computedOriginAccount;
16848
17005
  }
16849
- return moonChainAddress;
17006
+ return bridgeChainAddress;
16850
17007
  }
16851
17008
 
16852
17009
  // src/getTransferData/getSourceData.ts
16853
17010
  import {
16854
- ContractConfig,
17011
+ ContractConfig as ContractConfig2,
16855
17012
  MrlBuilder as MrlBuilder3,
17013
+ SnowbridgeConfig,
17014
+ SubstrateQueryConfig,
16856
17015
  WormholeConfig
16857
17016
  } from "@moonbeam-network/xcm-builder";
16858
17017
  import {
17018
+ EvmService as EvmService3,
16859
17019
  getAssetMin,
16860
17020
  getBalance as getBalance2,
16861
17021
  getContractFee,
16862
17022
  getDestinationFeeBalance,
16863
17023
  getExistentialDeposit,
16864
17024
  getExtrinsicFee,
16865
- getMax
17025
+ getMax,
17026
+ PolkadotService as PolkadotService2
16866
17027
  } from "@moonbeam-network/xcm-sdk";
16867
17028
  import {
16868
- AssetAmount as AssetAmount2
17029
+ AssetAmount as AssetAmount2,
17030
+ EvmChain,
17031
+ EvmParachain as EvmParachain3
16869
17032
  } from "@moonbeam-network/xcm-types";
16870
17033
  import { toBigInt as toBigInt2 } from "@moonbeam-network/xcm-utils";
16871
17034
 
@@ -16873,11 +17036,10 @@ import { toBigInt as toBigInt2 } from "@moonbeam-network/xcm-utils";
16873
17036
  import {
16874
17037
  BATCH_CONTRACT_ABI,
16875
17038
  BATCH_CONTRACT_ADDRESS,
16876
- ERC20_ABI,
17039
+ ERC20_ABI as ERC20_ABI2,
16877
17040
  MrlBuilder as MrlBuilder2
16878
17041
  } from "@moonbeam-network/xcm-builder";
16879
17042
  import {
16880
- getMoonChain as getMoonChain2,
16881
17043
  moonbaseAlpha,
16882
17044
  moonbeam
16883
17045
  } from "@moonbeam-network/xcm-config";
@@ -16894,33 +17056,33 @@ import {
16894
17056
  import Big from "big.js";
16895
17057
  import {
16896
17058
  createPublicClient as createPublicClient2,
16897
- encodeFunctionData,
17059
+ encodeFunctionData as encodeFunctionData2,
16898
17060
  http as http2
16899
17061
  } from "viem";
16900
17062
  var MOON_CHAIN_AUTOMATIC_GAS_ESTIMATION = {
16901
17063
  [moonbeam.key]: 1273110n,
16902
17064
  [moonbaseAlpha.key]: 1470417n
16903
17065
  };
16904
- function getMoonChainFeeValueOnSource({
17066
+ function getBridgeChainFeeValueOnSource({
16905
17067
  destinationData,
16906
- moonChainData,
17068
+ bridgeChainData,
16907
17069
  sourceData
16908
17070
  }) {
16909
17071
  const isSourceParachain = EvmParachain2.isAnyParachain(sourceData.chain);
16910
- const isDestinationMoonChain = destinationData.chain.isEqual(
16911
- moonChainData.chain
17072
+ const isDestinationBridgeChain = destinationData.chain.isEqual(
17073
+ bridgeChainData.chain
16912
17074
  );
16913
- const isSameAssetPayingMoonChainFee = sourceData.balance.isSame(
16914
- moonChainData.fee
17075
+ const isSameAssetPayingBridgeChainFee = sourceData.balance.isSame(
17076
+ bridgeChainData.fee
16915
17077
  );
16916
- return !isDestinationMoonChain && isSourceParachain && isSameAssetPayingMoonChainFee ? convertToChainDecimals({
16917
- asset: moonChainData.fee,
16918
- target: sourceData.chain.getChainAsset(moonChainData.fee)
17078
+ return !isDestinationBridgeChain && isSourceParachain && isSameAssetPayingBridgeChainFee ? convertToChainDecimals({
17079
+ asset: bridgeChainData.fee,
17080
+ target: sourceData.chain.getChainAsset(bridgeChainData.fee)
16919
17081
  }).toBig() : Big(0);
16920
17082
  }
16921
17083
  function getMrlMin({
16922
17084
  destinationData,
16923
- moonChainData,
17085
+ bridgeChainData,
16924
17086
  sourceData
16925
17087
  }) {
16926
17088
  const minInDestination = getMin(destinationData);
@@ -16930,16 +17092,19 @@ function getMrlMin({
16930
17092
  amount: minInDestination.amount
16931
17093
  }
16932
17094
  );
16933
- const moonChainFee = getMoonChainFeeValueOnSource({
17095
+ const bridgeChainFee = getBridgeChainFeeValueOnSource({
16934
17096
  destinationData,
16935
- moonChainData,
17097
+ bridgeChainData,
16936
17098
  sourceData
16937
17099
  });
16938
- const relayerFee = sourceData.relayerFee?.amount ? sourceData.relayerFee.toBig() : Big(0);
17100
+ const relayerFee = sourceData.otherFees?.relayer?.amount ? sourceData.otherFees.relayer.toBig() : Big(0);
16939
17101
  return min.copyWith({
16940
- amount: BigInt(min.toBig().add(moonChainFee).add(relayerFee).toFixed())
17102
+ amount: BigInt(min.toBig().add(bridgeChainFee).add(relayerFee).toFixed())
16941
17103
  });
16942
17104
  }
17105
+ function requiresTransact(route) {
17106
+ return route.mrl?.transfer.provider === "wormhole" && EvmParachain2.isAnyParachain(route.source.chain);
17107
+ }
16943
17108
  async function buildTransfer(params) {
16944
17109
  const { route } = params;
16945
17110
  if (!route.mrl) {
@@ -16955,11 +17120,12 @@ async function buildTransfer(params) {
16955
17120
  const builderParams = await getMrlBuilderParams(params);
16956
17121
  return route.mrl.transfer.build({
16957
17122
  ...builderParams,
16958
- transact: EvmParachain2.isAnyParachain(route.source.chain) ? await getTransact(builderParams) : void 0
17123
+ transact: requiresTransact(route) ? await getTransact(builderParams) : void 0
16959
17124
  });
16960
17125
  }
16961
17126
  async function getMrlBuilderParams({
16962
17127
  asset,
17128
+ protocolFee,
16963
17129
  destinationAddress,
16964
17130
  feeAsset,
16965
17131
  isAutomatic,
@@ -16974,22 +17140,23 @@ async function getMrlBuilderParams({
16974
17140
  }
16975
17141
  const source = route.source.chain;
16976
17142
  const destination = route.destination.chain;
16977
- const moonChain = getMoonChain2(source);
16978
- const [sourceApi, destinationApi, moonApi] = await Promise.all([
17143
+ const bridgeChain = route.mrl.bridgeChain.chain;
17144
+ const [sourceApi, destinationApi, bridgeApi] = await Promise.all([
16979
17145
  EvmParachain2.isAnyParachain(source) ? getPolkadotApi(source.ws) : void 0,
16980
17146
  EvmParachain2.isAnyParachain(destination) ? getPolkadotApi(destination.ws) : void 0,
16981
- getPolkadotApi(moonChain.ws)
17147
+ getPolkadotApi(bridgeChain.ws)
16982
17148
  ]);
16983
17149
  return {
16984
17150
  asset,
17151
+ protocolFee,
16985
17152
  destination,
16986
17153
  destinationAddress,
16987
17154
  destinationApi,
16988
17155
  fee: feeAsset,
16989
17156
  isAutomatic,
16990
- moonApi,
16991
- moonAsset: moonChain.nativeAsset,
16992
- moonChain,
17157
+ moonApi: bridgeApi,
17158
+ moonAsset: bridgeChain.nativeAsset,
17159
+ bridgeChain,
16993
17160
  sendOnlyRemoteExecution,
16994
17161
  source,
16995
17162
  sourceAddress,
@@ -16997,9 +17164,9 @@ async function getMrlBuilderParams({
16997
17164
  };
16998
17165
  }
16999
17166
  async function getTransact(params) {
17000
- const { sourceAddress, source, moonChain } = params;
17001
- const polkadot = await PolkadotService.create(moonChain);
17002
- const moonGasLimit = await getMoonGasLimit(params);
17167
+ const { sourceAddress, source, bridgeChain } = params;
17168
+ const polkadot = await PolkadotService.create(bridgeChain);
17169
+ const bridgeChainGasLimit = await getBridgeChainGasLimit(params);
17003
17170
  if (!EvmParachain2.isAnyParachain(source)) {
17004
17171
  throw new Error("Source chain must be Parachain or EvmParachain");
17005
17172
  }
@@ -17008,7 +17175,7 @@ async function getTransact(params) {
17008
17175
  paraId: source.parachainId,
17009
17176
  isParents: true
17010
17177
  });
17011
- const extrinsic = MrlBuilder2().wormhole().extrinsic().ethereumXcm().transact().build({ ...params, moonGasLimit });
17178
+ const extrinsic = MrlBuilder2().wormhole().extrinsic().ethereumXcm().transact().build({ ...params, bridgeChainGasLimit });
17012
17179
  const { weight } = await polkadot.getPaymentInfo(address20, extrinsic);
17013
17180
  return {
17014
17181
  call: polkadot.getExtrinsicCallHash(extrinsic),
@@ -17018,13 +17185,16 @@ async function getTransact(params) {
17018
17185
  }
17019
17186
  };
17020
17187
  }
17021
- async function getMoonGasLimit(params) {
17022
- const { asset, isAutomatic, moonChain, source, sourceAddress } = params;
17188
+ async function getBridgeChainGasLimit(params) {
17189
+ const { asset, isAutomatic, bridgeChain, source, sourceAddress } = params;
17023
17190
  if (!EvmParachain2.isAnyParachain(source)) {
17024
17191
  throw new Error("Source chain must be Parachain or EvmParachain");
17025
17192
  }
17193
+ if (!EvmParachain2.is(bridgeChain)) {
17194
+ throw new Error("Bridge chain must be an EvmParachain");
17195
+ }
17026
17196
  const client = createPublicClient2({
17027
- chain: moonChain.getViemChain(),
17197
+ chain: bridgeChain.getViemChain(),
17028
17198
  transport: http2()
17029
17199
  });
17030
17200
  const { address20 } = getMultilocationDerivedAddresses2({
@@ -17033,28 +17203,28 @@ async function getMoonGasLimit(params) {
17033
17203
  isParents: true
17034
17204
  });
17035
17205
  if (isAutomatic) {
17036
- return MOON_CHAIN_AUTOMATIC_GAS_ESTIMATION[moonChain.key] * 110n / 100n;
17206
+ return MOON_CHAIN_AUTOMATIC_GAS_ESTIMATION[bridgeChain.key] * 110n / 100n;
17037
17207
  }
17038
17208
  const contract = MrlBuilder2().wormhole().contract().TokenBridge().transferTokens().build({
17039
17209
  ...params,
17040
17210
  asset: asset.copyWith({ amount: 0n })
17041
17211
  });
17042
- const approveTx = encodeFunctionData({
17043
- abi: ERC20_ABI,
17212
+ const approveTx = encodeFunctionData2({
17213
+ abi: ERC20_ABI2,
17044
17214
  functionName: "approve",
17045
17215
  args: [contract.address, 0n]
17046
17216
  });
17047
- const tokenAddressOnMoonChain = moonChain.getChainAsset(asset).address;
17048
- if (!tokenAddressOnMoonChain) {
17217
+ const tokenAddressOnBridgeChain = bridgeChain.getChainAsset(asset).address;
17218
+ if (!tokenAddressOnBridgeChain) {
17049
17219
  throw new Error(
17050
- `Asset ${asset.symbol} does not have a token address on chain ${moonChain.name}`
17220
+ `Asset ${asset.symbol} does not have a token address on chain ${bridgeChain.name}`
17051
17221
  );
17052
17222
  }
17053
- const batchAll = encodeFunctionData({
17223
+ const batchAll = encodeFunctionData2({
17054
17224
  abi: BATCH_CONTRACT_ABI,
17055
17225
  functionName: "batchAll",
17056
17226
  args: [
17057
- [tokenAddressOnMoonChain, contract.address],
17227
+ [tokenAddressOnBridgeChain, contract.address],
17058
17228
  [0n, 0n],
17059
17229
  // Value to send for each call
17060
17230
  [approveTx, contract.encodeFunctionData()],
@@ -17085,6 +17255,7 @@ async function getSourceData({
17085
17255
  );
17086
17256
  }
17087
17257
  const source = route.source.chain;
17258
+ const destination = route.destination.chain;
17088
17259
  const asset = source.getChainAsset(route.source.asset);
17089
17260
  const feeAsset = route.source.fee ? source.getChainAsset(route.source.fee.asset) : asset;
17090
17261
  const balance = await getBalance2({
@@ -17105,20 +17276,25 @@ async function getSourceData({
17105
17276
  route,
17106
17277
  sourceAddress
17107
17278
  });
17108
- const moonChainFeeBalance = await getMoonChainFeeBalance({
17109
- balance,
17110
- feeBalance,
17111
- route,
17112
- sourceAddress
17113
- });
17114
17279
  const existentialDeposit = await getExistentialDeposit(source);
17115
17280
  const min = await getAssetMin({
17116
17281
  asset,
17117
17282
  builder: route.source.min,
17118
17283
  chain: source
17119
17284
  });
17285
+ const protocolFee = await getProtocolFee({
17286
+ source,
17287
+ destination,
17288
+ // For now, the fee asset is always the one used for the protocol fee
17289
+ // If it where to change, we need make protocolFee a FeeConfig in MrlSourceConfig
17290
+ asset: feeAsset,
17291
+ balance,
17292
+ protocolFee: route.source.protocolFee,
17293
+ address: destinationAddress
17294
+ });
17120
17295
  const transfer = await buildTransfer({
17121
- asset: balance,
17296
+ asset: balance.copyWith({ amount: balance.amount - protocolFee.amount }),
17297
+ protocolFee,
17122
17298
  destinationAddress,
17123
17299
  feeAsset: feeBalance,
17124
17300
  isAutomatic,
@@ -17155,13 +17331,16 @@ async function getSourceData({
17155
17331
  chain: source,
17156
17332
  destinationFee,
17157
17333
  destinationFeeBalance,
17158
- moonChainFeeBalance,
17334
+ // bridgeChainFeeBalance,
17159
17335
  existentialDeposit,
17160
17336
  fee,
17161
17337
  feeBalance,
17162
17338
  max,
17163
17339
  min,
17164
- relayerFee
17340
+ otherFees: {
17341
+ protocol: protocolFee,
17342
+ relayer: relayerFee?.amount ? relayerFee : void 0
17343
+ }
17165
17344
  };
17166
17345
  }
17167
17346
  async function getFee({
@@ -17178,17 +17357,31 @@ async function getFee({
17178
17357
  amount: 0n
17179
17358
  });
17180
17359
  }
17181
- if (ContractConfig.is(transfer)) {
17182
- return getContractFee({
17183
- address: sourceAddress,
17184
- balance,
17185
- chain: chain2,
17186
- contract: transfer,
17187
- destinationFee,
17188
- feeBalance,
17189
- feeConfig
17360
+ if (SnowbridgeConfig.is(transfer)) {
17361
+ const snowbridge = SnowbridgeService.create(
17362
+ chain2
17363
+ );
17364
+ const feeAmount = await snowbridge.getFee(sourceAddress, transfer);
17365
+ return AssetAmount2.fromChainAsset(chain2.getChainAsset(feeBalance), {
17366
+ amount: feeAmount
17190
17367
  });
17191
17368
  }
17369
+ if (ContractConfig2.is(transfer)) {
17370
+ try {
17371
+ return getContractFee({
17372
+ address: sourceAddress,
17373
+ balance,
17374
+ chain: chain2,
17375
+ contract: transfer,
17376
+ destinationFee,
17377
+ feeBalance,
17378
+ feeConfig
17379
+ });
17380
+ } catch (error) {
17381
+ console.error(error);
17382
+ return feeBalance.copyWith({ amount: 0n });
17383
+ }
17384
+ }
17192
17385
  return getExtrinsicFee({
17193
17386
  address: sourceAddress,
17194
17387
  balance,
@@ -17208,19 +17401,25 @@ async function getRelayerFee({
17208
17401
  sourceAddress,
17209
17402
  transfer
17210
17403
  }) {
17404
+ if (route.mrl.transfer.provider === "snowbridge" || SnowbridgeConfig.is(transfer)) {
17405
+ return void 0;
17406
+ }
17211
17407
  if (WormholeConfig.is(transfer)) {
17212
17408
  return getWormholeFee({ asset, chain: chain2, config: transfer });
17213
17409
  }
17214
- const builderParams = await getMrlBuilderParams({
17215
- asset,
17216
- destinationAddress,
17217
- feeAsset,
17218
- isAutomatic,
17219
- route,
17220
- sourceAddress
17221
- });
17222
- const wormholeConfig = MrlBuilder3().wormhole().wormhole().tokenTransfer().build(builderParams);
17223
- return getWormholeFee({ asset, chain: chain2, config: wormholeConfig });
17410
+ if (route.mrl.transfer.provider === "wormhole") {
17411
+ const builderParams = await getMrlBuilderParams({
17412
+ asset,
17413
+ destinationAddress,
17414
+ feeAsset,
17415
+ isAutomatic,
17416
+ route,
17417
+ sourceAddress
17418
+ });
17419
+ const wormholeConfig = MrlBuilder3().wormhole().wormhole().tokenTransfer().build(builderParams);
17420
+ return getWormholeFee({ asset, chain: chain2, config: wormholeConfig });
17421
+ }
17422
+ return;
17224
17423
  }
17225
17424
  async function getWormholeFee({
17226
17425
  asset,
@@ -17237,31 +17436,47 @@ async function getWormholeFee({
17237
17436
  }
17238
17437
  return;
17239
17438
  }
17240
- async function getMoonChainFeeBalance({
17439
+ async function getProtocolFee({
17440
+ address,
17441
+ asset,
17241
17442
  balance,
17242
- feeBalance,
17243
- route,
17244
- sourceAddress
17443
+ protocolFee,
17444
+ destination,
17445
+ source
17245
17446
  }) {
17246
- if (!route.source.moonChainFee) {
17247
- return void 0;
17248
- }
17249
- if (route.mrl?.moonChain.fee.asset.isEqual(balance)) {
17250
- return balance;
17447
+ if (typeof protocolFee === "number") {
17448
+ return AssetAmount2.fromChainAsset(asset, {
17449
+ amount: protocolFee
17450
+ });
17251
17451
  }
17252
- if (route.mrl?.moonChain.fee.asset.isEqual(feeBalance)) {
17253
- return feeBalance;
17452
+ const config = protocolFee?.build({
17453
+ address,
17454
+ asset,
17455
+ balance,
17456
+ destination,
17457
+ source
17458
+ });
17459
+ if (ContractConfig2.is(config) && EvmChain.is(source)) {
17460
+ const evm = EvmService3.create(source);
17461
+ const amount = await evm.read(config);
17462
+ if (typeof amount !== "bigint") {
17463
+ throw new Error(
17464
+ `Error getting bridge fee: expected bigint from contract call, but received ${typeof amount}. `
17465
+ );
17466
+ }
17467
+ return AssetAmount2.fromChainAsset(asset, {
17468
+ amount
17469
+ });
17254
17470
  }
17255
- if (!route.source.moonChainFee.balance) {
17256
- throw new Error(
17257
- "BalanceBuilder must be defined for source.moonChainFee.balance for MrlAssetRoute"
17258
- );
17471
+ if (SubstrateQueryConfig.is(config) && EvmParachain3.isAnyParachain(source)) {
17472
+ const polkadot = await PolkadotService2.create(source);
17473
+ const amount = await polkadot.query(config);
17474
+ return AssetAmount2.fromChainAsset(asset, {
17475
+ amount
17476
+ });
17259
17477
  }
17260
- return getBalance2({
17261
- address: sourceAddress,
17262
- asset: route.source.chain.getChainAsset(route.source.moonChainFee.asset),
17263
- builder: route.source.moonChainFee.balance,
17264
- chain: route.source.chain
17478
+ return AssetAmount2.fromChainAsset(source.getChainAsset(asset), {
17479
+ amount: 0n
17265
17480
  });
17266
17481
  }
17267
17482
 
@@ -17281,10 +17496,12 @@ async function getTransferData({
17281
17496
  route,
17282
17497
  destinationAddress
17283
17498
  });
17499
+ console.log("destinationData", destinationData);
17284
17500
  const destinationFee = convertToChainDecimals2({
17285
17501
  asset: destinationData.fee,
17286
17502
  target: route.getDestinationFeeAssetOnSource()
17287
17503
  });
17504
+ console.log("destinationFee", destinationFee);
17288
17505
  const sourceData = await getSourceData({
17289
17506
  isAutomatic: route.mrl.isAutomaticPossible && isAutomatic,
17290
17507
  route,
@@ -17292,11 +17509,13 @@ async function getTransferData({
17292
17509
  destinationFee,
17293
17510
  sourceAddress
17294
17511
  });
17295
- const moonChainData = await getMoonChainData({
17512
+ console.log("sourceData", sourceData);
17513
+ const bridgeChainData = await getBridgeChainData({
17296
17514
  route,
17297
17515
  sourceAddress,
17298
17516
  destinationAddress
17299
17517
  });
17518
+ console.log("bridgeChainData", bridgeChainData);
17300
17519
  return {
17301
17520
  destination: destinationData,
17302
17521
  getEstimate(amount) {
@@ -17304,14 +17523,14 @@ async function getTransferData({
17304
17523
  const bigAmount = Big2(
17305
17524
  toBigInt3(amount, sourceData.balance.decimals).toString()
17306
17525
  );
17307
- const fee = getMoonChainFeeValueOnSource({
17526
+ const fee = getBridgeChainFeeValueOnSource({
17308
17527
  destinationData,
17309
- moonChainData,
17528
+ bridgeChainData,
17310
17529
  sourceData
17311
17530
  });
17312
17531
  const result = bigAmount.minus(
17313
17532
  isSameAssetPayingDestinationFee ? destinationFee.toBig() : Big2(0)
17314
- ).minus(fee).minus(sourceData.relayerFee?.toBig() || Big2(0));
17533
+ ).minus(fee).minus(sourceData.otherFees?.relayer?.toBig() || Big2(0));
17315
17534
  return sourceData.balance.copyWith({
17316
17535
  amount: result.lt(0) ? 0n : BigInt(result.toFixed())
17317
17536
  });
@@ -17320,10 +17539,10 @@ async function getTransferData({
17320
17539
  max: sourceData.max,
17321
17540
  min: getMrlMin({
17322
17541
  destinationData,
17323
- moonChainData,
17542
+ bridgeChainData,
17324
17543
  sourceData
17325
17544
  }),
17326
- moonChain: moonChainData,
17545
+ bridgeChain: bridgeChainData,
17327
17546
  source: sourceData,
17328
17547
  async transfer({
17329
17548
  amount,
@@ -17346,6 +17565,7 @@ async function getTransferData({
17346
17565
  );
17347
17566
  const transfer = await buildTransfer({
17348
17567
  asset,
17568
+ protocolFee: sourceData.otherFees?.protocol,
17349
17569
  destinationAddress,
17350
17570
  feeAsset,
17351
17571
  isAutomatic: isAutomatic2,
@@ -17353,19 +17573,19 @@ async function getTransferData({
17353
17573
  sendOnlyRemoteExecution,
17354
17574
  sourceAddress
17355
17575
  });
17356
- if (ContractConfig2.is(transfer) && (EvmChain.is(source) || EvmParachain3.is(source))) {
17576
+ if (ContractConfig3.is(transfer) && (EvmChain2.is(source) || EvmParachain4.is(source))) {
17357
17577
  if (!evmSigner) {
17358
17578
  throw new Error("EVM Signer must be provided");
17359
17579
  }
17360
- const evm = EvmService2.create(source);
17580
+ const evm = EvmService4.create(source);
17361
17581
  const hash = await evm.transfer(evmSigner, transfer);
17362
17582
  return [hash];
17363
17583
  }
17364
- if (ExtrinsicConfig.is(transfer) && EvmParachain3.isAnyParachain(source)) {
17584
+ if (ExtrinsicConfig.is(transfer) && EvmParachain4.isAnyParachain(source)) {
17365
17585
  if (!polkadotSigner) {
17366
17586
  throw new Error("Polkadot signer must be provided");
17367
17587
  }
17368
- const polkadot = await PolkadotService2.create(source);
17588
+ const polkadot = await PolkadotService3.create(source);
17369
17589
  const hash = await polkadot.transfer(
17370
17590
  sourceAddress,
17371
17591
  transfer,
@@ -17374,13 +17594,21 @@ async function getTransferData({
17374
17594
  );
17375
17595
  return [hash];
17376
17596
  }
17377
- if (WormholeConfig2.is(transfer) && (EvmChain.is(source) || EvmParachain3.is(source))) {
17597
+ if (WormholeConfig2.is(transfer) && (EvmChain2.is(source) || EvmParachain4.is(source))) {
17378
17598
  if (!evmSigner) {
17379
17599
  throw new Error("EVM Signer must be provided");
17380
17600
  }
17381
17601
  const wh = WormholeService.create(source);
17382
17602
  return wh.transfer(evmSigner, transfer);
17383
17603
  }
17604
+ if (SnowbridgeConfig2.is(transfer) && (EvmChain2.is(source) || EvmParachain4.is(source))) {
17605
+ if (!evmSigner) {
17606
+ throw new Error("EVM Signer must be provided");
17607
+ }
17608
+ const snowbridge = SnowbridgeService.create(source);
17609
+ const hash = await snowbridge.transfer(evmSigner, transfer);
17610
+ return [hash];
17611
+ }
17384
17612
  throw new Error("Either contract or extrinsic must be provided");
17385
17613
  }
17386
17614
  };