From 2c627a995b0483c9c1b84092d21715b07e4f18af Mon Sep 17 00:00:00 2001 From: akorchyn Date: Thu, 30 Jan 2025 18:08:47 +0200 Subject: [PATCH 1/7] doc: moved near-sdk-macros doc to near-sdk crate. Replaced ignore -> rust for examples to be able to test them in CI --- .../src/core_impl/abi/abi_generator.rs | 20 +- .../core_impl/code_generator/attr_sig_info.rs | 2 +- near-sdk-macros/src/lib.rs | 239 ------------- near-sdk/src/json_types/vector.rs | 25 +- near-sdk/src/lib.rs | 321 +++++++++++++++++- 5 files changed, 345 insertions(+), 262 deletions(-) diff --git a/near-sdk-macros/src/core_impl/abi/abi_generator.rs b/near-sdk-macros/src/core_impl/abi/abi_generator.rs index 4a2d2b5f1..9654f49d7 100644 --- a/near-sdk-macros/src/core_impl/abi/abi_generator.rs +++ b/near-sdk-macros/src/core_impl/abi/abi_generator.rs @@ -44,13 +44,25 @@ impl ImplItemMethodInfo { /// /// # Example: /// The following function: - /// ```ignore + /// ```rust + /// # use near_sdk::{near}; + /// # #[near(contract_state)] + /// # #[derive(Default)] + /// # pub struct Counter { + /// # val: u64, + /// # } + /// + /// # #[near] + /// # impl Counter { /// /// I am a function. /// #[handle_result] - /// pub fn f3(&mut self, arg0: FancyStruct, arg1: u64) -> Result { } + /// pub fn f3(&mut self, arg0: FancyStruct, arg1: u64) -> Result { + /// # unimplemented!() + /// } + /// #} /// ``` - /// will produce this struct: - /// ```ignore + /// will produce this struct:ignore + /// ```rust /// near_sdk::__private::AbiFunction { /// name: "f3".to_string(), /// doc: Some(" I am a function.".to_string()), diff --git a/near-sdk-macros/src/core_impl/code_generator/attr_sig_info.rs b/near-sdk-macros/src/core_impl/code_generator/attr_sig_info.rs index 24afbb26e..fa9ebd4a3 100644 --- a/near-sdk-macros/src/core_impl/code_generator/attr_sig_info.rs +++ b/near-sdk-macros/src/core_impl/code_generator/attr_sig_info.rs @@ -75,7 +75,7 @@ impl AttrSigInfo { /// and `SUBTYPE` is one of the following: `[T; n]`, path like /// `std::collections::HashMap`, or tuple `(SUBTYPE0, SUBTYPE1, ...)`. /// # Example - /// ```ignore + /// ```rust /// struct Input { /// arg0: Vec, /// arg1: [u64; 10], diff --git a/near-sdk-macros/src/lib.rs b/near-sdk-macros/src/lib.rs index 4bd34b247..6f1f909ac 100644 --- a/near-sdk-macros/src/lib.rs +++ b/near-sdk-macros/src/lib.rs @@ -43,140 +43,6 @@ struct NearMacroArgs { inside_nearsdk: Option, } -/// This attribute macro is used on a struct and its implementations -/// to generate the necessary code to expose `pub` methods from the contract as well -/// as generating the glue code to be a valid NEAR contract. -/// -/// ## Example -/// -/// ```ignore -/// #[near(serializers=[borsh, json])] -/// struct MyStruct { -/// pub name: String, -/// } -/// ``` -/// -/// This macro will generate code to load and deserialize state if the `self` parameter is included -/// as well as saving it back to state if `&mut self` is used. -/// -/// # Parameter and result serialization -/// If the macro is used with Impl section, for parameter serialization, this macro will generate a struct with all of the parameters as -/// fields and derive deserialization for it. By default this will be JSON deserialized with `serde` -/// but can be overwritten by using `#[serializer(borsh)]`: -/// ```ignore -/// #[near] -/// impl Adder { -/// #[result_serializer(borsh)] -/// pub fn borsh_parameters(&self, #[serializer(borsh)] a: Pair, #[serializer(borsh)] b: Pair) -> Pair { -/// /// ... -/// } -/// } -/// ``` -/// -/// `#[near]` will also handle serializing and setting the return value of the -/// function execution based on what type is returned by the function. By default, this will be -/// done through `serde` serialized as JSON, but this can be overwritten using -/// `#[result_serializer(borsh)]`: -/// ```ignore -/// #[near] -/// impl Adder { -/// #[result_serializer(borsh)] -/// pub fn borsh_parameters(&self) -> Pair { -/// /// ... -/// } -/// } -/// ``` -/// -/// # Usage for enum / struct -/// -/// If the macro is used with struct or enum, it will make the struct or enum serializable with either -/// Borsh or Json depending on serializers passed. Use `#[near(serializers=[borsh])]` to make it serializable with Borsh. -/// Or use `#[near(serializers=[json])]` to make it serializable with Json. By default, borsh is used. -/// You can also specify both and none. BorshSchema or JsonSchema are always generated. -/// -/// If you want the struct to be a contract state, you can pass in the contract_state argument. -/// -/// ## Example -/// ```ignore -/// use near_sdk::near; -/// -/// #[near(contract_state)] -/// pub struct Contract { -/// data: i8, -/// } -/// -/// #[near] -/// impl Contract { -/// pub fn some_function(&self) {} -/// } -/// ``` -/// As well, the macro supports arguments like `event_json` and `contract_metadata`. -/// -/// # Events Standard: -/// -/// By passing `event_json` as an argument `near_bindgen` will generate the relevant code to format events -/// according to NEP-297 -/// -/// For parameter serialization, this macro will generate a wrapper struct to include the NEP-297 standard fields `standard` and `version -/// as well as include serialization reformatting to include the `event` and `data` fields automatically. -/// The `standard` and `version` values must be included in the enum and variant declaration (see example below). -/// By default this will be JSON deserialized with `serde` -/// -/// -/// ## Examples -/// -/// ```ignore -/// use near_sdk::near; -/// -/// #[near(event_json(standard = "nepXXX"))] -/// pub enum MyEvents { -/// #[event_version("1.0.0")] -/// Swap { token_in: AccountId, token_out: AccountId, amount_in: u128, amount_out: u128 }, -/// -/// #[event_version("2.0.0")] -/// StringEvent(String), -/// -/// #[event_version("3.0.0")] -/// EmptyEvent -/// } -/// -/// #[near] -/// impl Contract { -/// pub fn some_function(&self) { -/// MyEvents::StringEvent( -/// String::from("some_string") -/// ).emit(); -/// } -/// -/// } -/// ``` -/// -/// # Contract Source Metadata Standard: -/// -/// By using `contract_metadata` as an argument `near` will populate the contract metadata -/// according to [`NEP-330`]() standard. This still applies even when `#[near]` is used without -/// any arguments. -/// -/// All fields(version, link, standard) are optional and will be populated with defaults from the Cargo.toml file if not specified. -/// -/// The `contract_source_metadata()` view function will be added and can be used to retrieve the source metadata. -/// Also, the source metadata will be stored as a constant, `CONTRACT_SOURCE_METADATA`, in the contract code. -/// -/// ## Examples -/// ```ignore -/// use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize}; -/// use near_sdk::near; -/// -/// #[derive(Default, BorshSerialize, BorshDeserialize)] -/// #[near(contract_metadata( -/// version = "39f2d2646f2f60e18ab53337501370dc02a5661c", -/// link = "https://github.com/near-examples/nft-tutorial", -/// standard(standard = "nep330", version = "1.1.0"), -/// standard(standard = "nep171", version = "1.0.0"), -/// standard(standard = "nep177", version = "2.0.0"), -/// ))] -/// struct Contract {} -/// ``` #[proc_macro_attribute] pub fn near(attr: TokenStream, item: TokenStream) -> TokenStream { if attr.to_string().contains("event_json") { @@ -318,23 +184,6 @@ pub fn near(attr: TokenStream, item: TokenStream) -> TokenStream { TokenStream::from(expanded) } -/// This macro is deprecated. Use [#\[near\]](./attr.near.html) instead. The difference between #\[near\] and #\[near_bindgen\] is that -/// with #\[near_bindgen\] you have to manually add boilerplate code for structs and enums so that they become Json- and Borsh-serializable: -/// ```ignore -/// #[near_bindgen] -/// #[derive(BorshSerialize, BorshDeserialize, NearSchema)] -/// #[borsh(crate = "near_sdk::borsh")] -/// struct MyStruct { -/// pub name: String, -/// } -/// ``` -/// Instead of: -/// ```ignore -/// #[near] -/// struct MyStruct { -/// pub name: String, -/// } -/// ``` #[proc_macro_attribute] pub fn near_bindgen(attr: TokenStream, item: TokenStream) -> TokenStream { if attr.to_string().contains("event_json") { @@ -458,33 +307,6 @@ fn process_impl_block( .into()) } -/// `ext_contract` takes a Rust Trait and converts it to a module with static methods. -/// Each of these static methods takes positional arguments defined by the Trait, -/// then the receiver_id, the attached deposit and the amount of gas and returns a new Promise. -/// -/// ## Examples -/// -/// ```ignore -/// use near_sdk::ext_contract; -/// -/// #[ext_contract(ext_calculator)] -/// trait Calculator { -/// fn mult(&self, a: u64, b: u64) -> u128; -/// fn sum(&self, a: u128, b: u128) -> u128; -/// } -/// -/// #[near] -/// impl Contract { -/// pub fn multiply_by_five(&mut self, number: u64) -> Promise { -/// ext_calculator::ext(self.calculator_account.clone()) -/// .with_static_gas(Gas::from_tgas(5)) -/// .mult(number, 5) -/// } -/// } -/// -/// ``` -/// -/// See more information about role of ext_contract in [NEAR documentation](https://docs.near.org/build/smart-contracts/anatomy/crosscontract) #[proc_macro_attribute] pub fn ext_contract(attr: TokenStream, item: TokenStream) -> TokenStream { if let Ok(mut input) = syn::parse::(item) { @@ -568,18 +390,6 @@ struct DeriveNearSchema { borsh: Option, } -/// `NearSchema` is a derive macro that generates `BorshSchema` and / or `JsonSchema` implementations. -/// Use `#[abi(json)]` attribute to generate code for `JsonSchema`. And `#[abi(borsh)]` for `BorshSchema`. -/// You can use both and none as well. -/// ## Example -/// ```ignore -/// #[derive(NearSchema)] -/// #[abi(borsh)] -/// struct Value { -/// field: InnerValue, -/// } -/// ``` -/// In this example, BorshSchema will be generated for `Value` struct. #[proc_macro_derive(NearSchema, attributes(abi, serde, borsh, schemars, validate, inside_nearsdk))] pub fn derive_near_schema(#[allow(unused)] input: TokenStream) -> TokenStream { #[cfg(not(feature = "abi"))] @@ -785,10 +595,6 @@ fn get_where_clause( where_clause } -/// `PanicOnDefault` generates implementation for `Default` trait that panics with the following -/// message `The contract is not initialized` when `default()` is called. -/// This is a helpful macro in case the contract is required to be initialized with either `init` or -/// `init(ignore_state)`. #[proc_macro_derive(PanicOnDefault)] pub fn derive_no_default(item: TokenStream) -> TokenStream { if let Ok(input) = syn::parse::(item) { @@ -811,34 +617,6 @@ pub fn derive_no_default(item: TokenStream) -> TokenStream { } } -/// `BorshStorageKey` generates implementation for `BorshIntoStorageKey` trait. -/// It allows the type to be passed as a unique prefix for persistent collections. -/// The type should also implement or derive `BorshSerialize` trait. -/// -/// More information about storage keys in [NEAR documentation](https://docs.near.org/build/smart-contracts/anatomy/storage) -/// ## Example -/// ```ignore -/// #[derive(BorshSerialize, BorshDeserialize, BorshStorageKey)] -/// #[borsh(crate = "near_sdk::borsh")] -/// pub enum StorageKey { -/// Messages, -/// } -/// -/// // Define the contract structure -/// #[near(contract_state)] -/// pub struct Contract { -/// messages: Vector -/// } -/// -/// // Define the default, which automatically initializes the contract -/// impl Default for Contract { -/// fn default() -> Self { -/// Self { -/// messages: Vector::new(StorageKey::Messages) -/// } -/// } -/// } -/// ``` #[proc_macro_derive(BorshStorageKey)] pub fn borsh_storage_key(item: TokenStream) -> TokenStream { let (name, generics) = if let Ok(input) = syn::parse::(item.clone()) { @@ -867,9 +645,6 @@ pub fn borsh_storage_key(item: TokenStream) -> TokenStream { }) } -/// `FunctionError` generates implementation for `near_sdk::FunctionError` trait. -/// It allows contract runtime to panic with the type using its `ToString` implementation -/// as the message. #[proc_macro_derive(FunctionError)] pub fn function_error(item: TokenStream) -> TokenStream { let name = if let Ok(input) = syn::parse::(item.clone()) { @@ -894,20 +669,6 @@ pub fn function_error(item: TokenStream) -> TokenStream { }) } -/// NOTE: This is an internal implementation for `#[near_bindgen(events(standard = ...))]` attribute. -/// -/// This derive macro is used to inject the necessary wrapper and logic to auto format -/// standard event logs. The other appropriate attribute macros are not injected with this macro. -/// Required attributes below: -/// ```ignore -/// #[derive(near_sdk::serde::Serialize, std::clone::Clone)] -/// #[serde(crate="near_sdk::serde")] -/// #[serde(tag = "event", content = "data")] -/// #[serde(rename_all="snake_case")] -/// pub enum MyEvent { -/// Event -/// } -/// ``` #[proc_macro_derive(EventMetadata, attributes(event_version))] pub fn derive_event_attributes(item: TokenStream) -> TokenStream { if let Ok(input) = syn::parse::(item) { diff --git a/near-sdk/src/json_types/vector.rs b/near-sdk/src/json_types/vector.rs index b69e484ae..47dd3ac38 100644 --- a/near-sdk/src/json_types/vector.rs +++ b/near-sdk/src/json_types/vector.rs @@ -2,7 +2,16 @@ use near_sdk_macros::near; use serde::{Deserialize, Deserializer, Serializer}; /// Helper class to serialize/deserialize `Vec` to base64 string. - +/// +/// # Example +/// ```rust +/// use near_sdk::{json_types::Base64VecU8, near}; +/// +/// #[near(serializers=[json])] +/// struct NewStruct { +/// field: Base64VecU8, +/// } +/// ``` #[near(inside_nearsdk, serializers=[borsh, json])] #[derive(Debug, Clone, PartialEq, Eq)] pub struct Base64VecU8( @@ -25,19 +34,7 @@ impl From for Vec { } } -/// Convenience module to allow anotating a serde structure as base64 bytes. -/// -/// # Example -/// ```ignore -/// use serde::{Serialize, Deserialize}; -/// use near_sdk::json_types::base64_bytes; -/// -/// #[derive(Serialize, Deserialize)] -/// struct NewStruct { -/// #[serde(with = "base64_bytes")] -/// field: Vec, -/// } -/// ``` +/// Convenience module to allow annotating a serde structure as base64 bytes. mod base64_bytes { use super::*; use base64::Engine; diff --git a/near-sdk/src/lib.rs b/near-sdk/src/lib.rs index 8da02ca20..1f1bd90dc 100644 --- a/near-sdk/src/lib.rs +++ b/near-sdk/src/lib.rs @@ -87,6 +87,8 @@ //! ```bash //! cargo test //! ``` +//! +//! # For more information, see the [macro@near] documentation. //* Clippy is giving false positive warnings for this in 1.57 version. Remove this if fixed. //* https://github.com/rust-lang/rust-clippy/issues/8091 @@ -99,10 +101,321 @@ #[cfg(test)] extern crate quickcheck; -pub use near_sdk_macros::{ - ext_contract, near, near_bindgen, BorshStorageKey, EventMetadata, FunctionError, NearSchema, - PanicOnDefault, -}; +/// This attribute macro is used on a struct and its implementations +/// to generate the necessary code to expose `pub` methods from the contract as well +/// as generating the glue code to be a valid NEAR contract. +/// +/// ## Example +/// +/// ```rust +/// use near_sdk::near; +/// +/// #[near(serializers=[borsh, json])] +/// struct MyStruct { +/// pub name: String, +/// } +/// ``` +/// +/// This macro will generate code to load and deserialize state if the `self` parameter is included +/// as well as saving it back to state if `&mut self` is used. +/// +/// # Parameter and result serialization +/// If the macro is used with Impl section, for parameter serialization, this macro will generate a struct with all of the parameters as +/// fields and derive deserialization for it. By default this will be JSON deserialized with `serde` +/// but can be overwritten by using `#[serializer(borsh)]`: +/// ```rust +/// use near_sdk::near; +/// +/// # #[near(contract_state)] +/// # struct MyContract { +/// # pub name: String, +/// # } +/// +/// #[near] +/// impl MyContract { +/// #[result_serializer(borsh)] +/// pub fn borsh_parameters(&self, #[serializer(borsh)] a: String, #[serializer(borsh)] b: String) -> String { +/// format!("{} {}", a, b) +/// } +/// } +/// ``` +/// +/// `#[near]` will also handle serializing and setting the return value of the +/// function execution based on what type is returned by the function. By default, this will be +/// done through `serde` serialized as JSON, but this can be overwritten using +/// `#[result_serializer(borsh)]`: +/// ```rust +/// use near_sdk::near; +/// +/// # #[near(contract_state)] +/// # struct MyContract { +/// # pub name: String, +/// # } +/// +/// #[near] +/// impl MyContract { +/// #[result_serializer(borsh)] +/// pub fn borsh_parameters(&self) -> String { +/// self.name.clone() +/// } +/// } +/// ``` +/// +/// # Usage for enum / struct +/// +/// If the macro is used with struct or enum, it will make the struct or enum serializable with either +/// Borsh or Json depending on serializers passed. Use `#[near(serializers=[borsh])]` to make it serializable with Borsh. +/// Or use `#[near(serializers=[json])]` to make it serializable with Json. By default, borsh is used. +/// You can also specify both and none. BorshSchema or JsonSchema are always generated. +/// +/// If you want the struct to be a contract state, you can pass in the contract_state argument. +/// +/// ## Example +/// ```rust +/// use near_sdk::near; +/// +/// #[near(contract_state)] +/// pub struct Contract { +/// data: i8, +/// } +/// +/// #[near] +/// impl Contract { +/// pub fn some_function(&self) {} +/// } +/// ``` +/// As well, the macro supports arguments like `event_json` and `contract_metadata`. +/// +/// # Events Standard: +/// +/// By passing `event_json` as an argument `near_bindgen` will generate the relevant code to format events +/// according to NEP-297 +/// +/// For parameter serialization, this macro will generate a wrapper struct to include the NEP-297 standard fields `standard` and `version +/// as well as include serialization reformatting to include the `event` and `data` fields automatically. +/// The `standard` and `version` values must be included in the enum and variant declaration (see example below). +/// By default this will be JSON deserialized with `serde` +/// +/// +/// ## Examples +/// +/// ```rust +/// use near_sdk::{near, AccountId}; +/// +/// # #[near(contract_state)] +/// # pub struct Contract { +/// # data: i8, +/// # } +/// +/// +/// #[near(event_json(standard = "nepXXX"))] +/// pub enum MyEvents { +/// #[event_version("1.0.0")] +/// Swap { token_in: AccountId, token_out: AccountId, amount_in: u128, amount_out: u128 }, +/// +/// #[event_version("2.0.0")] +/// StringEvent(String), +/// +/// #[event_version("3.0.0")] +/// EmptyEvent +/// } +/// +/// #[near] +/// impl Contract { +/// pub fn some_function(&self) { +/// MyEvents::StringEvent( +/// String::from("some_string") +/// ).emit(); +/// } +/// +/// } +/// ``` +/// +/// # Contract Source Metadata Standard: +/// +/// By using `contract_metadata` as an argument `near` will populate the contract metadata +/// according to [`NEP-330`]() standard. This still applies even when `#[near]` is used without +/// any arguments. +/// +/// All fields(version, link, standard) are optional and will be populated with defaults from the Cargo.toml file if not specified. +/// +/// The `contract_source_metadata()` view function will be added and can be used to retrieve the source metadata. +/// Also, the source metadata will be stored as a constant, `CONTRACT_SOURCE_METADATA`, in the contract code. +/// +/// ## Examples +/// ```rust +/// use near_sdk::near; +/// +/// #[near(contract_metadata( +/// version = "39f2d2646f2f60e18ab53337501370dc02a5661c", +/// link = "https://github.com/near-examples/nft-tutorial", +/// standard(standard = "nep330", version = "1.1.0"), +/// standard(standard = "nep171", version = "1.0.0"), +/// standard(standard = "nep177", version = "2.0.0"), +/// ))] +/// struct Contract {} +/// ``` +pub use near_sdk_macros::near; + +/// `ext_contract` takes a Rust Trait and converts it to a module with static methods. +/// Each of these static methods takes positional arguments defined by the Trait, +/// then the receiver_id, the attached deposit and the amount of gas and returns a new Promise. +/// +/// ## Examples +/// +/// ```rust +/// use near_sdk::{AccountId,ext_contract, near, Promise, Gas}; +/// +/// #[near(contract_state)] +/// struct Contract { +/// calculator_account: AccountId, +/// } +/// +/// #[ext_contract(ext_calculator)] +/// trait Calculator { +/// fn mult(&self, a: u64, b: u64) -> u128; +/// fn sum(&self, a: u128, b: u128) -> u128; +/// } +/// +/// #[near] +/// impl Contract { +/// pub fn multiply_by_five(&mut self, number: u64) -> Promise { +/// ext_calculator::ext(self.calculator_account.clone()) +/// .with_static_gas(Gas::from_tgas(5)) +/// .mult(number, 5) +/// } +/// } +/// +/// ``` +/// +/// See more information about role of ext_contract in [NEAR documentation](https://docs.near.org/build/smart-contracts/anatomy/crosscontract) +pub use near_sdk_macros::ext_contract; + +/// This macro is deprecated. Use [macro@near] instead. The difference between `#[near]` and `#[near_bindgen]` is that +/// with `#[near_bindgen]` you have to manually add boilerplate code for structs and enums so that they become Json- and Borsh-serializable: +/// ```rust +/// use near_sdk::{near_bindgen, NearSchema, borsh::{BorshSerialize, BorshDeserialize}}; +/// +/// #[near_bindgen] +/// #[derive(BorshSerialize, BorshDeserialize, NearSchema)] +/// #[borsh(crate = "near_sdk::borsh")] +/// struct MyStruct { +/// pub name: String, +/// } +/// ``` +/// Instead of: +/// ```rust +/// use near_sdk::near; +/// +/// #[near(serializers=[borsh])] +/// struct MyStruct { +/// pub name: String, +/// } +/// ``` +pub use near_sdk_macros::near_bindgen; + +/// `BorshStorageKey` generates implementation for `BorshIntoStorageKey` trait. +/// It allows the type to be passed as a unique prefix for persistent collections. +/// The type should also implement or derive `BorshSerialize` trait. +/// +/// More information about storage keys in [NEAR documentation](https://docs.near.org/build/smart-contracts/anatomy/storage) +/// ## Example +/// ```rust +/// use near_sdk::{BorshStorageKey, collections::Vector, near}; +/// +/// #[near(serializers=[borsh])] +/// #[derive(BorshStorageKey)] +/// pub enum StorageKey { +/// Messages, +/// } +/// +/// // Define the contract structure +/// #[near(contract_state)] +/// pub struct Contract { +/// messages: Vector +/// } +/// +/// // Define the default, which automatically initializes the contract +/// impl Default for Contract { +/// fn default() -> Self { +/// Self { +/// messages: Vector::new(StorageKey::Messages) +/// } +/// } +/// } +/// ``` +pub use near_sdk_macros::BorshStorageKey; + +/// `PanicOnDefault` generates implementation for `Default` trait that panics with the following +/// message `The contract is not initialized` when `default()` is called. +/// This is a helpful macro in case the contract is required to be initialized with either `init` or +/// `init(rust_state)` +/// +/// ## Example +/// ```rust +/// use near_sdk::{PanicOnDefault, near}; +/// +/// #[near(contract_state)] +/// #[derive(PanicOnDefault)] +/// pub struct Contract { +/// pub name: String, +/// } +/// ``` +pub use near_sdk_macros::PanicOnDefault; + +/// NOTE: This is an internal implementation for `#[near_bindgen(events(standard = ...))]` attribute. +/// +/// This derive macro is used to inject the necessary wrapper and logic to auto format +/// standard event logs. The other appropriate attribute macros are not injected with this macro. +/// Required attributes below: +/// ```rust +/// #[derive(near_sdk::serde::Serialize, Clone)] +/// #[serde(crate="near_sdk::serde")] +/// #[serde(tag = "event", content = "data")] +/// #[serde(rename_all="snake_case")] +/// pub enum MyEvent { +/// Event +/// } +/// ``` +pub use near_sdk_macros::EventMetadata; + +/// `NearSchema` is a derive macro that generates `BorshSchema` and / or `JsonSchema` implementations. +/// Use `#[abi(json)]` attribute to generate code for `JsonSchema`. And `#[abi(borsh)]` for `BorshSchema`. +/// You can use both and none as well. +/// ## Example +/// ```rust +/// use near_sdk_macros::NearSchema; +/// +/// #[derive(NearSchema)] +/// #[abi(borsh)] +/// struct Value { +/// field: String, +/// } +/// ``` +/// In this example, BorshSchema will be generated for `Value` struct. +pub use near_sdk_macros::NearSchema; + +/// `FunctionError` generates implementation for `near_sdk::FunctionError` trait. +/// It allows contract runtime to panic with the type using its `ToString` implementation +/// as the message. +/// ## Example +/// ```rust +/// use near_sdk::FunctionError; +/// +/// #[derive(FunctionError)] +/// pub enum MyError { +/// Error, +/// } +/// +/// impl std::fmt::Display for MyError { +/// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +/// match self { +/// MyError::Error => write!(f, "Error"), +/// } +/// } +/// } +/// ``` +pub use near_sdk_macros::FunctionError; pub mod store; From 688bdc3cf00dea93f66dc34440855405b81661d3 Mon Sep 17 00:00:00 2001 From: akorchyn Date: Thu, 30 Jan 2025 18:12:21 +0200 Subject: [PATCH 2/7] nit --- near-sdk-macros/src/core_impl/abi/abi_generator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/near-sdk-macros/src/core_impl/abi/abi_generator.rs b/near-sdk-macros/src/core_impl/abi/abi_generator.rs index 9654f49d7..9f83179d5 100644 --- a/near-sdk-macros/src/core_impl/abi/abi_generator.rs +++ b/near-sdk-macros/src/core_impl/abi/abi_generator.rs @@ -61,7 +61,7 @@ impl ImplItemMethodInfo { /// } /// #} /// ``` - /// will produce this struct:ignore + /// will produce this struct: /// ```rust /// near_sdk::__private::AbiFunction { /// name: "f3".to_string(), From 92a9fabaeb863e945777164d4333f2017da9c4f9 Mon Sep 17 00:00:00 2001 From: akorchyn Date: Thu, 30 Jan 2025 18:52:48 +0200 Subject: [PATCH 3/7] ignore some abi example --- near-sdk-macros/src/core_impl/abi/abi_generator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/near-sdk-macros/src/core_impl/abi/abi_generator.rs b/near-sdk-macros/src/core_impl/abi/abi_generator.rs index 9f83179d5..29c4075ef 100644 --- a/near-sdk-macros/src/core_impl/abi/abi_generator.rs +++ b/near-sdk-macros/src/core_impl/abi/abi_generator.rs @@ -62,7 +62,7 @@ impl ImplItemMethodInfo { /// #} /// ``` /// will produce this struct: - /// ```rust + /// ```ignore /// near_sdk::__private::AbiFunction { /// name: "f3".to_string(), /// doc: Some(" I am a function.".to_string()), From 499d0ce714c277ae08290ef9d03b679c69bce3d7 Mon Sep 17 00:00:00 2001 From: akorchyn Date: Thu, 30 Jan 2025 19:23:54 +0200 Subject: [PATCH 4/7] restore --- .../src/core_impl/abi/abi_generator.rs | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/near-sdk-macros/src/core_impl/abi/abi_generator.rs b/near-sdk-macros/src/core_impl/abi/abi_generator.rs index 29c4075ef..4a2d2b5f1 100644 --- a/near-sdk-macros/src/core_impl/abi/abi_generator.rs +++ b/near-sdk-macros/src/core_impl/abi/abi_generator.rs @@ -44,22 +44,10 @@ impl ImplItemMethodInfo { /// /// # Example: /// The following function: - /// ```rust - /// # use near_sdk::{near}; - /// # #[near(contract_state)] - /// # #[derive(Default)] - /// # pub struct Counter { - /// # val: u64, - /// # } - /// - /// # #[near] - /// # impl Counter { + /// ```ignore /// /// I am a function. /// #[handle_result] - /// pub fn f3(&mut self, arg0: FancyStruct, arg1: u64) -> Result { - /// # unimplemented!() - /// } - /// #} + /// pub fn f3(&mut self, arg0: FancyStruct, arg1: u64) -> Result { } /// ``` /// will produce this struct: /// ```ignore From e80addb97f09c39d60f00d62004237674cd347ec Mon Sep 17 00:00:00 2001 From: akorchyn Date: Fri, 31 Jan 2025 14:01:55 +0200 Subject: [PATCH 5/7] review --- near-sdk/src/lib.rs | 56 +++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/near-sdk/src/lib.rs b/near-sdk/src/lib.rs index 1f1bd90dc..0dfc08838 100644 --- a/near-sdk/src/lib.rs +++ b/near-sdk/src/lib.rs @@ -24,7 +24,7 @@ //! near-sdk = "5.6.0" //! ``` //! -//! ### Example: Counter Smart Contract +//! ### Example: Counter Smart Contract. For more information, see the [macro@near] documentation. //! //! Below is an example of a simple counter contract that increments and retrieves a value: //! @@ -87,9 +87,6 @@ //! ```bash //! cargo test //! ``` -//! -//! # For more information, see the [macro@near] documentation. - //* Clippy is giving false positive warnings for this in 1.57 version. Remove this if fixed. //* https://github.com/rust-lang/rust-clippy/issues/8091 #![allow(clippy::redundant_closure)] @@ -101,10 +98,12 @@ #[cfg(test)] extern crate quickcheck; -/// This attribute macro is used on a struct and its implementations +/// This attribute macro is used on a struct/enum and its implementations /// to generate the necessary code to expose `pub` methods from the contract as well /// as generating the glue code to be a valid NEAR contract. /// +/// The macro is a syntactic sugar for [macro@near_bindgen] and expands to the [macro@near_bindgen] macro invocations. +/// /// ## Example /// /// ```rust @@ -142,7 +141,7 @@ extern crate quickcheck; /// /// `#[near]` will also handle serializing and setting the return value of the /// function execution based on what type is returned by the function. By default, this will be -/// done through `serde` serialized as JSON, but this can be overwritten using +/// done through `serde` serialized as JSON, but this can be overridden using /// `#[result_serializer(borsh)]`: /// ```rust /// use near_sdk::near; @@ -166,9 +165,9 @@ extern crate quickcheck; /// If the macro is used with struct or enum, it will make the struct or enum serializable with either /// Borsh or Json depending on serializers passed. Use `#[near(serializers=[borsh])]` to make it serializable with Borsh. /// Or use `#[near(serializers=[json])]` to make it serializable with Json. By default, borsh is used. -/// You can also specify both and none. BorshSchema or JsonSchema are always generated. +/// You can also specify both and none. BorshSchema or JsonSchema are always generated if respective serializer is toggled on. /// -/// If you want the struct to be a contract state, you can pass in the contract_state argument. +/// If you want the struct/enum to be a contract state, you can pass in the contract_state argument. /// /// ## Example /// ```rust @@ -184,18 +183,18 @@ extern crate quickcheck; /// pub fn some_function(&self) {} /// } /// ``` -/// As well, the macro supports arguments like `event_json` and `contract_metadata`. /// /// # Events Standard: /// /// By passing `event_json` as an argument `near_bindgen` will generate the relevant code to format events -/// according to NEP-297 +/// according to [NEP-297](https://github.com/near/NEPs/blob/master/neps/nep-0297.md) /// /// For parameter serialization, this macro will generate a wrapper struct to include the NEP-297 standard fields `standard` and `version /// as well as include serialization reformatting to include the `event` and `data` fields automatically. /// The `standard` and `version` values must be included in the enum and variant declaration (see example below). /// By default this will be JSON deserialized with `serde` /// +/// The version is required to allow backward compatibility. The older back-end will use the version field to determine if the event is supported. /// /// ## Examples /// @@ -237,7 +236,10 @@ extern crate quickcheck; /// according to [`NEP-330`]() standard. This still applies even when `#[near]` is used without /// any arguments. /// -/// All fields(version, link, standard) are optional and will be populated with defaults from the Cargo.toml file if not specified. +/// All fields(version, link) are optional and will be populated with defaults from the Cargo.toml file if not specified. +/// The `standard` will be populated with `nep330` by default. +/// +/// Any additional standards can be added and should be specified using the `standard` sub-attribute. /// /// The `contract_source_metadata()` view function will be added and can be used to retrieve the source metadata. /// Also, the source metadata will be stored as a constant, `CONTRACT_SOURCE_METADATA`, in the contract code. @@ -314,9 +316,9 @@ pub use near_sdk_macros::ext_contract; /// ``` pub use near_sdk_macros::near_bindgen; -/// `BorshStorageKey` generates implementation for `BorshIntoStorageKey` trait. +/// `BorshStorageKey` generates implementation for [BorshIntoStorageKey](crate::private::BorshIntoStorageKey) trait. /// It allows the type to be passed as a unique prefix for persistent collections. -/// The type should also implement or derive `BorshSerialize` trait. +/// The type should also implement or derive [BorshSerialize](borsh::BorshSerialize) trait. /// /// More information about storage keys in [NEAR documentation](https://docs.near.org/build/smart-contracts/anatomy/storage) /// ## Example @@ -364,19 +366,12 @@ pub use near_sdk_macros::BorshStorageKey; pub use near_sdk_macros::PanicOnDefault; /// NOTE: This is an internal implementation for `#[near_bindgen(events(standard = ...))]` attribute. +/// Please use [macro@near] instead. /// /// This derive macro is used to inject the necessary wrapper and logic to auto format -/// standard event logs. The other appropriate attribute macros are not injected with this macro. -/// Required attributes below: -/// ```rust -/// #[derive(near_sdk::serde::Serialize, Clone)] -/// #[serde(crate="near_sdk::serde")] -/// #[serde(tag = "event", content = "data")] -/// #[serde(rename_all="snake_case")] -/// pub enum MyEvent { -/// Event -/// } -/// ``` +/// standard event logs and generate the `emit` function, and event version. +/// +/// The macro is not for public use. pub use near_sdk_macros::EventMetadata; /// `NearSchema` is a derive macro that generates `BorshSchema` and / or `JsonSchema` implementations. @@ -400,7 +395,7 @@ pub use near_sdk_macros::NearSchema; /// as the message. /// ## Example /// ```rust -/// use near_sdk::FunctionError; +/// use near_sdk::{FunctionError, near}; /// /// #[derive(FunctionError)] /// pub enum MyError { @@ -414,6 +409,17 @@ pub use near_sdk_macros::NearSchema; /// } /// } /// } +/// +/// #[near(contract_state)] +/// pub struct Contract {} +/// +/// #[near] +/// impl Contract { +/// #[handle_result] +/// pub fn some_function(&self) -> Result<(), MyError> { +/// Err(MyError::Error) +/// } +/// } /// ``` pub use near_sdk_macros::FunctionError; From 4f715a450eadb6b79e8c6b861a56bc6dfc7f283d Mon Sep 17 00:00:00 2001 From: akorchyn Date: Tue, 4 Feb 2025 12:06:51 +0200 Subject: [PATCH 6/7] review 2 --- README.md | 8 -------- near-sdk/src/lib.rs | 4 ++-- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 4c55899b8..742ae8976 100644 --- a/README.md +++ b/README.md @@ -293,14 +293,6 @@ cargo near deploy Builds the smart contract (equivalent to `cargo near build`) and guides you to deploy it to the blockchain. -## Building with reproducible builds - -Since WebAssembly compiler includes a bunch of debug information into the binary, the resulting binary might be -different on different machines. To be able to compile the binary in a reproducible way, we added a Dockerfile -that allows to compile the binary. - -**Use [contract-builder](https://github.com/near/near-sdk-rs/tree/master/contract-builder)** - ## NEAR contract standards [`near-contract-standards` crate](https://github.com/near/near-sdk-rs/tree/master/near-contract-standards) provides a set of interfaces and implementations for NEAR's contract standards: diff --git a/near-sdk/src/lib.rs b/near-sdk/src/lib.rs index 0dfc08838..2e9414ad2 100644 --- a/near-sdk/src/lib.rs +++ b/near-sdk/src/lib.rs @@ -245,13 +245,13 @@ extern crate quickcheck; /// Also, the source metadata will be stored as a constant, `CONTRACT_SOURCE_METADATA`, in the contract code. /// /// ## Examples +/// /// ```rust /// use near_sdk::near; /// /// #[near(contract_metadata( /// version = "39f2d2646f2f60e18ab53337501370dc02a5661c", /// link = "https://github.com/near-examples/nft-tutorial", -/// standard(standard = "nep330", version = "1.1.0"), /// standard(standard = "nep171", version = "1.0.0"), /// standard(standard = "nep177", version = "2.0.0"), /// ))] @@ -316,7 +316,7 @@ pub use near_sdk_macros::ext_contract; /// ``` pub use near_sdk_macros::near_bindgen; -/// `BorshStorageKey` generates implementation for [BorshIntoStorageKey](crate::private::BorshIntoStorageKey) trait. +/// `BorshStorageKey` generates implementation for [BorshIntoStorageKey](crate::__private::BorshIntoStorageKey) trait. /// It allows the type to be passed as a unique prefix for persistent collections. /// The type should also implement or derive [BorshSerialize](borsh::BorshSerialize) trait. /// From 1177e5dd02499b8387cda46f7f4416c7b87fe432 Mon Sep 17 00:00:00 2001 From: akorchyn Date: Tue, 4 Feb 2025 12:08:48 +0200 Subject: [PATCH 7/7] moved near-bindgen after near macro --- near-sdk/src/lib.rs | 46 ++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/near-sdk/src/lib.rs b/near-sdk/src/lib.rs index 2e9414ad2..47063b567 100644 --- a/near-sdk/src/lib.rs +++ b/near-sdk/src/lib.rs @@ -259,6 +259,29 @@ extern crate quickcheck; /// ``` pub use near_sdk_macros::near; +/// This macro is deprecated. Use [macro@near] instead. The difference between `#[near]` and `#[near_bindgen]` is that +/// with `#[near_bindgen]` you have to manually add boilerplate code for structs and enums so that they become Json- and Borsh-serializable: +/// ```rust +/// use near_sdk::{near_bindgen, NearSchema, borsh::{BorshSerialize, BorshDeserialize}}; +/// +/// #[near_bindgen] +/// #[derive(BorshSerialize, BorshDeserialize, NearSchema)] +/// #[borsh(crate = "near_sdk::borsh")] +/// struct MyStruct { +/// pub name: String, +/// } +/// ``` +/// Instead of: +/// ```rust +/// use near_sdk::near; +/// +/// #[near(serializers=[borsh])] +/// struct MyStruct { +/// pub name: String, +/// } +/// ``` +pub use near_sdk_macros::near_bindgen; + /// `ext_contract` takes a Rust Trait and converts it to a module with static methods. /// Each of these static methods takes positional arguments defined by the Trait, /// then the receiver_id, the attached deposit and the amount of gas and returns a new Promise. @@ -293,29 +316,6 @@ pub use near_sdk_macros::near; /// See more information about role of ext_contract in [NEAR documentation](https://docs.near.org/build/smart-contracts/anatomy/crosscontract) pub use near_sdk_macros::ext_contract; -/// This macro is deprecated. Use [macro@near] instead. The difference between `#[near]` and `#[near_bindgen]` is that -/// with `#[near_bindgen]` you have to manually add boilerplate code for structs and enums so that they become Json- and Borsh-serializable: -/// ```rust -/// use near_sdk::{near_bindgen, NearSchema, borsh::{BorshSerialize, BorshDeserialize}}; -/// -/// #[near_bindgen] -/// #[derive(BorshSerialize, BorshDeserialize, NearSchema)] -/// #[borsh(crate = "near_sdk::borsh")] -/// struct MyStruct { -/// pub name: String, -/// } -/// ``` -/// Instead of: -/// ```rust -/// use near_sdk::near; -/// -/// #[near(serializers=[borsh])] -/// struct MyStruct { -/// pub name: String, -/// } -/// ``` -pub use near_sdk_macros::near_bindgen; - /// `BorshStorageKey` generates implementation for [BorshIntoStorageKey](crate::__private::BorshIntoStorageKey) trait. /// It allows the type to be passed as a unique prefix for persistent collections. /// The type should also implement or derive [BorshSerialize](borsh::BorshSerialize) trait.