import axios from 'axios';
import {
createPublicClient,
createWalletClient,
http,
erc20Abi,
type Address,
type Hex,
} from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { base } from 'viem/chains';
const API_URL = 'https://li.quest/v1';
// --- Configuration ---
const PRIVATE_KEY = 'YOUR_PRIVATE_KEY';
const RPC_URL = 'https://mainnet.base.org';
const FROM_CHAIN = 8453; // Base
const FROM_TOKEN = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'; // USDC on Base
const TO_TOKEN = '0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A'; // Morpho vault token
const FROM_AMOUNT = '1000000'; // 1 USDC
// --- Setup ---
const account = privateKeyToAccount(PRIVATE_KEY as Hex);
const publicClient = createPublicClient({ chain: base, transport: http(RPC_URL) });
const walletClient = createWalletClient({ account, chain: base, transport: http(RPC_URL) });
// --- Helpers ---
const getQuote = async (fromAddress: string) => {
const result = await axios.get(`${API_URL}/quote`, {
params: {
fromChain: FROM_CHAIN,
toChain: FROM_CHAIN,
fromToken: FROM_TOKEN,
toToken: TO_TOKEN,
fromAmount: FROM_AMOUNT,
fromAddress,
toAddress: fromAddress,
},
});
return result.data;
};
const ensureAllowance = async (
tokenAddress: Address,
approvalAddress: Address,
amount: bigint
) => {
const allowance = await publicClient.readContract({
address: tokenAddress,
abi: erc20Abi,
functionName: 'allowance',
args: [account.address, approvalAddress],
});
if (allowance < amount) {
console.log('Setting allowance...');
const hash = await walletClient.writeContract({
address: tokenAddress,
abi: erc20Abi,
functionName: 'approve',
args: [approvalAddress, amount],
});
await publicClient.waitForTransactionReceipt({ hash });
console.log('Allowance set.');
}
};
// --- Main ---
const run = async () => {
console.log('Wallet:', account.address);
// 1. Get quote
console.log('Requesting Composer quote...');
const quote = await getQuote(account.address);
console.log('Quote received. Tool:', quote.tool);
console.log('Estimated output:', quote.estimate.toAmount);
// 2. Approve
await ensureAllowance(
quote.action.fromToken.address as Address,
quote.estimate.approvalAddress as Address,
BigInt(quote.action.fromAmount)
);
// 3. Execute
console.log('Sending transaction...');
const hash = await walletClient.sendTransaction({
to: quote.transactionRequest.to as Address,
data: quote.transactionRequest.data as Hex,
value: BigInt(quote.transactionRequest.value),
gas: BigInt(quote.transactionRequest.gasLimit),
gasPrice: BigInt(quote.transactionRequest.gasPrice),
});
console.log('Tx hash:', hash);
const receipt = await publicClient.waitForTransactionReceipt({ hash });
console.log('Confirmed in block:', receipt.blockNumber);
console.log('Done! USDC deposited into Morpho vault.');
};
run().catch(console.error);