Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(spaceward): reduce calls to evm endpoint #1068

Merged
merged 1 commit into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion spaceward/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,18 @@
"@tanstack/react-query": "^4.36.1",
"@tharsis/proto": "^0.1.20",
"@uidotdev/usehooks": "^2.4.1",
"@wagmi/core": "2.10.4",
"@walletconnect/auth-client": "^2.1.2",
"@walletconnect/core": "^2.11.0",
"@walletconnect/types": "^2.11.0",
"@walletconnect/utils": "^2.11.0",
"@walletconnect/web3wallet": "^1.10.0",
"@wardenprotocol/wardenjs": "file:../wardenjs",
"@web3-onboard/common": "2.4.2",
"@web3-onboard/core": "^2.23.0",
"@web3-onboard/injected-wallets": "^2.11.2",
"@web3-onboard/react": "^2.10.0",
"@web3-onboard/transaction-preview": "^2.1.2",
"@web3-onboard/wagmi": "^2.0.1",
"@web3-onboard/walletconnect": "^2.6.1",
"buffer": "^6.0.3",
"chain-registry": "^1.29.1",
Expand All @@ -95,6 +96,8 @@
"dayjs": "^1.11.10",
"emoji-hash-gen": "^1.0.3",
"esbuild-plugin-polyfill-node": "^0.3.0",
"eventemitter3": "5.0.1",
"joi": "^17.13.3",
"js-sha256": "^0.10.1",
"jsqr": "^1.4.0",
"libp2p": "^1.0.8",
Expand Down
46 changes: 23 additions & 23 deletions spaceward/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 10 additions & 3 deletions spaceward/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ import { hashQueryKey } from "./utils/queryKeyHash.ts";
import { DashboardPage } from "./pages/Dashboard.tsx";
import { Web3OnboardProvider, init, useWagmiConfig } from "@web3-onboard/react";
import injectedModule from "@web3-onboard/injected-wallets";
import wagmi, { createConfig } from "@web3-onboard/wagmi";
import wagmi, { createConfig } from "./utils/web3-onboard/wagmi";
import walletConnect from "@web3-onboard/walletconnect";
import { WagmiProvider } from "wagmi";
import { defineChain, http } from "viem";

const queryClient = new QueryClient({
defaultOptions: {
queries: {
refetchInterval: 2000,
staleTime: 15_000,
queryKeyHashFn: hashQueryKey,
},
},
Expand Down Expand Up @@ -156,7 +156,14 @@ const chain = defineChain({

const defaultConfig = createConfig({
chains: [chain],
transports: [http()],
transports: {
[chain.id]: http(undefined, {
batch: {
batchSize: 1000,
wait: 16
},
})
},
Comment on lines +159 to +166
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider optimizing batch parameters

The batch configuration implements JSON-RPC batching to reduce EVM endpoint calls, but the current parameters might need adjustment:

  • batchSize: 1000 is quite large and might:
    • Cause timeout issues if the endpoint has a strict timeout
    • Lead to high memory usage when processing large batches
  • wait: 16ms is reasonable for collecting requests

Consider adjusting the batch parameters:

 transports: {
   [chain.id]: http(undefined, {
     batch: {
-      batchSize: 1000,
+      batchSize: 100, // Smaller batches for better reliability
       wait: 16
     },
   })
 },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
transports: {
[chain.id]: http(undefined, {
batch: {
batchSize: 1000,
wait: 16
},
})
},
transports: {
[chain.id]: http(undefined, {
batch: {
batchSize: 100, // Smaller batches for better reliability
wait: 16
},
})
},

})

function InjectWagmi({ children }: { children: React.ReactNode }) {
Expand Down
6 changes: 5 additions & 1 deletion spaceward/src/features/actions/Action.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ import { ActionModel } from "@/hooks/query/types";
import { fromBytes, isAddressEqual, toBytes } from "viem";
import { ActionStatus } from "@/hooks/query/act";
import { fromBech32 } from "@cosmjs/encoding";
import { QueryKey, useQueryClient } from "@tanstack/react-query";

export function Action({ action }: { action: ActionModel }) {
export function Action({ action, queryKey }: { action: ActionModel, queryKey: QueryKey }) {
const [{ wallet }] = useConnectWallet();
const address = wallet?.accounts[0].address;
const { writeContractAsync } = useWriteContract();
const client = usePublicClient();
const queryClient = useQueryClient();
const [{ chains, connectedChain }, setChain] = useSetChain();

async function voteFor(voteType: ActionVoteType) {
Expand All @@ -36,6 +38,8 @@ export function Action({ action }: { action: ActionModel }) {
}),
client,
);

queryClient.invalidateQueries({ queryKey });
Comment on lines +41 to +42
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider error handling for cache invalidation.

The cache invalidation is placed after the contract write operation but before confirming the transaction success. This could lead to premature cache invalidation if the transaction fails.

Consider wrapping the cache invalidation in the success callback:

  await handleContractWrite(
    () => writeContractAsync({
      address: PRECOMPILE_ACT_ADDRESS,
      abi: actPrecompileAbi,
      functionName: "voteForAction",
      args: [action.id, voteType],
      account: address,
      connector: wallet?.wagmiConnector,
    }),
    client,
+   {
+     onSuccess: () => {
+       queryClient.invalidateQueries({ queryKey });
+     }
+   }
  );
-  queryClient.invalidateQueries({ queryKey });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
queryClient.invalidateQueries({ queryKey });
await handleContractWrite(
() => writeContractAsync({
address: PRECOMPILE_ACT_ADDRESS,
abi: actPrecompileAbi,
functionName: "voteForAction",
args: [action.id, voteType],
account: address,
connector: wallet?.wagmiConnector,
}),
client,
{
onSuccess: () => {
queryClient.invalidateQueries({ queryKey });
}
}
);

}

if (!action.msg) {
Expand Down
1 change: 1 addition & 0 deletions spaceward/src/features/actions/Actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ export function Actions() {
<div className="space-y-4">
<Action
action={action}
queryKey={q.queryKey}
/>
</div>
</AccordionContent>
Expand Down
6 changes: 5 additions & 1 deletion spaceward/src/features/actions/ApproveSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ import { useConnectWallet, useSetChain } from "@web3-onboard/react";
import { PRECOMPILE_ACT_ADDRESS } from "@/contracts/constants";
import { ActionStatus, useActionsByAddress } from "@/hooks/query/act";
import { isAddressEqual } from "viem";
import { useQueryClient } from "@tanstack/react-query";

export default function ApproveSidebar() {
const [open, setOpen] = useState(false);
const [{ wallet }] = useConnectWallet();
const address = wallet?.accounts[0].address;

const { data } = useActionsByAddress({
const { data, queryKey } = useActionsByAddress({
request: {
address,
status: ActionStatus.Pending
Expand All @@ -26,6 +27,7 @@ export default function ApproveSidebar() {

const { writeContractAsync } = useWriteContract();
const client = usePublicClient();
const queryClient = useQueryClient();
const [{ chains, connectedChain }, setChain] = useSetChain();

async function voteFor(actionId: bigint, voteType: ActionVoteType) {
Expand All @@ -42,6 +44,8 @@ export default function ApproveSidebar() {
}),
client,
);

queryClient.invalidateQueries({ queryKey });
}

const actions = data?.actions.filter(
Expand Down
47 changes: 34 additions & 13 deletions spaceward/src/features/actions/StatusSidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import "./animate.css";
import clsx from "clsx";
import { useContext, useEffect, useRef, useState } from "react";
import { sendTransaction as _sendTransaction } from "viem/actions";
import { getAction, parseEventLogs } from "viem/utils";
import { useConfig, usePublicClient, useWalletClient } from "wagmi";
import { readContractQueryOptions } from "wagmi/query"
import { walletContext } from "@cosmos-kit/react-lite";
import { Action, ActionStatus } from "@wardenprotocol/wardenjs/codegen/warden/act/v1beta1/action";
import { ActionStatus } from "@wardenprotocol/wardenjs/codegen/warden/act/v1beta1/action";
import { useToast } from "@/components/ui/use-toast";

import {
Expand All @@ -17,13 +21,12 @@ import { QueuedAction, QueuedActionStatus, useActionsState } from "./hooks";
import { getActionHandler, GetStatus, handleCosmos, handleEth, handleEthRaw } from "./util";
import { TEMP_KEY, useKeySettingsState } from "../keys/state";
import Assets from "../keys/assets";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { QueryKey, useQuery, useQueryClient } from "@tanstack/react-query";
import { capitalize } from "../modals/util";
import { queryCosmosClients } from "../assets/queries";
import { sendTransaction as _sendTransaction } from "viem/actions";
import { getAction, parseEventLogs } from "viem/utils";
import { usePublicClient, useWalletClient } from "wagmi";
import actPrecompileAbi from "@/contracts/actPrecompileAbi";
import { env } from "@/env";
import { PRECOMPILE_ACT_ADDRESS } from "@/contracts/constants";

interface ItemProps extends QueuedAction {
single?: boolean;
Expand Down Expand Up @@ -54,15 +57,15 @@ function ActionItem({ single, ...item }: ItemProps) {
const cosmosClients = useQuery(queryCosmosClients(walletManager)).data;
const clientsRef = useRef(cosmosClients);
clientsRef.current = cosmosClients;

const { data: ks, setData: setKeySettings } = useKeySettingsState();
const { toast } = useToast()
const config = useConfig();
const { w } = useWeb3Wallet("wss://relay.walletconnect.org");
const { setData } = useActionsState();

const type = typeof item.keyThemeIndex !== "undefined" ?
"key" : (["walletConnectRequestId", "walletConnectTopic"] as const).every(key => typeof item[key] !== "undefined") ?
"wc" : typeof item.snapRequestId ?
"key" : item.wc ?
"wc" : item.snap ?
"snap" : undefined

const ready = Boolean(walletClient && publicClient);
Expand Down Expand Up @@ -208,12 +211,23 @@ function ActionItem({ single, ...item }: ItemProps) {
}

const client = await getClient();
let action: Action | undefined;

const queryOptions = readContractQueryOptions(config, {
chainId: env.evmChainId,
address: PRECOMPILE_ACT_ADDRESS,
abi: actPrecompileAbi,
functionName: "actionById",
args: [item.actionId],
});

let action: Awaited<ReturnType<typeof queryOptions.queryFn>>["action"] | undefined;

try {
const res = await client.warden.act.v1beta1.actionById({
id: item.actionId,
});

const res = await queryClient.fetchQuery(
// @ts-expect-error fixme update @tanstack/react-query version to > 5
queryOptions
);
Comment on lines +227 to +230
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid suppressing TypeScript errors with @ts-expect-error

Using // @ts-expect-error to suppress TypeScript errors can hide potential issues and make the codebase harder to maintain. Consider updating @tanstack/react-query to a compatible version (greater than 5) or refactoring the code to address the TypeScript error without suppressing it.

Would you like assistance in updating the dependency or refactoring the code to handle the TypeScript error properly?


action = res.action;
} catch (e) {
Expand Down Expand Up @@ -277,9 +291,12 @@ function ActionItem({ single, ...item }: ItemProps) {

case QueuedActionStatus.ActionReady: {
let getStatus: GetStatus | undefined;
let queryKeys: QueryKey[] = [];

try {
getStatus = getActionHandler(item).getStatus;
const res = getActionHandler(item);
getStatus = res.getStatus;
queryKeys = res.queryKeys;
} catch (e) {
console.error(e);

Expand Down Expand Up @@ -322,6 +339,10 @@ function ActionItem({ single, ...item }: ItemProps) {
} else if (status.pending) {
setTimeout(checkResult, 1000);
} else if (status.done) {
for (const queryKey of queryKeys) {
queryClient.invalidateQueries({ queryKey });
}

if (!status.next) {
toast({
title: "Success",
Expand Down
Loading
Loading