Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: moved near-sdk-macros doc to near-sdk crate. #1295

Merged
merged 10 commits into from
Feb 4, 2025
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
Loading