Skip to content

Commit

Permalink
Push: sync integration
Browse files Browse the repository at this point in the history
  • Loading branch information
flypaper0 committed Jun 29, 2023
1 parent 3d82139 commit 75bc40d
Show file tree
Hide file tree
Showing 28 changed files with 290 additions and 218 deletions.
2 changes: 1 addition & 1 deletion Example/ExampleApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objectVersion = 52;
objects = {

/* Begin PBXBuildFile section */
Expand Down
25 changes: 15 additions & 10 deletions Example/IntegrationTests/Pairing/PairingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import WalletConnectNetworking
import WalletConnectEcho
@testable import WalletConnectPush
@testable import WalletConnectPairing
@testable import WalletConnectSync

final class PairingTests: XCTestCase {

Expand All @@ -21,7 +22,7 @@ final class PairingTests: XCTestCase {

private var publishers = [AnyCancellable]()

func makeClientDependencies(prefix: String) -> (PairingClient, NetworkInteracting, KeychainStorageProtocol, KeyValueStorage) {
func makeClientDependencies(prefix: String) -> (PairingClient, NetworkInteracting, SyncClient, KeychainStorageProtocol, KeyValueStorage) {
let keychain = KeychainStorageMock()
let keyValueStorage = RuntimeKeyValueStorage()

Expand Down Expand Up @@ -49,27 +50,30 @@ final class PairingTests: XCTestCase {
keychainStorage: keychain,
networkingClient: networkingClient)

let syncClient = SyncClientFactory.create(networkInteractor: networkingClient, bip44: DefaultBIP44Provider(), keychain: keychain)

let clientId = try! networkingClient.getClientId()
networkingLogger.debug("My client id is: \(clientId)")

return (pairingClient, networkingClient, keychain, keyValueStorage)
return (pairingClient, networkingClient, syncClient, keychain, keyValueStorage)
}

func makeDappClients() {
let prefix = "🤖 Dapp: "
let (pairingClient, networkingInteractor, keychain, keyValueStorage) = makeClientDependencies(prefix: prefix)
let (pairingClient, networkingInteractor, syncClient, keychain, keyValueStorage) = makeClientDependencies(prefix: prefix)
let pushLogger = ConsoleLogger(suffix: prefix + " [Push]", loggingLevel: .debug)
appPairingClient = pairingClient
appPushClient = DappPushClientFactory.create(metadata: AppMetadata(name: name, description: "", url: "", icons: [""]),
logger: pushLogger,
keyValueStorage: keyValueStorage,
keychainStorage: keychain,
networkInteractor: networkingInteractor)
logger: pushLogger,
keyValueStorage: keyValueStorage,
keychainStorage: keychain,
networkInteractor: networkingInteractor,
syncClient: syncClient)
}

func makeWalletClients() {
let prefix = "🐶 Wallet: "
let (pairingClient, networkingInteractor, keychain, keyValueStorage) = makeClientDependencies(prefix: prefix)
let (pairingClient, networkingInteractor, syncClient, keychain, keyValueStorage) = makeClientDependencies(prefix: prefix)
let pushLogger = ConsoleLogger(suffix: prefix + " [Push]", loggingLevel: .debug)
walletPairingClient = pairingClient
let echoClient = EchoClientFactory.create(projectId: "",
Expand All @@ -84,12 +88,13 @@ final class PairingTests: XCTestCase {
groupKeychainStorage: KeychainStorageMock(),
networkInteractor: networkingInteractor,
pairingRegisterer: pairingClient,
echoClient: echoClient)
echoClient: echoClient,
syncClient: syncClient)
}

func makeWalletPairingClient() {
let prefix = "🐶 Wallet: "
let (pairingClient, _, _, _) = makeClientDependencies(prefix: prefix)
let (pairingClient, _, _, _, _) = makeClientDependencies(prefix: prefix)
walletPairingClient = pairingClient
}

Expand Down
45 changes: 32 additions & 13 deletions Example/IntegrationTests/Push/PushTests.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import Foundation
import XCTest
import WalletConnectUtils
import Web3
@testable import WalletConnectKMS
import WalletConnectRelay
import Combine
import WalletConnectNetworking
import WalletConnectEcho
@testable import WalletConnectPush
@testable import WalletConnectPairing
@testable import WalletConnectSync
import WalletConnectIdentity
import WalletConnectSigner

Expand All @@ -21,10 +23,19 @@ final class PushTests: XCTestCase {

var pairingStorage: PairingStorage!

let pk = try! EthereumPrivateKey()

var privateKey: Data {
return Data(pk.rawPrivateKey)
}

var account: Account {
return Account("eip155:1:" + pk.address.hex(eip55: true))!
}

private var publishers = [AnyCancellable]()

func makeClientDependencies(prefix: String) -> (PairingClient, NetworkInteracting, KeychainStorageProtocol, KeyValueStorage) {
func makeClientDependencies(prefix: String) -> (PairingClient, NetworkInteracting, SyncClient, KeychainStorageProtocol, KeyValueStorage) {
let keychain = KeychainStorageMock()
let keyValueStorage = RuntimeKeyValueStorage()

Expand Down Expand Up @@ -52,26 +63,29 @@ final class PushTests: XCTestCase {
keychainStorage: keychain,
networkingClient: networkingClient)

let syncClient = SyncClientFactory.create(networkInteractor: networkingClient, bip44: DefaultBIP44Provider(), keychain: keychain)

let clientId = try! networkingClient.getClientId()
networkingLogger.debug("My client id is: \(clientId)")
return (pairingClient, networkingClient, keychain, keyValueStorage)
return (pairingClient, networkingClient, syncClient, keychain, keyValueStorage)
}

func makeDappClients() {
let prefix = "🦄 Dapp: "
let (pairingClient, networkingInteractor, keychain, keyValueStorage) = makeClientDependencies(prefix: prefix)
let (pairingClient, networkingInteractor, syncClient, keychain, keyValueStorage) = makeClientDependencies(prefix: prefix)
let pushLogger = ConsoleLogger(suffix: prefix + " [Push]", loggingLevel: .debug)
dappPairingClient = pairingClient
dappPushClient = DappPushClientFactory.create(metadata: AppMetadata(name: "GM Dapp", description: "", url: "https://gm-dapp-xi.vercel.app/", icons: []),
logger: pushLogger,
keyValueStorage: keyValueStorage,
keychainStorage: keychain,
networkInteractor: networkingInteractor)
networkInteractor: networkingInteractor,
syncClient: syncClient)
}

func makeWalletClients() {
let prefix = "🦋 Wallet: "
let (pairingClient, networkingInteractor, keychain, keyValueStorage) = makeClientDependencies(prefix: prefix)
let (pairingClient, networkingInteractor, syncClient, keychain, keyValueStorage) = makeClientDependencies(prefix: prefix)
let pushLogger = ConsoleLogger(suffix: prefix + " [Push]", loggingLevel: .debug)
walletPairingClient = pairingClient
let echoClient = EchoClientFactory.create(projectId: "",
Expand All @@ -86,7 +100,8 @@ final class PushTests: XCTestCase {
groupKeychainStorage: KeychainStorageMock(),
networkInteractor: networkingInteractor,
pairingRegisterer: pairingClient,
echoClient: echoClient)
echoClient: echoClient,
syncClient: syncClient)
}

override func setUp() {
Expand All @@ -99,7 +114,8 @@ final class PushTests: XCTestCase {

let uri = try! await dappPairingClient.create()
try! await walletPairingClient.pair(uri: uri)
try! await dappPushClient.propose(account: Account.stub(), topic: uri.topic)
try! await walletPushClient.enableSync(account: account, onSign: sign)
try! await dappPushClient.propose(account: account, topic: uri.topic)

walletPushClient.requestPublisher.sink { [unowned self] (id, _, _) in
Task(priority: .high) { try! await walletPushClient.approve(id: id, onSign: sign) }
Expand All @@ -121,7 +137,7 @@ final class PushTests: XCTestCase {

let uri = try! await dappPairingClient.create()
try! await walletPairingClient.pair(uri: uri)
try! await dappPushClient.propose(account: Account.stub(), topic: uri.topic)
try! await dappPushClient.propose(account: account, topic: uri.topic)

walletPushClient.requestPublisher.sink { [unowned self] (id, _, _) in
Task(priority: .high) { try! await walletPushClient.reject(id: id) }
Expand All @@ -141,7 +157,8 @@ final class PushTests: XCTestCase {
func testWalletCreatesSubscription() async {
let expectation = expectation(description: "expects to create push subscription")
let metadata = AppMetadata(name: "GM Dapp", description: "", url: "https://gm-dapp-xi.vercel.app/", icons: [])
try! await walletPushClient.subscribe(metadata: metadata, account: Account.stub(), onSign: sign)
try! await walletPushClient.enableSync(account: account, onSign: sign)
try! await walletPushClient.subscribe(metadata: metadata, account: account, onSign: sign)
walletPushClient.subscriptionsPublisher
.first()
.sink { [unowned self] subscriptions in
Expand All @@ -156,7 +173,8 @@ final class PushTests: XCTestCase {
let expectation = expectation(description: "expects to delete push subscription")
let uri = try! await dappPairingClient.create()
try! await walletPairingClient.pair(uri: uri)
try! await dappPushClient.propose(account: Account.stub(), topic: uri.topic)
try! await walletPushClient.enableSync(account: account, onSign: sign)
try! await dappPushClient.propose(account: account, topic: uri.topic)
var subscriptionTopic: String!

walletPushClient.requestPublisher.sink { [unowned self] (id, _, _) in
Expand Down Expand Up @@ -184,7 +202,8 @@ final class PushTests: XCTestCase {
let expectation = expectation(description: "expects to create and update push subscription")
let metadata = AppMetadata(name: "GM Dapp", description: "", url: "https://gm-dapp-xi.vercel.app/", icons: [])
let updateScope: Set<String> = ["alerts"]
try! await walletPushClient.subscribe(metadata: metadata, account: Account.stub(), onSign: sign)
try! await walletPushClient.enableSync(account: account, onSign: sign)
try! await walletPushClient.subscribe(metadata: metadata, account: account, onSign: sign)
walletPushClient.subscriptionsPublisher
.first()
.sink { [unowned self] subscriptions in
Expand All @@ -211,7 +230,8 @@ final class PushTests: XCTestCase {
let pushMessage = PushMessage.stub()

let metadata = AppMetadata(name: "GM Dapp", description: "", url: "https://gm-dapp-xi.vercel.app/", icons: [])
try! await walletPushClient.subscribe(metadata: metadata, account: Account.stub(), onSign: sign)
try! await walletPushClient.enableSync(account: account, onSign: sign)
try! await walletPushClient.subscribe(metadata: metadata, account: account, onSign: sign)
var subscription: PushSubscription!
walletPushClient.subscriptionsPublisher
.first()
Expand All @@ -238,7 +258,6 @@ final class PushTests: XCTestCase {

private extension PushTests {
func sign(_ message: String) -> SigningResult {
let privateKey = Data(hex: "305c6cde3846927892cd32762f6120539f3ec74c9e3a16b9b798b1e85351ae2a")
let signer = MessageSignerFactory(signerFactory: DefaultSignerFactory()).create(projectId: InputConfig.projectId)
return .signed(try! signer.sign(message: message, privateKey: privateKey, type: .eip191))
}
Expand Down
15 changes: 6 additions & 9 deletions Example/WalletApp/ApplicationLayer/EthKeyStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,11 @@ class EthKeyStore {
}

private init() {
// TODO: For testing !!!
self.privateKey = try! EthereumPrivateKey(hexPrivateKey: "0x660bc2a94efbef506a499aef10066a914e2aaa1791362fd6d15a5b23a1078b44")

// if let privateKeyRaw = UserDefaults.standard.data(forKey: defaultsKey) {
// self.privateKey = try! EthereumPrivateKey(privateKeyRaw)
// } else {
// self.privateKey = try! EthereumPrivateKey()
// UserDefaults.standard.set(privateKeyRaw, forKey: defaultsKey)
// }
if let privateKeyRaw = UserDefaults.standard.data(forKey: defaultsKey) {
self.privateKey = try! EthereumPrivateKey(privateKeyRaw)
} else {
self.privateKey = try! EthereumPrivateKey()
UserDefaults.standard.set(privateKeyRaw, forKey: defaultsKey)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,27 @@ class DeletePushSubscriptionService {
private let networkingInteractor: NetworkInteracting
private let kms: KeyManagementServiceProtocol
private let logger: ConsoleLogging
private let pushSubscriptionStore: SyncStore<PushSubscription>
private let pushStorage: PushStorage
private let pushMessagesDatabase: PushMessagesDatabase?
init(networkingInteractor: NetworkInteracting,
kms: KeyManagementServiceProtocol,
logger: ConsoleLogging,
pushSubscriptionStore: SyncStore<PushSubscription>,
pushStorage: PushStorage,
pushMessagesDatabase: PushMessagesDatabase?) {
self.networkingInteractor = networkingInteractor
self.kms = kms
self.logger = logger
self.pushMessagesDatabase = pushMessagesDatabase
self.pushSubscriptionStore = pushSubscriptionStore
self.pushStorage = pushStorage
}

func delete(topic: String) async throws {
let params = PushDeleteParams.userDisconnected
logger.debug("Will delete push subscription for reason: message: \(params.message) code: \(params.code), topic: \(topic)")
guard let _ = pushSubscriptionStore.get(for: topic)
guard let _ = pushStorage.getSubscription(topic: topic)
else { throw Errors.pushSubscriptionNotFound}
let protocolMethod = PushDeleteProtocolMethod()
try await pushSubscriptionStore.delete(id: topic)
try await pushStorage.deleteSubscription(topic: topic)
pushMessagesDatabase?.deletePushMessages(topic: topic)
let request = RPCRequest(method: protocolMethod.method, params: params)
try await networkingInteractor.request(request, topic: topic, protocolMethod: protocolMethod)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,17 @@ class DeletePushSubscriptionSubscriber {
private let kms: KeyManagementServiceProtocol
private let logger: ConsoleLogging
private var publishers = [AnyCancellable]()
private let pushSubscriptionStore: SyncStore<PushSubscription>

private let deleteSubscriptionPublisherSubject = PassthroughSubject<String, Never>()

public var deleteSubscriptionPublisher: AnyPublisher<String, Never> {
deleteSubscriptionPublisherSubject.eraseToAnyPublisher()
}
private let pushStorage: PushStorage

init(networkingInteractor: NetworkInteracting,
kms: KeyManagementServiceProtocol,
logger: ConsoleLogging,
pushSubscriptionStore: SyncStore<PushSubscription>
pushStorage: PushStorage
) {
self.networkingInteractor = networkingInteractor
self.kms = kms
self.logger = logger
self.pushSubscriptionStore = pushSubscriptionStore
self.pushStorage = pushStorage
subscribeForDeleteSubscription()
}

Expand All @@ -34,10 +28,9 @@ class DeletePushSubscriptionSubscriber {
let topic = payload.topic
networkingInteractor.unsubscribe(topic: topic)
Task(priority: .high) {
try await pushSubscriptionStore.delete(id: topic)
try await pushStorage.deleteSubscription(topic: topic)
}
kms.deleteSymmetricKey(for: topic)
deleteSubscriptionPublisherSubject.send(payload.topic)
}.store(in: &publishers)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ final class PushResubscribeService {
private var publishers = Set<AnyCancellable>()

private let networkInteractor: NetworkInteracting
private let subscriptionsStorage: SyncStore<PushSubscription>
private let pushStorage: PushStorage

init(networkInteractor: NetworkInteracting, subscriptionsStorage: SyncStore<PushSubscription>) {
init(networkInteractor: NetworkInteracting, pushStorage: PushStorage) {
self.networkInteractor = networkInteractor
self.subscriptionsStorage = subscriptionsStorage
self.pushStorage = pushStorage
setUpResubscription()
}

func setUpResubscription() {
networkInteractor.socketConnectionStatusPublisher
.sink { [unowned self] status in
guard status == .connected else { return }
let topics = subscriptionsStorage.getAll().map{$0.topic}
let topics = pushStorage.getSubscriptions().map{$0.topic}
Task(priority: .high) {
try await networkInteractor.batchSubscribe(topics: topics)
}
Expand Down

This file was deleted.

Loading

0 comments on commit 75bc40d

Please sign in to comment.