# Server wallets

> Control wallets programmatically using access keys

> For the complete documentation index, see [llms.txt](/docs/llms.txt).

<Warning>Alchemy Signer APIs are being sunset. As of June 16, 2026, Alchemy Signer no longer supports new user signups. Existing users can still log in to be migrated. For new users, use [Privy](/docs/wallets/third-party/signers/privy) with [Wallet APIs](/docs/wallets/quickstart).</Warning>


<Tip>
  Server wallets are in early access. Contact wallets@alchemy.com for help
  getting up and running.
</Tip>

Server wallets can be programmatically controlled using access keys. This enables backend applications to sign transactions and messages on behalf of users without requiring interactive authentication.

<Tabs>
  <Tab title="JavaScript" language="typescript">
## Prerequisites

Get your **API key** by creating a new app in your [Alchemy Dashboard](https://dashboard.alchemy.com/apps). Make sure your desired network is enabled for your app under the Networks tab.

## Step 1: Generate an Access Key

Generate a secure access key for authentication. This key is never sent to the server -- a public key is derived from it when interacting with the API.

<Warning>
**Critical: Save your access key securely!**

This access key is required to control your server wallet and cannot be recovered if lost. Make sure to store it in a secure location.

</Warning>

<CodeBlocks>

```ts twoslash evm.ts
import { generateAccessKey } from "@account-kit/signer";

// Generate a random access key
const accessKey = generateAccessKey();
console.log("Access key:", accessKey);

// Store this securely - you'll need it to control the server signer
```

</CodeBlocks>

## Step 2: Create the server authentication provider

Before you can send transactions, you need a way to sign them. Create a server authentication provider using the access key from the previous step:

<CodeBlocks>

```ts twoslash evm.ts
import { createServerSigner } from "@account-kit/signer";

const signer = await createServerSigner({
  auth: {
    accessKey: "your-access-key-here",
  },
  connection: {
    apiKey: "your-alchemy-api-key",
  },
});

console.log("Signer address:", await signer.getAddress());
```

</CodeBlocks>

<Tip>
  Want to use the same access key to control multiple server authentication providers? Check out
  the example below to learn how to use `auth.accountId` to create multiple
  providers that you can control with the same access key.
</Tip>

<Accordion title="Multiple authentication providers per access key">

```ts twoslash
import { createServerSigner } from "@account-kit/signer";

const businessSigner = await createServerSigner({
  auth: {
    accessKey: "your-access-key-here",
    accountId: "business",
  },
  connection: {
    apiKey: "your-alchemy-api-key",
  },
});

const personalSigner = await createServerSigner({
  auth: {
    accessKey: "your-access-key-here", // same access key
    accountId: "personal", // different account ID
  },
  connection: {
    apiKey: "your-alchemy-api-key",
  },
});

// These will have different addresses despite using the same access key
console.log("Business address:", await businessSigner.getAddress());
console.log("Personal address:", await personalSigner.getAddress());
```

</Accordion>

## Step 3: Send a transaction

You can now send transactions using the Smart Account Client:

<CodeBlocks>

```ts twoslash evm.ts
import { createSmartWalletClient, alchemyWalletTransport } from "@alchemy/wallet-apis";
import { baseSepolia } from "viem/chains";

// Create Smart Wallet Client using the signer from Step 2
const client = createSmartWalletClient({
  transport: alchemyWalletTransport({
    apiKey: "your-alchemy-api-key",
  }),
  chain: baseSepolia,
  signer,
  paymaster: { policyId: "your-sponsor-gas-policy-id" }, // Make sure enabled on Base Sepolia
});

// Send a sponsored transaction
const { id } = await client.sendCalls({
  calls: [
    {
      to: "0x1234567890123456789012345678901234567890",
      value: BigInt(0),
      data: "0x",
    },
  ],
});
console.log("Transaction sent:", id);
```

</CodeBlocks>

## Solana support

Server wallets also work on Solana. To start sending sponsored transactions on Solana, set up a Solana sponsor gas policy in the [dashboard](https://dashboard.alchemy.com/gas-manager) and follow the guide below.

<CodeBlocks>

```ts twoslash solana.ts
import { createServerSigner } from "@account-kit/signer";
import { Connection, SystemProgram, PublicKey } from "@solana/web3.js";

// Set up Solana connection
const connection = new Connection(
  `https://solana-devnet.g.alchemy.com/v2/your-alchemy-api-key`,
);

const signer = await createServerSigner({
  auth: { accessKey: "your-access-key" },
  connection: { apiKey: "your-alchemy-api-key" },
});

// Convert the signer to a Solana-compatible signer
const solanaSigner = signer.toSolanaSigner();

// Build transaction instructions
const instructions = [
  SystemProgram.transfer({
    fromPubkey: new PublicKey(solanaSigner.address),
    toPubkey: new PublicKey(solanaSigner.address),
    lamports: 0,
  }),
];

// Add sponsorship
const tx = await solanaSigner.addSponsorship(
  instructions,
  connection,
  "your-solana-sponsorship-policy-id", // Make sure enabled on Solana devnet
);

// Sign the transaction
await solanaSigner.addSignature(tx);

// Send the transaction
const hash = await connection.sendTransaction(tx);
console.log("Transaction sent:", hash);
```

</CodeBlocks>

  </Tab>
</Tabs>