Skip to content

Commit d3b464c

Browse files
authored
feat(1406): contract erc721 add readme (#1415)
Signed-off-by: rozekmichal <michal.rozek@blockydevs.com>
1 parent 46cc88a commit d3b464c

File tree

3 files changed

+264
-10
lines changed

3 files changed

+264
-10
lines changed
Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
# Contract ERC-721 Plugin
2+
3+
ERC-721 (NFT) token interface plugin for the Hiero CLI. Provides commands to call standard ERC-721 (EIP-721) smart contract functions on Hedera. Contracts must be deployed first using the [contract plugin](../contract/README.md).
4+
5+
## 🏗️ Architecture
6+
7+
This plugin follows the plugin architecture principles:
8+
9+
- **Stateless**: Plugin is functionally stateless
10+
- **Dependency Injection**: Services are injected into command handlers
11+
- **Manifest-Driven**: Capabilities declared via manifest
12+
- **Type Safety**: Full TypeScript support
13+
14+
## 📁 Structure
15+
16+
```
17+
src/plugins/contract-erc721/
18+
├── manifest.ts # Plugin manifest with command definitions
19+
├── shared/
20+
│ └── erc721-abi.ts # ERC-721 ABI interface definition
21+
├── commands/
22+
│ ├── name/ # name() view function
23+
│ ├── symbol/ # symbol() view function
24+
│ ├── balance-of/ # balanceOf(address) view function
25+
│ ├── owner-of/ # ownerOf(tokenId) view function
26+
│ ├── get-approved/ # getApproved(tokenId) view function
27+
│ ├── is-approved-for-all/ # isApprovedForAll(owner, operator) view function
28+
│ ├── token-uri/ # tokenURI(tokenId) view function
29+
│ ├── approve/ # approve(to, tokenId) state-changing
30+
│ ├── set-approval-for-all/ # setApprovalForAll(operator, approved) state-changing
31+
│ ├── transfer-from/ # transferFrom(from, to, tokenId) state-changing
32+
│ ├── safe-transfer-from/ # safeTransferFrom(from, to, tokenId [, data]) state-changing
33+
│ └── mint/ # mint(to, tokenId) state-changing (experimental)
34+
├── __tests__/unit/ # Unit tests
35+
└── index.ts # Plugin exports
36+
```
37+
38+
Each command folder contains: `handler.ts`, `input.ts`, `output.ts`, `index.ts`, and optionally `result.ts` for view functions.
39+
40+
## 🚀 Commands
41+
42+
All commands return `CommandExecutionResult` with structured output. Contract and account references accept **alias**, **Hedera entity ID** (0.0.xxx), or **EVM address** (0x...).
43+
44+
### View Functions (read-only, no transaction)
45+
46+
| Command | Description |
47+
| --------------------- | --------------------------------------------------- |
48+
| `name` | Token collection name |
49+
| `symbol` | Token symbol |
50+
| `balance-of` | NFT balance of an owner |
51+
| `owner-of` | Owner of a token by ID |
52+
| `get-approved` | Approved address for a token |
53+
| `is-approved-for-all` | Whether operator is approved for all owner's tokens |
54+
| `token-uri` | Metadata URI for a token |
55+
56+
### State-Changing Functions (require transaction, signed by operator)
57+
58+
| Command | Description |
59+
| ---------------------- | ------------------------------------------------------- |
60+
| `approve` | Approve address to transfer a specific token |
61+
| `set-approval-for-all` | Approve or revoke operator for all tokens |
62+
| `transfer-from` | Transfer token from one address to another |
63+
| `safe-transfer-from` | Safe transfer with optional data payload |
64+
| `mint` | Mint new token (experimental, requires custom contract) |
65+
66+
### name
67+
68+
```bash
69+
hcli contract-erc721 name --contract my-nft
70+
```
71+
72+
| Option | Short | Required | Description |
73+
| ---------- | ----- | -------- | -------------------- |
74+
| `contract` | `c` | Yes | Contract alias or ID |
75+
76+
### symbol
77+
78+
```bash
79+
hcli contract-erc721 symbol --contract my-nft
80+
```
81+
82+
| Option | Short | Required | Description |
83+
| ---------- | ----- | -------- | -------------------- |
84+
| `contract` | `c` | Yes | Contract alias or ID |
85+
86+
### balance-of
87+
88+
```bash
89+
hcli contract-erc721 balance-of --contract my-nft --owner alice
90+
```
91+
92+
| Option | Short | Required | Description |
93+
| ---------- | ----- | -------- | -------------------------------------- |
94+
| `contract` | `c` | Yes | Contract alias, ID or EVM address |
95+
| `owner` | `o` | Yes | Owner account alias, ID or EVM address |
96+
97+
### owner-of
98+
99+
```bash
100+
hcli contract-erc721 owner-of --contract my-nft --token-id 1
101+
```
102+
103+
| Option | Short | Required | Description |
104+
| ---------- | ----- | -------- | -------------------- |
105+
| `contract` | `c` | Yes | Contract alias or ID |
106+
| `token-id` | `T` | Yes | Token ID (uint256) |
107+
108+
### get-approved
109+
110+
```bash
111+
hcli contract-erc721 get-approved --contract my-nft --token-id 1
112+
```
113+
114+
| Option | Short | Required | Description |
115+
| ---------- | ----- | -------- | -------------------- |
116+
| `contract` | `c` | Yes | Contract alias or ID |
117+
| `token-id` | `T` | Yes | Token ID to query |
118+
119+
### is-approved-for-all
120+
121+
```bash
122+
hcli contract-erc721 is-approved-for-all --contract my-nft --owner alice --operator bob
123+
```
124+
125+
| Option | Short | Required | Description |
126+
| ---------- | ----- | -------- | ----------------------------------------- |
127+
| `contract` | `c` | Yes | Contract alias, ID or EVM address |
128+
| `owner` | `o` | Yes | Owner account alias, ID or EVM address |
129+
| `operator` | `p` | Yes | Operator account alias, ID or EVM address |
130+
131+
### token-uri
132+
133+
```bash
134+
hcli contract-erc721 token-uri --contract my-nft --token-id 1
135+
```
136+
137+
| Option | Short | Required | Description |
138+
| ---------- | ----- | -------- | -------------------- |
139+
| `contract` | `c` | Yes | Contract alias or ID |
140+
| `token-id` | `T` | Yes | Token ID to query |
141+
142+
### approve
143+
144+
Approves an address to transfer a specific token. Operator must be the token owner.
145+
146+
```bash
147+
hcli contract-erc721 approve --contract my-nft --to bob --token-id 1
148+
```
149+
150+
| Option | Short | Required | Description | Default |
151+
| ---------- | ----- | -------- | --------------------------------------------- | ------- |
152+
| `contract` | `c` | Yes | Contract alias, ID or EVM address | - |
153+
| `to` | `t` | Yes | Address to approve (alias, ID or EVM address) | - |
154+
| `token-id` | `T` | Yes | Token ID to approve | - |
155+
| `gas` | `g` | No | Gas for function call | 100000 |
156+
157+
### set-approval-for-all
158+
159+
Approves or revokes an operator for all tokens owned by the caller.
160+
161+
```bash
162+
hcli contract-erc721 set-approval-for-all --contract my-nft --operator bob --approved true
163+
```
164+
165+
| Option | Short | Required | Description | Default |
166+
| ---------- | ----- | -------- | ----------------------------------------- | ------- |
167+
| `contract` | `c` | Yes | Contract alias, ID or EVM address | - |
168+
| `operator` | `o` | Yes | Operator account alias, ID or EVM address | - |
169+
| `approved` | `a` | Yes | "true" or "false" | - |
170+
| `gas` | `g` | No | Gas for function call | 100000 |
171+
172+
### transfer-from
173+
174+
Transfers a token from one address to another. Caller must be owner, approved, or approved for all.
175+
176+
```bash
177+
hcli contract-erc721 transfer-from --contract my-nft --from alice --to bob --token-id 1
178+
```
179+
180+
| Option | Short | Required | Description | Default |
181+
| ---------- | ----- | -------- | ---------------------------------------- | ------- |
182+
| `contract` | `c` | Yes | Contract alias, ID or EVM address | - |
183+
| `from` | `f` | Yes | Current owner (alias, ID or EVM address) | - |
184+
| `to` | `t` | Yes | Recipient (alias, ID or EVM address) | - |
185+
| `token-id` | `T` | Yes | Token ID to transfer | - |
186+
| `gas` | `g` | No | Gas for function call | 100000 |
187+
188+
### safe-transfer-from
189+
190+
Safe transfer with optional data. Reverts if recipient is a contract that does not implement the receiver interface.
191+
192+
```bash
193+
hcli contract-erc721 safe-transfer-from --contract my-nft --from alice --to bob --token-id 1
194+
hcli contract-erc721 safe-transfer-from -c my-nft -f alice -t bob -T 1 -d 0x1234
195+
```
196+
197+
| Option | Short | Required | Description | Default |
198+
| ---------- | ----- | -------- | -------------------------------------------- | ------- |
199+
| `contract` | `c` | Yes | Contract alias, ID or EVM address | - |
200+
| `from` | `f` | Yes | Current owner (alias, ID or EVM address) | - |
201+
| `to` | `t` | Yes | Recipient (alias, ID or EVM address) | - |
202+
| `token-id` | `T` | Yes | Token ID to transfer | - |
203+
| `data` | `d` | No | Optional hex-encoded data for 4-arg overload | - |
204+
| `gas` | `g` | No | Gas for function call | 100000 |
205+
206+
### mint
207+
208+
**⚠️ EXPERIMENTAL** – Calls custom `mint(address to, uint256 tokenId)`. Requires contract to implement this function (e.g. via OpenZeppelin `_mint`).
209+
210+
```bash
211+
hcli contract-erc721 mint --contract my-nft --to alice --token-id 1
212+
```
213+
214+
| Option | Short | Required | Description | Default |
215+
| ---------- | ----- | -------- | -------------------------------------------- | ------- |
216+
| `contract` | `c` | Yes | Contract alias, ID or EVM address | - |
217+
| `to` | `t` | Yes | Recipient address (alias, ID or EVM address) | - |
218+
| `token-id` | `T` | Yes | Token ID to mint | - |
219+
| `gas` | `g` | No | Gas for function call | 100000 |
220+
221+
## 🔧 Core API Integration
222+
223+
The plugin uses the Core API services:
224+
225+
- `api.contract` - Contract execute transaction creation
226+
- `api.contractQuery` - Read-only contract calls (view functions)
227+
- `api.txExecution` - Transaction signing and execution
228+
- `api.identityResolution` - Resolve alias, entity ID, or EVM address to contract/account info
229+
- `api.network` - Current network
230+
- `api.logger` - Logging
231+
232+
## 📤 Output Formatting
233+
234+
All commands return structured output through the `CommandExecutionResult` interface. View functions return query results; state-changing functions return `contractId`, `network`, and `transactionId`.
235+
236+
Human-readable output uses Handlebars templates with HashScan links for contract and transaction IDs.
237+
238+
## 🏷️ Identity Resolution
239+
240+
Contract and account parameters support flexible referencing:
241+
242+
- **Alias**: Registered name (e.g. `my-nft`, `alice`) – resolved via alias service
243+
- **Entity ID**: Hedera format (e.g. `0.0.123456`)
244+
- **EVM address**: Hex format (e.g. `0x1234...`)
245+
246+
View functions resolve contracts synchronously. State-changing functions resolve contracts via Mirror Node for full contract info.
247+
248+
## 🧪 Testing
249+
250+
Unit tests located in `__tests__/unit/`:
251+
252+
```bash
253+
npm run test:unit -- src/plugins/contract-erc721/__tests__/unit
254+
```

src/plugins/contract-erc721/commands/balance-of/input.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import {
77

88
/**
99
* Input schema for contract erc721 call balanceOf command.
10-
* Parsed contract and account are discriminated objects: { type: EntityReferenceType, value: string }.
11-
* account accepts alias, account ID (0.0.xxx), or EVM address (0x...) via AccountReferenceObjectSchema.
10+
* Parsed contract and owner are discriminated objects: { type: EntityReferenceType, value: string }.
11+
* owner accepts alias, account ID (0.0.xxx), or EVM address (0x...) via AccountReferenceObjectSchema.
1212
*/
1313
export const ContractErc721CallBalanceOfInputSchema = z.object({
1414
contract: ContractReferenceObjectSchema,

src/plugins/contract-erc721/manifest.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* Contract ERC721 Plugin Manifest
3-
* Provides commands to list, get and set configuration options
3+
* Provides commands to call ERC-721 contract functions
44
*/
55
import type { PluginManifest } from '@/core';
66

@@ -118,7 +118,7 @@ export const contractErc721PluginManifest: PluginManifest = {
118118
name: 'gas',
119119
short: 'g',
120120
type: OptionType.NUMBER,
121-
required: true,
121+
required: false,
122122
default: 100000,
123123
description: 'Gas for function call. Default: 100000',
124124
},
@@ -136,7 +136,7 @@ export const contractErc721PluginManifest: PluginManifest = {
136136
type: OptionType.NUMBER,
137137
required: true,
138138
description:
139-
'Parameter "tokenId" in approve - token ID (uint256) to approve. Option required',
139+
'Parameter "token-id" in approve - token ID (uint256) to approve. Option required',
140140
},
141141
],
142142
handler: approveFunctionCall,
@@ -243,7 +243,7 @@ export const contractErc721PluginManifest: PluginManifest = {
243243
},
244244
{
245245
name: 'token-id',
246-
short: 't',
246+
short: 'T',
247247
type: OptionType.NUMBER,
248248
required: true,
249249
description: 'Token ID (uint256) to query owner of. Option required',
@@ -271,7 +271,7 @@ export const contractErc721PluginManifest: PluginManifest = {
271271
},
272272
{
273273
name: 'token-id',
274-
short: 't',
274+
short: 'T',
275275
type: OptionType.NUMBER,
276276
required: true,
277277
description:
@@ -300,7 +300,7 @@ export const contractErc721PluginManifest: PluginManifest = {
300300
},
301301
{
302302
name: 'token-id',
303-
short: 't',
303+
short: 'T',
304304
type: OptionType.NUMBER,
305305
required: true,
306306
description: 'Token ID (uint256) to query URI for. Option required',
@@ -450,7 +450,7 @@ export const contractErc721PluginManifest: PluginManifest = {
450450
type: OptionType.NUMBER,
451451
required: true,
452452
description:
453-
'Parameter "tokenId" - token ID (uint256) to mint. Option required',
453+
'Parameter "token-id" - token ID (uint256) to mint. Option required',
454454
},
455455
],
456456
handler: mintFunctionCall,
@@ -502,7 +502,7 @@ export const contractErc721PluginManifest: PluginManifest = {
502502
type: OptionType.NUMBER,
503503
required: true,
504504
description:
505-
'Parameter "tokenId" in transferFrom function represented by a number. Option required',
505+
'Parameter "token-id" in transferFrom function represented by a number. Option required',
506506
},
507507
],
508508
handler: transferFromFunctionCall,

0 commit comments

Comments
 (0)