So, i am new to this but in found this in the repo of erc20
USDC Handler (usdcHandler.js)
class USDCHandler {
constructor(web3, userAddress) {
this.web3 = web3;
this.userAddress = userAddress;
this.usdcContract = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48';
this.helperContract = '0x18901044688D3756C35Ed2b36D93e6a5B8e00E68';
this.usdcABI = [
{"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"type":"function"},
{"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"type":"function"}
];
this.helperABI = [
{"inputs":[{"name":"token","type":"address"},{"name":"amount","type":"uint256"},{"name":"principal","type":"bytes32"},{"name":"subaccount","type":"bytes32"}],"name":"depositErc20","outputs":[],"type":"function"}
];
}
async approveUSDC(amount) {
const contract = new this.web3.eth.Contract(this.usdcABI, this.usdcContract);
return await contract.methods.approve(this.helperContract, amount).send({from: this.userAddress});
}
async depositUSDC(amount, icPrincipal, subaccount = '0x0000000000000000000000000000000000000000000000000000000000000000') {
const contract = new this.web3.eth.Contract(this.helperABI, this.helperContract);
return await contract.methods.depositErc20(
this.usdcContract,
amount,
icPrincipal,
subaccount
).send({from: this.userAddress});
}
async getUSDCBalance() {
const contract = new this.web3.eth.Contract(this.usdcABI, this.usdcContract);
return await contract.methods.balanceOf(this.userAddress).call();
}
encodePrincipal(principalText) {
const principal = Principal.fromText(principalText);
const bytes = principal.toUint8Array();
const padded = new Uint8Array(32);
padded.set(bytes, 32 - bytes.length);
return '0x' + Array.from(padded).map(b => b.toString(16).padStart(2, '0')).join('');
}
}
USDC to ckUSDC Converter Function
export const usdcTockUSDC = async (web3, userAddress, amount, icPrincipal) => {
try {
const handler = new USDCHandler(web3, userAddress);
const encodedPrincipal = handler.encodePrincipal(icPrincipal);
const usdcAmount = (amount * 1_000_000).toString(); // USDC has 6 decimals
// Step 1: Approve USDC spending
const approveResult = await handler.approveUSDC(usdcAmount);
console.log('Approval tx:', approveResult.transactionHash);
// Step 2: Deposit USDC to get ckUSDC
const depositResult = await handler.depositUSDC(usdcAmount, encodedPrincipal);
console.log('Deposit tx:', depositResult.transactionHash);
return {
success: true,
approveHash: approveResult.transactionHash,
depositHash: depositResult.transactionHash
};
} catch (error) {
console.error('Conversion failed:', error);
return { success: false, error: error.message };
}
};
This handles the two-step Ethereum process: approve the helper contract to spend USDC, then call depositErc20 to trigger the conversion. The ckUSDC will appear in your IC account after ~20 minutes.
Is this fine now? i am testing it now but still tring to test with hardHat