Skip to content

Commit

Permalink
Merge pull request #1364 from WalletConnect/jack/rejection-tags
Browse files Browse the repository at this point in the history
chore(rejection tags): Session rejection tags
  • Loading branch information
jackpooleywc authored Jun 3, 2024
2 parents d50f11f + aee6e31 commit f757f1b
Show file tree
Hide file tree
Showing 12 changed files with 130 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ class LinkAuthRequestSubscriber {

private func subscribeForRequest() {

envelopesDispatcher.requestSubscription(on: SessionAuthenticatedProtocolMethod().method)
envelopesDispatcher
.requestSubscription(on: SessionAuthenticatedProtocolMethod.responseApprove().method)
.sink { [unowned self] (payload: RequestSubscriptionPayload<SessionAuthenticateRequestParams>) in

logger.debug("LinkAuthRequestSubscriber: Received request")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ actor LinkAuthRequester {
var params = params
let pubKey = try kms.createX25519KeyPair()
let responseTopic = pubKey.rawRepresentation.sha256().toHexString()
let protocolMethod = SessionAuthenticatedProtocolMethod(ttl: params.ttl)
let protocolMethod = SessionAuthenticatedProtocolMethod.responseApprove(ttl: params.ttl)
guard let chainNamespace = Blockchain(params.chains.first!)?.namespace,
chainNamespace == "eip155"
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,15 @@ class AuthResponseSubscriber {
}

private func subscribeForResponse() {
networkingInteractor.responseErrorSubscription(on: SessionAuthenticatedProtocolMethod())
networkingInteractor
.responseErrorSubscription(on: SessionAuthenticatedProtocolMethod.responseApprove())
.sink { [unowned self] (payload: ResponseSubscriptionErrorPayload<SessionAuthenticateRequestParams>) in
guard let error = AuthError(code: payload.error.code) else { return }
authResponsePublisherSubject.send((payload.id, .failure(error)))
}.store(in: &publishers)

networkingInteractor.responseSubscription(on: SessionAuthenticatedProtocolMethod())
networkingInteractor
.responseSubscription(on: SessionAuthenticatedProtocolMethod.responseApprove())
.sink { [unowned self] (payload: ResponseSubscriptionPayload<SessionAuthenticateRequestParams, SessionAuthenticateResponseParams>) in

let transportType = getTransportTypeUpgradeIfPossible(peerMetadata: payload.response.responder.metadata, requestId: payload.id)
Expand Down Expand Up @@ -86,13 +88,13 @@ class AuthResponseSubscriber {
}

private func subscribeForLinkResponse() {
linkEnvelopesDispatcher.responseErrorSubscription(on: SessionAuthenticatedProtocolMethod())
linkEnvelopesDispatcher.responseErrorSubscription(on: SessionAuthenticatedProtocolMethod.responseApprove())
.sink { [unowned self] (payload: ResponseSubscriptionErrorPayload<SessionAuthenticateRequestParams>) in
guard let error = AuthError(code: payload.error.code) else { return }
authResponsePublisherSubject.send((payload.id, .failure(error)))
}.store(in: &publishers)

linkEnvelopesDispatcher.responseSubscription(on: SessionAuthenticatedProtocolMethod())
linkEnvelopesDispatcher.responseSubscription(on: SessionAuthenticatedProtocolMethod.responseApprove())
.sink { [unowned self] (payload: ResponseSubscriptionPayload<SessionAuthenticateRequestParams, SessionAuthenticateResponseParams>) in

let pairingTopic = payload.topic
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ class AuthenticateTransportTypeSwitcher {
// Continue with relay if the error is walletLinkSupportNotProven
}

let pairingURI = try await pairingClient.create(methods: [SessionAuthenticatedProtocolMethod().method])
let pairingURI = try await pairingClient.create(
methods: [SessionAuthenticatedProtocolMethod.responseApprove().method]
)
logger.debug("Requesting Authentication on existing pairing")
try await appRequestService.request(params: params, topic: pairingURI.topic)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ actor SessionAuthRequestService {
var params = params
let pubKey = try kms.createX25519KeyPair()
let responseTopic = pubKey.rawRepresentation.sha256().toHexString()
let protocolMethod = SessionAuthenticatedProtocolMethod(ttl: params.ttl)
let protocolMethod = SessionAuthenticatedProtocolMethod.responseApprove(ttl: params.ttl)
guard let chainNamespace = Blockchain(params.chains.first!)?.namespace,
chainNamespace == "eip155"
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class AuthRequestSubscriber {
}

private func subscribeForRequest() {
pairingRegisterer.register(method: SessionAuthenticatedProtocolMethod())
pairingRegisterer.register(method: SessionAuthenticatedProtocolMethod.responseApprove())
.sink { [unowned self] (payload: RequestSubscriptionPayload<SessionAuthenticateRequestParams>) in

guard !payload.request.isExpired() else {
Expand Down Expand Up @@ -70,10 +70,15 @@ class AuthRequestSubscriber {
}.store(in: &publishers)
}

func respondError(payload: SubscriptionPayload, reason: SignReasonCode) {
private func respondError(payload: SubscriptionPayload, reason: SignReasonCode) {
Task(priority: .high) {
do {
try await networkingInteractor.respondError(topic: payload.topic, requestId: payload.id, protocolMethod: SessionAuthenticatedProtocolMethod(), reason: reason)
try await networkingInteractor.respondError(
topic: payload.topic,
requestId: payload.id,
protocolMethod: SessionAuthenticatedProtocolMethod.responseAutoReject(),
reason: reason
)
} catch {
logger.error("Respond Error failed with: \(error.localizedDescription)")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,13 @@ actor SessionAuthenticateResponder {
let responseParams = SessionAuthenticateResponseParams(responder: selfParticipant, cacaos: auths)

let response = RPCResponse(id: requestId, result: responseParams)
try await networkingInteractor.respond(topic: responseTopic, response: response, protocolMethod: SessionAuthenticatedProtocolMethod(), envelopeType: .type1(pubKey: responseKeys.publicKey.rawRepresentation))

try await networkingInteractor.respond(
topic: responseTopic,
response: response,
protocolMethod: SessionAuthenticatedProtocolMethod.responseApprove(),
envelopeType: .type1(pubKey: responseKeys.publicKey.rawRepresentation)
)


let session = try util.createSession(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,47 @@
import Foundation

struct SessionAuthenticatedProtocolMethod: ProtocolMethod {

enum Tag: Int {
case sessionAuthenticate = 1116
case sessionAuthenticateResponseApprove = 1117
case sessionAuthenticateResponseReject = 1118
case sessionAuthenticateResponseAutoReject = 1119
}

let method: String = "wc_sessionAuthenticate"

let requestConfig = RelayConfig(tag: 1116, prompt: true, ttl: 3600)

let responseConfig = RelayConfig(tag: 1117, prompt: false, ttl: 3600)


static let defaultTtl: TimeInterval = 3600
private let ttl: Int
let requestConfig: RelayConfig

let responseConfig: RelayConfig

init(ttl: TimeInterval = Self.defaultTtl) {
self.ttl = Int(ttl)
static let defaultTtl: TimeInterval = 300

private init(
ttl: TimeInterval,
responseTag: Tag
) {
self.requestConfig = RelayConfig(
tag: Tag.sessionAuthenticate.rawValue,
prompt: true,
ttl: Int(ttl)
)
self.responseConfig = RelayConfig(
tag: responseTag.rawValue,
prompt: false,
ttl: Int(ttl)
)
}

static func responseApprove(ttl: TimeInterval = Self.defaultTtl) -> Self {
Self(ttl: ttl, responseTag: .sessionAuthenticateResponseApprove)
}

static func responseReject(ttl: TimeInterval = Self.defaultTtl) -> Self {
Self(ttl: ttl, responseTag: .sessionAuthenticateResponseReject)
}

static func responseAutoReject(ttl: TimeInterval = Self.defaultTtl) -> Self {
Self(ttl: ttl, responseTag: .sessionAuthenticateResponseAutoReject)
}
}
25 changes: 16 additions & 9 deletions Sources/WalletConnectSign/Engine/Common/ApproveEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ final class ApproveEngine {
async let proposeResponseTask: () = networkingInteractor.respond(
topic: payload.topic,
response: response,
protocolMethod: SessionProposeProtocolMethod()
protocolMethod: SessionProposeProtocolMethod.responseApprove()
)

async let settleRequestTask: WCSession = settle(
Expand Down Expand Up @@ -146,8 +146,13 @@ final class ApproveEngine {
guard let payload = try proposalPayloadsStore.get(key: proposerPubKey) else {
throw Errors.proposalNotFound
}

try await networkingInteractor.respondError(topic: payload.topic, requestId: payload.id, protocolMethod: SessionProposeProtocolMethod(), reason: reason)

try await networkingInteractor.respondError(
topic: payload.topic,
requestId: payload.id,
protocolMethod: SessionProposeProtocolMethod.responseReject(),
reason: reason
)

if let pairingTopic = rpcHistory.get(recordId: payload.id)?.topic,
let pairing = pairingStore.getPairing(forTopic: pairingTopic),
Expand Down Expand Up @@ -216,12 +221,14 @@ final class ApproveEngine {
private extension ApproveEngine {

func setupRequestSubscriptions() {
pairingRegisterer.register(method: SessionProposeProtocolMethod())
pairingRegisterer.register(method: SessionProposeProtocolMethod.responseAutoReject())
.sink { [unowned self] (payload: RequestSubscriptionPayload<SessionType.ProposeParams>) in
guard let pairing = pairingStore.getPairing(forTopic: payload.topic) else { return }
let responseApproveMethod = SessionAuthenticatedProtocolMethod.responseApprove().method
if let methods = pairing.methods,
methods.flatMap({ $0 })
.contains(SessionAuthenticatedProtocolMethod().method), authRequestSubscribersTracking.hasSubscribers() {
methods.contains(responseApproveMethod),
authRequestSubscribersTracking.hasSubscribers()
{
logger.debug("Ignoring Session Proposal")
// respond with an error?
return
Expand All @@ -236,7 +243,7 @@ private extension ApproveEngine {
}

func setupResponseSubscriptions() {
networkingInteractor.responseSubscription(on: SessionProposeProtocolMethod())
networkingInteractor.responseSubscription(on: SessionProposeProtocolMethod.responseApprove())
.sink { [unowned self] (payload: ResponseSubscriptionPayload<SessionType.ProposeParams, SessionType.ProposeResponse>) in
handleSessionProposeResponse(payload: payload)
}.store(in: &publishers)
Expand All @@ -248,7 +255,7 @@ private extension ApproveEngine {
}

func setupResponseErrorSubscriptions() {
networkingInteractor.responseErrorSubscription(on: SessionProposeProtocolMethod())
networkingInteractor.responseErrorSubscription(on: SessionProposeProtocolMethod.responseApprove())
.sink { [unowned self] (payload: ResponseSubscriptionErrorPayload<SessionType.ProposeParams>) in
handleSessionProposeResponseError(payload: payload)
}.store(in: &publishers)
Expand Down Expand Up @@ -340,7 +347,7 @@ private extension ApproveEngine {
logger.debug("Received Session Proposal")
let proposal = payload.request
do { try Namespace.validate(proposal.requiredNamespaces) } catch {
return respondError(payload: payload, reason: .invalidUpdateRequest, protocolMethod: SessionProposeProtocolMethod())
return respondError(payload: payload, reason: .invalidUpdateRequest, protocolMethod: SessionProposeProtocolMethod.responseAutoReject())
}
proposalPayloadsStore.set(payload, forKey: proposal.proposer.publicKey)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,13 @@ actor WalletErrorResponder {

private func respondErrorRelay(_ error: AuthError, requestId: RPCID, topic: String, type1EnvelopeKey: Data) async throws {
let envelopeType = Envelope.EnvelopeType.type1(pubKey: type1EnvelopeKey)
try await networkingInteractor.respondError(topic: topic, requestId: requestId, protocolMethod: SessionAuthenticatedProtocolMethod(), reason: error, envelopeType: envelopeType)
try await networkingInteractor.respondError(
topic: topic,
requestId: requestId,
protocolMethod: SessionAuthenticatedProtocolMethod.responseReject(),
reason: error,
envelopeType: envelopeType
)
}

private func respondErrorLinkMode(_ error: AuthError, requestId: RPCID, topic: String, type1EnvelopeKey: Data) async throws -> String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ final class AppProposeService {
if let sessionProperties {
try SessionProperties.validate(sessionProperties)
}
let protocolMethod = SessionProposeProtocolMethod()
let protocolMethod = SessionProposeProtocolMethod.responseApprove()
let publicKey = try! kms.createX25519KeyPair()
let proposer = Participant(
publicKey: publicKey.hexRepresentation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,45 @@ import Foundation

struct SessionProposeProtocolMethod: ProtocolMethod {
let method: String = "wc_sessionPropose"

enum Tag: Int {
case sessionPropose = 1100
case sessionProposeResponseApprove = 1101
case sessionProposeResponseReject = 1120
case sessionProposeResponseAutoReject = 1121
}

let requestConfig = RelayConfig(tag: 1100, prompt: true, ttl: 300)
let requestConfig: RelayConfig

let responseConfig = RelayConfig(tag: 1101, prompt: false, ttl: 300)
let responseConfig: RelayConfig

static let defaultTtl: TimeInterval = 300

private init(
ttl: TimeInterval,
responseTag: Tag
) {
self.requestConfig = RelayConfig(
tag: Tag.sessionPropose.rawValue,
prompt: true,
ttl: Int(ttl)
)
self.responseConfig = RelayConfig(
tag: responseTag.rawValue,
prompt: false,
ttl: Int(ttl)
)
}

static func responseApprove(ttl: TimeInterval = Self.defaultTtl) -> Self {
Self(ttl: ttl, responseTag: .sessionProposeResponseApprove)
}

static func responseReject(ttl: TimeInterval = Self.defaultTtl) -> Self {
Self(ttl: ttl, responseTag: .sessionProposeResponseReject)
}

static func responseAutoReject(ttl: TimeInterval = Self.defaultTtl) -> Self {
Self(ttl: ttl, responseTag: .sessionProposeResponseAutoReject)
}
}

0 comments on commit f757f1b

Please sign in to comment.