Holochain Forum

A note on using AgentPubKey as a base or target in create_link and later retrieving with get_links

create_link currently accepts EntryHash for base_address and target_address.
This means that when I am using create_link to link an entry (base) to an AgentPubKey (target) in my case (can be vice versa), I need to call into() for AgentPubKey (my_agent_pubkey below) like this.

/* 
   In kizuna, we link a `message_entry_hash` (which is an entry hash) to the 
  `AgentPubKey` of the agent who read the message already. 
   We retrieve this link later on to determine who got to read the message
*/
let my_agent_pubkey = agent_info()?.agent_latest_pubkey;
create_link(
  message_entry_hash,
  my_agent_pubkey.clone().into(),
  LinkTag::new("read".to_owned()),
)?;

What I DIDN’T realize right away is that this changed the prefix of the base64 string of the AgentPubKey in the frontend from uhCA (prefix for HoloHash<Agent>) to uhCE (prefix for Holohash<Entry>). This caused inconsistencies in the frontend especially when I wanted to compare the AgentPubKey that is either a base or target in the link to something I can get from the cell_id (from conductor-api in my case) in the frontend (To see if the agent read the message already or not for displaying something like unread badge count).

This was a snippet of code for get_links which returns the AgentPubKey with prefix of uhCE which was causing inconsistencies in the frontend.

let mut read_list: HashMap<String, Timestamp> = HashMap::new();
let read_links: Vec<Link> =
    get_links(link.target.clone(), Some(LinkTag::new("read")))?.into_inner();

for link in read_links {
     // The link.target here is an AgentPubKey but it still had the prefix of `uhCE` 
     // when it is converted to base64 string :D
     read_list.insert(link.target.to_string(), link.timestamp);
}
return read_list

The fix was very very simple, I just had to convert the link.target back to the prefix of AgentPubKey by calling into() like this!

let read_links: Vec<Link> =
    get_links(link.target.clone(), Some(LinkTag::new("read")))?.into_inner();

for link in read_links {
    // Here, we convert the prefix of the AgentPubKey back to `uhCA` when it is converted to base64 string in the frontend
    let reader: AgentPubKey = link.target.into();
    read_list.insert(reader.to_string(), link.timestamp);
}

The line let reader: AgentPubKey = link.target.into(); is possible because HoloHash has an impl
pub fn from(hash: HoloHash<Entry>) -> HoloHash<Agent> (Wohoooooo!)

This was a bit of a gotcha for me so I`m leaving a post here just in case others may face a similar experience!

3 Likes