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 (typeof message !== 'string') {41 consoleErr(message);42 return;43 }44 if (!message.includes('StorageChangeSet:: WebSocket is not connected') && 45 !message.includes('2021-') &&46 !message.includes('StorageChangeSet:: Normal connection closure'))47 consoleErr(message);48 };4950 console.error = outFn;51 console.log = outFn;52 console.warn = outFn;5354 try {55 await promisifySubstrate(api, async () => {56 if (api) {57 await api.isReadyOrError;58 result = await action(api);59 }60 })();61 } finally {62 await api.disconnect();63 console.error = consoleErr;64 console.log = consoleLog;65 console.warn = consoleWarn;66 }67 return result as T;68}6970enum TransactionStatus {71 Success,72 Fail,73 NotReady74}7576function getTransactionStatus(events: EventRecord[], status: ExtrinsicStatus): TransactionStatus {77 if (status.isReady) {78 return TransactionStatus.NotReady;79 }80 if (status.isBroadcast) {81 return TransactionStatus.NotReady;82 } 83 if (status.isInBlock || status.isFinalized) {84 if(events.filter(e => e.event.data.method === 'ExtrinsicFailed').length > 0) {85 return TransactionStatus.Fail;86 }87 if(events.filter(e => e.event.data.method === 'ExtrinsicSuccess').length > 0) {88 return TransactionStatus.Success;89 }90 }9192 return TransactionStatus.Fail;93}9495export function96submitTransactionAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {97 98 return new Promise(async (resolve, reject) => {99 try {100 await transaction.signAndSend(sender, ({ events = [], status }) => {101 const transactionStatus = getTransactionStatus(events, status);102103 if (transactionStatus === TransactionStatus.Success) {104 resolve(events);105 } else if (transactionStatus === TransactionStatus.Fail) {106 console.log(`Something went wrong with transaction. Status: ${status}`);107 reject(events);108 }109 });110 } catch (e) {111 console.log('Error: ', e);112 reject(e);113 }114 });115}116117export function submitTransactionExpectFailAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {118 const consoleError = console.error;119 const consoleLog = console.log;120 console.error = () => {};121 console.log = () => {};122123 124 return new Promise<EventRecord[]>(async function(res, rej) {125 const resolve = (rec: EventRecord[]) => {126 setTimeout(() => {127 res(rec);128 console.error = consoleError;129 console.log = consoleLog;130 });131 };132 const reject = (errror: any) => {133 setTimeout(() => {134 rej(errror);135 console.error = consoleError;136 console.log = consoleLog;137 });138 };139 try {140 await transaction.signAndSend(sender, ({ events = [], status }) => {141 const transactionStatus = getTransactionStatus(events, status);142143 144145 if (transactionStatus === TransactionStatus.Success) {146 resolve(events);147 } else if (transactionStatus === TransactionStatus.Fail) {148 reject(events);149 }150 });151 } catch (e) {152 reject(e);153 }154 });155}