/api/system/decrypt_existing_files

POST

The reverse of encrypt_existing_files: rewrite every encrypted (Type 10, 612-byte) coin file back to plaintext (Type 9, 439-byte). Returns a task_id immediately; the caller polls /api/system/tasks.

POST http://localhost:8080/api/system/decrypt_existing_files

Description

Requires a confirmed session — the password loaded via /api/system/load-password and verified by the RAIDA (key_state: "confirmed"). Per file: a Type 10 file is decrypted in memory and rewritten atomically as plaintext Type 9; plaintext files are skipped. The walk covers the wallet coin folders (Bank, Fracked, Limbo, Suspect, Grade, Pending, Import, Imported).

When the run finishes and no Type 10 files remain in any registered wallet, the session itself is cleared — the next start of the core will not prompt for a password. If other wallets still hold encrypted files, the session is retained (the task's final message says session retained; type10_remaining=N). Decrypted coins stay decrypted until the user chooses to encrypt again.

The operation is idempotent and resumable: if a run is interrupted, encryption-status reports a mixed state and running this endpoint again finishes the job ("Finish Decrypting" in the GUI).

Cross-salt files are skipped, not garbled

Files encrypted under a different wallet's password (a different salt domain) are deliberately left alone — decrypting them with this session's key would silently produce garbage, because Type 10 files carry no password verifier. Collect them with copy_undecryptable.

⚠️ Coins become unprotected at rest

After decryption, anyone with access to the disk can read the coins' authenticity numbers. The GUI should warn the user before starting.

Parameters

One optional parameter, mirroring encrypt_existing_files: wallet_path — the wallet to decrypt (must be a registered wallet, else 400; default: the Default wallet).

Response

Kickoff — 200 OK

{
  "command": "decrypt-existing-files",
  "success": true,
  "task_id": "Jul-30-26_02-10-14-pm-a9b6",
  "url": "http://localhost:8080/api/system/tasks?task_id=Jul-30-26_02-10-14-pm-a9b6",
  "wallet_path": "E:\\Client_Data\\Wallets\\Default",
  "key_state": "confirmed",
  "key_set": true,
  "message": "Decryption started — poll task url for status"
}

Task result counts

{
  "counts": {
    "processed": 45,
    "decrypted": 45,
    "skipped": 0,
    "errors": 0,
    "already_target": 0,
    "skipped_multi": 0,
    "conflict": 0
  }
}
FieldDescription
processedNumber of .bin files visited.
decryptedNumber physically rewritten Type 10 → plaintext Type 9.
skippedNumber left untouched, total (sum of the reasons below plus cross-salt and unreadable files).
already_targetSkipped because already plaintext.
skipped_multiSkipped multi-coin files.
conflictFiles that changed on disk mid-run (concurrent writer). Any conflict fails the task; re-run to converge.
errorsNumber that failed to read or rewrite. Each error is logged to main.log.

If errors > 0 or conflict > 0 the task status is "failed"; files already decrypted stay decrypted and re-running finishes the job.

Error Responses

400 — Confirmed key required

{
  "error": true,
  "message": "Confirmed key required for decrypt_existing_files",
  "code": 400,
  "key_state": "none",
  "key_set": false
}

Decryption requires the correct password verified via RAIDA (key_state: "confirmed"). Call /api/system/load-password first.

400 — Bad wallet

Invalid wallet_path or wallet_path is not a registered wallet.

405 — GET not allowed

Use POST.

500 — Cannot start worker thread

Returned only on memory or thread-creation failure. Should not happen in normal operation.

Related Endpoints