> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# signTransaction

> Signs an EVM transaction using the specified wallet

## Function Signature

```typescript theme={"system"}
signTransaction(params: {
  walletMetadata: WalletMetadata;
  transaction: TransactionSerializable;
  password?: string;
  externalServerKeyShares?: ServerKeyShare[];
}): Promise<string>
```

## Description

Signs an EVM transaction using the wallet identified by the supplied `walletMetadata`. The SDK is stateless — every call requires `walletMetadata`. If the wallet was created with `backUpToDynamic: true`, supply the `password` so the SDK can recover shares from backup when `externalServerKeyShares` is omitted.

<Warning>
  When you pass `externalServerKeyShares` (the caller-supplied path), `walletMetadata.externalServerKeySharesBackupInfo` must also be present — `signTransaction` throws if shares are supplied but backup metadata is missing. The full `walletMetadata` returned from `createWalletAccount` / `importPrivateKey` already includes it; identity-only metadata from `fetchWalletMetadata` will be rejected.
</Warning>

## Parameters

### Required Parameters

* **`walletMetadata`** ([`WalletMetadata`](/node/reference/types/wallet-metadata)) - Non-sensitive wallet metadata persisted from `createWalletAccount()` / `importPrivateKey()`. The sender address comes from `walletMetadata.accountAddress`.
* **`transaction`** (`TransactionSerializable`) - The transaction to sign (viem format)

### Optional Parameters

* **`password`** (`string`) - Required if the wallet was created with `backUpToDynamic: true`. Used for backup decryption when `externalServerKeyShares` is not provided.
* **`externalServerKeyShares`** ([`ServerKeyShare[]`](/node/reference/types/server-key-share)) - Caller-supplied plaintext shares. If omitted, the SDK recovers from backup using `password`.

## Returns

* **`Promise<string>`** - The signed transaction as a hex string

## Example

```typescript theme={"system"}
import { authenticatedEvmClient } from './client';
import { parseEther } from 'viem/utils';

const evmClient = await authenticatedEvmClient();

// Load the metadata + shares you persisted at creation time.
const walletMetadata = JSON.parse(await redis.get(`wallet:${accountAddress}`));
const externalServerKeyShares = await vault.read(`wallet:${accountAddress}/shares`);

const signedTx = await evmClient.signTransaction({
  walletMetadata,
  transaction: {
    to: '0xRecipientAddress',
    value: parseEther('0.1'),
    chain: base,
    account: walletMetadata.accountAddress,
  },
  externalServerKeyShares,
  password: 'user-password',
});

console.log('Signed transaction:', signedTx);
```

## Error Handling

```typescript theme={"system"}
try {
  const signedTx = await evmClient.signTransaction({
    walletMetadata,
    transaction: tx,
    externalServerKeyShares,
    password: 'user-password',
  });
  console.log('Transaction signed successfully');
} catch (error) {
  console.error('Failed to sign transaction:', error);
}
```

## Related

* [`WalletMetadata`](/node/reference/types/wallet-metadata) - The metadata object passed to every operation
* [`signMessage()`](/node/reference/evm/sign-message) - Sign a message instead of a transaction
* [`createWalletAccount()`](/node/reference/evm/create-wallet-account) - Create a new wallet account
* [Storage Best Practices](/node/wallets/server-wallets/storage-best-practices) - Where to cache metadata vs. vault shares
