# Usernames Zome ###### tags: `Kizuna-architecture` ## User Stories * As an agent newly entering the network, I would like to have a human-readable username that can be used by others to identify me ## Entry Structure ```rust // TODO: Define Path accordingly Entry "Path" { struct Path(String) } Entry "username" struct Username { username: String } Links: { path->username|usernames| agent_pub_key->username|username| } } ``` Paths will contain this: ```rust // Path above can be sparsed adding sparsing // algorithm in zome (will be available in RSM) such as // by initials of username or by time // For example: Path("USERNAME.a.al.ali.alic.alice"); Path("USERNAME.b.bo.bob.bobb.bobby"); ``` ## Entry Relationship Diagram (With path) ```mermaid graph TD subgraph profile_zome subgraph anchors usernames end subgraph path usernames.a-->|path|usernames.aa usernames.a-->|path|usernames.ab usernames.a-->|path|usernames.al usernames.b-->|path|usernames.ba usernames.b-->|path|usernames.bb usernames.b-->|path|usernames.bo end subgraph username usernames-->|username|usernames.a usernames-->|username|usernames.b usernames.al-->|username|aliceHC usernames.bo-->|username|bobbyHC end subgraph agents alice_id-->|username|aliceHC bobby_id-->|username|bobbyHC end end ``` ## Validation ### Entries * `paths`: * Update/Delete is not valid * create is always valid * `username` * update/delete is valid if the address of the agent committing the entry is the same with the agent address of the author of the entry * create is valid only once when username doesn't exist yet for the authoring agent (Currently being checked at commit time) * create is only valid when there is no same entry exisiting - Will be checked by making the username entry a "single author entry" and have resolution callback when there is conflict especially in network partition. ### Links * `path->username` * only valid when the agent is signing * RemoveLink valid if the author of the entry is removing ### Additional Notes - In RSM, you can already build a tree of create, updates, and deletes. Each agent will walk their own tree. - This can allow us to put those people who wanted the username but were already taken by someone else to be in queue (if we want to). - When you get details on an entry, you get all the CUD details on a particular entry. - Input validation for uniqueness in set_username will not work when the network is partitioned. This can be solved by single author mechanism. This only `detects` the conflict but does not resolve it. The resolution callback for these kinds of conflicts should be provided by the app developer. - TODO: some sort of sybil protection mechanism. - Path is now implemented in RSM. Adds additional hops to spread out the load linked to one anchor. This adds more dht hops in getting the desired entries, but if you know the anchor beforehand, then you can skip the middle trees and hop right into the anchor that was supposed to be fetched. ### `set_username` ```rust= pub struct UsernameWrapper(String); pub fn set_username(username_input: UsernameWrapper) -> ExternResult<UsernameOutput> ``` ### `get_usernames` ```rust= pub struct AgentPubKeys(Vec<AgentPubKey>); pub struct UsernameList(Vec<UsernameOutput>); pub fn get_usernames(agent_pubkeys: AgentPubKeys) -> ExternResult<UsernameList> ``` ### `get_my_username` ```rust= pub struct UsernameOutput { username: String, agent_id: AgentPubKey, created_at: Timestamp, entry_header_hash: HeaderHash, } pub fn get_my_username_handler() -> ExternResult<UsernameOutput> ``` ### `get_all_usernames` ```rust= pub struct UsernameList(Vec<UsernameOutput>); pub fn get_all_usernames() -> ExternResult<UsernameList> ``` ### `get_agent_pubkey_from_username` ```rust= pub struct UsernameWrapper(String); pub(crate) fn get_agent_pubkey_from_username_handler( username_input: UsernameWrapper ) -> ExternResult<AgentPubKey> ```