@net-protocol/cli 0.1.20 → 0.1.22

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
@@ -375,6 +375,7 @@ Profile operations for managing your Net Protocol profile.
375
375
  - `profile set-picture` - Set your profile picture URL
376
376
  - `profile set-x-username` - Set your X (Twitter) username
377
377
  - `profile set-bio` - Set your profile bio
378
+ - `profile set-display-name` - Set your profile display name
378
379
  - `profile set-token-address` - Set your profile token address (ERC-20 token)
379
380
  - `profile set-canvas` - Set your profile canvas (HTML content)
380
381
  - `profile get-canvas` - Get profile canvas for an address
@@ -527,6 +528,42 @@ netp profile set-bio \
527
528
  --encode-only
528
529
  ```
529
530
 
531
+ ##### Profile Set Display Name
532
+
533
+ Set your profile display name (max 25 characters).
534
+
535
+ ```bash
536
+ netp profile set-display-name \
537
+ --name <display-name> \
538
+ [--private-key <0x...>] \
539
+ [--chain-id <8453|1|...>] \
540
+ [--rpc-url <custom-rpc>] \
541
+ [--encode-only]
542
+ ```
543
+
544
+ **Profile Set Display Name Arguments:**
545
+
546
+ - `--name` (required): Your display name (max 25 characters, no control characters)
547
+ - `--private-key` (optional): Private key. Can also be set via `NET_PRIVATE_KEY` environment variable
548
+ - `--chain-id` (optional): Chain ID. Can also be set via `NET_CHAIN_ID` environment variable
549
+ - `--rpc-url` (optional): Custom RPC URL. Can also be set via `NET_RPC_URL` environment variable
550
+ - `--encode-only` (optional): Output transaction data as JSON instead of executing
551
+
552
+ **Example:**
553
+
554
+ ```bash
555
+ # Set display name
556
+ netp profile set-display-name \
557
+ --name "Alice" \
558
+ --chain-id 8453
559
+
560
+ # Encode-only
561
+ netp profile set-display-name \
562
+ --name "Alice" \
563
+ --chain-id 8453 \
564
+ --encode-only
565
+ ```
566
+
530
567
  ##### Profile Set Token Address
531
568
 
532
569
  Set an ERC-20 token address that represents you on your profile.
@@ -11,9 +11,9 @@ import { stringToHex, createWalletClient, http, hexToString, parseEther, encodeF
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
- 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';
16
+ import { PROFILE_PICTURE_STORAGE_KEY, PROFILE_METADATA_STORAGE_KEY, parseProfileMetadata, PROFILE_CANVAS_STORAGE_KEY, isValidUrl, getProfilePictureStorageArgs, STORAGE_CONTRACT, isValidXUsername, getProfileMetadataStorageArgs, isValidBio, isValidDisplayName, isValidTokenAddress } from '@net-protocol/profiles';
17
17
  import { base } from 'viem/chains';
18
18
  import * as path from 'path';
19
19
  import { BazaarClient } from '@net-protocol/bazaar';
@@ -1558,8 +1558,8 @@ function registerStorageCommand(program2) {
1558
1558
  console.log(chalk4.blue(`\u{1F4C1} Reading file: ${options.file}`));
1559
1559
  console.log(chalk4.blue(`\u{1F517} Using relay API: ${options.apiUrl}`));
1560
1560
  const result = await uploadFileWithRelay(uploadRelayOptions);
1561
- const { privateKeyToAccount: privateKeyToAccount24 } = await import('viem/accounts');
1562
- const userAccount = privateKeyToAccount24(commonOptions.privateKey);
1561
+ const { privateKeyToAccount: privateKeyToAccount25 } = await import('viem/accounts');
1562
+ const userAccount = privateKeyToAccount25(commonOptions.privateKey);
1563
1563
  const storageUrl = generateStorageUrl(
1564
1564
  userAccount.address,
1565
1565
  commonOptions.chainId,
@@ -1647,6 +1647,12 @@ function createNetClient(options) {
1647
1647
  overrides: options.rpcUrl ? { rpcUrls: [options.rpcUrl] } : void 0
1648
1648
  });
1649
1649
  }
1650
+ function createAgentRegistryClient(options) {
1651
+ return new AgentRegistryClient({
1652
+ chainId: options.chainId,
1653
+ overrides: options.rpcUrl ? { rpcUrls: [options.rpcUrl] } : void 0
1654
+ });
1655
+ }
1650
1656
 
1651
1657
  // src/commands/message/send.ts
1652
1658
  function prepareMessageConfig(client, options) {
@@ -2710,6 +2716,96 @@ Bio updated successfully!
2710
2716
  );
2711
2717
  }
2712
2718
  }
2719
+ async function executeProfileSetDisplayName(options) {
2720
+ if (!isValidDisplayName(options.name)) {
2721
+ exitWithError(
2722
+ `Invalid display name: "${options.name}". Display name must be 1-25 characters and cannot contain control characters.`
2723
+ );
2724
+ }
2725
+ if (options.encodeOnly) {
2726
+ const readOnlyOptions = parseReadOnlyOptions({
2727
+ chainId: options.chainId,
2728
+ rpcUrl: options.rpcUrl
2729
+ });
2730
+ const storageArgs = getProfileMetadataStorageArgs({
2731
+ display_name: options.name
2732
+ });
2733
+ const encoded = encodeTransaction(
2734
+ {
2735
+ to: STORAGE_CONTRACT.address,
2736
+ abi: STORAGE_CONTRACT.abi,
2737
+ functionName: "put",
2738
+ args: [storageArgs.bytesKey, storageArgs.topic, storageArgs.bytesValue]
2739
+ },
2740
+ readOnlyOptions.chainId
2741
+ );
2742
+ console.log(JSON.stringify(encoded, null, 2));
2743
+ return;
2744
+ }
2745
+ const commonOptions = parseCommonOptions(
2746
+ {
2747
+ privateKey: options.privateKey,
2748
+ chainId: options.chainId,
2749
+ rpcUrl: options.rpcUrl
2750
+ },
2751
+ true
2752
+ // supports --encode-only
2753
+ );
2754
+ try {
2755
+ const account = privateKeyToAccount(commonOptions.privateKey);
2756
+ const rpcUrls = getChainRpcUrls({
2757
+ chainId: commonOptions.chainId,
2758
+ rpcUrl: commonOptions.rpcUrl
2759
+ });
2760
+ const client = createWalletClient({
2761
+ account,
2762
+ chain: base,
2763
+ // TODO: Support other chains
2764
+ transport: http(rpcUrls[0])
2765
+ }).extend(publicActions);
2766
+ console.log(chalk4.blue(`Setting display name...`));
2767
+ console.log(chalk4.gray(` Name: ${options.name}`));
2768
+ console.log(chalk4.gray(` Address: ${account.address}`));
2769
+ const storageClient = new StorageClient({
2770
+ chainId: commonOptions.chainId,
2771
+ overrides: commonOptions.rpcUrl ? { rpcUrls: [commonOptions.rpcUrl] } : void 0
2772
+ });
2773
+ const existing = await readExistingMetadata(
2774
+ account.address,
2775
+ storageClient
2776
+ );
2777
+ const storageArgs = getProfileMetadataStorageArgs({
2778
+ display_name: options.name,
2779
+ bio: existing.bio,
2780
+ x_username: existing.x_username,
2781
+ token_address: existing.token_address
2782
+ });
2783
+ const hash = await client.writeContract({
2784
+ address: STORAGE_CONTRACT.address,
2785
+ abi: STORAGE_CONTRACT.abi,
2786
+ functionName: "put",
2787
+ args: [storageArgs.bytesKey, storageArgs.topic, storageArgs.bytesValue]
2788
+ });
2789
+ console.log(chalk4.blue(`Waiting for confirmation...`));
2790
+ const receipt = await client.waitForTransactionReceipt({ hash });
2791
+ if (receipt.status === "success") {
2792
+ console.log(
2793
+ chalk4.green(
2794
+ `
2795
+ Display name updated successfully!
2796
+ Transaction: ${hash}
2797
+ Name: ${options.name}`
2798
+ )
2799
+ );
2800
+ } else {
2801
+ exitWithError(`Transaction failed: ${hash}`);
2802
+ }
2803
+ } catch (error) {
2804
+ exitWithError(
2805
+ `Failed to set display name: ${error instanceof Error ? error.message : String(error)}`
2806
+ );
2807
+ }
2808
+ }
2713
2809
  async function executeProfileSetTokenAddress(options) {
2714
2810
  if (!isValidTokenAddress(options.tokenAddress)) {
2715
2811
  exitWithError(
@@ -3134,6 +3230,28 @@ function registerProfileCommand(program2) {
3134
3230
  encodeOnly: options.encodeOnly
3135
3231
  });
3136
3232
  });
3233
+ const setDisplayNameCommand = new Command("set-display-name").description("Set your profile display name").requiredOption("--name <name>", "Your display name (max 25 characters)").option(
3234
+ "--private-key <key>",
3235
+ "Private key (0x-prefixed hex, 66 characters). Can also be set via NET_PRIVATE_KEY env var"
3236
+ ).option(
3237
+ "--chain-id <id>",
3238
+ "Chain ID. Can also be set via NET_CHAIN_ID env var",
3239
+ (value) => parseInt(value, 10)
3240
+ ).option(
3241
+ "--rpc-url <url>",
3242
+ "Custom RPC URL. Can also be set via NET_RPC_URL env var"
3243
+ ).option(
3244
+ "--encode-only",
3245
+ "Output transaction data as JSON instead of executing"
3246
+ ).action(async (options) => {
3247
+ await executeProfileSetDisplayName({
3248
+ name: options.name,
3249
+ privateKey: options.privateKey,
3250
+ chainId: options.chainId,
3251
+ rpcUrl: options.rpcUrl,
3252
+ encodeOnly: options.encodeOnly
3253
+ });
3254
+ });
3137
3255
  const setTokenAddressCommand = new Command("set-token-address").description("Set your profile token address (ERC-20 token that represents you)").requiredOption(
3138
3256
  "--token-address <address>",
3139
3257
  "ERC-20 token contract address (0x-prefixed)"
@@ -3202,6 +3320,7 @@ function registerProfileCommand(program2) {
3202
3320
  profileCommand.addCommand(setPictureCommand);
3203
3321
  profileCommand.addCommand(setUsernameCommand);
3204
3322
  profileCommand.addCommand(setBioCommand);
3323
+ profileCommand.addCommand(setDisplayNameCommand);
3205
3324
  profileCommand.addCommand(setTokenAddressCommand);
3206
3325
  profileCommand.addCommand(setCanvasCommand);
3207
3326
  profileCommand.addCommand(getCanvasCommand);
@@ -6390,6 +6509,73 @@ function registerFeedHistoryCommand(parent) {
6390
6509
  await executeFeedHistory(options);
6391
6510
  });
6392
6511
  }
6512
+ async function executeRegisterAgent(options) {
6513
+ if (options.encodeOnly) {
6514
+ const readOnlyOptions = parseReadOnlyOptionsWithDefault({
6515
+ chainId: options.chainId,
6516
+ rpcUrl: options.rpcUrl
6517
+ });
6518
+ const client2 = createAgentRegistryClient(readOnlyOptions);
6519
+ const txConfig2 = client2.prepareRegisterAgent();
6520
+ const encoded = encodeTransaction(txConfig2, readOnlyOptions.chainId);
6521
+ printJson(encoded);
6522
+ return;
6523
+ }
6524
+ const commonOptions = parseCommonOptionsWithDefault(
6525
+ {
6526
+ privateKey: options.privateKey,
6527
+ chainId: options.chainId,
6528
+ rpcUrl: options.rpcUrl
6529
+ },
6530
+ true
6531
+ // supports --encode-only
6532
+ );
6533
+ const client = createAgentRegistryClient(commonOptions);
6534
+ const walletClient = createWallet(
6535
+ commonOptions.privateKey,
6536
+ commonOptions.chainId,
6537
+ commonOptions.rpcUrl
6538
+ );
6539
+ const isRegistered = await client.isAgentRegistered(walletClient.account.address);
6540
+ if (isRegistered) {
6541
+ exitWithError(`Address ${walletClient.account.address} is already registered as an agent`);
6542
+ }
6543
+ console.log(chalk4.blue(`Registering agent ${walletClient.account.address}...`));
6544
+ const txConfig = client.prepareRegisterAgent();
6545
+ try {
6546
+ const hash = await executeTransaction(walletClient, txConfig);
6547
+ addHistoryEntry({
6548
+ type: "register",
6549
+ txHash: hash,
6550
+ chainId: commonOptions.chainId,
6551
+ feed: "agent-registry",
6552
+ sender: walletClient.account.address
6553
+ });
6554
+ console.log(
6555
+ chalk4.green(
6556
+ `Agent registered successfully!
6557
+ Transaction: ${hash}
6558
+ Address: ${walletClient.account.address}`
6559
+ )
6560
+ );
6561
+ } catch (error) {
6562
+ exitWithError(
6563
+ `Failed to register agent: ${error instanceof Error ? error.message : String(error)}`
6564
+ );
6565
+ }
6566
+ }
6567
+ function registerAgentRegisterCommand(parent) {
6568
+ parent.command("register-agent").description("Register your address on the agent leaderboard").option(
6569
+ "--chain-id <id>",
6570
+ "Chain ID (default: 8453 for Base)",
6571
+ (value) => parseInt(value, 10)
6572
+ ).option("--rpc-url <url>", "Custom RPC URL").option("--private-key <key>", "Private key (0x-prefixed)").option(
6573
+ "--encode-only",
6574
+ "Output transaction data as JSON instead of executing"
6575
+ ).action(async (options) => {
6576
+ await executeRegisterAgent(options);
6577
+ });
6578
+ }
6393
6579
 
6394
6580
  // src/commands/feed/index.ts
6395
6581
  function registerFeedCommand(program2) {
@@ -6404,6 +6590,7 @@ function registerFeedCommand(program2) {
6404
6590
  registerFeedPostsCommand(feedCommand);
6405
6591
  registerFeedConfigCommand(feedCommand);
6406
6592
  registerFeedHistoryCommand(feedCommand);
6593
+ registerAgentRegisterCommand(feedCommand);
6407
6594
  }
6408
6595
 
6409
6596
  // src/cli/index.ts