Developers
6/10/2021
Inside Flow: The Power of Simplicity with FCL
Flow

Background: Flow is a new blockchain originally designed and developed by Dapper Labs, the makers of CryptoKitties and NBA Top Shot. In this multi-part series, we will explore the different components of Flow blockchain from a technical perspective.

Cadence, the new programming language that makes smart contract development faster, safer
Flow Client Library (FCL), it is analogous to Web3.js on Ethereum, but built for the consumer audience in mind
Flow multi-node architecture, future-proof scaling for the mainstream adoption


Blockchain technology enables new capabilities for developers: the ability to create and program forms of money (cryptocurrencies), mint and distribute limited edition unique assets (NFTs), engage in group governance (DAOs), or simply to mediate authentication and passwordless login (e.g. Magic). 

Just as you need a web browser to access websites on the internet, you need a crypto wallet to access, store, transfer, and otherwise interact with assets and information on blockchains. 

Crypto wallets can be used for authentication even when there’s no payment involved, solving the problem of a million passwords for every different service. 

Crypto wallets are better than social login (Facebook, Apple, etc) because the infrastructure they rely on is fully transparent, and the security is enforced by proven encryption in the user's own control. 

As a result, the interface between apps and wallets is critically important. That’s where the Flow Client Library (FCL) comes in. 

FCL on Flow is analogous to Web3.js on Ethereum, but built for the consumer audience in mind. Rather than rely on Web3, we built FCL because: 

  1. We did not want to depend on “Javascript injection”. The way that Web3 works is that your wallet adds code to your browser so that dapps can ask you to sign transactions. This means you have to use a custom browser (like Brave) or use an extension (like Metamask). This creates a high barrier for consumer-scale adoption, in addition to introducing security concerns.
  2. We didn’t want dapp developers to make premature assumptions on which providers nor the type of platforms their target user base will utilize.  We wanted to make sure that you could write a dapp once, and have it work properly with all kinds of wallets, custodial or self-sovereign, hardware or software, mobile or desktop.

This second point cannot be overstated: with a single line of code, developers can enable their apps to accept both decentralized, cryptocurrency-centric payment methods as well as the more mainstream, USD or fiat currency-centric payment methods chosen by each user

This article teaches you how to leverage the power and speed of FCL after contrasting it with other well-known tools and strategies in blockchain development. Feel free to check out the resources at the end to dive deeper into the possibilities of developing on Flow.

A note on Dapper Labs products: they built NBA Top Shot and the current version of Dapper Wallet before FCL even existed. As a result, NBA Top Shot currently relies on a fully custodial wallet implementation driven through the Go SDK on the backend. Going forward, all Dapper Labs products will begin to migrate to using FCL fully. This means that dapps using FCL will be one step ahead in being ready and compatible for Dapper Wallet once the full “Dapp Store” is ready for action.

Navigating the triangle of delegated trust

Blockchain development is surprisingly easy to get started. Sure, there are some foundational basics to wrap your head around, but once you’ve got your initial moment of enlightenment, things start moving quickly. There are thousands of great tutorials, walking you through how to build the puzzle pieces of what will be the future of the web.

However, the real challenges arise when you begin gluing these pieces together  and start building real world applications for real users. It is only then you’ll find yourself in the middle of the triangle of delegated trust: the communication processes between application, wallet and blockchain.

This delicate axis of communication is also the make-or-break moment for user acceptance  —  if these processes are not well-designed and secure, you will have a hard time onboarding and retaining users. 

Building our popular Ethereum-based application CryptoKitties, our team had to learn this the hard way. Let’s talk about some of the challenges we encountered that eventually inspired us to build products and tools like Flow and FCL.

The issues with browser plugins

When writing blockchain applications, external wallets free you from the responsibility of managing your user’s private keys. A very popular solution on a network like Ethereum are browser plugin wallets like Metamask. If you have integrated Metamask to your application before, chances are you have written code like this: 


 if (window.ethereum) {
    window.web3 = new Web3(window.ethereum);
    await window.ethereum.enable();
  } else if (window.web3) {
    window.web3 = new Web3(window.web3.currentProvider);
  } else {
    window.alert("Non-Ethereum browser detected. Please use MetaMask!");
  }

Here, we are checking if the user has installed the given browser plugin. If not, we direct them towards the installation; else, we continue with the process. This approach poses a problem to developers in two ways: We need to write extra code checking for both possible scenarios, while introducing an element that is beyond our control  —  the initialisation of the wallet on the user’s side.

For the user, this extra step of having to install and set up an external wallet can pose a huge barrier of entry. This greatly increases friction of the process, especially when working with a less tech-savvy audience that is new to blockchain. 

The problem of vendor-specific implementations

Many wallet providers have identified and addressed this issue, especially those focusing on a simpler onboarding experience. Wallets like Fortmatic promise an easier gateway to the blockchain by keeping interactions browser-based and simplifying the setup process. We can integrate Fortmatic into our code by writing something like the following:


import Fortmatic from 'fortmatic';
import Web3 from 'web3';

const fm = new Fortmatic('YOUR_API_KEY');

if (window.ethereum) {
  window.web3 = new Web3(window.ethereum);
} else {
  window.web3 = new Web3(fm.getProvider());
}

if (typeof web3 !== 'undefined') {
  window.web3 = new Web3(web3.currentProvider);
} else {
  window.web3 = new Web3(fm.getProvider());
}

The problem with this implementation is that it's not very clean and does not scale well at all. Our if-else statement is growing as we are checking for different wallet providers. Besides, we also have to take care of setting up a specific Fortmatic provider at the top of the file, injecting an API key that requires some managing, too. Imagine how this already quite verbose code would proliferate if we were to add more wallet providers in the future. 

We can easily see how this puts an ever-growing technical burden onto the developer team as users will continue to expect the support of more wallets. A significant amount of boilerplate code has to be created before writing a single line of application-specific logic. While providing some ease for users, this solution does lead to complications on the developers’ side down the road. 

Introducing FCL: Disrupting with the power of simplicity

The Flow Client Library (FCL) is specifically designed to address those challenges. With FCL, all the steps above boil down to one single line:


fcl.authenticate()

That’s it. That’s essentially everything you have to do in order to authenticate your user from a developer perspective. With a single line you can connect any FCL-compatible wallet to your application - no matter if it’s custodial or self-sovereign, hardware or software, mobile or desktop. And you can easily subscribe to all changes of the current user in just one line, too: 


fcl.currentUser().subscribe()

The magic that allows this simplicity is the integrated wallet discovery protocol. When calling the authenticate method, FCL will automatically discover FCL-compatible wallet providers and fetch the specific configuration for the service the user has chosen. 

In essence, FCL takes care of the heavy-lifting of trustful communication, freeing developers from the responsibility of managing code for different wallet providers. This allows you to focus on the important thing that really matters: Building an application people love.

The building blocks for blockchain interactions

But FCL is much more than just authentication in one line. Being a high-level framework built on top of the Flow Javascript SDK, FCL enables you to create rich interactions with the Flow blockchain. With just a handful of builder functions, customising queries and transactions on the blockchain becomes as easy as arranging lego blocks. There’s one line to remember:


fcl.send([...]).then(fcl.decode)

All the specifics of your given interaction plug into the simplicity of this formula, which takes care of building, resolving, sending and decoding of your interaction in one line. Let’s discover the legos you may insert: 

  • Querying data: scripts
    Use scripts when you want to query data from the blockchain. Script refers to Cadence code that includes the public function main, a function that will be run on execution. As scripts do not mutate data on the blockchain, you will not have to specify any additional information. 

fcl.send([
 fcl.script`
   pub fun main(): Int {
     return 1 + 2
   }
 `
])
  • Mutating data: transactions
    Whenever you want to change data on the blockchain, fcl.transaction is your way to go. For this to work, you will need to provide the transaction method with a Cadence transaction and specify someone who proposes, authorises and pays for the transaction. One of the innovations of Flow is that these roles can be spread across different accounts, but let’s keep it simple by using the current user for all. FCL makes things simple by providing all authorisation details of the current user with fcl.authz:

fcl.send([
 fcl.transaction`
   transaction {
     prepare(acct: AuthAccount) {
       log("Hello from prepare")
     }
     execute {
       log("Hello from execute")
     }
   }
 `,
 fcl.proposer(fcl.authz),
 fcl.authorizations([fcl.authz]),
 fcl.payer(fcl.authz),
])

Injecting arguments into those builder functions is just as easy. Simply add the following lines to any script or transaction that needs to have additional arguments specified:


fcl.args([
 fcl.arg(5, t.Int),
 ...
])

Note that any argument you specify will need to name a specific type as well. You can import these types from the package @onflow/types.

If you want to see all these pieces combined in action, take a look at the Flow app quickstart tutorial, where you will build your first application on Flow:

Flow App Quickstart

Start Building docs.onflow.org

As you can see from these examples, the simplicity of FCL’s architecture allows you to move fast while writing clean, expectable and secure code along the way.

Opinionated yet customisable: The best of both worlds

FCL as a framework dramatically speeds up blockchain development by leveraging the underlying Flow Javascript SDK in an opinionated manner, providing an abstraction layer that simplifies interactions and enforces security best practices. However, it still provides developers with the flexibility to customise the nitty-gritty details any application might need  —  it’s the best of both worlds. 

There are various methods of the original Javascript SDK exposed in FCL, allowing you to use lower-level actions like finding an account by address, getting the status of a specific transaction or querying events emitted by other interactions. Also, methods like decode let you pass in your own custom function, giving you full control of how a response is parsed for your application. 

Because of this versatility, you should choose FCL over the Javascript SDK whenever possible, as it significantly lowers development time and complexity while still accounting for advanced scenarios. The direct usage of the Javascript SDK should be your last resort for complex use cases with frequent low-level blockchain interactions. For example, when building a custodial application that handles the creation of your user’s accounts or when writing developer tools that frequently consume technical metrics of the protocol layer.

Establishing a definite standard for wallet providers

At Flow, we believe in empowering builders that enable creators and innovators. Wallet providers are a good fit for this category, as they enable other creators to build great user experiences without needing to manage private keys. However, this comes at the cost of increased responsibility of those providers, since they are expected to securely support many different use cases.

In order to lessen the pressure on wallet providers, FCL provides a definite standard of blockchain authentication and authorisation, normalising the communication processes between FCL-compatible wallets and FCL-powered applications. Just like other authorisation protocols such as OAuth, it enforces security best practices by clarifying expectations between parties, thereby enabling faster and safer communication procedures.

For wallet providers, this standardisation makes working with Flow straightforward, enabling them to focus on the performance and security of their critical tools. At the same time, it’s a promise for the future: Their wallet will be supported in every single FCL-powered application, without developers having to write vendor-specific code. In this way, wallet applications can get to market faster while consistently increasing their reach to a bigger pool of prospective users.

Conclusion: Flow Client Library (FCL) makes blockchain app development faster, easier, and more secure 


FCL is a better approach for dapps and wallets to talk to each other because: 

  1. FCL does not require a browser extension or additional installation to get users onboarded.
  2. FCL works with custodial and non-custodial wallets equally well, including mobile wallets.
  3. FCL lets developers write cleaner, more concise, and less error-prone code.


With that being said, the best is yet to come: In combination with Flow’s first stablecoin FUSD and third-party providers like Moonpay or Ramp, FCL will be your gateway to easy fiat on and off-ramps, allowing your users to fully engage with your dapp faster and easier than ever. 

FCL is a tool that fits Flow’s overall philosophy: We want to provide a simple yet refined experience for users, developers, and partners alike. It’s about overcoming friction and stimulating creative synergy in order to help you bring the next million users to your blockchain-powered application.

FCL & Flow resources

If you want to dive deeper into the details of FCL and Flow, please refer to the additional resources below. If you run into trouble building applications with FCL and Flow, feel free to reach out to us on the channels listed below — we are more than happy to help.

Inside Flow: The Power of Simplicity with FCL

September 17, 2021

Background: Flow is a new blockchain originally designed and developed by Dapper Labs, the makers of CryptoKitties and NBA Top Shot. In this multi-part series, we will explore the different components of Flow blockchain from a technical perspective.

Cadence, the new programming language that makes smart contract development faster, safer
Flow Client Library (FCL), it is analogous to Web3.js on Ethereum, but built for the consumer audience in mind
Flow multi-node architecture, future-proof scaling for the mainstream adoption


Blockchain technology enables new capabilities for developers: the ability to create and program forms of money (cryptocurrencies), mint and distribute limited edition unique assets (NFTs), engage in group governance (DAOs), or simply to mediate authentication and passwordless login (e.g. Magic). 

Just as you need a web browser to access websites on the internet, you need a crypto wallet to access, store, transfer, and otherwise interact with assets and information on blockchains. 

Crypto wallets can be used for authentication even when there’s no payment involved, solving the problem of a million passwords for every different service. 

Crypto wallets are better than social login (Facebook, Apple, etc) because the infrastructure they rely on is fully transparent, and the security is enforced by proven encryption in the user's own control. 

As a result, the interface between apps and wallets is critically important. That’s where the Flow Client Library (FCL) comes in. 

FCL on Flow is analogous to Web3.js on Ethereum, but built for the consumer audience in mind. Rather than rely on Web3, we built FCL because: 

  1. We did not want to depend on “Javascript injection”. The way that Web3 works is that your wallet adds code to your browser so that dapps can ask you to sign transactions. This means you have to use a custom browser (like Brave) or use an extension (like Metamask). This creates a high barrier for consumer-scale adoption, in addition to introducing security concerns.
  2. We didn’t want dapp developers to make premature assumptions on which providers nor the type of platforms their target user base will utilize.  We wanted to make sure that you could write a dapp once, and have it work properly with all kinds of wallets, custodial or self-sovereign, hardware or software, mobile or desktop.

This second point cannot be overstated: with a single line of code, developers can enable their apps to accept both decentralized, cryptocurrency-centric payment methods as well as the more mainstream, USD or fiat currency-centric payment methods chosen by each user

This article teaches you how to leverage the power and speed of FCL after contrasting it with other well-known tools and strategies in blockchain development. Feel free to check out the resources at the end to dive deeper into the possibilities of developing on Flow.

A note on Dapper Labs products: they built NBA Top Shot and the current version of Dapper Wallet before FCL even existed. As a result, NBA Top Shot currently relies on a fully custodial wallet implementation driven through the Go SDK on the backend. Going forward, all Dapper Labs products will begin to migrate to using FCL fully. This means that dapps using FCL will be one step ahead in being ready and compatible for Dapper Wallet once the full “Dapp Store” is ready for action.

Navigating the triangle of delegated trust

Blockchain development is surprisingly easy to get started. Sure, there are some foundational basics to wrap your head around, but once you’ve got your initial moment of enlightenment, things start moving quickly. There are thousands of great tutorials, walking you through how to build the puzzle pieces of what will be the future of the web.

However, the real challenges arise when you begin gluing these pieces together  and start building real world applications for real users. It is only then you’ll find yourself in the middle of the triangle of delegated trust: the communication processes between application, wallet and blockchain.

This delicate axis of communication is also the make-or-break moment for user acceptance  —  if these processes are not well-designed and secure, you will have a hard time onboarding and retaining users. 

Building our popular Ethereum-based application CryptoKitties, our team had to learn this the hard way. Let’s talk about some of the challenges we encountered that eventually inspired us to build products and tools like Flow and FCL.

The issues with browser plugins

When writing blockchain applications, external wallets free you from the responsibility of managing your user’s private keys. A very popular solution on a network like Ethereum are browser plugin wallets like Metamask. If you have integrated Metamask to your application before, chances are you have written code like this: 


 if (window.ethereum) {
    window.web3 = new Web3(window.ethereum);
    await window.ethereum.enable();
  } else if (window.web3) {
    window.web3 = new Web3(window.web3.currentProvider);
  } else {
    window.alert("Non-Ethereum browser detected. Please use MetaMask!");
  }

Here, we are checking if the user has installed the given browser plugin. If not, we direct them towards the installation; else, we continue with the process. This approach poses a problem to developers in two ways: We need to write extra code checking for both possible scenarios, while introducing an element that is beyond our control  —  the initialisation of the wallet on the user’s side.

For the user, this extra step of having to install and set up an external wallet can pose a huge barrier of entry. This greatly increases friction of the process, especially when working with a less tech-savvy audience that is new to blockchain. 

The problem of vendor-specific implementations

Many wallet providers have identified and addressed this issue, especially those focusing on a simpler onboarding experience. Wallets like Fortmatic promise an easier gateway to the blockchain by keeping interactions browser-based and simplifying the setup process. We can integrate Fortmatic into our code by writing something like the following:


import Fortmatic from 'fortmatic';
import Web3 from 'web3';

const fm = new Fortmatic('YOUR_API_KEY');

if (window.ethereum) {
  window.web3 = new Web3(window.ethereum);
} else {
  window.web3 = new Web3(fm.getProvider());
}

if (typeof web3 !== 'undefined') {
  window.web3 = new Web3(web3.currentProvider);
} else {
  window.web3 = new Web3(fm.getProvider());
}

The problem with this implementation is that it's not very clean and does not scale well at all. Our if-else statement is growing as we are checking for different wallet providers. Besides, we also have to take care of setting up a specific Fortmatic provider at the top of the file, injecting an API key that requires some managing, too. Imagine how this already quite verbose code would proliferate if we were to add more wallet providers in the future. 

We can easily see how this puts an ever-growing technical burden onto the developer team as users will continue to expect the support of more wallets. A significant amount of boilerplate code has to be created before writing a single line of application-specific logic. While providing some ease for users, this solution does lead to complications on the developers’ side down the road. 

Introducing FCL: Disrupting with the power of simplicity

The Flow Client Library (FCL) is specifically designed to address those challenges. With FCL, all the steps above boil down to one single line:


fcl.authenticate()

That’s it. That’s essentially everything you have to do in order to authenticate your user from a developer perspective. With a single line you can connect any FCL-compatible wallet to your application - no matter if it’s custodial or self-sovereign, hardware or software, mobile or desktop. And you can easily subscribe to all changes of the current user in just one line, too: 


fcl.currentUser().subscribe()

The magic that allows this simplicity is the integrated wallet discovery protocol. When calling the authenticate method, FCL will automatically discover FCL-compatible wallet providers and fetch the specific configuration for the service the user has chosen. 

In essence, FCL takes care of the heavy-lifting of trustful communication, freeing developers from the responsibility of managing code for different wallet providers. This allows you to focus on the important thing that really matters: Building an application people love.

The building blocks for blockchain interactions

But FCL is much more than just authentication in one line. Being a high-level framework built on top of the Flow Javascript SDK, FCL enables you to create rich interactions with the Flow blockchain. With just a handful of builder functions, customising queries and transactions on the blockchain becomes as easy as arranging lego blocks. There’s one line to remember:


fcl.send([...]).then(fcl.decode)

All the specifics of your given interaction plug into the simplicity of this formula, which takes care of building, resolving, sending and decoding of your interaction in one line. Let’s discover the legos you may insert: 

  • Querying data: scripts
    Use scripts when you want to query data from the blockchain. Script refers to Cadence code that includes the public function main, a function that will be run on execution. As scripts do not mutate data on the blockchain, you will not have to specify any additional information. 

fcl.send([
 fcl.script`
   pub fun main(): Int {
     return 1 + 2
   }
 `
])
  • Mutating data: transactions
    Whenever you want to change data on the blockchain, fcl.transaction is your way to go. For this to work, you will need to provide the transaction method with a Cadence transaction and specify someone who proposes, authorises and pays for the transaction. One of the innovations of Flow is that these roles can be spread across different accounts, but let’s keep it simple by using the current user for all. FCL makes things simple by providing all authorisation details of the current user with fcl.authz:

fcl.send([
 fcl.transaction`
   transaction {
     prepare(acct: AuthAccount) {
       log("Hello from prepare")
     }
     execute {
       log("Hello from execute")
     }
   }
 `,
 fcl.proposer(fcl.authz),
 fcl.authorizations([fcl.authz]),
 fcl.payer(fcl.authz),
])

Injecting arguments into those builder functions is just as easy. Simply add the following lines to any script or transaction that needs to have additional arguments specified:


fcl.args([
 fcl.arg(5, t.Int),
 ...
])

Note that any argument you specify will need to name a specific type as well. You can import these types from the package @onflow/types.

If you want to see all these pieces combined in action, take a look at the Flow app quickstart tutorial, where you will build your first application on Flow:

Flow App Quickstart

Start Building docs.onflow.org

As you can see from these examples, the simplicity of FCL’s architecture allows you to move fast while writing clean, expectable and secure code along the way.

Opinionated yet customisable: The best of both worlds

FCL as a framework dramatically speeds up blockchain development by leveraging the underlying Flow Javascript SDK in an opinionated manner, providing an abstraction layer that simplifies interactions and enforces security best practices. However, it still provides developers with the flexibility to customise the nitty-gritty details any application might need  —  it’s the best of both worlds. 

There are various methods of the original Javascript SDK exposed in FCL, allowing you to use lower-level actions like finding an account by address, getting the status of a specific transaction or querying events emitted by other interactions. Also, methods like decode let you pass in your own custom function, giving you full control of how a response is parsed for your application. 

Because of this versatility, you should choose FCL over the Javascript SDK whenever possible, as it significantly lowers development time and complexity while still accounting for advanced scenarios. The direct usage of the Javascript SDK should be your last resort for complex use cases with frequent low-level blockchain interactions. For example, when building a custodial application that handles the creation of your user’s accounts or when writing developer tools that frequently consume technical metrics of the protocol layer.

Establishing a definite standard for wallet providers

At Flow, we believe in empowering builders that enable creators and innovators. Wallet providers are a good fit for this category, as they enable other creators to build great user experiences without needing to manage private keys. However, this comes at the cost of increased responsibility of those providers, since they are expected to securely support many different use cases.

In order to lessen the pressure on wallet providers, FCL provides a definite standard of blockchain authentication and authorisation, normalising the communication processes between FCL-compatible wallets and FCL-powered applications. Just like other authorisation protocols such as OAuth, it enforces security best practices by clarifying expectations between parties, thereby enabling faster and safer communication procedures.

For wallet providers, this standardisation makes working with Flow straightforward, enabling them to focus on the performance and security of their critical tools. At the same time, it’s a promise for the future: Their wallet will be supported in every single FCL-powered application, without developers having to write vendor-specific code. In this way, wallet applications can get to market faster while consistently increasing their reach to a bigger pool of prospective users.

Conclusion: Flow Client Library (FCL) makes blockchain app development faster, easier, and more secure 


FCL is a better approach for dapps and wallets to talk to each other because: 

  1. FCL does not require a browser extension or additional installation to get users onboarded.
  2. FCL works with custodial and non-custodial wallets equally well, including mobile wallets.
  3. FCL lets developers write cleaner, more concise, and less error-prone code.


With that being said, the best is yet to come: In combination with Flow’s first stablecoin FUSD and third-party providers like Moonpay or Ramp, FCL will be your gateway to easy fiat on and off-ramps, allowing your users to fully engage with your dapp faster and easier than ever. 

FCL is a tool that fits Flow’s overall philosophy: We want to provide a simple yet refined experience for users, developers, and partners alike. It’s about overcoming friction and stimulating creative synergy in order to help you bring the next million users to your blockchain-powered application.

FCL & Flow resources

If you want to dive deeper into the details of FCL and Flow, please refer to the additional resources below. If you run into trouble building applications with FCL and Flow, feel free to reach out to us on the channels listed below — we are more than happy to help.

Read More

Inside Flow: The Multi-Node Architecture that Scales to Millions

Announcing FLIP Fest, the Flow Buildathon

Partner Spotlight: GigLabs is Building the NFT Bridge for Brands