본문으로 건너뛰기

WalletKit 서명과 페어링

Signer 인터페이스

WalletKit의 세션 API가 지갑 앱에 서명을 요청할 때 사용하는 인터페이스입니다. 세션 API 자체는 개인키를 생성·보관하지 않지만, 아래 InMemorySigner와 개인키 바이트를 직접 받는 서명 함수를 사용하면 키가 지갑 앱 프로세스 메모리에서 처리됩니다.

public interface Signer {
public val address: String
public suspend fun signRecoverable(digest: ByteArray): EthSignature
}
멤버설명
address서명자 EVM 주소. 0x 접두사가 있는 소문자, 체크섬 없음
signRecoverable32바이트 EIP-712 digest를 복구 가능한 서명으로 반환

Kotlin 인터페이스는 Swift에 프로토콜로 노출되므로 NSObject를 상속한 클래스로 구현합니다. 32바이트 서명 해시인 digestKotlinByteArray로 전달됩니다. 구현 예시는 서명하기의 Swift 탭을 참고하세요.

개인키를 인자로 전달하면 앱 메모리에 노출됩니다

WalletKit은 특정 개인키 저장 방식을 강제하지 않습니다. Secp256k1Signer처럼 개인키 바이트를 받는 함수를 사용하는 지갑은 자체 보안 구조와 사용자 인증 정책에 따라 개인키의 메모리 노출 시간을 최소화해야 합니다.

InMemorySigner

public class InMemorySigner(privateKey: ByteArray) : Signer

32바이트 secp256k1 개인키를 메모리에 보관하는 참조 구현입니다. 테스트·데모 전용이며, 실제 지갑 앱은 자체 보안 구조에 맞는 Signer를 구현합니다.

페어링 URI — PairingUri

public object PairingUri {
public data class Parsed(
val topic: String,
val symKey: ByteArray,
val relayUrl: String,
)

fun build(topic: String, symKey: ByteArray, relayUrl: String): String
fun parse(uri: String): Parsed
}
멤버설명
Parsed.topic페어링 채널 토픽. scope:@·? 앞 구간
Parsed.symKey페어링 채널 대칭키 바이트. hex 파라미터를 디코딩한 값
Parsed.relayUrlrelay-url 파라미터 값. 연결 대상은 빌드 시점 고정값이므로 진단용입니다
builddApp 측 빌더. relay-protocol=scr·version=1을 고정으로 붙입니다
parse지갑 측 파서. 아래 조건에서 예외를 던집니다

parse는 URI가 scope:로 시작하지 않거나, topic이 비어 있거나, symKey·relay-url 파라미터가 없으면 예외를 던집니다. symKey hex가 홀수 길이거나 잘못된 문자를 담고 있으면 hexToBytes()IllegalArgumentException을 던집니다.

scope:{topic}@1?relay-url={wss...}&symKey={hex}&relay-protocol=scr 형식의 페어링 URI를 topic, symKey, relayUrl 필드로 파싱합니다. 파싱된 relay-url은 연결 대상이 아닙니다 — WalletKit은 빌드 시점에 고정된 RelayDefaults.DEFAULT_RELAY_URL로 연결하며, 이 값은 진단(불일치 시 steps 기록)에만 쓰입니다. relay-protocol·version 파라미터 값은 파싱 시 검증하지 않습니다 — scr가 아닌 URI도 파싱은 성공하지만 이후 세션 연결에 실패합니다.