@oracle-agent/oracle 0.35.34 → 0.35.36

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 (64) hide show
  1. package/README.md +43 -8
  2. package/artifacts/specialist-packs/oracle-full-crypto.json +11 -0
  3. package/dist/address-book.mjs +2 -2
  4. package/dist/agent-sessions.mjs +8 -8
  5. package/dist/assets/profiles/canton-agent/SOUL.md +44 -0
  6. package/dist/assets/profiles/canton-agent/profile.json +30 -0
  7. package/dist/assets/profiles/oracle/SOUL.md +1 -0
  8. package/dist/assets/skills/oracle-canton/SKILL.md +49 -0
  9. package/dist/assets/skills/oracle-desk-product/SKILL.md +1 -1
  10. package/dist/bin/desk-server.mjs +35 -35
  11. package/dist/bin/oracle-data-mcp.mjs +17 -17
  12. package/dist/bin/oracle-gateway.mjs +14 -14
  13. package/dist/bin/oracle-launch-radar-shadow.mjs +4 -4
  14. package/dist/bin/oracle-mev-arb-shadow.mjs +4 -4
  15. package/dist/bin/oracle-mev-shadow.mjs +4 -4
  16. package/dist/bin/oracle-public-server.mjs +4 -4
  17. package/dist/bin/oracle-route.mjs +8 -8
  18. package/dist/bin/oracle-scan.mjs +10 -10
  19. package/dist/bin/oracle.mjs +8 -6
  20. package/dist/cli/commands/agent-session.mjs +10 -10
  21. package/dist/cli/commands/airdrop.mjs +16 -0
  22. package/dist/cli/commands/chain.mjs +1 -1
  23. package/dist/cli/commands/chat.mjs +215 -204
  24. package/dist/cli/commands/doctor.mjs +5 -5
  25. package/dist/cli/commands/eval.mjs +151 -141
  26. package/dist/cli/commands/extension-policy.mjs +3 -3
  27. package/dist/cli/commands/farm.mjs +22 -22
  28. package/dist/cli/commands/mint.mjs +22 -0
  29. package/dist/cli/commands/model.mjs +219 -208
  30. package/dist/cli/commands/plugins.mjs +42 -39
  31. package/dist/cli/commands/quickstart.mjs +6 -6
  32. package/dist/cli/commands/session-vault.mjs +1 -1
  33. package/dist/cli/commands/sign.mjs +12 -12
  34. package/dist/cli/commands/signer.mjs +25 -23
  35. package/dist/cli/commands/snipe.mjs +6 -6
  36. package/dist/cli/commands/swap.mjs +12 -12
  37. package/dist/cli/commands/venues.mjs +2 -2
  38. package/dist/control/receipt-lineage.mjs +1 -0
  39. package/dist/data/desk-data.mjs +33 -33
  40. package/dist/data/providers/farming.mjs +2 -2
  41. package/dist/data/providers/lp-destination-discovery.mjs +4 -4
  42. package/dist/index.mjs +50 -49
  43. package/dist/launch-radar/index.mjs +4 -4
  44. package/dist/local-signer/anvil-attestation-worker.mjs +1 -1
  45. package/dist/local-signer/index.mjs +3 -3
  46. package/dist/local-signer/runtime.mjs +22 -20
  47. package/dist/router/index.mjs +3 -3
  48. package/dist/router/prepare-bridge.mjs +1 -1
  49. package/dist/scanner/index.mjs +4 -4
  50. package/dist/task.mjs +2 -2
  51. package/dist/teams/index.mjs +3 -1
  52. package/dist/tui/standalone-client.mjs +85 -75
  53. package/package.json +3 -2
  54. package/public/eval-report.json +6 -6
  55. package/public/oracle-splash/assets/desktop-app.jpg +0 -0
  56. package/public/oracle-splash/assets/hero/agent-session-poster.jpg +0 -0
  57. package/public/oracle-splash/assets/hero/agent-session.mp4 +0 -0
  58. package/public/oracle-splash/assets/hero/agent-session.webm +0 -0
  59. package/public/oracle-splash/assets/oracle-cli-v03535-poster.jpg +0 -0
  60. package/public/oracle-splash/assets/oracle-cli-v03535.gif +0 -0
  61. package/public/oracle-splash/assets/protocol-build-time.jpg +0 -0
  62. package/public/oracle-splash/downloads/index.html +2 -2
  63. package/public/oracle-splash/index.html +132 -54
  64. package/server.json +2 -2
package/README.md CHANGED
@@ -247,11 +247,13 @@ be checked per route. This is not a claim of universal signing, broadcasting,
247
247
  or end-to-end execution readiness.
248
248
 
249
249
  **11 EVM chains** built in: Ethereum, Optimism, BNB, Polygon, Stable, HyperEVM,
250
- Abstract, Robinhood Chain, Base, Arbitrum, Avalanche. Plus Solana and Bitcoin L1
251
- lanes. Solana covers Jupiter quote/prepare, SPL account research, live
250
+ Abstract, Robinhood Chain, Base, Arbitrum, Avalanche. Plus Solana, Bitcoin L1,
251
+ and a read-only Canton Coin (CC) lane. Solana covers Jupiter quote/prepare, SPL account research, live
252
252
  simulation of the prepared swap, and Magic Eden NFT reads with unsigned
253
253
  buy/list/mint tickets. Bitcoin covers Esplora fee/UTXO reads, Ordinals/runes
254
- research, Satflow PSBT intents, and inscription PSBT preparation. Hyperliquid
254
+ research, Satflow PSBT intents, and inscription PSBT preparation. Canton is not
255
+ EVM: Oracle reads Canton Coin via Scan and explains onboarding; quote/prepare stay
256
+ fail-closed. Hyperliquid
255
257
  adds HyperCore HYPE staking: validator reads plus EIP-712 stake, delegate,
256
258
  undelegate, and unstake preparation. User wallets sign.
257
259
 
@@ -293,15 +295,15 @@ known answer. This matters: the canonical QuoterV2 address also has bytecode on
293
295
  Base, but does not price that chain's pairs. A codesize check would have
294
296
  allowlisted the wrong contract.
295
297
 
296
- **127 provider modules** and **548 operations** in the read/quote catalog, covering **220 unique
297
- protocols/venues** across EVM, Solana, and Bitcoin (115 EVM + cross-chain, 98
298
+ **134 provider modules** and **594 operations** in the read/quote catalog, covering **221 unique
299
+ protocols/venues** across EVM, Solana, Bitcoin, and Canton (115 EVM + cross-chain, 98
298
300
  Solana venues backed by 101 verified Jupiter program IDs, 6 Bitcoin surfaces).
299
301
  One module can cover many protocols: the Jupiter module alone routes 98 Solana
300
302
  venues, so provider-module count and protocol count are different numbers.
301
303
 
302
304
  | Class | Providers |
303
305
  |---|---|
304
- | Chain / explorer | EVM JSON-RPC, Blockscout, Solana RPC, Bitcoin Esplora |
306
+ | Chain / explorer | EVM JSON-RPC, Blockscout, Solana RPC, Bitcoin Esplora, Canton Scan (CC) |
305
307
  | Market data | DexScreener, GeckoTerminal, DeFiLlama |
306
308
  | DEX / aggregator | Uniswap V3/V4, Aerodrome, Curve, Balancer, LI.FI, ParaSwap, Odos, 0x, 1inch, HyperEVM DEXes |
307
309
  | Solana | Jupiter (98 venue labels, 101 verified program IDs) |
@@ -484,7 +486,7 @@ model reviewing its own work would have shipped three of them.
484
486
 
485
487
  ## Agent profiles
486
488
 
487
- Oracle ships an installable 8-lane mesh for Hermes:
489
+ Oracle ships an installable 9-lane mesh for Hermes:
488
490
 
489
491
  ```bash
490
492
  oracle-init # dry run -- shows exactly what it would do
@@ -503,7 +505,7 @@ loopback-only public local signer after independent local confirmation and
503
505
  sealed-policy checks. Private Administrator execution remains separate.
504
506
 
505
507
  Lanes: `oracle` (router), `polymarket-agent`, `hyperliquid-agent`,
506
- `robinhood-agent`, `solana-agent`, `bitcoin-agent`, `stable-agent`,
508
+ `robinhood-agent`, `solana-agent`, `bitcoin-agent`, `canton-agent`, `stable-agent`,
507
509
  `protocol-builder`, plus `_template` for your own. Details in
508
510
  [`docs/profiles.md`](docs/profiles.md).
509
511
 
@@ -523,6 +525,39 @@ skills, sessions, and a separate model choice per specialist — is profile
523
525
  machinery from a multi-profile harness such as Hermes. Use Oracle from any
524
526
  agent, or on its own; add a profile mesh only if you want that topology.
525
527
 
528
+ ## Teams
529
+
530
+ A team is a compiled, hash-pinned pipeline of specialist agents that turns public
531
+ evidence into an operator handoff. It never signs and never broadcasts.
532
+
533
+ ```js
534
+ import { TEAM_TEMPLATES, compileTeamDefinition } from "@oracle-agent/oracle";
535
+
536
+ const compiled = compileTeamDefinition(TEAM_TEMPLATES[0], { nowMs: Date.now() });
537
+ compiled.team.agents.map((a) => a.role);
538
+ // scanner -> sentiment -> strategy -> risk -> executor
539
+ ```
540
+
541
+ Seven templates ship in the box (`hyperliquid-alpha`, `perp-market-breadth`,
542
+ `perp-technical-strategy`, `basket-relative-value`, `wallet-watch`,
543
+ `evm-launch-radar`, `nft-mint-guard`) across six modes: `draft`, `shadow`,
544
+ `confirm`, `armed`, `autonomous`, `halted`.
545
+
546
+ The shape is enforced at compile time. A definition is refused if the executor is
547
+ not the terminal agent, if any non-executor holds executor tools, if the policy
548
+ omits wallet confirmation or a kill switch, if the chain allowlist is unbounded,
549
+ if the policy has already expired, or if `autonomous` is requested without an
550
+ explicit opt-in. Secret-like values and DAG cycles are rejected outright.
551
+
552
+ Compilation is deterministic: key insertion order does not change the `teamHash`,
553
+ so the same team is the same identity across machines. Every handoff reports
554
+ `executionAllowed: false`, `backendSigner: false`, `signingReady: false`, and
555
+ `broadcastReady: false`.
556
+
557
+ Teams are a library surface. They run in the **Oracle desktop app** — the CLI
558
+ stays a single-agent shell. Drive them from the desktop, your own harness, or a
559
+ service. Full reference in [`docs/teams.md`](docs/teams.md).
560
+
526
561
  ## Best-execution routing
527
562
 
528
563
  The highest quote is not the cheapest swap. Oracle ranks on **net received after
@@ -193,6 +193,16 @@
193
193
  "label": "bitcoin agent",
194
194
  "description": "Bitcoin L1, Ordinals/runes research, Satflow PSBTs, and inscription preparation."
195
195
  },
196
+ {
197
+ "id": "canton-agent",
198
+ "skills": [
199
+ "oracle-canton",
200
+ "oracle-receipts",
201
+ "oracle-circuit-breaker"
202
+ ],
203
+ "label": "canton agent",
204
+ "description": "Canton Network read-only Canton Coin (CC) Scan reads and onboarding. Not EVM."
205
+ },
196
206
  {
197
207
  "id": "stable-agent",
198
208
  "skills": [
@@ -264,6 +274,7 @@
264
274
  "analyzer",
265
275
  "solana-jupiter",
266
276
  "bitcoin-inscriptions",
277
+ "canton-cc-reads",
267
278
  "nft-project-launch",
268
279
  "gacha-launch",
269
280
  "dex-launch",
@@ -1,2 +1,2 @@
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};
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 n=r?process.env[r]:void 0;return n!=null&&String(n).trim()!==""?n: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 v(){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 C(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(v(),"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(C)}}catch{return g()}}function _(e){let r=v();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(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 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(),n=d(),i=n.entries.findIndex(s=>s.address===r&&s.label===t),u=C({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 w=s=>s==="agent"?0:s==="owner"?1:2;n.entries.sort((s,f)=>w(s.role)-w(f.role)||s.label.localeCompare(f.label)||s.address.localeCompare(f.address));let O=_(n);return{ok:!0,entry:u,count:O.entries.length}}function Y(e,r=null){let t=h(e),o=d(),n=o.entries.length;return o.entries=o.entries.filter(i=>i.address!==t?!0:r==null?!1:i.label!==String(r)),_(o),{ok:!0,removed:n-o.entries.length,count:o.entries.length}}export{v as addressBookPath,Y as forgetAddress,G as listAddresses,q as lookupAddress,d as readAddressBook,T as rememberAddress};