/api/system/load-password
POSTLoad the file-decryption password into RAM. While the password is loaded, encrypted (Type 10) coin files can be decrypted in memory as needed, and coin encryption operations become possible.
This endpoint replaces /api/system/login. The old URL is no longer registered. Its counterpart, /api/system/logout, is replaced by /api/system/shutdown, which deletes the password from RAM and shuts the core down.
Description
/api/system/load-password accepts a password in a form-encoded POST body and holds the derived key in RAM. It is deliberately not called "login": no account exists, and nothing is stored on disk. The password is the only thing standing between the encrypted coin files and their authenticity numbers — the server keeps it (as a derived key) in memory until /api/system/shutdown is called or the process exits.
How the password is verified: encrypted Type 10 coin files intentionally contain no password check of any kind — nothing on disk can prove a password right or wrong. The core verifies a candidate password by decrypting one coin and asking the RAIDA (detect). If the RAIDA rejects the result, the response is bad password. This requires network access.
The Type 10 encrypted file format is being implemented. In the current build this endpoint stores the password and returns success without RAIDA verification (there are no Type 10 files yet to verify against). The bad password response described here activates together with Type 10 support. Track the plan in core/docs/file-encryption/.
- POST only. GET requests are rejected with
405— a password in a URL would be written toClient_Data/main.logand to any proxy or browser history logs. - Lost password = lost coins. Once files are encrypted, there is no recovery if the password is forgotten. The GUI must warn the user and require the password to be typed twice when encrypting for the first time.
- UTF-8 byte exactness. The key is derived from the raw bytes the client sends. Encode non-ASCII characters as UTF-8 (form-encode with
--data-urlencode/FormData) so every client derives the same key. - Use HTTPS in any deployment that is not loopback-only.
Client Flow — what to call, in what order
- Call
GET /api/system/encryption-statusat startup, before showing the dashboard.- If encrypted files exist and no key is loaded, prompt for the password before the dashboard appears.
- If no encrypted files exist, no prompt is needed. The wallet is decrypted.
- Send the password with
POST /api/system/load-password. - On
bad password(once Type 10 verification is live), let the user retry. On success, show the dashboard. - To encrypt a decrypted wallet, call
/api/system/encrypt_existing_files. To decrypt, call/api/system/decrypt_existing_files. - When the user logs out, call
POST /api/system/shutdown— it deletes the password from RAM and shuts the core down; the GUI should then exit too.
Parameters
| Parameter | Location | Type | Required | Description |
|---|---|---|---|---|
password |
POST body (form-encoded) | string | Required | The user's password as raw UTF-8 bytes. Any characters are accepted. Minimum 1 byte; maximum 4096 bytes (HTTP layer ceiling). |
Response
Success — 200 OK
{
"command": "load-password",
"success": true,
"message": "Password loaded into RAM. Verification is deferred until Type 10 encrypted files exist (RAIDA confirmation).",
"key_set": true
}
Response Fields
| Field | Type | Description |
|---|---|---|
key_set | bool | Always true on a 200 response. The derived key is now in RAM. |
Error Responses
400 — Password missing
{
"error": true,
"message": "Missing required parameter: password",
"code": 400
}
405 — GET not allowed
{
"error": true,
"message": "Use POST: a password in a GET URL would be written to server and proxy logs",
"code": 405
}
Bad password (activates with Type 10 support)
When encrypted Type 10 files exist, the core verifies the candidate password by decrypting one coin and running RAIDA detect. If the RAIDA rejects it, the response reports bad password and the key is cleared so the user can retry. If the RAIDA is unreachable, the result is inconclusive: the wallet opens locked/read-only until verification succeeds.
500 — Internal failure
Returned when the key could not be derived or installed. Should not happen in normal operation.
Example Usage
curl -X POST \
-H "Content-Type: application/x-www-form-urlencoded; charset=utf-8" \
--data-urlencode "password=¥CheeseCake£" \
"http://localhost:8080/api/system/load-password"
const body = new URLSearchParams();
body.set('password', '¥CheeseCake£');
const res = await fetch('http://localhost:8080/api/system/load-password', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8' },
body: body
});
const data = await res.json();
// data.key_set === true → password is in RAM; show the dashboard.
import requests
url = 'http://localhost:8080/api/system/load-password'
resp = requests.post(url, data={'password': '¥CheeseCake£'})
print(resp.json())
# {'command': 'load-password', 'success': True, 'key_set': True, ...}
Related Endpoints
- /api/system/encryption-status — Call this BEFORE prompting: it says whether a password is needed at all.
- /api/system/shutdown — Delete the password from RAM and shut the core down (the GUI log-out).
- /api/system/encrypt_existing_files — Encrypt all plaintext coin files.
- /api/system/decrypt_existing_files — Decrypt all encrypted coin files.