UNPKG

@keplr-ewallet/ewallet-sdk-eth

Version:
142 lines 4.92 kB
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