Skip to content

Commit

Permalink
Merge pull request #1404 from WalletConnect/link-mode-SR
Browse files Browse the repository at this point in the history
Link mode sr
  • Loading branch information
llbartekll authored Aug 23, 2024
2 parents 7d7b9b1 + e588da5 commit b9246a5
Show file tree
Hide file tree
Showing 28 changed files with 355 additions and 117 deletions.
19 changes: 0 additions & 19 deletions Sources/Events/Event.swift

This file was deleted.

18 changes: 9 additions & 9 deletions Sources/Events/EventStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
import Foundation

protocol EventStorage {
func saveErrorEvent(_ event: Event)
func fetchErrorEvents() -> [Event]
func saveErrorEvent(_ event: TraceEvent)
func fetchErrorEvents() -> [TraceEvent]
func clearErrorEvents()
}

class UserDefaultsEventStorage: EventStorage {
class UserDefaultsTraceEventStorage: EventStorage {
private let errorEventsKey = "com.walletconnect.sdk.errorEvents"
private let maxEvents = 30

func saveErrorEvent(_ event: Event) {
func saveErrorEvent(_ event: TraceEvent) {
var existingEvents = fetchErrorEvents()
existingEvents.append(event)
// Ensure we keep only the last 30 events
Expand All @@ -23,9 +23,9 @@ class UserDefaultsEventStorage: EventStorage {
}
}

func fetchErrorEvents() -> [Event] {
func fetchErrorEvents() -> [TraceEvent] {
if let data = UserDefaults.standard.data(forKey: errorEventsKey),
let events = try? JSONDecoder().decode([Event].self, from: data) {
let events = try? JSONDecoder().decode([TraceEvent].self, from: data) {
// Return only the last 30 events
return Array(events.suffix(maxEvents))
}
Expand All @@ -39,13 +39,13 @@ class UserDefaultsEventStorage: EventStorage {

#if DEBUG
class MockEventStorage: EventStorage {
private(set) var savedEvents: [Event] = []
private(set) var savedEvents: [TraceEvent] = []

func saveErrorEvent(_ event: Event) {
func saveErrorEvent(_ event: TraceEvent) {
savedEvents.append(event)
}

func fetchErrorEvents() -> [Event] {
func fetchErrorEvents() -> [TraceEvent] {
return savedEvents
}

Expand Down
46 changes: 36 additions & 10 deletions Sources/Events/EventsClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,31 @@ import Foundation

public protocol EventsClientProtocol {
func startTrace(topic: String)
func saveEvent(_ event: TraceEvent)
func saveTraceEvent(_ event: TraceEventItem)
func setTopic(_ topic: String)
func setTelemetryEnabled(_ enabled: Bool)
func saveMessageEvent(_ event: MessageEventType)
}

public class EventsClient: EventsClientProtocol {
private let eventsCollector: EventsCollector
private let eventsDispatcher: EventsDispatcher
private let logger: ConsoleLogging
private var stateStorage: TelemetryStateStorage
private let messageEventsStorage: MessageEventsStorage

init(
eventsCollector: EventsCollector,
eventsDispatcher: EventsDispatcher,
logger: ConsoleLogging,
stateStorage: TelemetryStateStorage
stateStorage: TelemetryStateStorage,
messageEventsStorage: MessageEventsStorage
) {
self.eventsCollector = eventsCollector
self.eventsDispatcher = eventsDispatcher
self.logger = logger
self.stateStorage = stateStorage
self.messageEventsStorage = messageEventsStorage

if stateStorage.telemetryEnabled {
Task { await sendStoredEvents() }
Expand All @@ -48,12 +52,17 @@ public class EventsClient: EventsClientProtocol {
}

// Public method to save event
public func saveEvent(_ event: TraceEvent) {
public func saveTraceEvent(_ event: TraceEventItem) {
guard stateStorage.telemetryEnabled else { return }
logger.debug("Will store an event: \(event)")
logger.debug("Will store a trace event: \(event)")
eventsCollector.saveEvent(event)
}

public func saveMessageEvent(_ event: MessageEventType) {
logger.debug("Will store a message event: \(event)")
messageEventsStorage.saveMessageEvent(event)
}

// Public method to set telemetry enabled or disabled
public func setTelemetryEnabled(_ enabled: Bool) {
stateStorage.telemetryEnabled = enabled
Expand All @@ -66,15 +75,27 @@ public class EventsClient: EventsClientProtocol {

private func sendStoredEvents() async {
guard stateStorage.telemetryEnabled else { return }
let events = eventsCollector.storage.fetchErrorEvents()
guard !events.isEmpty else { return }

logger.debug("Will send events")
let traceEvents = eventsCollector.storage.fetchErrorEvents()
let messageEvents = messageEventsStorage.fetchMessageEvents()

guard !traceEvents.isEmpty || !messageEvents.isEmpty else { return }

var combinedEvents: [AnyCodable] = []

// Wrap trace events
combinedEvents.append(contentsOf: traceEvents.map { AnyCodable($0) })

// Wrap message events
combinedEvents.append(contentsOf: messageEvents.map { AnyCodable($0) })

logger.debug("Will send combined events")
do {
let success: Bool = try await eventsDispatcher.executeWithRetry(events: events)
let success: Bool = try await eventsDispatcher.executeWithRetry(events: combinedEvents)
if success {
logger.debug("Events sent successfully")
logger.debug("Combined events sent successfully")
self.eventsCollector.storage.clearErrorEvents()
self.messageEventsStorage.clearMessageEvents()
}
} catch {
logger.debug("Failed to send events after multiple attempts: \(error)")
Expand All @@ -96,12 +117,17 @@ public class MockEventsClient: EventsClientProtocol {

public func setTopic(_ topic: String) {}

public func saveEvent(_ event: TraceEvent) {
public func saveTraceEvent(_ event: TraceEventItem) {
saveEventCalled = true
}

public func setTelemetryEnabled(_ enabled: Bool) {
telemetryEnabled = enabled
}

public func saveMessageEvent(_ event: MessageEventType) {

}

}
#endif
5 changes: 3 additions & 2 deletions Sources/Events/EventsClientFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ public class EventsClientFactory {
static func create(
projectId: String,
sdkVersion: String,
storage: EventStorage = UserDefaultsEventStorage()
storage: EventStorage = UserDefaultsTraceEventStorage()
) -> EventsClient {
let networkingService = NetworkingService(
projectId: projectId,
Expand All @@ -18,7 +18,8 @@ public class EventsClientFactory {
eventsCollector: eventsCollector,
eventsDispatcher: eventsDispatcher,
logger: logger,
stateStorage: UserDefaultsTelemetryStateStorage()
stateStorage: UserDefaultsTelemetryStateStorage(),
messageEventsStorage: UserDefaultsMessageEventsStorage()
)
}
}
Expand Down
12 changes: 6 additions & 6 deletions Sources/Events/EventsCollector.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import Foundation

// Protocol for TraceEvent
public protocol TraceEvent: CustomStringConvertible {
public protocol TraceEventItem: CustomStringConvertible {
var description: String { get }
}

// Protocol for ErrorEvent
protocol ErrorEvent: TraceEvent {}
protocol ErrorEvent: TraceEventItem {}


class EventsCollector {
Expand Down Expand Up @@ -34,7 +34,7 @@ class EventsCollector {
}

// Function to save event
func saveEvent(_ event: TraceEvent) {
func saveEvent(_ event: TraceEventItem) {
trace.append(event.description)
if let errorEvent = event as? ErrorEvent {
saveErrorEvent(errorEvent)
Expand All @@ -51,14 +51,14 @@ class EventsCollector {
// Private function to save error event
private func saveErrorEvent(_ errorEvent: ErrorEvent) {
let bundleId = Bundle.main.bundleIdentifier ?? "Unknown"
let event = Event(
let event = TraceEvent(
eventId: UUID().uuidString,
bundleId: bundleId,
timestamp: Int64(Date().timeIntervalSince1970 * 1000),
props: Props(
props: TraceEvent.Props(
event: "ERROR",
type: errorEvent.description,
properties: Properties(
properties: TraceEvent.Properties(
topic: topic,
trace: trace
)
Expand Down
2 changes: 1 addition & 1 deletion Sources/Events/EventsDispatcher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class EventsDispatcher {
self.retryPolicy = retryPolicy
}

func executeWithRetry(events: [Event]) async throws -> Bool {
func executeWithRetry<T: Encodable>(events: [T]) async throws -> Bool {
var attempts = 0
var delay = retryPolicy.initialDelay

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

import Foundation

public enum PairingExecutionTraceEvents: String, TraceEvent {
public enum PairingExecutionTraceEvents: String, TraceEventItem {
case pairingUriValidationSuccess = "pairing_uri_validation_success"
case pairingStarted = "pairing_started"
case noWssConnection = "no_wss_connection"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

import Foundation

public enum SessionApproveExecutionTraceEvents: String, TraceEvent {
public enum SessionApproveExecutionTraceEvents: String, TraceEventItem {
case approvingSessionProposal = "approving_session_proposal"
case sessionNamespacesValidationStarted = "session_namespaces_validation_started"
case sessionNamespacesValidationSuccess = "session_namespaces_validation_success"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

import Foundation

public enum SessionAuthenticateTraceEvents: String, TraceEvent {
public enum SessionAuthenticateTraceEvents: String, TraceEventItem {
case signatureVerificationStarted = "signature_verification_started"
case signatureVerificationSuccess = "signature_verification_success"
case requestParamsRetrieved = "request_params_retrieved"
Expand Down
33 changes: 33 additions & 0 deletions Sources/Events/MessageEvent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

import Foundation

struct MessageEvent: Codable {
struct Props: Codable {
let event: String = "SUCCESS"
let type: String
let properties: Properties
}

struct Properties: Codable {
let correlationId: Int64
let clientId: String
let direction: Direction

// Custom CodingKeys to map Swift property names to JSON keys
enum CodingKeys: String, CodingKey {
case correlationId = "correlation_id"
case clientId = "client_id"
case direction
}
}

enum Direction: String, Codable {
case sent
case received
}

let eventId: String
let bundleId: String
let timestamp: Int64
let props: Props
}
62 changes: 62 additions & 0 deletions Sources/Events/MessageEventProperties.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import Foundation

protocol MessageEventsStorage {
func saveMessageEvent(_ eventType: MessageEventType)
func fetchMessageEvents() -> [MessageEvent]
func clearMessageEvents()
}

class UserDefaultsMessageEventsStorage: MessageEventsStorage {
private let messageEventsKey = "com.walletconnect.sdk.messageEvents"
private let maxEvents = 200

func saveMessageEvent(_ eventType: MessageEventType) {
let correlationId = eventType.rpcId.integer
let type = "\(eventType.tag)"
let bundleId = Bundle.main.bundleIdentifier ?? "Unknown"
let clientId = (try? Networking.interactor.getClientId()) ?? "Unknown"

let props = MessageEvent.Props(
type: type,
properties: MessageEvent.Properties(
correlationId: correlationId,
clientId: clientId,
direction: eventType.direction
)
)

let event = MessageEvent(
eventId: UUID().uuidString,
bundleId: bundleId,
timestamp: Int64(Date().timeIntervalSince1970 * 1000),
props: props
)

// Fetch existing events from UserDefaults
var existingEvents = fetchMessageEvents()
existingEvents.append(event)

// Ensure we keep only the last 200 events
if existingEvents.count > maxEvents {
existingEvents = Array(existingEvents.suffix(maxEvents))
}

// Save updated events back to UserDefaults
if let encoded = try? JSONEncoder().encode(existingEvents) {
UserDefaults.standard.set(encoded, forKey: messageEventsKey)
}
}

func fetchMessageEvents() -> [MessageEvent] {
if let data = UserDefaults.standard.data(forKey: messageEventsKey),
let events = try? JSONDecoder().decode([MessageEvent].self, from: data) {
// Return only the last 200 events
return Array(events.suffix(maxEvents))
}
return []
}

func clearMessageEvents() {
UserDefaults.standard.removeObject(forKey: messageEventsKey)
}
}
Loading

0 comments on commit b9246a5

Please sign in to comment.