关于 solana-kit-migration
此技能帮助开发者在 `@solana/web3.js` 与 `@solana/kit` 之间做出选择并规划迁移。它分析依赖和代码模式,再建议完整、渐进、混合迁移或暂缓迁移。
主要功能
- 01比较 SDK 适用场景
- 02分析代码与依赖
- 03检测待迁移代码模式
- 04查询 API 变更映射
- 05建议迁移策略
适用场景
- 01评估 Solana 项目的迁移条件
- 02借助 `@solana/compat` 规划渐进迁移
- 03查找 Anchor 或 SDK 迁移阻碍
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ sendaifun/ skills --skill solana-kit-migration安装后在 Claude Code 中输入/solana-kit-migration确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
docs/edge-cases.mdexamples/mixed-codebase/anchor-with-kit.mdexamples/v1-to-kit/basic-transfer.mdsubscription-handling.mdtoken-operations.mdresources/api-mappings.mdcompatibility-matrix.mdpackage-comparison.mdscripts/analyze-migration.shdetect-patterns.js详细介绍
Solana Kit 迁移助手
此技能可帮助你了解从 @solana/web3.js(v1.x)迁移到 @solana/kit(前身为 web3.js 2.0)的流程,并指导你判断何时使用各个库以及如何在它们之间迁移。
概览
Solana JavaScript 生态系统有两种主要的 SDK 选择:
| 库 | 状态 | 使用场景 |
|---|---|---|
@solana/web3.js (1.x) | 维护模式 | 旧版项目、依赖 Anchor 的应用 |
@solana/kit | 积极开发中 | 新项目、对性能要求高的应用 |
关键决策:@solana/kit 是未来的发展方向,但迁移并非总是简单直接。
何时使用各个库
使用 @solana/kit 的情况:
- 启动不依赖 Anchor 的新项目
- 关注包体积——Kit 支持 tree-shaking(包体积缩小 26%)
- 对性能要求高——确认延迟快约 200ms,加密操作快 10 倍
- 使用标准程序(System、Token、Associated Token)
- 构建浏览器应用,其中包体积会影响加载时间
- 重视类型安全——更好的 TypeScript 支持可在编译时发现错误
- 使用现代 JavaScript——原生 BigInt、WebCrypto、AsyncIterators
使用 @solana/web3.js(v1.x)的情况:
- 使用 Anchor——Anchor 目前尚未开箱支持 Kit
- 现有大型代码库——迁移成本超过其收益
- 依赖项要求 v1——检查你的 SDK 是否支持 Kit
- 快速原型开发——v1 的 OOP 风格可能更熟悉
- 文档/示例——v1 有更多社区资源
同时使用两者(混合方案)的情况:
- 逐步迁移——使用
@solana/compat实现互操作 - 依赖项混用——部分库要求 v1,部分库支持 Kit
- 按功能逐步迁移——优先转换热点路径
快速决策流程图
START
│
├─ New project? ─────────────────────────────────────────┐
│ │ │
│ ├─ Using Anchor? ──► YES ──► Use @solana/web3.js │
│ │ │
│ └─ No Anchor? ──► Use @solana/kit │
│ │
└─ Existing project? ────────────────────────────────────┤
│ │
├─ Performance issues? ──► Consider migration │
│ │
├─ Bundle size issues? ──► Consider migration │
│ │
└─ Working fine? ──► Stay with current SDK │
迁移分析说明
当用户询问迁移事宜时,请按以下步骤操作:
步骤 1:分析当前代码库
运行迁移分析脚本以检测:
- 当前使用的 SDK 版本
- Anchor 依赖项
- 第三方 SDK 依赖项
- 需要迁移的使用模式
# Use the analyze-migration.sh script in scripts/
./scripts/analyze-migration.sh /path/to/project
步骤 2:检查依赖项
查找以下阻塞性依赖项:
@coral-xyz/anchor或@project-serum/anchor——等待 Anchor 支持 Kit- 尚未迁移的 SDK(检查其 package.json)
步骤 3:评估迁移复杂度
统计以下需要更改的模式的出现次数:
new Connection(...)→createSolanaRpc(...)Keypair.fromSecretKey(...)→createKeyPairSignerFromBytes(...)new PublicKey(...)→address(...)new Transaction()→createTransactionMessage(...)- 基于类的模式 → 使用
pipe()进行函数式组合
步骤 4:建议策略
根据调查结果,建议:
- 完整迁移:没有阻塞因素,且迁移点少于 50 处
- 逐步迁移:迁移点为 50–200 处,使用
@solana/compat - 等待:依赖 Anchor,或关键 SDK 不支持 Kit
- 混合方案:仅特定模块需要 Kit 的性能优势
API 迁移参考
完整映射请参阅 resources/api-mappings.md。主要转换如下:
Connection → RPC
// v1
const connection = new Connection(url, 'confirmed');
const balance = await connection.getBalance(pubkey);
// Kit
const rpc = createSolanaRpc(url);
const { value: balance } = await rpc.getBalance(address).send();
Keypair → KeyPairSigner
// v1
const keypair = Keypair.fromSecretKey(secretKey);
console.log(keypair.publicKey.toBase58());
// Kit
const signer = await createKeyPairSignerFromBytes(secretKey);
console.log(signer.address);
构建交易
// v1
const tx = new Transaction().add(
SystemProgram.transfer({
fromPubkey: sender.publicKey,
toPubkey: recipient,
lamports: amount,
})
);
tx.recentBlockhash = blockhash;
tx.feePayer = sender.publicKey;
// Kit
const tx = pipe(
createTransactionMessage({ version: 0 }),
tx => setTransactionMessageFeePayer(sender.address, tx),
tx => setTransactionMessageLifetimeUsingBlockhash(blockhash, tx),
tx => appendTransactionMessageInstruction(
getTransferSolInstruction({
source: sender,
destination: address(recipient),
amount: lamports(BigInt(amount)),
}),
tx
),
);
边缘情况与注意事项
1. BigInt 转换
Kit 处处使用原生 BigInt。请注意:
// WRONG - will fail
const amount = 1000000000;
// CORRECT
const amount = 1_000_000_000n;
// or
const amount = BigInt(1000000000);
// or use helper
const amount = lamports(1_000_000_000n);
2. Base58 编码错误
Kit 可能要求显式编码:
// If you see: "Encoded binary (base 58) data should be less than 128 bytes"
// Add encoding parameter:
await rpc.getAccountInfo(address, { encoding: 'base64' }).send();
3. 异步生成 Keypair
Kit 的 keypair 创建是异步的(使用 WebCrypto):
// v1 - synchronous
const keypair = Keypair.generate();
// Kit - MUST await
const keypair = await generateKeyPairSigner();
4. RPC 方法链式调用
Kit 的 RPC 调用需要 .send():
// v1
const balance = await connection.getBalance(pubkey);
// Kit - don't forget .send()!
const { value: balance } = await rpc.getBalance(address).send();
5. PublicKey 与 Address
这两者是不同类型,不能互换:
// Use @solana/compat for conversion
import { fromLegacyPublicKey, toLegacyPublicKey } from '@solana/compat';
const kitAddress = fromLegacyPublicKey(legacyPublicKey);
const legacyPubkey = toLegacyPublicKey(kitAddress);
6. 交易签名
签名流程有所不同:
// v1
transaction.sign(keypair);
// or
const signed = await connection.sendTransaction(tx, [keypair]);
// Kit - use signer pattern
const signedTx = await signTransactionMessageWithSigners(txMessage);
const signature = await sendAndConfirmTransaction(signedTx);
7. Anchor 不兼容
Anchor 会生成 v1 类型。如果使用 Anchor:
// Keep @solana/web3.js for Anchor interactions
import { Connection, PublicKey } from '@solana/web3.js';
import { Program } from '@coral-xyz/anchor';
// Use Kit for non-Anchor parts if needed
// Bridge with @solana/compat
8. 订阅处理
Kit 使用 AsyncIterators:
// v1
const subscriptionId = connection.onAccountChange(pubkey, callback);
connection.removeAccountChangeListener(subscriptionId);
// Kit - use AbortController
const abortController = new AbortController();
const notifications = await rpcSubscriptions
.accountNotifications(address)
.subscribe({ abortSignal: abortController.signal });
for await (const notification of notifications) {
// handle notification
}
// To unsubscribe:
abortController.abort();
9. VersionedTransaction 迁移
// v1
const versionedTx = new VersionedTransaction(messageV0);
// Kit - transactions are versioned by default
const tx = createTransactionMessage({ version: 0 });
10. 查找表
地址查找表的工作方式有所不同:
// v1
const lookupTable = await connection.getAddressLookupTable(tableAddress);
const messageV0 = new TransactionMessage({...}).compileToV0Message([lookupTable.value]);
// Kit
// Lookup tables are handled in transaction compilation
// See resources/lookup-tables-example.md
替代方案:考虑 Gill
如果你觉得 Kit 太底层,可以考虑 Gill:
- 基于 Kit 基元构建
- 更高层次的抽象
- 常见任务的 API 更简单
- 完全兼容 Kit
import { createSolanaClient, sendSol } from 'gill';
const client = createSolanaClient({ rpcUrl });
await sendSol(client, { from: signer, to: recipient, amount: lamports(1n) });
指南
- 推荐迁移到 Kit 之前,务必检查与 Anchor 的兼容性
- 建议使用
@solana/compat进行渐进式迁移 - 对于浏览器应用,包体积优势最为显著
- 对于高吞吐量后端,性能优势最为显著
- 如果没有明确收益,不要迁移稳定运行的代码
- 彻底测试——Kit 的错误类型和行为有所不同
此技能包含的文件
solana-kit-migration/
├── SKILL.md # This file
├── scripts/
│ ├── analyze-migration.sh # Codebase analysis script
│ └── detect-patterns.js # Pattern detection utility
├── resources/
│ ├── api-mappings.md # Complete API reference
│ ├── compatibility-matrix.md # SDK compatibility info
│ └── package-comparison.md # Feature comparison
├── examples/
│ ├── v1-to-kit/ # Migration examples
│ │ ├── basic-transfer.md
│ │ ├── token-operations.md
│ │ └── subscription-handling.md
│ └── mixed-codebase/ # Hybrid approach examples
│ └── anchor-with-kit.md
└── docs/
└── edge-cases.md # Detailed edge cases
备注
- Kit 于 2024 年 12 月 16 日以 @solana/[email protected] 的名称发布
- 后来更名为 @solana/kit,以避免混淆
- 1.x 系列处于维护模式,但仍被广泛使用
- 迁移工具仍在不断完善——请定期查看更新
评论
支持 Markdown