@net-protocol/cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,339 @@
1
+ # @net-protocol/cli
2
+
3
+ A command-line tool for interacting with Net Protocol. Supports storage uploads and more.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ # Global install
9
+ npm install -g @net-protocol/cli
10
+
11
+ # Or with yarn
12
+ yarn global add @net-protocol/cli
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ The CLI uses a subcommand pattern. Each command is isolated and has its own options:
18
+
19
+ ```bash
20
+ netp <command> [options]
21
+ ```
22
+
23
+ ### Available Commands
24
+
25
+ #### Storage Command
26
+
27
+ Storage operations for Net Protocol. The `storage` command is a command group with subcommands for different operations.
28
+
29
+ **Available Subcommands:**
30
+
31
+ - `storage upload` - Upload files to Net Storage
32
+ - `storage preview` - Preview storage upload without submitting transactions
33
+
34
+ ##### Storage Upload
35
+
36
+ Upload files to Net Storage using either normal storage (for files ≤ 20KB) or XML storage (for files > 20KB or containing XML references).
37
+
38
+ ```bash
39
+ netp storage upload \
40
+ --file <path> \
41
+ --key <storage-key> \
42
+ --text <description> \
43
+ [--private-key <0x...>] \
44
+ --chain-id <8453|1|...> \
45
+ [--rpc-url <custom-rpc>]
46
+ ```
47
+
48
+ **Storage Upload Arguments:**
49
+
50
+ - `--file` (required): Path to file to upload
51
+ - `--key` (required): Storage key (filename/identifier)
52
+ - `--text` (required): Text description/filename
53
+ - `--private-key` (optional): Private key (0x-prefixed hex, 66 characters). Can also be set via `NET_PRIVATE_KEY` or `PRIVATE_KEY` environment variable
54
+ - `--chain-id` (optional): Chain ID (8453 for Base, 1 for Ethereum, etc.). Can also be set via `NET_CHAIN_ID` environment variable
55
+ - `--rpc-url` (optional): Custom RPC URL. Can also be set via `NET_RPC_URL` environment variable
56
+
57
+ **Examples:**
58
+
59
+ ```bash
60
+ # Using command-line flags
61
+ netp storage upload \
62
+ --file ./example.txt \
63
+ --key "my-file" \
64
+ --text "Example file" \
65
+ --private-key 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef \
66
+ --chain-id 8453
67
+
68
+ # Using environment variables (recommended)
69
+ export NET_PRIVATE_KEY=0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
70
+ export NET_CHAIN_ID=8453
71
+ netp storage upload \
72
+ --file ./example.txt \
73
+ --key "my-file" \
74
+ --text "Example file"
75
+
76
+ # Using .env file
77
+ # Create .env file with:
78
+ # NET_PRIVATE_KEY=0x...
79
+ # NET_CHAIN_ID=8453
80
+ # NET_RPC_URL=https://base-mainnet.public.blastapi.io # optional
81
+ netp storage upload --file ./example.txt --key "my-file" --text "Example file"
82
+ ```
83
+
84
+ ##### Storage Preview
85
+
86
+ Preview what would be uploaded without actually submitting transactions. Shows statistics about chunks, transactions, and what's already stored.
87
+
88
+ ```bash
89
+ netp storage preview \
90
+ --file <path> \
91
+ --key <storage-key> \
92
+ --text <description> \
93
+ [--private-key <0x...>] \
94
+ --chain-id <8453|1|...> \
95
+ [--rpc-url <custom-rpc>]
96
+ ```
97
+
98
+ **Storage Preview Arguments:**
99
+
100
+ Same as `storage upload` - see above.
101
+
102
+ **Example:**
103
+
104
+ ```bash
105
+ netp storage preview \
106
+ --file ./example.txt \
107
+ --key "my-file" \
108
+ --text "Example file" \
109
+ --chain-id 8453
110
+ ```
111
+
112
+ **Output:**
113
+
114
+ ```
115
+ 📁 Reading file: ./example.txt
116
+
117
+ 📊 Storage Preview:
118
+ Storage Key: my-file
119
+ Storage Type: Normal
120
+ Total Chunks: 1
121
+ Already Stored: 0
122
+ Need to Store: 1
123
+ Total Transactions: 1
124
+ Transactions to Send: 1
125
+ Transactions Skipped: 0
126
+ Operator Address: 0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf
127
+
128
+ ⚠ 1 transaction(s) would be sent
129
+ ```
130
+
131
+ ## Storage Types
132
+
133
+ ### Normal Storage
134
+
135
+ For files up to 20KB, the tool uses normal storage:
136
+
137
+ - Stores data directly in `Storage.sol`
138
+ - Single transaction
139
+ - Simple key-value storage
140
+
141
+ ### XML Storage
142
+
143
+ For files larger than 20KB or containing XML references, the tool uses XML storage:
144
+
145
+ - Breaks file into 80KB XML chunks
146
+ - Each XML chunk is stored in ChunkedStorage (compressed and chunked into 20KB pieces)
147
+ - XML metadata references all chunks
148
+ - Multiple sequential transactions (metadata first, then chunks)
149
+
150
+ ## Idempotency
151
+
152
+ The storage command includes built-in idempotency checks:
153
+
154
+ 1. **Pre-flight Checks**: Before uploading, checks if data already exists
155
+ 2. **Content Comparison**: For normal storage, compares file content with stored content
156
+ 3. **Chunk-Level Deduplication**: For XML storage, checks each chunk individually
157
+ 4. **Per-Transaction Checks**: Before sending each transaction, verifies data doesn't already exist
158
+
159
+ ### Retry Behavior
160
+
161
+ If an upload fails mid-way:
162
+
163
+ - Retry the same command
164
+ - The tool will check which chunks already exist
165
+ - Only missing chunks will be uploaded
166
+ - Safe to retry multiple times
167
+
168
+ ### Example: Upload Same File Twice
169
+
170
+ ```bash
171
+ # First upload
172
+ netp storage upload --file example.txt --key "test" --text "Test" --chain-id 8453
173
+ # Output: ✓ File uploaded successfully!
174
+
175
+ # Second upload (same file, same key)
176
+ netp storage upload --file example.txt --key "test" --text "Test" --chain-id 8453
177
+ # Output: ✓ All data already stored - skipping upload
178
+ ```
179
+
180
+ ## Architecture
181
+
182
+ The CLI is organized into a modular, extensible architecture:
183
+
184
+ ```
185
+ src/
186
+ ├── cli/
187
+ │ ├── index.ts # Main entry point, sets up commander program
188
+ │ └── shared.ts # Shared option parsing and validation
189
+ ├── commands/
190
+ │ └── storage/ # Storage command module
191
+ │ ├── index.ts # Storage command definition
192
+ │ ├── core/ # Upload and preview logic
193
+ │ ├── storage/ # Storage operations
194
+ │ ├── transactions/ # Transaction handling
195
+ │ ├── utils.ts # Storage-specific utilities
196
+ │ └── types.ts # Storage-specific types
197
+ └── shared/ # Shared utilities across commands
198
+ └── types.ts # Common types (CommonOptions, etc.)
199
+ ```
200
+
201
+ ### Key Components
202
+
203
+ - **`cli/index.ts`**: Main CLI entry point that sets up the commander program and registers all commands
204
+ - **`cli/shared.ts`**: Shared utilities for parsing common options (private-key, chain-id, rpc-url) that are available to all commands
205
+ - **`commands/{name}/index.ts`**: Each command module exports a `register{Name}Command()` function that defines the command's options and behavior
206
+ - **`shared/types.ts`**: Common types shared across commands (e.g., `CommonOptions`)
207
+
208
+ ### Command Structure
209
+
210
+ Each command can have its own internal structure:
211
+
212
+ - **`core/`**: Core business logic for the command
213
+ - **`storage/`**: Storage-specific operations (if applicable)
214
+ - **`transactions/`**: Transaction preparation, filtering, and sending
215
+ - **`utils.ts`**: Command-specific utility functions
216
+ - **`types.ts`**: Command-specific types
217
+
218
+ ## Extensibility
219
+
220
+ ### Adding a New Command
221
+
222
+ To add a new top-level command:
223
+
224
+ 1. **Create command directory**: `src/commands/{name}/`
225
+ 2. **Create command index**: `src/commands/{name}/index.ts` with a `register{Name}Command(program: Command)` function
226
+ 3. **Register in main CLI**: Import and call `register{Name}Command(program)` in `src/cli/index.ts`
227
+ 4. **Add command-specific code**: Create subdirectories as needed (core/, storage/, transactions/, etc.)
228
+
229
+ ### Adding a Storage Subcommand
230
+
231
+ To add a new subcommand to the `storage` command group:
232
+
233
+ 1. **Create subcommand**: Use `new Command("subcommand-name")` in `src/commands/storage/index.ts`
234
+ 2. **Add options**: Use `.requiredOption()` or `.option()` to define subcommand options
235
+ 3. **Add action**: Use `.action()` to define the subcommand behavior
236
+ 4. **Register**: Use `storageCommand.addCommand(subcommand)` to register it
237
+
238
+ **Example:**
239
+
240
+ ```typescript
241
+ // In src/commands/storage/index.ts
242
+ const verifyCommand = new Command("verify")
243
+ .description("Verify storage integrity")
244
+ .requiredOption("--key <key>", "Storage key to verify")
245
+ .action(async (options) => {
246
+ // Implementation
247
+ });
248
+
249
+ storageCommand.addCommand(verifyCommand);
250
+ ```
251
+
252
+ ### Example: Adding a New Command
253
+
254
+ ```typescript
255
+ // src/commands/mycommand/index.ts
256
+ import { Command } from "commander";
257
+ import { parseCommonOptions } from "../../cli/shared";
258
+
259
+ export function registerMyCommand(program: Command): void {
260
+ program
261
+ .command("mycommand")
262
+ .description("Description of my command")
263
+ .option("--my-option <value>", "My option")
264
+ .action(async (options) => {
265
+ const commonOptions = parseCommonOptions({
266
+ privateKey: options.privateKey,
267
+ chainId: options.chainId,
268
+ rpcUrl: options.rpcUrl,
269
+ });
270
+
271
+ // Command logic here
272
+ });
273
+ }
274
+
275
+ // src/cli/index.ts
276
+ import { registerMyCommand } from "../commands/mycommand";
277
+
278
+ // ... existing code ...
279
+ registerMyCommand(program);
280
+ ```
281
+
282
+ ### Shared Options
283
+
284
+ All commands automatically have access to common options:
285
+
286
+ - `--private-key` (or `NET_PRIVATE_KEY` env var)
287
+ - `--chain-id` (or `NET_CHAIN_ID` env var)
288
+ - `--rpc-url` (or `NET_RPC_URL` env var)
289
+
290
+ These are parsed and validated by `parseCommonOptions()` from `cli/shared.ts`.
291
+
292
+ ## Security & Environment Variables
293
+
294
+ ⚠️ **Warning**: Private keys are sensitive. Always use environment variables instead of passing the private key via command line:
295
+
296
+ ```bash
297
+ # Set environment variable
298
+ export NET_PRIVATE_KEY=0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
299
+
300
+ # Run without --private-key flag (it will use the env var)
301
+ netp storage upload \
302
+ --file ./example.txt \
303
+ --key "my-file" \
304
+ --text "Example file" \
305
+ --chain-id 8453
306
+ ```
307
+
308
+ The tool supports both `NET_PRIVATE_KEY` and `PRIVATE_KEY` environment variables. If neither is set, you must provide `--private-key` flag.
309
+
310
+ ## Development
311
+
312
+ ```bash
313
+ # Install dependencies (from repo root)
314
+ yarn install
315
+
316
+ # Build
317
+ yarn workspace @net-protocol/cli build
318
+
319
+ # Run in dev mode
320
+ yarn workspace @net-protocol/cli start storage upload --file example.txt --key "test" --text "Test" --chain-id 8453
321
+
322
+ # Watch mode
323
+ yarn workspace @net-protocol/cli dev
324
+
325
+ # Run tests
326
+ yarn workspace @net-protocol/cli test
327
+ ```
328
+
329
+ ## Error Handling
330
+
331
+ The CLI handles various error scenarios:
332
+
333
+ - Invalid private key format
334
+ - File not found
335
+ - Transaction failures (continues with remaining transactions)
336
+ - Network errors
337
+ - Storage read errors
338
+
339
+ If a transaction fails mid-upload, you can safely retry the command - it will only upload missing chunks.