# Deploying with CLI \[Deploy Newton Protocol policies and data oracles to IPFS and on-chain using newton-cli]

This guide walks through deploying your policy files to IPFS and registering them on-chain using `newton-cli`. By the end, you will have a deployed PolicyData contract, a deployed Policy contract, and a registered PolicyClient.

## Prerequisites

* **newton-cli** installed: `curl -L cli.newton.xyz | sh && newtup` (see [CLI Reference](/developers/reference/command-line-tool#installation))
* **Pinata account** for IPFS pinning ([pinata.cloud](https://pinata.cloud))
* **Sepolia ETH** in your deployer wallet
* Completed [Writing Data Oracles](/developers/guides/writing-data-oracles) and [Writing Policies](/developers/guides/writing-policies)

:::warning
Mainnet policy usage requires allowlisting by the Newton team. Before deploying or using policies on mainnet, [reach out through the intake form](https://newton.xyz/intake-form).
:::

## Environment Variables

Create a `.env` file with deployment credentials:

```bash
CHAIN_ID=11155111
PINATA_JWT=your_pinata_jwt
PINATA_GATEWAY=your_pinata_gateway
PRIVATE_KEY=0xYourDeploymentPK
RPC_URL=https://eth-sepolia.g.alchemy.com/v2/apiKey
```

Load the variables:

```bash
set -a && source .env && set +a
```

## Step 1: Generate CIDs and Upload to IPFS

```bash
newton-cli policy-files generate-cids \
  --directory policy-files \
  --output policy_cids.json \
  --entrypoint "your_policy.allow"
```

This uploads your policy files to IPFS via Pinata and generates `policy_cids.json` containing the content identifiers.

:::note
The `--entrypoint` value must match your Rego package name + rule name. For `package your_policy` with rule `allow`, use `your_policy.allow`.
:::

## Step 2: Deploy PolicyData

Deploy the WASM oracle on-chain:

```bash
newton-cli policy-data deploy --policy-cids policy_cids.json
```

Save the output address:

```
Policy data deployed successfully at address: 0xPolicyDataAddress
```

## Step 3: Deploy Policy

Deploy the Rego policy on-chain, referencing the PolicyData:

```bash
newton-cli policy deploy \
  --policy-cids policy_cids.json \
  --policy-data-address "0xPolicyDataAddress"
```

Save the output address — you will use it when deploying your PolicyClient contract.

## Step 4: Deploy Your Smart Contract

Before registering a PolicyClient, you need a deployed contract that inherits `NewtonPolicyClient`. Follow the [Smart Contract Integration](/developers/guides/smart-contract-integration) guide, then return here with your deployed contract address.

## Step 5: Register PolicyClient

Register your deployed contract with the PolicyClientRegistry:

```bash
newton-cli policy-client register \
  --registry 0x0dbd6e44a1814f5efe4f67a00b7f28642e3064dd \
  --client "0xYourPolicyClientAddress"
```

## Step 6: Set Policy on Client

Configure the policy and parameters on your PolicyClient:

```bash
newton-cli policy-client set-policy \
  --policy-client "0xYourPolicyClientAddress" \
  --policy-address "0xPolicyAddress"
```

Set policy parameters and expiration:

```bash
newton-cli policy-client set-policy-params \
  --policy-client "0xYourPolicyClientAddress" \
  --policy-params policy_params.json \
  --expire-after 1000
```

:::warning
**`set-policy-params` changes the `policyId`.** Every call internally calls `setPolicy(PolicyConfig)` which re-registers with the Policy contract and returns a new `policyId`. Any previously recorded `policyId` becomes stale. Always verify the new `policyId` on-chain after updating params.
:::

### Policy Params Format

On-chain policy params must be **flat JSON** matching your `params_schema.json`. The gateway reads these bytes directly and passes them to Rego as `data.params`. Do not use the nested CLI format.

| File | Purpose | Use With |
|------|---------|----------|
| `policy_params.json` | Template with `VAULT_ADDRESS_PLACEHOLDER` | Never use directly |
| `policy_params_live.json` | Nested CLI format with real vault address | Reference only |
| `policy_params_onchain.json` | Flat JSON matching the params schema | `set-policy-params` |

If on-chain params are in the nested CLI format instead of flat JSON, policy evaluation fails with `Missing required property` during schema validation.

## Step 7: Verify

Check that your PolicyClient is registered and active:

```bash
newton-cli policy-client status \
  --registry 0x0dbd6e44a1814f5efe4f67a00b7f28642e3064dd \
  --client "0xYourPolicyClientAddress"
```

You can also test the full policy via the Gateway:

```bash
curl -X POST https://gateway.testnet.newton.xyz/rpc \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <your_api_key>" \
  -d '{
    "jsonrpc": "2.0",
    "method": "newt_simulatePolicy",
    "params": {
      "policy_client": "0xYourPolicyClientAddress",
      "policy": "package your_policy\ndefault allow := false\nallow if { data.wasm.success }",
      "intent": {
        "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
        "to": "0xb1aD5f82407bC0f19f42b2614fb9083035a36b69",
        "value": "0x0",
        "data": "0x",
        "chain_id": "0xaa36a7",
        "function_signature": "0x"
      },
      "policy_data": [{"policy_data_address": "0xPolicyDataAddress"}],
      "policy_params": {}
    },
    "id": "7ca6621b-7aa4-4bb7-a896-1f2b58a18c78"
  }'
```

## Next Steps

<Card icon="window" to="/developers/guides/frontend-sdk-integration" title="Frontend SDK Integration">
  Build a frontend that submits tasks via the SDK
</Card>
