Skip to content

Commit

Permalink
chore: 178 hooks and some reorg
Browse files Browse the repository at this point in the history
  • Loading branch information
encody committed Oct 25, 2023
1 parent 0105484 commit b4e132e
Show file tree
Hide file tree
Showing 18 changed files with 329 additions and 475 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ use near_sdk::{
use near_sdk_contract_tools::nft::*;

#[derive(BorshSerialize, BorshDeserialize, PanicOnDefault, NonFungibleToken)]
#[non_fungible_token(no_approval_hooks)]
#[near_bindgen]
pub struct MyNft {}
```
Expand Down
6 changes: 3 additions & 3 deletions macros/src/standard/nep171.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ pub fn expand(meta: Nep171Meta) -> Result<TokenStream, darling::Error> {
if should_revert {
let token_ids = [token_id];

let transfer = Nep171Transfer {
let transfer = action::Nep171Transfer {
token_id: &token_ids[0],
authorization: Nep171TransferAuthorization::Owner,
sender_id: &receiver_id,
Expand Down Expand Up @@ -142,7 +142,7 @@ pub fn expand(meta: Nep171Meta) -> Result<TokenStream, darling::Error> {

let token_ids = [token_id];

let transfer = Nep171Transfer {
let transfer = action::Nep171Transfer {
token_id: &token_ids[0],
authorization: approval_id.map(Nep171TransferAuthorization::ApprovalId).unwrap_or(Nep171TransferAuthorization::Owner),
sender_id: &sender_id,
Expand Down Expand Up @@ -178,7 +178,7 @@ pub fn expand(meta: Nep171Meta) -> Result<TokenStream, darling::Error> {

let token_ids = [token_id];

let transfer = Nep171Transfer {
let transfer = action::Nep171Transfer {
token_id: &token_ids[0],
authorization: approval_id.map(Nep171TransferAuthorization::ApprovalId).unwrap_or(Nep171TransferAuthorization::Owner),
sender_id: &sender_id,
Expand Down
81 changes: 50 additions & 31 deletions macros/src/standard/nep178.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
use darling::{util::Flag, FromDeriveInput};
use darling::FromDeriveInput;
use proc_macro2::TokenStream;
use quote::quote;
use syn::Expr;
use syn::{Expr, Type};

use crate::unitify;

#[derive(Debug, FromDeriveInput)]
#[darling(attributes(nep178), supports(struct_named))]
pub struct Nep178Meta {
pub storage_key: Option<Expr>,
pub no_hooks: Flag,
pub all_hooks: Option<Type>,
pub approve_hook: Option<Type>,
pub revoke_hook: Option<Type>,
pub revoke_all_hook: Option<Type>,

pub generics: syn::Generics,
pub ident: syn::Ident,
Expand All @@ -22,7 +27,10 @@ pub struct Nep178Meta {
pub fn expand(meta: Nep178Meta) -> Result<TokenStream, darling::Error> {
let Nep178Meta {
storage_key,
no_hooks,
all_hooks,
approve_hook,
revoke_hook,
revoke_all_hook,

generics,
ident,
Expand All @@ -33,11 +41,6 @@ pub fn expand(meta: Nep178Meta) -> Result<TokenStream, darling::Error> {

let (imp, ty, wher) = generics.split_for_impl();

let hook = no_hooks
.is_present()
.then(|| quote! { () })
.unwrap_or_else(|| quote! { Self });

let root = storage_key.map(|storage_key| {
quote! {
fn root() -> #me::slot::Slot<()> {
Expand All @@ -46,9 +49,16 @@ pub fn expand(meta: Nep178Meta) -> Result<TokenStream, darling::Error> {
}
});

let all_hooks = unitify(all_hooks);
let approve_hook = unitify(approve_hook);
let revoke_hook = unitify(revoke_hook);
let revoke_all_hook = unitify(revoke_all_hook);

Ok(quote! {
impl #imp #me::standard::nep178::Nep178ControllerInternal for #ident #ty #wher {
type Hook = #hook;
type ApproveHook = (#approve_hook, #all_hooks);
type RevokeHook = (#revoke_hook, #all_hooks);
type RevokeAllHook = (#revoke_all_hook, #all_hooks);

#root
}
Expand All @@ -62,20 +72,23 @@ pub fn expand(meta: Nep178Meta) -> Result<TokenStream, darling::Error> {
account_id: #near_sdk::AccountId,
msg: Option<String>,
) -> #near_sdk::PromiseOrValue<()> {
use #me::standard::nep178::*;

#me::utils::assert_nonzero_deposit();

let predecessor = #near_sdk::env::predecessor_account_id();

let approval_id = #me::standard::nep178::Nep178Controller::approve(
self,
&token_id,
&predecessor,
&account_id,
)
.unwrap_or_else(|e| #near_sdk::env::panic_str(&e.to_string()));
let action = Nep178Approve {
token_id: &token_id,
current_owner_id: &predecessor,
account_id: &account_id,
};

let approval_id = Nep178Controller::approve(self, &action)
.unwrap_or_else(|e| #near_sdk::env::panic_str(&e.to_string()));

msg.map_or(#near_sdk::PromiseOrValue::Value(()), |msg| {
#me::standard::nep178::ext_nep178_receiver::ext(account_id)
ext_nep178_receiver::ext(account_id)
.nft_on_approve(token_id, predecessor, approval_id, msg)
.into()
})
Expand All @@ -87,31 +100,37 @@ pub fn expand(meta: Nep178Meta) -> Result<TokenStream, darling::Error> {
token_id: #me::standard::nep171::TokenId,
account_id: #near_sdk::AccountId,
) {
use #me::standard::nep178::*;

#near_sdk::assert_one_yocto();

let predecessor = #near_sdk::env::predecessor_account_id();

#me::standard::nep178::Nep178Controller::revoke(
self,
&token_id,
&predecessor,
&account_id,
)
.unwrap_or_else(|e| #near_sdk::env::panic_str(&e.to_string()));
let action = Nep178Revoke {
token_id: &token_id,
current_owner_id: &predecessor,
account_id: &account_id,
};

Nep178Controller::revoke(self, &action)
.unwrap_or_else(|e| #near_sdk::env::panic_str(&e.to_string()));
}

#[payable]
fn nft_revoke_all(&mut self, token_id: #me::standard::nep171::TokenId) {
use #me::standard::nep178::*;

#near_sdk::assert_one_yocto();

let predecessor = #near_sdk::env::predecessor_account_id();

#me::standard::nep178::Nep178Controller::revoke_all(
self,
&token_id,
&predecessor,
)
.unwrap_or_else(|e| #near_sdk::env::panic_str(&e.to_string()));
let action = Nep178RevokeAll {
token_id: &token_id,
current_owner_id: &predecessor,
};

Nep178Controller::revoke_all(self, &action)
.unwrap_or_else(|e| #near_sdk::env::panic_str(&e.to_string()));
}

fn nft_is_approved(
Expand Down
16 changes: 12 additions & 4 deletions macros/src/standard/non_fungible_token.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use darling::{util::Flag, FromDeriveInput};
use darling::FromDeriveInput;
use proc_macro2::TokenStream;
use quote::quote;
use syn::{parse_quote, Expr, Type};
Expand All @@ -23,7 +23,9 @@ pub struct NonFungibleTokenMeta {

// NEP-178 fields
pub approval_storage_key: Option<Expr>,
pub no_approval_hooks: Flag,
pub approve_hook: Option<Type>,
pub revoke_hook: Option<Type>,
pub revoke_all_hook: Option<Type>,

// NEP-181 fields
pub enumeration_storage_key: Option<Expr>,
Expand Down Expand Up @@ -51,7 +53,9 @@ pub fn expand(meta: NonFungibleTokenMeta) -> Result<TokenStream, darling::Error>
metadata_storage_key,

approval_storage_key,
no_approval_hooks,
approve_hook,
revoke_hook,
revoke_all_hook,

enumeration_storage_key,

Expand Down Expand Up @@ -97,7 +101,11 @@ pub fn expand(meta: NonFungibleTokenMeta) -> Result<TokenStream, darling::Error>

let expand_nep178 = nep178::expand(nep178::Nep178Meta {
storage_key: approval_storage_key,
no_hooks: no_approval_hooks,
all_hooks,
approve_hook,
revoke_hook,
revoke_all_hook,

generics: generics.clone(),
ident: ident.clone(),
me: me.clone(),
Expand Down
9 changes: 4 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,17 @@ pub mod nft {
StorageBalance, StorageBalanceBounds,
},
nep171::{
self, ext_nep171, ext_nep171_receiver, ext_nep171_resolver, Nep171,
Nep171Controller, Nep171ControllerInternal, Nep171Receiver, Nep171Resolver,
Nep171Transfer, Token, TokenId,
self, action::*, ext_nep171, ext_nep171_receiver, ext_nep171_resolver, Nep171,
Nep171Controller, Nep171ControllerInternal, Nep171Receiver, Nep171Resolver, Token,
TokenId,
},
nep177::{
self, ext_nep177, ContractMetadata, Nep177, Nep177Controller,
Nep177ControllerInternal, TokenMetadata,
},
nep178::{
self, ext_nep178, ext_nep178_receiver, ApprovalId, Nep178, Nep178Controller,
Nep178ControllerInternal, Nep178Hook, Nep178Receiver, SimpleNep178Hook,
TokenApprovals,
Nep178ControllerInternal, Nep178Receiver, TokenApprovals,
},
nep181::{
self, ext_nep181, Nep181, Nep181Controller, Nep181ControllerInternal,
Expand Down
47 changes: 47 additions & 0 deletions src/standard/nep171/action.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use super::*;
use near_sdk::{
borsh::{self, BorshSerialize},
serde::Serialize,
};

/// NEP-171 mint action.
#[derive(Clone, Debug, Serialize, BorshSerialize, PartialEq, Eq)]
pub struct Nep171Mint<'a> {
/// Token IDs to mint.
pub token_ids: &'a [TokenId],
/// Account ID of the receiver.
pub receiver_id: &'a AccountId,
/// Optional memo string.
pub memo: Option<&'a str>,
}

/// NEP-171 burn action.
#[derive(Clone, Debug, Serialize, BorshSerialize, PartialEq, Eq)]
pub struct Nep171Burn<'a> {
/// Token IDs to burn.
pub token_ids: &'a [TokenId],
/// Account ID of the owner.
pub owner_id: &'a AccountId,
/// Optional memo string.
pub memo: Option<&'a str>,
}

/// Transfer metadata generic over both types of transfer (`nft_transfer` and
/// `nft_transfer_call`).
#[derive(Serialize, BorshSerialize, PartialEq, Eq, Clone, Debug, Hash)]
pub struct Nep171Transfer<'a> {
/// Why is this sender allowed to perform this transfer?
pub authorization: Nep171TransferAuthorization,
/// Sending account ID.
pub sender_id: &'a AccountId,
/// Receiving account ID.
pub receiver_id: &'a AccountId,
/// Token ID.
pub token_id: &'a TokenId,
/// Optional memo string.
pub memo: Option<&'a str>,
/// Message passed to contract located at `receiver_id` in the case of `nft_transfer_call`.
pub msg: Option<&'a str>,
/// `true` if the transfer is a revert for a `nft_transfer_call`.
pub revert: bool,
}
26 changes: 24 additions & 2 deletions src/standard/nep171/event.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,29 @@
//! Event log metadata & associated structures.

use near_sdk::AccountId;
use serde::Serialize;
use near_sdk::{serde::Serialize, AccountId};
use near_sdk_contract_tools_macros::event;

/// NEP-171 standard events.
#[event(
crate = "crate",
macros = "crate",
serde = "serde",
standard = "nep171",
version = "1.2.0"
)]
#[derive(Debug, Clone)]
pub enum Nep171Event {
/// Emitted when a token is newly minted.
NftMint(Vec<NftMintLog>),
/// Emitted when a token is transferred between two parties.
NftTransfer(Vec<NftTransferLog>),
/// Emitted when a token is burned.
NftBurn(Vec<NftBurnLog>),
/// Emitted when the metadata associated with an NFT contract is updated.
NftMetadataUpdate(Vec<NftMetadataUpdateLog>),
/// Emitted when the metadata associated with an NFT contract is updated.
ContractMetadataUpdate(Vec<NftContractMetadataUpdateLog>),
}

/// Tokens minted to a single owner.
#[derive(Serialize, Debug, Clone)]
Expand Down
Loading

0 comments on commit b4e132e

Please sign in to comment.