수동 Borsh에서 LUMOS로 마이그레이션: 단계별 가이드

발행: (2025년 12월 18일 오전 08:15 GMT+9)
4 min read
원문: Dev.to

Source: Dev.to

수동 Borsh에서 LUMOS로 마이그레이션: 단계별 가이드 표지 이미지

왜 마이그레이션을 해야 할까요?

  • Zero runtime overhead – 생성된 코드는 수동 Borsh와 동일합니다
  • Type synchronization – TypeScript와 Rust가 항상 일치합니다
  • Reduced maintenance – 단일 진실 소스
  • Fewer bugs – 직렬화 불일치를 없앱니다

Migration time: 구조체/열거형당 5‑30분

1단계: 기존 코드 감사하기

모든 Borsh 타입 찾기

Rust

# Borsh 파생 구조체 찾기
rg '#\[derive.*Borsh' --type rust

# Account 매크로 찾기
rg '#\[account\]' --type rust

TypeScript

# Borsh 스키마 찾기
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 스키마)

Create schema/player.lumos:

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

Generate code:

lumos generate schema/player.lumos

Rust와 TypeScript 모두 자동으로 생성됩니다.

Step 3: Import 업데이트

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!");
}

타입 매핑 참고

Manual RustManual TypeScriptLUMOS
PubkeyPublicKeyPublicKey
u16numberu16
u64numberu64
VecT[][T]
OptionT | undefinedOption
StringstringString
boolbooleanbool

마이그레이션 체크리스트

  • LUMOS CLI 설치: cargo install lumos-cli
  • .lumos 스키마 파일 생성
  • Rust 및 TypeScript 코드 생성
  • 기존 코드의 import 업데이트
  • 바이너리 호환성 테스트 실행
  • 이전 수동 타입 정의 제거
  • 스키마 변경 시 재생성을 위해 CI/CD 업데이트

점진적 마이그레이션 전략

한 번에 모든 것을 마이그레이션할 필요는 없습니다:

  • Phase 1: 새로운 타입 → 처음부터 LUMOS 사용
  • Phase 2: 고빈도 변경 타입 → 자주 변경하는 타입 마이그레이션
  • Phase 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

문서:
깃허브:

Back to Blog

관련 글

더 보기 »