1- //! Object-safe wrapper around ldk-node's async `KVStore ` trait.
1+ //! Object-safe wrapper around ldk-node's async `PaginatedKVStore ` trait.
22//!
33//! `lightning`'s `KVStore` returns `impl Future` from its methods, which makes the trait not
44//! object-safe — orange-sdk can't share a backend across components as `Arc<dyn KVStore>`.
55//!
66//! This module defines `DynStore`, an object-safe trait covering the kv methods (returning
7- //! boxed futures), with a blanket impl over any concrete type that implements `KVStore`. The
8- //! whole crate stores backends as `Arc<dyn DynStore>`; conversion to a value ldk-node accepts
9- //! happens at the call site through a thin newtype that delegates back to `DynStore`.
7+ //! boxed futures), with a blanket impl over any concrete type that implements
8+ //! `PaginatedKVStore`. The whole crate stores backends as `Arc<dyn DynStore>`; conversion to a
9+ //! value ldk-node accepts happens at the call site through a thin newtype that delegates back to
10+ //! `DynStore`.
1011
1112use std:: future:: Future ;
1213use std:: pin:: Pin ;
1314use std:: sync:: Arc ;
1415
1516use ldk_node:: lightning:: io;
16- use ldk_node:: lightning:: util:: persist:: KVStore ;
17+ use ldk_node:: lightning:: util:: persist:: {
18+ KVStore , PageToken , PaginatedKVStore , PaginatedListResponse ,
19+ } ;
1720use tokio:: task:: JoinSet ;
1821
1922/// Matches the connection capacity used by the VSS HTTP client. Keeping the
@@ -38,11 +41,15 @@ pub(crate) trait DynStore: Send + Sync + 'static {
3841 fn list_async (
3942 & self , primary_namespace : & str , secondary_namespace : & str ,
4043 ) -> Pin < Box < dyn Future < Output = Result < Vec < String > , io:: Error > > + Send + ' static > > ;
44+
45+ fn list_paginated_async (
46+ & self , primary_namespace : & str , secondary_namespace : & str , page_token : Option < PageToken > ,
47+ ) -> Pin < Box < dyn Future < Output = Result < PaginatedListResponse , io:: Error > > + Send + ' static > > ;
4148}
4249
4350impl < T > DynStore for T
4451where
45- T : KVStore + Send + Sync + ' static ,
52+ T : PaginatedKVStore + Send + Sync + ' static ,
4653{
4754 fn read_async (
4855 & self , p : & str , s : & str , k : & str ,
6774 ) -> Pin < Box < dyn Future < Output = Result < Vec < String > , io:: Error > > + Send + ' static > > {
6875 Box :: pin ( <T as KVStore >:: list ( self , p, s) )
6976 }
77+
78+ fn list_paginated_async (
79+ & self , p : & str , s : & str , page_token : Option < PageToken > ,
80+ ) -> Pin < Box < dyn Future < Output = Result < PaginatedListResponse , io:: Error > > + Send + ' static > > {
81+ Box :: pin ( <T as PaginatedKVStore >:: list_paginated ( self , p, s, page_token) )
82+ }
7083}
7184
7285// Make `dyn DynStore` itself implement `KVStore` so the same handle orange-sdk shares
@@ -96,8 +109,16 @@ impl KVStore for dyn DynStore {
96109 }
97110}
98111
112+ impl PaginatedKVStore for dyn DynStore {
113+ fn list_paginated (
114+ & self , p : & str , s : & str , page_token : Option < PageToken > ,
115+ ) -> impl Future < Output = Result < PaginatedListResponse , io:: Error > > + Send + ' static {
116+ self . list_paginated_async ( p, s, page_token)
117+ }
118+ }
119+
99120/// Cloneable handle wrapping `Arc<dyn DynStore>` that satisfies ldk-node's
100- /// `KVStore + Send + Sync + 'static` bound on `build_with_store`. The trait impl just
121+ /// `PaginatedKVStore + Send + Sync + 'static` bound on `build_with_store`. The trait impl just
101122/// forwards to the underlying `dyn DynStore`.
102123#[ derive( Clone ) ]
103124pub ( crate ) struct LdkNodeStore ( pub ( crate ) Arc < dyn DynStore > ) ;
@@ -125,6 +146,14 @@ impl KVStore for LdkNodeStore {
125146 }
126147}
127148
149+ impl PaginatedKVStore for LdkNodeStore {
150+ fn list_paginated (
151+ & self , p : & str , s : & str , page_token : Option < PageToken > ,
152+ ) -> impl Future < Output = Result < PaginatedListResponse , io:: Error > > + Send + ' static {
153+ self . 0 . list_paginated_async ( p, s, page_token)
154+ }
155+ }
156+
128157/// Reads a set of keys concurrently while preserving the input order.
129158///
130159/// Storage formats expose record collections as a list followed by individual
@@ -242,6 +271,15 @@ mod tests {
242271 }
243272 }
244273
274+ impl PaginatedKVStore for ControlledStore {
275+ fn list_paginated (
276+ & self , _primary_namespace : & str , _secondary_namespace : & str ,
277+ _page_token : Option < PageToken > ,
278+ ) -> impl Future < Output = Result < PaginatedListResponse , io:: Error > > + Send + ' static {
279+ ready ( Ok ( PaginatedListResponse { keys : Vec :: new ( ) , next_page_token : None } ) )
280+ }
281+ }
282+
245283 #[ tokio:: test]
246284 async fn bounded_reads_limit_concurrency_and_preserve_order ( ) {
247285 let ( entered, mut entered_rx) = mpsc:: unbounded_channel ( ) ;
0 commit comments