@moonbeam-network/mrl 1.0.0-dev.264 → 1.0.0-dev.266
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.d.ts +12 -7
- package/build/index.mjs +369 -141
- 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,20 +17276,25 @@ async function getSourceData({
|
|
|
17105
17276
|
route,
|
|
17106
17277
|
sourceAddress
|
|
17107
17278
|
});
|
|
17108
|
-
const moonChainFeeBalance = await getMoonChainFeeBalance({
|
|
17109
|
-
balance,
|
|
17110
|
-
feeBalance,
|
|
17111
|
-
route,
|
|
17112
|
-
sourceAddress
|
|
17113
|
-
});
|
|
17114
17279
|
const existentialDeposit = await getExistentialDeposit(source);
|
|
17115
17280
|
const min = await getAssetMin({
|
|
17116
17281
|
asset,
|
|
17117
17282
|
builder: route.source.min,
|
|
17118
17283
|
chain: source
|
|
17119
17284
|
});
|
|
17285
|
+
const protocolFee = await getProtocolFee({
|
|
17286
|
+
source,
|
|
17287
|
+
destination,
|
|
17288
|
+
// For now, the fee asset is always the one used for the protocol fee
|
|
17289
|
+
// If it where to change, we need make protocolFee a FeeConfig in MrlSourceConfig
|
|
17290
|
+
asset: feeAsset,
|
|
17291
|
+
balance,
|
|
17292
|
+
protocolFee: route.source.protocolFee,
|
|
17293
|
+
address: destinationAddress
|
|
17294
|
+
});
|
|
17120
17295
|
const transfer = await buildTransfer({
|
|
17121
|
-
asset: balance,
|
|
17296
|
+
asset: balance.copyWith({ amount: balance.amount - protocolFee.amount }),
|
|
17297
|
+
protocolFee,
|
|
17122
17298
|
destinationAddress,
|
|
17123
17299
|
feeAsset: feeBalance,
|
|
17124
17300
|
isAutomatic,
|
|
@@ -17155,13 +17331,16 @@ async function getSourceData({
|
|
|
17155
17331
|
chain: source,
|
|
17156
17332
|
destinationFee,
|
|
17157
17333
|
destinationFeeBalance,
|
|
17158
|
-
|
|
17334
|
+
// bridgeChainFeeBalance,
|
|
17159
17335
|
existentialDeposit,
|
|
17160
17336
|
fee,
|
|
17161
17337
|
feeBalance,
|
|
17162
17338
|
max,
|
|
17163
17339
|
min,
|
|
17164
|
-
|
|
17340
|
+
otherFees: {
|
|
17341
|
+
protocol: protocolFee,
|
|
17342
|
+
relayer: relayerFee?.amount ? relayerFee : void 0
|
|
17343
|
+
}
|
|
17165
17344
|
};
|
|
17166
17345
|
}
|
|
17167
17346
|
async function getFee({
|
|
@@ -17178,17 +17357,31 @@ async function getFee({
|
|
|
17178
17357
|
amount: 0n
|
|
17179
17358
|
});
|
|
17180
17359
|
}
|
|
17181
|
-
if (
|
|
17182
|
-
|
|
17183
|
-
|
|
17184
|
-
|
|
17185
|
-
|
|
17186
|
-
|
|
17187
|
-
|
|
17188
|
-
feeBalance,
|
|
17189
|
-
feeConfig
|
|
17360
|
+
if (SnowbridgeConfig.is(transfer)) {
|
|
17361
|
+
const snowbridge = SnowbridgeService.create(
|
|
17362
|
+
chain2
|
|
17363
|
+
);
|
|
17364
|
+
const feeAmount = await snowbridge.getFee(sourceAddress, transfer);
|
|
17365
|
+
return AssetAmount2.fromChainAsset(chain2.getChainAsset(feeBalance), {
|
|
17366
|
+
amount: feeAmount
|
|
17190
17367
|
});
|
|
17191
17368
|
}
|
|
17369
|
+
if (ContractConfig2.is(transfer)) {
|
|
17370
|
+
try {
|
|
17371
|
+
return getContractFee({
|
|
17372
|
+
address: sourceAddress,
|
|
17373
|
+
balance,
|
|
17374
|
+
chain: chain2,
|
|
17375
|
+
contract: transfer,
|
|
17376
|
+
destinationFee,
|
|
17377
|
+
feeBalance,
|
|
17378
|
+
feeConfig
|
|
17379
|
+
});
|
|
17380
|
+
} catch (error) {
|
|
17381
|
+
console.error(error);
|
|
17382
|
+
return feeBalance.copyWith({ amount: 0n });
|
|
17383
|
+
}
|
|
17384
|
+
}
|
|
17192
17385
|
return getExtrinsicFee({
|
|
17193
17386
|
address: sourceAddress,
|
|
17194
17387
|
balance,
|
|
@@ -17208,19 +17401,25 @@ async function getRelayerFee({
|
|
|
17208
17401
|
sourceAddress,
|
|
17209
17402
|
transfer
|
|
17210
17403
|
}) {
|
|
17404
|
+
if (route.mrl.transfer.provider === "snowbridge" || SnowbridgeConfig.is(transfer)) {
|
|
17405
|
+
return void 0;
|
|
17406
|
+
}
|
|
17211
17407
|
if (WormholeConfig.is(transfer)) {
|
|
17212
17408
|
return getWormholeFee({ asset, chain: chain2, config: transfer });
|
|
17213
17409
|
}
|
|
17214
|
-
|
|
17215
|
-
|
|
17216
|
-
|
|
17217
|
-
|
|
17218
|
-
|
|
17219
|
-
|
|
17220
|
-
|
|
17221
|
-
|
|
17222
|
-
|
|
17223
|
-
|
|
17410
|
+
if (route.mrl.transfer.provider === "wormhole") {
|
|
17411
|
+
const builderParams = await getMrlBuilderParams({
|
|
17412
|
+
asset,
|
|
17413
|
+
destinationAddress,
|
|
17414
|
+
feeAsset,
|
|
17415
|
+
isAutomatic,
|
|
17416
|
+
route,
|
|
17417
|
+
sourceAddress
|
|
17418
|
+
});
|
|
17419
|
+
const wormholeConfig = MrlBuilder3().wormhole().wormhole().tokenTransfer().build(builderParams);
|
|
17420
|
+
return getWormholeFee({ asset, chain: chain2, config: wormholeConfig });
|
|
17421
|
+
}
|
|
17422
|
+
return;
|
|
17224
17423
|
}
|
|
17225
17424
|
async function getWormholeFee({
|
|
17226
17425
|
asset,
|
|
@@ -17237,31 +17436,47 @@ async function getWormholeFee({
|
|
|
17237
17436
|
}
|
|
17238
17437
|
return;
|
|
17239
17438
|
}
|
|
17240
|
-
async function
|
|
17439
|
+
async function getProtocolFee({
|
|
17440
|
+
address,
|
|
17441
|
+
asset,
|
|
17241
17442
|
balance,
|
|
17242
|
-
|
|
17243
|
-
|
|
17244
|
-
|
|
17443
|
+
protocolFee,
|
|
17444
|
+
destination,
|
|
17445
|
+
source
|
|
17245
17446
|
}) {
|
|
17246
|
-
if (
|
|
17247
|
-
return
|
|
17248
|
-
|
|
17249
|
-
|
|
17250
|
-
return balance;
|
|
17447
|
+
if (typeof protocolFee === "number") {
|
|
17448
|
+
return AssetAmount2.fromChainAsset(asset, {
|
|
17449
|
+
amount: protocolFee
|
|
17450
|
+
});
|
|
17251
17451
|
}
|
|
17252
|
-
|
|
17253
|
-
|
|
17452
|
+
const config = protocolFee?.build({
|
|
17453
|
+
address,
|
|
17454
|
+
asset,
|
|
17455
|
+
balance,
|
|
17456
|
+
destination,
|
|
17457
|
+
source
|
|
17458
|
+
});
|
|
17459
|
+
if (ContractConfig2.is(config) && EvmChain.is(source)) {
|
|
17460
|
+
const evm = EvmService3.create(source);
|
|
17461
|
+
const amount = await evm.read(config);
|
|
17462
|
+
if (typeof amount !== "bigint") {
|
|
17463
|
+
throw new Error(
|
|
17464
|
+
`Error getting bridge fee: expected bigint from contract call, but received ${typeof amount}. `
|
|
17465
|
+
);
|
|
17466
|
+
}
|
|
17467
|
+
return AssetAmount2.fromChainAsset(asset, {
|
|
17468
|
+
amount
|
|
17469
|
+
});
|
|
17254
17470
|
}
|
|
17255
|
-
if (
|
|
17256
|
-
|
|
17257
|
-
|
|
17258
|
-
|
|
17471
|
+
if (SubstrateQueryConfig.is(config) && EvmParachain3.isAnyParachain(source)) {
|
|
17472
|
+
const polkadot = await PolkadotService2.create(source);
|
|
17473
|
+
const amount = await polkadot.query(config);
|
|
17474
|
+
return AssetAmount2.fromChainAsset(asset, {
|
|
17475
|
+
amount
|
|
17476
|
+
});
|
|
17259
17477
|
}
|
|
17260
|
-
return
|
|
17261
|
-
|
|
17262
|
-
asset: route.source.chain.getChainAsset(route.source.moonChainFee.asset),
|
|
17263
|
-
builder: route.source.moonChainFee.balance,
|
|
17264
|
-
chain: route.source.chain
|
|
17478
|
+
return AssetAmount2.fromChainAsset(source.getChainAsset(asset), {
|
|
17479
|
+
amount: 0n
|
|
17265
17480
|
});
|
|
17266
17481
|
}
|
|
17267
17482
|
|
|
@@ -17281,10 +17496,12 @@ async function getTransferData({
|
|
|
17281
17496
|
route,
|
|
17282
17497
|
destinationAddress
|
|
17283
17498
|
});
|
|
17499
|
+
console.log("destinationData", destinationData);
|
|
17284
17500
|
const destinationFee = convertToChainDecimals2({
|
|
17285
17501
|
asset: destinationData.fee,
|
|
17286
17502
|
target: route.getDestinationFeeAssetOnSource()
|
|
17287
17503
|
});
|
|
17504
|
+
console.log("destinationFee", destinationFee);
|
|
17288
17505
|
const sourceData = await getSourceData({
|
|
17289
17506
|
isAutomatic: route.mrl.isAutomaticPossible && isAutomatic,
|
|
17290
17507
|
route,
|
|
@@ -17292,11 +17509,13 @@ async function getTransferData({
|
|
|
17292
17509
|
destinationFee,
|
|
17293
17510
|
sourceAddress
|
|
17294
17511
|
});
|
|
17295
|
-
|
|
17512
|
+
console.log("sourceData", sourceData);
|
|
17513
|
+
const bridgeChainData = await getBridgeChainData({
|
|
17296
17514
|
route,
|
|
17297
17515
|
sourceAddress,
|
|
17298
17516
|
destinationAddress
|
|
17299
17517
|
});
|
|
17518
|
+
console.log("bridgeChainData", bridgeChainData);
|
|
17300
17519
|
return {
|
|
17301
17520
|
destination: destinationData,
|
|
17302
17521
|
getEstimate(amount) {
|
|
@@ -17304,14 +17523,14 @@ async function getTransferData({
|
|
|
17304
17523
|
const bigAmount = Big2(
|
|
17305
17524
|
toBigInt3(amount, sourceData.balance.decimals).toString()
|
|
17306
17525
|
);
|
|
17307
|
-
const fee =
|
|
17526
|
+
const fee = getBridgeChainFeeValueOnSource({
|
|
17308
17527
|
destinationData,
|
|
17309
|
-
|
|
17528
|
+
bridgeChainData,
|
|
17310
17529
|
sourceData
|
|
17311
17530
|
});
|
|
17312
17531
|
const result = bigAmount.minus(
|
|
17313
17532
|
isSameAssetPayingDestinationFee ? destinationFee.toBig() : Big2(0)
|
|
17314
|
-
).minus(fee).minus(sourceData.
|
|
17533
|
+
).minus(fee).minus(sourceData.otherFees?.relayer?.toBig() || Big2(0));
|
|
17315
17534
|
return sourceData.balance.copyWith({
|
|
17316
17535
|
amount: result.lt(0) ? 0n : BigInt(result.toFixed())
|
|
17317
17536
|
});
|
|
@@ -17320,10 +17539,10 @@ async function getTransferData({
|
|
|
17320
17539
|
max: sourceData.max,
|
|
17321
17540
|
min: getMrlMin({
|
|
17322
17541
|
destinationData,
|
|
17323
|
-
|
|
17542
|
+
bridgeChainData,
|
|
17324
17543
|
sourceData
|
|
17325
17544
|
}),
|
|
17326
|
-
|
|
17545
|
+
bridgeChain: bridgeChainData,
|
|
17327
17546
|
source: sourceData,
|
|
17328
17547
|
async transfer({
|
|
17329
17548
|
amount,
|
|
@@ -17346,6 +17565,7 @@ async function getTransferData({
|
|
|
17346
17565
|
);
|
|
17347
17566
|
const transfer = await buildTransfer({
|
|
17348
17567
|
asset,
|
|
17568
|
+
protocolFee: sourceData.otherFees?.protocol,
|
|
17349
17569
|
destinationAddress,
|
|
17350
17570
|
feeAsset,
|
|
17351
17571
|
isAutomatic: isAutomatic2,
|
|
@@ -17353,19 +17573,19 @@ async function getTransferData({
|
|
|
17353
17573
|
sendOnlyRemoteExecution,
|
|
17354
17574
|
sourceAddress
|
|
17355
17575
|
});
|
|
17356
|
-
if (
|
|
17576
|
+
if (ContractConfig3.is(transfer) && (EvmChain2.is(source) || EvmParachain4.is(source))) {
|
|
17357
17577
|
if (!evmSigner) {
|
|
17358
17578
|
throw new Error("EVM Signer must be provided");
|
|
17359
17579
|
}
|
|
17360
|
-
const evm =
|
|
17580
|
+
const evm = EvmService4.create(source);
|
|
17361
17581
|
const hash = await evm.transfer(evmSigner, transfer);
|
|
17362
17582
|
return [hash];
|
|
17363
17583
|
}
|
|
17364
|
-
if (ExtrinsicConfig.is(transfer) &&
|
|
17584
|
+
if (ExtrinsicConfig.is(transfer) && EvmParachain4.isAnyParachain(source)) {
|
|
17365
17585
|
if (!polkadotSigner) {
|
|
17366
17586
|
throw new Error("Polkadot signer must be provided");
|
|
17367
17587
|
}
|
|
17368
|
-
const polkadot = await
|
|
17588
|
+
const polkadot = await PolkadotService3.create(source);
|
|
17369
17589
|
const hash = await polkadot.transfer(
|
|
17370
17590
|
sourceAddress,
|
|
17371
17591
|
transfer,
|
|
@@ -17374,13 +17594,21 @@ async function getTransferData({
|
|
|
17374
17594
|
);
|
|
17375
17595
|
return [hash];
|
|
17376
17596
|
}
|
|
17377
|
-
if (WormholeConfig2.is(transfer) && (
|
|
17597
|
+
if (WormholeConfig2.is(transfer) && (EvmChain2.is(source) || EvmParachain4.is(source))) {
|
|
17378
17598
|
if (!evmSigner) {
|
|
17379
17599
|
throw new Error("EVM Signer must be provided");
|
|
17380
17600
|
}
|
|
17381
17601
|
const wh = WormholeService.create(source);
|
|
17382
17602
|
return wh.transfer(evmSigner, transfer);
|
|
17383
17603
|
}
|
|
17604
|
+
if (SnowbridgeConfig2.is(transfer) && (EvmChain2.is(source) || EvmParachain4.is(source))) {
|
|
17605
|
+
if (!evmSigner) {
|
|
17606
|
+
throw new Error("EVM Signer must be provided");
|
|
17607
|
+
}
|
|
17608
|
+
const snowbridge = SnowbridgeService.create(source);
|
|
17609
|
+
const hash = await snowbridge.transfer(evmSigner, transfer);
|
|
17610
|
+
return [hash];
|
|
17611
|
+
}
|
|
17384
17612
|
throw new Error("Either contract or extrinsic must be provided");
|
|
17385
17613
|
}
|
|
17386
17614
|
};
|