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 nft: defs.nft.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 = (message: any, ...rest: any[]) => {44 if (typeof message !== 'string') {45 consoleErr(message, ...rest);46 return;47 }48 if (!message.includes('StorageChangeSet:: WebSocket is not connected') &&49 !message.includes('2021-') &&50 !message.includes('StorageChangeSet:: Normal connection closure'))51 consoleErr(message, ...rest);52 };5354 console.error = outFn;55 console.log = outFn;56 console.warn = outFn;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 function100submitTransactionAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {101 102 return new Promise(async (resolve, reject) => {103 try {104 await transaction.signAndSend(sender, ({ events = [], status }) => {105 const transactionStatus = getTransactionStatus(events, status);106107 if (transactionStatus === TransactionStatus.Success) {108 resolve(events);109 } else if (transactionStatus === TransactionStatus.Fail) {110 console.log(`Something went wrong with transaction. Status: ${status}`);111 reject(events);112 }113 });114 } catch (e) {115 console.log('Error: ', e);116 reject(e);117 }118 });119}120121export function submitTransactionExpectFailAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {122 const consoleError = console.error;123 const consoleLog = console.log;124 console.error = () => {};125 console.log = () => {};126127 128 return new Promise<EventRecord[]>(async function(res, rej) {129 const resolve = (rec: EventRecord[]) => {130 setTimeout(() => {131 res(rec);132 console.error = consoleError;133 console.log = consoleLog;134 });135 };136 const reject = (errror: any) => {137 setTimeout(() => {138 rej(errror);139 console.error = consoleError;140 console.log = consoleLog;141 });142 };143 try {144 await transaction.signAndSend(sender, ({ events = [], status }) => {145 const transactionStatus = getTransactionStatus(events, status);146147 148149 if (transactionStatus === TransactionStatus.Success) {150 resolve(events);151 } else if (transactionStatus === TransactionStatus.Fail) {152 reject(events);153 }154 });155 } catch (e) {156 reject(e);157 }158 });159}