User onboarding

Motivation

User onboarding is one of the most important user experiences, as it is often one of the first interactions a new user has with a community. Each psibase account has associated configuration data and therefore has an associated storage cost. The challenge is that the value provided by each new user often accrues to a different entity than the one who bears the account creation cost (the infrastructure provider). This asymmetry has caused onboarding experiences to be cumbersome in other distributed app frameworks, and the friction slows the growth of the network.

Goals

The psibase onboarding experience is intended to be comparable to the experience of signing in using OAuth on traditional web applications. It should be simple and immersive. It should allow the entities and organizations who gain from the addition of a new user to subsidize their account creation cost.

User flow

New users shall be onboarded through an invitation process. The default app responsible for the creation of new accounts is called Accounts. Any "invite" services which are permitted to facilitate the creation of a new account must be configured in this service.

Note: The following designs are specifically for providing new accounts to new users. New accounts can be created by existing users simply by allowing them to pay a small amount for additional accounts.

Generic onboarding refers to a process that allows a user to invite another user to the network as a whole, rather than to participate in a particular psibase app.

An existing user may access an invite service, and create an invite. When the invite is created, an HTTP link is generated which can be sent to a recipient. A new psibase account can be redeemed by clicking the link and following the instructions provided in the interface provided by the invite app.

Similarly, Psibase apps can easily expose the ability for users to create invites through their app. When initiated, the app's service creates the invite, and the generated link can be sent to a recipient. By clicking the link, the invitee may join the app to which they were invited, and may optionally create a new psibase account in the process.

After the invitee accepts the invite, they are redirected away from the invite page. If they were only given a generic invite, they will be directed to the root domain page. If they were given an app-specific invite link, they are directed back to either the root page of the app, or to a subpage (configurable by the app).

The user may then proceed to explore the community and its applications with their new user account.

How it works

Embedded in the query string of the generated HTTP link is a private key, generated at the time of the invite. A corresponding invite public key is also saved in a service database. This public key is also known as the invite ID. For example, the query string may look like this: ?id=ABC123&signKey=DEF456.

After the invitee clicks the link, and fills out their new account details in the invite plugin, they submit a transaction that prompts its creation. However, every transaction submitted to a psibase infrastructure provider must have a sender. Therefore, in order to submit this transaction, the invite service provides the account from which the transaction is sent (since the user may not have one yet). This sender account should use a custom auth service which authorizes actions if and only if the transaction is digitally signed with a private key that corresponds to an invite ID.

If the new account uses a PKI authorization service, such as auth-sig, it should not be configured to use the invite ID as its public key, since the invite creator also knows its corresponding private key.

App onboarding

When an app needs to generate an invite link, it can use the generateInvite plugin function of the invite app.

The invite plugin submits an action on behalf of the user to the psibase app's service to initiate the creation of an invite. The app's service should then call into the invite service to create the invite. This ensures that it is the psibase app's service who pays for the invite.

The invite service should allow psibase apps to register with it to configure rate-limiting details such as the number of open invites allowed per user, and the minimum age of an account that is permitted to generate invites.

In addition to the other parameters in the query string, an app invite link may also include a redirect subpage string, for example: ?id=ABC123&signKey=DEF456&redirect=welcome-page. This allows the invite app to redirect the user back to the application that generated the invite link after the user onboarding is completed.

Sequence diagram

The following sequence diagrams gives a rough outline of all the steps required to carry out the successful onboarding of a new user within an application willing to subsidize the invite cost.

sequenceDiagram
    title Creating an invite
    participant App
    participant Invite app
    participant Invite plugin
    participant Auth
    participant App service
    participant Invite service

    note over App: Alice generates<br>an invite
    App->>Invite plugin: generateInvite(alice,<br>"welcome-page")
    note over Invite plugin: Generate keypair<br>{PUB_ABC, PRIV_ABC}
    Invite plugin->>App service: createInvite(alice, <br>PUB_ABC)
    App service->>Invite service: createInvite(<br>PUB_ABC)
    note over Invite service: Invite created
    Invite plugin-->>App: invite link("/invite?id=PUB_ABC<br>&signKey=PRIV_ABC&redirect=welcome-page)
sequenceDiagram
    title Accepting an invite
    participant App
    participant Invite app
    participant Invite plugin
    participant Auth
    participant App service
    participant Invite service

    note over Invite app: Bob uses invite link<br>to submit new user details
    Invite app->>Invite plugin: acceptCreate(bob,<br>PUB_ABC, PRIV_ABC)
    Invite plugin->>Auth: Get keypair<br>for new account
    Auth-->>Invite plugin: {PUB_DEF}
    Invite plugin->>Invite service: acceptCreate(bob,<br>PUB_ABC, PUB_DEF)
    note over Invite service: Creates account
    Note over Invite plugin: Wait for account created
    Invite plugin-->>Invite app: Account created
    Note over Invite app: Redirect Bob to /subpage