Skip to content
This repository was archived by the owner on Feb 28, 2025. It is now read-only.

Commit 53e4716

Browse files
committed
formalize and decouple XMTP attributes from did:ethr
1 parent 92ab760 commit 53e4716

File tree

5 files changed

+275
-158
lines changed

5 files changed

+275
-158
lines changed

lib/src/types.rs

+14-35
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
mod did_parser;
55
mod did_url;
66
mod ethr;
7+
mod xmtp;
78

89
use serde::{Deserialize, Serialize};
910
use std::fmt;
@@ -12,6 +13,7 @@ use url::Url;
1213
pub use did_parser::*;
1314
pub use did_url::*;
1415
pub use ethr::*;
16+
pub use xmtp::*;
1517

1618
/// The ethereum null addresss
1719
pub const NULL_ADDRESS: &str = "0x0000000000000000000000000000000000000000";
@@ -191,26 +193,11 @@ impl From<KeyType> for String {
191193
}
192194
}
193195

194-
/// Any extra key-specific metadata that could be ascribed to the key
195-
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Serialize, Deserialize)]
196-
pub enum KeyMetadata {
197-
Installation,
198-
}
199-
200-
impl fmt::Display for KeyMetadata {
201-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
202-
match self {
203-
KeyMetadata::Installation => write!(f, "inst"),
204-
}
205-
}
206-
}
207-
208196
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Serialize, Deserialize)]
209197
pub enum KeyPurpose {
210198
VerificationKey,
211199
SignatureAuthentication,
212200
Encryption,
213-
Xmtp,
214201
}
215202

216203
impl fmt::Display for KeyPurpose {
@@ -219,7 +206,6 @@ impl fmt::Display for KeyPurpose {
219206
KeyPurpose::VerificationKey => write!(f, "veriKey"),
220207
KeyPurpose::SignatureAuthentication => write!(f, "sigAuth"),
221208
KeyPurpose::Encryption => write!(f, "enc"),
222-
KeyPurpose::Xmtp => write!(f, "xmtp"),
223209
}
224210
}
225211
}
@@ -236,28 +222,22 @@ pub enum Attribute {
236222
PublicKey(PublicKey),
237223
Service(ServiceType),
238224
Other(String),
225+
Xmtp(XmtpAttribute),
239226
}
240227

241228
impl fmt::Display for Attribute {
242229
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
243230
match self {
244231
Attribute::PublicKey(key) => {
245-
if let Some(metadata) = key.metadata {
246-
write!(
247-
f,
248-
"did/pub/{}/{}/{}/{}",
249-
key.key_type, key.purpose, metadata, key.encoding
250-
)
251-
} else {
252-
write!(
253-
f,
254-
"did/pub/{}/{}/{}",
255-
key.key_type, key.purpose, key.encoding
256-
)
257-
}
232+
write!(
233+
f,
234+
"did/pub/{}/{}/{}",
235+
key.key_type, key.purpose, key.encoding
236+
)
258237
}
259238
Attribute::Service(service) => write!(f, "did/svc/{}", service),
260239
Attribute::Other(other) => write!(f, "{}", other),
240+
Attribute::Xmtp(xmtp) => write!(f, "xmtp/{}/{}", xmtp.purpose, xmtp.encoding),
261241
}
262242
}
263243
}
@@ -309,7 +289,6 @@ impl From<KeyEncoding> for String {
309289
pub struct PublicKey {
310290
pub key_type: KeyType,
311291
pub purpose: KeyPurpose,
312-
pub metadata: Option<KeyMetadata>,
313292
pub encoding: KeyEncoding,
314293
}
315294

@@ -483,19 +462,19 @@ mod test {
483462
let bytes: [u8; 32] = parsed.into();
484463
assert_eq!(String::from_utf8_lossy(&bytes), attribute);
485464
};
486-
t("did/pub/Ed25519/xmtp/inst/base58");
465+
t("xmtp/installation/base58 ");
466+
t("xmtp/installation/hex ");
467+
t("xmtp/installation/base64 ");
468+
t("did/pub/Ed25519/veriKey/base58 ");
469+
t("did/pub/Secp256k1/veriKey/base64");
487470
t("did/svc/MessagingService ");
488-
t("did/pub/Secp256k1/xmtp/inst/hex ");
489-
t("did/pub/RSA/xmtp/inst/hex ");
490-
t("did/pub/Ed25519/xmtp/inst/base64");
491471
}
492472

493473
#[test]
494474
fn test_attribute_to_string() {
495475
let attr = Attribute::PublicKey(PublicKey {
496476
key_type: KeyType::Ed25519VerificationKey2020,
497477
purpose: KeyPurpose::VerificationKey,
498-
metadata: None,
499478
encoding: KeyEncoding::Base58,
500479
});
501480
assert_eq!(attr.to_string(), "did/pub/Ed25519/veriKey/base58");

lib/src/types/did_parser.rs

+58-20
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,7 @@ peg::parser! {
8181
= kt:(secp256k1() / ed25519() / rsa() / x25519() ) { kt }
8282

8383
rule key_purpose() -> KeyPurpose
84-
= i("veriKey") { KeyPurpose::VerificationKey } / "sigAuth" { KeyPurpose::SignatureAuthentication } / "enc" { KeyPurpose::Encryption } / "xmtp" { KeyPurpose::Xmtp }
85-
86-
rule key_metadata() -> KeyMetadata
87-
= i("inst") { KeyMetadata::Installation }
84+
= i("veriKey") { KeyPurpose::VerificationKey } / "sigAuth" { KeyPurpose::SignatureAuthentication } / "enc" { KeyPurpose::Encryption }
8885

8986
rule encoding() -> KeyEncoding
9087
= i("hex") { KeyEncoding::Hex } / "base64" { KeyEncoding::Base64 } / "base58" { KeyEncoding::Base58 }
@@ -98,24 +95,30 @@ peg::parser! {
9895
rule service() -> ServiceType
9996
= padding() "did/svc/" svc:(messaging_service() / other_service()) padding() { svc }
10097

101-
rule public_key() -> (KeyType, KeyPurpose, Option<KeyMetadata>, KeyEncoding)
102-
= padding() "did/pub/" kt:key_type() "/" kp:key_purpose() "/" me:metadata_and_encoding() padding() {
103-
(kt, kp, me.0, me.1)
98+
rule public_key() -> (KeyType, KeyPurpose, KeyEncoding)
99+
= padding() "did/pub/" kt:key_type() "/" kp:key_purpose() "/" enc:encoding() padding() {
100+
(kt, kp, enc)
104101
}
105102

106-
rule metadata_and_encoding() -> (Option<KeyMetadata>, KeyEncoding)
107-
= km:key_metadata() "/" enc:encoding() { (Some(km), enc) } / enc:encoding() { (None, enc) }
103+
rule xmtp_purpose() -> XmtpKeyPurpose
104+
= "installation" { XmtpKeyPurpose::Installation }
105+
106+
rule xmtp() -> Attribute
107+
= padding() "xmtp/" xmtp:xmtp_purpose() "/" enc:encoding() padding() { Attribute::Xmtp(XmtpAttribute { purpose: xmtp, encoding: enc })}
108+
109+
rule ethr() -> Attribute
110+
= pk:public_key() {
111+
let key = PublicKey { key_type: pk.0, purpose: pk.1, encoding: pk.2 };
112+
Attribute::PublicKey(key)
113+
}
114+
/ svc:service() { Attribute::Service(svc) }
108115

109116
/// Parses the DID attribute name value
110117
///
111118
/// Parses the `did/pub/(Secp256k1|RSA|Ed25519|X25519)/(veriKey|sigAuth|enc|xmtp)/(hex|base64|base58)` part of a DID attribute name for adding a public key,
112119
/// or the `did/svc/[ServiceName]` part for adding a service
113120
pub rule attribute() -> Attribute
114-
= pk:public_key() {
115-
let key = PublicKey { key_type: pk.0, purpose: pk.1, metadata: pk.2, encoding: pk.3 };
116-
Attribute::PublicKey(key)
117-
}
118-
/ svc:service() { Attribute::Service(svc) }
121+
= x:xmtp() { x } / e:ethr() { e }
119122
}
120123
}
121124

@@ -186,12 +189,6 @@ mod tests {
186189
"did/pub/X25519/enc/hex",
187190
"did/pub/X25519/enc/base64",
188191
"did/pub/X25519/enc/base58",
189-
"did/pub/ed25519/xmtp/inst/hex",
190-
"did/pub/x25519/xmtp/inst/hex",
191-
"did/pub/Secp256k1/xmtp/inst/hex",
192-
"did/pub/RSA/xmtp/inst/hex",
193-
"did/pub/ed25519/xmtp/inst/base64",
194-
"did/pub/ed25519/xmtp/inst/base58",
195192
"did/svc/MessagingService",
196193
];
197194

@@ -201,6 +198,47 @@ mod tests {
201198
}
202199
}
203200

201+
#[test]
202+
fn test_did_xmtp_attribute_parser() {
203+
let keys = [
204+
"xmtp/installation/hex",
205+
"xmtp/installation/base58",
206+
"xmtp/installation/base64",
207+
];
208+
209+
for key in keys {
210+
let parsed = parse_attribute(key);
211+
assert!(parsed.is_ok(), "Failed to parse key: {}", key);
212+
}
213+
}
214+
215+
#[test]
216+
fn test_xmtp_attribute_parses() {
217+
assert_eq!(
218+
parse_attribute("xmtp/installation/hex"),
219+
Ok(Attribute::Xmtp(XmtpAttribute {
220+
purpose: XmtpKeyPurpose::Installation,
221+
encoding: KeyEncoding::Hex
222+
}))
223+
);
224+
225+
assert_eq!(
226+
parse_attribute("xmtp/installation/base64"),
227+
Ok(Attribute::Xmtp(XmtpAttribute {
228+
purpose: XmtpKeyPurpose::Installation,
229+
encoding: KeyEncoding::Base64,
230+
}))
231+
);
232+
233+
assert_eq!(
234+
parse_attribute("xmtp/installation/base58"),
235+
Ok(Attribute::Xmtp(XmtpAttribute {
236+
purpose: XmtpKeyPurpose::Installation,
237+
encoding: KeyEncoding::Base58
238+
}))
239+
);
240+
}
241+
204242
#[test]
205243
fn test_ethr_method_parser() {
206244
let parsed =

0 commit comments

Comments
 (0)