Skip to content

Commit 52f80ac

Browse files
authored
Consent filtering by array (#460)
* update sdk version * disable history sync * remove setting consent on message send * add the message expiration stuff * add creating groups and dms by inboxIds * add a bunch of tests * add a last message test * get the tests passing
1 parent 696dc30 commit 52f80ac

File tree

14 files changed

+456
-184
lines changed

14 files changed

+456
-184
lines changed

Package.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ let package = Package(
2121
.package(url: "https://github.com/bufbuild/connect-swift", exact: "1.0.0"),
2222
.package(url: "https://github.com/apple/swift-docc-plugin.git", from: "1.4.3"),
2323
.package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", exact: "1.8.3"),
24-
.package(url: "https://github.com/xmtp/libxmtp-swift.git", exact: "3.0.18")
24+
.package(url: "https://github.com/xmtp/libxmtp-swift.git", exact: "3.0.20")
2525
],
2626
targets: [
2727
.target(

Sources/XMTPiOS/Client.swift

+1-14
Original file line numberDiff line numberDiff line change
@@ -67,20 +67,7 @@ public struct ClientOptions {
6767
self.preAuthenticateToInboxCallback = preAuthenticateToInboxCallback
6868
self.dbEncryptionKey = dbEncryptionKey
6969
self.dbDirectory = dbDirectory
70-
if historySyncUrl == nil {
71-
switch api.env {
72-
case .production:
73-
self.historySyncUrl =
74-
"https://message-history.production.ephemera.network/"
75-
case .local:
76-
self.historySyncUrl = "http://localhost:5558"
77-
default:
78-
self.historySyncUrl =
79-
"https://message-history.dev.ephemera.network/"
80-
}
81-
} else {
82-
self.historySyncUrl = historySyncUrl
83-
}
70+
self.historySyncUrl = historySyncUrl
8471
}
8572
}
8673

Sources/XMTPiOS/Conversations.swift

+141-25
Original file line numberDiff line numberDiff line change
@@ -75,21 +75,21 @@ public actor Conversations {
7575
public func sync() async throws {
7676
try await ffiConversations.sync()
7777
}
78-
public func syncAllConversations(consentState: ConsentState? = nil)
78+
public func syncAllConversations(consentStates: [ConsentState]? = nil)
7979
async throws -> UInt32
8080
{
8181
return try await ffiConversations.syncAllConversations(
82-
consentState: consentState?.toFFI)
82+
consentStates: consentStates?.toFFI)
8383
}
8484

8585
public func listGroups(
8686
createdAfter: Date? = nil, createdBefore: Date? = nil,
8787
limit: Int? = nil,
88-
consentState: ConsentState? = nil
88+
consentStates: [ConsentState]? = nil
8989
) throws -> [Group] {
9090
var options = FfiListConversationsOptions(
9191
createdAfterNs: nil, createdBeforeNs: nil, limit: nil,
92-
consentState: consentState?.toFFI, includeDuplicateDms: false)
92+
consentStates: consentStates?.toFFI, includeDuplicateDms: false)
9393
if let createdAfter {
9494
options.createdAfterNs = Int64(createdAfter.millisecondsSinceEpoch)
9595
}
@@ -111,11 +111,11 @@ public actor Conversations {
111111
public func listDms(
112112
createdAfter: Date? = nil, createdBefore: Date? = nil,
113113
limit: Int? = nil,
114-
consentState: ConsentState? = nil
114+
consentStates: [ConsentState]? = nil
115115
) throws -> [Dm] {
116116
var options = FfiListConversationsOptions(
117117
createdAfterNs: nil, createdBeforeNs: nil, limit: nil,
118-
consentState: consentState?.toFFI, includeDuplicateDms: false)
118+
consentStates: consentStates?.toFFI, includeDuplicateDms: false)
119119
if let createdAfter {
120120
options.createdAfterNs = Int64(createdAfter.millisecondsSinceEpoch)
121121
}
@@ -137,11 +137,11 @@ public actor Conversations {
137137
public func list(
138138
createdAfter: Date? = nil, createdBefore: Date? = nil,
139139
limit: Int? = nil,
140-
consentState: ConsentState? = nil
140+
consentStates: [ConsentState]? = nil
141141
) async throws -> [Conversation] {
142142
var options = FfiListConversationsOptions(
143143
createdAfterNs: nil, createdBeforeNs: nil, limit: nil,
144-
consentState: consentState?.toFFI, includeDuplicateDms: false)
144+
consentStates: consentStates?.toFFI, includeDuplicateDms: false)
145145
if let createdAfter {
146146
options.createdAfterNs = Int64(createdAfter.millisecondsSinceEpoch)
147147
}
@@ -227,6 +227,13 @@ public actor Conversations {
227227
}
228228
}
229229

230+
public func newConversation(
231+
with peerAddress: String
232+
) async throws -> Conversation {
233+
let dm = try await findOrCreateDm(with: peerAddress)
234+
return Conversation.dm(dm)
235+
}
236+
230237
public func findOrCreateDm(with peerAddress: String) async throws -> Dm {
231238
if peerAddress.lowercased() == client.address.lowercased() {
232239
throw ConversationError.memberCannotBeSelf
@@ -249,13 +256,39 @@ public actor Conversations {
249256
return newDm
250257
}
251258

259+
public func newConversationWithInboxId(
260+
with peerInboxId: String
261+
) async throws -> Conversation {
262+
let dm = try await findOrCreateDmWithInboxId(with: peerInboxId)
263+
return Conversation.dm(dm)
264+
}
265+
266+
public func findOrCreateDmWithInboxId(with peerInboxId: String)
267+
async throws -> Dm
268+
{
269+
if peerInboxId.lowercased() == client.inboxID.lowercased() {
270+
throw ConversationError.memberCannotBeSelf
271+
}
272+
if let existingDm = try client.findDmByInboxId(inboxId: peerInboxId) {
273+
return existingDm
274+
}
275+
276+
let newDm =
277+
try await ffiConversations
278+
.createDmWithInboxId(inboxId: peerInboxId)
279+
.dmFromFFI(client: client)
280+
return newDm
281+
}
282+
252283
public func newGroup(
253284
with addresses: [String],
254285
permissions: GroupPermissionPreconfiguration = .allMembers,
255286
name: String = "",
256287
imageUrlSquare: String = "",
257288
description: String = "",
258-
pinnedFrameUrl: String = ""
289+
pinnedFrameUrl: String = "",
290+
messageExpirationFromMs: Int64? = nil,
291+
messageExpirationMs: Int64? = nil
259292
) async throws -> Group {
260293
return try await newGroupInternal(
261294
with: addresses,
@@ -266,7 +299,9 @@ public actor Conversations {
266299
imageUrlSquare: imageUrlSquare,
267300
description: description,
268301
pinnedFrameUrl: pinnedFrameUrl,
269-
permissionPolicySet: nil
302+
permissionPolicySet: nil,
303+
messageExpirationFromMs: messageExpirationMs,
304+
messageExpirationMs: messageExpirationMs
270305
)
271306
}
272307

@@ -276,7 +311,9 @@ public actor Conversations {
276311
name: String = "",
277312
imageUrlSquare: String = "",
278313
description: String = "",
279-
pinnedFrameUrl: String = ""
314+
pinnedFrameUrl: String = "",
315+
messageExpirationFromMs: Int64? = nil,
316+
messageExpirationMs: Int64? = nil
280317
) async throws -> Group {
281318
return try await newGroupInternal(
282319
with: addresses,
@@ -286,18 +323,22 @@ public actor Conversations {
286323
description: description,
287324
pinnedFrameUrl: pinnedFrameUrl,
288325
permissionPolicySet: PermissionPolicySet.toFfiPermissionPolicySet(
289-
permissionPolicySet)
326+
permissionPolicySet),
327+
messageExpirationFromMs: messageExpirationMs,
328+
messageExpirationMs: messageExpirationMs
290329
)
291330
}
292331

293332
private func newGroupInternal(
294333
with addresses: [String],
295-
permissions: FfiGroupPermissionsOptions = .allMembers,
334+
permissions: FfiGroupPermissionsOptions = .default,
296335
name: String = "",
297336
imageUrlSquare: String = "",
298337
description: String = "",
299338
pinnedFrameUrl: String = "",
300-
permissionPolicySet: FfiPermissionPolicySet? = nil
339+
permissionPolicySet: FfiPermissionPolicySet? = nil,
340+
messageExpirationFromMs: Int64? = nil,
341+
messageExpirationMs: Int64? = nil
301342
) async throws -> Group {
302343
if addresses.first(where: {
303344
$0.lowercased() == client.address.lowercased()
@@ -322,7 +363,90 @@ public actor Conversations {
322363
groupImageUrlSquare: imageUrlSquare,
323364
groupDescription: description,
324365
groupPinnedFrameUrl: pinnedFrameUrl,
325-
customPermissionPolicySet: permissionPolicySet
366+
customPermissionPolicySet: permissionPolicySet,
367+
messageExpirationFromMs: messageExpirationMs,
368+
messageExpirationMs: messageExpirationMs
369+
)
370+
).groupFromFFI(client: client)
371+
return group
372+
}
373+
374+
public func newGroupWithInboxIds(
375+
with inboxIds: [String],
376+
permissions: GroupPermissionPreconfiguration = .allMembers,
377+
name: String = "",
378+
imageUrlSquare: String = "",
379+
description: String = "",
380+
pinnedFrameUrl: String = "",
381+
messageExpirationFromMs: Int64? = nil,
382+
messageExpirationMs: Int64? = nil
383+
) async throws -> Group {
384+
return try await newGroupInternalWithInboxIds(
385+
with: inboxIds,
386+
permissions:
387+
GroupPermissionPreconfiguration.toFfiGroupPermissionOptions(
388+
option: permissions),
389+
name: name,
390+
imageUrlSquare: imageUrlSquare,
391+
description: description,
392+
pinnedFrameUrl: pinnedFrameUrl,
393+
permissionPolicySet: nil,
394+
messageExpirationFromMs: messageExpirationMs,
395+
messageExpirationMs: messageExpirationMs
396+
)
397+
}
398+
399+
public func newGroupCustomPermissionsWithInboxIds(
400+
with inboxIds: [String],
401+
permissionPolicySet: PermissionPolicySet,
402+
name: String = "",
403+
imageUrlSquare: String = "",
404+
description: String = "",
405+
pinnedFrameUrl: String = "",
406+
messageExpirationFromMs: Int64? = nil,
407+
messageExpirationMs: Int64? = nil
408+
) async throws -> Group {
409+
return try await newGroupInternalWithInboxIds(
410+
with: inboxIds,
411+
permissions: FfiGroupPermissionsOptions.customPolicy,
412+
name: name,
413+
imageUrlSquare: imageUrlSquare,
414+
description: description,
415+
pinnedFrameUrl: pinnedFrameUrl,
416+
permissionPolicySet: PermissionPolicySet.toFfiPermissionPolicySet(
417+
permissionPolicySet),
418+
messageExpirationFromMs: messageExpirationMs,
419+
messageExpirationMs: messageExpirationMs
420+
)
421+
}
422+
423+
private func newGroupInternalWithInboxIds(
424+
with inboxIds: [String],
425+
permissions: FfiGroupPermissionsOptions = .default,
426+
name: String = "",
427+
imageUrlSquare: String = "",
428+
description: String = "",
429+
pinnedFrameUrl: String = "",
430+
permissionPolicySet: FfiPermissionPolicySet? = nil,
431+
messageExpirationFromMs: Int64? = nil,
432+
messageExpirationMs: Int64? = nil
433+
) async throws -> Group {
434+
if inboxIds.contains(where: {
435+
$0.lowercased() == client.inboxID.lowercased()
436+
}) {
437+
throw ConversationError.memberCannotBeSelf
438+
}
439+
let group = try await ffiConversations.createGroupWithInboxIds(
440+
inboxIds: inboxIds,
441+
opts: FfiCreateGroupOptions(
442+
permissions: permissions,
443+
groupName: name,
444+
groupImageUrlSquare: imageUrlSquare,
445+
groupDescription: description,
446+
groupPinnedFrameUrl: pinnedFrameUrl,
447+
customPermissionPolicySet: permissionPolicySet,
448+
messageExpirationFromMs: messageExpirationMs,
449+
messageExpirationMs: messageExpirationMs
326450
)
327451
).groupFromFFI(client: client)
328452
return group
@@ -334,7 +458,7 @@ public actor Conversations {
334458
AsyncThrowingStream { continuation in
335459
let ffiStreamActor = FfiStreamActor()
336460

337-
let messageCallback = MessageCallback() {
461+
let messageCallback = MessageCallback {
338462
message in
339463
guard !Task.isCancelled else {
340464
continuation.finish()
@@ -343,8 +467,7 @@ public actor Conversations {
343467
}
344468
return
345469
}
346-
if let message = Message.create(ffiMessage: message)
347-
{
470+
if let message = Message.create(ffiMessage: message) {
348471
continuation.yield(message)
349472
}
350473
}
@@ -386,13 +509,6 @@ public actor Conversations {
386509
return try await conversation.toConversation(client: client)
387510
}
388511

389-
public func newConversation(
390-
with peerAddress: String
391-
) async throws -> Conversation {
392-
let dm = try await findOrCreateDm(with: peerAddress)
393-
return Conversation.dm(dm)
394-
}
395-
396512
public func getHmacKeys() throws
397513
-> Xmtp_KeystoreApi_V1_GetConversationHmacKeysResponse
398514
{

Sources/XMTPiOS/Dm.swift

-12
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,6 @@ public struct Dm: Identifiable, Equatable, Hashable {
8686
}
8787

8888
public func send(encodedContent: EncodedContent) async throws -> String {
89-
if try consentState() == .unknown {
90-
try await updateConsentState(state: .allowed)
91-
}
92-
9389
let messageId = try await ffiConversation.send(
9490
contentBytes: encodedContent.serializedData())
9591
return messageId.toHex
@@ -136,10 +132,6 @@ public struct Dm: Identifiable, Equatable, Hashable {
136132
public func prepareMessage(encodedContent: EncodedContent) async throws
137133
-> String
138134
{
139-
if try consentState() == .unknown {
140-
try await updateConsentState(state: .allowed)
141-
}
142-
143135
let messageId = try ffiConversation.sendOptimistic(
144136
contentBytes: encodedContent.serializedData())
145137
return messageId.toHex
@@ -148,10 +140,6 @@ public struct Dm: Identifiable, Equatable, Hashable {
148140
public func prepareMessage<T>(content: T, options: SendOptions? = nil)
149141
async throws -> String
150142
{
151-
if try consentState() == .unknown {
152-
try await updateConsentState(state: .allowed)
153-
}
154-
155143
let encodeContent = try await encodeContent(
156144
content: content, options: options)
157145
return try ffiConversation.sendOptimistic(

Sources/XMTPiOS/Extensions/Ffi.swift

+6
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ extension FfiConversationMember {
4747
}
4848
}
4949

50+
extension Array where Element == ConsentState {
51+
var toFFI: [FfiConsentState] {
52+
return self.map { $0.toFFI }
53+
}
54+
}
55+
5056
extension ConsentState {
5157
var toFFI: FfiConsentState {
5258
switch self {

Sources/XMTPiOS/Group.swift

-12
Original file line numberDiff line numberDiff line change
@@ -282,10 +282,6 @@ public struct Group: Identifiable, Equatable, Hashable {
282282
}
283283

284284
public func send(encodedContent: EncodedContent) async throws -> String {
285-
if try consentState() == .unknown {
286-
try await updateConsentState(state: .allowed)
287-
}
288-
289285
let messageId = try await ffiGroup.send(
290286
contentBytes: encodedContent.serializedData())
291287
return messageId.toHex
@@ -332,10 +328,6 @@ public struct Group: Identifiable, Equatable, Hashable {
332328
public func prepareMessage(encodedContent: EncodedContent) async throws
333329
-> String
334330
{
335-
if try consentState() == .unknown {
336-
try await updateConsentState(state: .allowed)
337-
}
338-
339331
let messageId = try ffiGroup.sendOptimistic(
340332
contentBytes: encodedContent.serializedData())
341333
return messageId.toHex
@@ -344,10 +336,6 @@ public struct Group: Identifiable, Equatable, Hashable {
344336
public func prepareMessage<T>(content: T, options: SendOptions? = nil)
345337
async throws -> String
346338
{
347-
if try consentState() == .unknown {
348-
try await updateConsentState(state: .allowed)
349-
}
350-
351339
let encodeContent = try await encodeContent(
352340
content: content, options: options)
353341
return try ffiGroup.sendOptimistic(

0 commit comments

Comments
 (0)