Files
nick-doc/03 - API Reference/Trezor API.md
Siavash Sameni dceaf82934 audit: 2026-05-30 full-codebase audit — report, issues, docs, runbooks
Full-codebase-audit 2026-05-30 outputs:
- Audit report: 09 - Audits/Full Codebase Audit - 2026-05-30.md
- 81 issue files ISSUE-055..135 (decisions + 1 skipped no-brainer).
- Scanner docs from scratch (was zero): architecture, data model, API ref, payment
  flow, operations runbook + repo README.
- Doc-sync updates across API reference, data models, flows, design system.
- Secret Rotation Runbook (08 - Operations) for the exposed credentials.
- Reusable workflow guide (07 - Development) + .claude/workflows/full-codebase-audit.js.

Issues remain status:open intentionally — the code fixes are uncommitted-then-committed
working-tree changes per repo and aren't "resolved" until merged/deployed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 18:48:04 +04:00

4.5 KiB

title, tags
title tags
Trezor API
api
payments
trezor
safekeeping

Last updated: 2026-05-30 — break-glass mode added (commit b21df25)

Trezor API

The Trezor API is mounted at /api/trezor. It is optional support for hardware-backed safekeeping and does not replace Request Network checkout, the funds ledger, or the broader Safe/multisig custody roadmap.

Enforcement is controlled by:

TREZOR_SAFEKEEPING_REQUIRED=false

Only the literal value true makes Trezor proof mandatory during release/refund confirmation. When unset or false, release/refund flows continue without Trezor proof.

Break-glass mode

When TREZOR_SAFEKEEPING_REQUIRED=true and the Trezor is unavailable (lost, dead battery, etc.), an admin can activate break-glass mode to bypass Trezor for up to 1 hour. Break-glass state is in-memory only and resets on server restart.

See Admin APIBreak-glass (Trezor bypass) section for the three management endpoints (GET, POST, DELETE /api/admin/settings/break-glass). Activating break-glass fires an immediate Telegram alert via tgNotify.

GET /api/trezor/registration-message

Builds the exact message the user must sign to register a Trezor xpub.

Auth: bearer JWT

Query:

xpub=<extended public key>
registrationAddress=<first derived address>

Response:

{
  "success": true,
  "data": {
    "message": "Amanat escrow Trezor registration\n..."
  }
}

POST /api/trezor/register

Registers a Trezor xpub after the first derived address signs the registration challenge.

Auth: bearer JWT

Body:

{
  "xpub": "xpub...",
  "registrationAddress": "0x...",
  "proofMessage": "Amanat escrow Trezor registration\n...",
  "proofSignature": "0x...",
  "basePath": "m/44'/60'/0'",
  "deviceLabel": "Office Trezor"
}

Validation:

  • Rejects private extended keys (xprv, tprv).
  • Requires registrationAddress to equal xpub-derived m/44'/60'/0'/0/0.
  • Requires proofSignature to recover registrationAddress.

Response:

{
  "success": true,
  "data": {
    "xpubFingerprint": "0x...",
    "registrationAddress": "0x...",
    "basePath": "m/44'/60'/0'",
    "nextAddressIndex": 1
  }
}

GET /api/trezor/account

Returns the caller's active Trezor registration summary. If no Trezor has been registered for the authenticated user, returns { registered: false } without an error.

Auth: bearer JWT

Response when registered:

{
  "success": true,
  "data": {
    "registered": true,
    "xpubFingerprint": "0x...",
    "registrationAddress": "0x...",
    "basePath": "m/44'/60'/0'",
    "deviceLabel": "Office Trezor",
    "nextAddressIndex": 3
  }
}

Response when absent:

{
  "success": true,
  "data": {
    "registered": false
  }
}

POST /api/trezor/addresses/next

Allocates or returns a deterministic receive address from the registered xpub.

Auth: bearer JWT

Body:

{
  "purpose": "deposit",
  "paymentId": "..."
}

If paymentId already has an assigned address, the same address is returned. Otherwise the backend derives:

m/44'/60'/0'/0/{nextAddressIndex}

POST /api/trezor/operation-message

Builds the exact transaction-intent message an admin must sign when Trezor safekeeping is enabled.

Auth: bearer JWT, admin

Body:

{
  "operation": "release",
  "paymentId": "...",
  "transactionHash": "0x...",
  "amount": 100,
  "currency": "USDT",
  "provider": "request.network"
}

Response:

{
  "success": true,
  "data": {
    "message": "Amanat escrow Trezor transaction approval\n..."
  }
}

POST /api/trezor/verify-operation

Admin-only standalone signature verification endpoint. Verifies a signed operation intent against the admin's registered Trezor safekeeping address without performing any release or refund. Use this to validate a Trezor proof before submitting it to the release/refund flow.

Auth: bearer JWT, admin

Body:

{
  "payload": {
    "operation": "release",
    "paymentId": "...",
    "transactionHash": "0x...",
    "amount": 100,
    "currency": "USDT",
    "provider": "request.network"
  },
  "message": "Amanat escrow Trezor transaction approval\n...",
  "signature": "0x..."
}

Release / Refund Integration

When TREZOR_SAFEKEEPING_REQUIRED=true, release/refund confirmation bodies must include the Trezor proof:

{
  "txHash": "0x...",
  "amount": 100,
  "trezor": {
    "message": "Amanat escrow Trezor transaction approval\n...",
    "signature": "0x..."
  }
}

This proof is optional when enforcement is disabled.