Skip to main content
Version: Next

Wallet Discovery

Wallet Discovery

Knowing all the wallets available to users on a blockchain can be challenging. FCL's Discovery mechanism relieves much of the burden of integrating with Flow compatible wallets and let's developers focus on building their dapp and providing as many options as possible to their users.

There are two ways an app can use Discovery:

  1. The UI version which can be configured for display via iFrame, Popup, or Tab.
  2. The API version which allows you to access authentication services directly in your code via fcl.discovery.authn method which we'll describe below.

UI Version

When authenticating via FCL using Discovery UI, a user is shown a list of services they can use to login.

FCL Default Discovery UI

This method is the simplest way to integrate Discovery and its wallets and services into your app. All you have to do is configure discovery.wallet with the host endpoint for testnet or mainnet.

Note: Opt-in wallets, like Ledger and Dapper Wallet, require you to explicitly state you'd like to use them. For more information on including opt-in wallets, see these docs.

A Dapper Wallet developer account is required. To enable Dapper Wallet inside FCL, you need to follow this guide.


_10
import { config } from "@onflow/fcl";
_10
_10
config({
_10
"accessNode.api": "https://rest-testnet.onflow.org",
_10
"discovery.wallet": "https://fcl-discovery.onflow.org/testnet/authn"
_10
})

Any time you call fcl.authenticate the user will be presented with that screen.

To change the default view from iFrame to popup or tab set discovery.wallet.method to POP/RPC (opens as a popup) or TAB/RPC (opens in a new tab). More info about service methods can be found here.

Branding Discovery UI

Starting in version 0.0.79-alpha.4, dapps now have the ability to display app a title and app icon in the Discovery UI by setting a few values in their FCL app config. This branding provides users with messaging that has clear intent before authenticating to add a layer of trust.

All you have to do is set app.detail.icon and app.detail.title like this:


_10
import { config } from "@onflow/fcl";
_10
_10
config({
_10
"app.detail.icon": "https://placekitten.com/g/200/200",
_10
"app.detail.title": "Kitten Dapp"
_10
})

Note: If these configuration options aren't set, Dapps using the Discovery API will still display a default icon and "Unknown App" as the title when attempting to authorize a user who is not logged in. It is highly recommended to set these values accurately before going live.

API Version

If you want more control over your authentication UI, the Discovery API is also simple to use as it exposes Discovery directly in your code via fcl.

Setup still requires configuration of the Discovery endpoint, but when using the API it is set via discovery.authn.endpoint as shown below.


_10
import { config } from "@onflow/fcl"
_10
_10
config({
_10
"accessNode.api": "https://rest-testnet.onflow.org",
_10
"discovery.authn.endpoint": "https://fcl-discovery.onflow.org/api/testnet/authn"
_10
})

You can access services in your Dapp from fcl.discovery:


_10
import * as fcl from "@onflow/fcl"
_10
_10
fcl.discovery.authn.subscribe(callback)
_10
_10
// OR
_10
_10
fcl.discovery.authn.snapshot()

In order to authenticate with a service (for example, when a user click's "login"), pass the selected service to the fcl.authenticate method described here in the API reference:


_10
fcl.authenticate({ service })

A simple React component may end up looking like this:


_14
import "./config"
_14
import { useState, useEffect } from "react"
_14
import * as fcl from "@onflow/fcl"
_14
_14
function Component() {
_14
const [services, setServices] = useState([])
_14
useEffect(() => fcl.discovery.authn.subscribe(res => setServices(res.results)), [])
_14
_14
return (
_14
<div>
_14
{services.map(service => <button key={service.provider.address} onClick={() => fcl.authenticate({ service })}>Login with {service.provider.name}</button>)}
_14
</div>
_14
)
_14
}

Helpful fields for your UI can be found in the provider object inside of the service. Fields include the following:


_13
{
_13
...,
_13
"provider": {
_13
"address": "0xf086a545ce3c552d",
_13
"name": "Blocto",
_13
"icon": "/images/blocto.png",
_13
"description": "Your entrance to the blockchain world.",
_13
"color": "#afd8f7",
_13
"supportEmail": "support@blocto.app",
_13
"authn_endpoint": "https://flow-wallet-testnet.blocto.app/authn",
_13
"website": "https://blocto.portto.io"
_13
}
_13
}

Network Configuration

Discovery UI URLs

EnvironmentExample
Mainnethttps://fcl-discovery.onflow.org/authn
Testnethttps://fcl-discovery.onflow.org/testnet/authn
Localhttps://fcl-discovery.onflow.org/local/authn

Discovery API Endpoints

EnvironmentExample
Mainnethttps://fcl-discovery.onflow.org/api/authn
Testnethttps://fcl-discovery.onflow.org/api/testnet/authn
Localhttps://fcl-discovery.onflow.org/api/local/authn

Note: Local will return Dev Wallet on emulator for developing locally with the default port of 8701. If you'd like to override the default port add ?port=0000 with the port being whatever you'd like to override it to.

Other Configuration

Note: Configuration works across both UI and API versions of Discovery.

Include Opt-In Wallets

Starting in FCL v0.0.78-alpha.10

Opt-in wallets are those that don't have support for authentication, authorization, and user signature services. Or, support only a limited set of transactions.

To include opt-in wallets from FCL:


_10
import * as fcl from "@onflow/fcl"
_10
_10
fcl.config({
_10
"discovery.wallet": "https://fcl-discovery.onflow.org/testnet/authn",
_10
"discovery.authn.endpoint": "https://fcl-discovery.onflow.org/api/testnet/authn",
_10
"discovery.authn.include": ["0x123"] // Service account address
_10
})

Opt-In Wallet Addresses on Testnet and Mainnet

ServiceTestnetMainnet
Dapper Wallet0x82ec283f88a62e650xead892083b3e2c6c
Ledger0x9d2e44203cb130510xe5cd26afebe62781

To learn more about other possible configurations, check out the following links: