从手动 Borsh 迁移到 LUMOS:分步指南

发布: (2025年12月18日 GMT+8 07:15)
3 min read
原文: Dev.to

Source: Dev.to

迁移手动 Borsh 到 LUMOS:一步步指南的封面图片

为什么迁移?

  • 零运行时开销 – 生成的代码与手写 Borsh 完全相同
  • 类型同步 – TypeScript 和 Rust 始终保持一致
  • 降低维护成本 – 单一真相来源
  • 减少错误 – 消除序列化不匹配

迁移时间: 5‑30 分钟每个 struct/enum

第一步:审计现有代码

查找所有 Borsh 类型

Rust

# Find structs with Borsh derives
rg '#\[derive.*Borsh' --type rust

# Find Account macros
rg '#\[account\]' --type rust

TypeScript

# Find Borsh schemas
rg 'borsh\.(struct|rustEnum)' --type ts

第2步:前后示例

之前(手动 Borsh)

Rust (state.rs)

use anchor_lang::prelude::*;

#[account]
pub struct PlayerAccount {
    pub wallet: Pubkey,
    pub level: u16,
    pub experience: u64,
    pub items: Vec,
}

TypeScript (types.ts)

import { PublicKey } from '@solana/web3.js';
import * as borsh from '@coral-xyz/borsh';

export interface PlayerAccount {
  wallet: PublicKey;
  level: number;
  experience: number;
  items: PublicKey[];
}

export const PlayerAccountSchema = borsh.struct([
  borsh.publicKey('wallet'),
  borsh.u16('level'),
  borsh.u64('experience'),
  borsh.vec(borsh.publicKey(), 'items'),
]);

之后(LUMOS Schema)

创建 schema/player.lumos

#[solana]
#[account]
struct PlayerAccount {
    wallet: PublicKey,
    level: u16,
    experience: u64,
    items: [PublicKey],
}

生成代码:

lumos generate schema/player.lumos

Rust 和 TypeScript 均自动生成。

第 3 步:更新导入

Rust

// OLD:
use crate::state::PlayerAccount;

// NEW:
mod generated;
use generated::PlayerAccount;

TypeScript

// OLD:
import { PlayerAccount, PlayerAccountSchema } from './types';

// NEW:
import { PlayerAccount, PlayerAccountBorshSchema } from './generated';

第4步:验证二进制兼容性

关键: 确保 LUMOS‑生成的代码产生相同的字节。

#[test]
fn test_borsh_compatibility() {
    let player = PlayerAccount {
        wallet: Pubkey::new_unique(),
        level: 10,
        experience: 5000,
        items: vec![Pubkey::new_unique()],
    };

    // Serialize with manual implementation
    let manual_bytes = player.try_to_vec().unwrap();

    // Serialize with LUMOS‑generated implementation
    let generated_bytes = player.try_to_vec().unwrap();

    assert_eq!(manual_bytes, generated_bytes, "Binary output must match!");
}

类型映射参考

手动 Rust手动 TypeScriptLUMOS
PubkeyPublicKeyPublicKey
u16numberu16
u64numberu64
VecT[][T]
OptionT | undefinedOption
StringstringString
boolbooleanbool

Migration Checklist

  • 安装 LUMOS CLI:cargo install lumos-cli
  • 创建 .lumos 架构文件
  • 生成 Rust 和 TypeScript 代码
  • 更新现有代码中的导入
  • 运行二进制兼容性测试
  • 删除旧的手动类型定义
  • 在模式更改时更新 CI/CD 以重新生成

渐进迁移策略

您不必一次性迁移所有内容:

  • 阶段 1: 新类型 → 从一开始就使用 LUMOS
  • 阶段 2: 高 churn 类型 → 迁移经常更改的类型
  • 阶段 3: 稳定类型 → 迁移剩余的类型

CI/CD 集成

# .github/workflows/codegen.yml
name: Generate LUMOS Code

on: [push, pull_request]

jobs:
  generate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: cargo install lumos-cli
      - run: lumos generate schema/*.lumos
      - run: git diff --exit-code || (echo "Generated files outdated!" && exit 1)

快速开始

cargo install lumos-cli
lumos generate your-schema.lumos

文档:
GitHub:

Back to Blog

相关文章

阅读更多 »