diff --git a/android/src/main/java/com/wakureactnative/ReactNativeModule.kt b/android/src/main/java/com/wakureactnative/ReactNativeModule.kt index 4bebaeb..3ffb718 100644 --- a/android/src/main/java/com/wakureactnative/ReactNativeModule.kt +++ b/android/src/main/java/com/wakureactnative/ReactNativeModule.kt @@ -48,7 +48,7 @@ class ReactNativeModule(reactContext: ReactApplicationContext) : ReactContextBas } @ReactMethod - fun newNode(configJSON: String?, promise: Promise) { + fun newNode(configJSON: String = "", promise: Promise) { signalHandler = DefaultEventHandler(reactContext) Gowaku.setMobileSignalHandler(signalHandler) promise.resolve(Gowaku.newNode(configJSON)) @@ -105,28 +105,67 @@ class ReactNativeModule(reactContext: ReactApplicationContext) : ReactContextBas } @ReactMethod - fun relaySubscribe(topic: String?, promise: Promise) { + fun relaySubscribe(topic: String, promise: Promise) { promise.resolve(Gowaku.relaySubscribe(topic)) } @ReactMethod - fun relayPublish(messageJSON: String, topic: String?, ms: Double, promise: Promise) { + fun relayPublish(messageJSON: String, topic: String, ms: Double, promise: Promise) { promise.resolve(Gowaku.relayPublish(messageJSON, topic, ms.toLong())) } -/* -TODO: Create functions for these -extern char* waku_peers(); -extern char* waku_decode_symmetric(char* messageJSON, char* symmetricKey); -extern char* waku_decode_asymmetric(char* messageJSON, char* privateKey); -extern char* waku_lightpush_publish(char* messageJSON, char* topic, char* peerID, int ms); -extern char* waku_lightpush_publish_enc_asymmetric(char* messageJSON, char* topic, char* peerID, char* publicKey, char* optionalSigningKey, int ms); -extern char* waku_lightpush_publish_enc_symmetric(char* messageJSON, char* topic, char* peerID, char* symmetricKey, char* optionalSigningKey, int ms); -extern char* waku_relay_enough_peers(char* topic); -extern char* waku_relay_publish_enc_asymmetric(char* messageJSON, char* topic, char* publicKey, char* optionalSigningKey, int ms); -extern char* waku_relay_publish_enc_symmetric(char* messageJSON, char* topic, char* symmetricKey, char* optionalSigningKey, int ms); -extern char* waku_relay_unsubscribe(char* topic); -extern char* waku_store_query(char* queryJSON, char* peerID, int ms); -*/ + @ReactMethod + fun relayEnoughPeers(topic: String, promise: Promise) { + promise.resolve(Gowaku.relayEnoughPeers(topic)) + } + @ReactMethod + fun relayUnsubscribe(topic: String, promise: Promise) { + promise.resolve(Gowaku.relayUnsubscribe(topic)) + } + + @ReactMethod + fun relayPublishEncodeAsymmetric(messageJSON: String, topic: String, publicKey: String, optionalSigningKey: String = "", ms: Double, promise: Promise) { + promise.resolve(Gowaku.relayPublishEncodeAsymmetric(messageJSON, topic, publicKey, optionalSigningKey, ms.toLong())) + } + + @ReactMethod + fun relayPublishEncodeSymmetric(messageJSON: String, topic: String, symmetricKey: String, optionalSigningKey: String = "", ms: Double, promise: Promise) { + promise.resolve(Gowaku.relayPublishEncodeSymmetric(messageJSON, topic, symmetricKey, optionalSigningKey, ms.toLong())) + } + + @ReactMethod + fun peers(promise: Promise) { + promise.resolve(Gowaku.peers()) + } + + @ReactMethod + fun lightpushPublish(messageJSON: String, topic: String, peerID: String = "", ms: Double, promise: Promise) { + promise.resolve(Gowaku.lightpushPublish(messageJSON, topic, peerID, ms.toLong())) + } + + @ReactMethod + fun lightpushPublishEncodeAsymmetric(messageJSON: String, topic: String, peerID: String = "", publicKey: String = "", optionalSigningKey: String = "", ms: Double, promise: Promise) { + promise.resolve(Gowaku.lightpushPublishEncodeAsymmetric(messageJSON, topic, peerID, publicKey, optionalSigningKey, ms.toLong())) + } + + @ReactMethod + fun lightpushPublishEncodeSymmetric(messageJSON: String, topic: String, peerID: String = "", symmetricKey: String = "", optionalSigningKey: String = "", ms: Double, promise: Promise) { + promise.resolve(Gowaku.lightpushPublishEncodeSymmetric(messageJSON, topic, peerID, symmetricKey, optionalSigningKey, ms.toLong())) + } + + @ReactMethod + fun decodeSymmetric(messageJSON: String, symmetricKey: String, promise: Promise) { + promise.resolve(Gowaku.decodeSymmetric(messageJSON, symmetricKey)) + } + + @ReactMethod + fun decodeAsymmetric(messageJSON: String, privateKey: String, promise: Promise) { + promise.resolve(Gowaku.decodeAsymmetric(messageJSON, privateKey)) + } + + @ReactMethod + fun storeQuery(queryJSON: String, peerID: String = "", ms: Double, promise: Promise) { + promise.resolve(Gowaku.storeQuery(queryJSON, peerID, ms.toLong())) + } } diff --git a/package.json b/package.json index c8a5e97..51f4636 100644 --- a/package.json +++ b/package.json @@ -142,5 +142,8 @@ } ] ] + }, + "dependencies": { + "base-64": "^1.0.0" } } diff --git a/src/index.tsx b/src/index.tsx index 3708d88..b62e374 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,4 +1,5 @@ import { NativeModules, Platform, NativeEventEmitter } from 'react-native'; +import {decode, encode} from 'base-64' const LINKING_ERROR = `The package '@waku/react-native' doesn't seem to be linked. Make sure: \n\n` + @@ -26,8 +27,7 @@ export class WakuMessage { timestamp: Number | null = null; toJSON(){ - var decoder = new TextDecoder('utf8'); - var b64encoded = btoa(decoder.decode(this.payload)); + const b64encoded = encode(String.fromCharCode(...this.payload)); return { contentTopic: this.contentTopic, version: this.version, @@ -37,26 +37,32 @@ export class WakuMessage { } } -export function onMessage(cb) { - // TODO: - let eventListener = eventEmitter.addListener("message", event => { +export function onMessage(cb: (arg0:any) => void) { + eventEmitter.addListener("message", event => { let signal = JSON.parse(event.signal); let msg = signal.event.wakuMessage; - console.log(msg); signal.event.wakuMessage = new WakuMessage(); signal.event.wakuMessage.timestamp = msg.timestamp; signal.event.wakuMessage.version = msg.version || 0; signal.event.wakuMessage.contentTopic = msg.contentTopic; - signal.event.wakuMessage.payload = new Uint8Array(atob(msg.payload).split("").map(c => c.charCodeAt(0))); + signal.event.wakuMessage.payload = new Uint8Array(decode(msg.payload).split("").map((c:any) => c.charCodeAt(0))); cb(signal); }) } -export function newNode(): Promise { +export class Config { + host: String | null = null + port: Number | null = null + advertiseAddr: String | null = null + nodeKey: String | null = null + keepAliveInterval: Number | null = null + relay: Boolean | null = null + minPeersToPublish: Number | null = null +} + +export function newNode(config: Config | null): Promise { return new Promise(async (resolve, reject) => { - // TODO: - let config = null - let response = JSON.parse(await ReactNative.newNode(config)); + let response = JSON.parse(await ReactNative.newNode(config ? JSON.stringify(config) : "")); if(response.error){ reject(response.error); } else { @@ -98,7 +104,7 @@ export function peerID(): Promise { }); } -export function relayPublish(msg: WakuMessage, topic: String | null = null, ms: Number = 0): Promise { +export function relayPublish(msg: WakuMessage, topic: String = "", ms: Number = 0): Promise { return new Promise(async (resolve, reject) => { let messageJSON = JSON.stringify(msg) let response = JSON.parse(await ReactNative.relayPublish(messageJSON, topic, ms)); @@ -110,7 +116,31 @@ export function relayPublish(msg: WakuMessage, topic: String | null = null, ms: }); } -export function relaySubscribe(topic: String | null = null): Promise { +export function relayPublishEncodeAsymmetric(msg: WakuMessage, publicKey: String, topic: String = "", ms: Number = 0): Promise { + return new Promise(async (resolve, reject) => { + let messageJSON = JSON.stringify(msg) + let response = JSON.parse(await ReactNative.relayPublishEncodeAsymmetric(messageJSON, topic, publicKey, ms)); + if(response.error){ + reject(response.error); + } else { + resolve(response.result); + } + }); +} + +export function relayPublishEncodeSymmetric(msg: WakuMessage, symmetricKey: String, topic: String = "", ms: Number = 0): Promise { + return new Promise(async (resolve, reject) => { + let messageJSON = JSON.stringify(msg) + let response = JSON.parse(await ReactNative.relayPublishEncodeAsymmetric(messageJSON, topic, symmetricKey, ms)); + if(response.error){ + reject(response.error); + } else { + resolve(response.result); + } + }); +} + +export function relaySubscribe(topic: String = ""): Promise { return new Promise(async (resolve, reject) => { let response = JSON.parse(await ReactNative.relaySubscribe(topic)); if(response.error){ @@ -125,20 +155,185 @@ export function defaultPubsubTopic(): Promise { return ReactNative.defaultPubsubTopic(); } -// TODO: listenAddresses -// TODO: addPeer -// TODO: connect -// TODO: connectPeerID -// TODO: disconnect -// TODO: peerCnt +export function listenAddresses(): Promise> { + return new Promise>(async (resolve, reject) => { + let response = JSON.parse(await ReactNative.listenAddresses()); + if(response.error){ + reject(response.error); + } else { + resolve(response.result); + } + }); +} + +export function addPeer(multiAddress: String, protocol: String): Promise { + return new Promise(async (resolve, reject) => { + let response = JSON.parse(await ReactNative.addPeer(multiAddress, protocol)); + if(response.error){ + reject(response.error); + } else { + resolve(response.result); + } + }); +} + +export function connect(multiAddress: String): Promise { + return new Promise(async (resolve, reject) => { + let response = JSON.parse(await ReactNative.connect(multiAddress)); + if(response.error){ + reject(response.error); + } else { + resolve(); + } + }); +} + +export function connectPeerID(peerID: String): Promise { + return new Promise(async (resolve, reject) => { + let response = JSON.parse(await ReactNative.connectPeerID(peerID)); + if(response.error){ + reject(response.error); + } else { + resolve(); + } + }); +} + +export function disconnect(peerID: String): Promise { + return new Promise(async (resolve, reject) => { + let response = JSON.parse(await ReactNative.disconnect(peerID)); + if(response.error){ + reject(response.error); + } else { + resolve(); + } + }); +} + +export function peerCnt(): Promise { + return new Promise(async (resolve, reject) => { + let response = JSON.parse(await ReactNative.peerCnt()); + if(response.error){ + reject(response.error); + } else { + resolve(response.result); + } + }); +} + +export class DecodedPayload { + payload: Uint8Array = new Uint8Array(); + padding: Uint8Array = new Uint8Array(); + pubkey: String | null = ""; + signature: String | null = ""; + + toJSON(){ + const b64payload = encode(String.fromCharCode(...this.payload)); + const b64padding = encode(String.fromCharCode(...this.padding)); + return { + payload: b64payload, + padding: b64padding, + pubkey: this.pubkey, + signature: this.signature, + } + } +} + +export function decodeSymmetric(msg: WakuMessage, symmetricKey: String): Promise { + return new Promise(async (resolve, reject) => { + let messageJSON = JSON.stringify(msg); + let response = JSON.parse(await ReactNative.decodeSymmetric(messageJSON, symmetricKey)); + if(response.error){ + reject(response.error); + } else { + let decodedPayload = new DecodedPayload(); + decodedPayload.payload = new Uint8Array(atob(response.result.payload).split("").map(c => c.charCodeAt(0))); + decodedPayload.padding = new Uint8Array(atob(response.result.padding).split("").map(c => c.charCodeAt(0))); + decodedPayload.pubkey = response.result.pubkey; + decodedPayload.signature = response.result.signature; + resolve(decodedPayload); + } + }); +} + +export function decodeAsymmetric(msg: WakuMessage, privateKey: String): Promise { + return new Promise(async (resolve, reject) => { + let messageJSON = JSON.stringify(msg); + let response = JSON.parse(await ReactNative.decodeSymmetric(messageJSON, privateKey)); + if(response.error){ + reject(response.error); + } else { + let decodedPayload = new DecodedPayload(); + decodedPayload.payload = new Uint8Array(atob(response.result.payload).split("").map(c => c.charCodeAt(0))); + decodedPayload.padding = new Uint8Array(atob(response.result.padding).split("").map(c => c.charCodeAt(0))); + decodedPayload.pubkey = response.result.pubkey; + decodedPayload.signature = response.result.signature; + resolve(decodedPayload); + } + }); +} + +export function relayEnoughPeers(topic: String = ""): Promise { + return new Promise(async (resolve, reject) => { + let response = JSON.parse(await ReactNative.relayEnoughPeers(topic)); + if(response.error){ + reject(response.error); + } else { + resolve(response.result); + } + }); +} + +export function relayUnsubscribe(topic: String = ""): Promise { + return new Promise(async (resolve, reject) => { + let response = JSON.parse(await ReactNative.relayUnsubscribe(topic)); + if(response.error){ + reject(response.error); + } else { + resolve(response.result); + } + }); +} + +export function lightpushPublish(msg: WakuMessage, topic: String = "", peerID: String = "", ms: Number = 0): Promise { + return new Promise(async (resolve, reject) => { + let messageJSON = JSON.stringify(msg) + let response = JSON.parse(await ReactNative.relayPublish(messageJSON, topic, peerID, ms)); + if(response.error){ + reject(response.error); + } else { + resolve(response.result); + } + }); +} + +export function lightpushPublishEncAsymmetric(msg: WakuMessage, publicKey: String, topic: String = "", peerID: String = "", ms: Number = 0): Promise { + return new Promise(async (resolve, reject) => { + let messageJSON = JSON.stringify(msg) + let response = JSON.parse(await ReactNative.relayPublishEncodeAsymmetric(messageJSON, topic, peerID, publicKey, ms)); + if(response.error){ + reject(response.error); + } else { + resolve(response.result); + } + }); +} + +export function lightpushPublishEncSymmetric(msg: WakuMessage, symmetricKey: String, topic: String = "", peerID: String = "", ms: Number = 0): Promise { + return new Promise(async (resolve, reject) => { + let messageJSON = JSON.stringify(msg) + let response = JSON.parse(await ReactNative.relayPublishEncodeAsymmetric(messageJSON, topic, peerID, symmetricKey, ms)); + if(response.error){ + reject(response.error); + } else { + resolve(response.result); + } + }); +} + + + + + // TODO: peers -// TODO: decodeSymmetric -// TODO: decodeAsymmetric -// TODO: lightpushPublish -// TODO: lightpushPublishEncAsymmetric -// TODO: lightpushPublishEncSymmetric -// TODO: relayEnoughPeers -// TODO: relayPublishEncAsymmetric -// TODO: relayPublishEncSymmetric -// TODO: relayUnsubscribe // TODO: relayStoreQuery diff --git a/tsconfig.json b/tsconfig.json index 93cdb1f..f8db0b7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,7 +10,7 @@ "importsNotUsedAsValues": "error", "forceConsistentCasingInFileNames": true, "jsx": "react", - "lib": ["esnext"], + "lib": ["esnext", "dom", "es2017"], "module": "esnext", "moduleResolution": "node", "noFallthroughCasesInSwitch": true, diff --git a/yarn.lock b/yarn.lock index 3939c01..b54f1f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2556,6 +2556,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base-64@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/base-64/-/base-64-1.0.0.tgz#09d0f2084e32a3fd08c2475b973788eee6ae8f4a" + integrity sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg== + base64-js@^1.1.2, base64-js@^1.3.1, base64-js@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"