@jinn-network/client 0.1.1 → 0.1.2-canary.d6e72dfd

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 (317) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/CONTRIBUTING.md +123 -0
  3. package/README.md +210 -37
  4. package/deployments/deployment-claim-registry-baseSepolia.json +13 -0
  5. package/deployments/deployment-jinn-testnet-faucet-baseSepolia-fast.json +15 -0
  6. package/dist/adapters/claim-registry/abi.d.ts +127 -0
  7. package/dist/adapters/claim-registry/abi.js +93 -0
  8. package/dist/adapters/claim-registry/abi.js.map +1 -0
  9. package/dist/adapters/claim-registry/client.d.ts +89 -0
  10. package/dist/adapters/claim-registry/client.js +205 -0
  11. package/dist/adapters/claim-registry/client.js.map +1 -0
  12. package/dist/adapters/mech/adapter.d.ts +1 -0
  13. package/dist/adapters/mech/adapter.js +75 -41
  14. package/dist/adapters/mech/adapter.js.map +1 -1
  15. package/dist/adapters/mech/contracts.d.ts +2 -0
  16. package/dist/adapters/mech/contracts.js +57 -7
  17. package/dist/adapters/mech/contracts.js.map +1 -1
  18. package/dist/adapters/mech/ipfs.d.ts +8 -0
  19. package/dist/adapters/mech/ipfs.js +12 -0
  20. package/dist/adapters/mech/ipfs.js.map +1 -1
  21. package/dist/adapters/mech/types.d.ts +20 -46
  22. package/dist/adapters/mech/types.js +16 -35
  23. package/dist/adapters/mech/types.js.map +1 -1
  24. package/dist/api/gather-status.d.ts +1 -0
  25. package/dist/api/gather-status.js +33 -1
  26. package/dist/api/gather-status.js.map +1 -1
  27. package/dist/api/portfolio-v0-build.d.ts +81 -0
  28. package/dist/api/portfolio-v0-build.js +141 -0
  29. package/dist/api/portfolio-v0-build.js.map +1 -0
  30. package/dist/api/portfolio-v0-doctor.d.ts +37 -0
  31. package/dist/api/portfolio-v0-doctor.js +123 -0
  32. package/dist/api/portfolio-v0-doctor.js.map +1 -0
  33. package/dist/api/rewards-build.js +1 -1
  34. package/dist/api/rewards-build.js.map +1 -1
  35. package/dist/api/status-build.d.ts +7 -0
  36. package/dist/api/status-build.js +1 -0
  37. package/dist/api/status-build.js.map +1 -1
  38. package/dist/bin/jinn-mcp.d.ts +0 -12
  39. package/dist/bin/jinn-mcp.js +5 -14
  40. package/dist/bin/jinn-mcp.js.map +1 -1
  41. package/dist/build-meta.json +1 -1
  42. package/dist/cli/commands/auth.js +115 -25
  43. package/dist/cli/commands/auth.js.map +1 -1
  44. package/dist/cli/commands/bootstrap.js +1 -0
  45. package/dist/cli/commands/bootstrap.js.map +1 -1
  46. package/dist/cli/commands/doctor.js +130 -14
  47. package/dist/cli/commands/doctor.js.map +1 -1
  48. package/dist/cli/commands/fleet-scale.js +1 -0
  49. package/dist/cli/commands/fleet-scale.js.map +1 -1
  50. package/dist/cli/commands/fund-requirements.js +2 -0
  51. package/dist/cli/commands/fund-requirements.js.map +1 -1
  52. package/dist/cli/commands/intents.d.ts +17 -0
  53. package/dist/cli/commands/intents.js +489 -0
  54. package/dist/cli/commands/intents.js.map +1 -0
  55. package/dist/cli/commands/keys-backup.js +13 -11
  56. package/dist/cli/commands/keys-backup.js.map +1 -1
  57. package/dist/cli/commands/mcp.d.ts +3 -0
  58. package/dist/cli/commands/mcp.js +19 -0
  59. package/dist/cli/commands/mcp.js.map +1 -0
  60. package/dist/cli/commands/plugin-install.js +8 -4
  61. package/dist/cli/commands/plugin-install.js.map +1 -1
  62. package/dist/cli/commands/quickstart.js +60 -4
  63. package/dist/cli/commands/quickstart.js.map +1 -1
  64. package/dist/cli/commands/rewards.js +27 -1
  65. package/dist/cli/commands/rewards.js.map +1 -1
  66. package/dist/cli/commands/submit-intent.js +108 -5
  67. package/dist/cli/commands/submit-intent.js.map +1 -1
  68. package/dist/cli/commands/version.js +1 -0
  69. package/dist/cli/commands/version.js.map +1 -1
  70. package/dist/cli/deployment-digest.js +5 -0
  71. package/dist/cli/deployment-digest.js.map +1 -1
  72. package/dist/cli/execution-context.js +1 -0
  73. package/dist/cli/execution-context.js.map +1 -1
  74. package/dist/cli/index.js +4 -0
  75. package/dist/cli/index.js.map +1 -1
  76. package/dist/cli/intent-registry-access.d.ts +64 -0
  77. package/dist/cli/intent-registry-access.js +187 -0
  78. package/dist/cli/intent-registry-access.js.map +1 -0
  79. package/dist/cli/introspection-context.js +1 -0
  80. package/dist/cli/introspection-context.js.map +1 -1
  81. package/dist/cli/password.d.ts +21 -9
  82. package/dist/cli/password.js +45 -24
  83. package/dist/cli/password.js.map +1 -1
  84. package/dist/config.d.ts +110 -8
  85. package/dist/config.js +41 -12
  86. package/dist/config.js.map +1 -1
  87. package/dist/daemon/creator.d.ts +7 -1
  88. package/dist/daemon/creator.js +38 -3
  89. package/dist/daemon/creator.js.map +1 -1
  90. package/dist/daemon/daemon.d.ts +43 -0
  91. package/dist/daemon/daemon.js +87 -2
  92. package/dist/daemon/daemon.js.map +1 -1
  93. package/dist/earning/bootstrap.d.ts +2 -1
  94. package/dist/earning/bootstrap.js +72 -4
  95. package/dist/earning/bootstrap.js.map +1 -1
  96. package/dist/earning/contracts.d.ts +10 -0
  97. package/dist/earning/contracts.js +24 -0
  98. package/dist/earning/contracts.js.map +1 -1
  99. package/dist/earning/jinn-rewards.d.ts +9 -0
  100. package/dist/earning/jinn-rewards.js +7 -0
  101. package/dist/earning/jinn-rewards.js.map +1 -1
  102. package/dist/intents/prediction-apy-v0-auto.d.ts +11 -0
  103. package/dist/intents/prediction-apy-v0-auto.js +46 -0
  104. package/dist/intents/prediction-apy-v0-auto.js.map +1 -0
  105. package/dist/intents/prediction-apy-v0-template.d.ts +8 -0
  106. package/dist/intents/prediction-apy-v0-template.js +22 -0
  107. package/dist/intents/prediction-apy-v0-template.js.map +1 -0
  108. package/dist/intents/prediction-v0-auto.d.ts +53 -0
  109. package/dist/intents/prediction-v0-auto.js +84 -0
  110. package/dist/intents/prediction-v0-auto.js.map +1 -0
  111. package/dist/intents/prediction-v0-template.d.ts +65 -0
  112. package/dist/intents/prediction-v0-template.js +125 -0
  113. package/dist/intents/prediction-v0-template.js.map +1 -0
  114. package/dist/main.js +149 -1
  115. package/dist/main.js.map +1 -1
  116. package/dist/mcp/operator-server.d.ts +1 -1
  117. package/dist/mcp/operator-server.js +1 -1
  118. package/dist/preflight/claude-auth.d.ts +12 -1
  119. package/dist/preflight/claude-auth.js +21 -3
  120. package/dist/preflight/claude-auth.js.map +1 -1
  121. package/dist/restorer/engine/canonical-json.d.ts +18 -0
  122. package/dist/restorer/engine/canonical-json.js +59 -0
  123. package/dist/restorer/engine/canonical-json.js.map +1 -0
  124. package/dist/restorer/engine/claim.d.ts +69 -0
  125. package/dist/restorer/engine/claim.js +104 -0
  126. package/dist/restorer/engine/claim.js.map +1 -0
  127. package/dist/restorer/engine/delivery.d.ts +52 -0
  128. package/dist/restorer/engine/delivery.js +63 -0
  129. package/dist/restorer/engine/delivery.js.map +1 -0
  130. package/dist/restorer/engine/engine.d.ts +203 -0
  131. package/dist/restorer/engine/engine.js +753 -0
  132. package/dist/restorer/engine/engine.js.map +1 -0
  133. package/dist/restorer/engine/manifest-assembly.d.ts +67 -0
  134. package/dist/restorer/engine/manifest-assembly.js +79 -0
  135. package/dist/restorer/engine/manifest-assembly.js.map +1 -0
  136. package/dist/restorer/engine/packaging.d.ts +87 -0
  137. package/dist/restorer/engine/packaging.js +350 -0
  138. package/dist/restorer/engine/packaging.js.map +1 -0
  139. package/dist/restorer/engine/persistence.d.ts +170 -0
  140. package/dist/restorer/engine/persistence.js +381 -0
  141. package/dist/restorer/engine/persistence.js.map +1 -0
  142. package/dist/restorer/engine/recovery.d.ts +22 -0
  143. package/dist/restorer/engine/recovery.js +24 -0
  144. package/dist/restorer/engine/recovery.js.map +1 -0
  145. package/dist/restorer/engine/registry.d.ts +62 -0
  146. package/dist/restorer/engine/registry.js +73 -0
  147. package/dist/restorer/engine/registry.js.map +1 -0
  148. package/dist/restorer/engine/signing.d.ts +30 -0
  149. package/dist/restorer/engine/signing.js +39 -0
  150. package/dist/restorer/engine/signing.js.map +1 -0
  151. package/dist/restorer/engine/state.d.ts +42 -0
  152. package/dist/restorer/engine/state.js +87 -0
  153. package/dist/restorer/engine/state.js.map +1 -0
  154. package/dist/restorer/impls/claude-mcp-hyperliquid/api-wallet.d.ts +64 -0
  155. package/dist/restorer/impls/claude-mcp-hyperliquid/api-wallet.js +96 -0
  156. package/dist/restorer/impls/claude-mcp-hyperliquid/api-wallet.js.map +1 -0
  157. package/dist/restorer/impls/claude-mcp-hyperliquid/index.d.ts +101 -0
  158. package/dist/restorer/impls/claude-mcp-hyperliquid/index.js +710 -0
  159. package/dist/restorer/impls/claude-mcp-hyperliquid/index.js.map +1 -0
  160. package/dist/restorer/impls/claude-mcp-hyperliquid/mcp-tools.d.ts +137 -0
  161. package/dist/restorer/impls/claude-mcp-hyperliquid/mcp-tools.js +865 -0
  162. package/dist/restorer/impls/claude-mcp-hyperliquid/mcp-tools.js.map +1 -0
  163. package/dist/restorer/impls/claude-mcp-hyperliquid/safety-rails.d.ts +74 -0
  164. package/dist/restorer/impls/claude-mcp-hyperliquid/safety-rails.js +74 -0
  165. package/dist/restorer/impls/claude-mcp-hyperliquid/safety-rails.js.map +1 -0
  166. package/dist/restorer/impls/claude-mcp-hyperliquid/session-orchestrator.d.ts +97 -0
  167. package/dist/restorer/impls/claude-mcp-hyperliquid/session-orchestrator.js +226 -0
  168. package/dist/restorer/impls/claude-mcp-hyperliquid/session-orchestrator.js.map +1 -0
  169. package/dist/restorer/impls/claude-mcp-prediction/index.d.ts +43 -0
  170. package/dist/restorer/impls/claude-mcp-prediction/index.js +230 -0
  171. package/dist/restorer/impls/claude-mcp-prediction/index.js.map +1 -0
  172. package/dist/restorer/impls/claude-mcp-prediction/mcp-tools.d.ts +38 -0
  173. package/dist/restorer/impls/claude-mcp-prediction/mcp-tools.js +135 -0
  174. package/dist/restorer/impls/claude-mcp-prediction/mcp-tools.js.map +1 -0
  175. package/dist/restorer/impls/claude-mcp-prediction/prompt.d.ts +8 -0
  176. package/dist/restorer/impls/claude-mcp-prediction/prompt.js +54 -0
  177. package/dist/restorer/impls/claude-mcp-prediction/prompt.js.map +1 -0
  178. package/dist/restorer/impls/claude-mcp-prediction/session-orchestrator.d.ts +36 -0
  179. package/dist/restorer/impls/claude-mcp-prediction/session-orchestrator.js +137 -0
  180. package/dist/restorer/impls/claude-mcp-prediction/session-orchestrator.js.map +1 -0
  181. package/dist/restorer/impls/claude-mcp-prediction/types.d.ts +82 -0
  182. package/dist/restorer/impls/claude-mcp-prediction/types.js +6 -0
  183. package/dist/restorer/impls/claude-mcp-prediction/types.js.map +1 -0
  184. package/dist/restorer/impls/legacy-claude/index.d.ts +45 -0
  185. package/dist/restorer/impls/legacy-claude/index.js +71 -0
  186. package/dist/restorer/impls/legacy-claude/index.js.map +1 -0
  187. package/dist/restorer/impls/portfolio-v0-evaluator/canonical-metrics.d.ts +68 -0
  188. package/dist/restorer/impls/portfolio-v0-evaluator/canonical-metrics.js +117 -0
  189. package/dist/restorer/impls/portfolio-v0-evaluator/canonical-metrics.js.map +1 -0
  190. package/dist/restorer/impls/portfolio-v0-evaluator/checks/availability.d.ts +49 -0
  191. package/dist/restorer/impls/portfolio-v0-evaluator/checks/availability.js +91 -0
  192. package/dist/restorer/impls/portfolio-v0-evaluator/checks/availability.js.map +1 -0
  193. package/dist/restorer/impls/portfolio-v0-evaluator/checks/consistency.d.ts +78 -0
  194. package/dist/restorer/impls/portfolio-v0-evaluator/checks/consistency.js +274 -0
  195. package/dist/restorer/impls/portfolio-v0-evaluator/checks/consistency.js.map +1 -0
  196. package/dist/restorer/impls/portfolio-v0-evaluator/checks/eligibility.d.ts +23 -0
  197. package/dist/restorer/impls/portfolio-v0-evaluator/checks/eligibility.js +49 -0
  198. package/dist/restorer/impls/portfolio-v0-evaluator/checks/eligibility.js.map +1 -0
  199. package/dist/restorer/impls/portfolio-v0-evaluator/checks/integrity.d.ts +25 -0
  200. package/dist/restorer/impls/portfolio-v0-evaluator/checks/integrity.js +44 -0
  201. package/dist/restorer/impls/portfolio-v0-evaluator/checks/integrity.js.map +1 -0
  202. package/dist/restorer/impls/portfolio-v0-evaluator/checks/spec.d.ts +17 -0
  203. package/dist/restorer/impls/portfolio-v0-evaluator/checks/spec.js +43 -0
  204. package/dist/restorer/impls/portfolio-v0-evaluator/checks/spec.js.map +1 -0
  205. package/dist/restorer/impls/portfolio-v0-evaluator/index.d.ts +43 -0
  206. package/dist/restorer/impls/portfolio-v0-evaluator/index.js +431 -0
  207. package/dist/restorer/impls/portfolio-v0-evaluator/index.js.map +1 -0
  208. package/dist/restorer/impls/portfolio-v0-evaluator/score.d.ts +21 -0
  209. package/dist/restorer/impls/portfolio-v0-evaluator/score.js +32 -0
  210. package/dist/restorer/impls/portfolio-v0-evaluator/score.js.map +1 -0
  211. package/dist/restorer/impls/portfolio-v0-evaluator/types.d.ts +32 -0
  212. package/dist/restorer/impls/portfolio-v0-evaluator/types.js +8 -0
  213. package/dist/restorer/impls/portfolio-v0-evaluator/types.js.map +1 -0
  214. package/dist/restorer/impls/prediction-apy-v0-baseline/index.d.ts +39 -0
  215. package/dist/restorer/impls/prediction-apy-v0-baseline/index.js +98 -0
  216. package/dist/restorer/impls/prediction-apy-v0-baseline/index.js.map +1 -0
  217. package/dist/restorer/impls/prediction-apy-v0-baseline/strategy.d.ts +2 -0
  218. package/dist/restorer/impls/prediction-apy-v0-baseline/strategy.js +7 -0
  219. package/dist/restorer/impls/prediction-apy-v0-baseline/strategy.js.map +1 -0
  220. package/dist/restorer/impls/prediction-apy-v0-baseline/types.d.ts +4 -0
  221. package/dist/restorer/impls/prediction-apy-v0-baseline/types.js +2 -0
  222. package/dist/restorer/impls/prediction-apy-v0-baseline/types.js.map +1 -0
  223. package/dist/restorer/impls/prediction-apy-v0-evaluator/canonical-metrics.d.ts +2 -0
  224. package/dist/restorer/impls/prediction-apy-v0-evaluator/canonical-metrics.js +7 -0
  225. package/dist/restorer/impls/prediction-apy-v0-evaluator/canonical-metrics.js.map +1 -0
  226. package/dist/restorer/impls/prediction-apy-v0-evaluator/index.d.ts +39 -0
  227. package/dist/restorer/impls/prediction-apy-v0-evaluator/index.js +186 -0
  228. package/dist/restorer/impls/prediction-apy-v0-evaluator/index.js.map +1 -0
  229. package/dist/restorer/impls/prediction-apy-v0-evaluator/score.d.ts +9 -0
  230. package/dist/restorer/impls/prediction-apy-v0-evaluator/score.js +20 -0
  231. package/dist/restorer/impls/prediction-apy-v0-evaluator/score.js.map +1 -0
  232. package/dist/restorer/impls/prediction-apy-v0-evaluator/types.d.ts +7 -0
  233. package/dist/restorer/impls/prediction-apy-v0-evaluator/types.js +2 -0
  234. package/dist/restorer/impls/prediction-apy-v0-evaluator/types.js.map +1 -0
  235. package/dist/restorer/impls/prediction-v0-baseline/index.d.ts +29 -0
  236. package/dist/restorer/impls/prediction-v0-baseline/index.js +94 -0
  237. package/dist/restorer/impls/prediction-v0-baseline/index.js.map +1 -0
  238. package/dist/restorer/impls/prediction-v0-baseline/strategy.d.ts +8 -0
  239. package/dist/restorer/impls/prediction-v0-baseline/strategy.js +41 -0
  240. package/dist/restorer/impls/prediction-v0-baseline/strategy.js.map +1 -0
  241. package/dist/restorer/impls/prediction-v0-baseline/types.d.ts +7 -0
  242. package/dist/restorer/impls/prediction-v0-baseline/types.js +2 -0
  243. package/dist/restorer/impls/prediction-v0-baseline/types.js.map +1 -0
  244. package/dist/restorer/impls/prediction-v0-evaluator/canonical-metrics.d.ts +20 -0
  245. package/dist/restorer/impls/prediction-v0-evaluator/canonical-metrics.js +66 -0
  246. package/dist/restorer/impls/prediction-v0-evaluator/canonical-metrics.js.map +1 -0
  247. package/dist/restorer/impls/prediction-v0-evaluator/checks/availability.d.ts +9 -0
  248. package/dist/restorer/impls/prediction-v0-evaluator/checks/availability.js +23 -0
  249. package/dist/restorer/impls/prediction-v0-evaluator/checks/availability.js.map +1 -0
  250. package/dist/restorer/impls/prediction-v0-evaluator/checks/eligibility.d.ts +3 -0
  251. package/dist/restorer/impls/prediction-v0-evaluator/checks/eligibility.js +13 -0
  252. package/dist/restorer/impls/prediction-v0-evaluator/checks/eligibility.js.map +1 -0
  253. package/dist/restorer/impls/prediction-v0-evaluator/checks/integrity.d.ts +7 -0
  254. package/dist/restorer/impls/prediction-v0-evaluator/checks/integrity.js +93 -0
  255. package/dist/restorer/impls/prediction-v0-evaluator/checks/integrity.js.map +1 -0
  256. package/dist/restorer/impls/prediction-v0-evaluator/checks/spec.d.ts +5 -0
  257. package/dist/restorer/impls/prediction-v0-evaluator/checks/spec.js +20 -0
  258. package/dist/restorer/impls/prediction-v0-evaluator/checks/spec.js.map +1 -0
  259. package/dist/restorer/impls/prediction-v0-evaluator/index.d.ts +33 -0
  260. package/dist/restorer/impls/prediction-v0-evaluator/index.js +208 -0
  261. package/dist/restorer/impls/prediction-v0-evaluator/index.js.map +1 -0
  262. package/dist/restorer/impls/prediction-v0-evaluator/score.d.ts +8 -0
  263. package/dist/restorer/impls/prediction-v0-evaluator/score.js +15 -0
  264. package/dist/restorer/impls/prediction-v0-evaluator/score.js.map +1 -0
  265. package/dist/restorer/impls/prediction-v0-evaluator/types.d.ts +7 -0
  266. package/dist/restorer/impls/prediction-v0-evaluator/types.js +2 -0
  267. package/dist/restorer/impls/prediction-v0-evaluator/types.js.map +1 -0
  268. package/dist/restorer/types.d.ts +177 -0
  269. package/dist/restorer/types.js +7 -0
  270. package/dist/restorer/types.js.map +1 -0
  271. package/dist/store/store.d.ts +3 -1
  272. package/dist/store/store.js +3 -0
  273. package/dist/store/store.js.map +1 -1
  274. package/dist/types/desired-state.d.ts +53 -0
  275. package/dist/types/desired-state.js +20 -0
  276. package/dist/types/desired-state.js.map +1 -1
  277. package/dist/types/index.d.ts +4 -1
  278. package/dist/types/index.js +4 -1
  279. package/dist/types/index.js.map +1 -1
  280. package/dist/types/portfolio.d.ts +1000 -0
  281. package/dist/types/portfolio.js +168 -0
  282. package/dist/types/portfolio.js.map +1 -0
  283. package/dist/types/prediction-apy.d.ts +919 -0
  284. package/dist/types/prediction-apy.js +121 -0
  285. package/dist/types/prediction-apy.js.map +1 -0
  286. package/dist/types/prediction.d.ts +925 -0
  287. package/dist/types/prediction.js +140 -0
  288. package/dist/types/prediction.js.map +1 -0
  289. package/dist/venues/aave-v3/addresses.d.ts +6 -0
  290. package/dist/venues/aave-v3/addresses.js +19 -0
  291. package/dist/venues/aave-v3/addresses.js.map +1 -0
  292. package/dist/venues/aave-v3/client.d.ts +81 -0
  293. package/dist/venues/aave-v3/client.js +97 -0
  294. package/dist/venues/aave-v3/client.js.map +1 -0
  295. package/dist/venues/chainlink/client.d.ts +99 -0
  296. package/dist/venues/chainlink/client.js +130 -0
  297. package/dist/venues/chainlink/client.js.map +1 -0
  298. package/dist/venues/chainlink/feeds.d.ts +8 -0
  299. package/dist/venues/chainlink/feeds.js +9 -0
  300. package/dist/venues/chainlink/feeds.js.map +1 -0
  301. package/dist/venues/hyperliquid/account-value.d.ts +30 -0
  302. package/dist/venues/hyperliquid/account-value.js +30 -0
  303. package/dist/venues/hyperliquid/account-value.js.map +1 -0
  304. package/dist/venues/hyperliquid/client.d.ts +63 -0
  305. package/dist/venues/hyperliquid/client.js +135 -0
  306. package/dist/venues/hyperliquid/client.js.map +1 -0
  307. package/dist/venues/hyperliquid/grid.d.ts +36 -0
  308. package/dist/venues/hyperliquid/grid.js +61 -0
  309. package/dist/venues/hyperliquid/grid.js.map +1 -0
  310. package/dist/venues/hyperliquid/types.d.ts +81 -0
  311. package/dist/venues/hyperliquid/types.js +8 -0
  312. package/dist/venues/hyperliquid/types.js.map +1 -0
  313. package/dist/withdraw/run-withdraw-plan.js +2 -0
  314. package/dist/withdraw/run-withdraw-plan.js.map +1 -1
  315. package/docker-compose.yml +44 -0
  316. package/package.json +12 -1
  317. package/skills/jinn-operator/SKILL.md +85 -0
@@ -0,0 +1,62 @@
1
+ /**
2
+ * RestorerImplRegistry — impl registration + operator-config-aware dispatch.
3
+ *
4
+ * §6.7 of spec/2026-04-17-portfolio-v0-design.md
5
+ *
6
+ * Dispatch priority:
7
+ * 1. byKind[spec.kind] — explicit operator mapping wins regardless of
8
+ * registration order
9
+ * 2. config.default — named fallback impl
10
+ * 3. First-match — iterate registered impls, return first whose supports()
11
+ * returns true
12
+ *
13
+ * Disabled impls (config.disabled[]) are filtered out before dispatch.
14
+ */
15
+ import type { RestorerImpl } from '../types.js';
16
+ import type { RestorerImplRegistry as IRestorerImplRegistry } from './engine.js';
17
+ export interface RestorerDispatchConfig {
18
+ /**
19
+ * Explicit kind → impl name mapping.
20
+ * e.g. { "portfolio.v0": "claude-mcp-hyperliquid" }
21
+ */
22
+ byKind?: Record<string, string>;
23
+ /**
24
+ * Fallback impl name when no kind-specific match is found.
25
+ */
26
+ default?: string;
27
+ /**
28
+ * Impl names to exclude from dispatch entirely.
29
+ */
30
+ disabled?: string[];
31
+ }
32
+ export declare class RestorerImplRegistry implements IRestorerImplRegistry {
33
+ private readonly impls;
34
+ private readonly config;
35
+ constructor(config?: RestorerDispatchConfig);
36
+ /**
37
+ * Register an impl. Later registrations appear later in the list for
38
+ * first-match fallback dispatch.
39
+ */
40
+ register(impl: RestorerImpl): void;
41
+ /**
42
+ * Find the impl to use for the given spec kind, applying operator config
43
+ * dispatch rules.
44
+ *
45
+ * Returns undefined if no suitable impl is found (all disabled, none
46
+ * support the kind, or registry is empty).
47
+ */
48
+ findFor(ctx: {
49
+ kind: string;
50
+ type?: 'restoration' | 'evaluation';
51
+ }): RestorerImpl | undefined;
52
+ /** All registered impls (including disabled ones). */
53
+ list(): RestorerImpl[];
54
+ /**
55
+ * IRestorerImplRegistry compatibility: resolve an impl name for a given
56
+ * spec kind, or null if none registered.
57
+ */
58
+ resolveImplName(ctx: {
59
+ kind: string | null;
60
+ type?: 'restoration' | 'evaluation';
61
+ }): string | null;
62
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * RestorerImplRegistry — impl registration + operator-config-aware dispatch.
3
+ *
4
+ * §6.7 of spec/2026-04-17-portfolio-v0-design.md
5
+ *
6
+ * Dispatch priority:
7
+ * 1. byKind[spec.kind] — explicit operator mapping wins regardless of
8
+ * registration order
9
+ * 2. config.default — named fallback impl
10
+ * 3. First-match — iterate registered impls, return first whose supports()
11
+ * returns true
12
+ *
13
+ * Disabled impls (config.disabled[]) are filtered out before dispatch.
14
+ */
15
+ // ── RestorerImplRegistry ──────────────────────────────────────────────────────
16
+ export class RestorerImplRegistry {
17
+ impls = [];
18
+ config;
19
+ constructor(config = {}) {
20
+ this.config = config;
21
+ }
22
+ /**
23
+ * Register an impl. Later registrations appear later in the list for
24
+ * first-match fallback dispatch.
25
+ */
26
+ register(impl) {
27
+ this.impls.push(impl);
28
+ }
29
+ /**
30
+ * Find the impl to use for the given spec kind, applying operator config
31
+ * dispatch rules.
32
+ *
33
+ * Returns undefined if no suitable impl is found (all disabled, none
34
+ * support the kind, or registry is empty).
35
+ */
36
+ findFor(ctx) {
37
+ const disabled = new Set(this.config.disabled ?? []);
38
+ const active = this.impls.filter((impl) => !disabled.has(impl.name));
39
+ // 1. byKind explicit mapping — but ONLY honor it if the named impl supports
40
+ // the requested ctx. Otherwise fall through (e.g., byKind points at the
41
+ // restorer impl, but ctx asks for an evaluation).
42
+ const kindName = this.config.byKind?.[ctx.kind];
43
+ if (kindName) {
44
+ const named = active.find((impl) => impl.name === kindName);
45
+ if (named && named.supports(ctx))
46
+ return named;
47
+ }
48
+ // 2. default fallback name
49
+ if (this.config.default) {
50
+ const defaultImpl = active.find((impl) => impl.name === this.config.default);
51
+ if (defaultImpl && defaultImpl.supports(ctx)) {
52
+ return defaultImpl;
53
+ }
54
+ }
55
+ // 3. First-match by supports()
56
+ return active.find((impl) => impl.supports(ctx));
57
+ }
58
+ /** All registered impls (including disabled ones). */
59
+ list() {
60
+ return [...this.impls];
61
+ }
62
+ /**
63
+ * IRestorerImplRegistry compatibility: resolve an impl name for a given
64
+ * spec kind, or null if none registered.
65
+ */
66
+ resolveImplName(ctx) {
67
+ if (ctx.kind === null)
68
+ return null;
69
+ const impl = this.findFor({ kind: ctx.kind, type: ctx.type });
70
+ return impl?.name ?? null;
71
+ }
72
+ }
73
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/restorer/engine/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAuBH,iFAAiF;AAEjF,MAAM,OAAO,oBAAoB;IACd,KAAK,GAAmB,EAAE,CAAC;IAC3B,MAAM,CAAyB;IAEhD,YAAY,SAAiC,EAAE;QAC7C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED;;;OAGG;IACH,QAAQ,CAAC,IAAkB;QACzB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED;;;;;;OAMG;IACH,OAAO,CAAC,GAA0D;QAChE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAErE,4EAA4E;QAC5E,2EAA2E;QAC3E,qDAAqD;QACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;YAC5D,IAAI,KAAK,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;QACjD,CAAC;QAED,2BAA2B;QAC3B,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACxB,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC7E,IAAI,WAAW,IAAI,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7C,OAAO,WAAW,CAAC;YACrB,CAAC;QACH,CAAC;QAED,+BAA+B;QAC/B,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,sDAAsD;IACtD,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,eAAe,CAAC,GAAiE;QAC/E,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9D,OAAO,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC;IAC5B,CAAC;CACF"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Shared canonical signing helper for the restorer engine.
3
+ *
4
+ * Extracted from manifest-assembly.ts and portfolio-v0-evaluator/index.ts to
5
+ * eliminate duplicated keccak256 → secp256k1 sign → assemble-recovery-byte logic.
6
+ *
7
+ * Signing method: raw secp256k1 ECDSA, no EIP-191 prefix.
8
+ * Uses viem `sign({ hash, privateKey })` from `viem/accounts`.
9
+ */
10
+ export interface SignedCanonical {
11
+ /** Canonical JSON string of the object (sorted keys, no whitespace). */
12
+ canonicalJson: string;
13
+ /** keccak256 hash of the canonical JSON bytes. */
14
+ hash: `0x${string}`;
15
+ /** 65-byte secp256k1 signature: r ++ s ++ recoveryByte, hex-encoded. */
16
+ sig: `0x${string}`;
17
+ /** Address of the signing key (passed through from caller). */
18
+ signer: `0x${string}`;
19
+ }
20
+ /**
21
+ * Serialise `obj` to canonical JSON, hash it with keccak256, sign with
22
+ * `privateKey`, and return the hash + 65-byte signature.
23
+ *
24
+ * @param obj Object to sign (must be JSON-serialisable).
25
+ * @param privateKey Agent EOA private key.
26
+ * @param signerAddress Address corresponding to `privateKey` (caller-supplied
27
+ * to avoid a redundant `privateKeyToAccount` call when the
28
+ * caller already has it).
29
+ */
30
+ export declare function signCanonical(obj: unknown, privateKey: `0x${string}`, signerAddress: `0x${string}`): Promise<SignedCanonical>;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Shared canonical signing helper for the restorer engine.
3
+ *
4
+ * Extracted from manifest-assembly.ts and portfolio-v0-evaluator/index.ts to
5
+ * eliminate duplicated keccak256 → secp256k1 sign → assemble-recovery-byte logic.
6
+ *
7
+ * Signing method: raw secp256k1 ECDSA, no EIP-191 prefix.
8
+ * Uses viem `sign({ hash, privateKey })` from `viem/accounts`.
9
+ */
10
+ import { keccak256, toHex, hexToBytes } from 'viem';
11
+ import { sign } from 'viem/accounts';
12
+ import { canonicalJson } from './canonical-json.js';
13
+ // ── signCanonical ─────────────────────────────────────────────────────────────
14
+ /**
15
+ * Serialise `obj` to canonical JSON, hash it with keccak256, sign with
16
+ * `privateKey`, and return the hash + 65-byte signature.
17
+ *
18
+ * @param obj Object to sign (must be JSON-serialisable).
19
+ * @param privateKey Agent EOA private key.
20
+ * @param signerAddress Address corresponding to `privateKey` (caller-supplied
21
+ * to avoid a redundant `privateKeyToAccount` call when the
22
+ * caller already has it).
23
+ */
24
+ export async function signCanonical(obj, privateKey, signerAddress) {
25
+ const canonical = canonicalJson(obj);
26
+ const canonicalBytes = new TextEncoder().encode(canonical);
27
+ const hash = keccak256(canonicalBytes);
28
+ const sigResult = await sign({ hash, privateKey });
29
+ // viem sign() returns { r, s, v, yParity } — use yParity (canonical) with
30
+ // fallback to v for older viem versions that may not populate yParity.
31
+ const recoveryByte = sigResult.yParity ?? (sigResult.v === 28n ? 1 : 0);
32
+ const sig = toHex(new Uint8Array([
33
+ ...hexToBytes(sigResult.r),
34
+ ...hexToBytes(sigResult.s),
35
+ recoveryByte,
36
+ ]));
37
+ return { canonicalJson: canonical, hash, sig, signer: signerAddress };
38
+ }
39
+ //# sourceMappingURL=signing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signing.js","sourceRoot":"","sources":["../../../src/restorer/engine/signing.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAY,MAAM,MAAM,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAepD,iFAAiF;AAEjF;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAY,EACZ,UAAyB,EACzB,aAA4B;IAE5B,MAAM,SAAS,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IACrC,MAAM,cAAc,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC3D,MAAM,IAAI,GAAG,SAAS,CAAC,cAAc,CAAkB,CAAC;IAExD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IACnD,0EAA0E;IAC1E,uEAAuE;IACvE,MAAM,YAAY,GAAG,SAAS,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,MAAM,GAAG,GAAG,KAAK,CACf,IAAI,UAAU,CAAC;QACb,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;QAC1B,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;QAC1B,YAAY;KACb,CAAC,CACc,CAAC;IAEnB,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;AACxE,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Restorer engine — state machine definitions.
3
+ *
4
+ * §6.3 of spec/2026-04-17-portfolio-v0-design.md
5
+ *
6
+ * Pure logic; no I/O, no persistence.
7
+ */
8
+ export declare const IntentState: {
9
+ readonly DISCOVERED: "DISCOVERED";
10
+ readonly CLAIMED: "CLAIMED";
11
+ readonly WAITING: "WAITING";
12
+ readonly PRE_SNAPSHOT: "PRE_SNAPSHOT";
13
+ readonly RUNNING: "RUNNING";
14
+ readonly POST_SNAPSHOT: "POST_SNAPSHOT";
15
+ readonly PACKAGING: "PACKAGING";
16
+ readonly DELIVERING: "DELIVERING";
17
+ readonly COMPLETE: "COMPLETE";
18
+ readonly FAILED: "FAILED";
19
+ };
20
+ export type IntentState = (typeof IntentState)[keyof typeof IntentState];
21
+ export declare const TERMINAL_STATES: ReadonlySet<IntentState>;
22
+ export declare const IN_FLIGHT_STATES: ReadonlySet<IntentState>;
23
+ /**
24
+ * Returns true if the transition from → to is permitted by the state machine.
25
+ */
26
+ export declare function isValidTransition(from: IntentState, to: IntentState): boolean;
27
+ /**
28
+ * Asserts that a transition is valid; throws if not.
29
+ */
30
+ export declare function assertValidTransition(from: IntentState, to: IntentState): void;
31
+ /**
32
+ * All state values as an array, useful for exhaustive checks.
33
+ */
34
+ export declare const ALL_STATES: readonly IntentState[];
35
+ /**
36
+ * Thrown by deliver() when claimDeliveryVariant is 'v2' but evidenceHash is
37
+ * null/undefined. A zero fallback would silently submit bytes32(0) on-chain
38
+ * and brick staking rewards; we prefer a loud FAILED transition instead.
39
+ */
40
+ export declare class MissingEvidenceHashError extends Error {
41
+ constructor(requestId: string);
42
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Restorer engine — state machine definitions.
3
+ *
4
+ * §6.3 of spec/2026-04-17-portfolio-v0-design.md
5
+ *
6
+ * Pure logic; no I/O, no persistence.
7
+ */
8
+ // ── State enum ────────────────────────────────────────────────────────────────
9
+ export const IntentState = {
10
+ DISCOVERED: 'DISCOVERED',
11
+ CLAIMED: 'CLAIMED',
12
+ WAITING: 'WAITING',
13
+ PRE_SNAPSHOT: 'PRE_SNAPSHOT',
14
+ RUNNING: 'RUNNING',
15
+ POST_SNAPSHOT: 'POST_SNAPSHOT',
16
+ PACKAGING: 'PACKAGING',
17
+ DELIVERING: 'DELIVERING',
18
+ COMPLETE: 'COMPLETE',
19
+ FAILED: 'FAILED',
20
+ };
21
+ export const TERMINAL_STATES = new Set([
22
+ IntentState.COMPLETE,
23
+ IntentState.FAILED,
24
+ ]);
25
+ export const IN_FLIGHT_STATES = new Set([
26
+ IntentState.DISCOVERED,
27
+ IntentState.CLAIMED,
28
+ IntentState.WAITING,
29
+ IntentState.PRE_SNAPSHOT,
30
+ IntentState.RUNNING,
31
+ IntentState.POST_SNAPSHOT,
32
+ IntentState.PACKAGING,
33
+ IntentState.DELIVERING,
34
+ ]);
35
+ // ── Transition table ──────────────────────────────────────────────────────────
36
+ /**
37
+ * Allowed transitions. Any state can transition to FAILED (terminal error path).
38
+ * The table below lists non-FAILED successors only.
39
+ */
40
+ const TRANSITIONS = new Map([
41
+ [IntentState.DISCOVERED, new Set([IntentState.CLAIMED, IntentState.FAILED])],
42
+ [IntentState.CLAIMED, new Set([IntentState.WAITING, IntentState.FAILED])],
43
+ [IntentState.WAITING, new Set([IntentState.PRE_SNAPSHOT, IntentState.FAILED])],
44
+ [IntentState.PRE_SNAPSHOT, new Set([IntentState.RUNNING, IntentState.FAILED])],
45
+ [IntentState.RUNNING, new Set([IntentState.POST_SNAPSHOT, IntentState.FAILED])],
46
+ [IntentState.POST_SNAPSHOT, new Set([IntentState.PACKAGING, IntentState.FAILED])],
47
+ [IntentState.PACKAGING, new Set([IntentState.DELIVERING, IntentState.FAILED])],
48
+ [IntentState.DELIVERING, new Set([IntentState.COMPLETE, IntentState.FAILED])],
49
+ [IntentState.COMPLETE, new Set()],
50
+ [IntentState.FAILED, new Set()],
51
+ ]);
52
+ /**
53
+ * Returns true if the transition from → to is permitted by the state machine.
54
+ */
55
+ export function isValidTransition(from, to) {
56
+ const allowed = TRANSITIONS.get(from);
57
+ if (!allowed)
58
+ return false;
59
+ return allowed.has(to);
60
+ }
61
+ /**
62
+ * Asserts that a transition is valid; throws if not.
63
+ */
64
+ export function assertValidTransition(from, to) {
65
+ if (!isValidTransition(from, to)) {
66
+ throw new Error(`Invalid state transition: ${from} → ${to}. ` +
67
+ `Allowed from ${from}: [${[...(TRANSITIONS.get(from) ?? [])].join(', ')}]`);
68
+ }
69
+ }
70
+ /**
71
+ * All state values as an array, useful for exhaustive checks.
72
+ */
73
+ export const ALL_STATES = Object.values(IntentState);
74
+ // ── Delivery errors ───────────────────────────────────────────────────────────
75
+ /**
76
+ * Thrown by deliver() when claimDeliveryVariant is 'v2' but evidenceHash is
77
+ * null/undefined. A zero fallback would silently submit bytes32(0) on-chain
78
+ * and brick staking rewards; we prefer a loud FAILED transition instead.
79
+ */
80
+ export class MissingEvidenceHashError extends Error {
81
+ constructor(requestId) {
82
+ super(`deliver: evidenceHash is required for v2 claimDelivery but is missing ` +
83
+ `(requestId=${requestId}). Ensure pack() completed successfully before deliver().`);
84
+ this.name = 'MissingEvidenceHashError';
85
+ }
86
+ }
87
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/restorer/engine/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * API wallet management for claude-mcp-hyperliquid — §8.1.
3
+ *
4
+ * Architecture decision (v0):
5
+ * Option (b): fresh keypair generated on first use, persisted in implStateDir.
6
+ * This provides blast-radius isolation — a compromised API wallet does not
7
+ * expose other keys held by the operator.
8
+ *
9
+ * HL "approve agent" flow (v0 operator prerequisite):
10
+ * The approve-agent authorization (linking the API wallet to the master account)
11
+ * is an OPERATOR PREREQUISITE for v0. The operator must manually approve the API
12
+ * wallet via the Hyperliquid UI (Settings → API Wallets → Add) or via the HL
13
+ * L2 action `approveAgent` BEFORE the impl can place trades.
14
+ *
15
+ * Steps:
16
+ * 1. Run any `jinn` command or let the daemon boot once — the API wallet
17
+ * keypair is generated and persisted to <implStateDir>/api-wallet.json.
18
+ * 2. Run `jinn portfolio api-wallet` (or inspect the file) to get the address.
19
+ * 3. Approve that address as an API wallet on your HL master account.
20
+ * 4. Set `approved: true` in <implStateDir>/api-wallet.json OR call
21
+ * `markApiWalletApproved(implStateDir)` from the CLI.
22
+ *
23
+ * This impl checks `state.approved` in `canAttempt()` and returns an
24
+ * informative error including the wallet address if not approved.
25
+ *
26
+ * Programmatic approval is a §8.5 future item.
27
+ *
28
+ * State file: <implStateDir>/api-wallet.json (mode 0o600)
29
+ */
30
+ export interface ApiWalletState {
31
+ /** 0x-prefixed hex private key */
32
+ privateKey: string;
33
+ /** Derived Ethereum address */
34
+ address: string;
35
+ /** Whether the operator has approved this wallet as an HL agent */
36
+ approved: boolean;
37
+ /** Epoch ms when the wallet was created */
38
+ createdAt: number;
39
+ /** Epoch ms when approved flag was last set */
40
+ approvedAt?: number;
41
+ /**
42
+ * The HL master that approved this agent, captured during the operator's
43
+ * approve-agent setup. When present, the impl cross-checks this against
44
+ * the intent's `spec.account.masterAddress` on every run — if they
45
+ * disagree, it aborts with `E_MASTER_MISMATCH` rather than silently
46
+ * routing trades to the wrong master.
47
+ */
48
+ masterAddress?: string;
49
+ }
50
+ export declare function walletStatePath(implStateDir: string): string;
51
+ export declare function loadApiWalletState(implStateDir: string): ApiWalletState | null;
52
+ export declare function saveApiWalletState(implStateDir: string, state: ApiWalletState): void;
53
+ /**
54
+ * Ensure an API wallet exists in implStateDir. Creates one if absent.
55
+ * Returns the current state (approved or not).
56
+ *
57
+ * Synchronous — safe to call at impl startup.
58
+ */
59
+ export declare function provisionApiWallet(implStateDir: string): ApiWalletState;
60
+ /**
61
+ * Mark the API wallet as approved by the operator.
62
+ * Call this after the operator completes the HL approve-agent flow.
63
+ */
64
+ export declare function markApiWalletApproved(implStateDir: string): ApiWalletState;
@@ -0,0 +1,96 @@
1
+ /**
2
+ * API wallet management for claude-mcp-hyperliquid — §8.1.
3
+ *
4
+ * Architecture decision (v0):
5
+ * Option (b): fresh keypair generated on first use, persisted in implStateDir.
6
+ * This provides blast-radius isolation — a compromised API wallet does not
7
+ * expose other keys held by the operator.
8
+ *
9
+ * HL "approve agent" flow (v0 operator prerequisite):
10
+ * The approve-agent authorization (linking the API wallet to the master account)
11
+ * is an OPERATOR PREREQUISITE for v0. The operator must manually approve the API
12
+ * wallet via the Hyperliquid UI (Settings → API Wallets → Add) or via the HL
13
+ * L2 action `approveAgent` BEFORE the impl can place trades.
14
+ *
15
+ * Steps:
16
+ * 1. Run any `jinn` command or let the daemon boot once — the API wallet
17
+ * keypair is generated and persisted to <implStateDir>/api-wallet.json.
18
+ * 2. Run `jinn portfolio api-wallet` (or inspect the file) to get the address.
19
+ * 3. Approve that address as an API wallet on your HL master account.
20
+ * 4. Set `approved: true` in <implStateDir>/api-wallet.json OR call
21
+ * `markApiWalletApproved(implStateDir)` from the CLI.
22
+ *
23
+ * This impl checks `state.approved` in `canAttempt()` and returns an
24
+ * informative error including the wallet address if not approved.
25
+ *
26
+ * Programmatic approval is a §8.5 future item.
27
+ *
28
+ * State file: <implStateDir>/api-wallet.json (mode 0o600)
29
+ */
30
+ import { readFileSync, writeFileSync, existsSync } from 'node:fs';
31
+ import { join } from 'node:path';
32
+ import { randomBytes } from 'node:crypto';
33
+ import { privateKeyToAccount } from 'viem/accounts';
34
+ // ── File path ──────────────────────────────────────────────────────────────────
35
+ export function walletStatePath(implStateDir) {
36
+ return join(implStateDir, 'api-wallet.json');
37
+ }
38
+ // ── Load / save ────────────────────────────────────────────────────────────────
39
+ export function loadApiWalletState(implStateDir) {
40
+ const path = walletStatePath(implStateDir);
41
+ if (!existsSync(path))
42
+ return null;
43
+ try {
44
+ const raw = readFileSync(path, 'utf-8');
45
+ return JSON.parse(raw);
46
+ }
47
+ catch {
48
+ return null;
49
+ }
50
+ }
51
+ export function saveApiWalletState(implStateDir, state) {
52
+ const path = walletStatePath(implStateDir);
53
+ writeFileSync(path, JSON.stringify(state, null, 2), { encoding: 'utf-8', mode: 0o600 });
54
+ }
55
+ // ── Provision ──────────────────────────────────────────────────────────────────
56
+ /**
57
+ * Ensure an API wallet exists in implStateDir. Creates one if absent.
58
+ * Returns the current state (approved or not).
59
+ *
60
+ * Synchronous — safe to call at impl startup.
61
+ */
62
+ export function provisionApiWallet(implStateDir) {
63
+ const existing = loadApiWalletState(implStateDir);
64
+ if (existing)
65
+ return existing;
66
+ // Generate a fresh 32-byte private key
67
+ const privateKeyBytes = randomBytes(32);
68
+ const privateKey = `0x${privateKeyBytes.toString('hex')}`;
69
+ const account = privateKeyToAccount(privateKey);
70
+ const state = {
71
+ privateKey,
72
+ address: account.address,
73
+ approved: false,
74
+ createdAt: Date.now(),
75
+ };
76
+ saveApiWalletState(implStateDir, state);
77
+ return state;
78
+ }
79
+ /**
80
+ * Mark the API wallet as approved by the operator.
81
+ * Call this after the operator completes the HL approve-agent flow.
82
+ */
83
+ export function markApiWalletApproved(implStateDir) {
84
+ const existing = loadApiWalletState(implStateDir);
85
+ if (!existing) {
86
+ throw new Error('api-wallet: no wallet found in implStateDir — call provisionApiWallet first');
87
+ }
88
+ const updated = {
89
+ ...existing,
90
+ approved: true,
91
+ approvedAt: Date.now(),
92
+ };
93
+ saveApiWalletState(implStateDir, updated);
94
+ return updated;
95
+ }
96
+ //# sourceMappingURL=api-wallet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-wallet.js","sourceRoot":"","sources":["../../../../src/restorer/impls/claude-mcp-hyperliquid/api-wallet.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAyBpD,kFAAkF;AAElF,MAAM,UAAU,eAAe,CAAC,YAAoB;IAClD,OAAO,IAAI,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAC;AAC/C,CAAC;AAED,kFAAkF;AAElF,MAAM,UAAU,kBAAkB,CAAC,YAAoB;IACrD,MAAM,IAAI,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC;IAC3C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACxC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAmB,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,YAAoB,EAAE,KAAqB;IAC5E,MAAM,IAAI,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC;IAC3C,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAC1F,CAAC;AAED,kFAAkF;AAElF;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,YAAoB;IACrD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAClD,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,uCAAuC;IACvC,MAAM,eAAe,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,KAAK,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAmB,CAAC;IAE3E,MAAM,OAAO,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;IAEhD,MAAM,KAAK,GAAmB;QAC5B,UAAU;QACV,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,QAAQ,EAAE,KAAK;QACf,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;KACtB,CAAC;IAEF,kBAAkB,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IACxC,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,YAAoB;IACxD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAClD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAC;IACjG,CAAC;IAED,MAAM,OAAO,GAAmB;QAC9B,GAAG,QAAQ;QACX,QAAQ,EAAE,IAAI;QACd,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;KACvB,CAAC;IAEF,kBAAkB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC1C,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * claude-mcp-hyperliquid — Reference RestorerImpl for portfolio.v0 — §8.
3
+ *
4
+ * Spawns Claude Code session(s) with HL-specific MCP tools (§8.2).
5
+ * Safety rails enforced at the tool boundary (§8.3).
6
+ * Sequential session cadence per §8.4.
7
+ * API wallet managed in implStateDir (§8.1).
8
+ *
9
+ * OPERATOR PREREQUISITE (v0):
10
+ * Before this impl can place trades, the operator must:
11
+ * 1. Let the daemon boot once (or call canAttempt()) to generate the API wallet.
12
+ * 2. Approve the generated API wallet address on their HL master account
13
+ * (Settings → API Wallets → Add in the HL UI).
14
+ * 3. Set approved:true in <implStateDir>/api-wallet.json
15
+ *
16
+ * The impl will surface the wallet address and instructions in canAttempt()
17
+ * if the wallet is not yet approved.
18
+ *
19
+ * Programmatic approval is a §8.5 future item.
20
+ */
21
+ import type { RestorerImpl, RestorationContext, RestorationOutput, ReadyStatus, EnableResult, IntentEnableMetadata } from '../../types.js';
22
+ import type { DesiredState } from '../../../types/desired-state.js';
23
+ import { HyperliquidClient } from '../../../venues/hyperliquid/client.js';
24
+ import type { SafetyConfig } from './safety-rails.js';
25
+ export interface ClaudeMcpHyperliquidConfig {
26
+ claudePath?: string;
27
+ claudeModel?: string;
28
+ /** Per-intent safety override (from intent context) */
29
+ safetyConfig?: Partial<SafetyConfig>;
30
+ /** Cadence between sessions in ms. Default: 30 min */
31
+ cadenceMs?: number;
32
+ /** Max session wall time in ms. Default: 8 min */
33
+ sessionMaxMs?: number;
34
+ /**
35
+ * Impl state directory root — used by `isReady` and `onEnable` to locate
36
+ * the api-wallet file outside of a running intent context. Defaults to
37
+ * `/tmp/jinn-engine-impl-state/claude-mcp-hyperliquid` to match the
38
+ * convention the engine uses in `main.ts`.
39
+ */
40
+ implStateDir?: string;
41
+ /** Injected deps for testing */
42
+ _testDeps?: TestDeps;
43
+ }
44
+ export interface TestDeps {
45
+ /** Mock runner — called instead of spawning Claude */
46
+ runSession?: (sessionId: string, prompt: string) => Promise<{
47
+ stdout: string;
48
+ }>;
49
+ hlClient?: HyperliquidClient;
50
+ }
51
+ export declare class ClaudeMcpHyperliquidImpl implements RestorerImpl {
52
+ readonly name = "claude-mcp-hyperliquid";
53
+ readonly version = "1.0.0";
54
+ private config;
55
+ constructor(config?: ClaudeMcpHyperliquidConfig);
56
+ supports(ctx: {
57
+ kind: string;
58
+ type?: 'restoration' | 'evaluation';
59
+ }): boolean;
60
+ canAttempt(intent: DesiredState): Promise<{
61
+ ok: true;
62
+ } | {
63
+ ok: false;
64
+ reason: string;
65
+ }>;
66
+ /** Resolve the impl state directory used by enable / readiness flows. */
67
+ private resolveImplStateDir;
68
+ isReady(): Promise<ReadyStatus>;
69
+ enableMetadata(): IntentEnableMetadata;
70
+ onEnable(args: Record<string, string | undefined>): Promise<EnableResult>;
71
+ onDisable(): Promise<void>;
72
+ run(ctx: RestorationContext): Promise<RestorationOutput>;
73
+ }
74
+ interface HlServerConfig {
75
+ hlBaseUrl: string;
76
+ apiWalletPrivateKey: string;
77
+ apiWalletAddress: string;
78
+ masterAddress: string;
79
+ safetyConfig?: Partial<SafetyConfig>;
80
+ }
81
+ /**
82
+ * Write a thin ESM wrapper script to disk that delegates to the compiled
83
+ * startMcpServer() from this package. This is spawned as a subprocess by
84
+ * Claude's --mcp-config.
85
+ *
86
+ * Security: the config (including apiWalletPrivateKey) is written to a
87
+ * SEPARATE file (hl-server-config.json) with mode 0o600. The script body
88
+ * receives only the config file path via process.argv[2] — no private key
89
+ * or secret data appears in the script source.
90
+ *
91
+ * The import path is resolved at write-time from __dirname (this module's
92
+ * location) so it always points to the compiled mcp-tools.js alongside this
93
+ * file. The daemon MUST run from a compiled build (dist/) — `yarn build`
94
+ * produces `dist/restorer/impls/claude-mcp-hyperliquid/mcp-tools.js`, which
95
+ * this wrapper imports by absolute path from plain Node. Running from tsx
96
+ * against src/ would leave mcp-tools.js non-existent and cause Claude to
97
+ * silently spawn with no HL tools loaded — hence the explicit existence
98
+ * check and `E_DAEMON_MUST_RUN_FROM_DIST` error below.
99
+ */
100
+ export declare function _writeHlMcpServerScript(outPath: string, hlConfig: HlServerConfig): void;
101
+ export default ClaudeMcpHyperliquidImpl;