httpcat-cli 0.0.19 → 0.0.21
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/.claude/settings.local.json +2 -1
- package/README.md +102 -0
- package/dist/commands/buy.d.ts.map +1 -1
- package/dist/commands/buy.js +5 -5
- package/dist/commands/buy.js.map +1 -1
- package/dist/commands/positions.d.ts.map +1 -0
- package/dist/commands/positions.js +136 -0
- package/dist/commands/positions.js.map +1 -0
- package/dist/index.js +112 -10
- package/dist/index.js.map +1 -1
- package/dist/interactive/shell.d.ts.map +1 -1
- package/dist/interactive/shell.js +103 -13
- package/dist/interactive/shell.js.map +1 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +20 -0
- package/dist/mcp/tools.js.map +1 -1
- package/dist/mcp/types.d.ts.map +1 -1
- package/dist/utils/loading.d.ts.map +1 -0
- package/dist/utils/loading.js +61 -0
- package/dist/utils/loading.js.map +1 -0
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +37 -2
- package/dist/utils/validation.js.map +1 -1
- package/homebrew-httpcat/Formula/httpcat.rb +3 -3
- package/homebrew-httpcat/homebrew-httpcat/Formula/httpcat.rb +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -129,6 +129,7 @@ Available Commands:
|
|
|
129
129
|
sell <id|name|symbol> <amount|all> Sell tokens
|
|
130
130
|
info <id|name|symbol> Get token information
|
|
131
131
|
list [--sort mcap|created] List all tokens
|
|
132
|
+
positions Get all your positions with comprehensive info
|
|
132
133
|
chat [token] Start streaming chat (optional: token symbol/name/address)
|
|
133
134
|
balance Check wallet balance (ETH and USDC)
|
|
134
135
|
health Check agent health
|
|
@@ -322,6 +323,42 @@ httpcat list --page 3 --sort name
|
|
|
322
323
|
|
|
323
324
|
**Cost:** $0.0001 USDC
|
|
324
325
|
|
|
326
|
+
### Positions
|
|
327
|
+
|
|
328
|
+
Get all your positions with comprehensive information including current value, profit/loss, ROI, transaction history, and portfolio summary.
|
|
329
|
+
|
|
330
|
+
**Interactive:**
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
httpcat> positions
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
**CLI:**
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
httpcat positions
|
|
340
|
+
httpcat --json positions
|
|
341
|
+
httpcat --private-key 0x... positions
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
**Output:**
|
|
345
|
+
|
|
346
|
+
For each position:
|
|
347
|
+
- Token information (name, symbol, address, status, price, market cap, graduation progress)
|
|
348
|
+
- Position details (tokens owned, USDC invested, current value, average cost per token)
|
|
349
|
+
- Performance metrics (profit/loss in USDC and percentage ROI)
|
|
350
|
+
- Position age (days, hours, minutes, seconds since first purchase)
|
|
351
|
+
- Transaction history (total transaction count, last transaction date)
|
|
352
|
+
- Timestamps (position created and updated dates)
|
|
353
|
+
|
|
354
|
+
Portfolio summary:
|
|
355
|
+
- Total positions count
|
|
356
|
+
- Total portfolio value
|
|
357
|
+
- Total amount invested
|
|
358
|
+
- Total profit/loss and overall ROI percentage
|
|
359
|
+
|
|
360
|
+
**Cost:** $0.01 USDC
|
|
361
|
+
|
|
325
362
|
### Check Balance
|
|
326
363
|
|
|
327
364
|
Check your wallet's ETH and USDC balances.
|
|
@@ -623,6 +660,51 @@ All commands with `--json` flag return structured JSON responses. The output fol
|
|
|
623
660
|
}
|
|
624
661
|
```
|
|
625
662
|
|
|
663
|
+
**Positions (`positions`)**
|
|
664
|
+
|
|
665
|
+
```json
|
|
666
|
+
{
|
|
667
|
+
"positions": [
|
|
668
|
+
{
|
|
669
|
+
"tokenId": "uuid-string",
|
|
670
|
+
"tokensOwned": "50000",
|
|
671
|
+
"usdcInvested": "5000000",
|
|
672
|
+
"currentValue": "10000000",
|
|
673
|
+
"pnl": "5000000",
|
|
674
|
+
"pnlPercentage": 100.0,
|
|
675
|
+
"averageCostPerToken": "0.0001",
|
|
676
|
+
"positionAge": {
|
|
677
|
+
"days": 2,
|
|
678
|
+
"hours": 5,
|
|
679
|
+
"minutes": 30,
|
|
680
|
+
"seconds": 15
|
|
681
|
+
},
|
|
682
|
+
"createdAt": "2025-11-22T10:30:00.000Z",
|
|
683
|
+
"updatedAt": "2025-11-24T15:30:00.000Z",
|
|
684
|
+
"lastTransactionDate": "2025-11-24T15:30:00.000Z",
|
|
685
|
+
"transactionCount": 3,
|
|
686
|
+
"token": {
|
|
687
|
+
"name": "Token Name",
|
|
688
|
+
"symbol": "SYMBOL",
|
|
689
|
+
"address": "0x...",
|
|
690
|
+
"status": "active",
|
|
691
|
+
"price": "0.0002",
|
|
692
|
+
"mcap": "200000",
|
|
693
|
+
"graduationProgress": 0.15
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
],
|
|
697
|
+
"total": 1,
|
|
698
|
+
"summary": {
|
|
699
|
+
"totalPositions": 1,
|
|
700
|
+
"totalValue": "10000000",
|
|
701
|
+
"totalInvested": "5000000",
|
|
702
|
+
"totalPnl": "5000000",
|
|
703
|
+
"totalPnlPercentage": 100.0
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
```
|
|
707
|
+
|
|
626
708
|
**Health Check (`health`)**
|
|
627
709
|
|
|
628
710
|
```json
|
|
@@ -857,6 +939,23 @@ List all tokens with pagination and sorting.
|
|
|
857
939
|
|
|
858
940
|
**Cost:** $0.0001 USDC
|
|
859
941
|
|
|
942
|
+
#### `positions`
|
|
943
|
+
|
|
944
|
+
Get all your positions with comprehensive information including current value, profit/loss, ROI, transaction history, and portfolio summary.
|
|
945
|
+
|
|
946
|
+
**Parameters:**
|
|
947
|
+
|
|
948
|
+
- `privateKey` (string, optional) - Private key (overrides config/env)
|
|
949
|
+
|
|
950
|
+
**Returns:** All positions for the requesting address with:
|
|
951
|
+
- Position details (tokens owned, USDC invested, current value, average cost)
|
|
952
|
+
- Performance metrics (profit/loss, ROI percentage)
|
|
953
|
+
- Position age and transaction history
|
|
954
|
+
- Token information for each position
|
|
955
|
+
- Portfolio summary (total value, total invested, total P/L, overall ROI)
|
|
956
|
+
|
|
957
|
+
**Cost:** $0.01 USDC
|
|
958
|
+
|
|
860
959
|
#### `check_balance`
|
|
861
960
|
|
|
862
961
|
Check wallet balance (ETH and USDC).
|
|
@@ -1262,6 +1361,9 @@ httpcat buy <tokenId> 5
|
|
|
1262
1361
|
# Check your position
|
|
1263
1362
|
httpcat info <tokenId>
|
|
1264
1363
|
|
|
1364
|
+
# Get all your positions with comprehensive info
|
|
1365
|
+
httpcat positions
|
|
1366
|
+
|
|
1265
1367
|
# Sell half when profitable
|
|
1266
1368
|
httpcat sell <tokenId> 50%
|
|
1267
1369
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buy.d.ts","sourceRoot":"","sources":["../../src/commands/buy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAM7C,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;CAC5B;
|
|
1
|
+
{"version":3,"file":"buy.d.ts","sourceRoot":"","sources":["../../src/commands/buy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAM7C,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,eAAO,MAAM,YAAY,UAA2B,CAAC;AACrD,eAAO,MAAM,YAAY,UAAuB,CAAC;AAEjD,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,MAAM,EAAE,mCAAmC;AACvD,MAAM,EAAE,MAAM,EACd,UAAU,UAAO,EACjB,MAAM,UAAQ,GACb,OAAO,CAAC,cAAc,CAAC,CAuBzB;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAkB7D"}
|
package/dist/commands/buy.js
CHANGED
|
@@ -2,8 +2,8 @@ import { validateTokenId, validateAmount } from '../utils/validation.js';
|
|
|
2
2
|
import { printBox, formatTokenAmount, formatCurrency } from '../utils/formatting.js';
|
|
3
3
|
import { printSuccess, printGraduationProgress } from '../interactive/art.js';
|
|
4
4
|
import { resolveTokenId } from '../utils/token-resolver.js';
|
|
5
|
-
const TEST_AMOUNTS = ['0.05', '0.10', '0.20'];
|
|
6
|
-
const PROD_AMOUNTS = ['50', '100', '200'];
|
|
5
|
+
export const TEST_AMOUNTS = ['0.05', '0.10', '0.20'];
|
|
6
|
+
export const PROD_AMOUNTS = ['50', '100', '200'];
|
|
7
7
|
export async function buyToken(client, identifier, // Can be token ID, name, or symbol
|
|
8
8
|
amount, isTestMode = true, silent = false // Suppress resolver output for quiet/JSON mode
|
|
9
9
|
) {
|
|
@@ -12,12 +12,12 @@ amount, isTestMode = true, silent = false // Suppress resolver output for quiet/
|
|
|
12
12
|
// Validate input
|
|
13
13
|
validateTokenId(tokenId);
|
|
14
14
|
const validAmounts = isTestMode ? TEST_AMOUNTS : PROD_AMOUNTS;
|
|
15
|
-
validateAmount(amount, validAmounts);
|
|
16
|
-
const input = { tokenId, amount };
|
|
15
|
+
const normalizedAmount = validateAmount(amount, validAmounts, isTestMode);
|
|
16
|
+
const input = { tokenId, amount: normalizedAmount };
|
|
17
17
|
// Route to correct entrypoint based on test mode and amount
|
|
18
18
|
// Test mode: token_buy_0_05, token_buy_0_10, token_buy_0_20
|
|
19
19
|
// Production mode: token_buy (single entrypoint)
|
|
20
|
-
const entrypoint = isTestMode ? `token_buy_${
|
|
20
|
+
const entrypoint = isTestMode ? `token_buy_${normalizedAmount.replace('.', '_')}` : 'token_buy';
|
|
21
21
|
// Make request
|
|
22
22
|
const { data } = await client.invoke(entrypoint, input);
|
|
23
23
|
return data;
|
package/dist/commands/buy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buy.js","sourceRoot":"","sources":["../../src/commands/buy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAkB5D,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"buy.js","sourceRoot":"","sources":["../../src/commands/buy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAkB5D,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AACrD,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAEjD,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,MAAqB,EACrB,UAAkB,EAAE,mCAAmC;AACvD,MAAc,EACd,UAAU,GAAG,IAAI,EACjB,MAAM,GAAG,KAAK,CAAC,+CAA+C;;IAE9D,iCAAiC;IACjC,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjE,iBAAiB;IACjB,eAAe,CAAC,OAAO,CAAC,CAAC;IACzB,MAAM,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC;IAC9D,MAAM,gBAAgB,GAAG,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;IAE1E,MAAM,KAAK,GAAkB,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAEnE,4DAA4D;IAC5D,4DAA4D;IAC5D,iDAAiD;IACjD,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,aAAa,gBAAgB,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;IAEhG,eAAe;IACf,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAClC,UAAU,EACV,KAAK,CACN,CAAC;IAEF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAsB;IACrD,YAAY,CAAC,gCAAgC,EAAE,OAAO,CAAC,CAAC;IAExD,MAAM,gBAAgB,GAAG,MAAM,CAAC,iBAAiB;QAC/C,CAAC,CAAC,cAAc;QAChB,CAAC,CAAC,GAAG,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IAE/C,QAAQ,CAAC,qBAAqB,EAAE;QAC9B,iBAAiB,EAAE,iBAAiB,CAAC,MAAM,CAAC,cAAc,CAAC;QAC3D,cAAc,EAAE,cAAc,CAAC,MAAM,CAAC,WAAW,CAAC;QAClD,UAAU,EAAE,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC;QACtC,WAAW,EAAE,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC5C,gBAAgB,EAAE,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC;QAChD,YAAY,EAAE,gBAAgB;KAC/B,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,uBAAuB,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"positions.d.ts","sourceRoot":"","sources":["../../src/commands/positions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAI7C,MAAM,WAAW,cAAc;CAE9B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,WAAW,CAAC,EAAE;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,SAAS,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE;QACR,cAAc,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;QACtB,QAAQ,EAAE,MAAM,CAAC;QACjB,kBAAkB,EAAE,MAAM,CAAC;KAC5B,CAAC;CACH;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,eAAe,CAAC,CAU1B;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAwJ9D"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { createTable, formatAddress, formatCurrency, formatTokenAmount } from '../utils/formatting.js';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
export async function getPositions(client) {
|
|
4
|
+
const input = {};
|
|
5
|
+
// Make request
|
|
6
|
+
const { data } = await client.invoke('positions', input);
|
|
7
|
+
return data;
|
|
8
|
+
}
|
|
9
|
+
export function displayPositions(result) {
|
|
10
|
+
console.log();
|
|
11
|
+
console.log(chalk.cyan.bold(`💼 Your Positions (${result.total} total)`));
|
|
12
|
+
console.log();
|
|
13
|
+
if (result.positions.length === 0) {
|
|
14
|
+
console.log(chalk.yellow('No positions found.'));
|
|
15
|
+
console.log();
|
|
16
|
+
console.log(chalk.dim('💡 Try buying some tokens:'));
|
|
17
|
+
console.log(chalk.dim(' httpcat buy <tokenId> <amount>'));
|
|
18
|
+
console.log(chalk.dim(' httpcat list'));
|
|
19
|
+
console.log();
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
// Display each position
|
|
23
|
+
for (let i = 0; i < result.positions.length; i++) {
|
|
24
|
+
const position = result.positions[i];
|
|
25
|
+
// Position header
|
|
26
|
+
const graduationIcon = position.token.status === 'graduated'
|
|
27
|
+
? '🎓'
|
|
28
|
+
: position.token.graduationProgress >= 90
|
|
29
|
+
? '🔥'
|
|
30
|
+
: position.token.graduationProgress >= 50
|
|
31
|
+
? '📈'
|
|
32
|
+
: '🌱';
|
|
33
|
+
console.log(chalk.bold(`${i + 1}. ${position.token.name} (${position.token.symbol}) ${graduationIcon}`));
|
|
34
|
+
console.log(chalk.dim(` Token ID: ${position.tokenId}`));
|
|
35
|
+
console.log(chalk.dim(` Address: ${formatAddress(position.token.address, 12)}`));
|
|
36
|
+
console.log(chalk.dim(` Status: ${position.token.status}`));
|
|
37
|
+
console.log();
|
|
38
|
+
// Position details table
|
|
39
|
+
const detailsTable = createTable(['Metric', 'Value']);
|
|
40
|
+
detailsTable.push(['Price', formatCurrency(position.token.price)], ['Market Cap', formatCurrency(position.token.mcap)], ['Graduation', `${position.token.graduationProgress.toFixed(2)}%`], ['Tokens Owned', formatTokenAmount(position.tokensOwned)], ['USDC Invested', formatCurrency(position.usdcInvested)]);
|
|
41
|
+
// Add enhanced fields if available
|
|
42
|
+
if (position.currentValue !== undefined) {
|
|
43
|
+
detailsTable.push(['Current Value', formatCurrency(position.currentValue)]);
|
|
44
|
+
}
|
|
45
|
+
if (position.averageCostPerToken !== undefined) {
|
|
46
|
+
detailsTable.push(['Avg Cost/Token', formatCurrency(position.averageCostPerToken)]);
|
|
47
|
+
}
|
|
48
|
+
console.log(detailsTable.toString());
|
|
49
|
+
console.log();
|
|
50
|
+
// Performance section (if available)
|
|
51
|
+
if (position.pnl !== undefined && position.pnlPercentage !== undefined) {
|
|
52
|
+
const pnl = parseFloat(position.pnl) / 1e6;
|
|
53
|
+
const pnlColor = pnl >= 0 ? chalk.green : chalk.red;
|
|
54
|
+
const pnlSign = pnl >= 0 ? '+' : '';
|
|
55
|
+
const pnlIcon = pnl >= 0 ? '🟢' : '🔴';
|
|
56
|
+
console.log(chalk.bold('📈 Performance:'));
|
|
57
|
+
console.log(` ${pnlIcon} P/L: ${pnlColor(`${pnlSign}${formatCurrency(position.pnl)}`)} (${pnlColor(`${pnlSign}${position.pnlPercentage.toFixed(2)}%`)})`);
|
|
58
|
+
console.log();
|
|
59
|
+
}
|
|
60
|
+
// Position age (if available)
|
|
61
|
+
if (position.positionAge) {
|
|
62
|
+
const age = position.positionAge;
|
|
63
|
+
let ageStr = '';
|
|
64
|
+
if (age.days > 0) {
|
|
65
|
+
ageStr = `${age.days} day${age.days !== 1 ? 's' : ''}, ${age.hours} hour${age.hours !== 1 ? 's' : ''}, ${age.minutes} minute${age.minutes !== 1 ? 's' : ''}`;
|
|
66
|
+
}
|
|
67
|
+
else if (age.hours > 0) {
|
|
68
|
+
ageStr = `${age.hours} hour${age.hours !== 1 ? 's' : ''}, ${age.minutes} minute${age.minutes !== 1 ? 's' : ''}, ${age.seconds} second${age.seconds !== 1 ? 's' : ''}`;
|
|
69
|
+
}
|
|
70
|
+
else if (age.minutes > 0) {
|
|
71
|
+
ageStr = `${age.minutes} minute${age.minutes !== 1 ? 's' : ''}, ${age.seconds} second${age.seconds !== 1 ? 's' : ''}`;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
ageStr = `${age.seconds} second${age.seconds !== 1 ? 's' : ''}`;
|
|
75
|
+
}
|
|
76
|
+
console.log(chalk.bold('⏱️ Position Age:'));
|
|
77
|
+
console.log(` ${ageStr}`);
|
|
78
|
+
console.log();
|
|
79
|
+
}
|
|
80
|
+
// Transaction history (if available)
|
|
81
|
+
if (position.transactionCount !== undefined) {
|
|
82
|
+
console.log(chalk.bold('📝 Transaction History:'));
|
|
83
|
+
console.log(` Total Transactions: ${position.transactionCount}`);
|
|
84
|
+
if (position.lastTransactionDate) {
|
|
85
|
+
const lastTxDate = new Date(position.lastTransactionDate);
|
|
86
|
+
console.log(` Last Transaction: ${lastTxDate.toLocaleString()}`);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
console.log(` Last Transaction: N/A`);
|
|
90
|
+
}
|
|
91
|
+
console.log();
|
|
92
|
+
}
|
|
93
|
+
// Timestamps
|
|
94
|
+
console.log(chalk.bold('📅 Timestamps:'));
|
|
95
|
+
console.log(` Created: ${new Date(position.createdAt).toLocaleString()}`);
|
|
96
|
+
console.log(` Updated: ${new Date(position.updatedAt).toLocaleString()}`);
|
|
97
|
+
console.log();
|
|
98
|
+
}
|
|
99
|
+
// Display summary if available
|
|
100
|
+
if (result.summary) {
|
|
101
|
+
console.log(chalk.cyan('='.repeat(80)));
|
|
102
|
+
console.log(chalk.cyan.bold('📊 Portfolio Summary'));
|
|
103
|
+
console.log(chalk.cyan('='.repeat(80)));
|
|
104
|
+
console.log();
|
|
105
|
+
const summaryTable = createTable(['Metric', 'Value']);
|
|
106
|
+
summaryTable.push(['Total Positions', result.summary.totalPositions.toString()]);
|
|
107
|
+
if (result.summary.totalInvested !== undefined) {
|
|
108
|
+
summaryTable.push(['Total Invested', formatCurrency(result.summary.totalInvested)]);
|
|
109
|
+
}
|
|
110
|
+
if (result.summary.totalValue !== undefined) {
|
|
111
|
+
summaryTable.push(['Total Value', formatCurrency(result.summary.totalValue)]);
|
|
112
|
+
}
|
|
113
|
+
if (result.summary.totalPnl !== undefined && result.summary.totalPnlPercentage !== undefined) {
|
|
114
|
+
const totalPnl = parseFloat(result.summary.totalPnl) / 1e6;
|
|
115
|
+
const totalPnlColor = totalPnl >= 0 ? chalk.green : chalk.red;
|
|
116
|
+
const totalPnlSign = totalPnl >= 0 ? '+' : '';
|
|
117
|
+
const totalPnlIcon = totalPnl >= 0 ? '🟢' : '🔴';
|
|
118
|
+
summaryTable.push([
|
|
119
|
+
'Total P/L',
|
|
120
|
+
`${totalPnlIcon} ${totalPnlColor(`${totalPnlSign}${formatCurrency(result.summary.totalPnl)}`)} (${totalPnlColor(`${totalPnlSign}${result.summary.totalPnlPercentage.toFixed(2)}%`)})`
|
|
121
|
+
]);
|
|
122
|
+
}
|
|
123
|
+
console.log(summaryTable.toString());
|
|
124
|
+
console.log();
|
|
125
|
+
}
|
|
126
|
+
// Show example commands
|
|
127
|
+
if (result.positions.length > 0) {
|
|
128
|
+
const firstPosition = result.positions[0];
|
|
129
|
+
console.log(chalk.dim('💡 Example commands:'));
|
|
130
|
+
console.log(chalk.dim(` httpcat info ${firstPosition.token.symbol}`));
|
|
131
|
+
console.log(chalk.dim(` httpcat sell ${firstPosition.token.symbol} 50%`));
|
|
132
|
+
console.log(chalk.dim(` httpcat buy ${firstPosition.token.symbol} 0.10`));
|
|
133
|
+
console.log();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=positions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"positions.js","sourceRoot":"","sources":["../../src/commands/positions.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
import chalk from "chalk";
|
|
4
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
4
5
|
import { config } from "./config.js";
|
|
5
6
|
import { HttpcatClient } from "./client.js";
|
|
6
7
|
import { handleError, getExitCode } from "./utils/errors.js";
|
|
7
8
|
import { startInteractiveShell } from "./interactive/shell.js";
|
|
8
9
|
import { outputJson, outputError } from "./headless/json-output.js";
|
|
9
10
|
import { promptForPrivateKey } from "./utils/privateKeyPrompt.js";
|
|
11
|
+
import { withLoading } from "./utils/loading.js";
|
|
10
12
|
// Import commands
|
|
11
13
|
import { createToken, displayCreateResult } from "./commands/create.js";
|
|
12
14
|
import { buyToken, displayBuyResult } from "./commands/buy.js";
|
|
13
15
|
import { sellToken, displaySellResult, parseTokenAmount, } from "./commands/sell.js";
|
|
14
16
|
import { getTokenInfo, displayTokenInfo } from "./commands/info.js";
|
|
15
17
|
import { listTokens, displayTokenList } from "./commands/list.js";
|
|
18
|
+
import { getPositions, displayPositions } from "./commands/positions.js";
|
|
16
19
|
import { checkHealth, displayHealthStatus } from "./commands/health.js";
|
|
17
20
|
import { checkBalance, displayBalance } from "./commands/balance.js";
|
|
18
21
|
import { startChatStream } from "./commands/chat.js";
|
|
@@ -23,7 +26,7 @@ if (args.includes("--version") || args.includes("-V")) {
|
|
|
23
26
|
if (args.includes("--json")) {
|
|
24
27
|
console.log(JSON.stringify({
|
|
25
28
|
name: "httpcat-cli",
|
|
26
|
-
version: "0.0.
|
|
29
|
+
version: "0.0.20",
|
|
27
30
|
}, null, 2));
|
|
28
31
|
process.exit(0);
|
|
29
32
|
}
|
|
@@ -32,7 +35,7 @@ const program = new Command();
|
|
|
32
35
|
program
|
|
33
36
|
.name("httpcat")
|
|
34
37
|
.description("CLI tool for interacting with httpcat agent")
|
|
35
|
-
.version("0.0.
|
|
38
|
+
.version("0.0.20")
|
|
36
39
|
.option("--json", "Output in JSON format")
|
|
37
40
|
.option("--quiet", "Minimal output (exit codes only)")
|
|
38
41
|
.option("--verbose", "Verbose error messages")
|
|
@@ -81,6 +84,7 @@ envCommand
|
|
|
81
84
|
if (current) {
|
|
82
85
|
console.log(chalk.dim(`Current environment: ${chalk.green(current)}`));
|
|
83
86
|
}
|
|
87
|
+
process.exit(0);
|
|
84
88
|
}
|
|
85
89
|
catch (error) {
|
|
86
90
|
handleError(error, false);
|
|
@@ -98,6 +102,7 @@ envCommand
|
|
|
98
102
|
console.log(chalk.green(`✅ Switched to environment: ${name}`));
|
|
99
103
|
console.log(chalk.dim(` Agent URL: ${env?.agentUrl}`));
|
|
100
104
|
console.log(chalk.dim(` Network: ${env?.network}`));
|
|
105
|
+
process.exit(0);
|
|
101
106
|
}
|
|
102
107
|
catch (error) {
|
|
103
108
|
handleError(error, false);
|
|
@@ -112,11 +117,13 @@ envCommand
|
|
|
112
117
|
const current = config.getCurrentEnvironment();
|
|
113
118
|
if (!current) {
|
|
114
119
|
console.log(chalk.yellow("No environment selected"));
|
|
120
|
+
process.exit(0);
|
|
115
121
|
return;
|
|
116
122
|
}
|
|
117
123
|
const env = config.getEnvironmentConfig(current);
|
|
118
124
|
if (!env) {
|
|
119
125
|
console.log(chalk.yellow(`Environment "${current}" not found`));
|
|
126
|
+
process.exit(0);
|
|
120
127
|
return;
|
|
121
128
|
}
|
|
122
129
|
console.log();
|
|
@@ -125,6 +132,7 @@ envCommand
|
|
|
125
132
|
console.log(chalk.dim(`Agent URL: ${env.agentUrl}`));
|
|
126
133
|
console.log(chalk.dim(`Network: ${env.network}`));
|
|
127
134
|
console.log();
|
|
135
|
+
process.exit(0);
|
|
128
136
|
}
|
|
129
137
|
catch (error) {
|
|
130
138
|
handleError(error, false);
|
|
@@ -145,6 +153,7 @@ envCommand
|
|
|
145
153
|
console.log(chalk.dim(` Network: ${options.network}`));
|
|
146
154
|
console.log();
|
|
147
155
|
console.log(chalk.dim(`Switch to it with: httpcat env use ${name}`));
|
|
156
|
+
process.exit(0);
|
|
148
157
|
}
|
|
149
158
|
catch (error) {
|
|
150
159
|
handleError(error, false);
|
|
@@ -163,6 +172,7 @@ envCommand
|
|
|
163
172
|
console.log(chalk.green(`✅ Updated environment: ${name}`));
|
|
164
173
|
console.log(chalk.dim(` Agent URL: ${agentUrl}`));
|
|
165
174
|
console.log(chalk.dim(` Network: ${options.network}`));
|
|
175
|
+
process.exit(0);
|
|
166
176
|
}
|
|
167
177
|
catch (error) {
|
|
168
178
|
handleError(error, false);
|
|
@@ -235,12 +245,17 @@ Examples:
|
|
|
235
245
|
privateKey = await promptForPrivateKey();
|
|
236
246
|
}
|
|
237
247
|
const client = await HttpcatClient.create(privateKey);
|
|
238
|
-
const result = await createToken(client, {
|
|
248
|
+
const result = await withLoading(() => createToken(client, {
|
|
239
249
|
name,
|
|
240
250
|
symbol,
|
|
241
251
|
photoUrl: options.photo,
|
|
242
252
|
bannerUrl: options.banner,
|
|
243
253
|
websiteUrl: options.website,
|
|
254
|
+
}), {
|
|
255
|
+
message: "Creating token...",
|
|
256
|
+
json: globalOpts.json,
|
|
257
|
+
quiet: globalOpts.quiet,
|
|
258
|
+
spinner: "cat",
|
|
244
259
|
});
|
|
245
260
|
if (globalOpts.json) {
|
|
246
261
|
outputJson("create_token", result);
|
|
@@ -291,7 +306,12 @@ Examples:
|
|
|
291
306
|
const client = await HttpcatClient.create(privateKey);
|
|
292
307
|
const isTestMode = client.getNetwork().includes("sepolia");
|
|
293
308
|
const silent = globalOpts.json || globalOpts.quiet;
|
|
294
|
-
const result = await buyToken(client, tokenId, amount, isTestMode, silent)
|
|
309
|
+
const result = await withLoading(() => buyToken(client, tokenId, amount, isTestMode, silent), {
|
|
310
|
+
message: "Buying tokens...",
|
|
311
|
+
json: globalOpts.json,
|
|
312
|
+
quiet: globalOpts.quiet,
|
|
313
|
+
spinner: "cat",
|
|
314
|
+
});
|
|
295
315
|
if (globalOpts.json) {
|
|
296
316
|
outputJson("token_buy", result);
|
|
297
317
|
}
|
|
@@ -339,13 +359,26 @@ Examples:
|
|
|
339
359
|
}
|
|
340
360
|
const client = await HttpcatClient.create(privateKey);
|
|
341
361
|
const silent = globalOpts.json || globalOpts.quiet;
|
|
362
|
+
// Derive user address from private key
|
|
363
|
+
const account = privateKeyToAccount(privateKey);
|
|
364
|
+
const userAddress = account.address;
|
|
342
365
|
// Get current holdings
|
|
343
|
-
const info = await getTokenInfo(client, tokenId,
|
|
366
|
+
const info = await withLoading(() => getTokenInfo(client, tokenId, userAddress, silent), {
|
|
367
|
+
message: "Checking token info...",
|
|
368
|
+
json: globalOpts.json,
|
|
369
|
+
quiet: globalOpts.quiet,
|
|
370
|
+
spinner: "cat",
|
|
371
|
+
});
|
|
344
372
|
if (!info.userPosition || info.userPosition.tokensOwned === "0") {
|
|
345
373
|
throw new Error("You do not own any of this token");
|
|
346
374
|
}
|
|
347
375
|
const tokenAmount = parseTokenAmount(amountInput, info.userPosition.tokensOwned);
|
|
348
|
-
const result = await sellToken(client, tokenId, tokenAmount, silent)
|
|
376
|
+
const result = await withLoading(() => sellToken(client, tokenId, tokenAmount, silent), {
|
|
377
|
+
message: "Selling tokens...",
|
|
378
|
+
json: globalOpts.json,
|
|
379
|
+
quiet: globalOpts.quiet,
|
|
380
|
+
spinner: "cat",
|
|
381
|
+
});
|
|
349
382
|
if (globalOpts.json) {
|
|
350
383
|
outputJson("token_sell", result);
|
|
351
384
|
}
|
|
@@ -392,7 +425,12 @@ Examples:
|
|
|
392
425
|
}
|
|
393
426
|
const client = await HttpcatClient.create(privateKey);
|
|
394
427
|
const silent = globalOpts.json || globalOpts.quiet;
|
|
395
|
-
const result = await getTokenInfo(client, tokenId, undefined, silent)
|
|
428
|
+
const result = await withLoading(() => getTokenInfo(client, tokenId, undefined, silent), {
|
|
429
|
+
message: "Fetching token info...",
|
|
430
|
+
json: globalOpts.json,
|
|
431
|
+
quiet: globalOpts.quiet,
|
|
432
|
+
spinner: "cat",
|
|
433
|
+
});
|
|
396
434
|
if (globalOpts.json) {
|
|
397
435
|
outputJson("token_info", result);
|
|
398
436
|
}
|
|
@@ -440,7 +478,12 @@ Examples:
|
|
|
440
478
|
privateKey = await promptForPrivateKey();
|
|
441
479
|
}
|
|
442
480
|
const client = await HttpcatClient.create(privateKey);
|
|
443
|
-
const result = await listTokens(client, parseInt(options.page), parseInt(options.limit), options.sort)
|
|
481
|
+
const result = await withLoading(() => listTokens(client, parseInt(options.page), parseInt(options.limit), options.sort), {
|
|
482
|
+
message: "Fetching token list...",
|
|
483
|
+
json: globalOpts.json,
|
|
484
|
+
quiet: globalOpts.quiet,
|
|
485
|
+
spinner: "cat",
|
|
486
|
+
});
|
|
444
487
|
if (globalOpts.json) {
|
|
445
488
|
outputJson("list_tokens", result);
|
|
446
489
|
}
|
|
@@ -460,6 +503,55 @@ Examples:
|
|
|
460
503
|
process.exit(getExitCode(error));
|
|
461
504
|
}
|
|
462
505
|
});
|
|
506
|
+
// Positions command
|
|
507
|
+
program
|
|
508
|
+
.command("positions")
|
|
509
|
+
.description("Get all your positions with comprehensive information")
|
|
510
|
+
.addHelpText("after", `
|
|
511
|
+
Examples:
|
|
512
|
+
httpcat positions
|
|
513
|
+
httpcat --json positions
|
|
514
|
+
httpcat --private-key 0x... positions
|
|
515
|
+
`)
|
|
516
|
+
.action(async (command) => {
|
|
517
|
+
try {
|
|
518
|
+
const globalOpts = command.parent?.opts() || {};
|
|
519
|
+
let privateKey = getPrivateKey(globalOpts.privateKey);
|
|
520
|
+
// If not configured and not in JSON mode, prompt interactively
|
|
521
|
+
if (!isConfigured(globalOpts.privateKey)) {
|
|
522
|
+
if (globalOpts.json) {
|
|
523
|
+
console.error('❌ Not configured. Run "httpcat config" first or use --private-key flag.');
|
|
524
|
+
process.exit(2);
|
|
525
|
+
}
|
|
526
|
+
// Interactive prompt for private key
|
|
527
|
+
privateKey = await promptForPrivateKey();
|
|
528
|
+
}
|
|
529
|
+
const client = await HttpcatClient.create(privateKey);
|
|
530
|
+
const result = await withLoading(() => getPositions(client), {
|
|
531
|
+
message: "Fetching positions...",
|
|
532
|
+
json: globalOpts.json,
|
|
533
|
+
quiet: globalOpts.quiet,
|
|
534
|
+
spinner: "cat",
|
|
535
|
+
});
|
|
536
|
+
if (globalOpts.json) {
|
|
537
|
+
outputJson("positions", result);
|
|
538
|
+
}
|
|
539
|
+
else if (!globalOpts.quiet) {
|
|
540
|
+
displayPositions(result);
|
|
541
|
+
}
|
|
542
|
+
process.exit(0);
|
|
543
|
+
}
|
|
544
|
+
catch (error) {
|
|
545
|
+
const globalOpts = command.parent?.opts() || {};
|
|
546
|
+
if (globalOpts.json) {
|
|
547
|
+
outputError("positions", error, getExitCode(error));
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
handleError(error, globalOpts.verbose);
|
|
551
|
+
}
|
|
552
|
+
process.exit(getExitCode(error));
|
|
553
|
+
}
|
|
554
|
+
});
|
|
463
555
|
// Health command
|
|
464
556
|
program
|
|
465
557
|
.command("health")
|
|
@@ -479,7 +571,12 @@ Examples:
|
|
|
479
571
|
process.exit(2);
|
|
480
572
|
}
|
|
481
573
|
const client = await HttpcatClient.create(privateKey);
|
|
482
|
-
const result = await checkHealth(client)
|
|
574
|
+
const result = await withLoading(() => checkHealth(client), {
|
|
575
|
+
message: "Checking health...",
|
|
576
|
+
json: globalOpts.json,
|
|
577
|
+
quiet: globalOpts.quiet,
|
|
578
|
+
spinner: "cat",
|
|
579
|
+
});
|
|
483
580
|
if (globalOpts.json) {
|
|
484
581
|
outputJson("health", result);
|
|
485
582
|
}
|
|
@@ -522,7 +619,12 @@ Examples:
|
|
|
522
619
|
// Interactive prompt for private key (handled inside checkBalance)
|
|
523
620
|
privateKey = undefined;
|
|
524
621
|
}
|
|
525
|
-
const result = await checkBalance(privateKey)
|
|
622
|
+
const result = await withLoading(() => checkBalance(privateKey), {
|
|
623
|
+
message: "Checking balance...",
|
|
624
|
+
json: globalOpts.json,
|
|
625
|
+
quiet: globalOpts.quiet,
|
|
626
|
+
spinner: "cat",
|
|
627
|
+
});
|
|
526
628
|
if (globalOpts.json) {
|
|
527
629
|
outputJson("balance", result);
|
|
528
630
|
}
|