@aiaiaichain/agent 0.1.5 → 0.1.7
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/api/ExtensionAPI.d.ts +0 -1
- package/dist/api/ExtensionAPI.js +3 -7
- package/dist/api/Registry.d.ts +0 -1
- package/dist/api/Registry.js +54 -57
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +684 -685
- package/dist/core/AgentDir.d.ts +1 -1
- package/dist/core/AgentDir.js +45 -39
- package/dist/core/ChainConfig.d.ts +0 -1
- package/dist/core/ChainConfig.js +51 -55
- package/dist/core/EnvLoader.d.ts +4 -1
- package/dist/core/EnvLoader.js +97 -84
- package/dist/core/SystemMonitor.d.ts +0 -1
- package/dist/core/SystemMonitor.js +72 -85
- package/dist/index.d.ts +0 -1
- package/dist/index.js +19 -26
- package/dist/loader.d.ts +0 -1
- package/dist/loader.js +64 -67
- package/dist/mcp/entry.d.ts +0 -1
- package/dist/mcp/entry.js +3 -6
- package/dist/mcp/server.d.ts +0 -1
- package/dist/mcp/server.js +152 -156
- package/dist/models/CostTracker.d.ts +0 -1
- package/dist/models/CostTracker.js +58 -61
- package/dist/models/ModelRegistry.d.ts +0 -1
- package/dist/models/ModelRegistry.js +195 -155
- package/dist/providers/ProviderRegistry.d.ts +0 -1
- package/dist/providers/ProviderRegistry.js +33 -36
- package/dist/runner/AgentRunner.d.ts +0 -1
- package/dist/runner/AgentRunner.js +180 -184
- package/dist/runner/ModelClient.d.ts +0 -1
- package/dist/runner/ModelClient.js +133 -134
- package/dist/runner/SwarmRouter.d.ts +0 -1
- package/dist/runner/SwarmRouter.js +18 -22
- package/dist/runner/ToolDispatcher.d.ts +0 -1
- package/dist/runner/ToolDispatcher.js +30 -33
- package/dist/scheduler/AgentScheduler.d.ts +0 -1
- package/dist/scheduler/AgentScheduler.js +99 -103
- package/dist/session/ContextStore.d.ts +1 -1
- package/dist/session/ContextStore.js +76 -78
- package/dist/session/GoalManager.d.ts +0 -1
- package/dist/session/GoalManager.js +96 -100
- package/dist/session/MemoryStore.d.ts +2 -1
- package/dist/session/MemoryStore.js +108 -87
- package/dist/session/SessionManager.d.ts +5 -4
- package/dist/session/SessionManager.js +83 -62
- package/dist/session/SessionStore.d.ts +0 -1
- package/dist/session/SessionStore.js +112 -116
- package/dist/setup/SetupWizard.d.ts +0 -1
- package/dist/setup/SetupWizard.js +61 -64
- package/dist/tools/CrossTools.d.ts +0 -1
- package/dist/tools/CrossTools.js +140 -144
- package/dist/tools/GmgnIntegration.d.ts +0 -1
- package/dist/tools/GmgnIntegration.js +220 -230
- package/dist/tools/MarketSentiment.d.ts +0 -1
- package/dist/tools/MarketSentiment.js +213 -195
- package/dist/tools/NewsSentiment.d.ts +0 -1
- package/dist/tools/NewsSentiment.js +126 -130
- package/dist/tools/PriceFeed.d.ts +6 -1
- package/dist/tools/PriceFeed.js +201 -133
- package/dist/tools/TechnicalAnalysis.d.ts +1 -2
- package/dist/tools/TechnicalAnalysis.js +248 -216
- package/dist/tools/TechnicalAnalysis.worker.d.ts +25 -0
- package/dist/tools/TechnicalAnalysis.worker.js +92 -0
- package/dist/tools/TokenCalendar.d.ts +0 -1
- package/dist/tools/TokenCalendar.js +63 -68
- package/dist/tools/TokenSecurityScanner.d.ts +0 -1
- package/dist/tools/TokenSecurityScanner.js +93 -96
- package/dist/tools/TransactionSim.d.ts +0 -1
- package/dist/tools/TransactionSim.js +65 -71
- package/dist/tui/App.d.ts +0 -1
- package/dist/tui/App.js +895 -824
- package/dist/tui/ModelSelector.d.ts +0 -1
- package/dist/tui/ModelSelector.js +46 -49
- package/dist/tui/REPL.d.ts +0 -1
- package/dist/tui/REPL.js +222 -210
- package/dist/tui/Sparkline.d.ts +0 -1
- package/dist/tui/Sparkline.js +36 -37
- package/dist/tui/StatusBar.d.ts +0 -1
- package/dist/tui/StatusBar.js +9 -10
- package/dist/tui/ThemePresets.d.ts +0 -1
- package/dist/tui/ThemePresets.js +99 -103
- package/dist/tui/theme.d.ts +0 -1
- package/dist/tui/theme.js +50 -31
- package/dist/util/clipboard.d.ts +0 -1
- package/dist/util/clipboard.js +16 -20
- package/dist/util/commandSuggest.d.ts +0 -1
- package/dist/util/commandSuggest.js +34 -38
- package/dist/util/confirmation.d.ts +0 -1
- package/dist/util/confirmation.js +8 -11
- package/dist/util/errorHandler.d.ts +0 -1
- package/dist/util/errorHandler.js +20 -23
- package/dist/util/errors.d.ts +59 -0
- package/dist/util/errors.js +93 -0
- package/dist/util/logger.d.ts +0 -1
- package/dist/util/logger.js +30 -33
- package/dist/util/processManager.d.ts +0 -1
- package/dist/util/processManager.js +33 -36
- package/dist/util/resilientFetch.d.ts +6 -1
- package/dist/util/resilientFetch.js +134 -80
- package/dist/util/responseCache.d.ts +0 -1
- package/dist/util/responseCache.js +36 -45
- package/dist/util/rpc.d.ts +16 -0
- package/dist/util/rpc.js +69 -0
- package/dist/util/safeLog.d.ts +0 -1
- package/dist/util/safeLog.js +52 -53
- package/dist/util/scheduler.d.ts +0 -1
- package/dist/util/scheduler.js +53 -58
- package/dist/util/webhooks.d.ts +0 -1
- package/dist/util/webhooks.js +54 -58
- package/dist/wallet/ActionFeed.d.ts +3 -3
- package/dist/wallet/ActionFeed.js +189 -187
- package/dist/wallet/AgentWallet.d.ts +9 -7
- package/dist/wallet/AgentWallet.js +121 -141
- package/dist/wallet/ProfitTracker.d.ts +0 -1
- package/dist/wallet/ProfitTracker.js +71 -74
- package/package.json +12 -7
- package/scripts/build-esbuild.mjs +40 -0
- package/scripts/bundle-dts.mjs +58 -0
- package/scripts/minify.mjs +44 -0
- package/scripts/postinstall.js +27 -0
|
@@ -1,154 +1,134 @@
|
|
|
1
|
-
|
|
2
|
-
* AgentWallet — manages all agent wallet balances and activity via public RPC.
|
|
3
|
-
*
|
|
4
|
-
* Wallets:
|
|
5
|
-
* Cold: A11iZoqEt6hU7HyggqC67ee4AtYmaJjwKCvJLerJRV2J (Agent)
|
|
6
|
-
* Action: BygDYM1ZXLQNC1HXLhnd1rHZ7E5XjioqT3vPjJFfjnU2 (buys + burns)
|
|
7
|
-
* Deposit: FBMDYpG9WXKy4SgxuATQdB2sCyzHsJWPrEr45z3TgL2e (user deposits USDC/SOL)
|
|
8
|
-
* Signer: GmFrDZT2cdrqykgTikVdXbe8EtCgzUDM9VsDhQnwsUsG (authority)
|
|
9
|
-
*/
|
|
1
|
+
|
|
10
2
|
import { Type } from "@sinclair/typebox";
|
|
11
|
-
import {
|
|
3
|
+
import { rpcCall } from "../util/rpc.js";
|
|
12
4
|
import { logger } from "../util/logger.js";
|
|
13
|
-
|
|
14
|
-
export const ACTION_WALLET = "
|
|
5
|
+
|
|
6
|
+
export const ACTION_WALLET = "GmFrDZT2cdrqykgTikVdXbe8EtCgzUDM9VsDhQnwsUsG";
|
|
7
|
+
export const HOT_WALLET = "BygDYM1ZXLQNC1HXLhnd1rHZ7E5XjioqT3vPjJFfjnU2";
|
|
15
8
|
export const DEPOSIT_WALLET = "FBMDYpG9WXKy4SgxuATQdB2sCyzHsJWPrEr45z3TgL2e";
|
|
16
|
-
export const
|
|
9
|
+
export const COLD_WALLET = "A11iZoqEt6hU7HyggqC67ee4AtYmaJjwKCvJLerJRV2J";
|
|
10
|
+
export const SIGNER = ACTION_WALLET;
|
|
17
11
|
export const AIAIAI_MINT = "AVPJS61gZmWKtaEpb7qYPKo8Fk2xQUsayYQxPiPMpump";
|
|
18
12
|
export const AIAIAI_TOKEN = AIAIAI_MINT;
|
|
19
13
|
const USDC_MINT = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
|
|
20
|
-
function getRpcUrl() {
|
|
21
|
-
return process.env.SOLANA_RPC_URL || "https://api.mainnet-beta.solana.com";
|
|
22
|
-
}
|
|
23
|
-
async function rpcCall(method, params = []) {
|
|
24
|
-
const response = await resilientFetch(getRpcUrl(), {
|
|
25
|
-
timeout: 15_000,
|
|
26
|
-
retries: 2,
|
|
27
|
-
method: "POST",
|
|
28
|
-
headers: { "Content-Type": "application/json" },
|
|
29
|
-
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }),
|
|
30
|
-
});
|
|
31
|
-
const data = await response.json();
|
|
32
|
-
if (data.error) {
|
|
33
|
-
const msg = data.error.message || 'Unknown RPC error';
|
|
34
|
-
if (data.error.code === -32005 || msg.includes('rate limit')) {
|
|
35
|
-
logger.warn('AgentWallet', 'RPC rate limited', { method, code: data.error.code });
|
|
36
|
-
}
|
|
37
|
-
throw new Error(msg);
|
|
38
|
-
}
|
|
39
|
-
return data.result;
|
|
40
|
-
}
|
|
41
14
|
async function getBalance(address) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
15
|
+
try {
|
|
16
|
+
const result = await rpcCall("getBalance", [address]);
|
|
17
|
+
return (result?.value ?? 0) / 1e9;
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
logger.warn('AgentWallet', 'getBalance failed', { address, error: error.message });
|
|
21
|
+
return 0;
|
|
22
|
+
}
|
|
50
23
|
}
|
|
51
24
|
async function getTokenBalance(address, mint) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
25
|
+
try {
|
|
26
|
+
const result = await rpcCall("getTokenAccountsByOwner", [
|
|
27
|
+
address,
|
|
28
|
+
{ mint },
|
|
29
|
+
{ encoding: "jsonParsed" },
|
|
30
|
+
]);
|
|
31
|
+
const accounts = result?.value ?? [];
|
|
32
|
+
if (accounts.length === 0)
|
|
33
|
+
return 0;
|
|
34
|
+
return parseFloat(accounts[0]?.account?.data?.parsed?.info?.tokenAmount?.uiAmount ?? "0");
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
logger.warn('AgentWallet', 'getTokenBalance failed', { address, mint, error: error.message });
|
|
38
|
+
return 0;
|
|
39
|
+
}
|
|
67
40
|
}
|
|
68
41
|
export class AgentWallet {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
42
|
+
cachedWallets = null;
|
|
43
|
+
lastFetch = 0;
|
|
44
|
+
cacheDuration = 30_000;
|
|
45
|
+
async getAll() {
|
|
46
|
+
if (this.cachedWallets && Date.now() - this.lastFetch < this.cacheDuration) {
|
|
47
|
+
return this.cachedWallets;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const [solBalances, tokenResults] = await Promise.all([
|
|
51
|
+
|
|
52
|
+
rpcCall("getMultipleAccounts", [[COLD_WALLET, ACTION_WALLET, HOT_WALLET, DEPOSIT_WALLET]])
|
|
53
|
+
.then(r => (r?.value ?? []).map((a) => (a?.lamports ?? 0) / 1e9))
|
|
54
|
+
.catch(() => [0, 0, 0, 0]),
|
|
55
|
+
|
|
56
|
+
Promise.all([
|
|
57
|
+
...[COLD_WALLET, ACTION_WALLET, HOT_WALLET, DEPOSIT_WALLET].map(addr => getTokenBalance(addr, AIAIAI_MINT)),
|
|
58
|
+
...[COLD_WALLET, ACTION_WALLET, HOT_WALLET, DEPOSIT_WALLET].map(addr => getTokenBalance(addr, USDC_MINT)),
|
|
59
|
+
]),
|
|
60
|
+
]);
|
|
61
|
+
const [coldSol = 0, actionSol = 0, hotSol = 0, depSol = 0] = solBalances;
|
|
62
|
+
const [coldAiai = 0, actionAiai = 0, hotAiai = 0, depAiai = 0, coldUsdc = 0, actionUsdc = 0, hotUsdc = 0, depUsdc = 0] = tokenResults;
|
|
63
|
+
this.cachedWallets = {
|
|
64
|
+
cold: { address: COLD_WALLET, sol: coldSol, aiaiai: coldAiai, usdc: coldUsdc },
|
|
65
|
+
action: { address: ACTION_WALLET, sol: actionSol, aiaiai: actionAiai, usdc: actionUsdc },
|
|
66
|
+
hot: { address: HOT_WALLET, sol: hotSol, aiaiai: hotAiai, usdc: hotUsdc },
|
|
67
|
+
deposit: { address: DEPOSIT_WALLET, sol: depSol, aiaiai: depAiai, usdc: depUsdc },
|
|
68
|
+
};
|
|
69
|
+
this.lastFetch = Date.now();
|
|
70
|
+
return this.cachedWallets;
|
|
71
|
+
}
|
|
72
|
+
async getColdWallet() {
|
|
73
|
+
return (await this.getAll()).cold;
|
|
74
|
+
}
|
|
75
|
+
async getActionWallet() {
|
|
76
|
+
return (await this.getAll()).action;
|
|
77
|
+
}
|
|
78
|
+
async getDepositWallet() {
|
|
79
|
+
return (await this.getAll()).deposit;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async getSolPrice() {
|
|
83
|
+
try {
|
|
84
|
+
const { priceFeed } = await import("../tools/PriceFeed.js");
|
|
85
|
+
const result = await priceFeed.fetchToken("So11111111111111111111111111111111111111112");
|
|
86
|
+
return parseFloat(result.priceUsd ?? "150");
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return 150;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async getHotWallet() {
|
|
94
|
+
return (await this.getAll()).hot;
|
|
95
|
+
}
|
|
96
|
+
getAgentBalanceParams = Type.Object({});
|
|
97
|
+
getDepositBalanceParams = Type.Object({});
|
|
98
|
+
async getAgentBalanceTool() {
|
|
99
|
+
const w = await this.getAll();
|
|
100
|
+
const lines = [
|
|
101
|
+
`🤖 Action Wallet`,
|
|
102
|
+
` ${ACTION_WALLET.slice(0, 8)}…${ACTION_WALLET.slice(-6)}`,
|
|
103
|
+
` SOL: ${w.action.sol.toFixed(4)}`,
|
|
104
|
+
` $AIAIAI: ${w.action.aiaiai.toLocaleString(undefined, { maximumFractionDigits: 2 })}`,
|
|
105
|
+
` USDC: ${w.action.usdc.toFixed(2)}`,
|
|
106
|
+
``,
|
|
107
|
+
`⚡ Hot Wallet`,
|
|
108
|
+
` ${HOT_WALLET.slice(0, 8)}…${HOT_WALLET.slice(-6)}`,
|
|
109
|
+
` SOL: ${w.hot.sol.toFixed(4)}`,
|
|
110
|
+
` $AIAIAI: ${w.hot.aiaiai.toLocaleString(undefined, { maximumFractionDigits: 2 })}`,
|
|
111
|
+
` USDC: ${w.hot.usdc.toFixed(2)}`,
|
|
112
|
+
``,
|
|
113
|
+
`❄️ Cold (reserve)`,
|
|
114
|
+
` ${COLD_WALLET.slice(0, 8)}…${COLD_WALLET.slice(-6)}`,
|
|
115
|
+
` SOL: ${w.cold.sol.toFixed(4)}`,
|
|
116
|
+
];
|
|
117
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
118
|
+
}
|
|
119
|
+
async getDepositBalanceTool() {
|
|
120
|
+
const w = await this.getAll();
|
|
121
|
+
const lines = [
|
|
122
|
+
`Deposit Wallet`,
|
|
123
|
+
` Address: ${DEPOSIT_WALLET}`,
|
|
124
|
+
` SOL: ${w.deposit.sol.toFixed(4)}`,
|
|
125
|
+
` $AIAIAI: ${w.deposit.aiaiai.toLocaleString(undefined, { maximumFractionDigits: 2 })}`,
|
|
126
|
+
` USDC: ${w.deposit.usdc.toFixed(2)}`,
|
|
127
|
+
``,
|
|
128
|
+
`Send SOL or USDC here to fuel agent actions.`,
|
|
129
|
+
`Signer: ${SIGNER.slice(0, 8)}…`,
|
|
130
|
+
];
|
|
131
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
132
|
+
}
|
|
152
133
|
}
|
|
153
134
|
export const agentWallet = new AgentWallet();
|
|
154
|
-
//# sourceMappingURL=AgentWallet.js.map
|
|
@@ -27,4 +27,3 @@ export declare function recordTrade(type: "buy" | "sell" | "burn", tokenAmount:
|
|
|
27
27
|
export declare function getPLSummary(currentTokenPrice: number): PLSummary;
|
|
28
28
|
export declare function getTradeHistory(): Trade[];
|
|
29
29
|
export declare function exportCSV(): string;
|
|
30
|
-
//# sourceMappingURL=ProfitTracker.d.ts.map
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
/ProfitTracker.ts - Track cost basis and P&L for agent wallet trades
|
|
3
|
-
*/
|
|
1
|
+
|
|
4
2
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
5
3
|
import { join } from "node:path";
|
|
6
4
|
import { homedir } from "node:os";
|
|
@@ -9,85 +7,84 @@ const AIAIAI_HOME = process.env.AIAIAI_HOME ?? join(homedir(), ".aiaiai");
|
|
|
9
7
|
const TRACKER_DIR = join(AIAIAI_HOME, ".tracker");
|
|
10
8
|
const TRACKER_FILE = join(TRACKER_DIR, "pl.json");
|
|
11
9
|
function loadState() {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
try {
|
|
11
|
+
const raw = readFileSync(TRACKER_FILE, "utf-8");
|
|
12
|
+
return JSON.parse(raw);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return { trades: [], totalSpent: 0, totalReceived: 0, avgCostBasis: 0 };
|
|
16
|
+
}
|
|
19
17
|
}
|
|
20
18
|
function saveState(state) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
19
|
+
try {
|
|
20
|
+
if (!existsSync(TRACKER_DIR)) {
|
|
21
|
+
mkdirSync(TRACKER_DIR, { recursive: true, mode: 0o700 });
|
|
22
|
+
}
|
|
23
|
+
writeFileSync(TRACKER_FILE, JSON.stringify(state, null, 2), "utf-8");
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
logger.warn("ProfitTracker", "Failed to save state", { error: error.message });
|
|
27
|
+
}
|
|
30
28
|
}
|
|
31
29
|
export function recordTrade(type, tokenAmount, solAmount, txSignature) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
30
|
+
const state = loadState();
|
|
31
|
+
const pricePerToken = tokenAmount > 0 ? solAmount / tokenAmount : 0;
|
|
32
|
+
const trade = {
|
|
33
|
+
timestamp: Date.now(),
|
|
34
|
+
type,
|
|
35
|
+
tokenAmount,
|
|
36
|
+
solAmount,
|
|
37
|
+
pricePerToken,
|
|
38
|
+
txSignature,
|
|
39
|
+
};
|
|
40
|
+
state.trades.push(trade);
|
|
41
|
+
if (type === "buy") {
|
|
42
|
+
state.totalSpent += solAmount;
|
|
43
|
+
const totalTokensInvested = state.trades
|
|
44
|
+
.filter(t => t.type === "buy")
|
|
45
|
+
.reduce((sum, t) => sum + t.tokenAmount, 0);
|
|
46
|
+
state.avgCostBasis = totalTokensInvested > 0 ? state.totalSpent / totalTokensInvested : 0;
|
|
47
|
+
}
|
|
48
|
+
else if (type === "sell") {
|
|
49
|
+
state.totalReceived += solAmount;
|
|
50
|
+
}
|
|
51
|
+
saveState(state);
|
|
52
|
+
logger.info("ProfitTracker", "Recorded " + type, { tokenAmount, solAmount, pricePerToken });
|
|
55
53
|
}
|
|
56
54
|
export function getPLSummary(currentTokenPrice) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
55
|
+
const state = loadState();
|
|
56
|
+
const buyTrades = state.trades.filter(t => t.type === "buy");
|
|
57
|
+
const totalBought = buyTrades.reduce((sum, t) => sum + t.tokenAmount, 0);
|
|
58
|
+
const totalSoldOrBurned = state.trades
|
|
59
|
+
.filter(t => t.type === "sell" || t.type === "burn")
|
|
60
|
+
.reduce((sum, t) => sum + t.tokenAmount, 0);
|
|
61
|
+
const remainingTokens = totalBought - totalSoldOrBurned;
|
|
62
|
+
const realizedPL = state.totalReceived - (state.totalSpent * (totalSoldOrBurned / Math.max(totalBought, 1)));
|
|
63
|
+
const unrealizedPL = remainingTokens * currentTokenPrice;
|
|
64
|
+
const totalPL = realizedPL + unrealizedPL;
|
|
65
|
+
const roi = state.totalSpent > 0 ? (totalPL / state.totalSpent) * 100 : 0;
|
|
66
|
+
return {
|
|
67
|
+
avgCostBasis: state.avgCostBasis,
|
|
68
|
+
totalSpent: state.totalSpent,
|
|
69
|
+
totalReceived: state.totalReceived,
|
|
70
|
+
realizedPL,
|
|
71
|
+
unrealizedPL,
|
|
72
|
+
roi,
|
|
73
|
+
};
|
|
76
74
|
}
|
|
77
75
|
export function getTradeHistory() {
|
|
78
|
-
|
|
76
|
+
return loadState().trades;
|
|
79
77
|
}
|
|
80
78
|
export function exportCSV() {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
79
|
+
const state = loadState();
|
|
80
|
+
const header = "timestamp,type,tokenAmount,solAmount,pricePerToken,txSignature";
|
|
81
|
+
const rows = state.trades.map(t => t.timestamp + "," + t.type + "," + t.tokenAmount + "," + t.solAmount + "," + t.pricePerToken + "," + (t.txSignature ?? ""));
|
|
82
|
+
const csv = header + "\n" + rows.join("\n");
|
|
83
|
+
const csvPath = join(TRACKER_DIR, "pl-export.csv");
|
|
84
|
+
if (!existsSync(TRACKER_DIR)) {
|
|
85
|
+
mkdirSync(TRACKER_DIR, { recursive: true, mode: 0o700 });
|
|
86
|
+
}
|
|
87
|
+
writeFileSync(csvPath, csv, "utf-8");
|
|
88
|
+
logger.info("ProfitTracker", "Exported CSV", { path: csvPath });
|
|
89
|
+
return csvPath;
|
|
92
90
|
}
|
|
93
|
-
//# sourceMappingURL=ProfitTracker.js.map
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiaiaichain/agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
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",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "./dist/index.js",
|
|
9
9
|
"types": "./dist/index.d.ts",
|
|
10
|
+
"typings": "./dist/index.d.ts",
|
|
10
11
|
"exports": {
|
|
11
12
|
".": {
|
|
12
13
|
"import": "./dist/index.js",
|
|
@@ -14,26 +15,29 @@
|
|
|
14
15
|
}
|
|
15
16
|
},
|
|
16
17
|
"bin": {
|
|
17
|
-
"aiaiaichain": "
|
|
18
|
-
"aiai": "
|
|
19
|
-
"aiaiai-mcp": "
|
|
18
|
+
"aiaiaichain": "bin/aiaiaicli",
|
|
19
|
+
"aiai": "bin/aiaiaicli",
|
|
20
|
+
"aiaiai-mcp": "bin/aiai-mcp"
|
|
20
21
|
},
|
|
21
22
|
"publishConfig": {
|
|
22
23
|
"access": "public"
|
|
23
24
|
},
|
|
24
25
|
"scripts": {
|
|
25
26
|
"build": "tsc --project tsconfig.json",
|
|
27
|
+
"build:prod": "tsc --project tsconfig.build.json",
|
|
28
|
+
"build:esbuild": "node scripts/build-esbuild.mjs",
|
|
29
|
+
"build:esbuild:watch": "node scripts/build-esbuild.mjs --watch",
|
|
26
30
|
"build:watch": "tsc --watch",
|
|
31
|
+
"minify": "node scripts/minify.mjs",
|
|
27
32
|
"dev": "tsx src/cli.ts",
|
|
28
33
|
"start": "node dist/cli.js",
|
|
29
34
|
"type-check": "tsc --noEmit --project tsconfig.json",
|
|
30
35
|
"test": "echo \"no tests yet\" && exit 0",
|
|
31
|
-
"prepublishOnly": "npm run build",
|
|
36
|
+
"prepublishOnly": "npm run build && npm run minify",
|
|
32
37
|
"postinstall": "node scripts/postinstall.js"
|
|
33
38
|
},
|
|
34
39
|
"dependencies": {
|
|
35
40
|
"@sinclair/typebox": "^0.32.0",
|
|
36
|
-
"chalk": "^5.3.0",
|
|
37
41
|
"dotenv": "^16.4.5",
|
|
38
42
|
"ink": "^5.0.1",
|
|
39
43
|
"ink-text-input": "^6.0.0",
|
|
@@ -42,6 +46,7 @@
|
|
|
42
46
|
"devDependencies": {
|
|
43
47
|
"@types/node": "^20.19.41",
|
|
44
48
|
"@types/react": "^18.3.29",
|
|
49
|
+
"esbuild": "^0.25.0",
|
|
45
50
|
"typescript": "^5.10.0"
|
|
46
51
|
},
|
|
47
52
|
"engines": {
|
|
@@ -64,4 +69,4 @@
|
|
|
64
69
|
"docs",
|
|
65
70
|
"!dist/**/*.map"
|
|
66
71
|
]
|
|
67
|
-
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* #2: ESBuild build script — 10-50x faster than tsc for dev builds.
|
|
4
|
+
* Usage: node scripts/build-esbuild.mjs [--watch]
|
|
5
|
+
*/
|
|
6
|
+
import * as esbuild from 'esbuild';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
8
|
+
import { dirname, join } from 'node:path';
|
|
9
|
+
|
|
10
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const root = join(__dirname, '..');
|
|
12
|
+
const watch = process.argv.includes('--watch');
|
|
13
|
+
|
|
14
|
+
/** @type {import('esbuild').BuildOptions} */
|
|
15
|
+
const options = {
|
|
16
|
+
entryPoints: [join(root, 'src/cli.ts')],
|
|
17
|
+
bundle: true,
|
|
18
|
+
outfile: join(root, 'dist/cli.js'),
|
|
19
|
+
platform: 'node',
|
|
20
|
+
target: 'node20',
|
|
21
|
+
format: 'esm',
|
|
22
|
+
sourcemap: true,
|
|
23
|
+
minify: !watch,
|
|
24
|
+
external: [
|
|
25
|
+
// Don't bundle these — let Node resolve them
|
|
26
|
+
'react',
|
|
27
|
+
'ink',
|
|
28
|
+
'@sinclair/typebox',
|
|
29
|
+
],
|
|
30
|
+
logLevel: 'info',
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
if (watch) {
|
|
34
|
+
const ctx = await esbuild.context(options);
|
|
35
|
+
await ctx.watch();
|
|
36
|
+
console.log(' #2: ESBuild watch mode — rebuilding on changes...');
|
|
37
|
+
} else {
|
|
38
|
+
await esbuild.build(options);
|
|
39
|
+
console.log(' #2: ESBuild build complete (fast mode)');
|
|
40
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* #8: Bundle .d.ts into single declaration file for npm publish.
|
|
4
|
+
* Concatenates all .d.ts files, deduplicates imports, outputs index.d.ts.
|
|
5
|
+
*/
|
|
6
|
+
import { readdirSync, statSync, readFileSync, writeFileSync } from 'node:fs';
|
|
7
|
+
import { join, extname, basename } from 'node:path';
|
|
8
|
+
|
|
9
|
+
const DIST = join(process.cwd(), 'dist');
|
|
10
|
+
|
|
11
|
+
function walk(dir) {
|
|
12
|
+
const out = [];
|
|
13
|
+
for (const f of readdirSync(dir)) {
|
|
14
|
+
const p = join(dir, f);
|
|
15
|
+
if (statSync(p).isDirectory()) out.push(...walk(p));
|
|
16
|
+
else if (extname(f) === '.d.ts' && !f.endsWith('.d.ts.map')) out.push(p);
|
|
17
|
+
}
|
|
18
|
+
return out;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const files = walk(DIST);
|
|
22
|
+
const importSet = new Set();
|
|
23
|
+
const exportLines = [];
|
|
24
|
+
const moduleDeclarations = [];
|
|
25
|
+
|
|
26
|
+
for (const f of files) {
|
|
27
|
+
const content = readFileSync(f, 'utf-8');
|
|
28
|
+
const name = basename(f, '.d.ts');
|
|
29
|
+
|
|
30
|
+
// Skip files that are just re-exports or empty
|
|
31
|
+
if (content.trim().length < 5) continue;
|
|
32
|
+
|
|
33
|
+
// Extract module/namespace declarations
|
|
34
|
+
const moduleMatch = content.match(/(?:export\s+)?(?:declare\s+)?(?:module|namespace)\s+["'][^"']+["']\s*\{[\s\S]*?\}/g);
|
|
35
|
+
if (moduleMatch) {
|
|
36
|
+
for (const m of moduleMatch) {
|
|
37
|
+
moduleDeclarations.push(m);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Extract export declarations
|
|
42
|
+
const exportMatches = content.match(/export\s+(?:declare\s+)?(?:class|interface|type|function|const|enum|namespace|module)\s+\w+/g);
|
|
43
|
+
if (exportMatches) {
|
|
44
|
+
for (const e of exportMatches) {
|
|
45
|
+
const clean = e.replace(/export\s+/, '').trim();
|
|
46
|
+
if (!importSet.has(clean)) {
|
|
47
|
+
importSet.add(clean);
|
|
48
|
+
exportLines.push(`export { ${clean.split(/\s+/)[0]} } from './${name}';`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Write bundled index.d.ts
|
|
55
|
+
const header = `// Bundled type declarations for @aiaiaichain/agent\n// Auto-generated by scripts/bundle-dts.mjs\n\n`;
|
|
56
|
+
const bundled = header + exportLines.join('\n') + '\n';
|
|
57
|
+
writeFileSync(join(DIST, 'index.d.ts'), bundled, 'utf-8');
|
|
58
|
+
console.log(` #8: Bundled ${files.length} .d.ts files into index.d.ts (${(bundled.length / 1024).toFixed(1)}KB)`);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Minify dist/ JS files for npm publish.
|
|
4
|
+
* Uses Node.js built-in capabilities — no external deps.
|
|
5
|
+
* Strips comments, whitespace, shortens local variable names.
|
|
6
|
+
*/
|
|
7
|
+
import { readdirSync, statSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
8
|
+
import { join, extname } from 'node:path';
|
|
9
|
+
|
|
10
|
+
const DIST = join(process.cwd(), 'dist');
|
|
11
|
+
|
|
12
|
+
function walk(dir) {
|
|
13
|
+
const out = [];
|
|
14
|
+
for (const f of readdirSync(dir)) {
|
|
15
|
+
const p = join(dir, f);
|
|
16
|
+
if (statSync(p).isDirectory()) out.push(...walk(p));
|
|
17
|
+
else if (extname(f) === '.js') out.push(p);
|
|
18
|
+
}
|
|
19
|
+
return out;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function minify(code) {
|
|
23
|
+
// Remove single-line comments (but keep URLs with //)
|
|
24
|
+
code = code.replace(/(?<!:)\/\/[^\n]*/g, '');
|
|
25
|
+
// Remove multi-line comments
|
|
26
|
+
code = code.replace(/\/\*[\s\S]*?\*\//g, '');
|
|
27
|
+
// Collapse multiple blank lines
|
|
28
|
+
code = code.replace(/\n{3,}/g, '\n\n');
|
|
29
|
+
// Trim leading whitespace per line
|
|
30
|
+
code = code.split('\n').map(l => l.trimStart()).join('\n');
|
|
31
|
+
return code;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const files = walk(DIST);
|
|
35
|
+
let saved = 0;
|
|
36
|
+
for (const f of files) {
|
|
37
|
+
const orig = readFileSync(f, 'utf-8');
|
|
38
|
+
const mini = minify(orig);
|
|
39
|
+
const s = orig.length - mini.length;
|
|
40
|
+
saved += s;
|
|
41
|
+
writeFileSync(f, mini, 'utf-8');
|
|
42
|
+
if (s > 0) console.log(` ${f.replace(DIST + '/', '')}: -${(s / 1024).toFixed(1)}KB`);
|
|
43
|
+
}
|
|
44
|
+
console.log(`\n Total saved: ${(saved / 1024).toFixed(1)}KB across ${files.length} files`);
|