Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
12bac8d
Adding collapsible code blocks to run l3 rollup from scratch for cris…
pete-vielhaber Mar 3, 2026
0ff8aaa
Adding customdetail collapsiable codeblocks to longer code sections.
pete-vielhaber Mar 3, 2026
8cc3f3a
Fixing where tags were not closed
pete-vielhaber Mar 3, 2026
ad391f2
Apply suggestion from @anegg0
anegg0 Mar 4, 2026
27bcc91
add missing indentation
anegg0 Mar 4, 2026
b5e684b
Apply suggestions from code review
pete-vielhaber Mar 27, 2026
4682b55
Update docs/launch-arbitrum-chain/03-deploy-an-arbitrum-chain/run-l3-…
pete-vielhaber Mar 27, 2026
e486e14
Update docs/launch-arbitrum-chain/03-deploy-an-arbitrum-chain/run-l3-…
pete-vielhaber Mar 27, 2026
8bf7b45
Update docs/launch-arbitrum-chain/03-deploy-an-arbitrum-chain/run-l3-…
pete-vielhaber Mar 27, 2026
8c0931f
Update docs/launch-arbitrum-chain/03-deploy-an-arbitrum-chain/run-l3-…
pete-vielhaber Mar 27, 2026
1fd82fb
Update docs/launch-arbitrum-chain/03-deploy-an-arbitrum-chain/run-l3-…
pete-vielhaber Mar 27, 2026
a4a75fd
Update docs/launch-arbitrum-chain/03-deploy-an-arbitrum-chain/run-l3-…
pete-vielhaber Mar 27, 2026
0132e01
Update docs/launch-arbitrum-chain/03-deploy-an-arbitrum-chain/run-l3-…
pete-vielhaber Mar 27, 2026
f040811
Update docs/launch-arbitrum-chain/03-deploy-an-arbitrum-chain/run-l3-…
pete-vielhaber Mar 27, 2026
9a50f01
Update docs/launch-arbitrum-chain/03-deploy-an-arbitrum-chain/run-l3-…
pete-vielhaber Mar 27, 2026
5eb759b
Merge branch 'master' into deploy-chain-style-refactor
pete-vielhaber Mar 27, 2026
efa75a2
yarn format
pete-vielhaber Mar 27, 2026
79cd3f2
Correcting dangling CustomDetails brackets
pete-vielhaber Mar 27, 2026
97c1c08
fix file format error breaking vercel
anegg0 Mar 27, 2026
4931626
Deleted prerequisites.mdx (belongs to an upcoming PR)
anegg0 Mar 27, 2026
44b65cb
Merge branch 'master' into deploy-chain-style-refactor
anegg0 Apr 2, 2026
f47eca2
Merge branch 'master' into deploy-chain-style-refactor
pete-vielhaber Apr 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ sidebar_position: 0
---

import RaaSNotice from '../partials/_raas-providers-notice.mdx';
import CustomDetails from '@site/src/components/CustomDetails';

<RaaSNotice />

Expand Down Expand Up @@ -72,7 +73,9 @@ Your key must start with `0x` and be 64 hex characters long (66 characters total

In this step you will deploy your chain's contracts to Arbitrum Sepolia. It will cost a small amount of `ETH` in gas fees.

- Create a new file named `deploy.mjs` in your propject folder. Then copy and paste this entire script:
- Create a new file named `deploy.mjs` in your project folder. Then copy and paste this entire script:

<CustomDetails summary="deploy.mjs">

```javascript
import { createPublicClient, http } from 'viem';
Expand Down Expand Up @@ -143,6 +146,8 @@ async function main() {
main().catch(console.error);
```

</CustomDetails>

- Run the deployment script:

```bash
Expand All @@ -159,6 +164,8 @@ In this step you will create the `node-config.json`—the file your node needs t

- Create a new file named `prepare-node-config.mjs`. Copy and paste this entire script:

<CustomDetails summary="prepare-node-config.mjs">

```javascript
import { writeFile } from 'fs/promises';
import { createPublicClient, http } from 'viem';
Expand Down Expand Up @@ -210,6 +217,8 @@ async function main() {
main().catch(console.error);
```

</CustomDetails>

- Now run the script:

```bash
Expand Down Expand Up @@ -255,6 +264,8 @@ In this step you'll enable the bridging tokens between your chain and Arbitrum S
- Open a **new terminal** in the same project folder—leave the node running in the first one.
- Create a new file named `deploy-token-bridge.mjs`. Copy and paste this entire script:

<CustomDetails summary="deploy-token-bridge.mjs">

```javascript
import { createPublicClient, http, defineChain } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
Expand Down Expand Up @@ -356,6 +367,8 @@ async function main() {
main().catch(console.error);
```

</CustomDetails>

- Run the script (it reads from your `.env` file):

```bash
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ content_type: how-to
---

import RaaSNotice from '../partials/_raas-providers-notice.mdx';
import CustomDetails from '@site/src/components/CustomDetails';

<RaaSNotice />

Expand Down Expand Up @@ -54,13 +55,18 @@ The commands use shell variables (`$CHAIN_ID`, `$PARENT_CHAIN_ID`, `$PARENT_RPC`

- On your local machine, in the folder that contains `node-config.json`, run:

<CustomDetails summary="node-config.json">

```bash
# Export so variables persist for all steps below
export CHAIN_ID=$(jq -r '.chain["info-json"]' node-config.json | jq -r '.[0]["chain-id"]')
export PARENT_CHAIN_ID=$(jq -r '.chain["info-json"]' node-config.json | jq -r '.[0]["parent-chain-id"]')
export PARENT_RPC=$(jq -r '.["parent-chain"].connection.url' node-config.json)

# Save chain info to file (used by Helm --set-file)

# Save chain info to file (used by Helm --set-file)

jq -r '.chain["info-json"]' node-config.json > chain-info.json

echo "CHAIN_ID=$CHAIN_ID"
Expand All @@ -69,6 +75,8 @@ echo "PARENT_RPC=$PARENT_RPC"
echo "chain-info.json saved"
```

</CustomDetails>

- In Step 8, you will extract the batch poster private key—never commit it to Git or expose it in logs.

## Step 2: Add Helm repo and create namespace
Expand Down Expand Up @@ -117,37 +125,33 @@ export REDIS_URL="redis://YOUR_REDIS_ENDPOINT:6379"

- Deploy 3 sequencer replicas with the sequencer coordinator enabled. Replace placeholders with your values. Use `--set-file` for the chain info JSON to avoid shell escaping issues:

```bash
helm install sequencer offchainlabs/nitro \
--namespace my-l3-chain \
--set replicaCount=3 \
--set configmap.data.parent-chain.id=$PARENT_CHAIN_ID \
--set configmap.data.parent-chain.connection.url=$PARENT_RPC \
--set configmap.data.chain.id=$CHAIN_ID \
--set-file configmap.data.chain.info-json=chain-info.json \
--set configmap.data.node.sequencer=true \
--set configmap.data.node.delayed-sequencer.enable=true \
--set configmap.data.node.seq-coordinator.enable=true \
--set configmap.data.node.seq-coordinator.redis-url=$REDIS_URL \
--set configmap.data.node.feed.output.enable=true \
--set configmap.data.node.feed.output.port=9642 \
--set configmap.data.execution.sequencer.enable=true \
--set configmap.data.init.empty=true \
<CustomDetails summary="Deploy sequencers:">

```shell \ --set configmap.data.parent-chain.id=$PARENT_CHAIN_ID \ --set
configmap.data.parent-chain.connection.url=$PARENT_RPC \ --set configmap.data.chain.id=$CHAIN_ID \
--set-file configmap.data.chain.info-json=chain-info.json \ --set
configmap.data.node.sequencer=true \ --set configmap.data.node.delayed-sequencer.enable=true \
--set configmap.data.node.seq-coordinator.enable=true \ --set
configmap.data.node.seq-coordinator.redis-url=$REDIS_URL \ --set
configmap.data.node.feed.output.enable=true \ --set configmap.data.node.feed.output.port=9642 \
--set configmap.data.execution.sequencer.enable=true \ --set configmap.data.init.empty=true \
--set perReplicaHeadlessService.enabled=true
```

- If sequencers fail to coordinate, each needs a unique URL. Create `sequencer-extra-env.yaml`:
</CustomDetails>

- If sequencers fail to coordinate, each needs a unique URL.:

<CustomDetails summary="Create sequencer-extra-env.yaml">

```yaml
extraEnv:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: NITRO_NODE_SEQ__COORDINATOR_MY__URL
value: 'http://$(POD_NAME).sequencer-nitro-headless.my-l3-chain.svc.cluster.local:8547/rpc'
extraEnv: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name:
NITRO_NODE_SEQ__COORDINATOR_MY__URL value:
'http://$(POD_NAME).sequencer-nitro-headless.my-l3-chain.svc.cluster.local:8547/rpc'
```

</CustomDetails>

- Then add `-f sequencer-extra-env.yaml` to the `helm install` command above.

- Wait for the sequencer pods to be ready:
Expand All @@ -166,16 +170,15 @@ After deploying sequencers, you must set at least one sequencer in the priority

Sequencer relays combine feeds from all sequencer replicas. Other components connect to these relays rather than directly to the sequencers.

- Run the following commands:
<CustomDetails summary="Run the following commands:">

```bash
helm install sequencer-relay offchainlabs/relay \
--namespace my-l3-chain \
--set replicaCount=2 \
--set configmap.data.chain.id=$CHAIN_ID \
--set configmap.data.node.feed.input.url=ws://sequencer-nitro-0.sequencer-nitro-headless:9642\,ws://sequencer-nitro-1.sequencer-nitro-headless:9642\,ws://sequencer-nitro-2.sequencer-nitro-headless:9642
```shell
replicaCount=2 \ --set configmap.data.chain.id=$CHAIN_ID \ --set
configmap.data.node.feed.input.url=ws://sequencer-nitro-0.sequencer-nitro-headless:9642\,ws://sequencer-nitro-1.sequencer-nitro-headless:9642\,ws://sequencer-nitro-2.sequencer-nitro-headless:9642
```

</CustomDetails>

- The relay service names (`sequencer-nitro-0`, etc.) depend on your Helm release name. If you used a different release name for the sequencer, adjust accordingly (format: `<release>-nitro-<index>.<release>-nitro-headless`).

## Step 6: Deploy external relays
Expand All @@ -196,22 +199,19 @@ helm install external-relay offchainlabs/relay \

Full nodes serve RPC requests and forward transactions to the active sequencer. They use Redis to find the active sequencer automatically.

- Run the following commands:
<CustomDetails summary="Run the following commands:">

```bash
helm install fullnode offchainlabs/nitro \
--namespace my-l3-chain \
--set replicaCount=2 \
--set configmap.data.parent-chain.id=$PARENT_CHAIN_ID \
--set configmap.data.parent-chain.connection.url=$PARENT_RPC \
--set configmap.data.chain.id=$CHAIN_ID \
--set-file configmap.data.chain.info-json=chain-info.json \
--set configmap.data.execution.forwarder.redis-url=$REDIS_URL \
--set configmap.data.node.feed.input.url=ws://external-relay:9642 \
--set configmap.data.init.empty=true \
--set configmap.data.execution.forwarding-target=http://sequencer-nitro:8547
```shell
\ --set configmap.data.parent-chain.id=$PARENT_CHAIN_ID \ --set
configmap.data.parent-chain.connection.url=$PARENT_RPC \ --set configmap.data.chain.id=$CHAIN_ID \
--set-file configmap.data.chain.info-json=chain-info.json \ --set
configmap.data.execution.forwarder.redis-url=$REDIS_URL \ --set
configmap.data.node.feed.input.url=ws://external-relay:9642 \ --set configmap.data.init.empty=true
\ --set configmap.data.execution.forwarding-target=http://sequencer-nitro:8547
```

</CustomDetails>

- If your chain already has blocks, use `--set configmap.data.init.latest=pruned` instead of `init.empty=true`.

## Step 8: Deploy batch poster
Expand All @@ -224,23 +224,22 @@ The batch poster posts transaction batches to the parent chain.
printf '%s' "$(jq -r '.node["batch-poster"]["parent-chain-wallet"]["private-key"]' node-config.json)" > batch-poster-key.txt
```

- Deploy the batch poster:

```bash
helm install batchposter offchainlabs/nitro \
--namespace my-l3-chain \
--set configmap.data.parent-chain.id=$PARENT_CHAIN_ID \
--set configmap.data.parent-chain.connection.url=$PARENT_RPC \
--set configmap.data.chain.id=$CHAIN_ID \
--set-file configmap.data.chain.info-json=chain-info.json \
--set-string configmap.data.execution.forwarding-target=null \
--set configmap.data.node.seq-coordinator.enable=true \
--set configmap.data.node.seq-coordinator.redis-url=$REDIS_URL \
--set configmap.data.node.batch-poster.enable=true \
--set configmap.data.node.feed.input.url=ws://sequencer-relay:9642 \
--set-file configmap.data.node.batch-poster.parent-chain-wallet.private-key=batch-poster-key.txt
<CustomDetails summary="Deploy the batch poster:">

```shell
configmap.data.parent-chain.id=$PARENT_CHAIN_ID \ --set
configmap.data.parent-chain.connection.url=$PARENT_RPC \ --set configmap.data.chain.id=$CHAIN_ID \
--set-file configmap.data.chain.info-json=chain-info.json \ --set-string
configmap.data.execution.forwarding-target=null \ --set
configmap.data.node.seq-coordinator.enable=true \ --set
configmap.data.node.seq-coordinator.redis-url=$REDIS_URL \ --set
configmap.data.node.batch-poster.enable=true \ --set
configmap.data.node.feed.input.url=ws://sequencer-relay:9642 \ --set-file
configmap.data.node.batch-poster.parent-chain-wallet.private-key=batch-poster-key.txt
```

</CustomDetails>

- Remove the key file after deployment:

```bash
Expand All @@ -263,25 +262,22 @@ The validator validates blocks and posts assertions to the parent chain. It is r
printf '%s' "$(jq -r '.node["staker"]["parent-chain-wallet"]["private-key"]' node-config.json)" > validator-key.txt
```

- Deploy the validator:
<CustomDetails summary="Deploy the validator:">

```bash
helm install validator offchainlabs/nitro \
--namespace my-l3-chain \
--set configmap.data.parent-chain.id=$PARENT_CHAIN_ID \
--set configmap.data.parent-chain.connection.url=$PARENT_RPC \
--set configmap.data.chain.id=$CHAIN_ID \
--set-file configmap.data.chain.info-json=chain-info.json \
--set configmap.data.node.sequencer=false \
--set configmap.data.node.batch-poster.enable=false \
--set configmap.data.node.staker.enable=true \
--set configmap.data.node.staker.strategy=MakeNodes \
--set configmap.data.node.feed.input.url=ws://external-relay:9642 \
--set configmap.data.execution.forwarding-target=http://sequencer-nitro:8547 \
--set-file configmap.data.node.staker.parent-chain-wallet.private-key=validator-key.txt \
--set configmap.data.init.empty=true
configmap.data.parent-chain.id=$PARENT_CHAIN_ID \ --set
configmap.data.parent-chain.connection.url=$PARENT_RPC \ --set configmap.data.chain.id=$CHAIN_ID \
--set-file configmap.data.chain.info-json=chain-info.json \ --set
configmap.data.node.sequencer=false \ --set configmap.data.node.batch-poster.enable=false \ --set
configmap.data.node.staker.enable=true \ --set configmap.data.node.staker.strategy=MakeNodes \
--set configmap.data.node.feed.input.url=ws://external-relay:9642 \ --set
configmap.data.execution.forwarding-target=http://sequencer-nitro:8547 \ --set-file
configmap.data.node.staker.parent-chain-wallet.private-key=validator-key.txt \ --set
configmap.data.init.empty=true
```

</CustomDetails>

- Remove the key file after deployment:

```bash
Expand Down Expand Up @@ -410,6 +406,8 @@ This enables bridging tokens between your chain and Arbitrum Sepolia. Run this f

- Create `deploy-token-bridge.mjs` in your project folder:

<CustomDetails summary="deploy-token-bridge.mjs">

```javascript
import { createPublicClient, http, defineChain } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
Expand Down Expand Up @@ -508,6 +506,8 @@ async function main() {
main().catch(console.error);
```

</CustomDetails>

- Run it with your chain's RPC URL (the LoadBalancer IP from Step 11):

```bash
Expand Down
Loading