/api/transactions/deposit

GET POST ASYNC

The deposit endpoint combines import, authentication, and automatic coin breaking into a single streamlined operation. Specify an exact amount, and the system will import coins from absolute file paths or a folder, authenticate them with RAIDA, and automatically break larger coins until the exact amount is available in your wallet. This integrated workflow ensures you always have the exact change needed for transactions.

📌 GET vs POST

GET: Use for small imports (up to ~31 files) or folder imports. Files specified as multiple file query parameters OR use source_folder to import all .bin files from a folder.
POST: Use for large imports (unlimited files). Files specified as JSON array in request body OR use source_folder to import all .bin files from a folder.

GET Request Example - Individual Files

GET Request Example - Folder Import

POST Request Example

Body (JSON) - Individual Files:

{
  "files": [
    "C:\\Users\\User\\tmp\\coin1.bin",
    "C:\\Users\\User\\tmp\\coin2.bin"
  ],
  "memo": "I love you!",
  "wallet_path": "C:/CloudCoin/Wallets/Default"
}

Body (JSON) - Folder Import:

{
  "source_folder": "C:\\Users\\User\\tmp\\import_test",
  "memo": "Imported from folder",
  "wallet_path": "C:/CloudCoin/Wallets/Default"
}
🖥️ Cross-Platform Path Format

File paths must use the appropriate format for your operating system:

  • Windows: Use backslashes or forward slashes. In JSON, backslashes must be escaped (doubled).
    • URL format: file=C:\Users\User\tmp\coin1.bin
    • JSON format: "C:\\Users\\User\\tmp\\coin1.bin" (backslashes escaped)
    • Alternative: "C:/Users/User/tmp/coin1.bin" (forward slashes work on Windows)
  • Linux/macOS: Use forward slashes (no escaping needed).
    • URL format: file=/home/user/tmp/coin1.bin
    • JSON format: "/home/user/tmp/coin1.bin"

Important: All paths must be absolute paths (starting from the root directory or drive letter). Relative paths are not supported.

Description

The `/api/transactions/deposit` endpoint provides a way to import CloudCoin files from specific absolute file paths anywhere on the filesystem. This endpoint allows you to:

  • Specify exact files: Import from any absolute path on the filesystem
  • Add transaction memo: Include a memo for record-keeping and audit trails
  • Target specific wallet: Specify which wallet to import into using the wallet_path parameter
  • Track progress: Use the task ID to monitor the asynchronous import operation
  • Create receipts: Automatic transaction receipt generation in the Receipts folder
💡 Asynchronous Processing

This endpoint returns immediately with a task ID. The import operation runs in a background thread, authenticating coins with all 25 RAIDA servers in parallel. Use /api/transactions/task?id=[task_id] to check progress and results.

🔄 Complete Import Workflow

Step 1: Files are moved (not copied) from absolute paths to [wallet]/Import/
Step 2: Background thread authenticates coins with RAIDA (Detect command 0x010A)
Step 3: POWN strings updated based on RAIDA responses (13+ passes = authentic)
Step 4: Authenticated coins → [wallet]/Bank/
Step 5: Fracked coins (partial passes) → [wallet]/Fracked/
Step 6: Counterfeit coins → [wallet]/Counterfeit/
Step 7: Transaction receipt saved to [wallet]/Receipts/[task_id].import.txt

⚠️ Important: Atomic Move Operation

Files are moved (not copied) using atomic rename operations. The original files will no longer exist at their source paths after the import request is accepted. Ensure:

  • Files are not in use by other applications
  • You have write permissions for both source and destination paths
  • Source and destination are on the same filesystem (for atomic rename)

Request Parameters

GET Request - Query Parameters

Pass parameters in the URL query string (recommended for small imports with up to ~31 files):

Parameter Type Required Description
file string (multiple) Optional* Absolute file path to a CloudCoin file (.bin, .stack, .jpeg, .jpg, .png). Specify this parameter multiple times for multiple files. Each path must be absolute and accessible from the server. Maximum ~31 files (due to HTTP query string limits). Example: file=C:\path1.bin&file=C:\path2.bin. *Either file or source_folder must be specified.
source_folder string Optional* Absolute path to a folder containing .bin files to import. All .bin files in the folder will be imported. Maximum 100 files per folder. Example: source_folder=C:\Users\User\tmp\import_test or source_folder=/home/user/import_test. *Either file or source_folder must be specified.
memo string Optional Transaction memo for record-keeping. Will be included in the receipt file in [wallet]/Receipts/. Maximum 100 characters. URL encode spaces and special characters (e.g., space becomes %20).
wallet_path string Required File system path to the wallet directory to import coins into. Example: wallet_path=C:/CloudCoin/Wallets/Default or wallet_path=/home/user/CloudCoin/Wallets/Archive
📝 Example GET URL
GET http://localhost:8080/api/transactions/deposit?file=C:\Users\User\tmp\coin1.bin&file=C:\Users\User\tmp\coin2.bin&memo=I%20love%20you!&wallet_path=C:/CloudCoin/Wallets/Default

POST Request - JSON Body

Send parameters in JSON request body (recommended for large imports with unlimited files):

Property Type Required Description
files array of strings Optional* Array of absolute file paths to CloudCoin files. No practical limit on number of files. Each path must be absolute and accessible from the server. Example: ["C:\\path1.bin", "C:\\path2.bin"]. *Either files or source_folder must be specified.
source_folder string Optional* Absolute path to a folder containing .bin files to import. All .bin files in the folder will be imported. Maximum 100 files per folder. Example: "C:\\Users\\User\\tmp\\import_test" or "/home/user/import_test". *Either files or source_folder must be specified.
memo string Optional Transaction memo for record-keeping. Will be included in the receipt file. Maximum 100 characters.
wallet_path string Required File system path to the wallet directory to import coins into. Example: "C:\\CloudCoin\\Wallets\\Default" or "/home/user/CloudCoin/Wallets/Archive"
📝 Example POST Body
{
  "files": [
    "C:\\Users\\User\\tmp\\coin1.bin",
    "C:\\Users\\User\\tmp\\coin2.bin",
    "C:\\Users\\User\\tmp\\coin3.bin"
  ],
  "memo": "I love you!",
  "wallet_path": "C:\\CloudCoin\\Wallets\\Default"
}

Response

Returns a JSON object with a task ID to track the asynchronous import operation.

Response Properties

command string
Always "deposit".
success boolean
Always true if the request was accepted.
task_id string
Unique task identifier to check import progress and results. Use with /api/system/tasks endpoint.
message string
Confirmation message - "Import started in background".
imported integer
Number of files imported with original filenames.
renamed integer
Number of files renamed (timestamped) due to duplicate filenames.
skipped integer
Number of files skipped (not found or inaccessible).
total integer
Total number of files attempted.

Example Response (Success)

{
  "command": "deposit",
  "success": true,
  "task_id": "Nov-21-25_10-43-31-AM-f410",
  "message": "Import started in background",
  "imported": 20,
  "renamed": 0,
  "skipped": 0,
  "total": 20
}

Example Error Response (Missing Parameter)

{
  "error": "Missing required parameter: files (array of absolute paths)"
}

Example Error Response (File Not Found)

{
  "error": "File not found: C:\\Downloads\\coins.stack"
}

Examples

JavaScript (fetch) - GET Request (Small Imports)

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

async function importFilesGET(filePaths, memo, walletPath) {
    try {
        // Step 1: Build query string with multiple 'file' parameters
        const params = new URLSearchParams();
        filePaths.forEach(path => params.append('file', path));
        if (memo) params.append('memo', memo);
        if (walletPath) params.append('wallet_path', walletPath);

        // Step 2: Start import with GET request
        const response = await fetch(`${API_HOST}/api/transactions/deposit?${params}`);

        const result = await response.json();

        if (result.status === 'success') {
            console.log(`Import started with task ID: ${result.task_id}`);
            console.log(`Processing ${result.file_count} files`);
            console.log(`Importing to wallet: ${walletPath}`);

            // Step 3: Poll for completion
            const taskResult = await pollTaskStatus(result.task_id);

            // Step 4: Check receipt for details
            if (taskResult.status === 'completed') {
                console.log('Import complete! Check receipt at:');
                console.log(`[wallet]/Receipts/${result.task_id}.import.txt`);

                // Step 5: Check updated balance
                await checkBalance(walletPath);
            }
        } else {
            console.error('Import failed:', result.error);
        }
    } catch (error) {
        console.error('Error importing files:', error);
    }
}

async function pollTaskStatus(taskId) {
    while (true) {
        const response = await fetch(`${API_HOST}/api/transactions/task?id=${taskId}`);
        const task = await response.json();

        console.log(`Status: ${task.status}, Progress: ${task.progress || 0}%`);

        if (task.status === 'completed') {
            console.log('Import complete:', task);
            return task;
        } else if (task.status === 'error' || task.status === 'failed') {
            console.error('Import failed:', task.message);
            throw new Error(task.message);
        }

        // Poll every second
        await new Promise(resolve => setTimeout(resolve, 1000));
    }
}

async function checkBalance(walletPath) {
    const encodedPath = encodeURIComponent(walletPath);
    const response = await fetch(`${API_HOST}/api/wallets/balance?wallet_path=${encodedPath}`);
    const balance = await response.json();
    console.log('New wallet balance:', balance);
}

// Example: Deposit Coins to specified wallet
importFilesGET([
    'C:\\Users\\User\\tmp\\coin1.bin',
    'C:\\Users\\User\\tmp\\coin2.bin'
], 'I love you!', 'C:/CloudCoin/Wallets/Default');

JavaScript (fetch) - POST Request (Large Imports)

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

async function importFilesPOST(filePaths, memo, walletPath) {
    try {
        // Step 1: Build JSON request body
        const requestBody = {
            files: filePaths,
            memo: memo || ""
        };
        if (walletPath) {
            requestBody.wallet_path = walletPath;
        }

        // Step 2: Start import with POST request
        const response = await fetch(`${API_HOST}/api/transactions/deposit`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(requestBody)
        });

        const result = await response.json();

        if (result.status === 'success') {
            console.log(`Import started with task ID: ${result.task_id}`);
            console.log(`Processing ${result.file_count} files`);
            console.log(`Importing to wallet: ${walletPath}`);

            // Step 3: Poll for completion (same as GET)
            const taskResult = await pollTaskStatus(result.task_id);

            // Step 4: Check receipt for details
            if (taskResult.status === 'completed') {
                console.log('Import complete! Check receipt at:');
                console.log(`[wallet]/Receipts/${result.task_id}.import.txt`);

                // Step 5: Check updated balance
                await checkBalance(walletPath);
            }
        } else {
            console.error('Import failed:', result.error);
        }
    } catch (error) {
        console.error('Error importing files:', error);
    }
}

async function pollTaskStatus(taskId) {
    while (true) {
        const response = await fetch(`${API_HOST}/api/transactions/task?id=${taskId}`);
        const task = await response.json();

        console.log(`Status: ${task.status}, Progress: ${task.progress || 0}%`);

        if (task.status === 'completed') {
            console.log('Import complete:', task);
            return task;
        } else if (task.status === 'error' || task.status === 'failed') {
            console.error('Import failed:', task.message);
            throw new Error(task.message);
        }

        // Poll every second
        await new Promise(resolve => setTimeout(resolve, 1000));
    }
}

async function checkBalance(walletPath) {
    const encodedPath = encodeURIComponent(walletPath);
    const response = await fetch(`${API_HOST}/api/wallets/balance?wallet_path=${encodedPath}`);
    const balance = await response.json();
    console.log('New wallet balance:', balance);
}

// Example: Deposit Coins to specified wallet (unlimited files)
importFilesPOST([
    'C:\\Users\\User\\tmp\\coin1.bin',
    'C:\\Users\\User\\tmp\\coin2.bin',
    'C:\\Users\\User\\tmp\\coin3.bin',
    // ... can add hundreds more
], 'I love you!', 'C:/CloudCoin/Wallets/Default');

cURL - GET Request (Small Imports)

# Start import with GET request
curl -X GET "http://localhost:8080/api/transactions/deposit?file=C:\Users\User\tmp\coin1.bin&file=C:\Users\User\tmp\coin2.bin&memo=I%20love%20you!&wallet_path=C:/CloudCoin/Wallets/Default"

# Response:
# {
#   "status": "success",
#   "operation": "deposit",
#   "task_id": "Jan-31-25_03-45-12-PM",
#   "message": "Import task started successfully",
#   "file_count": 2
# }

# Step 2: Poll task status
curl -X GET "http://localhost:8080/api/transactions/task?id=Jan-31-25_03-45-12-PM"

# Step 3: Check receipt (after completion)
# Receipt saved to: [wallet]/Receipts/Jan-31-25_03-45-12-PM.import.txt

# Step 4: Check wallet balance
curl -X GET "http://localhost:8080/api/wallets/balance?wallet_path=C:/CloudCoin/Wallets/Default"

# Note: Remember to URL encode special characters in query parameters
# Example: Spaces become %20, backslashes might need escaping depending on shell

cURL - POST Request (Large Imports)

# Start import with POST request (JSON body)
curl -X POST "http://localhost:8080/api/transactions/deposit" \
  -H "Content-Type: application/json" \
  -d '{
    "files": [
      "C:\\Users\\User\\tmp\\coin1.bin",
      "C:\\Users\\User\\tmp\\coin2.bin",
      "C:\\Users\\User\\tmp\\coin3.bin"
    ],
    "memo": "I love you!",
    "wallet_path": "C:/CloudCoin/Wallets/Default"
  }'

# Response:
# {
#   "status": "success",
#   "operation": "deposit",
#   "task_id": "Jan-31-25_03-45-12-PM",
#   "message": "Import task started successfully",
#   "file_count": 3
# }

# Step 2: Poll task status
curl -X GET "http://localhost:8080/api/transactions/task?id=Jan-31-25_03-45-12-PM"

# Step 3: Check receipt (after completion)
# Receipt saved to: [wallet]/Receipts/Jan-31-25_03-45-12-PM.import.txt

# Step 4: Check wallet balance
curl -X GET "http://localhost:8080/api/wallets/balance?wallet_path=C:/CloudCoin/Wallets/Default"

# Note: JSON strings require double backslashes for Windows paths
# Example: "C:\\path\\file.bin" not "C:\path\file.bin"

Go - Complete Workflow

package main

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

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

type ImportResponse struct {
    Status    string `json:"status"`
    Operation string `json:"operation"`
    TaskID    string `json:"task_id"`
    Message   string `json:"message"`
    FileCount int    `json:"file_count"`
}

type TaskStatus struct {
    Status   string `json:"status"`
    Progress int    `json:"progress"`
    Message  string `json:"message"`
}

type WalletBalance struct {
    TotalValue int `json:"total_value"`
    CoinCount  int `json:"coin_count"`
}

func importFiles(filePaths []string, memo string, walletPath string) error {
    // Step 1: Build query string with files (pipe-separated), memo, and optional wallet_path
    params := url.Values{}
    params.Add("files", strings.Join(filePaths, "|"))
    params.Add("memo", memo)
    if walletPath != "" {
        params.Add("wallet_path", walletPath)
    }

    // Step 2: Make GET request with query parameters
    requestURL := fmt.Sprintf("%s/api/transactions/deposit?%s", ApiHost, params.Encode())
    resp, err := http.Get(requestURL)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

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

    var result ImportResponse
    if err := json.Unmarshal(body, &result); err != nil {
        return err
    }

    if result.Status != "success" {
        return fmt.Errorf("import failed: %s", result.Message)
    }

    fmt.Printf("Import started with task ID: %s\n", result.TaskID)
    fmt.Printf("Processing %d files\n", result.FileCount)
    fmt.Printf("Importing to wallet: %s\n", walletPath)

    // Step 3: Poll for completion
    if err := pollTaskStatus(result.TaskID); err != nil {
        return err
    }

    // Step 4: Check receipt
    fmt.Printf("Receipt saved to: [wallet]/Receipts/%s.import.txt\n", result.TaskID)

    // Step 5: Check updated balance
    return checkBalance(walletPath)
}

func pollTaskStatus(taskID string) error {
    for {
        requestURL := fmt.Sprintf("%s/api/transactions/task?id=%s", ApiHost, taskID)
        resp, err := http.Get(requestURL)
        if err != nil {
            return err
        }

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

        var task TaskStatus
        if err := json.Unmarshal(body, &task); err != nil {
            return err
        }

        fmt.Printf("Status: %s, Progress: %d%%\n", task.Status, task.Progress)

        if task.Status == "completed" {
            fmt.Println("Import complete!")
            return nil
        } else if task.Status == "error" || task.Status == "failed" {
            return fmt.Errorf("import failed: %s", task.Message)
        }

        time.Sleep(1 * time.Second)
    }
}

func checkBalance(walletPath string) error {
    requestURL := fmt.Sprintf("%s/api/wallets/balance?wallet_path=%s",
        ApiHost, url.QueryEscape(walletPath))
    resp, err := http.Get(requestURL)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

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

    var balance WalletBalance
    if err := json.Unmarshal(body, &balance); err != nil {
        return err
    }

    fmt.Printf("New wallet balance: %d CloudCoins, Total value: %d\n",
        balance.CoinCount, balance.TotalValue)
    return nil
}

func main() {
    filePaths := []string{
        "C:\\Users\\User\\tmp\\coin1.bin",
        "C:\\Users\\User\\tmp\\coin2.bin",
    }

    // Import to specified wallet
    if err := importFiles(filePaths, "I love you!", "C:/CloudCoin/Wallets/Default"); err != nil {
        fmt.Printf("Error: %v\n", err)
    }
}

Related Endpoints

/api/transactions/task

Check the status and progress of the asynchronous import operation using the task ID. Essential for monitoring long-running imports.

/api/wallet/receipt

View the detailed transaction receipt after import completes. Shows authentication results, coin counts, and POWN strings.

/api/wallets/balance

After import completes, check the wallet balance to see the newly imported coins added to the Bank folder.