1234567891011121314151617import 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, generateKeyringPair} from './util/helpers';25import waitNewBlocks from './substrate/wait-new-blocks';26import getBalance from './substrate/get-balance';2728chai.use(chaiAsPromised);29const expect = chai.expect;3031const UNIQUE_CHAIN = 5000;32const ACALA_CHAIN = 2000;33const ACALA_PORT = '9946';34const TRANSFER_AMOUNT = 2000000000000000000000000n;3536describe('Integration test: Exchanging UNQ with Acala', () => {37 let alice: IKeyringPair;38 let randomAccount: IKeyringPair;3940 let balanceUniqueTokenBefore: bigint;41 let balanceUniqueTokenAfter: bigint;42 let balanceUniqueTokenFinal: bigint;43 let balanceAcalaTokenBefore: bigint;44 let balanceAcalaTokenAfter: bigint;45 let balanceAcalaTokenFinal: bigint;46 let balanceUniqueForeignTokenAfter: bigint;47 let balanceUniqueForeignTokenBefore: bigint;48 let balanceUniqueForeignTokenFinal: bigint;4950 before(async () => {51 await usingApi(async (api, privateKeyWrapper) => {52 alice = privateKeyWrapper('//Alice');53 randomAccount = generateKeyringPair();54 });5556 const acalaApiOptions: ApiOptions = {57 provider: new WsProvider('ws://127.0.0.1:' + ACALA_PORT),58 };5960 await usingApi(61 async (api) => {62 const destination = {63 V0: {64 X2: [65 'Parent',66 {67 Parachain: UNIQUE_CHAIN,68 },69 ],70 },71 };7273 const metadata = {74 name: 'UNQ',75 symbol: 'UNQ',76 decimals: 18,77 minimalBalance: 1,78 };7980 const tx = api.tx.assetRegistry.registerForeignAsset(destination, metadata);81 const sudoTx = api.tx.sudo.sudo(tx as any);82 const events = await submitTransactionAsync(alice, sudoTx);83 const result = getGenericResult(events);84 expect(result.success).to.be.true;8586 const tx1 = api.tx.balances.transfer(randomAccount.address, 10000000000000n);87 const events1 = await submitTransactionAsync(alice, tx1);88 const result1 = getGenericResult(events1);89 expect(result1.success).to.be.true;9091 [balanceAcalaTokenBefore] = await getBalance(api, [randomAccount.address]);92 {93 const {free} = (await api.query.tokens.accounts(alice.addressRaw, {ForeignAsset: 0})).toJSON() as any;94 balanceUniqueForeignTokenBefore = BigInt(free);95 }96 },97 acalaApiOptions,98 );99100 await usingApi(async (api) => {101 const tx0 = api.tx.balances.transfer(randomAccount.address, 10n * TRANSFER_AMOUNT);102 const events0 = await submitTransactionAsync(alice, tx0);103 const result0 = getGenericResult(events0);104 expect(result0.success).to.be.true;105106 [balanceUniqueTokenBefore] = await getBalance(api, [randomAccount.address]);107 });108 });109110 it('Should connect and send UNQ to Acala', async () => {111112 await usingApi(async (api) => {113114 const destination = {115 V0: {116 X2: [117 'Parent',118 {119 Parachain: ACALA_CHAIN,120 },121 ],122 },123 };124125 const beneficiary = {126 V0: {127 X1: {128 AccountId32: {129 network: 'Any',130 id: randomAccount.addressRaw,131 },132 },133 },134 };135136 const assets = {137 V1: [138 {139 id: {140 Concrete: {141 parents: 0,142 interior: 'Here',143 },144 },145 fun: {146 Fungible: TRANSFER_AMOUNT,147 },148 },149 ],150 };151152 const feeAssetItem = 0;153154 const weightLimit = {155 Limited: 5000000000,156 };157158 const tx = api.tx.polkadotXcm.limitedReserveTransferAssets(destination, beneficiary, assets, feeAssetItem, weightLimit);159 const events = await submitTransactionAsync(randomAccount, tx);160 const result = getGenericResult(events);161 expect(result.success).to.be.true;162163 [balanceUniqueTokenAfter] = await getBalance(api, [randomAccount.address]);164165 expect((balanceUniqueTokenBefore - balanceUniqueTokenAfter) > 0n).to.be.true;166 });167168 await usingApi(169 async (api) => {170 171 await waitNewBlocks(api, 3);172 const {free} = (await api.query.tokens.accounts(randomAccount.addressRaw, {ForeignAsset: 0})).toJSON() as any;173 balanceUniqueForeignTokenAfter = BigInt(free);174175 [balanceAcalaTokenAfter] = await getBalance(api, [randomAccount.address]);176 const acaFees = balanceAcalaTokenBefore - balanceAcalaTokenAfter;177 const unqFees = balanceUniqueForeignTokenBefore - balanceUniqueForeignTokenAfter;178 console.log('Unique to Acala transaction fees on Acala: %s ACA', acaFees);179 console.log('Unique to Acala transaction fees on Acala: %s UNQ', unqFees);180 expect(acaFees == 0n).to.be.true;181 expect(unqFees == 0n).to.be.true;182 },183 {provider: new WsProvider('ws://127.0.0.1:' + ACALA_PORT)},184 );185 });186187 it('Should connect to Acala and send UNQ back', async () => {188189 await usingApi(190 async (api) => {191 const destination = {192 V1: {193 parents: 1,194 interior: {195 X2: [196 {Parachain: UNIQUE_CHAIN},197 {198 AccountId32: {199 network: 'Any',200 id: randomAccount.addressRaw,201 },202 },203 ],204 },205 },206 };207208 const id = {209 ForeignAsset: 0,210 };211212 const amount = TRANSFER_AMOUNT;213 const destWeight = 50000000;214215 const tx = api.tx.xTokens.transfer(id, amount, destination, destWeight);216 const events = await submitTransactionAsync(randomAccount, tx);217 const result = getGenericResult(events);218 expect(result.success).to.be.true;219220 [balanceAcalaTokenFinal] = await getBalance(api, [randomAccount.address]);221 {222 const {free} = (await api.query.tokens.accounts(randomAccount.addressRaw, {ForeignAsset: 0})).toJSON() as any;223 balanceUniqueForeignTokenFinal = BigInt(free);224 }225226 const acaFees = balanceAcalaTokenFinal - balanceAcalaTokenAfter;227 const unqFees = balanceUniqueForeignTokenFinal - balanceUniqueForeignTokenAfter;228 console.log('Acala to Unique transaction fees on Acala: %s ACA', acaFees);229 console.log('Acala to Unique transaction fees on Acala: %s UNQ', unqFees);230 expect(acaFees > 0).to.be.true;231 expect(unqFees == 0n).to.be.true;232 },233 {provider: new WsProvider('ws://127.0.0.1:' + ACALA_PORT)},234 );235236 await usingApi(async (api) => {237 238 await waitNewBlocks(api, 3);239240 [balanceUniqueTokenFinal] = await getBalance(api, [randomAccount.address]);241 const actuallyDelivered = balanceUniqueTokenFinal - balanceUniqueTokenAfter;242 expect(actuallyDelivered > 0).to.be.true;243244 const unqFees = TRANSFER_AMOUNT - actuallyDelivered;245 console.log('Acala to Unique transaction fees on Unique: %s UNQ', unqFees);246 expect(unqFees > 0).to.be.true;247 });248 });249});