Learn the Basics
Learn the Basics

Learn the Basics

Learn the Basics - Technical Guides

The following guides have key information about interacting with Dapper and FCL, and are a must-read prior to going to Mainnet.

1 – Learn the FCL Basics

Ensure you check out the Flow App Quickstart tutorial to learn the essentials of FCL (Flow Client Library)

2 – Add FCL to your project

FCL is available on npm here: https://www.npmjs.com/package/@onflow/fcl

Dapper requires an @onflow/fcl version of at least 0.0.78-alpha.8 or higher.

To install:

3 – Connect FCL to Dapper

Before a user can connect Dapper to an application, FCL must first be configured to communicate with Dapper.

There are two ways to configure FCL for Dapper.

Configuration method 1: hard-code the wallet URI

To connect a Flow-based application with Dapper, FCL must be explicitly configured for Dapper.

The environment variable values will be different between production / mainnet and staging / testnet environments:

For more details on access nodes, please see the Flow documentation on this subject: https://developers.flow.com/nodes/access-api#flow-access-node-endpoints

The wallet discovery endpoints we configured here tells FCL to direct user to the Dapper Wallet login/signup page.

The values for app.detail.title and app.detail.icon are used by Dapper for cosmetic display purposes. At the time of this writing (Dec 13, 2021), only app.detail.title is used during the wallet connection flow. If this value is set, the user will see Connecting to <app.detail.title>.... If not set, the user will see Connecting...

Configuration method 2: use FCL's wallet discovery page

Using this method, FCL will show a pop-up window with a list of supported wallets. Clicking on a specific wallet provider will further configure FCL with details of that wallet.


To enable Dapper Wallet on the discovery page, configure FCL in the following way:

Connect a user's Dapper wallet to the application

Once FCL is configured, a user's Dapper account can be connected by calling fcl.authenticate()

When FCL is configured for Dapper, calling authenticate() will open a new browser window to the specified Dapper URI. authenticate() must be called in the same call stack as the click handler for the button click, or the popup will be blocked by the browser (i.e. you cannot call authenticate() asynchronous to the click handler).

4 – Use FCL to interact with a Dapper user

How to request a transaction signature from a Dapper user

In order for a Cadence transaction to be executed on Flow, it must have the appropriate cryptographic signatures. On Flow, there are 3 types of signatures that must be provided: Proposer, Payer, and one ore more Authorizers See this document for more details:

See the FCL documentation for guidance on how to request transaction signatures from a wallet, including Dapper:

Using FCL, follow the example of this code snippet to submit Dapper transaction through FCL.

⚠️ WARNING: Popup blocking behavior in Safari and Firefox
This warning pertains specifically to Safari and Firefox browsers. Chrome does not currently exhibit this behavior.

FCL will attempt to open a popup window to Dapper to request transaction signatures. Default browser behavior is to block the popup if there is any asynchronous action between when the user clicks the button to request the signature and when the call to fcl.send or fcl.mutate is made.

For example, this code will result in Safari or Firefox blocking the Dapper popup:

Please thoroughly test with Safari/Firefox any code paths that request signatures from Dapper to ensure that the popup is not blocked.

How to query Flow for account information on a Dapper user

Information about a user's Flow account can be queried using Cadence scripts. Scripts do not require authorization from the user and can be accessed from public information made available on their account.

See the FCL documentation on how to send scripts to the chain:

5 – Dapper signing transactions

Dapper signer roles

For Dapper users, the transaction signatures provided will be a mix of the user's keys and Dapper admin keys.

User-provided signatures

A Dapper user will provide a signature for theProposer and possibly an Authorizer. Users do not provide a Payer signature.

An example of a transaction where the user provides both Proposer and Authorizer signatures is the 'initialization' transaction here.

An example of a transaction where the user only provides the Proposer signature here.

Dapper-provided signatures

A Dapper admin account will provide a signature for the Payer and possibly an Authorizer.

By providing the Payer signature, Dapper pays for transaction fees on behalf of its users.

Dapper provides the Authorizer signature when it needs access to private resources in the Dapper Wallet admin account, such as the case when a Dapper user purchases an NFT from a marketplace. See the 'buy listing' transaction here.

Supported transactions on Dapper

Because Dapper is a custodial wallet, transactions signatures will only be provided for specific, known transaction scripts. This is to prevent transactions that are malicious or against our policies from being executed.

As part of the engagement process with marketplaces wishing to integrate with Dapper, the Dapper team will review all marketplace transaction templates to make sure they are compliant with our policies and, in the case of purchase-type transactions, will work with our payment system.

Once the transactions are reviewed and approved by the Dapper team, they will be added to an 'allow-list' on the Dapper platform, which will allow Dapper users to sign them.

6 – Initialize a user's Flow account for a marketplace

A user's Flow account, typically, needs the specific marketplace resources and capabilities to be created in their account in order to be able to execute the Cadence transactions that underpin the marketplace.

For a typical marketplace, two types of resources need to be created:

  • specific NFT resources to be able to store, deposit, and withdraw NFTs
  • an NFT Storefront resource to be able to list NFTs for sale

The NFTStorefront resource only needs to be deployed once per Flow account, so it is unlikely that the marketplace will need to initialize this resource for the user

Capabilities are created on top of these resources that expose specific functionality to allow the marketplace to interact with the user's resources in a secure manner.

Required marketplace resources

A marketplace is responsible for writing the Cadence transactions that will check for, and create if missing, the specific NFT resources and capabilities that are required to interact with the marketplace contracts and transactions.

Whether a marketplace only allows one type of NFT (NBA Top Shot) or allows many different NFT types (VIV3), the process of checking for the specific NFT resource and creating it if it's missing, is largely the same.

NFT Storefront resource

The NFTStorefront resource can handle any type of NFT. During the Dapper account creation process, an NFTStorefront resource will be created in the user's Flow account, so the marketplace should not have to create this for the user. It is recommended that marketplace transactions still check for the existence of this resource.

The NFTStorefront contract, scripts, and transactions are open source:

The Cadence transaction to add this resource and expose capabilities can be found here.

NFT resources

There are two approaches a marketplace may take when attempting to add NFT resources to a user's Flow account:

  • a one-time 'initialization' transaction
  • as part of a transaction that requires the NFT resource to exist, such as a 'Buy NFT' transaction

It is preferable to initialize the user's account as a one-time 'initialization' transaction to ensure can interact with all marketplace transactions (such as gifting, for example).

User initialization transaction

After a user connects their Dapper wallet to the marketplace for the first time, the marketplace can ask the user to sign a transaction that adds the correct resources and capabilities to their Flow account. By initializing the user's Flow account as part of the first-time connection experience, the user is able to receive the marketplace NFTs (again, such as receiving a gift).

If a marketplace deals with multiple type of NFTs, the initialization transaction would add each NFT resource and capability one by one:

As part of a 'buy' transaction

A potential downside of the one-time 'initialization' transaction described above is the extra step a user must take before being able to fully interact with the marketplace transactions. Instead, the NFT resources can be added as part of the 'buy' transaction, if they are missing from the user's account.

Detecting if a user's Flow account is initialized

A marketplace can determine if a user has already initialized their Flow account for the marketplace by querying their on-chain account for the required resources and capabilities.

For example, to check if a specific NFT resource and capability used by the marketplace has been added to a user's Flow account, a marketplace could run the following script, which returns a boolean indicating whether or not the account is initialized.

7 – Initialize the Storefront account

Setting up the Storefront resource

The Flow account that will be selling direct-to-user NFTs will need to create and store a NFTStorefront.Storefront resource, by running this transaction:

Receiving on-chain payments from Dapper users transaction

For marketplaces that will sell from a central Storefront account (e.g direct-to-user, usually used for 'drops' or other non-p2p sales), a special type of fungible token resource will need to be created on the Storefront account in order to integrate with Dapper's payment system.

To receive on-chain payments from a Dapper user, a specific fungible token resources needs to be added to the Storefront account.

A Storefront account is defined here as an account controlled by the marketplace operator, used for direct-to-consumer type sales such as NFT 'drops'.

When a Dapper user purchases an NFT listing from the Storefront, two distinct payment events happen: one off-chain, and one on-chain:

  • Off-chain: a Dapper user can purchase an NFT using Dapper credits, credit cards, ACH payment, and cryptocurrencies from other chains. Dapper collects the user's payment on behalf of the Storefront.
  • On-chain: after collecting the user's off-chain payment, Dapper purchases the NFT on behalf of a user, using an on-chain fungible token called DapperUtilityCoin (DUC). As the name implies, the Dapper Utility Coin is used strictly for utility and has no intrinsic value. Please note, DUC is intended only to be used within Dapper products.

The DUC contract is deployed here:

To receive the payment on-chain in DUC, the Storefront account must create a special resource called a Forwarder. The Forwarder ensures that the Storefront is properly credited for purchases made by Dapper users.

The TokenForwarding contract, which defines the Forwarder resource, is deployed here:

An example of the transaction to run on the Storefront account:

The TokenForwarding.Forwarder resource forwards, or routes, the DUC payment back to the Dapper admin account, such that the Storefront account never actually holds any DUC. Instead, on-chain events are emitted by the TokenForwarding contract whenever a payment in DUC is received. These events are consumed by the Dapper platform to credit the storefront operator with Dapper credits. These credits can later be withdrawn at the storefront operator's request.

8 – List an NFT for sale

Listing an NFT for sale for non-Dapper users

An NFT can be listed for sale by creating a Listing resource in the seller's Flow account. See the following transaction that lists an ExampleNFT.NFT for sale:

Listing an NFT for sale for Dapper users

For a Dapper user to be able to purchase an NFT, the transaction that creates the Listing transaction needs to be different than the above example so that:

  • Dapper users can pay for an NFT using off-chain payment methods, such as Dapper Balance, credit cards, ACH, wires and/or cryptocurrencies on other chains

For example:

9 – Buy an NFT from a marketplace

A Dapper user can purchase an NFT from a marketplace if the NFTStorefront.Listing resource representing the sale was created to accept the Dapper Utility Coin (DUC) as payment. For more info, please see here.

When purchasing an NFT from a compatible marketplace, a Dapper user purchases the NFT using Dapper checkout and an off-chain payment method such as credit card, Dapper credits, ACH, or cryptocurrencies on other chains.

The payment is collected by Dapper on behalf of the marketplace (seller) and Dapper purchases the NFT on behalf of the user (buyer). On-chain, Dapper purchases the Listing with DUC and deposits the NFT in the buyer's NFT collection. The seller receives the payment in the form of Dapper credits.

High-level 'buy NFT' flow

An example buy transaction

10 – Transaction metadata

Transactions can have metadata associated with them in order to display a user-facing description of an underlying Cadence transaction script. Dapper (will) support two types of metadata: off-chain and on-chain.

Off-chain metadata

Off-chain metadata is generic and does not take into account the specifics of a transaction, such as the arguments to it.

For example, many applications require that a user’s Flow account be properly initialized so that it can hold the application’s specific NFTs. A high-level description of such a transaction might read: “Prepare your Flow account for our awesome NFTs.” This would be displayed more prominently than the Cadence transaction script that it describes since most users do not understand Cadence.

On-chain metadata

On the other hand, on-chain metadata can be more specific than off-chain metadata because Dapper can use transaction arguments to query Flow for details about a transaction.

For example, a ‘buy NFT’ transaction will specify transaction arguments such as NFT_ID and price. Dapper can then run a Cadence script, using those argument values, to query for metadata about that particular NFT (if it exists on-chain). A hypothetical NFT might define metadata such as ‘serial number’, ‘edition name’, ‘series name’, etc. which can be queried by NFT_ID. Dapper Checkout then uses this mechanism to populate the Checkout screen with the name, serial number, price, and image of the NFT.

Another example would be listing an NFT for sale. The arguments to this transaction would be similar to the ‘buy NFT’ transaction: the NFT_ID and the price. Dapper can run an on-chain query using these arguments to display a screen to the user listing the NFT for sale with the metadata reading “Do you want to list Furry Octopus #14/100 for $99 USD?” alongside an image of the Furry Octopus. For more details on how Dapper manages assets, please see our FAQ entry titled ‘How do I provide images/assets to Dapper?

11 – On-chain metadata

On-chain metadata is needed for Dapper checkout to ensure that the asset description and price displayed to the user matches the asset description and price on-chain.

For a more bespoke implementation, an NFT contract can define a metadata structure particular to that NFT. For example, the Geniescontract defines metadata using a hierarchy of on-chain structs singletons that are referenced by the NFTs. This allows the metadata to be stored on-chain at minimal cost, as opposed to duplicating and storing the metadata within the NFT resource itself (storing data on-chain incurs storage costs).

In the Genies contract, the only data stored on the NFT itself is the serialNumber, the mintingDate, and a reference to the Edition from which it was minted. The rest of the metadata for an NFT can be retrieved by querying these other structs, using the NFT.id as the starting point.


Metadata in Dapper checkout

For transactions that are eligible for Dapper checkout, Dapper will display purchase details on the checkout UI that is pulled from on-chain NFT metadata. Using arguments to the 'buy' transaction, such as the NFTStorefront.Listing.id, Dapper will query the chain for metadata related to the sale such as NFT name, description, imageURL (url to off-chain image of NFT), and sale price.

For example, the data Dapper references for the purchase of a Genies NFT is:

12 – Flow contract examples

Generic contracts

NFT Storefront

Non Fungible Token

Fungible Token

Specific marketplace contracts

NBA Top Shot


Kitty Items


13 – How to provide images to Dapper

NFT images can be displayed on the Dapper Checkout if they are publicly accessible via HTTP. For optimal performance, we recommend you optimize these images for 150px X 150px and host them on a CDN.