How to Create an HBAR Token Faucet for MetaMask | Hedera
Hedera
Network
Services
Token Service
Mint and configure tokens and accounts.
Consensus Service
Verifiable timestamps and ordering of events.
Smart Contracts
Run Solidity smart contracts.
HBAR
The Hedera network's native cryptocurrency.
Insights
How It Works
Learn about Hedera from end to end.
Explorers
View live and historical data on Hedera.
Dashboards
Analyze network activity and metrics.
Network Nodes
Understand networks and node types.
Devs
Start Building
Get Started
Learn core concepts and build the future.
Documentation
Review the API and build using your favorite language.
Developer Resources
Integrations
Plugins and microservices for Hedera.
Fee Estimator
Understand and estimate transaction costs.
Open Source
Hedera is committed to open, transparent code.
Learning Center
Learn about web3 and blockchain technologies.
Grants
Grants & accelerators for your project.
Bounties
Find bugs. Submit a report. Earn rewards.
Ecosystem
ECOSYSTEM
Hedera Ecosystem
Applications, developer tools, network explorers, and more.
NFT Ecosystem Metrics
Analyze on-chain and market NFT ecosystem metrics.
CATEGORIES
Web3 Applications
Connect into the innovative startups decentralizing the web on Hedera.
Enterprise Applications
Learn about the Fortune 500 companies decentralizing the web on Hedera.
Wallets & Custodians
Create a Hedera account to manage HBAR, fungible tokens, and NFTs.
Network Explorers
Hedera mainnet and testnet graphical network explorers.
Developer Tooling
Third-party APIs, integrations, and plugins to build apps on Hedera.
Grants & Accelerators
Boost your project with support from the Hedera ecosystem.
Partner Program
Explore our partners to bring your vision into reality.
Hedera Council
Over 30 highly diversified organizations govern Hedera.
Use Cases
Hedera Solutions
Asset Tokenization Studio
Open source toolkit for tokenizing assets securely.
Stablecoin Studio
All-in-one toolkit for stablecoin solutions.
Hedera Guardian
Auditable carbon markets and traceability.
Functional Use Cases
Data Integrity & AI
Reliable, secure, and ethically governed insights.
Sustainability
Enabling fair carbon markets with trust.
Real-World Asset Tokenization
Seamless tokenization of real-world assets and digital at scale.
Consumer Engagement & Loyalty
Mint, distribute, and redeem loyalty rewards.
Decentralized Identity
Maintain the lifecycle of credentials.
Decentralized Logs
Scalable, real-time timestamped events.
DeFi
Dapps built for the next-generation of finance.
NFTs
Low, fixed fees. Immutable royalties.
Payments
Scalable, real-time, and affordable crypto-payments.
HBAR
Overview
Learn about Hedera's token, HBAR.
Treasury Management
Hedera’s report of the HBAR supply.
Governance
Decentralized Governance
Hedera Council
See the world's leading organizations that own Hedera.
About
Meet Hedera's Board of Directors and team.
Journey
Watch Hedera's journey to build an empowered digital future for all.
Transparent Governance
Public Policy
Hedera's mission is to inform policy and regulation that impact the industry.
Meeting Minutes
Immutably recorded on Hedera.
Roadmap
Follow Hedera's roadmap in its journey to build the future.
Resources
Company
What's New
Partners
Papers
Careers
Media
Blog
Technical
Press
Podcast
Community
Events
Meetups
Store
Brand
Navigation
QUICKSTART
How to Create an HBAR Token Faucet for MetaMask
technical
Apr 03, 2023
by Abi Castro
Enabling the opportunity to connect to a dApp with different wallets provides more control to the user. Recently, HIP-583 added the necessary network infrastructure to support Ethereum Virtual Machine (EVM) wallets on the Hedera network. This added functionality, combined with the auto-create flow described in HIP-32, enables developers to transfer native Hedera Token Service tokens to EVM addresses that do not yet exist on the Hedera network. In this tutorial, we start out with a Hedera react app, connect our dApp to MetaMask, and finally transfer HBAR to the connected MetaMask account.
What we will do:
Create a Hedera react-app Utilizing TypeScript and Material UI
Install MetaMask Chrome Extension
Add Hedera Testnet Network to MetaMask
Connect Our dApp to MetaMask and Retrieve Wallet Address
Install Hedera Hashgraph JS SDK and Create Your Client
Send HBAR to MetaMask Wallet
The complete TypeScript project can be found on GitHub here.
The complete JavaScript project can be found on GitHub here.
How Do I Build an HBAR Faucet for MetaMask?
Step 1: Create a react-app
Open your terminal and run the following command to create a react-app that utilizes TypeScript and Material UI.
npx create-react-app hbar-faucet-testing --template git+ssh://[email protected]/a-ridley/cra-template-hedera-theme.git
Copy
This create react-app theme provides a navbar with a button, footer, react-router, and a global context for state management. We will use this template to kickstart our project.
Open the project in Visual Studio code. Your project directory structure will look like this:
├── node_modules
├── public
├── src
├── .gitignore
├── package-lock.json
├── package.json
├── README.md
└── tsconfig.json
Copy
Step 2: Install MetaMask Chrome Extension
If you have not already installed the MetaMask extension, please install it here.
Step 3: Add Hedera Testnet Network to MetaMask
In this step, we will add the code necessary to add the Hedera Testnet Network to MetaMask so we can connect to it. Before we do that, let’s check out our src folder structure, which looks like this:
src
├── assets
├── components
├── App.tsx
├── AppRouter.tsx
├── Home.tsx
├── index.tsx
├── react-app-env.ts
Copy
Let’s continue and add a new folder inside src and name it services. Inside the services folder, add a file named metamaskService.ts. Your src folder structure will look like this:
src
├── assets
├── components
├── services
├── metamaskServices.ts
├── App.tsx
├── AppRouter.tsx
├── Home.tsx
├── index.tsx
├── react-app-env.ts
Copy
We will store code in the services folder, which will be used to support certain services required to run our application. We added the metamaskService.ts file to hold the code necessary for our MetaMask integration with our application. This distinction helps keep our code organized and clean.
It’s important to note that to add the Hedera Testnet Network to MetaMask, we must determine if MetaMask exists in our browser. We can achieve this by using the window, aka the Browser Object Model (BOM), which represents the browser's window. This window object can access all global JavaScript objects, functions, and variables. If we are successful in accessing the Ethereum object off of the window object, then it is an indication that MetaMask is installed. If it is not successful, then we will handle that by throwing an error message to the console that reads, “MetaMask is not installed! Go install the extension!”
Let's begin!
In our metamaskService.ts file, create a function named switchToHederaNetwork.
export const switchToHederaNetwork = async (ethereum: any) => {
try {
await ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: '0x128' }] // chainId must be in hexadecimal numbers
});
} catch (error: any) {
if (error.code === 4902) {
try {
await ethereum.request({
method: 'wallet_addEthereumChain',
params: [
{
chainName: 'Hedera Testnet',
chainId: '0x128',
nativeCurrency: {
name: 'HBAR',
symbol: 'HBAR',
decimals: 18
},
rpcUrls: ['https://testnet.hashio.io/api']
},
],
});
} catch (addError) {
console.error(addError);
}
}
console.error(error);
}
}
Copy
Let’s digest this function a little further. This function starts by submitting a request to change to the Hedera Testnet Network. If it fails to connect due to the Hedera Testnet not being added to MetaMask, then we will submit a request to add a new chain.
In the request to add a new chain, the decimal value is set to 18 even though HBAR has 8 decimals. The reason for this is because MetaMask only supports chains that have 18 decimals. The rpc url that we use is https://testnet.hashio.io/api, which comes from Hashio, the SwirldsLabs-hosted version of the JSON-RPC Relay.
Step 4: Connect Our dApp to MetaMask and Retrieve Wallet Address
We have added the code necessary to add the Hedera Testnet Network to MetaMask. Now, it's time to focus on adding the code that will allow us to connect to MetaMask.
In the metamaskService.ts file underneath switchToHederaNetwork(), add a new function named connectToMetamask().
// returns a list of accounts
// otherwise empty array
export const connectToMetamask = async () => {
const { ethereum } = window as any;
// keep track of accounts returned
let accounts: string[] = []
if (!ethereum) {
throw new Error("Metamask is not installed! Go install the extension!");
}
switchToHederaNetwork(ethereum);
accounts = await ethereum.request({
method: 'eth_requestAccounts',
});
return accounts;
}
Copy
If MetaMask is installed, connectToMetamask() will call switchToHederaNetwork() and submit a request to get accounts.
Before we do any kind of work or testing, it is important to ensure we are connected to the correct network.
Step 5: Install Hedera Hashgraph JS SDK and Create Your Client
We’ve written the code to connect our application to MetaMask. Now it’s time to send HBAR to our MetaMask wallet.
Install Dependencies
Install hashgraph sdk and dotenv by running the following command in project root directory:
npm install --save @hashgraph/sdk dotenv
Copy
Create your .env file by adding a new file to the root directory of your react-app and naming it .env. Next, add the .env file to your .gitignore to prevent sharing your credentials in source control.
Your .env file will look like this:
REACT_APP_MY_ACCOUNT_ID=
REACT_APP_MY_PRIVATE_KEY=
Copy
In a react-app, your environment variables in your .env file must start with REACT_APP_. Set the values to a Testnet account you created through the Hedera developer portal.
Note: If you need to create a Hedera Testnet account, visit portal.hedera.com and sign up to receive 10,000 test HBAR.
Create Your Client
A client is used to communicate with the network. We create our client for the Hedera Testnet Network, which enables us to submit transactions and pay for them. Let’s create our client in our Home.tsx file.
export default function Home() {
// If we weren't able to grab it, we should throw a new error
if (!process.env.REACT_APP_MY_ACCOUNT_ID || !process.env.REACT_APP_MY_PRIVATE_KEY) {
throw new Error("Environment variables REACT_APP_MY_ACCOUNT_ID and REACT_APP_MY_PRIVATE_KEY must be present");
}
// create your client
const myAccountId = AccountId.fromString(process.env.REACT_APP_MY_ACCOUNT_ID);
const myPrivateKey = PrivateKey.fromString(process.env.REACT_APP_MY_PRIVATE_KEY);
const client = Client.forTestnet();
client.setOperator(myAccountId, myPrivateKey);
return (
Let's buidl a dApp on Hedera
)
}
Copy
Build Your TransferTransaction
In our services folder, add a new file and name it hederaService.ts. This file will hold the code to send HBAR to our MetaMask wallet. Inside the file, let’s create a function and name it sendHbar.
import { AccountId, Client, PrivateKey, TransactionReceiptQuery, TransferTransaction } from "@hashgraph/sdk"
export const sendHbar = async (client:Client, fromAddress: AccountId | string, toAddress: AccountId | string, amount: number, operatorPrivateKey: PrivateKey) => {
const transferHbarTransaction = new TransferTransaction()
.addHbarTransfer(fromAddress, -amount)
.addHbarTransfer(toAddress, amount)
.freezeWith(client);
const transferHbarTransactionSigned = await transferHbarTransaction.sign(operatorPrivateKey);
const transferHbarTransactionResponse = await transferHbarTransactionSigned.execute(client);
// Get the child receipt or child record to return the Hedera Account ID for the new account that was created
const transactionReceipt = await new TransactionReceiptQuery()
.setTransactionId(transferHbarTransactionResponse.transactionId)
.setIncludeChildren(true)
.execute(client);
const childReceipt = transactionReceipt.children[0];
if(!childReceipt || childReceipt.accountId === null) {
console.warn(`No account id was found in child receipt. Child Receipt: ${JSON.stringify(childReceipt, null, 4)}`);
return;
}
const newAccountId = childReceipt.accountId.toString();
console.log(`Account ID of the newly created account: ${newAccountId}`);
}
Copy
This function builds a TransferTransaction that will send a specified amount of HBAR from one account to another account. In our case, our from account is our developer portal account and our to account is our MetaMask wallet address.
Once the transaction is built, we approve it by signing it with our private key by calling .sign(). We call .execute() on our signed transaction using the client to pay for the transaction fee.
When a transaction is executed, the result is of type TransactionResponse. Use the transaction id from the TransactionResponse in a TransactionReceiptQuery to get a TransactionReceipt, including children transactions.
You can learn and read more about parent and child transactions on our documentation site.
Note: For security purposes, the account that is sending the tokens should be on a backend server, but for simplicity, it will be on the frontend. This is a reminder that private keys should never be exposed on the frontend, as that is the easiest way to lose control of your account.
Step 6: Send HBAR to MetaMask Wallet
We’ve written the code necessary to connect our application to MetaMask and added the Hedera Hashgaph JavaScript SDK. Now it’s time to focus on connecting all the parts and sending HBAR to our MetaMask wallet.
6.1 Configure State Management
React has a feature called Context that allows you to easily pass data between components without prop drilling. We will be leveraging this feature to save the MetaMask wallet address and enable us to access it from various components in our react-app.
Let's edit our src/contexts/GlobalAppContext.tsx file, which came with our template, to look like this:
import { createContext, ReactNode, useState } from "react";
const defaultValue = {
metamaskAccountAddress: '',
setMetamaskAccountAddress: (newValue: string) => { },
}
export const GlobalAppContext = createContext(defaultValue)
export const GlobalAppContextProvider = (props: { children: ReactNode | undefined }) => {
const [metamaskAccountAddress, setMetamaskAccountAddress] = useState('')
return (
{props.children}
)
}
Copy
6.2 Add Functionality to the NavBar Button
Once we’ve set up our context, we use it to share application state throughout the app. We use the context by calling useContext() and passing in GlobalAppContext as an argument. This allows us to get and set the wallet address from anywhere in the app.
Add the following code to the top of the file src/components/Navbar.tsx:
export default function NavBar() {
// use the GlobalAppContext to keep track of the metamask account connection
const { metamaskAccountAddress, setMetamaskAccountAddress } = useContext(GlobalAppContext);
Copy
Next, we will create a new function to connect to metamask and store the wallet address in the GlobalAppContext.
const retrieveWalletAddress = async () => {
const addresses = await connectToMetamask();
if (addresses) {
// grab the first wallet address
setMetamaskAccountAddress(addresses[0]);
console.log(addresses[0]);
}
}
Copy
Now we can add an onClick to our button and change the text to say ‘Connect to MetaMask.’ onClick will call retrieveWalletAddress.
Your completed button code will look like this:
Copy
6.3 Add Send HBAR Button
In the Home.tsx file, we will call our global context to gain access to our metamaskAccountAddress state variable.
export default function Home() {
const { metamaskAccountAddress } = useContext(GlobalAppContext);
Copy
Next, add a new button to send HBAR to our MetaMask wallet. After the closing tag , create a material UI button and add onClick. The onClick will call sendHbar(), which is inside src/services/hederaService.ts.
onClick={() => {
sendHbar(client, myAccountId, AccountId.fromEvmAddress(0, 0, metamaskAccountAddress), 7, myPrivateKey)
}}
Copy
The to address will be the metamaskAccountAddress that we pulled out from our context using useContext(GlobalAppContext).
Your completed button code will look like this:
Let's buidl a dApp on Hedera
Copy
We’re ready to run our application! Open a terminal In the root directory of the project and run:
npm run start
Copy
Once up and running, click on the ‘Connect to MetaMask’ button in the upper right-hand corner.
After you click on it, the MetaMask pop-up window will open and you will be asked to switch from your previously connected network to the Hedera Testnet Network.
Choose the account that you would like to connect to this application.
Debugging tip: If you have previously connected your account to this dApp and clicking connect is not opening the wallet, disconnect all the connected accounts and then try again
Once connected, send HBAR by clicking on the ‘SEND HBAR TO METAMASK’ button. You can open your console and see that the transaction response is printed to the console.
Summary
Congratulations! You successfully followed the instructions to build an HBAR faucet for MetaMask. You created a Hedera react-app that integrates with MetaMask. You learned how to build a transfer transaction that sends an amount of HBAR through the Hedera Testnet Network over to a MetaMask account. This can also be applied to other applications, and I encourage all to keep on building.
Happy Building 👷♀️👷♂️
Continue Learning
Create a Hedera Testnet account and receive 10,000 test HBAR every 24 hours!!
Try Tutorials
Join the Developer Discord
Explore The Hedera Learning Center
Share This
Back to blog
What is gRPC, gRPC-Web, and Proxies?
Ed Marquez
Pragmatic Blockchain Design Patterns – Integrating Blockchain into Business Processes
Michiel Mulders
Zero Cost EthereumTransaction on Success: Hedera's New Fee Model for Relay Operators
Oliver Thorn
Hedera Adopts Chainlink Standard for Cross-Chain Interoperability To Accelerate Ecosystem Adoption
Hedera Team
Hedera Developer Highlights March 2025
Michiel Mulders
Hedera Release Cycle Overview
Ed Marquez
View All Posts
Sign up for the newsletter
CONNECT WITH US
Transparency
Open Source
Audits & Standards
Sustainability Commitment
Carbon Offsets
Governance
Hedera Council
Public Policy
Treasury Management
Meeting Minutes
LLC Agreement
Node Requirements
Community
Events
Meetups
HBAR Telegram
Developer Discord
Twitter Community
Support
FAQ
Network Status
Developer Discord
StackOverflow
Brand
Brand Guidelines
Built on Hedera Logo
Hedera Store
About
Team
Partners
Journey
Roadmap
Careers
Contact
General Inquiry
Public Relations
© 2018-2025 Hedera Hashgraph, LLC. All trademarks and company names are the property of their respective owners. All rights in the Deutsche Telekom mark are protected by Deutsche Telekom AG. All rights reserved. Hedera uses the third party marks with permission.
Terms of Use | Privacy Policy