Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:WalletConnect/WalletConnectSwift…
Browse files Browse the repository at this point in the history
…V2 into #263-Add-client-id
  • Loading branch information
llbartekll committed Jun 23, 2022
2 parents 621942c + f676780 commit d61a9d8
Show file tree
Hide file tree
Showing 29 changed files with 473 additions and 89 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/swift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ jobs:
with:
xcode-version: '13.2'

- uses: actions/cache@v2
with:
path: .build
key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }}
restore-keys: |
${{ runner.os }}-spm-
# Package builds
- name: Build Package
run: swift build -v
Expand Down
6 changes: 3 additions & 3 deletions Example/DApp/Connect/ConnectViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ class ConnectViewController: UIViewController, UITableViewDataSource, UITableVie
super.viewDidLoad()
DispatchQueue.global().async { [unowned self] in
if let qrImage = generateQRCode(from: uriString) {
DispatchQueue.main.async {
connectView.qrCodeView.image = qrImage
connectView.copyButton.isHidden = false
DispatchQueue.main.async { [self] in
self.connectView.qrCodeView.image = qrImage
self.connectView.copyButton.isHidden = false
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions Example/ExampleApp/Wallet/WalletViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,8 @@ extension WalletViewController {
return settledSessions.map { session -> ActiveSessionItem in
let app = session.peer
return ActiveSessionItem(
dappName: app.name ?? "",
dappURL: app.url ?? "",
dappName: app.name ,
dappURL: app.url ,
iconURL: app.icons.first ?? "",
topic: session.topic)
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/Chat/Types/ChatRequestParams.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ enum ChatRequestParams: Codable, Equatable {
}

extension JSONRPCRequest {
init(id: Int64 = JSONRPCRequest.generateId(), params: T) where T == ChatRequestParams {
init(id: Int64 = JsonRpcID.generate(), params: T) where T == ChatRequestParams {
var method: String!
switch params {
case .invite:
Expand Down
8 changes: 5 additions & 3 deletions Sources/WalletConnectSign/Engine/Common/ApproveEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,11 @@ final class ApproveEngine {
}
proposalPayloadsStore.delete(forKey: proposerPubKey)
try await networkingInteractor.respondError(payload: payload, reason: reason)
// TODO: Delete pairing if inactive
// TODO: Delete pairing if inactive
}

func settle(topic: String, proposal: SessionProposal, namespaces: [String: SessionNamespace]) async throws {
guard let agreementKeys = try kms.getAgreementSecret(for: topic) else {
guard let agreementKeys = kms.getAgreementSecret(for: topic) else {
throw Errors.agreementMissingOrInvalid
}
let selfParticipant = Participant(
Expand All @@ -120,6 +120,7 @@ final class ApproveEngine {

let session = WCSession(
topic: topic,
timestamp: Date(),
selfParticipant: selfParticipant,
peerParticipant: proposal.proposer,
settleParams: settleParams,
Expand Down Expand Up @@ -294,7 +295,7 @@ private extension ApproveEngine {
}

let topic = payload.topic
let agreementKeys = try kms.getAgreementSecret(for: topic)!
let agreementKeys = kms.getAgreementSecret(for: topic)!
let selfParticipant = Participant(
publicKey: agreementKeys.publicKey.hexRepresentation,
metadata: metadata
Expand All @@ -305,6 +306,7 @@ private extension ApproveEngine {

let session = WCSession(
topic: topic,
timestamp: Date(),
selfParticipant: selfParticipant,
peerParticipant: settleParams.controller,
settleParams: settleParams,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ final class ControllerSessionStateMachine {
try validateControlledAcknowledged(session)
try Namespace.validate(namespaces)
logger.debug("Controller will update methods")
session.updateNamespaces(namespaces)
try session.updateNamespaces(namespaces)
sessionStore.setSession(session)
try await networkingInteractor.request(.wcSessionUpdate(SessionType.UpdateParams(namespaces: namespaces)), onTopic: topic)
}
Expand All @@ -50,42 +50,46 @@ final class ControllerSessionStateMachine {

private func handleResponse(_ response: WCResponse) {
switch response.requestParams {
case .sessionUpdate:
handleUpdateResponse(topic: response.topic, result: response.result)
case .sessionExtend:
handleUpdateExpiryResponse(topic: response.topic, result: response.result)
case .sessionUpdate(let payload):
handleUpdateResponse(response: response, payload: payload)
case .sessionExtend(let payload):
handleUpdateExpiryResponse(response: response, payload: payload)
default:
break
}
}

// TODO: Re-enable callback
private func handleUpdateResponse(topic: String, result: JsonRpcResult) {
guard let _ = sessionStore.getSession(forTopic: topic) else {
return
}
switch result {
private func handleUpdateResponse(response: WCResponse, payload: SessionType.UpdateParams) {
guard var session = sessionStore.getSession(forTopic: response.topic) else { return }
switch response.result {
case .response:
// TODO - state sync
// onNamespacesUpdate?(session.topic, session.namespaces)
break
do {
try session.updateNamespaces(payload.namespaces, timestamp: response.timestamp)

if sessionStore.setSessionIfNewer(session) {
onNamespacesUpdate?(session.topic, session.namespaces)
}
} catch {
logger.error("Update namespaces error: \(error.localizedDescription)")
}
case .error:
// TODO - state sync
logger.error("Peer failed to update methods.")
logger.error("Peer failed to update session")
}
}

private func handleUpdateExpiryResponse(topic: String, result: JsonRpcResult) {
guard let session = sessionStore.getSession(forTopic: topic) else {
return
}
switch result {
private func handleUpdateExpiryResponse(response: WCResponse, payload: SessionType.UpdateExpiryParams) {
guard var session = sessionStore.getSession(forTopic: response.topic) else { return }
switch response.result {
case .response:
// TODO - state sync
onExtend?(session.topic, session.expiryDate)
do {
try session.updateExpiry(to: payload.expiry)
sessionStore.setSession(session)
onExtend?(session.topic, session.expiryDate)
} catch {
logger.error("Update expiry error: \(error.localizedDescription)")
}
case .error:
// TODO - state sync
logger.error("Peer failed to update events.")
logger.error("Peer failed to extend session")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,11 @@ final class NonControllerSessionStateMachine {
guard session.peerIsController else {
throw Errors.respondError(payload: payload, reason: .unauthorizedUpdateNamespacesRequest)
}
session.updateNamespaces(updateParams.namespaces)
do {
try session.updateNamespaces(updateParams.namespaces, timestamp: payload.timestamp)
} catch {
throw Errors.respondError(payload: payload, reason: .invalidUpdateNamespaceRequest)
}
sessionStore.setSession(session)
networkingInteractor.respondSuccess(for: payload)
onNamespacesUpdate?(session.topic, updateParams.namespaces)
Expand Down
6 changes: 6 additions & 0 deletions Sources/WalletConnectSign/Namespace.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ public struct SessionNamespace: Equatable, Codable {
self.methods = methods
self.events = events
}

func isSuperset(of other: Extension) -> Bool {
self.accounts.isSuperset(of: other.accounts) &&
self.methods.isSuperset(of: other.methods) &&
self.events.isSuperset(of: other.events)
}
}

public init(accounts: Set<Account>, methods: Set<String>, events: Set<String>, extensions: [SessionNamespace.Extension]? = nil) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,6 @@ import Combine
import WalletConnectUtils
import WalletConnectKMS

struct WCResponse: Codable {
let topic: String
let chainId: String?
let requestMethod: WCRequest.Method
let requestParams: WCRequest.Params
let result: JsonRpcResult
}

protocol NetworkInteracting: AnyObject {
var transportConnectionPublisher: AnyPublisher<Void, Never> {get}
var wcRequestPublisher: AnyPublisher<WCRequestSubscriptionPayload, Never> {get}
Expand Down
6 changes: 1 addition & 5 deletions Sources/WalletConnectSign/Request.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,10 @@ public struct Request: Codable, Equatable {
}

public init(topic: String, method: String, params: AnyCodable, chainId: Blockchain) {
self.id = Self.generateId()
self.id = JsonRpcID.generate()
self.topic = topic
self.method = method
self.params = params
self.chainId = chainId
}

public static func generateId() -> Int64 {
return Int64(Date().timeIntervalSince1970 * 1000)*1000 + Int64.random(in: 0..<1000)
}
}
14 changes: 10 additions & 4 deletions Sources/WalletConnectSign/Storage/SequenceStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ protocol Expirable {
var expiryDate: Date { get }
}

protocol ExpirableSequence: Codable, Expirable {
protocol Entitled {
var topic: String { get }
}

// TODO: Find replacement for 'Sequence' prefix
final class SequenceStore<T> where T: ExpirableSequence {
typealias SequenceObject = Entitled & Expirable & Codable

final class SequenceStore<T> where T: SequenceObject {

var onSequenceExpiration: ((_ sequence: T) -> Void)?

Expand Down Expand Up @@ -47,8 +48,13 @@ final class SequenceStore<T> where T: ExpirableSequence {
func deleteAll() {
store.deleteAll()
}
}

// MARK: Privates

private extension SequenceStore {

private func verifyExpiry(on sequence: T) -> T? {
func verifyExpiry(on sequence: T) -> T? {
let now = dateInitializer()
if now >= sequence.expiryDate {
store.delete(forKey: sequence.topic)
Expand Down
21 changes: 20 additions & 1 deletion Sources/WalletConnectSign/Storage/SessionStorage.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
protocol WCSessionStorage: AnyObject {
var onSessionExpiration: ((WCSession) -> Void)? { get set }
func hasSession(forTopic topic: String) -> Bool
@discardableResult
func setSessionIfNewer(_ session: WCSession) -> Bool
func setSession(_ session: WCSession)
func hasSession(forTopic topic: String) -> Bool
func getSession(forTopic topic: String) -> WCSession?
func getAll() -> [WCSession]
func delete(topic: String)
Expand Down Expand Up @@ -29,6 +31,13 @@ final class SessionStorage: WCSessionStorage {
storage.setSequence(session)
}

@discardableResult
func setSessionIfNewer(_ session: WCSession) -> Bool {
guard isNeedToReplace(session) else { return false }
storage.setSequence(session)
return true
}

func getSession(forTopic topic: String) -> WCSession? {
return try? storage.getSequence(forTopic: topic)
}
Expand All @@ -45,3 +54,13 @@ final class SessionStorage: WCSessionStorage {
storage.deleteAll()
}
}

// MARK: Privates

private extension SessionStorage {

func isNeedToReplace(_ session: WCSession) -> Bool {
guard let old = getSession(forTopic: session.topic) else { return true }
return session.timestamp > old.timestamp
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import Foundation
import WalletConnectUtils

struct WCRequestSubscriptionPayload: Codable {
let topic: String
let wcRequest: WCRequest

var timestamp: Date {
return JsonRpcID.timestamp(from: wcRequest.id)
}
}
2 changes: 1 addition & 1 deletion Sources/WalletConnectSign/Types/Pairing/WCPairing.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation
import WalletConnectKMS

struct WCPairing: ExpirableSequence {
struct WCPairing: SequenceObject {
let topic: String
let relay: RelayProtocolOptions
var peerMetadata: AppMetadata?
Expand Down
Loading

0 comments on commit d61a9d8

Please sign in to comment.