11'use client'
22
33import { useState } from 'react'
4- import { Core } from "@evolution-sdk/evolution"
4+ import { Core , Schema } from "@evolution-sdk/evolution"
5+
6+ type DecodeType = 'transaction' | 'witnessSet' | 'data'
57
68export function TransactionDecoder ( ) {
79 const [ txHex , setTxHex ] = useState ( "" )
810 const [ decodedJson , setDecodedJson ] = useState < string > ( "" )
911 const [ error , setError ] = useState < string | null > ( null )
12+ const [ decodeType , setDecodeType ] = useState < DecodeType > ( 'transaction' )
1013
1114 const decodeTx = async ( ) => {
1215 setError ( null )
@@ -16,60 +19,114 @@ export function TransactionDecoder() {
1619 const cleanHex = txHex . trim ( ) . replace ( / \s + / g, '' )
1720
1821 if ( ! cleanHex ) {
19- setError ( " Please enter a transaction CBOR hex string" )
22+ setError ( ` Please enter a ${ decodeType === ' transaction' ? 'transaction' : decodeType === 'witnessSet' ? 'transaction witness set' : 'plutus data' } CBOR hex string` )
2023 return
2124 }
2225
23- const tx = Core . Transaction . fromCBORHex ( cleanHex )
24- const json = JSON . stringify ( tx . toJSON ( ) , ( key , value ) =>
25- typeof value === 'bigint' ? value . toString ( ) : value
26- , 2 )
27- setDecodedJson ( json )
26+ if ( decodeType === 'transaction' ) {
27+ const tx = Core . Transaction . fromCBORHex ( cleanHex )
28+ const json = Schema . encodeSync ( Schema . parseJson ( Core . Transaction . Transaction , { space : 2 } ) ) ( tx )
29+ setDecodedJson ( json )
30+ } else if ( decodeType === 'witnessSet' ) {
31+ const witnessSet = Core . TransactionWitnessSet . fromCBORHex ( cleanHex )
32+ const json = Schema . encodeSync ( Schema . parseJson ( Core . TransactionWitnessSet . TransactionWitnessSet , { space : 2 } ) ) ( witnessSet )
33+ setDecodedJson ( json )
34+ } else {
35+ const data = Core . Data . fromCBORHex ( cleanHex )
36+ const json = Schema . encodeSync ( Schema . parseJson ( Core . Data . DataSchema , { space : 2 } ) ) ( data )
37+ setDecodedJson ( json )
38+ }
2839 } catch ( err ) {
2940 console . error ( 'Decode error:' , err )
30- setError ( err instanceof Error ? err . message : " Failed to decode transaction" )
41+ setError ( err instanceof Error ? err . message : ` Failed to decode ${ decodeType === ' transaction' ? 'transaction' : decodeType === 'witnessSet' ? 'witness set' : 'data' } ` )
3142 }
3243 }
3344
3445 return (
35- < div className = "space-y-6" >
36- < div className = "space-y-4" >
37- < button
38- onClick = { decodeTx }
39- className = "px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors"
40- >
41- Decode Transaction
42- </ button >
43-
44- < div className = "space-y-2" >
45- < label htmlFor = "tx-hex" className = "block text-sm font-medium" >
46- Transaction CBOR Hex
47- </ label >
48- < textarea
49- id = "tx-hex"
50- value = { txHex }
51- onChange = { ( e ) => setTxHex ( e . target . value ) }
52- placeholder = "Paste transaction CBOR hex here..."
53- className = "w-full h-32 px-3 py-2 bg-background border border-border rounded-md font-mono text-sm resize-y focus:outline-none focus:ring-2 focus:ring-ring"
54- />
46+ < div className = "max-w-6xl mx-auto space-y-6" >
47+ < div className = "rounded-lg border bg-card text-card-foreground shadow-sm" >
48+ < div className = "p-6 space-y-6" >
49+ < div className = "flex items-center justify-between" >
50+ < div className = "space-y-1" >
51+ < h3 className = "text-2xl font-semibold tracking-tight" > CBOR Decoder</ h3 >
52+ < p className = "text-sm text-muted-foreground" > Decode Cardano CBOR hex strings</ p >
53+ </ div >
54+ </ div >
55+
56+ < div className = "space-y-4" >
57+ < div className = "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4" >
58+ < div className = "space-y-2" >
59+ < label htmlFor = "decode-type" className = "text-sm font-medium leading-none" >
60+ Type
61+ </ label >
62+ < select
63+ id = "decode-type"
64+ value = { decodeType }
65+ onChange = { ( e ) => setDecodeType ( e . target . value as DecodeType ) }
66+ className = "flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring"
67+ >
68+ < option value = "transaction" > Transaction</ option >
69+ < option value = "witnessSet" > Transaction Witness Set</ option >
70+ < option value = "data" > Plutus Data</ option >
71+ </ select >
72+ </ div >
73+ </ div >
74+
75+ < div className = "space-y-2" >
76+ < label htmlFor = "tx-hex" className = "text-sm font-medium leading-none" >
77+ CBOR Hex Input
78+ </ label >
79+ < textarea
80+ id = "tx-hex"
81+ value = { txHex }
82+ onChange = { ( e ) => setTxHex ( e . target . value ) }
83+ placeholder = { `Paste ${ decodeType === 'transaction' ? 'transaction' : decodeType === 'witnessSet' ? 'transaction witness set' : 'plutus data' } CBOR hex here...` }
84+ className = "flex min-h-[120px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm font-mono resize-y focus:outline-none focus:ring-2 focus:ring-ring"
85+ />
86+ </ div >
87+
88+ < button
89+ onClick = { decodeTx }
90+ className = "sm:w-auto w-full inline-flex items-center justify-center rounded-md text-sm font-medium h-9 px-6 py-2 bg-zinc-700 text-white hover:bg-zinc-600 active:bg-zinc-500 transition-all cursor-pointer shadow-sm hover:shadow"
91+ >
92+ Decode { decodeType === 'transaction' ? 'Transaction' : decodeType === 'witnessSet' ? 'Witness Set' : 'Data' }
93+ </ button >
94+ </ div >
5595 </ div >
5696 </ div >
5797
5898 { error && (
59- < div className = "p-4 bg-destructive/10 border border-destructive/20 rounded-md" >
60- < p className = "text-destructive font-medium" > Error decoding transaction:</ p >
61- < p className = "text-destructive/80 text-sm mt-1" > { error } </ p >
99+ < div className = "rounded-lg border bg-card text-card-foreground shadow-sm" >
100+ < div className = "p-6" >
101+ < div className = "flex gap-3" >
102+ < svg className = "h-5 w-5 text-destructive shrink-0 mt-0.5" viewBox = "0 0 20 20" fill = "currentColor" >
103+ < path fillRule = "evenodd" d = "M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule = "evenodd" />
104+ </ svg >
105+ < div className = "flex-1 min-w-0 space-y-2" >
106+ < p className = "text-sm font-medium text-destructive" > Error decoding { decodeType === 'transaction' ? 'transaction' : decodeType === 'witnessSet' ? 'witness set' : 'data' } </ p >
107+ < pre className = "text-xs text-muted-foreground whitespace-pre-wrap break-words overflow-wrap-anywhere font-mono" > { error } </ pre >
108+ </ div >
109+ </ div >
110+ </ div >
62111 </ div >
63112 ) }
64-
113+
65114 { decodedJson && (
66- < div className = "space-y-2" >
67- < label className = "block text-sm font-medium" > Decoded Transaction (JSON)</ label >
68- < pre className = "w-full p-4 bg-muted border border-border rounded-md overflow-auto max-h-[600px] text-sm" >
69- < code > { decodedJson } </ code >
70- </ pre >
115+ < div className = "rounded-lg border bg-card text-card-foreground shadow-sm" >
116+ < div className = "p-6 space-y-3" >
117+ < h4 className = "text-sm font-semibold" > Decoded Result</ h4 >
118+ < pre className = "rounded-md bg-muted p-4 overflow-x-auto max-h-[500px]" >
119+ < code className = "text-xs" > { decodedJson } </ code >
120+ </ pre >
121+ </ div >
71122 </ div >
72123 ) }
124+
125+ < div className = "pt-4 border-t border-border/50" >
126+ < p className = "text-xs text-center text-muted-foreground" >
127+ Questions or feedback? < a href = "https://github.com/IntersectMBO/evolution-sdk/issues" target = "_blank" rel = "noopener noreferrer" className = "text-primary hover:underline" > Start a discussion on GitHub</ a >
128+ </ p >
129+ </ div >
73130 </ div >
74131 )
75132}
0 commit comments