@raintree-technology/perps 0.1.0

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 (316) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/LICENSE +21 -0
  3. package/README.md +175 -0
  4. package/dist/adapters/aevo.d.ts +64 -0
  5. package/dist/adapters/aevo.js +899 -0
  6. package/dist/adapters/certification.d.ts +33 -0
  7. package/dist/adapters/certification.js +99 -0
  8. package/dist/adapters/decibel/order-manager.d.ts +45 -0
  9. package/dist/adapters/decibel/order-manager.js +140 -0
  10. package/dist/adapters/decibel/rest-client.d.ts +176 -0
  11. package/dist/adapters/decibel/rest-client.js +155 -0
  12. package/dist/adapters/decibel/ws-feed.d.ts +28 -0
  13. package/dist/adapters/decibel/ws-feed.js +166 -0
  14. package/dist/adapters/decibel.d.ts +108 -0
  15. package/dist/adapters/decibel.js +1377 -0
  16. package/dist/adapters/hyperliquid.d.ts +63 -0
  17. package/dist/adapters/hyperliquid.js +797 -0
  18. package/dist/adapters/index.d.ts +11 -0
  19. package/dist/adapters/index.js +12 -0
  20. package/dist/adapters/interface.d.ts +310 -0
  21. package/dist/adapters/interface.js +15 -0
  22. package/dist/adapters/orderly.d.ts +70 -0
  23. package/dist/adapters/orderly.js +936 -0
  24. package/dist/adapters/paradex.d.ts +69 -0
  25. package/dist/adapters/paradex.js +862 -0
  26. package/dist/adapters/utils.d.ts +17 -0
  27. package/dist/adapters/utils.js +122 -0
  28. package/dist/cli/command-metadata.d.ts +2 -0
  29. package/dist/cli/command-metadata.js +44 -0
  30. package/dist/cli/context.d.ts +14 -0
  31. package/dist/cli/context.js +59 -0
  32. package/dist/cli/experience.d.ts +48 -0
  33. package/dist/cli/experience.js +243 -0
  34. package/dist/cli/ink/app/AppShell.d.ts +12 -0
  35. package/dist/cli/ink/app/AppShell.js +32 -0
  36. package/dist/cli/ink/app/MetricStrip.d.ts +6 -0
  37. package/dist/cli/ink/app/MetricStrip.js +14 -0
  38. package/dist/cli/ink/app/Panel.d.ts +9 -0
  39. package/dist/cli/ink/app/Panel.js +7 -0
  40. package/dist/cli/ink/app/ascii.d.ts +2 -0
  41. package/dist/cli/ink/app/ascii.js +46 -0
  42. package/dist/cli/ink/app/index.d.ts +5 -0
  43. package/dist/cli/ink/app/index.js +4 -0
  44. package/dist/cli/ink/app/types.d.ts +15 -0
  45. package/dist/cli/ink/app/types.js +1 -0
  46. package/dist/cli/ink/components/PnL.d.ts +12 -0
  47. package/dist/cli/ink/components/PnL.js +23 -0
  48. package/dist/cli/ink/components/Spinner.d.ts +13 -0
  49. package/dist/cli/ink/components/Spinner.js +13 -0
  50. package/dist/cli/ink/components/Table.d.ts +14 -0
  51. package/dist/cli/ink/components/Table.js +42 -0
  52. package/dist/cli/ink/components/WatchHeader.d.ts +10 -0
  53. package/dist/cli/ink/components/WatchHeader.js +18 -0
  54. package/dist/cli/ink/components/index.d.ts +4 -0
  55. package/dist/cli/ink/components/index.js +4 -0
  56. package/dist/cli/ink/index.d.ts +4 -0
  57. package/dist/cli/ink/index.js +4 -0
  58. package/dist/cli/ink/render.d.ts +12 -0
  59. package/dist/cli/ink/render.js +21 -0
  60. package/dist/cli/ink/theme.d.ts +29 -0
  61. package/dist/cli/ink/theme.js +40 -0
  62. package/dist/cli/network-defaults.d.ts +10 -0
  63. package/dist/cli/network-defaults.js +35 -0
  64. package/dist/cli/output.d.ts +11 -0
  65. package/dist/cli/output.js +115 -0
  66. package/dist/cli/program.d.ts +18 -0
  67. package/dist/cli/program.js +164 -0
  68. package/dist/cli/watch.d.ts +19 -0
  69. package/dist/cli/watch.js +35 -0
  70. package/dist/client/index.d.ts +55 -0
  71. package/dist/client/index.js +157 -0
  72. package/dist/commands/account/add.d.ts +2 -0
  73. package/dist/commands/account/add.js +510 -0
  74. package/dist/commands/account/balances-simple.d.ts +5 -0
  75. package/dist/commands/account/balances-simple.js +63 -0
  76. package/dist/commands/account/index.d.ts +2 -0
  77. package/dist/commands/account/index.js +17 -0
  78. package/dist/commands/account/ls.d.ts +2 -0
  79. package/dist/commands/account/ls.js +95 -0
  80. package/dist/commands/account/positions-simple.d.ts +5 -0
  81. package/dist/commands/account/positions-simple.js +77 -0
  82. package/dist/commands/account/remove.d.ts +2 -0
  83. package/dist/commands/account/remove.js +47 -0
  84. package/dist/commands/account/set-default.d.ts +2 -0
  85. package/dist/commands/account/set-default.js +47 -0
  86. package/dist/commands/agent/index.d.ts +2 -0
  87. package/dist/commands/agent/index.js +126 -0
  88. package/dist/commands/arb/alert.d.ts +6 -0
  89. package/dist/commands/arb/alert.js +88 -0
  90. package/dist/commands/arb/basis-execute.d.ts +6 -0
  91. package/dist/commands/arb/basis-execute.js +332 -0
  92. package/dist/commands/arb/basis.d.ts +6 -0
  93. package/dist/commands/arb/basis.js +181 -0
  94. package/dist/commands/arb/compare.d.ts +6 -0
  95. package/dist/commands/arb/compare.js +216 -0
  96. package/dist/commands/arb/execute.d.ts +6 -0
  97. package/dist/commands/arb/execute.js +467 -0
  98. package/dist/commands/arb/funding.d.ts +6 -0
  99. package/dist/commands/arb/funding.js +201 -0
  100. package/dist/commands/arb/history.d.ts +6 -0
  101. package/dist/commands/arb/history.js +153 -0
  102. package/dist/commands/arb/index.d.ts +6 -0
  103. package/dist/commands/arb/index.js +29 -0
  104. package/dist/commands/arb/positions.d.ts +6 -0
  105. package/dist/commands/arb/positions.js +158 -0
  106. package/dist/commands/arb/spread.d.ts +6 -0
  107. package/dist/commands/arb/spread.js +253 -0
  108. package/dist/commands/arb/track.d.ts +6 -0
  109. package/dist/commands/arb/track.js +259 -0
  110. package/dist/commands/asset/book-simple.d.ts +5 -0
  111. package/dist/commands/asset/book-simple.js +77 -0
  112. package/dist/commands/asset/index.d.ts +2 -0
  113. package/dist/commands/asset/index.js +5 -0
  114. package/dist/commands/completion.d.ts +2 -0
  115. package/dist/commands/completion.js +161 -0
  116. package/dist/commands/config/index.d.ts +5 -0
  117. package/dist/commands/config/index.js +109 -0
  118. package/dist/commands/data/index.d.ts +31 -0
  119. package/dist/commands/data/index.js +1466 -0
  120. package/dist/commands/doctor.d.ts +2 -0
  121. package/dist/commands/doctor.js +201 -0
  122. package/dist/commands/exchange/index.d.ts +2 -0
  123. package/dist/commands/exchange/index.js +107 -0
  124. package/dist/commands/index.d.ts +2 -0
  125. package/dist/commands/index.js +48 -0
  126. package/dist/commands/markets/index.d.ts +2 -0
  127. package/dist/commands/markets/index.js +5 -0
  128. package/dist/commands/markets/ls-simple.d.ts +7 -0
  129. package/dist/commands/markets/ls-simple.js +277 -0
  130. package/dist/commands/operator/index.d.ts +2 -0
  131. package/dist/commands/operator/index.js +146 -0
  132. package/dist/commands/order/cancel-simple.d.ts +5 -0
  133. package/dist/commands/order/cancel-simple.js +104 -0
  134. package/dist/commands/order/index.d.ts +2 -0
  135. package/dist/commands/order/index.js +13 -0
  136. package/dist/commands/order/limit-simple.d.ts +5 -0
  137. package/dist/commands/order/limit-simple.js +195 -0
  138. package/dist/commands/order/market-simple.d.ts +5 -0
  139. package/dist/commands/order/market-simple.js +190 -0
  140. package/dist/commands/order/shared.d.ts +17 -0
  141. package/dist/commands/order/shared.js +51 -0
  142. package/dist/commands/order/trigger-simple.d.ts +5 -0
  143. package/dist/commands/order/trigger-simple.js +246 -0
  144. package/dist/commands/referral/index.d.ts +2 -0
  145. package/dist/commands/referral/index.js +7 -0
  146. package/dist/commands/referral/set.d.ts +2 -0
  147. package/dist/commands/referral/set.js +26 -0
  148. package/dist/commands/referral/status.d.ts +2 -0
  149. package/dist/commands/referral/status.js +31 -0
  150. package/dist/commands/replay/index.d.ts +2 -0
  151. package/dist/commands/replay/index.js +152 -0
  152. package/dist/commands/risk/analytics.d.ts +2 -0
  153. package/dist/commands/risk/analytics.js +64 -0
  154. package/dist/commands/risk/audit.d.ts +2 -0
  155. package/dist/commands/risk/audit.js +52 -0
  156. package/dist/commands/risk/index.d.ts +2 -0
  157. package/dist/commands/risk/index.js +9 -0
  158. package/dist/commands/risk/rules.d.ts +2 -0
  159. package/dist/commands/risk/rules.js +102 -0
  160. package/dist/commands/server.d.ts +2 -0
  161. package/dist/commands/server.js +208 -0
  162. package/dist/commands/setup/index.d.ts +2 -0
  163. package/dist/commands/setup/index.js +478 -0
  164. package/dist/commands/signal/index.d.ts +2 -0
  165. package/dist/commands/signal/index.js +129 -0
  166. package/dist/commands/state/index.d.ts +2 -0
  167. package/dist/commands/state/index.js +5 -0
  168. package/dist/commands/state/show.d.ts +2 -0
  169. package/dist/commands/state/show.js +105 -0
  170. package/dist/commands/strategy/index.d.ts +4 -0
  171. package/dist/commands/strategy/index.js +73 -0
  172. package/dist/commands/traces/index.d.ts +2 -0
  173. package/dist/commands/traces/index.js +76 -0
  174. package/dist/commands/ui/demo.d.ts +9 -0
  175. package/dist/commands/ui/demo.js +195 -0
  176. package/dist/commands/ui/index.d.ts +2 -0
  177. package/dist/commands/ui/index.js +7 -0
  178. package/dist/commands/ui/terminal.d.ts +2 -0
  179. package/dist/commands/ui/terminal.js +255 -0
  180. package/dist/commands/upgrade.d.ts +2 -0
  181. package/dist/commands/upgrade.js +98 -0
  182. package/dist/index.d.ts +2 -0
  183. package/dist/index.js +4 -0
  184. package/dist/lib/agent/audit.d.ts +12 -0
  185. package/dist/lib/agent/audit.js +13 -0
  186. package/dist/lib/agent/gateway.d.ts +13 -0
  187. package/dist/lib/agent/gateway.js +598 -0
  188. package/dist/lib/agent/metrics.d.ts +33 -0
  189. package/dist/lib/agent/metrics.js +175 -0
  190. package/dist/lib/agent/signature.d.ts +8 -0
  191. package/dist/lib/agent/signature.js +28 -0
  192. package/dist/lib/agent/tools.d.ts +28 -0
  193. package/dist/lib/agent/tools.js +453 -0
  194. package/dist/lib/agent/x402.d.ts +23 -0
  195. package/dist/lib/agent/x402.js +62 -0
  196. package/dist/lib/api-wallet.d.ts +69 -0
  197. package/dist/lib/api-wallet.js +101 -0
  198. package/dist/lib/balance-watcher.d.ts +25 -0
  199. package/dist/lib/balance-watcher.js +83 -0
  200. package/dist/lib/book-watcher.d.ts +25 -0
  201. package/dist/lib/book-watcher.js +48 -0
  202. package/dist/lib/config.d.ts +88 -0
  203. package/dist/lib/config.js +427 -0
  204. package/dist/lib/constants.d.ts +50 -0
  205. package/dist/lib/constants.js +84 -0
  206. package/dist/lib/contracts.d.ts +7 -0
  207. package/dist/lib/contracts.js +8 -0
  208. package/dist/lib/credential-vault.d.ts +22 -0
  209. package/dist/lib/credential-vault.js +109 -0
  210. package/dist/lib/db/accounts.d.ts +83 -0
  211. package/dist/lib/db/accounts.js +203 -0
  212. package/dist/lib/db/funding-history.d.ts +69 -0
  213. package/dist/lib/db/funding-history.js +183 -0
  214. package/dist/lib/db/index.d.ts +11 -0
  215. package/dist/lib/db/index.js +272 -0
  216. package/dist/lib/events/bus.d.ts +10 -0
  217. package/dist/lib/events/bus.js +17 -0
  218. package/dist/lib/events/types.d.ts +51 -0
  219. package/dist/lib/events/types.js +1 -0
  220. package/dist/lib/exchange.d.ts +30 -0
  221. package/dist/lib/exchange.js +84 -0
  222. package/dist/lib/execution/journal.d.ts +25 -0
  223. package/dist/lib/execution/journal.js +158 -0
  224. package/dist/lib/execution/safety.d.ts +34 -0
  225. package/dist/lib/execution/safety.js +197 -0
  226. package/dist/lib/exit-codes.d.ts +18 -0
  227. package/dist/lib/exit-codes.js +60 -0
  228. package/dist/lib/fetch.d.ts +18 -0
  229. package/dist/lib/fetch.js +66 -0
  230. package/dist/lib/fs-security.d.ts +10 -0
  231. package/dist/lib/fs-security.js +26 -0
  232. package/dist/lib/funding-tracker.d.ts +40 -0
  233. package/dist/lib/funding-tracker.js +118 -0
  234. package/dist/lib/logger.d.ts +27 -0
  235. package/dist/lib/logger.js +82 -0
  236. package/dist/lib/network-model.d.ts +13 -0
  237. package/dist/lib/network-model.js +30 -0
  238. package/dist/lib/onboarding.d.ts +133 -0
  239. package/dist/lib/onboarding.js +1459 -0
  240. package/dist/lib/operator-state.d.ts +25 -0
  241. package/dist/lib/operator-state.js +82 -0
  242. package/dist/lib/orders-watcher.d.ts +24 -0
  243. package/dist/lib/orders-watcher.js +74 -0
  244. package/dist/lib/paths.d.ts +20 -0
  245. package/dist/lib/paths.js +23 -0
  246. package/dist/lib/portfolio-watcher.d.ts +33 -0
  247. package/dist/lib/portfolio-watcher.js +95 -0
  248. package/dist/lib/position-watcher.d.ts +16 -0
  249. package/dist/lib/position-watcher.js +44 -0
  250. package/dist/lib/price-watcher.d.ts +15 -0
  251. package/dist/lib/price-watcher.js +84 -0
  252. package/dist/lib/prompts.d.ts +32 -0
  253. package/dist/lib/prompts.js +105 -0
  254. package/dist/lib/rate-limit.d.ts +32 -0
  255. package/dist/lib/rate-limit.js +88 -0
  256. package/dist/lib/risk/analytics.d.ts +39 -0
  257. package/dist/lib/risk/analytics.js +98 -0
  258. package/dist/lib/risk/drawdown.d.ts +18 -0
  259. package/dist/lib/risk/drawdown.js +49 -0
  260. package/dist/lib/risk/evaluation-log.d.ts +29 -0
  261. package/dist/lib/risk/evaluation-log.js +61 -0
  262. package/dist/lib/risk/index.d.ts +4 -0
  263. package/dist/lib/risk/index.js +4 -0
  264. package/dist/lib/risk/limits.d.ts +23 -0
  265. package/dist/lib/risk/limits.js +27 -0
  266. package/dist/lib/risk/manager.d.ts +32 -0
  267. package/dist/lib/risk/manager.js +85 -0
  268. package/dist/lib/risk/policy-middleware.d.ts +33 -0
  269. package/dist/lib/risk/policy-middleware.js +267 -0
  270. package/dist/lib/risk/position-sizer.d.ts +9 -0
  271. package/dist/lib/risk/position-sizer.js +14 -0
  272. package/dist/lib/risk/rules-store.d.ts +16 -0
  273. package/dist/lib/risk/rules-store.js +47 -0
  274. package/dist/lib/schema.d.ts +254 -0
  275. package/dist/lib/schema.js +199 -0
  276. package/dist/lib/secrets.d.ts +3 -0
  277. package/dist/lib/secrets.js +62 -0
  278. package/dist/lib/settings.d.ts +24 -0
  279. package/dist/lib/settings.js +86 -0
  280. package/dist/lib/signals.d.ts +73 -0
  281. package/dist/lib/signals.js +136 -0
  282. package/dist/lib/stable-stringify.d.ts +6 -0
  283. package/dist/lib/stable-stringify.js +17 -0
  284. package/dist/lib/state-context.d.ts +44 -0
  285. package/dist/lib/state-context.js +133 -0
  286. package/dist/lib/strategy/basis-trade.d.ts +2 -0
  287. package/dist/lib/strategy/basis-trade.js +24 -0
  288. package/dist/lib/strategy/funding-arb.d.ts +2 -0
  289. package/dist/lib/strategy/funding-arb.js +23 -0
  290. package/dist/lib/strategy/interface.d.ts +23 -0
  291. package/dist/lib/strategy/interface.js +1 -0
  292. package/dist/lib/strategy/registry.d.ts +4 -0
  293. package/dist/lib/strategy/registry.js +10 -0
  294. package/dist/lib/telemetry.d.ts +25 -0
  295. package/dist/lib/telemetry.js +101 -0
  296. package/dist/lib/trace-queries.d.ts +20 -0
  297. package/dist/lib/trace-queries.js +133 -0
  298. package/dist/lib/trace.d.ts +1 -0
  299. package/dist/lib/trace.js +4 -0
  300. package/dist/lib/trade-reputation.d.ts +6 -0
  301. package/dist/lib/trade-reputation.js +99 -0
  302. package/dist/lib/ui-tokens.d.ts +21 -0
  303. package/dist/lib/ui-tokens.js +26 -0
  304. package/dist/lib/validate.d.ts +39 -0
  305. package/dist/lib/validate.js +108 -0
  306. package/dist/lib/validation.d.ts +9 -0
  307. package/dist/lib/validation.js +64 -0
  308. package/dist/server/cache.d.ts +38 -0
  309. package/dist/server/cache.js +56 -0
  310. package/dist/server/index.d.ts +2 -0
  311. package/dist/server/index.js +89 -0
  312. package/dist/server/ipc.d.ts +18 -0
  313. package/dist/server/ipc.js +159 -0
  314. package/dist/server/subscriptions.d.ts +18 -0
  315. package/dist/server/subscriptions.js +114 -0
  316. package/package.json +124 -0
@@ -0,0 +1,95 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text, render } from "ink";
3
+ import { getOutputOptions } from "../../cli/program.js";
4
+ import { output } from "../../cli/output.js";
5
+ import { getAllAccounts } from "../../lib/db/index.js";
6
+ import { AppShell, MetricStrip, Panel, Table, toBar, } from "../../cli/ink/index.js";
7
+ import { colors } from "../../cli/ink/theme.js";
8
+ function formatAddress(address) {
9
+ if (address.length <= 14) {
10
+ return address;
11
+ }
12
+ return `${address.slice(0, 6)}...${address.slice(-4)}`;
13
+ }
14
+ function buildExchangeCoverage(accounts) {
15
+ const counts = new Map();
16
+ for (const account of accounts) {
17
+ counts.set(account.exchange, (counts.get(account.exchange) || 0) + 1);
18
+ }
19
+ const rows = Array.from(counts.entries())
20
+ .map(([exchange, count]) => ({ exchange, count, bar: "" }))
21
+ .sort((left, right) => right.count - left.count || left.exchange.localeCompare(right.exchange));
22
+ const maxCount = Math.max(1, ...rows.map((row) => row.count));
23
+ return rows.map((row) => ({
24
+ ...row,
25
+ bar: toBar(row.count, maxCount, 16, "#", "."),
26
+ }));
27
+ }
28
+ function AccountsList({ accounts }) {
29
+ const hasAccounts = accounts.length > 0;
30
+ const exchangeCoverage = hasAccounts ? buildExchangeCoverage(accounts) : [];
31
+ const defaultCount = accounts.filter((account) => account.isDefault).length;
32
+ const apiWalletCount = accounts.filter((account) => Boolean(account.apiWalletPublicKey)).length;
33
+ const metrics = [
34
+ { label: "Accounts", value: String(accounts.length), tone: hasAccounts ? "info" : "neutral" },
35
+ { label: "Default", value: String(defaultCount), tone: defaultCount > 0 ? "success" : "warning" },
36
+ { label: "API Wallets", value: String(apiWalletCount), tone: "neutral" },
37
+ { label: "Exchanges", value: String(exchangeCoverage.length), tone: "neutral" },
38
+ ];
39
+ if (accounts.length === 0) {
40
+ return (_jsxs(AppShell, { title: "Accounts", subtitle: "Local account profiles", status: [{ label: "EMPTY", tone: "warning" }], children: [_jsx(MetricStrip, { metrics: metrics }), _jsx(Panel, { title: "Profiles", subtitle: "No accounts are configured yet.", children: _jsx(Text, { color: colors.muted, children: "Run `perps account add` to add your first account." }) })] }));
41
+ }
42
+ const rows = accounts.map((acc) => ({
43
+ alias: acc.alias,
44
+ exchange: acc.exchange,
45
+ address: formatAddress(acc.userAddress),
46
+ type: acc.type,
47
+ apiWallet: acc.apiWalletPublicKey
48
+ ? formatAddress(acc.apiWalletPublicKey)
49
+ : "-",
50
+ default: acc.isDefault ? "*" : "",
51
+ }));
52
+ const columns = [
53
+ { key: "default", header: "", width: 2 },
54
+ { key: "alias", header: "Alias" },
55
+ { key: "exchange", header: "Exchange" },
56
+ { key: "address", header: "Address" },
57
+ { key: "type", header: "Type" },
58
+ { key: "apiWallet", header: "API Wallet" },
59
+ ];
60
+ const exchangeColumns = [
61
+ { key: "exchange", header: "Exchange", width: 14 },
62
+ { key: "count", header: "Count", align: "right", width: 5 },
63
+ { key: "bar", header: "Coverage", width: 16 },
64
+ ];
65
+ return (_jsxs(AppShell, { title: "Accounts", subtitle: "Local account profiles", status: [{ label: `${accounts.length} PROFILES`, tone: "info" }], children: [_jsx(MetricStrip, { metrics: metrics }), _jsx(Box, { flexDirection: "column", marginBottom: 1, children: _jsxs(Panel, { title: "Profiles", subtitle: "Saved accounts and default selection", children: [_jsx(Table, { data: rows, columns: columns }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.muted, children: "* = default account" }) })] }) }), _jsx(Panel, { title: "Exchange Coverage", subtitle: "Account distribution by exchange", children: _jsx(Table, { data: exchangeCoverage, columns: exchangeColumns }) })] }));
66
+ }
67
+ export function registerLsCommand(account) {
68
+ account
69
+ .command("ls")
70
+ .description("List all accounts")
71
+ .action(async function () {
72
+ const outputOpts = getOutputOptions(this);
73
+ const accounts = getAllAccounts();
74
+ if (outputOpts.json) {
75
+ // For JSON output, include full addresses but redact private keys
76
+ const jsonAccounts = accounts.map((acc) => ({
77
+ id: acc.id,
78
+ alias: acc.alias,
79
+ userAddress: acc.userAddress,
80
+ type: acc.type,
81
+ source: acc.source,
82
+ apiWalletPublicKey: acc.apiWalletPublicKey,
83
+ isDefault: acc.isDefault,
84
+ createdAt: acc.createdAt,
85
+ updatedAt: acc.updatedAt,
86
+ }));
87
+ output(jsonAccounts, outputOpts);
88
+ }
89
+ else {
90
+ const { unmount, waitUntilExit } = render(_jsx(AccountsList, { accounts: accounts }));
91
+ await waitUntilExit();
92
+ unmount();
93
+ }
94
+ });
95
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Simple positions command using the adapter interface
3
+ */
4
+ import { Command } from "commander";
5
+ export declare function registerPositionsSimpleCommand(account: Command): void;
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Simple positions command using the adapter interface
3
+ */
4
+ import { getContext, getOutputOptions, getSelectedExchange } from "../../cli/program.js";
5
+ import { output, outputError } from "../../cli/output.js";
6
+ import { getExchangeAdapter } from "../../lib/exchange.js";
7
+ import { getExchangeCredentials } from "../../lib/config.js";
8
+ export function registerPositionsSimpleCommand(account) {
9
+ account
10
+ .command("positions")
11
+ .alias("pos")
12
+ .description("Show open positions")
13
+ .action(async function () {
14
+ const ctx = getContext(this);
15
+ const outputOpts = getOutputOptions(this);
16
+ const exchangeId = getSelectedExchange(this);
17
+ const adapter = getExchangeAdapter();
18
+ let connected = false;
19
+ try {
20
+ const credentials = getExchangeCredentials(ctx.config, exchangeId, {
21
+ requireReadAccess: true,
22
+ });
23
+ await adapter.connect({
24
+ testnet: ctx.config.testnet,
25
+ rpcUrl: credentials.fullnodeUrl,
26
+ wsUrl: credentials.wsUrl,
27
+ credentials,
28
+ });
29
+ connected = true;
30
+ const positions = await adapter.getPositions();
31
+ if (outputOpts.json) {
32
+ output(positions, outputOpts);
33
+ }
34
+ else {
35
+ if (positions.length === 0) {
36
+ console.log("\nNo open positions.\n");
37
+ }
38
+ else {
39
+ console.log(`\n${adapter.info.name} Positions (${positions.length}):\n`);
40
+ console.log(" " +
41
+ "Market".padEnd(12) +
42
+ "Side".padEnd(7) +
43
+ "Size".padEnd(12) +
44
+ "Entry".padEnd(12) +
45
+ "Mark".padEnd(12) +
46
+ "uPnL".padEnd(14) +
47
+ "Lev");
48
+ console.log(" " + "─".repeat(80));
49
+ for (const pos of positions) {
50
+ const pnl = parseFloat(pos.unrealizedPnl);
51
+ const pnlColor = pnl >= 0 ? "\x1b[32m" : "\x1b[31m";
52
+ const pnlStr = `${pnl >= 0 ? "+" : ""}$${pnl.toFixed(2)}`;
53
+ const sideColor = pos.side === "long" ? "\x1b[32m" : "\x1b[31m";
54
+ console.log(" " +
55
+ pos.market.replace("-PERP", "").padEnd(12) +
56
+ `${sideColor}${pos.side.toUpperCase().padEnd(6)}\x1b[0m ` +
57
+ parseFloat(pos.size).toFixed(4).padEnd(12) +
58
+ `$${parseFloat(pos.entryPrice).toFixed(2)}`.padEnd(12) +
59
+ `$${parseFloat(pos.markPrice).toFixed(2)}`.padEnd(12) +
60
+ `${pnlColor}${pnlStr.padEnd(13)}\x1b[0m ` +
61
+ `${pos.leverage}x`);
62
+ }
63
+ console.log("");
64
+ }
65
+ }
66
+ }
67
+ catch (err) {
68
+ outputError(err instanceof Error ? err.message : String(err));
69
+ process.exitCode = 1;
70
+ }
71
+ finally {
72
+ if (connected) {
73
+ await adapter.disconnect().catch(() => undefined);
74
+ }
75
+ }
76
+ });
77
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerRemoveCommand(account: Command): void;
@@ -0,0 +1,47 @@
1
+ import { getOutputOptions } from "../../cli/program.js";
2
+ import { output, outputError, outputSuccess } from "../../cli/output.js";
3
+ import { deleteAccount, getAccountByAlias } from "../../lib/db/index.js";
4
+ import { getExchangeId } from "../../lib/exchange.js";
5
+ import { confirm } from "../../lib/prompts.js";
6
+ export function registerRemoveCommand(account) {
7
+ account
8
+ .command("remove")
9
+ .description("Remove an account")
10
+ .argument("<alias>", "Account alias to remove")
11
+ .option("-f, --force", "Skip confirmation prompt")
12
+ .action(async function (alias, options) {
13
+ const outputOpts = getOutputOptions(this);
14
+ const exchangeId = getExchangeId();
15
+ try {
16
+ // Check if account exists
17
+ const existingAccount = getAccountByAlias(alias, exchangeId);
18
+ if (!existingAccount) {
19
+ throw new Error(`Account with alias "${alias}" not found for exchange "${exchangeId}". Run 'perps account ls' to see available accounts.`);
20
+ }
21
+ // Confirm deletion unless --force is used
22
+ if (!options.force) {
23
+ const confirmed = await confirm(`Are you sure you want to remove account "${alias}" (${existingAccount.userAddress})?`, false);
24
+ if (!confirmed) {
25
+ console.log("Cancelled.");
26
+ return;
27
+ }
28
+ }
29
+ const deleted = deleteAccount(alias, exchangeId);
30
+ if (deleted) {
31
+ if (outputOpts.json) {
32
+ output({ message: `Account "${alias}" removed`, deleted: true }, outputOpts);
33
+ }
34
+ else {
35
+ outputSuccess(`Account "${alias}" removed.`);
36
+ }
37
+ }
38
+ else {
39
+ throw new Error(`Failed to remove account "${alias}"`);
40
+ }
41
+ }
42
+ catch (err) {
43
+ outputError(err instanceof Error ? err.message : String(err));
44
+ process.exit(1);
45
+ }
46
+ });
47
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerSetDefaultCommand(account: Command): void;
@@ -0,0 +1,47 @@
1
+ import { getOutputOptions } from "../../cli/program.js";
2
+ import { output, outputError, outputSuccess } from "../../cli/output.js";
3
+ import { setDefaultAccount, getAccountByAlias } from "../../lib/db/index.js";
4
+ import { getExchangeId } from "../../lib/exchange.js";
5
+ export function registerSetDefaultCommand(account) {
6
+ account
7
+ .command("set-default")
8
+ .description("Set an account as the default")
9
+ .argument("<alias>", "Account alias to set as default")
10
+ .action(async function (alias) {
11
+ const outputOpts = getOutputOptions(this);
12
+ const exchangeId = getExchangeId();
13
+ try {
14
+ // Check if account exists
15
+ const existingAccount = getAccountByAlias(alias, exchangeId);
16
+ if (!existingAccount) {
17
+ throw new Error(`Account with alias "${alias}" not found for exchange "${exchangeId}". Run 'perps account ls' to see available accounts.`);
18
+ }
19
+ if (existingAccount.isDefault) {
20
+ if (outputOpts.json) {
21
+ output({ message: `Account "${alias}" is already the default` }, outputOpts);
22
+ }
23
+ else {
24
+ console.log(`Account "${alias}" is already the default.`);
25
+ }
26
+ return;
27
+ }
28
+ const updatedAccount = setDefaultAccount(alias, exchangeId);
29
+ if (outputOpts.json) {
30
+ output({
31
+ id: updatedAccount.id,
32
+ alias: updatedAccount.alias,
33
+ userAddress: updatedAccount.userAddress,
34
+ type: updatedAccount.type,
35
+ isDefault: updatedAccount.isDefault,
36
+ }, outputOpts);
37
+ }
38
+ else {
39
+ outputSuccess(`Account "${alias}" is now the default.`);
40
+ }
41
+ }
42
+ catch (err) {
43
+ outputError(err instanceof Error ? err.message : String(err));
44
+ process.exit(1);
45
+ }
46
+ });
47
+ }
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerAgentCommands(program: Command): void;
@@ -0,0 +1,126 @@
1
+ import { getContext, getOutputOptions, getSelectedExchange } from "../../cli/program.js";
2
+ import { output, outputError } from "../../cli/output.js";
3
+ import { withJsonContract } from "../../lib/contracts.js";
4
+ import { createAgentGateway } from "../../lib/agent/gateway.js";
5
+ export function registerAgentCommands(program) {
6
+ const agent = program
7
+ .command("agent")
8
+ .description("Agent gateway controls and metadata");
9
+ agent
10
+ .command("serve")
11
+ .description("Start the HTTP agent gateway")
12
+ .option("--host <host>", "Bind host", process.env.PERPS_AGENT_HOST ?? "127.0.0.1")
13
+ .option("--port <port>", "Bind port", process.env.PERPS_AGENT_PORT ?? "4020")
14
+ .option("--allow-mainnet", "Allow mainnet execute requests")
15
+ .action(async function () {
16
+ const ctx = getContext(this);
17
+ const outputOpts = getOutputOptions(this);
18
+ const exchange = getSelectedExchange(this);
19
+ const opts = this.opts();
20
+ const port = Number.parseInt(opts.port, 10);
21
+ if (!Number.isFinite(port) || port <= 0 || port > 65535) {
22
+ throw new Error("port must be a valid integer between 1 and 65535");
23
+ }
24
+ const allowMainnet = opts.allowMainnet === true ||
25
+ process.env.PERPS_AGENT_ALLOW_MAINNET === "1";
26
+ const gateway = createAgentGateway({
27
+ host: opts.host,
28
+ port,
29
+ defaultExchange: exchange,
30
+ defaultTestnet: ctx.config.testnet,
31
+ allowMainnetExecution: allowMainnet,
32
+ });
33
+ await gateway.start();
34
+ const baseUrl = `http://${opts.host}:${port}`;
35
+ if (outputOpts.json) {
36
+ output(withJsonContract("agent.gateway.started", {
37
+ status: "running",
38
+ baseUrl,
39
+ defaultExchange: exchange,
40
+ defaultTestnet: ctx.config.testnet,
41
+ allowMainnetExecution: allowMainnet,
42
+ }), outputOpts);
43
+ }
44
+ else {
45
+ console.log("");
46
+ console.log(`Agent gateway running at ${baseUrl}`);
47
+ console.log(` GET ${baseUrl}/capabilities`);
48
+ console.log(` POST ${baseUrl}/quote`);
49
+ console.log(` POST ${baseUrl}/execute`);
50
+ console.log(` POST ${baseUrl}/acp/intent`);
51
+ console.log(``);
52
+ console.log("Press Ctrl+C to stop.");
53
+ console.log("");
54
+ }
55
+ await new Promise((resolve) => {
56
+ let stopping = false;
57
+ const shutdown = async () => {
58
+ if (stopping)
59
+ return;
60
+ stopping = true;
61
+ await gateway.stop().catch(() => { });
62
+ resolve();
63
+ };
64
+ process.once("SIGINT", () => {
65
+ void shutdown();
66
+ });
67
+ process.once("SIGTERM", () => {
68
+ void shutdown();
69
+ });
70
+ });
71
+ });
72
+ agent
73
+ .command("status")
74
+ .description("Check whether agent gateway is reachable")
75
+ .option("--host <host>", "Host", process.env.PERPS_AGENT_HOST ?? "127.0.0.1")
76
+ .option("--port <port>", "Port", process.env.PERPS_AGENT_PORT ?? "4020")
77
+ .action(async function () {
78
+ const outputOpts = getOutputOptions(this);
79
+ const opts = this.opts();
80
+ const baseUrl = `http://${opts.host}:${opts.port}`;
81
+ try {
82
+ const res = await fetch(`${baseUrl}/status`);
83
+ const payload = await res.json();
84
+ if (outputOpts.json) {
85
+ output(payload, outputOpts);
86
+ return;
87
+ }
88
+ output(`Gateway is reachable at ${baseUrl}`, outputOpts);
89
+ }
90
+ catch (err) {
91
+ if (outputOpts.json) {
92
+ output(withJsonContract("agent.gateway.status", {
93
+ status: "unreachable",
94
+ baseUrl,
95
+ error: err instanceof Error ? err.message : String(err),
96
+ }), outputOpts);
97
+ return;
98
+ }
99
+ outputError(`Gateway is not reachable at ${baseUrl}`);
100
+ }
101
+ });
102
+ agent
103
+ .command("manifest")
104
+ .description("Print endpoint summary for agent orchestration")
105
+ .option("--host <host>", "Host", process.env.PERPS_AGENT_HOST ?? "127.0.0.1")
106
+ .option("--port <port>", "Port", process.env.PERPS_AGENT_PORT ?? "4020")
107
+ .action(function () {
108
+ const outputOpts = getOutputOptions(this);
109
+ const opts = this.opts();
110
+ const baseUrl = `http://${opts.host}:${opts.port}`;
111
+ output(withJsonContract("agent.gateway.manifest", {
112
+ baseUrl,
113
+ endpoints: [
114
+ { method: "GET", path: "/capabilities" },
115
+ { method: "GET", path: "/status" },
116
+ { method: "GET", path: "/metrics" },
117
+ { method: "GET", path: "/reputation" },
118
+ { method: "POST", path: "/quote" },
119
+ { method: "POST", path: "/execute" },
120
+ { method: "POST", path: "/acp/intent" },
121
+ ],
122
+ paymentProtocol: "x402",
123
+ note: "POST /execute requires idempotencyKey and payment proof by default",
124
+ }), outputOpts);
125
+ });
126
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Arb Alert Command
3
+ * Set up alerts for funding rate arbitrage opportunities
4
+ */
5
+ import { Command } from "commander";
6
+ export declare function registerArbAlertCommand(arb: Command): void;
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Arb Alert Command
3
+ * Set up alerts for funding rate arbitrage opportunities
4
+ */
5
+ import { getContext } from "../../cli/program.js";
6
+ import { pollFundingRates } from "../../lib/funding-tracker.js";
7
+ import { getAvailableExchanges } from "../../lib/exchange.js";
8
+ import { COMMON_ASSETS, MIN_PROFITABLE_SPREAD_PCT, DEFAULT_ALERT_INTERVAL_MS } from "../../lib/constants.js";
9
+ import { parseAssetList, parsePositiveNumber, parsePositiveInt } from "../../lib/validate.js";
10
+ export function registerArbAlertCommand(arb) {
11
+ arb
12
+ .command("alert")
13
+ .description("Monitor for funding arbitrage opportunities")
14
+ .option("-a, --assets <assets>", "Comma-separated assets to monitor", "BTC,ETH,SOL")
15
+ .option("-t, --threshold <percent>", "Minimum annualized spread to alert on", String(MIN_PROFITABLE_SPREAD_PCT))
16
+ .option("-i, --interval <minutes>", "Check interval in minutes", String(DEFAULT_ALERT_INTERVAL_MS / 60000))
17
+ .action(async function () {
18
+ const ctx = getContext(this);
19
+ const opts = this.opts();
20
+ const config = {
21
+ assets: parseAssetList(opts.assets, COMMON_ASSETS.slice(0, 3)),
22
+ threshold: parsePositiveNumber(opts.threshold, "threshold", MIN_PROFITABLE_SPREAD_PCT),
23
+ intervalMin: parsePositiveInt(opts.interval, "interval", 5),
24
+ };
25
+ const exchanges = getAvailableExchanges();
26
+ const isTestnet = ctx.config.testnet;
27
+ console.log("\n \x1b[1mFunding Rate Alert Monitor\x1b[0m");
28
+ console.log(` Assets: ${config.assets.join(", ")}`);
29
+ console.log(` Threshold: ${config.threshold}% annualized`);
30
+ console.log(` Interval: ${config.intervalMin} minutes`);
31
+ console.log(` Exchanges: ${exchanges.join(", ")}`);
32
+ console.log("\n Monitoring... (Ctrl+C to stop)\n");
33
+ console.log(" " + "─".repeat(60));
34
+ // Check immediately
35
+ await checkAndAlert(config.assets, exchanges, config.threshold, isTestnet);
36
+ // Then check on interval
37
+ const interval = setInterval(async () => {
38
+ await checkAndAlert(config.assets, exchanges, config.threshold, isTestnet);
39
+ }, config.intervalMin * 60 * 1000);
40
+ // Handle Ctrl+C
41
+ process.once("SIGINT", () => {
42
+ clearInterval(interval);
43
+ console.log("\n\n Alert monitor stopped.\n");
44
+ process.exit(0);
45
+ });
46
+ // Keep running
47
+ await new Promise(() => { });
48
+ });
49
+ }
50
+ async function checkAndAlert(assets, exchanges, threshold, isTestnet) {
51
+ try {
52
+ const records = await pollFundingRates(assets, exchanges, undefined, isTestnet);
53
+ const now = new Date().toLocaleTimeString();
54
+ // Group by asset and find opportunities
55
+ const byAsset = new Map();
56
+ for (const r of records) {
57
+ const asset = r.market.replace("-PERP", "");
58
+ const existing = byAsset.get(asset) || [];
59
+ existing.push(r);
60
+ byAsset.set(asset, existing);
61
+ }
62
+ let foundAny = false;
63
+ for (const [asset, assetRecords] of byAsset) {
64
+ if (assetRecords.length < 2)
65
+ continue;
66
+ const sorted = [...assetRecords].sort((a, b) => b.rate - a.rate);
67
+ const high = sorted[0];
68
+ const low = sorted[sorted.length - 1];
69
+ const spread = high.rate - low.rate;
70
+ const annualized = spread * 24 * 365 * 100;
71
+ if (annualized >= threshold) {
72
+ foundAny = true;
73
+ const dailyOn10k = spread * 24 * 10000;
74
+ console.log(`\n \x1b[32m🔔 ${now} - ${asset} OPPORTUNITY\x1b[0m`);
75
+ console.log(` Short ${high.exchange} (${(high.rate * 100).toFixed(4)}%)`);
76
+ console.log(` Long ${low.exchange} (${(low.rate * 100).toFixed(4)}%)`);
77
+ console.log(` Spread: \x1b[32m${annualized.toFixed(1)}%\x1b[0m annualized (~$${dailyOn10k.toFixed(2)}/day on $10k)`);
78
+ // Could add external notifications here (Discord, Telegram, etc.)
79
+ }
80
+ }
81
+ if (!foundAny) {
82
+ process.stdout.write(`\r ${now} - No opportunities above ${threshold}%`);
83
+ }
84
+ }
85
+ catch (err) {
86
+ console.error(`\n \x1b[31mError:\x1b[0m ${err instanceof Error ? err.message : err}`);
87
+ }
88
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Arb Basis Execute Command
3
+ * Execute basis trades (cash-and-carry arbitrage) on a single exchange
4
+ */
5
+ import { Command } from "commander";
6
+ export declare function registerArbBasisExecuteCommand(arb: Command): void;