- 1. Deploy reputation contract — mainnet. Run the existing
scripts/deploy-oracle-mainnet.tsscript, record the contract ID in the repo, and wiresubmitToOracle(packages/publisher/src/batch.ts) for real: build the Soroban invoke tx, sign with the publisher key, submit. The publisher tick must publish real outcomes on-chain BEFORE entry. This is the categorical D3 move (6 → 8-9). Deliberately deferred — deployment stays testnet-only for now. Everything downstream of it (publisher tick, on-chain reads, leaderboard reconciliation) is wired and verified end-to-end against the existing testnet contract instead; only the mainnet deploy + contract-id swap is outstanding. - 2. App reads scores from chain. Reconcile/verify the leaderboard
against contract state and surface on-chain tx hashes in the UI. Closes
the oracle loop in both directions — no mock-adjacent gap.
Done against testnet. New
lib/oracle/read.tsis a read-only Soroban client (get_score_for_corridor,get_corridor_aggregate,list_anchors— puresimulateTransaction, no signing/funds needed; verified against the live deployed contract)./api/reputation/leaderboardno longer returns hardcodedSTUB_METRICS— it computes real scorecards fromoutcome_logand, when a corridor filter is given, attaches a live on-chain score per anchor for reconciliation.app/anchors/[id]/page.tsxwas actually surfacing the wrong tx hash (the off-chain settlement payment, not an oracle submission) — fixed to source the realoracle_tx_hashwritten by the publisher (see fix-order item 2 below). - 3. Publish
@stellarintel/mcp+@stellarintel/publisherto npm with a runnable example wired to the REAL contract ID; makeexamples/consumer-contractinvoke the deployed oracle. "Primitive others depend on" = only observed path to S. Both packages build +npm pack --dry-runclean;packages/mcpnow actually registers its two tools for real (see fix-order item 1) instead of shipping an empty server.examples/consumer-contracthas a runnableread-oracle.mjsverified live against the real testnet contract, plus a README covering both that and the full Rust deploy/invoke path. Did not run the actualnpm publish— needs the maintainer's npm login/2FA and is hard to fully reverse once published.
- 1. Wire real tools into
packages/mcp/src/server.tsfromlib/mcp/offramp.ts— with LIVE rates, not routing-table constants.intel.offramp.quote/intel.offramp.prepareare now registered for real (was an empty tool list), sourcinglib/mcp/offramp.tsdirectly via atsc-alias-rewritten build so the publisheddist/stays self-contained outside this monorepo.getQuoteno longer computesnetReceivedoff the staticANCHOR_ROUTINGrate — it callsfetchCorridorRatesfor the routed anchor's actual current price (SEP-38 firm quote, falling back to SEP-24/SEP-6 fee-adjusted live FX) and throwsRATE_UNAVAILABLEwhen that anchor can't currently be quoted, rather than returning a stale number. Needed two small Node16 compat fixes along the way inlib/stellar/sep1.tsandlib/stellar/anchors.ts, and fixed thebinfield noted in item 4 below. - 2. Wire
submitToOracleto the deployed contract (blocks on contract deploy — item 1 of the uplift plan). Addpg+@stellar/stellar-sdktopackages/publisherdependencies. Done against the testnet deployment (CCZ54NTEOVL2DKWCGJA5XHTHOGRDS7JHFKYWEC6QH2IMZLYNM3FBFKDG); mainnet wiring still pending item 1 of the uplift plan. Found and fixed a real bug on top of this:fetchPendingOutcomes/markPublishedinbatch.tsqueried a table calledreputation_outcomes, which the app never creates — its real table isoutcome_log.packages/publisher's own e2e test seeds through the app's real store, so this would have failed the moment it ran against an actual database. Renamed tooutcome_logand added thepublished_at/oracle_tx_hashcolumns it needs (migrationlib/reputation/migrations/005_oracle_publish.sql). Also madepackages/publisher'sindex.tssafe toimport(it previously ran its CLImain(), includingprocess.exit(1), unconditionally at module load) and wired/api/publisher/tick— previously a hardcoded no-op stub — to actually callrunBatchagainst the testnet oracle. - 3. Fix both package tsconfigs (
module: "Node16", excludetestsfrom build), verifynpm run buildemitsdist/, and checknpm pack --dry-runshows the expected files. Both packages now build and pack clean. Along the way: fixed a pre-existing@types/nodeauto-discovery gap (TS 6 stopped finding it in this workspace layout — added explicit"types": ["node"]), and worked around@stellar/stellar-sdkshipping ESM-only types againstpublisher's CommonJS build via a dynamicimport()inbatch.ts. Also added a localvitest.config.mtsforpackages/publisher(it was silently inheriting the root app's config, pointed at a setup file that doesn't exist there) and gitignoredpackages/*/dist. - 4. Add README + LICENSE +
repository+"publishConfig": {"access": "public"}to each package. Also added"license": "MIT"to eachpackage.json(implied by shipping a LICENSE file — avoids the npm-publish "no license field" warning) and refresheddocs/ORACLE_SPEC.mdto point at the real testnet contract instead of describing it generically. Noted but did not fix:packages/mcp/package.json'sbinkey is the full scoped name ("@stellarintel/mcp"), which contains/— likely invalid as an npm bin command name; worth checking before publish. Fixed (see fix-order item 1):binis now the baredist/...path string, letting npm derive the unscoped command name.
- Monthly recheck complete for the latest survey snapshot.
Latest documented snapshot: 92 directory-tagged domains -> 32 reachable
stellar.toml files -> 9 transfer-capable / 23 issuer-only; 60 unreachable or
unconfirmed.
The 23 issuer-only domains (advertise an asset/issuer but no SEP-6/SEP-24
transfer rails, so they back no corridor) are enumerated with reasons in
docs/anchors/exclusions.md.
Source: scripts/anchor-survey.snapshot.json, generated
2026-06-25T23:08:26.806Z from
https://api.stellar.expert/explorer/public/directory?tag[]=anchor&limit=200.
Refresh cadence: re-run node scripts/anchor-survey.mjs --json monthly, update
these counts, and keep the recheck checkbox aligned with the current snapshot.