/**
* Script: Call CoreDepositWallet.deposit on HyperEVM
* - Approves USDC spending
* - Calls deposit(amount, destinationDex)
*/
import {
createWalletClient,
createPublicClient,
http,
parseUnits,
formatUnits,
type Address,
type Hex,
} from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { hyperliquidEvmTestnet } from "viem/chains";
// -------- Configuration --------
const config = {
privateKey: (process.env.PRIVATE_KEY || "0x") as Hex,
// Contract addresses (HyperEVM Testnet)
coreDepositWallet: "0x0B80659a4076E9E93C7DbE0f10675A16a3e5C206" as Address,
usdcToken: "0x2B3370eE501B4a559b57D449569354196457D8Ab" as Address,
// Transfer parameters
amount: "2", // USDC amount to deposit
// HyperCore destination (0 = perps, 4294967295 = spot)
destinationDex: 0,
};
// -------- Main Function --------
async function main() {
// Validate private key
if (!config.privateKey || config.privateKey === "0x") {
throw new Error("Set PRIVATE_KEY");
}
// Setup account and clients
const account = privateKeyToAccount(config.privateKey);
const publicClient = createPublicClient({
chain: hyperliquidEvmTestnet,
transport: http(),
});
const walletClient = createWalletClient({
chain: hyperliquidEvmTestnet,
transport: http(),
account,
});
const amount = parseUnits(config.amount, 6);
console.log("User:", account.address);
console.log("CoreDepositWallet:", config.coreDepositWallet);
console.log("USDC:", config.usdcToken);
console.log("Amount (USDC):", config.amount);
console.log(
"Destination DEX:",
config.destinationDex === 0 ? "perps" : "spot",
);
// Check USDC balance
const balance = await publicClient.readContract({
address: config.usdcToken,
abi: [
{
name: "balanceOf",
type: "function",
stateMutability: "view",
inputs: [{ name: "account", type: "address" }],
outputs: [{ name: "", type: "uint256" }],
},
],
functionName: "balanceOf",
args: [account.address],
});
if (balance < amount) {
throw new Error(
`Insufficient USDC: have ${formatUnits(balance, 6)}, need ${config.amount}`,
);
}
// Check current allowance
const currentAllowance = await publicClient.readContract({
address: config.usdcToken,
abi: [
{
name: "allowance",
type: "function",
stateMutability: "view",
inputs: [
{ name: "owner", type: "address" },
{ name: "spender", type: "address" },
],
outputs: [{ name: "", type: "uint256" }],
},
],
functionName: "allowance",
args: [account.address, config.coreDepositWallet],
});
// Step 1: Approve if needed
if (currentAllowance < amount) {
console.log("\nApproving USDC spending...");
const hash = await walletClient.writeContract({
address: config.usdcToken,
abi: [
{
name: "approve",
type: "function",
stateMutability: "nonpayable",
inputs: [
{ name: "spender", type: "address" },
{ name: "amount", type: "uint256" },
],
outputs: [{ name: "", type: "bool" }],
},
],
functionName: "approve",
args: [config.coreDepositWallet, amount],
});
console.log("Approve tx hash:", hash);
await publicClient.waitForTransactionReceipt({ hash });
console.log("Approval confirmed");
} else {
console.log("\nSufficient allowance already exists");
}
// Step 2: Deposit
console.log("\nDepositing USDC to HyperCore...");
const hash = await walletClient.writeContract({
address: config.coreDepositWallet,
abi: [
{
name: "deposit",
type: "function",
stateMutability: "nonpayable",
inputs: [
{ name: "amount", type: "uint256" },
{ name: "destinationDex", type: "uint32" },
],
outputs: [],
},
],
functionName: "deposit",
args: [amount, config.destinationDex],
});
console.log("Deposit tx hash:", hash);
// Wait for transaction receipt
const receipt = await publicClient.waitForTransactionReceipt({ hash });
console.log("Status:", receipt.status === "success" ? "SUCCESS" : "FAILED");
console.log(
"Block:",
receipt.blockNumber,
"\nGas Used:",
receipt.gasUsed.toString(),
);
}
// Run
main().catch((error) => {
console.error("Error:", error.message);
process.exit(1);
});