RIP-0305 Bridge API Documentation

June 14, 2026 · View on GitHub

Overview

The Bridge API provides REST endpoints for managing cross-chain transfers between RustChain and external chains (Solana, Ergo, Base). This implementation follows RIP-0305 Track C specifications.

Base URL

Production: https://rustchain.org
Development: http://localhost:5000

Authentication

Admin Endpoints

Most bridge management endpoints require an admin key:

X-Admin-Key: <your-admin-key>

POST /api/bridge/initiate is not a public self-service native RTC to wRTC/Solana bridge endpoint. RustChain-origin deposits lock RustChain balances and are operator-assisted/admin-authenticated: the node must have RC_ADMIN_KEY configured and the caller must provide a matching X-Admin-Key header. Public web routing may intentionally leave the bridge management API unavailable; an operator node that exposes the route returns 401 unauthorized when the admin key is missing or wrong.

API Callbacks

Bridge service callbacks use API key authentication:

X-API-Key: <bridge-api-key>

Endpoints

1. Initiate Bridge Transfer

Create a new bridge transfer (deposit or withdraw). RustChain-origin deposits are operator-assisted and require admin authentication; do not treat this as a user-callable public payout, minting, or wallet-credit endpoint.

Endpoint: POST /api/bridge/initiate

Headers (operator/admin only):

X-Admin-Key: <admin-key>
Content-Type: application/json

Request:

{
    "direction": "deposit",
    "source_chain": "rustchain",
    "dest_chain": "solana",
    "source_address": "RTC_miner123",
    "dest_address": "4TRwNqXqXqXqXqXqXqXqXqXqXqXqXqXqXqXq",
    "amount_rtc": 100.0,
    "memo": "Optional memo (max 256 chars)"
}

Fields:

FieldTypeRequiredDescription
directionstringYesdeposit (RTC→external) or withdraw (external→RTC)
source_chainstringYesSource chain: rustchain, solana, ergo, base
dest_chainstringYesDestination chain (must differ from source)
source_addressstringYesSource wallet address
dest_addressstringYesDestination wallet address
amount_rtcnumberYesAmount in RTC (minimum: 1.0)
memostringNoOptional memo (max 256 characters)

Response (200 OK):

{
    "ok": true,
    "bridge_transfer_id": 12345,
    "tx_hash": "abc123def456...",
    "status": "pending",
    "lock_epoch": 85,
    "unlock_at": 1709942400,
    "estimated_completion": "2026-03-10T12:00:00Z",
    "direction": "deposit",
    "source_chain": "rustchain",
    "dest_chain": "solana",
    "amount_rtc": 100.0
}

Error Responses:

// 401 Unauthorized - missing or invalid admin key for RustChain deposits
{
    "error": "unauthorized"
}

// 503 Service Unavailable - operator bridge is not configured on this node
{
    "error": "RC_ADMIN_KEY not configured"
}

// 400 Bad Request - Insufficient balance
{
    "error": "Insufficient available balance",
    "available_rtc": 50.0,
    "pending_debits_rtc": 20.0,
    "requested_rtc": 100.0
}

// 400 Bad Request - Invalid address
{
    "error": "Invalid solana address: length must be 32-44 characters"
}

2. Query Bridge Status

Get status of a specific bridge transfer.

Endpoint: GET /api/bridge/status/<tx_hash>

Or with query parameter:

GET /api/bridge/status?tx_hash=abc123...
GET /api/bridge/status?id=12345

Response (200 OK):

{
    "ok": true,
    "transfer": {
        "id": 12345,
        "direction": "deposit",
        "source_chain": "rustchain",
        "dest_chain": "solana",
        "source_address": "RTC_miner123",
        "dest_address": "4TRwNqXqXqXqXqXqXqXqXqXqXqXqXqXqXqXq",
        "amount_rtc": 100.0,
        "bridge_type": "bottube",
        "external_tx_hash": "5xKjPqR...",
        "external_confirmations": 8,
        "required_confirmations": 12,
        "status": "confirming",
        "lock_epoch": 85,
        "created_at": 1709856000,
        "updated_at": 1709859600,
        "expires_at": 1710460800,
        "tx_hash": "abc123def456...",
        "memo": null
    }
}

Status Values:

StatusDescription
pendingTransfer initiated, awaiting lock
lockedAssets locked, awaiting external confirmation
confirmingExternal confirmations in progress
completedTransfer completed successfully
failedTransfer failed (see failure_reason)
voidedTransfer voided by admin/user

Error Responses:

// 404 Not Found
{
    "error": "Bridge transfer not found"
}

3. List Bridge Transfers

List bridge transfers with optional filters.

Endpoint: GET /api/bridge/list

Query Parameters:

ParameterTypeDefaultDescription
statusstring-Filter by status
source_addressstring-Filter by source address
dest_addressstring-Filter by destination address
directionstring-Filter by direction
limitinteger100Max results (max: 500)

Example:

GET /api/bridge/list?status=pending&source_address=RTC_miner123&limit=50

Response (200 OK):

{
    "ok": true,
    "count": 3,
    "transfers": [
        {
            "id": 12345,
            "direction": "deposit",
            "source_chain": "rustchain",
            "dest_chain": "solana",
            "source_address": "RTC_miner123",
            "dest_address": "4TRwNqXqXqXqXqXqXqXqXqXqXqXqXqXqXqXq",
            "amount_rtc": 100.0,
            "bridge_type": "bottube",
            "external_tx_hash": "5xKjPqR...",
            "external_confirmations": 8,
            "required_confirmations": 12,
            "status": "confirming",
            "lock_epoch": 85,
            "created_at": 1709856000,
            "tx_hash": "abc123def456..."
        }
    ]
}

4. Void Bridge Transfer (Admin)

Void a pending bridge transfer and release associated locks.

Endpoint: POST /api/bridge/void

Headers:

X-Admin-Key: <admin-key>

Request:

{
    "tx_hash": "abc123def456...",
    "reason": "user_request",
    "voided_by": "admin_john"
}

Reason Values:

ValueDescription
user_requestUser requested cancellation
security_holdSecurity team flagged transfer
failed_externalExternal chain transfer failed
admin_voidGeneral admin void

Response (200 OK):

{
    "ok": true,
    "voided_id": 12345,
    "tx_hash": "abc123def456...",
    "source_address": "RTC_miner123",
    "dest_address": "4TRwNqXqXqXqXqXqXqXqXqXqXqXqXqXqXqXq",
    "amount_rtc": 100.0,
    "voided_by": "admin_john",
    "reason": "user_request",
    "lock_released": true
}

5. Update External Confirmation (Bridge Service)

Update external transaction confirmation data (called by bridge service).

Endpoint: POST /api/bridge/update-external

Headers:

X-API-Key: <bridge-api-key>

Request:

{
    "tx_hash": "abc123def456...",
    "external_tx_hash": "5xKjPqR...",
    "confirmations": 8,
    "required_confirmations": 12
}

Response (200 OK):

{
    "ok": true,
    "tx_hash": "abc123def456...",
    "status": "confirming",
    "external_confirmations": 8,
    "required_confirmations": 12
}

6. Get Miner Locks

Get lock ledger entries for a specific miner.

Endpoint: GET /api/lock/miner/<miner_id>

Query Parameters:

ParameterTypeDefaultDescription
statusstring-Filter: locked, released, forfeited, or summary
limitinteger100Max results

Example:

GET /api/lock/miner/RTC_miner123?status=locked
GET /api/lock/miner/RTC_miner123?status=summary

Response (200 OK) - List:

{
    "ok": true,
    "miner_id": "RTC_miner123",
    "count": 2,
    "locks": [
        {
            "id": 789,
            "amount_rtc": 50.0,
            "lock_type": "bridge_deposit",
            "status": "locked",
            "locked_at": 1709856000,
            "unlock_at": 1709942400,
            "time_until_unlock": 86400
        }
    ]
}

Response (200 OK) - Summary:

{
    "miner_id": "RTC_miner123",
    "total_locked_rtc": 150.0,
    "total_locked_count": 3,
    "breakdown": {
        "bridge_deposit": {"amount_rtc": 100.0, "count": 2},
        "bridge_withdraw": {"amount_rtc": 50.0, "count": 1}
    },
    "next_unlock": {
        "unlock_at": 1709942400,
        "amount_rtc": 50.0,
        "seconds_until": 86400
    }
}

7. Get Pending Unlocks

Get locks ready to be released.

Endpoint: GET /api/lock/pending-unlock

Query Parameters:

ParameterTypeDefaultDescription
beforeinteger-Unix timestamp filter
limitinteger100Max results

Response (200 OK):

{
    "ok": true,
    "count": 5,
    "locks": [
        {
            "id": 789,
            "miner_id": "RTC_miner123",
            "amount_rtc": 50.0,
            "lock_type": "bridge_deposit",
            "unlock_at": 1709856000,
            "expired_seconds": 3600
        }
    ]
}

8. Release Lock (Admin)

Manually release a lock.

Endpoint: POST /api/lock/release

Headers:

X-Admin-Key: <admin-key>

Request:

{
    "lock_id": 789,
    "release_tx_hash": "optional_tx_hash"
}

Response (200 OK):

{
    "ok": true,
    "lock_id": 789,
    "miner_id": "RTC_miner123",
    "amount_rtc": 50.0,
    "released_by": "admin",
    "release_tx_hash": "optional_tx_hash",
    "released_at": 1709859600
}

9. Forfeit Lock (Admin)

Forfeit a lock (penalty/slashing).

Endpoint: POST /api/lock/forfeit

Headers:

X-Admin-Key: <admin-key>

Request:

{
    "lock_id": 789,
    "reason": "penalty"
}

Response (200 OK):

{
    "ok": true,
    "lock_id": 789,
    "miner_id": "RTC_miner123",
    "amount_rtc": 50.0,
    "reason": "penalty",
    "forfeited_by": "admin",
    "forfeited_at": 1709859600,
    "note": "Forfeited assets are retained by protocol"
}

10. Auto-Release Expired Locks (Worker)

Automatically release locks that have passed their unlock time.

Endpoint: POST /api/lock/auto-release

Headers:

X-Worker-Key: <worker-key>

Query Parameters:

ParameterTypeDefaultDescription
batch_sizeinteger100Max locks to release per call

Response (200 OK):

{
    "released_count": 10,
    "total_amount_rtc": 500.0,
    "errors": [],
    "processed_at": 1709859600
}

Error Codes

HTTP CodeDescription
200Success
400Bad Request - Invalid payload or validation error
401Unauthorized - Missing or invalid auth key
404Not Found - Resource doesn't exist
500Internal Server Error

Configuration

Environment variables:

VariableDefaultDescription
RC_BRIDGE_DEFAULT_CONFIRMATIONS12Default external confirmations required
RC_BRIDGE_LOCK_EXPIRY_SECONDS604800Max lock duration (7 days)
RC_BRIDGE_MIN_AMOUNT_RTC1.0Minimum bridge amount
RC_BRIDGE_API_KEY-API key for bridge callbacks

Integration Example

Python Example: Initiate Bridge Transfer

import requests

BASE_URL = "https://rustchain.org"

def initiate_bridge_deposit(miner_id, dest_address, amount_rtc):
    """Initiate a bridge deposit from RustChain to Solana."""
    response = requests.post(
        f"{BASE_URL}/api/bridge/initiate",
        json={
            "direction": "deposit",
            "source_chain": "rustchain",
            "dest_chain": "solana",
            "source_address": miner_id,
            "dest_address": dest_address,
            "amount_rtc": amount_rtc
        }
    )
    
    if response.status_code == 200:
        result = response.json()
        print(f"Bridge initiated: {result['tx_hash']}")
        print(f"Status: {result['status']}")
        print(f"Estimated completion: {result['estimated_completion']}")
        return result
    else:
        print(f"Error: {response.json()}")
        return None

# Usage
result = initiate_bridge_deposit(
    miner_id="RTC_miner123",
    dest_address="4TRwNqXqXqXqXqXqXqXqXqXqXqXqXqXqXqXq",
    amount_rtc=100.0
)

Python Example: Check Bridge Status

def check_bridge_status(tx_hash):
    """Check status of a bridge transfer."""
    response = requests.get(f"{BASE_URL}/api/bridge/status/{tx_hash}")
    
    if response.status_code == 200:
        transfer = response.json()["transfer"]
        print(f"Status: {transfer['status']}")
        print(f"Confirmations: {transfer['external_confirmations']}/{transfer['required_confirmations']}")
        return transfer
    else:
        print(f"Error: {response.json()}")
        return None

# Usage
status = check_bridge_status("abc123def456...")

Security Considerations

  1. Admin Key Protection: Store admin keys securely, never expose in client code
  2. Address Validation: Always validate destination addresses before initiating
  3. Confirmation Monitoring: Monitor external confirmations for completion
  4. Lock Expiry: Transfers auto-expire after 7 days if not completed
  5. Rate Limiting: Implement rate limiting on production endpoints