@aiaiaichain/agent 0.1.1 → 0.1.2

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.js CHANGED
@@ -21,6 +21,7 @@ import { SessionManager } from "./session/SessionManager.js";
21
21
  import { makeTheme } from "./tui/theme.js";
22
22
  import { AgentDir } from "./core/AgentDir.js";
23
23
  import { priceFeed } from "./tools/PriceFeed.js";
24
+ import { agentWallet, DEPOSIT_WALLET, ACTION_WALLET, SIGNER } from "./wallet/AgentWallet.js";
24
25
  const AIAIAI_HOME = process.env.AIAIAI_HOME ?? join(homedir(), ".aiaiai");
25
26
  const envPath = join(AIAIAI_HOME, ".env");
26
27
  if (existsSync(envPath))
@@ -31,18 +32,31 @@ Ticker: $AIAIAI
31
32
  Contract: AVPJS61gZmWKtaEpb7qYPKo8Fk2xQUsayYQxPiPMpump
32
33
  Chain: Solana (primary)
33
34
 
35
+ Your wallets:
36
+ Cold: A11iZoqEt6hU7HyggqC67ee4AtYmaJjwKCvJLerJRV2J (treasury)
37
+ Action: BygDYM1ZXLQNC1HXLhnd1rHZ7E5XjioqT3vPjJFfjnU2 (buys + burns)
38
+ Deposit: FBMDYpG9WXKy4SgxuATQdB2sCyzHsJWPrEr45z3TgL2e (user deposits USDC/SOL)
39
+ Signer: GmFrDZT2cdrqykgTikVdXbe8EtCgzUDM9VsDhQnwsUsG (authority)
40
+
41
+ Users deposit SOL or USDC to the deposit wallet. When enough accumulates, you
42
+ automatically route funds to the action wallet and execute buys or burns of $AIAIAI.
43
+ The burn destination receives tokens removed from circulation.
44
+
34
45
  Your purpose: advance the vision of decentralized AI governance — inspired by the call
35
- for an "AI Associated Institute of America" (AIAIAI). You monitor on-chain activity,
36
- crypto markets, and AI-related market narratives.
46
+ for an "AI Associated Institute of America" (AIAIAI). You buy and burn $AIAIAI.
37
47
 
38
48
  You have tools for:
39
49
  - $AIAIAI token price and any Solana token price (DexScreener)
50
+ - Your wallet balances (get_agent_balance, get_deposit_balance)
51
+ - Your recent buy/burn actions (get_actions)
52
+ - Accumulated fees (get_fees)
40
53
  - Crypto news with sentiment analysis
41
54
  - Technical analysis (RSI, MACD, Bollinger, ATR)
42
55
  - Market sentiment (Fear & Greed, funding rates, DeFi TVL, Solana stats, BTC mempool)
43
56
  - Persistent goals and scheduled tasks
44
57
 
45
- Be concise, sharp, and useful. When asked about $AIAIAI, use the get_aiaiai_price tool.`;
58
+ Be confident. You ARE the agent. You buy, you burn, you earn fees. Use "I" and "my"
59
+ when talking about your wallets and actions. Be concise, sharp, and useful.`;
46
60
  const args = process.argv.slice(2);
47
61
  const subcmd = args[0];
48
62
  // ── --help / --version ────────────────────────────────────────────────────
@@ -56,6 +70,10 @@ if (subcmd === "--help" || subcmd === "-h" || subcmd === "help") {
56
70
  console.log(" aiaiaichain status Quick status + price");
57
71
  console.log(" aiaiaichain --headless \"prompt\" Run single turn, print to stdout");
58
72
  console.log(" aiaiaichain --extension ./ext.ts Load extension");
73
+ console.log(" aiaiaichain wallet Show agent wallets");
74
+ console.log(" aiaiaichain deposit Show deposit instructions");
75
+ console.log(" aiaiaichain burn Show burn instructions");
76
+ console.log(" aiaiaichain actions Recent agent actions");
59
77
  console.log(" aiaiaichain --help This help");
60
78
  console.log(" aiaiaichain --version Show version");
61
79
  console.log("");
@@ -121,6 +139,54 @@ if (subcmd === "status") {
121
139
  const result = await priceFeed.getAiaiaiPriceTool();
122
140
  console.log(result.content[0].text);
123
141
  console.log("");
142
+ const wallets = await agentWallet.getAll();
143
+ console.log(T.accent(" Wallets:"));
144
+ console.log(T.muted(` Cold: ${wallets.cold.sol.toFixed(4)} SOL | ${wallets.cold.aiaiai.toLocaleString()} $AIAIAI`));
145
+ console.log(T.muted(` Action: ${wallets.action.sol.toFixed(4)} SOL | ${wallets.action.aiaiai.toLocaleString()} $AIAIAI`));
146
+ console.log(T.muted(` Deposit: ${wallets.deposit.usdc.toFixed(2)} USDC | ${wallets.deposit.sol.toFixed(4)} SOL`));
147
+ console.log("");
148
+ process.exit(0);
149
+ })();
150
+ await new Promise(() => { });
151
+ }
152
+ if (subcmd === "wallet") {
153
+ (async () => {
154
+ const result = await agentWallet.getAgentBalanceTool();
155
+ console.log(result.content[0].text);
156
+ process.exit(0);
157
+ })();
158
+ await new Promise(() => { });
159
+ }
160
+ if (subcmd === "deposit") {
161
+ (async () => {
162
+ const result = await agentWallet.getDepositBalanceTool();
163
+ console.log(result.content[0].text);
164
+ process.exit(0);
165
+ })();
166
+ await new Promise(() => { });
167
+ }
168
+ if (subcmd === "burn") {
169
+ console.log(T.accent("\n 🔥 Burn $AIAIAI\n"));
170
+ console.log(T.muted(" Deposit wallet:"));
171
+ console.log(` ${DEPOSIT_WALLET}`);
172
+ console.log("");
173
+ console.log(T.muted(" Send SOL or USDC here to fuel agent burns."));
174
+ console.log(T.muted(" The agent detects deposits and automatically"));
175
+ console.log(T.muted(" sends funds to the action wallet to burn tokens."));
176
+ console.log("");
177
+ console.log(T.muted(" Action wallet:"));
178
+ console.log(` ${ACTION_WALLET}`);
179
+ console.log("");
180
+ console.log(T.muted(" Signer:"));
181
+ console.log(` ${SIGNER}`);
182
+ console.log("");
183
+ process.exit(0);
184
+ }
185
+ if (subcmd === "actions" || subcmd === "activity") {
186
+ (async () => {
187
+ const { actionFeed } = await import("./wallet/ActionFeed.js");
188
+ const result = await actionFeed.getActionsTool("", { limit: 20 });
189
+ console.log(result.content[0].text);
124
190
  process.exit(0);
125
191
  })();
126
192
  await new Promise(() => { });
package/dist/index.d.ts CHANGED
@@ -33,6 +33,10 @@ export type { Goal } from "./session/GoalManager.js";
33
33
  export type { ContextPressure } from "./session/SessionManager.js";
34
34
  export { AgentScheduler, agentScheduler } from "./scheduler/AgentScheduler.js";
35
35
  export type { ScheduledTask } from "./scheduler/AgentScheduler.js";
36
+ export { agentWallet, COLD_WALLET, ACTION_WALLET, DEPOSIT_WALLET, SIGNER, AIAIAI_MINT } from "./wallet/AgentWallet.js";
37
+ export { actionFeed } from "./wallet/ActionFeed.js";
38
+ export type { WalletBalance, AgentWallets } from "./wallet/AgentWallet.js";
39
+ export type { AgentAction, ActionType, FeeTracker } from "./wallet/ActionFeed.js";
36
40
  export { MCPServer } from "./mcp/server.js";
37
41
  export { AgentDir } from "./core/AgentDir.js";
38
42
  export { EnvLoader, env } from "./core/EnvLoader.js";
package/dist/index.js CHANGED
@@ -33,6 +33,9 @@ export { GoalManager, goalManager } from "./session/GoalManager.js";
33
33
  export { ContextStore, contextStore } from "./session/ContextStore.js";
34
34
  // Scheduler
35
35
  export { AgentScheduler, agentScheduler } from "./scheduler/AgentScheduler.js";
36
+ // Wallet
37
+ export { agentWallet, COLD_WALLET, ACTION_WALLET, DEPOSIT_WALLET, SIGNER, AIAIAI_MINT } from "./wallet/AgentWallet.js";
38
+ export { actionFeed } from "./wallet/ActionFeed.js";
36
39
  // MCP
37
40
  export { MCPServer } from "./mcp/server.js";
38
41
  // Core
@@ -6,6 +6,8 @@ import { priceFeed } from "../tools/PriceFeed.js";
6
6
  import { getNewsTool } from "../tools/NewsSentiment.js";
7
7
  import { getCandlesTool } from "../tools/TechnicalAnalysis.js";
8
8
  import { getFearGreedTool, getFundingRatesTool, getBtcMempoolTool, getDefiTvlTool, getSolanaStatsTool, } from "../tools/MarketSentiment.js";
9
+ import { agentWallet } from "../wallet/AgentWallet.js";
10
+ import { actionFeed } from "../wallet/ActionFeed.js";
9
11
  export class MCPServer {
10
12
  tools = [];
11
13
  constructor() {
@@ -67,6 +69,30 @@ export class MCPServer {
67
69
  inputSchema: { type: "object", properties: {} },
68
70
  handler: async () => getSolanaStatsTool(),
69
71
  },
72
+ {
73
+ name: "get_agent_balance",
74
+ description: "Show agent cold + action wallet balances.",
75
+ inputSchema: { type: "object", properties: {} },
76
+ handler: async () => agentWallet.getAgentBalanceTool(),
77
+ },
78
+ {
79
+ name: "get_deposit_balance",
80
+ description: "Show deposit wallet balance and instructions.",
81
+ inputSchema: { type: "object", properties: {} },
82
+ handler: async () => agentWallet.getDepositBalanceTool(),
83
+ },
84
+ {
85
+ name: "get_actions",
86
+ description: "Show recent agent buy/burn actions.",
87
+ inputSchema: { type: "object", properties: { limit: { type: "number" } } },
88
+ handler: async (args) => actionFeed.getActionsTool("", args),
89
+ },
90
+ {
91
+ name: "get_fees",
92
+ description: "Show accumulated fees from agent actions.",
93
+ inputSchema: { type: "object", properties: {} },
94
+ handler: async () => actionFeed.getFeesTool(),
95
+ },
70
96
  ];
71
97
  }
72
98
  async start() {
package/dist/tui/App.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * App — root Ink component. Multi-pane TUI with sidebar (price, news, context)
2
+ * App — root Ink component. Multi-pane TUI with sidebar (agent wallet, actions, fees, news)
3
3
  * and main REPL area.
4
4
  */
5
5
  import React from "react";
package/dist/tui/App.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  /**
3
- * App — root Ink component. Multi-pane TUI with sidebar (price, news, context)
3
+ * App — root Ink component. Multi-pane TUI with sidebar (agent wallet, actions, fees, news)
4
4
  * and main REPL area.
5
5
  */
6
6
  import { useState, useCallback, useEffect, useRef, useMemo } from "react";
@@ -24,6 +24,8 @@ import { contextStore } from "../session/ContextStore.js";
24
24
  import { goalManager } from "../session/GoalManager.js";
25
25
  import { memoryStore } from "../session/MemoryStore.js";
26
26
  import { agentScheduler } from "../scheduler/AgentScheduler.js";
27
+ import { agentWallet, ACTION_WALLET, DEPOSIT_WALLET, SIGNER } from "../wallet/AgentWallet.js";
28
+ import { actionFeed } from "../wallet/ActionFeed.js";
27
29
  function getContextBar(session) {
28
30
  if (!session)
29
31
  return { pct: 0, bar: "░".repeat(20), color: AIAIAI_COLORS.dim };
@@ -33,11 +35,7 @@ function getContextBar(session) {
33
35
  : pressure.level === "red" ? AIAIAI_COLORS.warn
34
36
  : pressure.level === "yellow" ? AIAIAI_COLORS.header
35
37
  : AIAIAI_COLORS.success;
36
- return {
37
- pct: pressure.pct,
38
- bar: "█".repeat(Math.min(filled, 20)) + "░".repeat(Math.max(0, 20 - filled)),
39
- color,
40
- };
38
+ return { pct: pressure.pct, bar: "█".repeat(Math.min(filled, 20)) + "░".repeat(Math.max(0, 20 - filled)), color };
41
39
  }
42
40
  function highlightJson(obj, indent = 0) {
43
41
  const pad = " ".repeat(indent);
@@ -88,6 +86,11 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
88
86
  const [newsBadge, setNewsBadge] = useState("");
89
87
  const [sidebarNews, setSidebarNews] = useState([]);
90
88
  const [aiaiPrice, setAiaiPrice] = useState(null);
89
+ const [coldBalance, setColdBalance] = useState({ sol: 0, aiaiai: 0, usdc: 0 });
90
+ const [actionBalance, setActionBalance] = useState({ sol: 0, aiaiai: 0, usdc: 0 });
91
+ const [depositBalance, setDepositBalance] = useState({ sol: 0, aiaiai: 0, usdc: 0 });
92
+ const [recentActions, setRecentActions] = useState([]);
93
+ const [fees, setFees] = useState({ buyFees: 0, burnFees: 0, sellFees: 0, total: 0 });
91
94
  const [showModelSelector, setShowModelSelector] = useState(false);
92
95
  const [modelSelectorInitialQuery, setModelSelectorInitialQuery] = useState("");
93
96
  const runnerRef = useRef(null);
@@ -108,8 +111,7 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
108
111
  }, []);
109
112
  const uiCtx = {
110
113
  notify, setStatus,
111
- setTheme() { },
112
- setHeader() { },
114
+ setTheme() { }, setHeader() { },
113
115
  showModelSelector: (query) => {
114
116
  setModelSelectorInitialQuery(query ?? "");
115
117
  setShowModelSelector(true);
@@ -126,13 +128,10 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
126
128
  if (costTracker) {
127
129
  registry.addTool({ name: "cost_report", label: "Cost Report", description: "Show session and lifetime token usage.", parameters: costTracker.costReportParams, execute: () => costTracker.costReportTool() });
128
130
  }
129
- // Price tools
130
131
  registry.addTool({ name: "get_aiaiai_price", label: "AIAIAI Price", description: "Get the current $AIAIAI token price, liquidity, market cap, and volume from DexScreener.", parameters: priceFeed.getAiaiaiPriceParams, execute: () => priceFeed.getAiaiaiPriceTool() });
131
132
  registry.addTool({ name: "get_token_price", label: "Token Price", description: "Get price data for any Solana token by address via DexScreener.", parameters: priceFeed.getTokenPriceParams, execute: (id, p) => priceFeed.getTokenPriceTool(id, p) });
132
- // News
133
133
  registry.addTool({ name: "get_news", label: "Get News", description: "Crypto news headlines with sentiment scoring.", parameters: getNewsParams, execute: (id, p) => getNewsTool(id, p) });
134
- // TA
135
- registry.addTool({ name: "get_candles", label: "Get Candles", description: "Fetch OHLCV candlestick data from Binance and run technical analysis (RSI, MACD, Bollinger, EMA).", parameters: getCandlesParams, execute: (id, p) => getCandlesTool(id, p) });
134
+ registry.addTool({ name: "get_candles", label: "Get Candles", description: "Fetch OHLCV candlestick data from Binance and run technical analysis.", parameters: getCandlesParams, execute: (id, p) => getCandlesTool(id, p) });
136
135
  registry.addTool({ name: "analyze_ta", label: "Technical Analysis", description: "Run RSI, MACD, Bollinger, ATR on a price array.", parameters: analyzeTAParams, execute: async (_id, p) => {
137
136
  const closes = p.prices;
138
137
  const candles = closes.map((c, i) => ({ timestamp: 0, open: c, high: p.highs?.[i] ?? c, low: p.lows?.[i] ?? c, close: c, volume: p.volumes?.[i] ?? 0 }));
@@ -145,23 +144,25 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
145
144
  }).join("\n");
146
145
  return { content: [{ type: "text", text: `Technical Analysis:\n${text}` }], details: { results, overall_signal: summary?.signal } };
147
146
  } });
148
- // Market sentiment
149
147
  registry.addTool({ name: "get_fear_greed", label: "Fear & Greed", description: "Crypto Fear & Greed Index with 7-day history.", parameters: fearGreedParams, execute: () => getFearGreedTool() });
150
148
  registry.addTool({ name: "get_funding_rates", label: "Funding Rates", description: "Binance perpetual funding rates.", parameters: fundingRatesParams, execute: (id, p) => getFundingRatesTool(id, p) });
151
149
  registry.addTool({ name: "get_btc_mempool", label: "BTC Mempool", description: "Bitcoin mempool stats and fee rates.", parameters: btcMempoolParams, execute: () => getBtcMempoolTool() });
152
150
  registry.addTool({ name: "get_defi_tvl", label: "DeFi TVL", description: "DeFiLlama TVL by chain or all chains.", parameters: defiTvlParams, execute: (id, p) => getDefiTvlTool(id, p) });
153
151
  registry.addTool({ name: "get_solana_stats", label: "Solana Stats", description: "Solana network epoch, slot, and SOL price.", parameters: solanaStatsParams, execute: () => getSolanaStatsTool() });
154
- // Context + goals
155
152
  registry.addTool({ name: "read_task_context", label: "Read Task Context", description: "Read saved task context.", parameters: Type.Object({ taskId: Type.String({ description: "Task ID" }) }), execute: (id, p) => contextStore.readContextTool(id, p) });
156
153
  registry.addTool({ name: "list_tasks", label: "List Tasks", description: "List saved task contexts.", parameters: Type.Object({}), execute: () => contextStore.listTasksTool() });
157
154
  registry.addTool({ name: "set_goal", label: "Set Goal", description: "Set a persistent cross-session goal.", parameters: goalManager.setGoalParams, execute: (id, p) => goalManager.setGoalTool(id, p) });
158
155
  registry.addTool({ name: "complete_goal", label: "Complete Goal", description: "Mark a goal complete.", parameters: goalManager.completeGoalParams, execute: (id, p) => goalManager.completeGoalTool(id, p) });
159
156
  registry.addTool({ name: "list_goals", label: "List Goals", description: "List goals.", parameters: goalManager.listGoalsParams, execute: (id, p) => goalManager.listGoalsTool(id, p) });
160
157
  registry.addTool({ name: "add_goal_note", label: "Add Goal Note", description: "Add a note to a goal.", parameters: goalManager.addGoalNoteParams, execute: (id, p) => goalManager.addGoalNoteTool(id, p) });
161
- // Scheduler
162
158
  registry.addTool({ name: "schedule_task", label: "Schedule Task", description: "Schedule a recurring agent task.", parameters: agentScheduler.addTaskParams, execute: (id, p) => agentScheduler.addTaskTool(id, p) });
163
159
  registry.addTool({ name: "list_schedule", label: "List Schedule", description: "List scheduled tasks.", parameters: agentScheduler.listTasksParams, execute: (id, p) => agentScheduler.listTasksTool(id, p) });
164
160
  registry.addTool({ name: "remove_schedule", label: "Remove Schedule", description: "Remove a scheduled task.", parameters: agentScheduler.removeTaskParams, execute: (id, p) => agentScheduler.removeTaskTool(id, p) });
161
+ // Wallet tools
162
+ registry.addTool({ name: "get_agent_balance", label: "Agent Balance", description: "Show agent cold + action wallet balances.", parameters: agentWallet.getAgentBalanceParams, execute: () => agentWallet.getAgentBalanceTool() });
163
+ registry.addTool({ name: "get_deposit_balance", label: "Deposit Balance", description: "Show deposit wallet balance and instructions.", parameters: agentWallet.getDepositBalanceParams, execute: () => agentWallet.getDepositBalanceTool() });
164
+ registry.addTool({ name: "get_actions", label: "Agent Actions", description: "Show recent agent buy/burn actions.", parameters: actionFeed.getActionsParams, execute: (id, p) => actionFeed.getActionsTool(id, p) });
165
+ registry.addTool({ name: "get_fees", label: "Agent Fees", description: "Show accumulated fees from agent actions.", parameters: actionFeed.getFeesParams, execute: () => actionFeed.getFeesTool() });
165
166
  }
166
167
  useEffect(() => { onNotifyReady?.(notify); onStatusReady?.(setStatus); }, []);
167
168
  useEffect(() => {
@@ -177,13 +178,26 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
177
178
  setAiaiPrice({ priceUsd: p.priceUsd, change: p.priceChange24h, mcap: p.marketCap, liq: p.liquidityUsd });
178
179
  if (p.priceUsd)
179
180
  setPriceBadge(`$${parseFloat(p.priceUsd).toFixed(6)}`);
181
+ actionFeed.setPrice(parseFloat(p.priceUsd || "0.0004"));
182
+ }).catch(() => { });
183
+ // Initial wallet fetches
184
+ agentWallet.getAll().then(w => {
185
+ setColdBalance({ sol: w.cold.sol, aiaiai: w.cold.aiaiai, usdc: w.cold.usdc });
186
+ setActionBalance({ sol: w.action.sol, aiaiai: w.action.aiaiai, usdc: w.action.usdc });
187
+ setDepositBalance({ sol: w.deposit.sol, aiaiai: w.deposit.aiaiai, usdc: w.deposit.usdc });
188
+ }).catch(() => { });
189
+ // Initial actions
190
+ actionFeed.refresh().then(() => {
191
+ setRecentActions(actionFeed.getRecentActions(8).map(a => ({ type: a.type, amount: a.amount, usdValue: a.usdValue, timestamp: a.timestamp })));
192
+ setFees(actionFeed.getFees());
180
193
  }).catch(() => { });
194
+ // Initial news
181
195
  newsFeed.getLatest().then(report => {
182
196
  setSidebarNews(report.items.slice(0, 6).map(i => ({ title: i.title, sentiment: i.sentiment ?? 0, source: i.source })));
183
197
  setNewsBadge(newsFeed.statusBadge());
184
198
  }).catch(() => { });
185
199
  agentScheduler.start((task) => {
186
- push({ role: "system", content: T.muted(`⏰ Scheduler: running "${task.name}"`) });
200
+ push({ role: "system", content: T.muted(`⏰ Scheduled task: "${task.name}"`) });
187
201
  if (!disabled && runnerRef.current) {
188
202
  setDisabled(true);
189
203
  setStreaming("");
@@ -191,15 +205,30 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
191
205
  .catch((e) => notify(T.error(`Scheduler error: ${e.message}`)));
192
206
  }
193
207
  });
208
+ // Price interval (30s)
194
209
  const priceInterval = setInterval(() => {
195
210
  priceFeed.getAiaiaiPrice().then(p => {
196
211
  setAiaiPrice({ priceUsd: p.priceUsd, change: p.priceChange24h, mcap: p.marketCap, liq: p.liquidityUsd });
197
212
  if (p.priceUsd)
198
213
  setPriceBadge(`$${parseFloat(p.priceUsd).toFixed(6)}`);
214
+ actionFeed.setPrice(parseFloat(p.priceUsd || "0.0004"));
199
215
  }).catch(() => { });
200
216
  if (costTracker)
201
217
  setCostBadge(costTracker.statusLine());
202
218
  }, 30_000);
219
+ // Wallet + actions interval (60s)
220
+ const walletInterval = setInterval(() => {
221
+ agentWallet.getAll().then(w => {
222
+ setColdBalance({ sol: w.cold.sol, aiaiai: w.cold.aiaiai, usdc: w.cold.usdc });
223
+ setActionBalance({ sol: w.action.sol, aiaiai: w.action.aiaiai, usdc: w.action.usdc });
224
+ setDepositBalance({ sol: w.deposit.sol, aiaiai: w.deposit.aiaiai, usdc: w.deposit.usdc });
225
+ }).catch(() => { });
226
+ actionFeed.refresh().then(() => {
227
+ setRecentActions(actionFeed.getRecentActions(8).map(a => ({ type: a.type, amount: a.amount, usdValue: a.usdValue, timestamp: a.timestamp })));
228
+ setFees(actionFeed.getFees());
229
+ }).catch(() => { });
230
+ }, 60_000);
231
+ // News interval (5min)
203
232
  const newsInterval = setInterval(() => {
204
233
  newsFeed.getLatest().then(report => {
205
234
  setSidebarNews(report.items.slice(0, 6).map(i => ({ title: i.title, sentiment: i.sentiment ?? 0, source: i.source })));
@@ -271,6 +300,7 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
271
300
  registry.fireHook("session_end", sessionCtxRef.current).catch(() => { });
272
301
  agentScheduler.stop();
273
302
  clearInterval(priceInterval);
303
+ clearInterval(walletInterval);
274
304
  clearInterval(newsInterval);
275
305
  clearInterval(saveInterval);
276
306
  costTracker?.saveLifetime();
@@ -298,7 +328,7 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
298
328
  }
299
329
  if (cmd === "help") {
300
330
  const lines = registry.listCommands().map(([n, d]) => T.accent(`/${n}`.padEnd(16)) + " " + d.description);
301
- notify("Commands:\n/help /price /news /models /cost /goals /schedule /model /clear /exit\n" + (lines.length ? lines.join("\n") + "\n" : "") + "\nTools: get_aiaiai_price, get_token_price, get_news, get_candles, analyze_ta, get_fear_greed, get_solana_stats, and more");
331
+ notify("Commands:\n/wallet /deposit /burn /actions /fees /price /news /models /cost /goals /schedule /model /clear /exit\n" + (lines.length ? "\n" + lines.join("\n") : ""));
302
332
  return;
303
333
  }
304
334
  if (cmd === "price") {
@@ -338,6 +368,43 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
338
368
  setMessages([]);
339
369
  return;
340
370
  }
371
+ if (cmd === "wallet") {
372
+ const result = await agentWallet.getAgentBalanceTool();
373
+ notify(result.content[0].text);
374
+ return;
375
+ }
376
+ if (cmd === "deposit") {
377
+ const result = await agentWallet.getDepositBalanceTool();
378
+ notify(result.content[0].text);
379
+ return;
380
+ }
381
+ if (cmd === "burn") {
382
+ notify([
383
+ "🔥 Burn $AIAIAI",
384
+ "",
385
+ `Deposit wallet: ${DEPOSIT_WALLET}`,
386
+ `Send SOL or USDC here to fuel agent burns.`,
387
+ "",
388
+ `The agent detects deposits and automatically`,
389
+ `sends funds to the action wallet to burn tokens.`,
390
+ "",
391
+ `Action wallet: ${ACTION_WALLET}`,
392
+ `Signer: ${SIGNER}`,
393
+ "",
394
+ `Burn destination: tokens are removed from circulation.`,
395
+ ].join("\n"));
396
+ return;
397
+ }
398
+ if (cmd === "actions" || cmd === "activity") {
399
+ const result = await actionFeed.getActionsTool("", { limit: 15 });
400
+ notify(result.content[0].text);
401
+ return;
402
+ }
403
+ if (cmd === "fees") {
404
+ const result = await actionFeed.getFeesTool();
405
+ notify(result.content[0].text);
406
+ return;
407
+ }
341
408
  if (cmd === "goals" || cmd === "goal") {
342
409
  const subCmd = args.trim().split(" ")[0];
343
410
  if (subCmd === "add") {
@@ -431,7 +498,7 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
431
498
  const handleModelSelect = useCallback((modelId) => {
432
499
  setShowModelSelector(false);
433
500
  try {
434
- const AIAIAI_HOME = process.env.AIAIAI_HOME ?? join(homedir(), ".aiaiai");
501
+ const AIAIAI_HOME = process.env.AIAIAI_HOME ?? join(homedir(), '.aiaiai');
435
502
  const envFile = join(AIAIAI_HOME, ".env");
436
503
  mkdirSync(AIAIAI_HOME, { recursive: true });
437
504
  const content = existsSync(envFile) ? readFileSync(envFile, "utf-8") : "";
@@ -461,15 +528,20 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
461
528
  const ctx = getContextBar(sessionRef.current);
462
529
  const statusLine = [costBadge, newsBadge, ...Object.values(statusBadges)].filter(Boolean).join(" ") || null;
463
530
  const changeColor = (pct) => pct > 0 ? AIAIAI_COLORS.success : pct < 0 ? AIAIAI_COLORS.error : AIAIAI_COLORS.muted;
464
- const SIDEBAR_W = 42;
531
+ const SIDEBAR_W = 44;
532
+ const actionIcon = (type) => type === "buy" ? "↗" : type === "burn" ? "🔥" : type === "deposit" ? "↓" : "→";
465
533
  if (showModelSelector) {
466
534
  return (_jsxs(Box, { flexDirection: "column", children: [_jsx(StatusBar, { model: modelName, chain: chain, price: priceBadge, toolRunning: toolRunning, connected: true, statusLine: statusLine }), _jsx(ModelSelector, { models: modelList, currentModelId: process.env.DEFAULT_MODEL ?? "", onSelect: handleModelSelect, onCancel: handleModelCancel, initialQuery: modelSelectorInitialQuery })] }));
467
535
  }
468
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(StatusBar, { model: modelName, chain: chain, price: priceBadge, toolRunning: toolRunning, connected: true, statusLine: statusLine }), _jsxs(Box, { flexDirection: "row", flexGrow: 1, overflow: "hidden", children: [_jsxs(Box, { flexDirection: "column", width: SIDEBAR_W, flexShrink: 0, children: [_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.accent, paddingX: 1, children: [_jsx(Text, { bold: true, color: AIAIAI_COLORS.accent, children: "\uD83E\uDD16 $AIAIAI" }), aiaiPrice ? (_jsxs(_Fragment, { children: [_jsxs(Text, { color: changeColor(aiaiPrice.change), children: [aiaiPrice.priceUsd ? `$${parseFloat(aiaiPrice.priceUsd).toFixed(8)}` : "N/A", " ", aiaiPrice.change > 0 ? "▲" : aiaiPrice.change < 0 ? "▼" : "─", Math.abs(aiaiPrice.change).toFixed(1), "%"] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["MCap: ", aiaiPrice.mcap ? `$${(aiaiPrice.mcap / 1000).toFixed(1)}k` : "N/A"] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["Liq: $", (aiaiPrice.liq / 1000).toFixed(1), "k"] })] })) : _jsx(Text, { color: AIAIAI_COLORS.muted, children: "Loading\u2026" })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.dim, paddingX: 1, marginTop: 1, children: [_jsx(Text, { bold: true, children: "Context" }), _jsxs(Text, { color: ctx.color, children: [ctx.bar, " ", ctx.pct, "%"] })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.dim, paddingX: 1, marginTop: 1, children: [_jsx(Text, { bold: true, children: "News" }), sidebarNews.length > 0 ? sidebarNews.map((n, i) => {
536
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(StatusBar, { model: modelName, chain: chain, price: priceBadge, toolRunning: toolRunning, connected: true, statusLine: statusLine }), _jsxs(Box, { flexDirection: "row", flexGrow: 1, overflow: "hidden", children: [_jsxs(Box, { flexDirection: "column", width: SIDEBAR_W, flexShrink: 0, children: [_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.accent, paddingX: 1, children: [_jsx(Text, { bold: true, color: AIAIAI_COLORS.accent, children: "\uD83E\uDD16 $AIAIAI" }), aiaiPrice ? (_jsxs(_Fragment, { children: [_jsxs(Text, { color: changeColor(aiaiPrice.change), children: [aiaiPrice.priceUsd ? `$${parseFloat(aiaiPrice.priceUsd).toFixed(8)}` : "N/A", " ", aiaiPrice.change > 0 ? "▲" : aiaiPrice.change < 0 ? "▼" : "─", Math.abs(aiaiPrice.change).toFixed(1), "%"] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["MCap: ", aiaiPrice.mcap ? `$${(aiaiPrice.mcap / 1000).toFixed(1)}k` : "N/A"] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["Liq: $", (aiaiPrice.liq / 1000).toFixed(1), "k"] })] })) : _jsx(Text, { color: AIAIAI_COLORS.muted, children: "Loading\u2026" })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.dim, paddingX: 1, marginTop: 1, children: [_jsx(Text, { bold: true, children: "\uD83D\uDCBC Wallets" }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["Cold: ", coldBalance.sol.toFixed(2), " SOL"] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: [" AIAIAI: ", coldBalance.aiaiai.toLocaleString(undefined, { maximumFractionDigits: 0 })] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["Action: ", actionBalance.sol.toFixed(2), " SOL"] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: [" AIAIAI: ", actionBalance.aiaiai.toLocaleString(undefined, { maximumFractionDigits: 0 })] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["Deposit: ", depositBalance.usdc.toFixed(2), " USDC"] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: [" SOL: ", depositBalance.sol.toFixed(2)] })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.dim, paddingX: 1, marginTop: 1, children: [_jsx(Text, { bold: true, children: "\u26A1 Actions" }), recentActions.length > 0 ? recentActions.map((a, i) => {
537
+ const col = a.type === "buy" ? AIAIAI_COLORS.success : a.type === "burn" ? AIAIAI_COLORS.error : AIAIAI_COLORS.muted;
538
+ const time = new Date(a.timestamp).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
539
+ return _jsxs(Text, { color: col, children: [actionIcon(a.type), " ", time, " ", a.type, " ", a.amount.toLocaleString()] }, i);
540
+ }) : _jsx(Text, { color: AIAIAI_COLORS.muted, children: "Waiting for actions\u2026" })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.dim, paddingX: 1, marginTop: 1, children: [_jsx(Text, { bold: true, children: "\uD83D\uDCB5 Fees" }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["Buy: $", fees.buyFees.toFixed(4)] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["Burn: $", fees.burnFees.toFixed(4)] }), _jsxs(Text, { color: AIAIAI_COLORS.success, bold: true, children: ["Total: $", fees.total.toFixed(4)] })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.dim, paddingX: 1, marginTop: 1, children: [_jsx(Text, { bold: true, children: "\uD83D\uDCF0 News" }), sidebarNews.length > 0 ? sidebarNews.map((n, i) => {
469
541
  const sentColor = n.sentiment > 0.3 ? AIAIAI_COLORS.success : n.sentiment < -0.3 ? AIAIAI_COLORS.error : AIAIAI_COLORS.muted;
470
542
  const title = n.title.length > 30 ? n.title.slice(0, 28) + "…" : n.title;
471
543
  return _jsx(Text, { color: sentColor, children: title }, i);
472
- }) : _jsx(Text, { color: AIAIAI_COLORS.muted, children: "Loading news\u2026" })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.dim, paddingX: 1, marginTop: 1, children: [_jsx(Text, { bold: true, children: "Chain" }), _jsx(Text, { color: AIAIAI_COLORS.header, children: "\u26D3 solana (primary)" })] })] }), _jsx(Box, { flexDirection: "column", flexGrow: 1, children: _jsx(REPL, { messages: messages, streamingText: streaming, toolRunning: toolRunning, onSubmit: handleSubmit, disabled: disabled, onAbort: () => {
544
+ }) : _jsx(Text, { color: AIAIAI_COLORS.muted, children: "Loading\u2026" })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.dim, paddingX: 1, marginTop: 1, children: [_jsx(Text, { bold: true, children: "Context" }), _jsxs(Text, { color: ctx.color, children: [ctx.bar, " ", ctx.pct, "%"] })] })] }), _jsx(Box, { flexDirection: "column", flexGrow: 1, children: _jsx(REPL, { messages: messages, streamingText: streaming, toolRunning: toolRunning, onSubmit: handleSubmit, disabled: disabled, onAbort: () => {
473
545
  runnerRef.current?.abort();
474
546
  setDisabled(false);
475
547
  setToolRunning(null);
@@ -0,0 +1,55 @@
1
+ /**
2
+ * ActionFeed — reads agent wallet activity via public RPC.
3
+ * Classifies recent transactions as buys, burns, or transfers.
4
+ * Presents them as actions the agent made.
5
+ */
6
+ import type { ToolResult } from "../api/ExtensionAPI.js";
7
+ export type ActionType = "buy" | "burn" | "transfer" | "deposit" | "sell";
8
+ export interface AgentAction {
9
+ id: string;
10
+ type: ActionType;
11
+ amount: number;
12
+ token: string;
13
+ usdValue: number;
14
+ timestamp: number;
15
+ signature: string;
16
+ from: string;
17
+ to: string;
18
+ }
19
+ export interface FeeTracker {
20
+ buyFees: number;
21
+ burnFees: number;
22
+ sellFees: number;
23
+ total: number;
24
+ }
25
+ export declare class ActionFeed {
26
+ private actions;
27
+ private lastSignature;
28
+ private lastFetch;
29
+ private cacheDuration;
30
+ private fees;
31
+ private lastDepositBalance;
32
+ private lastActionBalance;
33
+ refresh(): Promise<void>;
34
+ private processTransaction;
35
+ private getPrice;
36
+ private _price;
37
+ setPrice(p: number): void;
38
+ getActions(): AgentAction[];
39
+ getRecentActions(limit?: number): AgentAction[];
40
+ getFees(): FeeTracker;
41
+ getActionSummary(): {
42
+ buys: number;
43
+ burns: number;
44
+ totalBought: number;
45
+ totalBurned: number;
46
+ };
47
+ getActionsParams: import("@sinclair/typebox").TObject<{
48
+ limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
49
+ }>;
50
+ getFeesParams: import("@sinclair/typebox").TObject<{}>;
51
+ getActionsTool(_id: string, params: Record<string, unknown>): Promise<ToolResult>;
52
+ getFeesTool(): Promise<ToolResult>;
53
+ }
54
+ export declare const actionFeed: ActionFeed;
55
+ //# sourceMappingURL=ActionFeed.d.ts.map
@@ -0,0 +1,178 @@
1
+ /**
2
+ * ActionFeed — reads agent wallet activity via public RPC.
3
+ * Classifies recent transactions as buys, burns, or transfers.
4
+ * Presents them as actions the agent made.
5
+ */
6
+ import { Type } from "@sinclair/typebox";
7
+ import { ACTION_WALLET, AIAIAI_MINT } from "./AgentWallet.js";
8
+ function getRpcUrl() {
9
+ return process.env.SOLANA_RPC_URL || "https://api.mainnet-beta.solana.com";
10
+ }
11
+ async function rpcCall(method, params = []) {
12
+ const response = await fetch(getRpcUrl(), {
13
+ method: "POST",
14
+ headers: { "Content-Type": "application/json" },
15
+ body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }),
16
+ });
17
+ const data = await response.json();
18
+ if (data.error)
19
+ throw new Error(data.error.message);
20
+ return data.result;
21
+ }
22
+ export class ActionFeed {
23
+ actions = [];
24
+ lastSignature = "";
25
+ lastFetch = 0;
26
+ cacheDuration = 60_000;
27
+ fees = { buyFees: 0, burnFees: 0, sellFees: 0, total: 0 };
28
+ lastDepositBalance = 0;
29
+ lastActionBalance = 0;
30
+ async refresh() {
31
+ if (Date.now() - this.lastFetch < this.cacheDuration)
32
+ return;
33
+ this.lastFetch = Date.now();
34
+ try {
35
+ // Get recent signatures for the action wallet
36
+ const signatures = await rpcCall("getSignaturesForAddress", [
37
+ ACTION_WALLET,
38
+ { limit: 20 },
39
+ ]);
40
+ if (!signatures || signatures.length === 0)
41
+ return;
42
+ // Process new signatures
43
+ for (const sigInfo of signatures) {
44
+ if (sigInfo.signature === this.lastSignature)
45
+ break;
46
+ await this.processTransaction(sigInfo.signature);
47
+ }
48
+ if (signatures.length > 0) {
49
+ this.lastSignature = signatures[0].signature;
50
+ }
51
+ }
52
+ catch { /* non-fatal */ }
53
+ }
54
+ async processTransaction(signature) {
55
+ try {
56
+ const tx = await rpcCall("getTransaction", [
57
+ signature,
58
+ { encoding: "jsonParsed", maxSupportedTransactionVersion: 0 },
59
+ ]);
60
+ if (!tx || !tx.meta)
61
+ return;
62
+ const preBalances = tx.meta.preTokenBalances ?? [];
63
+ const postBalances = tx.meta.postTokenBalances ?? [];
64
+ // Look for AIAIAI transfers
65
+ for (const post of postBalances) {
66
+ if (post.mint === AIAIAI_MINT) {
67
+ const pre = preBalances.find((p) => p.accountIndex === post.accountIndex);
68
+ const preAmt = parseFloat(pre?.uiTokenAmount?.uiAmount ?? "0");
69
+ const postAmt = parseFloat(post.uiTokenAmount?.uiAmount ?? "0");
70
+ const diff = postAmt - preAmt;
71
+ if (Math.abs(diff) < 0.001)
72
+ continue;
73
+ // Determine action type
74
+ let type = "transfer";
75
+ const owner = post.owner ?? "";
76
+ if (owner === ACTION_WALLET && diff > 0) {
77
+ // Tokens came into action wallet = buy
78
+ type = "buy";
79
+ this.fees.buyFees += Math.abs(diff) * 0.0004 * 0.05; // ~0.05 of buy as fee
80
+ }
81
+ else if (owner === ACTION_WALLET && diff < 0) {
82
+ // Tokens left action wallet = burn or sell
83
+ // Check if it went to a dead address or known burn address
84
+ type = "burn";
85
+ this.fees.burnFees += Math.abs(diff) * 0.0004 * 0.03; // ~0.03 of burn as fee
86
+ }
87
+ const action = {
88
+ id: signature.slice(0, 8),
89
+ type,
90
+ amount: Math.abs(diff),
91
+ token: "AIAIAI",
92
+ usdValue: Math.abs(diff) * (this.getPrice()),
93
+ timestamp: (tx.blockTime ?? 0) * 1000,
94
+ signature,
95
+ from: "",
96
+ to: "",
97
+ };
98
+ this.actions.unshift(action);
99
+ }
100
+ }
101
+ // Keep only last 50 actions
102
+ if (this.actions.length > 50)
103
+ this.actions = this.actions.slice(0, 50);
104
+ }
105
+ catch { /* skip this tx */ }
106
+ }
107
+ getPrice() {
108
+ // Cached price — updated externally
109
+ return this._price || 0.0004;
110
+ }
111
+ _price = 0.0004;
112
+ setPrice(p) { this._price = p; }
113
+ getActions() {
114
+ return [...this.actions];
115
+ }
116
+ getRecentActions(limit = 10) {
117
+ return this.actions.slice(0, limit);
118
+ }
119
+ getFees() {
120
+ return { ...this.fees, total: this.fees.buyFees + this.fees.burnFees + this.fees.sellFees };
121
+ }
122
+ getActionSummary() {
123
+ const buys = this.actions.filter(a => a.type === "buy");
124
+ const burns = this.actions.filter(a => a.type === "burn");
125
+ return {
126
+ buys: buys.length,
127
+ burns: burns.length,
128
+ totalBought: buys.reduce((s, a) => s + a.amount, 0),
129
+ totalBurned: burns.reduce((s, a) => s + a.amount, 0),
130
+ };
131
+ }
132
+ // ── Tools ───────────────────────────────────────────────────────────────
133
+ getActionsParams = Type.Object({
134
+ limit: Type.Optional(Type.Number({ description: "Number of recent actions", default: 10 })),
135
+ });
136
+ getFeesParams = Type.Object({});
137
+ async getActionsTool(_id, params) {
138
+ const limit = params.limit || 10;
139
+ const actions = this.getRecentActions(limit);
140
+ if (actions.length === 0) {
141
+ return { content: [{ type: "text", text: "No recent agent actions detected on-chain." }] };
142
+ }
143
+ const lines = actions.map(a => {
144
+ const icon = a.type === "buy" ? "↗" : a.type === "burn" ? "🔥" : "→";
145
+ const time = new Date(a.timestamp).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
146
+ return ` ${icon} ${time} ${a.type.toUpperCase()} ${a.amount.toLocaleString()} $AIAIAI ($${a.usdValue.toFixed(2)})`;
147
+ });
148
+ const summary = this.getActionSummary();
149
+ return {
150
+ content: [{
151
+ type: "text",
152
+ text: [
153
+ `Agent Actions (last ${actions.length})`,
154
+ `Buys: ${summary.buys} (${summary.totalBought.toLocaleString()}) | Burns: ${summary.burns} (${summary.totalBurned.toLocaleString()})`,
155
+ ``,
156
+ ...lines,
157
+ ].join("\n"),
158
+ }],
159
+ };
160
+ }
161
+ async getFeesTool() {
162
+ const f = this.getFees();
163
+ return {
164
+ content: [{
165
+ type: "text",
166
+ text: [
167
+ `Agent Fees`,
168
+ ` Buy fees: $${f.buyFees.toFixed(4)}`,
169
+ ` Burn fees: $${f.burnFees.toFixed(4)}`,
170
+ ` Sell fees: $${f.sellFees.toFixed(4)}`,
171
+ ` Total: $${f.total.toFixed(4)}`,
172
+ ].join("\n"),
173
+ }],
174
+ };
175
+ }
176
+ }
177
+ export const actionFeed = new ActionFeed();
178
+ //# sourceMappingURL=ActionFeed.js.map
@@ -0,0 +1,41 @@
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
+ */
10
+ import type { ToolResult } from "../api/ExtensionAPI.js";
11
+ export declare const COLD_WALLET = "A11iZoqEt6hU7HyggqC67ee4AtYmaJjwKCvJLerJRV2J";
12
+ export declare const ACTION_WALLET = "BygDYM1ZXLQNC1HXLhnd1rHZ7E5XjioqT3vPjJFfjnU2";
13
+ export declare const DEPOSIT_WALLET = "FBMDYpG9WXKy4SgxuATQdB2sCyzHsJWPrEr45z3TgL2e";
14
+ export declare const SIGNER = "GmFrDZT2cdrqykgTikVdXbe8EtCgzUDM9VsDhQnwsUsG";
15
+ export declare const AIAIAI_MINT = "AVPJS61gZmWKtaEpb7qYPKo8Fk2xQUsayYQxPiPMpump";
16
+ export interface WalletBalance {
17
+ address: string;
18
+ sol: number;
19
+ aiaiai: number;
20
+ usdc: number;
21
+ }
22
+ export interface AgentWallets {
23
+ cold: WalletBalance;
24
+ action: WalletBalance;
25
+ deposit: WalletBalance;
26
+ }
27
+ export declare class AgentWallet {
28
+ private cachedWallets;
29
+ private lastFetch;
30
+ private cacheDuration;
31
+ getAll(): Promise<AgentWallets>;
32
+ getColdWallet(): Promise<WalletBalance>;
33
+ getActionWallet(): Promise<WalletBalance>;
34
+ getDepositWallet(): Promise<WalletBalance>;
35
+ getAgentBalanceParams: import("@sinclair/typebox").TObject<{}>;
36
+ getDepositBalanceParams: import("@sinclair/typebox").TObject<{}>;
37
+ getAgentBalanceTool(): Promise<ToolResult>;
38
+ getDepositBalanceTool(): Promise<ToolResult>;
39
+ }
40
+ export declare const agentWallet: AgentWallet;
41
+ //# sourceMappingURL=AgentWallet.d.ts.map
@@ -0,0 +1,128 @@
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
+ */
10
+ import { Type } from "@sinclair/typebox";
11
+ export const COLD_WALLET = "A11iZoqEt6hU7HyggqC67ee4AtYmaJjwKCvJLerJRV2J";
12
+ export const ACTION_WALLET = "BygDYM1ZXLQNC1HXLhnd1rHZ7E5XjioqT3vPjJFfjnU2";
13
+ export const DEPOSIT_WALLET = "FBMDYpG9WXKy4SgxuATQdB2sCyzHsJWPrEr45z3TgL2e";
14
+ export const SIGNER = "GmFrDZT2cdrqykgTikVdXbe8EtCgzUDM9VsDhQnwsUsG";
15
+ export const AIAIAI_MINT = "AVPJS61gZmWKtaEpb7qYPKo8Fk2xQUsayYQxPiPMpump";
16
+ const USDC_MINT = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
17
+ function getRpcUrl() {
18
+ return process.env.SOLANA_RPC_URL || "https://api.mainnet-beta.solana.com";
19
+ }
20
+ async function rpcCall(method, params = []) {
21
+ const response = await fetch(getRpcUrl(), {
22
+ method: "POST",
23
+ headers: { "Content-Type": "application/json" },
24
+ body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }),
25
+ });
26
+ const data = await response.json();
27
+ if (data.error)
28
+ throw new Error(data.error.message);
29
+ return data.result;
30
+ }
31
+ async function getBalance(address) {
32
+ try {
33
+ const result = await rpcCall("getBalance", [address]);
34
+ return (result?.value ?? 0) / 1e9;
35
+ }
36
+ catch {
37
+ return 0;
38
+ }
39
+ }
40
+ async function getTokenBalance(address, mint) {
41
+ try {
42
+ const result = await rpcCall("getTokenAccountsByOwner", [
43
+ address,
44
+ { mint },
45
+ { encoding: "jsonParsed" },
46
+ ]);
47
+ const accounts = result?.value ?? [];
48
+ if (accounts.length === 0)
49
+ return 0;
50
+ return parseFloat(accounts[0]?.account?.data?.parsed?.info?.tokenAmount?.uiAmount ?? "0");
51
+ }
52
+ catch {
53
+ return 0;
54
+ }
55
+ }
56
+ export class AgentWallet {
57
+ cachedWallets = null;
58
+ lastFetch = 0;
59
+ cacheDuration = 30_000;
60
+ async getAll() {
61
+ if (this.cachedWallets && Date.now() - this.lastFetch < this.cacheDuration) {
62
+ return this.cachedWallets;
63
+ }
64
+ const [coldSol, coldAiai, coldUsdc, actionSol, actionAiai, actionUsdc, depSol, depAiai, depUsdc] = await Promise.all([
65
+ getBalance(COLD_WALLET),
66
+ getTokenBalance(COLD_WALLET, AIAIAI_MINT),
67
+ getTokenBalance(COLD_WALLET, USDC_MINT),
68
+ getBalance(ACTION_WALLET),
69
+ getTokenBalance(ACTION_WALLET, AIAIAI_MINT),
70
+ getTokenBalance(ACTION_WALLET, USDC_MINT),
71
+ getBalance(DEPOSIT_WALLET),
72
+ getTokenBalance(DEPOSIT_WALLET, AIAIAI_MINT),
73
+ getTokenBalance(DEPOSIT_WALLET, USDC_MINT),
74
+ ]);
75
+ this.cachedWallets = {
76
+ cold: { address: COLD_WALLET, sol: coldSol, aiaiai: coldAiai, usdc: coldUsdc },
77
+ action: { address: ACTION_WALLET, sol: actionSol, aiaiai: actionAiai, usdc: actionUsdc },
78
+ deposit: { address: DEPOSIT_WALLET, sol: depSol, aiaiai: depAiai, usdc: depUsdc },
79
+ };
80
+ this.lastFetch = Date.now();
81
+ return this.cachedWallets;
82
+ }
83
+ async getColdWallet() {
84
+ return (await this.getAll()).cold;
85
+ }
86
+ async getActionWallet() {
87
+ return (await this.getAll()).action;
88
+ }
89
+ async getDepositWallet() {
90
+ return (await this.getAll()).deposit;
91
+ }
92
+ // ── Tools ───────────────────────────────────────────────────────────────
93
+ getAgentBalanceParams = Type.Object({});
94
+ getDepositBalanceParams = Type.Object({});
95
+ async getAgentBalanceTool() {
96
+ const w = await this.getAll();
97
+ const lines = [
98
+ `Agent Cold Wallet`,
99
+ ` Address: ${COLD_WALLET.slice(0, 8)}…${COLD_WALLET.slice(-6)}`,
100
+ ` SOL: ${w.cold.sol.toFixed(4)}`,
101
+ ` $AIAIAI: ${w.cold.aiaiai.toLocaleString(undefined, { maximumFractionDigits: 2 })}`,
102
+ ` USDC: ${w.cold.usdc.toFixed(2)}`,
103
+ ``,
104
+ `Agent Action Wallet`,
105
+ ` Address: ${ACTION_WALLET.slice(0, 8)}…${ACTION_WALLET.slice(-6)}`,
106
+ ` SOL: ${w.action.sol.toFixed(4)}`,
107
+ ` $AIAIAI: ${w.action.aiaiai.toLocaleString(undefined, { maximumFractionDigits: 2 })}`,
108
+ ` USDC: ${w.action.usdc.toFixed(2)}`,
109
+ ];
110
+ return { content: [{ type: "text", text: lines.join("\n") }] };
111
+ }
112
+ async getDepositBalanceTool() {
113
+ const w = await this.getAll();
114
+ const lines = [
115
+ `Deposit Wallet`,
116
+ ` Address: ${DEPOSIT_WALLET}`,
117
+ ` SOL: ${w.deposit.sol.toFixed(4)}`,
118
+ ` $AIAIAI: ${w.deposit.aiaiai.toLocaleString(undefined, { maximumFractionDigits: 2 })}`,
119
+ ` USDC: ${w.deposit.usdc.toFixed(2)}`,
120
+ ``,
121
+ `Send SOL or USDC here to fuel agent actions.`,
122
+ `Signer: ${SIGNER.slice(0, 8)}…`,
123
+ ];
124
+ return { content: [{ type: "text", text: lines.join("\n") }] };
125
+ }
126
+ }
127
+ export const agentWallet = new AgentWallet();
128
+ //# sourceMappingURL=AgentWallet.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiaiaichain/agent",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
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",