Skip to content

Commit

Permalink
add velords claim simulate tx
Browse files Browse the repository at this point in the history
  • Loading branch information
RedBeardEth committed Oct 14, 2024
1 parent 96598fc commit 783f0d9
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 4 deletions.
17 changes: 14 additions & 3 deletions apps/nextjs/src/app/(app)/account/lords/velords/VeLords.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { differenceInSeconds, getUnixTime, fromUnixTime } from "date-fns";
import { motion } from "framer-motion";
import { formatNumber } from "@realms-world/utils";
import Link from "next/link";
import { useSimulateTransactions } from "@/hooks/useSimulateTransactions";

const WEEK_IN_SECONDS = 7 * 24 * 60 * 60; // 1 week in seconds
const YEAR_IN_SECONDS = 365 * 24 * 60 * 60; // 1 year in seconds
Expand Down Expand Up @@ -192,7 +193,7 @@ export const VeLords = () => {
return 0n;
}, [ownerLordsLock]);

const { claim, manageLock, withdraw } = useVeLords();
const { claim, manageLock, withdraw, claimCall } = useVeLords();

const newLockEndTime = useMemo(() => {
const currentTime = getUnixTime(new Date());
Expand All @@ -214,6 +215,12 @@ export const VeLords = () => {
setLockWeeks(0);
}
};
const { data: simulateData, error: simulateError } = useSimulateTransactions({
calls: claimCall,
});

const lordsClaimable =
simulateData?.[0]?.transaction_trace.execute_invocation.result[2];

return (
<div className="mt-4 grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5">
Expand Down Expand Up @@ -521,8 +528,12 @@ export const VeLords = () => {
</CardHeader>
<CardContent>
<div className="flex gap-4">
You have <span className="text-3xl font-bold">0</span> Lords
to claim
You have{" "}
<span className="text-3xl font-bold">
{lordsClaimable &&
formatNumber(formatEther(BigInt(lordsClaimable)))}
</span>{" "}
Lords to claim
</div>
</CardContent>
<CardFooter>
Expand Down
8 changes: 7 additions & 1 deletion apps/nextjs/src/hooks/staking/useVeLords.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from "@starknet-react/core";

import { LORDS, StakingAddresses } from "@realms-world/constants";
import { useMemo } from "react";

export const useVeLords = () => {
const veLordsAddress = StakingAddresses.velords[SUPPORTED_L2_CHAIN_ID];
Expand Down Expand Up @@ -65,6 +66,11 @@ export const useVeLords = () => {
}
};

const claimCall = useMemo(
() => address && [rewardPool?.populate("claim", [address])],
[address, rewardPool],
);

const claim = async (recipient?: Address) => {
const endRecipient = recipient ?? address;

Expand All @@ -74,5 +80,5 @@ export const useVeLords = () => {
return await claimRewards([rewardPool?.populate("claim", [endRecipient])]);
};

return { manageLock, claim, withdraw };
return { manageLock, claim, withdraw, claimCall };
};
117 changes: 117 additions & 0 deletions apps/nextjs/src/hooks/useSimulateTransactions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { useMemo } from "react";
import {
type AccountInterface,
type Call,
type EstimateFeeDetails,
type EstimateFeeResponse,
type SimulateTransactionResponse,
type SimulateTransactionDetails,
TransactionType,
} from "starknet";

import { useAccount, useInvalidateOnBlock } from "@starknet-react/core";
import {

Check warning on line 13 in apps/nextjs/src/hooks/useSimulateTransactions.ts

View workflow job for this annotation

GitHub Actions / lint

Imports "QueryKey" and "UseQueryResult" are only used as type
QueryKey,
useQuery,
UseQueryResult,
type UseQueryOptions as UseQueryOptions_,
} from "@tanstack/react-query";

export type SimulateTransactionsArgs = {
/** List of smart contract calls to simulate. */
calls?: Call[];
/** Simualte Transaction options. */
options?: SimulateTransactionDetails;
};
type UseQueryProps<
TQueryFnData = unknown,
TError = unknown,
TData = TQueryFnData,
TQueryKey extends QueryKey = QueryKey,
> = Pick<
UseQueryOptions_<TQueryFnData, TError, TData, TQueryKey>,
"enabled" | "refetchInterval" | "retry" | "retryDelay"
>;
/** Options for `useSimulateTransactions`. */
export type UseSimulateTransactionsProps = SimulateTransactionsArgs &
UseQueryProps<
SimulateTransactionResponse,
Error,
SimulateTransactionResponse,
ReturnType<typeof queryKey>
> & {
/** Refresh data at every block. */
watch?: boolean;
};

/** Value returned from `useSimulateTransactions`. */
export type UseSimulateTransactionsResult = UseQueryResult<
SimulateTransactionResponse,
Error
>;

/**
* Hook to estimate fees for smart contract calls.
*
* @remarks
*
* The hook only performs estimation if the `calls` is not undefined.
*/
export function useSimulateTransactions({
calls,
options,
watch = false,
enabled: enabled_ = true,
...props
}: UseSimulateTransactionsProps): UseSimulateTransactionsResult {
const { account } = useAccount();

const queryKey_ = useMemo(
() => queryKey({ calls, options }),
[calls, options],
);

const enabled = useMemo(() => Boolean(enabled_ && calls), [enabled_, calls]);

useInvalidateOnBlock({
enabled: Boolean(enabled && watch),
queryKey: queryKey_,
});

return useQuery({
queryKey: queryKey_,
queryFn: queryFn({
account,
calls,
options,
}),
enabled,
...props,
});
}

function queryKey({ calls, options }: SimulateTransactionsArgs) {
return [
{
entity: "simulateTransactions",
calls,
options,
},
] as const;
}

function queryFn({
account,
calls,
options,
}: { account?: AccountInterface } & SimulateTransactionsArgs) {
return async () => {
if (!account) throw new Error("account is required");
if (!calls || calls.length === 0) throw new Error("calls are required");
const callMap = calls.map((call) => ({
type: TransactionType.INVOKE,
...call,
}));
return account?.simulateTransaction(callMap, options);
};
}

0 comments on commit 783f0d9

Please sign in to comment.