이슈 #443
진행중Phase 0.7 Wallet-as-Identity MVP — WalletChallenge/Verify + Reference Clients (sdktest wallet-login + Web Console 4섹션)
0%
설명
배경¶
로드맵(#440) 의 Phase 0.7 Wallet-as-Identity 를 MVP 형태로 구현한다. AI Agent / 자동화 / CI / headless entity 가 GoTrue 없이 secp256k1 지갑만으로 서버와 상호작용 가능하게 하고, 사람 흐름 (GoTrue) ↔ headless 흐름 (wallet) 을 같은 reference client 에서 비교 검증 할 수 있게 한다.
작업 순서 (완결 시점 순서)¶
-
Web Console Test Client — Section A (User/GoTrue) 먼저 교체
-
webconsole_test_client.go의 JS UI 에서 기존 MetaMask +AuthService.Challenge/Verify흐름 제거 - GoTrue URL / email / password 입력 + signup / login / refresh 버튼
- 현재 서버 RPC 만으로 구현 가능 (서버 수정 없음)
-
-
서버 RPC 구현 — Phase 0.7 의 핵심
-
AuthService.WalletChallenge/WalletVerify추가 (proto, handler, store/redis nonce) - Challenge payload 해석 명세 구현: JSON
{domain, purpose, wallet, nonce, issued_at, expires_at} - wallet JWT 발급 —
typ:"wallet",sub:<wallet_address>, 1h TTL,golang-jwt/jwt/v4 -
internal/server/interceptors.go::AuthInterceptor가wallettyp 수용 +AuthContext.PrincipalType/PrincipalID채움 (Phase 0.5 의 Principal 모델 적용) -
RegisterNode확장 — user token 이면owner_user_id = sub, wallet token 이면owner_wallet_address = sub(owner_user_id = NULL). 자율 노드 생성 -
VerifySignature보안 강화 (선행 필수): nonce 저장 (DB 또는 redis) + TTL (5분) + one-time use + domain/purpose 검증 + 서명에서 public key recover 후 address 비교
-
-
Web Console Test Client — Section B (Wallet Identity, MVP)
- local private key sign 먼저 (MetaMask 후속). 브라우저/extension 상태 무관, 프로토콜 안정화 우선
- private key 입력 / wallet address 표시 / WalletChallenge → sign → WalletVerify → wallet token 표시
-
sdktest 신규 명령 —
cmd/sdktest-
wallet-login --key <hex>(or--state에 저장된 keypair 사용) - 같은 서버 RPC 사용. State 에
wallet_token저장
-
-
Web Console Test Client — Section C (Node Register)
- auth mode toggle: user token | wallet token
- 별도 node keypair 입력 / node_id
- NodeChallenge → sign → RegisterNode — 선택한 auth mode 로 bearer 전송
-
RegisterNode 확장 검증 — user JWT 일 때
owner_user_id채움, wallet JWT 일 때owner_wallet_address채움 확인
-
(Optional) Section B 에 MetaMask
personal_sign을 signing method 옵션으로 추가
Section D (Smoke Calls) 신규 항목¶
- Health / SystemInfo
- GetNode / ListNodes
- ConnectNode bidi — 노드 토큰으로 stream open 테스트
- VFS smoke (Phase 1 후 dFS 로 교체)
DoD¶
-
AuthService.WalletChallenge+WalletVerify동작 (machine-readable payload + nonce/TTL/one-time/domain/recover) -
wallet token 을 수용하는
AuthInterceptor에서PrincipalType="wallet",PrincipalID=<address>채움 -
RegisterNode가 wallet token bearer 수용 (owner_user_id=NULL,owner_wallet_address=sub) -
cmd/sdktest wallet-login동작 검증 -
webconsole_test_client.goSection A/B/C/D 4개 섹션 모두 동작 — 한 화면에서 GoTrue 흐름·Wallet 흐름 비교 가능 -
wallet token 의 기본 scope 가
wallet://<자기주소>/로 제한됨 (다른 namespace 접근 거부) -
user_wallets테이블 시서마 (Phase 0.5 공통 모듈과 함께) 도입 -
VerifySignature보안 강화 완료 -
wallet_delegations테이블 자리만 잡힌 (실 구현은 후속 마일스톤)
관련 이슈¶
HP Henry Park이(가) 6달 전에 변경
작업 디자인/어장 정리 완료¶
commit:server|ea34feb
Phase 0.7 MVP 작업을 코드 단계로 넘기기 전의 디자인/문서 정지작업:
- 로드맵 Phase 0.7 에 Reference Client 섹션 신설 (sdktest CLI + Web Console Test Client 4섹션 구조)
- MVP signing = local private key sign 먼저, MetaMask 후속으로 명시
- 구현 순서 6단계 명시 (이 이슈 description 과 동일)
- DoD 에 Web Console 4섹션 동작 항목 추가
- docs/06-mobile-sdk.md, docs/01-auth.md 와 PROJECT_STATUS 부채 표 정렬
다음은 구현 착수 — 로드맵의 구현 순서 6단계 그대로 진행 예정 (① WC Section A → ② 서버 RPC → ③ WC Section B → ④ sdktest wallet-login → ⑤ Section C auth mode → (Opt) MetaMask).
HP Henry Park이(가) 6달 전에 변경
docs/06-mobile-sdk.md 잔여 stale 제거¶
commit:server|a1c7d49
Phase 0 의 SDK cleanup 이 이제 코드/문서 완전 일치:
- Android Implementation 의
Mobile.authenticate(...)예제 →Mobile.authenticateWithGoTrueToken(...)교체 - iOS Implementation 동일게
MobileAuthenticateWithGoTrueToken(...)교체 - WalletConnect Integration 섹션 (Android / iOS / React Native 예제 포함) 통째 제거 → "External Wallet — TBD (이 이슈 구현 후 재작성)" placeholder 로 대체
- 옷
AuthResult.balanceAgx필드 참조 도 제거 (새 AuthResult 에 없음)
Mobile SDK 예제 코드 전송이 새 AuthenticateWithGoTrueToken API 만 사용. 외부 wallet 인증 UX 는 이 이슈에서 WalletChallenge/Verify 구현 완료 후 다시 추가됨.
HP Henry Park이(가) 6달 전에 변경
- 상태을(를) 신규에서 진행(으)로 변경되었습니다.
구현 순서 1단계 완료 — Web Console Test Client Section A (User/GoTrue)¶
commit:server|e77e776
원격 서버 (alphea-rpc :3001)¶
-
internal/handler/webconsole_test_client_gotrue.go신규-
POST /monitor/api/auth/gotrue/signup→ GoTrue/signup프록시 -
POST /monitor/api/auth/gotrue/login→ GoTrue/token?grant_type=password -
POST /monitor/api/auth/gotrue/refresh→ GoTrue/token?grant_type=refresh_token - admin 의
internal/admin/gotrue.go와 유사한 패턴, main server 위에서 같은 origin 으로 접근 가능한 프록시 (CORS 회피 + GoTrue 외부 노출 불필요)
-
-
internal/handler/webconsole_pages.go에 3개 라우트 등록
Test Client 페이지 (internal/handler/webconsole_test_client.go)¶
-
Section A · User (GoTrue) 카드 신설 (Connection 카드 위)
- Email / Password 입력 + Sign Up / Log In / Refresh Token / Sign Out 버튼
- User ID / Email / Access Token / Expires At / Refresh Token 세션 표시
- 마지막 GoTrue 응답 JSON 디버그 박스
-
옷 wallet challenge-signature 흐름 제거
-
Login With MetaMask버튼 -
connectWithMetaMask()JS 함수 (옷AuthService.Challenge/AuthService.Verify호출 포함) -
loginBtn핸들러
-
- session 모델 확장:
gotrueAccessToken,gotrueRefreshToken,gotrueUserId,gotrueEmail,gotrueExpiresAt
구현 순서 진행 상황¶
- 1. Web Console Test Client Section A (User/GoTrue) — 본 커밋
-
2. 서버 RPC:
AuthService.WalletChallenge/WalletVerify+ wallet JWT +RegisterNode확장 +VerifySignature보안 강화 - 3. Web Console Test Client Section B (Wallet Identity, local key sign)
-
4. sdktest
wallet-login명령 - 5. Section C (Node Register) auth mode toggle
- (Optional) MetaMask signing method
테스트 방법 (로드맵/테스트 서버)¶
docker compose up -d # gotrue (:9011) 포함
open http://localhost:3001/monitor/test-client
# Section A 에서 email/password 입력 → Sign Up
# 응답에 access_token, refresh_token, user{id,email} 이 온다
# Refresh Token 버튼으로 grant_type=refresh_token 검증 가능
이슈 상태 → 진행 중 (구현 순서 1/6 완료).
HP Henry Park이(가) 6달 전에 변경
구현 인프라 — dev loop targets¶
commit:server|a2aaa74 에서 Makefile 에 dev-up / dev-deps / dev-server / dev-down / dev-logs 을 추가. Phase 0.7 RPC 구현 시 다음 루프로 빠르게 검증 가능:
make dev-deps # postgres + gotrue + redis
make dev-server # 호스트에서 go run (rebuild 없이 코드 수정 반영)
# sdktest 로 검증 (다음 step 의 wallet-login 명령 추가 전)
make sdktest ARGS="signup --email dev@example.com --password ..."
make sdktest ARGS="node-register --node-id mac-test-1"
make sdktest ARGS="connect --seconds 30"
#441 에서 자세 설명.
구현 순서 이제 step 2 (AuthService.WalletChallenge / WalletVerify + wallet JWT + VerifySignature 강화) 진입 준비 완료.
HP Henry Park이(가) 6달 전에 변경
Step 1 잔여 정리 + #444 파생¶
commit:server|e1ab575
Step 1 구현에서 주가된 GoTrue proxy 가 public route 로 열려 있어 운영 도메인에서도 노출됨 이 확인됨. 별도 이슈로 뛰운 차단 작업: #444 GoTrue proxy guard.
이번 커밋에서 함께 정리:
-
webconsole_test_client_gotrue.go주석을TODO(#444)마커로 격상 -
claimVirtualNodePackage()의 옷 "Login with MetaMask first" 메시지 → 중립 "Wallet session required"
Step 1 (Section A) 는 이로 깨끗하게 닫힘. 다음은 step 2 — 서버 RPC (WalletChallenge/Verify + wallet JWT + RegisterNode 확장 + VerifySignature 강화).
HP Henry Park이(가) 6달 전에 변경
Step 2 진입 전 회귀 안전망 구축¶
commits:
- commit:server|6c63ffc — SDK smoke harness (#441)
- commit:server|3313555 — edge_node bootstrap 정합 (#438)
make smoke 한 줄로 signup → state → keygen → node-register → connect 전체 시퀀스가 검증됨. 이제 step 2 의 AuthService.WalletChallenge / WalletVerify 구현을 따라가면서 회귀 없는지 즉시 검증 가능. TEST_CLIENT_CHECKLIST.md 에 Phase 0.7 항목 (WalletChallenge / WalletVerify / wallet JWT typ=wallet / nonce TTL one-time / sdktest wallet-login / RegisterNode user|wallet 수용 / Web Console Section B|C) 이 이미 나열되어 있으므로 구현 완료 시점에 하나씩 [x] 로 전환하면 됨.
다음: step 2a — proto/alphea/v1/auth.proto 에 WalletChallenge + WalletVerify 메시지/RPC 추가 + buf generate.
HP Henry Park이(가) 6달 전에 변경
Step 2a 완료 — proto contract¶
commit:server|0270bea
wallet-as-identity 의 RPC contract 만 먼저 박음 (실 동작은 Unimplemented stub).
스키마 결정¶
-
WalletChallengeResponse가 사람-읽기용challenge(EIP-191) 와 machine-readablepayload(JSON: domain/purpose/wallet/nonce/issued_at/expires_at) 둘 다 발급 -
WalletVerifyRequest가 challenge + payload 둘 다 echo 로 받음 — 서버가 사람-읽기용 텍스트 파싱 없이 nonce/TTL/domain/purpose 검증 가능 + nonce store 와 cross-check -
purpose는 enum 이 아닌 string — 향후 새 흐름이 proto 변경 없이 추가 가능
파일¶
-
proto/alphea/v1/auth.proto— RPC + 메시지 -
gen/alphea/v1/*— buf generate 결과 -
internal/handler/auth.go— Unimplemented stub 두 개 -
internal/server/interceptors.go— publicRPCs 에 등록 (wallet 인증 출발점은 토큰 없이 호출) -
internal/handler/webconsole_rpc.go— test-client proxy public set
구현 순서 진행 상황¶
- 1. WC Test Client Section A (User/GoTrue)
- 2a. proto contract — 본 커밋
-
2b. nonce store +
VerifySignature보안 강화 (nonce TTL, one-time, domain/purpose, public-key recover) -
2c.
WalletChallenge/WalletVerify핸들러 + wallet JWT 발급 -
2d.
AuthInterceptor가typ:"wallet"수용 + Principal 모델 채움 -
2e.
RegisterNode확장 (wallet token bearer) - 3. WC Test Client Section B (Wallet Identity, local key sign)
-
4. sdktest
wallet-login - 5. Section C auth mode toggle
검증¶
-
make proto/make lint/go test ./...통과 -
make smoke는 stub 때문에 wallet 경로는 아직 검증 X — step 2c 완료 시 TEST_CLIENT_CHECKLIST.md 의 Phase 0.7 항목 [x] 로 전환
다음: step 2b — nonce store 구현 (in-memory 또는 Redis) + internal/domain/auth/crypto.go::VerifySignature 강화.
HP Henry Park이(가) 6달 전에 변경
Step 2b 완료 — production-grade VerifySignature + wallet challenge store¶
commits:
- commit:server|85105d1 — 서명 검증 강화 + wallet challenge store + SDK/sdktest 정합 + 테스트
- commit:server|d101275 — PROJECT_STATUS 부채 표 ✅ 정리
핵심¶
internal/domain/auth/crypto.go:
- VerifySignature stub → 실제 구현. EIP-191 + ecrecover
- Decred V||R||S / Ethereum R||S||V 둘 다 수용 — 휴리스틱이 아니라 가능한 후보 모두 recover 시도 후 wallet 일치 후보 인정 (R[0] ∈ [27,34] ambiguous 코너 케이스 안전)
-
EIP191MessageHash/AddressFromPublicKey/NormalizeWalletAddresshelper - legacy
demo-sig-*bypass 유지 (simulator/NodeChallenge 호환)
internal/domain/auth/challenge.go:
-
ChallengeStore확장 — 기존Issue/Verify유지 +IssueWallet/VerifyPayload추가 - wallet payload
{domain, purpose, wallet, nonce, issued_at, expires_at}JSON + EIP-191 사람 읽기용 메시지 동시 발급 -
VerifyPayload가 mismatch/만료/성공 어느 경우라도 항상 delete — 강한 one-time use -
NodeChallengeTTL/DefaultWalletChallengeTTL상수화
sdk/sign.go + cmd/sdktest/main.go:
- raw keccak + 64-byte R||S → EIP-191 + 65-byte V||R||S
- server 와 동일 wire format
테스트:
-
crypto_test.go: round-trip / Ethereum RSV / wrong wallet / non-recoverable / demo bypass / ambiguous R[0] ∈ [27,34] 동적 발견 후 회귀 -
challenge_test.go: wallet payload build/parse + one-time consume
TEST_CLIENT_CHECKLIST.md: payload byte-for-byte echo 룰 명시
구현 순서 진행 상황¶
- 1. WC Test Client Section A (User/GoTrue)
-
2a. proto contract (
0270bea) -
2b. nonce store +
VerifySignature강화 — 본 단계 -
2c.
WalletChallenge/WalletVerify핸들러 + wallet JWT 발급 (nonce store + payload helper + VerifySignature 연결) -
2d.
AuthInterceptor가typ:"wallet"수용 + Principal 모델 채움 -
2e.
RegisterNode확장 (wallet token bearer) - 3. WC Test Client Section B (Wallet Identity, local key sign)
-
4. sdktest
wallet-login - 5. Section C auth mode toggle
검증¶
-
go test ./...통과 -
make dev-up이미지 rebuild +make smoke-check통과 (signup → state → keygen → node-register → connect) - PROJECT_STATUS 부채 표의 "🔴 secp256k1 검증 강화" 이제 ✅ 해제
미세 후속 (선택)¶
- MetaMask / ethers 실제 통합 시점에 fixed known-vector 1개 추가 (동적 테스트는 이번에 충분)
HP Henry Park이(가) 6달 전에 변경
Step 2c 완료 — WalletChallenge / WalletVerify handlers + wallet JWT¶
commit:server|4474812
step 2b 의 store + payload helper + VerifySignature 를 실제 RPC 핸들러로 연결. 한 파이프라인으로 challenge → sign → verify → wallet JWT.
구현 특징¶
3겹 defense (WalletVerify):
- payload parse + wallet/domain/expiry cross-check
- ChallengeStore.VerifyPayload (one-time consume + byte-equal)
- VerifySignature (EIP-191 ecrecover)
토큰: typ="wallet", sub=<wallet_address>, default TTL 3600s. 독립한 GenerateWalletToken — NodeScope 없음 (wallet 은 namespace owner 자체 권한)
Wire-up:
-
WALLET_CHALLENGE_DOMAIN/WALLET_TOKEN_TTL_SECONDSconfig + env - functional options (
WithWalletChallengeDomain/WithWalletTokenTTLSeconds) -
VerifyToken: TokenType switch 확장 — wallet token 이면AuthContext.Wallet = sub,TokenType = "wallet"(step 2d 의 wallet token recognition 일부 흡수) - key prefix
"wallet:"로 NodeChallenge 와 store namespace 분리
테스트¶
auth_wallet_test.go (신규):
- challenge → sign → verify → wallet JWT 발급 round-trip
- wallet JWT 가
VerifyToken→AuthContext.Wallet/TokenType="wallet"채움 - nonce one-time consume
- payload 변형 시 reject
구현 순서 진행 상황¶
- 1. WC Test Client Section A (User/GoTrue)
- 2a. proto contract
- 2b. nonce store + VerifySignature 강화
- 2c. WalletChallenge / WalletVerify 핸들러 + wallet JWT — 본 이슈
- 2d. AuthInterceptor 가 PrincipalType/PrincipalID 채움 (부분 흡수: wallet token recognition 이미 동작)
- 2e. RegisterNode 확장 (wallet token bearer 수용 → owner_wallet_address 매핑)
- 3. WC Test Client Section B (Wallet Identity, local key sign)
- 4. sdktest wallet-login — 다음
- 5. Section C auth mode toggle
검증¶
-
go test ./...통과 -
make dev-up다시 rebuild +make smoke-check통과
다음¶
Step 4 — sdktest wallet-login 명령 추가. CLI 차원 reference. 흐름:
sdktest keygen # 이미 있음
sdktest wallet-login # 신규
→ WalletChallenge 호출
→ sign (EIP-191, SDK 을 공유 함수 또는 sdk/sign.go::signChallenge)
→ WalletVerify 호출
→ wallet JWT 를 state 에 저장
sdktest state # wallet token 표시
step 2e (RegisterNode wallet bearer) 는 sdktest wallet-login 이후 언제든 가능 — step 4 가 독립적으로 reference 역할 수행.
HP Henry Park이(가) 6달 전에 변경
Step 2d 완료 — AuthContext Principal 모델 정리¶
commit:server|df953a5
메모리 메타원칙 "모든 ownership/identity 필드는 Principal 모델로 표현" 을 AuthContext 에 반영. minimal change — 권한 판정 분기는 점진 마이그레이션.
변경¶
-
AuthContext에PrincipalType/PrincipalID주 필드 추가 - 기존
UserID/NodeID/Wallet/Email은 compatibility 편의 필드로 유지 (PrincipalID 와 매칭 type 일 때 같은 값 미러) -
TokenType도 compatibility alias 로 PrincipalType 과 동일 값 -
VerifyToken이 user / node / wallet 모두 주 필드 + 매칭 편의 필드 채움
구현 순서 진행 상황¶
- 1. Section A
- 2a. proto contract
- 2b. nonce store + VerifySignature
- 2c. WalletChallenge/Verify handlers + wallet JWT
- 2d. AuthContext Principal 모델 — 본 이슈
- 2e. RegisterNode wallet bearer + schema migration — 다음
- 3. Section B
- 4. sdktest wallet-login
- 5. Section C auth toggle
Step 2e schema 조정¶
v15 가 nodes.owner_wallet_address 를 retire 한 상태이므로 옵션 B: nodes.owner_principal_type (user | wallet) + nodes.owner_principal_id 추가. owner_user_id 는 기존 쿼리 호환용 유지, 새 판정은 principal 필드로.
이 schema 변경은 v16 migration 으로 진행. step 2e 는 이 migration + RegisterNode 의 wallet bearer 분기 + store 함수 수정 + smoke 검증 까지. step 4 (sdktest wallet-login) 는 step 2e 뒤에 붙여 wallet-login → node-register --auth wallet → connect 까지 하나의 켬래웅 에서 검증.
검증¶
-
go build ./...통과 -
go test ./internal/handler/... ./internal/domain/auth/...통과
HP Henry Park이(가) 6달 전에 변경
Step 2e 완료 — RegisterNode wallet principal + schema v16¶
commit:server|5428d60
wallet-as-identity 가 자율 노드를 등록할 수 있게 서버 전 계층을 principal 모델로 확장.
핵심¶
schema v16 (migrations.go::migrateV16NodeOwnerPrincipal):
-
nodes.owner_principal_type/owner_principal_id컴럼 추가 (idempotent) - 기존
owner_user_idrow 를("user", uuid)로 backfill - partial index (
owner_principal_type,owner_principal_id) WHERE both NOT NULL -
owner_user_id는 기존 쿼리 호환용 유지
store/nodes.go:
-
Nodestruct 에OwnerPrincipalType/OwnerPrincipalID포인터 필드 -
RegisterNodeForUser기존 시그니처 유지 +RegisterNodeForWallet신규 - 내부
registerNodeForPrincipal공통 helper 로 UPDATE/INSERT 통합
handler/node.go::RegisterNode:
-
authPrincipal(ac)몇 등록 흐름 분기 (user / wallet / default reject) - wallet bearer 일 때
msg.WalletAddressvs token principal sub 일치 검증 (case insensitive) - 검증 순서: 인증 → 입력 → normalize → challenge → signature → wallet cross-check → ownership 전이 방지 → register
-
nodeHasOwner/nodeOwnedByPrincipalhelper — principal-aware ownership cross-check (owner_principal우선,owner_user_idfallback) -
requireNodeAccess도 principal-aware — Heartbeat / ConnectNode 등이 wallet-owned 자율 노드에서도 통과 -
nodeToProto가 새 두 필드 응답에 채움
proto/alphea/v1/node.proto: NodeInfo 에 owner_principal_type / owner_principal_id 추가
테스트: wallet principal register 성공 + msg.WalletAddress mismatch reject
자율 노드 동작¶
wallet bearer + RegisterNode
↓
signature 검증 (EIP-191 ecrecover → wallet address)
+ wallet cross-check (msg.wallet == token sub)
↓
store: owner_user_id = NULL, owner_principal_type = "wallet",
owner_principal_id = <wallet_address>
↓
node JWT 발급 — ConnectNode bidi 가능
구현 순서 진행 상황¶
- 1. Section A
- 2a. proto contract
- 2b. nonce store + VerifySignature
- 2c. handlers + wallet JWT
- 2d. AuthContext Principal 모델
- 2e. RegisterNode wallet bearer + schema v16 — 본 이슈
- 3. Section B (Wallet Identity) 겹치는 상태
- 4. sdktest wallet-login — 다음
- 5. Section C auth toggle
검증¶
-
go test ./...통과 -
make lint통과 -
make dev-up(DB v15 → v16 적용 확인) +make smoke-check통과 - compose 4개 컨테이너 healthy/running
다음¶
step 4 — sdktest wallet-login 명령 추가. 흐름:
sdktest keygen
sdktest wallet-login # WalletChallenge → sign → WalletVerify → wallet JWT
sdktest node-register --auth wallet # wallet bearer 로 RegisterNode
sdktest connect --seconds 30 # node JWT 로 bidi
smoke-check 에도 이 흐름을 자동 검증 항목으로 추가.
CP Chris Park이(가) 6달 전에 변경
- 담당자을(를) James Lee에서 Henry Park(으)로 변경되었습니다.
HP Henry Park이(가) 6달 전에 변경
Step 4 완료 — sdktest wallet-login + node-register --auth¶
commit:server|1d84f1f
wallet-login → wallet bearer RegisterNode → ConnectNode 까지 sdktest 의 CLI reference 와 make smoke-check 자동 회귀 검증 완성.
cmd/sdktest¶
- state 에
WalletToken+WalletTokenExpiresAt추가 (state redaction 포함) -
wallet-login명령 — WalletChallenge → sign → WalletVerify → state 로 저장 -
node-register --auth user|wallet(defaultuser) — wallet 모드는 state.WalletToken bearer 사용 - wallet token 만료 시 "run wallet-login again" 안내
Makefile¶
- smoke-check 시퀀스 에 wallet-login +
node-register --auth wallet추가 — 자율 노드 시나리오 자동 검증
TEST_CLIENT_CHECKLIST.md — Phase 0.7 자동 항목 체크¶
- WalletChallenge nonce / domain / purpose / expiry / message
- WalletVerify 서명 검증 + wallet JWT 반환
- Wallet JWT typ=wallet, sub=
- Challenge nonce TTL + one-time use
- sdktest wallet-login
- RegisterNode user JWT
- RegisterNode wallet JWT
남은 항목 (UI/수동)¶
- Web Console Section A signs up a GoTrue user (UI smoke)
- Web Console Section A logs in (UI smoke)
- Web Console Section A refreshes session (UI smoke)
- Web Console Section B signs a wallet challenge with MetaMask (step 3 + MetaMask)
- Web Console Section C registers a node with a wallet token (step 5)
구현 순서 진행 상황 (7단계 중 6 완료 — 서버/CLI 레이어 완전 체르)¶
- 1. Section A (User/GoTrue) — UI 레이어
- 2a. proto contract
- 2b. nonce store + VerifySignature
- 2c. handlers + wallet JWT
- 2d. AuthContext Principal 모델
- 2e. RegisterNode wallet bearer + schema v16
- 4. sdktest wallet-login + node-register --auth
- 3. Web Console Section B (Wallet Identity, local key sign)
- 5. Web Console Section C (auth mode toggle)
서버/CLI 측은 production-grade 으로 완성. Section B/C 는 브라우저 reference UI 작업.
검증¶
-
go test ./...통과 -
make smoke-check는 서버 실 환경에서 별도 검증 (로컬 compose 필요)
다음¶
step 3 (Web Console Section B — Wallet Identity, local private key sign) + step 5 (Section C — auth mode toggle). 서버 RPC 는 이미 준비 되어 있으므로 JS UI 만 추가하면 됨.