solana-kit-migration
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSolana Kit Migration Assistant
Solana Kit 迁移助手
This skill helps you navigate the transition between (v1.x) and (formerly web3.js 2.0), providing guidance on when to use each library and how to migrate between them.
@solana/web3.js@solana/kit本技能可帮助你完成(v1.x版本)与(原web3.js 2.0)之间的过渡,指导你何时使用各个库以及如何在它们之间进行迁移。
@solana/web3.js@solana/kitOverview
概述
The Solana JavaScript ecosystem has two major SDK options:
| Library | Status | Use Case |
|---|---|---|
| Maintenance mode | Legacy projects, Anchor-dependent apps |
| Active development | New projects, performance-critical apps |
Key Decision: is the future, but migration isn't always straightforward.
@solana/kitSolana JavaScript生态系统有两个主要的SDK选项:
| 库 | 状态 | 使用场景 |
|---|---|---|
| 维护模式 | 遗留项目、依赖Anchor的应用 |
| 活跃开发中 | 新项目、对性能要求高的应用 |
核心决策:是未来的方向,但迁移并非总是一帆风顺。
@solana/kitWhen to Use Each Library
何时使用各个库
Use @solana/kit When:
选择@solana/kit的场景:
- Starting a new project without Anchor dependencies
- Bundle size matters - Kit is tree-shakeable (26% smaller bundles)
- Performance is critical - ~200ms faster confirmation latency, 10x faster crypto ops
- Using standard programs (System, Token, Associated Token)
- Building browser applications where bundle size impacts load time
- Type safety is important - Better TypeScript support catches errors at compile time
- Using modern JavaScript - Native BigInt, WebCrypto, AsyncIterators
- 启动新项目且不依赖Anchor
- 包体积很重要 - Kit支持摇树优化(包体积小26%)
- 性能要求严苛 - 确认延迟快约200ms,加密操作速度提升10倍
- 使用标准程序(System、Token、Associated Token)
- 构建浏览器应用 - 包体积会影响加载时间
- 类型安全很关键 - 更完善的TypeScript支持可在编译时捕获错误
- 使用现代JavaScript - 原生支持BigInt、WebCrypto、AsyncIterators
Use @solana/web3.js (v1.x) When:
选择@solana/web3.js (v1.x)的场景:
- Using Anchor - Anchor doesn't support Kit out of the box yet
- Existing large codebase - Migration cost outweighs benefits
- Dependencies require v1 - Check if your SDKs support Kit
- Rapid prototyping - v1's OOP style may be more familiar
- Documentation/examples - More community resources for v1
- 使用Anchor - Anchor目前尚未原生支持Kit
- 已有大型代码库 - 迁移成本超过收益
- 依赖项要求v1版本 - 检查你的SDK是否支持Kit
- 快速原型开发 - v1的面向对象风格可能更易上手
- 文档/示例资源 - v1拥有更多社区资源
Use Both (Hybrid Approach) When:
混合使用两者的场景:
- Gradual migration - Use for interoperability
@solana/compat - Mixed dependencies - Some libs require v1, some support Kit
- Feature-by-feature migration - Convert hot paths first
- 渐进式迁移 - 使用实现互操作性
@solana/compat - 依赖项混合 - 部分库需要v1,部分支持Kit
- 按功能模块迁移 - 先转换性能关键路径
Quick Decision Flowchart
快速决策流程图
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 │START
│
├─ 新项目? ─────────────────────────────────────────┐
│ │ │
│ ├─ 使用Anchor? ──► 是 ──► 使用@solana/web3.js │
│ │ │
│ └─ 不使用Anchor? ──► 使用@solana/kit │
│ │
└─ 已有项目? ────────────────────────────────────┤
│ │
├─ 存在性能问题? ──► 考虑迁移 │
│ │
├─ 包体积过大? ──► 考虑迁移 │
│ │
└─ 运行正常? ──► 继续使用当前SDK │Instructions for Migration Analysis
迁移分析步骤
When a user asks about migration, follow these steps:
当用户询问迁移相关问题时,请遵循以下步骤:
Step 1: Analyze Current Codebase
步骤1:分析当前代码库
Run the migration analysis script to detect:
- Which SDK version is currently used
- Anchor dependencies
- Third-party SDK dependencies
- Usage patterns that need migration
bash
undefined运行迁移分析脚本以检测:
- 当前使用的SDK版本
- Anchor依赖项
- 第三方SDK依赖项
- 需要迁移的使用模式
bash
undefinedUse the analyze-migration.sh script in scripts/
使用scripts/目录下的analyze-migration.sh脚本
./scripts/analyze-migration.sh /path/to/project
undefined./scripts/analyze-migration.sh /path/to/project
undefinedStep 2: Check Dependencies
步骤2:检查依赖项
Look for these blocking dependencies:
- or
@coral-xyz/anchor- Wait for Anchor Kit support@project-serum/anchor - SDKs that haven't migrated (check their package.json)
注意以下可能阻碍迁移的依赖项:
- 或
@coral-xyz/anchor- 等待Anchor对Kit的支持@project-serum/anchor - 尚未完成迁移的SDK(检查其package.json)
Step 3: Assess Migration Complexity
步骤3:评估迁移复杂度
Count occurrences of these patterns that need changes:
- →
new Connection(...)createSolanaRpc(...) - →
Keypair.fromSecretKey(...)createKeyPairSignerFromBytes(...) - →
new PublicKey(...)address(...) - →
new Transaction()createTransactionMessage(...) - Class-based patterns → Functional composition with
pipe()
统计需要修改的以下模式的出现次数:
- →
new Connection(...)createSolanaRpc(...) - →
Keypair.fromSecretKey(...)createKeyPairSignerFromBytes(...) - →
new PublicKey(...)address(...) - →
new Transaction()createTransactionMessage(...) - 基于类的模式 → 使用进行函数式组合
pipe()
Step 4: Recommend Strategy
步骤4:推荐迁移策略
Based on findings, recommend:
- Full Migration: If no blockers and < 50 migration points
- Gradual Migration: If 50-200 migration points, use
@solana/compat - Wait: If Anchor-dependent or critical SDKs don't support Kit
- Hybrid: If only specific modules need Kit performance
根据分析结果,推荐以下策略:
- 完全迁移:无阻碍项且迁移点少于50个
- 渐进式迁移:迁移点在50-200个之间,使用
@solana/compat - 等待:依赖Anchor或关键SDK不支持Kit
- 混合模式:仅特定模块需要Kit的性能提升
API Migration Reference
API迁移参考
See for complete mappings. Key conversions:
resources/api-mappings.md完整的映射关系请查看。核心转换示例:
resources/api-mappings.mdConnection → RPC
Connection → RPC
typescript
// 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();typescript
// 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
Keypair → KeyPairSigner
typescript
// v1
const keypair = Keypair.fromSecretKey(secretKey);
console.log(keypair.publicKey.toBase58());
// Kit
const signer = await createKeyPairSignerFromBytes(secretKey);
console.log(signer.address);typescript
// v1
const keypair = Keypair.fromSecretKey(secretKey);
console.log(keypair.publicKey.toBase58());
// Kit
const signer = await createKeyPairSignerFromBytes(secretKey);
console.log(signer.address);Transaction Building
交易构建
typescript
// 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
),
);typescript
// 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
),
);Edge Cases & Gotchas
边缘情况与注意事项
1. BigInt Conversion
1. BigInt转换
Kit uses native BigInt everywhere. Watch for:
typescript
// 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);Kit全程使用原生BigInt。请注意:
typescript
// 错误写法 - 会失败
const amount = 1000000000;
// 正确写法
const amount = 1_000_000_000n;
// 或
const amount = BigInt(1000000000);
// 或使用工具函数
const amount = lamports(1_000_000_000n);2. Base58 Encoding Errors
2. Base58编码错误
Kit may require explicit encoding:
typescript
// If you see: "Encoded binary (base 58) data should be less than 128 bytes"
// Add encoding parameter:
await rpc.getAccountInfo(address, { encoding: 'base64' }).send();Kit可能需要显式指定编码:
typescript
// 如果出现错误:"Encoded binary (base 58) data should be less than 128 bytes"
// 添加编码参数:
await rpc.getAccountInfo(address, { encoding: 'base64' }).send();3. Async Keypair Generation
3. 异步密钥对生成
Kit keypair creation is async (uses WebCrypto):
typescript
// v1 - synchronous
const keypair = Keypair.generate();
// Kit - MUST await
const keypair = await generateKeyPairSigner();Kit的密钥对创建是异步操作(使用WebCrypto):
typescript
// v1 - 同步
const keypair = Keypair.generate();
// Kit - 必须使用await
const keypair = await generateKeyPairSigner();4. RPC Method Chaining
4. RPC方法链式调用
Kit RPC calls require :
.send()typescript
// v1
const balance = await connection.getBalance(pubkey);
// Kit - don't forget .send()!
const { value: balance } = await rpc.getBalance(address).send();Kit的RPC调用需要:
.send()typescript
// v1
const balance = await connection.getBalance(pubkey);
// Kit - 不要忘记.send()!
const { value: balance } = await rpc.getBalance(address).send();5. PublicKey vs Address
5. PublicKey vs Address
These are different types and not interchangeable:
typescript
// Use @solana/compat for conversion
import { fromLegacyPublicKey, toLegacyPublicKey } from '@solana/compat';
const kitAddress = fromLegacyPublicKey(legacyPublicKey);
const legacyPubkey = toLegacyPublicKey(kitAddress);这是两种不同的类型,不可互换:
typescript
// 使用@solana/compat进行转换
import { fromLegacyPublicKey, toLegacyPublicKey } from '@solana/compat';
const kitAddress = fromLegacyPublicKey(legacyPublicKey);
const legacyPubkey = toLegacyPublicKey(kitAddress);6. Transaction Signing
6. 交易签名
Signing flow is different:
typescript
// 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);签名流程不同:
typescript
// v1
transaction.sign(keypair);
// 或
const signed = await connection.sendTransaction(tx, [keypair]);
// Kit - 使用签名者模式
const signedTx = await signTransactionMessageWithSigners(txMessage);
const signature = await sendAndConfirmTransaction(signedTx);7. Anchor Incompatibility
7. Anchor不兼容
Anchor generates v1 types. If using Anchor:
typescript
// 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/compatAnchor生成v1版本的类型。如果使用Anchor:
typescript
// 继续使用@solana/web3.js处理Anchor相关交互
import { Connection, PublicKey } from '@solana/web3.js';
import { Program } from '@coral-xyz/anchor';
// 如果需要,可在非Anchor部分使用Kit
// 通过@solana/compat实现桥接8. Subscription Handling
8. 订阅处理
Kit uses AsyncIterators:
typescript
// 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();Kit使用AsyncIterators:
typescript
// v1
const subscriptionId = connection.onAccountChange(pubkey, callback);
connection.removeAccountChangeListener(subscriptionId);
// Kit - 使用AbortController
const abortController = new AbortController();
const notifications = await rpcSubscriptions
.accountNotifications(address)
.subscribe({ abortSignal: abortController.signal });
for await (const notification of notifications) {
// 处理通知
}
// 取消订阅:
abortController.abort();9. VersionedTransaction Migration
9. VersionedTransaction迁移
typescript
// v1
const versionedTx = new VersionedTransaction(messageV0);
// Kit - transactions are versioned by default
const tx = createTransactionMessage({ version: 0 });typescript
// v1
const versionedTx = new VersionedTransaction(messageV0);
// Kit - 交易默认支持版本化
const tx = createTransactionMessage({ version: 0 });10. Lookup Tables
10. 地址查找表
Address Lookup Tables work differently:
typescript
// 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地址查找表的处理方式不同:
typescript
// v1
const lookupTable = await connection.getAddressLookupTable(tableAddress);
const messageV0 = new TransactionMessage({...}).compileToV0Message([lookupTable.value]);
// Kit
// 查找表在交易编译阶段处理
// 请查看resources/lookup-tables-example.mdAlternative: Consider Gill
替代方案:考虑Gill
If Kit feels too low-level, consider Gill:
- Built on Kit primitives
- Higher-level abstractions
- Simpler API for common tasks
- Full Kit compatibility
typescript
import { createSolanaClient, sendSol } from 'gill';
const client = createSolanaClient({ rpcUrl });
await sendSol(client, { from: signer, to: recipient, amount: lamports(1n) });如果你觉得Kit的层级过低,可以考虑Gill:
- 基于Kit原语构建
- 更高层级的抽象
- 常见任务的简化API
- 与Kit完全兼容
typescript
import { createSolanaClient, sendSol } from 'gill';
const client = createSolanaClient({ rpcUrl });
await sendSol(client, { from: signer, to: recipient, amount: lamports(1n) });Guidelines
指导原则
- Always check Anchor compatibility before recommending Kit migration
- Recommend for gradual migrations
@solana/compat - Bundle size benefits matter most for browser applications
- Performance benefits matter most for high-throughput backends
- Don't migrate stable, working code without clear benefits
- Test thoroughly - Kit has different error types and behaviors
- 在推荐Kit迁移前,务必检查Anchor兼容性
- 对于渐进式迁移,推荐使用
@solana/compat - 包体积优化对浏览器应用最为重要
- 性能提升对高吞吐量后端最为关键
- 若无明确收益,不要迁移稳定运行的代码
- 务必充分测试 - Kit的错误类型和行为与v1不同
Files in This Skill
本技能包含的文件
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 casessolana-kit-migration/
├── SKILL.md # 本文档
├── scripts/
│ ├── analyze-migration.sh # 代码库分析脚本
│ └── detect-patterns.js # 模式检测工具
├── resources/
│ ├── api-mappings.md # 完整API参考
│ ├── compatibility-matrix.md # SDK兼容性信息
│ └── package-comparison.md # 功能对比
├── examples/
│ ├── v1-to-kit/ # 迁移示例
│ │ ├── basic-transfer.md
│ │ ├── token-operations.md
│ │ └── subscription-handling.md
│ └── mixed-codebase/ # 混合模式示例
│ └── anchor-with-kit.md
└── docs/
└── edge-cases.md # 详细边缘情况说明Notes
说明
- Kit was released as @solana/web3.js@2.0.0 on December 16, 2024
- It was later renamed to @solana/kit to avoid confusion
- The 1.x line is in maintenance mode but still widely used
- Migration tooling is evolving - check for updates regularly
- Kit于2024年12月16日以@solana/web3.js@2.0.0版本发布
- 随后更名为@solana/kit以避免混淆
- 1.x版本处于维护模式,但仍被广泛使用
- 迁移工具正在持续演进 - 请定期检查更新