# Relay deployment and configuration

The deployment and configuration of an external relay closely resemble the process of deploying and configuring the client part of the protocol (client contracts and client off-chain module). The process can be divided into 3 steps:

1. [Deployment of external relay contracts](#deployment-of-external-relay-contracts) to all supported networks
2. [Contacting our support service](#contacting-asterizm-support) to obtain an identification key for the relay's off-chain module and adding the addresses of external relay contracts to the trusted list on the protocol initializer contracts
3. [Configuration](#configuration-settings) and launch of the external relay's off-chain module.

## Deployment of external relay contracts

First, it is essential to deploy the external relay contracts to all supported networks. The contracts are available in the protocol repositories:

{% embed url="<https://github.com/Asterizm-Protocol/asterizm-contracts-tvm/blob/master/contracts/AsterizmTranslator.tsol>" %}
EVM contract
{% endembed %}

{% embed url="<https://github.com/Asterizm-Protocol/asterizm-contracts-tvm/blob/master/contracts/AsterizmTranslator.tsol>" %}
TVM contract
{% endembed %}

{% embed url="<https://github.com/Asterizm-Protocol/asterizm-contracts-ton/blob/master/contracts/AsterizmTranslator.tsol>" %}
TON contract
{% endembed %}

{% embed url="<https://github.com/Asterizm-Protocol/asterizm-contracts-sol/tree/master/programs/asterizm-relayer>" %}
Solana program
{% endembed %}

The deployment of the relay contract consists of two steps:

1. Deployment of the relay contract
2. Adding the list of supported networks and their types to the contract by invoking the method <mark style="color:orange;">`function addChains(uint64[] calldata _chainIds, uint8[] calldata _chainTypes)`</mark> on the deployed contract.

Additionally, console commands have been developed to simplify the deployment of these contracts.

#### EVM

```bash
npx hardhat relay:deploy {initializerAddress} {testnetFlag?} --network {networkName}
```

The command accepts the following parameters:

* **initializerAddress** - mandatory parameter: the address of the initializer on the network. You can review the list of available initializer addresses on the corresponding pages ([Mainnet](/technical-reference/mainnet.md) or [Testnet](/technical-reference/testnet.md))
* **testnetFlag** - optional parameter, accepted values **0** or **1**)&#x20;
* **networkName** - mandatory parameter: The name of the network into which the contract is being deployed. You can check the list of available networks [here](https://github.com/Asterizm-Protocol/asterizm-contracts-evm/blob/master/hardhat.config.ts#L41)

Upon successful execution, the command will return a response similar to the following (the relay address will be displayed under the **External relay address**):

```bash
Deployment was done

Total gas limit: 684778
Owner address: 0xf9E3b4AC4CEFF24464840c426E7e3506dC145c44
Initializer address: 0x68a0C7aE8557F0477fe985636aE8827eAE7577F1
External relay address: 0xDc6baC9cDF881572f3f77522f74301F429E4Ba87
```

#### TVM

<pre class="language-bash"><code class="lang-bash"><strong>npx locklift run --script ./scripts/relay/relay_deploy_task.ts --initializer {initializerAddress} --network {networkName}
</strong></code></pre>

The command accepts the following parameters:

* **initializerAddress** - mandatory parameter: the address of the initializer on the network. You can review the list of available initializer addresses on the corresponding pages ([Mainnet](/technical-reference/mainnet.md) or [Testnet](/technical-reference/testnet.md))
* **networkName** - mandatory parameter: The name of the network into which the contract is being deployed. You can check the list of available networks [here](https://github.com/Asterizm-Protocol/asterizm-contracts-evm/blob/master/hardhat.config.ts#L41).

Upon successful execution, the command will return a response similar to the following (the relay address will be displayed under the **External relay address**):

```bash
Deployment was done.

Owner address: 0:68a73acf79fed327d33a1e60503060021cbc2d9e1e8500d073d448d9a74f978f
Initializer address: 0:c8693de0c988b5f418db9916b9b43d4613e87a527ba9fbb216136526ea21b191
External relay address: 0:1bfd87c7f21c12c39f6a1eb3bd18eec8503beaae3f91a41ebf3fb1d39e1c3bff
```

#### TON

Coming soon

#### **Solana**

Coming soon

## Contacting Asterizm Support

Asterizm Protocol conducts a personal audit of each connected external relay. Additionally, the protocol retains the right to remove a specific external relay from the protocol system if the relay violates the protocol's rules and agreements.

Furthermore, the protocol has a real-time monitoring system for the status of each external relay. In the event of any issues on the external relay's side, its status will be updated on the corresponding page of the protocol [scanner](https://scan.asterizm.io/).

To execute these protocol logics, the protocol must have the ability to identify each connected external relay. For this purpose, a unique identifier is assigned to each external relay, which needs to be added to the configuration of the off-chain module (see below).

After the relay representative contacts the [Asterizm support service](/guides/getting-started.md#talk-to-the-team), it requests a list of addresses of relay contracts deployed in all supported networks, conducts its own audit, adds the contract addresses to the trusted relay list on the initializer contract, stores the external relay in the internal database, and issues a unique identifier. After this, you can proceed to the final step - configuring the off-chain module of the external relay.

## Off-chain module configuration

To operate the external relay, in addition to the relay contracts in each network, it is also necessary to configure the off-chain module. The configuration is done on a private server of the external relay and is the responsibility of the external relay's staff. Asterizm Protocol has **no** access to it.

To proceed further, it's necessary to install [Docker](https://www.docker.com/) together with [Docker Compose](https://docs.docker.com/compose/) on the server. You can refer to the official documentation for installation and setup instructions: <https://docs.docker.com/engine/install/>

For these purposes, Asterizm Protocol has developed a Docker image. You should use this image to create Docker containers on your server. To begin, please download the image:

```bash
docker pull asterizm/external-relay:latest
```

After downloading the image, you should follow these steps:

1. Create a <mark style="color:orange;">**`docker-compose.yml`**</mark> file to automate the deployment of the server
2. Configure the configuration parameters for the external relay&#x20;
3. Apply migrations, fixtures, and launch the Docker containers

For example, let's assume that the external relay intends to support two networks - Ethereum (EVM) and Everscale (TVM), with the root directory of the off-chain module being <mark style="color:orange;">`/opt/relay`</mark>. All system configuration files will be based on this example. To add other supported networks, you need to make the necessary changes to the configuration files of the external relay's off-chain module.

### docker-compose.yml file

This file is intended for automating the deployment of Docker containers. To complete this step, follow these instructions:

1. In the terminal, create the root directory and, if necessary, assign the required permissions: <mark style="color:orange;">`mkdir /opt/relay && cd /opt/relay`</mark> (To assign permissions, use the  <mark style="color:orange;">`chown {username} /opt/relay`</mark> command)
2. Next, create directories for the off-chain module data:

   <mark style="color:orange;">`mkdir -p docker-data/db`</mark>

   <mark style="color:orange;">`mkdir -p docker-data/config`</mark>
3. Now, create the <mark style="color:orange;">**`docker-compose.yml`**</mark> file (<mark style="color:orange;">`touch /opt/relay/docker-compose.yml`</mark>). Here's the template structure for this file:

{% code title="/opt/relay/docker-compose.yml" %}

```yaml
version: '3.9'
services:

  relay-db:
    container_name: relay-db
    image: postgres:15-alpine
    restart: always
    volumes:
      - ./docker-data/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_USER=database-user # set it to config file
      - POSTGRES_PASSWORD=database-password # set it to config file
    networks:
      - relay
  
  relay-redis:
    container_name: relay-redis
    image: redis:7.0.8-alpine
    command: >
      --requirepass redis-password # set it to config file
    networks:
      - relay

  relay-console: &console-template
    container_name: relay-console
    privileged: true
    image: asterizm/external-relay:latest
    working_dir: /app
    restart: always
    depends_on:
      - relay-db
    volumes:
      - ./docker-data/config/Project.yml:/app/config.yml:rw
    networks:
      - relay

  relay-cron:
    <<: *console-template
    container_name: relay-cron
    command: ["cron/process"]

  relay-eth:
    <<: *console-template
    container_name: relay-eth
    command: ["node/scan", "ETH"]

  relay-ever:
    <<: *console-template
    container_name: relay-ever
    command: ["node/scan", "EVER"]

  relay-ton:
    <<: *console-template
    container_name: relay-ton
    command: ["node/scan", "TON"]

  relay-sol:
    <<: *console-template
    container_name: relay-sol
    command: ["node/scan", "SOL"]

networks:
  relay:
    driver: bridge
```

{% endcode %}

In this file, you need to specify the username and password for the PostgreSQL database and Redis caching service of the off-chain module.

After creating this file, you can proceed to the next step.

### Configuration settings

To set the internal settings of the off-chain module, there is a primary configuration file. You should modify the parameters in this file to suit your needs.

In our example, the configuration file will be located in the directory <mark style="color:orange;">`/opt/relay/docker-data/config/Project.yml`</mark>(<mark style="color:orange;">`touch /opt/relay/docker-data/config/Project.yml`</mark>), however, you can change its name/path according to your preference. If you do so, make sure to update the paths in the <mark style="color:orange;">`docker-compose.yml`</mark> file.

Here is the structure of the configuration file:

{% code title="Project.yml" fullWidth="false" %}

```yaml
Environment:
  LogLevel: INFO # logging level for the off-chain module
  LicenseKey: "license-key" # unique identifier for the off-chain module 
  LicenseHost: https://tr.asterizm.io # for the testent, change this parameter to https://testtr.asterizm.io
Utils:
  Encryption:
    Key: "encryption-key" #transfer data encryption key
    Salt: "encryption-default-salt" # default data encryption salt
    CipherMethod: "AES-256-CBC" # encryption method
  Db:
    Host: relay-db # database host (name of database container docker)
    Port: 5432 # database port
    Name: "relay" # database name
    User: "database-user" # the user name of the database (see the file docker-compose.yml)
    Password: "database-password" # database password (see the file docker-compose.yml)
  Redis:
    Host: relay-redis
    Port: 6379
    Password: "redis-password" # cache service password (see the docker-compose.yml file)
    Db: 0
  Chainspot: # Chainspot service settings. Simply copy this one
    Host: https://rate.chainspot.io
    ApiKey: 38gXgViK7BcQhoB5Sfyj0PBeKyEAn2M3VmqCEfdFhMrydJGEH4G4ZLPKpjLm8tOJ 
Nodes:
  List:
    ETH: # Ethereum network (EVM)
      RPC: https://ethereum-rpc.com # RPC nodes
      ContractAddress: "client-contract-address-in-eth-network" # external relay contract address on Ethereum network
    EVER: # Everscale network (TVM)
      RPC: https://everscale-rpc.com # node RPC
      ContractAddress: "client-contract-address-in-everscale-network" # external relay contract address on Ethereum network
```

{% endcode %}

{% hint style="info" %}
**Important**: Please note that the configuration format for EVM and TVM networks is slightly different: in **TVM** networks the **OwnerPublicKey** parameter is added
{% endhint %}

Supported encryption methods (**CipherMethod** parameter): AES-{128, 192, 256}-{CBC, OFB, CFB, CTR}. **Recommended: AES-256-CBC**.

In order for the off-chain module to properly extract the payload received from the contract, it is necessary to specify what types of data are stored in it. For this purpose, the **PayloadStruct** parameter is used. You need to specify what types of parameters are stored in your contract. System-supported parameters: **bool, string, bytes, int (all sizes), uint (all sizes).**

You can configure the logging level of the client off-chain module. This parameter affects the completeness of the information in the module's logs. Logs are written to stdout, so you can see them in docker container logs (**docker logs -f {container-name}**). There are 4 levels:

* &#x20;**INFO** (logs minimal required information, standard actions),
* **WARN** (includes **INFO** logging level, adds a detailed log of some exceptions),
* **ERROR** (includes **WARN** logging level, adds full system error log),
* **DEBUG** (includes **ERROR** logging level, adds a log of most system actions, used for error detection and debugging, not recommended for product deployment).

Default logging level (if the configuration parameter is not set) is **INFO**.

Personal unique data, such as the private encryption key, the default encryption salt, the RPC addresses of the nodes, the contract addresses of each network (contracts must already be deployed), and the user names, database, and hash service passwords (specified in the <mark style="color:orange;">**`docker-compose.yml`**</mark> file, see the [previous step](#docker-compose.yml-file)) must be entered into this configuration file.

### Running the module

To start the Docker containers for the off-chain module, you can simply execute one command: <mark style="color:orange;">`docker compose -f /opt/relay/docker-compose.yml up -d`</mark>. After executing this command, the module will start.

The next and final step is to configure the off-chain module's database. To do this, follow these steps:

1. <mark style="color:orange;">`docker exec relay-db psql -U database-user -c "CREATE DATABASE relay"`</mark> - This command will create a database in the **relay-db** container (note the database user name, it was specified in <mark style="color:orange;">**`docker-compose.yml`**</mark>);
2. <mark style="color:orange;">`docker exec relay-console /app/main migrations/up`</mark> - this command extracts migrations to the database;
3. <mark style="color:orange;">`docker exec relay-console /app/main db/seed`</mark> - this command extracts fixtures onto the database.  **Important**: you can add <mark style="color:orange;">`-test`</mark> a flag for filling the database with [testnet networks](/technical-reference/testnet.md).

After successfully executing these commands, the off-chain module's database will be ready for operation. You can then restart the module's containers with the following command: <mark style="color:orange;">`docker compose -f /opt/relay/docker-compose.yml restart`</mark>.

### Managing system owners

To enable operation, it is necessary to add data about contract owners to the system. This can be done using the following console command:

```bash
docker exec relay-console /app/main owners/add {netwotk-symbol} {owner-address} {owner-private-key} {?owner-public-key}
```

This command adds a contract owner of a specific network. It accepts the following parameters:

* **network-symbol** - mandatory parameter, the network symbol (e.g., ETH, POL, etc.)
* **owner-address** - mandatory parameter, the address of the owner
* **owner-private-key** - mandatory parameter, the private key of the owner
* **owner-public-key** - optional parameter, the public key of the owner (used in TVM systems).

To display a list of owners already added to the system, execute the following command:

```bash
docker exec relay-console /app/main owners/list {?network-symbol}
```

To display a list of owners already added to the system, you can execute the following command:

* **network-symbol** - optional parameter, the network symbol (e.g., ETH, POL, etc.)

Added owners cannot be deleted; they can only be deactivated. This is done with the following command:

```bash
docker exec relay-console /app/main owners/disable {owner-id}
```

This command deactivates a previously added owner. The command accepts the following parameters:

* **owner-id** - mandatory parameter, the ID of the owner, which can be obtained by executing the console method for listing owners

Deactivated owners can be reactivated. This is achieved by executing the following console command:

```bash
docker exec relay-console /app/main owners/enable {owner-id}
```

This command activates a previously deactivated owner. The command accepts the following parameters:

* **owner-id** - mandatory parameter, the ID of the owner, which can be obtained by executing the console method for listing owners.

After changing the configuration file, it is necessary to restart the system containers (if they were previously running) with the following command: <mark style="color:orange;">`docker compose -f /opt/relay/docker-compose.yml restart`</mark>

Congratulations! You are now ready to start working with the system.

#### Debug

To check the functionality of the Docker containers, you can use the <mark style="color:orange;">`docker ps`</mark> command,  which will display a list of containers along with their status and other information.

If you want to read the logs of a specific off-chain module container, you can use the <mark style="color:orange;">`docker logs -f relay-eth`</mark> command. This command will display the logs of the Ethereum network container. You can similarly check the logs of other containers by replacing <mark style="color:orange;">`relay-eth`</mark> with the name of the specific container you want to check.

The verbosity level of the logs can be configured in the module's configuration file under the <mark style="color:orange;">`Environment.LogLevel`</mark> parameter.


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.asterizm.io/guides/external-relays/relay-deployment-and-configuration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
