@oracle-agent/oracle 0.35.19 → 0.35.21
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.
- package/dist/assets/skills/oracle-desk-product/SKILL.md +23 -17
- package/dist/assets/skills/oracle-mcp-install/SKILL.md +17 -22
- package/dist/assets/skills/protocol-api-key-integration/SKILL.md +14 -11
- package/dist/assets/skills/self-custodial-onchain-execution/SKILL.md +14 -13
- package/dist/assets/skills/trade-loop-circuit-breaker/SKILL.md +1 -1
- package/dist/bin/desk-server.mjs +30 -30
- package/dist/bin/oracle-data-mcp.mjs +17 -17
- package/dist/bin/oracle-gateway.mjs +3 -3
- package/dist/bin/oracle-public-server.mjs +5 -5
- package/dist/bin/oracle-telegram-mcp.mjs +5 -5
- package/dist/cli/commands/chat.mjs +200 -200
- package/dist/cli/commands/doctor.mjs +7 -7
- package/dist/cli/commands/eval.mjs +113 -113
- package/dist/cli/commands/extension-policy.mjs +1 -1
- package/dist/cli/commands/governance-prepare.mjs +5 -0
- package/dist/cli/commands/model.mjs +204 -204
- package/dist/cli/commands/portfolio-risk.mjs +4 -0
- package/dist/cli/commands/position-health.mjs +4 -0
- package/dist/cli/commands/safety-intelligence.mjs +4 -0
- package/dist/cli/commands/swap.mjs +12 -12
- package/dist/cli/commands/tax-lots.mjs +4 -0
- package/dist/cli/commands/telegram.mjs +6 -6
- package/dist/data/desk-data.mjs +26 -26
- package/dist/index.mjs +40 -40
- package/package.json +1 -1
- package/public/eval-report.json +22 -8
- package/public/oracle-splash/index.html +44 -23
- package/server.json +2 -2
- package/dist/assets/skills/oracle-best-execution.md +0 -27
- package/dist/assets/skills/oracle-desk.md +0 -27
- package/dist/assets/skills/oracle-receipts.md +0 -29
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
var vr=Object.defineProperty;var w=(t,e,r)=>()=>{if(r)throw r[0];try{return t&&(e=t(t=0)),e}catch(n){throw r=[n],n}};var j=(t,e)=>{for(var r in e)vr(t,r,{get:e[r],enumerable:!0})};var We={};j(We,{A2ABus:()=>fe,normalizeName:()=>Q});function Q(t){return String(t||"").trim().toLowerCase().replace(/^@/,"")}var fe,ze=w(()=>{fe=class{constructor({maxHops:e=4,historyCap:r=200}={}){this.maxHops=e,this.historyCap=r,this.agents=new Map,this.history=[],this.seq=0}register(e,{role:r="",chains:n=[],handler:o}={}){let a=Q(e);if(!a)throw new Error("a2a: agent name required");if(this.agents.has(a))throw new Error(`a2a: agent '${a}' already registered`);if(typeof o!="function")throw new Error(`a2a: agent '${a}' needs a handler`);return this.agents.set(a,{name:a,role:String(r),chains:n.map(String),handler:o}),this.agents.get(a)}unregister(e){this.agents.delete(Q(e))}roster(){return[...this.agents.values()].map(({name:e,role:r,chains:n})=>({name:e,role:r,chains:n}))}async send({from:e,to:r,text:n,kind:o="consult",hops:a=0}={}){let i=Q(e),l=Q(r);if(!i||!this.agents.has(i))return{ok:!1,error:`a2a: unknown sender '${e}'`};if(!l||!this.agents.has(l))return{ok:!1,error:`a2a: unknown recipient '${r}' (roster: ${[...this.agents.keys()].join(", ")||"empty"})`};if(l===i)return{ok:!1,error:"a2a: self-send refused"};let c=String(n||"").trim().slice(0,8e3);if(!c)return{ok:!1,error:"a2a: empty message"};let s=Number(a)+1;if(s>this.maxHops)return this.record({from:i,to:l,kind:o,dropped:"hop-limit"}),{ok:!1,error:`a2a: hop limit ${this.maxHops} reached \u2014 dropped`};let d={id:`a2a-${Date.now()}-${++this.seq}`,from:i,to:l,kind:String(o),text:c,hops:s,ts:new Date().toISOString()};this.record(d);try{let p=await this.agents.get(l).handler(d);return p&&this.record({id:`${d.id}-reply`,from:l,to:i,kind:"reply",text:String(p).slice(0,8e3),hops:s,ts:new Date().toISOString()}),{ok:!0,reply:p||null,id:d.id}}catch(p){return{ok:!1,error:`a2a: '${l}' handler failed: ${p.message}`}}}record(e){this.history.push(e),this.history.length>this.historyCap&&this.history.splice(0,this.history.length-this.historyCap)}recent(e=20){return this.history.slice(-e)}}});import Z from"node:fs";import Ar from"node:os";import F from"node:path";import{fileURLToPath as Cr}from"node:url";function he(){return process.env.ORACLE_FAKE_HOME||Ar.homedir()}function _r(){return process.env.ORACLE_PUBLIC_DESKTOP==="1"}function $(){return _r()?process.env.ORACLE_CONFIG_DIR||F.join(he(),".config","oracle"):F.join(he(),".config","oracle")}function Er(){return F.join($(),"desk.json")}function Or(){return F.join($(),"env")}function B({force:t=!1}={}){if(B._done&&!t)return B._result||null;B._done=!0;let e={},r=(o,a)=>{if(a==null)return;let i=String(a).trim();i&&(process.env[o]!=null&&String(process.env[o]).trim()!==""||(process.env[o]=i,e[o]=i))};try{let o=Or();if(Z.existsSync(o))for(let a of Z.readFileSync(o,"utf8").split(/\r?\n/)){let i=a.match(/^\s*([A-Z0-9_]+)\s*=\s*(.*?)\s*$/);if(!i||i[2].startsWith("#"))continue;let l=i[2];(l.startsWith('"')&&l.endsWith('"')||l.startsWith("'")&&l.endsWith("'"))&&(l=l.slice(1,-1)),r(i[1],l)}}catch{}try{let o=Er();if(Z.existsSync(o)){let a=JSON.parse(Z.readFileSync(o,"utf8"));a&&typeof a=="object"&&(r("ORACLE_DESK_URL",a.deskUrl||a.dataUrl||a.url),r("ORACLE_DATA_URL",a.dataUrl||a.deskUrl||a.url),r("ORACLE_API_URL",a.apiUrl||a.dataUrl||a.deskUrl),r("ORACLE_PUBLIC_URL",a.publicUrl||a.deskUrl||a.dataUrl),r("ORACLE_EXEC_URL",a.execUrl),r("MAD_DESK_URL",a.deskUrl||a.dataUrl))}}catch{}let n=process.env.ORACLE_DESK_URL||process.env.ORACLE_DATA_URL||"";return n&&(r("ORACLE_DESK_URL",n),r("ORACLE_DATA_URL",n),r("ORACLE_API_URL",n),r("ORACLE_PUBLIC_URL",n),r("MAD_DESK_URL",n)),B._result=Object.keys(e).length?e:null,B._result}function ae(t){return Z.mkdirSync(t,{recursive:!0}),t}var $r,Go,ie=w(()=>{$r=F.dirname(Cr(import.meta.url)),Go=F.resolve($r,"../..");try{B()}catch{}});function se(t){return String(t||"").trim()||void 0}function Nr(t,{required:e=!1}={}){let r=se(t)?.toLowerCase();if(!r){if(e)throw new Error("model provider is required");return}if(!Rr.has(r))throw new Error(`unsupported provider: ${r}`);return r}function Lr(t,{required:e=!1}={}){let r=se(t);if(!r){if(e)throw new Error("model is required");return}if(r.includes("..")||r.startsWith("/")||!/^[a-zA-Z0-9._:/-]{1,200}$/.test(r))throw new Error("invalid model id");return r}function Ir(t){let e=se(t);if(!e||e.length>2048)throw new Error("invalid custom base URL");let r;try{r=new URL(e)}catch{throw new Error("invalid custom base URL")}let n=r.hostname.toLowerCase().replace(/^\[|\]$/g,""),o=n==="localhost"||n==="127.0.0.1"||n==="::1";if(r.protocol!=="https:"&&!(r.protocol==="http:"&&o)||r.username||r.password||r.search||r.hash)throw new Error("custom base URL must use HTTPS or loopback HTTP without credentials, query, or fragment");return r.toString().replace(/\/+$/,"")}function Ve({provider:t,model:e,baseUrl:r}={},{requireModel:n=!1}={}){let o=Nr(t),a=Lr(e,{required:n});if(o==="custom")return{provider:o,...a?{model:a}:{},baseUrl:Ir(r)};if(se(r))throw new Error("baseUrl is only supported for the custom provider");return{...o?{provider:o}:{},...a?{model:a}:{}}}var Rr,Ke=w(()=>{Rr=new Set(["openrouter","openai","anthropic","xai","deepseek","gemini","kimi","mistral","nous","qwen","glm","local","ollama","custom","anthropic-oauth","openai-codex","xai-oauth"])});import G from"node:fs";import ge from"node:path";function Ye(){return ge.join($(),"model.json")}function H(t){return String(t||"").trim()||void 0}function Je(t={}){let e=H(t.backend)?.toLowerCase()||"auto",r=Ve({provider:t.provider,model:t.model,baseUrl:t.baseUrl},{requireModel:e==="standalone"}),n=H(t.apiKeyEnv),o=Number.parseInt(String(t.contextLength||""),10),a=H(t.reasoningEffort),i=H(t.computeHost||t.remoteHost),l=H(t.computeUser||t.remoteUser),c=H(t.computePath||t.remotePath);if(!Tr.has(e))throw new Error(`unsupported backend: ${e}`);if(process.env.ORACLE_PUBLIC_DESKTOP==="1"&&["remote","arch"].includes(e))throw new Error("remote compute backends are disabled in the public desktop");if(n&&!/^[A-Z][A-Z0-9_]*$/.test(n))throw new Error("api key env must be an uppercase environment variable name");if(e==="remote"&&!i)throw new Error("remote backend requires computeHost");return{backend:e,...r,...n?{apiKeyEnv:n}:{},...Number.isFinite(o)&&o>0?{contextLength:o}:{},...a?{reasoningEffort:a}:{},...i?{computeHost:i}:{},...l?{computeUser:l}:{},...c?{computePath:c}:{}}}function q(){let t=Ye();if(!G.existsSync(t))return null;try{return Je(JSON.parse(G.readFileSync(t,"utf8")))}catch{return null}}function ye(t){let e=Je(t),r=Ye();ae(ge.dirname(r)),process.platform!=="win32"&&G.chmodSync(ge.dirname(r),448);let n=`${r}.${process.pid}.tmp`;return G.writeFileSync(n,`${JSON.stringify(e,null,2)}
|
|
3
|
-
`,{mode:384}),G.renameSync(n,r),process.platform!=="win32"&&G.chmodSync(r,384),e}var Tr,Xe=w(()=>{ie();Ke();Tr=new Set(["auto","standalone","hermes","remote","arch"])});import{existsSync as Pr,readFileSync as Mr}from"node:fs";import{request as Ur}from"node:http";import Dr from"node:path";function Br(t=process.env){let e=String(t.ORACLE_SIGNER_URL||jr).replace(/\/$/,""),r;try{r=new URL(e)}catch{return null}return r.hostname!=="127.0.0.1"&&r.hostname!=="localhost"&&r.hostname!=="::1"?null:r.origin}function Fr(t=process.env){if(t.ORACLE_SIGNER_TOKEN)return String(t.ORACLE_SIGNER_TOKEN);let e=Dr.join($(),"signer","signer-token");return Pr(e)?Mr(e,"utf8").trim():null}function T(t,{method:e="GET",body:r=null,env:n=process.env,timeoutMs:o=4e3}={}){let a=Br(n),i=Fr(n);return!a||!i?Promise.resolve({ok:!1,error:"local signer is not running"}):new Promise(l=>{let c=new URL(t,a),s=r?Buffer.from(JSON.stringify(r)):null,d=Ur({hostname:c.hostname,port:c.port||80,path:c.pathname,method:e,timeout:o,headers:{authorization:`Bearer ${i}`,origin:a,...s?{"content-type":"application/json","content-length":s.length}:{}}},p=>{let m=[];p.on("data",h=>m.push(h)),p.on("end",()=>{let h=Buffer.concat(m).toString("utf8"),g={};try{g=h?JSON.parse(h):{}}catch{g={error:"signer refused"}}l({httpStatus:p.statusCode,...g})})});d.on("timeout",()=>{d.destroy(),l({ok:!1,error:"local signer timed out"})}),d.on("error",()=>l({ok:!1,error:"local signer is not running"})),s&&d.write(s),d.end()})}var jr,ce=w(()=>{ie();jr="http://127.0.0.1:9462"});function Qe(t){return Gr.get(Number(t))||null}var Hr,Gr,Ze=w(()=>{Hr={robinhood:{chainId:4663,name:"Robinhood Chain",rpcEnv:["RH_CHAIN_RPC"],evm:!0},ethereum:{chainId:1,name:"Ethereum",rpcEnv:["ETH_RPC_URL","ETHEREUM_RPC_URL","MAINNET_RPC_URL"],evm:!0},polygon:{chainId:137,name:"Polygon",rpcEnv:["POLYGON_RPC_URL","POLYGON_RPC"],evm:!0},arbitrum:{chainId:42161,name:"Arbitrum One",rpcEnv:["ARBITRUM_RPC_URL","ARB_RPC_URL"],evm:!0},base:{chainId:8453,name:"Base",rpcEnv:["BASE_RPC_URL"],evm:!0},hyperevm:{chainId:999,name:"HyperEVM",rpcEnv:["HYPEREVM_RPC_URL","HYPER_EVM_RPC"],evm:!0},bsc:{chainId:56,name:"BNB Smart Chain",rpcEnv:["BSC_RPC_URL","BNB_RPC_URL"],evm:!0},avalanche:{chainId:43114,name:"Avalanche C-Chain",rpcEnv:["AVALANCHE_RPC_URL","AVAX_RPC_URL"],evm:!0},optimism:{chainId:10,name:"OP Mainnet",rpcEnv:["OPTIMISM_RPC_URL","OP_RPC_URL"],evm:!0},abstract:{chainId:2741,name:"Abstract",rpcEnv:["ABSTRACT_RPC_URL","ABS_RPC_URL"],evm:!0},stable:{chainId:988,name:"Stable Mainnet",rpcEnv:["STABLE_RPC_URL","STABLE_RPC"],evm:!0}},Gr=new Map(Object.values(Hr).map(t=>[t.chainId,t]))});function Wr(t){let e=String(t||"").trim();if(!e||e.includes("ts.net")||!/^https:\/\//i.test(e))return null;try{return new URL(e)}catch{return null}}function et(t,{coin:e,side:r,sizeUsd:n,leverage:o,venue:a,confirm:i,user:l}={}){let c=Wr(t);if(!c)return null;if(e&&qr.test(String(e).toUpperCase())&&c.searchParams.set("coin",String(e).toUpperCase()),(r==="long"||r==="short")&&c.searchParams.set("side",r),Number.isFinite(Number(n))&&Number(n)>=1&&c.searchParams.set("size",String(Math.min(1e5,Math.round(Number(n))))),Number.isInteger(Number(o))&&Number(o)>=1&&c.searchParams.set("lev",String(Math.min(50,Number(o)))),a){let s=String(a).toLowerCase()==="hl"?"hyperliquid":String(a).toLowerCase();c.searchParams.set("venue",s)}else c.searchParams.get("venue")||c.searchParams.set("venue","hyperliquid");return c.searchParams.set("view","perps"),c.searchParams.set("build","1"),i&&/^[0-9a-f]{32}$/i.test(String(i))&&c.searchParams.set("confirm",String(i).toLowerCase()),l&&/^0x[0-9a-fA-F]{40}$/.test(String(l))&&c.searchParams.set("user",String(l).toLowerCase()),c.toString()}var qr,we=w(()=>{qr=/^[A-Z0-9][A-Z0-9._-]{0,11}$/});var ia,sa,tt=w(()=>{we();ia=Object.freeze([100,50,25]),sa=Object.freeze([100,50,25,10])});function u(t){return S(t)?String(t).replace(zr,e=>`\\${e}`):f}function S(t){return t==null?!1:typeof t=="number"?Number.isFinite(t):typeof t=="string"?t.trim()!=="":!0}function A(t){if(!S(t))return f;let e=String(t).replace(/`/g,"");return e===""?f:`\`${e}\``}function P(t,{decimals:e=2}={}){if(!S(t))return f;let r=Number(t);return Number.isFinite(r)?r.toLocaleString("en-US",{minimumFractionDigits:0,maximumFractionDigits:e}):f}function b(t,{decimals:e=2}={}){let r=P(t,{decimals:e});return r===f?f:`${r} USD`}function ke(t,{decimals:e=2}={}){let r=P(t,{decimals:e});return r===f?f:`${r}%`}function le(t){let e=P(t,{decimals:0});return e===f?f:`${e} bps`}function M(t,e){if(!S(t))return f;let r=Number(e);if(!Number.isInteger(r)||r<0||r>77)return f;let n;try{n=BigInt(typeof t=="string"?t.trim():t)}catch{return f}let o=n<0n,a=o?-n:n,i=10n**BigInt(r),l=(a/i).toString(),c=(a%i).toString().padStart(r,"0").replace(/0+$/,"");return`${o?"-":""}${l}${c?`.${c}`:""}`}function Se(t){if(typeof t=="number"&&Number.isFinite(t))return t<0||t>1?f:t>=.75?"HIGH":t>=.4?"MEDIUM":"LOW";if(typeof t=="string"){let e=t.trim().toUpperCase();if(e==="HIGH"||e==="MEDIUM"||e==="LOW")return e}return f}function R(t={}){let e=t.chainId;if(!S(e)||!Number.isFinite(Number(e)))return S(t.chain)?u(t.chain):f;let n=Qe(e)?.name||(S(t.chain)?String(t.chain):f);return`${u(n)} (chainId ${Number(e)})`}function rt(t={}){return u(t.venue??t.dex??t.pool?.venue)}function Vr(t){return t==null?"NONE (text card only)":typeof t=="string"?t.trim()?A(t):"NONE (text card only)":t.error||t.ok===!1||t.available===!1?`UNAVAILABLE${S(t.error)?` \u2014 ${u(t.error)}`:""} (text card stands)`:S(t.url)?A(t.url):"NONE (text card only)"}function U(t={},{now:e=Date.now()}={}){let r=t.grant??t.session??null;if(!r||typeof r!="object")return{allowed:!1,reason:"no local grant/session",actions:[]};if(r.local===!1)return{allowed:!1,reason:"grant is not local",actions:[]};if(r.revoked===!0)return{allowed:!1,reason:"grant revoked",actions:[]};let n=r.expiresAt??r.expiry;if(S(n)){let a=typeof n=="number"?n:Date.parse(n);if(!Number.isFinite(a))return{allowed:!1,reason:"grant expiry unreadable",actions:[]};if(a<=e)return{allowed:!1,reason:"grant expired",actions:[]}}return{allowed:!0,reason:"valid local grant",actions:Array.isArray(r.actions)&&r.actions.length?r.actions.slice():["BUY","SELL"]}}function Kr(t){let e=U(t);return e.allowed?`${e.actions.map(r=>u(r)).join(" / ")} (${u(e.reason)})`:`prepare-only \u2014 ${u(e.reason)}`}function _(t,e,r={}){let n=[`*${t}*`];for(let
|
|
4
|
-
`)}function E(t){return["Confidence",
|
|
3
|
+
`,{mode:384}),G.renameSync(n,r),process.platform!=="win32"&&G.chmodSync(r,384),e}var Tr,Xe=w(()=>{ie();Ke();Tr=new Set(["auto","standalone","hermes","remote","arch"])});import{existsSync as Pr,readFileSync as Mr}from"node:fs";import{request as Ur}from"node:http";import Dr from"node:path";function Br(t=process.env){let e=String(t.ORACLE_SIGNER_URL||jr).replace(/\/$/,""),r;try{r=new URL(e)}catch{return null}return r.hostname!=="127.0.0.1"&&r.hostname!=="localhost"&&r.hostname!=="::1"?null:r.origin}function Fr(t=process.env){if(t.ORACLE_SIGNER_TOKEN)return String(t.ORACLE_SIGNER_TOKEN);let e=Dr.join($(),"signer","signer-token");return Pr(e)?Mr(e,"utf8").trim():null}function T(t,{method:e="GET",body:r=null,env:n=process.env,timeoutMs:o=4e3}={}){let a=Br(n),i=Fr(n);return!a||!i?Promise.resolve({ok:!1,error:"local signer is not running"}):new Promise(l=>{let c=new URL(t,a),s=r?Buffer.from(JSON.stringify(r)):null,d=Ur({hostname:c.hostname,port:c.port||80,path:c.pathname,method:e,timeout:o,headers:{authorization:`Bearer ${i}`,origin:a,...s?{"content-type":"application/json","content-length":s.length}:{}}},p=>{let m=[];p.on("data",h=>m.push(h)),p.on("end",()=>{let h=Buffer.concat(m).toString("utf8"),g={};try{g=h?JSON.parse(h):{}}catch{g={error:"signer refused"}}l({httpStatus:p.statusCode,...g})})});d.on("timeout",()=>{d.destroy(),l({ok:!1,error:"local signer timed out"})}),d.on("error",()=>l({ok:!1,error:"local signer is not running"})),s&&d.write(s),d.end()})}var jr,ce=w(()=>{ie();jr="http://127.0.0.1:9462"});function Qe(t){return Gr.get(Number(t))||null}var Hr,Gr,Ze=w(()=>{Hr={robinhood:{chainId:4663,name:"Robinhood Chain",rpcEnv:["RH_CHAIN_RPC"],evm:!0},ethereum:{chainId:1,name:"Ethereum",rpcEnv:["ETH_RPC_URL","ETHEREUM_RPC_URL","MAINNET_RPC_URL"],evm:!0},polygon:{chainId:137,name:"Polygon",rpcEnv:["POLYGON_RPC_URL","POLYGON_RPC"],evm:!0},arbitrum:{chainId:42161,name:"Arbitrum One",rpcEnv:["ARBITRUM_RPC_URL","ARB_RPC_URL"],evm:!0},base:{chainId:8453,name:"Base",rpcEnv:["BASE_RPC_URL"],evm:!0},hyperevm:{chainId:999,name:"HyperEVM",rpcEnv:["HYPEREVM_RPC_URL","HYPER_EVM_RPC"],evm:!0},bsc:{chainId:56,name:"BNB Smart Chain",rpcEnv:["BSC_RPC_URL","BNB_RPC_URL"],evm:!0},avalanche:{chainId:43114,name:"Avalanche C-Chain",rpcEnv:["AVALANCHE_RPC_URL","AVAX_RPC_URL"],evm:!0},optimism:{chainId:10,name:"OP Mainnet",rpcEnv:["OPTIMISM_RPC_URL","OP_RPC_URL"],evm:!0},abstract:{chainId:2741,name:"Abstract",rpcEnv:["ABSTRACT_RPC_URL","ABS_RPC_URL"],evm:!0},stable:{chainId:988,name:"Stable Mainnet",rpcEnv:["STABLE_RPC_URL","STABLE_RPC"],evm:!0}},Gr=new Map(Object.values(Hr).map(t=>[t.chainId,t]))});function Wr(t){let e=String(t||"").trim();if(!e||e.includes("ts.net")||!/^https:\/\//i.test(e))return null;try{return new URL(e)}catch{return null}}function et(t,{coin:e,side:r,sizeUsd:n,leverage:o,venue:a,confirm:i,user:l}={}){let c=Wr(t);if(!c)return null;if(e&&qr.test(String(e).toUpperCase())&&c.searchParams.set("coin",String(e).toUpperCase()),(r==="long"||r==="short")&&c.searchParams.set("side",r),Number.isFinite(Number(n))&&Number(n)>=1&&c.searchParams.set("size",String(Math.min(1e5,Math.round(Number(n))))),Number.isInteger(Number(o))&&Number(o)>=1&&c.searchParams.set("lev",String(Math.min(50,Number(o)))),a){let s=String(a).toLowerCase()==="hl"?"hyperliquid":String(a).toLowerCase();c.searchParams.set("venue",s)}else c.searchParams.get("venue")||c.searchParams.set("venue","hyperliquid");return c.searchParams.set("view","perps"),c.searchParams.set("build","1"),i&&/^[0-9a-f]{32}$/i.test(String(i))&&c.searchParams.set("confirm",String(i).toLowerCase()),l&&/^0x[0-9a-fA-F]{40}$/.test(String(l))&&c.searchParams.set("user",String(l).toLowerCase()),c.toString()}var qr,we=w(()=>{qr=/^[A-Z0-9][A-Z0-9._-]{0,11}$/});var ia,sa,tt=w(()=>{we();ia=Object.freeze([100,50,25]),sa=Object.freeze([100,50,25,10])});function u(t){return S(t)?String(t).replace(zr,e=>`\\${e}`):f}function S(t){return t==null?!1:typeof t=="number"?Number.isFinite(t):typeof t=="string"?t.trim()!=="":!0}function A(t){if(!S(t))return f;let e=String(t).replace(/`/g,"");return e===""?f:`\`${e}\``}function P(t,{decimals:e=2}={}){if(!S(t))return f;let r=Number(t);return Number.isFinite(r)?r.toLocaleString("en-US",{minimumFractionDigits:0,maximumFractionDigits:e}):f}function b(t,{decimals:e=2}={}){let r=P(t,{decimals:e});return r===f?f:`${r} USD`}function ke(t,{decimals:e=2}={}){let r=P(t,{decimals:e});return r===f?f:`${r}%`}function le(t){let e=P(t,{decimals:0});return e===f?f:`${e} bps`}function M(t,e){if(!S(t))return f;let r=Number(e);if(!Number.isInteger(r)||r<0||r>77)return f;let n;try{n=BigInt(typeof t=="string"?t.trim():t)}catch{return f}let o=n<0n,a=o?-n:n,i=10n**BigInt(r),l=(a/i).toString(),c=(a%i).toString().padStart(r,"0").replace(/0+$/,"");return`${o?"-":""}${l}${c?`.${c}`:""}`}function Se(t){if(typeof t=="number"&&Number.isFinite(t))return t<0||t>1?f:t>=.75?"HIGH":t>=.4?"MEDIUM":"LOW";if(typeof t=="string"){let e=t.trim().toUpperCase();if(e==="HIGH"||e==="MEDIUM"||e==="LOW")return e}return f}function R(t={}){let e=t.chainId;if(!S(e)||!Number.isFinite(Number(e)))return S(t.chain)?u(t.chain):f;let n=Qe(e)?.name||(S(t.chain)?String(t.chain):f);return`${u(n)} (chainId ${Number(e)})`}function rt(t={}){return u(t.venue??t.dex??t.pool?.venue)}function Vr(t){return t==null?"NONE (text card only)":typeof t=="string"?t.trim()?A(t):"NONE (text card only)":t.error||t.ok===!1||t.available===!1?`UNAVAILABLE${S(t.error)?` \u2014 ${u(t.error)}`:""} (text card stands)`:S(t.url)?A(t.url):"NONE (text card only)"}function U(t={},{now:e=Date.now()}={}){let r=t.grant??t.session??null;if(!r||typeof r!="object")return{allowed:!1,reason:"no local grant/session",actions:[]};if(r.local===!1)return{allowed:!1,reason:"grant is not local",actions:[]};if(r.revoked===!0)return{allowed:!1,reason:"grant revoked",actions:[]};let n=r.expiresAt??r.expiry;if(S(n)){let a=typeof n=="number"?n:Date.parse(n);if(!Number.isFinite(a))return{allowed:!1,reason:"grant expiry unreadable",actions:[]};if(a<=e)return{allowed:!1,reason:"grant expired",actions:[]}}return{allowed:!0,reason:"valid local grant",actions:Array.isArray(r.actions)&&r.actions.length?r.actions.slice():["BUY","SELL"]}}function Kr(t){let e=U(t);return e.allowed?`${e.actions.map(r=>u(r)).join(" / ")} (${u(e.reason)})`:`prepare-only \u2014 ${u(e.reason)}`}function _(t,e,r={}){let n=[`*${t}*`];for(let o of e){if(!o)continue;let[a,i]=o;n.push(`${a}: ${i==null||i===""?f:i}`)}return n.push(`Chart: ${Vr(r.chart)}`),n.push(`Actions: ${Kr(r)}`),Array.isArray(r.warnings)&&r.warnings.length&&n.push(`Warnings: ${r.warnings.map(o=>u(o)).join("; ")}`),(S(r.source)||S(r.fetchedAt))&&n.push(`Source: ${u(r.source)} at ${u(r.fetchedAt)}`),n.join(`
|
|
4
|
+
`)}function E(t){let e=Se(t.confidence);return e===f?null:["Confidence",e]}function Yr(t){let e=t.quote;if(!e||typeof e!="object")return[];let r=S(e.decimals)?M(e.amountOutRaw??e.out??e.raw,e.decimals):f;return[["Quote out (raw)",A(e.amountOutRaw??e.out??e.raw)],["Quote out",r===f?f:`${u(r)} ${u(e.symbol??"")}`.trim()]]}function nt(t){let e=t.autoSlippage;if(!e||typeof e!="object")return["Auto-slippage",f];let r=le(e.selectedBps),n=le(e.capBps);return["Auto-slippage",r===f&&n===f?f:`${r} selected, cap ${n}`]}function Jr(t={}){let e=t||{};return _(`ORACLE TOKEN \u2014 ${u(e.symbol??e.token??e.name)}`,[["Chain",R(e)],["Venue",rt(e)],["Name",u(e.name)],["Address",A(e.address??e.mint??e.contract)],["Price",b(e.priceUsd,{decimals:8})],["Market cap",b(e.marketCapUsd)],["Liquidity",b(e.liquidityUsd)],["Volume 24h",b(e.volume24hUsd)],["Change 24h",ke(e.priceChange24h)],["Fee tier",S(e.feeTier)?`${le(Number(e.feeTier)/100)} (${P(e.feeTier,{decimals:0})})`:f],["Age",u(e.age)],...Yr(e),nt(e),E(e)],e)}function Xr(t={}){let e=t||{};return _(`ORACLE LAUNCH \u2014 ${u(e.symbol??e.token??e.name)}`,[["Chain",R(e)],["Venue",rt(e)],["Address",A(e.address??e.mint??e.contract)],["Pool",A(e.pool?.address??e.poolAddress??e.pool)],["Liquidity",b(e.liquidityUsd)],["Route ready",u(e.routeReady)],["Sellable",u(e.sellable)],["Sell sim",u(e.sellSimulation??e.sellSim)],["Smart wallets",u(e.smartWalletOverlap)],["Risk",u(e.risk??e.riskStatus)],["Prepared ticket",u(e.preparedTicket??e.ticketStatus)],nt(e),E(e)],e)}function Qr(t={}){let e=t||{};return _(`ORACLE HIP-3 \u2014 ${u(e.market??e.coin??e.name)}`,[["Venue",`Hyperliquid builder-dex ${u(e.dex)}`],["Market",u(e.market??e.coin)],["Mark",b(e.markPx,{decimals:6})],["Oracle",b(e.oraclePx,{decimals:6})],["Funding",ke(e.funding,{decimals:6})],["Open interest",b(e.openInterestUsd)],["Depth",u(e.depth)],["Liquidation notes",u(e.liquidationNotes??e.riskNotes)],["Account context",u(e.accountContext)],E(e)],e)}function Zr(t={}){let e=t||{};return _(`ORACLE HIP-4 \u2014 ${u(e.event??e.market??e.name)}`,[["Venue",`Hyperliquid HIP-4 ${u(e.dex??"outcome")}`],["Event",u(e.event)],["Outcome",u(e.outcome)],["Market id",A(e.marketId??e.market)],["Bid",b(e.bid,{decimals:6})],["Ask",b(e.ask,{decimals:6})],["Depth",u(e.depth)],["Edge",ke(e.edge)],["Position",u(e.position)],E(e)],e)}function en(t={}){let e=t||{};return _(`ORACLE POLYMARKET \u2014 ${u(e.event??e.market??e.name)}`,[["Venue","Polymarket CLOB"],["Event",u(e.event)],["Market",u(e.market)],["Market id",A(e.marketId??e.conditionId??e.tokenId)],["Yes",b(e.yesPrice,{decimals:4})],["No",b(e.noPrice,{decimals:4})],["Best bid / ask",`${b(e.bestBid,{decimals:4})} / ${b(e.bestAsk,{decimals:4})}`],["Volume",b(e.volumeUsd)],["Resolution risk",u(e.resolutionRisk)],["Order intent",u(e.orderIntent)],E(e)],e)}function tn(t={}){let e=t||{},r=S(e.completedSplits)&&S(e.totalSplits)?`${P(e.completedSplits,{decimals:0})} / ${P(e.totalSplits,{decimals:0})}`:f;return _(`ORACLE TWAP \u2014 ${u(e.pair??e.symbol??e.name)}`,[["Chain",R(e)],["Side",u(e.side??e.direction)],["Amount",`${u(M(e.amountTotal??e.amount,e.decimals??18))} ${u(e.symbol??"")}`.trim()],["Splits",`${P(e.totalSplits,{decimals:0})} over ${u(e.window)}`],["Progress",r],["Avg price",b(e.averagePrice,{decimals:6})],["Next split",u(e.nextSplitAt)],["Slippage cap",le(e.slippageBps)],["Status",u(e.status)],E(e)],e)}function rn(t={}){let e=t||{},r=e.approval??e.revokeCheck??{},n=r.needsRevoke&&r.spender?`revoke.cash \u2014 ${u(r.spender)}`:r.needsRevoke===!1?"revoke.cash \u2014 clean":"revoke.cash \u2014 unchecked";return _(`ORACLE BRIDGE \u2014 ${u(e.pair??e.fromSymbol)} \u2192 ${u(e.toSymbol??"")}`.replace(/→ $/,""),[["Bridging","deBridge \xB7 LI.FI \u2014 best route wins"],["From chain",R({chainId:e.fromChainId,chain:e.fromChain})],["To chain",R({chainId:e.toChainId,chain:e.toChain})],["Amount",`${u(M(e.amount,e.fromDecimals??18))} ${u(e.fromSymbol??"")}`.trim()],["Best route",u(e.bestRoute??e.winner)],["Est. received",`${u(M(e.amountOut,e.toDecimals??18))} ${u(e.toSymbol??"")}`.trim()],["Fee",b(e.feeUsd)],["Est. time",u(e.estimatedTime)],["Revoke check",n],["All providers",u(e.providers?.join(", "))],["Preparable",u(e.preparable)],E(e)],e)}function nn(t){let r=(Array.isArray(t)?t:[]).slice(1,4).map(n=>{let o=u(n.source??n.venue??n.name),a=n.improvementBps==null&&n.deltaBps==null?null:Number(n.improvementBps??n.deltaBps),i=Number.isFinite(a)?`${Math.abs(a).toFixed(0)} bps behind`:"spread UNKNOWN";return`${o} (${i})`});return r.length?r.join("; "):f}function on(t){let e=t.rankedOn??t.swap?.rankedOn??t.best?.rankedOn;return S(e)?u(e):f}function an(t={}){let e=t||{},r=e.swap&&typeof e.swap=="object"?e.swap:e,n=e.bridge&&typeof e.bridge=="object"?e.bridge:null,o=r.best??r.winner??{},a=`${u(e.tokenInSymbol??e.fromSymbol??"IN")} \u2192 ${u(e.tokenOutSymbol??e.toSymbol??"OUT")}`,i=[["Intent",u(e.intent??"swap")],["Chain",R({chainId:e.chainId??r.chainId,chain:e.chain??r.chain})],["Pair",a],["Amount in",`${u(M(e.amountIn??r.amountIn,e.decimalsIn??18))} ${u(e.tokenInSymbol??"")}`.trim()],["Best swap",u(o.source??o.venue??r.bestRoute??e.bestRoute)],["Net out",`${u(M(o.netOut??o.amountOut??r.amountOut,e.decimalsOut??18))} ${u(e.tokenOutSymbol??"")}`.trim()],["Ranked on",on(r)],["Gas accounted",u(o.costAccounted===!0?"yes":o.costAccounted===!1?"no \u2014 gross ranking may flatter this route":null)],["Spread vs next",S(r.improvementBps)?`${u(r.improvementBps)} bps`:f],["Runners-up",nn(r.routes??e.routes)]];if(n){let l=n.best??n.winner??{};i.push(["Best bridge",u(l.source??n.bestRoute??e.bestBridge)],["Bridge out",`${u(M(l.netOut??l.amountOut??n.amountOut,e.bridgeDecimalsOut??e.decimalsOut??18))} ${u(e.bridgeOutSymbol??e.tokenOutSymbol??"")}`.trim()],["Bridge to",R({chainId:n.toChainId??e.toChainId,chain:n.toChain??e.toChain})],["Est. time",u(n.estimatedTime??l.meta?.durationSeconds)])}else i.push(["Best bridge","same-chain \u2014 use Best swap"]);return i.push(["Preparable",u(e.preparable??o.executionReady)],E(e)),_(`ORACLE SWAP \u2014 ${a}`,i,e)}function be(t={}){let e=t||{};return _("ORACLE APPROVE \u2014 local signer",[["Pending id",A(e.id??(typeof e.digest=="string"?e.digest.slice(0,8):null))],["Surface",u(e.surface)],["Action",u(e.action)],["Chain",R({chainId:e.chain??e.chainId,chain:e.chainName})],["To",A(e.to??e.destination)],["Value",S(e.value)?u(e.value):f],["Signer",u(e.armed===!0?"running + armed":e.armed===!1?"running, disarmed":"not running")],E({confidence:e.confidence??(e.armed===!0?"high":"low")})],e)}function xe({platform:t="telegram",id:e,digest:r,hasGrant:n=!1}={}){let o=String(e||(typeof r=="string"?r.slice(0,8):"")||"").trim();return n?o?String(t)==="telegram"?{kind:"inline_keyboard",replyMarkup:{inline_keyboard:[[{text:"Allow",callback_data:`oracle:approve:${o}`},{text:"Deny",callback_data:`oracle:deny:${o}`}]]},cancelHint:"Allow signs with the local signer. Deny drops the pending artifact."}:{kind:"text_menu",text:["1. Allow \u2014 reply /approve "+o,"2. Deny \u2014 reply /deny "+o].join(`
|
|
5
5
|
`),cancelHint:"Cards are not available on this chat. Use /approve or /deny."}:{kind:"text_menu",text:"nothing to approve",cancelHint:""}:String(t)==="telegram"?{kind:"inline_keyboard",replyMarkup:{inline_keyboard:[]},cancelHint:"prepare-only \u2014 no local grant/session"}:{kind:"text_menu",text:"prepare-only \u2014 no local grant/session",cancelHint:""}}var f,pa,zr,ma,ve=w(()=>{Ze();tt();f="UNKNOWN",pa=Object.freeze(["token","launch","hip3","hip4","polymarket","twap","bridge","swap","approve"]),zr=/[_*[\]`]/g;ma=Object.freeze({token:Jr,launch:Xr,hip3:Qr,hip4:Zr,polymarket:en,twap:tn,bridge:rn,swap:an,approve:be})});function Ae(t){let r=String(t||"").trim().match(/^\/(approve|deny|pending)(?:@[\w_]+)?(?:\s+([0-9a-fA-F]{4,64}))?\s*$/i);return r?{verb:r[1].toLowerCase(),id:r[2]?r[2].toLowerCase():null}:null}function Ce(t,{platform:e,grant:r,armed:n}){if(!t.length)return{text:"No pending local-signer artifacts.",buttons:xe({platform:e,hasGrant:!1})};let o=t[0];return{text:t.map(i=>be({...i,armed:n,grant:r,confidence:n?"high":"medium"})).join(`
|
|
6
6
|
|
|
7
7
|
`),buttons:xe({platform:e,id:o.id,digest:o.digest,hasGrant:U({grant:r}).allowed})}}async function $e({platform:t,text:e,grant:r={local:!0},env:n=process.env,ownerProof:o}={}){let a=Ae(e);if(!a)return null;let i=String(t)==="telegram";if(i&&a.verb!=="pending"&&!a.id)return{text:"On Telegram, tap Allow or Deny on the approve card. /approve is only for chats without cards.",buttons:null};if(a.verb==="pending"){let p=await T("/pending",{env:n});if(p.ok===!1||p.error)return{text:`Local signer: ${p.error||"not running"}. Start \`oracle signer\` on this machine first.`,buttons:null};let m=Array.isArray(p.items)?p.items:[],h=Ce(m,{platform:t,grant:r,armed:p.armed===!0});if(i)return h;if(!m.length)return{text:"No pending local-signer artifacts. /approve is only needed when cards are unavailable.",buttons:null};let g=m.map(k=>`\u2022 ${k.id} ${k.surface}/${k.action} to ${k.to||"n/a"}`);return g.push("Cards are not available here. Reply /approve <id> or /deny <id>."),{text:g.join(`
|
|
@@ -11,7 +11,7 @@ Tx: \`${s}\``,buttons:null,executed:!0,hash:s}:{text:`Local signer executed ${d}
|
|
|
11
11
|
Update it the same way you installed it \u2014 git pull, or npm install -g @oracle-agent/oracle@latest.`};let o=`${Ee}@${t}`,a=["install","--prefix",r,"--no-audit","--no-fund",o];if(e)return{ok:!0,dryRun:!0,root:r,command:`npm ${a.join(" ")}`};try{let{stdout:i,stderr:l}=await mn("npm",a,{timeout:3e5,maxBuffer:16777216});return{ok:!0,root:r,stdout:i,stderr:l}}catch(i){return{ok:!1,reason:"npm-failed",root:r,message:i?.stderr||i?.message||"npm install failed"}}}var mn,Ee,fn,hn,ut=w(()=>{mn=pn(sn),Ee="@oracle-agent/oracle",fn="https://registry.npmjs.org",hn=1440*60*1e3});import bn from"node:fs";import xn from"node:os";import dt from"node:path";function W(t){return String(t||"").trim().toLowerCase().replace(/^\/+/,"").replace(/\s+/g,"-")}function vn(){let t=process.env.ORACLE_CONFIG_DIR||dt.join(xn.homedir(),".config","oracle");return dt.join(t,"chains.json")}function An(t){if(!t||typeof t!="object")return null;let e=String(t.key??"").trim();if(!e||/[/\\.]/.test(e))return null;let r=W(e);if(!mt.test(r))return null;let n=typeof t.chainId=="string"?t.chainId.trim():Number(t.chainId);if(n===""||n===null||n===void 0||typeof n=="number"&&!Number.isFinite(n))return null;let o=typeof t.agent=="string"&&mt.test(t.agent.trim())?t.agent.trim():"oracle";return{key:r,aliases:Array.isArray(t.aliases)?t.aliases.map(W).filter(Boolean).slice(0,8):[],chainId:n,name:String(t.name||r).slice(0,60),kind:["evm","svm","utxo","venue"].includes(t.kind)?t.kind:"evm",family:W(t.family)||r,agent:o,note:String(t.note||"user-defined").slice(0,80),build:t.build!==!1,source:"user"}}function Cn(t=bn.readFileSync){try{let e=JSON.parse(t(vn(),"utf8")),r=Array.isArray(e?.chains)?e.chains:[],n=[],o=new Set;for(let a of r){let i=An(a);!i||o.has(i.key)||(o.add(i.key),n.push(i))}return n}catch{return[]}}function ft(){let t=Cn();if(t.length===0)return pt;let e=new Map(pt.map(r=>[r.key,r]));for(let r of t)e.set(r.key,r);return[...e.values()]}function $n({buildOnly:t=!1}={}){return ft().filter(e=>t?e.build:!0)}function ee(t){let e=W(t);if(!e)return null;for(let r of ft())if(r.key===e||String(r.chainId).toLowerCase()===e||(r.aliases||[]).map(W).includes(e)||W(r.name)===e)return r;return null}function ht({selectedKey:t=null,buildOnly:e=!1}={}){let r=$n({buildOnly:e}),n=["oracle chains","","pick a build/trade surface:",""];for(let o of r){let a=t&&t===o.key?"*":" ",i=String(o.chainId).padEnd(6),l=o.key.padEnd(12);n.push(`${a} ${l} ${i} ${o.note}`)}return n.push(""),n.push("usage:"),n.push(" /chain list"),n.push(" /chain hyperliquid select"),n.push(" /chain show current"),n.push(" /chain clear unset"),n.push(" oracle chain use base same from shell"),t&&n.push("",`active: ${t}`),n.join(`
|
|
12
12
|
`)+`
|
|
13
13
|
`}var pt,mt,Re=w(()=>{pt=Object.freeze([{key:"hyperliquid",aliases:["hl","hyperevm","hype","999"],chainId:999,name:"hyperliquid",kind:"evm",family:"hyperliquid",agent:"hyperliquid-agent",note:"perps \xB7 hip-3/4 \xB7 hyperevm 999",build:!0},{key:"ethereum",aliases:["eth","mainnet","1"],chainId:1,name:"ethereum",kind:"evm",family:"evm",agent:"oracle",note:"l1 \xB7 bridge hub",build:!0},{key:"base",aliases:["8453"],chainId:8453,name:"base",kind:"evm",family:"evm",agent:"oracle",note:"evm l2",build:!0},{key:"arbitrum",aliases:["arb","42161"],chainId:42161,name:"arbitrum",kind:"evm",family:"evm",agent:"oracle",note:"evm l2",build:!0},{key:"optimism",aliases:["op","10"],chainId:10,name:"optimism",kind:"evm",family:"evm",agent:"oracle",note:"op mainnet",build:!0},{key:"polygon",aliases:["matic","137"],chainId:137,name:"polygon",kind:"evm",family:"evm",agent:"oracle",note:"evm l2",build:!0},{key:"bsc",aliases:["bnb","56"],chainId:56,name:"bnb chain",kind:"evm",family:"evm",agent:"oracle",note:"bsc",build:!0},{key:"avalanche",aliases:["avax","43114"],chainId:43114,name:"avalanche",kind:"evm",family:"evm",agent:"oracle",note:"c-chain",build:!0},{key:"abstract",aliases:["abs","2741"],chainId:2741,name:"abstract",kind:"evm",family:"evm",agent:"oracle",note:"open / add agent",build:!0},{key:"stable",aliases:["988"],chainId:988,name:"stable",kind:"evm",family:"stable",agent:"stable-agent",note:"usdt0 gas \xB7 stable agent",build:!0},{key:"robinhood",aliases:["rh","4663"],chainId:4663,name:"robinhood",kind:"evm",family:"robinhood",agent:"robinhood-agent",note:"rh chain 4663",build:!0},{key:"solana",aliases:["sol"],chainId:"SOL",name:"solana",kind:"svm",family:"solana",agent:"solana-agent",note:"jup \xB7 nfts \xB7 dexs",build:!0},{key:"bitcoin",aliases:["btc"],chainId:"BTC",name:"bitcoin",kind:"utxo",family:"bitcoin",agent:"bitcoin-agent",note:"ord \xB7 runes \xB7 l1",build:!0},{key:"polymarket",aliases:["poly","polygon-poly"],chainId:137,name:"polymarket",kind:"venue",family:"polymarket",agent:"polymarket-agent",note:"prediction markets (polygon venue)",build:!1}]);mt=/^[a-z0-9][a-z0-9-]*$/});import Ne from"node:fs";import _n from"node:path";function gt(){return _n.join($(),"active-chain.json")}function Le(){let t=gt();if(!Ne.existsSync(t))return null;try{let e=JSON.parse(Ne.readFileSync(t,"utf8"));if(!e||typeof e!="object"||!e.key)return null;let r=ee(e.key);return r?{key:r.key,chainId:r.chainId,name:r.name,agent:r.agent,selectedAt:e.selectedAt||null}:null}catch{return null}}function yt(t){let e=ee(t);if(!e){let n=new Error(`unknown chain '${t}'`);throw n.code="UNKNOWN_CHAIN",n}ae($());let r={key:e.key,chainId:e.chainId,name:e.name,agent:e.agent,selectedAt:new Date().toISOString()};return Ne.writeFileSync(gt(),JSON.stringify(r,null,2)+`
|
|
14
|
-
`,{mode:384}),r}var wt=w(()=>{Re();ie()});import{createHash as En,randomBytes as Ua}from"node:crypto";import{mkdirSync as On,readFileSync as Rn,writeFileSync as Nn}from"node:fs";import{homedir as Ln}from"node:os";import{dirname as In,join as kt}from"node:path";function re(t=process.env){return kt(t.ORACLE_CONFIG_DIR||kt(Ln(),".config","oracle"),"telegram-cards.json")}function ne(){return{links:{},artifacts:{},threads:{}}}function ue(){return te}function St(t,{readFile:e=Rn}={}){try{let r=JSON.parse(String(e(t)));te={links:r.links&&typeof r.links=="object"?r.links:{},artifacts:r.artifacts&&typeof r.artifacts=="object"?r.artifacts:{},threads:r.threads&&typeof r.threads=="object"?r.threads:{}}}catch{te=ne()}return te}function de(t,e=te,{writeFile:r=Nn,mkdir:n=On}={}){n(In(t),{recursive:!0,mode:448}),r(t,JSON.stringify(e),{mode:384})}function L(t){return t==null?!1:typeof t=="string"?t.trim()!=="":!0}function Dn(t){return En("sha256").update(String(t)).digest("hex")}function Ie(t){if(Array.isArray(t))return t.map(Ie);if(!t||typeof t!="object")return t;let e={};for(let[r,n]of Object.entries(t))/(secret|token|key|seed|private|password|mnemonic|auth)/i.test(r)||(e[r]=Ie(n));return e}function jn(t){let r=String(t||"").trim().match(/^oracle:card:(deepen|refresh|prepare|ta|fa|long|short|allow|deny):([a-z0-9-]{4,40})$/i);return r?{action:r[1].toLowerCase(),artifactId:r[2].toLowerCase()}:null}function bt({platform:t="telegram",artifactId:e,openUrl:r,hasGrant:n=!1}={}){let o=String(e||"").trim().toLowerCase();if(!Te.test(o))return{kind:"text_menu",text:"no artifact to continue",cancelHint:""};let a=[],i=[{text:"TA",callback_data:`oracle:card:ta:${o}`},{text:"FA",callback_data:`oracle:card:fa:${o}`}],l=p=>et(r,{side:p}),c=l("long"),s=l("short"),d=c&&s?[{text:"LONG",url:c},{text:"SHORT",url:s}]:[{text:"LONG",callback_data:`oracle:card:long:${o}`},{text:"SHORT",callback_data:`oracle:card:short:${o}`}];return L(r)?(a.push([{text:"Open",url:String(r)},i[0]]),a.push(d),a.push(n?[i[1],{text:"Prep",callback_data:`oracle:card:prepare:${o}`}]:[i[1]])):(a.push(i),a.push(d),n&&a.push([{text:"Prep",callback_data:`oracle:card:prepare:${o}`}])),String(t)==="telegram"?{kind:"inline_keyboard",replyMarkup:{inline_keyboard:a.filter(p=>p.length>0)},cancelHint:"LONG/SHORT open the graph. CONFIRM there. Telegram never sends."}:{kind:"text_menu",text:"TA / FA / LONG / SHORT",cancelHint:""}}function xt(t={}){let r=[`*${L(t.title)?u(t.title):"Oracle artifact"}*`,`Kind: ${L(t.kind)?u(t.kind):f}`,`Id: ${L(t.id)?`\`${String(t.id).replace(/`/g,"")}\``:f}`,`Summary: ${L(t.summary)?u(t.summary):f}
|
|
14
|
+
`,{mode:384}),r}var wt=w(()=>{Re();ie()});import{createHash as En,randomBytes as Ua}from"node:crypto";import{mkdirSync as On,readFileSync as Rn,writeFileSync as Nn}from"node:fs";import{homedir as Ln}from"node:os";import{dirname as In,join as kt}from"node:path";function re(t=process.env){return kt(t.ORACLE_CONFIG_DIR||kt(Ln(),".config","oracle"),"telegram-cards.json")}function ne(){return{links:{},artifacts:{},threads:{}}}function ue(){return te}function St(t,{readFile:e=Rn}={}){try{let r=JSON.parse(String(e(t)));te={links:r.links&&typeof r.links=="object"?r.links:{},artifacts:r.artifacts&&typeof r.artifacts=="object"?r.artifacts:{},threads:r.threads&&typeof r.threads=="object"?r.threads:{}}}catch{te=ne()}return te}function de(t,e=te,{writeFile:r=Nn,mkdir:n=On}={}){n(In(t),{recursive:!0,mode:448}),r(t,JSON.stringify(e),{mode:384})}function L(t){return t==null?!1:typeof t=="string"?t.trim()!=="":!0}function Dn(t){return En("sha256").update(String(t)).digest("hex")}function Ie(t){if(Array.isArray(t))return t.map(Ie);if(!t||typeof t!="object")return t;let e={};for(let[r,n]of Object.entries(t))/(secret|token|key|seed|private|password|mnemonic|auth)/i.test(r)||(e[r]=Ie(n));return e}function jn(t){let r=String(t||"").trim().match(/^oracle:card:(deepen|refresh|prepare|ta|fa|long|short|allow|deny):([a-z0-9-]{4,40})$/i);return r?{action:r[1].toLowerCase(),artifactId:r[2].toLowerCase()}:null}function bt({platform:t="telegram",artifactId:e,openUrl:r,hasGrant:n=!1}={}){let o=String(e||"").trim().toLowerCase();if(!Te.test(o))return{kind:"text_menu",text:"no artifact to continue",cancelHint:""};let a=[],i=[{text:"TA",callback_data:`oracle:card:ta:${o}`},{text:"FA",callback_data:`oracle:card:fa:${o}`}],l=p=>et(r,{side:p}),c=l("long"),s=l("short"),d=c&&s?[{text:"LONG",url:c},{text:"SHORT",url:s}]:[{text:"LONG",callback_data:`oracle:card:long:${o}`},{text:"SHORT",callback_data:`oracle:card:short:${o}`}];return L(r)?(a.push([{text:"Open",url:String(r)},i[0]]),a.push(d),a.push(n?[i[1],{text:"Prep",callback_data:`oracle:card:prepare:${o}`}]:[i[1]])):(a.push(i),a.push(d),n&&a.push([{text:"Prep",callback_data:`oracle:card:prepare:${o}`}])),String(t)==="telegram"?{kind:"inline_keyboard",replyMarkup:{inline_keyboard:a.filter(p=>p.length>0)},cancelHint:"LONG/SHORT open the graph. CONFIRM there. Telegram never sends."}:{kind:"text_menu",text:"TA / FA / LONG / SHORT",cancelHint:""}}function xt(t={}){let r=[`*${L(t.title)?u(t.title):"Oracle artifact"}*`,`Kind: ${L(t.kind)?u(t.kind):f}`,`Id: ${L(t.id)?`\`${String(t.id).replace(/`/g,"")}\``:f}`,`Summary: ${L(t.summary)?u(t.summary):f}`],n=Se(t.confidence);n!==f&&r.push(`Confidence: ${n}`),(L(t.source)||L(t.fetchedAt))&&r.push(`Source: ${u(t.source)} at ${u(t.fetchedAt)}`),Array.isArray(t.warnings)&&t.warnings.length&&r.push(`Warnings: ${t.warnings.map(a=>u(a)).join("; ")}`);let o=U(t);return r.push(o.allowed?"Actions: TA / FA / LONG / SHORT open the graph. Execute on CONFIRM there.":`Actions: TA / FA / LONG / SHORT \u2014 ${u(o.reason)}`),r.join(`
|
|
15
15
|
`)}function Bn(t,e={},{now:r=Date.now()}={}){let n=t||ne(),o=String(e.id||"").trim().toLowerCase();if(!Te.test(o))throw new TypeError("artifact id required");let a={id:o,kind:String(e.kind||"thesis"),title:String(e.title||"Oracle artifact"),summary:String(e.summary||""),openUrl:L(e.openUrl)?String(e.openUrl):null,confidence:e.confidence,source:e.source||"oracle",fetchedAt:e.fetchedAt||new Date(r).toISOString(),warnings:Array.isArray(e.warnings)?e.warnings.map(String):[],payload:Ie(e.payload||{}),createdAt:new Date(r).toISOString()};return n.artifacts[o]=a,a}function Pe(t,{chatId:e,artifactId:r,now:n=Date.now()}={}){let o=t||ne(),a=String(e||"").trim(),i=String(r||"").trim().toLowerCase();if(!a)throw new TypeError("chat id required");if(!Te.test(i))throw new TypeError("artifact id required");return o.threads[a]={artifactId:i,updatedAt:n},o.threads[a]}function vt(t,{chatId:e,text:r}={}){let n=String(e||"").trim(),o=String(r||"").trim();if(!n||!o||/^\//.test(o))return null;let a=t?.threads?.[n];if(!a?.artifactId)return null;let i=t.artifacts?.[a.artifactId];return i?`Continue artifact ${i.id} (${i.kind}). Prior: ${i.summary||i.title}. User: ${o}`:null}function At(t,{token:e,telegramUserId:r,now:n=Date.now()}={}){let o=t||ne(),a=String(e||"").trim(),i=String(r||"").trim();if(!Mn.test(a))return{ok:!1,error:"invalid start token"};if(!Un.test(i))return{ok:!1,error:"invalid telegram user"};let l=Dn(a),c=o.links[l];return c?(delete o.links[l],Number(c.expiresAt)<=n?{ok:!1,error:"start token expired"}:String(c.ownerId)!==i?{ok:!1,error:"start token is bound to a different owner"}:{ok:!0,ownerId:i}):{ok:!1,error:"unknown or already used start token"}}function Ct(t,{data:e,chatId:r,grant:n=null,now:o=Date.now()}={}){let a=jn(e);if(!a)return null;if(!Pn.has(a.action))return{text:"That card action is not available.",buttons:null};let i=t?.artifacts?.[a.artifactId];if(!i)return{text:"That artifact is gone. Ask again and I will issue a new card.",buttons:null};r&&Pe(t,{chatId:r,artifactId:i.id,now:o});let l=U({grant:n},{now:o}),c=bt({artifactId:i.id,openUrl:i.openUrl,hasGrant:l.allowed});return a.action==="refresh"?{text:xt(i),buttons:c,prompt:null}:a.action==="deepen"?{text:null,buttons:null,prompt:`Deepen artifact ${i.id} (${i.kind}). Prior: ${i.summary||i.title}. Be terse. Do not sign or broadcast.`}:a.action==="ta"?{text:null,buttons:null,prompt:`TA artifact ${i.id}. Prior: ${i.summary||i.title}. Run deterministic TA on the coin/venue in the artifact (RSI divergence, S/R, candle patterns). Reply in this Telegram chat with the verdict rows and say what was drawn. Do not sign or broadcast.`}:a.action==="fa"?{text:null,buttons:null,prompt:`FA artifact ${i.id}. Prior: ${i.summary||i.title}. Run per-coin FA (funding, OI, book, premium) plus the separate MACRO thesis (M1/M2/Fed BS/net liquidity) if relevant. Cite receipts. Stay in this Telegram chat. Do not sign or broadcast.`}:a.action==="allow"?{text:"Allow is the graph. Open the ticket there and CONFIRM. Telegram did not send.",buttons:null,prompt:null}:a.action==="deny"?{text:`Denied ${i.id}. Ticket cancelled. Nothing signed.`,buttons:null,prompt:null}:a.action==="long"||a.action==="short"?{text:null,buttons:null,prompt:`Open the live graph ticket for a ${a.action} on artifact ${i.id}. Prior: ${i.summary||i.title}. Size from the connected HL account. Execute only on CONFIRM on the graph. Never sign from Telegram.`}:l.allowed?{text:`Queued unsigned prepare for ${i.id}. Nothing signed. Allow/Deny still required.`,buttons:c,prompt:null,prepare:{artifactId:i.id,unsigned:!0,broadcast:!1}}:{text:`Prepare blocked \u2014 ${l.reason}. Deepen and Refresh still work.`,buttons:c,prompt:null}}function $t(t={},{grant:e=null,now:r=Date.now(),state:n}={}){let o=n||ue(),a=String(t.id||`art-${Math.abs(Number(r)).toString(36)}`).toLowerCase().slice(0,40),i=Bn(o,{...t,id:a},{now:r}),l=U({grant:e},{now:r});return{text:xt({...i,grant:e}),replyMarkup:bt({artifactId:i.id,openUrl:i.openUrl,hasGrant:l.allowed}).replyMarkup,artifact:i,state:o}}var Tn,Pn,Te,Mn,Un,te,Me=w(()=>{we();ve();Tn=Object.freeze(["deepen","refresh","prepare","ta","fa","long","short","allow","deny"]),Pn=new Set(Tn),Te=/^[a-z0-9-]{4,40}$/i,Mn=/^[0-9a-f]{32}$/,Un=/^\d+$/;te=ne()});var Yt={};j(Yt,{NON_OWNER_REPLY:()=>V,buildPersona:()=>K,handleSelfUpdate:()=>It,isForwarded:()=>Tt,isOwnerSender:()=>z,ownerIdsFor:()=>Nt,parseGatewayChainCommand:()=>Gt,parseGatewayCompactCommand:()=>Ht,parseGatewayEffortCommand:()=>Dt,parseGatewayGoalCommand:()=>Ft,parseGatewayHelpCommand:()=>jt,parseGatewayModelCommand:()=>Ut,parseGatewaySetupModelCommand:()=>Qn,parseGatewayStatusCommand:()=>Bt,parsePeerAsk:()=>Wt,parseSelfUpdate:()=>Lt,resolveBackendArgv:()=>zt,resolveGatewayModel:()=>Pt,resolveOracleBin:()=>Rt,routePeerConsult:()=>oe,routeToAgent:()=>O});import{spawn as Ot}from"node:child_process";import{dirname as Fn,join as De}from"node:path";import{homedir as Hn}from"node:os";import{mkdirSync as Gn,readFileSync as qn,writeFileSync as Wn,unlinkSync as zn}from"node:fs";import{fileURLToPath as Vn}from"node:url";function Rt({env:t=process.env,moduleUrl:e=import.meta.url}={}){return t.ORACLE_CLI_ENTRY||De(Fn(Vn(e)),"oracle.mjs")}function Nt(t,e=process.env){let r=String(e[`ORACLE_OWNER_${String(t).toUpperCase()}`]||""),n=String(e.ORACLE_OWNER_IDS||"");return new Set(`${r},${n}`.split(",").map(o=>o.trim()).filter(Boolean))}function z({platform:t,senderId:e,extraOwners:r},n=process.env){let o=String(e||"").trim();return o?Nt(t,n).has(o)?!0:Array.isArray(r)?r.map(a=>String(a).trim()).filter(Boolean).includes(o):!1:!1}function Lt(t){let e=String(t||"").trim();if(!e)return null;let r=e.replace(/^\/update(?:@[\w_]+)?\b/i,"update");return/^(?:oracle\s+)?update\s+--check\s*$/i.test(r)?{checkOnly:!0}:/^(?:oracle\s+)?update\s*$/i.test(r)?{checkOnly:!1}:null}async function It(t,{check:e=ct,update:r=lt,versionOf:n=Oe}={}){let o=await e({force:!0});if(t.checkOnly)return o.checked?o.updateAvailable?`oracle ${o.current} \u2192 ${o.latest} available. Send /update to install.`:`oracle ${o.current} is up to date`:`oracle ${o.current||"?"} \u2014 could not reach npm`;if(o.checked&&!o.updateAvailable)return`oracle ${o.current} is already up to date`;let a=o.latest||"latest",i=await r({version:a==="latest"?"latest":a});if(!i.ok)return`oracle update failed: ${i.message}`;let l=n();return[`oracle ${o.current||"?"} \u2192 ${l||a}`,"Restart the gateway to load it: oracle gateway"].join(`
|
|
16
16
|
`)}function Tt(t={}){return!!(t.forwarded||t.forward_from||t.forward_from_chat||t.forward_origin||t.forward_sender_name||t.forward_date)}function Pt({readConfig:t=q}={}){let e=t();return e?e.backend==="hermes"?{ok:!1,error:"model config delegates to hermes; the gateway runs Oracle's native loop. Set a standalone backend: oracle model --backend standalone"}:e.model?{ok:!0,provider:e.provider,model:e.model,reasoningEffort:e.reasoningEffort||null}:{ok:!1,error:"model config has no model \u2014 run: oracle model --backend standalone --provider <p> --model <m>"}:{ok:!1,error:"gateway has no model configured \u2014 run: oracle model --backend standalone --provider <p> --model <m>"}}function Ut(t){let r=String(t||"").trim().match(/^\/model(?:\s+(.+))?$/i);if(!r)return null;let n=String(r[1]||"").trim();if(!n)return{action:"list"};if(n.toLowerCase()==="show"||n==="?")return{action:"show"};if(n.toLowerCase()==="list")return{action:"list"};let o=n.split(/\s+/),a=Mt[o[0].toLowerCase()];if(a&&o.length===1)return{action:"set",provider:a.provider,model:a.model};if(a&&o.length>=2)return{action:"set",provider:a.provider,model:o.slice(1).join(" ")};if(o.length>=2)return{action:"set",provider:o[0],model:o.slice(1).join(" ")};if(o[0]?.includes(":")){let[i,l]=o[0].split(":");if(i&&l)return{action:"set",provider:i,model:l}}return{action:"usage"}}function Dt(t){let r=String(t||"").trim().match(/^\/(?:effort|reasoning)(?:\s+(.+))?$/i);if(!r)return null;let n=String(r[1]||"").trim().toLowerCase();return!n||n==="show"||n==="?"?{action:"show"}:Yn.includes(n)?{action:"set",reasoningEffort:n}:{action:"usage"}}function Jn({provider:t,model:e}){let r=q()||{},n=ye({...r,backend:r.backend&&r.backend!=="auto"?r.backend:"standalone",provider:t,model:e});return`model ${n.provider} / ${n.model}
|
|
17
17
|
Oracle persona unchanged. Native harness only \u2014 Hermes Telegram uses its own /model.`}function Xn(t){let e=q();if(!e)throw new Error("no model configured \u2014 run /model first");return`effort ${ye({...e,reasoningEffort:t}).reasoningEffort||t}
|