Skip to main content

Upgrade the LSP6 Key Manager

caution

This article is a WIP

Requirements

You will need a Universal Profile that you can control via its KeyManager to follow this guide. If you don't have a Universal Profile yet, follow our previous guide Create a Universal Profile or look at the lsp-factory.js docs.

In this guide, we will learn how to upgrade the LSP6 Key Manager of your Universal Profile to the latest version available.

By the end of this guide, you will know how to:

  • Deploy a new LSP6 Key Manager with the last updates.
  • Upgrade your Key Manager by changing the owner of your UP from your old to your new 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

Step 1 - Set up the constants and imports​

Create a JavaScript file and add the following imports on the top of the file:

  • privateKey: private key of a controller address, MUST have CHANGEOWNER permission.
  • universalProfileAddress: address of your Universal Profile.
Imports & Constants
import UniversalProfile from '@lukso/lsp-smart-contracts/artifacts/UniversalProfile.json';
import LSP6KeyManager from '@lukso/lsp-smart-contracts/artifacts/LSP6KeyManager.json';
import Web3 from 'web3';

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

const privateKey = '0x...';
const universalProfileAddress = '0x...';

Step 2 - Initialize the controller account​

In order to send any transaction on the blockchain you need an EOA. In our case that account MUST have CHANGEOWNER permission on the Universal Profile that will have its LSP6 Key Manager upgraded.

Initialise EOA
const account = web3.eth.accounts.wallet.add(privateKey);

Step 3 - Initialize UP contract​

In order to transfer ownership of your Universal Profile, you need to initialize the UP's contract.

Create an instance of the old Key Manager
const universalProfile = new web3.eth.Contract(UniversalProfile.abi, universalProfileAddress);

Step 4 - Deploy the new LSP6 Key Manager​

Deploy a new LSP6 Key Manager with the latest updates.

Deploy a new Key Manager
const newKeyManager = new web3.eth.Contract(LSP6KeyManager.abi);
await newKeyManager
.deploy({
data: LSP6KeyManager.bytecode,
arguments: [universalProfileAddress],
})
.send({
from: account.address,
gas: 3_000_000,
gasPrice: '1000000000',
});

Step 5 - Upgrade your Key Manager​

Step 5.1 - Transfer Ownership to your new Key Manager​

Create a calldata for the transferOwnership(address) function and shift the ownership of your Universal Profile from your current LSP6 Key Manager.

Transfer ownership of the Universal Profile from the old Key Manager to the new one
await universalProfile.methods.transferOwnership(newKeyManager.address).send({
from: account.address,
gas: 1_000_000,
gasPrice: '1000000000',
});

Step 5.2 - Accept Ownership from your new Key Manager​

Create a calldata for the acceptOwnership() function and take the ownership of your Universal Profile from your new LSP6 Key Manager.

Accept ownership of the Universal Profile via the new Key Manager
const acceptOwnershipCalldata = new web3.eth.Contract(UniversalProfile.abi).methods.acceptOwnership().encodeABI();

await newKeyManager.methods.execute(acceptOwnershipCalldata).send({
from: account.address,
gas: 1_000_000,
gasPrice: '1000000000',
});
ðŸĨģ

The upgrade has been completed successfully.

Final code​

upgrade-lsp6.js
import UniversalProfile from '@lukso/lsp-smart-contracts/artifacts/UniversalProfile.json';
import LSP6KeyManager from '@lukso/lsp-smart-contracts/artifacts/LSP6KeyManager.json';
import Web3 from 'web3';
const web3 = new Web3('https://rpc.testnet.lukso.network');

const privateKey = '0x...';
const universalProfileAddress = '0x...';

const upgradeLSP6 = async () => {
// Initialize the controller account
const account = web3.eth.accounts.wallet.add(privateKey);

// Initialize your current UP
const universalProfile = new web3.eth.Contract(UniversalProfile.abi, universalProfileAddress);

// Deploy a new LSP6 Key Manager
const newKeyManager = new web3.eth.Contract(LSP6KeyManager.abi);
await newKeyManager.deploy({
data: LSP6KeyManager.bytecode,
arguments: [universalProfileAddress],
}).send({
from: account.address,
gas: 3_000_000,
gasPrice: '1000000000',
});

// Transfer the ownership of your Universal Profile from the current LSP6 Key Manager to a new LSP6 Key Manager
await universalProfile.methods.transferOwnership(newKeyManager.address).send({
from: account.address,
gas: 1_000_000,
gasPrice: '1000000000',
});

// Accept the ownership of your Universal Profile from the new LSP6 Key Manager
const acceptOwnershipCalldata = new web3.eth.Contract(UniversalProfile.abi).methods.acceptOwnership().encodeABI();

await newKeyManager.methods.execute(acceptOwnershipCalldata).send({
from: account.address,
gas: 1_000_000,
gasPrice: '1000000000',
});
};

await upgradeLSP6();

Test the new LSP6 Key Manager​

We can now check the owner of the Universal Profile. If everything went through, the owner should be the address of the new LSP6 Key Manager. Create the following file with the name test-new-lsp6.js and run:

node test-new-lsp6.js
test-new-lsp6.js
import LSP0ERC725YAccount from '@lukso/lsp-smart-contracts/artifacts/LSP0ERC725YAccount.json';
import LSP6KeyManager from '@lukso/lsp-smart-contracts/artifacts/LSP6KeyManager.json';
import Web3 from 'web3';

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

const universalProfileAddress = '0x...';

const testLSP6 = async () => {
const universalProfile = new web3.eth.Contract(LSP0ERC725YAccount.abi, universalProfileAddress);

const universalProfileOwner = await universalProfile.methods.owner().call();

console.log(`The new owner of the Universal Profile is: ${universalProfileOwner}`);
console.log(`The old LSP6 Key Manager is at address: ${keyManagerAdderss}`);

const keyManager = new web3.eth.Contract(LSP6KeyManager.abi, universalProfileOwner);

const keyManagerTarget = await keyManager.methods.target().call();

console.log(`The address of the Universal Profile is: ${universalProfile._address}`);
console.log(`The target of the new LSP6 Key Manager: ${keyManagerTarget}`);
};

await testLSP6();