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 { provider: wsProvider, types: rtt };19}2021export default async function usingApi<T = void>(action: (api: ApiPromise) => Promise<T>, settings: ApiOptions | undefined = undefined): Promise<T> {22 settings = settings || defaultApiOptions();23 let api: ApiPromise = new ApiPromise(settings);24 let result: T = null as unknown as T;2526 27 28 const consoleErr = console.error;29 console.error = (message: string) => {30 if (message.includes("StorageChangeSet:: WebSocket is not connected") || message.includes("2021-")) {}31 else consoleErr(message);32 };3334 try {35 await promisifySubstrate(api, async () => {36 if (api) {37 await api.isReadyOrError;38 result = await action(api);39 }40 })();41 } finally {42 await api.disconnect();43 console.error = consoleErr;44 }45 return result as T;46}4748enum TransactionStatus {49 Success,50 Fail,51 NotReady52}5354function getTransactionStatus(events: EventRecord[], status: ExtrinsicStatus): TransactionStatus {55 if (status.isReady) {56 return TransactionStatus.NotReady;57 }58 if (status.isBroadcast) {59 return TransactionStatus.NotReady;60 } 61 if (status.isInBlock || status.isFinalized) {62 if(events.filter(e => e.event.data.method === 'ExtrinsicFailed').length > 0) {63 return TransactionStatus.Fail;64 }65 if(events.filter(e => e.event.data.method === 'ExtrinsicSuccess').length > 0) {66 return TransactionStatus.Success;67 }68 }6970 return TransactionStatus.Fail;71}7273export function74submitTransactionAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {75 return new Promise(async (resolve, reject) => {76 try {77 await transaction.signAndSend(sender, ({ events = [], status }) => {78 const transactionStatus = getTransactionStatus(events, status);7980 if (transactionStatus === TransactionStatus.Success) {81 resolve(events);82 } else if (transactionStatus === TransactionStatus.Fail) {83 console.log(`Something went wrong with transaction. Status: ${status}`);84 reject(events);85 }86 });87 } catch (e) {88 console.log('Error: ', e);89 reject(e);90 }91 });92}9394export function submitTransactionExpectFailAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {95 const consoleError = console.error;96 const consoleLog = console.log;97 console.error = () => {};98 console.log = () => {};99100 return new Promise<EventRecord[]>(async function(res, rej) {101 const resolve = (rec: EventRecord[]) => {102 setTimeout(() => {103 res(rec);104 console.error = consoleError;105 console.log = consoleLog;106 });107 };108 const reject = (errror: any) => {109 setTimeout(() => {110 rej(errror);111 console.error = consoleError;112 console.log = consoleLog;113 });114 };115 try {116 await transaction.signAndSend(sender, ({ events = [], status }) => {117 const transactionStatus = getTransactionStatus(events, status);118119 120121 if (transactionStatus === TransactionStatus.Success) {122 resolve(events);123 } else if (transactionStatus === TransactionStatus.Fail) {124 reject(events);125 }126 });127 } catch (e) {128 reject(e);129 }130 });131}