mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-07-26 16:45:39 +00:00
1295c36241
- Fixed TypeScript type assertion issues - Updated imports from api-augment/substrate to api-augment/bizinikiwi - Fixed imgConvert.mjs header and imports - Added @ts-expect-error for runtime-converted types - Fixed all @polkadot copyright headers to @pezkuwi
121 lines
3.5 KiB
TypeScript
121 lines
3.5 KiB
TypeScript
// Copyright 2017-2025 @pezkuwi/react-hooks authors & contributors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
import type { LinkOption } from '@pezkuwi/apps-config/endpoints/types';
|
|
import type { ParaId } from '@pezkuwi/types/interfaces';
|
|
|
|
import { useEffect, useState } from 'react';
|
|
|
|
import { createWsEndpoints } from '@pezkuwi/apps-config';
|
|
import { isNumber } from '@pezkuwi/util';
|
|
|
|
import { createNamedHook } from './createNamedHook.js';
|
|
import { useApi } from './useApi.js';
|
|
import { useCall } from './useCall.js';
|
|
|
|
interface Teleport {
|
|
allowTeleport: boolean;
|
|
destinations: LinkOption[];
|
|
isParaTeleport?: boolean;
|
|
isRelayTeleport?: boolean;
|
|
oneWay: number[]
|
|
}
|
|
|
|
interface ExtLinkOption extends LinkOption {
|
|
teleport: number[];
|
|
}
|
|
|
|
const DEFAULT_STATE: Teleport = {
|
|
allowTeleport: false,
|
|
destinations: [],
|
|
oneWay: []
|
|
};
|
|
|
|
const endpoints = createWsEndpoints((k, v) => v?.toString() || k).filter((v): v is ExtLinkOption => !!v.teleport);
|
|
|
|
function extractRelayDestinations (relayGenesis: string, filter: (l: ExtLinkOption) => boolean): ExtLinkOption[] {
|
|
return endpoints
|
|
.filter((l) =>
|
|
(
|
|
l.genesisHashRelay === relayGenesis ||
|
|
l.genesisHash === relayGenesis
|
|
) && filter(l)
|
|
)
|
|
.reduce((result: ExtLinkOption[], curr): ExtLinkOption[] => {
|
|
const isExisting = result.some(({ genesisHash, paraId }) =>
|
|
paraId === curr.paraId ||
|
|
(genesisHash && genesisHash === curr.genesisHash)
|
|
);
|
|
|
|
if (!isExisting) {
|
|
result.push(curr);
|
|
}
|
|
|
|
return result;
|
|
}, [])
|
|
.sort((a, b) =>
|
|
a.isRelay === b.isRelay
|
|
? 0
|
|
: a.isRelay
|
|
? -1
|
|
: 1
|
|
);
|
|
}
|
|
|
|
function useTeleportImpl (): Teleport {
|
|
const { api, apiUrl, isApiReady } = useApi();
|
|
const paraId = useCall<ParaId>(isApiReady && api.query.parachainInfo?.parachainId);
|
|
const [state, setState] = useState<Teleport>(() => ({ ...DEFAULT_STATE }));
|
|
|
|
useEffect((): void => {
|
|
if (isApiReady) {
|
|
const relayGenesis = api.genesisHash.toHex();
|
|
const endpoint = endpoints.find(({ genesisHash }) => genesisHash === relayGenesis);
|
|
|
|
if (endpoint) {
|
|
const destinations = extractRelayDestinations(relayGenesis, ({ paraId }) =>
|
|
isNumber(paraId) &&
|
|
endpoint.teleport.includes(paraId)
|
|
);
|
|
const oneWay = extractRelayDestinations(relayGenesis, ({ paraId, teleport }) =>
|
|
isNumber(paraId) &&
|
|
!teleport.includes(-1)
|
|
).map(({ paraId }) => paraId || -1);
|
|
|
|
setState({
|
|
allowTeleport: destinations.length !== 0,
|
|
destinations,
|
|
isRelayTeleport: true,
|
|
oneWay
|
|
});
|
|
}
|
|
}
|
|
}, [api, isApiReady]);
|
|
|
|
useEffect((): void => {
|
|
if (paraId) {
|
|
const endpoint = endpoints.find(({ value }) => value === apiUrl);
|
|
|
|
if (endpoint?.genesisHashRelay) {
|
|
const destinations = extractRelayDestinations(endpoint.genesisHashRelay, ({ paraId }) =>
|
|
endpoint.teleport.includes(isNumber(paraId) ? paraId : -1)
|
|
);
|
|
const oneWay = extractRelayDestinations(endpoint.genesisHashRelay, ({ paraId, teleport }) =>
|
|
!teleport.includes(isNumber(paraId) ? paraId : -1)
|
|
).map(({ paraId }) => paraId || -1);
|
|
|
|
setState({
|
|
allowTeleport: destinations.length !== 0,
|
|
destinations,
|
|
isParaTeleport: true,
|
|
oneWay
|
|
});
|
|
}
|
|
}
|
|
}, [apiUrl, paraId]);
|
|
|
|
return state;
|
|
}
|
|
|
|
export const useTeleport = createNamedHook('useTeleport', useTeleportImpl);
|