/api/raida/locker/upload

GET

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

Description

The /api/raida/locker/upload endpoint uploads CloudCoins from your wallet to the RAIDA cloud locker system. This is a secure way to store coins temporarily on the RAIDA network or to send coins to someone who knows the locker code.

The endpoint performs a two-phase operation:

  1. Coin Selection: Reads coins from Bank and Fracked folders, selects coins using a greedy algorithm to meet the requested amount.
  2. RAIDA Upload: Sends Locker Put (0x0852) requests to all 25 RAIDAs in parallel with the selected coins and derived locker key.
  3. Consensus Verification: Requires 13+ successful RAIDA responses (cloud consensus) to complete the upload.
  4. File Management: Successfully uploaded coins are moved to the Lockered folder.
Use Cases
  • Secure Transfers: Send coins to someone by sharing the locker_code out-of-band (SMS, email, secure messaging)
  • Cloud Storage: Temporarily store coins in the RAIDA cloud
  • Cross-Wallet Transfers: Transfer coins between your own wallets
  • Gift Coins: Gift coins using a shared secret code
Security Warning

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

  • Use strong, unique locker codes (mix of letters, numbers, symbols)
  • Share codes through secure channels only
  • The same locker_code always generates the same locker_key (deterministic)

Parameters

This endpoint requires two query parameters.

Query Parameters

Parameter Type Required Description
locker_code string Yes Text string to hash into a 16-byte locker key. This is the "password" for the locker. Can be any text (letters, numbers, symbols).
amount integer Yes Number of whole CloudCoin units to upload (e.g., 1, 5, 25, 100, 500). Must be greater than 0.

Locker Key Generation

The locker key is a 16-byte value derived from the locker_code parameter using a simple XOR hash:

// Initialize locker_key to all zeros
uint8_t locker_key[16] = {0};

// XOR each character of locker_code into the key
for (size_t i = 0; i < strlen(locker_code); i++) {
    locker_key[i % 16] ^= (uint8_t)locker_code[i];
}

// Set last 4 bytes to 0xFFFFFFFF (protocol requirement)
locker_key[12] = 0xFF;
locker_key[13] = 0xFF;
locker_key[14] = 0xFF;
locker_key[15] = 0xFF;

Important: The same locker_code always generates the same locker_key. This is by design - it allows the recipient to download coins by providing the same code.

RAIDA Protocol Details

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

Command Code

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

Request Format

Challenge(16 bytes)
+ LockerKey(16 bytes)
+ [DN(1) + SN(4) + AN(16)] × N coins
+ Terminator(0x3E3E)

Response Formats

  • STATUS_ALL_PASS (241): All coins uploaded successfully
  • STATUS_ALL_FAIL (242): All coins failed to upload
  • STATUS_MIXED (243): Some coins succeeded, some failed - includes bitfield
  • Error codes: Various error statuses for request/protocol errors

Consensus Requirement

Requires 13 or more out of 25 RAIDAs to successfully upload for cloud consensus. If fewer than 13 RAIDAs confirm the upload, the operation fails and coins remain in their original folders.

Response

Returns a JSON object with upload results.

Response Properties (Success)

status string
Always "success" for successful uploads.
operation string
Always "locker_upload".
amount_requested integer
The amount of CloudCoins requested to upload (whole units).
amount_uploaded integer
The actual amount of CloudCoins uploaded (whole units). May be slightly more than requested due to coin denominations.
coins_uploaded integer
Number of individual coin files uploaded.
locker_key string
The 32-character hex representation of the derived locker key (for debugging/verification).
successful_uploads integer
Number of RAIDAs that successfully confirmed the upload (out of 25).
message string
Human-readable success message.

Example Success Response

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

Error Responses

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

HTTP 400 - Bad Request

  • No active wallet set
  • Missing or empty locker_code parameter
  • Missing amount parameter
  • Invalid amount (must be greater than 0)
  • Insufficient balance in wallet

HTTP 500 - Internal Server Error

  • Failed to read Bank folder
  • Failed to read Fracked folder
  • Failed to generate RAIDA requests
  • Upload failed - insufficient RAIDA confirmations (fewer than 13)

Example Error Response

{
  "status": "error",
  "message": "Insufficient funds in wallet",
  "code": 400
}

Coin Selection Algorithm

The endpoint uses a greedy algorithm to select coins for upload:

  1. Reads all coins from the Bank folder
  2. Reads all coins from the Fracked folder
  3. Sorts coins by denomination (largest first)
  4. Selects coins greedily until the requested amount is met or exceeded
  5. If insufficient funds, returns a 400 error with available balance

The actual amount uploaded may be slightly more than requested due to coin denominations. For example, if you request 100 units but only have denominations of 250, one 250 coin will be uploaded.

Post-Upload Process

After RAIDA responses are received:

Successful Upload (13+ RAIDAs confirm)

  1. Coins are moved from Bank/Fracked folders to the Lockered folder
  2. Original coin files are deleted from Bank/Fracked
  3. Lockered folder is created automatically if it doesn't exist
  4. Success response is returned with upload details

Failed Upload (Fewer than 13 RAIDAs confirm)

  1. Coins remain in their original folders (Bank/Fracked)
  2. No files are moved or deleted
  3. Error response is returned with failure reason

Examples

JavaScript (fetch)

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

async function uploadToLocker(lockerCode, amount) {
    try {
        const url = `${API_HOST}/api/raida/locker/upload?` +
                   `locker_code=${encodeURIComponent(lockerCode)}&` +
                   `amount=${amount}`;

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

        if (result.status === 'success') {
            console.log('Upload Successful!');
            console.log(`Coins uploaded: ${result.coins_uploaded}`);
            console.log(`Amount uploaded: ${result.amount_uploaded} units`);
            console.log(`RAIDAs confirmed: ${result.successful_uploads} / 25`);
            console.log(`Locker key: ${result.locker_key}`);
            console.log('\nShare this locker code with recipient:');
            console.log(lockerCode);
        } else {
            console.error('Upload failed:', result.message);
        }
    } catch (error) {
        console.error('Error uploading to locker:', error);
    }
}

// Example: Upload 500 CloudCoins with secure code
uploadToLocker('MySecretCode2025!', 500);

cURL

# Upload 500 CloudCoins to locker
curl -X GET "http://localhost:8080/api/raida/locker/upload?locker_code=MySecretCode2025!&amount=500"

# Example with URL encoding for special characters
curl -X GET "http://localhost:8080/api/raida/locker/upload?locker_code=My%20Secret%20Code%202025%21&amount=100"

# Example with insufficient funds (will return 400 error)
curl -X GET "http://localhost:8080/api/raida/locker/upload?locker_code=test&amount=999999"

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"`
    AmountRequested   int    `json:"amount_requested"`
    AmountUploaded    int    `json:"amount_uploaded"`
    CoinsUploaded     int    `json:"coins_uploaded"`
    LockerKey         string `json:"locker_key"`
    SuccessfulUploads int    `json:"successful_uploads"`
    Message           string `json:"message"`
}

func uploadToLocker(lockerCode string, amount int) error {
    // Build URL with query parameters
    baseURL := fmt.Sprintf("%s/api/raida/locker/upload", ApiHost)
    params := url.Values{}
    params.Add("locker_code", lockerCode)
    params.Add("amount", fmt.Sprintf("%d", amount))

    fullURL := fmt.Sprintf("%s?%s", baseURL, params.Encode())

    resp, err := http.Get(fullURL)
    if err != nil {
        return fmt.Errorf("HTTP request failed: %v", err)
    }
    defer resp.Body.Close()

    body, _ := ioutil.ReadAll(resp.Body)

    var result LockerUploadResponse
    if err := json.Unmarshal(body, &result); err != nil {
        return fmt.Errorf("JSON decode failed: %v", err)
    }

    if result.Status == "success" {
        fmt.Println("Upload Successful!")
        fmt.Printf("Coins uploaded: %d\n", result.CoinsUploaded)
        fmt.Printf("Amount uploaded: %d units\n", result.AmountUploaded)
        fmt.Printf("RAIDAs confirmed: %d / 25\n", result.SuccessfulUploads)
        fmt.Printf("Locker key: %s\n", result.LockerKey)
        fmt.Printf("\nShare this locker code with recipient:\n%s\n", lockerCode)
    } else {
        fmt.Printf("Upload failed: %s\n", result.Message)
    }

    return nil
}

func main() {
    // Upload 500 CloudCoins with secure code
    if err := uploadToLocker("MySecretCode2025!", 500); err != nil {
        panic(err)
    }
}

Related Endpoints

/api/raida/lockers/peek

View the contents of a locker without downloading the coins. Check balance before downloading.

/api/transactions/locker/download

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

/api/wallet/balance

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

Implementation Notes

Production Ready

This endpoint is fully implemented and production-ready (CloudCoinConsole v192+). All features are complete and tested:

  • Parallel RAIDA execution (all 25 RAIDAs queried simultaneously)
  • Greedy coin selection algorithm
  • Cloud consensus (13/25 threshold)
  • Automatic folder management (Lockered folder creation)
  • Proper error handling and rollback on failure
Best Practices
  • Test First: Use small amounts (1-5 units) when testing
  • Check Balance: Call /api/wallet/balance before uploading
  • Secure Codes: Use strong, random locker codes (12+ characters with mixed case, numbers, symbols)
  • Share Safely: Only share locker codes through secure channels (encrypted messaging, in person, etc.)
  • Verify Upload: Check the successful_uploads field - should be 24-25 for optimal reliability
  • Timeout: RAIDA operations have a 10-second timeout - expect 1-3 second response times normally