To get HyperEVM testnet USDC
Use Circle's faucet or transfer USDC from
another chain using the
CCTP sample app.
This guide shows you how to transfer USDC on the HyperEVM testnet. You'll write a simple script that checks your balance and sends a test transfer.
Before you begin, make sure you have:
.env
file.To get HyperEVM testnet USDC
Use Circle's faucet or transfer USDC from
another chain using the
CCTP sample app.
Initialize a new Node.js project and install dependencies:
npm init -y
npm pkg set type=module
npm install viem dotenv
In the project root, create a .env
file with your private key and recipient
address:
PRIVATE_KEY=<YOUR_PRIVATE_KEY>
RECIPIENT_ADDRESS=0x<RECIPIENT_ADDRESS>
Create an index.js
file. You'll add code step by step in the following
sections.
In index.js
, import required modules and define constants for the HyperEVM
testnet and the USDC contract:
import "dotenv/config";
import {
createPublicClient,
createWalletClient,
http,
formatUnits,
parseUnits,
} from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { hyperliquidEvmTestnet } from "viem/chains";
const hyperevmNetwork = hyperliquidEvmTestnet;
const USDC_ADDRESS = "0x2B3370eE501B4a559b57D449569354196457D8Ab";
const USDC_DECIMALS = 6;
const USDC_ABI = [
{
name: "balanceOf",
type: "function",
stateMutability: "view",
inputs: [{ name: "account", type: "address" }],
outputs: [{ name: "", type: "uint256" }],
},
{
name: "transfer",
type: "function",
stateMutability: "nonpayable",
inputs: [
{ name: "to", type: "address" },
{ name: "amount", type: "uint256" },
],
outputs: [{ name: "", type: "bool" }],
},
];
.env
file.balanceOf
and transfer
functions, since they're all
that's needed for this guide.Next, load your private key and recipient address from .env
:
const PRIVATE_KEY_RAW = process.env.PRIVATE_KEY;
const RECIPIENT = process.env.RECIPIENT_ADDRESS;
if (!PRIVATE_KEY_RAW || !RECIPIENT) {
console.error("Error: Missing PRIVATE_KEY or RECIPIENT_ADDRESS in .env");
process.exit(1);
}
if (!/^0x[a-fA-F0-9]{40}$/.test(RECIPIENT)) {
console.error("Error: Recipient address is invalid");
process.exit(1);
}
const PRIVATE_KEY = PRIVATE_KEY_RAW.startsWith("0x")
? PRIVATE_KEY_RAW
: `0x${PRIVATE_KEY_RAW}`;
.env
file so you don't hardcode sensitive information.0x
so Viem can use it.Create a public client for reading blockchain data and a wallet client for sending transactions:
const account = privateKeyToAccount(PRIVATE_KEY);
const publicClient = createPublicClient({
chain: hyperevmNetwork,
transport: http(),
});
const walletClient = createWalletClient({
account,
chain: hyperevmNetwork,
transport: http(),
});
privateKeyToAccount
creates an account object from your private key.createPublicClient
is used for reading data from the blockchain (no private
key needed).createWalletClient
uses your account to sign and send transactions.Now, write the main logic to check your balance and send a transfer:
(async () => {
try {
// Check balance
const balance = await publicClient.readContract({
address: USDC_ADDRESS,
abi: USDC_ABI,
functionName: "balanceOf",
args: [account.address],
});
const balanceFormatted = Number(formatUnits(balance, USDC_DECIMALS));
const amount = 1; // send 1 USDC
console.log("Sender:", account.address);
console.log("Recipient:", RECIPIENT);
console.log("Balance:", balanceFormatted);
if (amount > balanceFormatted) {
console.error("Error: Insufficient balance");
process.exit(1);
}
const amountInDecimals = parseUnits(amount.toString(), USDC_DECIMALS);
// Transfer
const hash = await walletClient.writeContract({
address: USDC_ADDRESS,
abi: USDC_ABI,
functionName: "transfer",
args: [RECIPIENT, amountInDecimals],
});
console.log("Transfer successful!");
console.log("Tx hash:", hash);
console.log(
"Explorer:",
`${hyperevmNetwork.blockExplorers.default.url}/tx/${hash}`,
);
} catch (err) {
console.error("Transfer failed:", err.message || err);
process.exit(1);
}
})();
balanceOf
function.formatUnits
.parseUnits
.transfer
function on the USDC contract to send tokens.After running the script:
node index.js
You'll see output similar to the following:
Sender: 0x1A2b...7890
Recipient: 0x9F8f...1234
Balance: 250.0
Transfer successful!
Tx hash: 0xabc123...def456
Explorer: https://<hyperliquid-block-explorer>/tx/0xabc123...def456
To verify the transfer, copy the transaction hash URL from the Explorer:
line
and open it in your browser. This will take you to the HyperEVM testnet
explorer, where you can view full transaction details.
Tip: If your script doesn't output a full explorer URL, you can manually paste the transaction hash into the HyperEVM testnet explorer.
In this quickstart, you learned how to check balances and transfer USDC on HyperEVM using Viem and Node.js. Here are the key points to remember:
.env
. Never commit secrets.balanceOf
and transfer
for
simplicity.