Skip to content

Commit

Permalink
eip5792: use ChainId in WalletCapabilities (#1622)
Browse files Browse the repository at this point in the history
* eip5792: use ChainId in WalletCapabilities

* Update crates/consensus/Cargo.toml
  • Loading branch information
tcoratger authored Nov 6, 2024
1 parent 0a93fe7 commit c2ac91b
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 8 deletions.
2 changes: 1 addition & 1 deletion crates/eip5792/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ exclude.workspace = true

[dependencies]
alloy-primitives = { workspace = true, features = ["serde", "map"] }
alloy-serde = { workspace = true, optional = true }
alloy-serde.workspace = true
serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true

Expand Down
55 changes: 48 additions & 7 deletions crates/eip5792/src/wallet.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use alloy_primitives::{map::HashMap, Address, ChainId, U64};
use alloy_primitives::{map::HashMap, Address, ChainId};
use serde::{Deserialize, Serialize};

/// The capability to perform [EIP-7702][eip-7702] delegations, sponsored by the sequencer.
Expand All @@ -21,26 +21,27 @@ pub struct Capabilities {
}

/// A map of wallet capabilities per chain ID.
// NOTE(onbjerg): We use `U64` to serialize the chain ID as a quantity. This can be changed back to `ChainId` with https://github.com/alloy-rs/alloy/issues/1502
#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
pub struct WalletCapabilities(pub HashMap<U64, Capabilities>);
pub struct WalletCapabilities(
#[serde(with = "alloy_serde::quantity::hashmap")] pub HashMap<ChainId, Capabilities>,
);

impl WalletCapabilities {
/// Get the capabilities of the wallet API for the specified chain ID.
pub fn get(&self, chain_id: ChainId) -> Option<&Capabilities> {
self.0.get(&U64::from(chain_id))
self.0.get(&chain_id)
}
}

#[cfg(test)]
mod tests {
use super::*;
use alloy_primitives::{address, map::HashMap, U64};
use alloy_primitives::{address, map::HashMap};

#[test]
fn ser() {
let caps = WalletCapabilities(HashMap::from_iter([(
U64::from(0x69420),
0x69420,
Capabilities {
delegation: DelegationCapability {
addresses: vec![address!("90f79bf6eb2c4f870365e785982e1f101e93b906")],
Expand All @@ -66,7 +67,7 @@ mod tests {
assert_eq!(
caps,
WalletCapabilities(HashMap::from_iter([(
U64::from(0x69420),
0x69420,
Capabilities {
delegation: DelegationCapability {
addresses: vec![address!("90f79bf6eb2c4f870365e785982e1f101e93b906")],
Expand All @@ -75,4 +76,44 @@ mod tests {
)]))
);
}

#[test]
fn test_get_capabilities() {
let caps = WalletCapabilities(HashMap::from_iter([(
0x69420,
Capabilities {
delegation: DelegationCapability {
addresses: vec![address!("90f79bf6eb2c4f870365e785982e1f101e93b906")],
},
},
)]));

// Retrieve an existing chain ID.
let capabilities = caps.get(0x69420);
assert!(capabilities.is_some());
assert_eq!(
capabilities.unwrap().delegation.addresses[0],
address!("90f79bf6eb2c4f870365e785982e1f101e93b906")
);

// Try to retrieve a non-existing chain ID.
let non_existing_capabilities = caps.get(0x12345);
assert!(non_existing_capabilities.is_none());
}

#[test]
fn test_capabilities_with_empty_delegation() {
let caps = WalletCapabilities(HashMap::from_iter([(
0x12345,
Capabilities { delegation: DelegationCapability { addresses: vec![] } },
)]));

// Verify that delegation exists but contains no addresses.
let capabilities = caps.get(0x12345).unwrap();
assert!(capabilities.delegation.addresses.is_empty());

// Serialize and ensure JSON output is correct.
let serialized = serde_json::to_string(&caps).unwrap();
assert_eq!(serialized, "{\"0x12345\":{\"delegation\":{\"addresses\":[]}}}");
}
}

0 comments on commit c2ac91b

Please sign in to comment.