@moonbeam-network/mrl 1.0.0-dev.263 → 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.d.ts +13 -7
- package/build/index.mjs +385 -124
- package/build/index.mjs.map +1 -1
- package/package.json +6 -6
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
|
|
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
|
|
16765
|
+
EvmService as EvmService4,
|
|
16765
16766
|
getDestinationData,
|
|
16766
|
-
PolkadotService as
|
|
16767
|
+
PolkadotService as PolkadotService3
|
|
16767
16768
|
} from "@moonbeam-network/xcm-sdk";
|
|
16768
16769
|
import {
|
|
16769
16770
|
AssetAmount as AssetAmount3,
|
|
16770
|
-
EvmChain,
|
|
16771
|
-
EvmParachain as
|
|
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/
|
|
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
|
-
|
|
16781
|
-
|
|
16782
|
-
|
|
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
|
|
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
|
|
16796
|
-
const
|
|
16797
|
-
|
|
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:
|
|
16959
|
+
address: bridgeChainAddress,
|
|
16804
16960
|
asset: route.source.asset,
|
|
16805
|
-
destination:
|
|
16806
|
-
fee: route.mrl.
|
|
16807
|
-
feeAsset: route.mrl.
|
|
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:
|
|
16812
|
-
asset:
|
|
16813
|
-
builder: route.mrl.
|
|
16814
|
-
chain:
|
|
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:
|
|
16818
|
-
asset:
|
|
16819
|
-
builder: route.mrl.
|
|
16820
|
-
chain:
|
|
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:
|
|
16979
|
+
address: bridgeChainAddress,
|
|
16824
16980
|
balance,
|
|
16825
16981
|
feeBalance,
|
|
16826
|
-
chain:
|
|
16982
|
+
chain: bridgeChain,
|
|
16827
16983
|
fee
|
|
16828
16984
|
};
|
|
16829
16985
|
}
|
|
16830
|
-
function
|
|
16831
|
-
|
|
16832
|
-
destination,
|
|
16986
|
+
function getBridgeChainAddress({
|
|
16987
|
+
route,
|
|
16833
16988
|
sourceAddress,
|
|
16834
16989
|
destinationAddress
|
|
16835
16990
|
}) {
|
|
16836
|
-
const
|
|
16837
|
-
const
|
|
16838
|
-
const
|
|
16839
|
-
|
|
16840
|
-
|
|
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
|
-
|
|
17004
|
+
bridgeChainAddress = computedOriginAccount;
|
|
16848
17005
|
}
|
|
16849
|
-
return
|
|
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
|
|
17066
|
+
function getBridgeChainFeeValueOnSource({
|
|
16905
17067
|
destinationData,
|
|
16906
|
-
|
|
17068
|
+
bridgeChainData,
|
|
16907
17069
|
sourceData
|
|
16908
17070
|
}) {
|
|
16909
17071
|
const isSourceParachain = EvmParachain2.isAnyParachain(sourceData.chain);
|
|
16910
|
-
const
|
|
16911
|
-
|
|
17072
|
+
const isDestinationBridgeChain = destinationData.chain.isEqual(
|
|
17073
|
+
bridgeChainData.chain
|
|
16912
17074
|
);
|
|
16913
|
-
const
|
|
16914
|
-
|
|
17075
|
+
const isSameAssetPayingBridgeChainFee = sourceData.balance.isSame(
|
|
17076
|
+
bridgeChainData.fee
|
|
16915
17077
|
);
|
|
16916
|
-
return !
|
|
16917
|
-
asset:
|
|
16918
|
-
target: sourceData.chain.getChainAsset(
|
|
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
|
-
|
|
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
|
|
17095
|
+
const bridgeChainFee = getBridgeChainFeeValueOnSource({
|
|
16934
17096
|
destinationData,
|
|
16935
|
-
|
|
17097
|
+
bridgeChainData,
|
|
16936
17098
|
sourceData
|
|
16937
17099
|
});
|
|
16938
|
-
const relayerFee = sourceData.
|
|
17100
|
+
const relayerFee = sourceData.otherFees?.relayer?.amount ? sourceData.otherFees.relayer.toBig() : Big(0);
|
|
16939
17101
|
return min.copyWith({
|
|
16940
|
-
amount: BigInt(min.toBig().add(
|
|
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:
|
|
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
|
|
16978
|
-
const [sourceApi, destinationApi,
|
|
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(
|
|
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:
|
|
16992
|
-
|
|
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,
|
|
17001
|
-
const polkadot = await PolkadotService.create(
|
|
17002
|
-
const
|
|
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,
|
|
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
|
|
17022
|
-
const { asset, isAutomatic,
|
|
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:
|
|
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[
|
|
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 =
|
|
17043
|
-
abi:
|
|
17212
|
+
const approveTx = encodeFunctionData2({
|
|
17213
|
+
abi: ERC20_ABI2,
|
|
17044
17214
|
functionName: "approve",
|
|
17045
17215
|
args: [contract.address, 0n]
|
|
17046
17216
|
});
|
|
17047
|
-
const
|
|
17048
|
-
if (!
|
|
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 ${
|
|
17220
|
+
`Asset ${asset.symbol} does not have a token address on chain ${bridgeChain.name}`
|
|
17051
17221
|
);
|
|
17052
17222
|
}
|
|
17053
|
-
const batchAll =
|
|
17223
|
+
const batchAll = encodeFunctionData2({
|
|
17054
17224
|
abi: BATCH_CONTRACT_ABI,
|
|
17055
17225
|
functionName: "batchAll",
|
|
17056
17226
|
args: [
|
|
17057
|
-
[
|
|
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
|
|
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
|
-
|
|
17340
|
+
bridgeChainFeeBalance,
|
|
17159
17341
|
existentialDeposit,
|
|
17160
17342
|
fee,
|
|
17161
17343
|
feeBalance,
|
|
17162
17344
|
max,
|
|
17163
17345
|
min,
|
|
17164
|
-
|
|
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 (
|
|
17182
|
-
|
|
17183
|
-
|
|
17184
|
-
|
|
17185
|
-
|
|
17186
|
-
|
|
17187
|
-
|
|
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
|
-
|
|
17215
|
-
|
|
17216
|
-
|
|
17217
|
-
|
|
17218
|
-
|
|
17219
|
-
|
|
17220
|
-
|
|
17221
|
-
|
|
17222
|
-
|
|
17223
|
-
|
|
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
|
|
17445
|
+
async function getBridgeChainFeeBalance({
|
|
17241
17446
|
balance,
|
|
17242
17447
|
feeBalance,
|
|
17243
17448
|
route,
|
|
17244
17449
|
sourceAddress
|
|
17245
17450
|
}) {
|
|
17246
|
-
if (!route.source.
|
|
17451
|
+
if (!route.source.bridgeChainFee) {
|
|
17247
17452
|
return void 0;
|
|
17248
17453
|
}
|
|
17249
|
-
if (route.mrl?.
|
|
17454
|
+
if (route.mrl?.bridgeChain.fee.asset.isEqual(balance)) {
|
|
17250
17455
|
return balance;
|
|
17251
17456
|
}
|
|
17252
|
-
if (route.mrl?.
|
|
17457
|
+
if (route.mrl?.bridgeChain.fee.asset.isEqual(feeBalance)) {
|
|
17253
17458
|
return feeBalance;
|
|
17254
17459
|
}
|
|
17255
|
-
if (!route.source.
|
|
17460
|
+
if (!route.source.bridgeChainFee.balance) {
|
|
17256
17461
|
throw new Error(
|
|
17257
|
-
"BalanceBuilder must be defined for source.
|
|
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.
|
|
17263
|
-
builder: route.source.
|
|
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
|
-
|
|
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 =
|
|
17559
|
+
const fee = getBridgeChainFeeValueOnSource({
|
|
17308
17560
|
destinationData,
|
|
17309
|
-
|
|
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.
|
|
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
|
-
|
|
17575
|
+
bridgeChainData,
|
|
17324
17576
|
sourceData
|
|
17325
17577
|
}),
|
|
17326
|
-
|
|
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 (
|
|
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 =
|
|
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) &&
|
|
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
|
|
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) && (
|
|
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
|
};
|