@oracle-agent/oracle 0.2.4 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -226,7 +226,7 @@ owner-local source lane.** The short version:
226
226
  - Reads and quotes need **no keys**.
227
227
  - The public package exposes no signer, key vault, or broadcast path.
228
228
  - User wallets authorize prepared actions outside the public data plane.
229
- - The source-only operator signer is not a public API and is not shipped to npm.
229
+ - Owner-local signing is shipped separately as `@oracle-agent/operator`; its agent-facing daemon supports only policy-bounded Hyperliquid and Polymarket execution.
230
230
 
231
231
  Run the read-only data plane:
232
232
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oracle-agent/oracle",
3
- "version": "0.2.4",
3
+ "version": "0.3.1",
4
4
  "description": "Oracle: prepare-only multichain agent control plane. Policy-bounded intents for a user-signed wallet. Self-custody by default — the public package never takes your key. Built for Hermes; no model key required.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
package/src/index.mjs CHANGED
@@ -7,7 +7,15 @@
7
7
  // public package entrypoint, so importing the package cannot hand a caller a
8
8
  // signer.
9
9
 
10
- export { stampPrepared, assertPreparedEnvelope, computePrepareHash } from "./prepare-envelope.mjs";
10
+ export {
11
+ stampPrepared,
12
+ assertPreparedEnvelope,
13
+ computePrepareHash,
14
+ resolvePrepareMaxAgeMs,
15
+ PREPARE_VERSION,
16
+ PREPARE_MAX_AGE_MS,
17
+ PREPARE_HARD_MAX_AGE_MS,
18
+ } from "./prepare-envelope.mjs";
11
19
  export { data, dataCall, dataHealth, dataCatalog } from "./data/desk-data.mjs";
12
20
  export { registerProvider, getProvider, listProviders } from "./data/catalog.mjs";
13
21
 
@@ -1,12 +1,23 @@
1
- // Canonical prepare envelope stamped by @oracle-agent/oracle prepare helpers,
2
- // verified by @oracle-agent/operator before any local sign/submit.
3
- // Keeps agentic UX identical: prepare() exec(prepared). Blocks handcrafted actions.
1
+ // Canonical prepare envelope shared by Oracle prepare helpers and the local operator.
2
+ // The versioned checksum binds payload and freshness metadata. It detects mutation;
3
+ // signer-owned policy, not this public checksum, authorizes execution.
4
4
 
5
5
  import { createHash } from "node:crypto";
6
6
 
7
- export const PREPARE_VERSION = 1;
7
+ export const PREPARE_VERSION = 2;
8
8
  /** Default max age for a prepared envelope at sign time (ms). */
9
9
  export const PREPARE_MAX_AGE_MS = 5 * 60 * 1000;
10
+ /** Hard ceiling for authenticated envelope lifetime (ms). */
11
+ export const PREPARE_HARD_MAX_AGE_MS = (() => {
12
+ const n = Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);
13
+ return Number.isFinite(n) && n > 0 ? n : 30 * 60 * 1000;
14
+ })();
15
+
16
+ export function resolvePrepareMaxAgeMs(requested) {
17
+ const base = requested == null || requested === "" ? PREPARE_MAX_AGE_MS : Number(requested);
18
+ if (!Number.isFinite(base) || base < 0) return PREPARE_MAX_AGE_MS;
19
+ return Math.min(base, PREPARE_HARD_MAX_AGE_MS);
20
+ }
10
21
 
11
22
  function stableStringify(value) {
12
23
  if (value === null || typeof value !== "object") return JSON.stringify(value);
@@ -20,10 +31,7 @@ export function prepareBodyForHash(prepared) {
20
31
  const {
21
32
  oraclePrepared,
22
33
  prepareHash,
23
- preparedAt,
24
- prepareVersion,
25
34
  note,
26
- // strip volatile display-only
27
35
  ...body
28
36
  } = prepared || {};
29
37
  return body;
@@ -52,8 +60,9 @@ export function stampPrepared(payload, { provider, kind } = {}) {
52
60
  if (!base.provider) throw new Error("stampPrepared: provider required");
53
61
  if (!base.kind) throw new Error("stampPrepared: kind required");
54
62
  const preparedAt = Date.now();
63
+ const expiresAt = preparedAt + PREPARE_MAX_AGE_MS;
55
64
  const prepareVersion = PREPARE_VERSION;
56
- const withMeta = { ...base, preparedAt, prepareVersion };
65
+ const withMeta = { ...base, preparedAt, expiresAt, prepareVersion };
57
66
  const prepareHash = computePrepareHash(withMeta);
58
67
  return {
59
68
  ...withMeta,
@@ -78,20 +87,33 @@ export function assertPreparedEnvelope(prepared, {
78
87
  }
79
88
  if (prepared.oraclePrepared !== true) {
80
89
  throw new Error(
81
- `${label}: refused handcrafted actionpass a stamped prepare result from @oracle-agent/oracle (oraclePrepared missing)`
90
+ `${label}: prepared integrity envelope missing use an @oracle-agent/oracle prepare result`
82
91
  );
83
92
  }
84
93
  if (Number(prepared.prepareVersion) !== PREPARE_VERSION) {
85
94
  throw new Error(`${label}: unsupported prepareVersion ${prepared.prepareVersion}`);
86
95
  }
87
- const age = nowMs - Number(prepared.preparedAt || 0);
88
- if (!Number.isFinite(age) || age < 0 || age > maxAgeMs) {
89
- throw new Error(`${label}: prepare envelope expired or clock-skewed (ageMs=${age}, max=${maxAgeMs})`);
90
- }
91
96
  const expected = computePrepareHash(prepared);
92
97
  if (String(prepared.prepareHash || "") !== expected) {
93
98
  throw new Error(`${label}: prepareHash mismatch — payload was altered after prepare`);
94
99
  }
100
+ const preparedAt = Number(prepared.preparedAt);
101
+ const expiresAt = Number(prepared.expiresAt);
102
+ const effectiveMax = resolvePrepareMaxAgeMs(maxAgeMs);
103
+ const age = nowMs - preparedAt;
104
+ const lifetime = expiresAt - preparedAt;
105
+ if (
106
+ !Number.isFinite(age) ||
107
+ !Number.isFinite(expiresAt) ||
108
+ !Number.isFinite(lifetime) ||
109
+ age < 0 ||
110
+ lifetime <= 0 ||
111
+ lifetime > PREPARE_HARD_MAX_AGE_MS ||
112
+ age > effectiveMax ||
113
+ nowMs > expiresAt
114
+ ) {
115
+ throw new Error(`${label}: prepare envelope expired or clock-skewed (ageMs=${age}, max=${effectiveMax})`);
116
+ }
95
117
  if (providers) {
96
118
  const allow = new Set(providers);
97
119
  if (!allow.has(prepared.provider)) {