Skip to content

Commit

Permalink
code refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
xlassix committed Nov 13, 2024
1 parent 0f476ef commit 2c689d3
Show file tree
Hide file tree
Showing 40 changed files with 9,357 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/contract/nft/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
package-lock.json linguist-generated=true -diff
yarn.lock linguist-generated=true -diff
16 changes: 16 additions & 0 deletions src/contract/nft/.github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: 2
updates:
- package-ecosystem: npm
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
- package-ecosystem: cargo
directory: "/contracts/rust"
schedule:
interval: daily
open-pull-requests-limit: 10
ignore:
- dependency-name: near-sdk
versions:
- 3.0.1
73 changes: 73 additions & 0 deletions src/contract/nft/.github/scripts/readme-quick-deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/bin/bash
echo ==== Quick Deploy ====
TEXT=$(printf 'y\n' | near dev-deploy --wasmFile res/non_fungible_token.wasm)
if [[ ! "$TEXT" =~ .*"Done deploying to".* ]]; then
echo -e "\033[0;31m FAIL \033[0m"
exit 1
else
echo -e "\033[0;32m SUCCESS \033[0m"
fi

echo ==== Set dev account env variable ====
source neardev/dev-account.env
TEXT=$(echo $CONTRACT_NAME)
if [[ ! "$TEXT" =~ .*"dev-".* ]]; then
echo -e "\033[0;31m FAIL \033[0m"
exit 1
else
echo -e "\033[0;32m SUCCESS \033[0m"
fi

echo ==== Initialize contract using the new method ====
TEXT=$(near call $CONTRACT_NAME new_default_meta '{"owner_id": "'$CONTRACT_NAME'"}' --accountId $CONTRACT_NAME)
if [[ ! "$TEXT" =~ .*"To see the transaction in the transaction explorer".* ]]; then
echo -e "\033[0;31m FAIL \033[0m"
exit 1
else
echo -e "\033[0;32m SUCCESS \033[0m"
fi

echo ==== View contract metadata ====
TEXT=$(near view $CONTRACT_NAME nft_metadata)
if [[ ! "$TEXT" =~ .*"Example NEAR non-fungible token".* ]]; then
echo -e "\033[0;31m FAIL \033[0m"
exit 1
else
echo -e "\033[0;32m SUCCESS \033[0m"
fi

echo ==== Mint NFT ====
TEXT=$(near call $CONTRACT_NAME nft_mint '{"token_id": "0", "receiver_id": "'$CONTRACT_NAME'", "token_metadata": { "title": "Olympus Mons", "description": "Tallest mountain in charted solar system", "media": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Olympus_Mons_alt.jpg/1024px-Olympus_Mons_alt.jpg", "copies": 1}}' --accountId $CONTRACT_NAME --deposit 0.1)
if [[ ! "$TEXT" =~ .*"To see the transaction in the transaction explorer, please open this url in your browser".* ]]; then
echo -e "\033[0;31m FAIL \033[0m"
exit 1
else
echo -e "\033[0;32m SUCCESS \033[0m"
fi

echo ==== Create Sub Account ====
TEXT=$(near create-account alice.$CONTRACT_NAME --masterAccount $CONTRACT_NAME --initialBalance 10)
if [[ ! "$TEXT" =~ .*"Account alice.$CONTRACT_NAME for network".* ]]; then
echo -e "\033[0;31m FAIL \033[0m"
exit 1
else
echo -e "\033[0;32m SUCCESS \033[0m"
fi

echo ==== Check Sub Account for Tokens ====
TEXT=$(near view $CONTRACT_NAME nft_tokens_for_owner '{"account_id": "'alice.$CONTRACT_NAME'"}')
if [[ ! "$TEXT" =~ .*"[]".* ]]; then
echo -e "\033[0;31m FAIL \033[0m"
exit 1
else
echo -e "\033[0;32m SUCCESS \033[0m"
fi

echo ==== Transfer NFT ====
TEXT=$(near call $CONTRACT_NAME nft_transfer '{"token_id": "0", "receiver_id": "alice.'$CONTRACT_NAME'", "memo": "transfer ownership"}' --accountId $CONTRACT_NAME --depositYocto 1)
if [[ ! "$TEXT" =~ .*"To see the transaction in the transaction explorer, please open this url in your browser".* ]]; then
echo -e "\033[0;31m FAIL \033[0m"
exit 1
else
echo -e "\033[0;32m SUCCESS \033[0m"
fi
27 changes: 27 additions & 0 deletions src/contract/nft/.github/workflows/readme-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Readme CI
on:
repository_dispatch:
types: [tests-report]
push:
jobs:
readme-ci:
strategy:
matrix:
platform: [ubuntu-latest] # mac-os lags out
runs-on: ${{ matrix.platform }}
steps:
- name: Checkout branch
uses: actions/checkout@v2
- name: Install Node
uses: actions/setup-node@v2
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: wasm32-unknown-unknown
- name: Install NEAR CLI
run: npm install near-cli -g
- name: Building this contract
run: bash ./scripts/build.sh
- name: Run Readme Quick Deploy Commands
run: bash .github/scripts/readme-quick-deploy.sh
33 changes: 33 additions & 0 deletions src/contract/nft/.github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Tests
on:
repository_dispatch:
types: [tests-report]
push:
jobs:
tests:
strategy:
matrix:
platform: [ubuntu-latest] # mac-os currently in progress
runs-on: ${{ matrix.platform }}
steps:
- name: Checkout branch
uses: actions/checkout@v2
- name: Install Node
uses: actions/setup-node@v3
with:
node-version: 16
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: wasm32-unknown-unknown
- name: Build wasm files
run: source scripts/flags.sh && rustup target add wasm32-unknown-unknown && cargo build --all --target wasm32-unknown-unknown --release && cp target/wasm32-unknown-unknown/release/*.wasm ./res/
- name: Run unit tests
env:
IS_GITHUB_ACTION: true
run: cd nft && cargo test -- --nocapture --color=always
- name: Run Rust integration tests
run: cd integration-tests/rs && cargo run --example integration-tests
- name: Run TypeScript integration tests
run: cd integration-tests/ts && npm i && npm run test
33 changes: 33 additions & 0 deletions src/contract/nft/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# Developer note: near.gitignore will be renamed to .gitignore upon project creation
# dependencies
package-lock.json
**/node_modules
/.pnp
.pnp.js
**/out
*.lock

#keys
**/neardev

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
.testnet

npm-debug.log*
yarn-debug.log*
yarn-error.log*

**/target
*.wasm
19 changes: 19 additions & 0 deletions src/contract/nft/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[profile.release]
codegen-units = 1
# Tell `rustc` to optimize for small code size.
opt-level = "z"
lto = true
debug = false
panic = "abort"
overflow-checks = true

[workspace]
# remember to include a member for each contract
members = [
"nft"
]

# This can be removed when near-sdk is updated
# Unfortuantely, this crate was yanked by the author and this is needed
[patch.crates-io]
parity-secp256k1 = { git = 'https://github.com/paritytech/rust-secp256k1.git' }
159 changes: 159 additions & 0 deletions src/contract/nft/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
Non-fungible Token (NFT)
===================

>**Note**: If you'd like to learn how to create an NFT contract from scratch that explores every aspect of the [NEP-171](https://github.com/near/NEPs/blob/master/neps/nep-0171.md) standard including an NFT marketplace, check out the NFT [Zero to Hero Tutorial](https://docs.near.org/tutorials/nfts/introduction).
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/near-examples/NFT)

This repository includes an example implementation of a [non-fungible token] contract which uses [near-contract-standards] and workspaces-js and -rs tests.

[non-fungible token]: https://nomicon.io/Standards/NonFungibleToken/README.html
[near-contract-standards]: https://github.com/near/near-sdk-rs/tree/master/near-contract-standards
[simulation]: https://github.com/near/near-sdk-rs/tree/master/near-sdk-sim

---

Prerequisites
=============

If you're using Gitpod, you can skip this step.

* Make sure Rust is installed per the prerequisites in [`near-sdk-rs`](https://github.com/near/near-sdk-rs).
* Make sure [near-cli](https://github.com/near/near-cli) is installed.

Explore this contract
=====================

The source for this contract is in `nft/src/lib.rs`. It provides methods to manage access to tokens, transfer tokens, check access, and get token owner. Note, some further exploration inside the rust macros is needed to see how the `NonFungibleToken` contract is implemented.

Building this contract
======================
Run the following, and we'll build our rust project up via cargo. This will generate our WASM binaries into our `res/` directory. This is the smart contract we'll be deploying onto the NEAR blockchain later.
```bash
./scripts/build.sh
```

Testing this contract
=====================
We have some tests that you can run. For example, the following will run our simple tests to verify that our contract code is working.

*Unit Tests*
```bash
cd nft
cargo test -- --nocapture
```

*Integration Tests*
*Rust*
```bash
cd integration-tests/rs
cargo run --example integration-tests
```

*TypeScript*
```bash
cd integration-tests/ts
yarn && yarn test
```

Using this contract
===================

### Quickest deploy

You can build and deploy this smart contract to a development account. [Dev Accounts](https://docs.near.org/concepts/basics/account#dev-accounts) are auto-generated accounts to assist in developing and testing smart contracts. Please see the [Standard deploy](#standard-deploy) section for creating a more personalized account to deploy to.

```bash
near dev-deploy --wasmFile res/non_fungible_token.wasm
```

Behind the scenes, this is creating an account and deploying a contract to it. On the console, notice a message like:

>Done deploying to dev-1234567890123
In this instance, the account is `dev-1234567890123`. A file has been created containing a key pair to
the account, located at `neardev/dev-account`. To make the next few steps easier, we're going to set an
environment variable containing this development account id and use that when copy/pasting commands.
Run this command to set the environment variable:

```bash
source neardev/dev-account.env
```

You can tell if the environment variable is set correctly if your command line prints the account name after this command:
```bash
echo $CONTRACT_NAME
```

The next command will initialize the contract using the `new` method:

```bash
near call $CONTRACT_NAME new_default_meta '{"owner_id": "'$CONTRACT_NAME'"}' --accountId $CONTRACT_NAME
```

submit mint request
```bash
near call $CONTRACT_NAME mint_tweet_request '{"image_url": "'$IMAGE_URL'","tweet_id": '$TWEET_ID', "notify":""}' --accountId $CONTRACT_NAME --depositYocto 5870000000000000000000
```

To view the NFT metadata:

```bash
near view $CONTRACT_NAME nft_metadata
```

### Standard deploy

This smart contract will get deployed to your NEAR account. For this example, please create a new NEAR account. Because NEAR allows the ability to upgrade contracts on the same account, initialization functions must be cleared. If you'd like to run this example on a NEAR account that has had prior contracts deployed, please use the `near-cli` command `near delete`, and then recreate it in Wallet. To create (or recreate) an account, please follow the directions in [Test Wallet](https://wallet.testnet.near.org) or ([NEAR Wallet](https://wallet.near.org/) if we're using `mainnet`).

In the project root, log in to your newly created account with `near-cli` by following the instructions after this command.

near login

To make this tutorial easier to copy/paste, we're going to set an environment variable for our account id. In the below command, replace `MY_ACCOUNT_NAME` with the account name we just logged in with, including the `.testnet` (or `.near` for `mainnet`):

ID=MY_ACCOUNT_NAME

We can tell if the environment variable is set correctly if our command line prints the account name after this command:

echo $ID

Now we can deploy the compiled contract in this example to your account:

near deploy --wasmFile res/non_fungible_token.wasm --accountId $ID

NFT contract should be initialized before usage. More info about the metadata at [nomicon.io](https://nomicon.io/Standards/NonFungibleToken/Metadata.html). But for now, we'll initialize with the default metadata.

near call $ID new_default_meta '{"owner_id": "'$ID'"}' --accountId $ID

We'll be able to view our metadata right after:

near view $ID nft_metadata

Then, let's mint our first token. This will create a NFT based on Olympus Mons where only one copy exists:

near call $ID nft_mint '{"token_id": "0", "receiver_id": "'$ID'", "token_metadata": { "title": "Olympus Mons", "description": "Tallest mountain in charted solar system", "media": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Olympus_Mons_alt.jpg/1024px-Olympus_Mons_alt.jpg", "copies": 1}}' --accountId $ID --deposit 0.1

Transferring our NFT
====================

Let's set up an account to transfer our freshly minted token to. This account will be a sub-account of the NEAR account we logged in with originally via `near login`.

near create-account alice.$ID --masterAccount $ID --initialBalance 10

Checking Alice's account for tokens:

near view $ID nft_tokens_for_owner '{"account_id": "'alice.$ID'"}'

Then we'll transfer over the NFT into Alice's account. Exactly 1 yoctoNEAR of deposit should be attached:

near call $ID nft_transfer '{"token_id": "0", "receiver_id": "alice.'$ID'", "memo": "transfer ownership"}' --accountId $ID --depositYocto 1

Checking Alice's account again shows us that she has the Olympus Mons token.

Notes
=====

* The maximum balance value is limited by U128 (2**128 - 1).
* JSON calls should pass U128 as a base-10 string. E.g. "100".
* This does not include escrow functionality, as ft_transfer_call provides a superior approach. An escrow system can, of course, be added as a separate contract or additional functionality within this contract.
10 changes: 10 additions & 0 deletions src/contract/nft/makeFile.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[tasks.test]
alias = "tests"

[tasks.tests]
dependencies = ["build"]
run_task = "run-tests"

[tasks.run-tests]
command = "cargo"
args = ["test", "--workspace", "--all-targets", "${@}"]
Loading

0 comments on commit 2c689d3

Please sign in to comment.