китаев.tech

Обзор провайдеров 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.


Сравнение

КритерийSafeZeroDevAlchemy Account Kit
Что даёт SDKКонтракт-кошелёк (multisig) + модуль ERC-4337Modular smart account Kernel (ERC-7579) + клиентLight Account / Modular Account + клиент
Bundler «из коробки»Обычно внешний (Pimlico, Candide и др.)Свой / партнёрский (Ultra Relay и политики)Alchemy Rundler через их RPC
PaymasterПодключается отдельно (часто Pimlico)Gas Policies в продукте ZeroDevGas 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 keysdApp уже на Alchemy, нужен gasless быстрее

«Без своего Bundler» у Safe чаще значит «взять чужой managed Bundler», у ZeroDev и Alchemy — «использовать их managed-инфру». Контракты аккаунтов у всех трёх открыты; закрытость — в off-chain политиках и биллинге.


Один и тот же шаг: клиент smart-аккаунта

Задача одна: получить адрес аккаунта и отправить gasless-вызов. Отличается только SDK. Ниже — минимальные каркасы (Sepolia, ключ и API — из env).

Safe + Pimlico (Bundler / Paymaster снаружи)

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

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

typescript
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-продукты; их условия читайте у конкретного провайдера.


Что выбрать

НужноСмотреть в сторону
Мультиподпись, казна, уже есть SafeSafe + managed Bundler/Paymaster
Session keys, кастомные валидаторы, 7579-модулиZeroDev Kernel
Быстро gasless на стеке AlchemyAccount 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 — разные экосистемы. Плагин от одного стека не «просто ставится» на другой.


Что дальше

Материалы китаev.tech публикуются в образовательных целях и не являются инвестиционной рекомендацией. Примеры кода и описания протоколов — для обучения; использование в продакшне на ваш собственный риск. Дисклеймер и политика конфиденциальности.