@keplr-ewallet/ewallet-sdk-eth
Version:
142 lines • 4.92 kB
JavaScript
import { publicKeyToAddress } from "viem/accounts";
import { secp256k1 } from "@noble/curves/secp256k1";
export const publicKeyToEthereumAddress = (publicKey) => {
let publicKeyWithout0x = publicKey;
if (typeof publicKey === "string" && publicKey.startsWith("0x")) {
publicKeyWithout0x = publicKey.slice(2);
}
const point = secp256k1.Point.fromHex(publicKeyWithout0x);
const uncompressedPublicKey = `0x${point.toHex(false)}`;
return publicKeyToAddress(uncompressedPublicKey);
};
export const isValidChainId = (chainId) => Boolean(chainId) && typeof chainId === "string" && chainId.startsWith("0x");
export const isValidUrl = (url) => {
try {
new URL(url);
return true;
}
catch (_a) {
return false;
}
};
export const validateChainIdFormat = (chainId) => {
try {
const decimalChainId = parseInt(chainId, 16);
if (!/^0x[0-9a-fA-F]+$/.test(chainId) || isNaN(decimalChainId)) {
return { isValid: false, error: "Invalid chain ID format" };
}
if (decimalChainId > Number.MAX_SAFE_INTEGER) {
return {
isValid: false,
error: "Chain ID value exceeds maximum safe integer",
};
}
return { isValid: true, decimalValue: decimalChainId };
}
catch (error) {
return { isValid: false, error: "Invalid chain ID format" };
}
};
export const validateRpcUrls = (rpcUrls) => {
if (!rpcUrls || rpcUrls.length === 0) {
return { isValid: false, error: "RPC URLs are required" };
}
for (const url of rpcUrls) {
if (!isValidUrl(url)) {
return { isValid: false, error: `Invalid RPC URL: ${url}` };
}
}
return { isValid: true };
};
export const validateBlockExplorerUrls = (blockExplorerUrls) => {
if (!blockExplorerUrls) {
return { isValid: true };
}
if (!Array.isArray(blockExplorerUrls) || blockExplorerUrls.length === 0) {
return {
isValid: false,
error: "Block explorer URLs must be a non-empty array",
};
}
for (const url of blockExplorerUrls) {
if (!isValidUrl(url)) {
return { isValid: false, error: `Invalid block explorer URL: ${url}` };
}
}
return { isValid: true };
};
export const validateNativeCurrencySymbol = (symbol) => {
if (symbol.length < 2 || symbol.length > 6) {
return {
isValid: false,
error: "Native currency symbol must be between 2-6 characters",
};
}
return { isValid: true };
};
export const validateChain = (chain, addedChains) => {
const { rpcUrls, blockExplorerUrls, chainId, nativeCurrency } = chain;
if (addedChains.some((c) => c.chainId === chainId)) {
return {
isValid: false,
error: "Chain already added",
errorType: "DUPLICATE_CHAIN",
errorData: { chainId },
};
}
const chainIdResult = validateChainIdFormat(chainId);
if (!chainIdResult.isValid) {
return {
isValid: false,
error: chainIdResult.error,
errorType: "INVALID_CHAIN_ID",
errorData: { chainId },
};
}
const rpcResult = validateRpcUrls(rpcUrls);
if (!rpcResult.isValid) {
return {
isValid: false,
error: rpcResult.error,
errorType: "INVALID_RPC_URLS",
errorData: { rpcUrls },
};
}
const blockExplorerResult = validateBlockExplorerUrls(blockExplorerUrls);
if (!blockExplorerResult.isValid) {
return {
isValid: false,
error: blockExplorerResult.error,
errorType: "INVALID_BLOCK_EXPLORER_URLS",
errorData: { blockExplorerUrls },
};
}
if (nativeCurrency) {
const symbolResult = validateNativeCurrencySymbol(nativeCurrency.symbol);
if (!symbolResult.isValid) {
return {
isValid: false,
error: symbolResult.error,
errorType: "INVALID_NATIVE_CURRENCY",
errorData: { symbol: nativeCurrency.symbol },
};
}
const existingChain = addedChains.find((c) => c.chainId === chainId);
if (existingChain &&
existingChain.nativeCurrency &&
existingChain.nativeCurrency.symbol !== nativeCurrency.symbol) {
return {
isValid: false,
error: "Native currency symbol mismatch with existing chain",
errorType: "CURRENCY_SYMBOL_MISMATCH",
errorData: {
chainId,
existing: existingChain.nativeCurrency.symbol,
provided: nativeCurrency.symbol,
},
};
}
}
return { isValid: true };
};
//# sourceMappingURL=utils.js.map