@@ -17,7 +17,9 @@ use cln_lsps::lsps2::model::{
1717use  cln_lsps:: util; 
1818use  cln_lsps:: LSP_FEATURE_BIT ; 
1919use  cln_plugin:: options; 
20- use  cln_rpc:: model:: requests:: { DatastoreMode ,  DatastoreRequest ,  ListpeersRequest } ; 
20+ use  cln_rpc:: model:: requests:: { 
21+     DatastoreMode ,  DatastoreRequest ,  DeldatastoreRequest ,  ListdatastoreRequest ,  ListpeersRequest , 
22+ } ; 
2123use  cln_rpc:: model:: responses:: InvoiceResponse ; 
2224use  cln_rpc:: primitives:: { AmountOrAny ,  PublicKey ,  ShortChannelId } ; 
2325use  cln_rpc:: ClnRpc ; 
@@ -238,7 +240,6 @@ async fn on_lsps_lsps2_approve(
238240)  -> Result < serde_json:: Value ,  anyhow:: Error >  { 
239241    let  req:  ClnRpcLsps2Approve  = serde_json:: from_value ( v) ?; 
240242    let  ds_rec = DatastoreRecord  { 
241-         lsp_id :  req. lsp_id , 
242243        jit_channel_scid :  req. jit_channel_scid , 
243244        client_trusts_lsp :  req. client_trusts_lsp . unwrap_or_default ( ) , 
244245    } ; 
@@ -253,11 +254,7 @@ async fn on_lsps_lsps2_approve(
253254        hex :  None , 
254255        mode :  Some ( DatastoreMode :: CREATE_OR_REPLACE ) , 
255256        string :  Some ( ds_rec_json) , 
256-         key :  vec ! [ 
257-             "lsps" . to_string( ) , 
258-             "client" . to_string( ) , 
259-             req. jit_channel_scid. to_string( ) , 
260-         ] , 
257+         key :  vec ! [ "lsps" . to_string( ) ,  "client" . to_string( ) ,  req. lsp_id] , 
261258    } ; 
262259    let  _ds_res = cln_client. call_typed ( & ds_req) . await ?; 
263260    Ok ( serde_json:: Value :: default ( ) ) 
@@ -494,19 +491,52 @@ async fn on_htlc_accepted(
494491    Ok ( value) 
495492} 
496493
494+ /// Allows `zero_conf` channels to the client if the LSP is on the allowlist. 
497495async  fn  on_openchannel ( 
498-     _p :  cln_plugin:: Plugin < State > , 
499-     _v :  serde_json:: Value , 
496+     p :  cln_plugin:: Plugin < State > , 
497+     v :  serde_json:: Value , 
500498)  -> Result < serde_json:: Value ,  anyhow:: Error >  { 
501-     // Fixme: Register a list of trusted LSPs and check if LSP is allowlisted. 
502-     // And if we expect a channel to be opened. 
503-     // - either datastore or invoice label possible. 
504-     info ! ( "Allowing zero-conf channel from LSP" ) ; 
505-     Ok ( serde_json:: json!( { 
506-         "result" :  "continue" , 
507-         "reserve" :  "0msat" , 
508-         "mindepth" :  0 , 
509-     } ) ) 
499+     #[ derive( Deserialize ) ]  
500+     struct  Request  { 
501+         id :  String , 
502+     } 
503+ 
504+     let  req:  Request  = serde_json:: from_value ( v. get ( "openchannel" ) . unwrap ( ) . clone ( ) ) 
505+         . context ( "Failed to parse request JSON" ) ?; 
506+     let  dir = p. configuration ( ) . lightning_dir ; 
507+     let  rpc_path = Path :: new ( & dir) . join ( & p. configuration ( ) . rpc_file ) ; 
508+     let  mut  cln_client = cln_rpc:: ClnRpc :: new ( rpc_path. clone ( ) ) . await ?; 
509+ 
510+     let  ds_req = ListdatastoreRequest  { 
511+         key :  Some ( vec ! [ 
512+             "lsps" . to_string( ) , 
513+             "client" . to_string( ) , 
514+             req. id. clone( ) , 
515+         ] ) , 
516+     } ; 
517+     let  ds_res = cln_client. call_typed ( & ds_req) . await ?; 
518+     if  let  Some ( _rec)  = ds_res. datastore . iter ( ) . next ( )  { 
519+         info ! ( "Allowing zero-conf channel from LSP {}" ,  & req. id) ; 
520+         let  ds_req = DeldatastoreRequest  { 
521+             generation :  None , 
522+             key :  vec ! [ "lsps" . to_string( ) ,  "client" . to_string( ) ,  req. id. clone( ) ] , 
523+         } ; 
524+         if  let  Some ( err)  = cln_client. call_typed ( & ds_req) . await . err ( )  { 
525+             // We can do nothing but report that there was an issue deleting the 
526+             // datastore record. 
527+             warn ! ( "Failed to delete LSP record from datastore: {}" ,  err) ; 
528+         } 
529+         // Fixme: Check that we actually use client-trusts-LSP mode - can be 
530+         // found in the ds record. 
531+         return  Ok ( serde_json:: json!( { 
532+             "result" :  "continue" , 
533+             "reserve" :  "0msat" , 
534+             "mindepth" :  0 , 
535+         } ) ) ; 
536+     }  else  { 
537+         // Not a requested JIT-channel opening, continue. 
538+         Ok ( serde_json:: json!( { "result" :  "continue" } ) ) 
539+     } 
510540} 
511541
512542async  fn  on_lsps_listprotocols ( 
@@ -659,7 +689,6 @@ struct ClnRpcLsps2Approve {
659689
660690#[ derive( Debug ,  Clone ,  Serialize ,  Deserialize ) ]  
661691struct  DatastoreRecord  { 
662-     lsp_id :  String , 
663692    jit_channel_scid :  ShortChannelId , 
664693    client_trusts_lsp :  bool , 
665694} 
0 commit comments