Building on Nexus: A Developer's Starting Point
NexusEVM is a fully EVM-compatible L1. If you've deployed on Ethereum or any EVM chain, the tools and
NexusEVM is a fully EVM-compatible L1. If you've deployed on Ethereum or any EVM chain, the tools and patterns you already use work here.
This post covers everything you need to go from zero to a deployed contract: network configuration, RPC basics, toolchain setup, and the places where Nexus behaves differently from Ethereum.
There are two networks: mainnet (chain ID 3946) and testnet (chain ID 3945). Both are live.
RPC endpoints:
Mainnet HTTP: https://mainnet.rpc.nexus.xyz
Mainnet WSS: wss://mainnet.rpc.nexus.xyz
Testnet HTTP: https://testnet.rpc.nexus.xyz
Testnet WSS: wss://testnet.rpc.nexus.xyz
Get testnet NEX from the faucet at https://faucet.nexus.xyz.
To add Nexus Mainnet manually in MetaMask or any EIP-1193 wallet, use these values:
Network Name: Nexus Mainnet
RPC URL: https://mainnet.rpc.nexus.xyz
Chain ID: 3946
Currency Symbol: NEX
Block Explorer: https://explorer.nexus.xyz
To add the network programmatically:
await window.ethereum.request({
method: "wallet_addEthereumChain",
params: [{
chainId: "0xF6A", // 3946 in hex
chainName: "Nexus Mainnet",
nativeCurrency: { name: "NEX", symbol: "NEX", decimals: 18 },
rpcUrls: ["https://mainnet.rpc.nexus.xyz"],
blockExplorerUrls: ["https://explorer.nexus.xyz"],
}],
});
The testnet block explorer is at https://testnet.explorer.nexus.xyz.
Before touching your toolchain, confirm the RPC is reachable and returning the right chain ID:
curl -s -X POST https://mainnet.rpc.nexus.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'
Expected response: "0xf6a" (3946 for mainnet) or "0xf69" (3945 for testnet). If that's what you see, you're connected.
Building on Nexus Mainnet? Tag @NexusLabs on X so we can check out your project.
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox
hardhat.config.ts:
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
const config: HardhatUserConfig = {
solidity: "0.8.24",
networks: {
nexusMainnet: {
url: process.env.NEXUS_RPC_URL || "https://mainnet.rpc.nexus.xyz",
chainId: 3946,
accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [],
},
nexusTestnet: {
url: process.env.NEXUS_TESTNET_RPC_URL || "https://testnet.rpc.nexus.xyz",
chainId: 3945,
accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [],
},
},
};
export default config;
Deploy:
npx hardhat run scripts/deploy.ts --network nexusMainnet
Verify a deployment:
cast code 0xYOUR_CONTRACT_ADDRESS --rpc-url https://mainnet.rpc.nexus.xyz
curl -L https://foundry.paradigm.xyz | bash
foundryup
foundry.toml:
[profile.default]
solc_version = "0.8.24"
[rpc_endpoints]
nexus_mainnet = "https://mainnet.rpc.nexus.xyz"
nexus_testnet = "https://testnet.rpc.nexus.xyz"
Deploy to testnet:
forge create src/MyContract.sol:MyContract \
--rpc-url nexus_testnet \
--chain-id 3945 \
--private-key $PRIVATE_KEY
With constructor arguments:
forge create src/MyContract.sol:MyContract \
--rpc-url nexus_mainnet \
--chain-id 3946 \
--private-key $PRIVATE_KEY \
--constructor-args "arg1" 42
Open Remix IDE, go to the Deploy & Run tab, select "Injected Provider — MetaMask", and make sure MetaMask is connected to Nexus (chain ID 3946 for mainnet, 3945 for testnet). Everything else works the same as on any EVM chain.
Nexus uses standard JSON-RPC 2.0. The full eth_*, net_*, and web3_* namespaces are supported. A few things worth knowing:
Batch requests are supported — up to 10 sub-requests per batch, with a 2 MB payload ceiling. If you exceed either limit, you'll get a -32005 error. When rate-limited, the response includes a Retry-After header; back off and retry after that interval.
A quick batch example:
curl -s -X POST https://mainnet.rpc.nexus.xyz \
-H "Content-Type: application/json" \
-d '[
{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1},
{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":2},
{"jsonrpc":"2.0","method":"eth_gasPrice","params":[],"id":3}
]'
EIP-1559 transactions are fully supported. Use maxFeePerGas and maxPriorityFeePerGas in your transaction object. Gas is paid in NEX, and opcode costs mirror Ethereum exactly.
EIP-4844 blobs are not used on Nexus — eth_blobBaseFee always returns 0x1. ENS is not available on NexusEVM.
NexusEVM is EVM-compatible but it's not Ethereum. A few differences matter at the application level:
Block time is 1 second, versus Ethereum's 12 seconds. Time-based logic still works — block.timestamp increments reliably — but any code that uses block.number as a time proxy will behave differently. Audit those patterns before deploying.
Finality is single-slot. There are no reorgs, no uncle blocks. One confirmation is sufficient and block.number is always authoritative. You don't need to wait for multiple confirmations the way you would on Ethereum.
Transaction ordering follows CometBFT's FIFO mempool. There's no gas auction and no MEV competition. Transactions are ordered by arrival time.
The native currency is NEX. msg.value transfers NEX, not ETH.
WebSocket endpoints are available at wss://mainnet.rpc.nexus.xyz and wss://testnet.rpc.nexus.xyz, but they require an X-Api-Key header on the upgrade handshake. Because browsers can't set custom headers on WebSocket connections, WSS is currently limited to server-side use. Browser dApps should use HTTP polling or a server-side relay.
Three subscription types are available: newHeads (a header object per block, roughly once per second), logs (real-time log entries matching a filter), and newPendingTransactions (tx hashes as they enter the mempool).
Node.js example:
const WebSocket = require("ws");
const ws = new WebSocket("wss://mainnet.rpc.nexus.xyz", {
headers: { "X-Api-Key": "YOUR_API_KEY" },
});
ws.on("open", () => {
ws.send(JSON.stringify({
jsonrpc: "2.0",
method: "eth_subscribe",
params: ["newHeads"],
id: 1,
}));
});
ws.on("message", (data) => {
const msg = JSON.parse(data);
if (msg.params) {
console.log("New block:", parseInt(msg.params.result.number, 16));
}
});
Debug and trace methods are not available on the default RPC endpoint. They're served from a separate archive node — just append /archive to the RPC URL:
# Transaction trace
curl -s -X POST https://mainnet.rpc.nexus.xyz/archive \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"debug_traceTransaction","params":["0xYOUR_TX_HASH",{"tracer":"callTracer"}],"id":1}'
# Block traces (Parity style)
curl -s -X POST https://mainnet.rpc.nexus.xyz/archive \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"trace_block","params":["0x2c620e"],"id":1}'
Supported methods on /archive: debug_traceTransaction, debug_traceBlockByNumber, debug_traceBlockByHash, trace_block, trace_transaction, trace_replayTransaction. Both callTracer and prestateTracer are supported. Note that trace_block doesn't accept block tags like "latest" — pass a hex block number.
Standard methods (eth_blockNumber, eth_chainId, etc.) are rejected on the /archive path. Use the default endpoint for those. eth_getLogs with a block range is automatically routed to the archive node when needed.
When the Exchange launches, NexusEVM contracts will be able to call into NexusCore — placing orders, reading market data, and managing margin atomically within a single EVM transaction. The composability surface between onchain contracts and the exchange is being designed with that integration in mind.
The full RPC reference, including supported methods and error codes, is at docs.nexus.xyz. If you run into issues, the /archive endpoint returns standard JSON-RPC errors, so your existing error handling should work without modification.