import { type Attester, type StrongRef, type Verdict } from './attestation.ts'; import { type Patience } from './ratelimit.ts'; import { type DidDocument, type Value } from './repo.ts'; /** The PLC directory (`BUNDLE_PLC_DIRECTORY` overrides it). */ export declare const DEFAULT_PLC_DIRECTORY = "https://plc.directory"; /** What every network call here accepts: where the cache is, and how to fetch. */ /** How the network is reached; a server that says to slow down is waited for, as `Patience` says. */ export interface NetworkOptions extends Patience { cache?: string | undefined; fetch?: typeof globalThis.fetch | undefined; /** How TXT records are looked up, for handle resolution (default: `node:dns`). */ resolveTxt?: ((name: string) => Promise) | undefined; /** The PLC directory to resolve `did:plc:` against. */ plc?: string | undefined; now?: (() => Date) | undefined; /** * DID documents fetched so far, by DID, for work that asks about the same * people many times over — `trust`, `validate` — to ask the network once. */ documents?: Map> | undefined; } /** Fetch and check a DID document, and cache it. */ export declare function resolveDid(did: string, options?: NetworkOptions): Promise; /** * Fetch and check a DID document, without caching it. The attestation cache * holds the documents of attesters, and `bundle trust` refreshes everyone it * holds — so a lookup made for any other reason stays out of it. */ export declare function fetchDidDocument(did: string, options?: NetworkOptions): Promise; /** * Resolve a handle to its DID — DNS (`_atproto.` TXT `did=…`) first, * then `https:///.well-known/atproto-did` — and check that the DID * document claims the handle back. A handle that only points one way is * someone pointing at an account that does not agree. */ export declare function resolveHandle(handle: string, options?: NetworkOptions): Promise<{ did: string; doc: DidDocument; }>; /** Turn a `[kind@]` into an attester with a DID. */ export declare function resolveAttester(spec: string, options?: NetworkOptions): Promise; /** * Fetch `did`'s attestation of `hex` into the cache, or remove it from the cache * when the proof shows it is gone. Returns which it was. */ export declare function fetchAttestation(did: string, hashAlg: string, hex: string, options?: NetworkOptions): Promise<'present' | 'absent'>; /** * Fetch `did`'s attestations of many hashes into the cache — or out of it, for * those the proofs show are gone — in a handful of requests however many * there are: see `fetchProofs()`. What `validate` does for each attester. */ export declare function fetchAttestations(did: string, wanted: { hashAlg: string | null; hex: string; }[], options?: NetworkOptions): Promise>; /** * Proofs of many attestation records in `doc`'s repository — or of their * absence — in a handful of requests however many there are. A record's * proof is the signed commit, the tree nodes on the path from its root to the * record's key, and the record: `com.atproto.sync.getRecord` sends one record's * at a time. Here the commit is fetched once, and the tree is walked toward * every key at the same time, a level to a request (`com.atproto.sync. * getBlocks`), then the records — about as many requests as the tree is deep. * Each proof is put together from those blocks, and checked by the caller * exactly as one fetched on its own would be. Fewer keys than make that worth * it, or a repository that moves on in the middle — its old nodes gone — are * fetched a record at a time instead. */ export declare function fetchProofs(doc: DidDocument, rkeys: string[], options?: NetworkOptions, head?: string | undefined): Promise>; /** * Bring the cache up to date with everything `did` has attested: new * attestations are fetched, withdrawn ones removed, and the rest re-confirmed. * * The listing comes from the attester's PDS and is not itself signed, which is * sound for what it is used for. A listing can only make this cache *drop* a * proof — and the PDS can withdraw an attestation anyway — or *keep* one whose * record it still claims, which it could equally sign a fresh commit for. */ export declare function refreshAttester(did: string, options?: NetworkOptions): Promise<{ present: number; fetched: number; removed: number; }>; /** * Fetch, for each attester, its attestation of one hash. Failures are reported * rather than thrown: the cache keeps what it had, and the policy check decides * whether that is still good enough. */ export declare function refreshFor(attesters: Attester[], hashAlg: string, hex: string, options?: NetworkOptions): Promise; /** * Who has attested `hashAlg:hex`, according to a backlink index — Constellation's * `blue.microcosm.links.getBacklinks`, which indexes every record field that * parses as a URI, `sha256:` included. * * The answer is a list of DIDs to ask, nothing more: an index can leave people * out or make them up, and every attestation it names is fetched from the * attester's own PDS and verified before it counts for anything. `limit` caps * how many are returned, so a hash that has attracted a crowd cannot turn one * install into thousands of requests. */ export declare function discover(hashAlg: string, hex: string, { index, limit, ...options }: NetworkOptions & { index: string; limit?: number | undefined; }): Promise; /** One record a backlink index says links to a subject. */ export interface Backlink { did: string; collection: string; rkey: string; } /** * Every record whose `source` field (`:`) links to * `subject`, according to a backlink index, a page of 100 at a time. A * generator, so a caller that has seen enough can stop asking. */ export declare function backlinks(subject: string, source: string, { index, ...options }: NetworkOptions & { index: string; }): AsyncGenerator; /** * How many accounts have a record in `collection` whose field at `path` * (`.subject`) links to `subject`, according to a backlink index: each account * counted once, however many records it has. A count the index keeps, not one * verified here. */ export declare function backlinkDistinctCount(subject: string, collection: string, path: string, { index, ...options }: NetworkOptions & { index: string; }): Promise; /** A logged-in session on someone's PDS. */ /** * A logged-in session on someone's PDS: who, where, and how to make an * authenticated request there. OAuth (oauth.ts) and app passwords (`login` * below) both produce one, and writing records does not care which. */ export interface Session { did: string; pds: string; /** How it was signed in, for saying so. */ how: string; request(url: string, init: RequestInit): Promise; /** Done with it: revoke what can be revoked. */ end?: (() => Promise) | undefined; } /** * Log in with an app password — for CI, where nobody can sign in through a * browser. Everywhere else, OAuth (`oauthLogin` in oauth.ts) is the way: * atproto is moving away from passwords, and a PDS need not accept them. * `identifier` is a handle or a DID; the PDS is found from the DID document * rather than assumed, so this works for any account on any host. * * A session is kept for a few minutes (see `SessionCache`), so that a script * running one command after another signs in once rather than each time: * `createSession` is among the most tightly rate-limited calls a PDS has. */ export declare function login(identifier: string, password: string, options?: NetworkOptions & { sessions?: SessionCache | false | undefined; }): Promise; /** A session `login()` signed in, as it is kept. */ export interface KeptSession { did: string; pds: string; token: string; } /** * Where `login()` keeps a session between commands, and for how long. * * One file per account, in `sessions/` in the state directory, readable only * by its owner, and **encrypted with a key derived from the app password** — * so the file is worth nothing to anyone without that password, and anyone * with it could sign in anyway. Keeping it exposes nothing new; the short * lifetime is tidiness, not the protection. A changed or revoked password * stops it working by itself, since the token no longer decrypts. * * The lifetime is `BUNDLE_ATPROTO_SESSION_TTL` (default 5m; 0 turns keeping * off), and never past the token's own expiry. An OAuth session is never kept: * it is bound to a key that only ever exists in memory. */ export interface SessionCache { read(identifier: string, password: string): KeptSession | null; write(identifier: string, password: string, session: KeptSession): void; forget(identifier: string): void; } /** The default session cache, or false when the environment turns it off. */ export declare function sessionCache({ dir, ttl, now }?: { dir?: string; ttl?: number; now?: () => number; }): SessionCache | false; /** What an attestation says: of which file, and — when not simply vouching for it — what about it. */ export interface Attesting { hashAlg: string; hex: string; kind?: string | undefined; /** 'bad' to warn against the file; good is the default and is not written. */ verdict?: Verdict | undefined; /** Context, in the attester's own words. */ note?: string | undefined; /** A post that gives the context: see `resolvePost()` and `createPost()`. */ post?: StrongRef | undefined; } /** * Publish an attestation of `hashAlg:hex`. The PDS saying it is written is * taken as it being written: nothing is read back, since every request counts * against the account's rate limits, and `bundle trust` or an install fetches * it — verified — whenever it is needed. */ export declare function attest(session: Session, attesting: Attesting, options?: NetworkOptions): Promise<{ uri: string; }>; /** Publish several attestations, in as few requests as the PDS allows (see `putAll()`). */ export declare function attestAll(session: Session, attestations: Attesting[], options?: NetworkOptions): Promise<{ uri: string; }[]>; /** The collection a post of the Atmosphere's microblog is a record in. */ export declare const POST_COLLECTION = "app.bsky.feed.post"; /** A post, as `resolvePost()` found it: pinned to this version, with its text when it has some. */ export interface FoundPost extends StrongRef { text?: string | undefined; } /** * The post `ref` names, fetched from its author's PDS and verified, pinned to * the version there now. `ref` is an `at://` address — of a post, or of any * record — or a post's web address, `https://bsky.app/profile//post/`. A handle is resolved, and the address returned names the * DID, which does not change hands. */ export declare function resolvePost(ref: string, options?: NetworkOptions): Promise; /** * Post `text` from the session's account, as a post of the Atmosphere's * microblog — with `facets` marking links in it, when there are any — and * return where it is, pinned. Its key is left to the PDS, which * gives a post the time-ordered key it should have. */ export declare function createPost(session: Session, { text, facets }: { text: string; facets?: Record[] | undefined; }, options?: NetworkOptions): Promise; /** Delete a post `createPost()` made, by its address. */ export declare function deletePost(session: Session, uri: string, options?: NetworkOptions): Promise; /** Withdraw attestations, in as few requests as it takes, and drop them from the cache. */ export declare function revokeAll(session: Session, hexes: string[], options?: NetworkOptions): Promise; /** One write in an `applyWrites` batch. */ export type Write = { action: 'create' | 'update'; collection: string; rkey: string; record: Record; } | { action: 'delete'; collection: string; rkey: string; }; /** The most writes one `applyWrites` takes. */ export declare const MAX_BATCH = 200; /** * Apply `writes` to the session's own repository: one request for up to * `MAX_BATCH` of them, each request one commit — all of it written, or none. * A create of a record that is there, or an update or delete of one that is * not, refuses the whole request. */ export declare function applyWrites(session: Session, writes: Write[], options?: NetworkOptions): Promise; /** * The records in one collection of the session's own repository, by key: as * the PDS lists them, a hundred to a request. Unverified — it is the * account's own repository, asked only which records are there. */ export declare function listOwn(session: Session, collection: string, options?: NetworkOptions): Promise>; /** * Write records at keys of their own, replacing what is there, in as few * requests as there can be. One record is one putRecord. Several are created * in one batch — the usual case, nothing there yet — and only if the PDS * refuses that, because some are there already, is the collection listed and * the batch sent again, updating those. `existing`, when the caller has listed * the collection already, skips straight to the right batch. Being told to * slow down is not a refusal: it is waited out, or fails, as it is. */ export declare function putAll(session: Session, collection: string, records: { rkey: string; record: Record; }[], options?: NetworkOptions & { existing?: ReadonlySet | ReadonlyMap | undefined; }): Promise; /** Delete records — those that are there — in as few requests as there can be, as `putAll()` writes them. */ export declare function deleteAll(session: Session, collection: string, rkeys: string[], options?: NetworkOptions & { existing?: ReadonlySet | ReadonlyMap | undefined; }): Promise; /** Withdraw an attestation, and drop it from the cache. */ /** * Any record, verified: resolve `did`, fetch the record's proof from its PDS, * and check it against the DID's key. Null when the proof shows there is none. */ export declare function getRecord(did: string, collection: string, rkey: string, options?: NetworkOptions): Promise<{ cid: string; value: Value; } | null>; /** What `putRecord()` throws when `swapRecord` no longer holds: the record changed meanwhile. */ export declare const SWAPPED = "ERR_BUNDLE_RECORD_SWAPPED"; /** * Write a record into the session's own repository, at a key of the caller's * choosing. With `swapRecord`, only over the record as it was read: its CID, * or null for none there yet. Anything else there by then — a write from * another machine — refuses it, with the code `SWAPPED`, and nothing is lost. */ export declare function putRecord(session: Session, collection: string, rkey: string, record: Record, { swapRecord, ...options }?: NetworkOptions & { swapRecord?: string | null | undefined; }): Promise<{ uri: string; cid: string; }>; /** Delete a record from the session's own repository. */ export declare function deleteRecord(session: Session, collection: string, rkey: string, options?: NetworkOptions): Promise; export declare function revoke(session: Session, hex: string, options?: NetworkOptions): Promise; /** The fetch every request here is made with: the one given, or the global one, waiting when told to. */ export declare function net(options: NetworkOptions): typeof globalThis.fetch; /** A query answered in JSON, from `pds` (or any XRPC host). */ export declare function xrpcJson(pds: string, method: string, params: Record, options: NetworkOptions): Promise; //# sourceMappingURL=atproto.d.ts.map