@net-protocol/cli 0.1.28 → 0.1.30

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,7 +7,7 @@ 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
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';
@@ -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) {
@@ -3243,7 +3244,7 @@ ${available}`
3243
3244
  const buffer = fs6.readFileSync(filePath);
3244
3245
  if (buffer.length > MAX_CSS_SIZE) {
3245
3246
  exitWithError(
3246
- `File too large: ${buffer.length} bytes exceeds maximum of ${MAX_CSS_SIZE} bytes (10KB).`
3247
+ `File too large: ${buffer.length} bytes exceeds maximum of ${MAX_CSS_SIZE} bytes (15KB).`
3247
3248
  );
3248
3249
  }
3249
3250
  cssContent = buffer.toString("utf-8");
@@ -3252,7 +3253,7 @@ ${available}`
3252
3253
  const contentSize = Buffer.byteLength(cssContent, "utf-8");
3253
3254
  if (contentSize > MAX_CSS_SIZE) {
3254
3255
  exitWithError(
3255
- `Content too large: ${contentSize} bytes exceeds maximum of ${MAX_CSS_SIZE} bytes (10KB).`
3256
+ `Content too large: ${contentSize} bytes exceeds maximum of ${MAX_CSS_SIZE} bytes (15KB).`
3256
3257
  );
3257
3258
  }
3258
3259
  }
@@ -6914,6 +6915,226 @@ function registerFeedCommand(program2) {
6914
6915
  registerFeedHistoryCommand(feedCommand);
6915
6916
  registerAgentRegisterCommand(feedCommand);
6916
6917
  }
6918
+ async function executeUpvoteToken(options) {
6919
+ const count = parseInt(options.count, 10);
6920
+ if (isNaN(count) || count <= 0) {
6921
+ exitWithError("Count must be a positive integer");
6922
+ return;
6923
+ }
6924
+ const tokenAddress = options.tokenAddress;
6925
+ if (!tokenAddress.startsWith("0x") || tokenAddress.length !== 42) {
6926
+ exitWithError(
6927
+ "Invalid token address format (must be 0x-prefixed, 42 characters)"
6928
+ );
6929
+ return;
6930
+ }
6931
+ const readOnlyOptions = parseReadOnlyOptionsWithDefault({
6932
+ chainId: options.chainId,
6933
+ rpcUrl: options.rpcUrl
6934
+ });
6935
+ const rpcUrls = getChainRpcUrls({
6936
+ chainId: readOnlyOptions.chainId,
6937
+ rpcUrl: readOnlyOptions.rpcUrl
6938
+ });
6939
+ const publicClient = createPublicClient({
6940
+ transport: http(rpcUrls[0])
6941
+ });
6942
+ console.log(chalk4.blue("Discovering Uniswap pool for token..."));
6943
+ let poolResult;
6944
+ try {
6945
+ poolResult = await discoverTokenPool({
6946
+ publicClient,
6947
+ tokenAddress
6948
+ });
6949
+ } catch (error) {
6950
+ exitWithError(
6951
+ `Failed to discover token pool: ${error instanceof Error ? error.message : String(error)}`
6952
+ );
6953
+ return;
6954
+ }
6955
+ let strategyAddress;
6956
+ let storedContext;
6957
+ if (!poolResult || !poolResult.poolKey) {
6958
+ strategyAddress = PURE_ALPHA_STRATEGY.address;
6959
+ storedContext = "0x";
6960
+ console.log(chalk4.yellow("No pool found \u2014 using Pure Alpha strategy"));
6961
+ } else if (options.splitType === "50/50") {
6962
+ strategyAddress = UNIV234_POOLS_STRATEGY.address;
6963
+ storedContext = encodePoolKey(poolResult.poolKey);
6964
+ console.log(
6965
+ chalk4.green(
6966
+ `Pool found (fee: ${poolResult.fee}) \u2014 using 50/50 Pools strategy`
6967
+ )
6968
+ );
6969
+ } else {
6970
+ strategyAddress = DYNAMIC_SPLIT_STRATEGY.address;
6971
+ storedContext = encodePoolKey(poolResult.poolKey);
6972
+ console.log(
6973
+ chalk4.green(
6974
+ `Pool found (fee: ${poolResult.fee}) \u2014 using Dynamic Split strategy`
6975
+ )
6976
+ );
6977
+ }
6978
+ const scoreKey = getTokenScoreKey(tokenAddress);
6979
+ const value = parseEther((count * UPVOTE_PRICE_ETH).toString());
6980
+ const txConfig = {
6981
+ to: UPVOTE_APP.address,
6982
+ abi: UPVOTE_APP.abi,
6983
+ functionName: "upvote",
6984
+ args: [strategyAddress, scoreKey, count, storedContext, "0x"],
6985
+ value
6986
+ };
6987
+ if (options.encodeOnly) {
6988
+ const encoded = encodeTransaction(txConfig, readOnlyOptions.chainId);
6989
+ console.log(JSON.stringify(encoded, null, 2));
6990
+ return;
6991
+ }
6992
+ const commonOptions = parseCommonOptionsWithDefault(
6993
+ {
6994
+ privateKey: options.privateKey,
6995
+ chainId: options.chainId,
6996
+ rpcUrl: options.rpcUrl
6997
+ },
6998
+ true
6999
+ );
7000
+ const walletClient = createWallet(
7001
+ commonOptions.privateKey,
7002
+ commonOptions.chainId,
7003
+ commonOptions.rpcUrl
7004
+ );
7005
+ console.log(
7006
+ chalk4.blue(`Submitting ${count} upvote(s) for ${tokenAddress}...`)
7007
+ );
7008
+ try {
7009
+ const hash = await executeTransaction(walletClient, txConfig);
7010
+ console.log(chalk4.green(`Upvote submitted successfully!`));
7011
+ console.log(chalk4.white(` Transaction: ${hash}`));
7012
+ console.log(chalk4.white(` Token: ${tokenAddress}`));
7013
+ console.log(chalk4.white(` Count: ${count}`));
7014
+ console.log(
7015
+ chalk4.white(` Value: ${(count * UPVOTE_PRICE_ETH).toFixed(6)} ETH`)
7016
+ );
7017
+ } catch (error) {
7018
+ exitWithError(
7019
+ `Failed to submit upvote: ${error instanceof Error ? error.message : String(error)}`
7020
+ );
7021
+ }
7022
+ }
7023
+ function registerUpvoteTokenCommand(parent, commandName = "token") {
7024
+ parent.command(commandName).description("Upvote a token on Net Protocol").requiredOption(
7025
+ "--token-address <address>",
7026
+ "Token contract address to upvote"
7027
+ ).requiredOption("--count <n>", "Number of upvotes").option(
7028
+ "--split-type <type>",
7029
+ 'Strategy split type: "dynamic" (default) or "50/50"'
7030
+ ).option(
7031
+ "--chain-id <id>",
7032
+ "Chain ID (default: 8453 for Base)",
7033
+ (value) => parseInt(value, 10)
7034
+ ).option("--rpc-url <url>", "Custom RPC URL").option("--private-key <key>", "Private key (0x-prefixed)").option(
7035
+ "--encode-only",
7036
+ "Output transaction data as JSON instead of executing"
7037
+ ).action(async (options) => {
7038
+ await executeUpvoteToken(options);
7039
+ });
7040
+ }
7041
+ function getStrategyName(address) {
7042
+ const lower = address.toLowerCase();
7043
+ if (lower === PURE_ALPHA_STRATEGY.address.toLowerCase()) return "Pure Alpha";
7044
+ if (lower === UNIV234_POOLS_STRATEGY.address.toLowerCase())
7045
+ return "50/50 Pools";
7046
+ if (lower === DYNAMIC_SPLIT_STRATEGY.address.toLowerCase())
7047
+ return "Dynamic Split";
7048
+ return address;
7049
+ }
7050
+ async function executeGetUpvotes(options) {
7051
+ const tokenAddress = options.tokenAddress;
7052
+ if (!tokenAddress.startsWith("0x") || tokenAddress.length !== 42) {
7053
+ exitWithError(
7054
+ "Invalid token address format (must be 0x-prefixed, 42 characters)"
7055
+ );
7056
+ return;
7057
+ }
7058
+ const readOnlyOptions = parseReadOnlyOptionsWithDefault({
7059
+ chainId: options.chainId,
7060
+ rpcUrl: options.rpcUrl
7061
+ });
7062
+ const client = new ScoreClient({
7063
+ chainId: readOnlyOptions.chainId,
7064
+ overrides: readOnlyOptions.rpcUrl ? { rpcUrls: [readOnlyOptions.rpcUrl] } : void 0
7065
+ });
7066
+ const scoreKey = getTokenScoreKey(tokenAddress);
7067
+ try {
7068
+ const [totalCounts, ...perStrategyCounts] = await Promise.all([
7069
+ client.getUpvotesWithLegacy({
7070
+ scoreKeys: [scoreKey],
7071
+ strategies: ALL_STRATEGY_ADDRESSES
7072
+ }),
7073
+ ...ALL_STRATEGY_ADDRESSES.map(
7074
+ (strategy) => client.getStrategyKeyScores({
7075
+ strategy,
7076
+ scoreKeys: [scoreKey]
7077
+ })
7078
+ )
7079
+ ]);
7080
+ const total = totalCounts[0] ?? 0;
7081
+ const strategyCounts = ALL_STRATEGY_ADDRESSES.map((addr, i) => ({
7082
+ strategy: getStrategyName(addr),
7083
+ address: addr,
7084
+ count: perStrategyCounts[i]?.[0] ?? 0
7085
+ }));
7086
+ if (options.json) {
7087
+ console.log(
7088
+ JSON.stringify(
7089
+ {
7090
+ tokenAddress,
7091
+ scoreKey,
7092
+ total,
7093
+ strategies: strategyCounts.map((s) => ({
7094
+ name: s.strategy,
7095
+ address: s.address,
7096
+ count: s.count
7097
+ }))
7098
+ },
7099
+ null,
7100
+ 2
7101
+ )
7102
+ );
7103
+ } else {
7104
+ console.log(chalk4.white(`Upvotes for ${tokenAddress}:`));
7105
+ console.log(chalk4.cyan(` Total: ${total}`));
7106
+ console.log();
7107
+ for (const s of strategyCounts) {
7108
+ if (s.count > 0) {
7109
+ console.log(chalk4.white(` ${s.strategy}: ${s.count}`));
7110
+ }
7111
+ }
7112
+ if (total === 0) {
7113
+ console.log(chalk4.yellow(" No upvotes found"));
7114
+ }
7115
+ }
7116
+ } catch (error) {
7117
+ exitWithError(
7118
+ `Failed to fetch upvotes: ${error instanceof Error ? error.message : String(error)}`
7119
+ );
7120
+ }
7121
+ }
7122
+ function registerGetUpvotesCommand(parent, commandName = "info") {
7123
+ parent.command(commandName).description("Get upvote counts for a token").requiredOption("--token-address <address>", "Token contract address").option(
7124
+ "--chain-id <id>",
7125
+ "Chain ID (default: 8453 for Base)",
7126
+ (value) => parseInt(value, 10)
7127
+ ).option("--rpc-url <url>", "Custom RPC URL").option("--json", "Output in JSON format").action(async (options) => {
7128
+ await executeGetUpvotes(options);
7129
+ });
7130
+ }
7131
+
7132
+ // src/commands/upvote/index.ts
7133
+ function registerUpvoteCommand(program2) {
7134
+ const upvoteCommand = program2.command("upvote").description("Upvote tokens on Net Protocol");
7135
+ registerUpvoteTokenCommand(upvoteCommand);
7136
+ registerGetUpvotesCommand(upvoteCommand);
7137
+ }
6917
7138
  var CACHE_DIR = join(homedir(), ".netp");
6918
7139
  var CACHE_FILE = join(CACHE_DIR, "update-check.json");
6919
7140
  var CHECK_INTERVAL_MS = 4 * 60 * 60 * 1e3;
@@ -7013,6 +7234,7 @@ registerTokenCommand(program);
7013
7234
  registerProfileCommand(program);
7014
7235
  registerBazaarCommand(program);
7015
7236
  registerFeedCommand(program);
7237
+ registerUpvoteCommand(program);
7016
7238
  program.command("update").description("Update netp to the latest version").action(async () => {
7017
7239
  const { execSync } = await import('child_process');
7018
7240
  console.log("Updating @net-protocol/cli...");