Skip to content

Commit

Permalink
Add events on API method calls
Browse files Browse the repository at this point in the history
  • Loading branch information
vasyafromrussia authored and VladasZ committed Nov 21, 2023
1 parent 5a19f72 commit 8ada4bd
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

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

10 changes: 9 additions & 1 deletion contract/src/burn/api.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use model::{api::BurnApi, TokensAmount, UnixTimestamp};
use model::{
api::BurnApi,
event::{emit, BurnData, EventKind},
TokensAmount, UnixTimestamp,
};
use near_sdk::{json_types::U128, near_bindgen, require, PromiseOrValue};

use crate::{common::now_seconds, Contract, ContractExt};
Expand Down Expand Up @@ -50,6 +54,10 @@ impl Contract {
self.accruals.remove(&datetime);
}

emit(EventKind::Burn(BurnData {
burnt_amount: U128(total_to_burn),
}));

U128(total_to_burn)
}
}
Expand Down
16 changes: 15 additions & 1 deletion contract/src/claim/api.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use model::{api::ClaimApi, ClaimAvailabilityView, TokensAmount, UnixTimestamp};
use model::{
api::ClaimApi,
event::{emit, ClaimData, EventKind},
ClaimAvailabilityView, TokensAmount, UnixTimestamp,
};
use near_sdk::{env, json_types::U128, near_bindgen, require, store::Vector, AccountId, PromiseOrValue};

use crate::{common::now_seconds, Contract, ContractExt, StorageKey::AccrualsEntry};
Expand Down Expand Up @@ -103,6 +107,16 @@ impl Contract {

if is_success {
account.last_claim_at = now.into();

let event_data = ClaimData {
details: details
.iter()
.map(|(timestamp, amount)| (*timestamp, U128(*amount)))
.collect(),
total_claimed: U128(total_accrual),
};
emit(EventKind::Claim(event_data));

return U128(total_accrual);
}

Expand Down
5 changes: 4 additions & 1 deletion contract/src/clean/api.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use model::event::{emit, CleanData, EventKind};
use near_sdk::{near_bindgen, AccountId};

use crate::{Contract, ContractExt};
Expand All @@ -11,8 +12,10 @@ impl CleanApi for Contract {
fn clean(&mut self, account_ids: Vec<AccountId>) {
self.assert_oracle();

for account_id in account_ids {
for account_id in account_ids.clone() {
self.accounts.set(account_id, None);
}

emit(EventKind::Clean(CleanData { account_ids }));
}
}
17 changes: 14 additions & 3 deletions contract/src/record/api.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use model::{account_record::AccountRecord, api::RecordApi};
use model::{
account_record::AccountRecord,
api::RecordApi,
event::{emit, EventKind, RecordData},
};
use near_sdk::{json_types::U128, near_bindgen, require, store::Vector, AccountId};

use crate::{common::now_seconds, Contract, ContractExt, StorageKey::AccrualsEntry};
Expand All @@ -8,13 +12,18 @@ impl RecordApi for Contract {
fn record_batch_for_hold(&mut self, amounts: Vec<(AccountId, U128)>) {
self.assert_oracle();

self.assert_oracle();

let now_seconds = now_seconds();
let mut balances = Vector::new(AccrualsEntry(now_seconds));
let mut total_balance = 0;

let mut event_data = RecordData {
timestamp: now_seconds,
amounts: vec![],
};

for (account_id, amount) in amounts {
event_data.amounts.push((account_id.clone(), amount));

let amount = amount.0;
let index = balances.len();

Expand All @@ -36,6 +45,8 @@ impl RecordApi for Contract {

let existing = self.accruals.insert(now_seconds, (balances, total_balance));

emit(EventKind::Record(event_data));

require!(
existing.is_none(),
format!("Record for this timestamp: {now_seconds} already existed. It was owerwritten.")
Expand Down
2 changes: 1 addition & 1 deletion model/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "model"
version = "0.1.0"
version = "1.0.0"
edition = "2021"

[lib]
Expand Down
129 changes: 129 additions & 0 deletions model/src/event.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
use near_sdk::{
env,
json_types::U128,
log,
serde::{Deserialize, Serialize},
serde_json, AccountId,
};

use crate::UnixTimestamp;

pub const PACKAGE_NAME: &str = "sweat_claim";
pub const VERSION: &str = env!("CARGO_PKG_VERSION");

#[derive(Serialize, Deserialize, Debug)]
#[serde(
crate = "near_sdk::serde",
tag = "event",
content = "data",
rename_all = "snake_case"
)]
pub enum EventKind {
Burn(BurnData),
Claim(ClaimData),
Clean(CleanData),
Record(RecordData),
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(crate = "near_sdk::serde")]
pub struct BurnData {
pub burnt_amount: U128,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(crate = "near_sdk::serde")]
pub struct ClaimData {
pub details: Vec<(UnixTimestamp, U128)>,
pub total_claimed: U128,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(crate = "near_sdk::serde")]
pub struct CleanData {
pub account_ids: Vec<AccountId>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(crate = "near_sdk::serde")]
pub struct RecordData {
pub timestamp: UnixTimestamp,
pub amounts: Vec<(AccountId, U128)>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(crate = "near_sdk::serde", rename_all = "snake_case")]
struct SweatClaimEvent {
standard: &'static str,
version: &'static str,
#[serde(flatten)]
event_kind: EventKind,
}

impl From<EventKind> for SweatClaimEvent {
fn from(event_kind: EventKind) -> Self {
Self {
standard: PACKAGE_NAME,
version: VERSION,
event_kind,
}
}
}

pub fn emit(event: EventKind) {
log!(SweatClaimEvent::from(event).to_json_event_string());
}

impl SweatClaimEvent {
fn to_json_string(&self) -> String {
serde_json::to_string_pretty(self)
.unwrap_or_else(|err| env::panic_str(&format!("Failed to serialize SweatClaimEvent: {err}")))
}

fn to_json_event_string(&self) -> String {
format!("EVENT_JSON:{}", self.to_json_string())
}
}

#[cfg(test)]
mod test {
use near_sdk::json_types::U128;

use crate::event::{BurnData, EventKind, SweatClaimEvent};

#[test]
fn event_to_string() {
assert_eq!(
strip(
SweatClaimEvent::from(EventKind::Burn(BurnData {
burnt_amount: U128(100_000_000),
}))
.to_json_event_string()
.as_str()
),
strip(
r#"EVENT_JSON:{
"standard": "sweat_claim",
"version": "1.0.0",
"event": "burn",
"data": {
"burnt_amount": "100000000"
}}"#
)
)
}

fn strip(s: &str) -> String {
let without_newlines: String = s.chars().filter(|&c| c != '\n').collect();
let mut previous_char = ' ';
let result: String = without_newlines
.chars()
.filter(|&c| {
let keep = !(c == ' ' && previous_char == ' ');
previous_char = c;
keep
})
.collect();
result
}
}
1 change: 1 addition & 0 deletions model/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod account_record;
pub mod api;
pub mod event;

use near_sdk::serde::{Deserialize, Serialize};

Expand Down

0 comments on commit 8ada4bd

Please sign in to comment.