Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ apply plugin: 'maven-publish'
group = 'expo.modules.xmtpreactnativesdk'
version = '0.1.0'

def isNewArchEnabled =
((findProperty('newArchEnabled') ?: rootProject.findProperty('newArchEnabled') ?: 'false')
.toString()
.toBoolean())

buildscript {
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
if (expoModulesCorePlugin.exists()) {
Expand Down Expand Up @@ -82,6 +87,7 @@ android {
targetSdkVersion safeExtGet("targetSdkVersion", 31)
versionCode 1
versionName "0.1.0"
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchEnabled.toString()
}
lintOptions {
abortOnError false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,18 @@ class XMTPModule : Module() {
return reactContext
}

private fun readHostBuildConfigBoolean(fieldName: String): Boolean? {
val packageName = appContext.reactContext?.applicationContext?.packageName ?: return null

return try {
val buildConfigClass = Class.forName("$packageName.BuildConfig")
buildConfigClass.getField(fieldName).getBoolean(null)
} catch (e: Throwable) {
logV("Unable to read $fieldName from $packageName.BuildConfig: ${e.message}")
null
}
}

private fun apiEnvironments(env: String, customLocalUrl: String? = null, appVersion: String? = null, gatewayHost: String? = null): ClientOptions.Api {
return when (env) {
"local" -> {
Expand Down Expand Up @@ -283,6 +295,22 @@ class XMTPModule : Module() {
"messageDeletionClosed"
)

AsyncFunction("getArchitectureDiagnostics") {
val hostPackageName = appContext.reactContext?.applicationContext?.packageName.orEmpty()
val hostNewArchEnabled = readHostBuildConfigBoolean("IS_NEW_ARCHITECTURE_ENABLED")

mapOf(
"platform" to "android",
"moduleName" to "XMTP",
"moduleType" to "expo-module",
"moduleClassName" to this@XMTPModule::class.java.name,
"hostAppId" to hostPackageName,
"isNewArchitectureEnabled" to (hostNewArchEnabled ?: BuildConfig.IS_NEW_ARCHITECTURE_ENABLED),
"newArchitectureFlagSource" to "BuildConfig.IS_NEW_ARCHITECTURE_ENABLED",
"newArchitectureFlagProvider" to if (hostNewArchEnabled != null) "host-app" else "xmtp-module",
)
}

Function("inboxId") { installationId: String ->
logV("inboxId")
val client = clients[installationId]
Expand Down
66 changes: 58 additions & 8 deletions example/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { NavigationContainer } from '@react-navigation/native'
// import { Ethereum } from '@thirdweb-dev/chains'
import React, { useEffect, useState } from 'react'
import 'react-native-get-random-values'
import '@ethersproject/shims'
import { Buffer as BufferPolyfill } from 'buffer'
Expand All @@ -21,12 +22,9 @@ import {
StyleSheet,
FlatList,
} from 'react-native'
import Config from 'react-native-config'
// Used to polyfill webCrypto in react-native
import { QueryClient, QueryClientProvider } from 'react-query'
import { XmtpProvider, Client } from 'xmtp-react-native-sdk'
import { useState, useEffect } from 'react'
import React from 'react'

import ConversationCreateScreen from './src/ConversationCreateScreen'
import ConversationScreen from './src/ConversationScreen'
Expand Down Expand Up @@ -135,7 +133,9 @@ const LogFilesModal: React.FC<LogFilesModalProps> = ({ visible, onClose }) => {
}
}

fetchLogFiles()
fetchLogFiles().catch((error) => {
console.error('Unexpected error fetching log files:', error)
})
}
}, [visible])

Expand Down Expand Up @@ -347,8 +347,53 @@ const AndroidDropdown: React.FC<AndroidDropdownProps> = ({
}

export default function App() {
// Uncomment below to ensure correct id loaded from .env
// console.log("Thirdweb client id: " + Config.THIRD_WEB_CLIENT_ID)
// New Architecture verification logging
useEffect(() => {
const checkNewArchitecture = async () => {
const diagnostics = await Client.getArchitectureDiagnostics()

console.log('=== XMTP ARCHITECTURE DIAGNOSTICS ===')
console.log(
` Native new architecture flag (${diagnostics.newArchitectureFlagSource} via ${diagnostics.newArchitectureFlagProvider}): ${
diagnostics.isNewArchitectureEnabled ? 'ENABLED' : 'DISABLED'
}`
)
console.log(
` XMTP module access path: ${diagnostics.moduleAccess.toUpperCase()}`
)
console.log(
` Supports synchronous native methods: ${
diagnostics.supportsSynchronousFunctions ? 'YES' : 'NO'
}`
)
console.log(` Native module type: ${diagnostics.moduleType}`)
console.log(` Native module class: ${diagnostics.moduleClassName}`)
console.log(` Host app id: ${diagnostics.hostAppId}`)
console.log(` Platform: ${diagnostics.platform}`)
console.log('=====================================')

if (
diagnostics.isNewArchitectureEnabled &&
diagnostics.moduleAccess === 'jsi'
) {
console.log(
'XMTP is running in a new-architecture app and is being resolved through the JSI module registry.'
)
} else if (diagnostics.isNewArchitectureEnabled) {
console.log(
'The app is built with the new architecture, but XMTP is currently being accessed through the bridge proxy.'
)
} else {
console.log(
'The app is not built with the new architecture, so XMTP cannot use the new-architecture runtime path.'
)
}
}

checkNewArchitecture().catch((error) => {
console.error('Failed to read XMTP architecture diagnostics:', error)
})
}, [])

const [showAndroidDropdown, setShowAndroidDropdown] = useState<boolean>(false)
const [showLogFilesModal, setShowLogFilesModal] = useState<boolean>(false)
Expand All @@ -362,7 +407,7 @@ export default function App() {
return
}

let successCount = await Client.clearXMTPLogs()
const successCount = await Client.clearXMTPLogs()

if (successCount === files.length) {
alert('All log files cleared successfully')
Expand Down Expand Up @@ -463,7 +508,12 @@ export default function App() {
},
(buttonIndex) => {
if (buttonIndex === 0) {
clearLogFiles()
clearLogFiles().catch((error) => {
console.error(
'Unexpected error clearing log files:',
error
)
})
}
}
)
Expand Down
1 change: 1 addition & 0 deletions example/app.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"expo": {
"newArchEnabled": true,
"name": "xmtp-react-native-sdk-example",
"slug": "xmtp-react-native-sdk-example",
"version": "1.0.0",
Expand Down
Loading
Loading