Split apiSystem connection (#7662)

* Split apiSystem connection

* Test init

* Remove unused

* typo
This commit is contained in:
Jaco 2022-05-31 08:43:02 +02:00 committed by GitHub
parent 2277235203
commit 3a08d2d98a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 103 additions and 75 deletions

View File

@ -60,8 +60,9 @@ export const DEFAULT_AUX = ['Aux1', 'Aux2', 'Aux3', 'Aux4', 'Aux5', 'Aux6', 'Aux
const DISALLOW_EXTENSIONS: string[] = [];
let api: ApiPromise;
let apiSystem: ApiPromise;
export { api };
export { api, apiSystem };
function isKeyringLoaded () {
try {
@ -216,23 +217,35 @@ async function createApi (apiUrl: string, signer: ApiSigner, onError: (error: un
const isLight = apiUrl.startsWith('light://');
try {
const provider = isLight
? new ScProvider(getWellKnownChain(apiUrl.replace('light://substrate-connect/', '')))
: new WsProvider(apiUrl);
const providers = [0, 1].map(() =>
isLight
? new ScProvider(getWellKnownChain(apiUrl.replace('light://substrate-connect/', '')))
: new WsProvider(apiUrl)
);
api = new ApiPromise({
provider,
provider: providers[0],
registry,
signer,
types,
typesBundle,
typesChain
});
apiSystem = new ApiPromise({ provider: providers[1] });
// See https://github.com/polkadot-js/api/pull/4672#issuecomment-1078843960
if (isLight) {
await provider.connect();
for (let i = 0; i < providers.length; i++) {
await providers[i].connect();
}
}
// Debug - overall provider stats
// setInterval((): void => {
// for (let i = 0; i < providers.length; i++) {
// console.log(i, JSON.stringify(providers[i].stats));
// }
// }, 5000);
} catch (error) {
onError(error);
}
@ -256,7 +269,7 @@ function Api ({ apiUrl, children, isElectron, store }: Props): React.ReactElemen
);
const apiRelay = useApiUrl(relayUrls);
const value = useMemo<ApiProps>(
() => objectSpread({}, state, { api, apiEndpoint, apiError, apiRelay, apiUrl, createLink: createLink(apiUrl, isElectron), extensions, isApiConnected, isApiInitialized, isElectron, isWaitingInjected: !extensions }),
() => objectSpread({}, state, { api, apiEndpoint, apiError, apiRelay, apiSystem, apiUrl, createLink: createLink(apiUrl, isElectron), extensions, isApiConnected, isApiInitialized, isElectron, isWaitingInjected: !extensions }),
[apiError, extensions, isApiConnected, isApiInitialized, isElectron, state, apiEndpoint, apiRelay, apiUrl]
);

View File

@ -35,6 +35,7 @@ export interface ApiProps extends ApiState {
apiEndpoint: LinkOption | null;
apiError: string | null;
apiRelay: ApiPromise | null;
apiSystem: ApiPromise;
apiUrl?: string;
createLink: (path: string, apiUrl?: string) => string;
extensions?: InjectedExtension[];

View File

@ -32,7 +32,7 @@ function AccountIndex ({ children, className = '', defaultValue, label, value }:
[info]
);
if (!api.query.indices) {
if (!api || !api.query.indices) {
return null;
}

View File

@ -185,7 +185,7 @@ function AccountName ({ children, className = '', defaultName, label, onClick, o
parentCache.set(cacheAddr, identity.parent.toString());
}
if (isFunction(api.query.identity?.identityOf)) {
if (api && isFunction(api.query.identity?.identityOf)) {
setName(() =>
identity?.display
? extractIdentity(cacheAddr, identity)

View File

@ -11,7 +11,7 @@ import { useSystemApi } from './useSystemApi';
function useDeriveAccountFlagsImpl (value?: AccountId | Address | Uint8Array | string | null): DeriveAccountFlags | undefined {
const api = useSystemApi();
return useCall<DeriveAccountFlags>(api.derive.accounts.flags, [value]);
return useCall<DeriveAccountFlags>(api && api.derive.accounts.flags, [value]);
}
export const useDeriveAccountFlags = createNamedHook('useDeriveAccountFlags', useDeriveAccountFlagsImpl);

View File

@ -11,7 +11,7 @@ import { useSystemApi } from './useSystemApi';
function useDeriveAccountInfoImpl (value?: AccountId | AccountIndex | Address | Uint8Array | string | null): DeriveAccountInfo | undefined {
const api = useSystemApi();
return useCall<DeriveAccountInfo>(api.derive.accounts.info, [value]);
return useCall<DeriveAccountInfo>(api && api.derive.accounts.info, [value]);
}
export const useDeriveAccountInfo = createNamedHook('useDeriveAccountInfo', useDeriveAccountInfoImpl);

View File

@ -3,15 +3,24 @@
import type { ApiPromise } from '@polkadot/api';
import { useMemo } from 'react';
import { useEffect, useMemo, useState } from 'react';
import { createNamedHook } from './createNamedHook';
import { useApi } from './useApi';
function useSystemApiImpl (): ApiPromise {
const { api, apiRelay } = useApi();
function useSystemApiImpl (): ApiPromise | undefined {
const { apiRelay, apiSystem } = useApi();
const [apiDefault, setApiDefault] = useState<ApiPromise | undefined>();
return useMemo(() => apiRelay || api, [apiRelay, api]);
// This system API does not use the global ready, so we
// explicitly wait for it here
useEffect((): void => {
apiSystem && apiSystem.isReady
.then(setApiDefault)
.catch(console.error);
}, [apiSystem]);
return useMemo(() => apiRelay || apiDefault, [apiRelay, apiDefault]);
}
export const useSystemApi = createNamedHook('useSystemApi', useSystemApiImpl);

View File

@ -120,70 +120,75 @@ export abstract class Page {
});
const noop = () => Promise.resolve(() => { /**/ });
const mockApi: ApiProps = {
api: {
consts: {
babe: {
expectedBlockTime: new BN(1)
},
democracy: {
enactmentPeriod: new BN(1)
},
proxy: {
proxyDepositBase: new BN(1),
proxyDepositFactor: new BN(1)
}
const api = {
consts: {
babe: {
expectedBlockTime: new BN(1)
},
createType: () => ({
defKeys: []
}),
derive: {
accounts: {
info: noop
},
balances: {
all: noop
},
chain: {
bestNumber: noop
},
democracy: {
locks: noop
},
staking: {
account: noop
}
democracy: {
enactmentPeriod: new BN(1)
},
genesisHash: new TypeRegistry().createType('Hash', POLKADOT_GENESIS),
query: {
democracy: {
votingOf: noop
},
identity: {
identityOf: noop
}
},
registry: {
chainDecimals: [12],
chainTokens: ['Unit'],
lookup: {
names: []
}
},
tx: {
council: {},
democracy: {
delegate: noop
},
multisig: {
approveAsMulti: Object.assign(noop, { meta: { args: [] } })
},
proxy: {
removeProxies: noop
},
utility: noop
proxy: {
proxyDepositBase: new BN(1),
proxyDepositFactor: new BN(1)
}
},
createType: () => ({
defKeys: []
}),
derive: {
accounts: {
info: noop
},
balances: {
all: noop
},
chain: {
bestNumber: noop
},
democracy: {
locks: noop
},
staking: {
account: noop
}
},
genesisHash: new TypeRegistry().createType('Hash', POLKADOT_GENESIS),
query: {
democracy: {
votingOf: noop
},
identity: {
identityOf: noop
}
},
registry: {
chainDecimals: [12],
chainTokens: ['Unit'],
lookup: {
names: []
}
},
tx: {
council: {},
democracy: {
delegate: noop
},
multisig: {
approveAsMulti: Object.assign(noop, { meta: { args: [] } })
},
proxy: {
removeProxies: noop
},
utility: noop
}
};
const mockApi: ApiProps = {
api,
apiSystem: {
...api,
isReady: Promise.resolve(api)
},
systemName: 'substrate'
} as unknown as ApiProps;