11use std:: result:: Result ;
22use std:: str:: FromStr ;
3- use std:: sync:: Arc ;
4- use std:: time:: Duration ;
53
6- use axum_server:: tls_rustls:: RustlsConfig ;
74use bitcoin:: { Amount , Psbt } ;
85pub use corepc_node; // re-export for convenience
96use corepc_node:: AddressType ;
10- use http:: StatusCode ;
11- use ohttp:: hpke:: { Aead , Kdf , Kem } ;
12- use ohttp:: { KeyId , SymmetricSuite } ;
137use once_cell:: sync:: { Lazy , OnceCell } ;
14- use payjoin:: io:: { fetch_ohttp_keys_with_cert, Error as IOError } ;
15- use payjoin:: OhttpKeys ;
16- use rcgen:: Certificate ;
17- use reqwest:: { Client , ClientBuilder } ;
18- use rustls:: pki_types:: CertificateDer ;
19- use rustls:: RootCertStore ;
20- use tempfile:: tempdir;
21- use tokio:: task:: JoinHandle ;
228use tracing:: Level ;
239use tracing_subscriber:: { EnvFilter , FmtSubscriber } ;
2410
11+ #[ cfg( feature = "v2" ) ]
12+ pub mod v2;
13+ #[ cfg( feature = "v2" ) ]
14+ pub use v2:: * ;
15+
2516pub type BoxError = Box < dyn std:: error:: Error + ' static > ;
2617pub type BoxSendSyncError = Box < dyn std:: error:: Error + Send + Sync > ;
2718
28- pub use payjoin:: persist:: { InMemoryPersister , SessionPersister } ;
29-
3019static INIT_TRACING : OnceCell < ( ) > = OnceCell :: new ( ) ;
3120
3221pub fn init_tracing ( ) {
@@ -41,137 +30,6 @@ pub fn init_tracing() {
4130 } ) ;
4231}
4332
44- pub struct TestServices {
45- cert : Certificate ,
46- directory : ( u16 , Option < JoinHandle < Result < ( ) , BoxSendSyncError > > > ) ,
47- ohttp_relay : ( u16 , Option < JoinHandle < Result < ( ) , BoxSendSyncError > > > ) ,
48- http_agent : Arc < Client > ,
49- }
50-
51- impl TestServices {
52- pub async fn initialize ( ) -> Result < Self , BoxSendSyncError > {
53- // TODO add a UUID, and cleanup guard to delete after on successful run
54- let cert = local_cert_key ( ) ;
55- let cert_der = cert. cert . der ( ) . to_vec ( ) ;
56- let key_der = cert. signing_key . serialize_der ( ) ;
57- let cert_key = ( cert_der. clone ( ) , key_der) ;
58-
59- let mut root_store = RootCertStore :: empty ( ) ;
60- root_store. add ( CertificateDer :: from ( cert. cert . der ( ) . to_vec ( ) ) ) . unwrap ( ) ;
61-
62- let directory = init_directory ( cert_key, root_store. clone ( ) ) . await ?;
63- let ohttp_relay = init_ohttp_relay ( root_store, None ) . await ?;
64-
65- let http_agent: Arc < Client > = Arc :: new ( http_agent ( cert_der) ?) ;
66-
67- Ok ( Self {
68- cert : cert. cert ,
69- directory : ( directory. 0 , Some ( directory. 1 ) ) ,
70- ohttp_relay : ( ohttp_relay. 0 , Some ( ohttp_relay. 1 ) ) ,
71- http_agent,
72- } )
73- }
74-
75- pub fn cert ( & self ) -> Vec < u8 > { self . cert . der ( ) . to_vec ( ) }
76-
77- pub fn directory_url ( & self ) -> String { format ! ( "https://localhost:{}" , self . directory. 0 ) }
78-
79- pub fn take_directory_handle ( & mut self ) -> JoinHandle < Result < ( ) , BoxSendSyncError > > {
80- self . directory . 1 . take ( ) . expect ( "directory handle not found" )
81- }
82-
83- pub fn ohttp_relay_url ( & self ) -> String { format ! ( "http://localhost:{}" , self . ohttp_relay. 0 ) }
84-
85- pub fn ohttp_gateway_url ( & self ) -> String {
86- format ! ( "{}/.well-known/ohttp-gateway" , self . directory_url( ) )
87- }
88-
89- pub fn take_ohttp_relay_handle ( & mut self ) -> JoinHandle < Result < ( ) , BoxSendSyncError > > {
90- self . ohttp_relay . 1 . take ( ) . expect ( "ohttp relay handle not found" )
91- }
92-
93- pub fn http_agent ( & self ) -> Arc < Client > { self . http_agent . clone ( ) }
94-
95- pub async fn wait_for_services_ready ( & self ) -> Result < ( ) , & ' static str > {
96- wait_for_service_ready ( & self . ohttp_relay_url ( ) , self . http_agent ( ) ) . await ?;
97- wait_for_service_ready ( & self . directory_url ( ) , self . http_agent ( ) ) . await ?;
98- Ok ( ( ) )
99- }
100-
101- pub async fn fetch_ohttp_keys ( & self ) -> Result < OhttpKeys , IOError > {
102- fetch_ohttp_keys_with_cert (
103- self . ohttp_relay_url ( ) . as_str ( ) ,
104- self . directory_url ( ) . as_str ( ) ,
105- & self . cert ( ) ,
106- )
107- . await
108- }
109- }
110-
111- pub async fn init_directory (
112- local_cert_key : ( Vec < u8 > , Vec < u8 > ) ,
113- root_store : RootCertStore ,
114- ) -> std:: result:: Result <
115- ( u16 , tokio:: task:: JoinHandle < std:: result:: Result < ( ) , BoxSendSyncError > > ) ,
116- BoxSendSyncError ,
117- > {
118- let tempdir = tempdir ( ) ?;
119- let config = payjoin_mailroom:: config:: Config :: new (
120- "[::]:0" . parse ( ) . expect ( "valid listener address" ) ,
121- tempdir. path ( ) . to_path_buf ( ) ,
122- Duration :: from_secs ( 2 ) ,
123- Some ( payjoin_mailroom:: config:: V1Config :: default ( ) ) ,
124- ) ;
125-
126- let tls_config = RustlsConfig :: from_der ( vec ! [ local_cert_key. 0 ] , local_cert_key. 1 ) . await ?;
127-
128- let ( port, handle) =
129- payjoin_mailroom:: serve_manual_tls ( config, Some ( tls_config) , root_store, None )
130- . await
131- . map_err ( |e| e. to_string ( ) ) ?;
132-
133- let handle = tokio:: spawn ( async move {
134- let _tempdir = tempdir; // keep the tempdir until the directory shuts down
135- handle. await . map_err ( |e| e. to_string ( ) ) ?. map_err ( |e| e. to_string ( ) . into ( ) )
136- } ) ;
137-
138- Ok ( ( port, handle) )
139- }
140-
141- pub async fn init_ohttp_relay (
142- root_store : RootCertStore ,
143- default_gateway : Option < payjoin_mailroom:: ohttp_relay:: GatewayUri > ,
144- ) -> std:: result:: Result <
145- ( u16 , tokio:: task:: JoinHandle < std:: result:: Result < ( ) , BoxSendSyncError > > ) ,
146- BoxSendSyncError ,
147- > {
148- let tempdir = tempdir ( ) ?;
149- let config = payjoin_mailroom:: config:: Config :: new (
150- "[::]:0" . parse ( ) . expect ( "valid listener address" ) ,
151- tempdir. path ( ) . to_path_buf ( ) ,
152- Duration :: from_secs ( 2 ) ,
153- None ,
154- ) ;
155-
156- let ( port, handle) =
157- payjoin_mailroom:: serve_manual_tls ( config, None , root_store, default_gateway)
158- . await
159- . map_err ( |e| e. to_string ( ) ) ?;
160-
161- let handle = tokio:: spawn ( async move {
162- let _tempdir = tempdir; // keep the tempdir until the relay shuts down
163- handle. await . map_err ( |e| e. to_string ( ) ) ?. map_err ( |e| e. to_string ( ) . into ( ) )
164- } ) ;
165-
166- Ok ( ( port, handle) )
167- }
168-
169- /// generate or get a DER encoded localhost cert and key.
170- pub fn local_cert_key ( ) -> rcgen:: CertifiedKey < rcgen:: KeyPair > {
171- rcgen:: generate_simple_self_signed ( vec ! [ "0.0.0.0" . to_string( ) , "localhost" . to_string( ) ] )
172- . expect ( "Failed to generate cert" )
173- }
174-
17533pub fn init_bitcoind ( ) -> Result < corepc_node:: Node , BoxError > {
17634 let bitcoind_exe = corepc_node:: exe_path ( ) ?;
17735 let mut conf = corepc_node:: Conf :: default ( ) ;
@@ -226,10 +84,6 @@ fn create_and_fund_wallets<W: AsRef<str>>(
22684 Ok ( funded_wallets)
22785}
22886
229- pub fn http_agent ( cert_der : Vec < u8 > ) -> Result < Client , BoxSendSyncError > {
230- Ok ( http_agent_builder ( cert_der) . build ( ) ?)
231- }
232-
23387pub fn init_bitcoind_multi_sender_single_reciever (
23488 number_of_senders : usize ,
23589) -> Result < ( corepc_node:: Node , Vec < corepc_node:: Client > , corepc_node:: Client ) , BoxError > {
@@ -243,43 +97,8 @@ pub fn init_bitcoind_multi_sender_single_reciever(
24397 Ok ( ( bitcoind, senders, receiver) )
24498}
24599
246- fn http_agent_builder ( cert_der : Vec < u8 > ) -> ClientBuilder {
247- ClientBuilder :: new ( ) . http1_only ( ) . use_rustls_tls ( ) . add_root_certificate (
248- reqwest:: tls:: Certificate :: from_der ( cert_der. as_slice ( ) )
249- . expect ( "cert_der should be a valid DER-encoded certificate" ) ,
250- )
251- }
252-
253- const TESTS_TIMEOUT : Duration = Duration :: from_secs ( 20 ) ;
254- const WAIT_SERVICE_INTERVAL : Duration = Duration :: from_secs ( 3 ) ;
255-
256- pub async fn wait_for_service_ready (
257- service_url : & str ,
258- agent : Arc < Client > ,
259- ) -> Result < ( ) , & ' static str > {
260- let health_url = format ! ( "{}/health" , service_url. trim_end_matches( "/" ) ) ;
261- let start = std:: time:: Instant :: now ( ) ;
262-
263- while start. elapsed ( ) < TESTS_TIMEOUT {
264- let request_result =
265- agent. get ( health_url. clone ( ) ) . send ( ) . await . map_err ( |_| "Bad request" ) ?;
266- match request_result. status ( ) {
267- StatusCode :: OK => return Ok ( ( ) ) ,
268- StatusCode :: NOT_FOUND => return Err ( "Endpoint not found" ) ,
269- _ => std:: thread:: sleep ( WAIT_SERVICE_INTERVAL ) ,
270- }
271- }
272-
273- Err ( "Timeout waiting for service to be ready" )
274- }
275-
276100pub static EXAMPLE_URL : & str = "https://example.com" ;
277101
278- pub const KEY_ID : KeyId = 1 ;
279- pub const KEM : Kem = Kem :: K256Sha256 ;
280- pub const SYMMETRIC : & [ SymmetricSuite ] =
281- & [ ohttp:: SymmetricSuite :: new ( Kdf :: HkdfSha256 , Aead :: ChaCha20Poly1305 ) ] ;
282-
283102// https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#user-content-span_idtestvectorsspanTest_vectors
284103// | InputScriptType | Original PSBT Fee rate | maxadditionalfeecontribution | additionalfeeoutputindex|
285104// |-----------------|-----------------------|------------------------------|-------------------------|
0 commit comments