A development environment for cross-chain bridge development between NeoX and NeoN3 blockchains.
- Overview
- Prerequisites
- Clone the repository (with submodules)
- Quick Start
- Funding Accounts
- Check Node Availability
- Deployment of EVM Message Bridge Contracts
- Additional Tools
This project provides a complete development stack with:
- NeoX Node: Ethereum-compatible blockchain node with dBFT consensus
- NeoN3 Node: Neo N3 blockchain node for cross-chain operations
- RabbitMQ: Message broker for inter-service communication
- Docker & Docker Compose
-
First-time clone:
git clone --recurse-submodules https://github.com/AxLabs/neox-bridge-devnet.git cd neox-bridge-devnet -
If you already cloned without submodules:
git submodule update --init --recursive
-
Navigate to the project directory:
cd neox-bridge-devnet -
Start all services:
docker compose up
-
Access the services:
- NeoX RPC: http://localhost:8562
- NeoN3 RPC: http://localhost:40332
- RabbitMQ Management UI: http://localhost:15672 (admin/admin123)
- RabbitMQ AMQP URL: amqp://admin:admin123@localhost:5672/
-
Stop all services:
docker compose down
To remove volumes (reset blockchain data):
docker compose down -v
To fund accounts on NeoX, you can use the tools/funding/neox-funding.csv to add addresses and amounts. The funding will be processed automatically after the NeoX node starts, by the neox-funding service.
- Note: When the bridges are funded, the personal wallet is also funded with the NEO token on NeoX.
Optionally, you can invoke again the funding script manually if needed:
docker compose up -d neox-fundingNote that running the funding script multiple times will fund all the addresses in tools/funding/neox-funding.csv as well as the default accounts only if they have less balance than the GAS_AMOUNT env variable.
To fund accounts on NeoN3, you must now specify both the GAS_AMOUNT and the NEO_AMOUNT environment variables for the neon3-funding service. The funding will be processed automatically after the NeoN3 node starts, and it will also fund all the wallets in the /tools/neon3-funding/neon3-wallets directory.
- Both GAS and NEO tokens are funded.
- The NEO amount is now a required parameter.
- The script will only fund a wallet if its GAS balance is below the
GAS_AMOUNTor its NEO balance is below theNEO_AMOUNT. - The docker-compose command for neon3-funding now explicitly sets the NEO amount as the third parameter.
- If you run the funding service multiple times, it will only top up wallets that are below the specified thresholds for either token.
Optionally, you can invoke the funding script manually if needed:
docker compose up -d neon3-fundingNote:
- Both
GAS_AMOUNTandNEO_AMOUNTmust be set and must be valid numbers. - The script will validate these parameters and fail early if they are missing or invalid.
- The script now provides clear error messages and debug output if there are issues with the funding process.
To verify that the nodes are up and responding via RPC:
curl -X POST --json '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' http://localhost:8562curl -s -X POST --json '{"jsonrpc" : "2.0", "id": 1, "method": "getblockcount", "params":[] }' http://localhost:40332The EVM contracts are deployed automatically when the neox-contracts service starts. It uses the wallets in the tools/neox-funding/neox-wallets folder to deploy the contracts. The deployment logs can be found in the neox-contracts service logs.
The service can also be run manually if it did not start automatically. This service depends on the NeoX node being operational and the deployer wallet having sufficient funds:
docker compose up -d neox-contractsThe NeoN3 contracts are deployed automatically when the neon3-contracts service starts. It uses the wallets in the tools/neon3-funding/neon3-wallets folder to deploy the contracts. The deployment logs can be found in the neon3-contracts service logs.
The service can also be run manually if it did not start automatically. This service depends on the NeoN3 node being operational and the deployer wallet having sufficient funds:
docker compose up -d neon3-contractsIf you make changes to the contracts and want to deploy them again, you can follow these steps:
-
Stop all the services:
docker compose down -v
-
Checkout the desired branch or make changes to the contracts repos.
-
Update the service definitions and commands
Make sure that the correct deployment script is invoked by the
neox-contractsandneon3-contractsservices. Ensure that all expected environment variables are correctly set and any required volumes are correctly mounted.The scripts used for deployment are located as follows:q
-
Start the services again:
docker compose up -d
To send messages from NeoX to NeoN3, use scripts in tools/send-from-evm. The default wallet is deployer, override with PERSONAL_WALLET_FILENAME. Wallets must exist in bridge-evm-contracts/wallets (auto-copied from tools/neox-funding/neox-wallets if missing).
If the wallet has insufficient funds, the script will fail. Fund the wallet beforehand (see Funding Accounts).
./tools/send-from-evm/send-string.sh <message> [network]<message>: String message to send (required).[network]: Target NeoN3 network (optional, default:neoxDevnet).
Environment Variables:
PERSONAL_WALLET_FILENAME: Wallet name (default: deployer)
./tools/send-from-evm/send-n3-script.sh <script_hex> [store_result] [network]<script_hex>: Hex-encoded NeoN3 script (required).[store_result]: Store result (trueorfalse, default:true).[network]: Target NeoN3 network (optional, default:neoxDevnet).
N3 scripts are always sent as executable messages.
Environment Variables:
- Same as above.
./tools/send-from-evm/send-message.sh [OPTIONS]Options:
-a, --address ADDRESS: MessageBridge contract address (auto-loaded fromtools/addresses/neox-addresses.json)-t, --type TYPE: Message type (executableorstore-only, default:store-only)-d, --data DATA: Raw hex message data, string message, or NeoN3 script bytes-s, --store-result BOOL: Store result for executable messages (default: true)-n, --network NETWORK: Hardhat network (default: neoxDevnet)-h, --help: Show help
Environment Variables:
PERSONAL_WALLET_FILENAME
Notes:
- MessageBridge address is auto-loaded if not provided.
- Wallets are auto-copied if missing.
- If you encounter issues, check script output and verify wallet balances and environment variables.
Use scripts in tools/send-from-neo. The default wallet is deployer, override with SENDER_WALLET. Wallets must exist in bridge-neo-contracts/wallets (auto-copied from tools/neon3-funding/neon3-wallets if missing).
If the wallet has insufficient funds, the script will fail. Fund the wallet beforehand (see Funding Accounts).
./tools/send-from-neo/send-string.sh <message> [node_url]<message>: String message to send (required).[node_url]: NeoN3 RPC endpoint URL (optional, default: http://127.0.0.1:40332).
Environment Variables:
SENDER_WALLET: User wallet JSON file (default:deployerit refers towallets/deployer.json)SENDER_WALLET_PASSWORD: Wallet password
./tools/send-from-neo/send-evm-call.sh <evm_data_hex> [store_result] [node_url]<evm_data_hex>: Hex-encoded EVM contract call data (required).[store_result]: Store result (trueorfalse, default:true).[node_url]: NeoN3 RPC endpoint URL (optional, default: http://127.0.0.1:40332).
Environment Variables:
- Same as above.
./tools/send-from-neo/send-message.sh [OPTIONS]Options:
-a, --address ADDRESS: MessageBridge contract hash (auto-loaded fromtools/addresses/n3-addresses.json)-t, --type TYPE: Message type (executableorstore-only, default:store-only)-d, --data DATA: Raw hex message data, string message, or EVM contract call data-f, --fee-sponsor HASH160: Fee sponsor hash160 (optional)-s, --store-result BOOL: Store result for executable messages (default: true)-n, --node URL: NeoN3 RPC endpoint URL (default: http://127.0.0.1:40332)-h, --help: Show help
Environment Variables:
- Same as above.
Notes:
- MessageBridge hash is auto-loaded if not provided.
- Wallets are auto-copied if missing.
- If you encounter issues, check script output and verify your environment variables and wallet balances.
The tools/bridge-examples-ts directory provides TypeScript scripts for interacting with the MessageBridge contract. These examples use the bridge-sdk-ts library and cover common operations such as sending messages, executing contract calls, and querying contract state.
For setup and usage instructions, see the bridge-examples-ts README.