Grant Vault Permissions
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.
Granting Permission to 3rd Partiesâ
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.
- You can use either
web3.js
orethers.js
- You MUST install
@lukso/lsp-smart-contracts
- You SHOULD install
@erc725/erc725.js
- web3.js
- ethers.js
npm install web3 @lukso/lsp-smart-contracts @erc725/erc725.js
npm install ethers @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.
- web3.js
- ethers.js
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);
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 { ethers } from 'ethers';
// constants
const provider = new ethers.JsonRpcProvider(
'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...'; // your EOA private key (controller address)
const myEOA = new ethers.Wallet(privateKey).connect(provider);
Step 2 - Create UP contract instanceâ
At this point we will create instance for the Universal Profile contract.
- web3.js
- ethers.js
// create an instance of the UP
const universalProfile = new web3.eth.Contract(
UniversalProfile.abi,
universalProfileAddress,
);
// create an instance of the UP
const universalProfile = new ethers.Contract(
universalProfileAddress,
UniversalProfile.abi,
);
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
- web3.js
- ethers.js
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',
]);
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.
- web3.js
- ethers.js
// Set the AllowedCalls data key on the Universal Profile
await universalProfile.methods.setData(
allowedCallsDataKey,
allowedCallsDataValue,
).send({
from: myEOA.address,
gasLimit: 600_000,
});
// Set the AllowedCalls data key on the Universal Profile
await universalProfile
.connect(myEOA)
.setData(allowedCallsDataKey, allowedCallsDataValue);
Final codeâ
- web3.js
- ethers.js
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,
});
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 { ethers } from 'ethers';
// constants
const provider = new ethers.JsonRpcProvider(
'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...'; // your EOA private key (controller address)
const myEOA = new ethers.Wallet(privateKey).connect(provider);
// create an instance of the UP
const universalProfile = new ethers.Contract(
universalProfileAddress,
UniversalProfile.abi,
);
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
.connect(myEOA)
.setData(allowedCallsDataKey, allowedCallsDataValue);