git.delta.rocks / unique-network / refs/commits / 347f218123fd

difftreelog

source

js-packages/tests/xcm/lowLevelXcmUnique.test.ts14.5 KiBsourcehistory
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import type {IKeyringPair} from '@polkadot/types/types';18import config from '../config.js';19import {itSub, describeXCM, usingPlaygrounds, usingAcalaPlaygrounds, usingMoonbeamPlaygrounds, usingAstarPlaygrounds, usingPolkadexPlaygrounds, usingHydraDxPlaygrounds} from '@unique/test-utils/util.js';20import {nToBigInt} from '@polkadot/util';21import {hexToString} from '@polkadot/util';22import {ASTAR_DECIMALS, SAFE_XCM_VERSION, SENDER_BUDGET, UNIQUE_CHAIN, UNQ_DECIMALS, XcmTestHelper, acalaUrl, astarUrl,  hydraDxUrl,  moonbeamUrl, polkadexUrl, uniqueAssetId} from './xcm.types.js';2324const testHelper = new XcmTestHelper('unique');2526272829describeXCM('[XCMLL] Integration test: Exchanging tokens with Acala', () => {30  let alice: IKeyringPair;31  let randomAccount: IKeyringPair;3233  before(async () => {34    await usingPlaygrounds(async (helper, privateKey) => {35      alice = await privateKey('//Alice');36      console.log(config.acalaUrl);37      randomAccount = helper.arrange.createEmptyAccount();3839      // Set the default version to wrap the first message to other chains.40      await helper.getSudo().xcm.setSafeXcmVersion(alice, SAFE_XCM_VERSION);41    });4243    await usingAcalaPlaygrounds(acalaUrl, async (helper) => {44      const destination = {45        V2: {46          parents: 1,47          interior: {48            X1: {49              Parachain: UNIQUE_CHAIN,50            },51          },52        },53      };5455      const metadata = {56        name: 'Unique Network',57        symbol: 'UNQ',58        decimals: 18,59        minimalBalance: 1250_000_000_000_000_000n,60      };61      const assets = (await (helper.callRpc('api.query.assetRegistry.assetMetadatas.entries'))).map(([_k, v] : [any, any]) =>62        hexToString(v.toJSON()['symbol'])) as string[];6364      if(!assets.includes('UNQ')) {65        await helper.getSudo().assetRegistry.registerForeignAsset(alice, destination, metadata);66      } else {67        console.log('UNQ token already registered on Acala assetRegistry pallet');68      }69      await helper.balance.transferToSubstrate(alice, randomAccount.address, 10000000000000n);70    });7172    await usingPlaygrounds(async (helper) => {73      await helper.balance.transferToSubstrate(alice, randomAccount.address, SENDER_BUDGET);74    });75  });7677  itSub('Should connect and send UNQ to Acala', async () => {78    await testHelper.sendUnqTo('acala', randomAccount);79  });8081  itSub('Should connect to Acala and send UNQ back', async () => {82    await testHelper.sendUnqBack('acala', alice, randomAccount);83  });8485  itSub('Acala can send only up to its balance', async () => {86    await testHelper.sendOnlyOwnedBalance('acala', alice);87  });8889  itSub('Should not accept reserve transfer of UNQ from Acala', async () => {90    await testHelper.rejectReserveTransferUNQfrom('acala', alice);91  });92});9394describeXCM('[XCMLL] Integration test: Exchanging tokens with Polkadex', () => {95  let alice: IKeyringPair;96  let randomAccount: IKeyringPair;9798  before(async () => {99    await usingPlaygrounds(async (helper, privateKey) => {100      alice = await privateKey('//Alice');101      randomAccount = helper.arrange.createEmptyAccount();102103      // Set the default version to wrap the first message to other chains.104      await helper.getSudo().xcm.setSafeXcmVersion(alice, SAFE_XCM_VERSION);105    });106107    await usingPolkadexPlaygrounds(polkadexUrl, async (helper) => {108      const isWhitelisted = ((await helper.callRpc('api.query.xcmHelper.whitelistedTokens', []))109        .toJSON() as [])110        .map(nToBigInt).length != 0;111      /*112      Check whether the Unique token has been added113      to the whitelist, since an error will occur114      if it is added again. Needed for debugging115      when this test is run multiple times.116      */117      if(isWhitelisted) {118        console.log('UNQ token is already whitelisted on Polkadex');119      } else {120        await helper.getSudo().xcmHelper.whitelistToken(alice, uniqueAssetId);121      }122123      await helper.balance.transferToSubstrate(alice, randomAccount.address, 10000000000000n);124    });125126    await usingPlaygrounds(async (helper) => {127      await helper.balance.transferToSubstrate(alice, randomAccount.address, SENDER_BUDGET);128    });129  });130131  itSub('Should connect and send UNQ to Polkadex', async () => {132    await testHelper.sendUnqTo('polkadex', randomAccount);133  });134135136  itSub('Should connect to Polkadex and send UNQ back', async () => {137    await testHelper.sendUnqBack('polkadex', alice, randomAccount);138  });139140  itSub('Polkadex can send only up to its balance', async () => {141    await testHelper.sendOnlyOwnedBalance('polkadex', alice);142  });143144  itSub('Should not accept reserve transfer of UNQ from Polkadex', async () => {145    await testHelper.rejectReserveTransferUNQfrom('polkadex', alice);146  });147});148149// These tests are relevant only when150// the the corresponding foreign assets are not registered151describeXCM('[XCMLL] Integration test: Unique rejects non-native tokens', () => {152  let alice: IKeyringPair;153154  before(async () => {155    await usingPlaygrounds(async (helper, privateKey) => {156      alice = await privateKey('//Alice');157158      // Set the default version to wrap the first message to other chains.159      await helper.getSudo().xcm.setSafeXcmVersion(alice, SAFE_XCM_VERSION);160    });161  });162163  itSub('Unique rejects ACA tokens from Acala', async () => {164    await testHelper.rejectNativeTokensFrom('acala', alice);165  });166167  itSub('Unique rejects GLMR tokens from Moonbeam', async () => {168    await testHelper.rejectNativeTokensFrom('moonbeam', alice);169  });170171  itSub('Unique rejects ASTR tokens from Astar', async () => {172    await testHelper.rejectNativeTokensFrom('astar', alice);173  });174175  itSub('Unique rejects PDX tokens from Polkadex', async () => {176    await testHelper.rejectNativeTokensFrom('polkadex', alice);177  });178});179180describeXCM('[XCMLL] Integration test: Exchanging UNQ with Moonbeam', () => {181  // Unique constants182  let alice: IKeyringPair;183  let uniqueAssetLocation;184185  let randomAccountUnique: IKeyringPair;186  let randomAccountMoonbeam: IKeyringPair;187188  // Moonbeam constants189  let assetId: string;190191  const uniqueAssetMetadata = {192    name: 'xcUnique',193    symbol: 'xcUNQ',194    decimals: 18,195    isFrozen: false,196    minimalBalance: 1n,197  };198199200  before(async () => {201    await usingPlaygrounds(async (helper, privateKey) => {202      alice = await privateKey('//Alice');203      [randomAccountUnique] = await helper.arrange.createAccounts([0n], alice);204205206      // Set the default version to wrap the first message to other chains.207      await helper.getSudo().xcm.setSafeXcmVersion(alice, SAFE_XCM_VERSION);208    });209210    await usingMoonbeamPlaygrounds(moonbeamUrl, async (helper) => {211      const alithAccount = helper.account.alithAccount();212      const baltatharAccount = helper.account.baltatharAccount();213      const dorothyAccount = helper.account.dorothyAccount();214215      randomAccountMoonbeam = helper.account.create();216217      // >>> Sponsoring Dorothy >>>218      console.log('Sponsoring Dorothy.......');219      await helper.balance.transferToEthereum(alithAccount, dorothyAccount.address, 11_000_000_000_000_000_000n);220      console.log('Sponsoring Dorothy.......DONE');221      // <<< Sponsoring Dorothy <<<222      uniqueAssetLocation = {223        XCM: {224          parents: 1,225          interior: {X1: {Parachain: UNIQUE_CHAIN}},226        },227      };228      const existentialDeposit = 1n;229      const isSufficient = true;230      const unitsPerSecond = 1n;231      const numAssetsWeightHint = 0;232233      if((await helper.assetManager.assetTypeId(uniqueAssetLocation)).toJSON()) {234        console.log('Unique asset already registered on Moonbeam');235      } else {236        const encodedProposal = helper.assetManager.makeRegisterForeignAssetProposal({237          location: uniqueAssetLocation,238          metadata: uniqueAssetMetadata,239          existentialDeposit,240          isSufficient,241          unitsPerSecond,242          numAssetsWeightHint,243        });244245        console.log('Encoded proposal for registerForeignAsset & setAssetUnitsPerSecond is %s', encodedProposal);246247        await helper.fastDemocracy.executeProposal('register UNQ foreign asset', encodedProposal);248      }249250      // >>> Acquire Unique AssetId Info on Moonbeam >>>251      console.log('Acquire Unique AssetId Info on Moonbeam.......');252253      assetId = (await helper.assetManager.assetTypeId(uniqueAssetLocation)).toString();254255      console.log('UNQ asset ID is %s', assetId);256      console.log('Acquire Unique AssetId Info on Moonbeam.......DONE');257258      // >>> Sponsoring random Account >>>259      console.log('Sponsoring random Account.......');260      await helper.balance.transferToEthereum(baltatharAccount, randomAccountMoonbeam.address, 11_000_000_000_000_000_000n);261      console.log('Sponsoring random Account.......DONE');262      // <<< Sponsoring random Account <<<263    });264265    await usingPlaygrounds(async (helper) => {266      await helper.balance.transferToSubstrate(alice, randomAccountUnique.address, SENDER_BUDGET);267    });268  });269270  itSub('Should connect and send UNQ to Moonbeam', async () => {271    await testHelper.sendUnqTo('moonbeam', randomAccountUnique, randomAccountMoonbeam);272  });273274  itSub('Should connect to Moonbeam and send UNQ back', async () => {275    await testHelper.sendUnqBack('moonbeam', alice, randomAccountUnique);276  });277278  itSub('Moonbeam can send only up to its balance', async () => {279    await testHelper.sendOnlyOwnedBalance('moonbeam', alice);280  });281282  itSub('Should not accept reserve transfer of UNQ from Moonbeam', async () => {283    await testHelper.rejectReserveTransferUNQfrom('moonbeam', alice);284  });285});286287describeXCM('[XCMLL] Integration test: Exchanging tokens with Astar', () => {288  let alice: IKeyringPair;289  let randomAccount: IKeyringPair;290291  const UNQ_ASSET_ID_ON_ASTAR = 18_446_744_073_709_551_631n; // The value is taken from the live Astar292  const UNQ_MINIMAL_BALANCE_ON_ASTAR = 1n; // The value is taken from the live Astar293294  // Unique -> Astar295  const astarInitialBalance = 1n * (10n ** ASTAR_DECIMALS); // 1 ASTR, existential deposit required to actually create the account on Astar.296  const unitsPerSecond = 9_451_000_000_000_000_000n; // The value is taken from the live Astar297298  before(async () => {299    await usingPlaygrounds(async (helper, privateKey) => {300      alice = await privateKey('//Alice');301      randomAccount = helper.arrange.createEmptyAccount();302      await helper.balance.transferToSubstrate(alice, randomAccount.address, SENDER_BUDGET);303      console.log('randomAccount', randomAccount.address);304305      // Set the default version to wrap the first message to other chains.306      await helper.getSudo().xcm.setSafeXcmVersion(alice, SAFE_XCM_VERSION);307    });308309    await usingAstarPlaygrounds(astarUrl, async (helper) => {310      if(!(await helper.callRpc('api.query.assets.asset', [UNQ_ASSET_ID_ON_ASTAR])).toJSON()) {311        console.log('1. Create foreign asset and metadata');312        await helper.getSudo().assets.forceCreate(313          alice,314          UNQ_ASSET_ID_ON_ASTAR,315          alice.address,316          UNQ_MINIMAL_BALANCE_ON_ASTAR,317        );318319        await helper.assets.setMetadata(320          alice,321          UNQ_ASSET_ID_ON_ASTAR,322          'Unique Network',323          'UNQ',324          Number(UNQ_DECIMALS),325        );326327        console.log('2. Register asset location on Astar');328        const assetLocation = {329          V2: {330            parents: 1,331            interior: {332              X1: {333                Parachain: UNIQUE_CHAIN,334              },335            },336          },337        };338339        await helper.getSudo().executeExtrinsic(alice, 'api.tx.xcAssetConfig.registerAssetLocation', [assetLocation, UNQ_ASSET_ID_ON_ASTAR]);340341        console.log('3. Set UNQ payment for XCM execution on Astar');342        await helper.getSudo().executeExtrinsic(alice, 'api.tx.xcAssetConfig.setAssetUnitsPerSecond', [assetLocation, unitsPerSecond]);343      } else {344        console.log('UNQ is already registered on Astar');345      }346      console.log('4. Transfer 1 ASTR to recipient to create the account (needed due to existential balance)');347      await helper.balance.transferToSubstrate(alice, randomAccount.address, astarInitialBalance);348    });349  });350351  itSub('Should connect and send UNQ to Astar', async () => {352    await testHelper.sendUnqTo('astar', randomAccount);353  });354355  itSub('Should connect to Astar and send UNQ back', async () => {356    await testHelper.sendUnqBack('astar', alice, randomAccount);357  });358359  itSub('Astar can send only up to its balance', async () => {360    await testHelper.sendOnlyOwnedBalance('astar', alice);361  });362363  itSub('Should not accept reserve transfer of UNQ from Astar', async () => {364    await testHelper.rejectReserveTransferUNQfrom('astar', alice);365  });366});367368describeXCM('[XCMLL] Integration test: Exchanging tokens with HydraDx', () => {369  let alice: IKeyringPair;370  let randomAccount: IKeyringPair;371372  before(async () => {373    await usingPlaygrounds(async (helper, privateKey) => {374      alice = await privateKey('//Alice');375      console.log(config.acalaUrl);376      randomAccount = helper.arrange.createEmptyAccount();377378      // Set the default version to wrap the first message to other chains.379      await helper.getSudo().xcm.setSafeXcmVersion(alice, SAFE_XCM_VERSION);380      await helper.balance.transferToSubstrate(alice, randomAccount.address, SENDER_BUDGET);381    });382383    await usingHydraDxPlaygrounds(hydraDxUrl, async (helper) => {384      await helper.balance.transferToSubstrate(alice, randomAccount.address, 10000000000000n);385    });386  });387388  itSub('Should connect and send UNQ to HydraDx', async () => {389    await testHelper.sendUnqTo('hydraDx', randomAccount);390  });391392  itSub('Should connect to HydraDx and send UNQ back', async () => {393    await testHelper.sendUnqBack('hydraDx', alice, randomAccount);394  });395396  itSub('HydraDx can send only up to its balance', async () => {397    await testHelper.sendOnlyOwnedBalance('hydraDx', alice);398  });399400  itSub('Should not accept reserve transfer of UNQ from HydraDx', async () => {401    await testHelper.rejectReserveTransferUNQfrom('hydraDx', alice);402  });403});