Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ near view $NFT_CONTRACT_ID nft_metadata
### Minting Token

```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": "'$MAIN_ACCOUNT'"}' --accountId $MAIN_ACCOUNT --amount 0.1
near call $NFT_CONTRACT_ID nft_mint '{"token_id": "token-1", "token_metadata": {"title": "My Non Fungible Team Token", "description": "The Team Most Certainly Goes :)", "media": "https://bafybeiftczwrtyr3k7a2k4vutd3amkwsmaqyhrdzlhvpt33dyjivufqusq.ipfs.dweb.link/goteam-gif.gif"}, "token_owner_id": "'$MAIN_ACCOUNT'"}' --accountId $MAIN_ACCOUNT --amount 0.1
```

After you've minted the token go to wallet.testnet.near.org to `your-account.testnet` and look in the collections tab and check out your new sample NFT!
Expand Down
4 changes: 2 additions & 2 deletions integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ publish = false
edition = "2021"

[dev-dependencies]
near-sdk = { version = "5.4.0", features = ["unit-testing"] }
near-workspaces = { version = "0.14.1", features = ["unstable"] }
near-sdk = { version = "5.11.0", features = ["unit-testing"] }
near-workspaces = { version = "0.18.0", features = ["unstable"] }
tokio = { version = "1.12.0", features = ["full"] }
serde_json = "1"

Expand Down
67 changes: 37 additions & 30 deletions integration-tests/src/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use near_sdk::Gas;
use near_workspaces::{
types::{AccountDetails, NearToken},
Account, Contract,
};
use serde_json::json;
use near_workspaces::{types::{NearToken, AccountDetails}, Account, Contract};

pub const DEFAULT_DEPOSIT: u128 = 10000000000000000000000;
pub const ONE_YOCTO_NEAR: NearToken = NearToken::from_yoctonear(1);
Expand All @@ -8,23 +12,24 @@ pub async fn mint_nft(
user: &Account,
nft_contract: &Contract,
token_id: &str,
) -> Result<(), Box<dyn std::error::Error>> {
) -> Result<(), Box<dyn std::error::Error>> {
let request_payload = json!({
"token_id": token_id,
"receiver_id": user.id(),
"metadata": {
"token_owner_id": user.id(),
"token_metadata": {
"title": "Grumpy Cat",
"description": "Not amused.",
"media": "https://www.adamsdrafting.com/wp-content/uploads/2018/06/More-Grumpy-Cat.jpg"
},
});

let _ = user.call(nft_contract.id(), "nft_mint")
let _ = user
.call(nft_contract.id(), "nft_mint")
.args_json(request_payload)
.deposit(NearToken::from_yoctonear(DEFAULT_DEPOSIT))
.transact()
.await;

Ok(())
}

Expand All @@ -34,13 +39,14 @@ pub async fn approve_nft(
nft_contract: &Contract,
token_id: &str,
) -> Result<(), Box<dyn std::error::Error>> {
let request_payload = json!({
let request_payload = json!({
"token_id": token_id,
"account_id": market_contract.id(),
"msg": serde_json::Value::Null,
});

let _ = user.call(nft_contract.id(), "nft_approve")
let _ = user
.call(nft_contract.id(), "nft_approve")
.args_json(request_payload)
.deposit(NearToken::from_yoctonear(DEFAULT_DEPOSIT))
.transact()
Expand All @@ -55,8 +61,9 @@ pub async fn pay_for_storage(
amount: NearToken,
) -> Result<(), Box<dyn std::error::Error>> {
let request_payload = json!({});

let _ = user.call(market_contract.id(), "storage_deposit")

let _ = user
.call(market_contract.id(), "storage_deposit")
.args_json(request_payload)
.deposit(amount)
.transact()
Expand All @@ -70,7 +77,7 @@ pub async fn place_nft_for_sale(
market_contract: &Contract,
nft_contract: &Contract,
token_id: &str,
approval_id: u32,
approval_id: u64,
price: &NearToken,
) -> Result<(), Box<dyn std::error::Error>> {
let request_payload = json!({
Expand All @@ -79,20 +86,21 @@ pub async fn place_nft_for_sale(
"approval_id": approval_id,
"sale_conditions": NearToken::as_yoctonear(price).to_string(),
});
let _ = user.call(market_contract.id(), "list_nft_for_sale")
let _ = user
.call(market_contract.id(), "list_nft_for_sale")
.args_json(request_payload)
.max_gas()
.deposit(NearToken::from_yoctonear(DEFAULT_DEPOSIT))
.gas(Gas::from_tgas(100))
.transact()
.await;

Ok(())
}

pub async fn get_user_balance(
user: &Account,
) -> NearToken {
let details: AccountDetails = user.view_account().await.expect("Account has to have some balance");
pub async fn get_user_balance(user: &Account) -> NearToken {
let details: AccountDetails = user
.view_account()
.await
.expect("Account has to have some balance");
details.balance
}

Expand All @@ -101,14 +109,15 @@ pub async fn purchase_listed_nft(
market_contract: &Contract,
nft_contract: &Contract,
token_id: &str,
offer_price: NearToken
offer_price: NearToken,
) -> Result<(), Box<dyn std::error::Error>> {
let request_payload = json!({
let request_payload = json!({
"token_id": token_id,
"nft_contract_id": nft_contract.id(),
});

let _ = bidder.call(market_contract.id(), "offer")
let _ = bidder
.call(market_contract.id(), "offer")
.args_json(request_payload)
.max_gas()
.deposit(offer_price)
Expand All @@ -124,19 +133,20 @@ pub async fn transfer_nft(
nft_contract: &Contract,
token_id: &str,
) -> Result<(), Box<dyn std::error::Error>> {
let request_payload = json!({
let request_payload = json!({
"token_id": token_id,
"receiver_id": receiver.id(),
"approval_id": 1 as u64,
});

let _ = sender.call(nft_contract.id(), "nft_transfer")
let _ = sender
.call(nft_contract.id(), "nft_transfer")
.args_json(request_payload)
.max_gas()
.deposit(ONE_YOCTO_NEAR)
.transact()
.await;

Ok(())
}

Expand All @@ -155,10 +165,7 @@ pub async fn get_nft_token_info(
Ok(token_info)
}

pub fn round_to_near_dp(
amount: u128,
sf: u128,
) -> String {
let near_amount = amount as f64 / 1_000_000_000_000_000_000_000_000.0; // yocto in 1 NEAR
pub fn round_to_near_dp(amount: u128, sf: u128) -> String {
let near_amount = amount as f64 / 1_000_000_000_000_000_000_000_000.0; // yocto in 1 NEAR
return format!("{:.1$}", near_amount, sf as usize);
}
}
21 changes: 8 additions & 13 deletions integration-tests/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ async fn test_nft_mint_call(
) -> Result<(), Box<dyn std::error::Error>> {
let request_payload = json!({
"token_id": "1",
"receiver_id": user.id(),
"metadata": {
"token_owner_id": user.id(),
"token_metadata": {
"title": "LEEROYYYMMMJENKINSSS",
"description": "Alright time's up, let's do this.",
"media": "https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse3.mm.bing.net%2Fth%3Fid%3DOIP.Fhp4lHufCdTzTeGCAblOdgHaF7%26pid%3DApi&f=1"
Expand Down Expand Up @@ -182,15 +182,10 @@ async fn test_sell_nft_listed_on_marketplace(
) -> Result<(), Box<dyn std::error::Error>> {
let token_id = "4";
let approval_id = 0;
let sale_price: NearToken = NearToken::from_yoctonear(10000000000000000000000000);
let sale_price: NearToken = NearToken::from_near(1);

helpers::mint_nft(seller, nft_contract, token_id).await?;
helpers::pay_for_storage(
seller,
market_contract,
NearToken::from_yoctonear(1000000000000000000000000),
)
.await?;
helpers::pay_for_storage(seller, market_contract, NearToken::from_millinear(10)).await?;
helpers::approve_nft(market_contract, seller, nft_contract, token_id).await?;
helpers::place_nft_for_sale(
seller,
Expand Down Expand Up @@ -392,8 +387,8 @@ async fn test_reselling_and_royalties(
// mint with royalties
let request_payload = json!({
"token_id": token_id,
"receiver_id": user.id(),
"metadata": {
"token_owner_id": user.id(),
"token_metadata": {
"title": "Grumpy Cat",
"description": "Not amused.",
"media": "https://www.adamsdrafting.com/wp-content/uploads/2018/06/More-Grumpy-Cat.jpg"
Expand Down Expand Up @@ -555,8 +550,8 @@ async fn test_royalties_exceeding_100_percents(
// mint with royalties
let request_payload = json!({
"token_id": token_id,
"receiver_id": user.id(),
"metadata": {
"token_owner_id": user.id(),
"token_metadata": {
"title": "Grumpy Cat",
"description": "Not amused.",
"media": "https://www.adamsdrafting.com/wp-content/uploads/2018/06/More-Grumpy-Cat.jpg"
Expand Down
6 changes: 3 additions & 3 deletions market-contract/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ edition = "2021"
crate-type = ["cdylib", "rlib"]

[dependencies]
near-sdk = { version = "5.4.0", features = ["legacy"] }
near-sdk = { version = "5.11.0", features = ["legacy"] }

[dev-dependencies]
near-sdk = { version = "5.4.0", features = ["unit-testing"] }
near-workspaces = { version = "0.14.1", features = ["unstable"] }
near-sdk = { version = "5.11.0", features = ["unit-testing"] }
near-workspaces = { version = "0.18.0", features = ["unstable"] }
tokio = { version = "1.12.0", features = ["full"] }
serde_json = "1"

Expand Down
19 changes: 7 additions & 12 deletions market-contract/src/external.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,17 @@ trait ExtContract {
fn nft_transfer_payout(
&mut self,
receiver_id: AccountId, //purchaser (person to transfer the NFT to)
token_id: TokenId, //token ID to transfer
approval_id: u32, //market contract's approval ID in order to transfer the token on behalf of the owner
memo: String, //memo (to include some context)
token_id: TokenId, //token ID to transfer
approval_id: u64, //market contract's approval ID in order to transfer the token on behalf of the owner
memo: String, //memo (to include some context)
/*
the price that the token was purchased for. This will be used in conjunction with the royalty percentages
for the token in order to determine how much money should go to which account.
for the token in order to determine how much money should go to which account.
*/
balance: NearToken,
//the maximum amount of accounts the market can payout at once (this is limited by GAS)
max_len_payout: u32,
max_len_payout: u32,
);
fn nft_token(&self, token_id: TokenId);
fn nft_is_approved(
&self,
token_id: TokenId,
approved_account_id: AccountId,
approval_id: u32,
);
}
fn nft_is_approved(&self, token_id: TokenId, approved_account_id: AccountId, approval_id: u64);
}
6 changes: 3 additions & 3 deletions market-contract/src/nft_callbacks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ use crate::*;
/*
trait that will be used as the callback from the NFT contract. When nft_approve is
called, it will fire a cross contract call to this marketplace and this is the function
that is invoked.
that is invoked.
*/
trait NonFungibleTokenApprovalsReceiver {
fn nft_on_approve(
&mut self,
token_id: TokenId,
owner_id: AccountId,
approval_id: u32,
approval_id: u64,
msg: String,
);
}
Expand All @@ -24,7 +24,7 @@ impl NonFungibleTokenApprovalsReceiver for Contract {
&mut self,
token_id: TokenId,
owner_id: AccountId,
approval_id: u32,
approval_id: u64,
msg: String,
) {
/*
Expand Down
Loading