Skip to main content

Proxy local testing

Prerequisites

  • Ubuntu/Intel

This tutorial presents a flow using an Intel chip with Ubuntu (as of the time of writing, the Solana image does not support alternative operating systems).

  • Browser supporting a MetaMask wallet

This tutorial uses Brave.

Solana provides further details on the recommended minimum requirements.

  • nmap (or equivalent)
important

This example for setting up the local proxy works only with Neon EVM Devnet.

Step 1: Create a docker compose file

Save the following code to a file in your local destination.

docker-compose.yml file content
version: "3"

services:
solana:
container_name: solana
image: neonlabsorg/evm_loader:${NEON_EVM_COMMIT:-v1.7.2}
environment:
SOLANA_URL: http://solana:8899
RUST_LOG: solana_runtime::system_instruction_processor=trace,solana_runtime::message_processor=debug,solana_bpf_loader=debug,solana_rbpf=debug
hostname: solana
expose:
- "8899"
- "9900"
- "8900"
- "8001"
- "8001-8009/udp"
networks:
- net
ports:
- 8899:8899
- 8900:8900
healthcheck:
# Must be available from outside (calling without -u causes premature result)
test: [ CMD-SHELL, "./wait-for-neon.sh" ]
interval: 5s
timeout: 5s
retries: 20
start_period: 5s
entrypoint: /opt/solana-run-neon.sh

neon_test_invoke_program_loader:
container_name: neon_test_invoke_program_loader
image: neonlabsorg/neon_test_invoke_program:develop
environment:
SOLANA_URL: http://solana:8899
networks:
- net
depends_on:
solana:
condition: service_healthy
entrypoint: /opt/neon-test-invoke-program.sh

postgres:
container_name: postgres
image: postgres:15.3
command: postgres -c 'max_connections=1000'
environment:
POSTGRES_DB: neon-db
POSTGRES_USER: neon-proxy
POSTGRES_PASSWORD: neon-proxy-pass
hostname: postgres
healthcheck:
test: [ CMD-SHELL, "pg_isready -h postgres -p 5432" ]
interval: 3s
timeout: 3s
retries: 10
start_period: 5s
expose:
- "5432"
ports:
- "5432"
networks:
- net

dbcreation:
container_name: dbcreation
image: neonlabsorg/proxy:${PROXY_COMMIT:-v1.7.9}
environment:
SOLANA_URL: http://solana:8899
POSTGRES_DB: neon-db
POSTGRES_USER: neon-proxy
POSTGRES_PASSWORD: neon-proxy-pass
POSTGRES_HOST: postgres
entrypoint: /bin/sh
command: proxy/run-dbcreation.sh
networks:
- net
depends_on:
postgres:
condition: service_healthy

proxy:
container_name: proxy
image: neonlabsorg/proxy:${PROXY_COMMIT:-v1.7.9}
environment:
SOLANA_URL: http://solana:8899
FAUCET_URL: http://faucet:3333
PROXY_URL: http://proxy:9090/solana
POSTGRES_DB: neon-db
POSTGRES_USER: neon-proxy
POSTGRES_PASSWORD: neon-proxy-pass
POSTGRES_HOST: postgres
NEON_CLI_DEBUG_LOG: "YES"
FUZZ_FAIL_PCT: 0
GATHER_STATISTICS: "YES"
CONFIG: ci
MIN_OPERATOR_BALANCE_TO_WARN: 4565760000 # = 913152000 * 5 (5 storage accounts) = 4.56576 SOL
MIN_OPERATOR_BALANCE_TO_ERR: 913152000 # = solana rent 131072 (= Rent-exempt minimum: 0.913152 SOL) SOLs to create a storage
PP_SOLANA_URL: ${CI_PP_SOLANA_URL:-https://api.devnet.solana.com}
PYTH_MAPPING_ACCOUNT: ${CI_PYTH_MAPPING_ACCOUNT:-BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2}
GAS_PRICE_SLIPPAGE: 0.3
ENABLE_PRIVATE_API: "NO"
ALLOW_UNDERPRICED_TX_WITHOUT_CHAINID: "YES"
LOG_FULL_OBJECT_INFO: "NO"
EVM_LOADER: 53DfF883gyixYNXnM7s5xhdeyV8mVk9T4i2hGV9vG9io
RUST_BACKTRACE: ${RUST_BACKTRACE:-0}
COMMIT_LEVEL: "Confirmed"
SOLANA_KEY_FOR_EVM_CONFIG: "BMp6gEnveANdvSvspESJUrNczuHz1GF5UQKjVLCkAZih"
hostname: proxy
depends_on:
solana:
condition: service_healthy
dbcreation:
condition: service_completed_successfully
ports:
- 9090:9090
- 8881:8888
expose:
- "8888"
- "9090"
networks:
- net
entrypoint: proxy/run-test-proxy.sh
healthcheck:
test: [ CMD-SHELL, "/opt/health_check_proxy.sh" ]
interval: 5s
timeout: 3s
retries: 20
start_period: 5s

faucet:
container_name: faucet
image: neonlabsorg/faucet:${FAUCET_COMMIT:-v1.7.x}
environment:
FAUCET_RPC_BIND: 0.0.0.0
FAUCET_RPC_PORT: 3333
FAUCET_WEB3_ENABLE: 'true'
WEB3_RPC_URL: http://solana:8899
WEB3_PRIVATE_KEY: 0x4deacb079b4714c38f39508aa8900039f2721ed8686835d43347ba9267da767b
NEON_ERC20_TOKENS: '["0xB521b9F3484deF53545F276F1DAA50ef0Ca82E2d", "0x8a2a66CA0E5D491A001957edD45A6350bC76D708", "0x914782059DC42d4E590aeFCfdbF004B2EcBB9fAA", "0x7A7510b9b18241C788a7aAE8299D1fA6010D8128"]'
NEON_ERC20_MAX_AMOUNT: 1000
FAUCET_SOLANA_ENABLE: 'true'
SOLANA_URL: http://solana:8899
NEON_OPERATOR_KEYFILE: /root/.config/solana/id.json
NEON_ETH_MAX_AMOUNT: 50000
TEST_FAUCET_INIT_NEON_BALANCE: 100000000
EVM_LOADER: 53DfF883gyixYNXnM7s5xhdeyV8mVk9T4i2hGV9vG9io
NEON_TOKEN_MINT: HPsV9Deocecw3GeZv1FkAPNCBRfuVyfw9MMwjwRe1xaU
NEON_TOKEN_MINT_DECIMALS: 9
SOLANA_COMMITMENT: confirmed
RUST_BACKTRACE: ${RUST_BACKTRACE:-0}
hostname: faucet
ports:
- 3333:3333
expose:
- "3333"
networks:
- net
entrypoint: ./run-test-faucet.sh
depends_on:
solana:
condition: service_healthy

indexer:
container_name: indexer
image: neonlabsorg/proxy:${PROXY_COMMIT:-v1.7.9}
environment:
SOLANA_URL: http://solana:8899
POSTGRES_DB: neon-db
POSTGRES_USER: neon-proxy
POSTGRES_PASSWORD: neon-proxy-pass
POSTGRES_HOST: postgres
POSTGRES_TIMEOUT: 5
GATHER_STATISTICS: "YES"
LOG_FULL_OBJECT_INFO: "NO"
CONFIG: ci
EVM_LOADER: 53DfF883gyixYNXnM7s5xhdeyV8mVk9T4i2hGV9vG9io
START_SLOT: latest
REINDEX_START_SLOT: continue
hostname: indexer
depends_on:
solana:
condition: service_healthy
dbcreation:
condition: service_completed_successfully
expose:
- "8887"
ports:
- 8882:8888
networks:
- net
entrypoint: proxy/run-indexer.sh

networks:
net:

In case you want to use a remote Solana node, change the SOLANA_URL value to its URL.

Step 2: Configure environment variables

Set the following optional variables to "latest" to work with the Docker image's latest settings. If a variable is not specified, the version 1.7 of the corresponding component is used by default.

Run the commands:

export NEON_EVM_COMMIT=latest; export PROXY_COMMIT=latest; export FAUCET_COMMIT=latest

Step 3: Run the Docker containers

Use the docker compose file created in the Step 1 to pull and run the docker containers:

3.1 Pull the Docker images:

docker-compose -f /path/to/docker-compose.yml pull

3.2 Start the proxy with:

docker-compose -f /path/to/docker-compose.yml up

Let's check the status of our containers with:

docker stats

Congratulations, you are now running Neon EVM deployed to a single, local node of Solana.

tip

When you are at the point where you are willing to lose your data, then free your disk space and close the instance by running:

docker-compose -f /path/to/docker-compose.yml down

Step 4: Set up MetaMask wallet to run with the local proxy

Set up your MetaMask wallet with the proxy:

Tip:

Run nmap, or equivalent, to view the ports the services are running on:

nmap localhost

The port 9090 is our proxy and 3333 is our faucet.

From your browser's MetaMask extension, set the localhost as a network within the MetaMask wallet, click: Settings > Networks > Add a Network > Add a network manually

4.2 Fill out the following fields:

And click Save.

Step 5: Use the faucet to populate your wallet with NEON tokens

5.1 Copy your account address from your MetaMask wallet and update the following script to use your address:

file: drop_neons.sh

#!/usr/bin/env bash

if [ -z "$1" ]; then
echo "Usage: drop_neons.sh <wallet-address>"
exit 1
fi

/usr/bin/curl --location --request POST 'http://localhost:3333/request_neon' \
--header 'Content-Type: application/json' \
--data-raw '{
"wallet": "'${1}'",
"amount": 1000
}'

5.2 From your terminal, at the file location run sh ./drop_neons.sh {wallet address}.

Gotchas

  • It is recommended that you have a couple of terabytes of free space! Should you want to run your node with persistent data, the space requirements will grow.
  • The MetaMask Wallet may not update automatically:

Neon Localhost to force a refresh after using the faucet

  • It is only possible to set up the localhost network in the MetaMask wallet while the proxy service is running.
  • If you are following best practice, and adding your user to the docker group to avoid running Docker as root or sudo, then restart to apply the update.

What next?

Congratulations you can now deploy and test smart contracts on the NeonEVM. Consider:

Was this page helpful?