Skip to main content
Methods on the wallet flow of a createAuthClient client. signIn runs the whole flow in one call; getNonce, createMessage, and verify are the underlying primitives for custom message construction. The signer can be a human user (signing in their own wallet UI) or the agent itself signing programmatically with an agent signing token — only a valid signature from the wallet address is required, so SIWE supports fully autonomous agents with no human in the loop. See Sign In with a Private Key for both patterns.

signIn

Function Signature

auth.wallet.signIn(params: {
  address: string;
  signMessage: (message: string) => Promise<string>;
  sessionPublicKey?: string;
  domain?: string;
  uri?: string;
  chainId?: number;
  statement?: string;
  walletName?: string;
  walletProvider?: WalletProviderEnum;
}): Promise<AuthResult>
One call for the whole flow: fetches a nonce, builds the sign-in message internally, collects the signature from your signMessage callback, and verifies it. Key custody stays behind the callback — the wallet key never enters the client.

Parameters

  • address (string) - The signing wallet’s public address. Must be a 0x-prefixed 20-byte hex address.
  • signMessage ((message: string) => Promise<string>) - Your signer callback. Receives the sign-in message; returns the signature.
  • sessionPublicKey (string, optional) - Compressed P-256 public key hex from generateSessionKeyPair. Binds the session key into the minted JWT — required if you will use a session signer with authenticateJwt for backUpToDynamic flows.
  • domain / uri (string, optional) - The origin the sign-in presents as. Default: derived from the appOrigin set on createAuthClient (domain = its host, uri = the origin). Passing both per call overrides appOrigin.
  • chainId (number, optional) - EVM-specific. Defaults to 1.
  • statement (string, optional) - Human-readable statement included in the message.
  • walletName (string, optional) / walletProvider (WalletProviderEnum, optional) - Forwarded to verify; see its defaults below.

Returns

  • Promise<AuthResult> - { jwt, expiresAt, userId }. Pass jwt to authenticateJwt; never log it.

Errors

  • address not a 0x-prefixed 20-byte hex address → "wallet.signIn requires a 0x-prefixed 20-byte hex address" (thrown before any network call).
  • domain, uri, or statement containing line breaks → "wallet.signIn: <name> must not contain line breaks" (line breaks would corrupt the EIP-4361 message structure).
  • Neither appOrigin nor per-call domain/uri provided → "wallet.signIn requires domain/uri — pass them or set appOrigin on createAuthClient".
  • Plus the verify errors below once the flow reaches the server.

getNonce

Function Signature

auth.wallet.getNonce(): Promise<{ nonce: string }>

Parameters

None.

Returns

  • nonce (string) - Include it in the sign-in message via createMessage. Nonces are single-use.

createMessage

Function Signature

auth.wallet.createMessage(params: {
  domain: string;
  address: string;
  uri: string;
  chainId: number;
  nonce: string;
  statement?: string;
  issuedAt?: string;
}): string
Synchronous — builds the EIP-4361-style message locally; no network call.

Parameters

  • domain (string) - The domain requesting the sign-in (for example, yourapp.example.com).
  • address (string) - The signing wallet’s public address.
  • uri (string) - The URI of the sign-in origin (for example, https://yourapp.example.com).
  • chainId (number) - The EVM chain ID (for example, 1 for Ethereum mainnet).
  • nonce (string) - The nonce from getNonce.
  • statement (string, optional) - Human-readable statement shown to the user in their wallet.
  • issuedAt (string, optional) - ISO 8601 timestamp. Defaults to now.

Returns

  • string - The sign-in message. Have the wallet key holder sign it, then pass both to verify.

verify

Function Signature

auth.wallet.verify(params: {
  message: string;
  signature: string;
  walletAddress: string;
  sessionPublicKey?: string;
  walletName?: string;
  walletProvider?: WalletProviderEnum;
  chain?: ChainEnum;
}): Promise<AuthResult>

Parameters

  • message (string) - The exact message from createMessage.
  • signature (string) - The signature over the message.
  • walletAddress (string) - The signing wallet’s public address (must match the message).
  • sessionPublicKey (string, optional) - Compressed P-256 public key hex from generateSessionKeyPair. Binds the session key into the minted JWT.
  • walletName (string, optional) - Defaults to 'unknown'.
  • walletProvider (WalletProviderEnum, optional) - Defaults to custodialService.
  • chain (ChainEnum, optional) - Defaults to EVM.

Returns

  • Promise<AuthResult> - { jwt, expiresAt, userId }. Pass jwt to authenticateJwt; never log it.

Example

import { createAuthClient, generateSessionKeyPair } from '@dynamic-labs-wallet/node';

const auth = createAuthClient({
  environmentId: 'your-environment-id',
  appOrigin: 'https://yourapp.example.com',
});
const { publicKeyHex, privateKeyJwk } = await generateSessionKeyPair();

// The public address of the wallet that will sign the message.
const walletAddress = '0xUserPublicAddress';

const { jwt, expiresAt } = await auth.wallet.signIn({
  address: walletAddress,
  // The wallet key holder signs — a human in your app's UI, or the agent's own key.
  signMessage: (message) => collectSignatureFromUser(message),
  sessionPublicKey: publicKeyHex,
  statement: 'Authorize this agent to use your Dynamic wallet',
});

Error Handling

try {
  const result = await auth.wallet.signIn({ address, signMessage, sessionPublicKey });
} catch (error) {
  // - Invalid or expired signature/nonce (401): "SIWE sign-in failed: the code
  //   or signature is invalid or expired"
  // - MFA-required account: "account requires MFA, which the headless auth
  //   client does not support"
  // - Cookie-auth environment: sign-in returned no JWT in the response body
  // - Input validation errors thrown before any network call — see Errors above
  console.error('Sign-in failed:', error);
}
Sign-in endpoints are rate limited per IP address (429 when exceeded) — see Rate Limit Policies.
Last modified on July 9, 2026