diff --git a/graphql-server/src/substrateApi.ts b/graphql-server/src/substrateApi.ts index f7a8574..a0f1a57 100644 --- a/graphql-server/src/substrateApi.ts +++ b/graphql-server/src/substrateApi.ts @@ -1,46 +1,60 @@ -import { ApiPromise, WsProvider } from '@polkadot/api'; +import {ApiPromise, WsProvider} from '@polkadot/api'; export type SubstrateNetwork = 'kusama' | 'polkadot' | 'litmus' | 'khala'; // TODO: get ws providers from .env -const polkadotWsProvider = new WsProvider('wss://rpc.polkadot.io'); -const kusamaWsProvider = new WsProvider( - 'wss://kusama.api.onfinality.io/public-ws', -); -const phalaWsProvider = new WsProvider( - 'wss://khala.api.onfinality.io/public-ws', -); -const khalaWsProvider = new WsProvider( - 'wss://khala.api.onfinality.io/public-ws', -); -const litmusWsProvider = new WsProvider( - 'wss://rpc.litmus-parachain.litentry.io', -); - export async function initSubstrateApi() { - const polkadotApi = await ApiPromise.create({ provider: polkadotWsProvider }); - await polkadotApi.isReady; - const kusamaApi = await ApiPromise.create({ provider: kusamaWsProvider }); - await kusamaApi.isReady; + const providers = { + polkadot: new WsProvider('wss://rpc.polkadot.io'), + kusama: new WsProvider( + 'wss://kusama.api.onfinality.io/public-ws' + ), + khala: new WsProvider( + 'wss://khala.api.onfinality.io/public-ws' + ), + litmus: new WsProvider( + 'wss://rpc.litmus-parachain.litentry.io' + ) + }; - const khalaApi = await ApiPromise.create({ provider: khalaWsProvider }); - await khalaApi.isReady; + const apiPromises = []; + const apis = {}; - const litmusApi = await ApiPromise.create({ provider: litmusWsProvider }); - await litmusApi.isReady; + const reconnect = async (api, network) => { + if (api.isConnected) { + console.log(`${network} is connected`); + return; + } - return (network?: SubstrateNetwork) => { - switch (network) { - case 'kusama': - return kusamaApi; - case 'litmus': - return litmusApi; - case 'khala': - return khalaApi; + console.log(`${network} is disconnected - reconnecting`); + await api.connect(); - default: - return polkadotApi; + if (api.isConnected) { + console.log(`${network} has reconnected`); + } else { + console.error(`${network} failed to reconnect`); } - }; + } + + for (const [network, wsProvider] of Object.entries(providers)) { + apiPromises.push(async () => { + const api = await ApiPromise.create({provider: wsProvider}); + await api.isReady; + + api.once('error', async error => { + console.error(`${network}: ${JSON.stringify(error)}`); + await reconnect(api, network); + }); + + api.once('disconnected', async () => { + await reconnect(api, network); + }) + + apis[network] = api; + }) + } + + await Promise.allSettled(apiPromises); + return (network?: SubstrateNetwork) => apis[network || 'polkadot']; }