Account Proof
Account Proof

Account Proof

Verify Account Ownership With a Single Click with Account Proof

ℹ️
Using Account Proof, developers can now verify the account ownership for a user all with a single AuthN click. No longer will there be an additional user_signature or transaction authorization call.

An “account-proof” is a cryptographically signed message generated during authentication to your application that proves a Dapper Wallet user controls a specific Flow account. An account-proof can be used as an authentication mechanism in your application.

The process of requesting and processing an account proof is as follows:

  1. configure your FCL instance with an fcl.accountProof.resolver function that fetches the appIdentifier and cryptographically random nonce from your backend service and sends these values to Dapper Wallet
  2. verify the account-proof data returned by Dapper Wallet against the user’s Flow account on-chain, thereby proving control of that account.

For more information, please refer to Flow’s Proving Authentication documentation.

Configure an accountProof.resolver function

To have your application receive an account-proof during authentication, an account-proof-resolver must be configured in FCL. The configuration specifics will depend upon your application’s specific implementation, but the process is the same: configure FCL with an account-proof-resolver function that fetches an appIdentifier and cryptographic 32-byte random nonce from your application’s backend each time a user attempts to authenticate with the wallet.

💡
See the FCL account-proof documentation for technical details and security considerations, especially regarding the nonce in the Implementation considerations section.

An account-proof-resolver can be configured as follows:

The resolver function must immediately resolve the promise with data that is available locally, rather than fetched from a backend during authentication so that the browser (notably Safari and Firefox) does not block the Dapper Wallet popup. The application backend should still generate and track the nonce.

💡
When your app calls fcl.authenticate or fcl.logIn in response to a user action such as a button click, FCL will first execute the acccount-proof-resolver function, then call window.open to open a popup window to Dapper Wallet. On Safari and Firefox, if the delay between when the user action was performed and when the call to window.open is greater than a certain threshold (exact number unknown, but it is very small), the browser will block the popup.

Depending on the implementation of your application, different strategies can be used to make the AccountProofData available locally in the frontend.

One of the simplest is to load the data on page load, then configure the account-proof-resolver to use this local data:

If a framework such as NextJS is used, the data can be generated server-side and set as Page props:

Your backend will need to store the nonce somehow so that it can later be verified against the account-proof data returned during authentication. How you store this data is up to you, but for a stateless solution, we recommend setting a cookie, which will be sent to your backend when verifying the account proof (this is a similar technique to the double-submit cookie pattern using to prevent CSRF):

Verify the account-proof data

Once the user successfully authenticates with their Dapper Wallet, an account-proof service containing the user-signed message will be available in FCL’s currentUser snapshot. This data should be sent to your backend for verification. If the verification is successful, you can proceed with the login flow, perhaps by setting a session cookie. If the verification is not successful, then the login flow should be halted and an error should be shown to the user:

To verify the account-proof in your application’s backend service:

👋