Flow Dev Wallet
The Flow Dev Wallet is a mock Flow wallet that simulates the protocols the Flow Client Library (FCL) uses to interact with the Flow blockchain on behalf of simulated user accounts.
This project implements an FCL compatible interface, but should not be used as a reference to build a production grade wallet.
This project should only be used in aid of local development against a locally run instance of the Flow blockchain like the Flow emulator, and should never be used in conjunction with Flow Mainnet, Testnet, or any other instances of Flow.
To see a full list of Flow compatible wallets, visit the Wallets page
Get started
Before you use the dev wallet, you'll need to start the Flow emulator.
Install the flow-cli
The Flow emulator is bundled with the Flow CLI. Instructions for how to install the CLI can be found here: flow-cli/install/
Create a flow.json file
Run this command to create flow.json file (typically in your project's root directory):
_10flow init --config-only
Start the Emulator
To start the Emulator and deploy the contracts, run the following command from the directory that contains flow.json in your project:
_10flow emulator start_10flow project deploy --network emulator
Start the dev wallet
In a separate terminal session, start the dev wallet service.
_10flow dev-wallet
Configure your JavaScript application
The Flow Dev Wallet is designed to be used with @onflow/fcl version 1.0.0 or higher. The FCL package can be installed with: npm install @onflow/fcl or yarn add @onflow/fcl.
To use the dev wallet, configure FCL to point to the address of a locally running Flow emulator and the dev wallet endpoint.
_10import * as fcl from '@onflow/fcl';_10_10fcl_10 .config()_10 // Point App at Emulator REST API_10 .put('accessNode.api', 'http://localhost:8888')_10 // Point FCL at dev-wallet (default port)_10 .put('discovery.wallet', 'http://localhost:8701/fcl/authn');
For a full example refer to Authenticate using FCL snippet
Test harness
It's easy to use this FCL harness app as a barebones app to interact with the dev-wallet during development:
Navigate to http://localhost:8701/harness
Wallet Discovery
Wallet Discoveryoffers a convenient modal and mechanism to authenticate users and connects to all wallets available in the Flow ecosystem.
The following code from Emerald Academy can be added to your React app to turn on Wallet Discovery:
_60import { config, authenticate, unauthenticate, currentUser } from '@onflow/fcl';_60import { useEffect, useState } from 'react';_60_60const fclConfigInfo = {_60 emulator: {_60 accessNode: 'http://127.0.0.1:8888',_60 discoveryWallet: 'http://localhost:8701/fcl/authn',_60 discoveryAuthInclude: [],_60 },_60 testnet: {_60 accessNode: 'https://rest-testnet.onflow.org',_60 discoveryWallet: 'https://fcl-discovery.onflow.org/testnet/authn',_60 discoveryAuthnEndpoint:_60 'https://fcl-discovery.onflow.org/api/testnet/authn',_60 // Adds in Dapper + Ledger_60 discoveryAuthInclude: ['0x82ec283f88a62e65', '0x9d2e44203cb13051'],_60 },_60 mainnet: {_60 accessNode: 'https://rest-mainnet.onflow.org',_60 discoveryWallet: 'https://fcl-discovery.onflow.org/authn',_60 discoveryAuthnEndpoint: 'https://fcl-discovery.onflow.org/api/authn',_60 // Adds in Dapper + Ledger_60 discoveryAuthInclude: ['0xead892083b3e2c6c', '0xe5cd26afebe62781'],_60 },_60};_60_60const network = 'emulator';_60_60config({_60 'walletconnect.projectId': 'YOUR_PROJECT_ID', // your WalletConnect project ID_60 'app.detail.title': 'Emerald Academy', // the name of your DApp_60 'app.detail.icon': 'https://academy.ecdao.org/favicon.png', // your DApps icon_60 'app.detail.description': 'Emerald Academy is a DApp for learning Flow', // a description of your DApp_60 'app.detail.url': 'https://academy.ecdao.org', // the URL of your DApp_60 'flow.network': network,_60 'accessNode.api': fclConfigInfo[network].accessNode,_60 'discovery.wallet': fclConfigInfo[network].discoveryWallet,_60 'discovery.authn.endpoint': fclConfigInfo[network].discoveryAuthnEndpoint,_60 // adds in opt-in wallets like Dapper and Ledger_60 'discovery.authn.include': fclConfigInfo[network].discoveryAuthInclude,_60 'discovery.authn.exclude': ['0x1234567890abcdef'], // excludes chosen wallets by address_60});_60_60export default function App() {_60 const [user, setUser] = useState({ loggedIn: false, addr: '' });_60_60 // So that the user stays logged in_60 // even if the page refreshes_60 useEffect(() => {_60 currentUser.subscribe(setUser);_60 }, []);_60_60 return (_60 <div className="App">_60 <button onClick={authenticate}>Log In</button>_60 <button onClick={unauthenticate}>Log Out</button>_60 <p>{user.loggedIn ? `Welcome, ${user.addr}!` : 'Please log in.'}</p>_60 </div>_60 );_60}
Account or Address creation
You can create a new account with the &Account constructor. When you do this, make sure to specify which account will pay for the creation fees. TO do this, set it as the payer.
The account you choose to pay these fees must have enough money to cover the cost. If it doesn't, the process will stop and the account won't be created.
_14transaction(publicKey: String) {_14 prepare(signer: &Account) {_14 let key = PublicKey(_14 publicKey: publicKey.decodeHex(),_14 signatureAlgorithm: SignatureAlgorithm.ECDSA_P256_14 )_14 let account = Account(payer: signer)_14 account.keys.add(_14 publicKey: key,_14 hashAlgorithm: HashAlgorithm.SHA3_256,_14 weight: 1000.0_14 )_14 }_14}
To create a new Flow account refer to these resources
Get Flow balance
To retrieve the token balance of a specific account, you must write involves write a script that pulls data from onchain. The user may have both locked tokens as well as unlocked so to retrieve the total balance we would aggregate them together.
_34import * as fcl from '@onflow/fcl';_34import * as t from '@onflow/types';_34const CODE = `_34import "FungibleToken"_34import "FlowToken"_34import "LockedTokens"_34_34access(all) fun main(address: Address): UFix64 {_34 let account = getAccount(address)_34 let unlockedVault = account_34 .capabilities.get<&FlowToken.Vault>(/public/flowTokenBalance)_34 .borrow()_34 ?? panic("Could not borrow Balance reference to the Vault"_34 .concat(" at path /public/flowTokenBalance!")_34 .concat(" Make sure that the account address is correct ")_34 .concat("and that it has properly set up its account with a FlowToken Vault."))_34_34 let unlockedBalance = unlockedVault.balance_34 let lockedAccountInfoCap = account_34 .capabilities.get_34 <&LockedTokens.TokenHolder>_34 (LockedTokens.LockedAccountInfoPublicPath)_34 if !(lockedAccountInfoCap!.check()) {_34 return unlockedBalance_34 }_34 let lockedAccountInfoRef = lockedAccountInfoCap!.borrow()!_34 let lockedBalance = lockedAccountInfoRef.getLockedAccountBalance()_34 return lockedBalance + unlockedBalance_34}`;_34export const getTotalFlowBalance = async (address) => {_34 return await fcl.decode(_34 await fcl.send([fcl.script(CODE), fcl.args([fcl.arg(address, t.Address)])]),_34 );_34};
Contribute
To release a new version of Dev Wallet is as simple as tagging and creating a release, a Github Action will then build a bundle of the Dev Wallet that can be used in other tools (such as CLI). If the update of the Dev Wallet is required in the CLI, create a seperate update PR on the CLI. For more information, visit the fcl-dev-wallet GitHub repository.
More
Additionally, you can explore these resources: