Skip to content

Commit d6777f7

Browse files
authored
feat: return hash_ref from create_key_package_for_event (marmot-protocol#178)
Return the KeyPackage hash_ref as a third tuple element from create_key_package_for_event and create_key_package_for_event_with_options. This enables callers to track key packages for lifecycle management (publish → consume → cleanup) without needing to re-parse the package. Remove compute_key_package_hash_ref() which is now redundant — the hash_ref is computed atomically during key package creation.
1 parent 3db914a commit d6777f7

12 files changed

Lines changed: 85 additions & 80 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
136136
let relay_url = RelayUrl::parse("wss://relay.example.com")?;
137137

138138
// Bob creates a key package
139-
let (bob_key_package, tags) = bob_mdk
139+
let (bob_key_package, tags, _hash_ref) = bob_mdk
140140
.create_key_package_for_event(&bob_keys.public_key(), [relay_url.clone()])?;
141141

142142
let bob_key_package_event = EventBuilder::new(Kind::MlsKeyPackage, bob_key_package)

crates/mdk-core/CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
### Breaking changes
2727

28+
- **`create_key_package_for_event` Return Type Change**: The return type changed from `(String, Vec<Tag>)` to `(String, Vec<Tag>, Vec<u8>)`. The third element is the serialized hash_ref of the key package, computed atomically during creation. This enables callers to track key packages for lifecycle management (publish → consume → cleanup) without needing to re-parse the package. Callers that don't need the hash_ref can destructure with `_`. ([#178](https://github.com/marmot-protocol/mdk/pull/178))
2829
- **`create_key_package_for_event` Return Type Change**: The return type changed from `(String, [Tag; 7])` to `(String, Vec<Tag>)`. Most code patterns (iteration, indexing) continue to work unchanged. This change was necessary because the protected tag is now optional. ([#173](https://github.com/marmot-protocol/mdk/pull/173), related: [#168](https://github.com/marmot-protocol/mdk/issues/168))
2930
- **`create_key_package_for_event` No Longer Adds Protected Tag**: The `create_key_package_for_event()` function no longer adds the NIP-70 protected tag (`["-"]`) by default. This is a behavioral change - existing code that relied on the protected tag being present will now produce key packages without it. Key packages can now be republished by third parties to any relay. This improves relay compatibility since many popular relays (Damus, Primal, nos.lol) reject protected events outright. For users who need the protected tag, use the new `create_key_package_for_event_with_options()` function with `protected: true`. ([#173](https://github.com/marmot-protocol/mdk/pull/173), related: [#168](https://github.com/marmot-protocol/mdk/issues/168))
3031
- **OpenMLS 0.8.0 Upgrade**: Upgraded from a git-pinned openmls 0.7.1 to the crates.io openmls 0.8.0 release. This resolves security advisory [GHSA-8x3w-qj7j-gqhf](https://github.com/openmls/openmls/security/advisories/GHSA-8x3w-qj7j-gqhf) (improper tag validation) and moves GREASE support from a git pin to an official release. Companion crates updated: `openmls_traits` 0.5, `openmls_basic_credential` 0.5, `openmls_rust_crypto` 0.5. ([#174](https://github.com/marmot-protocol/mdk/pull/174))
@@ -41,7 +42,7 @@
4142

4243
### Added
4344

44-
- **KeyPackage hash_ref computation and deletion by bytes**: Added `compute_key_package_hash_ref()` to serialize a key package's hash_ref for external caching, and `delete_key_package_from_storage_by_hash_ref()` to delete a key package using previously serialized hash_ref bytes. This enables delayed key material cleanup workflows where the hash_ref is cached at welcome-processing time and used for deletion later. ([#176](https://github.com/marmot-protocol/mdk/pull/176))
45+
- **KeyPackage deletion by hash_ref bytes**: Added `delete_key_package_from_storage_by_hash_ref()` to delete a key package using previously serialized hash_ref bytes. This enables delayed key material cleanup workflows where the hash_ref is obtained at creation time (via `create_key_package_for_event`) and used for deletion later. ([#178](https://github.com/marmot-protocol/mdk/pull/178))
4546
- **Custom Message Sort Order**: `get_messages()` now supports custom sort orders via the `Pagination::sort_order` field. Added `get_last_message(group_id, sort_order)` method to retrieve the most recent message under a given sort order, enabling clients using `ProcessedAtFirst` ordering to get a consistent "last message" value. ([#171](https://github.com/marmot-protocol/mdk/pull/171))
4647
- **`create_key_package_for_event_with_options`**: New function that allows specifying whether to include the NIP-70 protected tag. Use this if you need to publish to relays that accept protected events. ([#173](https://github.com/marmot-protocol/mdk/pull/173), related: [#168](https://github.com/marmot-protocol/mdk/issues/168))
4748
- **MIP-04 Epoch Fallback for Media Decryption**: `decrypt_from_download` now resolves the correct decryption key via an O(1) epoch hint lookup instead of only using the current epoch's exporter secret. Added `NoExporterSecretForEpoch` variant to `EncryptedMediaError` for programmatic error matching. ([#167](https://github.com/marmot-protocol/mdk/pull/167))
@@ -60,6 +61,8 @@
6061

6162
### Removed
6263

64+
- **`compute_key_package_hash_ref` removed**: This method is no longer needed now that `create_key_package_for_event` returns the hash_ref directly as its third tuple element. Callers should use the hash_ref from `create_key_package_for_event` instead. ([#178](https://github.com/marmot-protocol/mdk/pull/178))
65+
6366
### Deprecated
6467

6568
- **Unified Storage Architecture**: `MdkProvider` now uses the storage provider directly as the OpenMLS `StorageProvider`, instead of accessing it via `openmls_storage()`. This enables atomic transactions across MLS and MDK state for proper commit race resolution per MIP-03. Storage implementations must now directly implement `StorageProvider<1>`. ([#148](https://github.com/marmot-protocol/mdk/pull/148))

crates/mdk-core/examples/group_inspection.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ async fn main() -> Result<(), Error> {
6363
let relay_url = RelayUrl::parse("wss://relay.example.com").unwrap();
6464

6565
// Create key packages for members (not creator)
66-
let (member1_kp_encoded, member1_tags) =
66+
let (member1_kp_encoded, member1_tags, _) =
6767
mdk.create_key_package_for_event(&member1_keys.public_key(), [relay_url.clone()])?;
6868

6969
let member1_event =
@@ -73,7 +73,7 @@ async fn main() -> Result<(), Error> {
7373
.sign(&member1_keys)
7474
.await?;
7575

76-
let (member2_kp_encoded, member2_tags) =
76+
let (member2_kp_encoded, member2_tags, _) =
7777
mdk.create_key_package_for_event(&member2_keys.public_key(), [relay_url.clone()])?;
7878

7979
let member2_event =

crates/mdk-core/examples/key_package_inspection.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ async fn main() -> Result<(), Error> {
4242
println!("=== Creating Key Package ===\n");
4343

4444
// Create key package with protected=true to demonstrate NIP-70 tag
45-
let (key_package_encoded, tags) = mdk.create_key_package_for_event_with_options(
45+
let (key_package_encoded, tags, _hash_ref) = mdk.create_key_package_for_event_with_options(
4646
&keys.public_key(),
4747
[relay_url.clone()],
4848
true,

crates/mdk-core/examples/mls_memory.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ async fn main() -> Result<(), Error> {
3333

3434
// Create key package for Bob
3535
// This would be published to the Nostr network for other users to find
36-
let (bob_key_package_encoded, tags) =
36+
let (bob_key_package_encoded, tags, _) =
3737
bob_mdk.create_key_package_for_event(&bob_keys.public_key(), [relay_url.clone()])?;
3838

3939
let bob_key_package_event = EventBuilder::new(Kind::MlsKeyPackage, bob_key_package_encoded)
@@ -242,7 +242,7 @@ async fn main() -> Result<(), Error> {
242242
tracing::info!("Charlie identity generated");
243243

244244
// Create key package for Charlie
245-
let (charlie_key_package_encoded, charlie_tags) = charlie_mdk
245+
let (charlie_key_package_encoded, charlie_tags, _) = charlie_mdk
246246
.create_key_package_for_event(&charlie_keys.public_key(), [relay_url.clone()])?;
247247

248248
let charlie_key_package_event =

crates/mdk-core/examples/mls_sqlite.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ async fn main() -> Result<(), Error> {
4040

4141
// Create key package for Bob
4242
// This would be published to the Nostr network for other users to find
43-
let (bob_key_package_encoded, tags) =
43+
let (bob_key_package_encoded, tags, _) =
4444
bob_mdk.create_key_package_for_event(&bob_keys.public_key(), [relay_url.clone()])?;
4545

4646
let bob_key_package_event = EventBuilder::new(Kind::MlsKeyPackage, bob_key_package_encoded)
@@ -254,7 +254,7 @@ async fn main() -> Result<(), Error> {
254254
tracing::info!("Charlie identity generated");
255255

256256
// Create key package for Charlie
257-
let (charlie_key_package_encoded, charlie_tags) = charlie_mdk
257+
let (charlie_key_package_encoded, charlie_tags, _) = charlie_mdk
258258
.create_key_package_for_event(&charlie_keys.public_key(), [relay_url.clone()])?;
259259

260260
let charlie_key_package_event =

0 commit comments

Comments
 (0)