@net-protocol/cli 0.1.29 → 0.1.31

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,9 +7,9 @@ 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, defineChain } from 'viem';
10
+ import { stringToHex, createWalletClient, http, hexToString, parseEther, encodeFunctionData, publicActions, defineChain, createPublicClient } from 'viem';
11
11
  import { privateKeyToAccount } from 'viem/accounts';
12
- import { getNetContract, getChainName, getPublicClient, getChainRpcUrls, NetClient, toBytes32, NULL_ADDRESS } from '@net-protocol/core';
12
+ import { getNetContract, getChainName, getPublicClient, getChainRpcUrls, NetClient, getBaseDataSuffix, 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
14
  import { FeedRegistryClient, FeedClient, AgentRegistryClient } from '@net-protocol/feeds';
15
15
  import { isNetrSupportedChain, NetrClient } from '@net-protocol/netr';
@@ -21,6 +21,7 @@ import { BazaarClient } from '@net-protocol/bazaar';
21
21
  import * as os from 'os';
22
22
  import { homedir } from 'os';
23
23
  import * as readline from 'readline';
24
+ import { discoverTokenPool, PURE_ALPHA_STRATEGY, UNIV234_POOLS_STRATEGY, encodePoolKey, DYNAMIC_SPLIT_STRATEGY, getTokenScoreKey, UPVOTE_PRICE_ETH, UPVOTE_APP, ScoreClient, ALL_STRATEGY_ADDRESSES } from '@net-protocol/score';
24
25
 
25
26
  var DEFAULT_CHAIN_ID = 8453;
26
27
  function getRequiredChainId(optionValue) {
@@ -447,7 +448,8 @@ function createWalletClientFromPrivateKey(params) {
447
448
  const walletClient = createWalletClient({
448
449
  account,
449
450
  chain,
450
- transport: http()
451
+ transport: http(),
452
+ dataSuffix: getBaseDataSuffix(chainId)
451
453
  });
452
454
  return {
453
455
  walletClient,
@@ -2147,7 +2149,8 @@ async function executeTokenDeploy(options) {
2147
2149
  });
2148
2150
  const walletClient = createWalletClient({
2149
2151
  account,
2150
- transport: http(rpcUrls[0])
2152
+ transport: http(rpcUrls[0]),
2153
+ dataSuffix: getBaseDataSuffix(commonOptions.chainId)
2151
2154
  });
2152
2155
  if (options.initialBuy) {
2153
2156
  console.log(chalk4.blue(`Deploying token with ${options.initialBuy} ETH initial buy...`));
@@ -6002,7 +6005,8 @@ function createWallet(privateKey, chainId, rpcUrl) {
6002
6005
  });
6003
6006
  return createWalletClient({
6004
6007
  account,
6005
- transport: http(rpcUrls[0])
6008
+ transport: http(rpcUrls[0]),
6009
+ dataSuffix: getBaseDataSuffix(chainId)
6006
6010
  });
6007
6011
  }
6008
6012
  async function executeTransaction(walletClient, txConfig) {
@@ -6914,6 +6918,226 @@ function registerFeedCommand(program2) {
6914
6918
  registerFeedHistoryCommand(feedCommand);
6915
6919
  registerAgentRegisterCommand(feedCommand);
6916
6920
  }
6921
+ async function executeUpvoteToken(options) {
6922
+ const count = parseInt(options.count, 10);
6923
+ if (isNaN(count) || count <= 0) {
6924
+ exitWithError("Count must be a positive integer");
6925
+ return;
6926
+ }
6927
+ const tokenAddress = options.tokenAddress;
6928
+ if (!tokenAddress.startsWith("0x") || tokenAddress.length !== 42) {
6929
+ exitWithError(
6930
+ "Invalid token address format (must be 0x-prefixed, 42 characters)"
6931
+ );
6932
+ return;
6933
+ }
6934
+ const readOnlyOptions = parseReadOnlyOptionsWithDefault({
6935
+ chainId: options.chainId,
6936
+ rpcUrl: options.rpcUrl
6937
+ });
6938
+ const rpcUrls = getChainRpcUrls({
6939
+ chainId: readOnlyOptions.chainId,
6940
+ rpcUrl: readOnlyOptions.rpcUrl
6941
+ });
6942
+ const publicClient = createPublicClient({
6943
+ transport: http(rpcUrls[0])
6944
+ });
6945
+ console.log(chalk4.blue("Discovering Uniswap pool for token..."));
6946
+ let poolResult;
6947
+ try {
6948
+ poolResult = await discoverTokenPool({
6949
+ publicClient,
6950
+ tokenAddress
6951
+ });
6952
+ } catch (error) {
6953
+ exitWithError(
6954
+ `Failed to discover token pool: ${error instanceof Error ? error.message : String(error)}`
6955
+ );
6956
+ return;
6957
+ }
6958
+ let strategyAddress;
6959
+ let storedContext;
6960
+ if (!poolResult || !poolResult.poolKey) {
6961
+ strategyAddress = PURE_ALPHA_STRATEGY.address;
6962
+ storedContext = "0x";
6963
+ console.log(chalk4.yellow("No pool found \u2014 using Pure Alpha strategy"));
6964
+ } else if (options.splitType === "50/50") {
6965
+ strategyAddress = UNIV234_POOLS_STRATEGY.address;
6966
+ storedContext = encodePoolKey(poolResult.poolKey);
6967
+ console.log(
6968
+ chalk4.green(
6969
+ `Pool found (fee: ${poolResult.fee}) \u2014 using 50/50 Pools strategy`
6970
+ )
6971
+ );
6972
+ } else {
6973
+ strategyAddress = DYNAMIC_SPLIT_STRATEGY.address;
6974
+ storedContext = encodePoolKey(poolResult.poolKey);
6975
+ console.log(
6976
+ chalk4.green(
6977
+ `Pool found (fee: ${poolResult.fee}) \u2014 using Dynamic Split strategy`
6978
+ )
6979
+ );
6980
+ }
6981
+ const scoreKey = getTokenScoreKey(tokenAddress);
6982
+ const value = parseEther((count * UPVOTE_PRICE_ETH).toString());
6983
+ const txConfig = {
6984
+ to: UPVOTE_APP.address,
6985
+ abi: UPVOTE_APP.abi,
6986
+ functionName: "upvote",
6987
+ args: [strategyAddress, scoreKey, count, storedContext, "0x"],
6988
+ value
6989
+ };
6990
+ if (options.encodeOnly) {
6991
+ const encoded = encodeTransaction(txConfig, readOnlyOptions.chainId);
6992
+ console.log(JSON.stringify(encoded, null, 2));
6993
+ return;
6994
+ }
6995
+ const commonOptions = parseCommonOptionsWithDefault(
6996
+ {
6997
+ privateKey: options.privateKey,
6998
+ chainId: options.chainId,
6999
+ rpcUrl: options.rpcUrl
7000
+ },
7001
+ true
7002
+ );
7003
+ const walletClient = createWallet(
7004
+ commonOptions.privateKey,
7005
+ commonOptions.chainId,
7006
+ commonOptions.rpcUrl
7007
+ );
7008
+ console.log(
7009
+ chalk4.blue(`Submitting ${count} upvote(s) for ${tokenAddress}...`)
7010
+ );
7011
+ try {
7012
+ const hash = await executeTransaction(walletClient, txConfig);
7013
+ console.log(chalk4.green(`Upvote submitted successfully!`));
7014
+ console.log(chalk4.white(` Transaction: ${hash}`));
7015
+ console.log(chalk4.white(` Token: ${tokenAddress}`));
7016
+ console.log(chalk4.white(` Count: ${count}`));
7017
+ console.log(
7018
+ chalk4.white(` Value: ${(count * UPVOTE_PRICE_ETH).toFixed(6)} ETH`)
7019
+ );
7020
+ } catch (error) {
7021
+ exitWithError(
7022
+ `Failed to submit upvote: ${error instanceof Error ? error.message : String(error)}`
7023
+ );
7024
+ }
7025
+ }
7026
+ function registerUpvoteTokenCommand(parent, commandName = "token") {
7027
+ parent.command(commandName).description("Upvote a token on Net Protocol").requiredOption(
7028
+ "--token-address <address>",
7029
+ "Token contract address to upvote"
7030
+ ).requiredOption("--count <n>", "Number of upvotes").option(
7031
+ "--split-type <type>",
7032
+ 'Strategy split type: "dynamic" (default) or "50/50"'
7033
+ ).option(
7034
+ "--chain-id <id>",
7035
+ "Chain ID (default: 8453 for Base)",
7036
+ (value) => parseInt(value, 10)
7037
+ ).option("--rpc-url <url>", "Custom RPC URL").option("--private-key <key>", "Private key (0x-prefixed)").option(
7038
+ "--encode-only",
7039
+ "Output transaction data as JSON instead of executing"
7040
+ ).action(async (options) => {
7041
+ await executeUpvoteToken(options);
7042
+ });
7043
+ }
7044
+ function getStrategyName(address) {
7045
+ const lower = address.toLowerCase();
7046
+ if (lower === PURE_ALPHA_STRATEGY.address.toLowerCase()) return "Pure Alpha";
7047
+ if (lower === UNIV234_POOLS_STRATEGY.address.toLowerCase())
7048
+ return "50/50 Pools";
7049
+ if (lower === DYNAMIC_SPLIT_STRATEGY.address.toLowerCase())
7050
+ return "Dynamic Split";
7051
+ return address;
7052
+ }
7053
+ async function executeGetUpvotes(options) {
7054
+ const tokenAddress = options.tokenAddress;
7055
+ if (!tokenAddress.startsWith("0x") || tokenAddress.length !== 42) {
7056
+ exitWithError(
7057
+ "Invalid token address format (must be 0x-prefixed, 42 characters)"
7058
+ );
7059
+ return;
7060
+ }
7061
+ const readOnlyOptions = parseReadOnlyOptionsWithDefault({
7062
+ chainId: options.chainId,
7063
+ rpcUrl: options.rpcUrl
7064
+ });
7065
+ const client = new ScoreClient({
7066
+ chainId: readOnlyOptions.chainId,
7067
+ overrides: readOnlyOptions.rpcUrl ? { rpcUrls: [readOnlyOptions.rpcUrl] } : void 0
7068
+ });
7069
+ const scoreKey = getTokenScoreKey(tokenAddress);
7070
+ try {
7071
+ const [totalCounts, ...perStrategyCounts] = await Promise.all([
7072
+ client.getUpvotesWithLegacy({
7073
+ scoreKeys: [scoreKey],
7074
+ strategies: ALL_STRATEGY_ADDRESSES
7075
+ }),
7076
+ ...ALL_STRATEGY_ADDRESSES.map(
7077
+ (strategy) => client.getStrategyKeyScores({
7078
+ strategy,
7079
+ scoreKeys: [scoreKey]
7080
+ })
7081
+ )
7082
+ ]);
7083
+ const total = totalCounts[0] ?? 0;
7084
+ const strategyCounts = ALL_STRATEGY_ADDRESSES.map((addr, i) => ({
7085
+ strategy: getStrategyName(addr),
7086
+ address: addr,
7087
+ count: perStrategyCounts[i]?.[0] ?? 0
7088
+ }));
7089
+ if (options.json) {
7090
+ console.log(
7091
+ JSON.stringify(
7092
+ {
7093
+ tokenAddress,
7094
+ scoreKey,
7095
+ total,
7096
+ strategies: strategyCounts.map((s) => ({
7097
+ name: s.strategy,
7098
+ address: s.address,
7099
+ count: s.count
7100
+ }))
7101
+ },
7102
+ null,
7103
+ 2
7104
+ )
7105
+ );
7106
+ } else {
7107
+ console.log(chalk4.white(`Upvotes for ${tokenAddress}:`));
7108
+ console.log(chalk4.cyan(` Total: ${total}`));
7109
+ console.log();
7110
+ for (const s of strategyCounts) {
7111
+ if (s.count > 0) {
7112
+ console.log(chalk4.white(` ${s.strategy}: ${s.count}`));
7113
+ }
7114
+ }
7115
+ if (total === 0) {
7116
+ console.log(chalk4.yellow(" No upvotes found"));
7117
+ }
7118
+ }
7119
+ } catch (error) {
7120
+ exitWithError(
7121
+ `Failed to fetch upvotes: ${error instanceof Error ? error.message : String(error)}`
7122
+ );
7123
+ }
7124
+ }
7125
+ function registerGetUpvotesCommand(parent, commandName = "info") {
7126
+ parent.command(commandName).description("Get upvote counts for a token").requiredOption("--token-address <address>", "Token contract address").option(
7127
+ "--chain-id <id>",
7128
+ "Chain ID (default: 8453 for Base)",
7129
+ (value) => parseInt(value, 10)
7130
+ ).option("--rpc-url <url>", "Custom RPC URL").option("--json", "Output in JSON format").action(async (options) => {
7131
+ await executeGetUpvotes(options);
7132
+ });
7133
+ }
7134
+
7135
+ // src/commands/upvote/index.ts
7136
+ function registerUpvoteCommand(program2) {
7137
+ const upvoteCommand = program2.command("upvote").description("Upvote tokens on Net Protocol");
7138
+ registerUpvoteTokenCommand(upvoteCommand);
7139
+ registerGetUpvotesCommand(upvoteCommand);
7140
+ }
6917
7141
  var CACHE_DIR = join(homedir(), ".netp");
6918
7142
  var CACHE_FILE = join(CACHE_DIR, "update-check.json");
6919
7143
  var CHECK_INTERVAL_MS = 4 * 60 * 60 * 1e3;
@@ -7013,6 +7237,7 @@ registerTokenCommand(program);
7013
7237
  registerProfileCommand(program);
7014
7238
  registerBazaarCommand(program);
7015
7239
  registerFeedCommand(program);
7240
+ registerUpvoteCommand(program);
7016
7241
  program.command("update").description("Update netp to the latest version").action(async () => {
7017
7242
  const { execSync } = await import('child_process');
7018
7243
  console.log("Updating @net-protocol/cli...");