wallet_adapter/wallet_ser_der/standard_features/
features.rs1use wallet_adapter_common::{
2 feature_support::FeatureSupport,
3 standardized_events::{
4 SOLANA_SIGN_AND_SEND_TRANSACTION_IDENTIFIER, SOLANA_SIGN_IN_IDENTIFIER,
5 SOLANA_SIGN_MESSAGE_IDENTIFIER, SOLANA_SIGN_TRANSACTION_IDENTIFIER,
6 STANDARD_CONNECT_IDENTIFIER, STANDARD_DISCONNECT_IDENTIFIER, STANDARD_EVENTS_IDENTIFIER,
7 },
8};
9
10use crate::{
11 Connect, Disconnect, Reflection, SemverVersion, SignIn, SignMessage, SignTransaction,
12 StandardEvents, WalletError, WalletResult,
13};
14
15#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
20pub struct Features {
21 pub(crate) connect: Connect,
23 pub(crate) disconnect: Disconnect,
25 pub(crate) events: StandardEvents,
27 pub(crate) sign_and_send_tx: SignTransaction,
29 pub(crate) sign_tx: SignTransaction,
31 pub(crate) sign_message: SignMessage,
33 pub(crate) sign_in: Option<SignIn>,
35 extensions: Vec<String>,
37}
38
39impl Features {
40 pub(crate) fn parse(reflection: &Reflection) -> WalletResult<(Self, FeatureSupport)> {
42 let features_keys = reflection.object_to_vec_string("features")?;
43 let features_object = Reflection::new_from_str(reflection.get_inner(), "features")?;
44
45 let mut features = Features::default();
46 let mut supported_features = FeatureSupport::default();
47
48 features_keys.into_iter().try_for_each(|feature| {
49 let inner_object = features_object.reflect_inner(&feature)?;
50 let inner_object = Reflection::new(inner_object)?;
51
52 if feature.starts_with("standard:") || feature.starts_with("solana:") {
53 let version = SemverVersion::from_jsvalue(&inner_object)?;
54
55 if feature == STANDARD_CONNECT_IDENTIFIER {
56 features.connect = Connect::new(&inner_object, version)?;
57 supported_features.connect = true;
58 } else if feature == STANDARD_DISCONNECT_IDENTIFIER {
59 features.disconnect = Disconnect::new(&inner_object, version)?;
60 supported_features.disconnect = true;
61 } else if feature == STANDARD_EVENTS_IDENTIFIER {
62 features.events = StandardEvents::new(&inner_object, version)?;
63 supported_features.events = true;
64 } else if feature == SOLANA_SIGN_AND_SEND_TRANSACTION_IDENTIFIER {
65 features.sign_and_send_tx =
66 SignTransaction::new_sign_and_send_tx(&inner_object, version)?;
67 supported_features.sign_and_send_tx = true;
68 } else if feature == SOLANA_SIGN_TRANSACTION_IDENTIFIER {
69 features.sign_tx = SignTransaction::new_sign_tx(&inner_object, version)?;
70 supported_features.sign_tx = true;
71 } else if feature == SOLANA_SIGN_MESSAGE_IDENTIFIER {
72 features.sign_message = SignMessage::new(&inner_object, version)?;
73 supported_features.sign_message = true;
74 } else if feature == SOLANA_SIGN_IN_IDENTIFIER {
75 features
76 .sign_in
77 .replace(SignIn::new(&inner_object, version)?);
78 supported_features.sign_in = true;
79 } else {
80 return Err(WalletError::UnsupportedWalletFeature(feature));
81 }
82 } else {
83 features.extensions.push(feature);
84 }
85
86 Ok(())
87 })?;
88
89 Ok((features, supported_features))
90 }
91
92 pub fn extensions(&self) -> &[String] {
94 &self.extensions
95 }
96}