Use relay identity for common-good & system chains (#6758)

* Use relay identity for common-good & system chains

* Adjust

* Align useCallMulti
This commit is contained in:
Jaco 2021-12-30 16:38:26 +01:00 committed by GitHub
parent f96f7ead7b
commit a16d60076d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 42 additions and 20 deletions

View File

@ -24,7 +24,7 @@ export function createKusama (t: TFunction): EndpointOption {
OnFinality: 'wss://kusama.api.onfinality.io/public-ws',
'Patract Elara': 'wss://pub.elara.patract.io/kusama',
// 'Geometry Labs': 'wss://kusama.geometry.io/websockets', // https://github.com/polkadot-js/apps/pull/6746
Dwellir: 'wss://kusama-rpc.dwellir.com',
// Dwellir: 'wss://kusama-rpc.dwellir.com', // https://github.com/polkadot-js/apps/issues/6753
'light client': 'light://substrate-connect/kusama'
// Pinknode: 'wss://rpc.pinknode.io/kusama/explorer' // https://github.com/polkadot-js/apps/issues/5721
},

View File

@ -30,8 +30,8 @@ function Asset ({ className, value: { details, id, isIssuerMe, metadata } }: Pro
<td className='together'>{metadata?.name.toUtf8()}</td>
<td className='address media--1000'>{details && <AddressSmall value={details.owner} />}</td>
<td className='address media--1200'>{details && <AddressSmall value={details.admin} />}</td>
<td className='address media--1300'>{details && <AddressSmall value={details.issuer} />}</td>
<td className='address media--1400'>{details && <AddressSmall value={details.freezer} />}</td>
<td className='address media--1400'>{details && <AddressSmall value={details.issuer} />}</td>
<td className='address media--1700'>{details && <AddressSmall value={details.freezer} />}</td>
<td className='number all'>{details && (
<FormatBalance
format={format}

View File

@ -22,8 +22,8 @@ function Assets ({ className, infos }: Props): React.ReactElement<Props> {
[t('assets'), 'start', 2],
[t('owner'), 'address media--1000'],
[t('admin'), 'address media--1200'],
[t('issuer'), 'address media--1300'],
[t('freezer'), 'address media--1400'],
[t('issuer'), 'address media--1400'],
[t('freezer'), 'address media--1700'],
[t('supply')],
[]
]);

View File

@ -17,11 +17,11 @@ import { ethereumChains, typesBundle, typesChain } from '@polkadot/apps-config';
import { web3Accounts, web3Enable } from '@polkadot/extension-dapp';
import { TokenUnit } from '@polkadot/react-components/InputNumber';
import { StatusContext } from '@polkadot/react-components/Status';
import { useEndpoint } from '@polkadot/react-hooks';
import { useApiUrl, useEndpoint } from '@polkadot/react-hooks';
import ApiSigner from '@polkadot/react-signer/signers/ApiSigner';
import { keyring } from '@polkadot/ui-keyring';
import { settings } from '@polkadot/ui-settings';
import { formatBalance, isTestChain, objectSpread, stringify } from '@polkadot/util';
import { formatBalance, isNumber, isTestChain, objectSpread, stringify } from '@polkadot/util';
import { defaults as addressDefaults } from '@polkadot/util-crypto/address/defaults';
import ApiContext from './ApiContext';
@ -179,17 +179,24 @@ async function loadOnReady (api: ApiPromise, injectedPromise: Promise<InjectedEx
}
function Api ({ apiUrl, children, isElectron, store }: Props): React.ReactElement<Props> | null {
const apiEndpoint = useEndpoint(apiUrl);
const { queuePayload, queueSetTxStatus } = useContext(StatusContext);
const [state, setState] = useState<ApiState>({ hasInjectedAccounts: false, isApiReady: false } as unknown as ApiState);
const [isApiConnected, setIsApiConnected] = useState(false);
const [isApiInitialized, setIsApiInitialized] = useState(false);
const [apiError, setApiError] = useState<null | string>(null);
const [extensions, setExtensions] = useState<InjectedExtension[] | undefined>();
const apiEndpoint = useEndpoint(apiUrl);
const relayUrls = useMemo(
() => (apiEndpoint && apiEndpoint.valueRelay && isNumber(apiEndpoint.paraId) && (apiEndpoint.paraId < 2000))
? apiEndpoint.valueRelay
: null,
[apiEndpoint]
);
const apiRelay = useApiUrl(relayUrls);
const value = useMemo<ApiProps>(
() => objectSpread({}, state, { api, apiEndpoint, apiError, apiUrl, extensions, isApiConnected, isApiInitialized, isElectron, isWaitingInjected: !extensions }),
[apiError, extensions, isApiConnected, isApiInitialized, isElectron, state, apiEndpoint, apiUrl]
() => objectSpread({}, state, { api, apiEndpoint, apiError, apiRelay, apiUrl, extensions, isApiConnected, isApiInitialized, isElectron, isWaitingInjected: !extensions }),
[apiError, extensions, isApiConnected, isApiInitialized, isElectron, state, apiEndpoint, apiRelay, apiUrl]
);
// initial initialization

View File

@ -33,6 +33,7 @@ export interface ApiProps extends ApiState {
api: ApiPromise;
apiEndpoint: LinkOption | null;
apiError: string | null;
apiRelay: ApiPromise | null;
apiUrl?: string;
extensions?: InjectedExtension[];
isApiConnected: boolean;

View File

@ -1,11 +1,11 @@
// Copyright 2017-2021 @polkadot/react-hooks authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { useCallback, useEffect, useRef, useState } from 'react';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { ApiPromise, WsProvider } from '@polkadot/api';
import { typesBundle, typesChain } from '@polkadot/apps-config';
import { isString } from '@polkadot/util';
import { arrayShuffle, isString } from '@polkadot/util';
import { createNamedHook } from './createNamedHook';
import { useIsMountedRef } from './useIsMountedRef';
@ -14,10 +14,18 @@ function disconnect (api: ApiPromise | null): void {
api && api.disconnect().catch(console.error);
}
function useApiUrlImpl (url?: string | string[]): ApiPromise | null {
function useApiUrlImpl (url?: null | string | string[]): ApiPromise | null {
const apiRef = useRef<ApiPromise | null>(null);
const mountedRef = useIsMountedRef();
const [state, setState] = useState<ApiPromise | null>(null);
const urls = useMemo(
() => url
? isString(url)
? [url]
: arrayShuffle(url.filter((u) => !u.startsWith('light://')))
: [],
[url]
);
useEffect((): () => void => {
return (): void => {
@ -41,16 +49,16 @@ function useApiUrlImpl (url?: string | string[]): ApiPromise | null {
useEffect((): void => {
_setApi(null);
url && (isString(url) || url.length) &&
urls.length &&
ApiPromise
.create({
provider: new WsProvider(url),
provider: new WsProvider(urls),
typesBundle,
typesChain
})
.then(_setApi)
.catch(console.error);
}, [_setApi, url]);
}, [_setApi, urls]);
return state;
}

View File

@ -45,6 +45,7 @@ type CallFn = (...params: unknown[]) => Promise<VoidFn>;
export type TrackFn = PromiseResult<AnyFunction> | QueryFn;
export interface Tracker {
fn: TrackFn | undefined | null | false;
isActive: boolean;
serialized: string | null;
subscriber: TrackFnResult | null;
@ -140,7 +141,7 @@ function subscribe <T> (mountedRef: MountedRef, tracker: TrackerRef, fn: TrackFn
// FIXME This is generic, we cannot really use createNamedHook
export function useCall <T> (fn: TrackFn | undefined | null | false, params?: CallParams | null, options?: CallOptions<T>): T | undefined {
const mountedRef = useIsMountedRef();
const tracker = useRef<Tracker>({ isActive: false, serialized: null, subscriber: null });
const tracker = useRef<Tracker>({ fn: null, isActive: false, serialized: null, subscriber: null });
const [value, setValue] = useState<T | undefined>((options || {}).defaultValue);
// initial effect, we need an un-subscription
@ -154,7 +155,8 @@ export function useCall <T> (fn: TrackFn | undefined | null | false, params?: Ca
if (mountedRef.current && fn) {
const [serialized, mappedParams] = extractParams(fn, params || [], options);
if (mappedParams && serialized !== tracker.current.serialized) {
if (mappedParams && ((fn !== tracker.current.fn) || (serialized !== tracker.current.serialized))) {
tracker.current.fn = fn;
tracker.current.serialized = serialized;
subscribe(mountedRef, tracker, fn, mappedParams, setValue, options);

View File

@ -68,7 +68,7 @@ function subscribe <T> (api: ApiPromise, mountedRef: MountedRef, tracker: Tracke
export function useCallMulti <T> (calls?: QueryableStorageMultiArg<'promise'>[] | null | false, options?: CallOptions<T>): T {
const { api } = useApi();
const mountedRef = useIsMountedRef();
const tracker = useRef<Tracker>({ isActive: false, serialized: null, subscriber: null });
const tracker = useRef<Tracker>({ fn: null, isActive: false, serialized: null, subscriber: null });
const [value, setValue] = useState<T>(() => (options || {}).defaultValue || [] as unknown as T);
// initial effect, we need an un-subscription

View File

@ -3,11 +3,15 @@
import type { ApiPromise } from '@polkadot/api';
import { useMemo } from 'react';
import { createNamedHook } from './createNamedHook';
import { useApi } from './useApi';
function useSystemApiImpl (): ApiPromise {
return useApi().api;
const { api, apiRelay } = useApi();
return useMemo(() => apiRelay || api, [apiRelay, api]);
}
export const useSystemApi = createNamedHook('useSystemApi', useSystemApiImpl);