Skip to content

Commit

Permalink
Merge pull request #531 from WalletConnect/#526-remove-pairing-method…
Browse files Browse the repository at this point in the history
…s-from-auth

#526 remove pairing methods from auth
  • Loading branch information
llbartekll authored Sep 30, 2022
2 parents fad593b + 8bd029d commit d7a458c
Show file tree
Hide file tree
Showing 14 changed files with 74 additions and 86 deletions.
4 changes: 3 additions & 1 deletion Example/DApp/Auth/AuthViewModel.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import UIKit
import Combine
import Auth
import WalletConnectPairing

final class AuthViewModel: ObservableObject {

Expand All @@ -27,7 +28,8 @@ final class AuthViewModel: ObservableObject {
func setupInitialState() async throws {
state = .none
uri = nil
uri = try await Auth.instance.request(.stub()).absoluteString
let uri = try! await Pair.instance.create()
try await Auth.instance.request(.stub(), topic: uri.topic)
}

func copyDidPressed() {
Expand Down
3 changes: 2 additions & 1 deletion Example/DApp/Sign/SignCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import UIKit
import Combine
import WalletConnectSign
import WalletConnectRelay
import WalletConnectPairing

final class SignCoordinator {

Expand All @@ -25,7 +26,7 @@ final class SignCoordinator {
url: "wallet.connect",
icons: ["https://avatars.githubusercontent.com/u/37784886"])

Sign.configure(metadata: metadata)
Pair.configure(metadata: metadata)
#if DEBUG
if CommandLine.arguments.contains("-cleanInstall") {
try? Sign.instance.cleanup()
Expand Down
64 changes: 39 additions & 25 deletions Example/IntegrationTests/Auth/AuthTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,22 @@ import Combine
import WalletConnectPairing

final class AuthTests: XCTestCase {
var app: AuthClient!
var wallet: AuthClient!
var appPairingClient: PairingClient!
var walletPairingClient: PairingClient!

var appAuthClient: AuthClient!
var walletAuthClient: AuthClient!
let prvKey = Data(hex: "462c1dad6832d7d96ccf87bd6a686a4110e114aaaebd5512e552c0e3a87b480f")
private var publishers = [AnyCancellable]()

override func setUp() {
app = makeClient(prefix: "👻 App")
let walletAccount = Account(chainIdentifier: "eip155:1", address: "0x724d0D2DaD3fbB0C168f947B87Fa5DBe36F1A8bf")!
wallet = makeClient(prefix: "🤑 Wallet", account: walletAccount)

(appPairingClient, appAuthClient) = makeClients(prefix: "🤖 App")
(walletPairingClient, walletAuthClient) = makeClients(prefix: "🐶 Wallet", account: walletAccount)
}

func makeClient(prefix: String, account: Account? = nil) -> AuthClient {
func makeClients(prefix: String, account: Account? = nil) -> (PairingClient, AuthClient) {
let logger = ConsoleLogger(suffix: prefix, loggingLevel: .debug)
let keychain = KeychainStorageMock()
let relayClient = RelayClient(relayHost: InputConfig.relayHost, projectId: InputConfig.projectId, keychainStorage: keychain, socketFactory: SocketFactory(), logger: logger)
Expand All @@ -31,38 +35,44 @@ final class AuthTests: XCTestCase {
keychainStorage: keychain,
relayClient: relayClient)

return AuthClientFactory.create(
let authClient = AuthClientFactory.create(
metadata: AppMetadata(name: name, description: "", url: "", icons: [""]),
account: account,
logger: logger,
keyValueStorage: keyValueStorage,
keychainStorage: keychain,
relayClient: relayClient,
pairingClient: pairingClient)
pairingRegisterer: pairingClient)

return (pairingClient, authClient)
}

func testRequest() async {
let requestExpectation = expectation(description: "request delivered to wallet")
let uri = try! await app.request(RequestParams.stub())
try! await wallet.pair(uri: uri)
wallet.authRequestPublisher.sink { _ in
let uri = try! await appPairingClient.create()
try! await appAuthClient.request(RequestParams.stub(), topic: uri.topic)

try! await walletPairingClient.pair(uri: uri)
walletAuthClient.authRequestPublisher.sink { _ in
requestExpectation.fulfill()
}.store(in: &publishers)
wait(for: [requestExpectation], timeout: InputConfig.defaultTimeout)
}

func testRespondSuccess() async {
let responseExpectation = expectation(description: "successful response delivered")
let uri = try! await app.request(RequestParams.stub())
try! await wallet.pair(uri: uri)
wallet.authRequestPublisher.sink { [unowned self] request in
let uri = try! await appPairingClient.create()
try! await appAuthClient.request(RequestParams.stub(), topic: uri.topic)

try! await walletPairingClient.pair(uri: uri)
walletAuthClient.authRequestPublisher.sink { [unowned self] request in
Task(priority: .high) {
let signature = try! MessageSigner().sign(message: request.message, privateKey: prvKey)
try! await wallet.respond(requestId: request.id, signature: signature)
try! await walletAuthClient.respond(requestId: request.id, signature: signature)
}
}
.store(in: &publishers)
app.authResponsePublisher.sink { (_, result) in
appAuthClient.authResponsePublisher.sink { (_, result) in
guard case .success = result else { XCTFail(); return }
responseExpectation.fulfill()
}
Expand All @@ -72,15 +82,17 @@ final class AuthTests: XCTestCase {

func testUserRespondError() async {
let responseExpectation = expectation(description: "error response delivered")
let uri = try! await app.request(RequestParams.stub())
try! await wallet.pair(uri: uri)
wallet.authRequestPublisher.sink { [unowned self] request in
let uri = try! await appPairingClient.create()
try! await appAuthClient.request(RequestParams.stub(), topic: uri.topic)

try! await walletPairingClient.pair(uri: uri)
walletAuthClient.authRequestPublisher.sink { [unowned self] request in
Task(priority: .high) {
try! await wallet.reject(requestId: request.id)
try! await walletAuthClient.reject(requestId: request.id)
}
}
.store(in: &publishers)
app.authResponsePublisher.sink { (_, result) in
appAuthClient.authResponsePublisher.sink { (_, result) in
guard case .failure(let error) = result else { XCTFail(); return }
XCTAssertEqual(error, .userRejeted)
responseExpectation.fulfill()
Expand All @@ -91,17 +103,19 @@ final class AuthTests: XCTestCase {

func testRespondSignatureVerificationFailed() async {
let responseExpectation = expectation(description: "invalid signature response delivered")
let uri = try! await app.request(RequestParams.stub())
try! await wallet.pair(uri: uri)
wallet.authRequestPublisher.sink { [unowned self] request in
let uri = try! await appPairingClient.create()
try! await appAuthClient.request(RequestParams.stub(), topic: uri.topic)

try! await walletPairingClient.pair(uri: uri)
walletAuthClient.authRequestPublisher.sink { [unowned self] request in
Task(priority: .high) {
let invalidSignature = "438effc459956b57fcd9f3dac6c675f9cee88abf21acab7305e8e32aa0303a883b06dcbd956279a7a2ca21ffa882ff55cc22e8ab8ec0f3fe90ab45f306938cfa1b"
let cacaoSignature = CacaoSignature(t: "eip191", s: invalidSignature)
try! await wallet.respond(requestId: request.id, signature: cacaoSignature)
try! await walletAuthClient.respond(requestId: request.id, signature: cacaoSignature)
}
}
.store(in: &publishers)
app.authResponsePublisher.sink { (_, result) in
appAuthClient.authResponsePublisher.sink { (_, result) in
guard case .failure(let error) = result else { XCTFail(); return }
XCTAssertEqual(error, .signatureVerificationFailed)
responseExpectation.fulfill()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ struct ThirdPartyConfigurator: Configurator {

func configure() {
Relay.configure(projectId: InputConfig.projectId, socketFactory: SocketFactory())

Auth.configure(
Pair.configure(
metadata: AppMetadata(
name: "Showcase App",
description: "Showcase description",
url: "example.wallet",
icons: ["https://avatars.githubusercontent.com/u/37784886"]
),
))

Auth.configure(
account: Account("eip155:1:0xe5EeF1368781911d265fDB6946613dA61915a501")!
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import UIKit
import Auth
import WalletConnectPairing

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

Expand Down Expand Up @@ -30,7 +31,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {

let uri = context.url.absoluteString.replacingOccurrences(of: "showcase://wc?uri=", with: "")
Task {
try await Auth.instance.pair(uri: WalletConnectURI(string: uri)!)
try await Pair.instance.pair(uri: WalletConnectURI(string: uri)!)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import Combine
import Auth
import WalletConnectPairing

final class WalletInteractor {

func pair(uri: WalletConnectURI) async throws {
try await Auth.instance.pair(uri: uri)
try await Pair.instance.pair(uri: uri)
}

var requestPublisher: AnyPublisher<AuthRequest, Never> {
Expand Down
2 changes: 1 addition & 1 deletion Sources/Auth/Auth.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class Auth {
metadata: config.metadata,
account: config.account,
relayClient: Relay.instance,
pairingClient: Pair.instance)
pairingRegisterer: Pair.instance)
}()

private static var config: Config?
Expand Down
48 changes: 4 additions & 44 deletions Sources/Auth/AuthClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ public class AuthClient {
authResponsePublisherSubject.eraseToAnyPublisher()
}



/// Publisher that sends web socket connection status
public let socketConnectionStatusPublisher: AnyPublisher<SocketConnectionStatus, Never>

Expand All @@ -42,7 +40,7 @@ public class AuthClient {

// MARK: - Private Properties

private let pairingClient: PairingClient
private let pairingRegisterer: PairingRegisterer

private var authResponsePublisherSubject = PassthroughSubject<(id: RPCID, result: Result<Cacao, AuthError>), Never>()
private var authRequestPublisherSubject = PassthroughSubject<AuthRequest, Never>()
Expand All @@ -61,7 +59,7 @@ public class AuthClient {
pendingRequestsProvider: PendingRequestsProvider,
logger: ConsoleLogging,
socketConnectionStatusPublisher: AnyPublisher<SocketConnectionStatus, Never>,
pairingClient: PairingClient
pairingRegisterer: PairingRegisterer
) {
self.appRequestService = appRequestService
self.walletRequestSubscriber = walletRequestSubscriber
Expand All @@ -71,39 +69,16 @@ public class AuthClient {
self.pendingRequestsProvider = pendingRequestsProvider
self.logger = logger
self.socketConnectionStatusPublisher = socketConnectionStatusPublisher
self.pairingClient = pairingClient
self.pairingRegisterer = pairingRegisterer
setUpPublishers()
}

/// For wallet to establish a pairing and receive an authentication request
/// Wallet should call this function in order to accept peer's pairing proposal and be able to subscribe for future authentication request.
/// - Parameter uri: Pairing URI that is commonly presented as a QR code by a dapp or delivered with universal linking.
///
/// Throws Error:
/// - When URI is invalid format or missing params
/// - When topic is already in use
@available(*, deprecated, message: "Use Pair.pair(uri:) instead")
public func pair(uri: WalletConnectURI) async throws {
try await pairingClient.pair(uri: uri)
}

/// For a dapp to send an authentication request to a wallet
/// - Parameter params: Set of parameters required to request authentication
///
/// - Returns: Pairing URI that should be shared with wallet out of bound. Common way is to present it as a QR code.
public func request(_ params: RequestParams) async throws -> WalletConnectURI {
logger.debug("Requesting Authentication")
let uri = try await pairingClient.create()
try await appRequestService.request(params: params, topic: uri.topic)
return uri
}

/// For a dapp to send an authentication request to a wallet
/// - Parameter params: Set of parameters required to request authentication
/// - Parameter topic: Pairing topic that wallet already subscribes for
public func request(_ params: RequestParams, topic: String) async throws {
logger.debug("Requesting Authentication on existing pairing")
try pairingClient.getPairing(for: topic)
try pairingRegisterer.validatePairingExistance(topic)
try await appRequestService.request(params: params, topic: topic)
}

Expand All @@ -122,21 +97,6 @@ public class AuthClient {
try await walletRespondService.respondError(requestId: requestId)
}

@available(*, deprecated, message: "Use Pair.disconnect(topic:) instead")
public func disconnect(topic: String) async throws {
try await pairingClient.disconnect(topic: topic)
}

@available(*, deprecated, message: "Use Pair.ping(topic:) instead")
public func ping(topic: String) async throws {
try await pairingClient.ping(topic: topic)
}

@available(*, deprecated, message: "Use Pair.getPairings() instead")
public func getPairings() -> [Pairing] {
pairingClient.getPairings()
}

/// Query pending authentication requests
/// - Returns: Pending authentication requests
public func getPendingRequests() throws -> [AuthRequest] {
Expand Down
10 changes: 5 additions & 5 deletions Sources/Auth/AuthClientFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import WalletConnectNetworking

public struct AuthClientFactory {

public static func create(metadata: AppMetadata, account: Account?, relayClient: RelayClient, pairingClient: PairingClient) -> AuthClient {
public static func create(metadata: AppMetadata, account: Account?, relayClient: RelayClient, pairingRegisterer: PairingRegisterer) -> AuthClient {
let logger = ConsoleLogger(loggingLevel: .off)
let keyValueStorage = UserDefaults.standard
let keychainStorage = KeychainStorage(serviceIdentifier: "com.walletconnect.sdk")
return AuthClientFactory.create(metadata: metadata, account: account, logger: logger, keyValueStorage: keyValueStorage, keychainStorage: keychainStorage, relayClient: relayClient, pairingClient: pairingClient)
return AuthClientFactory.create(metadata: metadata, account: account, logger: logger, keyValueStorage: keyValueStorage, keychainStorage: keychainStorage, relayClient: relayClient, pairingRegisterer: pairingRegisterer)
}

static func create(metadata: AppMetadata, account: Account?, logger: ConsoleLogging, keyValueStorage: KeyValueStorage, keychainStorage: KeychainStorageProtocol, relayClient: RelayClient, pairingClient: PairingClient) -> AuthClient {
static func create(metadata: AppMetadata, account: Account?, logger: ConsoleLogging, keyValueStorage: KeyValueStorage, keychainStorage: KeychainStorageProtocol, relayClient: RelayClient, pairingRegisterer: PairingRegisterer) -> AuthClient {
let kms = KeyManagementService(keychain: keychainStorage)
let serializer = Serializer(kms: kms)
let history = RPCHistoryFactory.createForNetwork(keyValueStorage: keyValueStorage)
Expand All @@ -24,7 +24,7 @@ public struct AuthClientFactory {
let messageSigner = MessageSigner(signer: Signer())
let appRespondSubscriber = AppRespondSubscriber(networkingInteractor: networkingInteractor, logger: logger, rpcHistory: history, signatureVerifier: messageSigner, messageFormatter: messageFormatter)
let walletErrorResponder = WalletErrorResponder(networkingInteractor: networkingInteractor, logger: logger, kms: kms, rpcHistory: history)
let walletRequestSubscriber = WalletRequestSubscriber(networkingInteractor: networkingInteractor, logger: logger, kms: kms, messageFormatter: messageFormatter, address: account?.address, walletErrorResponder: walletErrorResponder, pairingRegisterer: pairingClient)
let walletRequestSubscriber = WalletRequestSubscriber(networkingInteractor: networkingInteractor, logger: logger, kms: kms, messageFormatter: messageFormatter, address: account?.address, walletErrorResponder: walletErrorResponder, pairingRegisterer: pairingRegisterer)
let walletRespondService = WalletRespondService(networkingInteractor: networkingInteractor, logger: logger, kms: kms, rpcHistory: history, walletErrorResponder: walletErrorResponder)
let pendingRequestsProvider = PendingRequestsProvider(rpcHistory: history)

Expand All @@ -36,6 +36,6 @@ public struct AuthClientFactory {
pendingRequestsProvider: pendingRequestsProvider,
logger: logger,
socketConnectionStatusPublisher: relayClient.socketConnectionStatusPublisher,
pairingClient: pairingClient)
pairingRegisterer: pairingRegisterer)
}
}
5 changes: 4 additions & 1 deletion Sources/WalletConnectPairing/PairingClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import Combine
import JSONRPC

public class PairingClient: PairingRegisterer {

public var pingResponsePublisher: AnyPublisher<(String), Never> {
pingResponsePublisherSubject.eraseToAnyPublisher()
}
Expand Down Expand Up @@ -101,6 +100,10 @@ public class PairingClient: PairingRegisterer {

}

public func validatePairingExistance(_ topic: String) throws {
_ = try pairingsProvider.getPairing(for: topic)
}

public func register<RequestParams>(method: ProtocolMethod) -> AnyPublisher<RequestSubscriptionPayload<RequestParams>, Never> {
logger.debug("Pairing Client - registering for \(method.method)")
return pairingRequestsSubscriber.subscribeForRequest(method)
Expand Down
1 change: 1 addition & 0 deletions Sources/WalletConnectPairing/PairingRegisterer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ import JSONRPC

public protocol PairingRegisterer {
func register<RequestParams>(method: ProtocolMethod) -> AnyPublisher<RequestSubscriptionPayload<RequestParams>, Never> where RequestParams : Codable
func validatePairingExistance(_ topic: String) throws
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

public class PairingsProvider {
class PairingsProvider {
enum Errors: Error {
case noPairingMatchingTopic
}
Expand All @@ -15,8 +15,7 @@ public class PairingsProvider {
.map {Pairing($0)}
}


public func getPairing(for topic: String) throws -> Pairing {
func getPairing(for topic: String) throws -> Pairing {
guard let pairing = pairingStorage.getPairing(forTopic: topic) else {
throw Errors.noPairingMatchingTopic
}
Expand Down
1 change: 1 addition & 0 deletions Sources/WalletConnectSign/Sign/Sign.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public class Sign {
/// - metadata: App metadata
@available(*, deprecated, message: "Use Pair.configure(metadata:) instead")
static public func configure(metadata: AppMetadata) {
Pair.configure(metadata: metadata)
Sign.metadata = metadata
}
}
Loading

0 comments on commit d7a458c

Please sign in to comment.