@oracle-agent/oracle 0.35.20 → 0.35.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -1
- package/dist/agent-lifecycle.mjs +3 -0
- package/dist/assets/skills/oracle-desk-product/SKILL.md +23 -17
- package/dist/assets/skills/oracle-mcp-install/SKILL.md +17 -22
- package/dist/assets/skills/protocol-api-key-integration/SKILL.md +14 -11
- package/dist/assets/skills/self-custodial-onchain-execution/SKILL.md +14 -13
- package/dist/assets/skills/trade-loop-circuit-breaker/SKILL.md +1 -1
- package/dist/bin/desk-server.mjs +36 -36
- package/dist/bin/oracle-data-mcp.mjs +17 -17
- package/dist/bin/oracle-mev-arb-shadow.mjs +4 -4
- package/dist/bin/oracle-mev-shadow.mjs +6 -6
- package/dist/bin/oracle-public-server.mjs +5 -5
- package/dist/bin/oracle-route.mjs +11 -11
- package/dist/bin/oracle-scan.mjs +15 -15
- package/dist/bin/oracle.mjs +19 -10
- package/dist/cli/commands/chat.mjs +200 -200
- package/dist/cli/commands/context.mjs +16 -0
- package/dist/cli/commands/doctor.mjs +7 -7
- package/dist/cli/commands/eval.mjs +113 -113
- package/dist/cli/commands/extension-policy.mjs +1 -1
- package/dist/cli/commands/governance-prepare.mjs +5 -0
- package/dist/cli/commands/lifecycle.mjs +17 -0
- package/dist/cli/commands/model.mjs +204 -204
- package/dist/cli/commands/portfolio-risk.mjs +4 -0
- package/dist/cli/commands/position-health.mjs +4 -0
- package/dist/cli/commands/quickstart.mjs +5 -5
- package/dist/cli/commands/safety-intelligence.mjs +4 -0
- package/dist/cli/commands/sign.mjs +1 -1
- package/dist/cli/commands/signer.mjs +22 -22
- package/dist/cli/commands/snipe.mjs +4 -4
- package/dist/cli/commands/swap.mjs +13 -13
- package/dist/cli/commands/tax-lots.mjs +4 -0
- package/dist/cli/commands/venues.mjs +2 -2
- package/dist/context-graph.mjs +3 -0
- package/dist/data/desk-data.mjs +34 -34
- package/dist/data/providers/lp-destination-discovery.mjs +6 -0
- package/dist/data/providers/lp-liquidity-ranker.mjs +1 -0
- package/dist/index.mjs +50 -48
- package/dist/local-signer/anvil-attestation-worker.mjs +1 -1
- package/dist/local-signer/runtime.mjs +1 -1
- package/dist/router/index.mjs +3 -3
- package/dist/router/prepare-bridge.mjs +2 -2
- package/dist/scanner/index.mjs +4 -4
- package/dist/tenant-rbac.mjs +1 -1
- package/dist/workflow-telemetry.mjs +1 -1
- package/package.json +5 -1
- package/public/eval-report.json +2 -2
- package/public/oracle-splash/brand/liquidlaunch.webp +0 -0
- package/public/oracle-splash/brand/markets.webp +0 -0
- package/public/oracle-splash/brand/motion.webp +0 -0
- package/public/oracle-splash/brand/nest.webp +0 -0
- package/public/oracle-splash/brand/outcome.webp +0 -0
- package/public/oracle-splash/brand/silhouette.webp +0 -0
- package/public/oracle-splash/brand/tradexyz.webp +0 -0
- package/public/oracle-splash/index.html +9 -9
- package/server.json +2 -2
- package/dist/assets/skills/oracle-best-execution.md +0 -27
- package/dist/assets/skills/oracle-desk.md +0 -27
- package/dist/assets/skills/oracle-receipts.md +0 -29
package/dist/tenant-rbac.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash as M}from"node:crypto";var f=1,p=1,b=1,H="local-owner",W="local-owner",B=Object.freeze(["owner","operator","agent","viewer"]),K=Object.freeze(["tenant","config","policy","grant","workflow","trade","receipt","audit","telemetry"]),g=Object.freeze({read:"read",create:"create",update:"update",delete:"delete",manage:"manage",prepare:"prepare",cancel:"cancel",export:"export",approve:"approve"}),F=Object.freeze(["owner"]),s=Object.freeze({ALLOW_ROLE_PERMISSION:"allow.role_permission",DENY_MISSING_CONTEXT:"deny.missing_context",DENY_INVALID_CONTEXT:"deny.invalid_context",DENY_INVALID_REQUEST:"deny.invalid_request",DENY_UNKNOWN_RESOURCE:"deny.unknown_resource",DENY_UNKNOWN_ACTION:"deny.unknown_action",DENY_UNBOUND_OBJECT:"deny.unbound_object",DENY_TENANT_MISMATCH:"deny.tenant_mismatch",DENY_RESOURCE_MISMATCH:"deny.resource_mismatch",DENY_ROLE_PERMISSION:"deny.role_permission",DENY_POLICY_NOT_APPROVER:"deny.policy_not_approver"}),j=new Set(B),A=new Set(K),X=new Set(Object.values(g)),D=new Set(["user","service","local-owner"]),k=new Set(["verified-session","service-credential","desktop-session","owner-arm-token","local-owner"]),m=/^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$/,x="tob1",V=new WeakSet,L=Object.freeze({owner:Object.freeze(["tenant:read","tenant:manage","config:read","config:manage","policy:read","policy:manage","grant:read","grant:create","grant:update","grant:delete","grant:manage","workflow:read","workflow:create","workflow:update","workflow:delete","workflow:cancel","workflow:approve","trade:read","trade:prepare","receipt:read","receipt:export","audit:read","audit:export","telemetry:read","telemetry:create","telemetry:export"]),operator:Object.freeze(["tenant:read","config:read","policy:read","grant:read","workflow:read","workflow:create","workflow:update","workflow:cancel","trade:read","trade:prepare","receipt:read","audit:read","telemetry:read","telemetry:create"]),agent:Object.freeze(["tenant:read","config:read","policy:read","grant:read","workflow:read","workflow:create","workflow:update","trade:read","trade:prepare","receipt:read","telemetry:create"]),viewer:Object.freeze(["tenant:read","config:read","grant:read","workflow:read","trade:read","receipt:read","audit:read","telemetry:read"])}),ee=Object.freeze(Object.fromEntries(Object.entries(L).map(([e,t])=>[e,Object.freeze([...t])]))),o=class extends Error{constructor(t,n="invalid-context"){super(t),this.name="TenantContextError",this.code=n}};function N(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&Object.getPrototypeOf(e)===Object.prototype}function E(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(let t of Object.values(e))E(t)}return e}function I(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(I).join(",")}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${I(e[t])}`).join(",")}}`}function S(e){return M("sha256").update(I(e)).digest("hex")}function R(e,t,n){if(!N(e))throw new o(`${n} must be a plain object`);let r=Object.keys(e).filter(a=>!t.has(a));if(r.length)throw new o(`${n} has unknown fields: ${r.sort().join(", ")}`)}function O(e,t){let n=String(e??"").trim();if(!m.test(n))throw new o(`${t} is invalid`);return n}function C(e,t="assignedRoles"){if(!Array.isArray(e)||e.length===0)throw new o(`${t} must contain at least one trusted role`,"missing-role-assignment");let n=[...new Set(e.map(a=>String(a??"").trim()))].sort(),r=n.filter(a=>!j.has(a));if(r.length)throw new o(`${t} contains unknown roles: ${r.join(", ")}`,"unknown-role");return n}function Y(e,t){return e.length===t.length&&e.every((n,r)=>n===t[r])}function J(e){if(!N(e)||e.schemaVersion!==f||!m.test(e.tenantId||"")||typeof e.localCompatibility!="boolean")return!1;let t=e.actor;if(!N(t)||t.schemaVersion!==p||!m.test(t.actorId||"")||!D.has(t.actorType)||!k.has(t.authSource)||!Array.isArray(t.roles)||t.roles.length===0)return!1;let n=[...new Set(t.roles)].sort();return n.every(r=>j.has(r))&&Y(n,t.roles)}function $(e,{assignedRoles:t,localCompatibility:n=!1}={}){if(R(e,new Set(["schemaVersion","tenantId","actor","localCompatibility"]),"tenant claims"),e.schemaVersion!=null&&e.schemaVersion!==f)throw new o("unsupported tenant context schema version","unsupported-version");let r=O(e.tenantId,"tenantId");if(R(e.actor,new Set(["schemaVersion","actorId","actorType","authSource","roles"]),"actor claims"),e.actor.schemaVersion!=null&&e.actor.schemaVersion!==p)throw new o("unsupported actor identity schema version","unsupported-version");let a=C(t);if(e.actor.roles!==void 0){let w;try{w=C(e.actor.roles,"claimed roles")}catch{throw new o("claimed roles do not match the trusted assignment","forged-role")}if(!Y(w,a))throw new o("claimed roles do not match the trusted assignment","forged-role")}if(e.localCompatibility!==void 0&&e.localCompatibility!==n)throw new o("local compatibility may only be set by the trusted boundary","forged-local-compatibility");let c=String(e.actor.actorType??"").trim(),d=String(e.actor.authSource??"").trim();if(!D.has(c))throw new o("actorType is invalid");if(!k.has(d))throw new o("authSource is invalid");let i=E({schemaVersion:f,tenantId:r,actor:{schemaVersion:p,actorId:O(e.actor.actorId,"actorId"),actorType:c,authSource:d,roles:a},localCompatibility:n===!0});return V.add(i),i}function Z(e,t){let n=O(e,"tenantId"),r=O(t,"workflowId");if(n.includes(":")||r.includes(":"))throw new o("stream key parts must not contain ':'","invalid-stream-key");return`${n}:${r}`}function te(e,t){return v(e),Z(e.tenantId,t)}function ne(e,{assignedRoles:t,localCompatibility:n=!1}={}){let r=e?.headers,a=typeof r?.get=="function"?d=>r.get(d):d=>r?.[d]??r?.[String(d).toLowerCase()];a?.("x-oracle-tenant-id"),a?.("x-oracle-tenant"),a?.("x-oracle-role"),a?.("x-oracle-roles");let c=e?.stamped??e?.claims??{};return $({schemaVersion:c.schemaVersion??f,tenantId:c.tenantId,actor:{schemaVersion:c.actor?.schemaVersion??p,actorId:c.actor?.actorId,actorType:c.actor?.actorType,authSource:c.actor?.authSource,roles:void 0},localCompatibility:void 0},{assignedRoles:t,localCompatibility:n})}function re({authSource:e="local-owner"}={}){if(!new Set(["local-owner","desktop-session","owner-arm-token"]).has(e))throw new o("local owner authSource is invalid");return $({schemaVersion:f,tenantId:H,actor:{schemaVersion:p,actorId:W,actorType:"local-owner",authSource:e}},{assignedRoles:["owner"],localCompatibility:!0})}function u(e){return V.has(e)&&J(e)}function v(e){if(!u(e))throw new o("a resolved tenant context is required","unresolved-context");return e}function h(e){return Buffer.from(e,"utf8").toString("base64url")}function _(e,t){if(!e||!/^[A-Za-z0-9_-]+$/.test(e))throw new o(`${t} binding is invalid`,"invalid-object-binding");let n=Buffer.from(e,"base64url").toString("utf8");if(!n||h(n)!==e)throw new o(`${t} binding is non-canonical`,"invalid-object-binding");return n}function z(e){let t=String(e??"").trim();if(!t||t.length>256||/[\u0000-\u001f\u007f]/.test(t))throw new o("objectId is invalid","invalid-object-id");return t}function oe(e,t,n){v(e);let r=String(t??"").trim();if(!A.has(r))throw new o("resource is unknown","unknown-resource");let a=z(n);return`${x}.${h(e.tenantId)}.${h(r)}.${h(a)}`}function G(e){let t=String(e??""),n=t.split(".");if(n.length!==4||n[0]!==x)throw new o("tenant-bound object id required","unbound-object");let r=_(n[1],"tenant"),a=_(n[2],"resource"),c=_(n[3],"object");if(!m.test(r)||!A.has(a))throw new o("tenant-bound object id is invalid","invalid-object-binding");return z(c),E({schemaVersion:1,tenantId:r,resource:a,objectId:c,boundId:t})}function P(e){if(typeof e!="string"||!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(e))return null;let t=Date.parse(e);return Number.isFinite(t)&&new Date(t).toISOString()===e?e:null}function T(e){let t={...e,decisionId:S(e)};return E(t)}function Q({context:e,resource:t,action:n,objectId:r=null,decidedAt:a}={}){let c=P(a),d={schemaVersion:b,recordType:"tenant.access-decision",decidedAt:c,tenantId:u(e)?e.tenantId:null,actor:u(e)?{actorId:e.actor.actorId,actorType:e.actor.actorType,authSource:e.actor.authSource,roles:[...e.actor.roles]}:null,request:{resource:typeof t=="string"?t:null,action:typeof n=="string"?n:null,objectRefHash:r==null?null:S(String(r))}},i=l=>T({...d,allowed:!1,outcome:"deny",reason:l});if(e==null)return i(s.DENY_MISSING_CONTEXT);if(!u(e))return i(s.DENY_INVALID_CONTEXT);if(!c)return i(s.DENY_INVALID_REQUEST);if(!A.has(t))return i(s.DENY_UNKNOWN_RESOURCE);if(!X.has(n))return i(s.DENY_UNKNOWN_ACTION);if(r!=null){let l;try{l=G(r)}catch{return i(s.DENY_UNBOUND_OBJECT)}if(l.tenantId!==e.tenantId)return i(s.DENY_TENANT_MISMATCH);if(l.resource!==t)return i(s.DENY_RESOURCE_MISMATCH)}if(n===g.approve&&!e.actor.roles.some(U=>F.includes(U)))return i(s.DENY_ROLE_PERMISSION);let w=`${t}:${n}`,y=e.actor.roles.some(l=>L[l]?.includes(w));return T({...d,allowed:y,outcome:y?"allow":"deny",reason:y?s.ALLOW_ROLE_PERMISSION:s.DENY_ROLE_PERMISSION})}function ae(e={}){let t=P(e.decidedAt),n=e.context,r=e.resource??"workflow",a=e.objectId??null;return T({schemaVersion:b,recordType:"tenant.access-decision",decidedAt:t,tenantId:u(n)?n.tenantId:null,actor:u(n)?{actorId:n.actor.actorId,actorType:n.actor.actorType,authSource:n.actor.authSource,roles:[...n.actor.roles]}:null,request:{resource:typeof r=="string"?r:null,action:g.approve,objectRefHash:a==null?null:S(String(a))},allowed:!1,outcome:"deny",reason:s.DENY_POLICY_NOT_APPROVER})}function ce(e){let t=Q(e);if(!t.allowed){let n=new o(`tenant access denied: ${t.reason}`,"access-denied");throw n.decision=t,n}return t}function ie(e){if(!N(e)||e.schemaVersion!==b||e.recordType!=="tenant.access-decision"||!Object.isFrozen(e))return!1;let{decisionId:t,...n}=e;return typeof t=="string"&&t===S(n)&&typeof e.allowed=="boolean"&&["allow","deny"].includes(e.outcome)}export{p as ACTOR_IDENTITY_VERSION,W as LOCAL_OWNER_ACTOR_ID,H as LOCAL_OWNER_TENANT_ID,b as TENANT_ACCESS_DECISION_VERSION,g as TENANT_ACTIONS,F as TENANT_APPROVER_ROLES,f as TENANT_CONTEXT_VERSION,s as TENANT_DECISION_REASONS,K as TENANT_RESOURCES,B as TENANT_ROLES,ee as TENANT_ROLE_PERMISSIONS,o as TenantContextError,v as assertResolvedTenantContext,oe as bindTenantObjectId,Z as canonicalTenantStreamKey,re as createLocalOwnerTenantContext,ae as decidePolicyApproval,Q as decideTenantAccess,u as isResolvedTenantContext,ie as isTenantAuditDecision,G as parseTenantObjectId,ce as requireTenantAccess,ne as resolveDispatcherStampedTenantContext,$ as resolveTenantContext,te as tenantStreamKeyFromContext};
|
|
1
|
+
import{createHash as ee}from"node:crypto";var y=1,h=1,j=1,L="local-owner",Y="local-owner",te=Object.freeze(["owner","operator","agent","viewer"]),ne=Object.freeze(["tenant","config","policy","grant","workflow","trade","receipt","audit","telemetry","context","lifecycle"]),D=Object.freeze({read:"read",create:"create",update:"update",delete:"delete",manage:"manage",prepare:"prepare",cancel:"cancel",export:"export",approve:"approve"}),re=Object.freeze(["owner"]),l=Object.freeze({ALLOW_ROLE_PERMISSION:"allow.role_permission",DENY_MISSING_CONTEXT:"deny.missing_context",DENY_INVALID_CONTEXT:"deny.invalid_context",DENY_INVALID_REQUEST:"deny.invalid_request",DENY_UNKNOWN_RESOURCE:"deny.unknown_resource",DENY_UNKNOWN_ACTION:"deny.unknown_action",DENY_UNBOUND_OBJECT:"deny.unbound_object",DENY_TENANT_MISMATCH:"deny.tenant_mismatch",DENY_RESOURCE_MISMATCH:"deny.resource_mismatch",DENY_ROLE_PERMISSION:"deny.role_permission",DENY_POLICY_NOT_APPROVER:"deny.policy_not_approver"}),U=new Set(te),k=new Set(ne),oe=new Set(Object.values(D)),W=new Set(["user","service","local-owner"]),H=new Set(["verified-session","service-credential","desktop-session","owner-arm-token","local-owner"]),N=/^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$/,B="tob1",K=new WeakSet,F=new WeakMap,X=Object.freeze({owner:Object.freeze(["tenant:read","tenant:manage","config:read","config:manage","policy:read","policy:manage","grant:read","grant:create","grant:update","grant:delete","grant:manage","workflow:read","workflow:create","workflow:update","workflow:delete","workflow:cancel","workflow:approve","trade:read","trade:prepare","receipt:read","receipt:export","audit:read","audit:export","telemetry:read","telemetry:create","telemetry:export","context:read","context:create","context:update","context:delete","context:manage","context:export","lifecycle:read","lifecycle:create","lifecycle:update","lifecycle:delete","lifecycle:manage","lifecycle:approve","lifecycle:export"]),operator:Object.freeze(["tenant:read","config:read","policy:read","grant:read","workflow:read","workflow:create","workflow:update","workflow:cancel","trade:read","trade:prepare","receipt:read","audit:read","telemetry:read","telemetry:create","context:read","context:create","context:update","context:delete","lifecycle:read","lifecycle:create","lifecycle:update","lifecycle:manage"]),agent:Object.freeze(["tenant:read","config:read","policy:read","grant:read","workflow:read","workflow:create","workflow:update","trade:read","trade:prepare","receipt:read","telemetry:create","context:read","context:create","context:update","lifecycle:read"]),viewer:Object.freeze(["tenant:read","config:read","grant:read","workflow:read","trade:read","receipt:read","audit:read","telemetry:read","context:read","lifecycle:read"])}),fe=Object.freeze(Object.fromEntries(Object.entries(X).map(([e,t])=>[e,Object.freeze([...t])]))),o=class extends Error{constructor(t,n="invalid-context"){super(t),this.name="TenantContextError",this.code=n}};function m(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&Object.getPrototypeOf(e)===Object.prototype}function _(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(let t of Object.values(e))_(t)}return e}function R(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(R).join(",")}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${R(e[t])}`).join(",")}}`}function g(e){return ee("sha256").update(R(e)).digest("hex")}function P(e,t,n){if(!m(e))throw new o(`${n} must be a plain object`);let r=Object.keys(e).filter(a=>!t.has(a));if(r.length)throw new o(`${n} has unknown fields: ${r.sort().join(", ")}`)}function E(e,t){let n=String(e??"").trim();if(!N.test(n))throw new o(`${t} is invalid`);return n}function M(e,t="assignedRoles"){if(!Array.isArray(e)||e.length===0)throw new o(`${t} must contain at least one trusted role`,"missing-role-assignment");let n=[...new Set(e.map(a=>String(a??"").trim()))].sort(),r=n.filter(a=>!U.has(a));if(r.length)throw new o(`${t} contains unknown roles: ${r.join(", ")}`,"unknown-role");return n}function q(e,t){return e.length===t.length&&e.every((n,r)=>n===t[r])}function ae(e){if(!m(e)||e.schemaVersion!==y||!N.test(e.tenantId||"")||typeof e.localCompatibility!="boolean")return!1;let t=e.actor;if(!m(t)||t.schemaVersion!==h||!N.test(t.actorId||"")||!W.has(t.actorType)||!H.has(t.authSource)||!Array.isArray(t.roles)||t.roles.length===0)return!1;let n=[...new Set(t.roles)].sort();return n.every(r=>U.has(r))&&q(n,t.roles)}function J(e,{assignedTenantId:t,assignedActorId:n,assignedActorType:r,assignedAuthSource:a,assignedRoles:s,assignedContextDomains:c=null,localCompatibility:i=!1}={}){let f=e;if(P(f,new Set(["schemaVersion","tenantId","actor","localCompatibility"]),"tenant claims"),f.schemaVersion!=null&&f.schemaVersion!==y)throw new o("unsupported tenant context schema version","unsupported-version");if(![t,n,r,a].every(d=>d!=null))throw new o("trusted tenant and actor identity assignments are required","missing-trusted-identity");let u=f.actor??{};if(P(u,new Set(["schemaVersion","actorId","actorType","authSource","roles"]),"actor claims"),u.schemaVersion!=null&&u.schemaVersion!==h)throw new o("unsupported actor identity schema version","unsupported-version");let v=E(t,"tenantId"),z=E(n,"actorId"),I=String(r).trim(),T=String(a).trim();if(!W.has(I))throw new o("actorType is invalid");if(!H.has(T))throw new o("authSource is invalid");let b=M(s);if(!Array.isArray(c)&&c!=null)throw new o("assignedContextDomains must be an array","invalid-domain-assignment");let $=c==null?b.includes("owner")?["*"]:[]:[...new Set(c.map(d=>String(d??"").trim()))].sort();if($.some(d=>d!=="*"&&!/^[a-z0-9][a-z0-9._-]{0,95}$/.test(d)))throw new o("assignedContextDomains contains an invalid domain","invalid-domain-assignment");if(u.roles!==void 0){let d;try{d=M(u.roles,"claimed roles")}catch{throw new o("claimed roles do not match the trusted assignment","forged-role")}if(!q(d,b))throw new o("claimed roles do not match the trusted assignment","forged-role")}if(f.localCompatibility!==void 0&&f.localCompatibility!==i)throw new o("local compatibility may only be set by the trusted boundary","forged-local-compatibility");if([[f.tenantId,v],[u.actorId,z],[u.actorType,I],[u.authSource,T]].some(([d,Q])=>d!==void 0&&String(d).trim()!==Q))throw new o("claimed identity does not match the trusted assignment","forged-identity");let A=_({schemaVersion:y,tenantId:v,actor:{schemaVersion:h,actorId:z,actorType:I,authSource:T,roles:b},localCompatibility:i===!0});return K.add(A),F.set(A,Object.freeze($)),A}function ie(e,t){V(e);let n=String(t??"").trim();if(!/^[a-z0-9][a-z0-9._-]{0,95}$/.test(n))return!1;let r=F.get(e)||[];return r.includes("*")||r.includes(n)}function pe(e,t){if(!ie(e,t))throw new o("context domain access denied","domain-access-denied");return t}function ce(e,t){let n=E(e,"tenantId"),r=E(t,"workflowId");if(n.includes(":")||r.includes(":"))throw new o("stream key parts must not contain ':'","invalid-stream-key");return`${n}:${r}`}function we(e,t){return V(e),ce(e.tenantId,t)}function me(e,{assignedRoles:t,assignedContextDomains:n=null,localCompatibility:r=!1}={}){let a=e?.headers,s=typeof a?.get=="function"?i=>a.get(i):i=>a?.[i]??a?.[String(i).toLowerCase()];s?.("x-oracle-tenant-id"),s?.("x-oracle-tenant"),s?.("x-oracle-role"),s?.("x-oracle-roles");let c=e?.stamped;if(!m(c)||!m(c.actor))throw new o("a trusted dispatcher identity stamp is required","missing-trusted-identity");return J({schemaVersion:c.schemaVersion??y,actor:{schemaVersion:c.actor.schemaVersion??h}},{assignedTenantId:c.tenantId,assignedActorId:c.actor.actorId,assignedActorType:c.actor.actorType,assignedAuthSource:c.actor.authSource,assignedRoles:t,assignedContextDomains:n,localCompatibility:r})}function ye({authSource:e="local-owner"}={}){if(!new Set(["local-owner","desktop-session","owner-arm-token"]).has(e))throw new o("local owner authSource is invalid");return J({schemaVersion:y,tenantId:L,actor:{schemaVersion:h,actorId:Y,actorType:"local-owner",authSource:e}},{assignedTenantId:L,assignedActorId:Y,assignedActorType:"local-owner",assignedAuthSource:e,assignedRoles:["owner"],localCompatibility:!0})}function w(e){return K.has(e)&&ae(e)}function V(e){if(!w(e))throw new o("a resolved tenant context is required","unresolved-context");return e}function S(e){return Buffer.from(e,"utf8").toString("base64url")}function x(e,t){if(!e||!/^[A-Za-z0-9_-]+$/.test(e))throw new o(`${t} binding is invalid`,"invalid-object-binding");let n=Buffer.from(e,"base64url").toString("utf8");if(!n||S(n)!==e)throw new o(`${t} binding is non-canonical`,"invalid-object-binding");return n}function Z(e){let t=String(e??"").trim();if(!t||t.length>256||/[\u0000-\u001f\u007f]/.test(t))throw new o("objectId is invalid","invalid-object-id");return t}function he(e,t,n){V(e);let r=String(t??"").trim();if(!k.has(r))throw new o("resource is unknown","unknown-resource");let a=Z(n);return`${B}.${S(e.tenantId)}.${S(r)}.${S(a)}`}function se(e){let t=String(e??""),n=t.split(".");if(n.length!==4||n[0]!==B)throw new o("tenant-bound object id required","unbound-object");let r=x(n[1],"tenant"),a=x(n[2],"resource"),s=x(n[3],"object");if(!N.test(r)||!k.has(a))throw new o("tenant-bound object id is invalid","invalid-object-binding");return Z(s),_({schemaVersion:1,tenantId:r,resource:a,objectId:s,boundId:t})}function G(e){if(typeof e!="string"||!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(e))return null;let t=Date.parse(e);return Number.isFinite(t)&&new Date(t).toISOString()===e?e:null}function C(e){let t={...e,decisionId:g(e)};return _(t)}function de({context:e,resource:t,action:n,objectId:r=null,decidedAt:a}={}){let s=G(a),c={schemaVersion:j,recordType:"tenant.access-decision",decidedAt:s,tenantId:w(e)?e.tenantId:null,actor:w(e)?{actorId:e.actor.actorId,actorType:e.actor.actorType,authSource:e.actor.authSource,roles:[...e.actor.roles]}:null,request:{resource:typeof t=="string"?t:null,action:typeof n=="string"?n:null,objectRefHash:r==null?null:g(String(r))}},i=p=>C({...c,allowed:!1,outcome:"deny",reason:p});if(e==null)return i(l.DENY_MISSING_CONTEXT);if(!w(e))return i(l.DENY_INVALID_CONTEXT);if(!s)return i(l.DENY_INVALID_REQUEST);if(!k.has(t))return i(l.DENY_UNKNOWN_RESOURCE);if(!oe.has(n))return i(l.DENY_UNKNOWN_ACTION);if(r!=null){let p;try{p=se(r)}catch{return i(l.DENY_UNBOUND_OBJECT)}if(p.tenantId!==e.tenantId)return i(l.DENY_TENANT_MISMATCH);if(p.resource!==t)return i(l.DENY_RESOURCE_MISMATCH)}if(n===D.approve&&!e.actor.roles.some(u=>re.includes(u)))return i(l.DENY_ROLE_PERMISSION);let f=`${t}:${n}`,O=e.actor.roles.some(p=>X[p]?.includes(f));return C({...c,allowed:O,outcome:O?"allow":"deny",reason:O?l.ALLOW_ROLE_PERMISSION:l.DENY_ROLE_PERMISSION})}function Oe(e={}){let t=G(e.decidedAt),n=e.context,r=e.resource??"workflow",a=e.objectId??null;return C({schemaVersion:j,recordType:"tenant.access-decision",decidedAt:t,tenantId:w(n)?n.tenantId:null,actor:w(n)?{actorId:n.actor.actorId,actorType:n.actor.actorType,authSource:n.actor.authSource,roles:[...n.actor.roles]}:null,request:{resource:typeof r=="string"?r:null,action:D.approve,objectRefHash:a==null?null:g(String(a))},allowed:!1,outcome:"deny",reason:l.DENY_POLICY_NOT_APPROVER})}function Se(e){let t=de(e);if(!t.allowed){let n=new o(`tenant access denied: ${t.reason}`,"access-denied");throw n.decision=t,n}return t}function Ne(e){if(!m(e)||e.schemaVersion!==j||e.recordType!=="tenant.access-decision"||!Object.isFrozen(e))return!1;let{decisionId:t,...n}=e;return typeof t=="string"&&t===g(n)&&typeof e.allowed=="boolean"&&["allow","deny"].includes(e.outcome)}export{h as ACTOR_IDENTITY_VERSION,Y as LOCAL_OWNER_ACTOR_ID,L as LOCAL_OWNER_TENANT_ID,j as TENANT_ACCESS_DECISION_VERSION,D as TENANT_ACTIONS,re as TENANT_APPROVER_ROLES,y as TENANT_CONTEXT_VERSION,l as TENANT_DECISION_REASONS,ne as TENANT_RESOURCES,te as TENANT_ROLES,fe as TENANT_ROLE_PERMISSIONS,o as TenantContextError,V as assertResolvedTenantContext,he as bindTenantObjectId,ie as canAccessContextDomain,ce as canonicalTenantStreamKey,ye as createLocalOwnerTenantContext,Oe as decidePolicyApproval,de as decideTenantAccess,w as isResolvedTenantContext,Ne as isTenantAuditDecision,se as parseTenantObjectId,pe as requireContextDomainAccess,Se as requireTenantAccess,me as resolveDispatcherStampedTenantContext,J as resolveTenantContext,we as tenantStreamKeyFromContext};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash as ee,randomBytes as te}from"node:crypto";var X=Object.freeze(["owner","operator","agent","viewer"]),J=Object.freeze(["tenant","config","policy","grant","workflow","trade","receipt","audit","telemetry"]),G=Object.freeze({read:"read",create:"create",update:"update",delete:"delete",manage:"manage",prepare:"prepare",cancel:"cancel",export:"export",approve:"approve"}),Oe=Object.freeze(["owner"]),be=Object.freeze({ALLOW_ROLE_PERMISSION:"allow.role_permission",DENY_MISSING_CONTEXT:"deny.missing_context",DENY_INVALID_CONTEXT:"deny.invalid_context",DENY_INVALID_REQUEST:"deny.invalid_request",DENY_UNKNOWN_RESOURCE:"deny.unknown_resource",DENY_UNKNOWN_ACTION:"deny.unknown_action",DENY_UNBOUND_OBJECT:"deny.unbound_object",DENY_TENANT_MISMATCH:"deny.tenant_mismatch",DENY_RESOURCE_MISMATCH:"deny.resource_mismatch",DENY_ROLE_PERMISSION:"deny.role_permission",DENY_POLICY_NOT_APPROVER:"deny.policy_not_approver"}),Te=new Set(X),Ee=new Set(J),_e=new Set(Object.values(G));var q=/^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$/;var Q=Object.freeze({owner:Object.freeze(["tenant:read","tenant:manage","config:read","config:manage","policy:read","policy:manage","grant:read","grant:create","grant:update","grant:delete","grant:manage","workflow:read","workflow:create","workflow:update","workflow:delete","workflow:cancel","workflow:approve","trade:read","trade:prepare","receipt:read","receipt:export","audit:read","audit:export","telemetry:read","telemetry:create","telemetry:export"]),operator:Object.freeze(["tenant:read","config:read","policy:read","grant:read","workflow:read","workflow:create","workflow:update","workflow:cancel","trade:read","trade:prepare","receipt:read","audit:read","telemetry:read","telemetry:create"]),agent:Object.freeze(["tenant:read","config:read","policy:read","grant:read","workflow:read","workflow:create","workflow:update","trade:read","trade:prepare","receipt:read","telemetry:create"]),viewer:Object.freeze(["tenant:read","config:read","grant:read","workflow:read","trade:read","receipt:read","audit:read","telemetry:read"])}),Ae=Object.freeze(Object.fromEntries(Object.entries(Q).map(([e,t])=>[e,Object.freeze([...t])]))),h=class extends Error{constructor(t,n="invalid-context"){super(t),this.name="TenantContextError",this.code=n}};function k(e,t){let n=String(e??"").trim();if(!q.test(n))throw new h(`${t} is invalid`);return n}function C(e,t){let n=k(e,"tenantId"),r=k(t,"workflowId");if(n.includes(":")||r.includes(":"))throw new h("stream key parts must not contain ':'","invalid-stream-key");return`${n}:${r}`}var L=1,$=1,ne=Object.freeze(["succeeded","denied","invalid","failed","cancelled","timed_out","unavailable","skipped"]),re=Object.freeze(["workflow","task","intent","plan","run","event","eval"]),S=Object.freeze(["taskId","intentId","planId","runId","eventId"]);function I(e,t){return C(e,t)}var p=Object.freeze({maxAttributes:24,maxKeyLength:48,maxStringLength:256,maxArrayLength:8}),D=new Set(ne),oe=new Set(re),ae=new Set(S),ie=/^[0-9a-f]{32}$/,j=/^[0-9a-f]{16}$/,se=/^[0-9a-f]{64}$/,v=new WeakSet,ce=/^[A-Za-z0-9][A-Za-z0-9._:/-]{0,95}$/,V=/^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,127}$/,de=/^[A-Za-z][A-Za-z0-9_.-]*$/,le=Object.freeze(["authorization","bearer","cookie","credential","password","passphrase","secret","token","privatekey","privkey","seed","mnemonic","keystore","signature","prompt","systemmessage","usermessage","assistantmessage","rawtransaction","signedtransaction","serializedtransaction","transactionbytes","calldata","callbytes","inputdata"]),ue=/(?:^|\s)Bearer\s+\S+|-----BEGIN [A-Z ]*PRIVATE KEY-----|\bxprv[0-9A-Za-z]{20,}\b|\bsk-[A-Za-z0-9_-]{16,}\b|[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{16,}/i,fe=/(?:0x)?[0-9a-fA-F]{66,}/,pe=/[A-Za-z0-9+/=_-]{96,}/,a=class extends Error{constructor(t,n="invalid-telemetry"){super(t),this.name="WorkflowTelemetryError",this.code=n}};function w(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&Object.getPrototypeOf(e)===Object.prototype}function u(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(let t of Object.values(e))u(t)}return e}function E(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(E).join(",")}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${E(e[t])}`).join(",")}}`}function K(e){return ee("sha256").update(E(e)).digest("hex")}function R(e,t,n){let r=n?n(e,t):te(e).toString("hex");return String(r??"").trim().toLowerCase()}function O(e={}){if(e==null)return{};if(!w(e))throw new a("correlation must be a plain object");let t=Object.keys(e).filter(r=>!ae.has(r));if(t.length)throw new a(`unknown correlation fields: ${t.sort().join(", ")}`);let n={};for(let r of S){if(e[r]==null)continue;let o=String(e[r]).trim();if(!V.test(o))throw new a(`${r} is invalid`);n[r]=o}return n}function f(e){if(!w(e)||e.schemaVersion!==L)throw new a("trace context version is invalid","invalid-trace");if(!ie.test(e.traceId||"")||!j.test(e.spanId||"")||/^0+$/.test(e.traceId)||/^0+$/.test(e.spanId))throw new a("trace or span id is invalid","invalid-trace");if(e.parentSpanId!==null&&!j.test(e.parentSpanId||""))throw new a("parent span id is invalid","invalid-trace");if(typeof e.sampled!="boolean")throw new a("sampled must be boolean","invalid-trace");return O(e.correlation),e}function _({traceId:e,spanId:t,parentSpanId:n=null,sampled:r=!1,correlation:o={}}={},{idFactory:s}={}){let i=e==null?R(16,"trace",s):String(e).trim().toLowerCase(),c=t==null?R(8,"span",s):String(t).trim().toLowerCase(),l=n==null?null:String(n).trim().toLowerCase(),d=u({schemaVersion:L,traceId:i,spanId:c,parentSpanId:l,sampled:r===!0,correlation:O(o)});return f(d)}var je=_;function Re(e,{spanId:t,correlation:n={}}={},{idFactory:r}={}){f(e);let o=O(n),s={...e.correlation};for(let[i,c]of Object.entries(o)){if(s[i]!=null&&s[i]!==c)throw new a(`correlation ${i} cannot change inside a trace`,"correlation-conflict");s[i]=c}return _({traceId:e.traceId,spanId:t,parentSpanId:e.spanId,sampled:e.sampled,correlation:s},{idFactory:r})}function we(e){return f(e),`00-${e.traceId}-${e.spanId}-${e.sampled?"01":"00"}`}function me(e,{correlation:t={}}={}){let n=/^00-([0-9a-f]{32})-([0-9a-f]{16})-(0[01])$/.exec(String(e??"").trim().toLowerCase());if(!n||/^0+$/.test(n[1])||/^0+$/.test(n[2]))throw new a("traceparent is invalid","invalid-traceparent");return _({traceId:n[1],spanId:n[2],sampled:n[3]==="01",correlation:t})}var Y=Object.freeze({taskId:"x-oracle-task-id",intentId:"x-oracle-intent-id",planId:"x-oracle-plan-id",runId:"x-oracle-run-id",eventId:"x-oracle-event-id"});function x(e,t){if(e?.get&&typeof e.get=="function")return e.get(t);if(!e||typeof e!="object")return null;let n=t.toLowerCase();for(let[r,o]of Object.entries(e))if(r.toLowerCase()===n)return o;return null}function xe(e,t={}){f(e);let n={};n.traceparent=we(e);for(let[r,o]of Object.entries(Y))e.correlation[r]!=null&&(n[o]=e.correlation[r]);return u(n)}function ze(e){let t={};for(let[n,r]of Object.entries(Y)){let o=x(e,r);o!=null&&String(o).trim()&&(t[n]=String(o).trim())}return me(x(e,"traceparent"),{correlation:t})}function z(e){let t=String(e).replace(/[^a-z0-9]/gi,"").toLowerCase();return le.some(n=>t.includes(n))}function ye(e){return ue.test(e)||fe.test(e)||pe.test(e)?{value:"[REDACTED]",redacted:!0,truncated:!1}:e.length>p.maxStringLength?{value:`${e.slice(0,p.maxStringLength-1)}\u2026`,redacted:!1,truncated:!0}:{value:e,redacted:!1,truncated:!1}}function P(e){if(typeof e=="string")return ye(e);if(typeof e=="boolean")return{value:e,redacted:!1,truncated:!1};if(typeof e=="number"&&Number.isFinite(e))return{value:e,redacted:!1,truncated:!1};if(Array.isArray(e)){let t=e.slice(0,p.maxArrayLength),n=[],r=!1,o=e.length>t.length;for(let s of t){if(!["string","boolean","number"].includes(typeof s))return null;let i=P(s);if(!i)return null;n.push(i.value),r||=i.redacted,o||=i.truncated}return{value:n,redacted:r,truncated:o}}return null}function he(e={}){if(!w(e))throw new a("telemetry attributes must be a plain object");let t={},n=0,r=0,o=0,s=Object.keys(e).sort();for(let i of s){if(Object.keys(t).length>=p.maxAttributes){r+=1;continue}if(i.length>p.maxKeyLength||!de.test(i)||z(i)){r+=1,z(i)&&(n+=1);continue}let c=P(e[i]);if(!c){r+=1;continue}t[i]=c.value,c.redacted&&(n+=1),c.truncated&&(o+=1)}return u({attributes:t,redactedCount:n,droppedCount:r,truncatedCount:o})}function g(e,t){if(!Number.isSafeInteger(e)||e<0)throw new a(`${t} must be a non-negative integer milliseconds value`);return e}function M(e){if(e==null)return null;let t=String(e).trim();if(!/^[a-z0-9][a-z0-9._-]{0,63}$/.test(t))throw new a("outcomeCode is invalid");return t}function Ie({streamKey:e,tenantId:t,workflowId:n,sourceEvent:r}){let o=e??r?.streamKey??null,s=t??r?.tenantId??null,i=n??r?.workflowId??null;if(o!=null){let c=String(o).trim();if(s!=null&&i!=null){let l=I(s,i);if(c!==l)throw new a("streamKey must equal tenantId:workflowId","invalid-stream-key");return l}if(!/^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}:[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$/.test(c)||c.split(":").length!==2)throw new a("streamKey must be tenantId:workflowId","invalid-stream-key");return c}return s!=null&&i!=null?I(s,i):null}function U({trace:e,name:t,kind:n,diagnosticOutcome:r=null,outcome:o=null,outcomeCode:s=null,startedAt:i,endedAt:c,attributes:l,authority:d,sourceEvent:m=null,streamKey:F=null,tenantId:W=null,workflowId:Z=null}){f(e);let A=String(t??"").trim();if(!ce.test(A))throw new a("workflow telemetry name is invalid");if(!oe.has(n))throw new a("workflow telemetry kind is invalid");let H=d==="ledger_projection"?o:r;if(!D.has(H))throw new a("workflow telemetry outcome is invalid");let b=g(i,"startedAt"),T=g(c,"endedAt");if(T<b)throw new a("endedAt must not be before startedAt");let y=he(l),B=Ie({streamKey:F,tenantId:W,workflowId:Z,sourceEvent:m}),N={schemaVersion:$,recordType:"oracle.workflow.telemetry",authority:d,streamKey:B,trace:{traceId:e.traceId,spanId:e.spanId,parentSpanId:e.parentSpanId,sampled:e.sampled},correlation:{...e.correlation},name:A,kind:n,...d==="ledger_projection"?{outcome:o,sourceEvent:{...m}}:{diagnosticOutcome:r},outcomeCode:M(s),startedAt:b,endedAt:T,durationMs:T-b,attributes:{...y.attributes},attributePolicy:{redactedCount:y.redactedCount,droppedCount:y.droppedCount,truncatedCount:y.truncatedCount}};return u({...N,recordId:K(N)})}function ge({trace:e,name:t,kind:n="workflow",outcome:r,outcomeCode:o=null,startedAt:s,endedAt:i,attributes:c={},tenantId:l=null,workflowId:d=null,streamKey:m=null}={}){return U({trace:e,name:t,kind:n,diagnosticOutcome:r,outcomeCode:o,startedAt:s,endedAt:i,attributes:c,authority:"diagnostic",tenantId:l,workflowId:d,streamKey:m})}function Le(e,{validateLedgerEvent:t}={}){if(!w(e))throw new a("ledger event must be a plain object","invalid-ledger-event");if(typeof t!="function"||t(e)!==!0)throw new a("ledger event validation failed","invalid-ledger-event");let n=String(e.eventId??"").trim(),r=String(e.eventHash??e.hash??"").trim().toLowerCase();if(!V.test(n)||!se.test(r))throw new a("ledger event id or hash is invalid","invalid-ledger-event");let o=O(e.correlation);for(let d of S)if(o[d]==null)throw new a(`ledger event correlation requires ${d}`,"invalid-ledger-event");if(o.eventId!==n)throw new a("ledger eventId does not match correlation","invalid-ledger-event");if(!D.has(e.outcome))throw new a("ledger event outcome is invalid","invalid-ledger-event");let s=e.tenantId==null?null:String(e.tenantId).trim(),i=e.workflowId==null?null:String(e.workflowId).trim(),c=null;if(s&&i){if(c=I(s,i),e.streamKey!=null&&String(e.streamKey).trim()!==c)throw new a("ledger streamKey must equal tenantId:workflowId","invalid-stream-key")}else if(e.streamKey!=null){let d=String(e.streamKey).split(":");if(d.length!==2)throw new a("ledger streamKey must be tenantId:workflowId","invalid-stream-key");c=I(d[0],d[1])}let l=u({eventId:n,eventHash:r,correlation:o,outcome:e.outcome,outcomeCode:M(e.outcomeCode),startedAt:g(e.startedAt,"ledger event startedAt"),endedAt:g(e.endedAt,"ledger event endedAt"),tenantId:s,workflowId:i,streamKey:c});if(l.endedAt<l.startedAt)throw new a("ledger event endedAt must not be before startedAt","invalid-ledger-event");return v.add(l),l}function $e({sourceEvent:e,trace:t,name:n,kind:r="workflow",attributes:o={}}={}){if(!v.has(e))throw new a("a validated ledger source event is required","unvalidated-ledger-event");f(t);for(let s of S)if(t.correlation[s]!==e.correlation[s])throw new a(`trace correlation ${s} does not match ledger event`,"ledger-correlation-mismatch");return U({trace:t,name:n,kind:r,outcome:e.outcome,outcomeCode:e.outcomeCode,startedAt:e.startedAt,endedAt:e.endedAt,attributes:o,authority:"ledger_projection",sourceEvent:{eventId:e.eventId,eventHash:e.eventHash},tenantId:e.tenantId,workflowId:e.workflowId,streamKey:e.streamKey})}function Se(e){if(!w(e)||!Object.isFrozen(e)||e.schemaVersion!==$||e.recordType!=="oracle.workflow.telemetry")return!1;let{recordId:t,...n}=e;return typeof t=="string"&&t===K(n)}function De({exporter:e=null}={}){if(e!=null&&typeof e!="function"&&typeof e?.export!="function")throw new a("exporter must be a function or expose export(record)");let t=typeof e=="function"?e:e?.export?.bind(e);return Object.freeze({exporterConfigured:!!t,defaultExporter:"none",async emit(n){let r=Se(n)?n:ge(n);if(!t)return Object.freeze({record:r,exported:!1,exporterFailed:!1});try{return await t(r),Object.freeze({record:r,exported:!0,exporterFailed:!1})}catch{return Object.freeze({record:r,exported:!1,exporterFailed:!0})}}})}export{S as CORRELATION_KEYS,p as TELEMETRY_ATTRIBUTE_LIMITS,L as TRACE_CONTEXT_VERSION,re as WORKFLOW_KINDS,ne as WORKFLOW_OUTCOMES,$ as WORKFLOW_TELEMETRY_VERSION,a as WorkflowTelemetryError,Re as createChildTraceContext,je as createRootTraceContext,_ as createTraceContext,De as createWorkflowTelemetry,ge as createWorkflowTelemetryRecord,ze as extractTraceContext,we as formatTraceparent,xe as injectTraceContext,Se as isWorkflowTelemetryRecord,me as parseTraceparent,$e as projectWorkflowTelemetryFromLedgerEvent,he as sanitizeTelemetryAttributes,Le as validateWorkflowTelemetrySourceEvent,I as workflowTelemetryStreamKey};
|
|
1
|
+
import{createHash as ee,randomBytes as te}from"node:crypto";var q=Object.freeze(["owner","operator","agent","viewer"]),X=Object.freeze(["tenant","config","policy","grant","workflow","trade","receipt","audit","telemetry","context","lifecycle"]),J=Object.freeze({read:"read",create:"create",update:"update",delete:"delete",manage:"manage",prepare:"prepare",cancel:"cancel",export:"export",approve:"approve"}),Oe=Object.freeze(["owner"]),be=Object.freeze({ALLOW_ROLE_PERMISSION:"allow.role_permission",DENY_MISSING_CONTEXT:"deny.missing_context",DENY_INVALID_CONTEXT:"deny.invalid_context",DENY_INVALID_REQUEST:"deny.invalid_request",DENY_UNKNOWN_RESOURCE:"deny.unknown_resource",DENY_UNKNOWN_ACTION:"deny.unknown_action",DENY_UNBOUND_OBJECT:"deny.unbound_object",DENY_TENANT_MISMATCH:"deny.tenant_mismatch",DENY_RESOURCE_MISMATCH:"deny.resource_mismatch",DENY_ROLE_PERMISSION:"deny.role_permission",DENY_POLICY_NOT_APPROVER:"deny.policy_not_approver"}),Ae=new Set(q),Te=new Set(X),_e=new Set(Object.values(J));var G=/^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$/;var Q=Object.freeze({owner:Object.freeze(["tenant:read","tenant:manage","config:read","config:manage","policy:read","policy:manage","grant:read","grant:create","grant:update","grant:delete","grant:manage","workflow:read","workflow:create","workflow:update","workflow:delete","workflow:cancel","workflow:approve","trade:read","trade:prepare","receipt:read","receipt:export","audit:read","audit:export","telemetry:read","telemetry:create","telemetry:export","context:read","context:create","context:update","context:delete","context:manage","context:export","lifecycle:read","lifecycle:create","lifecycle:update","lifecycle:delete","lifecycle:manage","lifecycle:approve","lifecycle:export"]),operator:Object.freeze(["tenant:read","config:read","policy:read","grant:read","workflow:read","workflow:create","workflow:update","workflow:cancel","trade:read","trade:prepare","receipt:read","audit:read","telemetry:read","telemetry:create","context:read","context:create","context:update","context:delete","lifecycle:read","lifecycle:create","lifecycle:update","lifecycle:manage"]),agent:Object.freeze(["tenant:read","config:read","policy:read","grant:read","workflow:read","workflow:create","workflow:update","trade:read","trade:prepare","receipt:read","telemetry:create","context:read","context:create","context:update","lifecycle:read"]),viewer:Object.freeze(["tenant:read","config:read","grant:read","workflow:read","trade:read","receipt:read","audit:read","telemetry:read","context:read","lifecycle:read"])}),Ee=Object.freeze(Object.fromEntries(Object.entries(Q).map(([e,t])=>[e,Object.freeze([...t])]))),h=class extends Error{constructor(t,n="invalid-context"){super(t),this.name="TenantContextError",this.code=n}};function x(e,t){let n=String(e??"").trim();if(!G.test(n))throw new h(`${t} is invalid`);return n}function C(e,t){let n=x(e,"tenantId"),r=x(t,"workflowId");if(n.includes(":")||r.includes(":"))throw new h("stream key parts must not contain ':'","invalid-stream-key");return`${n}:${r}`}var L=1,$=1,ne=Object.freeze(["succeeded","denied","invalid","failed","cancelled","timed_out","unavailable","skipped"]),re=Object.freeze(["workflow","task","intent","plan","run","event","eval"]),S=Object.freeze(["taskId","intentId","planId","runId","eventId"]);function g(e,t){return C(e,t)}var p=Object.freeze({maxAttributes:24,maxKeyLength:48,maxStringLength:256,maxArrayLength:8}),v=new Set(ne),oe=new Set(re),ae=new Set(S),ie=/^[0-9a-f]{32}$/,k=/^[0-9a-f]{16}$/,se=/^[0-9a-f]{64}$/,D=new WeakSet,ce=/^[A-Za-z0-9][A-Za-z0-9._:/-]{0,95}$/,V=/^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,127}$/,de=/^[A-Za-z][A-Za-z0-9_.-]*$/,le=Object.freeze(["authorization","bearer","cookie","credential","password","passphrase","secret","token","privatekey","privkey","seed","mnemonic","keystore","signature","prompt","systemmessage","usermessage","assistantmessage","rawtransaction","signedtransaction","serializedtransaction","transactionbytes","calldata","callbytes","inputdata"]),ue=/(?:^|\s)Bearer\s+\S+|-----BEGIN [A-Z ]*PRIVATE KEY-----|\bxprv[0-9A-Za-z]{20,}\b|\bsk-[A-Za-z0-9_-]{16,}\b|[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{16,}/i,fe=/(?:0x)?[0-9a-fA-F]{66,}/,pe=/[A-Za-z0-9+/=_-]{96,}/,a=class extends Error{constructor(t,n="invalid-telemetry"){super(t),this.name="WorkflowTelemetryError",this.code=n}};function w(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&Object.getPrototypeOf(e)===Object.prototype}function u(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(let t of Object.values(e))u(t)}return e}function T(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(T).join(",")}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${T(e[t])}`).join(",")}}`}function K(e){return ee("sha256").update(T(e)).digest("hex")}function j(e,t,n){let r=n?n(e,t):te(e).toString("hex");return String(r??"").trim().toLowerCase()}function O(e={}){if(e==null)return{};if(!w(e))throw new a("correlation must be a plain object");let t=Object.keys(e).filter(r=>!ae.has(r));if(t.length)throw new a(`unknown correlation fields: ${t.sort().join(", ")}`);let n={};for(let r of S){if(e[r]==null)continue;let o=String(e[r]).trim();if(!V.test(o))throw new a(`${r} is invalid`);n[r]=o}return n}function f(e){if(!w(e)||e.schemaVersion!==L)throw new a("trace context version is invalid","invalid-trace");if(!ie.test(e.traceId||"")||!k.test(e.spanId||"")||/^0+$/.test(e.traceId)||/^0+$/.test(e.spanId))throw new a("trace or span id is invalid","invalid-trace");if(e.parentSpanId!==null&&!k.test(e.parentSpanId||""))throw new a("parent span id is invalid","invalid-trace");if(typeof e.sampled!="boolean")throw new a("sampled must be boolean","invalid-trace");return O(e.correlation),e}function _({traceId:e,spanId:t,parentSpanId:n=null,sampled:r=!1,correlation:o={}}={},{idFactory:s}={}){let i=e==null?j(16,"trace",s):String(e).trim().toLowerCase(),c=t==null?j(8,"span",s):String(t).trim().toLowerCase(),l=n==null?null:String(n).trim().toLowerCase(),d=u({schemaVersion:L,traceId:i,spanId:c,parentSpanId:l,sampled:r===!0,correlation:O(o)});return f(d)}var ke=_;function je(e,{spanId:t,correlation:n={}}={},{idFactory:r}={}){f(e);let o=O(n),s={...e.correlation};for(let[i,c]of Object.entries(o)){if(s[i]!=null&&s[i]!==c)throw new a(`correlation ${i} cannot change inside a trace`,"correlation-conflict");s[i]=c}return _({traceId:e.traceId,spanId:t,parentSpanId:e.spanId,sampled:e.sampled,correlation:s},{idFactory:r})}function we(e){return f(e),`00-${e.traceId}-${e.spanId}-${e.sampled?"01":"00"}`}function me(e,{correlation:t={}}={}){let n=/^00-([0-9a-f]{32})-([0-9a-f]{16})-(0[01])$/.exec(String(e??"").trim().toLowerCase());if(!n||/^0+$/.test(n[1])||/^0+$/.test(n[2]))throw new a("traceparent is invalid","invalid-traceparent");return _({traceId:n[1],spanId:n[2],sampled:n[3]==="01",correlation:t})}var Y=Object.freeze({taskId:"x-oracle-task-id",intentId:"x-oracle-intent-id",planId:"x-oracle-plan-id",runId:"x-oracle-run-id",eventId:"x-oracle-event-id"});function R(e,t){if(e?.get&&typeof e.get=="function")return e.get(t);if(!e||typeof e!="object")return null;let n=t.toLowerCase();for(let[r,o]of Object.entries(e))if(r.toLowerCase()===n)return o;return null}function Re(e,t={}){f(e);let n={};n.traceparent=we(e);for(let[r,o]of Object.entries(Y))e.correlation[r]!=null&&(n[o]=e.correlation[r]);return u(n)}function ze(e){let t={};for(let[n,r]of Object.entries(Y)){let o=R(e,r);o!=null&&String(o).trim()&&(t[n]=String(o).trim())}return me(R(e,"traceparent"),{correlation:t})}function z(e){let t=String(e).replace(/[^a-z0-9]/gi,"").toLowerCase();return le.some(n=>t.includes(n))}function ye(e){return ue.test(e)||fe.test(e)||pe.test(e)?{value:"[REDACTED]",redacted:!0,truncated:!1}:e.length>p.maxStringLength?{value:`${e.slice(0,p.maxStringLength-1)}\u2026`,redacted:!1,truncated:!0}:{value:e,redacted:!1,truncated:!1}}function P(e){if(typeof e=="string")return ye(e);if(typeof e=="boolean")return{value:e,redacted:!1,truncated:!1};if(typeof e=="number"&&Number.isFinite(e))return{value:e,redacted:!1,truncated:!1};if(Array.isArray(e)){let t=e.slice(0,p.maxArrayLength),n=[],r=!1,o=e.length>t.length;for(let s of t){if(!["string","boolean","number"].includes(typeof s))return null;let i=P(s);if(!i)return null;n.push(i.value),r||=i.redacted,o||=i.truncated}return{value:n,redacted:r,truncated:o}}return null}function he(e={}){if(!w(e))throw new a("telemetry attributes must be a plain object");let t={},n=0,r=0,o=0,s=Object.keys(e).sort();for(let i of s){if(Object.keys(t).length>=p.maxAttributes){r+=1;continue}if(i.length>p.maxKeyLength||!de.test(i)||z(i)){r+=1,z(i)&&(n+=1);continue}let c=P(e[i]);if(!c){r+=1;continue}t[i]=c.value,c.redacted&&(n+=1),c.truncated&&(o+=1)}return u({attributes:t,redactedCount:n,droppedCount:r,truncatedCount:o})}function I(e,t){if(!Number.isSafeInteger(e)||e<0)throw new a(`${t} must be a non-negative integer milliseconds value`);return e}function M(e){if(e==null)return null;let t=String(e).trim();if(!/^[a-z0-9][a-z0-9._-]{0,63}$/.test(t))throw new a("outcomeCode is invalid");return t}function ge({streamKey:e,tenantId:t,workflowId:n,sourceEvent:r}){let o=e??r?.streamKey??null,s=t??r?.tenantId??null,i=n??r?.workflowId??null;if(o!=null){let c=String(o).trim();if(s!=null&&i!=null){let l=g(s,i);if(c!==l)throw new a("streamKey must equal tenantId:workflowId","invalid-stream-key");return l}if(!/^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}:[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$/.test(c)||c.split(":").length!==2)throw new a("streamKey must be tenantId:workflowId","invalid-stream-key");return c}return s!=null&&i!=null?g(s,i):null}function U({trace:e,name:t,kind:n,diagnosticOutcome:r=null,outcome:o=null,outcomeCode:s=null,startedAt:i,endedAt:c,attributes:l,authority:d,sourceEvent:m=null,streamKey:W=null,tenantId:F=null,workflowId:Z=null}){f(e);let E=String(t??"").trim();if(!ce.test(E))throw new a("workflow telemetry name is invalid");if(!oe.has(n))throw new a("workflow telemetry kind is invalid");let H=d==="ledger_projection"?o:r;if(!v.has(H))throw new a("workflow telemetry outcome is invalid");let b=I(i,"startedAt"),A=I(c,"endedAt");if(A<b)throw new a("endedAt must not be before startedAt");let y=he(l),B=ge({streamKey:W,tenantId:F,workflowId:Z,sourceEvent:m}),N={schemaVersion:$,recordType:"oracle.workflow.telemetry",authority:d,streamKey:B,trace:{traceId:e.traceId,spanId:e.spanId,parentSpanId:e.parentSpanId,sampled:e.sampled},correlation:{...e.correlation},name:E,kind:n,...d==="ledger_projection"?{outcome:o,sourceEvent:{...m}}:{diagnosticOutcome:r},outcomeCode:M(s),startedAt:b,endedAt:A,durationMs:A-b,attributes:{...y.attributes},attributePolicy:{redactedCount:y.redactedCount,droppedCount:y.droppedCount,truncatedCount:y.truncatedCount}};return u({...N,recordId:K(N)})}function Ie({trace:e,name:t,kind:n="workflow",outcome:r,outcomeCode:o=null,startedAt:s,endedAt:i,attributes:c={},tenantId:l=null,workflowId:d=null,streamKey:m=null}={}){return U({trace:e,name:t,kind:n,diagnosticOutcome:r,outcomeCode:o,startedAt:s,endedAt:i,attributes:c,authority:"diagnostic",tenantId:l,workflowId:d,streamKey:m})}function Le(e,{validateLedgerEvent:t}={}){if(!w(e))throw new a("ledger event must be a plain object","invalid-ledger-event");if(typeof t!="function"||t(e)!==!0)throw new a("ledger event validation failed","invalid-ledger-event");let n=String(e.eventId??"").trim(),r=String(e.eventHash??e.hash??"").trim().toLowerCase();if(!V.test(n)||!se.test(r))throw new a("ledger event id or hash is invalid","invalid-ledger-event");let o=O(e.correlation);for(let d of S)if(o[d]==null)throw new a(`ledger event correlation requires ${d}`,"invalid-ledger-event");if(o.eventId!==n)throw new a("ledger eventId does not match correlation","invalid-ledger-event");if(!v.has(e.outcome))throw new a("ledger event outcome is invalid","invalid-ledger-event");let s=e.tenantId==null?null:String(e.tenantId).trim(),i=e.workflowId==null?null:String(e.workflowId).trim(),c=null;if(s&&i){if(c=g(s,i),e.streamKey!=null&&String(e.streamKey).trim()!==c)throw new a("ledger streamKey must equal tenantId:workflowId","invalid-stream-key")}else if(e.streamKey!=null){let d=String(e.streamKey).split(":");if(d.length!==2)throw new a("ledger streamKey must be tenantId:workflowId","invalid-stream-key");c=g(d[0],d[1])}let l=u({eventId:n,eventHash:r,correlation:o,outcome:e.outcome,outcomeCode:M(e.outcomeCode),startedAt:I(e.startedAt,"ledger event startedAt"),endedAt:I(e.endedAt,"ledger event endedAt"),tenantId:s,workflowId:i,streamKey:c});if(l.endedAt<l.startedAt)throw new a("ledger event endedAt must not be before startedAt","invalid-ledger-event");return D.add(l),l}function $e({sourceEvent:e,trace:t,name:n,kind:r="workflow",attributes:o={}}={}){if(!D.has(e))throw new a("a validated ledger source event is required","unvalidated-ledger-event");f(t);for(let s of S)if(t.correlation[s]!==e.correlation[s])throw new a(`trace correlation ${s} does not match ledger event`,"ledger-correlation-mismatch");return U({trace:t,name:n,kind:r,outcome:e.outcome,outcomeCode:e.outcomeCode,startedAt:e.startedAt,endedAt:e.endedAt,attributes:o,authority:"ledger_projection",sourceEvent:{eventId:e.eventId,eventHash:e.eventHash},tenantId:e.tenantId,workflowId:e.workflowId,streamKey:e.streamKey})}function Se(e){if(!w(e)||!Object.isFrozen(e)||e.schemaVersion!==$||e.recordType!=="oracle.workflow.telemetry")return!1;let{recordId:t,...n}=e;return typeof t=="string"&&t===K(n)}function ve({exporter:e=null}={}){if(e!=null&&typeof e!="function"&&typeof e?.export!="function")throw new a("exporter must be a function or expose export(record)");let t=typeof e=="function"?e:e?.export?.bind(e);return Object.freeze({exporterConfigured:!!t,defaultExporter:"none",async emit(n){let r=Se(n)?n:Ie(n);if(!t)return Object.freeze({record:r,exported:!1,exporterFailed:!1});try{return await t(r),Object.freeze({record:r,exported:!0,exporterFailed:!1})}catch{return Object.freeze({record:r,exported:!1,exporterFailed:!0})}}})}export{S as CORRELATION_KEYS,p as TELEMETRY_ATTRIBUTE_LIMITS,L as TRACE_CONTEXT_VERSION,re as WORKFLOW_KINDS,ne as WORKFLOW_OUTCOMES,$ as WORKFLOW_TELEMETRY_VERSION,a as WorkflowTelemetryError,je as createChildTraceContext,ke as createRootTraceContext,_ as createTraceContext,ve as createWorkflowTelemetry,Ie as createWorkflowTelemetryRecord,ze as extractTraceContext,we as formatTraceparent,Re as injectTraceContext,Se as isWorkflowTelemetryRecord,me as parseTraceparent,$e as projectWorkflowTelemetryFromLedgerEvent,he as sanitizeTelemetryAttributes,Le as validateWorkflowTelemetrySourceEvent,g as workflowTelemetryStreamKey};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oracle-agent/oracle",
|
|
3
|
-
"version": "0.35.
|
|
3
|
+
"version": "0.35.22",
|
|
4
4
|
"description": "Oracle: standalone multichain agent control plane with an optional encrypted, loopback-only self-hosted signer.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"type": "module",
|
|
@@ -64,6 +64,8 @@
|
|
|
64
64
|
"./chains": "./dist/chains.mjs",
|
|
65
65
|
"./scanner": "./dist/scanner/index.mjs",
|
|
66
66
|
"./router": "./dist/router/index.mjs",
|
|
67
|
+
"./lp-rebalance": "./dist/data/providers/lp-liquidity-ranker.mjs",
|
|
68
|
+
"./lp-destination-discovery": "./dist/data/providers/lp-destination-discovery.mjs",
|
|
67
69
|
"./prepare-bridge": "./dist/router/prepare-bridge.mjs",
|
|
68
70
|
"./equities": "./dist/equities/index.mjs",
|
|
69
71
|
"./action-semantics": "./dist/action-semantics.mjs",
|
|
@@ -96,6 +98,8 @@
|
|
|
96
98
|
"./session-orchestrator": "./dist/public-control/session-orchestrator.mjs",
|
|
97
99
|
"./control-plane": "./dist/control-plane/index.mjs",
|
|
98
100
|
"./tenant-rbac": "./dist/tenant-rbac.mjs",
|
|
101
|
+
"./context-graph": "./dist/context-graph.mjs",
|
|
102
|
+
"./agent-lifecycle": "./dist/agent-lifecycle.mjs",
|
|
99
103
|
"./workflow-telemetry": "./dist/workflow-telemetry.mjs",
|
|
100
104
|
"./local-signer": "./dist/local-signer/index.mjs",
|
|
101
105
|
"./local-marketplace": "./dist/local-marketplace.mjs",
|
package/public/eval-report.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"node": "v26.7.0"
|
|
9
9
|
},
|
|
10
10
|
"package": "@oracle-agent/oracle",
|
|
11
|
-
"packageVersion": "0.35.
|
|
11
|
+
"packageVersion": "0.35.22",
|
|
12
12
|
"methodology": "Reproduce locally: npx @oracle-agent/oracle eval guards|adversarial|fidelity --json. Dated, commit-stamped output; no chain state or live keys involved. A report is evidence of the pinned commit only.",
|
|
13
13
|
"suites": {
|
|
14
14
|
"guards": {
|
|
@@ -98,4 +98,4 @@
|
|
|
98
98
|
"exact-confirm",
|
|
99
99
|
"receipt"
|
|
100
100
|
]
|
|
101
|
-
}
|
|
101
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1325,8 +1325,8 @@ footer{margin-top:clamp(72px,12vh,120px);border-top:1px solid var(--line);paddin
|
|
|
1325
1325
|
|
|
1326
1326
|
<div class="home-stats rv" aria-label="Oracle surface metrics">
|
|
1327
1327
|
<div class="home-stat"><b id="hero-protocol-count" data-count="220">220</b><span>protocols / venues wired</span></div>
|
|
1328
|
-
<div class="home-stat"><b id="hero-provider-count" data-count="
|
|
1329
|
-
<div class="home-stat"><b id="hero-op-count" data-count="
|
|
1328
|
+
<div class="home-stat"><b id="hero-provider-count" data-count="125">125</b><span>data providers</span></div>
|
|
1329
|
+
<div class="home-stat"><b id="hero-op-count" data-count="537">537</b><span>data operations</span></div>
|
|
1330
1330
|
<div class="home-stat"><b id="hero-chain-count">14 + EVM</b><span>chains wired</span></div>
|
|
1331
1331
|
</div>
|
|
1332
1332
|
</div>
|
|
@@ -2068,14 +2068,14 @@ var BRAND = "brand/";
|
|
|
2068
2068
|
{ n: "Derive V2", img: "derive", cap: "read", u: "https://app.derive.xyz" },
|
|
2069
2069
|
{ n: "PancakeSwap AMM", img: "pancakeswap", cap: "read + quote", u: "https://pancakeswap.finance/" },
|
|
2070
2070
|
{ n: "Lista Lending", img: "lista", cap: "read + quote", u: "https://lista.org/lending" },
|
|
2071
|
-
{ n: "Silhouette", cap: "read", u: "https://silhouette.exchange/" },
|
|
2072
|
-
{ n: "Nest Exchange", cap: "read", u: "https://
|
|
2071
|
+
{ n: "Silhouette", img: "silhouette", cap: "read", u: "https://silhouette.exchange/" },
|
|
2072
|
+
{ n: "Nest Exchange", img: "nest", cap: "read", u: "https://usenest.xyz/" },
|
|
2073
2073
|
{ n: "Lista CDP", img: "lista", cap: "read", u: "https://lista.org/" },
|
|
2074
2074
|
{ n: "Benqi Lending", img: "benqi", cap: "read", u: "https://benqi.fi" },
|
|
2075
2075
|
{ n: "Pharaoh V3", img: "pharaoh", cap: "read + quote", u: "https://www.phar.gg/" },
|
|
2076
|
-
{ n: "Trade XYZ", cap: "read", u: "https://trade.xyz/" },
|
|
2077
|
-
{ n: "Markets by Kinetiq", cap: "read", u: "https://markets.xyz/" },
|
|
2078
|
-
{ n: "Outcome", cap: "read", u: "https://outcome.xyz/" },
|
|
2076
|
+
{ n: "Trade XYZ", img: "tradexyz", cap: "read", u: "https://trade.xyz/" },
|
|
2077
|
+
{ n: "Markets by Kinetiq", img: "markets", cap: "read", u: "https://markets.xyz/" },
|
|
2078
|
+
{ n: "Outcome", img: "outcome", cap: "read", u: "https://outcome.xyz/" },
|
|
2079
2079
|
{ n: "Polymarket", wm: "polymarket.png", cap: "read", u: "https://polymarket.com/" },
|
|
2080
2080
|
{ n: "XSY", img: "xsy", cap: "read", u: "https://xsy.fi" },
|
|
2081
2081
|
{ n: "Balancer V2", wm: "balancer.svg", cap: "read + quote", u: "https://balancer.fi/" },
|
|
@@ -2102,8 +2102,8 @@ var BRAND = "brand/";
|
|
|
2102
2102
|
{ n: "Odos", wm: "odos.svg", cap: "read + route source", u: "https://app.odos.xyz" },
|
|
2103
2103
|
{ n: "Jupiter", wm: "jupiter.svg", cap: "solana route source", u: "https://jup.ag/" },
|
|
2104
2104
|
{ n: "Stargate", wm: "stargate.svg", cap: "read + bridge route", u: "https://stargate.finance/" },
|
|
2105
|
-
{ n: "Motion", cap: "read", u: "https://
|
|
2106
|
-
{ n: "LiquidLaunch", cap: "read", u: "https://liquidlaunch.app/" },
|
|
2105
|
+
{ n: "Motion", img: "motion", cap: "read", u: "https://motion.meme/" },
|
|
2106
|
+
{ n: "LiquidLaunch", img: "liquidlaunch", cap: "read", u: "https://liquidlaunch.app/" },
|
|
2107
2107
|
];
|
|
2108
2108
|
var PROTOS_B = [
|
|
2109
2109
|
{ n: "Uniswap V3 LP", img: "uniswap", cap: "preview + mint/collect prepare", u: "https://app.uniswap.org/" },
|
package/server.json
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
"name": "io.github.demi-hl/oracle",
|
|
4
4
|
"description": "Keyless multichain crypto desk: chain reads + prepare-only unsigned txs. Your wallet signs.",
|
|
5
5
|
"websiteUrl": "https://oracle.demi.la",
|
|
6
|
-
"version": "0.35.
|
|
6
|
+
"version": "0.35.22",
|
|
7
7
|
"packages": [
|
|
8
8
|
{
|
|
9
9
|
"registryType": "npm",
|
|
10
10
|
"identifier": "@oracle-agent/oracle",
|
|
11
|
-
"version": "0.35.
|
|
11
|
+
"version": "0.35.22",
|
|
12
12
|
"transport": {
|
|
13
13
|
"type": "stdio"
|
|
14
14
|
},
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: oracle-best-execution
|
|
3
|
-
description: Use whenever swapping or bridging. The rule that the highest-output route wins.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Best execution
|
|
7
|
-
|
|
8
|
-
## One rule
|
|
9
|
-
The highest **net output** (after gas + bridge + impact) wins. Not the best quote, not the shortest route, not the prettiest UI.
|
|
10
|
-
|
|
11
|
-
## Swap flow
|
|
12
|
-
1. `data dex_search` → resolve token to chain + address
|
|
13
|
-
2. `data dex_token` → get live pairs, liquidity, price
|
|
14
|
-
3. `exec evm_quote` → exact-input quote from Uniswap V3
|
|
15
|
-
4. `data best_swap_route` → compare across aggregators (Li.Fi, Paraswap, 0x, CoW)
|
|
16
|
-
5. `data best_bridge_route` → if cross-chain, rank by net output
|
|
17
|
-
6. `exec evm_prepare` → build unsigned tx
|
|
18
|
-
7. Report: best route, net output, slippage, gas estimate
|
|
19
|
-
|
|
20
|
-
## Comparison always in USD
|
|
21
|
-
Convert gas + bridge fees to USD. 0.001 ETH ≠ 0.001 ETH across chains.
|
|
22
|
-
|
|
23
|
-
## Slippage
|
|
24
|
-
- Stable pools: 0.1% default
|
|
25
|
-
- Volatile pools: 0.5% default
|
|
26
|
-
- Memecoins: 1-3% or auto-detect from depth
|
|
27
|
-
- Block >1% slippage without explicit user approval
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: oracle-desk
|
|
3
|
-
description: Use when routing a crypto request to the right lane or comparing options across chains.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Oracle desk routing
|
|
7
|
-
|
|
8
|
-
1. **Which chain?** Resolve via DexScreener or user input. Never guess.
|
|
9
|
-
2. **Which lane?** Use public data and prepare providers for the resolved chain. Return unsigned transactions or typed-data intents for connected-wallet approval.
|
|
10
|
-
3. **Multi-chain?** Quote each option, synthesize. Same notional, include gas in USD, include bridge cost.
|
|
11
|
-
4. **Ambiguous?** Ask.
|
|
12
|
-
|
|
13
|
-
## Comparison rules
|
|
14
|
-
- Same notional on each chain
|
|
15
|
-
- Gas in USD (not native units)
|
|
16
|
-
- Include bridge cost + time if cross-chain
|
|
17
|
-
- Include price impact at request size
|
|
18
|
-
- Note liquidity depth — cheapest at $100 may not be cheapest at $50k
|
|
19
|
-
|
|
20
|
-
## Capability tiers
|
|
21
|
-
- `read-only` — data only
|
|
22
|
-
- `quote-only` — can price a route
|
|
23
|
-
- `prepare` — returns unsigned tx
|
|
24
|
-
- `intent` — typed-data order to sign
|
|
25
|
-
|
|
26
|
-
## Confidence
|
|
27
|
-
State explicitly: high / moderate / low / unknown. Never invent chain facts.
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: oracle-receipts
|
|
3
|
-
description: Use whenever reporting the outcome of any on-chain action (swap, bridge, mint, send, list, accept-offer).
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Receipt format
|
|
7
|
-
|
|
8
|
-
## Required fields
|
|
9
|
-
- tx hash (full, with chain explorer link)
|
|
10
|
-
- chain + chainId
|
|
11
|
-
- action (swap/bridge/mint/send/list/accept-offer)
|
|
12
|
-
- from → to (addresses)
|
|
13
|
-
- amount in → amount out (with token symbols)
|
|
14
|
-
- gas used + gas cost in USD
|
|
15
|
-
- status: confirmed / pending / failed
|
|
16
|
-
|
|
17
|
-
## Explorer links
|
|
18
|
-
- Ethereum: https://etherscan.io/tx/{hash}
|
|
19
|
-
- Base: https://basescan.org/tx/{hash}
|
|
20
|
-
- Arbitrum: https://arbiscan.io/tx/{hash}
|
|
21
|
-
- Optimism: https://optimistic.etherscan.io/tx/{hash}
|
|
22
|
-
- Polygon: https://polygonscan.com/tx/{hash}
|
|
23
|
-
- BSC: https://bscscan.com/tx/{hash}
|
|
24
|
-
- HyperEVM: https://www.hyperscan.com/tx/{hash}
|
|
25
|
-
|
|
26
|
-
## Never claim
|
|
27
|
-
- "submitted" = confirmed. Only tx receipt with status=1 is confirmed.
|
|
28
|
-
- A prepare is not a fill. Report prepare as "prepared, unsigned."
|
|
29
|
-
- A sign is not a send. Report sign as "signed, not broadcast."
|