# Newton Protocol SDK Reference

Official TypeScript SDK for the Newton Protocol. This page provides a complete reference for all exported methods, types, interfaces, and utilities in the `@newton-xyz/sdk` package.

:::info
The SDK integrates with [viem](https://viem.sh) by extending `PublicClient` and `WalletClient` instances with Newton-specific actions. Make sure you are familiar with viem basics before proceeding.
:::

***

## Installation

:::code-group
```bash [npm]
npm install @newton-xyz/sdk
```

```bash [pnpm (recommended)]
pnpm add @newton-xyz/sdk
```

```bash [yarn]
yarn add @newton-xyz/sdk
```
:::

**Requirements:**

* Node.js >= 20
* Package manager: pnpm >= 9 (recommended)

**Dependencies:**

| Package         | Version | Purpose                        |
| --------------- | ------- | ------------------------------ |
| `viem`          | ^2.35.1 | Ethereum client library        |
| `jose`          | ^6.0.13 | JWT / cryptographic operations |
| `eventemitter3` | ^4.0.4  | Event handling                 |

***

## Overview

The SDK is organized into two main client extensions:

| Extension                   | Purpose                                                | Client Type    |
| --------------------------- | ------------------------------------------------------ | -------------- |
| `newtonPublicClientActions` | Read-only operations (query tasks, policy state)       | `PublicClient` |
| `newtonWalletClientActions` | Write operations (submit evaluations, manage policies) | `WalletClient` |

For a step-by-step walkthrough of integrating these into your application, see the [Integration Guide](/developers/guides/integration-guide). For the underlying JSON-RPC methods the SDK calls, see the [RPC API Reference](/developers/reference/rpc-api).

***

## Setup & Initialization

:::info
Newton Protocol currently supports **Ethereum Sepolia** (chain ID `11155111`), **Base Sepolia** (chain ID `84532`), **Ethereum Mainnet** (chain ID `1`), and **Base** (chain ID `8453`). Pass the corresponding `chain` object from `viem/chains` when constructing your clients.
:::

### newtonPublicClientActions

Extends a viem `PublicClient` with Newton Protocol read methods.

```ts twoslash
import { createPublicClient, http } from 'viem';
import { sepolia, baseSepolia, base } from 'viem/chains';
import { newtonPublicClientActions } from '@newton-xyz/sdk';
// ---cut---
const publicClient = createPublicClient({
  chain: sepolia,        // or baseSepolia, base, mainnet
  transport: http('https://eth-sepolia.g.alchemy.com/v2/demo'),
}).extend(
  newtonPublicClientActions({
    policyContractAddress: '0x1234567890123456789012345678901234567890', // optional
  })
);
```

**Signature:**

```ts
function newtonPublicClientActions(
  options?: {
    policyContractAddress?: Address;
  },
  overrides?: SdkOverrides
): (publicClient: PublicClient) => NewtonPublicClientMethods;
```

**Parameters:**

| Parameter                       | Type           | Required | Description                                           |
| ------------------------------- | -------------- | -------- | ----------------------------------------------------- |
| `options.policyContractAddress` | `Address`      | No       | Scopes all policy read calls to this contract address |
| `overrides`                     | `SdkOverrides` | No       | Override default SDK configuration                    |

***

### newtonWalletClientActions

Extends a viem `WalletClient` with Newton Protocol write methods.

```ts twoslash
import { createWalletClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts'
import { sepolia, baseSepolia, base } from 'viem/chains';
import { newtonWalletClientActions } from '@newton-xyz/sdk';
// ---cut---
const walletClient = createWalletClient({
  account: privateKeyToAccount('0x' + '1'.repeat(64) as `0x${string}`),
  chain: sepolia,        // or baseSepolia, base, mainnet
  transport: http('https://eth-sepolia.g.alchemy.com/v2/demo'),
}).extend(
  newtonWalletClientActions({
    apiKey: 'test-api-key',
    policyContractAddress: '0x1234567890123456789012345678901234567890', // optional
  })
);
```

**Signature:**

```ts
function newtonWalletClientActions(
  config: {
    apiKey: string;
    policyContractAddress?: Address;
  },
  overrides?: SdkOverrides
): (walletClient: WalletClient) => NewtonWalletClientMethods;
```

**Parameters:**

| Parameter                      | Type           | Required | Description                                          |
| ------------------------------ | -------------- | -------- | ---------------------------------------------------- |
| `config.apiKey`                | `string`       | Yes      | Newton Protocol API key for gateway authentication   |
| `config.policyContractAddress` | `Address`      | No       | Default policy contract address for write operations |
| `overrides`                    | `SdkOverrides` | No       | Override default SDK configuration                   |

:::note
Your API key authenticates requests to the Newton Gateway. Keep it secret and never expose it in client-side code.
:::

***

### SdkOverrides

Optional configuration to override default SDK endpoints and contract addresses.

```ts
interface SdkOverrides {
  gatewayApiUrl?: string;
  taskManagerAddress?: Address;
  attestationValidatorAddress?: Address;
  newtonIdpUrl?: string;
  identityRegistry?: Address;
}
```

| Field                         | Type      | Description                                  |
| ----------------------------- | --------- | -------------------------------------------- |
| `gatewayApiUrl`               | `string`  | Custom Newton Gateway API URL                |
| `taskManagerAddress`          | `Address` | Custom TaskManager contract address          |
| `attestationValidatorAddress` | `Address` | Custom AttestationValidator contract address |
| `newtonIdpUrl`                | `string`  | Custom Newton identity provider URL          |
| `identityRegistry`            | `Address` | Custom IdentityRegistry contract address     |

***

## Wallet Client Methods (Write)

These methods are available after extending a `WalletClient` with `newtonWalletClientActions`.

### submitEvaluationRequest

Submits an intent evaluation request to the Newton Protocol via the gateway. The task is created on-chain and operators evaluate the intent against the policy. Returns a `PendingTaskBuilder` that can be used to await the task response.

```ts
const { result, waitForTaskResponded } = await walletClient.submitEvaluationRequest({
  policyClient: '0x...',
  intent: {
    from: '0x...',
    to: '0x...',
    value: '0x0',
    data: '0x...',
    chainId: '0xaa36a7', // Ethereum Sepolia (11155111)
    functionSignature: '0x...',
  },
  timeout: 60000,
});

console.log(result.taskId);  // Hex
console.log(result.txHash);  // Hex

// Optionally wait for the on-chain response
const response = await waitForTaskResponded({ timeoutMs: 120000 });
```

**Signature:**

```ts
submitEvaluationRequest(
  args: SubmitEvaluationRequestParams
): Promise<{ result: { taskId: Hex; txHash: Hex } } & PendingTaskBuilder>
```

**Parameters:**

| Parameter                  | Type               | Required | Description                                                                 |
| -------------------------- | ------------------ | -------- | --------------------------------------------------------------------------- |
| `policyClient`             | `Address`          | Yes      | The policy client contract address                                          |
| `intent`                   | `IntentFromParams` | Yes      | The intent to evaluate                                                      |
| `timeout`                  | `number`           | Yes      | Request timeout in seconds                                                  |
| `proofCid`                 | `string`           | No       | IPFS CID of a TLSNotary presentation proof for zkTLS-backed evaluation      |
| `includeValidateCalldata`  | `boolean`          | No       | Include ABI-encoded `validateAttestationDirect` calldata in the response    |

**Returns:** An object containing:

* `result.taskId` (`Hex`) -- The unique task identifier
* `result.txHash` (`Hex`) -- The transaction hash
* `waitForTaskResponded({ timeoutMs? })` -- A method to await the on-chain attestation result

:::note
The `validate_calldata` and `operator_errors` fields are available on the raw `GatewayCreateTaskResult` returned by the `newt_createTask` RPC method (see the [RPC API Reference](/developers/reference/rpc-api)). These fields are not surfaced by the SDK's `submitEvaluationRequest` or `evaluateIntentDirect` wrappers — call the gateway RPC directly when you need them.
:::

***

### evaluateIntentDirect

Evaluates an intent directly through the gateway without waiting for on-chain task response confirmation. Results are intended for use with `validateAttestationDirect` on `NewtonPolicyClient` (`NewtonProverTaskManagerShared`).

```ts
const domain = await readEip712Domain(policyClient, publicClient);
if (!domain) {
  throw new Error(
    "This policy client does not expose an EIP-712 domain, so the app cannot sign an intent for it.",
  );
}

const intent = {
  from: account.address,
  to: '0x...',
  value: '0x0',
  data: '0x',
  chainId: 11155111,
  functionSignature: '0x',
} as const;

const intentSignature = await walletClient.signTypedData({
  account,
  domain,
  types: {
    Intent: [
      { name: 'from', type: 'address' },
      { name: 'to', type: 'address' },
      { name: 'value', type: 'uint256' },
      { name: 'data', type: 'bytes' },
      { name: 'chainId', type: 'uint256' },
      { name: 'functionSignature', type: 'bytes' },
    ],
  },
  primaryType: 'Intent',
  message: {
    ...intent,
    value: BigInt(intent.value),
    chainId: BigInt(intent.chainId),
  },
});

const { result } = await walletClient.evaluateIntentDirect({
  policyClient,
  intent,
  intentSignature,
  timeout: 30000,
});

console.log(result.evaluationResult); // boolean
console.log(result.task);             // Task object
console.log(result.taskResponse);     // Raw task response
console.log(result.blsSignature);     // BLS signature data
```

**Signature:**

```ts
evaluateIntentDirect(
  args: SubmitEvaluationRequestParams
): Promise<{
  result: {
    evaluationResult: boolean;
    task: Task;
    taskResponse: unknown;
    blsSignature: unknown;
  };
}>
```

**Parameters:**

| Parameter      | Type               | Required | Description                                                                                        |
| -------------- | ------------------ | -------- | -------------------------------------------------------------------------------------------------- |
| `policyClient` | `Address`          | Yes      | The policy client contract address                                                                 |
| `intent`       | `IntentFromParams` | Yes      | The intent to evaluate. `chainId` must be `11155111` (Ethereum Sepolia), `84532` (Base Sepolia), or `8453` (Base). |
| `intentSignature` | `Hex`           | No       | EIP-712 signature of the exact intent. Optional in the SDK type, but required by policies and identity flows that read `input.intent_signature`. |
| `timeout`      | `number`           | No       | Request timeout in milliseconds                                                                    |

**Returns:**

* `result.evaluationResult` (`boolean`) -- Whether the intent was allowed by the policy
* `result.task` (`Task`) -- The full task object
* `result.taskResponse` -- The raw task response from the operator
* `result.blsSignature` -- The BLS aggregate signature

:::warning
Some policy clients and identity-backed flows require `intentSignature` even though it is optional in the base request type. If you omit it or pass `"0x"`, the gateway can fail before policy evaluation with `Failed to encode intent signature: 0x reason: expected exactly 65 bytes`.
:::

Read the EIP-712 domain from the policy client whenever possible. Dashboard-deployed clients expose EIP-5267 `eip712Domain()`, which binds the signature to the correct `name`, `version`, `chainId`, and `verifyingContract`.

```ts
import type { Address } from 'viem';

const EIP712_DOMAIN_ABI = [
  {
    type: 'function',
    name: 'eip712Domain',
    stateMutability: 'view',
    inputs: [],
    outputs: [
      { name: 'fields', type: 'bytes1' },
      { name: 'name', type: 'string' },
      { name: 'version', type: 'string' },
      { name: 'chainId', type: 'uint256' },
      { name: 'verifyingContract', type: 'address' },
      { name: 'salt', type: 'bytes32' },
      { name: 'extensions', type: 'uint256[]' },
    ],
  },
] as const;

export async function readEip712Domain(
  policyClient: Address,
  publicClient,
) {
  try {
    const [, name, version, chainId, verifyingContract] =
      await publicClient.readContract({
        address: policyClient,
        abi: EIP712_DOMAIN_ABI,
        functionName: 'eip712Domain',
      });

    return {
      name,
      version,
      chainId: Number(chainId),
      verifyingContract,
    };
  } catch {
    return null;
  }
}
```

If you deploy a custom policy client that does not implement EIP-5267, hardcoded signing domains must match the contract's `EIP712(name, version)` constructor values and the deployed policy client address.

***

### submitIntentAndSubscribe

Submits a task via `newt_sendTask` and opens a WebSocket connection to receive the evaluation result. Results are intended for use with `validateAttestation` on `NewtonProverTaskManager` (the on-chain task verification path).

```ts
const { result, ws } = await walletClient.submitIntentAndSubscribe({
  policyClient: '0x...',
  intent: {
    from: '0x...',
    to: '0x...',
    value: '0x0',
    data: '0x...',
    chainId: 11155111,
    functionSignature: '0x...',
  },
  timeout: 30,
});

console.log(result.task_id);             // Hex task identifier
console.log(result.subscription_topic);  // WebSocket topic

// Listen for the task response
ws.onmessage = (event) => {
  const taskResponse = JSON.parse(event.data);
  console.log(taskResponse);
};
```

**Signature:**

```ts
submitIntentAndSubscribe(
  args: SubmitEvaluationRequestParams
): Promise<{
  result: SubmitIntentResult;
  ws: WebSocket;
}>
```

**Parameters:**

| Parameter      | Type               | Required | Description                                                                                        |
| -------------- | ------------------ | -------- | -------------------------------------------------------------------------------------------------- |
| `policyClient` | `Address`          | Yes      | The policy client contract address                                                                 |
| `intent`       | `IntentFromParams` | Yes      | The intent to evaluate. `chainId` must be `11155111` (Ethereum Sepolia), `84532` (Base Sepolia), or `8453` (Base). |
| `timeout`      | `number`           | No       | Request timeout in seconds                                                                         |

**Returns:**

* `result.message` (`string`) -- Status message from the gateway
* `result.subscription_topic` (`string`) -- WebSocket topic to subscribe to for task updates
* `result.task_id` (`Hex`) -- 32-byte task identifier
* `result.timestamp` (`number`) -- Task creation timestamp
* `ws` (`WebSocket`) -- Active WebSocket connection subscribed to the task topic

**`SubmitIntentResult` type:**

```ts
interface SubmitIntentResult {
  message: string;
  subscription_topic: string;
  task_id: Hex;
  timestamp: number;
}
```

:::note
Use `submitIntentAndSubscribe` when you need on-chain task verification via `NewtonProverTaskManager.validateAttestation`. Use `evaluateIntentDirect` for the simpler direct validation path via `PolicyClient.validateAttestationDirect`.
:::

***

### simulateTask

Simulates task evaluation (`newt_simulateTask`). Forwards the task to an operator and returns an allow/deny result without executing on-chain. See the [RPC API Reference](/developers/reference/rpc-api) for the underlying JSON-RPC method.

```ts
const result = await walletClient.simulateTask({
  intent: {
    from: '0x...',
    to: '0x...',
    value: '0x0',
    data: '0x...',
    chainId: 11155111, // Ethereum Sepolia; use 84532 for Base Sepolia or 8453 for Base
    functionSignature: '0x...',
  },
  policyTaskData: {
    policyId: '0x...',
    policyAddress: '0x...',
    policy: '0x...',
    policyData: [
      {
        wasmArgs: '0x',
        data: '0x...',
        attestation: '0x...',
        policyDataAddress: '0x...',
        expireBlock: 999999,
      },
    ],
  },
});

console.log(result.success);
console.log(result.result?.allow);
console.log(result.result?.reason);
console.log(result.error);
```

**Signature:**

```ts
simulateTask(args: SimulateTaskParams): Promise<SimulateTaskResult>
```

***

### simulatePolicy

Simulates full Rego policy evaluation (`newt_simulatePolicy`). Tests a policy with a sample intent and policy data. May require ownership if `PolicyData` uses stored secrets.

```ts
const result = await walletClient.simulatePolicy({
  policyClient: '0x...',
  policy: '<rego-policy-string>',
  intent: {
    from: '0x...',
    to: '0x...',
    value: '0x0',
    data: '0x...',
    chainId: 11155111, // Ethereum Sepolia; use 84532 for Base Sepolia or 8453 for Base
    functionSignature: '0x...',
  },
  policyData: [
    { policyDataAddress: '0x...' },
  ],
  policyParams: { max_amount: 1000 },
  entrypoint: 'newton/policy/allow',
});

console.log(result.success);
console.log(result.evaluation_result);
console.log(result.error);
```

**Signature:**

```ts
simulatePolicy(args: SimulatePolicyParams): Promise<SimulatePolicyResult>
```

***

### simulatePolicyData

Simulates PolicyData WASM execution (`newt_simulatePolicyData`) with caller-provided secrets. No ownership verification is required.

```ts
const result = await walletClient.simulatePolicyData({
  policyDataAddress: '0x...',
  secrets: '<secrets-json-string>',
  wasmArgs: '0x...',
  chainId: 11155111, // required
});

console.log(result.success);
console.log(result.policy_data?.specifier);
console.log(result.policy_data?.data);
```

**Signature:**

```ts
simulatePolicyData(
  args: SimulatePolicyDataParams
): Promise<SimulatePolicyDataResult>
```

***

### simulatePolicyDataWithClient

Simulates PolicyData WASM execution (`newt_simulatePolicyDataWithClient`) using stored secrets for a policy client. Requires ownership of the policy client.

```ts
const result = await walletClient.simulatePolicyDataWithClient({
  policyDataAddress: '0x...',
  policyClient: '0x...',
  wasmArgs: '0x...',
});

console.log(result.success);
console.log(result.policy_data?.specifier);
```

**Signature:**

```ts
simulatePolicyDataWithClient(
  args: SimulatePolicyDataWithClientParams
): Promise<SimulatePolicyDataWithClientResult>
```

***

### initialize

Initializes a Newton Policy contract with the given configuration. This is a one-time setup call.

The contract requires `keccak256` of the Rego policy bytes as `_policyCodeHash` so the on-chain hash matches the policy referenced by `policyCid`. Provide it one of two ways:

* `policyCodeHash` -- pre-computed hex hash (from `policy_cids.json` or another out-of-band source). Takes precedence when both are set.
* `policyBytes` -- the raw Rego policy bytes; the SDK computes `keccak256` for you. Useful when fetching from IPFS via `policyCid`, reading a local file, or any other transport.

```ts
const txHash = await walletClient.initialize({
  factory: '0x...',
  entrypoint: 'newton/policy/allow',
  policyCid: 'bafyrei...',
  schemaCid: 'bafyrei...',
  policyData: ['0x...', '0x...'],
  metadataCid: 'bafyrei...',
  owner: '0x...',
  policyBytes: await fetchPolicyBytes(policyCid),
});
```

**Signature:**

```ts
type InitializePolicyArgs = {
  factory: Address;
  entrypoint: string;
  policyCid: string;
  schemaCid: string;
  policyData: Address[];
  metadataCid: string;
  owner: Address;
} & ({ policyCodeHash: Hex } | { policyBytes: Uint8Array });

initialize(args: InitializePolicyArgs): Promise<`0x${string}`>
```

**Parameters:**

| Parameter        | Type         | Required          | Description                                                              |
| ---------------- | ------------ | ----------------- | ------------------------------------------------------------------------ |
| `factory`        | `Address`    | Yes               | Address of the deploying factory contract                                |
| `entrypoint`     | `string`     | Yes               | Policy entrypoint path (e.g., `"newton/policy/allow"`)                   |
| `policyCid`      | `string`     | Yes               | Content identifier (CID) of the policy WASM                              |
| `schemaCid`      | `string`     | Yes               | Content identifier (CID) of the policy schema                            |
| `policyData`     | `Address[]`  | Yes               | Array of PolicyData contract addresses                                   |
| `metadataCid`    | `string`     | Yes               | Content identifier (CID) of the policy metadata                          |
| `owner`          | `Address`    | Yes               | Owner address of the policy contract                                     |
| `policyCodeHash` | `Hex`        | One of these two  | Pre-computed `keccak256` of the Rego policy bytes                        |
| `policyBytes`    | `Uint8Array` | One of these two  | Raw Rego policy bytes; SDK computes `keccak256(policyBytes)` for you     |

**Returns:** `` `0x${string}` `` -- The transaction hash.

***

### renounceOwnership

Renounces ownership of the policy contract. After calling this, no one will be able to perform owner-restricted actions.

:::note
This action is irreversible. Once ownership is renounced, administrative operations on the policy contract can never be performed again.
:::

```ts
const txHash = await walletClient.renounceOwnership();
```

**Signature:**

```ts
renounceOwnership(): Promise<`0x${string}`>
```

***

### transferOwnership

Transfers ownership of the policy contract to a new address.

```ts
const txHash = await walletClient.transferOwnership({
  newOwner: '0x...',
});
```

**Signature:**

```ts
transferOwnership(args: {
  newOwner: Address;
}): Promise<`0x${string}`>
```

***

### Identity Methods

These methods interact with the Newton Identity Provider for verified credential flows. They open a popup window for user interaction.

#### connectIdentityWithNewton

Connects the user's identity with Newton via the identity provider popup.

```ts
await walletClient.connectIdentityWithNewton({
  appWalletAddress: '0x...',
  appClientAddress: '0x...',
});
```

**Signature:**

```ts
connectIdentityWithNewton(args: {
  appWalletAddress: Address;
  appClientAddress: Address;
}): Promise<unknown>
```

***

#### registerUserData

Registers KYC user data through the identity provider popup.

```ts
await walletClient.registerUserData({
  userData: {
    status: 'approved',
    selected_country_code: 'US',
    address_subdivision: 'CA',
    address_country_code: 'US',
    birthdate: '1990-01-15',
    expiration_date: '2030-01-15',
    issue_date: '2020-01-15',
    issuing_authority: 'US_DL',
  },
  appIdentityDomain: '0x...',
  policyClient: '0xYourPolicyClientAddress',
});
```

**Signature:**

```ts
registerUserData(args: {
  userData: KycUserData;
  appIdentityDomain: Hex;
  policyClient: Address;
}): Promise<unknown>
```

***

#### linkApp

Links an application to the user's Newton identity.

```ts
await walletClient.linkApp({
  appWalletAddress: '0x...',
  appClientAddress: '0x...',
  appIdentityDomain: '0x...',
});
```

**Signature:**

```ts
linkApp(args: {
  appWalletAddress: Address;
  appClientAddress: Address;
  appIdentityDomain: Hex;
}): Promise<unknown>
```

***

#### unlinkApp

Unlinks an application from the user's Newton identity.

```ts
await walletClient.unlinkApp({
  appWalletAddress: '0x...',
  appClientAddress: '0x...',
  appIdentityDomain: '0x...',
});
```

**Signature:**

```ts
unlinkApp(args: {
  appWalletAddress: Address;
  appClientAddress: Address;
  appIdentityDomain: Hex;
}): Promise<unknown>
```

***

### Privacy Methods

These methods are available on the wallet client for privacy-preserving policy evaluation using client-side HPKE encryption. They are also exported as standalone functions from the package.

#### getPrivacyPublicKey

Fetches the Newton Gateway's X25519 HPKE public key for encrypting data.

```ts
const { public_key, key_type, encryption_suite } = await walletClient.getPrivacyPublicKey();
```

**Signature:**

```ts
getPrivacyPublicKey(): Promise<PrivacyPublicKeyResponse>
```

**Returns:**

* `public_key` (`string`) -- The gateway's X25519 public key (hex-encoded)
* `key_type` (`string`) -- Key type identifier
* `encryption_suite` (`string`) -- HPKE suite identifier

***

#### createSecureEnvelope

Creates an HPKE-encrypted envelope from plaintext. Runs entirely offline with zero network calls.

```ts
const signingKeyPair = walletClient.generateSigningKeyPair();
const { envelope, signature, senderPublicKey } = await walletClient.createSecureEnvelope(
  {
    plaintext: { secret: 'value' },
    policyClient: '0x...',
    chainId: 11155111,
    recipientPublicKey: '<gateway-public-key>',
  },
  signingKeyPair.privateKey // Uint8Array from generateSigningKeyPair()
);
```

**Signature:**

```ts
createSecureEnvelope(
  args: CreateSecureEnvelopeParams,
  signingKey: Uint8Array
): Promise<SecureEnvelopeResult>
```

**Parameters:**

| Parameter              | Type     | Required | Description                                    |
| ---------------------- | -------- | -------- | ---------------------------------------------- |
| `args.plaintext`       | `Uint8Array \| string \| Record<string, unknown>` | Yes | Data to encrypt (objects are JSON-stringified) |
| `args.policyClient`    | `Address`| Yes      | PolicyClient address (bound via AAD)           |
| `args.chainId`         | `number` | Yes      | Chain ID (bound via AAD)                       |
| `args.recipientPublicKey` | `string` | Yes   | Gateway's X25519 public key                    |
| `signingKey`           | `Uint8Array` | Yes  | Ed25519 private key seed (32 bytes)            |

***

#### getSecretsPublicKey

Fetches the Newton Gateway's X25519 HPKE public key for encrypting WASM secrets. In threshold DKG mode, this returns a different key than `getPrivacyPublicKey`.

```ts
const { public_key, key_type, encryption_suite } = await walletClient.getSecretsPublicKey();
```

**Signature:**

```ts
getSecretsPublicKey(): Promise<SecretsPublicKeyResponse>
```

**Returns:**

* `public_key` (`string`) -- The gateway's X25519 public key (hex-encoded)
* `key_type` (`string`) -- Key type identifier
* `encryption_suite` (`string`) -- HPKE suite identifier

***

#### uploadIdentityEncrypted

Uploads HPKE-encrypted identity data to the Newton Gateway. The caller must provide a pre-built SecureEnvelope (via `createSecureEnvelope`) and an EIP-712 signature of the envelope JSON from the identity owner. The gateway stores the envelope and returns a `data_ref_id` + gateway signature for the on-chain `registerIdentityData` call.

```ts
const { data_ref_id, gateway_signature, deadline } = await walletClient.uploadIdentityEncrypted({
  identityOwner: '0x...',
  identityOwnerSig: '0x...', // EIP-712 signature of the envelope JSON
  envelope: JSON.stringify(envelope),
  identityDomain: identityDomainHash('kyc'),
  chainId: 11155111,
});
```

**Signature:**

```ts
uploadIdentityEncrypted(
  args: UploadIdentityEncryptedParams
): Promise<UploadIdentityEncryptedResponse>
```

**Returns:**

* `data_ref_id` (`string`) -- Content-hash data reference ID: `keccak256(envelope_json_bytes)`
* `gateway_signature` (`string`) -- Gateway EIP-712 signature for `registerIdentityData` on-chain call
* `deadline` (`number`) -- Signature expiration (unix timestamp)

***

#### getIdentityEncrypted

Fetches encrypted identity data by its content-hash reference ID. Used to resolve a `data_ref_id` (stored on-chain in IdentityRegistry) back to the encrypted data blob (stored off-chain in the gateway).

```ts
const { envelope, identity_domain, identity_owner } = await walletClient.getIdentityEncrypted({
  dataRefId: 'abc123...',
});
```

**Signature:**

```ts
getIdentityEncrypted(
  args: { dataRefId: string }
): Promise<GetIdentityEncryptedResult>
```

**Returns:**

* `envelope` (`string`) -- The HPKE-encrypted identity data as a SecureEnvelope JSON string
* `identity_domain` (`string`) -- The identity domain this data was registered under
* `identity_owner` (`string`) -- The identity owner address

***

#### generateSigningKeyPair

Generates a random Ed25519 key pair for privacy authorization signatures.

```ts
const { privateKey, publicKey } = walletClient.generateSigningKeyPair();
// Both are 32-byte hex strings without 0x prefix
```

**Signature:**

```ts
generateSigningKeyPair(): Ed25519KeyPair
```

:::note
This is a **synchronous** method. Keys are generated locally and never sent to any server.
:::

***

#### storeEncryptedSecrets

Encrypts plaintext secrets client-side with HPKE and uploads the envelope to the gateway for a PolicyClient's PolicyData oracle. The gateway's X25519 public key is fetched automatically if not provided.

```ts
const { success } = await walletClient.storeEncryptedSecrets({
  policyClient: '0x...',
  policyDataAddress: '0x...',
  plaintext: { API_KEY: 'sk-...', ENDPOINT: 'https://api.example.com' },
  chainId: 11155111,
});
```

**Signature:**

```ts
storeEncryptedSecrets(
  args: StoreEncryptedSecretsParams
): Promise<StoreEncryptedSecretsResponse>
```

***

#### signPrivacyAuthorization

Computes dual Ed25519 signatures (user + app) for privacy-enabled task creation. Runs entirely offline.

```ts
const { userSignature, appSignature, userPublicKey, appPublicKey } =
  walletClient.signPrivacyAuthorization({
    policyClient: '0x...',
    intentHash: '0x...',
    encryptedDataRefs: ['ref-id-1', 'ref-id-2'],
    userSigningKey: '<user-ed25519-private-key>',
    appSigningKey: '<app-ed25519-private-key>',
  });
```

**Signature:**

```ts
signPrivacyAuthorization(
  args: SignPrivacyAuthorizationParams
): PrivacyAuthorizationResult
```

:::note
This is a **synchronous** method. Signatures are computed locally.
:::

***

### Webhook Methods

#### registerWebhook

Registers a webhook URL to receive task failure notifications. The gateway sends HMAC-SHA256 signed payloads to the registered URL when tasks fail.

```ts
const { success, message } = await walletClient.registerWebhook({
  url: 'https://example.com/newton-webhook',
  secret: 'my-hmac-secret',
  timeoutSeconds: 10,
  maxRetries: 3,
  failureTypes: ['timeout', 'quorum_not_reached'],
});
```

**Signature:**

```ts
registerWebhook(args: RegisterWebhookParams): Promise<RegisterWebhookResult>
```

**Parameters:**

| Parameter       | Type                | Required | Description                                                       |
| --------------- | ------------------- | -------- | ----------------------------------------------------------------- |
| `url`           | `string`            | Yes      | Webhook URL (must be HTTPS, or `http://localhost` for testing)    |
| `secret`        | `string`            | No       | HMAC secret for payload signing (recommended)                     |
| `timeoutSeconds`| `number`            | No       | Request timeout in seconds (default: 10)                          |
| `maxRetries`    | `number`            | No       | Maximum retry attempts (default: 3)                               |
| `failureTypes`  | `TaskFailureType[]` | No       | Failure types to notify about (default: all)                      |

***

#### unregisterWebhook

Removes the registered webhook for the current API key.

```ts
const { success, message } = await walletClient.unregisterWebhook();
```

**Signature:**

```ts
unregisterWebhook(): Promise<UnregisterWebhookResult>
```

***

### Identity Methods

These methods handle identity data registration and identity-to-PolicyClient linking via direct contract calls to the IdentityRegistry. They are also exported as standalone functions from the package.

#### registerIdentityData

Register an identity data reference on-chain. The identity owner (caller) submits a `data_ref_id` obtained from the gateway's `newt_uploadIdentityEncrypted` RPC, along with the gateway's co-signature and deadline.

```ts
await walletClient.registerIdentityData({
  identityDomain: identityDomainHash('kyc'),
  dataRefId: 'QmEncryptedDataRef...',
  gatewaySignature: '0x...', // from newt_uploadIdentityEncrypted response
  deadline: 1700000000n,      // from newt_uploadIdentityEncrypted response
})
```

**Signature:**

```ts
registerIdentityData(args: RegisterIdentityDataParams): Promise<Hex>
```

The contract verifies the gateway signature against `REGISTER_IDENTITY_TYPEHASH` and checks that the signer is a registered task generator via `isTaskGenerator()`. Overwrites are allowed — users can update their identity data reference by calling this again.

***

#### linkIdentityAsSignerAndUser

Link identity data when the caller is both the identity owner and the client user. The simplest linking flow — no counterparty signatures needed.

```ts
await walletClient.linkIdentityAsSignerAndUser({
  policyClient: '0xPolicyClientAddress',
  identityDomains: [identityDomainHash('kyc')],
});
```

**Signature:**

```ts
linkIdentityAsSignerAndUser(args: LinkIdentityAsSignerAndUserParams): Promise<Hex>
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `policyClient` | `Address` | PolicyClient contract address |
| `identityDomains` | `Hex[]` | Array of domain hashes (use `identityDomainHash()`) |

**Returns:** Transaction hash (`Hex`).

#### linkIdentityAsSigner

Link identity data as the identity owner (signer). Requires a counterparty EIP-712 signature from the client user.

```ts
await walletClient.linkIdentityAsSigner({
  policyClient: '0xPolicyClientAddress',
  identityDomains: [identityDomainHash('kyc')],
  clientUser: '0xClientUserAddress',
  clientUserSignature: '0x...',
  clientUserNonce: 0n,
  clientUserDeadline: BigInt(Math.floor(Date.now() / 1000) + 3600),
});
```

**Signature:**

```ts
linkIdentityAsSigner(args: LinkIdentityAsSignerParams): Promise<Hex>
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `policyClient` | `Address` | PolicyClient contract address |
| `identityDomains` | `Hex[]` | Array of domain hashes |
| `clientUser` | `Address` | The client user's address |
| `clientUserSignature` | `Hex` | EIP-712 signature from the client user |
| `clientUserNonce` | `bigint` | Nonce for the client user's signature |
| `clientUserDeadline` | `bigint` | Deadline timestamp for the signature |

**Returns:** Transaction hash (`Hex`).

#### linkIdentityAsUser

Link identity data as the client user. Requires a counterparty EIP-712 signature from the identity owner.

```ts
await walletClient.linkIdentityAsUser({
  identityOwner: '0xIdentityOwnerAddress',
  policyClient: '0xPolicyClientAddress',
  identityDomains: [identityDomainHash('kyc')],
  identityOwnerSignature: '0x...',
  identityOwnerNonce: 0n,
  identityOwnerDeadline: BigInt(Math.floor(Date.now() / 1000) + 3600),
});
```

**Signature:**

```ts
linkIdentityAsUser(args: LinkIdentityAsUserParams): Promise<Hex>
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `identityOwner` | `Address` | The identity owner's address |
| `policyClient` | `Address` | PolicyClient contract address |
| `identityDomains` | `Hex[]` | Array of domain hashes |
| `identityOwnerSignature` | `Hex` | EIP-712 signature from the identity owner |
| `identityOwnerNonce` | `bigint` | Nonce for the identity owner's signature |
| `identityOwnerDeadline` | `bigint` | Deadline timestamp for the signature |

**Returns:** Transaction hash (`Hex`).

#### linkIdentity

Link identity data as a 3rd party with EIP-712 signatures from both the identity owner and the client user.

**Signature:**

```ts
linkIdentity(args: LinkIdentityParams): Promise<Hex>
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `identityOwner` | `Address` | The identity owner's address |
| `clientUser` | `Address` | The client user's address |
| `policyClient` | `Address` | PolicyClient contract address |
| `identityDomains` | `Hex[]` | Array of domain hashes |
| `identityOwnerSignature` | `Hex` | EIP-712 signature from the identity owner |
| `identityOwnerNonce` | `bigint` | Nonce for the identity owner's signature |
| `identityOwnerDeadline` | `bigint` | Deadline timestamp for the owner signature |
| `clientUserSignature` | `Hex` | EIP-712 signature from the client user |
| `clientUserNonce` | `bigint` | Nonce for the client user's signature |
| `clientUserDeadline` | `bigint` | Deadline timestamp for the user signature |

**Returns:** Transaction hash (`Hex`).

#### unlinkIdentityAsSigner

Unlink identity data as the identity owner (signer). Only the identity owner who created the link can call this.

```ts
await walletClient.unlinkIdentityAsSigner({
  clientUser: '0xClientUserAddress',
  policyClient: '0xPolicyClientAddress',
  identityDomains: [identityDomainHash('kyc')],
});
```

**Signature:**

```ts
unlinkIdentityAsSigner(args: UnlinkIdentityAsSignerParams): Promise<Hex>
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `clientUser` | `Address` | The client user whose link to remove |
| `policyClient` | `Address` | PolicyClient contract address |
| `identityDomains` | `Hex[]` | Array of domain hashes to unlink |

**Returns:** Transaction hash (`Hex`).

#### unlinkIdentityAsUser

Unlink identity data as the client user. Allows users to revoke links to their own account.

```ts
await walletClient.unlinkIdentityAsUser({
  policyClient: '0xPolicyClientAddress',
  identityDomains: [identityDomainHash('kyc')],
});
```

**Signature:**

```ts
unlinkIdentityAsUser(args: UnlinkIdentityAsUserParams): Promise<Hex>
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `policyClient` | `Address` | PolicyClient contract address |
| `identityDomains` | `Hex[]` | Array of domain hashes to unlink |

**Returns:** Transaction hash (`Hex`).

***

## Public Client Methods (Read)

These methods are available after extending a `PublicClient` with `newtonPublicClientActions`.

### Task Methods

#### waitForTaskResponded

Polls the on-chain `TaskManager` contract for a `TaskResponded` event for the given task ID.

```ts
const result = await publicClient.waitForTaskResponded({
  taskId: '0x...',
  timeoutMs: 120000,
});

console.log(result.taskResponse.evaluationResult);
console.log(result.attestation.expiration);
```

**Signature:**

```ts
waitForTaskResponded(args: {
  taskId: TaskId;
  timeoutMs?: number;
  abortSignal?: AbortSignal;
}): Promise<TaskResponseResult>
```

**Parameters:**

| Parameter     | Type             | Required | Description                       |
| ------------- | ---------------- | -------- | --------------------------------- |
| `taskId`      | `TaskId` (`Hex`) | Yes      | The task identifier to monitor    |
| `timeoutMs`   | `number`         | No       | Maximum wait time in milliseconds |
| `abortSignal` | `AbortSignal`    | No       | Signal to abort the polling       |

***

#### getTaskStatus

Queries the current status of a task from the on-chain contracts.

```ts
const status = await publicClient.getTaskStatus({ taskId: '0x...' });
// status: 'Created' | 'Responded' | 'AttestationSpent'
//       | 'AttestationExpired' | 'SuccessfullyChallenged'
```

**Signature:**

```ts
getTaskStatus(args: {
  taskId: TaskId;
}): Promise<TaskStatus>
```

***

#### getTaskResponseHash

Retrieves the response hash for a given task from the on-chain contract.

```ts
const hash = await publicClient.getTaskResponseHash({ taskId: '0x...' });
// hash: '0x...' | null
```

**Signature:**

```ts
getTaskResponseHash(args: {
  taskId: TaskId;
}): Promise<Hex | null>
```

***

### Policy Methods

#### getPolicyId

Returns the policy ID associated with a given client address.

```ts
const policyId = await publicClient.getPolicyId({ client: '0x...' });
```

**Signature:**

```ts
getPolicyId(args: { client: Address }): Promise<`0x${string}`>
```

***

#### getPolicyConfig

Returns the full policy configuration for a given policy ID, including parameters and expiration settings.

```ts
const config = await publicClient.getPolicyConfig({ policyId: '0x...' });
console.log(config.policyParams);
console.log(config.policyParamsHex);
console.log(config.expireAfter);
```

**Signature:**

```ts
getPolicyConfig(args: {
  policyId: `0x${string}`;
}): Promise<{
  policyParams: string | object;
  policyParamsHex: `0x${string}`;
  expireAfter: number;
}>
```

***

#### getPolicyCid

Returns the content identifier (CID) of the policy WASM stored in the contract.

```ts
const cid = await publicClient.getPolicyCid();
```

**Signature:**

```ts
getPolicyCid(): Promise<string>
```

***

#### getSchemaCid

Returns the content identifier (CID) of the policy schema.

```ts
const cid = await publicClient.getSchemaCid();
```

**Signature:**

```ts
getSchemaCid(): Promise<string>
```

***

#### getMetadataCid

Returns the content identifier (CID) of the policy metadata.

```ts
const cid = await publicClient.getMetadataCid();
```

**Signature:**

```ts
getMetadataCid(): Promise<string>
```

***

#### getEntrypoint

Returns the policy entrypoint string (e.g., `"newton/policy/allow"`).

```ts
const entrypoint = await publicClient.getEntrypoint();
```

**Signature:**

```ts
getEntrypoint(): Promise<string>
```

***

#### getPolicyData

Returns the array of PolicyData contract addresses associated with the policy.

```ts
const addresses = await publicClient.getPolicyData();
```

**Signature:**

```ts
getPolicyData(): Promise<Address[]>
```

***

#### isPolicyVerified

Returns whether the policy contract has been verified.

```ts
const verified = await publicClient.isPolicyVerified();
```

**Signature:**

```ts
isPolicyVerified(): Promise<boolean>
```

***

#### precomputePolicyId

Synchronously computes a policy ID from its constituent parts without making an on-chain call.

```ts
const policyId = publicClient.precomputePolicyId({
  policyContract: '0x...',
  policyData: ['0x...'],
  params: {
    admin: '0x...',
    allowed_actions: {},
    token_whitelist: {},
  },
  client: '0x...',
  policyUri: 'ipfs://...',
  schemaUri: 'ipfs://...',
  entrypoint: 'newton/policy/allow',
  expireAfter: 3600,
});
```

**Signature:**

```ts
precomputePolicyId(args: {
  policyContract: Address;
  policyData: Address[];
  params: Record<string, any>;
  client: Address;
  policyUri: string;
  schemaUri: string;
  entrypoint: string;
  expireAfter?: number;
  blockTimestamp?: bigint;
}): `0x${string}`
```

:::note
This is a **synchronous** method. It does not make any network or contract calls.
:::

***

#### Additional Policy Contract Readers

The following methods read individual fields from the policy contract. They all require a `policyContractAddress` to have been set during initialization (or passed via overrides).

| Method                               | Return Type                 | Description                                            |
| ------------------------------------ | --------------------------- | ------------------------------------------------------ |
| `owner()`                            | `Promise<Address>`          | Returns the owner address of the policy contract       |
| `factory()`                          | `Promise<Address>`          | Returns the factory address that deployed the contract |
| `entrypoint()`                       | `Promise<string>`           | Returns the policy entrypoint path                     |
| `clientToPolicyId({ client })`       | `Promise<\`0x$string\`>\` | Maps a client address to its policy ID                 |
| `policyData({ index })`              | `Promise<Address>`          | Returns the PolicyData contract address at the given index |
| `policyCid()`                        | `Promise<string>`           | Returns the policy CID                                 |
| `schemaCid()`                        | `Promise<string>`           | Returns the schema CID                                 |
| `metadataCid()`                      | `Promise<string>`           | Returns the metadata CID                               |
| `supportsInterface({ interfaceId })` | `Promise<boolean>`          | EIP-165 interface support check                        |

***

## Privacy Methods

Client-side HPKE encryption for privacy-preserving policy evaluation. These methods are available as wallet client actions and as standalone exports.

:::info
The privacy module uses X25519 KEM + HKDF-SHA256 + ChaCha20-Poly1305 (RFC 9180, Base mode) and is compatible with the Rust gateway implementation.
:::

### `createSecureEnvelope`

Encrypt plaintext into a SecureEnvelope using HPKE. This is a pure offline function — zero network calls. The ephemeral HPKE key is generated internally and zeroed after use.

**Standalone signature:**

```ts
createSecureEnvelope(
  params: CreateSecureEnvelopeParams,
  signingKey: Uint8Array
): Promise<SecureEnvelopeResult>
```

**Wallet client signature:**

```ts
client.createSecureEnvelope(params: CreateSecureEnvelopeParams, signingKey: Uint8Array): Promise<SecureEnvelopeResult>
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `params.plaintext` | `Uint8Array \| string \| Record<string, unknown>` | Data to encrypt |
| `params.policyClient` | `Address` | Policy client address this data is scoped to |
| `params.chainId` | `number` | Chain ID for AAD context binding |
| `params.recipientPublicKey` | `string` | Gateway's X25519 public key (hex, no 0x prefix) |
| `signingKey` | `Uint8Array` | Ed25519 private key seed (32 bytes). Caller owns the buffer lifecycle. |

**Returns:** `SecureEnvelopeResult` containing the encrypted envelope, Ed25519 signature, and sender public key.

:::warning
The caller is responsible for zeroing the `signingKey` buffer when done. The function copies the key internally and zeroes the copy after signing, but the original buffer remains in the caller's control.
:::

***

### `getPrivacyPublicKey`

Fetch the gateway's X25519 HPKE public key. Call this once and cache the result — the key only changes on gateway restart or key rotation.

**Standalone signature:**

```ts
getPrivacyPublicKey(
  chainId: number,
  apiKey: string,
  gatewayApiUrlOverride?: string
): Promise<PrivacyPublicKeyResponse>
```

**Wallet client signature:**

```ts
client.getPrivacyPublicKey(): Promise<PrivacyPublicKeyResponse>
```

**Returns:**

| Field | Type | Description |
|-------|------|-------------|
| `public_key` | `string` | X25519 public key (hex, no 0x prefix) |
| `key_type` | `string` | Always `"x25519"` |
| `encryption_suite` | `string` | Encryption suite identifier |

***

### `getSecretsPublicKey`

Fetch the gateway's X25519 HPKE public key for WASM secrets encryption. In threshold DKG mode, this returns a different key than `getPrivacyPublicKey`. Use this key when encrypting secrets via `storeEncryptedSecrets`.

**Standalone signature:**

```ts
getSecretsPublicKey(
  chainId: number,
  apiKey: string,
  gatewayApiUrlOverride?: string
): Promise<SecretsPublicKeyResponse>
```

**Wallet client signature:**

```ts
client.getSecretsPublicKey(): Promise<SecretsPublicKeyResponse>
```

**Returns:**

| Field | Type | Description |
|-------|------|-------------|
| `public_key` | `string` | X25519 public key (hex, no 0x prefix) |
| `key_type` | `string` | Always `"x25519"` |
| `encryption_suite` | `string` | Encryption suite identifier |

***

### `uploadIdentityEncrypted`

Upload HPKE-encrypted identity data to the gateway. The caller must provide a pre-built SecureEnvelope (via `createSecureEnvelope`) and an EIP-712 signature of the envelope JSON from the identity owner. The gateway stores the envelope and returns a `data_ref_id` + gateway signature for the on-chain `registerIdentityData` call.

**Standalone signature:**

```ts
uploadIdentityEncrypted(
  chainId: number,
  apiKey: string,
  params: UploadIdentityEncryptedParams,
  gatewayApiUrlOverride?: string
): Promise<UploadIdentityEncryptedResponse>
```

**Wallet client signature:**

```ts
client.uploadIdentityEncrypted(params: UploadIdentityEncryptedParams): Promise<UploadIdentityEncryptedResponse>
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `params.identityOwner` | `Address` | EVM address of the identity owner |
| `params.identityOwnerSig` | `string` | EIP-712 signature of the SecureEnvelope JSON by the identity owner |
| `params.envelope` | `string` | JSON-serialized SecureEnvelope (from `createSecureEnvelope`) |
| `params.identityDomain` | `` `0x${string}` `` | Identity domain as 0x-prefixed bytes32 hex (e.g., `keccak256("kyc")`) |
| `params.chainId` | `number` | Chain ID the identity registry lives on |

**Returns:**

| Field | Type | Description |
|-------|------|-------------|
| `data_ref_id` | `string` | Content-hash data reference ID: `keccak256(envelope_json_bytes)` |
| `gateway_signature` | `string` | Gateway EIP-712 signature for `registerIdentityData` on-chain call |
| `deadline` | `number` | Signature expiration (unix timestamp) |

***

### `getIdentityEncrypted`

Fetch encrypted identity data by its content-hash reference ID. Used to resolve a `data_ref_id` (stored on-chain in IdentityRegistry) back to the encrypted data blob (stored off-chain in the gateway).

**Standalone signature:**

```ts
getIdentityEncrypted(
  chainId: number,
  apiKey: string,
  dataRefId: string,
  gatewayApiUrlOverride?: string
): Promise<GetIdentityEncryptedResult>
```

**Wallet client signature:**

```ts
client.getIdentityEncrypted(args: { dataRefId: string }): Promise<GetIdentityEncryptedResult>
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `dataRefId` | `string` | Content-hash data reference ID (keccak256 of the encrypted data) |

**Returns:**

| Field | Type | Description |
|-------|------|-------------|
| `envelope` | `string` | HPKE-encrypted identity data as a SecureEnvelope JSON string |
| `identity_domain` | `string` | Identity domain this data was registered under |
| `identity_owner` | `string` | Identity owner address |

***

### `uploadConfidentialData`

Encrypt confidential data (blacklists, allowlists, sanctions lists, etc.) client-side with HPKE and upload the envelope to the gateway. The gateway stores it and returns a content-hash `data_ref_id`. The provider then calls `ConfidentialDataRegistry.publishData(domain, dataRefId)` on-chain.

The gateway validates provider registration via on-chain lookup — no Ed25519 signing key required.

**Standalone signature:**

```ts
uploadConfidentialData(
  chainId: number,
  apiKey: string,
  params: UploadConfidentialDataParams,
  gatewayApiUrlOverride?: string
): Promise<UploadConfidentialDataResult>
```

**Wallet client signature:**

```ts
client.uploadConfidentialData(params: UploadConfidentialDataParams): Promise<UploadConfidentialDataResult>
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `params.provider` | `string` | Provider address (must be registered on-chain with ConfidentialDataRegistry) |
| `params.domain` | `string` | Confidential domain as 0x-prefixed bytes32 hex (e.g., `keccak256("newton.privacy.blacklist")`) |
| `params.plaintext` | `Uint8Array \| string \| Record<string, unknown>` | Data to encrypt and upload |
| `params.chainId` | `number` | Chain ID for AAD context binding |
| `params.recipientPublicKey` | `string?` | Gateway's X25519 key (hex, no 0x prefix). If omitted, fetched via RPC. |

**Returns:**

| Field | Type | Description |
|-------|------|-------------|
| `data_ref_id` | `string` | Content-hash data reference ID |

***

### `getConfidentialData`

Retrieve an HPKE-encrypted confidential data envelope by its data reference ID. The caller is responsible for decryption using their HPKE private key.

**Standalone signature:**

```ts
getConfidentialData(
  chainId: number,
  apiKey: string,
  dataRefId: string,
  gatewayApiUrlOverride?: string
): Promise<GetConfidentialDataResult>
```

**Wallet client signature:**

```ts
client.getConfidentialData(args: { dataRefId: string }): Promise<GetConfidentialDataResult>
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `dataRefId` | `string` | Content-hash data reference ID returned from `uploadConfidentialData` |

**Returns:**

| Field | Type | Description |
|-------|------|-------------|
| `envelope` | `string` | JSON-serialized HPKE SecureEnvelope |
| `domain` | `string` | Confidential domain as 0x-prefixed bytes32 hex |
| `provider` | `string` | Provider address |

***

## Identity Methods

EIP-712 signed identity data submission to the on-chain IdentityRegistry. These methods are available as wallet client actions and as standalone exports.

:::info
The identity module uses a single `EncryptedIdentityData { string data }` EIP-712 struct across all identity domains. The `identity_domain` field (bytes32 hash of the domain name) tells the gateway how to interpret the encrypted blob.
:::

### `identityDomainHash`

Compute the bytes32 identity domain hash from a human-readable domain name. Matches the Rust convention: `keccak256(toBytes(domainName))`.

**Signature:**

```ts
identityDomainHash(domainName: string): Hex
```

**Example:**

```ts twoslash
import { identityDomainHash } from '@newton-xyz/sdk';

const kycDomain = identityDomainHash('kyc');
// Returns keccak256 of "kyc" as 0x-prefixed bytes32
```

### `linkIdentityAsSignerAndUser`

Link identity data when the caller is both the identity owner and the client user. Calls the IdentityRegistry contract directly via `writeContract`.

**Standalone signature:**

```ts
linkIdentityAsSignerAndUser(
  walletClient: WalletClient,
  params: LinkIdentityAsSignerAndUserParams
): Promise<Hex>
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `policyClient` | `Address` | PolicyClient contract address |
| `identityDomains` | `Hex[]` | Array of domain hashes (use `identityDomainHash()`) |

**Returns:** Transaction hash (`Hex`).

### `linkIdentityAsSigner`

Link identity data as the identity owner (signer). Requires a counterparty EIP-712 signature from the client user.

**Standalone signature:**

```ts
linkIdentityAsSigner(
  walletClient: WalletClient,
  params: LinkIdentityAsSignerParams
): Promise<Hex>
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `policyClient` | `Address` | PolicyClient contract address |
| `identityDomains` | `Hex[]` | Array of domain hashes |
| `clientUser` | `Address` | The client user's address |
| `clientUserSignature` | `Hex` | EIP-712 signature from the client user |
| `clientUserNonce` | `bigint` | Nonce for the client user's signature |
| `clientUserDeadline` | `bigint` | Deadline timestamp for the signature |

**Returns:** Transaction hash (`Hex`).

### `linkIdentityAsUser`

Link identity data as the client user. Requires a counterparty EIP-712 signature from the identity owner.

**Standalone signature:**

```ts
linkIdentityAsUser(
  walletClient: WalletClient,
  params: LinkIdentityAsUserParams
): Promise<Hex>
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `identityOwner` | `Address` | The identity owner's address |
| `policyClient` | `Address` | PolicyClient contract address |
| `identityDomains` | `Hex[]` | Array of domain hashes |
| `identityOwnerSignature` | `Hex` | EIP-712 signature from the identity owner |
| `identityOwnerNonce` | `bigint` | Nonce for the identity owner's signature |
| `identityOwnerDeadline` | `bigint` | Deadline timestamp for the signature |

**Returns:** Transaction hash (`Hex`).

### `linkIdentity`

Link identity data as a 3rd party with EIP-712 signatures from both the identity owner and the client user.

**Standalone signature:**

```ts
linkIdentity(
  walletClient: WalletClient,
  params: LinkIdentityParams
): Promise<Hex>
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `identityOwner` | `Address` | The identity owner's address |
| `clientUser` | `Address` | The client user's address |
| `policyClient` | `Address` | PolicyClient contract address |
| `identityDomains` | `Hex[]` | Array of domain hashes |
| `identityOwnerSignature` | `Hex` | EIP-712 signature from the identity owner |
| `identityOwnerNonce` | `bigint` | Nonce for the identity owner's signature |
| `identityOwnerDeadline` | `bigint` | Deadline timestamp for the owner signature |
| `clientUserSignature` | `Hex` | EIP-712 signature from the client user |
| `clientUserNonce` | `bigint` | Nonce for the client user's signature |
| `clientUserDeadline` | `bigint` | Deadline timestamp for the user signature |

**Returns:** Transaction hash (`Hex`).

### `unlinkIdentityAsSigner`

Unlink identity data as the identity owner (signer). Only the identity owner who created the link can call this.

**Standalone signature:**

```ts
unlinkIdentityAsSigner(
  walletClient: WalletClient,
  params: UnlinkIdentityAsSignerParams
): Promise<Hex>
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `clientUser` | `Address` | The client user whose link to remove |
| `policyClient` | `Address` | PolicyClient contract address |
| `identityDomains` | `Hex[]` | Array of domain hashes to unlink |

**Returns:** Transaction hash (`Hex`).

### `unlinkIdentityAsUser`

Unlink identity data as the client user. Allows users to revoke links to their own account.

**Standalone signature:**

```ts
unlinkIdentityAsUser(
  walletClient: WalletClient,
  params: UnlinkIdentityAsUserParams
): Promise<Hex>
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `policyClient` | `Address` | PolicyClient contract address |
| `identityDomains` | `Hex[]` | Array of domain hashes to unlink |

**Returns:** Transaction hash (`Hex`).

***

## Types & Interfaces

### Intent Types

:::details[IntentFromParams]
The intent shape accepted by SDK methods before normalization.

```ts
interface IntentFromParams {
  from: string;
  to: string;
  value: string;
  data: string;
  chainId: string | number;
  functionSignature: string;
}
```
:::

:::details[NormalizedIntent]
The intent after internal normalization, with all fields as consistent types.

```ts
interface NormalizedIntent {
  from: Address;
  to: Address;
  value: Hex;
  data: Hex;
  chainId: number;
  functionSignature: Hex;
}
```
:::

:::details[HexlifiedIntent]
The intent with all fields encoded as hex strings for on-chain use.

```ts
interface HexlifiedIntent {
  from: Hex;
  to: Hex;
  value: Hex;
  data: Hex;
  chainId: Hex;
  functionSignature: Hex;
}
```
:::

***

### Task Types

:::details[TaskId]
```ts
type TaskId = Hex;
```

A hex-encoded unique identifier for a task.
:::

:::details[TaskStatus]
```ts
type TaskStatus =
  | 'Created'
  | 'Responded'
  | 'AttestationSpent'
  | 'AttestationExpired'
  | 'SuccessfullyChallenged';
```

Represents the lifecycle state of a task on-chain.
:::

:::details[Task]
```ts
interface Task {
  taskId: TaskId;
  intent: NormalizedIntent;
  policyId: Hex;
  taskCreatedBlock: number;
  // Additional operator-specific fields
}
```

The full task object returned by evaluation methods.
:::

:::details[TaskResponse]
```ts
interface TaskResponse {
  evaluationResult: boolean;
  referenceTaskId: TaskId;
  // Additional response metadata
}
```

The operator's response to a task evaluation.
:::

:::details[TaskResponseResult]
```ts
interface TaskResponseResult {
  taskResponse: TaskResponse;
  attestation: {
    expiration: number;
    // Additional attestation fields
  };
}
```

The combined result returned by `waitForTaskResponded`.
:::

:::details[SubmitEvaluationRequestParams]
```ts
interface SubmitEvaluationRequestParams {
  policyClient: Address;
  intent: IntentFromParams;
  timeout: number;
  proofCid?: string;
  includeValidateCalldata?: boolean;
  encryptedDataRefs?: string[];
  userSignature?: string;
  appSignature?: string;
  userPublicKey?: string;
  appPublicKey?: string;
}
```

| Field                      | Type               | Required | Description                                                              |
| -------------------------- | ------------------ | -------- | ------------------------------------------------------------------------ |
| `policyClient`             | `Address`          | Yes      | The policy client contract address                                       |
| `intent`                   | `IntentFromParams` | Yes      | The intent to evaluate                                                   |
| `timeout`                  | `number`           | Yes      | Request timeout in seconds                                               |
| `proofCid`                 | `string`           | No       | IPFS CID of a TLSNotary presentation proof for zkTLS-backed evaluation   |
| `includeValidateCalldata`  | `boolean`          | No       | Include ABI-encoded `validateAttestationDirect` calldata in the response |
| `encryptedDataRefs`        | `string[]`         | No       | Encrypted data reference UUIDs for privacy-preserving evaluation         |
| `userSignature`            | `string`           | No       | User Ed25519 signature for privacy authorization (hex-encoded)           |
| `appSignature`             | `string`           | No       | Application Ed25519 signature for privacy authorization (hex-encoded)    |
| `userPublicKey`            | `string`           | No       | User Ed25519 public key (hex-encoded, 32 bytes)                          |
| `appPublicKey`             | `string`           | No       | Application Ed25519 public key (hex-encoded, 32 bytes)                   |
:::

***

### Simulation Types

:::details[SimulateTaskParams & SimulateTaskResult]
```ts
interface SimulateTaskParams {
  intent: IntentFromParams;
  policyTaskData: SimulateTaskPolicyTaskData;
}

interface SimulateTaskPolicyTaskData {
  policyId: Hex;
  policyAddress: Address;
  policy: Hex;
  policyData: SimulateTaskPolicyData[];
}

interface SimulateTaskPolicyData {
  wasmArgs: Hex;
  data: Hex;
  attestation: Hex;
  policyDataAddress: Address;
  expireBlock: number;
}

interface SimulateTaskResult {
  success: boolean;
  result?: {
    allow: boolean;
    reason?: string;
  };
  error?: string;
}
```
:::

:::details[SimulatePolicyParams & SimulatePolicyResult]
```ts
interface SimulatePolicyParams {
  policyClient: Address;
  policy: string;
  intent: IntentFromParams;
  policyData: Array<{ policyDataAddress: Address }>;
  policyParams?: Record<string, any>;
  entrypoint?: string;
}

interface SimulatePolicyResult {
  success: boolean;
  evaluation_result?: SimulatePolicyEvaluationResult;
  error?: string;
}

interface SimulatePolicyEvaluationResult {
  allow: boolean;
  reason?: string;
}
```
:::

:::details[SimulatePolicyDataParams & SimulatePolicyDataResult]
```ts
interface SimulatePolicyDataParams {
  policyDataAddress: Address;
  secrets?: string;
  wasmArgs?: Hex;
  chainId: number; // required
}

interface SimulatePolicyDataResult {
  success: boolean;
  policy_data: {
    specifier: string;
    data: unknown;
    timestamp: number;
  } | null;
  error: string | null;
}
```
:::

:::details[SimulatePolicyDataWithClientParams & SimulatePolicyDataWithClientResult]
```ts
interface SimulatePolicyDataWithClientParams {
  policyDataAddress: Address;
  policyClient: Address;
  wasmArgs?: Hex;
}

interface SimulatePolicyDataWithClientResult {
  success: boolean;
  policy_data: {
    specifier: string;
    data: unknown;
    timestamp: number;
  } | null;
  error: string | null;
}
```
:::

***

### Policy Types

:::details[PolicyId, PolicyInfo, PolicyCodeInfo, PolicyDataInfo]
```ts
type PolicyId = `0x${string}`;

interface PolicyInfo {
  policyId: PolicyId;
  policyParams: string | object;
  policyParamsHex: `0x${string}`;
  expireAfter: number;
}

interface PolicyCodeInfo {
  policyCid: string;
  schemaCid: string;
  metadataCid: string;
  entrypoint: string;
}

interface PolicyDataInfo {
  addresses: Address[];
}
```
:::

:::details[PolicyParamsJson, SetPolicyInput, SetPolicyResult, PolicyDataInput]
```ts
type PolicyParamsJson = Record<string, any>;

interface SetPolicyInput {
  client: Address;
  policyUri: string;
  schemaUri: string;
  entrypoint: string;
  params: PolicyParamsJson;
  policyData: Address[];
  expireAfter: number;
}

interface SetPolicyResult {
  txHash: `0x${string}`;
  policyId: PolicyId;
}

interface PolicyDataInput {
  policyDataAddress: Address;
}
```
:::

***

### Gateway Types

:::details[GatewayCreateTaskResult & AggregationResponse]
```ts
interface GatewayCreateTaskResult {
  task_id: Hex;
  task: Task;
  task_response: unknown;
  aggregation_response: AggregationResponse;
  status: 'success' | 'failed';
  error: string | null;
  expiration: number;
  reference_block: number;
  signature_data: Hex;
  timestamp: number;
  /** ABI-encoded calldata for validateAttestationDirect (present when include_validate_calldata was true) */
  validate_calldata?: string;
  /** Per-operator error details when quorum fails */
  operator_errors?: OperatorError[];
}

interface AggregationResponse {
  non_signer_quorum_bitmap_indices: number[];
  non_signer_stake_indices: number[][];
  non_signers_pub_keys_g1: number[][];
  quorum_apk_indices: number[];
  quorum_apks_g1: number[][];
  signers_agg_sig_g1: { g1_point: number[] };
  signers_apk_g2: number[];
  total_stake_indices: number[];
  task_created_block: number;
}

interface OperatorError {
  operator_address: Address;
  operator_id: Hex;
  error_code: number;
  message: string;
  timestamp: string;
  retryable: boolean;
}
```
:::

***

### JSON-RPC Types

:::details[JsonRpcRequestPayload, JsonRpcResponsePayload, JsonRpcError, NewtonWalletPayloadMethod]
```ts
interface JsonRpcRequestPayload {
  jsonrpc: '2.0';
  id: number | string;
  method: NewtonWalletPayloadMethod;
  params: any[];
}

interface JsonRpcResponsePayload<T = any> {
  jsonrpc: '2.0';
  id: number | string;
  result?: T;
  error?: JsonRpcError;
}

interface JsonRpcError {
  code: number;
  message: string;
  data?: any;
}

enum NewtonWalletPayloadMethod {
  ShowUI = 'newton_wallet_wallet',
  Receive = 'newton_wallet_wallet_receive',
  PersonalSign = 'personal_sign',
  SendUserOperation = 'eth_sendUserOperation',
  Connect = 'newton_wallet_user_connect',
  Disconnect = 'newton_wallet_user_disconnect',
  IsConnected = 'newton_wallet_user_is_connected',
  GetConnectedProfile = 'newton_wallet_user_get_connected_profile',
}
```
:::

***

### Builder Types

:::details[PendingTaskBuilder]
```ts
interface PendingTaskBuilder {
  readonly taskId?: TaskId;
  waitForTaskResponded(args: {
    timeoutMs?: number;
  }): Promise<TaskResponseResult>;
}
```

Returned by `submitEvaluationRequest`. Call `waitForTaskResponded()` to poll for the on-chain attestation.
:::

***

### Privacy Types

:::details[SecureEnvelope & CreateSecureEnvelopeParams]
```ts
interface SecureEnvelope {
  enc: string;
  ciphertext: string;
  policy_client: string;
  chain_id: number;
  recipient_pubkey: string;
}

interface CreateSecureEnvelopeParams {
  plaintext: Uint8Array | string | Record<string, unknown>;
  policyClient: Address;
  chainId: number;
  recipientPublicKey: string;
}

interface SecureEnvelopeResult {
  envelope: SecureEnvelope;
  signature: string;
  senderPublicKey: string;
}
```
:::

:::details[Ed25519KeyPair]
```ts
interface Ed25519KeyPair {
  privateKey: string;  // 32-byte hex, no 0x prefix
  publicKey: string;   // 32-byte hex, no 0x prefix
}
```
:::

:::details[UploadIdentityEncryptedParams & Response]
```ts
interface UploadIdentityEncryptedParams {
  identityOwner: Address;
  identityOwnerSig: string;
  envelope: string;
  identityDomain: `0x${string}`;
  chainId: number;
}

interface UploadIdentityEncryptedResponse {
  data_ref_id: string;
  gateway_signature: string;
  deadline: number;
}
```
:::

:::details[GetIdentityEncryptedResult]
```ts
interface GetIdentityEncryptedResult {
  envelope: string;
  identity_domain: string;
  identity_owner: string;
}
```
:::

:::details[SecretsPublicKeyResponse]
```ts
interface SecretsPublicKeyResponse {
  public_key: string;
  key_type: string;
  encryption_suite: string;
}
```
:::

:::details[StoreEncryptedSecretsParams & Response]
```ts
interface StoreEncryptedSecretsParams {
  policyClient: Address;
  policyDataAddress: Address;
  /** Plaintext secrets as a JSON object (e.g., { "API_KEY": "...", "ENDPOINT": "..." }) */
  plaintext: Record<string, unknown>;
  chainId: number;
  /** Gateway's X25519 public key (hex, no 0x prefix). Fetched automatically if omitted. */
  recipientPublicKey?: string;
}

interface StoreEncryptedSecretsResponse {
  success: boolean;
  schema: Record<string, unknown> | null;
  error: string | null;
}
```
:::

:::details[SignPrivacyAuthorizationParams & PrivacyAuthorizationResult]
```ts
interface SignPrivacyAuthorizationParams {
  policyClient: Address;
  intentHash: Hex;
  encryptedDataRefs: string[];
  userSigningKey: string;
  appSigningKey: string;
}

interface PrivacyAuthorizationResult {
  userSignature: string;
  appSignature: string;
  userPublicKey: string;
  appPublicKey: string;
}
```
:::

:::details[PrivacyPublicKeyResponse]
```ts
interface PrivacyPublicKeyResponse {
  public_key: string;
  key_type: string;
  encryption_suite: string;
}
```
:::

***

### Webhook Types

:::details[RegisterWebhookParams & RegisterWebhookResult]
```ts
interface RegisterWebhookParams {
  url: string;
  secret?: string;
  timeoutSeconds?: number;
  maxRetries?: number;
  failureTypes?: TaskFailureType[];
}

interface RegisterWebhookResult {
  success: boolean;
  message: string;
}
```
:::

:::details[UnregisterWebhookResult]
```ts
interface UnregisterWebhookResult {
  success: boolean;
  message: string;
}
```
:::

:::details[TaskFailureType]
```ts
type TaskFailureType =
  | 'channel_error'
  | 'timeout'
  | 'quorum_not_reached'
  | 'onchain_submission_failed'
  | 'policy_evaluation_failed'
  | 'signature_verification_failed'
  | 'internal_error';
```
:::

### Identity Types

:::details[LinkIdentityAsSignerAndUserParams]
```ts
interface LinkIdentityAsSignerAndUserParams {
  policyClient: Address;
  identityDomains: Hex[];
}
```
:::

:::details[LinkIdentityAsSignerParams]
```ts
interface LinkIdentityAsSignerParams {
  policyClient: Address;
  identityDomains: Hex[];
  clientUser: Address;
  clientUserSignature: Hex;
  clientUserNonce: bigint;
  clientUserDeadline: bigint;
}
```
:::

:::details[LinkIdentityAsUserParams]
```ts
interface LinkIdentityAsUserParams {
  identityOwner: Address;
  policyClient: Address;
  identityDomains: Hex[];
  identityOwnerSignature: Hex;
  identityOwnerNonce: bigint;
  identityOwnerDeadline: bigint;
}
```
:::

:::details[LinkIdentityParams]
```ts
interface LinkIdentityParams {
  identityOwner: Address;
  clientUser: Address;
  policyClient: Address;
  identityDomains: Hex[];
  identityOwnerSignature: Hex;
  identityOwnerNonce: bigint;
  identityOwnerDeadline: bigint;
  clientUserSignature: Hex;
  clientUserNonce: bigint;
  clientUserDeadline: bigint;
}
```
:::

:::details[UnlinkIdentityAsSignerParams]
```ts
interface UnlinkIdentityAsSignerParams {
  clientUser: Address;
  policyClient: Address;
  identityDomains: Hex[];
}
```
:::

:::details[UnlinkIdentityAsUserParams]
```ts
interface UnlinkIdentityAsUserParams {
  policyClient: Address;
  identityDomains: Hex[];
}
```
:::

:::details[RegisterIdentityDataParams]
```ts
interface RegisterIdentityDataParams {
  identityDomain: Hex;
  dataRefId: string;
  gatewaySignature: Hex;
  deadline: bigint;
}
```
:::

***

## Error Handling

The SDK provides structured error classes with typed error codes for precise error handling.

### SDKError

Thrown when an SDK-level error occurs (e.g., missing API key, invalid arguments).

```ts
class SDKError extends Error {
  code: SDKErrorCode;
  rawMessage: string;

  constructor(code: SDKErrorCode, rawMessage: string);
}
```

### MagicRPCError

Thrown when the Newton Gateway returns a JSON-RPC error.

```ts
class MagicRPCError extends Error {
  code: RPCErrorCode | number;
  rawMessage: string;
  data: unknown;

  constructor(sourceError?: JsonRpcError | null);
}
```

### SDKErrorCode

:::details[SDKErrorCode enum values]
```ts
enum SDKErrorCode {
  MissingApiKey = 'MISSING_API_KEY',
  PopupAlreadyExists = 'POPUP_ALREADY_EXISTS',
  MalformedResponse = 'MALFORMED_RESPONSE',
  InvalidArgument = 'INVALID_ARGUMENT',
  ExtensionNotInitialized = 'EXTENSION_NOT_INITIALIZED',
  IncompatibleExtensions = 'INCOMPATIBLE_EXTENSIONS',
  FailedToOpenPopup = 'FAILED_TO_OPEN_POPUP',
  FailedToRetrieveNativeTokenBalance = 'FAILED_TO_RETRIEVE_NATIVE_TOKEN_BALANCE',
  MissingChain = 'MISSING_CHAIN',
  MissingAccount = 'MISSING_ACCOUNT',
  InvalidAddress = 'INVALID_ADDRESS',
}
```
:::

### RPCErrorCode

:::details[RPCErrorCode enum values]
```ts
enum RPCErrorCode {
  // Standard JSON-RPC 2.0 error codes
  ParseError = -32700,
  InvalidRequest = -32600,
  MethodNotFound = -32601,
  InvalidParams = -32602,
  InternalError = -32603,

  // Custom Newton error codes
  MagicLinkRateLimited = -10002,
  UserAlreadyLoggedIn = -10003,
  AccessDeniedToUser = -10011,
  UserRejectedAction = -10012,
  RequestCancelled = -10014,
  RedirectLoginComplete = -10015,
  NewtonWalletSessionTerminated = -10016,
  PopupRequestOverriden = -10017,
}
```
:::

### SDKWarningCode

:::details[SDKWarningCode enum values]
```ts
enum SDKWarningCode {
  SyncWeb3Method = 'SYNC_WEB3_METHOD',
  ReactNativeEndpointConfiguration = 'REACT_NATIVE_ENDPOINT_CONFIGURATION',
  DeprecationNotice = 'DEPRECATION_NOTICE',
  ProductAnnouncement = 'ANNOUNCEMENT',
}
```
:::

:::note
`SDKError`, `MagicRPCError`, `SDKErrorCode`, and `RPCErrorCode` are exported from the package's public API, so you can narrow with `instanceof SDKError` / `instanceof MagicRPCError` and switch on the typed `code`. `SDKWarningCode` is not exported.
:::

***

## Subpath Exports

The SDK provides multiple entry points for tree-shaking and targeted imports.

| Import Path                                 | Description                                                                       |
| ------------------------------------------- | --------------------------------------------------------------------------------- |
| `@newton-xyz/sdk`          | Full SDK -- all methods, types, utilities, and constants                          |
| `@newton-xyz/sdk/types`    | Type definitions and interfaces only                                              |

:::info
Use subpath exports to minimize bundle size when you only need a subset of SDK functionality.
:::

***

## Related Resources

* [Integration Guide](/developers/guides/integration-guide) -- Step-by-step guide to building with the Newton Protocol SDK
* [RPC API Reference](/developers/reference/rpc-api) -- Underlying JSON-RPC methods called by the SDK
