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

[Auth] #472 extend pairing #477

Merged
merged 4 commits into from
Sep 1, 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
1 change: 0 additions & 1 deletion Example/DApp/Auth/AuthView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,3 @@ struct CircleButtonStyle: ButtonStyle {
.cornerRadius(8.0)
}
}

4 changes: 2 additions & 2 deletions Example/DApp/Auth/AuthViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ final class AuthViewModel: ObservableObject {
}

func walletDidPressed() {

}

func deeplinkPressed() {
Expand All @@ -47,7 +47,7 @@ final class AuthViewModel: ObservableObject {
private extension AuthViewModel {

func setupSubscriptions() {
Auth.instance.authResponsePublisher.sink { [weak self] (id, result) in
Auth.instance.authResponsePublisher.sink { [weak self] (_, result) in
switch result {
case .success(let cacao):
self?.state = .signed(cacao)
Expand Down
2 changes: 1 addition & 1 deletion Example/DApp/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
private let authCoordinator = AuthCoordinator()

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
Relay.configure(projectId: "8ba9ee138960775e5231b70cc5ef1c3a",socketFactory: SocketFactory())
Relay.configure(projectId: "8ba9ee138960775e5231b70cc5ef1c3a", socketFactory: SocketFactory())

setupWindow(scene: scene)
}
Expand Down
6 changes: 3 additions & 3 deletions Example/IntegrationTests/Auth/AuthTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ final class AuthTests: XCTestCase {
}
}
.store(in: &publishers)
app.authResponsePublisher.sink { (id, result) in
app.authResponsePublisher.sink { (_, result) in
guard case .success = result else { XCTFail(); return }
responseExpectation.fulfill()
}
Expand All @@ -90,7 +90,7 @@ final class AuthTests: XCTestCase {
}
}
.store(in: &publishers)
app.authResponsePublisher.sink { (id, result) in
app.authResponsePublisher.sink { (_, result) in
guard case .failure(let error) = result else { XCTFail(); return }
XCTAssertEqual(error, .userRejeted)
responseExpectation.fulfill()
Expand All @@ -111,7 +111,7 @@ final class AuthTests: XCTestCase {
}
}
.store(in: &publishers)
app.authResponsePublisher.sink { (id, result) in
app.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 @@ -12,7 +12,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
MigrationConfigurator(app: app),
ThirdPartyConfigurator(),
ApplicationConfigurator(app: app),
AppearanceConfigurator(),
AppearanceConfigurator()
]
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
import SwiftUI

struct ScanQR: UIViewRepresentable {

class Coordinator: ScanQRViewDelegate {
private let onValue: (String) -> Void
private let onError: (Error) -> Void

init(onValue: @escaping (String) -> Void, onError: @escaping (Error) -> Void) {
self.onValue = onValue
self.onError = onError
}

func scanDidDetect(value: String) {
onValue(value)
}

func scanDidFail(with error: Error) {
onError(error)
}
}

let onValue: (String) -> Void
let onError: (Error) -> Void

func makeUIView(context: Context) -> ScanQRView {
let view = ScanQRView()
view.delegate = context.coordinator
return view
}

func updateUIView(_ uiView: ScanQRView, context: Context) {

}

func makeCoordinator() -> Coordinator {
return Coordinator(onValue: onValue, onError: onError)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ final class ScanQRView: UIView {
enum Errors: Error {
case deviceNotFound
}

weak var delegate: ScanQRViewDelegate?

private let targetSize = CGSize(
width: UIScreen.main.bounds.width - 32.0,
height: UIScreen.main.bounds.width - 32.0
)

private var videoPreviewLayer: AVCaptureVideoPreviewLayer?
private var captureSession: AVCaptureSession?

private lazy var borderView: UIView = {
let borderView = ScanTargetView(radius: 24.0, color: .white, strokeWidth: 2.0, length: 36.0)
borderView.alpha = 0.85
Expand All @@ -34,21 +34,21 @@ final class ScanQRView: UIView {
bluredView.layer.mask = createMaskLayer()
return bluredView
}()

override init(frame: CGRect) {
super.init(frame: frame)

setupView()
startCaptureSession()
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func layoutSubviews() {
super.layoutSubviews()

updateFrames()
updateOrientation()
}
Expand All @@ -61,7 +61,7 @@ final class ScanQRView: UIView {
// MARK: AVCaptureMetadataOutputObjectsDelegate

extension ScanQRView: AVCaptureMetadataOutputObjectsDelegate {

func metadataOutput(_ metadataOutput: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
guard
let metadataObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject,
Expand All @@ -76,14 +76,14 @@ extension ScanQRView: AVCaptureMetadataOutputObjectsDelegate {
// MARK: Privates

private extension ScanQRView {

private func setupView() {
backgroundColor = .black

addSubview(bluredView)
addSubview(borderView)
}

private func createMaskLayer() -> CAShapeLayer {
let maskPath = UIBezierPath(rect: bounds)
let rect = UIBezierPath(
Expand All @@ -98,76 +98,76 @@ private extension ScanQRView {
)
maskPath.append(rect)
maskPath.usesEvenOddFillRule = true

let maskLayer = CAShapeLayer()
maskLayer.path = maskPath.cgPath
maskLayer.fillRule = .evenOdd
return maskLayer
}

private func startCaptureSession() {
DispatchQueue.global().async { [weak self] in
guard let self = self else { return }

do {
let session = try self.createCaptureSession()
session.startRunning()
self.captureSession = session

DispatchQueue.main.async { self.setupVideoPreviewLayer(with: session) }
} catch {
DispatchQueue.main.async { self.delegate?.scanDidFail(with: error) }
}
}
}

private func createCaptureSession() throws -> AVCaptureSession {
guard let captureDevice = AVCaptureDevice.default(for: .video) else {
throw Errors.deviceNotFound
}

let input = try AVCaptureDeviceInput(device: captureDevice)

let session = AVCaptureSession()
session.addInput(input)

let captureMetadataOutput = AVCaptureMetadataOutput()
captureMetadataOutput.setMetadataObjectsDelegate(self, queue: .main)
session.addOutput(captureMetadataOutput)

captureMetadataOutput.metadataObjectTypes = [.qr]

return session
}

private func stopCaptureSession() {
captureSession?.stopRunning()
captureSession = nil
}

private func setupVideoPreviewLayer(with session: AVCaptureSession) {
let previewLayer = AVCaptureVideoPreviewLayer(session: session)
previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
previewLayer.frame = layer.bounds
videoPreviewLayer = previewLayer

layer.insertSublayer(previewLayer, at: 0)
}

private func updateFrames() {
borderView.frame.size = targetSize
borderView.center = center
bluredView.frame = bounds
bluredView.layer.mask = createMaskLayer()
videoPreviewLayer?.frame = layer.bounds
}

private func updateOrientation() {
guard let connection = videoPreviewLayer?.connection else {
return
}
let previewLayerConnection: AVCaptureConnection = connection

guard previewLayerConnection.isVideoOrientationSupported else {
return
}
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ let package = Package(
dependencies: ["WalletConnectKMS", "WalletConnectUtils", "TestingUtils"]),
.target(
name: "TestingUtils",
dependencies: ["WalletConnectUtils", "WalletConnectKMS", "JSONRPC"],
dependencies: ["WalletConnectUtils", "WalletConnectKMS", "JSONRPC", "WalletConnectPairing"],
path: "Tests/TestingUtils"),
.testTarget(
name: "WalletConnectUtilsTests",
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 {
account: config.account,
relayClient: Relay.instance)
}()

private static var config: Config?

private init() { }
Expand Down
2 changes: 0 additions & 2 deletions Sources/Auth/AuthClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import WalletConnectUtils
import WalletConnectPairing
import WalletConnectRelay


/// WalletConnect Auth Client
///
/// Cannot be instantiated outside of the SDK
Expand Down Expand Up @@ -41,7 +40,6 @@ public class AuthClient {
/// An object that loggs SDK's errors and info messages
public let logger: ConsoleLogging


// MARK: - Private Properties

private var authResponsePublisherSubject = PassthroughSubject<(id: RPCID, result: Result<Cacao, AuthError>), Never>()
Expand Down
2 changes: 1 addition & 1 deletion Sources/Auth/AuthClientFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public struct AuthClientFactory {
let appPairService = AppPairService(networkingInteractor: networkingInteractor, kms: kms, pairingStorage: pairingStore)
let appRequestService = AppRequestService(networkingInteractor: networkingInteractor, kms: kms, appMetadata: metadata, logger: logger)
let messageSigner = MessageSigner(signer: Signer())
let appRespondSubscriber = AppRespondSubscriber(networkingInteractor: networkingInteractor, logger: logger, rpcHistory: history, signatureVerifier: messageSigner, messageFormatter: messageFormatter)
let appRespondSubscriber = AppRespondSubscriber(networkingInteractor: networkingInteractor, logger: logger, rpcHistory: history, signatureVerifier: messageSigner, messageFormatter: messageFormatter, pairingStorage: pairingStore)
let walletPairService = WalletPairService(networkingInteractor: networkingInteractor, kms: kms, pairingStorage: pairingStore)
let walletRequestSubscriber = WalletRequestSubscriber(networkingInteractor: networkingInteractor, logger: logger, kms: kms, messageFormatter: messageFormatter, address: account?.address)
let walletRespondService = WalletRespondService(networkingInteractor: networkingInteractor, logger: logger, kms: kms, rpcHistory: history)
Expand Down
18 changes: 17 additions & 1 deletion Sources/Auth/Services/App/AppRespondSubscriber.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import Combine
import Foundation
import WalletConnectUtils
import JSONRPC
import WalletConnectPairing

class AppRespondSubscriber {
private let networkingInteractor: NetworkInteracting
private let pairingStorage: WCPairingStorage
private let logger: ConsoleLogging
private let rpcHistory: RPCHistory
private let signatureVerifier: MessageSignatureVerifying
Expand All @@ -17,12 +19,14 @@ class AppRespondSubscriber {
logger: ConsoleLogging,
rpcHistory: RPCHistory,
signatureVerifier: MessageSignatureVerifying,
messageFormatter: SIWEMessageFormatting) {
messageFormatter: SIWEMessageFormatting,
pairingStorage: WCPairingStorage) {
self.networkingInteractor = networkingInteractor
self.logger = logger
self.rpcHistory = rpcHistory
self.signatureVerifier = signatureVerifier
self.messageFormatter = messageFormatter
self.pairingStorage = pairingStorage
subscribeForResponse()
}

Expand All @@ -35,6 +39,7 @@ class AppRespondSubscriber {
let requestParams = request.params, request.method == "wc_authRequest"
else { return }

activatePairingIfNeeded(id: requestId)
networkingInteractor.unsubscribe(topic: subscriptionPayload.topic)

if let errorResponse = response.error,
Expand Down Expand Up @@ -62,4 +67,15 @@ class AppRespondSubscriber {

}.store(in: &publishers)
}

private func activatePairingIfNeeded(id: RPCID) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throws?

guard let record = rpcHistory.get(recordId: id) else { return }
let pairingTopic = record.topic
guard var pairing = pairingStorage.getPairing(forTopic: pairingTopic) else { return }
if !pairing.active {
pairing.activate()
} else {
try? pairing.updateExpiry()
}
}
}
2 changes: 1 addition & 1 deletion Sources/Auth/Services/Common/NetworkingInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ protocol NetworkInteracting {
func subscribe(topic: String) async throws
func unsubscribe(topic: String)
func request(_ request: RPCRequest, topic: String, tag: Int, envelopeType: Envelope.EnvelopeType) async throws
func requestNetworkAck(_ request: RPCRequest, topic: String, tag: Int) async throws
func requestNetworkAck(_ request: RPCRequest, topic: String, tag: Int) async throws
func respond(topic: String, response: RPCResponse, tag: Int, envelopeType: Envelope.EnvelopeType) async throws
func respondError(topic: String, requestId: RPCID, tag: Int, reason: Reason, envelopeType: Envelope.EnvelopeType) async throws
}
Expand Down
1 change: 0 additions & 1 deletion Sources/Auth/Types/Errors/Reason.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ protocol Reason {
var code: Int { get }
var message: String { get }
}

1 change: 0 additions & 1 deletion Sources/WalletConnectSign/Sign/SignClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,6 @@ public final class SignClient {
return WalletConnectUtils.JsonRpcRecord(id: record.id, topic: record.topic, request: request, response: record.response, chainId: record.chainId)
}


#if DEBUG
/// Delete all stored data such as: pairings, sessions, keys
///
Expand Down
Loading