chore: consolidate local WIP (repo cleanup 20260707)
All checks were successful
CI / lint-and-test (push) Successful in 9m52s

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
defiQUG
2026-07-07 09:41:38 -07:00
parent c94eb595f8
commit a03417be98
121 changed files with 4253 additions and 1750 deletions

142
scripts/audit-env.sh Executable file
View File

@@ -0,0 +1,142 @@
#!/usr/bin/env bash
# Audit required and optional credentials across workspace dotenv files.
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
ok() { echo -e "${GREEN}${NC} $1"; }
warn() { echo -e "${YELLOW}⚠️${NC} $1"; }
fail() { echo -e "${RED}${NC} $1"; }
is_placeholder() {
local v="$1"
[[ -z "$v" ]] && return 0
[[ "$v" == *replace_me* ]] && return 0
[[ "$v" == *your_* ]] && return 0
[[ "$v" == *temp_* ]] && return 0
return 1
}
read_env() {
local file="$1"
local key="$2"
[[ -f "$file" ]] || { echo ""; return; }
grep -E "^${key}=" "$file" 2>/dev/null | head -1 | cut -d= -f2- | sed 's/^"//;s/"$//' || true
}
echo "=== Solace Treasury — Environment Audit ==="
echo ""
# Frontend
FE="$ROOT/frontend/.env.local"
echo "## Frontend ($FE)"
for key in NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID NEXT_PUBLIC_CHAIN138_RPC_URL NEXT_PUBLIC_TREASURY_WALLET_ADDRESS NEXT_PUBLIC_SUB_ACCOUNT_FACTORY_ADDRESS NEXT_PUBLIC_API_URL; do
val=$(read_env "$FE" "$key")
if is_placeholder "$val"; then
if [[ "$key" == "NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID" ]]; then
warn "$key optional (Injected/MetaMask work without it)"
else
fail "$key missing or placeholder"
fi
else
ok "$key set"
fi
done
# Backend
BE="$ROOT/backend/.env"
echo ""
echo "## Backend ($BE)"
for key in DATABASE_URL RPC_URL CHAIN_ID CONTRACT_ADDRESS FACTORY_ADDRESS; do
val=$(read_env "$BE" "$key")
if is_placeholder "$val"; then
fail "$key missing or placeholder"
else
ok "$key set"
fi
done
IDX="$ROOT/backend/.env.indexer"
echo ""
echo "## Indexer ($IDX)"
if [[ -f "$IDX" ]]; then
for key in CONTRACT_ADDRESS START_BLOCK RPC_URL; do
val=$(read_env "$IDX" "$key")
if is_placeholder "$val"; then
warn "$key missing in .env.indexer (falls back to backend/.env)"
else
ok "$key set"
fi
done
else
warn ".env.indexer not found"
fi
# Contracts
CE="$ROOT/contracts/.env"
echo ""
echo "## Contracts ($CE)"
for key in CHAIN138_RPC_URL PRIVATE_KEY; do
val=$(read_env "$CE" "$key")
if is_placeholder "$val"; then
fail "$key missing or placeholder"
else
ok "$key set"
fi
done
# Address alignment
DEPLOY="$ROOT/contracts/deployments/chain138.json"
if [[ -f "$DEPLOY" && -f "$BE" ]]; then
echo ""
echo "## Deployment alignment"
DEPLOY_TREASURY=$(jq -r '.contracts.TreasuryWallet' "$DEPLOY" | tr '[:upper:]' '[:lower:]')
ENV_TREASURY=$(read_env "$BE" CONTRACT_ADDRESS | tr '[:upper:]' '[:lower:]')
if [[ -n "$DEPLOY_TREASURY" && "$DEPLOY_TREASURY" == "$ENV_TREASURY" ]]; then
ok "CONTRACT_ADDRESS matches chain138.json"
else
warn "CONTRACT_ADDRESS drift — run ./scripts/sync-env-from-deployment.sh"
fi
fi
# Connectivity
echo ""
echo "## Connectivity"
RPC=$(read_env "$BE" RPC_URL)
RPC="${RPC:-http://192.168.11.211:8545}"
if curl -sf -m 3 -X POST "$RPC" -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' | grep -q '"0x8a"'; then
ok "Chain 138 RPC reachable ($RPC)"
else
fail "Chain 138 RPC unreachable ($RPC)"
fi
DB=$(read_env "$BE" DATABASE_URL)
if [[ -n "$DB" ]]; then
if command -v psql >/dev/null && psql "$DB" -c "SELECT 1;" >/dev/null 2>&1; then
ok "PostgreSQL reachable"
else
warn "PostgreSQL not reachable (use local Docker or Proxmox CT 3002)"
fi
fi
API=$(read_env "$FE" NEXT_PUBLIC_API_URL)
API="${API:-http://localhost:3001}"
if curl -sf -m 3 "$API/health" | grep -q '"status"'; then
ok "Backend API reachable ($API)"
else
warn "Backend API not reachable ($API) — run pnpm run dev"
fi
if [[ -f "$DEPLOY" ]]; then
ok "Chain138 deployment record present"
else
warn "No contracts/deployments/chain138.json — run deploy:chain138"
fi
echo ""
echo "Run ./scripts/sync-env-from-deployment.sh after deploy to propagate addresses."

View File

@@ -1,39 +1,33 @@
#!/bin/bash
#!/usr/bin/env bash
# Setup verification script
# Checks if all required dependencies and configurations are in place
set -e
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT"
echo "🔍 Checking Solace Treasury DApp setup..."
echo ""
# Check Node.js
if command -v node &> /dev/null; then
NODE_VERSION=$(node --version)
echo "✅ Node.js: $NODE_VERSION"
echo "✅ Node.js: $(node --version)"
else
echo "❌ Node.js not found. Please install Node.js >= 18.0.0"
exit 1
fi
# Check pnpm
if command -v pnpm &> /dev/null; then
PNPM_VERSION=$(pnpm --version)
echo "✅ pnpm: $PNPM_VERSION"
echo "✅ pnpm: $(pnpm --version)"
else
echo "❌ pnpm not found. Install with: npm install -g pnpm"
exit 1
fi
# Check PostgreSQL
if command -v psql &> /dev/null; then
echo "✅ PostgreSQL: $(psql --version | head -n1)"
else
echo "⚠️ PostgreSQL not found (required for database)"
fi
# Check if dependencies are installed
if [ -d "node_modules" ]; then
echo "✅ Dependencies installed"
else
@@ -41,62 +35,58 @@ else
exit 1
fi
# Check contracts compilation
if [ -d "contracts/artifacts" ]; then
echo "✅ Contracts compiled"
else
echo "⚠️ Contracts not compiled. Run: cd contracts && pnpm run compile"
fi
# Check environment files
echo ""
echo "📋 Environment files:"
if [ -f "frontend/.env.local" ] || [ -f "frontend/.env" ]; then
echo "✅ Frontend env file exists"
else
echo "⚠️ Frontend .env.local not found (create from template)"
fi
for f in frontend/.env.local backend/.env backend/.env.indexer contracts/.env; do
if [ -f "$f" ]; then
echo "$f exists"
else
echo "⚠️ $f not found"
fi
done
if [ -f "backend/.env" ]; then
echo "✅ Backend env file exists"
else
echo "⚠️ Backend .env not found (create from template)"
fi
if [ -f "contracts/.env" ]; then
echo "✅ Contracts env file exists"
else
echo "⚠️ Contracts .env not found (create from template)"
fi
# Check database migrations
if [ -d "backend/drizzle" ] && [ "$(ls -A backend/drizzle/*.sql 2>/dev/null)" ]; then
echo "✅ Database migrations generated"
echo "✅ Database migrations present"
else
echo "⚠️ Database migrations not generated. Run: cd backend && pnpm run db:generate"
echo "⚠️ Database migrations missing. Run: cd backend && pnpm run db:generate"
fi
# Check if database is accessible (if DATABASE_URL is set)
if [ -f "backend/.env" ]; then
set -a
# shellcheck disable=SC1091
source backend/.env
if [ -n "$DATABASE_URL" ]; then
if command -v psql &> /dev/null; then
if psql "$DATABASE_URL" -c "SELECT 1;" &> /dev/null; then
echo "✅ Database connection successful"
else
echo "⚠️ Database connection failed (check DATABASE_URL)"
fi
set +a
if [ -n "${DATABASE_URL:-}" ] && command -v psql &> /dev/null; then
if psql "$DATABASE_URL" -c "SELECT 1;" &> /dev/null; then
echo "✅ Database connection successful"
else
echo "⚠️ Database connection failed (check DATABASE_URL or docker start solace-postgres)"
fi
fi
fi
if [ -f "contracts/deployments/chain138.json" ]; then
echo "✅ Chain 138 deployment record present"
else
echo "⚠️ No chain138 deployment — run: cd contracts && pnpm run deploy:chain138"
fi
echo ""
echo "Running audit-env..."
bash scripts/audit-env.sh || true
echo ""
echo "✨ Setup check complete!"
echo ""
echo "Next steps:"
echo "1. Create .env files if missing"
echo "2. Set up database: cd backend && pnpm run db:migrate"
echo "3. Deploy contracts: cd contracts && pnpm run deploy:sepolia"
echo "4. Start dev servers: pnpm run dev"
echo "1. cd backend && pnpm run db:migrate && pnpm run db:seed"
echo "2. pnpm run sync-env (after deploy)"
echo "3. pnpm run dev (frontend :3000, backend :3001)"
echo "4. cd backend && pnpm run indexer:start"

View File

@@ -0,0 +1,88 @@
#!/usr/bin/env bash
# Fund Solace treasury multisig with a small canary on Chain 138 (ETH + cUSDT + cUSDC).
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
PROXMOX_ROOT="${PROXMOX_ROOT:-$(cd "$REPO_ROOT/../proxmox" 2>/dev/null && pwd || echo "")}"
if [[ -n "$PROXMOX_ROOT" && -f "$PROXMOX_ROOT/scripts/lib/load-project-env.sh" ]]; then
# shellcheck source=/dev/null
source "$PROXMOX_ROOT/scripts/lib/load-project-env.sh"
elif [[ -f "$REPO_ROOT/../smom-dbis-138/scripts/load-env.sh" ]]; then
# shellcheck source=/dev/null
source "$REPO_ROOT/../smom-dbis-138/scripts/load-env.sh"
fi
RPC_URL="${RPC_URL_138:-http://192.168.11.211:8545}"
TREASURY="${TREASURY_WALLET:-${NEXT_PUBLIC_TREASURY_WALLET_ADDRESS:-0x96bF8cd30C4f0e22fa33469f8e2C23AA3faF525C}}"
C_USDT="${C_USDT_CHAIN138:-0x93E66202A11B1772E55407B32B44e5Cd8eda7f22}"
C_USDC="${C_USDC_CHAIN138:-0xf22258f57794CC8E06237084b353Ab30fFfa640b}"
CANARY_ETH="${CANARY_ETH:-0.01}"
CANARY_STABLE="${CANARY_STABLE:-10}"
CANARY_ETH_WEI="$(python3 - <<PY
from decimal import Decimal
wei = int(Decimal("$CANARY_ETH") * Decimal(10**18))
print(wei)
PY
)"
CANARY_STABLE_RAW="$(python3 - <<PY
from decimal import Decimal
raw = int(Decimal("$CANARY_STABLE") * Decimal(10**6))
print(raw)
PY
)"
DRY_RUN=0
for arg in "$@"; do
case "$arg" in
--dry-run) DRY_RUN=1 ;;
esac
done
if [[ -z "${PRIVATE_KEY:-}" ]]; then
echo "error: PRIVATE_KEY not set (load from smom-dbis-138/.env or proxmox .env)" >&2
exit 1
fi
FROM="$(cast wallet address --private-key "$PRIVATE_KEY")"
echo "=== Solace treasury canary fund (Chain 138) ==="
echo "RPC: $RPC_URL"
echo "From: $FROM"
echo "Treasury: $TREASURY"
echo "Amounts: ${CANARY_ETH} ETH, ${CANARY_STABLE} cUSDT, ${CANARY_STABLE} cUSDC"
echo
run_cast() {
if [[ "$DRY_RUN" -eq 1 ]]; then
echo "[dry-run] cast $*"
else
cast "$@"
fi
}
echo "→ Native ETH"
run_cast send --private-key "$PRIVATE_KEY" --rpc-url "$RPC_URL" --value "$CANARY_ETH_WEI" "$TREASURY"
echo "→ cUSDT transfer"
run_cast send --private-key "$PRIVATE_KEY" --rpc-url "$RPC_URL" "$C_USDT" \
"transfer(address,uint256)" "$TREASURY" "$CANARY_STABLE_RAW"
echo "→ cUSDC transfer"
run_cast send --private-key "$PRIVATE_KEY" --rpc-url "$RPC_URL" "$C_USDC" \
"transfer(address,uint256)" "$TREASURY" "$CANARY_STABLE_RAW"
if [[ "$DRY_RUN" -eq 1 ]]; then
echo "Dry run complete."
exit 0
fi
echo
echo "=== Post-fund balances ==="
cast balance "$TREASURY" --rpc-url "$RPC_URL" | xargs -I{} echo "ETH wei: {}"
cast call "$C_USDT" "balanceOf(address)(uint256)" "$TREASURY" --rpc-url "$RPC_URL"
cast call "$C_USDC" "balanceOf(address)(uint256)" "$TREASURY" --rpc-url "$RPC_URL"
echo "Done."

View File

@@ -0,0 +1,73 @@
#!/usr/bin/env bash
# Push env files, migrate, seed, and start Solace services on Proxmox CTs.
set -euo pipefail
PROXMOX_HOST="${PROXMOX_HOST:-192.168.11.11}"
PROXMOX_USER="${PROXMOX_USER:-root}"
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
DEPLOY="$ROOT/deployment/proxmox"
VMID_FRONTEND="${VMID_FRONTEND:-3000}"
VMID_BACKEND="${VMID_BACKEND:-3001}"
VMID_INDEXER="${VMID_INDEXER:-3003}"
echo "=== Solace Proxmox finish deploy ==="
"$ROOT/scripts/proxmox-prepare-env.sh"
echo "Pushing env and unit files..."
scp "$ROOT/frontend/.env.production" "$PROXMOX_USER@$PROXMOX_HOST:/tmp/solace-frontend.env.production"
scp "$ROOT/backend/.env" "$PROXMOX_USER@$PROXMOX_HOST:/tmp/solace-backend.env"
scp "$ROOT/backend/.env.indexer" "$PROXMOX_USER@$PROXMOX_HOST:/tmp/solace-indexer.env.indexer"
scp "$DEPLOY/templates/nginx.conf" "$PROXMOX_USER@$PROXMOX_HOST:/tmp/solace-nginx.conf"
scp "$DEPLOY/templates/solace-treasury-locations.conf" "$PROXMOX_USER@$PROXMOX_HOST:/tmp/solace-nginx-locations.conf"
scp "$DEPLOY/templates/solace-frontend.service" "$PROXMOX_USER@$PROXMOX_HOST:/tmp/solace-frontend.service"
scp "$DEPLOY/templates/solace-backend.service" "$PROXMOX_USER@$PROXMOX_HOST:/tmp/solace-backend.service"
scp "$DEPLOY/templates/solace-indexer.service" "$PROXMOX_USER@$PROXMOX_HOST:/tmp/solace-indexer.service"
ssh "$PROXMOX_USER@$PROXMOX_HOST" bash -s \
"$VMID_FRONTEND" "$VMID_BACKEND" "$VMID_INDEXER" <<'REMOTE'
set -euo pipefail
VMID_FRONTEND=$1
VMID_BACKEND=$2
VMID_INDEXER=$3
pct push "$VMID_FRONTEND" /tmp/solace-frontend.env.production /opt/solace-frontend/.env.production
pct push "$VMID_FRONTEND" /tmp/solace-frontend.service /etc/systemd/system/solace-frontend.service
pct push "$VMID_BACKEND" /tmp/solace-backend.env /opt/solace-backend/.env
pct push "$VMID_INDEXER" /tmp/solace-indexer.env.indexer /opt/solace-indexer/.env.indexer
pct push "$VMID_BACKEND" /tmp/solace-backend.service /etc/systemd/system/solace-backend.service
pct push "$VMID_INDEXER" /tmp/solace-indexer.service /etc/systemd/system/solace-indexer.service
pct push "$VMID_FRONTEND" /tmp/solace-nginx.conf /etc/nginx/sites-available/solace-treasury
pct push "$VMID_FRONTEND" /tmp/solace-nginx-locations.conf /etc/nginx/snippets/solace-treasury-locations.conf
pct exec "$VMID_BACKEND" -- systemctl daemon-reload
pct exec "$VMID_INDEXER" -- systemctl daemon-reload
pct exec "$VMID_FRONTEND" -- bash -c 'mkdir -p /etc/nginx/snippets /etc/nginx/ssl; ln -sf /etc/nginx/sites-available/solace-treasury /etc/nginx/sites-enabled/solace-treasury; rm -f /etc/nginx/sites-enabled/default; test -f /etc/nginx/ssl/cert.pem || openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/key.pem -out /etc/nginx/ssl/cert.pem -subj /CN=solace-treasury.local; nginx -t; systemctl enable nginx solace-frontend'
echo "Running migrations..."
pct exec "$VMID_BACKEND" -- bash -c 'cd /opt/solace-backend && pnpm run db:migrate'
pct exec "$VMID_BACKEND" -- bash -c 'cd /opt/solace-backend && pnpm run db:seed || true'
echo "Starting services..."
pct exec "$VMID_BACKEND" -- systemctl enable solace-backend
pct exec "$VMID_INDEXER" -- systemctl enable solace-indexer
pct exec "$VMID_BACKEND" -- systemctl restart solace-backend
pct exec "$VMID_INDEXER" -- systemctl restart solace-indexer
pct exec "$VMID_FRONTEND" -- systemctl restart solace-frontend
pct exec "$VMID_FRONTEND" -- systemctl restart nginx
sleep 4
echo "=== Service status ==="
pct exec "$VMID_FRONTEND" -- systemctl is-active solace-frontend nginx || true
pct exec "$VMID_BACKEND" -- systemctl is-active solace-backend || true
pct exec "$VMID_INDEXER" -- systemctl is-active solace-indexer || true
REMOTE
echo "Smoke checks..."
curl -sf "http://192.168.11.61:3001/health" && echo " backend OK" || echo " backend FAIL"
curl -sf "http://192.168.11.60/api/config" | grep -q chainId && echo " nginx /api OK" || echo " nginx /api FAIL"
curl -sf -o /dev/null -w "frontend HTTP %{http_code}\n" "http://192.168.11.60/" || true
curl -sfk -o /dev/null -w "frontend HTTPS %{http_code}\n" "https://192.168.11.60/" || true
echo "Done."

46
scripts/proxmox-prepare-env.sh Executable file
View File

@@ -0,0 +1,46 @@
#!/usr/bin/env bash
# Prepare backend/frontend env files for Proxmox CT IPs (192.168.11.6063).
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
DB_HOST="${DATABASE_IP:-192.168.11.62}"
DB_USER="${DATABASE_USER:-solace_user}"
DB_NAME="${DATABASE_NAME:-solace_treasury}"
DB_PASS="${DATABASE_PASSWORD:?Set DATABASE_PASSWORD}"
DB_URL="postgresql://${DB_USER}:${DB_PASS}@${DB_HOST}:5432/${DB_NAME}"
set_env() {
local file="$1" key="$2" value="$3"
if grep -q "^${key}=" "$file" 2>/dev/null; then
sed -i "s|^${key}=.*|${key}=${value}|" "$file"
else
echo "${key}=${value}" >> "$file"
fi
}
[[ -f "$ROOT/contracts/deployments/chain138.json" ]] && "$ROOT/scripts/sync-env-from-deployment.sh"
for f in "$ROOT/backend/.env" "$ROOT/backend/.env.indexer"; do
[[ -f "$f" ]] || continue
set_env "$f" DATABASE_URL "$DB_URL"
set_env "$f" NODE_ENV production
done
# Same-origin API when nginx on CT 3000 proxies /api/ (public NPMplus or LAN HTTPS)
if [[ "${SOLACE_API_SAME_ORIGIN:-1}" == "1" ]]; then
set_env "$ROOT/frontend/.env.production" NEXT_PUBLIC_API_URL ""
else
set_env "$ROOT/frontend/.env.production" NEXT_PUBLIC_API_URL "${SOLACE_PUBLIC_API_URL:-http://192.168.11.61:3001}"
fi
set_env "$ROOT/frontend/.env.production" NEXT_PUBLIC_CHAIN138_RPC_URL "${CHAIN138_PUBLIC_RPC_URL:-https://rpc-http-pub.d-bis.org}"
set_env "$ROOT/frontend/.env.production" NEXT_PUBLIC_CHAIN138_WS_URL ""
set_env "$ROOT/frontend/.env.production" NEXT_PUBLIC_CHAIN138_EXPLORER_URL "${CHAIN138_PUBLIC_EXPLORER_URL:-https://explorer.d-bis.org}"
set_env "$ROOT/frontend/.env.production" NODE_ENV production
for f in "$ROOT/backend/.env" "$ROOT/backend/.env.indexer"; do
[[ -f "$f" ]] || continue
set_env "$f" CLIENT_RPC_URL "${CHAIN138_PUBLIC_RPC_URL:-https://rpc-http-pub.d-bis.org}"
done
echo "Prepared production env (DB host ${DB_HOST}, API same-origin=${SOLACE_API_SAME_ORIGIN:-1}, public RPC=${CHAIN138_PUBLIC_RPC_URL:-https://rpc-http-pub.d-bis.org})"

View File

@@ -0,0 +1,23 @@
#!/usr/bin/env bash
# Destroy and recreate Solace CTs 3000-3003 on the Proxmox node where they live.
set -euo pipefail
PROXMOX_HOST="${PROXMOX_HOST:-192.168.11.11}"
PROXMOX_USER="${PROXMOX_USER:-root}"
echo "Recreating Solace CTs on $PROXMOX_HOST (3000-3003)..."
ssh "$PROXMOX_USER@$PROXMOX_HOST" bash -s <<'EOF'
set -euo pipefail
for vmid in 3003 3002 3001 3000; do
if pct status "$vmid" &>/dev/null; then
echo "Stopping and destroying CT $vmid..."
pct stop "$vmid" || true
sleep 2
pct destroy "$vmid" || true
fi
done
pct list | grep -E '300[0-3]' || echo "All Solace CTs removed."
EOF
echo "Done. Run deploy-remote.sh next."

View File

@@ -0,0 +1,54 @@
#!/usr/bin/env bash
# Resume Solace Proxmox deploy after partial run (sync code, rebuild, frontend, finish).
set -euo pipefail
PROXMOX_HOST="${PROXMOX_HOST:-192.168.11.11}"
PROXMOX_USER="${PROXMOX_USER:-root}"
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
DEPLOYMENT_DIR="/tmp/solace-dapp-deployment"
DATABASE_PASSWORD="${DATABASE_PASSWORD:?Set DATABASE_PASSWORD}"
export DATABASE_PASSWORD
"$ROOT/scripts/proxmox-prepare-env.sh"
echo "Syncing deployment bundle to $PROXMOX_HOST..."
ssh "$PROXMOX_USER@$PROXMOX_HOST" "mkdir -p $DEPLOYMENT_DIR/project $DEPLOYMENT_DIR/config"
rsync -az "$ROOT/deployment/proxmox/" "$PROXMOX_USER@$PROXMOX_HOST:$DEPLOYMENT_DIR/"
rsync -az --delete --exclude node_modules --exclude .next --exclude dist \
"$ROOT/backend/" "$PROXMOX_USER@$PROXMOX_HOST:$DEPLOYMENT_DIR/project/backend/"
rsync -az --delete --exclude node_modules --exclude .next \
"$ROOT/frontend/" "$PROXMOX_USER@$PROXMOX_HOST:$DEPLOYMENT_DIR/project/frontend/"
ssh "$PROXMOX_USER@$PROXMOX_HOST" "cat > $DEPLOYMENT_DIR/config/dapp.conf <<EOF
$(grep -v '^DATABASE_PASSWORD=' "$ROOT/deployment/proxmox/config/dapp.conf")
DATABASE_PASSWORD=$DATABASE_PASSWORD
PROJECT_ROOT=$DEPLOYMENT_DIR/project
PROXMOX_STORAGE=thin1
CONTAINER_UNPRIVILEGED=0
CONTAINER_HOSTNAME=
EOF
chmod +x $DEPLOYMENT_DIR/*.sh"
echo "Rebuilding backend (3001) and indexer (3003)..."
ssh "$PROXMOX_USER@$PROXMOX_HOST" bash -s <<'REMOTE'
set -euo pipefail
DEPLOYMENT_DIR=/tmp/solace-dapp-deployment
PROJECT_ROOT=$DEPLOYMENT_DIR/project
rebuild_backend() {
local vmid=$1 dir=$2
pct exec "$vmid" -- bash -c "rm -rf /opt/$dir/* /opt/$dir/.* 2>/dev/null || true"
cd "$PROJECT_ROOT"
tar czf - backend | pct exec "$vmid" -- bash -c "cd /opt && tar xzf - && mv backend/* $dir/ && mv backend/.* $dir/ 2>/dev/null || true && rmdir backend 2>/dev/null || true"
pct exec "$vmid" -- bash -c "cd /opt/$dir && pnpm install --no-frozen-lockfile"
}
rebuild_backend 3001 solace-backend
rebuild_backend 3003 solace-indexer
REMOTE
echo "Deploying frontend (3000) + nginx..."
ssh "$PROXMOX_USER@$PROXMOX_HOST" "cd $DEPLOYMENT_DIR && DEPLOY_DATABASE=false DEPLOY_BACKEND=false DEPLOY_INDEXER=false DEPLOY_FRONTEND=true DEPLOY_NGINX=true ./deploy-dapp.sh"
"$ROOT/scripts/proxmox-finish-deploy.sh"
echo "Resume deploy complete."

View File

@@ -13,8 +13,8 @@ echo "=========================================="
echo ""
# Chain 138 RPC endpoints
RPC_URL="${CHAIN138_RPC_URL:-http://192.168.11.250:8545}"
WS_URL="${CHAIN138_WS_URL:-ws://192.168.11.250:8546}"
RPC_URL="${CHAIN138_RPC_URL:-http://192.168.11.211:8545}"
WS_URL="${CHAIN138_WS_URL:-ws://192.168.11.211:8546}"
echo "Chain 138 RPC URL: $RPC_URL"
echo "Chain 138 WS URL: $WS_URL"
@@ -26,6 +26,7 @@ if [[ -f "$DEPLOYMENT_FILE" ]]; then
echo "Found deployment file: $DEPLOYMENT_FILE"
TREASURY_ADDRESS=$(jq -r '.contracts.TreasuryWallet' "$DEPLOYMENT_FILE" 2>/dev/null || echo "")
FACTORY_ADDRESS=$(jq -r '.contracts.SubAccountFactory' "$DEPLOYMENT_FILE" 2>/dev/null || echo "")
DEPLOY_BLOCK=$(jq -r '.deployBlock // 0' "$DEPLOYMENT_FILE" 2>/dev/null || echo "0")
if [[ -n "$TREASURY_ADDRESS" && "$TREASURY_ADDRESS" != "null" ]]; then
echo "Treasury Wallet Address: $TREASURY_ADDRESS"
@@ -83,7 +84,7 @@ CHAIN_ID=138
CONTRACT_ADDRESS=${TREASURY_ADDRESS:-}
# Indexer Configuration
START_BLOCK=0
START_BLOCK=${DEPLOY_BLOCK:-0}
EOF
echo ""

28
scripts/start-local-stack.sh Executable file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env bash
# Start local dev stack: Postgres (Docker), migrate, seed, dev servers.
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT"
if ! docker ps --format '{{.Names}}' | grep -q '^solace-postgres$'; then
if docker ps -a --format '{{.Names}}' | grep -q '^solace-postgres$'; then
echo "Starting existing solace-postgres container..."
docker start solace-postgres
else
echo "Creating solace-postgres container..."
docker run -d --name solace-postgres \
-e POSTGRES_USER=solace_user \
-e POSTGRES_PASSWORD=SolaceTreasury2024! \
-e POSTGRES_DB=solace_treasury \
-p 5432:5432 \
postgres:16-alpine
sleep 3
fi
fi
echo "Running migrations and seed..."
(cd backend && pnpm run db:migrate && pnpm run db:seed)
echo "Starting dev servers (frontend :3000, backend :3001)..."
pnpm run dev

View File

@@ -0,0 +1,69 @@
#!/usr/bin/env bash
# Sync contract addresses from contracts/deployments/chain138.json into app env files.
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
DEPLOY="$ROOT/contracts/deployments/chain138.json"
if [[ ! -f "$DEPLOY" ]]; then
echo "Missing $DEPLOY — run: cd contracts && pnpm run deploy:chain138" >&2
exit 1
fi
TREASURY=$(jq -r '.contracts.TreasuryWallet' "$DEPLOY")
FACTORY=$(jq -r '.contracts.SubAccountFactory' "$DEPLOY")
DEPLOY_BLOCK=$(jq -r '.deployBlock // empty' "$DEPLOY")
if [[ -z "$TREASURY" || "$TREASURY" == "null" ]]; then
echo "TreasuryWallet missing in deployment JSON" >&2
exit 1
fi
set_env() {
local file="$1"
local key="$2"
local value="$3"
if [[ ! -f "$file" ]]; then
touch "$file"
fi
if grep -q "^${key}=" "$file" 2>/dev/null; then
sed -i "s|^${key}=.*|${key}=${value}|" "$file"
else
echo "${key}=${value}" >> "$file"
fi
}
PUBLIC_RPC="${CHAIN138_PUBLIC_RPC_URL:-https://rpc-http-pub.d-bis.org}"
LAN_RPC="${CHAIN138_RPC_URL:-http://192.168.11.211:8545}"
LAN_WS="${CHAIN138_WS_URL:-ws://192.168.11.211:8546}"
for f in "$ROOT/frontend/.env.local" "$ROOT/frontend/.env.production"; do
[[ -f "$f" ]] || continue
set_env "$f" NEXT_PUBLIC_TREASURY_WALLET_ADDRESS "$TREASURY"
set_env "$f" NEXT_PUBLIC_SUB_ACCOUNT_FACTORY_ADDRESS "$FACTORY"
set_env "$f" NEXT_PUBLIC_CHAIN138_RPC_URL "$PUBLIC_RPC"
set_env "$f" NEXT_PUBLIC_CHAIN138_WS_URL ""
set_env "$f" NEXT_PUBLIC_CHAIN138_EXPLORER_URL "${CHAIN138_PUBLIC_EXPLORER_URL:-https://explorer.d-bis.org}"
set_env "$f" NEXT_PUBLIC_CHAIN_ID "138"
done
for f in "$ROOT/backend/.env" "$ROOT/backend/.env.indexer"; do
[[ -f "$f" ]] || continue
set_env "$f" CONTRACT_ADDRESS "$TREASURY"
set_env "$f" FACTORY_ADDRESS "$FACTORY"
set_env "$f" RPC_URL "$LAN_RPC"
set_env "$f" CLIENT_RPC_URL "$PUBLIC_RPC"
set_env "$f" CHAIN_ID "138"
if [[ -n "$DEPLOY_BLOCK" && "$DEPLOY_BLOCK" != "null" ]]; then
set_env "$f" START_BLOCK "$DEPLOY_BLOCK"
fi
done
for f in "$ROOT/backend/.env.indexer"; do
[[ -f "$f" ]] || continue
set_env "$f" FACTORY_ADDRESS "$FACTORY"
done
echo "Synced deployment addresses:"
echo " TreasuryWallet: $TREASURY"
echo " SubAccountFactory: $FACTORY"

47
scripts/verify-full-stack.sh Executable file
View File

@@ -0,0 +1,47 @@
#!/usr/bin/env bash
# End-to-end smoke verification for local dev stack.
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT"
API="${NEXT_PUBLIC_API_URL:-http://localhost:3001}"
FE="${FRONTEND_URL:-http://localhost:3000}"
TREASURY="${NEXT_PUBLIC_TREASURY_WALLET_ADDRESS:-0x96bF8cd30C4f0e22fa33469f8e2C23AA3faF525C}"
echo "=== Solace Full-Stack Verification ==="
echo ""
bash scripts/audit-env.sh
echo ""
echo "## Type checks"
(cd frontend && pnpm exec tsc --noEmit)
echo "✅ Frontend types"
echo ""
echo "## HTTP smoke"
curl -sf "$API/health" | grep -q '"status"' && echo "✅ GET /health"
curl -sf "$API/api/config" | grep -q '"chainId"' && echo "✅ GET /api/config"
curl -sf "$API/api/treasury?wallet=$TREASURY" | grep -q '"treasury"' && echo "✅ GET /api/treasury"
curl -sf -o /dev/null -w '' "$FE/" && echo "✅ Frontend $FE"
curl -sf -o /dev/null -w '' "$FE/settings" && echo "✅ Frontend /settings"
curl -sf -o /dev/null -w '' "$FE/approvals" && echo "✅ Frontend /approvals"
curl -sf -o /dev/null -w '' "$FE/receive" && echo "✅ Frontend /receive"
if command -v pnpm >/dev/null && [[ -d frontend/node_modules/@playwright/test ]]; then
echo ""
echo "## E2E (optional)"
if (cd frontend && PW_SKIP_WEBSERVER=1 pnpm run test:e2e 2>&1); then
echo "✅ Playwright smoke tests"
else
echo "⚠️ Playwright tests failed (dev server may be compiling — retry with pnpm run test:e2e)"
fi
fi
if [[ -f contracts/deployments/chain138.json ]]; then
echo "✅ chain138 deployment JSON"
fi
echo ""
echo "=== All checks passed ==="