Verify Signature
Verify a smart-account signature against its original payload.
namera.verifySignature(request) performs read-only verification. It requires access to the account, but no session-key ID.
Usage
Install @namera-ai/sdk and set NAMERA_API_KEY. Replace example IDs with resources available to your credential.
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);
const verification = await namera.verifySignature({
namespace: "eip155",
walletId: signed.data.walletId,
chainId: signed.data.chainId,
type: "message",
message,
signature: signed.data.signature,
});
if (!verification.success) throw new Error(verification.error.message);
console.log(verification.data);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 for the error shape.
namespace("eip155"): Chain namespace.walletId(string): Account UUID.chainId(SupportedEvmChainId): Verification network.account(`0x${string}`): Smart-account address.valid(boolean): Whether the account accepts this signature for the payload.type("message" | "typed-data"): Payload kind.
Example Response
{
"namespace": "eip155",
"walletId": "0199dfe1-0000-7000-8000-000000000001",
"chainId": "eip155:84532",
"account": "0x1111111111111111111111111111111111111111",
"valid": true,
"type": "message"
}Parameters
Pass a VerifySignatureRequest object. No session-key ID is needed. For type: "typed-data", provide typedData instead of message.
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.
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);
const verification = await namera.verifySignature({
namespace: "eip155",
walletId: signed.data.walletId,
chainId: signed.data.chainId,
type: "message",
message,
signature: signed.data.signature,
});
if (!verification.success) throw new Error(verification.error.message);
console.log(verification.data);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.
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);
const verification = await namera.verifySignature({
namespace: "eip155",
walletId: signed.data.walletId,
chainId: signed.data.chainId,
type: "message",
message,
signature: signed.data.signature,
});
if (!verification.success) throw new Error(verification.error.message);
console.log(verification.data);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. Network availability is also checked by the API.
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);
const verification = await namera.verifySignature({
namespace: "eip155",
walletId: signed.data.walletId,
chainId: signed.data.chainId,
type: "message",
message,
signature: signed.data.signature,
});
if (!verification.success) throw new Error(verification.error.message);
console.log(verification.data);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
- Type:
string - Required when:
typeis"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
- Type:
EvmTypedData - Required when:
typeis"typed-data"
An EIP-712 payload containing domain, types, primaryType, and message.
Use the identical payload when verifying its signature.
import type { EvmTypedData } from "@namera-ai/sdk";
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;typedData.domain
- 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
- 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
- Type:
string - Required
The root struct name from types, such as "Greeting". It determines how the
message fields are encoded.
typedData.message
- 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.
signature
- Type:
`0x${string}` - Required
The complete signature returned by sign(), including its validation envelope. Do not strip it to a bare EOA signature. Supply the original payload, account, and network.
A successful request can return valid: false; only data.valid: true means the signature was accepted.
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);
const verification = await namera.verifySignature({
namespace: "eip155",
walletId: signed.data.walletId,
chainId: signed.data.chainId,
type: "message",
message,
signature: signed.data.signature,
});
if (!verification.success) throw new Error(verification.error.message);
console.log(verification.data);Errors
VERIFICATION_FAILED indicates verification could not be completed; valid: false is a completed check that rejected the signature. See Handling Results and Errors for shared authentication, transport, and contract errors.
Guide: Verify Signatures.