# Deploying with CLI \[Build, simulate, and deploy Newton policies with newton-cli, then wire a tested PolicyClient with Foundry and cast]

This guide starts from a scaffolded Newton policy, proves its allow and deny behavior locally, deploys PolicyData and Policy contracts, and then wires an existing PolicyClient.

:::warning
Deployment uploads artifacts and sends transactions. Finish local simulation first, review the target chain and transactions, and use a funded testnet signer before broadcasting.
:::

## Prerequisites

* `newton-cli`: `curl -L cli.newton.xyz | sh && newtup`
* A policy created with `newton-cli policy scaffold`
* A tested contract that inherits `NewtonPolicyClient`
* A target chain, funded deployer, and RPC endpoint
* Foundry (`forge` and `cast`) for PolicyClient deployment and wiring

Run the toolchain check before building:

```bash
newton-cli --version
newton-cli doctor
```

Dashboard login is not required to scaffold, build, or simulate locally.

## Credential handling

Provide deploy credentials through the current process environment or `~/.newton/.env`:

```bash
export CHAIN_ID=11155111
export RPC_URL=https://your-sepolia-rpc.example
export PRIVATE_KEY=0xYourDeploymentKey
```

Do not commit populated credentials or source a project-local `.env`. Never paste private keys, JWTs, API keys, or credential-bearing RPC URLs into chat with a coding agent.

`newton-cli policy deploy` uses the Newton upload proxy by default. Direct Pinata upload is optional and requires both `PINATA_JWT` and `PINATA_GATEWAY` in the same protected environment.

## Step 1 — Build the policy

Given a scaffolded directory such as `policies/transfer-limit`:

```bash
newton-cli policy build -p policies/transfer-limit
```

Use the CLI build command instead of invoking `jco componentize` directly. It validates the expected policy files and writes compiled artifacts under `dist/`.

## Step 2 — Simulate allow and deny

Configure `configs/intent.json`, `configs/wasm_args.json`, and `configs/params.json`, then run:

```bash
newton-cli policy simulate -p policies/transfer-limit
```

Run at least one expected allow case and one expected deny case. When the WASM provider calls `getSecrets()`, pass a non-production fixture stored outside tracked source:

```bash
newton-cli policy simulate -p policies/transfer-limit \
  --secrets-file /secure/local-fixtures/transfer-limit-secrets.json
```

Local WASM output is available to Rego under `data.wasm.*`; policy parameters are under `data.params.*`; the transaction intent is `input`.

Do not deploy until both cases match the intended policy.

## Step 3 — Review deployment configuration

`policy scaffold` creates the non-secret file `configs/deployment.toml`. Review its chain and expiration settings before deployment. Environment variables and explicit CLI flags override the file.

The policy directory should now include:

```text
policies/transfer-limit/
  policy.js
  policy.rego
  params_schema.json
  configs/
    deployment.toml
    intent.json
    params.json
    wasm_args.json
  dist/
    policy.wasm
    policy.rego
```

## Step 4 — Deploy PolicyData and Policy

The orchestrated deploy generates CIDs, uploads policy artifacts, deploys PolicyData, and deploys the Policy bound to it:

```bash
newton-cli policy deploy -p policies/transfer-limit
```

Record:

* `dist/policy_cids.json`
* PolicyData address or addresses, in order
* Policy address
* Chain ID and expiration configuration

If the policy has `secrets_schema.json`, the CLI includes it automatically. Confirm `secretsSchemaCid` is present in `dist/policy_cids.json` before uploading secrets.

Useful reuse options include `--skip-cids` and `--skip-data --policy-data-address 0x...`. Preserve PolicyData address order for composite policies because evaluation is positional.

:::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).
:::

## Step 5 — Deploy the PolicyClient

The PolicyClient is application code, not something `registerClient` creates. Implement and test it with Foundry first, then deploy it with the local deployer as initial owner:

```bash
forge build
forge test
forge script script/DeployPolicyClient.s.sol:DeployPolicyClient \
  --rpc-url "$RPC_URL" \
  --broadcast
```

Resolve current protocol addresses for the target chain rather than copying constants from an old guide:

```bash
newton-cli --chain-id "$CHAIN_ID" deployments show
```

## Step 6 — Bind policy and parameters

While the local deployer still owns the PolicyClient, set its Policy address:

```bash
cast send 0xPOLICY_CLIENT \
  "setPolicyAddress(address)" 0xPOLICY \
  --rpc-url "$RPC_URL" \
  --private-key "$PRIVATE_KEY"
```

If the Rego policy reads `data.params.*`, serialize the flat JSON that matches `params_schema.json` and call `setPolicy` with a non-zero expiration:

```bash
PARAMS_HEX=$(cast --from-utf8 "$(cat policies/transfer-limit/configs/params.json)")

cast send 0xPOLICY_CLIENT \
  "setPolicy((bytes,uint32))" "($PARAMS_HEX,1000)" \
  --rpc-url "$RPC_URL" \
  --private-key "$PRIVATE_KEY"
```

Choose `expireAfter` for the target chain and application. Calling `setPolicy` produces a new `policyId`; verify it immediately and update any recorded handoff or application configuration.

## Step 7 — Transfer ownership for dashboard operations

Gateway secrets and client-scoped live evaluation authorize against `PolicyClient.getOwner()`. If the dashboard login wallet must own the client, transfer after policy binding is complete:

```bash
cast send 0xPOLICY_CLIENT \
  "setPolicyClientOwner(address)" 0xDASHBOARD_LOGIN_WALLET \
  --rpc-url "$RPC_URL" \
  --private-key "$PRIVATE_KEY"
```

Verify `getOwner()` on-chain. `PolicyClientRegistry.setClientOwner` changes the registry record; it is not a substitute for `setPolicyClientOwner` on the contract.

:::warning
After ownership transfer, the local deployer can no longer call owner-only `setPolicy` or `setPolicyAddress`. Plan policy and parameter updates before transfer. If the application treats clients as replaceable, deploy and wire a new client for later changes.
:::

## Step 8 — Register with the dashboard user (coming soon)

:::note
PolicyClient registration is temporarily omitted from this guide. After [newt-foundation/newton-prover-avs#771](https://github.com/newt-foundation/newton-prover-avs/pull/771) lands in a stable `newton-cli` release, `newton-cli policy-client register` will open the dashboard so the dashboard user can sign and register the client. The exact released command and verification steps will be added here then.
:::

## Step 9 — Upload secrets when used

Only upload secrets after:

* PolicyData has the intended secrets schema CID
* The PolicyClient address is final
* `getOwner()` matches the dashboard identity behind the API key
* The secrets JSON matches the schema

```bash
newton-cli --chain-id "$CHAIN_ID" secrets upload \
  --secrets-file /secure/secrets/transfer-limit.json \
  --policy-client 0xPOLICY_CLIENT \
  --policy-data-address 0xPOLICY_DATA
```

Keep the secrets file outside tracked source. Do not print the file or API key while diagnosing upload problems.

## Step 10 — Verify before live evaluation

Check these values on-chain:

* PolicyClient TaskManager matches the target Newton deployment
* Policy address and `policyId` are non-zero and current
* Params and `expireAfter` are correct
* `getOwner()` is the expected wallet
* Registry record matches the dashboard user when registration is available and required
* Client-scoped secrets exist when the WASM provider requires them

Use `@newton-xyz/sdk` `evaluateIntentDirect` for a live direct-attestation flow. The browser wallet signs the exact EIP-712 intent; a server Route Handler supplies `NEWTON_API_KEY`. See [Frontend SDK Integration](/developers/guides/frontend-sdk-integration).

## Agent-assisted deployment

Newton Agent Skills automate the same local-first sequence and preserve policy and client state in handoff files. They still pause before uploads, broadcasts, ownership transfer, dashboard registration when available, gateway evaluation, and the first attested application transaction.

<Card icon="terminal" to="/developers/overview/agent-quickstart" title="Build with an Agent">
  Start from a product brief and review each live checkpoint
</Card>

<Card icon="shield" to="/developers/guides/smart-contract-integration" title="Smart Contract Integration">
  Implement and test the PolicyClient before deployment
</Card>

<Card icon="window" to="/developers/guides/frontend-sdk-integration" title="Frontend SDK Integration">
  Sign in the browser, evaluate on the server, and submit only on allow
</Card>
