Skip to content

Commit

Permalink
Merge pull request #1041 from WalletConnect/develop
Browse files Browse the repository at this point in the history
1.6.18
  • Loading branch information
llbartekll authored Aug 17, 2023
2 parents 5199a4d + d65f55b commit 10efd24
Show file tree
Hide file tree
Showing 42 changed files with 750 additions and 246 deletions.
5 changes: 3 additions & 2 deletions Example/DApp/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {

WalletConnectModal.configure(
projectId: InputConfig.projectId,
metadata: metadata
metadata: metadata,
accentColor: .green
)

setupWindow(scene: scene)
}

Expand Down
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 = 52;
objectVersion = 54;
objects = {

/* Begin PBXBuildFile section */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@
<TestPlanReference
reference = "container:../NotifyTests.xctestplan">
</TestPlanReference>
<TestPlanReference
reference = "container:../XPlatformProtocolTests.xctestplan">
</TestPlanReference>
</TestPlans>
</TestAction>
<LaunchAction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,16 @@ final class MainInteractor {
var pushRequestPublisher: AnyPublisher<(id: RPCID, account: Account, metadata: AppMetadata), Never> {
return Push.wallet.requestPublisher
}

var sessionProposalPublisher: AnyPublisher<(proposal: Session.Proposal, context: VerifyContext?), Never> {
return Web3Wallet.instance.sessionProposalPublisher
}

var sessionRequestPublisher: AnyPublisher<(request: Request, context: VerifyContext?), Never> {
return Web3Wallet.instance.sessionRequestPublisher
}

var requestPublisher: AnyPublisher<(request: AuthRequest, context: VerifyContext?), Never> {
return Web3Wallet.instance.authRequestPublisher
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ final class MainPresenter {

// MARK: - Private functions
extension MainPresenter {

private func setupInitialState() {
configurationService.configure(importAccount: importAccount)
pushRegisterer.registerForPushNotifications()
Expand All @@ -45,5 +44,25 @@ extension MainPresenter {
.sink { [unowned self] request in
router.present(pushRequest: request)
}.store(in: &disposeBag)

interactor.sessionProposalPublisher
.receive(on: DispatchQueue.main)
.sink { [unowned self] session in
router.present(proposal: session.proposal, importAccount: importAccount, context: session.context)
}
.store(in: &disposeBag)

interactor.sessionRequestPublisher
.receive(on: DispatchQueue.main)
.sink { [unowned self] request, context in
router.present(sessionRequest: request, importAccount: importAccount, sessionContext: context)
}.store(in: &disposeBag)

interactor.requestPublisher
.receive(on: DispatchQueue.main)
.sink { [unowned self] result in
router.present(request: result.request, importAccount: importAccount, context: result.context)
}
.store(in: &disposeBag)
}
}
15 changes: 15 additions & 0 deletions Example/WalletApp/PresentationLayer/Wallet/Main/MainRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,19 @@ final class MainRouter {
// PushRequestModule.create(app: app, pushRequest: pushRequest)
// .presentFullScreen(from: viewController, transparentBackground: true)
}

func present(proposal: Session.Proposal, importAccount: ImportAccount, context: VerifyContext?) {
SessionProposalModule.create(app: app, importAccount: importAccount, proposal: proposal, context: context)
.presentFullScreen(from: viewController, transparentBackground: true)
}

func present(sessionRequest: Request, importAccount: ImportAccount, sessionContext: VerifyContext?) {
SessionRequestModule.create(app: app, sessionRequest: sessionRequest, importAccount: importAccount, sessionContext: sessionContext)
.presentFullScreen(from: viewController, transparentBackground: true)
}

func present(request: AuthRequest, importAccount: ImportAccount, context: VerifyContext?) {
AuthRequestModule.create(app: app, request: request, importAccount: importAccount, context: context)
.presentFullScreen(from: viewController, transparentBackground: true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,6 @@ import Web3Wallet
import WalletConnectPush

final class WalletInteractor {
var sessionProposalPublisher: AnyPublisher<(proposal: Session.Proposal, context: VerifyContext?), Never> {
return Web3Wallet.instance.sessionProposalPublisher
}

var sessionRequestPublisher: AnyPublisher<(request: Request, context: VerifyContext?), Never> {
return Web3Wallet.instance.sessionRequestPublisher
}

var requestPublisher: AnyPublisher<(request: AuthRequest, context: VerifyContext?), Never> {
return Web3Wallet.instance.authRequestPublisher
}

var sessionsPublisher: AnyPublisher<[Session], Never> {
return Web3Wallet.instance.sessionsPublisher
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,29 +98,6 @@ final class WalletPresenter: ObservableObject {
// MARK: - Private functions
extension WalletPresenter {
private func setupInitialState() {
interactor.sessionProposalPublisher
.receive(on: DispatchQueue.main)
.sink { [unowned self] session in
showPairingLoading = false
router.present(proposal: session.proposal, importAccount: importAccount, context: session.context)
}
.store(in: &disposeBag)

interactor.sessionRequestPublisher
.receive(on: DispatchQueue.main)
.sink { [unowned self] request, context in
showPairingLoading = false
router.present(sessionRequest: request, importAccount: importAccount, sessionContext: context)
}.store(in: &disposeBag)

interactor.requestPublisher
.receive(on: DispatchQueue.main)
.sink { [unowned self] result in
showPairingLoading = false
router.present(request: result.request, importAccount: importAccount, context: result.context)
}
.store(in: &disposeBag)

interactor.sessionsPublisher
.receive(on: DispatchQueue.main)
.sink { [weak self] sessions in
Expand Down Expand Up @@ -158,10 +135,6 @@ extension WalletPresenter {

private func removePairingIndicator() {
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
if self.showPairingLoading {
self.errorMessage = "WalletConnect - Pairing timeout error"
self.showError.toggle()
}
self.showPairingLoading = false
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,10 @@ final class WalletRouter {
self.app = app
}

func present(proposal: Session.Proposal, importAccount: ImportAccount, context: VerifyContext?) {
SessionProposalModule.create(app: app, importAccount: importAccount, proposal: proposal, context: context)
.presentFullScreen(from: viewController, transparentBackground: true)
}

func present(sessionRequest: Request, importAccount: ImportAccount, sessionContext: VerifyContext?) {
SessionRequestModule.create(app: app, sessionRequest: sessionRequest, importAccount: importAccount, sessionContext: sessionContext)
.presentFullScreen(from: viewController, transparentBackground: true)
}

func present(request: AuthRequest, importAccount: ImportAccount, context: VerifyContext?) {
AuthRequestModule.create(app: app, request: request, importAccount: importAccount, context: context)
.presentFullScreen(from: viewController, transparentBackground: true)
}

func present(sessionProposal: Session.Proposal, importAccount: ImportAccount, sessionContext: VerifyContext?) {
SessionProposalModule.create(app: app, importAccount: importAccount, proposal: sessionProposal, context: sessionContext)
Expand Down
1 change: 1 addition & 0 deletions Sources/HTTPClient/HTTPClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ import Foundation
public protocol HTTPClient {
func request<T: Decodable>(_ type: T.Type, at service: HTTPService) async throws -> T
func request(service: HTTPService) async throws
func updateHost(host: String) async
}
19 changes: 18 additions & 1 deletion Sources/HTTPClient/HTTPError.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
import Foundation

enum HTTPError: Error {
public enum HTTPError: Error, Equatable {
case malformedURL(HTTPService)
case couldNotConnect
case dataTaskError(Error)
case noResponse
case badStatusCode(Int)
case responseDataNil
case jsonDecodeFailed(Error, Data)

public static func ==(lhs: HTTPError, rhs: HTTPError) -> Bool {
switch (lhs, rhs) {
case (.malformedURL, .malformedURL),
(.couldNotConnect, .couldNotConnect),
(.noResponse, .noResponse),
(.responseDataNil, .responseDataNil),
(.dataTaskError, .dataTaskError),
(.badStatusCode, .badStatusCode),
(.jsonDecodeFailed, .jsonDecodeFailed):
return true

default:
return false
}
}
}
9 changes: 8 additions & 1 deletion Sources/HTTPClient/HTTPNetworkClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Foundation

public actor HTTPNetworkClient: HTTPClient {

let host: String
private var host: String

private let session: URLSession

Expand Down Expand Up @@ -31,6 +31,10 @@ public actor HTTPNetworkClient: HTTPClient {
}
}
}

public func updateHost(host: String) async {
self.host = host
}

private func request<T: Decodable>(_ type: T.Type, at service: HTTPService, completion: @escaping (Result<T, Error>) -> Void) {
guard let request = service.resolve(for: host) else {
Expand Down Expand Up @@ -67,6 +71,9 @@ public actor HTTPNetworkClient: HTTPClient {
}

private static func validate(_ urlResponse: URLResponse?, _ error: Error?) throws {
if let error = (error as? NSError), error.code == -1004 {
throw HTTPError.couldNotConnect
}
if let error = error {
throw HTTPError.dataTaskError(error)
}
Expand Down
19 changes: 12 additions & 7 deletions Sources/WalletConnectEcho/EchoClientFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,19 @@ public struct EchoClientFactory {
environment: environment)
}

public static func create(projectId: String,
echoHost: String,
keychainStorage: KeychainStorageProtocol,
environment: APNSEnvironment) -> EchoClient {

public static func create(
projectId: String,
echoHost: String,
keychainStorage: KeychainStorageProtocol,
environment: APNSEnvironment
) -> EchoClient {
let sessionConfiguration = URLSessionConfiguration.default
sessionConfiguration.timeoutIntervalForRequest = 5.0
sessionConfiguration.timeoutIntervalForResource = 5.0
let session = URLSession(configuration: sessionConfiguration)

let logger = ConsoleLogger(suffix: "👂🏻", loggingLevel: .debug)

let httpClient = HTTPNetworkClient(host: echoHost)
let httpClient = HTTPNetworkClient(host: echoHost, session: session)

let clientIdStorage = ClientIdStorage(keychain: keychainStorage)

Expand Down
57 changes: 42 additions & 15 deletions Sources/WalletConnectEcho/Register/EchoRegisterService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ actor EchoRegisterService {
private let environment: APNSEnvironment
private let echoAuthenticator: EchoAuthenticating
private let clientIdStorage: ClientIdStoring

/// The property is used to determine whether echo.walletconnect.org will be used
/// in case echo.walletconnect.com doesn't respond for some reason (most likely due to being blocked in the user's location).
private var fallback = false

enum Errors: Error {
case registrationFailed
}
Expand All @@ -33,29 +36,53 @@ actor EchoRegisterService {
let clientId = try clientIdStorage.getClientId()
let clientIdMutlibase = try DIDKey(did: clientId).multibase(variant: .ED25519)
logger.debug("APNS device token: \(token)")
let response = try await httpClient.request(
EchoResponse.self,
at: EchoAPI.register(clientId: clientIdMutlibase, token: token, projectId: projectId, environment: environment, auth: echoAuthToken)
)
guard response.status == .success else {
throw Errors.registrationFailed

do {
let response = try await httpClient.request(
EchoResponse.self,
at: EchoAPI.register(clientId: clientIdMutlibase, token: token, projectId: projectId, environment: environment, auth: echoAuthToken)
)
guard response.status == .success else {
throw Errors.registrationFailed
}
logger.debug("Successfully registered at Echo Server")
} catch {
if (error as? HTTPError) == .couldNotConnect && !fallback {
fallback = true
await echoHostFallback()
try await register(deviceToken: deviceToken)
}
throw error
}
logger.debug("Successfully registered at Echo Server")
}

func echoHostFallback() async {
await httpClient.updateHost(host: "echo.walletconnect.org")
}

#if DEBUG
public func register(deviceToken: String) async throws {
let echoAuthToken = try echoAuthenticator.createAuthToken()
let clientId = try clientIdStorage.getClientId()
let clientIdMutlibase = try DIDKey(did: clientId).multibase(variant: .ED25519)
let response = try await httpClient.request(
EchoResponse.self,
at: EchoAPI.register(clientId: clientIdMutlibase, token: deviceToken, projectId: projectId, environment: environment, auth: echoAuthToken)
)
guard response.status == .success else {
throw Errors.registrationFailed

do {
let response = try await httpClient.request(
EchoResponse.self,
at: EchoAPI.register(clientId: clientIdMutlibase, token: deviceToken, projectId: projectId, environment: environment, auth: echoAuthToken)
)
guard response.status == .success else {
throw Errors.registrationFailed
}
logger.debug("Successfully registered at Echo Server")
} catch {
if (error as? HTTPError) == .couldNotConnect && !fallback {
fallback = true
await echoHostFallback()
try await register(deviceToken: deviceToken)
}
throw error
}
logger.debug("Successfully registered at Echo Server")
}
#endif
}
Expand Down
Loading

0 comments on commit 10efd24

Please sign in to comment.