Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Sign] #372 Clean protocol codes #419

Merged
merged 4 commits into from
Aug 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Example/ExampleApp/Wallet/WalletViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ extension WalletViewController: ProposalViewControllerDelegate {
func didRejectSession() {
let proposal = currentProposal!
currentProposal = nil
reject(proposalId: proposal.id, reason: .disapprovedChains)
reject(proposalId: proposal.id, reason: .userRejectedChains)
}
}

Expand Down
5 changes: 2 additions & 3 deletions Example/IntegrationTests/Sign/SignClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ final class SignClientTests: XCTestCase {
wallet.onSessionProposal = { [unowned self] proposal in
Task(priority: .high) {
do {
try await wallet.client.reject(proposalId: proposal.id, reason: .disapprovedChains) // TODO: Review reason
try await wallet.client.reject(proposalId: proposal.id, reason: .userRejectedChains) // TODO: Review reason
store.rejectedProposal = proposal
} catch { XCTFail("\(error)") }
}
Expand Down Expand Up @@ -165,8 +165,7 @@ final class SignClientTests: XCTestCase {
wallet.onSessionProposal = { [unowned self] proposal in
Task(priority: .high) {
do {
try await wallet.client.approve(proposalId: proposal.id, namespaces: sessionNamespaces) }
catch {
try await wallet.client.approve(proposalId: proposal.id, namespaces: sessionNamespaces) } catch {
XCTFail("\(error)")
}
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/Auth/Services/Common/SIWEMessageFormatter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ struct SIWEMessageFormatter: SIWEMessageFormatting {
}
}

fileprivate struct SIWEMessage: Equatable {
private struct SIWEMessage: Equatable {
let domain: String
let uri: String //aud
let uri: String // aud
let address: String
let version: Int
let nonce: String
Expand Down
2 changes: 1 addition & 1 deletion Sources/Auth/Services/Wallet/AuthRequestSubscriber.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class AuthRequestSubscriber {
private let address: String
private var publishers = [AnyCancellable]()
private let messageFormatter: SIWEMessageFormatting
var onRequest: ((_ id: RPCID, _ message: String)->())?
var onRequest: ((_ id: RPCID, _ message: String)->Void)?

init(networkingInteractor: NetworkInteracting,
logger: ConsoleLogging,
Expand Down
6 changes: 3 additions & 3 deletions Sources/WalletConnectSign/Engine/Common/ApproveEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ private extension ApproveEngine {
)
settlingProposal = proposal

Task(priority: .high) {
Task(priority: .high) {
try? await networkingInteractor.subscribe(topic: sessionTopic)
}
} catch {
Expand Down Expand Up @@ -280,7 +280,7 @@ private extension ApproveEngine {

func handleSessionProposeRequest(payload: WCRequestSubscriptionPayload, proposal: SessionType.ProposeParams) throws {
logger.debug("Received Session Proposal")
do { try Namespace.validate(proposal.requiredNamespaces) } catch { throw Errors.respondError(payload: payload, reason: .invalidUpdateNamespaceRequest) }
do { try Namespace.validate(proposal.requiredNamespaces) } catch { throw Errors.respondError(payload: payload, reason: .invalidUpdateRequest) }
proposalPayloadsStore.set(payload, forKey: proposal.proposer.publicKey)
onSessionProposal?(proposal.publicRepresentation())
}
Expand All @@ -290,7 +290,7 @@ private extension ApproveEngine {
logger.debug("Did receive session settle request")

guard let proposedNamespaces = settlingProposal?.requiredNamespaces
else { throw Errors.respondError(payload: payload, reason: .invalidUpdateNamespaceRequest) }
else { throw Errors.respondError(payload: payload, reason: .invalidUpdateRequest) }

settlingProposal = nil

Expand Down
8 changes: 4 additions & 4 deletions Sources/WalletConnectSign/Engine/Common/SessionEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ private extension SessionEngine {
func onSessionDelete(_ payload: WCRequestSubscriptionPayload, deleteParams: SessionType.DeleteParams) throws {
let topic = payload.topic
guard sessionStore.hasSession(forTopic: topic) else {
throw Errors.respondError(payload: payload, reason: .noContextWithTopic(context: .session, topic: topic))
throw Errors.respondError(payload: payload, reason: .noSessionForTopic)
}
sessionStore.delete(topic: topic)
networkingInteractor.unsubscribe(topic: topic)
Expand All @@ -172,11 +172,11 @@ private extension SessionEngine {
chainId: payloadParams.chainId)

guard let session = sessionStore.getSession(forTopic: topic) else {
throw Errors.respondError(payload: payload, reason: .noContextWithTopic(context: .session, topic: topic))
throw Errors.respondError(payload: payload, reason: .noSessionForTopic)
}
let chain = request.chainId
guard session.hasNamespace(for: chain) else {
throw Errors.respondError(payload: payload, reason: .unauthorizedTargetChain(chain.absoluteString))
throw Errors.respondError(payload: payload, reason: .unauthorizedChain)
}
guard session.hasPermission(forMethod: request.method, onChain: chain) else {
throw Errors.respondError(payload: payload, reason: .unauthorizedMethod(request.method))
Expand All @@ -192,7 +192,7 @@ private extension SessionEngine {
let event = eventParams.event
let topic = payload.topic
guard let session = sessionStore.getSession(forTopic: topic) else {
throw Errors.respondError(payload: payload, reason: .noContextWithTopic(context: .session, topic: payload.topic))
throw Errors.respondError(payload: payload, reason: .noSessionForTopic)
}
guard
session.peerIsController,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,18 @@ final class NonControllerSessionStateMachine {
do {
try Namespace.validate(updateParams.namespaces)
} catch {
throw Errors.respondError(payload: payload, reason: .invalidUpdateNamespaceRequest)
throw Errors.respondError(payload: payload, reason: .invalidUpdateRequest)
}
guard var session = sessionStore.getSession(forTopic: payload.topic) else {
throw Errors.respondError(payload: payload, reason: .noContextWithTopic(context: .session, topic: payload.topic))
throw Errors.respondError(payload: payload, reason: .noSessionForTopic)
}
guard session.peerIsController else {
throw Errors.respondError(payload: payload, reason: .unauthorizedUpdateNamespacesRequest)
throw Errors.respondError(payload: payload, reason: .unauthorizedUpdateRequest)
}
do {
try session.updateNamespaces(updateParams.namespaces, timestamp: payload.timestamp)
} catch {
throw Errors.respondError(payload: payload, reason: .invalidUpdateNamespaceRequest)
throw Errors.respondError(payload: payload, reason: .invalidUpdateRequest)
}
sessionStore.setSession(session)
networkingInteractor.respondSuccess(for: payload)
Expand All @@ -83,15 +83,15 @@ final class NonControllerSessionStateMachine {
private func onSessionUpdateExpiry(_ payload: WCRequestSubscriptionPayload, updateExpiryParams: SessionType.UpdateExpiryParams) throws {
let topic = payload.topic
guard var session = sessionStore.getSession(forTopic: topic) else {
throw Errors.respondError(payload: payload, reason: .noContextWithTopic(context: .session, topic: topic))
throw Errors.respondError(payload: payload, reason: .noSessionForTopic)
}
guard session.peerIsController else {
throw Errors.respondError(payload: payload, reason: .unauthorizedUpdateExpiryRequest)
throw Errors.respondError(payload: payload, reason: .unauthorizedExtendRequest)
}
do {
try session.updateExpiry(to: updateExpiryParams.expiry)
} catch {
throw Errors.respondError(payload: payload, reason: .invalidUpdateExpiryRequest)
throw Errors.respondError(payload: payload, reason: .invalidExtendRequest)
}
sessionStore.setSession(session)
networkingInteractor.respondSuccess(for: payload)
Expand Down
21 changes: 12 additions & 9 deletions Sources/WalletConnectSign/RejectionReason.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,23 @@ import Foundation

/// https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-25.md
public enum RejectionReason {
case disapprovedChains
case disapprovedMethods
case disapprovedEventTypes
case userRejected
case userRejectedChains
case userRejectedMethods
case userRejectedEvents
}

internal extension RejectionReason {
func internalRepresentation() -> ReasonCode {
switch self {
case .disapprovedChains:
return ReasonCode.disapprovedChains
case .disapprovedMethods:
return ReasonCode.disapprovedMethods
case .disapprovedEventTypes:
return ReasonCode.disapprovedEventTypes
case .userRejected:
return ReasonCode.userRejected
case .userRejectedChains:
return ReasonCode.userRejectedChains
case .userRejectedMethods:
return ReasonCode.userRejectedMethods
case .userRejectedEvents:
return ReasonCode.userRejectedEvents
}
}
}
122 changes: 62 additions & 60 deletions Sources/WalletConnectSign/Types/ReasonCode.swift
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
enum ReasonCode {
enum ReasonCode: Codable, Equatable {

enum Context: String {
enum Context: String, Codable {
case pairing = "pairing"
case session = "session"
}

// 0 (Generic)
case generic(message: String)
// 1000 - (Internal)
case invalidMethod
case invalidEvent
case invalidUpdateRequest
case invalidExtendRequest
case noSessionForTopic

// 1000 (Internal)
case missingOrInvalid(String)
case invalidUpdateAccountsRequest
case invalidUpdateNamespaceRequest
case invalidUpdateExpiryRequest
case noContextWithTopic(context: Context, topic: String)

// 3000 (Unauthorized)
case unauthorizedTargetChain(String)
// 3000 - (Unauthorized)
case unauthorizedMethod(String)
case unauthorizedEvent(String)
case unauthorizedUpdateAccountRequest
case unauthorizedUpdateNamespacesRequest
case unauthorizedUpdateExpiryRequest
case unauthorizedMatchingController(isController: Bool)

// 5000
case disapprovedChains
case disapprovedMethods
case disapprovedEventTypes
case unauthorizedUpdateRequest
case unauthorizedExtendRequest
case unauthorizedChain

// 4001 - (EIP-1193)
case userRejectedRequest

// 5000 - (REJECTED (CAIP-25))
case userRejected
case userRejectedChains
case userRejectedMethods
case userRejectedEvents

case unsupportedChains
case unsupportedMethods
case unsupportedEvents
Expand All @@ -39,25 +39,23 @@ enum ReasonCode {

var code: Int {
switch self {
case .generic: return 0
case .missingOrInvalid: return 1000

case .invalidUpdateAccountsRequest: return 1003
case .invalidUpdateNamespaceRequest: return 1004
case .invalidUpdateExpiryRequest: return 1005
case .noContextWithTopic: return 1301
case .invalidMethod: return 1001
case .invalidEvent: return 1002
case .invalidUpdateRequest: return 1003
case .invalidExtendRequest: return 1004

case .unauthorizedTargetChain: return 3000
case .unauthorizedMethod: return 3001
case .unauthorizedEvent: return 3002
case .unauthorizedUpdateRequest: return 3003
case .unauthorizedExtendRequest: return 3004
case .unauthorizedChain: return 3005

case .userRejectedRequest: return 4001

case .unauthorizedUpdateAccountRequest: return 3003
case .unauthorizedUpdateNamespacesRequest: return 3004
case .unauthorizedUpdateExpiryRequest: return 3005
case .unauthorizedMatchingController: return 3100
case .disapprovedChains: return 5000
case .disapprovedMethods: return 5001
case .disapprovedEventTypes: return 5002
case .userRejected: return 5000
case .userRejectedChains: return 5001
case .userRejectedMethods: return 5002
case .userRejectedEvents: return 5003

case .unsupportedChains: return 5100
case .unsupportedMethods: return 5101
Expand All @@ -66,43 +64,47 @@ enum ReasonCode {
case .unsupportedNamespaceKey: return 5104

case .userDisconnected: return 6000

case .noSessionForTopic: return 7001
}
}

var message: String {
switch self {
case .generic(let message):
return message
case .missingOrInvalid(let name):
return "Missing or invalid \(name)"
case .invalidUpdateAccountsRequest:
return "Invalid update accounts request"
case .invalidUpdateNamespaceRequest:
case .invalidMethod:
return "Invalid Method"
case .invalidEvent:
return "Invalid Event"
case .invalidUpdateRequest:
return "Invalid update namespace request"
case .invalidUpdateExpiryRequest:
case .invalidExtendRequest:
return "Invalid update expiry request"
case .noContextWithTopic(let context, let topic):
return "No matching \(context) with topic: \(topic)"
case .unauthorizedTargetChain(let chainId):
return "Unauthorized target chain id requested: \(chainId)"
case .noSessionForTopic:
return "No matching session matching topic"

case .unauthorizedMethod(let method):
return "Unauthorized JSON-RPC method requested: \(method)"
case .unauthorizedEvent(let type):
return "Unauthorized event type requested: \(type)"
case .unauthorizedUpdateAccountRequest:
return "Unauthorized update accounts request"
case .unauthorizedUpdateNamespacesRequest:
return "Unauthorized update namespaces request"
case .unauthorizedUpdateExpiryRequest:
return "Unauthorized update expiry request"
case .unauthorizedMatchingController(let isController):
return "Unauthorized: peer is also \(isController ? "" : "non-")controller"
case .disapprovedChains:
case .unauthorizedUpdateRequest:
return "Unauthorized update request"
case .unauthorizedExtendRequest:
return "Unauthorized extend request"
case .unauthorizedChain:
return "Unauthorized target chain id requested"

case .userRejectedRequest:
return "User rejected request"

case .userRejected:
return "User rejected"
case .userRejectedChains:
return "User disapproved requested chains"
case .disapprovedMethods:
case .userRejectedMethods:
return "User disapproved requested json-rpc methods"
case .disapprovedEventTypes:
case .userRejectedEvents:
return "User disapproved requested event types"

case .unsupportedChains:
return "Unsupported or empty chains for namespace"
case .unsupportedMethods:
Expand Down
1 change: 0 additions & 1 deletion Tests/AuthTests/SIWEMessageFormatterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ class SIWEMessageFormatterTests: XCTestCase {
var sut: SIWEMessageFormatter!
let address = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"


override func setUp() {
sut = SIWEMessageFormatter()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class NonControllerSessionStateMachineTests: XCTestCase {
networkingInteractor.wcRequestPublisherSubject.send(WCRequestSubscriptionPayload.stubUpdateNamespaces(topic: ""))
usleep(100)
XCTAssertFalse(networkingInteractor.didRespondSuccess)
XCTAssertEqual(networkingInteractor.lastErrorCode, 1301)
XCTAssertEqual(networkingInteractor.lastErrorCode, 7001)
}

func testUpdateMethodPeerErrorUnauthorized() {
Expand All @@ -61,7 +61,7 @@ class NonControllerSessionStateMachineTests: XCTestCase {
networkingInteractor.wcRequestPublisherSubject.send(WCRequestSubscriptionPayload.stubUpdateNamespaces(topic: session.topic))
usleep(100)
XCTAssertFalse(networkingInteractor.didRespondSuccess)
XCTAssertEqual(networkingInteractor.lastErrorCode, 3004)
XCTAssertEqual(networkingInteractor.lastErrorCode, 3003)
}

// MARK: - Update Expiry
Expand Down