Overview
This guide walks through the full Newton Protocol integration flow end-to-end. By the time you finish, you will have:- Written a data oracle that provides external data to policies
- Created a policy that evaluates transaction intents against oracle data, written in Rego
- Deployed policy files to IPFS and registered them on-chain with
newton-cli - Deployed an Newton Policy Client smart wallet on Sepolia that uses the policy to gate transactions
- Built a Next.js application with the Newton SDK that submits transactions through your policy-gated wallet
Prerequisites
Before you begin, make sure you have the following tools and accounts ready.| Requirement | Use |
|---|---|
| Rust + Cargo | Building and running newton-cli |
| Node.js >= 20 + npm | Running @bytecodealliance/jco and the Next.js demo app |
Foundry (forge, cast, anvil) | Compiling and deploying Solidity contracts |
| newton-cli 0.1.31 | Uploading policy files, generating CIDs, deploying policies |
| Pinata account | IPFS pinning (you will need a JWT and a gateway URL) |
| Sepolia ETH | Gas fees on the Ethereum Sepolia testnet |
| Newton API key | Authenticate SDK requests — email [email protected] to request one |
Install tooling
Step 1: Write and Build the Data Oracle
Data oracles are WebAssembly components that fetch or compute external data at evaluation time. The Newton network executes your WASM, and the output is fed into your Rego policy asdata.data.
Create a working directory for the policy workspace:
1.1 Define the WIT interface
Createnewton-provider.wit. This file declares the shape of the WASM component — what it imports (an HTTP fetch capability) and what it exports (a run function).
1.2 Implement the oracle in JavaScript
Createpolicy.js. The exported run function receives a JSON string of arguments (wasm_args) and must return a JSON string. The skeleton below always returns { "success": true }. Replace the body with your own data-fetching logic.
1.3 Build the WASM component
Usejco componentize to compile the JavaScript into a WASM component that conforms to the WIT interface:
policy.wasm in the current directory.
If you installed
jco locally (without -g), run it via npx jco componentize ... instead.1.4 (Optional) Simulate locally
You can test your WASM before deploying it:newton-cli commands.
Step 2: Write Rego Policy and Metadata
Every Newton policy consists of a Rego file, a parameter schema, and two metadata descriptors. This step creates all four files.2.1 Create policy.rego
The Rego policy evaluates the JSON output from your WASM oracle. The result of the data.data path is whatever your run function returned.
For a full reference on supported Rego syntax, operators, and built-in functions, see the Rego Syntax Guide.
2.2 Create params_schema.json
This JSON Schema controls which policy parameters end users are allowed to set when they call setPolicy. Leave it empty if your policy has no configurable parameters.
2.3 Create policy_data_metadata.json
Metadata describing the WASM data oracle:
2.4 Create policy_metadata.json
Metadata describing the policy itself:
2.5 Organize into policy-files/
The newton-cli commands in the next step expect all five files in a single directory:
policy-files/ directory should now contain:
policy.wasmpolicy.regoparams_schema.jsonpolicy_data_metadata.jsonpolicy_metadata.json
Step 3: Upload to IPFS and Deploy Policy
3.1 Set up environment variables
Create a.env file (or .env.policy) with the values needed for policy deployment:
3.2 Generate CIDs
The
--entrypoint value must match your Rego package name combined with the rule name. For package your_policy with rule allow, the entrypoint is your_policy.allow.3.3 Deploy Policy Data
This uploads your WASM oracle to IPFS and registers it on-chain:3.4 Deploy Policy
This deploys the Rego policy on-chain, pointing it at the policy data you just deployed:Step 4: Deploy Policy Client Contract
This step deploys a smart contract wallet on Sepolia that requires Newton attestations before executing any transaction.4.1 Create the Foundry project
4.2 Write the contract
The following is a sample smart wallet that uses a Newton policy. Createsrc/NewtonPolicyWallet.sol:
- Inherits from
NewtonPolicyClient, which handles policy registration with the Newton Policy contract. - Must override
supportsInterfaceto include0xdbdcaa9c(the interface ID expected by the deployed Newton Policy contract). - Uses an
initialize()pattern instead of constructor arguments for proper policy client setup. - The
setPolicyfunction is inherited fromNewtonPolicyClient— no custom wrapper is needed. - Uses
_validateAttestationDirect()for direct attestation verification (evaluates intent without waiting for on-chain task response confirmation). - Imports
INewtonProverTaskManagerfor theTaskandTaskResponsestruct types used by the direct validation flow.
4.3 Configure foundry.toml
Replace the default foundry.toml with:
4.4 Create the deployment script
Createscript/Deploy.s.sol:
4.5 Create the set policy script
Createscript/SetPolicy.s.sol:
4.6 Deploy the wallet
Create a.env file in the newton-policy-wallet directory:
The wallet owner is automatically derived from the
PRIVATE_KEY, so you do not need a separate OWNER variable.4.7 Set the policy on the wallet
Createpolicy_params.json in the project root:
.env:
- Newton can generate attestations for your
NewtonPolicyWallet. - The wallet will only execute transactions that carry a valid attestation.
Step 5: SDK Integration
Build a Next.js application that uses the Newton SDK to evaluate transaction intents against your policy and then execute them through your deployed wallet.5.1 Create the project and install dependencies
5.2 Environment variables
Create.env.local in the newton-sdk-app directory:
NEXT_PUBLIC_POLICY_CONTRACT_ADDRESS is the Newton Policy contract (fixed address on Sepolia: 0x698C687f86Bc2206AC7C06eA68AC513A2949abA6). NEXT_PUBLIC_POLICY_WALLET_ADDRESS is YOUR deployed wallet contract. These are different contracts. The Policy contract manages policy registration; your wallet is a client of it.5.3 Create the configuration file
Createsrc/const/config.ts:
5.4 Create the ABI file
Createsrc/lib/abi.ts. This ABI covers the functions you will call from the frontend. The full compiled ABI will include additional inherited functions like policyClientOwner() and policyId().
5.5 Create the evaluation request helper
Createsrc/lib/evaluation-request.ts:
5.6 Create the transaction execution helper
Createsrc/lib/execute-with-attestation.ts:
5.7 Create the Newton client hook
Createsrc/lib/use-newton-client.ts:
5.8 Create the main page
Replacesrc/app/page.tsx with the complete evaluation and execution flow:
5.9 Run the application
Step 6: Verification
Verify that your end-to-end setup works correctly.Run the app
Start the Next.js dev server with
npm run dev inside the newton-sdk-app directory and open http://localhost:3000.Submit an evaluation request
Fill in the form fields:
- Target Address — any valid Ethereum address for testing
- Value —
0(or a small amount if sending ETH, making sure the wallet contract is funded) - Data —
0x(or encoded calldata for the target) - WASM Args —
{}(or JSON matching your oracle’s expected input)
Observe the flow
Watch the UI update through each stage:
- Task ID appears — the Newton network has received your evaluation request
- Evaluation Result — shows “Allowed” or “Blocked” based on your policy logic.
- Transaction execution — if allowed, the transaction is signed and submitted with the attestation
- Transaction hash — a link to view the confirmed transaction on Sepolia Etherscan
Verify the task on Newton Explorer
Copy the Task ID from the UI and look it up on the Newton Explorer. Confirm that the task status shows as completed and the evaluation result matches what the UI displayed.
Verify on Sepolia Etherscan
Click the Etherscan link and confirm:
- The transaction was sent to your Newton Policy Wallet address
- The
Executedevent appears in the transaction logs - The
taskIdin the event matches the one shown in the UI
Troubleshooting
”command not found” after installing tools
Restart your shell after installing Rust (rustup), Node via Homebrew, or Foundry. Alternatively, re-source your shell configuration:
jco componentize fails
If you installed @bytecodealliance/jco locally (without -g), you must run it via npx:
@bytecodealliance/componentize-js as a peer dependency. Install both together:
WebSocket connection fails
Make sure yourNEXT_PUBLIC_SEPOLIA_ALCHEMY_WS_URL uses the wss:// protocol, not https://. The Newton SDK requires a WebSocket transport for the wallet client.
Invalid attestation error (0xbd8ba84d)
This is the InvalidAttestation() revert. The most common causes are:
- Wrong Task Manager address (most common): The wallet was initialized with a task manager address that does not match the one the Newton SDK gateway signs against. The wallet must use
0xecb741F4875770f9A5F060cb30F6c9eb5966eD13on Sepolia. BLS signatures are cryptographically bound to this specific address — using any other address will always fail. - Intent parameter mismatch: The
to,value,data, orchainIdfields in the evaluation request do not match what was signed. - Policy ID mismatch: The
policyIddoes not match the wallet’s configured policy. - Incorrect struct passthrough: The
taskortaskResponsestructs fromevaluateIntentDirectwere not forwarded correctly tovalidateAndExecuteDirect.
ExecutionFailed error (0xacfdb444)
This means the attestation passed (the policy allowed the transaction) but the inner to.call{value: value}(data) reverted. Common causes:
- Wallet contract has no ETH: If you are sending
value > 0, the wallet contract itself needs ETH. Fund the wallet contract address directly — it is not enough for only the signer EOA to have ETH. - Target contract reverted: The target’s own logic rejected the call.
- Malformed calldata: The
datafield does not match the target function’s expected ABI encoding.
cast:
cast sig "ExecutionFailed()" returns 0xacfdb444, cast sig "InvalidAttestation()" returns 0xbd8ba84d.
Environment variables not loading
For Next.js:- Client-side variables must be prefixed with
NEXT_PUBLIC_. - Server-side-only variables should not have this prefix.
- You must restart the dev server after modifying
.env.local.
Gas estimation fails
TheestimateGas call simulates the transaction on-chain. If it reverts, the viem error message is often unhelpful (“execution reverted for an unknown reason”). To debug:
- Extract the calldata from the error message.
- Run
cast call <wallet> "0x<calldata>" --from <signer> --rpc-url <rpc>to see the revert selector. - Match the selector:
0xacfdb444=ExecutionFailed(),0xbd8ba84d=InvalidAttestation().
- The signer does not have sufficient Sepolia ETH for gas.
- The wallet contract has no ETH but
value > 0is being sent. - Wrong task manager address (see “Invalid attestation” above).
- The attestation has expired.
Policy evaluation times out
- Check that your policy WASM builds correctly by running the local simulation.
- Verify that
wasmArgsare in the format your WASM expects. - Increase the
timeoutvalue in the evaluation request if needed. - If your WASM calls external APIs, make sure those APIs are responding.
Foundry deployment fails
- Verify
PRIVATE_KEYis prefixed with0x. - Ensure the deployer wallet has sufficient Sepolia ETH.
- Check that
RPC_URLis valid and accessible. - Run
forge buildfirst to catch compilation errors before deploying. - If
forge init --no-commitfails, useforge init --no-gitinstead (the flag name varies by Foundry version). forge installrequires a git repository. Rungit initfirst if you used--no-git.- Compilation requires
via_ir = trueinfoundry.tomldue to the stack depth of newton-contracts. Without it, you will get a “stack too deep” error.
Additional Resources: Factory Pattern
If your application needs to deploy a separate policy client per user (for example, per-user trading vaults or guarded accounts), use the factory pattern with OpenZeppelin’sClones library. This deploys minimal proxy contracts that are much cheaper than full contract deployments.
Factory Solidity contracts
Policy client implementation (used as the clone template):Frontend example
Next Steps
- Rego Syntax Guide — Full reference for supported Rego syntax, operators, and built-in functions.
- SDK Reference — Complete API documentation for
@magicnewton/newton-protocol-sdk. - CLI Reference — All
newton-clicommands and options.