> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nex-t1.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# JSON-RPC Methods

> Complete reference for Nexis Network JSON-RPC API methods

## 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:**

<CodeGroup>
  ```javascript JavaScript (ethers.js) theme={null}
  const provider = new ethers.JsonRpcProvider('https://testnet-rpc.nex-t1.ai');
  const blockNumber = await provider.getBlockNumber();
  console.log("Latest block:", blockNumber);
  ```

  ```javascript JavaScript (raw JSON-RPC) theme={null}
  const response = await fetch('https://testnet-rpc.nex-t1.ai', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      method: 'eth_blockNumber',
      params: [],
      id: 1
    })
  });

  const data = await response.json();
  const blockNumber = parseInt(data.result, 16);
  console.log("Latest block:", blockNumber);
  ```

  ```python Python theme={null}
  from web3 import Web3

  w3 = Web3(Web3.HTTPProvider('https://testnet-rpc.nex-t1.ai'))
  block_number = w3.eth.block_number
  print(f"Latest block: {block_number}")
  ```

  ```bash cURL theme={null}
  curl -X POST https://testnet-rpc.nex-t1.ai \
    -H "Content-Type: application/json" \
    -d '{
      "jsonrpc": "2.0",
      "method": "eth_blockNumber",
      "params": [],
      "id": 1
    }'

  # Response:
  # {"jsonrpc":"2.0","id":1,"result":"0x12ab34"}
  ```
</CodeGroup>

***

### 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:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  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);
  ```

  ```python Python theme={null}
  address = "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
  balance = w3.eth.get_balance(address)
  print(f"Balance: {w3.from_wei(balance, 'ether')} ETH")

  # At specific block
  balance_at_block = w3.eth.get_balance(address, 1000000)
  ```

  ```bash cURL theme={null}
  curl -X POST https://testnet-rpc.nex-t1.ai \
    -H "Content-Type: application/json" \
    -d '{
      "jsonrpc": "2.0",
      "method": "eth_getBalance",
      "params": ["0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", "latest"],
      "id": 1
    }'
  ```
</CodeGroup>

***

### 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:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  // 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);
  ```

  ```python Python theme={null}
  # Get latest block
  block = w3.eth.get_block('latest')
  print(f"Block number: {block.number}")
  print(f"Block hash: {block.hash.hex()}")
  print(f"Transactions: {len(block.transactions)}")

  # Get block with full transaction objects
  block_with_txs = w3.eth.get_block('latest', full_transactions=True)
  ```

  ```bash cURL theme={null}
  curl -X POST https://testnet-rpc.nex-t1.ai \
    -H "Content-Type: application/json" \
    -d '{
      "jsonrpc": "2.0",
      "method": "eth_getBlockByNumber",
      "params": ["latest", false],
      "id": 1
    }'
  ```
</CodeGroup>

***

### 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:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  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);
  ```

  ```python Python theme={null}
  tx_hash = "0x..."
  tx = w3.eth.get_transaction(tx_hash)

  print("Transaction Details:")
  print(f"  From: {tx['from']}")
  print(f"  To: {tx['to']}")
  print(f"  Value: {w3.from_wei(tx['value'], 'ether')} ETH")
  print(f"  Block: {tx['blockNumber']}")
  ```
</CodeGroup>

***

### 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:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  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");
  }
  ```

  ```python Python theme={null}
  receipt = w3.eth.get_transaction_receipt(tx_hash)

  print("Receipt:")
  print(f"  Status: {'Success' if receipt.status == 1 else 'Failed'}")
  print(f"  Block: {receipt.blockNumber}")
  print(f"  Gas Used: {receipt.gasUsed}")
  print(f"  Logs: {len(receipt.logs)}")
  ```
</CodeGroup>

***

### eth\_sendRawTransaction

Submit a signed transaction to the network.

**Parameters:**

1. `DATA` - Signed transaction data (RLP-encoded)

**Returns:**

* `DATA`, 32 bytes - Transaction hash

**Example:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  // 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);
  ```

  ```python Python theme={null}
  # Build transaction
  tx = {
      'to': '0x...',
      'value': w3.to_wei(0.1, 'ether'),
      'gas': 21000,
      'gasPrice': w3.eth.gas_price,
      'nonce': w3.eth.get_transaction_count(account.address)
  }

  # Sign transaction
  signed_tx = account.sign_transaction(tx)

  # Send
  tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
  print(f"Transaction hash: {tx_hash.hex()}")

  # Wait for receipt
  receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
  ```
</CodeGroup>

***

### 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:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  // 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 }
  );
  ```

  ```python Python theme={null}
  # Call contract method
  contract = w3.eth.contract(address=contract_address, abi=contract_abi)

  # Simple call
  balance = contract.functions.balanceOf(account_address).call()
  print(f"Token balance: {balance}")

  # Call at specific block
  historical_balance = contract.functions.balanceOf(
      account_address
  ).call(block_identifier=1000000)
  ```
</CodeGroup>

***

### eth\_estimateGas

Estimate gas required for a transaction.

**Parameters:**

1. `Object` - Transaction object (same as eth\_call)

**Returns:**

* `QUANTITY` - Estimated gas amount

**Example:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  // 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)
  );
  ```

  ```python Python theme={null}
  # Estimate gas for transfer
  gas_estimate = w3.eth.estimate_gas({
      'to': recipient_address,
      'value': w3.to_wei(1, 'ether'),
      'from': sender_address
  })

  print(f"Estimated gas: {gas_estimate}")
  ```
</CodeGroup>

***

### eth\_gasPrice

Get current gas price.

**Parameters:** None

**Returns:**

* `QUANTITY` - Current gas price in wei

**Example:**

```javascript JavaScript theme={null}
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 JavaScript theme={null}
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:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  // 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);
  });
  ```

  ```python Python theme={null}
  # Get Transfer events
  transfer_topic = w3.keccak(text='Transfer(address,address,uint256)').hex()

  logs = w3.eth.get_logs({
      'fromBlock': 1000000,
      'toBlock': 'latest',
      'address': token_address,
      'topics': [transfer_topic]
  })

  print(f"Found {len(logs)} Transfer events")
  ```
</CodeGroup>

***

### eth\_chainId

Get the chain ID of the network.

**Parameters:** None

**Returns:**

* `QUANTITY` - Chain ID

**Example:**

```javascript JavaScript theme={null}
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:**

```bash cURL theme={null}
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:**

```bash cURL theme={null}
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:**

<CodeGroup>
  ```javascript JavaScript (ethers.js) theme={null}
  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);
  });
  ```

  ```javascript JavaScript (raw WebSocket) theme={null}
  const WebSocket = require('ws');
  const ws = new WebSocket('wss://testnet-ws.nex-t1.ai');

  ws.on('open', () => {
    // Subscribe to new blocks
    ws.send(JSON.stringify({
      jsonrpc: '2.0',
      id: 1,
      method: 'eth_subscribe',
      params: ['newHeads']
    }));
  });

  ws.on('message', (data) => {
    const response = JSON.parse(data);
    if (response.params) {
      console.log("New block:", response.params.result);
    }
  });
  ```

  ```python Python (web3.py) theme={null}
  from web3 import Web3

  ws_url = 'wss://testnet-ws.nex-t1.ai'
  w3 = Web3(Web3.WebsocketProvider(ws_url))

  # Subscribe to new blocks
  def handle_block(block_hash):
      block = w3.eth.get_block(block_hash)
      print(f"New block: {block.number}")

  block_filter = w3.eth.filter('latest')
  w3.eth.filter('latest').watch(handle_block)

  # Subscribe to contract events
  event_filter = contract.events.Transfer.create_filter(fromBlock='latest')
  for event in event_filter.get_new_entries():
      print(f"Transfer: {event.args}")
  ```
</CodeGroup>

***

### 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:**

```bash cURL theme={null}
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:

| Code   | Message              | Description                      |
| ------ | -------------------- | -------------------------------- |
| -32700 | Parse error          | Invalid JSON                     |
| -32600 | Invalid request      | Missing required fields          |
| -32601 | Method not found     | RPC method doesn't exist         |
| -32602 | Invalid params       | Invalid method parameters        |
| -32603 | Internal error       | Server error                     |
| -32000 | Server error         | Generic execution error          |
| -32001 | Resource not found   | Requested resource doesn't exist |
| -32002 | Resource unavailable | Resource temporarily unavailable |
| -32003 | Transaction rejected | Transaction failed validation    |
| -32004 | Method not supported | Method not implemented           |
| -32005 | Limit exceeded       | Request exceeds limits           |

**Example Error Response:**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32000,
    "message": "execution reverted: insufficient balance",
    "data": "0x..."
  }
}
```

***

## Rate Limits

| Tier       | Requests/Second | Burst  | WebSocket Connections |
| ---------- | --------------- | ------ | --------------------- |
| Free       | 100             | 200    | 10 per IP             |
| Pro        | 1,000           | 2,000  | 50 per IP             |
| Enterprise | Custom          | Custom | Custom                |

**Rate Limit Headers:**

```
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1638360000
```

**Rate Limit Error:**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32005,
    "message": "rate limit exceeded",
    "data": {
      "limit": 100,
      "reset": 1638360000
    }
  }
}
```

***

## Best Practices

<AccordionGroup>
  <Accordion title="Connection Management">
    * Reuse HTTP connections with keep-alive
    * Use WebSocket for real-time subscriptions
    * Implement connection pooling for high throughput
    * Handle reconnection with exponential backoff
  </Accordion>

  <Accordion title="Error Handling">
    * Always check for error field in responses
    * Implement retry logic for transient errors
    * Log errors with request context
    * Handle rate limits gracefully
  </Accordion>

  <Accordion title="Performance Optimization">
    * 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
  </Accordion>

  <Accordion title="Security">
    * Use HTTPS endpoints only
    * Never expose API keys in client code
    * Validate all user input before RPC calls
    * Implement request signing for write operations
  </Accordion>
</AccordionGroup>

***

## Complete Integration Example

<CodeGroup>
  ```javascript JavaScript theme={null}
  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
  );
  ```

  ```python Python theme={null}
  from web3 import Web3
  from eth_account import Account
  import json

  class NexisClient:
      def __init__(self, private_key):
          # Connect to Nexis testnet
          self.w3 = Web3(Web3.HTTPProvider('https://testnet-rpc.nex-t1.ai'))
          self.account = Account.from_key(private_key)

          # WebSocket connection
          self.ws_w3 = Web3(Web3.WebsocketProvider('wss://testnet-ws.nex-t1.ai'))

      def get_network_info(self):
          return {
              'chain_id': self.w3.eth.chain_id,
              'block_number': self.w3.eth.block_number,
              'gas_price': self.w3.from_wei(self.w3.eth.gas_price, 'gwei')
          }

      def get_account_info(self, address):
          balance = self.w3.eth.get_balance(address)
          nonce = self.w3.eth.get_transaction_count(address)
          code = self.w3.eth.get_code(address)

          return {
              'address': address,
              'balance': self.w3.from_wei(balance, 'ether'),
              'nonce': nonce,
              'is_contract': code != b'\\x00'
          }

      def send_transaction(self, to, value_eth):
          tx = {
              'to': to,
              'value': self.w3.to_wei(value_eth, 'ether'),
              'gas': 21000,
              'gasPrice': self.w3.eth.gas_price,
              'nonce': self.w3.eth.get_transaction_count(self.account.address)
          }

          signed_tx = self.account.sign_transaction(tx)
          tx_hash = self.w3.eth.send_raw_transaction(signed_tx.rawTransaction)

          print(f'Transaction sent: {tx_hash.hex()}')

          receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash)
          print(f'Confirmed in block: {receipt.blockNumber}')

          return receipt

      def call_contract(self, address, abi, method, *args):
          contract = self.w3.eth.contract(address=address, abi=abi)
          return contract.functions[method](*args).call()

      def execute_contract(self, address, abi, method, *args):
          contract = self.w3.eth.contract(address=address, abi=abi)

          tx = contract.functions[method](*args).build_transaction({
              'from': self.account.address,
              'gas': 500000,
              'gasPrice': self.w3.eth.gas_price,
              'nonce': self.w3.eth.get_transaction_count(self.account.address)
          })

          signed_tx = self.account.sign_transaction(tx)
          tx_hash = self.w3.eth.send_raw_transaction(signed_tx.rawTransaction)

          return self.w3.eth.wait_for_transaction_receipt(tx_hash)

      def subscribe_to_blocks(self, callback):
          block_filter = self.ws_w3.eth.filter('latest')

          while True:
              for block_hash in block_filter.get_new_entries():
                  block = self.ws_w3.eth.get_block(block_hash)
                  callback(block.number)

  # Usage
  client = NexisClient(os.environ['PRIVATE_KEY'])

  # Get network info
  info = client.get_network_info()
  print(f"Network: {info}")

  # Get account info
  account = client.get_account_info(client.account.address)
  print(f"Account: {account}")

  # Send transaction
  receipt = client.send_transaction(
      '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
      0.1
  )
  ```
</CodeGroup>

***

## Additional Resources

<CardGroup cols={2}>
  <Card title="Ethereum JSON-RPC Spec" icon="book" href="https://ethereum.org/en/developers/docs/apis/json-rpc/">
    Official Ethereum JSON-RPC specification
  </Card>

  <Card title="Optimism RPC Docs" icon="book" href="https://docs.optimism.io/builders/node-operators/json-rpc">
    Optimism-specific RPC methods
  </Card>

  <Card title="ethers.js Documentation" icon="js" href="https://docs.ethers.org/">
    ethers.js library documentation
  </Card>

  <Card title="web3.py Documentation" icon="python" href="https://web3py.readthedocs.io/">
    web3.py library documentation
  </Card>
</CardGroup>
