tempo_precompiles/account_keychain/
dispatch.rs

1use super::{AccountKeychain, IAccountKeychain};
2use crate::{
3    Precompile, fill_precompile_output, input_cost, mutate_void,
4    storage::PrecompileStorageProvider, unknown_selector, view,
5};
6use alloy::{primitives::Address, sol_types::SolCall};
7use revm::precompile::{PrecompileError, PrecompileResult};
8
9impl<S: PrecompileStorageProvider> Precompile for AccountKeychain<'_, S> {
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        let selector: [u8; 4] = calldata
16            .get(..4)
17            .ok_or_else(|| {
18                PrecompileError::Other("Invalid input: missing function selector".into())
19            })?
20            .try_into()
21            .unwrap();
22
23        let result = match selector {
24            IAccountKeychain::authorizeKeyCall::SELECTOR => {
25                mutate_void::<IAccountKeychain::authorizeKeyCall>(
26                    calldata,
27                    msg_sender,
28                    |sender, call| self.authorize_key(sender, call),
29                )
30            }
31
32            IAccountKeychain::revokeKeyCall::SELECTOR => {
33                mutate_void::<IAccountKeychain::revokeKeyCall>(
34                    calldata,
35                    msg_sender,
36                    |sender, call| self.revoke_key(sender, call),
37                )
38            }
39
40            IAccountKeychain::updateSpendingLimitCall::SELECTOR => {
41                mutate_void::<IAccountKeychain::updateSpendingLimitCall>(
42                    calldata,
43                    msg_sender,
44                    |sender, call| self.update_spending_limit(sender, call),
45                )
46            }
47
48            IAccountKeychain::getKeyCall::SELECTOR => {
49                view::<IAccountKeychain::getKeyCall>(calldata, |call| self.get_key(call))
50            }
51
52            IAccountKeychain::getRemainingLimitCall::SELECTOR => {
53                view::<IAccountKeychain::getRemainingLimitCall>(calldata, |call| {
54                    self.get_remaining_limit(call)
55                })
56            }
57
58            IAccountKeychain::getTransactionKeyCall::SELECTOR => {
59                view::<IAccountKeychain::getTransactionKeyCall>(calldata, |call| {
60                    self.get_transaction_key(call, msg_sender)
61                })
62            }
63
64            _ => unknown_selector(selector, self.storage.gas_used(), self.storage.spec()),
65        };
66
67        result.map(|res| fill_precompile_output(res, self.storage))
68    }
69}