Skip to content

Commit 4175590

Browse files
authored
Merge branch 'master' into multichain-reorg
2 parents e5f7344 + e459afe commit 4175590

File tree

8 files changed

+319
-34
lines changed

8 files changed

+319
-34
lines changed

docs/data-infrastructure/indexers.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,17 @@ Because indexers listen to the *stream of data* from the blockchain and the data
9191
Another example that highlights the need for a "wide query" is when you use a seed phrase to recover one or more accounts. Since a seed phrase essentially represents a signing key pair, the recovery is for all accounts that share the associated public key. Therefore, when a seed phrase is used to recover an account via [NEAR Wallet](https://wallet.near.org), the query requires that all accounts with a matching public key are found and recovered. Utilizing [Near Lake Framework](https://github.com/near/near-lake-framework-rs) can be used to store this data in a permanent database and this allows [NEAR Wallet](https://wallet.near.org) to perform such "wide queries". This is impossible to achieve using JSON-RPC only.
9292

9393
---
94+
95+
## Indexers in the NEAR ecosystem
96+
97+
There are [multiple indexing options](../tools/data-services.md) available in the NEAR ecosystem. If you are ready to host your own indexer, we recommend using the [Near Lake Framework](./lake-framework/near-lake.md) as it is simple, reliable, and available in multiple languages (JavaScript, Rust, Python).
98+
99+
If speed is critical for your indexing needs, consider using [Near Indexer](./near-indexer.md). However, please note that maintaining it can be more complex and costly, as it essentially operates as an independent node in the network.
100+
101+
If you prefer not to host your own solution, you can utilize [third-party services](../tools/data-services.md).
102+
103+
---
104+
94105
## Summary
95106

96107
We hope this article gives you an understanding of the Indexer concept. Also, we hope now you can easily decide whether you need an indexer for your application.

docs/data-infrastructure/tutorials/near-indexer.md

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -128,17 +128,31 @@ After we finish initializing the indexer, and configuring it, we can start it by
128128
```
129129
</TabItem>
130130
</Tabs>
131+
132+
<details>
133+
<summary>How it works</summary>
134+
135+
- The command initializes the indexer's configuration: home directory, sync mode, streaming mode, finality, etc.
136+
- Creates a Tokio runtime on a dedicated thread.
137+
- Creates an instance of the Indexer using the provided configuration, starts it, and streams blocks to our handler. Within the handler (`listen_blocks` method), there is an infinite loop that parses block data for each new block received.
138+
139+
<Github fname="main.rs" language="rust"
140+
url="https://github.com/near/nearcore/blob/master/tools/indexer/example/src/main.rs"
141+
start="271" end="289" />
142+
143+
</details>
144+
131145
#### Run into an Error?
132146
- If your indexer cannot find `boot nodes`, check the [boot nodes](#boot-nodes) section
133147
---
134148

135149
## Parsing the Block Data
136150

137-
From the block data, we can access the transactions, their receipts and actions. See the code below for an example of how to parse the block data:
151+
Within the `listen_blocks` method, we can parse the block data as it flows from the stream. From the block data, we can access the transactions, their receipts, and actions. See the code below for an example of how to parse the block data:
138152

139153
<Github fname="main.rs" language="rust"
140154
url="https://github.com/near/nearcore/blob/master/tools/indexer/example/src/main.rs"
141-
start="13" end="243" />
155+
start="10" end="254" />
142156

143157
---
144158

@@ -183,8 +197,8 @@ You can choose Indexer Framework sync mode by setting what to stream:
183197
- BlockHeight(u64) - Specific block height to start syncing from.
184198

185199
<Github fname="main.rs" language="rust"
186-
url="https://github.com/near-examples/near-indexer/blob/main/src/main.rs"
187-
start="34" end="34" />
200+
url="https://github.com/near/nearcore/blob/master/tools/indexer/example/src/main.rs"
201+
start="274" end="274" />
188202

189203
<hr class="subsection" />
190204

@@ -195,8 +209,8 @@ You can choose Indexer Framework streaming mode by setting what to stream:
195209
- WaitForFullSync - Don't stream until the node is fully synced
196210

197211
<Github fname="main.rs" language="rust"
198-
url="https://github.com/near-examples/near-indexer/blob/main/src/main.rs"
199-
start="35" end="35" />
212+
url="https://github.com/near/nearcore/blob/master/tools/indexer/example/src/main.rs"
213+
start="275" end="275" />
200214

201215
<hr class="subsection" />
202216

@@ -208,8 +222,8 @@ You can choose finality level at which blocks are streamed:
208222
- Final - `final`, the block is final and irreversible.
209223

210224
<Github fname="main.rs" language="rust"
211-
url="https://github.com/near-examples/near-indexer/blob/main/src/main.rs"
212-
start="36" end="36" />
225+
url="https://github.com/near/nearcore/blob/master/tools/indexer/example/src/main.rs"
226+
start="276" end="276" />
213227

214228
<hr class="subsection" />
215229

@@ -285,11 +299,11 @@ You can also use NEAR Indexer Framework as a dependency in your own Rust project
285299

286300
```toml
287301
[dependencies]
288-
near-indexer = { git = "https://github.com/near/nearcore", tag = "2.8.0" }
289-
near-indexer-primitives = { git = "https://github.com/near/nearcore", tag = "2.8.0" }
290-
near-config-utils = { git = "https://github.com/near/nearcore", tag = "2.8.0" }
291-
near-o11y = { git = "https://github.com/near/nearcore", tag = "2.8.0" }
292-
near-primitives = { git = "https://github.com/near/nearcore", tag = "2.8.0" }
302+
near-indexer = { git = "https://github.com/near/nearcore", tag = "2.9.1" }
303+
near-indexer-primitives = { git = "https://github.com/near/nearcore", tag = "2.9.1" }
304+
near-config-utils = { git = "https://github.com/near/nearcore", tag = "2.9.1" }
305+
near-o11y = { git = "https://github.com/near/nearcore", tag = "2.9.1" }
306+
near-primitives = { git = "https://github.com/near/nearcore", tag = "2.9.1" }
293307
```
294308

295309
<MovingForwardSupportSection />

docs/index.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@ import LandingHero from '@site/src/components/LandingHero';
7373
title="Smart Contracts"
7474
>
7575
<ul>
76-
<li><a href="/smart-contracts/what-is">What are Smart Contracts?</a></li>
77-
<li><a href="/smart-contracts/quickstart">Quickstart ✨</a></li>
78-
<li><a href="/smart-contracts/anatomy/">Contract's Anatomy</a></li>
76+
<li><a href="/smart-contracts/what-is">Learn what is a Smart Contract</a></li>
77+
<li><a href="/smart-contracts/quickstart">Build your First Contract ✨</a></li>
78+
<li><a href="/smart-contracts/anatomy/">Understand Fundamental Concepts</a></li>
7979
</ul>
8080
</Card>
8181
</div>
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 />

0 commit comments

Comments
 (0)