Skip to content

How to create invite to DAO invite links for the wallet.

Nikolaus Heger edited this page Aug 10, 2023 · 4 revisions

Overview

The invite functionality is simple from a user perspective:

Any user in the DAO who is an enroller - who has the right to enroll members - can create an invite link to invite new people into a DAO.

The wallet consumes the invite link, and calls an action on join.hypha to enroll the member directly into the DAO without having to apply to be a member or be enrolled by an enroller.

Hypha Wallet

The hypha wallet consumes invite / onboarding links the same, they contain an onboarding code which the wallet is using to call a backend to create an account, and it contains an invite code in an "enroll_secret"

The hypha wallet onboarding link contains the following data:

class InviteLinkData {
  final String code;
  final Network network;
  final String? dao;
  final String? enrollSecret;

  const InviteLinkData({required this.code, required this.network, this.dao, this.enrollSecret,});
}

DAO Web App

Invite link specification

The invite link is the same as the onboarding link which we already create, with the addition of a field called enroll_secret.

The link is presented as QR Code to scan with phone, or a URL opened on the phone where it will download the wallet, onboard the user, and enroll the user. The QR code basically just encodes the URL

The URL looks like this:

https://hyphawallet.page.link/?link=https://hypha.earth/invite?code%3D811096b0301a614c%26chain%3DtelosTestnet%26dao%3D219987%26enroll_secret%3D<ENROLL_SECRET>%26env%3Ddev%26apn%3Dearth.hypha.wallet.hypha_wallet%26isi%3D1659926348%26ibi%3Dearth.hypha.wallet.hyphaWallet

The link in link=... is a URL encoded link as follows:

CHAIN = telos | telosTestnet | eos | eosTestnet
DAO_ID = 219987 (the DAOs numeric ID)
INVITE_CODE = invite code from account creator (a string)
ENROLL_SECRET = enroll secret created as below

https://hypha.earth/invite?code=<INVITE_CODE>&chain=<CHAIN>&dao=<DAO_ID>&enroll_secret=<ENROLL_SECRET>&env=dev&apn=earth.hypha.wallet.hypha_wallet&isi=1659926348&ibi=earth.hypha.wallet.hyphaWallet

Creating the invite secret

Process

  1. Create a random string, and hash it -> This is the secret S
  2. Hash the secret again - this is the hashed secret H
  3. Call a blockchain action to write the hashed secret H to chain
  4. Put the secret S into the enroll_secret parameter in the invite link

Create the invite secret

const ecc = require('eosjs-ecc')
const sha256 = ecc.sha256
var crypto = require('crypto');

const generateSecret = async () => {
    // Generate a random secret (32 bytes)
    const secret = new Uint8Array(32);
    crypto.getRandomValues(secret);
  
    // Convert the secret to a checksum256 string
    const secretChecksum256 = await sha256(Buffer.from(secret));
  
    // Hash the secret using SHA256
    // Note: sha256 needs to be called on a byte buffer so we take our secret and convert it
    // back to a byte buffer, then hash that.
    const hashedSecret = sha256(Buffer.from(secretChecksum256, 'hex'))
  
    // verify here: 
    // https://emn178.github.io/online-tools/sha256.html - set input type to "hex"
    console.log('Generated Secret:', secretChecksum256)
    console.log('Hashed Secret:', hashedSecret)
  
    return {
      secret: secretChecksum256,
      hashedSecret
    }
  }
  

Put the hash on chain (need to be enroller to call this)

The smart contract action is defined as: ACTION createinvite(const uint64_t dao_id, const name dao_name, const string dao_fullname, const name inviter, const checksum256 hashed_secret);

Create the following action:

- dao ID, example 219987 for hypha dao eos name, example "hypha" (name limitations apply, 12 characters etc) <dao_fullname> full name as string, e.g. "The Hypha DAO" <hash_of_secret> hash of the secret.

                    {
                        "account": "join.hypha",
                        "name: "createinvite",
                        "authorization: [{
                            "actor": "...........1",
                            "permission": "active",
                        }],
                        data: {
                            "dao_id": <id>,
                            "dao_name": "<name>",
                            "dao_fullname": "<string>",
                            "inviter: "...........1",
                            "hashed_secret": "<hash_of_secret>"
                        },
                    },

Signing this transaction by an enroller will create the hashed secret on chain

Later on the wallet can call redeem on the invite with the actual secret- the contract checks the hash, and consumes the invite.

Clone this wiki locally