Skip to main content

tempo_precompiles/account_keychain/
dispatch.rs

1//! ABI dispatch for the [`AccountKeychain`] precompile.
2
3use super::AccountKeychain;
4use crate::{Precompile, dispatch_call, input_cost, mutate_void, view};
5use alloy::{primitives::Address, sol_types::SolInterface};
6use revm::precompile::{PrecompileError, PrecompileResult};
7use tempo_contracts::precompiles::IAccountKeychain::IAccountKeychainCalls;
8
9impl Precompile for AccountKeychain {
10    fn call(&mut self, calldata: &[u8], msg_sender: Address) -> PrecompileResult {
11        self.storage
12            .deduct_gas(input_cost(calldata.len()))
13            .map_err(|_| PrecompileError::OutOfGas)?;
14
15        dispatch_call(
16            calldata,
17            IAccountKeychainCalls::abi_decode,
18            |call| match call {
19                IAccountKeychainCalls::authorizeKey(call) => {
20                    mutate_void(call, msg_sender, |sender, c| self.authorize_key(sender, c))
21                }
22                IAccountKeychainCalls::revokeKey(call) => {
23                    mutate_void(call, msg_sender, |sender, c| self.revoke_key(sender, c))
24                }
25                IAccountKeychainCalls::updateSpendingLimit(call) => {
26                    mutate_void(call, msg_sender, |sender, c| {
27                        self.update_spending_limit(sender, c)
28                    })
29                }
30                IAccountKeychainCalls::getKey(call) => view(call, |c| self.get_key(c)),
31                IAccountKeychainCalls::getRemainingLimit(call) => {
32                    view(call, |c| self.get_remaining_limit(c))
33                }
34                IAccountKeychainCalls::getTransactionKey(call) => {
35                    view(call, |c| self.get_transaction_key(c, msg_sender))
36                }
37            },
38        )
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45    use crate::{
46        storage::{StorageCtx, hashmap::HashMapStorageProvider},
47        test_util::{assert_full_coverage, check_selector_coverage},
48    };
49
50    #[test]
51    fn test_account_keychain_selector_coverage() -> eyre::Result<()> {
52        let mut storage = HashMapStorageProvider::new(1);
53        StorageCtx::enter(&mut storage, || {
54            let mut fee_manager = AccountKeychain::new();
55
56            let unsupported = check_selector_coverage(
57                &mut fee_manager,
58                IAccountKeychainCalls::SELECTORS,
59                "IAccountKeychain",
60                IAccountKeychainCalls::name_by_selector,
61            );
62
63            assert_full_coverage([unsupported]);
64
65            Ok(())
66        })
67    }
68}