Merge pull request #108 from cosmos/feat/type-chain-registry

Add chain registry types
This commit is contained in:
Abel Fernández
2023-04-19 10:43:46 +02:00
committed by GitHub
2 changed files with 107 additions and 46 deletions
+37 -43
View File
@@ -8,7 +8,12 @@ import Button from "../inputs/Button";
import Input from "../inputs/Input";
import Select from "../inputs/Select";
import StackableContainer from "../layout/StackableContainer";
import { ChainRegistryAsset } from "./chainregistry";
import {
RegistryChainApisRpc,
RegistryChainExplorer,
getAssetsFromRegistry,
getChainFromRegistry,
} from "./chainregistry";
interface ChainOption {
label: string;
@@ -112,75 +117,64 @@ const ChainSelect = () => {
const getChainInfo = async (chainOption: GithubChainRegistryItem) => {
setChainError(null);
try {
const chainInfoUrl =
"https://cdn.jsdelivr.net/gh/cosmos/chain-registry@master/" +
chainOption.path +
"/chain.json";
const chainAssetUrl =
"https://cdn.jsdelivr.net/gh/cosmos/chain-registry@master/" +
chainOption.path +
"/assetlist.json";
const { data: chainData } = await axios.get(chainInfoUrl);
const { data: assetData } = await axios.get(chainAssetUrl);
try {
const chainData = await getChainFromRegistry(chainOption.path);
const assets = await getAssetsFromRegistry(chainOption.path);
const firstAsset = assets[0];
const nodeAddress = await getNodeFromArray(chainData.apis.rpc);
const addressPrefix = chainData["bech32_prefix"];
const chainId = chainData["chain_id"];
const chainDisplayName = chainData["pretty_name"];
const registryName = chainOption.name;
const explorerLink = getExplorerFromArray(chainData.explorers);
const denom = firstAsset.base || "";
const displayDenom = firstAsset.symbol || "";
const firstAsset: ChainRegistryAsset | undefined = assetData.assets?.[0];
const denom = firstAsset?.base || "";
const displayDenom = firstAsset?.symbol || "";
const feeToken =
chainData["fees"]?.fee_tokens.find((token: { denom: string }) => token.denom == denom) ??
{};
const displayUnit = firstAsset.denom_units.find((u) => u.denom == firstAsset.display);
const displayDenomExponent = displayUnit?.exponent ?? 6;
const feeToken = chainData.fees.fee_tokens.find((token) => token.denom == denom) ?? { denom };
const gasPrice =
feeToken["average_gas_price"] ??
feeToken["low_gas_price"] ??
feeToken["high_gas_price"] ??
feeToken["fixed_min_gas_price"] ??
feeToken.average_gas_price ??
feeToken.low_gas_price ??
feeToken.high_gas_price ??
feeToken.fixed_min_gas_price ??
0.03;
const formattedGasPrice = firstAsset ? `${gasPrice}${denom}` : "";
const displayUnit = firstAsset?.denom_units.find((u) => u.denom == firstAsset.display);
const displayDenomExponent = displayUnit?.exponent ?? 6;
// change app state
dispatch({
type: "changeChain",
value: {
registryName: chainOption.name,
addressPrefix: chainData.bech32_prefix,
chainId: chainData.chain_id,
chainDisplayName: chainData.pretty_name,
nodeAddress,
explorerLink,
denom,
displayDenom,
displayDenomExponent,
gasPrice: formattedGasPrice,
chainId,
chainDisplayName,
registryName,
addressPrefix,
explorerLink,
},
});
setShowSettings(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
console.log(error);
} catch (error) {
if (error instanceof Error) {
setChainError(error.message);
} else {
setChainError("Error getting chain info");
}
console.error("Error getting chain info", error);
setShowSettings(true);
setChainError(error.toString());
}
};
const getExplorerFromArray = (array: { kind: string; url: string; tx_page: string }[]) => {
if (array && array.length > 0) {
return array[0]["tx_page"];
}
return "";
const getExplorerFromArray = (explorers: readonly RegistryChainExplorer[]) => {
return explorers[0]?.tx_page ?? "";
};
const getNodeFromArray = async (nodeArray: { address: string; provider: string }[]) => {
const getNodeFromArray = async (nodeArray: readonly RegistryChainApisRpc[]) => {
// only return https connections
const secureNodes = nodeArray
.filter((node) => node.address.startsWith("https://"))
+70 -3
View File
@@ -1,7 +1,49 @@
import axios from "axios";
export interface RegistryChainApisRpc {
readonly address: string;
readonly provider: string;
}
export interface RegistryChainApis {
readonly rpc: readonly RegistryChainApisRpc[];
}
export interface RegistryChainExplorer {
readonly kind: string;
readonly url: string;
readonly tx_page: string;
}
export interface RegistryChainFeeTokens {
readonly denom: string;
readonly average_gas_price?: number;
readonly low_gas_price?: number;
readonly high_gas_price?: number;
readonly fixed_min_gas_price?: number;
}
export interface RegistryChainFees {
readonly fee_tokens: readonly RegistryChainFeeTokens[];
}
export interface RegistryChain {
readonly apis: RegistryChainApis;
readonly bech32_prefix: string;
readonly chain_id: string;
readonly explorers: readonly RegistryChainExplorer[];
readonly fees: RegistryChainFees;
readonly pretty_name: string;
}
export interface RegistryChainResponse {
readonly data: RegistryChain;
}
/**
* See https://github.com/cosmos/chain-registry/blob/1e9ecde770951cab90f0853a624411d79af90b83/provenance/assetlist.json#L8-L12
*/
export interface ChainRegistryDemonUnit {
export interface RegistryAssetDenomUnit {
denom: string;
exponent: number;
aliases: string[];
@@ -10,9 +52,9 @@ export interface ChainRegistryDemonUnit {
/**
* See https://github.com/cosmos/chain-registry/blob/1e9ecde770951cab90f0853a624411d79af90b83/provenance/assetlist.json#L5-L28
*/
export interface ChainRegistryAsset {
export interface RegistryAsset {
description: string;
denom_units: ChainRegistryDemonUnit[];
denom_units: RegistryAssetDenomUnit[];
base: string;
name: string;
display: string;
@@ -23,3 +65,28 @@ export interface ChainRegistryAsset {
};
coingecko_id: string;
}
export interface RegistryAssetsResponse {
readonly data: { readonly assets: readonly RegistryAsset[] };
}
const registryGhUrl = "https://cdn.jsdelivr.net/gh/cosmos/chain-registry@master/";
export const getChainFromRegistry = async (chainGhName: string): Promise<RegistryChain> => {
const chainGhUrl = registryGhUrl + chainGhName + "/chain.json";
const { data: chain }: RegistryChainResponse = await axios.get(chainGhUrl);
return chain;
};
export const getAssetsFromRegistry = async (
chainGhName: string,
): Promise<readonly RegistryAsset[]> => {
const assetsGhUrl = registryGhUrl + chainGhName + "/assetlist.json";
const {
data: { assets },
}: RegistryAssetsResponse = await axios.get(assetsGhUrl);
return assets;
};