PoCs

한 번 연결한다는 것은 세션을 인가한다는 뜻이다

WalletConnect 연결은 단순한 주소 교환이 아닙니다. namespace, 체인, 메서드, 계정, 만료, 갱신 이벤트가 애플리케이션이 추적해야 할 상시 권한을 기술합니다.

어떻게 보나

WalletConnect Sign client(또는 Reown AppKit)로 최소 권한 제안과 넓은 권한 제안을 하나씩 만들고, 계정 변경, 체인 변경, 세션 갱신, 만료, 릴레이 단절, 재연결, 명시적 해지를 차례로 실행합니다 — 각 이벤트가 애플리케이션 상태를 올바르게 좁히거나 무효화하는지 확인합니다.

기술 노트

각 항목이 실제로 무엇을 보여주고 어떻게 동작하는지 — 위 카드보다 자세한 기술 설명입니다.

한 번 연결한다는 것은 세션을 인가한다는 뜻이다완료

목적: UI 는 보통 세션 상태를 "connected" 하나로 뭉갭니다. 그러면 어떤 메서드가 아직 인가되어 있는지가 가려지고, 지갑이 애플리케이션 바깥에서 상태를 바꿀 때 낡은 계정 버그가 생깁니다. WalletConnect 세션에는 계정, 체인, 메서드, 이벤트, 만료가 들어 있습니다. 이것을 `isConnected` 불리언 하나로 다루면, 애플리케이션이 무엇을 요청할 수 있는지와 캐시된 계정이 아직 최신인지 알려 주는 정보가 사라집니다.

동작 방식: 가장 작은 메서드 집합으로 연결하고 넓은 기본 제안과 비교한 뒤, 계정 변경, 체인 변경, 세션 갱신, 만료, 릴레이 단절, 명시적 해지를 차례로 실행합니다. ### PoC WalletConnect Sign client 또는 Reown AppKit 으로 최소 권한 제안과 넓은 권한 제안을 각각 만듭니다. 계정·체인 변경, 세션 갱신, 만료, 릴레이 단절, 재연결, 명시적 연결 해제를 실행합니다. 각 이벤트가 애플리케이션 상태를 올바르게 무효화하거나 좁히는지 확인합니다. ### 무엇을 증명하나 연결 UX 는 권한 관리입니다. 안전한 기본값은 최소한의 namespace 와 메서드 집합, 관찰 가능한 세션 상태 머신, 눈에 보이는 해지 경로입니다 — 낡은 상태에서도 살아남는 초록색 점이 아닙니다. 참고: [Reown WalletConnect 세션 사용법](https://docs.reown.com/advanced/api/sign/dapp-usage).

검토 후 보완: ### 같은 병, 다른 장기 — 생애주기에서 인가로 제목이 곧 재정의입니다 — **한 번 연결 = 세션을 인가하는 것이지 주소를 교환하는 게 아니다.** 세션은 *상시 권한* — 범위 + 수명 + 변경 이벤트 — 이고, 불리언 `isConnected` 는 그걸 거의 다 버리는 손실 있는 투영입니다. `a-boolean-hides-a-state-machine` 이 이름 붙인 패턴의 인가 쪽 멤버입니다. ### 초록 점은 세 개의 독립 계층을 뭉갠다 `private-rpc-visibility`·`bundler-paymaster-dependencies` 의 바로 그 구조적 오류가 지갑에 나타난 것입니다: | 계층 | 진짜 질문 | 초록 점의 위장 | | --- | --- | --- | | **릴레이/전송** | 지금 지갑과 *대화*할 수 있나? | "연결됨" | | **세션/인가** | 그 권한이 아직 *유효*한가(만료·취소 아님)? | "연결됨" | | **계정/상태** | 캐시된 계정·체인이 아직 *최신*인가? | "연결됨" | 릴레이 끊김은 세션을 무효화하지 **않고**, 재연결이 재인가하지 **않습니다.** 전송 가용성은 인가가 아닙니다 — `bundler-paymaster-dependencies` 가 "accepted ≠ settled" 로 그은 그 선. ### 보안의 핵심은 최소권한 세션은 `namespaces`·`chains`·`methods`·`accounts`(EIP-155 / CAIP-2 / CAIP-10)를 지정합니다. 광범위한 기본 — 모든 체인, 모든 메서드, `eth_sign` 포함 — 을 요청하는 것은 OAuth 의 "이 앱이 전부에 접근하려 함" 안티패턴의 web3 판입니다. **메서드 집합이 곧 공격 표면**입니다 — `eth_sign`(블라인드 서명)을 인가한 세션은 `personal_sign` 으로 좁힌 세션보다 범주적으로 큰 부채입니다. 그래서 안전한 기본값은 *가장 작은* 네임스페이스·메서드 집합이고, 최소 대 광범위 제안 비교가 그 차이를 가정이 아니라 *측정 가능*하게 만듭니다. `embedded-wallet-policy`·`agentic-intent-veto` 와 같은 "실제로 무엇을 인가했나" 질문, 전송 표준 한 층 아래. ### 스테일 계정이 구체적이고 위험한 버그 지갑은 **앱 밖에서** 상태를 바꿀 수 있습니다 — 사용자가 계정 전환, 체인 전환, 세션 만료, 취소. UI 가 초록 점 뒤에 캐시된 계정을 쥐고 있으면 *틀린* 계정·체인의 잔고를 보여주거나 서명을 요청합니다. `accountsChanged`/`chainChanged`/`session_update`/`session_delete`/`session_expire` 이벤트는 바로 앱 상태를 좁히거나 무효화하려 존재하고, 이를 무시하는 것이 **곧** 스테일 상태를 살아남는 초록 점입니다. 한 당사자의 캐시 뷰가 그라운드 트루스가 아니라는 `rpc-view-not-consensus` 의 교훈을, 당신 자신의 세션 캐시에 적용한 것. ### 불변식: 모든 이벤트는 좁히거나 무효화하지, 조용히 넓히지 않는다 "각 이벤트가 앱 상태를 올바르게 좁히거나 무효화하는지 단언"이 실제로 인코딩하는 게 이것입니다. 권한은 오직 *줄어들거나* 새 승인을 요구해야지, 조용히 *늘어나면* 안 됩니다. 명시적 재제안 없이 메서드나 계정을 얻은 듯 보이는 세션은 버그 — 또는 공격입니다. 세션을 명시적 상태기계(제안됨 → 성립됨 → 갱신됨 → 만료/끊김/취소됨 → 재제안)로 모델링하는 것이 그 불변식을 검사 가능하게 합니다. ### 만료와 취소는 1급 개념이지 예외가 아니다 `expiry` 지난 세션은 권한이 아닙니다 — 연결됨으로 취급하는 것은 `receipt-is-not-settlement` 의 인가판 쌍둥이(*완료처럼 보이지만* 유효하지 않음)입니다. 그리고 취소는 **보이고 양방향**이어야 합니다 — 사용자는 지갑에서 `session_delete` 할 수 있고, 앱도 자체 취소 경로를 드러내야 합니다. 깨끗이 관찰·취소할 수 없는 "연결됨"은 남아 있는 권한 — 잊힌 OAuth 승인 실패 유형이며, 인가 도메인의 `who-holds-the-mint` / "누가 멈추나" 주제입니다.