@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 +1 -1
- package/package.json +1 -1
- package/src/index.mjs +9 -1
- package/src/prepare-envelope.mjs +35 -13
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
|
-
-
|
|
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.
|
|
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 {
|
|
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
|
|
package/src/prepare-envelope.mjs
CHANGED
|
@@ -1,12 +1,23 @@
|
|
|
1
|
-
// Canonical prepare envelope
|
|
2
|
-
//
|
|
3
|
-
//
|
|
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 =
|
|
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}:
|
|
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)) {
|