시스템 구조¶
Umul은 지갑 주소를 신원으로 쓰는 모바일형 웹 메신저입니다. 메시징은 XMTP dev 네트워크, 인증 상태 조회와 대화 증빙은 GIWA Sepolia를 사용합니다.

앱은 기기별 XMTP installation 키와 로컬 MLS DB로 메시지를 암복호화하고, 서버는 로그인 세션과 증빙 상태(Auth / Evidence)만 다룹니다. 편집 가능한 원본은 architecture.drawio다.
구성 요소¶
| 구성 요소 | 책임 | 메시지 원문 접근 |
|---|---|---|
frontend |
지갑 연결, XMTP E2EE 메시징, Dojang 조회, 증빙 manifest 생성과 서명 | 있음 |
backend |
로그인 nonce와 세션, 증빙 요청 상태와 서명 수집 | 없음 |
contracts |
EIP-712 다중 서명 검증, Dojang 재확인, 증빙 해시 기록 | 없음 |
메시지 원문을 다루는 유일한 구성 요소는 프론트엔드입니다. 백엔드와 컨트랙트에는 해시와 서명만 전달합니다.
계층 경계¶
프론트엔드와 백엔드 모두 같은 네 계층을 씁니다.
domain: 주소 정규화, 수신함 분류, 증빙 manifest 규칙, 증빙 상태 전이application: 유스케이스와 포트 인터페이스infrastructure: XMTP, 지갑, RPC, PostgreSQL, HTTP 어댑터presentation/interfaces: 화면과 HTTP 라우트
presentation은 SDK를 직접 호출하지 않고 application의 포트만 사용합니다.
구현체는 앱 시작 시 src/app/runtime/UmulRuntime.ts에서 주입합니다.
런타임 조립¶
readConfig() -> createShell() --지갑 로그인--> createSession()
│ │
├─ WagmiWalletAdapter ├─ XmtpMessagingAdapter
├─ HttpSessionAdapter ├─ ViemEvidenceContractAdapter
├─ ViemDojangAdapter └─ 메시징·증빙 유스케이스
└─ HttpEvidenceAdapter
createShell은 로그인 전에 만들 수 있는 의존성만 담습니다. XMTP 클라이언트와
증빙 컨트랙트 어댑터는 지갑 주소가 확정된 뒤 createSession에서 만듭니다.
VITE_EVIDENCE_CONTRACT_ADDRESS가 없으면 증빙 기능만 비활성이고 메시징은
그대로 동작합니다.
신뢰와 분류¶
DojangScroll.isVerified(address, attesterId) 결과를 주소별로 한 시간 캐시합니다.
RPC 오류는 unverified가 아니라 unknown으로 구분해, 확인 불가 상태에서도
메시징은 허용하고 증빙만 차단합니다.
수신함 분류는 domain/inbox/classifyConversation.ts 한 곳에서 결정합니다.
| 조건 | 분류 |
|---|---|
사용자가 스팸으로 지정 (XMTP consent denied) |
스팸함 |
자신을 제외한 참여자 전원 verified |
메시지함 |
그 외 (unverified 또는 unknown 포함) |
요청함 |
증빙 흐름¶
[제안자] 메시지 선택 -> manifest 생성 -> Dojang 재조회(캐시 우회)
-> 전원 verified 일 때만 POST /v1/evidence-requests
-> 원문을 암호화해 POST .../archive (콘텐츠 키는 서버에 없다)
-> XMTP 제어 메시지 gasok:evidence:v1:<base64url-json> 전송 (키 포함)
[참여자] 제어 메시지 수신 -> 로컬 메시지로 content hash 재계산
-> 일치할 때만 EIP-712 서명 -> POST .../signatures
-> 지갑 서명 파생 키로 래핑한 복원 키 POST .../archive/keys
[전원 서명] 상태 READY -> recordEvidence 트랜잭션 -> POST .../submission
[복원] 서명한 지갑이 GET .../archive -> 지갑 서명으로 복호화
-> content hash 재검증 후 표시 ([대화 기록](message-history.md) 참조)
컨트랙트는 제출 시점에 Dojang을 다시 조회합니다. 서명 이후 인증이 철회되면 프론트엔드 사전 검사를 통과했더라도 트랜잭션이 거부됩니다.