123456import {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 38 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 function99submitTransactionAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {100 101 return new Promise(async (resolve, reject) => {102 try {103 await transaction.signAndSend(sender, ({events = [], status}) => {104 const transactionStatus = getTransactionStatus(events, status);105106 if (transactionStatus === TransactionStatus.Success) {107 resolve(events);108 } else if (transactionStatus === TransactionStatus.Fail) {109 console.log(`Something went wrong with transaction. Status: ${status}`);110 reject(events);111 }112 });113 } catch (e) {114 console.log('Error: ', e);115 reject(e);116 }117 });118}119120export function submitTransactionExpectFailAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {121 console.error = () => {};122 console.log = () => {};123124 125 return new Promise<EventRecord[]>(async function(res, rej) {126 const resolve = (rec: EventRecord[]) => {127 setTimeout(() => {128 res(rec);129 });130 };131 const reject = (errror: any) => {132 setTimeout(() => {133 rej(errror);134 });135 };136 try {137 await transaction.signAndSend(sender, ({events = [], status}) => {138 const transactionStatus = getTransactionStatus(events, status);139140 141142 if (transactionStatus === TransactionStatus.Success) {143 resolve(events);144 } else if (transactionStatus === TransactionStatus.Fail) {145 reject(events);146 }147 });148 } catch (e) {149 reject(e);150 }151 });152}