@@ -2,25 +2,31 @@ import { useState } from "react";
2
2
import type { Action , TransactionAction } from "@1hive/evmcrispr" ;
3
3
import { EVMcrispr , isProviderAction , parseScript } from "@1hive/evmcrispr" ;
4
4
import type { Connector } from "wagmi" ;
5
- import { useConnect , useWalletClient } from "wagmi" ;
6
- import type { Account , Chain , Transport , WalletClient } from "viem" ;
5
+ import { useConnect , usePublicClient , useWalletClient } from "wagmi" ;
6
+ import type {
7
+ Account ,
8
+ Chain ,
9
+ PublicClient ,
10
+ Transport ,
11
+ WalletClient ,
12
+ } from "viem" ;
13
+ import { createPublicClient } from "viem" ;
7
14
import { HStack , VStack , useDisclosure } from "@chakra-ui/react" ;
8
15
import type SafeAppProvider from "@safe-global/safe-apps-sdk" ;
9
16
10
17
import LogModal from "../LogModal" ;
11
18
import ErrorMsg from "./ErrorMsg" ;
12
19
13
- import { config } from "../../wagmi" ;
20
+ import { config , transports } from "../../wagmi" ;
14
21
15
22
import {
16
23
terminalStoreActions ,
17
24
useTerminalStore ,
18
25
} from "../TerminalEditor/use-terminal-store" ;
19
- import { clientToSigner } from "../../utils/ethers" ;
20
26
import { ExecuteButton } from "./ExecuteButton" ;
21
27
22
28
type ActionButtonsType = {
23
- address : string ;
29
+ address : `0x${ string } ` | undefined ;
24
30
maximizeGasLimit : boolean ;
25
31
} ;
26
32
@@ -40,7 +46,8 @@ export default function ActionButtons({
40
46
id : "log" ,
41
47
} ) ;
42
48
43
- const { data : client , refetch } = useWalletClient ( ) ;
49
+ let publicClient : PublicClient | undefined = usePublicClient ( ) ;
50
+ const { data : walletClient } = useWalletClient ( ) ;
44
51
const { connectors } = useConnect ( ) ;
45
52
const safeConnector = connectors . find ( ( c : Connector ) => c . id === "safe" ) ;
46
53
@@ -57,30 +64,45 @@ export default function ActionButtons({
57
64
setLogs ( [ ] ) ;
58
65
}
59
66
67
+ function getChainAndTransport ( chainId : number ) {
68
+ const chain : Chain | undefined = config . chains . find (
69
+ ( chain ) => Number ( chain . id ) === chainId ,
70
+ ) ;
71
+ if ( ! chain ) {
72
+ throw new Error ( "Chain not supported" ) ;
73
+ }
74
+ function isValidChainId (
75
+ chainId : number ,
76
+ ) : chainId is keyof typeof transports {
77
+ return chainId in transports ;
78
+ }
79
+ if ( ! isValidChainId ( chainId ) ) {
80
+ throw new Error ( "Transport not supported" ) ;
81
+ }
82
+ const transport = transports [ chainId ] ;
83
+ return { chain, transport } ;
84
+ }
85
+
60
86
const executeAction = async (
61
87
action : Action ,
62
- client : WalletClient < Transport , Chain , Account > ,
88
+ walletClient : WalletClient < Transport , Chain , Account > ,
63
89
maximizeGasLimit : boolean ,
64
90
) => {
65
91
if ( isProviderAction ( action ) ) {
66
- const [ chainParam ] = action . params ;
67
- await client . switchChain ( { id : Number ( chainParam . chainId ) } ) ;
68
- const { data : refetchedClient } = await refetch ( ) ;
69
- if ( ! refetchedClient ) {
70
- throw new Error ( "Failed to refetch client after chain switch" ) ;
71
- }
72
- return refetchedClient ;
92
+ const chainId = Number ( action . params [ 0 ] . chainId ) ;
93
+ await walletClient . switchChain ( { id : chainId } ) ;
94
+ const { chain, transport } = getChainAndTransport ( chainId ) ;
95
+ publicClient = createPublicClient ( { chain, transport } ) ;
73
96
} else {
74
- const chainId = await client . getChainId ( ) ;
75
- await client . sendTransaction ( {
97
+ const chainId = await walletClient . getChainId ( ) ;
98
+ await walletClient . sendTransaction ( {
76
99
chain : config . chains . find ( ( chain ) => chain . id === chainId ) ,
77
100
to : action . to as `0x${string } `,
78
101
from : action . from as `0x${string } `,
79
102
data : action . data as `0x${string } `,
80
103
value : BigInt ( action . value || 0 ) ,
81
104
gasLimit : maximizeGasLimit ? 10_000_000n : undefined ,
82
105
} ) ;
83
- return client ;
84
106
}
85
107
} ;
86
108
@@ -89,7 +111,8 @@ export default function ActionButtons({
89
111
terminalStoreActions . isLoading ( true ) ;
90
112
91
113
try {
92
- if ( client === undefined ) throw new Error ( "Account not connected" ) ;
114
+ if ( ! address || publicClient === undefined || walletClient === undefined )
115
+ throw new Error ( "Account not connected" ) ;
93
116
94
117
const { ast, errors } = parseScript ( script ) ;
95
118
@@ -100,20 +123,21 @@ export default function ActionButtons({
100
123
}
101
124
102
125
const batched : TransactionAction [ ] = [ ] ;
103
- const getSigner = async ( ) => {
104
- const { data : client } = await refetch ( ) ;
105
- return clientToSigner ( client ! ) ;
106
- } ;
107
- await new EVMcrispr ( ast , getSigner )
126
+
127
+ await new EVMcrispr (
128
+ ast ,
129
+ async ( ) => publicClient ! ,
130
+ async ( ) => address ,
131
+ )
108
132
. registerLogListener ( logListener )
109
- . interpret ( async ( action ) => {
133
+ . interpret ( async ( action : Action ) => {
110
134
if ( inBatch ) {
111
135
if ( isProviderAction ( action ) ) {
112
136
throw new Error ( "Batching not supported for provider actions" ) ;
113
137
}
114
138
batched . push ( action ) ;
115
139
} else {
116
- await executeAction ( action , client , maximizeGasLimit ) ;
140
+ await executeAction ( action , walletClient , maximizeGasLimit ) ;
117
141
}
118
142
} ) ;
119
143
0 commit comments