Predict
Published in

Predict

How to build an app on Flow blockchain platform?

When the crypto kitties project brought Ethereum to a halt in late 2017 due to congestion, Dapper labs realized that the blockchain currently in use is not designed to handle huge demands. The Dapper team decided to build a blockchain platform on which developers can rely even in immense critical situations.

The Dapper Labs team developed a purpose-built blockchain platform named Flow to support large-scale crypto and NFT collectibles. The Flow blockchain is a decentralized, fast and developer-friendly blockchain built for the next generation of games, apps, collectibles and digital assets. Its architecture helps to achieve the required performance of mainstream applications without sharding the network and without any compromise on decentralization. It enables developers to build secure and composable applications that open new possibilities for customers in every domain.

How to build an app on Flow blockchain?

Start the app development on Flow blockchain using @onflow/fcl. FCL is the Flow Client Library that allows application integration with all FCL compatible wallets and services. Developers with a strong foundation can compose their apps with existing building blocks. FCL enables developers to:

  • Authenticate users
  • Handle transactions
  • Sign transactions via wallet integration
  • Query the Flow blockchain
  • Integrate all compatible wallets

The app development being discussed here does not require any server-side code and is built using create-react-app.

Create React App

Start a new FCL project by executing the following command:

yarn create react-app my-apps

cd my-apps

yarn add @onflow/fcl @onflow/types

FCL’s latest build is @onflow/fcl. @onflow/types are the conversion layer between Javascript and Cadence. It is used when javascript is passed to Cadence scripts and transactions.

Configuration

Create two files ./.env.local and ./src/config.js to hold environment variables locally and also to import and supply them to FCL. In .env.local add the following code:

import {config} from “@onflow/fcl”

config().x

.put(“accessNode.api”, process.env.REACT_ACCESS_NODE)

.put(“challenge.handshake”, process.REACT_WALLET_DISCOVERY)

.put(“0xProfile”, process..REACT_APP_CONTRACT_PROFILE)

The file configures FCL but is not invoked yet. The final step os to import the file. Open ./src/index.js and implement the following:

// File: ./src/index.js import “./config”

import React from “react”

import ReactDOM from “react-dom”

The FCL is configured now.

Authentication

Our application already has authentication. It was implemented when we configured challenge.handshake value.

Now, call the component AuthCluster. It goes to /src/auth-cluster.js. The following code implements the same:

// File: ./src/auth-cluster.js

import React, {useState, useEffect} from “react”

import * as fcl from “@onflow/fcl”

export function AuthCluster() {

const [user, setUser] = useState({loggedIn: null})

useEffect(() => fcl.currentUser().subscribe(setUser), [])

if (user.loggedIn) {

return (

<div>

<span>{user?.addr ?? “No Address”}</span>

<button onClick={fcl.unauthenticate}>Log Out</button>

</div>

)

} else {

return (

<div>

<button onClick={fcl.logIn}>Log In</button>

<button onClick={fcl.signUp}>Sign Up</button>

</div>

)

}

}

It is recommended to import and add AuthCluster to the application in ./src/App.js. Now, run the following:

// File: ./src/Auth.js

import React from “react”

import {AuthCluster} from “./auth-cluster”

export default function App() {

return (

<div> <AuthCluster /> </div>

)

}

Ensure if Flow account is initialized with the profile contract

Call the directory flow. Name the transactions *.tx.js and scripts *.script.js. The first script checks if the account with a particularly given address is initialized with a profile.

mkdir ./src/flow

touch ./src/flow/is-initialized.script.js

The profile Smart contract uses a helper function to check if address is initialized and returns a boolean value.

// File: ./src/flow/is-initialized.script.js

import * as fcl from “@onflow/fcl”

import * as t from “@onflow/types”

export async function isInitialized(address) {

if (address == null)

throw new Error(“isInitialized(address) — address required”)

return fcl

.send([

fcl.script`

import Profile from 0xProfile

pub fun main(address: Address): Bool {

return Profile.check(address)

}

`,

fcl.args([fcl.arg(address, t.Address)]),

])

.then(fcl.decode)

}

Now, we have a reusable script that ensures the account is initialized.

Initialize an account with a profile

A transaction is required to initialize an account with a profile. Transactions are almost similar to scripts.

Create ./src/flow/init-account.tx.js file with the following transaction to initiate the account:

// File: ./src/flow/init-account.tx.js

import * as fcl from “@onflow/fcl”

import * as t from “@onflow/types”

export async function initAccount() {

const txId = await fcl

.send([

fcl.transaction`

import Profile from 0xProfile transaction {

let address: Address

prepare(account: AuthAccount) {

self.address = account.address

if (!Profile.check(self.address)) {

account.save(<- Profile.new(), to: Profile.privatePath)

account.link<&Profile.Base{Profile.Public}>(Profile.publicPath, target: Profile.privatePath)

}

}

post {

Profile.check(self.address): “Account was not initialized”

}

} `,

fcl.payer(fcl.authz),

fcl.proposer(fcl.authz),

fcl.authorizations([fcl.authz]),

fcl.limit(35),

])

.then(fcl.decode)

return fcl.tx(txId).onceSealed()

}

Update profile

Updating information on profile is a transaction.

Transaction from ./src/flow/profile-set-name.tx.js borrows resource from AuthAccount and acts on the resource. The AuthAccount borrows its vault resource. The transaction takes the public capability from FLOW tokens and gets the temporary FLOW token vault.

// File: ./src/flow/profile-set-name.tx.js

import * as fcl from “@onflow/fcl”

import * as t from “@onflow/types”

export async function setName(name) {

const txId = await fcl

.send([

fcl.proposer(fcl.authz),

fcl.payer(fcl.authz),

fcl.authorizations([fcl.authz]),

fcl.limit(35),

fcl.args([fcl.arg(name, t.String)]),

fcl.transaction`

import Profile from 0xProfile

transaction(name: String) {

prepare(account: AuthAccount) {

account

.borrow<&Profile.Base{Profile.Owner}>(from: Profile.privatePath)!

.setName(name)

}

}

`,

])

.then(fcl.decode)

return fcl.tx(txId).onceSealed()

}

Deployment

Ensure that the application is ready for mainnet by confirming the presence of Smart contracts. The Flow team approves the Smart contracts that are deployed. Update all environment variables:

  • REACT_APP_ACCESS_NODE
  • REACT_APP_CONTRACT_PROFILE
  • REACT_APP_WALLET_DISCOVERY

Now, the application will start working on the mainnet.

Flow Client Library allows easy development of cross-platform dApps and is the base for new generation gaming apps and digital assets. Flow has achieved the top blockchain platform position by providing a wide range of SDKs for different programming languages. Anyone planning to build blockchain applications based on Flow must consider hiring an expert blockchain development company to develop a robust and reliable application.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
LeewayHertz

LeewayHertz

Full-stack software development company for startups and enterprises using blockchain, AI, IoT, AR and cloud computing. https://www.leewayhertz.com