@net-protocol/cli 0.1.39 → 0.1.41

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.
@@ -7,11 +7,11 @@ import chalk4 from 'chalk';
7
7
  import * as fs6 from 'fs';
8
8
  import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'fs';
9
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
- import { stringToHex, createWalletClient, http, hexToString, parseEther, encodeFunctionData, publicActions, concat, defineChain, createPublicClient, formatEther } from 'viem';
10
+ import { stringToHex, createWalletClient, http, hexToString, parseEther, encodeFunctionData, publicActions, concat, defineChain, decodeEventLog, createPublicClient, formatEther } from 'viem';
11
11
  import { privateKeyToAccount } from 'viem/accounts';
12
12
  import { getNetContract, getChainName, getPublicClient, getChainRpcUrls, getBaseDataSuffix, 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, AgentRegistryClient } from '@net-protocol/feeds';
14
+ import { isCommentTopic, parseCommentData, FeedRegistryClient, FeedClient, AgentRegistryClient, COMMENT_TOPIC_SUFFIX, FEED_TOPIC_PREFIX } from '@net-protocol/feeds';
15
15
  import '@net-protocol/chats';
16
16
  import { isNetrSupportedChain, NetrClient } from '@net-protocol/netr';
17
17
  import { PROFILE_PICTURE_STORAGE_KEY, PROFILE_METADATA_STORAGE_KEY, parseProfileMetadata, PROFILE_CANVAS_STORAGE_KEY, PROFILE_CSS_STORAGE_KEY, isValidUrl, getProfilePictureStorageArgs, STORAGE_CONTRACT, isValidXUsername, getProfileMetadataStorageArgs, isValidBio, isValidDisplayName, isValidTokenAddress, DEMO_THEMES, MAX_CSS_SIZE, isValidCSS, getProfileCSSStorageArgs, buildCSSPrompt } from '@net-protocol/profiles';
@@ -6169,6 +6169,9 @@ function registerFeedPostCommand(parent) {
6169
6169
  }
6170
6170
 
6171
6171
  // src/shared/postId.ts
6172
+ function createPostId(post) {
6173
+ return `${post.sender}:${post.timestamp}`;
6174
+ }
6172
6175
  function parsePostId(postId) {
6173
6176
  const parts = postId.split(":");
6174
6177
  if (parts.length !== 2) {
@@ -6993,6 +6996,143 @@ function registerListAgentsCommand(parent, commandName = "list-agents") {
6993
6996
  await executeListAgents(options);
6994
6997
  });
6995
6998
  }
6999
+ function extractFeedName(topic) {
7000
+ const baseTopic = isCommentTopic(topic) ? topic.split(COMMENT_TOPIC_SUFFIX)[0] : topic;
7001
+ return baseTopic.startsWith(FEED_TOPIC_PREFIX) ? baseTopic.slice(FEED_TOPIC_PREFIX.length) : baseTopic;
7002
+ }
7003
+ async function executeFeedVerifyClaim(txHash, options) {
7004
+ if (!txHash.startsWith("0x") || txHash.length !== 66) {
7005
+ exitWithError(
7006
+ "Invalid transaction hash format (must be 0x-prefixed, 66 characters)"
7007
+ );
7008
+ }
7009
+ const readOnlyOptions = parseReadOnlyOptionsWithDefault({
7010
+ chainId: options.chainId,
7011
+ rpcUrl: options.rpcUrl
7012
+ });
7013
+ const publicClient = getPublicClient({
7014
+ chainId: readOnlyOptions.chainId,
7015
+ rpcUrl: readOnlyOptions.rpcUrl
7016
+ });
7017
+ const netContract = getNetContract(readOnlyOptions.chainId);
7018
+ const netClient = createNetClient(readOnlyOptions);
7019
+ const existingHistory = getHistory();
7020
+ if (existingHistory.some((entry) => entry.txHash === txHash)) {
7021
+ console.log(
7022
+ chalk4.yellow("Transaction already recorded in history. Skipping.")
7023
+ );
7024
+ return;
7025
+ }
7026
+ const receipt = await publicClient.getTransactionReceipt({ hash: txHash }).catch(
7027
+ () => exitWithError(
7028
+ "Could not fetch transaction receipt. Make sure the transaction hash is correct and the transaction has been confirmed."
7029
+ )
7030
+ );
7031
+ const contractAddress = netContract.address.toLowerCase();
7032
+ const messageSentEvents = [];
7033
+ for (const log of receipt.logs) {
7034
+ if (log.address.toLowerCase() !== contractAddress) {
7035
+ continue;
7036
+ }
7037
+ try {
7038
+ const decoded = decodeEventLog({
7039
+ abi: netContract.abi,
7040
+ data: log.data,
7041
+ topics: log.topics
7042
+ });
7043
+ if (decoded.eventName === "MessageSent") {
7044
+ const args = decoded.args;
7045
+ messageSentEvents.push({
7046
+ sender: args.sender,
7047
+ messageIndex: args.messageIndex
7048
+ });
7049
+ }
7050
+ } catch {
7051
+ }
7052
+ }
7053
+ if (messageSentEvents.length === 0) {
7054
+ exitWithError(
7055
+ "Transaction does not contain any Net protocol messages."
7056
+ );
7057
+ }
7058
+ console.log(
7059
+ chalk4.blue(
7060
+ `Found ${messageSentEvents.length} message(s) in transaction. Fetching details...`
7061
+ )
7062
+ );
7063
+ const messages = await Promise.all(
7064
+ messageSentEvents.map(
7065
+ (event) => netClient.getMessageAtIndex({
7066
+ messageIndex: Number(event.messageIndex)
7067
+ })
7068
+ )
7069
+ );
7070
+ let recorded = 0;
7071
+ for (let i = 0; i < messages.length; i++) {
7072
+ const message = messages[i];
7073
+ if (!message) {
7074
+ console.log(
7075
+ chalk4.yellow(
7076
+ ` Could not fetch message at index ${messageSentEvents[i].messageIndex}. Skipping.`
7077
+ )
7078
+ );
7079
+ continue;
7080
+ }
7081
+ const feedName = extractFeedName(message.topic);
7082
+ const isComment = isCommentTopic(message.topic);
7083
+ let type;
7084
+ let postId;
7085
+ let label;
7086
+ if (isComment) {
7087
+ type = "comment";
7088
+ const commentData = parseCommentData(message.data);
7089
+ postId = commentData ? `${commentData.parentSender}:${commentData.parentTimestamp}` : void 0;
7090
+ label = `Verified comment:
7091
+ Feed: ${feedName}
7092
+ Sender: ${message.sender}
7093
+ Text: ${message.text}
7094
+ Parent post: ${postId ?? "unknown"}
7095
+ Tx: ${txHash}`;
7096
+ } else {
7097
+ type = "post";
7098
+ postId = createPostId(message);
7099
+ label = `Verified post:
7100
+ Feed: ${feedName}
7101
+ Sender: ${message.sender}
7102
+ Text: ${message.text}
7103
+ Post ID: ${postId}
7104
+ Tx: ${txHash}`;
7105
+ }
7106
+ addHistoryEntry({
7107
+ type,
7108
+ txHash,
7109
+ chainId: readOnlyOptions.chainId,
7110
+ feed: feedName,
7111
+ sender: message.sender,
7112
+ text: message.text,
7113
+ postId
7114
+ });
7115
+ console.log(chalk4.green(` ${label}`));
7116
+ recorded++;
7117
+ }
7118
+ if (recorded > 0) {
7119
+ console.log(
7120
+ chalk4.green(`
7121
+ Successfully recorded ${recorded} history entry(ies).`)
7122
+ );
7123
+ }
7124
+ }
7125
+ function registerFeedVerifyClaimCommand(parent) {
7126
+ parent.command("verify-claim <tx-hash>").description(
7127
+ "Verify a transaction and add it to history. Recovers post/comment details from on-chain data."
7128
+ ).option(
7129
+ "--chain-id <id>",
7130
+ "Chain ID (default: 8453 for Base)",
7131
+ (value) => parseInt(value, 10)
7132
+ ).option("--rpc-url <url>", "Custom RPC URL").action(async (txHash, options) => {
7133
+ await executeFeedVerifyClaim(txHash, options);
7134
+ });
7135
+ }
6996
7136
 
6997
7137
  // src/commands/feed/index.ts
6998
7138
  function registerFeedCommand(program2) {
@@ -7009,6 +7149,7 @@ function registerFeedCommand(program2) {
7009
7149
  registerFeedHistoryCommand(feedCommand);
7010
7150
  registerAgentRegisterCommand(feedCommand);
7011
7151
  registerListAgentsCommand(feedCommand);
7152
+ registerFeedVerifyClaimCommand(feedCommand);
7012
7153
  }
7013
7154
  async function executeUpvoteToken(options) {
7014
7155
  const count = parseInt(options.count, 10);