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';27import getBalance from './substrate/get-balance';282930chai.use(chaiAsPromised);31const expect = chai.expect;3233343536let UNIQUE_CHAIN = 0;37let STATEMINE_CHAIN = 0;383940process.argv.forEach((val) => {4142 const ai = val.indexOf('statemineId=');43 const ui = val.indexOf('uniqueId=');44 if (ai != -1)45 {46 STATEMINE_CHAIN = Number(val.substring('statemineId='.length));47 }48 if (ui != -1)49 {50 UNIQUE_CHAIN = Number(val.substring('uniqueId='.length));51 }52});5354const RELAY_PORT = '9844';55const UNIQUE_PORT = '9944';56const STATEMINE_PORT = '9946';57const STATEMINE_PALLET_INSTANCE = 50;58const ASSET_ID = 100;59const ASSET_METADATA_DECIMALS = 18;60const ASSET_METADATA_NAME = 'USDT';61const ASSET_METADATA_DESCRIPTION = 'USDT';62const ASSET_METADATA_MINIMAL_BALANCE = 1;6364const TRANSFER_AMOUNT = 1_000_000_000_000_000_000n;65const TRANSFER_AMOUNT2 = 10_000_000_000_000_000n;6667describe('Integration test: Exchanging USDT with Statemine', () => {68 let alice: IKeyringPair;69 let bob: IKeyringPair;70 71 let balanceStmnBefore: bigint;72 let balanceStmnAfter: bigint;73 let balanceStmnFinal: bigint;7475 before(async () => {76 await usingApi(async (api, privateKeyWrapper) => {77 alice = privateKeyWrapper('//Alice');78 bob = privateKeyWrapper('//Bob'); 79 });8081 const statemineApiOptions: ApiOptions = {82 provider: new WsProvider('ws://127.0.0.1:' + STATEMINE_PORT),83 };8485 const uniqueApiOptions: ApiOptions = {86 provider: new WsProvider('ws://127.0.0.1:' + UNIQUE_PORT),87 };8889 const relayApiOptions: ApiOptions = {90 provider: new WsProvider('ws://127.0.0.1:' + RELAY_PORT),91 };9293 await usingApi(async (api) => {9495 96 const assetAmount = 1_000_000_000_000_000_000_000n; 97 98 const fundingAmount = 3_500_000_000_000; 99100 const tx = api.tx.assets.create(ASSET_ID, alice.addressRaw, ASSET_METADATA_MINIMAL_BALANCE);101 const events = await submitTransactionAsync(alice, tx);102 const result = getGenericResult(events);103 expect(result.success).to.be.true;104105 106 const tx2 = api.tx.assets.setMetadata(ASSET_ID, ASSET_METADATA_NAME, ASSET_METADATA_DESCRIPTION, ASSET_METADATA_DECIMALS);107 const events2 = await submitTransactionAsync(alice, tx2);108 const result2 = getGenericResult(events2);109 expect(result2.success).to.be.true;110111 112 const tx3 = api.tx.assets.mint(ASSET_ID, alice.addressRaw, assetAmount);113 const events3 = await submitTransactionAsync(alice, tx3);114 const result3 = getGenericResult(events3);115 expect(result3.success).to.be.true;116117 118 119 const parachainSovereingAccount = '0x7369626cf5070000000000000000000000000000000000000000000000000000';120 const tx4 = api.tx.balances.transfer(parachainSovereingAccount, fundingAmount);121 const events4 = await submitTransactionAsync(bob, tx4);122 const result4 = getGenericResult(events4);123 expect(result4.success).to.be.true;124125 }, statemineApiOptions);126127128 await usingApi(async (api) => {129130 const location = {131 V1: {132 parents: 1,133 interior: {X3: [134 {135 Parachain: STATEMINE_CHAIN,136 },137 {138 PalletInstance: STATEMINE_PALLET_INSTANCE,139 },140 {141 GeneralIndex: ASSET_ID,142 },143 ]},144 },145 };146147 const metadata =148 {149 name: ASSET_ID,150 symbol: ASSET_METADATA_NAME,151 decimals: ASSET_METADATA_DECIMALS,152 minimalBalance: ASSET_METADATA_MINIMAL_BALANCE,153 };154 155 const tx = api.tx.foreingAssets.registerForeignAsset(alice.addressRaw, location, metadata);156 const sudoTx = api.tx.sudo.sudo(tx as any);157 const events = await submitTransactionAsync(alice, sudoTx);158 const result = getGenericResult(events);159 expect(result.success).to.be.true;160161 }, uniqueApiOptions);162163164 165 await usingApi(async (api) => {166 const destination = {167 V1: {168 parents: 0,169 interior: {X1: {170 Parachain: UNIQUE_CHAIN,171 },172 },173 }};174175 const beneficiary = {176 V1: {177 parents: 0,178 interior: {X1: {179 AccountId32: {180 network: 'Any',181 id: alice.addressRaw,182 },183 }},184 },185 };186187 const assets = {188 V1: [189 {190 id: {191 Concrete: {192 parents: 0,193 interior: 'Here',194 },195 },196 fun: {197 Fungible: 50_000_000_000_000_000n,198 },199 },200 ],201 };202203 const feeAssetItem = 0;204205 const weightLimit = {206 Limited: 5_000_000_000,207 };208209 const tx = api.tx.xcmPallet.limitedReserveTransferAssets(destination, beneficiary, assets, feeAssetItem, weightLimit);210 const events = await submitTransactionAsync(alice, tx);211 const result = getGenericResult(events);212 expect(result.success).to.be.true;213 }, relayApiOptions);214 215 });216217 it('Should connect and send USDT from Statemine to Unique', async () => {218 219 const statemineApiOptions: ApiOptions = {220 provider: new WsProvider('ws://127.0.0.1:' + STATEMINE_PORT),221 };222223 const uniqueApiOptions: ApiOptions = {224 provider: new WsProvider('ws://127.0.0.1:' + UNIQUE_PORT),225 };226227 await usingApi(async (api) => {228229 const dest = {230 V1: {231 parents: 1,232 interior: {X1: {233 Parachain: UNIQUE_CHAIN,234 },235 },236 }};237238 const beneficiary = {239 V1: {240 parents: 0,241 interior: {X1: {242 AccountId32: {243 network: 'Any',244 id: alice.addressRaw,245 },246 }},247 },248 };249250 const assets = {251 V1: [252 {253 id: {254 Concrete: {255 parents: 0,256 interior: {257 X2: [258 {259 PalletInstance: STATEMINE_PALLET_INSTANCE,260 },261 {262 GeneralIndex: ASSET_ID,263 }, 264 ]},265 },266 },267 fun: {268 Fungible: TRANSFER_AMOUNT,269 },270 },271 ],272 };273274 const feeAssetItem = 0;275276 const weightLimit = {277 Limited: 5000000000,278 };279280 [balanceStmnBefore] = await getBalance(api, [alice.address]);281282 const tx = api.tx.polkadotXcm.limitedReserveTransferAssets(dest, beneficiary, assets, feeAssetItem, weightLimit);283 const events = await submitTransactionAsync(alice, tx);284 const result = getGenericResult(events);285 expect(result.success).to.be.true;286287 [balanceStmnAfter] = await getBalance(api, [alice.address]);288 expect(balanceStmnBefore > balanceStmnAfter).to.be.true;289290 }, statemineApiOptions);291292293 294 await usingApi(async (api) => {295 await waitNewBlocks(api, 3);296 297 const free = (await api.query.fungible.balance(1, normalizeAccountId(alice.address))).toBigInt();298 expect(free == TRANSFER_AMOUNT).to.be.true;299300 }, uniqueApiOptions);301 });302303 it('Should connect and send USDT from Unique to Statemine back', async () => {304 let balanceBefore: bigint;305 const uniqueApiOptions: ApiOptions = {306 provider: new WsProvider('ws://127.0.0.1:' + UNIQUE_PORT),307 };308309 await usingApi(async (api) => {310 balanceBefore = (await api.query.fungible.balance(1, normalizeAccountId(alice.address))).toBigInt();311312 const destination = {313 V1: {314 parents: 1,315 interior: {X2: [316 {317 Parachain: STATEMINE_CHAIN,318 },319 {320 AccountId32: {321 network: 'Any',322 id: alice.addressRaw,323 },324 },325 ]},326 },327 };328329 const currencies = [[330 {331 ForeignAssetId: 0,332 },333 10_000_000_000_000_000n,334 ], 335 [336 {337 NativeAssetId: 'Parent',338 },339 400_000_000_000_000n,340 ]];341342 const feeItem = 1;343 const destWeight = 500000000000;344345 const tx = api.tx.xTokens.transferMulticurrencies(currencies, feeItem, destination, destWeight);346 const events = await submitTransactionAsync(alice, tx);347 const result = getGenericResult(events);348 expect(result.success).to.be.true;349350 351 [balanceStmnFinal] = await getBalance(api, [alice.address]);352 expect(balanceStmnFinal > balanceStmnBefore).to.be.true;353354 355 await waitNewBlocks(api, 3);356 const balanceAfter = (await api.query.fungible.balance(1, normalizeAccountId(alice.address))).toBigInt();357 expect(balanceAfter < balanceBefore).to.be.true;358 }, uniqueApiOptions);359 });360});