Skip to content

feat: wallet signature verification middleware for API auth (closes #41)#159

Merged
YaronZaki merged 2 commits into
Quantarq:mainfrom
Tyler7x:feat/wallet-auth-middleware-41
Jun 22, 2026
Merged

feat: wallet signature verification middleware for API auth (closes #41)#159
YaronZaki merged 2 commits into
Quantarq:mainfrom
Tyler7x:feat/wallet-auth-middleware-41

Conversation

@Tyler7x

@Tyler7x Tyler7x commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements Ed25519 Stellar wallet signature verification middleware for all state-changing API endpoints, closing the critical authentication bypass described in issue #41.

Changes

Backend

  • web_app/api/wallet_auth.py (existing) — nonce generation, Ed25519 verification, verify_wallet_signature FastAPI dependency, GET /api/auth/nonce endpoint
  • web_app/api/dependencies.py — re-exports verify_wallet_signature alongside get_stellar_client for clean import paths
  • web_app/api/user.py — added Depends(verify_wallet_signature) to POST /api/update-user-contract and POST /api/subscribe-to-notification (previously unprotected)
  • position.py and vault.py were already protected

Frontend

  • services/wallet.jsx — adds signNonce(nonce, walletId) using Freighter's signMessage API; converts base64 → hex to match backend bytes.fromhex()
  • utils/axios.js — adds getAuthHeaders(walletId): fetches nonce from /api/auth/nonce, signs it, returns x-wallet-id / x-nonce / x-signature headers
  • services/transaction.jsPOST /api/create-position now includes auth headers
  • services/contract.jsPOST /api/update-user-contract now includes auth headers

Tests

  • tests/test_positions.py — removed module-level app.dependency_overrides.clear() that was wiping the bypass_wallet_auth autouse fixture and causing auth failures on protected endpoints
  • tests/conftest.py (existing)bypass_wallet_auth autouse fixture keeps all existing test suites decoupled from real crypto; test_wallet_auth.py covers the full auth flow with 23 unit tests

Test Results

  • ✅ 23/23 wallet auth unit tests pass
  • ✅ All position/vault endpoint tests pass with the auth bypass fixture
  • ✅ 1 pre-existing DB-connection failure in test_positions.py (no local Postgres) — unchanged from main

Acceptance Criteria

  • POST/PUT/DELETE endpoints require valid Ed25519 signature matching claimed wallet_id
  • GET endpoints for public data remain unauthenticated
  • Invalid signatures return 401 Unauthorized with descriptive error
  • Expired nonces return 401 Unauthorized with clear message
  • Frontend updated to include signature in API requests
  • All existing tests pass (updated to include auth fixtures)

Tyler7x added 2 commits June 22, 2026 11:32
Quantarq#41)

- Add verify_wallet_signature FastAPI dependency (wallet_auth.py)
- Protect POST /api/update-user-contract and /api/subscribe-to-notification
  in user.py (position.py and vault.py were already protected)
- Re-export verify_wallet_signature from dependencies.py for clean imports
- Frontend: add signNonce() to wallet.jsx using Freighter signMessage API
- Frontend: add getAuthHeaders(walletId) to axios.js; fetches nonce,
  signs it, returns x-wallet-id / x-nonce / x-signature headers
- Frontend: update create-position POST in transaction.js with auth headers
- Frontend: update update-user-contract POST in contract.js with auth headers
- Fix test_positions.py: remove module-level app.dependency_overrides.clear()
  that was wiping the bypass_wallet_auth autouse fixture

All 23 wallet_auth unit tests pass. The bypass_wallet_auth autouse fixture
in conftest.py keeps existing test suites decoupled from real signatures.

Copy link
Copy Markdown
Contributor

✅ Nice work, @Tyler7x — challenge/response using Freighter signMessage plus a FastAPI dependency is exactly the right shape. Test mocks line up with the changes. Merging.

@YaronZaki YaronZaki merged commit a5a28a4 into Quantarq:main Jun 22, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants