Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add new controller in list when setting permissions for new address #151

Merged
merged 17 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading