use crate::{helpers::chainsig::ChainEnvironment, *}; use near_sdk::AccountId; use std::collections::HashMap; // ==================== Role Types ==================== #[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)] #[near(serializers = [json, borsh])] pub struct Codehash(pub String); impl Codehash { pub fn new(hash: String) -> Self { Self(hash) } pub fn as_str(&self) -> &str { &self.0 } } impl std::fmt::Display for Codehash { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.0) } } impl From for Codehash { fn from(hash: String) -> Self { Self(hash) } } impl From<&str> for Codehash { fn from(hash: &str) -> Self { Self(hash.to_string()) } } #[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)] #[near(serializers = [json, borsh])] pub enum RoleTarget { AccountId(AccountId), Codehash(Codehash), } impl RoleTarget { pub fn account_id(account_id: AccountId) -> Self { Self::AccountId(account_id) } pub fn codehash(codehash: Codehash) -> Self { Self::Codehash(codehash) } pub fn from_codehash_str(codehash: &str) -> Self { Self::Codehash(Codehash::from(codehash)) } } impl std::fmt::Display for RoleTarget { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { RoleTarget::AccountId(account_id) => write!(f, "account:{}", account_id), RoleTarget::Codehash(codehash) => write!(f, "codehash:{}", codehash), } } } #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] #[near(serializers=[borsh, serde])] pub struct Role(pub String); // ==================== Policy Types ==================== #[derive(PartialEq, Debug, Clone)] #[near(serializers=[json, borsh])] pub enum PolicyType { KernelConfiguration, // Owner, Accountant, Teller ChainSigTransaction, // Only strategist can NearNativeTransaction, ChainSigMessage, } #[near(serializers=[json, borsh])] #[derive(Clone)] pub enum PolicyDetails { ChainSigTransaction(ChainSigTransactionConfig), NearNativeTransaction(NearNativeTransactionConfig), ChainSigMessage(ChainSigMessageConfig), KernelConfiguration, } impl PolicyDetails { pub fn as_chain_sig_transaction(&self) -> Option { if let PolicyDetails::ChainSigTransaction(ref e) = self { Some(e.clone()) } else { None } } pub fn as_near_native_transaction(&self) -> Option { if let PolicyDetails::NearNativeTransaction(ref e) = self { Some(e.clone()) } else { None } } pub fn as_chain_sig_message(&self) -> Option { if let PolicyDetails::ChainSigMessage(ref e) = self { Some(e.clone()) } else { None } } } #[near(serializers=[json, borsh])] pub struct SwapIntent { pub intent: String, pub diff: HashMap, pub referral: Option, } #[near(serializers=[json, borsh])] pub struct SwapIntentMessage { pub deadline: String, pub intents: Vec, pub signer_id: String, } #[near(serializers=[json, borsh])] #[derive(Clone)] pub struct Policy { pub id: String, pub description: Option, pub required_role: String, pub required_vote_count: u32, pub policy_type: PolicyType, pub policy_details: PolicyDetails, /// Nano timestamp when this policy becomes active (for activation delays) pub activation_time: U128, /// Proposal expiry duration in nanoseconds (how long proposals for this policy remain active) pub proposal_expiry_time_nanosec: U128, /// Follow-up actions that must be completed after this policy executes pub required_pending_actions: Vec, } #[near(serializers=[json, borsh])] pub struct NEP413 { pub message: String, pub recipient: String, pub nonce: Vec, pub callback_url: Option, } // ==================== Proposal Types ==================== #[near(serializers=[json, borsh])] #[derive(Clone)] pub struct Proposal { pub id: u64, pub policy_id: String, pub function_args: String, // JSON string pub proposer: AccountId, pub creation_time: U128, pub deadline: U128, pub execution_threshold: u32, // Required votes to execute } #[near(serializers=[json, borsh])] #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct Vote { pub proposal_id: u64, pub voter: AccountId, pub timestamp: U128, } impl Default for Proposal { fn default() -> Self { Self { id: 0, policy_id: String::new(), function_args: String::new(), proposer: "default.near".parse().unwrap(), creation_time: U128(0), deadline: U128(0), execution_threshold: 1, } } } // ==================== Strategy Configuration Types ==================== #[near(serializers = [json, borsh])] #[derive(Clone)] pub enum TypeKind { // available comparator: eq, ne String, // available comparator: eq, ne, gte, lte, gt, lt BigInt, // available comparator: eq // bool comparator value should be "true" | "false" Boolean, } #[near(serializers = [json, borsh])] #[derive(Clone)] pub struct Schema { pub path: String, pub r#type: TypeKind, pub eq: Option, pub ne: Option, pub gte: Option, pub lte: Option, pub gt: Option, pub lt: Option, pub nullable: Option, } #[near(serializers = [json, borsh])] #[derive(Clone)] pub struct Restriction { // method and contract is now part of the schema // pub method: String, // pub contract_id: String, pub schema: String, // ABI (evm), IDL (svm), encoded in base 64 pub interface: String, // for svm, the instructions have a wide range of possibility // eg: Transferring USDC from account A to account B // possible instructions set: // 1. [create_account, transfer] // 2. [transfer] // both are valid, strategist can utilize this prop to // skip first instruction if required pub go_to_index_if_not_found: Option, } #[near(serializers=[json, borsh])] #[derive(Clone)] pub enum ChainSigSignMethod { NearIntentsSwap, } #[near(serializers = [json, borsh])] #[derive(Clone)] pub struct NearNativeTransactionConfig { pub chain_environment: ChainEnvironment, pub restrictions: Vec, } #[near(serializers = [json, borsh])] #[derive(Clone)] pub struct ChainSigTransactionConfig { pub derivation_path: String, pub chain_environment: ChainEnvironment, pub restrictions: Vec, } #[near(serializers=[json, borsh])] #[derive(Clone)] pub struct ChainSigMessageConfig { pub derivation_path: String, pub sign_method: ChainSigSignMethod, } #[near(serializers=[borsh])] pub struct EmergencyConfig { // Invactive duration for emergency activation pub emergency_inactive_duration_ns: U128, // Emergency accounts, pub emergency_accounts: IterableSet, // Emergency vote threshold pub emergency_vote_threshold: u32, // Emergency vote valid duration pub emergency_vote_duration_ns: U128, }