Skip to main content

Edit Vault Data

Disclaimer

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

This guide will teach you how to set data to an LSP9Vault contract through a UniversalProfile owned by an LSP6KeyManager. Any data can be attached to the vault, and since it supports the LSP1-UniversalReceiver standard, we will set the Universal Receiver Delegate address inside the storage.

Setting Data (Universal Receiver Delegate)​

The default implementation of the Universal Receiver Delegate of the Vault that we will deploy will register the assets received to the storage and and will remove them when their balance equals 0.

Setup​

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

npm install web3 @lukso/lsp-smart-contracts

Step 1 - Imports, constants and EOA​

For starters we need to get the ABIs for the contracts that we will use and the bytecode for the LSP1UniversalReceiverDelegateVault.
After that we need to store the address of our LSP9 Vault and our Universal Profile.
Then we will initialize the EOA that we will further use.

import LSP1UniversalReceiverDelegateVault from '@lukso/lsp-smart-contracts/artifacts/LSP1UniversalReceiverDelegateVault.json';
import UniversalProfile from '@lukso/lsp-smart-contracts/artifacts/UniversalProfile.json';
import LSP9Vault from '@lukso/lsp-smart-contracts/artifacts/LSP9Vault.json';
import { ERC725YDataKeys } from '@lukso/lsp-smart-contracts';
import Web3 from 'web3';

// constants
const web3 = new Web3('https://rpc.testnet.lukso.network');
const vaultAddress = '0x...';
const universalProfileAddress = '0x...';

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

Step 2 - Deploying Universal Receiver Delegate (URD)​

info

The Universal Profile and the Vault don't use the same implementation of the Universal Receiver Delegate.

Create a contract instance​

At this step we will create an instance of the Vault URD that we will further be used to deploy one.

// create an instance of the LSP1UniversalReceiverDelegateVault
const vaultURD = new web3.eth.Contract(LSP1UniversalReceiverDelegateVault.abi);

Send the contract deployment transaction​

Send the deployment transaction and in a few seconds you will get a new deployed Vault URD.

// deploy the Universal Receiver Delegate Vault contract
await vaultURD
.deploy({
data: LSP1UniversalReceiverDelegateVault.bytecode,
})
.send({
from: myEOA.address,
gas: '5000000',
gasPrice: '1000000000',
});

Final code​

const deployVaultURD = async () => {
// create an instance of the LSP1UniversalReceiverDelegateVault
const vaultURD = new web3.eth.Contract(
LSP1UniversalReceiverDelegateVault.abi,
);
let vaultURDAddress;

// deploy the Universal Receiver Delegate Vault contract
await vaultURD
.deploy({
data: LSP1UniversalReceiverDelegateVault.bytecode,
})
.send({
from: myEOA.address,
gas: '5000000',
gasPrice: '1000000000',
})
.on('receipt', (receipt) => (vaultURDAddress = receipt.contractAddress));

return vaultURDAddress;
};

// deploy a new Vault URD and retrieve its address
const vaultURDAddress = await deployVaultURD();

Step 3 - Setting the URD address in the storage​

The Vault's owner could be an EOA, or any other smart contract. In our case, we will suppose that the Vault's owner is a Universal Profile that is controlled by a Key Manager.

Create the contract instances​

Firstly we need to create instances for the following contracts:

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

Encode setData(..) calldata​

Secondly, we need to encode a calldata that will update the address of the Vault URD.

// encode setData Calldata on the Vault
const setDataCalldata = await vault.methods
.setData(ERC725YDataKeys.LSP1.LSP1UniversalReceiverDelegate, vaultURDAddress)
.encodeABI(); // Any other information can be stored here

Update the Vault data​

Lastly, we need to send the transaction that will update the Vault data through the Universal Profile's execute(..).

// execute the `setData(bytes32,bytes)` calldata that updates the Vault data
await universalProfile.methods
.execute(
0, // OPERATION CALL
vaultAddress,
0, // value to transfer
setDataCalldata,
)
.send({
from: myEOA.address,
gasLimit: 600_000,
});

Final code​

const updateVaultURD = async (vaultURDAddress) => {
// create an instance of the LSP9Vault
const vault = new web3.eth.Contract(LSP9Vault.abi, vaultAddress);
// create an instance of the Universal Profile
const universalProfile = new web3.eth.Contract(
UniversalProfile.abi,
universalProfileAddress,
);

// encode setData Calldata on the Vault
const setDataCalldata = await vault.methods
.setData(
ERC725YDataKeys.LSP1.LSP1UniversalReceiverDelegate,
vaultURDAddress,
)
.encodeABI(); // Any other information can be stored here

// execute the `setDataCalldata` that updates the Vault data
await universalProfile.methods
.execute(
0, // OPERATION CALL
vaultAddress,
0, // value to transfer
setDataCalldata,
)
.send({
from: myEOA.address,
gasLimit: 600_000,
});
};

// update the curent Vault's URD
await updateVaultURD(vaultURDAddress);

Final code - Deploy & Update​

Deploy new Vault URD and update Vault's URD
import LSP1UniversalReceiverDelegateVault from '@lukso/lsp-smart-contracts/artifacts/LSP1UniversalReceiverDelegateVault.json';
import UniversalProfile from '@lukso/lsp-smart-contracts/artifacts/UniversalProfile.json';
import LSP9Vault from '@lukso/lsp-smart-contracts/artifacts/LSP9Vault.json';
import { ERC725YDataKeys } from '@lukso/lsp-smart-contracts';
import Web3 from 'web3';

const web3 = new Web3('https://rpc.testnet.lukso.network');
const vaultAddress = '0x...';
const universalProfileAddress = '0x...';

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

const deployVaultURD = async () => {
// create an instance of the LSP1UniversalReceiverDelegateVault
const vaultURD = new web3.eth.Contract(
LSP1UniversalReceiverDelegateVault.abi,
);
let vaultURDAddress;

// deploy the Universal Receiver Delegate Vault contract
await vaultURD
.deploy({
data: LSP1UniversalReceiverDelegateVault.bytecode,
})
.send({
from: myEOA.address,
gas: '5000000',
gasPrice: '1000000000',
})
.on('receipt', (receipt) => (vaultURDAddress = receipt.contractAddress));

return vaultURDAddress;
};

const updateVaultURD = async (vaultURDAddress) => {
// create an instance of the LSP9Vault
const vault = new web3.eth.Contract(LSP9Vault.abi, vaultAddress);
// create an instance of the Universal Profile
const universalProfile = new web3.eth.Contract(
UniversalProfile.abi,
universalProfileAddress,
);

// encode setData Calldata on the Vault
const setDataCalldata = await vault.methods
.setData(
ERC725YDataKeys.LSP1.LSP1UniversalReceiverDelegate,
vaultURDAddress,
)
.encodeABI(); // Any other information can be stored here

// execute the `setDataCalldata` that updates the Vault data
await universalProfile.methods
.execute(
0, // OPERATION CALL
vaultAddress,
0, // value to transfer
setDataCalldata,
)
.send({
from: myEOA.address,
gasLimit: 600_000,
});
};

// deploy a new Vault URD and retrieve its address
const vaultURDAddress = await deployVaultURD();
// update the curent Vault's URD
await updateVaultURD(vaultURDAddress);

Reading Data​

The LSP9Vault contract is an ERC725 contract, so it shares the same way to read data as Universal Profiles and other ERC725 contracts by using erc725.js.

You can refer to the Read Profile Data Guide to learn how to fetch data like received or issued assets from ERC725Y Storage. However, please note that the Universal Profile address has to be exchanged with the Vault's address.