Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 16 additions & 9 deletions crates/alloy/src/provider/keychain.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
use core::fmt;

use alloy_primitives::{Address, B256, Bytes, TxKind, U256};
use alloy_rlp::Encodable;
use alloy_sol_types::SolCall;
use tempo_contracts::precompiles::{
ACCOUNT_KEYCHAIN_ADDRESS,
IAccountKeychain::{
KeyRestrictions as AbiKeyRestrictions, LegacyTokenLimit as AbiLegacyTokenLimit,
TokenLimit as AbiTokenLimit, removeAllowedCallsCall, revokeKeyCall, setAllowedCallsCall,
TokenLimit as AbiTokenLimit, removeAllowedCallsCall, revokeKeyCall,
updateSpendingLimitCall,
},
ITIP20, authorizeAdminKeyCall, authorizeKeyCall, legacyAuthorizeKeyCall,
ITIP20, authorizeAdminKeyCall, authorizeKeyCall, legacyAuthorizeKeyCall, setAllowedCallsCall,
};
use tempo_primitives::{
SignatureType,
Expand Down Expand Up @@ -309,7 +310,7 @@ pub fn authorize_key_legacy(
}))
}

/// Build an `authorizeKey(address,uint8,KeyRestrictions)` precompile call.
/// Build a pre-T11 `authorizeKey(address,uint8,KeyRestrictions)` precompile call.
pub fn authorize_key(
key_id: Address,
signature_type: SignatureType,
Expand All @@ -322,7 +323,7 @@ pub fn authorize_key(
})
}

/// Build an `authorizeAdminKey(address,uint8,bytes32)` precompile call.
/// Build a pre-T11 `authorizeAdminKey(address,uint8,bytes32)` precompile call.
///
/// Admin keys (TIP-1049) can perform account-management calls such as authorizing or
/// revoking other keys and setting a receive policy. Pass [`B256::ZERO`] for `witness`
Expand All @@ -349,7 +350,7 @@ pub fn update_spending_limit(key_id: Address, token: Address, new_limit: U256) -
})
}

/// Build a `setAllowedCalls(address,CallScope[])` precompile call.
/// Build a `setAllowedCalls(address,bytes)` precompile call with RLP-encoded scopes.
///
/// # Examples
///
Expand All @@ -368,9 +369,11 @@ pub fn update_spending_limit(key_id: Address, token: Address, new_limit: U256) -
/// let call = set_allowed_calls(key_id, vec![scope]);
/// ```
pub fn set_allowed_calls(key_id: Address, scopes: Vec<CallScope>) -> Call {
let mut encoded = Vec::new();
scopes.encode(&mut encoded);
account_keychain_call(setAllowedCallsCall {
keyId: key_id,
scopes: scopes.into_iter().map(Into::into).collect(),
scopes: encoded.into(),
})
}

Expand Down Expand Up @@ -407,10 +410,11 @@ fn account_keychain_call(call: impl SolCall) -> Call {
mod tests {
use super::*;
use alloy_primitives::{address, uint};
use alloy_rlp::Decodable;
use tempo_contracts::precompiles::IAccountKeychain::{
CallScope as AbiCallScope, SelectorRule as AbiSelectorRule,
SignatureType as AbiSignatureType, removeAllowedCallsCall, revokeKeyCall,
setAllowedCallsCall, updateSpendingLimitCall,
updateSpendingLimitCall,
};

#[test]
Expand Down Expand Up @@ -604,8 +608,11 @@ mod tests {

let decoded = setAllowedCallsCall::abi_decode(&call.input).expect("decode setAllowedCalls");
assert_eq!(decoded.keyId, key_id);
assert_eq!(decoded.scopes.len(), 1);
assert_eq!(decoded.scopes[0].selectorRules.len(), 1);
let mut encoded = decoded.scopes.as_ref();
let decoded_scopes = Vec::<CallScope>::decode(&mut encoded).expect("decode RLP scopes");
assert!(encoded.is_empty());
assert_eq!(decoded_scopes.len(), 1);
assert_eq!(decoded_scopes[0].selector_rules.len(), 1);
}

#[test]
Expand Down
6 changes: 6 additions & 0 deletions crates/contracts/src/precompiles/account_keychain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ pub use IAccountKeychain::{
authorizeKey_1Call as authorizeKeyCall, authorizeKey_2Call as authorizeKeyWithWitnessCall,
getAllowedCallsReturn, getRemainingLimitWithPeriodCall,
getRemainingLimitWithPeriodReturn as getRemainingLimitReturn,
setAllowedCalls_0Call as legacySetAllowedCallsCall,
setAllowedCalls_1Call as setAllowedCallsCall,
};

crate::sol! {
Expand Down Expand Up @@ -166,6 +168,10 @@ crate::sol! {
CallScope[] calldata scopes
) external;

/// Set or replace RLP-encoded allowed calls for one or more key+target pairs.
/// @dev `scopes` is the canonical RLP encoding of a non-empty CallScope list.
function setAllowedCalls(address keyId, bytes calldata scopes) external;

/// Remove any configured call scope for a key+target pair.
function removeAllowedCalls(address keyId, address target) external;

Expand Down
13 changes: 10 additions & 3 deletions crates/node/tests/it/storage_credits.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::utils::{TEST_MNEMONIC, TestNodeBuilder, setup_test_token};
use crate::utils::{ForkSchedule, TEST_MNEMONIC, TestNodeBuilder, setup_test_token};
use alloy::{
network::ReceiptResponse,
primitives::{Address, B256, Bytes, U256, aliases::U96},
Expand All @@ -12,6 +12,7 @@ use alloy::{
use alloy_eips::{BlockId, Encodable2718};
use alloy_rpc_types_eth::{TransactionReceipt, TransactionRequest};
use tempo_alloy::rpc::TempoTransactionReceipt;
use tempo_chainspec::hardfork::TempoHardfork;
use tempo_contracts::precompiles::{
DEFAULT_FEE_TOKEN, IFeeManager, IReceivePolicyGuard, IStorageCredits, ITIP20,
ITIP20ChannelReserve, ITIP403Registry, ITIPFeeAMM,
Expand Down Expand Up @@ -106,7 +107,10 @@ async fn send_tempo_tx<P: Provider>(
async fn test_tip1060_keychain_fee_refund_does_not_retain_storage_credit() -> eyre::Result<()> {
reth_tracing::init_test_tracing();

let setup = TestNodeBuilder::new().build_http_only().await?;
let setup = TestNodeBuilder::new()
.with_schedule(ForkSchedule::DevnetAt(TempoHardfork::T10))
.build_http_only()
.await?;
let root = MnemonicBuilder::from_phrase(TEST_MNEMONIC).build()?;
let root_addr = root.address();
let provider = ProviderBuilder::new()
Expand Down Expand Up @@ -1109,7 +1113,10 @@ async fn test_tip1060_successful_keychain_spend_fee_refund_cancels_restored_limi
-> eyre::Result<()> {
reth_tracing::init_test_tracing();

let setup = TestNodeBuilder::new().build_http_only().await?;
let setup = TestNodeBuilder::new()
.with_schedule(ForkSchedule::DevnetAt(TempoHardfork::T10))
.build_http_only()
.await?;
let root = MnemonicBuilder::from_phrase(TEST_MNEMONIC).build()?;
let root_addr = root.address();
let provider = ProviderBuilder::new()
Expand Down
10 changes: 8 additions & 2 deletions crates/node/tests/it/tempo_transaction/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1532,7 +1532,10 @@ async fn test_key_authorization_witness_burn_evicts_pending_replay() -> eyre::Re
async fn test_t6_authorize_admin_key_abi_e2e() -> eyre::Result<()> {
reth_tracing::init_test_tracing();

let mut setup = TestNodeBuilder::new().build_with_node_access().await?;
let mut setup = TestNodeBuilder::new()
.with_schedule(ForkSchedule::DevnetAt(TempoHardfork::T10))
.build_with_node_access()
.await?;
let root_signer = MnemonicBuilder::from_phrase(TEST_MNEMONIC).build()?;
let root_addr = root_signer.address();
let provider = ProviderBuilder::new_with_network::<TempoNetwork>()
Expand Down Expand Up @@ -1609,7 +1612,10 @@ async fn test_t6_inline_admin_key_authorization_e2e() -> eyre::Result<()> {
async fn test_t6_admin_key_authorizes_child_admin_key_e2e() -> eyre::Result<()> {
reth_tracing::init_test_tracing();

let mut setup = TestNodeBuilder::new().build_with_node_access().await?;
let mut setup = TestNodeBuilder::new()
.with_schedule(ForkSchedule::DevnetAt(TempoHardfork::T10))
.build_with_node_access()
.await?;
let root_signer = MnemonicBuilder::from_phrase(TEST_MNEMONIC).build()?;
let root_addr = root_signer.address();
let provider = ProviderBuilder::new_with_network::<TempoNetwork>()
Expand Down
1 change: 1 addition & 0 deletions crates/precompiles/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ workspace = true
tempo-contracts.workspace = true
tempo-chainspec = { workspace = true, features = ["evm"] }
tempo-primitives = { workspace = true, features = ["evm"] }
alloy-rlp.workspace = true
tempo-precompiles-macros.workspace = true
alloy = { workspace = true, features = ["sol-types", "consensus"] }
alloy-json-abi = { workspace = true, optional = true }
Expand Down
Loading
Loading