marmot_dart 0.0.4
marmot_dart: ^0.0.4 copied to clipboard
End-to-end encrypted group messaging for Flutter, built on the Marmot protocol (MLS over Nostr) via MDK.
0.0.4 #
- Added
ensureNativeLibrary()guards toinitKeyringStore,initMdk, andremoveSession. Prevents native library "not loaded" crashes when calling init functions before the FFI layer is ready.
0.0.3 #
buildUnsignedRumornow uses named parameters with optionalcontentTypefor structured (JSON) payloads. The receiver'sMarmotMessage.payloadJsonis populated when a content-type tag is present.- New
Marmot.sendStructured(npub, groupId, payload)— one-call convenience for sending JSON messages. - New
Marmot.getMessages(groupId, {params})— paginated retrieval of stored messages from the encrypted local DB. - New
Marmot.getMessage(groupId, eventIdHex)— single message lookup by Nostr event ID. - New
Marmot.getLastMessage(groupId)— most recent message in a group. - New
MessageListParamsmodel (limit, offset, sortByProcessedAt). - New
Marmot.leaveGroup(groupId)— remove self from a group via MLS. Returns commit event to publish. - New
Marmot.deleteMessagesForGroup(groupId)— delete all locally stored messages for a group. Group stays active. - New
Marmot.deleteGroup(groupId)— delete all local state for a group. Idempotent, local-only. - New
MarmotGroupfields:lastMessageId,lastMessageAtSecs,lastMessageProcessedAtSecs— updated automatically on every send/receive. - Comprehensive test suite: 22 Rust tests (identity, key packages, groups, messages, media roundtrip) and 42 Dart model tests.
- Codebase cleanup: consolidated redundant wrapper files;
buildUnsignedRumorandsignEventnow top-level inmarmot.dart.
0.0.2 #
- Bumped homepage and repository URLs.
0.0.1 #
Initial development release. Built on MDK 0.8 via flutter_rust_bridge 2.12.
Storage #
Three backends via StorageConfig:
StorageConfig.memory— in-memory storage (ephemeral, for testing)StorageConfig.sqlite(dbPath, serviceId, keyId)— keyring-managed encryptionStorageConfig.sqliteWithKey(dbPath, dbKey)— host supplies 32-byte encryption key
Call Marmot.initKeyringStore() once before using .sqlite.
Identity (MarmotIdentity) #
generate()— new Nostr keypair (nsec returned, host must persist)importFromNsec(nsec)— import existing keypairvalidateNsec(nsec)— check validitynpubFromNsec(nsec)— derive npubpubkeyHexFromNpub(npub)— convert bech32 to hex
Pure functions — no MDK state needed. Keys held in memory only for current session.
Key packages #
Marmot.createKeyPackage(npub, relayUrls)— mint MLS key package, return piecesMarmot.createSignedKeyPackage(nsec, relayUrls)— mint + sign a kind:30443 eventsignEvent(nsec, unsignedEventJson)— top-level pure function
Groups #
Full MLS group lifecycle on Marmot instance:
createGroup(creatorNpub, params)— create group, return welcome rumorsprocessWelcome(wrapperEventId, welcomeRumorJson)— parse incoming welcomegetPendingWelcomes()— list unaccepted invitesacceptWelcome(welcomeId)— join a grouplistGroups()— all groups for this identitygetMembers(groupId)— member listaddMember(groupId, keyPackageEventJson)— add member, return commit + welcomeremoveMember(groupId, npub)— remove member, return commitupdateGroupMetadata(groupId, {name, description, relayUrls, adminNpubs})— edit MIP-01 metadataMarmot.prepareGroupImage(imageData, mimeType)— encrypt group image (static)setGroupImage(groupId, {imageHash, imageKey, imageNonce, imageUploadKey})— store image refs in metadataclearGroupImage(groupId)— remove group imageMarmot.decryptGroupImage({encryptedData, imageHash, imageKey, imageNonce})— decrypt downloaded blob (static)
Messages #
buildUnsignedRumor(npub, content)— build unsigned kind-9 rumor (top-level, pure)sendMessage(unsignedRumorJson, groupId)— encrypt rumor via MLS, return kind:445 eventbuildMediaRumor({...})— build media rumor with MIP-04 imeta tagprocessIncoming(nostrEventJson)— decrypt and apply incoming event
Media (MIP-04) #
encryptMedia(groupId, data, mimeType, filename)— encrypt file for groupdecryptMedia(groupId, encryptedData, mediaRef)— decrypt downloaded blob
Top-level exports #
buildUnsignedRumor, signEvent, MarmotIdentity, plus models: StorageConfig, NostrKeypair, KeyPackageEventData, CreateGroupParams, GroupCreateResult, MarmotGroup, MarmotMember, PendingWelcome, MemberChangeResult, GroupMetadataUpdate, GroupImagePrepared, MarmotMessage, MarmotMediaRef, EncryptedMediaOutput, MediaRefInput, MarmotError