Skip to content

Commit e5113db

Browse files
sdk: add app address in member metadata stream view (#4545)
1 parent 6cab9df commit e5113db

File tree

4 files changed

+61
-0
lines changed

4 files changed

+61
-0
lines changed

packages/sdk/src/streamStateView_MemberMetadata.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,15 @@ export type UserInfo = {
2626
displayNameEncrypted: boolean
2727
ensAddress?: string
2828
nft?: Nft
29+
appAddress?: string
2930
}
3031

3132
export class StreamStateView_MemberMetadata {
3233
readonly usernames: MemberMetadata_Usernames
3334
readonly displayNames: MemberMetadata_DisplayNames
3435
readonly ensAddresses: MemberMetadata_EnsAddresses
3536
readonly nfts: MemberMetadata_Nft
37+
readonly appAddresses = new Map<string, string>()
3638
readonly currentUserId: string
3739
constructor(streamId: string, currentUserId: string) {
3840
this.usernames = new MemberMetadata_Usernames(streamId, currentUserId)
@@ -47,6 +49,7 @@ export class StreamStateView_MemberMetadata {
4749
displayNames: { userId: string; wrappedEncryptedData: WrappedEncryptedData }[],
4850
ensAddresses: { userId: string; ensAddress: Uint8Array }[],
4951
nfts: { userId: string; nft: MemberPayload_Nft }[],
52+
appAddresses: { userId: string; appAddress: string }[],
5053
cleartexts: Record<string, Uint8Array | string> | undefined,
5154
encryptionEmitter: TypedEmitter<StreamEncryptionEvents> | undefined,
5255
) {
@@ -93,6 +96,12 @@ export class StreamStateView_MemberMetadata {
9396

9497
this.ensAddresses.applySnapshot(ensAddresses)
9598
this.nfts.applySnapshot(nfts)
99+
100+
for (const item of appAddresses) {
101+
if (item.appAddress) {
102+
this.appAddresses.set(item.userId, item.appAddress)
103+
}
104+
}
96105
}
97106

98107
onConfirmedEvent(
@@ -185,13 +194,23 @@ export class StreamStateView_MemberMetadata {
185194
const displayNameInfo = this.displayNames.info(userId)
186195
const ensAddress = this.ensAddresses.info(userId)
187196
const nft = this.nfts.info(userId)
197+
const appAddress = this.appAddresses.get(userId)
188198
return {
189199
...usernameInfo,
190200
...displayNameInfo,
191201
ensAddress,
192202
nft,
203+
appAddress,
193204
}
194205
}
206+
207+
setAppAddress(userId: string, appAddress: string): void {
208+
this.appAddresses.set(userId, appAddress)
209+
}
210+
211+
removeAppAddress(userId: string): void {
212+
this.appAddresses.delete(userId)
213+
}
195214
}
196215

197216
function sortPayloads(

packages/sdk/src/streamStateView_Members.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,12 +177,19 @@ export class StreamStateView_Members extends StreamStateView_AbstractContent {
177177
userId: member.userId,
178178
nft: member.nft!,
179179
}))
180+
const appAddresses = Array.from(this.joined.values())
181+
.filter((x) => isDefined(x.appAddress))
182+
.map((member) => ({
183+
userId: member.userId,
184+
appAddress: member.appAddress!,
185+
}))
180186

181187
this.memberMetadata.applySnapshot(
182188
usernames,
183189
displayNames,
184190
ensAddresses,
185191
nfts,
192+
appAddresses,
186193
cleartexts,
187194
encryptionEmitter,
188195
)
@@ -313,13 +320,18 @@ export class StreamStateView_Members extends StreamStateView_AbstractContent {
313320
})
314321
if (membership.appAddress) {
315322
this.apps.add(userId)
323+
this.memberMetadata.setAppAddress(
324+
userId,
325+
userIdFromAddress(membership.appAddress),
326+
)
316327
}
317328
this.streamMemberIdsView.addMember(this.streamId, userId)
318329
break
319330
case MembershipOp.SO_LEAVE: {
320331
const leavingMember = this.joined.get(userId)
321332
if (leavingMember?.appAddress) {
322333
this.apps.delete(userId)
334+
this.memberMetadata.removeAppAddress(userId)
323335
}
324336
this.joined.delete(userId)
325337
this.streamMemberIdsView.removeMember(this.streamId, userId)

packages/sdk/src/tests/multi/botMembership.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@ describe('bot membership tests', () => {
9999
expect(botUserStreamView.userContent.isMember(spaceId, MembershipOp.SO_JOIN)).toBe(true)
100100
})
101101

102+
// Verify that the bot's userInfo includes the appAddress
103+
const spaceStream = spaceOwner.stream(spaceId)
104+
await spaceOwner.waitForStream(spaceId)
105+
expect(spaceStream).toBeDefined()
106+
const botUserInfo = spaceStream!.view.getMemberMetadata().userInfo(bot.userId)
107+
expect(botUserInfo.appAddress?.toLowerCase()).toBe(foundAppAddress.toLowerCase())
108+
102109
// Have space owner add the bot to the channel
103110
await expect(spaceOwner.joinUser(channelId, bot.userId)).resolves.toBeDefined()
104111

@@ -212,6 +219,12 @@ describe('bot membership tests', () => {
212219
expect(botUserStreamView.userContent.isMember(spaceId, MembershipOp.SO_JOIN)).toBe(true)
213220
})
214221

222+
// Verify that the bot's userInfo includes the appAddress
223+
const spaceStream = spaceOwner.stream(spaceId)
224+
expect(spaceStream).toBeDefined()
225+
const botUserInfo = spaceStream!.view.getMemberMetadata().userInfo(bot.userId)
226+
expect(botUserInfo.appAddress).toBe(foundAppAddress)
227+
215228
// Space owner CAN add bot to default channel despite bot not satisfying entitlements
216229
await expect(spaceOwner.joinUser(defaultChannelId, bot.userId)).resolves.toBeDefined()
217230

packages/sdk/src/tests/multi_ne/memberMetadata.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,20 @@ describe('memberMetadataTests', () => {
7575
}
7676
})
7777

78+
test('clientDoesntHaveAppAddress', async () => {
79+
await expect(bobsClient.initializeUser()).resolves.not.toThrow()
80+
bobsClient.startSync()
81+
82+
const streamId = makeUniqueSpaceStreamId()
83+
await bobsClient.createSpace(streamId)
84+
await bobsClient.waitForStream(streamId)
85+
86+
const streamView = bobsClient.streams.get(streamId)!.view
87+
expect(streamView.getMemberMetadata().userInfo(bobsClient.userId).appAddress).toEqual(
88+
undefined,
89+
)
90+
})
91+
7892
test('clientCanSetDisplayNamesInDM', async () => {
7993
await expect(bobsClient.initializeUser()).resolves.not.toThrow()
8094
bobsClient.startSync()
@@ -313,6 +327,9 @@ describe('memberMetadataTests', () => {
313327
for (const client of [bobsClient, alicesClient]) {
314328
const streamView = client.streams.get(streamId)!.view
315329
expect(streamView.getMemberMetadata()?.usernames.plaintextUsernames).toEqual(expected)
330+
expect(
331+
streamView.getMemberMetadata()?.userInfo(client.userId).appAddress,
332+
).toBeUndefined()
316333
}
317334
})
318335

0 commit comments

Comments
 (0)