The Flow Client Library (FCL) is a package used to interact with user wallets and the Flow blockchain. When using FCL for authentication, DApps are able to support all FCL-compatible wallets on Flow and their users without any custom integrations or changes needed to the DApp code.
- Min SDK 21+
In build.gradle
of app module, include this dependency
implementation("com.portto.fcl:fcl:x.y.z")
Add
maven("https://jitpack.io")
ormaven { url 'https://jitpack.io' }
to your project'sbuild.gradle
if you haven't. This is required by flow-jvm-sdk.
Add FCL content provider to AndroidManifest.xml
.
<application>
<provider android:authorities="com.portto.fcl.context"
android:name="com.portto.fcl.lifecycle.FCLContentProvider" android:exported="false" />
</application>
To initialize FCL, use the following function:
Fcl.init(
env = Network.TESTNET,
supportedWallets = getWalletList(isMainnet),
appDetail = AppDetail(),
)
- env: The network on which the app was built. i.e.
Network.TESTNET
orNetwork.MAINNET
- supportedWallets: A list of wallet providers supported by the app. See Wallet Discovery for more info.
- appDetail(Optional): The information of the app.
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 lets developers focus on building their DApp and providing as many options as possible to their users.
When you initialize FCL, it's required to provide a list of wallet providers. The following is an
example of adding Blocto
and Dapper
as wallet providers.
listOf(Blocto.getInstance(BLOCTO_TESTNET_APP_ID), Dapper)
- Blocto (Fully supported) Doc
- Dapper Wallet (Support only authn for now)
Once you've initialized FCL, you may use Discovery directly from Discovery UI
or Config
.
The simplest way to integrate Wallet Discovery is to utilize Discovery UI.
// MainActivity.kt
showConnectWalletDialog(this) {
// authentication
}
If you want to create your own authentication UI, the wallet providers are exposed as a list which
can be retrieved from
Fcl.config
.
// Create a custom UI by supplying wallet provider list as data
val providerList = Fcl.config.supportedWallets
// Once you get the user's selected provider, you need to add it to config
Fcl.config.put(Config.Option.SelectedWalletProvider(provider))
In order to interact with Flow blockchain, the current user's information is required. The user's
account address can be easily retrieved by calling Fcl.authenticate()
.
when (val result = Fcl.authenticate()) {
is Result.Success -> {
val address = result.value
}
is Result.Failure -> {
// Handle error
}
}
A common desire that application developers have is to be able to prove that a user controls an on-chain account. Proving ownership of an on-chain account is a way to authenticate a user with an application backend. Fortunately, FCL provides a way to achieve this.
By supplying AccountProofData
to authenticate, the signatures will be acquired and set to the
current user in config
.
when (val result = Fcl.authenticate(accountProofData)) {
is Result.Success -> {
val address = result.value
}
is Result.Failure -> {
// Handle error
}
}
If you've acquired account proof signed data from authenticate
, you may retrieve the signatures
from config
.
val accountProofData = Fcl.currentUser?.accountProofData
Then you can verify the signatures by calling Fcl.verifyAccountProof()
.
when (val result = Fcl.verifyAccountProof(FLOW_APP_IDENTIFIER, accountProofData)) {
is Result.Success -> {
val isValid = reuslt.value
}
is Result.Failure -> {
// Handle error
}
}
Learn more about account proof
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.
To sign a message, simply call Fcl.signUserMessage
.
when (val result = Fcl.signUserMessage(message)) {
is Result.Success -> {
val userSignatures = result.value
}
is Result.Failure -> {
// Handle error
}
}
when (val result = Fcl.verifyUserSignatures(userMessage, userSignatures)) {
is Result.Success -> {
val isValid = reuslt.value
}
is Result.Failure -> {
// Handle error
}
}
Fcl.query()
: Send arbitrary Cadence scripts to the chain and receive back decoded valuesFcl.mutate()
: Send arbitrary transactions with your own signatures or via a user's wallet to perform state changes on chain
Learn more about on-chain interactions
- Get account details from any Flow address
// suspending function
val account: FlowAccount = AppUtils.getAccount(address)
- Get the latest block
// suspending function
val latestBlock: FlowBlock = AppUtils.getLatestBlock()
- Get transaction status
// suspending function
val result = Fcl.getTransactionStatus(transactionId)
To report a specific problem or feature request, open a new issue on Github. For questions, suggestions, or anything else, feel free to join FCL-Android's Discussion.
See the LICENSE file for details.