Skip to content

Commit

Permalink
Merge pull request #58 from WalletConnect/zerion-changes
Browse files Browse the repository at this point in the history
Zerion changes
  • Loading branch information
Andrey Scherbovich authored Jul 9, 2021
2 parents e446897 + f2eefeb commit c73e66d
Show file tree
Hide file tree
Showing 14 changed files with 118 additions and 56 deletions.
8 changes: 8 additions & 0 deletions ExampleApps/ClientApp/WalletConnect.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ extension WalletConnect: ClientDelegate {
delegate.failedToConnect()
}

func client(_ client: Client, didConnect url: WCURL) {
// do nothing
}

func client(_ client: Client, didConnect session: Session) {
self.session = session
let sessionData = try! JSONEncoder().encode(session)
Expand All @@ -81,4 +85,8 @@ extension WalletConnect: ClientDelegate {
UserDefaults.standard.removeObject(forKey: sessionKey)
delegate.didDisconnect()
}

func client(_ client: Client, didUpdate session: Session) {
// do nothing
}
}
10 changes: 5 additions & 5 deletions Sources/Internal/Communicator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ class Communicator {
return sessions.find(url: url)
}

func addSession(_ session: Session) {
sessions.add(session)
func addOrUpdateSession(_ session: Session) {
sessions.addOrUpdate(session)
}

func removeSession(by url: WCURL) {
Expand All @@ -53,8 +53,8 @@ class Communicator {
return pendingDisconnectSessions.find(url: url)
}

func addPendingDisconnectSession(_ session: Session) {
pendingDisconnectSessions.add(session)
func addOrUpdatePendingDisconnectSession(_ session: Session) {
pendingDisconnectSessions.addOrUpdate(session)
}

func removePendingDisconnectSession(by url: WCURL) {
Expand Down Expand Up @@ -107,7 +107,7 @@ class Communicator {
self.queue = queue
}

func add(_ session: Session) {
func addOrUpdate(_ session: Session) {
dispatchPrecondition(condition: .notOnQueue(queue))
queue.sync { [unowned self] in
self.sessions[session.url] = session
Expand Down
2 changes: 1 addition & 1 deletion Sources/Internal/HandshakeHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import Foundation

protocol HandshakeHandlerDelegate: class {
protocol HandshakeHandlerDelegate: AnyObject {
// TODO: instead of IDType, use RequestID
func handler(_ handler: HandshakeHandler, didReceiveRequestToCreateSession: Session, requestId: RequestID)
}
Expand Down
13 changes: 10 additions & 3 deletions Sources/Internal/UpdateSessionHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

import Foundation

protocol UpdateSessionHandlerDelegate: class {
func handler(_ handler: UpdateSessionHandler, didUpdateSessionByURL: WCURL, approved: Bool)
protocol UpdateSessionHandlerDelegate: AnyObject {
func handler(_ handler: UpdateSessionHandler, didUpdateSessionByURL: WCURL, sessionInfo: SessionInfo)
}

class UpdateSessionHandler: RequestHandler {
Expand All @@ -22,14 +22,21 @@ class UpdateSessionHandler: RequestHandler {
func handle(request: Request) {
do {
let sessionInfo = try request.parameter(of: SessionInfo.self, at: 0)
delegate?.handler(self, didUpdateSessionByURL: request.url, approved: sessionInfo.approved)
delegate?.handler(self, didUpdateSessionByURL: request.url, sessionInfo: sessionInfo)
} catch {
LogService.shared.log("WC: wrong format of wc_sessionUpdate request: \(error)")
// TODO: send error response
}
}
}

/// https://docs.walletconnect.org/tech-spec#session-update
struct SessionInfo: Decodable {
var approved: Bool
var accounts: [String]?
var chainId: Int?
}

enum ChainID {
static let mainnet = 1
}
42 changes: 31 additions & 11 deletions Sources/PublicInterface/Client.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@

import Foundation

public protocol ClientDelegate: class {
public protocol ClientDelegate: AnyObject {
func client(_ client: Client, didFailToConnect url: WCURL)
func client(_ client: Client, didConnect url: WCURL)
func client(_ client: Client, didConnect session: Session)
func client(_ client: Client, didDisconnect session: Session)
func client(_ client: Client, didUpdate session: Session)
}

public class Client: WalletConnect {
Expand Down Expand Up @@ -179,6 +181,7 @@ public class Client: WalletConnect {

override func onConnect(to url: WCURL) {
LogService.shared.log("WC: client didConnect url: \(url.bridgeURL.absoluteString)")
delegate?.client(self, didConnect: url)
if let existingSession = communicator.session(by: url) {
communicator.subscribe(on: existingSession.dAppInfo.peerId, url: existingSession.url)
delegate?.client(self, didConnect: existingSession)
Expand All @@ -205,7 +208,7 @@ public class Client: WalletConnect {
return
}

communicator.addSession(session)
communicator.addOrUpdateSession(session)
delegate?.client(self, didConnect: session)
} catch {
// TODO: handle error
Expand All @@ -228,16 +231,34 @@ public class Client: WalletConnect {

private func expectUpdateSessionRequest(_ request: Request) {
if request.method == "wc_sessionUpdate" {
guard let approval = sessionApproval(from: request) else {
guard let info = sessionInfo(from: request) else {
// TODO: error handling
try! send(Response(request: request, error: .invalidJSON))
return
}
guard let session = communicator.session(by: request.url), !approval else { return }
do {
try disconnect(from: session)
} catch { // session already disconnected
delegate?.client(self, didDisconnect: session)

guard let session = communicator.session(by: request.url) else { return }

if !info.approved {
do {
try disconnect(from: session)
} catch { // session already disconnected
delegate?.client(self, didDisconnect: session)
}
} else {
// we do not add sessions without walletInfo
let walletInfo = session.walletInfo!
let updatedInfo = Session.WalletInfo(
approved: info.approved,
accounts: info.accounts ?? [],
chainId: info.chainId ?? ChainID.mainnet,
peerId: walletInfo.peerId,
peerMeta: walletInfo.peerMeta
)
var updatedSesson = session
updatedSesson.walletInfo = updatedInfo
communicator.addOrUpdateSession(updatedSesson)
delegate?.client(self, didUpdate: updatedSesson)
}
} else {
// TODO: error handling
Expand All @@ -246,10 +267,10 @@ public class Client: WalletConnect {
}
}

private func sessionApproval(from request: Request) -> Bool? {
private func sessionInfo(from request: Request) -> SessionInfo? {
do {
let info = try request.parameter(of: SessionInfo.self, at: 0)
return info.approved
return info
} catch {
LogService.shared.log("WC: incoming approval cannot be parsed: \(error)")
return nil
Expand Down Expand Up @@ -302,7 +323,6 @@ public class Client: WalletConnect {
_ = self.responses.removeValue(forKey: requestID)
}
}

}

/// https://docs.walletconnect.org/json-rpc/ethereum#parameters-3
Expand Down
23 changes: 18 additions & 5 deletions Sources/PublicInterface/Server.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

import Foundation

public protocol RequestHandler: class {
public protocol RequestHandler: AnyObject {
func canHandle(request: Request) -> Bool
func handle(request: Request)
}

public protocol ServerDelegate: class {
public protocol ServerDelegate: AnyObject {
/// Websocket connection was dropped during handshake. The connectoin process should be initiated again.
func server(_ server: Server, didFailToConnect url: WCURL)

Expand Down Expand Up @@ -172,7 +172,7 @@ extension Server: HandshakeHandlerDelegate {
self.communicator.send(response, topic: session.dAppInfo.peerId)
if walletInfo.approved {
let updatedSession = Session(url: session.url, dAppInfo: session.dAppInfo, walletInfo: walletInfo)
self.communicator.addSession(updatedSession)
self.communicator.addOrUpdateSession(updatedSession)
self.communicator.subscribe(on: walletInfo.peerId, url: updatedSession.url)
self.delegate?.server(self, didConnect: updatedSession)
}
Expand All @@ -181,14 +181,27 @@ extension Server: HandshakeHandlerDelegate {
}

extension Server: UpdateSessionHandlerDelegate {
func handler(_ handler: UpdateSessionHandler, didUpdateSessionByURL url: WCURL, approved: Bool) {
func handler(_ handler: UpdateSessionHandler, didUpdateSessionByURL url: WCURL, sessionInfo: SessionInfo) {
guard let session = communicator.session(by: url) else { return }
if !approved {
if !sessionInfo.approved {
do {
try disconnect(from: session)
} catch { // session already disconnected
delegate?.server(self, didDisconnect: session)
}
} else {
// we do not add sessions without walletInfo
let walletInfo = session.walletInfo!
let updatedInfo = Session.WalletInfo(
approved: sessionInfo.approved,
accounts: sessionInfo.accounts ?? [],
chainId: sessionInfo.chainId ?? ChainID.mainnet,
peerId: walletInfo.peerId,
peerMeta: walletInfo.peerMeta
)
var updatedSesson = session
updatedSesson.walletInfo = updatedInfo
communicator.addOrUpdateSession(updatedSesson)
}
}
}
4 changes: 2 additions & 2 deletions Sources/PublicInterface/Session.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public struct Session: Codable {
public let url: URL
public let scheme: String?

public init(name: String, description: String?, icons: [URL], url: URL, scheme: String? = nil ) {
public init(name: String, description: String?, icons: [URL], url: URL, scheme: String? = nil) {
self.name = name
self.description = description
self.icons = icons
Expand All @@ -69,7 +69,7 @@ public struct Session: Codable {
self.peerMeta = peerMeta
}

func with(approved: Bool) -> WalletInfo {
public func with(approved: Bool) -> WalletInfo {
return WalletInfo(approved: approved,
accounts: self.accounts,
chainId: self.chainId,
Expand Down
4 changes: 2 additions & 2 deletions Sources/PublicInterface/WalletConnect.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ open class WalletConnect {
guard session.walletInfo != nil else {
throw WalletConnectError.missingWalletInfoInSession
}
communicator.addSession(session)
communicator.addOrUpdateSession(session)
listen(on: session.url)
}

Expand All @@ -46,7 +46,7 @@ open class WalletConnect {
throw WalletConnectError.tryingToDisconnectInactiveSession
}
try sendDisconnectSessionRequest(for: session)
communicator.addPendingDisconnectSession(session)
communicator.addOrUpdatePendingDisconnectSession(session)
communicator.disconnect(from: session.url)
}

Expand Down
26 changes: 21 additions & 5 deletions Tests/ClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ class ClientTests: XCTestCase {
}

func test_sendRequest_whenNoWalletInfo_thenThrows() {
communicator.addSession(Session.testSessionWithoutWalletInfo)
communicator.addOrUpdateSession(Session.testSessionWithoutWalletInfo)
XCTAssertThrowsError(try client.send(Request.testRequest, completion: nil),
"missingWalletInfoInSession") { error in
XCTAssertEqual(error as? Client.ClientError, .missingWalletInfoInSession)
}
}

func test_sendRequest_callsCommunicator() {
communicator.addSession(Session.testSession)
communicator.addOrUpdateSession(Session.testSession)
try? client.send(Request.testRequest, completion: nil)
XCTAssertNotNil(communicator.sentRequest)
}
Expand Down Expand Up @@ -68,19 +68,25 @@ class ClientTests: XCTestCase {

@discardableResult
private func prepareAccountWithTestSession() -> String {
communicator.addSession(Session.testSession)
communicator.addOrUpdateSession(Session.testSession)
return Session.testSession.walletInfo!.accounts[0]
}

func test_onConnect_whenSessionExists_thenSubscribesOnDappPeerIdTopic() {
communicator.addSession(Session.testSession)
communicator.addOrUpdateSession(Session.testSession)
client.onConnect(to: WCURL.testURL)
XCTAssertEqual(communicator.subscribedOn?.topic, Session.testSession.dAppInfo.peerId)
XCTAssertEqual(communicator.subscribedOn?.url, Session.testSession.url)
}

func test_onConnect_callsDelegate() {
XCTAssertNil(delegate.connectedUrl)
client.onConnect(to: WCURL.testURL)
XCTAssertEqual(delegate.connectedUrl, WCURL.testURL)
}

func test_onConnect_whenSessionExists_thenCallsDelegate() {
communicator.addSession(Session.testSession)
communicator.addOrUpdateSession(Session.testSession)
XCTAssertNil(delegate.connectedSession)
client.onConnect(to: WCURL.testURL)
XCTAssertEqual(delegate.connectedSession, Session.testSession)
Expand All @@ -104,6 +110,11 @@ class MockClientDelegate: ClientDelegate {
didFailToConnect = true
}

var connectedUrl: WCURL?
func client(_ client: Client, didConnect url: WCURL) {
connectedUrl = url
}

var connectedSession: Session?
func client(_ client: Client, didConnect session: Session) {
connectedSession = session
Expand All @@ -113,4 +124,9 @@ class MockClientDelegate: ClientDelegate {
func client(_ client: Client, didDisconnect session: Session) {
disconnectedSession = session
}

var didUpdateSession: Session?
func client(_ client: Client, didUpdate session: Session) {
didUpdateSession = session
}
}
2 changes: 1 addition & 1 deletion Tests/Helpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class MockCommunicator: Communicator {
didListen = true
}

override func addSession(_ session: Session) {
override func addOrUpdateSession(_ session: Session) {
sessions.append(session)
}

Expand Down
2 changes: 1 addition & 1 deletion Tests/WalletConnectTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class WalletConnectTests: XCTestCase {
}

func test_whenConnectingToExistingURL_thenThrows() {
mockCommunicator.addSession(Session.testSession)
mockCommunicator.addOrUpdateSession(Session.testSession)
XCTAssertThrowsError(try wc.connect(to: WCURL.testURL))
}

Expand Down
6 changes: 4 additions & 2 deletions WalletConnectSwift.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1030;
LastUpgradeCheck = 1030;
LastUpgradeCheck = 1250;
ORGANIZATIONNAME = "Gnosis Ltd.";
TargetAttributes = {
0A92784F230BFB2600FDCC0D = {
Expand Down Expand Up @@ -487,6 +487,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
Expand Down Expand Up @@ -548,6 +549,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
Expand Down Expand Up @@ -615,7 +617,7 @@
repositoryURL = "https://github.com/krzyzanowskim/CryptoSwift.git";
requirement = {
kind = upToNextMinorVersion;
minimumVersion = 1.2.0;
minimumVersion = 1.4.0;
};
};
55B7819524A614240036F8E5 /* XCRemoteSwiftPackageReference "Starscream" */ = {
Expand Down
Loading

0 comments on commit c73e66d

Please sign in to comment.