Provable Authn
In order to improve UX/DX and encourage seamless integration with App backends and services, fcl.authenticate has been upgraded.
Additional data is sent in the body of FCL:VIEW:READY:RESPONSE. This data includes what the wallet needs to build a message for signing with the user’s private key/s.
The signature can be returned as part of an optional account-proof service with the FCL:VIEW:RESPONSE.
When provided by the wallet, this signature and additional account-proof data is available to the App via fcl.currentUser services. The service data can be used to recreate the message, and verify the signature on the Flow Blockchain.
For example, it can be sent to the App’s backend and after validating the signature and the other account-proof data, it can safely associate the included account address to a user and log them in.
TL;DR Wallet Provider
- Wallet receives Authn FCL:VIEW:READY:RESPONSErequest and parses out theappIdentifier, andnonce.
- The wallet authenticates the user however they choose to do, and determines the user's account address
- The wallet must validate the appIdentifieragainst the RFC 6454 origin of the request if it matches the format of a RFC 3986 URI. Requests with a mismatch should be rejected. Some legacy systems may use arbitrary strings asappIdentifierand not RFC 6454 origins. In this case, wallets should display a warning to the user that the app identifier does not match the origin of the request.
- Wallet prepares and signs the message:
- Encodes the appIdentifier,nonce, andaddressalong with the"FCL-ACCOUNT-PROOF-V0.0"domain separation tag, using the encoding scheme described below.
- Signs the message with the signatureAlgorithmandhashAlgorithmspecified on user's key. It is highly recommended that the wallet display the message data and receive user approval before signing.
 
- Encodes the 
- Wallet sends back this new service and data along with the other service configuration when completing Authn.
Account Proof Message Encoding
The account proof message is encoded as follows:
_10MESSAGE = _10  USER_DOMAIN_TAG ||_10  RLP_ENCODE([_10    APP_IDENTIFIER, _10    ADDRESS, _10    NONCE_10  ])
with the following values:
- ACCOUNT_PROOF_DOMAIN_TAGis the constant- "FCL-ACCOUNT-PROOF-V0.0", encoded as UTF-8 byte array and right-padded with zero bytes to a length of 32 bytes.
- APP_IDENTIFIERis an arbitrary length string.
- ADDRESSis a byte array containing the address bytes, left-padded with zero bytes to a length of 8 bytes.
- NONCEis an byte array with a minimum length of 32 bytes.
RLP_ENCODE is a function that performs RLP encoding and returns the encoded value as bytes.
JavaScript Signing Example
_34// Using WalletUtils_34import {WalletUtils} from "@onflow/fcl"_34_34WalletUtils.onMessageFromFcl(_34  (data, {origin}) => {_34    const {address, nonce, appIdentifier} = data.data_34_34    // Check if the appIdentifier is a valid RFC 3986 URI_34    if (!isRfc3986Uri(appIdentifier)) {_34      // Warn the user that the appIdentifier does not match the origin and to proceed with caution_34    } else if (origin !== appIdentifier) {_34      // Reject the request if the appIdentifier is a valid RFC 3986 URI but does not match the origin_34      throw new Error("Invalid appIdentifier")_34    }_34_34    const message = WalletUtils.encodeAccountProof(_34      appIdentifier, // A human readable string to identify your application during signing_34      address,       // Flow address of the user authenticating_34      nonce,         // minimum 32-btye nonce_34    )_34_34    sign(privateKey, message)_34_34    // Without using FCL WalletUtils_34    const ACCOUNT_PROOF_DOMAIN_TAG = rightPaddedHexBuffer(_34      Buffer.from("FCL-ACCOUNT-PROOF-V0.0").toString("hex"),_34      32_34    )_34    const message =  rlp([appIdentifier, address, nonce])_34    const prependUserDomainTag = (message) => ACCOUNT_PROOF_DOMAIN_TAG + message_34_34    sign(privateKey, prependUserDomainTag(message))    _34  }_34)
_17// Authentication Proof Service_17{_17  f_type: "Service",                       // Its a service!_17  f_vsn: "1.0.0",                          // Follows the v1.0.0 spec for the service_17  type: "account-proof",                   // the type of service it is_17  method: "DATA",                          // Its data!_17  uid: "awesome-wallet#account-proof",     // A unique identifier for the service            _17  data: {_17    f_type: "account-proof",_17    f_vsn: "1.0.0"_17    // The user's address (8 bytes, i.e 16 hex characters)_17    address: "0xf8d6e0586b0a20c7",                 _17    // Nonce signed by the current account-proof (minimum 32 bytes in total, i.e 64 hex characters)_17    nonce: "75f8587e5bd5f9dcc9909d0dae1f0ac5814458b2ae129620502cb936fde7120a",_17    signatures: [CompositeSignature],_17  }_17}