near_contract_standards/non_fungible_token/core/mod.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
mod core_impl;
mod receiver;
mod resolver;
pub use self::core_impl::*;
pub use self::receiver::{ext_nft_receiver, NonFungibleTokenReceiver};
pub use self::resolver::{ext_nft_resolver, NonFungibleTokenResolver};
use crate::non_fungible_token::token::{Token, TokenId};
use near_sdk::ext_contract;
use near_sdk::AccountId;
use near_sdk::PromiseOrValue;
/// Used for all non-fungible tokens. The specification for the
/// [core non-fungible token standard] lays out the reasoning for each method.
/// It's important to check out [NonFungibleTokenReceiver](crate::non_fungible_token::core::NonFungibleTokenReceiver)
/// and [NonFungibleTokenResolver](crate::non_fungible_token::core::NonFungibleTokenResolver) to
/// understand how the cross-contract call work.
///
/// [core non-fungible token standard]: <https://nomicon.io/Standards/NonFungibleToken/Core.html>
///
/// # Examples
///
/// ```
/// use near_sdk::{PanicOnDefault, AccountId, PromiseOrValue, near};
/// use near_contract_standards::non_fungible_token::{core::NonFungibleTokenCore, NonFungibleToken, TokenId, Token};
///
/// #[near(contract_state)]
/// #[derive(PanicOnDefault)]
/// pub struct Contract {
/// tokens: NonFungibleToken,
///}
/// #[near]
/// impl NonFungibleTokenCore for Contract {
/// #[payable]
/// fn nft_transfer(&mut self, receiver_id: AccountId, token_id: TokenId, approval_id: Option<u64>, memo: Option<String>) {
/// self.tokens.nft_transfer(receiver_id, token_id, approval_id, memo);
/// }
///
/// #[payable]
/// fn nft_transfer_call(&mut self, receiver_id: AccountId, token_id: TokenId, approval_id: Option<u64>, memo: Option<String>, msg: String) -> PromiseOrValue<bool> {
/// self.tokens.nft_transfer_call(receiver_id, token_id, approval_id, memo, msg)
/// }
///
/// fn nft_token(&self, token_id: TokenId) -> Option<Token> {
/// self.tokens.nft_token(token_id)
/// }
///}
/// ```
///
#[ext_contract(ext_nft_core)]
pub trait NonFungibleTokenCore {
/// Simple transfer. Transfer a given `token_id` from current owner to
/// `receiver_id`.
///
/// Requirements
/// * Caller of the method must attach a deposit of 1 yoctoⓃ for security purposes
/// * Contract MUST panic if called by someone other than token owner or,
/// if using Approval Management, one of the approved accounts
/// * `approval_id` is for use with Approval Management,
/// see <https://nomicon.io/Standards/NonFungibleToken/ApprovalManagement.html>
/// * If using Approval Management, contract MUST nullify approved accounts on
/// successful transfer.
/// * TODO: needed? Both accounts must be registered with the contract for transfer to
/// succeed. See see <https://nomicon.io/Standards/StorageManagement.html>
///
/// Arguments:
/// * `receiver_id`: the valid NEAR account receiving the token
/// * `token_id`: the token to transfer
/// * `approval_id`: expected approval ID. A number smaller than
/// 2^53, and therefore representable as JSON. See Approval Management
/// standard for full explanation.
/// * `memo` (optional): for use cases that may benefit from indexing or
/// providing information for a transfer
fn nft_transfer(
&mut self,
receiver_id: AccountId,
token_id: TokenId,
approval_id: Option<u64>,
memo: Option<String>,
);
/// Transfer token and call a method on a receiver contract. A successful
/// workflow will end in a success execution outcome to the callback on the NFT
/// contract at the method `nft_resolve_transfer`.
///
/// You can think of this as being similar to attaching native NEAR tokens to a
/// function call. It allows you to attach any Non-Fungible Token in a call to a
/// receiver contract.
///
/// Requirements:
/// * Caller of the method must attach a deposit of 1 yoctoⓃ for security
/// purposes
/// * Contract MUST panic if called by someone other than token owner or,
/// if using Approval Management, one of the approved accounts
/// * The receiving contract must implement `ft_on_transfer` according to the
/// standard. If it does not, FT contract's `ft_resolve_transfer` MUST deal
/// with the resulting failed cross-contract call and roll back the transfer.
/// * Contract MUST implement the behavior described in `ft_resolve_transfer`
/// * `approval_id` is for use with Approval Management extension, see
/// that document for full explanation.
/// * If using Approval Management, contract MUST nullify approved accounts on
/// successful transfer.
///
/// Arguments:
/// * `receiver_id`: the valid NEAR account receiving the token.
/// * `token_id`: the token to send.
/// * `approval_id`: expected approval ID. A number smaller than
/// 2^53, and therefore representable as JSON. See Approval Management
/// standard for full explanation.
/// * `memo` (optional): for use cases that may benefit from indexing or
/// providing information for a transfer.
/// * `msg`: specifies information needed by the receiving contract in
/// order to properly handle the transfer. Can indicate both a function to
/// call and the parameters to pass to that function.
fn nft_transfer_call(
&mut self,
receiver_id: AccountId,
token_id: TokenId,
approval_id: Option<u64>,
memo: Option<String>,
msg: String,
) -> PromiseOrValue<bool>;
/// Returns the token with the given `token_id` or `null` if no such token.
fn nft_token(&self, token_id: TokenId) -> Option<Token>;
}