wallet_standard/types.rs
1use crate::WalletStandardConnect;
2use crate::WalletStandardDisconnect;
3
4pub trait WalletInfo {
5 type Account: WalletAccountInfo;
6
7 /// {@link `WalletVersion` | Version} of the Wallet Standard implemented by
8 /// the Wallet.
9 ///
10 /// Must be read-only, static, and canonically defined by the Wallet
11 /// Standard.
12 fn version(&self) -> String;
13 /// Name of the Wallet. This may be displayed by the app.
14 ///
15 /// Must be read-only, static, descriptive, unique, and canonically defined
16 /// by the wallet extension or application.
17 fn name(&self) -> String;
18 /// {@link `WalletIcon` | Icon} of the Wallet. This may be displayed by the
19 /// app.
20 ///
21 /// Must be read-only, static, and canonically defined by the wallet
22 /// extension or application.
23 fn icon(&self) -> String;
24 /// Chains supported by the Wallet.
25 ///
26 /// A **chain** is an {@link `IdentifierString`} which identifies a
27 /// blockchain in a canonical, human-readable format. [CAIP-2](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-2.md) chain IDs are compatible with this,
28 /// but are not required to be used.
29 ///
30 /// Each blockchain should define its own **chains** by extension of the
31 /// Wallet Standard, using its own namespace. The `standard` and
32 /// `experimental` namespaces are reserved by the Wallet Standard.
33 ///
34 /// The {@link "@wallet-standard/features".EventsFeature | `standard:events`
35 /// feature} should be used to notify the app if the value changes.
36 fn chains(&self) -> Vec<String>;
37 /// Features supported by the Wallet.
38 ///
39 /// A **feature name** is an {@link `IdentifierString`} which identifies a
40 /// **feature** in a canonical, human-readable format.
41 ///
42 /// Each blockchain should define its own features by extension of the
43 /// Wallet Standard.
44 ///
45 /// The `standard` and `experimental` namespaces are reserved by the Wallet
46 /// Standard.
47 ///
48 /// A **feature** may have any type. It may be a single method or value, or
49 /// a collection of them.
50 ///
51 /// A **conventional feature** has the following structure:
52 ///
53 /// ```ts
54 /// export type ExperimentalEncryptFeature = {
55 /// // Name of the feature.
56 /// 'experimental:encrypt': {
57 /// // Version of the feature.
58 /// version: '1.0.0';
59 /// // Properties of the feature.
60 /// ciphers: readonly 'x25519-xsalsa20-poly1305'[];
61 /// // Methods of the feature.
62 /// encrypt (data: Uint8Array): Promise<Uint8Array>;
63 /// };
64 /// };
65 /// ```
66 ///
67 /// The {@link "@wallet-standard/features".EventsFeature | `standard:events`
68 /// feature} should be used to notify the app if the value changes.
69 fn features(&self) -> Vec<String>;
70 /// {@link `WalletAccount` | Accounts} that the app is authorized to use.
71 ///
72 /// This can be set by the Wallet so the app can use authorized accounts on
73 /// the initial page load.
74 ///
75 /// The {@link "@wallet-standard/features".ConnectFeature |
76 /// `standard:connect` feature} should be used to obtain authorization to
77 /// the accounts.
78 ///
79 /// The {@link "@wallet-standard/features".EventsFeature | `standard:events`
80 /// feature} should be used to notify the app if the value changes.
81 fn accounts(&self) -> Vec<Self::Account>;
82}
83
84/// Interface of a **`WalletAccount`**, also referred to as an **Account**.
85///
86/// An account is a _read-only data object_ that is provided from the Wallet to
87/// the app, authorizing the app to use it.
88///
89/// The app can use an account to display and query information from a chain.
90///
91/// The app can also act using an account by passing it to {@link
92/// Wallet.features | features} of the Wallet.
93///
94/// Wallets may use or extend {@link
95/// "@wallet-standard/wallet".ReadonlyWalletAccount} which implements this
96/// interface.
97pub trait WalletAccountInfo {
98 /// Address of the account, corresponding with a public key.
99 fn address(&self) -> String;
100 /// Public key of the account, corresponding with a secret key to use.
101 fn public_key(&self) -> Vec<u8>;
102 /// Chains supported by the account.
103 ///
104 /// This must be a subset of the {@link Wallet.chains | chains} of the
105 /// Wallet.
106 fn chains(&self) -> Vec<String>;
107 /// Feature names supported by the account.
108 ///
109 /// This must be a subset of the names of {@link Wallet.features | features}
110 /// of the Wallet.
111 fn features(&self) -> Vec<String>;
112 /// Optional user-friendly descriptive label or name for the account. This
113 /// may be displayed by the app.
114 fn label(&self) -> Option<String>;
115 /// Optional user-friendly icon for the account. This may be displayed by
116 /// the app.
117 fn icon(&self) -> Option<String>;
118}
119
120pub trait Wallet {
121 type Wallet: WalletInfo;
122 type Account: WalletAccountInfo;
123
124 fn wallet(&self) -> Self::Wallet;
125 fn wallet_account(&self) -> Option<Self::Account>;
126
127 fn name(&self) -> String {
128 self.wallet().name()
129 }
130
131 fn icon(&self) -> String {
132 self.wallet().icon()
133 }
134
135 fn connected(&self) -> bool {
136 self.wallet_account().is_some()
137 }
138
139 fn try_public_key(&self) -> Option<Vec<u8>> {
140 self.wallet_account().map(|account| account.public_key())
141 }
142
143 fn public_key(&self) -> Vec<u8> {
144 self.try_public_key().unwrap()
145 }
146}
147
148pub trait WalletStandard: WalletStandardConnect + WalletStandardDisconnect + Wallet {}
149
150impl<T> WalletStandard for T where T: WalletStandardConnect + WalletStandardDisconnect + Wallet {}