Proposal for an invitation service to ease onboarding

Invitation service


Circles runs on top of the Gnosis Chain which uses xDai as native gas-currency. New users don’t easily grasp the concept of gas fees. Therefore we try to hide this concept from new users in order to not hurt the adoption due to a complicated onboarding experience.

Before the implementation of this concept, Circles wallets relied on a relayer service that accepted user transactions and payed for the gas in exchange for a small CRC amount. However, the relayer needs to be funded with xDai. Also it is a central service that might be not available when users want to make a transaction.

The invitation service that’s described by this proposal tries to solve most of the above issues. It basically allows users to exchange CRC for a small amount of xDai which they keep on their EOA to pay all fees themselves.

User flows

There are two scenarios that must be considered for the invitaiton service. The first is the inital onboarding of new users. The other one handles the case that a user runs out of xDai after some time when he/her already performed a lot of transactions.

Additionally its possible to inform the creator of an invitation when the invitee redeemed the invitation and completed the setup of the new circles account. Since inviter and invitee usually already know each other, this is a good opportunity for the invitee to establish the first trust connection to the inviter and vice versa.

Onboard a new user

  1. Existing users purchase an invitation code at the invitation service
  2. Inviter sends the code to the invitee e.g. via email or messenger
  3. The invitee redeems the code at the invitation service
  4. The invitation service sends some xDai to the user’s eoa
  5. The invitee uses the received xDai to proceed with the setup (deploying safe, signing-up at the hub, etc.)
  6. The invitee is now a user and can do transactions

Top up the xDai balance

  1. Existing users purchase an invitation code at the invitation service
  2. The buyer of the invitation redeems the invitation to it’s own eoa


The following GraphQL schema describes the queries, mutations and data types the service should provide.
In general, every query and mutation requires a signed challenge as parameter to identify the user/wallet that interacts with the service. The user must request a new challenge for every call to the api.

type Invitation {
    createdAt: Date!
    createdBy: String! # The address of the eoa that created the invitation
    redeemedAt: Date # The point in time when the invitation got redeemed
    redeemedBy: String # The address of the eoa that redeemed the invitation
    code: String! # The invitation code

type PaymentInfo {
    payTo: String! # The address to which the circles should be sent
    payUntil: Date! # The offer is valid until this date
    price: String! # The price of the invitation in CRC

type ErrorResponse {
    reason: String!

union CompletionResponse = ErrorResponse | Invitation

type Redeemed {
    redeemedAt: Date!
    redeemedBy: String!
    transactionHash: String!

union RedemptionResponse = ErrorResponse | Redeemed

type Query {
    challenge: String! # Returns a challenge string that must be signed and included in any request 
    invitations(signedChallenge: String!): [Invitation!]! # Returns a list of all invitations a wallet purchased so far

type Mutation {
    beginPurchase(signedChallenge: String!): PaymentInfo! # Starts the purchase process and returns price and payment information
    completePurchase(signedChallenge: String! transactionHash: String!): CompletionResponse! # Accepts the hash of a CrcHubTransfer transaction and validates if the block is confirmed and if the payed amount is sufficient
    redeemInvitation(signedChallenge: String! code: String!) : RedemptionResponse! # Redeems an invitation code to the address that was restored from the challenge signature


What’s an invitation?

Currently an invitation just equals a small amount of xdai. But in the future an invitation could also include other tokens such as GRT (graph token) for other decentralized services.

Who pays for the invitation?

An invitation can be payed by anyone who got a path to the ‘payTo’ address and enough CRC-balance to pay the ‘price’. That means that users can pay for the invitations of other people as well as for their own. This allows to donate invitations.

Protection from draining

Since the ‘payTo’ address is registered as CRC organization a trust path is required in order to purchase invitations. Other measures like rate limiting etc. could be considered but they can be easily circumvented.

Incentivize funding of the invitation service

Just as the relayer, the invitation service needs to be funded by someone in order to allow the exchange from CRC to xDai. People who fund the invitation pool could be incentivized with an own token. The utility of this token is yet to be discussed.

As always with the kind request for comments :slight_smile:


Thanks Daniel!

The bits will discuss this with the Product owner of and reply further after that.