passnote library
Passnote: an end-to-end encrypted, local-first CRDT sync engine for Dart.
This is the frozen app-facing library, covered by semver from v1.0.0
(see VERSIONING.md): the builder entry, databases, collections and
queries, codecs and their annotations, merge strategies and CRDT types,
the device / pairing / recovery API, configuration, events, and the port
interfaces the builder's overrides accept.
Engine implementations, the conformance suites, protocol internals, and
the passnoteLowLevel wiring function live on the advanced
package:passnote/engine.dart library. Flutter bindings and
batteries-included setup live in package:passnote_flutter.
Classes
- Cipher
- An authenticated symmetric cipher.
-
Codec<
T> -
Converts values of type
Tto and from a JSON-style map, and extracts a stable document identifier from each value. -
Collection<
T> - A typed, queryable set of documents backed by a per-collection CrdtTable.
-
CollectionQuery<
T> - An immutable, typed query over a Collection, built by chaining where, orderBy, limit, and startAfter, and executed with get or page.
- Crdt
- Assigns a CrdtType to the annotated field, so concurrent edits to it merge by that type's rule instead of last-write-wins.
- 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.
- Database
- A shared, encrypted, peer-synced database.
- DeepMergeStrategy
-
A MergeStrategy that flattens nested maps recursively, joining keys with
pathSeparator (default
'.'). - 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.
- 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.
- Document
-
Marks a class as a Passnote document model, so
package:passnote_generatorgenerates its codec, document-id extractor, and per-field CRDT schema in one pass — no hand-written maps, and the schema can never drift from the codec. - DocumentId
-
Marks the one field whose value identifies the document
(Codec.idOf). Required, exactly once per Document class, on a
non-nullable
Stringfield. - Frame
- A tagged binary payload routed by room.
- FrameHandlingFailed
- An inbound frame was dropped because handling it threw.
- Identity
- This device's cryptographic identity.
- InboundFrame
- A Frame received from from.
-
JsonCodec<
T> - A Codec backed by plain functions.
- 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.
- 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.
- ObjectMergeStrategy
- A MergeStrategy that treats each document as a single, atomic CRDT record.
- 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.
- PassnoteBuilder
- Staged configuration for a Passnote instance.
- PassnoteConfig
- Top-level configuration for a Passnote instance.
- PassnoteDefaults
- The platform factories PassnoteBuilder fills in for any slot the caller does not override.
- PassnoteEvent
- An observable event from a Passnote instance. Listen via Passnote.events.
- PassphrasePolicy
- Passphrase word-count and strictness policy.
- PeerAppeared
- A peer became reachable on the transport.
- PeerConnected
- Emitted when a new peer connects.
- PeerDisappeared
- A peer stopped being reachable.
- PeerDiscoveryRestored
- Discovery works again after a PeerDiscoveryUnavailable.
- The transport reported that peer discovery is unavailable on this platform (DiscoveryUnavailable at the transport layer) — typically a missing local-network permission or multicast entitlement.
- PeerEvent
- Base type for transport events: peer lifecycle and discovery state.
- PeerIncompatible
- A peer advertised wire versions that share nothing with this build's.
- 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.
-
QueryPage<
T> - One page of query results: the decoded items and, when the result set continues past them, the nextCursor to fetch the following page with CollectionQuery.startAfter.
- QueryPredicate
-
One compiled
whereclause 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
CrdtTableto 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.
- SchemaMergeStrategy
- A MergeStrategy that decomposes a document per top-level field and assigns a CrdtType to named paths.
- ShallowMergeStrategy
- A MergeStrategy that gives each top-level field its own CRDT record.
- SnapshotCapable
- A CrdtTable that keeps periodic on-disk snapshots as a peerless recovery fallback.
- StoreRecovered
- A collection's local store was found unreadable on open and rebuilt.
- Transport
- Discovers same-app nodes and moves opaque frames between them.
- 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.
- PassphraseStrictness
- How Passnote.openDatabase treats a passphrase that is not a recognised BIP39 mnemonic.
- 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.
Functions
-
crdtTypeFromTag(
String? tag) → CrdtType - Resolves a persisted CrdtType.tag back to a CrdtType.
-
newId(
) → String - Generates a collision-resistant document id.
Typedefs
- 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 currentvalue, 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
pathand currentvalue. 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.openDatabaseandPassnote.reopenDatabasewhen the device roster's local trust pins (the founder, the device keys and the revocations this device has validated) are stored but unreadable. - 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.
- WeakPassphraseException
- Thrown by Passnote.openDatabase when PassphrasePolicy.strictness is PassphraseStrictness.reject and the supplied passphrase is not a valid BIP39 mnemonic with known entropy.
- WrongPassphraseException
- Thrown when a supplied passphrase (or the key derived from it) does not decrypt a database's existing local data.