git.delta.rocks / unique-network / refs/commits / 12cd6cb586e3

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 '../interfaces/augment-api-events';7import {WsProvider, ApiPromise} from '@polkadot/api';8import {EventRecord} from '@polkadot/types/interfaces/system/types';9import {ExtrinsicStatus} from '@polkadot/types/interfaces/author/types';10import {IKeyringPair} from '@polkadot/types/types';1112import config from '../config';13import promisifySubstrate from './promisify-substrate';14import {ApiOptions, SubmittableExtrinsic, ApiTypes} from '@polkadot/api/types';15import * as defs from '../interfaces/definitions';161718function defaultApiOptions(): ApiOptions {19  const wsProvider = new WsProvider(config.substrateUrl);20  return {21    provider: wsProvider, signedExtensions: {22      ContractHelpers: {23        extrinsic: {},24        payload: {},25      },26    },27    rpc: {28      unique: defs.unique.rpc,29    },30  };31}3233export default async function usingApi<T = void>(action: (api: ApiPromise) => Promise<T>, settings: ApiOptions | undefined = undefined): Promise<T> {34  settings = settings || defaultApiOptions();35  const api: ApiPromise = new ApiPromise(settings);36  let result: T = null as unknown as T;3738  // TODO: Remove, this is temporary: Filter unneeded API output39  // (Jaco promised it will be removed in the next version)40  const consoleErr = console.error;41  const consoleLog = console.log;42  const consoleWarn = console.warn;4344  const outFn = (printer: any) => (...args: any[]) => {45    for (const arg of args) {46      if (typeof arg !== 'string')47        continue;48      if (arg.includes('1000:: Normal connection closure' || arg === 'Normal connection closure'))49        return;50    }51    printer(...args);52  };5354  console.error = outFn(consoleErr.bind(console));55  console.log = outFn(consoleLog.bind(console));56  console.warn = outFn(consoleWarn.bind(console));5758  try {59    await promisifySubstrate(api, async () => {60      if (api) {61        await api.isReadyOrError;62        result = await action(api);63      }64    })();65  } finally {66    await api.disconnect();67    console.error = consoleErr;68    console.log = consoleLog;69    console.warn = consoleWarn;70  }71  return result as T;72}7374enum TransactionStatus {75  Success,76  Fail,77  NotReady78}7980function getTransactionStatus(events: EventRecord[], status: ExtrinsicStatus): TransactionStatus {81  if (status.isReady) {82    return TransactionStatus.NotReady;83  }84  if (status.isBroadcast) {85    return TransactionStatus.NotReady;86  }87  if (status.isInBlock || status.isFinalized) {88    if(events.filter(e => e.event.data.method === 'ExtrinsicFailed').length > 0) {89      return TransactionStatus.Fail;90    }91    if(events.filter(e => e.event.data.method === 'ExtrinsicSuccess').length > 0) {92      return TransactionStatus.Success;93    }94  }9596  return TransactionStatus.Fail;97}9899export function executeTransaction(api: ApiPromise, sender: IKeyringPair, transaction: SubmittableExtrinsic<'promise'>): Promise<EventRecord[]> {100  return new Promise(async (res, rej) => {101    try {102      await transaction.signAndSend(sender, ({events, status}) => {103        if (!status.isInBlock && !status.isFinalized) return;104        for (const {event} of events) {105          if (api.events.system.ExtrinsicSuccess.is(event)) {106            res(events);107          } else if (api.events.system.ExtrinsicFailed.is(event)) {108            const {data: [error]} = event;109            if (error.isModule) {110              const decoded = api.registry.findMetaError(error.asModule);111              const {method, section} = decoded;112              rej(new Error(`${section}.${method}`));113            } else {114              rej(new Error(error.toString()));115            }116          }117        }118      });119    } catch (e) {120      rej(e);121    }122  });123}124125export function126submitTransactionAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {127  /* eslint no-async-promise-executor: "off" */128  return new Promise(async (resolve, reject) => {129    try {130      await transaction.signAndSend(sender, ({events = [], status}) => {131        const transactionStatus = getTransactionStatus(events, status);132133        if (transactionStatus === TransactionStatus.Success) {134          resolve(events);135        } else if (transactionStatus === TransactionStatus.Fail) {136          console.log(`Something went wrong with transaction. Status: ${status}`);137          reject(events);138        }139      });140    } catch (e) {141      console.log('Error: ', e);142      reject(e);143    }144  });145}146147export function submitTransactionExpectFailAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {148  console.error = () => {};149  console.log = () => {};150151  /* eslint no-async-promise-executor: "off" */152  return new Promise<EventRecord[]>(async function(res, rej) {153    const resolve = (rec: EventRecord[]) => {154      setTimeout(() => {155        res(rec);156      });157    };158    const reject = (errror: any) => {159      setTimeout(() => {160        rej(errror);161      });162    };163    try {164      await transaction.signAndSend(sender, ({events = [], status}) => {165        const transactionStatus = getTransactionStatus(events, status);166167        // console.log('transactionStatus', transactionStatus, 'events', events);168169        if (transactionStatus === TransactionStatus.Success) {170          resolve(events);171        } else if (transactionStatus === TransactionStatus.Fail) {172          reject(events);173        }174      });175    } catch (e) {176      reject(e);177    }178  });179}