-
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.
- Loading branch information
Showing
20 changed files
with
807 additions
and
15 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// Copyright 2023 Parity Technologies (UK) Ltd. | ||
|
||
import { ApiPromise } from '@polkadot/api'; | ||
import type { FrameSystemAccountInfo, PalletAssetsAssetAccount } from '@polkadot/types/lookup'; | ||
import type { Option } from '@polkadot/types-codec'; | ||
export interface IBalance { | ||
initial: [string, number][]; | ||
final: [string, number][]; | ||
} | ||
|
||
export const balanceTracker = async ( | ||
api: ApiPromise, | ||
test: string, | ||
address: string, | ||
assetIds: string[], | ||
balance?: IBalance | ||
): Promise<IBalance> => { | ||
let balances: IBalance = { initial: [], final: [] }; | ||
let accountInfo: FrameSystemAccountInfo | Option<PalletAssetsAssetAccount>; | ||
switch (test) { | ||
case '--foreign-assets': | ||
if (!balance) { | ||
for (const assetId of assetIds) { | ||
accountInfo = (await api.query.foreignAssets.account(assetId, address)) as Option<PalletAssetsAssetAccount>; | ||
balances.initial.push([assetId, accountInfo.unwrap().balance.toBn().toNumber()]); | ||
} | ||
} else { | ||
balances = balance; | ||
for (const assetId of assetIds) { | ||
accountInfo = (await api.query.foreignAssets.account(assetId, address)) as Option<PalletAssetsAssetAccount>; | ||
balances.final.push([assetId, accountInfo.unwrap().balance.toBn().toNumber()]); | ||
} | ||
} | ||
return balances; | ||
case '--liquidity-assets': | ||
if (!balance) { | ||
for (const assetId of assetIds) { | ||
accountInfo = await api.query.poolAssets.account(assetId, address); | ||
balances.initial.push([assetId, accountInfo.unwrap().balance.toBn().toNumber()]); | ||
} | ||
} else { | ||
balances = balance; | ||
for (const assetId of assetIds) { | ||
accountInfo = await api.query.poolAssets.account(assetId, address); | ||
balances.final.push([assetId, accountInfo.unwrap().balance.toBn().toNumber()]); | ||
} | ||
} | ||
return balances; | ||
case '--local': | ||
if (!balance) { | ||
accountInfo = await api.query.system.account(address); | ||
balances.initial.push(['0', accountInfo.data.free.toBn().toNumber()]); | ||
} else { | ||
balances = balance; | ||
accountInfo = await api.query.system.account(address); | ||
balances.final.push(['0', accountInfo.data.free.toBn().toNumber()]); | ||
} | ||
return balances; | ||
case '--assets': | ||
if (!balance) { | ||
for (const assetId of assetIds) { | ||
accountInfo = await api.query.assets.account(assetId, address); | ||
if (accountInfo.valueOf() == null) { | ||
balances.initial.push([assetId, 0]); | ||
} else { | ||
balances.initial.push([assetId, accountInfo.unwrap().balance.toBn().toNumber()]); | ||
} | ||
} | ||
} else { | ||
balances = balance; | ||
for (const assetId of assetIds) { | ||
accountInfo = await api.query.assets.account(assetId, address); | ||
balances.final.push([assetId, accountInfo.unwrap().balance.toBn().toNumber()]); | ||
|
||
} | ||
} | ||
return balances; | ||
default: | ||
if (!balance) { | ||
for (const assetId of assetIds) { | ||
accountInfo = await api.query.system.account(address); | ||
if (accountInfo) { | ||
balances.initial.push([assetId, accountInfo.data.free.toBn().toNumber()]); | ||
} else { | ||
balances.initial.push([assetId, 0]); | ||
|
||
} | ||
} | ||
} else { | ||
balances = balance; | ||
for (const assetId of assetIds) { | ||
accountInfo = await api.query.system.account(address); | ||
balances.final.push([assetId, accountInfo.data.free.toBn().toNumber()]); | ||
} | ||
} | ||
return balances; | ||
} | ||
}; |
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,17 @@ | ||
// Copyright 2023 Parity Technologies (UK) Ltd. | ||
|
||
export const KUSAMA_ASSET_HUB_WS_URL = 'ws://127.0.0.1:9911'; | ||
export const ROCOCO_ALICE_WS_URL = 'ws://127.0.0.1:9900'; | ||
export const TRAPPIST_WS_URL = 'ws://127.0.0.1:9921'; | ||
export const MOONRIVER_WS_URL = 'ws://127.0.0.1:9931'; | ||
|
||
export const BOB_ROC_ADDR = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'; | ||
export const FERDE_ROC_ADDR = '5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL'; | ||
export const BOB_KAH_ADDR = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'; | ||
export const FERDE_KAH_ADDR = '5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL'; | ||
|
||
export const ASSET_ID = 1; | ||
|
||
export const MOONRIVER_ADDR = '5Eg2fnt8QeGtg4mcc5ELxPx6qxP2FSEWHbbYXENZ17ormkGP'; | ||
export const TRAPPIST_ADDR = '5Eg2fntDDP4P8TjqRg3Jq89y5boE26JUMM3D7VU3bCAp76nc'; | ||
export const ASSET_HUB_ADDR = '5Eg2fntNprdN3FgH4sfEaaZhYtddZQSQUqvYJ1f2mLtinVhV'; |
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,156 @@ | ||
// Copyright 2023 Parity Technologies (UK) Ltd. | ||
import { ApiPromise, WsProvider } from '@polkadot/api'; | ||
import { Keyring } from '@polkadot/keyring'; | ||
// import { KeyringPair } from '@polkadot/keyring/types'; | ||
import { cryptoWaitReady } from '@polkadot/util-crypto'; | ||
|
||
import { constructApiPromise } from '../src'; | ||
import { balanceTracker, IBalance } from './balance'; | ||
import { KUSAMA_ASSET_HUB_WS_URL, MOONRIVER_WS_URL, ROCOCO_ALICE_WS_URL, TRAPPIST_WS_URL } from './consts'; | ||
import { assetTests, foreignAssetsTests, IndividualTest, liquidPoolsTests, localTests, tests } from './tests'; | ||
import { verification } from './verification'; | ||
import { delay } from '../scripts/util' | ||
|
||
const executor = async (testCase: string) => { | ||
let originWsUrl = ''; | ||
let destWsUrl = ''; | ||
|
||
let testData: IndividualTest[] = []; | ||
|
||
await cryptoWaitReady(); | ||
|
||
const keyring = new Keyring({ type: 'sr25519' }); | ||
|
||
switch (testCase) { | ||
case '--foreign-assets': | ||
testData = tests.foreignAssets; | ||
break; | ||
case '--liquidity-assets': | ||
testData = tests.liquidPools; | ||
break; | ||
case '--local': | ||
testData = tests.local; | ||
break; | ||
case '--assets': | ||
testData = tests.assets; | ||
break; | ||
} | ||
|
||
let n: { [K: string]: Function } = {}; | ||
|
||
switch (testCase) { | ||
case '--foreign-assets': | ||
n = foreignAssetsTests; | ||
break; | ||
case '--liquidity-assets': | ||
n = liquidPoolsTests; | ||
break; | ||
case '--local': | ||
n = localTests; | ||
break; | ||
case '--assets': | ||
n = assetTests; | ||
break; | ||
} | ||
console.log(n) | ||
|
||
let originChainId = ''; | ||
let destChainId = ''; | ||
let originAddr = ''; | ||
let destAddr = ''; | ||
let assetIds: string[] = []; | ||
let amounts: string[] = []; | ||
let opts: object = {}; | ||
|
||
for (const t of testData) { | ||
|
||
originChainId = t.args[0]; | ||
destChainId = t.args[1]; | ||
originAddr = t.args[2]; | ||
destAddr = t.args[3]; | ||
assetIds = t.args[4].slice(1, -1).split(','); | ||
amounts = t.args[5].slice(1, -1).split(','); | ||
opts = JSON.parse(t.args[6]); | ||
|
||
switch (originChainId) { | ||
case '0': | ||
originWsUrl = ROCOCO_ALICE_WS_URL; | ||
break; | ||
case '1000': | ||
originWsUrl = KUSAMA_ASSET_HUB_WS_URL; | ||
break; | ||
case '2500': | ||
originWsUrl = TRAPPIST_WS_URL; | ||
break; | ||
case '2600': | ||
originWsUrl = MOONRIVER_WS_URL; | ||
break; | ||
} | ||
|
||
if (originChainId == destChainId) { | ||
destWsUrl = originWsUrl; | ||
} else { | ||
switch (destChainId) { | ||
case '0': | ||
destWsUrl = ROCOCO_ALICE_WS_URL; | ||
break; | ||
case '1000': | ||
destWsUrl = KUSAMA_ASSET_HUB_WS_URL; | ||
break; | ||
case '2500': | ||
destWsUrl = TRAPPIST_WS_URL; | ||
break; | ||
case '2600': | ||
destWsUrl = MOONRIVER_WS_URL; | ||
break; | ||
} | ||
} | ||
const { api, specName, safeXcmVersion } = await constructApiPromise(originWsUrl); | ||
|
||
await api.isReady; | ||
|
||
const originApi = api; | ||
const destinationApi = | ||
originChainId == destChainId | ||
? originApi | ||
: await ApiPromise.create({ | ||
provider: new WsProvider(destWsUrl), | ||
noInitWarn: true, | ||
}); | ||
|
||
await destinationApi.isReady; | ||
let destInitialBalance: IBalance = await balanceTracker(destinationApi, testCase, destAddr, assetIds); | ||
const originKeyring = keyring.addFromUri(originAddr); | ||
|
||
//eslint-disable-next-line @typescript-eslint/no-unsafe-call | ||
await n[t.test](originKeyring, destChainId, destAddr, assetIds, amounts, opts, api, specName, safeXcmVersion); | ||
|
||
await delay(24000); | ||
|
||
let destFinalBalance: IBalance = await balanceTracker( | ||
destinationApi, | ||
testCase, | ||
destAddr, | ||
assetIds, | ||
destInitialBalance | ||
); | ||
|
||
const correctlyReceived = verification(assetIds, amounts, destFinalBalance); | ||
|
||
for (let i = 0; i < assetIds.length; i++) { | ||
if (correctlyReceived[i][1]) { | ||
console.log('all good'); | ||
} else { | ||
console.log('badd'); | ||
} | ||
} | ||
|
||
await delay(12000); | ||
|
||
originApi.disconnect(); | ||
destinationApi.disconnect(); | ||
} | ||
|
||
}; | ||
|
||
executor(process.argv[2]).finally(() => process.exit()); |
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 @@ | ||
// Copyright 2023 Parity Technologies (UK) Ltd. |
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,18 @@ | ||
#!/bin/sh | ||
test=$1 | ||
yarn run build:e2e && | ||
if [ $test = '--assets' ]; then | ||
script=post | ||
elif [ $test = '--local' ]; then | ||
script=post | ||
elif [ $test = '--liquidity-assets' ]; then | ||
script=liquidity-assets | ||
elif [ $test = '--foreign-assets' ]; then | ||
script=foreign-assets | ||
fi | ||
|
||
yarn run start:zombienet-$script-script | ||
|
||
sleep 24 | ||
|
||
node ./e2e-tests/build/e2e-tests/executor.js $test |
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,72 @@ | ||
// Copyright 2023 Parity Technologies (UK) Ltd. | ||
import { ApiPromise } from '@polkadot/api'; | ||
import { KeyringPair } from '@polkadot/keyring/types'; | ||
|
||
import { AssetTransferApi } from '../../src'; | ||
import { TxResult } from '../../src/types'; | ||
|
||
const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: number): AssetTransferApi => { | ||
const injectedRegistry = { | ||
rococo: { | ||
'2500': { | ||
tokens: ['HOP'], | ||
assetsInfo: {}, | ||
foreignAssetsInfo: {}, | ||
specName: 'trappist-rococo', | ||
poolPairsInfo: {}, | ||
}, | ||
}, | ||
}; | ||
const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, { | ||
injectedRegistry, | ||
}); | ||
|
||
return assetApi; | ||
}; | ||
|
||
const createLocalSystemAssetsTransferTransaction = async ( | ||
origin: KeyringPair, | ||
destChainId: string, | ||
destAddr: string, | ||
assetIds: string[], | ||
amounts: string[], | ||
opts: object, | ||
api: ApiPromise, | ||
specName: string, | ||
safeXcmVersion: number | ||
) => { | ||
const assetApi = createAssetApi(api, specName, safeXcmVersion); | ||
|
||
let localTransfer: TxResult<'submittable'>; | ||
try { | ||
localTransfer = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); | ||
await localTransfer.tx.signAndSend(origin); | ||
} catch (e) { | ||
console.error(e); | ||
throw Error(e as string); | ||
} | ||
}; | ||
|
||
const createPayFeesTransaction = async ( | ||
origin: KeyringPair, | ||
destChainId: string, | ||
destAddr: string, | ||
assetIds: string[], | ||
amounts: string[], | ||
opts: object, | ||
api: ApiPromise, | ||
specName: string, | ||
safeXcmVersion: number | ||
) => { | ||
const assetApi = createAssetApi(api, specName, safeXcmVersion); | ||
|
||
let localTransfer: TxResult<'submittable'>; | ||
try { | ||
localTransfer = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); | ||
await localTransfer.tx.signAndSend(origin) | ||
} catch (e) { | ||
console.error(e); | ||
throw Error(e as string); | ||
} | ||
}; | ||
export const assetTests: { [K: string]: Function } = { createLocalSystemAssetsTransferTransaction, createPayFeesTransaction }; |
Oops, something went wrong.