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} from './util/helpers';25import waitNewBlocks from './substrate/wait-new-blocks';26import {normalizeAccountId} from './util/helpers';272829chai.use(chaiAsPromised);30const expect = chai.expect;3132const RELAY_PORT = '9844';33const UNIQUE_CHAIN = 2037;34const UNIQUE_PORT = '9944';35const STATEMINE_CHAIN = 1000;36const STATEMINE_PORT = '9946';37const STATEMINE_PALLET_INSTANCE = 50;38const ASSET_ID = 100;39const ASSET_METADATA_DECIMALS = 18;40const ASSET_METADATA_NAME = 'USDT';41const ASSET_METADATA_DESCRIPTION = 'USDT';42const ASSET_METADATA_MINIMAL_BALANCE = 1;4344describe('Integration test: Exchanging USDT with Statemine', () => {45 let alice: IKeyringPair;46 let bob: IKeyringPair;47 48 before(async () => {49 await usingApi(async (api, privateKeyWrapper) => {50 alice = privateKeyWrapper('//Alice');51 bob = privateKeyWrapper('//Bob'); 52 });5354 const statemineApiOptions: ApiOptions = {55 provider: new WsProvider('ws://127.0.0.1:' + STATEMINE_PORT),56 };5758 const uniqueApiOptions: ApiOptions = {59 provider: new WsProvider('ws://127.0.0.1:' + UNIQUE_PORT),60 };6162 const relayApiOptions: ApiOptions = {63 provider: new WsProvider('ws://127.0.0.1:' + RELAY_PORT),64 };6566 await usingApi(async (api) => {6768 69 const assetAmount = 1_000_000_000_000_000_000_000n; 70 71 const fundingAmount = 3_500_000_000_000; 7273 const tx = api.tx.assets.create(ASSET_ID, alice.addressRaw, ASSET_METADATA_MINIMAL_BALANCE);74 const events = await submitTransactionAsync(alice, tx);75 const result = getGenericResult(events);76 expect(result.success).to.be.true;7778 79 const tx2 = api.tx.assets.setMetadata(ASSET_ID, ASSET_METADATA_NAME, ASSET_METADATA_DESCRIPTION, ASSET_METADATA_DECIMALS);80 const events2 = await submitTransactionAsync(alice, tx2);81 const result2 = getGenericResult(events2);82 expect(result2.success).to.be.true;8384 85 const tx3 = api.tx.assets.mint(ASSET_ID, alice.addressRaw, assetAmount);86 const events3 = await submitTransactionAsync(alice, tx3);87 const result3 = getGenericResult(events3);88 expect(result3.success).to.be.true;8990 91 92 const parachainSovereingAccount = '0x7369626cf5070000000000000000000000000000000000000000000000000000';93 const tx4 = api.tx.balances.transfer(parachainSovereingAccount, fundingAmount);94 const events4 = await submitTransactionAsync(bob, tx4);95 const result4 = getGenericResult(events4);96 expect(result4.success).to.be.true;9798 }, statemineApiOptions);99100101 await usingApi(async (api) => {102103 const location = {104 V1: {105 parents: 1,106 interior: {X3: [107 {108 Parachain: STATEMINE_CHAIN,109 },110 {111 PalletInstance: STATEMINE_PALLET_INSTANCE,112 },113 {114 GeneralIndex: ASSET_ID,115 },116 ]},117 },118 };119120 const metadata =121 {122 name: ASSET_ID,123 symbol: ASSET_METADATA_NAME,124 decimals: ASSET_METADATA_DECIMALS,125 minimalBalance: ASSET_METADATA_MINIMAL_BALANCE,126 };127 128 const tx = api.tx.foreingAssets.registerForeignAsset(alice.addressRaw, location, metadata);129 const sudoTx = api.tx.sudo.sudo(tx as any);130 const events = await submitTransactionAsync(alice, sudoTx);131 const result = getGenericResult(events);132 expect(result.success).to.be.true;133134 }, uniqueApiOptions);135136137 138 await usingApi(async (api) => {139 const destination = {140 V1: {141 parents: 0,142 interior: {X1: {143 Parachain: UNIQUE_CHAIN,144 },145 },146 }};147148 const beneficiary = {149 V1: {150 parents: 0,151 interior: {X1: {152 AccountId32: {153 network: 'Any',154 id: alice.addressRaw,155 },156 }},157 },158 };159160 const assets = {161 V1: [162 {163 id: {164 Concrete: {165 parents: 0,166 interior: 'Here',167 },168 },169 fun: {170 Fungible: 50_000_000_000_000_000n,171 },172 },173 ],174 };175176 const feeAssetItem = 0;177178 const weightLimit = {179 Limited: 5_000_000_000,180 };181182 const tx = api.tx.xcmPallet.limitedReserveTransferAssets(destination, beneficiary, assets, feeAssetItem, weightLimit);183 const events = await submitTransactionAsync(alice, tx);184 const result = getGenericResult(events);185 expect(result.success).to.be.true;186 }, relayApiOptions);187 188 });189190 it('Should connect and send USDT from Statemine to Unique', async () => {191 192 const statemineApiOptions: ApiOptions = {193 provider: new WsProvider('ws://127.0.0.1:' + STATEMINE_PORT),194 };195196 const uniqueApiOptions: ApiOptions = {197 provider: new WsProvider('ws://127.0.0.1:' + UNIQUE_PORT),198 };199200 await usingApi(async (api) => {201202 const dest = {203 V1: {204 parents: 1,205 interior: {X1: {206 Parachain: UNIQUE_CHAIN,207 },208 },209 }};210211 const beneficiary = {212 V1: {213 parents: 0,214 interior: {X1: {215 AccountId32: {216 network: 'Any',217 id: alice.addressRaw,218 },219 }},220 },221 };222223 const assets = {224 V1: [225 {226 id: {227 Concrete: {228 parents: 0,229 interior: {230 X2: [231 {232 PalletInstance: STATEMINE_PALLET_INSTANCE,233 },234 {235 GeneralIndex: ASSET_ID,236 }, 237 ]},238 },239 },240 fun: {241 Fungible: 1_000_000_000_000_000_000n,242 },243 },244 ],245 };246247 const feeAssetItem = 0;248249 const weightLimit = {250 Limited: 5000000000,251 };252253 const tx = api.tx.polkadotXcm.limitedReserveTransferAssets(dest, beneficiary, assets, feeAssetItem, weightLimit);254 const events = await submitTransactionAsync(alice, tx);255 const result = getGenericResult(events);256 expect(result.success).to.be.true;257 }, statemineApiOptions);258259260 261 await usingApi(async (api) => {262 await waitNewBlocks(api, 3);263 264 const free = (await api.query.fungible.balance(1, normalizeAccountId(alice.address))).toBigInt();265 expect(free > 0).to.be.true;266 }, uniqueApiOptions);267 });268269 it('Should connect and send USDT from Unique to Statemine back', async () => {270 let balanceBefore: bigint;271 const uniqueApiOptions: ApiOptions = {272 provider: new WsProvider('ws://127.0.0.1:' + UNIQUE_PORT),273 };274275 await usingApi(async (api) => {276 balanceBefore = (await api.query.fungible.balance(1, normalizeAccountId(alice.address))).toBigInt();277278 const destination = {279 V1: {280 parents: 1,281 interior: {X2: [282 {283 Parachain: STATEMINE_CHAIN,284 },285 {286 AccountId32: {287 network: 'Any',288 id: alice.addressRaw,289 },290 },291 ]},292 },293 };294295 const currencies = [[296 {297 ForeignAssetId: 0,298 },299 10_000_000_000_000_000n,300 ], 301 [302 {303 NativeAssetId: 'Parent',304 },305 400_000_000_000_000n,306 ]];307308 const feeItem = 1;309 const destWeight = 500000000000;310311 const tx = api.tx.xTokens.transferMulticurrencies(currencies, feeItem, destination, destWeight);312 const events = await submitTransactionAsync(alice, tx);313 const result = getGenericResult(events);314 expect(result.success).to.be.true;315316 317 await waitNewBlocks(api, 3);318 const balanceAfter = (await api.query.fungible.balance(1, normalizeAccountId(alice.address))).toBigInt();319 expect(balanceAfter < balanceBefore).to.be.true;320 }, uniqueApiOptions);321 });322});