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

***

## Policy-set requests

This reference targets SDK **1.2.2**. `submitEvaluationRequest`, `evaluateIntentDirect`, `submitIntentAndSubscribe`, and `simulatePolicy` require `wasmArgs: Hex[]`, positionally aligned with the client's ordered set. Pass `['0x']` for one pure-Rego policy and `['0x', '0x']` for two. A scalar or omitted value is not supported by these SDK methods.

```ts
interface PolicyConfig { policyParams: Hex; expireAfter: number }
interface PolicySpec { policy: Address; config: PolicyConfig }
```

Read `getPolicySetSnapshot()` through the exported `NewtonPolicyClientAbi` with viem `readContract` when you need identity, revision, and specs together. There is no SDK action with that name in v1.2.2. Preserve order and repeated entries in both tasks and responses. Individual oracle simulation methods still use scalar `wasmArgs`.

## 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...',
  },
  wasmArgs: ['0x'], // One pure-Rego policy
  timeout: 60,
});

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,
  wasmArgs: ['0x', '0x'], // Two pure-Rego policies, in set order
  timeout: 30,
});

console.log(result.allowed); // 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: {
    allowed: boolean;
    task: Task;
    taskResponse: TaskResponse;
    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`           | Yes       | Request timeout in seconds                                                                         |

**Returns:**

* `result.allowed` (`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...',
  },
  wasmArgs: ['0x', '0x'], // Two pure-Rego policies, in set order
  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`           | Yes       | 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

:::warning
SDK v1.2.2's `simulateTask` wrapper still sends the legacy `policy_task_data` schema shown below. It is not compatible with the policy-set gateway at the pinned revision. Use `simulatePolicy` for full WASM + Rego simulation, or call [newt\_simulateTask](/developers/reference/rpc-api#newt_simulatetask) directly with the new schema for provided-output evaluation. Neither simulation returns a BLS attestation.
:::

```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...',
        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 the configured policy set (`newt_simulatePolicy`). The gateway runs each policy's optional WASM and evaluates its Rego, returning per-policy results and an aggregate verdict. It requires deployed policies and a configured client. The pinned gateway checks client ownership, including pure-Rego sets; explicitly authorized admin keys have a read-only bypass.

```ts
const result = await walletClient.simulatePolicy({
  policyClient: '0x...',
  chainId: 11155111,
  intent: {
    from: '0x...', to: '0x...', value: '0x0', data: '0x...',
    chainId: 11155111, functionSignature: '0x...',
  },
  wasmArgs: ['0x', '0x'], // One slot per policy, including pure-Rego entries
});
console.log(result.success, result.allowed, result.policy_id);
for (const policy of result.policies ?? []) {
  console.log(policy.policy_index, policy.policy, policy.allowed, policy.result);
}
```

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

`success` means evaluation completed; `allowed` means every policy allowed. Errors have `allowed: null`. This is an unsigned simulation, not an operator quorum or application transaction.

***

### simulatePolicyData

Simulates one Policy’s WASM. No ownership verification is required for caller-supplied secrets. In v1.2.2 the SDK types `secrets` as a string and forwards it unchanged, while the pinned gateway expects a SecureEnvelope JSON object. Use raw RPC for encrypted inline secrets until the wrapper matches; the no-secrets example can omit that field.

```ts
const result = await walletClient.simulatePolicyData({
  policyAddress: '0x...',
  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 one Policy’s WASM with stored secrets. Requires client ownership. SDK v1.2.2’s wrapper omits the required top-level `chain_id`; use [raw RPC](/developers/reference/rpc-api#newt_simulatepolicydatawithclient) with the deployment chain for the pinned gateway. The signature below documents the wrapper, not a compatible request.

```ts
const result = await walletClient.simulatePolicyDataWithClient({
  policyAddress: '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 Policy oracle. The gateway's X25519 public key is fetched automatically if not provided.

```ts
const { success } = await walletClient.storeEncryptedSecrets({
  policyClient: '0x...',
  policyAddress: '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.allowed);
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 {
  initializationTimestamp: Hex
  intent: {
    chainId: Hex
    data: Hex
    from: Address
    functionSignature: Hex
    to: Address
    value: Hex
  }
  intentSignature: Hex
  policyClient: Address
  policyId: Hex
  policyRevision: number
  /** Frozen at admission. Order and repeats are significant. */
  policies: PolicySpec[]
  wasmArgs: Hex[]
  quorumNumbers: Hex
  quorumThresholdPercentage: number
  taskCreatedBlock: number
  taskId: Hex
}
```
:::

:::details[TaskResponse]
```ts
interface PolicyDataEntry {
  wasmArgs: Hex
  data: Hex
  expireBlock: number
}

interface PolicyTaskData {
  policyId: Hex
  policyAddress: Address
  policy: Hex
  policyData: PolicyDataEntry[]
}

interface TaskResponse {
  taskId: Hex
  policyClient: Address
  policyId: Hex
  intent: NormalizedIntent
  intentSignature: Hex
  /** True only when every policy allows. */
  allowed: boolean
  policyTaskData: PolicyTaskData[]
}
```
:::

:::details[TaskResponseResult]
```ts
interface TaskResponseResult {
  taskResponse: TaskResponse
  responseCertificate: ResponseCertificate
  attestation: {
    taskId: Hex
    policyId: Hex
    policyClient: Address
    intent: NormalizedIntent
    intentSignature: Hex
    expiration: number
  }
}
```
:::

:::details[SubmitEvaluationRequestParams]
```ts
interface SubmitEvaluationRequestParams {
  policyClient: Address
  intent: IntentFromParams
  intentSignature?: Hex
  quorumNumber?: Hex
  quorumThresholdPercentage?: number
  /** One per policy, positionally aligned. Pure-Rego policies still need a slot — pass `'0x'`. */
  wasmArgs: Hex[]
  timeout: number // in seconds
  identityDomain?: Hex
  /** Encrypted data reference UUIDs for privacy-preserving evaluation */
  encryptedDataRefs?: string[]
  /** User Ed25519 signature for privacy authorization (hex-encoded) */
  userSignature?: string
  /** Application Ed25519 signature for privacy authorization (hex-encoded) */
  appSignature?: string
  /** User Ed25519 public key for privacy signature verification (hex-encoded, 32 bytes) */
  userPublicKey?: string
  /** Application Ed25519 public key for privacy signature verification (hex-encoded, 32 bytes) */
  appPublicKey?: string
  /** IPFS CID of a TLSNotary presentation proof for zkTLS-backed policy evaluation */
  proofCid?: string
  /** Include ABI-encoded validateAttestationDirect calldata in the response */
  includeValidateCalldata?: boolean
}
```
:::

***

### 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
  expireBlock: number
}

interface SimulateTaskResult {
  success: boolean
  result: { allow?: boolean; reason?: string } | null
  error: string | null
  details: unknown
}
```
:::

:::details[SimulatePolicyParams & SimulatePolicyResult]
```ts
interface SimulatePolicyParams {
  policyClient: Address
  chainId: number
  intent: IntentFromParams
  /** One per policy, positionally aligned. `'0x'` for a pure-Rego policy. */
  wasmArgs: Hex[]
  intentSignature?: Hex
}

interface PolicySimulationResult {
  policy_index: number
  policy: Address
  result: unknown
  allowed: boolean
  expire_after: number
}

interface SimulatePolicyResult {
  success: boolean
  allowed: boolean | null
  policy_id: string | null
  policies: PolicySimulationResult[] | null
  error: string | null
  parsed_intent: unknown | null
}
```
:::

:::details[SimulatePolicyDataParams & SimulatePolicyDataResult]
```ts
interface SimulatePolicyDataParams {
  policyAddress: 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 {
  policyAddress: 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 {
  policyAddress: Address;
}
```
:::

***

### Gateway Types

:::details[GatewayCreateTaskResult & AggregationResponse]
```ts
interface GatewayCreateTaskResult {
  aggregation_response: AggregationResponse
  error: string | null
  expiration: number
  reference_block: number
  status: 'success' | 'failed'
  task: Task
  task_id: Hex
  task_response: {
    allowed: boolean
    initialization_timestamp: Hex
    intent: {
      chainId: Hex
      data: Hex
      from: Address
      functionSignature: Hex
      to: Address
      value: Hex
    }
    intent_signature: Hex
    policy_client: Address
    policy_id: Hex
    policy_task_data: Array<{
      policy: Hex
      policyAddress: Address
      policyData: Array<{
        data: Hex
        expireBlock: number
        wasmArgs: Hex
      }>
      policyId: Hex
    }>
    task_id: Hex
  }
  signature_data: Hex
  /** 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[]
  timestamp: number
}

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;
  policyAddress: 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
