Quick Start
Start your first temporary Avalanche network in minutes
This guide will help you create, interact with, and manage your first temporary network using tmpnet.
Before You Start
Make sure you've completed the installation and have:
- Built
avalanchegoandtmpnetctl - A shell in the avalanchego repo root
- Either
direnv allow'd the repo or can pass--avalanchego-path
Start Your First Network
Basic Start Command
Start a 2-node network (default is 5):
cd /path/to/avalanchego
# If you enabled direnv (.envrc sets paths)
tmpnetctl start-network --node-count=2
# Without direnv, pass the avalanchego path explicitly
./bin/tmpnetctl start-network \
--avalanchego-path="$(pwd)/bin/avalanchego" \
--node-count=2Expected Output:
[12-05|15:23:26.831] INFO tmpnet/network.go:254 preparing configuration for new network
[12-05|15:23:26.839] INFO tmpnet/network.go:385 starting network {"networkDir": "/Users/you/.tmpnet/networks/20251205-152326.831812", "uuid": "0ef20abc-4d96-438f-943c-a4442254b9bb"}
[12-05|15:23:27.992] INFO tmpnet/process_runtime.go:148 started local node {"nodeID": "NodeID-Pw8tmrG..."}
[12-05|15:23:28.395] INFO tmpnet/process_runtime.go:148 started local node {"nodeID": "NodeID-KBxAJo5..."}
[12-05|15:23:28.396] INFO tmpnet/network.go:400 waiting for nodes to report healthy
[12-05|15:23:30.399] INFO tmpnet/network.go:976 node is healthy {"nodeID": "NodeID-KBxAJo5...", "uri": "http://127.0.0.1:56395"}
[12-05|15:23:33.999] INFO tmpnet/network.go:976 node is healthy {"nodeID": "NodeID-Pw8tmrG...", "uri": "http://127.0.0.1:56386"}
[12-05|15:23:33.999] INFO tmpnet/network.go:404 started network
Configure tmpnetctl to target this network by default with one of the following statements:
- source /Users/you/.tmpnet/networks/20251205-152326.831812/network.env
- export TMPNET_NETWORK_DIR=/Users/you/.tmpnet/networks/20251205-152326.831812
- export TMPNET_NETWORK_DIR=/Users/you/.tmpnet/networks/latestThe network is now running with 2 validator nodes!
With direnv (Simpler)
If you've set up direnv:
cd /path/to/avalanchego
direnv allow
# Much simpler!
tmpnetctl start-network --node-count=2Configure Your Shell
To manage your network without specifying --network-dir every time, set TMPNET_NETWORK_DIR:
# Option 1: Use the 'latest' symlink (recommended)
export TMPNET_NETWORK_DIR=~/.tmpnet/networks/latestThe latest symlink always points to the most recently created network. Now you can run commands without flags:
tmpnetctl stop-network # Uses TMPNET_NETWORK_DIR
tmpnetctl restart-networkMake it permanent by adding to your shell config:
# For zsh (macOS)
echo 'export TMPNET_NETWORK_DIR=~/.tmpnet/networks/latest' >> ~/.zshrc
source ~/.zshrc
# For bash (Linux)
echo 'export TMPNET_NETWORK_DIR=~/.tmpnet/networks/latest' >> ~/.bashrc
source ~/.bashrcAlternative: Source the network's env file directly:
source ~/.tmpnet/networks/latest/network.envExplore Your Network
Network Directory Structure
ls ~/.tmpnet/networks/latest/Output:
config.json # Network configuration
genesis.json # Genesis file
metrics.txt # Grafana dashboard link
network.env # Environment setup script
NodeID-74mGyq7dVVCeE4RUn4pufRMvYTFTEykcp/ # Node 1 directory
NodeID-BTtC98RhLA5mbctKczZQC2Rt6N9DziM4c/ # Node 2 directoryFind Node API Endpoints
Each node exposes API endpoints on dynamically allocated ports. When tmpnet starts a node with --http-port=0, the OS assigns an available port. AvalancheGo then writes the actual allocated port to process.json via the --process-context-file flag.
How process.json is created
The process.json file is created by avalanchego itself, not by tmpnetctl. When tmpnet starts a node, it passes:
--http-port=0and--staking-port=0for dynamic port allocation--process-context-file=[node-dir]/process.jsonto specify where avalanchego should write runtime info
AvalancheGo then writes its PID, URI (with the actual allocated port), and staking address to this file once it starts.
# View all node URIs
cat ~/.tmpnet/networks/latest/NodeID-*/process.json | jq -r '.uri'Example output:
http://127.0.0.1:56395
http://127.0.0.1:56386Get a Single Node URI
# Store first node URI in a variable
NODE_URI=$(cat ~/.tmpnet/networks/latest/NodeID-*/process.json | jq -r '.uri' | head -1)
echo $NODE_URICall Node RPCs
Use the URI to call standard Avalanche APIs over HTTP:
# Health
curl -s "$NODE_URI/ext/health" | jq '.healthy'
# Node ID
curl -s -X POST --data '{
"jsonrpc": "2.0",
"id": 1,
"method": "info.getNodeID"
}' -H 'content-type:application/json;' "$NODE_URI/ext/info" | jq
# C-Chain RPC (replace with your chain ID if different)
CHAIN_ID=C
curl -s -X POST --data '{
"jsonrpc":"2.0",
"id":1,
"method":"eth_blockNumber",
"params":[]
}' -H 'content-type:application/json;' "$NODE_URI/ext/bc/$CHAIN_ID/rpc" | jqInteract with Your Network
Check Node Health
curl -s http://127.0.0.1:56395/ext/health | jq '.healthy'Response:
trueGet Node Information
curl -s -X POST --data '{
"jsonrpc": "2.0",
"id": 1,
"method": "info.getNodeID"
}' -H 'content-type:application/json;' http://127.0.0.1:56395/ext/info | jqResponse:
{
"jsonrpc": "2.0",
"result": {
"nodeID": "NodeID-74mGyq7dVVCeE4RUn4pufRMvYTFTEykcp",
"nodePOP": {
"publicKey": "...",
"proofOfPossession": "..."
}
},
"id": 1
}Check Network Info
curl -s -X POST --data '{
"jsonrpc": "2.0",
"id": 1,
"method": "info.getNetworkID"
}' -H 'content-type:application/json;' http://127.0.0.1:56395/ext/info | jqUse Pre-funded Keys
Every tmpnet network comes with 50 pre-funded test keys ready for immediate use. These keys have large balances on all chains (X-Chain, P-Chain, and C-Chain).
View Pre-funded Keys
cat ~/.tmpnet/networks/latest/config.json | jq '.preFundedKeys'Example output:
[
"PrivateKey-ewoqjP7PxY4yr3iLTpLisriqt94hdyDFNgchSxGGztUrTXtNN",
"PrivateKey-2VbLJLjPJn4XA8UqQ4BjmF5LmkZj4EZ2dXLKmKPmXTbKHvvQh6",
"PrivateKey-R6e8f5QSa89DjpvL9asNdhdJ4u8VqzMJStPV8VVdDmLgPd8x4",
...
]Get a Single Key for Testing
# Store the first pre-funded key
TEST_KEY=$(cat ~/.tmpnet/networks/latest/config.json | jq -r '.preFundedKeys[0]')
echo $TEST_KEY
# Output: PrivateKey-ewoqjP7PxY4yr3iLTpLisriqt94hdyDFNgchSxGGztUrTXtNNWhat Are These Keys Funded With?
Each key has balances on:
- P-Chain - For staking and subnet operations
- X-Chain - For asset transfers
- C-Chain - For EVM transactions (contract deployments, etc.)
You can use these keys immediately for transactions, contract deployments, staking operations, and validator management.
Use with Foundry/Cast
tmpnet networks work with standard EVM tools like Foundry. Here's how to connect.
Set Up Environment Variables
# Get the first node's URI and construct the C-Chain RPC URL
NODE_URI=$(cat ~/.tmpnet/networks/latest/NodeID-*/process.json | jq -r '.uri' | head -1)
export RPC_URL="${NODE_URI}/ext/bc/C/rpc"
echo $RPC_URL
# Example: http://127.0.0.1:56395/ext/bc/C/rpcThe EWOQ Test Key
Every tmpnet network includes the well-known EWOQ test key, pre-funded with AVAX:
| Property | Value |
|---|---|
| Private Key (hex) | 56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027 |
| Address | 0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC |
| C-Chain Balance | 50,000,000 AVAX |
export PRIVATE_KEY="56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027"Test Key Only
The EWOQ key is publicly known. Never use it on Fuji or Mainnet—only for local development.
Common Cast Commands
# Check balance
cast balance 0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC --rpc-url $RPC_URL
# Get chain ID
cast chain-id --rpc-url $RPC_URL
# Get latest block
cast block-number --rpc-url $RPC_URL
# Send AVAX to another address
cast send 0xYourAddress --value 1ether \
--rpc-url $RPC_URL \
--private-key $PRIVATE_KEYDeploy Contracts with Forge
# Deploy a contract
forge create src/MyContract.sol:MyContract \
--rpc-url $RPC_URL \
--private-key $PRIVATE_KEY
# Run a deployment script
forge script script/Deploy.s.sol \
--rpc-url $RPC_URL \
--private-key $PRIVATE_KEY \
--broadcastChain Configuration
For foundry.toml:
[rpc_endpoints]
local = "http://127.0.0.1:56395/ext/bc/C/rpc"
[etherscan]
# No explorer for local networksDynamic Ports
Remember that tmpnet uses dynamic ports. If you restart your network, the port may change. Always re-export RPC_URL after restarting.
View Network Configuration
Network Configuration
cat ~/.tmpnet/networks/latest/config.json | jq '{
uuid,
owner,
preFundedKeyCount: (.preFundedKeys | length)
}'Genesis Configuration
cat ~/.tmpnet/networks/latest/genesis.json | jq '.networkID'Node Configuration
# View node flags
cat ~/.tmpnet/networks/latest/NodeID-*/flags.json | head -1 | jq
# View node runtime config
cat ~/.tmpnet/networks/latest/NodeID-*/config.json | head -1 | jqManage Your Network
Stop the Network
tmpnetctl stop-networkOutput:
Stopped network configured at: /Users/you/.tmpnet/networks/latestRestart the Network
tmpnetctl restart-networkThis preserves all network data and configuration, restarting with the same genesis and keys.
Start a New Network
# This creates a completely new network with new keys
tmpnetctl start-network \
--avalanchego-path="$(pwd)/bin/avalanchego" \
--node-count=3View Node Logs
Watch Logs in Real-time
# Watch all node logs
tail -f ~/.tmpnet/networks/latest/NodeID-*/logs/main.log
# Watch a specific node
tail -f ~/.tmpnet/networks/latest/NodeID-74mGyq7dVVCeE4RUn4pufRMvYTFTEykcp/logs/main.logSearch Logs for Errors
grep -i "error" ~/.tmpnet/networks/latest/NodeID-*/logs/main.logView Recent Log Lines
tail -50 ~/.tmpnet/networks/latest/NodeID-*/logs/main.logCommon Operations
Check Running Processes
# View all node processes
ps aux | grep avalanchego
# Count running nodes
ps aux | grep avalanchego | grep -v grep | wc -lGet All Node URIs at Once
# Create a simple script
for process_file in ~/.tmpnet/networks/latest/NodeID-*/process.json; do
jq -r '.uri' "$process_file"
doneCheck Node Process Details
# View process information for all nodes
cat ~/.tmpnet/networks/latest/NodeID-*/process.json | jq '{
pid,
uri,
stakingAddress
}'Directory Structure Reference
~/.tmpnet/networks/latest/
├── config.json # Network configuration (owner, UUID, keys)
├── genesis.json # Genesis file with allocations
├── metrics.txt # Grafana dashboard link
├── network.env # Shell environment variables
└── NodeID-<ID>/ # Per-node directory
├── config.json # Node runtime configuration
├── flags.json # Node flags
├── process.json # Process info (PID, URIs, ports)
├── logs/
│ └── main.log # Node logs
├── db/ # Node database
└── chainData/ # Chain dataTroubleshooting
Network Won't Start
Error: avalanchego binary not found
Solution:
# Verify binary exists
ls -lh ./bin/avalanchego
# Use absolute path
tmpnetctl start-network \
--avalanchego-path="$(pwd)/bin/avalanchego"Error: address already in use
Solution:
# Check for running nodes
ps aux | grep avalanchego
# Stop existing network
export TMPNET_NETWORK_DIR=~/.tmpnet/networks/latest
tmpnetctl stop-networkCan't Connect to Nodes
Issue: Curl commands fail
Solution:
# 1. Verify nodes are running
ps aux | grep avalanchego
# 2. Check actual URIs
cat ~/.tmpnet/networks/latest/NodeID-*/process.json | jq -r '.uri'
# 3. Test health endpoint with correct URI
curl http://127.0.0.1:<actual-port>/ext/healthMissing process.json Files
Issue: process.json files don't exist in node directories, or ports in flags.json are all 0
This happens when running avalanchego manually without the --process-context-file flag.
Understanding the issue:
flags.jsonshowing"http-port": "0"is correct - this tells the OS to allocate a dynamic portprocess.jsonis created by avalanchego itself when started with the--process-context-fileflag- tmpnetctl automatically passes this flag, but manual setups need to include it
Solution for manual avalanchego setups:
# When starting avalanchego manually with dynamic ports, include:
avalanchego \
--http-port=0 \
--staking-port=0 \
--process-context-file=/path/to/node/process.json \
# ... other flags
# AvalancheGo will write the actual allocated ports to process.jsonIf using tmpnetctl: The process.json files should be created automatically. If they're missing, ensure:
- The network started successfully (check for "started network" in output)
- Nodes are still running (
ps aux | grep avalanchego) - You're looking in the correct network directory
Command Not Found
Error: tmpnetctl: command not found
Solution:
# Use full path
./bin/tmpnetctl --help
# Or add to PATH
export PATH=$PATH:$(pwd)/bin
tmpnetctl --help
# Or use direnv
direnv allow
tmpnetctl --helpClean Up Everything
To remove all networks and start fresh:
# Stop any running networks
export TMPNET_NETWORK_DIR=~/.tmpnet/networks/latest
tmpnetctl stop-network
# Remove all tmpnet data (optional)
rm -rf ~/.tmpnet/networksNext Steps
Now that you have a running network, learn how to:
Is this guide helpful?