1use alloy_primitives::{map::HashMap, Address, ChainId};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
11pub struct DelegationCapability {
12 pub addresses: Vec<Address>,
14}
15
16#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
18pub struct Capabilities {
19 pub delegation: DelegationCapability,
21}
22
23#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
25pub struct WalletCapabilities(
26 #[serde(with = "alloy_serde::quantity::hashmap")] pub HashMap<ChainId, Capabilities>,
27);
28
29impl WalletCapabilities {
30 pub fn get(&self, chain_id: ChainId) -> Option<&Capabilities> {
32 self.0.get(&chain_id)
33 }
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39 use alloy_primitives::{address, map::HashMap};
40
41 #[test]
42 fn ser() {
43 let caps = WalletCapabilities(HashMap::from_iter([(
44 0x69420,
45 Capabilities {
46 delegation: DelegationCapability {
47 addresses: vec![address!("90f79bf6eb2c4f870365e785982e1f101e93b906")],
48 },
49 },
50 )]));
51 assert_eq!(serde_json::to_string(&caps).unwrap(), "{\"0x69420\":{\"delegation\":{\"addresses\":[\"0x90f79bf6eb2c4f870365e785982e1f101e93b906\"]}}}");
52 }
53
54 #[test]
55 fn de() {
56 let caps: WalletCapabilities = serde_json::from_str(
57 r#"{
58 "0x69420": {
59 "delegation": {
60 "addresses": ["0x90f79bf6eb2c4f870365e785982e1f101e93b906"]
61 }
62 }
63 }"#,
64 )
65 .expect("could not deser");
66
67 assert_eq!(
68 caps,
69 WalletCapabilities(HashMap::from_iter([(
70 0x69420,
71 Capabilities {
72 delegation: DelegationCapability {
73 addresses: vec![address!("90f79bf6eb2c4f870365e785982e1f101e93b906")],
74 },
75 },
76 )]))
77 );
78 }
79
80 #[test]
81 fn test_get_capabilities() {
82 let caps = WalletCapabilities(HashMap::from_iter([(
83 0x69420,
84 Capabilities {
85 delegation: DelegationCapability {
86 addresses: vec![address!("90f79bf6eb2c4f870365e785982e1f101e93b906")],
87 },
88 },
89 )]));
90
91 let capabilities = caps.get(0x69420);
93 assert!(capabilities.is_some());
94 assert_eq!(
95 capabilities.unwrap().delegation.addresses[0],
96 address!("90f79bf6eb2c4f870365e785982e1f101e93b906")
97 );
98
99 let non_existing_capabilities = caps.get(0x12345);
101 assert!(non_existing_capabilities.is_none());
102 }
103
104 #[test]
105 fn test_capabilities_with_empty_delegation() {
106 let caps = WalletCapabilities(HashMap::from_iter([(
107 0x12345,
108 Capabilities { delegation: DelegationCapability { addresses: vec![] } },
109 )]));
110
111 let capabilities = caps.get(0x12345).unwrap();
113 assert!(capabilities.delegation.addresses.is_empty());
114
115 let serialized = serde_json::to_string(&caps).unwrap();
117 assert_eq!(serialized, "{\"0x12345\":{\"delegation\":{\"addresses\":[]}}}");
118 }
119}