/import

POST ASYNC

Imports CloudCoins into a wallet from one or more sources and verifies their authenticity.

POST /api/v1/import
Alias: /import-and-verify-coins

Description

The `/import` endpoint is used to add new coins to a wallet. It can accept coins from local files (e.g., `.stack`, `.chest`) or from base64-encoded `inline` data. During the import, each coin is unpacked and checked against the RAIDA network (POWN'd) to determine its authenticity. A transaction receipt is generated for each successful import.

💡 Receiving Coins

This is the primary endpoint for receiving coins. Whether you get a `.stack` file from a friend or purchase coins, this is the command you use to add them to your wallet.

Asynchronous Workflow

Understanding Asynchronous API Calls

This is an asynchronous operation. The server will start the import and verification process in the background and immediately return a task ID.

  1. You send a `POST` request with the import details.
  2. The server responds with a task ID.
  3. You poll the /api/v1/tasks/{id} endpoint to check the progress.
  4. Once the `status` is "completed", the `data` field will contain a detailed report of the import.

Request Body

The request must include a JSON body specifying the destination wallet and the items to import.

ParameterTypeRequiredDescription
name string Yes The name of the wallet where coins will be imported.
items array of objects Yes An array of `ImportItem` objects, each specifying a source of coins. See table below.
tag string No An optional text tag to associate with the import transaction.

ImportItem Object

ParameterTypeRequiredDescription
type string Yes The method of import. Supported values: `file`, `inline`, `suspect`.
data string Conditional Required for `type: "file"` (as a file path) and `type: "inline"` (as base64 data). Must be empty for `type: "suspect"`.

Example Request (Import from File)

{
  "name": "Default",
  "tag": "Import from hardware wallet",
  "items": [
    {
      "type": "file",
      "data": "/Users/user/Documents/coins/1.CloudCoin.stack"
    }
  ]
}

Response

After the task completes, its `data` field of the task status response will contain an object with the import results and a receipt ID.

Response Properties

pown_resultsobject
An object with a detailed breakdown of the coin verification process.
receipt_idstring
A unique receipt ID for this import transaction.

`pown_results` Object Properties

totalnumber
Total value of coins submitted for import.
authenticnumber
Total value of coins confirmed as authentic.
counterfeitnumber
Total value of coins confirmed as counterfeit.
frackednumber
Total value of coins that are now fracked.
limbonumber
Total value of coins that are now in limbo.
already_existsnumber
Total value of coins that were skipped because they already exist in the wallet.
coinsarray
An array providing a detailed status for each individual coin.

Example Response (from task endpoint after completion)

{
  "status": "success",
  "payload": {
    "id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
    "status": "completed",
    "progress": 100,
    "message": "Command Completed",
    "data": {
      "pown_results": {
        "total": 100,
        "authentic": 95,
        "fracked": 5,
        "limbo": 0,
        "counterfeit": 0,
        "already_exists": 0,
        "coins": [
          {
            "sn": 12345,
            "pownstring": "ppppppppppppppppppppppppp",
            "result": "Authentic"
          },
          {
            "sn": 12346,
            "pownstring": "ppppppppppppppppppfpppppp",
            "result": "Fracked"
          }
        ]
      },
      "receipt_id": "f3e1d60e2461e8c5832ca9f0a617a988"
    }
  }
}

Examples

JavaScript (async/await)

const API_HOST = 'http://localhost:8006';
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

async function importCoins() {
    try {
        const payload = {
            name: "Default",
            tag: "Received from Bob",
            items: [{ type: "file", data: "/path/to/coins_from_bob.stack" }]
        };

        const initialResponse = await fetch(`${API_HOST}/api/v1/import`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(payload)
        });
        const task = await initialResponse.json();
        console.log(`Import task created with ID: ${task.id}`);

        while (true) {
            const statusResponse = await fetch(`${API_HOST}/api/v1/tasks/${task.id}`);
            const taskStatus = await statusResponse.json();
            console.log(`Task progress: ${taskStatus.progress}%`);

            if (taskStatus.status === 'completed') {
                console.log('Import Complete:', taskStatus.data);
                break;
            } else if (taskStatus.status === 'error') {
                 console.error('Task failed:', taskStatus.message);
                 break;
            }
            await sleep(1000);
        }
    } catch (error) {
        console.error('An error occurred:', error);
    }
}
importCoins();

cURL

# Step 1: Initiate the import task
TASK_ID=$(curl -s -X POST "http://localhost:8006/api/v1/import" \
-H "Content-Type: application/json" \
-d '{"name":"Default","items":[{"type":"file","data":"/path/to/coins.stack"}]}' | jq -r .id)
echo "Import 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 .status)
  echo "Polling task... Status: $STATUS"
  if [[ "$STATUS" == "completed" || "$STATUS" == "error" ]]; then
    echo "Final Response:"
    echo $RESPONSE | jq
    break
  fi
  sleep 2
done

Go

package main

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

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

type ImportItem struct {
    Type string `json:"type"`
    Data string `json:"data"`
}
type ImportRequest struct {
    Name  string       `json:"name"`
    Tag   string       `json:"tag"`
    Items []ImportItem `json:"items"`
}

func main() {
    importPayload := ImportRequest{
        Name: "Default",
        Tag:   "From Go",
        Items: []ImportItem{{Type: "file", Data: "/path/to/your/coins.stack"}},
    }
    payloadBytes, _ := json.Marshal(importPayload)
    
    req, _ := http.NewRequest("POST", fmt.Sprintf("%s/api/v1/import", ApiHost), bytes.NewBuffer(payloadBytes))
    req.Header.Set("Content-Type", "application/json")
    
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil { panic(err) }
    defer resp.Body.Close()

    // The initial response just gives us the task ID to monitor
    // ... polling logic would be the same as other examples
    fmt.Println("Import task submitted. Status Code:", resp.StatusCode)
}

Related Endpoints

/detect

Before importing, you can use `/detect` to check the authenticity of coins in a file without adding them to a wallet.

/export

To create a file from your wallet's coins that can be sent to someone else for them to import.