Independent settlement intelligence for Stellar — evidence about a counterparty, computed from the public ledger rather than supplied by the counterparty.
Every answer to that question available today comes from the party being assessed: their stellar.toml, their /info endpoint, their status page. Each is editable in ten seconds. Landfall does not ask them. It reads what their accounts actually did on-chain, and publishes the result permissionlessly — for anchors, for arbitrary addresses, and for the payee an autonomous agent is about to sign a payment to.
| Ask | Landfall answers with |
|---|---|
| Is this anchor still settling? | Liveness, volume, counterparty concentration and refund rate, from SEP-24 legs already on the ledger |
| Is this address safe to pay? | Trust Check — account age, concentration and pass-through signals, a 0–100 score where every deduction names its evidence, and a confidence rating that overrides the score when history is too thin |
| Has anyone reported them? | Evidence-anchored fraud reports — every one cites a transaction verified to exist and involve the subject — each answerable by the reported party through a signature, never a password |
| Which route should this take? | Intent + Route Engine: routes ranked with evidence ahead of price, returning a step-by-step plan where every step names who performs it |
| Who should an agent pay? | x402 payee checks, an 11-tool MCP server, and @landfall/sdk on npm |
What it will not do: move your money. Landfall holds no keys, signs no payments, and takes no custody — every step that moves value belongs to the wallet or the anchor. That is a standing design decision, not a missing feature (why).
Live: landfall-chi.vercel.app · Architecture: three planes · Trust assumptions: what you must trust
Contributors welcome. Issues are filed and labelled by complexity. Start with
good first issue, and wait to be assigned before writing code — an unassigned issue is not yours. See CONTRIBUTING.md.
- Why this exists
- Current finding
- Tech stack
- Getting started
- Environment variables
- Documentation
- Honesty rules
- Contributing
- Contributors
- License
Stellar's anchors are the bridge between the ledger and real money, and there is no independent record of whether any of them are actually settling.
An anchor is the on/off ramp: it takes fiat and issues a token, or takes the token and pays out fiat. A wallet routing a remittance has to pick one. Today that choice rests on three things, and all three are supplied by the anchor itself:
| What a wallet can check today | Who controls the answer |
|---|---|
The stellar.toml at the home domain |
The anchor — editable in ten seconds |
The SEP-24 /info endpoint |
The anchor — it returns what it chooses |
| The anchor's own status page | The anchor |
So the question "is this anchor still paying people?" has no answer a wallet can verify. When an anchor quietly stops settling, the ledger shows it immediately — but nobody was reading the ledger for that purpose, so the first signal reaching a user is their own payment not arriving.
This has teeth on Stellar specifically because the network's whole value proposition is cross-border payments into markets where the recipient is least able to absorb a failure. A stalled remittance is not an inconvenience; and the party best placed to detect the stall — the anchor — is the party with the least incentive to announce it.
Landfall answers it from the ledger instead. Anchor accounts are discovered from SEP-1, their SEP-24 settlement legs are already public and permanent, and liveness, volume, counterparty concentration and refund rate are computed from what those accounts did. No anchor grants access. No anchor can withhold it. A TOML file can be edited in ten seconds; two years of settlement history cannot.
This is answerable because of how Stellar itself works, not despite it:
- SEP-1 resolves a home domain to the accounts an anchor claims to operate — permissionlessly, with no cooperation required.
- SEP-24 puts one leg of every deposit and withdrawal on the public ledger, so settlement behaviour is already there, retroactively, for every anchor — a prober starts collecting the day you switch it on, Landfall computed years of history on its first run.
- CAP-67 (Protocol 23) turns per-account paging into one unified event stream, and makes mint/burn distinguishable from transfer instead of inferred.
- SEP-38 firm quotes give slippage — quoted amount versus landed amount — a defined baseline, which nothing in the ecosystem publishes today.
- x402 turns "can an agent pay?" into a solved problem, and leaves "who should an agent pay?" open — see below.
- Soroban publishes a digest of each dataset on-chain (deployed to testnet), so a contract can route on the same data a wallet reads from the API, and anyone can re-derive the digest and check it agrees.
Move any of this to a chain without those primitives and there is nothing left — it is not a generic app that happens to settle on Stellar.
In July 2026 Stellar joined the x402 Foundation alongside Visa, Stripe and Google, standardising how software pays software with no human in the loop. Stellar's own x402 announcement covers the settlement path in detail — facilitators, spending limits, budget controls, stablecoin transfer in about five seconds. It answers how much an agent may spend. It does not answer who an agent should be willing to pay.
A human routing a payment has a fallback the protocol does not provide: they recognise the brand, they have used it before, a colleague vouched for it. An autonomous agent has none of that. It has a domain string and whatever that domain says about itself — which is the one input that can be edited in ten seconds.
That is the gap Landfall was already built for, and why the MCP server matters more than its size suggests: it is the interface through which an agent can ask did this anchor actually settle? and get an answer computed from the ledger rather than supplied by the counterparty.
Nothing in this repository claims that gap is closed. No external agent queries Landfall today. But the question is now the ecosystem's, not just ours.
What is built, and what is not:
| Capability | Status | Description |
|---|---|---|
| SEP-1 discovery | ✅ shipping | Permissionless domain → declared issuer/distribution accounts |
| Horizon indexing & incremental sync | ✅ shipping | Scheduled scan with fast order=asc cursor pagination (sub-minute runtime) |
| Liveness, volume, concentration, returns | ✅ shipping | Deterministic settlement metrics without requesting data from anchors |
| Path payments (cross-asset flows) | ✅ shipping | Extracts source & delivered asset pairs (USD ➔ NGN, EUR ➔ BRL) |
| Settlement corridors API + export | ✅ shipping | GET /api/v1/corridors with real-time matrix and compliance CSV export |
| Anchor Reliability Score (0–100 & A–F) | ✅ shipping | Deterministic health score based on liveness, throughput, and refund rates |
| Pre-Flight Wallet Health Check API | ✅ shipping | GET /api/v1/anchors/:domain/health-check for wallet routing checks |
| Dynamic SVG Status Badges | ✅ shipping | GET /api/v1/badges/:domain.svg for embedding live status badges in repos/docs |
| Developer & Admin Portal | ✅ shipping | /portal.html with self-serve auth, hashed API keys (lf_live_...), and webhooks |
| Interactive API Documentation | ✅ shipping | /docs.html with live try-it playground and badge renderer |
| Model Context Protocol (MCP) Server | ✅ shipping | scripts/mcp/server.mjs for AI agents (Claude, Cursor, Antigravity) |
| x402 payee check & paid API | ✅ shipping, testnet paywall live | POST /api/v1/x402/check-payee, landfall_x402_check_payee MCP tool, and native HTTP 402 paywall on premium exports (POST /api/v1/corridors/export). Includes interactive in-browser tester at /x402-tester.html. Supports both classic (G...) and muxed (M...) accounts. See packages/x402 |
| GraphQL API | ✅ shipping | POST /api/v1/graphql for structured queries |
| Postgres persistence + REST API | ✅ shipping | Supabase Session Pooler + serverless Vercel function endpoints |
| Live transactions dashboard | ✅ shipping | /dashboard.html with dark account indicators and counterparty breakdown |
| Scheduled ledger scan (GitHub Actions) | ✅ shipping | Cron asks for hourly (0 * * * *); GitHub runs scheduled workflows best-effort, so the measured cadence over 24h is a median 2.8h gap (range 1.7–4.8h), starting a median 38 minutes past the hour. Every payload carries asOf/staleHours so a consumer reads the real age rather than trusting a schedule. $0/month hosting upkeep |
Anchor Route Scout (/compare.html) |
Reliability grades are ledger-derived. Fees are live where an anchor publishes SEP-24 terms, hardcoded catalogue otherwise. FX rates now check every anchor's SEP-38 quote server too — but as of this writing SEP-38 adoption among tracked anchors is close to zero, so the rate column is still mostly the catalogue spread. See docs/gaps.md and /api/v1/anchor-quotes.json for exactly which anchor, if any |
|
Trust Check (/trust-check.html) |
✅ shipping | Paste a Stellar address (classic G... or muxed M...) or transaction hash — live, ledger-only counterparty signals (observed history, counterparty concentration, pass-through/forwarding pattern), a transparent 0–100 score with every deduction traceable to a named flag, and a confidence rating that overrides the score when there isn't enough history to say anything. No external fraud database — none exists that this project can independently verify, and fabricating one would be the exact failure mode Landfall exists to catch elsewhere. See packages/trust-check/src/analyze.ts |
| Fraud Reports | ✅ shipping | POST /api/v1/fraud-reports — every report must cite a transaction Landfall verifies exists and involves the reported address before it is stored; unverifiable reports are rejected, not filed quietly at low weight. Shown on the Trust Check page in their own card, never blended into the score, and report volume is never counted toward anything — three reports is three strangers, which may be three victims or one person with three browsers. See packages/fraud-reports |
| Dispute response | ✅ shipping | POST /api/v1/fraud-reports/:id/dispute — the reported party answers, gated on an Ed25519 signature from that account's own key. Landfall never asks for or receives a secret key: the page shows the message to sign and takes back only the signature. The response travels with the accusation everywhere the report appears |
| AI Investigator (Sentinel's "Analyzed" stage) | ✅ shipping, narrative needs a key | POST /api/v1/fraud-reports/:id/investigate — splits into two strictly separate halves. Cited facts (the report's fields, the cited transaction re-fetched from Horizon, the subject's Trust Check flags) are deterministic and computed with no AI at all. The narrative is optional model-written prose over exactly those facts, labelled with the model that wrote it, and null whenever no key is configured. The model is never told how many other reports exist — feeding it a count risks it reading volume as corroboration, which is the one thing fraud reports must never become. See packages/investigator |
| Dispute-response attestations (Sentinel's "Attested" stage) | ✅ shipping, one-sided on purpose | GET /api/v1/fraud-reports/:id/attestation — a portable, verifiable record that the account holder responded and proved control. The accusation itself is never signed: a signature makes a claim permanent and portable, and a portable accusation travels stripped of the disclaimer and the response that hold it honest. So the payload carries no category, no reporter note and no evidence hash — asserted by a test, not just by intent. Signed when STP_SIGNING_KEY is set, otherwise a recomputable SHA-256 digest and signed: false |
Crypto Routes (/compare.html, same page) |
✅ shipping | Live XLM→BTC/ETH/SOL/BNB quotes fetched client-side from NEAR Intents' public 1Click API — real market rates, no API key, no backend. Informational only: Landfall never executes the swap. Stellar-side USDC isn't wired up yet (see the note in the page) |
Cross-chain evidence view (/cross-chain.html) |
✅ shipping | Per-anchor settlement evidence across Stellar, EVM/CCTP, Tron and Solana, every figure labelled with the tier behind it |
| STP attestation schema + signing | ✅ shipping | packages/stp — one portable settlement-attestation shape, canonical serialization, Ed25519 sign/verify |
ChainAdapter layer |
✅ shipping | Stellar (PROVEN), EVM/CCTP (ATTESTED), Tron + Solana (DERIVED) behind one interface — see docs/architecture/MULTICHAIN.md |
pickAnchor() evidence ranking |
✅ shipping, on npm | npm install @landfall/sdk — ranks PROVEN → ATTESTED → DERIVED, so derived evidence can never outrank ledger-proven settlement. Deliberately no blended score. See packages/sdk/README.md |
Python SDK (landfall-sdk) |
✅ shipping | Python package with native LangChain and CrewAI agent tool integrations. See packages/sdk-py |
| Non-Stellar anchor addresses | Curated verified gateway addresses for MoneyGram and Circle in registry/anchors.registry.json; other anchors report unresolved |
|
| Recipient-confirmation proof binder | ✅ shipping | The weakest of three ways to bind DERIVED evidence, and the only one needing no anchor cooperation — a recipient's own report, tightly scoped (once per transfer, timed server-side, sender reports never bind). See packages/adapters/src/fiatConfirmation.ts |
| zkTLS / Proof-of-Reserve proof binder | designed, not built | The two stronger options — need a counterparty's cooperation or hard engineering. Until either exists the DERIVED adapters lean on recipient confirmation or emit nothing |
| Soroban smart contract oracle | deployed to testnet | Rust Soroban contract with 16 test cases, digest verification |
| CAP-67 event stream ingestion | ✅ shipping | Protocol 23 event streaming via Stellar RPC in packages/indexer/src/rpc-events.ts and continuous sub-minute stream-daemon.ts |
| Live SEP-38 quote ingestion | ✅ shipping, near-zero coverage | scripts/fetch-anchor-quotes.mjs asks every tracked anchor's own quote server hourly. The mechanism is real; today essentially no tracked anchor runs SEP-38 against a corridor Route Scout shows for it, so most rates are still the catalogue estimate — stated per anchor, not hidden |
| Dark-anchor early warning (predictive) | measured as not yet buildable | The scan history now exists as a committed record (data/scan-history.ndjson, 5,900+ observations from 12 August, extended hourly). Measured against it, exactly one account went dark in 26 days (slow → dark, n=1) against 17 live → slow degradations. This roadmap item requires the false-positive rate be published, and one positive example cannot produce a rate that means anything — any threshold fits n=1 perfectly and generalises to nothing. Revisited on a count of going-dark events, not on a date. Full transition table in data/README.md |
pickAnchor() multi-factor route scoring |
designed, not built | Weighted score over payout, reliability, and degradation signal; needs real quotes first |
| Slippage: quoted versus landed | ✅ shipping | Deterministic basis-point calculation comparing SEP-38 firm quotes against on-chain delivery amounts (packages/stp/src/slippage.ts) |
We would rather list this honestly than let a roadmap read as a changelog. Full detail in docs/gaps.md and ROADMAP.md.
From the scheduled ledger scan, most recently 8 September 2026, across 108 declared anchor accounts on 27 Stellar home domains:
63 of 108 anchor accounts have processed no on-chain settlement in over 30 days. A further 27 are slow (nothing in 3–30 days); 17 are settling; 1 has no payment history at all.
Recomputable from data/scan-history.ndjson, which
carries every observation behind this figure rather than only the latest.
Two things this is not. It is not a census — the scan covers accounts seeded in
packages/indexer/data/anchors.json and discovered from their own SEP-1
declarations, which is a curated set, not every anchor on Stellar. And a dark
account is not a failed anchor: an issuer account that never moves, a rotated
account still declared in a stale stellar.toml, and an operator who has actually
stopped settling all look identical from the ledger. The figure is what the ledger
shows, not a verdict on any operator — see DISPUTES.md if you run one
of these and think a specific figure is wrong.
Every figure ships with its transaction hashes — see /dashboard.html on the live
site, and /api/v1/anchors.json for the raw records behind it.
(An earlier version of this section read "6 of 13 accounts", from the first scan on 12 August 2026. That number was true of that scan and is preserved in docs/gaps.md as the dated record it is — the network tracked here has since grown from 5 domains to 27.)
| Layer | Technology |
|---|---|
| Indexer | TypeScript, Node.js 20+, tsx, node:test (zero-dep SEP-1/TOML parser, CAP-67 RPC streaming, incremental cursor syncing) |
| API | Node.js serverless functions, read-only HTTP & x402 payment routes over pg with Supabase pooler |
| Web Portal | Vanilla HTML/CSS/JS (no framework bloat), responsive for mobile, GSAP loader |
| Oracle | Rust, Soroban SDK — deployed to testnet |
| AI Integration | Model Context Protocol (MCP) stdio server (@modelcontextprotocol/sdk) + Python SDK (landfall-sdk with LangChain & CrewAI) |
| Database | PostgreSQL (Supabase Session Pooler or local via Docker) |
| Deployment | Vercel (frontend + API proxy), GitHub Actions (scheduled ledger scan cron) |
Whole stack, one command. Requires Docker.
# Clone the repository
git clone https://github.com/ibochivincent-lang/landfall.git
cd landfall
cp .env.example .env
# Run full stack with local Postgres + Horizon
docker compose upBrings up a local Stellar Quickstart node, Postgres with the schema applied, the indexer, and the API — no account anywhere, no mainnet, no credentials. Site on :8080, API on :8787, Horizon on :8000.
If you already run Postgres natively, port 5432 is taken and both servers will bind it — host connections then reach the wrong one and fail with a password error against credentials that are correct. Publish the container somewhere else instead:
POSTGRES_PORT=55432 docker compose upJust the indexer. Requires Node 20+, no Docker, no database.
npm install
npm run anchors:discover # propose new anchor domains from an independent directory
npm run discover # resolve tracked anchor domains to on-chain accounts
npm run scan # index payment history and print the finding
npm run scan:verify # check the newest scan before it could be published
npm test # 460+ JS + 5 Python + 25 Rust tests
npm run typecheckanchors:discover reads stellar.expert's anchor directory, drops anything
tagged malicious/unsafe/scam, and resolves what remains against SEP-1 — a
domain only reaches the seed list if it declares its own accounts. It reports
by default; -- --write applies. The directory is treated as a source of
candidates, never of truth.
Layout:
packages/contracts Rust + Soroban oracle
packages/db PostgreSQL schema
packages/indexer ledger reader, CAP-67 RPC streaming, and metrics
packages/api read-only HTTP API & x402 payment routes
packages/web the public site, dashboard, and x402 tester
packages/sdk @landfall/sdk TypeScript client
packages/sdk-py landfall-sdk Python client (LangChain & CrewAI)
packages/x402 payee risk evaluation & muxed account unwrapping
packages/stp settlement attestation schema & slippage tracking
Scan flags, deployment steps (Supabase, prod compose, Vercel, oracle), and the transactions dashboard are covered in docs/architecture.md and docs/deployment.md.
DOMAIN ACCOUNT IN OUT REFUNDS RATE LAST SEEN
--------------------------------------------------------------------------------------
example-anchor.com GABC…WXYZ 1204 1190 47 3.90% 2.1h
Followed by a headline finding — the aggregate refund rate across every account with enough inbound traffic to support the claim.
An internal /admin view for maintainers — backend health (scan status, table sizes, resume cursors), the full raw payment stream, and tracked-anchor management (added domains feed straight into the next scan, no redeploy needed). Session-based login only: scrypt-hashed passwords, httpOnly cookies, 24h expiry. There is no public sign-up route and it is not linked from the public nav.
npm run db:migrate
DATABASE_URL=... node scripts/create-admin.mjs <username>Then log in at /admin on the deployed site, or localhost:8080/admin locally. Full setup notes in docs/deployment.md.
Copy .env.example to .env and adjust. Nothing in the example file is a secret — the local stack is deliberately credential-free so a contributor can start without asking anyone for anything.
| Variable | Required | Default | Description |
|---|---|---|---|
DATABASE_URL |
For --persist |
postgres://landfall:landfall@localhost:5432/landfall |
Postgres connection string. |
HORIZON_URL |
No | http://localhost:8000 |
Horizon server. Point at https://horizon.stellar.org to scan mainnet anchors. |
SOROBAN_RPC_URL |
No | http://localhost:8001 |
Soroban RPC endpoint, for oracle interaction. |
SCAN_INTERVAL_SECONDS |
No | 900 |
How often the indexer loop re-scans. |
DUST_THRESHOLD |
No | 0.01 |
Minimum payment amount counted, to filter dust. |
MAX_RECORDS |
No | 10000 |
Per-account record cap for a scan. |
PORT |
No | 8787 |
API listen port. |
CORS_ORIGIN |
No | * |
API CORS origin. |
ORACLE_CONTRACT_ID |
Only to publish on-chain | — | Deployed Soroban oracle contract id. |
ORACLE_ADMIN_SECRET |
Only to publish on-chain | — | Admin key for the oracle contract. Never commit this. |
SEP10_SERVER_SECRET |
For Stellar web auth | — | Server signing key (S...) for SEP-10. Unset means /api/v1/auth reports that web auth is disabled — no challenge, no token, nothing half-enabled. |
SEP10_HOME_DOMAIN |
No | landfall-chi.vercel.app |
Home domain named in the challenge. Must match what the client expects, or its wallet will refuse to sign. |
SEP10_NETWORK_PASSPHRASE |
No | Public network | Set to the testnet passphrase to authenticate testnet accounts. |
SEP10_JWT_LIFETIME_SECONDS |
No | 86400 |
Token lifetime. |
RESEND_API_KEY |
For password-reset emails | — | Resend API key. Without it, the reset endpoint logs a clear failure instead of pretending to succeed. |
FROM_EMAIL |
Same as above | — | Sending address. Must be on a domain verified with Resend — it cannot send from a vercel.app subdomain this project doesn't control DNS for. |
| Document | What it covers |
|---|---|
| docs/architecture.md | The three-plane architecture, the scan lifecycle, SEP-10 auth and the x402 payee check — as rendered diagrams. |
| CHANGELOG.md | Notable changes, Keep a Changelog format. Corrections are listed, not quietly dropped. |
| docs/KEY_ROTATION.md | What to do when a key is compromised or due for a change — different blast radius, different procedure, per secret. |
| docs/COOKBOOK.md | Nine working recipes, each one executed before it was written down. |
| docs/FOR_ANCHORS.md | For anchor operators: how you ended up here, what each field does and does not mean, and how to correct one. |
| docs/API_REFERENCE.md | Every public endpoint: shapes, rate limits, caching, error semantics, and what is deliberately not offered. |
| docs/WEBHOOKS.md | Event types, payload envelope, HMAC verification, retries and dead-letter replay. |
| docs/FAQ.md | Short answers to the questions the data actually provokes — starting with what dark does not mean. |
| docs/ORACLE_SPEC.md | The Soroban contract's full interface, events, errors and authority model. |
| docs/BENCHMARKS.md | Measured latency, test and cadence figures, with the method and what is not measured. |
| docs/CONTRIBUTOR_LADDER.md | Contributor → Triager → Reviewer → Maintainer, and what each rung grants. |
| docs/NON_CUSTODY.md | The constraint the rest of the design bends around, and where it is enforced rather than asserted. |
| docs/TAKEDOWN.md | What happens when someone demands a finding be removed — corrections are welcome, accurate findings are not withdrawn on request. |
| docs/JURISDICTIONAL.md | Regulatory and defamation posture for publishing findings about named businesses. |
| docs/GOVERNANCE.md | Who decides what, key authority, and what changes if a second person joins. |
| docs/VERSIONING.md | What is versioned, what breaks, and what will not break without warning. |
| docs/CANONICAL_JSON.md | The exact bytes an attestation is signed over, so a verifier can be written in any language. |
| docs/TERMS.md | Terms of use for the public API, site and SDK. |
| docs/WHY_NOT.md | Why not the anchor's own endpoint, the Anchor Platform, an explorer, Horizon directly, an AML vendor, or an LLM — including where one of those is the better choice. |
| docs/SEP_COVERAGE.md | Which SEPs and CAPs Landfall uses, for what, and which it deliberately does not implement. |
| docs/PROPOSAL.md | Funding proposal: the problem, what has shipped, what is deliberately not built, and the roadmap. |
| docs/architecture/MULTICHAIN.md | The cross-chain design: the STP attestation schema, the ChainAdapter interface, and the evidence-tier ladder that keeps a custodial guess from reading as ledger truth. |
| docs/methodology.md | Exactly how each published metric is computed, and where the method is weak. |
| docs/TRUST.md | What you have to trust to rely on this, stated plainly — including the one place you must trust a key rather than check a computation, and why the oracle is not on mainnet yet. |
| docs/SECURITY_ASSESSMENT.md | STRIDE and OWASP Top 10:2025 review, with findings cited to file and line — including one critical privilege escalation found and fixed, and what held up under review. |
| docs/gaps.md | Honest inventory of what isn't built yet, ordered by how much each gap could hurt. |
| docs/product-vision-status.md | The product vision deck, module by module, checked against what's actually running. |
| ROADMAP.md | What is built, what is next, and what is deliberately not being built. |
| docs/deployment.md | Full deploy path: Supabase, production compose, Vercel, the oracle. |
| docs/GRAPHQL_API.md | The /api/v1/graphql schema, examples, and how it reuses the REST resolvers. |
| docs/MCP.md | Running the MCP server, its tools, and how to connect an agent to it. |
| docs/backlog.md | Summary of the scoped, complexity-tagged issues filed on the tracker. |
| docs/checklist.md | Current status snapshot: what is done, what is open. |
| SECURITY.md | Disclosure policy. |
| CODE_OF_CONDUCT.md | Includes a project-specific clause on discussing named anchors factually. |
| DISPUTES.md | For a graded anchor operator: what a grade is and isn't, and how to challenge a specific figure. |
Constraints on the code, not aspirations:
-
No number on the site that the code cannot prove. Every published figure traces to indexed ledger records.
-
Failures are visible. A domain that will not resolve prints as
FAIL— never silently dropped, because a missing anchor is itself a finding. -
Thin data is suppressed, not ranked. A refund rate computed over three payments is noise dressed as a statistic. Accounts below
--min-inboundare excluded from the headline. -
Heuristics are labelled, everywhere they surface. Refund detection is a heuristic and says so. See docs/methodology.md.
-
Degradation is stale, not broken. There is no external probe to fail. If indexing stops, it resumes from the last cursor.
-
Incoherent scans are not published. Every scan is checked against the last published one before it can overwrite it (
packages/indexer/src/invariants.ts, run byscripts/verify-scan.tsas a workflow step ahead of the publish). One on-chain account attributed to two anchors, a row belonging to no anchor, or payment counts moving implausibly between scans all block publication rather than ship. Rule 5 is why: a reader can see stale data, but cannot see a misattributed figure, so withholding beats publishing.This exists because it was needed. The site credited Circle's shared USDC issuer account to a named anchor — MoneyGram's
stellar.tomlcites that issuer correctly under SEP-1, and the discovery code read every cited issuer as the citing domain's own — so global stablecoin issuance traffic was published as one business's settlement record, and nothing objected. Discovery now confirms a cited issuer's ownhome_domainbefore attributing it, and these invariants are the second line for whatever the next version of that mistake looks like.
Issues are scoped and labelled by complexity. Start with good first issue; larger tickets are tagged help wanted.
See CONTRIBUTING.md, DEVELOPMENT.md, and docs/backlog.md for the full backlog. All contributors are expected to follow the Code of Conduct.
npm run contracts:test # oracle: 25 Rust testsThanks to everyone who has shipped code, docs, or infrastructure for Landfall.
| Ibochi Vincent (@ibochivincent-lang) | Lead — indexer, contract, project owner |
| Your name here | Open a PR → |
MIT — see LICENSE.