Skip to content

Commit 1fa5e40

Browse files
committed
add typescript definitions for request signer trait
Signed-off-by: Ryan Tate <ryan.tate@spruceid.com>
1 parent 6617532 commit 1fa5e40

File tree

3 files changed

+127
-17
lines changed

3 files changed

+127
-17
lines changed

Cargo.lock

Lines changed: 101 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

wasm/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#[cfg(target_arch = "wasm32")]
12
pub mod signer;
23

34
use dc_api_core::request::DCAPIRequest;

wasm/src/signer.rs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,25 @@
1+
use async_trait::async_trait;
12
use dc_api_core::openid4vp::verifier::request_signer::{JWK, RequestSigner};
23
use js_sys::{Function, Promise, Reflect, Uint8Array};
34
use std::{fmt::Debug, sync::Arc};
45
use wasm_bindgen::prelude::*;
56
use 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)]
824
pub 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)]
6174
pub 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

Comments
 (0)