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 = 2037;32const ACALA_CHAIN = 2000;3334const ACALA_PORT = '9946';3536const TRANSFER_AMOUNT = 2000000000000000000000000n;3738describe('Integration test: Exchanging UNQ with Acala', () => {39 let alice: IKeyringPair;40 let randomAccount: IKeyringPair;41 42 let balanceUniqueTokenBefore: bigint;43 let balanceUniqueTokenAfter: bigint;44 let balanceUniqueTokenFinal: bigint;45 let balanceAcalaTokenBefore: bigint;46 let balanceAcalaTokenAfter: bigint;47 let balanceAcalaTokenFinal: bigint;48 let balanceUniqueForeignTokenAfter: bigint;49 let balanceUniqueForeignTokenBefore: bigint;50 let balanceUniqueForeignTokenFinal: bigint;51 52 before(async () => {53 await usingApi(async (api, privateKeyWrapper) => {54 alice = privateKeyWrapper('//Alice');55 randomAccount = generateKeyringPair();56 });57 58 const acalaApiOptions: ApiOptions = {59 provider: new WsProvider('ws://127.0.0.1:' + ACALA_PORT),60 };61 62 63 await usingApi(64 async (api) => {65 const destination = {66 V0: {67 X2: [68 'Parent',69 {70 Parachain: UNIQUE_CHAIN,71 },72 ],73 },74 };75 76 const metadata = {77 name: 'UNQ',78 symbol: 'UNQ',79 decimals: 18,80 minimalBalance: 1,81 };82 83 const tx = api.tx.assetRegistry.registerForeignAsset(destination, metadata);84 const sudoTx = api.tx.sudo.sudo(tx as any);85 const events = await submitTransactionAsync(alice, sudoTx);86 const result = getGenericResult(events);87 expect(result.success).to.be.true;88 89 const tx1 = api.tx.balances.transfer(randomAccount.address, 10000000000000n);90 const events1 = await submitTransactionAsync(alice, tx1);91 const result1 = getGenericResult(events1);92 expect(result1.success).to.be.true;93 94 [balanceAcalaTokenBefore] = await getBalance(api, [randomAccount.address]);95 {96 const {free} = (await api.query.tokens.accounts(randomAccount.addressRaw, {ForeignAsset: 0})).toJSON() as any;97 balanceUniqueForeignTokenBefore = BigInt(free);98 }99 },100 acalaApiOptions,101 );102 103 104 await usingApi(async (api) => {105 const tx0 = api.tx.balances.transfer(randomAccount.address, 10n * TRANSFER_AMOUNT);106 const events0 = await submitTransactionAsync(alice, tx0);107 const result0 = getGenericResult(events0);108 expect(result0.success).to.be.true;109 110 [balanceUniqueTokenBefore] = await getBalance(api, [randomAccount.address]);111 });112 });113 114 it('Should connect and send UNQ to Acala', async () => {115 116 117 await usingApi(async (api) => {118 119 const destination = {120 V0: {121 X2: [122 'Parent',123 {124 Parachain: ACALA_CHAIN,125 },126 ],127 },128 };129 130 const beneficiary = {131 V0: {132 X1: {133 AccountId32: {134 network: 'Any',135 id: randomAccount.addressRaw,136 },137 },138 },139 };140 141 const assets = {142 V1: [143 {144 id: {145 Concrete: {146 parents: 0,147 interior: 'Here',148 },149 },150 fun: {151 Fungible: TRANSFER_AMOUNT,152 },153 },154 ],155 };156 157 const feeAssetItem = 0;158 159 const weightLimit = {160 Limited: 5000000000,161 };162 163 const tx = api.tx.polkadotXcm.limitedReserveTransferAssets(destination, beneficiary, assets, feeAssetItem, weightLimit);164 const events = await submitTransactionAsync(randomAccount, tx);165 const result = getGenericResult(events);166 expect(result.success).to.be.true;167 168 [balanceUniqueTokenAfter] = await getBalance(api, [randomAccount.address]);169 170 const unqFees = balanceUniqueTokenBefore - balanceUniqueTokenAfter;171 console.log('[Unique -> Acala] transaction fees on Unique: %s UNQ', unqFees);172 expect(unqFees > 0n).to.be.true;173 });174 175 176 await usingApi(177 async (api) => {178 179 await waitNewBlocks(api, 3);180 const {free} = (await api.query.tokens.accounts(randomAccount.addressRaw, {ForeignAsset: 0})).toJSON() as any;181 balanceUniqueForeignTokenAfter = BigInt(free);182 183 [balanceAcalaTokenAfter] = await getBalance(api, [randomAccount.address]);184185 const acaFees = balanceAcalaTokenBefore - balanceAcalaTokenAfter;186 const unqDiffAfterIncomeTransfer = balanceUniqueForeignTokenAfter - balanceUniqueForeignTokenBefore;187188 const unqFees = unqDiffAfterIncomeTransfer - TRANSFER_AMOUNT;189190 console.log('[Unique -> Acala] transaction fees on Acala: %s ACA', acaFees);191 console.log('[Unique -> Acala] transaction fees on Acala: %s UNQ', unqFees);192 expect(acaFees == 0n).to.be.true;193 expect(unqFees == 0n).to.be.true;194 },195 {provider: new WsProvider('ws://127.0.0.1:' + ACALA_PORT)},196 );197 });198 199 it('Should connect to Acala and send UNQ back', async () => {200 201 202 await usingApi(203 async (api) => {204 const destination = {205 V1: {206 parents: 1,207 interior: {208 X2: [209 {Parachain: UNIQUE_CHAIN},210 {211 AccountId32: {212 network: 'Any',213 id: randomAccount.addressRaw,214 },215 },216 ],217 },218 },219 };220 221 const id = {222 ForeignAsset: 0,223 };224 225 const amount = TRANSFER_AMOUNT;226 const destWeight = 50000000;227 228 const tx = api.tx.xTokens.transfer(id, amount, destination, destWeight);229 const events = await submitTransactionAsync(randomAccount, tx);230 const result = getGenericResult(events);231 expect(result.success).to.be.true;232 233 [balanceAcalaTokenFinal] = await getBalance(api, [randomAccount.address]);234 {235 const {free} = (await api.query.tokens.accounts(randomAccount.addressRaw, {ForeignAsset: 0})).toJSON() as any;236 balanceUniqueForeignTokenFinal = BigInt(free);237 }238 239 const acaFees = balanceAcalaTokenAfter - balanceAcalaTokenFinal;240 const unqDiffAfterOutcomeTransfer = balanceUniqueForeignTokenAfter - TRANSFER_AMOUNT;241242 const unqFees = unqDiffAfterOutcomeTransfer - balanceUniqueForeignTokenFinal;243244 console.log('[Acala -> Unique] transaction fees on Acala: %s ACA', acaFees);245 console.log('[Acala -> Unique] transaction fees on Acala: %s UNQ', unqFees);246247 expect(acaFees > 0).to.be.true;248 expect(unqFees == 0n).to.be.true;249 },250 {provider: new WsProvider('ws://127.0.0.1:' + ACALA_PORT)},251 );252253 254 await usingApi(async (api) => {255 256 await waitNewBlocks(api, 3);257 258 [balanceUniqueTokenFinal] = await getBalance(api, [randomAccount.address]);259 const actuallyDelivered = balanceUniqueTokenFinal - balanceUniqueTokenAfter;260 expect(actuallyDelivered > 0).to.be.true;261 262 const unqFees = TRANSFER_AMOUNT - actuallyDelivered;263 console.log('[Acala -> Unique] transaction fees on Unique: %s UNQ', unqFees);264 expect(unqFees == 0n).to.be.true;265 });266 });267});