Umul의 XMTP 사용¶
앞의 세 문서가 프로토콜을 설명했다면, 이 문서는 Umul이 그중 무엇을 실제로 쓰는지 적습니다.
| 항목 | 값 |
|---|---|
| SDK | @xmtp/browser-sdk 7 |
| 네트워크 환경 | dev (SDK 7 기본값) |
| 로컬 DB | 영속 브라우저 저장소(OPFS). 지갑 서명에서 유도한 키로 암호화 |
| 어댑터 | XmtpMessagingAdapter, XmtpSignerAdapter |
dev 환경이므로 production 환경의 XMTP 앱과는 통하지 않습니다. 환경 분리는
개요의 조건표에 있는 그대로입니다.
로컬 MLS DB의 암호화 키는 지갑 서명에서 유도하고 세션마다 다시 유도하므로 어디에도 저장하지 않습니다.
로그인은 지갑 서명 하나로 두 가지를 만듭니다¶
지갑 서명이 백엔드 세션과 XMTP 신원 양쪽의 뿌리입니다.
지갑 연결
→ SIWE 방식 서명 → 백엔드 세션 (umul_session 쿠키)
→ XmtpSignerAdapter 서명 → XMTP Inbox / installation
XmtpSignerAdapter가 신원 문서의 identity 등록을 담당합니다.
브라우저 저장소가 빈 상태로 로그인하면 그때마다 새 installation이 생기므로
10개 한도를 소모합니다.
증빙 제어 메시지: 별도 codec 대신 prefix¶
Umul은 커스텀 content type(codec)을 만들지 않고 버전이 붙은 텍스트 봉투를 씁니다.
gasok:evidence:v1:<base64url-json>
일반 채팅 UI는 이 prefix가 붙은 메시지를 숨기고 증빙 카드로 바꿔 보여줍니다.
EVIDENCE_CONTROL_PREFIX 상수 하나가 그 판별 기준입니다.
이 선택의 대가는 개요의 네 번째
조건입니다. 다른 XMTP 앱에서 이 대화를 열면 증빙 카드가 아니라 gasok:evidence:v1:...
원문이 그대로 보입니다. P0에서는 감수한 한계입니다.
payload에 원문은 들어가지 않습니다. XMTP 메시지 ID 목록(messageRefs)만
담고, 수신자는 그 ID로 자신의 로컬 메시지를 찾아 content hash를 다시
계산합니다. 서버가 준 값을 믿지 않고 각자 재계산하는 것이 증빙의 핵심입니다.
제어 메시지가 MLS로 종단간 암호화된다는 점도 그대로 활용합니다. 증빙 아카이브의
콘텐츠 키(archiveKey)를 이 경로로 실어 보내면 서버를 거치지 않고
참여자에게만 전달됩니다.
consent를 수신함 분류에 씁니다¶
XMTP의 수신 동의 상태 3가지를 그대로 받아 씁니다.
XMTP ConsentState |
Umul |
|---|---|
Allowed |
allowed |
Denied |
denied → 스팸함 |
Unknown |
unknown |
다만 Umul의 수신함 분류는 consent만으로 결정되지 않습니다. 수동 스팸 지정이
Dojang 인증 상태보다 우선하고, 그 외에는 자신을 제외한 참여자 전원이
verified일 때만 메시지함에 둡니다.
| 조건 | 분류 |
|---|---|
사용자가 스팸으로 지정 (consent denied) |
스팸함 |
자신을 제외한 참여자 전원 verified |
메시지함 |
그 외 (unverified 또는 unknown 포함) |
요청함 |
RPC 오류로 확인하지 못한 unknown은 unverified와 같이 요청함으로 보냅니다.
확인하지 못한 상대를 인증된 것처럼 메시지함에 올리지 않는 쪽이 안전합니다.
consent는 암호화되어 네트워크에 저장되므로 사용자가 쓰는 모든 XMTP 앱에서 같은 분류가 유지됩니다. Dojang 기반 분류는 Umul에만 있습니다.
과거 메시지를 읽는 경로¶
XmtpMessagingAdapter.listMessages
conversation.sync() 네트워크에 쌓인 메시지를 받아 복호화해 로컬에 저장
conversation.messages() 로컬 MLS DB에서 읽는다
sync()가 먼저 필요합니다. 스트림(streamAllMessages)은 구독 이후의 메시지만
주기 때문에, 과거 메시지를 화면에 띄우려면 이 경로가 반드시 있어야 합니다.
자세한 내용과 새 installation의 복구 한계는 대화 기록에 있습니다.
한계¶
dev네트워크입니다. production 앱과 통하지 않고, dev 네트워크의 데이터 보존을 XMTP가 보장하지 않습니다.- installation 10개 한도. 브라우저 저장소를 비우고 재로그인할 때마다 슬롯을 소모합니다. 한도에 닿으면 로그인이 멈춥니다.
- 새 installation은 과거를 못 읽습니다. 종단간 암호화의 결과이지 버그가 아닙니다. 증빙에 쓴 대화만 암호문 아카이브로 우회합니다.
- 증빙 제어 메시지가 다른 앱에서는 원문으로 보입니다. 커스텀 codec 대신 prefix를 택한 대가입니다.
- 세대 교체 비용. v2가 4년 만에 읽기 전용이 됐고 v2 대화는 이식되지 않았습니다. XMTP 위에 앱을 짓는 것은 이런 교체를 따라갈 운영 비용을 감수한다는 뜻입니다.