Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
Use `Did` in a bunch more places
Sebastian Martinez committed 3 years ago
commit b04451a1bd4f9fc3ef312d15a96f99d9b6a26c68
parent 2b5552546c6dc637aaa282a990083df8a4a0c0c0
13 files changed +76 -70
modified Cargo.lock
@@ -1972,6 +1972,7 @@ dependencies = [
 "hyper",
 "lexopt",
 "nonempty 0.8.1",
+
 "pretty_assertions",
 "radicle",
 "radicle-cli",
 "radicle-crypto",
modified radicle-cli/examples/rad-id-rebase.md
@@ -10,7 +10,7 @@ ok Identity proposal '57332790a2eabc0b2fd8c7ff48c3579d5812d405' created 🌱
title: Add Alice
description: Add Alice as a delegate
status:  open 
-
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
author: did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi

Document Diff

@@ -52,7 +52,7 @@ ok Identity proposal 'c3698d4e85f9d4c0ee536b34d6122fc7c81f7e2e' created 🌱
title: Add Bob
description: Add Bob as a delegate
status:  open 
-
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
author: did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi

Document Diff

@@ -98,7 +98,7 @@ ok Accepted proposal ✓
title: Add Alice
description: Add Alice as a delegate
status:  open 
-
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
author: did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi

Document Diff

@@ -123,7 +123,7 @@ Accepted

total: 1
keys: [
-
  "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
  "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
]

Rejected
@@ -142,7 +142,7 @@ ok Committed new identity '29ae4b72f5a315328f06fbd68dc1c396a2d5c45e' 🌱
title: Add Alice
description: Add Alice as a delegate
status:  committed 
-
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
author: did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi

Document Diff

@@ -167,7 +167,7 @@ Accepted

total: 1
keys: [
-
  "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
  "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
]

Rejected
@@ -191,7 +191,7 @@ ok Accepted proposal ✓
title: Add Bob
description: Add Bob as a delegate
status:  open 
-
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
author: did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi

Document Diff

@@ -216,7 +216,7 @@ Accepted

total: 1
keys: [
-
  "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
  "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
]

Rejected
@@ -255,7 +255,7 @@ ok Revision 'z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/4'
title: Add Bob
description: Add Bob as a delegate
status:  open 
-
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
author: did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi

Document Diff

@@ -300,7 +300,7 @@ ok Revision 'z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/6'
title: Add Bob
description: Add Bob as a delegate
status:  open 
-
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
author: did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi

Document Diff

@@ -347,7 +347,7 @@ ok Accepted proposal ✓
title: Add Bob
description: Add Bob as a delegate
status:  open 
-
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
author: did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi

Document Diff

@@ -372,7 +372,7 @@ Accepted

total: 1
keys: [
-
  "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
  "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
]

Rejected
@@ -391,7 +391,7 @@ ok Committed new identity '60de897bc24898f6908fd1272633c0b15aa4096f' 🌱
title: Add Bob
description: Add Bob as a delegate
status:  committed 
-
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
author: did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi

Document Diff

@@ -416,7 +416,7 @@ Accepted

total: 1
keys: [
-
  "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
  "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
]

Rejected
modified radicle-cli/examples/rad-id.md
@@ -18,7 +18,7 @@ ok Identity proposal '06d9efa2a9aad06bfdf25a25690e1ec7db2c3c39' created 🌱
title: Add Bob
description: Add Bob as a delegate
status:  open 
-
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
author: did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi

Document Diff

@@ -69,21 +69,21 @@ Next we have the number of `Accepted` reviews from delegates, starting
off with none:

    Accepted
-
    
+

    total: 0
    keys: []

The same with `Rejected` reviews:

    Rejected
-
    
+

    total: 0
    keys: []

Finally, we can see whether the `Quorum` was reached:

    Quorum Reached
-
    
+

    ✗ no

Let's see what happens when we reject the change:
@@ -94,7 +94,7 @@ ok Rejected proposal ✗
title: Add Bob
description: Add Bob as a delegate
status:  open 
-
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
author: did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi

Document Diff

@@ -124,7 +124,7 @@ Rejected

total: 1
keys: [
-
  "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
  "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
]

Quorum Reached
@@ -136,7 +136,7 @@ Our key was added to the `Rejected` set of `keys` and the `total`
increased to `1`.

    Rejected
-
    
+

    total: 1
    keys: [
      "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
@@ -150,7 +150,7 @@ ok Accepted proposal ✓
title: Add Bob
description: Add Bob as a delegate
status:  open 
-
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
author: did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi

Document Diff

@@ -175,7 +175,7 @@ Accepted

total: 1
keys: [
-
  "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
  "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
]

Rejected
@@ -192,16 +192,16 @@ Our key has changed from the `Rejected` set to the `Accepted` set
instead:

    Accepted
-
    
+

    total: 1
    keys: [
-
      "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
      "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
    ]

As well as that, the `Quorum` has now been reached:

    Quorum Reached
-
    
+

    ✓ yes

At this point, we can commit the proposal and update the identity:
@@ -212,7 +212,7 @@ ok Committed new identity 'c96e764965aaeff1c6ea3e5b97e2b9828773c8b0' 🌱
title: Add Bob
description: Add Bob as a delegate
status:  committed 
-
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
author: did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi

Document Diff

@@ -237,7 +237,7 @@ Accepted

total: 1
keys: [
-
  "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
  "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
]

Rejected
@@ -259,7 +259,7 @@ ok Identity proposal 'dc00640d3152ea5f1df59f39f2f5983d2ad21810' created 🌱
title: Update threshold
description: Update to safer threshold
status:  open 
-
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
author: did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi

Document Diff

@@ -303,7 +303,7 @@ ok Closed identity proposal 'dc00640d3152ea5f1df59f39f2f5983d2ad21810'
title: Update threshold
description: Update to safer threshold
status:  closed 
-
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
author: did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi

Document Diff

@@ -360,7 +360,7 @@ $ rad id show dc00640d3152ea5f1df59f39f2f5983d2ad21810
title: Update threshold
description: Update to safer threshold
status:  closed 
-
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
author: did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi

Document Diff

modified radicle-cli/src/commands/patch/common.rs
@@ -232,7 +232,7 @@ pub fn find_unmerged_with_base(
    workdir: &git::raw::Repository,
) -> anyhow::Result<Vec<(PatchId, Patch, Clock)>> {
    // My patches.
-
    let proposed: Vec<_> = patches.proposed_by(patches.public_key())?.collect();
+
    let proposed: Vec<_> = patches.proposed_by(&patches.public_key().into())?.collect();
    let mut matches = Vec::new();

    for (id, patch, clock) in proposed {
modified radicle-cli/src/commands/patch/list.rs
@@ -32,7 +32,7 @@ pub fn run(
    let mut other = Vec::new();

    for (id, patch, _) in proposed {
-
        if *patch.author().id() == me {
+
        if patch.author().id().as_key() == &me {
            own.push((id, patch));
        } else {
            other.push((id, patch));
@@ -85,7 +85,7 @@ fn print(
) -> anyhow::Result<()> {
    let target_head = common::patch_merge_target_oid(patch.target(), storage)?;

-
    let you = patch.author().id() == whoami;
+
    let you = patch.author().id().as_key() == whoami;
    let prefix = "└─ ";
    let mut author_info = vec![format!(
        "{}* opened by {}",
modified radicle-httpd/Cargo.toml
@@ -42,6 +42,7 @@ version = "0.2.0"

[dev-dependencies]
hyper = { version = "0.14.17", default-features = false, features = ["client"] }
+
pretty_assertions = { version = "1.3.0" }
radicle-cli = { path = "../radicle-cli" }
radicle-crypto = { path = "../radicle-crypto" }
tempfile = { version = "3.3.0" }
modified radicle-httpd/src/api/json.rs
@@ -9,8 +9,7 @@ use serde_json::{json, Value};
use radicle::cob::issue::{Issue, IssueId};
use radicle::cob::patch::{Patch, PatchId};
use radicle::cob::thread::{self, CommentId};
-
use radicle::cob::{OpId, Timestamp};
-
use radicle::identity::PublicKey;
+
use radicle::cob::{Author, OpId, Timestamp};
use radicle_surf::blob::Blob;
use radicle_surf::tree::Tree;
use radicle_surf::{Commit, Stats};
@@ -131,11 +130,6 @@ fn name_in_path(path: &str) -> &str {
}

#[derive(Serialize)]
-
struct Author {
-
    id: PublicKey,
-
}
-

-
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct Comment {
    id: OpId,
@@ -156,9 +150,7 @@ impl<'a> FromIterator<(&'a CommentId, &'a thread::Comment)> for Comments {
        for (id, comment) in iter {
            comments.push(Comment {
                id: id.to_owned(),
-
                author: Author {
-
                    id: comment.author(),
-
                },
+
                author: comment.author().into(),
                body: comment.body().to_owned(),
                reactions: [],
                timestamp: comment.timestamp(),
modified radicle-httpd/src/api/v1/projects.rs
@@ -559,6 +559,7 @@ async fn patch_handler(
mod routes {
    use axum::body::Body;
    use axum::http::StatusCode;
+
    use pretty_assertions::assert_eq;
    use serde_json::json;

    use crate::api::test::{self, get, patch, post, HEAD, HEAD_1, ISSUE_ID, PATCH_ID};
@@ -1020,7 +1021,7 @@ mod routes {
              {
                "id": ISSUE_ID,
                "author": {
-
                    "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
                    "id": "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
                },
                "title": "Issue #1",
                "state": {
@@ -1031,7 +1032,7 @@ mod routes {
                  {
                    "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/1",
                    "author": {
-
                        "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
                        "id": "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
                    },
                    "body": "Change 'hello world' to 'hello everyone'",
                    "reactions": [],
@@ -1083,7 +1084,7 @@ mod routes {
            json!({
              "id": CREATED_ISSUE_ID,
              "author": {
-
                  "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
                  "id": "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
              },
              "assignees": [],
              "title": "Issue #2",
@@ -1093,7 +1094,7 @@ mod routes {
              "discussion": [{
                  "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/1",
                  "author": {
-
                      "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
                      "id": "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
                  },
                  "body": "Change 'hello world' to 'hello everyone'",
                  "reactions": [],
@@ -1143,7 +1144,7 @@ mod routes {
            json!({
              "id": ISSUE_ID,
              "author": {
-
                  "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
                  "id": "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
              },
              "assignees": [],
              "title": "Issue #1",
@@ -1154,7 +1155,7 @@ mod routes {
                {
                  "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/1",
                  "author": {
-
                      "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
                      "id": "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
                  },
                  "body": "Change 'hello world' to 'hello everyone'",
                  "reactions": [],
@@ -1164,7 +1165,7 @@ mod routes {
                {
                  "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/5",
                  "author": {
-
                      "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
                      "id": "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
                  },
                  "body": "This is first-level comment",
                  "reactions": [],
@@ -1213,7 +1214,7 @@ mod routes {
            json!({
              "id": ISSUE_ID,
              "author": {
-
                  "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
                  "id": "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
              },
              "assignees": [],
              "title": "Issue #1",
@@ -1224,7 +1225,7 @@ mod routes {
                {
                  "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/1",
                  "author": {
-
                      "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
                      "id": "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
                  },
                  "body": "Change 'hello world' to 'hello everyone'",
                  "reactions": [],
@@ -1234,7 +1235,7 @@ mod routes {
                {
                  "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/5",
                  "author": {
-
                      "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
                      "id": "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
                  },
                  "body": "This is a reply to the first comment",
                  "reactions": [],
@@ -1260,7 +1261,7 @@ mod routes {
              {
                "id": PATCH_ID,
                "author": {
-
                    "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
                    "id": "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
                },
                "title": "A new `hello word`",
                "description": "change `hello world` in README to something else",
@@ -1291,7 +1292,7 @@ mod routes {
              {
                "id": PATCH_ID,
                "author": {
-
                    "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
                    "id": "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
                },
                "title": "A new `hello word`",
                "description": "change `hello world` in README to something else",
modified radicle/src/cob/common.rs
@@ -10,19 +10,25 @@ pub use radicle_crdt::clock::Physical as Timestamp;
/// Author.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Author {
-
    pub id: NodeId,
+
    pub id: Did,
}

impl Author {
-
    pub fn new(id: NodeId) -> Self {
-
        Self { id }
+
    pub fn new(id: impl Into<Did>) -> Self {
+
        Self { id: id.into() }
    }

-
    pub fn id(&self) -> &NodeId {
+
    pub fn id(&self) -> &Did {
        &self.id
    }
}

+
impl From<PublicKey> for Author {
+
    fn from(value: PublicKey) -> Self {
+
        Self::new(value)
+
    }
+
}
+

#[derive(thiserror::Error, Debug)]
pub enum ReactionError {
    #[error("invalid reaction")]
modified radicle/src/cob/identity.rs
@@ -15,7 +15,7 @@ use crate::{
        common::Timestamp,
        store::{self, FromHistory as _, Transaction},
    },
-
    identity::{doc::DocError, Identity, IdentityError},
+
    identity::{doc::DocError, Did, Identity, IdentityError},
    prelude::Doc,
    storage::{git as storage, RemoteId, WriteRepository},
};
@@ -277,7 +277,7 @@ impl Proposal {
            })
    }

-
    pub fn latest_by(&self, who: &PublicKey) -> Option<(&RevisionId, &Revision)> {
+
    pub fn latest_by(&self, who: &Did) -> Option<(&RevisionId, &Revision)> {
        self.revisions().rev().find_map(|(rid, r)| {
            if r.author.id() == who {
                Some((rid, r))
@@ -409,20 +409,20 @@ impl Revision {
            .filter_map(|(key, verdict)| verdict.get().map(|verdict| (key, verdict)))
    }

-
    pub fn accepted(&self) -> Vec<PublicKey> {
+
    pub fn accepted(&self) -> Vec<Did> {
        self.verdicts()
            .filter_map(|(key, v)| match v {
-
                Verdict::Accept(_) => Some(*key),
+
                Verdict::Accept(_) => Some(key.into()),
                Verdict::Reject => None,
            })
            .collect()
    }

-
    pub fn rejected(&self) -> Vec<PublicKey> {
+
    pub fn rejected(&self) -> Vec<Did> {
        self.verdicts()
            .filter_map(|(key, v)| match v {
                Verdict::Accept(_) => None,
-
                Verdict::Reject => Some(*key),
+
                Verdict::Reject => Some(key.into()),
            })
            .collect()
    }
modified radicle/src/cob/issue.rs
@@ -169,11 +169,12 @@ impl Issue {
        self.tags.iter()
    }

-
    pub fn author(&self) -> Option<Author> {
+
    pub fn author(&self) -> Author {
        self.thread
            .comments()
            .next()
            .map(|(_, c)| Author::new(c.author()))
+
            .expect("Issue::author: at least one comment is present")
    }

    pub fn description(&self) -> Option<&str> {
@@ -580,7 +581,7 @@ mod test {

        assert_eq!(created, issue);
        assert_eq!(issue.title(), "My first issue");
-
        assert_eq!(issue.author(), Some(issues.author()));
+
        assert_eq!(issue.author(), issues.author());
        assert_eq!(issue.description(), Some("Blah blah blah."));
        assert_eq!(issue.comments().count(), 1);
        assert_eq!(issue.state(), &State::Open);
modified radicle/src/cob/patch.rs
@@ -839,7 +839,7 @@ impl<'a> Patches<'a> {
    /// Get patches proposed by the given key.
    pub fn proposed_by<'b>(
        &'b self,
-
        who: &'b PublicKey,
+
        who: &'b Did,
    ) -> Result<impl Iterator<Item = (PatchId, Patch, clock::Lamport)> + '_, Error> {
        Ok(self
            .proposed()?
@@ -1027,7 +1027,7 @@ mod test {
        let tmp = tempfile::tempdir().unwrap();
        let (_, signer, project) = test::setup::context(&tmp);
        let mut patches = Patches::open(*signer.public_key(), &project).unwrap();
-
        let author = *signer.public_key();
+
        let author: Did = signer.public_key().into();
        let target = MergeTarget::Delegates;
        let oid = git::Oid::from_str("e2a85016a458cd809c0ecee81f8c99613b0b0945").unwrap();
        let base = git::Oid::from_str("cb18e95ada2bb38aadd8e6cef0963ce37a87add3").unwrap();
modified radicle/src/identity/did.rs
@@ -32,6 +32,10 @@ impl Did {
            .map(Did)
            .map_err(DidError::from)
    }
+

+
    pub fn as_key(&self) -> &crypto::PublicKey {
+
        self.deref()
+
    }
}

impl From<&crypto::PublicKey> for Did {