/api/transactions/locker/upload

GET

Upload CloudCoins from your wallet to a RAIDA locker using a secure locker key.

Description

The /api/transactions/locker/upload endpoint uploads CloudCoins from your wallet to the RAIDA cloud locker system. This endpoint supports two modes of operation:

Two Upload Modes
  • Single Coin Mode: Use the denomination parameter to upload exactly one coin of a specific denomination.
  • Amount Mode: Use the amount parameter to upload coins totaling a specific value (uses greedy selection).

The endpoint performs a multi-phase operation:

  1. Coin Selection: Reads coins from the Bank folder and selects based on mode (single denomination or amount).
  2. RAIDA Upload: Sends Locker Put (0x0852) requests to all 25 RAIDAs in parallel with XOR-sum verification.
  3. Consensus Verification: Requires 13+ successful RAIDA responses (cloud consensus) to complete the upload.
Security Warning

The locker_key parameter is essentially a password. Anyone with this key can download the coins from the locker. Keep it secret and share it securely with the intended recipient only.

Parameters

This endpoint requires locker_key plus either denomination (single coin) or amount (multiple coins).

Query Parameters

Parameter Type Required Description
locker_key string Yes Any string of characters (e.g., "ABC-1234"). This becomes the password to access the locker.
denomination number No* Single Coin Mode. Upload exactly one coin of this denomination. Values are metric (powers of 10) including fractional: 0.00000001, 0.0000001, ..., 0.1, 1, 10, 100, ..., 1000000. *Required if amount not provided.
amount integer No* Amount Mode. Upload coins totaling this many whole CloudCoin units. Uses greedy selection (largest denominations first). *Required if denomination not provided.
wallet_path string No Full path to the wallet directory containing the coins. If omitted, uses the default wallet.
wallet string No Wallet name (alternative to wallet_path). Looks up wallet in standard locations.
Metric Denomination Values

Denominations are metric (powers of 10). Pass the actual value, not a code:

Denomination ParameterNameDescription
0.00000001Nanno10-8 CloudCoin (smallest unit)
0.0000001Micro-Cent10-7 CloudCoin
0.000001Milli-Cent10-6 CloudCoin
0.00001Centi-Cent10-5 CloudCoin
0.0001Deci-Cent10-4 CloudCoin
0.001Cent10-3 CloudCoin (1/1000)
0.01Deci10-2 CloudCoin (1/100)
0.1One-Tenth10-1 CloudCoin (1/10)
1One1 CloudCoin
10Ten10 CloudCoins
100Hundred100 CloudCoins
1000Thousand1,000 CloudCoins
10000Ten-K10,000 CloudCoins
100000Hundred-K100,000 CloudCoins
1000000Million1,000,000 CloudCoins

Locker Key Format

The locker_key can be any string. We recommend a format like "ABC-1234" for easy sharing, but any characters work.

Example locker_key values:

CUP-1974
MySecret2025
ABC-DEFG-1234
gift-for-alice

Important: The same locker_key always accesses the same locker. Keep your locker_key secret and share it securely with the intended recipient only. Anyone with the locker_key can download the coins.

RAIDA Protocol Details

This endpoint uses the RAIDA Locker Put command (0x0852).

Command Code

0x0852 (Command Group: 0x08 = Locker, Command: 0x52 = Put)

Request Body Format

N x [DN(1 byte) + SN(4 bytes)]    // Token records
+ XOR_SUM(16 bytes)                // XOR of all ANs for this RAIDA
+ LOCKER_CODE(16 bytes)            // Per-RAIDA derived locker code (ends with 0xFFFFFFFF)

Body size = (N x 5) + 16 + 16 = (N x 5) + 32 bytes, where N is the number of coins.

XOR Sum Calculation

Each coin's AN (16 bytes) is treated as four little-endian 32-bit integers. All coins' ANs are XORed together to produce the 16-byte sum. The RAIDA verifies this sum matches its stored ANs.

Response Status Codes

  • 241 (Sum Was Correct): All coins uploaded successfully
  • 242 (Sum Was Not Correct): XOR sum mismatch - coin may be counterfeit or already in a locker

Consensus Requirement

Requires 13 or more out of 25 RAIDAs to return status 241 for success.

Response

Returns a JSON object with upload results. Response format varies slightly between single coin and amount modes.

Example: Single Coin Mode Success

{
  "status": "success",
  "operation": "locker_upload",
  "denomination": 1,
  "amount_uploaded": 1,
  "coins_uploaded": 1,
  "locker_key": "NEW-KEY1",
  "successful_uploads": 24,
  "message": "Single coin uploaded to locker"
}

Example: Amount Mode Success

{
  "status": "success",
  "operation": "locker_upload",
  "amount_requested": 500,
  "amount_uploaded": 500,
  "coins_uploaded": 3,
  "locker_key": "CUP-1974",
  "successful_uploads": 24,
  "message": "Coins uploaded to locker successfully"
}

Response Properties

status string
"success" or "error"
operation string
Always "locker_upload"
denomination number
(Single coin mode only) The denomination that was uploaded (0.00000001 to 1000000).
amount_requested integer
(Amount mode only) The amount of CloudCoins requested to upload.
amount_uploaded integer
The actual amount of CloudCoins uploaded (whole units).
coins_uploaded integer
Number of individual coins uploaded.
locker_key string
The locker key used for the upload.
successful_uploads integer
Number of RAIDAs that successfully confirmed the upload (out of 25). Should be 13+ for success.
message string
Human-readable message.

Error Responses

The endpoint returns appropriate HTTP status codes with JSON error messages.

HTTP 400 - Bad Request

  • Missing or empty locker_key parameter
  • Missing both amount and denomination parameters
  • Invalid amount (must be greater than 0)
  • Insufficient balance in wallet
  • Invalid wallet path

HTTP 404 - Not Found

  • No coins in Bank folder
  • No coin of requested denomination found (single coin mode)
  • Wallet not found

HTTP 500 - Internal Server Error

  • Upload failed - insufficient RAIDA confirmations (fewer than 13)
  • Failed to get encryption keys

Example Error Response

{
  "status": "error",
  "operation": "locker_upload",
  "message": "Upload failed - insufficient RAIDA confirmations",
  "error": "Success",
  "locker_key": "MY-KEY",
  "successful_uploads": 0,
  "failed_uploads": 25
}

Examples

cURL

# Single Coin Mode: Upload one 1 CC coin
curl "http://localhost:8080/api/transactions/locker/upload?locker_key=MY-KEY&denomination=1"

# Single Coin Mode: Upload one 0.01 CC (1 cent) coin
curl "http://localhost:8080/api/transactions/locker/upload?locker_key=PENNY&denomination=0.01"

# Single Coin Mode: Upload one 100 CC coin from specific wallet
curl "http://localhost:8080/api/transactions/locker/upload?locker_key=GIFT-CODE&denomination=100&wallet_path=/path/to/wallet"

# Single Coin Mode: Upload one 1000 CC coin
curl "http://localhost:8080/api/transactions/locker/upload?locker_key=BIG-ONE&denomination=1000"

# Single Coin Mode: Upload smallest denomination (nanno)
curl "http://localhost:8080/api/transactions/locker/upload?locker_key=TINY-COIN&denomination=0.00000001"

# Amount Mode: Upload 500 CloudCoins worth of coins
curl "http://localhost:8080/api/transactions/locker/upload?locker_key=CUP-1974&amount=500"

# Amount Mode: Upload 100 CloudCoins from a named wallet
curl "http://localhost:8080/api/transactions/locker/upload?locker_key=ABC-1234&amount=100&wallet=MyWallet"

JavaScript (fetch)

const API_HOST = 'http://localhost:8080';

// Upload a single coin by denomination
async function uploadSingleCoin(lockerKey, denomination, walletPath = null) {
    let url = `${API_HOST}/api/transactions/locker/upload?` +
              `locker_key=${encodeURIComponent(lockerKey)}&` +
              `denomination=${denomination}`;

    if (walletPath) {
        url += `&wallet_path=${encodeURIComponent(walletPath)}`;
    }

    const response = await fetch(url);
    const result = await response.json();

    if (result.status === 'success') {
        console.log(`Uploaded 1 coin (denom ${denomination}) to locker`);
        console.log(`RAIDAs confirmed: ${result.successful_uploads}/25`);
    } else {
        console.error('Upload failed:', result.message);
    }
    return result;
}

// Upload coins by amount
async function uploadByAmount(lockerKey, amount, walletPath = null) {
    let url = `${API_HOST}/api/transactions/locker/upload?` +
              `locker_key=${encodeURIComponent(lockerKey)}&` +
              `amount=${amount}`;

    if (walletPath) {
        url += `&wallet_path=${encodeURIComponent(walletPath)}`;
    }

    const response = await fetch(url);
    const result = await response.json();

    if (result.status === 'success') {
        console.log(`Uploaded ${result.coins_uploaded} coins (${result.amount_uploaded} CC)`);
        console.log(`RAIDAs confirmed: ${result.successful_uploads}/25`);
    } else {
        console.error('Upload failed:', result.message);
    }
    return result;
}

// Examples:
// Upload one 1 CC coin
uploadSingleCoin('GIFT-CODE', 1);

// Upload one 0.01 CC coin (1 cent)
uploadSingleCoin('PENNY', 0.01);

// Upload one 100 CC coin
uploadSingleCoin('MY-KEY', 100);

// Upload one 1000 CC coin from specific wallet
uploadSingleCoin('BIG-ONE', 1000, 'E:/Wallets/MyWallet');

// Upload smallest denomination (nanno)
uploadSingleCoin('TINY', 0.00000001);

// Upload 500 CloudCoins worth (amount mode)
uploadByAmount('CUP-1974', 500);

Go

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
)

const ApiHost = "http://localhost:8080"

type LockerUploadResponse struct {
    Status            string  `json:"status"`
    Operation         string  `json:"operation"`
    Denomination      float64 `json:"denomination,omitempty"`
    AmountRequested   int     `json:"amount_requested,omitempty"`
    AmountUploaded    int     `json:"amount_uploaded"`
    CoinsUploaded     int     `json:"coins_uploaded"`
    LockerKey         string  `json:"locker_key"`
    SuccessfulUploads int     `json:"successful_uploads"`
    Message           string  `json:"message"`
}

// Upload a single coin by denomination (supports fractional: 0.00000001 to 1000000)
func uploadSingleCoin(lockerKey string, denomination float64, walletPath string) (*LockerUploadResponse, error) {
    params := url.Values{}
    params.Add("locker_key", lockerKey)
    params.Add("denomination", fmt.Sprintf("%g", denomination))
    if walletPath != "" {
        params.Add("wallet_path", walletPath)
    }

    fullURL := fmt.Sprintf("%s/api/transactions/locker/upload?%s", ApiHost, params.Encode())
    return doRequest(fullURL)
}

// Upload coins by amount
func uploadByAmount(lockerKey string, amount int, walletPath string) (*LockerUploadResponse, error) {
    params := url.Values{}
    params.Add("locker_key", lockerKey)
    params.Add("amount", fmt.Sprintf("%d", amount))
    if walletPath != "" {
        params.Add("wallet_path", walletPath)
    }

    fullURL := fmt.Sprintf("%s/api/transactions/locker/upload?%s", ApiHost, params.Encode())
    return doRequest(fullURL)
}

func doRequest(url string) (*LockerUploadResponse, error) {
    resp, err := http.Get(url)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    body, _ := ioutil.ReadAll(resp.Body)
    var result LockerUploadResponse
    json.Unmarshal(body, &result)
    return &result, nil
}

func main() {
    // Upload one 1 CC coin
    result, _ := uploadSingleCoin("GIFT-CODE", 1.0, "")
    fmt.Printf("Single coin: %s (%d/25 RAIDAs)\n", result.Status, result.SuccessfulUploads)

    // Upload one 0.01 CC coin (1 cent)
    result, _ = uploadSingleCoin("PENNY", 0.01, "")
    fmt.Printf("Cent coin: %s (%d/25 RAIDAs)\n", result.Status, result.SuccessfulUploads)

    // Upload one 1000 CC coin
    result, _ = uploadSingleCoin("BIG-ONE", 1000.0, "")
    fmt.Printf("1000 CC coin: %s (%d/25 RAIDAs)\n", result.Status, result.SuccessfulUploads)

    // Upload 500 CloudCoins worth (amount mode)
    result, _ = uploadByAmount("CUP-1974", 500, "")
    fmt.Printf("Amount mode: %s (%d coins, %d/25 RAIDAs)\n",
               result.Status, result.CoinsUploaded, result.SuccessfulUploads)
}

Related Endpoints

/api/locker/peek

View the contents of a locker without downloading the coins. Check what's inside before downloading.

/api/transactions/locker/download

Download coins from a locker to your wallet using the locker key.

/api/wallet/balance

Check your wallet balance before uploading coins to ensure sufficient funds.

Implementation Notes

Best Practices
  • Test First: Use small denominations (denomination=0.00000001) when testing
  • Check Balance: Ensure wallet has coins before uploading
  • Secure Keys: Use memorable but unpredictable locker keys
  • Share Safely: Only share locker keys through secure channels
  • Verify Upload: Check successful_uploads - should be 13+ for success, 24-25 for optimal reliability
Common Issues
  • Invalid Denomination: Must be a metric value (power of 10): 0.00000001 through 1000000. Values like 5, 25, 50 are not valid.
  • 0/25 Success: Coin may already be in a locker, or ANs are out of sync. Run frack fix first.
  • Coin Not Found: Ensure the coin is in the Bank folder, not Fracked or other folders.
  • Same Key Reuse: Using the same locker_key creates a new locker or overwrites - recipient gets all coins uploaded with that key.