git.delta.rocks / unique-network / refs/commits / 28d7737590e5

difftreelog

Transaction commisions displayed

Dev2022-09-06parent: #0d218a2.patch.diff
in: master

1 file changed

modifiedtests/src/xcm/xcmOpal.test.tsdiffbeforeafterboth
before · tests/src/xcm/xcmOpal.test.ts
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 chai from 'chai';18import chaiAsPromised from 'chai-as-promised';1920import {WsProvider} from '@polkadot/api';21import {ApiOptions} from '@polkadot/api/types';22import {IKeyringPair} from '@polkadot/types/types';23import usingApi, {submitTransactionAsync} from './../substrate/substrate-api';24import {getGenericResult, paraSiblingSovereignAccount} from './../util/helpers';25import waitNewBlocks from './../substrate/wait-new-blocks';26import {normalizeAccountId} from './../util/helpers';27import getBalance from './../substrate/get-balance';282930chai.use(chaiAsPromised);31const expect = chai.expect;3233const STATEMINE_CHAIN = 1000;34const UNIQUE_CHAIN = 2095;3536const RELAY_PORT = '9844';37const UNIQUE_PORT = '9944';38const STATEMINE_PORT = '9946';39const STATEMINE_PALLET_INSTANCE = 50;40const ASSET_ID = 100;41const ASSET_METADATA_DECIMALS = 18;42const ASSET_METADATA_NAME = 'USDT';43const ASSET_METADATA_DESCRIPTION = 'USDT';44const ASSET_METADATA_MINIMAL_BALANCE = 1;4546const TRANSFER_AMOUNT = 1_000_000_000_000_000_000n;4748// 10,000.00 (ten thousands) USDT49const ASSET_AMOUNT = 1_000_000_000_000_000_000_000n; 5051describe('Integration test: Exchanging USDT with Statemine', () => {52  let alice: IKeyringPair;53  let bob: IKeyringPair;54  55  let balanceStmnBefore: bigint;56  let balanceStmnAfter: bigint;5758  let balanceOpalBefore: bigint;59  let balanceOpalAfter: bigint;60  let balanceOpalFinal: bigint;6162  let balanceBobBefore: bigint;63  let balanceBobAfter: bigint;64  let balanceBobFinal: bigint;6566  before(async () => {67    await usingApi(async (api, privateKeyWrapper) => {68      alice = privateKeyWrapper('//Alice');69      bob = privateKeyWrapper('//Bob'); // funds donor70    });7172    const statemineApiOptions: ApiOptions = {73      provider: new WsProvider('ws://127.0.0.1:' + STATEMINE_PORT),74    };7576    const uniqueApiOptions: ApiOptions = {77      provider: new WsProvider('ws://127.0.0.1:' + UNIQUE_PORT),78    };7980    const relayApiOptions: ApiOptions = {81      provider: new WsProvider('ws://127.0.0.1:' + RELAY_PORT),82    };8384    await usingApi(async (api) => {8586      // 350.00 (three hundred fifty) DOT87      const fundingAmount = 3_500_000_000_000; 8889      const tx = api.tx.assets.create(ASSET_ID, alice.addressRaw, ASSET_METADATA_MINIMAL_BALANCE);90      const events = await submitTransactionAsync(alice, tx);91      const result = getGenericResult(events);92      expect(result.success).to.be.true;9394      // set metadata95      const tx2 = api.tx.assets.setMetadata(ASSET_ID, ASSET_METADATA_NAME, ASSET_METADATA_DESCRIPTION, ASSET_METADATA_DECIMALS);96      const events2 = await submitTransactionAsync(alice, tx2);97      const result2 = getGenericResult(events2);98      expect(result2.success).to.be.true;99100      // mint some amount of asset101      const tx3 = api.tx.assets.mint(ASSET_ID, alice.addressRaw, ASSET_AMOUNT);102      const events3 = await submitTransactionAsync(alice, tx3);103      const result3 = getGenericResult(events3);104      expect(result3.success).to.be.true;105106      // funding parachain sovereing account (Parachain: 2095)107      const parachainSovereingAccount = await paraSiblingSovereignAccount(UNIQUE_CHAIN);108      const tx4 = api.tx.balances.transfer(parachainSovereingAccount, fundingAmount);109      const events4 = await submitTransactionAsync(bob, tx4);110      const result4 = getGenericResult(events4);111      expect(result4.success).to.be.true;112113    }, statemineApiOptions);114115116    await usingApi(async (api) => {117118      const location = {119        V1: {120          parents: 1,121          interior: {X3: [122            {123              Parachain: STATEMINE_CHAIN,124            },125            {126              PalletInstance: STATEMINE_PALLET_INSTANCE,127            },128            {129              GeneralIndex: ASSET_ID,130            },131          ]},132        },133      };134135      const metadata =136      {137        name: ASSET_ID,138        symbol: ASSET_METADATA_NAME,139        decimals: ASSET_METADATA_DECIMALS,140        minimalBalance: ASSET_METADATA_MINIMAL_BALANCE,141      };142      //registerForeignAsset(owner, location, metadata)143      const tx = api.tx.foreingAssets.registerForeignAsset(alice.addressRaw, location, metadata);144      const sudoTx = api.tx.sudo.sudo(tx as any);145      const events = await submitTransactionAsync(alice, sudoTx);146      const result = getGenericResult(events);147      expect(result.success).to.be.true;148149      [balanceOpalBefore] = await getBalance(api, [alice.address]);150151    }, uniqueApiOptions);152153154    // Providing the relay currency to the unique sender account155    await usingApi(async (api) => {156      const destination = {157        V1: {158          parents: 0,159          interior: {X1: {160            Parachain: UNIQUE_CHAIN,161          },162          },163        }};164165      const beneficiary = {166        V1: {167          parents: 0,168          interior: {X1: {169            AccountId32: {170              network: 'Any',171              id: alice.addressRaw,172            },173          }},174        },175      };176177      const assets = {178        V1: [179          {180            id: {181              Concrete: {182                parents: 0,183                interior: 'Here',184              },185            },186            fun: {187              Fungible: 50_000_000_000_000_000n,188            },189          },190        ],191      };192193      const feeAssetItem = 0;194195      const weightLimit = {196        Limited: 5_000_000_000,197      };198199      const tx = api.tx.xcmPallet.limitedReserveTransferAssets(destination, beneficiary, assets, feeAssetItem, weightLimit);200      const events = await submitTransactionAsync(alice, tx);201      const result = getGenericResult(events);202      expect(result.success).to.be.true;203    }, relayApiOptions);204  205  });206207  it('Should connect and send USDT from Statemine to Unique', async () => {208    209    const statemineApiOptions: ApiOptions = {210      provider: new WsProvider('ws://127.0.0.1:' + STATEMINE_PORT),211    };212213    const uniqueApiOptions: ApiOptions = {214      provider: new WsProvider('ws://127.0.0.1:' + UNIQUE_PORT),215    };216217    await usingApi(async (api) => {218219      const dest = {220        V1: {221          parents: 1,222          interior: {X1: {223            Parachain: UNIQUE_CHAIN,224          },225          },226        }};227228      const beneficiary = {229        V1: {230          parents: 0,231          interior: {X1: {232            AccountId32: {233              network: 'Any',234              id: alice.addressRaw,235            },236          }},237        },238      };239240      const assets = {241        V1: [242          {243            id: {244              Concrete: {245                parents: 0,246                interior: {247                  X2: [248                    {249                      PalletInstance: STATEMINE_PALLET_INSTANCE,250                    },251                    {252                      GeneralIndex: ASSET_ID,253                    }, 254                  ]},255              },256            },257            fun: {258              Fungible: TRANSFER_AMOUNT,259            },260          },261        ],262      };263264      const feeAssetItem = 0;265266      const weightLimit = {267        Limited: 5000000000,268      };269270      [balanceStmnBefore] = await getBalance(api, [alice.address]);271272      const tx = api.tx.polkadotXcm.limitedReserveTransferAssets(dest, beneficiary, assets, feeAssetItem, weightLimit);273      const events = await submitTransactionAsync(alice, tx);274      const result = getGenericResult(events);275      expect(result.success).to.be.true;276277      [balanceStmnAfter] = await getBalance(api, [alice.address]);278279      // common good parachain take commission in it native token280      expect(balanceStmnBefore > balanceStmnAfter).to.be.true;281282    }, statemineApiOptions);283284285    // ensure that asset has been delivered286    await usingApi(async (api) => {287      await waitNewBlocks(api, 3);288      // expext collection id will be with id 1289      const free = (await api.query.fungible.balance(1, normalizeAccountId(alice.address))).toBigInt();290291      [balanceOpalAfter] = await getBalance(api, [alice.address]);292293      // commission has not paid in USDT token294      expect(free == TRANSFER_AMOUNT).to.be.true;295      // ... and parachain native token296      expect(balanceOpalAfter == balanceOpalBefore).to.be.true;297298299    }, uniqueApiOptions);300    301  });302303  it('Should connect and send USDT from Unique to Statemine back', async () => {304305    const uniqueApiOptions: ApiOptions = {306      provider: new WsProvider('ws://127.0.0.1:' + UNIQUE_PORT),307    };308309    const statemineApiOptions: ApiOptions = {310      provider: new WsProvider('ws://127.0.0.1:' + STATEMINE_PORT),311    };312313    await usingApi(async (api) => {314      const destination = {315        V1: {316          parents: 1,317          interior: {X2: [318            {319              Parachain: STATEMINE_CHAIN,320            },321            {322              AccountId32: {323                network: 'Any',324                id: alice.addressRaw,325              },326            },327          ]},328        },329      };330331      const currencies = [[332        {333          ForeignAssetId: 0,334        },335        //10_000_000_000_000_000n,336        TRANSFER_AMOUNT,337      ], 338      [339        {340          NativeAssetId: 'Parent',341        },342        400_000_000_000_000n,343      ]];344345      const feeItem = 1;346      const destWeight = 500000000000;347348      const tx = api.tx.xTokens.transferMulticurrencies(currencies, feeItem, destination, destWeight);349      const events = await submitTransactionAsync(alice, tx);350      const result = getGenericResult(events);351      expect(result.success).to.be.true;352      353      // the commission has been paid in parachain native token354      [balanceOpalFinal] = await getBalance(api, [alice.address]);355      expect(balanceOpalAfter > balanceOpalFinal).to.be.true;356    }, uniqueApiOptions);357358    await usingApi(async (api) => {359      await waitNewBlocks(api, 3);360      361      // The USDT token never paid fees. Its amount not changed from begin value.362      // Also check that xcm transfer has been succeeded 363      const free = ((await api.query.assets.account(100, alice.address)).toHuman()) as any;364      expect(BigInt(free.balance.replace(/,/g, '')) == ASSET_AMOUNT).to.be.true;365    }, statemineApiOptions);366  });367368  it('Should connect and send Relay token to Unique', async () => {369370    const uniqueApiOptions: ApiOptions = {371      provider: new WsProvider('ws://127.0.0.1:' + UNIQUE_PORT),372    };373374    const uniqueApiOptions2: ApiOptions = {375      provider: new WsProvider('ws://127.0.0.1:' + UNIQUE_PORT),376    };377378    const relayApiOptions: ApiOptions = {379      provider: new WsProvider('ws://127.0.0.1:' + RELAY_PORT),380    };381382    await usingApi(async (api) => {383      [balanceBobBefore] = await getBalance(api, [alice.address]);384    }, uniqueApiOptions);385386    // Providing the relay currency to the unique sender account387    await usingApi(async (api) => {388      const destination = {389        V1: {390          parents: 0,391          interior: {X1: {392            Parachain: UNIQUE_CHAIN,393          },394          },395        }};396397      const beneficiary = {398        V1: {399          parents: 0,400          interior: {X1: {401            AccountId32: {402              network: 'Any',403              id: bob.addressRaw,404            },405          }},406        },407      };408409      const assets = {410        V1: [411          {412            id: {413              Concrete: {414                parents: 0,415                interior: 'Here',416              },417            },418            fun: {419              Fungible: 50_000_000_000_000_000n,420            },421          },422        ],423      };424425      const feeAssetItem = 0;426427      const weightLimit = {428        Limited: 5_000_000_000,429      };430431      const tx = api.tx.xcmPallet.limitedReserveTransferAssets(destination, beneficiary, assets, feeAssetItem, weightLimit);432      const events = await submitTransactionAsync(bob, tx);433      const result = getGenericResult(events);434      expect(result.success).to.be.true;435    }, relayApiOptions);436  437438    await usingApi(async (api) => {439      await waitNewBlocks(api, 3);440441      [balanceBobAfter] = await getBalance(api, [alice.address]);442      expect(balanceBobBefore == balanceBobAfter).to.be.true;443    }, uniqueApiOptions2);444445  });446447  it('Should connect and send Relay token back', async () => {448449    const uniqueApiOptions: ApiOptions = {450      provider: new WsProvider('ws://127.0.0.1:' + UNIQUE_PORT),451    };452453    await usingApi(async (api) => {454      const destination = {455        V1: {456          parents: 1,457          interior: {X2: [458            {459              Parachain: STATEMINE_CHAIN,460            },461            {462              AccountId32: {463                network: 'Any',464                id: bob.addressRaw,465              },466            },467          ]},468        },469      };470471      const currencies = [472        [473          {474            NativeAssetId: 'Parent',475          },476          50_000_000_000_000_000n,477        ]];478479      const feeItem = 0;480      const destWeight = 500000000000;481482      const tx = api.tx.xTokens.transferMulticurrencies(currencies, feeItem, destination, destWeight);483      const events = await submitTransactionAsync(bob, tx);484      const result = getGenericResult(events);485      expect(result.success).to.be.true;486    }, uniqueApiOptions);487  });488489});
after · tests/src/xcm/xcmOpal.test.ts
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 chai from 'chai';18import chaiAsPromised from 'chai-as-promised';1920import {WsProvider} from '@polkadot/api';21import {ApiOptions} from '@polkadot/api/types';22import {IKeyringPair} from '@polkadot/types/types';23import usingApi, {submitTransactionAsync} from './../substrate/substrate-api';24import {getGenericResult, paraSiblingSovereignAccount} from './../util/helpers';25import waitNewBlocks from './../substrate/wait-new-blocks';26import {normalizeAccountId} from './../util/helpers';27import getBalance from './../substrate/get-balance';282930chai.use(chaiAsPromised);31const expect = chai.expect;3233const STATEMINE_CHAIN = 1000;34const UNIQUE_CHAIN = 2095;3536const RELAY_PORT = '9844';37const UNIQUE_PORT = '9944';38const STATEMINE_PORT = '9946';39const STATEMINE_PALLET_INSTANCE = 50;40const ASSET_ID = 100;41const ASSET_METADATA_DECIMALS = 18;42const ASSET_METADATA_NAME = 'USDT';43const ASSET_METADATA_DESCRIPTION = 'USDT';44const ASSET_METADATA_MINIMAL_BALANCE = 1;4546const TRANSFER_AMOUNT = 1_000_000_000_000_000_000n;4748// 10,000.00 (ten thousands) USDT49const ASSET_AMOUNT = 1_000_000_000_000_000_000_000n; 5051describe('Integration test: Exchanging USDT with Westmint', () => {52  let alice: IKeyringPair;53  let bob: IKeyringPair;54  55  let balanceStmnBefore: bigint;56  let balanceStmnAfter: bigint;5758  let balanceOpalBefore: bigint;59  let balanceOpalAfter: bigint;60  let balanceOpalFinal: bigint;6162  let balanceBobBefore: bigint;63  let balanceBobAfter: bigint;6465  before(async () => {66    await usingApi(async (api, privateKeyWrapper) => {67      alice = privateKeyWrapper('//Alice');68      bob = privateKeyWrapper('//Bob'); // funds donor69    });7071    const statemineApiOptions: ApiOptions = {72      provider: new WsProvider('ws://127.0.0.1:' + STATEMINE_PORT),73    };7475    const uniqueApiOptions: ApiOptions = {76      provider: new WsProvider('ws://127.0.0.1:' + UNIQUE_PORT),77    };7879    const relayApiOptions: ApiOptions = {80      provider: new WsProvider('ws://127.0.0.1:' + RELAY_PORT),81    };8283    await usingApi(async (api) => {8485      // 350.00 (three hundred fifty) DOT86      const fundingAmount = 3_500_000_000_000; 8788      const tx = api.tx.assets.create(ASSET_ID, alice.addressRaw, ASSET_METADATA_MINIMAL_BALANCE);89      const events = await submitTransactionAsync(alice, tx);90      const result = getGenericResult(events);91      expect(result.success).to.be.true;9293      // set metadata94      const tx2 = api.tx.assets.setMetadata(ASSET_ID, ASSET_METADATA_NAME, ASSET_METADATA_DESCRIPTION, ASSET_METADATA_DECIMALS);95      const events2 = await submitTransactionAsync(alice, tx2);96      const result2 = getGenericResult(events2);97      expect(result2.success).to.be.true;9899      // mint some amount of asset100      const tx3 = api.tx.assets.mint(ASSET_ID, alice.addressRaw, ASSET_AMOUNT);101      const events3 = await submitTransactionAsync(alice, tx3);102      const result3 = getGenericResult(events3);103      expect(result3.success).to.be.true;104105      // funding parachain sovereing account (Parachain: 2095)106      const parachainSovereingAccount = await paraSiblingSovereignAccount(UNIQUE_CHAIN);107      const tx4 = api.tx.balances.transfer(parachainSovereingAccount, fundingAmount);108      const events4 = await submitTransactionAsync(bob, tx4);109      const result4 = getGenericResult(events4);110      expect(result4.success).to.be.true;111112    }, statemineApiOptions);113114115    await usingApi(async (api) => {116117      const location = {118        V1: {119          parents: 1,120          interior: {X3: [121            {122              Parachain: STATEMINE_CHAIN,123            },124            {125              PalletInstance: STATEMINE_PALLET_INSTANCE,126            },127            {128              GeneralIndex: ASSET_ID,129            },130          ]},131        },132      };133134      const metadata =135      {136        name: ASSET_ID,137        symbol: ASSET_METADATA_NAME,138        decimals: ASSET_METADATA_DECIMALS,139        minimalBalance: ASSET_METADATA_MINIMAL_BALANCE,140      };141      //registerForeignAsset(owner, location, metadata)142      const tx = api.tx.foreingAssets.registerForeignAsset(alice.addressRaw, location, metadata);143      const sudoTx = api.tx.sudo.sudo(tx as any);144      const events = await submitTransactionAsync(alice, sudoTx);145      const result = getGenericResult(events);146      expect(result.success).to.be.true;147148      [balanceOpalBefore] = await getBalance(api, [alice.address]);149150    }, uniqueApiOptions);151152153    // Providing the relay currency to the unique sender account154    await usingApi(async (api) => {155      const destination = {156        V1: {157          parents: 0,158          interior: {X1: {159            Parachain: UNIQUE_CHAIN,160          },161          },162        }};163164      const beneficiary = {165        V1: {166          parents: 0,167          interior: {X1: {168            AccountId32: {169              network: 'Any',170              id: alice.addressRaw,171            },172          }},173        },174      };175176      const assets = {177        V1: [178          {179            id: {180              Concrete: {181                parents: 0,182                interior: 'Here',183              },184            },185            fun: {186              Fungible: 50_000_000_000_000_000n,187            },188          },189        ],190      };191192      const feeAssetItem = 0;193194      const weightLimit = {195        Limited: 5_000_000_000,196      };197198      const tx = api.tx.xcmPallet.limitedReserveTransferAssets(destination, beneficiary, assets, feeAssetItem, weightLimit);199      const events = await submitTransactionAsync(alice, tx);200      const result = getGenericResult(events);201      expect(result.success).to.be.true;202    }, relayApiOptions);203  204  });205206  it('Should connect and send USDT from Westmint to Opal', async () => {207    208    const statemineApiOptions: ApiOptions = {209      provider: new WsProvider('ws://127.0.0.1:' + STATEMINE_PORT),210    };211212    const uniqueApiOptions: ApiOptions = {213      provider: new WsProvider('ws://127.0.0.1:' + UNIQUE_PORT),214    };215216    await usingApi(async (api) => {217218      const dest = {219        V1: {220          parents: 1,221          interior: {X1: {222            Parachain: UNIQUE_CHAIN,223          },224          },225        }};226227      const beneficiary = {228        V1: {229          parents: 0,230          interior: {X1: {231            AccountId32: {232              network: 'Any',233              id: alice.addressRaw,234            },235          }},236        },237      };238239      const assets = {240        V1: [241          {242            id: {243              Concrete: {244                parents: 0,245                interior: {246                  X2: [247                    {248                      PalletInstance: STATEMINE_PALLET_INSTANCE,249                    },250                    {251                      GeneralIndex: ASSET_ID,252                    }, 253                  ]},254              },255            },256            fun: {257              Fungible: TRANSFER_AMOUNT,258            },259          },260        ],261      };262263      const feeAssetItem = 0;264265      const weightLimit = {266        Limited: 5000000000,267      };268269      [balanceStmnBefore] = await getBalance(api, [alice.address]);270271      const tx = api.tx.polkadotXcm.limitedReserveTransferAssets(dest, beneficiary, assets, feeAssetItem, weightLimit);272      const events = await submitTransactionAsync(alice, tx);273      const result = getGenericResult(events);274      expect(result.success).to.be.true;275276      [balanceStmnAfter] = await getBalance(api, [alice.address]);277278      // common good parachain take commission in it native token279      console.log('Opal to Westmint transaction fees on Westmint: %s WND', balanceStmnBefore - balanceStmnAfter);280      expect(balanceStmnBefore > balanceStmnAfter).to.be.true;281282    }, statemineApiOptions);283284285    // ensure that asset has been delivered286    await usingApi(async (api) => {287      await waitNewBlocks(api, 3);288      // expext collection id will be with id 1289      const free = (await api.query.fungible.balance(1, normalizeAccountId(alice.address))).toBigInt();290291      [balanceOpalAfter] = await getBalance(api, [alice.address]);292293      // commission has not paid in USDT token294      expect(free == TRANSFER_AMOUNT).to.be.true;295      console.log('Opal to Westmint transaction fees on Opal: %s USDT', TRANSFER_AMOUNT - free);296      // ... and parachain native token297      expect(balanceOpalAfter == balanceOpalBefore).to.be.true;298      console.log('Opal to Westmint transaction fees on Opal: %s WND', balanceOpalAfter - balanceOpalBefore);299300    }, uniqueApiOptions);301    302  });303304  it('Should connect and send USDT from Unique to Statemine back', async () => {305306    const uniqueApiOptions: ApiOptions = {307      provider: new WsProvider('ws://127.0.0.1:' + UNIQUE_PORT),308    };309310    const statemineApiOptions: ApiOptions = {311      provider: new WsProvider('ws://127.0.0.1:' + STATEMINE_PORT),312    };313314    await usingApi(async (api) => {315      const destination = {316        V1: {317          parents: 1,318          interior: {X2: [319            {320              Parachain: STATEMINE_CHAIN,321            },322            {323              AccountId32: {324                network: 'Any',325                id: alice.addressRaw,326              },327            },328          ]},329        },330      };331332      const currencies = [[333        {334          ForeignAssetId: 0,335        },336        //10_000_000_000_000_000n,337        TRANSFER_AMOUNT,338      ], 339      [340        {341          NativeAssetId: 'Parent',342        },343        400_000_000_000_000n,344      ]];345346      const feeItem = 1;347      const destWeight = 500000000000;348349      const tx = api.tx.xTokens.transferMulticurrencies(currencies, feeItem, destination, destWeight);350      const events = await submitTransactionAsync(alice, tx);351      const result = getGenericResult(events);352      expect(result.success).to.be.true;353      354      // the commission has been paid in parachain native token355      [balanceOpalFinal] = await getBalance(api, [alice.address]);356      expect(balanceOpalAfter > balanceOpalFinal).to.be.true;357    }, uniqueApiOptions);358359    await usingApi(async (api) => {360      await waitNewBlocks(api, 3);361      362      // The USDT token never paid fees. Its amount not changed from begin value.363      // Also check that xcm transfer has been succeeded 364      const free = ((await api.query.assets.account(100, alice.address)).toHuman()) as any;365      expect(BigInt(free.balance.replace(/,/g, '')) == ASSET_AMOUNT).to.be.true;366    }, statemineApiOptions);367  });368369  it('Should connect and send Relay token to Unique', async () => {370371    const uniqueApiOptions: ApiOptions = {372      provider: new WsProvider('ws://127.0.0.1:' + UNIQUE_PORT),373    };374375    const uniqueApiOptions2: ApiOptions = {376      provider: new WsProvider('ws://127.0.0.1:' + UNIQUE_PORT),377    };378379    const relayApiOptions: ApiOptions = {380      provider: new WsProvider('ws://127.0.0.1:' + RELAY_PORT),381    };382383    await usingApi(async (api) => {384      [balanceBobBefore] = await getBalance(api, [alice.address]);385    }, uniqueApiOptions);386387    // Providing the relay currency to the unique sender account388    await usingApi(async (api) => {389      const destination = {390        V1: {391          parents: 0,392          interior: {X1: {393            Parachain: UNIQUE_CHAIN,394          },395          },396        }};397398      const beneficiary = {399        V1: {400          parents: 0,401          interior: {X1: {402            AccountId32: {403              network: 'Any',404              id: bob.addressRaw,405            },406          }},407        },408      };409410      const assets = {411        V1: [412          {413            id: {414              Concrete: {415                parents: 0,416                interior: 'Here',417              },418            },419            fun: {420              Fungible: 50_000_000_000_000_000n,421            },422          },423        ],424      };425426      const feeAssetItem = 0;427428      const weightLimit = {429        Limited: 5_000_000_000,430      };431432      const tx = api.tx.xcmPallet.limitedReserveTransferAssets(destination, beneficiary, assets, feeAssetItem, weightLimit);433      const events = await submitTransactionAsync(bob, tx);434      const result = getGenericResult(events);435      expect(result.success).to.be.true;436    }, relayApiOptions);437  438439    await usingApi(async (api) => {440      await waitNewBlocks(api, 3);441442      [balanceBobAfter] = await getBalance(api, [alice.address]);443      expect(balanceBobBefore == balanceBobAfter).to.be.true;444      console.log('Relay (Westend) to Opal transaction fees: %s OPL', balanceBobAfter - balanceBobBefore);445446    }, uniqueApiOptions2);447448  });449450  it('Should connect and send Relay token back', async () => {451452    const uniqueApiOptions: ApiOptions = {453      provider: new WsProvider('ws://127.0.0.1:' + UNIQUE_PORT),454    };455456    await usingApi(async (api) => {457      const destination = {458        V1: {459          parents: 1,460          interior: {X2: [461            {462              Parachain: STATEMINE_CHAIN,463            },464            {465              AccountId32: {466                network: 'Any',467                id: bob.addressRaw,468              },469            },470          ]},471        },472      };473474      const currencies = [475        [476          {477            NativeAssetId: 'Parent',478          },479          50_000_000_000_000_000n,480        ]];481482      const feeItem = 0;483      const destWeight = 500000000000;484485      const tx = api.tx.xTokens.transferMulticurrencies(currencies, feeItem, destination, destWeight);486      const events = await submitTransactionAsync(bob, tx);487      const result = getGenericResult(events);488      expect(result.success).to.be.true;489    }, uniqueApiOptions);490  });491492});