pay-lobster 1.1.2 ā 1.1.3
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/dist/cli.d.ts +7 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +468 -0
- package/dist/cli.js.map +1 -0
- package/lib/cli.ts +508 -0
- package/package.json +7 -6
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../lib/cli.ts"],"names":[],"mappings":";AAEA;;;GAGG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Pay Lobster CLI - Setup Wizard & Commands
|
|
5
|
+
* š¦ Payment infrastructure for AI agents
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const readline = __importStar(require("readline"));
|
|
44
|
+
const ethers_1 = require("ethers");
|
|
45
|
+
// Colors for terminal output
|
|
46
|
+
const colors = {
|
|
47
|
+
reset: '\x1b[0m',
|
|
48
|
+
bright: '\x1b[1m',
|
|
49
|
+
dim: '\x1b[2m',
|
|
50
|
+
red: '\x1b[31m',
|
|
51
|
+
green: '\x1b[32m',
|
|
52
|
+
yellow: '\x1b[33m',
|
|
53
|
+
blue: '\x1b[34m',
|
|
54
|
+
magenta: '\x1b[35m',
|
|
55
|
+
cyan: '\x1b[36m',
|
|
56
|
+
white: '\x1b[37m',
|
|
57
|
+
};
|
|
58
|
+
const c = colors;
|
|
59
|
+
// Config file location
|
|
60
|
+
const CONFIG_DIR = path.join(process.env.HOME || '~', '.paylobster');
|
|
61
|
+
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
62
|
+
const DEFAULT_CONFIG = {
|
|
63
|
+
network: 'base',
|
|
64
|
+
rpcUrl: 'https://mainnet.base.org',
|
|
65
|
+
setupComplete: false,
|
|
66
|
+
version: '1.1.2',
|
|
67
|
+
};
|
|
68
|
+
// ASCII Art Banner
|
|
69
|
+
function showBanner() {
|
|
70
|
+
console.log(`
|
|
71
|
+
${c.cyan} āāāāāāā āāāāāā āāā āāā āāā āāāāāāā āāāāāāā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
72
|
+
āāāāāāāāāāāāāāāāāāāā āāāā āāā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
73
|
+
āāāāāāāāāāāāāāāā āāāāāāā āāā āāā āāāāāāāāāāāāāāāāāāā āāā āāāāāā āāāāāāāā
|
|
74
|
+
āāāāāāā āāāāāāāā āāāāā āāā āāā āāāāāāāāāāāāāāāāāāā āāā āāāāāā āāāāāāāā
|
|
75
|
+
āāā āāā āāā āāā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā āāā āāāāāāāāāāā āāā
|
|
76
|
+
āāā āāā āāā āāā āāāāāāāā āāāāāāā āāāāāāā āāāāāāāā āāā āāāāāāāāāāā āāā${c.reset}
|
|
77
|
+
|
|
78
|
+
${c.dim}š¦ Payment Infrastructure for AI Agents${c.reset}
|
|
79
|
+
${c.dim} Built on Base ⢠Powered by USDC${c.reset}
|
|
80
|
+
`);
|
|
81
|
+
}
|
|
82
|
+
// Create readline interface
|
|
83
|
+
function createRL() {
|
|
84
|
+
return readline.createInterface({
|
|
85
|
+
input: process.stdin,
|
|
86
|
+
output: process.stdout,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
// Prompt helper
|
|
90
|
+
function prompt(rl, question) {
|
|
91
|
+
return new Promise((resolve) => {
|
|
92
|
+
rl.question(question, (answer) => {
|
|
93
|
+
resolve(answer.trim());
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
// Prompt for password (hidden input)
|
|
98
|
+
function promptSecret(rl, question) {
|
|
99
|
+
return new Promise((resolve) => {
|
|
100
|
+
process.stdout.write(question);
|
|
101
|
+
const stdin = process.stdin;
|
|
102
|
+
const wasRaw = stdin.isRaw;
|
|
103
|
+
if (stdin.setRawMode) {
|
|
104
|
+
stdin.setRawMode(true);
|
|
105
|
+
}
|
|
106
|
+
stdin.resume();
|
|
107
|
+
let input = '';
|
|
108
|
+
const onData = (char) => {
|
|
109
|
+
const c = char.toString();
|
|
110
|
+
if (c === '\n' || c === '\r') {
|
|
111
|
+
stdin.removeListener('data', onData);
|
|
112
|
+
if (stdin.setRawMode) {
|
|
113
|
+
stdin.setRawMode(wasRaw || false);
|
|
114
|
+
}
|
|
115
|
+
console.log();
|
|
116
|
+
resolve(input);
|
|
117
|
+
}
|
|
118
|
+
else if (c === '\u0003') {
|
|
119
|
+
process.exit();
|
|
120
|
+
}
|
|
121
|
+
else if (c === '\u007F') {
|
|
122
|
+
input = input.slice(0, -1);
|
|
123
|
+
process.stdout.write('\b \b');
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
input += c;
|
|
127
|
+
process.stdout.write('*');
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
stdin.on('data', onData);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
// Load config
|
|
134
|
+
function loadConfig() {
|
|
135
|
+
try {
|
|
136
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
137
|
+
const data = fs.readFileSync(CONFIG_FILE, 'utf-8');
|
|
138
|
+
return { ...DEFAULT_CONFIG, ...JSON.parse(data) };
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch (e) {
|
|
142
|
+
// Ignore errors, return default
|
|
143
|
+
}
|
|
144
|
+
return { ...DEFAULT_CONFIG };
|
|
145
|
+
}
|
|
146
|
+
// Save config
|
|
147
|
+
function saveConfig(config) {
|
|
148
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
149
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
|
|
150
|
+
}
|
|
151
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), { mode: 0o600 });
|
|
152
|
+
}
|
|
153
|
+
// Validate private key
|
|
154
|
+
function isValidPrivateKey(key) {
|
|
155
|
+
try {
|
|
156
|
+
const cleanKey = key.startsWith('0x') ? key : `0x${key}`;
|
|
157
|
+
new ethers_1.ethers.Wallet(cleanKey);
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Get wallet address from private key
|
|
165
|
+
function getAddress(privateKey) {
|
|
166
|
+
const cleanKey = privateKey.startsWith('0x') ? privateKey : `0x${privateKey}`;
|
|
167
|
+
const wallet = new ethers_1.ethers.Wallet(cleanKey);
|
|
168
|
+
return wallet.address;
|
|
169
|
+
}
|
|
170
|
+
// Setup wizard
|
|
171
|
+
async function runSetupWizard() {
|
|
172
|
+
const rl = createRL();
|
|
173
|
+
const config = loadConfig();
|
|
174
|
+
console.log(`\n${c.bright}${c.cyan}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā${c.reset}`);
|
|
175
|
+
console.log(`${c.bright} š¦ Pay Lobster Setup Wizard${c.reset}`);
|
|
176
|
+
console.log(`${c.bright}${c.cyan}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā${c.reset}\n`);
|
|
177
|
+
console.log(`${c.dim}This wizard will help you configure Pay Lobster for your AI agent.${c.reset}`);
|
|
178
|
+
console.log(`${c.dim}Your configuration will be stored securely at: ${CONFIG_FILE}${c.reset}\n`);
|
|
179
|
+
// Step 1: Agent Name
|
|
180
|
+
console.log(`${c.yellow}Step 1/4:${c.reset} ${c.bright}Agent Name${c.reset}`);
|
|
181
|
+
console.log(`${c.dim}Give your agent a name for the registry.${c.reset}\n`);
|
|
182
|
+
const agentName = await prompt(rl, `${c.green}āÆ${c.reset} Agent name: `);
|
|
183
|
+
config.agentName = agentName || 'MyAgent';
|
|
184
|
+
console.log(`${c.green}ā${c.reset} Agent: ${c.bright}${config.agentName}${c.reset}\n`);
|
|
185
|
+
// Step 2: Network Selection
|
|
186
|
+
console.log(`${c.yellow}Step 2/4:${c.reset} ${c.bright}Network${c.reset}`);
|
|
187
|
+
console.log(`${c.dim}Choose your network. Use testnet for development.${c.reset}\n`);
|
|
188
|
+
console.log(` ${c.cyan}1)${c.reset} Base Mainnet ${c.dim}(production, real USDC)${c.reset}`);
|
|
189
|
+
console.log(` ${c.cyan}2)${c.reset} Base Sepolia ${c.dim}(testnet, free test USDC)${c.reset}\n`);
|
|
190
|
+
const networkChoice = await prompt(rl, `${c.green}āÆ${c.reset} Select network [1/2]: `);
|
|
191
|
+
if (networkChoice === '2') {
|
|
192
|
+
config.network = 'base-sepolia';
|
|
193
|
+
config.rpcUrl = 'https://sepolia.base.org';
|
|
194
|
+
console.log(`${c.green}ā${c.reset} Network: ${c.yellow}Base Sepolia (Testnet)${c.reset}\n`);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
config.network = 'base';
|
|
198
|
+
config.rpcUrl = 'https://mainnet.base.org';
|
|
199
|
+
console.log(`${c.green}ā${c.reset} Network: ${c.bright}Base Mainnet${c.reset}\n`);
|
|
200
|
+
}
|
|
201
|
+
// Step 3: Wallet Setup
|
|
202
|
+
console.log(`${c.yellow}Step 3/4:${c.reset} ${c.bright}Wallet Setup${c.reset}`);
|
|
203
|
+
console.log(`${c.dim}You need a wallet to send and receive USDC.${c.reset}\n`);
|
|
204
|
+
console.log(` ${c.cyan}1)${c.reset} Generate new wallet ${c.dim}(recommended for new users)${c.reset}`);
|
|
205
|
+
console.log(` ${c.cyan}2)${c.reset} Import existing private key ${c.dim}(for existing wallets)${c.reset}`);
|
|
206
|
+
console.log(` ${c.cyan}3)${c.reset} Skip for now ${c.dim}(read-only mode)${c.reset}\n`);
|
|
207
|
+
const walletChoice = await prompt(rl, `${c.green}āÆ${c.reset} Select option [1/2/3]: `);
|
|
208
|
+
if (walletChoice === '1') {
|
|
209
|
+
// Generate new wallet
|
|
210
|
+
const wallet = ethers_1.ethers.Wallet.createRandom();
|
|
211
|
+
config.privateKey = wallet.privateKey;
|
|
212
|
+
console.log(`\n${c.green}ā${c.reset} New wallet generated!\n`);
|
|
213
|
+
console.log(`${c.bright}${c.cyan}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā${c.reset}`);
|
|
214
|
+
console.log(`${c.bright}${c.cyan}ā${c.reset} ${c.bright}ā ļø SAVE THIS INFORMATION SECURELY!${c.reset} ${c.cyan}ā${c.reset}`);
|
|
215
|
+
console.log(`${c.bright}${c.cyan}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤${c.reset}`);
|
|
216
|
+
console.log(`${c.cyan}ā${c.reset} Address: ${c.green}${wallet.address}${c.reset} ${c.cyan}ā${c.reset}`);
|
|
217
|
+
console.log(`${c.cyan}ā${c.reset} Private Key: ${c.yellow}${wallet.privateKey.slice(0, 20)}...${c.reset} ${c.cyan}ā${c.reset}`);
|
|
218
|
+
console.log(`${c.bright}${c.cyan}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā${c.reset}`);
|
|
219
|
+
console.log(`\n${c.red}${c.bright}IMPORTANT:${c.reset} ${c.dim}Write down your private key and store it safely.${c.reset}`);
|
|
220
|
+
console.log(`${c.dim}If you lose it, you lose access to your funds forever.${c.reset}\n`);
|
|
221
|
+
await prompt(rl, `${c.yellow}Press Enter when you've saved your key...${c.reset}`);
|
|
222
|
+
console.log();
|
|
223
|
+
}
|
|
224
|
+
else if (walletChoice === '2') {
|
|
225
|
+
// Import existing
|
|
226
|
+
console.log(`\n${c.dim}Enter your private key (input is hidden):${c.reset}\n`);
|
|
227
|
+
let validKey = false;
|
|
228
|
+
while (!validKey) {
|
|
229
|
+
const privateKey = await promptSecret(rl, `${c.green}āÆ${c.reset} Private key: `);
|
|
230
|
+
if (isValidPrivateKey(privateKey)) {
|
|
231
|
+
config.privateKey = privateKey.startsWith('0x') ? privateKey : `0x${privateKey}`;
|
|
232
|
+
const address = getAddress(config.privateKey);
|
|
233
|
+
console.log(`${c.green}ā${c.reset} Wallet imported: ${c.bright}${address}${c.reset}\n`);
|
|
234
|
+
validKey = true;
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
console.log(`${c.red}ā${c.reset} Invalid private key. Please try again.\n`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
console.log(`${c.yellow}ā ${c.reset} Skipping wallet setup. You'll only be able to read data.\n`);
|
|
243
|
+
}
|
|
244
|
+
// Step 4: Verify & Complete
|
|
245
|
+
console.log(`${c.yellow}Step 4/4:${c.reset} ${c.bright}Verification${c.reset}\n`);
|
|
246
|
+
// Test RPC connection
|
|
247
|
+
process.stdout.write(`${c.dim}Testing connection to ${config.network}...${c.reset} `);
|
|
248
|
+
try {
|
|
249
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
250
|
+
const blockNumber = await provider.getBlockNumber();
|
|
251
|
+
console.log(`${c.green}ā${c.reset} Connected (block #${blockNumber})`);
|
|
252
|
+
}
|
|
253
|
+
catch (e) {
|
|
254
|
+
console.log(`${c.red}ā${c.reset} Failed to connect`);
|
|
255
|
+
}
|
|
256
|
+
// Check balance if wallet configured
|
|
257
|
+
if (config.privateKey) {
|
|
258
|
+
process.stdout.write(`${c.dim}Checking USDC balance...${c.reset} `);
|
|
259
|
+
try {
|
|
260
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
261
|
+
const usdcAddress = config.network === 'base'
|
|
262
|
+
? '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
|
|
263
|
+
: '0x036CbD53842c5426634e7929541eC2318f3dCF7e';
|
|
264
|
+
const usdcAbi = ['function balanceOf(address) view returns (uint256)'];
|
|
265
|
+
const usdc = new ethers_1.ethers.Contract(usdcAddress, usdcAbi, provider);
|
|
266
|
+
const address = getAddress(config.privateKey);
|
|
267
|
+
const balance = await usdc.balanceOf(address);
|
|
268
|
+
const formatted = ethers_1.ethers.formatUnits(balance, 6);
|
|
269
|
+
console.log(`${c.green}ā${c.reset} ${formatted} USDC`);
|
|
270
|
+
}
|
|
271
|
+
catch (e) {
|
|
272
|
+
console.log(`${c.yellow}ā ${c.reset} Could not fetch balance`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
// Save config
|
|
276
|
+
config.setupComplete = true;
|
|
277
|
+
saveConfig(config);
|
|
278
|
+
console.log(`\n${c.green}ā${c.reset} Configuration saved to ${c.dim}${CONFIG_FILE}${c.reset}\n`);
|
|
279
|
+
// Success message
|
|
280
|
+
console.log(`${c.bright}${c.green}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā${c.reset}`);
|
|
281
|
+
console.log(`${c.bright}${c.green} š¦ Setup Complete!${c.reset}`);
|
|
282
|
+
console.log(`${c.bright}${c.green}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā${c.reset}\n`);
|
|
283
|
+
console.log(`${c.bright}Quick Start:${c.reset}\n`);
|
|
284
|
+
console.log(` ${c.cyan}paylobster balance${c.reset} Check your USDC balance`);
|
|
285
|
+
console.log(` ${c.cyan}paylobster send${c.reset} Send USDC to an address`);
|
|
286
|
+
console.log(` ${c.cyan}paylobster escrow create${c.reset} Create a new escrow`);
|
|
287
|
+
console.log(` ${c.cyan}paylobster discover${c.reset} Find agents by capability`);
|
|
288
|
+
console.log(` ${c.cyan}paylobster help${c.reset} Show all commands\n`);
|
|
289
|
+
if (config.network === 'base' && config.privateKey) {
|
|
290
|
+
const address = getAddress(config.privateKey);
|
|
291
|
+
console.log(`${c.dim}Fund your wallet with USDC on Base:${c.reset}`);
|
|
292
|
+
console.log(`${c.cyan}${address}${c.reset}\n`);
|
|
293
|
+
}
|
|
294
|
+
console.log(`${c.dim}Docs: https://paylobster.com/docs${c.reset}`);
|
|
295
|
+
console.log(`${c.dim}GitHub: https://github.com/itsGustav/Pay-Lobster${c.reset}\n`);
|
|
296
|
+
rl.close();
|
|
297
|
+
}
|
|
298
|
+
// Show help
|
|
299
|
+
function showHelp() {
|
|
300
|
+
console.log(`
|
|
301
|
+
${c.bright}Pay Lobster CLI${c.reset} - Payment infrastructure for AI agents
|
|
302
|
+
|
|
303
|
+
${c.bright}USAGE${c.reset}
|
|
304
|
+
paylobster <command> [options]
|
|
305
|
+
|
|
306
|
+
${c.bright}COMMANDS${c.reset}
|
|
307
|
+
${c.cyan}setup${c.reset} Run the setup wizard
|
|
308
|
+
${c.cyan}balance${c.reset} Check USDC balance
|
|
309
|
+
${c.cyan}send <amount> <to>${c.reset} Send USDC to address or agent
|
|
310
|
+
${c.cyan}receive${c.reset} Show your wallet address
|
|
311
|
+
${c.cyan}escrow create${c.reset} Create new escrow
|
|
312
|
+
${c.cyan}escrow list${c.reset} List your escrows
|
|
313
|
+
${c.cyan}escrow release <id>${c.reset} Release escrow funds
|
|
314
|
+
${c.cyan}trust <agent>${c.reset} Check agent trust score
|
|
315
|
+
${c.cyan}discover${c.reset} Find agents by capability
|
|
316
|
+
${c.cyan}register${c.reset} Register your agent
|
|
317
|
+
${c.cyan}config${c.reset} Show current configuration
|
|
318
|
+
${c.cyan}help${c.reset} Show this help message
|
|
319
|
+
|
|
320
|
+
${c.bright}EXAMPLES${c.reset}
|
|
321
|
+
${c.dim}# Send 25 USDC to another agent${c.reset}
|
|
322
|
+
paylobster send 25.00 agent:DataAnalyzer
|
|
323
|
+
|
|
324
|
+
${c.dim}# Create escrow for a job${c.reset}
|
|
325
|
+
paylobster escrow create 500 agent:WebDevBot --milestone "Landing page"
|
|
326
|
+
|
|
327
|
+
${c.dim}# Check an agent's reputation${c.reset}
|
|
328
|
+
paylobster trust agent:WebDevBot
|
|
329
|
+
|
|
330
|
+
${c.bright}CONTRACTS (Base Mainnet)${c.reset}
|
|
331
|
+
Escrow: ${c.dim}0xa091fC821c85Dfd2b2B3EF9e22c5f4c8B8A24525${c.reset}
|
|
332
|
+
Registry: ${c.dim}0x10BCa62Ce136A70F914c56D97e491a85d1e050E7${c.reset}
|
|
333
|
+
|
|
334
|
+
${c.dim}Documentation: https://paylobster.com/docs${c.reset}
|
|
335
|
+
`);
|
|
336
|
+
}
|
|
337
|
+
// Show config
|
|
338
|
+
function showConfig() {
|
|
339
|
+
const config = loadConfig();
|
|
340
|
+
console.log(`\n${c.bright}Pay Lobster Configuration${c.reset}\n`);
|
|
341
|
+
console.log(`${c.dim}Config file: ${CONFIG_FILE}${c.reset}\n`);
|
|
342
|
+
console.log(` Agent Name: ${c.cyan}${config.agentName || 'Not set'}${c.reset}`);
|
|
343
|
+
console.log(` Network: ${c.cyan}${config.network}${c.reset}`);
|
|
344
|
+
console.log(` RPC URL: ${c.dim}${config.rpcUrl}${c.reset}`);
|
|
345
|
+
if (config.privateKey) {
|
|
346
|
+
const address = getAddress(config.privateKey);
|
|
347
|
+
console.log(` Wallet: ${c.green}${address}${c.reset}`);
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
console.log(` Wallet: ${c.yellow}Not configured${c.reset}`);
|
|
351
|
+
}
|
|
352
|
+
console.log(` Setup: ${config.setupComplete ? `${c.green}Complete${c.reset}` : `${c.yellow}Incomplete${c.reset}`}`);
|
|
353
|
+
console.log();
|
|
354
|
+
}
|
|
355
|
+
// Check balance command
|
|
356
|
+
async function checkBalance() {
|
|
357
|
+
const config = loadConfig();
|
|
358
|
+
if (!config.privateKey) {
|
|
359
|
+
console.log(`${c.red}ā${c.reset} No wallet configured. Run ${c.cyan}paylobster setup${c.reset} first.`);
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
console.log(`\n${c.dim}š Querying ${config.network}...${c.reset}\n`);
|
|
363
|
+
try {
|
|
364
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
365
|
+
const address = getAddress(config.privateKey);
|
|
366
|
+
// USDC contract
|
|
367
|
+
const usdcAddress = config.network === 'base'
|
|
368
|
+
? '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
|
|
369
|
+
: '0x036CbD53842c5426634e7929541eC2318f3dCF7e';
|
|
370
|
+
const usdcAbi = ['function balanceOf(address) view returns (uint256)'];
|
|
371
|
+
const usdc = new ethers_1.ethers.Contract(usdcAddress, usdcAbi, provider);
|
|
372
|
+
const balance = await usdc.balanceOf(address);
|
|
373
|
+
const formatted = ethers_1.ethers.formatUnits(balance, 6);
|
|
374
|
+
// Get ETH balance for gas
|
|
375
|
+
const ethBalance = await provider.getBalance(address);
|
|
376
|
+
const ethFormatted = ethers_1.ethers.formatEther(ethBalance);
|
|
377
|
+
console.log(`${c.cyan}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā${c.reset}`);
|
|
378
|
+
console.log(`${c.cyan}ā${c.reset} ${c.bright}š° Wallet Balance${c.reset} ${c.cyan}ā${c.reset}`);
|
|
379
|
+
console.log(`${c.cyan}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤${c.reset}`);
|
|
380
|
+
console.log(`${c.cyan}ā${c.reset} USDC: ${c.green}${formatted.padStart(15)} USDC${c.reset} ${c.cyan}ā${c.reset}`);
|
|
381
|
+
console.log(`${c.cyan}ā${c.reset} ETH: ${c.dim}${parseFloat(ethFormatted).toFixed(6).padStart(15)} ETH${c.reset} ${c.cyan}ā${c.reset}`);
|
|
382
|
+
console.log(`${c.cyan}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā${c.reset}`);
|
|
383
|
+
console.log(`\n${c.dim}Wallet: ${address}${c.reset}`);
|
|
384
|
+
console.log(`${c.dim}Network: ${config.network}${c.reset}\n`);
|
|
385
|
+
}
|
|
386
|
+
catch (e) {
|
|
387
|
+
console.log(`${c.red}ā${c.reset} Error: ${e.message}`);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
// Show receive address
|
|
391
|
+
function showReceive() {
|
|
392
|
+
const config = loadConfig();
|
|
393
|
+
if (!config.privateKey) {
|
|
394
|
+
console.log(`${c.red}ā${c.reset} No wallet configured. Run ${c.cyan}paylobster setup${c.reset} first.`);
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
const address = getAddress(config.privateKey);
|
|
398
|
+
console.log(`\n${c.bright}Your Pay Lobster Wallet${c.reset}\n`);
|
|
399
|
+
console.log(`${c.cyan}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā${c.reset}`);
|
|
400
|
+
console.log(`${c.cyan}ā${c.reset} ${c.green}${address}${c.reset} ${c.cyan}ā${c.reset}`);
|
|
401
|
+
console.log(`${c.cyan}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā${c.reset}`);
|
|
402
|
+
console.log(`\n${c.dim}Network: ${config.network}${c.reset}`);
|
|
403
|
+
console.log(`${c.dim}Send USDC on Base to this address.${c.reset}\n`);
|
|
404
|
+
}
|
|
405
|
+
// Main CLI entry point
|
|
406
|
+
async function main() {
|
|
407
|
+
const args = process.argv.slice(2);
|
|
408
|
+
const command = args[0]?.toLowerCase();
|
|
409
|
+
// Check if first run
|
|
410
|
+
const config = loadConfig();
|
|
411
|
+
if (!command || command === 'setup') {
|
|
412
|
+
showBanner();
|
|
413
|
+
await runSetupWizard();
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
// Check if setup needed
|
|
417
|
+
if (!config.setupComplete && command !== 'help') {
|
|
418
|
+
console.log(`\n${c.yellow}ā ${c.reset} Pay Lobster is not configured yet.\n`);
|
|
419
|
+
console.log(`Run ${c.cyan}paylobster setup${c.reset} to get started.\n`);
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
switch (command) {
|
|
423
|
+
case 'help':
|
|
424
|
+
case '--help':
|
|
425
|
+
case '-h':
|
|
426
|
+
showHelp();
|
|
427
|
+
break;
|
|
428
|
+
case 'config':
|
|
429
|
+
showConfig();
|
|
430
|
+
break;
|
|
431
|
+
case 'balance':
|
|
432
|
+
await checkBalance();
|
|
433
|
+
break;
|
|
434
|
+
case 'receive':
|
|
435
|
+
case 'address':
|
|
436
|
+
case 'wallet':
|
|
437
|
+
showReceive();
|
|
438
|
+
break;
|
|
439
|
+
case 'send':
|
|
440
|
+
console.log(`\n${c.yellow}ā ${c.reset} Send command coming soon!`);
|
|
441
|
+
console.log(`${c.dim}For now, use the library directly:${c.reset}\n`);
|
|
442
|
+
console.log(` ${c.cyan}import { LobsterAgent } from 'pay-lobster';${c.reset}`);
|
|
443
|
+
console.log(` ${c.cyan}const agent = new LobsterAgent({ privateKey });${c.reset}`);
|
|
444
|
+
console.log(` ${c.cyan}await agent.transfer(recipientAddress, 25.00);${c.reset}\n`);
|
|
445
|
+
break;
|
|
446
|
+
case 'escrow':
|
|
447
|
+
console.log(`\n${c.yellow}ā ${c.reset} Escrow commands coming soon!`);
|
|
448
|
+
console.log(`${c.dim}For now, use the library directly. See docs.${c.reset}\n`);
|
|
449
|
+
break;
|
|
450
|
+
case 'trust':
|
|
451
|
+
console.log(`\n${c.yellow}ā ${c.reset} Trust command coming soon!`);
|
|
452
|
+
console.log(`${c.dim}Registry: 0x10BCa62Ce136A70F914c56D97e491a85d1e050E7${c.reset}\n`);
|
|
453
|
+
break;
|
|
454
|
+
case 'discover':
|
|
455
|
+
console.log(`\n${c.yellow}ā ${c.reset} Discover command coming soon!`);
|
|
456
|
+
console.log(`${c.dim}Registry: 0x10BCa62Ce136A70F914c56D97e491a85d1e050E7${c.reset}\n`);
|
|
457
|
+
break;
|
|
458
|
+
case 'register':
|
|
459
|
+
console.log(`\n${c.yellow}ā ${c.reset} Register command coming soon!`);
|
|
460
|
+
console.log(`${c.dim}For now, register directly via the contract.${c.reset}\n`);
|
|
461
|
+
break;
|
|
462
|
+
default:
|
|
463
|
+
console.log(`\n${c.red}ā${c.reset} Unknown command: ${command}`);
|
|
464
|
+
console.log(`Run ${c.cyan}paylobster help${c.reset} to see available commands.\n`);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
main().catch(console.error);
|
|
468
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../lib/cli.ts"],"names":[],"mappings":"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"}
|
package/lib/cli.ts
ADDED
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Pay Lobster CLI - Setup Wizard & Commands
|
|
5
|
+
* š¦ Payment infrastructure for AI agents
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import * as fs from 'fs';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
import * as readline from 'readline';
|
|
11
|
+
import { ethers } from 'ethers';
|
|
12
|
+
|
|
13
|
+
// Colors for terminal output
|
|
14
|
+
const colors = {
|
|
15
|
+
reset: '\x1b[0m',
|
|
16
|
+
bright: '\x1b[1m',
|
|
17
|
+
dim: '\x1b[2m',
|
|
18
|
+
red: '\x1b[31m',
|
|
19
|
+
green: '\x1b[32m',
|
|
20
|
+
yellow: '\x1b[33m',
|
|
21
|
+
blue: '\x1b[34m',
|
|
22
|
+
magenta: '\x1b[35m',
|
|
23
|
+
cyan: '\x1b[36m',
|
|
24
|
+
white: '\x1b[37m',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const c = colors;
|
|
28
|
+
|
|
29
|
+
// Config file location
|
|
30
|
+
const CONFIG_DIR = path.join(process.env.HOME || '~', '.paylobster');
|
|
31
|
+
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
32
|
+
|
|
33
|
+
interface PayLobsterConfig {
|
|
34
|
+
privateKey?: string;
|
|
35
|
+
network: 'base' | 'base-sepolia';
|
|
36
|
+
rpcUrl: string;
|
|
37
|
+
agentName?: string;
|
|
38
|
+
setupComplete: boolean;
|
|
39
|
+
version: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const DEFAULT_CONFIG: PayLobsterConfig = {
|
|
43
|
+
network: 'base',
|
|
44
|
+
rpcUrl: 'https://mainnet.base.org',
|
|
45
|
+
setupComplete: false,
|
|
46
|
+
version: '1.1.2',
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// ASCII Art Banner
|
|
50
|
+
function showBanner(): void {
|
|
51
|
+
console.log(`
|
|
52
|
+
${c.cyan} āāāāāāā āāāāāā āāā āāā āāā āāāāāāā āāāāāāā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
53
|
+
āāāāāāāāāāāāāāāāāāāā āāāā āāā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
54
|
+
āāāāāāāāāāāāāāāā āāāāāāā āāā āāā āāāāāāāāāāāāāāāāāāā āāā āāāāāā āāāāāāāā
|
|
55
|
+
āāāāāāā āāāāāāāā āāāāā āāā āāā āāāāāāāāāāāāāāāāāāā āāā āāāāāā āāāāāāāā
|
|
56
|
+
āāā āāā āāā āāā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā āāā āāāāāāāāāāā āāā
|
|
57
|
+
āāā āāā āāā āāā āāāāāāāā āāāāāāā āāāāāāā āāāāāāāā āāā āāāāāāāāāāā āāā${c.reset}
|
|
58
|
+
|
|
59
|
+
${c.dim}š¦ Payment Infrastructure for AI Agents${c.reset}
|
|
60
|
+
${c.dim} Built on Base ⢠Powered by USDC${c.reset}
|
|
61
|
+
`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Create readline interface
|
|
65
|
+
function createRL(): readline.Interface {
|
|
66
|
+
return readline.createInterface({
|
|
67
|
+
input: process.stdin,
|
|
68
|
+
output: process.stdout,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Prompt helper
|
|
73
|
+
function prompt(rl: readline.Interface, question: string): Promise<string> {
|
|
74
|
+
return new Promise((resolve) => {
|
|
75
|
+
rl.question(question, (answer) => {
|
|
76
|
+
resolve(answer.trim());
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Prompt for password (hidden input)
|
|
82
|
+
function promptSecret(rl: readline.Interface, question: string): Promise<string> {
|
|
83
|
+
return new Promise((resolve) => {
|
|
84
|
+
process.stdout.write(question);
|
|
85
|
+
const stdin = process.stdin;
|
|
86
|
+
const wasRaw = stdin.isRaw;
|
|
87
|
+
|
|
88
|
+
if (stdin.setRawMode) {
|
|
89
|
+
stdin.setRawMode(true);
|
|
90
|
+
}
|
|
91
|
+
stdin.resume();
|
|
92
|
+
|
|
93
|
+
let input = '';
|
|
94
|
+
const onData = (char: Buffer) => {
|
|
95
|
+
const c = char.toString();
|
|
96
|
+
if (c === '\n' || c === '\r') {
|
|
97
|
+
stdin.removeListener('data', onData);
|
|
98
|
+
if (stdin.setRawMode) {
|
|
99
|
+
stdin.setRawMode(wasRaw || false);
|
|
100
|
+
}
|
|
101
|
+
console.log();
|
|
102
|
+
resolve(input);
|
|
103
|
+
} else if (c === '\u0003') {
|
|
104
|
+
process.exit();
|
|
105
|
+
} else if (c === '\u007F') {
|
|
106
|
+
input = input.slice(0, -1);
|
|
107
|
+
process.stdout.write('\b \b');
|
|
108
|
+
} else {
|
|
109
|
+
input += c;
|
|
110
|
+
process.stdout.write('*');
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
stdin.on('data', onData);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Load config
|
|
119
|
+
function loadConfig(): PayLobsterConfig {
|
|
120
|
+
try {
|
|
121
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
122
|
+
const data = fs.readFileSync(CONFIG_FILE, 'utf-8');
|
|
123
|
+
return { ...DEFAULT_CONFIG, ...JSON.parse(data) };
|
|
124
|
+
}
|
|
125
|
+
} catch (e) {
|
|
126
|
+
// Ignore errors, return default
|
|
127
|
+
}
|
|
128
|
+
return { ...DEFAULT_CONFIG };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Save config
|
|
132
|
+
function saveConfig(config: PayLobsterConfig): void {
|
|
133
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
134
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
|
|
135
|
+
}
|
|
136
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), { mode: 0o600 });
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Validate private key
|
|
140
|
+
function isValidPrivateKey(key: string): boolean {
|
|
141
|
+
try {
|
|
142
|
+
const cleanKey = key.startsWith('0x') ? key : `0x${key}`;
|
|
143
|
+
new ethers.Wallet(cleanKey);
|
|
144
|
+
return true;
|
|
145
|
+
} catch {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Get wallet address from private key
|
|
151
|
+
function getAddress(privateKey: string): string {
|
|
152
|
+
const cleanKey = privateKey.startsWith('0x') ? privateKey : `0x${privateKey}`;
|
|
153
|
+
const wallet = new ethers.Wallet(cleanKey);
|
|
154
|
+
return wallet.address;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Setup wizard
|
|
158
|
+
async function runSetupWizard(): Promise<void> {
|
|
159
|
+
const rl = createRL();
|
|
160
|
+
const config = loadConfig();
|
|
161
|
+
|
|
162
|
+
console.log(`\n${c.bright}${c.cyan}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā${c.reset}`);
|
|
163
|
+
console.log(`${c.bright} š¦ Pay Lobster Setup Wizard${c.reset}`);
|
|
164
|
+
console.log(`${c.bright}${c.cyan}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā${c.reset}\n`);
|
|
165
|
+
|
|
166
|
+
console.log(`${c.dim}This wizard will help you configure Pay Lobster for your AI agent.${c.reset}`);
|
|
167
|
+
console.log(`${c.dim}Your configuration will be stored securely at: ${CONFIG_FILE}${c.reset}\n`);
|
|
168
|
+
|
|
169
|
+
// Step 1: Agent Name
|
|
170
|
+
console.log(`${c.yellow}Step 1/4:${c.reset} ${c.bright}Agent Name${c.reset}`);
|
|
171
|
+
console.log(`${c.dim}Give your agent a name for the registry.${c.reset}\n`);
|
|
172
|
+
|
|
173
|
+
const agentName = await prompt(rl, `${c.green}āÆ${c.reset} Agent name: `);
|
|
174
|
+
config.agentName = agentName || 'MyAgent';
|
|
175
|
+
console.log(`${c.green}ā${c.reset} Agent: ${c.bright}${config.agentName}${c.reset}\n`);
|
|
176
|
+
|
|
177
|
+
// Step 2: Network Selection
|
|
178
|
+
console.log(`${c.yellow}Step 2/4:${c.reset} ${c.bright}Network${c.reset}`);
|
|
179
|
+
console.log(`${c.dim}Choose your network. Use testnet for development.${c.reset}\n`);
|
|
180
|
+
console.log(` ${c.cyan}1)${c.reset} Base Mainnet ${c.dim}(production, real USDC)${c.reset}`);
|
|
181
|
+
console.log(` ${c.cyan}2)${c.reset} Base Sepolia ${c.dim}(testnet, free test USDC)${c.reset}\n`);
|
|
182
|
+
|
|
183
|
+
const networkChoice = await prompt(rl, `${c.green}āÆ${c.reset} Select network [1/2]: `);
|
|
184
|
+
|
|
185
|
+
if (networkChoice === '2') {
|
|
186
|
+
config.network = 'base-sepolia';
|
|
187
|
+
config.rpcUrl = 'https://sepolia.base.org';
|
|
188
|
+
console.log(`${c.green}ā${c.reset} Network: ${c.yellow}Base Sepolia (Testnet)${c.reset}\n`);
|
|
189
|
+
} else {
|
|
190
|
+
config.network = 'base';
|
|
191
|
+
config.rpcUrl = 'https://mainnet.base.org';
|
|
192
|
+
console.log(`${c.green}ā${c.reset} Network: ${c.bright}Base Mainnet${c.reset}\n`);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Step 3: Wallet Setup
|
|
196
|
+
console.log(`${c.yellow}Step 3/4:${c.reset} ${c.bright}Wallet Setup${c.reset}`);
|
|
197
|
+
console.log(`${c.dim}You need a wallet to send and receive USDC.${c.reset}\n`);
|
|
198
|
+
console.log(` ${c.cyan}1)${c.reset} Generate new wallet ${c.dim}(recommended for new users)${c.reset}`);
|
|
199
|
+
console.log(` ${c.cyan}2)${c.reset} Import existing private key ${c.dim}(for existing wallets)${c.reset}`);
|
|
200
|
+
console.log(` ${c.cyan}3)${c.reset} Skip for now ${c.dim}(read-only mode)${c.reset}\n`);
|
|
201
|
+
|
|
202
|
+
const walletChoice = await prompt(rl, `${c.green}āÆ${c.reset} Select option [1/2/3]: `);
|
|
203
|
+
|
|
204
|
+
if (walletChoice === '1') {
|
|
205
|
+
// Generate new wallet
|
|
206
|
+
const wallet = ethers.Wallet.createRandom();
|
|
207
|
+
config.privateKey = wallet.privateKey;
|
|
208
|
+
|
|
209
|
+
console.log(`\n${c.green}ā${c.reset} New wallet generated!\n`);
|
|
210
|
+
console.log(`${c.bright}${c.cyan}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā${c.reset}`);
|
|
211
|
+
console.log(`${c.bright}${c.cyan}ā${c.reset} ${c.bright}ā ļø SAVE THIS INFORMATION SECURELY!${c.reset} ${c.cyan}ā${c.reset}`);
|
|
212
|
+
console.log(`${c.bright}${c.cyan}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤${c.reset}`);
|
|
213
|
+
console.log(`${c.cyan}ā${c.reset} Address: ${c.green}${wallet.address}${c.reset} ${c.cyan}ā${c.reset}`);
|
|
214
|
+
console.log(`${c.cyan}ā${c.reset} Private Key: ${c.yellow}${wallet.privateKey.slice(0, 20)}...${c.reset} ${c.cyan}ā${c.reset}`);
|
|
215
|
+
console.log(`${c.bright}${c.cyan}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā${c.reset}`);
|
|
216
|
+
console.log(`\n${c.red}${c.bright}IMPORTANT:${c.reset} ${c.dim}Write down your private key and store it safely.${c.reset}`);
|
|
217
|
+
console.log(`${c.dim}If you lose it, you lose access to your funds forever.${c.reset}\n`);
|
|
218
|
+
|
|
219
|
+
await prompt(rl, `${c.yellow}Press Enter when you've saved your key...${c.reset}`);
|
|
220
|
+
console.log();
|
|
221
|
+
|
|
222
|
+
} else if (walletChoice === '2') {
|
|
223
|
+
// Import existing
|
|
224
|
+
console.log(`\n${c.dim}Enter your private key (input is hidden):${c.reset}\n`);
|
|
225
|
+
|
|
226
|
+
let validKey = false;
|
|
227
|
+
while (!validKey) {
|
|
228
|
+
const privateKey = await promptSecret(rl, `${c.green}āÆ${c.reset} Private key: `);
|
|
229
|
+
|
|
230
|
+
if (isValidPrivateKey(privateKey)) {
|
|
231
|
+
config.privateKey = privateKey.startsWith('0x') ? privateKey : `0x${privateKey}`;
|
|
232
|
+
const address = getAddress(config.privateKey);
|
|
233
|
+
console.log(`${c.green}ā${c.reset} Wallet imported: ${c.bright}${address}${c.reset}\n`);
|
|
234
|
+
validKey = true;
|
|
235
|
+
} else {
|
|
236
|
+
console.log(`${c.red}ā${c.reset} Invalid private key. Please try again.\n`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
} else {
|
|
241
|
+
console.log(`${c.yellow}ā ${c.reset} Skipping wallet setup. You'll only be able to read data.\n`);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Step 4: Verify & Complete
|
|
245
|
+
console.log(`${c.yellow}Step 4/4:${c.reset} ${c.bright}Verification${c.reset}\n`);
|
|
246
|
+
|
|
247
|
+
// Test RPC connection
|
|
248
|
+
process.stdout.write(`${c.dim}Testing connection to ${config.network}...${c.reset} `);
|
|
249
|
+
try {
|
|
250
|
+
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
251
|
+
const blockNumber = await provider.getBlockNumber();
|
|
252
|
+
console.log(`${c.green}ā${c.reset} Connected (block #${blockNumber})`);
|
|
253
|
+
} catch (e) {
|
|
254
|
+
console.log(`${c.red}ā${c.reset} Failed to connect`);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Check balance if wallet configured
|
|
258
|
+
if (config.privateKey) {
|
|
259
|
+
process.stdout.write(`${c.dim}Checking USDC balance...${c.reset} `);
|
|
260
|
+
try {
|
|
261
|
+
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
262
|
+
const usdcAddress = config.network === 'base'
|
|
263
|
+
? '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
|
|
264
|
+
: '0x036CbD53842c5426634e7929541eC2318f3dCF7e';
|
|
265
|
+
|
|
266
|
+
const usdcAbi = ['function balanceOf(address) view returns (uint256)'];
|
|
267
|
+
const usdc = new ethers.Contract(usdcAddress, usdcAbi, provider);
|
|
268
|
+
const address = getAddress(config.privateKey);
|
|
269
|
+
const balance = await usdc.balanceOf(address);
|
|
270
|
+
const formatted = ethers.formatUnits(balance, 6);
|
|
271
|
+
console.log(`${c.green}ā${c.reset} ${formatted} USDC`);
|
|
272
|
+
} catch (e) {
|
|
273
|
+
console.log(`${c.yellow}ā ${c.reset} Could not fetch balance`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Save config
|
|
278
|
+
config.setupComplete = true;
|
|
279
|
+
saveConfig(config);
|
|
280
|
+
|
|
281
|
+
console.log(`\n${c.green}ā${c.reset} Configuration saved to ${c.dim}${CONFIG_FILE}${c.reset}\n`);
|
|
282
|
+
|
|
283
|
+
// Success message
|
|
284
|
+
console.log(`${c.bright}${c.green}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā${c.reset}`);
|
|
285
|
+
console.log(`${c.bright}${c.green} š¦ Setup Complete!${c.reset}`);
|
|
286
|
+
console.log(`${c.bright}${c.green}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā${c.reset}\n`);
|
|
287
|
+
|
|
288
|
+
console.log(`${c.bright}Quick Start:${c.reset}\n`);
|
|
289
|
+
console.log(` ${c.cyan}paylobster balance${c.reset} Check your USDC balance`);
|
|
290
|
+
console.log(` ${c.cyan}paylobster send${c.reset} Send USDC to an address`);
|
|
291
|
+
console.log(` ${c.cyan}paylobster escrow create${c.reset} Create a new escrow`);
|
|
292
|
+
console.log(` ${c.cyan}paylobster discover${c.reset} Find agents by capability`);
|
|
293
|
+
console.log(` ${c.cyan}paylobster help${c.reset} Show all commands\n`);
|
|
294
|
+
|
|
295
|
+
if (config.network === 'base' && config.privateKey) {
|
|
296
|
+
const address = getAddress(config.privateKey);
|
|
297
|
+
console.log(`${c.dim}Fund your wallet with USDC on Base:${c.reset}`);
|
|
298
|
+
console.log(`${c.cyan}${address}${c.reset}\n`);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
console.log(`${c.dim}Docs: https://paylobster.com/docs${c.reset}`);
|
|
302
|
+
console.log(`${c.dim}GitHub: https://github.com/itsGustav/Pay-Lobster${c.reset}\n`);
|
|
303
|
+
|
|
304
|
+
rl.close();
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Show help
|
|
308
|
+
function showHelp(): void {
|
|
309
|
+
console.log(`
|
|
310
|
+
${c.bright}Pay Lobster CLI${c.reset} - Payment infrastructure for AI agents
|
|
311
|
+
|
|
312
|
+
${c.bright}USAGE${c.reset}
|
|
313
|
+
paylobster <command> [options]
|
|
314
|
+
|
|
315
|
+
${c.bright}COMMANDS${c.reset}
|
|
316
|
+
${c.cyan}setup${c.reset} Run the setup wizard
|
|
317
|
+
${c.cyan}balance${c.reset} Check USDC balance
|
|
318
|
+
${c.cyan}send <amount> <to>${c.reset} Send USDC to address or agent
|
|
319
|
+
${c.cyan}receive${c.reset} Show your wallet address
|
|
320
|
+
${c.cyan}escrow create${c.reset} Create new escrow
|
|
321
|
+
${c.cyan}escrow list${c.reset} List your escrows
|
|
322
|
+
${c.cyan}escrow release <id>${c.reset} Release escrow funds
|
|
323
|
+
${c.cyan}trust <agent>${c.reset} Check agent trust score
|
|
324
|
+
${c.cyan}discover${c.reset} Find agents by capability
|
|
325
|
+
${c.cyan}register${c.reset} Register your agent
|
|
326
|
+
${c.cyan}config${c.reset} Show current configuration
|
|
327
|
+
${c.cyan}help${c.reset} Show this help message
|
|
328
|
+
|
|
329
|
+
${c.bright}EXAMPLES${c.reset}
|
|
330
|
+
${c.dim}# Send 25 USDC to another agent${c.reset}
|
|
331
|
+
paylobster send 25.00 agent:DataAnalyzer
|
|
332
|
+
|
|
333
|
+
${c.dim}# Create escrow for a job${c.reset}
|
|
334
|
+
paylobster escrow create 500 agent:WebDevBot --milestone "Landing page"
|
|
335
|
+
|
|
336
|
+
${c.dim}# Check an agent's reputation${c.reset}
|
|
337
|
+
paylobster trust agent:WebDevBot
|
|
338
|
+
|
|
339
|
+
${c.bright}CONTRACTS (Base Mainnet)${c.reset}
|
|
340
|
+
Escrow: ${c.dim}0xa091fC821c85Dfd2b2B3EF9e22c5f4c8B8A24525${c.reset}
|
|
341
|
+
Registry: ${c.dim}0x10BCa62Ce136A70F914c56D97e491a85d1e050E7${c.reset}
|
|
342
|
+
|
|
343
|
+
${c.dim}Documentation: https://paylobster.com/docs${c.reset}
|
|
344
|
+
`);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Show config
|
|
348
|
+
function showConfig(): void {
|
|
349
|
+
const config = loadConfig();
|
|
350
|
+
|
|
351
|
+
console.log(`\n${c.bright}Pay Lobster Configuration${c.reset}\n`);
|
|
352
|
+
console.log(`${c.dim}Config file: ${CONFIG_FILE}${c.reset}\n`);
|
|
353
|
+
|
|
354
|
+
console.log(` Agent Name: ${c.cyan}${config.agentName || 'Not set'}${c.reset}`);
|
|
355
|
+
console.log(` Network: ${c.cyan}${config.network}${c.reset}`);
|
|
356
|
+
console.log(` RPC URL: ${c.dim}${config.rpcUrl}${c.reset}`);
|
|
357
|
+
|
|
358
|
+
if (config.privateKey) {
|
|
359
|
+
const address = getAddress(config.privateKey);
|
|
360
|
+
console.log(` Wallet: ${c.green}${address}${c.reset}`);
|
|
361
|
+
} else {
|
|
362
|
+
console.log(` Wallet: ${c.yellow}Not configured${c.reset}`);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
console.log(` Setup: ${config.setupComplete ? `${c.green}Complete${c.reset}` : `${c.yellow}Incomplete${c.reset}`}`);
|
|
366
|
+
console.log();
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// Check balance command
|
|
370
|
+
async function checkBalance(): Promise<void> {
|
|
371
|
+
const config = loadConfig();
|
|
372
|
+
|
|
373
|
+
if (!config.privateKey) {
|
|
374
|
+
console.log(`${c.red}ā${c.reset} No wallet configured. Run ${c.cyan}paylobster setup${c.reset} first.`);
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
console.log(`\n${c.dim}š Querying ${config.network}...${c.reset}\n`);
|
|
379
|
+
|
|
380
|
+
try {
|
|
381
|
+
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
382
|
+
const address = getAddress(config.privateKey);
|
|
383
|
+
|
|
384
|
+
// USDC contract
|
|
385
|
+
const usdcAddress = config.network === 'base'
|
|
386
|
+
? '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
|
|
387
|
+
: '0x036CbD53842c5426634e7929541eC2318f3dCF7e';
|
|
388
|
+
|
|
389
|
+
const usdcAbi = ['function balanceOf(address) view returns (uint256)'];
|
|
390
|
+
const usdc = new ethers.Contract(usdcAddress, usdcAbi, provider);
|
|
391
|
+
|
|
392
|
+
const balance = await usdc.balanceOf(address);
|
|
393
|
+
const formatted = ethers.formatUnits(balance, 6);
|
|
394
|
+
|
|
395
|
+
// Get ETH balance for gas
|
|
396
|
+
const ethBalance = await provider.getBalance(address);
|
|
397
|
+
const ethFormatted = ethers.formatEther(ethBalance);
|
|
398
|
+
|
|
399
|
+
console.log(`${c.cyan}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā${c.reset}`);
|
|
400
|
+
console.log(`${c.cyan}ā${c.reset} ${c.bright}š° Wallet Balance${c.reset} ${c.cyan}ā${c.reset}`);
|
|
401
|
+
console.log(`${c.cyan}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤${c.reset}`);
|
|
402
|
+
console.log(`${c.cyan}ā${c.reset} USDC: ${c.green}${formatted.padStart(15)} USDC${c.reset} ${c.cyan}ā${c.reset}`);
|
|
403
|
+
console.log(`${c.cyan}ā${c.reset} ETH: ${c.dim}${parseFloat(ethFormatted).toFixed(6).padStart(15)} ETH${c.reset} ${c.cyan}ā${c.reset}`);
|
|
404
|
+
console.log(`${c.cyan}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā${c.reset}`);
|
|
405
|
+
console.log(`\n${c.dim}Wallet: ${address}${c.reset}`);
|
|
406
|
+
console.log(`${c.dim}Network: ${config.network}${c.reset}\n`);
|
|
407
|
+
|
|
408
|
+
} catch (e: any) {
|
|
409
|
+
console.log(`${c.red}ā${c.reset} Error: ${e.message}`);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// Show receive address
|
|
414
|
+
function showReceive(): void {
|
|
415
|
+
const config = loadConfig();
|
|
416
|
+
|
|
417
|
+
if (!config.privateKey) {
|
|
418
|
+
console.log(`${c.red}ā${c.reset} No wallet configured. Run ${c.cyan}paylobster setup${c.reset} first.`);
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
const address = getAddress(config.privateKey);
|
|
423
|
+
|
|
424
|
+
console.log(`\n${c.bright}Your Pay Lobster Wallet${c.reset}\n`);
|
|
425
|
+
console.log(`${c.cyan}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā${c.reset}`);
|
|
426
|
+
console.log(`${c.cyan}ā${c.reset} ${c.green}${address}${c.reset} ${c.cyan}ā${c.reset}`);
|
|
427
|
+
console.log(`${c.cyan}āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā${c.reset}`);
|
|
428
|
+
console.log(`\n${c.dim}Network: ${config.network}${c.reset}`);
|
|
429
|
+
console.log(`${c.dim}Send USDC on Base to this address.${c.reset}\n`);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// Main CLI entry point
|
|
433
|
+
async function main(): Promise<void> {
|
|
434
|
+
const args = process.argv.slice(2);
|
|
435
|
+
const command = args[0]?.toLowerCase();
|
|
436
|
+
|
|
437
|
+
// Check if first run
|
|
438
|
+
const config = loadConfig();
|
|
439
|
+
|
|
440
|
+
if (!command || command === 'setup') {
|
|
441
|
+
showBanner();
|
|
442
|
+
await runSetupWizard();
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// Check if setup needed
|
|
447
|
+
if (!config.setupComplete && command !== 'help') {
|
|
448
|
+
console.log(`\n${c.yellow}ā ${c.reset} Pay Lobster is not configured yet.\n`);
|
|
449
|
+
console.log(`Run ${c.cyan}paylobster setup${c.reset} to get started.\n`);
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
switch (command) {
|
|
454
|
+
case 'help':
|
|
455
|
+
case '--help':
|
|
456
|
+
case '-h':
|
|
457
|
+
showHelp();
|
|
458
|
+
break;
|
|
459
|
+
|
|
460
|
+
case 'config':
|
|
461
|
+
showConfig();
|
|
462
|
+
break;
|
|
463
|
+
|
|
464
|
+
case 'balance':
|
|
465
|
+
await checkBalance();
|
|
466
|
+
break;
|
|
467
|
+
|
|
468
|
+
case 'receive':
|
|
469
|
+
case 'address':
|
|
470
|
+
case 'wallet':
|
|
471
|
+
showReceive();
|
|
472
|
+
break;
|
|
473
|
+
|
|
474
|
+
case 'send':
|
|
475
|
+
console.log(`\n${c.yellow}ā ${c.reset} Send command coming soon!`);
|
|
476
|
+
console.log(`${c.dim}For now, use the library directly:${c.reset}\n`);
|
|
477
|
+
console.log(` ${c.cyan}import { LobsterAgent } from 'pay-lobster';${c.reset}`);
|
|
478
|
+
console.log(` ${c.cyan}const agent = new LobsterAgent({ privateKey });${c.reset}`);
|
|
479
|
+
console.log(` ${c.cyan}await agent.transfer(recipientAddress, 25.00);${c.reset}\n`);
|
|
480
|
+
break;
|
|
481
|
+
|
|
482
|
+
case 'escrow':
|
|
483
|
+
console.log(`\n${c.yellow}ā ${c.reset} Escrow commands coming soon!`);
|
|
484
|
+
console.log(`${c.dim}For now, use the library directly. See docs.${c.reset}\n`);
|
|
485
|
+
break;
|
|
486
|
+
|
|
487
|
+
case 'trust':
|
|
488
|
+
console.log(`\n${c.yellow}ā ${c.reset} Trust command coming soon!`);
|
|
489
|
+
console.log(`${c.dim}Registry: 0x10BCa62Ce136A70F914c56D97e491a85d1e050E7${c.reset}\n`);
|
|
490
|
+
break;
|
|
491
|
+
|
|
492
|
+
case 'discover':
|
|
493
|
+
console.log(`\n${c.yellow}ā ${c.reset} Discover command coming soon!`);
|
|
494
|
+
console.log(`${c.dim}Registry: 0x10BCa62Ce136A70F914c56D97e491a85d1e050E7${c.reset}\n`);
|
|
495
|
+
break;
|
|
496
|
+
|
|
497
|
+
case 'register':
|
|
498
|
+
console.log(`\n${c.yellow}ā ${c.reset} Register command coming soon!`);
|
|
499
|
+
console.log(`${c.dim}For now, register directly via the contract.${c.reset}\n`);
|
|
500
|
+
break;
|
|
501
|
+
|
|
502
|
+
default:
|
|
503
|
+
console.log(`\n${c.red}ā${c.reset} Unknown command: ${command}`);
|
|
504
|
+
console.log(`Run ${c.cyan}paylobster help${c.reset} to see available commands.\n`);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
main().catch(console.error);
|
package/package.json
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pay-lobster",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "Payment infrastructure for AI agents - The Stripe for autonomous agents. Send, receive, and escrow USDC on Base.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"bin": {
|
|
8
|
+
"paylobster": "./dist/cli.js",
|
|
8
9
|
"pay-lobster": "./dist/cli.js"
|
|
9
10
|
},
|
|
10
11
|
"scripts": {
|
|
11
12
|
"build": "tsc",
|
|
12
13
|
"prepublishOnly": "npm run build",
|
|
13
|
-
"
|
|
14
|
+
"postinstall": "echo '\nš¦ Pay Lobster installed!\n Run: paylobster setup\n'",
|
|
15
|
+
"cli": "npx tsx lib/cli.ts",
|
|
14
16
|
"test": "echo \"Tests coming soon\" && exit 0"
|
|
15
17
|
},
|
|
16
18
|
"files": [
|
|
@@ -51,14 +53,13 @@
|
|
|
51
53
|
"license": "MIT",
|
|
52
54
|
"repository": {
|
|
53
55
|
"type": "git",
|
|
54
|
-
"url": "git+https://github.com/itsGustav/Lobster
|
|
56
|
+
"url": "git+https://github.com/itsGustav/Pay-Lobster.git"
|
|
55
57
|
},
|
|
56
58
|
"bugs": {
|
|
57
|
-
"url": "https://github.com/itsGustav/Lobster
|
|
59
|
+
"url": "https://github.com/itsGustav/Pay-Lobster/issues"
|
|
58
60
|
},
|
|
59
61
|
"homepage": "https://paylobster.com",
|
|
60
62
|
"engines": {
|
|
61
63
|
"node": ">=18.0.0"
|
|
62
|
-
}
|
|
63
|
-
"type": "module"
|
|
64
|
+
}
|
|
64
65
|
}
|