diff --git a/examples/swift-waku/swift-waku.xcodeproj/project.pbxproj b/examples/swift-waku/swift-waku.xcodeproj/project.pbxproj index 07dcae6b..d8e4c68d 100644 --- a/examples/swift-waku/swift-waku.xcodeproj/project.pbxproj +++ b/examples/swift-waku/swift-waku.xcodeproj/project.pbxproj @@ -8,6 +8,12 @@ /* Begin PBXBuildFile section */ 791190E528047A5900A81D4A /* Gowaku.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 791190E328047A4500A81D4A /* Gowaku.xcframework */; }; + 797CFE202828077C00D0B7E7 /* WakuNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 797CFE1F2828077C00D0B7E7 /* WakuNode.swift */; }; + 797CFE2428285C3100D0B7E7 /* Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = 797CFE2328285C3100D0B7E7 /* Config.swift */; }; + 797CFE2628285C5500D0B7E7 /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = 797CFE2528285C5500D0B7E7 /* Message.swift */; }; + 797CFE2828285C7300D0B7E7 /* DecodedPayload.swift in Sources */ = {isa = PBXBuildFile; fileRef = 797CFE2728285C7300D0B7E7 /* DecodedPayload.swift */; }; + 797CFE2C28285CA700D0B7E7 /* JsonResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 797CFE2B28285CA700D0B7E7 /* JsonResult.swift */; }; + 797CFE3028285CDE00D0B7E7 /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 797CFE2F28285CDE00D0B7E7 /* Response.swift */; }; 798FB3D028046F7F00937EDF /* swift_wakuApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 798FB3CF28046F7F00937EDF /* swift_wakuApp.swift */; }; 798FB3D228046F7F00937EDF /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 798FB3D128046F7F00937EDF /* ContentView.swift */; }; 798FB3D428046F8200937EDF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 798FB3D328046F8200937EDF /* Assets.xcassets */; }; @@ -16,6 +22,12 @@ /* Begin PBXFileReference section */ 791190E328047A4500A81D4A /* Gowaku.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = Gowaku.xcframework; sourceTree = ""; }; + 797CFE1F2828077C00D0B7E7 /* WakuNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WakuNode.swift; sourceTree = ""; }; + 797CFE2328285C3100D0B7E7 /* Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Config.swift; sourceTree = ""; }; + 797CFE2528285C5500D0B7E7 /* Message.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Message.swift; sourceTree = ""; }; + 797CFE2728285C7300D0B7E7 /* DecodedPayload.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DecodedPayload.swift; sourceTree = ""; }; + 797CFE2B28285CA700D0B7E7 /* JsonResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JsonResult.swift; sourceTree = ""; }; + 797CFE2F28285CDE00D0B7E7 /* Response.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Response.swift; sourceTree = ""; }; 798FB3CC28046F7F00937EDF /* swift-waku.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "swift-waku.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 798FB3CF28046F7F00937EDF /* swift_wakuApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = swift_wakuApp.swift; sourceTree = ""; }; 798FB3D128046F7F00937EDF /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; @@ -67,6 +79,12 @@ 798FB3D128046F7F00937EDF /* ContentView.swift */, 798FB3D328046F8200937EDF /* Assets.xcassets */, 798FB3D528046F8200937EDF /* Preview Content */, + 797CFE1F2828077C00D0B7E7 /* WakuNode.swift */, + 797CFE2328285C3100D0B7E7 /* Config.swift */, + 797CFE2528285C5500D0B7E7 /* Message.swift */, + 797CFE2728285C7300D0B7E7 /* DecodedPayload.swift */, + 797CFE2B28285CA700D0B7E7 /* JsonResult.swift */, + 797CFE2F28285CDE00D0B7E7 /* Response.swift */, ); path = "swift-waku"; sourceTree = ""; @@ -149,8 +167,14 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 797CFE3028285CDE00D0B7E7 /* Response.swift in Sources */, + 797CFE202828077C00D0B7E7 /* WakuNode.swift in Sources */, + 797CFE2428285C3100D0B7E7 /* Config.swift in Sources */, + 797CFE2628285C5500D0B7E7 /* Message.swift in Sources */, + 797CFE2828285C7300D0B7E7 /* DecodedPayload.swift in Sources */, 798FB3D228046F7F00937EDF /* ContentView.swift in Sources */, 798FB3D028046F7F00937EDF /* swift_wakuApp.swift in Sources */, + 797CFE2C28285CA700D0B7E7 /* JsonResult.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/examples/swift-waku/swift-waku/Config.swift b/examples/swift-waku/swift-waku/Config.swift new file mode 100644 index 00000000..60893c66 --- /dev/null +++ b/examples/swift-waku/swift-waku/Config.swift @@ -0,0 +1,16 @@ +// +// Config.swift +// swift-waku +// + +import Foundation + +class Config: Codable { + var host: String? = nil; + var result: Int? = nil; + var advertiseAddr: String? = nil; + var nodeKey: String? = nil; + var keepAliveInterval: Int? = nil; + var relay: Bool? = nil; + var minPeersToPublish: Int? = nil; +} diff --git a/examples/swift-waku/swift-waku/ContentView.swift b/examples/swift-waku/swift-waku/ContentView.swift index dde3d892..8709f948 100644 --- a/examples/swift-waku/swift-waku/ContentView.swift +++ b/examples/swift-waku/swift-waku/ContentView.swift @@ -2,8 +2,6 @@ // ContentView.swift // swift-waku // -// Created by Richard Ramos on 11/4/22. -// import SwiftUI import Gowaku diff --git a/examples/swift-waku/swift-waku/DecodedPayload.swift b/examples/swift-waku/swift-waku/DecodedPayload.swift new file mode 100644 index 00000000..7331323d --- /dev/null +++ b/examples/swift-waku/swift-waku/DecodedPayload.swift @@ -0,0 +1,13 @@ +// +// DecodedPayload.swift +// swift-waku +// + +import Foundation + +class DecodedPayload: Codable { + var pubkey: String? + var signature: String? + var data: [UInt8] + var padding: String? +} diff --git a/examples/swift-waku/swift-waku/JsonResult.swift b/examples/swift-waku/swift-waku/JsonResult.swift new file mode 100644 index 00000000..b961b8f6 --- /dev/null +++ b/examples/swift-waku/swift-waku/JsonResult.swift @@ -0,0 +1,11 @@ +// +// JsonResult.swift +// swift-waku +// + +import Foundation + +class JsonResult: Codable { + var error: String? = nil; + var result: T? = nil; +} diff --git a/examples/swift-waku/swift-waku/Message.swift b/examples/swift-waku/swift-waku/Message.swift new file mode 100644 index 00000000..a015596c --- /dev/null +++ b/examples/swift-waku/swift-waku/Message.swift @@ -0,0 +1,30 @@ +// +// Message.swift +// swift-waku +// + +import Foundation +import Gowaku + +class Message: Codable { + var payload: [UInt8] = []; + var contentTopic: String? = ""; + var version: Int? = 0; + var timestamp: Int64? = nil; + + func decodeAsymmetric(_ privateKey: String) throws -> DecodedPayload { + let jsonEncoder = JSONEncoder() + let jsonData = try! jsonEncoder.encode(self) + let jsonMsg = String(data: jsonData, encoding: String.Encoding.utf8) + let response = GowakuDecodeAsymmetric(jsonMsg, privateKey) + return try handleResponse(response) + } + + func decodeSymmetric(symmetricKey: String) throws -> DecodedPayload { + let jsonEncoder = JSONEncoder() + let jsonData = try! jsonEncoder.encode(self) + let jsonMsg = String(data: jsonData, encoding: String.Encoding.utf8) + let response = GowakuDecodeSymmetric(jsonMsg, symmetricKey) + return try handleResponse(response) + } +} diff --git a/examples/swift-waku/swift-waku/Response.swift b/examples/swift-waku/swift-waku/Response.swift new file mode 100644 index 00000000..0460d99c --- /dev/null +++ b/examples/swift-waku/swift-waku/Response.swift @@ -0,0 +1,42 @@ +// +// Response.swift +// swift-waku +// + +import Foundation + +struct WakuError: Error { + let message: String + + init(_ message: String) { + self.message = message + } + + public var localizedDescription: String { + return message + } +} + +func handleResponse(_ response: String) throws -> T { + let decoder = JSONDecoder() + let jsonResult = try! decoder.decode(JsonResult.self, from: response.data(using: .utf8)!) + + if (jsonResult.error != nil) { + throw WakuError(jsonResult.error!) + } + + if (jsonResult.result == nil) { + throw WakuError("no result in response") + } + + return jsonResult.result!; +} + +func handleResponse(_ response: String) throws { + let decoder = JSONDecoder() + let jsonResult = try! decoder.decode(JsonResult.self, from: response.data(using: .utf8)!) + + if jsonResult.error != nil { + throw WakuError("no result in response") + } +} diff --git a/examples/swift-waku/swift-waku/WakuNode.swift b/examples/swift-waku/swift-waku/WakuNode.swift new file mode 100644 index 00000000..c819fb78 --- /dev/null +++ b/examples/swift-waku/swift-waku/WakuNode.swift @@ -0,0 +1,198 @@ +// +// WakuNode.swift +// swift-waku +// + +import Foundation +import Gowaku + +class WakuNode { + var running: Bool = false; + var signalHandler: GowakuSignalHandlerProtocol + + internal class DefaultEventHandler: NSObject, GowakuSignalHandlerProtocol { + func handleSignal(_ signalJson: String?) { + print("TODO: handle signal - " + signalJson!) + /*if (eventHandler != null) { + val evt = Json { + ignoreUnknownKeys = true; coerceInputValues = true + }.decodeFromString(signalJson) + when (evt.type) { + EventType.Message -> { + try { + val msgEvt = Json.decodeFromString(signalJson) + eventHandler.handleEvent(msgEvt) + } catch (e: Exception) { + // TODO: do something + } + } + else -> { + // TODO: do something with invalid message type + } + }*/ + } + } + + init(_ c: Config?) throws { + let jsonEncoder = JSONEncoder() + let jsonData = try! jsonEncoder.encode(c) + let configJson = String(data: jsonData, encoding: String.Encoding.utf8) + let response = GowakuNewNode(configJson) + + try handleResponse(response) + + signalHandler = DefaultEventHandler() + GowakuSetMobileSignalHandler(signalHandler) + } + + func start() throws { + if (running) { + return + } + + let response = GowakuStart() + try handleResponse(response) + running = true + } + + func stop() throws { + if(!running){ + return + } + + let response = GowakuStop() + try handleResponse(response) + running = false + } + + func peerID() throws -> String { + let response = GowakuPeerID() + return try handleResponse(response) + } + + func peerCnt() throws -> Int { + let response = GowakuPeerCnt() + return try handleResponse(response) + } + + func listenAddresses() throws -> [String] { + let response = GowakuListenAddresses() + return try handleResponse(response) + } + + func addPeer(_ address: String, _ protocolID: String) throws -> String { + let response = GowakuAddPeer(address, protocolID) + return try handleResponse(response) + } + + func connect(_ address: String, _ ms: Int = 0) throws { + let response = GowakuConnect(address, ms) + try handleResponse(response) + } + + func disconnect(_ peerID: String) throws { + let response = GowakuDisconnect(peerID) + try handleResponse(response) + } + + func relaySubscribe(_ topic: String? = nil) throws { + let response = GowakuRelaySubscribe(topic) + try handleResponse(response) + } + + func relayPublish(_ msg: Message, _ topic: String? = nil, _ ms: Int = 0) throws -> String { + let jsonEncoder = JSONEncoder() + let jsonData = try! jsonEncoder.encode(msg) + let jsonMsg = String(data: jsonData, encoding: String.Encoding.utf8) + let response = GowakuRelayPublish(jsonMsg, topic, ms) + return try handleResponse(response) + } + + func lightpushPublish(_ msg: Message, _ topic: String? = nil, _ peerID: String? = nil, _ ms: Int = 0) throws -> String { + let jsonEncoder = JSONEncoder() + let jsonData = try! jsonEncoder.encode(msg) + let jsonMsg = String(data: jsonData, encoding: String.Encoding.utf8) + let response = GowakuLightpushPublish(jsonMsg, topic, peerID, ms) + return try handleResponse(response) + } + + func relayPublishEncodeAsymmetric( + _ msg: Message, + _ publicKey: String, + _ optionalSigningKey: String? = nil, + _ topic: String? = nil, + _ ms: Int = 0 + ) throws -> String { + let jsonEncoder = JSONEncoder() + let jsonData = try! jsonEncoder.encode(msg) + let jsonMsg = String(data: jsonData, encoding: String.Encoding.utf8) + let response = GowakuRelayPublishEncodeAsymmetric(jsonMsg, topic, publicKey, optionalSigningKey, ms) + return try handleResponse(response) + } + + func lightpushPublishEncodeAsymmetric( + _ msg: Message, + _ publicKey: String, + _ optionalSigningKey: String? = nil, + _ topic: String? = nil, + _ peerID: String? = nil, + _ ms: Int = 0 + ) throws -> String { + let jsonEncoder = JSONEncoder() + let jsonData = try! jsonEncoder.encode(msg) + let jsonMsg = String(data: jsonData, encoding: String.Encoding.utf8) + let response = GowakuLightpushPublishEncodeAsymmetric(jsonMsg, topic, peerID, publicKey, optionalSigningKey, ms) + return try handleResponse(response) + } + + func relayPublishEncodeSymmetric( + msg: Message, + symmetricKey: String, + optionalSigningKey: String? = nil, + topic: String? = nil, + ms: Int = 0 + ) throws -> String { + let jsonEncoder = JSONEncoder() + let jsonData = try! jsonEncoder.encode(msg) + let jsonMsg = String(data: jsonData, encoding: String.Encoding.utf8) + let response = GowakuRelayPublishEncodeSymmetric(jsonMsg, topic, symmetricKey, optionalSigningKey, ms) + return try handleResponse(response) + } + + func lightpushPublishEncodeSymmetric( + _ msg: Message, + _ symmetricKey: String, + _ optionalSigningKey: String? = nil, + _ topic: String? = nil, + _ peerID: String? = nil, + _ ms: Int = 0 + ) throws -> String { + let jsonEncoder = JSONEncoder() + let jsonData = try! jsonEncoder.encode(msg) + let jsonMsg = String(data: jsonData, encoding: String.Encoding.utf8) + let response = GowakuLightpushPublishEncodeSymmetric(jsonMsg, topic, peerID, symmetricKey, optionalSigningKey, ms) + return try handleResponse(response) + } + + func relayEnoughPeers(_ topic: String? = nil) throws -> Bool { + let response = GowakuRelayEnoughPeers(topic) + return try handleResponse(response) + } + + func relayUnsubscribe(_ topic: String? = nil) throws { + let response = GowakuRelayUnsubscribe(topic) + try handleResponse(response) + } +/* + func peers() throws -> [Peer] { + val response = Gowaku.peers() + return try handleResponse(response) + } + + func storeQuery(_ query: StoreQuery, _ peerID: String?, ms: Int = 0) throws -> StoreResponse { + val queryJSON = Json.encodeToString(query) + val response = Gowaku.storeQuery(queryJSON, peerID, ms) + return handleResponse(response) + }*/ + +} diff --git a/examples/swift-waku/swift-waku/swift_wakuApp.swift b/examples/swift-waku/swift-waku/swift_wakuApp.swift index e3950b20..d0917149 100644 --- a/examples/swift-waku/swift-waku/swift_wakuApp.swift +++ b/examples/swift-waku/swift-waku/swift_wakuApp.swift @@ -2,8 +2,6 @@ // swift_wakuApp.swift // swift-waku // -// Created by Richard Ramos on 11/4/22. -// import SwiftUI @@ -14,4 +12,22 @@ struct swift_wakuApp: App { ContentView() } } + + init(){ + let n: WakuNode = try! WakuNode(nil) + try! n.start() + + try! n.relaySubscribe() + + let msg:Message = Message() + msg.contentTopic = "abc" + msg.timestamp = 1 + msg.version = 0 + msg.payload = [UInt8]("Hello World".utf8) + + let id = try! n.relayPublish(msg) + print(id) + + + } }