-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implement Batch contract builder for sending assets and xcm message w…
…ith remote execution
- Loading branch information
Showing
16 changed files
with
867 additions
and
113 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { type AnyParachain, EvmParachain } from '@moonbeam-network/xcm-types'; | ||
import { u8aToHex } from '@polkadot/util'; | ||
import { decodeAddress } from '@polkadot/util-crypto'; | ||
import type { Address } from 'viem'; | ||
|
||
export function getPrecompileDestinationInterior( | ||
destination: AnyParachain, | ||
address?: string, | ||
): [Address, Address] | [Address] { | ||
if (!address) { | ||
return [`0x0000000${destination.parachainId.toString(16)}`]; | ||
} | ||
|
||
/* | ||
01: AccountId32 | ||
03: AccountKey20 | ||
https://docs.moonbeam.network/builders/interoperability/xcm/xc20/xtokens/#building-the-precompile-multilocation | ||
*/ | ||
const accountType = EvmParachain.is(destination) ? '03' : '01'; | ||
const acc = `0x${accountType}${u8aToHex( | ||
decodeAddress(address), | ||
-1, | ||
false, | ||
)}00` as Address; | ||
|
||
return destination.parachainId | ||
? [`0x0000000${destination.parachainId.toString(16)}`, acc] | ||
: [acc]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
169 changes: 169 additions & 0 deletions
169
packages/builder/src/mrl/providers/wormhole/contract/Batch/Batch.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
import { | ||
type AssetAmount, | ||
type ChainAsset, | ||
EvmParachain, | ||
type Parachain, | ||
} from '@moonbeam-network/xcm-types'; | ||
import { getMultilocationDerivedAddresses } from '@moonbeam-network/xcm-utils'; | ||
import { _0n } from '@polkadot/util'; | ||
import { evmToAddress } from '@polkadot/util-crypto'; | ||
import { type Address, encodeFunctionData, maxUint64 } from 'viem'; | ||
import { getPrecompileDestinationInterior } from '../../../../../builder.utils'; | ||
import { ContractConfig } from '../../../../../contract'; | ||
import type { MrlConfigBuilder } from '../../../../MrlBuilder.interfaces'; | ||
import { | ||
CROSS_CHAIN_FEE, | ||
buildSendExtrinsic, | ||
} from '../../extrinsic/polkadotXcm/polkadotXcm'; | ||
import { getAbisForChain } from './abi/abi.helpers'; | ||
|
||
const module = 'PeaqTest'; | ||
export const TEST_PEAQ_CALL: `0x${string}` = | ||
'0x96e292b8000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000094000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000803000000000000000000000000000000000000000000000000000000000000080400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000244ab946323000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000ffffffffffffffff0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000ffffffff000000000000000000000000000003e8000000000000000000000000000000000000000000000000016345785d8a0000000000000000000000000000ffffffff000000000000000000000000000003e900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000500000003e80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016033b6d6b531a9c2d2e1490f39ad2609ea9cd2f7b29000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000052498600e64000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000500000003e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003f0031000040000010403001300008a5d78456301130000010403001300008a5d7845630100060107b81f98d005eecd03007d0e260001bd370f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008080000000000000000000000000000000000000000000000000000000000000000110d96e292b8000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000566c1cebc6a4afa1c122e039c4bebe77043148ee000000000000000000000000bc976d4b9d57e57c3ca52e1fd136c45ff7955a960000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000044095ea7b3000000000000000000000000bc976d4b9d57e57c3ca52e1fd136c45ff7955a9600000000000000000000000000000000000000000000000000005af3107a40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c40f5287b0000000000000000000000000566c1cebc6a4afa1c122e039c4bebe77043148ee00000000000000000000000000000000000000000000000000005af3107a4000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000008480769599e23f626efff39b89f3137e9917a4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608140d010204000103003b6d6b531a9c2d2e1490f39ad2609ea9cd2f7b2900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'; | ||
|
||
export function Batch() { | ||
return { | ||
transferAssetsAndMessage: (): MrlConfigBuilder => ({ | ||
build: ({ | ||
asset, | ||
destination, | ||
destinationAddress, | ||
fee, | ||
isAutomatic, | ||
moonAsset, | ||
moonChain, | ||
moonApi, | ||
source, | ||
sourceAddress, | ||
sourceApi, | ||
transact, | ||
}) => { | ||
if (!EvmParachain.is(source)) { | ||
throw new Error('Source chain needs to be an EVMParachain'); | ||
} | ||
|
||
if (!sourceApi) { | ||
throw new Error('Source API needs to be defined'); | ||
} | ||
|
||
if ( | ||
!source.contracts?.Xtokens || | ||
!source.contracts?.XcmUtils || | ||
!source.contracts?.Batch | ||
) { | ||
throw new Error( | ||
'Source chain needs to have the Xtokens, XcmUtils and Batch contract addresses configured', | ||
); | ||
} | ||
|
||
const subMappedAddress = evmToAddress(sourceAddress); | ||
|
||
const { BatchAbi, XcmUtilsAbi, XtokensAbi } = getAbisForChain(source); | ||
|
||
const { address20: computedOriginAccount } = | ||
getMultilocationDerivedAddresses({ | ||
address: subMappedAddress, | ||
paraId: source.parachainId, | ||
isParents: true, | ||
}); | ||
|
||
const send = buildSendExtrinsic({ | ||
asset, | ||
destination, | ||
destinationAddress, | ||
computedOriginAccount, | ||
fee, | ||
isAutomatic, | ||
moonAsset, | ||
moonChain, | ||
moonApi, | ||
source, | ||
sourceAddress, | ||
sourceApi, | ||
transact, | ||
}); | ||
// we keep only the message | ||
const encodedXcmMessage = send.args[1].toHex(); | ||
|
||
const { destinationParachain, destinationParachainAndAddress } = | ||
getDestinationInHex(moonChain, computedOriginAccount); | ||
|
||
const { currencies, feeItem } = getCurrencies({ | ||
source, | ||
moonAsset, | ||
asset, | ||
}); | ||
const weight = maxUint64; | ||
|
||
const multiTransferTxData = encodeFunctionData({ | ||
abi: XtokensAbi, | ||
functionName: 'transferMultiCurrencies', | ||
args: [currencies, feeItem, destinationParachainAndAddress, weight], | ||
}); | ||
|
||
const xcmSendTxData = encodeFunctionData({ | ||
abi: XcmUtilsAbi, | ||
functionName: 'xcmSend', | ||
args: [destinationParachain, encodedXcmMessage], | ||
}); | ||
|
||
return new ContractConfig({ | ||
address: source.contracts.Batch, | ||
abi: BatchAbi, | ||
args: [ | ||
[source.contracts.Xtokens, source.contracts.XcmUtils], | ||
[], | ||
[multiTransferTxData, xcmSendTxData], | ||
[], | ||
], | ||
func: 'batchAll', | ||
module, | ||
}); | ||
}, | ||
}), | ||
}; | ||
} | ||
|
||
function getDestinationInHex( | ||
moonChain: EvmParachain, | ||
computedOriginAccount: string, | ||
) { | ||
const destinationParachain = { | ||
parents: 1, | ||
interior: getPrecompileDestinationInterior(moonChain), | ||
} as const; | ||
|
||
const destinationParachainAndAddress = { | ||
parents: 1, | ||
interior: getPrecompileDestinationInterior( | ||
moonChain, | ||
computedOriginAccount, | ||
), | ||
} as const; | ||
|
||
return { | ||
destinationParachain, | ||
destinationParachainAndAddress, | ||
}; | ||
} | ||
|
||
interface GetCurrenciesParams { | ||
source: Parachain | EvmParachain; | ||
moonAsset: ChainAsset; | ||
asset: AssetAmount; | ||
} | ||
|
||
function getCurrencies({ source, moonAsset, asset }: GetCurrenciesParams) { | ||
const currencies = [ | ||
{ | ||
currencyAddress: source.getChainAsset(moonAsset).address as Address, | ||
amount: CROSS_CHAIN_FEE, | ||
}, | ||
{ | ||
currencyAddress: asset.address as Address, | ||
amount: asset.amount, | ||
}, | ||
]; | ||
const feeItem = 0; // moonAsset | ||
return { currencies, feeItem }; | ||
} |
13 changes: 13 additions & 0 deletions
13
packages/builder/src/mrl/providers/wormhole/contract/Batch/abi/abi.helpers.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import type { EvmParachain } from '@moonbeam-network/xcm-types'; | ||
import { PEAQ_BATCH_ABI } from './peaq/PeaqBatchContractAbi'; | ||
import { PEAQ_XCM_UTILS_ABI } from './peaq/PeaqXcmUtilsContractAbi'; | ||
import { PEAQ_XTOKENS_ABI } from './peaq/PeaqXtokensContractAbi'; | ||
|
||
export function getAbisForChain(chain: EvmParachain) { | ||
// TODO when we add more chains, find a way to handle Abis for the different chains, if the Abis differ | ||
return { | ||
BatchAbi: PEAQ_BATCH_ABI, | ||
XcmUtilsAbi: PEAQ_XCM_UTILS_ABI, | ||
XtokensAbi: PEAQ_XTOKENS_ABI, | ||
}; | ||
} |
Oops, something went wrong.