Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions cmd/nigiri/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ var arkFlag = cli.BoolFlag{
//go:embed resources/bitcoin.conf
//go:embed resources/elements.conf
//go:embed resources/lnd.conf
//go:embed resources/esplora-relay.conf
var f embed.FS

func main() {
Expand Down Expand Up @@ -152,6 +153,10 @@ func provisionResourcesToDatadir(datadir string) error {
filepath.Join(datadir, "volumes", "ark", "wallet"),
filepath.Join(datadir, "volumes", "nbxplorer"),
filepath.Join(datadir, "volumes", "postgres"),
filepath.Join(datadir, "volumes", "fulcrum"),
filepath.Join(datadir, "volumes", "mempool-mariadb"),
filepath.Join(datadir, "volumes", "mempool-api"),
filepath.Join(datadir, "volumes", "esplora-relay"),
}

for _, dir := range volumeDirs {
Expand Down Expand Up @@ -200,6 +205,16 @@ func provisionResourcesToDatadir(datadir string) error {
return err
}

// copy esplora-relay nginx config so chopsticks can hit mempool-api's /api/* surface
if err := copyFromResourcesToDatadir(
filepath.Join("resources", "esplora-relay.conf"),
filepath.Join(datadir, "volumes", "esplora-relay", "default.conf"),
uid,
gid,
); err != nil {
return err
}

if err := nigiriState.Set(map[string]string{"ready": strconv.FormatBool(true)}); err != nil {
return err
}
Expand Down
143 changes: 110 additions & 33 deletions cmd/nigiri/resources/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,36 +32,108 @@ services:
- ./volumes/elements/:/config
restart: unless-stopped

# Block explorer server
electrs:
image: ghcr.io/vulpemventures/electrs:latest
container_name: electrs
entrypoint:
- /build/electrs
# Bitcoin Electrum protocol server
fulcrum:
image: cculianu/fulcrum:latest
container_name: fulcrum
depends_on:
- bitcoin
command:
- -vvvv
- --network
- regtest
- --daemon-dir
- /config
- --daemon-rpc-addr
- Fulcrum
- --datadir
- /data
- --bitcoind
- bitcoin:18443
- --cookie
- admin1:123
- --http-addr
- 0.0.0.0:30000
- --electrum-rpc-addr
- 0.0.0.0:50000
- --cors
- "*"
- --jsonrpc-import
- --rpcuser
- admin1
- --rpcpassword
- "123"
- --tcp
- 0.0.0.0:50001
- --ws
- 0.0.0.0:50003
- --peering
- "0"
- --announce
- "0"
ports:
- 50000:50001
- 50003:50003
volumes:
- ./volumes/fulcrum:/data
restart: unless-stopped

# MariaDB backing store for mempool-api
mempool-mariadb:
image: mariadb:10.5
container_name: mempool-mariadb
environment:
MYSQL_DATABASE: mempool
MYSQL_USER: mempool
MYSQL_PASSWORD: mempool
MYSQL_ROOT_PASSWORD: moneyprintergobrrr
volumes:
- ./volumes/mempool-mariadb:/var/lib/mysql
restart: unless-stopped

# mempool API — serves esplora-compatible REST under /api/*
mempool-api:
image: mempool/backend:v3.2.1
container_name: mempool-api
user: "${UID:-1000}:${GID:-1000}"
init: true
depends_on:
- mempool-mariadb
- fulcrum
- bitcoin
command: "./wait-for-it.sh mempool-mariadb:3306 --timeout=720 --strict -- ./start.sh"
environment:
# Bitcoin Core RPC (regtest)
CORE_RPC_HOST: "bitcoin"
CORE_RPC_PORT: "18443"
CORE_RPC_USERNAME: "admin1"
CORE_RPC_PASSWORD: "123"
CORE_RPC_TIMEOUT: "120000"
# Electrum backend (Fulcrum)
MEMPOOL_BACKEND: "electrum"
ELECTRUM_HOST: "fulcrum"
ELECTRUM_PORT: "50001"
ELECTRUM_TLS_ENABLED: "false"
# Database
DATABASE_ENABLED: "true"
DATABASE_HOST: "mempool-mariadb"
DATABASE_PORT: "3306"
DATABASE_DATABASE: "mempool"
DATABASE_USERNAME: "mempool"
DATABASE_PASSWORD: "mempool"
DATABASE_TIMEOUT: "300000"
# Mempool core
MEMPOOL_NETWORK: "regtest"
MEMPOOL_HTTP_PORT: "8999"
MEMPOOL_CACHE_DIR: "/backend/cache"
MEMPOOL_CACHE_ENABLED: "true"
MEMPOOL_INDEXING_BLOCKS_AMOUNT: "-1"
MEMPOOL_POLL_RATE_MS: "2000"
MEMPOOL_ALLOW_UNREACHABLE: "true"
STATISTICS_ENABLED: "false"
LIGHTNING_ENABLED: "false"
volumes:
- ./volumes/mempool-api:/backend/cache
ports:
- 50000:50000
- 30000:30000
- 8999:8999
restart: unless-stopped

# nginx relay: rewrites unprefixed paths to /api/* so chopsticks (and any
# legacy esplora-style client) keep working unchanged against mempool-api.
esplora-relay:
image: nginx:alpine
container_name: esplora-relay
depends_on:
- mempool-api
volumes:
- ./volumes/bitcoin/:/config
- ./volumes/esplora-relay/default.conf:/etc/nginx/conf.d/default.conf:ro
ports:
- 30000:80
restart: unless-stopped

electrs-liquid:
Expand Down Expand Up @@ -97,16 +169,21 @@ services:
- ./volumes/elements/:/config
restart: unless-stopped

# Block explorer frontend
esplora:
image: ghcr.io/vulpemventures/esplora:latest
container_name: esplora
# Block explorer frontend (mempool)
mempool-web:
image: mempool/frontend:v3.2.1
container_name: mempool-web
user: "${UID:-1000}:${GID:-1000}"
init: true
depends_on:
- chopsticks
- mempool-api
command: "./wait-for mempool-mariadb:3306 --timeout=720 -- nginx -g 'daemon off;'"
environment:
API_URL: http://localhost:3000
FRONTEND_HTTP_PORT: "80"
BACKEND_MAINNET_HTTP_HOST: "mempool-api"
BACKEND_MAINNET_HTTP_PORT: "8999"
ports:
- 5000:5000
- 5000:80
restart: unless-stopped

esplora-liquid:
Expand All @@ -131,12 +208,12 @@ services:
- --rpc-addr
- bitcoin:18443
- --electrs-addr
- electrs:30000
- esplora-relay:80
- --addr
- 0.0.0.0:3000
depends_on:
- bitcoin
- electrs
- esplora-relay
ports:
- 3000:3000
restart: unless-stopped
Expand Down
15 changes: 15 additions & 0 deletions cmd/nigiri/resources/esplora-relay.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
server {
listen 80 default_server;

# chopsticks (and any legacy esplora client) sends unprefixed paths like
# /address/:addr/utxo or /tx/:txid. mempool-api serves the same surface
# under /api/*, so we prepend the prefix and proxy through.
location / {
rewrite ^(.*)$ /api$1 break;
proxy_pass http://mempool-api:8999;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
}
}
21 changes: 19 additions & 2 deletions cmd/nigiri/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,16 +122,26 @@ func startAction(ctx *cli.Context) error {
}
}

bitcoinExplorerStack := []string{
"bitcoin",
"fulcrum",
"mempool-mariadb",
"mempool-api",
"esplora-relay",
"chopsticks",
}

var services []string

if effectiveFlags.Ci {
services = []string{"bitcoin", "electrs", "chopsticks"}
services = append(services, bitcoinExplorerStack...)

if effectiveFlags.Liquid {
services = append(services, "liquid", "electrs-liquid", "chopsticks-liquid")
}
} else {
services = []string{"bitcoin", "electrs", "chopsticks", "esplora"}
services = append(services, bitcoinExplorerStack...)
services = append(services, "mempool-web")

if effectiveFlags.Liquid {
services = append(services, "liquid", "electrs-liquid", "chopsticks-liquid", "esplora-liquid")
Expand Down Expand Up @@ -185,6 +195,13 @@ func startAction(ctx *cli.Context) error {
}

filteredEndpoints[name] = endpoint

// fulcrum exposes both TCP Electrum (the auto-derived endpoint above)
// and WebSocket Electrum on a second port. Surface the WS URL with an
// explicit scheme so users know not to point HTTP clients at it.
if name == "fulcrum" {
filteredEndpoints["fulcrum (ws)"] = "ws://localhost:50003"
}
}

// Display endpoints
Expand Down
24 changes: 15 additions & 9 deletions internal/docker/mock_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,13 @@ func (m *MockClient) GetEndpoints(composePath string) (map[string]string, error)
}
// Default mock endpoints
return map[string]string{
"bitcoin": "localhost:18443",
"electrs": "localhost:3002",
"esplora": "localhost:3000",
"chopsticks": "localhost:3000",
"ark": "localhost:7070",
"bitcoin": "localhost:18443",
"fulcrum": "localhost:50000",
"mempool-api": "localhost:8999",
"mempool-web": "localhost:5000",
"esplora-relay": "localhost:30000",
"chopsticks": "localhost:3000",
"ark": "localhost:7070",
}, nil
}

Expand All @@ -72,10 +74,14 @@ func (m *MockClient) GetPortsForService(composePath string, serviceName string)
switch serviceName {
case "bitcoin":
return []string{"18443"}, nil
case "electrs":
return []string{"3002"}, nil
case "esplora":
return []string{"3000"}, nil
case "fulcrum":
return []string{"50000", "50003"}, nil
case "mempool-api":
return []string{"8999"}, nil
case "mempool-web":
return []string{"5000"}, nil
case "esplora-relay":
return []string{"30000"}, nil
case "chopsticks":
return []string{"3000"}, nil
case "ark":
Expand Down
Loading
Loading