import { type Cell, type OpenedContract } from '@ton/core'; import { type PriceLeaf, type Phoebe } from './contracts/Phoebe'; /** * One operator's public HTTP read endpoint. Ships in * `PHOEBE_MAINNET.operators` per network; dapps can also bring their * own list. The `address` is the operator's wallet (UQ-form) — used to * verify that the snapshot served claims to be from the right operator. */ export interface OperatorEndpoint { /** Operator wallet, UQ-form non-bounceable. Matches * `snapshot.operatorAddress` in the served JSON. */ address: string; /** Base URL where the operator serves `/phoebe/v1/snapshot`. No * trailing slash. E.g. `http://18.153.225.178:9092`. */ url: string; } /** * A verified, ready-to-submit price quote. The `leaf` + `proof` pair * goes into the consumer contract's PriceRequest message; phoebe * verifies the proof against `lastRoot` and dispatches the verified * leaf back to the consumer's callback. */ export interface VerifiedPriceQuote { /** The feed this quote is for. */ feedId: number; /** Signed integer mantissa. `actual_price = mantissa × 10^expo`. */ mantissa: bigint; /** Signed exponent. */ expo: number; /** Confidence interval in basis points. */ confBps: number; /** Unix seconds — when the operator's aggregator sampled this leaf. */ pubTime: number; /** Unix seconds — when the snapshot containing this leaf was pushed * on-chain. */ snapshotTime: number; /** Merkle root we verified against — same as `phoebe.lastRoot`. */ root: bigint; /** Merkle proof for `leaf` — pass to consumer contract alongside * `leaf`. */ proof: Cell; /** The leaf itself — pass to consumer contract. */ leaf: PriceLeaf; /** UQ-form wallet of the operator that served this snapshot. */ sourceOperator: string; /** Seconds since the snapshot was pushed. Use this to enforce a * client-side staleness bound if `opts.maxAgeSec` wasn't passed. */ ageSec: number; } export interface FetchVerifiedPriceOptions { /** Maximum acceptable age of the snapshot, in seconds. Default * unlimited (a consumer contract should enforce its own * staleness bound on `pubTime` anyway). */ maxAgeSec?: number; /** Per-operator HTTP timeout in milliseconds. Default 5000. */ timeoutMs?: number; /** Override clock for tests. */ nowSec?: () => number; /** Inject `fetch` for tests. */ fetchImpl?: typeof fetch; } /** * Fetch a verified price quote for `feedId` from any operator in * `operators`. Throws if no operator returns a snapshot whose * reconstructed merkle root matches `phoebe.lastRoot` on-chain. * * Trust model: NO trust in the operator. The reconstructed merkle root * is compared against `phoebe.lastRoot` on-chain; any operator that * doesn't match — stale, buggy, or unreachable — is skipped. A * *malicious* operator can't forge a matching root because they don't * hold the threshold BLS secret that signed it on-chain. * * @param phoebe Opened Phoebe contract (`tonClient.open(Phoebe.createFromAddress(addr))`). * @param feedId Which feed to extract (e.g. `0` for the canonical TON/USD slot). * @param operators List of operator endpoints to try. The helper queries them in parallel * and returns the first verifying response. * @returns A quote with the leaf + merkle proof, ready to submit to a consumer contract. * * @throws if `operators` is empty. * @throws if `phoebe.lastRoot === 0n` (no snapshot ever published). * @throws if no operator returns a snapshot whose reconstructed root matches on-chain. * @throws if the matching snapshot has no leaf for the requested `feedId`. * @throws if `opts.maxAgeSec` is set and the snapshot is older than that bound. * * @example * import { TonClient } from '@ton/ton'; * import { Phoebe, assertDeployment, fetchVerifiedPrice } from '@titon-network/phoebe-sdk'; * const client = new TonClient({ endpoint: 'https://toncenter.com/api/v2/jsonRPC' }); * const dep = assertDeployment('mainnet'); * const phoebe = client.open(Phoebe.createFromAddress(dep.phoebe)); * const quote = await fetchVerifiedPrice(phoebe, 0, dep.operators ?? []); * // → submit quote.leaf + quote.proof to your consumer contract */ export declare function fetchVerifiedPrice(phoebe: OpenedContract, feedId: number, operators: readonly OperatorEndpoint[], opts?: FetchVerifiedPriceOptions): Promise;