/api/program/fix-encryption

GET

Recover lost encryption connections by automatically healing fracked coins using the RAIDA network.

Description

The /api/program/fix-encryption endpoint attempts to recover "lost encryption connections" - situations where some RAIDA servers don't have valid authentication numbers (ANs) for coins in your wallet. This typically happens when:

  • Encryption key mismatch: The encryption key stored on certain RAIDAs doesn't match the key in your coin files
  • Partial authentication: Coins are "fracked" (authenticated on some RAIDAs but not all 25)
  • Failed POWN operations: Previous password-own operations only partially succeeded
  • Network issues: Past authentication attempts timed out on specific RAIDAs

The recovery process works by:

  1. Detection: Scanning Bank and Fracked folders to identify which RAIDAs have no coins with 'p' (pass) status
  2. Candidate Selection: Finding the best fracked coin for each lost RAIDA (coins with the most passes on other RAIDAs)
  3. Ticket Collection: Requesting authentication tickets from passing RAIDAs using unencrypted requests
  4. Healing: Sending Fix requests to lost RAIDAs with collected tickets to re-establish the encryption connection
  5. Verification: Grading coins to confirm successful recovery
⚠️ Current Implementation Status

NOTE: As of January 2025, this endpoint performs detection and candidate selection but does NOT YET execute the actual healing workflow. The implementation requires unencrypted RAIDA communication functions that are currently under development.

The endpoint will return success but indicate that recovery is not yet fully implemented. Use /api/program/detect-lost-encryption to identify lost connections.

💡 Use Cases

This endpoint is useful for:

  • Emergency recovery: Restoring wallet access after encryption key issues
  • Wallet maintenance: Fixing fracked coins to maximize wallet balance
  • Migration workflows: Recovering coins after moving between systems
  • Troubleshooting: Diagnosing and fixing RAIDA connectivity problems

Parameters

This endpoint does not require any parameters.

Response

Returns a JSON object indicating whether the encryption recovery process completed successfully.

Response Properties

status string
Always "success" for this endpoint (even if no recovery was needed).
operation string
Always "fix-encryption".
completed boolean
True if recovery process completed without errors, false if errors occurred.
message string
Human-readable message describing the result ("Encryption recovery completed successfully" or "Encryption recovery encountered errors").
error_code integer
(Optional) Only present if completed is false. Contains the error code from the recovery operation.

Example Response (Success)

{
  "status": "success",
  "operation": "fix-encryption",
  "completed": true,
  "message": "Encryption recovery completed successfully"
}

Example Response (Error)

{
  "status": "success",
  "operation": "fix-encryption",
  "completed": false,
  "message": "Encryption recovery encountered errors",
  "error_code": 501
}

Recovery Process Details

The encryption recovery workflow consists of several phases:

Phase 1: Detection

The system scans all coins in the Bank and Fracked folders, checking the POWN string (Proof of Ownership) for each coin. A RAIDA is considered to have a "lost connection" if no coins have a 'p' (pass) status for that RAIDA.

Phase 2: Candidate Selection

For each lost RAIDA, the system searches the Fracked folder for the best candidate coin to use for recovery. The best candidate is the coin with:

  • Non-'p' status on the lost RAIDA (needs fixing)
  • Maximum number of 'p' statuses on other RAIDAs (most authentic)
  • Ideally 13+ passes (meets the authenticity threshold)

Phase 3: Ticket Collection (Planned)

The system will send unencrypted Get Ticket (0x0228) requests to all RAIDAs where the candidate coin has 'p' status. These tickets prove ownership and can be used to fix the coin on the lost RAIDA.

Phase 4: Healing (Planned)

Using collected tickets (minimum 13 required), the system will send an unencrypted Fix (0x0250) request to the lost RAIDA. If successful, the RAIDA will update its encryption key for that coin.

Phase 5: Verification

After fixing, the coin is graded to verify it now has 13+ passes and can be moved back to the Bank folder.

🔒 Why Unencrypted Requests?

The recovery process uses unencrypted RAIDA requests because the encryption key on the lost RAIDA doesn't match the client's key. Encrypted requests would fail. The tickets from passing RAIDAs prove ownership securely even without encryption.

Error Codes

Common error codes returned in the error_code field:

501
CC_ERROR_INVALID_STATE: No active wallet is set.
300-399
Network/RAIDA errors: Communication failures with RAIDA servers.
100-199
File/IO errors: Problems reading or writing coin files.
650-699
Encryption errors: Issues with encryption keys or decryption.

Examples

JavaScript (fetch)

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

async function fixEncryptionConnections() {
    try {
        console.log('Starting encryption recovery...');

        const response = await fetch(`${API_HOST}/api/program/fix-encryption`);
        const result = await response.json();

        if (result.completed) {
            console.log('✓ Recovery completed successfully');
            console.log(result.message);
        } else {
            console.error('✗ Recovery encountered errors');
            console.error(`Error code: ${result.error_code}`);
            console.error(result.message);
        }

        return result;
    } catch (error) {
        console.error('Network error during recovery:', error);
        throw error;
    }
}

// Example: Run recovery after detecting lost connections
async function recoverWallet() {
    // Step 1: Detect lost connections
    const detectResponse = await fetch(`${API_HOST}/api/program/detect-lost-encryption`);
    const detection = await detectResponse.json();

    console.log(`Found ${detection.summary.lost_raida_count} lost RAIDAs`);

    if (detection.summary.lost_raida_count > 0) {
        console.log('Lost RAIDAs:', detection.lost_raidas);

        // Step 2: Attempt recovery
        const recovery = await fixEncryptionConnections();

        // Step 3: Re-check (optional)
        const recheck = await fetch(`${API_HOST}/api/program/detect-lost-encryption`);
        const recheckResult = await recheck.json();

        console.log(`Remaining lost RAIDAs: ${recheckResult.summary.lost_raida_count}`);
    } else {
        console.log('No lost connections detected - wallet is healthy');
    }
}

recoverWallet();

cURL

# Fix encryption connections
curl -X GET "http://localhost:8080/api/program/fix-encryption"

# Example: Complete recovery workflow with jq for JSON parsing
echo "Step 1: Detect lost connections..."
LOST_COUNT=$(curl -s "http://localhost:8080/api/program/detect-lost-encryption" | jq '.summary.lost_raida_count')

echo "Found $LOST_COUNT lost RAIDAs"

if [ "$LOST_COUNT" -gt 0 ]; then
    echo "Step 2: Attempting recovery..."
    curl -s "http://localhost:8080/api/program/fix-encryption" | jq '.'

    echo "Step 3: Verifying recovery..."
    curl -s "http://localhost:8080/api/program/detect-lost-encryption" | jq '.summary'
else
    echo "No recovery needed - wallet is healthy"
fi

Go

package main

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

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

type FixEncryptionResponse struct {
    Status    string `json:"status"`
    Operation string `json:"operation"`
    Completed bool   `json:"completed"`
    Message   string `json:"message"`
    ErrorCode int    `json:"error_code,omitempty"`
}

type DetectionSummary struct {
    BankCoins      int `json:"bank_coins"`
    FrackedCoins   int `json:"fracked_coins"`
    TotalCoins     int `json:"total_coins"`
    LostRaidaCount int `json:"lost_raida_count"`
}

type DetectLostEncryptionResponse struct {
    Status      string             `json:"status"`
    Operation   string             `json:"operation"`
    Summary     DetectionSummary   `json:"summary"`
    LostRaidas  []int              `json:"lost_raidas"`
}

func fixEncryption() (*FixEncryptionResponse, error) {
    resp, err := http.Get(fmt.Sprintf("%s/api/program/fix-encryption", ApiHost))
    if err != nil {
        return nil, fmt.Errorf("request failed: %w", err)
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return nil, fmt.Errorf("read failed: %w", err)
    }

    var result FixEncryptionResponse
    if err := json.Unmarshal(body, &result); err != nil {
        return nil, fmt.Errorf("JSON parse failed: %w", err)
    }

    return &result, nil
}

func detectLostConnections() (*DetectLostEncryptionResponse, error) {
    resp, err := http.Get(fmt.Sprintf("%s/api/program/detect-lost-encryption", ApiHost))
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    body, _ := ioutil.ReadAll(resp.Body)
    var result DetectLostEncryptionResponse
    json.Unmarshal(body, &result)
    return &result, nil
}

func main() {
    // Step 1: Detect lost connections
    fmt.Println("Step 1: Detecting lost encryption connections...")
    detection, err := detectLostConnections()
    if err != nil {
        panic(err)
    }

    fmt.Printf("Found %d lost RAIDAs\n", detection.Summary.LostRaidaCount)

    if detection.Summary.LostRaidaCount > 0 {
        fmt.Printf("Lost RAIDAs: %v\n", detection.LostRaidas)

        // Step 2: Attempt recovery
        fmt.Println("\nStep 2: Attempting encryption recovery...")
        result, err := fixEncryption()
        if err != nil {
            panic(err)
        }

        if result.Completed {
            fmt.Printf("✓ %s\n", result.Message)
        } else {
            fmt.Printf("✗ %s (Error code: %d)\n", result.Message, result.ErrorCode)
        }

        // Step 3: Verify
        fmt.Println("\nStep 3: Verifying recovery...")
        recheck, _ := detectLostConnections()
        fmt.Printf("Remaining lost RAIDAs: %d\n", recheck.Summary.LostRaidaCount)
    } else {
        fmt.Println("No lost connections detected - wallet is healthy")
    }
}

Best Practices

1. Always Detect Before Fixing

Run /api/program/detect-lost-encryption first to identify which RAIDAs need recovery and assess the severity of the problem.

2. Verify Recovery Results

After running fix-encryption, run detect-lost-encryption again to confirm the number of lost RAIDAs has decreased.

3. Understand Limitations

Recovery can only succeed if you have fracked coins with sufficient passes (13+) on other RAIDAs. If all coins are counterfeit or have very few passes, recovery may not be possible.

4. Backup Before Recovery

Always backup your wallet using /api/wallet/backup before attempting encryption recovery operations.

5. Monitor Progress

For large wallets with many lost connections, the recovery process may take time. Consider implementing retry logic with exponential backoff.

⚠️ Important Considerations
  • Requires fracked coins: Recovery needs fracked coins in the Fracked folder. If you only have Bank coins, there's nothing to fix.
  • Network dependent: Recovery requires stable connections to all RAIDA servers.
  • Time intensive: For wallets with many lost connections, the process may take several minutes.
  • Not guaranteed: If coins have insufficient passes on other RAIDAs, recovery may not succeed.

Related Endpoints

/api/program/detect-lost-encryption

Detect which RAIDA servers have lost encryption connections by scanning wallet POWN strings.

/api/wallet/fix-fracked

Fix fracked coins using the RAIDA healing protocol (Get Ticket + Fix).

/api/program/login

Load encryption key into memory to enable automatic decryption of encrypted coin files.

/api/wallet/backup

Create a backup ZIP file of the active wallet before performing recovery operations.

Technical Implementation

The /api/program/fix-encryption endpoint internally calls the cmd_recover_lost_connections() function, which implements a multi-phase recovery algorithm:

// Simplified recovery algorithm
cc_result_t cmd_recover_lost_connections(void) {
    // Phase 1: Scan Bank and Fracked folders
    bool raida_has_key[25] = {false};
    for each coin in wallet {
        for each raida in 0..24 {
            if (coin.pown_string[raida] == 'p') {
                raida_has_key[raida] = true;
            }
        }
    }

    // Phase 2: For each lost RAIDA, find best candidate
    for each lost_raida where !raida_has_key[lost_raida] {
        best_coin = find_coin_with_most_passes_on_other_raidas();

        // Phase 3: Get tickets from passing RAIDAs (UNENCRYPTED)
        tickets = get_tickets_unencrypted(best_coin);

        // Phase 4: Fix on lost RAIDA (UNENCRYPTED)
        if (tickets.count >= 13) {
            fix_unencrypted(lost_raida, best_coin, tickets);
        }

        // Phase 5: Grade and verify
        grade_coin(best_coin);
    }

    return CC_SUCCESS;
}

The recovery process uses unencrypted RAIDA requests because the encryption keys on lost RAIDAs don't match the client's keys. Encrypted requests would fail with CRC errors. The authentication tickets from passing RAIDAs provide cryptographic proof of ownership even without encryption.