@oracle-agent/oracle 0.35.43 → 0.35.45

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 (68) hide show
  1. package/dist/agent-sessions.mjs +24 -24
  2. package/dist/assets/skills/oracle-desk-product/SKILL.md +1 -1
  3. package/dist/bin/desk-server.mjs +28 -28
  4. package/dist/bin/oracle-data-mcp.mjs +19 -19
  5. package/dist/bin/oracle-gateway.mjs +48 -48
  6. package/dist/bin/oracle-investigate.mjs +5 -5
  7. package/dist/bin/oracle-launch-radar-shadow.mjs +6 -6
  8. package/dist/bin/oracle-mev-arb-shadow.mjs +6 -6
  9. package/dist/bin/oracle-mev-shadow.mjs +6 -6
  10. package/dist/bin/oracle-public-server.mjs +5 -5
  11. package/dist/bin/oracle-route.mjs +26 -26
  12. package/dist/bin/oracle-scan.mjs +11 -11
  13. package/dist/bin/oracle.mjs +13 -12
  14. package/dist/cli/commands/account.mjs +39 -0
  15. package/dist/cli/commands/agent-session.mjs +23 -23
  16. package/dist/cli/commands/airdrop.mjs +10 -10
  17. package/dist/cli/commands/chat.mjs +218 -217
  18. package/dist/cli/commands/data.mjs +244 -8
  19. package/dist/cli/commands/doctor.mjs +7 -7
  20. package/dist/cli/commands/eval.mjs +157 -153
  21. package/dist/cli/commands/extension-policy.mjs +1 -1
  22. package/dist/cli/commands/farm.mjs +19 -19
  23. package/dist/cli/commands/fees.mjs +3 -3
  24. package/dist/cli/commands/follow.mjs +36 -36
  25. package/dist/cli/commands/mcp.mjs +6 -6
  26. package/dist/cli/commands/mint.mjs +11 -11
  27. package/dist/cli/commands/model.mjs +222 -221
  28. package/dist/cli/commands/quickstart.mjs +7 -7
  29. package/dist/cli/commands/receipt.mjs +11 -11
  30. package/dist/cli/commands/resolve.mjs +12 -12
  31. package/dist/cli/commands/session-vault.mjs +5 -5
  32. package/dist/cli/commands/sign.mjs +12 -12
  33. package/dist/cli/commands/signer.mjs +25 -25
  34. package/dist/cli/commands/snipe.mjs +11 -11
  35. package/dist/cli/commands/strategy.mjs +5 -5
  36. package/dist/cli/commands/swap.mjs +15 -15
  37. package/dist/cli/commands/venues.mjs +2 -2
  38. package/dist/data/desk-data.mjs +26 -26
  39. package/dist/data/names.mjs +3 -3
  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 +44 -44
  43. package/dist/investigator/index.mjs +2 -2
  44. package/dist/launch-radar/index.mjs +5 -5
  45. package/dist/local-signer/anvil-attestation-worker.mjs +1 -1
  46. package/dist/local-signer/index.mjs +7 -3
  47. package/dist/local-signer/runtime.mjs +22 -22
  48. package/dist/nft/universal-mint-router.mjs +4 -4
  49. package/dist/notifications/index.mjs +7 -7
  50. package/dist/router/index.mjs +3 -3
  51. package/dist/router/prepare-bridge.mjs +2 -2
  52. package/dist/router/prepare-route.mjs +3 -3
  53. package/dist/scanner/index.mjs +4 -4
  54. package/dist/strategy/index.mjs +3 -3
  55. package/dist/tui/standalone-client.mjs +90 -88
  56. package/package.json +1 -1
  57. package/public/eval-report.json +347 -13
  58. package/public/oracle-splash/docs/browser-and-web/index.html +2 -2
  59. package/public/oracle-splash/docs/connectors/index.html +2 -2
  60. package/public/oracle-splash/docs/getting-started/index.html +2 -2
  61. package/public/oracle-splash/docs/index.html +3 -3
  62. package/public/oracle-splash/docs/reference/index.html +2 -2
  63. package/public/oracle-splash/docs/security/index.html +2 -2
  64. package/public/oracle-splash/docs/using-oracle/index.html +2 -2
  65. package/public/oracle-splash/download/index.html +3 -3
  66. package/public/oracle-splash/downloads/index.html +1 -1
  67. package/public/oracle-splash/index.html +6 -6
  68. package/server.json +2 -2
@@ -1,9 +1,9 @@
1
- var ke=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(r){throw n=[r],r}};import ae from"node:net";import hr from"node:dns";function $e(e){let t=String(e).toLowerCase().split("%")[0];if((t.match(/::/g)||[]).length>1)return null;let n=f=>{if(!f)return[];let h=f.split(":"),w=h.at(-1);if(w?.includes(".")){let T=w.split(".").map(Number);if(T.length!==4||T.some(v=>!Number.isInteger(v)||v<0||v>255))return null;h.splice(h.length-1,1,(T[0]<<8|T[1]).toString(16),(T[2]<<8|T[3]).toString(16))}return h.some(T=>!/^[0-9a-f]{1,4}$/.test(T))?null:h.map(T=>Number.parseInt(T,16))},[r,o]=t.split("::"),i=n(r),s=n(o);if(!i||!s)return null;let a=t.includes("::"),c=8-i.length-s.length;if(!a&&c!==0||a&&c<1)return null;let y=[...i,...Array(Math.max(0,c)).fill(0),...s];return y.length!==8?null:Uint8Array.from(y.flatMap(f=>[f>>8,f&255]))}function Qe(e,t,n){let r=Math.floor(n/8),o=n%8;for(let s=0;s<r;s+=1)if(e[s]!==t[s])return!1;if(!o)return!0;let i=255<<8-o;return(e[r]&i)===(t[r]&i)}function Xe(e){if(ae.isIPv4(e)){let t=e.split(".").map(Number);return!(t[0]===0||t[0]===10||t[0]===127||t[0]>=224||t[0]===100&&t[1]>=64&&t[1]<=127||t[0]===169&&t[1]===254||t[0]===172&&t[1]>=16&&t[1]<=31||t[0]===192&&(t[1]===0||t[1]===2||t[1]===168)||t[0]===192&&t[1]===88&&t[2]===99||t[0]===198&&(t[1]===18||t[1]===19||t[1]===51)||t[0]===203&&t[1]===0&&t[2]===113)}if(ae.isIPv6(e)){let t=$e(e);if(!t)return!1;let n=$e("::ffff:0:0");return Qe(t,n,96)?Xe([...t.slice(12)].join(".")):Qe(t,$e("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,i])=>Qe(t,$e(o),i)):!1}return!1}function br(e){let t;try{t=new URL(String(e))}catch{return{ok:!1,error:`not a valid URL: ${String(e).slice(0,120)}`}}if(t.protocol!=="http:"&&t.protocol!=="https:")return{ok:!1,error:`refused protocol ${t.protocol} (only http/https)`};let n=t.hostname.toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,"");if(yr.has(n)||n.endsWith(".localhost")||n.endsWith(".internal"))return{ok:!1,error:`refused internal host ${n}`};let r=ae.isIP(n);return r!==0&&!Xe(n)?{ok:!1,error:`refused private address ${n}`}:{ok:!0,url:t,host:n,isLiteralIp:r!==0}}async function Ee(e,{lookupFn:t=hr.promises.lookup}={}){let n=br(e);if(!n.ok)return n;if(n.isLiteralIp)return{ok:!0,url:n.url,addresses:[{address:n.host,family:ae.isIPv6(n.host)?6:4}]};let r;try{r=await t(n.host,{all:!0,verbatim:!0})}catch{return{ok:!1,error:`refused: ${n.host} did not resolve`}}return!Array.isArray(r)||r.length===0||r.some(o=>!Xe(o.address))?{ok:!1,error:`refused: ${n.host} resolves to a non-public address`}:{ok:!0,url:n.url,addresses:r}}async function et({requireUndici:e=!1,importUndici:t=()=>import("undici")}={}){let n,r;try{let h=await t();n=h.Agent,r=h.fetch}catch(h){if(e)throw new Error(`egress-guard: untrustedUrl pinning requires the undici package, which failed to load: ${h?.message||h}`);return null}if(typeof n!="function"||typeof r!="function"){if(e)throw new Error("egress-guard: untrustedUrl pinning requires undici's Agent and fetch exports, which were not found on the imported module");return null}let o=h=>String(h).toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,""),i=new Map,s=h=>(Array.isArray(h)?h:[h]).map(w=>typeof w=="string"?{address:w}:w).filter(w=>w&&w.address).map(w=>({address:w.address,family:w.family||(ae.isIPv6(w.address)?6:4)})),a=(h,w,T)=>{i.set(o(h),s(typeof w=="string"?[{address:w,family:T}]:w))},c=h=>{let w=o(h);if(ae.isIP(w))return[{address:w,family:ae.isIPv6(w)?6:4}];let T=i.get(w);if(!T||!T.length)throw new Error(`refused: unpinned host ${h} during pinned fetch`);return T},y=new n({connect:{lookup(h,w,T){let v;try{v=c(h)}catch(_){return T(_)}return w?.all?T(null,v):T(null,v[0].address,v[0].family)}}}),f=wr((h,w={})=>r(h,{...w,dispatcher:y}),a);return{dispatcher:y,fetch:f,pin:a,resolve:c,async close(){try{await y.destroy()}catch{}}}}function wr(e,t){if(typeof e!="function")throw new Error("markPinCapableFetch: fetchImpl must be a function");if(typeof t!="function")throw new Error("markPinCapableFetch: pin must be a function");return e[tt]=Object.freeze({pin:t}),e}function nt(e){return typeof e=="function"&&typeof e[tt]?.pin=="function"}function $t(e,t,n){if(!nt(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[tt].pin(t,n)}var yr,tt,rt=ke(()=>{yr=new Set(["localhost","metadata.google.internal","metadata.goog"]);tt=Symbol.for("oracle.egressGuard.pinCapableFetch")});import{createHash as gr}from"node:crypto";import{types as re}from"node:util";function H(e){return oe(`HTTP JSON body refused: ${e}`)}function _r(e){return["isArgumentsObject","isArrayBuffer","isAnyArrayBuffer","isArrayBufferView","isBoxedPrimitive","isDataView","isDate","isExternal","isGeneratorObject","isKeyObject","isCryptoKey","isMap","isMapIterator","isModuleNamespaceObject","isNativeError","isPromise","isRegExp","isSet","isSetIterator","isTypedArray","isWeakMap","isWeakSet"].some(t=>typeof re[t]=="function"&&re[t](e))}function Nr(e){let t=[],n=0,r=0,o=0,i=0,s=new WeakSet,a=f=>{if(n+=Buffer.byteLength(f,"utf8"),n>ne.bytes)throw H("serialized byte limit exceeded");t.push(f)},c=f=>{if(Buffer.byteLength(f,"utf8")>ne.bytes)throw H("serialized byte limit exceeded");return JSON.stringify(f)},y=(f,h)=>{if(r+=1,r>ne.nodes)throw H("node limit exceeded");if(h>ne.depth)throw H("depth limit exceeded");if(f===null){a("null");return}if(typeof f=="string"){a(c(f));return}if(typeof f=="boolean"){a(f?"true":"false");return}if(typeof f=="number"){if(!Number.isFinite(f))throw H("non-finite number");a(Object.is(f,-0)?"0":String(f));return}if(typeof f!="object")throw H("unsupported non-JSON value");if(re.isProxy(f))throw H("proxy value");if(_r(f))throw H("unsupported exotic object");if(s.has(f))throw H("cyclic value");s.add(f);try{if(Object.getOwnPropertySymbols(f).length>0)throw H("symbol-keyed fields are unsupported");if(Array.isArray(f)){let v=Object.getPrototypeOf(f),_=0;for(;v!==null;){if(re.isProxy(v))throw H("proxy array prototype");if(_+=1,_>ne.depth)throw H("array prototype depth limit exceeded");v=Object.getPrototypeOf(v)}if(f.length>ne.arrayLength)throw H("array length limit exceeded");for(let $=0;$<f.length;$+=1){let M=Object.getOwnPropertyDescriptor(f,String($));if(!M||!Object.hasOwn(M,"value")||M.enumerable!==!0)throw H("array entries must be dense enumerable own data")}let C=0;for(let $ in f){if(i+=1,i>ne.fields)throw H("enumeration limit exceeded");if(Object.hasOwn(f,$)&&(C+=1,C>f.length))throw H("named array fields are unsupported")}if(C!==f.length)throw H("array entries must be dense enumerable own data");a("[");for(let $=0;$<f.length;$+=1)$&&a(","),y(Object.getOwnPropertyDescriptor(f,String($)).value,h+1);a("]");return}let w=Object.getPrototypeOf(f);if(w!==Object.prototype&&w!==null)throw H("non-plain object");let T=[];for(let v in f){if(i+=1,i>ne.fields)throw H("enumeration limit exceeded");if(!Object.hasOwn(f,v))continue;if(o+=1,o>ne.fields)throw H("field limit exceeded");let _=Object.getOwnPropertyDescriptor(f,v);if(!_||!Object.hasOwn(_,"value")||_.enumerable!==!0)throw H("object fields must be enumerable own data");T.push([v,_.value])}a("{");for(let v=0;v<T.length;v+=1)v&&a(","),a(c(T[v][0])),a(":"),y(T[v][1],h+1);a("}")}finally{s.delete(f)}};return y(e,0),t.join("")}function Or(e){let t=Object.create(null);if(e==null)return t;if(typeof e!="object"&&typeof e!="function")throw new TypeError("HTTP headers must be an object");if(re.isProxy(e))throw new TypeError("HTTP headers must not be a proxy");if(Object.getOwnPropertySymbols(e).length>0)throw new TypeError("HTTP headers must not contain symbol fields");let n=new Set;for(let r of Object.keys(e)){if(!/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/u.test(r))throw new TypeError("HTTP header names must be valid tokens");let o=r.toLowerCase();if(n.has(o))throw new TypeError("HTTP headers contain a duplicate canonical name");n.add(o);let i=Object.getOwnPropertyDescriptor(e,r);if(!i||!Object.hasOwn(i,"value"))throw new TypeError("HTTP headers must contain own data properties");let s=i.value;if(s==null||["object","function","symbol"].includes(typeof s))throw new TypeError("HTTP header values must be scalar");t[r]=String(s)}return t}function Cr(){return Object.assign(Object.create(null),{Accept:"application/json"})}function Pr(e,t){if(!e)throw new Error(`HTTP redirect from ${t} missing Location`);let n=new URL(String(e),String(t));if(n.protocol!=="http:"&&n.protocol!=="https:")throw new Error(`HTTP redirect from ${t} used unsupported protocol ${n.protocol}`);return n.toString()}function Rr(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function Le(e){if((typeof e!="object"||e===null)&&typeof e!="function")return`${typeof e}:${String(e)}`;let t=Bt.get(e);return t||(t=Mt,Mt+=1,Bt.set(e,t)),`reference:${t}`}function qt(e){if(!e||typeof e!="object"||Array.isArray(e)||!Object.hasOwn(e,"jsonrpc")||!Object.hasOwn(e,"method")||e.jsonrpc!=="2.0")return!1;let t=typeof e.method=="string"?e.method:"";return t?$r.has(t)||/^get[A-Z0-9_]/u.test(t)||/^is[A-Z0-9_]/u.test(t)||/^eth_get[A-Z0-9_]/u.test(t):!1}function jt(e,t){if(e==="GET"&&t==null)return!0;if(e!=="POST"||t==null)return!1;let n=t;if(typeof t=="string")try{n=JSON.parse(t)}catch{return!1}if(Array.isArray(n))return n.length>0&&n.every(qt);if(!n||typeof n!="object")return!1;if(Object.hasOwn(n,"jsonrpc")||Object.hasOwn(n,"method"))return qt(n);let r=Object.hasOwn(n,"type")?n.type:null;return typeof r=="string"&&Lr.has(r)&&(!Object.hasOwn(n,"action")||n.action==null)&&(!Object.hasOwn(n,"signature")||n.signature==null)&&(!Object.hasOwn(n,"nonce")||n.nonce==null)}function Fr(e,t,n,r={},o=null){let i=gr("sha256"),s=(c,y)=>{let f=String(y);i.update(String(Buffer.byteLength(c,"utf8"))).update(":").update(c),i.update("=").update(String(Buffer.byteLength(f,"utf8"))).update(":").update(f).update(`
2
- `)};s("method",e),s("url",t),Object.keys(n||{}).map((c,y)=>({name:c.toLowerCase(),order:y,value:String(n[c])})).sort((c,y)=>c.name.localeCompare(y.name)||c.order-y.order).forEach((c,y)=>{s(`header-name-${y}`,c.name),s(`header-value-${y}`,c.value)}),s("body",o??"-");for(let c of["untrustedUrl","maxResponseBytes","sameOriginRedirectsOnly","redirectPolicy","maxRedirects","timeoutMs","retries","fetchImpl","realFetch","lookupFn","importUndici","validateResponse"])s(`context-${c}`,r[c]??"-");return i.digest("hex")}function Ur(e,t){let n=Number(t);return Number.isFinite(n)&&n>0?Math.min(n*1e3,Ft):Math.min(250*2**e,Ft)+Math.floor(Math.random()*100)}function oe(e,t={}){let n=new Error(e);return n.retryable=!1,Object.assign(n,t),n}function it(e,t,n){return oe(`HTTP response from ${e} exceeded maxResponseBytes ${n} (${t})`,{oversize:!0})}function ce(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function Br(e){return e?e.byteLength??e.length??0:0}async function Mr(e,t,{url:n,truncate:r=!1,onOversize:o}={}){if(t==null)return await e.text();let i=Number(e.headers?.get?.("content-length"));if(Number.isFinite(i)&&i>t&&(ce(e),!r))throw it(n,`content-length ${i}`,t);let s=e.body?.getReader?.();if(!s){let h=await e.text(),w=Buffer.byteLength(h,"utf8");if(w>t){if(!r)throw it(n,`body ${w} bytes`,t);return Buffer.from(h,"utf8").subarray(0,t).toString("utf8")}return h}let a=[],c=0,y=!1;try{for(;;){let{value:h,done:w}=await s.read();if(w)break;if(h&&(a.push(Buffer.from(h)),c+=Br(h),c>t)){y=!0;break}}}finally{if(y)try{await s.cancel()}catch{}try{s.releaseLock?.()}catch{}}if(y&&(typeof o=="function"&&o(),!r))throw it(n,`streamed ${c} bytes`,t);let f=Buffer.concat(a);return(y?f.subarray(0,t):f).toString("utf8")}function qr(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function jr(e,{fetchImpl:t,method:n,headers:r,body:o,timeoutMs:i,lookupFn:s,realFetch:a,untrustedUrl:c=!1,maxResponseBytes:y=null,sameOriginRedirectsOnly:f=!1,importUndici:h,validateResponse:w,signal:T,redirectPolicy:v="follow",maxRedirects:_=Fe}){let C=null,$=t,M=s?{lookupFn:s}:{};if(c&&!a&&!nt($))throw oe(`HTTP refused ${e}: untrustedUrl requires a pin-capable fetchImpl (see markPinCapableFetch in egress-guard.mjs) or no fetchImpl override so Oracle can pin the connection itself`);let b=new AbortController,d=setTimeout(()=>b.abort(),i),u=T?Dt?Dt([T,b.signal]):T:b.signal,m=async(p,{status:S=null}={})=>{let A=await Ee(p,M);if(!A.ok)throw oe(S==null?`HTTP refused ${p}: ${A.error}`:`HTTP redirect to ${p} ${A.error}`,S==null?{}:{status:S});let g=new URL(p).hostname;if(a){if(C&&(await C.close(),C=null),!C)try{C=await et({requireUndici:!0,...h?{importUndici:h}:{}})}catch(l){throw oe(S==null?`HTTP refused ${p}: ${l?.message||l}`:`HTTP redirect to ${p} refused: ${l?.message||l}`,S==null?{}:{status:S})}C.pin(g,A.addresses),$=C.fetch}else $t($,g,A.addresses);return A};try{let p=String(e),S=Object.assign(Object.create(null),r||{});c&&await m(p);for(let A=0;A<=_;A+=1){let g=Object.assign(Object.create(null),{method:n,headers:S,body:o,signal:u,redirect:"manual",dispatcher:void 0}),l=await $(p,g);if((v==="error"||_===0)&&l.status>=300&&l.status<400)throw ce(l),oe(`HTTP ${l.status} ${n} redirect refused`,{status:l.status,redirectRefused:!0});if(Ir.has(l.status)){let x=f===!0&&n==="POST"&&[307,308].includes(l.status)&&jt(n,o);if(n!=="GET"&&n!=="HEAD"&&!x){ce(l);let L=new Error(`HTTP ${l.status} ${n} ${p} redirected non-idempotent request`);throw L.status=l.status,L}if(A===_)throw ce(l),oe(`HTTP ${l.status} ${n} redirect budget exhausted`,{status:l.status,redirectRefused:!0});let I=l.headers?.get?.("location"),R;try{R=Pr(I,p)}catch(L){throw ce(l),L}let U=!Rr(R,p);if(ce(l),U&&n==="POST"){let L=new Error(`HTTP ${l.status} ${n} cross-origin redirect refused`);throw L.status=l.status,L}if(U&&f){let L=new Error(`HTTP ${l.status} ${n} cross-origin redirect refused`);throw L.status=l.status,L.retryable=!1,L}if(U&&(S=Cr(S)),c)await m(R,{status:l.status});else if(U){let L=await Ee(R,M);if(!L.ok){let N=new Error(`HTTP redirect from ${p} ${L.error}`);throw N.status=l.status,N.retryable=!1,N}a&&L.addresses?.length&&(C||(C=await et(h?{importUndici:h}:{})),C&&(C.pin(new URL(R).hostname,L.addresses),$=C.fetch))}p=R;continue}if(typeof w=="function")try{await w(l,{url:p})}catch(x){throw ce(l),oe(x?.message||String(x))}let E=await Mr(l,y,{url:p,onOversize:()=>b.abort()}),k=qr(E);if(!l.ok){let x=new Error(`HTTP ${l.status} ${n} ${p}`);throw x.status=l.status,x.retryAfter=l.headers?.get?.("retry-after")??null,x.body=k??E.slice(0,300),x}return k??E}throw new Error(`HTTP redirect loop for ${e}`)}catch(p){if(b.signal.aborted&&!Se(T)){let S=p&&(typeof p=="object"||typeof p=="function")&&!re.isProxy(p)?p:null,A=S?Object.getOwnPropertyDescriptor(S,"oversize"):null;if(!(A&&Object.hasOwn(A,"value")&&A.value===!0))try{if(!S)throw new TypeError("unsafe rejection");Object.defineProperties(S,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}})}catch{let l=new Error("HTTP request timed out");throw Object.defineProperties(l,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}}),l}}throw p}finally{clearTimeout(d),C&&await C.close()}}async function V(e,t={}){if(t!=null&&typeof t!="object"&&typeof t!="function")throw new TypeError("HTTP options must be an object");if(t!=null&&re.isProxy(t))throw new TypeError("HTTP options must not be a proxy");let n=new Set(["body","dedupe","fetchImpl","headers","importUndici","lookupFn","maxRedirects","maxResponseBytes","method","redirectPolicy","retries","sameOriginRedirectsOnly","signal","timeoutMs","untrustedUrl","validateResponse"]);if(t!=null){if(Object.getOwnPropertySymbols(t).length>0)throw new TypeError("HTTP options contain unknown fields");for(let N of Object.getOwnPropertyNames(t)){let F=Object.getOwnPropertyDescriptor(t,N);if(!(N==="toJSON"&&F&&Object.hasOwn(F,"value")&&F.value===void 0)){if(!n.has(N))throw new TypeError("HTTP options contain unknown fields");if(!F||!F.enumerable||!Object.hasOwn(F,"value"))throw new TypeError("HTTP options must contain enumerable own data properties")}}}let r=N=>{if(t==null||!Object.hasOwn(t,N))return;let F=Object.getOwnPropertyDescriptor(t,N);if(!F||!Object.hasOwn(F,"value"))throw new TypeError("HTTP options must contain own data properties");return F.value};if(typeof e!="string"||e.length===0||e.length>8192)throw new TypeError("HTTP URL must be a bounded string");let o=r("method");if(o!==void 0&&(typeof o!="string"||!/^[A-Za-z]+$/u.test(o)))throw new TypeError("HTTP method must be a string token");let i=r("timeoutMs");if(i!==void 0&&(!Number.isInteger(i)||i<1||i>12e4))throw new TypeError("HTTP timeoutMs must be a bounded integer");let s=r("retries");if(s!==void 0&&(!Number.isInteger(s)||s<0||s>10))throw new TypeError("HTTP retries must be a bounded integer");let a=r("redirectPolicy");if(a!==void 0&&a!=="follow"&&a!=="error")throw new TypeError('HTTP redirectPolicy must be "follow" or "error"');let c=r("maxRedirects");if(c!==void 0&&(!Number.isInteger(c)||c<0||c>Fe))throw new TypeError(`HTTP maxRedirects must be an integer from 0 through ${Fe}`);if(a==="error"&&c!==void 0&&c!==0)throw new TypeError('HTTP redirectPolicy "error" requires maxRedirects 0 when supplied');let y=a??"follow",f=y==="error"?0:c??Fe;for(let N of["dedupe","untrustedUrl","sameOriginRedirectsOnly"]){let F=r(N);if(F!==void 0&&typeof F!="boolean")throw new TypeError(`HTTP ${N} must be boolean`)}let h=r("maxResponseBytes");if(h!==void 0&&(!Number.isInteger(h)||h<1||h>64*1024*1024))throw new TypeError("HTTP maxResponseBytes must be a bounded integer");let w=r("signal");if(w!==void 0){if(re.isProxy(w)||!(w instanceof AbortSignal))throw new TypeError("HTTP signal must be a native AbortSignal");try{Se(w)}catch{throw new TypeError("HTTP signal must be a native AbortSignal")}}for(let N of["importUndici","lookupFn","validateResponse"]){let F=r(N);if(F!==void 0&&typeof F!="function")throw new TypeError(`HTTP ${N} must be a function`)}let T=r("fetchImpl"),v=T||globalThis.fetch;if(typeof v!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let _=i??12e3,C=(o||"GET").toUpperCase(),$=r("headers"),M=Or($),b=Object.assign(Object.create(null),M);Object.keys(b).some(N=>N.toLowerCase()==="accept")||(b.Accept="application/json");let d=r("body");d!=null&&typeof d!="string"&&(Object.keys(b).find(F=>F.toLowerCase()==="content-type")||(b["Content-Type"]="application/json"),d=Nr(d));let u=s??Sr,m=r("lookupFn"),p=!T,S=r("untrustedUrl")===!0,A=r("sameOriginRedirectsOnly")===!0,g=r("importUndici"),l=r("validateResponse"),E=w,k=h??null,x=async()=>{let N;for(let F=0;F<=u;F++){E&&xr.call(E);try{return await jr(e,{fetchImpl:v,method:C,headers:b,body:d,timeoutMs:_,lookupFn:m,realFetch:p,untrustedUrl:S,maxResponseBytes:k,sameOriginRedirectsOnly:A,importUndici:g,validateResponse:l,signal:E,redirectPolicy:y,maxRedirects:f})}catch(K){N=K;let q=Ke=>{if(!K||typeof K!="object"&&typeof K!="function"||re.isProxy(K))return;let he=Object.getOwnPropertyDescriptor(K,Ke);return he&&Object.hasOwn(he,"value")?he.value:void 0},ze=q("status"),Cn=q("oracleTimeout")===!0||q("name")==="AbortError"||q("name")==="TimeoutError"||Se(E),Pn=new Set([408,425,429]),Rn=q("retryable")===!1?!1:ze!=null?Pn.has(ze)||Er.has(ze)&&Lt.has(C):!Cn&&Lt.has(C);if(F===u||!Rn)throw K;let yt=Ur(F,q("retryAfter"));E?await new Promise((Ke,he)=>{let bt,ye=()=>{clearTimeout(bt),Ut.call(E,"abort",ye),he(Tr(E)||new DOMException("Aborted","AbortError"))};if(Se(E)){ye();return}bt=setTimeout(()=>{Ut.call(E,"abort",ye),Ke()},yt),kr.call(E,"abort",ye,{once:!0}),Se(E)&&ye()}):await Dr(yt)}}throw N};if(!(r("dedupe")!==!1&&!E&&jt(C,d)))return x();let R=Fr(C,e,b,{untrustedUrl:S,maxResponseBytes:k,sameOriginRedirectsOnly:A,redirectPolicy:y,maxRedirects:f,timeoutMs:_,retries:u,fetchImpl:Le(v),realFetch:p,lookupFn:Le(m),importUndici:Le(g),validateResponse:Le(l)},d),U=ot.get(R);if(U)return U;let L=x().finally(()=>ot.delete(R));return ot.set(R,L),L}async function Ue(e){let t=Date.now();try{let n=await e();return{ok:!0,ms:Date.now()-t,data:n}}catch(n){return{ok:!1,ms:Date.now()-t,error:String(n.message||n),status:n.status??null}}}async function Ae(e,t,n){let r=Array.from(e),o=Math.max(1,Math.min(Number(t)||1,r.length||1)),i=new Array(r.length),s=0;return await Promise.all(Array.from({length:o},async()=>{for(;s<r.length;){let a=s++;i[a]=await n(r[a],a)}})),i}var Er,Lt,Sr,Ft,Ar,vr,xr,kr,Ut,Dt,Se,Tr,Ir,Fe,Ki,ne,ot,Bt,Mt,$r,Lr,Dr,z=ke(()=>{rt();Er=new Set([408,425,429,500,502,503,504]),Lt=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),Sr=2,Ft=4e3,Ar=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"aborted")?.get,vr=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"reason")?.get,xr=AbortSignal.prototype.throwIfAborted,kr=EventTarget.prototype.addEventListener,Ut=EventTarget.prototype.removeEventListener,Dt=typeof AbortSignal.any=="function"?AbortSignal.any.bind(AbortSignal):null,Se=e=>e?Ar.call(e):!1,Tr=e=>e?vr.call(e):void 0,Ir=new Set([301,302,303,307,308]),Fe=3,Ki=64*1024,ne=Object.freeze({depth:32,nodes:1e4,fields:1e4,arrayLength:1e4,bytes:1024*1024});ot=new Map,Bt=new WeakMap,Mt=1;$r=new Set(["eth_blockNumber","eth_call","eth_chainId","eth_estimateGas","getHealth","minimumLedgerSlot","net_version","simulateTransaction","web3_clientVersion"]),Lr=new Set(["allMids","l2Book","outcomeMeta","spotClearinghouseState","userFills","meta","metaAndAssetCtxs","perpDexs","candleSnapshot","fundingHistory","openOrders","frontendOpenOrders","clearinghouseState","spotMeta","validatorSummaries","delegatorSummary","delegations","delegatorRewards","delegatorHistory","maxBuilderFee"]);Dr=e=>new Promise(t=>setTimeout(t,e))});var Wt,ns,Gt=ke(()=>{Wt={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}},ns=new Map(Object.values(Wt).map(e=>[e.chainId,e]))});import{Interface as Gr,getAddress as us}from"ethers";var ds,ve=ke(()=>{z();Gt();ds=new Gr(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"])});import D from"node:fs";import Te from"node:path";import{createHash as $n,randomUUID as wt}from"node:crypto";var Ne=1,G=class extends Error{constructor(t,n="DURABLE_STORE_ERROR"){super(t),this.name="DurableStoreError",this.code=n}};function J(e){if(e===null)return"null";if(typeof e=="string"||typeof e=="boolean")return JSON.stringify(e);if(typeof e=="number"){if(!Number.isFinite(e))throw new TypeError("durable store values must contain finite numbers");return JSON.stringify(e)}if(Array.isArray(e))return`[${e.map(J).join(",")}]`;if(e&&typeof e=="object")return`{${Object.keys(e).sort().map(n=>`${JSON.stringify(n)}:${J(e[n])}`).join(",")}}`;throw new TypeError(`durable store values must be JSON-safe, got ${typeof e}`)}function gt(e){return $n("sha256").update(J(e)).digest("hex")}function Ie(e){let t=e(),n=t instanceof Date?t.getTime():typeof t=="string"?Date.parse(t):Number(t);if(!Number.isFinite(n))throw new TypeError("clock must return epoch milliseconds, an ISO string, or a Date");return Math.trunc(n)}function _e(e){return e===void 0?void 0:JSON.parse(JSON.stringify(e))}function Et(e){D.mkdirSync(e,{recursive:!0,mode:448});try{D.chmodSync(e,448)}catch{}}function We(e){try{let t=D.statSync(e);return{...JSON.parse(D.readFileSync(e,"utf8")),mtimeMs:t.mtimeMs}}catch{return null}}function te({filePath:e,kind:t,initialData:n,validateData:r,clock:o=()=>Date.now(),maxBytes:i=4*1024*1024,lockStaleMs:s=3e4,lockWaitMs:a=2e3,lockIdFactory:c=()=>wt()}={}){if(typeof e!="string"||e==="")throw new TypeError("filePath is required");if(!/^[a-z][a-z0-9._-]{0,63}$/i.test(String(t)))throw new TypeError("a bounded store kind is required");if(typeof n!="function"||typeof r!="function")throw new TypeError("initialData and validateData are required");if(!Number.isSafeInteger(i)||i<1024)throw new TypeError("maxBytes must be at least 1024");if(!Number.isSafeInteger(s)||s<1e3)throw new TypeError("lockStaleMs must be at least 1000");if(!Number.isSafeInteger(a)||a<0||a>3e4)throw new TypeError("lockWaitMs must be between 0 and 30000");let y=`${e}.lock`;function f(){let b=n();return r(b),{schemaVersion:Ne,kind:t,generation:0,data:b}}function h(b){let d;try{d=JSON.parse(b)}catch(p){throw new G(`corrupt ${t} snapshot: invalid JSON (${p.message})`,"STORE_CORRUPT")}if(!d||typeof d!="object"||Array.isArray(d))throw new G(`corrupt ${t} snapshot: root must be an object`,"STORE_CORRUPT");if(d.schemaVersion!==Ne)throw new G(`unsupported ${t} schemaVersion ${String(d.schemaVersion)}`,"STORE_SCHEMA");if(d.kind!==t||!Number.isSafeInteger(d.generation)||d.generation<0)throw new G(`corrupt ${t} snapshot metadata`,"STORE_CORRUPT");let{integrity:u,...m}=d;if(typeof u!="string"||!/^[a-f0-9]{64}$/.test(u)||gt(m)!==u)throw new G(`corrupt ${t} snapshot: checksum mismatch`,"STORE_CORRUPT");try{r(d.data)}catch(p){throw new G(`corrupt ${t} snapshot: ${p.message}`,"STORE_CORRUPT")}return m}function w(){if(!D.existsSync(e))return f();let b=D.statSync(e);if(!b.isFile()||b.size>i)throw new G(`${t} snapshot is not a bounded regular file`,"STORE_BOUNDS");try{D.chmodSync(e,384)}catch{}return h(D.readFileSync(e,"utf8"))}function T(){Et(Te.dirname(e));let b=Ie(o),d=String(c()),u=`${JSON.stringify({schemaVersion:1,lockId:d,pid:process.pid,acquiredAt:b})}
3
- `,m=()=>{let g;try{return g=D.openSync(y,"wx",384),D.writeFileSync(g,u,"utf8"),D.fsyncSync(g),D.closeSync(g),{lockId:d}}catch(l){let E=g!==void 0;if(E)try{D.closeSync(g)}catch{}if(E)try{D.unlinkSync(y)}catch{}if(l?.code!=="EEXIST")throw l;return null}},S=Ie(o)+a,A=new Int32Array(new SharedArrayBuffer(4));for(;;){let g=m();if(g)return g;let l=Ie(o),E=We(y),k=!1;if(E){let I=l-Number(E.acquiredAt??E.mtimeMs);k=Number.isFinite(I)&&I>=s}else try{k=l-D.statSync(y).mtimeMs>=s}catch{k=!1}if(k){let I=We(y);if(E?I?.lockId===E.lockId:I===null){try{D.unlinkSync(y)}catch(U){if(U?.code!=="ENOENT")throw U}continue}}let x=S-l;if(x<=0)throw new G(`${t} store is busy`,"STORE_BUSY");Atomics.wait(A,0,0,Math.min(10,x))}}function v(b){if(We(y)?.lockId===b.lockId)try{D.unlinkSync(y)}catch(u){if(u?.code!=="ENOENT")throw u}}function _(b){r(b.data);let d={...b,integrity:gt(b)},u=`${J(d)}
4
- `;if(Buffer.byteLength(u)>i)throw new G(`${t} snapshot exceeds ${i} bytes`,"STORE_BOUNDS");let m=Te.dirname(e);Et(m);let p=Te.join(m,`.${Te.basename(e)}.${process.pid}.${wt()}.tmp`),S;try{S=D.openSync(p,"wx",384),D.writeFileSync(S,u,"utf8"),D.fsyncSync(S),D.closeSync(S),S=void 0,D.renameSync(p,e);try{D.chmodSync(e,384)}catch{}try{let A=D.openSync(m,"r");try{D.fsyncSync(A)}finally{D.closeSync(A)}}catch{}}finally{if(S!==void 0)try{D.closeSync(S)}catch{}try{D.unlinkSync(p)}catch(A){if(A?.code!=="ENOENT")throw A}}}function C(){return _e(w().data)}function $(){let b=w();return{schemaVersion:b.schemaVersion,kind:b.kind,generation:b.generation,data:_e(b.data)}}function M(b){if(typeof b!="function")throw new TypeError("mutator must be a function");let d=T();try{let u=w(),m=_e(u.data),p=b(m,{generation:u.generation,now:Ie(o)});return r(m),_({schemaVersion:Ne,kind:t,generation:u.generation+1,data:m}),_e(p)}finally{v(d)}}return Object.freeze({filePath:e,read:C,inspect:$,mutate:M})}import{createHash as Qn}from"node:crypto";var Ge=Object.freeze(["price","wallet","risk","execution","security","nft","governance","system"]),Ln=new Set(Ge);function Fn(e){if(!Ln.has(e))throw new TypeError(`Unknown watch category: ${String(e)}`);return e}function Un(e={}){let t=e.subscribedCategories??[];if(!Array.isArray(t))throw new TypeError("subscribedCategories must be an array");return t}function Dn(){return{subscribedCategories:[]}}function Bn(e,t){return!(!t||t.notify!==!0||t.category!==e.category||e.watchId!==void 0&&t.id!==e.watchId)}function St(e,t=Dn(),n){if(!e||typeof e!="object")throw new TypeError("alert must be an object");return Fn(e.category),Un(t).includes(e.category)?{deliver:!0,reason:"category-subscribed"}:Bn(e,n)?{deliver:!0,reason:"watch-opt-in"}:{deliver:!1,reason:"not-subscribed"}}var Mn=(process.env.ORACLE_REDACT_SECRETS??"true").toLowerCase(),qn=["1","true","yes","on"].includes(Mn),jn=[/sk-[A-Za-z0-9_-]{10,}/g,/sk_live_[A-Za-z0-9]{10,}/g,/sk_test_[A-Za-z0-9]{10,}/g,/ghp_[A-Za-z0-9]{10,}/g,/github_pat_[A-Za-z0-9_]{10,}/g,/gho_[A-Za-z0-9]{10,}/g,/ghs_[A-Za-z0-9]{10,}/g,/xox[baprs]-[A-Za-z0-9-]{10,}/g,/AIza[A-Za-z0-9_-]{30,}/g,/AKIA[A-Z0-9]{16}/g,/pplx-[A-Za-z0-9]{10,}/g,/hf_[A-Za-z0-9]{10,}/g,/xai-[A-Za-z0-9]{30,}/g,/gsk_[A-Za-z0-9]{10,}/g,/npm_[A-Za-z0-9]{10,}/g,/tvly-[A-Za-z0-9]{10,}/g,/Bearer\s+[A-Za-z0-9\-._~+/]+=*/gi],Hn=/\b0x[a-fA-F0-9]{64}\b/g,Vn=/-----BEGIN (?:RSA |EC |OPENSSH |ENCRYPTED )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH |ENCRYPTED )?PRIVATE KEY-----/g,zn=/\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g,Kn=/\b([A-Z][A-Z0-9_]{0,40}(?:API_?KEY|TOKEN|SECRET|PASSWORD|PASSWD|PRIVATE_?KEY|MNEMONIC|SEED|AUTH)[A-Z0-9_]{0,20})\s*=\s*(['"]?)(\S+)\2/g,Wn=/^(?:export\s+)?((?:api[_-]?key|token|secret|password|private[_-]?key|mnemonic|seed[_-]?phrase|authorization))\s*[:=]\s*(['"]?)([^\s&]+)\2/gim,Gn=/("(?:api[_-]?key|apiKey|access[_-]?token|refresh[_-]?token|client[_-]?secret|private[_-]?key|privateKey|secret|password|authorization|bearer|mnemonic|seedPhrase)"\s*:\s*")([^"]{6,})(")/gi,Yn=new Set(["access_token","refresh_token","id_token","token","api_key","apikey","client_secret","password","auth","jwt","session","secret","key","code","signature","x-amz-signature","private_key","authorization"]),wi=new Set([...Yn].map(e=>e.replace(/[^a-z0-9]/gi,"").toLowerCase()));function Jn(e){let t=String(e??"");return t.length<18?"[REDACTED]":`${t.slice(0,6)}\u2026${t.slice(-4)}`}function Zn(e){return`\xABredacted:${String(e??"").slice(0,4)}\u2026\xBB`}function At(e,t={}){if(e==null)return e;let n=typeof e=="string"?e:String(e);if(!n||!(t.force||qn))return n;let r=t.fileRead?Zn:Jn;n=n.replace(Vn,"[REDACTED_PRIVATE_KEY]"),n=n.replace(Hn,"[REDACTED_EVM_KEY]"),n=n.replace(zn,o=>r(o));for(let o of jn)o.lastIndex=0,n=n.replace(o,i=>r(i));return n=n.replace(Kn,(o,i,s,a)=>/^(?:os\.(?:getenv|environ)|process\.env|\$ENV\{)/.test(a)?`${i}=${s||""}${a}${s||""}`:`${i}=${s||""}${r(a)}${s||""}`),n=n.replace(Wn,(o,i,s,a)=>o.replace(a,r(a))),n=n.replace(Gn,(o,i,s,a)=>`${i}${r(s)}${a}`),n}var Y=1,vt=Object.freeze(["alert","prepare"]),xt=Object.freeze(["LIVE","STALE","UNAVAILABLE","UNKNOWN"]),Xn=/^[A-Za-z0-9](?:[A-Za-z0-9._:-]{0,126}[A-Za-z0-9])?$/,er=new Set(["secret","webhooksecret","password","passphrase","privatekey","mnemonic","seed","authorization","apikey","accesstoken","bearertoken","signingkey"]);function B(e,t){for(let[n,r]of[["tenantId",e],["workflowId",t]])if(typeof r!="string"||!Xn.test(r))throw new TypeError(`${n} must be a bounded, non-wildcard scope id`);return{tenantId:e,workflowId:t}}function P(e,t,{min:n=1,max:r=256}={}){if(typeof t!="string"||t.length<n||t.length>r||/[\u0000-\u001f\u007f]/.test(t))throw new TypeError(`${e} must be a string between ${n} and ${r} characters without control bytes`);return t}function Z(e){if(!Ge.includes(e))throw new TypeError(`Unknown watch category: ${String(e)}`);return e}function Oe(e){if(!vt.includes(e))throw new TypeError(`notification work kind must be alert or prepare, got ${String(e)}`);return e}function de(e,t="value",n=new Set){if(e!=null){if(typeof e=="function"||typeof e=="symbol"||typeof e=="bigint")throw new TypeError(`${t} must be JSON-safe`);if(typeof e=="number"&&!Number.isFinite(e))throw new TypeError(`${t} must contain finite numbers`);if(typeof e=="object"){if(n.has(e))throw new TypeError(`${t} must not contain cycles`);if(!Array.isArray(e)&&Object.getPrototypeOf(e)!==Object.prototype&&Object.getPrototypeOf(e)!==null)throw new TypeError(`${t} must contain plain JSON objects only`);if(n.add(e),Array.isArray(e))e.forEach((r,o)=>de(r,`${t}[${o}]`,n));else for(let[r,o]of Object.entries(e)){let i=r.toLowerCase().replace(/[^a-z0-9]/g,"");if(er.has(i))throw new TypeError(`${t}.${r} may contain secret material and is rejected`);de(o,`${t}.${r}`,n)}n.delete(e)}}}function Ye(e,t,n){if(e==null)return e;if(typeof e=="string"){let o=At(e,{force:!0});if(o!==e)throw new TypeError(`${t} may contain secret material and is rejected`);return o}if(typeof e!="object")return e;if(n.has(e))throw new TypeError(`${t} must not contain cycles`);if(n.add(e),Array.isArray(e)){let o=e.map((i,s)=>Ye(i,`${t}[${s}]`,n));return n.delete(e),o}let r={};for(let[o,i]of Object.entries(e))r[o]=Ye(i,`${t}.${o}`,n);return n.delete(e),r}function Q(e,{name:t="payload",maxBytes:n=64*1024}={}){de(e,t);let r=Ye(e,t,new Set),o;try{o=J(r)}catch(i){throw new TypeError(`${t} must be JSON-safe: ${i.message}`)}if(Buffer.byteLength(o)>n)throw new TypeError(`${t} exceeds ${n} bytes`);return JSON.parse(o)}function se(e){let t=typeof e=="string"?e.toUpperCase():e?.status?.toUpperCase?.();return xt.includes(t)?t:"UNKNOWN"}function be(e){return Qn("sha256").update(J(e)).digest("hex")}function we({category:e,preferences:t,watch:n,watchId:r}={}){Z(e);let o=St({category:e,...r===void 0?{}:{watchId:r}},t,n);if(!o.deliver){let i=new Error(`notification category ${e} is not opted in`);throw i.name="NotificationOptInError",i.code="NOTIFICATION_NOT_OPTED_IN",i}return o}function O(e){if(!Number.isFinite(e))throw new TypeError("time must be finite");return new Date(Math.trunc(e)).toISOString()}function j(e){let t=e(),n=t instanceof Date?t.getTime():typeof t=="string"?Date.parse(t):Number(t);if(!Number.isFinite(n))throw new TypeError("clock must return epoch milliseconds, an ISO string, or a Date");return Math.trunc(n)}function tr(e,{onError:t=()=>{}}={}){if(typeof e!="function")throw new TypeError("event append function is required");return Object.freeze({append(n){try{let r=e(Object.freeze({...n}));r&&typeof r.then=="function"&&r.catch(t)}catch(r){t(r)}}})}function W(e,t){if(e){if(typeof e.append!="function")throw new TypeError("eventSink must expose append(event)");e.append(t)}}import kt from"node:path";import{homedir as nr}from"node:os";import{randomUUID as Tt}from"node:crypto";var Je=1,_t=new Set(["pending","leased","completed"]),rr=5*366*24*60;function or(e=process.env){let t=e.ORACLE_CONFIG_DIR||kt.join(nr(),".config","oracle");return kt.join(t,"notification-schedules.v1.json")}function Ce(e,t,n,r){if(!/^\d+$/.test(e))throw new TypeError(`invalid ${r} cron field`);let o=Number(e);if(!Number.isSafeInteger(o)||o<t||o>n)throw new TypeError(`${r} cron field is out of range`);return o}function ge(e,t,n,r,{weekday:o=!1}={}){let i=new Set,s=e==="*";if(!e||e.length>80)throw new TypeError(`invalid ${r} cron field`);for(let a of e.split(",")){if(!a)throw new TypeError(`invalid ${r} cron field`);let[c,y,f]=a.split("/");if(f!==void 0)throw new TypeError(`invalid ${r} cron step`);let h=y===void 0?1:Ce(y,1,n-t+1,`${r} step`),w,T;if(c==="*")w=t,T=n;else if(c.includes("-")){let v=c.split("-");if(v.length!==2)throw new TypeError(`invalid ${r} cron range`);if(w=Ce(v[0],t,n,r),T=Ce(v[1],t,n,r),T<w)throw new TypeError(`invalid descending ${r} cron range`)}else if(w=Ce(c,t,n,r),T=w,y!==void 0)throw new TypeError(`cron step requires * or a range in ${r}`);for(let v=w;v<=T;v+=h)i.add(o&&v===7?0:v)}if(i.size===0)throw new TypeError(`empty ${r} cron field`);return{values:i,wildcard:s}}function Re(e){if(typeof e!="string"||e.length>160)throw new TypeError("schedule must be a bounded string");let t=e.trim().toLowerCase();if(!t)throw new TypeError("schedule is required");if(t==="hourly")return Object.freeze({type:"interval",intervalMs:36e5,source:t});if(t==="daily")return Object.freeze({type:"interval",intervalMs:864e5,source:t});let n=t.match(/^every\s+([1-9]\d{0,5})\s*([mhd])$/);if(n){let s=n[2]==="m"?6e4:n[2]==="h"?36e5:864e5,a=Number(n[1])*s;if(!Number.isSafeInteger(a)||a<6e4||a>366*864e5)throw new TypeError("schedule interval must be between one minute and 366 days");return Object.freeze({type:"interval",intervalMs:a,source:t})}let r=t.match(/^at\s+(.+)$/);if(r){let s=r[1];if(!/^\d{4}-\d{2}-\d{2}t\d{2}:\d{2}:\d{2}(?:\.\d{3})?z$/.test(s))throw new TypeError("one-time schedule must use an ISO-8601 UTC time");let a=Date.parse(s);if(!Number.isFinite(a))throw new TypeError("invalid one-time schedule time");return Object.freeze({type:"at",atMs:a,source:`at ${new Date(a).toISOString()}`})}let o=t.split(/\s+/);if(o.length!==5)throw new TypeError(`invalid schedule: ${e}`);let i={minute:ge(o[0],0,59,"minute"),hour:ge(o[1],0,23,"hour"),day:ge(o[2],1,31,"day-of-month"),month:ge(o[3],1,12,"month"),weekday:ge(o[4],0,7,"day-of-week",{weekday:!0})};return Object.freeze({type:"cron",fields:i,source:t})}function Pe(e,t){let n=typeof e=="string"?Re(e):e,r=t instanceof Date?t.getTime():typeof t=="string"?Date.parse(t):Number(t);if(!Number.isFinite(r))throw new TypeError("after must be a valid time");if(n.type==="interval")return Math.trunc(r)+n.intervalMs;if(n.type==="at")return n.atMs>r?n.atMs:null;if(n.type!=="cron")throw new TypeError("unknown parsed schedule type");let o=Math.floor(r/6e4)*6e4+6e4;for(let i=0;i<rr;i+=1,o+=6e4){let s=new Date(o),a=n.fields,c=a.day.values.has(s.getUTCDate()),y=a.weekday.values.has(s.getUTCDay()),f=a.day.wildcard&&a.weekday.wildcard?!0:a.day.wildcard?y:a.weekday.wildcard?c:c||y;if(a.minute.values.has(s.getUTCMinutes())&&a.hour.values.has(s.getUTCHours())&&a.month.values.has(s.getUTCMonth()+1)&&f)return o}throw new RangeError("cron schedule has no occurrence within five years")}function ir(e){if(!e||e.schemaVersion!==Y)throw new TypeError("invalid schedule record version");if(B(e.tenantId,e.workflowId),P("schedule id",e.id,{max:128}),P("idempotencyKey",e.idempotencyKey,{max:160}),P("schedule name",e.name,{max:160}),Oe(e.kind),Z(e.category),Re(e.schedule),e.startAt!==null&&!Number.isFinite(Date.parse(e.startAt)))throw new TypeError("invalid schedule startAt");if(typeof e.enabled!="boolean")throw new TypeError("schedule enabled must be boolean");if(e.nextRunAt!==null&&!Number.isFinite(Date.parse(e.nextRunAt)))throw new TypeError("invalid schedule nextRunAt");if(!Number.isFinite(Date.parse(e.createdAt))||!Number.isFinite(Date.parse(e.updatedAt)))throw new TypeError("invalid schedule timestamps");if(Q(e.payload),!/^[a-f0-9]{64}$/.test(e.definitionFingerprint))throw new TypeError("invalid schedule fingerprint")}function sr(e){if(!e||e.schemaVersion!==Y)throw new TypeError("invalid scheduled work version");if(B(e.tenantId,e.workflowId),P("work id",e.id,{max:128}),P("schedule id",e.scheduleId,{max:128}),P("work idempotencyKey",e.idempotencyKey,{max:512}),Oe(e.kind),Z(e.category),!_t.has(e.status))throw new TypeError("invalid scheduled work status");if(!Number.isSafeInteger(e.attempts)||e.attempts<0)throw new TypeError("invalid scheduled work attempts");if(e.executionAllowed!==!1||e.custody!=="none")throw new TypeError("scheduled work crossed the custody boundary");if(!Number.isFinite(Date.parse(e.scheduledFor))||!Number.isFinite(Date.parse(e.createdAt)))throw new TypeError("invalid work time");if(e.lease!==null&&(P("lease owner",e.lease.owner,{max:128}),P("lease token",e.lease.token,{max:160}),!Number.isFinite(Date.parse(e.lease.until))))throw new TypeError("invalid work lease");Q(e.payload)}function ar(e,t){return n=>{if(!n||n.schemaVersion!==Je||!Array.isArray(n.schedules)||!Array.isArray(n.work))throw new TypeError("invalid schedule store schema");if(n.schedules.length>e||n.work.length>t)throw new TypeError("schedule store record bound exceeded");let r=new Set,o=new Set;for(let a of n.schedules){if(ir(a),r.has(a.id))throw new TypeError("duplicate schedule id");let c=`${a.tenantId}\0${a.workflowId}\0${a.idempotencyKey}`;if(o.has(c))throw new TypeError("duplicate scoped schedule idempotency key");r.add(a.id),o.add(c)}let i=new Set,s=new Set;for(let a of n.work){if(sr(a),i.has(a.id)||s.has(a.idempotencyKey))throw new TypeError("duplicate scheduled work identity");i.add(a.id),s.add(a.idempotencyKey)}}}function X(e,t,n){return e.tenantId===t&&e.workflowId===n}function It(e,t,n){if(e.status!=="leased"||!e.lease||e.lease.token!==t)throw new Error("scheduled work lease token does not match");if(Date.parse(e.lease.until)<=n)throw new Error("scheduled work lease expired")}function cr({filePath:e=or(),clock:t=()=>Date.now(),idFactory:n=()=>Tt(),leaseTokenFactory:r=()=>Tt(),eventSink:o,maxSchedules:i=1e3,maxWork:s=5e3,maxBytes:a=8*1024*1024}={}){if(!Number.isSafeInteger(i)||i<1||!Number.isSafeInteger(s)||s<1)throw new TypeError("schedule record bounds must be positive integers");let c=te({filePath:e,kind:"oracle-notification-schedules",clock:t,maxBytes:a,initialData:()=>({schemaVersion:Je,schedules:[],work:[]}),validateData:ar(i,s)});function y(b={},d={}){let u=j(t),{tenantId:m,workflowId:p}=B(b.tenantId,b.workflowId),S=P("idempotencyKey",b.idempotencyKey,{max:160}),A=P("schedule name",b.name??S,{max:160}),g=Oe(b.kind??b.mode),l=Z(b.category),E=Re(b.schedule),k=Q(b.payload??{});g==="alert"&&we({category:l,preferences:d.preferences??b.preferences,watch:d.watch??b.watch,watchId:b.watchId});let x={tenantId:m,workflowId:p,idempotencyKey:S,name:A,kind:g,category:l,schedule:E.source,payload:k,startAt:b.startAt??null},I=be(x),R=Pe(E,u);if(b.startAt!==void 0){if(typeof b.startAt!="string"||!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/.test(b.startAt))throw new TypeError("startAt must be an ISO-8601 UTC time");if(R=Date.parse(b.startAt),!Number.isFinite(R)||R<=u)throw new TypeError("startAt must be in the future")}if(R===null||R<=u)throw new TypeError("schedule must have a future occurrence");let U=c.mutate(L=>{let N=L.schedules.find(q=>X(q,m,p)&&q.idempotencyKey===S);if(N){if(N.definitionFingerprint!==I){let q=new Error("schedule idempotency key was reused with different content");throw q.code="IDEMPOTENCY_CONFLICT",q}return{...N,duplicate:!0}}if(L.schedules.length>=i)throw new Error("schedule capacity reached");let F=O(u),K={schemaVersion:Y,id:P("generated schedule id",String(n()),{max:128}),...x,definitionFingerprint:I,enabled:b.enabled!==!1,createdAt:F,updatedAt:F,lastMaterializedAt:null,nextRunAt:O(R)};return L.schedules.push(K),K});return U.duplicate||W(o,{type:"notification.schedule.created",at:O(u),tenantId:m,workflowId:p,scheduleId:U.id,kind:g,category:l}),U}function f({tenantId:b,workflowId:d}={}){return B(b,d),c.read().schedules.filter(u=>X(u,b,d))}function h({tenantId:b,workflowId:d,id:u,enabled:m}={}){if(B(b,d),typeof m!="boolean")throw new TypeError("enabled must be boolean");let p=j(t),S=c.mutate(A=>{let g=A.schedules.find(l=>X(l,b,d)&&l.id===u);if(!g)return null;if(g.enabled=m,g.updatedAt=O(p),m&&g.nextRunAt===null){let l=Pe(g.schedule,p);if(l===null)throw new Error("a completed one-time schedule cannot be re-enabled");g.nextRunAt=O(l)}return g});return S&&W(o,{type:"notification.schedule.enabled",at:O(p),tenantId:b,workflowId:d,scheduleId:u,enabled:m}),S}function w({tenantId:b,workflowId:d,id:u}={}){B(b,d);let m=j(t),p=c.mutate(S=>{let A=S.schedules.findIndex(g=>X(g,b,d)&&g.id===u);return A<0?!1:(S.schedules.splice(A,1),!0)});return p&&W(o,{type:"notification.schedule.removed",at:O(m),tenantId:b,workflowId:d,scheduleId:u}),p}function T({tenantId:b,workflowId:d,limit:u=100,until:m}={}){if(B(b,d),!Number.isSafeInteger(u)||u<1||u>1e3)throw new TypeError("limit must be between 1 and 1000");let p=m===void 0?j(t):typeof m=="string"?Date.parse(m):Number(m);if(!Number.isFinite(p))throw new TypeError("until must be a valid time");let S=c.mutate(A=>{let g=[],l=new Set(A.work.map(k=>k.idempotencyKey)),E=A.schedules.filter(k=>X(k,b,d)&&k.enabled&&k.nextRunAt!==null&&Date.parse(k.nextRunAt)<=p).sort((k,x)=>k.nextRunAt.localeCompare(x.nextRunAt)||k.id.localeCompare(x.id));for(let k of E){for(;k.enabled&&k.nextRunAt!==null&&Date.parse(k.nextRunAt)<=p&&g.length<u;){let x=k.nextRunAt,I=`${b}:${d}:${k.id}:${x}`;if(!l.has(I)){if(A.work.length>=s)throw new Error("scheduled work capacity reached");let U={schemaVersion:Y,id:P("generated work id",String(n()),{max:128}),tenantId:b,workflowId:d,scheduleId:k.id,idempotencyKey:I,kind:k.kind,category:k.category,payload:k.payload,evidence:se(k.payload?.evidence),scheduledFor:x,createdAt:O(p),status:"pending",attempts:0,lease:null,completedAt:null,custody:"none",executionAllowed:!1};A.work.push(U),g.push(U),l.add(I)}k.lastMaterializedAt=x;let R=Pe(k.schedule,Date.parse(x));k.nextRunAt=R===null?null:O(R),R===null&&(k.enabled=!1),k.updatedAt=O(p)}if(g.length>=u)break}return g});for(let A of S)W(o,{type:"notification.schedule.work.created",at:O(p),tenantId:b,workflowId:d,scheduleId:A.scheduleId,workId:A.id,kind:A.kind,evidence:A.evidence});return S}function v({tenantId:b,workflowId:d,status:u}={}){if(B(b,d),u!==void 0&&!_t.has(u))throw new TypeError("invalid work status");return c.read().work.filter(m=>X(m,b,d)&&(u===void 0||m.status===u))}function _({tenantId:b,workflowId:d}={}){B(b,d);let u=j(t);return c.mutate(m=>{let p=0;for(let S of m.work)X(S,b,d)&&S.status==="leased"&&Date.parse(S.lease.until)<=u&&(S.status="pending",S.lease=null,p+=1);return p})}function C({tenantId:b,workflowId:d,workerId:u,limit:m=1,leaseMs:p=3e4}={}){if(B(b,d),P("workerId",u,{max:128}),!Number.isSafeInteger(m)||m<1||m>100)throw new TypeError("claim limit must be between 1 and 100");if(!Number.isSafeInteger(p)||p<1e3||p>36e5)throw new TypeError("leaseMs must be between 1000 and 3600000");let S=j(t),A=c.mutate(g=>{let l=g.work.filter(E=>X(E,b,d)&&(E.status==="pending"||E.status==="leased"&&Date.parse(E.lease.until)<=S)).sort((E,k)=>E.scheduledFor.localeCompare(k.scheduledFor)||E.id.localeCompare(k.id)).slice(0,m);for(let E of l)E.status="leased",E.attempts+=1,E.lease={owner:u,token:P("generated lease token",String(r()),{max:160}),until:O(S+p)};return l});for(let g of A)W(o,{type:"notification.schedule.work.claimed",at:O(S),tenantId:b,workflowId:d,workId:g.id,attempt:g.attempts});return A}function $({tenantId:b,workflowId:d,id:u,leaseToken:m}={}){B(b,d);let p=j(t),S=c.mutate(A=>{let g=A.work.find(l=>X(l,b,d)&&l.id===u);return g?(It(g,m,p),g.status="completed",g.lease=null,g.completedAt=O(p),g):null});return S&&W(o,{type:"notification.schedule.work.completed",at:O(p),tenantId:b,workflowId:d,workId:u}),S}function M({tenantId:b,workflowId:d,id:u,leaseToken:m}={}){B(b,d);let p=j(t);return c.mutate(S=>{let A=S.work.find(g=>X(g,b,d)&&g.id===u);return A?(It(A,m,p),A.status="pending",A.lease=null,A):null})}return Object.freeze({filePath:e,createSchedule:y,listSchedules:f,setEnabled:h,removeSchedule:w,materializeDue:T,listWork:v,recoverExpiredWork:_,claimWork:C,completeWork:$,releaseWork:M,inspect:c.inspect})}import Nt from"node:path";import{homedir as lr}from"node:os";import{randomUUID as Ot}from"node:crypto";var Ze=1,Pt=Object.freeze(["pending","leased","delivered","dead_letter"]),Rt=new Set(Pt);function ur(e=process.env){let t=e.ORACLE_CONFIG_DIR||Nt.join(lr(),".config","oracle");return Nt.join(t,"notification-outbox.v1.json")}function dr(e){if(!e||e.schemaVersion!==Y)throw new TypeError("invalid outbox record version");if(B(e.tenantId,e.workflowId),P("message id",e.id,{max:128}),P("idempotencyKey",e.idempotencyKey,{max:200}),P("channel",e.channel,{max:32}),e.channel!=="webhook")throw new TypeError("P1 outbox supports webhook only");if(Z(e.category),!Rt.has(e.status))throw new TypeError("invalid outbox state");if(!Number.isSafeInteger(e.attempts)||e.attempts<0)throw new TypeError("outbox attempts must be monotonic non-negative integers");if(!Number.isSafeInteger(e.maxAttempts)||e.maxAttempts<1||e.maxAttempts>100)throw new TypeError("invalid outbox maxAttempts");if(!Number.isFinite(Date.parse(e.createdAt))||!Number.isFinite(Date.parse(e.updatedAt))||!Number.isFinite(Date.parse(e.nextAttemptAt)))throw new TypeError("invalid outbox timestamp");if(e.destinationId!==null&&P("destinationId",e.destinationId,{max:160}),!/^[a-f0-9]{64}$/.test(e.contentFingerprint))throw new TypeError("invalid outbox fingerprint");if(e.lease!==null&&(P("lease owner",e.lease.owner,{max:128}),P("lease token",e.lease.token,{max:160}),!Number.isFinite(Date.parse(e.lease.until))))throw new TypeError("invalid outbox lease");if(e.lastError!==null&&P("lastError",e.lastError,{max:512}),e.replayOf!==null&&P("replayOf",e.replayOf,{max:128}),!Array.isArray(e.failures)||e.failures.length>100)throw new TypeError("invalid outbox failure records");for(let t of e.failures){if(!t||!Number.isSafeInteger(t.attempt)||t.attempt<1)throw new TypeError("invalid outbox failure attempt");if(!Number.isFinite(Date.parse(t.at)))throw new TypeError("invalid outbox failure time");if(P("failure code",t.code,{max:512}),typeof t.retryable!="boolean")throw new TypeError("failure retryable must be boolean");if(t.terminal!==!0&&t.terminal!==!1)throw new TypeError("failure terminal must be boolean")}if(e.executionAllowed!==!1||e.custody!=="none")throw new TypeError("outbox crossed the custody boundary");Q(e.payload)}function fr(e){return t=>{if(!t||t.schemaVersion!==Ze||!Array.isArray(t.messages))throw new TypeError("invalid outbox store schema");if(t.messages.length>e)throw new TypeError("outbox record bound exceeded");let n=new Set,r=new Set;for(let o of t.messages){dr(o);let i=`${o.tenantId}\0${o.workflowId}\0${o.idempotencyKey}`;if(n.has(o.id)||r.has(i))throw new TypeError("duplicate outbox identity");n.add(o.id),r.add(i)}}}function ee(e,t,n){return e.tenantId===t&&e.workflowId===n}function pr(e){let t=e&&typeof e=="object"?e.code:null;if(typeof t=="string"&&/^[A-Z][A-Z0-9_.:-]{0,63}$/.test(t))return`delivery failed: ${t}`;let n=e&&typeof e=="object"?Number(e.status??e.statusCode):NaN;return Number.isInteger(n)&&n>=100&&n<=599?`delivery failed: HTTP_${n}`:"delivery failed"}function Ct(e,t,n){if(e.status!=="leased"||!e.lease||e.lease.token!==t)throw new Error("outbox lease token does not match");if(Date.parse(e.lease.until)<=n)throw new Error("outbox lease expired")}function mr({filePath:e=ur(),clock:t=()=>Date.now(),idFactory:n=()=>Ot(),leaseTokenFactory:r=()=>Ot(),eventSink:o,maxRecords:i=1e4,maxBytes:s=16*1024*1024,maxAttempts:a=5,baseBackoffMs:c=1e3,maxBackoffMs:y=36e5}={}){for(let[u,m,p,S]of[["maxRecords",i,1,1e5],["maxAttempts",a,1,100],["baseBackoffMs",c,1,864e5],["maxBackoffMs",y,1,7*864e5]])if(!Number.isSafeInteger(m)||m<p||m>S)throw new TypeError(`${u} is out of range`);if(c>y)throw new TypeError("baseBackoffMs cannot exceed maxBackoffMs");let f=te({filePath:e,kind:"oracle-notification-outbox",clock:t,maxBytes:s,initialData:()=>({schemaVersion:Ze,messages:[]}),validateData:fr(i)}),h=u=>Math.min(y,c*2**Math.min(30,Math.max(0,u-1)));function w(u,m){return we({category:u.category,preferences:m?.preferences??u.preferences,watch:m?.watch??u.watch,watchId:u.watchId})}function T(u){let{tenantId:m,workflowId:p}=B(u.tenantId,u.workflowId),S=Z(u.category),A=P("idempotencyKey",u.idempotencyKey,{max:200}),g=u.channel??"webhook";if(g!=="webhook")throw new TypeError("P1 outbox supports webhook only; fiat/P2 channels are not available");let l=u.destinationId==null?null:P("destinationId",u.destinationId,{max:160}),E=Q(u.payload??{}),k=se(u.evidence??u.payload?.evidence),x={tenantId:m,workflowId:p,idempotencyKey:A,category:S,channel:g,destinationId:l,payload:E,evidence:k};return{...x,contentFingerprint:be(x)}}function v(u={},m={}){w(u,m);let p=T(u),S=j(t),A=f.mutate(g=>{let l=g.messages.find(x=>ee(x,p.tenantId,p.workflowId)&&x.idempotencyKey===p.idempotencyKey);if(l){if(l.contentFingerprint!==p.contentFingerprint){let x=new Error("outbox idempotency key was reused with different content");throw x.code="IDEMPOTENCY_CONFLICT",x}return{...l,duplicate:!0}}if(g.messages.length>=i)throw new Error("outbox capacity reached");let E=O(S),k={schemaVersion:Y,id:P("generated message id",String(n()),{max:128}),...p,status:"pending",attempts:0,maxAttempts:u.maxAttempts===void 0?a:Number(u.maxAttempts),nextAttemptAt:E,lease:null,lastError:null,failures:[],createdAt:E,updatedAt:E,deliveredAt:null,deadLetteredAt:null,replayOf:null,custody:"none",executionAllowed:!1};if(!Number.isSafeInteger(k.maxAttempts)||k.maxAttempts<1||k.maxAttempts>a)throw new TypeError(`message maxAttempts must be between 1 and ${a}`);return g.messages.push(k),k});return A.duplicate||W(o,{type:"notification.outbox.enqueued",at:O(S),tenantId:p.tenantId,workflowId:p.workflowId,messageId:A.id,category:p.category,evidence:p.evidence}),A}function _({tenantId:u,workflowId:m,status:p}={}){if(B(u,m),p!==void 0&&!Rt.has(p))throw new TypeError("invalid outbox status");return f.read().messages.filter(S=>ee(S,u,m)&&(p===void 0||S.status===p))}function C({tenantId:u,workflowId:m}={}){B(u,m);let p=j(t),S=f.mutate(A=>{let g=[];for(let l of A.messages)!ee(l,u,m)||l.status!=="leased"||Date.parse(l.lease.until)>p||(l.lease=null,l.updatedAt=O(p),l.attempts>=l.maxAttempts?(l.status="dead_letter",l.lastError="delivery lease expired after final attempt",l.deadLetteredAt=O(p)):(l.status="pending",l.lastError="delivery lease expired before acknowledgement",l.nextAttemptAt=O(p+h(l.attempts))),g.push(l));return g});for(let A of S)W(o,{type:"notification.outbox.lease_recovered",at:O(p),tenantId:u,workflowId:m,messageId:A.id,status:A.status,attempt:A.attempts});return S}function $({tenantId:u,workflowId:m,workerId:p,limit:S=1,leaseMs:A=3e4}={}){if(B(u,m),P("workerId",p,{max:128}),!Number.isSafeInteger(S)||S<1||S>100)throw new TypeError("claim limit must be between 1 and 100");if(!Number.isSafeInteger(A)||A<1e3||A>36e5)throw new TypeError("leaseMs must be between 1000 and 3600000");let g=j(t),l=f.mutate(E=>{for(let x of E.messages)!ee(x,u,m)||x.status!=="leased"||Date.parse(x.lease.until)>g||(x.lease=null,x.updatedAt=O(g),x.attempts>=x.maxAttempts?(x.status="dead_letter",x.lastError="delivery lease expired after final attempt",x.deadLetteredAt=O(g)):(x.status="pending",x.lastError="delivery lease expired before acknowledgement",x.nextAttemptAt=O(g)));let k=E.messages.filter(x=>ee(x,u,m)&&x.status==="pending"&&Date.parse(x.nextAttemptAt)<=g&&x.attempts<x.maxAttempts).sort((x,I)=>x.nextAttemptAt.localeCompare(I.nextAttemptAt)||x.createdAt.localeCompare(I.createdAt)||x.id.localeCompare(I.id)).slice(0,S);for(let x of k)x.status="leased",x.attempts+=1,x.updatedAt=O(g),x.lease={owner:p,token:P("generated lease token",String(r()),{max:160}),until:O(g+A)};return k});for(let E of l)W(o,{type:"notification.outbox.claimed",at:O(g),tenantId:u,workflowId:m,messageId:E.id,attempt:E.attempts});return l}function M({tenantId:u,workflowId:m,id:p,leaseToken:S}={}){B(u,m);let A=j(t),g=f.mutate(l=>{let E=l.messages.find(k=>ee(k,u,m)&&k.id===p);return E?(Ct(E,S,A),E.status="delivered",E.lease=null,E.updatedAt=O(A),E.deliveredAt=O(A),E):null});return g&&W(o,{type:"notification.outbox.delivered",at:O(A),tenantId:u,workflowId:m,messageId:p,attempt:g.attempts}),g}function b({tenantId:u,workflowId:m,id:p,leaseToken:S,error:A,retryable:g=!0}={}){if(B(u,m),typeof g!="boolean")throw new TypeError("retryable must be boolean");let l=j(t),E=pr(A),k=f.mutate(x=>{let I=x.messages.find(U=>ee(U,u,m)&&U.id===p);if(!I)return null;Ct(I,S,l),I.lease=null,I.lastError=E;let R=!g||I.attempts>=I.maxAttempts;return I.failures=[...I.failures??[],{attempt:I.attempts,at:O(l),code:E,retryable:g,terminal:R}],I.updatedAt=O(l),R?(I.status="dead_letter",I.deadLetteredAt=O(l)):(I.status="pending",I.nextAttemptAt=O(l+h(I.attempts))),I});return k&&W(o,{type:k.status==="dead_letter"?"notification.outbox.dead_lettered":"notification.outbox.retry_scheduled",at:O(l),tenantId:u,workflowId:m,messageId:p,attempt:k.attempts,nextAttemptAt:k.nextAttemptAt}),k}function d({tenantId:u,workflowId:m,id:p,idempotencyKey:S}={},A={}){B(u,m);let g=P("replay idempotencyKey",S,{max:200}),E=f.read().messages.find(I=>ee(I,u,m)&&I.id===p);if(!E)return null;if(E.status!=="dead_letter"&&E.status!=="delivered")throw new Error("only delivered or dead-letter messages may be replayed");w({...E,preferences:A.preferences,watch:A.watch},A);let k=j(t),x=f.mutate(I=>{let R=I.messages.find(q=>ee(q,u,m)&&q.id===p);if(!R||R.status!=="dead_letter"&&R.status!=="delivered")throw new Error("replay source changed state");let U=I.messages.find(q=>ee(q,u,m)&&q.idempotencyKey===g),L={tenantId:u,workflowId:m,idempotencyKey:g,category:R.category,channel:R.channel,destinationId:R.destinationId,payload:R.payload,evidence:R.evidence},N=be(L);if(U){if(U.contentFingerprint!==N||U.replayOf!==p){let q=new Error("replay idempotency key was reused with different content");throw q.code="IDEMPOTENCY_CONFLICT",q}return{...U,duplicate:!0}}if(I.messages.length>=i)throw new Error("outbox capacity reached");let F=O(k),K={schemaVersion:Y,id:P("generated message id",String(n()),{max:128}),...L,contentFingerprint:N,status:"pending",attempts:0,maxAttempts:R.maxAttempts,nextAttemptAt:F,lease:null,lastError:null,failures:[],createdAt:F,updatedAt:F,deliveredAt:null,deadLetteredAt:null,replayOf:p,custody:"none",executionAllowed:!1};return I.messages.push(K),K});return x.duplicate||W(o,{type:"notification.outbox.replayed",at:O(k),tenantId:u,workflowId:m,messageId:x.id,replayOf:p}),x}return Object.freeze({filePath:e,enqueue:v,list:_,claim:$,acknowledge:M,fail:b,recoverExpiredLeases:C,replay:d,backoffForAttempt:h,inspect:f.inspect})}import He from"node:path";import{homedir as pn}from"node:os";import{readFileSync as Do}from"node:fs";import{createHash as Bo}from"node:crypto";z();z();import{getAddress as Kr}from"ethers";import{types as Ht}from"node:util";function st(e){if(!e||typeof e!="object"||Ht.isProxy(e)||Array.isArray(e))return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function ie(e,t="provider response",n=0){if(n>64)throw new Error(`${t} exceeds the JSON nesting bound`);if(e===null||typeof e=="string"||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e))return e;if(Array.isArray(e)){if(Ht.isProxy(e)||e.length>1e5)throw new Error(`${t} contains an invalid array`);let o=new Array(e.length);for(let i=0;i<e.length;i+=1){let s=Object.getOwnPropertyDescriptor(e,String(i));if(!s||!Object.hasOwn(s,"value"))throw new Error(`${t} arrays must contain dense own data`);o[i]=ie(s.value,t,n+1)}return o}if(!st(e))throw new Error(`${t} contains a non-JSON value`);let r=Object.create(null);for(let o of Object.keys(e)){let i=Object.getOwnPropertyDescriptor(e,o);if(!i||!Object.hasOwn(i,"value"))throw new Error(`${t} objects must contain own data`);r[o]=ie(i.value,t,n+1)}return r}var Hr=/[\u200B-\u200F\u202A-\u202E\u2060-\u2064\uFEFF]/g,Vr=/[<>&`*_~[\]()|\\]/g,zr=/[\u0000-\u001F\u007F]/g;function De(e,{max:t=32,fallback:n=""}={}){return e==null?n:String(e).normalize("NFKC").replace(Hr,"").replace(zr,"").replace(Vr,"").replace(/\s+/g," ").trim().slice(0,t).trim()||n}var Vt=Object.freeze({1:"https://eth.blockscout.com",8453:"https://base.blockscout.com",42161:"https://arbitrum.blockscout.com"}),zt=e=>!!Vt[e];function Wr(e){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("invalid NFT cursor");let t=new URLSearchParams;for(let[n,r]of Object.entries(e)){if(!(n==="token_contract_address_hash"?/^0x[\da-f]{40}$/i.test(String(r)):n==="token_type"?["ERC-721","ERC-1155","ERC-404"].includes(r):["token_id","items_count"].includes(n)&&/^\d{1,100}$/.test(String(r))))throw new Error("invalid NFT cursor");t.set(n,String(r))}if(!t.size)throw new Error("empty NFT cursor");return t.toString()}async function Kt(e={},t={}){let n=Kr(e.address),r=Vt[e.chainId];if(!r)throw new Error("Blockscout NFT chain not verified");let o=Math.min(3,Math.max(1,Math.trunc(Number(e.maxPages)||3))),i=[],s=[],a=new Set,c=null,y="",f=0,h=!1;for(;f<o;)try{let w=ie(await V(`${r}/api/v2/addresses/${n}/nft${y?`?${y}`:""}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??8e3,maxResponseBytes:2e6,redirectPolicy:"error",headers:{accept:"application/json","user-agent":"OraclePortfolio/1.0"}}),"blockscout NFT inventory");if(!Array.isArray(w?.items))throw new Error("invalid NFT inventory response");f++;for(let v of w.items.slice(0,50)){let _=v.token;if(!/^0x[\da-f]{40}$/i.test(_?.address_hash||"")||!/^\d+$/.test(String(v.id??"")))throw new Error("invalid NFT identity");if(!["ERC-721","ERC-1155","ERC-404"].includes(_.type))throw new Error("invalid NFT standard");if(v.owner?.hash&&v.owner.hash.toLowerCase()!==n.toLowerCase())throw new Error("NFT owner mismatch");i.push({chain:e.chain,chainId:e.chainId,family:"evm",owner:n,contract:_.address_hash,tokenId:String(v.id),tokenStandard:_.type,collection:De(_.name,{max:160,fallback:_.address_hash}),name:De(v.metadata?.name||_.name,{max:160,fallback:`NFT ${v.id}`}),imageUrl:v.image_url||null,estimatedValueUsd:null,spam:["scam","spam"].includes(_.reputation)||_.is_spam===!0,source:"blockscout-owner-inventory",listingAdapter:null,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"owner indexer provides no acquisition cost"}})}if(w.items.length>50)throw new Error("NFT provider page exceeds 50 item bound");let T=w.next_page_params??null;if(!T){c=null,h=!0;break}if(c=null,y=Wr(T),c=Object.fromEntries(new URLSearchParams(y)),a.has(y))throw new Error("repeated NFT cursor");a.add(y)}catch(w){if(s.push(`blockscout: ${w.message}`.slice(0,300)),!f)throw w;break}return{nfts:i,complete:h,next:c,pages:f,truncated:!h,errors:s}}import{getAddress as oo}from"ethers";ve();z();var ys=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"});z();var ws=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),at=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),ct=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"});ve();ve();var Zr=Object.freeze([{key:"ethereum",chainId:1,name:"Ethereum",rpcEnv:["ETH_RPC_URL","ETHEREUM_RPC_URL","MAINNET_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://etherscan.io",dexscreenerSlug:"ethereum",venueKind:"uniswap-v3",wrappedNative:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",stableQuoteAssets:["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48","0xdAC17F958D2ee523a2206206994597C13D831ec7"],venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDC fee 500 quoted 1908.71 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:1}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:1}}]},{key:"optimism",chainId:10,name:"OP Mainnet",rpcEnv:["OPTIMISM_RPC_URL","OP_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://optimistic.etherscan.io",dexscreenerSlug:"optimism",venueKind:"uniswap-v3",wrappedNative:"0x4200000000000000000000000000000000000006",stableQuoteAssets:["0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85","0x94b008aA00579c1307B0EF2c499aD98a8ce58e58"],venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDC fee 500 quoted 1905.23 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:10}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:10}}]},{key:"bsc",chainId:56,name:"BNB Smart Chain",rpcEnv:["BSC_RPC_URL","BNB_RPC_URL"],nativeCurrency:{symbol:"BNB",decimals:18},explorer:"https://bscscan.com",dexscreenerSlug:"bsc",venueKind:"uniswap-v3",wrappedNative:"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",stableQuoteAssets:["0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d","0x55d398326f99059fF775485246999027B3197955"],venues:[{kind:"quoter",address:"0x78D78E420Da98ad378D7799bE8f4AF69033EB077",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WBNB->USDC fee 500 quoted 413.86 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:56}},{kind:"router",address:"0xB971eF87ede563556b2ED4b1C0b0019111Dd85d2",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:56}}]},{key:"polygon",chainId:137,name:"Polygon",rpcEnv:["POLYGON_RPC_URL","POLYGON_RPC"],nativeCurrency:{symbol:"POL",decimals:18},explorer:"https://polygonscan.com",dexscreenerSlug:"polygon",venueKind:"uniswap-v3",wrappedNative:"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",stableQuoteAssets:["0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359","0xc2132D05D31c914a87C6611C10748AEb04B58e8F"],venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WMATIC->USDC fee 500 quoted 0.0720 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:137}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:137}}]},{key:"stable",chainId:988,name:"Stable Mainnet",rpcEnv:["STABLE_RPC_URL","STABLE_RPC"],nativeCurrency:{symbol:"USDT0",decimals:18},venueKind:"uniswap-v3",wrappedNative:"0x5d442b349590a6048Eb2dC0eC346cAA5F47A9ab5",venues:[{kind:"quoter",address:"0xb070179E7032CdA868b53e6C1742F80c9e940d1A",label:"Uniswap V3 QuoterV2 (canonical)",verified:{method:"Stable is on the OFFICIAL Uniswap v3 Deployments List (governance-recognised 2026-05-12, UAC process completed 2026-04, deployed by Protofire), so this is a canonical deployment rather than a fork. eth_getCode returned 8273 bytes, the same size as the canonical quoter on the seven already-verified chains. Functional probe on a live pool (TOAST -> USDT0, fee 10000): 100 in -> 0.000003, 1000 -> 0.000031, 10000 -> 0.000319 USDT0. Output scales monotonically with input, which is a working quoter answering, not a revert. Two of three sampled pools carry non-zero liquidity. NOTE: the pools discovered so far are thin, so real routing size is limited -- the venue is proved, deep liquidity is not.",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-08-05",chainId:988}},{kind:"router",address:"0x32eaf9B5d5F2CD7361c5012890C943D7de84C22a",label:"Uniswap SwapRouter02 (canonical)",verified:{method:"eth_getCode returned 24497 bytes. Cross-checked on-chain rather than trusted from docs: router.factory() returns 0x88f0a512ef09175d456bc9547f914f48c013e4aa, the same v3 core factory that created the pools quoted above, and router.WETH9() returns the wrappedNative recorded on this chain entry. Address published in the Stable docs DEX reference and the Uniswap deployments list.",source:"docs.stable.xyz/en/reference/dexes + on-chain factory()/WETH9() round-trip",date:"2026-08-05",chainId:988}}]},{key:"hyperevm",chainId:999,name:"HyperEVM",rpcEnv:["HYPEREVM_RPC_URL","HYPER_EVM_RPC"],nativeCurrency:{symbol:"HYPE",decimals:18},dexscreenerSlug:"hyperevm",venueKind:"uniswap-v3",wrappedNative:"0x5555555555555555555555555555555555555555",venues:[{kind:"quoter",address:"0x03A918028f22D9E1473B7959C927AD7425A45C7C",label:"HyperSwap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle(1 WHYPE -> USDT0) returned live output on all four fee tiers (100: 57.3385, 500: 57.4187, 3000: 57.3237, 10000: 56.1963 USDT0). Decimals read on-chain: WHYPE 18, USDT0 6. Best tier checked against an INDEPENDENT control the same minute -- Hyperliquid allMids put HYPE at 57.3205, so the pool is 0.171% from the perp mid, which is the right shape for fee plus impact rather than a wrong contract or a decimals bug.",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-08-05",chainId:999}},{kind:"router",address:"0x4E2960a8cd19B467b82d26D83fAcb0fAE26b094D",label:"HyperSwap V3 SwapRouter",verified:{method:"eth_getCode returned 12070 bytes, and it is the router paired with the quoter proved above -- the same pair already shipped in UNI_V3_VENUES[999].hyperswap, which is the map the quote/prepare path actually routes through.",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-08-05",chainId:999}}]},{key:"abstract",chainId:2741,name:"Abstract",rpcEnv:["ABSTRACT_RPC_URL","ABS_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},venueKind:"uniswap-v3",wrappedNative:"0x3439153EB7AF838Ad19d56E1571FBD09333C2809",venues:[{kind:"quoter",address:"0x728BD3eC25D5EDBafebB84F3d67367Cd9EBC7693",label:"Uniswap V3 QuoterV2 (Abstract deployment)",verified:{method:"Abstract is a ZK-stack chain, so CREATE2 addresses differ and the canonical Uniswap addresses are NOT valid here -- probing them returns codesize 0, which is what previously made this chain look like it had no V3 at all. Found the real deployment from live traffic instead: scanned recent Swap(...) logs, took the busiest pool, read pool.factory() = 0xa1160e73b63f322ae88cc2d8e700833e71d0b2a1, then enumerated that factory's deployer (0xf3d63166F0Ca56C3c1A3508FcE03Ff0Cf3Fb691e) and probed each of its 56 contracts with a real quoteExactInputSingle call. Exactly one answered: 1 WETH -> 1846.475731 USDC.e at fee 500. Independent sanity check: the pool's own slot0() spot price is 1873.11 USDC.e per WETH, so the quoter sits ~1.4% below spot, the right shape for fee plus price impact on this size.",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-08-05",chainId:2741}},{kind:"router",address:"0x7712FA47387542819d4E35A23f8116C90C18767C",label:"Uniswap SwapRouter02 (Abstract deployment)",verified:{method:"eth_getCode returned 167392 bytes and the runtime contains the exactInputSingle selector. router.factory() matches the factory proved above and router.WETH9() matches the wrappedNative on this entry. Chosen over its byte-identical twin (0xfD6257F4...) because this is the address real users actually route through: it appeared as tx.to on live swaps against the WETH/USDC.e pool.",source:"on-chain factory()/WETH9() round-trip + live swap tx.to sampling",date:"2026-08-05",chainId:2741}}]},{key:"robinhood",chainId:4663,name:"Robinhood Chain",rpcEnv:["RH_CHAIN_RPC","ROBINHOOD_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},dexscreenerSlug:"robinhood",venueKind:"uniswap-v3",wrappedNative:"0x0bd7d308f8e1639fab988df18a8011f41eacad73",stableQuoteAssets:["0x5fc5360d0400a0fd4f2af552add042d716f1d168"],venues:[{kind:"quoter",address:"0x33e885ed0ec9bf04ecfb19341582aadcb4c8a9e7",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDG fee 100 quoted 1866.58 USDG, and USDG->CASHCAT fee 10000 quoted a live amount). A contract that correctly prices known pairs IS a working V3 quoter",source:"live eth_call against rpc.mainnet.chain.robinhood.com",date:"2026-07-31",chainId:4663}},{kind:"router",address:"0xcaf681a66d020601342297493863e78c959e5cb2",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode (24497 bytes) on this chain and the paired quoter at the same deployment passed a live functional quote",source:"live eth_getCode against rpc.mainnet.chain.robinhood.com",date:"2026-07-31",chainId:4663}},{kind:"factory",address:"0x1f7d7550b1b028f7571e69a784071f0205fd2efa",label:"Uniswap V3 Factory",verified:{method:"eth_getCode returned real bytecode (24535 bytes) and a PoolCreated log scan over this factory returned 76 pools in ~9000 recent blocks",source:"live eth_getLogs against rpc.mainnet.chain.robinhood.com",date:"2026-07-31",chainId:4663}}]},{key:"base",chainId:8453,name:"Base",rpcEnv:["BASE_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://basescan.org",dexscreenerSlug:"base",venueKind:"uniswap-v3",wrappedNative:"0x4200000000000000000000000000000000000006",stableQuoteAssets:["0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"],venues:[{kind:"quoter",address:"0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a",label:"Uniswap V3 QuoterV2 (Base)",verified:{method:"functional probe: quoteExactInputSingle returned WETH->USDC at fee 500 = 1908.44 USDC, a live sane price. The canonical mainnet quoter address also has bytecode on Base but does NOT price this pair, which is exactly the false positive a codesize-only check accepts",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:8453}},{kind:"router",address:"0x2626664c2603336E57B271c5C0b26F421741e481",label:"Uniswap V3 SwapRouter02 (Base)",verified:{method:"eth_getCode returned real bytecode and the paired Base quoter passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:8453}},{kind:"router-v2",address:"0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24",label:"Uniswap V2 Router02 (Base)",verified:{method:"eth_getCode returned 17891 bytes; live getAmountsOut on WETH->USDC round-tripped to 98.75% (2x0.30% fee + impact)",source:"https://docs.uniswap.org/contracts/v2/reference/smart-contracts/v2-deployments",date:"2026-07-30",chainId:8453}}]},{key:"arbitrum",chainId:42161,name:"Arbitrum One",rpcEnv:["ARBITRUM_RPC_URL","ARB_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://arbiscan.io",dexscreenerSlug:"arbitrum",venueKind:"uniswap-v3",wrappedNative:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",stableQuoteAssets:["0xaf88d065e77c8cC2239327C5EDb3A432268e5831","0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9"],venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDC fee 500 quoted 1908.72 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:42161}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:42161}}]},{key:"avalanche",chainId:43114,name:"Avalanche C-Chain",rpcEnv:["AVALANCHE_RPC_URL","AVAX_RPC_URL"],nativeCurrency:{symbol:"AVAX",decimals:18},explorer:"https://snowtrace.io",dexscreenerSlug:"avalanche",venueKind:"uniswap-v3",wrappedNative:"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",stableQuoteAssets:["0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"],venues:[{kind:"quoter",address:"0xbe0F5544EC67e9B3b2D979aaA43f18Fd87E6257F",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WAVAX->USDC fee 500 quoted 6.48 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:43114}},{kind:"router",address:"0xbb00FF08d01D300023C629E8fFfFcb65A5a578cE",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:43114}}]}]);z();ve();z();function lt(e,t="address"){let n=String(e||"").trim();if(!/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(n))throw new Error(`solana-rpc: ${t} must be a base58 public key`);return n}z();function fe(e,t="address"){let n=String(e||"").trim();if(!/^(bc1|tb1|bcrt1)[a-z0-9]{20,90}$/i.test(n)&&!/^[13mn2][a-km-zA-HJ-NP-Z1-9]{25,34}$/.test(n))throw new Error(`bitcoin-esplora: ${t} must look like a Bitcoin address`);return n}var Jt="ORACLE_ALLOW_CUSTOM_PROVIDER_URL";function pe({provider:e,defaultUrl:t,hosts:n=[],url:r,strict:o=!1}){let s=(String(r??"").trim()||String(t)).replace(/\/$/,"");if(s===String(t).replace(/\/$/,""))return{baseUrl:s,trusted:!0,host:Zt(t)};let a;try{a=new URL(s)}catch{throw new Error(`${e}: baseUrl must be an absolute http(s) URL`)}if(a.protocol!=="http:"&&a.protocol!=="https:")throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);let c=a.host;if(!c)throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);if(new Set([Zt(t),...n]).has(c)){let f=/^(127\.0\.0\.1|localhost|\[::1\])(:\d+)?$/i.test(c);return a.protocol==="http:"&&!f?{baseUrl:s,trusted:!1,host:c,reason:"plaintext http downgrade"}:{baseUrl:s,trusted:!0,host:c}}if(String(process.env[Jt]||"")==="1")return{baseUrl:s,trusted:!1,host:c};if(o)throw new Error(`${e}: refusing to call non-allowlisted host ${c} (set ${Jt}=1 to permit it)`);return{baseUrl:s,trusted:!1,host:c}}function Zt(e){let t=new URL(String(e));if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error("unsupported protocol");return t.host}function le(e,t,n){let r={...e};if(!n)return r;for(let[o,i]of Object.entries(t||{}))i&&(r[o]=i);return r}function Qt(e={}){return String(e.baseUrl||process.env.BTC_META_API_URL||process.env.UNISAT_API_URL||"").trim().replace(/\/$/,"")}var Xr=["open-api.unisat.io","open-api-testnet.unisat.io","api.bestinslot.xyz","api.hiro.so"];function eo(e={}){let t=e.apiKey||process.env.UNISAT_API_KEY||process.env.BESTINSLOT_API_KEY||process.env.BTC_META_API_KEY||"",n=!1;try{let r=Qt(e);if(r){let o=new URL(r).host,i=new URL(r).protocol,s=/^(127\.0\.0\.1|localhost|\[::1\])(:\d+)?$/i.test(o);n=Xr.includes(o)&&(i==="https:"||s)}}catch{n=!1}return le({accept:"application/json","user-agent":"oracle-btc-meta/0.1"},{authorization:t?`Bearer ${t}`:"","x-api-key":t},n)}async function to(e,t={}){let r=await(t.fetchImpl||fetch)(e,{method:"GET",headers:eo(t),signal:AbortSignal.timeout(t.timeoutMs??12e3)}),o=await r.text(),i;try{i=JSON.parse(o)}catch{i=o}if(!r.ok)throw new Error(`bitcoin-meta GET ${e}: HTTP ${r.status} ${String(o).slice(0,160)}`);return i}async function ut(e={},t={}){let n=fe(e.address||e.addr,"address"),r=Qt(t);if(!r)return{provider:"bitcoin-meta",address:n,ok:!1,inscriptions:[],error:"no indexer configured \u2014 address-indexed lookups need a keyed indexer (BTC_META_API_URL + UNISAT_API_KEY / BESTINSLOT_API_KEY). ordinals.com recursive is keyless but has no address index.",unknownNotEmpty:!0,keylessAlternatives:["btc_inscription_info (by inscription id)","btc_meta_health"]};let o=Math.min(Number(e.limit||50),200),i=[`${r}/v1/indexer/address/${n}/inscription-data?cursor=0&size=${o}`,`${r}/v1/inscriptions/address/${n}?limit=${o}`,`${r}/address/${n}/inscriptions?limit=${o}`],s=null;for(let a of i)try{let c=await to(a,t),y=no(c);return{provider:"bitcoin-meta",address:n,ok:!0,count:y.length,inscriptions:y,source:a}}catch(c){s=c}return{provider:"bitcoin-meta",address:n,ok:!1,inscriptions:[],error:String(s?.message||s||"all indexer paths failed")}}function no(e){let t=e?.data?.inscription||e?.data?.detail||e?.data?.list||e?.data||e?.inscriptions||e?.results||(Array.isArray(e)?e:[]);return(Array.isArray(t)?t:[]).map(r=>({id:r.inscriptionId||r.id||r.inscription_id||null,number:r.inscriptionNumber??r.number??null,sat:r.sat||r.satoshi||null,contentType:r.contentType||r.content_type||null,utxo:r.utxo||r.output||(r.txid!=null?`${r.txid}:${r.vout??r.n}`:null),raw:r}))}z();z();z();var pa=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood",2741:"abstract",solana:"solana"});z();var ga=Object.freeze({1:"https://eth.blockscout.com",10:"https://explorer.optimism.io",137:"https://polygon.blockscout.com",324:"https://zksync.blockscout.com",8453:"https://base.blockscout.com",42161:"https://arbitrum.blockscout.com",534352:"https://scrollscan.com"}),ro=Object.freeze(["block_number","index"]),Ea=new Set([...ro,"items_count","value","hash","inserted_at","fee"]);var Ya=Object.freeze({ETH:"coingecko:ethereum",POL:"coingecko:polygon-ecosystem-token",BNB:"coingecko:binancecoin",AVAX:"coingecko:avalanche-2",HYPE:"coingecko:hyperliquid",USDT0:"coingecko:tether",SOL:"coingecko:solana",BTC:"coingecko:bitcoin"});function Be(e,...t){for(let n of t){let r=String(e?.[n]||"").trim();if(r)return r}return null}function Xt(e){if(!e)return null;try{return oo(String(e).trim().toLowerCase())}catch{throw new Error("portfolio: EVM address must be a valid 20-byte address")}}function en(e={},t=process.env){let n=e.addresses||{},r=Xt(n.evm||e.evmAddress||Be(t,"ORACLE_EVM_ADDRESS","ORACLE_DEFAULT_ADDRESS","MAD_OPERATOR_ADDRESS")),o=n.solana||e.solanaAddress||Be(t,"ORACLE_SOLANA_ADDRESS"),i=n.bitcoin||e.bitcoinAddress||Be(t,"ORACLE_BITCOIN_ADDRESS"),s=Xt(n.hyperliquid||e.hyperliquidAddress||Be(t,"ORACLE_HYPERLIQUID_ADDRESS")||r);return{evm:r,solana:o?lt(o,"portfolio Solana address"):null,bitcoin:i?fe(i,"portfolio Bitcoin address"):null,hyperliquid:s}}z();import{readFileSync as so,existsSync as ao}from"node:fs";import{getAddress as co,Interface as Me,TypedDataEncoder as rc,parseUnits as oc}from"ethers";var io=300*1e3,Za=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})();var lo="https://api.opensea.io/api/v2",uo="fulfillAdvancedOrder(((address offerer,address zone,(uint8 itemType,address token,uint256 identifierOrCriteria,uint256 startAmount,uint256 endAmount)[] offer,(uint8 itemType,address token,uint256 identifierOrCriteria,uint256 startAmount,uint256 endAmount,address recipient)[] consideration,uint8 orderType,uint256 startTime,uint256 endTime,bytes32 zoneHash,uint256 salt,bytes32 conduitKey,uint256 totalOriginalConsiderationItems) parameters,uint120 numerator,uint120 denominator,bytes signature,bytes extraData) advancedOrder,(uint256 orderIndex,uint8 side,uint256 index,uint256 identifier,bytes32[] criteriaProof)[] criteriaResolvers,bytes32 fulfillerConduitKey,address recipient)",lc=new Me([`function ${uo}`]),uc=new Me(["function mintPublic(address nftContract,address feeRecipient,address minterIfNotPayer,uint256 quantity) payable","function mintAllowList(address nftContract,address feeRecipient,address minterIfNotPayer,uint256 quantity,(uint80 mintPrice,uint48 maxTotalMintableByWallet,uint48 startTime,uint48 endTime,uint48 dropStageIndex,uint32 maxTokenSupplyForStage,uint16 feeBps,bool restrictFeeRecipients) mintParams,bytes32[] proof) payable"]),fo=Object.freeze(["blast","base","ethereum","zora","arbitrum","sei","avalanche","polygon","optimism","ape_chain","flow","b3","soneium","ronin","bera_chain","solana","shape","unichain","gunzilla","abstract","animechain","hyperevm","somnia","monad","hyperliquid","megaeth","ink","robinhood","stablechain"]),po=new Set(fo),mo=new Set(["solana","flow"]);function ho(){let e=process.env.OPENSEA_ENV_FILE||`${process.env.HOME||""}/.config/locals-only/opensea.env`;if(!ao(e))return"";try{for(let t of so(e,"utf8").split(`
5
- `)){let n=t.match(/^\s*OPENSEA_API_KEY\s*=\s*(.+)\s*$/);if(n)return n[1].replace(/^["']|["']$/g,"").trim()}}catch{}return""}function xe(e={}){return e.apiKey?e.apiKey:e.allowAmbientCredentials===!1||e.allowDiskCredentials===!1?e.env?.OPENSEA_API_KEY||e.env?.OPEN_SEA_API_KEY||"":e.env?.OPENSEA_API_KEY||process.env.OPENSEA_API_KEY||process.env.OPEN_SEA_API_KEY||ho()}function nn(e={}){return pe({provider:"opensea",defaultUrl:lo,hosts:["api.opensea.io","testnets-api.opensea.io"],url:e.baseUrl||process.env.OPENSEA_API_URL})}function qe(e={}){return nn(e).baseUrl}function je(e={}){return le({accept:"application/json"},{"x-api-key":xe(e)},nn(e).trusted)}function yo(e){let t=String(e||"ethereum").trim().toLowerCase();if(!po.has(t))throw new Error(`opensea: unsupported account chain ${t}`);return t}function tn(e,t="address"){try{return co(String(e||"").trim().toLowerCase())}catch{throw new Error(`opensea: invalid ${t}`)}}function rn(e,t=null){let n=String(e||"").trim();if(!n)throw new Error("opensea: account address required");if(t&&!mo.has(t)||!t&&/^0x[0-9a-fA-F]{40}$/.test(n))return tn(n,"account address");if(!/^[1-9A-HJ-NP-Za-km-z]{32,64}$/.test(n))throw new Error("opensea: invalid account address");return n}function bo(e={},t,n){return{chain:t,owner:n,contract:e.contract||null,tokenId:e.identifier==null?null:String(e.identifier),tokenStandard:e.token_standard||null,quantity:e.quantity==null&&e.balance==null?null:String(e.quantity??e.balance),collection:e.collection||null,name:e.name||null,description:e.description||null,imageUrl:e.display_image_url||e.image_url||e.original_image_url||null,originalImageUrl:e.original_image_url||e.image_url||null,animationUrl:e.display_animation_url||e.original_animation_url||null,metadataUrl:e.metadata_url||null,marketplaceUrl:e.opensea_url||null,estimatedValueUsd:e.estimated_value_usd!=null&&Number.isFinite(Number(e.estimated_value_usd))?Number(e.estimated_value_usd):null,spam:e.is_disabled===!0,disabled:e.is_disabled===!0,nsfw:e.is_nsfw===!0,traits:Array.isArray(e.traits)?e.traits:[],updatedAt:e.updated_at||null,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"OpenSea account inventory does not expose trustworthy per-item acquisition cost"}}}async function wo(e,t={}){if(!e)throw new Error("collection slug required");if(!xe(t))throw new Error("OPENSEA_API_KEY required");return V(`${qe(t)}/collections/${encodeURIComponent(e)}`,{headers:je(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function go(e,t={}){if(!e)throw new Error("collection slug required");if(!xe(t))throw new Error("OPENSEA_API_KEY required");return V(`${qe(t)}/collections/${encodeURIComponent(e)}/stats`,{headers:je(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function on(e,t={}){let n=await wo(e,t),r=n.stats||n.total||{},o=n.floor_price??n.floorPrice??r.floor_price??r.floorPrice??null;if(o==null){let h=await go(e,t);r=h?.total||h?.stats||h||{},o=r.floor_price??r.floorPrice??null}let i=(Array.isArray(n.contracts)?n.contracts:[]).map(h=>({chain:String(h?.chain||h?.chain_identifier||n.chain||"").trim().toLowerCase(),address:String(h?.address||h?.contract_address||h?.contract||"").trim()})).filter(h=>h.chain&&h.address),s=String(t.expectedChain||"").trim().toLowerCase(),a=String(t.expectedContract||"").trim(),c=null;if(s&&a){let h=w=>s==="solana"?w:w.toLowerCase();if(c=i.find(w=>w.chain===s&&h(w.address)===h(a))||null,!c)throw new Error("opensea: collection identity does not match held contract")}let y=c?.chain||String(n.chain||"").trim().toLowerCase()||i[0]?.chain||"",f=String(n.floor_price_symbol||n.floorPriceSymbol||r.floor_price_symbol||r.floorPriceSymbol||"").trim().toUpperCase()||null;return{slug:n.collection||e,name:n.name||null,floor:o,chain:y||null,contracts:i,currency:f,totalSupply:n.total_supply??r.total_supply??null,numOwners:n.num_owners??r.num_owners??null,raw:{contracts:i,fees:n.fees,category:n.category}}}async function ft(e={},t={}){if(!xe(t))throw new Error("OPENSEA_API_KEY required");let n=yo(e.chain),r=rn(e.address||e.owner,n),o=Math.min(Math.max(Number(e.pageSize??e.limit??200)||200,1),200),i=Math.min(Math.max(Number(e.maxPages??5)||5,1),25),s=[],a=e.next?String(e.next):null,c=0;do{let y=new URL(`${qe(t)}/chain/${encodeURIComponent(n)}/account/${encodeURIComponent(r)}/nfts`);y.searchParams.set("limit",String(o)),e.collection&&y.searchParams.set("collection",String(e.collection)),a&&y.searchParams.set("next",a);let f=await V(y.toString(),{headers:je(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4});for(let h of Array.isArray(f?.nfts)?f.nfts:[])s.push(bo(h,n,r));a=f?.next?String(f.next):null,c+=1}while(a&&c<i);return{provider:"opensea-nft",source:"opensea-account-inventory",chain:n,owner:r,count:s.length,pages:c,complete:!a,next:a,nfts:s,exec:!1,readOnly:!0}}async function sn(e={},t={}){if(!xe(t))throw new Error("OPENSEA_API_KEY required");let n=rn(e.address||e.owner),r=await V(`${qe(t)}/account/${encodeURIComponent(n)}/pnl`,{headers:je(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4});return{provider:"opensea-nft",source:"opensea-indexed-account-pnl",address:n,scope:"OpenSea-indexed account trading PnL across supported currencies, not per-item NFT cost basis",methodology:"provider-indexed",realizedPnlUsd:r?.realized_pnl_usd??null,unrealizedPnlUsd:r?.unrealized_pnl_usd??null,totalPnlUsd:r?.total_pnl_usd??null,netInvestedUsd:r?.net_invested_usd??null,currentValueUsd:r?.current_value_usd??null,returnPercentage:r?.return_percentage??null,itemLevelPnlAvailable:!1,raw:r,exec:!1,readOnly:!0}}var dc=Object.freeze({robinhood:4663,ethereum:1,base:8453,arbitrum:42161,optimism:10,polygon:137,avalanche:43114,zora:7777777,blast:81457,sei:1329,ape_chain:33139,b3:8333,soneium:1868,ronin:2020,bera_chain:80094,shape:360,unichain:130,gunzilla:43419,abstract:2741,animechain:69e3,hyperevm:999,somnia:5031,monad:143,megaeth:4326,ink:57073,stablechain:988});var fc=Object.freeze({OrderComponents:[{name:"offerer",type:"address"},{name:"zone",type:"address"},{name:"offer",type:"OfferItem[]"},{name:"consideration",type:"ConsiderationItem[]"},{name:"orderType",type:"uint8"},{name:"startTime",type:"uint256"},{name:"endTime",type:"uint256"},{name:"zoneHash",type:"bytes32"},{name:"salt",type:"uint256"},{name:"conduitKey",type:"bytes32"},{name:"counter",type:"uint256"}],OfferItem:[{name:"itemType",type:"uint8"},{name:"token",type:"address"},{name:"identifierOrCriteria",type:"uint256"},{name:"startAmount",type:"uint256"},{name:"endAmount",type:"uint256"}],ConsiderationItem:[{name:"itemType",type:"uint8"},{name:"token",type:"address"},{name:"identifierOrCriteria",type:"uint256"},{name:"startAmount",type:"uint256"},{name:"endAmount",type:"uint256"},{name:"recipient",type:"address"}]});var pc=new Me(["function setApprovalForAll(address operator,bool approved)"]),mc=new Me(["function cancel((address offerer,address zone,(uint8 itemType,address token,uint256 identifierOrCriteria,uint256 startAmount,uint256 endAmount)[] offer,(uint8 itemType,address token,uint256 identifierOrCriteria,uint256 startAmount,uint256 endAmount,address recipient)[] consideration,uint8 orderType,uint256 startTime,uint256 endTime,bytes32 zoneHash,uint256 salt,bytes32 conduitKey,uint256 counter)[] orders) returns (bool cancelled)"]);var So="https://api.satflow.com/v1";function an(e={}){return pe({provider:"satflow",defaultUrl:So,hosts:["api.satflow.com"],url:e.baseUrl||process.env.SATFLOW_API_URL})}function Ao(e={}){return an(e).baseUrl}function cn(e={}){return String(e.apiKey||process.env.SATFLOW_API_KEY||process.env.BTC_SATFLOW_API_KEY||"").trim()}function vo(e={}){return le({accept:"application/json","content-type":"application/json","user-agent":"oracle-btc-satflow/0.1"},{"x-api-key":cn(e)},an(e).trusted)}async function xo(e,{method:t="GET",body:n,opts:r={}}={}){if(!cn(r))throw new Error("satflow: SATFLOW_API_KEY not set (request key via Satflow docs form)");let i=`${Ao(r)}${e.startsWith("/")?e:`/${e}`}`,a=await(r.fetchImpl||fetch)(i,{method:t,headers:vo(r),body:n!=null?JSON.stringify(n):void 0,signal:AbortSignal.timeout(r.timeoutMs??2e4)}),c=await a.text(),y;try{y=JSON.parse(c)}catch{y=c}if(!a.ok)throw new Error(`satflow ${t} ${e}: HTTP ${a.status} ${String(c).slice(0,200)}`);return y}async function ln(e={},t={}){let n=fe(e.address||e.addr,"address"),r=new URLSearchParams({address:n});e.type&&r.set("type",e.type),e.limit!=null&&r.set("limit",String(e.limit)),e.offset!=null&&r.set("offset",String(e.offset));let o=await xo(`/address/wallet-contents?${r}`,{opts:t});return{provider:"satflow",address:n,contents:o}}z();z();var Nc=Object.freeze(["i.seadn.io","openseauserdata.com","arweave.net","ipfs.io","nftstorage.link","dweb.link","cloudflare-ipfs.com","ordinals.com","ordinals.g.com","cdn.helius-rpc.com","shdw-drive.genesysgo.net"]);var ko=[/\bclaim\b/i,/\breward\b/i,/\bairdrop\b/i,/\bvoucher\b/i,/\bwinner\b/i,/\bfree\s*mint\b/i,/\bactivate\b/i,/\bunlock\b/i,/\bverify\b/i,/\bconnect\s+wallet\b/i],To=/(https?:\/\/|www\.|[a-z0-9-]+\.(?:com|net|io|xyz|org|app|finance|gift|claims?|site|link|live|vip|top|cc))/i,Io=/(\$\s?\d|\d[\d,.]*\s*(?:usd|usdc|usdt|eth|weth|btc|sol)\b)/i;function _o(e={}){let t=[],n=String(e.name||""),r=String(e.description||""),o=`${n} ${r}`;To.test(n)&&t.push("url-in-name");let i=ko.filter(y=>y.test(o)).length;i>0&&t.push(`lure-language:${i}`),Io.test(n)&&t.push("value-claim-in-name"),/[\u200B-\u200F\u202A-\u202E\uFEFF]/.test(n)&&t.push("invisible-characters"),e.disabled===!0&&t.push("marketplace-disabled");let s=e.estimatedValueUsd==null&&e.estimatedValueSats==null,a=!Array.isArray(e.traits)||e.traits.length===0;s&&a&&i>0&&t.push("valueless-airdrop-with-lure");let c=t.includes("url-in-name")||t.includes("invisible-characters")||t.includes("valueless-airdrop-with-lure")||t.length>=2;return{spam:c,risk:c?"high":t.length>0?"low":"none",reasons:t}}function un(e={}){let t=_o(e);return{...e,spam:e.spam===!0||t.spam,riskLevel:t.risk,riskReasons:t.reasons.length?t.reasons:void 0}}var No=Object.freeze([{chain:"ethereum",chainId:1,family:"evm"},{chain:"optimism",chainId:10,family:"evm"},{chain:"polygon",chainId:137,family:"evm"},{chain:"stablechain",chainId:988,family:"evm"},{chain:"hyperevm",chainId:999,family:"evm"},{chain:"abstract",chainId:2741,family:"evm"},{chain:"robinhood",chainId:4663,family:"evm"},{chain:"base",chainId:8453,family:"evm"},{chain:"arbitrum",chainId:42161,family:"evm"},{chain:"avalanche",chainId:43114,family:"evm"},{chain:"hyperliquid",chainId:null,family:"hyperliquid"}]),Oo=Object.freeze([{family:"evm",chain:"bsc",chainId:56,reason:"OpenSea account inventory does not support BSC"},{family:"cosmos",reason:"requires a chain-specific bech32 address and NFT indexer"},{family:"sui",reason:"owner inventory adapter not installed"},{family:"aptos",reason:"owner inventory adapter not installed"}]);function pt(e={},t){return{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs,env:e.env,allowDiskCredentials:e.allowDiskCredentials,allowAmbientCredentials:e.allowAmbientCredentials,...e[t]||{}}}async function me(e,t){let n=await Ue(t);return n.ok?{ok:!0,data:n.data}:{ok:!1,error:`${e}: ${n.error}`.slice(0,300)}}function Co(e){if(Array.isArray(e))return e;for(let t of["items","results","ordinals","inscriptions","data"])if(Array.isArray(e?.[t]))return e[t];return[]}function Po(e={},t){let n=e.inscription_id||e.inscriptionId||e.id||e.inscription||null;return{chain:"bitcoin",family:"bitcoin",owner:t,contract:null,tokenId:n==null?null:String(n),tokenStandard:"ordinal",collection:e.collection_slug||e.collectionSlug||e.collection?.slug||e.collection||null,name:e.name||e.meta?.name||(n?`Inscription ${n}`:"Bitcoin inscription"),description:e.description||e.meta?.description||null,imageUrl:e.image_url||e.imageUrl||e.content_url||e.contentUrl||e.thumbnail||null,originalImageUrl:e.content_url||e.contentUrl||e.image_url||e.imageUrl||null,animationUrl:null,metadataUrl:e.metadata_url||e.metadataUrl||null,marketplaceUrl:e.marketplace_url||e.marketplaceUrl||null,estimatedValueUsd:e.estimated_value_usd!=null&&Number.isFinite(Number(e.estimated_value_usd))?Number(e.estimated_value_usd):null,estimatedValueSats:(e.floor_price_sats??e.price_sats)!=null&&Number.isFinite(Number(e.floor_price_sats??e.price_sats))?Number(e.floor_price_sats??e.price_sats):null,spam:!1,disabled:!1,nsfw:!1,listed:e.listed===!0||e.is_listed===!0,listingId:e.listing_id||e.listingId||null,traits:Array.isArray(e.traits)?e.traits:[],updatedAt:e.updated_at||e.updatedAt||null,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"Satflow wallet inventory does not expose trustworthy acquisition cost"},listingAdapter:"satflow",source:"satflow-wallet-contents"}}function Ro(e,t){return{chain:"bitcoin",family:"bitcoin",owner:t,contract:null,tokenId:String(e),tokenStandard:"ordinal",collection:null,name:`Inscription ${e}`,description:null,imageUrl:null,originalImageUrl:null,animationUrl:null,metadataUrl:null,marketplaceUrl:null,estimatedValueUsd:null,spam:!1,disabled:!1,nsfw:!1,traits:[],updatedAt:null,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"address indexer returned no acquisition or valuation data"},listingAdapter:"satflow",source:"bitcoin-meta-address-indexer"}}function dn(e={}){return[e.chain||"unknown",e.contract||"native",e.tokenId||"unknown"].join(":").toLowerCase()}function $o(e){let t=new Map;if(Array.isArray(e)){for(let n of e)n?.assetKey&&t.set(String(n.assetKey).toLowerCase(),n);return t}if(e&&typeof e=="object")for(let[n,r]of Object.entries(e))t.set(n.toLowerCase(),r);return t}function Lo(e,t){let n=dn(e),r=t.get(n),o=e.estimatedValueUsd==null?null:Number(e.estimatedValueUsd);if(!r)return{...e,assetKey:n};let i=Number(r.costUsd),s=Number(r.feesUsd??0);if(!Number.isFinite(i)||i<0||!Number.isFinite(s)||s<0)return{...e,assetKey:n,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"invalid user-supplied cost basis"}};let a=Math.round((i+s)*100)/100;return Number.isFinite(o)?{...e,assetKey:n,acquisitionCost:{costUsd:i,feesUsd:s,totalCostUsd:a,acquiredAt:r.acquiredAt||null,source:r.source||"user-supplied"},itemPnl:{status:"estimated",methodology:"provider estimated current value minus supplied USD acquisition cost and fees",unrealizedUsd:Math.round((o-a)*100)/100,currentValueUsd:o,totalCostUsd:a,realizedUsd:null}}:{...e,assetKey:n,acquisitionCost:{costUsd:i,feesUsd:s,totalCostUsd:a,acquiredAt:r.acquiredAt||null,source:r.source||"user-supplied"},itemPnl:{status:"unavailable",reason:"current NFT valuation is unavailable"}}}function Fo(e){let t=new Map;for(let n of e){let r=dn(n);t.has(r)||t.set(r,n)}return[...t.values()]}function Uo(e,t){let n=e.filter(i=>i.itemPnl?.status==="estimated"),r=e.length-n.length,o=Math.round(n.reduce((i,s)=>i+Number(s.itemPnl.unrealizedUsd||0),0)*100)/100;return{nftItemPnl:{status:r===0&&e.length?"estimated-complete-for-held-items":n.length?"partial":"unavailable",methodology:"Only items with explicit acquisition cost and provider estimated current value are included",knownUnrealizedUsd:o,knownItems:n.length,unknownItems:r,realizedUsd:null,warning:"Transfers, gifts, airdrops, mints, bridges, gas, royalties, and off-market sales can make cost basis unavailable or incomplete."},providerAccountPnl:t}}async function fn(e={},t={}){let n=new Date().toISOString(),r=en(e,t.env||process.env),o=Array.isArray(e.chains)&&e.chains.length?new Set(e.chains.map(d=>String(d).toLowerCase())):null,i=No.filter(d=>!o||o.has(d.chain)),s=[],a=[],c=pt(t,"opensea"),y=r.evm?i.filter(d=>d.family!=="solana"):[],f=await Ae(y,4,async d=>({row:d,result:await me(`opensea-${d.chain}`,()=>ft({chain:d.chain,address:r.evm,pageSize:e.pageSize,maxPages:e.maxPages},c),t.timeoutMs??35e3)}));for(let{row:d,result:u}of f)if(u.ok){let m=u.data.nfts.map(p=>({...p,family:d.family,chainId:d.chainId,listingAdapter:"opensea",source:"opensea-account-inventory"}));a.push(...m),s.push({family:d.family,chain:d.chain,chainId:d.chainId,status:u.data.complete?"ok":"partial",count:m.length,complete:u.data.complete,next:u.data.next,source:"opensea"})}else{let m=zt(d.chainId)?await me(`blockscout-${d.chain}`,()=>Kt({chain:d.chain,chainId:d.chainId,address:r.evm,maxPages:e.maxPages},{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})):null;m?.ok?(a.push(...m.data.nfts),s.push({...d,status:m.data.complete?"ok":"partial",count:m.data.nfts.length,complete:m.data.complete,next:m.data.next,truncated:m.data.truncated,source:"blockscout",errors:[u.error,...m.data.errors]})):s.push({...d,status:"unavailable",count:null,complete:!1,error:u.error,errors:[u.error,...m?[m.error]:[]],source:"opensea"})}if(!r.evm)for(let d of i.filter(u=>u.family!=="solana"))s.push({family:d.family,chain:d.chain,chainId:d.chainId,status:"not-configured",reason:"EVM address missing"});if(r.solana&&(!o||o.has("solana"))){let d=await me("opensea-solana",()=>ft({chain:"solana",address:r.solana,pageSize:e.pageSize,maxPages:e.maxPages},c),t.timeoutMs??35e3);if(d.ok){let u=d.data.nfts.map(m=>({...m,family:"solana",chainId:null,listingAdapter:null,source:"opensea-account-inventory"}));a.push(...u),s.push({family:"solana",chain:"solana",status:d.data.complete?"ok":"partial",count:u.length,complete:d.data.complete,next:d.data.next,source:"opensea"})}else s.push({family:"solana",chain:"solana",status:"unavailable",error:d.error,source:"opensea"})}else(!o||o.has("solana"))&&s.push({family:"solana",chain:"solana",status:"not-configured",reason:"Solana address missing"});if(r.bitcoin&&(!o||o.has("bitcoin"))){let d=await me("satflow-wallet-contents",()=>ln({address:r.bitcoin,type:"ordinals",limit:e.bitcoinLimit??100,offset:0},pt(t,"satflow")),t.timeoutMs??35e3);if(d.ok){let u=Co(d.data.contents).map(p=>Po(p,r.bitcoin));a.push(...u);let m=u.length<Number(e.bitcoinLimit??100);s.push({family:"bitcoin",chain:"bitcoin",status:m?"ok":"partial",count:u.length,complete:m,source:"satflow"})}else{let u=await me("bitcoin-meta-inscriptions",()=>ut({address:r.bitcoin},pt(t,"bitcoinMeta")),t.timeoutMs??35e3),m=u.ok&&u.data?.ok&&Array.isArray(u.data.inscriptions)?u.data.inscriptions:[];a.push(...m.map(p=>Ro(p,r.bitcoin))),s.push({family:"bitcoin",chain:"bitcoin",status:m.length?"partial":"unavailable",count:m.length,complete:!1,source:m.length?"bitcoin-meta":"satflow",error:m.length?"Satflow unavailable; fallback has IDs only":d.error})}}else(!o||o.has("bitcoin"))&&s.push({family:"bitcoin",chain:"bitcoin",status:"not-configured",reason:"Bitcoin address missing"});let h=[];if(e.includePnl!==!1)for(let d of[...new Set([r.evm,r.solana].filter(Boolean))]){let u=await me(`opensea-pnl-${d}`,()=>sn({address:d},c),t.timeoutMs??35e3);h.push(u.ok?{status:"ok",...u.data}:{status:"unavailable",address:d,source:"opensea-indexed-account-pnl",error:u.error})}let w=$o(e.costBasis),T=Fo(a).map(d=>Lo(d,w)).map(d=>un(d)),v=T.filter(d=>!d.spam),_=T.filter(d=>d.spam),C=v.filter(d=>d.estimatedValueUsd!=null&&Number.isFinite(Number(d.estimatedValueUsd))),$=Math.round(C.reduce((d,u)=>d+Number(u.estimatedValueUsd),0)*100)/100,M=v.length-C.length,b=s.filter(d=>d.status!=="ok"||d.complete===!1);return{provider:"nft-portfolio",operation:"inventory",readOnly:!0,generatedAt:n,addresses:r,coverage:s,unsupported:Oo,inventory:{count:T.length,visibleCount:v.length,flaggedCount:_.length,items:T,visibleItems:v,flaggedItems:_},valuation:{estimatedCurrentValueUsd:$,valuedItems:C.length,unvaluedItems:M,complete:M===0&&b.length===0,methodology:"Sum of provider estimated_value_usd for non-flagged items. It is not an executable bid."},pnl:Uo(v,h),listingCoverage:{opensea:"EVM listing actions available with OPENSEA_API_KEY, explicit price/currency/expiry, and user confirmation",satflow:"Bitcoin unsigned listing PSBT available with SATFLOW_API_KEY, explicit price/expiry, and user confirmation",solana:"Magic Eden unsigned list transaction available with MAGICEDEN_API_KEY, explicit SOL price/expiry, and user confirmation",unsupported:"Sui, Aptos, Cosmos, BSC, and unknown marketplaces fail closed"},traitSniperCoverage:{opensea:"Evaluates reveal/trait-floor mispricing only with recent trait sales and volume evidence. Buy intents require local vault signing.",execution:"prepare-only on hosted surfaces; local vault required for purchase"},metadataSafety:{imagesAreUntrusted:!0,animationAndHtmlNotRendered:!0,galleryRasterOnly:!0,missingImagesUsePlaceholders:!0}}}var mn=1,Mo=/^0x[0-9a-f]{40}$/,qo=/^[1-9A-HJ-NP-Za-km-z]{32,64}$/,jo=/^[A-Z0-9][A-Z0-9._-]{1,15}$/;function Ho(e=process.env){let t=e.ORACLE_CONFIG_DIR||He.join(pn(),".config","oracle");return He.join(t,"held-nft-pump.v1.json")}function Vo(e=process.env){let t=e.ORACLE_CONFIG_DIR||He.join(pn(),".config","oracle"),n={};try{let o=JSON.parse(Do(He.join(t,"portfolio.json"),"utf8"));n=o&&typeof o=="object"&&!Array.isArray(o)?o.addresses||o:{}}catch{}let r={evm:e.ORACLE_EVM_ADDRESS||n.evm,solana:e.ORACLE_SOLANA_ADDRESS||n.solana};return Object.fromEntries(Object.entries(r).filter(([,o])=>typeof o=="string"&&o.trim()).map(([o,i])=>[o,i.trim()]))}function zo(e){return{...e,ORACLE_DEFAULT_ADDRESS:"",MAD_OPERATOR_ADDRESS:""}}function hn(e){let t=Number(e);return Number.isFinite(t)&&t>0?t:null}function Ko(e){let t=e?.quantity??e?.balance??1;if(typeof t!="string"&&typeof t!="number"&&typeof t!="bigint"||!/^\d+$/.test(String(t)))return 0n;let n=BigInt(String(t));return n>0n?n:0n}function Wo(e){return e<=BigInt(Number.MAX_SAFE_INTEGER)?Number(e):e.toString()}function Go(e){if(!e||e.version!==mn||!e.collections||typeof e.collections!="object"||Array.isArray(e.collections))throw new TypeError("invalid held NFT pump state");if(!Number.isSafeInteger(e.cursor??0)||(e.cursor??0)<0)throw new TypeError("invalid held NFT pump cursor");if(e.walletFingerprint!==void 0&&!/^[a-f0-9]{64}$/.test(e.walletFingerprint))throw new TypeError("invalid held NFT wallet fingerprint");if(e.walletChanged!==void 0&&typeof e.walletChanged!="boolean")throw new TypeError("invalid held NFT wallet-change marker");let t=e.failures??{};if(!t||typeof t!="object"||Array.isArray(t))throw new TypeError("invalid held NFT pump failures");let n=Object.entries(e.collections);if(n.length>1e4||Object.keys(t).length>1e4)throw new TypeError("held NFT pump state exceeds collection bound");for(let[r,o]of n){if(!r||r.length>260||!o||hn(o.anchorFloor)===null)throw new TypeError("invalid held NFT floor record");if(!Number.isFinite(o.updatedAt)||o.updatedAt<0)throw new TypeError("invalid held NFT update time");if(o.lastAlertAt!==null&&(!Number.isFinite(o.lastAlertAt)||o.lastAlertAt<0))throw new TypeError("invalid held NFT alert time")}for(let r of Object.values(t))if(!r||!Number.isSafeInteger(r.count)||r.count<1||!Number.isFinite(r.nextCheckAt)||r.nextCheckAt<0)throw new TypeError("invalid held NFT provider backoff")}function yn(e={}){let t=e?.inventory?.visibleItems??e?.inventory?.items??[],n=new Map;for(let r of Array.isArray(t)?t:[]){if(r?.spam===!0||r?.disabled===!0)continue;let o=String(r?.chain||"").trim().toLowerCase(),i=String(r?.contract||"").trim(),s=o==="solana"?i:i.toLowerCase(),a=String(r?.collection||"").trim().toLowerCase();if(!o||!a||!(o==="solana"?qo.test(s):Mo.test(s)))continue;let c=Ko(r);if(c===0n)continue;let y=`${o}:${s}`,f=n.get(y);f&&f.slug!==a||n.set(y,{key:y,chain:o,contract:s,slug:a,name:f?.name||String(r?.name||a),heldCountRaw:(f?.heldCountRaw||0n)+c})}return[...n.values()].map(({heldCountRaw:r,...o})=>({...o,heldCount:Wo(r)})).sort((r,o)=>r.key.localeCompare(o.key))}function Yo(e,t){let n=String(e?.currency||"").trim().toUpperCase();if(!jo.test(n))return{ok:!1,reason:"floor-currency-unavailable"};if(e?.chain&&String(e.chain).trim().toLowerCase()!==t.chain)return{ok:!1,reason:"floor-identity-mismatch"};let r=Array.isArray(e?.contracts)?e.contracts:Array.isArray(e?.raw?.contracts)?e.raw.contracts:[],o=t.chain==="solana"?t.contract:t.contract.toLowerCase();return r.some(s=>{let a=String(s?.address||s?.contract_address||s?.contract||"").trim(),c=t.chain==="solana"?a:a.toLowerCase(),y=String(s?.chain||s?.chain_identifier||"").trim().toLowerCase();return c===o&&y===t.chain})?{ok:!0,currency:n}:{ok:!1,reason:"floor-identity-mismatch"}}function Jo(e,t,n,r,o){let i=Math.round((t/r.anchorFloor-1)*1e4)/100;return Object.freeze({type:"held_nft_floor_pump",category:"price",chain:e.chain,contract:e.contract,slug:e.slug,name:e.name,heldCount:e.heldCount,fromFloor:r.anchorFloor,floor:t,currency:n,changePct:i,observedAt:new Date(o).toISOString(),evidence:Object.freeze({source:"opensea-collection-floor",status:"provider-estimate",chain:e.chain,contract:e.contract,currency:n,observedAt:new Date(o).toISOString(),warning:"Floor is a provider estimate, not an executable bid or guaranteed liquidation value."}),custody:"none",executionAllowed:!1})}function Zo({filePath:e,env:t=process.env,clock:n=()=>Date.now(),inventoryFn:r=fn,floorFn:o=on,notifyFn:i=async()=>({delivered:0}),thresholdPct:s=Number(t.ORACLE_NFT_PUMP_THRESHOLD_PCT??15),cooldownMs:a=Number(t.ORACLE_NFT_PUMP_COOLDOWN_HOURS??6)*36e5,maxFloorChecksPerTick:c=Number(t.ORACLE_NFT_PUMP_MAX_FLOORS_PER_TICK??20),inventoryPageSize:y=100,inventoryMaxPages:f=2}={}){if(typeof r!="function"||typeof o!="function"||typeof i!="function")throw new TypeError("held NFT watchdog functions are required");if(!Number.isFinite(s)||s<=0||s>1e3)throw new TypeError("held NFT pump threshold is out of range");if(!Number.isFinite(a)||a<6e4||a>30*864e5)throw new TypeError("held NFT pump cooldown is out of range");if(!Number.isSafeInteger(c)||c<1||c>100)throw new TypeError("held NFT floor budget is out of range");let h=te({filePath:e||Ho(t),kind:"oracle-held-nft-pump",clock:n,maxBytes:4*1024*1024,initialData:()=>({version:mn,cursor:0,collections:{},failures:{}}),validateData:Go}),w=!1;function T(_,C){h.mutate($=>{$.failures||={};let M=Math.min(20,Number($.failures[_]?.count||0)+1);$.failures[_]={count:M,nextCheckAt:C+Math.min(6*36e5,3e5*2**Math.min(6,M-1))}})}async function v(){if(w)return{skipped:!0,reason:"tick-in-progress",alerts:[],unavailable:[]};w=!0;try{let _=Number(n());if(!Number.isFinite(_))throw new TypeError("held NFT watchdog clock is invalid");let C=Vo(t),$=zo(t),M=Bo("sha256").update(JSON.stringify(Object.entries(C).sort())).digest("hex");h.mutate(l=>{let E=!!(l.walletFingerprint&&l.walletFingerprint!==M);E&&(l.collections={},l.failures={},l.cursor=0),l.walletFingerprint=M,l.walletChanged=E});let b=await r({addresses:C,includePnl:!1,pageSize:y,maxPages:f},{env:$}),d=yn(b),u=new Set(d.map(l=>l.key)),m=new Set((Array.isArray(b?.coverage)?b.coverage:[]).filter(l=>l?.status==="ok"&&l?.complete===!0).map(l=>String(l.chain||"").toLowerCase()).filter(Boolean));m.size&&h.mutate(l=>{for(let E of Object.keys(l.collections)){let k=E.slice(0,E.indexOf(":"));m.has(k)&&!u.has(E)&&delete l.collections[E]}for(let E of Object.keys(l.failures||{})){let k=E.slice(0,E.indexOf(":"));m.has(k)&&!u.has(E)&&delete l.failures[E]}});let p=h.mutate(l=>{let E=d.length?(l.cursor||0)%d.length:0;return l.cursor=d.length?(E+Math.min(c,d.length))%d.length:0,E}),S=[];for(let l=0;l<Math.min(c,d.length);l+=1)S.push(d[(p+l)%d.length]);let A=[],g=[];for(let l of S){let E=h.inspect().data.failures?.[l.key];if(E&&E.nextCheckAt>_){g.push({key:l.key,reason:"floor-provider-backoff"});continue}let k;try{k=await o(l.slug,{env:$,expectedChain:l.chain,expectedContract:l.contract})}catch{T(l.key,_),g.push({key:l.key,reason:"floor-provider-unavailable"});continue}let x=Yo(k,l);if(!x.ok){T(l.key,_),g.push({key:l.key,reason:x.reason});continue}let I=hn(k?.floor);if(I===null){T(l.key,_),g.push({key:l.key,reason:"floor-unavailable"});continue}let R=h.mutate(L=>{L.failures||={},delete L.failures[l.key];let N=L.collections[l.key];if(!N)return L.collections[l.key]={anchorFloor:I,lastAlertAt:null,updatedAt:_,currency:x.currency},null;if(N.updatedAt=_,N.currency!==x.currency)return N.anchorFloor=I,N.currency=x.currency,N.lastAlertAt=null,null;if(I<N.anchorFloor)return N.anchorFloor=I,N.currency=x.currency,null;if((I/N.anchorFloor-1)*100+1e-9<s)return null;if(N.lastAlertAt!==null&&_-N.lastAlertAt<a)return N.anchorFloor=I,N.currency=x.currency,null;let K=Jo({...l,name:k?.name||l.name},I,x.currency,N,_);return N.anchorFloor=I,N.lastAlertAt=_,N.updatedAt=_,N.currency=x.currency,K});if(!R)continue;let U;try{U=await i(R)}catch{U=null}if(!U||Number(U.delivered||0)!==1){g.push({key:l.key,reason:"notification-delivery-failed"});continue}A.push(R)}return{provider:"held-nft-pump",readOnly:!0,custody:"none",executionAllowed:!1,heldCollections:d.length,checkedCollections:S.length,alerts:A,unavailable:g,coverage:b?.coverage??[]}}finally{w=!1}}return Object.freeze({filePath:h.filePath,tick:v,inspect:h.inspect})}function ue(e,t=160){return String(e??"").replace(/[\u0000-\u001f\u007f]/g," ").slice(0,t)}function mt(e){let t=Number(e);return Number.isFinite(t)?t:null}function Qo(e,t={},n=process.env){let r=String(e||"").trim().toUpperCase().replace(/[^A-Z0-9]/g,"");if(!r)return[];let o=String(n[`ORACLE_OWNER_${r}`]||"").split(/[\s,;]+/).filter(Boolean),i=Array.isArray(t.owners)?t.owners.map(String):[];return[...new Set([...o,...i].map(s=>s.trim()).filter(Boolean))]}function bn(e={}){let t=typeof e.heldCount=="string"&&/^\d+$/.test(e.heldCount)?e.heldCount:Number.isSafeInteger(Number(e.heldCount))?String(Number(e.heldCount)):"unknown",n=mt(e.fromFloor),r=mt(e.floor),o=mt(e.changePct),i=ue(e.currency||"unknown",16);return`ORACLE NFT \u2014 YOUR BAG IS PUMPING
1
+ var we=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(r){throw n=[r],r}};import{AsyncLocalStorage as Er}from"node:async_hooks";function Fe(e){let t=Sr.getStore();if(!t||t.closed||!Ar.includes(e))return null;if(t.spans.length>=vr)return t.droppedSpans++,null;let n={stage:e,startMs:t.now()-t.start,durationMs:null,outcome:"pending",status:null};return t.spans.push(n),(r,o=null)=>{t.closed||n.durationMs!==null||(n.durationMs=Math.max(0,t.now()-t.start-n.startMs),n.outcome=r==="succeeded"?"succeeded":"failed",n.status=Number.isInteger(o)&&o>=100&&o<=599?o:null)}}var Sr,Ar,vr,Ut=we(()=>{Sr=new Er,Ar=["http","retry","shared"],vr=512});import ae from"node:net";import xr from"node:dns";function Ue(e){let t=String(e).toLowerCase().split("%")[0];if((t.match(/::/g)||[]).length>1)return null;let n=p=>{if(!p)return[];let w=p.split(":"),T=w.at(-1);if(T?.includes(".")){let x=T.split(".").map(Number);if(x.length!==4||x.some(b=>!Number.isInteger(b)||b<0||b>255))return null;w.splice(w.length-1,1,(x[0]<<8|x[1]).toString(16),(x[2]<<8|x[3]).toString(16))}return w.some(x=>!/^[0-9a-f]{1,4}$/.test(x))?null:w.map(x=>Number.parseInt(x,16))},[r,o]=t.split("::"),i=n(r),s=n(o);if(!i||!s)return null;let a=t.includes("::"),c=8-i.length-s.length;if(!a&&c!==0||a&&c<1)return null;let h=[...i,...Array(Math.max(0,c)).fill(0),...s];return h.length!==8?null:Uint8Array.from(h.flatMap(p=>[p>>8,p&255]))}function et(e,t,n){let r=Math.floor(n/8),o=n%8;for(let s=0;s<r;s+=1)if(e[s]!==t[s])return!1;if(!o)return!0;let i=255<<8-o;return(e[r]&i)===(t[r]&i)}function tt(e){if(ae.isIPv4(e)){let t=e.split(".").map(Number);return!(t[0]===0||t[0]===10||t[0]===127||t[0]>=224||t[0]===100&&t[1]>=64&&t[1]<=127||t[0]===169&&t[1]===254||t[0]===172&&t[1]>=16&&t[1]<=31||t[0]===192&&(t[1]===0||t[1]===2||t[1]===168)||t[0]===192&&t[1]===88&&t[2]===99||t[0]===198&&(t[1]===18||t[1]===19||t[1]===51)||t[0]===203&&t[1]===0&&t[2]===113)}if(ae.isIPv6(e)){let t=Ue(e);if(!t)return!1;let n=Ue("::ffff:0:0");return et(t,n,96)?tt([...t.slice(12)].join(".")):et(t,Ue("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,i])=>et(t,Ue(o),i)):!1}return!1}function Tr(e){let t;try{t=new URL(String(e))}catch{return{ok:!1,error:`not a valid URL: ${String(e).slice(0,120)}`}}if(t.protocol!=="http:"&&t.protocol!=="https:")return{ok:!1,error:`refused protocol ${t.protocol} (only http/https)`};let n=t.hostname.toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,"");if(kr.has(n)||n.endsWith(".localhost")||n.endsWith(".internal"))return{ok:!1,error:`refused internal host ${n}`};let r=ae.isIP(n);return r!==0&&!tt(n)?{ok:!1,error:`refused private address ${n}`}:{ok:!0,url:t,host:n,isLiteralIp:r!==0}}async function Ae(e,{lookupFn:t=xr.promises.lookup}={}){let n=Tr(e);if(!n.ok)return n;if(n.isLiteralIp)return{ok:!0,url:n.url,addresses:[{address:n.host,family:ae.isIPv6(n.host)?6:4}]};let r;if(process.env.ORACLE_HOSTED_EGRESS_PROXY)return{ok:!0,url:n.url,addresses:[]};try{r=await t(n.host,{all:!0,verbatim:!0})}catch{return{ok:!1,error:`refused: ${n.host} did not resolve`}}return!Array.isArray(r)||r.length===0||r.some(o=>!tt(o.address))?{ok:!1,error:`refused: ${n.host} resolves to a non-public address`}:{ok:!0,url:n.url,addresses:r}}function Ir(e=process.env){let t=e.ORACLE_HOSTED_EGRESS_PROXY||"";if(!t)return null;let n;try{n=new URL(t)}catch{throw new Error("egress-guard: ORACLE_HOSTED_EGRESS_PROXY is not a URL")}if(n.protocol!=="http:"||!["127.0.0.1","::1","localhost","[::1]"].includes(n.hostname)||!n.port||n.username||n.password)throw new Error("egress-guard: egress proxy must be an exact loopback http origin");let r=e.ORACLE_HOSTED_EGRESS_TOKEN||"";if(!/^[A-Za-z0-9_-]{43}$/.test(r))throw new Error("egress-guard: egress proxy token is missing");return{uri:n.origin,token:r}}async function nt({requireUndici:e=!1,importUndici:t=()=>import("undici")}={}){let n,r,o;try{o=await t(),n=o.Agent,r=o.fetch}catch(x){if(e)throw new Error(`egress-guard: untrustedUrl pinning requires the undici package, which failed to load: ${x?.message||x}`);return null}if(typeof n!="function"||typeof r!="function"){if(e)throw new Error("egress-guard: untrustedUrl pinning requires undici's Agent and fetch exports, which were not found on the imported module");return null}let i=x=>String(x).toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,""),s=new Map,a=x=>(Array.isArray(x)?x:[x]).map(b=>typeof b=="string"?{address:b}:b).filter(b=>b&&b.address).map(b=>({address:b.address,family:b.family||(ae.isIPv6(b.address)?6:4)})),c=(x,b,I)=>{s.set(i(x),a(typeof b=="string"?[{address:b,family:I}]:b))},h=x=>{let b=i(x);if(ae.isIP(b))return[{address:b,family:ae.isIPv6(b)?6:4}];let I=s.get(b);if(!I||!I.length)throw new Error(`refused: unpinned host ${x} during pinned fetch`);return I},p=Ir(),w=p&&typeof o.ProxyAgent=="function"?new o.ProxyAgent({uri:p.uri,token:`Bearer ${p.token}`,connectTimeout:1e4}):new n({connect:{lookup(x,b,I){let O;try{O=h(x)}catch($){return I($)}return b?.all?I(null,O):I(null,O[0].address,O[0].family)}}}),T=_r((x,b={})=>r(x,{...b,dispatcher:w}),c);return{dispatcher:w,fetch:T,pin:c,resolve:h,async close(){try{await w.destroy()}catch{}}}}function _r(e,t){if(typeof e!="function")throw new Error("markPinCapableFetch: fetchImpl must be a function");if(typeof t!="function")throw new Error("markPinCapableFetch: pin must be a function");return e[rt]=Object.freeze({pin:t}),e}function ot(e){return typeof e=="function"&&typeof e[rt]?.pin=="function"}function Mt(e,t,n){if(!ot(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[rt].pin(t,n)}var kr,rt,it=we(()=>{kr=new Set(["localhost","metadata.google.internal","metadata.goog"]);rt=Symbol.for("oracle.egressGuard.pinCapableFetch")});import{createHash as Nr}from"node:crypto";import{types as re}from"node:util";function H(e){return oe(`HTTP JSON body refused: ${e}`)}function Mr(e){return["isArgumentsObject","isArrayBuffer","isAnyArrayBuffer","isArrayBufferView","isBoxedPrimitive","isDataView","isDate","isExternal","isGeneratorObject","isKeyObject","isCryptoKey","isMap","isMapIterator","isModuleNamespaceObject","isNativeError","isPromise","isRegExp","isSet","isSetIterator","isTypedArray","isWeakMap","isWeakSet"].some(t=>typeof re[t]=="function"&&re[t](e))}function Dr(e){let t=[],n=0,r=0,o=0,i=0,s=new WeakSet,a=p=>{if(n+=Buffer.byteLength(p,"utf8"),n>ne.bytes)throw H("serialized byte limit exceeded");t.push(p)},c=p=>{if(Buffer.byteLength(p,"utf8")>ne.bytes)throw H("serialized byte limit exceeded");return JSON.stringify(p)},h=(p,w)=>{if(r+=1,r>ne.nodes)throw H("node limit exceeded");if(w>ne.depth)throw H("depth limit exceeded");if(p===null){a("null");return}if(typeof p=="string"){a(c(p));return}if(typeof p=="boolean"){a(p?"true":"false");return}if(typeof p=="number"){if(!Number.isFinite(p))throw H("non-finite number");a(Object.is(p,-0)?"0":String(p));return}if(typeof p!="object")throw H("unsupported non-JSON value");if(re.isProxy(p))throw H("proxy value");if(Mr(p))throw H("unsupported exotic object");if(s.has(p))throw H("cyclic value");s.add(p);try{if(Object.getOwnPropertySymbols(p).length>0)throw H("symbol-keyed fields are unsupported");if(Array.isArray(p)){let b=Object.getPrototypeOf(p),I=0;for(;b!==null;){if(re.isProxy(b))throw H("proxy array prototype");if(I+=1,I>ne.depth)throw H("array prototype depth limit exceeded");b=Object.getPrototypeOf(b)}if(p.length>ne.arrayLength)throw H("array length limit exceeded");for(let $=0;$<p.length;$+=1){let B=Object.getOwnPropertyDescriptor(p,String($));if(!B||!Object.hasOwn(B,"value")||B.enumerable!==!0)throw H("array entries must be dense enumerable own data")}let O=0;for(let $ in p){if(i+=1,i>ne.fields)throw H("enumeration limit exceeded");if(Object.hasOwn(p,$)&&(O+=1,O>p.length))throw H("named array fields are unsupported")}if(O!==p.length)throw H("array entries must be dense enumerable own data");a("[");for(let $=0;$<p.length;$+=1)$&&a(","),h(Object.getOwnPropertyDescriptor(p,String($)).value,w+1);a("]");return}let T=Object.getPrototypeOf(p);if(T!==Object.prototype&&T!==null)throw H("non-plain object");let x=[];for(let b in p){if(i+=1,i>ne.fields)throw H("enumeration limit exceeded");if(!Object.hasOwn(p,b))continue;if(o+=1,o>ne.fields)throw H("field limit exceeded");let I=Object.getOwnPropertyDescriptor(p,b);if(!I||!Object.hasOwn(I,"value")||I.enumerable!==!0)throw H("object fields must be enumerable own data");x.push([b,I.value])}a("{");for(let b=0;b<x.length;b+=1)b&&a(","),a(c(x[b][0])),a(":"),h(x[b][1],w+1);a("}")}finally{s.delete(p)}};return h(e,0),t.join("")}function Br(e){let t=Object.create(null);if(e==null)return t;if(typeof e!="object"&&typeof e!="function")throw new TypeError("HTTP headers must be an object");if(re.isProxy(e))throw new TypeError("HTTP headers must not be a proxy");if(Object.getOwnPropertySymbols(e).length>0)throw new TypeError("HTTP headers must not contain symbol fields");let n=new Set;for(let r of Object.keys(e)){if(!/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/u.test(r))throw new TypeError("HTTP header names must be valid tokens");let o=r.toLowerCase();if(n.has(o))throw new TypeError("HTTP headers contain a duplicate canonical name");n.add(o);let i=Object.getOwnPropertyDescriptor(e,r);if(!i||!Object.hasOwn(i,"value"))throw new TypeError("HTTP headers must contain own data properties");let s=i.value;if(s==null||["object","function","symbol"].includes(typeof s))throw new TypeError("HTTP header values must be scalar");t[r]=String(s)}return t}function qr(){return Object.assign(Object.create(null),{Accept:"application/json"})}function jr(e,t){if(!e)throw new Error(`HTTP redirect from ${t} missing Location`);let n=new URL(String(e),String(t));if(n.protocol!=="http:"&&n.protocol!=="https:")throw new Error(`HTTP redirect from ${t} used unsupported protocol ${n.protocol}`);return n.toString()}function Hr(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function Me(e){if((typeof e!="object"||e===null)&&typeof e!="function")return`${typeof e}:${String(e)}`;let t=Ht.get(e);return t||(t=Vt,Vt+=1,Ht.set(e,t)),`reference:${t}`}function zt(e){if(!e||typeof e!="object"||Array.isArray(e)||!Object.hasOwn(e,"jsonrpc")||!Object.hasOwn(e,"method")||e.jsonrpc!=="2.0")return!1;let t=typeof e.method=="string"?e.method:"";return t?Vr.has(t)||/^get[A-Z0-9_]/u.test(t)||/^is[A-Z0-9_]/u.test(t)||/^eth_get[A-Z0-9_]/u.test(t):!1}function Kt(e,t){if(e==="GET"&&t==null)return!0;if(e!=="POST"||t==null)return!1;let n=t;if(typeof t=="string")try{n=JSON.parse(t)}catch{return!1}if(Array.isArray(n))return n.length>0&&n.every(zt);if(!n||typeof n!="object")return!1;if(Object.hasOwn(n,"jsonrpc")||Object.hasOwn(n,"method"))return zt(n);let r=Object.hasOwn(n,"type")?n.type:null;return typeof r=="string"&&zr.has(r)&&(!Object.hasOwn(n,"action")||n.action==null)&&(!Object.hasOwn(n,"signature")||n.signature==null)&&(!Object.hasOwn(n,"nonce")||n.nonce==null)}function Kr(e,t,n,r={},o=null){let i=Nr("sha256"),s=(c,h)=>{let p=String(h);i.update(String(Buffer.byteLength(c,"utf8"))).update(":").update(c),i.update("=").update(String(Buffer.byteLength(p,"utf8"))).update(":").update(p).update(`
2
+ `)};s("method",e),s("url",t),Object.keys(n||{}).map((c,h)=>({name:c.toLowerCase(),order:h,value:String(n[c])})).sort((c,h)=>c.name.localeCompare(h.name)||c.order-h.order).forEach((c,h)=>{s(`header-name-${h}`,c.name),s(`header-value-${h}`,c.value)}),s("body",o??"-");for(let c of["untrustedUrl","maxResponseBytes","sameOriginRedirectsOnly","redirectPolicy","maxRedirects","timeoutMs","retries","fetchImpl","realFetch","lookupFn","importUndici","validateResponse"])s(`context-${c}`,r[c]??"-");return i.digest("hex")}function Wr(e,t){let n=Number(t);return Number.isFinite(n)&&n>0?Math.min(n*1e3,Bt):Math.min(250*2**e,Bt)+Math.floor(Math.random()*100)}function oe(e,t={}){let n=new Error(e);return n.retryable=!1,Object.assign(n,t),n}function at(e,t,n){return oe(`HTTP response from ${e} exceeded maxResponseBytes ${n} (${t})`,{oversize:!0})}function ce(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function Yr(e){return e?e.byteLength??e.length??0:0}async function Jr(e,t,{url:n,truncate:r=!1,onOversize:o}={}){if(t==null)return await e.text();let i=Number(e.headers?.get?.("content-length"));if(Number.isFinite(i)&&i>t&&(ce(e),!r))throw at(n,`content-length ${i}`,t);let s=e.body?.getReader?.();if(!s){let w=await e.text(),T=Buffer.byteLength(w,"utf8");if(T>t){if(!r)throw at(n,`body ${T} bytes`,t);return Buffer.from(w,"utf8").subarray(0,t).toString("utf8")}return w}let a=[],c=0,h=!1;try{for(;;){let{value:w,done:T}=await s.read();if(T)break;if(w&&(a.push(Buffer.from(w)),c+=Yr(w),c>t)){h=!0;break}}}finally{if(h)try{await s.cancel()}catch{}try{s.releaseLock?.()}catch{}}if(h&&(typeof o=="function"&&o(),!r))throw at(n,`streamed ${c} bytes`,t);let p=Buffer.concat(a);return(h?p.subarray(0,t):p).toString("utf8")}function Zr(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function Xr(e,{fetchImpl:t,method:n,headers:r,body:o,timeoutMs:i,lookupFn:s,realFetch:a,untrustedUrl:c=!1,maxResponseBytes:h=null,sameOriginRedirectsOnly:p=!1,importUndici:w,validateResponse:T,signal:x,redirectPolicy:b="follow",maxRedirects:I=De}){let O=null,$=t,B=s?{lookupFn:s}:{};if(c&&!a&&!ot($))throw oe(`HTTP refused ${e}: untrustedUrl requires a pin-capable fetchImpl (see markPinCapableFetch in egress-guard.mjs) or no fetchImpl override so Oracle can pin the connection itself`);let y=new AbortController,d=setTimeout(()=>y.abort(),i),u=x?jt?jt([x,y.signal]):x:y.signal,m=async(f,{status:S=null}={})=>{let A=await Ae(f,B);if(!A.ok)throw oe(S==null?`HTTP refused ${f}: ${A.error}`:`HTTP redirect to ${f} ${A.error}`,S==null?{}:{status:S});let g=new URL(f).hostname;if(a){if(O&&(await O.close(),O=null),!O)try{O=await nt({requireUndici:!0,...w?{importUndici:w}:{}})}catch(l){throw oe(S==null?`HTTP refused ${f}: ${l?.message||l}`:`HTTP redirect to ${f} refused: ${l?.message||l}`,S==null?{}:{status:S})}O.pin(g,A.addresses),$=O.fetch}else Mt($,g,A.addresses);return A};try{let f=String(e),S=Object.assign(Object.create(null),r||{});c&&await m(f);for(let A=0;A<=I;A+=1){let g=Object.assign(Object.create(null),{method:n,headers:S,body:o,signal:u,redirect:"manual",dispatcher:void 0}),l=await $(f,g);if((b==="error"||I===0)&&l.status>=300&&l.status<400)throw ce(l),oe(`HTTP ${l.status} ${n} redirect refused`,{status:l.status,redirectRefused:!0});if(Ur.has(l.status)){let v=p===!0&&n==="POST"&&[307,308].includes(l.status)&&Kt(n,o);if(n!=="GET"&&n!=="HEAD"&&!v){ce(l);let F=new Error(`HTTP ${l.status} ${n} ${f} redirected non-idempotent request`);throw F.status=l.status,F}if(A===I)throw ce(l),oe(`HTTP ${l.status} ${n} redirect budget exhausted`,{status:l.status,redirectRefused:!0});let _=l.headers?.get?.("location"),R;try{R=jr(_,f)}catch(F){throw ce(l),F}let U=!Hr(R,f);if(ce(l),U&&n==="POST"){let F=new Error(`HTTP ${l.status} ${n} cross-origin redirect refused`);throw F.status=l.status,F}if(U&&p){let F=new Error(`HTTP ${l.status} ${n} cross-origin redirect refused`);throw F.status=l.status,F.retryable=!1,F}if(U&&(S=qr(S)),c)await m(R,{status:l.status});else if(U){let F=await Ae(R,B);if(!F.ok){let N=new Error(`HTTP redirect from ${f} ${F.error}`);throw N.status=l.status,N.retryable=!1,N}a&&F.addresses?.length&&(O||(O=await nt(w?{importUndici:w}:{})),O&&(O.pin(new URL(R).hostname,F.addresses),$=O.fetch))}f=R;continue}if(typeof T=="function")try{await T(l,{url:f})}catch(v){throw ce(l),oe(v?.message||String(v))}let E=await Jr(l,h,{url:f,onOversize:()=>y.abort()}),k=Zr(E);if(!l.ok){let v=new Error(`HTTP ${l.status} ${n} ${f}`);throw v.status=l.status,v.retryAfter=l.headers?.get?.("retry-after")??null,v.body=k??E.slice(0,300),v}return k??E}throw new Error(`HTTP redirect loop for ${e}`)}catch(f){if(y.signal.aborted&&!ve(x)){let S=f&&(typeof f=="object"||typeof f=="function")&&!re.isProxy(f)?f:null,A=S?Object.getOwnPropertyDescriptor(S,"oversize"):null;if(!(A&&Object.hasOwn(A,"value")&&A.value===!0))try{if(!S)throw new TypeError("unsafe rejection");Object.defineProperties(S,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}})}catch{let l=new Error("HTTP request timed out");throw Object.defineProperties(l,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}}),l}}throw f}finally{clearTimeout(d),O&&await O.close()}}async function V(e,t={}){if(t!=null&&typeof t!="object"&&typeof t!="function")throw new TypeError("HTTP options must be an object");if(t!=null&&re.isProxy(t))throw new TypeError("HTTP options must not be a proxy");let n=new Set(["body","dedupe","fetchImpl","headers","importUndici","lookupFn","maxRedirects","maxResponseBytes","method","redirectPolicy","retries","sameOriginRedirectsOnly","signal","timeoutMs","untrustedUrl","validateResponse"]);if(t!=null){if(Object.getOwnPropertySymbols(t).length>0)throw new TypeError("HTTP options contain unknown fields");for(let N of Object.getOwnPropertyNames(t)){let L=Object.getOwnPropertyDescriptor(t,N);if(!(N==="toJSON"&&L&&Object.hasOwn(L,"value")&&L.value===void 0)){if(!n.has(N))throw new TypeError("HTTP options contain unknown fields");if(!L||!L.enumerable||!Object.hasOwn(L,"value"))throw new TypeError("HTTP options must contain enumerable own data properties")}}}let r=N=>{if(t==null||!Object.hasOwn(t,N))return;let L=Object.getOwnPropertyDescriptor(t,N);if(!L||!Object.hasOwn(L,"value"))throw new TypeError("HTTP options must contain own data properties");return L.value};if(typeof e!="string"||e.length===0||e.length>8192)throw new TypeError("HTTP URL must be a bounded string");let o=r("method");if(o!==void 0&&(typeof o!="string"||!/^[A-Za-z]+$/u.test(o)))throw new TypeError("HTTP method must be a string token");let i=r("timeoutMs");if(i!==void 0&&(!Number.isInteger(i)||i<1||i>12e4))throw new TypeError("HTTP timeoutMs must be a bounded integer");let s=r("retries");if(s!==void 0&&(!Number.isInteger(s)||s<0||s>10))throw new TypeError("HTTP retries must be a bounded integer");let a=r("redirectPolicy");if(a!==void 0&&a!=="follow"&&a!=="error")throw new TypeError('HTTP redirectPolicy must be "follow" or "error"');let c=r("maxRedirects");if(c!==void 0&&(!Number.isInteger(c)||c<0||c>De))throw new TypeError(`HTTP maxRedirects must be an integer from 0 through ${De}`);if(a==="error"&&c!==void 0&&c!==0)throw new TypeError('HTTP redirectPolicy "error" requires maxRedirects 0 when supplied');let h=a??"follow",p=h==="error"?0:c??De;for(let N of["dedupe","untrustedUrl","sameOriginRedirectsOnly"]){let L=r(N);if(L!==void 0&&typeof L!="boolean")throw new TypeError(`HTTP ${N} must be boolean`)}let w=r("maxResponseBytes");if(w!==void 0&&(!Number.isInteger(w)||w<1||w>64*1024*1024))throw new TypeError("HTTP maxResponseBytes must be a bounded integer");let T=r("signal");if(T!==void 0){if(re.isProxy(T)||!(T instanceof AbortSignal))throw new TypeError("HTTP signal must be a native AbortSignal");try{ve(T)}catch{throw new TypeError("HTTP signal must be a native AbortSignal")}}for(let N of["importUndici","lookupFn","validateResponse"]){let L=r(N);if(L!==void 0&&typeof L!="function")throw new TypeError(`HTTP ${N} must be a function`)}let x=r("fetchImpl"),b=x||globalThis.fetch;if(typeof b!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let I=i??12e3,O=(o||"GET").toUpperCase(),$=r("headers"),B=Br($),y=Object.assign(Object.create(null),B);Object.keys(y).some(N=>N.toLowerCase()==="accept")||(y.Accept="application/json");let d=r("body");d!=null&&typeof d!="string"&&(Object.keys(y).find(L=>L.toLowerCase()==="content-type")||(y["Content-Type"]="application/json"),d=Dr(d));let u=s??Cr,m=r("lookupFn"),f=!x,S=r("untrustedUrl")===!0,A=r("sameOriginRedirectsOnly")===!0,g=r("importUndici"),l=r("validateResponse"),E=T,k=w??null,v=async()=>{let N;for(let L=0;L<=u;L++){E&&$r.call(E);let Z=Fe("http");try{let q=await Xr(e,{fetchImpl:b,method:O,headers:y,body:d,timeoutMs:I,lookupFn:m,realFetch:f,untrustedUrl:S,maxResponseBytes:k,sameOriginRedirectsOnly:A,importUndici:g,validateResponse:l,signal:E,redirectPolicy:h,maxRedirects:p});return Z?.("succeeded"),q}catch(q){N=q;let de=Ge=>{if(!q||typeof q!="object"&&typeof q!="function"||re.isProxy(q))return;let ye=Object.getOwnPropertyDescriptor(q,Ge);return ye&&Object.hasOwn(ye,"value")?ye.value:void 0},Ie=de("status");Z?.("failed",Ie);let Ln=de("oracleTimeout")===!0||de("name")==="AbortError"||de("name")==="TimeoutError"||ve(E),Fn=new Set([408,425,429]),Un=de("retryable")===!1?!1:Ie!=null?Fn.has(Ie)||Or.has(Ie)&&Dt.has(O):!Ln&&Dt.has(O);if(L===u||!Un)throw q;let wt=Wr(L,de("retryAfter")),Mn=Fe("retry"),gt=!1;try{E?await new Promise((Ge,ye)=>{let Et,be=()=>{clearTimeout(Et),qt.call(E,"abort",be),ye(Fr(E)||new DOMException("Aborted","AbortError"))};if(ve(E)){be();return}Et=setTimeout(()=>{qt.call(E,"abort",be),Ge()},wt),Lr.call(E,"abort",be,{once:!0}),ve(E)&&be()}):await Gr(wt),gt=!0}finally{Mn?.(gt?"succeeded":"failed")}}}throw N};if(!(r("dedupe")!==!1&&!E&&Kt(O,d)))return v();let R=Kr(O,e,y,{untrustedUrl:S,maxResponseBytes:k,sameOriginRedirectsOnly:A,redirectPolicy:h,maxRedirects:p,timeoutMs:I,retries:u,fetchImpl:Me(b),realFetch:f,lookupFn:Me(m),importUndici:Me(g),validateResponse:Me(l)},d),U=st.get(R);if(U){let N=Fe("shared");try{let L=await U;return N?.("succeeded"),L}catch(L){throw N?.("failed"),L}}let F=v().finally(()=>st.delete(R));return st.set(R,F),F}async function Be(e){let t=Date.now();try{let n=await e();return{ok:!0,ms:Date.now()-t,data:n}}catch(n){return{ok:!1,ms:Date.now()-t,error:String(n.message||n),status:n.status??null}}}async function xe(e,t,n){let r=Array.from(e),o=Math.max(1,Math.min(Number(t)||1,r.length||1)),i=new Array(r.length),s=0;return await Promise.all(Array.from({length:o},async()=>{for(;s<r.length;){let a=s++;i[a]=await n(r[a],a)}})),i}var Or,Dt,Cr,Bt,Pr,Rr,$r,Lr,qt,jt,ve,Fr,Ur,De,is,ne,st,Ht,Vt,Vr,zr,Gr,z=we(()=>{Ut();it();Or=new Set([408,425,429,500,502,503,504]),Dt=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),Cr=2,Bt=4e3,Pr=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"aborted")?.get,Rr=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"reason")?.get,$r=AbortSignal.prototype.throwIfAborted,Lr=EventTarget.prototype.addEventListener,qt=EventTarget.prototype.removeEventListener,jt=typeof AbortSignal.any=="function"?AbortSignal.any.bind(AbortSignal):null,ve=e=>e?Pr.call(e):!1,Fr=e=>e?Rr.call(e):void 0,Ur=new Set([301,302,303,307,308]),De=3,is=64*1024,ne=Object.freeze({depth:32,nodes:1e4,fields:1e4,arrayLength:1e4,bytes:1024*1024});st=new Map,Ht=new WeakMap,Vt=1;Vr=new Set(["eth_blockNumber","eth_call","eth_chainId","eth_estimateGas","getHealth","minimumLedgerSlot","net_version","simulateTransaction","web3_clientVersion"]),zr=new Set(["allMids","l2Book","outcomeMeta","spotClearinghouseState","userFills","meta","metaAndAssetCtxs","perpDexs","candleSnapshot","fundingHistory","openOrders","frontendOpenOrders","clearinghouseState","spotMeta","validatorSummaries","delegatorSummary","delegations","delegatorRewards","delegatorHistory","maxBuilderFee"]);Gr=e=>new Promise(t=>setTimeout(t,e))});var Zt,hs,Xt=we(()=>{Zt={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}},hs=new Map(Object.values(Zt).map(e=>[e.chainId,e]))});import{Interface as oo,getAddress as vs}from"ethers";var xs,ke=we(()=>{z();Xt();xs=new oo(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"])});import M from"node:fs";import _e from"node:path";import{createHash as Dn,randomUUID as St}from"node:crypto";var Ce=1,W=class extends Error{constructor(t,n="DURABLE_STORE_ERROR"){super(t),this.name="DurableStoreError",this.code=n}};function Y(e){if(e===null)return"null";if(typeof e=="string"||typeof e=="boolean")return JSON.stringify(e);if(typeof e=="number"){if(!Number.isFinite(e))throw new TypeError("durable store values must contain finite numbers");return JSON.stringify(e)}if(Array.isArray(e))return`[${e.map(Y).join(",")}]`;if(e&&typeof e=="object")return`{${Object.keys(e).sort().map(n=>`${JSON.stringify(n)}:${Y(e[n])}`).join(",")}}`;throw new TypeError(`durable store values must be JSON-safe, got ${typeof e}`)}function At(e){return Dn("sha256").update(Y(e)).digest("hex")}function Ne(e){let t=e(),n=t instanceof Date?t.getTime():typeof t=="string"?Date.parse(t):Number(t);if(!Number.isFinite(n))throw new TypeError("clock must return epoch milliseconds, an ISO string, or a Date");return Math.trunc(n)}function Oe(e){return e===void 0?void 0:JSON.parse(JSON.stringify(e))}function vt(e){M.mkdirSync(e,{recursive:!0,mode:448});try{M.chmodSync(e,448)}catch{}}function Ye(e){try{let t=M.statSync(e);return{...JSON.parse(M.readFileSync(e,"utf8")),mtimeMs:t.mtimeMs}}catch{return null}}function te({filePath:e,kind:t,initialData:n,validateData:r,clock:o=()=>Date.now(),maxBytes:i=4*1024*1024,lockStaleMs:s=3e4,lockWaitMs:a=2e3,lockIdFactory:c=()=>St()}={}){if(typeof e!="string"||e==="")throw new TypeError("filePath is required");if(!/^[a-z][a-z0-9._-]{0,63}$/i.test(String(t)))throw new TypeError("a bounded store kind is required");if(typeof n!="function"||typeof r!="function")throw new TypeError("initialData and validateData are required");if(!Number.isSafeInteger(i)||i<1024)throw new TypeError("maxBytes must be at least 1024");if(!Number.isSafeInteger(s)||s<1e3)throw new TypeError("lockStaleMs must be at least 1000");if(!Number.isSafeInteger(a)||a<0||a>3e4)throw new TypeError("lockWaitMs must be between 0 and 30000");let h=`${e}.lock`;function p(){let y=n();return r(y),{schemaVersion:Ce,kind:t,generation:0,data:y}}function w(y){let d;try{d=JSON.parse(y)}catch(f){throw new W(`corrupt ${t} snapshot: invalid JSON (${f.message})`,"STORE_CORRUPT")}if(!d||typeof d!="object"||Array.isArray(d))throw new W(`corrupt ${t} snapshot: root must be an object`,"STORE_CORRUPT");if(d.schemaVersion!==Ce)throw new W(`unsupported ${t} schemaVersion ${String(d.schemaVersion)}`,"STORE_SCHEMA");if(d.kind!==t||!Number.isSafeInteger(d.generation)||d.generation<0)throw new W(`corrupt ${t} snapshot metadata`,"STORE_CORRUPT");let{integrity:u,...m}=d;if(typeof u!="string"||!/^[a-f0-9]{64}$/.test(u)||At(m)!==u)throw new W(`corrupt ${t} snapshot: checksum mismatch`,"STORE_CORRUPT");try{r(d.data)}catch(f){throw new W(`corrupt ${t} snapshot: ${f.message}`,"STORE_CORRUPT")}return m}function T(){if(!M.existsSync(e))return p();let y=M.statSync(e);if(!y.isFile()||y.size>i)throw new W(`${t} snapshot is not a bounded regular file`,"STORE_BOUNDS");try{M.chmodSync(e,384)}catch{}return w(M.readFileSync(e,"utf8"))}function x(){vt(_e.dirname(e));let y=Ne(o),d=String(c()),u=`${JSON.stringify({schemaVersion:1,lockId:d,pid:process.pid,acquiredAt:y})}
3
+ `,m=()=>{let g;try{return g=M.openSync(h,"wx",384),M.writeFileSync(g,u,"utf8"),M.fsyncSync(g),M.closeSync(g),{lockId:d}}catch(l){let E=g!==void 0;if(E)try{M.closeSync(g)}catch{}if(E)try{M.unlinkSync(h)}catch{}if(l?.code!=="EEXIST")throw l;return null}},S=Ne(o)+a,A=new Int32Array(new SharedArrayBuffer(4));for(;;){let g=m();if(g)return g;let l=Ne(o),E=Ye(h),k=!1;if(E){let _=l-Number(E.acquiredAt??E.mtimeMs);k=Number.isFinite(_)&&_>=s}else try{k=l-M.statSync(h).mtimeMs>=s}catch{k=!1}if(k){let _=Ye(h);if(E?_?.lockId===E.lockId:_===null){try{M.unlinkSync(h)}catch(U){if(U?.code!=="ENOENT")throw U}continue}}let v=S-l;if(v<=0)throw new W(`${t} store is busy`,"STORE_BUSY");Atomics.wait(A,0,0,Math.min(10,v))}}function b(y){if(Ye(h)?.lockId===y.lockId)try{M.unlinkSync(h)}catch(u){if(u?.code!=="ENOENT")throw u}}function I(y){r(y.data);let d={...y,integrity:At(y)},u=`${Y(d)}
4
+ `;if(Buffer.byteLength(u)>i)throw new W(`${t} snapshot exceeds ${i} bytes`,"STORE_BOUNDS");let m=_e.dirname(e);vt(m);let f=_e.join(m,`.${_e.basename(e)}.${process.pid}.${St()}.tmp`),S;try{S=M.openSync(f,"wx",384),M.writeFileSync(S,u,"utf8"),M.fsyncSync(S),M.closeSync(S),S=void 0,M.renameSync(f,e);try{M.chmodSync(e,384)}catch{}try{let A=M.openSync(m,"r");try{M.fsyncSync(A)}finally{M.closeSync(A)}}catch{}}finally{if(S!==void 0)try{M.closeSync(S)}catch{}try{M.unlinkSync(f)}catch(A){if(A?.code!=="ENOENT")throw A}}}function O(){return Oe(T().data)}function $(){let y=T();return{schemaVersion:y.schemaVersion,kind:y.kind,generation:y.generation,data:Oe(y.data)}}function B(y){if(typeof y!="function")throw new TypeError("mutator must be a function");let d=x();try{let u=T(),m=Oe(u.data),f=y(m,{generation:u.generation,now:Ne(o)});return r(m),I({schemaVersion:Ce,kind:t,generation:u.generation+1,data:m}),Oe(f)}finally{b(d)}}return Object.freeze({filePath:e,read:O,inspect:$,mutate:B})}import{createHash as rr}from"node:crypto";var Je=Object.freeze(["price","wallet","risk","execution","security","nft","governance","system"]),Bn=new Set(Je);function qn(e){if(!Bn.has(e))throw new TypeError(`Unknown watch category: ${String(e)}`);return e}function jn(e={}){let t=e.subscribedCategories??[];if(!Array.isArray(t))throw new TypeError("subscribedCategories must be an array");return t}function Hn(){return{subscribedCategories:[]}}function Vn(e,t){return!(!t||t.notify!==!0||t.category!==e.category||e.watchId!==void 0&&t.id!==e.watchId)}function xt(e,t=Hn(),n){if(!e||typeof e!="object")throw new TypeError("alert must be an object");return qn(e.category),jn(t).includes(e.category)?{deliver:!0,reason:"category-subscribed"}:Vn(e,n)?{deliver:!0,reason:"watch-opt-in"}:{deliver:!1,reason:"not-subscribed"}}var zn=(process.env.ORACLE_REDACT_SECRETS??"true").toLowerCase(),Kn=["1","true","yes","on"].includes(zn),Wn=[/sk-[A-Za-z0-9_-]{10,}/g,/sk_live_[A-Za-z0-9]{10,}/g,/sk_test_[A-Za-z0-9]{10,}/g,/ghp_[A-Za-z0-9]{10,}/g,/github_pat_[A-Za-z0-9_]{10,}/g,/gho_[A-Za-z0-9]{10,}/g,/ghs_[A-Za-z0-9]{10,}/g,/xox[baprs]-[A-Za-z0-9-]{10,}/g,/AIza[A-Za-z0-9_-]{30,}/g,/AKIA[A-Z0-9]{16}/g,/pplx-[A-Za-z0-9]{10,}/g,/hf_[A-Za-z0-9]{10,}/g,/xai-[A-Za-z0-9]{30,}/g,/gsk_[A-Za-z0-9]{10,}/g,/npm_[A-Za-z0-9]{10,}/g,/tvly-[A-Za-z0-9]{10,}/g,/Bearer\s+[A-Za-z0-9\-._~+/]+=*/gi],Gn=/\b0x[a-fA-F0-9]{64}\b/g,Yn=/-----BEGIN (?:RSA |EC |OPENSSH |ENCRYPTED )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH |ENCRYPTED )?PRIVATE KEY-----/g,Jn=/\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g,Zn=/\b([A-Z][A-Z0-9_]{0,40}(?:API_?KEY|TOKEN|SECRET|PASSWORD|PASSWD|PRIVATE_?KEY|MNEMONIC|SEED|AUTH)[A-Z0-9_]{0,20})\s*=\s*(['"]?)(\S+)\2/g,Xn=/^(?:export\s+)?((?:api[_-]?key|token|secret|password|private[_-]?key|mnemonic|seed[_-]?phrase|authorization))\s*[:=]\s*(['"]?)([^\s&]+)\2/gim,Qn=/("(?:api[_-]?key|apiKey|access[_-]?token|refresh[_-]?token|client[_-]?secret|private[_-]?key|privateKey|secret|password|authorization|bearer|mnemonic|seedPhrase)"\s*:\s*")([^"]{6,})(")/gi,er=new Set(["access_token","refresh_token","id_token","token","api_key","apikey","client_secret","password","auth","jwt","session","secret","key","code","signature","x-amz-signature","private_key","authorization"]),_i=new Set([...er].map(e=>e.replace(/[^a-z0-9]/gi,"").toLowerCase()));function tr(e){let t=String(e??"");return t.length<18?"[REDACTED]":`${t.slice(0,6)}\u2026${t.slice(-4)}`}function nr(e){return`\xABredacted:${String(e??"").slice(0,4)}\u2026\xBB`}function kt(e,t={}){if(e==null)return e;let n=typeof e=="string"?e:String(e);if(!n||!(t.force||Kn))return n;let r=t.fileRead?nr:tr;n=n.replace(Yn,"[REDACTED_PRIVATE_KEY]"),n=n.replace(Gn,"[REDACTED_EVM_KEY]"),n=n.replace(Jn,o=>r(o));for(let o of Wn)o.lastIndex=0,n=n.replace(o,i=>r(i));return n=n.replace(Zn,(o,i,s,a)=>/^(?:os\.(?:getenv|environ)|process\.env|\$ENV\{)/.test(a)?`${i}=${s||""}${a}${s||""}`:`${i}=${s||""}${r(a)}${s||""}`),n=n.replace(Xn,(o,i,s,a)=>o.replace(a,r(a))),n=n.replace(Qn,(o,i,s,a)=>`${i}${r(s)}${a}`),n}var G=1,Tt=Object.freeze(["alert","prepare"]),It=Object.freeze(["LIVE","STALE","UNAVAILABLE","UNKNOWN"]),or=/^[A-Za-z0-9](?:[A-Za-z0-9._:-]{0,126}[A-Za-z0-9])?$/,ir=new Set(["secret","webhooksecret","password","passphrase","privatekey","mnemonic","seed","authorization","apikey","accesstoken","bearertoken","signingkey"]);function D(e,t){for(let[n,r]of[["tenantId",e],["workflowId",t]])if(typeof r!="string"||!or.test(r))throw new TypeError(`${n} must be a bounded, non-wildcard scope id`);return{tenantId:e,workflowId:t}}function P(e,t,{min:n=1,max:r=256}={}){if(typeof t!="string"||t.length<n||t.length>r||/[\u0000-\u001f\u007f]/.test(t))throw new TypeError(`${e} must be a string between ${n} and ${r} characters without control bytes`);return t}function J(e){if(!Je.includes(e))throw new TypeError(`Unknown watch category: ${String(e)}`);return e}function Pe(e){if(!Tt.includes(e))throw new TypeError(`notification work kind must be alert or prepare, got ${String(e)}`);return e}function pe(e,t="value",n=new Set){if(e!=null){if(typeof e=="function"||typeof e=="symbol"||typeof e=="bigint")throw new TypeError(`${t} must be JSON-safe`);if(typeof e=="number"&&!Number.isFinite(e))throw new TypeError(`${t} must contain finite numbers`);if(typeof e=="object"){if(n.has(e))throw new TypeError(`${t} must not contain cycles`);if(!Array.isArray(e)&&Object.getPrototypeOf(e)!==Object.prototype&&Object.getPrototypeOf(e)!==null)throw new TypeError(`${t} must contain plain JSON objects only`);if(n.add(e),Array.isArray(e))e.forEach((r,o)=>pe(r,`${t}[${o}]`,n));else for(let[r,o]of Object.entries(e)){let i=r.toLowerCase().replace(/[^a-z0-9]/g,"");if(ir.has(i))throw new TypeError(`${t}.${r} may contain secret material and is rejected`);pe(o,`${t}.${r}`,n)}n.delete(e)}}}function Ze(e,t,n){if(e==null)return e;if(typeof e=="string"){let o=kt(e,{force:!0});if(o!==e)throw new TypeError(`${t} may contain secret material and is rejected`);return o}if(typeof e!="object")return e;if(n.has(e))throw new TypeError(`${t} must not contain cycles`);if(n.add(e),Array.isArray(e)){let o=e.map((i,s)=>Ze(i,`${t}[${s}]`,n));return n.delete(e),o}let r={};for(let[o,i]of Object.entries(e))r[o]=Ze(i,`${t}.${o}`,n);return n.delete(e),r}function X(e,{name:t="payload",maxBytes:n=64*1024}={}){pe(e,t);let r=Ze(e,t,new Set),o;try{o=Y(r)}catch(i){throw new TypeError(`${t} must be JSON-safe: ${i.message}`)}if(Buffer.byteLength(o)>n)throw new TypeError(`${t} exceeds ${n} bytes`);return JSON.parse(o)}function se(e){let t=typeof e=="string"?e.toUpperCase():e?.status?.toUpperCase?.();return It.includes(t)?t:"UNKNOWN"}function ge(e){return rr("sha256").update(Y(e)).digest("hex")}function Ee({category:e,preferences:t,watch:n,watchId:r}={}){J(e);let o=xt({category:e,...r===void 0?{}:{watchId:r}},t,n);if(!o.deliver){let i=new Error(`notification category ${e} is not opted in`);throw i.name="NotificationOptInError",i.code="NOTIFICATION_NOT_OPTED_IN",i}return o}function C(e){if(!Number.isFinite(e))throw new TypeError("time must be finite");return new Date(Math.trunc(e)).toISOString()}function j(e){let t=e(),n=t instanceof Date?t.getTime():typeof t=="string"?Date.parse(t):Number(t);if(!Number.isFinite(n))throw new TypeError("clock must return epoch milliseconds, an ISO string, or a Date");return Math.trunc(n)}function sr(e,{onError:t=()=>{}}={}){if(typeof e!="function")throw new TypeError("event append function is required");return Object.freeze({append(n){try{let r=e(Object.freeze({...n}));r&&typeof r.then=="function"&&r.catch(t)}catch(r){t(r)}}})}function K(e,t){if(e){if(typeof e.append!="function")throw new TypeError("eventSink must expose append(event)");e.append(t)}}import _t from"node:path";import{homedir as ar}from"node:os";import{randomUUID as Nt}from"node:crypto";var Xe=1,Ct=new Set(["pending","leased","completed"]),cr=5*366*24*60;function lr(e=process.env){let t=e.ORACLE_CONFIG_DIR||_t.join(ar(),".config","oracle");return _t.join(t,"notification-schedules.v1.json")}function Re(e,t,n,r){if(!/^\d+$/.test(e))throw new TypeError(`invalid ${r} cron field`);let o=Number(e);if(!Number.isSafeInteger(o)||o<t||o>n)throw new TypeError(`${r} cron field is out of range`);return o}function Se(e,t,n,r,{weekday:o=!1}={}){let i=new Set,s=e==="*";if(!e||e.length>80)throw new TypeError(`invalid ${r} cron field`);for(let a of e.split(",")){if(!a)throw new TypeError(`invalid ${r} cron field`);let[c,h,p]=a.split("/");if(p!==void 0)throw new TypeError(`invalid ${r} cron step`);let w=h===void 0?1:Re(h,1,n-t+1,`${r} step`),T,x;if(c==="*")T=t,x=n;else if(c.includes("-")){let b=c.split("-");if(b.length!==2)throw new TypeError(`invalid ${r} cron range`);if(T=Re(b[0],t,n,r),x=Re(b[1],t,n,r),x<T)throw new TypeError(`invalid descending ${r} cron range`)}else if(T=Re(c,t,n,r),x=T,h!==void 0)throw new TypeError(`cron step requires * or a range in ${r}`);for(let b=T;b<=x;b+=w)i.add(o&&b===7?0:b)}if(i.size===0)throw new TypeError(`empty ${r} cron field`);return{values:i,wildcard:s}}function Le(e){if(typeof e!="string"||e.length>160)throw new TypeError("schedule must be a bounded string");let t=e.trim().toLowerCase();if(!t)throw new TypeError("schedule is required");if(t==="hourly")return Object.freeze({type:"interval",intervalMs:36e5,source:t});if(t==="daily")return Object.freeze({type:"interval",intervalMs:864e5,source:t});let n=t.match(/^every\s+([1-9]\d{0,5})\s*([mhd])$/);if(n){let s=n[2]==="m"?6e4:n[2]==="h"?36e5:864e5,a=Number(n[1])*s;if(!Number.isSafeInteger(a)||a<6e4||a>366*864e5)throw new TypeError("schedule interval must be between one minute and 366 days");return Object.freeze({type:"interval",intervalMs:a,source:t})}let r=t.match(/^at\s+(.+)$/);if(r){let s=r[1];if(!/^\d{4}-\d{2}-\d{2}t\d{2}:\d{2}:\d{2}(?:\.\d{3})?z$/.test(s))throw new TypeError("one-time schedule must use an ISO-8601 UTC time");let a=Date.parse(s);if(!Number.isFinite(a))throw new TypeError("invalid one-time schedule time");return Object.freeze({type:"at",atMs:a,source:`at ${new Date(a).toISOString()}`})}let o=t.split(/\s+/);if(o.length!==5)throw new TypeError(`invalid schedule: ${e}`);let i={minute:Se(o[0],0,59,"minute"),hour:Se(o[1],0,23,"hour"),day:Se(o[2],1,31,"day-of-month"),month:Se(o[3],1,12,"month"),weekday:Se(o[4],0,7,"day-of-week",{weekday:!0})};return Object.freeze({type:"cron",fields:i,source:t})}function $e(e,t){let n=typeof e=="string"?Le(e):e,r=t instanceof Date?t.getTime():typeof t=="string"?Date.parse(t):Number(t);if(!Number.isFinite(r))throw new TypeError("after must be a valid time");if(n.type==="interval")return Math.trunc(r)+n.intervalMs;if(n.type==="at")return n.atMs>r?n.atMs:null;if(n.type!=="cron")throw new TypeError("unknown parsed schedule type");let o=Math.floor(r/6e4)*6e4+6e4;for(let i=0;i<cr;i+=1,o+=6e4){let s=new Date(o),a=n.fields,c=a.day.values.has(s.getUTCDate()),h=a.weekday.values.has(s.getUTCDay()),p=a.day.wildcard&&a.weekday.wildcard?!0:a.day.wildcard?h:a.weekday.wildcard?c:c||h;if(a.minute.values.has(s.getUTCMinutes())&&a.hour.values.has(s.getUTCHours())&&a.month.values.has(s.getUTCMonth()+1)&&p)return o}throw new RangeError("cron schedule has no occurrence within five years")}function ur(e){if(!e||e.schemaVersion!==G)throw new TypeError("invalid schedule record version");if(D(e.tenantId,e.workflowId),P("schedule id",e.id,{max:128}),P("idempotencyKey",e.idempotencyKey,{max:160}),P("schedule name",e.name,{max:160}),Pe(e.kind),J(e.category),Le(e.schedule),e.startAt!==null&&!Number.isFinite(Date.parse(e.startAt)))throw new TypeError("invalid schedule startAt");if(typeof e.enabled!="boolean")throw new TypeError("schedule enabled must be boolean");if(e.nextRunAt!==null&&!Number.isFinite(Date.parse(e.nextRunAt)))throw new TypeError("invalid schedule nextRunAt");if(!Number.isFinite(Date.parse(e.createdAt))||!Number.isFinite(Date.parse(e.updatedAt)))throw new TypeError("invalid schedule timestamps");if(X(e.payload),!/^[a-f0-9]{64}$/.test(e.definitionFingerprint))throw new TypeError("invalid schedule fingerprint")}function dr(e){if(!e||e.schemaVersion!==G)throw new TypeError("invalid scheduled work version");if(D(e.tenantId,e.workflowId),P("work id",e.id,{max:128}),P("schedule id",e.scheduleId,{max:128}),P("work idempotencyKey",e.idempotencyKey,{max:512}),Pe(e.kind),J(e.category),!Ct.has(e.status))throw new TypeError("invalid scheduled work status");if(!Number.isSafeInteger(e.attempts)||e.attempts<0)throw new TypeError("invalid scheduled work attempts");if(e.executionAllowed!==!1||e.custody!=="none")throw new TypeError("scheduled work crossed the custody boundary");if(!Number.isFinite(Date.parse(e.scheduledFor))||!Number.isFinite(Date.parse(e.createdAt)))throw new TypeError("invalid work time");if(e.lease!==null&&(P("lease owner",e.lease.owner,{max:128}),P("lease token",e.lease.token,{max:160}),!Number.isFinite(Date.parse(e.lease.until))))throw new TypeError("invalid work lease");X(e.payload)}function pr(e,t){return n=>{if(!n||n.schemaVersion!==Xe||!Array.isArray(n.schedules)||!Array.isArray(n.work))throw new TypeError("invalid schedule store schema");if(n.schedules.length>e||n.work.length>t)throw new TypeError("schedule store record bound exceeded");let r=new Set,o=new Set;for(let a of n.schedules){if(ur(a),r.has(a.id))throw new TypeError("duplicate schedule id");let c=`${a.tenantId}\0${a.workflowId}\0${a.idempotencyKey}`;if(o.has(c))throw new TypeError("duplicate scoped schedule idempotency key");r.add(a.id),o.add(c)}let i=new Set,s=new Set;for(let a of n.work){if(dr(a),i.has(a.id)||s.has(a.idempotencyKey))throw new TypeError("duplicate scheduled work identity");i.add(a.id),s.add(a.idempotencyKey)}}}function Q(e,t,n){return e.tenantId===t&&e.workflowId===n}function Ot(e,t,n){if(e.status!=="leased"||!e.lease||e.lease.token!==t)throw new Error("scheduled work lease token does not match");if(Date.parse(e.lease.until)<=n)throw new Error("scheduled work lease expired")}function fr({filePath:e=lr(),clock:t=()=>Date.now(),idFactory:n=()=>Nt(),leaseTokenFactory:r=()=>Nt(),eventSink:o,maxSchedules:i=1e3,maxWork:s=5e3,maxBytes:a=8*1024*1024}={}){if(!Number.isSafeInteger(i)||i<1||!Number.isSafeInteger(s)||s<1)throw new TypeError("schedule record bounds must be positive integers");let c=te({filePath:e,kind:"oracle-notification-schedules",clock:t,maxBytes:a,initialData:()=>({schemaVersion:Xe,schedules:[],work:[]}),validateData:pr(i,s)});function h(y={},d={}){let u=j(t),{tenantId:m,workflowId:f}=D(y.tenantId,y.workflowId),S=P("idempotencyKey",y.idempotencyKey,{max:160}),A=P("schedule name",y.name??S,{max:160}),g=Pe(y.kind??y.mode),l=J(y.category),E=Le(y.schedule),k=X(y.payload??{});g==="alert"&&Ee({category:l,preferences:d.preferences??y.preferences,watch:d.watch??y.watch,watchId:y.watchId});let v={tenantId:m,workflowId:f,idempotencyKey:S,name:A,kind:g,category:l,schedule:E.source,payload:k,startAt:y.startAt??null},_=ge(v),R=$e(E,u);if(y.startAt!==void 0){if(typeof y.startAt!="string"||!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/.test(y.startAt))throw new TypeError("startAt must be an ISO-8601 UTC time");if(R=Date.parse(y.startAt),!Number.isFinite(R)||R<=u)throw new TypeError("startAt must be in the future")}if(R===null||R<=u)throw new TypeError("schedule must have a future occurrence");let U=c.mutate(F=>{let N=F.schedules.find(q=>Q(q,m,f)&&q.idempotencyKey===S);if(N){if(N.definitionFingerprint!==_){let q=new Error("schedule idempotency key was reused with different content");throw q.code="IDEMPOTENCY_CONFLICT",q}return{...N,duplicate:!0}}if(F.schedules.length>=i)throw new Error("schedule capacity reached");let L=C(u),Z={schemaVersion:G,id:P("generated schedule id",String(n()),{max:128}),...v,definitionFingerprint:_,enabled:y.enabled!==!1,createdAt:L,updatedAt:L,lastMaterializedAt:null,nextRunAt:C(R)};return F.schedules.push(Z),Z});return U.duplicate||K(o,{type:"notification.schedule.created",at:C(u),tenantId:m,workflowId:f,scheduleId:U.id,kind:g,category:l}),U}function p({tenantId:y,workflowId:d}={}){return D(y,d),c.read().schedules.filter(u=>Q(u,y,d))}function w({tenantId:y,workflowId:d,id:u,enabled:m}={}){if(D(y,d),typeof m!="boolean")throw new TypeError("enabled must be boolean");let f=j(t),S=c.mutate(A=>{let g=A.schedules.find(l=>Q(l,y,d)&&l.id===u);if(!g)return null;if(g.enabled=m,g.updatedAt=C(f),m&&g.nextRunAt===null){let l=$e(g.schedule,f);if(l===null)throw new Error("a completed one-time schedule cannot be re-enabled");g.nextRunAt=C(l)}return g});return S&&K(o,{type:"notification.schedule.enabled",at:C(f),tenantId:y,workflowId:d,scheduleId:u,enabled:m}),S}function T({tenantId:y,workflowId:d,id:u}={}){D(y,d);let m=j(t),f=c.mutate(S=>{let A=S.schedules.findIndex(g=>Q(g,y,d)&&g.id===u);return A<0?!1:(S.schedules.splice(A,1),!0)});return f&&K(o,{type:"notification.schedule.removed",at:C(m),tenantId:y,workflowId:d,scheduleId:u}),f}function x({tenantId:y,workflowId:d,limit:u=100,until:m}={}){if(D(y,d),!Number.isSafeInteger(u)||u<1||u>1e3)throw new TypeError("limit must be between 1 and 1000");let f=m===void 0?j(t):typeof m=="string"?Date.parse(m):Number(m);if(!Number.isFinite(f))throw new TypeError("until must be a valid time");let S=c.mutate(A=>{let g=[],l=new Set(A.work.map(k=>k.idempotencyKey)),E=A.schedules.filter(k=>Q(k,y,d)&&k.enabled&&k.nextRunAt!==null&&Date.parse(k.nextRunAt)<=f).sort((k,v)=>k.nextRunAt.localeCompare(v.nextRunAt)||k.id.localeCompare(v.id));for(let k of E){for(;k.enabled&&k.nextRunAt!==null&&Date.parse(k.nextRunAt)<=f&&g.length<u;){let v=k.nextRunAt,_=`${y}:${d}:${k.id}:${v}`;if(!l.has(_)){if(A.work.length>=s)throw new Error("scheduled work capacity reached");let U={schemaVersion:G,id:P("generated work id",String(n()),{max:128}),tenantId:y,workflowId:d,scheduleId:k.id,idempotencyKey:_,kind:k.kind,category:k.category,payload:k.payload,evidence:se(k.payload?.evidence),scheduledFor:v,createdAt:C(f),status:"pending",attempts:0,lease:null,completedAt:null,custody:"none",executionAllowed:!1};A.work.push(U),g.push(U),l.add(_)}k.lastMaterializedAt=v;let R=$e(k.schedule,Date.parse(v));k.nextRunAt=R===null?null:C(R),R===null&&(k.enabled=!1),k.updatedAt=C(f)}if(g.length>=u)break}return g});for(let A of S)K(o,{type:"notification.schedule.work.created",at:C(f),tenantId:y,workflowId:d,scheduleId:A.scheduleId,workId:A.id,kind:A.kind,evidence:A.evidence});return S}function b({tenantId:y,workflowId:d,status:u}={}){if(D(y,d),u!==void 0&&!Ct.has(u))throw new TypeError("invalid work status");return c.read().work.filter(m=>Q(m,y,d)&&(u===void 0||m.status===u))}function I({tenantId:y,workflowId:d}={}){D(y,d);let u=j(t);return c.mutate(m=>{let f=0;for(let S of m.work)Q(S,y,d)&&S.status==="leased"&&Date.parse(S.lease.until)<=u&&(S.status="pending",S.lease=null,f+=1);return f})}function O({tenantId:y,workflowId:d,workerId:u,limit:m=1,leaseMs:f=3e4}={}){if(D(y,d),P("workerId",u,{max:128}),!Number.isSafeInteger(m)||m<1||m>100)throw new TypeError("claim limit must be between 1 and 100");if(!Number.isSafeInteger(f)||f<1e3||f>36e5)throw new TypeError("leaseMs must be between 1000 and 3600000");let S=j(t),A=c.mutate(g=>{let l=g.work.filter(E=>Q(E,y,d)&&(E.status==="pending"||E.status==="leased"&&Date.parse(E.lease.until)<=S)).sort((E,k)=>E.scheduledFor.localeCompare(k.scheduledFor)||E.id.localeCompare(k.id)).slice(0,m);for(let E of l)E.status="leased",E.attempts+=1,E.lease={owner:u,token:P("generated lease token",String(r()),{max:160}),until:C(S+f)};return l});for(let g of A)K(o,{type:"notification.schedule.work.claimed",at:C(S),tenantId:y,workflowId:d,workId:g.id,attempt:g.attempts});return A}function $({tenantId:y,workflowId:d,id:u,leaseToken:m}={}){D(y,d);let f=j(t),S=c.mutate(A=>{let g=A.work.find(l=>Q(l,y,d)&&l.id===u);return g?(Ot(g,m,f),g.status="completed",g.lease=null,g.completedAt=C(f),g):null});return S&&K(o,{type:"notification.schedule.work.completed",at:C(f),tenantId:y,workflowId:d,workId:u}),S}function B({tenantId:y,workflowId:d,id:u,leaseToken:m}={}){D(y,d);let f=j(t);return c.mutate(S=>{let A=S.work.find(g=>Q(g,y,d)&&g.id===u);return A?(Ot(A,m,f),A.status="pending",A.lease=null,A):null})}return Object.freeze({filePath:e,createSchedule:h,listSchedules:p,setEnabled:w,removeSchedule:T,materializeDue:x,listWork:b,recoverExpiredWork:I,claimWork:O,completeWork:$,releaseWork:B,inspect:c.inspect})}import Pt from"node:path";import{homedir as mr}from"node:os";import{randomUUID as Rt}from"node:crypto";var Qe=1,Lt=Object.freeze(["pending","leased","delivered","dead_letter"]),Ft=new Set(Lt);function hr(e=process.env){let t=e.ORACLE_CONFIG_DIR||Pt.join(mr(),".config","oracle");return Pt.join(t,"notification-outbox.v1.json")}function yr(e){if(!e||e.schemaVersion!==G)throw new TypeError("invalid outbox record version");if(D(e.tenantId,e.workflowId),P("message id",e.id,{max:128}),P("idempotencyKey",e.idempotencyKey,{max:200}),P("channel",e.channel,{max:32}),e.channel!=="webhook")throw new TypeError("P1 outbox supports webhook only");if(J(e.category),!Ft.has(e.status))throw new TypeError("invalid outbox state");if(!Number.isSafeInteger(e.attempts)||e.attempts<0)throw new TypeError("outbox attempts must be monotonic non-negative integers");if(!Number.isSafeInteger(e.maxAttempts)||e.maxAttempts<1||e.maxAttempts>100)throw new TypeError("invalid outbox maxAttempts");if(!Number.isFinite(Date.parse(e.createdAt))||!Number.isFinite(Date.parse(e.updatedAt))||!Number.isFinite(Date.parse(e.nextAttemptAt)))throw new TypeError("invalid outbox timestamp");if(e.destinationId!==null&&P("destinationId",e.destinationId,{max:160}),!/^[a-f0-9]{64}$/.test(e.contentFingerprint))throw new TypeError("invalid outbox fingerprint");if(e.lease!==null&&(P("lease owner",e.lease.owner,{max:128}),P("lease token",e.lease.token,{max:160}),!Number.isFinite(Date.parse(e.lease.until))))throw new TypeError("invalid outbox lease");if(e.lastError!==null&&P("lastError",e.lastError,{max:512}),e.replayOf!==null&&P("replayOf",e.replayOf,{max:128}),!Array.isArray(e.failures)||e.failures.length>100)throw new TypeError("invalid outbox failure records");for(let t of e.failures){if(!t||!Number.isSafeInteger(t.attempt)||t.attempt<1)throw new TypeError("invalid outbox failure attempt");if(!Number.isFinite(Date.parse(t.at)))throw new TypeError("invalid outbox failure time");if(P("failure code",t.code,{max:512}),typeof t.retryable!="boolean")throw new TypeError("failure retryable must be boolean");if(t.terminal!==!0&&t.terminal!==!1)throw new TypeError("failure terminal must be boolean")}if(e.executionAllowed!==!1||e.custody!=="none")throw new TypeError("outbox crossed the custody boundary");X(e.payload)}function br(e){return t=>{if(!t||t.schemaVersion!==Qe||!Array.isArray(t.messages))throw new TypeError("invalid outbox store schema");if(t.messages.length>e)throw new TypeError("outbox record bound exceeded");let n=new Set,r=new Set;for(let o of t.messages){yr(o);let i=`${o.tenantId}\0${o.workflowId}\0${o.idempotencyKey}`;if(n.has(o.id)||r.has(i))throw new TypeError("duplicate outbox identity");n.add(o.id),r.add(i)}}}function ee(e,t,n){return e.tenantId===t&&e.workflowId===n}function wr(e){let t=e&&typeof e=="object"?e.code:null;if(typeof t=="string"&&/^[A-Z][A-Z0-9_.:-]{0,63}$/.test(t))return`delivery failed: ${t}`;let n=e&&typeof e=="object"?Number(e.status??e.statusCode):NaN;return Number.isInteger(n)&&n>=100&&n<=599?`delivery failed: HTTP_${n}`:"delivery failed"}function $t(e,t,n){if(e.status!=="leased"||!e.lease||e.lease.token!==t)throw new Error("outbox lease token does not match");if(Date.parse(e.lease.until)<=n)throw new Error("outbox lease expired")}function gr({filePath:e=hr(),clock:t=()=>Date.now(),idFactory:n=()=>Rt(),leaseTokenFactory:r=()=>Rt(),eventSink:o,maxRecords:i=1e4,maxBytes:s=16*1024*1024,maxAttempts:a=5,baseBackoffMs:c=1e3,maxBackoffMs:h=36e5}={}){for(let[u,m,f,S]of[["maxRecords",i,1,1e5],["maxAttempts",a,1,100],["baseBackoffMs",c,1,864e5],["maxBackoffMs",h,1,7*864e5]])if(!Number.isSafeInteger(m)||m<f||m>S)throw new TypeError(`${u} is out of range`);if(c>h)throw new TypeError("baseBackoffMs cannot exceed maxBackoffMs");let p=te({filePath:e,kind:"oracle-notification-outbox",clock:t,maxBytes:s,initialData:()=>({schemaVersion:Qe,messages:[]}),validateData:br(i)}),w=u=>Math.min(h,c*2**Math.min(30,Math.max(0,u-1)));function T(u,m){return Ee({category:u.category,preferences:m?.preferences??u.preferences,watch:m?.watch??u.watch,watchId:u.watchId})}function x(u){let{tenantId:m,workflowId:f}=D(u.tenantId,u.workflowId),S=J(u.category),A=P("idempotencyKey",u.idempotencyKey,{max:200}),g=u.channel??"webhook";if(g!=="webhook")throw new TypeError("P1 outbox supports webhook only; fiat/P2 channels are not available");let l=u.destinationId==null?null:P("destinationId",u.destinationId,{max:160}),E=X(u.payload??{}),k=se(u.evidence??u.payload?.evidence),v={tenantId:m,workflowId:f,idempotencyKey:A,category:S,channel:g,destinationId:l,payload:E,evidence:k};return{...v,contentFingerprint:ge(v)}}function b(u={},m={}){T(u,m);let f=x(u),S=j(t),A=p.mutate(g=>{let l=g.messages.find(v=>ee(v,f.tenantId,f.workflowId)&&v.idempotencyKey===f.idempotencyKey);if(l){if(l.contentFingerprint!==f.contentFingerprint){let v=new Error("outbox idempotency key was reused with different content");throw v.code="IDEMPOTENCY_CONFLICT",v}return{...l,duplicate:!0}}if(g.messages.length>=i)throw new Error("outbox capacity reached");let E=C(S),k={schemaVersion:G,id:P("generated message id",String(n()),{max:128}),...f,status:"pending",attempts:0,maxAttempts:u.maxAttempts===void 0?a:Number(u.maxAttempts),nextAttemptAt:E,lease:null,lastError:null,failures:[],createdAt:E,updatedAt:E,deliveredAt:null,deadLetteredAt:null,replayOf:null,custody:"none",executionAllowed:!1};if(!Number.isSafeInteger(k.maxAttempts)||k.maxAttempts<1||k.maxAttempts>a)throw new TypeError(`message maxAttempts must be between 1 and ${a}`);return g.messages.push(k),k});return A.duplicate||K(o,{type:"notification.outbox.enqueued",at:C(S),tenantId:f.tenantId,workflowId:f.workflowId,messageId:A.id,category:f.category,evidence:f.evidence}),A}function I({tenantId:u,workflowId:m,status:f}={}){if(D(u,m),f!==void 0&&!Ft.has(f))throw new TypeError("invalid outbox status");return p.read().messages.filter(S=>ee(S,u,m)&&(f===void 0||S.status===f))}function O({tenantId:u,workflowId:m}={}){D(u,m);let f=j(t),S=p.mutate(A=>{let g=[];for(let l of A.messages)!ee(l,u,m)||l.status!=="leased"||Date.parse(l.lease.until)>f||(l.lease=null,l.updatedAt=C(f),l.attempts>=l.maxAttempts?(l.status="dead_letter",l.lastError="delivery lease expired after final attempt",l.deadLetteredAt=C(f)):(l.status="pending",l.lastError="delivery lease expired before acknowledgement",l.nextAttemptAt=C(f+w(l.attempts))),g.push(l));return g});for(let A of S)K(o,{type:"notification.outbox.lease_recovered",at:C(f),tenantId:u,workflowId:m,messageId:A.id,status:A.status,attempt:A.attempts});return S}function $({tenantId:u,workflowId:m,workerId:f,limit:S=1,leaseMs:A=3e4}={}){if(D(u,m),P("workerId",f,{max:128}),!Number.isSafeInteger(S)||S<1||S>100)throw new TypeError("claim limit must be between 1 and 100");if(!Number.isSafeInteger(A)||A<1e3||A>36e5)throw new TypeError("leaseMs must be between 1000 and 3600000");let g=j(t),l=p.mutate(E=>{for(let v of E.messages)!ee(v,u,m)||v.status!=="leased"||Date.parse(v.lease.until)>g||(v.lease=null,v.updatedAt=C(g),v.attempts>=v.maxAttempts?(v.status="dead_letter",v.lastError="delivery lease expired after final attempt",v.deadLetteredAt=C(g)):(v.status="pending",v.lastError="delivery lease expired before acknowledgement",v.nextAttemptAt=C(g)));let k=E.messages.filter(v=>ee(v,u,m)&&v.status==="pending"&&Date.parse(v.nextAttemptAt)<=g&&v.attempts<v.maxAttempts).sort((v,_)=>v.nextAttemptAt.localeCompare(_.nextAttemptAt)||v.createdAt.localeCompare(_.createdAt)||v.id.localeCompare(_.id)).slice(0,S);for(let v of k)v.status="leased",v.attempts+=1,v.updatedAt=C(g),v.lease={owner:f,token:P("generated lease token",String(r()),{max:160}),until:C(g+A)};return k});for(let E of l)K(o,{type:"notification.outbox.claimed",at:C(g),tenantId:u,workflowId:m,messageId:E.id,attempt:E.attempts});return l}function B({tenantId:u,workflowId:m,id:f,leaseToken:S}={}){D(u,m);let A=j(t),g=p.mutate(l=>{let E=l.messages.find(k=>ee(k,u,m)&&k.id===f);return E?($t(E,S,A),E.status="delivered",E.lease=null,E.updatedAt=C(A),E.deliveredAt=C(A),E):null});return g&&K(o,{type:"notification.outbox.delivered",at:C(A),tenantId:u,workflowId:m,messageId:f,attempt:g.attempts}),g}function y({tenantId:u,workflowId:m,id:f,leaseToken:S,error:A,retryable:g=!0}={}){if(D(u,m),typeof g!="boolean")throw new TypeError("retryable must be boolean");let l=j(t),E=wr(A),k=p.mutate(v=>{let _=v.messages.find(U=>ee(U,u,m)&&U.id===f);if(!_)return null;$t(_,S,l),_.lease=null,_.lastError=E;let R=!g||_.attempts>=_.maxAttempts;return _.failures=[..._.failures??[],{attempt:_.attempts,at:C(l),code:E,retryable:g,terminal:R}],_.updatedAt=C(l),R?(_.status="dead_letter",_.deadLetteredAt=C(l)):(_.status="pending",_.nextAttemptAt=C(l+w(_.attempts))),_});return k&&K(o,{type:k.status==="dead_letter"?"notification.outbox.dead_lettered":"notification.outbox.retry_scheduled",at:C(l),tenantId:u,workflowId:m,messageId:f,attempt:k.attempts,nextAttemptAt:k.nextAttemptAt}),k}function d({tenantId:u,workflowId:m,id:f,idempotencyKey:S}={},A={}){D(u,m);let g=P("replay idempotencyKey",S,{max:200}),E=p.read().messages.find(_=>ee(_,u,m)&&_.id===f);if(!E)return null;if(E.status!=="dead_letter"&&E.status!=="delivered")throw new Error("only delivered or dead-letter messages may be replayed");T({...E,preferences:A.preferences,watch:A.watch},A);let k=j(t),v=p.mutate(_=>{let R=_.messages.find(q=>ee(q,u,m)&&q.id===f);if(!R||R.status!=="dead_letter"&&R.status!=="delivered")throw new Error("replay source changed state");let U=_.messages.find(q=>ee(q,u,m)&&q.idempotencyKey===g),F={tenantId:u,workflowId:m,idempotencyKey:g,category:R.category,channel:R.channel,destinationId:R.destinationId,payload:R.payload,evidence:R.evidence},N=ge(F);if(U){if(U.contentFingerprint!==N||U.replayOf!==f){let q=new Error("replay idempotency key was reused with different content");throw q.code="IDEMPOTENCY_CONFLICT",q}return{...U,duplicate:!0}}if(_.messages.length>=i)throw new Error("outbox capacity reached");let L=C(k),Z={schemaVersion:G,id:P("generated message id",String(n()),{max:128}),...F,contentFingerprint:N,status:"pending",attempts:0,maxAttempts:R.maxAttempts,nextAttemptAt:L,lease:null,lastError:null,failures:[],createdAt:L,updatedAt:L,deliveredAt:null,deadLetteredAt:null,replayOf:f,custody:"none",executionAllowed:!1};return _.messages.push(Z),Z});return v.duplicate||K(o,{type:"notification.outbox.replayed",at:C(k),tenantId:u,workflowId:m,messageId:v.id,replayOf:f}),v}return Object.freeze({filePath:e,enqueue:b,list:I,claim:$,acknowledge:B,fail:y,recoverExpiredLeases:O,replay:d,backoffForAttempt:w,inspect:p.inspect})}import Ke from"node:path";import{homedir as bn}from"node:os";import{readFileSync as Go}from"node:fs";import{createHash as Yo}from"node:crypto";z();z();import{getAddress as no}from"ethers";import{types as Wt}from"node:util";function ct(e){if(!e||typeof e!="object"||Wt.isProxy(e)||Array.isArray(e))return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function ie(e,t="provider response",n=0){if(n>64)throw new Error(`${t} exceeds the JSON nesting bound`);if(e===null||typeof e=="string"||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e))return e;if(Array.isArray(e)){if(Wt.isProxy(e)||e.length>1e5)throw new Error(`${t} contains an invalid array`);let o=new Array(e.length);for(let i=0;i<e.length;i+=1){let s=Object.getOwnPropertyDescriptor(e,String(i));if(!s||!Object.hasOwn(s,"value"))throw new Error(`${t} arrays must contain dense own data`);o[i]=ie(s.value,t,n+1)}return o}if(!ct(e))throw new Error(`${t} contains a non-JSON value`);let r=Object.create(null);for(let o of Object.keys(e)){let i=Object.getOwnPropertyDescriptor(e,o);if(!i||!Object.hasOwn(i,"value"))throw new Error(`${t} objects must contain own data`);r[o]=ie(i.value,t,n+1)}return r}var Qr=/[\u200B-\u200F\u202A-\u202E\u2060-\u2064\uFEFF]/g,eo=/[<>&`*_~[\]()|\\]/g,to=/[\u0000-\u001F\u007F]/g;function qe(e,{max:t=32,fallback:n=""}={}){return e==null?n:String(e).normalize("NFKC").replace(Qr,"").replace(to,"").replace(eo,"").replace(/\s+/g," ").trim().slice(0,t).trim()||n}var Gt=Object.freeze({1:"https://eth.blockscout.com",8453:"https://base.blockscout.com",42161:"https://arbitrum.blockscout.com"}),Yt=e=>!!Gt[e];function ro(e){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("invalid NFT cursor");let t=new URLSearchParams;for(let[n,r]of Object.entries(e)){if(!(n==="token_contract_address_hash"?/^0x[\da-f]{40}$/i.test(String(r)):n==="token_type"?["ERC-721","ERC-1155","ERC-404"].includes(r):["token_id","items_count"].includes(n)&&/^\d{1,100}$/.test(String(r))))throw new Error("invalid NFT cursor");t.set(n,String(r))}if(!t.size)throw new Error("empty NFT cursor");return t.toString()}async function Jt(e={},t={}){let n=no(e.address),r=Gt[e.chainId];if(!r)throw new Error("Blockscout NFT chain not verified");let o=Math.min(3,Math.max(1,Math.trunc(Number(e.maxPages)||3))),i=[],s=[],a=new Set,c=null,h="",p=0,w=!1;for(;p<o;)try{let T=ie(await V(`${r}/api/v2/addresses/${n}/nft${h?`?${h}`:""}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??8e3,maxResponseBytes:2e6,redirectPolicy:"error",headers:{accept:"application/json","user-agent":"OraclePortfolio/1.0"}}),"blockscout NFT inventory");if(!Array.isArray(T?.items))throw new Error("invalid NFT inventory response");p++;for(let b of T.items.slice(0,50)){let I=b.token;if(!/^0x[\da-f]{40}$/i.test(I?.address_hash||"")||!/^\d+$/.test(String(b.id??"")))throw new Error("invalid NFT identity");if(!["ERC-721","ERC-1155","ERC-404"].includes(I.type))throw new Error("invalid NFT standard");if(b.owner?.hash&&b.owner.hash.toLowerCase()!==n.toLowerCase())throw new Error("NFT owner mismatch");i.push({chain:e.chain,chainId:e.chainId,family:"evm",owner:n,contract:I.address_hash,tokenId:String(b.id),tokenStandard:I.type,collection:qe(I.name,{max:160,fallback:I.address_hash}),name:qe(b.metadata?.name||I.name,{max:160,fallback:`NFT ${b.id}`}),imageUrl:b.image_url||null,estimatedValueUsd:null,spam:["scam","spam"].includes(I.reputation)||I.is_spam===!0,source:"blockscout-owner-inventory",listingAdapter:null,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"owner indexer provides no acquisition cost"}})}if(T.items.length>50)throw new Error("NFT provider page exceeds 50 item bound");let x=T.next_page_params??null;if(!x){c=null,w=!0;break}if(c=null,h=ro(x),c=Object.fromEntries(new URLSearchParams(h)),a.has(h))throw new Error("repeated NFT cursor");a.add(h)}catch(T){if(s.push(`blockscout: ${T.message}`.slice(0,300)),!p)throw T;break}return{nfts:i,complete:w,next:c,pages:p,truncated:!w,errors:s}}import{getAddress as ho}from"ethers";ke();z();var Ns=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"});z();var Cs=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),lt=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),ut=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"});ke();ke();var ao=Object.freeze([{key:"ethereum",chainId:1,name:"Ethereum",rpcEnv:["ETH_RPC_URL","ETHEREUM_RPC_URL","MAINNET_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://etherscan.io",dexscreenerSlug:"ethereum",venueKind:"uniswap-v3",wrappedNative:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",stableQuoteAssets:["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48","0xdAC17F958D2ee523a2206206994597C13D831ec7"],venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDC fee 500 quoted 1908.71 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:1}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:1}}]},{key:"optimism",chainId:10,name:"OP Mainnet",rpcEnv:["OPTIMISM_RPC_URL","OP_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://optimistic.etherscan.io",dexscreenerSlug:"optimism",venueKind:"uniswap-v3",wrappedNative:"0x4200000000000000000000000000000000000006",stableQuoteAssets:["0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85","0x94b008aA00579c1307B0EF2c499aD98a8ce58e58"],venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDC fee 500 quoted 1905.23 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:10}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:10}}]},{key:"bsc",chainId:56,name:"BNB Smart Chain",rpcEnv:["BSC_RPC_URL","BNB_RPC_URL"],nativeCurrency:{symbol:"BNB",decimals:18},explorer:"https://bscscan.com",dexscreenerSlug:"bsc",venueKind:"uniswap-v3",wrappedNative:"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",stableQuoteAssets:["0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d","0x55d398326f99059fF775485246999027B3197955"],venues:[{kind:"quoter",address:"0x78D78E420Da98ad378D7799bE8f4AF69033EB077",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WBNB->USDC fee 500 quoted 413.86 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:56}},{kind:"router",address:"0xB971eF87ede563556b2ED4b1C0b0019111Dd85d2",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:56}}]},{key:"polygon",chainId:137,name:"Polygon",rpcEnv:["POLYGON_RPC_URL","POLYGON_RPC"],nativeCurrency:{symbol:"POL",decimals:18},explorer:"https://polygonscan.com",dexscreenerSlug:"polygon",venueKind:"uniswap-v3",wrappedNative:"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",stableQuoteAssets:["0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359","0xc2132D05D31c914a87C6611C10748AEb04B58e8F"],venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WMATIC->USDC fee 500 quoted 0.0720 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:137}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:137}}]},{key:"stable",chainId:988,name:"Stable Mainnet",rpcEnv:["STABLE_RPC_URL","STABLE_RPC"],nativeCurrency:{symbol:"USDT0",decimals:18},venueKind:"uniswap-v3",wrappedNative:"0x5d442b349590a6048Eb2dC0eC346cAA5F47A9ab5",venues:[{kind:"quoter",address:"0xb070179E7032CdA868b53e6C1742F80c9e940d1A",label:"Uniswap V3 QuoterV2 (canonical)",verified:{method:"Stable is on the OFFICIAL Uniswap v3 Deployments List (governance-recognised 2026-05-12, UAC process completed 2026-04, deployed by Protofire), so this is a canonical deployment rather than a fork. eth_getCode returned 8273 bytes, the same size as the canonical quoter on the seven already-verified chains. Functional probe on a live pool (TOAST -> USDT0, fee 10000): 100 in -> 0.000003, 1000 -> 0.000031, 10000 -> 0.000319 USDT0. Output scales monotonically with input, which is a working quoter answering, not a revert. Two of three sampled pools carry non-zero liquidity. NOTE: the pools discovered so far are thin, so real routing size is limited -- the venue is proved, deep liquidity is not.",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-08-05",chainId:988}},{kind:"router",address:"0x32eaf9B5d5F2CD7361c5012890C943D7de84C22a",label:"Uniswap SwapRouter02 (canonical)",verified:{method:"eth_getCode returned 24497 bytes. Cross-checked on-chain rather than trusted from docs: router.factory() returns 0x88f0a512ef09175d456bc9547f914f48c013e4aa, the same v3 core factory that created the pools quoted above, and router.WETH9() returns the wrappedNative recorded on this chain entry. Address published in the Stable docs DEX reference and the Uniswap deployments list.",source:"docs.stable.xyz/en/reference/dexes + on-chain factory()/WETH9() round-trip",date:"2026-08-05",chainId:988}}]},{key:"hyperevm",chainId:999,name:"HyperEVM",rpcEnv:["HYPEREVM_RPC_URL","HYPER_EVM_RPC"],nativeCurrency:{symbol:"HYPE",decimals:18},dexscreenerSlug:"hyperevm",venueKind:"uniswap-v3",wrappedNative:"0x5555555555555555555555555555555555555555",venues:[{kind:"quoter",address:"0x03A918028f22D9E1473B7959C927AD7425A45C7C",label:"HyperSwap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle(1 WHYPE -> USDT0) returned live output on all four fee tiers (100: 57.3385, 500: 57.4187, 3000: 57.3237, 10000: 56.1963 USDT0). Decimals read on-chain: WHYPE 18, USDT0 6. Best tier checked against an INDEPENDENT control the same minute -- Hyperliquid allMids put HYPE at 57.3205, so the pool is 0.171% from the perp mid, which is the right shape for fee plus impact rather than a wrong contract or a decimals bug.",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-08-05",chainId:999}},{kind:"router",address:"0x4E2960a8cd19B467b82d26D83fAcb0fAE26b094D",label:"HyperSwap V3 SwapRouter",verified:{method:"eth_getCode returned 12070 bytes, and it is the router paired with the quoter proved above -- the same pair already shipped in UNI_V3_VENUES[999].hyperswap, which is the map the quote/prepare path actually routes through.",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-08-05",chainId:999}}]},{key:"abstract",chainId:2741,name:"Abstract",rpcEnv:["ABSTRACT_RPC_URL","ABS_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},venueKind:"uniswap-v3",wrappedNative:"0x3439153EB7AF838Ad19d56E1571FBD09333C2809",venues:[{kind:"quoter",address:"0x728BD3eC25D5EDBafebB84F3d67367Cd9EBC7693",label:"Uniswap V3 QuoterV2 (Abstract deployment)",verified:{method:"Abstract is a ZK-stack chain, so CREATE2 addresses differ and the canonical Uniswap addresses are NOT valid here -- probing them returns codesize 0, which is what previously made this chain look like it had no V3 at all. Found the real deployment from live traffic instead: scanned recent Swap(...) logs, took the busiest pool, read pool.factory() = 0xa1160e73b63f322ae88cc2d8e700833e71d0b2a1, then enumerated that factory's deployer (0xf3d63166F0Ca56C3c1A3508FcE03Ff0Cf3Fb691e) and probed each of its 56 contracts with a real quoteExactInputSingle call. Exactly one answered: 1 WETH -> 1846.475731 USDC.e at fee 500. Independent sanity check: the pool's own slot0() spot price is 1873.11 USDC.e per WETH, so the quoter sits ~1.4% below spot, the right shape for fee plus price impact on this size.",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-08-05",chainId:2741}},{kind:"router",address:"0x7712FA47387542819d4E35A23f8116C90C18767C",label:"Uniswap SwapRouter02 (Abstract deployment)",verified:{method:"eth_getCode returned 167392 bytes and the runtime contains the exactInputSingle selector. router.factory() matches the factory proved above and router.WETH9() matches the wrappedNative on this entry. Chosen over its byte-identical twin (0xfD6257F4...) because this is the address real users actually route through: it appeared as tx.to on live swaps against the WETH/USDC.e pool.",source:"on-chain factory()/WETH9() round-trip + live swap tx.to sampling",date:"2026-08-05",chainId:2741}}]},{key:"robinhood",chainId:4663,name:"Robinhood Chain",rpcEnv:["RH_CHAIN_RPC","ROBINHOOD_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},dexscreenerSlug:"robinhood",venueKind:"uniswap-v3",wrappedNative:"0x0bd7d308f8e1639fab988df18a8011f41eacad73",stableQuoteAssets:["0x5fc5360d0400a0fd4f2af552add042d716f1d168"],venues:[{kind:"quoter",address:"0x33e885ed0ec9bf04ecfb19341582aadcb4c8a9e7",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDG fee 100 quoted 1866.58 USDG, and USDG->CASHCAT fee 10000 quoted a live amount). A contract that correctly prices known pairs IS a working V3 quoter",source:"live eth_call against rpc.mainnet.chain.robinhood.com",date:"2026-07-31",chainId:4663}},{kind:"router",address:"0xcaf681a66d020601342297493863e78c959e5cb2",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode (24497 bytes) on this chain and the paired quoter at the same deployment passed a live functional quote",source:"live eth_getCode against rpc.mainnet.chain.robinhood.com",date:"2026-07-31",chainId:4663}},{kind:"factory",address:"0x1f7d7550b1b028f7571e69a784071f0205fd2efa",label:"Uniswap V3 Factory",verified:{method:"eth_getCode returned real bytecode (24535 bytes) and a PoolCreated log scan over this factory returned 76 pools in ~9000 recent blocks",source:"live eth_getLogs against rpc.mainnet.chain.robinhood.com",date:"2026-07-31",chainId:4663}}]},{key:"base",chainId:8453,name:"Base",rpcEnv:["BASE_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://basescan.org",dexscreenerSlug:"base",venueKind:"uniswap-v3",wrappedNative:"0x4200000000000000000000000000000000000006",stableQuoteAssets:["0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"],venues:[{kind:"quoter",address:"0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a",label:"Uniswap V3 QuoterV2 (Base)",verified:{method:"functional probe: quoteExactInputSingle returned WETH->USDC at fee 500 = 1908.44 USDC, a live sane price. The canonical mainnet quoter address also has bytecode on Base but does NOT price this pair, which is exactly the false positive a codesize-only check accepts",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:8453}},{kind:"router",address:"0x2626664c2603336E57B271c5C0b26F421741e481",label:"Uniswap V3 SwapRouter02 (Base)",verified:{method:"eth_getCode returned real bytecode and the paired Base quoter passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:8453}},{kind:"router-v2",address:"0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24",label:"Uniswap V2 Router02 (Base)",verified:{method:"eth_getCode returned 17891 bytes; live getAmountsOut on WETH->USDC round-tripped to 98.75% (2x0.30% fee + impact)",source:"https://docs.uniswap.org/contracts/v2/reference/smart-contracts/v2-deployments",date:"2026-07-30",chainId:8453}}]},{key:"arbitrum",chainId:42161,name:"Arbitrum One",rpcEnv:["ARBITRUM_RPC_URL","ARB_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://arbiscan.io",dexscreenerSlug:"arbitrum",venueKind:"uniswap-v3",wrappedNative:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",stableQuoteAssets:["0xaf88d065e77c8cC2239327C5EDb3A432268e5831","0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9"],venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDC fee 500 quoted 1908.72 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:42161}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:42161}}]},{key:"avalanche",chainId:43114,name:"Avalanche C-Chain",rpcEnv:["AVALANCHE_RPC_URL","AVAX_RPC_URL"],nativeCurrency:{symbol:"AVAX",decimals:18},explorer:"https://snowtrace.io",dexscreenerSlug:"avalanche",venueKind:"uniswap-v3",wrappedNative:"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",stableQuoteAssets:["0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"],venues:[{kind:"quoter",address:"0xbe0F5544EC67e9B3b2D979aaA43f18Fd87E6257F",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WAVAX->USDC fee 500 quoted 6.48 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:43114}},{kind:"router",address:"0xbb00FF08d01D300023C629E8fFfFcb65A5a578cE",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:43114}}]}]);z();ke();z();function dt(e,t="address"){let n=String(e||"").trim();if(!/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(n))throw new Error(`solana-rpc: ${t} must be a base58 public key`);return n}z();function fe(e,t="address"){let n=String(e||"").trim();if(!/^(bc1|tb1|bcrt1)[a-z0-9]{20,90}$/i.test(n)&&!/^[13mn2][a-km-zA-HJ-NP-Z1-9]{25,34}$/.test(n))throw new Error(`bitcoin-esplora: ${t} must look like a Bitcoin address`);return n}var en="ORACLE_ALLOW_CUSTOM_PROVIDER_URL";function me({provider:e,defaultUrl:t,hosts:n=[],url:r,strict:o=!1}){let s=(String(r??"").trim()||String(t)).replace(/\/$/,"");if(s===String(t).replace(/\/$/,""))return{baseUrl:s,trusted:!0,host:tn(t)};let a;try{a=new URL(s)}catch{throw new Error(`${e}: baseUrl must be an absolute http(s) URL`)}if(a.protocol!=="http:"&&a.protocol!=="https:")throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);let c=a.host;if(!c)throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);if(new Set([tn(t),...n]).has(c)){let p=/^(127\.0\.0\.1|localhost|\[::1\])(:\d+)?$/i.test(c);return a.protocol==="http:"&&!p?{baseUrl:s,trusted:!1,host:c,reason:"plaintext http downgrade"}:{baseUrl:s,trusted:!0,host:c}}if(String(process.env[en]||"")==="1")return{baseUrl:s,trusted:!1,host:c};if(o)throw new Error(`${e}: refusing to call non-allowlisted host ${c} (set ${en}=1 to permit it)`);return{baseUrl:s,trusted:!1,host:c}}function tn(e){let t=new URL(String(e));if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error("unsupported protocol");return t.host}function le(e,t,n){let r={...e};if(!n)return r;for(let[o,i]of Object.entries(t||{}))i&&(r[o]=i);return r}function nn(e={}){return String(e.baseUrl||process.env.BTC_META_API_URL||process.env.UNISAT_API_URL||"").trim().replace(/\/$/,"")}var lo=["open-api.unisat.io","open-api-testnet.unisat.io","api.bestinslot.xyz","api.hiro.so"];function uo(e={}){let t=e.apiKey||process.env.UNISAT_API_KEY||process.env.BESTINSLOT_API_KEY||process.env.BTC_META_API_KEY||"",n=!1;try{let r=nn(e);if(r){let o=new URL(r).host,i=new URL(r).protocol,s=/^(127\.0\.0\.1|localhost|\[::1\])(:\d+)?$/i.test(o);n=lo.includes(o)&&(i==="https:"||s)}}catch{n=!1}return le({accept:"application/json","user-agent":"oracle-btc-meta/0.1"},{authorization:t?`Bearer ${t}`:"","x-api-key":t},n)}async function po(e,t={}){let r=await(t.fetchImpl||fetch)(e,{method:"GET",headers:uo(t),signal:AbortSignal.timeout(t.timeoutMs??12e3)}),o=await r.text(),i;try{i=JSON.parse(o)}catch{i=o}if(!r.ok)throw new Error(`bitcoin-meta GET ${e}: HTTP ${r.status} ${String(o).slice(0,160)}`);return i}async function pt(e={},t={}){let n=fe(e.address||e.addr,"address"),r=nn(t);if(!r)return{provider:"bitcoin-meta",address:n,ok:!1,inscriptions:[],error:"no indexer configured \u2014 address-indexed lookups need a keyed indexer (BTC_META_API_URL + UNISAT_API_KEY / BESTINSLOT_API_KEY). ordinals.com recursive is keyless but has no address index.",unknownNotEmpty:!0,keylessAlternatives:["btc_inscription_info (by inscription id)","btc_meta_health"]};let o=Math.min(Number(e.limit||50),200),i=[`${r}/v1/indexer/address/${n}/inscription-data?cursor=0&size=${o}`,`${r}/v1/inscriptions/address/${n}?limit=${o}`,`${r}/address/${n}/inscriptions?limit=${o}`],s=null;for(let a of i)try{let c=await po(a,t),h=fo(c);return{provider:"bitcoin-meta",address:n,ok:!0,count:h.length,inscriptions:h,source:a}}catch(c){s=c}return{provider:"bitcoin-meta",address:n,ok:!1,inscriptions:[],error:String(s?.message||s||"all indexer paths failed")}}function fo(e){let t=e?.data?.inscription||e?.data?.detail||e?.data?.list||e?.data||e?.inscriptions||e?.results||(Array.isArray(e)?e:[]);return(Array.isArray(t)?t:[]).map(r=>({id:r.inscriptionId||r.id||r.inscription_id||null,number:r.inscriptionNumber??r.number??null,sat:r.sat||r.satoshi||null,contentType:r.contentType||r.content_type||null,utxo:r.utxo||r.output||(r.txid!=null?`${r.txid}:${r.vout??r.n}`:null),raw:r}))}z();z();z();var Ta=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood",2741:"abstract",solana:"solana"});z();var Pa=Object.freeze({1:"https://eth.blockscout.com",10:"https://explorer.optimism.io",137:"https://polygon.blockscout.com",324:"https://zksync.blockscout.com",8453:"https://base.blockscout.com",42161:"https://arbitrum.blockscout.com",534352:"https://scrollscan.com"}),mo=Object.freeze(["block_number","index"]),Ra=new Set([...mo,"items_count","value","hash","inserted_at","fee"]);var cc=Object.freeze({ETH:"coingecko:ethereum",POL:"coingecko:polygon-ecosystem-token",BNB:"coingecko:binancecoin",AVAX:"coingecko:avalanche-2",HYPE:"coingecko:hyperliquid",USDT0:"coingecko:tether",SOL:"coingecko:solana",BTC:"coingecko:bitcoin"});function je(e,...t){for(let n of t){let r=String(e?.[n]||"").trim();if(r)return r}return null}function rn(e){if(!e)return null;try{return ho(String(e).trim().toLowerCase())}catch{throw new Error("portfolio: EVM address must be a valid 20-byte address")}}function on(e={},t=process.env){let n=e.addresses||{},r=rn(n.evm||e.evmAddress||je(t,"ORACLE_EVM_ADDRESS","ORACLE_DEFAULT_ADDRESS","MAD_OPERATOR_ADDRESS")),o=n.solana||e.solanaAddress||je(t,"ORACLE_SOLANA_ADDRESS"),i=n.bitcoin||e.bitcoinAddress||je(t,"ORACLE_BITCOIN_ADDRESS"),s=rn(n.hyperliquid||e.hyperliquidAddress||je(t,"ORACLE_HYPERLIQUID_ADDRESS")||r);return{evm:r,solana:o?dt(o,"portfolio Solana address"):null,bitcoin:i?fe(i,"portfolio Bitcoin address"):null,hyperliquid:s}}z();import{readFileSync as bo,existsSync as wo}from"node:fs";import{getAddress as go,Interface as He,TypedDataEncoder as yc,parseUnits as bc}from"ethers";var yo=300*1e3,uc=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})();var Eo="https://api.opensea.io/api/v2",So="fulfillAdvancedOrder(((address offerer,address zone,(uint8 itemType,address token,uint256 identifierOrCriteria,uint256 startAmount,uint256 endAmount)[] offer,(uint8 itemType,address token,uint256 identifierOrCriteria,uint256 startAmount,uint256 endAmount,address recipient)[] consideration,uint8 orderType,uint256 startTime,uint256 endTime,bytes32 zoneHash,uint256 salt,bytes32 conduitKey,uint256 totalOriginalConsiderationItems) parameters,uint120 numerator,uint120 denominator,bytes signature,bytes extraData) advancedOrder,(uint256 orderIndex,uint8 side,uint256 index,uint256 identifier,bytes32[] criteriaProof)[] criteriaResolvers,bytes32 fulfillerConduitKey,address recipient)",Ac=new He([`function ${So}`]),vc=new He(["function mintPublic(address nftContract,address feeRecipient,address minterIfNotPayer,uint256 quantity) payable","function mintAllowList(address nftContract,address feeRecipient,address minterIfNotPayer,uint256 quantity,(uint80 mintPrice,uint48 maxTotalMintableByWallet,uint48 startTime,uint48 endTime,uint48 dropStageIndex,uint32 maxTokenSupplyForStage,uint16 feeBps,bool restrictFeeRecipients) mintParams,bytes32[] proof) payable"]),Ao=Object.freeze(["blast","base","ethereum","zora","arbitrum","sei","avalanche","polygon","optimism","ape_chain","flow","b3","soneium","ronin","bera_chain","solana","shape","unichain","gunzilla","abstract","animechain","hyperevm","somnia","monad","hyperliquid","megaeth","ink","robinhood","stablechain"]),vo=new Set(Ao),xo=new Set(["solana","flow"]);function ko(){let e=process.env.OPENSEA_ENV_FILE||`${process.env.HOME||""}/.config/locals-only/opensea.env`;if(!wo(e))return"";try{for(let t of bo(e,"utf8").split(`
5
+ `)){let n=t.match(/^\s*OPENSEA_API_KEY\s*=\s*(.+)\s*$/);if(n)return n[1].replace(/^["']|["']$/g,"").trim()}}catch{}return""}function Te(e={}){return e.apiKey?e.apiKey:e.allowAmbientCredentials===!1||e.allowDiskCredentials===!1?e.env?.OPENSEA_API_KEY||e.env?.OPEN_SEA_API_KEY||"":e.env?.OPENSEA_API_KEY||process.env.OPENSEA_API_KEY||process.env.OPEN_SEA_API_KEY||ko()}function an(e={}){return me({provider:"opensea",defaultUrl:Eo,hosts:["api.opensea.io","testnets-api.opensea.io"],url:e.baseUrl||process.env.OPENSEA_API_URL})}function Ve(e={}){return an(e).baseUrl}function ze(e={}){return le({accept:"application/json"},{"x-api-key":Te(e)},an(e).trusted)}function To(e){let t=String(e||"ethereum").trim().toLowerCase();if(!vo.has(t))throw new Error(`opensea: unsupported account chain ${t}`);return t}function sn(e,t="address"){try{return go(String(e||"").trim().toLowerCase())}catch{throw new Error(`opensea: invalid ${t}`)}}function cn(e,t=null){let n=String(e||"").trim();if(!n)throw new Error("opensea: account address required");if(t&&!xo.has(t)||!t&&/^0x[0-9a-fA-F]{40}$/.test(n))return sn(n,"account address");if(!/^[1-9A-HJ-NP-Za-km-z]{32,64}$/.test(n))throw new Error("opensea: invalid account address");return n}function Io(e={},t,n){return{chain:t,owner:n,contract:e.contract||null,tokenId:e.identifier==null?null:String(e.identifier),tokenStandard:e.token_standard||null,quantity:e.quantity==null&&e.balance==null?null:String(e.quantity??e.balance),collection:e.collection||null,name:e.name||null,description:e.description||null,imageUrl:e.display_image_url||e.image_url||e.original_image_url||null,originalImageUrl:e.original_image_url||e.image_url||null,animationUrl:e.display_animation_url||e.original_animation_url||null,metadataUrl:e.metadata_url||null,marketplaceUrl:e.opensea_url||null,estimatedValueUsd:e.estimated_value_usd!=null&&Number.isFinite(Number(e.estimated_value_usd))?Number(e.estimated_value_usd):null,spam:e.is_disabled===!0,disabled:e.is_disabled===!0,nsfw:e.is_nsfw===!0,traits:Array.isArray(e.traits)?e.traits:[],updatedAt:e.updated_at||null,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"OpenSea account inventory does not expose trustworthy per-item acquisition cost"}}}async function _o(e,t={}){if(!e)throw new Error("collection slug required");if(!Te(t))throw new Error("OPENSEA_API_KEY required");return V(`${Ve(t)}/collections/${encodeURIComponent(e)}`,{headers:ze(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function No(e,t={}){if(!e)throw new Error("collection slug required");if(!Te(t))throw new Error("OPENSEA_API_KEY required");return V(`${Ve(t)}/collections/${encodeURIComponent(e)}/stats`,{headers:ze(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function ln(e,t={}){let n=await _o(e,t),r=n.stats||n.total||{},o=n.floor_price??n.floorPrice??r.floor_price??r.floorPrice??null;if(o==null){let w=await No(e,t);r=w?.total||w?.stats||w||{},o=r.floor_price??r.floorPrice??null}let i=(Array.isArray(n.contracts)?n.contracts:[]).map(w=>({chain:String(w?.chain||w?.chain_identifier||n.chain||"").trim().toLowerCase(),address:String(w?.address||w?.contract_address||w?.contract||"").trim()})).filter(w=>w.chain&&w.address),s=String(t.expectedChain||"").trim().toLowerCase(),a=String(t.expectedContract||"").trim(),c=null;if(s&&a){let w=T=>s==="solana"?T:T.toLowerCase();if(c=i.find(T=>T.chain===s&&w(T.address)===w(a))||null,!c)throw new Error("opensea: collection identity does not match held contract")}let h=c?.chain||String(n.chain||"").trim().toLowerCase()||i[0]?.chain||"",p=String(n.floor_price_symbol||n.floorPriceSymbol||r.floor_price_symbol||r.floorPriceSymbol||"").trim().toUpperCase()||null;return{slug:n.collection||e,name:n.name||null,floor:o,chain:h||null,contracts:i,currency:p,totalSupply:n.total_supply??r.total_supply??null,numOwners:n.num_owners??r.num_owners??null,raw:{contracts:i,fees:n.fees,category:n.category}}}async function mt(e={},t={}){if(!Te(t))throw new Error("OPENSEA_API_KEY required");let n=To(e.chain),r=cn(e.address||e.owner,n),o=Math.min(Math.max(Number(e.pageSize??e.limit??200)||200,1),200),i=Math.min(Math.max(Number(e.maxPages??5)||5,1),25),s=[],a=e.next?String(e.next):null,c=0;do{let h=new URL(`${Ve(t)}/chain/${encodeURIComponent(n)}/account/${encodeURIComponent(r)}/nfts`);h.searchParams.set("limit",String(o)),e.collection&&h.searchParams.set("collection",String(e.collection)),a&&h.searchParams.set("next",a);let p=await V(h.toString(),{headers:ze(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4});for(let w of Array.isArray(p?.nfts)?p.nfts:[])s.push(Io(w,n,r));a=p?.next?String(p.next):null,c+=1}while(a&&c<i);return{provider:"opensea-nft",source:"opensea-account-inventory",chain:n,owner:r,count:s.length,pages:c,complete:!a,next:a,nfts:s,exec:!1,readOnly:!0}}async function un(e={},t={}){if(!Te(t))throw new Error("OPENSEA_API_KEY required");let n=cn(e.address||e.owner),r=await V(`${Ve(t)}/account/${encodeURIComponent(n)}/pnl`,{headers:ze(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4});return{provider:"opensea-nft",source:"opensea-indexed-account-pnl",address:n,scope:"OpenSea-indexed account trading PnL across supported currencies, not per-item NFT cost basis",methodology:"provider-indexed",realizedPnlUsd:r?.realized_pnl_usd??null,unrealizedPnlUsd:r?.unrealized_pnl_usd??null,totalPnlUsd:r?.total_pnl_usd??null,netInvestedUsd:r?.net_invested_usd??null,currentValueUsd:r?.current_value_usd??null,returnPercentage:r?.return_percentage??null,itemLevelPnlAvailable:!1,raw:r,exec:!1,readOnly:!0}}var xc=Object.freeze({robinhood:4663,ethereum:1,base:8453,arbitrum:42161,optimism:10,polygon:137,avalanche:43114,zora:7777777,blast:81457,sei:1329,ape_chain:33139,b3:8333,soneium:1868,ronin:2020,bera_chain:80094,shape:360,unichain:130,gunzilla:43419,abstract:2741,animechain:69e3,hyperevm:999,somnia:5031,monad:143,megaeth:4326,ink:57073,stablechain:988});var kc=Object.freeze({OrderComponents:[{name:"offerer",type:"address"},{name:"zone",type:"address"},{name:"offer",type:"OfferItem[]"},{name:"consideration",type:"ConsiderationItem[]"},{name:"orderType",type:"uint8"},{name:"startTime",type:"uint256"},{name:"endTime",type:"uint256"},{name:"zoneHash",type:"bytes32"},{name:"salt",type:"uint256"},{name:"conduitKey",type:"bytes32"},{name:"counter",type:"uint256"}],OfferItem:[{name:"itemType",type:"uint8"},{name:"token",type:"address"},{name:"identifierOrCriteria",type:"uint256"},{name:"startAmount",type:"uint256"},{name:"endAmount",type:"uint256"}],ConsiderationItem:[{name:"itemType",type:"uint8"},{name:"token",type:"address"},{name:"identifierOrCriteria",type:"uint256"},{name:"startAmount",type:"uint256"},{name:"endAmount",type:"uint256"},{name:"recipient",type:"address"}]});var Tc=new He(["function setApprovalForAll(address operator,bool approved)"]),Ic=new He(["function cancel((address offerer,address zone,(uint8 itemType,address token,uint256 identifierOrCriteria,uint256 startAmount,uint256 endAmount)[] offer,(uint8 itemType,address token,uint256 identifierOrCriteria,uint256 startAmount,uint256 endAmount,address recipient)[] consideration,uint8 orderType,uint256 startTime,uint256 endTime,bytes32 zoneHash,uint256 salt,bytes32 conduitKey,uint256 counter)[] orders) returns (bool cancelled)"]);var Co="https://api.satflow.com/v1";function dn(e={}){return me({provider:"satflow",defaultUrl:Co,hosts:["api.satflow.com"],url:e.baseUrl||process.env.SATFLOW_API_URL})}function Po(e={}){return dn(e).baseUrl}function pn(e={}){return String(e.apiKey||process.env.SATFLOW_API_KEY||process.env.BTC_SATFLOW_API_KEY||"").trim()}function Ro(e={}){return le({accept:"application/json","content-type":"application/json","user-agent":"oracle-btc-satflow/0.1"},{"x-api-key":pn(e)},dn(e).trusted)}async function $o(e,{method:t="GET",body:n,opts:r={}}={}){if(!pn(r))throw new Error("satflow: SATFLOW_API_KEY not set (request key via Satflow docs form)");let i=`${Po(r)}${e.startsWith("/")?e:`/${e}`}`,a=await(r.fetchImpl||fetch)(i,{method:t,headers:Ro(r),body:n!=null?JSON.stringify(n):void 0,signal:AbortSignal.timeout(r.timeoutMs??2e4)}),c=await a.text(),h;try{h=JSON.parse(c)}catch{h=c}if(!a.ok)throw new Error(`satflow ${t} ${e}: HTTP ${a.status} ${String(c).slice(0,200)}`);return h}async function fn(e={},t={}){let n=fe(e.address||e.addr,"address"),r=new URLSearchParams({address:n});e.type&&r.set("type",e.type),e.limit!=null&&r.set("limit",String(e.limit)),e.offset!=null&&r.set("offset",String(e.offset));let o=await $o(`/address/wallet-contents?${r}`,{opts:t});return{provider:"satflow",address:n,contents:o}}z();z();var jc=Object.freeze(["i.seadn.io","openseauserdata.com","arweave.net","ipfs.io","nftstorage.link","dweb.link","cloudflare-ipfs.com","ordinals.com","ordinals.g.com","cdn.helius-rpc.com","shdw-drive.genesysgo.net"]);var Lo=[/\bclaim\b/i,/\breward\b/i,/\bairdrop\b/i,/\bvoucher\b/i,/\bwinner\b/i,/\bfree\s*mint\b/i,/\bactivate\b/i,/\bunlock\b/i,/\bverify\b/i,/\bconnect\s+wallet\b/i],Fo=/(https?:\/\/|www\.|[a-z0-9-]+\.(?:com|net|io|xyz|org|app|finance|gift|claims?|site|link|live|vip|top|cc))/i,Uo=/(\$\s?\d|\d[\d,.]*\s*(?:usd|usdc|usdt|eth|weth|btc|sol)\b)/i;function Mo(e={}){let t=[],n=String(e.name||""),r=String(e.description||""),o=`${n} ${r}`;Fo.test(n)&&t.push("url-in-name");let i=Lo.filter(h=>h.test(o)).length;i>0&&t.push(`lure-language:${i}`),Uo.test(n)&&t.push("value-claim-in-name"),/[\u200B-\u200F\u202A-\u202E\uFEFF]/.test(n)&&t.push("invisible-characters"),e.disabled===!0&&t.push("marketplace-disabled");let s=e.estimatedValueUsd==null&&e.estimatedValueSats==null,a=!Array.isArray(e.traits)||e.traits.length===0;s&&a&&i>0&&t.push("valueless-airdrop-with-lure");let c=t.includes("url-in-name")||t.includes("invisible-characters")||t.includes("valueless-airdrop-with-lure")||t.length>=2;return{spam:c,risk:c?"high":t.length>0?"low":"none",reasons:t}}function mn(e={}){let t=Mo(e);return{...e,spam:e.spam===!0||t.spam,riskLevel:t.risk,riskReasons:t.reasons.length?t.reasons:void 0}}var Do=Object.freeze([{chain:"ethereum",chainId:1,family:"evm"},{chain:"optimism",chainId:10,family:"evm"},{chain:"polygon",chainId:137,family:"evm"},{chain:"stablechain",chainId:988,family:"evm"},{chain:"hyperevm",chainId:999,family:"evm"},{chain:"abstract",chainId:2741,family:"evm"},{chain:"robinhood",chainId:4663,family:"evm"},{chain:"base",chainId:8453,family:"evm"},{chain:"arbitrum",chainId:42161,family:"evm"},{chain:"avalanche",chainId:43114,family:"evm"},{chain:"hyperliquid",chainId:null,family:"hyperliquid"}]),Bo=Object.freeze([{family:"evm",chain:"bsc",chainId:56,reason:"OpenSea account inventory does not support BSC"},{family:"cosmos",reason:"requires a chain-specific bech32 address and NFT indexer"},{family:"sui",reason:"owner inventory adapter not installed"},{family:"aptos",reason:"owner inventory adapter not installed"}]);function ht(e={},t){return{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs,env:e.env,allowDiskCredentials:e.allowDiskCredentials,allowAmbientCredentials:e.allowAmbientCredentials,...e[t]||{}}}async function he(e,t){let n=await Be(t);return n.ok?{ok:!0,data:n.data}:{ok:!1,error:`${e}: ${n.error}`.slice(0,300)}}function qo(e){if(Array.isArray(e))return e;for(let t of["items","results","ordinals","inscriptions","data"])if(Array.isArray(e?.[t]))return e[t];return[]}function jo(e={},t){let n=e.inscription_id||e.inscriptionId||e.id||e.inscription||null;return{chain:"bitcoin",family:"bitcoin",owner:t,contract:null,tokenId:n==null?null:String(n),tokenStandard:"ordinal",collection:e.collection_slug||e.collectionSlug||e.collection?.slug||e.collection||null,name:e.name||e.meta?.name||(n?`Inscription ${n}`:"Bitcoin inscription"),description:e.description||e.meta?.description||null,imageUrl:e.image_url||e.imageUrl||e.content_url||e.contentUrl||e.thumbnail||null,originalImageUrl:e.content_url||e.contentUrl||e.image_url||e.imageUrl||null,animationUrl:null,metadataUrl:e.metadata_url||e.metadataUrl||null,marketplaceUrl:e.marketplace_url||e.marketplaceUrl||null,estimatedValueUsd:e.estimated_value_usd!=null&&Number.isFinite(Number(e.estimated_value_usd))?Number(e.estimated_value_usd):null,estimatedValueSats:(e.floor_price_sats??e.price_sats)!=null&&Number.isFinite(Number(e.floor_price_sats??e.price_sats))?Number(e.floor_price_sats??e.price_sats):null,spam:!1,disabled:!1,nsfw:!1,listed:e.listed===!0||e.is_listed===!0,listingId:e.listing_id||e.listingId||null,traits:Array.isArray(e.traits)?e.traits:[],updatedAt:e.updated_at||e.updatedAt||null,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"Satflow wallet inventory does not expose trustworthy acquisition cost"},listingAdapter:"satflow",source:"satflow-wallet-contents"}}function Ho(e,t){return{chain:"bitcoin",family:"bitcoin",owner:t,contract:null,tokenId:String(e),tokenStandard:"ordinal",collection:null,name:`Inscription ${e}`,description:null,imageUrl:null,originalImageUrl:null,animationUrl:null,metadataUrl:null,marketplaceUrl:null,estimatedValueUsd:null,spam:!1,disabled:!1,nsfw:!1,traits:[],updatedAt:null,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"address indexer returned no acquisition or valuation data"},listingAdapter:"satflow",source:"bitcoin-meta-address-indexer"}}function hn(e={}){return[e.chain||"unknown",e.contract||"native",e.tokenId||"unknown"].join(":").toLowerCase()}function Vo(e){let t=new Map;if(Array.isArray(e)){for(let n of e)n?.assetKey&&t.set(String(n.assetKey).toLowerCase(),n);return t}if(e&&typeof e=="object")for(let[n,r]of Object.entries(e))t.set(n.toLowerCase(),r);return t}function zo(e,t){let n=hn(e),r=t.get(n),o=e.estimatedValueUsd==null?null:Number(e.estimatedValueUsd);if(!r)return{...e,assetKey:n};let i=Number(r.costUsd),s=Number(r.feesUsd??0);if(!Number.isFinite(i)||i<0||!Number.isFinite(s)||s<0)return{...e,assetKey:n,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"invalid user-supplied cost basis"}};let a=Math.round((i+s)*100)/100;return Number.isFinite(o)?{...e,assetKey:n,acquisitionCost:{costUsd:i,feesUsd:s,totalCostUsd:a,acquiredAt:r.acquiredAt||null,source:r.source||"user-supplied"},itemPnl:{status:"estimated",methodology:"provider estimated current value minus supplied USD acquisition cost and fees",unrealizedUsd:Math.round((o-a)*100)/100,currentValueUsd:o,totalCostUsd:a,realizedUsd:null}}:{...e,assetKey:n,acquisitionCost:{costUsd:i,feesUsd:s,totalCostUsd:a,acquiredAt:r.acquiredAt||null,source:r.source||"user-supplied"},itemPnl:{status:"unavailable",reason:"current NFT valuation is unavailable"}}}function Ko(e){let t=new Map;for(let n of e){let r=hn(n);t.has(r)||t.set(r,n)}return[...t.values()]}function Wo(e,t){let n=e.filter(i=>i.itemPnl?.status==="estimated"),r=e.length-n.length,o=Math.round(n.reduce((i,s)=>i+Number(s.itemPnl.unrealizedUsd||0),0)*100)/100;return{nftItemPnl:{status:r===0&&e.length?"estimated-complete-for-held-items":n.length?"partial":"unavailable",methodology:"Only items with explicit acquisition cost and provider estimated current value are included",knownUnrealizedUsd:o,knownItems:n.length,unknownItems:r,realizedUsd:null,warning:"Transfers, gifts, airdrops, mints, bridges, gas, royalties, and off-market sales can make cost basis unavailable or incomplete."},providerAccountPnl:t}}async function yn(e={},t={}){let n=new Date().toISOString(),r=on(e,t.env||process.env),o=Array.isArray(e.chains)&&e.chains.length?new Set(e.chains.map(d=>String(d).toLowerCase())):null,i=Do.filter(d=>!o||o.has(d.chain)),s=[],a=[],c=ht(t,"opensea"),h=r.evm?i.filter(d=>d.family!=="solana"):[],p=await xe(h,4,async d=>({row:d,result:await he(`opensea-${d.chain}`,()=>mt({chain:d.chain,address:r.evm,pageSize:e.pageSize,maxPages:e.maxPages},c),t.timeoutMs??35e3)}));for(let{row:d,result:u}of p)if(u.ok){let m=u.data.nfts.map(f=>({...f,family:d.family,chainId:d.chainId,listingAdapter:"opensea",source:"opensea-account-inventory"}));a.push(...m),s.push({family:d.family,chain:d.chain,chainId:d.chainId,status:u.data.complete?"ok":"partial",count:m.length,complete:u.data.complete,next:u.data.next,source:"opensea"})}else{let m=Yt(d.chainId)?await he(`blockscout-${d.chain}`,()=>Jt({chain:d.chain,chainId:d.chainId,address:r.evm,maxPages:e.maxPages},{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})):null;m?.ok?(a.push(...m.data.nfts),s.push({...d,status:m.data.complete?"ok":"partial",count:m.data.nfts.length,complete:m.data.complete,next:m.data.next,truncated:m.data.truncated,source:"blockscout",errors:[u.error,...m.data.errors]})):s.push({...d,status:"unavailable",count:null,complete:!1,error:u.error,errors:[u.error,...m?[m.error]:[]],source:"opensea"})}if(!r.evm)for(let d of i.filter(u=>u.family!=="solana"))s.push({family:d.family,chain:d.chain,chainId:d.chainId,status:"not-configured",reason:"EVM address missing"});if(r.solana&&(!o||o.has("solana"))){let d=await he("opensea-solana",()=>mt({chain:"solana",address:r.solana,pageSize:e.pageSize,maxPages:e.maxPages},c),t.timeoutMs??35e3);if(d.ok){let u=d.data.nfts.map(m=>({...m,family:"solana",chainId:null,listingAdapter:null,source:"opensea-account-inventory"}));a.push(...u),s.push({family:"solana",chain:"solana",status:d.data.complete?"ok":"partial",count:u.length,complete:d.data.complete,next:d.data.next,source:"opensea"})}else s.push({family:"solana",chain:"solana",status:"unavailable",error:d.error,source:"opensea"})}else(!o||o.has("solana"))&&s.push({family:"solana",chain:"solana",status:"not-configured",reason:"Solana address missing"});if(r.bitcoin&&(!o||o.has("bitcoin"))){let d=await he("satflow-wallet-contents",()=>fn({address:r.bitcoin,type:"ordinals",limit:e.bitcoinLimit??100,offset:0},ht(t,"satflow")),t.timeoutMs??35e3);if(d.ok){let u=qo(d.data.contents).map(f=>jo(f,r.bitcoin));a.push(...u);let m=u.length<Number(e.bitcoinLimit??100);s.push({family:"bitcoin",chain:"bitcoin",status:m?"ok":"partial",count:u.length,complete:m,source:"satflow"})}else{let u=await he("bitcoin-meta-inscriptions",()=>pt({address:r.bitcoin},ht(t,"bitcoinMeta")),t.timeoutMs??35e3),m=u.ok&&u.data?.ok&&Array.isArray(u.data.inscriptions)?u.data.inscriptions:[];a.push(...m.map(f=>Ho(f,r.bitcoin))),s.push({family:"bitcoin",chain:"bitcoin",status:m.length?"partial":"unavailable",count:m.length,complete:!1,source:m.length?"bitcoin-meta":"satflow",error:m.length?"Satflow unavailable; fallback has IDs only":d.error})}}else(!o||o.has("bitcoin"))&&s.push({family:"bitcoin",chain:"bitcoin",status:"not-configured",reason:"Bitcoin address missing"});let w=[];if(e.includePnl!==!1)for(let d of[...new Set([r.evm,r.solana].filter(Boolean))]){let u=await he(`opensea-pnl-${d}`,()=>un({address:d},c),t.timeoutMs??35e3);w.push(u.ok?{status:"ok",...u.data}:{status:"unavailable",address:d,source:"opensea-indexed-account-pnl",error:u.error})}let T=Vo(e.costBasis),x=Ko(a).map(d=>zo(d,T)).map(d=>mn(d)),b=x.filter(d=>!d.spam),I=x.filter(d=>d.spam),O=b.filter(d=>d.estimatedValueUsd!=null&&Number.isFinite(Number(d.estimatedValueUsd))),$=Math.round(O.reduce((d,u)=>d+Number(u.estimatedValueUsd),0)*100)/100,B=b.length-O.length,y=s.filter(d=>d.status!=="ok"||d.complete===!1);return{provider:"nft-portfolio",operation:"inventory",readOnly:!0,generatedAt:n,addresses:r,coverage:s,unsupported:Bo,inventory:{count:x.length,visibleCount:b.length,flaggedCount:I.length,items:x,visibleItems:b,flaggedItems:I},valuation:{estimatedCurrentValueUsd:$,valuedItems:O.length,unvaluedItems:B,complete:B===0&&y.length===0,methodology:"Sum of provider estimated_value_usd for non-flagged items. It is not an executable bid."},pnl:Wo(b,w),listingCoverage:{opensea:"EVM listing actions available with OPENSEA_API_KEY, explicit price/currency/expiry, and user confirmation",satflow:"Bitcoin unsigned listing PSBT available with SATFLOW_API_KEY, explicit price/expiry, and user confirmation",solana:"Magic Eden unsigned list transaction available with MAGICEDEN_API_KEY, explicit SOL price/expiry, and user confirmation",unsupported:"Sui, Aptos, Cosmos, BSC, and unknown marketplaces fail closed"},traitSniperCoverage:{opensea:"Evaluates reveal/trait-floor mispricing only with recent trait sales and volume evidence. Buy intents require local vault signing.",execution:"prepare-only on hosted surfaces; local vault required for purchase"},metadataSafety:{imagesAreUntrusted:!0,animationAndHtmlNotRendered:!0,galleryRasterOnly:!0,missingImagesUsePlaceholders:!0}}}var wn=1,Jo=/^0x[0-9a-f]{40}$/,Zo=/^[1-9A-HJ-NP-Za-km-z]{32,64}$/,Xo=/^[A-Z0-9][A-Z0-9._-]{1,15}$/;function Qo(e=process.env){let t=e.ORACLE_CONFIG_DIR||Ke.join(bn(),".config","oracle");return Ke.join(t,"held-nft-pump.v1.json")}function ei(e=process.env){let t=e.ORACLE_CONFIG_DIR||Ke.join(bn(),".config","oracle"),n={};try{let o=JSON.parse(Go(Ke.join(t,"portfolio.json"),"utf8"));n=o&&typeof o=="object"&&!Array.isArray(o)?o.addresses||o:{}}catch{}let r={evm:e.ORACLE_EVM_ADDRESS||n.evm,solana:e.ORACLE_SOLANA_ADDRESS||n.solana};return Object.fromEntries(Object.entries(r).filter(([,o])=>typeof o=="string"&&o.trim()).map(([o,i])=>[o,i.trim()]))}function ti(e){return{...e,ORACLE_DEFAULT_ADDRESS:"",MAD_OPERATOR_ADDRESS:""}}function gn(e){let t=Number(e);return Number.isFinite(t)&&t>0?t:null}function ni(e){let t=e?.quantity??e?.balance??1;if(typeof t!="string"&&typeof t!="number"&&typeof t!="bigint"||!/^\d+$/.test(String(t)))return 0n;let n=BigInt(String(t));return n>0n?n:0n}function ri(e){return e<=BigInt(Number.MAX_SAFE_INTEGER)?Number(e):e.toString()}function oi(e){if(!e||e.version!==wn||!e.collections||typeof e.collections!="object"||Array.isArray(e.collections))throw new TypeError("invalid held NFT pump state");if(!Number.isSafeInteger(e.cursor??0)||(e.cursor??0)<0)throw new TypeError("invalid held NFT pump cursor");if(e.walletFingerprint!==void 0&&!/^[a-f0-9]{64}$/.test(e.walletFingerprint))throw new TypeError("invalid held NFT wallet fingerprint");if(e.walletChanged!==void 0&&typeof e.walletChanged!="boolean")throw new TypeError("invalid held NFT wallet-change marker");let t=e.failures??{};if(!t||typeof t!="object"||Array.isArray(t))throw new TypeError("invalid held NFT pump failures");let n=Object.entries(e.collections);if(n.length>1e4||Object.keys(t).length>1e4)throw new TypeError("held NFT pump state exceeds collection bound");for(let[r,o]of n){if(!r||r.length>260||!o||gn(o.anchorFloor)===null)throw new TypeError("invalid held NFT floor record");if(!Number.isFinite(o.updatedAt)||o.updatedAt<0)throw new TypeError("invalid held NFT update time");if(o.lastAlertAt!==null&&(!Number.isFinite(o.lastAlertAt)||o.lastAlertAt<0))throw new TypeError("invalid held NFT alert time")}for(let r of Object.values(t))if(!r||!Number.isSafeInteger(r.count)||r.count<1||!Number.isFinite(r.nextCheckAt)||r.nextCheckAt<0)throw new TypeError("invalid held NFT provider backoff")}function En(e={}){let t=e?.inventory?.visibleItems??e?.inventory?.items??[],n=new Map;for(let r of Array.isArray(t)?t:[]){if(r?.spam===!0||r?.disabled===!0)continue;let o=String(r?.chain||"").trim().toLowerCase(),i=String(r?.contract||"").trim(),s=o==="solana"?i:i.toLowerCase(),a=String(r?.collection||"").trim().toLowerCase();if(!o||!a||!(o==="solana"?Zo.test(s):Jo.test(s)))continue;let c=ni(r);if(c===0n)continue;let h=`${o}:${s}`,p=n.get(h);p&&p.slug!==a||n.set(h,{key:h,chain:o,contract:s,slug:a,name:p?.name||String(r?.name||a),heldCountRaw:(p?.heldCountRaw||0n)+c})}return[...n.values()].map(({heldCountRaw:r,...o})=>({...o,heldCount:ri(r)})).sort((r,o)=>r.key.localeCompare(o.key))}function ii(e,t){let n=String(e?.currency||"").trim().toUpperCase();if(!Xo.test(n))return{ok:!1,reason:"floor-currency-unavailable"};if(e?.chain&&String(e.chain).trim().toLowerCase()!==t.chain)return{ok:!1,reason:"floor-identity-mismatch"};let r=Array.isArray(e?.contracts)?e.contracts:Array.isArray(e?.raw?.contracts)?e.raw.contracts:[],o=t.chain==="solana"?t.contract:t.contract.toLowerCase();return r.some(s=>{let a=String(s?.address||s?.contract_address||s?.contract||"").trim(),c=t.chain==="solana"?a:a.toLowerCase(),h=String(s?.chain||s?.chain_identifier||"").trim().toLowerCase();return c===o&&h===t.chain})?{ok:!0,currency:n}:{ok:!1,reason:"floor-identity-mismatch"}}function si(e,t,n,r,o){let i=Math.round((t/r.anchorFloor-1)*1e4)/100;return Object.freeze({type:"held_nft_floor_pump",category:"price",chain:e.chain,contract:e.contract,slug:e.slug,name:e.name,heldCount:e.heldCount,fromFloor:r.anchorFloor,floor:t,currency:n,changePct:i,observedAt:new Date(o).toISOString(),evidence:Object.freeze({source:"opensea-collection-floor",status:"provider-estimate",chain:e.chain,contract:e.contract,currency:n,observedAt:new Date(o).toISOString(),warning:"Floor is a provider estimate, not an executable bid or guaranteed liquidation value."}),custody:"none",executionAllowed:!1})}function ai({filePath:e,env:t=process.env,clock:n=()=>Date.now(),inventoryFn:r=yn,floorFn:o=ln,notifyFn:i=async()=>({delivered:0}),thresholdPct:s=Number(t.ORACLE_NFT_PUMP_THRESHOLD_PCT??15),cooldownMs:a=Number(t.ORACLE_NFT_PUMP_COOLDOWN_HOURS??6)*36e5,maxFloorChecksPerTick:c=Number(t.ORACLE_NFT_PUMP_MAX_FLOORS_PER_TICK??20),inventoryPageSize:h=100,inventoryMaxPages:p=2}={}){if(typeof r!="function"||typeof o!="function"||typeof i!="function")throw new TypeError("held NFT watchdog functions are required");if(!Number.isFinite(s)||s<=0||s>1e3)throw new TypeError("held NFT pump threshold is out of range");if(!Number.isFinite(a)||a<6e4||a>30*864e5)throw new TypeError("held NFT pump cooldown is out of range");if(!Number.isSafeInteger(c)||c<1||c>100)throw new TypeError("held NFT floor budget is out of range");let w=te({filePath:e||Qo(t),kind:"oracle-held-nft-pump",clock:n,maxBytes:4*1024*1024,initialData:()=>({version:wn,cursor:0,collections:{},failures:{}}),validateData:oi}),T=!1;function x(I,O){w.mutate($=>{$.failures||={};let B=Math.min(20,Number($.failures[I]?.count||0)+1);$.failures[I]={count:B,nextCheckAt:O+Math.min(6*36e5,3e5*2**Math.min(6,B-1))}})}async function b(){if(T)return{skipped:!0,reason:"tick-in-progress",alerts:[],unavailable:[]};T=!0;try{let I=Number(n());if(!Number.isFinite(I))throw new TypeError("held NFT watchdog clock is invalid");let O=ei(t),$=ti(t),B=Yo("sha256").update(JSON.stringify(Object.entries(O).sort())).digest("hex");w.mutate(l=>{let E=!!(l.walletFingerprint&&l.walletFingerprint!==B);E&&(l.collections={},l.failures={},l.cursor=0),l.walletFingerprint=B,l.walletChanged=E});let y=await r({addresses:O,includePnl:!1,pageSize:h,maxPages:p},{env:$}),d=En(y),u=new Set(d.map(l=>l.key)),m=new Set((Array.isArray(y?.coverage)?y.coverage:[]).filter(l=>l?.status==="ok"&&l?.complete===!0).map(l=>String(l.chain||"").toLowerCase()).filter(Boolean));m.size&&w.mutate(l=>{for(let E of Object.keys(l.collections)){let k=E.slice(0,E.indexOf(":"));m.has(k)&&!u.has(E)&&delete l.collections[E]}for(let E of Object.keys(l.failures||{})){let k=E.slice(0,E.indexOf(":"));m.has(k)&&!u.has(E)&&delete l.failures[E]}});let f=w.mutate(l=>{let E=d.length?(l.cursor||0)%d.length:0;return l.cursor=d.length?(E+Math.min(c,d.length))%d.length:0,E}),S=[];for(let l=0;l<Math.min(c,d.length);l+=1)S.push(d[(f+l)%d.length]);let A=[],g=[];for(let l of S){let E=w.inspect().data.failures?.[l.key];if(E&&E.nextCheckAt>I){g.push({key:l.key,reason:"floor-provider-backoff"});continue}let k;try{k=await o(l.slug,{env:$,expectedChain:l.chain,expectedContract:l.contract})}catch{x(l.key,I),g.push({key:l.key,reason:"floor-provider-unavailable"});continue}let v=ii(k,l);if(!v.ok){x(l.key,I),g.push({key:l.key,reason:v.reason});continue}let _=gn(k?.floor);if(_===null){x(l.key,I),g.push({key:l.key,reason:"floor-unavailable"});continue}let R=w.mutate(F=>{F.failures||={},delete F.failures[l.key];let N=F.collections[l.key];if(!N)return F.collections[l.key]={anchorFloor:_,lastAlertAt:null,updatedAt:I,currency:v.currency},null;if(N.updatedAt=I,N.currency!==v.currency)return N.anchorFloor=_,N.currency=v.currency,N.lastAlertAt=null,null;if(_<N.anchorFloor)return N.anchorFloor=_,N.currency=v.currency,null;if((_/N.anchorFloor-1)*100+1e-9<s)return null;if(N.lastAlertAt!==null&&I-N.lastAlertAt<a)return N.anchorFloor=_,N.currency=v.currency,null;let Z=si({...l,name:k?.name||l.name},_,v.currency,N,I);return N.anchorFloor=_,N.lastAlertAt=I,N.updatedAt=I,N.currency=v.currency,Z});if(!R)continue;let U;try{U=await i(R)}catch{U=null}if(!U||Number(U.delivered||0)!==1){g.push({key:l.key,reason:"notification-delivery-failed"});continue}A.push(R)}return{provider:"held-nft-pump",readOnly:!0,custody:"none",executionAllowed:!1,heldCollections:d.length,checkedCollections:S.length,alerts:A,unavailable:g,coverage:y?.coverage??[]}}finally{T=!1}}return Object.freeze({filePath:w.filePath,tick:b,inspect:w.inspect})}function ue(e,t=160){return String(e??"").replace(/[\u0000-\u001f\u007f]/g," ").slice(0,t)}function yt(e){let t=Number(e);return Number.isFinite(t)?t:null}function ci(e,t={},n=process.env){let r=String(e||"").trim().toUpperCase().replace(/[^A-Z0-9]/g,"");if(!r)return[];let o=String(n[`ORACLE_OWNER_${r}`]||"").split(/[\s,;]+/).filter(Boolean),i=Array.isArray(t.owners)?t.owners.map(String):[];return[...new Set([...o,...i].map(s=>s.trim()).filter(Boolean))]}function Sn(e={}){let t=typeof e.heldCount=="string"&&/^\d+$/.test(e.heldCount)?e.heldCount:Number.isSafeInteger(Number(e.heldCount))?String(Number(e.heldCount)):"unknown",n=yt(e.fromFloor),r=yt(e.floor),o=yt(e.changePct),i=ue(e.currency||"unknown",16);return`ORACLE NFT \u2014 YOUR BAG IS PUMPING
6
6
 
7
7
  ${[`Collection: ${ue(e.name||e.slug||"Unknown")}`,`Chain: ${ue(e.chain||"unknown")}`,`You hold: ${t}`,`Floor: ${n??"unknown"} \u2192 ${r??"unknown"} ${i}`,`Move: ${o===null?"unknown":`+${o}%`}`,`Contract: ${ue(e.contract||"unknown",64)}`,"Evidence: provider-estimated floor; not an executable bid or guaranteed liquidation value."].join(`
8
- `)}`}function wn(e=[],t=""){let n=(Array.isArray(e)?e:[]).filter(a=>typeof a?.notifyRecipient=="function");if(!n.length)return null;let r=String(t||"").trim().toLowerCase(),o=r?n.filter(a=>String(a.platform||"").toLowerCase()===r):[],i=n.filter(a=>a.platform==="telegram"),s=o.length?o:i.length?i:n;for(let a of s){let c=[...new Set((Array.isArray(a.ownerIds)?a.ownerIds:[]).map(f=>String(f).trim()).filter(Boolean))];if(c.length!==1)continue;let y=ue(String(a.platform||"").toLowerCase(),32);if(y)return Object.freeze({platform:y,recipientId:c[0],target:a})}return null}function Xo(e=[],t=""){let n=wn(e,t);return n?[n.target]:[]}function ei(e){if(!e||typeof e.target?.notifyRecipient!="function")throw new TypeError("one recipient-bound notification subscription is required");let{target:t,recipientId:n}=e,r=ue(e.platform||t.platform||"unknown",32);return async function(i){let s=bn(i);try{let a=Number(await t.notifyRecipient(n,s,i)),c=Number.isSafeInteger(a)&&a>0?1:0;return{delivered:c,recipient:{platform:r,id:n},error:c?null:"delivery-failed"}}catch{return{delivered:0,recipient:{platform:r,id:n},error:"delivery-failed"}}}}function ti({watchdog:e,intervalMs:t=3e5,setIntervalFn:n=setInterval,clearIntervalFn:r=clearInterval,onError:o=i=>process.stderr.write(`oracle-gateway: held NFT watchdog failed: ${ue(i?.message||i,200)}
9
- `)}={}){if(typeof e?.tick!="function")throw new TypeError("held NFT watchdog is required");if(!Number.isSafeInteger(t)||t<6e4||t>864e5)throw new TypeError("held NFT watchdog interval is out of range");let i=null,s=!1,a=async()=>{if(s)return{skipped:!0,reason:"tick-in-progress"};s=!0;try{return await e.tick()}catch(c){return o(c),{skipped:!0,reason:"tick-failed"}}finally{s=!1}};return Object.freeze({start(){i===null&&(a(),i=n(a,t),typeof i?.unref=="function"&&i.unref())},stop(){i!==null&&r(i),i=null},run:a})}rt();import gn from"node:path";import{homedir as ni}from"node:os";import{createHash as En,createHmac as Sn,randomUUID as ri,timingSafeEqual as oi}from"node:crypto";var ht=1,ii="hmac-sha256",An="x-oracle-signature",vn="x-oracle-timestamp",xn="x-oracle-delivery-id",kn="x-oracle-key-id";function Ve(e,t){if(e&&typeof e.get=="function")return e.get(t);let n=t.toLowerCase();for(let[r,o]of Object.entries(e??{}))if(r.toLowerCase()===n)return o}function si(e){let t=e&&typeof e=="object"&&!Buffer.isBuffer(e)&&!(e instanceof Uint8Array),n=t?e.secret:e,r=t?e.keyId??null:null,o;if(typeof n=="string")o=Buffer.from(n,"utf8");else if(Buffer.isBuffer(n)||n instanceof Uint8Array)o=Buffer.from(n),(Buffer.isBuffer(n)||n instanceof Uint8Array)&&n.fill(0);else throw new TypeError("secretProvider must return a string, bytes, or { secret, keyId }");if(o.length<32||o.length>4096)throw o.fill(0),new TypeError("webhook signing secret must contain 32 to 4096 bytes");return r!==null&&P("webhook keyId",r,{max:128}),{bytes:o,keyId:r}}async function Tn(e,t){if(typeof e!="function")throw new TypeError("an injected secretProvider is required");return si(await e(Object.freeze({...t})))}function In(e,t,n){return`${e??""}.${t}.${n}`}function _n(e){if(!e||e.schemaVersion!==ht)throw new TypeError("unsupported webhook envelope version");if(P("deliveryId",e.deliveryId,{max:128}),P("eventId",e.eventId,{max:160}),B(e.tenantId,e.workflowId),Z(e.category),e.destinationId!==null&&P("destinationId",e.destinationId,{max:160}),!Number.isFinite(Date.parse(e.occurredAt))||!Number.isFinite(Date.parse(e.createdAt)))throw new TypeError("invalid webhook envelope time");if(e.executionAllowed!==!1||e.custody!=="none")throw new TypeError("webhook envelope crossed the custody boundary");return Q(e.payload),e}async function Nn(e,{lookupFn:t,assertPublicUrlFn:n=Ee,pin:r}={}){if(typeof e!="string"||e.length<1||e.length>2048)throw new TypeError("webhook URL must be a bounded string");let o;try{o=new URL(e)}catch{throw new TypeError("webhook destination is not a valid URL")}if(o.protocol!=="https:")throw new TypeError("webhook destination must use HTTPS");if(o.username||o.password)throw new TypeError("webhook destination must not contain URL credentials");if(o.hash)throw new TypeError("webhook destination must not contain a fragment");let i=await n(o.toString(),t?{lookupFn:t}:{});if(!i?.ok)throw new Error(i?.error||"webhook destination was refused");if(!Array.isArray(i.addresses)||i.addresses.length===0)throw new Error("webhook destination did not return pinned addresses");let s=i.addresses.map(({address:a,family:c})=>Object.freeze({address:a,family:c}));if(r!==void 0){if(typeof r!="function")throw new TypeError("pin must be a function");await r(i.url.hostname,s)}return Object.freeze({url:i.url.toString(),host:i.url.hostname,addresses:Object.freeze(s)})}async function On(e={},{secretProvider:t,clock:n=()=>Date.now(),deliveryId:r=ri(),destinationId:o=e.destinationId??null}={}){let i=j(n),{tenantId:s,workflowId:a}=B(e.tenantId,e.workflowId),c=Z(e.category),y={schemaVersion:ht,deliveryId:P("deliveryId",String(r),{max:128}),eventId:P("eventId",String(e.eventId??e.id??""),{max:160}),tenantId:s,workflowId:a,category:c,destinationId:o==null?null:P("destinationId",o,{max:160}),occurredAt:e.occurredAt===void 0?O(i):O(Date.parse(e.occurredAt)),createdAt:O(i),evidence:se(e.evidence??e.payload?.evidence),payload:Q(e.payload??{}),custody:"none",executionAllowed:!1};_n(y),de(y,"webhook envelope");let f=J(y);if(Buffer.byteLength(f)>64*1024)throw new TypeError("webhook body exceeds 65536 bytes");let h=String(Math.floor(i/1e3)),w=await Tn(t,{tenantId:s,workflowId:a,destinationId:y.destinationId,purpose:"sign",keyId:null}),T;try{T=`sha256=${Sn("sha256",w.bytes).update(In(w.keyId,h,f)).digest("hex")}`}finally{w.bytes.fill(0)}let v={"content-type":"application/json",[xn]:y.deliveryId,[vn]:h,[An]:T,...w.keyId===null?{}:{[kn]:w.keyId}};return Object.freeze({body:f,headers:Object.freeze(v),envelope:Object.freeze(y)})}async function ai({body:e,headers:t}={},{secretProvider:n,clock:r=()=>Date.now(),maxAgeMs:o=5*6e4,maxFutureSkewMs:i=3e4,replayGuard:s,expectedTenantId:a,expectedWorkflowId:c,expectedDestinationId:y}={}){if(typeof e!="string"||Buffer.byteLength(e)>64*1024)return{ok:!1,reason:"invalid-body"};if(!Number.isSafeInteger(o)||o<1e3||!Number.isSafeInteger(i)||i<0)throw new TypeError("invalid webhook verification window");let f=Ve(t,vn),h=Ve(t,An);if(!/^\d{1,16}$/.test(String(f))||!/^sha256=[a-f0-9]{64}$/.test(String(h)))return{ok:!1,reason:"invalid-signature-headers"};let w=Number(f)*1e3,T=j(r);if(w>T+i)return{ok:!1,reason:"future-signature"};if(T-w>o)return{ok:!1,reason:"expired-signature"};let v;try{if(v=JSON.parse(e),_n(v),J(v)!==e)return{ok:!1,reason:"non-canonical-body"}}catch{return{ok:!1,reason:"invalid-envelope"}}if(Ve(t,xn)!==v.deliveryId)return{ok:!1,reason:"delivery-id-mismatch"};if(a!==void 0&&v.tenantId!==a)return{ok:!1,reason:"scope-mismatch"};if(c!==void 0&&v.workflowId!==c)return{ok:!1,reason:"scope-mismatch"};if(y!==void 0&&v.destinationId!==y)return{ok:!1,reason:"destination-mismatch"};let _=Ve(t,kn)??null,C;try{C=await Tn(n,{tenantId:v.tenantId,workflowId:v.workflowId,destinationId:v.destinationId,purpose:"verify",keyId:_})}catch{return{ok:!1,reason:"secret-unavailable"}}let $=!1;try{let b=Sn("sha256",C.bytes).update(In(_,String(f),e)).digest(),d=Buffer.from(String(h).slice(7),"hex");$=d.length===b.length&&oi(d,b)}finally{C.bytes.fill(0)}if(!$)return{ok:!1,reason:"signature-mismatch"};let M=!1;if(s!==void 0){if(!s||typeof s.consume!="function")throw new TypeError("replayGuard must expose consume(record)");if(M=!0,!await s.consume({tenantId:v.tenantId,workflowId:v.workflowId,deliveryId:v.deliveryId,expiresAt:O(w+o+i)}))return{ok:!1,reason:"replay"}}return{ok:!0,envelope:v,replayProtected:M}}function ci({clock:e=()=>Date.now(),maxEntries:t=1e4}={}){if(!Number.isSafeInteger(t)||t<1)throw new TypeError("maxEntries must be positive");let n=new Map;return Object.freeze({consume({tenantId:r,workflowId:o,deliveryId:i,expiresAt:s}={}){B(r,o),P("deliveryId",i,{max:128});let a=Date.parse(s),c=j(e);if(!Number.isFinite(a)||a<=c)return!1;for(let[f,h]of n)h<=c&&n.delete(f);let y=En("sha256").update(`${r}\0${o}\0${i}`).digest("hex");if(n.has(y))return!1;if(n.size>=t)throw new Error("webhook replay guard capacity reached");return n.set(y,a),!0},get size(){return n.size}})}function li(e=process.env){let t=e.ORACLE_CONFIG_DIR||gn.join(ni(),".config","oracle");return gn.join(t,"webhook-replay.v1.json")}function ui({filePath:e=li(),clock:t=()=>Date.now(),maxEntries:n=1e4,maxBytes:r=4*1024*1024}={}){if(!Number.isSafeInteger(n)||n<1||n>1e5)throw new TypeError("maxEntries is out of range");let i=te({filePath:e,kind:"oracle-webhook-replay",clock:t,maxBytes:r,initialData:()=>({schemaVersion:1,entries:[]}),validateData:s=>{if(!s||s.schemaVersion!==1||!Array.isArray(s.entries)||s.entries.length>n)throw new TypeError("invalid webhook replay store schema");let a=new Set;for(let c of s.entries){if(!c||!/^[a-f0-9]{64}$/.test(c.key)||a.has(c.key))throw new TypeError("invalid webhook replay key");if(!Number.isFinite(Date.parse(c.expiresAt))||!Number.isFinite(Date.parse(c.consumedAt)))throw new TypeError("invalid webhook replay time");a.add(c.key)}}});return Object.freeze({filePath:e,consume({tenantId:s,workflowId:a,deliveryId:c,expiresAt:y}={}){B(s,a),P("deliveryId",c,{max:128});let f=Date.parse(y),h=j(t);if(!Number.isFinite(f)||f<=h)return!1;let w=En("sha256").update(`${s}\0${a}\0${c}`).digest("hex");return i.mutate(T=>{if(T.entries=T.entries.filter(v=>Date.parse(v.expiresAt)>h),T.entries.some(v=>v.key===w))return!1;if(T.entries.length>=n)throw new Error("webhook replay guard capacity reached");return T.entries.push({schemaVersion:Y,key:w,consumedAt:O(h),expiresAt:O(f)}),!0})},inspect:i.inspect})}async function di(e,{destinationUrl:t,destinationId:n=e?.destinationId??null,secretProvider:r,transport:o,pin:i,lookupFn:s,assertPublicUrlFn:a,clock:c=()=>Date.now(),deliveryId:y}={}){if(typeof o!="function")throw new TypeError("an injected webhook transport is required");if(typeof i!="function")throw new TypeError("an injected pinned-resolution hook is required");let f=await Nn(t,{lookupFn:s,assertPublicUrlFn:a,pin:i}),h=await On(e,{secretProvider:r,clock:c,deliveryId:y,destinationId:n}),w=await o(Object.freeze({url:f.url,host:f.host,addresses:f.addresses,method:"POST",redirect:"error",headers:h.headers,body:h.body}));return{deliveryId:h.envelope.deliveryId,response:w}}export{G as DurableStoreError,xt as NOTIFICATION_EVIDENCE,vt as NOTIFICATION_KINDS,Y as NOTIFICATION_SCHEMA_VERSION,Pt as OUTBOX_STATES,Ze as OUTBOX_STORE_SCHEMA_VERSION,Je as SCHEDULE_STORE_SCHEMA_VERSION,Ne as SNAPSHOT_SCHEMA_VERSION,ht as WEBHOOK_ENVELOPE_SCHEMA_VERSION,ii as WEBHOOK_SIGNATURE_ALGORITHM,de as assertNoNotificationSecrets,B as assertNotificationScope,J as canonicalNotificationJson,Qo as configuredOwnerIds,cr as createDurableScheduler,te as createDurableSnapshotStore,ui as createDurableWebhookReplayGuard,ei as createGatewayOwnerNotifier,ti as createHeldNftPumpLoop,Zo as createHeldNftPumpWatchdog,ci as createMemoryWebhookReplayGuard,tr as createNotificationEventSink,mr as createNotificationOutbox,On as createSignedWebhookDelivery,di as deliverWebhook,yn as groupHeldNftCollections,Pe as nextScheduleTime,se as normalizeNotificationEvidence,Re as parseDurableSchedule,bn as renderHeldNftPumpAlert,we as requireNotificationOptIn,Nn as resolveWebhookDestination,Xo as selectNotificationPlatforms,wn as selectNotificationSubscription,ai as verifyWebhookDelivery};
8
+ `)}`}function An(e=[],t=""){let n=(Array.isArray(e)?e:[]).filter(a=>typeof a?.notifyRecipient=="function");if(!n.length)return null;let r=String(t||"").trim().toLowerCase(),o=r?n.filter(a=>String(a.platform||"").toLowerCase()===r):[],i=n.filter(a=>a.platform==="telegram"),s=o.length?o:i.length?i:n;for(let a of s){let c=[...new Set((Array.isArray(a.ownerIds)?a.ownerIds:[]).map(p=>String(p).trim()).filter(Boolean))];if(c.length!==1)continue;let h=ue(String(a.platform||"").toLowerCase(),32);if(h)return Object.freeze({platform:h,recipientId:c[0],target:a})}return null}function li(e=[],t=""){let n=An(e,t);return n?[n.target]:[]}function ui(e){if(!e||typeof e.target?.notifyRecipient!="function")throw new TypeError("one recipient-bound notification subscription is required");let{target:t,recipientId:n}=e,r=ue(e.platform||t.platform||"unknown",32);return async function(i){let s=Sn(i);try{let a=Number(await t.notifyRecipient(n,s,i)),c=Number.isSafeInteger(a)&&a>0?1:0;return{delivered:c,recipient:{platform:r,id:n},error:c?null:"delivery-failed"}}catch{return{delivered:0,recipient:{platform:r,id:n},error:"delivery-failed"}}}}function di({watchdog:e,intervalMs:t=3e5,setIntervalFn:n=setInterval,clearIntervalFn:r=clearInterval,onError:o=i=>process.stderr.write(`oracle-gateway: held NFT watchdog failed: ${ue(i?.message||i,200)}
9
+ `)}={}){if(typeof e?.tick!="function")throw new TypeError("held NFT watchdog is required");if(!Number.isSafeInteger(t)||t<6e4||t>864e5)throw new TypeError("held NFT watchdog interval is out of range");let i=null,s=!1,a=async()=>{if(s)return{skipped:!0,reason:"tick-in-progress"};s=!0;try{return await e.tick()}catch(c){return o(c),{skipped:!0,reason:"tick-failed"}}finally{s=!1}};return Object.freeze({start(){i===null&&(a(),i=n(a,t),typeof i?.unref=="function"&&i.unref())},stop(){i!==null&&r(i),i=null},run:a})}it();import vn from"node:path";import{homedir as pi}from"node:os";import{createHash as xn,createHmac as kn,randomUUID as fi,timingSafeEqual as mi}from"node:crypto";var bt=1,hi="hmac-sha256",Tn="x-oracle-signature",In="x-oracle-timestamp",_n="x-oracle-delivery-id",Nn="x-oracle-key-id";function We(e,t){if(e&&typeof e.get=="function")return e.get(t);let n=t.toLowerCase();for(let[r,o]of Object.entries(e??{}))if(r.toLowerCase()===n)return o}function yi(e){let t=e&&typeof e=="object"&&!Buffer.isBuffer(e)&&!(e instanceof Uint8Array),n=t?e.secret:e,r=t?e.keyId??null:null,o;if(typeof n=="string")o=Buffer.from(n,"utf8");else if(Buffer.isBuffer(n)||n instanceof Uint8Array)o=Buffer.from(n),(Buffer.isBuffer(n)||n instanceof Uint8Array)&&n.fill(0);else throw new TypeError("secretProvider must return a string, bytes, or { secret, keyId }");if(o.length<32||o.length>4096)throw o.fill(0),new TypeError("webhook signing secret must contain 32 to 4096 bytes");return r!==null&&P("webhook keyId",r,{max:128}),{bytes:o,keyId:r}}async function On(e,t){if(typeof e!="function")throw new TypeError("an injected secretProvider is required");return yi(await e(Object.freeze({...t})))}function Cn(e,t,n){return`${e??""}.${t}.${n}`}function Pn(e){if(!e||e.schemaVersion!==bt)throw new TypeError("unsupported webhook envelope version");if(P("deliveryId",e.deliveryId,{max:128}),P("eventId",e.eventId,{max:160}),D(e.tenantId,e.workflowId),J(e.category),e.destinationId!==null&&P("destinationId",e.destinationId,{max:160}),!Number.isFinite(Date.parse(e.occurredAt))||!Number.isFinite(Date.parse(e.createdAt)))throw new TypeError("invalid webhook envelope time");if(e.executionAllowed!==!1||e.custody!=="none")throw new TypeError("webhook envelope crossed the custody boundary");return X(e.payload),e}async function Rn(e,{lookupFn:t,assertPublicUrlFn:n=Ae,pin:r}={}){if(typeof e!="string"||e.length<1||e.length>2048)throw new TypeError("webhook URL must be a bounded string");let o;try{o=new URL(e)}catch{throw new TypeError("webhook destination is not a valid URL")}if(o.protocol!=="https:")throw new TypeError("webhook destination must use HTTPS");if(o.username||o.password)throw new TypeError("webhook destination must not contain URL credentials");if(o.hash)throw new TypeError("webhook destination must not contain a fragment");let i=await n(o.toString(),t?{lookupFn:t}:{});if(!i?.ok)throw new Error(i?.error||"webhook destination was refused");if(!Array.isArray(i.addresses)||i.addresses.length===0)throw new Error("webhook destination did not return pinned addresses");let s=i.addresses.map(({address:a,family:c})=>Object.freeze({address:a,family:c}));if(r!==void 0){if(typeof r!="function")throw new TypeError("pin must be a function");await r(i.url.hostname,s)}return Object.freeze({url:i.url.toString(),host:i.url.hostname,addresses:Object.freeze(s)})}async function $n(e={},{secretProvider:t,clock:n=()=>Date.now(),deliveryId:r=fi(),destinationId:o=e.destinationId??null}={}){let i=j(n),{tenantId:s,workflowId:a}=D(e.tenantId,e.workflowId),c=J(e.category),h={schemaVersion:bt,deliveryId:P("deliveryId",String(r),{max:128}),eventId:P("eventId",String(e.eventId??e.id??""),{max:160}),tenantId:s,workflowId:a,category:c,destinationId:o==null?null:P("destinationId",o,{max:160}),occurredAt:e.occurredAt===void 0?C(i):C(Date.parse(e.occurredAt)),createdAt:C(i),evidence:se(e.evidence??e.payload?.evidence),payload:X(e.payload??{}),custody:"none",executionAllowed:!1};Pn(h),pe(h,"webhook envelope");let p=Y(h);if(Buffer.byteLength(p)>64*1024)throw new TypeError("webhook body exceeds 65536 bytes");let w=String(Math.floor(i/1e3)),T=await On(t,{tenantId:s,workflowId:a,destinationId:h.destinationId,purpose:"sign",keyId:null}),x;try{x=`sha256=${kn("sha256",T.bytes).update(Cn(T.keyId,w,p)).digest("hex")}`}finally{T.bytes.fill(0)}let b={"content-type":"application/json",[_n]:h.deliveryId,[In]:w,[Tn]:x,...T.keyId===null?{}:{[Nn]:T.keyId}};return Object.freeze({body:p,headers:Object.freeze(b),envelope:Object.freeze(h)})}async function bi({body:e,headers:t}={},{secretProvider:n,clock:r=()=>Date.now(),maxAgeMs:o=5*6e4,maxFutureSkewMs:i=3e4,replayGuard:s,expectedTenantId:a,expectedWorkflowId:c,expectedDestinationId:h}={}){if(typeof e!="string"||Buffer.byteLength(e)>64*1024)return{ok:!1,reason:"invalid-body"};if(!Number.isSafeInteger(o)||o<1e3||!Number.isSafeInteger(i)||i<0)throw new TypeError("invalid webhook verification window");let p=We(t,In),w=We(t,Tn);if(!/^\d{1,16}$/.test(String(p))||!/^sha256=[a-f0-9]{64}$/.test(String(w)))return{ok:!1,reason:"invalid-signature-headers"};let T=Number(p)*1e3,x=j(r);if(T>x+i)return{ok:!1,reason:"future-signature"};if(x-T>o)return{ok:!1,reason:"expired-signature"};let b;try{if(b=JSON.parse(e),Pn(b),Y(b)!==e)return{ok:!1,reason:"non-canonical-body"}}catch{return{ok:!1,reason:"invalid-envelope"}}if(We(t,_n)!==b.deliveryId)return{ok:!1,reason:"delivery-id-mismatch"};if(a!==void 0&&b.tenantId!==a)return{ok:!1,reason:"scope-mismatch"};if(c!==void 0&&b.workflowId!==c)return{ok:!1,reason:"scope-mismatch"};if(h!==void 0&&b.destinationId!==h)return{ok:!1,reason:"destination-mismatch"};let I=We(t,Nn)??null,O;try{O=await On(n,{tenantId:b.tenantId,workflowId:b.workflowId,destinationId:b.destinationId,purpose:"verify",keyId:I})}catch{return{ok:!1,reason:"secret-unavailable"}}let $=!1;try{let y=kn("sha256",O.bytes).update(Cn(I,String(p),e)).digest(),d=Buffer.from(String(w).slice(7),"hex");$=d.length===y.length&&mi(d,y)}finally{O.bytes.fill(0)}if(!$)return{ok:!1,reason:"signature-mismatch"};let B=!1;if(s!==void 0){if(!s||typeof s.consume!="function")throw new TypeError("replayGuard must expose consume(record)");if(B=!0,!await s.consume({tenantId:b.tenantId,workflowId:b.workflowId,deliveryId:b.deliveryId,expiresAt:C(T+o+i)}))return{ok:!1,reason:"replay"}}return{ok:!0,envelope:b,replayProtected:B}}function wi({clock:e=()=>Date.now(),maxEntries:t=1e4}={}){if(!Number.isSafeInteger(t)||t<1)throw new TypeError("maxEntries must be positive");let n=new Map;return Object.freeze({consume({tenantId:r,workflowId:o,deliveryId:i,expiresAt:s}={}){D(r,o),P("deliveryId",i,{max:128});let a=Date.parse(s),c=j(e);if(!Number.isFinite(a)||a<=c)return!1;for(let[p,w]of n)w<=c&&n.delete(p);let h=xn("sha256").update(`${r}\0${o}\0${i}`).digest("hex");if(n.has(h))return!1;if(n.size>=t)throw new Error("webhook replay guard capacity reached");return n.set(h,a),!0},get size(){return n.size}})}function gi(e=process.env){let t=e.ORACLE_CONFIG_DIR||vn.join(pi(),".config","oracle");return vn.join(t,"webhook-replay.v1.json")}function Ei({filePath:e=gi(),clock:t=()=>Date.now(),maxEntries:n=1e4,maxBytes:r=4*1024*1024}={}){if(!Number.isSafeInteger(n)||n<1||n>1e5)throw new TypeError("maxEntries is out of range");let i=te({filePath:e,kind:"oracle-webhook-replay",clock:t,maxBytes:r,initialData:()=>({schemaVersion:1,entries:[]}),validateData:s=>{if(!s||s.schemaVersion!==1||!Array.isArray(s.entries)||s.entries.length>n)throw new TypeError("invalid webhook replay store schema");let a=new Set;for(let c of s.entries){if(!c||!/^[a-f0-9]{64}$/.test(c.key)||a.has(c.key))throw new TypeError("invalid webhook replay key");if(!Number.isFinite(Date.parse(c.expiresAt))||!Number.isFinite(Date.parse(c.consumedAt)))throw new TypeError("invalid webhook replay time");a.add(c.key)}}});return Object.freeze({filePath:e,consume({tenantId:s,workflowId:a,deliveryId:c,expiresAt:h}={}){D(s,a),P("deliveryId",c,{max:128});let p=Date.parse(h),w=j(t);if(!Number.isFinite(p)||p<=w)return!1;let T=xn("sha256").update(`${s}\0${a}\0${c}`).digest("hex");return i.mutate(x=>{if(x.entries=x.entries.filter(b=>Date.parse(b.expiresAt)>w),x.entries.some(b=>b.key===T))return!1;if(x.entries.length>=n)throw new Error("webhook replay guard capacity reached");return x.entries.push({schemaVersion:G,key:T,consumedAt:C(w),expiresAt:C(p)}),!0})},inspect:i.inspect})}async function Si(e,{destinationUrl:t,destinationId:n=e?.destinationId??null,secretProvider:r,transport:o,pin:i,lookupFn:s,assertPublicUrlFn:a,clock:c=()=>Date.now(),deliveryId:h}={}){if(typeof o!="function")throw new TypeError("an injected webhook transport is required");if(typeof i!="function")throw new TypeError("an injected pinned-resolution hook is required");let p=await Rn(t,{lookupFn:s,assertPublicUrlFn:a,pin:i}),w=await $n(e,{secretProvider:r,clock:c,deliveryId:h,destinationId:n}),T=await o(Object.freeze({url:p.url,host:p.host,addresses:p.addresses,method:"POST",redirect:"error",headers:w.headers,body:w.body}));return{deliveryId:w.envelope.deliveryId,response:T}}export{W as DurableStoreError,It as NOTIFICATION_EVIDENCE,Tt as NOTIFICATION_KINDS,G as NOTIFICATION_SCHEMA_VERSION,Lt as OUTBOX_STATES,Qe as OUTBOX_STORE_SCHEMA_VERSION,Xe as SCHEDULE_STORE_SCHEMA_VERSION,Ce as SNAPSHOT_SCHEMA_VERSION,bt as WEBHOOK_ENVELOPE_SCHEMA_VERSION,hi as WEBHOOK_SIGNATURE_ALGORITHM,pe as assertNoNotificationSecrets,D as assertNotificationScope,Y as canonicalNotificationJson,ci as configuredOwnerIds,fr as createDurableScheduler,te as createDurableSnapshotStore,Ei as createDurableWebhookReplayGuard,ui as createGatewayOwnerNotifier,di as createHeldNftPumpLoop,ai as createHeldNftPumpWatchdog,wi as createMemoryWebhookReplayGuard,sr as createNotificationEventSink,gr as createNotificationOutbox,$n as createSignedWebhookDelivery,Si as deliverWebhook,En as groupHeldNftCollections,$e as nextScheduleTime,se as normalizeNotificationEvidence,Le as parseDurableSchedule,Sn as renderHeldNftPumpAlert,Ee as requireNotificationOptIn,Rn as resolveWebhookDestination,li as selectNotificationPlatforms,An as selectNotificationSubscription,bi as verifyWebhookDelivery};