Skip to main content
RapidDev - Software Development Agency
flutterflow-tutorials

How to Integrate Blockchain for Secure Transactions in FlutterFlow

FlutterFlow integrates with Ethereum and EVM-compatible blockchains using the web3dart Flutter package combined with WalletConnect for wallet authentication. Connect a user's MetaMask or WalletConnect-compatible wallet, read smart contract data (token balances, NFT metadata), and send transactions via the user's wallet — never handling private keys in your app. Use Cloud Functions for server-side operations like batch minting.

What you'll learn

  • How to connect a user's crypto wallet to a FlutterFlow app using WalletConnect
  • How to read smart contract data (token balances, NFT tokenURIs) using web3dart
  • How to send a signed transaction from a FlutterFlow app via the user's wallet
  • How to implement token-gated content that only shows when the user holds a specific NFT or token
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Advanced9 min read120-180 minFlutterFlow Free+ (Custom Actions and Custom Widgets required)March 2026RapidDev Engineering Team
TL;DR

FlutterFlow integrates with Ethereum and EVM-compatible blockchains using the web3dart Flutter package combined with WalletConnect for wallet authentication. Connect a user's MetaMask or WalletConnect-compatible wallet, read smart contract data (token balances, NFT metadata), and send transactions via the user's wallet — never handling private keys in your app. Use Cloud Functions for server-side operations like batch minting.

Connect FlutterFlow to Ethereum smart contracts via web3dart and WalletConnect

Blockchain integration in FlutterFlow means reading from and writing to smart contracts on Ethereum or compatible networks (Polygon, Base, Arbitrum). The core rule is that private keys never touch your app — users sign transactions in their own wallet apps (MetaMask mobile, Rainbow, Trust Wallet). Your FlutterFlow app connects via WalletConnect, a protocol that pairs your app with the user's wallet over an encrypted relay. Reading contract data (view functions, token balances, NFT metadata) is free and requires only an RPC endpoint. Writing to the contract (transfers, minting) requires the user to sign and broadcast a transaction from their wallet.

Prerequisites

  • A FlutterFlow project with Custom Actions enabled
  • A WalletConnect Cloud project ID from cloud.walletconnect.com (free account)
  • A deployed smart contract address and ABI (or an existing ERC-20/ERC-721 contract on a testnet)
  • Basic understanding of Ethereum addresses, transactions, and the difference between read (view) and write functions

Step-by-step guide

1

Add web3dart and walletconnect_flutter_v2 to Pubspec Dependencies

In FlutterFlow, go to Custom Code → Pubspec Dependencies. Add two packages: web3dart with version ^2.7.3 and walletconnect_flutter_v2 with version ^2.1.0. Also add http ^1.2.0 if not already present (web3dart uses it for RPC calls). Click Save then Compile Code to verify. The web3dart package handles all Ethereum JSON-RPC calls — reading contract state, encoding function calls, and decoding responses. The walletconnect_flutter_v2 package manages the encrypted pairing session with the user's external wallet app.

Expected result: Both packages compile without errors in the FlutterFlow Custom Code editor.

2

Create the WalletConnect session and wallet connect button

Create a Custom Action named walletConnect. In the action, initialize Web3App from walletconnect_flutter_v2: final wcClient = await Web3App.createInstance(projectId: 'YOUR_WC_PROJECT_ID', metadata: PairingMetadata(name: 'MyApp', description: 'My FlutterFlow App', url: 'https://myapp.com', icons: []));. Call wcClient.connect(requiredNamespaces: {'eip155': RequiredNamespace(chains: ['eip155:1'], methods: ['eth_sendTransaction', 'personal_sign'], events: [])});. This returns a URI — store it in App State variable wcUri. Create a ConnectWallet page with a QR code widget or deep link button. For mobile wallet deep links: launch 'metamask://wc?uri=$wcUri' using Launch URL action. When the user approves in MetaMask, WalletConnect fires a session approval event — in the callback, extract the connected wallet address and store it in App State walletAddress.

Expected result: Tapping the Connect Wallet button opens MetaMask on mobile and displays the connected wallet address after approval.

3

Read contract data — token balance and NFT metadata

Create a Custom Action named readContract. Initialize a Web3Client: final client = Web3Client('https://mainnet.infura.io/v3/YOUR_INFURA_KEY', Client());. Define your contract ABI as a JSON string (just the specific function you need, not the full ABI). For ERC-20 balance: final contract = DeployedContract(ContractAbi.fromJson(erc20Abi, 'ERC20'), EthereumAddress.fromHex(contractAddress));. Call: final result = await client.call(contract: contract, function: contract.function('balanceOf'), params: [EthereumAddress.fromHex(userWalletAddress)]);. The result is a List — result[0] is the BigInt balance. Divide by 10^18 for ETH-decimaled tokens. For NFT tokenURI: same pattern but call 'tokenURI' with the token ID as parameter — returns a string URL to the NFT metadata JSON. Fetch that URL in a second API call to get name, description, and image.

Expected result: The action returns the token balance as a double and stores it in App State for display in the UI.

4

Implement token-gated content

After reading the token balance in step 3, add a conditional in your UI. On your premium content page, add a Backend Query that calls the readContract action on Page Load and stores the result in Page State variable tokenBalance. Add a Conditional Widget that wraps your premium content — show it only when tokenBalance > 0 (or >= minimumRequired). For the locked state, show a Container with text explaining the requirement and a Buy Token button that navigates to a purchase page or launches a DEX URL. Update the condition check on every page visit — do not cache token ownership in Firestore as the user may have sold the token since last visit.

Expected result: Users holding the required token see premium content; users without the token see the upgrade prompt.

5

Send a transaction via the connected wallet

Create a Custom Action named sendTransaction. Retrieve the active WalletConnect session and wallet address from App State. Build the transaction: final tx = Transaction(from: EthereumAddress.fromHex(walletAddress), to: EthereumAddress.fromHex(contractAddress), data: contract.function('transfer').encodeCall([recipientAddress, amountInWei]));. Request the transaction via WalletConnect: wcClient.request(topic: session.topic, chainId: 'eip155:1', request: SessionRequestParams(method: 'eth_sendTransaction', params: [tx.toJson()]));. This sends a signing request to the user's wallet app — the user sees a native transaction confirmation screen with gas estimate. Never create signed transactions yourself — always route through WalletConnect so the private key stays in the user's wallet.

Expected result: Tapping the Send button opens the user's wallet app with a pre-filled transaction for them to approve or reject.

Complete working example

read_token_balance.dart
1// Custom Action: readTokenBalance
2// Pubspec: web3dart: ^2.7.3, http: ^1.2.0
3import 'package:web3dart/web3dart.dart';
4import 'package:http/http.dart' as http;
5
6const String _erc20BalanceOfAbi = '''
7[{
8 "inputs": [{"name": "account", "type": "address"}],
9 "name": "balanceOf",
10 "outputs": [{"name": "", "type": "uint256"}],
11 "stateMutability": "view",
12 "type": "function"
13}]
14''';
15
16Future<double> readTokenBalance(
17 String rpcUrl,
18 String contractAddress,
19 String walletAddress,
20 int tokenDecimals,
21) async {
22 final client = Web3Client(rpcUrl, http.Client());
23
24 try {
25 final contract = DeployedContract(
26 ContractAbi.fromJson(_erc20BalanceOfAbi, 'ERC20'),
27 EthereumAddress.fromHex(contractAddress),
28 );
29
30 final result = await client.call(
31 contract: contract,
32 function: contract.function('balanceOf'),
33 params: [EthereumAddress.fromHex(walletAddress)],
34 );
35
36 final rawBalance = result[0] as BigInt;
37 final divisor = BigInt.from(10).pow(tokenDecimals);
38 final whole = rawBalance ~/ divisor;
39 final fraction = rawBalance % divisor;
40
41 return whole.toDouble() +
42 (fraction.toDouble() / divisor.toDouble());
43 } finally {
44 client.dispose();
45 }
46}

Common mistakes

Why it's a problem: Storing private keys in FlutterFlow App State, Firestore, or Secrets

How to avoid: Never handle private keys in FlutterFlow. Use WalletConnect so the private key stays exclusively in the user's wallet app (MetaMask, Rainbow, Trust Wallet). Your app only submits unsigned transaction requests that the wallet app signs after user confirmation.

Why it's a problem: Calling view functions on every widget build without caching

How to avoid: Read contract state on Page Load and store results in Page State variables. Re-read only when the user explicitly requests a refresh or after a successful write transaction. Cache token balances in App State with a timestamp and skip re-fetching if data is less than 60 seconds old.

Why it's a problem: Assuming a transaction is confirmed because WalletConnect returned a transaction hash

How to avoid: Poll the RPC endpoint with client.getTransactionReceipt(txHash) and wait for a non-null receipt with status == 1 (success) and at least 1 block confirmation before updating app state or Firestore to reflect the completed action.

Best practices

  • Always verify the network chain ID matches your intended network before submitting transactions — sending a mainnet transaction when testing on a testnet can result in real fund loss
  • Show gas cost estimates in the UI before the user taps the transaction button — retrieve gas estimate with client.estimateGas() and convert to ETH at current gas price for display
  • Implement wallet disconnect gracefully: clear walletAddress and the WalletConnect session from App State, and return the user to the Connect Wallet screen
  • Use Polygon (MATIC) or Base for low-cost user-facing transactions — Ethereum mainnet gas fees can exceed the value of small transactions
  • Store NFT metadata (name, description, image URL) in Firestore after the first fetch so repeat visits load instantly from cache instead of re-fetching from IPFS
  • Test all contract interactions on a testnet (Sepolia for Ethereum, Mumbai for Polygon) before deploying to mainnet — testnet tokens are free via faucets
  • Provide a clear fallback for users who do not have a Web3 wallet — explain what MetaMask is and link to installation instructions before showing the Connect Wallet button

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I am building a FlutterFlow app that reads an ERC-721 NFT contract. Write a Dart Custom Action function that uses web3dart to: (1) connect to an Ethereum RPC endpoint, (2) call the balanceOf function to check if a wallet address owns any tokens from a given contract, (3) if balance > 0, call tokenURI for token ID 1 and return the metadata URL. Include the minimal ABI JSON for both functions and proper error handling.

FlutterFlow Prompt

Add a token-gated section to my FlutterFlow app. On the premium content page, check the user's wallet address from App State against the NFT contract using the readContract custom action. If the balance is greater than 0, show the premium content Container. Otherwise, show a locked state Container with a 'Get Access' button that launches the OpenSea URL for the collection.

Frequently asked questions

Do I need to run my own Ethereum node to integrate blockchain in FlutterFlow?

No. Use a managed RPC provider: Infura (free 100K requests/day), Alchemy (free 300M compute units/month), or Ankr (public endpoints with rate limits). Pass the RPC URL to Web3Client in your Custom Action. Running your own node requires significant infrastructure and is unnecessary for app development.

Can I integrate Solana or other non-Ethereum blockchains?

Yes, but the packages differ. For Solana, use the solana Flutter package from pub.dev. For Polygon, Arbitrum, Base, and other EVM-compatible networks, web3dart works identically — just change the RPC URL and chain ID. For completely different architectures like Solana or Near, you will need chain-specific packages and the WalletConnect integration changes slightly.

How do I display NFT images from IPFS in FlutterFlow?

NFT tokenURIs often start with 'ipfs://' which browsers and Flutter Image widgets cannot load directly. Replace the ipfs:// prefix with a public IPFS gateway URL: https://ipfs.io/ipfs/ or https://cloudflare-ipfs.com/ipfs/. Do this transformation in a Custom Function before binding the URL to an Image widget. For better performance, use a pinning service like Pinata that serves your NFT images from a CDN rather than the slow public IPFS network.

Is it safe to show a user's wallet address in the FlutterFlow UI?

Yes — wallet addresses are public by design on the blockchain. Every transaction you make is visible to anyone. The sensitive piece is the private key, which controls the wallet, and that must never be exposed. Displaying, storing in Firestore, or sending the wallet address to your server is standard practice and carries no security risk.

Can I mint NFTs from within a FlutterFlow app?

Yes, minting is a write transaction that calls the mint or safeMint function on your ERC-721 contract. Use the sendTransaction pattern from Step 5 — build the encoded function call with the recipient address parameter and send it through WalletConnect. The user pays the gas fee and approves in their wallet. For free minting (where your server pays gas), use a Cloud Function with a private key stored in Google Secret Manager to sign and broadcast the transaction server-side.

What if my blockchain integration needs are more complex than the tutorial covers?

Custom smart contract interactions with complex ABI encoding, multi-step transaction flows, and cross-chain bridging go beyond the standard tutorial scope. RapidDev has built NFT marketplace, DAO governance, and DeFi dashboard apps in FlutterFlow. If your project requires multi-step contract interactions or a full Web3 wallet experience, reach out for a technical scoping discussion.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.