1- use std:: path:: PathBuf ;
2-
31use clap:: { Parser , Subcommand } ;
4- use jsonrpsee:: core:: params:: ObjectParams ;
5- use miette:: { bail, Context , IntoDiagnostic } ;
62use tracing:: instrument;
7- use tx3_lang:: Protocol ;
83
4+ mod new;
95mod resolve;
106mod sign;
117mod submit;
128
139#[ derive( Parser ) ]
1410pub struct Args {
15- #[ arg( long, help = "Path for TX3 file describing transaction" ) ]
16- tx3_file : Option < PathBuf > ,
17-
18- #[ arg( long, help = "Args for TX3 file describing transaction" ) ]
19- tx3_args_json : Option < String > ,
20-
21- #[ arg( long, help = "Template for TX3 file" ) ]
22- tx3_template : Option < String > ,
23-
24- #[ arg( long, help = "Wallet that will sign the transaction" ) ]
25- signer : Option < String > ,
26-
27- /// Name of the provider to use. If undefined, will use default
28- #[ arg( long, help = "Path for TX3 file describing transaction" ) ]
29- provider : Option < String > ,
30-
3111 #[ command( subcommand) ]
32- command : Option < Commands > ,
12+ command : Commands ,
3313}
3414
3515#[ derive( Subcommand ) ]
3616enum Commands {
17+ /// Start a new full transaction, resolve, sign and submit
18+ New ( new:: Args ) ,
19+
3720 /// Resolve a transaction
3821 Resolve ( resolve:: Args ) ,
3922
@@ -47,163 +30,9 @@ enum Commands {
4730#[ instrument( "transaction" , skip_all) ]
4831pub async fn run ( args : Args , ctx : & crate :: Context ) -> miette:: Result < ( ) > {
4932 match args. command {
50- Some ( command) => match command {
51- Commands :: Sign ( args) => sign:: run ( args, ctx) . await ?,
52- Commands :: Submit ( args) => submit:: run ( args, ctx) . await ?,
53- Commands :: Resolve ( args) => resolve:: run ( args, ctx) . await ?,
54- } ,
55- None => {
56- let provider = match args. provider {
57- Some ( name) => ctx. store . find_provider ( & name) ,
58- None => ctx. store . default_provider ( ) ,
59- } ;
60-
61- let Some ( provider) = provider else {
62- bail ! ( "Provider not found" )
63- } ;
64-
65- let Some ( tx3_file) = args. tx3_file else {
66- bail ! ( "Tx3 file not provided" )
67- } ;
68-
69- let protocol = Protocol :: from_file ( tx3_file)
70- . load ( )
71- . into_diagnostic ( )
72- . context ( "parsing tx3 file" ) ?;
73-
74- let txs: Vec < String > = protocol. txs ( ) . map ( |x| x. name . to_string ( ) ) . collect ( ) ;
75-
76- let template = match args. tx3_template {
77- Some ( template) => template,
78- None => {
79- let template = if txs. len ( ) == 1 {
80- txs. first ( ) . unwrap ( ) . clone ( )
81- } else {
82- inquire:: Select :: new ( "What transaction do you want to build?" , txs)
83- . prompt ( )
84- . into_diagnostic ( ) ?
85- } ;
86- template
87- }
88- } ;
89-
90- let prototx = protocol. new_tx ( & template) . unwrap ( ) ;
91-
92- let argvalues = match args. tx3_args_json {
93- Some ( args) => {
94- let json_value = serde_json:: from_str ( & args)
95- . into_diagnostic ( )
96- . context ( "invalid tx3-args" ) ?;
97-
98- let serde_json:: Value :: Object ( value) = json_value else {
99- bail ! ( "tx3-args must be an object" ) ;
100- } ;
101-
102- value
103- }
104- None => {
105- let params = prototx. find_params ( ) ;
106- let mut argvalues = serde_json:: Map :: new ( ) ;
107- for ( key, value) in params {
108- match value {
109- tx3_lang:: ir:: Type :: Address => {
110- let options = ctx
111- . store
112- . wallets ( )
113- . iter ( )
114- . map ( |x| x. name . to_string ( ) )
115- . collect ( ) ;
116- let wallet = inquire:: Select :: new ( & format ! ( "{}: " , & key) , options)
117- . prompt ( )
118- . into_diagnostic ( ) ?;
119- let address = ctx
120- . store
121- . wallets ( )
122- . iter ( )
123- . find ( |x| x. name . to_string ( ) == wallet)
124- . unwrap ( )
125- . address ( provider. is_testnet ( ) ) ;
126- argvalues. insert (
127- key,
128- serde_json:: Value :: String ( address. to_bech32 ( ) . unwrap ( ) ) ,
129- ) ;
130- }
131- tx3_lang:: ir:: Type :: Int => {
132- let value = inquire:: Text :: new ( & format ! ( "{}: " , & key) )
133- . prompt ( )
134- . into_diagnostic ( ) ?
135- . parse :: < u64 > ( )
136- . into_diagnostic ( )
137- . context ( "invalid integer value" ) ?;
138- argvalues. insert ( key, serde_json:: Value :: Number ( value. into ( ) ) ) ;
139- }
140- _ => todo ! ( ) ,
141- } ;
142- }
143- argvalues
144- }
145- } ;
146-
147- let mut builder = ObjectParams :: new ( ) ;
148- builder
149- . insert (
150- "tir" ,
151- serde_json:: json!( {
152- "version" : tx3_lang:: ir:: IR_VERSION . to_string( ) ,
153- "encoding" : "hex" ,
154- "bytecode" : hex:: encode( prototx. ir_bytes( ) )
155- } ) ,
156- )
157- . unwrap ( ) ;
158- builder. insert ( "args" , argvalues) . unwrap ( ) ;
159-
160- let response = provider. trp_resolve ( & builder) . await ?;
161- let signer = match args. signer {
162- Some ( signer) => signer,
163- None => {
164- let options = ctx
165- . store
166- . wallets ( )
167- . iter ( )
168- . map ( |x| x. name . to_string ( ) )
169- . collect ( ) ;
170- inquire:: Select :: new (
171- "What wallet should be used to sign the transaction?" ,
172- options,
173- )
174- . prompt ( )
175- . into_diagnostic ( ) ?
176- }
177- } ;
178-
179- let wallet = ctx
180- . store
181- . wallets ( )
182- . iter ( )
183- . find ( |x| x. name . to_string ( ) == signer) ;
184-
185- let Some ( wallet) = wallet else {
186- bail ! ( "invalid signer wallet" )
187- } ;
188-
189- let password = match wallet. is_unsafe {
190- true => None ,
191- false => Some (
192- inquire:: Password :: new ( "Password:" )
193- . with_help_message ( "The spending password of your wallet" )
194- . with_display_mode ( inquire:: PasswordDisplayMode :: Masked )
195- . prompt ( )
196- . into_diagnostic ( ) ?,
197- ) ,
198- } ;
199-
200- let signed = wallet. sign ( response. tx , & password) ?;
201- let txhash = provider. submit ( & signed) . await ?;
202-
203- println ! ( "Submitted TX: {}" , hex:: encode( & signed) ) ;
204- println ! ( "TX Hash: {}" , hex:: encode( & txhash) ) ;
205- }
206- } ;
207-
208- Ok ( ( ) )
33+ Commands :: New ( args) => new:: run ( args, ctx) . await ,
34+ Commands :: Resolve ( args) => resolve:: run ( args, ctx) . await ,
35+ Commands :: Sign ( args) => sign:: run ( args, ctx) . await ,
36+ Commands :: Submit ( args) => submit:: run ( args, ctx) . await ,
37+ }
20938}
0 commit comments