use crate::permission::RoleTarget; use near_sdk::json_types::U128; use near_sdk::serde::Serialize; use near_sdk::{env, AccountId}; #[derive(Serialize, Debug)] #[serde(crate = "near_sdk::serde")] #[serde(tag = "standard")] #[must_use = "don't forget to `.emit()` this event"] #[serde(rename_all = "snake_case")] pub(crate) enum NearEvent<'a> { Nep000(Nep000Event<'a>), } impl<'a> NearEvent<'a> { fn to_json_string(&self) -> String { // Events cannot fail to serialize so fine to panic on error #[allow(clippy::redundant_closure)] serde_json::to_string(self) .ok() .unwrap_or_else(|| env::abort()) } fn to_json_event_string(&self) -> String { format!("EVENT_JSON:{}", self.to_json_string()) } /// Logs the event to the host. This is required to ensure that the event is triggered /// and to consume the event. pub(crate) fn emit(self) { near_sdk::env::log_str(&self.to_json_event_string()); } } #[derive(Serialize, Debug)] #[serde(crate = "near_sdk::serde")] pub(crate) struct Nep000Event<'a> { version: &'static str, #[serde(flatten)] event_kind: Nep000EventKind<'a>, } #[derive(Serialize, Debug)] #[serde(crate = "near_sdk::serde")] #[serde(tag = "event", content = "data")] #[serde(rename_all = "snake_case")] #[allow(clippy::enum_variant_names)] enum Nep000EventKind<'a> { // Role & Permission Events RoleGranted(&'a [RoleGranted<'a>]), RoleRevoked(&'a [RoleRevoked<'a>]), // Governance Events ProposalCreated(&'a [ProposalCreated<'a>]), ProposalExecuted(&'a [ProposalExecuted<'a>]), ProposalCancelled(&'a [ProposalCancelled<'a>]), PolicyUpdated(&'a [PolicyUpdated<'a>]), // Security Events GlobalLockAcquired(&'a [GlobalLockAcquired<'a>]), GlobalLockReleased(&'a [GlobalLockReleased<'a>]), } // ==================== Role & Permission Events ==================== /// Event for when a role is granted to a target (AccountId or Codehash) #[must_use] #[derive(Serialize, Debug, Clone)] #[serde(crate = "near_sdk::serde")] pub struct RoleGranted<'a> { pub target: &'a RoleTarget, pub role: &'a str, } impl RoleGranted<'_> { pub fn emit(self) { Self::emit_many(&[self]) } pub fn emit_many(data: &[RoleGranted<'_>]) { new_000_v1(Nep000EventKind::RoleGranted(data)).emit() } } /// Event for when a role is revoked from a target (AccountId or Codehash) #[must_use] #[derive(Serialize, Debug, Clone)] #[serde(crate = "near_sdk::serde")] pub struct RoleRevoked<'a> { pub target: &'a RoleTarget, pub role: &'a str, } impl RoleRevoked<'_> { pub fn emit(self) { Self::emit_many(&[self]) } pub fn emit_many(data: &[RoleRevoked<'_>]) { new_000_v1(Nep000EventKind::RoleRevoked(data)).emit() } } // ==================== Governance Events ==================== /// Event for when a proposal is created #[must_use] #[derive(Serialize, Debug, Clone)] #[serde(crate = "near_sdk::serde")] pub struct ProposalCreated<'a> { pub proposal_id: u64, pub policy_id: &'a str, pub proposer: &'a AccountId, } impl ProposalCreated<'_> { pub fn emit(self) { Self::emit_many(&[self]) } pub fn emit_many(data: &[ProposalCreated<'_>]) { new_000_v1(Nep000EventKind::ProposalCreated(data)).emit() } } /// Event for when a proposal is executed #[must_use] #[derive(Serialize, Debug, Clone)] #[serde(crate = "near_sdk::serde")] pub struct ProposalExecuted<'a> { pub proposal_id: u64, pub policy_id: &'a str, } impl ProposalExecuted<'_> { pub fn emit(self) { Self::emit_many(&[self]) } pub fn emit_many(data: &[ProposalExecuted<'_>]) { new_000_v1(Nep000EventKind::ProposalExecuted(data)).emit() } } /// Event for when a proposal is cancelled #[must_use] #[derive(Serialize, Debug, Clone)] #[serde(crate = "near_sdk::serde")] pub struct ProposalCancelled<'a> { pub proposal_id: u64, pub policy_id: &'a str, } impl ProposalCancelled<'_> { pub fn emit(self) { Self::emit_many(&[self]) } pub fn emit_many(data: &[ProposalCancelled<'_>]) { new_000_v1(Nep000EventKind::ProposalCancelled(data)).emit() } } /// Event for when a policy is updated #[must_use] #[derive(Serialize, Debug, Clone)] #[serde(crate = "near_sdk::serde")] pub struct PolicyUpdated<'a> { pub policy_id: &'a str, pub updater: &'a AccountId, pub activation_time: U128, } impl PolicyUpdated<'_> { pub fn emit(self) { Self::emit_many(&[self]) } pub fn emit_many(data: &[PolicyUpdated<'_>]) { new_000_v1(Nep000EventKind::PolicyUpdated(data)).emit() } } // ==================== Security Events ==================== /// Event for when global lock is acquired #[must_use] #[derive(Serialize, Debug, Clone)] #[serde(crate = "near_sdk::serde")] pub struct GlobalLockAcquired<'a> { pub holder: &'a AccountId, } impl GlobalLockAcquired<'_> { pub fn emit(self) { Self::emit_many(&[self]) } pub fn emit_many(data: &[GlobalLockAcquired<'_>]) { new_000_v1(Nep000EventKind::GlobalLockAcquired(data)).emit() } } /// Event for when global lock is released #[must_use] #[derive(Serialize, Debug, Clone)] #[serde(crate = "near_sdk::serde")] pub struct GlobalLockReleased<'a> { pub holder: &'a AccountId, } impl GlobalLockReleased<'_> { pub fn emit(self) { Self::emit_many(&[self]) } pub fn emit_many(data: &[GlobalLockReleased<'_>]) { new_000_v1(Nep000EventKind::GlobalLockReleased(data)).emit() } } fn new_000<'a>(version: &'static str, event_kind: Nep000EventKind<'a>) -> NearEvent<'a> { NearEvent::Nep000(Nep000Event { version, event_kind, }) } fn new_000_v1(event_kind: Nep000EventKind) -> NearEvent { new_000("1.0.0", event_kind) }