@newton-xyz/vaultkit
v1.0.0
Published
VaultKit — the TypeScript SDK for vault curators. Wraps every vault-management action behind a Newton Protocol policy attestation, enforced on-chain by the Shield executor.
Readme
@newton-xyz/vaultkit
VaultKit is the TypeScript SDK for vault curators. It wraps every vault-management action behind a Newton Protocol policy attestation, so the curator's manager role is structurally incapable of executing actions that violate the policy.
Curators don't write calldata by hand and don't integrate a new vault product. They use the vendor's existing SDK (
@morpho-org/blue-sdk-viem) to produce calldata, and VaultKit plus the on-chain Shield contract handle the policy gating.
VaultKit and Shield
VaultKit is the product — the SDK you install (@newton-xyz/vaultkit) and the brand for the whole vault-protection / vault-compliance toolkit. Shield is the core on-chain mechanism it's built on: a NewtonPolicyClient executor contract that enforces the Newton policy on every call before it reaches the vault. That's why the SDK's entry point is createShield(...) and its client is ShieldClient — you're constructing and driving a Shield, the primitive that makes VaultKit protect your vault. VaultKit is the kit; Shield is the engine inside it. The naming is intentional and stable: install @newton-xyz/vaultkit, call createShield.
Highlights (target shape)
createShield({ apiKey, walletClient, rpc, policyClientAddress, pack, vault })— pairs a deployedShieldclone address with aCompositePolicyPack(fromawait defineComposite({ modules, chainId, env, publicClient, policyAddress })), deploying the clone if necessary. Single-pack curators wrap their one pack:defineComposite({ modules: [vaultsfyi], chainId, env, publicClient, policyAddress }). Returns aShieldClientwith setup functions (.setParams(paramsByShortId)and.uploadSecrets(secretsByShortId)) for configuring theShieldcontract and the execution entrypoint.sendCall({ to, data, functionSignature, prepareQueryOptions })that runs the composite's aggregatedprepareQuery → wasmArgsSchema → newt_createTask → shield.executeDirecton every call.- Deployment process Configuration order:
defineComposite → createShield → setParams → uploadSecrets → sendCallis needed for first-time configuration ONLY. By passing a configured Shield contract, the client detects, validates, and binds to the existing deployment. FunctionssetParamsanduploadSecretscan be called later to update configuration. Use parammustDeployto ensure not binding to existing contracts that you didn't deploy. Use paramexpectedParamswithskipPolicyBindingCheck: falseto ensure that the configuration is expected. Incrementversionto replace unusable or abandoned shield deployments. For testing on a non-production network where a pack's external data source has no coverage (e.g. vaults.fyi indexes mainnets only), a pack may expose its own data-source override insendCall'sprepareQueryOptions(e.g.{ vaultsfyi: { network, vaultAddress } }) to point its lookup at a real mainnet target while the Shield executes on a testnet — a testing affordance only; leave it unset in production so the policy describes the same vault it gates. NewtonShield— lower-level runtime exposed via.guardedCall({ to, data, functionSignature, wasmArgs }). Use this when you want to drive intent submission yourself.- Policy packs ship as separate npm packages. Install only the ones you integrate, e.g.
pnpm add @newton-xyz/policy-pack-vaultsfyi. The SDK declares@newton-xyz/policy-pack-sharedas a peer dep. Build a composite withdefineCompositefrom@newton-xyz/policy-pack-shared, then pass it tocreateShieldas thepackargument. - A typed error hierarchy (
PolicyDeniedError,GatewayHttpError,GatewayRpcError,GatewayTimeoutError,NewtonTaskEvaluationError,TransactionFailedError,InvalidConfigurationError,ConcurrentIntentError,UnsupportedChainError). - Browser-safe core. No
node:*imports.
Install
pnpm add @newton-xyz/vaultkit @newton-xyz/policy-pack-shared viem zod
# Plus one or more policy packs:
pnpm add @newton-xyz/policy-pack-vaultsfyi@newton-xyz/policy-pack-shared, viem, and zod are peer dependencies — the SDK uses whatever versions your application has installed. Per-pack packages (@newton-xyz/policy-pack-vaultsfyi, @newton-xyz/policy-pack-blockaid, …) are independent: install only the packs you integrate. Vendor SDKs (@morpho-org/blue-sdk-viem, etc.) are also peer deps; install only the ones you use.
Supported chains
SUPPORTED_CHAINS (in sdk/src/chains.ts) covers two mainnets and two testnets:
| Chain | Chain id | Network | Status |
| ------------- | ----------- | ------- | ----------------------------------------------- |
| Ethereum | 1 | Mainnet | Deployed (prod) |
| Base | 8453 | Mainnet | Deployed (prod) |
| Sepolia | 11155111 | Testnet | Deployed (stagef + prod) |
| Base Sepolia | 84532 | Testnet | Deployed (stagef + prod) |
Ethereum and Base mainnet are deployed on prod (the first mainnet rollout); their audit-trail JSON lives at deployments/{1,8453}-prod.json. See docs/deployment/chains.md for the add-a-chain procedure.
The SDK's per-chain registry lives in sdk/src/deployments.ts (SHIELD_DEPLOYMENTS, keyed by (chainId, env)). The audit trail per (chainId, env) slot lives in deployments/{chainId}-{env}.json at the repo root — those JSON files travel with the source repo and are not loaded at SDK runtime. Calling createShield on an unsupported chain throws UnsupportedChainError; calling against a supported chain with no deployment recorded yet throws ShieldDeploymentNotFoundError. Either way, the SDK fails before any tx is sent.
Repository structure
sdk/
├── src/
│ ├── index.ts ← top-level exports
│ ├── builder.ts ← `createShield(...)` factory
│ ├── pack-runtime.ts ← `buildIntentArgs` / `encodePackParams` helpers
│ ├── shield.ts ← `NewtonShield` low-level runtime
│ ├── factory.ts ← `predictShieldAddress` (CREATE2 derivation)
│ ├── gateway.ts ← Newton Gateway HTTP/JSON-RPC client
│ └── vendors/<name>/ ← vendor module subpath modules
├── test/
├── package.json
├── tsconfig.json
├── tsup.config.ts ← ESM + CJS + .d.ts build
├── vitest.config.ts
└── README.mdPack code lives in newton-policy-packs; each pack publishes as its own @newton-xyz/policy-pack-<name> npm package on its own release cadence.
Local development
Requires Node ≥22 and pnpm ≥10. The SDK lives in a pnpm monorepo at the repo root.
# from repo root
pnpm install
pnpm --filter @newton-xyz/vaultkit build
pnpm --filter @newton-xyz/vaultkit typecheck
pnpm --filter @newton-xyz/vaultkit testTo test against a consumer app without publishing:
"@newton-xyz/vaultkit": "link:../vaultkit/sdk"Versioning
Changesets for semver bumps. Public-surface changes get a .changeset/*.md entry per PR via pnpm changeset.
Vendor SDK breaking changes cascade through. Peer-dep versions are tracked, and any vendor-side breaking change is treated as a VaultKit SDK semver-major.
License
Apache-2.0
