/crossover/withdraw
POST ASYNCWithdraws CloudCoins from a locker, converting them to a cryptocurrency (e.g., BTC).
POST /api/v1/crossover/withdraw
Alias: /withdraw-to-crypto
Description
This endpoint initiates a "crossover" transaction, where CloudCoins stored in a RAIDA locker are converted and sent to an external cryptocurrency address. The operation requires specifying the locker, the target currency, the destination address, and other transaction details.
Asynchronous Operation
This operation is asynchronous. It returns a task ID immediately, and the final result must be retrieved by polling the /tasks/{id}
endpoint.
Request Body
Parameter | Type | Required | Description |
---|---|---|---|
locker_code | string | Yes | The transmit code of the locker containing the CloudCoins. |
ticker | string | Yes | The ticker of the target cryptocurrency. Currently, only "BTC" is supported. |
address | string | Yes | The destination cryptocurrency address where funds will be sent. |
conversion_cost | number | Yes | The agreed-upon cost for the conversion service. |
receipt_id | string | Yes | A unique hex identifier for this transaction. |
tag | string | No | An optional memo or message for the transaction. |
Response (in completed task `data`)
Once the withdrawal task is complete, its `data` field will contain a confirmation of the transaction.
statusstring
The final status of the withdrawal, e.g., "success".
messagestring
A human-readable confirmation message.
txidstring
The transaction ID on the target cryptocurrency's blockchain.
amount_sentnumber
The actual amount of cryptocurrency that was sent.
Examples
JavaScript: Crossover Withdraw
const apiHost = 'http://localhost:8006';
// Generic function to poll any task
async function pollTask(taskId) {
const taskResponse = await fetch(`${apiHost}/api/v1/tasks/${taskId}`);
const taskData = await taskResponse.json();
const task = taskData.payload;
console.log(`Task ${taskId} progress: ${task.progress}% - ${task.message}`);
if (task.status === 'completed') {
console.log(`Task finished successfully!`, task.data);
return true; // Stop polling
} else if (task.status === 'error') {
console.error(`Task failed:`, task.message);
return true; // Stop polling
}
return false; // Continue polling
}
async function crossoverWithdraw(withdrawDetails) {
try {
const response = await fetch(`${apiHost}/api/v1/crossover/withdraw`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(withdrawDetails)
});
const taskInfo = await response.json();
const taskId = taskInfo.payload.id;
console.log(`Crossover withdraw task created with ID: ${taskId}`);
const pollInterval = setInterval(async () => {
const isDone = await pollTask(taskId);
if (isDone) clearInterval(pollInterval);
}, 2000); // Check every 2 seconds
} catch (error) {
console.error('Failed to start withdraw task:', error);
}
}
// Example: Withdraw CloudCoins to a Bitcoin address
const details = {
locker_code: "AAC-WS5I",
ticker: "BTC",
address: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
conversion_cost: 0.00015,
receipt_id: "930c58c367f4b8a3201a066b69529768",
tag: "Payment for invoice #123"
};
crossoverWithdraw(details);
cURL: Crossover Withdraw
# Step 1: Initiate the crossover withdraw task
JSON_PAYLOAD='{"locker_code":"AAC-WS5I","ticker":"BTC","address":"bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh","conversion_cost":0.00015,"receipt_id":"930c58c367f4b8a3201a066b69529768","tag":"Payment for invoice #123"}'
TASK_ID=$(curl -s -X POST "http://localhost:8006/api/v1/crossover/withdraw" \
-H "Content-Type: application/json" \
-d "$JSON_PAYLOAD" | jq -r '.payload.id')
echo "Crossover withdraw 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 2
done
Go: Crossover Withdraw
package main
import (
"bytes"
"encoding/json"
"fmt"
"log"
"net/http"
"time"
)
const apiHost = "http://localhost:8006/api/v1"
// Type for the request
type CrossoverWithdrawRequest struct {
LockerCode string `json:"locker_code"`
Ticker string `json:"ticker"`
CryptoAddress string `json:"address"`
ConversionCost float64 `json:"conversion_cost"`
ReceiptID string `json:"receipt_id"`
Tag string `json:"tag"`
}
// Type for the task response
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"`
}
// pollTask polls a task until it is complete or fails.
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
}
var taskResp TaskResponse
json.NewDecoder(resp.Body).Decode(&taskResp)
resp.Body.Close()
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(2 * time.Second)
}
}
// crossoverWithdraw initiates a withdraw operation and polls for the result.
func crossoverWithdraw(details CrossoverWithdrawRequest) {
requestBody, _ := json.Marshal(details)
resp, err := http.Post(fmt.Sprintf("%s/crossover/withdraw", apiHost), "application/json", bytes.NewBuffer(requestBody))
if err != nil {
log.Fatalf("Failed to start withdraw task: %v", err)
}
defer resp.Body.Close()
var taskResp TaskResponse
json.NewDecoder(resp.Body).Decode(&taskResp)
fmt.Printf("Crossover withdraw task created with ID: %s\n", taskResp.Payload.ID)
pollTask(taskResp.Payload.ID)
}
func main() {
details := CrossoverWithdrawRequest{
LockerCode: "AAC-WS5I",
Ticker: "BTC",
CryptoAddress: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
ConversionCost: 0.00015,
ReceiptID: "930c58c367f4b8a3201a066b69529768",
Tag: "Payment for invoice #123",
}
crossoverWithdraw(details)
}