Secra API

The Secra API provides cryptographic identity and authentication services for Arkonova Network. It implements a challenge-response authentication flow using Ed25519 signatures, allowing any application to verify user identity without passwords.

Base URL: https://arkonova.network/api/v2/secra

Authentication

Most endpoints require no authentication themselves — they are used to establish authentication. Once authenticated, you receive a JWT token to use in subsequent requests to other APIs.

For endpoints that do require auth, pass the JWT token in the Authorization header:

HTTP Header
Authorization: Bearer <your_jwt_token>

Authentication Flow

Secra uses a 3-step challenge-response flow. No passwords are ever transmitted:

  1. Request a challenge — server returns a unique one-time string
  2. Sign the challenge — user signs it with their Ed25519 private key (via extension or SDK)
  3. Verify the signature — server verifies, returns a JWT token on success
Challenges are single-use and expire after a short window. Never reuse a challenge.

1. Get Challenge

POST /auth/challenge

Request a one-time challenge string for the given address.

ParameterTypeRequiredDescription
addressstringrequiredThe user's Secra address (Ed25519 public key fingerprint)
Request
POST /api/v2/secra/auth/challenge Content-Type: application/json { "address": "arkonova1abc123..." }
Response 200
{ "challenge": "arkonova-auth:1708345123:7f3a9b2c...", "expires_in": 300 }

2. Verify Signature

POST /auth/verify

Submit the signed challenge for server-side verification. Returns a JWT token on success.

ParameterTypeRequiredDescription
addressstringrequiredThe user's Secra address
challengestringrequiredThe challenge string received from /auth/challenge
signaturestringrequiredHex-encoded Ed25519 signature of the challenge
publicKeystringrequiredHex-encoded Ed25519 public key
Request
POST /api/v2/secra/auth/verify Content-Type: application/json { "address": "arkonova1abc123...", "challenge": "arkonova-auth:1708345123:7f3a9b2c...", "signature": "a4f3e9...", "publicKey": "b2c8d1..." }
Response 200 — Success
{ "success": true, "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "address": "arkonova1abc123..." }
Response 404 — User not registered
{ "error": "user_not_found" }
A 404 means the address has never registered with Arkonova. The user must register via the Secra extension first.

3. Set Flask Session

POST /auth/session

Persist the JWT token as a server-side session cookie. Call this after a successful verify to enable session-based authentication across page loads.

ParameterTypeRequiredDescription
tokenstringrequiredJWT token received from /auth/verify
Response 200
{ "ok": true }

Signing Data (Client-Side)

The Secra extension handles signing via postMessage. Here's the full client-side flow:

JavaScript — Extension Sign Request
// Request signing via the Secra browser extension function signWithSecra(message) { return new Promise((resolve, reject) => { const handler = (event) => { if (event.data?.type === 'SECRA_SIGN_RESPONSE') { window.removeEventListener('message', handler); resolve(event.data.signature); } else if (event.data?.type === 'SECRA_SIGN_REJECTED') { window.removeEventListener('message', handler); reject(new Error('rejected')); } }; window.addEventListener('message', handler); window.postMessage({ type: 'SECRA_SIGN_REQUEST', source: 'your-app', message: message }, '*'); setTimeout(() => { window.removeEventListener('message', handler); reject(new Error('timeout')); }, 60000); }); } // Full auth flow example async function loginWithSecra(address) { // Step 1: Get challenge const { challenge } = await fetch('/api/v2/secra/auth/challenge', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ address }) }).then(r => r.json()); // Step 2: Sign with extension const signature = await signWithSecra(challenge); // Step 3: Verify const { token } = await fetch('/api/v2/secra/auth/verify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ address, challenge, signature, publicKey }) }).then(r => r.json()); return token; // JWT }

About Ed25519 Keys

Secra uses Ed25519 (Edwards-curve Digital Signature Algorithm) for all cryptographic operations. Ed25519 provides:

Python — Verify an Ed25519 Signature
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat import binascii def verify_secra_signature(public_key_hex: str, message: str, signature_hex: str) -> bool: public_key_bytes = binascii.unhexlify(public_key_hex) signature_bytes = binascii.unhexlify(signature_hex) message_bytes = message.encode('utf-8') public_key = Ed25519PublicKey.from_public_bytes(public_key_bytes) try: public_key.verify(signature_bytes, message_bytes) return True except Exception: return False

Get User Info

GET /user/<address>

Retrieve public information about a registered Secra user. No authentication required.

Response 200
{ "address": "arkonova1abc123...", "username": "alice", "registered_at": "2025-01-15T10:00:00", "public_key": "b2c8d1..." }

Error Codes

All errors return JSON with an error field and an appropriate HTTP status:

StatusErrorMeaning
400missing_fieldsRequired parameters are absent
400invalid_challengeChallenge is expired or already used
400invalid_signatureEd25519 signature verification failed
401unauthorizedInvalid or missing JWT token
404user_not_foundAddress is not registered in the system
429rate_limitedToo many requests — slow down
500server_errorInternal server error

Need help integrating Secra? Join our developer community in Quanta.

Open Quanta Messenger Back to Wiki
Domain migration

Primary domain: arkonova.network

We are migrating away from arkonova.ru. Please update bookmarks and links.

Open primary domain