Skip to content

Commit

Permalink
Merge pull request #151 from lukso-network/addControllerWithPermissions
Browse files Browse the repository at this point in the history
feat: add new controller in list when setting permissions for new address
  • Loading branch information
CJ42 authored Apr 15, 2024
2 parents 56a0e60 + 4baf32a commit a7f6c62
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 56 deletions.
2 changes: 1 addition & 1 deletion .node-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v16.16.0
v18.12.1
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1 +1 @@
nodejs 16.16.0
nodejs 18.12.1
1 change: 1 addition & 0 deletions jest.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ module.exports = {
customExportConditions: ['node', 'node-addons'],
},
globalSetup: './jest.setup.cjs',
testTimeout: 10000,
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"build": "vue-tsc --noEmit && vite build",
"build:cloudflare": "yarn lint:js && yarn lint:css && yarn lint:format && yarn lint:types && yarn test && yarn build",
"preview": "vite preview",
"test": "jest",
"test": "jest --runInBand",
"lint": "npm-run-all --aggregate-output --continue-on-error --parallel 'lint:*!(fix)'",
"lint:js": "eslint src --ext .js,.ts,.vue",
"lint:css": "stylelint \"**/*.{css,scss,vue}\"",
Expand All @@ -18,7 +18,7 @@
"prepare": "husky install"
},
"dependencies": {
"@erc725/erc725.js": "0.24.0",
"@erc725/erc725.js": "0.24.2",
"@lukso/lsp-factory.js": "^3.3.1",
"@lukso/lsp-smart-contracts": "^0.15.0",
"@lukso/web3-onboard-config": "1.1.2",
Expand Down
12 changes: 6 additions & 6 deletions src/components/endpoints/Mint.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import { Lsp4Metadata } from '@/types'
import Lsp4MetadataForm from '@/components/shared/Lsp4MetadataForm.vue'
import {
ContractStandard,
LSP8TokenIdTypes,
LSP8TokenIdTypesData,
LSP8TokenIdFormats,
LSP8TokenIdFormatsData,
} from '@/enums'
import LSPSelect from '@/components/shared/LSPSelect.vue'
import {
Expand Down Expand Up @@ -65,7 +65,7 @@ watchEffect(async () => {
mintToken.value,
LSP8IdentifiableDigitalAsset as ERC725JSONSchema[]
)
const lsp8DigitalAsset = await erc725.fetchData('LSP8TokenIdType')
const lsp8DigitalAsset = await erc725.fetchData('LSP8TokenIdFormat')
tokenIdType.value = Number(lsp8DigitalAsset.value)
}
})
Expand Down Expand Up @@ -182,7 +182,7 @@ const mint = async () => {
})
// set asset metadata
const tokenIdTypeData = LSP8TokenIdTypesData[tokenIdType.value]
const tokenIdTypeData = LSP8TokenIdFormatsData[tokenIdType.value]
const metadataKey = ERC725.encodeKeyName(
`LSP8MetadataTokenURI:<${tokenIdTypeData}>`,
tokenId.value
Expand Down Expand Up @@ -233,8 +233,8 @@ const mint = async () => {
</div>
<div v-if="tokenType === ContractStandard.LSP8" class="field">
<label class="label"
>Token Id ({{ LSP8TokenIdTypes[tokenIdType] }} in
{{ LSP8TokenIdTypesData[tokenIdType] }})</label
>Token Id ({{ LSP8TokenIdFormats[tokenIdType] }} in
{{ LSP8TokenIdFormatsData[tokenIdType] }})</label
>
<div class="control">
<input
Expand Down
49 changes: 44 additions & 5 deletions src/components/endpoints/Permissions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
// @ts-ignore
} from '@lukso/lsp-smart-contracts'
import { Permissions } from '@erc725/erc725.js/build/main/src/types/Method'
import LSP6Schema from '@erc725/erc725.js/schemas/LSP6KeyManager.json'
import { computed, ref } from 'vue'
import useErc725 from '@/compositions/useErc725'
Expand All @@ -18,7 +19,7 @@ import Web3Utils, { hexToNumber, numberToHex, padLeft } from 'web3-utils'
const { notification, clearNotification, hasNotification, setNotification } =
useNotifications()
const { encodePermissions, decodePermissions } = useErc725()
const { encodePermissions, decodePermissions, getInstance } = useErc725()
const grantPermissionAddress = ref('0xaf3bf2ffb025098b79caddfbdd113b3681817744')
const permissions: Permissions = {
CHANGEOWNER: false,
Expand Down Expand Up @@ -59,16 +60,54 @@ const setPermissions = async () => {
clearNotification()
const erc725AccountAddress = getState('address')
const key =
let dataKeysToSet = [
ERC725YDataKeys.LSP6['AddressPermissions:Permissions'] +
grantPermissionAddress.value.slice(2)
const value = encodePermissions(selectedPermissions.value)
grantPermissionAddress.value.slice(2),
]
let dataValuesToSet = [encodePermissions(selectedPermissions.value)]
const erc725js = getInstance(erc725AccountAddress, LSP6Schema)
const controllersDataResult = await erc725js.getData([
'AddressPermissions[]',
{
keyName: 'AddressPermissions:Permissions:<address>',
dynamicKeyParts: grantPermissionAddress.value,
},
])
const [{ value: controllerList }, { value: currentPermissions }] =
controllersDataResult
// if we are setting permissions for a new controller, add it in the list of controller
// and increment the `AddressPermissions[]` Array.
if (
currentPermissions == '0x' ||
currentPermissions == null ||
// we also add the controller in the list if it was not present before
!(controllerList as string[]).includes(grantPermissionAddress.value)
) {
if (controllerList && Array.isArray(controllerList)) {
const encodedControllerList = erc725js.encodeData([
{
keyName: 'AddressPermissions[]',
value: [grantPermissionAddress.value],
totalArrayLength: controllerList.length + 1,
startingIndex: controllerList.length,
},
])
dataKeysToSet.push(...encodedControllerList.keys)
dataValuesToSet.push(...encodedControllerList.values)
}
}
try {
isPending.value = true
window.erc725Account &&
(await window.erc725Account.methods
.setDataBatch([key], [value])
.setDataBatch(dataKeysToSet, dataValuesToSet)
.send({
from: erc725AccountAddress,
})
Expand Down
78 changes: 46 additions & 32 deletions src/components/endpoints/__tests__/Permissions.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Permissions from '../Permissions.vue'
import { render, fireEvent, screen } from '@testing-library/vue'
import { render, fireEvent, screen, waitFor } from '@testing-library/vue'
import { setState } from '@/stores'
import { Contract } from 'web3-eth-contract'

Expand All @@ -26,45 +26,59 @@ window.erc725Account = {
},
} as Contract

beforeEach(() => {
jest.resetAllMocks()
})
describe('Setting Permissions tests', () => {
beforeEach(() => {
jest.resetAllMocks()
})

test('can update permissions for given address', async () => {
setState('address', '0x517216362D594516c6f96Ee34b2c502d65B847E4')
it('can update permissions for given address', async () => {
setState('address', '0x02f02b27eDFcBBDE762Ff2a7FC20a4Aebd495214')

mockSend.mockImplementation(() => ({
on: () => ({
once: () => jest.fn(),
}),
}))
mockSend.mockImplementation(() => ({
on: () => ({
once: () => jest.fn().mockImplementation(() => {}),
}),
}))

render(Permissions)
render(Permissions)

await fireEvent.click(screen.getByTestId('CHANGEOWNER'))
await fireEvent.click(screen.getByTestId('setPermissions'))
fireEvent.click(screen.getByTestId('CHANGEOWNER'))
fireEvent.click(screen.getByTestId('setPermissions'))

expect(screen.getByTestId('notification')).toHaveTextContent(
'Permissions set'
)
expect(mockSend).toBeCalledWith(
['0x4b80742de2bf82acb3630000af3bf2ffb025098b79caddfbdd113b3681817744'],
['0x0000000000000000000000000000000000000000000000000000000000000001']
)
})
await waitFor(() =>
expect(screen.getByTestId('notification')).toHaveTextContent(
'Permissions set'
)
)
expect(mockSend).toBeCalledWith(
[
'0x4b80742de2bf82acb3630000af3bf2ffb025098b79caddfbdd113b3681817744',
'0xdf30dba06db6a30e65354d9a64c609861f089545ca58c6b4dbe31a5f338cb0e3',
'0xdf30dba06db6a30e65354d9a64c6098600000000000000000000000000000007',
],
[
'0x0000000000000000000000000000000000000000000000000000000000000001',
'0x00000000000000000000000000000008',
'0xaf3bf2ffb025098b79caddfbdd113b3681817744',
]
)
})

test('can see set permission error from send function', async () => {
setState('address', '0x517216362D594516c6f96Ee34b2c502d65B847E4')
it('can see set permission error from send function', async () => {
setState('address', '0x02f02b27eDFcBBDE762Ff2a7FC20a4Aebd495214')

mockSend.mockImplementation(() =>
jest.fn().mockImplementation(() => {
throw new Error('Send error')
})()
)
mockSend.mockImplementation(() =>
jest.fn().mockImplementation(() => {
throw new Error('Send error')
})()
)

render(Permissions)
render(Permissions)

await fireEvent.click(screen.getByTestId('setPermissions'))
fireEvent.click(screen.getByTestId('setPermissions'))

expect(screen.getByTestId('notification')).toHaveTextContent('Send error')
await waitFor(() =>
expect(screen.getByTestId('notification')).toHaveTextContent('Send error')
)
})
})
3 changes: 1 addition & 2 deletions src/compositions/useErc725.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ import LSP4DigitalAsset from '@erc725/erc725.js/schemas/LSP4DigitalAsset.json'
import LSP9Vault from '@erc725/erc725.js/schemas/LSP9Vault.json'
import { Permissions } from '@erc725/erc725.js/build/main/src/types/Method'
import { FetchDataOutput } from '@erc725/erc725.js/build/main/src/types/decodeData'
import Web3 from 'web3'
import { getSelectedNetworkConfig } from '@/helpers/config'

window.ERC725 = ERC725

const defaultNetworkConfig = getSelectedNetworkConfig()
const provider = new Web3.providers.HttpProvider(defaultNetworkConfig.rpc.url)
const provider = defaultNetworkConfig.rpc.url
const config = {
ipfsGateway: defaultNetworkConfig.ipfs.url,
}
Expand Down
4 changes: 2 additions & 2 deletions src/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ export enum ContractStandard {
ERC721 = 'ERC721',
}

export const LSP8TokenIdTypes = [
export const LSP8TokenIdFormats = [
'NUMBER',
'STRING',
'UNIQUE_ID',
'HASH',
'ADDRESS',
]

export const LSP8TokenIdTypesData = [
export const LSP8TokenIdFormatsData = [
'uint256',
'string',
'bytes',
Expand Down
10 changes: 5 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -577,16 +577,16 @@ __metadata:
languageName: node
linkType: hard

"@erc725/erc725.js@npm:0.24.0":
version: 0.24.0
resolution: "@erc725/erc725.js@npm:0.24.0"
"@erc725/erc725.js@npm:0.24.2":
version: 0.24.2
resolution: "@erc725/erc725.js@npm:0.24.2"
dependencies:
add: ^2.0.6
ethereumjs-util: ^7.1.5
web3-eth-abi: ^1.10.0
web3-providers-http: ^1.10.0
web3-utils: ^1.10.0
checksum: d82bb1ba19e71d0e407cf543ac8afafd90128f64527570a92be35c4edebb7c50e43fb20e00bd43acc90b0189d3c1439f7fca3d8bd1b9f1a01fabf7a2c791cfe7
checksum: 2a4416f57ce4b6efc516b690fcaf2d14c12cd27f3a9cdba30ffee043209eb45148747610ea6d0594acf8195b187f64f69276e0ba250902663e1a0491ab7f5bbc
languageName: node
linkType: hard

Expand Down Expand Up @@ -15359,7 +15359,7 @@ __metadata:
resolution: "universalprofile-test-dapp@workspace:."
dependencies:
"@depay/web3-mock": ^14.17.0
"@erc725/erc725.js": 0.24.0
"@erc725/erc725.js": 0.24.2
"@lukso/lsp-factory.js": ^3.3.1
"@lukso/lsp-smart-contracts": ^0.15.0
"@lukso/web3-onboard-config": 1.1.2
Expand Down

0 comments on commit a7f6c62

Please sign in to comment.