Patterns

Events (NEP-297)

No native event type — you emit a structured JSON log line. Indexers parse the EVENT_JSON standard the way they parse EVM logs.

Solidity has first-class event / emit with indexed topics. NEAR has no event type — you write a structured log line. NEP-297 standardizes its shape so wallets and indexers can parse it reliably.

Emit an event
Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract Bell {
    event Rang(address indexed who, uint32 times);

    uint32 public count;

    function ring() external {
        count += 1;
        emit Rang(msg.sender, count);
    }
}
Rust
use near_sdk::{near, env};
use near_sdk::serde_json::json;

#[near(contract_state)]
#[derive(Default)]
pub struct Bell {
    count: u32,
}

#[near]
impl Bell {
    pub fn ring(&mut self) {
        self.count += 1;
        env::log_str(&format!(
            "EVENT_JSON:{}",
            json!({
                "standard": "bell",
                "version": "1.0.0",
                "event": "rang",
                "data": {
                    "who": env::predecessor_account_id(),
                    "times": self.count
                }
            })
        ));
    }
}
Coming from EVM

Solidity event + emit ↔ a log line via env::log_str. NEP-297 fixes the format: the string is prefixed EVENT_JSON: and carries standard, version, event, and a data payload.

There are no indexed topics — the whole event is JSON. You filter off-chain by the standard / event fields rather than by an indexed topic.

The token standards (NEP-141 / NEP-171) define exact event names like ft_transfer and nft_mint. When you implement a standard, match its event shapes — that is what indexers and wallets are watching for.