diff --git a/Example/WalletApp/PresentationLayer/Wallet/PushMessages/Models/PushMessageViewModel.swift b/Example/WalletApp/PresentationLayer/Wallet/PushMessages/Models/PushMessageViewModel.swift index a81193c71..35a61e1d6 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/PushMessages/Models/PushMessageViewModel.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/PushMessages/Models/PushMessageViewModel.swift @@ -21,4 +21,8 @@ struct PushMessageViewModel: Identifiable { var subtitle: String { return pushMessageRecord.message.body } + + var publishedAt: String { + return pushMessageRecord.publishedAt.formatted(.relative(presentation: .named, unitsStyle: .wide)) + } } diff --git a/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesInteractor.swift b/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesInteractor.swift index d6b23324f..b2fa4a51f 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesInteractor.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesInteractor.swift @@ -9,6 +9,10 @@ final class PushMessagesInteractor { self.subscription = subscription } + var pushMessagePublisher: AnyPublisher { + return Push.wallet.pushMessagePublisher + } + func getPushMessages() -> [PushMessageRecord] { return Push.wallet.getMessageHistory(topic: subscription.topic) } diff --git a/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesPresenter.swift b/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesPresenter.swift index 28f265bdf..1abf8a408 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesPresenter.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesPresenter.swift @@ -7,6 +7,7 @@ final class PushMessagesPresenter: ObservableObject { private let interactor: PushMessagesInteractor private let router: PushMessagesRouter private var disposeBag = Set() + @Published var pushMessages: [PushMessageViewModel] = [] init(interactor: PushMessagesInteractor, router: PushMessagesRouter) { @@ -14,7 +15,7 @@ final class PushMessagesPresenter: ObservableObject { self.interactor = interactor self.router = router } - + func deletePushMessage(at indexSet: IndexSet) { if let index = indexSet.first { interactor.deletePushMessage(id: pushMessages[index].id) @@ -40,9 +41,28 @@ extension PushMessagesPresenter: SceneViewModel { private extension PushMessagesPresenter { func reloadPushMessages() { - self.pushMessages = interactor.getPushMessages().map({ pushMessageRecord in - PushMessageViewModel(pushMessageRecord: pushMessageRecord) - }) + self.pushMessages = interactor.getPushMessages() + .sorted { + // Most recent first + $0.publishedAt > $1.publishedAt + } + .map { pushMessageRecord in + PushMessageViewModel(pushMessageRecord: pushMessageRecord) + } + + interactor.pushMessagePublisher + .receive(on: DispatchQueue.main) + .sink { [weak self] newPushMessage in + let newMessageViewModel = PushMessageViewModel(pushMessageRecord: newPushMessage) + guard let index = self?.pushMessages.firstIndex( + where: { $0.pushMessageRecord.publishedAt > newPushMessage.publishedAt } + ) else { + self?.pushMessages.append(newMessageViewModel) + return + } + self?.pushMessages.insert(newMessageViewModel, at: index) + } + .store(in: &disposeBag) } } diff --git a/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesView.swift b/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesView.swift index 9a6908ee7..c29766ed3 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesView.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesView.swift @@ -68,16 +68,26 @@ struct PushMessagesView: View { } } .padding(.leading, 20) - + + VStack(alignment: .leading, spacing: 2) { Text(pushMessage.title) .foregroundColor(.grey8) .font(.system(size: 20, weight: .semibold, design: .rounded)) - - Text(pushMessage.subtitle) - .foregroundColor(.grey50) - .font(.system(size: 13, weight: .medium, design: .rounded)) + + HStack { + Text(pushMessage.subtitle) + .foregroundColor(.grey50) + .font(.system(size: 13, weight: .medium, design: .rounded)) + + Spacer() + + Text(pushMessage.publishedAt) + .foregroundColor(.grey50) + .font(.system(size: 13, weight: .medium, design: .rounded)) + } } + .padding(.trailing, 20) } } } diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalInteractor.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalInteractor.swift index 85199af00..b5bc8aa7f 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalInteractor.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalInteractor.swift @@ -4,17 +4,25 @@ import Web3Wallet final class SessionProposalInteractor { func approve(proposal: Session.Proposal) async throws { + // Following properties are used to support all the required namespaces for the testing purposes + let supportedMethods = Array(proposal.requiredNamespaces.map { $0.value.methods }.first ?? []) + let supportedEvents = Array(proposal.requiredNamespaces.map { $0.value.events }.first ?? []) + let supportedChains = Array((proposal.requiredNamespaces.map { $0.value.chains }.first ?? [] )!) + let supportedAccounts = supportedChains.map { Account(blockchain: $0, address: ETHSigner.address)! } + + /* Use only supported values for production. I.e: + let supportedMethods = ["eth_signTransaction", "personal_sign", "eth_signTypedData", "eth_sendTransaction", "eth_sign"] + let supportedEvents = ["accountsChanged", "chainChanged"] + let supportedChains = [Blockchain("eip155:1")!, Blockchain("eip155:5")!] + let supportedAccounts = [Account(blockchain: Blockchain("eip155:5")!, address: ETHSigner.address)!] + */ do { let sessionNamespaces = try AutoNamespaces.build( sessionProposal: proposal, - chains: [Blockchain("eip155:1")!, Blockchain("eip155:137")!], - methods: ["eth_sendTransaction", "personal_sign"], - events: ["accountsChanged", "chainChanged"], - accounts: [ - Account(blockchain: Blockchain("eip155:5")!, address: ETHSigner.address)!, - Account(blockchain: Blockchain("eip155:1")!, address: ETHSigner.address)!, - Account(blockchain: Blockchain("eip155:137")!, address: ETHSigner.address)! - ] + chains: supportedChains, + methods: supportedMethods, + events: supportedEvents, + accounts: supportedAccounts ) try await Web3Wallet.instance.approve(proposalId: proposal.id, namespaces: sessionNamespaces) } catch { diff --git a/Sources/WalletConnectSign/Namespace.swift b/Sources/WalletConnectSign/Namespace.swift index 10567a145..5e398757b 100644 --- a/Sources/WalletConnectSign/Namespace.swift +++ b/Sources/WalletConnectSign/Namespace.swift @@ -126,7 +126,7 @@ enum Namespace { if let chains = proposedNamespace.chains { try chains.forEach { chain in if !approvedNamespace.accounts.contains(where: { $0.blockchain == chain }) { - throw WalletConnectError.unsupportedNamespace(.unsupportedChains) + throw WalletConnectError.unsupportedNamespace(.unsupportedAccounts) } } } else {