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

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,7 +17276,7 @@ async function getSourceData({
17105
17276
  route,
17106
17277
  sourceAddress
17107
17278
  });
17108
- const moonChainFeeBalance = await getMoonChainFeeBalance({
17279
+ const bridgeChainFeeBalance = await getBridgeChainFeeBalance({
17109
17280
  balance,
17110
17281
  feeBalance,
17111
17282
  route,
@@ -17117,8 +17288,19 @@ async function getSourceData({
17117
17288
  builder: route.source.min,
17118
17289
  chain: source
17119
17290
  });
17291
+ const protocolFee = await getProtocolFee({
17292
+ source,
17293
+ destination,
17294
+ // For now, the fee asset is always the one used for the protocol fee
17295
+ // If it where to change, we need make protocolFee a FeeConfig in MrlSourceConfig
17296
+ asset: feeAsset,
17297
+ balance,
17298
+ protocolFee: route.source.protocolFee,
17299
+ address: destinationAddress
17300
+ });
17120
17301
  const transfer = await buildTransfer({
17121
- asset: balance,
17302
+ asset: balance.copyWith({ amount: balance.amount - protocolFee.amount }),
17303
+ protocolFee,
17122
17304
  destinationAddress,
17123
17305
  feeAsset: feeBalance,
17124
17306
  isAutomatic,
@@ -17155,13 +17337,16 @@ async function getSourceData({
17155
17337
  chain: source,
17156
17338
  destinationFee,
17157
17339
  destinationFeeBalance,
17158
- moonChainFeeBalance,
17340
+ bridgeChainFeeBalance,
17159
17341
  existentialDeposit,
17160
17342
  fee,
17161
17343
  feeBalance,
17162
17344
  max,
17163
17345
  min,
17164
- relayerFee
17346
+ otherFees: {
17347
+ protocol: protocolFee,
17348
+ relayer: relayerFee?.amount ? relayerFee : void 0
17349
+ }
17165
17350
  };
17166
17351
  }
17167
17352
  async function getFee({
@@ -17178,17 +17363,31 @@ async function getFee({
17178
17363
  amount: 0n
17179
17364
  });
17180
17365
  }
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
17366
+ if (SnowbridgeConfig.is(transfer)) {
17367
+ const snowbridge = SnowbridgeService.create(
17368
+ chain2
17369
+ );
17370
+ const feeAmount = await snowbridge.getFee(sourceAddress, transfer);
17371
+ return AssetAmount2.fromChainAsset(chain2.getChainAsset(feeBalance), {
17372
+ amount: feeAmount
17190
17373
  });
17191
17374
  }
17375
+ if (ContractConfig2.is(transfer)) {
17376
+ try {
17377
+ return getContractFee({
17378
+ address: sourceAddress,
17379
+ balance,
17380
+ chain: chain2,
17381
+ contract: transfer,
17382
+ destinationFee,
17383
+ feeBalance,
17384
+ feeConfig
17385
+ });
17386
+ } catch (error) {
17387
+ console.error(error);
17388
+ return feeBalance.copyWith({ amount: 0n });
17389
+ }
17390
+ }
17192
17391
  return getExtrinsicFee({
17193
17392
  address: sourceAddress,
17194
17393
  balance,
@@ -17208,19 +17407,25 @@ async function getRelayerFee({
17208
17407
  sourceAddress,
17209
17408
  transfer
17210
17409
  }) {
17410
+ if (route.mrl.transfer.provider === "snowbridge" || SnowbridgeConfig.is(transfer)) {
17411
+ return void 0;
17412
+ }
17211
17413
  if (WormholeConfig.is(transfer)) {
17212
17414
  return getWormholeFee({ asset, chain: chain2, config: transfer });
17213
17415
  }
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 });
17416
+ if (route.mrl.transfer.provider === "wormhole") {
17417
+ const builderParams = await getMrlBuilderParams({
17418
+ asset,
17419
+ destinationAddress,
17420
+ feeAsset,
17421
+ isAutomatic,
17422
+ route,
17423
+ sourceAddress
17424
+ });
17425
+ const wormholeConfig = MrlBuilder3().wormhole().wormhole().tokenTransfer().build(builderParams);
17426
+ return getWormholeFee({ asset, chain: chain2, config: wormholeConfig });
17427
+ }
17428
+ return;
17224
17429
  }
17225
17430
  async function getWormholeFee({
17226
17431
  asset,
@@ -17237,33 +17442,76 @@ async function getWormholeFee({
17237
17442
  }
17238
17443
  return;
17239
17444
  }
17240
- async function getMoonChainFeeBalance({
17445
+ async function getBridgeChainFeeBalance({
17241
17446
  balance,
17242
17447
  feeBalance,
17243
17448
  route,
17244
17449
  sourceAddress
17245
17450
  }) {
17246
- if (!route.source.moonChainFee) {
17451
+ if (!route.source.bridgeChainFee) {
17247
17452
  return void 0;
17248
17453
  }
17249
- if (route.mrl?.moonChain.fee.asset.isEqual(balance)) {
17454
+ if (route.mrl?.bridgeChain.fee.asset.isEqual(balance)) {
17250
17455
  return balance;
17251
17456
  }
17252
- if (route.mrl?.moonChain.fee.asset.isEqual(feeBalance)) {
17457
+ if (route.mrl?.bridgeChain.fee.asset.isEqual(feeBalance)) {
17253
17458
  return feeBalance;
17254
17459
  }
17255
- if (!route.source.moonChainFee.balance) {
17460
+ if (!route.source.bridgeChainFee.balance) {
17256
17461
  throw new Error(
17257
- "BalanceBuilder must be defined for source.moonChainFee.balance for MrlAssetRoute"
17462
+ "BalanceBuilder must be defined for source.bridgeChainFee.balance for MrlAssetRoute"
17258
17463
  );
17259
17464
  }
17260
17465
  return getBalance2({
17261
17466
  address: sourceAddress,
17262
- asset: route.source.chain.getChainAsset(route.source.moonChainFee.asset),
17263
- builder: route.source.moonChainFee.balance,
17467
+ asset: route.source.chain.getChainAsset(route.source.bridgeChainFee.asset),
17468
+ builder: route.source.bridgeChainFee.balance,
17264
17469
  chain: route.source.chain
17265
17470
  });
17266
17471
  }
17472
+ async function getProtocolFee({
17473
+ address,
17474
+ asset,
17475
+ balance,
17476
+ protocolFee,
17477
+ destination,
17478
+ source
17479
+ }) {
17480
+ if (typeof protocolFee === "number") {
17481
+ return AssetAmount2.fromChainAsset(asset, {
17482
+ amount: protocolFee
17483
+ });
17484
+ }
17485
+ const config = protocolFee?.build({
17486
+ address,
17487
+ asset,
17488
+ balance,
17489
+ destination,
17490
+ source
17491
+ });
17492
+ if (ContractConfig2.is(config) && EvmChain.is(source)) {
17493
+ const evm = EvmService3.create(source);
17494
+ const amount = await evm.read(config);
17495
+ if (typeof amount !== "bigint") {
17496
+ throw new Error(
17497
+ `Error getting bridge fee: expected bigint from contract call, but received ${typeof amount}. `
17498
+ );
17499
+ }
17500
+ return AssetAmount2.fromChainAsset(asset, {
17501
+ amount
17502
+ });
17503
+ }
17504
+ if (SubstrateQueryConfig.is(config) && EvmParachain3.isAnyParachain(source)) {
17505
+ const polkadot = await PolkadotService2.create(source);
17506
+ const amount = await polkadot.query(config);
17507
+ return AssetAmount2.fromChainAsset(asset, {
17508
+ amount
17509
+ });
17510
+ }
17511
+ return AssetAmount2.fromChainAsset(source.getChainAsset(asset), {
17512
+ amount: 0n
17513
+ });
17514
+ }
17267
17515
 
17268
17516
  // src/getTransferData/getTransferData.ts
17269
17517
  async function getTransferData({
@@ -17281,10 +17529,12 @@ async function getTransferData({
17281
17529
  route,
17282
17530
  destinationAddress
17283
17531
  });
17532
+ console.log("destinationData", destinationData);
17284
17533
  const destinationFee = convertToChainDecimals2({
17285
17534
  asset: destinationData.fee,
17286
17535
  target: route.getDestinationFeeAssetOnSource()
17287
17536
  });
17537
+ console.log("destinationFee", destinationFee);
17288
17538
  const sourceData = await getSourceData({
17289
17539
  isAutomatic: route.mrl.isAutomaticPossible && isAutomatic,
17290
17540
  route,
@@ -17292,11 +17542,13 @@ async function getTransferData({
17292
17542
  destinationFee,
17293
17543
  sourceAddress
17294
17544
  });
17295
- const moonChainData = await getMoonChainData({
17545
+ console.log("sourceData", sourceData);
17546
+ const bridgeChainData = await getBridgeChainData({
17296
17547
  route,
17297
17548
  sourceAddress,
17298
17549
  destinationAddress
17299
17550
  });
17551
+ console.log("bridgeChainData", bridgeChainData);
17300
17552
  return {
17301
17553
  destination: destinationData,
17302
17554
  getEstimate(amount) {
@@ -17304,14 +17556,14 @@ async function getTransferData({
17304
17556
  const bigAmount = Big2(
17305
17557
  toBigInt3(amount, sourceData.balance.decimals).toString()
17306
17558
  );
17307
- const fee = getMoonChainFeeValueOnSource({
17559
+ const fee = getBridgeChainFeeValueOnSource({
17308
17560
  destinationData,
17309
- moonChainData,
17561
+ bridgeChainData,
17310
17562
  sourceData
17311
17563
  });
17312
17564
  const result = bigAmount.minus(
17313
17565
  isSameAssetPayingDestinationFee ? destinationFee.toBig() : Big2(0)
17314
- ).minus(fee).minus(sourceData.relayerFee?.toBig() || Big2(0));
17566
+ ).minus(fee).minus(sourceData.otherFees?.relayer?.toBig() || Big2(0));
17315
17567
  return sourceData.balance.copyWith({
17316
17568
  amount: result.lt(0) ? 0n : BigInt(result.toFixed())
17317
17569
  });
@@ -17320,10 +17572,10 @@ async function getTransferData({
17320
17572
  max: sourceData.max,
17321
17573
  min: getMrlMin({
17322
17574
  destinationData,
17323
- moonChainData,
17575
+ bridgeChainData,
17324
17576
  sourceData
17325
17577
  }),
17326
- moonChain: moonChainData,
17578
+ bridgeChain: bridgeChainData,
17327
17579
  source: sourceData,
17328
17580
  async transfer({
17329
17581
  amount,
@@ -17346,6 +17598,7 @@ async function getTransferData({
17346
17598
  );
17347
17599
  const transfer = await buildTransfer({
17348
17600
  asset,
17601
+ protocolFee: sourceData.otherFees?.protocol,
17349
17602
  destinationAddress,
17350
17603
  feeAsset,
17351
17604
  isAutomatic: isAutomatic2,
@@ -17353,19 +17606,19 @@ async function getTransferData({
17353
17606
  sendOnlyRemoteExecution,
17354
17607
  sourceAddress
17355
17608
  });
17356
- if (ContractConfig2.is(transfer) && (EvmChain.is(source) || EvmParachain3.is(source))) {
17609
+ if (ContractConfig3.is(transfer) && (EvmChain2.is(source) || EvmParachain4.is(source))) {
17357
17610
  if (!evmSigner) {
17358
17611
  throw new Error("EVM Signer must be provided");
17359
17612
  }
17360
- const evm = EvmService2.create(source);
17613
+ const evm = EvmService4.create(source);
17361
17614
  const hash = await evm.transfer(evmSigner, transfer);
17362
17615
  return [hash];
17363
17616
  }
17364
- if (ExtrinsicConfig.is(transfer) && EvmParachain3.isAnyParachain(source)) {
17617
+ if (ExtrinsicConfig.is(transfer) && EvmParachain4.isAnyParachain(source)) {
17365
17618
  if (!polkadotSigner) {
17366
17619
  throw new Error("Polkadot signer must be provided");
17367
17620
  }
17368
- const polkadot = await PolkadotService2.create(source);
17621
+ const polkadot = await PolkadotService3.create(source);
17369
17622
  const hash = await polkadot.transfer(
17370
17623
  sourceAddress,
17371
17624
  transfer,
@@ -17374,13 +17627,21 @@ async function getTransferData({
17374
17627
  );
17375
17628
  return [hash];
17376
17629
  }
17377
- if (WormholeConfig2.is(transfer) && (EvmChain.is(source) || EvmParachain3.is(source))) {
17630
+ if (WormholeConfig2.is(transfer) && (EvmChain2.is(source) || EvmParachain4.is(source))) {
17378
17631
  if (!evmSigner) {
17379
17632
  throw new Error("EVM Signer must be provided");
17380
17633
  }
17381
17634
  const wh = WormholeService.create(source);
17382
17635
  return wh.transfer(evmSigner, transfer);
17383
17636
  }
17637
+ if (SnowbridgeConfig2.is(transfer) && (EvmChain2.is(source) || EvmParachain4.is(source))) {
17638
+ if (!evmSigner) {
17639
+ throw new Error("EVM Signer must be provided");
17640
+ }
17641
+ const snowbridge = SnowbridgeService.create(source);
17642
+ const hash = await snowbridge.transfer(evmSigner, transfer);
17643
+ return [hash];
17644
+ }
17384
17645
  throw new Error("Either contract or extrinsic must be provided");
17385
17646
  }
17386
17647
  };