diff --git a/README.md b/README.md index 58c3d6b..336c29a 100644 --- a/README.md +++ b/README.md @@ -77,10 +77,22 @@ let services: InputData = [ "netflix": .service(Service(activities: ["watch"])), ] + +let style = StylingOptions( + primaryColor: "#7949D1", + backgroundColor: "#fff", + foregroundColor: "#562BA6", + accentColor: "#F4F0FB", +) + +let options = ConnectOptions(style: style) + let input = ConnectInput( publicKey: "yourPublicKey", redirectURL: "https://example.com", - services: services + services: services, + // Optional styling parameter to modify the Connect UI + options: options ) ``` diff --git a/Sources/Example/Example.swift b/Sources/Example/Example.swift index b063bb9..228e5e6 100644 --- a/Sources/Example/Example.swift +++ b/Sources/Example/Example.swift @@ -13,10 +13,13 @@ func testConnect() async { "uber": .service(Service(traits: ["rating"], activities: ["trip"], required: false)), "netflix": .service(Service(activities: ["watch"])), ] + let style = StylingOptions(primaryColor: "#7949D1", backgroundColor: "#fff000", foregroundColor: "#562BA6", accentColor: "#F4F0FB") + let connectOptions = ConnectOptions(style: style) let input = ConnectInput( publicKey: "0x02073d3b9daf439c19a267dcfc19bc1ac1aea5066d8c754554b046476099b6fa22", redirectURL: "https://gandalf.network", - services: services + services: services, + options: connectOptions ) let connect = Connect(input: input) diff --git a/Sources/GandalfConnect/GandalfConnect.swift b/Sources/GandalfConnect/GandalfConnect.swift index 717a393..f0dce30 100644 --- a/Sources/GandalfConnect/GandalfConnect.swift +++ b/Sources/GandalfConnect/GandalfConnect.swift @@ -12,6 +12,28 @@ public struct GandalfError: Error { public let code: GandalfErrorCode } +public struct StylingOptions { + public var primaryColor: String? + public var backgroundColor: String? + public var foregroundColor: String? + public var accentColor: String? + + public init(primaryColor: String? = nil, backgroundColor: String? = nil, foregroundColor: String? = nil, accentColor: String? = nil) { + self.primaryColor = primaryColor + self.backgroundColor = backgroundColor + self.foregroundColor = foregroundColor + self.accentColor = accentColor + } +} + +public struct ConnectOptions { + public var style: StylingOptions + + public init(style: StylingOptions) { + self.style = style + } +} + public struct Service { public var traits: [String]? public var activities: [String]? @@ -35,11 +57,13 @@ public struct ConnectInput { public var publicKey: String public var redirectURL: String public var services: InputData + public var options: ConnectOptions? = nil - public init(publicKey: String, redirectURL: String, services: InputData) { + public init(publicKey: String, redirectURL: String, services: InputData, options: ConnectOptions? = nil) { self.publicKey = publicKey self.redirectURL = redirectURL self.services = services + self.options = options } } @@ -48,18 +72,26 @@ public class Connect { public var redirectURL: String public var data: InputData public var verificationComplete: Bool = false + public var options: ConnectOptions? = nil public init(input: ConnectInput) { self.publicKey = input.publicKey self.redirectURL = input.redirectURL.hasSuffix("/") ? String(input.redirectURL.dropLast()) : input.redirectURL self.data = input.services + self.options = input.options } public func generateURL() async throws -> String { let inputData = data try await allValidations(publicKey: publicKey, redirectURL: redirectURL, data: inputData) + + var inputDataDictionary = self.dataToDictionary(inputData) + + if let style = options?.style { + inputDataDictionary["options"] = styleToDictionary(style) + } - let jsonData = try JSONSerialization.data(withJSONObject: self.dataToDictionary(self.data)) + let jsonData = try JSONSerialization.data(withJSONObject: inputDataDictionary) let dataString = String(data: jsonData, encoding: .utf8) ?? "" print(jsonData) @@ -83,6 +115,23 @@ public class Connect { } return dictionary } + + private func styleToDictionary(_ style: StylingOptions) -> [String: Any] { + var dictionary: [String: Any] = [:] + if let primaryColor = style.primaryColor { + dictionary["primaryColor"] = primaryColor + } + if let backgroundColor = style.backgroundColor { + dictionary["backgroundColor"] = backgroundColor + } + if let foregroundColor = style.foregroundColor { + dictionary["foregroundColor"] = foregroundColor + } + if let accentColor = style.accentColor { + dictionary["accentColor"] = accentColor + } + return dictionary + } private static func getSupportedServicesAndTraits() async throws -> SupportedServicesAndTraits { return try await withCheckedThrowingContinuation { continuation in diff --git a/Tests/GandalfConnectTests/GandalfConnectTests.swift b/Tests/GandalfConnectTests/GandalfConnectTests.swift index fc74726..33a8096 100644 --- a/Tests/GandalfConnectTests/GandalfConnectTests.swift +++ b/Tests/GandalfConnectTests/GandalfConnectTests.swift @@ -18,6 +18,7 @@ final class ConnectTests: XCTestCase { "netflix": .service(Service(traits: ["plan"], activities: ["watch"], required: false)), "instacart": .service(Service(traits: [], activities: ["shop"], required: false)) ] + let styling = StylingOptions(primaryColor: "#7949D1", backgroundColor: "#fff000", foregroundColor: "#562BA6", accentColor: "#F4F0FB") func testInitialization() { let input = ConnectInput(publicKey: publicKey, redirectURL: redirectURL, services: services) @@ -99,6 +100,22 @@ final class ConnectTests: XCTestCase { } } + func testGenerateURLWithStylingOptions() async { + let connectOptions = ConnectOptions(style: styling) + let input = ConnectInput(publicKey: publicKey, redirectURL: redirectURL, services: multipleServices, options: connectOptions) + let connect = Connect(input: input) + + do { + let generatedURL = try await connect.generateURL() + XCTAssertTrue(generatedURL.contains(publicKey)) + XCTAssertTrue(generatedURL.contains(redirectURL)) + } catch let error as GandalfError { + XCTAssertEqual(error.code, .InvalidService) + } catch { + XCTFail("Unexpected error type: \(type(of: error))") + } + } + func testGetDataKeyFromURL() { let url = "https://example.com?dataKey=testDataKey" do {