Skip to content

Commit

Permalink
v2.0.0 (#133)
Browse files Browse the repository at this point in the history
* basic generic upgrade function

* adding Upgrade and UpgradeHook traits

* update to stable near-sdk-rs

* broken upgrade workspaces-tests

* fix: remove migrate argument

* Added basic failure tests for upgrade

* added owner check for upgrade tests

* not owner failure test

* removing JS scripts

* feat: adds more derives to events

* cleaned up workspaces tests for upgrade

* removed unnecessary near_bindgen

* fixed macro version issue

* fix: some comments

* chore: conciseness

* fix: repo url in Cargo.toml

* fixing naming conventions

* chore: adds build task to workspaces tests

* feat: #[derive(Nep297)] allows enums

* feat: #[event] supports enums

* fix: Owner uses borsh storage keys

* fix: upgrade workspaces version to 0.6

* fix: removes generic requirement from Event trait

* chore: convert events back to enum shape with owned values

* fix: pin Rust version to 1.64; fixes #83

* Use dtolnay/rust-toolchain (#87)

* fix: use dtolnay/rust-toolchain for GH Action

* fix: rust doc warning from README.md

* Add safety invariants to owner module docs (#75)

* Add safety invariants to owner module docs

* Add usage and safety guide for owner component

* Add module docs for pause and rbac

* Add module docs for migrate and resolve comments

* Update links

* Resolve comments

* Fix cargo docs warning

* Resolve comments

* chore: minor corrections & formatting

Co-authored-by: Jacob <encody@users.noreply.github.com>

* chore: adds .DS_Store to .gitignore

* fix: better doc links in Slot

* Default storage keys enum (#90)

* feat: default storage keys enum

* fix: doc links

* Link items in docs and other improvements (#91)

* Link items and doc improvements

* Add rbac macro attr doc and resolve comments

* Upgrade macro (#84)

* adding upgrade macro

* fix linting issues

* removing generic parameters

* fixing lint issues

* feat: new upgrade macro

* fix: tests for new upgrade macro

* fix: use Box to decrease enum size

* chore: better documentation for new upgrade modules

* fix: macro documentation

* wip: transfer to mac

* chore: workspace tests for upgrade

* upgrade multisig testing

* feat: better naming for raw functions + args structs

* chore: rename "none" hook body flag to "empty"

* chore: serialized upgrade uses PostUpgrade struct

* Upgrade macros safety docs (#96)

* chore: simplify api

Co-authored-by: Jacob <encody@users.noreply.github.com>
Co-authored-by: Ishan Bhanuka <bhanuka.ishan@gmail.com>

* feat: unstable feature flag and upgrade near_sdk -> 4.1.0

* fix: Eq derive now that Base64VecU8: Eq

* fix: remove near-sdk default features usage (#98)

* fix: remove near-sdk default features usage

* commit to re-trigger CI

* explicitly increase sdk version on test to ensure it gets used internally

* chore: Cow -> String (#100)

* Makes `Rbac` iterable (#99)

* wip: how to implement iterator

* fix: unused imports

* feat: possible rbac iter implementation

* feat: iterable rbac works

* chore: finish docs & tests

* chore: upgrade Rust to 1.65

* chore: upgrade GH Actions Rust to 1.65

* feat: update version to 0.7.0

* chore: optimize has_role (#102)

* chore: update version to 0.7.1

* Fuller Iterator implementation for Rbac iterator (#105)

* feat: fuller Iterator implementation for Rbac iterator

* feat: mut and non-mut versions of with_members_of, more Iter guarantees

* Disallows Event name collisions (#108)

* feat: disallow event name collisions, tests

* chore: clippy fix

* chore: add name change notification

* chore: versions to 0.7.2

* Change package name to `near-sdk-contract-tools` (#109)

* chore: change name

* chore: change repository details

* fix: inaccurate documentation

* chore: upgrade rust, workspaces, adds approval keys test

* fix: clippy: needless borrow

* feat: easier network specification in tests

* feat: create account test

* chore: create account test, base64 for Vec<u8> in native tx actions

* feat: delete account native transaction action test

* feat: stake action test

* feat: utils tests

* chore: unused imports

* fix: check additional fees sum

* chore: add rename warning to docs

* feat: finally, a decent prefix_key signature

* BREAKING: Internal Traits (#111)

* feat: internal trait for Rbac

* feat: Pause internal trait and separate default implementation

* fix: remove duplicate empty impl in Pause macro

* feat: Owner internal trait

* feat: Nep141 internal trait

* feat: ApprovalManager internal trait

* fix: grammar

* better test naming

* fix: double underscore warning (#113)

* feat: adds kudelski audit final doc (#114)

* chore: mention audit in README.md

* chore: version bump to v1.0.0

* fix: exclude documents folder from publishing

* chore: version bump to v1.0.1

* fix: skip upgrade_jsonbase64 test on ghactions (#119)

* fix: warnings

* Non-Fungible Token Standards (#69)

* feat: nep171 wip

* feat: nep171 events are owned; some experiments for allowing approval extension

* feat: some ideas for implementing approval extension (wip)

* fix: crate name change

* feat: nep171 macro progress

* full nep171 implementation

* chore: simplify nft_resolve_transfer

* chore: finished nep171 macro

* chore: cleanup, tests, renaming

* chore: documentation comments

* chore: workspaces tests & multiple token ids

* feat: nep171 multiple token id transfer

* chore: more tests + small fixes

* fix: warnings

* feat: predicate api improvements

* feat: remove predicate, introduce check function

* feat: nft events version 1.2.0 update

* Nep177: NFT Metadata (#124)

* feat: nep177

* chore: more function implementation

* feat: nep177 macro

* feat: non_fungible_token macro

* feat: documentation comments

* feat: switch to using #[serde(flatten)] for token metadata

* feat: nep178

* chore: upgrade tests & organize libs

* feat: nep178 macro integration

* feat: nep178 testing

* chore: docs

* chore: more tests and examples in docs

* chore: lots of docs

* feat: switch hook state to associated type

* feat: nep181 internals done, improved hooks

* feat: nep181 macro, sanity test

* chore: qol nft module

* feat: docs

* feat: further enumeration tests

* feat: final (?) tests for enumeration

* chore: update readme to mention nep-171 and related

* Fast Account IDs (#123)

* feat: fast account ID

* fix: cleanup, extract to fn, switch to Rc

* Escrow (#121)

* feat: escrowable capabilities

* feat: add getter for locked state

* docs(escrow): add some documentation

* test(escrow): add integration test for macro

* test(escrow): add workspace test for macro

* test(escrow): add integration test for escrow macro

* fix: some clippy lints, also optional macro props

* feat(escrow): optionally implement events
allows types that implement `serde::Serialize` to emit events

---------

Co-authored-by: Jacob Lindahl <encody@users.noreply.github.com>

* chore: more tests, more const in fast account id

* chore: cleanup md

* feat: nep-178 hooks improved

* v1.1.0

* fix: gh actions tests should work again

* BREAKING: Fungible Token Improvements (better hooks + dynamic metadata) (#127)

* feat: better hooks for nep141

* chore: move resolve code to macro

* chore: use Result instead of panicking in nep141 functions

* chore: update nep148 to use dynamic metadata

* feat: extension hooks

* chore: upgrade to near-workspaces@0.8.0

* chore: use pretty_assertions and fix gas issue

* chore: clean tests

* fix: update ghactions rust version to 1.72

---------

Co-authored-by: Jacob Lindahl <encody@noreply.users.github.com>

* NEP-145: Storage Management (#126)

* storage management wip

* more internal methods

* wip: macro impl

* feat: finish + basic impl nep145

* chore: sanity test and docs

* fix: change method names + initial test skeleton

* fix: only resolved half the merge lmao

* chore: storage management tests

* chore: run out of storage test

* BREAKING: Refactor Fungible Token (#128)

* feat: better hooks for nep141

* chore: move resolve code to macro

* chore: use Result instead of panicking in nep141 functions

* chore: update nep148 to use dynamic metadata

* feat: extension hooks

* chore: upgrade to near-workspaces@0.8.0

* chore: use pretty_assertions and fix gas issue

* chore: clean tests

* fix: update ghactions rust version to 1.72

* feat: nep145 convenience method for storage accounting

* fix: error message typo

* feat: new hooks

* feat: removes State associated type variable

* fix: readme sample

* feat: adds all_hooks + PausableHook

* feat: storage force unregister hook

* feat: FungibleToken derive macro includes NEP-145

* chore: fmt + docs

* chore: split out hooks to separate modules

---------

Co-authored-by: Jacob Lindahl <encody@noreply.users.github.com>

* chore: NEARFoundation -> near repo update (#130)

* BREAKING: Upgrade all components to new hooks API (#129)

* feat: upgrade nep-171 to new hooks

* feat: "our most powerful hooks api yet"

* chore: 178 hooks and some reorg

* chore: move 178 actions to own module

* chore: nep178 extract error to separate module

* chore: nep141 transfers don't require owned values

* Normalize & update dependencies (#131)

* fix: remove external serde* deps; use near_sdk-provided serde* instead

* chore: use workspace dependencies for everything

* chore: upgrade strum deps

* chore: loosen version requirements

* chore: remove unused dependencies

* feat: nextest

* chore: use nextest in GH actions

* fix: gh actions syntax

* feat: use caching in ghaction

* Integrate NEP-145 with token standards (#132)

* feat: nep145 full integration with nep141

* feat: some renames; full nep145<>nep171 integration

* fmt

* fix: failing test & conciseness

* chore: better readme

* v2.0.0

---------

Co-authored-by: nearken <ken.miyachi@near.foundation>
Co-authored-by: nearken <108417131+nearken@users.noreply.github.com>
Co-authored-by: Ishan Bhanuka <bhanuka.ishan@gmail.com>
Co-authored-by: Austin Abell <austinabell8@gmail.com>
Co-authored-by: Don <37594653+dndll@users.noreply.github.com>
Co-authored-by: Jacob <encody@noreply.users.github.com>
  • Loading branch information
7 people committed Oct 30, 2023
1 parent 6759e8e commit 6ad62ca
Show file tree
Hide file tree
Showing 79 changed files with 4,036 additions and 2,513 deletions.
35 changes: 23 additions & 12 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
with:
toolchain: 1.69
toolchain: 1.72
components: rustfmt
- name: Check formatting
run: >
Expand All @@ -27,34 +27,45 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
with:
toolchain: 1.69
toolchain: 1.72
components: clippy
- name: Run linter
run: cargo clippy -- -D warnings
test:
runs-on: ubuntu-latest
env:
CARGO_TERM_COLOR: always

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
with:
toolchain: 1.69
toolchain: 1.72
- uses: taiki-e/install-action@v2
with:
tool: nextest
- uses: Swatinem/rust-cache@v2
- name: Run unit and integration tests
run: cargo test --workspace --exclude workspaces-tests
run: cargo nextest run --workspace --exclude workspaces-tests
- name: Run doctests
run: cargo test --doc
workspaces-test:
runs-on: ubuntu-latest
env:
CARGO_TERM_COLOR: always

steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@master
with:
toolchain: 1.69
toolchain: 1.72
targets: wasm32-unknown-unknown
- uses: taiki-e/install-action@v2
with:
tool: cargo-make,nextest
- uses: Swatinem/rust-cache@v2
- name: Run workspaces tests
run: >
cd workspaces-tests;
cargo install cargo-make;
cargo make test;
run: cd workspaces-tests && cargo make nextest
52 changes: 39 additions & 13 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,29 +1,50 @@
[package]
authors = ["Jacob Lindahl <jacob.lindahl@near.org>"]
authors.workspace = true
categories = ["wasm", "cryptography::cryptocurrencies"]
description = """
Helpful functions and macros for developing smart contracts on NEAR Protocol.
"""
documentation = "https://docs.rs/near-sdk-contract-tools"
edition = "2021"
edition.workspace = true
exclude = ["documents/"]
license = "GPL-3.0"
license.workspace = true
name = "near-sdk-contract-tools"
repository = "https://github.com/NEARFoundation/near-sdk-contract-tools"
version = "1.1.0"
repository.workspace = true
version.workspace = true

[workspace]
members = [".", "macros", "workspaces-tests", "workspaces-tests-utils"]

[workspace.package]
authors = ["Jacob Lindahl <jacob.lindahl@near.org>"]
edition = "2021"
license = "GPL-3.0"
repository = "https://github.com/near/near-sdk-contract-tools"
version = "2.0.0"

[workspace.dependencies]
# normal dependencies
near-sdk = { version = "4.1.1", default-features = false }
near-sdk-contract-tools-macros = { version = "=1.1.0", path = "./macros" }
serde = "1.0.144"
serde_json = "1.0.85"
thiserror = "1.0.35"
near-sdk-contract-tools-macros = { version = "=2.0.0", path = "./macros" }
thiserror = "1"

darling = "0.20"
heck = "0.4"
proc-macro2 = "1"
quote = "1.0"
strum = "0.25"
strum_macros = "0.25"
syn = "2.0"

# dev-dependencies
near-crypto = "0.15"
near-workspaces = "0.8"
pretty_assertions = "1"
tokio = "1"

[dependencies]
near-sdk.workspace = true
near-sdk-contract-tools-macros.workspace = true
serde.workspace = true
serde_json.workspace = true
thiserror.workspace = true

[dev-dependencies]
Expand All @@ -39,5 +60,10 @@ unstable = ["near-sdk/unstable"]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[workspace]
members = [".", "macros", "workspaces-tests", "workspaces-tests-utils"]
[profile.release]
codegen-units = 1
debug = false
lto = true
opt-level = "z"
overflow-checks = true
panic = "abort"
155 changes: 116 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,87 @@
# near-sdk-contract-tools

> Helpful functions and macros for developing smart contracts on NEAR Protocol.
## NFT

```diff
use near_sdk::{
borsh::{self, BorshDeserialize, BorshSerialize},
near_bindgen, PanicOnDefault,
};
+ use near_sdk_contract_tools::nft::*;

#[derive(BorshSerialize, BorshDeserialize, PanicOnDefault)]
+ #[derive(NonFungibleToken)]
#[near_bindgen]
pub struct MyNftContract {}

#[near_bindgen]
impl MyNftContract {
#[init]
pub fn new() -> Self {
let mut contract = Self {};

+ contract.set_contract_metadata(ContractMetadata::new(
+ "My NFT".to_string(),
+ "MNFT".to_string(),
+ None,
+ ));

contract
}
}
```

## FT

```diff
use near_sdk::{
borsh::{self, BorshDeserialize, BorshSerialize},
near_bindgen, PanicOnDefault,
};
+ use near_sdk_contract_tools::ft::*;

#[derive(BorshSerialize, BorshDeserialize, PanicOnDefault)]
+ #[derive(FungibleToken)]
#[near_bindgen]
pub struct MyFtContract {}

#[near_bindgen]
impl MyFtContract {
#[init]
pub fn new() -> Self {
let mut contract = Self {};

+ contract.set_metadata(&FungibleTokenMetadata::new(
+ "My Fungible Token".into(),
+ "MYFT".into(),
+ 24,
+ ));

contract
}
}
```

## What is it?

This package is a collection of common tools and patterns in NEAR smart contract development:

- Storage fee management
- Owner pattern + derive macro
- Pause pattern + derive macro
- Role-based access control
- Storage fee management.
- Escrow pattern and derive macro.
- Owner pattern and derive macro.
- Pause pattern and derive macro.
- Role-based access control.
- Derive macros for NEP standards:
- [NEP-297](https://nomicon.io/Standards/EventsFormat) (events)
- [NEP-141](https://nomicon.io/Standards/Tokens/FungibleToken/Core) (fungible token), extension [NEP-148](https://nomicon.io/Standards/Tokens/FungibleToken/Metadata)
- [NEP-171](https://nomicon.io/Standards/NonFungibleToken/NonFungibleToken) (non-fungible token), extensions [NEP-177](https://nomicon.io/Standards/Tokens/NonFungibleToken/Metadata), [NEP-178](https://nomicon.io/Standards/Tokens/NonFungibleToken/ApprovalManagement), [NEP-181](https://nomicon.io/Standards/Tokens/NonFungibleToken/Enumeration)
- [NEP-141][nep141] (fungible token), extension [NEP-148][nep148].
- [NEP-145][nep145] (storage management), and integrations for the fungible token and non-fungible token standards.
- [NEP-171][nep171] (non-fungible token), extensions [NEP-177][nep177], [NEP-178][nep178], [NEP-181][nep181].
- [NEP-297][nep297] (events).

Not to be confused with [`near-contract-standards`](https://crates.io/crates/near-contract-standards), which contains official implementations of standardized NEPs. This crate is intended to be a complement to `near-contract-standards`.

You can think of this collection of common tools and patterns (mostly in the form of [derive macros](https://doc.rust-lang.org/reference/procedural-macros.html#derive-macros)) as a sort of [OpenZeppelin](https://docs.openzeppelin.com/contracts/4.x/) for NEAR.

**WARNING:** This is still early software, and there may be breaking changes between versions. I'll try my best to keep the docs & changelogs up-to-date. Don't hesitate to create an issue if find anything wrong.
Pro tip: Use the [contract wizard](https://near.org/contractwizard.near/widget/ContractWizardUI) to generate starter code for your next project.

## Installation

Expand Down Expand Up @@ -96,30 +160,38 @@ e.emit();

### Fungible Token

To create a contract that is compatible with the NEP-141 and NEP-148 standards, that emits standard-compliant (NEP-141, NEP-297) events.
To create a contract that is compatible with the [NEP-141][nep141], [NEP-145][nep145], and [NEP-148][nep148] standards, that emits standard-compliant ([NEP-297][nep297]) events.

```rust
use near_sdk_contract_tools::FungibleToken;
use near_sdk_contract_tools::ft::*;
use near_sdk::near_bindgen;

#[derive(FungibleToken)]
#[fungible_token(
name = "My Fungible Token",
symbol = "MYFT",
decimals = 18,
no_hooks
)]
#[near_bindgen]
struct FungibleToken {
// ...
struct MyFt {}

#[near_bindgen]
impl MyFt {
#[init]
pub fn new() -> Self {
let mut contract = Self {};

contract.set_metadata(&FungibleTokenMetadata::new(
"My Fungible Token".to_string(),
"MYFT".to_string(),
24,
));

contract
}
}
```

Standalone macros for each individual standard also exist.

### Non-fungible Token

Use the `NonFungibleToken` derive macro to implement NEP-171, NEP-177, NEP-178, and NEP-181, with NEP-297 events.
Use the `NonFungibleToken` derive macro to implement [NEP-145][nep145], [NEP-171][nep171], [NEP-177][nep177], [NEP-178][nep178], and [NEP-181][nep181], with [NEP-297][nep297] events.

```rust
use near_sdk::{
Expand All @@ -130,7 +202,6 @@ use near_sdk::{
use near_sdk_contract_tools::nft::*;

#[derive(BorshSerialize, BorshDeserialize, PanicOnDefault, NonFungibleToken)]
#[non_fungible_token(no_core_hooks, no_approval_hooks)]
#[near_bindgen]
pub struct MyNft {}
```
Expand All @@ -141,26 +212,22 @@ One may wish to combine the features of multiple macros in one contract. All of

```rust
use near_sdk_contract_tools::{
pause::Pause,
standard::nep141::{Nep141Hook, Nep141Transfer},
FungibleToken, Pause,
ft::*,
pause::{*, hooks::PausableHook},
Pause,
};
use near_sdk::{
borsh::{self, BorshSerialize, BorshDeserialize},
PanicOnDefault,
near_bindgen,
};
use near_sdk::near_bindgen;

#[derive(FungibleToken, Pause)]
#[fungible_token(name = "Pausable Fungible Token", symbol = "PFT", decimals = 18)]
#[derive(BorshSerialize, BorshDeserialize, PanicOnDefault, FungibleToken, Pause)]
#[fungible_token(all_hooks = "PausableHook")]
#[near_bindgen]
struct Contract {}

impl Nep141Hook for Contract {
fn before_transfer(&mut self, _transfer: &Nep141Transfer) {
Contract::require_unpaused();
}
}
```

Note: Hooks can be disabled using `#[nep141(no_hooks)]` or `#[fungible_token(no_hooks)]`.

### Custom Crates

If you are a library developer, have modified a crate that one of the `near-sdk-contract-tools` macros uses (like `serde` or `near-sdk`), or are otherwise using a crate under a different name, you can specify crate names in macros like so:
Expand Down Expand Up @@ -221,20 +288,21 @@ Run `git config core.hooksPath hooks/` to set up commit hooks.
Install `cargo-make` if it is not installed already:

```text
cargo install cargo-make
cargo install cargo-make cargo-nextest
```

Run tests:

```text
cargo test
cargo nextest run
cargo test --doc
cd workspaces-tests
cargo make test
cargo make nextest
```

## Audit

This library has been [audited](./documents/NEAR%20Contract%20Tools%20-%20Final%20-%2005.05.2023.pdf) by [Kudelski Security](https://www.kudelskisecurity.com/).
Version 1.0.0 of this library has been [audited](./documents/NEAR%20Contract%20Tools%20-%20Final%20-%2005.05.2023.pdf) by [Kudelski Security](https://www.kudelskisecurity.com/). (May 2023)

## Authors

Expand All @@ -243,3 +311,12 @@ This library has been [audited](./documents/NEAR%20Contract%20Tools%20-%20Final%
---

(Formerly known as [`near-contract-tools`](https://crates.io/crates/near-contract-tools).)

[nep145]: https://nomicon.io/Standards/StorageManagement
[nep141]: https://nomicon.io/Standards/Tokens/FungibleToken/Core
[nep148]: https://nomicon.io/Standards/Tokens/FungibleToken/Metadata
[nep171]: https://nomicon.io/Standards/NonFungibleToken/NonFungibleToken
[nep177]: https://nomicon.io/Standards/Tokens/NonFungibleToken/Metadata
[nep178]: https://nomicon.io/Standards/Tokens/NonFungibleToken/ApprovalManagement
[nep181]: https://nomicon.io/Standards/Tokens/NonFungibleToken/Enumeration
[nep297]: https://nomicon.io/Standards/EventsFormat
Loading

0 comments on commit 6ad62ca

Please sign in to comment.