Обзор провайдеров Account Abstraction: Safe, ZeroDev, Alchemy Account Kit
Сравниваем Safe, ZeroDev и Alchemy Account Kit — три готовых SDK для запуска Account Abstraction без своего Bundler.
Три готовых стека без своего Bundler
Свой Bundler и Paymaster поднимать не обязательно: можно взять SDK, где smart-аккаунт, RPC к EntryPoint и спонсорство газа уже связаны.
Ниже — три распространённых варианта: Safe, ZeroDev (Kernel) и Alchemy Account Kit. Сравнение нейтральное: кастодиальность, сети, paymaster, порог входа. Базовые понятия — в Account Abstraction и ERC-4337.
Сравнение
| Критерий | Safe | ZeroDev | Alchemy Account Kit |
|---|---|---|---|
| Что даёт SDK | Контракт-кошелёк (multisig) + модуль ERC-4337 | Modular smart account Kernel (ERC-7579) + клиент | Light Account / Modular Account + клиент |
| Bundler «из коробки» | Обычно внешний (Pimlico, Candide и др.) | Свой / партнёрский (Ultra Relay и политики) | Alchemy Rundler через их RPC |
| Paymaster | Подключается отдельно (часто Pimlico) | Gas Policies в продукте ZeroDev | Gas Manager в кабинете Alchemy |
| Кастодиальность ключей | Некастодиально: порог владельцев Safe | Некастодиально: signer / модули валидации, которые вы задаёте | Некастодиально для signer; Embedded Accounts — отдельный auth-слой Alchemy |
| Сильная сторона | Аудиты, TVL, DAO/treasury, знакомый Safe UX | Плагины, session keys, модульность 7579 | Один вендор с RPC + AA, быстрый старт |
| Слабая сторона | AA — модуль поверх Safe; bundler не «встроен» | Меньше «всё в одном кабинете», чем у Alchemy | Привязка к экосистеме Alchemy (RPC / CU) |
| Порог входа | Средний: Safe + отдельный bundler/paymaster | Средний: Kernel + политики газа | Низкий, если RPC уже Alchemy |
| Когда смотреть | Мультиподпись, казна, compliance | Кастомная логика валидации / session keys | dApp уже на Alchemy, нужен gasless быстрее |
«Без своего Bundler» у Safe чаще значит «взять чужой managed Bundler», у ZeroDev и Alchemy — «использовать их managed-инфру». Контракты аккаунтов у всех трёх открыты; закрытость — в off-chain политиках и биллинге.
Один и тот же шаг: клиент smart-аккаунта
Задача одна: получить адрес аккаунта и отправить gasless-вызов. Отличается только SDK. Ниже — минимальные каркасы (Sepolia, ключ и API — из env).
Safe + Pimlico (Bundler / Paymaster снаружи)
import { createSmartAccountClient } from "permissionless";
import { createPimlicoClient } from "permissionless/clients/pimlico";
import { toSafeSmartAccount } from "permissionless/accounts";
import { createPublicClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { sepolia } from "viem/chains";
import { entryPoint07Address } from "viem/account-abstraction";
const apiKey = process.env.PIMLICO_API_KEY;
const privateKey = process.env.PRIVATE_KEY as `0x${string}` | undefined;
if (!apiKey || !privateKey) {
throw new Error("Задайте PIMLICO_API_KEY и PRIVATE_KEY");
}
const pimlicoUrl = `https://api.pimlico.io/v2/${sepolia.id}/rpc?apikey=${apiKey}`;
const publicClient = createPublicClient({
chain: sepolia,
transport: http("https://ethereum-sepolia-rpc.publicnode.com"),
});
const pimlicoClient = createPimlicoClient({
transport: http(pimlicoUrl),
entryPoint: { address: entryPoint07Address, version: "0.7" },
});
const account = await toSafeSmartAccount({
client: publicClient,
owners: [privateKeyToAccount(privateKey)],
entryPoint: { address: entryPoint07Address, version: "0.7" },
version: "1.4.1",
});
const client = createSmartAccountClient({
account,
chain: sepolia,
bundlerTransport: http(pimlicoUrl),
paymaster: pimlicoClient,
});
console.log("Safe smart account:", account.address);ZeroDev (Kernel)
import { createPublicClient, http } from "viem";
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
import { sepolia } from "viem/chains";
import {
createKernelAccount,
createKernelAccountClient,
createZeroDevPaymasterClient,
} from "@zerodev/sdk";
import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator";
import { getEntryPoint, KERNEL_V3_1 } from "@zerodev/sdk/constants";
const projectId = process.env.ZERODEV_PROJECT_ID;
if (!projectId) throw new Error("Задайте ZERODEV_PROJECT_ID");
const rpc = `https://rpc.zerodev.app/api/v2/bundler/${projectId}`;
const publicClient = createPublicClient({
chain: sepolia,
transport: http(rpc),
});
const signer = privateKeyToAccount(
(process.env.PRIVATE_KEY as `0x${string}`) ?? generatePrivateKey(),
);
const entryPoint = getEntryPoint("0.7");
const validator = await signerToEcdsaValidator(publicClient, {
signer,
entryPoint,
kernelVersion: KERNEL_V3_1,
});
const account = await createKernelAccount(publicClient, {
plugins: { sudo: validator },
entryPoint,
kernelVersion: KERNEL_V3_1,
});
const paymaster = createZeroDevPaymasterClient({
chain: sepolia,
transport: http(`https://rpc.zerodev.app/api/v2/paymaster/${projectId}`),
});
const client = createKernelAccountClient({
account,
chain: sepolia,
bundlerTransport: http(rpc),
paymaster,
});
console.log("Kernel account:", account.address);Alchemy Account Kit (Light Account)
import { createLightAccountAlchemyClient } from "@account-kit/smart-contracts";
import { sepolia, alchemy } from "@account-kit/infra";
import { LocalAccountSigner } from "@aa-sdk/core";
import { http } from "viem";
import { generatePrivateKey } from "viem/accounts";
const apiKey = process.env.ALCHEMY_API_KEY;
if (!apiKey) throw new Error("Задайте ALCHEMY_API_KEY");
const signer = LocalAccountSigner.privateKeyToAccountSigner(
(process.env.PRIVATE_KEY as `0x${string}`) ?? generatePrivateKey(),
);
const client = await createLightAccountAlchemyClient({
chain: sepolia,
signer,
transport: alchemy({ apiKey }),
policyId: process.env.ALCHEMY_GAS_POLICY_ID, // Gas Manager policy
});
console.log("Light Account:", client.getAddress());Имена пакетов и minor-API у ZeroDev / Account Kit меняются чаще, чем у Safe. Перед продом сверяйте актуальные импорты в доке провайдера — логика сравнения (аккаунт / bundler / paymaster) остаётся той же.
Как это работает
Safe отдаёт модель аккаунта (владельцы, порог, модули). Чтобы закрыть путь UserOp → EntryPoint, к нему обычно стыкуют чужой Bundler и Paymaster.
ZeroDev центрируется на Kernel: валидаторы и executors подключаются модулями (ERC-7579). Инфра ZeroDev закрывает bundler и политики спонсорства под project id.
Alchemy Account Kit связывает контракт аккаунта с их RPC, Rundler и Gas Manager. Порог входа ниже, если приложение уже считает CU Alchemy; смена RPC-провайдера потом дороже.
Кастодиальность во всех трёх случаях — про то, кто контролирует signer / владельцев, а не про «ключи лежат у вендора по умолчанию». Исключения — отдельные embedded/auth-продукты; их условия читайте у конкретного провайдера.
Что выбрать
| Нужно | Смотреть в сторону |
|---|---|
| Мультиподпись, казна, уже есть Safe | Safe + managed Bundler/Paymaster |
| Session keys, кастомные валидаторы, 7579-модули | ZeroDev Kernel |
| Быстро gasless на стеке Alchemy | Account Kit + Gas Manager |
| Только Bundler/Paymaster, аккаунт свой | Pimlico (не в таблице выше) — infra без своего account SDK |
Менять провайдера позже = менять factory/аккаунт или модули и политики газа. Заложите миграцию в дизайн, если вендорный lock-in критичен.
Частые ошибки
Сравнивать только «есть ли gasless» → gasless есть у всех трёх через paymaster. Разница — где крутятся политики (чей кабинет), какой аккаунт on-chain и насколько легко уйти с их RPC.
Путать Safe multisig без 4337 и Safe+AA → классический Safe по-прежнему исполняется через обычные TX от владельцев. ERC-4337 появляется только с модулем / потоком UserOp.
Ждать полной взаимозаменяемости модулей → Kernel (7579), Alchemy Modular Account (свои плагины) и Safe modules — разные экосистемы. Плагин от одного стека не «просто ставится» на другой.
Что дальше
- Частые ошибки при переходе на Account Abstraction — газ UserOp, initCode, nonce
- Paymaster: как оплатить газ за пользователя — verifying paymaster на примере Pimlico
- Smart-аккаунт vs EOA — когда AA вообще нужен продукту