@claws.fun/cli 1.0.0

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.
Files changed (48) hide show
  1. package/README.md +204 -0
  2. package/dist/commands/buy.d.ts +6 -0
  3. package/dist/commands/buy.d.ts.map +1 -0
  4. package/dist/commands/buy.js +120 -0
  5. package/dist/commands/buy.js.map +1 -0
  6. package/dist/commands/claim.d.ts +6 -0
  7. package/dist/commands/claim.d.ts.map +1 -0
  8. package/dist/commands/claim.js +141 -0
  9. package/dist/commands/claim.js.map +1 -0
  10. package/dist/commands/config.d.ts +6 -0
  11. package/dist/commands/config.d.ts.map +1 -0
  12. package/dist/commands/config.js +107 -0
  13. package/dist/commands/config.js.map +1 -0
  14. package/dist/commands/create.d.ts +6 -0
  15. package/dist/commands/create.d.ts.map +1 -0
  16. package/dist/commands/create.js +174 -0
  17. package/dist/commands/create.js.map +1 -0
  18. package/dist/commands/sell.d.ts +6 -0
  19. package/dist/commands/sell.d.ts.map +1 -0
  20. package/dist/commands/sell.js +134 -0
  21. package/dist/commands/sell.js.map +1 -0
  22. package/dist/commands/status.d.ts +6 -0
  23. package/dist/commands/status.d.ts.map +1 -0
  24. package/dist/commands/status.js +138 -0
  25. package/dist/commands/status.js.map +1 -0
  26. package/dist/index.d.ts +16 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +38 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/utils/config.d.ts +30 -0
  31. package/dist/utils/config.d.ts.map +1 -0
  32. package/dist/utils/config.js +176 -0
  33. package/dist/utils/config.js.map +1 -0
  34. package/dist/utils/contracts.d.ts +15 -0
  35. package/dist/utils/contracts.d.ts.map +1 -0
  36. package/dist/utils/contracts.js +90 -0
  37. package/dist/utils/contracts.js.map +1 -0
  38. package/package.json +48 -0
  39. package/src/commands/buy.ts +136 -0
  40. package/src/commands/claim.ts +152 -0
  41. package/src/commands/config.ts +77 -0
  42. package/src/commands/create.ts +217 -0
  43. package/src/commands/sell.ts +149 -0
  44. package/src/commands/status.ts +148 -0
  45. package/src/index.ts +41 -0
  46. package/src/utils/config.ts +159 -0
  47. package/src/utils/contracts.ts +92 -0
  48. package/tsconfig.json +20 -0
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ /**
3
+ * Configuration management for claws CLI
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.config = exports.RPC_URLS = exports.ADDRESSES = void 0;
40
+ exports.getConfig = getConfig;
41
+ exports.setConfig = setConfig;
42
+ exports.getNetworkAddresses = getNetworkAddresses;
43
+ exports.getRpcUrl = getRpcUrl;
44
+ exports.getProvider = getProvider;
45
+ exports.getWallet = getWallet;
46
+ exports.hasWallet = hasWallet;
47
+ exports.loadPrivateKey = loadPrivateKey;
48
+ const ethers_1 = require("ethers");
49
+ const fs = __importStar(require("fs"));
50
+ const path = __importStar(require("path"));
51
+ const os = __importStar(require("os"));
52
+ // Contract addresses by network
53
+ exports.ADDRESSES = {
54
+ sepolia: {
55
+ // V2 deployment - LP to FeeCollector (no Safe approval needed)
56
+ factory: '0x9dA76578Eb1f04d4235be9b9C71853D99E0C2EBE',
57
+ birthCertificate: '0xE0a9212dd519D02f4F70529d78eC5a61b9b4e7b2',
58
+ bondingCurve: '0x4812eacD5e4aAd57ABD9F68C89606E63e4e53BfE',
59
+ feeCollector: '0xD6Bd2Ba272AA89755d5829F4275dc023c9EF5Fa3',
60
+ memoryStorage: '0x0b348d3faF6752BA09Fae5CbF657F4A77Cb86d48',
61
+ swapRouter: '0x3bFA4769FB09eefC5a80d6E87c3B9C650f7Ae48E',
62
+ weth: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14',
63
+ },
64
+ base: {
65
+ factory: 'TBD',
66
+ birthCertificate: 'TBD',
67
+ bondingCurve: 'TBD',
68
+ feeCollector: 'TBD',
69
+ memoryStorage: 'TBD',
70
+ swapRouter: '0x2626664c2603336E57B271c5C0b26F421741e481',
71
+ weth: '0x4200000000000000000000000000000000000006',
72
+ },
73
+ };
74
+ // RPC endpoints
75
+ exports.RPC_URLS = {
76
+ sepolia: 'https://rpc.sepolia.org',
77
+ base: 'https://mainnet.base.org',
78
+ };
79
+ // Simple file-based config storage
80
+ const CONFIG_DIR = path.join(os.homedir(), '.claws');
81
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
82
+ function ensureConfigDir() {
83
+ if (!fs.existsSync(CONFIG_DIR)) {
84
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
85
+ }
86
+ }
87
+ function loadConfigFile() {
88
+ ensureConfigDir();
89
+ if (fs.existsSync(CONFIG_FILE)) {
90
+ try {
91
+ return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8'));
92
+ }
93
+ catch {
94
+ return { network: 'sepolia', privateKey: '', rpcUrl: '' };
95
+ }
96
+ }
97
+ return { network: 'sepolia', privateKey: '', rpcUrl: '' };
98
+ }
99
+ function saveConfigFile(data) {
100
+ ensureConfigDir();
101
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(data, null, 2));
102
+ }
103
+ // Config store wrapper
104
+ const config = {
105
+ get(key) {
106
+ const data = loadConfigFile();
107
+ return data[key] || '';
108
+ },
109
+ set(key, value) {
110
+ const data = loadConfigFile();
111
+ data[key] = value;
112
+ saveConfigFile(data);
113
+ },
114
+ };
115
+ exports.config = config;
116
+ function getConfig() {
117
+ return {
118
+ network: config.get('network') || 'sepolia',
119
+ privateKey: config.get('privateKey'),
120
+ rpcUrl: config.get('rpcUrl'),
121
+ };
122
+ }
123
+ function setConfig(key, value) {
124
+ config.set(key, value);
125
+ }
126
+ function getNetworkAddresses() {
127
+ const network = config.get('network') || 'sepolia';
128
+ return exports.ADDRESSES[network] || exports.ADDRESSES.sepolia;
129
+ }
130
+ function getRpcUrl() {
131
+ const customRpc = config.get('rpcUrl');
132
+ if (customRpc)
133
+ return customRpc;
134
+ const network = config.get('network') || 'sepolia';
135
+ return exports.RPC_URLS[network] || exports.RPC_URLS.sepolia;
136
+ }
137
+ function getProvider() {
138
+ return new ethers_1.ethers.JsonRpcProvider(getRpcUrl());
139
+ }
140
+ function getWallet() {
141
+ const privateKey = config.get('privateKey');
142
+ if (!privateKey)
143
+ return null;
144
+ try {
145
+ const provider = getProvider();
146
+ return new ethers_1.ethers.Wallet(privateKey, provider);
147
+ }
148
+ catch (error) {
149
+ return null;
150
+ }
151
+ }
152
+ function hasWallet() {
153
+ const privateKey = config.get('privateKey');
154
+ return !!privateKey;
155
+ }
156
+ // Load private key from environment or file
157
+ function loadPrivateKey() {
158
+ // 1. Check environment variable
159
+ if (process.env.CLAWS_PRIVATE_KEY) {
160
+ return process.env.CLAWS_PRIVATE_KEY;
161
+ }
162
+ // 2. Check .env file in current directory
163
+ const envPath = path.join(process.cwd(), '.env');
164
+ if (fs.existsSync(envPath)) {
165
+ const envContent = fs.readFileSync(envPath, 'utf-8');
166
+ const match = envContent.match(/CLAWS_PRIVATE_KEY=(.+)/);
167
+ if (match)
168
+ return match[1].trim();
169
+ }
170
+ // 3. Check config
171
+ const configKey = config.get('privateKey');
172
+ if (configKey)
173
+ return configKey;
174
+ return null;
175
+ }
176
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Contract utilities for claws CLI
3
+ */
4
+ import { Contract, Wallet } from 'ethers';
5
+ export declare const FACTORY_ABI: string[];
6
+ export declare const TOKEN_ABI: string[];
7
+ export declare const FEE_COLLECTOR_ABI: string[];
8
+ export declare const SWAP_ROUTER_ABI: string[];
9
+ export declare const WETH_ABI: string[];
10
+ export declare function getFactoryContract(wallet?: Wallet): Contract;
11
+ export declare function getTokenContract(tokenAddress: string, wallet?: Wallet): Contract;
12
+ export declare function getFeeCollectorContract(wallet?: Wallet): Contract;
13
+ export declare function getSwapRouterContract(wallet?: Wallet): Contract;
14
+ export declare function getWethContract(wallet?: Wallet): Contract;
15
+ //# sourceMappingURL=contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../src/utils/contracts.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAU,QAAQ,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIlD,eAAO,MAAM,WAAW,UAWvB,CAAC;AAEF,eAAO,MAAM,SAAS,UAgBrB,CAAC;AAEF,eAAO,MAAM,iBAAiB,UAU7B,CAAC;AAEF,eAAO,MAAM,eAAe,UAG3B,CAAC;AAEF,eAAO,MAAM,QAAQ,UAKpB,CAAC;AAGF,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAI5D;AAED,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAGhF;AAED,wBAAgB,uBAAuB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAIjE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAI/D;AAED,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAIzD"}
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ /**
3
+ * Contract utilities for claws CLI
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.WETH_ABI = exports.SWAP_ROUTER_ABI = exports.FEE_COLLECTOR_ABI = exports.TOKEN_ABI = exports.FACTORY_ABI = void 0;
7
+ exports.getFactoryContract = getFactoryContract;
8
+ exports.getTokenContract = getTokenContract;
9
+ exports.getFeeCollectorContract = getFeeCollectorContract;
10
+ exports.getSwapRouterContract = getSwapRouterContract;
11
+ exports.getWethContract = getWethContract;
12
+ const ethers_1 = require("ethers");
13
+ const config_1 = require("./config");
14
+ // Minimal ABIs for CLI operations
15
+ exports.FACTORY_ABI = [
16
+ 'function createAgent(address agentWallet, address creatorWallet, string name, string symbol, string socialHandle, string memoryCID, string avatarCID, string ensName) external payable returns (address token, uint256 nftId, address pool, uint256 positionId)',
17
+ 'function createAgent(address agentWallet, address creatorWallet, string name, string symbol, string socialHandle, string memoryCID, string avatarCID, string ensName, uint256 initialBuyETH) external payable returns (address token, uint256 nftId, address pool, uint256 positionId)',
18
+ 'function createMicroAgent(address agentWallet, address creatorWallet, string name, string symbol, string socialHandle, string memoryCID, string avatarCID, string ensName, uint256 initialBuyETH) external payable returns (address token, uint256 nftId, address pool, uint256 positionId)',
19
+ 'function tokenByWallet(address) external view returns (address)',
20
+ 'function walletByToken(address) external view returns (address)',
21
+ 'function isAgent(address) external view returns (bool)',
22
+ 'function agentTier(address) external view returns (uint8)',
23
+ 'function PREMIUM_TOTAL() external view returns (uint256)',
24
+ 'function MICRO_TOTAL() external view returns (uint256)',
25
+ 'event AgentBorn(address indexed wallet, address indexed token, address indexed creator, uint256 nftId, address pool, uint256 positionId, string name, uint8 tier, uint256 initialBuyAmount, uint256 timestamp)',
26
+ ];
27
+ exports.TOKEN_ABI = [
28
+ 'function name() external view returns (string)',
29
+ 'function symbol() external view returns (string)',
30
+ 'function decimals() external view returns (uint8)',
31
+ 'function totalSupply() external view returns (uint256)',
32
+ 'function balanceOf(address) external view returns (uint256)',
33
+ 'function transfer(address to, uint256 amount) external returns (bool)',
34
+ 'function approve(address spender, uint256 amount) external returns (bool)',
35
+ 'function agentWallet() external view returns (address)',
36
+ 'function creator() external view returns (address)',
37
+ 'function birthTimestamp() external view returns (uint256)',
38
+ 'function selfCreated() external view returns (bool)',
39
+ 'function launchBlock() external view returns (uint256)',
40
+ 'function getCurrentTaxBps() external view returns (uint256)',
41
+ 'function pool() external view returns (address)',
42
+ 'function feeCollector() external view returns (address)',
43
+ ];
44
+ exports.FEE_COLLECTOR_ABI = [
45
+ 'function collectSingle(address token) external',
46
+ 'function collectBatch(address[] tokens) external',
47
+ 'function manualClaim(address token) external',
48
+ 'function sellTokenTax(address token) external',
49
+ 'function getTotalCollected(address token) external view returns (uint256)',
50
+ 'function getLastCollectionBlock(address token) external view returns (uint256)',
51
+ 'function getPositionId(address token) external view returns (uint256)',
52
+ 'function getFeeSplits(address token) external view returns (uint256 agentPercent, uint256 creatorPercent, uint256 platformPercent, string splitType)',
53
+ 'function getPendingTokenTax(address token) external view returns (uint256)',
54
+ ];
55
+ exports.SWAP_ROUTER_ABI = [
56
+ 'function exactInputSingle((address tokenIn, address tokenOut, uint24 fee, address recipient, uint256 amountIn, uint256 amountOutMinimum, uint160 sqrtPriceLimitX96)) external payable returns (uint256 amountOut)',
57
+ 'function exactOutputSingle((address tokenIn, address tokenOut, uint24 fee, address recipient, uint256 amountOut, uint256 amountInMaximum, uint160 sqrtPriceLimitX96)) external payable returns (uint256 amountIn)',
58
+ ];
59
+ exports.WETH_ABI = [
60
+ 'function deposit() external payable',
61
+ 'function withdraw(uint256) external',
62
+ 'function approve(address spender, uint256 amount) external returns (bool)',
63
+ 'function balanceOf(address) external view returns (uint256)',
64
+ ];
65
+ // Contract getters
66
+ function getFactoryContract(wallet) {
67
+ const addresses = (0, config_1.getNetworkAddresses)();
68
+ const signerOrProvider = wallet || (0, config_1.getProvider)();
69
+ return new ethers_1.Contract(addresses.factory, exports.FACTORY_ABI, signerOrProvider);
70
+ }
71
+ function getTokenContract(tokenAddress, wallet) {
72
+ const signerOrProvider = wallet || (0, config_1.getProvider)();
73
+ return new ethers_1.Contract(tokenAddress, exports.TOKEN_ABI, signerOrProvider);
74
+ }
75
+ function getFeeCollectorContract(wallet) {
76
+ const addresses = (0, config_1.getNetworkAddresses)();
77
+ const signerOrProvider = wallet || (0, config_1.getProvider)();
78
+ return new ethers_1.Contract(addresses.feeCollector, exports.FEE_COLLECTOR_ABI, signerOrProvider);
79
+ }
80
+ function getSwapRouterContract(wallet) {
81
+ const addresses = (0, config_1.getNetworkAddresses)();
82
+ const signerOrProvider = wallet || (0, config_1.getProvider)();
83
+ return new ethers_1.Contract(addresses.swapRouter, exports.SWAP_ROUTER_ABI, signerOrProvider);
84
+ }
85
+ function getWethContract(wallet) {
86
+ const addresses = (0, config_1.getNetworkAddresses)();
87
+ const signerOrProvider = wallet || (0, config_1.getProvider)();
88
+ return new ethers_1.Contract(addresses.weth, exports.WETH_ABI, signerOrProvider);
89
+ }
90
+ //# sourceMappingURL=contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../src/utils/contracts.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AA8DH,gDAIC;AAED,4CAGC;AAED,0DAIC;AAED,sDAIC;AAED,0CAIC;AAvFD,mCAAkD;AAClD,qCAAuE;AAEvE,kCAAkC;AACrB,QAAA,WAAW,GAAG;IACzB,iQAAiQ;IACjQ,wRAAwR;IACxR,6RAA6R;IAC7R,iEAAiE;IACjE,iEAAiE;IACjE,wDAAwD;IACxD,2DAA2D;IAC3D,0DAA0D;IAC1D,wDAAwD;IACxD,gNAAgN;CACjN,CAAC;AAEW,QAAA,SAAS,GAAG;IACvB,gDAAgD;IAChD,kDAAkD;IAClD,mDAAmD;IACnD,wDAAwD;IACxD,6DAA6D;IAC7D,uEAAuE;IACvE,2EAA2E;IAC3E,wDAAwD;IACxD,oDAAoD;IACpD,2DAA2D;IAC3D,qDAAqD;IACrD,wDAAwD;IACxD,6DAA6D;IAC7D,iDAAiD;IACjD,yDAAyD;CAC1D,CAAC;AAEW,QAAA,iBAAiB,GAAG;IAC/B,gDAAgD;IAChD,kDAAkD;IAClD,8CAA8C;IAC9C,+CAA+C;IAC/C,2EAA2E;IAC3E,gFAAgF;IAChF,uEAAuE;IACvE,sJAAsJ;IACtJ,4EAA4E;CAC7E,CAAC;AAEW,QAAA,eAAe,GAAG;IAC7B,mNAAmN;IACnN,mNAAmN;CACpN,CAAC;AAEW,QAAA,QAAQ,GAAG;IACtB,qCAAqC;IACrC,qCAAqC;IACrC,2EAA2E;IAC3E,6DAA6D;CAC9D,CAAC;AAEF,mBAAmB;AACnB,SAAgB,kBAAkB,CAAC,MAAe;IAChD,MAAM,SAAS,GAAG,IAAA,4BAAmB,GAAE,CAAC;IACxC,MAAM,gBAAgB,GAAG,MAAM,IAAI,IAAA,oBAAW,GAAE,CAAC;IACjD,OAAO,IAAI,iBAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,mBAAW,EAAE,gBAAgB,CAAC,CAAC;AACxE,CAAC;AAED,SAAgB,gBAAgB,CAAC,YAAoB,EAAE,MAAe;IACpE,MAAM,gBAAgB,GAAG,MAAM,IAAI,IAAA,oBAAW,GAAE,CAAC;IACjD,OAAO,IAAI,iBAAQ,CAAC,YAAY,EAAE,iBAAS,EAAE,gBAAgB,CAAC,CAAC;AACjE,CAAC;AAED,SAAgB,uBAAuB,CAAC,MAAe;IACrD,MAAM,SAAS,GAAG,IAAA,4BAAmB,GAAE,CAAC;IACxC,MAAM,gBAAgB,GAAG,MAAM,IAAI,IAAA,oBAAW,GAAE,CAAC;IACjD,OAAO,IAAI,iBAAQ,CAAC,SAAS,CAAC,YAAY,EAAE,yBAAiB,EAAE,gBAAgB,CAAC,CAAC;AACnF,CAAC;AAED,SAAgB,qBAAqB,CAAC,MAAe;IACnD,MAAM,SAAS,GAAG,IAAA,4BAAmB,GAAE,CAAC;IACxC,MAAM,gBAAgB,GAAG,MAAM,IAAI,IAAA,oBAAW,GAAE,CAAC;IACjD,OAAO,IAAI,iBAAQ,CAAC,SAAS,CAAC,UAAU,EAAE,uBAAe,EAAE,gBAAgB,CAAC,CAAC;AAC/E,CAAC;AAED,SAAgB,eAAe,CAAC,MAAe;IAC7C,MAAM,SAAS,GAAG,IAAA,4BAAmB,GAAE,CAAC;IACxC,MAAM,gBAAgB,GAAG,MAAM,IAAI,IAAA,oBAAW,GAAE,CAAC;IACjD,OAAO,IAAI,iBAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,gBAAQ,EAAE,gBAAgB,CAAC,CAAC;AAClE,CAAC"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@claws.fun/cli",
3
+ "version": "1.0.0",
4
+ "description": "CLI tool for AI agents to interact with claws.fun",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "claws": "./dist/index.js",
8
+ "claws-fun": "./dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "start": "node dist/index.js",
13
+ "dev": "ts-node src/index.ts",
14
+ "prepublishOnly": "npm run build"
15
+ },
16
+ "keywords": [
17
+ "claws.fun",
18
+ "ai",
19
+ "agents",
20
+ "blockchain",
21
+ "crypto",
22
+ "immortal"
23
+ ],
24
+ "author": "claws.fun",
25
+ "license": "MIT",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/ClawsFun/claws-fun.git",
29
+ "directory": "cli"
30
+ },
31
+ "engines": {
32
+ "node": ">=18.0.0"
33
+ },
34
+ "dependencies": {
35
+ "commander": "^12.0.0",
36
+ "chalk": "^5.3.0",
37
+ "ethers": "^6.9.0",
38
+ "ora": "^7.0.1",
39
+ "inquirer": "^9.2.0",
40
+ "dotenv": "^16.3.0"
41
+ },
42
+ "devDependencies": {
43
+ "@types/node": "^20.0.0",
44
+ "@types/inquirer": "^9.0.0",
45
+ "typescript": "^5.3.0",
46
+ "ts-node": "^10.9.0"
47
+ }
48
+ }
@@ -0,0 +1,136 @@
1
+ /**
2
+ * claws buy - Buy agent tokens
3
+ */
4
+
5
+ import { Command } from 'commander';
6
+ import { ethers } from 'ethers';
7
+ import chalk from 'chalk';
8
+ import ora from 'ora';
9
+ import inquirer from 'inquirer';
10
+ import { getWallet, hasWallet, getConfig, getNetworkAddresses } from '../utils/config';
11
+ import { getTokenContract, getSwapRouterContract, getWethContract } from '../utils/contracts';
12
+
13
+ export const buyCommand = new Command('buy')
14
+ .description('Buy agent tokens')
15
+ .argument('<token>', 'Token address to buy')
16
+ .option('-a, --amount <eth>', 'ETH amount to spend')
17
+ .option('-y, --yes', 'Skip confirmation')
18
+ .action(async (tokenAddress, options) => {
19
+ console.log(chalk.cyan('\n🦞 Buy Agent Tokens\n'));
20
+
21
+ if (!hasWallet()) {
22
+ console.log(chalk.red('No wallet configured. Run: claws config --key <privateKey>'));
23
+ return;
24
+ }
25
+
26
+ const wallet = getWallet()!;
27
+ const config = getConfig();
28
+ const addresses = getNetworkAddresses();
29
+
30
+ console.log(chalk.gray(`Network: ${config.network}`));
31
+ console.log(chalk.gray(`Wallet: ${wallet.address}\n`));
32
+
33
+ // Get token info
34
+ const token = getTokenContract(tokenAddress, wallet);
35
+
36
+ try {
37
+ const name = await token.name();
38
+ const symbol = await token.symbol();
39
+ const pool = await token.pool();
40
+ const taxBps = await token.getCurrentTaxBps();
41
+
42
+ console.log(chalk.yellow('Token Info:'));
43
+ console.log(` Name: ${chalk.white(name)}`);
44
+ console.log(` Symbol: ${chalk.white(symbol)}`);
45
+ console.log(` Pool: ${chalk.gray(pool)}`);
46
+ console.log(` Tax: ${chalk.red(Number(taxBps) / 100 + '%')}`);
47
+
48
+ // Get amount
49
+ let amountEth = options.amount;
50
+ if (!amountEth) {
51
+ const { amount } = await inquirer.prompt([{
52
+ type: 'input',
53
+ name: 'amount',
54
+ message: 'ETH amount to spend:',
55
+ validate: (input: string) => {
56
+ const num = parseFloat(input);
57
+ return num > 0 || 'Must be greater than 0';
58
+ },
59
+ }]);
60
+ amountEth = amount;
61
+ }
62
+
63
+ const amountWei = ethers.parseEther(amountEth);
64
+
65
+ // Check balance
66
+ const balance = await wallet.provider?.getBalance(wallet.address);
67
+ if (balance && balance < amountWei) {
68
+ console.log(chalk.red(`Insufficient balance. Have ${ethers.formatEther(balance)} ETH`));
69
+ return;
70
+ }
71
+
72
+ // Calculate expected output (rough estimate)
73
+ const taxDeduction = Number(taxBps) / 10000;
74
+ const effectiveEth = Number(amountEth) * (1 - taxDeduction);
75
+ console.log(`\n Spending: ${chalk.cyan(amountEth)} ETH`);
76
+ console.log(` After ${Number(taxBps)/100}% tax: ~${chalk.cyan(effectiveEth.toFixed(6))} ETH worth of tokens`);
77
+
78
+ // Confirmation
79
+ if (!options.yes) {
80
+ const { confirm } = await inquirer.prompt([{
81
+ type: 'confirm',
82
+ name: 'confirm',
83
+ message: 'Proceed with purchase?',
84
+ default: true,
85
+ }]);
86
+
87
+ if (!confirm) {
88
+ console.log(chalk.yellow('Cancelled'));
89
+ return;
90
+ }
91
+ }
92
+
93
+ // Execute swap
94
+ const spinner = ora('Executing swap...').start();
95
+
96
+ const swapRouter = getSwapRouterContract(wallet);
97
+ const weth = getWethContract(wallet);
98
+
99
+ // Wrap ETH to WETH
100
+ spinner.text = 'Wrapping ETH to WETH...';
101
+ const wrapTx = await weth.deposit({ value: amountWei });
102
+ await wrapTx.wait();
103
+
104
+ // Approve router
105
+ spinner.text = 'Approving router...';
106
+ const approveTx = await weth.approve(addresses.swapRouter, amountWei);
107
+ await approveTx.wait();
108
+
109
+ // Swap WETH for tokens
110
+ spinner.text = 'Swapping for tokens...';
111
+ const swapParams = {
112
+ tokenIn: addresses.weth,
113
+ tokenOut: tokenAddress,
114
+ fee: 10000, // 1% fee tier
115
+ recipient: wallet.address,
116
+ amountIn: amountWei,
117
+ amountOutMinimum: 0, // No slippage protection for simplicity
118
+ sqrtPriceLimitX96: 0,
119
+ };
120
+
121
+ const swapTx = await swapRouter.exactInputSingle(swapParams);
122
+ const receipt = await swapTx.wait();
123
+
124
+ // Get new balance
125
+ const tokenBalance = await token.balanceOf(wallet.address);
126
+
127
+ spinner.succeed(chalk.green('Purchase complete!'));
128
+
129
+ console.log('\n' + chalk.yellow('Result:'));
130
+ console.log(` Tokens received: ${chalk.green(ethers.formatEther(tokenBalance))} ${symbol}`);
131
+ console.log(` TX Hash: ${chalk.gray(receipt.hash)}`);
132
+
133
+ } catch (error: any) {
134
+ console.log(chalk.red(`Error: ${error.message || error}`));
135
+ }
136
+ });
@@ -0,0 +1,152 @@
1
+ /**
2
+ * claws claim - Claim accumulated fees
3
+ */
4
+
5
+ import { Command } from 'commander';
6
+ import { ethers } from 'ethers';
7
+ import chalk from 'chalk';
8
+ import ora from 'ora';
9
+ import inquirer from 'inquirer';
10
+ import { getWallet, hasWallet, getConfig } from '../utils/config';
11
+ import { getTokenContract, getFeeCollectorContract, getFactoryContract } from '../utils/contracts';
12
+
13
+ export const claimCommand = new Command('claim')
14
+ .description('Claim accumulated trading fees')
15
+ .argument('[token]', 'Token address (optional if you have one agent)')
16
+ .option('-y, --yes', 'Skip confirmation')
17
+ .option('--sell-tax', 'Also sell accumulated token tax')
18
+ .action(async (tokenAddress, options) => {
19
+ console.log(chalk.cyan('\n🦞 Claim Agent Fees\n'));
20
+
21
+ if (!hasWallet()) {
22
+ console.log(chalk.red('No wallet configured. Run: claws config --key <privateKey>'));
23
+ return;
24
+ }
25
+
26
+ const wallet = getWallet()!;
27
+ const config = getConfig();
28
+
29
+ console.log(chalk.gray(`Network: ${config.network}`));
30
+ console.log(chalk.gray(`Wallet: ${wallet.address}\n`));
31
+
32
+ // If no token provided, try to find user's agent
33
+ if (!tokenAddress) {
34
+ const factory = getFactoryContract(wallet);
35
+ tokenAddress = await factory.tokenByWallet(wallet.address);
36
+
37
+ if (!tokenAddress || tokenAddress === ethers.ZeroAddress) {
38
+ console.log(chalk.red('No token address provided and no agent found for this wallet'));
39
+ console.log(chalk.gray('Usage: claws claim <token-address>'));
40
+ return;
41
+ }
42
+ console.log(chalk.gray(`Found your agent token: ${tokenAddress}\n`));
43
+ }
44
+
45
+ // Get token and fee collector info
46
+ const token = getTokenContract(tokenAddress, wallet);
47
+ const feeCollector = getFeeCollectorContract(wallet);
48
+
49
+ try {
50
+ const name = await token.name();
51
+ const symbol = await token.symbol();
52
+ const agentWallet = await token.agentWallet();
53
+
54
+ // Get fee info
55
+ const [agentPercent, creatorPercent, platformPercent, splitType] = await feeCollector.getFeeSplits(tokenAddress);
56
+ const totalCollected = await feeCollector.getTotalCollected(tokenAddress);
57
+ const lastBlock = await feeCollector.getLastCollectionBlock(tokenAddress);
58
+ const pendingTax = await feeCollector.getPendingTokenTax(tokenAddress);
59
+
60
+ console.log(chalk.yellow('Agent Info:'));
61
+ console.log(` Name: ${chalk.white(name)}`);
62
+ console.log(` Symbol: ${chalk.white(symbol)}`);
63
+ console.log(` Wallet: ${chalk.gray(agentWallet)}`);
64
+ console.log(` Type: ${chalk.green(splitType)}`);
65
+
66
+ console.log('\n' + chalk.yellow('Fee Splits:'));
67
+ console.log(` Agent: ${chalk.green(agentPercent.toString() + '%')}`);
68
+ if (Number(creatorPercent) > 0) {
69
+ console.log(` Creator: ${chalk.cyan(creatorPercent.toString() + '%')}`);
70
+ }
71
+ console.log(` Platform: ${chalk.gray(platformPercent.toString() + '%')}`);
72
+
73
+ console.log('\n' + chalk.yellow('Collection Status:'));
74
+ console.log(` Total Collected: ${chalk.cyan(ethers.formatEther(totalCollected))} ETH`);
75
+ console.log(` Last Collection: Block ${chalk.gray(lastBlock.toString())}`);
76
+ console.log(` Pending Tax: ${chalk.cyan(ethers.formatEther(pendingTax))} tokens`);
77
+
78
+ // Check if caller is agent or creator
79
+ const creator = await token.creator();
80
+ const canClaim = wallet.address.toLowerCase() === agentWallet.toLowerCase() ||
81
+ wallet.address.toLowerCase() === creator.toLowerCase();
82
+
83
+ if (!canClaim) {
84
+ console.log(chalk.yellow('\n⚠️ You are not the agent or creator. Only they can manual claim.'));
85
+ console.log(chalk.gray('Anyone can trigger collectSingle() to collect LP fees.'));
86
+ }
87
+
88
+ // Confirmation
89
+ if (!options.yes) {
90
+ const choices = ['Collect LP fees (collectSingle)'];
91
+ if (canClaim) {
92
+ choices.push('Manual claim (emergency backup)');
93
+ }
94
+ if (pendingTax > 0n) {
95
+ choices.push('Sell token tax');
96
+ }
97
+ choices.push('Cancel');
98
+
99
+ const { action } = await inquirer.prompt([{
100
+ type: 'list',
101
+ name: 'action',
102
+ message: 'What would you like to do?',
103
+ choices,
104
+ }]);
105
+
106
+ if (action === 'Cancel') {
107
+ console.log(chalk.yellow('Cancelled'));
108
+ return;
109
+ }
110
+
111
+ const spinner = ora('Processing...').start();
112
+
113
+ if (action.includes('collectSingle')) {
114
+ spinner.text = 'Collecting LP fees...';
115
+ const tx = await feeCollector.collectSingle(tokenAddress);
116
+ const receipt = await tx.wait();
117
+ spinner.succeed(chalk.green('LP fees collected!'));
118
+ console.log(` TX Hash: ${chalk.gray(receipt.hash)}`);
119
+ } else if (action.includes('Manual claim')) {
120
+ spinner.text = 'Manual claiming...';
121
+ const tx = await feeCollector.manualClaim(tokenAddress);
122
+ const receipt = await tx.wait();
123
+ spinner.succeed(chalk.green('Manual claim complete!'));
124
+ console.log(` TX Hash: ${chalk.gray(receipt.hash)}`);
125
+ } else if (action.includes('Sell token tax')) {
126
+ spinner.text = 'Selling token tax...';
127
+ const tx = await feeCollector.sellTokenTax(tokenAddress);
128
+ const receipt = await tx.wait();
129
+ spinner.succeed(chalk.green('Token tax sold and distributed!'));
130
+ console.log(` TX Hash: ${chalk.gray(receipt.hash)}`);
131
+ }
132
+ } else {
133
+ // Auto mode - collect LP fees
134
+ const spinner = ora('Collecting LP fees...').start();
135
+ const tx = await feeCollector.collectSingle(tokenAddress);
136
+ const receipt = await tx.wait();
137
+ spinner.succeed(chalk.green('LP fees collected!'));
138
+ console.log(` TX Hash: ${chalk.gray(receipt.hash)}`);
139
+
140
+ // Optionally sell token tax
141
+ if (options.sellTax && pendingTax > 0n) {
142
+ const taxSpinner = ora('Selling token tax...').start();
143
+ const taxTx = await feeCollector.sellTokenTax(tokenAddress);
144
+ await taxTx.wait();
145
+ taxSpinner.succeed(chalk.green('Token tax sold!'));
146
+ }
147
+ }
148
+
149
+ } catch (error: any) {
150
+ console.log(chalk.red(`Error: ${error.message || error}`));
151
+ }
152
+ });