Skip to content

Commit

Permalink
trying again
Browse files Browse the repository at this point in the history
  • Loading branch information
holic committed May 22, 2024
1 parent 01aee7e commit e1c8a21
Showing 1 changed file with 64 additions and 9 deletions.
73 changes: 64 additions & 9 deletions packages/account-kit/src/steps/deposit/WithdrawButton.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,66 @@
import { useMutation } from "@tanstack/react-query";
import { useMutation, useQuery } from "@tanstack/react-query";
import { useAppAccountClient } from "../../useAppAccountClient";
import { sendTransaction, waitForTransactionReceipt } from "viem/actions";
import { getAction } from "viem/utils";
import { prepareTransactionRequest, readContract, sendTransaction, waitForTransactionReceipt } from "viem/actions";
import { getAction, getChainContractAddress, serializeTransaction } from "viem/utils";
import { Button } from "../../ui/Button";
import { AppAccountClient } from "../../common";
import { useAccount, useBalance } from "wagmi";
import { Hex } from "viem";
import { useAccount, useBalance, useEstimateFeesPerGas, useEstimateGas } from "wagmi";
import { EstimateFeesPerGasReturnType, Hex, maxUint256 } from "viem";
import { gasPriceOracleAbi } from "viem/op-stack/abis";
import { useInvalidateBalance } from "./useInvalidateBalance";
import { estimateL1Fee } from "viem/op-stack";
import { useConfig } from "../../AccountKitConfigProvider";

// TODO: switch network

export function WithdrawButton() {
const invalidateBalance = useInvalidateBalance();
const { chainId } = useConfig();
const { address: userAddress } = useAccount();
const { data: appAccountClient } = useAppAccountClient();
const { data: balance } = useBalance({
chainId: appAccountClient?.chain.id,
address: appAccountClient?.account.address,
});

// TODO: estimate this for real with `estimateTotalGas` and price oracle
const withdrawFee = 100_000_000_000n;
const withdrawAmount = balance ? balance.value - withdrawFee : undefined;
const estimateL2Fee = useEstimateFeesPerGas({ chainId });
// sending value is a constant 21k gas
const withdrawL2Gas = 21000n;

const queryKey = [
"withdrawL1Fee",
appAccountClient?.chain.id,
appAccountClient?.account.address,
userAddress,
balance!.value.toString(),
];
const withdrawL1Fee = useQuery(
appAccountClient && userAddress && balance
? {
queryKey,
queryFn: async () => {
return estimateL1Fee(appAccountClient, {
account: appAccountClient.account,
to: userAddress,
value: balance.value,
// Skip gas estimation of `prepareTransactionRequest` inside `estimateL1Fee`,
// otherwise this will fail due to `balance` not being enough to cover `value` + `fee`.
gas: 0n,
});
},
// TODO: figure out a good refresh rate (L1 block time? L2 commit time?)
refetchInterval: 4_000,
}
: { queryKey, enabled: false },
);

console.log("balance", balance?.value);
console.log("withdrawL1Fee", withdrawL1Fee.status, withdrawL1Fee.data, withdrawL1Fee.error);

const withdrawL2Fee = estimateL2Fee.isSuccess ? withdrawL2Gas * estimateL2Fee.data.maxFeePerGas : undefined;
const withdrawFee = withdrawL1Fee.isSuccess && withdrawL2Fee != null ? withdrawL1Fee.data + withdrawL2Fee : undefined;
const withdrawAmount = balance && withdrawFee != null ? balance.value - withdrawFee : undefined;

// TODO: lift this up so we can conditionally hide the button

const withdraw = useMutation({
Expand All @@ -28,10 +69,14 @@ export function WithdrawButton() {
appAccountClient,
userAddress,
amount,
gas,
fees,
}: {
appAccountClient: AppAccountClient;
userAddress: Hex;
amount: bigint;
gas: bigint;
fees: EstimateFeesPerGasReturnType;
}) => {
console.log("withdrawing funds");
const hash = await getAction(
Expand All @@ -43,6 +88,8 @@ export function WithdrawButton() {
account: appAccountClient.account,
to: userAddress,
value: amount,
gas,
...fees,
});

const receipt = await getAction(
Expand All @@ -61,13 +108,21 @@ export function WithdrawButton() {
<Button
variant="secondary"
className="p-2 text-sm"
pending={userAddress == null || appAccountClient == null || withdrawAmount == null || withdraw.isPending}
pending={
userAddress == null ||
appAccountClient == null ||
withdrawAmount == null ||
withdraw.isPending ||
estimateL2Fee.isPending
}
disabled={withdrawAmount ? withdrawAmount <= 0n : false}
onClick={() =>
withdraw.mutateAsync({
userAddress: userAddress!,
appAccountClient: appAccountClient!,
amount: withdrawAmount!,
gas: withdrawL2Gas,
fees: estimateL2Fee.data!,
})
}
>
Expand Down

0 comments on commit e1c8a21

Please sign in to comment.