diff --git a/packages/sdk/src/updateRole.test.ts b/packages/sdk/src/updateRole.test.ts new file mode 100644 index 000000000..a9c898fa2 --- /dev/null +++ b/packages/sdk/src/updateRole.test.ts @@ -0,0 +1,32 @@ +/** + * @group with-v2-entitlements + */ + +import { createTownWithRequirements, updateRole } from './util.test' +import { NoopRuleData, UpdateRoleParams, Permission, EVERYONE_ADDRESS } from '@river-build/web3' + +describe('updateRole', () => { + test('user-gated space created with no-op ruleData allows updates on minter role', async () => { + const { bobSpaceDapp, bobProvider, spaceId } = await createTownWithRequirements({ + everyone: false, + users: ['alice'], + ruleData: NoopRuleData, + }) + + // Update role to be ungated + const { error } = await updateRole( + bobSpaceDapp, + bobProvider, + { + spaceNetworkId: spaceId, + roleId: 1, // Minter role id + roleName: 'Updated minter role', + permissions: [Permission.JoinSpace], + users: [EVERYONE_ADDRESS], + ruleData: NoopRuleData, + } as UpdateRoleParams, + bobProvider.signer, + ) + expect(error).toBeUndefined() + }) +}) diff --git a/packages/sdk/src/util.test.ts b/packages/sdk/src/util.test.ts index 6c34cd5c6..1eadf0f82 100644 --- a/packages/sdk/src/util.test.ts +++ b/packages/sdk/src/util.test.ts @@ -75,6 +75,7 @@ import { encodeERC1155Params, convertRuleDataV2ToV1, XchainConfig, + UpdateRoleParams, } from '@river-build/web3' const log = dlog('csb:test:util') @@ -945,6 +946,36 @@ export async function createRole( return { roleId, error: roleError } } +export interface UpdateRoleContext { + error: Error | undefined +} + +export async function updateRole( + spaceDapp: ISpaceDapp, + provider: ethers.providers.Provider, + params: UpdateRoleParams, + signer: ethers.Signer, +): Promise { + let txn: ethers.ContractTransaction | undefined = undefined + let error: Error | undefined = undefined + if (useLegacySpaces()) { + throw new Error('updateRole is v2 only') + } + try { + txn = await spaceDapp.updateRole(params, signer) + } catch (err) { + error = spaceDapp.parseSpaceError(params.spaceNetworkId, err) + return { error } + } + + const receipt = await provider.waitForTransaction(txn.hash) + if (receipt.status === 0) { + return { error: new Error('Transaction failed') } + } + + return { error: undefined } +} + export interface CreateChannelContext { channelId: string | undefined error: Error | undefined diff --git a/packages/web3/src/entitlement.ts b/packages/web3/src/entitlement.ts index ea0c2a1f2..fde3bb49c 100644 --- a/packages/web3/src/entitlement.ts +++ b/packages/web3/src/entitlement.ts @@ -289,6 +289,11 @@ export function decodeRuleData(entitlementData: Hex): IRuleEntitlementBase.RuleD } export function encodeRuleDataV2(ruleData: IRuleEntitlementV2Base.RuleDataV2Struct): Hex { + // If we encounter a no-op rule data, just encode as empty bytes. + if (ruleData.operations.length === 0) { + return '0x' + } + const getRuleDataV2Abi: ExtractAbiFunction = getAbiItem({ abi: IRuleEntitlementV2Abi,