Skip to main content

Grant Vault Permissions

Disclaimer

This guide might contain outdated information and will be updated soon.

As mentioned in the first Vault guide, the Vault can be used to restrict different addresses (protocols, other devices, etc..) to execute and set data on it instead of doing it directly on the Universal Profile.

This way, when granting a third party permissions to execute through your profile, this third party will only be able to interact with the Vault, and all the other assets will be safe.

Guide - Restrict addresses to an LSP9Vault

Granting Permission to 3rd Parties​

note

Make sure not to grant the 3rd party address the SUPER Permissions. Otherwise, the AllowedCalls restriction will not work.

Check the guide of granting permissions to 3rd Parties, and make sure to grant the 3rd party address the CALL Permission.

Use AllowedCalls permission for the 3rd Parties​

In this guide, after granting the 3rd party the permission CALL, we will need to allow the address of the 3rd party to interact with the Vault address. We will be using the AllowedCalls permission from the Key Manager.

Setup​

Make sure you have the following dependencies installed before beginning this tutorial.

Install the dependencies
npm install web3 @lukso/lsp-smart-contracts @erc725/erc725.js

Step 1 - Imports, Constants & EOA​

For this guide we will firstly need and import the ABIs for the Universal Profile & Key Manager contracts. Also we will import the ERC725YDataKeys to retrieve the data key for AllowedCalls permission.
As constants we will need to store the addresses for the Universal Profile, Vault & the restricted third party.
Finally, we will need a private key with the proper permissions, in our case ADDCONTROLLER permission.

Imports, Constants & EOA initialization
import UniversalProfile from '@lukso/lsp-smart-contracts/artifacts/UniversalProfile.json';
import { ERC725YDataKeys } from '@lukso/lsp-smart-contracts/constants.js';
import { encodeKey } from '@erc725/erc725.js/build/main/src/lib/utils.js';
import Web3 from 'web3';

// constants
const web3 = new Web3('https://rpc.testnet.lukso.network');
const universalProfileAddress = '0x..'; // address of the UP
const vaultAddress = '0x..'; // address of the Vault
const thirdPartyAddress = '0x..'; // address of the third party you want to restrict

// setup your EOA
const privateKey = '0x...';
const myEOA = web3.eth.accounts.wallet.add(privateKey);

Step 2 - Create UP contract instance​

At this point we will create instance for the Universal Profile contract.

Universal Profile contract instance
// create an instance of the UP
const universalProfile = new web3.eth.Contract(
UniversalProfile.abi,
universalProfileAddress,
);

Step 3 - Generate the data key-value pair for AllowedCalls​

Now we need to generate a data key & a data value for the Allowed Calls that we want for the Third Party address. After we do that, we will update the Allowed Calls data key with the encoded Allowed Calls

Data key & value for updating the Allowed Calls of a Controller address
const allowedCallsDataKey = // constructing the data key of allowed addresses
ERC725YDataKeys.LSP6['AddressPermissions:AllowedCalls'] +
thirdPartyAddress.substring(2); // of the 3rd party

const allowedCallsSchema = {
name: 'AddressPermissions:AllowedCalls:<address>',
key: '0x4b80742de2bf393a64c70000<address>',
keyType: 'MappingWithGrouping',
valueType: '(bytes4,address,bytes4)[CompactBytesArray]',
valueContent: '(Bytes4,Address,Bytes4)',
};

const allowedCallsDataValue = encodeKey(allowedCallsSchema, [
'0xffffffff',
vaultAddress,
'0xffffffff',
]);

Step 4 - Update the Universal profile data​

Finally we will send a transaction that will update the Universal Profile AllowedCalls data key with the newly generated AllowedCalls.

Set the data key on the Universal Profile
// Set the AllowedCalls data key on the Universal Profile
await universalProfile.methods.setData(
allowedCallsDataKey,
allowedCallsDataValue,
).send({
from: myEOA.address,
gasLimit: 600_000,
});

Final code​

Setting Allowed Addresses for the 3rd party address
import UniversalProfile from '@lukso/lsp-smart-contracts/artifacts/UniversalProfile.json';
import { ERC725YDataKeys } from '@lukso/lsp-smart-contracts/constants.js';
import { encodeKey } from '@erc725/erc725.js/build/main/src/lib/utils.js';
import Web3 from 'web3';

// constants
const web3 = new Web3('https://rpc.testnet.lukso.network');
const universalProfileAddress = '0x..'; // address of the UP
const vaultAddress = '0x..'; // address of the Vault
const thirdPartyAddress = '0x..'; // address of the third party you want to restrict

// setup your EOA
const privateKey = '0x...';
const myEOA = web3.eth.accounts.wallet.add(privateKey);

// create an instance of the UP
const universalProfile = new web3.eth.Contract(
UniversalProfile.abi,
universalProfileAddress,
);

const allowedCallsDataKey = // constructing the data key of allowed addresses
ERC725YDataKeys.LSP6['AddressPermissions:AllowedCalls'] +
thirdPartyAddress.substring(2); // of the 3rd party

const allowedCallsSchema = {
name: 'AddressPermissions:AllowedCalls:<address>',
key: '0x4b80742de2bf393a64c70000<address>',
keyType: 'MappingWithGrouping',
valueType: '(bytes4,address,bytes4)[CompactBytesArray]',
valueContent: '(Bytes4,Address,Bytes4)',
};

const allowedCallsDataValue = encodeKey(allowedCallsSchema, [
'0xffffffff',
vaultAddress,
'0xffffffff',
]);

// Set the AllowedCalls data key on the Universal Profile
await universalProfile.methods.setData(
allowedCallsDataKey,
allowedCallsDataValue,
).send({
from: myEOA.address,
gasLimit: 600_000,
});