wallet_adapter/wallet_ser_der/standard_features/
signin.rs1use wallet_adapter_common::{signin_standard::SignInOutput, WalletCommonUtils};
2use web_sys::{js_sys, wasm_bindgen::JsValue};
3
4use crate::{
5 Reflection, SemverVersion, SigninInput, StandardFunction, WalletAccount, WalletError,
6 WalletResult,
7};
8
9#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
12pub struct SignIn(StandardFunction);
13
14impl SignIn {
15 pub(crate) fn new(reflection: &Reflection, version: SemverVersion) -> WalletResult<Self> {
17 Ok(Self(StandardFunction::new(
18 reflection, version, "signIn", "solana",
19 )?))
20 }
21
22 pub(crate) async fn call_signin(
23 &self,
24 signin_input: &SigninInput,
25 public_key: [u8; 32],
26 ) -> WalletResult<SignInOutput> {
27 let outcome = self
28 .0
29 .callback
30 .call1(&JsValue::null(), &signin_input.get_object()?)?;
31
32 let outcome = js_sys::Promise::resolve(&outcome);
33
34 let value = wasm_bindgen_futures::JsFuture::from(outcome).await?;
35 let output_array = Reflection::new(value)?.get_array()?;
36
37 let first_index = Reflection::new(output_array.get(0))?;
38 let wallet_account = first_index.reflect_inner("account")?;
39 let wallet_account = WalletAccount::parse(Reflection::new(wallet_account)?)?;
40
41 let message_value = first_index.reflect_inner("signedMessage")?;
42 let message_bytes = Reflection::new(message_value)?.into_bytes()?;
43 let message =
44 core::str::from_utf8(&message_bytes).map_err(|error| WalletError::JsError {
45 name: "Invalid UTF-8 Message".to_string(),
46 message: error.to_string(),
47 stack: "INTERNAL_ERROR".to_string(),
48 })?;
49
50 signin_input.0.check_eq(message)?;
51
52 let signature_value = first_index.reflect_inner("signature")?;
53 let signature_bytes: [u8; 64] = Reflection::new(signature_value)?
54 .into_bytes()?
55 .try_into()
56 .or(Err(WalletError::InvalidEd25519SignatureBytes))?;
57
58 WalletCommonUtils::verify(&public_key, &message_bytes, &signature_bytes)?;
59
60 Ok(SignInOutput {
61 account: wallet_account.account,
62 message: message.to_string(),
63 signature: signature_bytes,
64 public_key,
65 })
66 }
67}