> For a complete page index, fetch https://docs.conduit.xyz/llms.txt

# Using Web3 Libraries

> Connect to Conduit RPC endpoints using popular web3 libraries including viem, ethers.js, and web3.py.

If you're building an application, web3 libraries provide a higher-level interface for interacting with Conduit RPC endpoints. They handle request formatting, response parsing, and type safety so you don't have to work with raw JSON-RPC directly.

Replace `[YOUR_RPC_URL]` and `[YOUR_API_KEY]` with your values from the [Conduit App](https://app.conduit.xyz/).

## eth\_blockNumber

Get the latest block number.

**`viem`**

```typescript viem
import { createPublicClient, http } from 'viem'

const client = createPublicClient({
  transport: http('https://[YOUR_RPC_URL]/[YOUR_API_KEY]'),
})

const blockNumber = await client.getBlockNumber()
console.log(blockNumber)
```

**`ethers.js`**

```typescript ethers.js
import { JsonRpcProvider } from 'ethers'

const provider = new JsonRpcProvider('https://[YOUR_RPC_URL]/[YOUR_API_KEY]')
const blockNumber = await provider.getBlockNumber()
console.log(blockNumber)
```

**`web3.py`**

```python web3.py
from web3 import Web3

w3 = Web3(Web3.HTTPProvider('https://[YOUR_RPC_URL]/[YOUR_API_KEY]'))
print(w3.eth.block_number)
```

---

## eth\_getBalance

Get the ETH balance of an address.

**`viem`**

```typescript viem
const balance = await client.getBalance({
  address: '0xYOUR_ADDRESS',
})
console.log(balance)
```

**`ethers.js`**

```typescript ethers.js
const balance = await provider.getBalance('0xYOUR_ADDRESS')
console.log(balance)
```

**`web3.py`**

```python web3.py
balance = w3.eth.get_balance('0xYOUR_ADDRESS')
print(balance)
```

---

## eth\_call

Call a contract function without sending a transaction.

**`viem`**

```typescript viem
const result = await client.call({
  to: '0xCONTRACT_ADDRESS',
  data: '0xCALLDATA',
})
console.log(result.data)
```

**`ethers.js`**

```typescript ethers.js
const result = await provider.call({
  to: '0xCONTRACT_ADDRESS',
  data: '0xCALLDATA',
})
console.log(result)
```

**`web3.py`**

```python web3.py
result = w3.eth.call({
    'to': '0xCONTRACT_ADDRESS',
    'data': '0xCALLDATA',
})
print(result)
```

---

## eth\_getLogs

Fetch logs matching a filter. See [Throughput](/rpc-nodes/information/throughput) for block range and event count limits.

**`viem`**

```typescript viem
const logs = await client.getLogs({
  address: '0xCONTRACT_ADDRESS',
  fromBlock: 0n,
  toBlock: 'latest',
})
console.log(logs)
```

**`ethers.js`**

```typescript ethers.js
const logs = await provider.getLogs({
  address: '0xCONTRACT_ADDRESS',
  fromBlock: 0,
  toBlock: 'latest',
})
console.log(logs)
```

**`web3.py`**

```python web3.py
logs = w3.eth.get_logs({
    'fromBlock': 0,
    'toBlock': 'latest',
    'address': '0xCONTRACT_ADDRESS',
})
print(logs)
```

---

## eth\_sendRawTransaction

Sign and broadcast a transaction.

**`viem`**

```typescript viem
import { createWalletClient, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'

const account = privateKeyToAccount('0xYOUR_PRIVATE_KEY')
const walletClient = createWalletClient({
  account,
  transport: http('https://[YOUR_RPC_URL]/[YOUR_API_KEY]'),
})

const hash = await walletClient.sendTransaction({
  to: '0xRECIPIENT_ADDRESS',
  value: 1000000000000000n,
})
console.log(hash)
```

**`ethers.js`**

```typescript ethers.js
import { Wallet, JsonRpcProvider } from 'ethers'

const provider = new JsonRpcProvider('https://[YOUR_RPC_URL]/[YOUR_API_KEY]')
const wallet = new Wallet('0xYOUR_PRIVATE_KEY', provider)

const tx = await wallet.sendTransaction({
  to: '0xRECIPIENT_ADDRESS',
  value: 1000000000000000n,
})
console.log(tx.hash)
```

**`web3.py`**

```python web3.py
signed_tx = w3.eth.account.sign_transaction({
    'to': '0xRECIPIENT_ADDRESS',
    'value': 1000000000000000,
    'gas': 21000,
    'nonce': w3.eth.get_transaction_count('0xYOUR_ADDRESS'),
}, private_key='0xYOUR_PRIVATE_KEY')

tx_hash = w3.eth.send_raw_transaction(signed_tx.raw_transaction)  # v7+; use rawTransaction for v6
print(tx_hash.hex())
```

---

## eth\_subscribe (WebSocket)

Subscribe to new block headers in real time. This requires a WebSocket connection with an API key appended to the WSS URL. Starting **August 4, 2026**, anonymous WebSocket connections are rejected. See [WebSockets](/rpc-nodes/information/websockets) for connection management guidance.

**`viem`**

```typescript viem
import { createPublicClient, webSocket } from 'viem'

const client = createPublicClient({
  transport: webSocket('wss://[YOUR_RPC_URL]/[YOUR_API_KEY]'),
})

const unwatch = client.watchBlocks({
  onBlock: (block) => console.log(block),
})
```

**`ethers.js`**

```typescript ethers.js
import { WebSocketProvider } from 'ethers'

const provider = new WebSocketProvider('wss://[YOUR_RPC_URL]/[YOUR_API_KEY]')

provider.on('block', (blockNumber) => {
  console.log('New block:', blockNumber)
})
```

**`web3.py`**

```python web3.py
import asyncio
from web3 import AsyncWeb3
from web3.providers import WebSocketProvider

async def main():
    async with AsyncWeb3(WebSocketProvider('wss://[YOUR_RPC_URL]/[YOUR_API_KEY]')) as w3:
        await w3.eth.subscribe('newHeads')
        async for block in w3.socket.process_subscriptions():
            print(block)

asyncio.run(main())
```