diff --git a/packages/mrl/src/getTransferData/getSourceData.ts b/packages/mrl/src/getTransferData/getSourceData.ts index 9c95a682..cee25343 100644 --- a/packages/mrl/src/getTransferData/getSourceData.ts +++ b/packages/mrl/src/getTransferData/getSourceData.ts @@ -1,17 +1,13 @@ /* eslint-disable @typescript-eslint/no-use-before-define */ +import { AssetRoute, FeeConfig } from '@moonbeam-network/xcm-config'; import { - AssetRoute, - FeeConfig, - getMoonChain, -} from '@moonbeam-network/xcm-config'; -import { + getAssetMin, getBalance, getContractFee, getDestinationFeeBalance, getExistentialDeposit, getExtrinsicFee, getMax, - getMin, SourceChainTransferData, } from '@moonbeam-network/xcm-sdk'; import { @@ -21,14 +17,12 @@ import { EvmChain, EvmParachain, } from '@moonbeam-network/xcm-types'; -import { getPolkadotApi } from '@moonbeam-network/xcm-utils'; import { ContractConfig, ExtrinsicConfig, - MrlBuilderParams, WormholeConfig, } from '@moonbeam-network/xcm-builder'; -import { getTransact } from './getTransferData.utils'; +import { buildTransfer } from './getTransferData.utils'; export interface GetSourceDataParams { route: AssetRoute; @@ -78,36 +72,18 @@ export async function getSourceData({ }); const existentialDeposit = await getExistentialDeposit(destination); - const min = await getMin({ asset, builder: route.source.min, chain: source }); - - const moonChain = getMoonChain(source); - const [sourceApi, destinationApi, moonApi] = await Promise.all([ - EvmParachain.isAnyParachain(source) ? getPolkadotApi(source.ws) : undefined, - EvmParachain.isAnyParachain(destination) - ? getPolkadotApi(destination.ws) - : undefined, - getPolkadotApi(moonChain.ws), - ]); + const min = await getAssetMin({ + asset, + builder: route.source.min, + chain: source, + }); - const params: MrlBuilderParams = { + const transfer = await buildTransfer({ asset: balance, - destination: route.destination.chain, destinationAddress, - destinationApi, - fee: destinationFee, - isAutomatic: route.mrl.isAutomatic, - moonApi, - moonAsset: moonChain.nativeAsset, - moonChain, - source, + destinationFee, + route, sourceAddress, - sourceApi, - }; - const transfer = route.mrl.transfer.build({ - ...params, - transact: EvmParachain.isAnyParachain(source) - ? await getTransact(params) - : undefined, }); const fee = await getFee({ diff --git a/packages/mrl/src/getTransferData/getTransferData.ts b/packages/mrl/src/getTransferData/getTransferData.ts index ced08ef7..42c55add 100644 --- a/packages/mrl/src/getTransferData/getTransferData.ts +++ b/packages/mrl/src/getTransferData/getTransferData.ts @@ -1,14 +1,23 @@ import { AssetRoute } from '@moonbeam-network/xcm-config'; import { convertToChainDecimals, + EvmService, getDestinationData, + getMin, + PolkadotService, Signers, } from '@moonbeam-network/xcm-sdk'; import { toBigInt } from '@moonbeam-network/xcm-utils'; -import { AssetAmount } from '@moonbeam-network/xcm-types'; +import { + AssetAmount, + EvmChain, + EvmParachain, +} from '@moonbeam-network/xcm-types'; import Big from 'big.js'; +import { ContractConfig, ExtrinsicConfig } from '@moonbeam-network/xcm-builder'; import { TransferData } from '../mrl.interfaces'; import { getSourceData } from './getSourceData'; +import { buildTransfer } from './getTransferData.utils'; export interface GetTransferDataParams { route: AssetRoute; @@ -69,58 +78,46 @@ export async function getTransferData({ { evmSigner, polkadotSigner }: Partial, ): Promise { const source = route.source.chain; - const destination = route.destination.chain; + const bigintAmount = toBigInt(amount, sourceData.balance.decimals); const asset = AssetAmount.fromChainAsset( route.source.chain.getChainAsset(route.asset), { amount: bigintAmount }, ); - const [sourcePolkadot, destinationPolkadot] = - await PolkadotService.createMulti([source, destination]); - const contract = route.contract?.build({ + const transfer = await buildTransfer({ asset, - destination, destinationAddress, - destinationApi: destinationPolkadot.api, - fee: destinationFee, - source, + destinationFee, + route, sourceAddress, - sourceApi: sourcePolkadot.api, - }); - const extrinsic = route.extrinsic?.build({ - asset, - destination, - destinationAddress, - destinationApi: destinationPolkadot.api, - fee: destinationFee, - source, - sourceAddress, - sourceApi: sourcePolkadot.api, }); - if (contract) { + if ( + ContractConfig.is(transfer) && + (EvmChain.is(source) || EvmParachain.is(source)) + ) { if (!evmSigner) { throw new Error('EVM Signer must be provided'); } - return ( - createContract(source, contract) as TransferContractInterface - ).transfer(evmSigner); + const evm = EvmService.create(source); + + return evm.transfer(evmSigner, transfer); } - if (extrinsic) { + if (ExtrinsicConfig.is(transfer) && EvmParachain.isAnyParachain(source)) { if (!polkadotSigner) { throw new Error('Polkadot signer must be provided'); } - return sourcePolkadot.transfer( - sourceAddress, - extrinsic, - polkadotSigner, - ); + const polkadot = await PolkadotService.create(source); + + return polkadot.transfer(sourceAddress, transfer, polkadotSigner); } + // TODO: Wormhole transfer! + throw new Error('Either contract or extrinsic must be provided'); }, }; diff --git a/packages/mrl/src/getTransferData/getTransferData.utils.ts b/packages/mrl/src/getTransferData/getTransferData.utils.ts index 8bcec1b8..16a56851 100644 --- a/packages/mrl/src/getTransferData/getTransferData.utils.ts +++ b/packages/mrl/src/getTransferData/getTransferData.utils.ts @@ -1,7 +1,15 @@ /* eslint-disable @typescript-eslint/no-use-before-define */ -import { moonbaseAlpha, moonbeam } from '@moonbeam-network/xcm-config'; -import { EvmParachain } from '@moonbeam-network/xcm-types'; -import { getMultilocationDerivedAddresses } from '@moonbeam-network/xcm-utils'; +import { + AssetRoute, + getMoonChain, + moonbaseAlpha, + moonbeam, +} from '@moonbeam-network/xcm-config'; +import { AssetAmount, EvmParachain } from '@moonbeam-network/xcm-types'; +import { + getMultilocationDerivedAddresses, + getPolkadotApi, +} from '@moonbeam-network/xcm-utils'; import { BATCH_CONTRACT_ABI, BATCH_CONTRACT_ADDRESS, @@ -20,6 +28,62 @@ const MOON_CHAIN_AUTOMATIC_GAS_ESTIMATION = { [moonbaseAlpha.key]: 1271922n, }; +export interface BuildTransferParams { + asset: AssetAmount; + destinationAddress: string; + destinationFee: AssetAmount; + route: AssetRoute; + sourceAddress: string; +} + +export async function buildTransfer({ + asset, + destinationAddress, + destinationFee, + route, + sourceAddress, +}: BuildTransferParams) { + if (!route.mrl) { + throw new Error( + `MrlConfigBuilder is not defined for source chain ${route.source.chain.name} and asset ${route.asset.originSymbol}`, + ); + } + + const source = route.source.chain; + const destination = route.destination.chain; + + const moonChain = getMoonChain(source); + const [sourceApi, destinationApi, moonApi] = await Promise.all([ + EvmParachain.isAnyParachain(source) ? getPolkadotApi(source.ws) : undefined, + EvmParachain.isAnyParachain(destination) + ? getPolkadotApi(destination.ws) + : undefined, + getPolkadotApi(moonChain.ws), + ]); + + const params: MrlBuilderParams = { + asset, + destination, + destinationAddress, + destinationApi, + fee: destinationFee, + isAutomatic: route.mrl.isAutomatic, + moonApi, + moonAsset: moonChain.nativeAsset, + moonChain, + source, + sourceAddress, + sourceApi, + }; + + return route.mrl.transfer.build({ + ...params, + transact: EvmParachain.isAnyParachain(source) + ? await getTransact(params) + : undefined, + }); +} + export async function getTransact(params: MrlBuilderParams): Promise { const { sourceAddress, source, moonChain } = params; const polkadot = await PolkadotService.create(moonChain);