@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.
- package/README.md +204 -0
- package/dist/commands/buy.d.ts +6 -0
- package/dist/commands/buy.d.ts.map +1 -0
- package/dist/commands/buy.js +120 -0
- package/dist/commands/buy.js.map +1 -0
- package/dist/commands/claim.d.ts +6 -0
- package/dist/commands/claim.d.ts.map +1 -0
- package/dist/commands/claim.js +141 -0
- package/dist/commands/claim.js.map +1 -0
- package/dist/commands/config.d.ts +6 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +107 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/create.d.ts +6 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +174 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/sell.d.ts +6 -0
- package/dist/commands/sell.d.ts.map +1 -0
- package/dist/commands/sell.js +134 -0
- package/dist/commands/sell.js.map +1 -0
- package/dist/commands/status.d.ts +6 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +138 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/config.d.ts +30 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +176 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/contracts.d.ts +15 -0
- package/dist/utils/contracts.d.ts.map +1 -0
- package/dist/utils/contracts.js +90 -0
- package/dist/utils/contracts.js.map +1 -0
- package/package.json +48 -0
- package/src/commands/buy.ts +136 -0
- package/src/commands/claim.ts +152 -0
- package/src/commands/config.ts +77 -0
- package/src/commands/create.ts +217 -0
- package/src/commands/sell.ts +149 -0
- package/src/commands/status.ts +148 -0
- package/src/index.ts +41 -0
- package/src/utils/config.ts +159 -0
- package/src/utils/contracts.ts +92 -0
- 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
|
+
});
|