/api/transactions/locker/download
GETDownload CloudCoins from a RAIDA locker using a 32-character hexadecimal locker key. Executes two-phase protocol: Peek to view coins, then Remove to download with new ANs.
Description
The /api/transactions/locker/download endpoint downloads CloudCoins from a RAIDA locker to the active wallet's Import folder. This endpoint implements a secure two-phase protocol:
- Peek Phase (0x0853): Queries all 25 RAIDA servers to retrieve the list of coins stored in the locker (denomination + serial number pairs). Requires 13+ successful responses for cloud consensus.
- Remove Phase (0x0854): Downloads the coins from the locker with newly generated random Authenticity Numbers (ANs). The old locker ANs are discarded, transferring ownership to the downloader.
Downloaded coins are saved to the Import/ folder with their POWN strings embedded in the filename, indicating which RAIDAs successfully transferred each coin.
Important: Downloading coins from a locker is a destructive operation. Once downloaded, the coins are removed from the locker and transferred with new ANs. The sender cannot recover the coins after download.
This endpoint is essential for:
- Receiving CloudCoins sent via locker by another user
- Transferring coins between your own wallets
- Collecting coins from a shared locker after out-of-band key exchange
- Automated locker monitoring and coin retrieval
The locker key is NOT the same as coin ANs. It's a 16-byte password/secret shared out-of-band between sender and receiver. Anyone with the locker key can download the coins, so keep it secret and share only via secure channels.
Parameters
This endpoint requires one query parameter:
| Parameter | Type | Required | Description |
|---|---|---|---|
locker_key |
string | Yes | 32 hexadecimal characters (16 bytes) representing the locker password. Must match the key used when uploading coins to the locker. |
Parameter Validation
- Must be exactly 32 characters long
- Must contain only hexadecimal characters (0-9, a-f, A-F)
- Case-insensitive (0A1B2C3D = 0a1b2c3d)
Two-Phase Protocol
Phase 1: Locker Peek (0x0853)
The Peek phase queries all 25 RAIDA servers to retrieve the list of coins in the locker without downloading them.
Request Structure:
- Challenge: 16 bytes (random + CRC32)
- Locker Key: 16 bytes
- Terminator: 0x3E3E (2 bytes)
Response Structure:
- ALL_PASS (0xF1): Returns list of DN+SN pairs for all coins
- ALL_FAIL (0xF2): Wrong locker key or locker doesn't exist
- Error codes: RAIDA server errors
Consensus Requirements:
- Minimum 13 successful Peek responses required (out of 25 RAIDAs)
- If <13 RAIDAs respond: Network issues (503 error)
- If <13 successful peeks: Wrong key or locker doesn't exist (404 error)
Phase 2: Locker Remove (0x0854)
The Remove phase downloads the coins from the locker with newly generated random ANs, transferring ownership.
Request Structure:
- Challenge: 16 bytes (random + CRC32)
- Locker Key: 16 bytes
- For each coin:
- Denomination: 1 byte
- Serial Number: 4 bytes
- New AN: 16 bytes (randomly generated)
- Terminator: 0x3E3E (2 bytes)
Response Structure:
- ALL_PASS (0xF1): All coins successfully removed and updated
- ALL_FAIL (0xF2): All coins failed (wrong key or expired)
- MIXED (0xF3): Some coins succeeded, some failed (bitfield response)
- Error codes: RAIDA server errors
POWN String Update:
Based on each RAIDA's response, the coin's POWN string is updated:
- 'p' (0x0A): Pass - coin successfully downloaded from this RAIDA
- 'f' (0x0F): Fail - authentication failed
- 'e' (0x0E): Error - RAIDA error occurred
- 'n' (0x0C): No reply - timeout
Response
Returns a JSON object with download results and coin details.
Success Response Properties
Success Response Example
{
"status": "success",
"operation": "locker_download",
"coins_found": 5,
"coins_saved": 5,
"destination": "Import",
"locker_key": "0123456789abcdef0123456789abcdef"
}
Error Responses
400 Bad Request - Invalid locker_key
{
"status": "error",
"error": "Invalid locker_key (must be 32 hex characters)",
"http_code": 400
}
404 Not Found - Locker not found or wrong key
{
"status": "error",
"error": "Locker not found",
"http_code": 404
}
This error occurs when fewer than 13 RAIDAs successfully peek the locker, indicating either a wrong locker key or the locker doesn't exist.
404 Not Found - Locker is empty
{
"status": "error",
"error": "Locker is empty",
"http_code": 404
}
The locker was found and peeked successfully, but contains no coins.
500 Internal Server Error - Request generation failed
{
"status": "error",
"error": "Failed to generate RAIDA requests",
"http_code": 500
}
500 Internal Server Error - Memory allocation failed
{
"status": "error",
"error": "Memory allocation failed",
"http_code": 500
}
503 Service Unavailable - Insufficient RAIDA responses
{
"status": "error",
"error": "Insufficient RAIDA responses",
"http_code": 503
}
Fewer than 13 RAIDAs responded at all (network connectivity issues). Try again later.
Downloaded Coin Files
Downloaded coins are saved to the active wallet's Import/ folder with the following filename format:
{value} CloudCoin #{serial} '{pown_string}'.bin
Filename Components:
- {value}: Coin denomination value (e.g., 1, 5, 25, 100, 250)
- {serial}: Coin serial number (0-16777215)
- {pown_string}: 25-character POWN string showing download status per RAIDA
Example Filenames:
250 CloudCoin #1234567 'ppppppppppppppppppppppppp'.bin
100 CloudCoin #8901234 'pppppppppppppnfpppppppppp'.bin
1 CloudCoin #5678901 'pppppppppppppeepppppppnpp'.bin
- 25 passes (all 'p'): Fully authenticated coin - move to Bank
- 13-24 passes: Authentic but fracked - move to Fracked folder, run Fix command
- <13 passes: Counterfeit or failed - move to Counterfeit folder
Post-Download Workflow
After downloading coins from a locker, follow this recommended workflow:
Download Coins
Call /api/transactions/locker/download with your locker key. Coins are saved to Import/ folder.
Unpack (if needed)
If multi-coin files were downloaded, run /api/coins/unpack to extract individual coins.
Authenticate
Run /api/coins/authenticate to verify the downloaded coins with all 25 RAIDAs.
Grade
Run /api/coins/grade to automatically sort coins based on POWN strings:
- Bank: 25/25 passes (fully authenticated)
- Fracked: 13-24 passes (authentic but damaged)
- Counterfeit: <13 passes (rejected)
Fix Fracked Coins (optional)
If any coins ended up in Fracked folder, run /api/coins/fix to heal them and move to Bank.
Examples
JavaScript (fetch)
const API_HOST = 'http://localhost:8080';
async function downloadFromLocker(lockerKey) {
try {
const response = await fetch(
`${API_HOST}/api/transactions/locker/download?locker_key=${lockerKey}`
);
const result = await response.json();
if (result.status === 'success') {
console.log(`Downloaded ${result.coins_saved} coins to Import folder`);
console.log(`Total coins found: ${result.coins_found}`);
console.log(`Locker key: ${result.locker_key}`);
// Next: Run authenticate and grade commands
await authenticateCoins();
await gradeCoins();
} else {
console.error(`Error: ${result.error} (HTTP ${result.http_code})`);
}
} catch (error) {
console.error('Network error:', error);
}
}
async function authenticateCoins() {
const response = await fetch(`${API_HOST}/api/coins/authenticate`);
const result = await response.json();
console.log('Authentication complete:', result);
}
async function gradeCoins() {
const response = await fetch(`${API_HOST}/api/coins/grade`);
const result = await response.json();
console.log('Grading complete:', result);
}
// Example: Download coins from locker
const lockerKey = '0123456789abcdef0123456789abcdef';
downloadFromLocker(lockerKey);
cURL
# Download coins from locker
curl -X GET "http://localhost:8080/api/transactions/locker/download?locker_key=0123456789abcdef0123456789abcdef"
# Example output:
# {
# "status": "success",
# "operation": "locker_download",
# "coins_found": 5,
# "coins_saved": 5,
# "destination": "Import",
# "locker_key": "0123456789abcdef0123456789abcdef"
# }
# Complete workflow: Download, authenticate, and grade
curl -X GET "http://localhost:8080/api/transactions/locker/download?locker_key=0123456789abcdef0123456789abcdef"
curl -X GET "http://localhost:8080/api/coins/authenticate"
curl -X GET "http://localhost:8080/api/coins/grade"
Go
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
const ApiHost = "http://localhost:8080"
type LockerDownloadResponse struct {
Status string `json:"status"`
Operation string `json:"operation"`
CoinsFound int `json:"coins_found"`
CoinsSaved int `json:"coins_saved"`
Destination string `json:"destination"`
LockerKey string `json:"locker_key"`
}
type ErrorResponse struct {
Status string `json:"status"`
Error string `json:"error"`
HTTPCode int `json:"http_code"`
}
func downloadFromLocker(lockerKey string) error {
url := fmt.Sprintf("%s/api/transactions/locker/download?locker_key=%s",
ApiHost, lockerKey)
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
if resp.StatusCode == 200 {
var result LockerDownloadResponse
if err := json.Unmarshal(body, &result); err != nil {
return err
}
fmt.Printf("Success! Downloaded %d coins to %s folder\n",
result.CoinsSaved, result.Destination)
fmt.Printf("Total coins found: %d\n", result.CoinsFound)
fmt.Printf("Locker key: %s\n", result.LockerKey)
// Next steps: authenticate and grade
authenticateCoins()
gradeCoins()
return nil
} else {
var errResp ErrorResponse
if err := json.Unmarshal(body, &errResp); err != nil {
return err
}
return fmt.Errorf("Error %d: %s", errResp.HTTPCode, errResp.Error)
}
}
func authenticateCoins() error {
resp, err := http.Get(fmt.Sprintf("%s/api/coins/authenticate", ApiHost))
if err != nil {
return err
}
defer resp.Body.Close()
fmt.Println("Authentication complete")
return nil
}
func gradeCoins() error {
resp, err := http.Get(fmt.Sprintf("%s/api/coins/grade", ApiHost))
if err != nil {
return err
}
defer resp.Body.Close()
fmt.Println("Grading complete")
return nil
}
func main() {
lockerKey := "0123456789abcdef0123456789abcdef"
if err := downloadFromLocker(lockerKey); err != nil {
fmt.Printf("Error: %v\n", err)
}
}
Technical Details
RAIDA Protocol
Command Codes:
- 0x0853: Locker Peek - Query locker contents
- 0x0854: Locker Remove - Download and remove coins
Timeout Configuration:
- Per-RAIDA timeout: 10 seconds (10000ms)
- Parallel execution: All 25 RAIDAs queried simultaneously
- Total operation time: ~10-15 seconds (single timeout period)
Cloud Consensus Algorithm:
- Send Peek requests to all 25 RAIDAs in parallel
- Count successful responses (status = ALL_PASS)
- If <13 RAIDAs respond at all → Network error (503)
- If <13 successful peeks → Wrong key or no locker (404)
- If ≥13 successful peeks → Use first RAIDA's coin list (all should match)
- Proceed to Remove phase with consensus coin list
New AN Generation:
For security, new random ANs are generated for each coin during download:
- Each coin gets 25 new 16-byte random ANs (one per RAIDA)
- Random source: BCrypt (Windows) or /dev/urandom (Unix)
- Old locker ANs are discarded and cannot be recovered
- Sender has no knowledge of the new ANs after download
File Format
Binary File Structure (CloudCoin v3, Format 9):
- File Header: 32 bytes
- Format ID: 9 (1 byte)
- Coin ID: 0x0006 (2 bytes)
- Encryption: 0 (1 byte - unencrypted)
- Password hash: 7 bytes (empty for unencrypted)
- POWN string: 12.5 bytes (25 nibbles, 4-bit packed)
- Reserved: 8 bytes
- Token count: 1 (2 bytes - single coin file)
- Coin Header: 7 bytes
- Split: 0 (1 byte)
- Shard: 0 (1 byte)
- Denomination: -8 to +11 (1 byte)
- Serial Number: 0-16777215 (4 bytes)
- Coin Body: 400 bytes
- 25 Authenticity Numbers × 16 bytes each
- Each AN is a random 128-bit value
- Total file size: 439 bytes per coin
Related Endpoints
/api/raida/lockers/peek
Peek at locker contents without downloading. View which coins are available before committing to download.
/api/raida/locker/upload
Upload CloudCoins to a locker for transfer to another user or wallet.
/api/coins/import
Import coins from various file formats (binary, JSON, PNG, JPEG) into the active wallet.
/api/coins/authenticate
Authenticate coins by checking with all 25 RAIDA servers and updating POWN strings.
/api/coins/grade
Sort coins into Bank, Fracked, or Counterfeit folders based on POWN string authentication results.
/api/coins/fix
Heal fracked coins (13-24 passes) using RAIDA ticket-based repair protocol.