@moonbeam-network/mrl 1.0.0-dev.270 → 1.0.0-dev.272
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 +381 -129
- 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,14 +17050,13 @@ 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
|
-
moonbeam
|
|
16898
|
-
moonriver
|
|
17059
|
+
moonbeam
|
|
16899
17060
|
} from "@moonbeam-network/xcm-config";
|
|
16900
17061
|
import {
|
|
16901
17062
|
convertToChainDecimals,
|
|
@@ -16910,34 +17071,33 @@ import {
|
|
|
16910
17071
|
import Big from "big.js";
|
|
16911
17072
|
import {
|
|
16912
17073
|
createPublicClient as createPublicClient2,
|
|
16913
|
-
encodeFunctionData,
|
|
17074
|
+
encodeFunctionData as encodeFunctionData2,
|
|
16914
17075
|
http as http2
|
|
16915
17076
|
} from "viem";
|
|
16916
17077
|
var MOON_CHAIN_AUTOMATIC_GAS_ESTIMATION = {
|
|
16917
17078
|
[moonbeam.key]: 1273110n,
|
|
16918
|
-
[moonriver.key]: 1273110n,
|
|
16919
17079
|
[moonbaseAlpha.key]: 1470417n
|
|
16920
17080
|
};
|
|
16921
|
-
function
|
|
17081
|
+
function getBridgeChainFeeValueOnSource({
|
|
16922
17082
|
destinationData,
|
|
16923
|
-
|
|
17083
|
+
bridgeChainData,
|
|
16924
17084
|
sourceData
|
|
16925
17085
|
}) {
|
|
16926
17086
|
const isSourceParachain = EvmParachain2.isAnyParachain(sourceData.chain);
|
|
16927
|
-
const
|
|
16928
|
-
|
|
17087
|
+
const isDestinationBridgeChain = destinationData.chain.isEqual(
|
|
17088
|
+
bridgeChainData.chain
|
|
16929
17089
|
);
|
|
16930
|
-
const
|
|
16931
|
-
|
|
17090
|
+
const isSameAssetPayingBridgeChainFee = sourceData.balance.isSame(
|
|
17091
|
+
bridgeChainData.fee
|
|
16932
17092
|
);
|
|
16933
|
-
return !
|
|
16934
|
-
asset:
|
|
16935
|
-
target: sourceData.chain.getChainAsset(
|
|
17093
|
+
return !isDestinationBridgeChain && isSourceParachain && isSameAssetPayingBridgeChainFee ? convertToChainDecimals({
|
|
17094
|
+
asset: bridgeChainData.fee,
|
|
17095
|
+
target: sourceData.chain.getChainAsset(bridgeChainData.fee)
|
|
16936
17096
|
}).toBig() : Big(0);
|
|
16937
17097
|
}
|
|
16938
17098
|
function getMrlMin({
|
|
16939
17099
|
destinationData,
|
|
16940
|
-
|
|
17100
|
+
bridgeChainData,
|
|
16941
17101
|
sourceData
|
|
16942
17102
|
}) {
|
|
16943
17103
|
const minInDestination = getMin(destinationData);
|
|
@@ -16947,16 +17107,19 @@ function getMrlMin({
|
|
|
16947
17107
|
amount: minInDestination.amount
|
|
16948
17108
|
}
|
|
16949
17109
|
);
|
|
16950
|
-
const
|
|
17110
|
+
const bridgeChainFee = getBridgeChainFeeValueOnSource({
|
|
16951
17111
|
destinationData,
|
|
16952
|
-
|
|
17112
|
+
bridgeChainData,
|
|
16953
17113
|
sourceData
|
|
16954
17114
|
});
|
|
16955
|
-
const relayerFee = sourceData.
|
|
17115
|
+
const relayerFee = sourceData.otherFees?.relayer?.amount ? sourceData.otherFees.relayer.toBig() : Big(0);
|
|
16956
17116
|
return min.copyWith({
|
|
16957
|
-
amount: BigInt(min.toBig().add(
|
|
17117
|
+
amount: BigInt(min.toBig().add(bridgeChainFee).add(relayerFee).toFixed())
|
|
16958
17118
|
});
|
|
16959
17119
|
}
|
|
17120
|
+
function requiresTransact(route) {
|
|
17121
|
+
return route.mrl?.transfer.provider === Provider.Wormhole && EvmParachain2.isAnyParachain(route.source.chain);
|
|
17122
|
+
}
|
|
16960
17123
|
async function buildTransfer(params) {
|
|
16961
17124
|
const { route } = params;
|
|
16962
17125
|
if (!route.mrl) {
|
|
@@ -16972,11 +17135,12 @@ async function buildTransfer(params) {
|
|
|
16972
17135
|
const builderParams = await getMrlBuilderParams(params);
|
|
16973
17136
|
return route.mrl.transfer.build({
|
|
16974
17137
|
...builderParams,
|
|
16975
|
-
transact:
|
|
17138
|
+
transact: requiresTransact(route) ? await getTransact(builderParams) : void 0
|
|
16976
17139
|
});
|
|
16977
17140
|
}
|
|
16978
17141
|
async function getMrlBuilderParams({
|
|
16979
17142
|
asset,
|
|
17143
|
+
protocolFee,
|
|
16980
17144
|
destinationAddress,
|
|
16981
17145
|
feeAsset,
|
|
16982
17146
|
isAutomatic,
|
|
@@ -16991,22 +17155,23 @@ async function getMrlBuilderParams({
|
|
|
16991
17155
|
}
|
|
16992
17156
|
const source = route.source.chain;
|
|
16993
17157
|
const destination = route.destination.chain;
|
|
16994
|
-
const
|
|
16995
|
-
const [sourceApi, destinationApi,
|
|
17158
|
+
const bridgeChain = route.mrl.bridgeChain.chain;
|
|
17159
|
+
const [sourceApi, destinationApi, bridgeApi] = await Promise.all([
|
|
16996
17160
|
EvmParachain2.isAnyParachain(source) ? getPolkadotApi(source.ws) : void 0,
|
|
16997
17161
|
EvmParachain2.isAnyParachain(destination) ? getPolkadotApi(destination.ws) : void 0,
|
|
16998
|
-
getPolkadotApi(
|
|
17162
|
+
getPolkadotApi(bridgeChain.ws)
|
|
16999
17163
|
]);
|
|
17000
17164
|
return {
|
|
17001
17165
|
asset,
|
|
17166
|
+
protocolFee,
|
|
17002
17167
|
destination,
|
|
17003
17168
|
destinationAddress,
|
|
17004
17169
|
destinationApi,
|
|
17005
17170
|
fee: feeAsset,
|
|
17006
17171
|
isAutomatic,
|
|
17007
|
-
moonApi,
|
|
17008
|
-
moonAsset:
|
|
17009
|
-
|
|
17172
|
+
moonApi: bridgeApi,
|
|
17173
|
+
moonAsset: bridgeChain.nativeAsset,
|
|
17174
|
+
bridgeChain,
|
|
17010
17175
|
sendOnlyRemoteExecution,
|
|
17011
17176
|
source,
|
|
17012
17177
|
sourceAddress,
|
|
@@ -17014,9 +17179,9 @@ async function getMrlBuilderParams({
|
|
|
17014
17179
|
};
|
|
17015
17180
|
}
|
|
17016
17181
|
async function getTransact(params) {
|
|
17017
|
-
const { sourceAddress, source,
|
|
17018
|
-
const polkadot = await PolkadotService.create(
|
|
17019
|
-
const
|
|
17182
|
+
const { sourceAddress, source, bridgeChain } = params;
|
|
17183
|
+
const polkadot = await PolkadotService.create(bridgeChain);
|
|
17184
|
+
const bridgeChainGasLimit = await getBridgeChainGasLimit(params);
|
|
17020
17185
|
if (!EvmParachain2.isAnyParachain(source)) {
|
|
17021
17186
|
throw new Error("Source chain must be Parachain or EvmParachain");
|
|
17022
17187
|
}
|
|
@@ -17025,9 +17190,8 @@ async function getTransact(params) {
|
|
|
17025
17190
|
paraId: source.parachainId,
|
|
17026
17191
|
isParents: true
|
|
17027
17192
|
});
|
|
17028
|
-
const extrinsic = MrlBuilder2().wormhole().extrinsic().ethereumXcm().transact().build({ ...params,
|
|
17193
|
+
const extrinsic = MrlBuilder2().wormhole().extrinsic().ethereumXcm().transact().build({ ...params, bridgeChainGasLimit });
|
|
17029
17194
|
const { weight } = await polkadot.getPaymentInfo(address20, extrinsic);
|
|
17030
|
-
console.log("extrinsic", extrinsic.getArgs());
|
|
17031
17195
|
return {
|
|
17032
17196
|
call: polkadot.getExtrinsicCallHash(extrinsic),
|
|
17033
17197
|
txWeight: {
|
|
@@ -17036,13 +17200,16 @@ async function getTransact(params) {
|
|
|
17036
17200
|
}
|
|
17037
17201
|
};
|
|
17038
17202
|
}
|
|
17039
|
-
async function
|
|
17040
|
-
const { asset, isAutomatic,
|
|
17203
|
+
async function getBridgeChainGasLimit(params) {
|
|
17204
|
+
const { asset, isAutomatic, bridgeChain, source, sourceAddress } = params;
|
|
17041
17205
|
if (!EvmParachain2.isAnyParachain(source)) {
|
|
17042
17206
|
throw new Error("Source chain must be Parachain or EvmParachain");
|
|
17043
17207
|
}
|
|
17208
|
+
if (!EvmParachain2.is(bridgeChain)) {
|
|
17209
|
+
throw new Error("Bridge chain must be an EvmParachain");
|
|
17210
|
+
}
|
|
17044
17211
|
const client = createPublicClient2({
|
|
17045
|
-
chain:
|
|
17212
|
+
chain: bridgeChain.getViemChain(),
|
|
17046
17213
|
transport: http2()
|
|
17047
17214
|
});
|
|
17048
17215
|
const { address20 } = getMultilocationDerivedAddresses2({
|
|
@@ -17051,28 +17218,28 @@ async function getMoonGasLimit(params) {
|
|
|
17051
17218
|
isParents: true
|
|
17052
17219
|
});
|
|
17053
17220
|
if (isAutomatic) {
|
|
17054
|
-
return MOON_CHAIN_AUTOMATIC_GAS_ESTIMATION[
|
|
17221
|
+
return MOON_CHAIN_AUTOMATIC_GAS_ESTIMATION[bridgeChain.key] * 110n / 100n;
|
|
17055
17222
|
}
|
|
17056
17223
|
const contract = MrlBuilder2().wormhole().contract().TokenBridge().transferTokens().build({
|
|
17057
17224
|
...params,
|
|
17058
17225
|
asset: asset.copyWith({ amount: 0n })
|
|
17059
17226
|
});
|
|
17060
|
-
const approveTx =
|
|
17061
|
-
abi:
|
|
17227
|
+
const approveTx = encodeFunctionData2({
|
|
17228
|
+
abi: ERC20_ABI2,
|
|
17062
17229
|
functionName: "approve",
|
|
17063
17230
|
args: [contract.address, 0n]
|
|
17064
17231
|
});
|
|
17065
|
-
const
|
|
17066
|
-
if (!
|
|
17232
|
+
const tokenAddressOnBridgeChain = bridgeChain.getChainAsset(asset).address;
|
|
17233
|
+
if (!tokenAddressOnBridgeChain) {
|
|
17067
17234
|
throw new Error(
|
|
17068
|
-
`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}`
|
|
17069
17236
|
);
|
|
17070
17237
|
}
|
|
17071
|
-
const batchAll =
|
|
17238
|
+
const batchAll = encodeFunctionData2({
|
|
17072
17239
|
abi: BATCH_CONTRACT_ABI,
|
|
17073
17240
|
functionName: "batchAll",
|
|
17074
17241
|
args: [
|
|
17075
|
-
[
|
|
17242
|
+
[tokenAddressOnBridgeChain, contract.address],
|
|
17076
17243
|
[0n, 0n],
|
|
17077
17244
|
// Value to send for each call
|
|
17078
17245
|
[approveTx, contract.encodeFunctionData()],
|
|
@@ -17103,6 +17270,7 @@ async function getSourceData({
|
|
|
17103
17270
|
);
|
|
17104
17271
|
}
|
|
17105
17272
|
const source = route.source.chain;
|
|
17273
|
+
const destination = route.destination.chain;
|
|
17106
17274
|
const asset = source.getChainAsset(route.source.asset);
|
|
17107
17275
|
const feeAsset = route.source.fee ? source.getChainAsset(route.source.fee.asset) : asset;
|
|
17108
17276
|
const balance = await getBalance2({
|
|
@@ -17123,7 +17291,7 @@ async function getSourceData({
|
|
|
17123
17291
|
route,
|
|
17124
17292
|
sourceAddress
|
|
17125
17293
|
});
|
|
17126
|
-
const
|
|
17294
|
+
const bridgeChainFeeBalance = await getBridgeChainFeeBalance({
|
|
17127
17295
|
balance,
|
|
17128
17296
|
feeBalance,
|
|
17129
17297
|
route,
|
|
@@ -17135,8 +17303,19 @@ async function getSourceData({
|
|
|
17135
17303
|
builder: route.source.min,
|
|
17136
17304
|
chain: source
|
|
17137
17305
|
});
|
|
17306
|
+
const protocolFee = await getProtocolFee({
|
|
17307
|
+
source,
|
|
17308
|
+
destination,
|
|
17309
|
+
// For now, the fee asset is always the one used for the protocol fee
|
|
17310
|
+
// If it where to change, we need make protocolFee a FeeConfig in MrlSourceConfig
|
|
17311
|
+
asset: feeAsset,
|
|
17312
|
+
balance,
|
|
17313
|
+
protocolFee: route.source.protocolFee,
|
|
17314
|
+
address: destinationAddress
|
|
17315
|
+
});
|
|
17138
17316
|
const transfer = await buildTransfer({
|
|
17139
|
-
asset: balance,
|
|
17317
|
+
asset: balance.copyWith({ amount: balance.amount - protocolFee.amount }),
|
|
17318
|
+
protocolFee,
|
|
17140
17319
|
destinationAddress,
|
|
17141
17320
|
feeAsset: feeBalance,
|
|
17142
17321
|
isAutomatic,
|
|
@@ -17173,13 +17352,16 @@ async function getSourceData({
|
|
|
17173
17352
|
chain: source,
|
|
17174
17353
|
destinationFee,
|
|
17175
17354
|
destinationFeeBalance,
|
|
17176
|
-
|
|
17355
|
+
bridgeChainFeeBalance,
|
|
17177
17356
|
existentialDeposit,
|
|
17178
17357
|
fee,
|
|
17179
17358
|
feeBalance,
|
|
17180
17359
|
max,
|
|
17181
17360
|
min,
|
|
17182
|
-
|
|
17361
|
+
otherFees: {
|
|
17362
|
+
protocol: protocolFee,
|
|
17363
|
+
relayer: relayerFee?.amount ? relayerFee : void 0
|
|
17364
|
+
}
|
|
17183
17365
|
};
|
|
17184
17366
|
}
|
|
17185
17367
|
async function getFee({
|
|
@@ -17196,17 +17378,29 @@ async function getFee({
|
|
|
17196
17378
|
amount: 0n
|
|
17197
17379
|
});
|
|
17198
17380
|
}
|
|
17199
|
-
if (
|
|
17200
|
-
|
|
17201
|
-
|
|
17202
|
-
|
|
17203
|
-
|
|
17204
|
-
contract: transfer,
|
|
17205
|
-
destinationFee,
|
|
17206
|
-
feeBalance,
|
|
17207
|
-
feeConfig
|
|
17381
|
+
if (SnowbridgeConfig.is(transfer)) {
|
|
17382
|
+
const snowbridge = SnowbridgeService.create(chain2);
|
|
17383
|
+
const feeAmount = await snowbridge.getFee(sourceAddress, transfer);
|
|
17384
|
+
return AssetAmount2.fromChainAsset(chain2.getChainAsset(feeBalance), {
|
|
17385
|
+
amount: feeAmount
|
|
17208
17386
|
});
|
|
17209
17387
|
}
|
|
17388
|
+
if (ContractConfig2.is(transfer)) {
|
|
17389
|
+
try {
|
|
17390
|
+
return getContractFee({
|
|
17391
|
+
address: sourceAddress,
|
|
17392
|
+
balance,
|
|
17393
|
+
chain: chain2,
|
|
17394
|
+
contract: transfer,
|
|
17395
|
+
destinationFee,
|
|
17396
|
+
feeBalance,
|
|
17397
|
+
feeConfig
|
|
17398
|
+
});
|
|
17399
|
+
} catch (error) {
|
|
17400
|
+
console.error(error);
|
|
17401
|
+
return feeBalance.copyWith({ amount: 0n });
|
|
17402
|
+
}
|
|
17403
|
+
}
|
|
17210
17404
|
return getExtrinsicFee({
|
|
17211
17405
|
address: sourceAddress,
|
|
17212
17406
|
balance,
|
|
@@ -17226,19 +17420,25 @@ async function getRelayerFee({
|
|
|
17226
17420
|
sourceAddress,
|
|
17227
17421
|
transfer
|
|
17228
17422
|
}) {
|
|
17423
|
+
if (route.mrl.transfer.provider === Provider2.Snowbridge || SnowbridgeConfig.is(transfer)) {
|
|
17424
|
+
return void 0;
|
|
17425
|
+
}
|
|
17229
17426
|
if (WormholeConfig.is(transfer)) {
|
|
17230
17427
|
return getWormholeFee({ asset, chain: chain2, config: transfer });
|
|
17231
17428
|
}
|
|
17232
|
-
|
|
17233
|
-
|
|
17234
|
-
|
|
17235
|
-
|
|
17236
|
-
|
|
17237
|
-
|
|
17238
|
-
|
|
17239
|
-
|
|
17240
|
-
|
|
17241
|
-
|
|
17429
|
+
if (route.mrl.transfer.provider === Provider2.Wormhole) {
|
|
17430
|
+
const builderParams = await getMrlBuilderParams({
|
|
17431
|
+
asset,
|
|
17432
|
+
destinationAddress,
|
|
17433
|
+
feeAsset,
|
|
17434
|
+
isAutomatic,
|
|
17435
|
+
route,
|
|
17436
|
+
sourceAddress
|
|
17437
|
+
});
|
|
17438
|
+
const wormholeConfig = MrlBuilder3().wormhole().wormhole().tokenTransfer().build(builderParams);
|
|
17439
|
+
return getWormholeFee({ asset, chain: chain2, config: wormholeConfig });
|
|
17440
|
+
}
|
|
17441
|
+
return;
|
|
17242
17442
|
}
|
|
17243
17443
|
async function getWormholeFee({
|
|
17244
17444
|
asset,
|
|
@@ -17255,33 +17455,76 @@ async function getWormholeFee({
|
|
|
17255
17455
|
}
|
|
17256
17456
|
return;
|
|
17257
17457
|
}
|
|
17258
|
-
async function
|
|
17458
|
+
async function getBridgeChainFeeBalance({
|
|
17259
17459
|
balance,
|
|
17260
17460
|
feeBalance,
|
|
17261
17461
|
route,
|
|
17262
17462
|
sourceAddress
|
|
17263
17463
|
}) {
|
|
17264
|
-
if (!route.source.
|
|
17464
|
+
if (!route.source.bridgeChainFee) {
|
|
17265
17465
|
return void 0;
|
|
17266
17466
|
}
|
|
17267
|
-
if (route.mrl?.
|
|
17467
|
+
if (route.mrl?.bridgeChain.fee.asset.isEqual(balance)) {
|
|
17268
17468
|
return balance;
|
|
17269
17469
|
}
|
|
17270
|
-
if (route.mrl?.
|
|
17470
|
+
if (route.mrl?.bridgeChain.fee.asset.isEqual(feeBalance)) {
|
|
17271
17471
|
return feeBalance;
|
|
17272
17472
|
}
|
|
17273
|
-
if (!route.source.
|
|
17473
|
+
if (!route.source.bridgeChainFee.balance) {
|
|
17274
17474
|
throw new Error(
|
|
17275
|
-
"BalanceBuilder must be defined for source.
|
|
17475
|
+
"BalanceBuilder must be defined for source.bridgeChainFee.balance for MrlAssetRoute"
|
|
17276
17476
|
);
|
|
17277
17477
|
}
|
|
17278
17478
|
return getBalance2({
|
|
17279
17479
|
address: sourceAddress,
|
|
17280
|
-
asset: route.source.chain.getChainAsset(route.source.
|
|
17281
|
-
builder: route.source.
|
|
17480
|
+
asset: route.source.chain.getChainAsset(route.source.bridgeChainFee.asset),
|
|
17481
|
+
builder: route.source.bridgeChainFee.balance,
|
|
17282
17482
|
chain: route.source.chain
|
|
17283
17483
|
});
|
|
17284
17484
|
}
|
|
17485
|
+
async function getProtocolFee({
|
|
17486
|
+
address,
|
|
17487
|
+
asset,
|
|
17488
|
+
balance,
|
|
17489
|
+
protocolFee,
|
|
17490
|
+
destination,
|
|
17491
|
+
source
|
|
17492
|
+
}) {
|
|
17493
|
+
if (typeof protocolFee === "number") {
|
|
17494
|
+
return AssetAmount2.fromChainAsset(asset, {
|
|
17495
|
+
amount: protocolFee
|
|
17496
|
+
});
|
|
17497
|
+
}
|
|
17498
|
+
const config = protocolFee?.build({
|
|
17499
|
+
address,
|
|
17500
|
+
asset,
|
|
17501
|
+
balance,
|
|
17502
|
+
destination,
|
|
17503
|
+
source
|
|
17504
|
+
});
|
|
17505
|
+
if (ContractConfig2.is(config) && EvmChain2.is(source)) {
|
|
17506
|
+
const evm = EvmService3.create(source);
|
|
17507
|
+
const amount = await evm.read(config);
|
|
17508
|
+
if (typeof amount !== "bigint") {
|
|
17509
|
+
throw new Error(
|
|
17510
|
+
`Error getting bridge fee: expected bigint from contract call, but received ${typeof amount}. `
|
|
17511
|
+
);
|
|
17512
|
+
}
|
|
17513
|
+
return AssetAmount2.fromChainAsset(asset, {
|
|
17514
|
+
amount
|
|
17515
|
+
});
|
|
17516
|
+
}
|
|
17517
|
+
if (SubstrateQueryConfig.is(config) && EvmParachain3.isAnyParachain(source)) {
|
|
17518
|
+
const polkadot = await PolkadotService2.create(source);
|
|
17519
|
+
const amount = await polkadot.query(config);
|
|
17520
|
+
return AssetAmount2.fromChainAsset(asset, {
|
|
17521
|
+
amount
|
|
17522
|
+
});
|
|
17523
|
+
}
|
|
17524
|
+
return AssetAmount2.fromChainAsset(source.getChainAsset(asset), {
|
|
17525
|
+
amount: 0n
|
|
17526
|
+
});
|
|
17527
|
+
}
|
|
17285
17528
|
|
|
17286
17529
|
// src/getTransferData/getTransferData.ts
|
|
17287
17530
|
async function getTransferData({
|
|
@@ -17310,7 +17553,7 @@ async function getTransferData({
|
|
|
17310
17553
|
destinationFee,
|
|
17311
17554
|
sourceAddress
|
|
17312
17555
|
});
|
|
17313
|
-
const
|
|
17556
|
+
const bridgeChainData = await getBridgeChainData({
|
|
17314
17557
|
route,
|
|
17315
17558
|
sourceAddress,
|
|
17316
17559
|
destinationAddress
|
|
@@ -17322,14 +17565,14 @@ async function getTransferData({
|
|
|
17322
17565
|
const bigAmount = Big2(
|
|
17323
17566
|
toBigInt3(amount, sourceData.balance.decimals).toString()
|
|
17324
17567
|
);
|
|
17325
|
-
const fee =
|
|
17568
|
+
const fee = getBridgeChainFeeValueOnSource({
|
|
17326
17569
|
destinationData,
|
|
17327
|
-
|
|
17570
|
+
bridgeChainData,
|
|
17328
17571
|
sourceData
|
|
17329
17572
|
});
|
|
17330
17573
|
const result = bigAmount.minus(
|
|
17331
17574
|
isSameAssetPayingDestinationFee ? destinationFee.toBig() : Big2(0)
|
|
17332
|
-
).minus(fee).minus(sourceData.
|
|
17575
|
+
).minus(fee).minus(sourceData.otherFees?.relayer?.toBig() || Big2(0));
|
|
17333
17576
|
return sourceData.balance.copyWith({
|
|
17334
17577
|
amount: result.lt(0) ? 0n : BigInt(result.toFixed())
|
|
17335
17578
|
});
|
|
@@ -17338,10 +17581,10 @@ async function getTransferData({
|
|
|
17338
17581
|
max: sourceData.max,
|
|
17339
17582
|
min: getMrlMin({
|
|
17340
17583
|
destinationData,
|
|
17341
|
-
|
|
17584
|
+
bridgeChainData,
|
|
17342
17585
|
sourceData
|
|
17343
17586
|
}),
|
|
17344
|
-
|
|
17587
|
+
bridgeChain: bridgeChainData,
|
|
17345
17588
|
source: sourceData,
|
|
17346
17589
|
async transfer({
|
|
17347
17590
|
amount,
|
|
@@ -17364,6 +17607,7 @@ async function getTransferData({
|
|
|
17364
17607
|
);
|
|
17365
17608
|
const transfer = await buildTransfer({
|
|
17366
17609
|
asset,
|
|
17610
|
+
protocolFee: sourceData.otherFees?.protocol,
|
|
17367
17611
|
destinationAddress,
|
|
17368
17612
|
feeAsset,
|
|
17369
17613
|
isAutomatic: isAutomatic2,
|
|
@@ -17371,19 +17615,19 @@ async function getTransferData({
|
|
|
17371
17615
|
sendOnlyRemoteExecution,
|
|
17372
17616
|
sourceAddress
|
|
17373
17617
|
});
|
|
17374
|
-
if (
|
|
17618
|
+
if (ContractConfig3.is(transfer) && (EvmChain3.is(source) || EvmParachain4.is(source))) {
|
|
17375
17619
|
if (!evmSigner) {
|
|
17376
17620
|
throw new Error("EVM Signer must be provided");
|
|
17377
17621
|
}
|
|
17378
|
-
const evm =
|
|
17622
|
+
const evm = EvmService4.create(source);
|
|
17379
17623
|
const hash = await evm.transfer(evmSigner, transfer);
|
|
17380
17624
|
return [hash];
|
|
17381
17625
|
}
|
|
17382
|
-
if (ExtrinsicConfig.is(transfer) &&
|
|
17626
|
+
if (ExtrinsicConfig.is(transfer) && EvmParachain4.isAnyParachain(source)) {
|
|
17383
17627
|
if (!polkadotSigner) {
|
|
17384
17628
|
throw new Error("Polkadot signer must be provided");
|
|
17385
17629
|
}
|
|
17386
|
-
const polkadot = await
|
|
17630
|
+
const polkadot = await PolkadotService3.create(source);
|
|
17387
17631
|
const hash = await polkadot.transfer(
|
|
17388
17632
|
sourceAddress,
|
|
17389
17633
|
transfer,
|
|
@@ -17392,13 +17636,21 @@ async function getTransferData({
|
|
|
17392
17636
|
);
|
|
17393
17637
|
return [hash];
|
|
17394
17638
|
}
|
|
17395
|
-
if (WormholeConfig2.is(transfer) && (
|
|
17639
|
+
if (WormholeConfig2.is(transfer) && (EvmChain3.is(source) || EvmParachain4.is(source))) {
|
|
17396
17640
|
if (!evmSigner) {
|
|
17397
17641
|
throw new Error("EVM Signer must be provided");
|
|
17398
17642
|
}
|
|
17399
17643
|
const wh = WormholeService.create(source);
|
|
17400
17644
|
return wh.transfer(evmSigner, transfer);
|
|
17401
17645
|
}
|
|
17646
|
+
if (SnowbridgeConfig2.is(transfer) && (EvmChain3.is(source) || EvmParachain4.is(source))) {
|
|
17647
|
+
if (!evmSigner) {
|
|
17648
|
+
throw new Error("EVM Signer must be provided");
|
|
17649
|
+
}
|
|
17650
|
+
const snowbridge = SnowbridgeService.create(source);
|
|
17651
|
+
const hash = await snowbridge.transfer(evmSigner, transfer);
|
|
17652
|
+
return [hash];
|
|
17653
|
+
}
|
|
17402
17654
|
throw new Error("Either contract or extrinsic must be provided");
|
|
17403
17655
|
}
|
|
17404
17656
|
};
|