@@ -2,6 +2,38 @@ import { createStore } from "@mina-js/connect";
2
2
import { useLocalStorage , useObjectState } from "@uidotdev/usehooks" ;
3
3
import { clsx } from "clsx" ;
4
4
import { useState , useSyncExternalStore } from "react" ;
5
+ import bs58 from 'bs58' ;
6
+
7
+ function bytesToHex ( bytes : Uint8Array ) : string {
8
+ return Array . from ( bytes )
9
+ . map ( ( byte ) => byte . toString ( 16 ) . padStart ( 2 , '0' ) )
10
+ . join ( '' ) ;
11
+ }
12
+
13
+ function convertSignature ( signature : string ) : { field : string ; scalar : string } {
14
+ // Decode the base58-encoded signature into bytes
15
+ const bytes = bs58 . decode ( signature ) ;
16
+
17
+ // Ensure the byte array can be split into two equal parts
18
+ if ( bytes . length % 2 !== 0 ) {
19
+ throw new Error ( 'Invalid signature length.' ) ;
20
+ }
21
+
22
+ const half = bytes . length / 2 ;
23
+ const fieldBytes = bytes . slice ( 0 , half ) ;
24
+ const scalarBytes = bytes . slice ( half ) ;
25
+
26
+ // Convert bytes to hexadecimal strings
27
+ const fieldHex = bytesToHex ( fieldBytes ) ;
28
+ const scalarHex = bytesToHex ( scalarBytes ) ;
29
+
30
+ // Convert hexadecimal strings to decimal strings
31
+ const field = BigInt ( '0x' + fieldHex ) . toString ( 10 ) ;
32
+ const scalar = BigInt ( '0x' + scalarHex ) . toString ( 10 ) ;
33
+
34
+ // Return the signature object
35
+ return { field, scalar } ;
36
+ }
5
37
6
38
const store = createStore ( ) ;
7
39
@@ -26,6 +58,7 @@ export const TestZkApp = () => {
26
58
mina_sign : "" ,
27
59
mina_signFields : "" ,
28
60
mina_signTransaction : "" ,
61
+ mina_sendTransaction : ""
29
62
} ) ;
30
63
const providers = useSyncExternalStore ( store . subscribe , store . getProviders ) ;
31
64
const provider = providers . find (
@@ -140,6 +173,22 @@ export const TestZkApp = () => {
140
173
mina_signTransaction : JSON . stringify ( result , undefined , "\t" ) ,
141
174
} ) ) ;
142
175
} ;
176
+ const sendTransaction = async ( ) => {
177
+ if ( ! provider ) return ;
178
+ if ( ! results . mina_signTransaction ) return ;
179
+ const signedTransaction = JSON . parse ( results . mina_signTransaction )
180
+ const { result } = await provider . request ( {
181
+ method : "mina_sendTransaction" ,
182
+ params : [ {
183
+ ...signedTransaction ,
184
+ signature : typeof signedTransaction . signature === "string" ?
185
+ convertSignature ( signedTransaction . signature ) : signedTransaction . signature
186
+ } ] ,
187
+ } ) ;
188
+ setResults ( ( ) => ( {
189
+ mina_sendTransaction : JSON . stringify ( result , undefined , "\t" ) ,
190
+ } ) ) ;
191
+ } ;
143
192
return (
144
193
< main className = "flex flex-col gap-8" >
145
194
< h1 className = "text-3xl font-bold" > Test zkApp</ h1 >
@@ -302,39 +351,39 @@ export const TestZkApp = () => {
302
351
< input
303
352
value = { transactionBody . to }
304
353
onChange = { ( event ) =>
305
- setTransactionBody ( ( ) => ( { to : event . target . value } ) )
354
+ setTransactionBody ( ( ) => ( { to : event . target . value } ) )
306
355
}
307
356
className = "input input-bordered"
308
357
/>
309
358
< label > Amount</ label >
310
359
< input
311
360
value = { transactionBody . amount }
312
361
onChange = { ( event ) =>
313
- setTransactionBody ( ( ) => ( { amount : event . target . value } ) )
362
+ setTransactionBody ( ( ) => ( { amount : event . target . value } ) )
314
363
}
315
364
className = "input input-bordered"
316
365
/>
317
366
< label > Fee</ label >
318
367
< input
319
368
value = { transactionBody . fee }
320
369
onChange = { ( event ) =>
321
- setTransactionBody ( ( ) => ( { fee : event . target . value } ) )
370
+ setTransactionBody ( ( ) => ( { fee : event . target . value } ) )
322
371
}
323
372
className = "input input-bordered"
324
373
/>
325
374
< label > Memo</ label >
326
375
< input
327
376
value = { transactionBody . memo }
328
377
onChange = { ( event ) =>
329
- setTransactionBody ( ( ) => ( { memo : event . target . value } ) )
378
+ setTransactionBody ( ( ) => ( { memo : event . target . value } ) )
330
379
}
331
380
className = "input input-bordered"
332
381
/>
333
382
< label > Nonce</ label >
334
383
< input
335
384
value = { transactionBody . nonce }
336
385
onChange = { ( event ) =>
337
- setTransactionBody ( ( ) => ( { nonce : event . target . value } ) )
386
+ setTransactionBody ( ( ) => ( { nonce : event . target . value } ) )
338
387
}
339
388
className = "input input-bordered"
340
389
/>
@@ -362,6 +411,23 @@ export const TestZkApp = () => {
362
411
className = "textarea textarea-bordered h-48 resize-none"
363
412
/>
364
413
</ div >
414
+ < div className = "flex gap-4" >
415
+ < button
416
+ type = "button"
417
+ className = "btn btn-primary flex-1"
418
+ disabled = { ! results . mina_signTransaction }
419
+ onClick = { sendTransaction }
420
+ >
421
+ Send Transaction
422
+ </ button >
423
+ </ div >
424
+ < div className = "flex flex-col gap-2" >
425
+ < label > Result</ label >
426
+ < textarea
427
+ value = { results . mina_sendTransaction }
428
+ className = "textarea textarea-bordered h-48 resize-none"
429
+ />
430
+ </ div >
365
431
</ div >
366
432
</ section >
367
433
</ main >
0 commit comments