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?