---
# System prepended metadata

title: Dao Memberships tech spec

---

# Dao Memberships tech spec
## ****Implementation Spec****

## Scope

- Technical design
    - What new tables or columns do we need?
      - [Figma roles diagram](https://www.figma.com/file/vVh1k3jfMP7zmIx1j7DrX6/DAO-Membership-Flows-and-IA?node-id=35%3A553&t=KnusfV3IjtGsN42l-4)
      - Member
      - contributor
      - Recruit
      - Supporter
      - Lurker

- Api endpoints
    - `CreateGuild`
        - Must take name
        - And members with whether they have an admin status
    - `CreateGuildUser`
        - Requires requester to have the same address as the created guild user
    - `ListGuilds`
        - Fetch daos a user can join
    - `UpdateGuildUser`
      - Ability to update guild to set a `favorite` status scoped to the connected user
      - Purpose: to add favorites to be surfaced in the My DAOs list and sidebar
  -  `UpdateGuildUser` - role
        - We'd likely need a way for the roles to be updated at a later point (such as removing an admin status)
      - Will need to be able to set user status to `recruit` of the selected DAO when they use *Join a DAO* on the DAO Profile
      - Question: Who would be able to do this? Guild admins only?
    - `UpdateGuild`
         - Update metadata (e.g. name, image,)
         - What metadata can be updated by admins? After verification?

- Schema
    - `GuildUser`
        - Add favorite column (Boolean)
            - Surface in api only if user 
            - is making a request
        - Add membership level column [foreign key]
            - Should start with admin status, and member status
    - `GuildMembershipStatus`
        - Has admin level
        - Contributior level etc
        - Roles:
          - `admin`, `contributor`, `recruit` -- with `recruit`
          - `admin`: 
          - `contributor`:
          - `recruit`: this is what is set when a user joins via the *Join a DAO*
            - Doesn't require an approval step, but do we want this to show up in their DAO list? it would likely need to so that they could add a contribution? 
              - We may need to give this a bit of thought
          - `null` -- default for all users who aren't opting in / part of that DAO since `recruit` has a different purpose and shouldn't be the default
    - `Guild`
        - Add verfication status column
    - `GuildVerificationStatus`
        - Add a table to house the guild verification statuses
    - `GuildImport` table
        - Should have a colmun for id, guild_id (FK to Guild), integration type, integration guild id, authentication token
        - Unique on integration type and integration guild_id
        - Should we instead have integration_id on the Guild table?
- New Infrastructure
    - Setup Nats to handle asynchronous tasks
        - https://docs.nats.io/
    - To process these asynchronously we will use a NATs queue with receives messages that are consumed by the workers we create.

### Does this require any third-party integrations?

- **Guild**
  - Guild API integration for the 
    - https://www.npmjs.com/package/@guildxyz/sdk
  - Sign a message for authentication
  - Use getUserMemberships to show which daos a user can import
  - Then send a message with the authentication signature, guildId and userId to be processed 
  - In guild consumer use guild.get to get all members and admins. Guild daos should be automatically verified.
  - We should also have a process to make sure members stay in sync with Guild. How would we do this without authentication?
- **ERC20**
    - Import coingeckos token list
        - https://tokens.coingecko.com/uniswap/all.json
        - Injest this once a day to pick up new tokens
    - Allow users to pick a token from this list and to also put in a custom address. A custom address should look for name and symbol.
    - When a user imports the dao allow, them to add a name for the dao and send a message to the backend with userID, dao name, token address, and admin addresses. We should import all tokenholders as members and push this dao into the verification process.
    - We should also have a process to keep members in sync with on chain data.
- **ERC721**
    - Process should be the same as ERC20, but the token list should be different
    - Does anyone have a good list for this?
- **Disco**
    - Start Disco discovery
    - [Disco Docs](https://docs.disco.xyz/api#operation/credentials)
- **CSV Upload**
    - Accept CSV upload with a max size of 2mb for now, along with the dao name and admins
    - Send a message with the above infor to the backend for processing
    - This should be automatically verified

### Frontend Spec

We are missing the settigns page, we kinda missed this in the first calls around membership and got distracted. Thinking that we'd mimic attestations with a spinner, import create etc. would all come back to their settings. 

#### DAO Profile

- https://linear.app/govrn/issue/PRO-616/dao-card-on-profile-page
- ![](https://hackmd.io/_uploads/BJvmMufDi.png)
  - **Data**:
    - Fetches the user's DAOs (`useDaosList`) -- scoped to connected user
    - `favorite` will need to be added to the GuildFragment once added to the schema
    - `role` will need to be added as well -- the user's current role in the DAO
      - @keating for vis
    - *Join a DAO* -- 
      - Gets list of all verified DAOs on Govrn
        - Can use `useDaosList` with a `where` filter on `verified` once we add that and filter out DAOs user is in
      - User selects verified DAO from list
        - Multi-select similar to the one on the User Dashboard filter?
          - If so, we'd likely iterate through making an update call to each DAO since we don't have a bulk update for DAOs
          - Likely better UX for the user than selecting a single DAO to join each time, although that may be a lighter lift to start for the MVP?
      - Update call setting their role as `recruit` in the chosen DAO
  - **Questions**:
      - If stars are interactive (clicking toggles favorite/not favorite status) we'll need a guild update call on the `onClick`

#### Create/Import DAO

![](https://hackmd.io/_uploads/H1M38o8wi.png)

View with an explainer and the 3 import methods: Guild, token, CSV. 
  - **Data**:
    - Guild:
      - Authenticate via signing a message and get list of available DAOs with `getUserMemberships` to show which DAOs a user can import -> populate a single Select and then user clicks to start the import process:
        - Choose DAO -> click *Import* -> sends message with the `guildId` and `userId`
        - After this is authorized, use `guild.get` to get all Members and Admins
          - This is the list that the user confirms on the *Create DAO* page 
          - We'll need to pass the data received from `guild.get` to a separate route (these imports are confirmed on the Create DAO page as of the current UX)
      - ERC20:
        - Import Coingecko's list and populate an editable Select where user can also add a custom address
          - Existing token: uses values from CG 
          - Adding custom: look up to get the name and symbol from CG
      - ERC721:

- **Questions**:
    - Each import method button -> opens a modal with the necessary fields
    - Connect Guild -> sign message -> populate list of Guilds that user is authorized to import -> choose DAO -> set off import
    - If we're splitting this across 2 routes (import and create) what would be on the Create page if a user lands on it directly? Is the state of that page co-located and depend entirely on what happens in the Import route?

#### Create

  - **Data**:
    - See above questions -- if this page is entirely dependent on the Import page and has no empty state for itself, would it make more sense to have the import page handle the confirmation steps as well? 
      -  > [I think that the UX of having this on a separate page is a lot cleaner, but thinking through implications of it][name=keating]
      - > [per feedback we'll move forward with create and import functionality on the create page.  edit/update are handled on settings page][name=tim]
    - Data will be in the shape of a list of members from the import step (Guild, token, or CSV)
    - Once the data is in, to create a DAO:
      - User adds the DAO's name to a form (required)
      - User toggles which members should be admin vs. contributor
      - `CreateGuild` call with DAO name, members list with each member's role, token address
  - **Questions**:
    - List of members from the import show up on this page -- we'll want to pass the data from import to this page since they're separate routes
    - After successfully creating a DAO, where would the user view it to update the settings?

#### Update/Edit DAO AKA settings

![](https://hackmd.io/_uploads/HycoJoUvo.png)





### Test Resources & Repo link

- **Provide link once created. Provide links to any test resources associated with this project via Linear/Figma comments**

### Definition of Done

- ***Outline what is required to consider this task complete. It’s necessary to have alignment on the definition of done.***

## Metrics

- ***What metrics do you want enabled as part of this feature? Each metric should be related to answering at least one future question on how to adapt the feature***

          -         Import all 
    - Should hould If we're splitting the is across two 2 routes ()import and create ahwwhat would be on hethe Create page when its notif a user lands on it directly? Does the sattate of that page depend entirely on thewhat happens in the Is co-olocated and Import route?
    - See above questions -- if this page is entirely dependent on the Import page and has no empty state for itself, would be  it Similar considerations to ERC20make more sense to have the import page handlee  evethe confirmation steps as well? 
    - I think that the UX of having this on a seprarate page is a cllot cleaner, but thinking through implications of it   
      -     Data eitherData will hab ee in the shape of a list of members from the import step ()Guil, d or , token, or SCVSV
    - Will need Once the data is in, to create a DAO:
    -   ``User adds ``the DOAO's name to the a form ()requi    - User chooses toggles which members are should be admin vs. contributor
      - ``CreateGuild call to backend with mutation with  with callDA DAOnam name, members list awith each member's role, tokentoken address 
      - AFtr fAftrer successfully creting a ating a DAO, where would the user view it to update the settings?
    -       - After successfully creating a DAO, where would the user view it to update the settings?=
    -   Loos lThis loos ks to be the ''**admin functions included here:
      -         - After successfully creating a DAO, where would the user view it to update the settings?
      -         ![Uploading file..._ngo3bbiin]()
![](https://hackmd.io/_uploads/SJpRYh7Pi.png)       
- What would the UI for this look like/ ?
        - How would I'd lielUYser ser would likely nneed to be able to view list of members to gotoggle status role vi?