본문으로 건너뛰기

WalletKit 승인

승인 단계

connect()는 두 지점에서 호스트 승인을 받습니다.

승인 단계시점거절 시
ApprovalRequest.ConnectiondApp propose 수신 후, settle 전세션을 수립하지 않고 approved = false로 반환합니다 (dApp에는 응답을 발행하지 않습니다)
ApprovalRequest.Sign서명 직전dApp에 EIP-1193 4001 오류로 응답하고 approved = false로 반환합니다

두 SDK의 오류 코드 대응 관계는 오류 처리을 참고합니다.

ApprovalRequestApprovalDecision

public sealed interface ApprovalRequest {
public data class Connection(val info: ConnectionRequestInfo) : ApprovalRequest
public data class Sign(val info: SignRequestInfo) : ApprovalRequest
}

public data class ApprovalDecision(val approved: Boolean, val reason: String? = null) {
public companion object {
public val APPROVE: ApprovalDecision
public fun reject(reason: String): ApprovalDecision
}
}

reject(reason)reason은 호출한 앱 코드에서 쓰기 위한 문자열입니다 — dApp에 전달되거나 라이브러리가 기록하지는 않으며, 서명 거절 응답에는 고정 메시지와 4001 코드가 실립니다.

sealed 계층은 Swift에 평탄화된 클래스 이름으로 노출됩니다 — ApprovalRequest.ConnectionApprovalRequestConnection, ApprovalRequest.SignApprovalRequestSign으로 캐스팅해 분기합니다. companion 멤버는 ApprovalDecision.companion.APPROVE·ApprovalDecision.companion.reject(reason:)으로 접근합니다.

ConnectionRequestInfo

public data class ConnectionRequestInfo(
val dappName: String,
val chains: List<String>,
val pairingTopic: String,
)
필드설명
dappNameproposer.metadata에 담긴 dApp 이름
chains요청된 CAIP-2 체인 목록
pairingTopic페어링 토픽

SignRequestInfo

디코딩된 EIP-3009 eth_signTypedData_v4 요청입니다. 필드는 표시용 문자열이며 금액은 토큰의 최소 단위로 표현된 정수입니다.

public data class SignRequestInfo(
val account: String,
val chainId: String,
val method: String,
val tokenName: String,
val verifyingContract: String,
val from: String,
val to: String,
val value: String,
val validAfter: String,
val validBefore: String,
val nonce: String,
)
필드설명
account서명 계정
chainIdeip155:{n} 형식의 CAIP-2 체인
methodeth_signTypedData_v4
tokenNameEIP-712 domain.name
verifyingContract서명 검증에 사용할 컨트랙트 주소
from, to전송 당사자
value토큰의 최소 단위로 표현된 uint256 정수
validAfter, validBefore유효 기간
noncebytes32 랜덤 nonce

사용 예

val wallet = WalletKit(WalletKitConfig(metadata = WalletMetadata("My Wallet")))
wallet.setApprovalHandler { request ->
when (request) {
is ApprovalRequest.Connection ->
if (userAllows(request.info.dappName)) ApprovalDecision.APPROVE
else ApprovalDecision.reject("user declined")
is ApprovalRequest.Sign ->
if (userConfirms(request.info)) ApprovalDecision.APPROVE
else ApprovalDecision.reject("user declined")
}
}
val result = wallet.connect(scannedUri, signer)
if (result.approved) submitElsewhere(result.signatureHex)

승인 전에는 요청의 도메인, 체인 ID, 서명 검증에 사용할 컨트랙트와 모든 메시지 필드를 사용자에게 표시하고 검증합니다.