Skip to content

Commit 7840e1f

Browse files
committed
Merge branch 'master' into update-quickstart-tutorial
2 parents a6ee578 + 618a478 commit 7840e1f

File tree

9 files changed

+292
-106
lines changed

9 files changed

+292
-106
lines changed

blog/2024-06-05.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ wsl --set-default-version 2
3030
```
3131

3232
```
33-
wsl --install --d Ubuntu
33+
wsl --install -d Ubuntu
3434
```
3535

3636
**Read more on WSL:**
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
---
2+
id: sdk-contract-tools
3+
title: Create FT using Contract Tools
4+
sidebar_label: Create FT using Contract Tools
5+
description: "Learn how to create a fungible token (FT) using Contract Tools package"
6+
---
7+
8+
import {Github} from "@site/src/components/UI/Codetabs";
9+
import MovingForwardSupportSection from '@site/src/components/MovingForwardSupportSection';
10+
11+
In this tutorial, we will create a fungible token (FT) using the [NEAR SDK Contract Tools](https://github.com/near/near-sdk-contract-tools) package. This package is a collection of common tools and patterns to simplify smart contract development, including:
12+
13+
- Storage fee management
14+
- Escrow pattern and derive macro
15+
- Owner pattern and derive macro
16+
- Pause pattern and derive macro
17+
- Role-based access control
18+
- Derive macros for [NEP standards](./standard.md)
19+
- NEP-141 (fungible token), extension NEP-148
20+
- NEP-145 (storage management), and integrations for the fungible token and non-fungible token standards
21+
- NEP-171 (non-fungible token), extensions NEP-177, NEP-178, NEP-181
22+
- NEP-297 (events)
23+
24+
---
25+
26+
## Introduction
27+
28+
While one can create a fungible token (FT) contract from scratch using only the `near-sdk` and `near_contract_standards` (e.g. [FT contract](https://github.com/near-examples/FT)), a simpler approach is to use `near-sdk-contract-tools`.
29+
30+
`near-sdk-contract-tools` allows us implement the logic for minting/burning logic, access control, and other FT standards by simply deriving macros on our contract struct, as `OpenZeppelin` does for Ethereum contracts.
31+
32+
---
33+
34+
## Basic FT Methods
35+
36+
To derive basic FT methods to our contract, we need to derive `FungibleToken` macro to our contract struct:
37+
38+
<Github fname="lib.rs" language="rust"
39+
url="https://github.com/near-examples/ft-contract-tools/blob/main/src/lib.rs"
40+
start="9" end="12" />
41+
42+
This will bring all the basic FT methods defined in NEP-141 standard to our contract:
43+
- `new`
44+
- `contract_source_metadata`
45+
- `ft_balance_of`
46+
- `ft_metadata`
47+
- `ft_total_supply`
48+
- `storage_balance_bounds`
49+
- `storage_balance_of`
50+
- `ft_resolve_transfer`
51+
- `ft_transfer`
52+
- `ft_transfer_call`
53+
- `storage_deposit`
54+
- `storage_unregister`
55+
- `storage_withdraw`
56+
57+
To bring basic owner methods to our contract, we can also derive the `Owner` macro which adds the following methods:
58+
- `own_get_owner`
59+
- `own_get_proposed_owner`
60+
- `own_accept_owner`
61+
- `own_propose_owner`
62+
- `own_renounce_owner`
63+
64+
---
65+
66+
## Initialization
67+
68+
To initialize the basic FT contract with custom owner, metadata and storage bounds implement `new` method:
69+
70+
<Github fname="lib.rs" language="rust"
71+
url="https://github.com/near-examples/ft-contract-tools/blob/main/src/lib.rs"
72+
start="14" end="45" />
73+
74+
---
75+
76+
## Transfer Hook
77+
78+
If we want to customize how the transfer of tokens work (i.e. modify the `ft_transfer` method), we need to implement a hook. Hooks are a way to **wrap (inject code before and after)** component functions:
79+
80+
<Github fname="transfer_hook.rs" language="rust"
81+
url="https://github.com/near-examples/ft-contract-tools/blob/main/src/transfer_hook.rs"
82+
start="5" end="33" />
83+
84+
Then derive it to our contract struct:
85+
86+
<Github fname="lib.rs" language="rust"
87+
url="https://github.com/near-examples/ft-contract-tools/blob/main/src/lib.rs"
88+
start="9" end="12" />
89+
90+
---
91+
92+
## Minting
93+
94+
By default, the FT standards do not include a minting method. However, we can easily mint tokens for the owner by implementing a `mint` method, which only the owner can call:
95+
96+
<Github fname="mint.rs" language="rust"
97+
url="https://github.com/near-examples/ft-contract-tools/blob/main/src/mint.rs"
98+
start="5" end="33" />
99+
100+
:::tip
101+
102+
You can modify this method as you need, for example, to allow minting only when the contract is not paused (requires deriving [`Pausable`](https://github.com/near/near-sdk-contract-tools/tree/develop?tab=readme-ov-file#macro-combinations) hook), or to allow minting only to specific accounts with a certain role or from whitelist with custom limitations
103+
104+
:::
105+
106+
---
107+
108+
## Burning
109+
110+
In the same way that minting is not included in the FT standards, burning is also not included. However, we can also easily implement it.
111+
112+
To burn tokens from the owner's account, we can add a `burn` method which is also only callable by the owner:
113+
114+
<Github fname="burn.rs" language="rust"
115+
url="https://github.com/near-examples/ft-contract-tools/blob/main/src/burn.rs"
116+
start="5" end="25" />
117+
118+
---
119+
120+
## Conclusion
121+
122+
Using `near-sdk-contract-tools` is a very simple and flexible way to create FT contract with minimal boilerplate which allows us to focus on the business logic.
123+
124+
You can further extend this contract with more features like pausing, role-based access control, escrow pattern, and more by deriving corresponding macros from the package.
125+
126+
<MovingForwardSupportSection />
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
---
2+
id: nft-contract-tools
3+
title: Create NFT using Contract Tools
4+
sidebar_label: Create NFT using Contract Tools
5+
description: "Learn how to create a non-fungible token (NFT) using Contract Tools package"
6+
---
7+
8+
import {Github} from "@site/src/components/UI/Codetabs";
9+
import MovingForwardSupportSection from '@site/src/components/MovingForwardSupportSection';
10+
11+
In this tutorial, you will create a non-fungible token (NFT) using the [NEAR SDK Contract Tools](https://github.com/near/near-sdk-contract-tools) package. This package is a collection of common tools and patterns to simplify smart contract development, including:
12+
13+
- Storage fee management
14+
- Escrow pattern and derive macro
15+
- Owner pattern and derive macro
16+
- Pause pattern and derive macro
17+
- Role-based access control
18+
- Derive macros for [NEP standards](./standard.md)
19+
- [NEP-141](https://github.com/near/NEPs/blob/master/neps/nep-0141.md) (fungible token), extension [NEP-148](https://github.com/near/NEPs/blob/master/neps/nep-0148.md)
20+
- [NEP-145](https://github.com/near/NEPs/blob/master/neps/nep-0145.md) (storage management), and integrations for the fungible token and non-fungible token standards
21+
- [NEP-171](https://github.com/near/NEPs/blob/master/neps/nep-0171.md) (non-fungible token), extensions [NEP-177](https://github.com/near/NEPs/blob/master/neps/nep-0177.md), [NEP-178](https://github.com/near/NEPs/blob/master/neps/nep-0178.md), [NEP-181](https://github.com/near/NEPs/blob/master/neps/nep-0181.md)
22+
- [NEP-297](https://github.com/near/NEPs/blob/master/neps/nep-0297.md) (events)
23+
24+
---
25+
26+
## Introduction
27+
28+
While one can create a non-fungible token (NFT) contract from scratch using only the `near-sdk` and `near_contract_standards` (e.g. [NFT contract](https://github.com/near-examples/NFT)), a simpler approach is to use `near-sdk-contract-tools`.
29+
30+
`near-sdk-contract-tools` allows you to implement the minting/burning logic, access control, and other NFT standards by simply deriving macros on the contract's `struct`, as `OpenZeppelin` does for Ethereum contracts.
31+
32+
---
33+
34+
## Basic NFT Methods
35+
36+
To derive basic NFT methods to your smart contract, you need to derive the `NonFungibleToken` macro to the contract's `struct`:
37+
38+
<Github fname="lib.rs" language="rust"
39+
url="https://github.com/near-examples/nft-contract-tools/blob/main/src/lib.rs"
40+
start="9" end="12" />
41+
42+
This will bring all the basic NFT methods to the contract:
43+
- `new`
44+
- `contract_source_metadata`
45+
- `nft_is_approved`
46+
- `nft_metadata`
47+
- `nft_supply_for_owner`
48+
- `nft_token`
49+
- `nft_tokens`
50+
- `nft_tokens_for_owner`
51+
- `nft_total_supply`
52+
- `nft_approve`
53+
- `nft_resolve_transfer`
54+
- `nft_revoke`
55+
- `nft_revoke_all`
56+
- `nft_transfer`
57+
- `nft_transfer_call`
58+
- `storage_balance_bounds`
59+
- `storage_balance_of`
60+
- `storage_deposit`
61+
- `storage_unregister`
62+
- `storage_withdraw`
63+
64+
To bring basic owner methods to the contract, you also need to derive the `Owner` macro, which adds the following methods:
65+
- `own_get_owner`
66+
- `own_get_proposed_owner`
67+
- `own_accept_owner`
68+
- `own_propose_owner`
69+
- `own_renounce_owner`
70+
71+
---
72+
73+
## Initialization
74+
75+
To initialize the basic NFT contract with a custom owner, metadata, and storage bounds, implement the `new` method:
76+
77+
<Github fname="lib.rs" language="rust"
78+
url="https://github.com/near-examples/nft-contract-tools/blob/main/src/lib.rs"
79+
start="14" end="45" />
80+
81+
---
82+
83+
## Transfer Hook
84+
85+
If you want to customize how the token transfer works (i.e., modify the `nft_transfer` method), you need to implement a hook. Hooks are a way to **wrap (inject code before and after)** component functions:
86+
87+
<Github fname="transfer_hook.rs" language="rust"
88+
url="https://github.com/near-examples/nft-contract-tools/blob/main/src/transfer_hook.rs"
89+
start="5" end="33" />
90+
91+
Then derive it to our contract struct:
92+
93+
<Github fname="lib.rs" language="rust"
94+
url="https://github.com/near-examples/nft-contract-tools/blob/main/src/lib.rs"
95+
start="9" end="12" />
96+
97+
---
98+
99+
## Minting
100+
101+
By default, the NFT standards do not include a minting method. However, you can easily mint tokens for the owner by implementing an `nft_mint` method:
102+
103+
<Github fname="mint.rs" language="rust"
104+
url="https://github.com/near-examples/nft-contract-tools/blob/main/src/mint.rs"
105+
start="10" end="40" />
106+
107+
:::tip
108+
109+
You can modify this method as you need, for example, to allow minting only when the contract is not paused (requires deriving [`Pausable`](https://github.com/near/near-sdk-contract-tools/tree/develop?tab=readme-ov-file#macro-combinations) hook), or to enable minting only to specific accounts with a certain role or from a whitelist with custom limitations.
110+
111+
:::
112+
113+
---
114+
115+
## Burning
116+
117+
In the same way that minting is not included in the NFT standards, burning is also not included. However, you can also easily implement it.
118+
119+
To allow users to burn their tokens, you can add a `burn` method:
120+
121+
<Github fname="burn.rs" language="rust"
122+
url="https://github.com/near-examples/nft-contract-tools/blob/main/src/burn.rs"
123+
start="5" end="25" />
124+
125+
---
126+
127+
## Conclusion
128+
129+
Using `near-sdk-contract-tools` is a simple and flexible way to create an NFT contract with minimal boilerplate, which allows you to focus on the business logic.
130+
131+
You can further extend this contract with more features like pausing, role-based access control, escrow pattern, and more by deriving corresponding macros from the package.
132+
133+
<MovingForwardSupportSection />

docs/protocol/transaction-anatomy.md

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,21 +35,20 @@ Each transaction has exactly one `Signer` and `Receiver`, but can have multiple
3535

3636
## Actions
3737

38-
Each transaction can have **one or multiple** `Actions`, which are the actual operations to be performed on the `Receiver` account. There are 9 types of actions that can be performed:
39-
40-
1. `FunctionCall`: to invoke a function on a contract (optionally attaching NEAR to the call)
41-
2. `Transfer`: to transfer tokens to another account
42-
3. `DeployContract`: to deploy a contract in the account
43-
4. `DeployGlobalContract`: registers a global contract referenced by its checksum hash, making it immutable.
44-
5. `DeployGlobalContractByAccountId`: registers a global contract under an account ID, allowing the code to be updated later.
45-
6. `UseGlobalContract`: uses a registered global contract by checksum hash, ensuring the contract code is immutable.
46-
7. `UseGlobalContractByAccountId` uses a registered global contract by account ID, allowing rolling updates as the account’s code changes.
47-
8. `CreateAccount`: to create a new sub-account (e.g. `ana.near` can create `sub.ana.near`)
48-
9. `DeleteAccount`: to delete the account (transferring the remaining balance to a beneficiary)
49-
10. `AddKey`: to add a new key to the account (either `FullAccess` or `FunctionCall` access)
50-
11. `DeleteKey`: to delete an existing key from the account
51-
12. `DelegateActions`: to create a meta-transaction
52-
13. `Stake`: special action to express interest in becoming a network validator
38+
Each transaction can have **one or multiple** [`Actions`](https://nomicon.io/RuntimeSpec/Actions.html), which are the actual operations to be performed on the `Receiver` account. There are different types of actions that can be performed:
39+
40+
1. [`FunctionCall`](https://nomicon.io/RuntimeSpec/Actions.html#functioncallaction): to invoke a function on a contract (optionally attaching NEAR to the call)
41+
2. [`Transfer`](https://nomicon.io/RuntimeSpec/Actions.html#transferaction): to transfer tokens to another account
42+
3. [`DeployContract`](https://nomicon.io/RuntimeSpec/Actions.html#deploycontractaction): to deploy a contract in the account
43+
4. [`DeployGlobalContract`](https://nomicon.io/RuntimeSpec/Actions.html#deployglobalcontractaction): registers a global contract referenced by its contract hash or by its account ID
44+
5. [`UseGlobalContract`](https://nomicon.io/RuntimeSpec/Actions.html#useglobalcontractaction): uses a registered global contract by contract hash or account ID
45+
6. [`CreateAccount`](https://nomicon.io/RuntimeSpec/Actions.html#createaccountaction): to create a new sub-account (e.g. `ana.near` can create `sub.ana.near`)
46+
7. [`DeleteAccount`](https://nomicon.io/RuntimeSpec/Actions.html#deleteaccountaction): to delete the account (transferring the remaining balance to a beneficiary)
47+
8. [`AddKey`](https://nomicon.io/RuntimeSpec/Actions.html#addkeyaction): to add a new key to the account (either `FullAccess` or `FunctionCall` access)
48+
9. [`DeleteKey`](https://nomicon.io/RuntimeSpec/Actions.html#deletekeyaction): to delete an existing key from the account
49+
10. [`DelegateActions`](https://nomicon.io/RuntimeSpec/Actions.html#delegate-actions): to create a meta-transaction
50+
11. [`Stake`](https://nomicon.io/RuntimeSpec/Actions.html#stakeaction): special action to express interest in becoming a network validator
51+
12. [`DeterministicStateInit`](https://nomicon.io/RuntimeSpec/Actions.html#deterministicstateinitaction): special action to create a deterministic account (an advanced kind of implicit account)
5352

5453
For example, `bob.near` can bundle the following actions in a single transaction:
5554
- Create the account `contract.bob.near`

docs/web3-apps/tutorials/web-login/ethereum-wallets.md

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,9 @@ Lets start by updating the `package.json`, adding all the necessary libraries to
4949

5050
In your `package.json`, add the `@near-wallet-selector/ethereum-wallets` package, and update **all** wallet selector packages to version `8.9.13` or above:
5151

52-
```json title="package.json"
53-
"dependencies": {
54-
...
55-
"@near-wallet-selector/core": "^9.5.0",
56-
// highlight-next-line
57-
"@near-wallet-selector/ethereum-wallets": "^9.5.0",
58-
"@near-wallet-selector/here-wallet": "^9.5.0",
59-
"@near-wallet-selector/modal-ui": "^9.5.0",
60-
"@near-wallet-selector/my-near-wallet": "^9.5.0",
61-
...
62-
}
63-
```
52+
<Github fname="package.json" language="js"
53+
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/package.json"
54+
start="17" end="19" />
6455

6556
<hr class="subsection" />
6657

docs/web3-apps/tutorials/web-login/wallet-selector.md

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -59,32 +59,9 @@ Notice that the wallet selector implements multiple wallet packages to select fr
5959

6060
To initialize the wallet selector, you will need to set it up in your main application file (e.g., `app.js` or `index.js`). You can choose which wallets to include in the selector by importing their respective setup functions and adding them to the `modules` array.
6161

62-
```jsx title="app.js"
63-
import { setupBitteWallet } from "@near-wallet-selector/bitte-wallet";
64-
import { setupLedger } from "@near-wallet-selector/ledger";
65-
import { setupMeteorWallet } from "@near-wallet-selector/meteor-wallet";
66-
import { setupNightly } from "@near-wallet-selector/nightly";
67-
import { WalletSelectorProvider } from "@near-wallet-selector/react-hook";
68-
69-
const walletSelectorConfig = {
70-
network: "testnet", // "mainnet"
71-
// Optional: createAccessKeyFor: "hello.near-examples.testnet",
72-
modules: [
73-
setupBitteWallet(),
74-
setupMeteorWallet(),
75-
setupLedger(),
76-
setupNightly()
77-
],
78-
}
79-
80-
export default function App({ Component }) {
81-
return (
82-
<WalletSelectorProvider config={walletSelectorConfig}>
83-
<Component {...pageProps} />
84-
</WalletSelectorProvider>
85-
);
86-
}
87-
```
62+
<Github fname="_app.tsx" language="ts" start="10" end="68" metastring="{23}"
63+
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/src/pages/_app.tsx" />
64+
8865

8966
<hr class="subsection" />
9067

@@ -110,16 +87,8 @@ const my_network = {
11087

11188
If you instantiated the `wallet-selector` passing an account id for the `createAccessKeyFor` parameter, then the wallet will create a [Function-Call Key](/protocol/access-keys#function-call-keys) and store it in the web's local storage.
11289

113-
```js
114-
const walletSelectorConfig = {
115-
network: "testnet", // "mainnet"
116-
createAccessKeyFor: "hello.near-examples.testnet",
117-
modules: [
118-
setupMeteorWallet()
119-
// ...
120-
],
121-
}
122-
```
90+
<Github fname="_app.tsx" language="ts" start="32" end="34" metastring="{32}"
91+
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/src/pages/_app.tsx" />
12392

12493
By default, such key enables to expend a maximum of `0.25Ⓝ` on GAS calling methods in **the specified** contract **without prompting** the user to sign them.
12594

0 commit comments

Comments
 (0)