engine library

Advanced and testing surface for Passnote.

The supported entry point is Passnote.builder from package:passnote/passnote.dart. Use this library only to build a custom adapter, wire everything by hand with passnoteLowLevel, or run the port conformance suites.

Everything here is covered by semver, but may change within a minor version with a CHANGELOG note. Application code should not need it.

Classes

AntiEntropy
The periodic state exchange that heals a dropped frame without a manual forceSync.
Cipher
An authenticated symmetric cipher.
CrdtRecovery
What CrdtTable.recoveries reports when CrdtTable.init rebuilds an unreadable local store.
CrdtTable
CRDT record store: the persistence and merge layer beneath Collection.
CrdtType
The conflict-resolution rule for a single field of a document.
DeviceInfo
A device in a database's roster, as reported by Database.devices().
DevicePublicKey
A device's long-lived public identity: the key-exchange and signing public keys that peers use to seal keys to it and to verify what it signs.
DeviceRecord
A paired device: its public identity plus human-facing metadata.
DeviceRosterEntry
One row of the device roster. Every row is a DeviceRecord, a WrappedGroupKey, or a KeyRotation.
DiscoveryRestored
Peer discovery works again after a DiscoveryUnavailable.
DiscoveryUnavailable
Emitted (at most once per Transport.start) when the transport determines its peer-discovery mechanism is unavailable on this platform — for example, the OS refused the multicast sockets mDNS needs because a permission or entitlement is missing.
Frame
A tagged binary payload routed by room.
FrameWindow
A per-peer send window: frames go out strictly in order, and at most capacity may be queued or in flight at once.
Identity
This device's cryptographic identity.
InboundFrame
A Frame received from from.
InMemoryBus
Routes Frames between InMemoryTransport nodes registered on this bus.
InMemoryTransport
A Transport implementation that routes frames through an InMemoryBus.
KeyRotation
A record that the group key was rotated to keyEpoch, excluding revokedDeviceId (empty for the initial founding at epoch 0).
KeyStore
Secure storage for per-database encryption keys.
LwwRegister
Last-write-wins register: the field with the higher Hybrid Logical Clock wins a merge and the other value is discarded.
MapCrdtTable
In-memory CrdtTable backed by the crdt package's MapCrdt.
MergeStrategy
Controls the granularity at which a document is split into independently timestamped CRDT records, and therefore how concurrent edits to the same document merge.
OrSet
Observed-remove set: concurrent adds and removes of different elements both survive a merge, and an add wins over a concurrent remove that did not observe it.
PairingBundle
What a sponsor hands a newly paired device: the key for the reserved roster collection, and the sponsor's roster trust pins. The database room tag derives from the key, and the device's own wrapped group key arrives by normal sync once it opens the database.
PairingCode
A one-time code that authorises a device join.
Pake
A password-authenticated key exchange, used to authenticate device pairing.
PakeResult
The output of a completed Pake run.
PakeSession
One party's state within a single Pake run. Not reusable.
Passnote
The app-level handle for Passnote.
PassnoteEvent
An observable event from a Passnote instance. Listen via Passnote.events.
PeerAppeared
A peer became reachable on the transport.
PeerConnected
Emitted when a new peer connects.
PeerDisappeared
A peer stopped being reachable.
PeerEvent
Base type for transport events: peer lifecycle and discovery state.
PeerLost
Emitted when a peer disconnects or becomes unreachable.
PnCounter
Positive/negative counter: the value is the sum of every peer's signed deltas, so concurrent increments on different devices all count.
QueryCursor
A position in a query's total order — the sort key of the last row of a page. Opaque to callers: obtain one from a returned page and feed it back to the same query to fetch the next page.
QueryPredicate
One compiled where clause of a collection query: the field path it tests, the op, the value to compare against, and the type the collection's merge strategy assigns to that path (which selects how the engine reads the stored field — a plain value, a counter total, or set membership).
QueryRow
One row of a query result at the engine level: a matching document id and its resolved order-by value (for building the next QueryCursor).
QuerySpec
A compiled collection query, ready for a CrdtTable to execute: the conjunction of predicates, an optional order, and a keyset page window.
RangeDigest
The summary of one HLC range of a table, as CrdtTable.rangeDigest returns it: the input to range-based set reconciliation.
RangeDigestBuilder
Streams records into a RangeDigest: an engine calls add once per record in the range (any order) and takes build.
RangeProbe
One range probe: "here is what I hold in (from, to] — do you match?"
RangeRequest
A half-open HLC range whose records the sender wants shipped to it.
RatchetEphemeral
One side's per-connection X25519 keypair. Lives in memory only; destroy it when the session ends.
RatchetSession
A forward-secret symmetric ratchet for a peer-to-peer transport session.
ReconcilePlan
What one side does in response to a reconcile message: probe back the still-unresolved subranges, ship its own records for the leaf ranges, and ask for the peer's records there.
Reconciler
The range-reconciliation state machine, pure over an injected digest function so it unit-tests without an engine.
SnapshotCapable
A CrdtTable that keeps periodic on-disk snapshots as a peerless recovery fallback.
SqliteCrdtTable
A CrdtTable backed by SQLite (package:sqlite3).
StoreRecovered
A collection's local store was found unreadable on open and rebuilt.
Transport
Discovers same-app nodes and moves opaque frames between them.
TypedCrdtTable
The layer that gives OrSet and PnCounter fields their merge semantics, wrapping any CrdtTable.
WrappedGroupKey
The group key, sealed to one device at one key epoch.
WrappedKey
A symmetric key encrypted ("sealed") to one device's DevicePublicKey.

Enums

CrdtRecoverySource
How a CrdtTable rebuilt its local store after finding it unreadable.
DeviceState
Where a device sits relative to its database's group key after Passnote.openDatabase.
QueryOp
How a QueryPredicate compares a field against its value.

Constants

kDeviceCollection → const String
The reserved collection that holds a database's device roster and the group key sealed to each device.
reconCapability → const String
The reconciliation capability advertised in the handshake. A peer that negotiated it runs anti-entropy as a range-fingerprint exchange; anyone else gets the full hello/state exchange.
supportedWireVersions → const List<int>
The wire versions this build can speak; negotiate picks the highest one both sides share.

Functions

crdtTypeFromTag(String? tag) → CrdtType
Resolves a persisted CrdtType.tag back to a CrdtType.
deriveRatchetRoot({required List<int> groupKey, required List<int> sharedSecret, required List<int> ephemeralA, required List<int> ephemeralB, required String nodeA, required String nodeB}) → List<int>
Derives the shared ratchet root for one peer pair.
negotiate(List<int> local, List<int> remote) → int?
The highest wire version present in both local and remote, or null when the sets share none (the peers cannot talk).
newRatchetNonce() → List<int>
A cryptographically random 16-byte value.
passnoteLowLevel({required PassnoteConfig config, required KeyStore keyStore, required Transport transport, required Future<List<int>> deriveKey(String passphrase, String salt), required String roomTag(List<int> key), required Cipher cipher(List<int> key), required List<String> mnemonicGenerator(int words), required bool validateMnemonic(String), required FutureOr<CrdtTable> engine(String databaseId, String collection, List<int> key), Identity? identity, Pake? pake, Future<Identity> recoveryIdentity(String phrase, String salt)?, List<int> wireVersions = supportedWireVersions, List<String> wireCapabilities = const [reconCapability]}) → Future<Passnote>
Constructs and wires a Passnote instance with every dependency explicit.

Typedefs

AntiEntropyTimerFactory = Timer Function(Duration interval, void tick())
Builds the periodic timer AntiEntropy runs on. Injectable so tests can drive ticks by hand; defaults to Timer.periodic.
FieldSpec = ({String path, CrdtType type, Object? value})
One field of a document, ready to be written as its own CRDT record: a stable path, the current value, and the CrdtType that governs how concurrent edits to it merge.
FieldValue = ({String path, Object? value})
One live field record read back from storage: its path and current value. The CrdtType is not needed to rebuild the document (the merge has already happened in the engine), so it is omitted here.
NodeId = String
A unique, stable identifier for this app instance within the transport.
PeerId = String
Identifies a remote peer.

Exceptions / Errors

CipherAuthError
Thrown when decryption fails due to an incorrect key or tampered ciphertext.
PairingRejected
Raised when the sponsor rejects a join: wrong code, too many tries, or the code was already used.
PairingTimeout
Raised when a join does not complete within the allowed time.
RosterPinsCorruptException
Thrown by Passnote.openDatabase and Passnote.reopenDatabase when the device roster's local trust pins (the founder, the device keys and the revocations this device has validated) are stored but unreadable.
SqlCipherUnavailableException
Thrown when an encryption key is supplied but the linked native SQLite library is not a SQLCipher build, so the key would be silently ignored and data would be written to disk in plaintext.
WrongPassphraseException
Thrown when a supplied passphrase (or the key derived from it) does not decrypt a database's existing local data.