When to chain oracles
| Goal | Shape |
|---|---|
| Gate a deposit on vault risk only | Single oracle — one PolicyData |
| Gate a deposit on vault risk and depositor reputation | Two oracles — read both in one policy |
| Gate on risk and sanctions and oracle divergence | Three oracles — one decision over all three |
How outputs are merged
Each PolicyData oracle is an independent WASM component that returns a JSON object (see Writing Data Oracles). When a policy references multiple oracles, the Newton network:- Runs every referenced oracle’s WASM (each receives the same
wasm_argsblob). - Shallow-merges every oracle’s JSON output into a single object exposed to Rego as
data.wasm. - Evaluates your Rego against the merged
data.wasmplus your configureddata.params.
score field would collide — the last one merged would win. To avoid this, each oracle namespaces its output under a unique key.
The namespacing convention
Every oracle wraps its entire output under a single top-level key — its pack id (a short, unique identifier, conventionally the oracle’s name):params object can configure every oracle:
Wrapping every return path (including error returns) under a single pack-id key is the convention used by all Newton policy packs. If you write your own oracle that you intend to chain, adopt the same wrapper so it composes cleanly with others.
Writing Rego that consumes two oracles
The recommended pattern is a deny set: each rule adds a reason string todeny when a condition fails, and the policy allows only when no deny rule fires. This composes naturally across oracles — every oracle contributes its own deny rules over its own namespace, and the final allow is simply “nothing denied.”
- One
allowrule, manydenyrules. Using a deny set (deny contains ...) instead of a single-valueddenyrule means multiple simultaneous failures coexist instead of conflicting — the policy can never accidentally fail open when two rules fire at once. - Read each oracle from its own namespace (
data.wasm.<pack-id>) and its thresholds fromdata.params.<pack-id>. - Fail closed on oracle errors. A namespaced
errorfield is the convention for signaling that an oracle could not produce data; deny on it unless you have a reason not to.
if, contains, sprintf, comprehensions — see the Rego Syntax Guide.
Simulating a multi-oracle policy
Before deploying, simulate the full policy against both oracles with the Gateway’snewt_simulatePolicy method (or the SDK’s simulatePolicy). Pass multiple entries in policy_data — one per oracle — and a policy_params object namespaced to match your Rego.
data.wasm, and evaluates your Rego. Inspect evaluation_result.policy_params_and_data in the response to confirm the merged data.wasm shape matches what your Rego expects.
If any oracle requires secrets, upload them per PolicyData address first (see Uploading & Accessing Secrets in Oracles).
newt_simulatePolicy requires ownership of the PolicyClient when at least one referenced oracle has a secrets schema. To iterate on a single oracle in isolation, use newt_simulatePolicyData with inline secrets.Deploying a multi-oracle policy
The two ways to put a multi-oracle policy on-chain:- Newton Dashboard — the policy editor lets you add multiple oracle modules to one policy and deploys the
NewtonPolicycontract bound to all of their PolicyData addresses. This is the recommended path today. See Using the Dashboard. - CLI —
newton-cli policy deploycurrently binds a single--policy-data-addressper policy. Multi-PolicyData deploys via the CLI are coming soon; until then, use the dashboard to deploy policies that reference more than one oracle.
Next Steps
Policy Packs
Prebuilt, deployed oracles you can chain together today
Secrets in Oracles
Upload and access API keys for oracles that need them
Testing Policies
Unit-test your Rego and simulate before deploying
Writing Policies
Rego fundamentals for a single policy