Skip to content

Commit

Permalink
Merge pull request #1161 from lukso-network/chore/key-manager-guides-…
Browse files Browse the repository at this point in the history
…polishing

Polish Key Manager guides
  • Loading branch information
CJ42 authored Oct 30, 2024
2 parents c6992c0 + 97eb0db commit 41294d8
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,25 +63,26 @@ async function getPermissionedAddresses() {
const controllerAddresses = await erc725.getData('AddressPermissions[]');

if (!controllerAddresses) {
console.error('No controllers listed under this Universal Profile ');
console.log('No controllers listed under this Universal Profile ');
} else {
console.log(controllerAddresses);
// {
// key: '0xdf30dba06db6a30e65354d9a64c609861f089545ca58c6b4dbe31a5f338cb0e3',
// name: 'AddressPermissions[]',
// value: [
// '0x5F606b5b237623463a90F63230F9b929321dbCBa',
// '0xa1061408e55c971fD129eF5561dFB953d598dAD7'
// ]
// }
}

console.log(controllerAddresses);
// {
// key: '0xdf30dba06db6a30e65354d9a64c609861f089545ca58c6b4dbe31a5f338cb0e3',
// name: 'AddressPermissions[]',
// value: [
// '0x5F606b5b237623463a90F63230F9b929321dbCBa',
// '0xa1061408e55c971fD129eF5561dFB953d598dAD7'
// ]
// }
}
```

<!-- TODO: double check this, it might be incorrect -->

<!-- :::tip
If you want to retrieve a controller address individually, you can use the [`AddressPermissions[index]`](/standards/access-control/lsp6-key-manager/#permissions) within the [`getData()`](../../../tools/libraries/erc725js/methods/#getdata) function of the contract or 🛠️[`erc725.js`](../../../tools/libraries/erc725js/getting-started.md) library.
If you want to retrieve the address of the controller stored at a specific index in the array, you can use the [`AddressPermissions[index]`](/standards/access-control/lsp6-key-manager/#permissions) data key as a parameter to the [`getData()`](../../../tools/libraries/erc725js/methods/#getdata) function of 🛠️[`erc725.js`](../../../tools/libraries/erc725js/getting-started.md) library.
::: -->

Expand Down Expand Up @@ -125,12 +126,12 @@ async function getPermissionedAddresses() {
for (let i = 0; i < controllerAddresses.value.length; i++) {
const address = controllerAddresses.value[i] as string;

const addressPermission = await erc725.getData({
const permissionsValue = await erc725.getData({
keyName: 'AddressPermissions:Permissions:<address>',
dynamicKeyParts: address,
});

console.log(addressPermission);
console.log(permissionsValue);
// {
// key: '0x4b80742de2bf82acb3630000a1061408e55c971fd129ef5561dfb953d598dad7',
// name: 'AddressPermissions:Permissions:a1061408e55c971fD129eF5561dFB953d598dAD7',
Expand Down Expand Up @@ -159,11 +160,11 @@ async function getPermissionedAddresses() {
// ...

// Decode the permission of each address
const decodedPermission = erc725.decodePermissions(addressPermission.value as string);
const decodedPermissions = erc725.decodePermissions(permissionsValue.value as string);

// Display the permission in a readable format
console.log(
`Decoded permission for ${address} = ` + JSON.stringify(decodedPermission, null, 2),
`Decoded permission for ${address} = ` + JSON.stringify(decodedPermissions, null, 2),
);
// Decoded permission for 0x5F606b5b237623463a90F63230F9b929321dbCBa = {
// "CHANGEOWNER": true,
Expand Down
72 changes: 50 additions & 22 deletions docs/learn/universal-profile/key-manager/grant-permissions.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ First initialize _erc725.js_ with the JSON schema of the LSP6 Key Manager. The s
import { ERC725 } from '@erc725/erc725.js';
import LSP6Schema from '@erc725/erc725.js/schemas/LSP6KeyManager.json';

// step 1 - initialize erc725.js with the ERC725Y permissions data keys from LSP6 Key Manager
// step 1 - initialize erc725.js with the schemas of the permissions data keys from LSP6 Key Manager
const erc725 = new ERC725(
LSP6Schema,
myUniversalProfileAddress,
Expand All @@ -95,16 +95,18 @@ Let's consider in our example that we want to grant the permission `SUPER_SETDAT
To do so, we will use the [`encodePermissions(..)`](../../../tools/libraries/erc725js/methods#encodepermissions) function, a convenience function from the _erc725.js_ library to encode permissions as their raw `bytes32` value. The function takes as an input will an object of all permissions that will be set.

```ts
// Create the permissions for our future controller
const beneficiaryPermissions = erc725.encodePermissions({
// Create the raw permissions value to allow an address
// to set any data keys (except LSP17 extensions and LSP1 Universal Receiver Delegates)
// on our Universal Profile
const permissionSetAnyDataKey = erc725.encodePermissions({
SUPER_SETDATA: true,
});
```

If you want to grant more than one permission, simply pass the other available permissions in the object. For instance, to also grant permission to transfer the LYX of the UP:

```ts
const beneficiaryPermissions = erc725.encodePermissions({
const multiplePermissions = erc725.encodePermissions({
SUPER_SETDATA: true,
TRANSFERVALUE: true,
});
Expand All @@ -118,27 +120,30 @@ As we learnt, permissions of controllers live inside the Universal Profile stora
| Add our `beneficiaryAddress`. | By adding the `beneficiaryAddress` inside the `AddressPermissions[]` Array, and increment the `AddressPermissions[]` array length (+1). |

```ts title="Encode the data key and values for the permissions"
const beneficiaryAddress = '0xcafecafecafecafecafecafecafecafecafecafe'; // address that we want to grant permission to
// address to give permissions to (can be an EOA or a smart contract)
const newControllerAddress = '0xcafecafecafecafecafecafecafecafecafecafe';

const addressPermissionsArray = await erc725.getData('AddressPermissions[]');
const currentControllerAddresses = addressPermissionsArray.value;
const currentControllerLength = currentControllerAddresses.length;
// Retrieve the list of addresses that have permissions on the Universal Profile (= controllers)
const addressPermissionsArrayValue = await erc725.getData(
'AddressPermissions[]',
);
const numberOfControllers = addressPermissionsArrayValue.value.length;

// Encode the key-value pairs of the controller permission
// Encode the set of key-value pairs to set a new controller with permissions on the Universal Profile
const permissionData = erc725.encodeData([
// the permission of the beneficiary address
// this sets the permission `SUPER_SETDATA` to the new controller address
{
keyName: 'AddressPermissions:Permissions:<address>',
dynamicKeyParts: beneficiaryAddress,
value: beneficiaryPermissions,
},
// Add this new address in the list of controllers.
// This is done Incremented list of permissioned controllers addresses
// The `AddressPermissions[]` array contains the list of permissioned addresses (= controllers)
// This adds the `newControllerAddress` in this list at the end (at the last index) and increment the array length.
{
keyName: 'AddressPermissions[]',
value: [myBeneficiaryAddress],
startingIndex: currentControllerLength,
totalArrayLength: currentControllerLength + 1,
value: [newControllerAddress],
startingIndex: numberOfControllers,
totalArrayLength: numberOfControllers + 1,
},
]);
```
Expand All @@ -160,13 +165,17 @@ The last and final step is to simply call the [`setDataBatch(...)`](../../../con

```ts
import { ether } from 'ethers';
import UniversalProfileArtifact from '@lukso/lsp-smart-contracts/artifacts/UniversalProfile.json';

// Connect the UP Browser Extension and retrieve our UP Address
const provider = new ethers.BrowserProvider(window.lukso);
const accounts = await provider.send('eth_requestAccounts', []);

// Create an instance of the UniversalProfile contract
const universalProfile = new ethers.Contract(accounts[0], UniversalProfile.abi);
const universalProfile = new ethers.Contract(
accounts[0],
UniversalProfileArtifact.abi,
);

// Send the transaction
await myUniversalProfile
Expand All @@ -180,14 +189,15 @@ await myUniversalProfile

```ts
import Web3 from 'web3';
import UniversalProfileArtifact from '@lukso/lsp-smart-contracts/artifacts/UniversalProfile.json';

// Connect the UP Browser Extension and retrieve our UP Address
const provider = new Web3(window.lukso);
const accounts = await provider.eth.requestAccounts();

// Create an instance of the UniversalProfile contract
const myUniversalProfile = new web3.eth.Contract(
UniversalProfile.abi,
UniversalProfileArtifact.abi,
accounts[0],
);

Expand All @@ -205,7 +215,7 @@ await myUniversalProfile.methods

## Testing the permissions

We can now check that the permissions have been correctly set by querying the `AddressPermissions:Permissions:<beneficiaryAddress>` data key on the Universal Profile.
We can now check that the permissions have been correctly set by querying the `AddressPermissions:Permissions:<address>` data key on the Universal Profile.

If everything went well, the code snippet below should return you an object with the permission `SETDATA` set to `true`.

Expand All @@ -214,9 +224,9 @@ If everything went well, the code snippet below should return you an object with
<TabItem value="ethers" label="ethers" attributes={{className: "tab_ethers"}}>

```ts
const result = await myUniversalProfile.methods.getData(data.keys[0]).call();
const result = await myUniversalProfile.getData(permissionData.keys[0]);
console.log(
`The beneficiary address ${beneficiaryAddress} has now the following permissions:`,
`The beneficiary address ${newControllerAddress} has now the following permissions:`,
ERC725.decodePermissions(result),
);
```
Expand All @@ -226,9 +236,27 @@ console.log(
<TabItem value="web3" label="web3" attributes={{className: "tab_web3"}}>

```ts
const result = await myUniversalProfile.getData(data.keys[0]);
const result = await myUniversalProfile.methods
.getData(permissionData.keys[0])
.call();
console.log(
`The beneficiary address ${newControllerAddress} has now the following permissions:`,
ERC725.decodePermissions(result),
);
```

</TabItem>

<TabItem value="erc725js" label="erc725js" attributes={{className: "tab_erc725"}}>

```ts
const result = await erc725.getData({
keyName: 'AddressPermissions:Permissions:<address>',
dynamicKeyParts: newControllerAddress,
});

console.log(
`The beneficiary address ${beneficiaryAddress} has now the following permissions:`,
`The beneficiary address ${newControllerAddress} has now the following permissions:`,
ERC725.decodePermissions(result),
);
```
Expand Down

0 comments on commit 41294d8

Please sign in to comment.