@aiaiaichain/agent 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/cli.js +224 -9
  2. package/dist/core/ChainConfig.js +1 -1
  3. package/dist/core/SystemMonitor.d.ts +1 -4
  4. package/dist/core/SystemMonitor.js +20 -46
  5. package/dist/index.d.ts +10 -0
  6. package/dist/index.js +11 -0
  7. package/dist/models/ModelRegistry.js +12 -4
  8. package/dist/runner/AgentRunner.d.ts +2 -0
  9. package/dist/runner/AgentRunner.js +18 -1
  10. package/dist/runner/ModelClient.js +109 -48
  11. package/dist/session/SessionManager.d.ts +1 -0
  12. package/dist/session/SessionManager.js +8 -2
  13. package/dist/session/SessionStore.js +8 -3
  14. package/dist/tools/CrossTools.js +13 -5
  15. package/dist/tools/MarketSentiment.js +22 -13
  16. package/dist/tools/NewsSentiment.js +9 -3
  17. package/dist/tools/PriceFeed.js +11 -4
  18. package/dist/tools/TechnicalAnalysis.js +2 -1
  19. package/dist/tools/TokenCalendar.d.ts +24 -0
  20. package/dist/tools/TokenCalendar.js +81 -0
  21. package/dist/tools/TokenSecurityScanner.d.ts +22 -0
  22. package/dist/tools/TokenSecurityScanner.js +102 -0
  23. package/dist/tools/TransactionSim.d.ts +17 -0
  24. package/dist/tools/TransactionSim.js +78 -0
  25. package/dist/tui/App.js +145 -23
  26. package/dist/tui/REPL.js +2 -2
  27. package/dist/tui/Sparkline.d.ts +21 -0
  28. package/dist/tui/Sparkline.js +44 -0
  29. package/dist/tui/ThemePresets.d.ts +25 -0
  30. package/dist/tui/ThemePresets.js +117 -0
  31. package/dist/util/clipboard.d.ts +9 -0
  32. package/dist/util/clipboard.js +26 -0
  33. package/dist/util/commandSuggest.d.ts +7 -0
  34. package/dist/util/commandSuggest.js +44 -0
  35. package/dist/util/confirmation.d.ts +6 -0
  36. package/dist/util/confirmation.js +16 -0
  37. package/dist/util/errorHandler.d.ts +3 -0
  38. package/dist/util/errorHandler.js +28 -0
  39. package/dist/util/logger.d.ts +11 -0
  40. package/dist/util/logger.js +43 -0
  41. package/dist/util/processManager.d.ts +5 -0
  42. package/dist/util/processManager.js +39 -0
  43. package/dist/util/resilientFetch.d.ts +21 -0
  44. package/dist/util/resilientFetch.js +94 -0
  45. package/dist/util/responseCache.d.ts +27 -0
  46. package/dist/util/responseCache.js +54 -0
  47. package/dist/util/safeLog.d.ts +4 -5
  48. package/dist/util/safeLog.js +68 -30
  49. package/dist/util/scheduler.d.ts +14 -0
  50. package/dist/util/scheduler.js +75 -0
  51. package/dist/util/webhooks.d.ts +9 -0
  52. package/dist/util/webhooks.js +75 -0
  53. package/dist/wallet/ActionFeed.d.ts +3 -2
  54. package/dist/wallet/ActionFeed.js +97 -76
  55. package/dist/wallet/AgentWallet.d.ts +6 -2
  56. package/dist/wallet/AgentWallet.js +59 -27
  57. package/dist/wallet/ProfitTracker.d.ts +30 -0
  58. package/dist/wallet/ProfitTracker.js +93 -0
  59. package/package.json +2 -2
@@ -8,10 +8,18 @@
8
8
  * Signer: GmFrDZT2cdrqykgTikVdXbe8EtCgzUDM9VsDhQnwsUsG (authority)
9
9
  */
10
10
  import { Type } from "@sinclair/typebox";
11
- export const COLD_WALLET = "A11iZoqEt6hU7HyggqC67ee4AtYmaJjwKCvJLerJRV2J";
12
- export const ACTION_WALLET = "BygDYM1ZXLQNC1HXLhnd1rHZ7E5XjioqT3vPjJFfjnU2";
11
+ import { resilientFetch } from "../util/resilientFetch.js";
12
+ import { logger } from "../util/logger.js";
13
+ // Wallet architecture (verified on-chain):
14
+ // ACTION: GmFrDZT2cdrqykgTikVdXbe8EtCgzUDM9VsDhQnwsUsG (executes buys + burns)
15
+ // HOT: BygDYM1ZXLQNC1HXLhnd1rHZ7E5XjioqT3vPjJFfjnU2 (temporary swap + burn)
16
+ // DEPOSIT: FBMDYpG9WXKy4SgxuATQdB2sCyzHsJWPrEr45z3TgL2e (user deposits)
17
+ // COLD: A11iZoqEt6hU7HyggqC67ee4AtYmaJjwKCvJLerJRV2J (reserve — /wallet only)
18
+ export const ACTION_WALLET = "GmFrDZT2cdrqykgTikVdXbe8EtCgzUDM9VsDhQnwsUsG";
19
+ export const HOT_WALLET = "BygDYM1ZXLQNC1HXLhnd1rHZ7E5XjioqT3vPjJFfjnU2";
13
20
  export const DEPOSIT_WALLET = "FBMDYpG9WXKy4SgxuATQdB2sCyzHsJWPrEr45z3TgL2e";
14
- export const SIGNER = "GmFrDZT2cdrqykgTikVdXbe8EtCgzUDM9VsDhQnwsUsG";
21
+ export const COLD_WALLET = "A11iZoqEt6hU7HyggqC67ee4AtYmaJjwKCvJLerJRV2J";
22
+ export const SIGNER = ACTION_WALLET;
15
23
  export const AIAIAI_MINT = "AVPJS61gZmWKtaEpb7qYPKo8Fk2xQUsayYQxPiPMpump";
16
24
  export const AIAIAI_TOKEN = AIAIAI_MINT;
17
25
  const USDC_MINT = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
@@ -19,14 +27,21 @@ function getRpcUrl() {
19
27
  return process.env.SOLANA_RPC_URL || "https://api.mainnet-beta.solana.com";
20
28
  }
21
29
  async function rpcCall(method, params = []) {
22
- const response = await fetch(getRpcUrl(), {
30
+ const response = await resilientFetch(getRpcUrl(), {
31
+ timeout: 15_000,
32
+ retries: 2,
23
33
  method: "POST",
24
34
  headers: { "Content-Type": "application/json" },
25
35
  body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }),
26
36
  });
27
37
  const data = await response.json();
28
- if (data.error)
29
- throw new Error(data.error.message);
38
+ if (data.error) {
39
+ const msg = data.error.message || 'Unknown RPC error';
40
+ if (data.error.code === -32005 || msg.includes('rate limit')) {
41
+ logger.warn('AgentWallet', 'RPC rate limited', { method, code: data.error.code });
42
+ }
43
+ throw new Error(msg);
44
+ }
30
45
  return data.result;
31
46
  }
32
47
  async function getBalance(address) {
@@ -34,7 +49,8 @@ async function getBalance(address) {
34
49
  const result = await rpcCall("getBalance", [address]);
35
50
  return (result?.value ?? 0) / 1e9;
36
51
  }
37
- catch {
52
+ catch (error) {
53
+ logger.warn('AgentWallet', 'getBalance failed', { address, error: error.message });
38
54
  return 0;
39
55
  }
40
56
  }
@@ -50,7 +66,8 @@ async function getTokenBalance(address, mint) {
50
66
  return 0;
51
67
  return parseFloat(accounts[0]?.account?.data?.parsed?.info?.tokenAmount?.uiAmount ?? "0");
52
68
  }
53
- catch {
69
+ catch (error) {
70
+ logger.warn('AgentWallet', 'getTokenBalance failed', { address, mint, error: error.message });
54
71
  return 0;
55
72
  }
56
73
  }
@@ -62,20 +79,17 @@ export class AgentWallet {
62
79
  if (this.cachedWallets && Date.now() - this.lastFetch < this.cacheDuration) {
63
80
  return this.cachedWallets;
64
81
  }
65
- const [coldSol, coldAiai, coldUsdc, actionSol, actionAiai, actionUsdc, depSol, depAiai, depUsdc] = await Promise.all([
66
- getBalance(COLD_WALLET),
67
- getTokenBalance(COLD_WALLET, AIAIAI_MINT),
68
- getTokenBalance(COLD_WALLET, USDC_MINT),
69
- getBalance(ACTION_WALLET),
70
- getTokenBalance(ACTION_WALLET, AIAIAI_MINT),
71
- getTokenBalance(ACTION_WALLET, USDC_MINT),
72
- getBalance(DEPOSIT_WALLET),
73
- getTokenBalance(DEPOSIT_WALLET, AIAIAI_MINT),
74
- getTokenBalance(DEPOSIT_WALLET, USDC_MINT),
82
+ // 4 wallets × 3 tokens = 12 parallel queries
83
+ const [coldSol, coldAiai, coldUsdc, actionSol, actionAiai, actionUsdc, hotSol, hotAiai, hotUsdc, depSol, depAiai, depUsdc] = await Promise.all([
84
+ getBalance(COLD_WALLET), getTokenBalance(COLD_WALLET, AIAIAI_MINT), getTokenBalance(COLD_WALLET, USDC_MINT),
85
+ getBalance(ACTION_WALLET), getTokenBalance(ACTION_WALLET, AIAIAI_MINT), getTokenBalance(ACTION_WALLET, USDC_MINT),
86
+ getBalance(HOT_WALLET), getTokenBalance(HOT_WALLET, AIAIAI_MINT), getTokenBalance(HOT_WALLET, USDC_MINT),
87
+ getBalance(DEPOSIT_WALLET), getTokenBalance(DEPOSIT_WALLET, AIAIAI_MINT), getTokenBalance(DEPOSIT_WALLET, USDC_MINT),
75
88
  ]);
76
89
  this.cachedWallets = {
77
90
  cold: { address: COLD_WALLET, sol: coldSol, aiaiai: coldAiai, usdc: coldUsdc },
78
91
  action: { address: ACTION_WALLET, sol: actionSol, aiaiai: actionAiai, usdc: actionUsdc },
92
+ hot: { address: HOT_WALLET, sol: hotSol, aiaiai: hotAiai, usdc: hotUsdc },
79
93
  deposit: { address: DEPOSIT_WALLET, sol: depSol, aiaiai: depAiai, usdc: depUsdc },
80
94
  };
81
95
  this.lastFetch = Date.now();
@@ -90,23 +104,41 @@ export class AgentWallet {
90
104
  async getDepositWallet() {
91
105
  return (await this.getAll()).deposit;
92
106
  }
107
+ // Get live SOL price from PriceFeed
108
+ async getSolPrice() {
109
+ try {
110
+ const { priceFeed } = await import("../tools/PriceFeed.js");
111
+ const result = await priceFeed.fetchToken("So11111111111111111111111111111111111111112");
112
+ return parseFloat(result.priceUsd ?? "150");
113
+ }
114
+ catch {
115
+ return 150; // fallback
116
+ }
117
+ }
93
118
  // ── Tools ───────────────────────────────────────────────────────────────
119
+ async getHotWallet() {
120
+ return (await this.getAll()).hot;
121
+ }
94
122
  getAgentBalanceParams = Type.Object({});
95
123
  getDepositBalanceParams = Type.Object({});
96
124
  async getAgentBalanceTool() {
97
125
  const w = await this.getAll();
98
126
  const lines = [
99
- `Agent Cold Wallet`,
100
- ` Address: ${COLD_WALLET.slice(0, 8)}…${COLD_WALLET.slice(-6)}`,
101
- ` SOL: ${w.cold.sol.toFixed(4)}`,
102
- ` $AIAIAI: ${w.cold.aiaiai.toLocaleString(undefined, { maximumFractionDigits: 2 })}`,
103
- ` USDC: ${w.cold.usdc.toFixed(2)}`,
104
- ``,
105
- `Agent Action Wallet`,
106
- ` Address: ${ACTION_WALLET.slice(0, 8)}…${ACTION_WALLET.slice(-6)}`,
127
+ `🤖 Action Wallet`,
128
+ ` ${ACTION_WALLET.slice(0, 8)}…${ACTION_WALLET.slice(-6)}`,
107
129
  ` SOL: ${w.action.sol.toFixed(4)}`,
108
- ` $AIAIAI: ${w.action.aiaiai.toLocaleString(undefined, { maximumFractionDigits: 2 })}`,
130
+ ` $AIAIAI: ${w.action.aiaiai.toLocaleString(undefined, { maximumFractionDigits: 2 })}`,
109
131
  ` USDC: ${w.action.usdc.toFixed(2)}`,
132
+ ``,
133
+ `⚡ Hot Wallet`,
134
+ ` ${HOT_WALLET.slice(0, 8)}…${HOT_WALLET.slice(-6)}`,
135
+ ` SOL: ${w.hot.sol.toFixed(4)}`,
136
+ ` $AIAIAI: ${w.hot.aiaiai.toLocaleString(undefined, { maximumFractionDigits: 2 })}`,
137
+ ` USDC: ${w.hot.usdc.toFixed(2)}`,
138
+ ``,
139
+ `❄️ Cold (reserve)`,
140
+ ` ${COLD_WALLET.slice(0, 8)}…${COLD_WALLET.slice(-6)}`,
141
+ ` SOL: ${w.cold.sol.toFixed(4)}`,
110
142
  ];
111
143
  return { content: [{ type: "text", text: lines.join("\n") }] };
112
144
  }
@@ -0,0 +1,30 @@
1
+ /**
2
+ /ProfitTracker.ts - Track cost basis and P&L for agent wallet trades
3
+ */
4
+ export interface Trade {
5
+ timestamp: number;
6
+ type: "buy" | "sell" | "burn";
7
+ tokenAmount: number;
8
+ solAmount: number;
9
+ pricePerToken: number;
10
+ txSignature?: string;
11
+ }
12
+ export interface ProfitState {
13
+ trades: Trade[];
14
+ totalSpent: number;
15
+ totalReceived: number;
16
+ avgCostBasis: number;
17
+ }
18
+ export interface PLSummary {
19
+ avgCostBasis: number;
20
+ totalSpent: number;
21
+ totalReceived: number;
22
+ realizedPL: number;
23
+ unrealizedPL: number;
24
+ roi: number;
25
+ }
26
+ export declare function recordTrade(type: "buy" | "sell" | "burn", tokenAmount: number, solAmount: number, txSignature?: string): void;
27
+ export declare function getPLSummary(currentTokenPrice: number): PLSummary;
28
+ export declare function getTradeHistory(): Trade[];
29
+ export declare function exportCSV(): string;
30
+ //# sourceMappingURL=ProfitTracker.d.ts.map
@@ -0,0 +1,93 @@
1
+ /**
2
+ /ProfitTracker.ts - Track cost basis and P&L for agent wallet trades
3
+ */
4
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
5
+ import { join } from "node:path";
6
+ import { homedir } from "node:os";
7
+ import { logger } from "../util/logger.js";
8
+ const AIAIAI_HOME = process.env.AIAIAI_HOME ?? join(homedir(), ".aiaiai");
9
+ const TRACKER_DIR = join(AIAIAI_HOME, ".tracker");
10
+ const TRACKER_FILE = join(TRACKER_DIR, "pl.json");
11
+ function loadState() {
12
+ try {
13
+ const raw = readFileSync(TRACKER_FILE, "utf-8");
14
+ return JSON.parse(raw);
15
+ }
16
+ catch {
17
+ return { trades: [], totalSpent: 0, totalReceived: 0, avgCostBasis: 0 };
18
+ }
19
+ }
20
+ function saveState(state) {
21
+ try {
22
+ if (!existsSync(TRACKER_DIR)) {
23
+ mkdirSync(TRACKER_DIR, { recursive: true, mode: 0o700 });
24
+ }
25
+ writeFileSync(TRACKER_FILE, JSON.stringify(state, null, 2), "utf-8");
26
+ }
27
+ catch (error) {
28
+ logger.warn("ProfitTracker", "Failed to save state", { error: error.message });
29
+ }
30
+ }
31
+ export function recordTrade(type, tokenAmount, solAmount, txSignature) {
32
+ const state = loadState();
33
+ const pricePerToken = tokenAmount > 0 ? solAmount / tokenAmount : 0;
34
+ const trade = {
35
+ timestamp: Date.now(),
36
+ type,
37
+ tokenAmount,
38
+ solAmount,
39
+ pricePerToken,
40
+ txSignature,
41
+ };
42
+ state.trades.push(trade);
43
+ if (type === "buy") {
44
+ state.totalSpent += solAmount;
45
+ const totalTokensInvested = state.trades
46
+ .filter(t => t.type === "buy")
47
+ .reduce((sum, t) => sum + t.tokenAmount, 0);
48
+ state.avgCostBasis = totalTokensInvested > 0 ? state.totalSpent / totalTokensInvested : 0;
49
+ }
50
+ else if (type === "sell") {
51
+ state.totalReceived += solAmount;
52
+ }
53
+ saveState(state);
54
+ logger.info("ProfitTracker", "Recorded " + type, { tokenAmount, solAmount, pricePerToken });
55
+ }
56
+ export function getPLSummary(currentTokenPrice) {
57
+ const state = loadState();
58
+ const buyTrades = state.trades.filter(t => t.type === "buy");
59
+ const totalBought = buyTrades.reduce((sum, t) => sum + t.tokenAmount, 0);
60
+ const totalSoldOrBurned = state.trades
61
+ .filter(t => t.type === "sell" || t.type === "burn")
62
+ .reduce((sum, t) => sum + t.tokenAmount, 0);
63
+ const remainingTokens = totalBought - totalSoldOrBurned;
64
+ const realizedPL = state.totalReceived - (state.totalSpent * (totalSoldOrBurned / Math.max(totalBought, 1)));
65
+ const unrealizedPL = remainingTokens * currentTokenPrice;
66
+ const totalPL = realizedPL + unrealizedPL;
67
+ const roi = state.totalSpent > 0 ? (totalPL / state.totalSpent) * 100 : 0;
68
+ return {
69
+ avgCostBasis: state.avgCostBasis,
70
+ totalSpent: state.totalSpent,
71
+ totalReceived: state.totalReceived,
72
+ realizedPL,
73
+ unrealizedPL,
74
+ roi,
75
+ };
76
+ }
77
+ export function getTradeHistory() {
78
+ return loadState().trades;
79
+ }
80
+ export function exportCSV() {
81
+ const state = loadState();
82
+ const header = "timestamp,type,tokenAmount,solAmount,pricePerToken,txSignature";
83
+ const rows = state.trades.map(t => t.timestamp + "," + t.type + "," + t.tokenAmount + "," + t.solAmount + "," + t.pricePerToken + "," + (t.txSignature ?? ""));
84
+ const csv = header + "\n" + rows.join("\n");
85
+ const csvPath = join(TRACKER_DIR, "pl-export.csv");
86
+ if (!existsSync(TRACKER_DIR)) {
87
+ mkdirSync(TRACKER_DIR, { recursive: true, mode: 0o700 });
88
+ }
89
+ writeFileSync(csvPath, csv, "utf-8");
90
+ logger.info("ProfitTracker", "Exported CSV", { path: csvPath });
91
+ return csvPath;
92
+ }
93
+ //# sourceMappingURL=ProfitTracker.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiaiaichain/agent",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "AIAIAI Chain Agent — Solana-native AI agent for decentralized AI governance. Ticker: $AIAIAI",
5
5
  "author": "AIAIAI Foundation",
6
6
  "license": "MIT",
@@ -64,4 +64,4 @@
64
64
  "docs",
65
65
  "!dist/**/*.map"
66
66
  ]
67
- }
67
+ }