Merge pull request #108 from cosmos/feat/type-chain-registry
Add chain registry types
This commit is contained in:
@@ -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://"))
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user