@@ -9,34 +9,98 @@ import { TransactionTypeSelector } from './TransactionTypeSelector';
99import { SendTokenBuilder } from './SendTokenBuilder' ;
1010import { CustomTransactionBuilder } from './CustomTransactionBuilder' ;
1111import { TransactionPreview } from './TransactionPreview' ;
12+ import { useConnectWallet } from '@web3-onboard/react' ;
13+ import Safe , { Eip1193Provider , SafeTransactionOptionalProps } from '@safe-global/protocol-kit' ;
14+ import { useCurrentSafeClient , useSelectedSafeAddress } from '@/providers/SafeProvider' ;
15+ import { MetaTransactionData } from '@safe-global/types-kit' ;
16+ import type { SafeTransaction } from '@safe-global/types-kit' ;
1217
1318export type TransactionType = 'send' | 'custom' ;
1419
20+ // Transaction data interface conforming to viem standards
1521export interface TransactionData {
1622 type : TransactionType ;
17- to ?: string ;
18- value ?: string ;
19- tokenAddress ?: string ;
20- data ?: string ;
21- gasLimit ?: string ;
22- maxFeePerGas ?: string ;
23- maxPriorityFeePerGas ?: string ;
23+ to ?: `0x${ string } ` ;
24+ value ?: bigint ; // Use bigint, in wei units
25+ tokenAddress ?: `0x${ string } ` ;
26+ data ?: `0x${ string } ` ;
27+ gasLimit ?: bigint ;
28+ maxFeePerGas ?: bigint ;
29+ maxPriorityFeePerGas ?: bigint ;
2430}
2531
26- export type Step = 'select' | 'build' | 'preview' ;
32+ // SafeTransaction related data
33+ export interface SafeTransactionData {
34+ rawTransaction : TransactionData ;
35+ safeTransaction ?: SafeTransaction ;
36+ transactionHash ?: string ;
37+ estimatedGas ?: bigint ;
38+ estimatedFees ?: {
39+ maxFeePerGas : bigint ;
40+ maxPriorityFeePerGas : bigint ;
41+ } ;
42+ }
43+
44+ export type Step = 'select' | 'build' | 'preview' | 'execute' ;
2745
2846export function TransactionProcess ( ) {
2947 const [ currentStep , setCurrentStep ] = useState < Step > ( 'select' ) ;
3048 const [ transactionData , setTransactionData ] = useState < TransactionData | null > ( null ) ;
49+ const [ safeTransactionData , setSafeTransactionData ] = useState < SafeTransactionData | null > ( null ) ;
50+
51+ const { selectedSafeAddress } = useSelectedSafeAddress ( ) ;
52+ const currentSafeClient = useCurrentSafeClient ( ) ;
53+ const [ { wallet } ] = useConnectWallet ( ) ;
3154
3255 const handleTypeSelect = ( type : TransactionType ) => {
3356 setTransactionData ( { type } ) ;
3457 setCurrentStep ( 'build' ) ;
3558 } ;
3659
37- const handleTransactionBuilt = ( data : Partial < TransactionData > ) => {
38- setTransactionData ( ( prev ) => ( { ...prev , ...data } ) as TransactionData ) ;
39- setCurrentStep ( 'preview' ) ;
60+ const handleTransactionBuilt = async ( data : Partial < TransactionData > ) => {
61+ const updatedTransactionData = { ...transactionData , ...data } as TransactionData ;
62+ setTransactionData ( updatedTransactionData ) ;
63+
64+ // Create SafeTransaction
65+ try {
66+ await createSafeTransaction ( updatedTransactionData ) ;
67+ setCurrentStep ( 'preview' ) ;
68+ } catch ( error ) {
69+ console . error ( 'Failed to create Safe transaction:' , error ) ;
70+ alert ( 'Failed to create Safe transaction. Please try again.' ) ;
71+ }
72+ } ;
73+
74+ const createSafeTransaction = async ( transactionData : TransactionData ) => {
75+ if ( ! wallet ?. provider || ! wallet ?. accounts ?. [ 0 ] ?. address || ! selectedSafeAddress ) {
76+ throw new Error ( 'Please connect your wallet and select a Safe first' ) ;
77+ }
78+
79+ const signer = wallet . accounts [ 0 ] . address ;
80+ const provider = wallet . provider ;
81+
82+ const protocolKit = await Safe . init ( {
83+ provider : provider as Eip1193Provider ,
84+ signer,
85+ safeAddress : selectedSafeAddress ,
86+ } ) ;
87+
88+ const transactions : MetaTransactionData [ ] = [
89+ {
90+ to : transactionData . to as string ,
91+ value : transactionData . value ?. toString ( ) || '0' ,
92+ data : transactionData . data || '0x' ,
93+ } ,
94+ ] ;
95+
96+ const safeTransaction = await protocolKit . createTransaction ( {
97+ transactions,
98+ } ) ;
99+
100+ setSafeTransactionData ( {
101+ rawTransaction : transactionData ,
102+ safeTransaction,
103+ } ) ;
40104 } ;
41105
42106 const handleBack = ( ) => {
@@ -47,14 +111,43 @@ export function TransactionProcess() {
47111 }
48112 } ;
49113
50- const handleSign = ( ) => {
51- console . log ( 'Signing transaction:' , transactionData ) ;
52- // TODO: Implement transaction signing
114+ const handleSign = async ( ) => {
115+ console . log ( 'handleSign' ) ;
116+
117+ if ( ! wallet ?. provider || ! wallet ?. accounts ?. [ 0 ] ?. address ) {
118+ alert ( 'Please connect your wallet first' ) ;
119+ return ;
120+ }
121+
122+ const signer = wallet . accounts [ 0 ] . address ;
123+ const provider = wallet . provider ;
124+
125+ const protocolKit = await Safe . init ( {
126+ provider : provider as Eip1193Provider ,
127+ signer,
128+ safeAddress : selectedSafeAddress as string ,
129+ } ) ;
130+
131+ const transactions : MetaTransactionData [ ] = [
132+ {
133+ to : transactionData ?. to as string ,
134+ value : transactionData ?. value ?. toString ( ) || '0' ,
135+ data : transactionData ?. data || '0x' ,
136+ } ,
137+ ] ;
138+
139+ const safeTransaction = await protocolKit . createTransaction ( {
140+ transactions,
141+ } ) ;
142+
143+ console . log ( safeTransaction ) ;
53144 } ;
54145
55146 const handleExecute = ( ) => {
56- console . log ( 'Executing transaction:' , transactionData ) ;
57- // TODO: Implement transaction execution
147+ if ( ! wallet ?. provider || ! wallet ?. accounts ?. [ 0 ] ?. address ) {
148+ alert ( 'Please connect your wallet first' ) ;
149+ return ;
150+ }
58151 } ;
59152
60153 const getStepTitle = ( ) => {
@@ -94,7 +187,14 @@ export function TransactionProcess() {
94187 return < CustomTransactionBuilder onComplete = { handleTransactionBuilt } /> ;
95188 }
96189 case 'preview' :
97- return < TransactionPreview transactionData = { transactionData ! } onSign = { handleSign } onExecute = { handleExecute } /> ;
190+ return (
191+ < TransactionPreview
192+ transactionData = { transactionData ! }
193+ safeTransactionData = { safeTransactionData || undefined }
194+ onSign = { handleSign }
195+ onExecute = { handleExecute }
196+ />
197+ ) ;
98198 default :
99199 return null ;
100200 }
0 commit comments