/api/coins/consolidate

POST

Reduce wallet size by automatically joining smaller denomination coins into larger ones.

Important

This endpoint modifies your wallet by joining coins via RAIDA. The operation cannot be undone. Ensure you understand the implications before running.

Description

The Consolidate endpoint automatically reduces the number of coins in your wallet by joining groups of smaller denomination coins into larger ones. This is useful when you have accumulated many small coins and want to reduce wallet clutter and improve transaction efficiency.

How It Works
  1. Scans Bank and Fracked folders for coins
  2. Counts coins by denomination (-8 to 6)
  3. For denominations with ≥ min_threshold coins (default 20):
    • Keeps 10 coins
    • Joins remaining coins in batches of 10
    • Each batch creates 1 coin of the next higher denomination
  4. Uses RAIDA Join command (0x095d) to perform actual joining
Example
  • You have 35 coins of denomination 0 (value 1)
  • Threshold is 20, so consolidation triggers
  • Keeps 10 coins (value 1 each)
  • Joins 20 coins in 2 batches of 10
  • Creates 2 coins of denomination 1 (value 5 each)
  • Result: 35 coins → 12 coins (10×1 + 2×5 = same total value of 20)

Request Body

The request body is optional. If provided, it should be a JSON object:

{
  "min_threshold": 20
}

Parameters

Parameter Type Required Default Description
min_threshold number No 20 Minimum coin count to trigger consolidation (10-100)

min_threshold Parameter

Controls when consolidation triggers for a denomination:

  • Default: 20 coins (keeps 10, joins 10)
  • Range: 10-100
  • Example: With threshold=30, a denomination with 35 coins will join 20 (2 batches)

Response

Success Response (Consolidation Performed)

{
  "status": "success",
  "operation": "consolidate",
  "consolidation_needed": true,
  "min_threshold": 20,
  "denominations_consolidated": 2,
  "summary": {
    "total_coins_before": 85,
    "total_coins_after": 47,
    "coins_reduced": 38
  },
  "denominations": [
    {
      "denomination": 0,
      "value": 1,
      "count_before": 35,
      "count_after": 15,
      "change": -20
    },
    {
      "denomination": 1,
      "value": 5,
      "count_before": 8,
      "count_after": 10,
      "change": 2
    }
  ],
  "result": "success"
}

Success Response (No Consolidation Needed)

{
  "status": "success",
  "operation": "consolidate",
  "consolidation_needed": false,
  "min_threshold": 20,
  "message": "No consolidation needed - all denominations below threshold"
}

Response Properties

Property Type Description
status string Always "success" for valid requests
operation string Always "consolidate"
consolidation_needed boolean true if consolidation was performed, false if not needed
min_threshold number The threshold value used (from request or default)
denominations_consolidated number Number of denominations that were consolidated
summary object Before/after coin count summary (only if consolidated)
denominations array Array of denomination objects showing changes (only if consolidated)
result string "success" or "partial_success" if some joins failed
message string Human-readable message (only if not consolidated or partial success)

Summary Object

Property Type Description
total_coins_before number Total number of coins before consolidation
total_coins_after number Total number of coins after consolidation
coins_reduced number Number of coins removed (before - after)

Denomination Object

Each denomination in the denominations array contains:

Property Type Description
denomination number The denomination code (-8 to 6)
value number The face value in whole units
count_before number Coin count before consolidation
count_after number Coin count after consolidation
change number Net change in coin count (negative = reduced)

Note: Only denominations that were consolidated or changed are included in the array.

Error Responses

Invalid Threshold

{
  "status": "error",
  "message": "min_threshold must be between 10 and 100",
  "code": 400
}

No Active Wallet

{
  "status": "error",
  "message": "No active wallet set",
  "code": 400
}

Consolidation Rules

Denomination Range

  • Eligible: Denominations -8 to 6
  • Not Eligible: Denominations 7-11 (cannot be joined higher)

Join Logic

For each denomination with ≥ min_threshold coins:

  1. Calculate batches: batches = (count - 10) / 10
  2. Keep: 10 coins of current denomination
  3. Join: 10 coins per batch
  4. Create: 1 coin of next denomination per batch
Example with threshold=20
  • 15 coins: No action (below threshold)
  • 20 coins: Join 10 → 1 coin (keep 10)
  • 35 coins: Join 20 → 2 coins (keep 15, but will keep only 10 after first batch)
  • 52 coins: Join 40 → 4 coins (keep 12)

Example Usage

// Consolidate wallet with default threshold (20)
async function consolidateWallet() {
  const response = await fetch('http://localhost:8080/api/coins/consolidate', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({})
  });

  const data = await response.json();

  if (data.consolidation_needed) {
    console.log('✓ Consolidation completed');
    console.log(`Coins reduced: ${data.summary.total_coins_before} → ${data.summary.total_coins_after}`);
    console.log(`Saved ${data.summary.coins_reduced} coins`);

    console.log('\nChanges by denomination:');
    data.denominations.forEach(denom => {
      console.log(`  Denom ${denom.denomination}: ${denom.count_before} → ${denom.count_after} (${denom.change})`);
    });
  } else {
    console.log('✓ No consolidation needed');
  }

  return data;
}

// Consolidate with custom threshold
async function consolidateWithThreshold(threshold) {
  const response = await fetch('http://localhost:8080/api/coins/consolidate', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      min_threshold: threshold
    })
  });

  return await response.json();
}

// Example: Consolidate only when 50+ coins
await consolidateWithThreshold(50);
# Consolidate with default threshold (20 coins)
curl -X POST http://localhost:8080/api/coins/consolidate \
  -H "Content-Type: application/json" \
  -d '{}'

# Consolidate with custom threshold (30 coins)
curl -X POST http://localhost:8080/api/coins/consolidate \
  -H "Content-Type: application/json" \
  -d '{"min_threshold": 30}'

# Consolidate aggressively (threshold=10)
curl -X POST http://localhost:8080/api/coins/consolidate \
  -H "Content-Type: application/json" \
  -d '{"min_threshold": 10}'
package main

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

type ConsolidateRequest struct {
    MinThreshold int `json:"min_threshold,omitempty"`
}

type ConsolidateResponse struct {
    Status                    string `json:"status"`
    Operation                 string `json:"operation"`
    ConsolidationNeeded       bool   `json:"consolidation_needed"`
    MinThreshold              int    `json:"min_threshold"`
    DenominationsConsolidated int    `json:"denominations_consolidated,omitempty"`
    Summary                   *struct {
        TotalCoinsBefore int `json:"total_coins_before"`
        TotalCoinsAfter  int `json:"total_coins_after"`
        CoinsReduced     int `json:"coins_reduced"`
    } `json:"summary,omitempty"`
    Denominations []struct {
        Denomination int     `json:"denomination"`
        Value        float64 `json:"value"`
        CountBefore  int     `json:"count_before"`
        CountAfter   int     `json:"count_after"`
        Change       int     `json:"change"`
    } `json:"denominations,omitempty"`
    Result  string `json:"result,omitempty"`
    Message string `json:"message,omitempty"`
}

func consolidateWallet(threshold int) (*ConsolidateResponse, error) {
    req := ConsolidateRequest{MinThreshold: threshold}
    body, err := json.Marshal(req)
    if err != nil {
        return nil, err
    }

    resp, err := http.Post(
        "http://localhost:8080/api/coins/consolidate",
        "application/json",
        bytes.NewBuffer(body),
    )
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    var result ConsolidateResponse
    if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
        return nil, err
    }

    return &result, nil
}

func main() {
    // Consolidate with default threshold
    result, err := consolidateWallet(0) // 0 uses default (20)
    if err != nil {
        panic(err)
    }

    if result.ConsolidationNeeded {
        fmt.Printf("✓ Consolidation completed\n")
        fmt.Printf("Coins reduced: %d → %d (saved %d coins)\n",
            result.Summary.TotalCoinsBefore,
            result.Summary.TotalCoinsAfter,
            result.Summary.CoinsReduced)

        fmt.Println("\nChanges by denomination:")
        for _, denom := range result.Denominations {
            fmt.Printf("  Denom %d: %d → %d (%+d)\n",
                denom.Denomination, denom.CountBefore,
                denom.CountAfter, denom.Change)
        }
    } else {
        fmt.Printf("✓ %s\n", result.Message)
    }
}

Best Practices

When to Consolidate

Good Times
  • After receiving many small denomination transactions
  • Before making large payments (reduces coins needed)
  • When wallet has 100+ coins
  • During low network activity (RAIDA join operations take time)
Avoid
  • If you need specific denominations soon
  • During active trading (coins in transit won't consolidate)
  • If network/RAIDA is experiencing issues

Threshold Selection

Threshold Use Case Result
10 Aggressive consolidation Minimal coins kept, frequent joining
20 Default - balanced Good for typical wallets
30-50 Conservative Only consolidates very cluttered denominations
100 Minimal consolidation Only for extremely large coin counts

Value Preservation

Important

Consolidation preserves total value but changes coin structure:

  • 10 coins of value 1 = 1 coin of value 10 ✓
  • Total value remains exactly the same ✓
  • Transaction fingerprint changes (different coin serial numbers)

Related Endpoints