LOPWDocumentation

Docs / Guides

Getting started for app builders

Everything LOPW does on-chain is public and indexed. The read-only API serves it as JSON for third-party apps, mobile clients and agents: no wallet, no node, no key.

Conventions

First calls

HTTP
GET /v1/testnet/stats
// { "services": 2, "active_services": 2, "total_stake": "4000000000", "claims_paid": 9, "claims_rejected": 1, "total_paid": "320000000", "indexed_ledger": 5021999 }

GET /v1/testnet/services?state=Active&limit=50
// { "data": [ { "service_id": "…64 hex…", "seller": "G…", "state": "Active", "stake": "2000000000", "min_stake": "1000000000",
//              "pending_withdrawal": "0", "terms_hash": "…", "key_version": 1, "claims": { "paid": 3, "rejected": 0, "total_paid": "150000000" } } ],
//   "next_cursor": null }

GET /v1/testnet/services/{service_id}/claims?outcome=paid
// { "data": [ { "id": "…", "service_id": "…", "predicate_id": 6, "outcome": "paid", "reason": null, "buyer": "G…", "amount": "50000000",
//              "payment_reference": "…", "transaction": "…", "ledger": 5021500, "occurred_at": 1790991420 } ], "next_cursor": null }

Field values shown here are illustrative shapes, not live numbers.

Live events

TypeScript
const es = new EventSource("https://api.lopw.com/v1/testnet/stream");
es.addEventListener("claim_paid", (e) => console.log("claim paid", JSON.parse(e.data)));
es.addEventListener("state_changed", (e) => console.log("state changed", JSON.parse(e.data)));
// Each message has id (event ID), event (kind) and data (an Event). Resume with the Last-Event-ID header or ?after=<id>.

Event kinds mirror the contract events: service_registered, deposited, slashed, state_changed, claim_paid, claim_rejected, and the admin events (claims_change_proposed, validator_change_proposed, claims_contract_set, validator_set). The full list is in the registry and claims references.

Reading the chain directly

The API is a convenience; the chain is the source of truth. Any app can read the same data with the protocol package’s binding, which simulates read-only contract calls from a throwaway account and never signs anything:

TypeScript
import { StellarBinding, getNetwork } from "@lopw/protocol";
const binding = new StellarBinding(getNetwork("testnet"));
const service = await binding.getService(serviceId);                   // { seller, state, stake, min_stake, terms_hash, key_version, max_claim_window, pending_withdrawal }
const terms = await binding.getTerms(serviceId, service.terms_hash);   // { predicates, claim_window, max_data_age, allowed_status, max_response_bytes, oracle }
const key = await binding.getKey(serviceId, service.key_version);      // { public_key, registered_at, retired_at }

Next: the complete HTTP API reference, or read one service’s bond from its own discovery endpoint.