import {
createPublicClient,
createWalletClient,
http,
parseEther,
} from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { celoSepolia, sepolia } from "viem/chains";
import {
publicActionsL1,
walletActionsL2,
walletActionsL1,
publicActionsL2,
} from "viem/op-stack";
const account = privateKeyToAccount(
"[PRIVATE_KEY]",
);
const value = parseEther("0.0001"); // Amount to Withdraw
export const publicClientL1 = createPublicClient({
chain: sepolia,
transport: http(),
}).extend(publicActionsL1());
export const publicClientL2 = createPublicClient({
chain: celoSepolia,
transport: http(),
}).extend(publicActionsL2());
export const walletClientL1 = createWalletClient({
chain: sepolia,
transport: http(),
account,
}).extend(walletActionsL1());
export const walletClientL2 = createWalletClient({
chain: celoSepolia,
transport: http(),
account,
}).extend(walletActionsL2());
export default async function main() {
console.log("Building Initiate Withdrawal...");
const args = await publicClientL1.buildInitiateWithdrawal({
account,
to: account.address, // Receive on the same address on L1.
value,
});
console.log("Initiaiting Withdrawal...");
const hash = await walletClientL2.initiateWithdrawal(args);
const initiateWithdrawalReceipt = await publicClientL2.waitForTransactionReceipt({
hash
});
console.log(`Withdrawal Initiated: ${initiateWithdrawalReceipt}`);
/**
* The below step can take upto 2 hours!
*
* Hence, you may want to use viem's `getTimeToProve`.
*
* https://viem.sh/op-stack/actions/getTimeToProve
*
* Store the wait time in a database
* and let the user know to come back later.
*
* */
console.log("Waiting to prove...");
const { output, withdrawal } = await publicClientL1.waitToProve({
receipt: initiateWithdrawalReceipt,
targetChain: walletClientL2.chain,
});
console.log("Building Prove Withdrawal...");
const proveArgs = await publicClientL2.buildProveWithdrawal({
output,
withdrawal,
});
console.log("Proving Withdrawal...");
const proveHash = await walletClientL1.proveWithdrawal(proveArgs);
const proveReceipt = await publicClientL1.waitForTransactionReceipt({
hash: proveHash,
});
console.log(`Withdrawal Proved: ${proveReceipt}`);
/**
* The below step can take a few minutes, ideally 2 minutes.
*
* Hence, you may want to use viem's `getTimeToFinalize`.
*
* https://viem.sh/op-stack/actions/getTimeToFinalize
*
* Store the wait time in a database
* and let the user know to come back later.
*
*
*/
console.log("Waiting To Finalize...");
await publicClientL1.waitToFinalize({
targetChain: walletClientL2.chain,
withdrawalHash: withdrawal.withdrawalHash,
});
console.log("Finalizing Withdrawal...");
const finalizeWithdrawalHash = await walletClientL1.finalizeWithdrawal({
targetChain: walletClientL2.chain,
withdrawal,
});
const finalizeWithdrawalReceipt = await publicClientL1.waitForTransactionReceipt({
hash: finalizeWithdrawalHash,
});
console.log(`Withdrawal Finalized: ${finalizeWithdrawalReceipt}`)
}