Refactor Chains service to hooks
This commit is contained in:
parent
3d13a34664
commit
a0c0fd77f4
@ -1,5 +1,6 @@
|
||||
import { StargateClient } from "@cosmjs/stargate";
|
||||
import { assert } from "@cosmjs/utils";
|
||||
import { useEffect, useState } from "react";
|
||||
import { requestJson } from "../../lib/request";
|
||||
import {
|
||||
GithubChainRegistryItem,
|
||||
RegistryAsset,
|
||||
@ -19,40 +20,45 @@ import { ChainInfo, ChainItems } from "./types";
|
||||
|
||||
const chainsUrl = "https://api.github.com/repos/cosmos/chain-registry/contents";
|
||||
const testnetsUrl = "https://api.github.com/repos/cosmos/chain-registry/contents/testnets";
|
||||
const registryGhUrl = "https://cdn.jsdelivr.net/gh/cosmos/chain-registry@master/";
|
||||
const registryGhUrl = "https://cdn.jsdelivr.net/gh/cosmos/chain-registry/";
|
||||
|
||||
const getChains = async (chainUrl: string) => {
|
||||
const response = await fetch(chainUrl);
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to get chains from registry");
|
||||
}
|
||||
const nonChainsFilter = (item: GithubChainRegistryItem) =>
|
||||
item.type === "dir" && !item.name.startsWith(".") && !item.name.startsWith("_");
|
||||
|
||||
const chainItems: readonly GithubChainRegistryItem[] = await response.json();
|
||||
return chainItems;
|
||||
};
|
||||
export const useChainsFromRegistry = () => {
|
||||
const [chainItems, setChainItems] = useState<ChainItems>({ mainnets: [], testnets: [] });
|
||||
const [chainItemsError, setChainItemsError] = useState<string | null>(null);
|
||||
|
||||
export const getChainItemsFromRegistry: () => Promise<ChainItems> = async () => {
|
||||
const [mainnets, testnets] = await Promise.all([getChains(chainsUrl), getChains(testnetsUrl)]);
|
||||
useEffect(() => {
|
||||
(async function () {
|
||||
try {
|
||||
const [mainnets, testnets] = await Promise.all([
|
||||
requestJson(chainsUrl),
|
||||
requestJson(testnetsUrl),
|
||||
]);
|
||||
setChainItems({
|
||||
mainnets: mainnets.filter(nonChainsFilter),
|
||||
testnets: testnets.filter(nonChainsFilter),
|
||||
});
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
setChainItemsError(e.message);
|
||||
} else {
|
||||
setChainItemsError("Failed to get chains from registry");
|
||||
}
|
||||
}
|
||||
})();
|
||||
}, []);
|
||||
|
||||
const nonChainsFilter = (item: GithubChainRegistryItem) =>
|
||||
item.type === "dir" && !item.name.startsWith(".") && !item.name.startsWith("_");
|
||||
|
||||
return {
|
||||
mainnets: mainnets.filter(nonChainsFilter),
|
||||
testnets: testnets.filter(nonChainsFilter),
|
||||
};
|
||||
return { chainItems, chainItemsError };
|
||||
};
|
||||
|
||||
export const getChainItemFromRegistry = async (chainName: string, isTestnet?: boolean) => {
|
||||
const chainGhPath = isTestnet ? "testnets/" + chainName : chainName;
|
||||
const chainGhUrl = registryGhUrl + chainGhPath + "/chain.json";
|
||||
|
||||
const response = await fetch(chainGhUrl);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to get ${chainName} chain from registry`);
|
||||
}
|
||||
|
||||
const chain: RegistryChain = await response.json();
|
||||
const chain: RegistryChain = await requestJson(chainGhUrl);
|
||||
// const chain: RegistryChain = await (await fetch(chainGhUrl)).json();
|
||||
return chain;
|
||||
};
|
||||
|
||||
@ -60,12 +66,8 @@ export const getAssetItemsFromRegistry = async (chainName: string, isTestnet?: b
|
||||
const assetsGhPath = isTestnet ? "testnets/" + chainName : chainName;
|
||||
const assetsGhUrl = registryGhUrl + assetsGhPath + "/assetlist.json";
|
||||
|
||||
const response = await fetch(assetsGhUrl);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to get assets for ${chainName} chain from registry`);
|
||||
}
|
||||
|
||||
const assets: readonly RegistryAsset[] = (await response.json()).assets;
|
||||
const assets: readonly RegistryAsset[] = (await requestJson(assetsGhUrl)).assets;
|
||||
// const assets: readonly RegistryAsset[] = (await (await fetch(assetsGhUrl)).json()).assets;
|
||||
return assets;
|
||||
};
|
||||
|
||||
@ -95,46 +97,78 @@ const getExplorerFromArray = (explorers: readonly RegistryChainExplorer[]) => {
|
||||
return explorers[0]?.tx_page ?? "";
|
||||
};
|
||||
|
||||
export const getChainFromRegistry = async (chainName: string, isTestnet?: boolean) => {
|
||||
const chainItem = await getChainItemFromRegistry(chainName, isTestnet);
|
||||
const registryAssets = await getAssetItemsFromRegistry(chainName, isTestnet);
|
||||
const firstAsset = registryAssets[0];
|
||||
export const useChainFromRegistry = (chain: ChainInfo, chains: ChainItems) => {
|
||||
const [chainFromRegistry, setChainFromRegistry] = useState<ChainInfo>(chain);
|
||||
const [chainFromRegistryError, setChainFromRegistryError] = useState<string | null>(null);
|
||||
|
||||
const nodeAddress = await getNodeFromArray(chainItem.apis.rpc);
|
||||
const explorerLink = getExplorerFromArray(chainItem.explorers);
|
||||
const firstAssetDenom = firstAsset.base;
|
||||
const displayDenom = firstAsset.symbol;
|
||||
const displayUnit = firstAsset.denom_units.find((u) => u.denom == firstAsset.display);
|
||||
assert(displayUnit, `Unit not found for ${firstAsset.display}`);
|
||||
useEffect(() => {
|
||||
(async function () {
|
||||
try {
|
||||
if (isChainInfoFilled(chain) || !chains.mainnets.length || !chains.testnets.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const feeToken = chainItem.fees.fee_tokens.find((token) => token.denom == firstAssetDenom) ?? {
|
||||
denom: firstAssetDenom,
|
||||
};
|
||||
const gasPrice =
|
||||
feeToken.average_gas_price ??
|
||||
feeToken.low_gas_price ??
|
||||
feeToken.high_gas_price ??
|
||||
feeToken.fixed_min_gas_price ??
|
||||
0.03;
|
||||
const formattedGasPrice = firstAsset ? `${gasPrice}${firstAssetDenom}` : "";
|
||||
const isTestnet = !!chains.testnets.find(({ name }) => name === chain.registryName);
|
||||
const chainItem = await getChainItemFromRegistry(chain.registryName, isTestnet);
|
||||
const registryAssets = await getAssetItemsFromRegistry(chain.registryName, isTestnet);
|
||||
const firstAsset = registryAssets[0];
|
||||
|
||||
const chain: ChainInfo = {
|
||||
registryName: chainName,
|
||||
addressPrefix: chainItem.bech32_prefix,
|
||||
chainId: chainItem.chain_id,
|
||||
chainDisplayName: chainItem.pretty_name,
|
||||
nodeAddress,
|
||||
explorerLink,
|
||||
denom: firstAssetDenom,
|
||||
displayDenom,
|
||||
displayDenomExponent: displayUnit.exponent,
|
||||
gasPrice: formattedGasPrice,
|
||||
assets: registryAssets,
|
||||
};
|
||||
const nodeAddress = await getNodeFromArray(chainItem.apis.rpc);
|
||||
const explorerLink = getExplorerFromArray(chainItem.explorers);
|
||||
const firstAssetDenom = firstAsset.base;
|
||||
const displayDenom = firstAsset.symbol;
|
||||
const displayUnit = firstAsset.denom_units.find((u) => u.denom == firstAsset.display);
|
||||
|
||||
assert(isChainInfoFilled(chain), `Chain ${chainName} loaded from the registry with missing data`);
|
||||
if (!displayUnit) {
|
||||
return setChainFromRegistryError(`Unit not found for ${firstAsset.display}`);
|
||||
}
|
||||
|
||||
return chain;
|
||||
const feeToken = chainItem.fees.fee_tokens.find(
|
||||
(token) => token.denom == firstAssetDenom,
|
||||
) ?? {
|
||||
denom: firstAssetDenom,
|
||||
};
|
||||
const gasPrice =
|
||||
feeToken.average_gas_price ??
|
||||
feeToken.low_gas_price ??
|
||||
feeToken.high_gas_price ??
|
||||
feeToken.fixed_min_gas_price ??
|
||||
0.03;
|
||||
const formattedGasPrice = firstAsset ? `${gasPrice}${firstAssetDenom}` : "";
|
||||
|
||||
const newChain: ChainInfo = {
|
||||
registryName: chain.registryName,
|
||||
addressPrefix: chainItem.bech32_prefix,
|
||||
chainId: chainItem.chain_id,
|
||||
chainDisplayName: chainItem.pretty_name,
|
||||
nodeAddress,
|
||||
explorerLink,
|
||||
denom: firstAssetDenom,
|
||||
displayDenom,
|
||||
displayDenomExponent: displayUnit.exponent,
|
||||
gasPrice: formattedGasPrice,
|
||||
assets: registryAssets,
|
||||
};
|
||||
|
||||
if (!isChainInfoFilled(newChain)) {
|
||||
setChainFromRegistryError(
|
||||
`Chain ${newChain.registryName} loaded from the registry with missing data`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
setChainFromRegistry(newChain);
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
setChainFromRegistryError(e.message);
|
||||
} else {
|
||||
setChainFromRegistryError(`Failed to get chain ${chain.registryName} from registry`);
|
||||
}
|
||||
}
|
||||
})();
|
||||
}, [chain, chains.mainnets.length, chains.testnets]);
|
||||
|
||||
return { chainFromRegistry, chainFromRegistryError };
|
||||
};
|
||||
|
||||
export const getChain = () => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user