Skip to main content

Signing and Verifying Arbitrary Data

Signing Arbitrary Data

Cryptographic signatures are a key part of the blockchain. They are used to prove ownership of an address without exposing its private key. While primarily used for signing transactions, cryptographic signatures can also be used to sign arbitrary messages.

FCL has a feature that lets you send arbitrary data to a configured wallet/service where the user may approve signing it with their private key/s.

Verifying User Signatures

What makes message signatures more interesting is that we can use Flow blockchain to verify the signatures. Cadence has a built-in function publicKey.verify that will verify a signature against a Flow account given the account address.

FCL includes a utility function, AppUtils.verifyUserSignatures, for verifying one or more signatures against an account's public key on the Flow blockchain.

You can use both in tandem to prove a user is in control of a private key or keys.

This enables cryptographically-secure login flow using a message-signing-based authentication mechanism with a user’s public address as their identifier.


currentUser.signUserMessage()

A method to use allowing the user to personally sign data via FCL Compatible Wallets/Services.

:Note: Requires authentication/configuration with an authorized signing service.

Arguments

NameTypeDescription
messagestringA hexadecimal string to be signed

Returns

TypeDescription
ArrayAn Array of CompositeSignatures: signature

Usage


_10
import * as fcl from "@onflow/fcl"
_10
_10
const signMessage = async () => {
_10
const MSG = Buffer.from("FOO").toString("hex")
_10
try {
_10
return await fcl.currentUser.signUserMessage(MSG)
_10
} catch (error) {
_10
console.log(error)
_10
}
_10
}


AppUtils.verifyUserSignatures

Note

⚠️ fcl.config.flow.network or options override is required to use this API. See FCL Configuration.

A method allowing applications to cryptographically verify the ownership of a Flow account by verifying a message was signed by a user's private key/s. This is typically used with the response from currentUser.signUserMessage.

Arguments

NameTypeDescription
messagestring (required)A hexadecimal string
compositeSignaturesArray (required)An Array of CompositeSignatures
optsObject (optional)opts.fclCryptoContract can be provided to override FCLCryptoContract address for local development

Returns

TypeDescription
Booleantrue if verified or false

Usage


_20
/**
_20
* Verify a valid signature/s for an account on Flow.
_20
*
_20
* @param {string} msg - A message string in hexadecimal format
_20
* @param {Array} compSigs - An array of Composite Signatures
_20
* @param {string} compSigs[].addr - The account address
_20
* @param {number} compSigs[].keyId - The account keyId
_20
* @param {string} compSigs[].signature - The signature to verify
_20
* @param {Object} [opts={}] - Options object
_20
* @param {string} opts.fclCryptoContract - An optional override of Flow account address where the FCLCrypto contract is deployed
_20
* @return {bool}
_20
*
_20
* @example
_20
*
_20
* const isValid = await fcl.AppUtils.verifyUserSignatures(
_20
* Buffer.from('FOO').toString("hex"),
_20
* [{f_type: "CompositeSignature", f_vsn: "1.0.0", addr: "0x123", keyId: 0, signature: "abc123"}],
_20
* {fclCryptoContract}
_20
* )
_20
*/

Examples

Use cases include cryptographic login, message validation, verifiable credentials, and others.