diff --git a/docs/3.tutorials/nfts/5-approval.md b/docs/3.tutorials/nfts/5-approval.md index 09b2b53dfb2..ab7dc956f3d 100644 --- a/docs/3.tutorials/nfts/5-approval.md +++ b/docs/3.tutorials/nfts/5-approval.md @@ -137,21 +137,9 @@ After the assertion comes back with no problems, you get the token object and ma You then calculate how much storage is being used by adding that new account to the map and increment the tokens `next_approval_id` by 1. After inserting the token object back into the `tokens_by_id` map, you refund any excess storage. -You'll notice that the function contains an optional `msg` parameter. This message is actually the foundation of all NFT marketplaces on NEAR. +You'll notice that the function contains an optional `msg` parameter. This message can be used by NFT marketplaces. If a message was provided into the function, you're going to perform a cross contract call to the account being given access. This cross contract call will invoke the `nft_on_approve` function which will parse the message and act accordingly. -#### Marketplace Integrations {#marketplace-integrations} - -If a message was provided into the function, you're going to perform a cross contract call to the account being given access. This cross contract call will invoke the `nft_on_approve` function which will parse the message and act accordingly. Let's consider a general use case. - -We have a marketplace that expects it's sale conditions to be passed in through the message field. Benji approves the marketplace with the `nft_approve` function and passes in a stringified JSON to the message which will outline sale conditions. These sale conditions could look something like the following: - -```json -sale_conditions: { - price: 5 -} -``` - -By leaving the message field type as just a string, this generalizes the process and allows users to input sale conditions for many different marketplaces. It is up to the person approving to pass in an appropriate message that the marketplace can properly decode and use. This is usually done through the marketplace's frontend app which would know how to construct the `msg` in a useful way. +It is up to the approving person to provide a properly encoded message that the marketplace can decode and use. This is usually done through the marketplace's frontend app which would know how to construct the `msg` in a useful way. #### Internal functions diff --git a/docs/3.tutorials/nfts/8-marketplace.md b/docs/3.tutorials/nfts/8-marketplace.md index 84577e1623c..6f50b9a4862 100644 --- a/docs/3.tutorials/nfts/8-marketplace.md +++ b/docs/3.tutorials/nfts/8-marketplace.md @@ -98,15 +98,20 @@ With that out of the way, it's time to move onto the `nft_callbacks.rs` file whe ## nft_callbacks.rs {#nft_callbacks-rs} -This file is responsible for the logic used to put NFTs for sale. If you remember from the [marketplaces section](/tutorials/nfts/approvals#marketplace-integrations) of the approvals tutorial, when users call `nft_approve` and pass in a message, it will perform a cross-contract call to the `receiver_id`'s contract and call the method `nft_on_approve`. This `nft_callbacks.rs` file will implement that function. +This file is responsible for the internal marketplace logic, the trigger for which is approving the marketplace contract on the NFT contract. If you remember from the [marketplaces section](/tutorials/nfts/approvals#marketplace-integrations) of the approvals tutorial, when users call `nft_approve` and pass in a message, it will perform a cross-contract call to the `receiver_id`'s contract and call the method `nft_on_approve`. This `nft_callbacks.rs` file will implement that function. ### Listing logic {#listing-logic} -The first important thing to note is the `SaleArgs` struct. This is what the market contract is expecting the message that the user passes into `nft_approve` on the NFT contract to be. This outlines the sale price in yoctoNEAR for the NFT that is listed. +In order to put an NFT on sale, a user should: + +1. Approve the marketplace contract on an NFT token (by calling `nft_approve` method on the NFT contract) +2. Call the `list_nft_for_sale` method on the marketplace contract. + +The first important thing to note is the `SaleArgs` struct. This is what the market contract is expecting the message that the user passes into `list_nft_for_sale` on the marketplace contract to be. This outlines the sale price in yoctoNEAR for the NFT that is listed. -Next, we'll look at the `nft_on_approve` function which is called via a cross-contract call by the NFT contract. This will make sure that the signer has enough storage to cover adding another sale. It will then attempt to get the `SaleArgs` from the message and create the listing. +Next, we'll look at the `nft_on_approve` function, which is called via a cross-contract call by the NFT contract. We won't put any logic there, but you can if you want to execute some additional logic on the marketplace contract after approving it on the NFT contract. @@ -159,7 +164,7 @@ Using the build script, deploy the contract as you did in the previous tutorials near deploy $MARKETPLACE_CONTRACT_ID out/market.wasm ``` -### Initialization and minting +### Initialization Since this is a new contract, you'll need to initialize it. Use the following command to initialize the contract: @@ -167,6 +172,22 @@ Since this is a new contract, you'll need to initialize it. Use the following co near call $MARKETPLACE_CONTRACT_ID new '{"owner_id": "'$MARKETPLACE_CONTRACT_ID'"}' --accountId $MARKETPLACE_CONTRACT_ID ``` +### Minting and approving + +Let's mint a new NFT token and approve a marketplace contract: + +```bash +near call $NFT_CONTRACT_ID nft_mint '{"token_id": "token-1", "metadata": {"title": "My Non Fungible Team Token", "description": "The Team Most Certainly Goes :)", "media": "https://bafybeiftczwrtyr3k7a2k4vutd3amkwsmaqyhrdzlhvpt33dyjivufqusq.ipfs.dweb.link/goteam-gif.gif"}, "receiver_id": "'$NFT_CONTRACT_ID'"}' --accountId $NFT_CONTRACT_ID --amount 0.1 + +near call $NFT_CONTRACT_ID nft_approve '{"token_id": "token-1", "account_id": "'$MARKETPLACE_CONTRACT_ID'"}' --accountId $NFT_CONTRACT_ID --deposit 0.1 +``` + +### Listing NFT on sale + +```bash +near call $MARKETPLACE_CONTRACT_ID list_nft_for_sale '{"nft_contract_id": "'$NFT_CONTRACT_ID'", "token_id": "token-1", "approval_id": 0, "msg": "{\"sale_conditions\": \"1\"}"}' --accountId $NFT_CONTRACT_ID --gas 30000000000000 +``` + ### Total supply {#total-supply} To query for the total supply of NFTs listed on the marketplace, you can call the `get_supply_sales` function. An example can be seen below. @@ -180,7 +201,7 @@ near view $MARKETPLACE_CONTRACT_ID get_supply_sales To query for the total supply of NFTs listed by a specific owner on the marketplace, you can call the `get_supply_by_owner_id` function. An example can be seen below. ```bash -near view $MARKETPLACE_CONTRACT_ID get_supply_by_owner_id '{"account_id": "benji.testnet"}' +near view $MARKETPLACE_CONTRACT_ID get_supply_by_owner_id '{"account_id": "'$NFT_CONTRACT_ID'"}' ``` ### Total supply by contract {#total-supply-by-contract} @@ -188,7 +209,7 @@ near view $MARKETPLACE_CONTRACT_ID get_supply_by_owner_id '{"account_id": "benji To query for the total supply of NFTs that belong to a specific contract, you can call the `get_supply_by_nft_contract_id` function. An example can be seen below. ```bash -near view $MARKETPLACE_CONTRACT_ID get_supply_by_nft_contract_id '{"nft_contract_id": "fayyr-nft.testnet"}' +near view $MARKETPLACE_CONTRACT_ID get_supply_by_nft_contract_id '{"nft_contract_id": "'$NFT_CONTRACT_ID'"}' ``` ### Query for listing information {#query-listing-information} @@ -196,26 +217,26 @@ near view $MARKETPLACE_CONTRACT_ID get_supply_by_nft_contract_id '{"nft_contract To query for important information for a specific listing, you can call the `get_sale` function. This requires that you pass in the `nft_contract_token`. This is essentially the unique identifier for sales on the market contract as explained earlier. It consists of the NFT contract followed by a `DELIMITER` followed by the token ID. In this contract, the `DELIMITER` is simply a period: `.`. An example of this query can be seen below. ```bash -near view $MARKETPLACE_CONTRACT_ID get_sale '{"nft_contract_token": "fayyr-nft.testnet.token-42"}' +near view $MARKETPLACE_CONTRACT_ID get_sale '{"nft_contract_token": "'$NFT_CONTRACT_ID'.token-1"}' ``` In addition, you can query for paginated information about the listings for a given owner by calling the `get_sales_by_owner_id` function. ```bash -near view $MARKETPLACE_CONTRACT_ID get_sales_by_owner_id '{"account_id": "benji.testnet", "from_index": "5", "limit": 10}' +near view $MARKETPLACE_CONTRACT_ID get_sales_by_owner_id '{"account_id": "'$NFT_CONTRACT_ID'", "from_index": "0", "limit": 5}' ``` Finally, you can query for paginated information about the listings that originate from a given NFT contract by calling the `get_sales_by_nft_contract_id` function. ```bash -near view $MARKETPLACE_CONTRACT_ID get_sales_by_nft_contract_id '{"nft_contract_id": "fayyr-nft.testnet", "from_index": "5", "limit": 10}' +near view $MARKETPLACE_CONTRACT_ID get_sales_by_nft_contract_id '{"nft_contract_id": "'$NFT_CONTRACT_ID'", "from_index": "0", "limit": 5}' ``` ## Conclusion In this tutorial, you learned about the basics of a marketplace contract and how it works. You went through the [lib.rs](#lib-rs) file and learned about the [initialization function](#initialization-function) in addition to the [storage management](#storage-management-model) model. -You then went through the [nft_callbacks](#nft_callbacks-rs) file to understand how to [list NFTs](#listing-logic). In addition, you went through some important functions needed for after you've listed an NFT. This includes [removing sales](#removing-sales), [updating the price](#updating-price), and [purchasing NFTs](#purchasing-nfts). +You went through the [nft_callbacks](#nft_callbacks-rs) file and [NFTs listing process](#listing-logic). In addition, you went through some important functions needed after you've listed an NFT. This includes [removing sales](#removing-sales), [updating the price](#updating-price), and [purchasing NFTs](#purchasing-nfts). Finally, you went through the enumeration methods found in the [`sale_view`](#sale_view-rs) file. These allow you to query for important information found on the marketplace contract.