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

# Register Node

> The following guide illustrates how to register a new Stream Node instance on Towns Chain. This guide uses Testnet as an example. The Mainnet guide follows from this guide with modifications to contract addresses and rpc url for Towns Chain.

### Requirements & Dependencies

* Foundry Toolkit: To install follow [this](https://book.getfoundry.sh/getting-started/installation) guide.
* Node Operator delegation: address migrated to Towns Chain by DAO (see below).
* Warm wallet access to Node Operator wallet.
* Node URL pointing via DNS to Node FE attached to Node Storage.
* Access to Base over RPC endpoint
* Access to Towns Chain over RPC endpoint
* Sufficient gas on Node Operator wallet on both Base and Towns Chain to register
* Sufficient gas on Node FE wallet on Towns Chain and Base for validation and cross-chain transactions once node is operational.

<Note>
  Node FE's are stateful and as such require consistent resolution of hostnames
  to active instance. To avoid unintended bad consequences, it is strongly
  encouraged to configure DNS for Node URL with exactly 1 A Record per domain
  name. Put differently, each Node URL should point to at most 1 IP address.
</Note>

<Note>
  The node operator wallet registered on Base must
  be bridged to Towns Chain by the DAO prior to proceeding with node registration. Furthermore, the node operator needs warm access to this
  wallet to perform node operations to register, and update a fleet of node instances.
</Note>

All contract addresses for testnet and mainnet needed to register nodes can be found in the [contracts](/node-operator/contracts) section.

<Note>When referencing contract methods in the below guide, keep in mind that our contracts are deployed using the [Diamond Standard](https://www.quicknode.com/guides/ethereum-development/smart-contracts/the-diamond-standard-eip-2535-explained-part-1) pattern. This means for practical purposes that when interacting with contracts on Base or Towns Chain, you will be calling each method on the associated diamond contract.</Note>

### Registration Outline

The following outlines the logical steps to onboarding a Node FE with attached storage from 0 to 1. Instructions are applicable to testnet and mainnet.

Instructions with specific calling signatures can be found below in the [Node FE Registration](#node-fe-registration) sections.

Please ensure you have completed [Node Operator registration](/node-operator/tutorials/register-towns-operator) before proceeding with node registration.

<Steps>
  <Step title="Start Stream Node in Info Mode">Operator should start the stream node process in [info](https://github.com/towns-protocol/towns/tree/main/core/node#checking-on-gamma-status-from-local-host) mode and additionally ensure DNS, TLS, and network are configured correctly.</Step>
  <Step title="Register Node in Towns Chain">Operator calls [registerNode](https://github.com/towns-protocol/towns/blob/main/packages/contracts/src/river/registry/facets/node/NodeRegistry.sol) on the [RiverRegistry](https://github.com/towns-protocol/towns/blob/main/packages/contracts/deployments/gamma/river/addresses/riverRegistry.json) diamond contract deployed on Towns Chain once health checks pass.</Step>
  <Step title="Register Node in Base">Operator calls [registerNode](https://github.com/towns-protocol/towns/blob/main/packages/contracts/src/base/registry/facets/checker/EntitlementChecker.sol) on the BaseRegistry diamond contract to support cross-chain checks.</Step>
  <Step title="Start Stream Node">Operator starts the stream node by running the docker image to enter Towns Chain network once registered.</Step>
</Steps>

### Node FE Registration

Once a node operator has registered their operator address on Towns Chain, they can proceed to register their nodes. Nodes are registered individually on Towns Chain and Base.

<Warning>
  Node Operator addresses must be registered on Towns Chain before below actions
  can be undertaken to register a new stream node. DAO will migrate operator address to Towns Chain
  once sufficient delegations are received.
</Warning>

Once a node is setup, attached to postgres storage, network configured with a public IP, and passing health checks (see [System Requirements & Installation](/node-operator/tutorials/system-requirements-installation)), the node is ready to enter the Towns Network and begin accepting stream writes.

Registering a node on Towns Chain, can be accomplished by calling the `registerNode(address,string,uint8)` method on the RiverRegistry diamond contract.

<Warning>
  Registering a node and operating a stream node in general requires that the
  node wallet has Eth for the target network (Sepolia Eth for testnet, Eth for mainnet) to pay for gas.
  On testnet, sepolia eth can be obtained from a
  [faucet](https://towns-devnet.hub.caldera.xyz/).
  Stream nodes should also have a wallet on Base with Base Eth (mainnet) or Base Sepolia Eth (testnet) to pay for gas when committing cross-chain transactions.
</Warning>

The below steps describe how to register a new node URL in `Operational` status using `cast`, a command-line tool that is part of Foundry for reading / writing to EVM chains over RPC url's.

<Note>
  Setting a Node to `Operational` status will allow the node to begin accepting stream writes and signal to the network that the node is healthy and ready to be connected to by clients. See all possible node statuses that a node can assume in [RegistryStorage](https://github.com/towns-protocol/towns/blob/main/packages/contracts/src/river/registry/libraries/RegistryStorage.sol#L30).
</Note>

<Steps>
  <Step title="Setup Variables for Registration">
    ```bash theme={null}
    # checkout repo and extract RiverRegistry deployed address
    $ git clone git@github.com:towns-protocol/towns.git
    $ cd river
    $ JSON_FILE="packages/generated/deployments/testnet/river/addresses/riverRegistry.json"
    $ RIVER_REGISTRY_ADDRESS=$(jq -r '.address' "$JSON_FILE") 

    # set node address, which is wallet address of node's ECDSA wallet created on configuration.
    NODE_ADDRESS=<Node FE Wallet Address>
    PRIVATE_KEY=<Node Operator private key>

    # node url
    NODE_URL=<public node url pointing to a single public IP address that represents running Node FE pid>

    # set RPC_URL to point to testnet
    RPC_URL=https://devnet.rpc.river.build

    # set BASE_RPC_URL to point to base testnet
    BASE_RPC_URL=https://base-sepolia.g.alchemy.com/v2/${RPC_KEY}
    ```

    <br />

    <Warning>Private Key needed for cast call is Node Operator's not Node FE's. It is up to Node Operator how they decide to secure this key and make it available to perform cast calls to register nodes.</Warning>
  </Step>

  <Step title="Register Node on Base and Towns Chain">
    Using `cast` let's register our new node. First let's check that the Node FE does not already exist. Node FE's are identified in Towns Registry by their address so let's check `getNode` to ensure the view reverts with `NODE_NOT_FOUND` before proceeding.

    ```bash theme={null}
    cast call --rpc-url $RPC_URL \                         
      $RIVER_REGISTRY_ADDRESS \
      "getNode(address)" \
      $NODE_ADDRESS
    ```

    Assuming the above reverts with `NODE_NOT_FOUND`, let's proceed to register the new node with the Node Operator's wallet.

    <br />

    <Note>Registering a new node is a write transaction that will require the Node Operator wallet on Towns Chain and Base has Eth. To monitor Towns Chain transactions, you can use the [explorer](https://explorer.river.build/).</Note>

    ```bash theme={null}
    # Register a new node with EntitlementChecker in Base to ensure xchain entitlements are in place when running stream node.
    # Note: EntitlementChecker is a facet and so call it's interface from Base Registry diamond contract (for address see baseRegistry.json under packages/generated/deployments in river repo).

    # Ensure you call the below with the Node Operator wallet you have registered on Base. NODE_ADDRESS is the wallet address of the Node FE.
    cast send \
      --rpc-url $BASE_RPC_URL \
      --private-key $PRIVATE_KEY \
      $BASE_REGISTRY_ADDRESS \
      "registerNode(address)" \
      $NODE_ADDRESS
    ```

    <br />

    ```bash theme={null}
     # Register a new node in Operational (2) Status in Towns Chain to signal to the network the node is ready to accept reads and writes.
     cast send \
       --rpc-url $RPC_URL \
       --private-key $PRIVATE_KEY \
       $RIVER_REGISTRY_ADDRESS \
       "registerNode(address,string,uint8)" \
       $NODE_ADDRESS \
       $NODE_URL \
       2 
    ```

    <Warning>When registering node, make sure you pass in the node url including the schema of the url, which must be https\://. For example, for node referenced by domain name, river-operator-1.xyz, you would pass in the node url to registerNode call as [https://river-operator-1.xyz](https://river-operator-1.xyz).
    Therefore, prior to calling registerNode using Operational status, you must ensure the node url resolves from the public internet.</Warning>
    When the above transactions succeed and have been mined in a block on Towns Chain, you can re-run `getNode(address)` to confirm the node now exists in the network.
  </Step>

  <Step title="Check Node Health from Debug Multi Dashboard">
    To check that your node is included in the network and healthy, you can navigate to:
    `$NODE_URL/debug/multi` in a browser to see the node's http1/2, grpc ping status and related health metrics.

    As an example, see [https://ohare-3.staking.production.figment.io/debug/multi](https://ohare-3.staking.production.figment.io/debug/multi).
  </Step>
</Steps>
