@net-protocol/cli 0.1.17 → 0.1.19

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 CHANGED
@@ -43,7 +43,8 @@ netp storage upload \
43
43
  --text <description> \
44
44
  [--private-key <0x...>] \
45
45
  --chain-id <8453|1|...> \
46
- [--rpc-url <custom-rpc>]
46
+ [--rpc-url <custom-rpc>] \
47
+ [--chunk-size <bytes>]
47
48
  ```
48
49
 
49
50
  **Storage Upload Arguments:**
@@ -54,6 +55,7 @@ netp storage upload \
54
55
  - `--private-key` (optional): Private key (0x-prefixed hex, 66 characters). Can also be set via `NET_PRIVATE_KEY` or `PRIVATE_KEY` environment variable
55
56
  - `--chain-id` (optional): Chain ID (8453 for Base, 1 for Ethereum, etc.). Can also be set via `NET_CHAIN_ID` environment variable
56
57
  - `--rpc-url` (optional): Custom RPC URL. Can also be set via `NET_RPC_URL` environment variable
58
+ - `--chunk-size` (optional): Size of each XML chunk in bytes (default: 80000). Controls how large files are split for XML storage
57
59
 
58
60
  **Examples:**
59
61
 
@@ -80,6 +82,14 @@ netp storage upload \
80
82
  # NET_CHAIN_ID=8453
81
83
  # NET_RPC_URL=https://base-mainnet.public.blastapi.io # optional
82
84
  netp storage upload --file ./example.txt --key "my-file" --text "Example file"
85
+
86
+ # Custom chunk size (40KB instead of default 80KB)
87
+ netp storage upload \
88
+ --file ./large-file.bin \
89
+ --key "my-file" \
90
+ --text "Large file" \
91
+ --chunk-size 40000 \
92
+ --chain-id 8453
83
93
  ```
84
94
 
85
95
  ##### Storage Preview
@@ -93,7 +103,8 @@ netp storage preview \
93
103
  --text <description> \
94
104
  [--private-key <0x...>] \
95
105
  --chain-id <8453|1|...> \
96
- [--rpc-url <custom-rpc>]
106
+ [--rpc-url <custom-rpc>] \
107
+ [--chunk-size <bytes>]
97
108
  ```
98
109
 
99
110
  **Storage Preview Arguments:**
@@ -675,7 +686,7 @@ For files up to 20KB, the tool uses normal storage:
675
686
 
676
687
  For files larger than 20KB or containing XML references, the tool uses XML storage:
677
688
 
678
- - Breaks file into 80KB XML chunks
689
+ - Breaks file into 80KB XML chunks (configurable via `--chunk-size`)
679
690
  - Each XML chunk is stored in ChunkedStorage (compressed and chunked into 20KB pieces)
680
691
  - XML metadata references all chunks
681
692
  - Multiple sequential transactions (metadata first, then chunks)
@@ -6,12 +6,12 @@ import { createRequire } from 'module';
6
6
  import chalk4 from 'chalk';
7
7
  import * as fs4 from 'fs';
8
8
  import { readFileSync } from 'fs';
9
- import { StorageClient, detectFileTypeFromBase64, base64ToDataUri, shouldSuggestXmlStorage, getStorageKeyBytes, encodeStorageKeyForUrl, chunkDataForStorage, CHUNKED_STORAGE_CONTRACT, STORAGE_CONTRACT as STORAGE_CONTRACT$1 } from '@net-protocol/storage';
9
+ import { OPTIMAL_CHUNK_SIZE, StorageClient, detectFileTypeFromBase64, base64ToDataUri, shouldSuggestXmlStorage, getStorageKeyBytes, encodeStorageKeyForUrl, chunkDataForStorage, CHUNKED_STORAGE_CONTRACT, STORAGE_CONTRACT as STORAGE_CONTRACT$1 } from '@net-protocol/storage';
10
10
  import { stringToHex, createWalletClient, http, hexToString, parseEther, encodeFunctionData, publicActions, defineChain } from 'viem';
11
11
  import { privateKeyToAccount } from 'viem/accounts';
12
12
  import { getNetContract, getChainName, getPublicClient, getChainRpcUrls, NetClient, toBytes32, NULL_ADDRESS } from '@net-protocol/core';
13
13
  import { createRelayX402Client, createRelaySession, checkBackendWalletBalance, fundBackendWallet, batchTransactions, submitTransactionsViaRelay, waitForConfirmations, retryFailedTransactions as retryFailedTransactions$1 } from '@net-protocol/relay';
14
- import { FeedRegistryClient, FeedClient } from '@net-protocol/feeds';
14
+ import { FeedRegistryClient, FeedClient, AgentRegistryClient } from '@net-protocol/feeds';
15
15
  import { isNetrSupportedChain, NetrClient } from '@net-protocol/netr';
16
16
  import { PROFILE_PICTURE_STORAGE_KEY, PROFILE_METADATA_STORAGE_KEY, parseProfileMetadata, PROFILE_CANVAS_STORAGE_KEY, isValidUrl, getProfilePictureStorageArgs, STORAGE_CONTRACT, isValidXUsername, getProfileMetadataStorageArgs, isValidBio, isValidTokenAddress } from '@net-protocol/profiles';
17
17
  import { base } from 'viem/chains';
@@ -264,7 +264,7 @@ function prepareNormalStorageTransaction(storageClient, args, originalStorageKey
264
264
  };
265
265
  }
266
266
  function prepareXmlStorageTransactions(params) {
267
- const { storageClient, storageKey, text, content, operatorAddress } = params;
267
+ const { storageClient, storageKey, text, content, operatorAddress, chunkSize } = params;
268
268
  const storageKeyBytes = getStorageKeyBytes(storageKey);
269
269
  const result = storageClient.prepareXmlStorage({
270
270
  data: content,
@@ -272,8 +272,9 @@ function prepareXmlStorageTransactions(params) {
272
272
  storageKey,
273
273
  // Pass as string, not bytes32
274
274
  filename: text,
275
- useChunkedStorageBackend: true
275
+ useChunkedStorageBackend: true,
276
276
  // Use ChunkedStorage backend (default)
277
+ chunkSize
277
278
  });
278
279
  const transactions = result.transactionConfigs.map(
279
280
  (tx, index) => {
@@ -550,7 +551,8 @@ async function uploadFile(options) {
550
551
  storageKey: options.storageKey,
551
552
  text: options.text,
552
553
  content: fileContent,
553
- operatorAddress
554
+ operatorAddress,
555
+ chunkSize: options.chunkSize
554
556
  });
555
557
  } else {
556
558
  const storageKeyBytes = getStorageKeyBytes(
@@ -791,7 +793,8 @@ async function uploadFileWithRelay(options) {
791
793
  operatorAddress: backendWalletAddress,
792
794
  storageKey: options.storageKey,
793
795
  filename: options.text,
794
- useChunkedStorageBackend: true
796
+ useChunkedStorageBackend: true,
797
+ chunkSize: options.chunkSize
795
798
  });
796
799
  const chunkTxs = chunkPrepareResult.transactionConfigs.slice(1);
797
800
  const topLevelHash = chunkPrepareResult.topLevelHash;
@@ -999,7 +1002,8 @@ async function previewFile(options) {
999
1002
  storageKey: options.storageKey,
1000
1003
  text: options.text,
1001
1004
  content: fileContent,
1002
- operatorAddress
1005
+ operatorAddress,
1006
+ chunkSize: options.chunkSize
1003
1007
  });
1004
1008
  } else {
1005
1009
  const storageKeyBytes = getStorageKeyBytes(
@@ -1260,7 +1264,8 @@ async function encodeStorageUpload(options) {
1260
1264
  data: fileContent,
1261
1265
  operatorAddress,
1262
1266
  storageKey: options.storageKey,
1263
- filename: options.text
1267
+ filename: options.text,
1268
+ chunkSize: options.chunkSize
1264
1269
  });
1265
1270
  const encodedTransactions = transactionConfigs.map(
1266
1271
  (config) => encodeTransaction(config, readOnlyOptions.chainId)
@@ -1290,8 +1295,6 @@ async function encodeStorageUpload(options) {
1290
1295
  };
1291
1296
  }
1292
1297
  }
1293
-
1294
- // src/commands/storage/index.ts
1295
1298
  function registerStorageCommand(program2) {
1296
1299
  const storageCommand = program2.command("storage").description("Storage operations");
1297
1300
  const uploadCommand = new Command("upload").description("Upload files to Net Storage").requiredOption("--file <path>", "Path to file to upload").requiredOption("--key <key>", "Storage key (filename/identifier)").requiredOption("--text <text>", "Text description/filename").option(
@@ -1307,6 +1310,10 @@ function registerStorageCommand(program2) {
1307
1310
  ).option(
1308
1311
  "--encode-only",
1309
1312
  "Output transaction data as JSON instead of executing"
1313
+ ).option(
1314
+ "--chunk-size <bytes>",
1315
+ `Max chunk size in bytes for splitting large files (default: ${OPTIMAL_CHUNK_SIZE})`,
1316
+ (value) => parseInt(value, 10)
1310
1317
  ).action(async (options) => {
1311
1318
  if (options.encodeOnly) {
1312
1319
  try {
@@ -1316,7 +1323,8 @@ function registerStorageCommand(program2) {
1316
1323
  text: options.text,
1317
1324
  privateKey: options.privateKey,
1318
1325
  chainId: options.chainId,
1319
- rpcUrl: options.rpcUrl
1326
+ rpcUrl: options.rpcUrl,
1327
+ chunkSize: options.chunkSize
1320
1328
  });
1321
1329
  console.log(JSON.stringify(result, null, 2));
1322
1330
  process.exit(0);
@@ -1345,7 +1353,8 @@ function registerStorageCommand(program2) {
1345
1353
  text: options.text,
1346
1354
  privateKey: commonOptions.privateKey,
1347
1355
  chainId: commonOptions.chainId,
1348
- rpcUrl: commonOptions.rpcUrl
1356
+ rpcUrl: commonOptions.rpcUrl,
1357
+ chunkSize: options.chunkSize
1349
1358
  };
1350
1359
  try {
1351
1360
  console.log(chalk4.blue(`\u{1F4C1} Reading file: ${options.file}`));
@@ -1410,6 +1419,10 @@ function registerStorageCommand(program2) {
1410
1419
  ).option(
1411
1420
  "--rpc-url <url>",
1412
1421
  "Custom RPC URL (can also be set via NET_RPC_URL env var)"
1422
+ ).option(
1423
+ "--chunk-size <bytes>",
1424
+ `Max chunk size in bytes for splitting large files (default: ${OPTIMAL_CHUNK_SIZE})`,
1425
+ (value) => parseInt(value, 10)
1413
1426
  ).action(async (options) => {
1414
1427
  const commonOptions = parseCommonOptions({
1415
1428
  privateKey: options.privateKey,
@@ -1422,7 +1435,8 @@ function registerStorageCommand(program2) {
1422
1435
  text: options.text,
1423
1436
  privateKey: commonOptions.privateKey,
1424
1437
  chainId: commonOptions.chainId,
1425
- rpcUrl: commonOptions.rpcUrl
1438
+ rpcUrl: commonOptions.rpcUrl,
1439
+ chunkSize: options.chunkSize
1426
1440
  };
1427
1441
  try {
1428
1442
  console.log(chalk4.blue(`\u{1F4C1} Reading file: ${options.file}`));
@@ -1504,6 +1518,10 @@ function registerStorageCommand(program2) {
1504
1518
  ).option(
1505
1519
  "--rpc-url <url>",
1506
1520
  "Custom RPC URL (can also be set via NET_RPC_URL env var)"
1521
+ ).option(
1522
+ "--chunk-size <bytes>",
1523
+ `Max chunk size in bytes for splitting large files (default: ${OPTIMAL_CHUNK_SIZE})`,
1524
+ (value) => parseInt(value, 10)
1507
1525
  ).action(async (options) => {
1508
1526
  const commonOptions = parseCommonOptions({
1509
1527
  privateKey: options.privateKey,
@@ -1527,7 +1545,8 @@ function registerStorageCommand(program2) {
1527
1545
  chainId: commonOptions.chainId,
1528
1546
  rpcUrl: commonOptions.rpcUrl,
1529
1547
  apiUrl: options.apiUrl,
1530
- secretKey
1548
+ secretKey,
1549
+ chunkSize: options.chunkSize
1531
1550
  };
1532
1551
  try {
1533
1552
  console.log(chalk4.blue(`\u{1F4C1} Reading file: ${options.file}`));
@@ -1622,6 +1641,12 @@ function createNetClient(options) {
1622
1641
  overrides: options.rpcUrl ? { rpcUrls: [options.rpcUrl] } : void 0
1623
1642
  });
1624
1643
  }
1644
+ function createAgentRegistryClient(options) {
1645
+ return new AgentRegistryClient({
1646
+ chainId: options.chainId,
1647
+ overrides: options.rpcUrl ? { rpcUrls: [options.rpcUrl] } : void 0
1648
+ });
1649
+ }
1625
1650
 
1626
1651
  // src/commands/message/send.ts
1627
1652
  function prepareMessageConfig(client, options) {
@@ -6365,6 +6390,73 @@ function registerFeedHistoryCommand(parent) {
6365
6390
  await executeFeedHistory(options);
6366
6391
  });
6367
6392
  }
6393
+ async function executeRegisterAgent(options) {
6394
+ if (options.encodeOnly) {
6395
+ const readOnlyOptions = parseReadOnlyOptionsWithDefault({
6396
+ chainId: options.chainId,
6397
+ rpcUrl: options.rpcUrl
6398
+ });
6399
+ const client2 = createAgentRegistryClient(readOnlyOptions);
6400
+ const txConfig2 = client2.prepareRegisterAgent();
6401
+ const encoded = encodeTransaction(txConfig2, readOnlyOptions.chainId);
6402
+ printJson(encoded);
6403
+ return;
6404
+ }
6405
+ const commonOptions = parseCommonOptionsWithDefault(
6406
+ {
6407
+ privateKey: options.privateKey,
6408
+ chainId: options.chainId,
6409
+ rpcUrl: options.rpcUrl
6410
+ },
6411
+ true
6412
+ // supports --encode-only
6413
+ );
6414
+ const client = createAgentRegistryClient(commonOptions);
6415
+ const walletClient = createWallet(
6416
+ commonOptions.privateKey,
6417
+ commonOptions.chainId,
6418
+ commonOptions.rpcUrl
6419
+ );
6420
+ const isRegistered = await client.isAgentRegistered(walletClient.account.address);
6421
+ if (isRegistered) {
6422
+ exitWithError(`Address ${walletClient.account.address} is already registered as an agent`);
6423
+ }
6424
+ console.log(chalk4.blue(`Registering agent ${walletClient.account.address}...`));
6425
+ const txConfig = client.prepareRegisterAgent();
6426
+ try {
6427
+ const hash = await executeTransaction(walletClient, txConfig);
6428
+ addHistoryEntry({
6429
+ type: "register",
6430
+ txHash: hash,
6431
+ chainId: commonOptions.chainId,
6432
+ feed: "agent-registry",
6433
+ sender: walletClient.account.address
6434
+ });
6435
+ console.log(
6436
+ chalk4.green(
6437
+ `Agent registered successfully!
6438
+ Transaction: ${hash}
6439
+ Address: ${walletClient.account.address}`
6440
+ )
6441
+ );
6442
+ } catch (error) {
6443
+ exitWithError(
6444
+ `Failed to register agent: ${error instanceof Error ? error.message : String(error)}`
6445
+ );
6446
+ }
6447
+ }
6448
+ function registerAgentRegisterCommand(parent) {
6449
+ parent.command("register-agent").description("Register your address on the agent leaderboard").option(
6450
+ "--chain-id <id>",
6451
+ "Chain ID (default: 8453 for Base)",
6452
+ (value) => parseInt(value, 10)
6453
+ ).option("--rpc-url <url>", "Custom RPC URL").option("--private-key <key>", "Private key (0x-prefixed)").option(
6454
+ "--encode-only",
6455
+ "Output transaction data as JSON instead of executing"
6456
+ ).action(async (options) => {
6457
+ await executeRegisterAgent(options);
6458
+ });
6459
+ }
6368
6460
 
6369
6461
  // src/commands/feed/index.ts
6370
6462
  function registerFeedCommand(program2) {
@@ -6379,6 +6471,7 @@ function registerFeedCommand(program2) {
6379
6471
  registerFeedPostsCommand(feedCommand);
6380
6472
  registerFeedConfigCommand(feedCommand);
6381
6473
  registerFeedHistoryCommand(feedCommand);
6474
+ registerAgentRegisterCommand(feedCommand);
6382
6475
  }
6383
6476
 
6384
6477
  // src/cli/index.ts