Skip to content

Commit

Permalink
Merge pull request #169 from xmtp/np/bump-pod-for-new-pppp
Browse files Browse the repository at this point in the history
Move React Native to latest User Preferences
  • Loading branch information
nplasterer authored Dec 8, 2023
2 parents 5ea4174 + 7316998 commit 8a3d762
Show file tree
Hide file tree
Showing 11 changed files with 170 additions and 32 deletions.
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ repositories {
dependencies {
implementation project(':expo-modules-core')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
implementation "org.xmtp:android:0.6.17"
implementation "org.xmtp:android:0.6.20"
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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import com.google.gson.JsonParser
import com.google.protobuf.kotlin.toByteString
import expo.modules.kotlin.modules.Module
import expo.modules.kotlin.modules.ModuleDefinition
import expo.modules.xmtpreactnativesdk.wrappers.ConsentWrapper
import expo.modules.xmtpreactnativesdk.wrappers.ConsentWrapper.Companion.consentStateToString
import expo.modules.xmtpreactnativesdk.wrappers.ContentJson
import expo.modules.xmtpreactnativesdk.wrappers.ConversationWrapper
import expo.modules.xmtpreactnativesdk.wrappers.DecodedMessageWrapper
Expand Down Expand Up @@ -546,23 +548,26 @@ class XMTPModule : Module() {

AsyncFunction("refreshConsentList") { clientAddress: String ->
val client = clients[clientAddress] ?: throw XMTPException("No client")
client.contacts.refreshConsentList()
val consentList = client.contacts.refreshConsentList()
consentList.entries.map { ConsentWrapper.encode(it.value) }
}

AsyncFunction("conversationConsentState") { clientAddress: String, conversationTopic: String ->
val conversation = findConversation(clientAddress, conversationTopic)
?: throw XMTPException("no conversation found for $conversationTopic")
when (conversation.consentState()) {
ConsentState.ALLOWED -> "allowed"
ConsentState.DENIED -> "denied"
ConsentState.UNKNOWN -> "unknown"
}
consentStateToString(conversation.consentState())
}

AsyncFunction("consentList") { clientAddress: String ->
val client = clients[clientAddress] ?: throw XMTPException("No client")
client.contacts.consentList.entries.map { ConsentWrapper.encode(it.value) }
}
}

//
// Helpers
//

private fun findConversation(
clientAddress: String,
topic: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package expo.modules.xmtpreactnativesdk.wrappers

import com.google.gson.GsonBuilder
import org.xmtp.android.library.ConsentListEntry
import org.xmtp.android.library.ConsentState
import org.xmtp.android.library.codecs.description
import org.xmtp.android.library.messages.DecryptedMessage

class ConsentWrapper {

companion object {
fun encode(model: ConsentListEntry): String {
val gson = GsonBuilder().create()
val message = encodeMap(model)
return gson.toJson(message)
}

fun encodeMap(model: ConsentListEntry): Map<String, Any> = mapOf(
"type" to model.entryType.name.lowercase(),
"value" to model.value.lowercase(),
"state" to consentStateToString(model.consentType),
)

fun consentStateToString(state: ConsentState): String {
return when (state) {
ConsentState.ALLOWED -> "allowed"
ConsentState.DENIED -> "denied"
ConsentState.UNKNOWN -> "unknown"
}
}
}
}
14 changes: 7 additions & 7 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -411,16 +411,16 @@ PODS:
- GenericJSON (~> 2.0)
- Logging (~> 1.0.0)
- secp256k1.swift (~> 0.1)
- XMTP (0.6.14-alpha0):
- XMTP (0.7.2-alpha0):
- Connect-Swift (= 0.3.0)
- GzipSwift
- web3.swift
- XMTPRust (= 0.3.6-beta0)
- XMTPRust (= 0.3.7-beta0)
- XMTPReactNative (0.1.0):
- ExpoModulesCore
- MessagePacker
- XMTP (= 0.6.14-alpha0)
- XMTPRust (0.3.6-beta0)
- XMTP (= 0.7.2-alpha0)
- XMTPRust (0.3.7-beta0)
- Yoga (1.14.0)

DEPENDENCIES:
Expand Down Expand Up @@ -668,9 +668,9 @@ SPEC CHECKSUMS:
secp256k1.swift: a7e7a214f6db6ce5db32cc6b2b45e5c4dd633634
SwiftProtobuf: b02b5075dcf60c9f5f403000b3b0c202a11b6ae1
web3.swift: 2263d1e12e121b2c42ffb63a5a7beb1acaf33959
XMTP: 5314a5151dbfad2e24bb5910e679052916a9faff
XMTPReactNative: 5e393ab43d402bae404f675245cfc66a078a33ff
XMTPRust: 3c958736a4f4ee798e425b5644551f1c948da4b0
XMTP: 4930b80dc99a6a8ebcf1f292a162c1f316f78c50
XMTPReactNative: 68c723488857950d10fc8ee969de0baae8f9b2ca
XMTPRust: 8848a2ba761b2c961d666632f2ad27d1082faa93
Yoga: 065f0b74dba4832d6e328238de46eb72c5de9556

PODFILE CHECKSUM: 522d88edc2d5fac4825e60a121c24abc18983367
Expand Down
15 changes: 15 additions & 0 deletions example/src/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,21 @@ test('canManagePreferences', async () => {
)
}

const boConsentList = await bo.contacts.consentList()
await delayToPropogate()

if (boConsentList.length !== 1) {
throw new Error(`consent list for bo should 1 not ${boConsentList.length}`)
}

const boConsentListState = boConsentList[0].permissionType

if (boConsentListState !== 'denied') {
throw new Error(
`conversations denied by bo should be denied in consent list not ${boConsentListState}`
)
}

return true
})

Expand Down
30 changes: 30 additions & 0 deletions ios/Wrappers/ConsentWrapper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Foundation
import XMTP

struct ConsentWrapper {
static func encodeToObj(_ entry: XMTP.ConsentListEntry) throws -> [String: Any] {
return [
"type": entry.entryType.rawValue,
"value": entry.value,
"state": consentStateToString(state: entry.consentType),
]
}

static func encode(_ entry: XMTP.ConsentListEntry) throws -> String {
let obj = try encodeToObj(entry)
let data = try JSONSerialization.data(withJSONObject: obj)
guard let result = String(data: data, encoding: .utf8) else {
throw WrapperError.encodeError("could not encode consent")
}
return result
}

static func consentStateToString(state: ConsentState) -> String {
switch state {
case .allowed: return "allowed"
case .denied: return "denied"
case .unknown: return "unknown"
}
}

}
27 changes: 19 additions & 8 deletions ios/XMTPModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -501,30 +501,41 @@ public class XMTPModule: Module {
try await client.contacts.allow(addresses: addresses)
}

AsyncFunction("refreshConsentList") { (clientAddress: String) in
AsyncFunction("refreshConsentList") { (clientAddress: String) -> [String] in
guard let client = await clientsManager.getClient(key: clientAddress) else {
throw Error.noClient
}
try await client.contacts.refreshConsentList()
let consentList = try await client.contacts.refreshConsentList()

return try consentList.entries.compactMap { entry in
try ConsentWrapper.encode(entry.value)
}
}

AsyncFunction("conversationConsentState") { (clientAddress: String, conversationTopic: String) -> String in
guard let conversation = try await findConversation(clientAddress: clientAddress, topic: conversationTopic) else {
throw Error.conversationNotFound(conversationTopic)
}
switch await conversation.consentState() {
case .allowed: return "allowed"
case .denied: return "denied"
case .unknown: return "unknown"
}
return ConsentWrapper.consentStateToString(state: await conversation.consentState())
}

AsyncFunction("consentList") { (clientAddress: String) -> [String] in
guard let client = await clientsManager.getClient(key: clientAddress) else {
throw Error.noClient
}
let entries = await client.contacts.consentList.entries

return try entries.compactMap { entry in
try ConsentWrapper.encode(entry.value)
}
}
}

//
// Helpers
//

func createClientConfig(env: String, appVersion: String?) -> XMTP.ClientOptions {
func createClientConfig(env: String, appVersion: String?) -> XMTP.ClientOptions {
// Ensure that all codecs have been registered.
switch env {
case "local":
Expand Down
2 changes: 1 addition & 1 deletion ios/XMTPReactNative.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ Pod::Spec.new do |s|

s.source_files = "**/*.{h,m,swift}"
s.dependency "MessagePacker"
s.dependency "XMTP", "= 0.6.14-alpha0"
s.dependency "XMTP", "= 0.7.2-alpha0"
end
24 changes: 21 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { EventEmitter, NativeModulesProxy } from 'expo-modules-core'
import { Client } from '.'
import { ConversationContext } from './XMTP.types'
import XMTPModule from './XMTPModule'
import { ConsentListEntry, ConsentState } from './lib/ConsentListEntry'
import {
DecryptedLocalAttachment,
EncryptedLocalAttachment,
Expand Down Expand Up @@ -320,7 +321,7 @@ export async function decodeMessage(
export async function conversationConsentState(
clientAddress: string,
conversationTopic: string
): Promise<'allowed' | 'denied' | 'unknown'> {
): Promise<ConsentState> {
return await XMTPModule.conversationConsentState(
clientAddress,
conversationTopic
Expand Down Expand Up @@ -349,8 +350,24 @@ export function allowContacts(clientAddress: string, addresses: string[]) {
XMTPModule.allowContacts(clientAddress, addresses)
}

export function refreshConsentList(clientAddress: string) {
XMTPModule.refreshConsentList(clientAddress)
export async function refreshConsentList(
clientAddress: string
): Promise<ConsentListEntry[]> {
const consentList = await XMTPModule.refreshConsentList(clientAddress)

return consentList.map((json: string) => {
return ConsentListEntry.from(json)
})
}

export async function consentList(
clientAddress: string
): Promise<ConsentListEntry[]> {
const consentList = await XMTPModule.consentList(clientAddress)

return consentList.map((json: string) => {
return ConsentListEntry.from(json)
})
}

export const emitter = new EventEmitter(XMTPModule ?? NativeModulesProxy.XMTP)
Expand All @@ -362,3 +379,4 @@ export * from './XMTP.types'
export { Query } from './lib/Query'
export { XMTPPush } from './lib/XMTPPush'
export { DecodedMessage }
export { ConsentListEntry }
24 changes: 24 additions & 0 deletions src/lib/ConsentListEntry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export type ConsentState = 'allowed' | 'denied' | 'unknown'

export type ConsentListEntryType = 'address'

export class ConsentListEntry {
value: string
entryType: ConsentListEntryType
permissionType: ConsentState

constructor(
value: string,
entryType: ConsentListEntryType,
permissionType: ConsentState
) {
this.value = value
this.entryType = entryType
this.permissionType = permissionType
}

static from(json: string): ConsentListEntry {
const entry = JSON.parse(json)
return new ConsentListEntry(entry.value, entry.type, entry.state)
}
}
15 changes: 9 additions & 6 deletions src/lib/Contacts.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Client } from './Client'
import { ConsentListEntry } from './ConsentListEntry'
import * as XMTPModule from '../index'

export default class Contacts {
Expand All @@ -9,13 +10,11 @@ export default class Contacts {
}

async isAllowed(address: string): Promise<boolean> {
const result = await XMTPModule.isAllowed(this.client.address, address)
return result
return await XMTPModule.isAllowed(this.client.address, address)
}

async isDenied(address: string): Promise<boolean> {
const result = await XMTPModule.isDenied(this.client.address, address)
return result
return await XMTPModule.isDenied(this.client.address, address)
}

deny(addresses: string[]) {
Expand All @@ -26,7 +25,11 @@ export default class Contacts {
XMTPModule.allowContacts(this.client.address, addresses)
}

refreshConsentList() {
XMTPModule.refreshConsentList(this.client.address)
async refreshConsentList(): Promise<ConsentListEntry[]> {
return await XMTPModule.refreshConsentList(this.client.address)
}

async consentList(): Promise<ConsentListEntry[]> {
return await XMTPModule.consentList(this.client.address)
}
}

0 comments on commit 8a3d762

Please sign in to comment.