MeteraDocs

Platform

Known limits

Being explicit about limits is consistent with the whole thesis. Every product has them; few write them down.

Seventeen servable types today. token.price (5 providers, anchored) and spot.price (4 providers, consensus) are the two price types that reach past a single source, through independent providers agreeing on the same asset. perp.price, funding.rate and futures.open_interest carry three, three and two venues respectively, and stay capped at single_source regardless, for the reason in the next paragraph. Eight direct on-chain reads — solana.sol_balance, solana.token_account_owner, solana.tx_simulation, solana.pool_state, solana.swap_quote, solana.resolve_address, solana.can_sign and solana.kamino_yield — reach consensus a different way: two independently operated nodes are read in parallel and checked against each other at the same slot, on every call, rather than through the provider-agreement path above. solana.token_risk, solana.stablecoin_risk, defi.protocol_tvl and tiktok.profile are single_source today, each served by one provider. Everything else is roadmap.

solana.swap_quote covers Raydium CPMM and Meteora DAMM V2 pools; any other AMM is refused cleanly (pool_unrecognized) rather than guessed at. On a Meteora concentrated-liquidity pool, priceImpactBps can read oddly high on a real trade — amountOut stays the correct, real simulated result regardless; the constant- product formula the impact number is modelled on does not match how price moves inside a concentrated range. Treat amountOut as authoritative there and priceImpactBps as noisier, not wrong.

solana.swap_quote also composes into evaluate_gate, a swap gate with its own scope and limits (MEV between check and execution, what happens when the quote cannot deliver) — see the Gates page rather than duplicating that here.

solana.token_risk composes Webacy's reputation score with three independent on-chain checks in the same call — Token-2022 mint extensions, LP-burn status, and a lock/vesting scan — each carrying its own checked flag and reason rather than folded into one score. Token-2022 and the lock scan run on the mint alone; LP-burn only runs when the caller also supplies pool — a token can have more than one pool, so none is assumed, and lpBurn: { checked: false } means not checked, never not burned. The on-chain checks deliver independently of Webacy's own coverage: an address Webacy has no data for still gets real Token-2022 and lock-scan facts, with webacy.checked: false saying exactly what has no data. See the Gates page for how this interacts with evaluate_gate's risk check and the caveat semantics.

None of the three new checks are verdicts. A PermanentDelegate address on a Token-2022 mint is reported as exactly that — a fact about who can move any holder's tokens — never a claim about intent. A transferHook extension present with programId: null is initialized but not running; presence is not the same as active. LP-mint-authority-renounced and LP-burned are two separate facts, not one — a renounced authority (normal for every real Raydium CPMM pool, since the mint authority is always the program's own PDA) says nothing about whether supply was actually sent to a dead address. And a lock-scan holder this module could not identify is reported as unidentified, never as not locked — an unrecognized controller is exactly as likely to be a private wallet as an unsupported lock program, and the response says so rather than picking one.

solana.resolve_address answers "what IS this address" — one dual-RPC read classifies it as a mint, a token account, a CPMM or Meteora DAMM V2 pool, a wallet, an executable program, a funded_pda, an uninitialized address with nothing created there yet, or an unrecognized account this resolver has no decoder for. The last four exist because the obvious rule — "System-Program-owned with no data means wallet" — is wrong: a real PDA (off-curve, structurally unable to ever hold a private key) can carry exactly that same shape once it has received lamports. wallet requires being on-curve; funded_pda is the honest label for the off-curve case, found by testing a real PDA rather than assumed.

type: "solana.resolve_address"
params: { "address": string }   // requiredParams: ["address"]

// response fields (every key always present, null when it does not apply):
{ address, onCurve, exists, type, tokenStandard, protocol, ownerProgramId,
  executable, dataLen, slot, headSlot, slotsBehind, agreement, readAt, scope }

solana.can_sign checks two separate, real facts about whether signer could validly act for target (a mint or a token account — anything else is refused by name, the same discipline as a mismatched type anywhere else in this catalog: a wallet target says so and explains a wallet has no separate authority field, not a generic error) — onCurve (structural, provable from the pubkey's own bytes: an off-curve address can never produce a signature, full stop) and isRecordedAuthority (signer matches target's current mint_authority, freeze_authority, or token-account owner field, read fresh). Neither proves custody. "signer is the recorded authority" is a fact about a field, not a fact about who holds signer's private key — nothing an RPC node can return proves that, on-curve or not. The same limit applies one level up: if the recorded authority is a multisig program's PDA, this confirms signer is a listed member, never that the other members would approve this specific action, and if it is a PDA some other program treats as an authority, this does not simulate whether that program's own instruction logic would allow a specific call — only solana.tx_simulation, running a real instruction against real current state, proves that. can_sign is the static, structural check an agent runs before it has a transaction to simulate; it never promises what simulation would find. Found live building this: the payer address used in every solana.swap_quote/evaluate_gate example on this site is itself off-curve — it only ever worked because simulation needs no real signature at all.

type: "solana.can_sign"
params: { "signer": string, "target": string }   // requiredParams: ["signer", "target"]

// response fields (every key always present, null when it does not apply):
{ signer, target, onCurve, targetType, recordedAuthorities, isRecordedAuthority,
  matchedRoles, slot, headSlot, slotsBehind, agreement, readAt, scope }

solana.kamino_yield decomposes a Kamino Reserve's yield into what is actually verifiable and refuses the rest, rather than reporting one blended “APY” the way a site's card does. exchangeRate is the reserve's real collateral-to-liquidity ratio, read live and decoded field-by-field from the account (not a stored percentage) — confirmed against Kamino's own public API for the main-market USDC reserve to within ~0.005%, the gap fully explained by the two reads landing on different slots.

realized is a real measured growth of that rate over a real window Metera has actually observed — the first time any reserve is asked about, there is nothing to compare against yet, and this refuses honestly (realizedRefusedReason) rather than reporting a zero or a guess. Once a prior reading exists, windowSeconds always travels with the number: an annualized figure computed from six real hours is a different kind of claim than one from thirty real days, even though the formula is the same, and this never lets the two look alike.

emitted is the reward schedule's CURRENT active rate, per configured token — never annualized by Metera. Kamino's own reward schedule is stepwise, with rate changes already written on chain for specific future dates; projecting today's rate forward as a yearly figure would be actively wrong the moment one of those dates arrives, not merely optimistic. An empty array is a real answer (no farm configured, or no active emission right now), not a failure to look.

stale is read directly from Kamino's own on-chain flag on the reserve, not inferred from slot distance — Kamino's interest accrual is lazy (it updates on the next transaction that touches the reserve, not on a timer), so the account itself says whether its last update might be behind the true accrued value.

"scope": {
  "covers": [
    "the collateral<->liquidity exchange rate, read live from the Reserve account",
    "realized growth of that rate over the real window Metera has actually observed it",
    "the reward schedule's current active emission rate per configured token, as written on chain right now",
    "Kamino's own on-chain staleness flag for the reserve's last interest accrual"
  ],
  "doesNotCover": [
    "impermanent loss or any price-path risk — not modeled, would require external price history",
    "leveraged or looped-position yield — not researched, nothing here computes it",
    "a forward projection of the reward rate as if it will persist — the schedule can and does change at dates already written on chain",
    "borrow-side interest rate — a separate, unverified fixed-point format this module does not decode yet"
  ]
}

More venues is not more observers. Three exchanges reporting their own funding rates are three quantities, not three observations of one quantity, and no number of venues will lift that cap: it is a property of what the number is. Only where the venues are pricing the same asset, as in spot.price, does agreement between them mean anything by this route.

Independence between providers is never measured, at any number of sources. Pairwise dispersion cannot separate the shared component from the private ones: at three sources the system of equations is exactly determined and has no residual to test, and the covariances stay unidentified however many sources are added. So independence is reported as assumed, not_refuted or refuted, never as a measurement. A test that could have refuted it and did not is the honest ceiling. The seven on-chain reads sidestep this problem rather than solve it: two nodes are asked the same deterministic question at the same slot, so there is nothing to statistically identify, only to check.

What verification cannot catch. Two colluding sources that read the same upstream, in a type without an anchor, are indistinguishable from the truth, which is why that datum is labelled single_source rather than consensus. Even an anchor that agrees is not automatically an independent check: when the feed aggregates centralised venues and the answering source is one of them, the trace says so instead of claiming independence.

Roadmap, not present. The pieces marked roadmap here and on the token page do not exist yet and are never described in the present tense.