neo_devpack/nep_macros.rs
1// Copyright (c) 2025-2026 R3E Network
2// Licensed under the MIT License
3
4//! NEP standard-library macros (L5).
5//!
6//! These declarative macros were intended to emit the canonical NEP method
7//! surface + Transfer event for a standard in one invocation.
8//!
9//! ## Status: unavailable on the current wasm32 export ABI
10//!
11//! A compliant NEP-17 / NEP-11 contract needs string method returns
12//! (`symbol`, `name`) and Hash160 (`ByteString`) account/token-id
13//! parameters. The `#[neo_method]` auto-export wrappers currently marshal
14//! **scalar integer/boolean types only** across the wasm32 → NeoVM
15//! boundary, so these macros cannot generate a working, standards-compliant
16//! contract yet.
17//!
18//! Before v0.13.2 the macros emitted those signatures but the export
19//! collector silently dropped every method (it matched the `#[neo_method]`
20//! attribute by bare ident and missed the macro-emitted qualified
21//! `#[$crate::neo_method]` form), so contracts built with them deployed
22//! with **no callable methods**. As of v0.13.2 the attribute matching is
23//! fixed and the macros fail to compile with actionable guidance instead of
24//! producing a silently-broken contract.
25//!
26//! ## What to do instead
27//!
28//! Write the contract by hand with `#[neo_contract]` + `#[neo_method]`
29//! using integer account ids — the same pattern every working example in
30//! this repo uses. See `contracts/nep17-token` and `contracts/nep11-nft`
31//! for complete, exported, callable token contracts.
32
33/// NEP-17 (fungible token) standard macro.
34///
35/// **Currently unavailable on the wasm32 export ABI.** A compliant NEP-17
36/// contract needs a `symbol()` method that returns a string and
37/// `balanceOf`/`transfer` methods that take Hash160 (`ByteString`)
38/// accounts. The `#[neo_method]` auto-export wrappers marshal scalar
39/// integer/boolean types only, so this macro cannot emit a working,
40/// standards-compliant contract yet. Any invocation therefore fails to
41/// compile with guidance rather than silently exporting no methods (the
42/// behaviour before v0.13.2).
43///
44/// Until the typed-parameter export ABI lands, write the contract by hand
45/// with `#[neo_contract]` + `#[neo_method]` using integer account ids —
46/// see `contracts/nep17-token` for a complete working example.
47#[macro_export]
48macro_rules! nep17 {
49 ($($tokens:tt)*) => {
50 ::core::compile_error!(
51 "`nep17!` cannot auto-generate a NEP-17 contract on the current wasm32 export \
52 ABI: `symbol()` must return a string and `balanceOf`/`transfer` take Hash160 \
53 (ByteString) accounts, but exported `#[neo_method]` wrappers marshal scalar \
54 integer/boolean types only. Write the contract by hand with `#[neo_contract]` \
55 + `#[neo_method]` using integer account ids until the typed-parameter export \
56 ABI is available — see `contracts/nep17-token` for a complete working example."
57 );
58 };
59}
60
61/// NEP-11 (non-fungible token) standard macro.
62///
63/// **Currently unavailable on the wasm32 export ABI**, for the same reason
64/// as [`nep17!`]: the NEP-11 surface (`symbol`/`name` string returns,
65/// Hash160/ByteString accounts and token ids) cannot be marshalled through
66/// the scalar-only `#[neo_method]` export wrappers. Any invocation fails to
67/// compile with guidance rather than silently exporting no methods.
68///
69/// Write the contract by hand with `#[neo_contract]` + `#[neo_method]`
70/// until the typed-parameter export ABI lands — see `contracts/nep11-nft`.
71#[macro_export]
72macro_rules! nep11 {
73 ($($tokens:tt)*) => {
74 ::core::compile_error!(
75 "`nep11!` cannot auto-generate a NEP-11 contract on the current wasm32 export \
76 ABI: the NEP-11 method surface needs string (`symbol`/`name`) returns and \
77 Hash160 (ByteString) accounts/token ids, but exported `#[neo_method]` wrappers \
78 marshal scalar integer/boolean types only. Write the contract by hand with \
79 `#[neo_contract]` + `#[neo_method]` until the typed-parameter export ABI is \
80 available — see `contracts/nep11-nft` for a complete working example."
81 );
82 };
83}
84
85#[cfg(test)]
86mod tests {
87 // The `nep17!`/`nep11!` macros currently expand to `compile_error!`
88 // (see the module docs), so they cannot be invoked in a passing test.
89 // The working token pattern they point to is exercised by the
90 // hand-written `contracts/nep17-token` and `contracts/nep11-nft`
91 // examples (built to wasm32 in CI). Here we only confirm the
92 // `macro_rules!` definitions are syntactically valid by loading the
93 // module.
94 #[test]
95 fn nep_macros_module_loads() {}
96}