/unpack

POST SYNC

Extracts individual coin data from a base64-encoded file.

POST /api/v1/unpack
Alias: /preview-coins-in-file

Description

This utility endpoint takes a base64-encoded string representing a CloudCoin container file (e.g., a `.stack`, `.bin`, or `.png` file) and returns the raw data for each individual coin found within it. This allows a client to inspect the contents of a file before committing to a full import, which would involve network-intensive authenticity checks.

Synchronous Operation

This is a synchronous API call that returns data immediately. It only extracts data and does not perform any RAIDA authenticity checks.

Request Body

The request body should be a JSON object containing the base64-encoded file data.

Request Body Parameters

Parameter Type Required Description
data string Yes A base64-encoded string of the CloudCoin file to be unpacked.

Example Request

{
    "data": "Q2xvdWRDb2lu...{very long base64 string}...CiAgICAgICAg"
}

Response

On success, returns a `200 OK` response with a JSON array where each object represents a single unpacked coin.

Response Properties (for each coin object in the array)

sninteger
The serial number of the unpacked coin.
denominationnumber
The denomination value of the coin.

Example Response

[
    {
        "sn": 8433406,
        "denomination": 1
    },
    {
        "sn": 8433407,
        "denomination": 1
    },
    {
        "sn": 2984511,
        "denomination": 5
    }
]

Examples

JavaScript Example

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

async function unpackFile(base64Data) {
    try {
        const response = await fetch(`${apiHost}/api/v1/unpack`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ data: base64Data })
        });

        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }

        const unpackedCoins = await response.json();
        console.log(`Successfully unpacked ${unpackedCoins.length} coins.`);
        unpackedCoins.forEach(coin => {
            console.log(`- Coin SN: ${coin.sn}, Denomination: ${coin.denomination}`);
        });
    } catch (error) {
        console.error('Error unpacking file:', error);
    }
}

// This would typically be read from a file and encoded
const base64Data = "Q2xvdWRDb2lu...{very long base64 string}...CiAgICAgICAg";
unpackFile(base64Data);

cURL Example

# The base64 data should be on a single line in the JSON.
# You can get base64 data from a file using a command like:
# B64_DATA=$(base64 -w 0 your_coin_file.stack)
# curl -X POST "http://localhost:8006/api/v1/unpack" -H "Content-Type: application/json" -d "{\"data\":\"$B64_DATA\"}"

curl -X POST "http://localhost:8006/api/v1/unpack" \
 -H "Content-Type: application/json" \
 -d '{"data":"Q2xvdWRDb2lu...CiAgICAgICAg"}'

# Example Success Response:
# [{"sn":8433406,"denomination":1},{"sn":8433407,"denomination":1}]

Go Example

package main

import (
    "bytes"
    "encoding/base64"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
)

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

type UnpackedCoin struct {
    SN           int     `json:"sn"`
    Denomination float64 `json:"denomination"`
}

func unpackFile(filePath string) {
    // Read the file and base64 encode it
    fileBytes, err := ioutil.ReadFile(filePath)
    if err != nil {
        log.Fatalf("Failed to read file: %v", err)
    }
    encodedString := base64.StdEncoding.EncodeToString(fileBytes)

    // Prepare the request
    requestBody, _ := json.Marshal(map[string]string{"data": encodedString})
    resp, err := http.Post(fmt.Sprintf("%s/unpack", apiHost), "application/json", bytes.NewBuffer(requestBody))
    if err != nil {
        log.Fatalf("Request failed: %v", err)
    }
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK {
        log.Fatalf("Unpack failed with status: %s", resp.Status)
    }

    var unpackedCoins []UnpackedCoin
    if err := json.NewDecoder(resp.Body).Decode(&unpackedCoins); err != nil {
        log.Fatalf("Failed to decode response: %v", err)
    }

    fmt.Printf("Successfully unpacked %d coins:\n", len(unpackedCoins))
    for _, coin := range unpackedCoins {
        fmt.Printf("- SN: %d, Denomination: %.0f\n", coin.SN, coin.Denomination)
    }
}

func main() {
    // Create a dummy file for the example
    // In a real scenario, this file would already exist.
    dummyData := []byte("CloudCoin-Stack-File-Content")
    dummyFilePath := "my_coins.stack"
    ioutil.WriteFile(dummyFilePath, dummyData, 0644)

    unpackFile(dummyFilePath)
}