forgex-cli 1.0.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 (275) hide show
  1. package/README.md +479 -0
  2. package/dist/bin/forgex.d.ts +12 -0
  3. package/dist/bin/forgex.d.ts.map +1 -0
  4. package/dist/bin/forgex.js +23 -0
  5. package/dist/bin/forgex.js.map +1 -0
  6. package/dist/src/adapters/codex-adapter.d.ts +238 -0
  7. package/dist/src/adapters/codex-adapter.d.ts.map +1 -0
  8. package/dist/src/adapters/codex-adapter.js +524 -0
  9. package/dist/src/adapters/codex-adapter.js.map +1 -0
  10. package/dist/src/adapters/connection.d.ts +20 -0
  11. package/dist/src/adapters/connection.d.ts.map +1 -0
  12. package/dist/src/adapters/connection.js +43 -0
  13. package/dist/src/adapters/connection.js.map +1 -0
  14. package/dist/src/adapters/ipfs.d.ts +17 -0
  15. package/dist/src/adapters/ipfs.d.ts.map +1 -0
  16. package/dist/src/adapters/ipfs.js +30 -0
  17. package/dist/src/adapters/ipfs.js.map +1 -0
  18. package/dist/src/adapters/jito-adapter.d.ts +194 -0
  19. package/dist/src/adapters/jito-adapter.d.ts.map +1 -0
  20. package/dist/src/adapters/jito-adapter.js +474 -0
  21. package/dist/src/adapters/jito-adapter.js.map +1 -0
  22. package/dist/src/adapters/rpc-adapter.d.ts +148 -0
  23. package/dist/src/adapters/rpc-adapter.d.ts.map +1 -0
  24. package/dist/src/adapters/rpc-adapter.js +410 -0
  25. package/dist/src/adapters/rpc-adapter.js.map +1 -0
  26. package/dist/src/adapters/sdk-adapter.d.ts +148 -0
  27. package/dist/src/adapters/sdk-adapter.d.ts.map +1 -0
  28. package/dist/src/adapters/sdk-adapter.js +554 -0
  29. package/dist/src/adapters/sdk-adapter.js.map +1 -0
  30. package/dist/src/commands/config/index.d.ts +8 -0
  31. package/dist/src/commands/config/index.d.ts.map +1 -0
  32. package/dist/src/commands/config/index.js +91 -0
  33. package/dist/src/commands/config/index.js.map +1 -0
  34. package/dist/src/commands/query/index.d.ts +10 -0
  35. package/dist/src/commands/query/index.d.ts.map +1 -0
  36. package/dist/src/commands/query/index.js +376 -0
  37. package/dist/src/commands/query/index.js.map +1 -0
  38. package/dist/src/commands/sniper/index.d.ts +16 -0
  39. package/dist/src/commands/sniper/index.d.ts.map +1 -0
  40. package/dist/src/commands/sniper/index.js +292 -0
  41. package/dist/src/commands/sniper/index.js.map +1 -0
  42. package/dist/src/commands/token/index.d.ts +16 -0
  43. package/dist/src/commands/token/index.d.ts.map +1 -0
  44. package/dist/src/commands/token/index.js +295 -0
  45. package/dist/src/commands/token/index.js.map +1 -0
  46. package/dist/src/commands/tools/index.d.ts +17 -0
  47. package/dist/src/commands/tools/index.d.ts.map +1 -0
  48. package/dist/src/commands/tools/index.js +626 -0
  49. package/dist/src/commands/tools/index.js.map +1 -0
  50. package/dist/src/commands/trade/index.d.ts +8 -0
  51. package/dist/src/commands/trade/index.d.ts.map +1 -0
  52. package/dist/src/commands/trade/index.js +531 -0
  53. package/dist/src/commands/trade/index.js.map +1 -0
  54. package/dist/src/commands/transfer/index.d.ts +16 -0
  55. package/dist/src/commands/transfer/index.d.ts.map +1 -0
  56. package/dist/src/commands/transfer/index.js +509 -0
  57. package/dist/src/commands/transfer/index.js.map +1 -0
  58. package/dist/src/commands/wallet/index.d.ts +10 -0
  59. package/dist/src/commands/wallet/index.d.ts.map +1 -0
  60. package/dist/src/commands/wallet/index.js +828 -0
  61. package/dist/src/commands/wallet/index.js.map +1 -0
  62. package/dist/src/config.d.ts +74 -0
  63. package/dist/src/config.d.ts.map +1 -0
  64. package/dist/src/config.js +190 -0
  65. package/dist/src/config.js.map +1 -0
  66. package/dist/src/const/IDL/index.d.ts +4 -0
  67. package/dist/src/const/IDL/index.d.ts.map +1 -0
  68. package/dist/src/const/IDL/index.js +2 -0
  69. package/dist/src/const/IDL/index.js.map +1 -0
  70. package/dist/src/const/IDL/meteora-DLMM.d.ts +10249 -0
  71. package/dist/src/const/IDL/meteora-DLMM.d.ts.map +1 -0
  72. package/dist/src/const/IDL/meteora-DLMM.js +4177 -0
  73. package/dist/src/const/IDL/meteora-DLMM.js.map +1 -0
  74. package/dist/src/const/IDL/pump-fun.d.ts +4811 -0
  75. package/dist/src/const/IDL/pump-fun.d.ts.map +1 -0
  76. package/dist/src/const/IDL/pump-fun.js +2954 -0
  77. package/dist/src/const/IDL/pump-fun.js.map +1 -0
  78. package/dist/src/const/IDL/pump-swap-IDL.d.ts +3119 -0
  79. package/dist/src/const/IDL/pump-swap-IDL.d.ts.map +1 -0
  80. package/dist/src/const/IDL/pump-swap-IDL.js +2095 -0
  81. package/dist/src/const/IDL/pump-swap-IDL.js.map +1 -0
  82. package/dist/src/const/IDL/raydium-launchlab-IDL.d.ts +4031 -0
  83. package/dist/src/const/IDL/raydium-launchlab-IDL.d.ts.map +1 -0
  84. package/dist/src/const/IDL/raydium-launchlab-IDL.js +2110 -0
  85. package/dist/src/const/IDL/raydium-launchlab-IDL.js.map +1 -0
  86. package/dist/src/const/index.d.ts +40 -0
  87. package/dist/src/const/index.d.ts.map +1 -0
  88. package/dist/src/const/index.js +57 -0
  89. package/dist/src/const/index.js.map +1 -0
  90. package/dist/src/data-source.d.ts +270 -0
  91. package/dist/src/data-source.d.ts.map +1 -0
  92. package/dist/src/data-source.js +628 -0
  93. package/dist/src/data-source.js.map +1 -0
  94. package/dist/src/data-store/index.d.ts +87 -0
  95. package/dist/src/data-store/index.d.ts.map +1 -0
  96. package/dist/src/data-store/index.js +561 -0
  97. package/dist/src/data-store/index.js.map +1 -0
  98. package/dist/src/data-store/types.d.ts +91 -0
  99. package/dist/src/data-store/types.d.ts.map +1 -0
  100. package/dist/src/data-store/types.js +8 -0
  101. package/dist/src/data-store/types.js.map +1 -0
  102. package/dist/src/index.d.ts +8 -0
  103. package/dist/src/index.d.ts.map +1 -0
  104. package/dist/src/index.js +36 -0
  105. package/dist/src/index.js.map +1 -0
  106. package/dist/src/output.d.ts +52 -0
  107. package/dist/src/output.d.ts.map +1 -0
  108. package/dist/src/output.js +218 -0
  109. package/dist/src/output.js.map +1 -0
  110. package/dist/src/shims/store.d.ts +58 -0
  111. package/dist/src/shims/store.d.ts.map +1 -0
  112. package/dist/src/shims/store.js +55 -0
  113. package/dist/src/shims/store.js.map +1 -0
  114. package/dist/src/sol-sdk/account/index.d.ts +13 -0
  115. package/dist/src/sol-sdk/account/index.d.ts.map +1 -0
  116. package/dist/src/sol-sdk/account/index.js +174 -0
  117. package/dist/src/sol-sdk/account/index.js.map +1 -0
  118. package/dist/src/sol-sdk/account/lookupTable.d.ts +24 -0
  119. package/dist/src/sol-sdk/account/lookupTable.d.ts.map +1 -0
  120. package/dist/src/sol-sdk/account/lookupTable.js +103 -0
  121. package/dist/src/sol-sdk/account/lookupTable.js.map +1 -0
  122. package/dist/src/sol-sdk/batch/create.d.ts +23 -0
  123. package/dist/src/sol-sdk/batch/create.d.ts.map +1 -0
  124. package/dist/src/sol-sdk/batch/create.js +580 -0
  125. package/dist/src/sol-sdk/batch/create.js.map +1 -0
  126. package/dist/src/sol-sdk/batch/external-sniper.d.ts +31 -0
  127. package/dist/src/sol-sdk/batch/external-sniper.d.ts.map +1 -0
  128. package/dist/src/sol-sdk/batch/external-sniper.js +163 -0
  129. package/dist/src/sol-sdk/batch/external-sniper.js.map +1 -0
  130. package/dist/src/sol-sdk/batch/index.d.ts +144 -0
  131. package/dist/src/sol-sdk/batch/index.d.ts.map +1 -0
  132. package/dist/src/sol-sdk/batch/index.js +1573 -0
  133. package/dist/src/sol-sdk/batch/index.js.map +1 -0
  134. package/dist/src/sol-sdk/calc.d.ts +277 -0
  135. package/dist/src/sol-sdk/calc.d.ts.map +1 -0
  136. package/dist/src/sol-sdk/calc.js +590 -0
  137. package/dist/src/sol-sdk/calc.js.map +1 -0
  138. package/dist/src/sol-sdk/index.d.ts +1 -0
  139. package/dist/src/sol-sdk/index.d.ts.map +1 -0
  140. package/dist/src/sol-sdk/index.js +1 -0
  141. package/dist/src/sol-sdk/index.js.map +1 -0
  142. package/dist/src/sol-sdk/jito/index.d.ts +50 -0
  143. package/dist/src/sol-sdk/jito/index.d.ts.map +1 -0
  144. package/dist/src/sol-sdk/jito/index.js +225 -0
  145. package/dist/src/sol-sdk/jito/index.js.map +1 -0
  146. package/dist/src/sol-sdk/launchlab/index.d.ts +32 -0
  147. package/dist/src/sol-sdk/launchlab/index.d.ts.map +1 -0
  148. package/dist/src/sol-sdk/launchlab/index.js +78 -0
  149. package/dist/src/sol-sdk/launchlab/index.js.map +1 -0
  150. package/dist/src/sol-sdk/launchlab/instructions/buy.d.ts +27 -0
  151. package/dist/src/sol-sdk/launchlab/instructions/buy.d.ts.map +1 -0
  152. package/dist/src/sol-sdk/launchlab/instructions/buy.js +124 -0
  153. package/dist/src/sol-sdk/launchlab/instructions/buy.js.map +1 -0
  154. package/dist/src/sol-sdk/launchlab/instructions/create.d.ts +27 -0
  155. package/dist/src/sol-sdk/launchlab/instructions/create.d.ts.map +1 -0
  156. package/dist/src/sol-sdk/launchlab/instructions/create.js +125 -0
  157. package/dist/src/sol-sdk/launchlab/instructions/create.js.map +1 -0
  158. package/dist/src/sol-sdk/launchlab/instructions/sell.d.ts +15 -0
  159. package/dist/src/sol-sdk/launchlab/instructions/sell.d.ts.map +1 -0
  160. package/dist/src/sol-sdk/launchlab/instructions/sell.js +65 -0
  161. package/dist/src/sol-sdk/launchlab/instructions/sell.js.map +1 -0
  162. package/dist/src/sol-sdk/meteora/index.d.ts +32 -0
  163. package/dist/src/sol-sdk/meteora/index.d.ts.map +1 -0
  164. package/dist/src/sol-sdk/meteora/index.js +72 -0
  165. package/dist/src/sol-sdk/meteora/index.js.map +1 -0
  166. package/dist/src/sol-sdk/meteora/instructions/buy.d.ts +46 -0
  167. package/dist/src/sol-sdk/meteora/instructions/buy.d.ts.map +1 -0
  168. package/dist/src/sol-sdk/meteora/instructions/buy.js +153 -0
  169. package/dist/src/sol-sdk/meteora/instructions/buy.js.map +1 -0
  170. package/dist/src/sol-sdk/meteora/instructions/sell.d.ts +24 -0
  171. package/dist/src/sol-sdk/meteora/instructions/sell.d.ts.map +1 -0
  172. package/dist/src/sol-sdk/meteora/instructions/sell.js +98 -0
  173. package/dist/src/sol-sdk/meteora/instructions/sell.js.map +1 -0
  174. package/dist/src/sol-sdk/pump/index.d.ts +22 -0
  175. package/dist/src/sol-sdk/pump/index.d.ts.map +1 -0
  176. package/dist/src/sol-sdk/pump/index.js +101 -0
  177. package/dist/src/sol-sdk/pump/index.js.map +1 -0
  178. package/dist/src/sol-sdk/pump/instructions/buy.d.ts +29 -0
  179. package/dist/src/sol-sdk/pump/instructions/buy.d.ts.map +1 -0
  180. package/dist/src/sol-sdk/pump/instructions/buy.js +131 -0
  181. package/dist/src/sol-sdk/pump/instructions/buy.js.map +1 -0
  182. package/dist/src/sol-sdk/pump/instructions/createAndBuy.d.ts +36 -0
  183. package/dist/src/sol-sdk/pump/instructions/createAndBuy.d.ts.map +1 -0
  184. package/dist/src/sol-sdk/pump/instructions/createAndBuy.js +77 -0
  185. package/dist/src/sol-sdk/pump/instructions/createAndBuy.js.map +1 -0
  186. package/dist/src/sol-sdk/pump/instructions/sell.d.ts +7 -0
  187. package/dist/src/sol-sdk/pump/instructions/sell.d.ts.map +1 -0
  188. package/dist/src/sol-sdk/pump/instructions/sell.js +38 -0
  189. package/dist/src/sol-sdk/pump/instructions/sell.js.map +1 -0
  190. package/dist/src/sol-sdk/pumpswap/index.d.ts +9 -0
  191. package/dist/src/sol-sdk/pumpswap/index.d.ts.map +1 -0
  192. package/dist/src/sol-sdk/pumpswap/index.js +27 -0
  193. package/dist/src/sol-sdk/pumpswap/index.js.map +1 -0
  194. package/dist/src/sol-sdk/pumpswap/instructions/buy.d.ts +61 -0
  195. package/dist/src/sol-sdk/pumpswap/instructions/buy.d.ts.map +1 -0
  196. package/dist/src/sol-sdk/pumpswap/instructions/buy.js +215 -0
  197. package/dist/src/sol-sdk/pumpswap/instructions/buy.js.map +1 -0
  198. package/dist/src/sol-sdk/pumpswap/instructions/migrate.d.ts +3 -0
  199. package/dist/src/sol-sdk/pumpswap/instructions/migrate.d.ts.map +1 -0
  200. package/dist/src/sol-sdk/pumpswap/instructions/migrate.js +33 -0
  201. package/dist/src/sol-sdk/pumpswap/instructions/migrate.js.map +1 -0
  202. package/dist/src/sol-sdk/pumpswap/instructions/sell.d.ts +20 -0
  203. package/dist/src/sol-sdk/pumpswap/instructions/sell.d.ts.map +1 -0
  204. package/dist/src/sol-sdk/pumpswap/instructions/sell.js +107 -0
  205. package/dist/src/sol-sdk/pumpswap/instructions/sell.js.map +1 -0
  206. package/dist/src/sol-sdk/pumpswap/rpc/index.d.ts +28 -0
  207. package/dist/src/sol-sdk/pumpswap/rpc/index.d.ts.map +1 -0
  208. package/dist/src/sol-sdk/pumpswap/rpc/index.js +63 -0
  209. package/dist/src/sol-sdk/pumpswap/rpc/index.js.map +1 -0
  210. package/dist/src/sol-sdk/raydium/index.d.ts +16 -0
  211. package/dist/src/sol-sdk/raydium/index.d.ts.map +1 -0
  212. package/dist/src/sol-sdk/raydium/index.js +47 -0
  213. package/dist/src/sol-sdk/raydium/index.js.map +1 -0
  214. package/dist/src/sol-sdk/raydium/instructions/buy.d.ts +29 -0
  215. package/dist/src/sol-sdk/raydium/instructions/buy.d.ts.map +1 -0
  216. package/dist/src/sol-sdk/raydium/instructions/buy.js +106 -0
  217. package/dist/src/sol-sdk/raydium/instructions/buy.js.map +1 -0
  218. package/dist/src/sol-sdk/raydium/instructions/cpmmBuy.d.ts +29 -0
  219. package/dist/src/sol-sdk/raydium/instructions/cpmmBuy.d.ts.map +1 -0
  220. package/dist/src/sol-sdk/raydium/instructions/cpmmBuy.js +80 -0
  221. package/dist/src/sol-sdk/raydium/instructions/cpmmBuy.js.map +1 -0
  222. package/dist/src/sol-sdk/raydium/instructions/cpmmSell.d.ts +17 -0
  223. package/dist/src/sol-sdk/raydium/instructions/cpmmSell.d.ts.map +1 -0
  224. package/dist/src/sol-sdk/raydium/instructions/cpmmSell.js +56 -0
  225. package/dist/src/sol-sdk/raydium/instructions/cpmmSell.js.map +1 -0
  226. package/dist/src/sol-sdk/raydium/instructions/sell.d.ts +8558 -0
  227. package/dist/src/sol-sdk/raydium/instructions/sell.d.ts.map +1 -0
  228. package/dist/src/sol-sdk/raydium/instructions/sell.js +70 -0
  229. package/dist/src/sol-sdk/raydium/instructions/sell.js.map +1 -0
  230. package/dist/src/sol-sdk/raydium/rpc/index.d.ts +39 -0
  231. package/dist/src/sol-sdk/raydium/rpc/index.d.ts.map +1 -0
  232. package/dist/src/sol-sdk/raydium/rpc/index.js +82 -0
  233. package/dist/src/sol-sdk/raydium/rpc/index.js.map +1 -0
  234. package/dist/src/sol-sdk/raydium/rpc/raydium.d.ts +5 -0
  235. package/dist/src/sol-sdk/raydium/rpc/raydium.d.ts.map +1 -0
  236. package/dist/src/sol-sdk/raydium/rpc/raydium.js +18 -0
  237. package/dist/src/sol-sdk/raydium/rpc/raydium.js.map +1 -0
  238. package/dist/src/sol-sdk/rpc/index.d.ts +33 -0
  239. package/dist/src/sol-sdk/rpc/index.d.ts.map +1 -0
  240. package/dist/src/sol-sdk/rpc/index.js +128 -0
  241. package/dist/src/sol-sdk/rpc/index.js.map +1 -0
  242. package/dist/src/sol-sdk/transfer/index.d.ts +24 -0
  243. package/dist/src/sol-sdk/transfer/index.d.ts.map +1 -0
  244. package/dist/src/sol-sdk/transfer/index.js +65 -0
  245. package/dist/src/sol-sdk/transfer/index.js.map +1 -0
  246. package/dist/src/sol-sdk/turnover/index.d.ts +84 -0
  247. package/dist/src/sol-sdk/turnover/index.d.ts.map +1 -0
  248. package/dist/src/sol-sdk/turnover/index.js +569 -0
  249. package/dist/src/sol-sdk/turnover/index.js.map +1 -0
  250. package/dist/src/tx-tracker/detail-adapter.d.ts +100 -0
  251. package/dist/src/tx-tracker/detail-adapter.d.ts.map +1 -0
  252. package/dist/src/tx-tracker/detail-adapter.js +215 -0
  253. package/dist/src/tx-tracker/detail-adapter.js.map +1 -0
  254. package/dist/src/tx-tracker/index.d.ts +142 -0
  255. package/dist/src/tx-tracker/index.d.ts.map +1 -0
  256. package/dist/src/tx-tracker/index.js +447 -0
  257. package/dist/src/tx-tracker/index.js.map +1 -0
  258. package/dist/src/types/index.d.ts +76 -0
  259. package/dist/src/types/index.d.ts.map +1 -0
  260. package/dist/src/types/index.js +69 -0
  261. package/dist/src/types/index.js.map +1 -0
  262. package/dist/src/types/websocket.d.ts +15 -0
  263. package/dist/src/types/websocket.d.ts.map +1 -0
  264. package/dist/src/types/websocket.js +18 -0
  265. package/dist/src/types/websocket.js.map +1 -0
  266. package/dist/src/utils/index.d.ts +13 -0
  267. package/dist/src/utils/index.d.ts.map +1 -0
  268. package/dist/src/utils/index.js +174 -0
  269. package/dist/src/utils/index.js.map +1 -0
  270. package/dist/src/wallet-store.d.ts +124 -0
  271. package/dist/src/wallet-store.d.ts.map +1 -0
  272. package/dist/src/wallet-store.js +524 -0
  273. package/dist/src/wallet-store.js.map +1 -0
  274. package/package.json +86 -0
  275. package/scripts/postinstall.js +88 -0
@@ -0,0 +1,87 @@
1
+ /**
2
+ * ForgeX CLI DataStore -- 全文件存储系统
3
+ *
4
+ * 按 ARCH-DESIGN-v2.md Section 1 设计实现。
5
+ * 所有 CLI 数据通过本地 JSON 文件存储,供 OpenClaw Agent 统一读写上下文。
6
+ *
7
+ * 目录结构:
8
+ * ~/.forgex/data/
9
+ * ├── tokens/<CA>/
10
+ * │ ├── token-info.json
11
+ * │ ├── pool-info.json
12
+ * │ └── groups/<groupId>/
13
+ * │ ├── transactions.json
14
+ * │ ├── holdings.json
15
+ * │ └── balances.json
16
+ * └── global/
17
+ * ├── sol-price.json
18
+ * └── fee-config.json
19
+ *
20
+ * 特性:
21
+ * - 原子写入 (先写 .tmp 再 rename)
22
+ * - 进程内文件锁 (防止同一进程内并发写入冲突)
23
+ * - 内存缓存 (减少磁盘 IO)
24
+ * - JSON 格式,人类可读
25
+ */
26
+ import type { TokenInfoFile, PoolInfoFile, TransactionsFile, TransactionRecord, HoldingsFile, WalletHolding, BalancesFile, WalletBalance, FeeConfigFile } from './types.js';
27
+ export type { TokenInfoFile, PoolInfoFile, TransactionsFile, TransactionRecord, HoldingsFile, WalletHolding, BalancesFile, WalletBalance, SolPriceFile, FeeConfigFile, } from './types.js';
28
+ export declare class DataStore {
29
+ private basePath;
30
+ private lock;
31
+ private cache;
32
+ constructor(basePath?: string);
33
+ /** 校验 CA 参数不能为空且不含路径穿越字符 */
34
+ private validateCA;
35
+ private tokensDir;
36
+ private tokenDir;
37
+ private groupDir;
38
+ private globalDir;
39
+ private tokenInfoPath;
40
+ private poolInfoPath;
41
+ private transactionsPath;
42
+ private holdingsPath;
43
+ private balancesPath;
44
+ private solPricePath;
45
+ private feeConfigPath;
46
+ /** 确保代币目录存在 */
47
+ ensureTokenDir(ca: string): void;
48
+ /** 确保钱包组目录存在 */
49
+ ensureGroupDir(ca: string, groupId: number): void;
50
+ /** 确保全局数据目录存在 */
51
+ private ensureGlobalDir;
52
+ getTokenInfo(ca: string): TokenInfoFile | null;
53
+ saveTokenInfo(ca: string, info: TokenInfoFile): Promise<void>;
54
+ getPoolInfo(ca: string): PoolInfoFile | null;
55
+ savePoolInfo(ca: string, info: PoolInfoFile): Promise<void>;
56
+ getTransactions(ca: string, groupId: number): TransactionsFile | null;
57
+ appendTransaction(ca: string, groupId: number, tx: TransactionRecord): Promise<void>;
58
+ getTransactionsByWallet(ca: string, groupId: number, wallet: string): TransactionRecord[];
59
+ getHoldings(ca: string, groupId: number): HoldingsFile | null;
60
+ updateHolding(ca: string, groupId: number, wallet: string, update: Partial<WalletHolding>): Promise<void>;
61
+ getBalances(ca: string, groupId: number): BalancesFile | null;
62
+ updateBalance(ca: string, groupId: number, wallet: string, balance: WalletBalance): Promise<void>;
63
+ /**
64
+ * 批量更新余额。
65
+ * 一次性更新多个钱包的余额,减少文件 IO 次数。
66
+ */
67
+ updateBalancesBatch(ca: string, groupId: number, balances: WalletBalance[]): Promise<void>;
68
+ getSolPrice(): number;
69
+ saveSolPrice(price: number): Promise<void>;
70
+ getFeeConfig(): FeeConfigFile | null;
71
+ saveFeeConfig(config: FeeConfigFile): Promise<void>;
72
+ /** 列出所有有数据的代币 CA */
73
+ listTokens(): string[];
74
+ /** 列出某个代币下所有有数据的 groupId */
75
+ listGroups(ca: string): number[];
76
+ /** 清除全部内存缓存 */
77
+ clearCache(): void;
78
+ /** 清除某个代币相关的缓存 */
79
+ clearTokenCache(ca: string): void;
80
+ /** 获取数据根目录路径 */
81
+ getBasePath(): string;
82
+ }
83
+ /** 获取全局 DataStore 单例 */
84
+ export declare function getDataStore(): DataStore;
85
+ /** 创建自定义路径的 DataStore(主要用于测试) */
86
+ export declare function createDataStore(basePath: string): DataStore;
87
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/data-store/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,561 @@
1
+ /**
2
+ * ForgeX CLI DataStore -- 全文件存储系统
3
+ *
4
+ * 按 ARCH-DESIGN-v2.md Section 1 设计实现。
5
+ * 所有 CLI 数据通过本地 JSON 文件存储,供 OpenClaw Agent 统一读写上下文。
6
+ *
7
+ * 目录结构:
8
+ * ~/.forgex/data/
9
+ * ├── tokens/<CA>/
10
+ * │ ├── token-info.json
11
+ * │ ├── pool-info.json
12
+ * │ └── groups/<groupId>/
13
+ * │ ├── transactions.json
14
+ * │ ├── holdings.json
15
+ * │ └── balances.json
16
+ * └── global/
17
+ * ├── sol-price.json
18
+ * └── fee-config.json
19
+ *
20
+ * 特性:
21
+ * - 原子写入 (先写 .tmp 再 rename)
22
+ * - 进程内文件锁 (防止同一进程内并发写入冲突)
23
+ * - 内存缓存 (减少磁盘 IO)
24
+ * - JSON 格式,人类可读
25
+ */
26
+ import fs from 'fs';
27
+ import path from 'path';
28
+ import { FORGEX_DIR } from '../config.js';
29
+ // ============================================================
30
+ // 原子写入
31
+ // ============================================================
32
+ /**
33
+ * 原子写入 JSON 文件。
34
+ * 先写入 .tmp 临时文件,再 rename 覆盖目标文件。
35
+ * 防止写入中断导致文件损坏。
36
+ */
37
+ function atomicWriteJson(filePath, data) {
38
+ const dir = path.dirname(filePath);
39
+ if (!fs.existsSync(dir)) {
40
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
41
+ }
42
+ const tmpPath = `${filePath}.tmp`;
43
+ fs.writeFileSync(tmpPath, JSON.stringify(data, null, 2), {
44
+ encoding: 'utf-8',
45
+ mode: 0o600,
46
+ });
47
+ fs.renameSync(tmpPath, filePath);
48
+ }
49
+ /**
50
+ * 安全读取 JSON 文件。
51
+ * 文件不存在时返回 null,解析失败时返回 null 并输出警告。
52
+ */
53
+ function readJson(filePath) {
54
+ if (!fs.existsSync(filePath)) {
55
+ return null;
56
+ }
57
+ try {
58
+ const raw = fs.readFileSync(filePath, 'utf-8');
59
+ return JSON.parse(raw);
60
+ }
61
+ catch (err) {
62
+ console.error(`DataStore: 读取文件失败 ${filePath}:`, err);
63
+ return null;
64
+ }
65
+ }
66
+ // ============================================================
67
+ // 进程内文件锁
68
+ // ============================================================
69
+ /**
70
+ * 简单的进程内锁,防止同一进程内并发写入同一文件。
71
+ * CLI 为单进程模型,不需要跨进程锁。
72
+ */
73
+ class FileLock {
74
+ locks = new Map();
75
+ /**
76
+ * 获取指定文件路径的锁,执行操作后自动释放。
77
+ */
78
+ async withLock(filePath, fn) {
79
+ // 等待该文件的现有锁释放
80
+ while (this.locks.has(filePath)) {
81
+ await this.locks.get(filePath);
82
+ }
83
+ let resolve;
84
+ const lockPromise = new Promise(r => {
85
+ resolve = r;
86
+ });
87
+ this.locks.set(filePath, lockPromise);
88
+ try {
89
+ return await fn();
90
+ }
91
+ finally {
92
+ this.locks.delete(filePath);
93
+ resolve();
94
+ }
95
+ }
96
+ }
97
+ class MemoryCache {
98
+ cache = new Map();
99
+ /** 缓存过期时间 (ms),默认 30 秒 */
100
+ ttlMs;
101
+ constructor(ttlMs = 30_000) {
102
+ this.ttlMs = ttlMs;
103
+ }
104
+ get(key) {
105
+ const entry = this.cache.get(key);
106
+ if (!entry)
107
+ return undefined;
108
+ // 过期检查
109
+ if (Date.now() - entry.loadedAt > this.ttlMs) {
110
+ this.cache.delete(key);
111
+ return undefined;
112
+ }
113
+ return entry.data;
114
+ }
115
+ set(key, data) {
116
+ this.cache.set(key, { data, loadedAt: Date.now() });
117
+ }
118
+ invalidate(key) {
119
+ this.cache.delete(key);
120
+ }
121
+ /** 清除以指定前缀开头的所有缓存 */
122
+ invalidatePrefix(prefix) {
123
+ for (const key of this.cache.keys()) {
124
+ if (key.startsWith(prefix)) {
125
+ this.cache.delete(key);
126
+ }
127
+ }
128
+ }
129
+ clear() {
130
+ this.cache.clear();
131
+ }
132
+ }
133
+ // ============================================================
134
+ // DataStore
135
+ // ============================================================
136
+ export class DataStore {
137
+ basePath;
138
+ lock;
139
+ cache;
140
+ constructor(basePath) {
141
+ this.basePath = basePath || path.join(FORGEX_DIR, 'data');
142
+ this.lock = new FileLock();
143
+ this.cache = new MemoryCache();
144
+ }
145
+ // ----------------------------------------------------------
146
+ // 输入校验
147
+ // ----------------------------------------------------------
148
+ /** 校验 CA 参数不能为空且不含路径穿越字符 */
149
+ validateCA(ca) {
150
+ if (!ca || ca.trim() === '') {
151
+ throw new Error('DataStore: CA (contract address) cannot be empty');
152
+ }
153
+ if (ca.includes('/') || ca.includes('\\') || ca.includes('..') || ca.includes('\0')) {
154
+ throw new Error('DataStore: CA contains invalid characters');
155
+ }
156
+ }
157
+ // ----------------------------------------------------------
158
+ // 路径构建
159
+ // ----------------------------------------------------------
160
+ tokensDir() {
161
+ return path.join(this.basePath, 'tokens');
162
+ }
163
+ tokenDir(ca) {
164
+ return path.join(this.tokensDir(), ca);
165
+ }
166
+ groupDir(ca, groupId) {
167
+ return path.join(this.tokenDir(ca), 'groups', String(groupId));
168
+ }
169
+ globalDir() {
170
+ return path.join(this.basePath, 'global');
171
+ }
172
+ tokenInfoPath(ca) {
173
+ return path.join(this.tokenDir(ca), 'token-info.json');
174
+ }
175
+ poolInfoPath(ca) {
176
+ return path.join(this.tokenDir(ca), 'pool-info.json');
177
+ }
178
+ transactionsPath(ca, groupId) {
179
+ return path.join(this.groupDir(ca, groupId), 'transactions.json');
180
+ }
181
+ holdingsPath(ca, groupId) {
182
+ return path.join(this.groupDir(ca, groupId), 'holdings.json');
183
+ }
184
+ balancesPath(ca, groupId) {
185
+ return path.join(this.groupDir(ca, groupId), 'balances.json');
186
+ }
187
+ solPricePath() {
188
+ return path.join(this.globalDir(), 'sol-price.json');
189
+ }
190
+ feeConfigPath() {
191
+ return path.join(this.globalDir(), 'fee-config.json');
192
+ }
193
+ // ----------------------------------------------------------
194
+ // 目录管理
195
+ // ----------------------------------------------------------
196
+ /** 确保代币目录存在 */
197
+ ensureTokenDir(ca) {
198
+ this.validateCA(ca);
199
+ const dir = this.tokenDir(ca);
200
+ if (!fs.existsSync(dir)) {
201
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
202
+ }
203
+ }
204
+ /** 确保钱包组目录存在 */
205
+ ensureGroupDir(ca, groupId) {
206
+ this.validateCA(ca);
207
+ const dir = this.groupDir(ca, groupId);
208
+ if (!fs.existsSync(dir)) {
209
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
210
+ }
211
+ }
212
+ /** 确保全局数据目录存在 */
213
+ ensureGlobalDir() {
214
+ const dir = this.globalDir();
215
+ if (!fs.existsSync(dir)) {
216
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
217
+ }
218
+ }
219
+ // ----------------------------------------------------------
220
+ // Token Info
221
+ // ----------------------------------------------------------
222
+ getTokenInfo(ca) {
223
+ this.validateCA(ca);
224
+ const cacheKey = `token-info:${ca}`;
225
+ const cached = this.cache.get(cacheKey);
226
+ if (cached)
227
+ return cached;
228
+ const data = readJson(this.tokenInfoPath(ca));
229
+ if (data) {
230
+ this.cache.set(cacheKey, data);
231
+ }
232
+ return data;
233
+ }
234
+ async saveTokenInfo(ca, info) {
235
+ this.validateCA(ca);
236
+ const filePath = this.tokenInfoPath(ca);
237
+ await this.lock.withLock(filePath, () => {
238
+ this.ensureTokenDir(ca);
239
+ atomicWriteJson(filePath, info);
240
+ this.cache.set(`token-info:${ca}`, info);
241
+ });
242
+ }
243
+ // ----------------------------------------------------------
244
+ // Pool Info
245
+ // ----------------------------------------------------------
246
+ getPoolInfo(ca) {
247
+ this.validateCA(ca);
248
+ const cacheKey = `pool-info:${ca}`;
249
+ const cached = this.cache.get(cacheKey);
250
+ if (cached)
251
+ return cached;
252
+ const data = readJson(this.poolInfoPath(ca));
253
+ if (data) {
254
+ this.cache.set(cacheKey, data);
255
+ }
256
+ return data;
257
+ }
258
+ async savePoolInfo(ca, info) {
259
+ this.validateCA(ca);
260
+ const filePath = this.poolInfoPath(ca);
261
+ await this.lock.withLock(filePath, () => {
262
+ this.ensureTokenDir(ca);
263
+ atomicWriteJson(filePath, info);
264
+ this.cache.set(`pool-info:${ca}`, info);
265
+ });
266
+ }
267
+ // ----------------------------------------------------------
268
+ // Transactions
269
+ // ----------------------------------------------------------
270
+ getTransactions(ca, groupId) {
271
+ this.validateCA(ca);
272
+ const cacheKey = `transactions:${ca}:${groupId}`;
273
+ const cached = this.cache.get(cacheKey);
274
+ if (cached)
275
+ return cached;
276
+ const data = readJson(this.transactionsPath(ca, groupId));
277
+ if (data) {
278
+ this.cache.set(cacheKey, data);
279
+ }
280
+ return data;
281
+ }
282
+ async appendTransaction(ca, groupId, tx) {
283
+ this.validateCA(ca);
284
+ const filePath = this.transactionsPath(ca, groupId);
285
+ await this.lock.withLock(filePath, () => {
286
+ this.ensureGroupDir(ca, groupId);
287
+ // 从磁盘读取最新数据(绕过缓存,确保不丢数据)
288
+ let file = readJson(filePath);
289
+ if (!file) {
290
+ file = {
291
+ ca,
292
+ groupId,
293
+ transactions: [],
294
+ updatedAt: Date.now(),
295
+ };
296
+ }
297
+ // 去重:同一 txHash 不重复追加
298
+ const exists = file.transactions.some(t => t.txHash === tx.txHash);
299
+ if (!exists) {
300
+ file.transactions.push(tx);
301
+ }
302
+ file.updatedAt = Date.now();
303
+ atomicWriteJson(filePath, file);
304
+ // 更新缓存
305
+ this.cache.set(`transactions:${ca}:${groupId}`, file);
306
+ });
307
+ }
308
+ getTransactionsByWallet(ca, groupId, wallet) {
309
+ // Note: validateCA is called inside getTransactions
310
+ const file = this.getTransactions(ca, groupId);
311
+ if (!file)
312
+ return [];
313
+ return file.transactions.filter(tx => tx.walletAddress === wallet);
314
+ }
315
+ // ----------------------------------------------------------
316
+ // Holdings
317
+ // ----------------------------------------------------------
318
+ getHoldings(ca, groupId) {
319
+ this.validateCA(ca);
320
+ const cacheKey = `holdings:${ca}:${groupId}`;
321
+ const cached = this.cache.get(cacheKey);
322
+ if (cached)
323
+ return cached;
324
+ const data = readJson(this.holdingsPath(ca, groupId));
325
+ if (data) {
326
+ this.cache.set(cacheKey, data);
327
+ }
328
+ return data;
329
+ }
330
+ async updateHolding(ca, groupId, wallet, update) {
331
+ this.validateCA(ca);
332
+ const filePath = this.holdingsPath(ca, groupId);
333
+ await this.lock.withLock(filePath, () => {
334
+ this.ensureGroupDir(ca, groupId);
335
+ let file = readJson(filePath);
336
+ if (!file) {
337
+ file = {
338
+ ca,
339
+ groupId,
340
+ wallets: [],
341
+ updatedAt: Date.now(),
342
+ };
343
+ }
344
+ const idx = file.wallets.findIndex(w => w.walletAddress === wallet);
345
+ if (idx >= 0) {
346
+ // 合并更新
347
+ file.wallets[idx] = { ...file.wallets[idx], ...update };
348
+ }
349
+ else {
350
+ // 新增钱包持仓
351
+ const newHolding = {
352
+ walletAddress: wallet,
353
+ tokenBalance: 0,
354
+ avgBuyPrice: 0,
355
+ totalBought: 0,
356
+ totalSold: 0,
357
+ totalCostSol: 0,
358
+ totalRevenueSol: 0,
359
+ realizedPnl: 0,
360
+ unrealizedPnl: 0,
361
+ ...update,
362
+ };
363
+ file.wallets.push(newHolding);
364
+ }
365
+ file.updatedAt = Date.now();
366
+ atomicWriteJson(filePath, file);
367
+ this.cache.set(`holdings:${ca}:${groupId}`, file);
368
+ });
369
+ }
370
+ // ----------------------------------------------------------
371
+ // Balances
372
+ // ----------------------------------------------------------
373
+ getBalances(ca, groupId) {
374
+ this.validateCA(ca);
375
+ const cacheKey = `balances:${ca}:${groupId}`;
376
+ const cached = this.cache.get(cacheKey);
377
+ if (cached)
378
+ return cached;
379
+ const data = readJson(this.balancesPath(ca, groupId));
380
+ if (data) {
381
+ this.cache.set(cacheKey, data);
382
+ }
383
+ return data;
384
+ }
385
+ async updateBalance(ca, groupId, wallet, balance) {
386
+ this.validateCA(ca);
387
+ const filePath = this.balancesPath(ca, groupId);
388
+ await this.lock.withLock(filePath, () => {
389
+ this.ensureGroupDir(ca, groupId);
390
+ let file = readJson(filePath);
391
+ if (!file) {
392
+ file = {
393
+ ca,
394
+ groupId,
395
+ balances: [],
396
+ updatedAt: Date.now(),
397
+ };
398
+ }
399
+ const idx = file.balances.findIndex(b => b.walletAddress === wallet);
400
+ if (idx >= 0) {
401
+ file.balances[idx] = balance;
402
+ }
403
+ else {
404
+ file.balances.push(balance);
405
+ }
406
+ file.updatedAt = Date.now();
407
+ atomicWriteJson(filePath, file);
408
+ this.cache.set(`balances:${ca}:${groupId}`, file);
409
+ });
410
+ }
411
+ /**
412
+ * 批量更新余额。
413
+ * 一次性更新多个钱包的余额,减少文件 IO 次数。
414
+ */
415
+ async updateBalancesBatch(ca, groupId, balances) {
416
+ this.validateCA(ca);
417
+ const filePath = this.balancesPath(ca, groupId);
418
+ await this.lock.withLock(filePath, () => {
419
+ this.ensureGroupDir(ca, groupId);
420
+ let file = readJson(filePath);
421
+ if (!file) {
422
+ file = {
423
+ ca,
424
+ groupId,
425
+ balances: [],
426
+ updatedAt: Date.now(),
427
+ };
428
+ }
429
+ for (const balance of balances) {
430
+ const idx = file.balances.findIndex(b => b.walletAddress === balance.walletAddress);
431
+ if (idx >= 0) {
432
+ file.balances[idx] = balance;
433
+ }
434
+ else {
435
+ file.balances.push(balance);
436
+ }
437
+ }
438
+ file.updatedAt = Date.now();
439
+ atomicWriteJson(filePath, file);
440
+ this.cache.set(`balances:${ca}:${groupId}`, file);
441
+ });
442
+ }
443
+ // ----------------------------------------------------------
444
+ // Global -- SOL Price
445
+ // ----------------------------------------------------------
446
+ getSolPrice() {
447
+ const cacheKey = 'global:sol-price';
448
+ const cached = this.cache.get(cacheKey);
449
+ if (cached)
450
+ return cached.priceUsd;
451
+ const data = readJson(this.solPricePath());
452
+ if (data) {
453
+ this.cache.set(cacheKey, data);
454
+ return data.priceUsd;
455
+ }
456
+ return 0;
457
+ }
458
+ async saveSolPrice(price) {
459
+ const filePath = this.solPricePath();
460
+ await this.lock.withLock(filePath, () => {
461
+ this.ensureGlobalDir();
462
+ const data = {
463
+ priceUsd: price,
464
+ updatedAt: Date.now(),
465
+ };
466
+ atomicWriteJson(filePath, data);
467
+ this.cache.set('global:sol-price', data);
468
+ });
469
+ }
470
+ // ----------------------------------------------------------
471
+ // Global -- Fee Config
472
+ // ----------------------------------------------------------
473
+ getFeeConfig() {
474
+ const cacheKey = 'global:fee-config';
475
+ const cached = this.cache.get(cacheKey);
476
+ if (cached)
477
+ return cached;
478
+ const data = readJson(this.feeConfigPath());
479
+ if (data) {
480
+ this.cache.set(cacheKey, data);
481
+ }
482
+ return data;
483
+ }
484
+ async saveFeeConfig(config) {
485
+ const filePath = this.feeConfigPath();
486
+ await this.lock.withLock(filePath, () => {
487
+ this.ensureGlobalDir();
488
+ atomicWriteJson(filePath, config);
489
+ this.cache.set('global:fee-config', config);
490
+ });
491
+ }
492
+ // ----------------------------------------------------------
493
+ // Utility
494
+ // ----------------------------------------------------------
495
+ /** 列出所有有数据的代币 CA */
496
+ listTokens() {
497
+ const dir = this.tokensDir();
498
+ if (!fs.existsSync(dir))
499
+ return [];
500
+ try {
501
+ return fs
502
+ .readdirSync(dir, { withFileTypes: true })
503
+ .filter(entry => entry.isDirectory())
504
+ .map(entry => entry.name);
505
+ }
506
+ catch {
507
+ return [];
508
+ }
509
+ }
510
+ /** 列出某个代币下所有有数据的 groupId */
511
+ listGroups(ca) {
512
+ this.validateCA(ca);
513
+ const groupsDir = path.join(this.tokenDir(ca), 'groups');
514
+ if (!fs.existsSync(groupsDir))
515
+ return [];
516
+ try {
517
+ return fs
518
+ .readdirSync(groupsDir, { withFileTypes: true })
519
+ .filter(entry => entry.isDirectory())
520
+ .map(entry => parseInt(entry.name, 10))
521
+ .filter(id => !isNaN(id))
522
+ .sort((a, b) => a - b);
523
+ }
524
+ catch {
525
+ return [];
526
+ }
527
+ }
528
+ /** 清除全部内存缓存 */
529
+ clearCache() {
530
+ this.cache.clear();
531
+ }
532
+ /** 清除某个代币相关的缓存 */
533
+ clearTokenCache(ca) {
534
+ this.validateCA(ca);
535
+ this.cache.invalidatePrefix(`token-info:${ca}`);
536
+ this.cache.invalidatePrefix(`pool-info:${ca}`);
537
+ this.cache.invalidatePrefix(`transactions:${ca}`);
538
+ this.cache.invalidatePrefix(`holdings:${ca}`);
539
+ this.cache.invalidatePrefix(`balances:${ca}`);
540
+ }
541
+ /** 获取数据根目录路径 */
542
+ getBasePath() {
543
+ return this.basePath;
544
+ }
545
+ }
546
+ // ============================================================
547
+ // 单例
548
+ // ============================================================
549
+ let _instance = null;
550
+ /** 获取全局 DataStore 单例 */
551
+ export function getDataStore() {
552
+ if (!_instance) {
553
+ _instance = new DataStore();
554
+ }
555
+ return _instance;
556
+ }
557
+ /** 创建自定义路径的 DataStore(主要用于测试) */
558
+ export function createDataStore(basePath) {
559
+ return new DataStore(basePath);
560
+ }
561
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/data-store/index.ts"],"names":[],"mappings":"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"}