git.delta.rocks / unique-network / refs/commits / 05c81ca4ae1f

difftreelog

source

js-packages/tests/xcm/xcmOpal.test.ts12.6 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, expect, describeXCM, usingPlaygrounds, usingWestmintPlaygrounds, usingRelayPlaygrounds} from '@unique/test-utils/util.js';20import {XcmTestHelper} from './xcm.types.js';2122const STATEMINE_CHAIN = +(process.env.RELAY_WESTMINT_ID || 1000);23const UNIQUE_CHAIN = +(process.env.RELAY_OPAL_ID || 2095);2425const relayUrl = config.relayUrl;26const westmintUrl = config.westmintUrl;2728const STATEMINE_PALLET_INSTANCE = 50;29const USDT_ASSET_ID = 100;30const USDT_ASSET_METADATA_DECIMALS = 18;31const USDT_ASSET_METADATA_NAME = 'USDT';32const USDT_ASSET_METADATA_DESCRIPTION = 'USDT';33const USDT_ASSET_METADATA_MINIMAL_BALANCE = 1n;3435const RELAY_DECIMALS = 12;36const WESTMINT_DECIMALS = 12;3738const TRANSFER_AMOUNT = 1_000_000_000_000_000_000n;3940// 10,000.00 (ten thousands) USDT41const USDT_ASSET_AMOUNT = 1_000_000_000_000_000_000_000n;4243const testHelper = new XcmTestHelper('opal');4445describeXCM('[XCM] Integration test: Exchanging USDT with Westmint', () => {46  let alice: IKeyringPair;47  let bob: IKeyringPair;4849  let balanceStmnBefore: bigint;50  let balanceStmnAfter: bigint;5152  let balanceOpalBefore: bigint;53  let balanceOpalAfter: bigint;54  let balanceOpalFinal: bigint;5556  let balanceBobBefore: bigint;57  let balanceBobAfter: bigint;58  let balanceBobFinal: bigint;5960  let balanceBobRelayTokenBefore: bigint;61  let balanceBobRelayTokenAfter: bigint;6263  let usdtCollectionId: number;64  let relayCollectionId: number;6566  before(async () => {67    await usingPlaygrounds(async (_helper, privateKey) => {68      alice = await privateKey('//Alice');69      bob = await privateKey('//Bob'); // funds donor7071      relayCollectionId = await testHelper.registerRelayNativeTokenOnUnique(alice);72    });7374    await usingWestmintPlaygrounds(westmintUrl, async (helper) => {75      const assetInfo = await helper.assets.assetInfo(USDT_ASSET_ID);76      if(assetInfo == null) {77        await helper.assets.create(78          alice,79          USDT_ASSET_ID,80          alice.address,81          USDT_ASSET_METADATA_MINIMAL_BALANCE,82        );83        await helper.assets.setMetadata(84          alice,85          USDT_ASSET_ID,86          USDT_ASSET_METADATA_NAME,87          USDT_ASSET_METADATA_DESCRIPTION,88          USDT_ASSET_METADATA_DECIMALS,89        );90      } else {91        console.log('The USDT asset is already registered on AssetHub');92      }9394      await helper.assets.mint(95        alice,96        USDT_ASSET_ID,97        alice.address,98        USDT_ASSET_AMOUNT,99      );100101      const sovereignFundingAmount = 3_500_000_000n;102103      // funding parachain sovereing account (Parachain: 2095)104      const parachainSovereingAccount = helper.address.paraSiblingSovereignAccount(UNIQUE_CHAIN);105      await helper.balance.transferToSubstrate(bob, parachainSovereingAccount, sovereignFundingAmount);106    });107108    await usingPlaygrounds(async (helper) => {109      const location = {110        parents: 1,111        interior: {X3: [112          {113            Parachain: STATEMINE_CHAIN,114          },115          {116            PalletInstance: STATEMINE_PALLET_INSTANCE,117          },118          {119            GeneralIndex: USDT_ASSET_ID,120          },121        ]},122      };123      const assetId = {Concrete: location};124125      if(await helper.foreignAssets.foreignCollectionId(assetId) == null) {126        const tokenPrefix = USDT_ASSET_METADATA_NAME;127        await helper.getSudo().foreignAssets.register(128          alice,129          assetId,130          USDT_ASSET_METADATA_NAME,131          tokenPrefix,132          {Fungible: USDT_ASSET_METADATA_DECIMALS},133        );134      } else {135        console.log('Foreign collection is already registered on Opal');136      }137138      balanceOpalBefore = await helper.balance.getSubstrate(alice.address);139      usdtCollectionId = await helper.foreignAssets.foreignCollectionId(assetId);140    });141142    // Providing the relay currency to the unique sender account143    await usingRelayPlaygrounds(relayUrl, async (helper) => {144      const destination = {145        V2: {146          parents: 0,147          interior: {X1: {148            Parachain: UNIQUE_CHAIN,149          },150          },151        }};152153      const beneficiary = {154        V2: {155          parents: 0,156          interior: {X1: {157            AccountId32: {158              network: 'Any',159              id: alice.addressRaw,160            },161          }},162        },163      };164165      const assets = {166        V2: [167          {168            id: {169              Concrete: {170                parents: 0,171                interior: 'Here',172              },173            },174            fun: {175              Fungible: 50_000_000_000_000_000n,176            },177          },178        ],179      };180181      const feeAssetItem = 0;182183      await helper.xcm.limitedReserveTransferAssets(alice, destination, beneficiary, assets, feeAssetItem, 'Unlimited');184    });185186  });187188  itSub('Should connect and send USDT from Westmint to Opal', async ({helper}) => {189    await usingWestmintPlaygrounds(westmintUrl, async (helper) => {190      const dest = {191        V2: {192          parents: 1,193          interior: {X1: {194            Parachain: UNIQUE_CHAIN,195          },196          },197        }};198199      const beneficiary = {200        V2: {201          parents: 0,202          interior: {X1: {203            AccountId32: {204              network: 'Any',205              id: alice.addressRaw,206            },207          }},208        },209      };210211      const assets = {212        V2: [213          {214            id: {215              Concrete: {216                parents: 0,217                interior: {218                  X2: [219                    {220                      PalletInstance: STATEMINE_PALLET_INSTANCE,221                    },222                    {223                      GeneralIndex: USDT_ASSET_ID,224                    },225                  ]},226              },227            },228            fun: {229              Fungible: TRANSFER_AMOUNT,230            },231          },232        ],233      };234235      const feeAssetItem = 0;236237      balanceStmnBefore = await helper.balance.getSubstrate(alice.address);238      await helper.xcm.limitedReserveTransferAssets(alice, dest, beneficiary, assets, feeAssetItem, 'Unlimited');239240      balanceStmnAfter = await helper.balance.getSubstrate(alice.address);241242      // common good parachain take commission in it native token243      console.log(244        '[Westmint -> Opal] transaction fees on Westmint: %s WND',245        helper.util.bigIntToDecimals(balanceStmnBefore - balanceStmnAfter, WESTMINT_DECIMALS),246      );247      expect(balanceStmnBefore > balanceStmnAfter).to.be.true;248249    });250251    // ensure that asset has been delivered252    await helper.wait.newBlocks(3);253254    const free = await helper.ft.getBalance(usdtCollectionId, {Substrate: alice.address});255256    balanceOpalAfter = await helper.balance.getSubstrate(alice.address);257258    console.log(259      '[Westmint -> Opal] transaction fees on Opal: %s USDT',260      helper.util.bigIntToDecimals(TRANSFER_AMOUNT - free, USDT_ASSET_METADATA_DECIMALS),261    );262    console.log(263      '[Westmint -> Opal] transaction fees on Opal: %s OPL',264      helper.util.bigIntToDecimals(balanceOpalAfter - balanceOpalBefore),265    );266267    // commission has not paid in USDT token268    expect(free == TRANSFER_AMOUNT).to.be.true;269    // ... and parachain native token270    expect(balanceOpalAfter == balanceOpalBefore).to.be.true;271  });272273  itSub('Should connect and send USDT from Unique to Statemine back', async ({helper}) => {274    const destination = {275      V2: {276        parents: 1,277        interior: {X2: [278          {279            Parachain: STATEMINE_CHAIN,280          },281          {282            AccountId32: {283              network: 'Any',284              id: alice.addressRaw,285            },286          },287        ]},288      },289    };290291    const currencies: [any, bigint][] = [292      [293        usdtCollectionId,294        TRANSFER_AMOUNT,295      ],296      [297        relayCollectionId,298        400_000_000_000_000n,299      ],300    ];301302    const feeItem = 1;303304    await helper.xTokens.transferMulticurrencies(alice, currencies, feeItem, destination, 'Unlimited');305306    // the commission has been paid in parachain native token307    balanceOpalFinal = await helper.balance.getSubstrate(alice.address);308    expect(balanceOpalAfter > balanceOpalFinal).to.be.true;309310    await usingWestmintPlaygrounds(westmintUrl, async (helper) => {311      await helper.wait.newBlocks(3);312313      // The USDT token never paid fees. Its amount not changed from begin value.314      // Also check that xcm transfer has been succeeded315      expect((await helper.assets.account(USDT_ASSET_ID, alice.address))! == USDT_ASSET_AMOUNT).to.be.true;316    });317  });318319  itSub('Should connect and send Relay token to Unique', async ({helper}) => {320    const TRANSFER_AMOUNT_RELAY = 50_000_000_000_000_000n;321322    balanceBobBefore = await helper.balance.getSubstrate(bob.address);323    balanceBobRelayTokenBefore = await helper.ft.getBalance(relayCollectionId, {Substrate: bob.address});324325    // Providing the relay currency to the unique sender account326    await usingRelayPlaygrounds(relayUrl, async (helper) => {327      const destination = {328        V2: {329          parents: 0,330          interior: {X1: {331            Parachain: UNIQUE_CHAIN,332          },333          },334        }};335336      const beneficiary = {337        V2: {338          parents: 0,339          interior: {X1: {340            AccountId32: {341              network: 'Any',342              id: bob.addressRaw,343            },344          }},345        },346      };347348      const assets = {349        V2: [350          {351            id: {352              Concrete: {353                parents: 0,354                interior: 'Here',355              },356            },357            fun: {358              Fungible: TRANSFER_AMOUNT_RELAY,359            },360          },361        ],362      };363364      const feeAssetItem = 0;365366      await helper.xcm.limitedReserveTransferAssets(bob, destination, beneficiary, assets, feeAssetItem, 'Unlimited');367    });368369    await helper.wait.newBlocks(3);370371    balanceBobAfter = await helper.balance.getSubstrate(bob.address);372    balanceBobRelayTokenAfter = await helper.ft.getBalance(relayCollectionId, {Substrate: bob.address});373374    const wndFee = balanceBobRelayTokenAfter - TRANSFER_AMOUNT_RELAY - balanceBobRelayTokenBefore;375    console.log(376      'Relay (Westend) to Opal transaction fees: %s OPL',377      helper.util.bigIntToDecimals(balanceBobAfter - balanceBobBefore),378    );379    console.log(380      'Relay (Westend) to Opal transaction fees: %s WND',381      helper.util.bigIntToDecimals(wndFee, WESTMINT_DECIMALS),382    );383    expect(balanceBobBefore == balanceBobAfter).to.be.true;384    expect(balanceBobRelayTokenBefore < balanceBobRelayTokenAfter).to.be.true;385  });386387  itSub('Should connect and send Relay token back', async ({helper}) => {388    let relayTokenBalanceBefore: bigint;389    let relayTokenBalanceAfter: bigint;390    await usingRelayPlaygrounds(relayUrl, async (helper) => {391      relayTokenBalanceBefore = await helper.balance.getSubstrate(bob.address);392    });393394    const destination = {395      V2: {396        parents: 1,397        interior: {398          X1:{399            AccountId32: {400              network: 'Any',401              id: bob.addressRaw,402            },403          },404        },405      },406    };407408    const currencies: any = [409      [410        relayCollectionId,411        50_000_000_000_000_000n,412      ],413    ];414415    const feeItem = 0;416417    await helper.xTokens.transferMulticurrencies(bob, currencies, feeItem, destination, 'Unlimited');418419    balanceBobFinal = await helper.balance.getSubstrate(bob.address);420    console.log('[Opal -> Relay (Westend)] transaction fees: %s OPL',  helper.util.bigIntToDecimals(balanceBobAfter - balanceBobFinal));421422    await usingRelayPlaygrounds(relayUrl, async (helper) => {423      await helper.wait.newBlocks(10);424      relayTokenBalanceAfter = await helper.balance.getSubstrate(bob.address);425426      const diff = relayTokenBalanceAfter - relayTokenBalanceBefore;427      console.log('[Opal -> Relay (Westend)] actually delivered: %s WND', helper.util.bigIntToDecimals(diff, RELAY_DECIMALS));428      expect(diff > 0, 'Relay tokens was not delivered back').to.be.true;429    });430  });431});