Solana Wallet Standard vs EIP-6963: RPC 스트림과 피처 탐색 객체가 갈라놓은

삼코딩

@samcoding

Solana Wallet Standard vs EIP-6963: RPC 스트림과 피처 탐색 객체가 갈라놓은 Web3 개발자 경험

Solana Wallet Standard vs EIP-6963: RPC 스트림과 피처 탐색 객체가 갈라놓은 Web3 개발자 경험

Web3 프론트엔드 개발에서 브라우저 확장 지갑들이 전역 네임스페이스를 선점하려고 경쟁하는 충돌 문제는 오랫동안 빌더들을 괴롭혀 왔습니다. 이를 해결하기 위해 이더리움은 EIP-6963을, 솔라나는 솔라나 지갑 표준을 도입해 여러 지갑이 안전하게 공존할 수 있는 길을 열었습니다. 두 표준 모두 멀티 지갑 검색이라는 목적은 같지만, 한쪽은 기존 JSON-RPC 스트림을 유지하고 다른 한쪽은 타입 안정성을 갖춘 자바스크립트 객체를 직접 전달하는 상반된 아키텍처를 선택했습니다.

EVM EIP-6963: DOM 이벤트와 EIP-1193 스트림의 공존

EIP-6963은 브라우저 확장 지갑의 무분별한 전역 변수 침범 문제를 해결하기 위해 도입된 표준입니다. 핵심은 전역 객체인 window.ethereum을 선점하려는 경쟁을 멈추고, 브라우저의 표준 DOM 이벤트를 활용해 지갑을 동적으로 찾아내는 독립적인 탐색 방식을 제공하는 데 있습니다.

탐색 과정은 지갑과 디앱의 직관적인 이벤트 통신으로 이루어집니다. 디앱이 로드되면서 eip6963:requestProvider 이벤트를 발생시키면, 브라우저에 실행 중인 모든 지갑 확장 프로그램들이 이를 감지합니다. 이어서 각 지갑은 자신의 고유 식별자, 이름, 아이콘 같은 메타데이터를 담아 eip6963:announceProvider 이벤트로 응답합니다.

하지만 EIP-6963은 오직 이 탐색 과정만 개선했을 뿐, 지갑과의 실제 데이터 통신 방식을 근본적으로 바꾸지는 못했습니다. 디앱이 발표 이벤트를 통해 최종적으로 전달받는 객체는 여전히 레거시 EIP-1193 호환 프로바이더입니다. 따라서 개발자는 지갑을 식별한 뒤에도 트랜잭션 전송이나 서명을 처리하기 위해 기존과 마찬가지로 문자열 기반의 느슨한 JSON-RPC 메시지 전송 인터페이스를 그대로 활용해야 합니다.

Solana Wallet Standard: 양방향 핸드셰이크와 피처 레지스트리

솔라나의 지갑 표준은 로딩 순서에 따른 레이스 컨디션을 해결하기 위해 이벤트 기반의 양방향 핸드셰이크와 전역 폴백 메커니즘을 결합했습니다.

핵심은 wallet-standard:app-readywallet-standard:register-wallet이라는 두 가지 커스텀 이벤트입니다. 디앱이 실행되면서 wallet-standard:app-ready 이벤트를 디스패치하면 지갑이 이를 수신하고, 반대로 지갑이 로드될 때는 wallet-standard:register-wallet 이벤트를 디스패치합니다. 이 양방향 구조 덕분에 어떤 브라우저 확장 프로그램이나 디앱이 먼저 실행되더라도 누락 없이 안전하게 서로를 감지하고 동기화할 수 있습니다.

만약 이벤트를 놓치거나 지원하지 않는 구형 환경을 대비해 window.navigator.wallets 배열을 폴백으로 제공합니다. 이 배열은 단순한 자바스크립트 배열이 아니라 커스텀 push 함수를 내장한 특수 객체입니다. 지갑이 디앱보다 먼저 실행된 경우, 등록 콜백을 이 배열의 push 메서드로 밀어 넣어 대기열에 안전하게 쌓아둡니다. 이후 디앱이 준비되었을 때 대기열의 콜백이 실행되므로 초기화 순서로 인한 레이스 컨디션이 완벽하게 방지됩니다.

이 핸드셰이크가 완료되면 디앱은 단순히 원시 JSON-RPC 스트림을 다루는 프로바이더가 아닌, 타입스크립트로 엄격하게 정의된 고유 기능 객체를 획득하게 됩니다.

결정적인 DX 차이: 피처 감지 vs 문자열 쿼리

두 표준이 개발자에게 노출하는 객체의 형태는 개발자 경험의 근본적인 차이를 만듭니다. EIP-6963은 무거운 전역 변수 충돌만 우회할 뿐, 최종적으로 전달하는 것은 여전히 기존의 JSON-RPC 통신 스트림입니다. 반면 솔라나 지갑 표준은 정적 타입이 적용된 자바스크립트 객체를 직접 디앱에 전달합니다.

이 차이는 기능 검증 단계에서 명확하게 드러납니다. EVM 디앱에서 특정 지갑이 트랜잭션 전송이나 특정 서명 기능을 지원하는지 확인하려면, 메서드 이름을 문자열 페이로드에 담아 런타임에 직접 요청을 호출해 봐야 합니다. 지갑이 해당 메서드를 지원하지 않는다면 런타임 에러가 발생한 뒤에야 호환성 여부를 인지할 수 있습니다.

반면 솔라나 지갑 표준은 타입스크립트 기반의 피처 맵을 제공하므로, 개발자는 객체의 속성이 존재하는지 검사하는 것만으로 해당 기능을 컴파일 단계에서 안전하게 검증할 수 있습니다.

typescript
// Solana Wallet Standard의 타입 안전한 피처 감지 예시
if ('solana:signAndSendTransaction' in wallet.features) {
    const feature = wallet.features['solana:signAndSendTransaction'];
    await feature.signAndSendTransaction(...);
} else {
    console.warn('이 지갑은 트랜잭션 서명 및 전송 피처를 지원하지 않습니다.');
}

이러한 구조 덕분에 솔라나 빌더들은 불안정한 예외 처리에 의존하지 않고도 견고한 프런트엔드 코드를 작성할 수 있습니다. 또한 'Sign In With Solana' 같은 신규 기능이 추가되더라도, 지갑 인터페이스 자체를 훼손하지 않고 피처 레지스트리에 새로운 규격을 정의하는 것만으로 안전하게 하위 호환성을 유지할 수 있습니다.

멀티체인 프론트엔드 빌더를 위한 요약

이더리움의 EIP-6963과 솔라나 지갑 표준은 전역 네임스페이스 충돌을 해결한다는 목적은 같지만, 이를 구현하는 아키텍처 관점에서는 완전히 다릅니다. 이더리움이 기존의 견고한 JSON-RPC 규격을 그대로 유지하면서 탐색 계층만 개선했다면, 솔라나는 처음부터 타입스크립트 환경에 맞춰 설계된 피처 감지 기반의 객체 모델을 선택했습니다.

멀티체인 디앱을 구축하는 빌더라면 서드파티 라이브러리가 추상화해 둔 로직 뒤편의 이러한 통신 설계 차이를 명확히 인지해야 합니다. 각 체인의 지갑 표준이 보장하는 인터페이스를 직접 제어할 수 있을 때, 장기적으로 훨씬 가볍고 예측 가능하며 안전한 사용자 경험을 구현할 수 있습니다.


참고 링크

No comments yet.