/transfer

POST ASYNC

Transfers CloudCoins between two local wallets.

POST /api/v1/transfer
Alias: /transfer-between-local-wallets

Description

This endpoint moves a specified amount of CloudCoins from a source wallet to a destination wallet. This is a local operation that moves coin files between wallet directories on the server's file system and does not involve the RAIDA network.

Asynchronous Operation

This is an asynchronous API call. It creates a background task to handle the file operations and returns a task ID immediately. You must poll the /tasks/{id} endpoint to get the final result.

Request Body

The request body should be a JSON object specifying the source, destination, and amount for the transfer.

Request Body Parameters

ParameterTypeRequiredDescription
srcnamestringYesThe name of the source wallet.
dstnamestringYesThe name of the destination wallet.
amountnumberYesThe total value of coins to transfer.
tagstringNoAn optional tag or memo for the transaction.

Example Request

{
    "srcname": "Default",
    "dstname": "Savings",
    "amount": 10050000000,
    "tag": "Monthly Savings"
}

Response

Upon successful completion of the task, the task status endpoint will return a `200 OK` response. The `data` field will contain an object summarizing the transfer.

Response Properties (within completed task `data`)

amount_transferredinteger
The total value of coins that were successfully transferred.
coins_transferredinteger
The number of individual coin files that were moved.

Example Response (from task endpoint after completion)

{
    "status": "success",
    "payload": {
        "id": "e5f6g7h8-i9j0-k1l2-m3n4-o5p6q7r8s9t0",
        "status": "completed",
        "progress": 100,
        "message": "Command Completed",
        "data": {
            "amount_transferred": 10050000000,
            "coins_transferred": 12
        }
    }
}

Examples

JavaScript Example

const apiHost = 'http://localhost:8006';

async function pollTask(taskId) {
    const response = await fetch(`${apiHost}/api/v1/tasks/${taskId}`);
    const taskData = await response.json();
    const task = taskData.payload;

    console.log(`Task ${taskId} progress: ${task.progress}% - ${task.message}`);

    if (task.status === 'completed') {
        console.log('Transfer Complete:', task.data);
        return true;
    } else if (task.status === 'error') {
        console.error('Task failed:', task.message);
        return true;
    }
    return false;
}

async function transferCoins(from, to, amount, memo) {
    try {
        const response = await fetch(`${apiHost}/api/v1/transfer`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ srcname: from, dstname: to, amount, tag: memo })
        });
        const taskInfo = await response.json();
        const taskId = taskInfo.payload.id;
        console.log(`Transfer task created with ID: ${taskId}`);

        const pollInterval = setInterval(async () => {
            const isDone = await pollTask(taskId);
            if (isDone) clearInterval(pollInterval);
        }, 1000);
    } catch (error) {
        console.error('Error initiating transfer:', error);
    }
}

transferCoins('Default', 'Savings', 10050000000, 'Monthly Savings');

cURL Example

# Step 1: Initiate the transfer task
TASK_ID=$(curl -s -X POST "http://localhost:8006/api/v1/transfer" \
 -H "Content-Type: application/json" \
 -d '{"srcname":"Default","dstname":"Savings","amount":10050000000,"tag":"Monthly Savings"}' | jq -r '.payload.id')

echo "Transfer task started with ID: $TASK_ID"

# Step 2: Poll the task endpoint until finished
while true; do
  RESPONSE=$(curl -s "http://localhost:8006/api/v1/tasks/$TASK_ID")
  STATUS=$(echo $RESPONSE | jq -r '.payload.status')
  echo "Polling task.. Status: $STATUS"
  
  if [[ "$STATUS" == "completed" ]] || [[ "$STATUS" == "error" ]]; then
    echo "Final Response:"
    echo $RESPONSE | jq
    break
  fi
  
  sleep 1
done

Go Example

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    "time"
)

const apiHost = "http://localhost:8006/api/v1"

type TaskResponse struct {
    Payload struct {
        ID       string      `json:"id"`
        Status   string      `json:"status"`
        Progress int         `json:"progress"`
        Message  string      `json:"message"`
        Data     interface{} `json:"data"`
    } `json:"payload"`
}

func pollTask(taskId string) {
    for {
        resp, err := http.Get(fmt.Sprintf("%s/tasks/%s", apiHost, taskId))
        if err != nil {
            log.Printf("Error polling task: %v\n", err)
            return
        }
        defer resp.Body.Close()

        var taskResp TaskResponse
        json.NewDecoder(resp.Body).Decode(&taskResp)

        fmt.Printf("Polling... Status: %s, Progress: %d%%\n", taskResp.Payload.Status, taskResp.Payload.Progress)

        if taskResp.Payload.Status == "completed" {
            fmt.Printf("Task completed successfully. Result: %+v\n", taskResp.Payload.Data)
            return
        } else if taskResp.Payload.Status == "error" {
            fmt.Printf("Task failed: %s\n", taskResp.Payload.Message)
            return
        }
        time.Sleep(1 * time.Second)
    }
}

func transferCoins(from, to string, amount uint64, tag string) {
    requestBody, _ := json.Marshal(map[string]interface{}{
        "srcname": from,
        "dstname": to,
        "amount":  amount,
        "tag":     tag,
    })
    resp, err := http.Post(fmt.Sprintf("%s/transfer", apiHost), "application/json", bytes.NewBuffer(requestBody))
    if err != nil {
        log.Fatalf("Failed to start transfer task: %v", err)
    }
    defer resp.Body.Close()

    var taskResp TaskResponse
    json.NewDecoder(resp.Body).Decode(&taskResp)
    
    fmt.Printf("Transfer task created with ID: %s\n", taskResp.Payload.ID)
    pollTask(taskResp.Payload.ID)
}

func main() {
    transferCoins("Default", "Savings", 10050000000, "Monthly Savings")
}