1+ use async_trait:: async_trait;
12use dc_api_core:: openid4vp:: verifier:: request_signer:: { JWK , RequestSigner } ;
23use js_sys:: { Function , Promise , Reflect , Uint8Array } ;
34use std:: { fmt:: Debug , sync:: Arc } ;
45use wasm_bindgen:: prelude:: * ;
56use wasm_bindgen_futures:: JsFuture ;
67
8+ #[ wasm_bindgen( typescript_custom_section) ]
9+ const TS_IFACE : & ' static str = r#"
10+ export interface RequestSigner {
11+ // Keep these synchronous to match the Rust trait above.
12+ alg(): string;
13+ jwk(): any;
14+
15+ // Must return a Promise of bytes.
16+ sign(payload: Uint8Array): Promise<Uint8Array>;
17+
18+ // Optional; if absent, Rust falls back to sign()
19+ try_sign?(payload: Uint8Array): Promise<Uint8Array>;
20+ }
21+ "# ;
22+
723#[ derive( Debug , Clone ) ]
824pub struct JsErr ( String ) ;
925
@@ -53,11 +69,8 @@ fn js_to_vec_u8(v: &JsValue) -> Result<Vec<u8>, JsErr> {
5369 }
5470}
5571
56- #[ derive( Debug , Clone ) ]
57- pub struct ShareableJsRequestSigner ( Arc < JsRequestSigner > ) ;
58-
5972#[ wasm_bindgen]
60- #[ derive( Clone ) ]
73+ #[ derive( Debug , Clone ) ]
6174pub struct JsRequestSigner {
6275 obj : JsValue ,
6376}
@@ -77,13 +90,13 @@ impl std::fmt::Debug for JsRequestSigner {
7790 }
7891}
7992
80- #[ async_trait:: async_trait ( ?Send ) ]
81- impl RequestSigner for ShareableJsRequestSigner {
93+ #[ async_trait( ?Send ) ]
94+ impl RequestSigner for JsRequestSigner {
8295 type Error = JsErr ;
8396
8497 fn alg ( & self ) -> Result < String , Self :: Error > {
8598 // Allow either a string return or a Promise<string>.
86- let out = call_method ( & self . 0 . obj , "alg" , & [ ] ) ?;
99+ let out = call_method ( & self . obj , "alg" , & [ ] ) ?;
87100 if out. is_instance_of :: < Promise > ( ) {
88101 // In a sync method, we can’t await; prefer requiring sync for `alg()`.
89102 // If you *really* need async here, change the trait to async and await.
@@ -96,7 +109,7 @@ impl RequestSigner for ShareableJsRequestSigner {
96109 }
97110
98111 fn jwk ( & self ) -> Result < JWK , Self :: Error > {
99- let out = call_method ( & self . 0 . obj , "jwk" , & [ ] ) ?;
112+ let out = call_method ( & self . obj , "jwk" , & [ ] ) ?;
100113 if out. is_instance_of :: < Promise > ( ) {
101114 return Err ( JsErr (
102115 "`jwk()` must be synchronous; make it return a plain object" . into ( ) ,
@@ -107,9 +120,9 @@ impl RequestSigner for ShareableJsRequestSigner {
107120
108121 async fn sign ( & self , payload : & [ u8 ] ) -> Vec < u8 > {
109122 let arg = slice_to_u8_array ( payload) ;
110- let out = match call_method ( & self . 0 . obj , "sign" , & [ arg. into ( ) ] ) {
123+ let out = match call_method ( & self . obj , "sign" , & [ arg. into ( ) ] ) {
111124 Ok ( v) => v,
112- Err ( e ) => return vec ! [ ] , // or panic/log; you can also bubble via a different signature
125+ Err ( _e ) => return vec ! [ ] , // or panic/log; you can also bubble via a different signature
113126 } ;
114127 let resolved = if out. is_instance_of :: < Promise > ( ) {
115128 match await_promise ( Promise :: from ( out) ) . await {
@@ -125,10 +138,10 @@ impl RequestSigner for ShareableJsRequestSigner {
125138 async fn try_sign ( & self , payload : & [ u8 ] ) -> Result < Vec < u8 > , Self :: Error > {
126139 // Prefer a dedicated try_sign if provided. Otherwise fall back to sign().
127140 let has_try =
128- Reflect :: has ( & self . 0 . obj , & JsValue :: from_str ( "try_sign" ) ) . map_err ( JsErr :: from) ?;
141+ Reflect :: has ( & self . obj , & JsValue :: from_str ( "try_sign" ) ) . map_err ( JsErr :: from) ?;
129142 if has_try {
130143 let arg = slice_to_u8_array ( payload) ;
131- let out = call_method ( & self . 0 . obj , "try_sign" , & [ arg. into ( ) ] ) ?;
144+ let out = call_method ( & self . obj , "try_sign" , & [ arg. into ( ) ] ) ?;
132145 let resolved = if out. is_instance_of :: < Promise > ( ) {
133146 await_promise ( Promise :: from ( out) ) . await ?
134147 } else {
0 commit comments