Skip to content

Commit

Permalink
Merge pull request #1321 from WalletConnect/develop
Browse files Browse the repository at this point in the history
1.16.0
  • Loading branch information
llbartekll authored Mar 15, 2024
2 parents 6d99888 + 2f8e32d commit e163761
Show file tree
Hide file tree
Showing 11 changed files with 90 additions and 30 deletions.
38 changes: 31 additions & 7 deletions Example/IntegrationTests/Sign/SignClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ final class SignClientTests: XCTestCase {
func testEIP191SessionAuthenticated() async throws {
let responseExpectation = expectation(description: "successful response delivered")

wallet.authRequestPublisher.sink { [unowned self] (request, _) in
wallet.authenticateRequestPublisher.sink { [unowned self] (request, _) in
Task(priority: .high) {
let signerFactory = DefaultSignerFactory()
let signer = MessageSignerFactory(signerFactory: signerFactory).create()
Expand Down Expand Up @@ -811,7 +811,7 @@ final class SignClientTests: XCTestCase {
func testEIP191SessionAuthenticateEmptyMethods() async throws {
let responseExpectation = expectation(description: "successful response delivered")

wallet.authRequestPublisher.sink { [unowned self] (request, _) in
wallet.authenticateRequestPublisher.sink { [unowned self] (request, _) in
Task(priority: .high) {
let signerFactory = DefaultSignerFactory()
let signer = MessageSignerFactory(signerFactory: signerFactory).create()
Expand Down Expand Up @@ -846,7 +846,7 @@ final class SignClientTests: XCTestCase {
func testEIP191SessionAuthenticatedMultiCacao() async throws {
let responseExpectation = expectation(description: "successful response delivered")

wallet.authRequestPublisher.sink { [unowned self] (request, _) in
wallet.authenticateRequestPublisher.sink { [unowned self] (request, _) in
Task(priority: .high) {
let signerFactory = DefaultSignerFactory()
let signer = MessageSignerFactory(signerFactory: signerFactory).create()
Expand Down Expand Up @@ -911,7 +911,7 @@ final class SignClientTests: XCTestCase {

try await walletPairingClient.pair(uri: uri)

wallet.authRequestPublisher.sink { [unowned self] (request, _) in
wallet.authenticateRequestPublisher.sink { [unowned self] (request, _) in
Task(priority: .high) {
let signature = CacaoSignature(t: .eip1271, s: eip1271Signature)
let cacao = try! wallet.buildSignedAuthObject(authPayload: request.payload, signature: signature, account: account)
Expand All @@ -932,7 +932,7 @@ final class SignClientTests: XCTestCase {
let uri = try! await dapp.authenticate(AuthRequestParams.stub())

try? await walletPairingClient.pair(uri: uri)
wallet.authRequestPublisher.sink { [unowned self] (request, _) in
wallet.authenticateRequestPublisher.sink { [unowned self] (request, _) in
Task(priority: .high) {
let invalidSignature = CacaoSignature(t: .eip1271, s: eip1271Signature)

Expand All @@ -954,7 +954,7 @@ final class SignClientTests: XCTestCase {
let uri = try! await dapp.authenticate(AuthRequestParams.stub())

try? await walletPairingClient.pair(uri: uri)
wallet.authRequestPublisher.sink { [unowned self] request in
wallet.authenticateRequestPublisher.sink { [unowned self] request in
Task(priority: .high) {
try! await wallet.rejectSession(requestId: request.0.id)
}
Expand All @@ -979,7 +979,7 @@ final class SignClientTests: XCTestCase {
let chain = Blockchain("eip155:1")!
// sleep is needed as emitRequestIfPending() will be called on client init and then on request itself, second request would be debouced
sleep(1)
wallet.authRequestPublisher.sink { [unowned self] (request, _) in
wallet.authenticateRequestPublisher.sink { [unowned self] (request, _) in
Task(priority: .high) {
let signerFactory = DefaultSignerFactory()
let signer = MessageSignerFactory(signerFactory: signerFactory).create()
Expand Down Expand Up @@ -1062,4 +1062,28 @@ final class SignClientTests: XCTestCase {
await fulfillment(of: [fallbackExpectation], timeout: InputConfig.defaultTimeout)
}


func testFallbackToSessionProposeIfWalletIsNotSubscribingSessionAuthenticate() async throws {
let responseExpectation = expectation(description: "successful response delivered")

let requiredNamespaces = ProposalNamespace.stubRequired()
let sessionNamespaces = SessionNamespace.make(toRespond: requiredNamespaces)

wallet.sessionProposalPublisher.sink { [unowned self] (proposal, _) in
Task(priority: .high) {
do { _ = try await wallet.approve(proposalId: proposal.id, namespaces: sessionNamespaces) } catch { XCTFail("\(error)") }
}
}.store(in: &publishers)

dapp.sessionSettlePublisher.sink { settledSession in
Task(priority: .high) {
responseExpectation.fulfill()
}
}.store(in: &publishers)

let uri = try await dapp.authenticate(AuthRequestParams.stub())
try await walletPairingClient.pair(uri: uri)
await fulfillment(of: [responseExpectation], timeout: InputConfig.defaultTimeout)
}

}
11 changes: 0 additions & 11 deletions Sources/WalletConnectNotify/Client/Wallet/NotifyClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -180,17 +180,6 @@ public class NotifyClient {
}
}

private extension NotifyClient {

func makeStatement(allApps: Bool) -> String {
switch allApps {
case false:
return "I further authorize this app to send me notifications. Read more at https://walletconnect.com/notifications"
case true:
return "I further authorize this app to view and manage my notifications for ALL apps. Read more at https://walletconnect.com/notifications"
}
}
}

#if targetEnvironment(simulator)
extension NotifyClient {
Expand Down
2 changes: 1 addition & 1 deletion Sources/WalletConnectRelay/PackageConfig.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version": "1.15.0"}
{"version": "1.16.0"}
7 changes: 5 additions & 2 deletions Sources/WalletConnectSign/Engine/Common/ApproveEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ final class ApproveEngine {
private let kms: KeyManagementServiceProtocol
private let logger: ConsoleLogging
private let rpcHistory: RPCHistory
private let authRequestSubscribersTracking: AuthRequestSubscribersTracking

private var publishers = Set<AnyCancellable>()

Expand All @@ -44,7 +45,8 @@ final class ApproveEngine {
pairingStore: WCPairingStorage,
sessionStore: WCSessionStorage,
verifyClient: VerifyClientProtocol,
rpcHistory: RPCHistory
rpcHistory: RPCHistory,
authRequestSubscribersTracking: AuthRequestSubscribersTracking
) {
self.networkingInteractor = networkingInteractor
self.proposalPayloadsStore = proposalPayloadsStore
Expand All @@ -58,6 +60,7 @@ final class ApproveEngine {
self.sessionStore = sessionStore
self.verifyClient = verifyClient
self.rpcHistory = rpcHistory
self.authRequestSubscribersTracking = authRequestSubscribersTracking

setupRequestSubscriptions()
setupResponseSubscriptions()
Expand Down Expand Up @@ -217,7 +220,7 @@ private extension ApproveEngine {
guard let pairing = pairingStore.getPairing(forTopic: payload.topic) else { return }
if let methods = pairing.methods,
methods.flatMap({ $0 })
.contains(SessionAuthenticatedProtocolMethod().method) {
.contains(SessionAuthenticatedProtocolMethod().method), authRequestSubscribersTracking.hasSubscribers() {
logger.debug("Ignoring Session Proposal")
// respond with an error?
return
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Foundation

// purpose of this class is to allow fallback to session propose in case wallet did not subscribe to authenticateRequestPublisher and dapp request wc_sessionAuthenticate
class AuthRequestSubscribersTracking {
private var subscribersCount: Int = 0
private let serialQueue = DispatchQueue(label: "com.walletconnect.AuthRequestSubscribersTrackingQueue")
private let logger: ConsoleLogging

init(logger: ConsoleLogging) {
self.logger = logger
}

func increment() {
serialQueue.sync {
subscribersCount += 1
logger.debug("Incremented subscriber count: \(subscribersCount)")
}
}

func decrement() {
serialQueue.sync {
subscribersCount = max(0, subscribersCount - 1)
logger.debug("Decremented subscriber count: \(subscribersCount)")
}
}

func hasSubscribers() -> Bool {
return serialQueue.sync { subscribersCount > 0 }
}
}
15 changes: 12 additions & 3 deletions Sources/WalletConnectSign/Sign/SignClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,14 @@ public final class SignClient: SignClientProtocol {
/// Publisher that sends authentication requests
///
/// Wallet should subscribe on events in order to receive auth requests.
public var authRequestPublisher: AnyPublisher<(request: AuthenticationRequest, context: VerifyContext?), Never> {
authRequestPublisherSubject.eraseToAnyPublisher()
public var authenticateRequestPublisher: AnyPublisher<(request: AuthenticationRequest, context: VerifyContext?), Never> {
return authRequestPublisherSubject
.handleEvents(receiveSubscription: { [unowned self] _ in
authRequestSubscribersTracking.increment()
}, receiveCancel: { [unowned self] in
authRequestSubscribersTracking.decrement()
})
.eraseToAnyPublisher()
}

/// Publisher that sends authentication responses
Expand Down Expand Up @@ -175,6 +181,7 @@ public final class SignClient: SignClientProtocol {
private let pingResponsePublisherSubject = PassthroughSubject<String, Never>()
private let sessionsPublisherSubject = PassthroughSubject<[Session], Never>()
private var authRequestPublisherSubject = PassthroughSubject<(request: AuthenticationRequest, context: VerifyContext?), Never>()
private let authRequestSubscribersTracking: AuthRequestSubscribersTracking

private var publishers = Set<AnyCancellable>()

Expand Down Expand Up @@ -204,7 +211,8 @@ public final class SignClient: SignClientProtocol {
proposalExpiryWatcher: ProposalExpiryWatcher,
pendingProposalsProvider: PendingProposalsProvider,
requestsExpiryWatcher: RequestsExpiryWatcher,
authResponseTopicResubscriptionService: AuthResponseTopicResubscriptionService
authResponseTopicResubscriptionService: AuthResponseTopicResubscriptionService,
authRequestSubscribersTracking: AuthRequestSubscribersTracking
) {
self.logger = logger
self.networkingClient = networkingClient
Expand All @@ -231,6 +239,7 @@ public final class SignClient: SignClientProtocol {
self.pendingProposalsProvider = pendingProposalsProvider
self.requestsExpiryWatcher = requestsExpiryWatcher
self.authResponseTopicResubscriptionService = authResponseTopicResubscriptionService
self.authRequestSubscribersTracking = authRequestSubscribersTracking

setUpConnectionObserving()
setUpEnginesCallbacks()
Expand Down
7 changes: 5 additions & 2 deletions Sources/WalletConnectSign/Sign/SignClientFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public struct SignClientFactory {
let sessionExtendRequestSubscriber = SessionExtendRequestSubscriber(networkingInteractor: networkingClient, sessionStore: sessionStore, logger: logger)
let sessionExtendResponseSubscriber = SessionExtendResponseSubscriber(networkingInteractor: networkingClient, sessionStore: sessionStore, logger: logger)
let sessionTopicToProposal = CodableStore<Session.Proposal>(defaults: RuntimeKeyValueStorage(), identifier: SignStorageIdentifiers.sessionTopicToProposal.rawValue)
let authRequestSubscribersTracking = AuthRequestSubscribersTracking(logger: logger)
let approveEngine = ApproveEngine(
networkingInteractor: networkingClient,
proposalPayloadsStore: proposalPayloadsStore,
Expand All @@ -80,7 +81,8 @@ public struct SignClientFactory {
pairingStore: pairingStore,
sessionStore: sessionStore,
verifyClient: verifyClient,
rpcHistory: rpcHistory
rpcHistory: rpcHistory,
authRequestSubscribersTracking: authRequestSubscribersTracking
)
let cleanupService = SignCleanupService(pairingStore: pairingStore, sessionStore: sessionStore, kms: kms, sessionTopicToProposal: sessionTopicToProposal, networkInteractor: networkingClient, rpcHistory: rpcHistory)
let deleteSessionService = DeleteSessionService(networkingInteractor: networkingClient, kms: kms, sessionStore: sessionStore, logger: logger)
Expand Down Expand Up @@ -135,7 +137,8 @@ public struct SignClientFactory {
proposalExpiryWatcher: proposalExpiryWatcher,
pendingProposalsProvider: pendingProposalsProvider,
requestsExpiryWatcher: requestsExpiryWatcher,
authResponseTopicResubscriptionService: authResponseTopicResubscriptionService
authResponseTopicResubscriptionService: authResponseTopicResubscriptionService,
authRequestSubscribersTracking: authRequestSubscribersTracking
)
return client
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/WalletConnectSign/Sign/SignClientProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public protocol SignClientProtocol {
var sessionResponsePublisher: AnyPublisher<Response, Never> { get }
var sessionRejectionPublisher: AnyPublisher<(Session.Proposal, Reason), Never> { get }
var sessionEventPublisher: AnyPublisher<(event: Session.Event, sessionTopic: String, chainId: Blockchain?), Never> { get }
var authRequestPublisher: AnyPublisher<(request: AuthenticationRequest, context: VerifyContext?), Never> { get }
var authenticateRequestPublisher: AnyPublisher<(request: AuthenticationRequest, context: VerifyContext?), Never> { get }
var logsPublisher: AnyPublisher<Log, Never> {get}
var sessionProposalExpirationPublisher: AnyPublisher<Session.Proposal, Never> { get }
var pendingProposalsPublisher: AnyPublisher<[(proposal: Session.Proposal, context: VerifyContext?)], Never> { get }
Expand Down
2 changes: 1 addition & 1 deletion Sources/Web3Wallet/Web3WalletClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class Web3WalletClient {
///
/// Wallet should subscribe on events in order to receive auth requests.
public var authenticateRequestPublisher: AnyPublisher<(request: AuthenticationRequest, context: VerifyContext?), Never> {
signClient.authRequestPublisher.eraseToAnyPublisher()
signClient.authenticateRequestPublisher.eraseToAnyPublisher()
}

/// Publisher that sends sessions on every sessions update
Expand Down
3 changes: 2 additions & 1 deletion Tests/WalletConnectSignTests/AppProposalServiceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ final class AppProposalServiceTests: XCTestCase {
pairingStore: storageMock,
sessionStore: WCSessionStorageMock(),
verifyClient: VerifyClientMock(),
rpcHistory: history
rpcHistory: history,
authRequestSubscribersTracking: AuthRequestSubscribersTracking(logger: logger)
)
}

Expand Down
3 changes: 2 additions & 1 deletion Tests/WalletConnectSignTests/ApproveEngineTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ final class ApproveEngineTests: XCTestCase {
pairingStore: pairingStorageMock,
sessionStore: sessionStorageMock,
verifyClient: VerifyClientMock(),
rpcHistory: history
rpcHistory: history,
authRequestSubscribersTracking: AuthRequestSubscribersTracking(logger: ConsoleLoggerMock())
)
}

Expand Down

0 comments on commit e163761

Please sign in to comment.