git.delta.rocks / unique-network / refs/commits / 647ca2aac4ad

difftreelog

source

js-packages/test-utils/xcm/index.ts16.1 KiBsourcehistory
1import {ApiPromise, WsProvider} from '@polkadot/api';2import type {IKeyringPair} from '@polkadot/types/types';3import {ChainHelperBase, EthereumBalanceGroup, HelperGroup, SubstrateBalanceGroup, UniqueHelper} from '@unique-nft/playgrounds/unique.js';4import type {ILogger, TSigner} from '@unique-nft/playgrounds/types.js';5import type {AcalaAssetMetadata, DemocracyStandardAccountVote, MoonbeamAssetInfo} from './types.js';678export class XcmChainHelper extends ChainHelperBase {9  override async connect(wsEndpoint: string, _listeners?: any): Promise<void> {10    const wsProvider = new WsProvider(wsEndpoint);11    this.api = new ApiPromise({12      provider: wsProvider,13    });14    await this.api.isReadyOrError;15    this.network = await UniqueHelper.detectNetwork(this.api);16  }17}1819class AcalaAssetRegistryGroup extends HelperGroup<AcalaHelper> {20  async registerForeignAsset(signer: TSigner, destination: any, metadata: AcalaAssetMetadata) {21    await this.helper.executeExtrinsic(signer, 'api.tx.assetRegistry.registerForeignAsset', [destination, metadata], true);22  }23}2425class MoonbeamAssetManagerGroup extends HelperGroup<MoonbeamHelper> {26  makeRegisterForeignAssetProposal(assetInfo: MoonbeamAssetInfo) {27    const apiPrefix = 'api.tx.assetManager.';2829    const registerTx = this.helper.constructApiCall(30      apiPrefix + 'registerForeignAsset',31      [assetInfo.location, assetInfo.metadata, assetInfo.existentialDeposit, assetInfo.isSufficient],32    );3334    const setUnitsTx = this.helper.constructApiCall(35      apiPrefix + 'setAssetUnitsPerSecond',36      [assetInfo.location, assetInfo.unitsPerSecond, assetInfo.numAssetsWeightHint],37    );3839    const batchCall = this.helper.getApi().tx.utility.batchAll([registerTx, setUnitsTx]);40    const encodedProposal = batchCall?.method.toHex() || '';41    return encodedProposal;42  }4344  async assetTypeId(location: any) {45    return await this.helper.callRpc('api.query.assetManager.assetTypeId', [location]);46  }47}4849class MoonbeamDemocracyGroup extends HelperGroup<MoonbeamHelper> {50  notePreimagePallet: string;5152  constructor(helper: MoonbeamHelper, options: { [key: string]: any } = {}) {53    super(helper);54    this.notePreimagePallet = options.notePreimagePallet;55  }5657  async notePreimage(signer: TSigner, encodedProposal: string) {58    await this.helper.executeExtrinsic(signer, `api.tx.${this.notePreimagePallet}.notePreimage`, [encodedProposal], true);59  }6061  externalProposeMajority(proposal: any) {62    return this.helper.constructApiCall('api.tx.democracy.externalProposeMajority', [proposal]);63  }6465  fastTrack(proposalHash: string, votingPeriod: number, delayPeriod: number) {66    return this.helper.constructApiCall('api.tx.democracy.fastTrack', [proposalHash, votingPeriod, delayPeriod]);67  }6869  async referendumVote(signer: TSigner, referendumIndex: number, accountVote: DemocracyStandardAccountVote) {70    await this.helper.executeExtrinsic(signer, 'api.tx.democracy.vote', [referendumIndex, {Standard: accountVote}], true);71  }72}7374class DemocracyGroup<T extends ChainHelperBase> extends HelperGroup<T> {75  notePreimagePallet: string;7677  constructor(helper: T, options: { [key: string]: any } = {}) {78    super(helper);79    this.notePreimagePallet = options.notePreimagePallet;80  }8182  async notePreimage(signer: TSigner, encodedProposal: string) {83    await this.helper.executeExtrinsic(signer, `api.tx.${this.notePreimagePallet}.notePreimage`, [encodedProposal], true);84  }8586  externalProposeMajority(proposal: any) {87    return this.helper.constructApiCall('api.tx.democracy.externalProposeMajority', [proposal]);88  }8990  fastTrack(proposalHash: string, votingPeriod: number, delayPeriod: number) {91    return this.helper.constructApiCall('api.tx.democracy.fastTrack', [proposalHash, votingPeriod, delayPeriod]);92  }9394  async referendumVote(signer: TSigner, referendumIndex: number, accountVote: DemocracyStandardAccountVote) {95    await this.helper.executeExtrinsic(signer, 'api.tx.democracy.vote', [referendumIndex, {Standard: accountVote}], true);96  }97}9899class MoonbeamCollectiveGroup extends HelperGroup<MoonbeamHelper> {100  collective: string;101102  constructor(helper: MoonbeamHelper, collective: string) {103    super(helper);104105    this.collective = collective;106  }107108  async propose(signer: TSigner, threshold: number, proposalHash: string, lengthBound: number) {109    await this.helper.executeExtrinsic(signer, `api.tx.${this.collective}.propose`, [threshold, proposalHash, lengthBound], true);110  }111112  async vote(signer: TSigner, proposalHash: string, proposalIndex: number, approve: boolean) {113    await this.helper.executeExtrinsic(signer, `api.tx.${this.collective}.vote`, [proposalHash, proposalIndex, approve], true);114  }115116  async close(signer: TSigner, proposalHash: string, proposalIndex: number, weightBound: any, lengthBound: number) {117    await this.helper.executeExtrinsic(signer, `api.tx.${this.collective}.close`, [proposalHash, proposalIndex, weightBound, lengthBound], true);118  }119120  async proposalCount() {121    return Number(await this.helper.callRpc(`api.query.${this.collective}.proposalCount`, []));122  }123}124125class CollectiveGroup<T extends ChainHelperBase> extends HelperGroup<T> {126  collective: string;127128  constructor(helper: T, palletName: string) {129    super(helper);130131    this.collective = palletName;132  }133134  async propose(signer: TSigner, threshold: number, proposalHash: string, lengthBound: number) {135    await this.helper.executeExtrinsic(signer, `api.tx.${this.collective}.propose`, [threshold, proposalHash, lengthBound], true);136  }137138  async vote(signer: TSigner, proposalHash: string, proposalIndex: number, approve: boolean) {139    await this.helper.executeExtrinsic(signer, `api.tx.${this.collective}.vote`, [proposalHash, proposalIndex, approve], true);140  }141142  async close(signer: TSigner, proposalHash: string, proposalIndex: number, weightBound: any, lengthBound: number) {143    await this.helper.executeExtrinsic(signer, `api.tx.${this.collective}.close`, [proposalHash, proposalIndex, weightBound, lengthBound], true);144  }145146  async proposalCount() {147    return Number(await this.helper.callRpc(`api.query.${this.collective}.proposalCount`, []));148  }149}150class PolkadexXcmHelperGroup<T extends ChainHelperBase> extends HelperGroup<T> {151  async whitelistToken(signer: TSigner, assetId: any) {152    await this.helper.executeExtrinsic(signer, 'api.tx.xcmHelper.whitelistToken', [assetId], true);153  }154}155156export class ForeignAssetsGroup extends HelperGroup<UniqueHelper> {157  async register(signer: TSigner, assetId: any, name: string, tokenPrefix: string, mode: 'NFT' | { Fungible: number }) {158    await this.helper.executeExtrinsic(159      signer,160      'api.tx.foreignAssets.forceRegisterForeignAsset',161      [{V3: assetId}, this.helper.util.str2vec(name), tokenPrefix, mode],162      true,163    );164  }165166  async foreignCollectionId(assetId: any) {167    return (await this.helper.callRpc('api.query.foreignAssets.foreignAssetToCollection', [assetId])).toJSON();168  }169}170171export class XcmGroup<T extends ChainHelperBase> extends HelperGroup<T> {172  palletName: string;173174  constructor(helper: T, palletName: string) {175    super(helper);176177    this.palletName = palletName;178  }179180  async limitedReserveTransferAssets(signer: TSigner, destination: any, beneficiary: any, assets: any, feeAssetItem: number, weightLimit: any) {181    await this.helper.executeExtrinsic(signer, `api.tx.${this.palletName}.limitedReserveTransferAssets`, [destination, beneficiary, assets, feeAssetItem, weightLimit], true);182  }183184  async setSafeXcmVersion(signer: TSigner, version: number) {185    await this.helper.executeExtrinsic(signer, `api.tx.${this.palletName}.forceDefaultXcmVersion`, [version], true);186  }187188  async teleportAssets(signer: TSigner, destination: any, beneficiary: any, assets: any, feeAssetItem: number) {189    await this.helper.executeExtrinsic(signer, `api.tx.${this.palletName}.teleportAssets`, [destination, beneficiary, assets, feeAssetItem], true);190  }191192  async teleportNativeAsset(signer: TSigner, destinationParaId: number, targetAccount: Uint8Array, amount: bigint, xcmVersion = 3) {193    const destinationContent = {194      parents: 0,195      interior: {196        X1: {197          Parachain: destinationParaId,198        },199      },200    };201202    const beneficiaryContent = {203      parents: 0,204      interior: {205        X1: {206          AccountId32: {207            network: 'Any',208            id: targetAccount,209          },210        },211      },212    };213214    const assetsContent = [215      {216        id: {217          Concrete: {218            parents: 0,219            interior: 'Here',220          },221        },222        fun: {223          Fungible: amount,224        },225      },226    ];227228    let destination;229    let beneficiary;230    let assets;231232    if(xcmVersion == 2) {233      destination = {V1: destinationContent};234      beneficiary = {V1: beneficiaryContent};235      assets = {V1: assetsContent};236237    } else if(xcmVersion == 3) {238      destination = {V2: destinationContent};239      beneficiary = {V2: beneficiaryContent};240      assets = {V2: assetsContent};241242    } else {243      throw Error('Unknown XCM version: ' + xcmVersion);244    }245246    const feeAssetItem = 0;247248    await this.teleportAssets(signer, destination, beneficiary, assets, feeAssetItem);249  }250251  async send(signer: IKeyringPair, destination: any, message: any) {252    await this.helper.executeExtrinsic(253      signer,254      `api.tx.${this.palletName}.send`,255      [256        destination,257        message,258      ],259      true,260    );261  }262}263264export class XTokensGroup<T extends ChainHelperBase> extends HelperGroup<T> {265  async transfer(signer: TSigner, currencyId: any, amount: bigint, destination: any, destWeight: any) {266    await this.helper.executeExtrinsic(signer, 'api.tx.xTokens.transfer', [currencyId, amount, destination, destWeight], true);267  }268269  async transferMultiasset(signer: TSigner, asset: any, destination: any, destWeight: any) {270    await this.helper.executeExtrinsic(signer, 'api.tx.xTokens.transferMultiasset', [asset, destination, destWeight], true);271  }272273  async transferMulticurrencies(signer: TSigner, currencies: any[], feeItem: number, destLocation: any, destWeight: any) {274    await this.helper.executeExtrinsic(signer, 'api.tx.xTokens.transferMulticurrencies', [currencies, feeItem, destLocation, destWeight], true);275  }276}277278279280export class TokensGroup<T extends ChainHelperBase> extends HelperGroup<T> {281  async accounts(address: string, currencyId: any) {282    const {free} = (await this.helper.callRpc('api.query.tokens.accounts', [address, currencyId])).toJSON() as any;283    return BigInt(free);284  }285}286287export class AssetsGroup<T extends ChainHelperBase> extends HelperGroup<T> {288  async create(signer: TSigner, assetId: number | bigint, admin: string, minimalBalance: bigint) {289    await this.helper.executeExtrinsic(signer, 'api.tx.assets.create', [assetId, admin, minimalBalance], true);290  }291292  async forceCreate(signer: TSigner, assetId: number | bigint, admin: string, minimalBalance: bigint, isSufficient = true) {293    await this.helper.executeExtrinsic(signer, 'api.tx.assets.forceCreate', [assetId, admin, isSufficient, minimalBalance], true);294  }295296  async setMetadata(signer: TSigner, assetId: number | bigint, name: string, symbol: string, decimals: number) {297    await this.helper.executeExtrinsic(signer, 'api.tx.assets.setMetadata', [assetId, name, symbol, decimals], true);298  }299300  async mint(signer: TSigner, assetId: number | bigint, beneficiary: string, amount: bigint) {301    await this.helper.executeExtrinsic(signer, 'api.tx.assets.mint', [assetId, beneficiary, amount], true);302  }303304  async assetInfo(assetId: number | bigint) {305    return (await this.helper.callRpc('api.query.assets.asset', [assetId])).toJSON();306  }307308  async account(assetId: string | number | bigint, address: string) {309    const accountAsset = (310      await this.helper.callRpc('api.query.assets.account', [assetId, address])311    ).toJSON()! as any;312313    if(accountAsset !== null) {314      return BigInt(accountAsset['balance']);315    } else {316      return null;317    }318  }319}320321export class RelayHelper extends XcmChainHelper {322  balance: SubstrateBalanceGroup<RelayHelper>;323  xcm: XcmGroup<RelayHelper>;324325  constructor(logger?: ILogger, options: { [key: string]: any } = {}) {326    super(logger, options.helperBase ?? RelayHelper);327328    this.balance = new SubstrateBalanceGroup(this);329    this.xcm = new XcmGroup(this, 'xcmPallet');330  }331}332333export class WestmintHelper extends XcmChainHelper {334  balance: SubstrateBalanceGroup<WestmintHelper>;335  xcm: XcmGroup<WestmintHelper>;336  assets: AssetsGroup<WestmintHelper>;337  xTokens: XTokensGroup<WestmintHelper>;338339  constructor(logger?: ILogger, options: { [key: string]: any } = {}) {340    super(logger, options.helperBase ?? WestmintHelper);341342    this.balance = new SubstrateBalanceGroup(this);343    this.xcm = new XcmGroup(this, 'polkadotXcm');344    this.assets = new AssetsGroup(this);345    this.xTokens = new XTokensGroup(this);346  }347}348349export class MoonbeamHelper extends XcmChainHelper {350  balance: EthereumBalanceGroup<MoonbeamHelper>;351  assetManager: MoonbeamAssetManagerGroup;352  assets: AssetsGroup<MoonbeamHelper>;353  xTokens: XTokensGroup<MoonbeamHelper>;354  democracy: MoonbeamDemocracyGroup;355  collective: {356    council: MoonbeamCollectiveGroup,357    techCommittee: MoonbeamCollectiveGroup,358  };359360  constructor(logger?: ILogger, options: { [key: string]: any } = {}) {361    super(logger, options.helperBase ?? MoonbeamHelper);362363    this.balance = new EthereumBalanceGroup(this);364    this.assetManager = new MoonbeamAssetManagerGroup(this);365    this.assets = new AssetsGroup(this);366    this.xTokens = new XTokensGroup(this);367    this.democracy = new MoonbeamDemocracyGroup(this, options);368    this.collective = {369      council: new MoonbeamCollectiveGroup(this, 'councilCollective'),370      techCommittee: new MoonbeamCollectiveGroup(this, 'techCommitteeCollective'),371    };372  }373}374375export class AstarHelper extends XcmChainHelper {376  balance: SubstrateBalanceGroup<AstarHelper>;377  assets: AssetsGroup<AstarHelper>;378  xcm: XcmGroup<AstarHelper>;379380  constructor(logger?: ILogger, options: { [key: string]: any } = {}) {381    super(logger, options.helperBase ?? AstarHelper);382383    this.balance = new SubstrateBalanceGroup(this);384    this.assets = new AssetsGroup(this);385    this.xcm = new XcmGroup(this, 'polkadotXcm');386  }387}388389export class AcalaHelper extends XcmChainHelper {390  balance: SubstrateBalanceGroup<AcalaHelper>;391  assetRegistry: AcalaAssetRegistryGroup;392  xTokens: XTokensGroup<AcalaHelper>;393  tokens: TokensGroup<AcalaHelper>;394  xcm: XcmGroup<AcalaHelper>;395396  constructor(logger?: ILogger, options: { [key: string]: any } = {}) {397    super(logger, options.helperBase ?? AcalaHelper);398399    this.balance = new SubstrateBalanceGroup(this);400    this.assetRegistry = new AcalaAssetRegistryGroup(this);401    this.xTokens = new XTokensGroup(this);402    this.tokens = new TokensGroup(this);403    this.xcm = new XcmGroup(this, 'polkadotXcm');404  }405}406407export class PolkadexHelper extends XcmChainHelper {408  assets: AssetsGroup<PolkadexHelper>;409  balance: SubstrateBalanceGroup<PolkadexHelper>;410  xTokens: XTokensGroup<PolkadexHelper>;411  xcm: XcmGroup<PolkadexHelper>;412  xcmHelper: PolkadexXcmHelperGroup<PolkadexHelper>;413414  constructor(logger?: ILogger, options: { [key: string]: any } = {}) {415    super(logger, options.helperBase ?? PolkadexHelper);416417    this.assets = new AssetsGroup(this);418    this.balance = new SubstrateBalanceGroup(this);419    this.xTokens = new XTokensGroup(this);420    this.xcm = new XcmGroup(this, 'polkadotXcm');421    this.xcmHelper = new PolkadexXcmHelperGroup(this);422  }423}424425export class HydraDxHelper extends XcmChainHelper {426  balance: SubstrateBalanceGroup<HydraDxHelper>;427  xcm: XcmGroup<HydraDxHelper>;428  xTokens: XTokensGroup<HydraDxHelper>;429  democracy: DemocracyGroup<HydraDxHelper>;430  collective: {431    council: CollectiveGroup<HydraDxHelper>,432    techCommittee: CollectiveGroup<HydraDxHelper>,433  };434435  constructor(logger?: ILogger, options: { [key: string]: any } = {}) {436    super(logger, options.helperBase ?? HydraDxHelper);437    options.notePreimagePallet = options.notePreimagePallet ?? 'preimage';438439    this.balance = new SubstrateBalanceGroup(this);440    this.xcm = new XcmGroup(this, 'polkadotXcm');441    this.xTokens = new XTokensGroup(this);442    this.democracy = new DemocracyGroup(this, options);443    this.collective = {444      council: new CollectiveGroup(this, 'council'),445      techCommittee: new CollectiveGroup(this, 'technicalCommittee'),446    };447  }448}449