Edit Vault Data
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:
- Either
web3.js
orethers.js
@lukso/lsp-smart-contracts
- web3.js
- ethers.js
npm install web3 @lukso/lsp-smart-contracts
npm install ethers @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.
- web3.js
- ethers.js
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);
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 { ethers } from 'ethers';
// constants
const provider = new ethers.providers.JsonRpcProvider(
'https://rpc.testnet.lukso.network',
);
const vaultAddress = '0x...';
const universalProfileAddress = '0x...';
// setup your EOA
const privateKey = '0x...'; // your EOA private key (controller address)
const myEOA = new ethers.Wallet(privateKey).connect(provider);
Step 2 - Deploying Universal Receiver Delegate (URD)â
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.
- web3.js
- ethers.js
// create an instance of the LSP1UniversalReceiverDelegateVault
const vaultURD = new web3.eth.Contract(LSP1UniversalReceiverDelegateVault.abi);
// create a LSP1UniversalReceiverDelegateVault Contract Factory
const vaultURDFactory = new ethers.ContractFactory(
LSP1UniversalReceiverDelegateVault.abi,
LSP1UniversalReceiverDelegateVault.bytecode,
);
Send the contract deployment transactionâ
Send the deployment transaction and in a few seconds you will get a new deployed Vault URD.
- web3.js
- ethers.js
// deploy the Universal Receiver Delegate Vault contract
await vaultURD
.deploy({
data: LSP1UniversalReceiverDelegateVault.bytecode,
})
.send({
from: myEOA.address,
gas: '5000000',
gasPrice: '1000000000',
});
// deploy the Universal Receiver Delegate Vault contract
const vaultURD = await vaultURDFactory.connect(myEOA).deploy();
Final codeâ
- web3.js
- ethers.js
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();
const deployVaultURD = async () => {
// create a LSP1UniversalReceiverDelegateVault Contract Factory
const vaultURDFactory = new ethers.ContractFactory(
LSP1UniversalReceiverDelegateVault.abi,
LSP1UniversalReceiverDelegateVault.bytecode,
);
// deploy the Universal Receiver Delegate Vault contract
const vaultURD = await vaultURDFactory.connect(myEOA).deploy();
// get back the transaction data when deployed
const transactionReceipt = await vaultURD.deployTransaction.wait();
// return the address of the Vault URD
return transactionReceipt.contractAddress;
};
// 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:
- web3.js
- ethers.js
// 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,
);
// create an instance of the LSP9Vault
const vault = new ethers.Contract(vaultAddress, LSP9Vault.abi);
// create an instance of the Universal Profile
const universalProfile = new ethers.Contract(
universalProfileAddress,
UniversalProfile.abi,
);
Encode setData(..)
calldataâ
Secondly, we need to encode a calldata that will update the address of the Vault URD.
- web3.js
- ethers.js
// encode setData Calldata on the Vault
const setDataCalldata = await vault.methods
.setData(ERC725YDataKeys.LSP1.LSP1UniversalReceiverDelegate, vaultURDAddress)
.encodeABI(); // Any other information can be stored here
// encode setData Calldata on the Vault
const setDataCalldata = vault.interface.encodeFunctionData('setData', [
ERC725YDataKeys.LSP1.LSP1UniversalReceiverDelegate,
vaultURDAddress,
]); // 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(..)
.
- web3.js
- ethers.js
// 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,
});
// execute the `setData(bytes32,bytes)` calldata that updates the Vault data
await universalProfile.connect(myEOA).execute(
0, // OPERATION CALL
vaultAddress,
0, // value to transfer
setDataCalldata,
);
Final codeâ
- web3.js
- ethers.js
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);
const updateVaultURD = async (vaultURDAddress) => {
// create an instance of the LSP9Vault
const vault = new ethers.Contract(vaultAddress, LSP9Vault.abi);
// create an instance of the Universal Profile
const universalProfile = new ethers.Contract(
universalProfileAddress,
UniversalProfile.abi,
);
// encode setData Calldata on the Vault
const setDataCalldata = vault.interface.encodeFunctionData('setData', [
ERC725YDataKeys.LSP1.LSP1UniversalReceiverDelegate,
vaultURDAddress,
]); // Any other information can be stored here
// execute the `setDataCalldata` that updates the Vault data
await universalProfile.connect(myEOA).execute(
0, // OPERATION CALL
vaultAddress,
0, // value to transfer
setDataCalldata,
);
};
// update the curent Vault's URD
await updateVaultURD(vaultURDAddress);
Final code - Deploy & Updateâ
- web3.js
- ethers.js
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);
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 { ethers } from 'ethers';
const provider = new ethers.providers.JsonRpcProvider(
'https://rpc.testnet.lukso.network',
);
const vaultAddress = '0x...';
const universalProfileAddress = '0x...';
// setup your EOA
const privateKey = '0x...'; // your EOA private key (controller address)
const myEOA = new ethers.Wallet(privateKey).connect(provider);
const deployVaultURD = async () => {
// create a LSP1UniversalReceiverDelegateVault Contract Factory
const vaultURDFactory = new ethers.ContractFactory(
LSP1UniversalReceiverDelegateVault.abi,
LSP1UniversalReceiverDelegateVault.bytecode,
);
// deploy the Universal Receiver Delegate Vault contract
const vaultURD = await vaultURDFactory.connect(myEOA).deploy();
return vaultURD.address;
};
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.connect(myEOA).execute(
0, // OPERATION CALL
vaultAddress,
0, // value to transfer
setDataCalldata,
);
};
// 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.