import type { Limitation } from './capabilities.js'; import type { PublicOperationOptions } from './operations.js'; import type { BoundedAsyncStream } from './streams.js'; export type SecurityBondState = 'bonded' | 'not-bonded' | 'bonding' | 'unknown' | 'unsupported'; export type SecurityEncryptionState = 'encrypted' | 'not-encrypted' | 'unknown' | 'unsupported'; export type SecurityAuthenticationState = 'authenticated' | 'unauthenticated' | 'unknown' | 'unsupported'; export type SecureConnectionsState = 'yes' | 'no' | 'unknown' | 'unsupported'; export interface PeerSecurityState { readonly bond: SecurityBondState; readonly encryption: SecurityEncryptionState; readonly authentication: SecurityAuthenticationState; readonly secureConnections: SecureConnectionsState; readonly pairingPossible: boolean | null; readonly measuredAtMonotonicMs: number; readonly limitations: readonly Limitation[]; } export interface PeerSecurityEvent { readonly kind: 'state'; readonly peerId: string; readonly sequence: number; readonly state: PeerSecurityState; } export type SecurityPairingChallenge = { readonly kind: 'confirm'; readonly peerId: string; readonly challengeId: string; readonly deadlineMonotonicMs: number; } | { readonly kind: 'confirm-passkey'; readonly peerId: string; readonly challengeId: string; readonly passkey: number; readonly deadlineMonotonicMs: number; } | { readonly kind: 'display-passkey'; readonly peerId: string; readonly challengeId: string; readonly passkey: number; readonly deadlineMonotonicMs: number; } | { readonly kind: 'provide-pin'; readonly peerId: string; readonly challengeId: string; readonly deadlineMonotonicMs: number; } | { readonly kind: 'provide-passkey'; readonly peerId: string; readonly challengeId: string; readonly deadlineMonotonicMs: number; }; export type SecurityPairingResponse = { readonly kind: 'confirm'; readonly confirmed: boolean; } | { readonly kind: 'confirm-passkey'; readonly confirmed: boolean; } | { readonly kind: 'display-passkey'; readonly acknowledged: boolean; } | { readonly kind: 'provide-pin'; readonly pin: string; } | { readonly kind: 'provide-passkey'; readonly passkey: string; }; export interface SecurityPairingAgent { onChallenge(challenge: SecurityPairingChallenge): Promise; } export type SecurityPairingCeremony = 'system' | { readonly kind: 'agent'; readonly agent: SecurityPairingAgent; }; export interface SecurityPairOptions extends PublicOperationOptions { readonly transport: 'le' | 'auto'; readonly protection: 'system-default' | 'encrypted' | 'authenticated'; readonly ceremony: SecurityPairingCeremony; /** * Preferred LE pairing generation. 'prefer' (default) leaves the choice to * the platform; 'require' insists on Secure Connections; 'disallow' requests * LE Legacy pairing for peers that reject Secure Connections. Backends that * cannot honour the request return capability.unsupported. */ readonly secureConnections?: 'require' | 'prefer' | 'disallow'; } export type SecurityPairResult = { readonly outcome: 'paired'; readonly state: PeerSecurityState; } | { readonly outcome: 'already-paired'; readonly state: PeerSecurityState; } | { readonly outcome: 'repaired'; readonly state: PeerSecurityState; } | { readonly outcome: 'rejected'; readonly reason: string | null; } | { readonly outcome: 'cancelled'; }; /** * What a cancellation actually achieved, not what it requested. * * A cancellation can lose the race, and it can also arrive at something that * was never going to bond. Each of those is a different fact and gets its own * word, mirroring `SecurityPairResult` so that a word means the same thing in * both types: * * - `'cancelled'` your cancellation stopped it * - `'not-pairing'` there was nothing to stop * - `'paired'` the bond completed before your cancellation arrived * - `'rejected'` the peer refused it; nobody cancelled anything * * `'paired'` is deliberately not `'already-paired'`, which in `SecurityPairResult` * means the peer was bonded BEFORE the call. A pairing that FAILS is not a * fourth outcome: `cancelPairing()` rejects with the same error the pairing * rejected with, because inventing a resolved outcome for a failure would be * the same substitution this type exists to prevent. */ export type SecurityCancelPairingResult = { readonly outcome: 'cancelled'; } | { readonly outcome: 'not-pairing'; } | { readonly outcome: 'paired'; } | { readonly outcome: 'rejected'; readonly reason: string | null; }; export type SecurityUnpairResult = { readonly outcome: 'unpaired' | 'already-unpaired' | 'unsupported'; }; /** * The cancellation outcome implied by the pairing's OWN result. * * Every backend answers `cancelPairing()` by asking the in-flight pairing what * happened to it, rather than forming a second, independent opinion: two * observations of one fact can disagree, and that disagreement is the defect - * `pair()` reporting `paired` while `cancelPairing()` reported `cancelled` for * the same operation. Reading the pairing's own answer makes them incapable of * disagreeing, and keeps the four backends saying one thing. */ export declare function cancelOutcomeForPairResult(result: SecurityPairResult): SecurityCancelPairingResult; export interface SecurityBackend { state(peerId: string, options: PublicOperationOptions): Promise; watch(peerId: string): BoundedAsyncStream; pair(peerId: string, options: SecurityPairOptions): Promise; cancelPairing(peerId: string, options: PublicOperationOptions): Promise; unpair(peerId: string, options: PublicOperationOptions): Promise; close?(): void; } //# sourceMappingURL=security.d.ts.map