@moonbeam-network/mrl 4.0.23 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.d.ts +13 -7
- package/build/index.mjs +392 -126
- package/build/index.mjs.map +1 -1
- package/package.json +6 -6
package/build/index.mjs
CHANGED
|
@@ -16770,34 +16770,189 @@ async function getExecuteTransferData({
|
|
|
16770
16770
|
|
|
16771
16771
|
// src/getTransferData/getTransferData.ts
|
|
16772
16772
|
import {
|
|
16773
|
-
ContractConfig as
|
|
16773
|
+
ContractConfig as ContractConfig3,
|
|
16774
16774
|
ExtrinsicConfig,
|
|
16775
|
+
SnowbridgeConfig as SnowbridgeConfig2,
|
|
16775
16776
|
WormholeConfig as WormholeConfig2
|
|
16776
16777
|
} from "@moonbeam-network/xcm-builder";
|
|
16777
16778
|
import {
|
|
16778
16779
|
convertToChainDecimals as convertToChainDecimals2,
|
|
16779
|
-
EvmService as
|
|
16780
|
+
EvmService as EvmService4,
|
|
16780
16781
|
getDestinationData,
|
|
16781
|
-
PolkadotService as
|
|
16782
|
+
PolkadotService as PolkadotService3
|
|
16782
16783
|
} from "@moonbeam-network/xcm-sdk";
|
|
16783
16784
|
import {
|
|
16784
16785
|
AssetAmount as AssetAmount3,
|
|
16785
|
-
EvmChain,
|
|
16786
|
-
EvmParachain as
|
|
16786
|
+
EvmChain as EvmChain3,
|
|
16787
|
+
EvmParachain as EvmParachain4
|
|
16787
16788
|
} from "@moonbeam-network/xcm-types";
|
|
16788
16789
|
import { toBigInt as toBigInt3 } from "@moonbeam-network/xcm-utils";
|
|
16789
16790
|
import Big2 from "big.js";
|
|
16790
16791
|
|
|
16791
|
-
// src/
|
|
16792
|
-
import { getMoonChain } from "@moonbeam-network/xcm-config";
|
|
16793
|
-
import { getBalance, getDestinationFee } from "@moonbeam-network/xcm-sdk";
|
|
16792
|
+
// src/services/snowbridge/SnowbridgeService.ts
|
|
16794
16793
|
import {
|
|
16795
|
-
|
|
16796
|
-
|
|
16797
|
-
|
|
16794
|
+
ContractConfig,
|
|
16795
|
+
ERC20_ABI,
|
|
16796
|
+
GATEWAY_ABI
|
|
16797
|
+
} from "@moonbeam-network/xcm-builder";
|
|
16798
|
+
import { EvmService as EvmService2 } from "@moonbeam-network/xcm-sdk";
|
|
16799
|
+
import { EvmChain } from "@moonbeam-network/xcm-types";
|
|
16800
|
+
import { u8aToHex } from "@polkadot/util";
|
|
16801
|
+
import { decodeAddress } from "@polkadot/util-crypto";
|
|
16802
|
+
import { encodeFunctionData } from "viem";
|
|
16803
|
+
var SnowbridgeService = class _SnowbridgeService {
|
|
16804
|
+
chain;
|
|
16805
|
+
#evmService;
|
|
16806
|
+
#gatewayAddress;
|
|
16807
|
+
static create(chain2) {
|
|
16808
|
+
return new _SnowbridgeService(chain2);
|
|
16809
|
+
}
|
|
16810
|
+
constructor(chain2) {
|
|
16811
|
+
if (!EvmChain.is(chain2) || !chain2.contracts?.Gateway) {
|
|
16812
|
+
throw new Error(
|
|
16813
|
+
"Chain must be an EVMChain with the Gateway contract address configured for Snowbridge operations"
|
|
16814
|
+
);
|
|
16815
|
+
}
|
|
16816
|
+
this.chain = chain2;
|
|
16817
|
+
this.#gatewayAddress = chain2.contracts.Gateway;
|
|
16818
|
+
this.#evmService = EvmService2.create(chain2);
|
|
16819
|
+
}
|
|
16820
|
+
async checkAllowance(ownerAddress, tokenAddress, spenderAddress) {
|
|
16821
|
+
const allowance = await this.#evmService.client.readContract({
|
|
16822
|
+
abi: ERC20_ABI,
|
|
16823
|
+
address: tokenAddress,
|
|
16824
|
+
args: [ownerAddress, spenderAddress],
|
|
16825
|
+
functionName: "allowance"
|
|
16826
|
+
});
|
|
16827
|
+
if (typeof allowance !== "bigint") {
|
|
16828
|
+
throw new Error(
|
|
16829
|
+
`Could not get allowance on ${this.chain.name} for token ${tokenAddress}`
|
|
16830
|
+
);
|
|
16831
|
+
}
|
|
16832
|
+
return allowance;
|
|
16833
|
+
}
|
|
16834
|
+
async transfer(signer, transfer) {
|
|
16835
|
+
const { args } = transfer;
|
|
16836
|
+
const { tokenAddress, amount, requiresApproval } = args;
|
|
16837
|
+
if (!signer.account) {
|
|
16838
|
+
throw new Error("Signer account is required");
|
|
16839
|
+
}
|
|
16840
|
+
const contract = this.buildContractConfig(transfer);
|
|
16841
|
+
if (!requiresApproval) {
|
|
16842
|
+
return await this.#evmService.transfer(signer, contract);
|
|
16843
|
+
}
|
|
16844
|
+
const currentAllowance = await this.checkAllowance(
|
|
16845
|
+
signer.account.address,
|
|
16846
|
+
tokenAddress,
|
|
16847
|
+
this.#gatewayAddress
|
|
16848
|
+
);
|
|
16849
|
+
if (currentAllowance < amount) {
|
|
16850
|
+
await this.approve(signer, tokenAddress, this.#gatewayAddress, amount);
|
|
16851
|
+
}
|
|
16852
|
+
return await this.#evmService.transfer(signer, contract);
|
|
16853
|
+
}
|
|
16854
|
+
buildContractConfig(transfer) {
|
|
16855
|
+
const { args } = transfer;
|
|
16856
|
+
const {
|
|
16857
|
+
tokenAddress,
|
|
16858
|
+
destinationAddress,
|
|
16859
|
+
destinationParaId,
|
|
16860
|
+
amount,
|
|
16861
|
+
bridgeFeeAmount,
|
|
16862
|
+
requiresApproval
|
|
16863
|
+
} = args;
|
|
16864
|
+
const value = requiresApproval ? bridgeFeeAmount : amount + bridgeFeeAmount;
|
|
16865
|
+
const contractArgs = [
|
|
16866
|
+
tokenAddress,
|
|
16867
|
+
destinationParaId,
|
|
16868
|
+
{
|
|
16869
|
+
kind: 1,
|
|
16870
|
+
data: u8aToHex(decodeAddress(destinationAddress))
|
|
16871
|
+
},
|
|
16872
|
+
0n,
|
|
16873
|
+
amount
|
|
16874
|
+
];
|
|
16875
|
+
return new ContractConfig({
|
|
16876
|
+
address: this.#gatewayAddress,
|
|
16877
|
+
abi: GATEWAY_ABI,
|
|
16878
|
+
args: contractArgs,
|
|
16879
|
+
func: "sendToken",
|
|
16880
|
+
value,
|
|
16881
|
+
module: "Gateway"
|
|
16882
|
+
});
|
|
16883
|
+
}
|
|
16884
|
+
async approve(signer, tokenAddress, spenderAddress, amount) {
|
|
16885
|
+
const { request } = await this.#evmService.client.simulateContract({
|
|
16886
|
+
abi: ERC20_ABI,
|
|
16887
|
+
account: signer.account,
|
|
16888
|
+
address: tokenAddress,
|
|
16889
|
+
functionName: "approve",
|
|
16890
|
+
args: [spenderAddress, amount]
|
|
16891
|
+
});
|
|
16892
|
+
const hash = await signer.writeContract(request);
|
|
16893
|
+
await this.#evmService.client.waitForTransactionReceipt({
|
|
16894
|
+
hash
|
|
16895
|
+
});
|
|
16896
|
+
return hash;
|
|
16897
|
+
}
|
|
16898
|
+
async getFee(address, transfer) {
|
|
16899
|
+
const { args } = transfer;
|
|
16900
|
+
const { tokenAddress, amount, requiresApproval } = args;
|
|
16901
|
+
const contract = this.buildContractConfig(transfer);
|
|
16902
|
+
if (!requiresApproval) {
|
|
16903
|
+
return await this.#evmService.getFee(address, contract);
|
|
16904
|
+
}
|
|
16905
|
+
const currentAllowance = await this.checkAllowance(
|
|
16906
|
+
address,
|
|
16907
|
+
tokenAddress,
|
|
16908
|
+
this.#gatewayAddress
|
|
16909
|
+
);
|
|
16910
|
+
if (currentAllowance >= amount) {
|
|
16911
|
+
return await this.#evmService.getFee(address, contract);
|
|
16912
|
+
}
|
|
16913
|
+
return await this.estimateApproveAndSendFee(address, transfer);
|
|
16914
|
+
}
|
|
16915
|
+
async estimateApproveAndSendFee(address, transfer) {
|
|
16916
|
+
const { args } = transfer;
|
|
16917
|
+
const { tokenAddress, amount } = args;
|
|
16918
|
+
const contract = this.buildContractConfig(transfer);
|
|
16919
|
+
try {
|
|
16920
|
+
const approveData = encodeFunctionData({
|
|
16921
|
+
abi: ERC20_ABI,
|
|
16922
|
+
functionName: "approve",
|
|
16923
|
+
args: [this.#gatewayAddress, amount]
|
|
16924
|
+
});
|
|
16925
|
+
const approveGas = await this.#evmService.client.estimateGas({
|
|
16926
|
+
account: address,
|
|
16927
|
+
to: tokenAddress,
|
|
16928
|
+
data: approveData
|
|
16929
|
+
});
|
|
16930
|
+
const sendData = encodeFunctionData({
|
|
16931
|
+
abi: contract.abi,
|
|
16932
|
+
functionName: contract.func,
|
|
16933
|
+
args: contract.args
|
|
16934
|
+
});
|
|
16935
|
+
const sendGas = await this.#evmService.client.estimateGas({
|
|
16936
|
+
account: address,
|
|
16937
|
+
to: contract.address,
|
|
16938
|
+
data: sendData,
|
|
16939
|
+
value: contract.value
|
|
16940
|
+
});
|
|
16941
|
+
const gasPrice = await this.#evmService.client.getGasPrice();
|
|
16942
|
+
return (approveGas + sendGas) * gasPrice;
|
|
16943
|
+
} catch (error) {
|
|
16944
|
+
console.error("Error estimating approve + send fee:", error);
|
|
16945
|
+
return 0n;
|
|
16946
|
+
}
|
|
16947
|
+
}
|
|
16948
|
+
};
|
|
16949
|
+
|
|
16950
|
+
// src/getTransferData/getBridgeChainData.ts
|
|
16951
|
+
import { getBalance, getDestinationFee } from "@moonbeam-network/xcm-sdk";
|
|
16952
|
+
import { EvmParachain, Parachain } from "@moonbeam-network/xcm-types";
|
|
16798
16953
|
import { getMultilocationDerivedAddresses } from "@moonbeam-network/xcm-utils";
|
|
16799
16954
|
import { evmToAddress } from "@polkadot/util-crypto";
|
|
16800
|
-
async function
|
|
16955
|
+
async function getBridgeChainData({
|
|
16801
16956
|
route,
|
|
16802
16957
|
sourceAddress,
|
|
16803
16958
|
destinationAddress
|
|
@@ -16807,80 +16962,87 @@ async function getMoonChainData({
|
|
|
16807
16962
|
`MRL config is not defined for source chain ${route.source.chain.name} and asset ${route.source.asset.originSymbol}`
|
|
16808
16963
|
);
|
|
16809
16964
|
}
|
|
16810
|
-
const
|
|
16811
|
-
const
|
|
16812
|
-
|
|
16813
|
-
destination: route.destination.chain,
|
|
16965
|
+
const bridgeChain = route.mrl.bridgeChain.chain;
|
|
16966
|
+
const bridgeChainAddress = getBridgeChainAddress({
|
|
16967
|
+
route,
|
|
16814
16968
|
sourceAddress,
|
|
16815
16969
|
destinationAddress
|
|
16816
16970
|
});
|
|
16817
16971
|
const fee = await getDestinationFee({
|
|
16818
|
-
address:
|
|
16972
|
+
address: bridgeChainAddress,
|
|
16819
16973
|
asset: route.source.asset,
|
|
16820
|
-
destination:
|
|
16821
|
-
fee: route.mrl.
|
|
16822
|
-
feeAsset: route.mrl.
|
|
16974
|
+
destination: bridgeChain,
|
|
16975
|
+
fee: route.mrl.bridgeChain.fee.amount,
|
|
16976
|
+
feeAsset: route.mrl.bridgeChain.fee.asset,
|
|
16823
16977
|
source: route.source.chain
|
|
16824
16978
|
});
|
|
16825
16979
|
const balance = await getBalance({
|
|
16826
|
-
address:
|
|
16827
|
-
asset:
|
|
16828
|
-
builder: route.mrl.
|
|
16829
|
-
chain:
|
|
16980
|
+
address: bridgeChainAddress,
|
|
16981
|
+
asset: bridgeChain.getChainAsset(route.mrl.bridgeChain.asset),
|
|
16982
|
+
builder: route.mrl.bridgeChain.balance,
|
|
16983
|
+
chain: bridgeChain
|
|
16830
16984
|
});
|
|
16831
16985
|
const feeBalance = await getBalance({
|
|
16832
|
-
address:
|
|
16833
|
-
asset:
|
|
16834
|
-
builder: route.mrl.
|
|
16835
|
-
chain:
|
|
16986
|
+
address: bridgeChainAddress,
|
|
16987
|
+
asset: bridgeChain.getChainAsset(route.mrl.bridgeChain.fee.asset),
|
|
16988
|
+
builder: route.mrl.bridgeChain.fee.balance,
|
|
16989
|
+
chain: bridgeChain
|
|
16836
16990
|
});
|
|
16837
16991
|
return {
|
|
16838
|
-
address:
|
|
16992
|
+
address: bridgeChainAddress,
|
|
16839
16993
|
balance,
|
|
16840
16994
|
feeBalance,
|
|
16841
|
-
chain:
|
|
16995
|
+
chain: bridgeChain,
|
|
16842
16996
|
fee
|
|
16843
16997
|
};
|
|
16844
16998
|
}
|
|
16845
|
-
function
|
|
16846
|
-
|
|
16847
|
-
destination,
|
|
16999
|
+
function getBridgeChainAddress({
|
|
17000
|
+
route,
|
|
16848
17001
|
sourceAddress,
|
|
16849
17002
|
destinationAddress
|
|
16850
17003
|
}) {
|
|
16851
|
-
const
|
|
16852
|
-
const
|
|
16853
|
-
const
|
|
16854
|
-
|
|
16855
|
-
|
|
17004
|
+
const source = route.source.chain;
|
|
17005
|
+
const destination = route.destination.chain;
|
|
17006
|
+
const bridgeChain = route.mrl.bridgeChain.chain;
|
|
17007
|
+
const isDestinationBridgeChain = bridgeChain.isEqual(destination);
|
|
17008
|
+
const isSourceBridgeChain = bridgeChain.isEqual(source);
|
|
17009
|
+
let bridgeChainAddress = isDestinationBridgeChain ? destinationAddress : sourceAddress;
|
|
17010
|
+
if (Parachain.is(source) && !isSourceBridgeChain) {
|
|
16856
17011
|
const isSourceEvmSigner = EvmParachain.is(source) && source.isEvmSigner;
|
|
16857
17012
|
const { address20: computedOriginAccount } = getMultilocationDerivedAddresses({
|
|
16858
17013
|
address: isSourceEvmSigner ? evmToAddress(sourceAddress) : sourceAddress,
|
|
16859
17014
|
paraId: source.parachainId,
|
|
16860
17015
|
isParents: true
|
|
16861
17016
|
});
|
|
16862
|
-
|
|
17017
|
+
bridgeChainAddress = computedOriginAccount;
|
|
16863
17018
|
}
|
|
16864
|
-
return
|
|
17019
|
+
return bridgeChainAddress;
|
|
16865
17020
|
}
|
|
16866
17021
|
|
|
16867
17022
|
// src/getTransferData/getSourceData.ts
|
|
16868
17023
|
import {
|
|
16869
|
-
ContractConfig,
|
|
17024
|
+
ContractConfig as ContractConfig2,
|
|
16870
17025
|
MrlBuilder as MrlBuilder3,
|
|
17026
|
+
Provider as Provider2,
|
|
17027
|
+
SnowbridgeConfig,
|
|
17028
|
+
SubstrateQueryConfig,
|
|
16871
17029
|
WormholeConfig
|
|
16872
17030
|
} from "@moonbeam-network/xcm-builder";
|
|
16873
17031
|
import {
|
|
17032
|
+
EvmService as EvmService3,
|
|
16874
17033
|
getAssetMin,
|
|
16875
17034
|
getBalance as getBalance2,
|
|
16876
17035
|
getContractFee,
|
|
16877
17036
|
getDestinationFeeBalance,
|
|
16878
17037
|
getExistentialDeposit,
|
|
16879
17038
|
getExtrinsicFee,
|
|
16880
|
-
getMax
|
|
17039
|
+
getMax,
|
|
17040
|
+
PolkadotService as PolkadotService2
|
|
16881
17041
|
} from "@moonbeam-network/xcm-sdk";
|
|
16882
17042
|
import {
|
|
16883
|
-
AssetAmount as AssetAmount2
|
|
17043
|
+
AssetAmount as AssetAmount2,
|
|
17044
|
+
EvmChain as EvmChain2,
|
|
17045
|
+
EvmParachain as EvmParachain3
|
|
16884
17046
|
} from "@moonbeam-network/xcm-types";
|
|
16885
17047
|
import { toBigInt as toBigInt2 } from "@moonbeam-network/xcm-utils";
|
|
16886
17048
|
|
|
@@ -16888,11 +17050,11 @@ import { toBigInt as toBigInt2 } from "@moonbeam-network/xcm-utils";
|
|
|
16888
17050
|
import {
|
|
16889
17051
|
BATCH_CONTRACT_ABI,
|
|
16890
17052
|
BATCH_CONTRACT_ADDRESS,
|
|
16891
|
-
ERC20_ABI,
|
|
16892
|
-
MrlBuilder as MrlBuilder2
|
|
17053
|
+
ERC20_ABI as ERC20_ABI2,
|
|
17054
|
+
MrlBuilder as MrlBuilder2,
|
|
17055
|
+
Provider
|
|
16893
17056
|
} from "@moonbeam-network/xcm-builder";
|
|
16894
17057
|
import {
|
|
16895
|
-
getMoonChain as getMoonChain2,
|
|
16896
17058
|
moonbaseAlpha,
|
|
16897
17059
|
moonbeam
|
|
16898
17060
|
} from "@moonbeam-network/xcm-config";
|
|
@@ -16909,33 +17071,33 @@ import {
|
|
|
16909
17071
|
import Big from "big.js";
|
|
16910
17072
|
import {
|
|
16911
17073
|
createPublicClient as createPublicClient2,
|
|
16912
|
-
encodeFunctionData,
|
|
17074
|
+
encodeFunctionData as encodeFunctionData2,
|
|
16913
17075
|
http as http2
|
|
16914
17076
|
} from "viem";
|
|
16915
17077
|
var MOON_CHAIN_AUTOMATIC_GAS_ESTIMATION = {
|
|
16916
17078
|
[moonbeam.key]: 1273110n,
|
|
16917
17079
|
[moonbaseAlpha.key]: 1470417n
|
|
16918
17080
|
};
|
|
16919
|
-
function
|
|
17081
|
+
function getBridgeChainFeeValueOnSource({
|
|
16920
17082
|
destinationData,
|
|
16921
|
-
|
|
17083
|
+
bridgeChainData,
|
|
16922
17084
|
sourceData
|
|
16923
17085
|
}) {
|
|
16924
17086
|
const isSourceParachain = EvmParachain2.isAnyParachain(sourceData.chain);
|
|
16925
|
-
const
|
|
16926
|
-
|
|
17087
|
+
const isDestinationBridgeChain = destinationData.chain.isEqual(
|
|
17088
|
+
bridgeChainData.chain
|
|
16927
17089
|
);
|
|
16928
|
-
const
|
|
16929
|
-
|
|
17090
|
+
const isSameAssetPayingBridgeChainFee = sourceData.balance.isSame(
|
|
17091
|
+
bridgeChainData.fee
|
|
16930
17092
|
);
|
|
16931
|
-
return !
|
|
16932
|
-
asset:
|
|
16933
|
-
target: sourceData.chain.getChainAsset(
|
|
17093
|
+
return !isDestinationBridgeChain && isSourceParachain && isSameAssetPayingBridgeChainFee ? convertToChainDecimals({
|
|
17094
|
+
asset: bridgeChainData.fee,
|
|
17095
|
+
target: sourceData.chain.getChainAsset(bridgeChainData.fee)
|
|
16934
17096
|
}).toBig() : Big(0);
|
|
16935
17097
|
}
|
|
16936
17098
|
function getMrlMin({
|
|
16937
17099
|
destinationData,
|
|
16938
|
-
|
|
17100
|
+
bridgeChainData,
|
|
16939
17101
|
sourceData
|
|
16940
17102
|
}) {
|
|
16941
17103
|
const minInDestination = getMin(destinationData);
|
|
@@ -16945,16 +17107,19 @@ function getMrlMin({
|
|
|
16945
17107
|
amount: minInDestination.amount
|
|
16946
17108
|
}
|
|
16947
17109
|
);
|
|
16948
|
-
const
|
|
17110
|
+
const bridgeChainFee = getBridgeChainFeeValueOnSource({
|
|
16949
17111
|
destinationData,
|
|
16950
|
-
|
|
17112
|
+
bridgeChainData,
|
|
16951
17113
|
sourceData
|
|
16952
17114
|
});
|
|
16953
|
-
const relayerFee = sourceData.
|
|
17115
|
+
const relayerFee = sourceData.otherFees?.relayer?.amount ? sourceData.otherFees.relayer.toBig() : Big(0);
|
|
16954
17116
|
return min.copyWith({
|
|
16955
|
-
amount: BigInt(min.toBig().add(
|
|
17117
|
+
amount: BigInt(min.toBig().add(bridgeChainFee).add(relayerFee).toFixed())
|
|
16956
17118
|
});
|
|
16957
17119
|
}
|
|
17120
|
+
function requiresTransact(route) {
|
|
17121
|
+
return route.mrl?.transfer.provider === Provider.Wormhole && EvmParachain2.isAnyParachain(route.source.chain);
|
|
17122
|
+
}
|
|
16958
17123
|
async function buildTransfer(params) {
|
|
16959
17124
|
const { route } = params;
|
|
16960
17125
|
if (!route.mrl) {
|
|
@@ -16970,11 +17135,12 @@ async function buildTransfer(params) {
|
|
|
16970
17135
|
const builderParams = await getMrlBuilderParams(params);
|
|
16971
17136
|
return route.mrl.transfer.build({
|
|
16972
17137
|
...builderParams,
|
|
16973
|
-
transact:
|
|
17138
|
+
transact: requiresTransact(route) ? await getTransact(builderParams) : void 0
|
|
16974
17139
|
});
|
|
16975
17140
|
}
|
|
16976
17141
|
async function getMrlBuilderParams({
|
|
16977
17142
|
asset,
|
|
17143
|
+
protocolFee,
|
|
16978
17144
|
destinationAddress,
|
|
16979
17145
|
feeAsset,
|
|
16980
17146
|
isAutomatic,
|
|
@@ -16989,22 +17155,23 @@ async function getMrlBuilderParams({
|
|
|
16989
17155
|
}
|
|
16990
17156
|
const source = route.source.chain;
|
|
16991
17157
|
const destination = route.destination.chain;
|
|
16992
|
-
const
|
|
16993
|
-
const [sourceApi, destinationApi,
|
|
17158
|
+
const bridgeChain = route.mrl.bridgeChain.chain;
|
|
17159
|
+
const [sourceApi, destinationApi, bridgeApi] = await Promise.all([
|
|
16994
17160
|
EvmParachain2.isAnyParachain(source) ? getPolkadotApi(source.ws) : void 0,
|
|
16995
17161
|
EvmParachain2.isAnyParachain(destination) ? getPolkadotApi(destination.ws) : void 0,
|
|
16996
|
-
getPolkadotApi(
|
|
17162
|
+
getPolkadotApi(bridgeChain.ws)
|
|
16997
17163
|
]);
|
|
16998
17164
|
return {
|
|
16999
17165
|
asset,
|
|
17166
|
+
protocolFee,
|
|
17000
17167
|
destination,
|
|
17001
17168
|
destinationAddress,
|
|
17002
17169
|
destinationApi,
|
|
17003
17170
|
fee: feeAsset,
|
|
17004
17171
|
isAutomatic,
|
|
17005
|
-
moonApi,
|
|
17006
|
-
moonAsset:
|
|
17007
|
-
|
|
17172
|
+
moonApi: bridgeApi,
|
|
17173
|
+
moonAsset: bridgeChain.nativeAsset,
|
|
17174
|
+
bridgeChain,
|
|
17008
17175
|
sendOnlyRemoteExecution,
|
|
17009
17176
|
source,
|
|
17010
17177
|
sourceAddress,
|
|
@@ -17012,9 +17179,9 @@ async function getMrlBuilderParams({
|
|
|
17012
17179
|
};
|
|
17013
17180
|
}
|
|
17014
17181
|
async function getTransact(params) {
|
|
17015
|
-
const { sourceAddress, source,
|
|
17016
|
-
const polkadot = await PolkadotService.create(
|
|
17017
|
-
const
|
|
17182
|
+
const { sourceAddress, source, bridgeChain } = params;
|
|
17183
|
+
const polkadot = await PolkadotService.create(bridgeChain);
|
|
17184
|
+
const bridgeChainGasLimit = await getBridgeChainGasLimit(params);
|
|
17018
17185
|
if (!EvmParachain2.isAnyParachain(source)) {
|
|
17019
17186
|
throw new Error("Source chain must be Parachain or EvmParachain");
|
|
17020
17187
|
}
|
|
@@ -17023,7 +17190,7 @@ async function getTransact(params) {
|
|
|
17023
17190
|
paraId: source.parachainId,
|
|
17024
17191
|
isParents: true
|
|
17025
17192
|
});
|
|
17026
|
-
const extrinsic = MrlBuilder2().wormhole().extrinsic().ethereumXcm().transact().build({ ...params,
|
|
17193
|
+
const extrinsic = MrlBuilder2().wormhole().extrinsic().ethereumXcm().transact().build({ ...params, bridgeChainGasLimit });
|
|
17027
17194
|
const { weight } = await polkadot.getPaymentInfo(address20, extrinsic);
|
|
17028
17195
|
return {
|
|
17029
17196
|
call: polkadot.getExtrinsicCallHash(extrinsic),
|
|
@@ -17033,13 +17200,16 @@ async function getTransact(params) {
|
|
|
17033
17200
|
}
|
|
17034
17201
|
};
|
|
17035
17202
|
}
|
|
17036
|
-
async function
|
|
17037
|
-
const { asset, isAutomatic,
|
|
17203
|
+
async function getBridgeChainGasLimit(params) {
|
|
17204
|
+
const { asset, isAutomatic, bridgeChain, source, sourceAddress } = params;
|
|
17038
17205
|
if (!EvmParachain2.isAnyParachain(source)) {
|
|
17039
17206
|
throw new Error("Source chain must be Parachain or EvmParachain");
|
|
17040
17207
|
}
|
|
17208
|
+
if (!EvmParachain2.is(bridgeChain)) {
|
|
17209
|
+
throw new Error("Bridge chain must be an EvmParachain");
|
|
17210
|
+
}
|
|
17041
17211
|
const client = createPublicClient2({
|
|
17042
|
-
chain:
|
|
17212
|
+
chain: bridgeChain.getViemChain(),
|
|
17043
17213
|
transport: http2()
|
|
17044
17214
|
});
|
|
17045
17215
|
const { address20 } = getMultilocationDerivedAddresses2({
|
|
@@ -17048,28 +17218,28 @@ async function getMoonGasLimit(params) {
|
|
|
17048
17218
|
isParents: true
|
|
17049
17219
|
});
|
|
17050
17220
|
if (isAutomatic) {
|
|
17051
|
-
return MOON_CHAIN_AUTOMATIC_GAS_ESTIMATION[
|
|
17221
|
+
return MOON_CHAIN_AUTOMATIC_GAS_ESTIMATION[bridgeChain.key] * 110n / 100n;
|
|
17052
17222
|
}
|
|
17053
17223
|
const contract = MrlBuilder2().wormhole().contract().TokenBridge().transferTokens().build({
|
|
17054
17224
|
...params,
|
|
17055
17225
|
asset: asset.copyWith({ amount: 0n })
|
|
17056
17226
|
});
|
|
17057
|
-
const approveTx =
|
|
17058
|
-
abi:
|
|
17227
|
+
const approveTx = encodeFunctionData2({
|
|
17228
|
+
abi: ERC20_ABI2,
|
|
17059
17229
|
functionName: "approve",
|
|
17060
17230
|
args: [contract.address, 0n]
|
|
17061
17231
|
});
|
|
17062
|
-
const
|
|
17063
|
-
if (!
|
|
17232
|
+
const tokenAddressOnBridgeChain = bridgeChain.getChainAsset(asset).address;
|
|
17233
|
+
if (!tokenAddressOnBridgeChain) {
|
|
17064
17234
|
throw new Error(
|
|
17065
|
-
`Asset ${asset.symbol} does not have a token address on chain ${
|
|
17235
|
+
`Asset ${asset.symbol} does not have a token address on chain ${bridgeChain.name}`
|
|
17066
17236
|
);
|
|
17067
17237
|
}
|
|
17068
|
-
const batchAll =
|
|
17238
|
+
const batchAll = encodeFunctionData2({
|
|
17069
17239
|
abi: BATCH_CONTRACT_ABI,
|
|
17070
17240
|
functionName: "batchAll",
|
|
17071
17241
|
args: [
|
|
17072
|
-
[
|
|
17242
|
+
[tokenAddressOnBridgeChain, contract.address],
|
|
17073
17243
|
[0n, 0n],
|
|
17074
17244
|
// Value to send for each call
|
|
17075
17245
|
[approveTx, contract.encodeFunctionData()],
|
|
@@ -17085,6 +17255,11 @@ async function getMoonGasLimit(params) {
|
|
|
17085
17255
|
});
|
|
17086
17256
|
return gasEstimation * 110n / 100n;
|
|
17087
17257
|
}
|
|
17258
|
+
function getAmountForTransferSimulation(balance, protocolFee) {
|
|
17259
|
+
return balance.copyWith({
|
|
17260
|
+
amount: balance.amount - protocolFee.amount > 0 ? balance.amount - protocolFee.amount : 0n
|
|
17261
|
+
});
|
|
17262
|
+
}
|
|
17088
17263
|
|
|
17089
17264
|
// src/getTransferData/getSourceData.ts
|
|
17090
17265
|
async function getSourceData({
|
|
@@ -17100,6 +17275,7 @@ async function getSourceData({
|
|
|
17100
17275
|
);
|
|
17101
17276
|
}
|
|
17102
17277
|
const source = route.source.chain;
|
|
17278
|
+
const destination = route.destination.chain;
|
|
17103
17279
|
const asset = source.getChainAsset(route.source.asset);
|
|
17104
17280
|
const feeAsset = route.source.fee ? source.getChainAsset(route.source.fee.asset) : asset;
|
|
17105
17281
|
const balance = await getBalance2({
|
|
@@ -17120,7 +17296,7 @@ async function getSourceData({
|
|
|
17120
17296
|
route,
|
|
17121
17297
|
sourceAddress
|
|
17122
17298
|
});
|
|
17123
|
-
const
|
|
17299
|
+
const bridgeChainFeeBalance = await getBridgeChainFeeBalance({
|
|
17124
17300
|
balance,
|
|
17125
17301
|
feeBalance,
|
|
17126
17302
|
route,
|
|
@@ -17132,8 +17308,18 @@ async function getSourceData({
|
|
|
17132
17308
|
builder: route.source.min,
|
|
17133
17309
|
chain: source
|
|
17134
17310
|
});
|
|
17311
|
+
const protocolFee = await getProtocolFee({
|
|
17312
|
+
source,
|
|
17313
|
+
destination,
|
|
17314
|
+
asset,
|
|
17315
|
+
feeAsset,
|
|
17316
|
+
balance,
|
|
17317
|
+
protocolFee: route.source.protocolFee,
|
|
17318
|
+
address: destinationAddress
|
|
17319
|
+
});
|
|
17135
17320
|
const transfer = await buildTransfer({
|
|
17136
|
-
asset: balance,
|
|
17321
|
+
asset: getAmountForTransferSimulation(balance, protocolFee),
|
|
17322
|
+
protocolFee,
|
|
17137
17323
|
destinationAddress,
|
|
17138
17324
|
feeAsset: feeBalance,
|
|
17139
17325
|
isAutomatic,
|
|
@@ -17170,13 +17356,16 @@ async function getSourceData({
|
|
|
17170
17356
|
chain: source,
|
|
17171
17357
|
destinationFee,
|
|
17172
17358
|
destinationFeeBalance,
|
|
17173
|
-
|
|
17359
|
+
bridgeChainFeeBalance,
|
|
17174
17360
|
existentialDeposit,
|
|
17175
17361
|
fee,
|
|
17176
17362
|
feeBalance,
|
|
17177
17363
|
max,
|
|
17178
17364
|
min,
|
|
17179
|
-
|
|
17365
|
+
otherFees: {
|
|
17366
|
+
protocol: protocolFee,
|
|
17367
|
+
relayer: relayerFee?.amount ? relayerFee : void 0
|
|
17368
|
+
}
|
|
17180
17369
|
};
|
|
17181
17370
|
}
|
|
17182
17371
|
async function getFee({
|
|
@@ -17193,16 +17382,33 @@ async function getFee({
|
|
|
17193
17382
|
amount: 0n
|
|
17194
17383
|
});
|
|
17195
17384
|
}
|
|
17196
|
-
if (
|
|
17197
|
-
|
|
17198
|
-
|
|
17199
|
-
|
|
17200
|
-
|
|
17201
|
-
|
|
17202
|
-
|
|
17203
|
-
|
|
17204
|
-
|
|
17205
|
-
|
|
17385
|
+
if (SnowbridgeConfig.is(transfer)) {
|
|
17386
|
+
const snowbridge = SnowbridgeService.create(chain2);
|
|
17387
|
+
try {
|
|
17388
|
+
const feeAmount = await snowbridge.getFee(sourceAddress, transfer);
|
|
17389
|
+
return AssetAmount2.fromChainAsset(chain2.getChainAsset(feeBalance), {
|
|
17390
|
+
amount: feeAmount
|
|
17391
|
+
});
|
|
17392
|
+
} catch (error) {
|
|
17393
|
+
console.error(error);
|
|
17394
|
+
return feeBalance.copyWith({ amount: 0n });
|
|
17395
|
+
}
|
|
17396
|
+
}
|
|
17397
|
+
if (ContractConfig2.is(transfer)) {
|
|
17398
|
+
try {
|
|
17399
|
+
return getContractFee({
|
|
17400
|
+
address: sourceAddress,
|
|
17401
|
+
balance,
|
|
17402
|
+
chain: chain2,
|
|
17403
|
+
contract: transfer,
|
|
17404
|
+
destinationFee,
|
|
17405
|
+
feeBalance,
|
|
17406
|
+
feeConfig
|
|
17407
|
+
});
|
|
17408
|
+
} catch (error) {
|
|
17409
|
+
console.error(error);
|
|
17410
|
+
return feeBalance.copyWith({ amount: 0n });
|
|
17411
|
+
}
|
|
17206
17412
|
}
|
|
17207
17413
|
return getExtrinsicFee({
|
|
17208
17414
|
address: sourceAddress,
|
|
@@ -17223,19 +17429,25 @@ async function getRelayerFee({
|
|
|
17223
17429
|
sourceAddress,
|
|
17224
17430
|
transfer
|
|
17225
17431
|
}) {
|
|
17432
|
+
if (route.mrl.transfer.provider === Provider2.Snowbridge || SnowbridgeConfig.is(transfer)) {
|
|
17433
|
+
return void 0;
|
|
17434
|
+
}
|
|
17226
17435
|
if (WormholeConfig.is(transfer)) {
|
|
17227
17436
|
return getWormholeFee({ asset, chain: chain2, config: transfer });
|
|
17228
17437
|
}
|
|
17229
|
-
|
|
17230
|
-
|
|
17231
|
-
|
|
17232
|
-
|
|
17233
|
-
|
|
17234
|
-
|
|
17235
|
-
|
|
17236
|
-
|
|
17237
|
-
|
|
17238
|
-
|
|
17438
|
+
if (route.mrl.transfer.provider === Provider2.Wormhole) {
|
|
17439
|
+
const builderParams = await getMrlBuilderParams({
|
|
17440
|
+
asset,
|
|
17441
|
+
destinationAddress,
|
|
17442
|
+
feeAsset,
|
|
17443
|
+
isAutomatic,
|
|
17444
|
+
route,
|
|
17445
|
+
sourceAddress
|
|
17446
|
+
});
|
|
17447
|
+
const wormholeConfig = MrlBuilder3().wormhole().wormhole().tokenTransfer().build(builderParams);
|
|
17448
|
+
return getWormholeFee({ asset, chain: chain2, config: wormholeConfig });
|
|
17449
|
+
}
|
|
17450
|
+
return;
|
|
17239
17451
|
}
|
|
17240
17452
|
async function getWormholeFee({
|
|
17241
17453
|
asset,
|
|
@@ -17252,33 +17464,78 @@ async function getWormholeFee({
|
|
|
17252
17464
|
}
|
|
17253
17465
|
return;
|
|
17254
17466
|
}
|
|
17255
|
-
async function
|
|
17467
|
+
async function getBridgeChainFeeBalance({
|
|
17256
17468
|
balance,
|
|
17257
17469
|
feeBalance,
|
|
17258
17470
|
route,
|
|
17259
17471
|
sourceAddress
|
|
17260
17472
|
}) {
|
|
17261
|
-
if (!route.source.
|
|
17473
|
+
if (!route.source.bridgeChainFee) {
|
|
17262
17474
|
return void 0;
|
|
17263
17475
|
}
|
|
17264
|
-
if (route.mrl?.
|
|
17476
|
+
if (route.mrl?.bridgeChain.fee.asset.isEqual(balance)) {
|
|
17265
17477
|
return balance;
|
|
17266
17478
|
}
|
|
17267
|
-
if (route.mrl?.
|
|
17479
|
+
if (route.mrl?.bridgeChain.fee.asset.isEqual(feeBalance)) {
|
|
17268
17480
|
return feeBalance;
|
|
17269
17481
|
}
|
|
17270
|
-
if (!route.source.
|
|
17482
|
+
if (!route.source.bridgeChainFee.balance) {
|
|
17271
17483
|
throw new Error(
|
|
17272
|
-
"BalanceBuilder must be defined for source.
|
|
17484
|
+
"BalanceBuilder must be defined for source.bridgeChainFee.balance for MrlAssetRoute"
|
|
17273
17485
|
);
|
|
17274
17486
|
}
|
|
17275
17487
|
return getBalance2({
|
|
17276
17488
|
address: sourceAddress,
|
|
17277
|
-
asset: route.source.chain.getChainAsset(route.source.
|
|
17278
|
-
builder: route.source.
|
|
17489
|
+
asset: route.source.chain.getChainAsset(route.source.bridgeChainFee.asset),
|
|
17490
|
+
builder: route.source.bridgeChainFee.balance,
|
|
17279
17491
|
chain: route.source.chain
|
|
17280
17492
|
});
|
|
17281
17493
|
}
|
|
17494
|
+
async function getProtocolFee({
|
|
17495
|
+
address,
|
|
17496
|
+
asset,
|
|
17497
|
+
feeAsset,
|
|
17498
|
+
balance,
|
|
17499
|
+
protocolFee,
|
|
17500
|
+
destination,
|
|
17501
|
+
source
|
|
17502
|
+
}) {
|
|
17503
|
+
if (typeof protocolFee === "number") {
|
|
17504
|
+
return AssetAmount2.fromChainAsset(asset, {
|
|
17505
|
+
amount: protocolFee
|
|
17506
|
+
});
|
|
17507
|
+
}
|
|
17508
|
+
const config = protocolFee?.build({
|
|
17509
|
+
address,
|
|
17510
|
+
asset,
|
|
17511
|
+
feeAsset,
|
|
17512
|
+
balance,
|
|
17513
|
+
destination,
|
|
17514
|
+
source
|
|
17515
|
+
});
|
|
17516
|
+
if (ContractConfig2.is(config) && EvmChain2.is(source)) {
|
|
17517
|
+
const evm = EvmService3.create(source);
|
|
17518
|
+
const amount = await evm.read(config);
|
|
17519
|
+
if (typeof amount !== "bigint") {
|
|
17520
|
+
throw new Error(
|
|
17521
|
+
`Error getting bridge fee: expected bigint from contract call, but received ${typeof amount}. `
|
|
17522
|
+
);
|
|
17523
|
+
}
|
|
17524
|
+
return AssetAmount2.fromChainAsset(feeAsset, {
|
|
17525
|
+
amount
|
|
17526
|
+
});
|
|
17527
|
+
}
|
|
17528
|
+
if (SubstrateQueryConfig.is(config) && EvmParachain3.isAnyParachain(source)) {
|
|
17529
|
+
const polkadot = await PolkadotService2.create(source);
|
|
17530
|
+
const amount = await polkadot.query(config);
|
|
17531
|
+
return AssetAmount2.fromChainAsset(feeAsset, {
|
|
17532
|
+
amount
|
|
17533
|
+
});
|
|
17534
|
+
}
|
|
17535
|
+
return AssetAmount2.fromChainAsset(feeAsset, {
|
|
17536
|
+
amount: 0n
|
|
17537
|
+
});
|
|
17538
|
+
}
|
|
17282
17539
|
|
|
17283
17540
|
// src/getTransferData/getTransferData.ts
|
|
17284
17541
|
async function getTransferData({
|
|
@@ -17307,7 +17564,7 @@ async function getTransferData({
|
|
|
17307
17564
|
destinationFee,
|
|
17308
17565
|
sourceAddress
|
|
17309
17566
|
});
|
|
17310
|
-
const
|
|
17567
|
+
const bridgeChainData = await getBridgeChainData({
|
|
17311
17568
|
route,
|
|
17312
17569
|
sourceAddress,
|
|
17313
17570
|
destinationAddress
|
|
@@ -17319,14 +17576,14 @@ async function getTransferData({
|
|
|
17319
17576
|
const bigAmount = Big2(
|
|
17320
17577
|
toBigInt3(amount, sourceData.balance.decimals).toString()
|
|
17321
17578
|
);
|
|
17322
|
-
const fee =
|
|
17579
|
+
const fee = getBridgeChainFeeValueOnSource({
|
|
17323
17580
|
destinationData,
|
|
17324
|
-
|
|
17581
|
+
bridgeChainData,
|
|
17325
17582
|
sourceData
|
|
17326
17583
|
});
|
|
17327
17584
|
const result = bigAmount.minus(
|
|
17328
17585
|
isSameAssetPayingDestinationFee ? destinationFee.toBig() : Big2(0)
|
|
17329
|
-
).minus(fee).minus(sourceData.
|
|
17586
|
+
).minus(fee).minus(sourceData.otherFees?.relayer?.toBig() || Big2(0));
|
|
17330
17587
|
return sourceData.balance.copyWith({
|
|
17331
17588
|
amount: result.lt(0) ? 0n : BigInt(result.toFixed())
|
|
17332
17589
|
});
|
|
@@ -17335,10 +17592,10 @@ async function getTransferData({
|
|
|
17335
17592
|
max: sourceData.max,
|
|
17336
17593
|
min: getMrlMin({
|
|
17337
17594
|
destinationData,
|
|
17338
|
-
|
|
17595
|
+
bridgeChainData,
|
|
17339
17596
|
sourceData
|
|
17340
17597
|
}),
|
|
17341
|
-
|
|
17598
|
+
bridgeChain: bridgeChainData,
|
|
17342
17599
|
source: sourceData,
|
|
17343
17600
|
async transfer({
|
|
17344
17601
|
amount,
|
|
@@ -17361,6 +17618,7 @@ async function getTransferData({
|
|
|
17361
17618
|
);
|
|
17362
17619
|
const transfer = await buildTransfer({
|
|
17363
17620
|
asset,
|
|
17621
|
+
protocolFee: sourceData.otherFees?.protocol,
|
|
17364
17622
|
destinationAddress,
|
|
17365
17623
|
feeAsset,
|
|
17366
17624
|
isAutomatic: isAutomatic2,
|
|
@@ -17368,19 +17626,19 @@ async function getTransferData({
|
|
|
17368
17626
|
sendOnlyRemoteExecution,
|
|
17369
17627
|
sourceAddress
|
|
17370
17628
|
});
|
|
17371
|
-
if (
|
|
17629
|
+
if (ContractConfig3.is(transfer) && (EvmChain3.is(source) || EvmParachain4.is(source))) {
|
|
17372
17630
|
if (!evmSigner) {
|
|
17373
17631
|
throw new Error("EVM Signer must be provided");
|
|
17374
17632
|
}
|
|
17375
|
-
const evm =
|
|
17633
|
+
const evm = EvmService4.create(source);
|
|
17376
17634
|
const hash = await evm.transfer(evmSigner, transfer);
|
|
17377
17635
|
return [hash];
|
|
17378
17636
|
}
|
|
17379
|
-
if (ExtrinsicConfig.is(transfer) &&
|
|
17637
|
+
if (ExtrinsicConfig.is(transfer) && EvmParachain4.isAnyParachain(source)) {
|
|
17380
17638
|
if (!polkadotSigner) {
|
|
17381
17639
|
throw new Error("Polkadot signer must be provided");
|
|
17382
17640
|
}
|
|
17383
|
-
const polkadot = await
|
|
17641
|
+
const polkadot = await PolkadotService3.create(source);
|
|
17384
17642
|
const hash = await polkadot.transfer(
|
|
17385
17643
|
sourceAddress,
|
|
17386
17644
|
transfer,
|
|
@@ -17389,13 +17647,21 @@ async function getTransferData({
|
|
|
17389
17647
|
);
|
|
17390
17648
|
return [hash];
|
|
17391
17649
|
}
|
|
17392
|
-
if (WormholeConfig2.is(transfer) && (
|
|
17650
|
+
if (WormholeConfig2.is(transfer) && (EvmChain3.is(source) || EvmParachain4.is(source))) {
|
|
17393
17651
|
if (!evmSigner) {
|
|
17394
17652
|
throw new Error("EVM Signer must be provided");
|
|
17395
17653
|
}
|
|
17396
17654
|
const wh = WormholeService.create(source);
|
|
17397
17655
|
return wh.transfer(evmSigner, transfer);
|
|
17398
17656
|
}
|
|
17657
|
+
if (SnowbridgeConfig2.is(transfer) && (EvmChain3.is(source) || EvmParachain4.is(source))) {
|
|
17658
|
+
if (!evmSigner) {
|
|
17659
|
+
throw new Error("EVM Signer must be provided");
|
|
17660
|
+
}
|
|
17661
|
+
const snowbridge = SnowbridgeService.create(source);
|
|
17662
|
+
const hash = await snowbridge.transfer(evmSigner, transfer);
|
|
17663
|
+
return [hash];
|
|
17664
|
+
}
|
|
17399
17665
|
throw new Error("Either contract or extrinsic must be provided");
|
|
17400
17666
|
}
|
|
17401
17667
|
};
|