Skip to content

Commit

Permalink
Present request for pending requests on pair
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-lsvk committed Aug 16, 2023
1 parent 37dc259 commit ef75976
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,7 @@ final class WalletPresenter: ObservableObject {
func onAppear() {
showPairingLoading = app.requestSent
removePairingIndicator()

let proposals = interactor.getPendingProposals()
if let proposal = proposals.last {
router.present(sessionProposal: proposal.proposal, importAccount: importAccount, sessionContext: proposal.context)
}


let pendingRequests = interactor.getPendingRequests()
if let request = pendingRequests.first(where: { $0.context != nil }) {
router.present(sessionRequest: request.request, importAccount: importAccount, sessionContext: request.context)
Expand Down
2 changes: 1 addition & 1 deletion Sources/Auth/AuthClientFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public struct AuthClientFactory {
let appRespondSubscriber = AppRespondSubscriber(networkingInteractor: networkingClient, logger: logger, rpcHistory: history, signatureVerifier: signatureVerifier, pairingRegisterer: pairingRegisterer, messageFormatter: messageFormatter)
let walletErrorResponder = WalletErrorResponder(networkingInteractor: networkingClient, logger: logger, kms: kms, rpcHistory: history)
let walletRequestSubscriber = WalletRequestSubscriber(networkingInteractor: networkingClient, logger: logger, kms: kms, walletErrorResponder: walletErrorResponder, pairingRegisterer: pairingRegisterer, verifyClient: verifyClient, verifyContextStore: verifyContextStore)
let walletRespondService = WalletRespondService(networkingInteractor: networkingClient, logger: logger, kms: kms, rpcHistory: history, verifyContextStore: verifyContextStore, walletErrorResponder: walletErrorResponder)
let walletRespondService = WalletRespondService(networkingInteractor: networkingClient, logger: logger, kms: kms, rpcHistory: history, verifyContextStore: verifyContextStore, walletErrorResponder: walletErrorResponder, pairingRegisterer: pairingRegisterer)
let pendingRequestsProvider = PendingRequestsProvider(rpcHistory: history, verifyContextStore: verifyContextStore)

return AuthClient(
Expand Down
5 changes: 1 addition & 4 deletions Sources/Auth/Services/Wallet/WalletRequestSubscriber.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,7 @@ class WalletRequestSubscriber {
.sink { [unowned self] (payload: RequestSubscriptionPayload<AuthRequestParams>) in
logger.debug("WalletRequestSubscriber: Received request")

pairingRegisterer.activate(
pairingTopic: payload.topic,
peerMetadata: payload.request.requester.metadata
)
pairingRegisterer.setReceived(pairingTopic: payload.topic)

let request = AuthRequest(id: payload.id, topic: payload.topic, payload: payload.request.payloadParams)

Expand Down
25 changes: 18 additions & 7 deletions Sources/Auth/Services/Wallet/WalletRespondService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,24 @@ actor WalletRespondService {
private let verifyContextStore: CodableStore<VerifyContext>
private let logger: ConsoleLogging
private let walletErrorResponder: WalletErrorResponder
private let pairingRegisterer: PairingRegisterer

init(networkingInteractor: NetworkInteracting,
logger: ConsoleLogging,
kms: KeyManagementService,
rpcHistory: RPCHistory,
verifyContextStore: CodableStore<VerifyContext>,
walletErrorResponder: WalletErrorResponder) {
init(
networkingInteractor: NetworkInteracting,
logger: ConsoleLogging,
kms: KeyManagementService,
rpcHistory: RPCHistory,
verifyContextStore: CodableStore<VerifyContext>,
walletErrorResponder: WalletErrorResponder,
pairingRegisterer: PairingRegisterer
) {
self.networkingInteractor = networkingInteractor
self.logger = logger
self.kms = kms
self.rpcHistory = rpcHistory
self.verifyContextStore = verifyContextStore
self.walletErrorResponder = walletErrorResponder
self.pairingRegisterer = pairingRegisterer
}

func respond(requestId: RPCID, signature: CacaoSignature, account: Account) async throws {
Expand All @@ -34,10 +39,16 @@ actor WalletRespondService {

let header = CacaoHeader(t: "eip4361")
let payload = try authRequestParams.payloadParams.cacaoPayload(address: account.address)
let responseParams = AuthResponseParams(h: header, p: payload, s: signature)
let responseParams = AuthResponseParams(h: header, p: payload, s: signature)

let response = RPCResponse(id: requestId, result: responseParams)
try await networkingInteractor.respond(topic: topic, response: response, protocolMethod: AuthRequestProtocolMethod(), envelopeType: .type1(pubKey: keys.publicKey.rawRepresentation))

pairingRegisterer.activate(
pairingTopic: topic,
peerMetadata: authRequestParams.requester.metadata
)

verifyContextStore.delete(forKey: requestId.string)
}

Expand Down
3 changes: 2 additions & 1 deletion Sources/WalletConnectNetworking/NetworkInteracting.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ public protocol NetworkInteracting {
func respond(topic: String, response: RPCResponse, protocolMethod: ProtocolMethod, envelopeType: Envelope.EnvelopeType) async throws
func respondSuccess(topic: String, requestId: RPCID, protocolMethod: ProtocolMethod, envelopeType: Envelope.EnvelopeType) async throws
func respondError(topic: String, requestId: RPCID, protocolMethod: ProtocolMethod, reason: Reason, envelopeType: Envelope.EnvelopeType) async throws

func handleHistoryRequest(topic: String, request: RPCRequest)

func requestSubscription<Request: Codable>(
on request: ProtocolMethod
) -> AnyPublisher<RequestSubscriptionPayload<Request>, Never>
Expand Down
4 changes: 4 additions & 0 deletions Sources/WalletConnectNetworking/NetworkingInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@ public class NetworkingInteractor: NetworkInteracting {
logger.debug("Networking Interactor - Received unknown object type from networking relay")
}
}

public func handleHistoryRequest(topic: String, request: RPCRequest) {
requestPublisherSubject.send((topic, request, Data(), Date(), nil))
}

private func handleRequest(topic: String, request: RPCRequest, decryptedPayload: Data, publishedAt: Date, derivedTopic: String?) {
do {
Expand Down
3 changes: 2 additions & 1 deletion Sources/WalletConnectPairing/PairingClientFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ public struct PairingClientFactory {
public static func create(logger: ConsoleLogging, keyValueStorage: KeyValueStorage, keychainStorage: KeychainStorageProtocol, networkingClient: NetworkingInteractor) -> PairingClient {
let pairingStore = PairingStorage(storage: SequenceStore<WCPairing>(store: .init(defaults: keyValueStorage, identifier: PairStorageIdentifiers.pairings.rawValue)))
let kms = KeyManagementService(keychain: keychainStorage)
let history = RPCHistoryFactory.createForNetwork(keyValueStorage: keyValueStorage)
let appPairService = AppPairService(networkingInteractor: networkingClient, kms: kms, pairingStorage: pairingStore)
let walletPairService = WalletPairService(networkingInteractor: networkingClient, kms: kms, pairingStorage: pairingStore)
let walletPairService = WalletPairService(networkingInteractor: networkingClient, kms: kms, pairingStorage: pairingStore, history: history)
let pairingRequestsSubscriber = PairingRequestsSubscriber(networkingInteractor: networkingClient, pairingStorage: pairingStore, logger: logger)
let pairingsProvider = PairingsProvider(pairingStorage: pairingStore)
let cleanupService = PairingCleanupService(pairingStore: pairingStore, kms: kms)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,23 @@ actor WalletPairService {
let networkingInteractor: NetworkInteracting
let kms: KeyManagementServiceProtocol
private let pairingStorage: WCPairingStorage
private let history: RPCHistory

init(networkingInteractor: NetworkInteracting,
kms: KeyManagementServiceProtocol,
pairingStorage: WCPairingStorage) {
init(
networkingInteractor: NetworkInteracting,
kms: KeyManagementServiceProtocol,
pairingStorage: WCPairingStorage,
history: RPCHistory
) {
self.networkingInteractor = networkingInteractor
self.kms = kms
self.pairingStorage = pairingStorage
self.history = history
}

func pair(_ uri: WalletConnectURI) async throws {
guard !hasPairing(for: uri.topic) else {
throw Errors.pairingAlreadyExist(topic: uri.topic)
guard try !pairingHasPendingRequest(for: uri.topic) else {
return
}

let pairing = WCPairing(uri: uri)
Expand All @@ -39,9 +44,23 @@ actor WalletPairService {

// MARK: - Private functions
extension WalletPairService {
func hasPairing(for topic: String) -> Bool {
if let pairing = pairingStorage.getPairing(forTopic: topic) {
return pairing.requestReceived
func pairingHasPendingRequest(for topic: String) throws -> Bool {
guard let pairing = pairingStorage.getPairing(forTopic: topic), pairing.requestReceived else {
return false
}

if pairing.active {
throw Errors.pairingAlreadyExist(topic: topic)
}

let pendingRequests = history.getPending()
.compactMap { record -> RPCRequest? in
(record.topic == pairing.topic) ? record.request : nil
}

if let pendingRequest = pendingRequests.first {
networkingInteractor.handleHistoryRequest(topic: topic, request: pendingRequest)
return true
}
return false
}
Expand All @@ -65,7 +84,7 @@ extension WalletPairService {
extension WalletPairService.Errors: LocalizedError {
var errorDescription: String? {
switch self {
case .pairingAlreadyExist(let topic): return "Pairing with topic (\(topic)) already exists. Use 'Web3Wallet.instance.getPendingProposals()' or 'Web3Wallet.instance.getPendingRequests()' in order to receive proposals or requests."
case .pairingAlreadyExist(let topic): return "Pairing with topic (\(topic)) is already active"
case .networkNotConnected: return "Pairing failed. You seem to be offline"
}
}
Expand Down
5 changes: 5 additions & 0 deletions Sources/WalletConnectSign/Engine/Common/ApproveEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,11 @@ private extension ApproveEngine {

pairingRegisterer.setReceived(pairingTopic: payload.topic)

if let verifyContext = try? verifyContextStore.get(key: proposal.proposer.publicKey) {
onSessionProposal?(proposal.publicRepresentation(pairingTopic: payload.topic), verifyContext)
return
}

Task(priority: .high) {
let assertionId = payload.decryptedPayload.sha256().toHexString()
do {
Expand Down

0 comments on commit ef75976

Please sign in to comment.