From 64f32e535d512c143c471c69795bfc9a25f12181 Mon Sep 17 00:00:00 2001 From: Mario J Maurello Date: Tue, 1 Oct 2024 20:00:21 +0200 Subject: [PATCH 1/6] add moonbase to fantom routes and fix configuration accordingly to consider moonChain as source --- .../providers/wormhole/wormhole/wormhole.ts | 17 +++-- packages/config/src/mrl-configs/index.ts | 6 +- .../config/src/mrl-configs/moonbaseAlpha.ts | 72 +++++++++++++++++++ .../src/getTransferData/getMoonChainData.ts | 3 +- .../mrl/src/getTransferData/getSourceData.ts | 27 ++++--- 5 files changed, 106 insertions(+), 19 deletions(-) create mode 100644 packages/config/src/mrl-configs/moonbaseAlpha.ts diff --git a/packages/builder/src/mrl/providers/wormhole/wormhole/wormhole.ts b/packages/builder/src/mrl/providers/wormhole/wormhole/wormhole.ts index ca156dd9..72a17960 100644 --- a/packages/builder/src/mrl/providers/wormhole/wormhole/wormhole.ts +++ b/packages/builder/src/mrl/providers/wormhole/wormhole/wormhole.ts @@ -26,7 +26,8 @@ export function wormhole() { sourceAddress, }) => { const isNativeAsset = asset.isSame(source.nativeAsset); - const isDestinationMoonChain = destination.isEqual(moonChain); + const isSourceOrDestinationMoonChain = + destination.isEqual(moonChain) || source.isEqual(moonChain); const tokenAddress = isNativeAsset ? 'native' : asset.address; if (!tokenAddress) { @@ -35,15 +36,17 @@ export function wormhole() { const wh = wormholeFactory(source); const whSource = wh.getChain(source.getWormholeName()); - const whMoonChain = wh.getChain(moonChain.getWormholeName()); + const whDestination = wh.getChain(destination.getWormholeName()); const whAsset = Wormhole.tokenId(whSource.chain, tokenAddress); const whSourceAddress = Wormhole.chainAddress( whSource.chain, sourceAddress, ); - const whMoonChainAddress = Wormhole.chainAddress( - whMoonChain.chain, - isDestinationMoonChain ? destinationAddress : GMP_CONTRACT_ADDRESS, + const whDestinationAddress = Wormhole.chainAddress( + whDestination.chain, + isSourceOrDestinationMoonChain + ? destinationAddress + : GMP_CONTRACT_ADDRESS, ); return new WormholeConfig({ @@ -51,9 +54,9 @@ export function wormhole() { whAsset, asset.amount, whSourceAddress, - whMoonChainAddress, + whDestinationAddress, isAutomatic, - isDestinationMoonChain + isSourceOrDestinationMoonChain ? undefined : getPayload({ destination, destinationAddress, moonApi }), ], diff --git a/packages/config/src/mrl-configs/index.ts b/packages/config/src/mrl-configs/index.ts index b7f3a12b..11adfcaf 100644 --- a/packages/config/src/mrl-configs/index.ts +++ b/packages/config/src/mrl-configs/index.ts @@ -1,7 +1,11 @@ import type { ChainRoutes } from '../types/ChainRoutes'; import { fantomTestnetRoutes } from './fantomTestnet'; +import { moonbaseAlphaRoutes } from './moonbaseAlpha'; -export const mrlRoutesList: ChainRoutes[] = [fantomTestnetRoutes]; +export const mrlRoutesList: ChainRoutes[] = [ + fantomTestnetRoutes, + moonbaseAlphaRoutes, +]; export const mrlRoutesMap = new Map( mrlRoutesList.map((config) => [config.chain.key, config]), diff --git a/packages/config/src/mrl-configs/moonbaseAlpha.ts b/packages/config/src/mrl-configs/moonbaseAlpha.ts new file mode 100644 index 00000000..ac238499 --- /dev/null +++ b/packages/config/src/mrl-configs/moonbaseAlpha.ts @@ -0,0 +1,72 @@ +import { BalanceBuilder, MrlBuilder } from '@moonbeam-network/xcm-builder'; +import { dev, ftm, ftmwh } from '../assets'; +import { fantomTestnet, moonbaseAlpha } from '../chains'; +import { ChainRoutes } from '../types/ChainRoutes'; + +export const moonbaseAlphaRoutes = new ChainRoutes({ + chain: moonbaseAlpha, + routes: [ + { + source: { + asset: ftmwh, + balance: BalanceBuilder().evm().erc20(), + destinationFee: { + asset: ftmwh, + balance: BalanceBuilder().evm().erc20(), + }, + }, + destination: { + asset: ftm, + chain: fantomTestnet, + balance: BalanceBuilder().evm().native(), + fee: { + asset: ftm, + amount: 0, + }, + }, + mrl: { + isAutomatic: true, + transfer: MrlBuilder().wormhole().wormhole().tokenTransfer(), + moonChain: { + asset: ftmwh, + fee: { + asset: dev, + amount: 0.1, // TODO not really, it would be the source fee as source is moonChain + balance: BalanceBuilder().substrate().system().account(), + }, + }, + }, + }, + { + source: { + asset: dev, + balance: BalanceBuilder().substrate().system().account(), + destinationFee: { + asset: dev, + balance: BalanceBuilder().substrate().system().account(), + }, + }, + destination: { + asset: dev, + chain: fantomTestnet, + balance: BalanceBuilder().evm().erc20(), + fee: { + asset: dev, + amount: 0, + }, + }, + mrl: { + isAutomatic: true, + transfer: MrlBuilder().wormhole().wormhole().tokenTransfer(), + moonChain: { + asset: dev, + fee: { + asset: dev, + amount: 0.1, + balance: BalanceBuilder().substrate().system().account(), + }, + }, + }, + }, + ], +}); diff --git a/packages/mrl/src/getTransferData/getMoonChainData.ts b/packages/mrl/src/getTransferData/getMoonChainData.ts index 24d2b6cb..fb4f7270 100644 --- a/packages/mrl/src/getTransferData/getMoonChainData.ts +++ b/packages/mrl/src/getTransferData/getMoonChainData.ts @@ -26,6 +26,7 @@ export async function getMoonChainData({ const moonChain = getMoonChain(route.source.chain); const asset = moonChain.getChainAsset(route.mrl.moonChain.asset); + const feeAsset = moonChain.getChainAsset(route.mrl.moonChain.fee.asset); const isDestinationMoonChain = route.destination.chain.isEqual(moonChain); if (isDestinationMoonChain) { @@ -37,7 +38,7 @@ export async function getMoonChainData({ } const fee = await getDestinationFee({ - asset, + asset: feeAsset, chain: moonChain, fee: route.mrl.moonChain.fee.amount, }); diff --git a/packages/mrl/src/getTransferData/getSourceData.ts b/packages/mrl/src/getTransferData/getSourceData.ts index 4c7f4160..9e475de1 100644 --- a/packages/mrl/src/getTransferData/getSourceData.ts +++ b/packages/mrl/src/getTransferData/getSourceData.ts @@ -3,7 +3,11 @@ import { type ExtrinsicConfig, WormholeConfig, } from '@moonbeam-network/xcm-builder'; -import type { AssetRoute, FeeConfig } from '@moonbeam-network/xcm-config'; +import { + type AssetRoute, + type FeeConfig, + dev, +} from '@moonbeam-network/xcm-config'; import { type SourceChainTransferData, getAssetMin, @@ -14,12 +18,12 @@ import { getExtrinsicFee, getMax, } from '@moonbeam-network/xcm-sdk'; -import type { - AnyChain, - AnyParachain, +import { + type AnyChain, + type AnyParachain, AssetAmount, - EvmChain, - EvmParachain, + type EvmChain, + type EvmParachain, } from '@moonbeam-network/xcm-types'; import { WormholeService } from '../services/wormhole'; import { buildTransfer } from './getTransferData.utils'; @@ -137,11 +141,14 @@ export async function getFee({ const wh = WormholeService.create(chain as EvmChain | EvmParachain); const fee = await wh.getFee(transfer); - console.log('fee', fee); + // TODO technically this is not the fee on source chain, it's relayer fee + // source fee should be the fee paid to send the message in polkadot to eth or to sign the transaction in eth to polkadot + console.log('fee in getFee', fee); - // TODO: finish - // biome-ignore lint/suspicious/noExplicitAny: - return {} as any; + return AssetAmount.fromChainAsset(chain.getChainAsset(dev), { + // TODO not dev + amount: fee.relayFee?.amount || 0n, + }); } if (ContractConfig.is(transfer)) { From 6b2ce5d147f246d642eaa6557fe0b25a2082fa47 Mon Sep 17 00:00:00 2001 From: Mario J Maurello Date: Wed, 2 Oct 2024 19:52:10 +0200 Subject: [PATCH 2/6] add peaqAlphanet routes --- .../extrinsic/polkadotXcm/polkadotXcm.ts | 45 +++++------ packages/config/src/mrl-configs/index.ts | 2 + .../config/src/mrl-configs/peaqAlphanet.ts | 76 +++++++++++++++++++ 3 files changed, 97 insertions(+), 26 deletions(-) create mode 100644 packages/config/src/mrl-configs/peaqAlphanet.ts diff --git a/packages/builder/src/mrl/providers/wormhole/extrinsic/polkadotXcm/polkadotXcm.ts b/packages/builder/src/mrl/providers/wormhole/extrinsic/polkadotXcm/polkadotXcm.ts index c1945ad0..f4c34a1e 100644 --- a/packages/builder/src/mrl/providers/wormhole/extrinsic/polkadotXcm/polkadotXcm.ts +++ b/packages/builder/src/mrl/providers/wormhole/extrinsic/polkadotXcm/polkadotXcm.ts @@ -1,8 +1,4 @@ -import { - type AnyParachain, - AssetAmount, - EvmParachain, -} from '@moonbeam-network/xcm-types'; +import { type AnyParachain, AssetAmount } from '@moonbeam-network/xcm-types'; import { getMultilocationDerivedAddresses } from '@moonbeam-network/xcm-utils'; import { ExtrinsicBuilder } from '../../../../../extrinsic/ExtrinsicBuilder'; import { ExtrinsicConfig } from '../../../../../types/substrate/ExtrinsicConfig'; @@ -23,6 +19,7 @@ export function polkadotXcm() { fee, moonAsset, moonChain, + moonApi, source, sourceAddress, sourceApi, @@ -32,12 +29,6 @@ export function polkadotXcm() { throw new Error('Destination chain does not have a wormhole name'); } - if (!EvmParachain.isAnyParachain(destination)) { - throw new Error( - `Destination ${destination.name} is not a Parachain or EvmParachain`, - ); - } - if (!transact) { throw new Error('Transact params are required'); } @@ -46,16 +37,23 @@ export function polkadotXcm() { throw new Error('Source API needs to be defined'); } + const { address20: computedOriginAccount } = + getMultilocationDerivedAddresses({ + address: sourceAddress, + paraId: moonChain.parachainId, + isParents: true, + }); + const { transfer } = sourceApi.tx.xTokens; const builder = ExtrinsicBuilder().xTokens().transfer(); const assetTransferTx = transfer( - builder + ...builder .build({ asset, - destination, - destinationAddress, - destinationApi, + destination: moonChain, + destinationAddress: computedOriginAccount, + destinationApi: moonApi, fee, // TODO: This is a workaround. xTokens.transfer doesn't need source chain but the interfaces requires it. // In this case we know that a source chain is not a Parachain. @@ -71,14 +69,14 @@ export function polkadotXcm() { * Also we need to move fees to AssetRoute. */ const feeAssetTransferTx = transfer( - builder + ...builder .build({ asset: AssetAmount.fromChainAsset(moonAsset, { amount: CROSS_CHAIN_FEE + BUY_EXECUTION_FEE, }), - destination, + destination: moonChain, destinationAddress, - destinationApi, + destinationApi: moonApi, fee, source: source as AnyParachain, sourceAddress, @@ -87,12 +85,6 @@ export function polkadotXcm() { .getArgs(transfer), ); - const { address20 } = getMultilocationDerivedAddresses({ - address: sourceAddress, - paraId: moonChain.parachainId, - isParents: true, - }); - const send = sourceApi.tx.polkadotXcm.send( { V3: { @@ -158,7 +150,7 @@ export function polkadotXcm() { beneficiary: { parents: 0, interior: { - X1: { AccountKey20: { key: address20 } }, + X1: { AccountKey20: { key: computedOriginAccount } }, }, }, }, @@ -169,10 +161,11 @@ export function polkadotXcm() { }, ); + // TODO add here ability to only send the remote execution (only `send`) return new ExtrinsicConfig({ module: 'utility', func: 'batchAll', - getArgs: () => [assetTransferTx, feeAssetTransferTx, send], + getArgs: () => [[assetTransferTx, feeAssetTransferTx, send]], }); }, }), diff --git a/packages/config/src/mrl-configs/index.ts b/packages/config/src/mrl-configs/index.ts index 11adfcaf..4636267a 100644 --- a/packages/config/src/mrl-configs/index.ts +++ b/packages/config/src/mrl-configs/index.ts @@ -1,10 +1,12 @@ import type { ChainRoutes } from '../types/ChainRoutes'; import { fantomTestnetRoutes } from './fantomTestnet'; import { moonbaseAlphaRoutes } from './moonbaseAlpha'; +import { peaqAlphanetRoutes } from './peaqAlphanet'; export const mrlRoutesList: ChainRoutes[] = [ fantomTestnetRoutes, moonbaseAlphaRoutes, + peaqAlphanetRoutes, ]; export const mrlRoutesMap = new Map( diff --git a/packages/config/src/mrl-configs/peaqAlphanet.ts b/packages/config/src/mrl-configs/peaqAlphanet.ts new file mode 100644 index 00000000..4328fd21 --- /dev/null +++ b/packages/config/src/mrl-configs/peaqAlphanet.ts @@ -0,0 +1,76 @@ +import { BalanceBuilder, MrlBuilder } from '@moonbeam-network/xcm-builder'; +import { agng, dev, ftm, ftmwh } from '../assets'; +import { fantomTestnet, peaqAlphanet } from '../chains'; +import { ChainRoutes } from '../types/ChainRoutes'; + +export const peaqAlphanetRoutes = new ChainRoutes({ + chain: peaqAlphanet, + routes: [ + { + source: { + asset: ftmwh, + balance: BalanceBuilder().substrate().assets().account(), + destinationFee: { + asset: ftmwh, + balance: BalanceBuilder().substrate().assets().account(), + }, + fee: { + asset: agng, + balance: BalanceBuilder().substrate().system().account(), + }, + }, + destination: { + asset: ftm, + chain: fantomTestnet, + balance: BalanceBuilder().evm().native(), + fee: { + asset: ftm, + amount: 0, + }, + }, + mrl: { + isAutomatic: true, + transfer: MrlBuilder().wormhole().extrinsic().polkadotXcm().send(), + moonChain: { + asset: ftmwh, + fee: { + asset: dev, + amount: 0.1, + balance: BalanceBuilder().substrate().system().account(), + }, + }, + }, + }, + { + source: { + asset: agng, + balance: BalanceBuilder().substrate().system().account(), + destinationFee: { + asset: ftmwh, + balance: BalanceBuilder().substrate().assets().account(), + }, + }, + destination: { + asset: ftm, + chain: fantomTestnet, + balance: BalanceBuilder().evm().native(), + fee: { + asset: ftm, + amount: 0, + }, + }, + mrl: { + isAutomatic: true, + transfer: MrlBuilder().wormhole().extrinsic().polkadotXcm().send(), + moonChain: { + asset: ftmwh, + fee: { + asset: dev, + amount: 0.1, + balance: BalanceBuilder().substrate().system().account(), + }, + }, + }, + }, + ], +}); From 448fdd5df7856e080355d8e8e70e40593d06a607 Mon Sep 17 00:00:00 2001 From: Mario J Maurello Date: Thu, 3 Oct 2024 10:51:41 +0200 Subject: [PATCH 3/6] fix moonAsset retrieval --- .../wormhole/extrinsic/polkadotXcm/polkadotXcm.ts | 11 +++++++---- .../mrl/src/getTransferData/getTransferData.utils.ts | 5 ++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/builder/src/mrl/providers/wormhole/extrinsic/polkadotXcm/polkadotXcm.ts b/packages/builder/src/mrl/providers/wormhole/extrinsic/polkadotXcm/polkadotXcm.ts index f4c34a1e..a7e7cee7 100644 --- a/packages/builder/src/mrl/providers/wormhole/extrinsic/polkadotXcm/polkadotXcm.ts +++ b/packages/builder/src/mrl/providers/wormhole/extrinsic/polkadotXcm/polkadotXcm.ts @@ -71,11 +71,14 @@ export function polkadotXcm() { const feeAssetTransferTx = transfer( ...builder .build({ - asset: AssetAmount.fromChainAsset(moonAsset, { - amount: CROSS_CHAIN_FEE + BUY_EXECUTION_FEE, - }), + asset: AssetAmount.fromChainAsset( + source.getChainAsset(moonAsset), + { + amount: CROSS_CHAIN_FEE + BUY_EXECUTION_FEE, + }, + ), destination: moonChain, - destinationAddress, + destinationAddress: computedOriginAccount, destinationApi: moonApi, fee, source: source as AnyParachain, diff --git a/packages/mrl/src/getTransferData/getTransferData.utils.ts b/packages/mrl/src/getTransferData/getTransferData.utils.ts index a4568260..a76bed5b 100644 --- a/packages/mrl/src/getTransferData/getTransferData.utils.ts +++ b/packages/mrl/src/getTransferData/getTransferData.utils.ts @@ -36,7 +36,7 @@ import { import type { MoonChainTransferData } from '../mrl.interfaces'; const MOON_CHAIN_AUTOMATIC_GAS_ESTIMATION = { - [moonbeam.key]: 657226n, + [moonbeam.key]: 1273110n, [moonbaseAlpha.key]: 1271922n, }; @@ -58,7 +58,6 @@ export function getMoonChainFeeValueOnSource({ const isSameAssetPayingMoonChainFee = sourceData.balance.isSame( moonChainData.fee, ); - return !isDestinationMoonChain && isSourceParachain && isSameAssetPayingMoonChainFee @@ -125,7 +124,7 @@ export async function buildTransfer({ destinationAddress, destinationApi, fee: destinationFee, - isAutomatic: route.mrl.isAutomatic, + isAutomatic: route.mrl.isAutomatic, // TODO moonApi, moonAsset: moonChain.nativeAsset, moonChain, From 01122470b5a985d7515d648391feedee40818c5a Mon Sep 17 00:00:00 2001 From: Mario J Maurello Date: Thu, 3 Oct 2024 10:56:29 +0200 Subject: [PATCH 4/6] fix asset in relayer fee --- packages/mrl/src/getTransferData/getSourceData.ts | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/packages/mrl/src/getTransferData/getSourceData.ts b/packages/mrl/src/getTransferData/getSourceData.ts index 9e475de1..e2dc3bfc 100644 --- a/packages/mrl/src/getTransferData/getSourceData.ts +++ b/packages/mrl/src/getTransferData/getSourceData.ts @@ -3,11 +3,7 @@ import { type ExtrinsicConfig, WormholeConfig, } from '@moonbeam-network/xcm-builder'; -import { - type AssetRoute, - type FeeConfig, - dev, -} from '@moonbeam-network/xcm-config'; +import type { AssetRoute, FeeConfig } from '@moonbeam-network/xcm-config'; import { type SourceChainTransferData, getAssetMin, @@ -141,12 +137,11 @@ export async function getFee({ const wh = WormholeService.create(chain as EvmChain | EvmParachain); const fee = await wh.getFee(transfer); + console.log('fee in getFee.WormholeConfig', fee); + // TODO technically this is not the fee on source chain, it's relayer fee // source fee should be the fee paid to send the message in polkadot to eth or to sign the transaction in eth to polkadot - console.log('fee in getFee', fee); - - return AssetAmount.fromChainAsset(chain.getChainAsset(dev), { - // TODO not dev + return AssetAmount.fromChainAsset(chain.getChainAsset(balance), { amount: fee.relayFee?.amount || 0n, }); } From 309683bb7c444a25bc70dffc7672be9cebb9b35a Mon Sep 17 00:00:00 2001 From: Mario J Maurello Date: Thu, 3 Oct 2024 11:41:49 +0200 Subject: [PATCH 5/6] remove comment --- packages/mrl/src/getTransferData/getMoonChainData.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/mrl/src/getTransferData/getMoonChainData.ts b/packages/mrl/src/getTransferData/getMoonChainData.ts index 5cbfb507..0bcc37cc 100644 --- a/packages/mrl/src/getTransferData/getMoonChainData.ts +++ b/packages/mrl/src/getTransferData/getMoonChainData.ts @@ -26,7 +26,6 @@ export async function getMoonChainData({ const moonChain = getMoonChain(route.source.chain); const asset = moonChain.getChainAsset(route.mrl.moonChain.asset); - // const feeAsset = moonChain.getChainAsset(route.mrl.moonChain.fee.asset); const isDestinationMoonChain = route.destination.chain.isEqual(moonChain); if (isDestinationMoonChain) { From fc4ae33d7da153bf6719e6f3431757ec636fa5d7 Mon Sep 17 00:00:00 2001 From: Mario J Maurello Date: Thu, 3 Oct 2024 12:34:21 +0200 Subject: [PATCH 6/6] udpate snap --- .../polkadotXcm/__snapshots__/polkadotXcm.test.ts.snap | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/builder/src/mrl/providers/wormhole/extrinsic/polkadotXcm/__snapshots__/polkadotXcm.test.ts.snap b/packages/builder/src/mrl/providers/wormhole/extrinsic/polkadotXcm/__snapshots__/polkadotXcm.test.ts.snap index 0b1f33a1..acd4285e 100644 --- a/packages/builder/src/mrl/providers/wormhole/extrinsic/polkadotXcm/__snapshots__/polkadotXcm.test.ts.snap +++ b/packages/builder/src/mrl/providers/wormhole/extrinsic/polkadotXcm/__snapshots__/polkadotXcm.test.ts.snap @@ -10,9 +10,11 @@ ExtrinsicConfig { exports[`polkadotXcm > send > should get correct arguments 1`] = ` [ - "xTokens.transfer => RESULT", - "xTokens.transfer => RESULT", - "polkadotXcm.send => RESULT", + [ + "xTokens.transfer => RESULT", + "xTokens.transfer => RESULT", + "polkadotXcm.send => RESULT", + ], ] `;