/convert

POST ASYNC

Imports CloudCoins from files on the server's local filesystem into a wallet.

POST /api/v1/convert
Alias: /import-coins-from-file

Description

This endpoint processes one or more CloudCoin files (e.g., .stack or .jpeg files) and imports the valid coins into a specified wallet. The key functionality is that it reads files directly from paths on the server where the API is running, not from a client upload.

Asynchronous Operation

This is an asynchronous operation. It returns a task ID immediately. You must poll the /tasks/{id} endpoint to get the final import summary.


Request Body

ParameterTypeRequiredDescription
namestringYesThe name of the destination wallet.
itemsarrayYesAn array of objects, where each object points to a file on the server.
fixbooleanNoOptional. If true, the system will attempt to fix any fracked coins it finds.

Item Object Properties

ParameterTypeRequiredDescription
datastringYesThe absolute path to the CloudCoin file on the server's local filesystem.

Response (in completed task `data`)

A successfully completed conversion task will contain the following summary object in its `data` field.

resultobject
An object containing the results of the conversion.

Result Object Properties

total_ininteger
The total value of all coins found in the source files.
total_outinteger
The total value of coins successfully imported into the wallet.
total_failedinteger
The total value of coins that failed to be imported.
receipt_idstring
A unique identifier for this conversion transaction.

Examples

JavaScript: Convert Files

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

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;
    } else if (task.status === 'error') {
        console.error(`Task failed:`, task.message);
        return true;
    }
    return false;
}

async function convertFiles(walletName, filePaths) {
    try {
        const payload = {
            name: walletName,
            items: filePaths.map(path => ({ data: path }))
        };

        const response = await fetch(`${apiHost}/api/v1/convert`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(payload)
        });

        const taskInfo = await response.json();
        const taskId = taskInfo.payload.id;
        console.log(`Convert task created with ID: ${taskId}`);

        const pollInterval = setInterval(async () => {
            const isDone = await pollTask(taskId);
            if (isDone) clearInterval(pollInterval);
        }, 2000);
    } catch (error) {
        console.error('Failed to start convert task:', error);
    }
}

// Example: Import two coin files from the server's filesystem
const paths = [
    "/home/user/coins/1.CloudCoin.stack",
    "/home/user/coins/5.CloudCoin.stack"
];
convertFiles("Default", paths);

cURL: Convert Files

# Step 1: Initiate the convert task
JSON_PAYLOAD='{"name":"Default", "items":[{"data":"/path/on/server/coins.stack"}]}'

TASK_ID=$(curl -s -X POST "http://localhost:8006/api/v1/convert" \
-H "Content-Type: application/json" \
-d "$JSON_PAYLOAD" | jq -r '.payload.id')
echo "Convert task started with ID: $TASK_ID"

# Step 2: Poll the task endpoint
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: Convert Files

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

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

type ConvertItem struct {
	Data string `json:"data"`
}
type ConvertRequest struct {
	Name  string        `json:"name"`
	Items []ConvertItem `json:"items"`
	Fix   bool          `json:"fix,omitempty"`
}

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
		}
		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. 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)
	}
}

func convertFiles(payload ConvertRequest) {
	requestBody, _ := json.Marshal(payload)
	resp, err := http.Post(fmt.Sprintf("%s/convert", apiHost), "application/json", bytes.NewBuffer(requestBody))
    if err != nil {
		log.Fatalf("Failed to start convert task: %v", err)
	}
	defer resp.Body.Close()

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

	fmt.Printf("Convert task created with ID: %s\n", taskResp.Payload.ID)
	pollTask(taskResp.Payload.ID)
}

func main() {
    payload := ConvertRequest{
        Name: "Default",
        Items: []ConvertItem{
            {Data: "/path/on/server/my_coins.stack"},
        },
    }
    convertFiles(payload)
}