/api/tools/serial-numbers

GET

Returns a complete inventory of all coin serial numbers in a specified folder with their denominations and filenames.

Description

The /api/tools/serial-numbers endpoint provides a comprehensive inventory of all CloudCoin serial numbers stored in a specified folder. Each coin entry includes its serial number, denomination value, and filename.

This endpoint is particularly useful for tracking coins, detecting duplicates, performing audits, and maintaining accurate records. You can scan any folder containing .bin coin files.

šŸ’” Use Cases

This endpoint is perfect for:

  • Wallet Inventory: Get a complete list of all coins in a specific folder (Bank, Fracked, etc.)
  • Duplicate Detection: Identify coins with the same serial number across multiple folders
  • Coin Tracking: Monitor specific serial numbers through transactions
  • Audit Trails: Maintain records for compliance and accounting
  • Reporting: Generate detailed coin holdings reports for any folder
  • Troubleshooting: Verify coin presence and location during debugging

Parameters

Parameter Type Required Description
folder_path string Yes Absolute path to the folder containing .bin coin files. Examples: C:/CloudCoin/Wallets/Default/Bank, /home/user/CloudCoin/Wallets/Default/Fracked
šŸ–„ļø Cross-Platform Paths

Windows: C:/CloudCoin/Wallets/Default/Bank or C:\CloudCoin\Wallets\Default\Bank
Linux/macOS: /home/user/CloudCoin/Wallets/Default/Bank

The folder must exist and be accessible. Only .bin files in the specified folder are scanned (subdirectories are not included).

Response

Returns a JSON object with a complete list of coins and a summary count.

Response Properties

status string
Always "success" for successful requests.
operation string
Always "list-serial-numbers".
folder_path string
Absolute path to the folder that was scanned.
coins array
Array of coin objects. Each object contains:
serial_number integer
Unique serial number of the coin (0 to 16,777,216).
denomination integer
Denomination code (-8 to +11). See denomination table below.
filename string
Name of the .bin file containing this coin.
total_coins integer
Total number of coins found in the specified folder.
šŸ“Š Denomination Codes

CloudCoin uses binary encoding for denominations:

Code Value Code Value
-80.000000013100
-70.00000014250
-10.151,000
0165,000
15725,000
225101,000,000

Note: Code 11 is reserved for special purposes (Keys/NFTs).

Example Response

{
  "status": "success",
  "operation": "list-serial-numbers",
  "folder_path": "C:/CloudCoin/Wallets/Default/Bank",
  "coins": [
    {
      "serial_number": 1234567,
      "denomination": 4,
      "filename": "250.CloudCoin.1234567.bin"
    },
    {
      "serial_number": 7654321,
      "denomination": 3,
      "filename": "100.CloudCoin.7654321.bin"
    },
    {
      "serial_number": 9876543,
      "denomination": 2,
      "filename": "25.CloudCoin.9876543.bin"
    },
    {
      "serial_number": 5555555,
      "denomination": 5,
      "filename": "1000.CloudCoin.5555555.bin"
    }
  ],
  "total_coins": 4
}

In this example:

  • Scanned folder: C:/CloudCoin/Wallets/Default/Bank
  • Coin #1234567 (denomination 4 = 250cc) - file: 250.CloudCoin.1234567.bin
  • Coin #7654321 (denomination 3 = 100cc) - file: 100.CloudCoin.7654321.bin
  • Coin #9876543 (denomination 2 = 25cc) - file: 25.CloudCoin.9876543.bin
  • Coin #5555555 (denomination 5 = 1,000cc) - file: 1000.CloudCoin.5555555.bin
  • Total: 4 coins worth 1,375cc

Error Responses

The endpoint may return the following error conditions:

Missing folder_path Parameter

Returns when the required folder_path parameter is not provided.

{
  "status": "error",
  "message": "Missing required parameter: folder_path",
  "error_code": 400
}

Invalid or Inaccessible Folder

Returns when the specified folder does not exist or cannot be accessed.

{
  "status": "error",
  "message": "Folder does not exist or is not accessible: C:/Invalid/Path",
  "error_code": 400
}

Examples

JavaScript (fetch)

const API_HOST = 'http://localhost:8080';

// Denomination code to value mapping
const DENOMINATION_MAP = {
    '-8': 0.00000001, '-7': 0.0000001, '-1': 0.1,
    '0': 1, '1': 5, '2': 25, '3': 100, '4': 250, '5': 1000,
    '6': 5000, '7': 25000, '8': 100000, '9': 250000, '10': 1000000,
    '11': 'Special'
};

async function listSerialNumbers(folderPath) {
    try {
        const url = `${API_HOST}/api/tools/serial-numbers?folder_path=${encodeURIComponent(folderPath)}`;
        const response = await fetch(url);
        const result = await response.json();

        if (result.status === 'error') {
            console.error('Error:', result.message);
            return;
        }

        console.log(`Folder: ${result.folder_path}`);
        console.log(`Total Coins: ${result.total_coins}\n`);

        // Display all coins
        result.coins.forEach(coin => {
            const value = DENOMINATION_MAP[coin.denomination];
            console.log(`SN ${coin.serial_number} - ${value}cc - ${coin.filename}`);
        });

        // Calculate total value
        const totalValue = result.coins.reduce((sum, coin) => {
            const value = DENOMINATION_MAP[coin.denomination];
            return sum + (typeof value === 'number' ? value : 0);
        }, 0);
        console.log(`\nTotal Value: ${totalValue}cc`);

    } catch (error) {
        console.error('Error fetching serial numbers:', error);
    }
}

// Example: List coins from Bank folder
listSerialNumbers('C:/CloudCoin/Wallets/Default/Bank');

// Example: List coins from Fracked folder
// listSerialNumbers('C:/CloudCoin/Wallets/Default/Fracked');

cURL

# Get list of serial numbers from Bank folder (Windows path)
curl -X GET "http://localhost:8080/api/tools/serial-numbers?folder_path=C:/CloudCoin/Wallets/Default/Bank"

# Get list from Fracked folder (Linux path)
curl -X GET "http://localhost:8080/api/tools/serial-numbers?folder_path=/home/user/CloudCoin/Wallets/Default/Fracked"

# Pretty print with jq
curl -X GET "http://localhost:8080/api/tools/serial-numbers?folder_path=C:/CloudCoin/Wallets/Default/Bank" | jq '.'

# Get only serial numbers (extract just the serial_number field)
curl -X GET "http://localhost:8080/api/tools/serial-numbers?folder_path=C:/CloudCoin/Wallets/Default/Bank" \
  | jq '.coins[].serial_number'

# Find specific serial number
curl -X GET "http://localhost:8080/api/tools/serial-numbers?folder_path=C:/CloudCoin/Wallets/Default/Bank" \
  | jq '.coins[] | select(.serial_number == 1234567)'

# Count total coins
curl -X GET "http://localhost:8080/api/tools/serial-numbers?folder_path=C:/CloudCoin/Wallets/Default/Bank" \
  | jq '.total_coins'

Go

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
)

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

type Coin struct {
    SerialNumber int    `json:"serial_number"`
    Denomination int    `json:"denomination"`
    Filename     string `json:"filename"`
}

type ListResponse struct {
    Status     string `json:"status"`
    Operation  string `json:"operation"`
    FolderPath string `json:"folder_path"`
    Coins      []Coin `json:"coins"`
    TotalCoins int    `json:"total_coins"`
}

// Denomination code to value mapping
var denominationValues = map[int]float64{
    -8: 0.00000001, -7: 0.0000001, -1: 0.1,
    0: 1, 1: 5, 2: 25, 3: 100, 4: 250, 5: 1000,
    6: 5000, 7: 25000, 8: 100000, 9: 250000, 10: 1000000,
}

func main() {
    // Specify folder path
    folderPath := "C:/CloudCoin/Wallets/Default/Bank"

    // Build URL with query parameter
    apiUrl := fmt.Sprintf("%s/api/tools/serial-numbers?folder_path=%s",
        ApiHost, url.QueryEscape(folderPath))

    resp, err := http.Get(apiUrl)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, _ := ioutil.ReadAll(resp.Body)

    var result ListResponse
    if err := json.Unmarshal(body, &result); err != nil {
        panic(err)
    }

    if result.Status == "error" {
        fmt.Println("Error:", result.Operation)
        return
    }

    fmt.Printf("Folder: %s\n", result.FolderPath)
    fmt.Printf("Total Coins: %d\n\n", result.TotalCoins)

    // Display all coins
    for _, coin := range result.Coins {
        value := denominationValues[coin.Denomination]
        fmt.Printf("SN %d - %.2fcc - %s\n", coin.SerialNumber, value, coin.Filename)
    }

    // Calculate total value
    var totalValue float64
    for _, coin := range result.Coins {
        if val, ok := denominationValues[coin.Denomination]; ok {
            totalValue += val
        }
    }
    fmt.Printf("\nTotal Value: %.2fcc\n", totalValue)
}

Python

import requests
from collections import defaultdict
from urllib.parse import urlencode

API_HOST = "http://localhost:8080"

# Denomination code to value mapping
DENOMINATION_MAP = {
    -8: 0.00000001, -7: 0.0000001, -1: 0.1,
    0: 1, 1: 5, 2: 25, 3: 100, 4: 250, 5: 1000,
    6: 5000, 7: 25000, 8: 100000, 9: 250000, 10: 1000000,
    11: 'Special'
}

def list_serial_numbers(folder_path):
    try:
        # Build URL with query parameter
        params = {'folder_path': folder_path}
        url = f"{API_HOST}/api/tools/serial-numbers?{urlencode(params)}"

        response = requests.get(url)
        result = response.json()

        if result['status'] == 'error':
            print(f"Error: {result['message']}")
            return

        print(f"Folder: {result['folder_path']}")
        print(f"Total Coins: {result['total_coins']}\n")

        # Display all coins
        for coin in result['coins']:
            value = DENOMINATION_MAP[coin['denomination']]
            print(f"SN {coin['serial_number']} - {value}cc - {coin['filename']}")

        # Calculate total value
        total_value = sum(
            DENOMINATION_MAP[coin['denomination']]
            for coin in result['coins']
            if isinstance(DENOMINATION_MAP[coin['denomination']], (int, float))
        )
        print(f"\nTotal Value: {total_value}cc")

        # Find duplicates (serial numbers appearing multiple times)
        serial_counts = defaultdict(int)
        for coin in result['coins']:
            serial_counts[coin['serial_number']] += 1

        duplicates = {sn: count for sn, count in serial_counts.items() if count > 1}
        if duplicates:
            print("\nāš ļø  Duplicate Serial Numbers:")
            for sn, count in duplicates.items():
                print(f"  SN {sn} appears {count} times")

    except requests.RequestException as e:
        print(f"Error fetching serial numbers: {e}")

if __name__ == "__main__":
    # Example: List coins from Bank folder
    list_serial_numbers('C:/CloudCoin/Wallets/Default/Bank')

    # Example: List coins from Fracked folder
    # list_serial_numbers('C:/CloudCoin/Wallets/Default/Fracked')

Use Case Examples

šŸ“ Example 1: Duplicate Detection Across Folders

Detect if the same coin serial number exists in different folders within a wallet (which would indicate duplicates that need resolution).

async function detectDuplicatesAcrossFolders() {
    const basePath = 'C:/CloudCoin/Wallets/Default';
    const folders = ['Bank', 'Fracked', 'Import', 'Export'];
    const allSerials = new Map(); // serial_number -> [folder_names]

    for (const folder of folders) {
        const folderPath = `${basePath}/${folder}`;
        const url = `${API_HOST}/api/tools/serial-numbers?folder_path=${encodeURIComponent(folderPath)}`;

        try {
            const response = await fetch(url);
            const result = await response.json();

            if (result.status === 'success') {
                result.coins.forEach(coin => {
                    if (!allSerials.has(coin.serial_number)) {
                        allSerials.set(coin.serial_number, []);
                    }
                    allSerials.get(coin.serial_number).push(folder);
                });
            }
        } catch (error) {
            console.log(`Skipping ${folder} (not accessible)`);
        }
    }

    // Find duplicates
    const duplicates = [];
    allSerials.forEach((folders, serial) => {
        if (folders.length > 1) {
            duplicates.push({ serial, folders });
        }
    });

    if (duplicates.length > 0) {
        console.log('āš ļø  DUPLICATES FOUND:');
        duplicates.forEach(dup => {
            console.log(`  SN ${dup.serial} in: ${dup.folders.join(', ')}`);
        });
    } else {
        console.log('āœ… No duplicates found');
    }
}
šŸ“ Example 2: Multi-Folder Dashboard

Create a dashboard showing coin distribution across multiple folders with denomination breakdown.

async function generateMultiFolderDashboard() {
    const basePath = 'C:/CloudCoin/Wallets/Default';
    const folders = ['Bank', 'Fracked', 'Import'];
    const folderStats = {};
    const denomStats = {};
    let totalCoins = 0;
    let totalValue = 0;

    // Scan each folder
    for (const folder of folders) {
        const folderPath = `${basePath}/${folder}`;
        const url = `${API_HOST}/api/tools/serial-numbers?folder_path=${encodeURIComponent(folderPath)}`;

        try {
            const response = await fetch(url);
            const result = await response.json();

            if (result.status === 'success') {
                // Folder statistics
                const folderValue = result.coins.reduce((sum, coin) => {
                    const value = DENOMINATION_MAP[coin.denomination];
                    return sum + (typeof value === 'number' ? value : 0);
                }, 0);

                folderStats[folder] = {
                    count: result.total_coins,
                    value: folderValue
                };

                // Denomination statistics
                result.coins.forEach(coin => {
                    const value = DENOMINATION_MAP[coin.denomination];
                    if (!denomStats[value]) denomStats[value] = 0;
                    denomStats[value]++;
                });

                totalCoins += result.total_coins;
                totalValue += folderValue;
            }
        } catch (error) {
            console.log(`Skipping ${folder} (not accessible)`);
        }
    }

    // Display dashboard
    console.log('=== MULTI-FOLDER DASHBOARD ===');
    console.log(`Total Coins: ${totalCoins} (${totalValue}cc)\n`);

    console.log('Distribution by Folder:');
    Object.entries(folderStats).forEach(([folder, stats]) => {
        console.log(`  ${folder}: ${stats.count} coins (${stats.value}cc)`);
    });

    console.log('\nDistribution by Denomination:');
    Object.entries(denomStats)
        .sort((a, b) => b[0] - a[0])
        .forEach(([value, count]) => {
            console.log(`  ${value}cc: ${count} coins`);
        });
}

Related Endpoints

/api/wallet/balance

Get the total balance of the active wallet without detailed coin information.

/api/wallet/show-coins

Display complete coin information including ANs, PANs, and POWN strings.

/api/program/status

Check which wallet is currently active before listing serial numbers.