Skip to main content

Overview

Nexis Network is fully compatible with the Ethereum JSON-RPC API, based on the Optimism stack. This means you can use standard Ethereum tools and libraries to interact with Nexis. Endpoints:
  • Mainnet: https://rpc.nex-t1.ai
  • Testnet: https://testnet-rpc.nex-t1.ai
  • WebSocket (Testnet): wss://testnet-ws.nex-t1.ai
Key Features:
  • Full Ethereum JSON-RPC compatibility
  • Optimism-specific methods for L2 functionality
  • WebSocket support for real-time event subscriptions
  • Archive node support for historical state queries
  • Debug and trace methods for development

Standard Ethereum Methods

eth_blockNumber

Get the latest block number. Parameters: None Returns:
  • QUANTITY - Integer block number (hex-encoded)
Example:
const provider = new ethers.JsonRpcProvider('https://testnet-rpc.nex-t1.ai');
const blockNumber = await provider.getBlockNumber();
console.log("Latest block:", blockNumber);

eth_getBalance

Get the balance of an account. Parameters:
  1. DATA, 20 bytes - Address to check
  2. QUANTITY|TAG - Block number (hex), or “latest”, “earliest”, “pending”
Returns:
  • QUANTITY - Balance in wei (hex-encoded)
Example:
const address = "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb";
const balance = await provider.getBalance(address);
console.log("Balance:", ethers.formatEther(balance), "ETH");

// At specific block
const balanceAtBlock = await provider.getBalance(address, 1000000);

eth_getBlockByNumber

Get block information by block number. Parameters:
  1. QUANTITY|TAG - Block number or “latest”, “earliest”, “pending”
  2. BOOLEAN - If true, returns full transaction objects; if false, only hashes
Returns:
  • Object - Block object with fields:
    • number - Block number
    • hash - Block hash
    • parentHash - Parent block hash
    • timestamp - Block timestamp (Unix)
    • transactions - Array of transaction hashes or objects
    • gasUsed - Gas used in this block
    • gasLimit - Gas limit for this block
    • And more…
Example:
// Get latest block with full transactions
const block = await provider.getBlock("latest", true);
console.log("Block number:", block.number);
console.log("Block hash:", block.hash);
console.log("Timestamp:", new Date(block.timestamp * 1000));
console.log("Transactions:", block.transactions.length);

// Get specific block
const specificBlock = await provider.getBlock(1000000);

eth_getTransactionByHash

Get transaction information by transaction hash. Parameters:
  1. DATA, 32 bytes - Transaction hash
Returns:
  • Object - Transaction object or null if not found
Example:
const txHash = "0x...";
const tx = await provider.getTransaction(txHash);

console.log("Transaction Details:");
console.log("  From:", tx.from);
console.log("  To:", tx.to);
console.log("  Value:", ethers.formatEther(tx.value), "ETH");
console.log("  Gas Price:", ethers.formatUnits(tx.gasPrice, "gwei"), "Gwei");
console.log("  Nonce:", tx.nonce);
console.log("  Block Number:", tx.blockNumber);

eth_getTransactionReceipt

Get transaction receipt (result of execution). Parameters:
  1. DATA, 32 bytes - Transaction hash
Returns:
  • Object - Receipt object with:
    • status - 1 for success, 0 for failure
    • blockNumber - Block number
    • gasUsed - Gas used by this transaction
    • logs - Array of log objects (events)
    • contractAddress - Address of created contract (if applicable)
Example:
const receipt = await provider.getTransactionReceipt(txHash);

console.log("Receipt:");
console.log("  Status:", receipt.status === 1 ? "Success" : "Failed");
console.log("  Block:", receipt.blockNumber);
console.log("  Gas Used:", receipt.gasUsed.toString());
console.log("  Logs:", receipt.logs.length);

// Check if transaction succeeded
if (receipt.status === 1) {
  console.log("✅ Transaction succeeded");
} else {
  console.log("❌ Transaction failed");
}

eth_sendRawTransaction

Submit a signed transaction to the network. Parameters:
  1. DATA - Signed transaction data (RLP-encoded)
Returns:
  • DATA, 32 bytes - Transaction hash
Example:
// Create and sign transaction
const tx = await wallet.signTransaction({
  to: "0x...",
  value: ethers.parseEther("0.1"),
  gasLimit: 21000,
  gasPrice: await provider.getFeeData().gasPrice,
  nonce: await provider.getTransactionCount(wallet.address)
});

// Send signed transaction
const txHash = await provider.broadcastTransaction(tx);
console.log("Transaction hash:", txHash);

// Wait for confirmation
const receipt = await provider.waitForTransaction(txHash);
console.log("Confirmed in block:", receipt.blockNumber);

eth_call

Execute a contract function call without creating a transaction (read-only). Parameters:
  1. Object - Transaction call object:
    • to - Contract address
    • data - Encoded function call data
    • (optional) from, gas, gasPrice, value
  2. QUANTITY|TAG - Block number or “latest”
Returns:
  • DATA - Return value of the executed contract method
Example:
// Call contract method (read-only)
const contract = new ethers.Contract(contractAddress, abi, provider);

// Simple call
const balance = await contract.balanceOf(accountAddress);
console.log("Token balance:", balance.toString());

// Call at specific block
const historicalBalance = await contract.balanceOf(
  accountAddress,
  { blockTag: 1000000 }
);

eth_estimateGas

Estimate gas required for a transaction. Parameters:
  1. Object - Transaction object (same as eth_call)
Returns:
  • QUANTITY - Estimated gas amount
Example:
// Estimate gas for transfer
const gasEstimate = await provider.estimateGas({
  to: recipientAddress,
  value: ethers.parseEther("1.0")
});

console.log("Estimated gas:", gasEstimate.toString());

// Estimate gas for contract call
const contract = new ethers.Contract(address, abi, wallet);
const gasForContractCall = await contract.transfer.estimateGas(
  recipientAddress,
  ethers.parseUnits("100", 18)
);

eth_gasPrice

Get current gas price. Parameters: None Returns:
  • QUANTITY - Current gas price in wei
Example:
JavaScript
const gasPrice = await provider.getFeeData();
console.log("Gas price:", ethers.formatUnits(gasPrice.gasPrice, "gwei"), "Gwei");
console.log("Max fee:", ethers.formatUnits(gasPrice.maxFeePerGas, "gwei"), "Gwei");
console.log("Priority fee:", ethers.formatUnits(gasPrice.maxPriorityFeePerGas, "gwei"), "Gwei");

eth_getTransactionCount

Get the number of transactions sent from an address (nonce). Parameters:
  1. DATA, 20 bytes - Address
  2. QUANTITY|TAG - Block number or “latest”, “pending”
Returns:
  • QUANTITY - Transaction count (nonce)
Example:
JavaScript
const nonce = await provider.getTransactionCount(address);
console.log("Nonce:", nonce);

// Get pending nonce (includes pending transactions)
const pendingNonce = await provider.getTransactionCount(address, "pending");

eth_getLogs

Get logs matching a filter. Parameters:
  1. Object - Filter options:
    • fromBlock - Starting block (number or “latest”)
    • toBlock - Ending block
    • address - Contract address(es)
    • topics - Array of topics (event signatures)
Returns:
  • Array - Log objects
Example:
// Get all Transfer events for a token
const transferTopic = ethers.id("Transfer(address,address,uint256)");

const logs = await provider.getLogs({
  fromBlock: 1000000,
  toBlock: "latest",
  address: tokenAddress,
  topics: [transferTopic]
});

console.log("Found", logs.length, "Transfer events");

// Decode logs
logs.forEach(log => {
  const decoded = tokenInterface.parseLog(log);
  console.log("Transfer from", decoded.args.from, "to", decoded.args.to);
});

eth_chainId

Get the chain ID of the network. Parameters: None Returns:
  • QUANTITY - Chain ID
Example:
JavaScript
const network = await provider.getNetwork();
console.log("Chain ID:", network.chainId); // 2371 for testnet, 2370 for mainnet

Optimism-Specific Methods

Nexis Network inherits Optimism functionality for L2 operations.

optimism_syncStatus

Get sync status of the node. Parameters: None Returns:
  • Object - Sync status information
Example:
cURL
curl -X POST https://testnet-rpc.nex-t1.ai \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "optimism_syncStatus",
    "params": [],
    "id": 1
  }'

# Response includes:
# - current_l1: Latest L1 block known
# - head_l1: L1 block head
# - safe_l1: Safe L1 block
# - finalized_l1: Finalized L1 block

optimism_outputAtBlock

Get the output root at a specific L2 block. Parameters:
  1. QUANTITY - L2 block number
Returns:
  • Object - Output information
Example:
cURL
curl -X POST https://testnet-rpc.nex-t1.ai \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "optimism_outputAtBlock",
    "params": ["0xf4240"],
    "id": 1
  }'

WebSocket Methods

eth_subscribe

Subscribe to real-time events. Subscription Types:
  • newHeads - New block headers
  • logs - New logs matching a filter
  • newPendingTransactions - New pending transactions
  • syncing - Sync status changes
Example:
const wsProvider = new ethers.WebSocketProvider('wss://testnet-ws.nex-t1.ai');

// Subscribe to new blocks
wsProvider.on("block", (blockNumber) => {
  console.log("New block:", blockNumber);
});

// Subscribe to contract events
const contract = new ethers.Contract(address, abi, wsProvider);
contract.on("Transfer", (from, to, amount, event) => {
  console.log("Transfer:", {
    from,
    to,
    amount: ethers.formatUnits(amount, 18),
    blockNumber: event.log.blockNumber
  });
});

// Subscribe to pending transactions
wsProvider.on("pending", (txHash) => {
  console.log("Pending tx:", txHash);
});

eth_unsubscribe

Unsubscribe from a subscription. Parameters:
  1. DATA - Subscription ID
Returns:
  • BOOLEAN - True if successful

Debug and Trace Methods

Available on archive nodes for development and debugging.

debug_traceTransaction

Get detailed execution trace of a transaction. Parameters:
  1. DATA - Transaction hash
  2. Object - Tracer options
Returns:
  • Object - Trace result
Example:
cURL
curl -X POST https://testnet-rpc.nex-t1.ai \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "debug_traceTransaction",
    "params": [
      "0x...",
      {"tracer": "callTracer"}
    ],
    "id": 1
  }'

debug_traceBlockByNumber

Trace all transactions in a block. Parameters:
  1. QUANTITY - Block number
  2. Object - Tracer options
Returns:
  • Array - Array of trace results

Admin Methods

Administrative methods for node operators.

admin_startSequencer

Start the sequencer (for Nexis node operators). Parameters: None Returns:
  • BOOLEAN - Success status

admin_stopSequencer

Stop the sequencer. Parameters: None Returns:
  • BOOLEAN - Success status

Error Codes

Standard JSON-RPC error codes:
CodeMessageDescription
-32700Parse errorInvalid JSON
-32600Invalid requestMissing required fields
-32601Method not foundRPC method doesn’t exist
-32602Invalid paramsInvalid method parameters
-32603Internal errorServer error
-32000Server errorGeneric execution error
-32001Resource not foundRequested resource doesn’t exist
-32002Resource unavailableResource temporarily unavailable
-32003Transaction rejectedTransaction failed validation
-32004Method not supportedMethod not implemented
-32005Limit exceededRequest exceeds limits
Example Error Response:
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32000,
    "message": "execution reverted: insufficient balance",
    "data": "0x..."
  }
}

Rate Limits

TierRequests/SecondBurstWebSocket Connections
Free10020010 per IP
Pro1,0002,00050 per IP
EnterpriseCustomCustomCustom
Rate Limit Headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1638360000
Rate Limit Error:
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32005,
    "message": "rate limit exceeded",
    "data": {
      "limit": 100,
      "reset": 1638360000
    }
  }
}

Best Practices

  • Reuse HTTP connections with keep-alive
  • Use WebSocket for real-time subscriptions
  • Implement connection pooling for high throughput
  • Handle reconnection with exponential backoff
  • Always check for error field in responses
  • Implement retry logic for transient errors
  • Log errors with request context
  • Handle rate limits gracefully
  • Batch requests when possible (eth_batch)
  • Cache responses for immutable data (old blocks)
  • Use appropriate block tags (latest vs finalized)
  • Filter logs efficiently with precise topics
  • Use HTTPS endpoints only
  • Never expose API keys in client code
  • Validate all user input before RPC calls
  • Implement request signing for write operations

Complete Integration Example

import { ethers } from 'ethers';

class NexisClient {
  constructor(privateKey) {
    // Connect to Nexis testnet
    this.provider = new ethers.JsonRpcProvider(
      'https://testnet-rpc.nex-t1.ai'
    );
    this.wallet = new ethers.Wallet(privateKey, this.provider);

    // WebSocket for events
    this.wsProvider = new ethers.WebSocketProvider(
      'wss://testnet-ws.nex-t1.ai'
    );
  }

  async getNetworkInfo() {
    const network = await this.provider.getNetwork();
    const blockNumber = await this.provider.getBlockNumber();
    const gasPrice = await this.provider.getFeeData();

    return {
      chainId: network.chainId,
      name: network.name,
      blockNumber,
      gasPrice: ethers.formatUnits(gasPrice.gasPrice, 'gwei')
    };
  }

  async getAccountInfo(address) {
    const balance = await this.provider.getBalance(address);
    const nonce = await this.provider.getTransactionCount(address);
    const code = await this.provider.getCode(address);

    return {
      address,
      balance: ethers.formatEther(balance),
      nonce,
      isContract: code !== '0x'
    };
  }

  async sendTransaction(to, value) {
    const tx = await this.wallet.sendTransaction({
      to,
      value: ethers.parseEther(value.toString())
    });

    console.log('Transaction sent:', tx.hash);

    const receipt = await tx.wait();
    console.log('Confirmed in block:', receipt.blockNumber);

    return receipt;
  }

  async callContract(address, abi, method, ...args) {
    const contract = new ethers.Contract(address, abi, this.provider);
    return await contract[method](...args);
  }

  async executeContract(address, abi, method, ...args) {
    const contract = new ethers.Contract(address, abi, this.wallet);
    const tx = await contract[method](...args);
    return await tx.wait();
  }

  subscribeToBlocks(callback) {
    this.wsProvider.on('block', callback);
  }

  subscribeToEvents(address, abi, eventName, callback) {
    const contract = new ethers.Contract(address, abi, this.wsProvider);
    contract.on(eventName, callback);
  }

  async getTransactionHistory(address, fromBlock = 0) {
    const filter = {
      fromBlock,
      toBlock: 'latest',
      topics: [
        null, // Any event
        ethers.zeroPadValue(address, 32) // Address as topic
      ]
    };

    const logs = await this.provider.getLogs(filter);
    return logs;
  }
}

// Usage
const client = new NexisClient(process.env.PRIVATE_KEY);

// Get network info
const networkInfo = await client.getNetworkInfo();
console.log('Network:', networkInfo);

// Get account info
const accountInfo = await client.getAccountInfo(client.wallet.address);
console.log('Account:', accountInfo);

// Subscribe to new blocks
client.subscribeToBlocks((blockNumber) => {
  console.log('New block:', blockNumber);
});

// Send transaction
const receipt = await client.sendTransaction(
  '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
  0.1
);

Additional Resources