Skip to content

Commit

Permalink
Splitet call in 2 builders
Browse files Browse the repository at this point in the history
  • Loading branch information
ekenigs committed Aug 6, 2024
1 parent 01a6ea6 commit 14b1d18
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 94 deletions.
8 changes: 8 additions & 0 deletions packages/builder/src/extrinsic/ExtrinsicBuilder.interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
EvmParachain,
} from '@moonbeam-network/xcm-types';
import type { ApiPromise } from '@polkadot/api';
import type { HexString } from '@polkadot/util/types';
import { ExtrinsicConfig } from './ExtrinsicConfig';

export interface ExtrinsicConfigBuilder<Params = ExtrinsicConfigBuilderPrams> {
Expand All @@ -31,6 +32,13 @@ export interface MrlExtrinsicConfigBuilderPrams
moonAsset: ChainAsset;
moonChain: EvmParachain;
moonGasLimit: bigint;
transact?: {
call: HexString;
txWeight: {
refTime: bigint;
proofSize: bigint;
};
};
}

export enum XcmVersion {
Expand Down
110 changes: 110 additions & 0 deletions packages/builder/src/extrinsic/mrl/wormhole/ethereumXcm/ethereumXcm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { convertAddressTo32Bytes } from '@moonbeam-network/xcm-utils';
import { Address, encodeFunctionData } from 'viem';
import { Wormhole } from '@wormhole-foundation/sdk-connect';
import { EvmPlatform } from '@wormhole-foundation/sdk-evm';
import { MrlExtrinsicConfigBuilder } from '../../../ExtrinsicBuilder.interfaces';
import { ExtrinsicConfig } from '../../../ExtrinsicConfig';
import { BATCH_CONTRACT_ABI } from './BatchContractAbi';
import { ERC20_ABI } from './Erc20Abi';
import { TOKEN_BRIDGE_ABI } from './TokenBridgeAbi';
import { TOKEN_BRIDGE_RELAYER_ABI } from './TokenBrigdeRelayerAbi';

export const BATCH_CONTRACT_ADDRESS =
'0x0000000000000000000000000000000000000808';

export function ethereumXcm() {
return {
transact: ({
isAutomatic,
}: {
isAutomatic: boolean;
}): MrlExtrinsicConfigBuilder => ({
build: ({
asset,
destination,
destinationAddress,
moonChain,
moonGasLimit,
}) => {
if (!destination.wh?.name) {
throw new Error('Destination chain does not have a wormhole name');
}

const wh = new Wormhole(moonChain.isTestChain ? 'Testnet' : 'Mainnet', [
EvmPlatform,
]);
const whDestinationChain = wh.getChain(destination.wh.name).config
.chainId;
const whContractAddress = (
isAutomatic
? wh.getChain('Moonbeam').config.contracts.tokenBridgeRelayer
: wh.getChain('Moonbeam').config.contracts.tokenBridge
) as Address;

const tokenAddressOnMoonChain = moonChain.getChainAsset(asset)
.address as Address;
const tokenAmountOnMoonChain = asset.convertDecimals(
moonChain.getChainAsset(asset).decimals,
).amount;

const approveTx = encodeFunctionData({
abi: ERC20_ABI,
functionName: 'approve',
args: [whContractAddress, tokenAmountOnMoonChain],
});
const transferTx = isAutomatic
? encodeFunctionData({
abi: TOKEN_BRIDGE_RELAYER_ABI,
functionName: 'transferTokensWithRelay',
args: [
tokenAddressOnMoonChain,
tokenAmountOnMoonChain,
0,
whDestinationChain,
destinationAddress,
0,
],
})
: encodeFunctionData({
abi: TOKEN_BRIDGE_ABI,
functionName: 'transferTokens',
args: [
tokenAddressOnMoonChain,
tokenAmountOnMoonChain,
whDestinationChain,
convertAddressTo32Bytes(destinationAddress) as Address,
0n,
0,
],
});
const batchAll = encodeFunctionData({
abi: BATCH_CONTRACT_ABI,
functionName: 'batchAll',
args: [
[tokenAddressOnMoonChain, whContractAddress],
[0n, 0n], // Value to send for each call
[approveTx, transferTx], // Call data for each call
[], // Gas limit for each call
],
});

return new ExtrinsicConfig({
module: 'ethereumXcm',
func: 'transact',
getArgs: () => [
{
V2: {
gasLimit: moonGasLimit,
action: {
Call: BATCH_CONTRACT_ADDRESS,
},
value: 0,
input: batchAll,
},
},
],
});
},
}),
};
}
105 changes: 11 additions & 94 deletions packages/builder/src/extrinsic/mrl/wormhole/xTokens/xTokens.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
import {
convertAddressTo32Bytes,
getMultilocationDerivedAddresses,
} from '@moonbeam-network/xcm-utils';
import { getMultilocationDerivedAddresses } from '@moonbeam-network/xcm-utils';
import { AssetAmount } from '@moonbeam-network/xcm-types';
import { Address, encodeFunctionData } from 'viem';
import { Chain, Wormhole } from '@wormhole-foundation/sdk-connect';
import { EvmPlatform } from '@wormhole-foundation/sdk-evm';
import { ExtrinsicBuilder } from '../../../ExtrinsicBuilder';
import { MrlExtrinsicConfigBuilder } from '../../../ExtrinsicBuilder.interfaces';
import { ExtrinsicConfig } from '../../../ExtrinsicConfig';
import { BATCH_CONTRACT_ABI } from './BatchContractAbi';
import { ERC20_ABI } from './Erc20ABI';
import { TOKEN_BRIDGE_ABI } from './TokenBridgeAbi';
import { TOKEN_BRIDGE_RELAYER_ABI } from './TokenBrigdeRelayerAbi';

// TODO: Can we move them somewhere?
const BUY_EXECUTION_FEE = 100_000_000_000_000_000n;
Expand All @@ -22,33 +12,31 @@ export const BATCH_CONTRACT_ADDRESS =

export function xTokens() {
return {
transfer: ({
isAutomatic,
}: {
isAutomatic: boolean;
}): MrlExtrinsicConfigBuilder => ({
transfer: (): MrlExtrinsicConfigBuilder => ({
build: (params) => {
const {
asset,
destination,
destinationAddress,
moonApi,
moonAsset,
moonChain,
moonGasLimit,
sourceApi,
transact,
} = params;

if (!destination.wh?.name) {
throw new Error('Destination chain does not have a wormhole name');
}

if (!transact) {
throw new Error('Transact params are required');
}

const { transfer } = sourceApi.tx.xTokens;
const builder = ExtrinsicBuilder().xTokens().transfer();

const assetTx = transfer(builder.build(params).getArgs(transfer));
/*
* TODO: We need to move it to AssetRoute and receive it in build params.
* TODO: Can we move it to AssetRoute and receive it in build params?
* In the future we could also check if wallet already has necessary DEV/GLMR to pay execution fees on Moonbase/Moonbeam.
* Also we need to move fees to AssetRoute.
*/
Expand All @@ -63,83 +51,12 @@ export function xTokens() {
.getArgs(transfer),
);

const wh = new Wormhole(moonChain.isTestChain ? 'Testnet' : 'Mainnet', [
EvmPlatform,
]);
const whDestinationChain = wh.getChain(destination.wh.name).config
.chainId;
const whContractAddress = (
isAutomatic
? wh.getChain('Moonbeam').config.contracts.tokenBridgeRelayer
: wh.getChain('Moonbeam').config.contracts.tokenBridge
) as Address;

const tokenAddressOnMoonChain = moonChain.getChainAsset(asset)
.address as Address;
const tokenAmountOnMoonChain = asset.convertDecimals(
moonChain.getChainAsset(asset).decimals,
).amount;

const approveTx = encodeFunctionData({
abi: ERC20_ABI,
functionName: 'approve',
args: [whContractAddress, tokenAmountOnMoonChain],
});
const transferTx = isAutomatic
? encodeFunctionData({
abi: TOKEN_BRIDGE_RELAYER_ABI,
functionName: 'transferTokensWithRelay',
args: [
tokenAddressOnMoonChain,
tokenAmountOnMoonChain,
0,
whDestinationChain,
destinationAddress,
0,
],
})
: encodeFunctionData({
abi: TOKEN_BRIDGE_ABI,
functionName: 'transferTokens',
args: [
tokenAddressOnMoonChain,
tokenAmountOnMoonChain,
whDestinationChain,
convertAddressTo32Bytes(destinationAddress) as Address,
0n,
0,
],
});
const batchAll = encodeFunctionData({
abi: BATCH_CONTRACT_ABI,
functionName: 'batchAll',
args: [
[tokenAddressOnMoonChain, whContractAddress],
[0n, 0n], // Value to send for each call
[approveTx, transferTx], // Call data for each call
[], // Gas limit for each call
],
});

const { address20 } = getMultilocationDerivedAddresses({
address: destinationAddress,
paraId: moonChain.parachainId,
isParents: true,
});

const transact = moonApi.tx.ethereumXcm.transact({
V2: {
gasLimit: moonGasLimit,
action: {
Call: BATCH_CONTRACT_ADDRESS,
},
value: 0,
input: batchAll,
},
});

const txWeight = (await transact.paymentInfo(address20)).weight;

const send = sourceApi.tx.polkadotXcm.send(
{
V3: {
Expand Down Expand Up @@ -188,11 +105,11 @@ export function xTokens() {
Transact: {
originKind: 'SovereignAccount',
requireWeightAtMost: {
refTime: txWeight.refTime,
proofSize: txWeight.proofSize,
refTime: transact.txWeight.refTime,
proofSize: transact.txWeight.proofSize,
},
call: {
encoded: transact.method.toHex(),
encoded: transact.call,
},
},
},
Expand Down

0 comments on commit 14b1d18

Please sign in to comment.