# Sign

> Documentation index: [llms.txt](https://namera.ai/llms.txt).

Source: https://namera.ai/docs/sdk/reference/signatures/sign

Sign a UTF-8 message or EIP-712 typed data.

`namera.sign(request)` prepares, validates, and completes a signature using the selected session key. It does not send a transaction.

## Usage [#usage]

Install `@namera-ai/sdk` and set `NAMERA_API_KEY`. Replace example IDs with resources available to your credential.

<Tabs items={["index.ts", "client.ts"]}>
<Tab value="index.ts">

```ts title="index.ts"
import { namera } from "./client";
const message = "Hello from Namera";

const signed = await namera.sign({
  namespace: "eip155",
  walletId: "0199dfe1-0000-7000-8000-000000000001",
  sessionKeyId: "0199dfe1-0000-7000-8000-000000000002",
  chainId: "eip155:84532",
  type: "message",
  message,
});

if (!signed.success) throw new Error(signed.error.message);

console.log(signed.data);
```

</Tab>
<Tab value="client.ts">

```ts title="client.ts"
import { NameraClient } from "@namera-ai/sdk";

export const namera = new NameraClient({
  apiKey: process.env.NAMERA_API_KEY!,
});
```

</Tab>
</Tabs>

## Returns [#returns]

API methods return a `Promise<NameraResult<T, E>>`. When `success` is `true`,
`data` contains the value described below and `error` is `null`. On failure,
`data` is `null` and `error` describes the failure.

The JSON example shows the complete successful `data`, with illustrative values.
Date-time values use ISO strings in JSON; bigint values use decimal strings.
See [Handling Results and Errors](https://namera.ai/docs/sdk/handling-results-and-errors) for the error shape.

- **`namespace`** (`"eip155"`): Chain namespace.
- **`walletId`** (`string`): Account UUID.
- **`chainId`** (`SupportedEvmChainId`): Signing network.
- **`account`** (`` `0x${string}` ``): Smart-account address.
- **`signature`** (`` `0x${string}` ``): Smart-account signature, not a bare EOA signature.
- **`type`** (`"message" | "typed-data"`): Payload kind.

### Example Response [#example-response]

<div className="docs-response">

```json
{
  "namespace": "eip155",
  "walletId": "0199dfe1-0000-7000-8000-000000000001",
  "chainId": "eip155:84532",
  "account": "0x1111111111111111111111111111111111111111",
  "signature": "0x0000000100111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111b",
  "type": "message"
}
```

</div>

## Parameters [#parameters]

Pass a `SignRequest` object. The selected session needs installed signature authority and an API policy permitting the payload.

### namespace [#namespace]

- **Type:** `"eip155"`
- **Required**

The blockchain namespace. Use `"eip155"` for every currently supported Namera
network. This is not a chain ID; select the specific network with `chainId`.

```ts title="index.ts"
import { namera } from "./client";
const message = "Hello from Namera";

const signed = await namera.sign({
  namespace: "eip155", // [!code focus]
  walletId: "0199dfe1-0000-7000-8000-000000000001",
  sessionKeyId: "0199dfe1-0000-7000-8000-000000000002",
  chainId: "eip155:84532",
  type: "message",
  message,
});

if (!signed.success) throw new Error(signed.error.message);

console.log(signed.data);
```

### walletId [#walletid]

- **Type:** `string`
- **Required**

The account UUID returned by `wallets.list()` or `wallets.get()`. Pass its `id`,
not its onchain `address`. The account must be accessible to the client’s credential.

```ts title="index.ts"
import { namera } from "./client";
const message = "Hello from Namera";

const signed = await namera.sign({
  namespace: "eip155",
  walletId: "0199dfe1-0000-7000-8000-000000000001", // [!code focus]
  sessionKeyId: "0199dfe1-0000-7000-8000-000000000002",
  chainId: "eip155:84532",
  type: "message",
  message,
});

if (!signed.success) throw new Error(signed.error.message);

console.log(signed.data);
```

### sessionKeyId [#sessionkeyid]

- **Type:** `string`
- **Required**

The session-key UUID returned by `sessionKeys.list()` or `sessionKeys.get()`.
This identifies the delegated session, not its signing key or network installation.
Your credential must have an active grant for this key.

For execution or signing, choose a key belonging to `walletId` with a confirmed
installation on `chainId` and permissions that allow the requested operation.

```ts title="index.ts"
import { namera } from "./client";
const message = "Hello from Namera";

const signed = await namera.sign({
  namespace: "eip155",
  walletId: "0199dfe1-0000-7000-8000-000000000001",
  sessionKeyId: "0199dfe1-0000-7000-8000-000000000002", // [!code focus]
  chainId: "eip155:84532",
  type: "message",
  message,
});

if (!signed.success) throw new Error(signed.error.message);

console.log(signed.data);
```

### chainId [#chainid]

- **Type:** `SupportedEvmChainId`
- **Required**

The target network in CAIP-2 format. For Base Sepolia, use `"eip155:84532"`,
not `84532` or `"84532"`. Use the network on which the account will execute, sign, or verify the payload.

The SDK restricts this field to the [supported network IDs](https://namera.ai/docs/sdk/supported-networks).
Network availability is also checked by the API.

```ts title="index.ts"
import { namera } from "./client";
const message = "Hello from Namera";

const signed = await namera.sign({
  namespace: "eip155",
  walletId: "0199dfe1-0000-7000-8000-000000000001",
  sessionKeyId: "0199dfe1-0000-7000-8000-000000000002",
  chainId: "eip155:84532", // [!code focus]
  type: "message",
  message,
});

if (!signed.success) throw new Error(signed.error.message);

console.log(signed.data);
```

### type [#type]

- **Type:** `"message" | "typed-data"`
- **Required**

Selects the payload format. Use `message` with `"message"` or `typedData` with
`"typed-data"`. Do not supply both payload fields.

### message [#message]

- **Type:** `string`
- **Required when:** `type` is `"message"`

The exact UTF-8 text to sign or verify. Whitespace and capitalization are part of
the payload. A string such as `"0x1234"` is text, not raw bytes.

### typedData [#typeddata]

- **Type:** `EvmTypedData`
- **Required when:** `type` is `"typed-data"`

An EIP-712 payload containing `domain`, `types`, `primaryType`, and `message`.
Use the identical payload when verifying its signature.

```ts title="index.ts"
import type { EvmTypedData } from "@namera-ai/sdk";

const typedData = {
  domain: {
    // [!code focus:6]
    name: "Namera Example",
    version: "1",
    chainId: 84532,
    verifyingContract: "0x3333333333333333333333333333333333333333",
  },
  types: { Greeting: [{ name: "contents", type: "string" }] },
  primaryType: "Greeting",
  message: { contents: "Hello from Namera" },
} satisfies EvmTypedData;
```

#### typedData.domain [#typeddatadomain]

- **Type:** `EvmTypedData["domain"]`
- **Required**

The signing domain. Its fields are optional: `name` and `version` are strings;
`chainId` is a nonnegative integer; `verifyingContract` is a 20-byte address;
`salt` is a 32-byte hex value. Unlike the request’s CAIP-2 `chainId`, this domain
uses a number such as `84532`. Use the domain expected by the verifying application.

#### typedData.types [#typeddatatypes]

- **Type:** `Record<string, readonly { name: string; type: string }[]>`
- **Required**

Definitions of the structs used by the payload. Struct names, field names, and
field types must be nonempty strings. Each struct needs at least one field.

#### typedData.primaryType [#typeddataprimarytype]

- **Type:** `string`
- **Required**

The root struct name from `types`, such as `"Greeting"`. It determines how the
message fields are encoded.

#### typedData.message [#typeddatamessage]

- **Type:** `Record<string, Json>`
- **Required**

Values matching the root struct. Use JSON-compatible values. Represent large
integers as decimal strings, not JavaScript `bigint`, to preserve precision.

#### Sign typed data [#sign-typed-data]

Use `type: "typed-data"` with the complete payload. The session’s signature policy
must permit its domain and primary type. Replace the domain’s contract address
with the one expected by your application.

```ts title="index.ts"
import type { EvmTypedData } from "@namera-ai/sdk";
import { namera } from "./client";

const typedData = {
  domain: {
    name: "Namera Example",
    version: "1",
    chainId: 84532,
    verifyingContract: "0x3333333333333333333333333333333333333333",
  },
  types: {
    Greeting: [{ name: "contents", type: "string" }],
  },
  primaryType: "Greeting",
  message: { contents: "Hello from Namera" },
} satisfies EvmTypedData;
```

## Errors [#errors]

Signature policy, authorization, billing, and signing failures return `success: false`. Prepared-payload or signature validation failures use `kind: "signer"`. See [Handling Results and Errors](https://namera.ai/docs/sdk/handling-results-and-errors) for shared authentication, transport, and contract errors.

Guides: [Sign Messages](https://namera.ai/docs/sdk/guides/signing/sign-messages) and [Sign Typed Data](https://namera.ai/docs/sdk/guides/signing/sign-typed-data).
