Skip to content

Commit

Permalink
Merge pull request #412 from WalletConnect/develop
Browse files Browse the repository at this point in the history
v0.9.3-rc.0
  • Loading branch information
llbartekll authored Aug 8, 2022
2 parents 6c47071 + 575c9d5 commit 8dda02c
Show file tree
Hide file tree
Showing 27 changed files with 319 additions and 45 deletions.
3 changes: 2 additions & 1 deletion .github/actions/ci/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ runs:
-project Example/ExampleApp.xcodeproj \
-scheme WalletConnect \
-clonedSourcePackagesDirPath SourcePackages \
-sdk iphonesimulator"
-destination 'platform=iOS Simulator,name=iPhone 13' \
test"

# Integration tests
- name: Run integration tests
Expand Down
39 changes: 39 additions & 0 deletions Sources/Auth/Services/App/AuthRespondSubscriber.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import Combine
import Foundation
import WalletConnectUtils
import JSONRPC

class AuthRespondSubscriber {
private let networkingInteractor: NetworkInteracting
private let logger: ConsoleLogging
private let rpcHistory: RPCHistory
private var publishers = [AnyCancellable]()
var onResponse: ((_ id: RPCID, _ cacao: Cacao) -> Void)?

init(networkingInteractor: NetworkInteracting,
logger: ConsoleLogging,
rpcHistory: RPCHistory) {
self.networkingInteractor = networkingInteractor
self.logger = logger
self.rpcHistory = rpcHistory
subscribeForResponse()
}

private func subscribeForResponse() {
networkingInteractor.responsePublisher.sink { [unowned self] subscriptionPayload in
guard let request = rpcHistory.get(recordId: subscriptionPayload.request.id!)?.request,
request.method == "wc_authRequest" else { return }
networkingInteractor.unsubscribe(topic: subscriptionPayload.topic)
guard let cacao = try? subscriptionPayload.request.result?.get(Cacao.self) else {
logger.debug("Malformed auth response params")
return
}
do {
try CacaoSignatureVerifier().verifySignature(cacao)
onResponse?(subscriptionPayload.request.id!, cacao)
} catch {
logger.debug("Received response with invalid signature")
}
}.store(in: &publishers)
}
}
15 changes: 15 additions & 0 deletions Sources/Auth/Services/Common/CacaoSignatureVerifier.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Foundation

protocol CacaoSignatureVerifying {
func verifySignature(_ cacao: Cacao) throws
}

class CacaoSignatureVerifier: CacaoSignatureVerifying {
enum Errors: Error {
case signatureInvalid
}

func verifySignature(_ cacao: Cacao) throws {
fatalError("not implemented")
}
}
10 changes: 10 additions & 0 deletions Sources/Auth/Services/Common/NetworkingInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import JSONRPC

protocol NetworkInteracting {
var requestPublisher: AnyPublisher<RequestSubscriptionPayload, Never> {get}
var responsePublisher: AnyPublisher<ResponseSubscriptionPayload, Never> {get}
func subscribe(topic: String) async throws
func unsubscribe(topic: String)
func request(_ request: RPCRequest, topic: String, tag: Int, envelopeType: Envelope.EnvelopeType) async throws
func respond(topic: String, response: RPCResponse, tag: Int, envelopeType: Envelope.EnvelopeType) async throws
}
Expand All @@ -26,6 +28,10 @@ class NetworkingInteractor: NetworkInteracting {
requestPublisherSubject.eraseToAnyPublisher()
}
private let requestPublisherSubject = PassthroughSubject<RequestSubscriptionPayload, Never>()
var responsePublisher: AnyPublisher<ResponseSubscriptionPayload, Never> {
responsePublisherSubject.eraseToAnyPublisher()
}
private let responsePublisherSubject = PassthroughSubject<ResponseSubscriptionPayload, Never>()

init(relayClient: RelayClient,
serializer: Serializing,
Expand All @@ -39,6 +45,10 @@ class NetworkingInteractor: NetworkInteracting {
try await relayClient.subscribe(topic: topic)
}

func unsubscribe(topic: String) {
fatalError("not implemented")
}

func request(_ request: RPCRequest, topic: String, tag: Int, envelopeType: Envelope.EnvelopeType) async throws {
try rpcHistory.set(request, forTopic: topic, emmitedBy: .local)
let message = try! serializer.serialize(topic: topic, encodable: request, envelopeType: envelopeType)
Expand Down
71 changes: 68 additions & 3 deletions Sources/Auth/Services/Common/SIWEMessageFormatter.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,76 @@
import Foundation
import WalletConnectUtils

protocol SIWEMessageFormatting {
func formatMessage(from request: AuthRequestParams) throws -> String
func formatMessage(from authPayload: AuthPayload, address: String) -> String
}

struct SIWEMessageFormatter: SIWEMessageFormatting {
func formatMessage(from request: AuthRequestParams) throws -> String {
fatalError("not implemented")
func formatMessage(from authPayload: AuthPayload, address: String) -> String {
SIWEMessage(domain: authPayload.domain,
uri: authPayload.aud,
address: address,
version: authPayload.version,
nonce: authPayload.nonce,
chainId: authPayload.chainId,
iat: authPayload.iat,
nbf: authPayload.nbf,
exp: authPayload.exp,
statement: authPayload.statement,
requestId: authPayload.requestId,
resources: authPayload.resources).formatted
}
}

fileprivate struct SIWEMessage: Equatable {
let domain: String
let uri: String //aud
let address: String
let version: Int
let nonce: String
let chainId: String
let iat: String
let nbf: String?
let exp: String?
let statement: String?
let requestId: String?
let resources: [String]?

var formatted: String {
return """
\(domain) wants you to sign in with your Ethereum account:
\(address)
\(statementLine)
URI: \(uri)
Version: \(version)
Chain ID: \(chainId)
Nonce: \(nonce)
Issued At: \(iat)\(expLine)\(nbfLine)\(requestIdLine)\(resourcesSection)
"""
}

var expLine: String {
guard let exp = exp else { return "" }
return "\nExpiration Time: \(exp)"
}

var statementLine: String {
guard let statement = statement else { return "" }
return "\n\(statement)\n"
}

var nbfLine: String {
guard let nbf = nbf else { return "" }
return "\nNot Before: \(nbf)"
}

var requestIdLine: String {
guard let requestId = requestId else { return "" }
return "\nRequest ID: \(requestId)"
}

var resourcesSection: String {
guard let resources = resources else { return "" }
return resources.reduce("\nResources:") { $0 + "\n- \($1)" }
}
}
7 changes: 5 additions & 2 deletions Sources/Auth/Services/Wallet/AuthRequestSubscriber.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ import JSONRPC
class AuthRequestSubscriber {
private let networkingInteractor: NetworkInteracting
private let logger: ConsoleLogging
private let address: String
private var publishers = [AnyCancellable]()
private let messageFormatter: SIWEMessageFormatting
var onRequest: ((_ id: RPCID, _ message: String)->())?

init(networkingInteractor: NetworkInteracting,
logger: ConsoleLogging,
messageFormatter: SIWEMessageFormatting) {
messageFormatter: SIWEMessageFormatting,
address: String) {
self.networkingInteractor = networkingInteractor
self.logger = logger
self.address = address
self.messageFormatter = messageFormatter
subscribeForRequest()
}
Expand All @@ -27,7 +30,7 @@ class AuthRequestSubscriber {
return
}
do {
let message = try messageFormatter.formatMessage(from: authRequestParams)
let message = try messageFormatter.formatMessage(from: authRequestParams.payloadParams, address: address)
guard let requestId = subscriptionPayload.request.id else { return }
onRequest?(requestId, message)
} catch {
Expand Down
10 changes: 5 additions & 5 deletions Sources/Auth/Types/AuthPayload.swift
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
import Foundation

struct AuthPayload: Codable, Equatable {
let type: String
let chainId: String
let domain: String
let aud: String
let version: String
let version: Int
let nonce: String
let chainId: String
let type: String
let iat: String
let nbf: String?
let exp: String?
let statement: String?
let requestId: String?
let resources: String?
let resources: [String]?

init(requestParams: RequestParams, iat: String) {
self.type = "eip4361"
self.chainId = requestParams.chainId
self.domain = requestParams.domain
self.aud = requestParams.aud
self.version = "1"
self.version = 1
self.nonce = requestParams.nonce
self.iat = iat
self.nbf = requestParams.nbf
Expand Down
2 changes: 1 addition & 1 deletion Sources/Auth/Types/Cacao/Cacao.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

struct Cacao: Codable, Equatable {
public struct Cacao: Codable, Equatable {
let header: CacaoHeader
let payload: CacaoPayload
let signature: CacaoSignature
Expand Down
2 changes: 1 addition & 1 deletion Sources/Auth/Types/RequestParams.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ struct RequestParams {
let exp: String?
let statement: String?
let requestId: String?
let resources: String?
let resources: [String]?
}
4 changes: 2 additions & 2 deletions Sources/Auth/Types/RequestSubscriptionPayload.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation
import JSONRPC

struct RequestSubscriptionPayload: Codable {
let id: Int64
struct RequestSubscriptionPayload: Codable, Equatable {
let topic: String
let request: RPCRequest
}
7 changes: 7 additions & 0 deletions Sources/Auth/Types/ResponseSubscriptionPayload.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Foundation
import JSONRPC

struct ResponseSubscriptionPayload: Codable, Equatable {
let topic: String
let request: RPCResponse
}
2 changes: 1 addition & 1 deletion Sources/WalletConnectRelay/EnvironmentInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ enum EnvironmentInfo {
}

static var sdkVersion: String {
"v0.9.2-rc.0"
"v0.9.3-rc.0"
}

static var operatingSystem: String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ private extension ApproveEngine {
)
settlingProposal = proposal

Task(priority: .background) {
Task(priority: .high) {
try? await networkingInteractor.subscribe(topic: sessionTopic)
}
} catch {
Expand Down
2 changes: 1 addition & 1 deletion Tests/AuthTests/AuthRequstSubscriberTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class AuthRequstSubscriberTests: XCTestCase {
messageFormatter = SIWEMessageFormatterMock()
sut = AuthRequestSubscriber(networkingInteractor: networkingInteractor,
logger: ConsoleLoggerMock(),
messageFormatter: messageFormatter)
messageFormatter: messageFormatter, address: "")
}

func testSubscribeRequest() {
Expand Down
9 changes: 9 additions & 0 deletions Tests/AuthTests/Mocks/NetworkingInteractorMock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import WalletConnectKMS

struct NetworkingInteractorMock: NetworkInteracting {

var responsePublisher: AnyPublisher<ResponseSubscriptionPayload, Never> {
responsePublisherSubject.eraseToAnyPublisher()
}
private let responsePublisherSubject = PassthroughSubject<ResponseSubscriptionPayload, Never>()

let requestPublisherSubject = PassthroughSubject<RequestSubscriptionPayload, Never>()
var requestPublisher: AnyPublisher<RequestSubscriptionPayload, Never> {
requestPublisherSubject.eraseToAnyPublisher()
Expand All @@ -15,6 +20,10 @@ struct NetworkingInteractorMock: NetworkInteracting {

}

func unsubscribe(topic: String) {

}

func request(_ request: RPCRequest, topic: String, tag: Int, envelopeType: Envelope.EnvelopeType) async throws {

}
Expand Down
2 changes: 1 addition & 1 deletion Tests/AuthTests/Mocks/SIWEMessageFormatterMock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Foundation

class SIWEMessageFormatterMock: SIWEMessageFormatting {
var formattedMessage: String!
func formatMessage(from request: AuthRequestParams) throws -> String {
func formatMessage(from authPayload: AuthPayload, address: String) -> String {
return formattedMessage
}
}
Loading

0 comments on commit 8dda02c

Please sign in to comment.