Onboarding Users on NEAR

NEAR unique account model opens up a pretty amazing opportunity to onboard users who don’t have $NEAR, don’t know what wallets are and still be able to provide them some of the benefits of the blockchain right away.

Here are 3 options in decreasing order of user ownership.

In all examples App runs a frontend, a centralized backend and a contract under app.near name.

Access key account

User comes to the Apps website, and identifies they don’t have a NEAR wallet yet.
App sends them to create an implicit account (e.g. key pair), for which they need to store seed phrase or send that seed phrase to their email/sms.

Note, that Tor.us or Magic.link can replace need to setup a wallet and recovery explicitly and instead allow to login across apps with social logins.

This implicit account doesn’t get represented in any way on chain. It also doesn’t contain any assets at this point.

Coming back to App’s frontend, user requests backend to add this access key to the contract app.near as function call access key. What this means is that user can actually send transactions calling functions on app.near and this contract will pay for these transaction fees.

For example, App allows user to mint some NFTs or create proposals in Sputnik DAO. That NFT or proposal belongs to their account which is identified hex(public_key) (this is special type of account name, called implicit account).

Now user will see these assets in the wallet, explorer can show this information and if user sells their NFT - the resulting money will go to their account.

You can see some different ways to implement this in @mattlockyer great videos:

The benefits of this approach is that it’s fully non custodial on the app’s side. Backend just provides “meta transaction” functionality via the access keys, paying for user’s initial transactions until they get their own funds.

Managed account

Not always you want to send user on a path to create non custodial account right away.
NEAR’s unique account model can provide a way around this.

App frontend/backend allow user to sign up with email/password or social login. This is done in a regular web2 way. While user signs up, they need provide some username. For example illia.

Going forward app proxies all the interaction with blockchain via backend, paying for all the transactions and enacting them from the “admin”'s perspective: minting NFTs, transferring assets, etc.

But instead of using “admin”'s account_id, a illia.app.near is used (e.g. username + contract name). For example user illia received 100 $APP tokens, the app.near contract would record that illia.app.near has 100 tokens. Same with NFTs or anything else.

Note, that illia.app.near account doesn’t really exist on chain. But at the same time, because in NEAR only app.near can create sub account - app can safely manage these accounts. Explorers and read only wallets can still show what account illia.app.near owns as they would index inside the contract itself.

If user wants to move away from managed situation and claim ownership, the backend just allows them to create the account illia.app.near. This would be done by user creating key pair and then asking backend to call a method on app.near like claim_account("illia", "<public_key>").

This account automatically has access to all the assets that were stored under this name both in this contract and any other contracts (for example due to airdrop to all the users of this contract).

In this case user benefits from on chain visibility and activity (airdrops, composability, etc), while not needing the self custodial wallet on day 1. They trust the app to create the account when needed and then become self custodial going forward.

Full custodial

Third option is to store all the data on the backend until the user actually requests it on the blockchain.

E.g. it’s same as in option above but only minting NFTs / depositing assets to the user’s account when user requests to move to self custody.

This way it allows to save on storage and gas fees to the app building, but limits what value user gets out of it until they decide to self custody. E.g. they wouldn’t see their assets in other places or won’t be able to participate passively in other economy.

This covers 3 options of onboarding users who are don’t have assets or not ready for self custody.


Great summary. The magic.com here should probably be https://magic.link/ I think

1 Like

Some Diagrams for

  1. Guest account with sub account name
  2. Guest account with implicit account ID


Account “bb.near” is a normal user. After upgrading, users will become normal users that pay for their own transactions."

In both options it is possible for the app to “never” have the client secret. This is harder to believe in the case of (2).

In (2) names cannot be reserved and asset transfer of tokens (anything not NEAR) is considerably more tricky.

(1) is the preferred method. The use of an additional account “guests.aa.near” is for convenience.

@evgenykuzyakov please check my logic here?

this would be really cool and would work really well for the particular app partner we are discussing w… But I have received some different perspective on if this is truly doable - can @evgenykuzyakov and @mattlockyer confirm?

but more importantly, how easily this is actually discoverable in the explorer as of now? @frol

My other question is around “cost of account”.

As storage would take up some NEAR, I assume once implicit accounts got funded, it would just be as expensive as a normal account? and for a berryclub like app, how much NEAR does the user need to reserve for storage?

additionally, would there be a difference in terms of storage cost between the managed accounts and access key account? what about gas fees per transaction? (still assume the scenario of a berryclub like app)

both of these would be very helpful to finalize the specs of this partner’s app, so really appreciate everyone’s time on this. :pray:

I’m also confused that how the Near explorer could show the assets of illia.app.near via NEAR Explorer | Account, before the account exists on chain.

I am not sure why we aren’t discussing another model as well:

  • app creates real .near account for user but retains full access key
  • app removes full access key when user’s account is funded (e.g. user sells a minted NFT successfully)

This can be implemented either through app backend having full custody to such accounts or through tiny smart contract deployed on accounts for this purpose.

This has an advantage of not having to deal with 2 different types of accounts, transfer assets between virtual and real account, etc. Making overall implementation much simpler on app’s side.

The only disadvantage is that storage fees for account are non-zero. However looks like with the upcoming storage fees reduction we’ll have to lock 0.1 NEAR to have 10kb contract. Which means 100k NEAR is enough to onboard more than 1 million users (I mean that contract can be smaller + accounts with funds can be reclaimed if account still isn’t funded by user within certain time period).

1 Like

Also something to consider is that at planned 10x storage reduction the overhead for storing .near account becomes much less relevant than gas fees (currently I think we need to have 0.25 NEAR on access key to be able to actually make non-trivial contract calls).

1 Like

@amosbestcookie It is not currently discoverable, but we are considering custom support for certain standards (NFT and things like described here)

Though, I agree with Vlad that it would be better if we can leverage native accounts

I’m interested in this model as well. I think that should be yet another demo. It’s easy enough to make Promise call to near account and just create_account. Also super cheap like you said.

We can all agree we need to kill the implicit account model and funding steps. Sponsored accounts should be the way to go.

Nice thing about the sub account model (even though it is a virtual account) is that none of the app assets have to be transferred when the account is upgraded to a real NEAR account. They are in the apps data structures with a full accountId just like a signed in wallet user.

Apps may actually opt for this if they are sponsoring new users, since users will upgrade and end up with their name e.g. vlad.flux vs. vlad.near. It’s kind of like a form of advertising.

1 Like

Another diagram of sub account flows.


Nice thing about the sub account model (even though it is a virtual account) is that none of the app assets have to be transferred when the account is upgraded to a real NEAR account. They are in the apps data structures with a full accountId just like a signed in wallet user.

yeah, I love it far more than pure access key model

1 Like

fully agree that this model makes sense (what should we call it now? :sweat_smile:) especially for apps.

But implicit accounts are still needed for exchange and legacy wallet?

yeah, proposed model completely orthogonal to implicit accounts. It’s more about creating limited accounts on behalf of users with ability to upgrade (similar as other models discussed here but with different trade offs).