git.delta.rocks / unique-network / refs/commits / f663e99db821

difftreelog

source

tests/src/substrate/substrate-api.ts5.4 KiBsourcehistory
1//2// This file is subject to the terms and conditions defined in3// file 'LICENSE', which is part of this source code package.4//56import {WsProvider, ApiPromise} from '@polkadot/api';7import {EventRecord} from '@polkadot/types/interfaces/system/types';8import {ExtrinsicStatus} from '@polkadot/types/interfaces/author/types';9import {IKeyringPair} from '@polkadot/types/types';1011import config from '../config';12import promisifySubstrate from './promisify-substrate';13import {ApiOptions, SubmittableExtrinsic, ApiTypes} from '@polkadot/api/types';14import * as defs from '../interfaces/definitions';151617function defaultApiOptions(): ApiOptions {18  const wsProvider = new WsProvider(config.substrateUrl);19  return {20    provider: wsProvider, signedExtensions: {21      ContractHelpers: {22        extrinsic: {},23        payload: {},24      },25    },26    rpc: {27      unique: defs.unique.rpc,28    },29  };30}3132export default async function usingApi<T = void>(action: (api: ApiPromise) => Promise<T>, settings: ApiOptions | undefined = undefined): Promise<T> {33  settings = settings || defaultApiOptions();34  const api: ApiPromise = new ApiPromise(settings);35  let result: T = null as unknown as T;3637  // TODO: Remove, this is temporary: Filter unneeded API output38  // (Jaco promised it will be removed in the next version)39  const consoleErr = console.error;40  const consoleLog = console.log;41  const consoleWarn = console.warn;4243  const outFn = (printer: any) => (...args: any[]) => {44    for (const arg of args) {45      if (typeof arg !== 'string')46        continue;47      if (arg.includes('1000:: Normal connection closure' || arg === 'Normal connection closure'))48        return;49    }50    printer(...args);51  };5253  console.error = outFn(consoleErr.bind(console));54  console.log = outFn(consoleLog.bind(console));55  console.warn = outFn(consoleWarn.bind(console));5657  try {58    await promisifySubstrate(api, async () => {59      if (api) {60        await api.isReadyOrError;61        result = await action(api);62      }63    })();64  } finally {65    await api.disconnect();66    console.error = consoleErr;67    console.log = consoleLog;68    console.warn = consoleWarn;69  }70  return result as T;71}7273enum TransactionStatus {74  Success,75  Fail,76  NotReady77}7879function getTransactionStatus(events: EventRecord[], status: ExtrinsicStatus): TransactionStatus {80  if (status.isReady) {81    return TransactionStatus.NotReady;82  }83  if (status.isBroadcast) {84    return TransactionStatus.NotReady;85  }86  if (status.isInBlock || status.isFinalized) {87    if(events.filter(e => e.event.data.method === 'ExtrinsicFailed').length > 0) {88      return TransactionStatus.Fail;89    }90    if(events.filter(e => e.event.data.method === 'ExtrinsicSuccess').length > 0) {91      return TransactionStatus.Success;92    }93  }9495  return TransactionStatus.Fail;96}9798export function executeTransaction(api: ApiPromise, sender: IKeyringPair, transaction: SubmittableExtrinsic<'promise'>): Promise<EventRecord[]> {99  return new Promise(async (res, rej) => {100    try {101      await transaction.signAndSend(sender, ({events, status}) => {102        if (!status.isInBlock && !status.isFinalized) return;103        for (const {event} of events) {104          if (api.events.system.ExtrinsicSuccess.is(event)) {105            res(events);106          } else if (api.events.system.ExtrinsicFailed.is(event)) {107            const {data: [error]} = event;108            if (error.isModule) {109              const decoded = api.registry.findMetaError(error.asModule);110              const {method, section} = decoded;111              rej(new Error(`${section}.${method}`));112            } else {113              rej(new Error(error.toString()));114            }115          }116        }117      });118    } catch (e) {119      rej(e);120    }121  });122}123124export function125submitTransactionAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {126  /* eslint no-async-promise-executor: "off" */127  return new Promise(async (resolve, reject) => {128    try {129      await transaction.signAndSend(sender, ({events = [], status}) => {130        const transactionStatus = getTransactionStatus(events, status);131132        if (transactionStatus === TransactionStatus.Success) {133          resolve(events);134        } else if (transactionStatus === TransactionStatus.Fail) {135          console.log(`Something went wrong with transaction. Status: ${status}`);136          reject(events);137        }138      });139    } catch (e) {140      console.log('Error: ', e);141      reject(e);142    }143  });144}145146export function submitTransactionExpectFailAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {147  console.error = () => {};148  console.log = () => {};149150  /* eslint no-async-promise-executor: "off" */151  return new Promise<EventRecord[]>(async function(res, rej) {152    const resolve = (rec: EventRecord[]) => {153      setTimeout(() => {154        res(rec);155      });156    };157    const reject = (errror: any) => {158      setTimeout(() => {159        rej(errror);160      });161    };162    try {163      await transaction.signAndSend(sender, ({events = [], status}) => {164        const transactionStatus = getTransactionStatus(events, status);165166        // console.log('transactionStatus', transactionStatus, 'events', events);167168        if (transactionStatus === TransactionStatus.Success) {169          resolve(events);170        } else if (transactionStatus === TransactionStatus.Fail) {171          reject(events);172        }173      });174    } catch (e) {175      reject(e);176    }177  });178}