@t2000/cli 0.14.0 → 0.14.1

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/README.md CHANGED
@@ -90,14 +90,28 @@ t2000 init
90
90
  Portfolio: 105.26 SUI (avg $0.95)
91
91
  Tx: https://suiscan.xyz/mainnet/tx/...
92
92
 
93
+ ❯ t2000 invest buy 500 BTC
94
+ ✓ Bought 0.00512820 BTC at $97,500.00
95
+ Invested: $500.00
96
+ Portfolio: 0.00512820 BTC (avg $97,500.00)
97
+ Tx: https://suiscan.xyz/mainnet/tx/...
98
+
99
+ ❯ t2000 invest buy 200 ETH
100
+ ✓ Bought 0.10526316 ETH at $1,900.00
101
+ Invested: $200.00
102
+ Portfolio: 0.10526316 ETH (avg $1,900.00)
103
+ Tx: https://suiscan.xyz/mainnet/tx/...
104
+
93
105
  ❯ t2000 portfolio
94
106
  Investment Portfolio
95
107
  ─────────────────────────────────────────────────────
96
- SUI 105.26 Avg: $0.95 Now: $0.97 +$2.10 (+2.1%)
108
+ SUI 105.26000000 Avg: $0.95 Now: $0.97 +$2.10 (+2.1%)
109
+ BTC 0.00512820 Avg: $97,500 Now: $98,200 +$3.59 (+0.7%)
110
+ ETH 0.10526316 Avg: $1,900 Now: $1,920 +$2.11 (+1.1%)
97
111
  ─────────────────────────────────────────────────────
98
- Total invested: $100.00
99
- Current value: $102.10
100
- Unrealized P&L: +$2.10 (+2.1%)
112
+ Total invested: $800.00
113
+ Current value: $807.80
114
+ Unrealized P&L: +$7.80 (+1.0%)
101
115
  ```
102
116
 
103
117
  30 seconds. Send → save → borrow → pay → repay → withdraw.
@@ -176,6 +190,16 @@ t2000 init
176
190
  | `t2000 contacts add <name> <address>` | Save a named contact |
177
191
  | `t2000 contacts remove <name>` | Remove a contact |
178
192
 
193
+ ### Investment
194
+
195
+ | Command | Description |
196
+ |---------|-------------|
197
+ | `t2000 invest buy <amount> <asset>` | Buy crypto with USDC (e.g. `t2000 invest buy 500 BTC`, `t2000 invest buy 200 ETH`) |
198
+ | `t2000 invest sell <amount\|all> <asset>` | Sell crypto back to USDC |
199
+ | `t2000 portfolio` | View investment portfolio with cost-basis P&L |
200
+
201
+ Supported assets: SUI, BTC, ETH. Dollar-denominated — `amount` is in USD.
202
+
179
203
  ### Safeguards
180
204
 
181
205
  | Command | Description |
@@ -20965,7 +20965,7 @@ var StdioServerTransport = class {
20965
20965
  import { readFile } from "fs/promises";
20966
20966
  import { resolve } from "path";
20967
20967
  import { homedir } from "os";
20968
- import { T2000, SafeguardError, T2000Error } from "@t2000/sdk";
20968
+ import { T2000, INVESTMENT_ASSETS, SafeguardError, T2000Error } from "@t2000/sdk";
20969
20969
  var SESSION_PATH = resolve(homedir(), ".t2000", ".session");
20970
20970
  async function resolvePin() {
20971
20971
  const envPin = process.env.T2000_PIN ?? process.env.T2000_PASSPHRASE;
@@ -21124,7 +21124,14 @@ function registerReadTools(server, agent) {
21124
21124
  async () => {
21125
21125
  try {
21126
21126
  const result = await agent.getPortfolio();
21127
- return { content: [{ type: "text", text: JSON.stringify(result) }] };
21127
+ const enriched = {
21128
+ ...result,
21129
+ positions: result.positions.map((p) => ({
21130
+ ...p,
21131
+ ...p.currentPrice === 0 && p.totalAmount > 0 ? { note: "price unavailable" } : {}
21132
+ }))
21133
+ };
21134
+ return { content: [{ type: "text", text: JSON.stringify(enriched) }] };
21128
21135
  } catch (err) {
21129
21136
  return errorResult(err);
21130
21137
  }
@@ -21364,22 +21371,29 @@ function registerWriteTools(server, agent) {
21364
21371
  }
21365
21372
  }
21366
21373
  );
21374
+ const investAssets = Object.keys(INVESTMENT_ASSETS);
21367
21375
  server.tool(
21368
21376
  "t2000_invest",
21369
- "Buy or sell investment assets (spot). Amount is in USD. Asset is the crypto to buy/sell (e.g. SUI). Set dryRun: true to preview.",
21377
+ "Buy or sell investment assets (spot). Amount is in USD. Asset is the crypto to buy/sell (e.g. SUI, BTC, ETH). Set dryRun: true to preview.",
21370
21378
  {
21371
21379
  action: external_exports.enum(["buy", "sell"]).describe("'buy' to invest USD into asset, 'sell' to convert asset back to USDC"),
21372
- asset: external_exports.enum(["SUI"]).describe("Asset to invest in"),
21380
+ asset: external_exports.enum(investAssets).describe("Asset to invest in"),
21373
21381
  amount: external_exports.union([external_exports.number(), external_exports.literal("all")]).describe('USD amount, or "all" to sell entire position'),
21382
+ slippage: external_exports.number().optional().describe("Max slippage percent (default: 3)"),
21374
21383
  dryRun: external_exports.boolean().optional().describe("Preview without signing (default: false)")
21375
21384
  },
21376
- async ({ action, asset, amount, dryRun }) => {
21385
+ async ({ action, asset, amount, slippage, dryRun }) => {
21377
21386
  try {
21378
21387
  if (dryRun) {
21379
21388
  agent.enforcer.assertNotLocked();
21380
21389
  const balance = await agent.balance();
21381
21390
  const portfolio = await agent.getPortfolio();
21382
21391
  const position = portfolio.positions.find((p) => p.asset === asset);
21392
+ if (action === "sell" && amount === "all" && !position) {
21393
+ return {
21394
+ content: [{ type: "text", text: JSON.stringify({ preview: true, error: `No ${asset} position to sell` }) }]
21395
+ };
21396
+ }
21383
21397
  return {
21384
21398
  content: [{
21385
21399
  type: "text",
@@ -21394,13 +21408,14 @@ function registerWriteTools(server, agent) {
21394
21408
  }]
21395
21409
  };
21396
21410
  }
21411
+ const maxSlippage = slippage ? slippage / 100 : void 0;
21397
21412
  if (action === "buy") {
21398
21413
  if (typeof amount !== "number") throw new Error("Buy amount must be a number");
21399
- const result = await mutex.run(() => agent.investBuy({ asset, usdAmount: amount }));
21414
+ const result = await mutex.run(() => agent.investBuy({ asset, usdAmount: amount, maxSlippage }));
21400
21415
  return { content: [{ type: "text", text: JSON.stringify(result) }] };
21401
21416
  } else {
21402
21417
  const usdAmount = amount === "all" ? "all" : amount;
21403
- const result = await mutex.run(() => agent.investSell({ asset, usdAmount }));
21418
+ const result = await mutex.run(() => agent.investSell({ asset, usdAmount, maxSlippage }));
21404
21419
  return { content: [{ type: "text", text: JSON.stringify(result) }] };
21405
21420
  }
21406
21421
  } catch (err) {
@@ -21695,4 +21710,4 @@ async function startMcpServer(opts) {
21695
21710
  export {
21696
21711
  startMcpServer
21697
21712
  };
21698
- //# sourceMappingURL=dist-4B5R5GWR.js.map
21713
+ //# sourceMappingURL=dist-4YM7JZSI.js.map