# Server wallets

> Control wallets programmatically using access keys

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

<Info>`@alchemy/wallet-apis` (v5.x.x) is currently in beta but is the recommended replacement for `@account-kit/wallet-client` (v4.x.x). If you run into any issues, please [reach out](mailto:support@alchemy.com).</Info>

<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>