@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 +14 -3
- package/dist/cli/index.mjs +107 -14
- package/dist/cli/index.mjs.map +1 -1
- package/dist/feed/index.d.ts +6 -1
- package/dist/feed/index.mjs +76 -2
- package/dist/feed/index.mjs.map +1 -1
- package/package.json +3 -3
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)
|
package/dist/cli/index.mjs
CHANGED
|
@@ -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
|