Skip to content
Merged
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
5 changes: 5 additions & 0 deletions contracts/grant_multisig/grant.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
if grantee.is_contract() {
require_cross_contract_auth(grantee, caller)?;
} else {
grantee.require_auth(); // normal account
}
2 changes: 2 additions & 0 deletions contracts/grant_multisig/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod grant;
pub mod multisig;
39 changes: 39 additions & 0 deletions contracts/grant_multisig/multisig.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// contracts/grant_multisig/multisig.rs

use std::collections::HashSet;

/// Mock multi-sig / Smart Contract Wallet
/// Simulates a contract wallet that approves calls if the caller is authorized
#[derive(Debug)]
pub struct MockMultisig {
authorized: HashSet<String>, // set of addresses authorized to execute
}

impl MockMultisig {
/// Create a new MockMultisig with a list of authorized addresses
pub fn new(auth_list: Vec<&str>) -> Self {
let authorized: HashSet<String> = auth_list.into_iter().map(|a| a.to_string()).collect();
Self { authorized }
}

/// Simulate execution by an external caller
/// Returns true if caller is authorized, false otherwise
pub fn execute(&self, caller: &str) -> bool {
self.authorized.contains(caller)
}

/// Optional helper to add an authorized signer
pub fn add_authorized(&mut self, caller: &str) {
self.authorized.insert(caller.to_string());
}

/// Optional helper to remove an authorized signer
pub fn remove_authorized(&mut self, caller: &str) {
self.authorized.remove(caller);
}

/// Check if this is a contract (always true for multi-sig)
pub fn is_contract(&self) -> bool {
true
}
}
Loading