diff --git a/components/contract-execution/contract-execution-tabs/index.tsx b/components/contract-execution/contract-execution-tabs/index.tsx
index d69b804..4cfa212 100644
--- a/components/contract-execution/contract-execution-tabs/index.tsx
+++ b/components/contract-execution/contract-execution-tabs/index.tsx
@@ -5,12 +5,12 @@ import { cn } from "../../../lib/utils.js";
import { Accordion } from "../../shadcn/accordion.js";
import { Input } from "../../shadcn/input.js";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../shadcn/tabs.js";
-import type { ContractFunctionsListProps } from "../shared/types.js";
+import type { ContractExecutionTabsProps } from "../shared/types.js";
import { FunctionItem } from "./function-item.js";
import { RawOperations } from "./raw-tab.js";
import { SignatureOperations } from "./signature-tab.js";
-export function ContractFunctionsList({
+export function ContractExecutionTabs({
abi,
address,
chainId,
@@ -21,14 +21,13 @@ export function ContractFunctionsList({
onQuery,
onWrite,
onSimulate,
- onRawCall,
- onRawTransaction,
- enableSignature,
+ enableRaw = true,
+ enableSignature = true,
addressRenderer,
onHashClick,
title,
NoAbiComponent,
-}: ContractFunctionsListProps) {
+}: ContractExecutionTabsProps) {
const [searchTerm, setSearchTerm] = useState("");
const contractFunctions = useMemo(() => {
@@ -53,9 +52,7 @@ export function ContractFunctionsList({
};
}, [contractFunctions, searchTerm]);
- const hasRawOperations = onRawCall || onRawTransaction;
- const hasSignature = !!enableSignature;
- const tabCount = 2 + (hasRawOperations ? 1 : 0) + (hasSignature ? 1 : 0);
+ const tabCount = 2 + (enableRaw ? 1 : 0) + (enableSignature ? 1 : 0);
return (
@@ -101,7 +98,7 @@ export function ContractFunctionsList({
{writeFunctions.length}
- {hasRawOperations && (
+ {enableRaw && (
)}
- {hasSignature && (
+ {enableSignature && (
- {hasRawOperations && (
+ {enableRaw && (
)}
- {hasSignature && (
+ {enableSignature && (
Promise<`0x${string}`>;
- onRawTransaction?: (params: RawCallParams) => Promise<`0x${string}`>;
+ onQuery: (params: ExecutionParams) => Promise<`0x${string}`>;
+ onWrite: (params: ExecutionParams) => Promise<`0x${string}`>;
}
export function RawOperations({
@@ -30,42 +30,38 @@ export function RawOperations({
addresses,
requiresConnection,
isConnected,
- onRawCall,
- onRawTransaction,
+ onQuery,
+ onWrite,
addressRenderer,
onHashClick,
}: RawOperationsProps) {
return (
- {onRawCall && (
-
- )}
- {onRawTransaction && (
-
- )}
+
+
);
@@ -73,7 +69,7 @@ export function RawOperations({
interface RawOperationItemProps extends BaseExecutionProps {
type: "call" | "transaction";
- onExecute: (params: RawCallParams) => Promise<`0x${string}`>;
+ onExecute: (params: ExecutionParams) => Promise<`0x${string}`>;
}
function RawOperationItem({
diff --git a/components/contract-execution/resend-transaction/index.tsx b/components/contract-execution/resend-transaction/index.tsx
index f8f4495..ed2d63f 100644
--- a/components/contract-execution/resend-transaction/index.tsx
+++ b/components/contract-execution/resend-transaction/index.tsx
@@ -10,7 +10,7 @@ import {
MsgSenderInput,
} from "../shared/components.js";
import { useMsgSenderForm } from "../shared/form-utils.js";
-import type { ExecutionParams, RawCallParams } from "../shared/types.js";
+import type { ExecutionParams } from "../shared/types.js";
import { useFunctionExecution } from "../shared/use-function-execution.js";
import { useRawExecution } from "../shared/use-raw-execution.js";
import { isWriteFunction } from "../shared/utils.js";
@@ -28,7 +28,6 @@ export interface ResendTransactionProps {
onQuery: (params: ExecutionParams) => Promise;
onWrite: (params: ExecutionParams) => Promise;
onSimulate?: (params: ExecutionParams) => Promise;
- onRawTransaction?: (params: RawCallParams) => Promise;
addressRenderer?: (address: Address) => React.ReactNode;
onHashClick?: (hash: string) => void;
}
@@ -46,7 +45,6 @@ export function ResendTransaction({
onQuery,
onWrite,
onSimulate,
- onRawTransaction,
addressRenderer,
onHashClick,
}: ResendTransactionProps) {
@@ -73,7 +71,7 @@ export function ResendTransaction({
const functionExecution = useFunctionExecution();
const rawExecution = useRawExecution({
isWrite: true,
- onExecute: onRawTransaction || (async () => "0x" as Hex),
+ onExecute: onWrite,
});
const handleSimulate = () => {
diff --git a/components/contract-execution/shared/types.ts b/components/contract-execution/shared/types.ts
index 8c962b2..ba2e294 100644
--- a/components/contract-execution/shared/types.ts
+++ b/components/contract-execution/shared/types.ts
@@ -13,19 +13,13 @@ export interface BaseExecutionProps {
}
export interface ExecutionParams {
- abiFunction: AbiFunction;
+ abiFunction?: AbiFunction;
callData: Hex;
msgSender?: Address;
value?: bigint;
}
-export interface RawCallParams {
- data: Hex;
- value?: bigint;
- msgSender?: Address;
-}
-
-export interface ContractFunctionsListProps {
+export interface ContractExecutionTabsProps {
/** Full contract ABI (will be filtered internally for functions) */
abi: Abi;
/** Contract address */
@@ -46,11 +40,9 @@ export interface ContractFunctionsListProps {
onWrite: (params: ExecutionParams) => Promise<`0x${string}`>;
/** Optional simulate function for write functions - returns raw hex result from simulation */
onSimulate?: (params: ExecutionParams) => Promise<`0x${string}`>;
- /** Optional raw call function (eth_call with arbitrary data) - returns raw hex result */
- onRawCall?: (params: RawCallParams) => Promise<`0x${string}`>;
- /** Optional raw transaction function (send transaction with arbitrary data) - returns transaction hash */
- onRawTransaction?: (params: RawCallParams) => Promise<`0x${string}`>;
- /** Enable signature-based interaction tab */
+ /** Enable raw call/transaction tab (default: true) */
+ enableRaw?: boolean;
+ /** Enable signature-based interaction tab (default: true) */
enableSignature?: boolean;
/** Custom address renderer for form inputs */
addressRenderer?: (address: Address) => React.ReactNode;
diff --git a/components/contract-execution/shared/use-raw-execution.ts b/components/contract-execution/shared/use-raw-execution.ts
index 82d6332..7f8fe0a 100644
--- a/components/contract-execution/shared/use-raw-execution.ts
+++ b/components/contract-execution/shared/use-raw-execution.ts
@@ -1,11 +1,11 @@
import { useState } from "react";
import type { Address, Hex } from "viem";
-import type { RawCallParams } from "./types.js";
+import type { ExecutionParams } from "./types.js";
import type { InternalResult } from "./use-function-execution.js";
interface UseRawExecutionParams {
isWrite: boolean;
- onExecute: (params: RawCallParams) => Promise;
+ onExecute: (params: ExecutionParams) => Promise;
}
export function useRawExecution({ isWrite, onExecute }: UseRawExecutionParams) {
@@ -22,7 +22,7 @@ export function useRawExecution({ isWrite, onExecute }: UseRawExecutionParams) {
setIsExecuting(true);
try {
const response = await onExecute({
- data: params.callData as Hex,
+ callData: params.callData as Hex,
value: params.value,
msgSender: params.msgSender,
});
diff --git a/stories/contract-functions-list.stories.tsx b/stories/contract-functions-list.stories.tsx
index 25924f1..6823945 100644
--- a/stories/contract-functions-list.stories.tsx
+++ b/stories/contract-functions-list.stories.tsx
@@ -1,16 +1,13 @@
import type { Meta, StoryObj } from "@storybook/react-vite";
import React, { useState } from "react";
import type { Abi } from "viem";
-import { ContractFunctionsList } from "../components/contract-execution/contract-execution-tabs/index.js";
-import type {
- ExecutionParams,
- RawCallParams,
-} from "../components/contract-execution/shared/types.js";
+import { ContractExecutionTabs } from "../components/contract-execution/contract-execution-tabs/index.js";
+import type { ExecutionParams } from "../components/contract-execution/shared/types.js";
import { Button } from "../components/shadcn/button.js";
-const meta: Meta = {
- title: "ethui/ContractFunctionsList",
- component: ContractFunctionsList,
+const meta: Meta = {
+ title: "ethui/ContractExecutionTabs",
+ component: ContractExecutionTabs,
parameters: {
layout: "padded",
},
@@ -111,6 +108,11 @@ const mockQuery = async (params: ExecutionParams): Promise<`0x${string}`> => {
// Simulate async operation
await new Promise((resolve) => setTimeout(resolve, 1000));
+ // If no abiFunction (raw call), return generic result
+ if (!params.abiFunction) {
+ return "0x0000000000000000000000000000000000000000000000000000000000000001";
+ }
+
// Mock encoded result for read operations (manually encoded for simplicity)
const mockResults: Record = {
balanceOf:
@@ -147,6 +149,11 @@ const mockSimulate = async (
// Simulate async operation
await new Promise((resolve) => setTimeout(resolve, 800));
+ // If no abiFunction, can't simulate
+ if (!params.abiFunction) {
+ return "0x0000000000000000000000000000000000000000000000000000000000000001";
+ }
+
const isWrite =
params.abiFunction.stateMutability !== "view" &&
params.abiFunction.stateMutability !== "pure";
@@ -160,23 +167,6 @@ const mockSimulate = async (
}
};
-// Mock raw operation handlers
-const mockRawCall = async (params: RawCallParams): Promise<`0x${string}`> => {
- console.log("Raw call with:", params);
- await new Promise((resolve) => setTimeout(resolve, 1000));
- // Return mock raw hex result
- return "0x0000000000000000000000000000000000000000000000000000000000000001";
-};
-
-const mockRawTransaction = async (
- params: RawCallParams,
-): Promise<`0x${string}`> => {
- console.log("Raw transaction with:", params);
- await new Promise((resolve) => setTimeout(resolve, 1000));
- // Return mock transaction hash
- return "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890";
-};
-
// Story: Basic usage with all features
export const Default: Story = {
args: {
@@ -190,8 +180,7 @@ export const Default: Story = {
onQuery: mockQuery,
onWrite: mockWrite,
onSimulate: mockSimulate,
- onRawCall: mockRawCall,
- onRawTransaction: mockRawTransaction,
+ enableRaw: true,
enableSignature: true,
},
};
@@ -208,7 +197,9 @@ export const WithoutSimulateAndRaw: Story = {
isConnected: true,
onQuery: mockQuery,
onWrite: mockWrite,
- // No onSimulate, onRawCall, or onRawTransaction - shows only Read/Write tabs
+ // No onSimulate or raw tabs
+ enableRaw: false,
+ enableSignature: false,
},
};
@@ -228,7 +219,7 @@ function InteractiveStory() {
-
);
@@ -272,8 +263,8 @@ export const WithError: Story = {
onQuery: mockQuery,
onWrite: mockWriteWithError,
onSimulate: mockSimulate,
- onRawCall: mockRawCall,
- onRawTransaction: mockRawTransaction,
+ enableRaw: true,
+ enableSignature: true,
},
};
@@ -290,8 +281,7 @@ export const EmptyAbi: Story = {
onQuery: mockQuery,
onWrite: mockWrite,
onSimulate: mockSimulate,
- onRawCall: mockRawCall,
- onRawTransaction: mockRawTransaction,
+ enableRaw: true,
enableSignature: true,
},
};
@@ -324,8 +314,7 @@ export const EmptyAbiWithCustomComponent: Story = {
onQuery: mockQuery,
onWrite: mockWrite,
onSimulate: mockSimulate,
- onRawCall: mockRawCall,
- onRawTransaction: mockRawTransaction,
+ enableRaw: true,
enableSignature: true,
NoAbiComponent: CustomNoAbi,
},