> For the complete documentation index, see [llms.txt](https://docs.rwa-chain.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rwa-chain.io/developers.md).

# Developers

Everything you need to connect to RWA Chain, deploy a contract and verify it. RWA Chain is an OP Stack rollup: anything that works on Optimism or Base works here, with the chain ID, RPC and explorer below.

## Networks

|                       | Mainnet                                                  | Testnet                                                                                                                            |
| --------------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| Chain ID              | 7741 (`0x1e3d`)                                          | 77410 (`0x12e62`)                                                                                                                  |
| RPC                   | <https://rpc.rwa-chain.io>                               | <https://sepolia-rpc.rwa-chain.io>                                                                                                 |
| WebSocket             | `wss://ws.rwa-chain.io`                                  | `wss://sepolia-ws.rwa-chain.io`                                                                                                    |
| Explorer (Blockscout) | <https://explorer.rwa-chain.io>                          | <https://sepolia-explorer.rwa-chain.io>                                                                                            |
| Verifier API          | `https://explorer.rwa-chain.io/api/`                     | `https://sepolia-explorer.rwa-chain.io/api/`                                                                                       |
| Gas token             | ETH (18 decimals)                                        | ETH (test, no value)                                                                                                               |
| Settles on            | Base (8453)                                              | Base Sepolia (84532)                                                                                                               |
| Get ETH               | [Bridge from Base](https://rwa-chain.io/explorer/bridge) | [Faucet](https://testnet.rwa-chain.io/explorer/faucet) or [bridge from Base Sepolia](https://testnet.rwa-chain.io/explorer/bridge) |
| App                   | <https://rwa-chain.io/explorer>                          | <https://testnet.rwa-chain.io/explorer>                                                                                            |

Block time is 1 second. Users without ETH can still transact through the [gasless relay](/gasless.md), which charges the fee in RWA.

## Connect a wallet

Use the **Add network** button on <https://rwa-chain.io/explorer/dev> (mainnet) or <https://testnet.rwa-chain.io/explorer/testnet> (testnet), or add the network by hand with the values above: network name `RWA Chain` / `RWA Chain Testnet`, currency symbol `ETH`.

## EVM version: Prague

Every OP Stack fork up to Isthmus is active from genesis, so the chain runs the **Prague** EVM. It does not run Osaka: opcodes such as `CLZ` fail with "invalid opcode". Newer solc releases may default to Osaka, so pin the EVM version in every tool:

* Foundry: `evm_version = "prague"`
* Hardhat: `settings: { evmVersion: "prague" }`
* Remix: Solidity compiler → Advanced configurations → EVM version `prague`

## Deploy with Foundry

`foundry.toml`:

```toml
[profile.default]
evm_version = "prague"

[rpc_endpoints]
rwa = "https://rpc.rwa-chain.io"
rwa_testnet = "https://sepolia-rpc.rwa-chain.io"
```

Deploy and verify in one step. `--broadcast` is required (without it forge 1.x only simulates), and `--constructor-args` must come last because it takes every argument after it:

```bash
forge create src/Greeter.sol:Greeter \
  --rpc-url rwa_testnet --private-key $PRIVATE_KEY --broadcast \
  --verify --verifier blockscout --verifier-url https://sepolia-explorer.rwa-chain.io/api/ \
  --constructor-args "hello RWA"
```

For mainnet use `--rpc-url rwa` and `--verifier-url https://explorer.rwa-chain.io/api/`. Scripts work the same way: `forge script script/Deploy.s.sol --rpc-url rwa --broadcast --verify --verifier blockscout --verifier-url https://explorer.rwa-chain.io/api/`.

## Deploy with Remix

1. Add the network to your wallet (above) and select it.
2. In **Solidity compiler → Advanced configurations**, set EVM version to `prague`, then compile.
3. In **Deploy & run transactions**, pick **Injected Provider - MetaMask** (or your wallet). Remix should show chain 7741 or 77410. Deploy.
4. Verify on the explorer (Remix's own verify plugin does not list RWA Chain yet): open <https://explorer.rwa-chain.io/contract-verification> (testnet: <https://sepolia-explorer.rwa-chain.io/contract-verification>), enter the address, choose **Solidity (Standard JSON input)** and upload the `input` object from Remix's `artifacts/build-info/*.json`. A flattened single file also works with **Solidity (Single file)**.

## Deploy with Hardhat

Hardhat 2 with `@nomicfoundation/hardhat-verify`. Blockscout needs no API key, but the plugin wants a non-empty string:

```ts
// hardhat.config.ts
const accounts = [process.env.PRIVATE_KEY!]

export default {
  solidity: { version: "0.8.28", settings: { evmVersion: "prague" } },
  networks: {
    rwa: { url: "https://rpc.rwa-chain.io", chainId: 7741, accounts },
    rwaTestnet: { url: "https://sepolia-rpc.rwa-chain.io", chainId: 77410, accounts },
  },
  etherscan: {
    apiKey: { rwa: "blockscout", rwaTestnet: "blockscout" },
    customChains: [
      { network: "rwa", chainId: 7741,
        urls: { apiURL: "https://explorer.rwa-chain.io/api", browserURL: "https://explorer.rwa-chain.io" } },
      { network: "rwaTestnet", chainId: 77410,
        urls: { apiURL: "https://sepolia-explorer.rwa-chain.io/api", browserURL: "https://sepolia-explorer.rwa-chain.io" } },
    ],
  },
  sourcify: { enabled: false },
}
```

```bash
npx hardhat verify --network rwaTestnet <address> "hello RWA"
```

Hardhat 3 verifies on Blockscout by default; it only needs to be told where the explorer is:

```ts
// hardhat.config.ts (Hardhat 3)
import { configVariable, defineConfig } from "hardhat/config"

export default defineConfig({
  solidity: { version: "0.8.28", settings: { evmVersion: "prague" } },
  networks: {
    rwaTestnet: { type: "http", url: "https://sepolia-rpc.rwa-chain.io", chainId: 77410,
      accounts: [configVariable("PRIVATE_KEY")] },
  },
  chainDescriptors: {
    77410: { name: "RWA Chain Testnet", blockExplorers: { blockscout: { name: "Blockscout",
      url: "https://sepolia-explorer.rwa-chain.io", apiUrl: "https://sepolia-explorer.rwa-chain.io/api" } } },
  },
})
```

If Hardhat 3 verification fails, verify with `forge verify-contract` or the explorer form (below).

## viem, wagmi and ethers

viem has OP Stack support built in. Spread `chainConfig` from `viem/op-stack` to get the OP formatters and the L2 predeploys:

```ts
import { defineChain } from "viem"
import { chainConfig } from "viem/op-stack"

export const rwaChain = defineChain({
  ...chainConfig,
  id: 7741,
  name: "RWA Chain",
  nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
  rpcUrls: { default: { http: ["https://rpc.rwa-chain.io"], webSocket: ["wss://ws.rwa-chain.io"] } },
  blockExplorers: { default: { name: "Blockscout", url: "https://explorer.rwa-chain.io",
    apiUrl: "https://explorer.rwa-chain.io/api" } },
  sourceId: 8453,
  contracts: {
    ...chainConfig.contracts,
    multicall3: { address: "0xcA11bde05977b3631167028862bE2a173976CA11", blockCreated: 0 },
    portal: { 8453: { address: "0x63832e6a88feb9fa0af1b9c67bbcef9fe6a41cae" } },
    disputeGameFactory: { 8453: { address: "0x99d4d6b9fabc9c3a4c5e370263b49c9cf9eb6dff" } },
    l1StandardBridge: { 8453: { address: "0x1bf527a4298e51051fa1a8db7c18c32827fa50d2" } },
  },
})
```

For the testnet use id `77410`, the `sepolia-` URLs, `sourceId: 84532` and the Base Sepolia addresses from [Testnet](/testnet.md) (portal `0xba35bf004f1a6a484489de1c92a08c23b759228c`, dispute game factory `0x410efc93c1ff18b36e24001c4923c03816b52b2b`, L1 bridge `0xed4451befeaa09365ac64d64c667919769329f3c`).

wagmi:

```ts
import { createConfig, http } from "wagmi"
export const config = createConfig({ chains: [rwaChain], transports: { [rwaChain.id]: http() } })
```

ethers v6:

```ts
import { JsonRpcProvider } from "ethers"
const provider = new JsonRpcProvider("https://rpc.rwa-chain.io", 7741, { staticNetwork: true })
```

## Verify a deployed contract

The explorer is Blockscout. Its Etherscan-style API needs no API key; use the URL **with** the trailing slash for Foundry.

```bash
forge verify-contract <address> src/Greeter.sol:Greeter \
  --chain 77410 --verifier blockscout --verifier-url https://sepolia-explorer.rwa-chain.io/api/ \
  --constructor-args $(cast abi-encode "constructor(string)" "hello RWA")
```

Mainnet: `--chain 7741 --verifier-url https://explorer.rwa-chain.io/api/`. Without a toolchain, use the explorer's form at <https://explorer.rwa-chain.io/contract-verification> (Standard JSON input or single file).

## Standard contracts

These are deployed at their usual addresses on **both** mainnet and testnet, so existing tooling (Multicall, Safe, CREATE2 factories, account abstraction) works unchanged.

| Contract                        | Address                                      |
| ------------------------------- | -------------------------------------------- |
| Multicall3                      | `0xcA11bde05977b3631167028862bE2a173976CA11` |
| Arachnid CREATE2 deployer       | `0x4e59b44847b379578588920cA78FbF26c0B4956C` |
| Safe singleton factory          | `0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7` |
| Create2Deployer                 | `0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2` |
| CreateX                         | `0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed` |
| Permit2                         | `0x000000000022D473030F116dDEE9F6B43aC78BA3` |
| ERC-4337 EntryPoint v0.7        | `0x0000000071727De22E5E9d8BAf0edAc6f37da032` |
| ERC-4337 EntryPoint v0.6        | `0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789` |
| WETH9                           | `0x4200000000000000000000000000000000000006` |
| Safe v1.3.0                     | `0x69f4D1788e39c87893C980c06EdF4b7f686e2938` |
| SafeL2 v1.3.0                   | `0xfb1bffC9d739B8D520DaF37dF666da4C687191EA` |
| MultiSend v1.3.0                | `0x998739BFdAAdde7C933B942a68053933098f9EDa` |
| MultiSendCallOnly v1.3.0        | `0xA1dabEF33b3B82c7814B6D82A79e50F4AC44102B` |
| L2StandardBridge (predeploy)    | `0x4200000000000000000000000000000000000010` |
| L2ToL1MessagePasser (predeploy) | `0x4200000000000000000000000000000000000016` |

The settlement contracts on Base and the RWA protocol contracts are listed on [Mainnet](/mainnet.md) and [Testnet](/testnet.md).

## Bridging and withdrawals

Deposits from Base arrive on RWA Chain in about a minute. Withdrawals back to Base take about 7 days, because they go through the fault-proof window: see [Withdrawals](/withdrawals.md).

## Public RPC limits

The public endpoints are shared, so they are limited:

* Only `eth_`, `net_` and `web3_` methods. `debug_*`, `trace_*`, `txpool_*`, `admin_*` and `miner_*` are refused with error `-32601`. For call traces and internal transactions use the explorer (Blockscout shows them per transaction and through its API).
* 20 requests per second per IP, with bursts of up to 40. Over the limit you get HTTP 503; back off and retry.
* Batches of up to 50 calls. A batch that contains a refused method is currently rejected as a whole, so keep such calls out of batches.
* Request bodies up to 1 MB; calls that take longer than 30 s time out (narrow the block range of `eth_getLogs`).
* WebSocket: up to 20 connections per IP; `eth_subscribe` supports `newHeads` and `logs`.

## Testnet vs mainnet

* Same software, same forks, same standard contracts and predeploys. Code that works on 77410 works on 7741.
* Testnet ETH and tokens have no value. The testnet RWA token is **RWAT** (Base Sepolia `0x9C435FBfc35E2328FF14e96909B6C82D2e2796A4`, faucet on <https://docs.rwa.inc>); the protocol contracts have different addresses (see [Testnet](/testnet.md)).
* The testnet may be restarted from a fresh genesis. The current one (v3) started on 9 October 2026; anything deployed before that is gone.
* The testnet faucet gives a small amount of ETH once per 24 hours per address.

## Developer kit

The [RWA Chain developer kit](https://github.com/rwa-chain-io/rwa-chain-devkit) is a starter repo with `networks.json`, Foundry, Hardhat 3 and viem examples, and a weekly CI job that deploys and verifies a contract on the testnet.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.rwa-chain.io/developers.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
