@oracle-agent/oracle 0.11.0 → 0.13.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 (487) hide show
  1. package/LICENSE +115 -201
  2. package/README.md +13 -516
  3. package/bin/oracle.mjs +19 -27
  4. package/package.json +15 -98
  5. package/CONTRIBUTING.md +0 -98
  6. package/SECURITY.md +0 -89
  7. package/SETUP.md +0 -381
  8. package/artifacts/inscription/oracle-was-here-preview.png +0 -0
  9. package/artifacts/inscription/oracle-was-here.svg +0 -1
  10. package/artifacts/specialist-packs/oracle-full-crypto.json +0 -295
  11. package/bin/desk-server.mjs +0 -440
  12. package/bin/oracle-data-mcp.mjs +0 -1019
  13. package/bin/oracle-init.mjs +0 -496
  14. package/bin/oracle-public-server.mjs +0 -36
  15. package/bin/oracle-route.mjs +0 -254
  16. package/bin/oracle-scan.mjs +0 -192
  17. package/bin/oracle-upgrade.mjs +0 -42
  18. package/docs/adding-a-chain.md +0 -229
  19. package/docs/architecture.md +0 -138
  20. package/docs/cli.md +0 -47
  21. package/docs/connectors.md +0 -13
  22. package/docs/oracle-pack-standard.md +0 -29
  23. package/docs/profiles.md +0 -151
  24. package/docs/public-surface.md +0 -133
  25. package/examples/add-a-chain.mjs +0 -65
  26. package/examples/oracle-pack-template.mjs +0 -38
  27. package/examples/research-a-token.mjs +0 -70
  28. package/plugins/oracle-owner-gate/__init__.py +0 -227
  29. package/plugins/oracle-owner-gate/plugin.yaml +0 -9
  30. package/profiles/_template/SOUL.md +0 -54
  31. package/profiles/_template/profile.json +0 -22
  32. package/profiles/bitcoin-agent/SOUL.md +0 -31
  33. package/profiles/bitcoin-agent/profile.json +0 -32
  34. package/profiles/hyperliquid-agent/SOUL.md +0 -34
  35. package/profiles/hyperliquid-agent/profile.json +0 -37
  36. package/profiles/oracle/SOUL.md +0 -107
  37. package/profiles/oracle/profile.json +0 -39
  38. package/profiles/polymarket-agent/SOUL.md +0 -35
  39. package/profiles/polymarket-agent/profile.json +0 -34
  40. package/profiles/profile.schema.json +0 -90
  41. package/profiles/protocol-builder/SOUL.md +0 -57
  42. package/profiles/protocol-builder/profile.json +0 -39
  43. package/profiles/robinhood-agent/SOUL.md +0 -53
  44. package/profiles/robinhood-agent/profile.json +0 -40
  45. package/profiles/solana-agent/SOUL.md +0 -37
  46. package/profiles/solana-agent/profile.json +0 -37
  47. package/profiles/stable-agent/SOUL.md +0 -43
  48. package/profiles/stable-agent/profile.json +0 -37
  49. package/protocols/templates/safe-erc20/SECURITY.md +0 -16
  50. package/protocols/templates/safe-erc20/foundry.toml +0 -12
  51. package/protocols/templates/safe-erc20/remappings.txt +0 -2
  52. package/protocols/templates/safe-erc20/src/SafeERC20.sol +0 -53
  53. package/protocols/templates/safe-erc20/test/SafeERC20.t.sol +0 -72
  54. package/public/agent-connect/app.js +0 -84
  55. package/public/agent-connect/index.html +0 -83
  56. package/public/agent-connect/styles.css +0 -70
  57. package/public/index.html +0 -12
  58. package/public/oracle-console/app.js +0 -272
  59. package/public/oracle-console/bitcoin-wallets.js +0 -206
  60. package/public/oracle-console/index.html +0 -91
  61. package/public/oracle-console/styles.css +0 -239
  62. package/public/oracle-splash/assets/cli-chain-hyperliquid.jpg +0 -0
  63. package/public/oracle-splash/assets/hero/orb.avif +0 -0
  64. package/public/oracle-splash/assets/hero/orb.webm +0 -0
  65. package/public/oracle-splash/assets/llms/claude.svg +0 -1
  66. package/public/oracle-splash/assets/llms/codex-icon.svg +0 -1
  67. package/public/oracle-splash/assets/llms/codex.svg +0 -1
  68. package/public/oracle-splash/assets/llms/cursor-icon.svg +0 -12
  69. package/public/oracle-splash/assets/llms/cursor.svg +0 -17
  70. package/public/oracle-splash/assets/llms/deepseek.svg +0 -1
  71. package/public/oracle-splash/assets/llms/gemini-icon.svg +0 -1
  72. package/public/oracle-splash/assets/llms/gemini.svg +0 -1
  73. package/public/oracle-splash/assets/llms/grok.svg +0 -8
  74. package/public/oracle-splash/assets/llms/hermes.png +0 -0
  75. package/public/oracle-splash/assets/llms/kimi-icon.svg +0 -1
  76. package/public/oracle-splash/assets/llms/kimi.svg +0 -1
  77. package/public/oracle-splash/assets/llms/manus.svg +0 -18
  78. package/public/oracle-splash/assets/llms/openclaw.svg +0 -22
  79. package/public/oracle-splash/assets/llms/perplexity.svg +0 -1
  80. package/public/oracle-splash/assets/llms/qwen.svg +0 -1
  81. package/public/oracle-splash/assets/llms/windsurf.svg +0 -1
  82. package/public/oracle-splash/assets/protocols/abcdex.png +0 -0
  83. package/public/oracle-splash/assets/protocols/across.png +0 -0
  84. package/public/oracle-splash/assets/protocols/aerodrome.png +0 -0
  85. package/public/oracle-splash/assets/protocols/balancer.png +0 -0
  86. package/public/oracle-splash/assets/protocols/cowswap.png +0 -0
  87. package/public/oracle-splash/assets/protocols/curve.png +0 -0
  88. package/public/oracle-splash/assets/protocols/dreamcash.png +0 -0
  89. package/public/oracle-splash/assets/protocols/felix.png +0 -0
  90. package/public/oracle-splash/assets/protocols/gmx.png +0 -0
  91. package/public/oracle-splash/assets/protocols/hyena.png +0 -0
  92. package/public/oracle-splash/assets/protocols/hyperbeat.png +0 -0
  93. package/public/oracle-splash/assets/protocols/hyperliquid.png +0 -0
  94. package/public/oracle-splash/assets/protocols/hyperswap.png +0 -0
  95. package/public/oracle-splash/assets/protocols/jupiter.png +0 -0
  96. package/public/oracle-splash/assets/protocols/kinetiq.png +0 -0
  97. package/public/oracle-splash/assets/protocols/lfj.png +0 -0
  98. package/public/oracle-splash/assets/protocols/lifi.png +0 -0
  99. package/public/oracle-splash/assets/protocols/magic-eden.png +0 -0
  100. package/public/oracle-splash/assets/protocols/morpho.png +0 -0
  101. package/public/oracle-splash/assets/protocols/odos.png +0 -0
  102. package/public/oracle-splash/assets/protocols/oneinch.png +0 -0
  103. package/public/oracle-splash/assets/protocols/opensea.png +0 -0
  104. package/public/oracle-splash/assets/protocols/pancakeswap.png +0 -0
  105. package/public/oracle-splash/assets/protocols/paragon.png +0 -0
  106. package/public/oracle-splash/assets/protocols/paraswap.png +0 -0
  107. package/public/oracle-splash/assets/protocols/pendle.png +0 -0
  108. package/public/oracle-splash/assets/protocols/polymarket.png +0 -0
  109. package/public/oracle-splash/assets/protocols/quickswap.png +0 -0
  110. package/public/oracle-splash/assets/protocols/relay.png +0 -0
  111. package/public/oracle-splash/assets/protocols/stargate.png +0 -0
  112. package/public/oracle-splash/assets/protocols/tradexyz.png +0 -0
  113. package/public/oracle-splash/assets/protocols/uniswap.png +0 -0
  114. package/public/oracle-splash/assets/protocols/velodrome.png +0 -0
  115. package/public/oracle-splash/assets/protocols/ventuals.png +0 -0
  116. package/public/oracle-splash/assets/wordmarks/across-icon.webp +0 -0
  117. package/public/oracle-splash/assets/wordmarks/across.svg +0 -4
  118. package/public/oracle-splash/assets/wordmarks/aerodrome.svg +0 -23
  119. package/public/oracle-splash/assets/wordmarks/balancer.svg +0 -3
  120. package/public/oracle-splash/assets/wordmarks/cowswap.svg +0 -1
  121. package/public/oracle-splash/assets/wordmarks/curve.png +0 -0
  122. package/public/oracle-splash/assets/wordmarks/gmx.svg +0 -13
  123. package/public/oracle-splash/assets/wordmarks/hop-icon.webp +0 -0
  124. package/public/oracle-splash/assets/wordmarks/hyena.svg +0 -7
  125. package/public/oracle-splash/assets/wordmarks/hyperliquid.svg +0 -21
  126. package/public/oracle-splash/assets/wordmarks/hyperswap.svg +0 -13
  127. package/public/oracle-splash/assets/wordmarks/jupiter.svg +0 -35
  128. package/public/oracle-splash/assets/wordmarks/kinetiq.svg +0 -1
  129. package/public/oracle-splash/assets/wordmarks/lfj.webp +0 -0
  130. package/public/oracle-splash/assets/wordmarks/lifi.png +0 -0
  131. package/public/oracle-splash/assets/wordmarks/magic-eden.svg +0 -1
  132. package/public/oracle-splash/assets/wordmarks/markets.svg +0 -1
  133. package/public/oracle-splash/assets/wordmarks/morpho.svg +0 -1
  134. package/public/oracle-splash/assets/wordmarks/odos.svg +0 -3
  135. package/public/oracle-splash/assets/wordmarks/oneinch-icon.webp +0 -0
  136. package/public/oracle-splash/assets/wordmarks/oneinch.svg +0 -6
  137. package/public/oracle-splash/assets/wordmarks/opensea-icon.svg +0 -17
  138. package/public/oracle-splash/assets/wordmarks/opensea.svg +0 -1
  139. package/public/oracle-splash/assets/wordmarks/outcome.svg +0 -16
  140. package/public/oracle-splash/assets/wordmarks/pancakeswap.svg +0 -18
  141. package/public/oracle-splash/assets/wordmarks/paragon.svg +0 -9
  142. package/public/oracle-splash/assets/wordmarks/paraswap.svg +0 -16
  143. package/public/oracle-splash/assets/wordmarks/pendle.png +0 -0
  144. package/public/oracle-splash/assets/wordmarks/polymarket.png +0 -0
  145. package/public/oracle-splash/assets/wordmarks/quickswap.png +0 -0
  146. package/public/oracle-splash/assets/wordmarks/relay.svg +0 -8
  147. package/public/oracle-splash/assets/wordmarks/satflow-icon.png +0 -0
  148. package/public/oracle-splash/assets/wordmarks/stargate-icon.webp +0 -0
  149. package/public/oracle-splash/assets/wordmarks/stargate.svg +0 -15
  150. package/public/oracle-splash/assets/wordmarks/uniswap.svg +0 -18
  151. package/public/oracle-splash/assets/wordmarks/velodrome.svg +0 -84
  152. package/public/oracle-splash/assets/wordmarks/xyz.svg +0 -12
  153. package/public/oracle-splash/assets/wordmarks/zerox-icon.webp +0 -0
  154. package/public/oracle-splash/brand/aave.webp +0 -0
  155. package/public/oracle-splash/brand/aavev2.webp +0 -0
  156. package/public/oracle-splash/brand/aborean.webp +0 -0
  157. package/public/oracle-splash/brand/across.webp +0 -0
  158. package/public/oracle-splash/brand/aerodrome.webp +0 -0
  159. package/public/oracle-splash/brand/afi.webp +0 -0
  160. package/public/oracle-splash/brand/arcus.webp +0 -0
  161. package/public/oracle-splash/brand/aster.webp +0 -0
  162. package/public/oracle-splash/brand/avant.webp +0 -0
  163. package/public/oracle-splash/brand/balancer.webp +0 -0
  164. package/public/oracle-splash/brand/beefy.webp +0 -0
  165. package/public/oracle-splash/brand/benqi.webp +0 -0
  166. package/public/oracle-splash/brand/bestinslot.ico +0 -0
  167. package/public/oracle-splash/brand/bitfi.webp +0 -0
  168. package/public/oracle-splash/brand/bonkswap.webp +0 -0
  169. package/public/oracle-splash/brand/bouncebit.webp +0 -0
  170. package/public/oracle-splash/brand/camelot.webp +0 -0
  171. package/public/oracle-splash/brand/compound.webp +0 -0
  172. package/public/oracle-splash/brand/concrete.webp +0 -0
  173. package/public/oracle-splash/brand/cow.webp +0 -0
  174. package/public/oracle-splash/brand/curve.webp +0 -0
  175. package/public/oracle-splash/brand/derive.webp +0 -0
  176. package/public/oracle-splash/brand/dolomite.webp +0 -0
  177. package/public/oracle-splash/brand/eigenlayer.webp +0 -0
  178. package/public/oracle-splash/brand/ekubo.webp +0 -0
  179. package/public/oracle-splash/brand/ethena.webp +0 -0
  180. package/public/oracle-splash/brand/etherfi.webp +0 -0
  181. package/public/oracle-splash/brand/etherfiborrow.webp +0 -0
  182. package/public/oracle-splash/brand/felix.webp +0 -0
  183. package/public/oracle-splash/brand/fluid.webp +0 -0
  184. package/public/oracle-splash/brand/fluxbeam.webp +0 -0
  185. package/public/oracle-splash/brand/folks.webp +0 -0
  186. package/public/oracle-splash/brand/fortyacres.webp +0 -0
  187. package/public/oracle-splash/brand/gainsnetwork.webp +0 -0
  188. package/public/oracle-splash/brand/gassss.webp +0 -0
  189. package/public/oracle-splash/brand/gmx.webp +0 -0
  190. package/public/oracle-splash/brand/harmonix.webp +0 -0
  191. package/public/oracle-splash/brand/hlorderbook.webp +0 -0
  192. package/public/oracle-splash/brand/hlp.webp +0 -0
  193. package/public/oracle-splash/brand/hop.webp +0 -0
  194. package/public/oracle-splash/brand/hyperbeat.webp +0 -0
  195. package/public/oracle-splash/brand/hyperlend.webp +0 -0
  196. package/public/oracle-splash/brand/hyperliquid.webp +0 -0
  197. package/public/oracle-splash/brand/hyperliquidhpl.webp +0 -0
  198. package/public/oracle-splash/brand/hyperliquidspot.webp +0 -0
  199. package/public/oracle-splash/brand/hyperswap.webp +0 -0
  200. package/public/oracle-splash/brand/hypha.webp +0 -0
  201. package/public/oracle-splash/brand/joedex.webp +0 -0
  202. package/public/oracle-splash/brand/jupiter.webp +0 -0
  203. package/public/oracle-splash/brand/kelp.webp +0 -0
  204. package/public/oracle-splash/brand/kinetiq.webp +0 -0
  205. package/public/oracle-splash/brand/kmhype.webp +0 -0
  206. package/public/oracle-splash/brand/kona.webp +0 -0
  207. package/public/oracle-splash/brand/konalend.webp +0 -0
  208. package/public/oracle-splash/brand/lfj.webp +0 -0
  209. package/public/oracle-splash/brand/lido.webp +0 -0
  210. package/public/oracle-splash/brand/lifi.webp +0 -0
  211. package/public/oracle-splash/brand/lighter.webp +0 -0
  212. package/public/oracle-splash/brand/lista.webp +0 -0
  213. package/public/oracle-splash/brand/loopedhype.webp +0 -0
  214. package/public/oracle-splash/brand/lorenzo.webp +0 -0
  215. package/public/oracle-splash/brand/magic-eden.webp +0 -0
  216. package/public/oracle-splash/brand/magiceden.webp +0 -0
  217. package/public/oracle-splash/brand/mempool.png +0 -0
  218. package/public/oracle-splash/brand/meteora.webp +0 -0
  219. package/public/oracle-splash/brand/morpho.webp +0 -0
  220. package/public/oracle-splash/brand/myriad.webp +0 -0
  221. package/public/oracle-splash/brand/noxa.webp +0 -0
  222. package/public/oracle-splash/brand/odos.webp +0 -0
  223. package/public/oracle-splash/brand/oneinch.webp +0 -0
  224. package/public/oracle-splash/brand/openbook.webp +0 -0
  225. package/public/oracle-splash/brand/opensea.webp +0 -0
  226. package/public/oracle-splash/brand/orca.webp +0 -0
  227. package/public/oracle-splash/brand/ordinals.png +0 -0
  228. package/public/oracle-splash/brand/ostium.webp +0 -0
  229. package/public/oracle-splash/brand/pancakeswap.webp +0 -0
  230. package/public/oracle-splash/brand/pendle.webp +0 -0
  231. package/public/oracle-splash/brand/perena.webp +0 -0
  232. package/public/oracle-splash/brand/pharaoh.webp +0 -0
  233. package/public/oracle-splash/brand/phoenix.webp +0 -0
  234. package/public/oracle-splash/brand/polymarket.webp +0 -0
  235. package/public/oracle-splash/brand/polynomial.webp +0 -0
  236. package/public/oracle-splash/brand/projectx.webp +0 -0
  237. package/public/oracle-splash/brand/pumpfun.webp +0 -0
  238. package/public/oracle-splash/brand/quickswap.webp +0 -0
  239. package/public/oracle-splash/brand/rain.webp +0 -0
  240. package/public/oracle-splash/brand/raydium.webp +0 -0
  241. package/public/oracle-splash/brand/relay.webp +0 -0
  242. package/public/oracle-splash/brand/rocketpool.webp +0 -0
  243. package/public/oracle-splash/brand/saber.webp +0 -0
  244. package/public/oracle-splash/brand/sakuraswap.webp +0 -0
  245. package/public/oracle-splash/brand/sanctum.webp +0 -0
  246. package/public/oracle-splash/brand/satflow.png +0 -0
  247. package/public/oracle-splash/brand/sierra.webp +0 -0
  248. package/public/oracle-splash/brand/sky.webp +0 -0
  249. package/public/oracle-splash/brand/solv.webp +0 -0
  250. package/public/oracle-splash/brand/spark.webp +0 -0
  251. package/public/oracle-splash/brand/sparksavings.webp +0 -0
  252. package/public/oracle-splash/brand/sphere.webp +0 -0
  253. package/public/oracle-splash/brand/ssv.webp +0 -0
  254. package/public/oracle-splash/brand/stabble.webp +0 -0
  255. package/public/oracle-splash/brand/stableswap.webp +0 -0
  256. package/public/oracle-splash/brand/stakewise.webp +0 -0
  257. package/public/oracle-splash/brand/stargate.webp +0 -0
  258. package/public/oracle-splash/brand/sthype.webp +0 -0
  259. package/public/oracle-splash/brand/sushiswap.webp +0 -0
  260. package/public/oracle-splash/brand/unisat.png +0 -0
  261. package/public/oracle-splash/brand/uniswap.webp +0 -0
  262. package/public/oracle-splash/brand/uniswapv2.webp +0 -0
  263. package/public/oracle-splash/brand/uniswapv4.webp +0 -0
  264. package/public/oracle-splash/brand/unit.webp +0 -0
  265. package/public/oracle-splash/brand/velodrome.webp +0 -0
  266. package/public/oracle-splash/brand/velora.webp +0 -0
  267. package/public/oracle-splash/brand/venus.webp +0 -0
  268. package/public/oracle-splash/brand/wbeth.webp +0 -0
  269. package/public/oracle-splash/brand/xsy.webp +0 -0
  270. package/public/oracle-splash/brand/yieldyak.webp +0 -0
  271. package/public/oracle-splash/brand/zerobase.webp +0 -0
  272. package/public/oracle-splash/brand/zerox.webp +0 -0
  273. package/public/oracle-splash/favicon.ico +0 -0
  274. package/public/oracle-splash/favicon.svg +0 -6
  275. package/public/oracle-splash/index.html +0 -1558
  276. package/public/oracle-splash/mesh-graph.png +0 -0
  277. package/public/oracle-splash/mesh-graph.svg +0 -216
  278. package/scripts/adversarial-bench.mjs +0 -114
  279. package/scripts/build-inscription.py +0 -230
  280. package/scripts/check-doc-drift.mjs +0 -123
  281. package/scripts/check-test-count.mjs +0 -105
  282. package/scripts/e2e-hl-markets.mjs +0 -21
  283. package/scripts/e2e-hl-perps.mjs +0 -48
  284. package/scripts/e2e-hypercore-staking.mjs +0 -128
  285. package/scripts/e2e-solana-bitcoin.mjs +0 -183
  286. package/scripts/protocol-template-gate.mjs +0 -15
  287. package/scripts/public-api-scan.mjs +0 -23
  288. package/scripts/secret-scan.mjs +0 -181
  289. package/scripts/verify-v3-venues.mjs +0 -192
  290. package/skills/balance/SKILL.md +0 -176
  291. package/skills/oracle-action-semantics/SKILL.md +0 -40
  292. package/skills/oracle-best-execution/SKILL.md +0 -127
  293. package/skills/oracle-bitcoin/SKILL.md +0 -53
  294. package/skills/oracle-chain-graphs-telegram-cards/SKILL.md +0 -59
  295. package/skills/oracle-chat/SKILL.md +0 -61
  296. package/skills/oracle-chat/chain.SKILL.md +0 -31
  297. package/skills/oracle-chat/setup.SKILL.md +0 -37
  298. package/skills/oracle-circuit-breaker/SKILL.md +0 -51
  299. package/skills/oracle-contract-research/SKILL.md +0 -55
  300. package/skills/oracle-desk/SKILL.md +0 -58
  301. package/skills/oracle-dex-launch/SKILL.md +0 -38
  302. package/skills/oracle-grants/SKILL.md +0 -69
  303. package/skills/oracle-hypercore-staking/SKILL.md +0 -57
  304. package/skills/oracle-hyperliquid/SKILL.md +0 -56
  305. package/skills/oracle-meme-token-sniper/SKILL.md +0 -73
  306. package/skills/oracle-multichain-nft-launch/SKILL.md +0 -338
  307. package/skills/oracle-multichain-token-launch/SKILL.md +0 -300
  308. package/skills/oracle-nft-gacha-launch/SKILL.md +0 -48
  309. package/skills/oracle-nft-mint-gas-war/SKILL.md +0 -63
  310. package/skills/oracle-polymarket/SKILL.md +0 -60
  311. package/skills/oracle-protocol-builder/SKILL.md +0 -59
  312. package/skills/oracle-protocol-security/SKILL.md +0 -60
  313. package/skills/oracle-public-product/SKILL.md +0 -44
  314. package/skills/oracle-receipts/SKILL.md +0 -52
  315. package/skills/oracle-rfq-tokenized-assets/SKILL.md +0 -69
  316. package/skills/oracle-smart-wallet-scanner/SKILL.md +0 -49
  317. package/skills/oracle-solana/SKILL.md +0 -65
  318. package/skills/oracle-solana-nft/SKILL.md +0 -54
  319. package/skills/oracle-token-research/SKILL.md +0 -67
  320. package/skins/oracle.yaml +0 -56
  321. package/src/action-receipts.mjs +0 -265
  322. package/src/action-semantics.mjs +0 -62
  323. package/src/address-book.mjs +0 -208
  324. package/src/agent-auth.mjs +0 -206
  325. package/src/approval-guard.mjs +0 -282
  326. package/src/attestation-secret.mjs +0 -88
  327. package/src/audit-log.mjs +0 -196
  328. package/src/auth/oauth.mjs +0 -672
  329. package/src/auto-slippage.mjs +0 -378
  330. package/src/capability-posture.mjs +0 -125
  331. package/src/chains.mjs +0 -62
  332. package/src/cli/chain-catalog.mjs +0 -215
  333. package/src/cli/chain-state.mjs +0 -74
  334. package/src/cli/commands/auth.mjs +0 -193
  335. package/src/cli/commands/bootstrap.mjs +0 -87
  336. package/src/cli/commands/chain.mjs +0 -143
  337. package/src/cli/commands/chat.mjs +0 -434
  338. package/src/cli/commands/credential.mjs +0 -9
  339. package/src/cli/commands/data-mcp.mjs +0 -18
  340. package/src/cli/commands/data.mjs +0 -75
  341. package/src/cli/commands/doctor.mjs +0 -136
  342. package/src/cli/commands/help.mjs +0 -7
  343. package/src/cli/commands/init.mjs +0 -27
  344. package/src/cli/commands/mcp.mjs +0 -142
  345. package/src/cli/commands/model.mjs +0 -99
  346. package/src/cli/commands/prepare.mjs +0 -12
  347. package/src/cli/commands/public.mjs +0 -20
  348. package/src/cli/commands/route.mjs +0 -12
  349. package/src/cli/commands/runner.mjs +0 -9
  350. package/src/cli/commands/scan.mjs +0 -12
  351. package/src/cli/commands/setup.mjs +0 -275
  352. package/src/cli/commands/sign.mjs +0 -21
  353. package/src/cli/commands/signer.mjs +0 -9
  354. package/src/cli/commands/upgrade.mjs +0 -12
  355. package/src/cli/commands/vault.mjs +0 -9
  356. package/src/cli/commands/version.mjs +0 -22
  357. package/src/cli/first-run.mjs +0 -23
  358. package/src/cli/kernel.mjs +0 -239
  359. package/src/cli/mcp-targets/chatgpt.mjs +0 -51
  360. package/src/cli/mcp-targets/claude-code.mjs +0 -39
  361. package/src/cli/mcp-targets/claude-desktop.mjs +0 -24
  362. package/src/cli/mcp-targets/codex.mjs +0 -41
  363. package/src/cli/mcp-targets/shared.mjs +0 -61
  364. package/src/cli/messaging-platforms.mjs +0 -209
  365. package/src/cli/model-config.mjs +0 -70
  366. package/src/cli/operator-dispatch.mjs +0 -258
  367. package/src/cli/oracle-harness.py +0 -415
  368. package/src/cli/paths.mjs +0 -83
  369. package/src/cli/runtime.mjs +0 -351
  370. package/src/cli/setup-state.mjs +0 -168
  371. package/src/cli/spawn-child.mjs +0 -43
  372. package/src/data/catalog.mjs +0 -585
  373. package/src/data/desk-data.mjs +0 -695
  374. package/src/data/http.mjs +0 -253
  375. package/src/data/provider-endpoint.mjs +0 -94
  376. package/src/data/providers/aerodrome.mjs +0 -245
  377. package/src/data/providers/balancer.mjs +0 -209
  378. package/src/data/providers/bitcoin-esplora.mjs +0 -216
  379. package/src/data/providers/bitcoin-meta.mjs +0 -378
  380. package/src/data/providers/blockscout.mjs +0 -14
  381. package/src/data/providers/bridges.mjs +0 -242
  382. package/src/data/providers/cowswap.mjs +0 -415
  383. package/src/data/providers/curve.mjs +0 -201
  384. package/src/data/providers/defillama.mjs +0 -88
  385. package/src/data/providers/dexscreener.mjs +0 -43
  386. package/src/data/providers/evm-rpc.mjs +0 -225
  387. package/src/data/providers/geckoterminal.mjs +0 -34
  388. package/src/data/providers/gmx.mjs +0 -496
  389. package/src/data/providers/hl-assets.mjs +0 -165
  390. package/src/data/providers/hl-info.mjs +0 -108
  391. package/src/data/providers/hl-markets.mjs +0 -210
  392. package/src/data/providers/hl-outcome.mjs +0 -61
  393. package/src/data/providers/hl-perps.mjs +0 -387
  394. package/src/data/providers/hl-staking.mjs +0 -353
  395. package/src/data/providers/hl-ws.mjs +0 -119
  396. package/src/data/providers/hyperevm-dex.mjs +0 -49
  397. package/src/data/providers/jupiter-venues.mjs +0 -119
  398. package/src/data/providers/jupiter.mjs +0 -315
  399. package/src/data/providers/lifi.mjs +0 -151
  400. package/src/data/providers/magiceden-sol.mjs +0 -406
  401. package/src/data/providers/morpho.mjs +0 -177
  402. package/src/data/providers/nft-gallery.mjs +0 -163
  403. package/src/data/providers/nft-portfolio.mjs +0 -494
  404. package/src/data/providers/odos.mjs +0 -156
  405. package/src/data/providers/oneinch.mjs +0 -174
  406. package/src/data/providers/opensea-multichain.mjs +0 -136
  407. package/src/data/providers/opensea-nft.mjs +0 -371
  408. package/src/data/providers/paraswap.mjs +0 -118
  409. package/src/data/providers/pendle.mjs +0 -188
  410. package/src/data/providers/poly-clob.mjs +0 -283
  411. package/src/data/providers/poly-public.mjs +0 -96
  412. package/src/data/providers/poly-ws.mjs +0 -103
  413. package/src/data/providers/portfolio-history.mjs +0 -394
  414. package/src/data/providers/portfolio.mjs +0 -594
  415. package/src/data/providers/rfq.mjs +0 -15
  416. package/src/data/providers/rh-agent.mjs +0 -59
  417. package/src/data/providers/satflow.mjs +0 -341
  418. package/src/data/providers/signed-material-guard.mjs +0 -108
  419. package/src/data/providers/solana-rpc.mjs +0 -197
  420. package/src/data/providers/uniswap-v3.mjs +0 -349
  421. package/src/data/providers/uniswap-v4.mjs +0 -414
  422. package/src/data/providers/zerox.mjs +0 -167
  423. package/src/data/public-api-scan.mjs +0 -61
  424. package/src/data/quote-placeholder.mjs +0 -31
  425. package/src/exact-integer.mjs +0 -72
  426. package/src/exec-policy.mjs +0 -455
  427. package/src/flags.mjs +0 -15
  428. package/src/fresh-window.mjs +0 -76
  429. package/src/gmx-attestation.mjs +0 -176
  430. package/src/index.mjs +0 -100
  431. package/src/nft-gas-war-guard.mjs +0 -139
  432. package/src/onboarding/agent-keys.mjs +0 -161
  433. package/src/onboarding/harness-configs.mjs +0 -102
  434. package/src/onboarding/index.mjs +0 -18
  435. package/src/onboarding/tiers.mjs +0 -139
  436. package/src/oracle-env.mjs +0 -47
  437. package/src/portfolio-risk.mjs +0 -170
  438. package/src/prepare-envelope.mjs +0 -204
  439. package/src/profile-upgrade.mjs +0 -277
  440. package/src/protocol-execution.mjs +0 -84
  441. package/src/protocol-templates/gate.mjs +0 -179
  442. package/src/protocol-templates/prepare-deploy.mjs +0 -81
  443. package/src/public-api/buzz-integration.mjs +0 -256
  444. package/src/public-api/connect-agent.mjs +0 -416
  445. package/src/public-api/grants.mjs +0 -142
  446. package/src/public-api/http.mjs +0 -389
  447. package/src/public-control/aa-adapter.mjs +0 -402
  448. package/src/public-control/build-registry.mjs +0 -227
  449. package/src/public-control/bundler-client.mjs +0 -357
  450. package/src/public-control/grant-indexer.mjs +0 -296
  451. package/src/public-control/policy-render.mjs +0 -69
  452. package/src/public-control/policy-schema.mjs +0 -318
  453. package/src/public-control/runtime-config.mjs +0 -275
  454. package/src/public-control/session-key-model.mjs +0 -374
  455. package/src/public-control/session-orchestrator.mjs +0 -412
  456. package/src/rfq/intent.mjs +0 -180
  457. package/src/rfq/sources.mjs +0 -181
  458. package/src/route-attestation.mjs +0 -132
  459. package/src/router/best-execution.mjs +0 -326
  460. package/src/router/index.mjs +0 -226
  461. package/src/router/prepare-bridge.mjs +0 -289
  462. package/src/router/prepare-route.mjs +0 -398
  463. package/src/router/proposal.mjs +0 -311
  464. package/src/router/risk-classifier.mjs +0 -119
  465. package/src/router/route-sources.mjs +0 -364
  466. package/src/scanner/chains.config.mjs +0 -430
  467. package/src/scanner/contract.mjs +0 -270
  468. package/src/scanner/evm-scanner.mjs +0 -394
  469. package/src/scanner/index.mjs +0 -9
  470. package/src/scanner/v2-venue.mjs +0 -335
  471. package/src/scanner/v3-venue.mjs +0 -290
  472. package/src/scopes.mjs +0 -44
  473. package/src/sell-simulation.mjs +0 -167
  474. package/src/signals/engine.mjs +0 -146
  475. package/src/signals/index.mjs +0 -1
  476. package/src/token-transfer-guard.mjs +0 -188
  477. package/src/tui/app.mjs +0 -438
  478. package/src/tui/backend.mjs +0 -145
  479. package/src/tui/format.mjs +0 -272
  480. package/src/tui/gateway-client.mjs +0 -177
  481. package/src/tui/input.mjs +0 -501
  482. package/src/tui/renderer.mjs +0 -443
  483. package/src/tui/standalone-client.mjs +0 -666
  484. package/src/tui/theme.mjs +0 -81
  485. package/src/vault-attestation.mjs +0 -146
  486. package/src/venues.mjs +0 -206
  487. package/src/watch-preferences.mjs +0 -85
@@ -1,394 +0,0 @@
1
- import { constants } from "node:fs";
2
- import { chmod, mkdir, open, readFile } from "node:fs/promises";
3
- import { createHash, randomUUID } from "node:crypto";
4
- import os from "node:os";
5
- import path from "node:path";
6
- import { portfolioBalance, resolvePortfolioAddresses } from "./portfolio.mjs";
7
- import { nftInventory } from "./nft-portfolio.mjs";
8
-
9
- const MAX_HISTORY_BYTES = 10 * 1024 * 1024;
10
- const MAX_HISTORY_LIMIT = 1000;
11
-
12
- function finiteNumber(value) {
13
- if (value == null || value === "") return null;
14
- const number = Number(value);
15
- return Number.isFinite(number) ? number : null;
16
- }
17
-
18
- function roundedUsd(value) {
19
- return Number.isFinite(value) ? Number(value.toFixed(2)) : null;
20
- }
21
-
22
- function isoDate(value, label) {
23
- if (value == null || value === "") return null;
24
- const time = Date.parse(String(value));
25
- if (!Number.isFinite(time)) throw new Error(`${label} must be an ISO 8601 timestamp`);
26
- return new Date(time).toISOString();
27
- }
28
-
29
- function boundedInteger(value, fallback, min, max, label) {
30
- if (value == null || value === "") return fallback;
31
- const number = Number(value);
32
- if (!Number.isInteger(number) || number < min || number > max) {
33
- throw new Error(`${label} must be an integer from ${min} to ${max}`);
34
- }
35
- return number;
36
- }
37
-
38
- function canonicalAddresses(addresses = {}) {
39
- return ["evm", "solana", "bitcoin", "hyperliquid"]
40
- .map((family) => `${family}:${String(addresses[family] || "").trim().toLowerCase()}`)
41
- .join("|");
42
- }
43
-
44
- export function portfolioIdForAddresses(addresses = {}) {
45
- const digest = createHash("sha256").update(canonicalAddresses(addresses)).digest("hex").slice(0, 20);
46
- return `portfolio_${digest}`;
47
- }
48
-
49
- export function resolvePortfolioHistoryFile(opts = {}) {
50
- if (opts.historyFile) return path.resolve(String(opts.historyFile));
51
- const env = opts.env || process.env;
52
- if (env.ORACLE_PORTFOLIO_HISTORY_FILE) {
53
- return path.resolve(String(env.ORACLE_PORTFOLIO_HISTORY_FILE));
54
- }
55
- const hermesHome = String(env.HERMES_HOME || "").trim() || path.join(os.homedir(), ".hermes");
56
- return path.join(path.resolve(hermesHome), "state", "oracle", "portfolio-history.jsonl");
57
- }
58
-
59
- function knownLiquidValue(balance) {
60
- const value = finiteNumber(balance?.valuation?.knownUsd);
61
- if (value == null) return null;
62
- if (Number(balance?.valuation?.pricedItems || 0) > 0 || balance?.valuation?.complete === true) {
63
- return roundedUsd(value);
64
- }
65
- return null;
66
- }
67
-
68
- function knownNftValue(nfts) {
69
- if (!nfts || nfts.status === "unavailable" || nfts.status === "not-requested") return null;
70
- const value = finiteNumber(nfts?.valuation?.estimatedCurrentValueUsd);
71
- if (value == null) return null;
72
- if (Number(nfts?.valuation?.valuedItems || 0) > 0 || nfts?.valuation?.complete === true) {
73
- return roundedUsd(value);
74
- }
75
- return null;
76
- }
77
-
78
- function liquidBreakdown(balance) {
79
- const rows = [];
80
- for (const chain of balance?.chains || []) {
81
- if (chain.family === "hyperliquid") {
82
- const spot = (chain.spot?.balances || []).reduce((sum, item) => {
83
- const value = finiteNumber(item.usdValue);
84
- return value == null ? sum : sum + value;
85
- }, 0);
86
- const perps = finiteNumber(chain.perps?.accountValueUsd);
87
- const knownUsd = roundedUsd(spot + (perps ?? 0));
88
- if (knownUsd !== 0 || perps != null || (chain.spot?.balances || []).some((item) => finiteNumber(item.usdValue) != null)) {
89
- rows.push({ family: "hyperliquid", chainId: null, name: chain.name || "Hyperliquid", knownUsd });
90
- }
91
- continue;
92
- }
93
- const value = finiteNumber(chain.native?.usdValue);
94
- if (value == null) continue;
95
- rows.push({
96
- family: chain.family || "evm",
97
- chainId: chain.chainId ?? null,
98
- name: chain.name || chain.native?.symbol || "Unknown",
99
- knownUsd: roundedUsd(value),
100
- });
101
- }
102
- return rows;
103
- }
104
-
105
- function coverageSummary(balance, nfts, includeNfts) {
106
- const nftRows = Array.isArray(nfts?.coverage) ? nfts.coverage : [];
107
- return {
108
- balances: balance?.coverage || null,
109
- nfts: {
110
- requested: includeNfts,
111
- ok: nftRows.filter((row) => row.status === "ok").length,
112
- partial: nftRows.filter((row) => row.status === "partial").length,
113
- unavailable: nftRows.filter((row) => row.status === "unavailable").length,
114
- notConfigured: nftRows.filter((row) => row.status === "not-configured").length,
115
- status: !includeNfts
116
- ? "not-requested"
117
- : nfts?.status === "unavailable"
118
- ? "unavailable"
119
- : nfts?.valuation?.complete
120
- ? "ok"
121
- : "partial",
122
- },
123
- };
124
- }
125
-
126
- async function appendSnapshot(snapshot, opts) {
127
- const file = resolvePortfolioHistoryFile(opts);
128
- const line = `${JSON.stringify(snapshot)}\n`;
129
- if (Buffer.byteLength(line) > 32 * 1024) throw new Error("portfolio history snapshot exceeds 32 KiB");
130
- await mkdir(path.dirname(file), { recursive: true, mode: 0o700 });
131
- const flags = constants.O_APPEND | constants.O_CREAT | constants.O_WRONLY | (constants.O_NOFOLLOW || 0);
132
- const handle = await open(file, flags, 0o600);
133
- try {
134
- await handle.writeFile(line, "utf8");
135
- } finally {
136
- await handle.close();
137
- }
138
- await chmod(file, 0o600);
139
- return file;
140
- }
141
-
142
- export async function portfolioSnapshot(args = {}, opts = {}) {
143
- const includeNfts = args.includeNfts !== false;
144
- const balanceImpl = opts.portfolioBalanceImpl || portfolioBalance;
145
- const nftImpl = opts.nftInventoryImpl || nftInventory;
146
- const balancePromise = balanceImpl(args, opts);
147
- const nftsPromise = includeNfts
148
- ? nftImpl({ ...args, includePnl: false }, opts).catch((error) => ({
149
- status: "unavailable",
150
- error: String(error?.message || error).slice(0, 300),
151
- }))
152
- : Promise.resolve({ status: "not-requested" });
153
- const [balance, nfts] = await Promise.all([balancePromise, nftsPromise]);
154
- const liquidKnownUsd = knownLiquidValue(balance);
155
- const nftEstimatedValueUsd = knownNftValue(nfts);
156
- const components = [liquidKnownUsd, nftEstimatedValueUsd].filter((value) => value != null);
157
- const knownUsd = components.length ? roundedUsd(components.reduce((sum, value) => sum + value, 0)) : null;
158
- const complete = Boolean(
159
- balance?.valuation?.complete &&
160
- (!includeNfts || nfts?.valuation?.complete === true),
161
- );
162
- const nowValue = typeof opts.now === "function" ? opts.now() : new Date();
163
- const recordedAt = new Date(nowValue).toISOString();
164
- const addresses = balance?.addresses || resolvePortfolioAddresses(args, opts.env || process.env);
165
- const portfolioId = portfolioIdForAddresses(addresses);
166
- const warnings = [...(balance?.warnings || [])];
167
- if (includeNfts && nfts?.status === "unavailable") warnings.push(`NFT inventory unavailable: ${nfts.error}`);
168
- if (includeNfts && nfts?.valuation && nfts.valuation.complete !== true) {
169
- warnings.push("NFT estimated value is incomplete and is not an executable bid.");
170
- }
171
- const snapshot = {
172
- schemaVersion: 1,
173
- id: `snapshot_${randomUUID()}`,
174
- portfolioId,
175
- recordedAt,
176
- sourceQueriedAt: {
177
- balances: balance?.queriedAt || null,
178
- nfts: nfts?.generatedAt || null,
179
- },
180
- configuredFamilies: Object.fromEntries(
181
- ["evm", "solana", "bitcoin", "hyperliquid"].map((family) => [family, Boolean(addresses?.[family])]),
182
- ),
183
- valuation: {
184
- knownUsd,
185
- liquidKnownUsd,
186
- nftEstimatedValueUsd,
187
- complete,
188
- label: complete
189
- ? "complete known portfolio value"
190
- : "known priced value, including provider-estimated NFTs when available, not a complete portfolio total",
191
- liquidPricedItems: Number(balance?.valuation?.pricedItems || 0),
192
- liquidUnpricedNonzeroItems: Number(balance?.valuation?.unpricedNonzeroItems || 0),
193
- nftValuedItems: Number(nfts?.valuation?.valuedItems || 0),
194
- nftUnvaluedItems: Number(nfts?.valuation?.unvaluedItems || 0),
195
- },
196
- breakdown: {
197
- liquid: liquidBreakdown(balance),
198
- nfts: {
199
- knownUsd: nftEstimatedValueUsd,
200
- visibleItems: Number(nfts?.inventory?.visibleCount || 0),
201
- flaggedItems: Number(nfts?.inventory?.flaggedCount || 0),
202
- },
203
- },
204
- coverage: coverageSummary(balance, nfts, includeNfts),
205
- warnings: [...new Set(warnings)].slice(0, 50),
206
- };
207
- const historyFile = await appendSnapshot(snapshot, opts);
208
- return {
209
- provider: "portfolio",
210
- operation: "snapshot",
211
- readOnly: true,
212
- localObservationRecorded: true,
213
- historyFile,
214
- snapshot,
215
- balance,
216
- nfts,
217
- };
218
- }
219
-
220
- async function readSnapshots(opts) {
221
- const file = resolvePortfolioHistoryFile(opts);
222
- try {
223
- const data = await readFile(file);
224
- if (data.byteLength > MAX_HISTORY_BYTES) {
225
- throw new Error(`portfolio history exceeds ${MAX_HISTORY_BYTES} bytes`);
226
- }
227
- const snapshots = [];
228
- let corruptLines = 0;
229
- for (const line of data.toString("utf8").split("\n")) {
230
- if (!line.trim()) continue;
231
- try {
232
- const row = JSON.parse(line);
233
- if (row?.schemaVersion === 1 && row?.portfolioId && row?.recordedAt) snapshots.push(row);
234
- else corruptLines += 1;
235
- } catch {
236
- corruptLines += 1;
237
- }
238
- }
239
- return { file, snapshots, corruptLines };
240
- } catch (error) {
241
- if (error?.code === "ENOENT") return { file, snapshots: [], corruptLines: 0 };
242
- throw error;
243
- }
244
- }
245
-
246
- function requestedPortfolioId(args, opts) {
247
- if (args.allPortfolios === true) return null;
248
- if (args.portfolioId) return String(args.portfolioId);
249
- const addresses = resolvePortfolioAddresses(args, opts.env || process.env);
250
- return Object.values(addresses).some(Boolean) ? portfolioIdForAddresses(addresses) : null;
251
- }
252
-
253
- export async function portfolioHistory(args = {}, opts = {}) {
254
- const limit = boundedInteger(args.limit, 100, 1, MAX_HISTORY_LIMIT, "portfolio history limit");
255
- const order = String(args.order || "desc").toLowerCase();
256
- if (!new Set(["asc", "desc"]).has(order)) throw new Error("portfolio history order must be asc or desc");
257
- const since = isoDate(args.since, "portfolio history since");
258
- const until = isoDate(args.until, "portfolio history until");
259
- const portfolioId = requestedPortfolioId(args, opts);
260
- const stored = await readSnapshots(opts);
261
- let matched = stored.snapshots.filter((row) => {
262
- if (portfolioId && row.portfolioId !== portfolioId) return false;
263
- if (since && row.recordedAt < since) return false;
264
- if (until && row.recordedAt > until) return false;
265
- return true;
266
- });
267
- matched.sort((a, b) => String(a.recordedAt).localeCompare(String(b.recordedAt)));
268
- const totalMatching = matched.length;
269
- matched = matched.slice(-limit);
270
- if (order === "desc") matched.reverse();
271
- const valued = matched.filter((row) => finiteNumber(row?.valuation?.knownUsd) != null);
272
- return {
273
- provider: "portfolio",
274
- operation: "history",
275
- readOnly: true,
276
- historyFile: stored.file,
277
- portfolioId,
278
- order,
279
- totalStored: stored.snapshots.length,
280
- totalMatching,
281
- corruptLines: stored.corruptLines,
282
- snapshots: matched,
283
- stats: {
284
- returned: matched.length,
285
- valuedSnapshots: valued.length,
286
- unpricedSnapshots: matched.length - valued.length,
287
- firstRecordedAt: matched.length ? [...matched].sort((a, b) => String(a.recordedAt).localeCompare(String(b.recordedAt)))[0].recordedAt : null,
288
- lastRecordedAt: matched.length ? [...matched].sort((a, b) => String(a.recordedAt).localeCompare(String(b.recordedAt))).at(-1).recordedAt : null,
289
- },
290
- };
291
- }
292
-
293
- function money(value) {
294
- return `$${Number(value).toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
295
- }
296
-
297
- function xml(value) {
298
- return String(value)
299
- .replaceAll("&", "&amp;")
300
- .replaceAll("<", "&lt;")
301
- .replaceAll(">", "&gt;")
302
- .replaceAll('"', "&quot;")
303
- .replaceAll("'", "&apos;");
304
- }
305
-
306
- function sampled(points, maxPoints) {
307
- if (points.length <= maxPoints) return points;
308
- const output = [];
309
- for (let i = 0; i < maxPoints; i += 1) {
310
- output.push(points[Math.round((i * (points.length - 1)) / (maxPoints - 1))]);
311
- }
312
- return output;
313
- }
314
-
315
- function graphSvg(points, portfolioId) {
316
- const width = 1200;
317
- const height = 675;
318
- const left = 100;
319
- const right = 1140;
320
- const top = 100;
321
- const bottom = 570;
322
- const values = points.map((point) => point.value);
323
- let min = Math.min(...values);
324
- let max = Math.max(...values);
325
- if (min === max) {
326
- const padding = Math.max(1, Math.abs(min) * 0.05);
327
- min -= padding;
328
- max += padding;
329
- } else {
330
- const padding = (max - min) * 0.1;
331
- min = Math.max(0, min - padding);
332
- max += padding;
333
- }
334
- const x = (index) => points.length === 1 ? (left + right) / 2 : left + ((right - left) * index) / (points.length - 1);
335
- const y = (value) => bottom - ((value - min) / (max - min)) * (bottom - top);
336
- const pathData = points.map((point, index) => `${index ? "L" : "M"}${x(index).toFixed(2)},${y(point.value).toFixed(2)}`).join(" ");
337
- const grids = Array.from({ length: 5 }, (_, index) => {
338
- const ratio = index / 4;
339
- const yy = top + ratio * (bottom - top);
340
- const value = max - ratio * (max - min);
341
- return `<line x1="${left}" y1="${yy}" x2="${right}" y2="${yy}" stroke="#26313c" stroke-width="1"/><text x="${left - 14}" y="${yy + 5}" text-anchor="end" fill="#8795a5" font-size="15">${money(value)}</text>`;
342
- }).join("");
343
- const circles = points.map((point, index) => `<circle cx="${x(index)}" cy="${y(point.value)}" r="5" fill="#b8f0ff"><title>${xml(point.recordedAt)}: ${money(point.value)}</title></circle>`).join("");
344
- const firstDate = xml(points[0].recordedAt.slice(0, 10));
345
- const lastDate = xml(points.at(-1).recordedAt.slice(0, 10));
346
- const portfolioLabel = xml(portfolioId || "configured portfolio");
347
- return `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}"><rect width="1200" height="675" fill="#0b1016"/><text x="60" y="50" fill="#f4f7fa" font-size="28" font-family="Inter,Arial,sans-serif" font-weight="700">Oracle Portfolio Value</text><text x="60" y="78" fill="#8795a5" font-size="15" font-family="Inter,Arial,sans-serif">Known priced value, not a complete total unless every snapshot says complete · ${portfolioLabel}</text>${grids}<line x1="${left}" y1="${bottom}" x2="${right}" y2="${bottom}" stroke="#526171" stroke-width="1"/><path d="${pathData}" fill="none" stroke="#b8f0ff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>${circles}<text x="${left}" y="610" fill="#8795a5" font-size="15">${firstDate}</text><text x="${right}" y="610" text-anchor="end" fill="#8795a5" font-size="15">${lastDate}</text><text x="60" y="650" fill="#526171" font-size="13">NFT values are provider estimates, not executable bids. Unavailable values are omitted, never plotted as zero.</text></svg>`;
348
- }
349
-
350
- export async function portfolioValueGraph(args = {}, opts = {}) {
351
- if (args.allPortfolios === true) {
352
- throw new Error("portfolio value graph requires one portfolioId or configured public-address portfolio");
353
- }
354
- const maxPoints = boundedInteger(args.maxPoints, 200, 2, 500, "portfolio graph maxPoints");
355
- const history = await portfolioHistory({ ...args, order: "asc", limit: args.limit ?? MAX_HISTORY_LIMIT }, opts);
356
- if (!history.portfolioId) {
357
- throw new Error("portfolio value graph requires one portfolioId or configured public-address portfolio");
358
- }
359
- const known = history.snapshots
360
- .map((snapshot) => ({
361
- recordedAt: snapshot.recordedAt,
362
- value: finiteNumber(snapshot?.valuation?.knownUsd),
363
- complete: snapshot?.valuation?.complete === true,
364
- }))
365
- .filter((point) => point.value != null);
366
- if (!known.length) throw new Error("portfolio value graph requires at least one snapshot with known priced value");
367
- const points = sampled(known, maxPoints);
368
- const start = points[0].value;
369
- const end = points.at(-1).value;
370
- const changeUsd = roundedUsd(end - start);
371
- const changePct = start === 0 ? null : Number((((end - start) / start) * 100).toFixed(2));
372
- const svg = graphSvg(points, history.portfolioId);
373
- return {
374
- provider: "portfolio",
375
- operation: "valueGraph",
376
- readOnly: true,
377
- portfolioId: history.portfolioId,
378
- mimeType: "image/svg+xml",
379
- dataBase64: Buffer.from(svg).toString("base64"),
380
- byteLength: Buffer.byteLength(svg),
381
- summary: {
382
- points: points.length,
383
- omittedUnavailablePoints: history.snapshots.length - known.length,
384
- startRecordedAt: points[0].recordedAt,
385
- endRecordedAt: points.at(-1).recordedAt,
386
- startKnownUsd: start,
387
- endKnownUsd: end,
388
- changeUsd,
389
- changePct,
390
- completeSnapshots: points.filter((point) => point.complete).length,
391
- label: "known priced value history; incomplete snapshots are not complete portfolio totals",
392
- },
393
- };
394
- }