Skip to content

Commit

Permalink
doc: moved near-sdk-macros doc to near-sdk crate. (#1295)
Browse files Browse the repository at this point in the history
Resolves: #1288

Replaced ignore -> rust for examples to be able to test them in CI
  • Loading branch information
akorchyn authored Feb 4, 2025
1 parent cc22bb2 commit 0a805b5
Show file tree
Hide file tree
Showing 5 changed files with 337 additions and 268 deletions.
8 changes: 0 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl AttrSigInfo {
/// and `SUBTYPE` is one of the following: `[T; n]`, path like
/// `std::collections::HashMap<SUBTYPE, SUBTYPE>`, or tuple `(SUBTYPE0, SUBTYPE1, ...)`.
/// # Example
/// ```ignore
/// ```rust
/// struct Input {
/// arg0: Vec<String>,
/// arg1: [u64; 10],
Expand Down
239 changes: 0 additions & 239 deletions near-sdk-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,140 +43,6 @@ struct NearMacroArgs {
inside_nearsdk: Option<bool>,
}

/// 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`](<https://github.com/near/NEPs/blob/master/neps/nep-0330.md>) 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") {
Expand Down Expand Up @@ -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") {
Expand Down Expand Up @@ -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::<ItemTrait>(item) {
Expand Down Expand Up @@ -568,18 +390,6 @@ struct DeriveNearSchema {
borsh: Option<bool>,
}

/// `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"))]
Expand Down Expand Up @@ -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::<ItemStruct>(item) {
Expand All @@ -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<String>
/// }
///
/// // 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::<ItemEnum>(item.clone()) {
Expand Down Expand Up @@ -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::<ItemEnum>(item.clone()) {
Expand All @@ -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::<ItemEnum>(item) {
Expand Down
25 changes: 11 additions & 14 deletions near-sdk/src/json_types/vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@ use near_sdk_macros::near;
use serde::{Deserialize, Deserializer, Serializer};

/// Helper class to serialize/deserialize `Vec<u8>` 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(
Expand All @@ -25,19 +34,7 @@ impl From<Base64VecU8> for Vec<u8> {
}
}

/// 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<u8>,
/// }
/// ```
/// Convenience module to allow annotating a serde structure as base64 bytes.
mod base64_bytes {
use super::*;
use base64::Engine;
Expand Down
Loading

0 comments on commit 0a805b5

Please sign in to comment.