# Integration Guide \[Install VaultKit 2.1, declare a Newton policy, and run a typed vault-manager action.]

VaultKit's current authoring flow is policy-first: declare the policy modules synchronously with `definePolicy(...)`, pass the deployed `NewtonPolicy` address to `createShield(...)`, extend the returned client with a vendor module, and then call a typed action.

## Prerequisites

| Requirement | Version or purpose |
| --- | --- |
| Node.js | 22 or newer |
| pnpm | 10 or newer |
| `viem` | `^2.35.1` |
| `zod` | `^3.0.0` |
| Newton API key | Created for the chain environment you will use |
| Curator wallet | Funded on the target chain and authorized to manage the target vault |

## Install

```bash
pnpm add @newton-xyz/vaultkit @newton-xyz/policy-core viem zod
pnpm add @newton-xyz/policy-pack-vaultsfyi
```

Install only the vendor SDKs your integration needs. The typed MetaMorpho module uses:

```bash
pnpm add @morpho-org/blue-sdk @morpho-org/blue-sdk-viem @morpho-org/morpho-ts
```

`@newton-xyz/policy-pack-shared` is not part of the VaultKit 2.x flow. Policy authoring and manifest utilities now live in `@newton-xyz/policy-core`.

## 1. Create Viem Clients

```typescript
import { createPublicClient, createWalletClient, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { base } from 'viem/chains'

const account = privateKeyToAccount(
  process.env.CURATOR_PRIVATE_KEY as `0x${string}`,
)

const publicClient = createPublicClient({
  chain: base,
  transport: http(process.env.RPC_URL),
})

const walletClient = createWalletClient({
  account,
  chain: base,
  transport: http(process.env.RPC_URL),
})
```

## 2. Declare the Policy

```typescript
import { definePolicy } from '@newton-xyz/vaultkit'
import { vaultsfyi } from '@newton-xyz/policy-pack-vaultsfyi'

const policy = definePolicy({
  chainId: '8453',
  env: 'prod',
}).with(vaultsfyi)
```

`definePolicy(...)` is synchronous and does not read the chain. Add more published packs or custom `defineOracle(...)` outputs with additional `.with(...)` calls. Module order does not need to match the deployed contract; VaultKit aligns the declared modules to `NewtonPolicy.getPolicyData()` when the client is created.

## 3. Create the Client and Add a Vendor Module

```typescript
import { createShield } from '@newton-xyz/vaultkit'
import { morphoActions } from '@newton-xyz/vaultkit/vendors/morpho'

const client = (await createShield({
  apiKey: process.env.NEWTON_API_KEY!,
  walletClient,
  publicClient,
  rpc: process.env.RPC_URL!,
  vault: '0xMetaMorphoVault',
  policy,
  policyAddress: '0xDeployedNewtonPolicy',
})).extend(morphoActions)
```

The `policyAddress` must reference a deployed `NewtonPolicy` whose `getPolicyData()` set matches the modules declared with `.with(...)`. `createShield(...)` resolves that policy and exposes the result as `client.policy`.

## 4. Configure Parameters and Secrets

```typescript
await client.setParams({
  vaultsfyi: {
    risk_score_floor: 80,
    tvl_drawdown_24h_max_pct: 25,
  },
})

await client.uploadSecrets({
  vaultsfyi: {
    VAULTS_FYI_API_KEY: process.env.VAULTSFYI_API_KEY!,
  },
})
```

Parameters are encoded into the onchain composite manifest. Secrets are encrypted client-side and uploaded separately; they are not written onchain.

Use `client.encodeParams(params)` to inspect the exact bytes before writing them.

## 5. Verify the Attachment

```typescript
console.log(client.policy.address)
console.log(client.policy.modules)
console.log(client.verification)
```

When attaching to an existing deployment, VaultKit verifies progressively:

1. The attached contract points to the expected policy address.
2. The onchain oracle set and WASM CIDs match the declared modules.
3. Stored params decode against the module schemas.
4. When `expectedParams` is supplied, stored bytes exactly match the expected encoding.

Call `client.reverify()` after changing parameters. Use `attachWithoutVerify: true` only to recover an incomplete first-time setup, and remove it immediately after writing the correct configuration.

## 6. Grant the Required Vault Role

The client address must hold the manager or allocator role required by the vendor action. Role assignment is vendor-specific; VaultKit does not bypass the vendor's authorization model.

```typescript
console.log(client.policyClientAddress)
```

Grant that address the appropriate role using the vendor's normal governance process.

## 7. Execute a Typed Action

```typescript
const result = await client.morpho.reallocate(
  '0xMetaMorphoVault',
  [{ marketParams, assets: 1_000_000n }],
  {
    prepareQueryOptions: {
      vaultsfyi: {
        previousAllocationHash: '0x...',
      },
    },
  },
)

const receipt = await publicClient.waitForTransactionReceipt({
  hash: result.transactionHash,
})
```

Each policy module owns its `wasmArgs` construction. Pass module-specific inputs through `prepareQueryOptions.<shortPackId>`; VaultKit validates the resulting data before building the intent.

## 8. Handle Expected Failures

```typescript
import {
  AttestationTimeoutError,
  PolicyDeniedError,
  RpcReadError,
} from '@newton-xyz/vaultkit'

try {
  await client.morpho.reallocate('0xMetaMorphoVault', allocations)
} catch (error) {
  if (error instanceof PolicyDeniedError) {
    console.error('The policy denied this action:', error.reason)
  } else if (error instanceof AttestationTimeoutError) {
    console.error('Request a fresh task after backoff')
  } else if (error instanceof RpcReadError) {
    console.error(error.read, error.cause)
  } else {
    throw error
  }
}
```

See [Errors](/developers/vaults/sdk/errors) before adding retries. A deterministic policy or schema failure does not become valid when retried.

## Next Steps

<Card title="Policies" icon="layers" to="/developers/vaults/sdk/policies">
  Compose published packs, custom oracles, and policy-level parameters.
</Card>

<Card title="Custom Oracles" icon="code" to="/developers/vaults/sdk/custom-oracles">
  Build a typed oracle with `defineOracle(...)`.
</Card>

<Card title="Examples" icon="terminal" to="/developers/vaults/sdk/examples">
  Copy current VaultKit 2.1 recipes.
</Card>
