Skip to content

feat(auth): implement Ed25519 wallet signature authentication (#41)#146

Merged
YaronZaki merged 6 commits into
Quantarq:mainfrom
Tyler7x:feature/issue-41-wallet-signature-auth
Jun 19, 2026
Merged

feat(auth): implement Ed25519 wallet signature authentication (#41)#146
YaronZaki merged 6 commits into
Quantarq:mainfrom
Tyler7x:feature/issue-41-wallet-signature-auth

Conversation

@Tyler7x

@Tyler7x Tyler7x commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements wallet signature authentication using Stellar Ed25519 keypairs (Issue #41).

  • quantara/web_app/api/wallet_auth.py (new): Challenge-response nonce system with in-memory TTL store, Ed25519 signature verification via stellar-sdk, a GET /api/auth/nonce endpoint, and a reusable verify_wallet_signature FastAPI dependency.
  • quantara/web_app/api/main.py: Registers the auth router; adds X-Wallet-Id, X-Nonce, X-Signature to the CORS allow-list.
  • quantara/web_app/api/vault.py: Protects POST /api/vault/deposit and POST /api/vault/add_balance with Depends(verify_wallet_signature).
  • quantara/web_app/api/position.py: Protects POST /api/create-position and POST /api/add-extra-deposit/{id} with Depends(verify_wallet_signature).
  • quantara/web_app/tests/conftest.py: Adds a bypass_wallet_auth autouse function-scoped fixture that replaces verify_wallet_signature with a no-op for every test — no nonce/signature exchange needed, no existing test files modified.
  • quantara/web_app/tests/test_wallet_auth.py (new): 18 tests covering nonce generation uniqueness, replay prevention, wrong-wallet rejection, TTL expiry, valid/invalid/tampered signatures, malformed keys, the FastAPI dependency (401 paths + success path), and the nonce endpoint.

Authentication flow

Client                                   Server
  |--GET /api/auth/nonce?wallet_id=G…-->|  issues nonce (TTL 300 s)
  |<-----------{nonce, expires_in}-------|
  |                                      |
  |  sig = sign(nonce, stellar_privkey)  |
  |                                      |
  |--POST /api/create-position---------->|
  |   X-Wallet-Id: G…                   |  dependency: consume nonce,
  |   X-Nonce: <nonce>                  |  verify Ed25519 sig
  |   X-Signature: <hex sig>            |
  |<-----------200 OK (position data)----|

CI notes

  • stellar-sdk is already in pyproject.toml.
  • Nonce store is in-memory — zero external dependencies in CI.
  • bypass_wallet_auth autouse fixture bypasses auth for all existing tests via app.dependency_overrides, keeping the existing test suite unchanged.

Test plan

  • pytest quantara/web_app/tests/test_wallet_auth.py — all 18 auth tests pass
  • pytest quantara/web_app/tests/ — full suite passes (auth bypassed via autouse fixture)
  • GET /api/auth/nonce?wallet_id=<key> returns {nonce, expires_in: 300}
  • POST /api/vault/deposit without auth headers returns 422
  • POST /api/vault/deposit with valid signed nonce returns 200
  • Replaying the same nonce returns 401

🤖 Generated with Claude Code

@YaronZaki YaronZaki left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@YaronZaki YaronZaki merged commit 301ebee into Quantarq:main Jun 19, 2026
3 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