mirror of
https://github.com/LORDBABUINO/stealth.git
synced 2026-06-09 06:11:52 -07:00
feat(docs): add docs for api package
This commit is contained in:
+3
-1
@@ -12,4 +12,6 @@ dist/
|
||||
.qwen
|
||||
**/__pycache__/
|
||||
target/
|
||||
Cargo.lock
|
||||
Cargo.lock
|
||||
bitcoin.conf
|
||||
.bitcoin-regtest
|
||||
|
||||
@@ -31,6 +31,7 @@ Stealth ships a Rust workspace with:
|
||||
|
||||
- `stealth-engine` (analysis engine)
|
||||
- `stealth-model` (domain model types and interfaces)
|
||||
- `stealth-api` (http api)
|
||||
- `stealth-bitcoincore` (Bitcoin Core RPC gateway adapter)
|
||||
|
||||
## Project Direction
|
||||
@@ -162,36 +163,94 @@ Stealth currently runs **12 detectors** in `stealth-engine`.
|
||||
```bash
|
||||
git clone https://github.com/stealth-bitcoin/stealth.git
|
||||
cd stealth
|
||||
cargo build
|
||||
```
|
||||
|
||||
### 2. Configure blockchain connection
|
||||
### 2. Configure Bitcoin Core RPC (regtest)
|
||||
|
||||
Edit:
|
||||
|
||||
```
|
||||
backend/script/config.ini
|
||||
```
|
||||
|
||||
### 3. Development setup (regtest)
|
||||
|
||||
A regtest environment is provided for development and reproducible testing of heuristics.
|
||||
Create a local `bitcoin.conf`:
|
||||
|
||||
```bash
|
||||
cd backend/script
|
||||
./setup.sh
|
||||
cat > bitcoin.conf <<'EOF'
|
||||
regtest=1
|
||||
server=1
|
||||
daemon=1
|
||||
txindex=1
|
||||
listen=0
|
||||
[regtest]
|
||||
rpcbind=127.0.0.1
|
||||
rpcallowip=127.0.0.1
|
||||
rpcuser=localuser
|
||||
rpcpassword=localpass
|
||||
rpcport=18443
|
||||
fallbackfee=0.0002
|
||||
EOF
|
||||
```
|
||||
|
||||
### 4. Generate sample transactions
|
||||
### 3. Start Bitcoin Core
|
||||
|
||||
Regtest example:
|
||||
|
||||
```bash
|
||||
python3 reproduce.py
|
||||
mkdir -p "$PWD/.bitcoin-regtest"
|
||||
bitcoind -datadir="$PWD/.bitcoin-regtest" -conf="$PWD/bitcoin.conf" -daemon
|
||||
```
|
||||
|
||||
### 5. Start backend
|
||||
Mainnet example:
|
||||
|
||||
```bash
|
||||
cd backend/src/StealthBackend
|
||||
./mvnw quarkus:dev
|
||||
bitcoind -daemon
|
||||
```
|
||||
|
||||
### 4. Start the API
|
||||
|
||||
```bash
|
||||
STEALTH_RPC_URL=http://127.0.0.1:18443 \
|
||||
STEALTH_RPC_USER=localuser \
|
||||
STEALTH_RPC_PASS=localpass \
|
||||
cargo run --bin stealth-api
|
||||
```
|
||||
|
||||
`stealth-api` auto-detects common local RPC ports and can use credentials from `bitcoin.conf`, cookie file, or env vars.
|
||||
|
||||
### 5. Run a usable scan request
|
||||
|
||||
```bash
|
||||
DATADIR="$PWD/.bitcoin-regtest"
|
||||
CONF="$PWD/bitcoin.conf"
|
||||
RPC="bitcoin-cli -datadir=$DATADIR -conf=$CONF -regtest -rpcport=18443"
|
||||
API_PORT=20899
|
||||
|
||||
mkdir -p "$DATADIR"
|
||||
if ! $RPC getblockchaininfo >/dev/null 2>&1; then
|
||||
bitcoind -datadir="$DATADIR" -conf="$CONF" -daemon
|
||||
fi
|
||||
|
||||
for _ in $(seq 1 100); do
|
||||
if $RPC getblockchaininfo >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 0.2
|
||||
done
|
||||
|
||||
STEALTH_RPC_URL=http://127.0.0.1:18443 \
|
||||
STEALTH_RPC_USER=localuser \
|
||||
STEALTH_RPC_PASS=localpass \
|
||||
STEALTH_API_BIND=127.0.0.1:$API_PORT \
|
||||
cargo run --bin stealth-api >/tmp/stealth-api.log 2>&1 &
|
||||
API_PID=$!
|
||||
trap 'kill $API_PID >/dev/null 2>&1 || true' EXIT
|
||||
|
||||
WALLET="scanwallet_$(date +%s)"
|
||||
$RPC createwallet "$WALLET" >/dev/null
|
||||
TARGET_ADDR="$($RPC -rpcwallet="$WALLET" getnewaddress)"
|
||||
$RPC generatetoaddress 101 "$TARGET_ADDR" >/dev/null
|
||||
|
||||
DESC="$($RPC -rpcwallet="$WALLET" getaddressinfo "$TARGET_ADDR" | jq -r '.desc')"
|
||||
|
||||
curl -s "http://127.0.0.1:$API_PORT/api/wallet/scan" -H 'content-type: application/json' -d "{\"descriptor\":\"$DESC\"}" | jq
|
||||
|
||||
$RPC stop
|
||||
```
|
||||
|
||||
### 6. Start frontend
|
||||
@@ -232,6 +291,10 @@ stealth/
|
||||
│ │ └── bitcoin-data/ # Regtest chain data (gitignored)
|
||||
│ └── src/StealthBackend/ # Quarkus Java REST API (single /api/wallet/scan endpoint)
|
||||
└── slides/ # Slidev pitch presentation
|
||||
├── api/ # stealth-api (Axum HTTP layer)
|
||||
│ ├── src/
|
||||
│ └── tests/
|
||||
└── target/ # Cargo build outputs
|
||||
```
|
||||
|
||||
### Test Coverage
|
||||
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
# Stealth API
|
||||
|
||||
`stealth-api` is the Rust HTTP transport layer for Stealth. It connects to a
|
||||
running `bitcoind` via JSON-RPC, imports descriptors into temporary wallets,
|
||||
builds a transaction graph, and runs privacy detectors from
|
||||
`stealth-engine`.
|
||||
|
||||
## Running
|
||||
|
||||
```bash
|
||||
# Stop any old API process, then start the current source build
|
||||
pkill -f 'target/debug/stealth-api' 2>/dev/null || true
|
||||
|
||||
# Auto-detects local bitcoind RPC port (prefers 18443, then 8332/18332/38332)
|
||||
# and uses credentials from bitcoin.conf or local cookie files.
|
||||
cargo run --bin stealth-api
|
||||
```
|
||||
|
||||
Set auth explicitly with username/password:
|
||||
|
||||
```bash
|
||||
STEALTH_RPC_URL=http://127.0.0.1:8332 \
|
||||
STEALTH_RPC_USER=user \
|
||||
STEALTH_RPC_PASS=pass \
|
||||
cargo run --bin stealth-api
|
||||
```
|
||||
|
||||
Or use a cookie file:
|
||||
|
||||
```bash
|
||||
STEALTH_RPC_URL=http://127.0.0.1:8332 \
|
||||
STEALTH_RPC_COOKIE=~/.bitcoin/.cookie \
|
||||
cargo run --bin stealth-api
|
||||
```
|
||||
|
||||
Configure the listen address with `STEALTH_API_BIND` (default `127.0.0.1:20899`).
|
||||
|
||||
If you see `Connection refused (os error 111)`, either:
|
||||
1. an old `stealth-api` process is still running, or
|
||||
2. `bitcoind` RPC is not reachable on the detected/configured URL.
|
||||
|
||||
## API
|
||||
|
||||
### `POST /api/wallet/scan`
|
||||
|
||||
Accepts one mutually-exclusive source:
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `descriptor` | `string` | Single output descriptor |
|
||||
| `descriptors` | `string[]` | Multiple descriptors |
|
||||
| `utxos` | `UtxoInput[]` | Raw UTXO set |
|
||||
|
||||
**Descriptor scan flow:** creates a blank watch-only wallet, imports the
|
||||
descriptor(s) with a full blockchain rescan, builds a `TxGraph`, runs all
|
||||
17 detectors, then cleans up the temporary wallet.
|
||||
|
||||
**UTXO scan flow:** resolves each UTXO's address from the node, builds a
|
||||
partial transaction graph, and runs applicable detectors.
|
||||
|
||||
#### Example (real descriptor from Bitcoin Core)
|
||||
|
||||
```bash
|
||||
RPC="bitcoin-cli -regtest -rpcport=18443 -rpcuser=localuser -rpcpassword=localpass"
|
||||
WALLET="scanwallet_$(date +%s)"
|
||||
|
||||
$RPC createwallet "$WALLET" >/dev/null
|
||||
ADDR="$($RPC -rpcwallet="$WALLET" getnewaddress)"
|
||||
DESC="$($RPC -rpcwallet="$WALLET" getaddressinfo "$ADDR" | jq -r '.desc')"
|
||||
|
||||
curl 'http://localhost:20899/api/wallet/scan' \
|
||||
-H 'content-type: application/json' \
|
||||
-d "{\"descriptor\":\"$DESC\"}" | jq
|
||||
```
|
||||
|
||||
#### Responses
|
||||
|
||||
| Status | Meaning |
|
||||
|--------|---------|
|
||||
| `200` | Scan completed — body is a `Report` |
|
||||
| `400` | Invalid input (bad descriptor shape, empty UTXOs, …) |
|
||||
| `502` | bitcoind RPC unavailable/auth failed/connection failed |
|
||||
|
||||
## Environment variables
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `STEALTH_API_BIND` | Listen address (default `127.0.0.1:20899`) |
|
||||
| `STEALTH_RPC_URL` | bitcoind RPC endpoint (overrides auto-detection) |
|
||||
| `STEALTH_RPC_USER` | RPC username (otherwise read from `bitcoin.conf` when available) |
|
||||
| `STEALTH_RPC_PASS` | RPC password (otherwise read from `bitcoin.conf` when available) |
|
||||
| `STEALTH_RPC_COOKIE` | Path to `.cookie` file (otherwise API auto-detects common local cookie locations) |
|
||||
|
||||
## E2E test (regtest)
|
||||
|
||||
The API includes an end-to-end regtest integration test that:
|
||||
1. creates wallets,
|
||||
2. gets a real descriptor from `bitcoind`,
|
||||
3. scans once with no history (`summary.clean = true`),
|
||||
4. creates/mine transactions,
|
||||
5. scans again and asserts findings (`summary.clean = false`).
|
||||
|
||||
Run it with:
|
||||
|
||||
```bash
|
||||
cargo test -p stealth-api scan_descriptor_clean_then_findings_after_regtest_activity -- --nocapture
|
||||
```
|
||||
@@ -0,0 +1,8 @@
|
||||
server=1
|
||||
rpcuser=localuser
|
||||
rpcpassword=localpass
|
||||
|
||||
[regtest]
|
||||
rpcbind=127.0.0.1
|
||||
rpcallowip=127.0.0.1
|
||||
rpcport=18443
|
||||
Reference in New Issue
Block a user