@oracle-agent/oracle 0.10.0 → 0.12.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 (424) hide show
  1. package/LICENSE +115 -201
  2. package/README.md +82 -91
  3. package/SECURITY.md +37 -12
  4. package/SETUP.md +207 -272
  5. package/dist/action-receipts.mjs +1 -0
  6. package/dist/action-semantics.mjs +1 -0
  7. package/dist/address-book.mjs +2 -0
  8. package/dist/bin/desk-server.mjs +14 -0
  9. package/dist/bin/oracle-data-mcp.mjs +8 -0
  10. package/dist/bin/oracle-init.mjs +24 -0
  11. package/dist/bin/oracle-public-server.mjs +5 -0
  12. package/dist/bin/oracle-route.mjs +22 -0
  13. package/dist/bin/oracle-scan.mjs +18 -0
  14. package/dist/bin/oracle-upgrade.mjs +21 -0
  15. package/dist/bin/oracle.mjs +68 -0
  16. package/dist/chains.mjs +1 -0
  17. package/dist/cli/commands/auth.mjs +16 -0
  18. package/dist/cli/commands/bootstrap.mjs +18 -0
  19. package/dist/cli/commands/chain.mjs +21 -0
  20. package/dist/cli/commands/chat.mjs +35 -0
  21. package/dist/cli/commands/credential.mjs +1 -0
  22. package/dist/cli/commands/data-mcp.mjs +2 -0
  23. package/dist/cli/commands/data.mjs +12 -0
  24. package/dist/cli/commands/doctor.mjs +5 -0
  25. package/dist/cli/commands/gate.mjs +13 -0
  26. package/dist/cli/commands/help.mjs +1 -0
  27. package/dist/cli/commands/init.mjs +3 -0
  28. package/dist/cli/commands/mcp.mjs +33 -0
  29. package/dist/cli/commands/model.mjs +44 -0
  30. package/dist/cli/commands/prepare.mjs +2 -0
  31. package/dist/cli/commands/public.mjs +3 -0
  32. package/dist/cli/commands/route.mjs +2 -0
  33. package/dist/cli/commands/runner.mjs +1 -0
  34. package/dist/cli/commands/scan.mjs +2 -0
  35. package/dist/cli/commands/setup.mjs +34 -0
  36. package/dist/cli/commands/sign.mjs +4 -0
  37. package/dist/cli/commands/signer.mjs +1 -0
  38. package/dist/cli/commands/upgrade.mjs +2 -0
  39. package/dist/cli/commands/vault.mjs +1 -0
  40. package/dist/cli/commands/version.mjs +2 -0
  41. package/dist/data/desk-data.mjs +12 -0
  42. package/dist/index.mjs +17 -0
  43. package/dist/nft-gas-war-guard.mjs +1 -0
  44. package/dist/onboarding/harness-configs.mjs +4 -0
  45. package/dist/portfolio-risk.mjs +1 -0
  46. package/dist/prepare-envelope.mjs +1 -0
  47. package/dist/public-control/policy-schema.mjs +1 -0
  48. package/dist/router/index.mjs +2 -0
  49. package/dist/scanner/index.mjs +4 -0
  50. package/dist/signals/index.mjs +1 -0
  51. package/dist/watch-preferences.mjs +1 -0
  52. package/package.json +27 -65
  53. package/public/oracle-splash/assets/cli-chain-hyperliquid.jpg +0 -0
  54. package/public/oracle-splash/brand/aave.webp +0 -0
  55. package/public/oracle-splash/brand/aavev2.webp +0 -0
  56. package/public/oracle-splash/brand/aborean.webp +0 -0
  57. package/public/oracle-splash/brand/across.webp +0 -0
  58. package/public/oracle-splash/brand/aerodrome.webp +0 -0
  59. package/public/oracle-splash/brand/afi.webp +0 -0
  60. package/public/oracle-splash/brand/arcus.webp +0 -0
  61. package/public/oracle-splash/brand/aster.webp +0 -0
  62. package/public/oracle-splash/brand/avant.webp +0 -0
  63. package/public/oracle-splash/brand/balancer.webp +0 -0
  64. package/public/oracle-splash/brand/beefy.webp +0 -0
  65. package/public/oracle-splash/brand/benqi.webp +0 -0
  66. package/public/oracle-splash/brand/bestinslot.ico +0 -0
  67. package/public/oracle-splash/brand/bitfi.webp +0 -0
  68. package/public/oracle-splash/brand/bonkswap.webp +0 -0
  69. package/public/oracle-splash/brand/bouncebit.webp +0 -0
  70. package/public/oracle-splash/brand/camelot.webp +0 -0
  71. package/public/oracle-splash/brand/compound.webp +0 -0
  72. package/public/oracle-splash/brand/concrete.webp +0 -0
  73. package/public/oracle-splash/brand/cow.webp +0 -0
  74. package/public/oracle-splash/brand/curve.webp +0 -0
  75. package/public/oracle-splash/brand/derive.webp +0 -0
  76. package/public/oracle-splash/brand/dolomite.webp +0 -0
  77. package/public/oracle-splash/brand/eigenlayer.webp +0 -0
  78. package/public/oracle-splash/brand/ekubo.webp +0 -0
  79. package/public/oracle-splash/brand/ethena.webp +0 -0
  80. package/public/oracle-splash/brand/etherfi.webp +0 -0
  81. package/public/oracle-splash/brand/etherfiborrow.webp +0 -0
  82. package/public/oracle-splash/brand/felix.webp +0 -0
  83. package/public/oracle-splash/brand/fluid.webp +0 -0
  84. package/public/oracle-splash/brand/fluxbeam.webp +0 -0
  85. package/public/oracle-splash/brand/folks.webp +0 -0
  86. package/public/oracle-splash/brand/fortyacres.webp +0 -0
  87. package/public/oracle-splash/brand/gainsnetwork.webp +0 -0
  88. package/public/oracle-splash/brand/gassss.webp +0 -0
  89. package/public/oracle-splash/brand/gmx.webp +0 -0
  90. package/public/oracle-splash/brand/harmonix.webp +0 -0
  91. package/public/oracle-splash/brand/hlorderbook.webp +0 -0
  92. package/public/oracle-splash/brand/hlp.webp +0 -0
  93. package/public/oracle-splash/brand/hop.webp +0 -0
  94. package/public/oracle-splash/brand/hyperbeat.webp +0 -0
  95. package/public/oracle-splash/brand/hyperlend.webp +0 -0
  96. package/public/oracle-splash/brand/hyperliquid.webp +0 -0
  97. package/public/oracle-splash/brand/hyperliquidhpl.webp +0 -0
  98. package/public/oracle-splash/brand/hyperliquidspot.webp +0 -0
  99. package/public/oracle-splash/brand/hyperswap.webp +0 -0
  100. package/public/oracle-splash/brand/hypha.webp +0 -0
  101. package/public/oracle-splash/brand/joedex.webp +0 -0
  102. package/public/oracle-splash/brand/jupiter.webp +0 -0
  103. package/public/oracle-splash/brand/kelp.webp +0 -0
  104. package/public/oracle-splash/brand/kinetiq.webp +0 -0
  105. package/public/oracle-splash/brand/kmhype.webp +0 -0
  106. package/public/oracle-splash/brand/kona.webp +0 -0
  107. package/public/oracle-splash/brand/konalend.webp +0 -0
  108. package/public/oracle-splash/brand/lfj.webp +0 -0
  109. package/public/oracle-splash/brand/lido.webp +0 -0
  110. package/public/oracle-splash/brand/lifi.webp +0 -0
  111. package/public/oracle-splash/brand/lighter.webp +0 -0
  112. package/public/oracle-splash/brand/lista.webp +0 -0
  113. package/public/oracle-splash/brand/loopedhype.webp +0 -0
  114. package/public/oracle-splash/brand/lorenzo.webp +0 -0
  115. package/public/oracle-splash/brand/magic-eden.webp +0 -0
  116. package/public/oracle-splash/brand/magiceden.webp +0 -0
  117. package/public/oracle-splash/brand/mempool.png +0 -0
  118. package/public/oracle-splash/brand/meteora.webp +0 -0
  119. package/public/oracle-splash/brand/morpho.webp +0 -0
  120. package/public/oracle-splash/brand/myriad.webp +0 -0
  121. package/public/oracle-splash/brand/noxa.webp +0 -0
  122. package/public/oracle-splash/brand/odos.webp +0 -0
  123. package/public/oracle-splash/brand/oneinch.webp +0 -0
  124. package/public/oracle-splash/brand/openbook.webp +0 -0
  125. package/public/oracle-splash/brand/opensea.webp +0 -0
  126. package/public/oracle-splash/brand/orca.webp +0 -0
  127. package/public/oracle-splash/brand/ordinals.png +0 -0
  128. package/public/oracle-splash/brand/ostium.webp +0 -0
  129. package/public/oracle-splash/brand/pancakeswap.webp +0 -0
  130. package/public/oracle-splash/brand/pendle.webp +0 -0
  131. package/public/oracle-splash/brand/perena.webp +0 -0
  132. package/public/oracle-splash/brand/pharaoh.webp +0 -0
  133. package/public/oracle-splash/brand/phoenix.webp +0 -0
  134. package/public/oracle-splash/brand/polymarket.webp +0 -0
  135. package/public/oracle-splash/brand/polynomial.webp +0 -0
  136. package/public/oracle-splash/brand/projectx.webp +0 -0
  137. package/public/oracle-splash/brand/pumpfun.webp +0 -0
  138. package/public/oracle-splash/brand/quickswap.webp +0 -0
  139. package/public/oracle-splash/brand/rain.webp +0 -0
  140. package/public/oracle-splash/brand/raydium.webp +0 -0
  141. package/public/oracle-splash/brand/relay.webp +0 -0
  142. package/public/oracle-splash/brand/rocketpool.webp +0 -0
  143. package/public/oracle-splash/brand/saber.webp +0 -0
  144. package/public/oracle-splash/brand/sakuraswap.webp +0 -0
  145. package/public/oracle-splash/brand/sanctum.webp +0 -0
  146. package/public/oracle-splash/brand/satflow.png +0 -0
  147. package/public/oracle-splash/brand/sierra.webp +0 -0
  148. package/public/oracle-splash/brand/sky.webp +0 -0
  149. package/public/oracle-splash/brand/solv.webp +0 -0
  150. package/public/oracle-splash/brand/spark.webp +0 -0
  151. package/public/oracle-splash/brand/sparksavings.webp +0 -0
  152. package/public/oracle-splash/brand/sphere.webp +0 -0
  153. package/public/oracle-splash/brand/ssv.webp +0 -0
  154. package/public/oracle-splash/brand/stabble.webp +0 -0
  155. package/public/oracle-splash/brand/stableswap.webp +0 -0
  156. package/public/oracle-splash/brand/stakewise.webp +0 -0
  157. package/public/oracle-splash/brand/stargate.webp +0 -0
  158. package/public/oracle-splash/brand/sthype.webp +0 -0
  159. package/public/oracle-splash/brand/sushiswap.webp +0 -0
  160. package/public/oracle-splash/brand/unisat.png +0 -0
  161. package/public/oracle-splash/brand/uniswap.webp +0 -0
  162. package/public/oracle-splash/brand/uniswapv2.webp +0 -0
  163. package/public/oracle-splash/brand/uniswapv4.webp +0 -0
  164. package/public/oracle-splash/brand/unit.webp +0 -0
  165. package/public/oracle-splash/brand/velodrome.webp +0 -0
  166. package/public/oracle-splash/brand/velora.webp +0 -0
  167. package/public/oracle-splash/brand/venus.webp +0 -0
  168. package/public/oracle-splash/brand/wbeth.webp +0 -0
  169. package/public/oracle-splash/brand/xsy.webp +0 -0
  170. package/public/oracle-splash/brand/yieldyak.webp +0 -0
  171. package/public/oracle-splash/brand/zerobase.webp +0 -0
  172. package/public/oracle-splash/brand/zerox.webp +0 -0
  173. package/public/oracle-splash/index.html +246 -169
  174. package/CONTRIBUTING.md +0 -98
  175. package/bin/desk-server.mjs +0 -440
  176. package/bin/oracle-data-mcp.mjs +0 -1010
  177. package/bin/oracle-init.mjs +0 -496
  178. package/bin/oracle-public-server.mjs +0 -36
  179. package/bin/oracle-route.mjs +0 -254
  180. package/bin/oracle-scan.mjs +0 -192
  181. package/bin/oracle-upgrade.mjs +0 -42
  182. package/bin/oracle.mjs +0 -33
  183. package/docs/adding-a-chain.md +0 -229
  184. package/docs/architecture.md +0 -136
  185. package/docs/cli.md +0 -47
  186. package/docs/connectors.md +0 -13
  187. package/docs/oracle-pack-standard.md +0 -29
  188. package/docs/profiles.md +0 -154
  189. package/examples/add-a-chain.mjs +0 -65
  190. package/examples/oracle-pack-template.mjs +0 -38
  191. package/examples/research-a-token.mjs +0 -70
  192. package/plugins/oracle-owner-gate/__init__.py +0 -227
  193. package/plugins/oracle-owner-gate/plugin.yaml +0 -9
  194. package/profiles/_template/SOUL.md +0 -54
  195. package/profiles/_template/profile.json +0 -22
  196. package/profiles/bitcoin-agent/SOUL.md +0 -31
  197. package/profiles/bitcoin-agent/profile.json +0 -32
  198. package/profiles/hyperliquid-agent/SOUL.md +0 -34
  199. package/profiles/hyperliquid-agent/profile.json +0 -37
  200. package/profiles/oracle/SOUL.md +0 -107
  201. package/profiles/oracle/profile.json +0 -39
  202. package/profiles/polymarket-agent/SOUL.md +0 -35
  203. package/profiles/polymarket-agent/profile.json +0 -34
  204. package/profiles/profile.schema.json +0 -90
  205. package/profiles/protocol-builder/SOUL.md +0 -57
  206. package/profiles/protocol-builder/profile.json +0 -39
  207. package/profiles/robinhood-agent/SOUL.md +0 -53
  208. package/profiles/robinhood-agent/profile.json +0 -40
  209. package/profiles/solana-agent/SOUL.md +0 -37
  210. package/profiles/solana-agent/profile.json +0 -37
  211. package/profiles/stable-agent/SOUL.md +0 -43
  212. package/profiles/stable-agent/profile.json +0 -37
  213. package/protocols/templates/safe-erc20/SECURITY.md +0 -16
  214. package/protocols/templates/safe-erc20/foundry.toml +0 -12
  215. package/protocols/templates/safe-erc20/remappings.txt +0 -2
  216. package/protocols/templates/safe-erc20/src/SafeERC20.sol +0 -53
  217. package/protocols/templates/safe-erc20/test/SafeERC20.t.sol +0 -72
  218. package/scripts/adversarial-bench.mjs +0 -114
  219. package/scripts/build-inscription.py +0 -230
  220. package/scripts/check-doc-drift.mjs +0 -112
  221. package/scripts/check-test-count.mjs +0 -105
  222. package/scripts/e2e-hl-markets.mjs +0 -21
  223. package/scripts/e2e-hl-perps.mjs +0 -48
  224. package/scripts/e2e-hypercore-staking.mjs +0 -128
  225. package/scripts/e2e-solana-bitcoin.mjs +0 -183
  226. package/scripts/protocol-template-gate.mjs +0 -15
  227. package/scripts/public-api-scan.mjs +0 -23
  228. package/scripts/secret-scan.mjs +0 -181
  229. package/scripts/verify-v3-venues.mjs +0 -192
  230. package/skills/balance/SKILL.md +0 -176
  231. package/skills/oracle-action-semantics/SKILL.md +0 -40
  232. package/skills/oracle-best-execution/SKILL.md +0 -127
  233. package/skills/oracle-bitcoin/SKILL.md +0 -53
  234. package/skills/oracle-chain-graphs-telegram-cards/SKILL.md +0 -59
  235. package/skills/oracle-chat/SKILL.md +0 -61
  236. package/skills/oracle-chat/chain.SKILL.md +0 -31
  237. package/skills/oracle-chat/setup.SKILL.md +0 -37
  238. package/skills/oracle-circuit-breaker/SKILL.md +0 -51
  239. package/skills/oracle-contract-research/SKILL.md +0 -55
  240. package/skills/oracle-desk/SKILL.md +0 -58
  241. package/skills/oracle-dex-launch/SKILL.md +0 -38
  242. package/skills/oracle-grants/SKILL.md +0 -69
  243. package/skills/oracle-hypercore-staking/SKILL.md +0 -57
  244. package/skills/oracle-hyperliquid/SKILL.md +0 -56
  245. package/skills/oracle-meme-token-sniper/SKILL.md +0 -73
  246. package/skills/oracle-multichain-nft-launch/SKILL.md +0 -338
  247. package/skills/oracle-multichain-token-launch/SKILL.md +0 -300
  248. package/skills/oracle-nft-gacha-launch/SKILL.md +0 -48
  249. package/skills/oracle-nft-mint-gas-war/SKILL.md +0 -63
  250. package/skills/oracle-polymarket/SKILL.md +0 -60
  251. package/skills/oracle-protocol-builder/SKILL.md +0 -59
  252. package/skills/oracle-protocol-security/SKILL.md +0 -60
  253. package/skills/oracle-public-product/SKILL.md +0 -44
  254. package/skills/oracle-receipts/SKILL.md +0 -52
  255. package/skills/oracle-rfq-tokenized-assets/SKILL.md +0 -69
  256. package/skills/oracle-smart-wallet-scanner/SKILL.md +0 -49
  257. package/skills/oracle-solana/SKILL.md +0 -65
  258. package/skills/oracle-solana-nft/SKILL.md +0 -54
  259. package/skills/oracle-token-research/SKILL.md +0 -67
  260. package/skins/oracle.yaml +0 -56
  261. package/src/action-receipts.mjs +0 -168
  262. package/src/action-semantics.mjs +0 -62
  263. package/src/address-book.mjs +0 -208
  264. package/src/agent-auth.mjs +0 -206
  265. package/src/approval-guard.mjs +0 -282
  266. package/src/attestation-secret.mjs +0 -88
  267. package/src/audit-log.mjs +0 -196
  268. package/src/auth/oauth.mjs +0 -672
  269. package/src/auto-slippage.mjs +0 -378
  270. package/src/capability-posture.mjs +0 -125
  271. package/src/chains.mjs +0 -62
  272. package/src/cli/chain-catalog.mjs +0 -215
  273. package/src/cli/chain-state.mjs +0 -74
  274. package/src/cli/commands/auth.mjs +0 -193
  275. package/src/cli/commands/bootstrap.mjs +0 -87
  276. package/src/cli/commands/chain.mjs +0 -143
  277. package/src/cli/commands/chat.mjs +0 -434
  278. package/src/cli/commands/credential.mjs +0 -9
  279. package/src/cli/commands/data-mcp.mjs +0 -18
  280. package/src/cli/commands/data.mjs +0 -73
  281. package/src/cli/commands/doctor.mjs +0 -126
  282. package/src/cli/commands/help.mjs +0 -7
  283. package/src/cli/commands/init.mjs +0 -27
  284. package/src/cli/commands/mcp.mjs +0 -142
  285. package/src/cli/commands/model.mjs +0 -99
  286. package/src/cli/commands/prepare.mjs +0 -12
  287. package/src/cli/commands/public.mjs +0 -20
  288. package/src/cli/commands/route.mjs +0 -12
  289. package/src/cli/commands/runner.mjs +0 -9
  290. package/src/cli/commands/scan.mjs +0 -12
  291. package/src/cli/commands/setup.mjs +0 -275
  292. package/src/cli/commands/sign.mjs +0 -21
  293. package/src/cli/commands/signer.mjs +0 -9
  294. package/src/cli/commands/upgrade.mjs +0 -12
  295. package/src/cli/commands/vault.mjs +0 -9
  296. package/src/cli/commands/version.mjs +0 -22
  297. package/src/cli/first-run.mjs +0 -23
  298. package/src/cli/kernel.mjs +0 -239
  299. package/src/cli/mcp-targets/chatgpt.mjs +0 -51
  300. package/src/cli/mcp-targets/claude-code.mjs +0 -39
  301. package/src/cli/mcp-targets/claude-desktop.mjs +0 -24
  302. package/src/cli/mcp-targets/codex.mjs +0 -41
  303. package/src/cli/mcp-targets/shared.mjs +0 -61
  304. package/src/cli/messaging-platforms.mjs +0 -209
  305. package/src/cli/model-config.mjs +0 -70
  306. package/src/cli/operator-dispatch.mjs +0 -258
  307. package/src/cli/oracle-harness.py +0 -415
  308. package/src/cli/paths.mjs +0 -83
  309. package/src/cli/runtime.mjs +0 -351
  310. package/src/cli/setup-state.mjs +0 -168
  311. package/src/cli/spawn-child.mjs +0 -43
  312. package/src/data/catalog.mjs +0 -554
  313. package/src/data/desk-data.mjs +0 -683
  314. package/src/data/http.mjs +0 -253
  315. package/src/data/provider-endpoint.mjs +0 -94
  316. package/src/data/providers/aerodrome.mjs +0 -245
  317. package/src/data/providers/balancer.mjs +0 -209
  318. package/src/data/providers/bitcoin-esplora.mjs +0 -216
  319. package/src/data/providers/bitcoin-meta.mjs +0 -378
  320. package/src/data/providers/blockscout.mjs +0 -14
  321. package/src/data/providers/bridges.mjs +0 -242
  322. package/src/data/providers/cowswap.mjs +0 -415
  323. package/src/data/providers/curve.mjs +0 -201
  324. package/src/data/providers/defillama.mjs +0 -88
  325. package/src/data/providers/dexscreener.mjs +0 -43
  326. package/src/data/providers/evm-rpc.mjs +0 -222
  327. package/src/data/providers/geckoterminal.mjs +0 -34
  328. package/src/data/providers/gmx.mjs +0 -496
  329. package/src/data/providers/hl-assets.mjs +0 -165
  330. package/src/data/providers/hl-info.mjs +0 -108
  331. package/src/data/providers/hl-markets.mjs +0 -210
  332. package/src/data/providers/hl-outcome.mjs +0 -61
  333. package/src/data/providers/hl-perps.mjs +0 -387
  334. package/src/data/providers/hl-staking.mjs +0 -353
  335. package/src/data/providers/hl-ws.mjs +0 -119
  336. package/src/data/providers/hyperevm-dex.mjs +0 -49
  337. package/src/data/providers/jupiter.mjs +0 -183
  338. package/src/data/providers/lifi.mjs +0 -151
  339. package/src/data/providers/magiceden-sol.mjs +0 -393
  340. package/src/data/providers/morpho.mjs +0 -173
  341. package/src/data/providers/nft-gallery.mjs +0 -163
  342. package/src/data/providers/nft-portfolio.mjs +0 -494
  343. package/src/data/providers/odos.mjs +0 -156
  344. package/src/data/providers/oneinch.mjs +0 -174
  345. package/src/data/providers/opensea-multichain.mjs +0 -136
  346. package/src/data/providers/opensea-nft.mjs +0 -371
  347. package/src/data/providers/paraswap.mjs +0 -118
  348. package/src/data/providers/pendle.mjs +0 -187
  349. package/src/data/providers/poly-clob.mjs +0 -283
  350. package/src/data/providers/poly-public.mjs +0 -96
  351. package/src/data/providers/poly-ws.mjs +0 -103
  352. package/src/data/providers/portfolio-history.mjs +0 -394
  353. package/src/data/providers/portfolio.mjs +0 -594
  354. package/src/data/providers/rfq.mjs +0 -15
  355. package/src/data/providers/rh-agent.mjs +0 -59
  356. package/src/data/providers/satflow.mjs +0 -338
  357. package/src/data/providers/solana-rpc.mjs +0 -197
  358. package/src/data/providers/uniswap-v3.mjs +0 -320
  359. package/src/data/providers/zerox.mjs +0 -167
  360. package/src/data/public-api-scan.mjs +0 -61
  361. package/src/data/quote-placeholder.mjs +0 -31
  362. package/src/exact-integer.mjs +0 -72
  363. package/src/exec-policy.mjs +0 -455
  364. package/src/flags.mjs +0 -15
  365. package/src/fresh-window.mjs +0 -76
  366. package/src/gmx-attestation.mjs +0 -176
  367. package/src/index.mjs +0 -100
  368. package/src/nft-gas-war-guard.mjs +0 -139
  369. package/src/onboarding/agent-keys.mjs +0 -161
  370. package/src/onboarding/harness-configs.mjs +0 -102
  371. package/src/onboarding/index.mjs +0 -18
  372. package/src/onboarding/tiers.mjs +0 -139
  373. package/src/oracle-env.mjs +0 -47
  374. package/src/portfolio-risk.mjs +0 -170
  375. package/src/prepare-envelope.mjs +0 -186
  376. package/src/profile-upgrade.mjs +0 -277
  377. package/src/protocol-execution.mjs +0 -84
  378. package/src/protocol-templates/gate.mjs +0 -179
  379. package/src/protocol-templates/prepare-deploy.mjs +0 -81
  380. package/src/public-api/buzz-integration.mjs +0 -256
  381. package/src/public-api/connect-agent.mjs +0 -416
  382. package/src/public-api/grants.mjs +0 -142
  383. package/src/public-api/http.mjs +0 -389
  384. package/src/public-control/aa-adapter.mjs +0 -402
  385. package/src/public-control/build-registry.mjs +0 -227
  386. package/src/public-control/bundler-client.mjs +0 -357
  387. package/src/public-control/grant-indexer.mjs +0 -296
  388. package/src/public-control/policy-render.mjs +0 -69
  389. package/src/public-control/policy-schema.mjs +0 -318
  390. package/src/public-control/runtime-config.mjs +0 -275
  391. package/src/public-control/session-key-model.mjs +0 -374
  392. package/src/public-control/session-orchestrator.mjs +0 -412
  393. package/src/rfq/intent.mjs +0 -180
  394. package/src/rfq/sources.mjs +0 -181
  395. package/src/route-attestation.mjs +0 -132
  396. package/src/router/best-execution.mjs +0 -326
  397. package/src/router/index.mjs +0 -226
  398. package/src/router/prepare-bridge.mjs +0 -289
  399. package/src/router/prepare-route.mjs +0 -381
  400. package/src/router/proposal.mjs +0 -311
  401. package/src/router/risk-classifier.mjs +0 -119
  402. package/src/router/route-sources.mjs +0 -329
  403. package/src/scanner/chains.config.mjs +0 -430
  404. package/src/scanner/contract.mjs +0 -270
  405. package/src/scanner/evm-scanner.mjs +0 -394
  406. package/src/scanner/index.mjs +0 -9
  407. package/src/scanner/v2-venue.mjs +0 -335
  408. package/src/scanner/v3-venue.mjs +0 -290
  409. package/src/scopes.mjs +0 -44
  410. package/src/sell-simulation.mjs +0 -167
  411. package/src/signals/engine.mjs +0 -146
  412. package/src/signals/index.mjs +0 -1
  413. package/src/token-transfer-guard.mjs +0 -188
  414. package/src/tui/app.mjs +0 -438
  415. package/src/tui/backend.mjs +0 -145
  416. package/src/tui/format.mjs +0 -272
  417. package/src/tui/gateway-client.mjs +0 -177
  418. package/src/tui/input.mjs +0 -501
  419. package/src/tui/renderer.mjs +0 -443
  420. package/src/tui/standalone-client.mjs +0 -666
  421. package/src/tui/theme.mjs +0 -81
  422. package/src/vault-attestation.mjs +0 -146
  423. package/src/venues.mjs +0 -206
  424. package/src/watch-preferences.mjs +0 -85
@@ -1,48 +0,0 @@
1
- import { data as desk } from "../src/data/desk-data.mjs";
2
-
3
- const info = await desk.call("hl-perps", "assetInfo", { coin: "BTC" });
4
- console.log(`BTC assetId=${info.assetId} szDecimals=${info.szDecimals} maxLev=${info.maxLeverage}x mark=$${info.markPx}`);
5
-
6
- // 1. LIMIT BUY
7
- const lim = await desk.call("hl-perps", "prepareOrder", {
8
- coin: "BTC", side: "buy", type: "limit", price: "60000.123456789", size: "0.0123456", tif: "Gtc",
9
- });
10
- console.log(`\nLIMIT BUY px=${lim.price} sz=${lim.size} notional=$${lim.notionalUsd?.toFixed(2)} tif=${JSON.stringify(lim.action.orders[0].t)}`);
11
- console.log(` signingReady=${lim.signingReady} broadcastReady=${lim.broadcastReady} requiresUserSig=${lim.requiresUserSignature}`);
12
-
13
- // 2. MARKET BUY with slippage cap
14
- const mkt = await desk.call("hl-perps", "prepareOrder", {
15
- coin: "ETH", side: "buy", type: "market", size: "0.5", maxSlippageBps: 50,
16
- });
17
- console.log(`\nMARKET BUY ETH aggressive px=${mkt.price} sz=${mkt.size} tif=${mkt.action.orders[0].t.limit.tif}`);
18
-
19
- // 3. slippage cap enforced
20
- try {
21
- await desk.call("hl-perps", "prepareOrder", { coin: "ETH", side: "buy", type: "market", size: "1", maxSlippageBps: 500 });
22
- console.log(" !! 500bps ACCEPTED — cap broken");
23
- } catch (e) { console.log(` 500bps rejected: ${e.message.slice(0, 60)}`); }
24
-
25
- // 4. LEVERAGE
26
- const lev = await desk.call("hl-perps", "prepareLeverage", { coin: "BTC", leverage: 25, marginMode: "isolated" });
27
- console.log(`\nLEVERAGE ${lev.leverage}x ${lev.marginMode} isCross=${lev.action.isCross}`);
28
- console.log(` warning: ${lev.liquidationWarning}`);
29
-
30
- try {
31
- await desk.call("hl-perps", "prepareLeverage", { coin: "BTC", leverage: 999 });
32
- console.log(" !! 999x ACCEPTED — cap broken");
33
- } catch (e) { console.log(` 999x rejected: ${e.message.slice(0, 70)}`); }
34
-
35
- // 5. BRACKET: entry + TP + SL
36
- const br = await desk.call("hl-perps", "prepareBracket", {
37
- coin: "BTC", side: "buy", type: "limit", price: "60000", size: "0.01",
38
- takeProfitPx: "72000", stopLossPx: "57000",
39
- });
40
- console.log(`\nBRACKET legs=${br.legs} entry=${br.entry.price} tp=${br.takeProfitPx} sl=${br.stopLossPx} grouping=${br.action.grouping}`);
41
- console.log(` tp reduceOnly=${br.action.orders[1].r} trigger=${JSON.stringify(br.action.orders[1].t.trigger)}`);
42
- console.log(` sl reduceOnly=${br.action.orders[2].r} trigger=${JSON.stringify(br.action.orders[2].t.trigger)}`);
43
-
44
- // 6. CANCEL
45
- const c = await desk.call("hl-perps", "prepareCancel", { coin: "BTC", orderId: 12345 });
46
- console.log(`\nCANCEL oid=${c.orderId} action=${JSON.stringify(c.action)}`);
47
-
48
- console.log("\nNo submit function exists in hl-perps — every result is user-signed.");
@@ -1,128 +0,0 @@
1
- import { data as desk } from "../src/data/desk-data.mjs";
2
- import {
3
- hlPrepareStakeDeposit,
4
- hlPrepareStakeWithdraw,
5
- hlPrepareDelegate,
6
- hypeToWei,
7
- weiToHype,
8
- } from "../src/data/providers/hl-staking.mjs";
9
-
10
- const USER = process.env.ORACLE_E2E_EVM_ADDRESS || "0x0000000000000000000000000000000000000001";
11
- const results = [];
12
- function log(lane, status, detail) {
13
- results.push({ lane, status });
14
- console.log(`${status === "ok" ? "OK " : "FAIL"} ${lane} :: ${detail}`);
15
- }
16
- async function run(lane, fn) {
17
- try {
18
- log(lane, "ok", await fn());
19
- } catch (e) {
20
- log(lane, "fail", String(e?.message || e).slice(0, 150));
21
- }
22
- }
23
-
24
- console.log("== HYPERCORE STAKING ==");
25
-
26
- let validator = null;
27
- await run("hl.staking.validators", async () => {
28
- const v = await desk.hl.staking.validators();
29
- const active = v.validators.filter((x) => x.isActive && !x.isJailed);
30
- validator = active[0]?.validator || v.validators[0]?.validator;
31
- return `validators=${v.count} activeUnjailed=${active.length} first=${(validator || "").slice(0, 10)}..`;
32
- });
33
-
34
- await run("hl.staking.health", async () => {
35
- const h = await desk.hl.staking.health();
36
- if (!h.ok) throw new Error("staking lane unhealthy");
37
- return `ok validators=${h.validators} chain=${h.chain}`;
38
- });
39
-
40
- await run("hl.staking.delegatorSummary", async () => {
41
- const s = await desk.hl.staking.summary(USER);
42
- return `delegated=${s.delegatedWei} undelegated=${s.undelegatedWei} pendingWithdrawals=${s.nPendingWithdrawals}`;
43
- });
44
-
45
- await run("hl.staking.delegations", async () => {
46
- const d = await desk.hl.staking.delegations(USER);
47
- return `count=${d.count}`;
48
- });
49
-
50
- await run("hl.staking.rewards", async () => {
51
- const r = await desk.hl.staking.rewards(USER);
52
- return `rewards=${r.rewards.length}`;
53
- });
54
-
55
- await run("hl.staking.preflight", async () => {
56
- const p = await desk.hl.staking.preflight(USER);
57
- return `undelegated=${p.stakingBalanceUndelegated} queueDays=${p.unstakingQueueDays} lockupDays=${p.validatorLockupDays}`;
58
- });
59
-
60
- await run("hl.staking.units", async () => {
61
- const w = hypeToWei("1.5");
62
- if (w !== "150000000") throw new Error(`1.5 HYPE -> ${w}, expected 150000000`);
63
- if (weiToHype("150000000") !== "1.5") throw new Error("roundtrip failed");
64
- return `1.5 HYPE = ${w} wei roundtrip ok`;
65
- });
66
-
67
- await run("hl.staking.prepareStake", async () => {
68
- const p = hlPrepareStakeDeposit({ amountHype: "2.5", maxHype: "10" });
69
- if (p.action.type !== "cDeposit") throw new Error("wrong action type");
70
- if (p.broadcastReady !== false || p.signingReady !== false) throw new Error("leaked readiness");
71
- if (!p.requiresUserSignature) throw new Error("must require user signature");
72
- return `cDeposit wei=${p.action.wei} primaryType=${p.typedData.primaryType} broadcastReady=false`;
73
- });
74
-
75
- await run("hl.staking.prepareStake.capBreach", async () => {
76
- try {
77
- hlPrepareStakeDeposit({ amountHype: "50", maxHype: "10" });
78
- } catch (e) {
79
- return `rejected over-cap: ${String(e.message).slice(0, 70)}`;
80
- }
81
- throw new Error("cap was NOT enforced");
82
- });
83
-
84
- await run("hl.staking.prepareDelegate", async () => {
85
- if (!validator) throw new Error("no validator resolved");
86
- const p = hlPrepareDelegate({ validator, amountHype: "2.5", isUndelegate: false, maxHype: "10" });
87
- if (p.action.type !== "tokenDelegate" || p.action.isUndelegate !== false) throw new Error("wrong action");
88
- return `tokenDelegate validator=${p.action.validator.slice(0, 10)}.. wei=${p.action.wei} isUndelegate=false`;
89
- });
90
-
91
- await run("hl.staking.prepareUndelegate", async () => {
92
- const p = hlPrepareDelegate({ validator, amountHype: "2.5", isUndelegate: true });
93
- if (p.action.isUndelegate !== true) throw new Error("undelegate flag lost");
94
- return `tokenDelegate isUndelegate=true kind=${p.kind}`;
95
- });
96
-
97
- await run("hl.staking.prepareUnstake", async () => {
98
- const p = hlPrepareStakeWithdraw({ amountHype: "2.5" });
99
- if (p.action.type !== "cWithdraw") throw new Error("wrong action type");
100
- if (!p.notes.join(" ").includes("7 day")) throw new Error("missing unstaking queue warning");
101
- return `cWithdraw wei=${p.action.wei} queue warning present`;
102
- });
103
-
104
- await run("hl.staking.badAmount", async () => {
105
- try {
106
- hlPrepareStakeDeposit({ amountHype: "0" });
107
- } catch (e) {
108
- return `rejected zero amount`;
109
- }
110
- throw new Error("zero amount accepted");
111
- });
112
-
113
- await run("hl.staking.badValidator", async () => {
114
- try {
115
- hlPrepareDelegate({ validator: "not-an-address", amountHype: "1" });
116
- } catch (e) {
117
- return `rejected bad validator`;
118
- }
119
- throw new Error("bad validator accepted");
120
- });
121
-
122
- const failed = results.filter((r) => r.status === "fail");
123
- console.log(`\nlanes=${results.length} ok=${results.length - failed.length} failed=${failed.length}`);
124
- if (failed.length) {
125
- console.log(`FAILED: ${failed.map((f) => f.lane).join(", ")}`);
126
- process.exit(1);
127
- }
128
- console.log("HYPERCORE STAKING OK: reads live, stake/unstake/delegate prepare-only, caps enforced.");
@@ -1,183 +0,0 @@
1
- // Oracle end-to-end LIVE lane probe: Solana + Bitcoin.
2
- // Read/quote/prepare/simulate only. No signing. No broadcast. No keys required.
3
- //
4
- // Run: node scripts/e2e-solana-bitcoin.mjs
5
- // Exit 0 = every mandatory lane answered live. Optional keyed lanes are reported, not failed.
6
-
7
- import { data as desk } from "../src/data/desk-data.mjs";
8
- import { jupiterQuote, jupiterPrepareSwap, SOL_MINT, USDC_MINT } from "../src/data/providers/jupiter.mjs";
9
- import { solanaSimulateTransaction } from "../src/data/providers/solana-rpc.mjs";
10
- import { magicEdenSolStats, magicEdenSolListings, magicEdenSolPrepareBuy } from "../src/data/providers/magiceden-sol.mjs";
11
-
12
- const PROBE_WALLET = process.env.ORACLE_E2E_SOL_PUBKEY || "11111111111111111111111111111111";
13
- const PROBE_BTC = process.env.ORACLE_E2E_BTC_ADDRESS || "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq";
14
-
15
- const results = [];
16
- function record(lane, status, detail) {
17
- results.push({ lane, status, detail });
18
- const tag = status === "ok" ? "OK " : status === "keyed" ? "KEY " : "FAIL";
19
- console.log(`${tag} ${lane} :: ${detail}`);
20
- }
21
-
22
- async function run(lane, fn, { optional = false } = {}) {
23
- try {
24
- const detail = await fn();
25
- record(lane, "ok", detail);
26
- return true;
27
- } catch (error) {
28
- const message = String(error?.message || error).slice(0, 140);
29
- record(lane, optional ? "keyed" : "fail", message);
30
- return optional;
31
- }
32
- }
33
-
34
- console.log("== SOLANA ==");
35
-
36
- await run("solana.rpc.health", async () => {
37
- const health = await desk.solana.health();
38
- if (!health?.ok) throw new Error(`rpc unhealthy ${JSON.stringify(health).slice(0, 80)}`);
39
- return `cluster ok slot lane live`;
40
- });
41
-
42
- await run("solana.rpc.balance", async () => {
43
- const bal = await desk.solana.balance(PROBE_WALLET);
44
- return `lamports=${bal?.lamports ?? bal?.value ?? "n/a"}`;
45
- });
46
-
47
- await run("solana.rpc.tokenAccounts", async () => {
48
- const accounts = await desk.solana.tokenAccounts({ owner: PROBE_WALLET });
49
- return `accounts=${accounts?.accounts?.length ?? 0}`;
50
- });
51
-
52
- let jupQuote = null;
53
- await run("solana.jupiter.quote(SOL->USDC)", async () => {
54
- jupQuote = await jupiterQuote({ inputMint: SOL_MINT, outputMint: USDC_MINT, amount: "10000000", slippageBps: 50 });
55
- const g = jupQuote.solanaGuard;
56
- if (jupQuote.executionReady !== false) throw new Error("quote must not be executionReady");
57
- if (g.slippageBps > 100) throw new Error("slippage cap breached");
58
- return `out=${jupQuote.quote.outAmount} bps=${g.slippageBps} expires=${g.expiresAtMs - g.quotedAtMs}ms execReady=false`;
59
- });
60
-
61
- await run("solana.jupiter.slippageCap", async () => {
62
- try {
63
- await jupiterQuote({ inputMint: SOL_MINT, outputMint: USDC_MINT, amount: "10000000", slippageBps: 500 });
64
- } catch (error) {
65
- return `rejected 500bps: ${String(error.message).slice(0, 60)}`;
66
- }
67
- throw new Error("500 bps was NOT rejected");
68
- });
69
-
70
- let jupPrepared = null;
71
- await run("solana.jupiter.prepareSwap", async () => {
72
- jupPrepared = await jupiterPrepareSwap({
73
- quoteResponse: jupQuote.quote,
74
- userPublicKey: PROBE_WALLET,
75
- });
76
- if (jupPrepared.signingReady !== false || jupPrepared.broadcastReady !== false) throw new Error("prepare leaked signing/broadcast readiness");
77
- if (!jupPrepared.requiresUserSignature) throw new Error("prepare must require user signature");
78
- return `tx=${jupPrepared.swapTransaction.length}b64 requiresUserSig=true signingReady=false broadcastReady=false`;
79
- });
80
-
81
- await run("solana.rpc.simulate(preparedSwap)", async () => {
82
- const sim = await solanaSimulateTransaction({ transaction: jupPrepared.swapTransaction, sigVerify: false });
83
- const err = sim?.err ?? sim?.value?.err ?? sim?.raw?.value?.err ?? null;
84
- const units = sim?.unitsConsumed ?? sim?.value?.unitsConsumed ?? sim?.raw?.value?.unitsConsumed ?? null;
85
- return `err=${JSON.stringify(err)} unitsConsumed=${units}`;
86
- });
87
-
88
- await run("solana.nft.magiceden.stats", async () => {
89
- const stats = await magicEdenSolStats({ symbol: "mad_lads" });
90
- if (!(stats.floorPriceSol > 0)) throw new Error("no floor");
91
- return `floor=${stats.floorPriceSol} SOL listed=${stats.listedCount}`;
92
- });
93
-
94
- let meListing = null;
95
- await run("solana.nft.magiceden.listings", async () => {
96
- const out = await magicEdenSolListings({ symbol: "mad_lads", limit: 1 });
97
- meListing = out.listings[0];
98
- if (!meListing?.tokenMint) throw new Error("no listing");
99
- return `mint=${meListing.tokenMint.slice(0, 8)}.. price=${meListing.priceSol} SOL seller=${meListing.seller.slice(0, 6)}..`;
100
- });
101
-
102
- await run(
103
- "solana.nft.magiceden.prepareBuy",
104
- async () => {
105
- const prep = await magicEdenSolPrepareBuy({
106
- buyer: PROBE_WALLET,
107
- seller: meListing.seller,
108
- auctionHouse: meListing.auctionHouse,
109
- tokenMint: meListing.tokenMint,
110
- tokenATA: meListing.tokenATA,
111
- priceSol: meListing.priceSol,
112
- });
113
- if (prep.broadcastReady !== false) throw new Error("prepare leaked broadcast readiness");
114
- return `tx prepared bytes=${String(prep.transaction || "").length} requiresUserSig=${prep.requiresUserSignature}`;
115
- },
116
- { optional: true }
117
- );
118
-
119
- console.log("== BITCOIN ==");
120
-
121
- await run("bitcoin.esplora.health", async () => {
122
- const h = await desk.bitcoin.health();
123
- if (!h?.ok) throw new Error("esplora unhealthy");
124
- return `ok tip lane live`;
125
- });
126
-
127
- await run("bitcoin.esplora.tipHeight", async () => {
128
- const t = await desk.bitcoin.tipHeight();
129
- const height = t?.height ?? t?.tipHeight ?? t;
130
- if (!Number(height)) throw new Error("no tip height");
131
- return `tip=${height}`;
132
- });
133
-
134
- await run("bitcoin.esplora.fees", async () => {
135
- const f = await desk.bitcoin.fees();
136
- const fast = f?.fastestFee ?? f?.fees?.fastestFee ?? f?.["1"] ?? null;
137
- return `fastest=${JSON.stringify(fast)}`;
138
- });
139
-
140
- await run("bitcoin.esplora.address", async () => {
141
- const a = await desk.bitcoin.address(PROBE_BTC);
142
- const funded = a?.chainStats?.fundedTxoSum ?? a?.balanceSats ?? a?.raw?.chain_stats?.funded_txo_sum ?? null;
143
- return `fundedSats=${funded}`;
144
- });
145
-
146
- await run("bitcoin.esplora.utxos", async () => {
147
- const u = await desk.bitcoin.utxos(PROBE_BTC);
148
- const n = u?.utxos?.length ?? u?.length ?? 0;
149
- return `utxos=${n}`;
150
- });
151
-
152
- await run("bitcoin.meta.health", async () => {
153
- const h = await desk.bitcoin.metaHealth();
154
- return `ok=${h?.ok} tier=${h?.tier ?? h?.mode ?? "keyless"}`;
155
- });
156
-
157
- await run(
158
- "bitcoin.meta.inscriptionInfo",
159
- async () => {
160
- const info = await desk.bitcoin.inscriptions(PROBE_BTC);
161
- return `inscriptions=${info?.inscriptions?.length ?? "unknown"}`;
162
- },
163
- { optional: true }
164
- );
165
-
166
- await run(
167
- "bitcoin.satflow.health",
168
- async () => {
169
- const h = await desk.bitcoin.satflowHealth();
170
- if (!h?.ok) throw new Error(`satflow ${JSON.stringify(h).slice(0, 90)}`);
171
- return `ok`;
172
- },
173
- { optional: true }
174
- );
175
-
176
- const failed = results.filter((r) => r.status === "fail");
177
- const keyed = results.filter((r) => r.status === "keyed");
178
- console.log(`\nlanes=${results.length} ok=${results.length - failed.length - keyed.length} keyed=${keyed.length} failed=${failed.length}`);
179
- if (failed.length) {
180
- console.log(`FAILED: ${failed.map((f) => f.lane).join(", ")}`);
181
- process.exit(1);
182
- }
183
- console.log("E2E OK: every mandatory Solana + Bitcoin lane answered live, prepare-only posture held.");
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env node
2
- import { listProtocolTemplates, runProtocolTemplateGate } from "../src/protocol-templates/gate.mjs";
3
-
4
- const id = process.argv[2];
5
- if (!id || id === "list") {
6
- console.log(JSON.stringify(listProtocolTemplates(), null, 2));
7
- process.exit(0);
8
- }
9
- try {
10
- const r = runProtocolTemplateGate(id, { allowSkipStatic: process.env.REQUIRE_SLITHER !== "1" });
11
- console.log(JSON.stringify(r, null, 2));
12
- } catch (e) {
13
- console.error(String(e.message || e));
14
- process.exit(1);
15
- }
@@ -1,23 +0,0 @@
1
- #!/usr/bin/env node
2
- import fs from "node:fs/promises";
3
- import path from "node:path";
4
- import { scanPublicApis } from "../src/data/public-api-scan.mjs";
5
-
6
- const args = process.argv.slice(2);
7
- const value = (flag) => {
8
- const i = args.indexOf(flag);
9
- return i >= 0 ? args[i + 1] : null;
10
- };
11
- const outPath = value("--out");
12
- const timeoutMs = Number(value("--timeout-ms") || 12_000);
13
- const providers = value("--providers")?.split(",").map((x) => x.trim()).filter(Boolean);
14
-
15
- const report = await scanPublicApis({ providers, timeoutMs });
16
- const json = `${JSON.stringify(report, null, 2)}\n`;
17
- if (outPath) {
18
- const target = path.resolve(outPath);
19
- await fs.mkdir(path.dirname(target), { recursive: true });
20
- await fs.writeFile(target, json, "utf8");
21
- console.error(`wrote ${target}`);
22
- }
23
- process.stdout.write(json);
@@ -1,181 +0,0 @@
1
- #!/usr/bin/env node
2
- // Pre-publication secret scan. Fails CLOSED: any hit is an error.
3
- //
4
- // Checks the working tree AND every blob in git history, because a secret
5
- // removed in a later commit is still public the moment the repo is.
6
-
7
- import { execFileSync } from "node:child_process";
8
-
9
- const ROOT = process.cwd();
10
-
11
- // Live values that must never appear. Sourced from the environment at scan
12
- // time so the scanner itself contains no secrets.
13
- function liveSecrets() {
14
- const out = [];
15
- const push = (label, value) => {
16
- const v = String(value || "").trim();
17
- if (v.length >= 8) out.push({ label, value: v });
18
- };
19
- for (const k of Object.keys(process.env)) {
20
- if (/(_KEY|_SECRET|_TOKEN|_PASSPHRASE|_WIF|PRIVATE_KEY)$/i.test(k)) {
21
- push(`env:${k}`, process.env[k]);
22
- }
23
- }
24
- return out;
25
- }
26
-
27
- // A representative slice of the BIP39 English wordlist. Full coverage is not
28
- // required: a real mnemonic is 12 or 24 words drawn ENTIRELY from the list, so
29
- // any genuine phrase will hit these common entries, while English prose will
30
- // not have every one of its words in the list.
31
- const BIP39_SAMPLE = new Set(
32
- ("abandon ability able about above absent absorb abstract absurd abuse access accident account accuse achieve acid " +
33
- "across act action actor actress actual adapt add addict address adjust admit adult advance advice aerobic affair " +
34
- "afford afraid again age agent agree ahead aim air airport aisle alarm album alcohol alert alien all alley allow " +
35
- "almost alone alpha already also alter always amateur amazing among amount amused analyst anchor ancient anger " +
36
- "angle angry animal ankle announce annual another answer antenna antique anxiety any apart apology appear apple " +
37
- "approve april arch arctic area arena argue arm armed armor army around arrange arrest arrive arrow art artefact " +
38
- "artist artwork ask aspect assault asset assist assume asthma athlete atom attack attend attitude attract auction " +
39
- "audit august aunt author auto autumn average avocado avoid awake aware away awesome awful awkward axis baby " +
40
- "bachelor bacon badge bag balance balcony ball bamboo banana banner bar barely bargain barrel base basic basket " +
41
- "battle beach bean beauty because become beef before begin behave behind believe below belt bench benefit best " +
42
- "betray better between beyond bicycle bid bike bind biology bird birth bitter black blade blame blanket blast " +
43
- "bleak bless blind blood blossom blouse blue blur blush board boat body boil bomb bone bonus book boost border " +
44
- "boring borrow boss bottom bounce box boy bracket brain brand brass brave bread breeze brick bridge brief bright " +
45
- "bring brisk broccoli broken bronze broom brother brown brush bubble buddy budget buffalo build bulb bulk bullet " +
46
- "bundle bunker burden burger burst bus business busy butter buyer buzz cabbage cabin cable cactus cage cake call " +
47
- "calm camera camp can canal cancel candy cannon canoe canvas canyon capable capital captain car carbon card cargo " +
48
- "carpet carry cart case cash casino castle casual cat catalog catch category cattle caught cause caution cave " +
49
- "ceiling celery cement census century cereal certain chair chalk champion change chaos chapter charge chase chat " +
50
- "cheap check cheese chef cherry chest chicken chief child chimney choice choose chronic chuckle chunk churn cigar " +
51
- "cinnamon circle citizen city civil claim clap clarify claw clay clean clerk clever click client cliff climb " +
52
- "clinic clip clock clog close cloth cloud clown club clump cluster clutch coach coast coconut code coffee coil " +
53
- "coin collect color column combine come comfort comic common company concert conduct confirm congress connect " +
54
- "consider control convince cook cool copper copy coral core corn correct cost cotton couch country couple course " +
55
- "cousin cover coyote crack cradle craft cram crane crash crater crawl crazy cream credit creek crew cricket crime " +
56
- "crisp critic crop cross crouch crowd crucial cruel cruise crumble crunch crush cry crystal cube culture cup " +
57
- "cupboard curious current curtain curve cushion custom cute cycle zoo zone zero youth young you yellow year " +
58
- "wrong write wrist wrap worth world work word wood wonder woman wolf wire winter wing wine window wind wild wife " +
59
- "why whisper white where when wheat what wet west welcome weird weekend week wedding web wealth wear weapon " +
60
- "weasel wear wave water watch waste wash warrior warm want walnut wall walk wait wagon void voice vote volume " +
61
- "vocal vivid virus violin virtual vintage view video vicious vibrant vessel very verify version verb vendor " +
62
- "vehicle vegetable vault various vast vase vanish valve valley valid vacuum vacant").split(/\s+/)
63
- );
64
-
65
- const PATTERNS = [
66
- { name: "private key (hex 64)", re: /\b(?:0x)?[0-9a-fA-F]{64}\b/, refine: (m, line) =>
67
- /priv|secret|wif|seed|mnemonic|signer|wallet/i.test(line) && !/hash|digest|sha256|txid|commit|blob|sha1|0x0{40,}/i.test(line) },
68
- { name: "BTC WIF", re: /\b[5KL][1-9A-HJ-NP-Za-km-z]{50,51}\b/ },
69
- { name: "BIP39 seed phrase", re: /\b(?:[a-z]{3,8} ){11,23}[a-z]{3,8}\b/, refine: (m) => {
70
- // Ordinary English prose trivially matches "12-24 short lowercase words".
71
- // A scanner that cries wolf on comments is a scanner people switch off,
72
- // so require the words to actually be in the BIP39 wordlist.
73
- const words = m[0].trim().split(/\s+/);
74
- if (words.length !== 12 && words.length !== 24) return false;
75
- return words.every((w) => BIP39_SAMPLE.has(w));
76
- } },
77
- { name: "AWS access key", re: /\bAKIA[0-9A-Z]{16}\b/ },
78
- { name: "OpenAI key", re: /\bsk-[A-Za-z0-9_-]{20,}\b/ },
79
- { name: "Anthropic key", re: /\bsk-ant-[A-Za-z0-9_-]{20,}\b/ },
80
- { name: "GitHub token", re: /\bgh[pousr]_[A-Za-z0-9]{36,}\b/ },
81
- { name: "Slack token", re: /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/ },
82
- { name: "Telegram bot token", re: /\b\d{8,10}:[A-Za-z0-9_-]{35}\b/ },
83
- { name: "PEM private key", re: /-----BEGIN (?:RSA |EC |OPENSSH |PGP )?PRIVATE KEY-----/ },
84
- { name: "Solana keypair array", re: /\[\s*(?:\d{1,3}\s*,\s*){63}\d{1,3}\s*\]/ },
85
- ];
86
-
87
- // Paths whose matches are known-safe test fixtures.
88
- const ALLOWED_PATHS = [
89
- /^scripts\/secret-scan\.mjs$/,
90
- /^package-lock\.json$/,
91
- ];
92
-
93
- // Literal strings that are documented, synthetic, or public by nature.
94
- const ALLOWED_VALUES = [
95
- "0x0123456789012345678901234567890123456789012345678901234567890123", // HL SDK public test vector
96
- "L1aW4aubDFB7yfras2S1mN3bqg9nwySY8nkoLmJebSLD5BWv3ENZ",
97
- "/-----BEGIN[A-Z ]*PRIVATE KEY-----/",
98
- '{ value: "-----BEGIN EC PRIVATE KEY-----" }',
99
- "0x0000000000000000000000000000000000000000",
100
- ];
101
-
102
- function sh(cmd, args) {
103
- return execFileSync(cmd, args, { cwd: ROOT, encoding: "utf8", maxBuffer: 256 * 1024 * 1024 });
104
- }
105
-
106
- function scanText(text, origin, findings) {
107
- const lines = text.split("\n");
108
- for (let i = 0; i < lines.length; i++) {
109
- const line = lines[i];
110
- if (line.length > 4000) continue;
111
- for (const p of PATTERNS) {
112
- const m = p.re.exec(line);
113
- if (!m) continue;
114
- if (ALLOWED_VALUES.some((v) => line.includes(v))) continue;
115
- if (p.refine && !p.refine(m, line)) continue;
116
- findings.push({ origin, line: i + 1, kind: p.name, sample: line.trim().slice(0, 100) });
117
- }
118
- for (const s of LIVE) {
119
- if (line.includes(s.value)) {
120
- findings.push({ origin, line: i + 1, kind: `LIVE SECRET ${s.label}`, sample: "[REDACTED — real credential]" });
121
- }
122
- }
123
- }
124
- }
125
-
126
- const LIVE = liveSecrets();
127
- const findings = [];
128
-
129
- // --- 1. working tree (tracked files only) ---
130
- const tracked = sh("git", ["ls-files"]).split("\n").filter(Boolean);
131
- for (const rel of tracked) {
132
- if (ALLOWED_PATHS.some((r) => r.test(rel))) continue;
133
- let content;
134
- try {
135
- content = sh("git", ["show", `:${rel}`]);
136
- } catch {
137
- continue; // binary or unreadable
138
- }
139
- if (content.includes("\u0000")) continue;
140
- scanText(content, rel, findings);
141
- }
142
-
143
- // --- 2. every blob in history ---
144
- const revs = sh("git", ["rev-list", "--all"]).split("\n").filter(Boolean);
145
- const seen = new Set();
146
- let historyBlobs = 0;
147
- for (const rev of revs) {
148
- const entries = sh("git", ["ls-tree", "-r", rev]).split("\n").filter(Boolean);
149
- for (const entry of entries) {
150
- const [meta, path] = entry.split("\t");
151
- const sha = meta.split(/\s+/)[2];
152
- if (!sha || seen.has(sha)) continue;
153
- seen.add(sha);
154
- if (ALLOWED_PATHS.some((r) => r.test(path))) continue;
155
- let content;
156
- try {
157
- content = sh("git", ["cat-file", "-p", sha]);
158
- } catch {
159
- continue;
160
- }
161
- if (content.includes("\u0000")) continue;
162
- historyBlobs++;
163
- scanText(content, `history:${rev.slice(0, 8)}:${path}`, findings);
164
- }
165
- }
166
-
167
- // --- 3. author identity leakage ---
168
- const authors = new Set(sh("git", ["log", "--all", "--format=%an <%ae>|%cn <%ce>"]).split(/[\n|]/).filter(Boolean));
169
-
170
- console.log(`scanned ${tracked.length} tracked files, ${historyBlobs} historical blobs, ${revs.length} commits`);
171
- console.log(`live env secrets checked: ${LIVE.length}`);
172
- console.log(`git identities: ${[...authors].join(", ") || "(none)"}`);
173
-
174
- if (findings.length) {
175
- console.error(`\nFAIL — ${findings.length} finding(s):`);
176
- for (const f of findings.slice(0, 40)) {
177
- console.error(` ${f.origin}:${f.line} [${f.kind}] ${f.sample}`);
178
- }
179
- process.exit(1);
180
- }
181
- console.log("\nPASS — no secrets found in tree or history");