@@ -6,8 +6,8 @@ use rustyline::error::ReadlineError;
66
77use orange_sdk:: bitcoin_payment_instructions:: amount:: Amount ;
88use orange_sdk:: {
9- ChainSource , Event , ExtraConfig , LoggerType , Mnemonic , PaymentInfo , Seed , SparkWalletConfig ,
10- StorageConfig , Tunables , Wallet , WalletConfig , bitcoin:: Network ,
9+ CashuConfig , ChainSource , CurrencyUnit , Event , ExtraConfig , LoggerType , Mnemonic , PaymentInfo ,
10+ Seed , SparkWalletConfig , StorageConfig , Tunables , Wallet , WalletConfig , bitcoin:: Network ,
1111} ;
1212use rand:: RngCore ;
1313use std:: fs;
@@ -23,6 +23,15 @@ const NETWORK: Network = Network::Bitcoin; // Supports Bitcoin and Regtest
2323#[ derive( Parser ) ]
2424#[ command( author, version, about, long_about = None ) ]
2525struct Cli {
26+ /// Use Cashu wallet instead of Spark
27+ #[ arg( long) ]
28+ cashu : bool ,
29+ /// Cashu mint URL (requires --cashu)
30+ #[ arg( long, requires = "cashu" ) ]
31+ mint_url : String ,
32+ /// npub.cash URL for lightning address support (requires --cashu)
33+ #[ arg( long, requires = "cashu" ) ]
34+ npubcash_url : Option < String > ,
2635 #[ command( subcommand) ]
2736 command : Option < Commands > ,
2837}
@@ -56,6 +65,13 @@ enum Commands {
5665 /// Amount in sats (optional)
5766 amount : Option < u64 > ,
5867 } ,
68+ /// Get the current lightning address
69+ GetLightningAddress ,
70+ /// Register a lightning address
71+ RegisterLightningAddress {
72+ /// The lightning address name to register
73+ name : String ,
74+ } ,
5975 /// Clear the screen
6076 Clear ,
6177 /// Exit the application
@@ -67,12 +83,22 @@ struct WalletState {
6783 shutdown : Arc < AtomicBool > ,
6884}
6985
70- fn get_config ( network : Network ) -> Result < WalletConfig > {
86+ fn get_config ( network : Network , cli : & Cli ) -> Result < WalletConfig > {
7187 let storage_path = format ! ( "./wallet_data/{network}" ) ;
7288
7389 // Generate or load seed
7490 let seed = generate_or_load_seed ( & storage_path) ?;
7591
92+ let extra_config = if cli. cashu {
93+ ExtraConfig :: Cashu ( CashuConfig {
94+ mint_url : cli. mint_url . clone ( ) ,
95+ unit : CurrencyUnit :: Sat ,
96+ npubcash_url : cli. npubcash_url . clone ( ) ,
97+ } )
98+ } else {
99+ ExtraConfig :: Spark ( SparkWalletConfig :: default ( ) )
100+ } ;
101+
76102 match network {
77103 Network :: Regtest => {
78104 let lsp_address = "185.150.162.100:3551"
@@ -96,7 +122,7 @@ fn get_config(network: Network) -> Result<WalletConfig> {
96122 network,
97123 seed,
98124 tunables : Tunables :: default ( ) ,
99- extra_config : ExtraConfig :: Spark ( SparkWalletConfig :: default ( ) ) ,
125+ extra_config,
100126 } )
101127 } ,
102128 Network :: Bitcoin => {
@@ -125,17 +151,17 @@ fn get_config(network: Network) -> Result<WalletConfig> {
125151 network,
126152 seed,
127153 tunables : Tunables :: default ( ) ,
128- extra_config : ExtraConfig :: Spark ( SparkWalletConfig :: default ( ) ) ,
154+ extra_config,
129155 } )
130156 } ,
131157 _ => Err ( anyhow:: anyhow!( "Unsupported network: {network:?}" ) ) ,
132158 }
133159}
134160
135161impl WalletState {
136- async fn new ( ) -> Result < Self > {
162+ async fn new ( cli : & Cli ) -> Result < Self > {
137163 let shutdown = Arc :: new ( AtomicBool :: new ( false ) ) ;
138- let config = get_config ( NETWORK )
164+ let config = get_config ( NETWORK , cli )
139165 . with_context ( || format ! ( "Failed to get wallet config for network: {NETWORK:?}" ) ) ?;
140166
141167 println ! ( "{} Initializing wallet..." , "⚡" . bright_yellow( ) ) ;
@@ -234,7 +260,7 @@ async fn main() -> Result<()> {
234260 println ! ( ) ;
235261
236262 // Initialize wallet once at startup
237- let mut state = WalletState :: new ( ) . await ?;
263+ let mut state = WalletState :: new ( & cli ) . await ?;
238264
239265 // Set up signal handling for graceful shutdown
240266 let shutdown_state = state. shutdown . clone ( ) ;
@@ -367,6 +393,14 @@ fn parse_command(input: &str) -> Result<Commands> {
367393
368394 Ok ( Commands :: EstimateFee { destination, amount } )
369395 } ,
396+ "get-lightning-address" | "get-ln-addr" | "ln-addr" => Ok ( Commands :: GetLightningAddress ) ,
397+ "register-lightning-address" | "register-ln-addr" => {
398+ if parts. len ( ) < 2 {
399+ return Err ( anyhow:: anyhow!( "Usage: register-lightning-address <name>" ) ) ;
400+ }
401+ let name = parts[ 1 ] . to_string ( ) ;
402+ Ok ( Commands :: RegisterLightningAddress { name } )
403+ } ,
370404 "clear" | "cls" => Ok ( Commands :: Clear ) ,
371405 "exit" | "quit" | "q" => Ok ( Commands :: Exit ) ,
372406 "help" => {
@@ -590,6 +624,60 @@ async fn execute_command(command: Commands, state: &mut WalletState) -> Result<(
590624 } ,
591625 }
592626 } ,
627+ Commands :: GetLightningAddress => {
628+ let wallet = state. wallet ( ) ;
629+
630+ println ! ( "{} Fetching lightning address..." , "⚡" . bright_yellow( ) ) ;
631+
632+ match wallet. get_lightning_address ( ) . await {
633+ Ok ( Some ( address) ) => {
634+ println ! (
635+ "{} Lightning address: {}" ,
636+ "⚡" . bright_green( ) ,
637+ address. bright_cyan( )
638+ ) ;
639+ } ,
640+ Ok ( None ) => {
641+ println ! ( "{} No lightning address registered yet." , "⚡" . bright_yellow( ) ) ;
642+ println ! (
643+ "{} Use 'register-lightning-address <name>' to register one" ,
644+ "Hint:" . bright_yellow( ) . bold( )
645+ ) ;
646+ } ,
647+ Err ( e) => {
648+ return Err ( anyhow:: anyhow!( "Failed to get lightning address: {:?}" , e) ) ;
649+ } ,
650+ }
651+ } ,
652+ Commands :: RegisterLightningAddress { name } => {
653+ let wallet = state. wallet ( ) ;
654+
655+ println ! (
656+ "{} Registering lightning address: {}..." ,
657+ "⚡" . bright_yellow( ) ,
658+ name. bright_cyan( )
659+ ) ;
660+
661+ match wallet. register_lightning_address ( name. clone ( ) ) . await {
662+ Ok ( ( ) ) => {
663+ println ! ( "{} Lightning address registered successfully!" , "✅" . bright_green( ) ) ;
664+ // Fetch and display the full address
665+ match wallet. get_lightning_address ( ) . await {
666+ Ok ( Some ( address) ) => {
667+ println ! (
668+ "{} Your lightning address: {}" ,
669+ "⚡" . bright_green( ) ,
670+ address. bright_cyan( )
671+ ) ;
672+ } ,
673+ _ => { } ,
674+ }
675+ } ,
676+ Err ( e) => {
677+ return Err ( anyhow:: anyhow!( "Failed to register lightning address: {:?}" , e) ) ;
678+ } ,
679+ }
680+ } ,
593681 Commands :: Clear => {
594682 print ! ( "\x1B [2J\x1B [1;1H" ) ;
595683 std:: io:: stdout ( ) . flush ( ) . unwrap ( ) ;
@@ -628,6 +716,12 @@ fn print_help() {
628716 println ! ( " {} <destination> [amount]" , "estimate-fee" . bright_green( ) . bold( ) ) ;
629717 println ! ( " Estimate the fee for a payment" ) ;
630718 println ! ( ) ;
719+ println ! ( " {}" , "get-lightning-address" . bright_green( ) . bold( ) ) ;
720+ println ! ( " Get the current lightning address" ) ;
721+ println ! ( ) ;
722+ println ! ( " {} <name>" , "register-lightning-address" . bright_green( ) . bold( ) ) ;
723+ println ! ( " Register a lightning address" ) ;
724+ println ! ( ) ;
631725 println ! ( " {}" , "clear" . bright_green( ) . bold( ) ) ;
632726 println ! ( " Clear the terminal screen" ) ;
633727 println ! ( ) ;
0 commit comments