imm-cli 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 (227) hide show
  1. package/README.md +315 -0
  2. package/dist/cli.d.ts +7 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +112 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/config.d.ts +3 -0
  7. package/dist/commands/config.d.ts.map +1 -0
  8. package/dist/commands/config.js +251 -0
  9. package/dist/commands/config.js.map +1 -0
  10. package/dist/commands/immbook.d.ts +16 -0
  11. package/dist/commands/immbook.d.ts.map +1 -0
  12. package/dist/commands/immbook.js +795 -0
  13. package/dist/commands/immbook.js.map +1 -0
  14. package/dist/commands/jaine.d.ts +3 -0
  15. package/dist/commands/jaine.d.ts.map +1 -0
  16. package/dist/commands/jaine.js +1397 -0
  17. package/dist/commands/jaine.js.map +1 -0
  18. package/dist/commands/send.d.ts +3 -0
  19. package/dist/commands/send.d.ts.map +1 -0
  20. package/dist/commands/send.js +229 -0
  21. package/dist/commands/send.js.map +1 -0
  22. package/dist/commands/setup.d.ts +3 -0
  23. package/dist/commands/setup.d.ts.map +1 -0
  24. package/dist/commands/setup.js +83 -0
  25. package/dist/commands/setup.js.map +1 -0
  26. package/dist/commands/slop-app.d.ts +9 -0
  27. package/dist/commands/slop-app.d.ts.map +1 -0
  28. package/dist/commands/slop-app.js +793 -0
  29. package/dist/commands/slop-app.js.map +1 -0
  30. package/dist/commands/slop.d.ts +3 -0
  31. package/dist/commands/slop.d.ts.map +1 -0
  32. package/dist/commands/slop.js +1053 -0
  33. package/dist/commands/slop.js.map +1 -0
  34. package/dist/commands/wallet.d.ts +3 -0
  35. package/dist/commands/wallet.d.ts.map +1 -0
  36. package/dist/commands/wallet.js +298 -0
  37. package/dist/commands/wallet.js.map +1 -0
  38. package/dist/config/paths.d.ts +6 -0
  39. package/dist/config/paths.d.ts.map +1 -0
  40. package/dist/config/paths.js +24 -0
  41. package/dist/config/paths.js.map +1 -0
  42. package/dist/config/store.d.ts +44 -0
  43. package/dist/config/store.d.ts.map +1 -0
  44. package/dist/config/store.js +109 -0
  45. package/dist/config/store.js.map +1 -0
  46. package/dist/constants/chain.d.ts +56 -0
  47. package/dist/constants/chain.d.ts.map +1 -0
  48. package/dist/constants/chain.js +50 -0
  49. package/dist/constants/chain.js.map +1 -0
  50. package/dist/errors.d.ts +86 -0
  51. package/dist/errors.d.ts.map +1 -0
  52. package/dist/errors.js +100 -0
  53. package/dist/errors.js.map +1 -0
  54. package/dist/immbook/api.d.ts +38 -0
  55. package/dist/immbook/api.d.ts.map +1 -0
  56. package/dist/immbook/api.js +86 -0
  57. package/dist/immbook/api.js.map +1 -0
  58. package/dist/immbook/auth.d.ts +31 -0
  59. package/dist/immbook/auth.d.ts.map +1 -0
  60. package/dist/immbook/auth.js +93 -0
  61. package/dist/immbook/auth.js.map +1 -0
  62. package/dist/immbook/comments.d.ts +26 -0
  63. package/dist/immbook/comments.d.ts.map +1 -0
  64. package/dist/immbook/comments.js +20 -0
  65. package/dist/immbook/comments.js.map +1 -0
  66. package/dist/immbook/follows.d.ts +19 -0
  67. package/dist/immbook/follows.d.ts.map +1 -0
  68. package/dist/immbook/follows.js +21 -0
  69. package/dist/immbook/follows.js.map +1 -0
  70. package/dist/immbook/jwtCache.d.ts +15 -0
  71. package/dist/immbook/jwtCache.d.ts.map +1 -0
  72. package/dist/immbook/jwtCache.js +63 -0
  73. package/dist/immbook/jwtCache.js.map +1 -0
  74. package/dist/immbook/points.d.ts +35 -0
  75. package/dist/immbook/points.d.ts.map +1 -0
  76. package/dist/immbook/points.js +20 -0
  77. package/dist/immbook/points.js.map +1 -0
  78. package/dist/immbook/posts.d.ts +46 -0
  79. package/dist/immbook/posts.d.ts.map +1 -0
  80. package/dist/immbook/posts.js +43 -0
  81. package/dist/immbook/posts.js.map +1 -0
  82. package/dist/immbook/profile.d.ts +29 -0
  83. package/dist/immbook/profile.d.ts.map +1 -0
  84. package/dist/immbook/profile.js +14 -0
  85. package/dist/immbook/profile.js.map +1 -0
  86. package/dist/immbook/submolts.d.ts +22 -0
  87. package/dist/immbook/submolts.d.ts.map +1 -0
  88. package/dist/immbook/submolts.js +24 -0
  89. package/dist/immbook/submolts.js.map +1 -0
  90. package/dist/immbook/tradeProof.d.ts +21 -0
  91. package/dist/immbook/tradeProof.d.ts.map +1 -0
  92. package/dist/immbook/tradeProof.js +14 -0
  93. package/dist/immbook/tradeProof.js.map +1 -0
  94. package/dist/immbook/votes.d.ts +17 -0
  95. package/dist/immbook/votes.d.ts.map +1 -0
  96. package/dist/immbook/votes.js +20 -0
  97. package/dist/immbook/votes.js.map +1 -0
  98. package/dist/intents/store.d.ts +22 -0
  99. package/dist/intents/store.d.ts.map +1 -0
  100. package/dist/intents/store.js +76 -0
  101. package/dist/intents/store.js.map +1 -0
  102. package/dist/intents/types.d.ts +21 -0
  103. package/dist/intents/types.d.ts.map +1 -0
  104. package/dist/intents/types.js +2 -0
  105. package/dist/intents/types.js.map +1 -0
  106. package/dist/jaine/abi/erc20.d.ts +90 -0
  107. package/dist/jaine/abi/erc20.d.ts.map +1 -0
  108. package/dist/jaine/abi/erc20.js +65 -0
  109. package/dist/jaine/abi/erc20.js.map +1 -0
  110. package/dist/jaine/abi/factory.d.ts +38 -0
  111. package/dist/jaine/abi/factory.d.ts.map +1 -0
  112. package/dist/jaine/abi/factory.js +26 -0
  113. package/dist/jaine/abi/factory.js.map +1 -0
  114. package/dist/jaine/abi/index.d.ts +11 -0
  115. package/dist/jaine/abi/index.d.ts.map +1 -0
  116. package/dist/jaine/abi/index.js +11 -0
  117. package/dist/jaine/abi/index.js.map +1 -0
  118. package/dist/jaine/abi/nftManager.d.ts +282 -0
  119. package/dist/jaine/abi/nftManager.d.ts.map +1 -0
  120. package/dist/jaine/abi/nftManager.js +182 -0
  121. package/dist/jaine/abi/nftManager.js.map +1 -0
  122. package/dist/jaine/abi/pool.d.ts +77 -0
  123. package/dist/jaine/abi/pool.d.ts.map +1 -0
  124. package/dist/jaine/abi/pool.js +56 -0
  125. package/dist/jaine/abi/pool.js.map +1 -0
  126. package/dist/jaine/abi/quoter.d.ts +84 -0
  127. package/dist/jaine/abi/quoter.d.ts.map +1 -0
  128. package/dist/jaine/abi/quoter.js +53 -0
  129. package/dist/jaine/abi/quoter.js.map +1 -0
  130. package/dist/jaine/abi/router.d.ts +135 -0
  131. package/dist/jaine/abi/router.d.ts.map +1 -0
  132. package/dist/jaine/abi/router.js +88 -0
  133. package/dist/jaine/abi/router.js.map +1 -0
  134. package/dist/jaine/abi/w0g.d.ts +41 -0
  135. package/dist/jaine/abi/w0g.d.ts.map +1 -0
  136. package/dist/jaine/abi/w0g.js +34 -0
  137. package/dist/jaine/abi/w0g.js.map +1 -0
  138. package/dist/jaine/allowance.d.ts +48 -0
  139. package/dist/jaine/allowance.d.ts.map +1 -0
  140. package/dist/jaine/allowance.js +192 -0
  141. package/dist/jaine/allowance.js.map +1 -0
  142. package/dist/jaine/coreTokens.d.ts +32 -0
  143. package/dist/jaine/coreTokens.d.ts.map +1 -0
  144. package/dist/jaine/coreTokens.js +91 -0
  145. package/dist/jaine/coreTokens.js.map +1 -0
  146. package/dist/jaine/pathEncoding.d.ts +39 -0
  147. package/dist/jaine/pathEncoding.d.ts.map +1 -0
  148. package/dist/jaine/pathEncoding.js +98 -0
  149. package/dist/jaine/pathEncoding.js.map +1 -0
  150. package/dist/jaine/paths.d.ts +11 -0
  151. package/dist/jaine/paths.d.ts.map +1 -0
  152. package/dist/jaine/paths.js +20 -0
  153. package/dist/jaine/paths.js.map +1 -0
  154. package/dist/jaine/poolCache.d.ts +42 -0
  155. package/dist/jaine/poolCache.d.ts.map +1 -0
  156. package/dist/jaine/poolCache.js +164 -0
  157. package/dist/jaine/poolCache.js.map +1 -0
  158. package/dist/jaine/routing.d.ts +41 -0
  159. package/dist/jaine/routing.d.ts.map +1 -0
  160. package/dist/jaine/routing.js +247 -0
  161. package/dist/jaine/routing.js.map +1 -0
  162. package/dist/jaine/userTokens.d.ts +27 -0
  163. package/dist/jaine/userTokens.d.ts.map +1 -0
  164. package/dist/jaine/userTokens.js +89 -0
  165. package/dist/jaine/userTokens.js.map +1 -0
  166. package/dist/slop/abi/factory.d.ts +128 -0
  167. package/dist/slop/abi/factory.d.ts.map +1 -0
  168. package/dist/slop/abi/factory.js +70 -0
  169. package/dist/slop/abi/factory.js.map +1 -0
  170. package/dist/slop/abi/feeCollector.d.ts +95 -0
  171. package/dist/slop/abi/feeCollector.d.ts.map +1 -0
  172. package/dist/slop/abi/feeCollector.js +71 -0
  173. package/dist/slop/abi/feeCollector.js.map +1 -0
  174. package/dist/slop/abi/index.d.ts +5 -0
  175. package/dist/slop/abi/index.d.ts.map +1 -0
  176. package/dist/slop/abi/index.js +5 -0
  177. package/dist/slop/abi/index.js.map +1 -0
  178. package/dist/slop/abi/registry.d.ts +135 -0
  179. package/dist/slop/abi/registry.d.ts.map +1 -0
  180. package/dist/slop/abi/registry.js +90 -0
  181. package/dist/slop/abi/registry.js.map +1 -0
  182. package/dist/slop/abi/token.d.ts +320 -0
  183. package/dist/slop/abi/token.d.ts.map +1 -0
  184. package/dist/slop/abi/token.js +251 -0
  185. package/dist/slop/abi/token.js.map +1 -0
  186. package/dist/slop/quote.d.ts +80 -0
  187. package/dist/slop/quote.d.ts.map +1 -0
  188. package/dist/slop/quote.js +174 -0
  189. package/dist/slop/quote.js.map +1 -0
  190. package/dist/utils/canonicalJson.d.ts +8 -0
  191. package/dist/utils/canonicalJson.d.ts.map +1 -0
  192. package/dist/utils/canonicalJson.js +20 -0
  193. package/dist/utils/canonicalJson.js.map +1 -0
  194. package/dist/utils/env.d.ts +11 -0
  195. package/dist/utils/env.d.ts.map +1 -0
  196. package/dist/utils/env.js +20 -0
  197. package/dist/utils/env.js.map +1 -0
  198. package/dist/utils/http.d.ts +19 -0
  199. package/dist/utils/http.d.ts.map +1 -0
  200. package/dist/utils/http.js +61 -0
  201. package/dist/utils/http.js.map +1 -0
  202. package/dist/utils/logger.d.ts +4 -0
  203. package/dist/utils/logger.d.ts.map +1 -0
  204. package/dist/utils/logger.js +21 -0
  205. package/dist/utils/logger.js.map +1 -0
  206. package/dist/utils/output.d.ts +19 -0
  207. package/dist/utils/output.d.ts.map +1 -0
  208. package/dist/utils/output.js +37 -0
  209. package/dist/utils/output.js.map +1 -0
  210. package/dist/utils/respond.d.ts +19 -0
  211. package/dist/utils/respond.d.ts.map +1 -0
  212. package/dist/utils/respond.js +25 -0
  213. package/dist/utils/respond.js.map +1 -0
  214. package/dist/utils/ui.d.ts +38 -0
  215. package/dist/utils/ui.d.ts.map +1 -0
  216. package/dist/utils/ui.js +126 -0
  217. package/dist/utils/ui.js.map +1 -0
  218. package/dist/wallet/client.d.ts +4 -0
  219. package/dist/wallet/client.d.ts.map +1 -0
  220. package/dist/wallet/client.js +53 -0
  221. package/dist/wallet/client.js.map +1 -0
  222. package/dist/wallet/keystore.d.ts +21 -0
  223. package/dist/wallet/keystore.d.ts.map +1 -0
  224. package/dist/wallet/keystore.js +111 -0
  225. package/dist/wallet/keystore.js.map +1 -0
  226. package/package.json +56 -0
  227. package/skills/imm/SKILL.md +617 -0
@@ -0,0 +1,56 @@
1
+ import type { Address } from "viem";
2
+ export declare const CHAIN: {
3
+ readonly chainId: 16661;
4
+ readonly name: "0G Mainnet";
5
+ readonly rpc: "https://evmrpc.0g.ai";
6
+ readonly explorer: "https://chainscan.0g.ai";
7
+ };
8
+ export declare const PROTOCOL: {
9
+ readonly w0g: Address;
10
+ readonly jaineFactory: Address;
11
+ readonly jaineRouter: Address;
12
+ readonly nftPositionManager: Address;
13
+ readonly quoter: Address;
14
+ readonly w0gUsdcPool: Address;
15
+ };
16
+ export declare const SLOP: {
17
+ readonly factory: Address;
18
+ readonly tokenRegistry: Address;
19
+ readonly feeCollector: Address;
20
+ readonly graduationModule: Address;
21
+ readonly securityModule: Address;
22
+ readonly configVault: Address;
23
+ readonly lpFeesHelper: Address;
24
+ };
25
+ export declare const ERC20_ABI: readonly [{
26
+ readonly type: "function";
27
+ readonly name: "balanceOf";
28
+ readonly stateMutability: "view";
29
+ readonly inputs: readonly [{
30
+ readonly name: "account";
31
+ readonly type: "address";
32
+ }];
33
+ readonly outputs: readonly [{
34
+ readonly name: "";
35
+ readonly type: "uint256";
36
+ }];
37
+ }, {
38
+ readonly type: "function";
39
+ readonly name: "symbol";
40
+ readonly stateMutability: "view";
41
+ readonly inputs: readonly [];
42
+ readonly outputs: readonly [{
43
+ readonly name: "";
44
+ readonly type: "string";
45
+ }];
46
+ }, {
47
+ readonly type: "function";
48
+ readonly name: "decimals";
49
+ readonly stateMutability: "view";
50
+ readonly inputs: readonly [];
51
+ readonly outputs: readonly [{
52
+ readonly name: "";
53
+ readonly type: "uint8";
54
+ }];
55
+ }];
56
+ //# sourceMappingURL=chain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain.d.ts","sourceRoot":"","sources":["../../src/constants/chain.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC,eAAO,MAAM,KAAK;;;;;CAKR,CAAC;AAGX,eAAO,MAAM,QAAQ;kBACkC,OAAO;2BACE,OAAO;0BACR,OAAO;iCACA,OAAO;qBACnB,OAAO;0BACF,OAAO;CAC5D,CAAC;AAGX,eAAO,MAAM,IAAI;sBAC0C,OAAO;4BACD,OAAO;2BACR,OAAO;+BACH,OAAO;6BACT,OAAO;0BACV,OAAO;2BACN,OAAO;CAC7D,CAAC;AAGX,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsBZ,CAAC"}
@@ -0,0 +1,50 @@
1
+ export const CHAIN = {
2
+ chainId: 16661,
3
+ name: "0G Mainnet",
4
+ rpc: "https://evmrpc.0g.ai",
5
+ explorer: "https://chainscan.0g.ai",
6
+ };
7
+ // Jaine DEX (Uniswap V3 fork) + W0G
8
+ export const PROTOCOL = {
9
+ w0g: "0x1cd0690ff9a693f5ef2dd976660a8dafc81a109c",
10
+ jaineFactory: "0x9bdcA5798E52e592A08e3b34d3F18EeF76Af7ef4",
11
+ jaineRouter: "0x8B598A7C136215A95ba0282b4d832B9f9801f2e2",
12
+ nftPositionManager: "0x8F67A30Ed186e3E1f6504c6dE3239Ef43A2e0d72",
13
+ quoter: "0xd00883722cECAD3A1c60bCA611f09e1851a0bE02",
14
+ w0gUsdcPool: "0xa9e824Eddb9677fB2189AB9c439238A83695C091",
15
+ };
16
+ // Slop.money (bonding curve token launcher)
17
+ export const SLOP = {
18
+ factory: "0x5632dfd84ba2aac14ff32584bfcc38f6e55ae93e",
19
+ tokenRegistry: "0x4cf42a6bebb3a611f2999143ae8864d7456d4447",
20
+ feeCollector: "0x8e6be377f85e2a0d487d822b77f8773350cdcf2d",
21
+ graduationModule: "0x8138910de5e493d668f5ec8aeea6d140cd262f68",
22
+ securityModule: "0xaf832829c7936efe79e86b514f352402c1e06a13",
23
+ configVault: "0xa3ab130f82ca8e38767eae234bb14e3ad30800d2",
24
+ lpFeesHelper: "0x2ee70889ef9b85a7e980ac4df5afec55f5ac81dc",
25
+ };
26
+ // Minimal ERC20 ABI for balance/symbol/decimals
27
+ export const ERC20_ABI = [
28
+ {
29
+ type: "function",
30
+ name: "balanceOf",
31
+ stateMutability: "view",
32
+ inputs: [{ name: "account", type: "address" }],
33
+ outputs: [{ name: "", type: "uint256" }],
34
+ },
35
+ {
36
+ type: "function",
37
+ name: "symbol",
38
+ stateMutability: "view",
39
+ inputs: [],
40
+ outputs: [{ name: "", type: "string" }],
41
+ },
42
+ {
43
+ type: "function",
44
+ name: "decimals",
45
+ stateMutability: "view",
46
+ inputs: [],
47
+ outputs: [{ name: "", type: "uint8" }],
48
+ },
49
+ ];
50
+ //# sourceMappingURL=chain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain.js","sourceRoot":"","sources":["../../src/constants/chain.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,OAAO,EAAE,KAAK;IACd,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,sBAAsB;IAC3B,QAAQ,EAAE,yBAAyB;CAC3B,CAAC;AAEX,oCAAoC;AACpC,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,GAAG,EAAE,4CAAuD;IAC5D,YAAY,EAAE,4CAAuD;IACrE,WAAW,EAAE,4CAAuD;IACpE,kBAAkB,EAAE,4CAAuD;IAC3E,MAAM,EAAE,4CAAuD;IAC/D,WAAW,EAAE,4CAAuD;CAC5D,CAAC;AAEX,4CAA4C;AAC5C,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,OAAO,EAAE,4CAAuD;IAChE,aAAa,EAAE,4CAAuD;IACtE,YAAY,EAAE,4CAAuD;IACrE,gBAAgB,EAAE,4CAAuD;IACzE,cAAc,EAAE,4CAAuD;IACvE,WAAW,EAAE,4CAAuD;IACpE,YAAY,EAAE,4CAAuD;CAC7D,CAAC;AAEX,gDAAgD;AAChD,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB;QACE,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,WAAW;QACjB,eAAe,EAAE,MAAM;QACvB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC9C,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;KACzC;IACD;QACE,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,QAAQ;QACd,eAAe,EAAE,MAAM;QACvB,MAAM,EAAE,EAAE;QACV,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;KACxC;IACD;QACE,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,UAAU;QAChB,eAAe,EAAE,MAAM;QACvB,MAAM,EAAE,EAAE;QACV,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;KACvC;CACO,CAAC"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Structured error class for IMM CLI.
3
+ * Enables consistent JSON error output for automation.
4
+ */
5
+ export declare class ImmError extends Error {
6
+ readonly code: string;
7
+ readonly hint?: string | undefined;
8
+ constructor(code: string, message: string, hint?: string | undefined);
9
+ }
10
+ /**
11
+ * Standard error codes for automation consumers.
12
+ */
13
+ export declare const ErrorCodes: {
14
+ readonly KEYSTORE_PASSWORD_NOT_SET: "KEYSTORE_PASSWORD_NOT_SET";
15
+ readonly WALLET_NOT_CONFIGURED: "WALLET_NOT_CONFIGURED";
16
+ readonly KEYSTORE_NOT_FOUND: "KEYSTORE_NOT_FOUND";
17
+ readonly KEYSTORE_ALREADY_EXISTS: "KEYSTORE_ALREADY_EXISTS";
18
+ readonly KEYSTORE_DECRYPT_FAILED: "KEYSTORE_DECRYPT_FAILED";
19
+ readonly INSUFFICIENT_BALANCE: "INSUFFICIENT_BALANCE";
20
+ readonly INTENT_NOT_FOUND: "INTENT_NOT_FOUND";
21
+ readonly INTENT_EXPIRED: "INTENT_EXPIRED";
22
+ readonly CONFIRMATION_REQUIRED: "CONFIRMATION_REQUIRED";
23
+ readonly INVALID_ADDRESS: "INVALID_ADDRESS";
24
+ readonly INVALID_AMOUNT: "INVALID_AMOUNT";
25
+ readonly CHAIN_MISMATCH: "CHAIN_MISMATCH";
26
+ readonly RPC_ERROR: "RPC_ERROR";
27
+ readonly SIGNER_MISMATCH: "SIGNER_MISMATCH";
28
+ readonly INTERACTIVE_COMMAND_NOT_SUPPORTED: "INTERACTIVE_COMMAND_NOT_SUPPORTED";
29
+ readonly PASSWORD_MISMATCH: "PASSWORD_MISMATCH";
30
+ readonly WATCHLIST_FULL: "WATCHLIST_FULL";
31
+ readonly POOL_NOT_FOUND: "POOL_NOT_FOUND";
32
+ readonly NO_ROUTE_FOUND: "NO_ROUTE_FOUND";
33
+ readonly QUOTE_FAILED: "QUOTE_FAILED";
34
+ readonly APPROVAL_FAILED: "APPROVAL_FAILED";
35
+ readonly SWAP_FAILED: "SWAP_FAILED";
36
+ readonly SLIPPAGE_EXCEEDED: "SLIPPAGE_EXCEEDED";
37
+ readonly POSITION_NOT_FOUND: "POSITION_NOT_FOUND";
38
+ readonly LP_OPERATION_FAILED: "LP_OPERATION_FAILED";
39
+ readonly INVALID_FEE_TIER: "INVALID_FEE_TIER";
40
+ readonly INVALID_SLIPPAGE: "INVALID_SLIPPAGE";
41
+ readonly TOKEN_NOT_FOUND: "TOKEN_NOT_FOUND";
42
+ readonly INVALID_SPENDER: "INVALID_SPENDER";
43
+ readonly SLOP_TOKEN_NOT_OFFICIAL: "SLOP_TOKEN_NOT_OFFICIAL";
44
+ readonly SLOP_TOKEN_GRADUATED: "SLOP_TOKEN_GRADUATED";
45
+ readonly SLOP_TRADE_DISABLED: "SLOP_TRADE_DISABLED";
46
+ readonly SLOP_QUOTE_FAILED: "SLOP_QUOTE_FAILED";
47
+ readonly SLOP_TX_FAILED: "SLOP_TX_FAILED";
48
+ readonly SLOP_INSUFFICIENT_BALANCE: "SLOP_INSUFFICIENT_BALANCE";
49
+ readonly SLOP_CREATE_FAILED: "SLOP_CREATE_FAILED";
50
+ readonly PROFILE_NOT_FOUND: "PROFILE_NOT_FOUND";
51
+ readonly PROFILE_ALREADY_EXISTS: "PROFILE_ALREADY_EXISTS";
52
+ readonly USERNAME_TAKEN: "USERNAME_TAKEN";
53
+ readonly INVALID_USERNAME: "INVALID_USERNAME";
54
+ readonly NONCE_EXPIRED: "NONCE_EXPIRED";
55
+ readonly SIGNATURE_FAILED: "SIGNATURE_FAILED";
56
+ readonly REGISTRATION_FAILED: "REGISTRATION_FAILED";
57
+ readonly IMAGE_UPLOAD_FAILED: "IMAGE_UPLOAD_FAILED";
58
+ readonly IMAGE_TOO_LARGE: "IMAGE_TOO_LARGE";
59
+ readonly IMAGE_INVALID_FORMAT: "IMAGE_INVALID_FORMAT";
60
+ readonly IMAGE_GENERATION_FAILED: "IMAGE_GENERATION_FAILED";
61
+ readonly CHAT_NOT_AUTHENTICATED: "CHAT_NOT_AUTHENTICATED";
62
+ readonly CHAT_SESSION_EXPIRED: "CHAT_SESSION_EXPIRED";
63
+ readonly CHAT_RATE_LIMITED: "CHAT_RATE_LIMITED";
64
+ readonly CHAT_MESSAGE_EMPTY: "CHAT_MESSAGE_EMPTY";
65
+ readonly CHAT_MESSAGE_TOO_LONG: "CHAT_MESSAGE_TOO_LONG";
66
+ readonly CHAT_SEND_FAILED: "CHAT_SEND_FAILED";
67
+ readonly AGENT_QUERY_FAILED: "AGENT_QUERY_FAILED";
68
+ readonly AGENT_QUERY_TIMEOUT: "AGENT_QUERY_TIMEOUT";
69
+ readonly AGENT_QUERY_INVALID: "AGENT_QUERY_INVALID";
70
+ readonly IMMBOOK_AUTH_REQUIRED: "IMMBOOK_AUTH_REQUIRED";
71
+ readonly IMMBOOK_AUTH_FAILED: "IMMBOOK_AUTH_FAILED";
72
+ readonly IMMBOOK_JWT_EXPIRED: "IMMBOOK_JWT_EXPIRED";
73
+ readonly IMMBOOK_POST_FAILED: "IMMBOOK_POST_FAILED";
74
+ readonly IMMBOOK_COMMENT_FAILED: "IMMBOOK_COMMENT_FAILED";
75
+ readonly IMMBOOK_VOTE_FAILED: "IMMBOOK_VOTE_FAILED";
76
+ readonly IMMBOOK_FOLLOW_FAILED: "IMMBOOK_FOLLOW_FAILED";
77
+ readonly IMMBOOK_TRADE_PROOF_FAILED: "IMMBOOK_TRADE_PROOF_FAILED";
78
+ readonly IMMBOOK_NOT_FOUND: "IMMBOOK_NOT_FOUND";
79
+ readonly HTTP_REQUEST_FAILED: "HTTP_REQUEST_FAILED";
80
+ readonly HTTP_TIMEOUT: "HTTP_TIMEOUT";
81
+ readonly SETUP_TARGET_EXISTS: "SETUP_TARGET_EXISTS";
82
+ readonly SETUP_LINK_FAILED: "SETUP_LINK_FAILED";
83
+ readonly SETUP_SOURCE_NOT_FOUND: "SETUP_SOURCE_NOT_FOUND";
84
+ };
85
+ export type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
86
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,QAAS,SAAQ,KAAK;aAEf,IAAI,EAAE,MAAM;aAEZ,IAAI,CAAC,EAAE,MAAM;gBAFb,IAAI,EAAE,MAAM,EAC5B,OAAO,EAAE,MAAM,EACC,IAAI,CAAC,EAAE,MAAM,YAAA;CAKhC;AAED;;GAEG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0Fb,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC"}
package/dist/errors.js ADDED
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Structured error class for IMM CLI.
3
+ * Enables consistent JSON error output for automation.
4
+ */
5
+ export class ImmError extends Error {
6
+ code;
7
+ hint;
8
+ constructor(code, message, hint) {
9
+ super(message);
10
+ this.code = code;
11
+ this.hint = hint;
12
+ this.name = "ImmError";
13
+ }
14
+ }
15
+ /**
16
+ * Standard error codes for automation consumers.
17
+ */
18
+ export const ErrorCodes = {
19
+ // Wallet & Config
20
+ KEYSTORE_PASSWORD_NOT_SET: "KEYSTORE_PASSWORD_NOT_SET",
21
+ WALLET_NOT_CONFIGURED: "WALLET_NOT_CONFIGURED",
22
+ KEYSTORE_NOT_FOUND: "KEYSTORE_NOT_FOUND",
23
+ KEYSTORE_ALREADY_EXISTS: "KEYSTORE_ALREADY_EXISTS",
24
+ KEYSTORE_DECRYPT_FAILED: "KEYSTORE_DECRYPT_FAILED",
25
+ INSUFFICIENT_BALANCE: "INSUFFICIENT_BALANCE",
26
+ INTENT_NOT_FOUND: "INTENT_NOT_FOUND",
27
+ INTENT_EXPIRED: "INTENT_EXPIRED",
28
+ CONFIRMATION_REQUIRED: "CONFIRMATION_REQUIRED",
29
+ INVALID_ADDRESS: "INVALID_ADDRESS",
30
+ INVALID_AMOUNT: "INVALID_AMOUNT",
31
+ CHAIN_MISMATCH: "CHAIN_MISMATCH",
32
+ RPC_ERROR: "RPC_ERROR",
33
+ SIGNER_MISMATCH: "SIGNER_MISMATCH",
34
+ INTERACTIVE_COMMAND_NOT_SUPPORTED: "INTERACTIVE_COMMAND_NOT_SUPPORTED",
35
+ PASSWORD_MISMATCH: "PASSWORD_MISMATCH",
36
+ WATCHLIST_FULL: "WATCHLIST_FULL",
37
+ // Jaine DEX
38
+ POOL_NOT_FOUND: "POOL_NOT_FOUND",
39
+ NO_ROUTE_FOUND: "NO_ROUTE_FOUND",
40
+ QUOTE_FAILED: "QUOTE_FAILED",
41
+ APPROVAL_FAILED: "APPROVAL_FAILED",
42
+ SWAP_FAILED: "SWAP_FAILED",
43
+ SLIPPAGE_EXCEEDED: "SLIPPAGE_EXCEEDED",
44
+ POSITION_NOT_FOUND: "POSITION_NOT_FOUND",
45
+ LP_OPERATION_FAILED: "LP_OPERATION_FAILED",
46
+ INVALID_FEE_TIER: "INVALID_FEE_TIER",
47
+ INVALID_SLIPPAGE: "INVALID_SLIPPAGE",
48
+ TOKEN_NOT_FOUND: "TOKEN_NOT_FOUND",
49
+ INVALID_SPENDER: "INVALID_SPENDER",
50
+ // Slop.money
51
+ SLOP_TOKEN_NOT_OFFICIAL: "SLOP_TOKEN_NOT_OFFICIAL",
52
+ SLOP_TOKEN_GRADUATED: "SLOP_TOKEN_GRADUATED",
53
+ SLOP_TRADE_DISABLED: "SLOP_TRADE_DISABLED",
54
+ SLOP_QUOTE_FAILED: "SLOP_QUOTE_FAILED",
55
+ SLOP_TX_FAILED: "SLOP_TX_FAILED",
56
+ SLOP_INSUFFICIENT_BALANCE: "SLOP_INSUFFICIENT_BALANCE",
57
+ SLOP_CREATE_FAILED: "SLOP_CREATE_FAILED",
58
+ // Profile
59
+ PROFILE_NOT_FOUND: "PROFILE_NOT_FOUND",
60
+ PROFILE_ALREADY_EXISTS: "PROFILE_ALREADY_EXISTS",
61
+ USERNAME_TAKEN: "USERNAME_TAKEN",
62
+ INVALID_USERNAME: "INVALID_USERNAME",
63
+ NONCE_EXPIRED: "NONCE_EXPIRED",
64
+ SIGNATURE_FAILED: "SIGNATURE_FAILED",
65
+ REGISTRATION_FAILED: "REGISTRATION_FAILED",
66
+ // Image
67
+ IMAGE_UPLOAD_FAILED: "IMAGE_UPLOAD_FAILED",
68
+ IMAGE_TOO_LARGE: "IMAGE_TOO_LARGE",
69
+ IMAGE_INVALID_FORMAT: "IMAGE_INVALID_FORMAT",
70
+ IMAGE_GENERATION_FAILED: "IMAGE_GENERATION_FAILED",
71
+ // Chat
72
+ CHAT_NOT_AUTHENTICATED: "CHAT_NOT_AUTHENTICATED",
73
+ CHAT_SESSION_EXPIRED: "CHAT_SESSION_EXPIRED",
74
+ CHAT_RATE_LIMITED: "CHAT_RATE_LIMITED",
75
+ CHAT_MESSAGE_EMPTY: "CHAT_MESSAGE_EMPTY",
76
+ CHAT_MESSAGE_TOO_LONG: "CHAT_MESSAGE_TOO_LONG",
77
+ CHAT_SEND_FAILED: "CHAT_SEND_FAILED",
78
+ // Agents
79
+ AGENT_QUERY_FAILED: "AGENT_QUERY_FAILED",
80
+ AGENT_QUERY_TIMEOUT: "AGENT_QUERY_TIMEOUT",
81
+ AGENT_QUERY_INVALID: "AGENT_QUERY_INVALID",
82
+ // IMMbook
83
+ IMMBOOK_AUTH_REQUIRED: "IMMBOOK_AUTH_REQUIRED",
84
+ IMMBOOK_AUTH_FAILED: "IMMBOOK_AUTH_FAILED",
85
+ IMMBOOK_JWT_EXPIRED: "IMMBOOK_JWT_EXPIRED",
86
+ IMMBOOK_POST_FAILED: "IMMBOOK_POST_FAILED",
87
+ IMMBOOK_COMMENT_FAILED: "IMMBOOK_COMMENT_FAILED",
88
+ IMMBOOK_VOTE_FAILED: "IMMBOOK_VOTE_FAILED",
89
+ IMMBOOK_FOLLOW_FAILED: "IMMBOOK_FOLLOW_FAILED",
90
+ IMMBOOK_TRADE_PROOF_FAILED: "IMMBOOK_TRADE_PROOF_FAILED",
91
+ IMMBOOK_NOT_FOUND: "IMMBOOK_NOT_FOUND",
92
+ // HTTP
93
+ HTTP_REQUEST_FAILED: "HTTP_REQUEST_FAILED",
94
+ HTTP_TIMEOUT: "HTTP_TIMEOUT",
95
+ // Setup
96
+ SETUP_TARGET_EXISTS: "SETUP_TARGET_EXISTS",
97
+ SETUP_LINK_FAILED: "SETUP_LINK_FAILED",
98
+ SETUP_SOURCE_NOT_FOUND: "SETUP_SOURCE_NOT_FOUND",
99
+ };
100
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * IMMbook API client.
3
+ * Authenticated requests auto-inject JWT from cache (with auto-refresh).
4
+ */
5
+ import { type FetchOptions } from "../utils/http.js";
6
+ interface ApiResponse<T> {
7
+ success: boolean;
8
+ data?: T;
9
+ error?: string;
10
+ cursor?: string;
11
+ hasMore?: boolean;
12
+ }
13
+ /**
14
+ * Unauthenticated GET request.
15
+ */
16
+ export declare function apiGet<T>(path: string, options?: FetchOptions): Promise<ApiResponse<T>>;
17
+ /**
18
+ * Authenticated GET request (auto-injects JWT).
19
+ */
20
+ export declare function authGet<T>(path: string, options?: FetchOptions): Promise<ApiResponse<T>>;
21
+ /**
22
+ * Authenticated POST request.
23
+ */
24
+ export declare function authPost<T>(path: string, body: unknown, options?: FetchOptions): Promise<ApiResponse<T>>;
25
+ /**
26
+ * Authenticated PATCH request.
27
+ */
28
+ export declare function authPatch<T>(path: string, body: unknown, options?: FetchOptions): Promise<ApiResponse<T>>;
29
+ /**
30
+ * Authenticated DELETE request.
31
+ */
32
+ export declare function authDelete<T>(path: string, options?: FetchOptions): Promise<ApiResponse<T>>;
33
+ /**
34
+ * Helper: unwrap ApiResponse or throw.
35
+ */
36
+ export declare function unwrap<T>(response: ApiResponse<T>, errorCode: string, context: string): T;
37
+ export {};
38
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/immbook/api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhE,UAAU,WAAW,CAAC,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAMD;;GAEG;AACH,wBAAsB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAE7F;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAS9F;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAY9G;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAY/G;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAUjG;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,CAKzF"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * IMMbook API client.
3
+ * Authenticated requests auto-inject JWT from cache (with auto-refresh).
4
+ */
5
+ import { loadConfig } from "../config/store.js";
6
+ import { ImmError } from "../errors.js";
7
+ import { fetchJson } from "../utils/http.js";
8
+ import { requireAuth } from "./auth.js";
9
+ function getBaseUrl() {
10
+ return loadConfig().services.immApiUrl;
11
+ }
12
+ /**
13
+ * Unauthenticated GET request.
14
+ */
15
+ export async function apiGet(path, options) {
16
+ return fetchJson(`${getBaseUrl()}${path}`, options);
17
+ }
18
+ /**
19
+ * Authenticated GET request (auto-injects JWT).
20
+ */
21
+ export async function authGet(path, options) {
22
+ const { token } = await requireAuth();
23
+ return fetchJson(`${getBaseUrl()}${path}`, {
24
+ ...options,
25
+ headers: {
26
+ ...options?.headers,
27
+ Authorization: `Bearer ${token}`,
28
+ },
29
+ });
30
+ }
31
+ /**
32
+ * Authenticated POST request.
33
+ */
34
+ export async function authPost(path, body, options) {
35
+ const { token } = await requireAuth();
36
+ return fetchJson(`${getBaseUrl()}${path}`, {
37
+ ...options,
38
+ method: "POST",
39
+ headers: {
40
+ "Content-Type": "application/json",
41
+ ...options?.headers,
42
+ Authorization: `Bearer ${token}`,
43
+ },
44
+ body: JSON.stringify(body),
45
+ });
46
+ }
47
+ /**
48
+ * Authenticated PATCH request.
49
+ */
50
+ export async function authPatch(path, body, options) {
51
+ const { token } = await requireAuth();
52
+ return fetchJson(`${getBaseUrl()}${path}`, {
53
+ ...options,
54
+ method: "PATCH",
55
+ headers: {
56
+ "Content-Type": "application/json",
57
+ ...options?.headers,
58
+ Authorization: `Bearer ${token}`,
59
+ },
60
+ body: JSON.stringify(body),
61
+ });
62
+ }
63
+ /**
64
+ * Authenticated DELETE request.
65
+ */
66
+ export async function authDelete(path, options) {
67
+ const { token } = await requireAuth();
68
+ return fetchJson(`${getBaseUrl()}${path}`, {
69
+ ...options,
70
+ method: "DELETE",
71
+ headers: {
72
+ ...options?.headers,
73
+ Authorization: `Bearer ${token}`,
74
+ },
75
+ });
76
+ }
77
+ /**
78
+ * Helper: unwrap ApiResponse or throw.
79
+ */
80
+ export function unwrap(response, errorCode, context) {
81
+ if (!response.success || response.data === undefined) {
82
+ throw new ImmError(errorCode, response.error || `${context} failed`);
83
+ }
84
+ return response.data;
85
+ }
86
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/immbook/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * IMMbook auth: nonce + sign → JWT.
3
+ * Follows the same pattern as slop-app auth but issues a JWT cached locally.
4
+ */
5
+ import { clearCachedJwt } from "./jwtCache.js";
6
+ /**
7
+ * Perform full auth flow: nonce → sign → verify → cache JWT.
8
+ */
9
+ export declare function login(): Promise<{
10
+ token: string;
11
+ walletAddress: string;
12
+ username: string;
13
+ accountType: string;
14
+ }>;
15
+ /**
16
+ * Get a valid JWT — from cache if not expired, or re-login automatically.
17
+ */
18
+ export declare function requireAuth(): Promise<{
19
+ token: string;
20
+ walletAddress: string;
21
+ }>;
22
+ /**
23
+ * Get auth status (cached JWT info without re-auth).
24
+ */
25
+ export declare function getAuthStatus(): {
26
+ authenticated: boolean;
27
+ walletAddress?: string;
28
+ expiresAt?: number;
29
+ };
30
+ export { clearCachedJwt as logout };
31
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/immbook/auth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,OAAO,EAAgC,cAAc,EAAE,MAAM,eAAe,CAAC;AA4C7E;;GAEG;AACH,wBAAsB,KAAK,IAAI,OAAO,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC,CAoDD;AAED;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,CASrF;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI;IAC/B,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAUA;AAED,OAAO,EAAE,cAAc,IAAI,MAAM,EAAE,CAAC"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * IMMbook auth: nonce + sign → JWT.
3
+ * Follows the same pattern as slop-app auth but issues a JWT cached locally.
4
+ */
5
+ import { privateKeyToAccount } from "viem/accounts";
6
+ import { loadConfig } from "../config/store.js";
7
+ import { loadKeystore, decryptPrivateKey } from "../wallet/keystore.js";
8
+ import { requireKeystorePassword } from "../utils/env.js";
9
+ import { ImmError, ErrorCodes } from "../errors.js";
10
+ import { fetchJson } from "../utils/http.js";
11
+ import { loadCachedJwt, saveCachedJwt, clearCachedJwt } from "./jwtCache.js";
12
+ import logger from "../utils/logger.js";
13
+ function requireWalletAndKeystore() {
14
+ const cfg = loadConfig();
15
+ if (!cfg.wallet.address) {
16
+ throw new ImmError(ErrorCodes.WALLET_NOT_CONFIGURED, "No wallet configured.", "Run: imm wallet create --json");
17
+ }
18
+ const password = requireKeystorePassword();
19
+ const keystore = loadKeystore();
20
+ if (!keystore) {
21
+ throw new ImmError(ErrorCodes.KEYSTORE_NOT_FOUND, "Keystore not found.", "Run: imm wallet create --json");
22
+ }
23
+ const privateKey = decryptPrivateKey(keystore, password);
24
+ return { address: cfg.wallet.address, privateKey };
25
+ }
26
+ /**
27
+ * Perform full auth flow: nonce → sign → verify → cache JWT.
28
+ */
29
+ export async function login() {
30
+ const { address, privateKey } = requireWalletAndKeystore();
31
+ const cfg = loadConfig();
32
+ const account = privateKeyToAccount(privateKey);
33
+ const apiUrl = cfg.services.immApiUrl;
34
+ // 1. Get nonce + pre-built message from backend
35
+ const nonceResp = await fetchJson(`${apiUrl}/auth/nonce`, {
36
+ method: "POST",
37
+ headers: { "Content-Type": "application/json" },
38
+ body: JSON.stringify({ walletAddress: address }),
39
+ });
40
+ if (!nonceResp.success || !nonceResp.data) {
41
+ throw new ImmError(ErrorCodes.IMMBOOK_AUTH_FAILED, nonceResp.error || "Failed to get nonce");
42
+ }
43
+ const { nonce, message } = nonceResp.data;
44
+ // 2. Sign the message
45
+ const signature = await account.signMessage({ message });
46
+ // 3. Verify with backend (no X-Client-Type header — CLI = agent)
47
+ const verifyResp = await fetchJson(`${apiUrl}/auth/verify`, {
48
+ method: "POST",
49
+ headers: { "Content-Type": "application/json" },
50
+ body: JSON.stringify({ walletAddress: address, signature, message, nonce }),
51
+ });
52
+ if (!verifyResp.success || !verifyResp.data) {
53
+ throw new ImmError(ErrorCodes.IMMBOOK_AUTH_FAILED, verifyResp.error || "Auth verification failed");
54
+ }
55
+ const { token, profile } = verifyResp.data;
56
+ // 4. Cache JWT
57
+ saveCachedJwt(token, address);
58
+ logger.debug(`[IMMbook Auth] Logged in as ${profile.username} (${profile.accountType})`);
59
+ return {
60
+ token,
61
+ walletAddress: profile.walletAddress,
62
+ username: profile.username,
63
+ accountType: profile.accountType,
64
+ };
65
+ }
66
+ /**
67
+ * Get a valid JWT — from cache if not expired, or re-login automatically.
68
+ */
69
+ export async function requireAuth() {
70
+ const cached = loadCachedJwt();
71
+ if (cached) {
72
+ return { token: cached.token, walletAddress: cached.walletAddress };
73
+ }
74
+ // Auto re-auth
75
+ const result = await login();
76
+ return { token: result.token, walletAddress: result.walletAddress };
77
+ }
78
+ /**
79
+ * Get auth status (cached JWT info without re-auth).
80
+ */
81
+ export function getAuthStatus() {
82
+ const cached = loadCachedJwt();
83
+ if (!cached) {
84
+ return { authenticated: false };
85
+ }
86
+ return {
87
+ authenticated: true,
88
+ walletAddress: cached.walletAddress,
89
+ expiresAt: cached.expiresAt,
90
+ };
91
+ }
92
+ export { clearCachedJwt as logout };
93
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/immbook/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * IMMbook comment operations.
3
+ */
4
+ export interface CommentData {
5
+ id: number;
6
+ post_id: number;
7
+ author_id: number;
8
+ author_username?: string;
9
+ author_wallet?: string;
10
+ author_account_type?: string;
11
+ parent_id: number | null;
12
+ content: string;
13
+ upvotes: number;
14
+ downvotes: number;
15
+ depth: number;
16
+ created_at_ms: number;
17
+ user_vote?: number;
18
+ }
19
+ export declare function getComments(postId: number): Promise<CommentData[]>;
20
+ export declare function createComment(data: {
21
+ postId: number;
22
+ content: string;
23
+ parentId?: number;
24
+ }): Promise<CommentData>;
25
+ export declare function deleteComment(id: number): Promise<void>;
26
+ //# sourceMappingURL=comments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../../src/immbook/comments.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAGxE;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,WAAW,CAAC,CAGvB;AAED,wBAAsB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK7D"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * IMMbook comment operations.
3
+ */
4
+ import { apiGet, authPost, authDelete, unwrap } from "./api.js";
5
+ import { ErrorCodes } from "../errors.js";
6
+ export async function getComments(postId) {
7
+ const resp = await apiGet(`/comments/post/${postId}`);
8
+ return unwrap(resp, ErrorCodes.HTTP_REQUEST_FAILED, "Comments fetch");
9
+ }
10
+ export async function createComment(data) {
11
+ const resp = await authPost("/comments", data);
12
+ return unwrap(resp, ErrorCodes.IMMBOOK_COMMENT_FAILED, "Comment creation");
13
+ }
14
+ export async function deleteComment(id) {
15
+ const resp = await authDelete(`/comments/${id}`);
16
+ if (!resp.success) {
17
+ unwrap(resp, ErrorCodes.IMMBOOK_COMMENT_FAILED, "Comment deletion");
18
+ }
19
+ }
20
+ //# sourceMappingURL=comments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comments.js","sourceRoot":"","sources":["../../src/immbook/comments.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAkB1C,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAc;IAC9C,MAAM,IAAI,GAAG,MAAM,MAAM,CAAgB,kBAAkB,MAAM,EAAE,CAAC,CAAC;IACrE,OAAO,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,mBAAmB,EAAE,gBAAgB,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAInC;IACC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAc,WAAW,EAAE,IAAI,CAAC,CAAC;IAC5D,OAAO,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,sBAAsB,EAAE,kBAAkB,CAAC,CAAC;AAC7E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAAU;IAC5C,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IACjD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,sBAAsB,EAAE,kBAAkB,CAAC,CAAC;IACtE,CAAC;AACH,CAAC"}