Skip to content

Latest commit

 

History

History
181 lines (138 loc) · 5.65 KB

File metadata and controls

181 lines (138 loc) · 5.65 KB

SettleProof Engineering Overview

SettleProof verifies whether an expected crypto payment is safe for a business to act on. The system exists to avoid a single RPC provider becoming the only source of truth for fulfillment, access control, account crediting, or invoice closure.

Problem

A merchant needs one operational answer: can this payment be treated as paid?

Relying on one RPC provider creates avoidable failure modes:

  • The provider is unavailable, so paid customers look unpaid.
  • The provider is stale, so confirmations appear later than they should.
  • The provider returns bad or inconsistent data, so an unpaid invoice may look paid.
  • Support and ops fall back to manual block explorer checks.

SettleProof reduces that risk by checking multiple RPC providers and recording the evidence behind the final task status.

Target MVP Architecture

graph TD
    Merchant["Merchant system"] -->|POST /v1/tasks| API["SettleProof API"]
    API --> Store["SQLite task store"]
    Worker["Verification worker"] --> Store
    Worker --> RPC1["RPC provider A"]
    Worker --> RPC2["RPC provider B"]
    Worker --> RPC3["RPC provider C"]
    RPC1 --> Quorum["Quorum evaluator"]
    RPC2 --> Quorum
    RPC3 --> Quorum
    Quorum --> Store
    Store --> Callback["Callback delivery"]
    Callback -->|status update| Merchant
Loading

The MVP should keep the system small:

  • REST intake for verification tasks.
  • SQLite persistence for tasks, observations, status history, and callback attempts.
  • Multi-RPC quorum verification for ERC20 transfers.
  • At-least-once callback delivery when task status changes.
  • Local devnet proof using Anvil and simulated RPC provider failures.

Task Intake API

Implemented intake endpoints:

  • GET /health: returns API and SQLite health.
  • POST /v1/tasks: validates and persists an ERC20 transfer verification task.
  • GET /v1/tasks/{task_id}: returns the stored task state.

POST /v1/tasks accepts:

{
  "type": "erc20_transfer",
  "chain_id": 31337,
  "token_address": "0x0000000000000000000000000000000000000001",
  "from_address": "0x0000000000000000000000000000000000000002",
  "to_address": "0x0000000000000000000000000000000000000003",
  "amount": "1000000",
  "from_block": 1,
  "min_confirmations": 12,
  "callback_url": "http://merchant.local/callback",
  "expires_after_blocks": 1000
}

Notes:

  • task_id is optional. If omitted, SettleProof generates one.
  • Idempotency-Key is optional but recommended for merchant retries.
  • A repeated request with the same idempotency key and same body returns the existing task.
  • A repeated idempotency key or task id with different request content returns 409 Conflict.
  • New tasks start as pending; the verification round reads pending tasks from SQLite in oldest-first batches.

Verification Flow

  1. A merchant submits the expected payment and a callback URL.
  2. SettleProof stores the task and returns a task id.
  3. The verifier queries configured RPC providers for latest block and matching ERC20 transfer logs.
  4. A payment is confirmed only when the configured quorum agrees on the same transaction hash, block number, and log index with enough confirmations.
  5. SettleProof records the status transition, checked provider count, quorum provider count, and settlement evidence.
  6. Callback delivery is still stubbed; durable delivery is the next MVP gap.

The core invariant is:

SettleProof must not mark a payment confirmed from one RPC provider alone.

Status Model

Recommended task statuses for the MVP:

  • pending: task accepted and waiting for enough evidence.
  • confirmed: quorum agreed on a matching transaction with enough confirmations.
  • conflict: providers returned incompatible confirmed evidence.
  • ambiguous: multiple matching events satisfy the task and the task needs narrower input.
  • expired: the task passed its configured block/time limit without confirmation.
  • callback_failed: the task status changed, but callback delivery reached its retry limit.

Current Repository State

This repository started as a hackathon demo built on Open Autonomy/AEA. The current code has a REST task intake path backed by SQLite. The agent reads pending SQLite tasks, checks configured RPC providers, and marks ERC20 transfer tasks confirmed only when quorum agrees on the same log identity.

Known gaps before the MVP claim is true:

  • Webhook delivery is currently stubbed and needs retries plus durable attempt records.
  • The local proof should move from public fork/manual setup to an Anvil-based devnet test.
  • Provider observations are summarized on the task row; a dedicated observation table would make audits and debugging stronger.

Development

System Requirements

  • Python >=3.10
  • Poetry
  • Docker Engine and Docker Compose
  • Tendermint 0.34.19
  • IPFS node 0.6.0

Existing Demo Commands

Create a virtual environment and install dependencies:

poetry shell
poetry install

Sync Open Autonomy packages:

autonomy packages sync --update-packages

Run one local agent after creating .env and key files:

bash run_agent.sh

Run the four-agent service after preparing .env and keys.json:

bash run_service.sh

MVP Test Direction

The productized test path should avoid mainnet and public testnets:

  • Start Anvil locally.
  • Deploy a minimal ERC20 test token.
  • Expose three RPC provider facades that can simulate healthy, down, lagging, and corrupt provider behavior.
  • Submit a SettleProof task through the REST API.
  • Send a matching ERC20 transfer on Anvil.
  • Assert the task reaches confirmed only when quorum agrees.
  • Assert callbacks are retried and recorded when the receiver fails.