├── README.png ├── config.cfg ├── config ├── devnet │ ├── 1-mx-chain-es-indexer-go │ │ ├── cmd │ │ │ └── elasticindexer │ │ │ │ ├── api.toml │ │ │ │ ├── config.toml │ │ │ │ └── prefs.toml │ │ ├── mvx-elasticindexer.service │ │ └── docker-compose.yml │ ├── 3-mx-api-service │ │ ├── mvx-api.service │ │ ├── docker-compose.yml │ │ └── config.yaml │ ├── 2-mx-exchange-service │ │ ├── mvx-exchange.service │ │ ├── docker-compose.yml │ │ ├── .env │ │ └── timescaledb.module.ts │ └── 0-observingSquad │ │ └── elrond-nodes │ │ ├── node-0 │ │ ├── external.toml │ │ └── prefs.toml │ │ ├── node-1 │ │ ├── external.toml │ │ └── prefs.toml │ │ ├── node-2 │ │ ├── external.toml │ │ └── prefs.toml │ │ └── node-3 │ │ ├── external.toml │ │ └── prefs.toml ├── mainnet │ ├── 1-mx-chain-es-indexer-go │ │ ├── cmd │ │ │ └── elasticindexer │ │ │ │ ├── api.toml │ │ │ │ ├── config.toml │ │ │ │ └── prefs.toml │ │ ├── mvx-elasticindexer.service │ │ └── docker-compose.yml │ ├── 3-mx-api-service │ │ ├── mvx-api.service │ │ ├── docker-compose.yml │ │ └── config.yaml │ ├── 2-mx-exchange-service │ │ ├── mvx-exchange.service │ │ ├── docker-compose.yml │ │ ├── .env │ │ └── timescaledb.module.ts │ └── 0-observingSquad │ │ └── elrond-nodes │ │ ├── node-0 │ │ ├── external.toml │ │ └── prefs.toml │ │ ├── node-1 │ │ ├── external.toml │ │ └── prefs.toml │ │ ├── node-2 │ │ ├── external.toml │ │ └── prefs.toml │ │ └── node-3 │ │ ├── external.toml │ │ └── prefs.toml └── bashrc ├── 3-Start.sh ├── LICENSE ├── 1-Init.sh ├── 2-Install.sh ├── scripts ├── 1-server.sh ├── 0-common.sh ├── 4-xexchange.sh ├── 2-observing-squad.sh ├── 5-mx-api.sh ├── 3-es-indexer.sh └── 6-manage-services.sh └── README.md /README.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhyByte/mvx-api-deployer/HEAD/README.png -------------------------------------------------------------------------------- /config.cfg: -------------------------------------------------------------------------------- 1 | # The name of the uesr that will be create to setup and deploy the API stack. 2 | USERNAME=ubuntu 3 | 4 | 5 | # MultiversX Network 6 | NETWORK="devnet" # devnet, testnet, mainnet 7 | 8 | -------------------------------------------------------------------------------- /config/devnet/1-mx-chain-es-indexer-go/cmd/elasticindexer/api.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | rest-api-interface = ":5555" 3 | 4 | [api-packages] 5 | 6 | [api-packages.status] 7 | routes = [ 8 | { name = "/metrics", open = true }, 9 | { name = "/prometheus-metrics", open = true } 10 | ] -------------------------------------------------------------------------------- /config/mainnet/1-mx-chain-es-indexer-go/cmd/elasticindexer/api.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | rest-api-interface = ":5555" 3 | 4 | [api-packages] 5 | 6 | [api-packages.status] 7 | routes = [ 8 | { name = "/metrics", open = true }, 9 | { name = "/prometheus-metrics", open = true } 10 | ] -------------------------------------------------------------------------------- /config/devnet/3-mx-api-service/mvx-api.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=MultiversX API Service 3 | After=network.target 4 | 5 | [Service] 6 | Type=simple 7 | User=ubuntu 8 | WorkingDirectory=/home/ubuntu/mx-api-service 9 | ExecStart=npm run start:devnet 10 | Restart=on-failure 11 | 12 | [Install] 13 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /config/mainnet/3-mx-api-service/mvx-api.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=MultiversX API Service 3 | After=network.target 4 | 5 | [Service] 6 | Type=simple 7 | User=ubuntu 8 | WorkingDirectory=/home/ubuntu/mx-api-service 9 | ExecStart=npm run start:mainnet 10 | Restart=on-failure 11 | 12 | [Install] 13 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /config/devnet/2-mx-exchange-service/mvx-exchange.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=MultiversX Exchange Service 3 | After=network.target 4 | 5 | [Service] 6 | Type=simple 7 | User=ubuntu 8 | WorkingDirectory=/home/ubuntu/mx-exchange-service 9 | ExecStart=npm run start 10 | Restart=on-failure 11 | 12 | [Install] 13 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /config/mainnet/2-mx-exchange-service/mvx-exchange.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=MultiversX Exchange Service 3 | After=network.target 4 | 5 | [Service] 6 | Type=simple 7 | User=ubuntu 8 | WorkingDirectory=/home/ubuntu/mx-exchange-service 9 | ExecStart=npm run start 10 | Restart=on-failure 11 | 12 | [Install] 13 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /3-Start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Load variables from configuration File 4 | source config.cfg 5 | 6 | # Import scripts for the different scripts 7 | source scripts/0-common.sh 8 | source scripts/6-manage-services.sh 9 | 10 | # Start all services 11 | ObsSquad_Start 12 | EsIndexer_Start 13 | EsKibana_Start 14 | xExchange_Start 15 | MxApi_Start -------------------------------------------------------------------------------- /config/devnet/1-mx-chain-es-indexer-go/mvx-elasticindexer.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=ElasticSearch Indexer 3 | After=network.target 4 | 5 | [Service] 6 | Type=simple 7 | User=ubuntu 8 | WorkingDirectory=/home/ubuntu/mx-chain-es-indexer-go/cmd/elasticindexer 9 | ExecStart=/home/ubuntu/mx-chain-es-indexer-go/cmd/elasticindexer/elasticindexer 10 | Restart=on-failure 11 | 12 | [Install] 13 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /config/mainnet/1-mx-chain-es-indexer-go/mvx-elasticindexer.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=ElasticSearch Indexer 3 | After=network.target 4 | 5 | [Service] 6 | Type=simple 7 | User=ubuntu 8 | WorkingDirectory=/home/ubuntu/mx-chain-es-indexer-go/cmd/elasticindexer 9 | ExecStart=/home/ubuntu/mx-chain-es-indexer-go/cmd/elasticindexer/elasticindexer 10 | Restart=on-failure 11 | 12 | [Install] 13 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /config/devnet/1-mx-chain-es-indexer-go/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | services: 3 | elasticsearch: 4 | container_name: es-container 5 | image: docker.elastic.co/elasticsearch/elasticsearch:7.16.1 6 | environment: 7 | - "discovery.type=single-node" 8 | - "xpack.security.enabled=false" 9 | - "ES_JAVA_OPTS=-Xms512m -Xmx512m" 10 | ulimits: 11 | memlock: 12 | soft: -1 13 | hard: -1 14 | networks: 15 | - es-net 16 | ports: 17 | - "9200:9200" 18 | - "9300:9300" 19 | kibana: 20 | container_name: kb-container 21 | image: docker.elastic.co/kibana/kibana:7.16.1 22 | environment: 23 | - ELASTICSEARCH_HOSTS=http://es-container:9200 24 | networks: 25 | - es-net 26 | depends_on: 27 | - elasticsearch 28 | ports: 29 | - "5601:5601" 30 | networks: 31 | es-net: 32 | driver: bridge -------------------------------------------------------------------------------- /config/mainnet/1-mx-chain-es-indexer-go/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | services: 3 | elasticsearch: 4 | container_name: es-container 5 | image: docker.elastic.co/elasticsearch/elasticsearch:7.16.1 6 | environment: 7 | - "discovery.type=single-node" 8 | - "xpack.security.enabled=false" 9 | - "ES_JAVA_OPTS=-Xms512m -Xmx512m" 10 | ulimits: 11 | memlock: 12 | soft: -1 13 | hard: -1 14 | networks: 15 | - es-net 16 | ports: 17 | - "9200:9200" 18 | - "9300:9300" 19 | kibana: 20 | container_name: kb-container 21 | image: docker.elastic.co/kibana/kibana:7.16.1 22 | environment: 23 | - ELASTICSEARCH_HOSTS=http://es-container:9200 24 | networks: 25 | - es-net 26 | depends_on: 27 | - elasticsearch 28 | ports: 29 | - "5601:5601" 30 | networks: 31 | es-net: 32 | driver: bridge -------------------------------------------------------------------------------- /config/devnet/1-mx-chain-es-indexer-go/cmd/elasticindexer/config.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | [config] 3 | available-indices = [ 4 | "rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", 5 | "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", 6 | "logs", "delegators", "operations", "esdts", "values", "events" 7 | ] 8 | [config.address-converter] 9 | length = 32 10 | type = "bech32" 11 | prefix = "erd" 12 | [config.validator-keys-converter] 13 | length = 96 14 | type = "hex" 15 | [config.hasher] 16 | type = "blake2b" 17 | [config.marshaller] 18 | type = "gogo protobuf" 19 | [config.economics] 20 | denomination = 18 21 | [config.logs] 22 | log-file-life-span-in-mb = 1024 # 1GB 23 | log-file-life-span-in-sec = 432000 # 5 days 24 | log-file-prefix = "elastic-indexer" 25 | logs-path = "logs" -------------------------------------------------------------------------------- /config/mainnet/1-mx-chain-es-indexer-go/cmd/elasticindexer/config.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | [config] 3 | available-indices = [ 4 | "rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", 5 | "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", 6 | "logs", "delegators", "operations", "esdts", "values", "events" 7 | ] 8 | [config.address-converter] 9 | length = 32 10 | type = "bech32" 11 | prefix = "erd" 12 | [config.validator-keys-converter] 13 | length = 96 14 | type = "hex" 15 | [config.hasher] 16 | type = "blake2b" 17 | [config.marshaller] 18 | type = "gogo protobuf" 19 | [config.economics] 20 | denomination = 18 21 | [config.logs] 22 | log-file-life-span-in-mb = 1024 # 1GB 23 | log-file-life-span-in-sec = 432000 # 5 days 24 | log-file-prefix = "elastic-indexer" 25 | logs-path = "logs" -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Philippe Martin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /config/devnet/2-mx-exchange-service/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | services: 3 | redis: 4 | image: redis 5 | container_name: redis 6 | command: redis-server 7 | ports: 8 | - "6380:6379" 9 | expose: 10 | - "6379" 11 | rabbitmq: 12 | image: 331leo/rabbitmq3-management-mqtt 13 | hostname: rabbitmq 14 | environment: 15 | HOSTNAME: rabbitmq 16 | RABBITMQ_NODENAME: rabbitmq 17 | RABBITMQ_DEFAULT_USER: "guest" 18 | RABBITMQ_DEFAULT_PASS: "guest" 19 | volumes: 20 | - /var/lib/rabbitmq 21 | ports: 22 | - "5674:5672" 23 | - "15674:15672" 24 | mongodb: 25 | image: mongo:latest 26 | environment: 27 | - MONGODB_DATABASE=development 28 | - MONGO_INITDB_ROOT_USERNAME=admin 29 | - MONGO_INITDB_ROOT_PASSWORD=admin 30 | ports: 31 | - "27018:27017" 32 | timescaledb: 33 | image: timescale/timescaledb-ha:pg14-latest 34 | container_name: timescaledb_instance 35 | ports: 36 | - "5432:5432" 37 | environment: 38 | POSTGRES_PASSWORD: postgres 39 | POSTGRES_USER: postgres 40 | TIMESCALEDB_TELEMETRY: off 41 | PGDATA: /var/lib/postgresql/data/pgdata 42 | -------------------------------------------------------------------------------- /config/mainnet/2-mx-exchange-service/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | services: 3 | redis: 4 | image: redis 5 | container_name: redis 6 | command: redis-server 7 | ports: 8 | - "6380:6379" 9 | expose: 10 | - "6379" 11 | rabbitmq: 12 | image: 331leo/rabbitmq3-management-mqtt 13 | hostname: rabbitmq 14 | environment: 15 | HOSTNAME: rabbitmq 16 | RABBITMQ_NODENAME: rabbitmq 17 | RABBITMQ_DEFAULT_USER: "guest" 18 | RABBITMQ_DEFAULT_PASS: "guest" 19 | volumes: 20 | - /var/lib/rabbitmq 21 | ports: 22 | - "5674:5672" 23 | - "15674:15672" 24 | mongodb: 25 | image: mongo:latest 26 | environment: 27 | - MONGODB_DATABASE=development 28 | - MONGO_INITDB_ROOT_USERNAME=admin 29 | - MONGO_INITDB_ROOT_PASSWORD=admin 30 | ports: 31 | - "27018:27017" 32 | timescaledb: 33 | image: timescale/timescaledb-ha:pg14-latest 34 | container_name: timescaledb_instance 35 | ports: 36 | - "5432:5432" 37 | environment: 38 | POSTGRES_PASSWORD: postgres 39 | POSTGRES_USER: postgres 40 | TIMESCALEDB_TELEMETRY: off 41 | PGDATA: /var/lib/postgresql/data/pgdata 42 | -------------------------------------------------------------------------------- /config/devnet/3-mx-api-service/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | services: 3 | redis: 4 | image: "redis:alpine" 5 | command: redis-server 6 | ports: 7 | - "6379:6379" 8 | environment: 9 | - REDIS_REPLICATION_MODE=master 10 | 11 | sqldatabase: 12 | image: "mysql:latest" 13 | ports: 14 | - "3306:3306" 15 | environment: 16 | - MYSQL_ROOT_PASSWORD=root 17 | - MYSQL_DATABASE=api 18 | 19 | mongodbdatabase: 20 | image: mongo:latest 21 | environment: 22 | MONGO_INITDB_ROOT_USERNAME: root 23 | MONGO_INITDB_ROOT_PASSWORD: secret 24 | ports: 25 | - 27017:27017 26 | 27 | ffmpeg: 28 | image: jrottenberg/ffmpeg 29 | 30 | rabbitmq: 31 | image: rabbitmq:3.9 32 | container_name: rabbitmq 33 | environment: 34 | RABBITMQ_DEFAULT_USER: guest 35 | RABBITMQ_DEFAULT_PASS: guest 36 | ports: 37 | - 5672:5672 38 | - 15672:15672 39 | 40 | notifier: 41 | image: 331leo/rabbitmq3-management-mqtt 42 | hostname: notifier 43 | environment: 44 | HOSTNAME: notifier 45 | RABBITMQ_NODENAME: rabbitmq 46 | RABBITMQ_DEFAULT_USER: "guest" 47 | RABBITMQ_DEFAULT_PASS: "guest" 48 | volumes: 49 | - /var/lib/notifier 50 | ports: 51 | - 5673:5672 52 | - 15673:15672 53 | -------------------------------------------------------------------------------- /config/mainnet/3-mx-api-service/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | services: 3 | redis: 4 | image: "redis:alpine" 5 | command: redis-server 6 | ports: 7 | - "6379:6379" 8 | environment: 9 | - REDIS_REPLICATION_MODE=master 10 | 11 | sqldatabase: 12 | image: "mysql:latest" 13 | ports: 14 | - "3306:3306" 15 | environment: 16 | - MYSQL_ROOT_PASSWORD=root 17 | - MYSQL_DATABASE=api 18 | 19 | mongodbdatabase: 20 | image: mongo:latest 21 | environment: 22 | MONGO_INITDB_ROOT_USERNAME: root 23 | MONGO_INITDB_ROOT_PASSWORD: secret 24 | ports: 25 | - 27017:27017 26 | 27 | ffmpeg: 28 | image: jrottenberg/ffmpeg 29 | 30 | rabbitmq: 31 | image: rabbitmq:3.9 32 | container_name: rabbitmq 33 | environment: 34 | RABBITMQ_DEFAULT_USER: guest 35 | RABBITMQ_DEFAULT_PASS: guest 36 | ports: 37 | - 5672:5672 38 | - 15672:15672 39 | 40 | notifier: 41 | image: 331leo/rabbitmq3-management-mqtt 42 | hostname: notifier 43 | environment: 44 | HOSTNAME: notifier 45 | RABBITMQ_NODENAME: rabbitmq 46 | RABBITMQ_DEFAULT_USER: "guest" 47 | RABBITMQ_DEFAULT_PASS: "guest" 48 | volumes: 49 | - /var/lib/notifier 50 | ports: 51 | - 5673:5672 52 | - 15673:15672 53 | -------------------------------------------------------------------------------- /config/devnet/1-mx-chain-es-indexer-go/cmd/elasticindexer/prefs.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | [config] 3 | disabled-indices = [] 4 | [config.web-socket] 5 | # URL for the WebSocket client/server connection 6 | # This value represents the IP address and port number that the WebSocket client or server will use to establish a connection. 7 | url = "localhost:22111" 8 | # This flag describes the mode to start the WebSocket connector. Can be "client" or "server" 9 | mode = "server" 10 | # Possible values: json, gogo protobuf. Should be compatible with mx-chain-node outport driver config 11 | data-marshaller-type = "json" 12 | # Retry duration (receive/send ack signal) in seconds 13 | retry-duration-in-seconds = 5 14 | # Signals if in case of data payload processing error, we should send the ack signal or not 15 | blocking-ack-on-error = true 16 | # After a message will be sent it will wait for an ack message if this flag is enabled 17 | with-acknowledge = true 18 | # The duration in seconds to wait for an acknowledgment message, after this time passes an error will be returned 19 | acknowledge-timeout-in-seconds = 50 20 | 21 | [config.elastic-cluster] 22 | use-kibana = false 23 | url = "http://localhost:9200" 24 | username = "" 25 | password = "" 26 | bulk-request-max-size-in-bytes = 4194304 # 4MB -------------------------------------------------------------------------------- /config/mainnet/1-mx-chain-es-indexer-go/cmd/elasticindexer/prefs.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | [config] 3 | disabled-indices = [] 4 | [config.web-socket] 5 | # URL for the WebSocket client/server connection 6 | # This value represents the IP address and port number that the WebSocket client or server will use to establish a connection. 7 | url = "localhost:22111" 8 | # This flag describes the mode to start the WebSocket connector. Can be "client" or "server" 9 | mode = "server" 10 | # Possible values: json, gogo protobuf. Should be compatible with mx-chain-node outport driver config 11 | data-marshaller-type = "json" 12 | # Retry duration (receive/send ack signal) in seconds 13 | retry-duration-in-seconds = 5 14 | # Signals if in case of data payload processing error, we should send the ack signal or not 15 | blocking-ack-on-error = true 16 | # After a message will be sent it will wait for an ack message if this flag is enabled 17 | with-acknowledge = true 18 | # The duration in seconds to wait for an acknowledgment message, after this time passes an error will be returned 19 | acknowledge-timeout-in-seconds = 50 20 | 21 | [config.elastic-cluster] 22 | use-kibana = false 23 | url = "http://localhost:9200" 24 | username = "" 25 | password = "" 26 | bulk-request-max-size-in-bytes = 4194304 # 4MB -------------------------------------------------------------------------------- /1-Init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # --------------------------------------------------------- 4 | # MultiversX API Deployer - Initialize the Server 5 | # --------------------------------------------------------- 6 | 7 | # Load configuration variables 8 | source config.cfg 9 | 10 | # Import common functions and server preparation scripts 11 | source scripts/0-common.sh 12 | source scripts/1-server.sh 13 | 14 | Log-Title "MultiversX API Deployer - Initialize the Server" 15 | # --------------------------------------------------------- 16 | # Validate Configuration and Machine Specifications 17 | # --------------------------------------------------------- 18 | Verify_Configuration 19 | 20 | # --------------------------------------------------------- 21 | # Upgrade System Packages 22 | # --------------------------------------------------------- 23 | Upgrade_System 24 | 25 | # --------------------------------------------------------- 26 | # Install Docker and Docker Compose 27 | # --------------------------------------------------------- 28 | Install_Docker 29 | 30 | # --------------------------------------------------------- 31 | # Update .bashrc 32 | # --------------------------------------------------------- 33 | Append_Bashrc 34 | source ~/.bashrc 35 | 36 | # --------------------------------------------------------- 37 | # Instructions for the User 38 | # --------------------------------------------------------- 39 | Log-Title "Server Initialization Completed" 40 | Log "Please proceed with the next script to install the required services by running:" 41 | Log " cd $HOME/mvx-api-deployer" 42 | Log " ./2-Install.sh" -------------------------------------------------------------------------------- /config/mainnet/2-mx-exchange-service/.env: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | NODE_ENV=mainnet 3 | PORT=3005 4 | PRIVATE_PORT=4002 5 | CACHEWARMER_PORT=6002 6 | LISTEN_ADDRESS=0.0.0.0 7 | PRIVATE_LISTEN_ADDRESS=0.0.0.0 8 | NODE_CONFIG_DIR="src/config" 9 | 10 | # keepalive 11 | KEEPALIVE_TIMEOUT_DOWNSTREAM=45000 12 | KEEPALIVE_TIMEOUT_UPSTREAM=65000 13 | 14 | #Redis for cache 15 | REDIS_URL="localhost" 16 | REDIS_PREFIX="development_env" 17 | REDIS_PASSWORD="" 18 | REDIS_PORT=6380 19 | REDIS_DB=0 20 | 21 | #MongoDB 22 | MONGODB_URL=mongodb://localhost:27018 23 | MONGODB_DATABASE=development 24 | MONGODB_USERNAME=admin 25 | MONGODB_PASSWORD=admin 26 | 27 | #Elasticsearch server to use for logging. Optional 28 | ELASTICSEARCH_URL="https://testnet-index.multiversx.com" 29 | 30 | #MultiversX resources 31 | MX_API_URL="http://localhost:3001" 32 | MX_GATEWAY_URL="http://localhost:8079" 33 | MX_DEX_URL="https://graphql-next.maiar.exchange" 34 | MX_DATA_API_URL="https://data-api.multiversx.com" 35 | 36 | #Enable or Disable modules 37 | ENABLE_PUBLIC_API=true 38 | ENABLE_PRIVATE_API=true 39 | ENABLE_CACHE_WARMER=true 40 | ENABLE_EVENTS_NOTIFIER=false 41 | ENABLE_TRACER=false 42 | 43 | #Log filename to use for file logging. Optional 44 | LOG_FILE= 45 | 46 | #Log level can be one of : error, debug, info 47 | LOG_LEVEL=info 48 | 49 | # JWT Authorization 50 | JWT_SECRET= 51 | NATIVE_AUTH_MAX_EXPIRY_SECONDS=86400 52 | NATIVE_AUTH_ACCEPTED_ORIGINS= 53 | IMPERSONATE_URL= 54 | 55 | # RabbitMQ 56 | RABBITMQ_URL= 57 | RABBITMQ_EXCHANGE=all_events 58 | RABBITMQ_QUEUE=dex_service 59 | 60 | # Other 61 | ENABLE_CACHE_GUEST_RATE_THRESHOLD=100 62 | GUEST_CACHE_REDIS_BATCH_SIZE=3 63 | NATIVE_AUTH_PEM_PATH= 64 | 65 | # AWS Timestream 66 | AWS_TIMESTREAM_READ=false 67 | AWS_TIMESTREAM_WRITE=false 68 | 69 | TIMESCALEDB_URL="localhost" 70 | TIMESCALEDB_PORT=5432 71 | TIMESCALEDB_DATABASE="postgres" 72 | TIMESCALEDB_USERNAME="postgres" 73 | TIMESCALEDB_PASSWORD="postgres" -------------------------------------------------------------------------------- /config/devnet/2-mx-exchange-service/.env: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | NODE_ENV=devnet # mainnet | testnet 3 | PORT=3005 4 | PRIVATE_PORT=4002 5 | CACHEWARMER_PORT=6002 6 | LISTEN_ADDRESS=0.0.0.0 7 | PRIVATE_LISTEN_ADDRESS=0.0.0.0 8 | NODE_CONFIG_DIR="src/config" 9 | 10 | # keepalive 11 | KEEPALIVE_TIMEOUT_DOWNSTREAM=45000 12 | KEEPALIVE_TIMEOUT_UPSTREAM=65000 13 | 14 | #Redis for cache 15 | REDIS_URL="localhost" 16 | REDIS_PREFIX="development_env" 17 | REDIS_PASSWORD="" 18 | REDIS_PORT=6380 19 | REDIS_DB=0 20 | 21 | #MongoDB 22 | MONGODB_URL=mongodb://localhost:27018 23 | MONGODB_DATABASE=development 24 | MONGODB_USERNAME=admin 25 | MONGODB_PASSWORD=admin 26 | 27 | #Elasticsearch server to use for logging. Optional 28 | ELASTICSEARCH_URL="https://testnet-index.multiversx.com" 29 | 30 | #MultiversX resources 31 | MX_API_URL="http://localhost:3001" 32 | MX_GATEWAY_URL="http://localhost:8079" 33 | MX_DEX_URL="https://devnet-graphql-next.maiar.exchange" 34 | MX_DATA_API_URL="https://data-api.multiversx.com" 35 | 36 | #Enable or Disable modules 37 | ENABLE_PUBLIC_API=true 38 | ENABLE_PRIVATE_API=true 39 | ENABLE_CACHE_WARMER=true 40 | ENABLE_EVENTS_NOTIFIER=false 41 | ENABLE_TRACER=false 42 | 43 | #Log filename to use for file logging. Optional 44 | LOG_FILE= 45 | 46 | #Log level can be one of : error, debug, info 47 | LOG_LEVEL=info 48 | 49 | # JWT Authorization 50 | JWT_SECRET= 51 | NATIVE_AUTH_MAX_EXPIRY_SECONDS=86400 52 | NATIVE_AUTH_ACCEPTED_ORIGINS= 53 | IMPERSONATE_URL= 54 | 55 | # RabbitMQ 56 | RABBITMQ_URL= 57 | RABBITMQ_EXCHANGE=all_events 58 | RABBITMQ_QUEUE=dex_service 59 | 60 | # Other 61 | ENABLE_CACHE_GUEST_RATE_THRESHOLD=100 62 | GUEST_CACHE_REDIS_BATCH_SIZE=3 63 | NATIVE_AUTH_PEM_PATH= 64 | 65 | # AWS Timestream 66 | AWS_TIMESTREAM_READ=false 67 | AWS_TIMESTREAM_WRITE=false 68 | 69 | TIMESCALEDB_URL="localhost" 70 | TIMESCALEDB_PORT=5432 71 | TIMESCALEDB_DATABASE="postgres" 72 | TIMESCALEDB_USERNAME="postgres" 73 | TIMESCALEDB_PASSWORD="postgres" -------------------------------------------------------------------------------- /2-Install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # --------------------------------------------------------- 4 | # MultiversX API Deployer - Install Required Services 5 | # --------------------------------------------------------- 6 | 7 | # Load variables from configuration File 8 | source config.cfg 9 | 10 | # Import scripts for the different scripts 11 | source scripts/0-common.sh 12 | source scripts/1-server.sh 13 | source scripts/2-observing-squad.sh 14 | source scripts/3-es-indexer.sh 15 | source scripts/4-xexchange.sh 16 | source scripts/5-mx-api.sh 17 | 18 | # --------------------------------------------------------- 19 | # Install Observing Squad 20 | # --------------------------------------------------------- 21 | Log-Title "Install Observing Squad" 22 | 23 | ObsSquad_Prepare_Environment 24 | ObsSquad_Install 25 | ObsSquad_Copy_Configuration 26 | 27 | # --------------------------------------------------------- 28 | # Install MultiversX ElasticSearch Indexer 29 | # --------------------------------------------------------- 30 | Log-Title "Install MultiversX Elastic Indexer" 31 | 32 | EsIndexer_Prepare_Environment 33 | EsIndexer_Copy_Configuration 34 | EsIndexer_Build 35 | EsIndexer_Create_Service 36 | 37 | 38 | # --------------------------------------------------------- 39 | # Install xExchange Service 40 | # --------------------------------------------------------- 41 | xExchange_Prepare_Environment 42 | xExchange_Copy_Configuration 43 | xExchange_Overwrite_Sll_configuration 44 | xExchange_Build 45 | xExchange_Create_Service 46 | # --------------------------------------------------------- 47 | # Install MultiversX API 48 | # --------------------------------------------------------- 49 | Log-Title "Install MultiversX API" 50 | MxApi_Prepare_Environment 51 | MxApi_Install_Dependencies 52 | MxApi_Initialize 53 | MxApi_Copy_Configuration 54 | MxApi_Create_Service 55 | 56 | # --------------------------------------------------------- 57 | # Next instructions for the User 58 | # --------------------------------------------------------- 59 | 60 | Log-Title "All services installed successfully" 61 | Log "Proceed with the next step to start all the services by running:" 62 | Log " ./3-Start.sh" 63 | 64 | -------------------------------------------------------------------------------- /config/devnet/2-mx-exchange-service/timescaledb.module.ts: -------------------------------------------------------------------------------- 1 | // Overwritted by mvx-api-deployer 2 | import { Module } from '@nestjs/common'; 3 | import { TypeOrmModule } from '@nestjs/typeorm'; 4 | import { CommonAppModule } from 'src/common.app.module'; 5 | import { ApiConfigService } from 'src/helpers/api.config.service'; 6 | import { TimescaleDBQueryService } from './timescaledb.query.service'; 7 | import { TimescaleDBWriteService } from './timescaledb.write.service'; 8 | import { 9 | CloseDaily, 10 | CloseHourly, 11 | PDCloseMinute, 12 | PriceCandleHourly, 13 | PriceCandleMinute, 14 | PriceCandleDaily, 15 | SumDaily, 16 | SumHourly, 17 | TokenBurnedWeekly, 18 | XExchangeAnalyticsEntity, 19 | } from './entities/timescaledb.entities'; 20 | import { DynamicModuleUtils } from 'src/utils/dynamic.module.utils'; 21 | 22 | @Module({ 23 | imports: [ 24 | CommonAppModule, 25 | DynamicModuleUtils.getCacheModule(), 26 | TypeOrmModule.forRootAsync({ 27 | imports: [CommonAppModule], 28 | useFactory: (apiConfig: ApiConfigService) => ({ 29 | type: 'postgres', 30 | host: apiConfig.getTimescaleDbHost(), 31 | port: apiConfig.getTimescaleDbPort(), 32 | database: apiConfig.getTimescaleDbDatabase(), 33 | username: apiConfig.getTimescaleDbUsername(), 34 | password: apiConfig.getTimescaleDbPassword(), 35 | applicationName: 'xExchangeService', 36 | ssl: false, 37 | entities: ['dist/**/*.entities.{ts,js}'], 38 | }), 39 | inject: [ApiConfigService], 40 | }), 41 | TypeOrmModule.forFeature([ 42 | XExchangeAnalyticsEntity, 43 | SumDaily, 44 | SumHourly, 45 | CloseDaily, 46 | CloseHourly, 47 | TokenBurnedWeekly, 48 | PDCloseMinute, 49 | PriceCandleMinute, 50 | PriceCandleHourly, 51 | PriceCandleDaily, 52 | ]), 53 | ], 54 | providers: [TimescaleDBQueryService, TimescaleDBWriteService], 55 | exports: [TimescaleDBQueryService, TimescaleDBWriteService], 56 | }) 57 | export class TimescaleDBModule {} 58 | -------------------------------------------------------------------------------- /config/mainnet/2-mx-exchange-service/timescaledb.module.ts: -------------------------------------------------------------------------------- 1 | // Overwritted by mvx-api-deployer 2 | import { Module } from '@nestjs/common'; 3 | import { TypeOrmModule } from '@nestjs/typeorm'; 4 | import { CommonAppModule } from 'src/common.app.module'; 5 | import { ApiConfigService } from 'src/helpers/api.config.service'; 6 | import { TimescaleDBQueryService } from './timescaledb.query.service'; 7 | import { TimescaleDBWriteService } from './timescaledb.write.service'; 8 | import { 9 | CloseDaily, 10 | CloseHourly, 11 | PDCloseMinute, 12 | PriceCandleHourly, 13 | PriceCandleMinute, 14 | PriceCandleDaily, 15 | SumDaily, 16 | SumHourly, 17 | TokenBurnedWeekly, 18 | XExchangeAnalyticsEntity, 19 | } from './entities/timescaledb.entities'; 20 | import { DynamicModuleUtils } from 'src/utils/dynamic.module.utils'; 21 | 22 | @Module({ 23 | imports: [ 24 | CommonAppModule, 25 | DynamicModuleUtils.getCacheModule(), 26 | TypeOrmModule.forRootAsync({ 27 | imports: [CommonAppModule], 28 | useFactory: (apiConfig: ApiConfigService) => ({ 29 | type: 'postgres', 30 | host: apiConfig.getTimescaleDbHost(), 31 | port: apiConfig.getTimescaleDbPort(), 32 | database: apiConfig.getTimescaleDbDatabase(), 33 | username: apiConfig.getTimescaleDbUsername(), 34 | password: apiConfig.getTimescaleDbPassword(), 35 | applicationName: 'xExchangeService', 36 | ssl: false, 37 | entities: ['dist/**/*.entities.{ts,js}'], 38 | }), 39 | inject: [ApiConfigService], 40 | }), 41 | TypeOrmModule.forFeature([ 42 | XExchangeAnalyticsEntity, 43 | SumDaily, 44 | SumHourly, 45 | CloseDaily, 46 | CloseHourly, 47 | TokenBurnedWeekly, 48 | PDCloseMinute, 49 | PriceCandleMinute, 50 | PriceCandleHourly, 51 | PriceCandleDaily, 52 | ]), 53 | ], 54 | providers: [TimescaleDBQueryService, TimescaleDBWriteService], 55 | exports: [TimescaleDBQueryService, TimescaleDBWriteService], 56 | }) 57 | export class TimescaleDBModule {} 58 | -------------------------------------------------------------------------------- /scripts/1-server.sh: -------------------------------------------------------------------------------- 1 | # --------------------------------------------------------- 2 | # MultiversX API Deployer - Server Preparation Functions 3 | # --------------------------------------------------------- 4 | 5 | # --------- FUNCTIONS --------- 6 | 7 | # Upgrade the system's packages 8 | Upgrade_System() { 9 | Log-Step "Upgrade the system's packages" 10 | Log-SubStep "Update the package list" 11 | # Update the package list to ensure the latest package information is fetched 12 | sudo apt-get update 13 | 14 | Log-SubStep "Upgrade the installed packages" 15 | # Upgrade all installed packages to their latest versions 16 | sudo apt-get upgrade -y 17 | } 18 | 19 | # Install Docker and Docker Compose 20 | Install_Docker() { 21 | Log-Step "Install Docker and Docker Compose" 22 | 23 | Log-SubStep "Install prerequisites for Docker" 24 | # Install required packages for Docker installation 25 | sudo apt-get update -y 26 | sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common 27 | 28 | Log-SubStep "Add Docker's official GPG key" 29 | # Add the Docker GPG key to verify Docker packages 30 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg 31 | 32 | Log-SubStep "Add Docker repository to APT sources" 33 | # Add Docker's official repository to the package manager's source list 34 | echo \ 35 | "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ 36 | $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list >/dev/null 37 | 38 | Log-SubStep "Update package list to include Docker repository" 39 | # Update the package list again to include Docker packages 40 | sudo apt-get update -y 41 | 42 | Log-SubStep "Install Docker and its CLI tools" 43 | # Install Docker, Docker CLI, and containerd 44 | sudo apt-get install -y docker-ce docker-ce-cli containerd.io 45 | 46 | Log-SubStep "Install Docker Compose" 47 | # Install Docker Compose plugin 48 | sudo apt-get install -y docker-compose-plugin 49 | 50 | Log-SubStep "Verify Docker and Docker Compose installation" 51 | # Verify the installation by checking the versions 52 | docker --version 53 | docker compose version 54 | } 55 | 56 | Append_Bashrc() { 57 | Log-Step "Append custom bashrc configuration" 58 | # Append the custom bashrc configuration to the user's .bashrc file 59 | if [ -f "/home/$USERNAME/mvx-api-deployer/config/bashrc" ]; then 60 | Log "Appending custom bashrc configuration to /home/$USERNAME/.bashrc" 61 | cat /home/$USERNAME/mvx-api-deployer/config/bashrc >>/home/$USERNAME/.bashrc 62 | else 63 | Log-Warning "Custom bashrc file not found in /home/$USERNAME/mvx-api-deployer/config/" 64 | fi 65 | } 66 | -------------------------------------------------------------------------------- /config/bashrc: -------------------------------------------------------------------------------- 1 | # 2 | # This .bashrc part is dedicated to the management of your MultiversX API Services 3 | # 4 | 5 | # Import necessary scripts 6 | source $HOME/mvx-api-deployer/config.cfg 7 | source $HOME/mvx-api-deployer/scripts/0-common.sh 8 | source $HOME/mvx-api-deployer/scripts/6-manage-services.sh 9 | 10 | #------------------------------------------------------------ 11 | # Service Status Commands 12 | #------------------------------------------------------------ 13 | 14 | api_check_status() { 15 | Check_All_Status 16 | } 17 | 18 | #------------------------------------------------------------ 19 | # Observing Squad Commands 20 | #------------------------------------------------------------ 21 | 22 | api_obssquad_start() { 23 | ObsSquad_Start 24 | } 25 | 26 | api_obssquad_stop() { 27 | ObsSquad_Stop 28 | } 29 | 30 | api_obssquad_monitoring_0() { 31 | $HOME/elrond-utils/termui --address localhost:8080 32 | } 33 | 34 | api_obssquad_monitoring_1() { 35 | $HOME/elrond-utils/termui --address localhost:8081 36 | } 37 | 38 | api_obssquad_monitoring_2() { 39 | $HOME/elrond-utils/termui --address localhost:8082 40 | } 41 | 42 | api_obssquad_monitoring_3() { 43 | $HOME/elrond-utils/termui --address localhost:8083 44 | } 45 | 46 | api_obssquad_monitoring_proxy() { 47 | journalctl -f -u elrond-proxy.service 48 | } 49 | 50 | #------------------------------------------------------------ 51 | # MultiversX Indexer Commands 52 | #------------------------------------------------------------ 53 | 54 | api_indexer_start() { 55 | EsIndexer_Start 56 | } 57 | 58 | api_indexer_stop() { 59 | EsIndexer_Stop 60 | } 61 | 62 | api_indexer_monitoring() { 63 | journalctl -f -u mvx-elasticindexer.service 64 | } 65 | 66 | #------------------------------------------------------------ 67 | # ElasticSearch and Kibana Commands 68 | #------------------------------------------------------------ 69 | 70 | api_eskibana_start() { 71 | EsKibana_Start 72 | } 73 | 74 | api_eskibana_stop() { 75 | EsKibana_Stop 76 | } 77 | 78 | #------------------------------------------------------------ 79 | # MultiversX Exchange Commands 80 | #------------------------------------------------------------ 81 | api_mx_exchange_start() { 82 | MxExchange_Start 83 | } 84 | 85 | api_mx_exchange_stop() { 86 | MxExchange_Stop 87 | } 88 | 89 | api_mx_exchange_monitoring() { 90 | journalctl -f -u mvx-exchange.service 91 | } 92 | 93 | #------------------------------------------------------------ 94 | # MultiversX API Commands 95 | #------------------------------------------------------------ 96 | 97 | api_mx_api_start() { 98 | MxApi_Start 99 | } 100 | 101 | api_mx_api_stop() { 102 | MxApi_Stop 103 | } 104 | 105 | #------------------------------------------------------------ 106 | # Generic User Configuration 107 | #------------------------------------------------------------ 108 | 109 | alias ll="ls -lah" 110 | alias ..="cd .." -------------------------------------------------------------------------------- /scripts/0-common.sh: -------------------------------------------------------------------------------- 1 | # --------------------------------------------------------- 2 | # Common Utilities and Logging Functions 3 | # --------------------------------------------------------- 4 | 5 | # --------- COLORS --------- 6 | # Reset 7 | COLOR_OFF='\033[0m' # Reset text color 8 | 9 | # Text Colors 10 | BLACK='\033[0;30m' 11 | RED='\033[0;31m' 12 | GREEN='\033[0;32m' 13 | YELLOW='\033[0;33m' 14 | BLUE='\033[0;34m' 15 | PURPLE='\033[0;35m' 16 | CYAN='\033[0;36m' 17 | WHITE='\033[0;37m' 18 | 19 | # Logs numbering 20 | TITLE_NUM=1 21 | STEP_NUM=1 22 | SUB_STEP_NUM=1 23 | 24 | # --------- LOGGING FUNCTIONS --------- 25 | 26 | # Log a title 27 | Log-Title() { 28 | # Format and print a title 29 | local title_text="| $TITLE_NUM/ $1 |" 30 | local border=$(printf '%*s' "${#title_text}" '' | tr ' ' '-') 31 | 32 | echo -e $PURPLE"\n--\n--\n$border" 33 | echo -e "$title_text" 34 | echo -e "$border\n--\n--\n$COLOR_OFF" 35 | 36 | # Increment the title number 37 | ((TITLE_NUM++)) 38 | } 39 | 40 | # Log a main step 41 | Log-Step() { 42 | # Format and print a main step title 43 | local step_text="| $TITLE_NUM.$STEP_NUM $1 |" 44 | local border=$(printf '%*s' "${#step_text}" '' | tr ' ' '-') 45 | 46 | echo -e $BLUE"\n--\n$border" 47 | echo -e "$step_text" 48 | echo -e "$border\n--\n$COLOR_OFF" 49 | 50 | # Increment the step number and reset the sub-step number 51 | ((STEP_NUM++)) 52 | SUB_STEP_NUM=1 53 | } 54 | 55 | # Log a sub-step 56 | Log-SubStep() { 57 | # Format and print a sub-step title 58 | local sub_step_text="--- $TITLE_NUM.$STEP_NUM.$SUB_STEP_NUM/ $1" 59 | 60 | echo -e "$CYAN\n--\n$sub_step_text\n--$COLOR_OFF" 61 | 62 | # Increment the sub-step number 63 | ((SUB_STEP_NUM++)) 64 | } 65 | 66 | # General log for informational messages 67 | Log() { 68 | echo -e "\n$BLUE - $1 $COLOR_OFF\n" 69 | } 70 | 71 | # Log a warning message 72 | Log-Warning() { 73 | echo -e "\n${YELLOW} WARNING: $1 $COLOR_OFF\n" 74 | } 75 | 76 | # Log an error message 77 | Log-Error() { 78 | echo -e "\n${RED} ERROR: $1 $COLOR_OFF\n" 79 | } 80 | 81 | # --------------------------------------------------------- 82 | # Configuration Validation 83 | # --------------------------------------------------------- 84 | 85 | # Verify that mandatory variables are set 86 | Verify_Configuration() { 87 | Log-Step "Validate Configuration" 88 | # Track if any errors are found 89 | ERROR_FOUND=false 90 | 91 | # Check USERNAME 92 | if [ -z "$USERNAME" ]; then 93 | Log-Error "The USERNAME variable is not set in the configuration file." 94 | ERROR_FOUND=true 95 | fi 96 | 97 | # Check NETWORK 98 | if [ -z "$NETWORK" ]; then 99 | Log-Error "The NETWORK variable is not set in the configuration file." 100 | ERROR_FOUND=true 101 | elif [[ "$NETWORK" != "mainnet" && "$NETWORK" != "devnet" && "$NETWORK" != "testnet" ]]; then 102 | Log-Error "The NETWORK variable must be one of the following: mainnet, devnet, or testnet." 103 | ERROR_FOUND=true 104 | fi 105 | 106 | # Exit if errors are found 107 | if [ "$ERROR_FOUND" = true ]; then 108 | Log-Error "Configuration verification failed. Please fix the errors above." 109 | exit 1 110 | fi 111 | 112 | Log "Configuration verification completed successfully." 113 | } 114 | -------------------------------------------------------------------------------- /scripts/4-xexchange.sh: -------------------------------------------------------------------------------- 1 | # Clone required repositories 2 | xExchange_Prepare_Environment() { 3 | Log-Step "Prepare xExchange Environment" 4 | 5 | local repo_url="https://github.com/multiversx/mx-exchange-service.git" 6 | local repo_dir="$HOME/mx-exchange-service" 7 | 8 | # Clone the MultiversX xExchange repository if it doesn't exist 9 | if [ ! -d "$repo_dir" ]; then 10 | Log-SubStep "Clone MultiversX xExchange Repository" 11 | git clone "$repo_url" "$repo_dir" || { 12 | Log-Error "Failed to clone MultiversX xExchange repository." 13 | return 1 14 | } 15 | Log "Repository cloned successfully." 16 | else 17 | Log-Warning "Repository already exists at $repo_dir. Skipping clone step." 18 | fi 19 | 20 | # Install npm 21 | Log-SubStep "Install npm" 22 | sudo apt install -y npm || { 23 | Log-Error "Failed to install npm." 24 | return 1 25 | } 26 | } 27 | 28 | xExchange_Copy_Configuration() { 29 | Log-Step "Copy xExchange Configuration" 30 | 31 | local source_dir="$HOME/mvx-api-deployer/config/$NETWORK/2-mx-exchange-service" 32 | local repo_dir="$HOME/mx-exchange-service" 33 | 34 | Log-SubStep "Copy docker-compose.yml file" 35 | cp -f "$source_dir/docker-compose.yml" "$repo_dir/docker-compose.yml" || { 36 | Log-Error "Failed to copy docker-compose.yml file." 37 | return 1 38 | } 39 | 40 | Log-SubStep "Copy xExchange .env file" 41 | cp -f "$source_dir/.env" "$repo_dir/.env" || { 42 | Log-Error "Failed to copy xExchange .env file." 43 | return 1 44 | } 45 | Log "xExchange configuration files copied successfully." 46 | } 47 | xExchange_Overwrite_Sll_configuration() { 48 | Log-Step "Overwrite SSL configuration file" 49 | 50 | local source_dir="$HOME/mvx-api-deployer/config/$NETWORK/2-mx-exchange-service" 51 | local repo_dir="$HOME/mx-exchange-service" 52 | local config_file="$source_dir/timescaledb.module.ts" 53 | 54 | if [ ! -f "$config_file" ]; then 55 | Log-Error "ssl file $config_file not found. Exiting." 56 | return 1 57 | fi 58 | 59 | cp -f "$config_file" "$repo_dir/src/services/analytics/timescaledb/timescaledb.module.ts" || { 60 | Log-Error "Failed to copy ssl file." 61 | return 1 62 | } 63 | } 64 | 65 | xExchange_Build() { 66 | Log-Step "Build xExchange" 67 | 68 | local repo_dir="$HOME/mx-exchange-service" 69 | 70 | cd "$repo_dir" || { 71 | Log-Error "Failed to navigate to $repo_dir." 72 | return 1 73 | } 74 | Log "Navigated to $repo_dir" 75 | 76 | Log-SubStep "Build xExchange" 77 | npm install || { 78 | Log-Error "Failed to build xExchange." 79 | return 1 80 | } 81 | sudo docker compose up -d || { 82 | Log-Error "Failed to start xExchange services. Check Docker Compose logs for details." 83 | return 1 84 | } 85 | } 86 | 87 | xExchange_Create_Service() { 88 | Log-Step "Enable Systemd Service for xExchange" 89 | 90 | local service_file="/etc/systemd/system/mvx-exchange.service" 91 | 92 | Log-SubStep "Copy xExchange Service File" 93 | sudo cp "$HOME/mvx-api-deployer/config/$NETWORK/2-mx-exchange-service/mvx-exchange.service" "$service_file" || { 94 | Log-Error "Failed to copy xExchange Indexer service file." 95 | return 1 96 | } 97 | 98 | Log-SubStep "Enable xExchange Service" 99 | sudo systemctl daemon-reload 100 | sudo systemctl enable mvx-exchange || { 101 | Log-Error "Failed to enable xExchange service." 102 | return 1 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /config/devnet/0-observingSquad/elrond-nodes/node-0/external.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | # ElasticSearchConnector defines settings related to ElasticSearch such as login information or URL 3 | [ElasticSearchConnector] 4 | ## We do not recommend to activate this indexer on a validator node since 5 | #the node might loose rating (even facing penalties) due to the fact that 6 | #the indexer is called synchronously and might block due to external causes. 7 | #Strongly suggested to activate this on a regular observer node. 8 | Enabled = false 9 | IndexerCacheSize = 0 10 | BulkRequestMaxSizeInBytes = 4194304 # 4MB 11 | URL = "http://localhost:9200" 12 | UseKibana = false 13 | Username = "" 14 | Password = "" 15 | # EnabledIndexes represents a slice of indexes that will be enabled for indexing. Full list is: 16 | # ["rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", "logs", "delegators", "operations", "esdts"] 17 | EnabledIndexes = ["rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", "logs", "delegators", "operations", "esdts"] 18 | 19 | # EventNotifierConnector defines settings needed to configure and launch the event notifier component 20 | # HTTP event notifier connector integration will be DEPRECATED in the following iterations 21 | [EventNotifierConnector] 22 | # Enabled will turn on or off the event notifier connector 23 | Enabled = false 24 | 25 | # UseAuthorization signals the proxy to use authorization 26 | # Never run a production setup without authorization 27 | UseAuthorization = false 28 | 29 | # ProxyUrl is used to communicate with the subscriptions hub 30 | # The indexer instance will broadcast data using ProxyUrl 31 | ProxyUrl = "http://localhost:5000" 32 | 33 | # Username and Password need to be specified if UseAuthorization is set to true 34 | Username = "" 35 | 36 | # Password is used to authorize an observer to push event data 37 | Password = "" 38 | 39 | # RequestTimeoutSec defines the timeout in seconds for the http client 40 | RequestTimeoutSec = 60 41 | 42 | # MarshallerType is used to define the marshaller type to be used for inner 43 | # marshalled structures in block events data 44 | MarshallerType = "json" 45 | 46 | [[HostDriversConfig]] 47 | # This flag shall only be used for observer nodes 48 | Enabled = true 49 | 50 | # This flag will start the WebSocket connector as server or client (can be "client" or "server") 51 | Mode = "client" 52 | 53 | # URL for the WebSocket client/server connection 54 | # This value represents the IP address and port number that the WebSocket client or server will use to establish a connection. 55 | URL = "ws://127.0.0.1:22111" 56 | 57 | # After a message will be sent it will wait for an ack message if this flag is enabled 58 | WithAcknowledge = true 59 | 60 | # The duration in seconds to wait for an acknowledgment message, after this time passes an error will be returned 61 | AcknowledgeTimeoutInSec = 60 62 | 63 | # This flag defines the marshaller type. Currently supported: "json", "gogo protobuf" 64 | MarshallerType = "json" 65 | 66 | # The number of seconds when the client will try again to send the data 67 | RetryDurationInSec = 5 68 | 69 | # Sets if, in case of data payload processing error, we should block or not the advancement to the next processing event. Set this to true if you wish the node to stop processing blocks if the client/server encounters errors while processing requests. 70 | BlockingAckOnError = true 71 | 72 | # Set to true to drop messages if there is no active WebSocket connection to send to. 73 | DropMessagesIfNoConnection = false 74 | 75 | # Defines the payload version. Version will be changed when there are breaking 76 | # changes on payload data. The receiver/consumer will have to know how to handle different 77 | # versions. The version will be sent as metadata in the websocket message. 78 | Version = 1 -------------------------------------------------------------------------------- /config/devnet/0-observingSquad/elrond-nodes/node-1/external.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | # ElasticSearchConnector defines settings related to ElasticSearch such as login information or URL 3 | [ElasticSearchConnector] 4 | ## We do not recommend to activate this indexer on a validator node since 5 | #the node might loose rating (even facing penalties) due to the fact that 6 | #the indexer is called synchronously and might block due to external causes. 7 | #Strongly suggested to activate this on a regular observer node. 8 | Enabled = false 9 | IndexerCacheSize = 0 10 | BulkRequestMaxSizeInBytes = 4194304 # 4MB 11 | URL = "http://localhost:9200" 12 | UseKibana = false 13 | Username = "" 14 | Password = "" 15 | # EnabledIndexes represents a slice of indexes that will be enabled for indexing. Full list is: 16 | # ["rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", "logs", "delegators", "operations", "esdts"] 17 | EnabledIndexes = ["rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", "logs", "delegators", "operations", "esdts"] 18 | 19 | # EventNotifierConnector defines settings needed to configure and launch the event notifier component 20 | # HTTP event notifier connector integration will be DEPRECATED in the following iterations 21 | [EventNotifierConnector] 22 | # Enabled will turn on or off the event notifier connector 23 | Enabled = false 24 | 25 | # UseAuthorization signals the proxy to use authorization 26 | # Never run a production setup without authorization 27 | UseAuthorization = false 28 | 29 | # ProxyUrl is used to communicate with the subscriptions hub 30 | # The indexer instance will broadcast data using ProxyUrl 31 | ProxyUrl = "http://localhost:5000" 32 | 33 | # Username and Password need to be specified if UseAuthorization is set to true 34 | Username = "" 35 | 36 | # Password is used to authorize an observer to push event data 37 | Password = "" 38 | 39 | # RequestTimeoutSec defines the timeout in seconds for the http client 40 | RequestTimeoutSec = 60 41 | 42 | # MarshallerType is used to define the marshaller type to be used for inner 43 | # marshalled structures in block events data 44 | MarshallerType = "json" 45 | 46 | [[HostDriversConfig]] 47 | # This flag shall only be used for observer nodes 48 | Enabled = true 49 | 50 | # This flag will start the WebSocket connector as server or client (can be "client" or "server") 51 | Mode = "client" 52 | 53 | # URL for the WebSocket client/server connection 54 | # This value represents the IP address and port number that the WebSocket client or server will use to establish a connection. 55 | URL = "ws://127.0.0.1:22111" 56 | 57 | # After a message will be sent it will wait for an ack message if this flag is enabled 58 | WithAcknowledge = true 59 | 60 | # The duration in seconds to wait for an acknowledgment message, after this time passes an error will be returned 61 | AcknowledgeTimeoutInSec = 60 62 | 63 | # This flag defines the marshaller type. Currently supported: "json", "gogo protobuf" 64 | MarshallerType = "json" 65 | 66 | # The number of seconds when the client will try again to send the data 67 | RetryDurationInSec = 5 68 | 69 | # Sets if, in case of data payload processing error, we should block or not the advancement to the next processing event. Set this to true if you wish the node to stop processing blocks if the client/server encounters errors while processing requests. 70 | BlockingAckOnError = true 71 | 72 | # Set to true to drop messages if there is no active WebSocket connection to send to. 73 | DropMessagesIfNoConnection = false 74 | 75 | # Defines the payload version. Version will be changed when there are breaking 76 | # changes on payload data. The receiver/consumer will have to know how to handle different 77 | # versions. The version will be sent as metadata in the websocket message. 78 | Version = 1 -------------------------------------------------------------------------------- /config/devnet/0-observingSquad/elrond-nodes/node-2/external.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | # ElasticSearchConnector defines settings related to ElasticSearch such as login information or URL 3 | [ElasticSearchConnector] 4 | ## We do not recommend to activate this indexer on a validator node since 5 | #the node might loose rating (even facing penalties) due to the fact that 6 | #the indexer is called synchronously and might block due to external causes. 7 | #Strongly suggested to activate this on a regular observer node. 8 | Enabled = false 9 | IndexerCacheSize = 0 10 | BulkRequestMaxSizeInBytes = 4194304 # 4MB 11 | URL = "http://localhost:9200" 12 | UseKibana = false 13 | Username = "" 14 | Password = "" 15 | # EnabledIndexes represents a slice of indexes that will be enabled for indexing. Full list is: 16 | # ["rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", "logs", "delegators", "operations", "esdts"] 17 | EnabledIndexes = ["rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", "logs", "delegators", "operations", "esdts"] 18 | 19 | # EventNotifierConnector defines settings needed to configure and launch the event notifier component 20 | # HTTP event notifier connector integration will be DEPRECATED in the following iterations 21 | [EventNotifierConnector] 22 | # Enabled will turn on or off the event notifier connector 23 | Enabled = false 24 | 25 | # UseAuthorization signals the proxy to use authorization 26 | # Never run a production setup without authorization 27 | UseAuthorization = false 28 | 29 | # ProxyUrl is used to communicate with the subscriptions hub 30 | # The indexer instance will broadcast data using ProxyUrl 31 | ProxyUrl = "http://localhost:5000" 32 | 33 | # Username and Password need to be specified if UseAuthorization is set to true 34 | Username = "" 35 | 36 | # Password is used to authorize an observer to push event data 37 | Password = "" 38 | 39 | # RequestTimeoutSec defines the timeout in seconds for the http client 40 | RequestTimeoutSec = 60 41 | 42 | # MarshallerType is used to define the marshaller type to be used for inner 43 | # marshalled structures in block events data 44 | MarshallerType = "json" 45 | 46 | [[HostDriversConfig]] 47 | # This flag shall only be used for observer nodes 48 | Enabled = true 49 | 50 | # This flag will start the WebSocket connector as server or client (can be "client" or "server") 51 | Mode = "client" 52 | 53 | # URL for the WebSocket client/server connection 54 | # This value represents the IP address and port number that the WebSocket client or server will use to establish a connection. 55 | URL = "ws://127.0.0.1:22111" 56 | 57 | # After a message will be sent it will wait for an ack message if this flag is enabled 58 | WithAcknowledge = true 59 | 60 | # The duration in seconds to wait for an acknowledgment message, after this time passes an error will be returned 61 | AcknowledgeTimeoutInSec = 60 62 | 63 | # This flag defines the marshaller type. Currently supported: "json", "gogo protobuf" 64 | MarshallerType = "json" 65 | 66 | # The number of seconds when the client will try again to send the data 67 | RetryDurationInSec = 5 68 | 69 | # Sets if, in case of data payload processing error, we should block or not the advancement to the next processing event. Set this to true if you wish the node to stop processing blocks if the client/server encounters errors while processing requests. 70 | BlockingAckOnError = true 71 | 72 | # Set to true to drop messages if there is no active WebSocket connection to send to. 73 | DropMessagesIfNoConnection = false 74 | 75 | # Defines the payload version. Version will be changed when there are breaking 76 | # changes on payload data. The receiver/consumer will have to know how to handle different 77 | # versions. The version will be sent as metadata in the websocket message. 78 | Version = 1 -------------------------------------------------------------------------------- /config/devnet/0-observingSquad/elrond-nodes/node-3/external.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | # ElasticSearchConnector defines settings related to ElasticSearch such as login information or URL 3 | [ElasticSearchConnector] 4 | ## We do not recommend to activate this indexer on a validator node since 5 | #the node might loose rating (even facing penalties) due to the fact that 6 | #the indexer is called synchronously and might block due to external causes. 7 | #Strongly suggested to activate this on a regular observer node. 8 | Enabled = false 9 | IndexerCacheSize = 0 10 | BulkRequestMaxSizeInBytes = 4194304 # 4MB 11 | URL = "http://localhost:9200" 12 | UseKibana = false 13 | Username = "" 14 | Password = "" 15 | # EnabledIndexes represents a slice of indexes that will be enabled for indexing. Full list is: 16 | # ["rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", "logs", "delegators", "operations", "esdts"] 17 | EnabledIndexes = ["rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", "logs", "delegators", "operations", "esdts"] 18 | 19 | # EventNotifierConnector defines settings needed to configure and launch the event notifier component 20 | # HTTP event notifier connector integration will be DEPRECATED in the following iterations 21 | [EventNotifierConnector] 22 | # Enabled will turn on or off the event notifier connector 23 | Enabled = false 24 | 25 | # UseAuthorization signals the proxy to use authorization 26 | # Never run a production setup without authorization 27 | UseAuthorization = false 28 | 29 | # ProxyUrl is used to communicate with the subscriptions hub 30 | # The indexer instance will broadcast data using ProxyUrl 31 | ProxyUrl = "http://localhost:5000" 32 | 33 | # Username and Password need to be specified if UseAuthorization is set to true 34 | Username = "" 35 | 36 | # Password is used to authorize an observer to push event data 37 | Password = "" 38 | 39 | # RequestTimeoutSec defines the timeout in seconds for the http client 40 | RequestTimeoutSec = 60 41 | 42 | # MarshallerType is used to define the marshaller type to be used for inner 43 | # marshalled structures in block events data 44 | MarshallerType = "json" 45 | 46 | [[HostDriversConfig]] 47 | # This flag shall only be used for observer nodes 48 | Enabled = true 49 | 50 | # This flag will start the WebSocket connector as server or client (can be "client" or "server") 51 | Mode = "client" 52 | 53 | # URL for the WebSocket client/server connection 54 | # This value represents the IP address and port number that the WebSocket client or server will use to establish a connection. 55 | URL = "ws://127.0.0.1:22111" 56 | 57 | # After a message will be sent it will wait for an ack message if this flag is enabled 58 | WithAcknowledge = true 59 | 60 | # The duration in seconds to wait for an acknowledgment message, after this time passes an error will be returned 61 | AcknowledgeTimeoutInSec = 60 62 | 63 | # This flag defines the marshaller type. Currently supported: "json", "gogo protobuf" 64 | MarshallerType = "json" 65 | 66 | # The number of seconds when the client will try again to send the data 67 | RetryDurationInSec = 5 68 | 69 | # Sets if, in case of data payload processing error, we should block or not the advancement to the next processing event. Set this to true if you wish the node to stop processing blocks if the client/server encounters errors while processing requests. 70 | BlockingAckOnError = true 71 | 72 | # Set to true to drop messages if there is no active WebSocket connection to send to. 73 | DropMessagesIfNoConnection = false 74 | 75 | # Defines the payload version. Version will be changed when there are breaking 76 | # changes on payload data. The receiver/consumer will have to know how to handle different 77 | # versions. The version will be sent as metadata in the websocket message. 78 | Version = 1 -------------------------------------------------------------------------------- /config/mainnet/0-observingSquad/elrond-nodes/node-0/external.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | # ElasticSearchConnector defines settings related to ElasticSearch such as login information or URL 3 | [ElasticSearchConnector] 4 | ## We do not recommend to activate this indexer on a validator node since 5 | #the node might loose rating (even facing penalties) due to the fact that 6 | #the indexer is called synchronously and might block due to external causes. 7 | #Strongly suggested to activate this on a regular observer node. 8 | Enabled = false 9 | IndexerCacheSize = 0 10 | BulkRequestMaxSizeInBytes = 4194304 # 4MB 11 | URL = "http://localhost:9200" 12 | UseKibana = false 13 | Username = "" 14 | Password = "" 15 | # EnabledIndexes represents a slice of indexes that will be enabled for indexing. Full list is: 16 | # ["rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", "logs", "delegators", "operations", "esdts"] 17 | EnabledIndexes = ["rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", "logs", "delegators", "operations", "esdts"] 18 | 19 | # EventNotifierConnector defines settings needed to configure and launch the event notifier component 20 | # HTTP event notifier connector integration will be DEPRECATED in the following iterations 21 | [EventNotifierConnector] 22 | # Enabled will turn on or off the event notifier connector 23 | Enabled = false 24 | 25 | # UseAuthorization signals the proxy to use authorization 26 | # Never run a production setup without authorization 27 | UseAuthorization = false 28 | 29 | # ProxyUrl is used to communicate with the subscriptions hub 30 | # The indexer instance will broadcast data using ProxyUrl 31 | ProxyUrl = "http://localhost:5000" 32 | 33 | # Username and Password need to be specified if UseAuthorization is set to true 34 | Username = "" 35 | 36 | # Password is used to authorize an observer to push event data 37 | Password = "" 38 | 39 | # RequestTimeoutSec defines the timeout in seconds for the http client 40 | RequestTimeoutSec = 60 41 | 42 | # MarshallerType is used to define the marshaller type to be used for inner 43 | # marshalled structures in block events data 44 | MarshallerType = "json" 45 | 46 | [[HostDriversConfig]] 47 | # This flag shall only be used for observer nodes 48 | Enabled = true 49 | 50 | # This flag will start the WebSocket connector as server or client (can be "client" or "server") 51 | Mode = "client" 52 | 53 | # URL for the WebSocket client/server connection 54 | # This value represents the IP address and port number that the WebSocket client or server will use to establish a connection. 55 | URL = "ws://127.0.0.1:22111" 56 | 57 | # After a message will be sent it will wait for an ack message if this flag is enabled 58 | WithAcknowledge = true 59 | 60 | # The duration in seconds to wait for an acknowledgment message, after this time passes an error will be returned 61 | AcknowledgeTimeoutInSec = 60 62 | 63 | # This flag defines the marshaller type. Currently supported: "json", "gogo protobuf" 64 | MarshallerType = "json" 65 | 66 | # The number of seconds when the client will try again to send the data 67 | RetryDurationInSec = 5 68 | 69 | # Sets if, in case of data payload processing error, we should block or not the advancement to the next processing event. Set this to true if you wish the node to stop processing blocks if the client/server encounters errors while processing requests. 70 | BlockingAckOnError = true 71 | 72 | # Set to true to drop messages if there is no active WebSocket connection to send to. 73 | DropMessagesIfNoConnection = false 74 | 75 | # Defines the payload version. Version will be changed when there are breaking 76 | # changes on payload data. The receiver/consumer will have to know how to handle different 77 | # versions. The version will be sent as metadata in the websocket message. 78 | Version = 1 -------------------------------------------------------------------------------- /config/mainnet/0-observingSquad/elrond-nodes/node-1/external.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | # ElasticSearchConnector defines settings related to ElasticSearch such as login information or URL 3 | [ElasticSearchConnector] 4 | ## We do not recommend to activate this indexer on a validator node since 5 | #the node might loose rating (even facing penalties) due to the fact that 6 | #the indexer is called synchronously and might block due to external causes. 7 | #Strongly suggested to activate this on a regular observer node. 8 | Enabled = false 9 | IndexerCacheSize = 0 10 | BulkRequestMaxSizeInBytes = 4194304 # 4MB 11 | URL = "http://localhost:9200" 12 | UseKibana = false 13 | Username = "" 14 | Password = "" 15 | # EnabledIndexes represents a slice of indexes that will be enabled for indexing. Full list is: 16 | # ["rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", "logs", "delegators", "operations", "esdts"] 17 | EnabledIndexes = ["rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", "logs", "delegators", "operations", "esdts"] 18 | 19 | # EventNotifierConnector defines settings needed to configure and launch the event notifier component 20 | # HTTP event notifier connector integration will be DEPRECATED in the following iterations 21 | [EventNotifierConnector] 22 | # Enabled will turn on or off the event notifier connector 23 | Enabled = false 24 | 25 | # UseAuthorization signals the proxy to use authorization 26 | # Never run a production setup without authorization 27 | UseAuthorization = false 28 | 29 | # ProxyUrl is used to communicate with the subscriptions hub 30 | # The indexer instance will broadcast data using ProxyUrl 31 | ProxyUrl = "http://localhost:5000" 32 | 33 | # Username and Password need to be specified if UseAuthorization is set to true 34 | Username = "" 35 | 36 | # Password is used to authorize an observer to push event data 37 | Password = "" 38 | 39 | # RequestTimeoutSec defines the timeout in seconds for the http client 40 | RequestTimeoutSec = 60 41 | 42 | # MarshallerType is used to define the marshaller type to be used for inner 43 | # marshalled structures in block events data 44 | MarshallerType = "json" 45 | 46 | [[HostDriversConfig]] 47 | # This flag shall only be used for observer nodes 48 | Enabled = true 49 | 50 | # This flag will start the WebSocket connector as server or client (can be "client" or "server") 51 | Mode = "client" 52 | 53 | # URL for the WebSocket client/server connection 54 | # This value represents the IP address and port number that the WebSocket client or server will use to establish a connection. 55 | URL = "ws://127.0.0.1:22111" 56 | 57 | # After a message will be sent it will wait for an ack message if this flag is enabled 58 | WithAcknowledge = true 59 | 60 | # The duration in seconds to wait for an acknowledgment message, after this time passes an error will be returned 61 | AcknowledgeTimeoutInSec = 60 62 | 63 | # This flag defines the marshaller type. Currently supported: "json", "gogo protobuf" 64 | MarshallerType = "json" 65 | 66 | # The number of seconds when the client will try again to send the data 67 | RetryDurationInSec = 5 68 | 69 | # Sets if, in case of data payload processing error, we should block or not the advancement to the next processing event. Set this to true if you wish the node to stop processing blocks if the client/server encounters errors while processing requests. 70 | BlockingAckOnError = true 71 | 72 | # Set to true to drop messages if there is no active WebSocket connection to send to. 73 | DropMessagesIfNoConnection = false 74 | 75 | # Defines the payload version. Version will be changed when there are breaking 76 | # changes on payload data. The receiver/consumer will have to know how to handle different 77 | # versions. The version will be sent as metadata in the websocket message. 78 | Version = 1 -------------------------------------------------------------------------------- /config/mainnet/0-observingSquad/elrond-nodes/node-2/external.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | # ElasticSearchConnector defines settings related to ElasticSearch such as login information or URL 3 | [ElasticSearchConnector] 4 | ## We do not recommend to activate this indexer on a validator node since 5 | #the node might loose rating (even facing penalties) due to the fact that 6 | #the indexer is called synchronously and might block due to external causes. 7 | #Strongly suggested to activate this on a regular observer node. 8 | Enabled = false 9 | IndexerCacheSize = 0 10 | BulkRequestMaxSizeInBytes = 4194304 # 4MB 11 | URL = "http://localhost:9200" 12 | UseKibana = false 13 | Username = "" 14 | Password = "" 15 | # EnabledIndexes represents a slice of indexes that will be enabled for indexing. Full list is: 16 | # ["rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", "logs", "delegators", "operations", "esdts"] 17 | EnabledIndexes = ["rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", "logs", "delegators", "operations", "esdts"] 18 | 19 | # EventNotifierConnector defines settings needed to configure and launch the event notifier component 20 | # HTTP event notifier connector integration will be DEPRECATED in the following iterations 21 | [EventNotifierConnector] 22 | # Enabled will turn on or off the event notifier connector 23 | Enabled = false 24 | 25 | # UseAuthorization signals the proxy to use authorization 26 | # Never run a production setup without authorization 27 | UseAuthorization = false 28 | 29 | # ProxyUrl is used to communicate with the subscriptions hub 30 | # The indexer instance will broadcast data using ProxyUrl 31 | ProxyUrl = "http://localhost:5000" 32 | 33 | # Username and Password need to be specified if UseAuthorization is set to true 34 | Username = "" 35 | 36 | # Password is used to authorize an observer to push event data 37 | Password = "" 38 | 39 | # RequestTimeoutSec defines the timeout in seconds for the http client 40 | RequestTimeoutSec = 60 41 | 42 | # MarshallerType is used to define the marshaller type to be used for inner 43 | # marshalled structures in block events data 44 | MarshallerType = "json" 45 | 46 | [[HostDriversConfig]] 47 | # This flag shall only be used for observer nodes 48 | Enabled = true 49 | 50 | # This flag will start the WebSocket connector as server or client (can be "client" or "server") 51 | Mode = "client" 52 | 53 | # URL for the WebSocket client/server connection 54 | # This value represents the IP address and port number that the WebSocket client or server will use to establish a connection. 55 | URL = "ws://127.0.0.1:22111" 56 | 57 | # After a message will be sent it will wait for an ack message if this flag is enabled 58 | WithAcknowledge = true 59 | 60 | # The duration in seconds to wait for an acknowledgment message, after this time passes an error will be returned 61 | AcknowledgeTimeoutInSec = 60 62 | 63 | # This flag defines the marshaller type. Currently supported: "json", "gogo protobuf" 64 | MarshallerType = "json" 65 | 66 | # The number of seconds when the client will try again to send the data 67 | RetryDurationInSec = 5 68 | 69 | # Sets if, in case of data payload processing error, we should block or not the advancement to the next processing event. Set this to true if you wish the node to stop processing blocks if the client/server encounters errors while processing requests. 70 | BlockingAckOnError = true 71 | 72 | # Set to true to drop messages if there is no active WebSocket connection to send to. 73 | DropMessagesIfNoConnection = false 74 | 75 | # Defines the payload version. Version will be changed when there are breaking 76 | # changes on payload data. The receiver/consumer will have to know how to handle different 77 | # versions. The version will be sent as metadata in the websocket message. 78 | Version = 1 -------------------------------------------------------------------------------- /config/mainnet/0-observingSquad/elrond-nodes/node-3/external.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | # ElasticSearchConnector defines settings related to ElasticSearch such as login information or URL 3 | [ElasticSearchConnector] 4 | ## We do not recommend to activate this indexer on a validator node since 5 | #the node might loose rating (even facing penalties) due to the fact that 6 | #the indexer is called synchronously and might block due to external causes. 7 | #Strongly suggested to activate this on a regular observer node. 8 | Enabled = false 9 | IndexerCacheSize = 0 10 | BulkRequestMaxSizeInBytes = 4194304 # 4MB 11 | URL = "http://localhost:9200" 12 | UseKibana = false 13 | Username = "" 14 | Password = "" 15 | # EnabledIndexes represents a slice of indexes that will be enabled for indexing. Full list is: 16 | # ["rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", "logs", "delegators", "operations", "esdts"] 17 | EnabledIndexes = ["rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", "logs", "delegators", "operations", "esdts"] 18 | 19 | # EventNotifierConnector defines settings needed to configure and launch the event notifier component 20 | # HTTP event notifier connector integration will be DEPRECATED in the following iterations 21 | [EventNotifierConnector] 22 | # Enabled will turn on or off the event notifier connector 23 | Enabled = false 24 | 25 | # UseAuthorization signals the proxy to use authorization 26 | # Never run a production setup without authorization 27 | UseAuthorization = false 28 | 29 | # ProxyUrl is used to communicate with the subscriptions hub 30 | # The indexer instance will broadcast data using ProxyUrl 31 | ProxyUrl = "http://localhost:5000" 32 | 33 | # Username and Password need to be specified if UseAuthorization is set to true 34 | Username = "" 35 | 36 | # Password is used to authorize an observer to push event data 37 | Password = "" 38 | 39 | # RequestTimeoutSec defines the timeout in seconds for the http client 40 | RequestTimeoutSec = 60 41 | 42 | # MarshallerType is used to define the marshaller type to be used for inner 43 | # marshalled structures in block events data 44 | MarshallerType = "json" 45 | 46 | [[HostDriversConfig]] 47 | # This flag shall only be used for observer nodes 48 | Enabled = true 49 | 50 | # This flag will start the WebSocket connector as server or client (can be "client" or "server") 51 | Mode = "client" 52 | 53 | # URL for the WebSocket client/server connection 54 | # This value represents the IP address and port number that the WebSocket client or server will use to establish a connection. 55 | URL = "ws://127.0.0.1:22111" 56 | 57 | # After a message will be sent it will wait for an ack message if this flag is enabled 58 | WithAcknowledge = true 59 | 60 | # The duration in seconds to wait for an acknowledgment message, after this time passes an error will be returned 61 | AcknowledgeTimeoutInSec = 60 62 | 63 | # This flag defines the marshaller type. Currently supported: "json", "gogo protobuf" 64 | MarshallerType = "json" 65 | 66 | # The number of seconds when the client will try again to send the data 67 | RetryDurationInSec = 5 68 | 69 | # Sets if, in case of data payload processing error, we should block or not the advancement to the next processing event. Set this to true if you wish the node to stop processing blocks if the client/server encounters errors while processing requests. 70 | BlockingAckOnError = true 71 | 72 | # Set to true to drop messages if there is no active WebSocket connection to send to. 73 | DropMessagesIfNoConnection = false 74 | 75 | # Defines the payload version. Version will be changed when there are breaking 76 | # changes on payload data. The receiver/consumer will have to know how to handle different 77 | # versions. The version will be sent as metadata in the websocket message. 78 | Version = 1 -------------------------------------------------------------------------------- /scripts/2-observing-squad.sh: -------------------------------------------------------------------------------- 1 | # --------------------------------------------------------- 2 | # Observing Squad Installation Functions 3 | # Official Link: https://docs.multiversx.com/integrators/observing-squad 4 | # --------------------------------------------------------- 5 | 6 | # Prepare the Observing Squad Environment 7 | ObsSquad_Prepare_Environment() { 8 | Log-Step "Prepare Observing Squad Environment" 9 | 10 | local repo_dir="$HOME/mx-chain-scripts" 11 | local config_file="$repo_dir/config/variables.cfg" 12 | 13 | if [ ! -d "$repo_dir" ]; then 14 | Log-SubStep "Clone the MultiversX chain scripts repository" 15 | git clone https://github.com/multiversx/mx-chain-scripts.git "$repo_dir" 16 | else 17 | Log "Repository already cloned. Skipping clone step." 18 | fi 19 | 20 | Log-SubStep "Replace variables in the configuration file (variables.cfg)." 21 | if [ ! -f "$config_file" ]; then 22 | Log-Error "Configuration file $config_file not found. Exiting." 23 | return 1 24 | fi 25 | 26 | sed -i "s/^ENVIRONMENT=\".*\"/ENVIRONMENT=\"$NETWORK\"/" "$config_file" 27 | sed -i "s|^CUSTOM_HOME=.*|CUSTOM_HOME=\"$HOME\"|" "$config_file" 28 | sed -i "s/^CUSTOM_USER=.*$/CUSTOM_USER=\"$USERNAME\"/" "$config_file" 29 | 30 | } 31 | 32 | # Function that install the observing squad and press enter to all the questions 33 | ObsSquad_Install() { 34 | Log-Step "Install Observing Squad" 35 | 36 | local script_dir="$HOME/mx-chain-scripts" 37 | local script_file="$script_dir/script.sh" 38 | 39 | # Verify the directory exists 40 | if [ ! -d "$script_dir" ]; then 41 | Log-Error "Directory $script_dir does not exist. Clone the repository first." 42 | return 1 43 | fi 44 | 45 | # Verify the script file exists 46 | if [ ! -f "$script_file" ]; then 47 | Log-Error "Script file $script_file does not exist." 48 | return 1 49 | fi 50 | 51 | # Run the script and automatically approve prompts 52 | yes "" | "$script_file" observing_squad 53 | if [ $? -eq 0 ]; then 54 | Log "Observing Squad installation completed successfully." 55 | else 56 | Log-Error "Observing Squad installation failed." 57 | return 1 58 | fi 59 | 60 | # Link Go to the PATH 61 | Log-SubStep "Link installed Go to the PATH" 62 | echo 'export PATH=$PATH:/usr/local/go/bin' >>~/.bashrc 63 | export PATH=$PATH:/usr/local/go/bin 64 | } 65 | 66 | # Function to copy the external.toml and prefs.toml files to the different node folders 67 | ObsSquad_Copy_Configuration() { 68 | Log-Step "Overwrite node configurations into ~/elrond-nodes/node-[0,1,2,3]/config" 69 | 70 | # Define the source directory for configuration files 71 | local config_source_dir="$HOME/mvx-api-deployer/config/$NETWORK/0-observingSquad/elrond-nodes" 72 | 73 | # Verify if the source directory exists 74 | if [ ! -d "$config_source_dir" ]; then 75 | Log-Error "Source configuration directory $config_source_dir does not exist." 76 | return 1 77 | fi 78 | 79 | # Define the destination directory for node configurations 80 | local node_base_dir="$HOME/elrond-nodes" 81 | 82 | # Iterate through each node directory 83 | for node_index in {0..3}; do 84 | local node_dir="$node_base_dir/node-$node_index/config" 85 | local external_file_source="$config_source_dir/node-$node_index/external.toml" 86 | local prefs_file_source="$config_source_dir/node-$node_index/prefs.toml" 87 | 88 | # Check if the node directory exists 89 | if [ ! -d "$node_dir" ]; then 90 | Log-Warning "Node directory $node_dir does not exist. Skipping." 91 | continue 92 | fi 93 | 94 | # Overwrite external.toml 95 | if [ -f "$external_file_source" ]; then 96 | cp "$external_file_source" "$node_dir/" 97 | Log-SubStep "Copied external.toml to $node_dir" 98 | else 99 | Log-Warning "external.toml not found for node-$node_index. Skipping." 100 | fi 101 | 102 | # Overwrite prefs.toml 103 | if [ -f "$prefs_file_source" ]; then 104 | cp "$prefs_file_source" "$node_dir/" 105 | Log-SubStep "Copied prefs.toml to $node_dir" 106 | else 107 | Log-Warning "prefs.toml not found for node-$node_index. Skipping." 108 | fi 109 | done 110 | 111 | Log "Node configurations successfully updated." 112 | } 113 | -------------------------------------------------------------------------------- /scripts/5-mx-api.sh: -------------------------------------------------------------------------------- 1 | # --------------------------------------------------------- 2 | # MultiversX API Service Installation Functions 3 | # Official Link: https://docs.multiversx.com/sdk-and-tools/rest-api/multiversx-api 4 | # --------------------------------------------------------- 5 | 6 | # Function to prepare the MultiversX API environment 7 | MxApi_Prepare_Environment() { 8 | Log-Step "Prepare MultiversX API Environment" 9 | 10 | local repo_url="https://github.com/multiversx/mx-api-service.git" 11 | local repo_dir="$HOME/mx-api-service" 12 | 13 | # Clone the MultiversX API repository if it doesn't exist 14 | if [ ! -d "$repo_dir" ]; then 15 | Log-SubStep "Clone MultiversX API Repository" 16 | git clone "$repo_url" "$repo_dir" || { 17 | Log-Error "Failed to clone MultiversX API repository." 18 | return 1 19 | } 20 | Log "Repository cloned successfully." 21 | else 22 | Log-Warning "Repository already exists at $repo_dir. Skipping clone step." 23 | fi 24 | } 25 | 26 | # Function to install npm if not already installed 27 | # MxApi_Install_Npm() { 28 | # Log-Step "Install Npm" 29 | 30 | # if ! command -v npm &>/dev/null; then 31 | # Log-SubStep "Install Npm Package Manager" 32 | # sudo apt update && sudo apt install npm -y || { 33 | # Log-Error "Npm installation failed. Please check your network or package manager settings." 34 | # return 1 35 | # } 36 | # Log "Npm installed successfully." 37 | # else 38 | # Log "Npm is already installed. Skipping installation." 39 | # fi 40 | # } 41 | 42 | # Function to install dependencies for the MultiversX API 43 | MxApi_Install_Dependencies() { 44 | Log-Step "Install MultiversX API Dependencies" 45 | 46 | local repo_dir="$HOME/mx-api-service" 47 | 48 | if [ -d "$repo_dir" ]; then 49 | cd "$repo_dir" || { 50 | Log-Error "Failed to navigate to $repo_dir." 51 | return 1 52 | } 53 | Log "Installing dependencies using Npm" 54 | npm install || { 55 | Log-Error "Failed to install dependencies. Check the npm logs for more information." 56 | return 1 57 | } 58 | Log "Dependencies installed successfully." 59 | else 60 | Log-Error "Repository directory $repo_dir does not exist. Ensure the repository was cloned correctly." 61 | return 1 62 | fi 63 | } 64 | 65 | # Function to initialize the MultiversX API 66 | MxApi_Initialize() { 67 | Log-Step "Initialize MultiversX API Plugin Structure" 68 | 69 | local repo_dir="$HOME/mx-api-service" 70 | 71 | if [ -d "$repo_dir" ]; then 72 | cd "$repo_dir" || { 73 | Log-Error "Failed to navigate to $repo_dir." 74 | return 1 75 | } 76 | Log "Initializing the default plugin structure" 77 | npm run init || { 78 | Log-Error "Failed to initialize the default plugin structure. Check the npm logs for more information." 79 | return 1 80 | } 81 | Log "Default plugin structure initialized successfully." 82 | else 83 | Log-Error "Repository directory $repo_dir does not exist. Ensure the repository was cloned correctly." 84 | return 1 85 | fi 86 | ## Run docker-compose up -d 87 | Log-SubStep "Run docker-compose up -d" 88 | sudo docker compose up -d 89 | } 90 | 91 | MxApi_Copy_Configuration() { 92 | Log-Step "Copy MultiversX API Configuration" 93 | 94 | local source_dir="$HOME/mvx-api-deployer/config/$NETWORK/3-mx-api-service" 95 | local repo_dir="$HOME/mx-api-service" 96 | 97 | Log-SubStep "Copy docker-compose.yml file" 98 | cp -f "$source_dir/docker-compose.yml" "$repo_dir/docker-compose.yml" || { 99 | Log-Error "Failed to copy docker-compose.yml file." 100 | return 1 101 | } 102 | 103 | Log-SubStep "Copy config.yaml file" 104 | cp -f "$source_dir/config.yaml" "$repo_dir/config/config.yaml" || { 105 | Log-Error "Failed to copy config.yaml file." 106 | return 1 107 | } 108 | 109 | Log "MultiversX API configuration files copied successfully." 110 | } 111 | 112 | MxApi_Create_Service() { 113 | Log-Step "Create MultiversX API Service" 114 | 115 | local service_file="/etc/systemd/system/mvx-api.service" 116 | 117 | Log-SubStep "Copy MultiversX API service file" 118 | sudo cp "$HOME/mvx-api-deployer/config/$NETWORK/3-mx-api-service/mvx-api.service" "$service_file" || { 119 | Log-Error "Failed to copy MultiversX API service file." 120 | return 1 121 | } 122 | 123 | Log-SubStep "Enable MultiversX API service" 124 | sudo systemctl daemon-reload 125 | sudo systemctl enable mvx-api.service || { 126 | Log-Error "Failed to enable MultiversX API service." 127 | return 1 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /config/devnet/3-mx-api-service/config.yaml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | network: "devnet" 3 | metaChainShardId: 4294967295 4 | api: 5 | public: true 6 | publicPort: 3001 7 | private: true 8 | privatePort: 4001 9 | websocket: true 10 | cron: 11 | cacheWarmer: true 12 | fastWarm: true 13 | queueWorker: true 14 | elasticUpdater: false 15 | flags: 16 | useRequestCaching: true 17 | useKeepAliveAgent: true 18 | useTracing: false 19 | useRequestLogging: false 20 | useVmQueryTracing: false 21 | processNfts: true 22 | collectionPropertiesFromGateway: false 23 | features: 24 | eventsNotifier: 25 | enabled: false 26 | port: 5674 27 | url: "amqp://guest:guest@127.0.0.1:5673" 28 | exchange: "all_events" 29 | queue: "api-process-logs-and-events" 30 | guestCaching: 31 | enabled: false 32 | hitsThreshold: 100 33 | ttl: 12 34 | transactionPool: 35 | enabled: false 36 | transactionPoolWarmer: 37 | enabled: false 38 | cronExpression: "*/5 * * * * *" 39 | ttlInSeconds: 60 40 | updateCollectionExtraDetails: 41 | enabled: false 42 | updateAccountExtraDetails: 43 | enabled: false 44 | marketplace: 45 | enabled: false 46 | serviceUrl: "https://devnet-nfts-graph.multiversx.com/graphql" 47 | exchange: 48 | enabled: true 49 | serviceUrl: "http://localhost:3005/graphql" 50 | dataApi: 51 | enabled: false 52 | serviceUrl: "https://devnet-data-api.multiversx.com" 53 | assetsFetch: 54 | enabled: true 55 | assetesUrl: "https://tools.multiversx.com/assets-cdn" 56 | auth: 57 | enabled: false 58 | maxExpirySeconds: 86400 59 | acceptedOrigins: 60 | - "" 61 | admins: 62 | - "" 63 | jwtSecret: "" 64 | stakingV4: 65 | enabled: false 66 | cronExpression: "*/5 * * * * *" 67 | activationEpoch: 1043 68 | nodeEpochsLeft: 69 | enabled: false 70 | transactionProcessor: 71 | enabled: false 72 | maxLookBehind: 100 73 | transactionCompleted: 74 | enabled: false 75 | maxLookBehind: 100 76 | logLevel: "Error" 77 | transactionBatch: 78 | enabled: true 79 | maxLookBehind: 100 80 | statusChecker: 81 | enabled: false 82 | thresholds: 83 | tokens: 500 84 | nodes: 3000 85 | providers: 10 86 | tokenSupplyCount: 20 87 | tokenAssets: 20 88 | tokenAccounts: 500 89 | tokenTransactions: 500 90 | nodeValidators: 300 91 | nftScamInfo: 92 | enabled: false 93 | processNfts: 94 | enabled: false 95 | nftQueueName: "api-process-nfts" 96 | deadLetterQueueName: "api-process-nfts-dlq" 97 | tps: 98 | enabled: false 99 | maxLookBehindNonces: 100 100 | nodesFetch: 101 | enabled: true 102 | serviceUrl: "https://devnet-api.multiversx.com" 103 | tokensFetch: 104 | enabled: true 105 | serviceUrl: "https://devnet-api.multiversx.com" 106 | providersFetch: 107 | enabled: true 108 | serviceUrl: "https://devnet-api.multiversx.com" 109 | image: 110 | width: 600 111 | height: 600 112 | type: "png" 113 | aws: 114 | s3KeyId: "" 115 | s3Secret: "" 116 | s3Bucket: "devnet-media.elrond.com" 117 | s3Region: "" 118 | urls: 119 | self: "https://devnet-api.multiversx.com" 120 | elastic: 121 | - "http://localhost:9200" 122 | gateway: 123 | - "http://localhost:8079" 124 | verifier: "https://play-api.multiversx.com" 125 | redis: "127.0.0.1" 126 | rabbitmq: "amqp://127.0.0.1:5672" 127 | providers: "https://devnet-delegation-api.multiversx.com/providers" 128 | delegation: "https://devnet-delegation-api.multiversx.com" 129 | media: "https://devnet-media.elrond.com" 130 | nftThumbnails: "https://devnet-media.elrond.com/nfts/thumbnail" 131 | tmp: "/tmp" 132 | ipfs: "https://ipfs.io/ipfs" 133 | socket: "devnet-socket-api.multiversx.com" 134 | maiarId: "https://devnet-id-api.multiversx.com" 135 | indexer: 136 | type: "elastic" 137 | maxPagination: 10000 138 | database: 139 | enabled: false 140 | url: "mongodb://127.0.0.1:27017/api?authSource=admin" 141 | type: "mysql" 142 | host: "localhost" 143 | port: 3306 144 | username: "root" 145 | password: "root" 146 | database: "api" 147 | caching: 148 | cacheTtl: 6 149 | processTtl: 600 150 | poolLimit: 50 151 | cacheDuration: 3 152 | keepAliveTimeout: 153 | downstream: 61000 154 | upstream: 60000 155 | contracts: 156 | esdt: "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u" 157 | auction: "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqplllst77y4l" 158 | staking: "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqllls0lczs7" 159 | delegationManager: "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqylllslmq6y6" 160 | delegation: "erd1qqqqqqqqqqqqqpgq97wezxw6l7lgg7k9rxvycrz66vn92ksh2tssxwf7ep" 161 | metabonding: "erd1qqqqqqqqqqqqqpgqkg7we73j769ew5we4yyx7uyvnn0nefqgd8ssm6vjc2" 162 | inflation: 163 | - 1952123 164 | - 1746637 165 | - 1541150 166 | - 1335663 167 | - 1130177 168 | - 924690 169 | - 719203 170 | nftProcess: 171 | parallelism: 1 172 | maxRetries: 3 173 | -------------------------------------------------------------------------------- /scripts/3-es-indexer.sh: -------------------------------------------------------------------------------- 1 | # --------------------------------------------------------- 2 | # ElasticSearch Indexer Installation Functions 3 | # Official Link: https://docs.multiversx.com/sdk-and-tools/indexer/#observer-client 4 | # --------------------------------------------------------- 5 | 6 | # Prepare the environment for the ElasticSearch Indexer 7 | EsIndexer_Prepare_Environment() { 8 | Log-Step "Prepare ElasticSearch Indexer Environment" 9 | 10 | local repo_url="https://github.com/multiversx/mx-chain-es-indexer-go.git" 11 | local repo_dir="$HOME/mx-chain-es-indexer-go" 12 | 13 | # Clone the repository if it doesn't exist 14 | if [ ! -d "$repo_dir" ]; then 15 | Log-SubStep "Clone ElasticSearch Indexer Repository" 16 | Log "Cloning repository from $repo_url into $repo_dir" 17 | git clone "$repo_url" "$repo_dir" || { 18 | Log-Error "Failed to clone the ElasticSearch Indexer repository. Check your network connection." 19 | return 1 20 | } 21 | Log "Repository cloned successfully." 22 | else 23 | Log-Warning "Repository already exists at $repo_dir. Skipping clone step." 24 | fi 25 | 26 | } 27 | 28 | EsIndexer_Copy_Configuration() { 29 | Log-Step "Copy ElasticSearch Indexer Configuration" 30 | 31 | local source_dir="$HOME/mvx-api-deployer/config/$NETWORK/1-mx-chain-es-indexer-go" 32 | local repo_dir="$HOME/mx-chain-es-indexer-go" 33 | 34 | Log-SubStep "Copy docker compose file" 35 | cp -f "$source_dir/docker-compose.yml" "$repo_dir/docker-compose.yml" || { 36 | Log-Error "Failed to copy docker compose file." 37 | return 1 38 | } 39 | 40 | Log-SubStep "Copy ElasticSearch Indexer service configuration files" 41 | cp -f "$source_dir/cmd/elasticindexer/api.toml" "$repo_dir/cmd/elasticindexer/config/api.toml" || { 42 | Log-Error "Failed to copy ElasticSearch Indexer service configuration files." 43 | return 1 44 | } 45 | cp -f "$source_dir/cmd/elasticindexer/config.toml" "$repo_dir/cmd/elasticindexer/config/config.toml" || { 46 | Log-Error "Failed to copy ElasticSearch Indexer service configuration files." 47 | return 1 48 | } 49 | cp -f "$source_dir/cmd/elasticindexer/prefs.toml" "$repo_dir/cmd/elasticindexer/config/prefs.toml" || { 50 | Log-Error "Failed to copy ElasticSearch Indexer service configuration files." 51 | return 1 52 | } 53 | Log "ElasticSearch Indexer configuration files copied successfully." 54 | } 55 | 56 | # Build and configure the ElasticSearch Indexer 57 | EsIndexer_Build() { 58 | Log-Step "Build ElasticSearch Indexer" 59 | 60 | local repo_dir="$HOME/mx-chain-es-indexer-go" 61 | local cmd_dir="$repo_dir/cmd/elasticindexer" 62 | 63 | Log "Pull the docker images" 64 | cd "$repo_dir" && sudo docker compose pull 65 | # Verify the command directory exists 66 | if [ ! -d "$cmd_dir" ]; then 67 | Log-Error "Directory $cmd_dir does not exist. Ensure the repository was cloned correctly." 68 | return 1 69 | fi 70 | 71 | cd "$cmd_dir" || { 72 | Log-Error "Failed to navigate to $cmd_dir." 73 | return 1 74 | } 75 | Log "Navigated to $cmd_dir" 76 | 77 | # Build the ElasticSearch Indexer executable 78 | Log-SubStep "Compile ElasticSearch Indexer Executable" 79 | go install || { 80 | Log-Error "Failed to install Go dependencies for ElasticSearch Indexer." 81 | return 1 82 | } 83 | go build -o elasticindexer || { 84 | Log-Error "Failed to build ElasticSearch Indexer executable." 85 | return 1 86 | } 87 | 88 | Log "ElasticSearch Indexer executable built successfully." 89 | } 90 | 91 | # Enable the systemd service for ElasticSearch Indexer 92 | EsIndexer_Create_Service() { 93 | Log-Step "Enable Systemd Service for ElasticSearch Indexer" 94 | 95 | local service_file="/etc/systemd/system/mvx-elasticindexer.service" 96 | 97 | Log-SubStep "Copy ElasticSearch Indexer Service File" 98 | sudo cp "$HOME/mvx-api-deployer/config/$NETWORK/1-mx-chain-es-indexer-go/mvx-elasticindexer.service" "$service_file" || { 99 | Log-Error "Failed to copy ElasticSearch Indexer service file." 100 | return 1 101 | } 102 | 103 | Log-SubStep "Enable ElasticSearch Indexer Service" 104 | sudo systemctl daemon-reload 105 | sudo systemctl enable mvx-elasticindexer || { 106 | Log-Error "Failed to enable ElasticSearch Indexer service." 107 | return 1 108 | } 109 | # sudo systemctl start mvx-elasticindexer || { 110 | # Log-Error "Failed to start ElasticSearch Indexer service." 111 | # return 1 112 | # } 113 | 114 | # Verify the service is running 115 | # sudo systemctl status mvx-elasticindexer --no-pager || { 116 | # Log-Error "ElasticSearch Indexer service failed to start. Check logs with 'journalctl -u mvx-elasticindexer'." 117 | # return 1 118 | # } 119 | 120 | Log "ElasticSearch Indexer systemd service configured and enabled." 121 | } 122 | -------------------------------------------------------------------------------- /config/mainnet/3-mx-api-service/config.yaml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | network: "mainnet" 3 | metaChainShardId: 4294967295 4 | api: 5 | public: true 6 | publicPort: 3001 7 | private: true 8 | privatePort: 4001 9 | websocket: true 10 | cron: 11 | cacheWarmer: true 12 | fastWarm: false 13 | queueWorker: true 14 | elasticUpdater: false 15 | flags: 16 | useRequestCaching: true 17 | useKeepAliveAgent: true 18 | useTracing: false 19 | useRequestLogging: false 20 | useVmQueryTracing: false 21 | processNfts: true 22 | collectionPropertiesFromGateway: false 23 | features: 24 | eventsNotifier: 25 | enabled: false 26 | port: 5674 27 | url: "amqp://guest:guest@127.0.0.1:5673" 28 | exchange: "all_events" 29 | queue: "api-process-logs-and-events" 30 | guestCaching: 31 | enabled: false 32 | hitsThreshold: 100 33 | ttl: 12 34 | transactionPool: 35 | enabled: false 36 | transactionPoolWarmer: 37 | enabled: false 38 | cronExpression: "*/5 * * * * *" 39 | ttlInSeconds: 60 40 | updateCollectionExtraDetails: 41 | enabled: false 42 | updateAccountExtraDetails: 43 | enabled: false 44 | transfersLast24hUrl: "https://tools.multiversx.com/growth-api/explorer/widgets/most-used/applications" 45 | marketplace: 46 | enabled: false 47 | serviceUrl: "https://nfts-graph.multiversx.com/graphql" 48 | exchange: 49 | enabled: true 50 | serviceUrl: "http://localhost:3005/graphql" 51 | dataApi: 52 | enabled: false 53 | serviceUrl: "https://data-api.multiversx.com" 54 | auth: 55 | enabled: false 56 | maxExpirySeconds: 86400 57 | acceptedOrigins: 58 | - "" 59 | admins: 60 | - "" 61 | jwtSecret: "" 62 | stakingV4: 63 | enabled: false 64 | cronExpression: "*/5 * * * * *" 65 | activationEpoch: 1391 66 | nodeEpochsLeft: 67 | enabled: false 68 | transactionProcessor: 69 | enabled: false 70 | maxLookBehind: 1000 71 | transactionCompleted: 72 | enabled: false 73 | maxLookBehind: 1000 74 | logLevel: "Error" 75 | transactionBatch: 76 | enabled: false 77 | maxLookBehind: 1000 78 | deepHistory: 79 | enabled: false 80 | url: "" 81 | statusChecker: 82 | enabled: false 83 | thresholds: 84 | tokens: 1000 85 | nodes: 5000 86 | providers: 150 87 | tokenSupplyCount: 100 88 | tokenAssets: 100 89 | tokenAccounts: 1000 90 | tokenTransactions: 1000 91 | nodeValidators: 3260 92 | nftScamInfo: 93 | enabled: false 94 | processNfts: 95 | enabled: false 96 | nftQueueName: "api-process-nfts" 97 | deadLetterQueueName: "api-process-nfts-dlq" 98 | tps: 99 | enabled: false 100 | maxLookBehindNonces: 100 101 | nodesFetch: 102 | enabled: true 103 | serviceUrl: "https://api.multiversx.com" 104 | tokensFetch: 105 | enabled: true 106 | serviceUrl: "https://api.multiversx.com" 107 | providersFetch: 108 | enabled: true 109 | serviceUrl: "https://api.multiversx.com" 110 | assetsFetch: 111 | enabled: true 112 | assetesUrl: "https://tools.multiversx.com/assets-cdn" 113 | image: 114 | width: 600 115 | height: 600 116 | type: "png" 117 | aws: 118 | s3KeyId: "" 119 | s3Secret: "" 120 | s3Bucket: "media.elrond.com" 121 | s3Region: "" 122 | urls: 123 | self: "https://api.multiversx.com" 124 | elastic: 125 | - "http://localhost:9200" 126 | gateway: 127 | - "http://localhost:8079" 128 | verifier: "https://play-api.multiversx.com" 129 | redis: "127.0.0.1" 130 | rabbitmq: "amqp://127.0.0.1:5672" 131 | providers: "https://delegation-api.multiversx.com/providers" 132 | delegation: "https://delegation-api.multiversx.com" 133 | media: "https://media.elrond.com" 134 | nftThumbnails: "https://media.elrond.com/nfts/thumbnail" 135 | tmp: "/tmp" 136 | ipfs: "https://ipfs.io/ipfs" 137 | socket: "socket-api-fra.multiversx.com" 138 | maiarId: "https://id-api.multiversx.com" 139 | indexer: 140 | type: "elastic" 141 | maxPagination: 10000 142 | database: 143 | enabled: false 144 | url: "mongodb://127.0.0.1:27017/api?authSource=admin" 145 | type: "mysql" 146 | host: "localhost" 147 | port: 3306 148 | username: "root" 149 | password: "root" 150 | database: "api" 151 | caching: 152 | cacheTtl: 6 153 | processTtl: 600 154 | poolLimit: 50 155 | cacheDuration: 3 156 | keepAliveTimeout: 157 | downstream: 61000 158 | upstream: 60000 159 | contracts: 160 | esdt: "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u" 161 | auction: "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqplllst77y4l" 162 | staking: "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqllls0lczs7" 163 | delegationManager: "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqylllslmq6y6" 164 | delegation: "erd1qqqqqqqqqqqqqpgqxwakt2g7u9atsnr03gqcgmhcv38pt7mkd94q6shuwt" 165 | metabonding: "erd1qqqqqqqqqqqqqpgq50dge6rrpcra4tp9hl57jl0893a4r2r72jpsk39rjj" 166 | inflation: 167 | - 1952123 168 | - 1746637 169 | - 1541150 170 | - 1335663 171 | - 1130177 172 | - 924690 173 | - 719203 174 | nftProcess: 175 | parallelism: 1 176 | maxRetries: 3 177 | -------------------------------------------------------------------------------- /config/devnet/0-observingSquad/elrond-nodes/node-0/prefs.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | [Preferences] 3 | # DestinationShardAsObserver represents the desired shard when running as observer 4 | # value will be given as string. For example: "0", "1", "15", "metachain" 5 | # if "disabled" is provided then the node will start in the corresponding shard for its public key or 0 otherwise 6 | DestinationShardAsObserver = "0" 7 | 8 | # NodeDisplayName represents the friendly name a user can pick for his node in the status monitor when the node does not run in multikey mode 9 | # In multikey mode, all bls keys not mentioned in NamedIdentity section will use this one as default 10 | NodeDisplayName = "node-observer-0" 11 | 12 | # Identity represents the GitHub identity when the node does not run in multikey mode 13 | # In multikey mode, all bls keys not mentioned in NamedIdentity section will use this one as default 14 | Identity = "" 15 | 16 | # RedundancyLevel represents the level of redundancy used by the node (-1 = disabled, 0 = main instance (default), 17 | # 1 = first backup, 2 = second backup, etc.) 18 | RedundancyLevel = 0 19 | 20 | # FullArchive, if enabled, will make the node able to respond to requests from past, old epochs. 21 | # It is highly recommended to enable this flag on an observer (not on a validator node) 22 | FullArchive = false 23 | 24 | # PreferredConnections holds an array containing valid ips or peer ids from nodes to connect with (in top of other connections) 25 | # Example: 26 | # PreferredConnections = [ 27 | # "127.0.0.10", 28 | # "16Uiu2HAm6yvbp1oZ6zjnWsn9FdRqBSaQkbhELyaThuq48ybdorrr" 29 | # ] 30 | PreferredConnections = [] 31 | 32 | # ConnectionWatcherType represents the type of the connection watcher needed. 33 | # possible options: 34 | # - "disabled" - no connection watching should be made 35 | # - "print" - new connection found will be printed in the log file 36 | ConnectionWatcherType = "disabled" 37 | 38 | # OverridableConfigTomlValues represents an array of items to be overloaded inside other configuration files, which can be helpful 39 | # so that certain config values need to remain the same during upgrades. 40 | # (for example, an Elasticsearch user wants external.toml->ElasticSearchConnector.Enabled to remain true all the time during upgrades, while the default 41 | # configuration of the node has the false value) 42 | # The Path indicates what value to change, while Value represents the new value. The node operator must make sure 43 | # to follow the same type of the original value (ex: uint32: 37, float32: 37.0, bool: true) 44 | # Also, the Value can be a struct (ex: { StartEpoch = 0, Version = "1.5" }) or an array (ex: [{ StartEpoch = 0, Version = "1.4" }, { StartEpoch = 1, Version = "1.5" }]) 45 | # File represents the file name that holds the configuration. Currently, the supported files are: 46 | # api.toml, config.toml, economics.toml, enableEpochs.toml, enableRounds.toml, external.toml, fullArchiveP2P.toml, p2p.toml, ratings.toml, systemSmartContractsConfig.toml 47 | # ------------------------------- 48 | # Un-comment and update the following section in order to enable config values overloading 49 | # ------------------------------- 50 | OverridableConfigTomlValues = [ 51 | { File = "config.toml", Path = "WebServerAntiflood.WebServerAntifloodEnabled", Value = false }, 52 | { File = "config.toml", Path = "WebServerAntiflood.TrieOperationsDeadlineMilliseconds", Value = 120000 }, 53 | { File = "config.toml", Path = "Antiflood.Enabled", Value = false }, 54 | { File = "config.toml", Path = "DbLookupExtensions.Enabled", Value = true }, 55 | { File = "config.toml", Path = "VirtualMachine.GasConfig.ShardMaxGasPerVmQuery", Value = 0 }, 56 | { File = "config.toml", Path = "VirtualMachine.Querying.TimeOutForSCExecutionInMilliseconds", Value = 100000 }, 57 | { File = "config.toml", Path = "VirtualMachine.Querying.NumConcurrentVMs", Value = 2 }, 58 | ] 59 | # BlockProcessingCutoff can be used to stop processing blocks at a certain round, nonce or epoch. 60 | # This can be useful for snapshotting different stuff and also for debugging purposes. 61 | [BlockProcessingCutoff] 62 | # If set to true, the node will stop at the given coordinate 63 | Enabled = false 64 | 65 | # Mode represents the cutoff mode. possible values: "pause" or "process-error". 66 | # "pause" mode will halt the processing at the block with the given coordinates. Useful for snapshots/analytics 67 | # "process-error" will return an error when processing the block with the given coordinates. Useful for debugging 68 | Mode = "pause" 69 | 70 | # CutoffTrigger represents the kind of coordinate to look after when cutting off the processing. 71 | # Possible values: "round", "nonce", or "epoch" 72 | CutoffTrigger = "round" 73 | 74 | # The minimum value of the cutoff. For example, if CutoffType is set to "round", and Value to 20, then the node will stop processing at round 20+ 75 | Value = 0 76 | 77 | # NamedIdentity represents an identity that runs nodes on the multikey 78 | # There can be multiple identities set on the same node, each one of them having different bls keys, just by duplicating the NamedIdentity 79 | [[NamedIdentity]] 80 | # Identity represents the GitHub identity for the current NamedIdentity 81 | Identity = "" 82 | # NodeName represents the name that will be given to the names of the current identity 83 | NodeName = "" 84 | # BLSKeys represents the BLS keys assigned to the current NamedIdentity 85 | BLSKeys = [ 86 | "", 87 | "" 88 | ] -------------------------------------------------------------------------------- /config/devnet/0-observingSquad/elrond-nodes/node-1/prefs.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | [Preferences] 3 | # DestinationShardAsObserver represents the desired shard when running as observer 4 | # value will be given as string. For example: "0", "1", "15", "metachain" 5 | # if "disabled" is provided then the node will start in the corresponding shard for its public key or 0 otherwise 6 | DestinationShardAsObserver = "1" 7 | 8 | # NodeDisplayName represents the friendly name a user can pick for his node in the status monitor when the node does not run in multikey mode 9 | # In multikey mode, all bls keys not mentioned in NamedIdentity section will use this one as default 10 | NodeDisplayName = "node-observer-1" 11 | 12 | # Identity represents the GitHub identity when the node does not run in multikey mode 13 | # In multikey mode, all bls keys not mentioned in NamedIdentity section will use this one as default 14 | Identity = "" 15 | 16 | # RedundancyLevel represents the level of redundancy used by the node (-1 = disabled, 0 = main instance (default), 17 | # 1 = first backup, 2 = second backup, etc.) 18 | RedundancyLevel = 0 19 | 20 | # FullArchive, if enabled, will make the node able to respond to requests from past, old epochs. 21 | # It is highly recommended to enable this flag on an observer (not on a validator node) 22 | FullArchive = false 23 | 24 | # PreferredConnections holds an array containing valid ips or peer ids from nodes to connect with (in top of other connections) 25 | # Example: 26 | # PreferredConnections = [ 27 | # "127.0.0.10", 28 | # "16Uiu2HAm6yvbp1oZ6zjnWsn9FdRqBSaQkbhELyaThuq48ybdorrr" 29 | # ] 30 | PreferredConnections = [] 31 | 32 | # ConnectionWatcherType represents the type of the connection watcher needed. 33 | # possible options: 34 | # - "disabled" - no connection watching should be made 35 | # - "print" - new connection found will be printed in the log file 36 | ConnectionWatcherType = "disabled" 37 | 38 | # OverridableConfigTomlValues represents an array of items to be overloaded inside other configuration files, which can be helpful 39 | # so that certain config values need to remain the same during upgrades. 40 | # (for example, an Elasticsearch user wants external.toml->ElasticSearchConnector.Enabled to remain true all the time during upgrades, while the default 41 | # configuration of the node has the false value) 42 | # The Path indicates what value to change, while Value represents the new value. The node operator must make sure 43 | # to follow the same type of the original value (ex: uint32: 37, float32: 37.0, bool: true) 44 | # Also, the Value can be a struct (ex: { StartEpoch = 0, Version = "1.5" }) or an array (ex: [{ StartEpoch = 0, Version = "1.4" }, { StartEpoch = 1, Version = "1.5" }]) 45 | # File represents the file name that holds the configuration. Currently, the supported files are: 46 | # api.toml, config.toml, economics.toml, enableEpochs.toml, enableRounds.toml, external.toml, fullArchiveP2P.toml, p2p.toml, ratings.toml, systemSmartContractsConfig.toml 47 | # ------------------------------- 48 | # Un-comment and update the following section in order to enable config values overloading 49 | # ------------------------------- 50 | OverridableConfigTomlValues = [ 51 | { File = "config.toml", Path = "WebServerAntiflood.WebServerAntifloodEnabled", Value = false }, 52 | { File = "config.toml", Path = "WebServerAntiflood.TrieOperationsDeadlineMilliseconds", Value = 120000 }, 53 | { File = "config.toml", Path = "Antiflood.Enabled", Value = false }, 54 | { File = "config.toml", Path = "DbLookupExtensions.Enabled", Value = true }, 55 | { File = "config.toml", Path = "VirtualMachine.GasConfig.ShardMaxGasPerVmQuery", Value = 0 }, 56 | { File = "config.toml", Path = "VirtualMachine.Querying.TimeOutForSCExecutionInMilliseconds", Value = 100000 }, 57 | { File = "config.toml", Path = "VirtualMachine.Querying.NumConcurrentVMs", Value = 2 }, 58 | ] 59 | # BlockProcessingCutoff can be used to stop processing blocks at a certain round, nonce or epoch. 60 | # This can be useful for snapshotting different stuff and also for debugging purposes. 61 | [BlockProcessingCutoff] 62 | # If set to true, the node will stop at the given coordinate 63 | Enabled = false 64 | 65 | # Mode represents the cutoff mode. possible values: "pause" or "process-error". 66 | # "pause" mode will halt the processing at the block with the given coordinates. Useful for snapshots/analytics 67 | # "process-error" will return an error when processing the block with the given coordinates. Useful for debugging 68 | Mode = "pause" 69 | 70 | # CutoffTrigger represents the kind of coordinate to look after when cutting off the processing. 71 | # Possible values: "round", "nonce", or "epoch" 72 | CutoffTrigger = "round" 73 | 74 | # The minimum value of the cutoff. For example, if CutoffType is set to "round", and Value to 20, then the node will stop processing at round 20+ 75 | Value = 0 76 | 77 | # NamedIdentity represents an identity that runs nodes on the multikey 78 | # There can be multiple identities set on the same node, each one of them having different bls keys, just by duplicating the NamedIdentity 79 | [[NamedIdentity]] 80 | # Identity represents the GitHub identity for the current NamedIdentity 81 | Identity = "" 82 | # NodeName represents the name that will be given to the names of the current identity 83 | NodeName = "" 84 | # BLSKeys represents the BLS keys assigned to the current NamedIdentity 85 | BLSKeys = [ 86 | "", 87 | "" 88 | ] -------------------------------------------------------------------------------- /config/devnet/0-observingSquad/elrond-nodes/node-2/prefs.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | [Preferences] 3 | # DestinationShardAsObserver represents the desired shard when running as observer 4 | # value will be given as string. For example: "0", "1", "15", "metachain" 5 | # if "disabled" is provided then the node will start in the corresponding shard for its public key or 0 otherwise 6 | DestinationShardAsObserver = "2" 7 | 8 | # NodeDisplayName represents the friendly name a user can pick for his node in the status monitor when the node does not run in multikey mode 9 | # In multikey mode, all bls keys not mentioned in NamedIdentity section will use this one as default 10 | NodeDisplayName = "node-observer-2" 11 | 12 | # Identity represents the GitHub identity when the node does not run in multikey mode 13 | # In multikey mode, all bls keys not mentioned in NamedIdentity section will use this one as default 14 | Identity = "" 15 | 16 | # RedundancyLevel represents the level of redundancy used by the node (-1 = disabled, 0 = main instance (default), 17 | # 1 = first backup, 2 = second backup, etc.) 18 | RedundancyLevel = 0 19 | 20 | # FullArchive, if enabled, will make the node able to respond to requests from past, old epochs. 21 | # It is highly recommended to enable this flag on an observer (not on a validator node) 22 | FullArchive = false 23 | 24 | # PreferredConnections holds an array containing valid ips or peer ids from nodes to connect with (in top of other connections) 25 | # Example: 26 | # PreferredConnections = [ 27 | # "127.0.0.10", 28 | # "16Uiu2HAm6yvbp1oZ6zjnWsn9FdRqBSaQkbhELyaThuq48ybdorrr" 29 | # ] 30 | PreferredConnections = [] 31 | 32 | # ConnectionWatcherType represents the type of the connection watcher needed. 33 | # possible options: 34 | # - "disabled" - no connection watching should be made 35 | # - "print" - new connection found will be printed in the log file 36 | ConnectionWatcherType = "disabled" 37 | 38 | # OverridableConfigTomlValues represents an array of items to be overloaded inside other configuration files, which can be helpful 39 | # so that certain config values need to remain the same during upgrades. 40 | # (for example, an Elasticsearch user wants external.toml->ElasticSearchConnector.Enabled to remain true all the time during upgrades, while the default 41 | # configuration of the node has the false value) 42 | # The Path indicates what value to change, while Value represents the new value. The node operator must make sure 43 | # to follow the same type of the original value (ex: uint32: 37, float32: 37.0, bool: true) 44 | # Also, the Value can be a struct (ex: { StartEpoch = 0, Version = "1.5" }) or an array (ex: [{ StartEpoch = 0, Version = "1.4" }, { StartEpoch = 1, Version = "1.5" }]) 45 | # File represents the file name that holds the configuration. Currently, the supported files are: 46 | # api.toml, config.toml, economics.toml, enableEpochs.toml, enableRounds.toml, external.toml, fullArchiveP2P.toml, p2p.toml, ratings.toml, systemSmartContractsConfig.toml 47 | # ------------------------------- 48 | # Un-comment and update the following section in order to enable config values overloading 49 | # ------------------------------- 50 | OverridableConfigTomlValues = [ 51 | { File = "config.toml", Path = "WebServerAntiflood.WebServerAntifloodEnabled", Value = false }, 52 | { File = "config.toml", Path = "WebServerAntiflood.TrieOperationsDeadlineMilliseconds", Value = 120000 }, 53 | { File = "config.toml", Path = "Antiflood.Enabled", Value = false }, 54 | { File = "config.toml", Path = "DbLookupExtensions.Enabled", Value = true }, 55 | { File = "config.toml", Path = "VirtualMachine.GasConfig.ShardMaxGasPerVmQuery", Value = 0 }, 56 | { File = "config.toml", Path = "VirtualMachine.Querying.TimeOutForSCExecutionInMilliseconds", Value = 100000 }, 57 | { File = "config.toml", Path = "VirtualMachine.Querying.NumConcurrentVMs", Value = 2 }, 58 | ] 59 | # BlockProcessingCutoff can be used to stop processing blocks at a certain round, nonce or epoch. 60 | # This can be useful for snapshotting different stuff and also for debugging purposes. 61 | [BlockProcessingCutoff] 62 | # If set to true, the node will stop at the given coordinate 63 | Enabled = false 64 | 65 | # Mode represents the cutoff mode. possible values: "pause" or "process-error". 66 | # "pause" mode will halt the processing at the block with the given coordinates. Useful for snapshots/analytics 67 | # "process-error" will return an error when processing the block with the given coordinates. Useful for debugging 68 | Mode = "pause" 69 | 70 | # CutoffTrigger represents the kind of coordinate to look after when cutting off the processing. 71 | # Possible values: "round", "nonce", or "epoch" 72 | CutoffTrigger = "round" 73 | 74 | # The minimum value of the cutoff. For example, if CutoffType is set to "round", and Value to 20, then the node will stop processing at round 20+ 75 | Value = 0 76 | 77 | # NamedIdentity represents an identity that runs nodes on the multikey 78 | # There can be multiple identities set on the same node, each one of them having different bls keys, just by duplicating the NamedIdentity 79 | [[NamedIdentity]] 80 | # Identity represents the GitHub identity for the current NamedIdentity 81 | Identity = "" 82 | # NodeName represents the name that will be given to the names of the current identity 83 | NodeName = "" 84 | # BLSKeys represents the BLS keys assigned to the current NamedIdentity 85 | BLSKeys = [ 86 | "", 87 | "" 88 | ] -------------------------------------------------------------------------------- /config/mainnet/0-observingSquad/elrond-nodes/node-0/prefs.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | [Preferences] 3 | # DestinationShardAsObserver represents the desired shard when running as observer 4 | # value will be given as string. For example: "0", "1", "15", "metachain" 5 | # if "disabled" is provided then the node will start in the corresponding shard for its public key or 0 otherwise 6 | DestinationShardAsObserver = "0" 7 | 8 | # NodeDisplayName represents the friendly name a user can pick for his node in the status monitor when the node does not run in multikey mode 9 | # In multikey mode, all bls keys not mentioned in NamedIdentity section will use this one as default 10 | NodeDisplayName = "node-observer-0" 11 | 12 | # Identity represents the GitHub identity when the node does not run in multikey mode 13 | # In multikey mode, all bls keys not mentioned in NamedIdentity section will use this one as default 14 | Identity = "" 15 | 16 | # RedundancyLevel represents the level of redundancy used by the node (-1 = disabled, 0 = main instance (default), 17 | # 1 = first backup, 2 = second backup, etc.) 18 | RedundancyLevel = 0 19 | 20 | # FullArchive, if enabled, will make the node able to respond to requests from past, old epochs. 21 | # It is highly recommended to enable this flag on an observer (not on a validator node) 22 | FullArchive = false 23 | 24 | # PreferredConnections holds an array containing valid ips or peer ids from nodes to connect with (in top of other connections) 25 | # Example: 26 | # PreferredConnections = [ 27 | # "127.0.0.10", 28 | # "16Uiu2HAm6yvbp1oZ6zjnWsn9FdRqBSaQkbhELyaThuq48ybdorrr" 29 | # ] 30 | PreferredConnections = [] 31 | 32 | # ConnectionWatcherType represents the type of the connection watcher needed. 33 | # possible options: 34 | # - "disabled" - no connection watching should be made 35 | # - "print" - new connection found will be printed in the log file 36 | ConnectionWatcherType = "disabled" 37 | 38 | # OverridableConfigTomlValues represents an array of items to be overloaded inside other configuration files, which can be helpful 39 | # so that certain config values need to remain the same during upgrades. 40 | # (for example, an Elasticsearch user wants external.toml->ElasticSearchConnector.Enabled to remain true all the time during upgrades, while the default 41 | # configuration of the node has the false value) 42 | # The Path indicates what value to change, while Value represents the new value. The node operator must make sure 43 | # to follow the same type of the original value (ex: uint32: 37, float32: 37.0, bool: true) 44 | # Also, the Value can be a struct (ex: { StartEpoch = 0, Version = "1.5" }) or an array (ex: [{ StartEpoch = 0, Version = "1.4" }, { StartEpoch = 1, Version = "1.5" }]) 45 | # File represents the file name that holds the configuration. Currently, the supported files are: 46 | # api.toml, config.toml, economics.toml, enableEpochs.toml, enableRounds.toml, external.toml, fullArchiveP2P.toml, p2p.toml, ratings.toml, systemSmartContractsConfig.toml 47 | # ------------------------------- 48 | # Un-comment and update the following section in order to enable config values overloading 49 | # ------------------------------- 50 | OverridableConfigTomlValues = [ 51 | { File = "config.toml", Path = "WebServerAntiflood.WebServerAntifloodEnabled", Value = false }, 52 | { File = "config.toml", Path = "WebServerAntiflood.TrieOperationsDeadlineMilliseconds", Value = 120000 }, 53 | { File = "config.toml", Path = "Antiflood.Enabled", Value = false }, 54 | { File = "config.toml", Path = "DbLookupExtensions.Enabled", Value = true }, 55 | { File = "config.toml", Path = "VirtualMachine.GasConfig.ShardMaxGasPerVmQuery", Value = 0 }, 56 | { File = "config.toml", Path = "VirtualMachine.Querying.TimeOutForSCExecutionInMilliseconds", Value = 100000 }, 57 | { File = "config.toml", Path = "VirtualMachine.Querying.NumConcurrentVMs", Value = 2 }, 58 | ] 59 | # BlockProcessingCutoff can be used to stop processing blocks at a certain round, nonce or epoch. 60 | # This can be useful for snapshotting different stuff and also for debugging purposes. 61 | [BlockProcessingCutoff] 62 | # If set to true, the node will stop at the given coordinate 63 | Enabled = false 64 | 65 | # Mode represents the cutoff mode. possible values: "pause" or "process-error". 66 | # "pause" mode will halt the processing at the block with the given coordinates. Useful for snapshots/analytics 67 | # "process-error" will return an error when processing the block with the given coordinates. Useful for debugging 68 | Mode = "pause" 69 | 70 | # CutoffTrigger represents the kind of coordinate to look after when cutting off the processing. 71 | # Possible values: "round", "nonce", or "epoch" 72 | CutoffTrigger = "round" 73 | 74 | # The minimum value of the cutoff. For example, if CutoffType is set to "round", and Value to 20, then the node will stop processing at round 20+ 75 | Value = 0 76 | 77 | # NamedIdentity represents an identity that runs nodes on the multikey 78 | # There can be multiple identities set on the same node, each one of them having different bls keys, just by duplicating the NamedIdentity 79 | [[NamedIdentity]] 80 | # Identity represents the GitHub identity for the current NamedIdentity 81 | Identity = "" 82 | # NodeName represents the name that will be given to the names of the current identity 83 | NodeName = "" 84 | # BLSKeys represents the BLS keys assigned to the current NamedIdentity 85 | BLSKeys = [ 86 | "", 87 | "" 88 | ] -------------------------------------------------------------------------------- /config/mainnet/0-observingSquad/elrond-nodes/node-1/prefs.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | [Preferences] 3 | # DestinationShardAsObserver represents the desired shard when running as observer 4 | # value will be given as string. For example: "0", "1", "15", "metachain" 5 | # if "disabled" is provided then the node will start in the corresponding shard for its public key or 0 otherwise 6 | DestinationShardAsObserver = "1" 7 | 8 | # NodeDisplayName represents the friendly name a user can pick for his node in the status monitor when the node does not run in multikey mode 9 | # In multikey mode, all bls keys not mentioned in NamedIdentity section will use this one as default 10 | NodeDisplayName = "node-observer-1" 11 | 12 | # Identity represents the GitHub identity when the node does not run in multikey mode 13 | # In multikey mode, all bls keys not mentioned in NamedIdentity section will use this one as default 14 | Identity = "" 15 | 16 | # RedundancyLevel represents the level of redundancy used by the node (-1 = disabled, 0 = main instance (default), 17 | # 1 = first backup, 2 = second backup, etc.) 18 | RedundancyLevel = 0 19 | 20 | # FullArchive, if enabled, will make the node able to respond to requests from past, old epochs. 21 | # It is highly recommended to enable this flag on an observer (not on a validator node) 22 | FullArchive = false 23 | 24 | # PreferredConnections holds an array containing valid ips or peer ids from nodes to connect with (in top of other connections) 25 | # Example: 26 | # PreferredConnections = [ 27 | # "127.0.0.10", 28 | # "16Uiu2HAm6yvbp1oZ6zjnWsn9FdRqBSaQkbhELyaThuq48ybdorrr" 29 | # ] 30 | PreferredConnections = [] 31 | 32 | # ConnectionWatcherType represents the type of the connection watcher needed. 33 | # possible options: 34 | # - "disabled" - no connection watching should be made 35 | # - "print" - new connection found will be printed in the log file 36 | ConnectionWatcherType = "disabled" 37 | 38 | # OverridableConfigTomlValues represents an array of items to be overloaded inside other configuration files, which can be helpful 39 | # so that certain config values need to remain the same during upgrades. 40 | # (for example, an Elasticsearch user wants external.toml->ElasticSearchConnector.Enabled to remain true all the time during upgrades, while the default 41 | # configuration of the node has the false value) 42 | # The Path indicates what value to change, while Value represents the new value. The node operator must make sure 43 | # to follow the same type of the original value (ex: uint32: 37, float32: 37.0, bool: true) 44 | # Also, the Value can be a struct (ex: { StartEpoch = 0, Version = "1.5" }) or an array (ex: [{ StartEpoch = 0, Version = "1.4" }, { StartEpoch = 1, Version = "1.5" }]) 45 | # File represents the file name that holds the configuration. Currently, the supported files are: 46 | # api.toml, config.toml, economics.toml, enableEpochs.toml, enableRounds.toml, external.toml, fullArchiveP2P.toml, p2p.toml, ratings.toml, systemSmartContractsConfig.toml 47 | # ------------------------------- 48 | # Un-comment and update the following section in order to enable config values overloading 49 | # ------------------------------- 50 | OverridableConfigTomlValues = [ 51 | { File = "config.toml", Path = "WebServerAntiflood.WebServerAntifloodEnabled", Value = false }, 52 | { File = "config.toml", Path = "WebServerAntiflood.TrieOperationsDeadlineMilliseconds", Value = 120000 }, 53 | { File = "config.toml", Path = "Antiflood.Enabled", Value = false }, 54 | { File = "config.toml", Path = "DbLookupExtensions.Enabled", Value = true }, 55 | { File = "config.toml", Path = "VirtualMachine.GasConfig.ShardMaxGasPerVmQuery", Value = 0 }, 56 | { File = "config.toml", Path = "VirtualMachine.Querying.TimeOutForSCExecutionInMilliseconds", Value = 100000 }, 57 | { File = "config.toml", Path = "VirtualMachine.Querying.NumConcurrentVMs", Value = 2 }, 58 | ] 59 | # BlockProcessingCutoff can be used to stop processing blocks at a certain round, nonce or epoch. 60 | # This can be useful for snapshotting different stuff and also for debugging purposes. 61 | [BlockProcessingCutoff] 62 | # If set to true, the node will stop at the given coordinate 63 | Enabled = false 64 | 65 | # Mode represents the cutoff mode. possible values: "pause" or "process-error". 66 | # "pause" mode will halt the processing at the block with the given coordinates. Useful for snapshots/analytics 67 | # "process-error" will return an error when processing the block with the given coordinates. Useful for debugging 68 | Mode = "pause" 69 | 70 | # CutoffTrigger represents the kind of coordinate to look after when cutting off the processing. 71 | # Possible values: "round", "nonce", or "epoch" 72 | CutoffTrigger = "round" 73 | 74 | # The minimum value of the cutoff. For example, if CutoffType is set to "round", and Value to 20, then the node will stop processing at round 20+ 75 | Value = 0 76 | 77 | # NamedIdentity represents an identity that runs nodes on the multikey 78 | # There can be multiple identities set on the same node, each one of them having different bls keys, just by duplicating the NamedIdentity 79 | [[NamedIdentity]] 80 | # Identity represents the GitHub identity for the current NamedIdentity 81 | Identity = "" 82 | # NodeName represents the name that will be given to the names of the current identity 83 | NodeName = "" 84 | # BLSKeys represents the BLS keys assigned to the current NamedIdentity 85 | BLSKeys = [ 86 | "", 87 | "" 88 | ] -------------------------------------------------------------------------------- /config/mainnet/0-observingSquad/elrond-nodes/node-2/prefs.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | [Preferences] 3 | # DestinationShardAsObserver represents the desired shard when running as observer 4 | # value will be given as string. For example: "0", "1", "15", "metachain" 5 | # if "disabled" is provided then the node will start in the corresponding shard for its public key or 0 otherwise 6 | DestinationShardAsObserver = "2" 7 | 8 | # NodeDisplayName represents the friendly name a user can pick for his node in the status monitor when the node does not run in multikey mode 9 | # In multikey mode, all bls keys not mentioned in NamedIdentity section will use this one as default 10 | NodeDisplayName = "node-observer-2" 11 | 12 | # Identity represents the GitHub identity when the node does not run in multikey mode 13 | # In multikey mode, all bls keys not mentioned in NamedIdentity section will use this one as default 14 | Identity = "" 15 | 16 | # RedundancyLevel represents the level of redundancy used by the node (-1 = disabled, 0 = main instance (default), 17 | # 1 = first backup, 2 = second backup, etc.) 18 | RedundancyLevel = 0 19 | 20 | # FullArchive, if enabled, will make the node able to respond to requests from past, old epochs. 21 | # It is highly recommended to enable this flag on an observer (not on a validator node) 22 | FullArchive = false 23 | 24 | # PreferredConnections holds an array containing valid ips or peer ids from nodes to connect with (in top of other connections) 25 | # Example: 26 | # PreferredConnections = [ 27 | # "127.0.0.10", 28 | # "16Uiu2HAm6yvbp1oZ6zjnWsn9FdRqBSaQkbhELyaThuq48ybdorrr" 29 | # ] 30 | PreferredConnections = [] 31 | 32 | # ConnectionWatcherType represents the type of the connection watcher needed. 33 | # possible options: 34 | # - "disabled" - no connection watching should be made 35 | # - "print" - new connection found will be printed in the log file 36 | ConnectionWatcherType = "disabled" 37 | 38 | # OverridableConfigTomlValues represents an array of items to be overloaded inside other configuration files, which can be helpful 39 | # so that certain config values need to remain the same during upgrades. 40 | # (for example, an Elasticsearch user wants external.toml->ElasticSearchConnector.Enabled to remain true all the time during upgrades, while the default 41 | # configuration of the node has the false value) 42 | # The Path indicates what value to change, while Value represents the new value. The node operator must make sure 43 | # to follow the same type of the original value (ex: uint32: 37, float32: 37.0, bool: true) 44 | # Also, the Value can be a struct (ex: { StartEpoch = 0, Version = "1.5" }) or an array (ex: [{ StartEpoch = 0, Version = "1.4" }, { StartEpoch = 1, Version = "1.5" }]) 45 | # File represents the file name that holds the configuration. Currently, the supported files are: 46 | # api.toml, config.toml, economics.toml, enableEpochs.toml, enableRounds.toml, external.toml, fullArchiveP2P.toml, p2p.toml, ratings.toml, systemSmartContractsConfig.toml 47 | # ------------------------------- 48 | # Un-comment and update the following section in order to enable config values overloading 49 | # ------------------------------- 50 | OverridableConfigTomlValues = [ 51 | { File = "config.toml", Path = "WebServerAntiflood.WebServerAntifloodEnabled", Value = false }, 52 | { File = "config.toml", Path = "WebServerAntiflood.TrieOperationsDeadlineMilliseconds", Value = 120000 }, 53 | { File = "config.toml", Path = "Antiflood.Enabled", Value = false }, 54 | { File = "config.toml", Path = "DbLookupExtensions.Enabled", Value = true }, 55 | { File = "config.toml", Path = "VirtualMachine.GasConfig.ShardMaxGasPerVmQuery", Value = 0 }, 56 | { File = "config.toml", Path = "VirtualMachine.Querying.TimeOutForSCExecutionInMilliseconds", Value = 100000 }, 57 | { File = "config.toml", Path = "VirtualMachine.Querying.NumConcurrentVMs", Value = 2 }, 58 | ] 59 | # BlockProcessingCutoff can be used to stop processing blocks at a certain round, nonce or epoch. 60 | # This can be useful for snapshotting different stuff and also for debugging purposes. 61 | [BlockProcessingCutoff] 62 | # If set to true, the node will stop at the given coordinate 63 | Enabled = false 64 | 65 | # Mode represents the cutoff mode. possible values: "pause" or "process-error". 66 | # "pause" mode will halt the processing at the block with the given coordinates. Useful for snapshots/analytics 67 | # "process-error" will return an error when processing the block with the given coordinates. Useful for debugging 68 | Mode = "pause" 69 | 70 | # CutoffTrigger represents the kind of coordinate to look after when cutting off the processing. 71 | # Possible values: "round", "nonce", or "epoch" 72 | CutoffTrigger = "round" 73 | 74 | # The minimum value of the cutoff. For example, if CutoffType is set to "round", and Value to 20, then the node will stop processing at round 20+ 75 | Value = 0 76 | 77 | # NamedIdentity represents an identity that runs nodes on the multikey 78 | # There can be multiple identities set on the same node, each one of them having different bls keys, just by duplicating the NamedIdentity 79 | [[NamedIdentity]] 80 | # Identity represents the GitHub identity for the current NamedIdentity 81 | Identity = "" 82 | # NodeName represents the name that will be given to the names of the current identity 83 | NodeName = "" 84 | # BLSKeys represents the BLS keys assigned to the current NamedIdentity 85 | BLSKeys = [ 86 | "", 87 | "" 88 | ] -------------------------------------------------------------------------------- /config/devnet/0-observingSquad/elrond-nodes/node-3/prefs.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | [Preferences] 3 | # DestinationShardAsObserver represents the desired shard when running as observer 4 | # value will be given as string. For example: "0", "1", "15", "metachain" 5 | # if "disabled" is provided then the node will start in the corresponding shard for its public key or 0 otherwise 6 | DestinationShardAsObserver = "metachain" 7 | 8 | # NodeDisplayName represents the friendly name a user can pick for his node in the status monitor when the node does not run in multikey mode 9 | # In multikey mode, all bls keys not mentioned in NamedIdentity section will use this one as default 10 | NodeDisplayName = "node-observer-3" 11 | 12 | # Identity represents the GitHub identity when the node does not run in multikey mode 13 | # In multikey mode, all bls keys not mentioned in NamedIdentity section will use this one as default 14 | Identity = "" 15 | 16 | # RedundancyLevel represents the level of redundancy used by the node (-1 = disabled, 0 = main instance (default), 17 | # 1 = first backup, 2 = second backup, etc.) 18 | RedundancyLevel = 0 19 | 20 | # FullArchive, if enabled, will make the node able to respond to requests from past, old epochs. 21 | # It is highly recommended to enable this flag on an observer (not on a validator node) 22 | FullArchive = false 23 | 24 | # PreferredConnections holds an array containing valid ips or peer ids from nodes to connect with (in top of other connections) 25 | # Example: 26 | # PreferredConnections = [ 27 | # "127.0.0.10", 28 | # "16Uiu2HAm6yvbp1oZ6zjnWsn9FdRqBSaQkbhELyaThuq48ybdorrr" 29 | # ] 30 | PreferredConnections = [] 31 | 32 | # ConnectionWatcherType represents the type of the connection watcher needed. 33 | # possible options: 34 | # - "disabled" - no connection watching should be made 35 | # - "print" - new connection found will be printed in the log file 36 | ConnectionWatcherType = "disabled" 37 | 38 | # OverridableConfigTomlValues represents an array of items to be overloaded inside other configuration files, which can be helpful 39 | # so that certain config values need to remain the same during upgrades. 40 | # (for example, an Elasticsearch user wants external.toml->ElasticSearchConnector.Enabled to remain true all the time during upgrades, while the default 41 | # configuration of the node has the false value) 42 | # The Path indicates what value to change, while Value represents the new value. The node operator must make sure 43 | # to follow the same type of the original value (ex: uint32: 37, float32: 37.0, bool: true) 44 | # Also, the Value can be a struct (ex: { StartEpoch = 0, Version = "1.5" }) or an array (ex: [{ StartEpoch = 0, Version = "1.4" }, { StartEpoch = 1, Version = "1.5" }]) 45 | # File represents the file name that holds the configuration. Currently, the supported files are: 46 | # api.toml, config.toml, economics.toml, enableEpochs.toml, enableRounds.toml, external.toml, fullArchiveP2P.toml, p2p.toml, ratings.toml, systemSmartContractsConfig.toml 47 | # ------------------------------- 48 | # Un-comment and update the following section in order to enable config values overloading 49 | # ------------------------------- 50 | OverridableConfigTomlValues = [ 51 | { File = "config.toml", Path = "WebServerAntiflood.WebServerAntifloodEnabled", Value = false }, 52 | { File = "config.toml", Path = "WebServerAntiflood.TrieOperationsDeadlineMilliseconds", Value = 120000 }, 53 | { File = "config.toml", Path = "Antiflood.Enabled", Value = false }, 54 | { File = "config.toml", Path = "DbLookupExtensions.Enabled", Value = true }, 55 | { File = "config.toml", Path = "VirtualMachine.GasConfig.ShardMaxGasPerVmQuery", Value = 0 }, 56 | { File = "config.toml", Path = "VirtualMachine.Querying.TimeOutForSCExecutionInMilliseconds", Value = 100000 }, 57 | { File = "config.toml", Path = "VirtualMachine.Querying.NumConcurrentVMs", Value = 2 }, 58 | ] 59 | # BlockProcessingCutoff can be used to stop processing blocks at a certain round, nonce or epoch. 60 | # This can be useful for snapshotting different stuff and also for debugging purposes. 61 | [BlockProcessingCutoff] 62 | # If set to true, the node will stop at the given coordinate 63 | Enabled = false 64 | 65 | # Mode represents the cutoff mode. possible values: "pause" or "process-error". 66 | # "pause" mode will halt the processing at the block with the given coordinates. Useful for snapshots/analytics 67 | # "process-error" will return an error when processing the block with the given coordinates. Useful for debugging 68 | Mode = "pause" 69 | 70 | # CutoffTrigger represents the kind of coordinate to look after when cutting off the processing. 71 | # Possible values: "round", "nonce", or "epoch" 72 | CutoffTrigger = "round" 73 | 74 | # The minimum value of the cutoff. For example, if CutoffType is set to "round", and Value to 20, then the node will stop processing at round 20+ 75 | Value = 0 76 | 77 | # NamedIdentity represents an identity that runs nodes on the multikey 78 | # There can be multiple identities set on the same node, each one of them having different bls keys, just by duplicating the NamedIdentity 79 | [[NamedIdentity]] 80 | # Identity represents the GitHub identity for the current NamedIdentity 81 | Identity = "" 82 | # NodeName represents the name that will be given to the names of the current identity 83 | NodeName = "" 84 | # BLSKeys represents the BLS keys assigned to the current NamedIdentity 85 | BLSKeys = [ 86 | "", 87 | "" 88 | ] -------------------------------------------------------------------------------- /config/mainnet/0-observingSquad/elrond-nodes/node-3/prefs.toml: -------------------------------------------------------------------------------- 1 | # Overwritted by mvx-api-deployer 2 | [Preferences] 3 | # DestinationShardAsObserver represents the desired shard when running as observer 4 | # value will be given as string. For example: "0", "1", "15", "metachain" 5 | # if "disabled" is provided then the node will start in the corresponding shard for its public key or 0 otherwise 6 | DestinationShardAsObserver = "metachain" 7 | 8 | # NodeDisplayName represents the friendly name a user can pick for his node in the status monitor when the node does not run in multikey mode 9 | # In multikey mode, all bls keys not mentioned in NamedIdentity section will use this one as default 10 | NodeDisplayName = "node-observer-3" 11 | 12 | # Identity represents the GitHub identity when the node does not run in multikey mode 13 | # In multikey mode, all bls keys not mentioned in NamedIdentity section will use this one as default 14 | Identity = "" 15 | 16 | # RedundancyLevel represents the level of redundancy used by the node (-1 = disabled, 0 = main instance (default), 17 | # 1 = first backup, 2 = second backup, etc.) 18 | RedundancyLevel = 0 19 | 20 | # FullArchive, if enabled, will make the node able to respond to requests from past, old epochs. 21 | # It is highly recommended to enable this flag on an observer (not on a validator node) 22 | FullArchive = false 23 | 24 | # PreferredConnections holds an array containing valid ips or peer ids from nodes to connect with (in top of other connections) 25 | # Example: 26 | # PreferredConnections = [ 27 | # "127.0.0.10", 28 | # "16Uiu2HAm6yvbp1oZ6zjnWsn9FdRqBSaQkbhELyaThuq48ybdorrr" 29 | # ] 30 | PreferredConnections = [] 31 | 32 | # ConnectionWatcherType represents the type of the connection watcher needed. 33 | # possible options: 34 | # - "disabled" - no connection watching should be made 35 | # - "print" - new connection found will be printed in the log file 36 | ConnectionWatcherType = "disabled" 37 | 38 | # OverridableConfigTomlValues represents an array of items to be overloaded inside other configuration files, which can be helpful 39 | # so that certain config values need to remain the same during upgrades. 40 | # (for example, an Elasticsearch user wants external.toml->ElasticSearchConnector.Enabled to remain true all the time during upgrades, while the default 41 | # configuration of the node has the false value) 42 | # The Path indicates what value to change, while Value represents the new value. The node operator must make sure 43 | # to follow the same type of the original value (ex: uint32: 37, float32: 37.0, bool: true) 44 | # Also, the Value can be a struct (ex: { StartEpoch = 0, Version = "1.5" }) or an array (ex: [{ StartEpoch = 0, Version = "1.4" }, { StartEpoch = 1, Version = "1.5" }]) 45 | # File represents the file name that holds the configuration. Currently, the supported files are: 46 | # api.toml, config.toml, economics.toml, enableEpochs.toml, enableRounds.toml, external.toml, fullArchiveP2P.toml, p2p.toml, ratings.toml, systemSmartContractsConfig.toml 47 | # ------------------------------- 48 | # Un-comment and update the following section in order to enable config values overloading 49 | # ------------------------------- 50 | OverridableConfigTomlValues = [ 51 | { File = "config.toml", Path = "WebServerAntiflood.WebServerAntifloodEnabled", Value = false }, 52 | { File = "config.toml", Path = "WebServerAntiflood.TrieOperationsDeadlineMilliseconds", Value = 120000 }, 53 | { File = "config.toml", Path = "Antiflood.Enabled", Value = false }, 54 | { File = "config.toml", Path = "DbLookupExtensions.Enabled", Value = true }, 55 | { File = "config.toml", Path = "VirtualMachine.GasConfig.ShardMaxGasPerVmQuery", Value = 0 }, 56 | { File = "config.toml", Path = "VirtualMachine.Querying.TimeOutForSCExecutionInMilliseconds", Value = 100000 }, 57 | { File = "config.toml", Path = "VirtualMachine.Querying.NumConcurrentVMs", Value = 2 }, 58 | ] 59 | # BlockProcessingCutoff can be used to stop processing blocks at a certain round, nonce or epoch. 60 | # This can be useful for snapshotting different stuff and also for debugging purposes. 61 | [BlockProcessingCutoff] 62 | # If set to true, the node will stop at the given coordinate 63 | Enabled = false 64 | 65 | # Mode represents the cutoff mode. possible values: "pause" or "process-error". 66 | # "pause" mode will halt the processing at the block with the given coordinates. Useful for snapshots/analytics 67 | # "process-error" will return an error when processing the block with the given coordinates. Useful for debugging 68 | Mode = "pause" 69 | 70 | # CutoffTrigger represents the kind of coordinate to look after when cutting off the processing. 71 | # Possible values: "round", "nonce", or "epoch" 72 | CutoffTrigger = "round" 73 | 74 | # The minimum value of the cutoff. For example, if CutoffType is set to "round", and Value to 20, then the node will stop processing at round 20+ 75 | Value = 0 76 | 77 | # NamedIdentity represents an identity that runs nodes on the multikey 78 | # There can be multiple identities set on the same node, each one of them having different bls keys, just by duplicating the NamedIdentity 79 | [[NamedIdentity]] 80 | # Identity represents the GitHub identity for the current NamedIdentity 81 | Identity = "" 82 | # NodeName represents the name that will be given to the names of the current identity 83 | NodeName = "" 84 | # BLSKeys represents the BLS keys assigned to the current NamedIdentity 85 | BLSKeys = [ 86 | "", 87 | "" 88 | ] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MultiversX API Deployer 2 | 3 | Effortlessly deploy a complete infrastructure to run your own **MultiversX API** in just a few steps. This repository streamlines the entire process, eliminating complex configurations and providing a rapid setup solution for any server. 4 | 5 | With a focus on simplicity and automation, this deployment is designed to make the MultiversX API accessible to everyone. Whether you're a blockchain enthusiast or a seasoned developer, you can have a fully operational API in no time. No need to gather resources from multiple repositories—everything you need is here in one place. 6 | 7 | ![MultiversX API Overview](README.png) 8 | 9 | ### **Quick Start** 10 | Deploying the infrastructure is as simple as running three commands: 11 | 1. **Initialize the server**: Set up the requirements and create a dedicated user for running services. 12 | 2. **Deploy the infrastructure**: Install the necessary services and configure the environment. 13 | 3. **Start the services**: Launch the components and expose the API for external access. 14 | 15 | 16 | Having a complete API usually required a lot of steps from a lot of repositories, here you have it all in one place. 17 | 18 | ### **This deployment includes:** 19 | - [**An Observing Squad**](https://docs.multiversx.com/integrators/observing-squad): Access blockchain data by running observer nodes. 20 | - [**ElasticSearch Indexer**](https://docs.multiversx.com/sdk-and-tools/indexer/#observer-client): Convert raw blockchain data for efficient querying. 21 | - [**ElasticSearch Database**](https://github.com/elastic/elasticsearch): Store the converted blockchain data. 22 | - [**Kibana**](https://github.com/elastic/kibana): Visualize data and logs from the blockchain. 23 | - [**MultiversX API**](https://docs.multiversx.com/sdk-and-tools/rest-api/multiversx-api): Query blockchain data externally via a standard API. 24 | - [**xExchange**](https://github.com/multiversx/mx-exchange-service): The official exchange service for feed the MultiversX API. 25 | 26 | 27 | ## **0 - Prerequisites** 28 | 29 | ### **Hardware** 30 | To support the infrastructure's heavy load, we recommend deploying on a bare-metal server with the following specifications depending on your needs: 31 | 32 | | Network | Machine Type| CPU Cores | RAM | Storage | Bandwidth | 33 | |---------|-------------|-----------|-----|---------|-----------| 34 | | Mainnet | Bare |8 | 32 GB | 1 TB SSD | 1 Gbps | 35 | | Devnet | VPS | 4 | 16 GB | 500 GB SSD | 1 Gbps | 36 | 37 | ### **Security** 38 | Before deployment: 39 | - Secure your server with an **SSH key**. 40 | - Ensure no sensitive data is on the server. Although the API is stateless, misuse of the infrastructure could disrupt services. 41 | 42 | ### **Configuration** 43 | At the root of this repository you will find the file named config.cfg. It contains variables that can be configured to customize the deployment. 44 | 45 | The following variables are available: 46 | - **USERNAME**: The username on which the services will be installed. 47 | - **NETWORK**: The network to deploy. Currently supports `mainnet`, `devnet` and `testnet` networks. 48 | 49 | Currently, the deployment is configured with default settings. As development progresses, more configuration options will be added, such as enabling a **full history node** or customizing ElasticSearch settings. 50 | 51 | ## **1 - Initialize Server** 52 | 53 | 1. Ensure you are logged in as the root user 54 | 55 | 2. You will need this repository on your machine before starting: 56 | ```bash 57 | git clone https://github.com/PhyByte/mvx-api-deployer.git 58 | ``` 59 | 60 | 3. Run the installation script that will set up the requirements for the deployment: 61 | ```bash 62 | cd mvx-api-deployer 63 | ./1-Init.sh 64 | ``` 65 | 66 | ### **What this script does:** 67 | - Updates and upgrades your system. 68 | - Installs Docker and Docker Compose. 69 | 70 | 71 | --- 72 | 73 | ## **2 - Install Services** 74 | 75 | As you already configured the `config.cfg` file, you can now deploy the infrastructure immediately by running: 76 | ```bash 77 | cd ~/mvx-api-deployer 78 | ./2-Install.sh 79 | ``` 80 | 81 | 82 | ### **What this script does:** 83 | - Setup the Observing Squad with `ElasticSearch Indexer Enabled`. 84 | - Setup the ElasticSearch Indexer and deploy the ElasticSearch Database with Kibana. 85 | - Setup the MultiversX API. 86 | - Setup the xExchange service. 87 | 88 | 89 | ## **3 - Start Services** 90 | 91 | After the installation is complete, you can start the services by running: 92 | ```bash 93 | cd ~/mvx-api-deployer 94 | ./3-Start.sh 95 | ``` 96 | 97 | # Maintenance Section for MultiversX API Services 98 | 99 | The installation process includes copying a pre-configured `.bashrc` file to the deployment server. This file provides a set of convenient commands to manage the MultiversX API services, including starting, stopping, monitoring, and checking the status of individual services. 100 | 101 | ## **Overview of Maintenance Commands** 102 | 103 | ### **Observing Squad Commands** 104 | The Observing Squad allows you to access blockchain data via observer nodes. These commands help you monitor and manage the Observing Squad services. 105 | - **Start & Stop Observing Nodes** 106 | Use these commands to start and stop individual observing nodes: 107 | ```bash 108 | api_obssquad_start # Start all observing squad nodes 109 | api_obssquad_stop # Stop all observing squad nodes 110 | ``` 111 | - **Monitor Observing Nodes** 112 | Use these commands to monitor individual observing nodes: 113 | ```bash 114 | api_obssquad_monitoring_0 # Monitor node 0 at localhost:8080 115 | api_obssquad_monitoring_1 # Monitor node 1 at localhost:8081 116 | api_obssquad_monitoring_2 # Monitor node 2 at localhost:8082 117 | api_obssquad_monitoring_3 # Monitor node 3 at localhost:8083 118 | api_obssquad_monitoring_proxy # View logs of the observing squad proxy service 119 | ``` 120 | 121 | 122 | ### **ElasticSearch Indexer Commands** 123 | The ElasticSearch Indexer processes raw blockchain data into structured data for querying. 124 | 125 | - ** Start & Stop ElasticSearch Indexer** 126 | Use these commands to start and stop the ElasticSearch Indexer: 127 | ```bash 128 | api_indexer_start # Start the ElasticSearch Indexer 129 | api_indexer_stop # Stop the ElasticSearch Indexer 130 | ``` 131 | 132 | ### **ElasticSearch & Kibana Commands** 133 | The ElasticSearch Database stores the converted blockchain data. 134 | ```bash 135 | api_eskibana_start # Start ElasticSearch and Kibana 136 | api_eskibana_stop # Stop ElasticSearch and Kibana 137 | ``` 138 | 139 | ### **MultiversX API Commands** 140 | The MultiversX API provides external REST access to blockchain data. 141 | 142 | - **Start & Stop MultiversX API** 143 | Use these commands to start and stop the MultiversX API: 144 | ```bash 145 | api_mx_api_start # Start the MultiversX API 146 | api_mx_api_stop # Stop the MultiversX API 147 | ``` 148 | 149 | ### **Check Status of All Services** 150 | Use this command to check the status of all services: 151 | ```bash 152 | api_check_status # Check the status of all services 153 | ``` 154 | 155 | ## Adding Custom Commands 156 | You can add custom commands to the `.bashrc` file to manage additional services or configurations that you would need to run your own MultiversX API. This is usually better than retyping the commands every time. -------------------------------------------------------------------------------- /scripts/6-manage-services.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # --------------------------------------------------------- 4 | # MultiversX API Deployer - Start and Stop Services 5 | # --------------------------------------------------------- 6 | 7 | # --------- START ALL SERVICES --------- 8 | 9 | Start_All_Services() { 10 | Log-Step "Start All Services" 11 | 12 | ObsSquad_Start || Log-Warning "Observing Squad failed to start." 13 | EsIndexer_Start || Log-Warning "ElasticSearch Indexer failed to start." 14 | EsKibana_Start || Log-Warning "ElasticSearch and Kibana failed to start." 15 | xExchange_Start || Log-Warning "MultiversX xExchange failed to start." 16 | MxApi_Start || Log-Warning "MultiversX API failed to start." 17 | 18 | Log "All services start commands executed. Verify individual service statuses." 19 | } 20 | 21 | # --------- STOP ALL SERVICES --------- 22 | 23 | Stop_All_Services() { 24 | Log-Step "Stop All Services" 25 | 26 | MxApi_Stop || Log-Warning "MultiversX API failed to stop." 27 | EsKibana_Stop || Log-Warning "ElasticSearch and Kibana failed to stop." 28 | EsIndexer_Stop || Log-Warning "ElasticSearch Indexer failed to stop." 29 | xExchange_Stop || Log-Warning "MultiversX xExchange failed to stop." 30 | ObsSquad_Stop || Log-Warning "Observing Squad failed to stop." 31 | 32 | Log "All services stop commands executed. Verify individual service statuses." 33 | } 34 | 35 | # --------- CHECK STATUS OF ALL SERVICES --------- 36 | 37 | Check_All_Status() { 38 | Log-Step "Check Status of All Services" 39 | 40 | Log-SubStep "Checking Observing Squad Status TODO:" 41 | 42 | Log-SubStep "Checking ElasticSearch Indexer Status" 43 | if systemctl is-active --quiet elasticindexer; then 44 | Log "ElasticSearch Indexer service is running." 45 | else 46 | Log-Warning "ElasticSearch Indexer service is not running." 47 | fi 48 | 49 | Log-SubStep "Checking MultiversX API Status: TODO:" 50 | 51 | Log "Service status check completed." 52 | } 53 | 54 | # --------- OBSERVING SQUAD FUNCTIONS --------- 55 | 56 | # Start the Observing Squad 57 | ObsSquad_Start() { 58 | Log-Step "Start Observing Squad" 59 | 60 | local script_path="$HOME/mx-chain-scripts/script.sh" 61 | 62 | # Check if the script exists and is executable 63 | if [ -x "$script_path" ]; then 64 | # Run the script with the appropriate argument 65 | "$script_path" start_all || { 66 | Log-Error "Failed to start Observing Squad. Check logs for details." 67 | return 1 68 | } 69 | Log "Observing Squad started successfully." 70 | else 71 | Log-Error "Start script not found or not executable at $script_path." 72 | return 1 73 | fi 74 | } 75 | 76 | # Stop the Observing Squad 77 | ObsSquad_Stop() { 78 | Log-Step "Stop Observing Squad" 79 | 80 | local script_path="$HOME/mx-chain-scripts/script.sh" 81 | 82 | # Check if the script exists and is executable 83 | if [ -x "$script_path" ]; then 84 | "$script_path" stop_all || { 85 | Log-Error "Failed to stop Observing Squad. Check logs for details." 86 | return 1 87 | } 88 | Log "Observing Squad stopped successfully." 89 | else 90 | Log-Error "Stop script not found or not executable at $script_path." 91 | return 1 92 | fi 93 | } 94 | 95 | # --------- ELASTICSEARCH INDEXER FUNCTIONS --------- 96 | 97 | # Start the ElasticSearch Indexer 98 | EsIndexer_Start() { 99 | Log-Step "Start ElasticSearch Indexer" 100 | 101 | local service_name="mvx-elasticindexer.service" 102 | 103 | sudo systemctl start "$service_name" || { 104 | Log-Error "Failed to start ElasticSearch Indexer service. Check logs with 'journalctl -u $service_name'." 105 | return 1 106 | } 107 | 108 | sudo systemctl status "$service_name" --no-pager || { 109 | Log-Error "ElasticSearch Indexer service is not running as expected. Check logs with 'journalctl -u $service_name'." 110 | return 1 111 | } 112 | 113 | Log "ElasticSearch Indexer service started successfully." 114 | } 115 | 116 | # Stop the ElasticSearch Indexer 117 | EsIndexer_Stop() { 118 | Log-Step "Stop ElasticSearch Indexer" 119 | 120 | local service_name="mvx-elasticindexer.service" 121 | 122 | sudo systemctl stop "$service_name" || { 123 | Log-Error "Failed to stop ElasticSearch Indexer service." 124 | return 1 125 | } 126 | 127 | sudo systemctl status "$service_name" --no-pager | grep "inactive (dead)" &>/dev/null 128 | if [ $? -eq 0 ]; then 129 | Log "ElasticSearch Indexer service stopped successfully." 130 | else 131 | Log-Error "ElasticSearch Indexer service is still running. Please check manually." 132 | return 1 133 | fi 134 | } 135 | 136 | # --------- ELASTICSEARCH & KIBANA FUNCTIONS --------- 137 | 138 | # Start ElasticSearch and Kibana using Docker Compose 139 | EsKibana_Start() { 140 | Log-Step "Start ElasticSearch and Kibana using Docker Compose" 141 | 142 | local compose_file="$HOME/mx-chain-es-indexer-go/docker-compose.yml" 143 | 144 | if [ ! -f "$compose_file" ]; then 145 | Log-Error "Docker Compose file $compose_file not found. Ensure the repository was cloned and configured properly." 146 | return 1 147 | fi 148 | 149 | cd "$(dirname "$compose_file")" || { 150 | Log-Error "Failed to navigate to the directory containing $compose_file." 151 | return 1 152 | } 153 | 154 | sudo docker compose up -d || { 155 | Log-Error "Failed to start ElasticSearch and Kibana services. Check Docker Compose logs for details." 156 | return 1 157 | } 158 | 159 | Log "ElasticSearch and Kibana services started successfully." 160 | } 161 | 162 | # Stop ElasticSearch and Kibana using Docker Compose 163 | EsKibana_Stop() { 164 | Log-Step "Stop ElasticSearch and Kibana using Docker Compose" 165 | 166 | local compose_file="$HOME/mx-chain-es-indexer-go/docker-compose.yml" 167 | 168 | if [ ! -f "$compose_file" ]; then 169 | Log-Error "Docker Compose file $compose_file not found. Ensure the repository was cloned and configured properly." 170 | return 1 171 | fi 172 | 173 | cd "$(dirname "$compose_file")" || { 174 | Log-Error "Failed to navigate to the directory containing $compose_file." 175 | return 1 176 | } 177 | 178 | sudo docker compose down || { 179 | Log-Error "Failed to stop ElasticSearch and Kibana services. Check Docker Compose logs for details." 180 | return 1 181 | } 182 | 183 | Log "ElasticSearch and Kibana services stopped successfully." 184 | } 185 | 186 | # --------- MULTIVERSX xEXCHANGE FUNCTIONS --------- 187 | # Start the MultiversX xExchange 188 | xExchange_Start() { 189 | Log-Step "Start MultiversX xExchange" 190 | 191 | sudo systemctl start mvx-exchange.service || { 192 | Log-Error "Failed to start MultiversX xExchange service. Check logs with 'journalctl -u mvx-exchange.service'." 193 | return 1 194 | } 195 | sudo systemctl status mvx-exchange.service --no-pager || { 196 | Log-Error "MultiversX xExchange service is not running as expected. Check logs with 'journalctl -u mvx-exchange.service'." 197 | return 1 198 | } 199 | Log "xExchange started successfully." 200 | } 201 | 202 | # Stop the MultiversX xExchange 203 | xExchange_Stop() { 204 | Log-Step "Stop MultiversX xExchange" 205 | 206 | sudo systemctl stop mvx-exchange.service || { 207 | Log-Error "Failed to stop MultiversX xExchange service. Check logs with 'journalctl -u mvx-exchange.service'." 208 | return 1 209 | } 210 | 211 | sudo systemctl status mvx-exchange.service --no-pager | grep "inactive (dead)" &>/dev/null 212 | if [ $? -eq 0 ]; then 213 | Log "xExchange stopped successfully." 214 | else 215 | Log-Error "xExchange is still running. Please check manually." 216 | return 1 217 | fi 218 | } 219 | # --------- MULTIVERSX API FUNCTIONS --------- 220 | 221 | # Start the MultiversX API 222 | MxApi_Start() { 223 | Log-Step "Start MultiversX API Service" 224 | 225 | local service_name="mvx-api" 226 | 227 | Log-SubStep "Starting MultiversX API using systemctl" 228 | sudo systemctl start "$service_name" || { 229 | Log-Error "Failed to start MultiversX API service. Check logs with 'journalctl -u $service_name'." 230 | return 1 231 | } 232 | 233 | sudo systemctl status "$service_name" --no-pager || { 234 | Log-Error "MultiversX API service is not running as expected. Check logs with 'journalctl -u $service_name'." 235 | return 1 236 | } 237 | 238 | Log "MultiversX API service started successfully." 239 | } 240 | 241 | # Stop the MultiversX API 242 | MxApi_Stop() { 243 | Log-Step "Stop MultiversX API Service" 244 | 245 | local service_name="mvx-api" 246 | 247 | Log-SubStep "Stopping MultiversX API using systemctl" 248 | sudo systemctl stop "$service_name" || { 249 | Log-Error "Failed to stop MultiversX API service. Check logs with 'journalctl -u $service_name'." 250 | return 1 251 | } 252 | 253 | sudo systemctl status "$service_name" --no-pager | grep "inactive (dead)" &>/dev/null 254 | if [ $? -eq 0 ]; then 255 | Log "MultiversX API service stopped successfully." 256 | else 257 | Log-Error "MultiversX API service is still running. Please check manually." 258 | return 1 259 | fi 260 | } 261 | 262 | # Function to check the status of the MultiversX API service 263 | MxApi_Check_Status() { 264 | Log-Step "Check MultiversX API Service Status" 265 | 266 | if systemctl is-active --quiet mvx-api.service; then 267 | Log "MultiversX API service is running." 268 | else 269 | Log-Warning "MultiversX API service is not running." 270 | sudo journalctl -u mvx-api.service --since "5 minutes ago" 271 | fi 272 | } 273 | --------------------------------------------------------------------------------