Coin API — Complete Reference

All endpoints, request/response shapes and behavior derived from api.js and logic.js.
Coin Website Privacy Policy API Documentation Terms of Use GitHub Repo

Table of contents

  1. Overview
  2. Authentication
  3. Queue & idempotency
  4. Endpoints (complete list)
  5. txId: generation & when responses include it
  6. Errors & status codes
  7. Appendix — op names

1) Overview

This documentation mirrors the exact behavior implemented in the server files (api.js and logic.js).

Key architecture: the HTTP API enqueues write operations into a bounded in‑memory queue (with optional DB persistence for pending jobs) and then either waits for the queue worker result or returns a legacy‑shaped response for backward compatibility. The queue attaches a txId to payloads for idempotency; whether that txId appears in the HTTP response depends on per‑route mapping rules implemented in doEnqueueAndMap.

2) Authentication

Endpoints that require authentication use an Authorization header with a session token:

Authorization: Bearer <sessionId>
Content-Type: application/json

The middleware resolves the session using db.getSession and sets req.userId. If the session is invalid the route returns 403 with { error: "operation failed" }.

3) Queue & idempotency

  • The server uses queue.enqueueAndWait(payload). Before enqueueing, doEnqueueAndMap ensures payload.args.ip is set and attaches payload.txId = a random UUID if not provided.
  • If the queue refuses with ENQUEUE_REJECTED the wrapper attempts an in‑memory cache and a DB pending job. If that also fails, the API returns 429 / { error: "QUEUE_FULL" }. The cache worker later flushes pending items into the queue.
  • Per‑route legacy mapping:
    • legacyReturn: 'transfer' → response is always { success: true } (hides txId).
    • legacyReturn: 'transfer_card' → response is { success: true, txId?, date? } if the worker result contains a txId, otherwise { success: true }.
    • Default (no legacyReturn) → returns the worker result as‑is.

4) Endpoints (complete list)

POST /api/login

Description: Authenticates a user and creates a session. The server hashes the password using SHA‑256 before checking.

Body:

{
  "username": "alice",
  "password": "secret"
}

Response (success):

{
  "sessionCreated": true,
  "passwordCorrect": true,
  "userId": "123456789012345678",
  "sessionId": "<session-token>",
  "saldo": 12.345678,
  "cooldownRemainingMs": 0
}

If IP is locked due to too many failed attempts, returns 429 with error: "IP blocked. Try again in X seconds.".

POST /api/register

Description: Creates a new user. Enforces a 1‑second IP registration cooldown (24h block in code, but currently set to 1s).

Body:

{
  "username": "bob",
  "password": "s3cret"
}

Response:

{
  "success": true,
  "userId": "987654321",
  "sessionId": "<session-token>"
}

Errors: 409 if username already taken, 429 if IP blocked or queue full.

POST /api/logout

Description: Deletes the session token provided in the Authorization header.

Auth: Bearer token

Response: { success: true }

POST /api/account/change

Description: Changes the username and/or password for the authenticated user. Requires both username and password in the body.

Auth: Bearer token

Body:

{
  "username": "newalice",
  "password": "newpass"
}

Response: { success: true }

POST /api/account/unregister

Description: Deletes the user account (clears username/password and removes the session).

Auth: Bearer token

Response: { success: true }

POST /api/account/update

Description: Updates the username and password hash for the user.

Auth: Bearer token

Body:

{
  "username": "alice",
  "passwordHash": "sha256 hash"
}

Response: { success: true }

POST /api/transfer

Description: Transfers coins from the authenticated user to another user. This endpoint uses legacy response (hides txId).

Auth: Bearer token

Body:

{
  "toId": "987654321",
  "amount": 0.001
}

Response: { success: true } (txId hidden).

Note: If you need the txId, either supply your own txId in the body or use the card‑based endpoint.

POST /api/transfer/card

Description: Transfers coins using a card code. Resolves the owner from the card hash. May return txId if available.

Body:

{
  "cardCode": "abcd-efgh-1234",
  "toId": "11111",
  "amount": 0.01
}

Response (if txId available):

{
  "success": true,
  "txId": "uuid-12345-abcdef",
  "date": "2025-12-07T12:00:00.000Z"
}

Response (legacy fallback): { success: true }

POST /api/card/pay

Description: Card‑to‑card transfer (alias of /api/transfer_between_cards).

Body:

{
  "fromCard": "abcd-ef",
  "toCard": "wxyz-12",
  "amount": 0.002
}

Response: same as /api/transfer/card.

POST /api/claim

Description: Claims the daily (or configured) reward. Respects cooldown set in claimConfig.

Auth: Bearer token

Response (success):

{
  "success": true,
  "claimed": 0.05
}

Response (cooldown):

{
  "error": "Cooldown active",
  "nextClaimInMs": 12345,
  "cooldownMs": 86400000,
  "lastClaimTs": 1234567890
}

GET /api/claim/status

Description: Returns the remaining cooldown for the authenticated user.

Auth: Bearer token

Response:

{
  "cooldownRemainingMs": 12345,
  "lastClaimTimestamp": 1234567890,
  "cooldownMs": 86400000
}

POST /api/card

Description: Retrieves the card code of the authenticated user.

Auth: Bearer token

Response:

{
  "cardCode": "abc123..."
}

POST /api/card/reset

Description: Generates a new card code for the user (invalidates the old one).

Auth: Bearer token

Response:

{
  "newCode": "def456..."
}

POST /api/card/info

Description: Get account information by card code (no authentication required).

Body:

{
  "cardCode": "abcdef"
}

Response:

{
  "success": true,
  "userId": "123",
  "coins": "0.00012345",
  "sats": 12345,
  "totalTransactions": 5,
  "lastClaimTs": 1234567890,
  "cooldownRemainingMs": 0,
  "cooldownMs": 86400000
}

POST /api/card/claim

Description: Claims reward using a card code (no auth).

Body: { "cardCode": "abcdef" }

Response:

{
  "success": true,
  "claimed": 0.05
}

On cooldown: 429 with error: "COOLDOWN_ACTIVE".

POST /api/backup/create

Description: Generates backup codes for the authenticated user. Up to 12 codes will be created if the user has a positive balance.

Auth: Bearer token

Response: { success: true }

POST /api/backup/list

Description: Lists the backup codes for the authenticated user.

Auth: Bearer token

Response:

{
  "backups": ["code1", "code2"]
}

POST /api/backup/restore

Description: Consumes a backup code and transfers the entire balance of the original owner to the authenticated user. Cannot restore your own backup.

Auth: Bearer token

Body: { "backupId": "code" }

Response: { success: true }

GET /api/totalusers

Description: Returns the total number of registered users.

Response:

{
  "totalUsers": 42
}

GET /api/tx/:txid

Description: Looks up a transaction by its ID. Returns detailed information including amounts in satoshis and coins.

Response (found):

{
  "success": true,
  "tx": {
    "id": "uuid-12345",
    "date": "2025-12-07T12:00:00.000Z",
    "from": "11111",
    "to": "22222",
    "amountSats": 12345,
    "amountCoins": "0.00012345"
  }
}

Response (not found): 404 with { error: "INVALID_TRANSACTION", message: "Transaction not found" }

GET /api/transactions

Description: Lists transactions for the authenticated user with pagination (page parameter).

Auth: Bearer token

Query: ?page=1

Response:

{
  "transactions": [
    {
      "id": "tx-1",
      "date": "2025-12-07T12:00:00.000Z",
      "from_id": "11111",
      "to_id": "22222",
      "amount": "0.001"
    }
  ],
  "page": 1
}

GET /api/user/:userId/balance

Description: Returns the balance of the authenticated user.

Auth: Bearer token

Response:

{
  "coins": 12.345678
}

GET /api/rank

Description: Returns the top 25 users by balance and the total coins in circulation.

Auth: Bearer token

Response:

{
  "totalCoins": 1234.56,
  "rankings": [
    { "id": "111", "username": "alice", "coins": 100.5 },
    ...
  ]
}

POST /api/bill/create

Description: Creates a bill (invoice) from the authenticated user (or from a specified fromId) to a recipient. The bill expires after the given duration.

Auth: Bearer token

Body:

{
  "toId": "recipient_id",
  "amount": 0.5,
  "time": "1d"      // optional, defaults to now
}

Response:

{
  "success": true,
  "billId": "bill-abc123"
}

POST /api/bill/pay

Description: Pays a bill using the authenticated user's balance.

Auth: Bearer token

Body: { "billId": "bill-abc123" }

Response: { success: true }

POST /api/bill/list

Description: Lists bills to pay (incoming) and bills to receive (outgoing) for the authenticated user.

Auth: Bearer token

Body (optional): { "page": 1 }

Response:

{
  "toPay": [
    { "id": "b1", "from_id": "111", "to_id": "222", "amount": "0.1", "date": "..." }
  ],
  "toReceive": [
    { "id": "b2", "from_id": "333", "to_id": "222", "amount": "0.2", "date": "..." }
  ],
  "page": 1
}

POST /api/bill/list/from

Description: Lists bills that the authenticated user must pay (incoming).

Auth: Bearer token

Body: { "page": 1 }

Response: { "toPay": [...], "page": 1 }

POST /api/bill/list/to

Description: Lists bills that the authenticated user will receive (outgoing).

Auth: Bearer token

Body: { "page": 1 }

Response: { "toReceive": [...], "page": 1 }

POST /api/bill/create/card

Description: Creates a bill using card codes (resolves owner IDs from the cards). At least one of fromCard or toCard must be provided.

Body:

{
  "fromCard": "abcd-ef",
  "toCard": "wxyz-12",
  "amount": 0.5,
  "time": "1d"
}

Response: { success: true, billId: "..." }

POST /api/bill/pay/card

Description: Pays a bill using a card code (the payer is resolved from the card).

Body:

{
  "cardCode": "abcd-ef",
  "billId": "bill-123"
}

Response: { success: true }

GET /api/queue/info

Description: Returns queue statistics (only available if EXPOSE_INTERNALS=true).

Response:

{
  "queued": 3,
  "usedBytes": 1234,
  "maxBytes": 524288,
  "maxOpsPerSecond": 500
}

GET /api/queue/status/:id

Description: Returns the status of a specific queue item (if exposed).

Response: { state: "done", ts: 1234567890, result: {...} }

5) txId: generation & when responses include it

  • Every enqueued payload receives a payload.txId (UUID) for idempotency; the server only sets it if the client didn't provide one.
  • Whether the HTTP response includes the txId depends on the route mapping:
    • legacyReturn: 'transfer' → response is always { success: true } (txId hidden).
    • legacyReturn: 'transfer_card' → response is { success: true, txId?, date? } if the worker result contains a txId; otherwise { success: true }.
    • Default (no legacyReturn) → returns the worker result as‑is, which may include txId if the underlying logic function returns it.
  • To always receive the txId, provide it yourself in the request body or modify doEnqueueAndMap mapping.

6) Errors & status codes

  • 400 – invalid parameters: { error: 'Invalid parameters' }
  • 403 – authentication failure: { error: 'operation failed' }
  • 404 – resource not found (e.g. card, transaction)
  • 409 – conflict (username already taken)
  • 429 – rate limit exceeded, queue full, or IP locked: { error: "QUEUE_FULL" } or { error: "RATE_LIMIT_EXCEEDED" }
  • 504 – queue wait timeout: { error: 'QUEUE_TIMEOUT' }
  • 500 – internal server error: { error: 'Internal error' }

7) Appendix — op names

login, register, logout, account_change, account_unregister, account_update,
transfer, transfer_card, claim, claim_status, get_card, reset_card,
backup_create, backup_list, backup_restore,
get_balance, rank, total_users, tx_lookup, transactions,
bill_list, bill_list_from, bill_list_to, bill_create, bill_pay,
card_info, card_claim, transfer_between_cards,
bill_create_card, bill_pay_card

Developer note: to change whether a route returns txId, edit doEnqueueAndMap mapping in api.js. You can also supply your own txId in the request to maintain idempotency and correlate with /api/tx/:txid.

Documentation generated to match the behavior in api.js and logic.js.
Last updated: 2025-02-26 14:30 UTC