Skip to content
Alchemy Logo

Server wallets

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

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

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.

Get your API key by creating a new app in your Alchemy Dashboard. Make sure your desired network is enabled for your app under the Networks tab.

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.

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.

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

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:

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());

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.

Multiple authentication providers per access key
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());

You can now send transactions using the Smart Account Client:

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

Server wallets also work on Solana. To start sending sponsored transactions on Solana, set up a Solana sponsor gas policy in the dashboard and follow the guide below.

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);
Was this page helpful?