Skip to main content
Glama
clients.ts3.29 kB
import { RpcProvider, Account, Contract, ProviderInterface, constants, validateAndParseAddress } from 'starknet'; import { getRpcUrl } from '../chains.js'; // Cache for providers to avoid recreating them for each request const providerCache = new Map<string, RpcProvider>(); // Map of network names to chain IDs for cleaner code const CHAIN_IDS = { mainnet: constants.StarknetChainId.SN_MAIN, sepolia: constants.StarknetChainId.SN_SEPOLIA }; /** * Get a RPC provider for a specific network * @param network Network name (mainnet, sepolia) * @returns RPC provider instance */ export function getProvider(network = 'mainnet'): RpcProvider { const cacheKey = String(network); // Return cached provider if available if (providerCache.has(cacheKey)) { return providerCache.get(cacheKey)!; } // Get the RPC URL for the network const rpcUrl = getRpcUrl(network); // Get chain ID, defaulting to mainnet if not recognized const chainId = CHAIN_IDS[network as keyof typeof CHAIN_IDS] || CHAIN_IDS.mainnet; // Create and cache the provider const provider = new RpcProvider({ nodeUrl: rpcUrl, chainId }); providerCache.set(cacheKey, provider); return provider; } /** * Create an account instance for a specific network and private key * @param privateKey The private key in hex format (with or without 0x prefix) * @param accountAddress The address of the deployed account contract * @param network Network name (mainnet, sepolia) * @returns Account instance */ export function getAccount( privateKey: string, accountAddress: string, network = 'mainnet' ): Account { const provider = getProvider(network); // Ensure the private key has the proper format const formattedPrivateKey = privateKey.startsWith('0x') ? privateKey : `0x${privateKey}`; const formattedAddress = parseStarknetAddress(accountAddress); return new Account( provider, formattedAddress, formattedPrivateKey ); } /** * Create a contract instance * @param contractAddress Address of the contract * @param provider Optional provider, if not provided a new one will be created * @param network Network name * @returns Contract instance */ export async function getContract( contractAddress: string, provider?: ProviderInterface, network = 'mainnet' ): Promise<Contract> { const contractProvider = provider || getProvider(network); const formattedAddress = parseStarknetAddress(contractAddress); // Fetch the contract class using getClassAt to get the ABI const contractClass = await contractProvider.getClassAt(formattedAddress); const abi = contractClass.abi || []; return new Contract( abi, formattedAddress, contractProvider ); } /** * Parse a Starknet address to ensure it's properly formatted * @param address The address to parse * @returns The formatted address */ export function parseStarknetAddress(address: string): string { try { // Use StarknetJS's built-in validation return validateAndParseAddress(address); } catch (error) { // If invalid, try to fix common issues - ensure 0x prefix if (!address.startsWith('0x')) { return parseStarknetAddress(`0x${address}`); } throw new Error(`Invalid Starknet address: ${address}`); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mcpdotdirect/starknet-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server