Ethereum integration in Bubble uses JavaScript embedded in HTML elements to connect MetaMask wallets, read smart contract data, and send blockchain transactions. You load the ethers.js library, prompt users to connect their wallet, call smart contract functions to read data, and initiate transactions that users confirm in MetaMask. This tutorial covers wallet connection, data reading, and transaction sending.
Overview: Ethereum in Bubble
This tutorial shows how to integrate Ethereum blockchain functionality into your Bubble app using JavaScript in HTML elements and the ethers.js library.
Prerequisites
- A Bubble app with user accounts
- MetaMask browser extension installed for testing
- Basic understanding of Ethereum, wallets, and smart contracts
- Toolbox plugin installed for JavaScript-to-Bubble bridge
Step-by-step guide
Load ethers.js and set up the HTML element
Load ethers.js and set up the HTML element
Add an HTML element to your page and load the ethers.js library from CDN. This library provides a clean API for interacting with Ethereum. Create a JavascriptToBubble element for passing data between JavaScript and Bubble workflows.
1<script src="https://cdn.ethers.io/lib/ethers-5.7.umd.min.js"></script>Expected result: The ethers.js library is loaded and ready for Ethereum interactions.
Implement MetaMask wallet connection
Implement MetaMask wallet connection
Add a 'Connect Wallet' button. In an HTML element, write JavaScript that requests MetaMask connection using window.ethereum.request({ method: 'eth_requestAccounts' }). When the user approves, capture their wallet address and pass it to Bubble via JavascriptToBubble. Store the wallet address on the User record for future reference. Show the connected address (abbreviated) in the UI.
1<script>2async function connectWallet() {3 if (typeof window.ethereum !== 'undefined') {4 const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });5 const address = accounts[0];6 // Pass to Bubble via JavascriptToBubble7 bubble_fn_wallet_connected(address);8 } else {9 alert('Please install MetaMask to connect your wallet');10 }11}12</script>Pro tip: Always check if window.ethereum exists before requesting accounts. Show a 'Please install MetaMask' message if it is not found.
Expected result: Users can connect their MetaMask wallet, and their address is stored in Bubble.
Read data from a smart contract
Read data from a smart contract
To read blockchain data (token balance, NFT ownership, contract state), create an ethers.js Contract instance with the contract address and ABI. Call read-only functions (view/pure) which do not require gas or transactions. Pass the results back to Bubble via JavascriptToBubble for display in your UI elements.
1<script>2async function readContract() {3 const provider = new ethers.providers.Web3Provider(window.ethereum);4 const contractAddress = '0x...your_contract...';5 const abi = ['function balanceOf(address) view returns (uint256)'];6 const contract = new ethers.Contract(contractAddress, abi, provider);7 const balance = await contract.balanceOf(userAddress);8 bubble_fn_token_balance(ethers.utils.formatEther(balance));9}10</script>Expected result: Blockchain data from smart contracts displays in Bubble UI elements.
Send transactions through MetaMask
Send transactions through MetaMask
For write operations (transfers, minting, contract interactions), use a signer instead of a provider. The user must approve the transaction in MetaMask and pay gas fees. Create the contract instance with the signer, call the write function, and wait for the transaction to be mined. Pass the transaction hash back to Bubble for recording.
Expected result: Users can initiate blockchain transactions from Bubble that they confirm in MetaMask.
Store wallet data and transaction history in Bubble
Store wallet data and transaction history in Bubble
Create a 'WalletTransaction' Data Type with: user, wallet_address, tx_hash, type (send/receive/contract), amount, status (pending/confirmed/failed), block_number, timestamp. After each transaction, create a record. For transaction status updates, either poll the blockchain periodically or use a webhook service like Alchemy Notify.
Expected result: All blockchain interactions are recorded in Bubble's database for user history and analytics.
Complete working example
1ETHEREUM INTEGRATION — SUMMARY2=================================34LIBRARY: ethers.js v5 (loaded via CDN)5BRIDGE: Toolbox JavascriptToBubble67WALLET CONNECTION:8 Check window.ethereum exists9 Request eth_requestAccounts10 Get address → store on User record11 Display abbreviated address in UI1213READ CONTRACT:14 Provider = Web3Provider(window.ethereum)15 Contract = new Contract(address, abi, provider)16 Call view functions (no gas needed)17 Pass results to Bubble1819SEND TRANSACTION:20 Signer = provider.getSigner()21 Contract = new Contract(address, abi, signer)22 Call write function → MetaMask approval23 Wait for tx.wait() → confirmed24 Store tx_hash in WalletTransaction2526DATA TYPE: WalletTransaction27 user, wallet_address, tx_hash, type,28 amount, status, block_number, timestampCommon mistakes when integrating Ethereum Blockchain in Bubble
Why it's a problem: Not checking if MetaMask is installed before requesting connection
How to avoid: Check 'typeof window.ethereum !== undefined' first and show an installation prompt if missing
Why it's a problem: Storing private keys or seed phrases in Bubble
How to avoid: Only store public wallet addresses in Bubble. All signing happens in MetaMask, never in your app.
Why it's a problem: Not handling network switching (wrong blockchain)
How to avoid: Check the chain ID after connection and prompt users to switch networks if they are on the wrong one
Best practices
- Never store private keys or seed phrases — only public wallet addresses
- Always check for MetaMask installation before requesting connection
- Verify the user is on the correct network (chain ID) before transactions
- Store all transaction hashes in your database for audit and history
- Use read-only calls (view functions) when you only need data, to avoid unnecessary gas costs
- Test on Ethereum testnets (Sepolia, Goerli) before mainnet
- Display clear transaction status (pending, confirmed, failed) to users
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I want to add Ethereum wallet connection to my Bubble.io app so users can connect MetaMask, view their token balance, and send transactions. How do I integrate Web3 functionality?
Add Ethereum blockchain features to my app. Create a Connect Wallet button that links MetaMask. Display the user's ETH balance. Allow sending ETH to another address with MetaMask confirmation. Store transaction history in the database.
Frequently asked questions
Do I need to know Solidity to integrate Ethereum in Bubble?
Not necessarily. You only need Solidity knowledge if building your own smart contracts. For reading existing contracts or sending basic transactions, JavaScript with ethers.js is sufficient.
Can I use this with other blockchains like Polygon or BSC?
Yes. ethers.js works with any EVM-compatible blockchain. Just change the network configuration (chain ID and RPC URL) in your connection code.
How much does it cost users to send transactions?
Users pay Ethereum gas fees for transactions. These vary based on network congestion — typically $0.50-$50 on Ethereum mainnet. Layer 2 solutions like Polygon cost fractions of a cent.
Can I display NFTs owned by the user?
Yes. Use an NFT API (like Alchemy or OpenSea) via the API Connector to fetch the user's NFTs by wallet address, then display them in a Repeating Group.
Can RapidDev help build a Web3 application in Bubble?
Yes. RapidDev can build Web3 applications with wallet integration, smart contract interactions, NFT features, and blockchain data display in Bubble.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation