diff --git a/android/build.gradle b/android/build.gradle index df5fa58bd..76851acaf 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -90,4 +90,6 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}" implementation "org.xmtp:android:0.3.0" implementation 'com.google.code.gson:gson:2.10.1' + implementation 'com.facebook.react:react-native:0.71.3' + implementation "com.daveanthonythomas.moshipack:moshipack:1.0.1" } diff --git a/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt b/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt index c5dcf90e8..9ac1fb62a 100644 --- a/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt +++ b/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt @@ -9,6 +9,7 @@ import expo.modules.kotlin.modules.ModuleDefinition import expo.modules.xmtpreactnativesdk.wrappers.ConversationWithClientAddress import expo.modules.xmtpreactnativesdk.wrappers.ConversationWrapper import expo.modules.xmtpreactnativesdk.wrappers.DecodedMessageWrapper +import expo.modules.xmtpreactnativesdk.wrappers.EncodedMessageWrapper import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -26,8 +27,9 @@ import org.xmtp.android.library.messages.PrivateKeyBuilder import org.xmtp.android.library.messages.Signature import org.xmtp.android.library.push.XMTPPush import org.xmtp.proto.keystore.api.v1.Keystore.TopicMap.TopicData -import org.xmtp.proto.message.contents.SignatureOuterClass +import org.xmtp.proto.message.contents.Content.EncodedContent import org.xmtp.proto.message.contents.PrivateKeyOuterClass +import org.xmtp.proto.message.contents.SignatureOuterClass import java.util.Date import java.util.UUID import kotlin.coroutines.Continuation @@ -192,12 +194,11 @@ class XMTPModule : Module() { val afterDate = if (after != null) Date(after) else null client.conversations.listBatchMessages(topics, limit, beforeDate, afterDate).map { - DecodedMessageWrapper.encode(it) + EncodedMessageWrapper.encode(it) } } - // TODO: Support content types - AsyncFunction("sendMessage") { clientAddress: String, conversationTopic: String, conversationID: String?, content: String -> + AsyncFunction("sendEncodedContentData") { clientAddress: String, conversationTopic: String, conversationID: String?, content: List -> logV("sendMessage") val conversation = findConversation( @@ -205,10 +206,17 @@ class XMTPModule : Module() { topic = conversationTopic ) ?: throw XMTPException("no conversation found for $conversationTopic") - val preparedMessage = conversation.prepareMessage(content = content) - val decodedMessage = preparedMessage.decodedMessage() - preparedMessage.send() - DecodedMessageWrapper.encode(decodedMessage) + + val contentData = content.foldIndexed(ByteArray(content.size)) { i, a, v -> + a.apply { + set( + i, + v.toByte() + ) + } + } + val encodedContent = EncodedContent.parseFrom(contentData) + conversation.send(encodedContent = encodedContent) } AsyncFunction("createConversation") { clientAddress: String, peerAddress: String, conversationID: String? -> diff --git a/android/src/main/java/expo/modules/xmtpreactnativesdk/wrappers/EncodeMessageWrapper.kt b/android/src/main/java/expo/modules/xmtpreactnativesdk/wrappers/EncodeMessageWrapper.kt new file mode 100644 index 000000000..788313fb2 --- /dev/null +++ b/android/src/main/java/expo/modules/xmtpreactnativesdk/wrappers/EncodeMessageWrapper.kt @@ -0,0 +1,27 @@ +package expo.modules.xmtpreactnativesdk.wrappers + +import com.daveanthonythomas.moshipack.MoshiPack +import com.facebook.react.bridge.ReadableArray +import com.facebook.react.bridge.WritableNativeArray +import org.xmtp.android.library.DecodedMessage + +class EncodedMessageWrapper { + + companion object { + fun encode(model: DecodedMessage): ReadableArray { + val message = mapOf( + "id" to model.id, + "content" to model.encodedContent.toByteArray(), + "senderAddress" to model.senderAddress.toByteArray(), + "sent" to model.sent.time.toString() + ) + val encodedContent = MoshiPack().pack(message).readByteArray() + + val byteArray = WritableNativeArray() + encodedContent.forEach { + byteArray.pushString(it.toString()) + } + return byteArray + } + } +} \ No newline at end of file diff --git a/example/babel.config.js b/example/babel.config.js index 97f936651..aeb96c181 100644 --- a/example/babel.config.js +++ b/example/babel.config.js @@ -1,19 +1,25 @@ -const path = require('path'); +const path = require("path"); module.exports = function (api) { api.cache(true); return { - presets: ['babel-preset-expo'], + presets: ["babel-preset-expo"], plugins: [ [ - 'module-resolver', + "module-resolver", { - extensions: ['.tsx', '.ts', '.js', '.json'], + extensions: [".tsx", ".ts", ".js", ".json"], alias: { // For development, we want to alias the library to the source - 'xmtp-react-native-sdk': path.join(__dirname, '..', 'src', 'index.ts'), + "xmtp-react-native-sdk": path.join( + __dirname, + "..", + "src", + "index.ts" + ), }, }, ], + "@babel/plugin-proposal-export-namespace-from", ], }; }; diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 1cde23f59..9fa4c7951 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -18,33 +18,34 @@ PODS: - ExpoModulesCore - EXFont (11.1.1): - ExpoModulesCore - - Expo (48.0.17): + - Expo (48.0.11): - ExpoModulesCore - ExpoKeepAwake (12.0.1): - ExpoModulesCore - - ExpoModulesCore (1.2.7): + - ExpoModulesCore (1.2.6): - React-Core - React-RCTAppDelegate - ReactCommon/turbomodule/core - EXSecureStore (12.1.1): - ExpoModulesCore - - FBLazyVector (0.71.8) - - FBReactNativeSpec (0.71.8): + - FBLazyVector (0.71.6) + - FBReactNativeSpec (0.71.6): - RCT-Folly (= 2021.07.22.00) - - RCTRequired (= 0.71.8) - - RCTTypeSafety (= 0.71.8) - - React-Core (= 0.71.8) - - React-jsi (= 0.71.8) - - ReactCommon/turbomodule/core (= 0.71.8) + - RCTRequired (= 0.71.6) + - RCTTypeSafety (= 0.71.6) + - React-Core (= 0.71.6) + - React-jsi (= 0.71.6) + - ReactCommon/turbomodule/core (= 0.71.6) - fmt (6.2.1) - GenericJSON (2.0.2) - glog (0.3.5) - GzipSwift (5.1.1) - - hermes-engine (0.71.8): - - hermes-engine/Pre-built (= 0.71.8) - - hermes-engine/Pre-built (0.71.8) + - hermes-engine (0.71.6): + - hermes-engine/Pre-built (= 0.71.6) + - hermes-engine/Pre-built (0.71.6) - libevent (2.1.12) - Logging (1.0.0) + - MessagePacker (0.4.7) - MMKV (1.3.0): - MMKVCore (~> 1.3.0) - MMKVCore (1.3.0) @@ -65,26 +66,26 @@ PODS: - fmt (~> 6.2.1) - glog - libevent - - RCTRequired (0.71.8) - - RCTTypeSafety (0.71.8): - - FBLazyVector (= 0.71.8) - - RCTRequired (= 0.71.8) - - React-Core (= 0.71.8) - - React (0.71.8): - - React-Core (= 0.71.8) - - React-Core/DevSupport (= 0.71.8) - - React-Core/RCTWebSocket (= 0.71.8) - - React-RCTActionSheet (= 0.71.8) - - React-RCTAnimation (= 0.71.8) - - React-RCTBlob (= 0.71.8) - - React-RCTImage (= 0.71.8) - - React-RCTLinking (= 0.71.8) - - React-RCTNetwork (= 0.71.8) - - React-RCTSettings (= 0.71.8) - - React-RCTText (= 0.71.8) - - React-RCTVibration (= 0.71.8) - - React-callinvoker (0.71.8) - - React-Codegen (0.71.8): + - RCTRequired (0.71.6) + - RCTTypeSafety (0.71.6): + - FBLazyVector (= 0.71.6) + - RCTRequired (= 0.71.6) + - React-Core (= 0.71.6) + - React (0.71.6): + - React-Core (= 0.71.6) + - React-Core/DevSupport (= 0.71.6) + - React-Core/RCTWebSocket (= 0.71.6) + - React-RCTActionSheet (= 0.71.6) + - React-RCTAnimation (= 0.71.6) + - React-RCTBlob (= 0.71.6) + - React-RCTImage (= 0.71.6) + - React-RCTLinking (= 0.71.6) + - React-RCTNetwork (= 0.71.6) + - React-RCTSettings (= 0.71.6) + - React-RCTText (= 0.71.6) + - React-RCTVibration (= 0.71.6) + - React-callinvoker (0.71.6) + - React-Codegen (0.71.6): - FBReactNativeSpec - hermes-engine - RCT-Folly @@ -95,209 +96,209 @@ PODS: - React-jsiexecutor - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - React-Core (0.71.8): + - React-Core (0.71.6): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - - React-Core/Default (= 0.71.8) - - React-cxxreact (= 0.71.8) + - React-Core/Default (= 0.71.6) + - React-cxxreact (= 0.71.6) - React-hermes - - React-jsi (= 0.71.8) - - React-jsiexecutor (= 0.71.8) - - React-perflogger (= 0.71.8) + - React-jsi (= 0.71.6) + - React-jsiexecutor (= 0.71.6) + - React-perflogger (= 0.71.6) - Yoga - - React-Core/CoreModulesHeaders (0.71.8): + - React-Core/CoreModulesHeaders (0.71.6): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.71.8) + - React-cxxreact (= 0.71.6) - React-hermes - - React-jsi (= 0.71.8) - - React-jsiexecutor (= 0.71.8) - - React-perflogger (= 0.71.8) + - React-jsi (= 0.71.6) + - React-jsiexecutor (= 0.71.6) + - React-perflogger (= 0.71.6) - Yoga - - React-Core/Default (0.71.8): + - React-Core/Default (0.71.6): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - - React-cxxreact (= 0.71.8) + - React-cxxreact (= 0.71.6) - React-hermes - - React-jsi (= 0.71.8) - - React-jsiexecutor (= 0.71.8) - - React-perflogger (= 0.71.8) + - React-jsi (= 0.71.6) + - React-jsiexecutor (= 0.71.6) + - React-perflogger (= 0.71.6) - Yoga - - React-Core/DevSupport (0.71.8): + - React-Core/DevSupport (0.71.6): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - - React-Core/Default (= 0.71.8) - - React-Core/RCTWebSocket (= 0.71.8) - - React-cxxreact (= 0.71.8) + - React-Core/Default (= 0.71.6) + - React-Core/RCTWebSocket (= 0.71.6) + - React-cxxreact (= 0.71.6) - React-hermes - - React-jsi (= 0.71.8) - - React-jsiexecutor (= 0.71.8) - - React-jsinspector (= 0.71.8) - - React-perflogger (= 0.71.8) + - React-jsi (= 0.71.6) + - React-jsiexecutor (= 0.71.6) + - React-jsinspector (= 0.71.6) + - React-perflogger (= 0.71.6) - Yoga - - React-Core/RCTActionSheetHeaders (0.71.8): + - React-Core/RCTActionSheetHeaders (0.71.6): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.71.8) + - React-cxxreact (= 0.71.6) - React-hermes - - React-jsi (= 0.71.8) - - React-jsiexecutor (= 0.71.8) - - React-perflogger (= 0.71.8) + - React-jsi (= 0.71.6) + - React-jsiexecutor (= 0.71.6) + - React-perflogger (= 0.71.6) - Yoga - - React-Core/RCTAnimationHeaders (0.71.8): + - React-Core/RCTAnimationHeaders (0.71.6): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.71.8) + - React-cxxreact (= 0.71.6) - React-hermes - - React-jsi (= 0.71.8) - - React-jsiexecutor (= 0.71.8) - - React-perflogger (= 0.71.8) + - React-jsi (= 0.71.6) + - React-jsiexecutor (= 0.71.6) + - React-perflogger (= 0.71.6) - Yoga - - React-Core/RCTBlobHeaders (0.71.8): + - React-Core/RCTBlobHeaders (0.71.6): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.71.8) + - React-cxxreact (= 0.71.6) - React-hermes - - React-jsi (= 0.71.8) - - React-jsiexecutor (= 0.71.8) - - React-perflogger (= 0.71.8) + - React-jsi (= 0.71.6) + - React-jsiexecutor (= 0.71.6) + - React-perflogger (= 0.71.6) - Yoga - - React-Core/RCTImageHeaders (0.71.8): + - React-Core/RCTImageHeaders (0.71.6): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.71.8) + - React-cxxreact (= 0.71.6) - React-hermes - - React-jsi (= 0.71.8) - - React-jsiexecutor (= 0.71.8) - - React-perflogger (= 0.71.8) + - React-jsi (= 0.71.6) + - React-jsiexecutor (= 0.71.6) + - React-perflogger (= 0.71.6) - Yoga - - React-Core/RCTLinkingHeaders (0.71.8): + - React-Core/RCTLinkingHeaders (0.71.6): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.71.8) + - React-cxxreact (= 0.71.6) - React-hermes - - React-jsi (= 0.71.8) - - React-jsiexecutor (= 0.71.8) - - React-perflogger (= 0.71.8) + - React-jsi (= 0.71.6) + - React-jsiexecutor (= 0.71.6) + - React-perflogger (= 0.71.6) - Yoga - - React-Core/RCTNetworkHeaders (0.71.8): + - React-Core/RCTNetworkHeaders (0.71.6): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.71.8) + - React-cxxreact (= 0.71.6) - React-hermes - - React-jsi (= 0.71.8) - - React-jsiexecutor (= 0.71.8) - - React-perflogger (= 0.71.8) + - React-jsi (= 0.71.6) + - React-jsiexecutor (= 0.71.6) + - React-perflogger (= 0.71.6) - Yoga - - React-Core/RCTSettingsHeaders (0.71.8): + - React-Core/RCTSettingsHeaders (0.71.6): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.71.8) + - React-cxxreact (= 0.71.6) - React-hermes - - React-jsi (= 0.71.8) - - React-jsiexecutor (= 0.71.8) - - React-perflogger (= 0.71.8) + - React-jsi (= 0.71.6) + - React-jsiexecutor (= 0.71.6) + - React-perflogger (= 0.71.6) - Yoga - - React-Core/RCTTextHeaders (0.71.8): + - React-Core/RCTTextHeaders (0.71.6): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.71.8) + - React-cxxreact (= 0.71.6) - React-hermes - - React-jsi (= 0.71.8) - - React-jsiexecutor (= 0.71.8) - - React-perflogger (= 0.71.8) + - React-jsi (= 0.71.6) + - React-jsiexecutor (= 0.71.6) + - React-perflogger (= 0.71.6) - Yoga - - React-Core/RCTVibrationHeaders (0.71.8): + - React-Core/RCTVibrationHeaders (0.71.6): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.71.8) + - React-cxxreact (= 0.71.6) - React-hermes - - React-jsi (= 0.71.8) - - React-jsiexecutor (= 0.71.8) - - React-perflogger (= 0.71.8) + - React-jsi (= 0.71.6) + - React-jsiexecutor (= 0.71.6) + - React-perflogger (= 0.71.6) - Yoga - - React-Core/RCTWebSocket (0.71.8): + - React-Core/RCTWebSocket (0.71.6): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - - React-Core/Default (= 0.71.8) - - React-cxxreact (= 0.71.8) + - React-Core/Default (= 0.71.6) + - React-cxxreact (= 0.71.6) - React-hermes - - React-jsi (= 0.71.8) - - React-jsiexecutor (= 0.71.8) - - React-perflogger (= 0.71.8) + - React-jsi (= 0.71.6) + - React-jsiexecutor (= 0.71.6) + - React-perflogger (= 0.71.6) - Yoga - - React-CoreModules (0.71.8): + - React-CoreModules (0.71.6): - RCT-Folly (= 2021.07.22.00) - - RCTTypeSafety (= 0.71.8) - - React-Codegen (= 0.71.8) - - React-Core/CoreModulesHeaders (= 0.71.8) - - React-jsi (= 0.71.8) + - RCTTypeSafety (= 0.71.6) + - React-Codegen (= 0.71.6) + - React-Core/CoreModulesHeaders (= 0.71.6) + - React-jsi (= 0.71.6) - React-RCTBlob - - React-RCTImage (= 0.71.8) - - ReactCommon/turbomodule/core (= 0.71.8) - - React-cxxreact (0.71.8): + - React-RCTImage (= 0.71.6) + - ReactCommon/turbomodule/core (= 0.71.6) + - React-cxxreact (0.71.6): - boost (= 1.76.0) - DoubleConversion - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - - React-callinvoker (= 0.71.8) - - React-jsi (= 0.71.8) - - React-jsinspector (= 0.71.8) - - React-logger (= 0.71.8) - - React-perflogger (= 0.71.8) - - React-runtimeexecutor (= 0.71.8) - - React-hermes (0.71.8): + - React-callinvoker (= 0.71.6) + - React-jsi (= 0.71.6) + - React-jsinspector (= 0.71.6) + - React-logger (= 0.71.6) + - React-perflogger (= 0.71.6) + - React-runtimeexecutor (= 0.71.6) + - React-hermes (0.71.6): - DoubleConversion - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - RCT-Folly/Futures (= 2021.07.22.00) - - React-cxxreact (= 0.71.8) + - React-cxxreact (= 0.71.6) - React-jsi - - React-jsiexecutor (= 0.71.8) - - React-jsinspector (= 0.71.8) - - React-perflogger (= 0.71.8) - - React-jsi (0.71.8): + - React-jsiexecutor (= 0.71.6) + - React-jsinspector (= 0.71.6) + - React-perflogger (= 0.71.6) + - React-jsi (0.71.6): - boost (= 1.76.0) - DoubleConversion - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - - React-jsiexecutor (0.71.8): + - React-jsiexecutor (0.71.6): - DoubleConversion - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - - React-cxxreact (= 0.71.8) - - React-jsi (= 0.71.8) - - React-perflogger (= 0.71.8) - - React-jsinspector (0.71.8) - - React-logger (0.71.8): + - React-cxxreact (= 0.71.6) + - React-jsi (= 0.71.6) + - React-perflogger (= 0.71.6) + - React-jsinspector (0.71.6) + - React-logger (0.71.6): - glog - react-native-get-random-values (1.8.0): - React-Core @@ -312,90 +313,90 @@ PODS: - RCTTypeSafety - React-Core - ReactCommon/turbomodule/core - - React-perflogger (0.71.8) - - React-RCTActionSheet (0.71.8): - - React-Core/RCTActionSheetHeaders (= 0.71.8) - - React-RCTAnimation (0.71.8): + - React-perflogger (0.71.6) + - React-RCTActionSheet (0.71.6): + - React-Core/RCTActionSheetHeaders (= 0.71.6) + - React-RCTAnimation (0.71.6): - RCT-Folly (= 2021.07.22.00) - - RCTTypeSafety (= 0.71.8) - - React-Codegen (= 0.71.8) - - React-Core/RCTAnimationHeaders (= 0.71.8) - - React-jsi (= 0.71.8) - - ReactCommon/turbomodule/core (= 0.71.8) - - React-RCTAppDelegate (0.71.8): + - RCTTypeSafety (= 0.71.6) + - React-Codegen (= 0.71.6) + - React-Core/RCTAnimationHeaders (= 0.71.6) + - React-jsi (= 0.71.6) + - ReactCommon/turbomodule/core (= 0.71.6) + - React-RCTAppDelegate (0.71.6): - RCT-Folly - RCTRequired - RCTTypeSafety - React-Core - ReactCommon/turbomodule/core - - React-RCTBlob (0.71.8): + - React-RCTBlob (0.71.6): - hermes-engine - RCT-Folly (= 2021.07.22.00) - - React-Codegen (= 0.71.8) - - React-Core/RCTBlobHeaders (= 0.71.8) - - React-Core/RCTWebSocket (= 0.71.8) - - React-jsi (= 0.71.8) - - React-RCTNetwork (= 0.71.8) - - ReactCommon/turbomodule/core (= 0.71.8) - - React-RCTImage (0.71.8): + - React-Codegen (= 0.71.6) + - React-Core/RCTBlobHeaders (= 0.71.6) + - React-Core/RCTWebSocket (= 0.71.6) + - React-jsi (= 0.71.6) + - React-RCTNetwork (= 0.71.6) + - ReactCommon/turbomodule/core (= 0.71.6) + - React-RCTImage (0.71.6): - RCT-Folly (= 2021.07.22.00) - - RCTTypeSafety (= 0.71.8) - - React-Codegen (= 0.71.8) - - React-Core/RCTImageHeaders (= 0.71.8) - - React-jsi (= 0.71.8) - - React-RCTNetwork (= 0.71.8) - - ReactCommon/turbomodule/core (= 0.71.8) - - React-RCTLinking (0.71.8): - - React-Codegen (= 0.71.8) - - React-Core/RCTLinkingHeaders (= 0.71.8) - - React-jsi (= 0.71.8) - - ReactCommon/turbomodule/core (= 0.71.8) - - React-RCTNetwork (0.71.8): + - RCTTypeSafety (= 0.71.6) + - React-Codegen (= 0.71.6) + - React-Core/RCTImageHeaders (= 0.71.6) + - React-jsi (= 0.71.6) + - React-RCTNetwork (= 0.71.6) + - ReactCommon/turbomodule/core (= 0.71.6) + - React-RCTLinking (0.71.6): + - React-Codegen (= 0.71.6) + - React-Core/RCTLinkingHeaders (= 0.71.6) + - React-jsi (= 0.71.6) + - ReactCommon/turbomodule/core (= 0.71.6) + - React-RCTNetwork (0.71.6): - RCT-Folly (= 2021.07.22.00) - - RCTTypeSafety (= 0.71.8) - - React-Codegen (= 0.71.8) - - React-Core/RCTNetworkHeaders (= 0.71.8) - - React-jsi (= 0.71.8) - - ReactCommon/turbomodule/core (= 0.71.8) - - React-RCTSettings (0.71.8): + - RCTTypeSafety (= 0.71.6) + - React-Codegen (= 0.71.6) + - React-Core/RCTNetworkHeaders (= 0.71.6) + - React-jsi (= 0.71.6) + - ReactCommon/turbomodule/core (= 0.71.6) + - React-RCTSettings (0.71.6): - RCT-Folly (= 2021.07.22.00) - - RCTTypeSafety (= 0.71.8) - - React-Codegen (= 0.71.8) - - React-Core/RCTSettingsHeaders (= 0.71.8) - - React-jsi (= 0.71.8) - - ReactCommon/turbomodule/core (= 0.71.8) - - React-RCTText (0.71.8): - - React-Core/RCTTextHeaders (= 0.71.8) - - React-RCTVibration (0.71.8): + - RCTTypeSafety (= 0.71.6) + - React-Codegen (= 0.71.6) + - React-Core/RCTSettingsHeaders (= 0.71.6) + - React-jsi (= 0.71.6) + - ReactCommon/turbomodule/core (= 0.71.6) + - React-RCTText (0.71.6): + - React-Core/RCTTextHeaders (= 0.71.6) + - React-RCTVibration (0.71.6): - RCT-Folly (= 2021.07.22.00) - - React-Codegen (= 0.71.8) - - React-Core/RCTVibrationHeaders (= 0.71.8) - - React-jsi (= 0.71.8) - - ReactCommon/turbomodule/core (= 0.71.8) - - React-runtimeexecutor (0.71.8): - - React-jsi (= 0.71.8) - - ReactCommon/turbomodule/bridging (0.71.8): + - React-Codegen (= 0.71.6) + - React-Core/RCTVibrationHeaders (= 0.71.6) + - React-jsi (= 0.71.6) + - ReactCommon/turbomodule/core (= 0.71.6) + - React-runtimeexecutor (0.71.6): + - React-jsi (= 0.71.6) + - ReactCommon/turbomodule/bridging (0.71.6): - DoubleConversion - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - - React-callinvoker (= 0.71.8) - - React-Core (= 0.71.8) - - React-cxxreact (= 0.71.8) - - React-jsi (= 0.71.8) - - React-logger (= 0.71.8) - - React-perflogger (= 0.71.8) - - ReactCommon/turbomodule/core (0.71.8): + - React-callinvoker (= 0.71.6) + - React-Core (= 0.71.6) + - React-cxxreact (= 0.71.6) + - React-jsi (= 0.71.6) + - React-logger (= 0.71.6) + - React-perflogger (= 0.71.6) + - ReactCommon/turbomodule/core (0.71.6): - DoubleConversion - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - - React-callinvoker (= 0.71.8) - - React-Core (= 0.71.8) - - React-cxxreact (= 0.71.8) - - React-jsi (= 0.71.8) - - React-logger (= 0.71.8) - - React-perflogger (= 0.71.8) + - React-callinvoker (= 0.71.6) + - React-Core (= 0.71.6) + - React-cxxreact (= 0.71.6) + - React-jsi (= 0.71.6) + - React-logger (= 0.71.6) + - React-perflogger (= 0.71.6) - RNScreens (3.20.0): - React-Core - React-RCTImage @@ -415,6 +416,7 @@ PODS: - XMTPRust (= 0.3.0-beta0) - XMTPReactNative (0.1.0): - ExpoModulesCore + - MessagePacker - XMTP (= 0.3.4-alpha0) - XMTPRust (0.3.0-beta0) - Yoga (1.14.0) @@ -484,6 +486,7 @@ SPEC REPOS: - GzipSwift - libevent - Logging + - MessagePacker - MMKV - MMKVCore - secp256k1.swift @@ -605,61 +608,62 @@ SPEC CHECKSUMS: EXConstants: f348da07e21b23d2b085e270d7b74f282df1a7d9 EXFileSystem: 844e86ca9b5375486ecc4ef06d3838d5597d895d EXFont: 6ea3800df746be7233208d80fe379b8ed74f4272 - Expo: d351b4546895fb99ae4e5a1bc39df770ab9dc7d1 + Expo: 81418098ffb16914b2e190f54e06db923248e4a1 ExpoKeepAwake: 69f5f627670d62318410392d03e0b5db0f85759a - ExpoModulesCore: 653958063a301098b541ae4dfed1ac0b98db607b + ExpoModulesCore: 6e0259511f4c4341b6b8357db393624df2280828 EXSecureStore: e8923258361cc406d0401af380f12bd05b2b720f - FBLazyVector: f637f31eacba90d4fdeff3fa41608b8f361c173b - FBReactNativeSpec: 0d9a4f4de7ab614c49e98c00aedfd3bfbda33d59 + FBLazyVector: a83ceaa8a8581003a623facdb3c44f6d4f342ac5 + FBReactNativeSpec: 85eee79837cb797ab6176f0243a2b40511c09158 fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 GenericJSON: 79a840eeb77030962e8cf02a62d36bd413b67626 glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b GzipSwift: 893f3e48e597a1a4f62fafcb6514220fcf8287fa - hermes-engine: 47986d26692ae75ee7a17ab049caee8864f855de + hermes-engine: b434cea529ad0152c56c7cb6486b0c4c0b23b5de libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 Logging: 9ef4ecb546ad3169398d5a723bc9bea1c46bef26 + MessagePacker: ab2fe250e86ea7aedd1a9ee47a37083edd41fd02 MMKV: 9c6c3fa4ddd849f28c7b9a5c9d23aab84f14ee35 MMKVCore: 9bb7440b170181ac5b81f542ac258103542e693d RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 - RCTRequired: 8af6a32dfc2b65ec82193c2dee6e1011ff22ac2a - RCTTypeSafety: bee9dd161c175896c680d47ef1d9eaacf2b587f4 - React: d850475db9ba8006a8b875d79e1e0d6ac8a0f8b6 - React-callinvoker: 6a0c75475ddc17c9ed54e4ff0478074a18fd7ab5 - React-Codegen: 786571642e87add634e7f4d299c85314ec6cc158 - React-Core: 1adfab153f59e4f56e09b97a153089f466d7b8aa - React-CoreModules: 958d236715415d4ccdd5fa35c516cf0356637393 - React-cxxreact: 2e7a6283807ce8755c3d501735acd400bec3b5cd - React-hermes: 8102c3112ba32207c3052619be8cfae14bf99d84 - React-jsi: dd29264f041a587e91f994e4be97e86c127742b2 - React-jsiexecutor: 747911ab5921641b4ed7e4900065896597142125 - React-jsinspector: c712f9e3bb9ba4122d6b82b4f906448b8a281580 - React-logger: 342f358b8decfbf8f272367f4eacf4b6154061be + RCTRequired: 5c6fd63b03abb06947d348dadac51c93e3485bd8 + RCTTypeSafety: 1c66daedd66f674e39ce9f40782f0d490c78b175 + React: e11ca7cdc7aa4ddd7e6a59278b808cfe17ebbd9f + React-callinvoker: 77a82869505c96945c074b80bbdc8df919646d51 + React-Codegen: 9ee33090c38ab3da3c4dc029924d50fb649f0dfc + React-Core: 44903e47b428a491f48fd0eae54caddb2ea05ebf + React-CoreModules: 83d989defdfc82be1f7386f84a56b6509f54ac74 + React-cxxreact: 058e7e6349649eae9cfcdec5854e702b26298932 + React-hermes: ba19a405804b833c9b832c1f2061ad5038bb97f2 + React-jsi: 3fe6f589c9cafbef85ed5a4be7c6dc8edfb4ab54 + React-jsiexecutor: 7894956638ff3e00819dd3f9f6f4a84da38f2409 + React-jsinspector: d5ce2ef3eb8fd30c28389d0bc577918c70821bd6 + React-logger: 9332c3e7b4ef007a0211c0a9868253aac3e1da82 react-native-get-random-values: a6ea6a8a65dc93e96e24a11105b1a9c8cfe1d72a react-native-mmkv: 7da5e18e55c04a9af9a7e0ab9792a1e8d33765a1 react-native-randombytes: 421f1c7d48c0af8dbcd471b0324393ebf8fe7846 react-native-safe-area-context: 39c2d8be3328df5d437ac1700f4f3a4f75716acc - React-perflogger: d21f182895de9d1b077f8a3cd00011095c8c9100 - React-RCTActionSheet: 0151f83ef92d2a7139bba7dfdbc8066632a6d47b - React-RCTAnimation: 5ec9c0705bb2297549c120fe6473aa3e4a01e215 - React-RCTAppDelegate: 9895fd1b6d1176d88c4b10ddc169b2e1300c91f0 - React-RCTBlob: f3634eb45b6e7480037655e1ca93d1136ac984dd - React-RCTImage: 3c12cb32dec49549ae62ed6cba4018db43841ffc - React-RCTLinking: 310e930ee335ef25481b4a173d9edb64b77895f9 - React-RCTNetwork: b6837841fe88303b0c04c1e3c01992b30f1f5498 - React-RCTSettings: 600d91fe25fa7c16b0ff891304082440f2904b89 - React-RCTText: a0a19f749088280c6def5397ed6211b811e7eef3 - React-RCTVibration: 43ffd976a25f6057a7cf95ea3648ba4e00287f89 - React-runtimeexecutor: 7c51ae9d4b3e9608a2366e39ccaa606aa551b9ed - ReactCommon: 85c98ab0a509e70bf5ee5d9715cf68dbf495b84c + React-perflogger: 43392072a5b867a504e2b4857606f8fc5a403d7f + React-RCTActionSheet: c7b67c125bebeda9fb19fc7b200d85cb9d6899c4 + React-RCTAnimation: c2de79906f607986633a7114bee44854e4c7e2f5 + React-RCTAppDelegate: 96bc933c3228a549718a6475c4d3f9dd4bbae98d + React-RCTBlob: cf72446957310e7da6627a4bdaadf970d3a8f232 + React-RCTImage: c6093f1bf3d67c0428d779b00390617d5bd90699 + React-RCTLinking: 5de47e37937889d22599af4b99d0552bad1b1c3c + React-RCTNetwork: e7d7077e073b08e5dd486fba3fe87ccad90a9bc4 + React-RCTSettings: 72a04921b2e8fb832da7201a60ffffff2a7c62f7 + React-RCTText: 7123c70fef5367e2121fea37e65b9ad6d3747e54 + React-RCTVibration: 73d201599a64ea14b4e0b8f91b64970979fd92e6 + React-runtimeexecutor: 8692ac548bec648fa121980ccb4304afd136d584 + ReactCommon: 0c43eaeaaee231d7d8dc24fc5a6e4cf2b75bf196 RNScreens: 218801c16a2782546d30bd2026bb625c0302d70f RNSVG: 53c661b76829783cdaf9b7a57258f3d3b4c28315 secp256k1.swift: a7e7a214f6db6ce5db32cc6b2b45e5c4dd633634 SwiftProtobuf: afced68785854575756db965e9da52bbf3dc45e7 web3.swift: 2263d1e12e121b2c42ffb63a5a7beb1acaf33959 XMTP: 0678e0b6c2e66f197db098106bec2fe35f7295fb - XMTPReactNative: 7f86c6cde3d3123d5f25adb0c9cdaedb7ca5b6aa + XMTPReactNative: d07b571ec0909762589aeafdfc1ac1ecff495b96 XMTPRust: 233518ed46fbe3ea9e3bc3035de9a620dba09ce5 - Yoga: 065f0b74dba4832d6e328238de46eb72c5de9556 + Yoga: ba09b6b11e6139e3df8229238aa794205ca6a02a PODFILE CHECKSUM: 522d88edc2d5fac4825e60a121c24abc18983367 diff --git a/example/ios/xmtpreactnativesdkexample.xcodeproj/project.pbxproj b/example/ios/xmtpreactnativesdkexample.xcodeproj/project.pbxproj index c17a0a3e5..517bd37af 100644 --- a/example/ios/xmtpreactnativesdkexample.xcodeproj/project.pbxproj +++ b/example/ios/xmtpreactnativesdkexample.xcodeproj/project.pbxproj @@ -41,6 +41,7 @@ 80323D3D45487AD85F64F249 /* Pods-xmtpreactnativesdkexample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-xmtpreactnativesdkexample.debug.xcconfig"; path = "Target Support Files/Pods-xmtpreactnativesdkexample/Pods-xmtpreactnativesdkexample.debug.xcconfig"; sourceTree = ""; }; A6A5DB852A00551E001DF8C2 /* xmtpreactnativesdkexampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = xmtpreactnativesdkexampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; A6A5DB872A00551E001DF8C2 /* xmtpreactnativesdkexampleUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = xmtpreactnativesdkexampleUITests.swift; sourceTree = ""; }; + A6AE8C832A49F1F300BD4E8B /* libMessagePack.swift.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libMessagePack.swift.a; sourceTree = BUILT_PRODUCTS_DIR; }; AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = SplashScreen.storyboard; path = xmtpreactnativesdkexample/SplashScreen.storyboard; sourceTree = ""; }; BB2F792C24A3F905000567C9 /* Expo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Expo.plist; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; @@ -86,6 +87,7 @@ 2D16E6871FA4F8E400B85C8A /* Frameworks */ = { isa = PBXGroup; children = ( + A6AE8C832A49F1F300BD4E8B /* libMessagePack.swift.a */, ED297162215061F000B7C4FE /* JavaScriptCore.framework */, 78B76F8B6347E6AE6088DF9B /* libPods-xmtpreactnativesdkexample.a */, ); @@ -581,7 +583,7 @@ DEVELOPMENT_TEAM = FY4NZR34Z3; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 16.4; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; MARKETING_VERSION = 1.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; @@ -614,7 +616,7 @@ DEVELOPMENT_TEAM = FY4NZR34Z3; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 16.4; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; MARKETING_VERSION = 1.0; MTL_FAST_MATH = YES; OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE"; diff --git a/example/ios/xmtpreactnativesdkexample.xcodeproj/xcshareddata/xcschemes/xmtpreactnativesdkexample.xcscheme b/example/ios/xmtpreactnativesdkexample.xcodeproj/xcshareddata/xcschemes/xmtpreactnativesdkexample.xcscheme deleted file mode 100644 index 9d7095974..000000000 --- a/example/ios/xmtpreactnativesdkexample.xcodeproj/xcshareddata/xcschemes/xmtpreactnativesdkexample.xcscheme +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/example/src/ConversationView.tsx b/example/src/ConversationView.tsx index 0eb82ecf7..129f944c8 100644 --- a/example/src/ConversationView.tsx +++ b/example/src/ConversationView.tsx @@ -1,4 +1,5 @@ import { NativeStackScreenProps } from "@react-navigation/native-stack"; +import { content as protoContent } from "@xmtp/proto"; import React, { useEffect, useState } from "react"; import { Text, @@ -8,25 +9,44 @@ import { View, Button, } from "react-native"; -import { Conversation, DecodedMessage } from "xmtp-react-native-sdk"; +import { Conversation } from "xmtp-react-native-sdk"; import { RootStackParamList } from "./HomeView"; +import { TextCodec } from "./test_utils"; +import { + CodecRegistry, + ContentCodecInterface, +} from "../../src/lib/CodecRegistry"; type Props = NativeStackScreenProps; +type DecodedMessage = { + content: any; + id: string; + senderAddress: string; + sent: Date; +}; + export default function ConversationView({ route }: Props): JSX.Element { const conversation = new Conversation(route.params.conversation); const [messages, setMessages] = useState([]); const [refreshing, setRefreshing] = useState(false); - const [text, onChangeText] = useState(""); + const [content, onChangeContent] = useState(""); const [isSending, setIsSending] = useState(false); async function loadMessages() { try { const messages = await conversation.messages(); + const textCodec = new TextCodec(); + const mappedMessages = messages.map((msg) => { + return { + ...msg, + content: textCodec.decode(msg.content), + }; + }); setMessages( - messages.sort((a, b) => { + mappedMessages.sort((a, b) => { return a.sent > b.sent ? 1 : -1; }) ); @@ -49,7 +69,14 @@ export default function ConversationView({ route }: Props): JSX.Element { async function sendMessage() { setIsSending(true); - const message = await conversation.send(text); + let codec: ContentCodecInterface = new TextCodec(); + + const registry = new CodecRegistry(); + registry.register(codec); + + const encodedContent = codec.encode(content); + const data = protoContent.EncodedContent.encode(encodedContent).finish(); + const message = await conversation.send(data); const uniqueMessages = [ ...new Map( @@ -62,7 +89,7 @@ export default function ConversationView({ route }: Props): JSX.Element { setMessages(uniqueMessages); setIsSending(false); - onChangeText(""); + onChangeContent(""); } useEffect(() => { @@ -96,8 +123,8 @@ export default function ConversationView({ route }: Props): JSX.Element { { + contentType: { + id(): string; + authorityId: string; + typeId: string; + versionMajor: number; + versionMinor: number; + }; + + constructor() { + this.contentType = new ContentTypeID({ + authorityId: "example.com", + typeId: "number", + versionMajor: 1, + versionMinor: 1, + }); + } + + encode(content: number) { + const encodedContent = { + type: this.contentType, + content: Buffer.from(JSON.stringify(content)), + fallback: content.toString(), + parameters: {}, + }; + + return encodedContent; + } + + decode(encodedContent: EncodedContent): number { + try { + const contentToDecode = new TextDecoder().decode(encodedContent.content); + if (!Number(contentToDecode)) { + throw new Error("Not a number"); + } + return Number(contentToDecode); + } catch (e) { + throw new CodecError("invalidContent"); + } + } +} + +export class TextCodec implements ContentCodecInterface { contentType: { id(): string; - authorityID: string; - typeID: string; + authorityId: string; + typeId: string; versionMajor: number; versionMinor: number; }; constructor() { this.contentType = new ContentTypeID({ - authorityID: "example.com", - typeID: "number", + authorityId: "example.com", + typeId: "number", versionMajor: 1, versionMinor: 1, }); } - encode(content: Uint8Array) { + encode(content: string) { const encodedContent = { type: this.contentType, content: Buffer.from(JSON.stringify(content)), - fallback: "fallbackText", + fallback: content, + parameters: {}, }; return encodedContent; } - decode(encodedContent: EncodedContent) { + decode(encodedContent: EncodedContent): string { try { - const contentToDecode = encodedContent.content.toString(); - const decodedContent = JSON.parse(contentToDecode); - return decodedContent; - } catch { + const contentToDecode = new TextDecoder().decode(encodedContent.content); + return JSON.parse(contentToDecode); + } catch (e) { throw new CodecError("invalidContent"); } } diff --git a/example/src/tests.ts b/example/src/tests.ts index b5128eb4c..1c01d91c6 100644 --- a/example/src/tests.ts +++ b/example/src/tests.ts @@ -1,11 +1,10 @@ +import { content } from "@xmtp/proto"; + +import { NumberCodec, TextCodec } from "./test_utils"; import * as XMTP from "../../src/index"; -import { - CodecRegistry, - ContentCodecInterface, -} from "../../src/lib/CodecRegistry"; +import { DecodedMessage } from "../../src/index"; import { CodecError } from "../../src/lib/CodecError"; - -import { NumberCodec } from "./test_utils"; +import { CodecRegistry } from "../../src/lib/CodecRegistry"; function sleep(ms: number) { return new Promise((resolve) => setTimeout(resolve, ms)); @@ -31,34 +30,49 @@ test("can make a client", async () => { return client.address.length > 0; }); -test("can message a client", async () => { - const bob = await XMTP.Client.createRandom("local"); - const alice = await XMTP.Client.createRandom("local"); +test("can send and receive a text codec", async () => { + const textCodec = new TextCodec(); + const registry = new CodecRegistry(); + registry.register(textCodec); - if (bob.address === alice.address) { - throw new Error("bob and alice should be different"); - } + try { + const id = textCodec.contentType.id(); + const codec = registry.find(id); - const bobConversation = await bob.conversations.newConversation( - alice.address - ); + const encodedContent = codec.encode("Hello world"); - const aliceConversation = (await alice.conversations.list())[0]; - if (!aliceConversation) { - throw new Error("aliceConversation should exist"); - } + const data = content.EncodedContent.encode(encodedContent).finish(); - await bobConversation.send("hello world"); + const bob = await XMTP.Client.createRandom("local"); + const alice = await XMTP.Client.createRandom("local"); - const messages = await aliceConversation.messages(); + if (bob.address === alice.address) { + throw new Error("bob and alice should be different"); + } - if (messages.length !== 1) { - throw Error("No message"); - } + const bobConversation = await bob.conversations.newConversation( + alice.address + ); + + const aliceConversation = (await alice.conversations.list())[0]; + if (!aliceConversation) { + throw new Error("aliceConversation should exist"); + } + + await bobConversation.send(data); - const message = messages[0]; + const messages: DecodedMessage[] = await aliceConversation.messages(); - return message.content === "hello world"; + if (messages.length !== 1) { + throw Error("No message"); + } + + const firstMessage = messages?.[0]; + const decodedMessage = codec.decode(firstMessage.content); + return decodedMessage === "Hello world"; + } catch (e) { + return false; + } }); test("canMessage", async () => { @@ -73,7 +87,7 @@ test("can register, encode, and decode a number codec", async () => { const numberCodec = new NumberCodec(); const registry = new CodecRegistry(); - registry.register(numberCodec as ContentCodecInterface); + registry.register(numberCodec); const id = numberCodec.contentType.id(); const codec = registry.find(id); @@ -87,7 +101,7 @@ test("can register, encode, and decode a number codec", async () => { test("throws an error if codec is not found in registry", async () => { const numberCodec = new NumberCodec(); const registry = new CodecRegistry(); - registry.register(numberCodec as ContentCodecInterface); + registry.register(numberCodec); try { const id = "invalidId"; @@ -101,7 +115,7 @@ test("throws an error if codec is not found in registry", async () => { test("throws an error if codec is invalid when decoding", async () => { const numberCodec = new NumberCodec(); const registry = new CodecRegistry(); - registry.register(numberCodec as ContentCodecInterface); + registry.register(numberCodec); try { const id = numberCodec.contentType.id(); @@ -110,7 +124,8 @@ test("throws an error if codec is invalid when decoding", async () => { const encodedContent = codec.encode(3.14); const invalidContentToDecode = { ...encodedContent, - content: { key1: "This cannot be parsed" }, + // Not a UInt8Array + content: 3.14, }; // @ts-ignore codec.decode(invalidContentToDecode); @@ -119,3 +134,47 @@ test("throws an error if codec is invalid when decoding", async () => { } return false; }); + +test("can send and receive number codec", async () => { + const numberCodec = new NumberCodec(); + const registry = new CodecRegistry(); + registry.register(numberCodec); + + try { + const id = numberCodec.contentType.id(); + const codec = registry.find(id); + + const encodedContent = codec.encode(3.14); + + const data = content.EncodedContent.encode(encodedContent).finish(); + + const bob = await XMTP.Client.createRandom("local"); + const alice = await XMTP.Client.createRandom("local"); + + if (bob.address === alice.address) { + throw new Error("bob and alice should be different"); + } + + const bobConversation = await bob.conversations.newConversation( + alice.address + ); + + const aliceConversation = (await alice.conversations.list())[0]; + if (!aliceConversation) { + throw new Error("aliceConversation should exist"); + } + + await bobConversation.send(data); + const messages: DecodedMessage[] = await aliceConversation.messages(); + + if (messages.length !== 1) { + throw Error("No message"); + } + + const firstMessage = messages?.[0]; + const decodedMessage = codec.decode(firstMessage.content); + return decodedMessage === 3.14; + } catch (e) { + return false; + } +}); diff --git a/ios/Wrappers/BinaryDataWrapper.swift b/ios/Wrappers/BinaryDataWrapper.swift new file mode 100644 index 000000000..7add3e9ed --- /dev/null +++ b/ios/Wrappers/BinaryDataWrapper.swift @@ -0,0 +1,24 @@ +// +// BinaryDataWrapper.swift +// + + +import Foundation +import MessagePacker + +enum BinaryDataWrapperError: Swift.Error { + case encodeError(String) +} + +protocol BinaryDataWrapper: Codable { + associatedtype T + static func wrap(model: T) throws -> Self +} + +extension BinaryDataWrapper { + static func encode(_ model: T) throws -> [UInt8] { + let wrapper = try wrap(model: model) + let encodedData = try MessagePackEncoder().encode(wrapper) + return [UInt8](encodedData) + } +} diff --git a/ios/Wrappers/EncodedMessageWrapper.swift b/ios/Wrappers/EncodedMessageWrapper.swift new file mode 100644 index 000000000..0c43ff326 --- /dev/null +++ b/ios/Wrappers/EncodedMessageWrapper.swift @@ -0,0 +1,24 @@ +// +// EncodedMessageWrapper.swift +// + +import Foundation +import XMTP + +// Wrapper around XMTP.EncodedMessage to allow passing these objects back +// into react native. +struct EncodedMessageWrapper: BinaryDataWrapper { + static func wrap(model: XMTP.DecodedMessage) throws -> EncodedMessageWrapper { + return EncodedMessageWrapper( + id: model.id, + content: [UInt8](try model.encodedContent.serializedData()), + senderAddress: model.senderAddress, + sent: model.sent + ) + } + + var id: String + var content: [UInt8] + var senderAddress: String + var sent: Date +} diff --git a/ios/XMTPModule.swift b/ios/XMTPModule.swift index 7914a114c..b13ff1bd8 100644 --- a/ios/XMTPModule.swift +++ b/ios/XMTPModule.swift @@ -199,32 +199,34 @@ public class XMTPModule: Module { } } - AsyncFunction("loadMessages") { (clientAddress: String, topics: [String], conversationIDs: [String?], limit: Int?, before: Double?, after: Double?) -> [String] in + AsyncFunction("loadMessages") { (clientAddress: String, topics: [String], conversationIDs: [String?], limit: Int?, before: Double?, after: Double?) -> [[UInt8]] in let beforeDate = before != nil ? Date(timeIntervalSince1970: before!) : nil - let afterDate = after != nil ? Date(timeIntervalSince1970: after!) : nil + let afterDate = after != nil ? Date(timeIntervalSince1970: after!) : nil guard let client = clients[clientAddress] else { throw Error.noClient } - return try await client.conversations.listBatchMessages( + + let decodedMessages = try await client.conversations.listBatchMessages( topics: topics, limit: limit, before: beforeDate, - after: afterDate) - .map { (msg) in try DecodedMessageWrapper.encode(msg) } - } + after: afterDate) + + let messages = try decodedMessages.map { (msg) in try EncodedMessageWrapper.encode(msg) } + + return messages + } - // TODO: Support content types - AsyncFunction("sendMessage") { (clientAddress: String, conversationTopic: String, conversationID: String?, content: String) -> String in + AsyncFunction("sendEncodedContentData") { (clientAddress: String, conversationTopic: String, conversationID: String?, content: Array) -> String in guard let conversation = try await findConversation(clientAddress: clientAddress, topic: conversationTopic) else { throw Error.conversationNotFound("no conversation found for \(conversationTopic)") } + + let contentData = Data(content) + let encodedContent = try EncodedContent(serializedData: contentData) - let preparedMessage = try await conversation.prepareMessage(content: content) - let decodedMessage = try preparedMessage.decodedMessage() - - try await preparedMessage.send() - - return try DecodedMessageWrapper.encode(decodedMessage) + let messageID = try await conversation.send(encodedContent: encodedContent) + return messageID } AsyncFunction("createConversation") { (clientAddress: String, peerAddress: String, conversationID: String?) -> String in diff --git a/ios/XMTPReactNative.podspec b/ios/XMTPReactNative.podspec index 6ee5f4728..c1a6aa4a6 100644 --- a/ios/XMTPReactNative.podspec +++ b/ios/XMTPReactNative.podspec @@ -24,5 +24,6 @@ Pod::Spec.new do |s| } s.source_files = "**/*.{h,m,swift}" + s.dependency "MessagePacker" s.dependency "XMTP", "= 0.3.4-alpha0" end diff --git a/package-lock.json b/package-lock.json index 1c8887233..7e6ef2fd0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,21 @@ { - "name": "xmtp-react-native-sdk", + "name": "@xmtp/react-native-sdk", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "xmtp-react-native-sdk", + "name": "@xmtp/react-native-sdk", "version": "0.1.0", "license": "MIT", "dependencies": { + "@msgpack/msgpack": "^3.0.0-beta2", + "@xmtp/proto": "^3.25.0", "ethers": "^5.7.2", "semantic-release": "^21.0.1" }, "devDependencies": { + "@babel/plugin-proposal-export-namespace-from": "^7.18.9", "@types/react": "^18.0.25", "@types/react-native": "^0.70.6", "expo-module-scripts": "^3.0.4", @@ -3474,7 +3477,8 @@ "node_modules/@gar/promisify": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==" + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "peer": true }, "node_modules/@graphql-typed-document-node/core": { "version": "3.2.0", @@ -4025,6 +4029,14 @@ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, + "node_modules/@msgpack/msgpack": { + "version": "3.0.0-beta2", + "resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-3.0.0-beta2.tgz", + "integrity": "sha512-y+l1PNV0XDyY8sM3YtuMLK5vE3/hkfId+Do8pLo/OPxfxuFAUwcGz3oiiUuV46/aBpwTzZ+mRWVMtlSKbradhw==", + "engines": { + "node": ">= 14" + } + }, "node_modules/@nicolo-ribaudo/chokidar-2": { "version": "2.1.8-no-fsevents.3", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", @@ -4068,6 +4080,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", + "peer": true, "dependencies": { "@gar/promisify": "^1.0.1", "semver": "^7.3.5" @@ -4077,6 +4090,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "peer": true, "dependencies": { "yallist": "^4.0.0" }, @@ -4088,6 +4102,7 @@ "version": "7.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "peer": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -4101,13 +4116,15 @@ "node_modules/@npmcli/fs/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "peer": true }, "node_modules/@npmcli/move-file": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", "deprecated": "This functionality has been moved to @npmcli/fs", + "peer": true, "dependencies": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" @@ -4120,6 +4137,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "peer": true, "bin": { "mkdirp": "bin/cmd.js" }, @@ -4131,6 +4149,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "peer": true, "dependencies": { "glob": "^7.1.3" }, @@ -4341,6 +4360,60 @@ "node": ">=12" } }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, "node_modules/@react-native-community/cli": { "version": "10.2.2", "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-10.2.2.tgz", @@ -6288,6 +6361,17 @@ "node": ">=10.0.0" } }, + "node_modules/@xmtp/proto": { + "version": "3.25.0", + "resolved": "https://registry.npmjs.org/@xmtp/proto/-/proto-3.25.0.tgz", + "integrity": "sha512-neVPGr40QRAWmIcG3R3d3g6ziSdY8bmKeSFRb6zWANXB3wluHoEGmud5/jZw4u/AY3E6FuNCwVODGku86iIeHw==", + "dependencies": { + "long": "^5.2.0", + "protobufjs": "^7.0.0", + "rxjs": "^7.8.0", + "undici": "^5.8.1" + } + }, "node_modules/abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", @@ -7296,7 +7380,19 @@ "node_modules/builtins": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", - "integrity": "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==" + "integrity": "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==", + "peer": true + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } }, "node_modules/bytes": { "version": "3.1.2", @@ -7311,6 +7407,7 @@ "version": "15.3.0", "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", + "peer": true, "dependencies": { "@npmcli/fs": "^1.0.0", "@npmcli/move-file": "^1.0.1", @@ -7339,6 +7436,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "peer": true, "dependencies": { "yallist": "^4.0.0" }, @@ -7350,6 +7448,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "peer": true, "bin": { "mkdirp": "bin/cmd.js" }, @@ -7361,6 +7460,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "peer": true, "dependencies": { "glob": "^7.1.3" }, @@ -7374,7 +7474,8 @@ "node_modules/cacache/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "peer": true }, "node_modules/cache-base": { "version": "1.0.1", @@ -7569,6 +7670,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "peer": true, "engines": { "node": ">=10" } @@ -10770,6 +10872,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "peer": true, "dependencies": { "minipass": "^3.0.0" }, @@ -11304,6 +11407,7 @@ "version": "3.0.8", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz", "integrity": "sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==", + "peer": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -11315,6 +11419,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "peer": true, "dependencies": { "yallist": "^4.0.0" }, @@ -11325,7 +11430,8 @@ "node_modules/hosted-git-info/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "peer": true }, "node_modules/html-encoding-sniffer": { "version": "3.0.0", @@ -11531,7 +11637,8 @@ "node_modules/infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "peer": true }, "node_modules/inflight": { "version": "1.0.6", @@ -14356,6 +14463,11 @@ "node": ">=6" } }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -15510,6 +15622,7 @@ "version": "3.1.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "peer": true, "dependencies": { "yallist": "^4.0.0" }, @@ -15521,6 +15634,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "peer": true, "dependencies": { "minipass": "^3.0.0" }, @@ -15532,6 +15646,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "peer": true, "dependencies": { "minipass": "^3.0.0" }, @@ -15543,6 +15658,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "peer": true, "dependencies": { "minipass": "^3.0.0" }, @@ -15553,12 +15669,14 @@ "node_modules/minipass/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "peer": true }, "node_modules/minizlib": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "peer": true, "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" @@ -15570,7 +15688,8 @@ "node_modules/minizlib/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "peer": true }, "node_modules/mixin-deep": { "version": "1.3.2", @@ -16066,6 +16185,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-7.0.0.tgz", "integrity": "sha512-xXxr8y5U0kl8dVkz2oK7yZjPBvqM2fwaO5l3Yg13p03v8+E3qQcD0JNhHzjL1vyGgxcKkD0cco+NLR72iuPk3g==", + "peer": true, "dependencies": { "hosted-git-info": "^3.0.2", "osenv": "^0.1.5", @@ -16077,6 +16197,7 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "peer": true, "bin": { "semver": "bin/semver" } @@ -19100,6 +19221,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -19108,6 +19230,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -19116,6 +19239,7 @@ "version": "0.1.5", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "peer": true, "dependencies": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.0" @@ -19200,6 +19324,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "peer": true, "dependencies": { "aggregate-error": "^3.0.0" }, @@ -19763,7 +19888,8 @@ "node_modules/promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==" + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "peer": true }, "node_modules/prompts": { "version": "2.4.2", @@ -19797,6 +19923,29 @@ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" }, + "node_modules/protobufjs": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.3.tgz", + "integrity": "sha512-TtpvOqwB5Gdz/PQmOjgsrGH1nHjAQVCN7JG4A6r1sXRWESL5rNMAiRcBQlCAdKxZcAbstExQePYG8xof/JVRgg==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -19852,6 +20001,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.11.0.tgz", "integrity": "sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ==", + "peer": true, "bin": { "qrcode-terminal": "bin/qrcode-terminal.js" } @@ -20787,6 +20937,14 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -21977,6 +22135,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "peer": true, "dependencies": { "minipass": "^3.1.1" }, @@ -22152,6 +22311,14 @@ "readable-stream": "^2.0.2" } }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -22413,6 +22580,7 @@ "version": "6.1.13", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz", "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==", + "peer": true, "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -22429,6 +22597,7 @@ "version": "4.2.8", "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "peer": true, "engines": { "node": ">=8" } @@ -22437,6 +22606,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "peer": true, "bin": { "mkdirp": "bin/cmd.js" }, @@ -22447,7 +22617,8 @@ "node_modules/tar/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "peer": true }, "node_modules/temp": { "version": "0.8.3", @@ -22591,7 +22762,8 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "peer": true }, "node_modules/thenify": { "version": "3.3.1", @@ -22885,8 +23057,7 @@ "node_modules/tslib": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", - "peer": true + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" }, "node_modules/tsutils": { "version": "3.21.0", @@ -23050,6 +23221,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici": { + "version": "5.22.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.22.1.tgz", + "integrity": "sha512-Ji2IJhFXZY0x/0tVBXeQwgPlLWw13GVzpsWPQ3rV50IFMMof2I55PZZxtm4P6iNq+L5znYN9nSTAq0ZyE6lSJw==", + "dependencies": { + "busboy": "^1.6.0" + }, + "engines": { + "node": ">=14.0" + } + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", @@ -23114,6 +23296,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "peer": true, "dependencies": { "unique-slug": "^2.0.0" } @@ -23122,6 +23305,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "peer": true, "dependencies": { "imurmurhash": "^0.1.4" } @@ -23345,6 +23529,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", "integrity": "sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==", + "peer": true, "dependencies": { "builtins": "^1.0.3" } @@ -23458,6 +23643,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "peer": true, "dependencies": { "isexe": "^2.0.0" }, diff --git a/package.json b/package.json index 8cab6e870..8aa1706ff 100644 --- a/package.json +++ b/package.json @@ -38,10 +38,13 @@ "license": "MIT", "homepage": "https://github.com/xmtp/xmtp-react-native#readme", "dependencies": { + "@msgpack/msgpack": "^3.0.0-beta2", + "@xmtp/proto": "^3.25.0", "ethers": "^5.7.2", "semantic-release": "^21.0.1" }, "devDependencies": { + "@babel/plugin-proposal-export-namespace-from": "^7.18.9", "@types/react": "^18.0.25", "@types/react-native": "^0.70.6", "expo-module-scripts": "^3.0.4", diff --git a/src/XMTP.types.ts b/src/XMTP.types.ts index 480ab5989..f01420b50 100644 --- a/src/XMTP.types.ts +++ b/src/XMTP.types.ts @@ -19,7 +19,7 @@ export type XMTPViewProps = { export type EncodedContent = { type: ContentTypeID; - parameters: { [key: string]: [value: string] } | undefined; + parameters: { [key: string]: string }; content: Uint8Array; fallback?: string; }; diff --git a/src/index.ts b/src/index.ts index 0e6b34dde..8eda88cf1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,6 @@ +import { decode } from "@msgpack/msgpack"; +import * as proto from "@xmtp/proto"; +import { EncodedContent } from "@xmtp/proto/ts/dist/types/message_contents/content.pb"; import { NativeModulesProxy, EventEmitter } from "expo-modules-core"; import XMTPModule from "./XMTPModule"; @@ -37,21 +40,30 @@ export async function exportKeyBundle(clientAddress: string): Promise { } export async function exportConversationTopicData( - clientAddress: string, - conversationTopic: string + clientAddress: string, + conversationTopic: string ): Promise { - return await XMTPModule.exportConversationTopicData(clientAddress, conversationTopic); + return await XMTPModule.exportConversationTopicData( + clientAddress, + conversationTopic + ); } export async function importConversationTopicData( - clientAddress: string, - topicData: string + clientAddress: string, + topicData: string ): Promise { - let json = await XMTPModule.importConversationTopicData(clientAddress, topicData); + let json = await XMTPModule.importConversationTopicData( + clientAddress, + topicData + ); return new Conversation(JSON.parse(json)); } -export async function canMessage(clientAddress: string, peerAddress: string): Promise { +export async function canMessage( + clientAddress: string, + peerAddress: string +): Promise { return await XMTPModule.canMessage(clientAddress, peerAddress); } @@ -73,17 +85,25 @@ export async function listMessages( before?: Date | undefined, after?: Date | undefined ): Promise { - return ( - await XMTPModule.loadMessages( - clientAddress, - [conversationTopic], - [conversationID], - limit, - before?.getTime, - after?.getTime - ) - ).map((json: string) => { - return JSON.parse(json); + const messages = await XMTPModule.loadMessages( + clientAddress, + [conversationTopic], + [conversationID], + limit, + before?.getTime, + after?.getTime + ); + + return messages.map((message) => { + let decodedMessage = decode(message); + message = decodedMessage; + + const encodedContent = proto.content.EncodedContent.decode( + (decodedMessage as EncodedContent).content + ); + message.content = encodedContent; + + return message; }); } @@ -95,17 +115,25 @@ export async function listBatchMessages( before?: Date | undefined, after?: Date | undefined ): Promise { - return ( - await XMTPModule.loadMessages( - clientAddress, - conversationTopics, - conversationIDs, - limit, - before?.getTime, - after?.getTime - ) - ).map((json: string) => { - return JSON.parse(json); + const messages = await XMTPModule.loadMessages( + clientAddress, + conversationTopics, + conversationIDs, + limit, + before?.getTime, + after?.getTime + ); + + return messages.map((message) => { + let decodedMessage = decode(message); + message = decodedMessage; + + const encodedContent = proto.content.EncodedContent.decode( + (decodedMessage as EncodedContent).content + ); + message.content = encodedContent; + + return message; }); } @@ -130,15 +158,13 @@ export async function sendMessage( clientAddress: string, conversationTopic: string, conversationID: string | undefined, - content: any -): Promise { - return JSON.parse( - await XMTPModule.sendMessage( - clientAddress, - conversationTopic, - conversationID, - content - ) + encodedContentData: Uint8Array +): Promise { + return await XMTPModule.sendEncodedContentData( + clientAddress, + conversationTopic, + conversationID, + Array.from(encodedContentData) ); } @@ -189,7 +215,12 @@ export async function decodeMessage( conversationID?: string | undefined ): Promise { return JSON.parse( - await XMTPModule.decodeMessage(clientAddress, topic, encryptedMessage, conversationID) + await XMTPModule.decodeMessage( + clientAddress, + topic, + encryptedMessage, + conversationID + ) ); } diff --git a/src/lib/CodecRegistry.ts b/src/lib/CodecRegistry.ts index d7e95823f..7b823ee54 100644 --- a/src/lib/CodecRegistry.ts +++ b/src/lib/CodecRegistry.ts @@ -7,14 +7,14 @@ import { ContentTypeID } from "./ContentTypeID"; * Codecs encode and decode content, and this is the interface for ContentCodecs within this app. * * @param {ContentTypeID} contentType - The content type this codec handles. - * @param {} encode(content) - Encodes the given content and returns an EncodedContent. - * @param {} decode(content) - Decodes the given EncodedContent and returns the original content. + * @param encode(content) - Encodes the given content and returns an EncodedContent. + * @param decode(content) - Decodes the given EncodedContent and returns the original content. */ -export interface ContentCodecInterface { +export interface ContentCodecInterface { contentType: ContentTypeID; - encode(content: T): EncodedContent; - decode(content: EncodedContent): T; + encode(content: T): EncodedContent; + decode(content: EncodedContent): T; } /* @@ -25,7 +25,7 @@ export interface ContentCodecInterface { * */ export class CodecRegistry { - codecs: { [key: string]: ContentCodecInterface }; + codecs: { [key: string]: ContentCodecInterface }; constructor() { /* @@ -40,7 +40,7 @@ export class CodecRegistry { * * @param {ContentCodecInterface} codec - This is the codec instance to register. */ - register(codec: ContentCodecInterface) { + register(codec: ContentCodecInterface) { const contentType = codec.contentType.id(); this.codecs[contentType] = codec; } diff --git a/src/lib/ContentTypeID.ts b/src/lib/ContentTypeID.ts index 651e6af5d..f916f7e51 100644 --- a/src/lib/ContentTypeID.ts +++ b/src/lib/ContentTypeID.ts @@ -2,28 +2,28 @@ * * This ContentTypeID class represents a content type identifier. * - * @param {string} authorityID - The authority that defined the content type. - * @param {string} typeID - The unique ID for the content type within the authority, e.g. "number" + * @param {string} authorityId - The authority that defined the content type. + * @param {string} typeId - The unique Id for the content type within the authority, e.g. "number" * @param {number} versionMajor - The major version number of the content type. * @param {number} versionMinor - The minor version number of the content type. * * @returns {string} The full content type ID in the format: - * : + * : */ export class ContentTypeID { - authorityID: string; - typeID: string; + authorityId: string; + typeId: string; versionMajor: number; versionMinor: number; - constructor({ authorityID, typeID, versionMajor, versionMinor }) { - this.authorityID = authorityID; - this.typeID = typeID; + constructor({ authorityId, typeId, versionMajor, versionMinor }) { + this.authorityId = authorityId; + this.typeId = typeId; this.versionMajor = versionMajor; this.versionMinor = versionMinor; } id() { - return `${this.authorityID}:${this.typeID}`; + return `${this.authorityId}:${this.typeId}`; } } diff --git a/src/lib/Conversation.ts b/src/lib/Conversation.ts index 285d1561d..c3b68baa2 100644 --- a/src/lib/Conversation.ts +++ b/src/lib/Conversation.ts @@ -47,8 +47,8 @@ export class Conversation { } } - // TODO: support content types and conversation ID - async send(content: any): Promise { + // TODO: support conversation ID + async send(content: any): Promise { try { return await XMTP.sendMessage( this.clientAddress, diff --git a/src/lib/DecodedMessage.ts b/src/lib/DecodedMessage.ts index 7f3f34e18..dbbc09d58 100644 --- a/src/lib/DecodedMessage.ts +++ b/src/lib/DecodedMessage.ts @@ -1,8 +1,10 @@ +import { EncodedContent } from "../XMTP.types"; + export type DecodedMessage = { id: string; // TODO: // topic: string; - content: any; + content: EncodedContent; senderAddress: string; sent: Date; }; diff --git a/tsconfig.json b/tsconfig.json index fde3fd2ea..dbf7492b8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,6 @@ { "extends": "expo-module-scripts/tsconfig.base", "compilerOptions": { - "lib": ["es2015", "DOM"], "outDir": "./build" }, "include": ["./src"],