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 rtt from '../../../runtime_types.json';1516function defaultApiOptions(): ApiOptions {17 const wsProvider = new WsProvider(config.substrateUrl);18 return {19 provider: wsProvider, types: rtt, signedExtensions: {20 ContractHelpers: {21 extrinsic: {},22 payload: {},23 },24 },25 };26}2728export default async function usingApi<T = void>(action: (api: ApiPromise) => Promise<T>, settings: ApiOptions | undefined = undefined): Promise<T> {29 settings = settings || defaultApiOptions();30 const api: ApiPromise = new ApiPromise(settings);31 let result: T = null as unknown as T;3233 34 35 const consoleErr = console.error;36 const consoleLog = console.log;37 const consoleWarn = console.warn;3839 const outFn = (message: string) => {40 if (!message.includes('StorageChangeSet:: WebSocket is not connected') && 41 !message.includes('2021-') &&42 !message.includes('StorageChangeSet:: Normal connection closure'))43 consoleErr(message);44 };4546 console.error = outFn;47 console.log = outFn;48 console.warn = outFn;4950 try {51 await promisifySubstrate(api, async () => {52 if (api) {53 await api.isReadyOrError;54 result = await action(api);55 }56 })();57 } finally {58 await api.disconnect();59 console.error = consoleErr;60 console.log = consoleLog;61 console.warn = consoleWarn;62 }63 return result as T;64}6566enum TransactionStatus {67 Success,68 Fail,69 NotReady70}7172function getTransactionStatus(events: EventRecord[], status: ExtrinsicStatus): TransactionStatus {73 if (status.isReady) {74 return TransactionStatus.NotReady;75 }76 if (status.isBroadcast) {77 return TransactionStatus.NotReady;78 } 79 if (status.isInBlock || status.isFinalized) {80 if(events.filter(e => e.event.data.method === 'ExtrinsicFailed').length > 0) {81 return TransactionStatus.Fail;82 }83 if(events.filter(e => e.event.data.method === 'ExtrinsicSuccess').length > 0) {84 return TransactionStatus.Success;85 }86 }8788 return TransactionStatus.Fail;89}9091export function92submitTransactionAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {93 94 return new Promise(async (resolve, reject) => {95 try {96 await transaction.signAndSend(sender, ({ events = [], status }) => {97 const transactionStatus = getTransactionStatus(events, status);9899 if (transactionStatus === TransactionStatus.Success) {100 resolve(events);101 } else if (transactionStatus === TransactionStatus.Fail) {102 console.log(`Something went wrong with transaction. Status: ${status}`);103 reject(events);104 }105 });106 } catch (e) {107 console.log('Error: ', e);108 reject(e);109 }110 });111}112113export function submitTransactionExpectFailAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {114 const consoleError = console.error;115 const consoleLog = console.log;116 console.error = () => {};117 console.log = () => {};118119 120 return new Promise<EventRecord[]>(async function(res, rej) {121 const resolve = (rec: EventRecord[]) => {122 setTimeout(() => {123 res(rec);124 console.error = consoleError;125 console.log = consoleLog;126 });127 };128 const reject = (errror: any) => {129 setTimeout(() => {130 rej(errror);131 console.error = consoleError;132 console.log = consoleLog;133 });134 };135 try {136 await transaction.signAndSend(sender, ({ events = [], status }) => {137 const transactionStatus = getTransactionStatus(events, status);138139 140141 if (transactionStatus === TransactionStatus.Success) {142 resolve(events);143 } else if (transactionStatus === TransactionStatus.Fail) {144 reject(events);145 }146 });147 } catch (e) {148 reject(e);149 }150 });151}