@towns-labs/sdk 2.0.5 → 2.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/createApp.d.ts.map +1 -1
- package/dist/createApp.js +7 -1
- package/dist/createApp.js.map +1 -1
- package/dist/id.d.ts +1 -0
- package/dist/id.d.ts.map +1 -1
- package/dist/id.js +3 -0
- package/dist/id.js.map +1 -1
- package/dist/streamStateView_Members.d.ts +7 -0
- package/dist/streamStateView_Members.d.ts.map +1 -1
- package/dist/streamStateView_Members.js +19 -0
- package/dist/streamStateView_Members.js.map +1 -1
- package/dist/sync-agent/dms/models/dm.d.ts +2 -4
- package/dist/sync-agent/dms/models/dm.d.ts.map +1 -1
- package/dist/sync-agent/dms/models/dm.js +2 -30
- package/dist/sync-agent/dms/models/dm.js.map +1 -1
- package/dist/sync-agent/gdms/models/gdm.d.ts +2 -4
- package/dist/sync-agent/gdms/models/gdm.d.ts.map +1 -1
- package/dist/sync-agent/gdms/models/gdm.js +2 -30
- package/dist/sync-agent/gdms/models/gdm.js.map +1 -1
- package/dist/sync-agent/river-connection/riverConnection.d.ts +1 -3
- package/dist/sync-agent/river-connection/riverConnection.d.ts.map +1 -1
- package/dist/sync-agent/river-connection/riverConnection.js +5 -3
- package/dist/sync-agent/river-connection/riverConnection.js.map +1 -1
- package/dist/sync-agent/spaces/models/channel.d.ts +3 -6
- package/dist/sync-agent/spaces/models/channel.d.ts.map +1 -1
- package/dist/sync-agent/spaces/models/channel.js +4 -76
- package/dist/sync-agent/spaces/models/channel.js.map +1 -1
- package/dist/sync-agent/spaces/models/space.d.ts +6 -6
- package/dist/sync-agent/spaces/models/space.d.ts.map +1 -1
- package/dist/sync-agent/spaces/models/space.js +8 -30
- package/dist/sync-agent/spaces/models/space.js.map +1 -1
- package/dist/sync-agent/spaces/spaces.d.ts +3 -4
- package/dist/sync-agent/spaces/spaces.d.ts.map +1 -1
- package/dist/sync-agent/spaces/spaces.js +6 -25
- package/dist/sync-agent/spaces/spaces.js.map +1 -1
- package/dist/sync-agent/syncAgent.d.ts.map +1 -1
- package/dist/sync-agent/syncAgent.js +2 -7
- package/dist/sync-agent/syncAgent.js.map +1 -1
- package/dist/tests/multi_ne/gdms.test.js +50 -3
- package/dist/tests/multi_ne/gdms.test.js.map +1 -1
- package/dist/tests/multi_ne/userInboxMessage.test.js +3 -3
- package/dist/tests/multi_ne/userInboxMessage.test.js.map +1 -1
- package/dist/townsEnv.js +5 -5
- package/dist/townsEnv.js.map +1 -1
- package/package.json +10 -10
- package/dist/createBot.d.ts +0 -159
- package/dist/createBot.d.ts.map +0 -1
- package/dist/createBot.js +0 -206
- package/dist/createBot.js.map +0 -1
- package/dist/makeRiverRpcClient.d.ts +0 -6
- package/dist/makeRiverRpcClient.d.ts.map +0 -1
- package/dist/makeRiverRpcClient.js +0 -9
- package/dist/makeRiverRpcClient.js.map +0 -1
- package/dist/streamStateView_ChannelMetadata.d.ts +0 -22
- package/dist/streamStateView_ChannelMetadata.d.ts.map +0 -1
- package/dist/streamStateView_ChannelMetadata.js +0 -77
- package/dist/streamStateView_ChannelMetadata.js.map +0 -1
- package/dist/sync-agent/entitlements/entitlements.d.ts +0 -10
- package/dist/sync-agent/entitlements/entitlements.d.ts.map +0 -1
- package/dist/sync-agent/entitlements/entitlements.js +0 -20
- package/dist/sync-agent/entitlements/entitlements.js.map +0 -1
- package/dist/sync-agent/river-connection/models/riverChain.d.ts +0 -24
- package/dist/sync-agent/river-connection/models/riverChain.d.ts.map +0 -1
- package/dist/sync-agent/river-connection/models/riverChain.js +0 -66
- package/dist/sync-agent/river-connection/models/riverChain.js.map +0 -1
- package/dist/tests/multi/appRegistryService.test.d.ts +0 -2
- package/dist/tests/multi/appRegistryService.test.d.ts.map +0 -1
- package/dist/tests/multi/appRegistryService.test.js +0 -41
- package/dist/tests/multi/appRegistryService.test.js.map +0 -1
- package/dist/tests/multi/botEntitlements.test.d.ts +0 -5
- package/dist/tests/multi/botEntitlements.test.d.ts.map +0 -1
- package/dist/tests/multi/botEntitlements.test.js +0 -178
- package/dist/tests/multi/botEntitlements.test.js.map +0 -1
- package/dist/tests/multi/botMembership.test.d.ts +0 -5
- package/dist/tests/multi/botMembership.test.d.ts.map +0 -1
- package/dist/tests/multi/botMembership.test.js +0 -295
- package/dist/tests/multi/botMembership.test.js.map +0 -1
- package/dist/tests/multi/botStreamCreation.test.d.ts +0 -5
- package/dist/tests/multi/botStreamCreation.test.d.ts.map +0 -1
- package/dist/tests/multi/botStreamCreation.test.js +0 -60
- package/dist/tests/multi/botStreamCreation.test.js.map +0 -1
- package/dist/tests/multi/channelScrubbing.test.d.ts +0 -5
- package/dist/tests/multi/channelScrubbing.test.d.ts.map +0 -1
- package/dist/tests/multi/channelScrubbing.test.js +0 -102
- package/dist/tests/multi/channelScrubbing.test.js.map +0 -1
- package/dist/tests/multi/notificationService.test.d.ts +0 -2
- package/dist/tests/multi/notificationService.test.d.ts.map +0 -1
- package/dist/tests/multi/notificationService.test.js +0 -51
- package/dist/tests/multi/notificationService.test.js.map +0 -1
- package/dist/tests/multi/sync-agent/member-queue.test.d.ts +0 -2
- package/dist/tests/multi/sync-agent/member-queue.test.d.ts.map +0 -1
- package/dist/tests/multi/sync-agent/member-queue.test.js +0 -54
- package/dist/tests/multi/sync-agent/member-queue.test.js.map +0 -1
- package/dist/tests/multi/sync-agent/member.test.d.ts +0 -2
- package/dist/tests/multi/sync-agent/member.test.d.ts.map +0 -1
- package/dist/tests/multi/sync-agent/member.test.js +0 -45
- package/dist/tests/multi/sync-agent/member.test.js.map +0 -1
- package/dist/tests/multi/sync-agent/members.test.d.ts +0 -2
- package/dist/tests/multi/sync-agent/members.test.d.ts.map +0 -1
- package/dist/tests/multi/sync-agent/members.test.js +0 -35
- package/dist/tests/multi/sync-agent/members.test.js.map +0 -1
- package/dist/tests/multi/sync-agent/riverConnection.test.d.ts +0 -5
- package/dist/tests/multi/sync-agent/riverConnection.test.d.ts.map +0 -1
- package/dist/tests/multi/sync-agent/riverConnection.test.js +0 -39
- package/dist/tests/multi/sync-agent/riverConnection.test.js.map +0 -1
- package/dist/tests/multi/sync-agent/spaces.test.d.ts +0 -2
- package/dist/tests/multi/sync-agent/spaces.test.d.ts.map +0 -1
- package/dist/tests/multi/sync-agent/spaces.test.js +0 -33
- package/dist/tests/multi/sync-agent/spaces.test.js.map +0 -1
- package/dist/tests/multi/sync-agent/streams.test.d.ts +0 -2
- package/dist/tests/multi/sync-agent/streams.test.d.ts.map +0 -1
- package/dist/tests/multi/sync-agent/streams.test.js +0 -27
- package/dist/tests/multi/sync-agent/streams.test.js.map +0 -1
- package/dist/tests/multi/sync-agent/syncAgent.test.d.ts +0 -2
- package/dist/tests/multi/sync-agent/syncAgent.test.d.ts.map +0 -1
- package/dist/tests/multi/sync-agent/syncAgent.test.js +0 -68
- package/dist/tests/multi/sync-agent/syncAgent.test.js.map +0 -1
- package/dist/tests/multi/sync-agent/syncAgents.test.d.ts +0 -2
- package/dist/tests/multi/sync-agent/syncAgents.test.d.ts.map +0 -1
- package/dist/tests/multi/sync-agent/syncAgents.test.js +0 -163
- package/dist/tests/multi/sync-agent/syncAgents.test.js.map +0 -1
- package/dist/tests/multi/sync-agent/timeline.test.d.ts +0 -2
- package/dist/tests/multi/sync-agent/timeline.test.d.ts.map +0 -1
- package/dist/tests/multi/sync-agent/timeline.test.js +0 -232
- package/dist/tests/multi/sync-agent/timeline.test.js.map +0 -1
- package/dist/tests/multi/sync-agent/user.test.d.ts +0 -5
- package/dist/tests/multi/sync-agent/user.test.d.ts.map +0 -1
- package/dist/tests/multi/sync-agent/user.test.js +0 -55
- package/dist/tests/multi/sync-agent/user.test.js.map +0 -1
- package/dist/tests/multi/transactions.test.d.ts +0 -5
- package/dist/tests/multi/transactions.test.d.ts.map +0 -1
- package/dist/tests/multi/transactions.test.js +0 -153
- package/dist/tests/multi/transactions.test.js.map +0 -1
- package/dist/tests/multi/transactions_SpaceReview.test.d.ts +0 -2
- package/dist/tests/multi/transactions_SpaceReview.test.d.ts.map +0 -1
- package/dist/tests/multi/transactions_SpaceReview.test.js +0 -278
- package/dist/tests/multi/transactions_SpaceReview.test.js.map +0 -1
- package/dist/tests/multi/transactions_Tip.test.d.ts +0 -5
- package/dist/tests/multi/transactions_Tip.test.d.ts.map +0 -1
- package/dist/tests/multi/transactions_Tip.test.js +0 -379
- package/dist/tests/multi/transactions_Tip.test.js.map +0 -1
- package/dist/tests/multi_ne/nodeSelection.test.d.ts +0 -5
- package/dist/tests/multi_ne/nodeSelection.test.d.ts.map +0 -1
- package/dist/tests/multi_ne/nodeSelection.test.js +0 -41
- package/dist/tests/multi_ne/nodeSelection.test.js.map +0 -1
- package/dist/tests/multi_ne/trading.solana.test.d.ts +0 -2
- package/dist/tests/multi_ne/trading.solana.test.d.ts.map +0 -1
- package/dist/tests/multi_ne/trading.solana.test.js +0 -229
- package/dist/tests/multi_ne/trading.solana.test.js.map +0 -1
- package/dist/tests/multi_ne/trading.test.d.ts +0 -2
- package/dist/tests/multi_ne/trading.test.d.ts.map +0 -1
- package/dist/tests/multi_ne/trading.test.js +0 -243
- package/dist/tests/multi_ne/trading.test.js.map +0 -1
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @group with-entitlements
|
|
3
|
-
*/
|
|
4
|
-
import { AppRegistryDapp, Permission, SpaceAddressFromSpaceId } from '@towns-protocol/web3';
|
|
5
|
-
import { createSpaceAndDefaultChannel, everyoneMembershipStruct, setupWalletsAndContexts, waitFor, createChannel, } from '../testUtils';
|
|
6
|
-
import { townsEnv } from '../../townsEnv';
|
|
7
|
-
import { ethers } from 'ethers';
|
|
8
|
-
import { MembershipOp } from '@towns-protocol/proto';
|
|
9
|
-
import { make_MemberPayload_KeySolicitation } from '../../types';
|
|
10
|
-
describe('bot entitlements tests', () => {
|
|
11
|
-
test('bot has READ permissions to channels when granted by isAppEntitled', async () => {
|
|
12
|
-
const { bob: bot, bobsWallet: botWallet, bobProvider: botProvider, carol: spaceOwner, carolProvider: spaceOwnerProvider, carolSpaceDapp: spaceOwnerSpaceDapp, } = await setupWalletsAndContexts();
|
|
13
|
-
const appRegistryDapp = new AppRegistryDapp(townsEnv().makeBaseChainConfig().chainConfig, spaceOwnerProvider);
|
|
14
|
-
// Create bot app contract with READ permission only
|
|
15
|
-
const tx = await appRegistryDapp.createApp(botProvider.signer, 'read-only-bot', [Permission.Read], // Only READ permission, no WRITE
|
|
16
|
-
botWallet.address, ethers.utils.parseEther('0.01').toBigInt(), 31536000n);
|
|
17
|
-
const receipt = await tx.wait();
|
|
18
|
-
const { app: foundAppAddress } = appRegistryDapp.getCreateAppEvent(receipt, botWallet.address);
|
|
19
|
-
expect(foundAppAddress).toBeDefined();
|
|
20
|
-
// Create bot user streams
|
|
21
|
-
await expect(bot.initializeUser({ appAddress: foundAppAddress })).resolves.toBeDefined();
|
|
22
|
-
bot.startSync();
|
|
23
|
-
// Create a town with channels (everyone can join)
|
|
24
|
-
const everyoneMembership = await everyoneMembershipStruct(spaceOwnerSpaceDapp, spaceOwner);
|
|
25
|
-
const { spaceId } = await createSpaceAndDefaultChannel(spaceOwner, spaceOwnerSpaceDapp, spaceOwnerProvider.wallet, "space owner's town", everyoneMembership);
|
|
26
|
-
// Install the bot to the space (as space owner)
|
|
27
|
-
const installTx = await appRegistryDapp.installApp(spaceOwnerProvider.signer, foundAppAddress, SpaceAddressFromSpaceId(spaceId), ethers.utils.parseEther('0.02').toBigInt());
|
|
28
|
-
const installReceipt = await installTx.wait();
|
|
29
|
-
expect(installReceipt.status).toBe(1);
|
|
30
|
-
// This channel has no roles attached, so the bot can only gain READ permissions through
|
|
31
|
-
// isAppEntitled.
|
|
32
|
-
const { channelId: restrictedChannelId, error: channelError } = await createChannel(spaceOwnerSpaceDapp, spaceOwnerProvider, spaceId, 'channel-without-roles', [], spaceOwnerProvider.wallet);
|
|
33
|
-
expect(channelError).toBeUndefined();
|
|
34
|
-
expect(restrictedChannelId).toBeDefined();
|
|
35
|
-
// Create the channel stream
|
|
36
|
-
const { streamId: returnedChannelId } = await spaceOwner.createChannel(spaceId, 'channel-without-roles', '', restrictedChannelId);
|
|
37
|
-
expect(returnedChannelId).toEqual(restrictedChannelId);
|
|
38
|
-
// Have space owner add bot to space and channel
|
|
39
|
-
await expect(spaceOwner.joinUser(spaceId, bot.userId)).resolves.toBeDefined();
|
|
40
|
-
await expect(spaceOwner.joinUser(restrictedChannelId, bot.userId)).resolves.toBeDefined();
|
|
41
|
-
// Validate bot is a member of both space and channel
|
|
42
|
-
const botUserStreamView = bot.stream(bot.userStreamId).view;
|
|
43
|
-
await waitFor(() => {
|
|
44
|
-
expect(botUserStreamView.userContent.isMember(spaceId, MembershipOp.SO_JOIN)).toBe(true);
|
|
45
|
-
expect(botUserStreamView.userContent.isMember(restrictedChannelId, MembershipOp.SO_JOIN)).toBe(true);
|
|
46
|
-
});
|
|
47
|
-
// Force miniblocks with snapshots for both space and channel streams
|
|
48
|
-
// The test will now fail if app address is not properly propogated through member snapshots.
|
|
49
|
-
const spaceStream = spaceOwner.stream(spaceId);
|
|
50
|
-
const channelStream = spaceOwner.stream(restrictedChannelId);
|
|
51
|
-
await waitFor(async () => {
|
|
52
|
-
const response = await spaceOwner.debugForceMakeMiniblock(spaceId, {
|
|
53
|
-
forceSnapshot: true,
|
|
54
|
-
lastKnownMiniblockNum: spaceStream.view.miniblockInfo.max,
|
|
55
|
-
});
|
|
56
|
-
expect(response).toBeDefined();
|
|
57
|
-
});
|
|
58
|
-
await waitFor(async () => {
|
|
59
|
-
const response = await spaceOwner.debugForceMakeMiniblock(restrictedChannelId, {
|
|
60
|
-
forceSnapshot: true,
|
|
61
|
-
lastKnownMiniblockNum: channelStream.view.miniblockInfo.max,
|
|
62
|
-
});
|
|
63
|
-
expect(response).toBeDefined();
|
|
64
|
-
});
|
|
65
|
-
// Bot should be able to post a key solicitation because it has READ permission through isAppEntitled
|
|
66
|
-
// Key solicitations require READ permission, not WRITE permission
|
|
67
|
-
const payload = make_MemberPayload_KeySolicitation({
|
|
68
|
-
deviceKey: 'bot-device-key',
|
|
69
|
-
sessionIds: ['aaa'],
|
|
70
|
-
fallbackKey: 'bot-fallback-key',
|
|
71
|
-
isNewDevice: true,
|
|
72
|
-
});
|
|
73
|
-
// This should succeed because the bot has READ permission via app entitlements
|
|
74
|
-
await bot.makeEventAndAddToStream(restrictedChannelId, payload);
|
|
75
|
-
// Cleanup
|
|
76
|
-
await bot.stopSync();
|
|
77
|
-
await spaceOwner.stopSync();
|
|
78
|
-
});
|
|
79
|
-
test('bot has write permissions to channels when granted by isAppEntitled', async () => {
|
|
80
|
-
const { alice: spaceOwner, aliceProvider: spaceOwnerProvider, aliceSpaceDapp: spaceOwnerSpaceDapp, bob: botWithoutWrite, bobsWallet: botWithoutWriteWallet, bobProvider: botWithoutWriteProvider, carol: botWithWrite, carolsWallet: botWithWriteWallet, carolProvider: botWithWriteProvider, } = await setupWalletsAndContexts();
|
|
81
|
-
const appRegistryDapp = new AppRegistryDapp(townsEnv().makeBaseChainConfig().chainConfig, spaceOwnerProvider);
|
|
82
|
-
// Create first bot app contract with READ permission only (no WRITE)
|
|
83
|
-
const tx1 = await appRegistryDapp.createApp(botWithoutWriteProvider.signer, 'read-only-bot', [Permission.Read], // Only READ permission, no WRITE
|
|
84
|
-
botWithoutWriteWallet.address, ethers.utils.parseEther('0.01').toBigInt(), 31536000n);
|
|
85
|
-
const receipt1 = await tx1.wait();
|
|
86
|
-
const { app: readOnlyBotAddress } = appRegistryDapp.getCreateAppEvent(receipt1, botWithoutWriteWallet.address);
|
|
87
|
-
expect(readOnlyBotAddress).toBeDefined();
|
|
88
|
-
// Create second bot app contract with both READ and WRITE permissions
|
|
89
|
-
const tx2 = await appRegistryDapp.createApp(botWithWriteProvider.signer, 'read-write-bot', [Permission.Read, Permission.Write], // Both READ and WRITE permissions
|
|
90
|
-
botWithWriteWallet.address, ethers.utils.parseEther('0.01').toBigInt(), 31536000n);
|
|
91
|
-
const receipt2 = await tx2.wait();
|
|
92
|
-
const { app: readWriteBotAddress } = appRegistryDapp.getCreateAppEvent(receipt2, botWithWriteWallet.address);
|
|
93
|
-
expect(readWriteBotAddress).toBeDefined();
|
|
94
|
-
// Create bot user streams for both bots
|
|
95
|
-
await expect(botWithoutWrite.initializeUser({ appAddress: readOnlyBotAddress })).resolves.toBeDefined();
|
|
96
|
-
await expect(botWithWrite.initializeUser({ appAddress: readWriteBotAddress })).resolves.toBeDefined();
|
|
97
|
-
botWithoutWrite.startSync();
|
|
98
|
-
botWithWrite.startSync();
|
|
99
|
-
// Create a town with channels (everyone can join)
|
|
100
|
-
const everyoneMembership = await everyoneMembershipStruct(spaceOwnerSpaceDapp, spaceOwner);
|
|
101
|
-
const { spaceId, defaultChannelId } = await createSpaceAndDefaultChannel(spaceOwner, spaceOwnerSpaceDapp, spaceOwnerProvider.wallet, "space owner's town", everyoneMembership);
|
|
102
|
-
// Install both bots to the space (as space owner)
|
|
103
|
-
const installTx1 = await appRegistryDapp.installApp(spaceOwnerProvider.signer, readOnlyBotAddress, SpaceAddressFromSpaceId(spaceId), ethers.utils.parseEther('0.02').toBigInt());
|
|
104
|
-
const installReceipt1 = await installTx1.wait();
|
|
105
|
-
expect(installReceipt1.status).toBe(1);
|
|
106
|
-
const installTx2 = await appRegistryDapp.installApp(spaceOwnerProvider.signer, readWriteBotAddress, SpaceAddressFromSpaceId(spaceId), ethers.utils.parseEther('0.02').toBigInt());
|
|
107
|
-
const installReceipt2 = await installTx2.wait();
|
|
108
|
-
expect(installReceipt2.status).toBe(1);
|
|
109
|
-
// Verify both bots are installed
|
|
110
|
-
const space = spaceOwnerSpaceDapp.getSpace(spaceId);
|
|
111
|
-
const installedApps = await space.AppAccount.read.getInstalledApps();
|
|
112
|
-
expect(installedApps).toContain(readOnlyBotAddress);
|
|
113
|
-
expect(installedApps).toContain(readWriteBotAddress);
|
|
114
|
-
// Have space owner add both bots to space and default channel
|
|
115
|
-
await expect(spaceOwner.joinUser(spaceId, botWithoutWrite.userId)).resolves.toBeDefined();
|
|
116
|
-
await expect(spaceOwner.joinUser(defaultChannelId, botWithoutWrite.userId)).resolves.toBeDefined();
|
|
117
|
-
await expect(spaceOwner.joinUser(spaceId, botWithWrite.userId)).resolves.toBeDefined();
|
|
118
|
-
await expect(spaceOwner.joinUser(defaultChannelId, botWithWrite.userId)).resolves.toBeDefined();
|
|
119
|
-
// Validate both bots are members of space and default channel
|
|
120
|
-
const botWithoutWriteUserStreamView = botWithoutWrite.stream(botWithoutWrite.userStreamId).view;
|
|
121
|
-
const botWithWriteUserStreamView = botWithWrite.stream(botWithWrite.userStreamId).view;
|
|
122
|
-
await waitFor(() => {
|
|
123
|
-
expect(botWithoutWriteUserStreamView.userContent.isMember(spaceId, MembershipOp.SO_JOIN)).toBe(true);
|
|
124
|
-
expect(botWithoutWriteUserStreamView.userContent.isMember(defaultChannelId, MembershipOp.SO_JOIN)).toBe(true);
|
|
125
|
-
expect(botWithWriteUserStreamView.userContent.isMember(spaceId, MembershipOp.SO_JOIN)).toBe(true);
|
|
126
|
-
expect(botWithWriteUserStreamView.userContent.isMember(defaultChannelId, MembershipOp.SO_JOIN)).toBe(true);
|
|
127
|
-
});
|
|
128
|
-
// Bot without WRITE permission should NOT be able to post a message
|
|
129
|
-
await expect(botWithoutWrite.sendMessage(defaultChannelId, 'Message from read-only bot')).rejects.toThrow(/PERMISSION_DENIED/);
|
|
130
|
-
// Bot with WRITE permission should be able to post a message
|
|
131
|
-
await expect(botWithWrite.sendMessage(defaultChannelId, 'Message from read-write bot')).resolves.not.toThrow();
|
|
132
|
-
// Cleanup
|
|
133
|
-
await botWithoutWrite.stopSync();
|
|
134
|
-
await botWithWrite.stopSync();
|
|
135
|
-
await spaceOwner.stopSync();
|
|
136
|
-
});
|
|
137
|
-
// TODO: flaky test
|
|
138
|
-
test.skip('bot does not have write permissions to channels when not granted by isAppEntitled', async () => {
|
|
139
|
-
const { alice: spaceOwner, aliceProvider: spaceOwnerProvider, aliceSpaceDapp: spaceOwnerSpaceDapp, bob: bot, bobsWallet: botWallet, bobProvider: botProvider, } = await setupWalletsAndContexts();
|
|
140
|
-
const appRegistryDapp = new AppRegistryDapp(townsEnv().makeBaseChainConfig().chainConfig, spaceOwnerProvider);
|
|
141
|
-
// Create bot app contract with READ permission only (no WRITE)
|
|
142
|
-
const tx = await appRegistryDapp.createApp(botProvider.signer, 'read-only-bot-no-write', [Permission.Read], // Only READ permission, no WRITE
|
|
143
|
-
botWallet.address, ethers.utils.parseEther('0.01').toBigInt(), 31536000n);
|
|
144
|
-
const receipt = await tx.wait();
|
|
145
|
-
const { app: foundAppAddress } = appRegistryDapp.getCreateAppEvent(receipt, botWallet.address);
|
|
146
|
-
expect(foundAppAddress).toBeDefined();
|
|
147
|
-
// Create bot user streams
|
|
148
|
-
await expect(bot.initializeUser({ appAddress: foundAppAddress })).resolves.toBeDefined();
|
|
149
|
-
bot.startSync();
|
|
150
|
-
// Create a town with channels where everyone can join and has write permissions
|
|
151
|
-
const everyoneMembership = await everyoneMembershipStruct(spaceOwnerSpaceDapp, spaceOwner);
|
|
152
|
-
const { spaceId, defaultChannelId } = await createSpaceAndDefaultChannel(spaceOwner, spaceOwnerSpaceDapp, spaceOwnerProvider.wallet, "space owner's town", everyoneMembership);
|
|
153
|
-
// Install the bot to the space (as space owner)
|
|
154
|
-
const installTx = await appRegistryDapp.installApp(spaceOwnerProvider.signer, foundAppAddress, SpaceAddressFromSpaceId(spaceId), ethers.utils.parseEther('0.02').toBigInt());
|
|
155
|
-
const installReceipt = await installTx.wait();
|
|
156
|
-
expect(installReceipt.status).toBe(1);
|
|
157
|
-
// Verify bot is installed
|
|
158
|
-
const space = spaceOwnerSpaceDapp.getSpace(spaceId);
|
|
159
|
-
const installedApps = await space.AppAccount.read.getInstalledApps();
|
|
160
|
-
expect(installedApps).toContain(foundAppAddress);
|
|
161
|
-
// Have space owner add bot to space and default channel
|
|
162
|
-
await expect(spaceOwner.joinUser(spaceId, bot.userId)).resolves.toBeDefined();
|
|
163
|
-
await expect(spaceOwner.joinUser(defaultChannelId, bot.userId)).resolves.toBeDefined();
|
|
164
|
-
// Validate bot is a member of both space and channel
|
|
165
|
-
const botUserStreamView = bot.stream(bot.userStreamId).view;
|
|
166
|
-
await waitFor(() => {
|
|
167
|
-
expect(botUserStreamView.userContent.isMember(spaceId, MembershipOp.SO_JOIN)).toBe(true);
|
|
168
|
-
expect(botUserStreamView.userContent.isMember(defaultChannelId, MembershipOp.SO_JOIN)).toBe(true);
|
|
169
|
-
});
|
|
170
|
-
// Bot should NOT be able to post a message because it lacks WRITE permission through isAppEntitled
|
|
171
|
-
// Even though the space grants write permissions to all users, the bot's app contract only has READ permission
|
|
172
|
-
await expect(bot.sendMessage(defaultChannelId, 'Message from read-only bot')).rejects.toThrow(/PERMISSION_DENIED/);
|
|
173
|
-
// Cleanup
|
|
174
|
-
await bot.stopSync();
|
|
175
|
-
await spaceOwner.stopSync();
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
//# sourceMappingURL=botEntitlements.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"botEntitlements.test.js","sourceRoot":"","sources":["../../../src/tests/multi/botEntitlements.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"botMembership.test.d.ts","sourceRoot":"","sources":["../../../src/tests/multi/botMembership.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @group with-entitlements
|
|
3
|
-
*/
|
|
4
|
-
import { AppRegistryDapp, Permission, SpaceAddressFromSpaceId, NoopRuleData, } from '@towns-protocol/web3';
|
|
5
|
-
import { createSpaceAndDefaultChannel, everyoneMembershipStruct, setupWalletsAndContexts, waitFor, createTownWithRequirements, createChannel, getXchainConfigForTesting, } from '../testUtils';
|
|
6
|
-
import { townsEnv } from '../../townsEnv';
|
|
7
|
-
import { ethers } from 'ethers';
|
|
8
|
-
import { MembershipOp } from '@towns-protocol/proto';
|
|
9
|
-
describe('bot membership tests', () => {
|
|
10
|
-
test('registered and installed bots can join spaces and channels', async () => {
|
|
11
|
-
const { aliceProvider: ownerProvider, bob: bot, bobsWallet: botWallet, bobProvider: botProvider, carol: spaceOwner, carolProvider: spaceOwnerProvider, carolSpaceDapp: spaceOwnerSpaceDapp, } = await setupWalletsAndContexts();
|
|
12
|
-
const appRegistryDapp = new AppRegistryDapp(townsEnv().makeBaseChainConfig().chainConfig, ownerProvider);
|
|
13
|
-
// Create bot app contract
|
|
14
|
-
const tx = await appRegistryDapp.createApp(botProvider.signer, 'bob-bot', [Permission.Read, Permission.Write], botWallet.address, ethers.utils.parseEther('0.01').toBigInt(), 31536000n);
|
|
15
|
-
const receipt = await tx.wait();
|
|
16
|
-
const { app: foundAppAddress } = appRegistryDapp.getCreateAppEvent(receipt, botWallet.address);
|
|
17
|
-
expect(foundAppAddress).toBeDefined();
|
|
18
|
-
// Create bot user streams
|
|
19
|
-
await expect(bot.initializeUser({ appAddress: foundAppAddress })).resolves.toBeDefined();
|
|
20
|
-
bot.startSync();
|
|
21
|
-
// Create a town with channels
|
|
22
|
-
const everyoneMembership = await everyoneMembershipStruct(spaceOwnerSpaceDapp, spaceOwner);
|
|
23
|
-
const { spaceId, defaultChannelId: channelId } = await createSpaceAndDefaultChannel(spaceOwner, spaceOwnerSpaceDapp, spaceOwnerProvider.wallet, "space owner's town", everyoneMembership);
|
|
24
|
-
// Install the bot to the space
|
|
25
|
-
const tx2 = await appRegistryDapp.installApp(spaceOwnerProvider.signer, foundAppAddress, SpaceAddressFromSpaceId(spaceId), ethers.utils.parseEther('0.02').toBigInt());
|
|
26
|
-
// Confirm installation transaction succeeded
|
|
27
|
-
const receipt2 = await tx2.wait();
|
|
28
|
-
expect(receipt2.status).toBe(1);
|
|
29
|
-
const space = spaceOwnerSpaceDapp.getSpace(spaceId);
|
|
30
|
-
expect(space).toBeDefined();
|
|
31
|
-
// Sanity check: the spaceDapp reports that the app is installed.
|
|
32
|
-
const installedApps = await space.AppAccount.read.getInstalledApps();
|
|
33
|
-
expect(installedApps).toContain(foundAppAddress);
|
|
34
|
-
// Have space owner add the bot to the space
|
|
35
|
-
await spaceOwner.joinUser(spaceId, bot.userId);
|
|
36
|
-
// Validate the bot is now a member of both space and channel
|
|
37
|
-
const botUserStreamView = bot.stream(bot.userStreamId).view;
|
|
38
|
-
expect(botUserStreamView).toBeDefined();
|
|
39
|
-
await waitFor(() => {
|
|
40
|
-
expect(botUserStreamView.userContent.isMember(spaceId, MembershipOp.SO_JOIN)).toBe(true);
|
|
41
|
-
});
|
|
42
|
-
// Verify that the bot's userInfo includes the appAddress
|
|
43
|
-
const spaceStream = spaceOwner.stream(spaceId);
|
|
44
|
-
await spaceOwner.waitForStream(spaceId);
|
|
45
|
-
expect(spaceStream).toBeDefined();
|
|
46
|
-
const botUserInfo = spaceStream.view.getMemberMetadata().userInfo(bot.userId);
|
|
47
|
-
expect(botUserInfo.appAddress?.toLowerCase()).toBe(foundAppAddress.toLowerCase());
|
|
48
|
-
// Have space owner add the bot to the channel
|
|
49
|
-
await expect(spaceOwner.joinUser(channelId, bot.userId)).resolves.toBeDefined();
|
|
50
|
-
// Validate that the bot is a channel member
|
|
51
|
-
await waitFor(() => {
|
|
52
|
-
expect(botUserStreamView.userContent.isMember(channelId, MembershipOp.SO_JOIN)).toBe(true);
|
|
53
|
-
});
|
|
54
|
-
// Cleanup
|
|
55
|
-
await bot.stopSync();
|
|
56
|
-
await spaceOwner.stopSync();
|
|
57
|
-
});
|
|
58
|
-
test('registered and installed bots can join spaces and channels in towns with gated membership', async () => {
|
|
59
|
-
// Create a town with user entitlements that only allows 'bob' (space owner)
|
|
60
|
-
// The bot is NOT in this list, so it doesn't satisfy the space entitlements.
|
|
61
|
-
// Thus we know the bot is disqualified for regular membership by the gating
|
|
62
|
-
// and can only be admitted to the space via the bot entitlement pathway.
|
|
63
|
-
const { spaceId, channelId: defaultChannelId, bob: spaceOwner, bobProvider: spaceOwnerProvider, bobSpaceDapp: spaceOwnerSpaceDapp, alice: bot, alicesWallet: botWallet, aliceProvider: botProvider, } = await createTownWithRequirements({
|
|
64
|
-
everyone: false,
|
|
65
|
-
users: ['bob'], // No one but the space owner can join this town
|
|
66
|
-
ruleData: NoopRuleData,
|
|
67
|
-
});
|
|
68
|
-
const appRegistryDapp = new AppRegistryDapp(townsEnv().makeBaseChainConfig().chainConfig, spaceOwnerProvider);
|
|
69
|
-
// Create bot app contract
|
|
70
|
-
const tx = await appRegistryDapp.createApp(botProvider.signer, 'bot-restricted-test', [Permission.Read, Permission.Write], botWallet.address, ethers.utils.parseEther('0.01').toBigInt(), 31536000n);
|
|
71
|
-
const receipt = await tx.wait();
|
|
72
|
-
const { app: foundAppAddress } = appRegistryDapp.getCreateAppEvent(receipt, botWallet.address);
|
|
73
|
-
expect(foundAppAddress).toBeDefined();
|
|
74
|
-
// Create bot user streams
|
|
75
|
-
await expect(bot.initializeUser({ appAddress: foundAppAddress })).resolves.toBeDefined();
|
|
76
|
-
bot.startSync();
|
|
77
|
-
// Install the bot to the space (as space owner)
|
|
78
|
-
const installTx = await appRegistryDapp.installApp(spaceOwnerProvider.signer, foundAppAddress, SpaceAddressFromSpaceId(spaceId), ethers.utils.parseEther('0.02').toBigInt());
|
|
79
|
-
const installReceipt = await installTx.wait();
|
|
80
|
-
expect(installReceipt.status).toBe(1);
|
|
81
|
-
// Verify bot is installed
|
|
82
|
-
const space = spaceOwnerSpaceDapp.getSpace(spaceId);
|
|
83
|
-
const installedApps = await space.AppAccount.read.getInstalledApps();
|
|
84
|
-
expect(installedApps).toContain(foundAppAddress);
|
|
85
|
-
// Create a custom channel with user entitlements that disallows all users.
|
|
86
|
-
// The bot naturally doesn't satisfy the channel entitlements.
|
|
87
|
-
const { channelId: restrictedChannelId, error: channelError } = await createChannel(spaceOwnerSpaceDapp, spaceOwnerProvider, spaceId, 'restricted-channel', [], // No role IDs - no users qualify for admission to this channel.
|
|
88
|
-
spaceOwnerProvider.wallet);
|
|
89
|
-
expect(channelError).toBeUndefined();
|
|
90
|
-
expect(restrictedChannelId).toBeDefined();
|
|
91
|
-
const { streamId: returnedChannelId } = await spaceOwner.createChannel(spaceId, 'restricted-channel', '', restrictedChannelId);
|
|
92
|
-
expect(returnedChannelId).toEqual(restrictedChannelId);
|
|
93
|
-
// Verify that the bot does NOT satisfy space entitlements.
|
|
94
|
-
const botEntitledWallet = await spaceOwnerSpaceDapp.getEntitledWalletForJoiningSpace(spaceId, botWallet.address, getXchainConfigForTesting());
|
|
95
|
-
expect(botEntitledWallet).toBeUndefined(); // Bot should NOT be entitled
|
|
96
|
-
// Space owner CAN add bot to space despite bot not satisfying entitlements
|
|
97
|
-
await expect(spaceOwner.joinUser(spaceId, bot.userId)).resolves.toBeDefined();
|
|
98
|
-
// Validate bot is a space member
|
|
99
|
-
const botUserStreamView = bot.stream(bot.userStreamId).view;
|
|
100
|
-
await waitFor(() => {
|
|
101
|
-
expect(botUserStreamView.userContent.isMember(spaceId, MembershipOp.SO_JOIN)).toBe(true);
|
|
102
|
-
});
|
|
103
|
-
// Verify that the bot's userInfo includes the appAddress
|
|
104
|
-
const spaceStream = spaceOwner.stream(spaceId);
|
|
105
|
-
expect(spaceStream).toBeDefined();
|
|
106
|
-
const botUserInfo = spaceStream.view.getMemberMetadata().userInfo(bot.userId);
|
|
107
|
-
expect(botUserInfo.appAddress).toBe(foundAppAddress);
|
|
108
|
-
// Space owner CAN add bot to default channel despite bot not satisfying entitlements
|
|
109
|
-
await expect(spaceOwner.joinUser(defaultChannelId, bot.userId)).resolves.toBeDefined();
|
|
110
|
-
// Validate bot is a default channel member
|
|
111
|
-
await waitFor(() => {
|
|
112
|
-
expect(botUserStreamView.userContent.isMember(defaultChannelId, MembershipOp.SO_JOIN)).toBe(true);
|
|
113
|
-
});
|
|
114
|
-
// Space owner CAN add bot to restricted channel despite bot not satisfying channel entitlements
|
|
115
|
-
await expect(spaceOwner.joinUser(restrictedChannelId, bot.userId)).resolves.toBeDefined();
|
|
116
|
-
// Validate bot is a restricted channel member
|
|
117
|
-
await waitFor(() => {
|
|
118
|
-
expect(botUserStreamView.userContent.isMember(restrictedChannelId, MembershipOp.SO_JOIN)).toBe(true);
|
|
119
|
-
});
|
|
120
|
-
// Cleanup
|
|
121
|
-
await bot.stopSync();
|
|
122
|
-
await spaceOwner.stopSync();
|
|
123
|
-
});
|
|
124
|
-
test('an uninstalled bot cannot join a space or channel', async () => {
|
|
125
|
-
const { aliceProvider: ownerProvider, bob: bot, bobsWallet: botWallet, bobProvider: botProvider, carol: spaceOwner, carolProvider: spaceOwnerProvider, carolSpaceDapp: spaceOwnerSpaceDapp, } = await setupWalletsAndContexts();
|
|
126
|
-
const appRegistryDapp = new AppRegistryDapp(townsEnv().makeBaseChainConfig().chainConfig, ownerProvider);
|
|
127
|
-
// Create bot app contract
|
|
128
|
-
const tx = await appRegistryDapp.createApp(botProvider.signer, 'bob-bot', [Permission.Read, Permission.Write], botWallet.address, ethers.utils.parseEther('0.01').toBigInt(), 31536000n);
|
|
129
|
-
const receipt = await tx.wait();
|
|
130
|
-
const { app: foundAppAddress } = appRegistryDapp.getCreateAppEvent(receipt, botWallet.address);
|
|
131
|
-
expect(foundAppAddress).toBeDefined();
|
|
132
|
-
// Create bot user streams
|
|
133
|
-
await expect(bot.initializeUser({ appAddress: foundAppAddress })).resolves.toBeDefined();
|
|
134
|
-
bot.startSync();
|
|
135
|
-
// Create a town with channels
|
|
136
|
-
const everyoneMembership = await everyoneMembershipStruct(spaceOwnerSpaceDapp, spaceOwner);
|
|
137
|
-
const { spaceId, defaultChannelId: channelId } = await createSpaceAndDefaultChannel(spaceOwner, spaceOwnerSpaceDapp, spaceOwnerProvider.wallet, "space owner's town", everyoneMembership);
|
|
138
|
-
// NOTE: We do NOT install the bot to the space (unlike the previous test)
|
|
139
|
-
// This is the key difference - the bot is registered but not installed
|
|
140
|
-
const space = spaceOwnerSpaceDapp.getSpace(spaceId);
|
|
141
|
-
expect(space).toBeDefined();
|
|
142
|
-
// Sanity check: the spaceDapp reports that the app is NOT installed
|
|
143
|
-
const installedApps = await space.AppAccount.read.getInstalledApps();
|
|
144
|
-
expect(installedApps).not.toContain(foundAppAddress);
|
|
145
|
-
// Space owner tries to add the uninstalled bot to the space - this should fail
|
|
146
|
-
await expect(spaceOwner.joinUser(spaceId, bot.userId)).rejects.toThrow();
|
|
147
|
-
// Space owner tries to add the uninstalled bot to the channel - this should also fail
|
|
148
|
-
await expect(spaceOwner.joinUser(channelId, bot.userId)).rejects.toThrow();
|
|
149
|
-
// Clean up
|
|
150
|
-
await bot.stopSync();
|
|
151
|
-
await spaceOwner.stopSync();
|
|
152
|
-
});
|
|
153
|
-
test('a non-owner member cannot add or remove a bot as a space or channel member', async () => {
|
|
154
|
-
const { alice: nonOwnerMember, aliceProvider: nonOwnerProvider, alicesWallet: nonOwnerWallet, bob: bot, bobsWallet: botWallet, bobProvider: botProvider, carol: spaceOwner, carolProvider: spaceOwnerProvider, carolSpaceDapp: spaceOwnerSpaceDapp, } = await setupWalletsAndContexts();
|
|
155
|
-
const appRegistryDapp = new AppRegistryDapp(townsEnv().makeBaseChainConfig().chainConfig, spaceOwnerProvider);
|
|
156
|
-
// Create bot app contract
|
|
157
|
-
const tx = await appRegistryDapp.createApp(botProvider.signer, 'bob-bot', [Permission.Read, Permission.Write], botWallet.address, ethers.utils.parseEther('0.01').toBigInt(), 31536000n);
|
|
158
|
-
const receipt = await tx.wait();
|
|
159
|
-
const { app: foundAppAddress } = appRegistryDapp.getCreateAppEvent(receipt, botWallet.address);
|
|
160
|
-
expect(foundAppAddress).toBeDefined();
|
|
161
|
-
// Create bot user streams
|
|
162
|
-
await expect(bot.initializeUser({ appAddress: foundAppAddress })).resolves.toBeDefined();
|
|
163
|
-
bot.startSync();
|
|
164
|
-
// Create a town with channels (everyone can join)
|
|
165
|
-
const everyoneMembership = await everyoneMembershipStruct(spaceOwnerSpaceDapp, spaceOwner);
|
|
166
|
-
const { spaceId, defaultChannelId: channelId } = await createSpaceAndDefaultChannel(spaceOwner, spaceOwnerSpaceDapp, spaceOwnerProvider.wallet, "space owner's town", everyoneMembership);
|
|
167
|
-
// Install the bot to the space (as space owner)
|
|
168
|
-
const installTx = await appRegistryDapp.installApp(spaceOwnerProvider.signer, foundAppAddress, SpaceAddressFromSpaceId(spaceId), ethers.utils.parseEther('0.02').toBigInt());
|
|
169
|
-
const installReceipt = await installTx.wait();
|
|
170
|
-
expect(installReceipt.status).toBe(1);
|
|
171
|
-
// Verify bot is installed
|
|
172
|
-
const space = spaceOwnerSpaceDapp.getSpace(spaceId);
|
|
173
|
-
const installedApps = await space.AppAccount.read.getInstalledApps();
|
|
174
|
-
expect(installedApps).toContain(foundAppAddress);
|
|
175
|
-
// Create a spaceDapp for the non-owner member
|
|
176
|
-
const nonOwnerSpaceDapp = spaceOwnerSpaceDapp; // They can use the same spaceDapp instance
|
|
177
|
-
// Have non-owner member join the space and channel
|
|
178
|
-
const { issued } = await nonOwnerSpaceDapp.joinSpace(spaceId, nonOwnerWallet.address, nonOwnerProvider.wallet);
|
|
179
|
-
expect(issued).toBe(true);
|
|
180
|
-
await nonOwnerMember.initializeUser({ spaceId });
|
|
181
|
-
nonOwnerMember.startSync();
|
|
182
|
-
await expect(nonOwnerMember.joinStream(spaceId)).resolves.not.toThrow();
|
|
183
|
-
await expect(nonOwnerMember.joinStream(channelId)).resolves.not.toThrow();
|
|
184
|
-
// First test that non-owner member CANNOT add bot to space (even though bot is installed)
|
|
185
|
-
await expect(nonOwnerMember.joinUser(spaceId, bot.userId)).rejects.toThrow(/PERMISSION_DENIED/);
|
|
186
|
-
// Validate that bot is NOT a space member yet
|
|
187
|
-
const botUserStreamView = bot.stream(bot.userStreamId).view;
|
|
188
|
-
expect(botUserStreamView.userContent.isMember(spaceId, MembershipOp.SO_JOIN)).toBe(false);
|
|
189
|
-
// Have space owner add bot to space (so we can test channel membership)
|
|
190
|
-
await expect(spaceOwner.joinUser(spaceId, bot.userId)).resolves.toBeDefined();
|
|
191
|
-
// Validate bot is now a space member
|
|
192
|
-
await waitFor(() => {
|
|
193
|
-
expect(botUserStreamView.userContent.isMember(spaceId, MembershipOp.SO_JOIN)).toBe(true);
|
|
194
|
-
});
|
|
195
|
-
// Now test that non-owner member CANNOT add bot to channel (even though bot is installed and space member)
|
|
196
|
-
await expect(nonOwnerMember.joinUser(channelId, bot.userId)).rejects.toThrow(/PERMISSION_DENIED/);
|
|
197
|
-
// Validate that bot is still NOT a channel member
|
|
198
|
-
expect(botUserStreamView.userContent.isMember(channelId, MembershipOp.SO_JOIN)).toBe(false);
|
|
199
|
-
// Also test that non-owner member cannot remove bot from space
|
|
200
|
-
await expect(nonOwnerMember.removeUser(spaceId, bot.userId)).rejects.toThrow(/PERMISSION_DENIED/);
|
|
201
|
-
// Validate bot is still a space member
|
|
202
|
-
expect(botUserStreamView.userContent.isMember(spaceId, MembershipOp.SO_JOIN)).toBe(true);
|
|
203
|
-
// Now, let's confirm the non-owner member cannot boot the bot from the channel.
|
|
204
|
-
// Have space owner add bot to channel
|
|
205
|
-
await expect(spaceOwner.joinUser(channelId, bot.userId)).resolves.toBeDefined();
|
|
206
|
-
// Validate bot is now a channel member
|
|
207
|
-
await waitFor(() => {
|
|
208
|
-
expect(botUserStreamView.userContent.isMember(channelId, MembershipOp.SO_JOIN)).toBe(true);
|
|
209
|
-
});
|
|
210
|
-
// Test that non-owner member CANNOT remove bot from channel
|
|
211
|
-
await expect(nonOwnerMember.removeUser(channelId, bot.userId)).rejects.toThrow(/PERMISSION_DENIED/);
|
|
212
|
-
// Validate bot is still a channel member
|
|
213
|
-
expect(botUserStreamView.userContent.isMember(channelId, MembershipOp.SO_JOIN)).toBe(true);
|
|
214
|
-
// Cleanup
|
|
215
|
-
await bot.stopSync();
|
|
216
|
-
await spaceOwner.stopSync();
|
|
217
|
-
await nonOwnerMember.stopSync();
|
|
218
|
-
});
|
|
219
|
-
test('the bot itself cannot add itself to the space or to channels', async () => {
|
|
220
|
-
const { bob: bot, bobsWallet: botWallet, bobProvider: botProvider, carol: spaceOwner, carolProvider: spaceOwnerProvider, carolSpaceDapp: spaceOwnerSpaceDapp, } = await setupWalletsAndContexts();
|
|
221
|
-
const appRegistryDapp = new AppRegistryDapp(townsEnv().makeBaseChainConfig().chainConfig, spaceOwnerProvider);
|
|
222
|
-
// Create bot app contract
|
|
223
|
-
const tx = await appRegistryDapp.createApp(botProvider.signer, 'self-join-test-bot', [Permission.Read, Permission.Write], botWallet.address, ethers.utils.parseEther('0.01').toBigInt(), 31536000n);
|
|
224
|
-
const receipt = await tx.wait();
|
|
225
|
-
const { app: foundAppAddress } = appRegistryDapp.getCreateAppEvent(receipt, botWallet.address);
|
|
226
|
-
expect(foundAppAddress).toBeDefined();
|
|
227
|
-
// Create bot user streams
|
|
228
|
-
await expect(bot.initializeUser({ appAddress: foundAppAddress })).resolves.toBeDefined();
|
|
229
|
-
bot.startSync();
|
|
230
|
-
// Create a town with channels (everyone can join)
|
|
231
|
-
const everyoneMembership = await everyoneMembershipStruct(spaceOwnerSpaceDapp, spaceOwner);
|
|
232
|
-
const { spaceId, defaultChannelId: channelId } = await createSpaceAndDefaultChannel(spaceOwner, spaceOwnerSpaceDapp, spaceOwnerProvider.wallet, "space owner's town", everyoneMembership);
|
|
233
|
-
// Install the bot to the space (as space owner)
|
|
234
|
-
const installTx = await appRegistryDapp.installApp(spaceOwnerProvider.signer, foundAppAddress, SpaceAddressFromSpaceId(spaceId), ethers.utils.parseEther('0.02').toBigInt());
|
|
235
|
-
const installReceipt = await installTx.wait();
|
|
236
|
-
expect(installReceipt.status).toBe(1);
|
|
237
|
-
// Verify bot is installed
|
|
238
|
-
const space = spaceOwnerSpaceDapp.getSpace(spaceId);
|
|
239
|
-
const installedApps = await space.AppAccount.read.getInstalledApps();
|
|
240
|
-
expect(installedApps).toContain(foundAppAddress);
|
|
241
|
-
// Test that bot CANNOT add itself to space (even though bot is installed)
|
|
242
|
-
await expect(bot.joinUser(spaceId, bot.userId)).rejects.toThrow(/PERMISSION_DENIED/);
|
|
243
|
-
// Validate that bot is NOT a space member
|
|
244
|
-
const botUserStreamView = bot.stream(bot.userStreamId).view;
|
|
245
|
-
expect(botUserStreamView.userContent.isMember(spaceId, MembershipOp.SO_JOIN)).toBe(false);
|
|
246
|
-
// Have space owner add bot to space (so we can test channel self-join)
|
|
247
|
-
await expect(spaceOwner.joinUser(spaceId, bot.userId)).resolves.toBeDefined();
|
|
248
|
-
// Validate bot is now a space member
|
|
249
|
-
await waitFor(() => {
|
|
250
|
-
expect(botUserStreamView.userContent.isMember(spaceId, MembershipOp.SO_JOIN)).toBe(true);
|
|
251
|
-
});
|
|
252
|
-
// Test that bot CANNOT add itself to channel (even though bot is installed and space member)
|
|
253
|
-
await expect(bot.joinUser(channelId, bot.userId)).rejects.toThrow(/PERMISSION_DENIED/);
|
|
254
|
-
// Validate that bot is still NOT a channel member
|
|
255
|
-
expect(botUserStreamView.userContent.isMember(channelId, MembershipOp.SO_JOIN)).toBe(false);
|
|
256
|
-
// Also test that bot cannot remove itself from space
|
|
257
|
-
await expect(bot.removeUser(spaceId, bot.userId)).rejects.toThrow(/PERMISSION_DENIED/);
|
|
258
|
-
// Validate bot is still a space member
|
|
259
|
-
expect(botUserStreamView.userContent.isMember(spaceId, MembershipOp.SO_JOIN)).toBe(true);
|
|
260
|
-
// Have space owner add bot to channel (so we can test channel self-removal)
|
|
261
|
-
await expect(spaceOwner.joinUser(channelId, bot.userId)).resolves.toBeDefined();
|
|
262
|
-
// Validate bot is now a channel member
|
|
263
|
-
await waitFor(() => {
|
|
264
|
-
expect(botUserStreamView.userContent.isMember(channelId, MembershipOp.SO_JOIN)).toBe(true);
|
|
265
|
-
});
|
|
266
|
-
// Test that bot CANNOT remove itself from channel
|
|
267
|
-
await expect(bot.removeUser(channelId, bot.userId)).rejects.toThrow(/PERMISSION_DENIED/);
|
|
268
|
-
// Validate bot is still a channel member
|
|
269
|
-
expect(botUserStreamView.userContent.isMember(channelId, MembershipOp.SO_JOIN)).toBe(true);
|
|
270
|
-
// Cleanup
|
|
271
|
-
await bot.stopSync();
|
|
272
|
-
await spaceOwner.stopSync();
|
|
273
|
-
});
|
|
274
|
-
// skipped because nothing is preventing you from creating dms or gdms with bots
|
|
275
|
-
test.skip('bots cannot be added to DMs or GDMs', async () => {
|
|
276
|
-
const { alice, aliceProvider, // owner
|
|
277
|
-
aliceSpaceDapp, bob: bot, bobsWallet: botWallet, bobProvider: botProvider, carol, carolSpaceDapp, carolProvider, } = await setupWalletsAndContexts();
|
|
278
|
-
const appRegistryDapp = new AppRegistryDapp(townsEnv().makeBaseChainConfig().chainConfig, aliceProvider);
|
|
279
|
-
const tx = await appRegistryDapp.createApp(botProvider.signer, 'bob-bot', [Permission.Read, Permission.Write], botWallet.address, ethers.utils.parseEther('0.01').toBigInt(), 31536000n);
|
|
280
|
-
const receipt = await tx.wait();
|
|
281
|
-
const { app: foundAppAddress } = appRegistryDapp.getCreateAppEvent(receipt, botWallet.address);
|
|
282
|
-
expect(foundAppAddress).toBeDefined();
|
|
283
|
-
const everyoneMembership = await everyoneMembershipStruct(carolSpaceDapp, carol);
|
|
284
|
-
const { spaceId } = await createSpaceAndDefaultChannel(carol, carolSpaceDapp, carolProvider.wallet, "space owner's town", everyoneMembership);
|
|
285
|
-
await aliceSpaceDapp.joinSpace(spaceId, alice.userId, aliceProvider.wallet);
|
|
286
|
-
await expect(bot.initializeUser({ appAddress: foundAppAddress })).resolves.toBeDefined();
|
|
287
|
-
await expect(alice.initializeUser({ spaceId })).resolves.toBeDefined();
|
|
288
|
-
// GDMs with bot creators are disallowed.
|
|
289
|
-
// (carol and dave don't have user streams yet)
|
|
290
|
-
await expect(carol.createGDMChannel([bot.userId, alice.userId])).rejects.toThrow(/PERMISSION_DENIED/);
|
|
291
|
-
// DMs with bot creators are disallowed.
|
|
292
|
-
await expect(carol.createDMChannel(bot.userId)).rejects.toThrow(/PERMISSION_DENIED/);
|
|
293
|
-
});
|
|
294
|
-
});
|
|
295
|
-
//# sourceMappingURL=botMembership.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"botMembership.test.js","sourceRoot":"","sources":["../../../src/tests/multi/botMembership.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"botStreamCreation.test.d.ts","sourceRoot":"","sources":["../../../src/tests/multi/botStreamCreation.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @group with-entitlements
|
|
3
|
-
*/
|
|
4
|
-
import { AppRegistryDapp, Permission, SpaceAddressFromSpaceId } from '@towns-protocol/web3';
|
|
5
|
-
import { createSpaceAndDefaultChannel, everyoneMembershipStruct, setupWalletsAndContexts, expectUserCanJoin, } from '../testUtils';
|
|
6
|
-
import { townsEnv } from '../../townsEnv';
|
|
7
|
-
import { makeDefaultChannelStreamId } from '../../id';
|
|
8
|
-
import { ethers } from 'ethers';
|
|
9
|
-
describe('bot stream creation tests', () => {
|
|
10
|
-
test('registered bots can only create app user streams with their registered app address', async () => {
|
|
11
|
-
const { aliceProvider: ownerProvider, bob: bot1, bobsWallet: bot1Wallet, bobProvider: bot1Provider, carol: bot2, carolsWallet: bot2Wallet, carolProvider: bot2Provider, } = await setupWalletsAndContexts();
|
|
12
|
-
const appRegistryDapp = new AppRegistryDapp(townsEnv().makeBaseChainConfig().chainConfig, ownerProvider);
|
|
13
|
-
// Create first bot app contract
|
|
14
|
-
const tx1 = await appRegistryDapp.createApp(bot1Provider.signer, 'bot1-app', [Permission.Read, Permission.Write], bot1Wallet.address, ethers.utils.parseEther('0.01').toBigInt(), 31536000n);
|
|
15
|
-
const receipt1 = await tx1.wait();
|
|
16
|
-
const { app: bot1AppAddress } = appRegistryDapp.getCreateAppEvent(receipt1, bot1Wallet.address);
|
|
17
|
-
expect(bot1AppAddress).toBeDefined();
|
|
18
|
-
// Create second bot app contract
|
|
19
|
-
const tx2 = await appRegistryDapp.createApp(bot2Provider.signer, 'bot2-app', [Permission.Read, Permission.Write], bot2Wallet.address, ethers.utils.parseEther('0.01').toBigInt(), 31536000n);
|
|
20
|
-
const receipt2 = await tx2.wait();
|
|
21
|
-
const { app: bot2AppAddress } = appRegistryDapp.getCreateAppEvent(receipt2, bot2Wallet.address);
|
|
22
|
-
expect(bot2AppAddress).toBeDefined();
|
|
23
|
-
// Attempt to create user streams for bot1 using bot2's app address (should fail)
|
|
24
|
-
await expect(bot1.initializeUser({ appAddress: bot2AppAddress })).rejects.toThrow(/7:PERMISSION_DENIED/);
|
|
25
|
-
// Create user streams for bot2 using its own app address (should succeed)
|
|
26
|
-
expect(await bot2.initializeUser({ appAddress: bot2AppAddress })).toBeDefined();
|
|
27
|
-
});
|
|
28
|
-
test('unregistered bots cannot create app user streams', async () => {
|
|
29
|
-
const { alicesWallet: wallet, bob: bot } = await setupWalletsAndContexts();
|
|
30
|
-
// Let's use the public key of the wallet as the bot's contract address for
|
|
31
|
-
// convenience here.
|
|
32
|
-
await expect(bot.initializeUser({ appAddress: wallet.address })).rejects.toThrow(/7:PERMISSION_DENIED/);
|
|
33
|
-
});
|
|
34
|
-
// TODO: re-enable this test when the app registry contract is validated and deployed to all
|
|
35
|
-
// environments.
|
|
36
|
-
test.skip('bots cannot create dms or gdms', async () => {
|
|
37
|
-
// DMs and GDMs are created by the bot posting messages to it's own user stream. This message type
|
|
38
|
-
// should be rejected as unpermitted for bots.
|
|
39
|
-
const { aliceProvider, alicesWallet, alice, aliceSpaceDapp, bob: bot, bobsWallet: botWallet, bobProvider: botProvider, carol, carolProvider, carolSpaceDapp, } = await setupWalletsAndContexts();
|
|
40
|
-
const appRegistryDapp = new AppRegistryDapp(townsEnv().makeBaseChainConfig().chainConfig, botProvider);
|
|
41
|
-
const tx = await appRegistryDapp.createApp(botProvider.signer, 'bob-bot', [Permission.Read, Permission.Write], botWallet.address, ethers.utils.parseEther('0.01').toBigInt(), 31536000n);
|
|
42
|
-
const receipt = await tx.wait();
|
|
43
|
-
const { app: foundAppAddress } = appRegistryDapp.getCreateAppEvent(receipt, botWallet.address);
|
|
44
|
-
expect(foundAppAddress).toBeDefined();
|
|
45
|
-
expect(await bot.initializeUser({ appAddress: foundAppAddress })).toBeDefined();
|
|
46
|
-
// Have Carol create a space on the spaceDapp
|
|
47
|
-
const everyoneMembership = await everyoneMembershipStruct(carolSpaceDapp, carol);
|
|
48
|
-
const { spaceId } = await createSpaceAndDefaultChannel(carol, carolSpaceDapp, carolProvider.wallet, "carol's space", everyoneMembership);
|
|
49
|
-
// Add Dave as a member to Carol's space
|
|
50
|
-
await expectUserCanJoin(spaceId, makeDefaultChannelStreamId(SpaceAddressFromSpaceId(spaceId)), 'alice', alice, aliceSpaceDapp, alicesWallet.address, aliceProvider.wallet);
|
|
51
|
-
// GDMs with bot creators are disallowed.
|
|
52
|
-
await expect(bot.createGDMChannel([carol.userId, alice.userId])).rejects.toThrow(/PERMISSION_DENIED/);
|
|
53
|
-
// DMs with bot creators are disallowed.
|
|
54
|
-
await expect(bot.createDMChannel(alice.userId)).rejects.toThrow(/PERMISSION_DENIED/);
|
|
55
|
-
// Cleanup
|
|
56
|
-
await carol.stopSync();
|
|
57
|
-
await alice.stopSync();
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
//# sourceMappingURL=botStreamCreation.test.js.map
|