@samcoding

EIP-6963 vs Solana Wallet Standard: RPC 스트림과 피처 탐지 객체의 아키텍처 비교
웹3 프론트엔드에서 여러 확장 프로그램 지갑이 동일한 전역 변수를 차지하려고 경쟁하며 발생하는 충돌은 오랫동안 개발자들을 괴롭힌 버그의 주범이었습니다. 이 문제를 해결하기 위해 이더리움 진영은 EIP-6963을, 솔라나 생태계는 솔라나 월렛 스탠다드를 도입했습니다. 두 표준은 다중 지갑 충돌을 해결한다는 목적은 같지만, 프론트엔드 개발자에게 제공하는 데이터 모델과 통신 인터페이스 아키텍처에서 근본적인 차이를 보입니다.
EIP-6963: DOM 이벤트 기반의 EIP-1193 공급자 탐색
EVM 생태계의 오랜 골칫거리였던 단일 전역 변수 window.ethereum 충돌 문제는 EIP-6963이 도입되면서 브라우저 네이티브 기술로 깔끔하게 해결되었습니다. 기존에는 브라우저 확장 프로그램 지갑들이 이 전역 객체를 서로 차지하려고 경쟁하는 구조였지만, EIP-6963은 표준 DOM 커스텀 이벤트를 활용해 지갑들이 독립적으로 공존할 수 있는 통로를 열어주었습니다.
이 표준의 탐색 메커니즘은 매우 직관적입니다. 디앱이 브라우저 창에 eip6963:requestProvider 이벤트를 발생시키면, 브라우저에 설치된 각 지갑 확장 프로그램이 이를 수신합니다. 지갑들은 즉시 자신의 메타데이터와 개별 공급자 객체를 실어 eip6963:announceProvider 이벤트를 되돌려줍니다. 설령 지갑이 디앱보다 늦게 로드되더라도, 로드되는 순간 스스로 발표 이벤트를 발생시키므로 초기화 순서 문제에서도 자유롭습니다.
이때 지갑이 제공하는 페이로드 정보는 EIP6963ProviderDetail 구조를 따릅니다. 여기에는 지갑을 구분할 고유 식별자(UUID), 표시용 이름, 아이콘 이미지 주소, 그리고 중복을 방지하기 위한 역도메인 식별자(RDNS, 예: io.metamask)가 포함됩니다. 디앱은 이 메타데이터를 조합해 충돌 없는 지갑 선택 목록을 사용자에게 보여주고, 선택한 지갑의 EIP-1193 공급자 객체를 안전하게 획득해 통신합니다.
Solana Wallet Standard: 양방향 이벤트 핸드셰이크와 전역 큐 폴백
솔라나 월렛 스탠다드는 디앱과 지갑의 로딩 타이밍 문제를 해결하기 위해 양방향 이벤트 핸드셰이크 아키텍처를 채택했습니다. 브라우저 환경에서 디앱과 확장 프로그램 중 무엇이 먼저 실행되더라도 지갑 누락 없이 완벽한 동기화를 보장하기 위함입니다.
이 메커니즘은 두 가지 커스텀 윈도우 이벤트를 통해 동작합니다. 디앱은 로드 완료 시점에 wallet-standard:app-ready 이벤트를 발생시키고, 지갑은 wallet-standard:register-wallet 이벤트를 트리거해 이에 응답합니다. 디앱이 실행되기도 전에 지갑이 먼저 로드된 경우에도 이 양방향 흐름 덕분에 서로를 안정적으로 발견할 수 있습니다.
더 나아가 극단적인 타이밍 오류에 대비해 window.navigator.wallets라는 전역 배열 객체를 폴백 구조로 제공합니다. 이 객체는 커스텀 push 함수를 내장한 일종의 전역 대기열 역할을 합니다. 디앱이 준비되기 전에 로드된 지갑들이 자신의 등록 콜백 함수를 이 대기열에 밀어 넣어두면, 디앱은 초기화 시점에 대기열을 순회하며 누락 없이 지갑 정보를 수집합니다.
RPC 스트림 vs 피처 탐지 기반 객체 모델
EIP-6963과 솔라나 월렛 스탠다드는 지갑을 탐색한 이후 개발자가 다루게 되는 인터페이스 규격에서 근본적인 차이를 보입니다. EIP-6963은 지갑 발견 과정만 표준화할 뿐, 반환하는 공급자는 기존 이더리움 표준인 EIP-1193 인터페이스를 따르는 원시 JSON-RPC 스트림 형태입니다. 개발자는 여전히 문자열 기반의 메소드 경로에 의존해 비동기 요청을 보내야 하므로 오탈자나 미지원 메소드 호출로 인한 런타임 오류에 취약합니다.
// EIP-1193: 문자열 기반 JSON-RPC 요청
await provider.request({
method: 'eth_sendTransaction',
params: [transactionPayload]
});반면 솔라나 월렛 스탠다드는 구조화된 자바스크립트 객체를 등록하며, 지갑이 지원하는 기능들을 피처 맵을 통해 안전하게 노출합니다. 타입스크립트 컴파일 타임에 지갑의 특정 기능 지원 여부와 인터페이스 타입을 직접 검증할 수 있어 개발자 경험이 크게 향상됩니다.
// Solana Wallet Standard: 타입화된 피처 탐지 및 호출
const feature = wallet.features['solana:signAndSendTransaction'];
if (feature) {
await feature.signAndSendTransaction(transaction);
}이러한 객체 모델 덕분에 솔라나 생태계에서는 지갑에 새로운 맞춤형 기능을 도입하더라도 피처 맵에 타입을 선언하는 것만으로 깨지지 않는 안전한 확장이 가능합니다.
멀티체인 프론트엔드를 설계하는 개발자의 선택
EIP-6963의 DOM 이벤트 방식과 솔라나 월렛 스탠다드의 양방향 핸드셰이크는 멀티체인 프론트엔드를 구축할 때 디버깅의 성패를 가르는 핵심 아키텍처입니다. Wagmi나 솔라나 월렛 어댑터 같은 고수준 라이브러리를 사용하더라도, 지갑 감지 실패나 비동기 로딩 타이밍 이슈를 해결하려면 이 하부 통신 규격을 명확히 알고 있어야 합니다. 런타임에 유연하게 RPC 스트림을 확장하는 이더리움 방식과 정적 타입 피처 탐지로 안전성을 확보하는 솔라나 방식의 아키텍처 차이를 이해하는 것이 더 강력하고 안정적인 멀티체인 디앱을 만드는 비결입니다.
참고 링크
- NPM @solana-mobile/wallet-adapter-mobile — React Native Integration Patterns: Customizing @solana-mobile/wallet-adapter-mobile
- wallet-standard Github Repository & Core Implementation — Solana Wallet Standard: Two-Way Event Handshake and Features Registry
- EIP-6963 Improvement Proposal Specification — EIP-6963: DOM Event-Driven Injected Provider Discovery for EVM