Official TypeScript SDK for interacting with the Cryptos EVM network.
Built on top of viem with first-class TypeScript support.
npm install @cryptos/evm-client @cryptos/contractsFor React apps:
npm install @cryptos/evm-client @cryptos/contracts @cryptos/reactimport { createCryptosClient } from "@cryptos/evm-client";
// Create a read-only client
const client = createCryptosClient();
// Get the current block number
const blockNumber = await client.public.getBlockNumber();
console.log("Current block:", blockNumber);| Package | Description |
|---|---|
@cryptos/evm-client |
Core client for read/write operations |
@cryptos/contracts |
Typed contract wrappers (ERC20, etc.) |
@cryptos/react |
React hooks for dApps |
The SDK comes pre-configured for Cryptos Testnet Beta:
import { cryptosTestnetBeta } from "@cryptos/evm-client";
console.log(cryptosTestnetBeta);
// {
// id: 77777777,
// name: "Cryptos Testnet Beta",
// nativeCurrency: { name: "CRYPTOS", symbol: "CRYPTOS", decimals: 18 },
// rpcUrls: { default: { http: ["https://rpc-testnet-beta-evm.cryptos.com"] } },
// testnet: true
// }For reading blockchain state (no private key needed):
import { createCryptosClient } from "@cryptos/evm-client";
const client = createCryptosClient();
// Access the public client for all read operations
const blockNumber = await client.public.getBlockNumber();
const balance = await client.public.getBalance({
address: "0x1234567890123456789012345678901234567890"
});To send transactions, you need to provide an account:
import { createCryptosClient } from "@cryptos/evm-client";
import { privateKeyToAccount } from "viem/accounts";
// Create account from private key
const account = privateKeyToAccount("0xYOUR_PRIVATE_KEY_HERE");
// Create client with wallet capabilities
const client = createCryptosClient({ account });
// Now client.wallet is available for write operations
console.log("Wallet address:", account.address);const client = createCryptosClient({
rpcUrl: "https://your-custom-rpc.example.com",
});const blockNumber = await client.public.getBlockNumber();
console.log("Block:", blockNumber); // e.g., 12345678nimport { formatEther } from "viem";
const balance = await client.public.getBalance({
address: "0x1234567890123456789012345678901234567890",
});
console.log("Balance (wei):", balance);
console.log("Balance (CRYPTOS):", formatEther(balance));const nonce = await client.public.getTransactionCount({
address: "0x1234567890123456789012345678901234567890",
});
console.log("Nonce:", nonce);Send CRYPTOS from your wallet to another address:
import { createCryptosClient } from "@cryptos/evm-client";
import { privateKeyToAccount } from "viem/accounts";
import { parseEther } from "viem";
// Setup client with wallet
const account = privateKeyToAccount("0xYOUR_PRIVATE_KEY_HERE");
const client = createCryptosClient({ account });
// Send 1.5 CRYPTOS to recipient
const hash = await client.wallet.sendTransaction({
to: "0xRecipientAddressHere",
value: parseEther("1.5"),
});
console.log("Transaction hash:", hash);
// Wait for confirmation
const receipt = await client.public.waitForTransactionReceipt({ hash });
console.log("Confirmed in block:", receipt.blockNumber);
console.log("Status:", receipt.status); // "success" or "reverted"The SDK provides a typed wrapper for ERC20 tokens:
import { createCryptosClient } from "@cryptos/evm-client";
import { ExampleErc20 } from "@cryptos/contracts";
const client = createCryptosClient();
// Create ERC20 wrapper (pass the token contract address)
const token = ExampleErc20(client, "0xTokenContractAddressHere");
// Read token info
const name = await token.read.name();
const symbol = await token.read.symbol();
const decimals = await token.read.decimals();
const totalSupply = await token.read.totalSupply();
console.log(`${name} (${symbol})`);
console.log(`Decimals: ${decimals}`);
console.log(`Total Supply: ${totalSupply}`);
// Check balance
const balance = await token.read.balanceOf("0xYourAddressHere");
console.log(`Balance: ${balance}`);import { createCryptosClient } from "@cryptos/evm-client";
import { ExampleErc20 } from "@cryptos/contracts";
import { privateKeyToAccount } from "viem/accounts";
// Setup client with wallet
const account = privateKeyToAccount("0xYOUR_PRIVATE_KEY_HERE");
const client = createCryptosClient({ account });
// Create ERC20 wrapper
const token = ExampleErc20(client, "0xTokenContractAddressHere");
// Transfer 1000 tokens (assuming 18 decimals)
const amount = 1000n * 10n ** 18n; // 1000 tokens in wei
const hash = await token.write.transfer("0xRecipientAddressHere", amount);
console.log("Transfer tx:", hash);
// Wait for confirmation
const receipt = await client.public.waitForTransactionReceipt({ hash });
console.log("Transfer confirmed:", receipt.status);const token = ExampleErc20(client, "0xTokenContractAddressHere");
const unwatch = token.watch.Transfer({
onLogs: (logs) => {
for (const log of logs) {
console.log("Transfer event:", {
from: log.args.from,
to: log.args.to,
value: log.args.value,
});
}
},
onError: (error) => {
console.error("Watch error:", error);
},
pollingInterval: 5000, // Poll every 5 seconds
});
// Later: stop watching
// unwatch();Use createContract to interact with any smart contract:
import { createCryptosClient } from "@cryptos/evm-client";
import { createContract } from "@cryptos/contracts";
import { privateKeyToAccount } from "viem/accounts";
// Your contract's ABI
const myAbi = [
{
name: "getValue",
type: "function",
stateMutability: "view",
inputs: [],
outputs: [{ type: "uint256" }],
},
{
name: "setValue",
type: "function",
stateMutability: "nonpayable",
inputs: [{ name: "newValue", type: "uint256" }],
outputs: [],
},
{
name: "ValueChanged",
type: "event",
inputs: [
{ name: "oldValue", type: "uint256", indexed: false },
{ name: "newValue", type: "uint256", indexed: false },
],
},
] as const;
// Setup client
const account = privateKeyToAccount("0xYOUR_PRIVATE_KEY_HERE");
const client = createCryptosClient({ account });
// Create contract wrapper
const contract = createContract({
client,
address: "0xYourContractAddressHere",
abi: myAbi,
});
// Read contract state
const value = await contract.read("getValue");
console.log("Current value:", value);
// Write to contract
const hash = await contract.write("setValue", [42n]);
console.log("setValue tx:", hash);
// Watch events
const unwatch = contract.watch("ValueChanged", {
onLogs: (logs) => {
console.log("Value changed:", logs);
},
});Create a memoized client instance:
import { useCryptosClient } from "@cryptos/react";
function MyComponent() {
const client = useCryptosClient();
const handleClick = async () => {
const block = await client.public.getBlockNumber();
console.log("Block:", block);
};
return <button onClick={handleClick}>Get Block</button>;
}With custom options:
const client = useCryptosClient({
rpcUrl: "https://custom-rpc.example.com",
chainId: 77777777,
});Poll the native token balance of an address:
import { useBalance } from "@cryptos/react";
import { formatEther } from "viem";
function BalanceDisplay({ address }: { address: `0x${string}` }) {
const { balance, isLoading, error } = useBalance(address, {
pollMs: 5000, // Poll every 5 seconds (default)
});
if (isLoading && balance === undefined) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
return <div>Balance: {formatEther(balance ?? 0n)} CRYPTOS</div>;
}Poll the current block number:
import { useBlockNumber } from "@cryptos/react";
function BlockDisplay() {
const { blockNumber, isLoading, error } = useBlockNumber({
pollMs: 3000, // Poll every 3 seconds (default)
});
if (isLoading && blockNumber === undefined) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
return <div>Current Block: {blockNumber?.toString()}</div>;
}The SDK provides TypeScript utilities for safer wallet operations:
import { createCryptosClient, assertWallet } from "@cryptos/evm-client";
import { privateKeyToAccount } from "viem/accounts";
const client = createCryptosClient({
account: privateKeyToAccount("0x..."),
});
// assertWallet throws if wallet is not configured
assertWallet(client);
// After assertion, TypeScript knows client.wallet exists
const hash = await client.wallet.sendTransaction({
to: "0x...",
value: 1000n,
});import { createCryptosClient } from "@cryptos/evm-client";
import { ExampleErc20 } from "@cryptos/contracts";
import { privateKeyToAccount } from "viem/accounts";
import { formatUnits, parseUnits } from "viem";
async function main() {
// 1. Setup
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const client = createCryptosClient({ account });
console.log("Wallet:", account.address);
// 2. Check native balance
const nativeBalance = await client.public.getBalance({
address: account.address
});
console.log("CRYPTOS Balance:", formatUnits(nativeBalance, 18));
// 3. Setup token
const tokenAddress = "0xYourTokenAddress" as `0x${string}`;
const token = ExampleErc20(client, tokenAddress);
const symbol = await token.read.symbol();
const decimals = await token.read.decimals();
const tokenBalance = await token.read.balanceOf(account.address);
console.log(`${symbol} Balance:`, formatUnits(tokenBalance, decimals));
// 4. Transfer tokens
const recipient = "0xRecipientAddress" as `0x${string}`;
const amount = parseUnits("100", decimals); // 100 tokens
console.log(`Transferring 100 ${symbol} to ${recipient}...`);
const hash = await token.write.transfer(recipient, amount);
console.log("Transaction:", hash);
const receipt = await client.public.waitForTransactionReceipt({ hash });
console.log("Status:", receipt.status);
}
main().catch(console.error);| Export | Description |
|---|---|
createCryptosClient(config?) |
Create a client for read/write operations |
cryptosTestnetBeta |
Chain configuration for Cryptos Testnet Beta |
assertWallet(client) |
Assert that client has a wallet configured |
| Export | Description |
|---|---|
createContract({ client, address, abi }) |
Create a generic contract wrapper |
ExampleErc20(client, address?) |
Create an ERC20 token wrapper |
ERC20_ABI |
Standard ERC20 ABI |
ADDRESSES |
Deployed contract addresses by network |
| Export | Description |
|---|---|
useCryptosClient(options?) |
Hook to create/memoize a client |
useBalance(address?, options?) |
Hook to poll native token balance |
useBlockNumber(options?) |
Hook to poll current block number |
MIT