Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

%passport v1 spec #1304

Open
ajlamarc opened this issue Mar 30, 2023 · 4 comments
Open

%passport v1 spec #1304

ajlamarc opened this issue Mar 30, 2023 · 4 comments
Assignees
Labels
1:high-priority Needs to be done as soon as possible state-update Requires a migration in hoon state

Comments

@ajlamarc
Copy link
Contributor

ajlamarc commented Mar 30, 2023

In https://github.com/holium/realm/wiki/Passport-spec we laid out different iterations of passport, starting with v1. V1 is about smooth onboarding and connecting users to others that are using Realm. This requires an opt-in centralized service and an evolution of the %friends agent.

image

Friends sur

Refer to https://github.com/holium/realm/blob/master/desks/realm/sur/friends.hoon for the current.

::
:: friends state version 2
+$  friends   (map @p friend)
::
::  $friend: these values are mostly used by us for bookkeeping on peers.
::  contact-info and status is received by peers.
::
+$  friend
  $:  pinned=_|
      tags=(set @t)
      ::
      :: public -> only set by us. If public, others can discover us
      :: by searching twitter handle or Realm username.
      :: linking contacts allows discovery via phone number.
      ::
      :: your phone number will _never_ be visible to anyone.
      ::
      :: private: those that "know" you (have shared space(s)/DMs with you)
      :: can see your profile.
      ::
      public=(unit _|)
      phone-number=(unit @t)
      :: %our = us
      :: %fren = friend (sent/received and accepted)
      :: %received = live friend request received
      :: %sent = live friend request sent
      :: %contact = legacy contact-store??
      ::
      :: %block = I blocked you. - last message is me going offline.
      :: Further friend requests are auto-denied,
      :: and we don't send them any updates.
      ::
      :: %know - Have shared space(s)/DMs together. Is this like %contact?
      :: This may present scaling issues - we can kill
      :: "knows" data when you no longer share a connection.
      ::
      :: defaults to %know
      relationship=?(%our %fren %received %sent %contact %know %block)
      :: %invisible is used by us only, communicated to peers as %offline
      :: defaults to %offline
      status=?(%online %away %dnd %offline %invisible)
      :: Taking live status updates further:
      :: These are decent ideas but we need to weigh 
      :: implementation time + extra traffic over Urbit.  Putting them as ideas for later
      :: Bazaar could be scried for apps/spaces we already know about, 
      :: otherwise (for public spaces / apps) a database query would be required
      :: to resolve from space-path to public space name, etc.
      ::
      :: platform=?(%desktop %mobile)
      :: curr-space=(unit space-path)
      :: curr-app=(unit app-path)
      :: curr-room=(unit room-path)
      contact-info=(unit contact-info)
      :: stretch: I should be able to set photos / names
      :: for friends that override theirs.
      ::
      :: I should be able to set my name / photo for different spaces.
  ==
::
::  $contact-info: what a peer decides to tell us about themselves.
::
+$  contact-info
  $:  nickname=@t    :: passport set name (required)
      color=@t             :: passport set color
      twitter=(unit @t)  :: twitter handle
      bio=(unit @t)
      avatar=(unit @t)
      cover=(unit @t)
      featured-url=(unit @t)  :: can be used for personal site, linktree, opensea...
  ==
::
::  $contact-info-edit: updates from peer about their information.
::  this should eventually be done via SSS.
::
+$  contact-info-edit
  $:  nickname=(unit @t)
      color=(unit @t)
      twitter=(unit @t)
      bio=(unit @t)
      avatar=(unit @t)
      cover=(unit @t)
      featured-url=(unit @t)
  ==

Postgres table

create table if not exists friends
(
    ship         TEXT    not null, // primary key
    is_public    boolean not null,
    nickname     TEXT    not null,
    color        TEXT    not null,
    twitter      TEXT,
    bio          TEXT,
    avatar       TEXT,
    cover        TEXT,
    featured_url TEXT,
    phone_number TEXT,
    created_at   integer not null,
    updated_at   integer not null,
)

^ If a ship was never public, this information should not be stored in the table.

@ajlamarc ajlamarc added 1:high-priority Needs to be done as soon as possible state-update Requires a migration in hoon state labels Mar 30, 2023
@drunkplato
Copy link
Contributor

drunkplato commented Mar 31, 2023

In all cases we should sync nickname, avatar, and color at the minimum. Whether a profile is private or public. Public would share all metadata.

@drunkplato
Copy link
Contributor

Also, we should consider how we can store attestations (signed and typed data) about ownership of NFTs -- even though this will be a future addition.

@ajlamarc
Copy link
Contributor Author

ajlamarc commented Mar 31, 2023

In all cases we should sync nickname, avatar, and color at the minimum. Whether a profile is private or public. Public would share all metadata.

Yes, profile information will still be visible to those in a space with you or in DMs (but not phone number). Difference being you aren't surfaced in global queries if private.

Also, we should consider how we can store attestations (signed and typed data) about ownership of NFTs -- even though this will be a future addition.

I don't think it makes sense to build a decentralized attestation system. So:

  • User A links his wallet address, which is stored in our friends table. Their Realm client calls a Realm backend, which asks Alchemy / etc. for all NFTs owned by the address and returns them, showing inside the Realm wallet.

    • From inside the wallet, they can set their profile picture to be one of their NFTs instead.
  • This is communicated to peers over Urbit with avatar as normal and then a boolean flag, nft=%.y.

  • User B has the option to view User A's NFT collection from their profile/passport. Results are cached locally, and each view attempt also requests the Alchemy API for latest.

    • Consider caching w/ timeout the Alchemy response on Realm servers to save on Alchemy API usage.

The interesting question here is: User A sells their NFT from profile picture, but their avatar is still labeled as NFT for everyone. This remains until the next time User A opens their wallet, when their ship realizes it is no longer theirs and informs everyone they know.

What we want is a way for centralized Realm to push updates to user's Urbits. So what are the solutions?

  1. Realm UI needs to request Realm backend for this (and other) information on each boot. This might look like an nft-update table, where you query for only the list of ships you care about and the time you last checked.
  2. Same as 1 but instead of a separate table, just query all ships you know for their nft flags.
  3. Realm backend airlocks + informs ~hostyv and its fleet of moons, who fire off pokes (or subscriptions) to everyone of interest when something like this occurs. User ships trust updates from ~hostyv as truth and update their state.

3 is more interesting long-term: updates are "pushed" rather than pulled, meaning current data is on someone's Urbit already when they log in rather than being forced to do Realm UI -> Realm Backend -> Realm UI -> gall agent. But that sounds like hell to implement when Urbit is still nascent, so I'd suggest option 2.

IMO the real way we "move faster" is unabashedly mixing centralized / decentralized technologies for a better user experience.

https://docs.alchemy.com/docs/how-to-get-all-nfts-owned-by-an-address#:~:text=To%20get%20all%20NFTs%20owned%20by%20an%20address%2C%20use%20the,to%20get%20NFT%20ownership%20data

Edit: solution will be along the lines of #608

@ajlamarc
Copy link
Contributor Author

ajlamarc commented Apr 6, 2023

OK, so I thought about %social-graph and it seems good to use for an SSS / basic Urbit graph store reference. Shoving everything into "tags" (paths) is very limiting. Uqbar isn't using it for much of anything: https://github.com/uqbar-dao/pongo/blob/master/app/posse.hoon. It also isn't implementing any sort of gossip protocol, so it doesn't serve well for communicating "friends of friends".

That being said, I will go forward with directly evolving %friends to serve for passport (@leowini thanks for the initial PR). I'm also going to remove the dependency on Tlon's contact-store unless there are any objections.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1:high-priority Needs to be done as soon as possible state-update Requires a migration in hoon state
Projects
None yet
Development

No branches or pull requests

3 participants