@net-protocol/cli 0.1.6 → 0.1.7
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 +37 -0
- package/dist/cli/index.mjs +155 -31
- package/dist/cli/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -363,6 +363,7 @@ Profile operations for managing your Net Protocol profile.
|
|
|
363
363
|
- `profile get` - Get profile data for an address
|
|
364
364
|
- `profile set-picture` - Set your profile picture URL
|
|
365
365
|
- `profile set-x-username` - Set your X (Twitter) username
|
|
366
|
+
- `profile set-bio` - Set your profile bio
|
|
366
367
|
|
|
367
368
|
##### Profile Get
|
|
368
369
|
|
|
@@ -476,6 +477,42 @@ netp profile set-x-username \
|
|
|
476
477
|
--encode-only
|
|
477
478
|
```
|
|
478
479
|
|
|
480
|
+
##### Profile Set Bio
|
|
481
|
+
|
|
482
|
+
Set your profile bio (max 280 characters).
|
|
483
|
+
|
|
484
|
+
```bash
|
|
485
|
+
netp profile set-bio \
|
|
486
|
+
--bio <bio-text> \
|
|
487
|
+
[--private-key <0x...>] \
|
|
488
|
+
[--chain-id <8453|1|...>] \
|
|
489
|
+
[--rpc-url <custom-rpc>] \
|
|
490
|
+
[--encode-only]
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
**Profile Set Bio Arguments:**
|
|
494
|
+
|
|
495
|
+
- `--bio` (required): Your profile bio (max 280 characters, no control characters)
|
|
496
|
+
- `--private-key` (optional): Private key. Can also be set via `NET_PRIVATE_KEY` environment variable
|
|
497
|
+
- `--chain-id` (optional): Chain ID. Can also be set via `NET_CHAIN_ID` environment variable
|
|
498
|
+
- `--rpc-url` (optional): Custom RPC URL. Can also be set via `NET_RPC_URL` environment variable
|
|
499
|
+
- `--encode-only` (optional): Output transaction data as JSON instead of executing
|
|
500
|
+
|
|
501
|
+
**Example:**
|
|
502
|
+
|
|
503
|
+
```bash
|
|
504
|
+
# Set bio
|
|
505
|
+
netp profile set-bio \
|
|
506
|
+
--bio "Building cool stuff on Net Protocol" \
|
|
507
|
+
--chain-id 8453
|
|
508
|
+
|
|
509
|
+
# Encode-only
|
|
510
|
+
netp profile set-bio \
|
|
511
|
+
--bio "Building cool stuff on Net Protocol" \
|
|
512
|
+
--chain-id 8453 \
|
|
513
|
+
--encode-only
|
|
514
|
+
```
|
|
515
|
+
|
|
479
516
|
#### Info Command
|
|
480
517
|
|
|
481
518
|
Show contract info and stats.
|
package/dist/cli/index.mjs
CHANGED
|
@@ -11,7 +11,7 @@ import { privateKeyToAccount } from 'viem/accounts';
|
|
|
11
11
|
import { getNetContract, getChainName, getPublicClient, getChainRpcUrls, NetClient } from '@net-protocol/core';
|
|
12
12
|
import { createRelayX402Client, createRelaySession, checkBackendWalletBalance, fundBackendWallet, batchTransactions, submitTransactionsViaRelay, waitForConfirmations, retryFailedTransactions as retryFailedTransactions$1 } from '@net-protocol/relay';
|
|
13
13
|
import { isNetrSupportedChain, NetrClient } from '@net-protocol/netr';
|
|
14
|
-
import { PROFILE_PICTURE_STORAGE_KEY, PROFILE_METADATA_STORAGE_KEY, parseProfileMetadata, isValidUrl, getProfilePictureStorageArgs, STORAGE_CONTRACT, isValidXUsername, getXUsernameStorageArgs } from '@net-protocol/profiles';
|
|
14
|
+
import { PROFILE_PICTURE_STORAGE_KEY, PROFILE_METADATA_STORAGE_KEY, parseProfileMetadata, isValidUrl, getProfilePictureStorageArgs, STORAGE_CONTRACT, isValidXUsername, getXUsernameStorageArgs, isValidBio, getProfileMetadataStorageArgs } from '@net-protocol/profiles';
|
|
15
15
|
import { base } from 'viem/chains';
|
|
16
16
|
|
|
17
17
|
function getRequiredChainId(optionValue) {
|
|
@@ -29,12 +29,13 @@ function getRequiredChainId(optionValue) {
|
|
|
29
29
|
function getRpcUrl(optionValue) {
|
|
30
30
|
return optionValue || process.env.NET_RPC_URL;
|
|
31
31
|
}
|
|
32
|
-
function parseCommonOptions(options) {
|
|
32
|
+
function parseCommonOptions(options, supportsEncodeOnly = false) {
|
|
33
33
|
const privateKey = options.privateKey || process.env.NET_PRIVATE_KEY || process.env.PRIVATE_KEY;
|
|
34
34
|
if (!privateKey) {
|
|
35
|
+
const encodeOnlyHint = supportsEncodeOnly ? ", or use --encode-only to output transaction data without submitting" : "";
|
|
35
36
|
console.error(
|
|
36
37
|
chalk4.red(
|
|
37
|
-
|
|
38
|
+
`Error: Private key is required. Provide via --private-key flag or NET_PRIVATE_KEY/PRIVATE_KEY environment variable${encodeOnlyHint}`
|
|
38
39
|
)
|
|
39
40
|
);
|
|
40
41
|
process.exit(1);
|
|
@@ -1271,11 +1272,15 @@ function registerStorageCommand(program2) {
|
|
|
1271
1272
|
}
|
|
1272
1273
|
return;
|
|
1273
1274
|
}
|
|
1274
|
-
const commonOptions = parseCommonOptions(
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1275
|
+
const commonOptions = parseCommonOptions(
|
|
1276
|
+
{
|
|
1277
|
+
privateKey: options.privateKey,
|
|
1278
|
+
chainId: options.chainId,
|
|
1279
|
+
rpcUrl: options.rpcUrl
|
|
1280
|
+
},
|
|
1281
|
+
true
|
|
1282
|
+
// supports --encode-only
|
|
1283
|
+
);
|
|
1279
1284
|
const uploadOptions = {
|
|
1280
1285
|
filePath: options.file,
|
|
1281
1286
|
storageKey: options.key,
|
|
@@ -1470,8 +1475,8 @@ function registerStorageCommand(program2) {
|
|
|
1470
1475
|
console.log(chalk4.blue(`\u{1F4C1} Reading file: ${options.file}`));
|
|
1471
1476
|
console.log(chalk4.blue(`\u{1F517} Using relay API: ${options.apiUrl}`));
|
|
1472
1477
|
const result = await uploadFileWithRelay(uploadRelayOptions);
|
|
1473
|
-
const { privateKeyToAccount:
|
|
1474
|
-
const userAccount =
|
|
1478
|
+
const { privateKeyToAccount: privateKeyToAccount9 } = await import('viem/accounts');
|
|
1479
|
+
const userAccount = privateKeyToAccount9(commonOptions.privateKey);
|
|
1475
1480
|
const storageUrl = generateStorageUrl(
|
|
1476
1481
|
userAccount.address,
|
|
1477
1482
|
commonOptions.chainId,
|
|
@@ -1561,11 +1566,15 @@ async function executeSend(options) {
|
|
|
1561
1566
|
executeEncodeOnly(options);
|
|
1562
1567
|
return;
|
|
1563
1568
|
}
|
|
1564
|
-
const commonOptions = parseCommonOptions(
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
+
const commonOptions = parseCommonOptions(
|
|
1570
|
+
{
|
|
1571
|
+
privateKey: options.privateKey,
|
|
1572
|
+
chainId: options.chainId,
|
|
1573
|
+
rpcUrl: options.rpcUrl
|
|
1574
|
+
},
|
|
1575
|
+
true
|
|
1576
|
+
// supports --encode-only
|
|
1577
|
+
);
|
|
1569
1578
|
const client = createNetClient(commonOptions);
|
|
1570
1579
|
const txConfig = prepareMessageConfig(client, options);
|
|
1571
1580
|
const account = privateKeyToAccount(commonOptions.privateKey);
|
|
@@ -1975,11 +1984,15 @@ async function executeTokenDeploy(options) {
|
|
|
1975
1984
|
await executeEncodeOnly2(options);
|
|
1976
1985
|
return;
|
|
1977
1986
|
}
|
|
1978
|
-
const commonOptions = parseCommonOptions(
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1987
|
+
const commonOptions = parseCommonOptions(
|
|
1988
|
+
{
|
|
1989
|
+
privateKey: options.privateKey,
|
|
1990
|
+
chainId: options.chainId,
|
|
1991
|
+
rpcUrl: options.rpcUrl
|
|
1992
|
+
},
|
|
1993
|
+
true
|
|
1994
|
+
// supports --encode-only
|
|
1995
|
+
);
|
|
1983
1996
|
if (!isNetrSupportedChain(commonOptions.chainId)) {
|
|
1984
1997
|
exitWithError(
|
|
1985
1998
|
`Chain ${commonOptions.chainId} is not supported for token deployment. Supported: Base (8453), Plasma (9745), Monad (143), HyperEVM (999)`
|
|
@@ -2244,6 +2257,7 @@ async function executeProfileGet(options) {
|
|
|
2244
2257
|
}
|
|
2245
2258
|
}
|
|
2246
2259
|
let xUsername;
|
|
2260
|
+
let bio;
|
|
2247
2261
|
try {
|
|
2248
2262
|
const metadataResult = await client.readStorageData({
|
|
2249
2263
|
key: PROFILE_METADATA_STORAGE_KEY,
|
|
@@ -2252,6 +2266,7 @@ async function executeProfileGet(options) {
|
|
|
2252
2266
|
if (metadataResult.data) {
|
|
2253
2267
|
const metadata = parseProfileMetadata(metadataResult.data);
|
|
2254
2268
|
xUsername = metadata?.x_username;
|
|
2269
|
+
bio = metadata?.bio;
|
|
2255
2270
|
}
|
|
2256
2271
|
} catch (error) {
|
|
2257
2272
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -2259,13 +2274,14 @@ async function executeProfileGet(options) {
|
|
|
2259
2274
|
throw error;
|
|
2260
2275
|
}
|
|
2261
2276
|
}
|
|
2262
|
-
const hasProfile = profilePicture || xUsername;
|
|
2277
|
+
const hasProfile = profilePicture || xUsername || bio;
|
|
2263
2278
|
if (options.json) {
|
|
2264
2279
|
const output = {
|
|
2265
2280
|
address: options.address,
|
|
2266
2281
|
chainId: readOnlyOptions.chainId,
|
|
2267
2282
|
profilePicture: profilePicture || null,
|
|
2268
2283
|
xUsername: xUsername || null,
|
|
2284
|
+
bio: bio || null,
|
|
2269
2285
|
hasProfile
|
|
2270
2286
|
};
|
|
2271
2287
|
console.log(JSON.stringify(output, null, 2));
|
|
@@ -2280,6 +2296,9 @@ async function executeProfileGet(options) {
|
|
|
2280
2296
|
console.log(
|
|
2281
2297
|
` ${chalk4.cyan("X Username:")} ${xUsername ? `@${xUsername}` : chalk4.gray("(not set)")}`
|
|
2282
2298
|
);
|
|
2299
|
+
console.log(
|
|
2300
|
+
` ${chalk4.cyan("Bio:")} ${bio || chalk4.gray("(not set)")}`
|
|
2301
|
+
);
|
|
2283
2302
|
if (!hasProfile) {
|
|
2284
2303
|
console.log(chalk4.yellow("\n No profile data found for this address."));
|
|
2285
2304
|
}
|
|
@@ -2314,11 +2333,15 @@ async function executeProfileSetPicture(options) {
|
|
|
2314
2333
|
console.log(JSON.stringify(encoded, null, 2));
|
|
2315
2334
|
return;
|
|
2316
2335
|
}
|
|
2317
|
-
const commonOptions = parseCommonOptions(
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2336
|
+
const commonOptions = parseCommonOptions(
|
|
2337
|
+
{
|
|
2338
|
+
privateKey: options.privateKey,
|
|
2339
|
+
chainId: options.chainId,
|
|
2340
|
+
rpcUrl: options.rpcUrl
|
|
2341
|
+
},
|
|
2342
|
+
true
|
|
2343
|
+
// supports --encode-only
|
|
2344
|
+
);
|
|
2322
2345
|
try {
|
|
2323
2346
|
const account = privateKeyToAccount(commonOptions.privateKey);
|
|
2324
2347
|
const rpcUrls = getChainRpcUrls({
|
|
@@ -2385,11 +2408,15 @@ async function executeProfileSetUsername(options) {
|
|
|
2385
2408
|
console.log(JSON.stringify(encoded, null, 2));
|
|
2386
2409
|
return;
|
|
2387
2410
|
}
|
|
2388
|
-
const commonOptions = parseCommonOptions(
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2411
|
+
const commonOptions = parseCommonOptions(
|
|
2412
|
+
{
|
|
2413
|
+
privateKey: options.privateKey,
|
|
2414
|
+
chainId: options.chainId,
|
|
2415
|
+
rpcUrl: options.rpcUrl
|
|
2416
|
+
},
|
|
2417
|
+
true
|
|
2418
|
+
// supports --encode-only
|
|
2419
|
+
);
|
|
2393
2420
|
try {
|
|
2394
2421
|
const account = privateKeyToAccount(commonOptions.privateKey);
|
|
2395
2422
|
const rpcUrls = getChainRpcUrls({
|
|
@@ -2431,6 +2458,80 @@ async function executeProfileSetUsername(options) {
|
|
|
2431
2458
|
);
|
|
2432
2459
|
}
|
|
2433
2460
|
}
|
|
2461
|
+
async function executeProfileSetBio(options) {
|
|
2462
|
+
if (!isValidBio(options.bio)) {
|
|
2463
|
+
exitWithError(
|
|
2464
|
+
`Invalid bio: "${options.bio}". Bio must be 1-280 characters and cannot contain control characters.`
|
|
2465
|
+
);
|
|
2466
|
+
}
|
|
2467
|
+
const storageArgs = getProfileMetadataStorageArgs({ bio: options.bio });
|
|
2468
|
+
if (options.encodeOnly) {
|
|
2469
|
+
const readOnlyOptions = parseReadOnlyOptions({
|
|
2470
|
+
chainId: options.chainId,
|
|
2471
|
+
rpcUrl: options.rpcUrl
|
|
2472
|
+
});
|
|
2473
|
+
const encoded = encodeTransaction(
|
|
2474
|
+
{
|
|
2475
|
+
to: STORAGE_CONTRACT.address,
|
|
2476
|
+
abi: STORAGE_CONTRACT.abi,
|
|
2477
|
+
functionName: "put",
|
|
2478
|
+
args: [storageArgs.bytesKey, storageArgs.topic, storageArgs.bytesValue]
|
|
2479
|
+
},
|
|
2480
|
+
readOnlyOptions.chainId
|
|
2481
|
+
);
|
|
2482
|
+
console.log(JSON.stringify(encoded, null, 2));
|
|
2483
|
+
return;
|
|
2484
|
+
}
|
|
2485
|
+
const commonOptions = parseCommonOptions(
|
|
2486
|
+
{
|
|
2487
|
+
privateKey: options.privateKey,
|
|
2488
|
+
chainId: options.chainId,
|
|
2489
|
+
rpcUrl: options.rpcUrl
|
|
2490
|
+
},
|
|
2491
|
+
true
|
|
2492
|
+
// supports --encode-only
|
|
2493
|
+
);
|
|
2494
|
+
try {
|
|
2495
|
+
const account = privateKeyToAccount(commonOptions.privateKey);
|
|
2496
|
+
const rpcUrls = getChainRpcUrls({
|
|
2497
|
+
chainId: commonOptions.chainId,
|
|
2498
|
+
rpcUrl: commonOptions.rpcUrl
|
|
2499
|
+
});
|
|
2500
|
+
const client = createWalletClient({
|
|
2501
|
+
account,
|
|
2502
|
+
chain: base,
|
|
2503
|
+
// TODO: Support other chains
|
|
2504
|
+
transport: http(rpcUrls[0])
|
|
2505
|
+
}).extend(publicActions);
|
|
2506
|
+
console.log(chalk4.blue(`Setting profile bio...`));
|
|
2507
|
+
console.log(chalk4.gray(` Bio: ${options.bio}`));
|
|
2508
|
+
console.log(chalk4.gray(` Address: ${account.address}`));
|
|
2509
|
+
const hash = await client.writeContract({
|
|
2510
|
+
address: STORAGE_CONTRACT.address,
|
|
2511
|
+
abi: STORAGE_CONTRACT.abi,
|
|
2512
|
+
functionName: "put",
|
|
2513
|
+
args: [storageArgs.bytesKey, storageArgs.topic, storageArgs.bytesValue]
|
|
2514
|
+
});
|
|
2515
|
+
console.log(chalk4.blue(`Waiting for confirmation...`));
|
|
2516
|
+
const receipt = await client.waitForTransactionReceipt({ hash });
|
|
2517
|
+
if (receipt.status === "success") {
|
|
2518
|
+
console.log(
|
|
2519
|
+
chalk4.green(
|
|
2520
|
+
`
|
|
2521
|
+
Bio updated successfully!
|
|
2522
|
+
Transaction: ${hash}
|
|
2523
|
+
Bio: ${options.bio}`
|
|
2524
|
+
)
|
|
2525
|
+
);
|
|
2526
|
+
} else {
|
|
2527
|
+
exitWithError(`Transaction failed: ${hash}`);
|
|
2528
|
+
}
|
|
2529
|
+
} catch (error) {
|
|
2530
|
+
exitWithError(
|
|
2531
|
+
`Failed to set bio: ${error instanceof Error ? error.message : String(error)}`
|
|
2532
|
+
);
|
|
2533
|
+
}
|
|
2534
|
+
}
|
|
2434
2535
|
|
|
2435
2536
|
// src/commands/profile/index.ts
|
|
2436
2537
|
function registerProfileCommand(program2) {
|
|
@@ -2497,9 +2598,32 @@ function registerProfileCommand(program2) {
|
|
|
2497
2598
|
encodeOnly: options.encodeOnly
|
|
2498
2599
|
});
|
|
2499
2600
|
});
|
|
2601
|
+
const setBioCommand = new Command("set-bio").description("Set your profile bio").requiredOption("--bio <bio>", "Your profile bio (max 280 characters)").option(
|
|
2602
|
+
"--private-key <key>",
|
|
2603
|
+
"Private key (0x-prefixed hex, 66 characters). Can also be set via NET_PRIVATE_KEY env var"
|
|
2604
|
+
).option(
|
|
2605
|
+
"--chain-id <id>",
|
|
2606
|
+
"Chain ID. Can also be set via NET_CHAIN_ID env var",
|
|
2607
|
+
(value) => parseInt(value, 10)
|
|
2608
|
+
).option(
|
|
2609
|
+
"--rpc-url <url>",
|
|
2610
|
+
"Custom RPC URL. Can also be set via NET_RPC_URL env var"
|
|
2611
|
+
).option(
|
|
2612
|
+
"--encode-only",
|
|
2613
|
+
"Output transaction data as JSON instead of executing"
|
|
2614
|
+
).action(async (options) => {
|
|
2615
|
+
await executeProfileSetBio({
|
|
2616
|
+
bio: options.bio,
|
|
2617
|
+
privateKey: options.privateKey,
|
|
2618
|
+
chainId: options.chainId,
|
|
2619
|
+
rpcUrl: options.rpcUrl,
|
|
2620
|
+
encodeOnly: options.encodeOnly
|
|
2621
|
+
});
|
|
2622
|
+
});
|
|
2500
2623
|
profileCommand.addCommand(getCommand);
|
|
2501
2624
|
profileCommand.addCommand(setPictureCommand);
|
|
2502
2625
|
profileCommand.addCommand(setUsernameCommand);
|
|
2626
|
+
profileCommand.addCommand(setBioCommand);
|
|
2503
2627
|
}
|
|
2504
2628
|
|
|
2505
2629
|
// src/cli/index.ts
|