@towns-labs/sdk 2.0.4 → 2.0.6
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/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/townsEnv.d.ts +6 -1
- package/dist/townsEnv.d.ts.map +1 -1
- package/dist/townsEnv.js +29 -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_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,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
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"botStreamCreation.test.js","sourceRoot":"","sources":["../../../src/tests/multi/botStreamCreation.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"channelScrubbing.test.d.ts","sourceRoot":"","sources":["../../../src/tests/multi/channelScrubbing.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @group with-entitlements
|
|
3
|
-
*/
|
|
4
|
-
import { MembershipOp, MembershipReason } from '@towns-protocol/proto';
|
|
5
|
-
import { makeUserStreamId } from '../../id';
|
|
6
|
-
import { getNftRuleData, linkWallets, unlinkWallet, setupChannelWithCustomRole, expectUserCanJoinChannel, waitFor, setupWalletsAndContexts, everyoneMembershipStruct, createSpaceAndDefaultChannel, } from '../testUtils';
|
|
7
|
-
import { dlog } from '@towns-protocol/utils';
|
|
8
|
-
import { TestERC721, AppRegistryDapp, Permission, SpaceAddressFromSpaceId, } from '@towns-protocol/web3';
|
|
9
|
-
import { ethers } from 'ethers';
|
|
10
|
-
import { townsEnv } from '../../townsEnv';
|
|
11
|
-
const log = dlog('csb:test:channelsWithEntitlements');
|
|
12
|
-
describe('channelScrubbing', () => {
|
|
13
|
-
test('User who loses entitlements is bounced after a channel scrub is triggered', async () => {
|
|
14
|
-
const TestNftName = 'TestNFT';
|
|
15
|
-
const TestNftAddress = await TestERC721.getContractAddress(TestNftName);
|
|
16
|
-
const { alice, aliceSpaceDapp, aliceProvider, carol, carolSpaceDapp, carolProvider, spaceId, channelId, } = await setupChannelWithCustomRole([], getNftRuleData(TestNftAddress));
|
|
17
|
-
const aliceLinkedWallet = ethers.Wallet.createRandom();
|
|
18
|
-
const carolLinkedWallet = ethers.Wallet.createRandom();
|
|
19
|
-
// link wallets
|
|
20
|
-
await Promise.all([
|
|
21
|
-
linkWallets(aliceSpaceDapp, aliceProvider.wallet, aliceLinkedWallet),
|
|
22
|
-
linkWallets(carolSpaceDapp, carolProvider.wallet, carolLinkedWallet),
|
|
23
|
-
]);
|
|
24
|
-
// Mint the needed asset to Alice and Carol's linked wallets
|
|
25
|
-
log('Minting an NFT to alices linked wallet');
|
|
26
|
-
await Promise.all([
|
|
27
|
-
TestERC721.publicMint(TestNftName, aliceLinkedWallet.address),
|
|
28
|
-
TestERC721.publicMint(TestNftName, carolLinkedWallet.address),
|
|
29
|
-
]);
|
|
30
|
-
// Join alice to the channel based on her linked wallet credentials
|
|
31
|
-
await expectUserCanJoinChannel(alice, aliceSpaceDapp, spaceId, channelId);
|
|
32
|
-
await unlinkWallet(aliceSpaceDapp, aliceProvider.wallet, aliceLinkedWallet);
|
|
33
|
-
// Wait 5 seconds so the channel stream will become eligible for scrubbing
|
|
34
|
-
await new Promise((f) => setTimeout(f, 5000));
|
|
35
|
-
// When carol's join event is added to the stream, it should trigger a scrub, and Alice
|
|
36
|
-
// should be booted from the stream since she unlinked her entitled wallet.
|
|
37
|
-
await expectUserCanJoinChannel(carol, carolSpaceDapp, spaceId, channelId);
|
|
38
|
-
const userStreamView = (await alice.waitForStream(makeUserStreamId(alice.userId))).view;
|
|
39
|
-
// Wait for alice's user stream to have the leave event
|
|
40
|
-
await waitFor(() => {
|
|
41
|
-
const membership = userStreamView.userContent.getMembership(channelId);
|
|
42
|
-
expect(membership?.op).toBe(MembershipOp.SO_LEAVE);
|
|
43
|
-
expect(membership?.reason).toBe(MembershipReason.MR_NOT_ENTITLED);
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
test('Bot loses membership and is scrubbed from channel when uninstalled from space', async () => {
|
|
47
|
-
const { alice: spaceOwner, aliceProvider: spaceOwnerProvider, aliceSpaceDapp: spaceOwnerSpaceDapp, bob: bot, bobsWallet: botWallet, bobProvider: botProvider, } = await setupWalletsAndContexts();
|
|
48
|
-
const appRegistryDapp = new AppRegistryDapp(townsEnv().makeBaseChainConfig().chainConfig, spaceOwnerProvider);
|
|
49
|
-
// Create bot app contract
|
|
50
|
-
const tx = await appRegistryDapp.createApp(botProvider.signer, 'scrub-test-bot', [Permission.Read, Permission.Write], botWallet.address, ethers.utils.parseEther('0.01').toBigInt(), 31536000n);
|
|
51
|
-
const receipt = await tx.wait();
|
|
52
|
-
const { app: foundAppAddress } = appRegistryDapp.getCreateAppEvent(receipt, botWallet.address);
|
|
53
|
-
expect(foundAppAddress).toBeDefined();
|
|
54
|
-
// Create bot user streams
|
|
55
|
-
await expect(bot.initializeUser({ appAddress: foundAppAddress })).resolves.toBeDefined();
|
|
56
|
-
bot.startSync();
|
|
57
|
-
// Create a town with channels (everyone can join)
|
|
58
|
-
const everyoneMembership = await everyoneMembershipStruct(spaceOwnerSpaceDapp, spaceOwner);
|
|
59
|
-
const { spaceId, defaultChannelId: channelId } = await createSpaceAndDefaultChannel(spaceOwner, spaceOwnerSpaceDapp, spaceOwnerProvider.wallet, "space owner's town", everyoneMembership);
|
|
60
|
-
// Install the bot to the space (as space owner)
|
|
61
|
-
const installTx = await appRegistryDapp.installApp(spaceOwnerProvider.signer, foundAppAddress, SpaceAddressFromSpaceId(spaceId), ethers.utils.parseEther('0.02').toBigInt());
|
|
62
|
-
const installReceipt = await installTx.wait();
|
|
63
|
-
expect(installReceipt.status).toBe(1);
|
|
64
|
-
// Verify bot is installed
|
|
65
|
-
const space = spaceOwnerSpaceDapp.getSpace(spaceId);
|
|
66
|
-
const installedApps = await space.AppAccount.read.getInstalledApps();
|
|
67
|
-
expect(installedApps).toContain(foundAppAddress);
|
|
68
|
-
// Have space owner add bot to space and channel
|
|
69
|
-
await expect(spaceOwner.joinUser(spaceId, bot.userId)).resolves.toBeDefined();
|
|
70
|
-
await expect(spaceOwner.joinUser(channelId, bot.userId)).resolves.toBeDefined();
|
|
71
|
-
// Validate bot is a member of both space and channel
|
|
72
|
-
const botUserStreamView = bot.stream(bot.userStreamId).view;
|
|
73
|
-
await waitFor(() => {
|
|
74
|
-
expect(botUserStreamView.userContent.isMember(spaceId, MembershipOp.SO_JOIN)).toBe(true);
|
|
75
|
-
expect(botUserStreamView.userContent.isMember(channelId, MembershipOp.SO_JOIN)).toBe(true);
|
|
76
|
-
});
|
|
77
|
-
// Uninstall the bot from the space (this should make it lose membership eligibility)
|
|
78
|
-
// Note: Using removeApp method - in a real implementation this might be a different method
|
|
79
|
-
// like uninstallApp, but removeApp should serve the same purpose for testing
|
|
80
|
-
const removeAppTx = await appRegistryDapp.uninstallApp(spaceOwnerProvider.signer, foundAppAddress, space?.Address);
|
|
81
|
-
const removeAppReceipt = await removeAppTx.wait();
|
|
82
|
-
expect(removeAppReceipt.status).toBe(1);
|
|
83
|
-
// Verify bot is no longer installed
|
|
84
|
-
const installedAppsAfterRemoval = await space.AppAccount.read.getInstalledApps();
|
|
85
|
-
expect(installedAppsAfterRemoval).not.toContain(foundAppAddress);
|
|
86
|
-
// Wait 5 seconds so the channel stream will become eligible for scrubbing
|
|
87
|
-
await new Promise((f) => setTimeout(f, 5000));
|
|
88
|
-
// Have the bot attempt to post a message to the channel to trigger scrubbing
|
|
89
|
-
// This should fail with a permission error since the bot is no longer installed/entitled, and trigger a scrub
|
|
90
|
-
await expect(bot.sendMessage(channelId, 'test message from bot')).rejects.toThrow(/PERMISSION_DENIED/);
|
|
91
|
-
// Wait for bot's user stream to have the leave event due to being scrubbed
|
|
92
|
-
await waitFor(() => {
|
|
93
|
-
const membership = botUserStreamView.userContent.getMembership(channelId);
|
|
94
|
-
expect(membership?.op).toBe(MembershipOp.SO_LEAVE);
|
|
95
|
-
expect(membership?.reason).toBe(MembershipReason.MR_NOT_ENTITLED);
|
|
96
|
-
});
|
|
97
|
-
// Cleanup
|
|
98
|
-
await bot.stopSync();
|
|
99
|
-
await spaceOwner.stopSync();
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
//# sourceMappingURL=channelScrubbing.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"channelScrubbing.test.js","sourceRoot":"","sources":["../../../src/tests/multi/channelScrubbing.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nodeSelection.test.d.ts","sourceRoot":"","sources":["../../../src/tests/multi_ne/nodeSelection.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @group main
|
|
3
|
-
*/
|
|
4
|
-
import { dlog } from '@towns-protocol/utils';
|
|
5
|
-
import { ethers } from 'ethers';
|
|
6
|
-
import { LocalhostWeb3Provider, createRiverRegistry } from '@towns-protocol/web3';
|
|
7
|
-
import { townsEnv } from '../../townsEnv';
|
|
8
|
-
const log = dlog('csb:test');
|
|
9
|
-
describe('nodeSelectionsTests', () => {
|
|
10
|
-
test('TestRiverRegistryNodeRetrieval', async () => {
|
|
11
|
-
// set up the web3 provider and riverRegistry
|
|
12
|
-
const riverConfig = townsEnv().makeRiverChainConfig();
|
|
13
|
-
const bobsWallet = ethers.Wallet.createRandom();
|
|
14
|
-
const bobRiverChainProvider = new LocalhostWeb3Provider(riverConfig.rpcUrl, bobsWallet);
|
|
15
|
-
// create river registry
|
|
16
|
-
const riverRegistry = createRiverRegistry(bobRiverChainProvider, riverConfig.chainConfig);
|
|
17
|
-
// read nodes from river registry
|
|
18
|
-
const nodes = await riverRegistry.getAllNodes();
|
|
19
|
-
log('river registry rpc nodes', nodes);
|
|
20
|
-
expect(nodes).toBeDefined();
|
|
21
|
-
if (nodes) {
|
|
22
|
-
expect(Object.values(nodes).length).toBeGreaterThan(0);
|
|
23
|
-
}
|
|
24
|
-
const nodes2 = await riverRegistry.getAllNodes(2);
|
|
25
|
-
log('river registry rpc nodes', nodes);
|
|
26
|
-
expect(nodes2).toBeDefined();
|
|
27
|
-
if (nodes2) {
|
|
28
|
-
expect(Object.values(nodes2).length).toBeGreaterThan(0);
|
|
29
|
-
}
|
|
30
|
-
const nodeUrls = await riverRegistry.getAllNodeUrls();
|
|
31
|
-
log('river registry rpc node urls', nodeUrls);
|
|
32
|
-
expect(nodeUrls).toBeDefined();
|
|
33
|
-
expect(nodeUrls?.length).toBeGreaterThan(0);
|
|
34
|
-
const nodeUrlsOperational = await riverRegistry.getAllNodeUrls(2);
|
|
35
|
-
log('river registry rpc operational node urls', nodeUrls);
|
|
36
|
-
expect(nodeUrlsOperational).toBeDefined();
|
|
37
|
-
expect(nodeUrlsOperational?.length).toBeGreaterThan(0);
|
|
38
|
-
log('Done');
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
//# sourceMappingURL=nodeSelection.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nodeSelection.test.js","sourceRoot":"","sources":["../../../src/tests/multi_ne/nodeSelection.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAA;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AACjF,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,CAAA;AAE5B,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACjC,IAAI,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,6CAA6C;QAC7C,MAAM,WAAW,GAAG,QAAQ,EAAE,CAAC,oBAAoB,EAAE,CAAA;QACrD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,CAAA;QAC/C,MAAM,qBAAqB,GAAG,IAAI,qBAAqB,CAAC,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;QAEvF,wBAAwB;QACxB,MAAM,aAAa,GAAG,mBAAmB,CAAC,qBAAqB,EAAE,WAAW,CAAC,WAAW,CAAC,CAAA;QACzF,iCAAiC;QACjC,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,WAAW,EAAE,CAAA;QAC/C,GAAG,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAA;QACtC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAA;QAC3B,IAAI,KAAK,EAAE,CAAC;YACR,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;QAC1D,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;QACjD,GAAG,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAA;QACtC,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAA;QAC5B,IAAI,MAAM,EAAE,CAAC;YACT,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;QAC3D,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,cAAc,EAAE,CAAA;QACrD,GAAG,CAAC,8BAA8B,EAAE,QAAQ,CAAC,CAAA;QAC7C,MAAM,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAA;QAC9B,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;QAE3C,MAAM,mBAAmB,GAAG,MAAM,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC,CAAA;QACjE,GAAG,CAAC,0CAA0C,EAAE,QAAQ,CAAC,CAAA;QACzD,MAAM,CAAC,mBAAmB,CAAC,CAAC,WAAW,EAAE,CAAA;QACzC,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;QAEtD,GAAG,CAAC,MAAM,CAAC,CAAA;IACf,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"trading.solana.test.d.ts","sourceRoot":"","sources":["../../../src/tests/multi_ne/trading.solana.test.ts"],"names":[],"mappings":""}
|