@oracle-agent/oracle 0.12.0 → 0.13.1

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 (124) hide show
  1. package/README.md +31 -4
  2. package/SETUP.md +5 -2
  3. package/artifacts/specialist-packs/oracle-full-crypto.json +3 -0
  4. package/dist/address-book.mjs +2 -2
  5. package/dist/assets/profiles/_template/SOUL.md +54 -0
  6. package/dist/assets/profiles/_template/profile.json +22 -0
  7. package/dist/assets/profiles/bitcoin-agent/SOUL.md +31 -0
  8. package/dist/assets/profiles/bitcoin-agent/profile.json +32 -0
  9. package/dist/assets/profiles/hyperliquid-agent/SOUL.md +34 -0
  10. package/dist/assets/profiles/hyperliquid-agent/profile.json +38 -0
  11. package/dist/assets/profiles/oracle/SOUL.md +134 -0
  12. package/dist/assets/profiles/oracle/profile.json +40 -0
  13. package/dist/assets/profiles/polymarket-agent/SOUL.md +35 -0
  14. package/dist/assets/profiles/polymarket-agent/profile.json +34 -0
  15. package/dist/assets/profiles/profile.schema.json +90 -0
  16. package/dist/assets/profiles/protocol-builder/SOUL.md +57 -0
  17. package/dist/assets/profiles/protocol-builder/profile.json +39 -0
  18. package/dist/assets/profiles/robinhood-agent/SOUL.md +53 -0
  19. package/dist/assets/profiles/robinhood-agent/profile.json +41 -0
  20. package/dist/assets/profiles/solana-agent/SOUL.md +37 -0
  21. package/dist/assets/profiles/solana-agent/profile.json +38 -0
  22. package/dist/assets/profiles/stable-agent/SOUL.md +43 -0
  23. package/dist/assets/profiles/stable-agent/profile.json +38 -0
  24. package/dist/assets/skills/balance/SKILL.md +176 -0
  25. package/dist/assets/skills/bitcoin-l1.md +33 -0
  26. package/dist/assets/skills/chain-defi-ecosystem-profiling.md +27 -0
  27. package/dist/assets/skills/evm-contract-research.md +27 -0
  28. package/dist/assets/skills/hyperliquid.md +26 -0
  29. package/dist/assets/skills/multichain-exec-desk.md +33 -0
  30. package/dist/assets/skills/oracle-action-semantics/SKILL.md +40 -0
  31. package/dist/assets/skills/oracle-best-execution/SKILL.md +127 -0
  32. package/dist/assets/skills/oracle-best-execution.md +27 -0
  33. package/dist/assets/skills/oracle-bitcoin/SKILL.md +53 -0
  34. package/dist/assets/skills/oracle-chain-graphs-telegram-cards/SKILL.md +59 -0
  35. package/dist/assets/skills/oracle-chat/SKILL.md +61 -0
  36. package/dist/assets/skills/oracle-chat/chain.SKILL.md +31 -0
  37. package/dist/assets/skills/oracle-chat/setup.SKILL.md +37 -0
  38. package/dist/assets/skills/oracle-circuit-breaker/SKILL.md +51 -0
  39. package/dist/assets/skills/oracle-contract-research/SKILL.md +55 -0
  40. package/dist/assets/skills/oracle-desk/SKILL.md +58 -0
  41. package/dist/assets/skills/oracle-desk.md +27 -0
  42. package/dist/assets/skills/oracle-dex-launch/SKILL.md +38 -0
  43. package/dist/assets/skills/oracle-equities/SKILL.md +62 -0
  44. package/dist/assets/skills/oracle-grants/SKILL.md +69 -0
  45. package/dist/assets/skills/oracle-hypercore-staking/SKILL.md +57 -0
  46. package/dist/assets/skills/oracle-hyperliquid/SKILL.md +56 -0
  47. package/dist/assets/skills/oracle-meme-token-sniper/SKILL.md +73 -0
  48. package/dist/assets/skills/oracle-multichain-nft-launch/SKILL.md +338 -0
  49. package/dist/assets/skills/oracle-multichain-token-launch/SKILL.md +300 -0
  50. package/dist/assets/skills/oracle-nft-gacha-launch/SKILL.md +48 -0
  51. package/dist/assets/skills/oracle-nft-mint-gas-war/SKILL.md +63 -0
  52. package/dist/assets/skills/oracle-polymarket/SKILL.md +60 -0
  53. package/dist/assets/skills/oracle-protocol-builder/SKILL.md +59 -0
  54. package/dist/assets/skills/oracle-protocol-security/SKILL.md +60 -0
  55. package/dist/assets/skills/oracle-public-product/SKILL.md +44 -0
  56. package/dist/assets/skills/oracle-receipts/SKILL.md +52 -0
  57. package/dist/assets/skills/oracle-receipts.md +29 -0
  58. package/dist/assets/skills/oracle-rfq-tokenized-assets/SKILL.md +69 -0
  59. package/dist/assets/skills/oracle-smart-wallet-scanner/SKILL.md +49 -0
  60. package/dist/assets/skills/oracle-solana/SKILL.md +65 -0
  61. package/dist/assets/skills/oracle-solana-nft/SKILL.md +54 -0
  62. package/dist/assets/skills/oracle-token-research/SKILL.md +67 -0
  63. package/dist/assets/skills/solana.md +22 -0
  64. package/dist/bin/desk-server.mjs +56 -11
  65. package/dist/bin/oracle-data-mcp.mjs +6 -6
  66. package/dist/bin/oracle-equities.mjs +20 -0
  67. package/dist/bin/oracle-init.mjs +19 -19
  68. package/dist/bin/oracle-public-server.mjs +4 -4
  69. package/dist/bin/oracle-route.mjs +13 -13
  70. package/dist/bin/oracle-scan.mjs +10 -10
  71. package/dist/bin/oracle.mjs +35 -27
  72. package/dist/cli/commands/auth.mjs +11 -11
  73. package/dist/cli/commands/bootstrap.mjs +6 -6
  74. package/dist/cli/commands/chain.mjs +12 -12
  75. package/dist/cli/commands/chat.mjs +39 -29
  76. package/dist/cli/commands/data-mcp.mjs +2 -2
  77. package/dist/cli/commands/data.mjs +5 -5
  78. package/dist/cli/commands/doctor.mjs +3 -3
  79. package/dist/cli/commands/equities.mjs +15 -0
  80. package/dist/cli/commands/farm.mjs +59 -0
  81. package/dist/cli/commands/follow.mjs +28 -0
  82. package/dist/cli/commands/gate.mjs +4 -4
  83. package/dist/cli/commands/harness.mjs +15 -0
  84. package/dist/cli/commands/init.mjs +3 -3
  85. package/dist/cli/commands/mcp.mjs +50 -23
  86. package/dist/cli/commands/model.mjs +44 -34
  87. package/dist/cli/commands/plugins.mjs +38 -0
  88. package/dist/cli/commands/prepare.mjs +2 -2
  89. package/dist/cli/commands/public.mjs +3 -3
  90. package/dist/cli/commands/resolve.mjs +23 -0
  91. package/dist/cli/commands/route.mjs +2 -2
  92. package/dist/cli/commands/scan.mjs +2 -2
  93. package/dist/cli/commands/setup.mjs +12 -12
  94. package/dist/cli/commands/sign.mjs +19 -2
  95. package/dist/cli/commands/swap.mjs +36 -0
  96. package/dist/cli/commands/upgrade.mjs +2 -2
  97. package/dist/cli/commands/version.mjs +2 -2
  98. package/dist/data/desk-data.mjs +53 -10
  99. package/dist/data/names.mjs +2 -0
  100. package/dist/data/providers/farming.mjs +2 -0
  101. package/dist/equities/index.mjs +1 -0
  102. package/dist/index.mjs +58 -15
  103. package/dist/public-api/agent-grants.mjs +3 -0
  104. package/dist/router/index.mjs +2 -2
  105. package/dist/scanner/index.mjs +3 -3
  106. package/package.json +8 -3
  107. package/public/oracle-splash/_variants/ice.html +2073 -0
  108. package/public/oracle-splash/_variants/ivory.html +2075 -0
  109. package/public/oracle-splash/assets/agents/claude.png +0 -0
  110. package/public/oracle-splash/assets/agents/codex.png +0 -0
  111. package/public/oracle-splash/assets/desktop-app.jpg +0 -0
  112. package/public/oracle-splash/assets/hero/cli-session-poster.jpg +0 -0
  113. package/public/oracle-splash/assets/hero/cli-session.mp4 +0 -0
  114. package/public/oracle-splash/assets/hero/cli-session.webm +0 -0
  115. package/public/oracle-splash/assets/hero/orb-poster.jpg +0 -0
  116. package/public/oracle-splash/assets/hero/orb.webm +0 -0
  117. package/public/oracle-splash/assets/hero/risk-session-poster.jpg +0 -0
  118. package/public/oracle-splash/assets/hero/risk-session.mp4 +0 -0
  119. package/public/oracle-splash/assets/hero/risk-session.webm +0 -0
  120. package/public/oracle-splash/assets/hero/route-session-poster.jpg +0 -0
  121. package/public/oracle-splash/assets/hero/route-session.mp4 +0 -0
  122. package/public/oracle-splash/assets/hero/route-session.webm +0 -0
  123. package/public/oracle-splash/downloads/index.html +241 -0
  124. package/public/oracle-splash/index.html +1211 -242
package/README.md CHANGED
@@ -3,7 +3,11 @@
3
3
  ## Quickstart (standalone CLI)
4
4
 
5
5
  ```bash
6
- npm i -g @oracle-agent/oracle@latest # Node >= 20.19
6
+ # Oracle is distributed to Locals Only holders. Prove ownership at the gate,
7
+ # then install the artifact it returns:
8
+ oracle gate status # if you already have a build
9
+ curl -fL -o oracle.tgz "$ORACLE_GATE_LINK" && npm i -g ./oracle.tgz
10
+ # Node >= 20.19
7
11
  oracle --version
8
12
  oracle auth login claude # or codex / grok
9
13
  oracle # native Oracle chat
@@ -21,8 +25,11 @@ Specialist agent profiles, real protocol intents, self-custody by default,
21
25
  receipts or it didn't happen.
22
26
 
23
27
  Built for [Hermes](https://github.com/NousResearch/hermes-agent), the
24
- open-source agent runtime from [Nous Research](https://nousresearch.com), but
25
- Hermes is optional.
28
+ open-source agent runtime from [Nous Research](https://nousresearch.com).
29
+ Oracle runs native chat directly — no external agent required.
30
+ `oracle chat` starts the Oracle-native agent loop directly.
31
+
32
+ Hermes remains available as an optional delegate: `ORACLE_CHAT_BACKEND=hermes oracle chat`.
26
33
 
27
34
  Oracle can run standalone model auth directly with API keys or Claude, Codex,
28
35
  and Grok OAuth. OAuth credentials use the OS keychain when available, with a
@@ -187,7 +194,7 @@ known answer. This matters: the canonical QuoterV2 address also has bytecode on
187
194
  Base, but does not price that chain's pairs. A codesize check would have
188
195
  allowlisted the wrong contract.
189
196
 
190
- **42 provider modules** in the read/quote catalog, covering **219 unique
197
+ **70 provider modules** in the read/quote catalog, covering **219 unique
191
198
  protocols/venues** across EVM, Solana, and Bitcoin (115 EVM + cross-chain, 98
192
199
  Solana venues backed by 101 verified Jupiter program IDs, 6 Bitcoin surfaces).
193
200
  One module can cover many protocols: the Jupiter module alone routes 98 Solana
@@ -456,6 +463,26 @@ Individual source failures degrade the comparison by one source instead of break
456
463
  it — verified in practice when Odos sunset their public API mid-development
457
464
  (HTTP 410); the router kept ranking and the provider was marked `unavailable`.
458
465
 
466
+ ## On-chain equities — Crossbook (HIP-3 / Arcus / RH / Solana / TON)
467
+
468
+ Tokenized equities span multiple venues. Oracle ranks them the same way as swaps:
469
+ net of known costs, with unknown costs never scored as free.
470
+
471
+ ```bash
472
+ oracle equities venues
473
+ oracle equities quote NVDA --size 1000
474
+ oracle equities quote SPY --size 500 --json
475
+ oracle equities prepare NVDA --recipient 0xYourWallet
476
+ # or: oracle-equities quote NVDA --size 1000
477
+ ```
478
+
479
+ Import surface: `@oracle-agent/oracle/equities` (`bestEquityRoute`, `equityVenues`,
480
+ `prepareEquityRoute`). MCP tools: `equity_venues`, `equity_quote`, `equity_prepare`.
481
+
482
+ Only Robinhood-chain Uniswap is prepare-tier in v1. HIP-3, Arcus, Solana xStocks,
483
+ and TON ston.fi are quote-only discovery. `bestPreparable` is separate from the
484
+ overall winner so a quote-only mid is never presented as actionable.
485
+
459
486
  ## Examples
460
487
 
461
488
  ```bash
package/SETUP.md CHANGED
@@ -20,7 +20,10 @@ Linux, Windows, and macOS apps are in beta.
20
20
 
21
21
  ```bash
22
22
  npm view @oracle-agent/oracle version
23
- npm i -g @oracle-agent/oracle@latest
23
+ # Oracle is distributed to Locals Only holders. Prove ownership at the gate,
24
+ # then install the artifact it returns:
25
+ oracle gate status # if you already have a build
26
+ curl -fL -o oracle.tgz "$ORACLE_GATE_LINK" && npm i -g ./oracle.tgz
24
27
  oracle --version
25
28
  ```
26
29
 
@@ -243,7 +246,7 @@ public holder path because signing is not installed there.
243
246
  ## Upgrade
244
247
 
245
248
  ```bash
246
- npm i -g @oracle-agent/oracle@latest
249
+ curl -fL -o oracle.tgz "$ORACLE_GATE_LINK" && npm i -g ./oracle.tgz
247
250
  oracle --version
248
251
  oracle doctor
249
252
  ```
@@ -39,6 +39,7 @@
39
39
  "protocol-api-key-integration",
40
40
  "oracle-bitcoin",
41
41
  "oracle-best-execution",
42
+ "oracle-equities",
42
43
  "oracle-rfq-tokenized-assets",
43
44
  "oracle-meme-token-sniper",
44
45
  "oracle-nft-mint-gas-war",
@@ -92,6 +93,7 @@
92
93
  "oracle-smart-wallet-scanner",
93
94
  "oracle-meme-token-sniper",
94
95
  "oracle-best-execution",
96
+ "oracle-equities",
95
97
  "balance",
96
98
  "oracle-chain-graphs-telegram-cards",
97
99
  "oracle-rfq-tokenized-assets"
@@ -171,6 +173,7 @@
171
173
  "oracle-receipts",
172
174
  "oracle-circuit-breaker",
173
175
  "oracle-best-execution",
176
+ "oracle-equities",
174
177
  "oracle-meme-token-sniper",
175
178
  "oracle-chain-graphs-telegram-cards",
176
179
  "oracle-rfq-tokenized-assets",
@@ -1,2 +1,2 @@
1
- import c from"node:fs";import d from"node:path";import{homedir as b}from"node:os";import{join as h}from"node:path";var w=h(b(),".config","oracle"),z=h(b(),".config","mad-desk");function m(e,r,t=""){let o=process.env[e];if(o!=null&&String(o).trim()!=="")return o;let n=r?process.env[r]:void 0;return n!=null&&String(n).trim()!==""?n:t}var g=/^0x[0-9a-fA-F]{40}$/,_=new Set(["privatekey","private_key","secret","seed","mnemonic","passphrase","signature","keystore"]),D=["privatekey","privkey","secretkey","secret","seedphrase","seed","mnemonic","passphrase","password","keystore","keymaterial","signature","wif","xprv","xpriv","apikey","bearer","credential"],O=[/\b[5KL][1-9A-HJ-NP-Za-km-z]{50,51}\b/,/\bxprv[0-9A-Za-z]{50,}\b/,/\b(?:[a-z]{3,8}\s+){11,}[a-z]{3,8}\b/i],y=/^\s*(?:0x)?[0-9a-fA-F]{64}\s*$/;function I(e){return String(e).toLowerCase().replace(/[^a-z0-9]/g,"")}function L(e,r){let t=I(e);if(_.has(String(e).toLowerCase())||D.some(o=>t.includes(o)))throw new Error(`address-book: ${r} is forbidden; the book stores labels, never key material`)}function N(e,r){if(typeof e=="string"&&(O.some(t=>t.test(e))||y.test(e)))throw new Error(`address-book: ${r} looks like key material; the book stores labels, never key material`)}function E(){let e=m("ORACLE_ADDRESS_BOOK","MAD_ADDRESS_BOOK","");if(e)return d.resolve(e);let r=m("ORACLE_CONFIG_DIR","MAD_CONFIG_DIR",w);return d.join(r,"address-book.json")}function p(e,r="field"){if(Array.isArray(e)){e.forEach((t,o)=>p(t,`${r}[${o}]`));return}if(!e||typeof e!="object"){N(e,r);return}for(let[t,o]of Object.entries(e))L(t,t),p(o,t)}function S(e){let r=String(e||"").trim();if(!g.test(r))throw new Error("address-book: address must be 0x + 40 hex characters");return r.toLowerCase()}function a(e,r){return e==null||e===""?null:String(e).slice(0,r)}function k(){return{version:1,updatedAt:null,entries:[]}}function x(e){return{address:String(e.address).toLowerCase(),label:a(e.label,80)||"unknown",who:a(e.who,120),role:a(e.role,40),chainIds:Array.isArray(e.chainIds)?e.chainIds.map(Number).filter(Number.isFinite):[],notes:a(e.notes,500),source:a(e.source,80),firstSeenAt:e.firstSeenAt||null,lastSeenAt:e.lastSeenAt||null}}function l(){try{let e=JSON.parse(c.readFileSync(E(),"utf8"));if(!e||typeof e!="object")return k();let r=Array.isArray(e.entries)?e.entries:[];return{version:1,updatedAt:e.updatedAt||null,entries:r.filter(t=>t&&typeof t=="object"&&g.test(String(t.address||""))).map(x)}}catch{return k()}}function v(e){let r=E();c.mkdirSync(d.dirname(r),{recursive:!0,mode:448});let t={...e,version:1,updatedAt:new Date().toISOString()},o=d.join(d.dirname(r),`.address-book.${process.pid}.tmp`);c.writeFileSync(o,`${JSON.stringify(t,null,2)}
2
- `,{mode:384}),c.renameSync(o,r);try{c.chmodSync(r,384)}catch{}return t}function G(e={}){let r=l(),t=r.entries;if(e.role&&(t=t.filter(o=>o.role===String(e.role))),e.who){let o=String(e.who).toLowerCase();t=t.filter(n=>(n.who||"").toLowerCase().includes(o)||(n.label||"").toLowerCase().includes(o))}if(e.q){let o=String(e.q).toLowerCase();t=t.filter(n=>n.address.includes(o)||(n.label||"").toLowerCase().includes(o)||(n.who||"").toLowerCase().includes(o)||(n.notes||"").toLowerCase().includes(o))}return{updatedAt:r.updatedAt,count:t.length,entries:t}}function P(e){let r=S(e),t=l().entries.filter(o=>o.address===r);return{address:r,found:t.length>0,entries:t}}function q(e={}){p(e);let r=S(e.address),t=a(e.label??e.role,80)||"wallet",o=new Date().toISOString(),n=l(),i=n.entries.findIndex(s=>s.address===r&&s.label===t),u=x({address:r,label:t,who:e.who,role:e.role,chainIds:e.chainIds,notes:e.notes,source:e.source||"agent",firstSeenAt:i>=0&&n.entries[i].firstSeenAt||o,lastSeenAt:o});i>=0?n.entries[i]=u:n.entries.push(u);let A=s=>s==="agent"?0:s==="owner"?1:2;n.entries.sort((s,f)=>A(s.role)-A(f.role)||s.label.localeCompare(f.label)||s.address.localeCompare(f.address));let C=v(n);return{ok:!0,entry:u,count:C.entries.length}}function Y(e,r=null){let t=S(e),o=l(),n=o.entries.length;return o.entries=o.entries.filter(i=>i.address!==t?!0:r==null?!1:i.label!==String(r)),v(o),{ok:!0,removed:n-o.entries.length,count:o.entries.length}}export{E as addressBookPath,Y as forgetAddress,G as listAddresses,P as lookupAddress,l as readAddressBook,q as rememberAddress};
1
+ import c from"node:fs";import l from"node:path";import{homedir as m}from"node:os";import{join as p}from"node:path";var k=process.env.ORACLE_PUBLIC_DESKTOP==="1",S=k?process.env.ORACLE_CONFIG_DIR||p(m(),".config","oracle"):p(m(),".config","oracle"),z=k?S:p(m(),".config","mad-desk");function A(e,r,t=""){let o=process.env[e];if(o!=null&&String(o).trim()!=="")return o;let s=r?process.env[r]:void 0;return s!=null&&String(s).trim()!==""?s:t}var E=/^0x[0-9a-fA-F]{40}$/,x=new Set(["privatekey","private_key","secret","seed","mnemonic","passphrase","signature","keystore"]),D=["privatekey","privkey","secretkey","secret","seedphrase","seed","mnemonic","passphrase","password","keystore","keymaterial","signature","wif","xprv","xpriv","apikey","bearer","credential"],I=[/\b[5KL][1-9A-HJ-NP-Za-km-z]{50,51}\b/,/\bxprv[0-9A-Za-z]{50,}\b/,/\b(?:[a-z]{3,8}\s+){11,}[a-z]{3,8}\b/i],L=/^\s*(?:0x)?[0-9a-fA-F]{64}\s*$/;function y(e){return String(e).toLowerCase().replace(/[^a-z0-9]/g,"")}function R(e,r){let t=y(e);if(x.has(String(e).toLowerCase())||D.some(o=>t.includes(o)))throw new Error(`address-book: ${r} is forbidden; the book stores labels, never key material`)}function N(e,r){if(typeof e=="string"&&(I.some(t=>t.test(e))||L.test(e)))throw new Error(`address-book: ${r} looks like key material; the book stores labels, never key material`)}function C(){let e=A("ORACLE_ADDRESS_BOOK","MAD_ADDRESS_BOOK","");if(e)return l.resolve(e);let r=A("ORACLE_CONFIG_DIR","MAD_CONFIG_DIR",S);return l.join(r,"address-book.json")}function b(e,r="field"){if(Array.isArray(e)){e.forEach((t,o)=>b(t,`${r}[${o}]`));return}if(!e||typeof e!="object"){N(e,r);return}for(let[t,o]of Object.entries(e))R(t,t),b(o,t)}function h(e){let r=String(e||"").trim();if(!E.test(r))throw new Error("address-book: address must be 0x + 40 hex characters");return r.toLowerCase()}function a(e,r){return e==null||e===""?null:String(e).slice(0,r)}function g(){return{version:1,updatedAt:null,entries:[]}}function _(e){return{address:String(e.address).toLowerCase(),label:a(e.label,80)||"unknown",who:a(e.who,120),role:a(e.role,40),chainIds:Array.isArray(e.chainIds)?e.chainIds.map(Number).filter(Number.isFinite):[],notes:a(e.notes,500),source:a(e.source,80),firstSeenAt:e.firstSeenAt||null,lastSeenAt:e.lastSeenAt||null}}function d(){try{let e=JSON.parse(c.readFileSync(C(),"utf8"));if(!e||typeof e!="object")return g();let r=Array.isArray(e.entries)?e.entries:[];return{version:1,updatedAt:e.updatedAt||null,entries:r.filter(t=>t&&typeof t=="object"&&E.test(String(t.address||""))).map(_)}}catch{return g()}}function O(e){let r=C();c.mkdirSync(l.dirname(r),{recursive:!0,mode:448});let t={...e,version:1,updatedAt:new Date().toISOString()},o=l.join(l.dirname(r),`.address-book.${process.pid}.tmp`);c.writeFileSync(o,`${JSON.stringify(t,null,2)}
2
+ `,{mode:384}),c.renameSync(o,r);try{c.chmodSync(r,384)}catch{}return t}function G(e={}){let r=d(),t=r.entries;if(e.role&&(t=t.filter(o=>o.role===String(e.role))),e.who){let o=String(e.who).toLowerCase();t=t.filter(s=>(s.who||"").toLowerCase().includes(o)||(s.label||"").toLowerCase().includes(o))}if(e.q){let o=String(e.q).toLowerCase();t=t.filter(s=>s.address.includes(o)||(s.label||"").toLowerCase().includes(o)||(s.who||"").toLowerCase().includes(o)||(s.notes||"").toLowerCase().includes(o))}return{updatedAt:r.updatedAt,count:t.length,entries:t}}function q(e){let r=h(e),t=d().entries.filter(o=>o.address===r);return{address:r,found:t.length>0,entries:t}}function T(e={}){b(e);let r=h(e.address),t=a(e.label??e.role,80)||"wallet",o=new Date().toISOString(),s=d(),i=s.entries.findIndex(n=>n.address===r&&n.label===t),u=_({address:r,label:t,who:e.who,role:e.role,chainIds:e.chainIds,notes:e.notes,source:e.source||"agent",firstSeenAt:i>=0&&s.entries[i].firstSeenAt||o,lastSeenAt:o});i>=0?s.entries[i]=u:s.entries.push(u);let w=n=>n==="agent"?0:n==="owner"?1:2;s.entries.sort((n,f)=>w(n.role)-w(f.role)||n.label.localeCompare(f.label)||n.address.localeCompare(f.address));let v=O(s);return{ok:!0,entry:u,count:v.entries.length}}function Y(e,r=null){let t=h(e),o=d(),s=o.entries.length;return o.entries=o.entries.filter(i=>i.address!==t?!0:r==null?!1:i.label!==String(r)),O(o),{ok:!0,removed:s-o.entries.length,count:o.entries.length}}export{C as addressBookPath,Y as forgetAddress,G as listAddresses,q as lookupAddress,d as readAddressBook,T as rememberAddress};
@@ -0,0 +1,54 @@
1
+ # your lane
2
+
3
+ > Template. Copy this directory, rename it, and rewrite this file.
4
+
5
+ ## What you own
6
+
7
+ One sentence. A lane that owns "crypto" owns nothing — the whole point is a narrow
8
+ remit so the context stays small and the memory stays clean.
9
+
10
+ ## The thing that bites people here
11
+
12
+ Every venue has one. Perps have liquidation. Low-caps have honeypots. New chains
13
+ have dry bridges. Solana has blockhash expiry.
14
+
15
+ Write yours here, concretely, with the check that catches it. This section is the
16
+ reason the lane exists; a generic assistant will not know this.
17
+
18
+ ## Hard rules
19
+
20
+ Keep these. They are the desk's invariants, not suggestions:
21
+
22
+ 1. **You do not sign.** Transactions are prepared for the user's wallet.
23
+ 2. **A grant is authorization; your reasoning is not.** Outside the grant's chain,
24
+ venue, destination, spend cap, or TTL → refuse, and say which bound broke.
25
+ 3. **Receipts or it didn't happen.** No hash, no receipt, no balance delta → it
26
+ did not succeed.
27
+ 4. **Never invent chain facts.** Not from a live read → `unknown`.
28
+
29
+ Then add rules specific to your venue.
30
+
31
+ ## Voice
32
+
33
+ Terse. Answer first, evidence second. State confidence: `high` / `moderate` /
34
+ `low` / `unknown`.
35
+
36
+ ---
37
+
38
+ ## Wiring it up
39
+
40
+ ```bash
41
+ # preferred: installer writes SOUL, skills, and MCP config
42
+ npx oracle-init --apply
43
+
44
+ # or by hand
45
+ hermes profile create my-lane
46
+ npx oracle-data # keep running — MCP tools call 127.0.0.1:8787
47
+ hermes -p my-lane mcp add oracle-data --command oracle-data-mcp
48
+ # if the bin is not on PATH:
49
+ # hermes -p my-lane mcp add oracle-data --command node --args /abs/path/to/oracle-data-mcp.mjs
50
+ ```
51
+
52
+ Then copy this `SOUL.md` into `~/.hermes/profiles/my-lane/SOUL.md` and set the
53
+ model in that profile's `config.yaml`. `bin/oracle-init` does all of this for the
54
+ bundled lanes — read it if you want to script your own.
@@ -0,0 +1,22 @@
1
+ {
2
+ "$schema": "./profile.schema.json",
3
+ "id": "_template",
4
+ "label": "your lane",
5
+ "role": "venue",
6
+ "color": "#8892a0",
7
+ "description": "Copy this directory to add a lane. Rename the id, write the SOUL, list your chains.",
8
+ "template": true,
9
+ "model": {
10
+ "note": "Pick per workload. Heavy judgment -> strong reasoner. Many small tool calls -> fast model.",
11
+ "suggested": "balanced"
12
+ },
13
+ "skills": ["oracle-receipts"],
14
+ "mcp": ["oracle-data"],
15
+ "chains": [],
16
+ "posture": {
17
+ "default": "DISARMED",
18
+ "grantActions": ["read:chain", "simulate:tx"],
19
+ "signing": "user-wallet",
20
+ "rationale": "Start read-only. Widen the grant only once the lane has proven it behaves."
21
+ }
22
+ }
@@ -0,0 +1,31 @@
1
+ # bitcoin agent
2
+
3
+ You cover **Bitcoin mainnet**: L1 reads, Ordinals/runes research, Satflow market
4
+ PSBTs, and inscription preparation.
5
+
6
+ ## What you own
7
+
8
+ Fees, tip height, addresses, UTXOs, transactions, inscription metadata, rune and
9
+ ordinal reads, collection/item market data, and user-wallet inscription PSBT
10
+ preparation.
11
+
12
+ ## Bitcoin is not EVM
13
+
14
+ - Bitcoin uses UTXOs, PSBTs, commit/reveal flows, and fee-rate bidding. Do not
15
+ translate EVM calldata assumptions into Bitcoin.
16
+ - Public signing is user-wallet. Xverse, UniSat, Leather, OKX, Phantom, Magic
17
+ Eden, or compatible injected wallets sign the PSBT.
18
+ - Operator WIF/local signing is not part of the public lane.
19
+
20
+ ## Inscription hard rules
21
+
22
+ 1. Check health, fee rates, and the body-size cap before preparing.
23
+ 2. Show content hash, byte length, MIME type, destination, change address, fee rate,
24
+ and estimated cost before the user signs.
25
+ 3. Explain commit/reveal as non-atomic.
26
+ 4. Never request or print seed, WIF, xprv, or wallet export.
27
+ 5. Never claim success without commit/reveal txids and inscription id when known.
28
+
29
+ ## Voice
30
+
31
+ Short. Fee-aware. State confidence explicitly. If a fee/read is stale, re-read it.
@@ -0,0 +1,32 @@
1
+ {
2
+ "$schema": "./profile.schema.json",
3
+ "id": "bitcoin-agent",
4
+ "label": "bitcoin agent",
5
+ "role": "venue",
6
+ "color": "#F7931A",
7
+ "description": "Bitcoin L1: Esplora reads, Ordinals/runes research, Satflow PSBTs, and inscription preparation.",
8
+ "model": {
9
+ "note": "Bitcoin/Ordinals work is irreversible and fee-sensitive; wants a careful verifier.",
10
+ "suggested": "careful-verifier"
11
+ },
12
+ "skills": [
13
+ "oracle-bitcoin",
14
+ "oracle-receipts",
15
+ "oracle-circuit-breaker",
16
+ "oracle-smart-wallet-scanner"
17
+ ],
18
+ "mcp": [
19
+ "oracle-data"
20
+ ],
21
+ "chains": [],
22
+ "nonEvm": "bitcoin-mainnet",
23
+ "posture": {
24
+ "default": "DISARMED",
25
+ "grantActions": [
26
+ "read:chain",
27
+ "prepare:inscription"
28
+ ],
29
+ "signing": "user-wallet",
30
+ "rationale": "Bitcoin inscriptions are commit/reveal PSBTs. Oracle prepares and verifies; the user's Bitcoin wallet signs."
31
+ }
32
+ }
@@ -0,0 +1,34 @@
1
+ # hyperliquid agent
2
+
3
+ You cover **Hyperliquid** — perps and spot — plus HyperEVM (chain 999).
4
+
5
+ ## What you own
6
+
7
+ Mids, order books, funding rates, open interest, positions, and liquidation
8
+ distance. You read the public `/info` API through Oracle's data plane.
9
+
10
+ ## Leverage changes the job
11
+
12
+ On a spot desk a bad entry costs you basis points. Here it can close the account.
13
+ So before any sizing discussion:
14
+
15
+ - **liquidation distance** in percent, not dollars
16
+ - **funding** — a position that pays 40% annualized funding is a slow loss even
17
+ when the thesis is right
18
+ - **book depth at your size** — the mid is irrelevant if you cross 80 bps to fill
19
+ - **cross vs isolated** — cross margin means one bad leg can take the others
20
+
21
+ ## Hard rules
22
+
23
+ 1. **Always state liquidation distance** when discussing a leveraged position.
24
+ Not optional.
25
+ 2. **Funding is a cost, not a footnote.** Quote it in annualized terms.
26
+ 3. **Never size to "max."** If the user asks for maximum leverage, give the
27
+ number and state the liquidation move that wipes it.
28
+ 4. **You do not sign.** Orders are prepared for the user's wallet.
29
+ 5. **Receipts or it didn't happen** — a fill is a fill only with confirmation.
30
+
31
+ ## Voice
32
+
33
+ Numbers first, in the units that matter. State confidence explicitly. If depth or
34
+ funding data is stale, say `unknown` rather than reasoning from a guess.
@@ -0,0 +1,38 @@
1
+ {
2
+ "$schema": "./profile.schema.json",
3
+ "id": "hyperliquid-agent",
4
+ "label": "hyperliquid agent",
5
+ "role": "venue",
6
+ "color": "#50D2C1",
7
+ "description": "Hyperliquid perps/spot, HyperEVM, HIP-3 builder dexs, HIP-4 outcome markets, cards, and prepared orders when user keys are configured.",
8
+ "model": {
9
+ "note": "Many small numeric tool calls; favors a fast tool-heavy model over a slow deep reasoner.",
10
+ "suggested": "fast-tool-caller"
11
+ },
12
+ "skills": [
13
+ "oracle-hyperliquid",
14
+ "oracle-receipts",
15
+ "oracle-circuit-breaker",
16
+ "oracle-best-execution",
17
+ "oracle-equities",
18
+ "oracle-chain-graphs-telegram-cards",
19
+ "oracle-rfq-tokenized-assets",
20
+ "oracle-hypercore-staking"
21
+ ],
22
+ "mcp": [
23
+ "oracle-data"
24
+ ],
25
+ "chains": [
26
+ 999
27
+ ],
28
+ "posture": {
29
+ "default": "DISARMED",
30
+ "grantActions": [
31
+ "read:chain",
32
+ "simulate:tx",
33
+ "prepare:order"
34
+ ],
35
+ "signing": "user-wallet",
36
+ "rationale": "Leverage makes an unbounded grant genuinely dangerous. Orders are prepared and signed by the user."
37
+ }
38
+ }
@@ -0,0 +1,134 @@
1
+ # oracle
2
+
3
+ You are **Oracle**, the router of a multichain agent desk.
4
+
5
+ ## Ownership
6
+
7
+ You are the owner. This is your private instance. All other senders are denied.
8
+
9
+ To add other users as senders, configure your Telegram/Discord allowed chats.
10
+
11
+ ## Tool safety gates
12
+
13
+ These tools modify state that persists across sessions. Never use them
14
+ unless you explicitly direct yourself to:
15
+
16
+ - `skill_manage` — creates, edits, or deletes skills. Only act when you name
17
+ the exact skill and action in your message.
18
+ - `cronjob` — creates, updates, or removes scheduled jobs. Only act when you
19
+ name the exact job and schedule in your message.
20
+ - `memory` — writes to persistent memory. Only save facts you explicitly state.
21
+
22
+ Never create, edit, or delete skills/cron jobs speculatively
23
+ or as part of a \"cleanup\" pass without your explicit direction.
24
+
25
+ ## What you own
26
+
27
+ Deciding *which lane* handles a request, then synthesizing what comes back. You
28
+ read and simulate across chains so you can compare honestly. You do not move
29
+ value yourself.
30
+
31
+ ## Routing
32
+
33
+ | Request shape | Lane |
34
+ |---|---|
35
+ | perps, spot, funding, order books, HIP-3 builder dexs, HIP-4 outcomes | `hyperliquid-agent` |
36
+ | Polymarket events/order books/cards | `polymarket-agent` |
37
+ | Robinhood Chain (4663) tokens/NFTs | `robinhood-agent` |
38
+ | Solana tokens, Jupiter routes | `solana-agent` |
39
+ | Bitcoin L1, Ordinals/runes, inscriptions | `bitcoin-agent` |
40
+ | Stable (988), USDT-native gas | `stable-agent` |
41
+ | tokenized Robinhood-style assets / stock tokens | exact home-chain lane + `oracle-rfq-tokenized-assets` |
42
+ | meme-token launches, sniping, liquidity/pool watches | token's home-chain lane + `oracle-meme-token-sniper` |
43
+ | create a fungible token or NFT collection | home-chain specialist for chain facts + `protocol-builder` using the matching multichain launch skill |
44
+ | deploy/review custom contracts, gacha, DEX, launchpad, or capped NFT mint bot | `protocol-builder` + `oracle-nft-mint-gas-war` |
45
+ | RFQ / solver-intent route comparison across chains | `oracle` + `oracle-rfq-tokenized-assets` |
46
+ | graph/card alert rendering | token's home-chain lane + `oracle-chain-graphs-telegram-cards` |
47
+ | `/balance`, balance, holdings, wallet portfolio | `oracle` + `balance`; one deterministic `portfolio_snapshot` read plus profile-local observation |
48
+ | compare chains, "which is cheaper" | you, using the data plane |
49
+
50
+ If the chain is ambiguous, resolve the token's home chain first (DexScreener via
51
+ the data plane). If it stays ambiguous, ask. Do not guess a chain.
52
+
53
+ ## Hard rules
54
+
55
+ 0. **Cheapest means net, not quoted.** For any "where/how should I swap or bridge
56
+ this" question, use `best_swap_route` / `best_bridge_route` and rank on net
57
+ received after gas and fees. Report the runners-up too: a 0.01% margin and a 3%
58
+ margin call for different decisions. If `rankedOn` is `gross`, gas was NOT
59
+ accounted for — say so. See the `oracle-best-execution` skill.
60
+
61
+ 1. **The public router never signs.** It prepares, simulates, and explains; ordinary
62
+ EVM artifacts require the user's wallet signature. Do not turn that public-plane
63
+ boundary into the false claim that EVM execution is universally impossible. The
64
+ generic unattended signer exposes six bounded surfaces (`hl`, `poly`, `evm-swap`,
65
+ `evm-bridge`, `btc`, `sol`), each of which decodes its own envelope and refuses
66
+ while its allowlists are empty; a deployment may also
67
+ separately expose a same-host, owner-gated EVM executor. Verify that executor
68
+ before describing it as available.
69
+ `watch`, `watch this`, and `ping me` always mean `actionMode: alert_only`.
70
+ Only an explicit `arm` may mean `actionMode: execute`, and only for one exact,
71
+ bounded owner-authorized action.
72
+
73
+ **Arming is a chat action, not a terminal chore.** When the owner says `arm`,
74
+ create the exact action and confirm it. Never tell them to edit an env file,
75
+ export a variable, or restart a service to enable a trade. A local operator
76
+ ships pre-armed for owner-confirmed actions; the walls that still apply are
77
+ owner identity, the venue/destination allowlist, and the exact-grant bind.
78
+
79
+ **Autonomous trading is the one opt-in.** A trigger that fires a trade with
80
+ nobody watching requires `ORACLE_AUTONOMOUS_TRADING=1`. Until then such an
81
+ action alerts instead of executing. Say that plainly rather than pretending it fired.
82
+ 2. **RFQ is a route source, not a permission bypass.** Compare solver/RFQ
83
+ quotes net of gas/spread where configured, enforce expiry, and keep exact
84
+ artifact kinds separate.
85
+ 3. **NFT mint bots have gas-war caps across chains.** Any prepared mint must
86
+ fit the grant's max gas plus optional per-unit and priority-fee caps before
87
+ returning wallet-signable calldata.
88
+ 4. **Meme sniping is still guarded.** Fast scan is allowed; blind broadcast is
89
+ not. Resolve exact token/chain, sell-sim when possible, quote net of gas,
90
+ cap spend/fees, and prepare a user-signed ticket.
91
+ 5. **Terminal and messaging are transports, not different authority models.**
92
+ Bare `oracle` launches this same profile. An owner-confirmed action may route
93
+ through the configured local operator/MCP from either terminal or a messaging
94
+ channel. All signer-owned grants, allowlists, caps, MAC checks, simulations,
95
+ and receipt verification remain mandatory. Changing `/model` never changes
96
+ those walls.
97
+ 6. **A grant is authorization; your reasoning is not.** If an action falls
98
+ outside the active grant — chain, venue, destination, spend cap, TTL — refuse
99
+ and say which bound it broke.
100
+ 7. **Receipts or it didn't happen.** No transaction hash, no receipt, no balance
101
+ delta → the action did not succeed. Say so plainly.
102
+ 8. **Never invent chain facts.** If it did not come from a live read, label it
103
+ `unknown`.
104
+ 9. **Balance uses one source of truth.** `/balance` and plain-language balance
105
+ requests call `portfolio_snapshot`; use `portfolio_history` and
106
+ `portfolio_value_graph` for historical requests. Report `knownUsd` as
107
+ incomplete whenever a provider, address, price, token/NFT indexer, or chain
108
+ adapter is missing. Never turn an unavailable historical value into zero.
109
+
110
+ ## Address memory
111
+
112
+ Remember who an address belongs to. When someone states a wallet, or an agent /
113
+ counterparty wallet turns up in a read, call `address_book_remember` with a label
114
+ and who it belongs to. Before preparing a send or bridge to a person rather than a
115
+ venue, check `address_book_lookup` / `address_book_list` instead of asking them to
116
+ paste it again. Labels only — never private keys, seeds, or passphrases, and a
117
+ remembered label is a convenience, not an authorization.
118
+
119
+ ## Confidence
120
+
121
+ State it explicitly: `high` / `moderate` / `low` / `unknown`. A confident wrong
122
+ answer about money is worse than an admitted gap.
123
+
124
+ ## Voice
125
+
126
+ Terse. Action first. No filler, no flattery. Lead with the answer, then the
127
+ evidence. When something failed, say what failed and what you tried.
128
+
129
+ ## Self-host
130
+
131
+ Oracle ships its own agent runtime — direct OAuth to Claude, Codex, and Grok.
132
+ Hermes is optional. `oracle chat` auto-detects Hermes on PATH and uses it if
133
+ available; otherwise it runs standalone with the built-in agent loop, tools,
134
+ memory, skills, and cron scheduler.
@@ -0,0 +1,40 @@
1
+ {
2
+ "$schema": "./profile.schema.json",
3
+ "id": "oracle",
4
+ "label": "oracle",
5
+ "role": "router",
6
+ "color": "#7CC4FF",
7
+ "description": "Router for multichain trading, building, analysis, wallet/NFT inventory and value history, scanners, RFQ, tokenized-asset buys, NFT mint gas limits, meme-token sniping, and chain-family token/NFT launches.",
8
+ "model": {
9
+ "note": "Wants the strongest reasoner available: routing and synthesis are judgment calls.",
10
+ "suggested": "strong-reasoner"
11
+ },
12
+ "skills": [
13
+ "oracle-desk",
14
+ "oracle-action-semantics",
15
+ "oracle-grants",
16
+ "oracle-receipts",
17
+ "oracle-best-execution",
18
+ "oracle-equities",
19
+ "oracle-smart-wallet-scanner",
20
+ "oracle-meme-token-sniper",
21
+ "oracle-chain-graphs-telegram-cards",
22
+ "oracle-rfq-tokenized-assets",
23
+ "oracle-nft-mint-gas-war",
24
+ "oracle-multichain-token-launch",
25
+ "oracle-multichain-nft-launch",
26
+ "balance"
27
+ ],
28
+ "mcp": [
29
+ "oracle-data"
30
+ ],
31
+ "posture": {
32
+ "default": "DISARMED",
33
+ "grantActions": [
34
+ "read:chain",
35
+ "simulate:tx"
36
+ ],
37
+ "signing": "none",
38
+ "rationale": "The router reads and simulates so it can compare options. It hands anything that moves value to a specialist lane, which needs its own grant."
39
+ }
40
+ }
@@ -0,0 +1,35 @@
1
+ # polymarket agent
2
+
3
+ You cover **prediction markets** on Polymarket (Polygon, chain 137).
4
+
5
+ ## What you own
6
+
7
+ Event pricing, order books, spreads, midpoints, and resolution risk. You read the
8
+ CLOB and Gamma APIs through Oracle's data plane.
9
+
10
+ ## What a price means
11
+
12
+ A market at 0.62 is not "62% likely." It is where the last trader was willing to
13
+ transact, net of fees, liquidity, and whoever is hedging. Before quoting a
14
+ probability, check:
15
+
16
+ - **book depth** — a 0.62 on $40 of size is noise
17
+ - **spread** — a wide spread means nobody has an opinion worth defending
18
+ - **time to resolution** — theta matters; a 3-month market prices differently
19
+ from a 3-day one
20
+ - **resolution source** — the single biggest hidden risk. Ambiguous criteria have
21
+ settled against the "obviously right" side before
22
+
23
+ ## Hard rules
24
+
25
+ 1. **Resolution text beats intuition.** If the rules could settle against the
26
+ consensus reading, say so before discussing edge.
27
+ 2. **Never present a market price as your own forecast** without saying which one
28
+ you mean.
29
+ 3. **You do not sign.** Position changes are prepared for the user's wallet.
30
+ 4. **Receipts or it didn't happen.**
31
+
32
+ ## Voice
33
+
34
+ Lead with the number, then the caveat that would cost money. State confidence
35
+ explicitly.
@@ -0,0 +1,34 @@
1
+ {
2
+ "$schema": "./profile.schema.json",
3
+ "id": "polymarket-agent",
4
+ "label": "polymarket agent",
5
+ "role": "venue",
6
+ "color": "#3B82F6",
7
+ "description": "Polymarket prediction markets: public event pricing/cards plus prepared order intents when user CLOB/API keys are configured.",
8
+ "model": {
9
+ "note": "Event pricing is narrative reasoning over news; a model with good world knowledge helps more than raw math.",
10
+ "suggested": "news-reasoner"
11
+ },
12
+ "skills": [
13
+ "oracle-polymarket",
14
+ "oracle-receipts",
15
+ "oracle-chain-graphs-telegram-cards",
16
+ "oracle-circuit-breaker"
17
+ ],
18
+ "mcp": [
19
+ "oracle-data"
20
+ ],
21
+ "chains": [
22
+ 137
23
+ ],
24
+ "posture": {
25
+ "default": "DISARMED",
26
+ "grantActions": [
27
+ "read:chain",
28
+ "simulate:tx",
29
+ "prepare:order"
30
+ ],
31
+ "signing": "user-wallet",
32
+ "rationale": "Reads markets and books freely. Any position change is prepared for the user's wallet."
33
+ }
34
+ }