How to check if an address is a Universal Profile?
You may want to read the Standard Detection page first.
To check if an address is a Universal Profile we need to perform 3 checks:
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 - Check address format
This first basic test can be performed via regular expression or 3rd party library function. For example this is how we can achieve this using Web3.js isAddress
:
- web3.js
- ethers.js
import { isAddress } from 'web3-utils';
if (!isAddress(address)) {
throw new Error('Invalid address');
}
import { isAddress } from 'ethers';
if (!isAddress(address)) {
throw new Error('Invalid address');
}
Step 2 - Check if the contract supports the LSP0ERC725Account
interface using ERC165
This is next check that makes sure we deal with a smart contract that supports the LSP0ERC725Account
interface (EIP-165). For this we need to create an universalProfile
contract instance and call supportsInterface(...)
method.
Universal Profiles inherit ERC165, therefore by creating an instance of the Universal Profile contract you have access to the supportsInterface(...)
method.
- web3.js
- ethers.js
import UniversalProfile from '@lukso/lsp-smart-contracts/artifacts/UniversalProfile.json';
import { INTERFACE_IDS } from '@lukso/lsp-smart-contracts/constants';
import Web3 from 'web3';
const web3 = new Web3('https://rpc.testnet.lukso.network');
const universalProfileAddress = '0x...'; // The address of the contract that you are verifying
const universalProfile = new web3.eth.Contract(UniversalProfile.abi, universalProfileAddress);
const supportsLSP0Interface = await universalProfile.methods.supportsInterface(INTERFACE_IDS.LSP0ERC725Account).call();
// true or false -> if false, this address is not a Universal Profile.
if (!supportsLSP0Interface) {
throw new Error('Contract does not support LSP0ERC725Account interface');
}
import UniversalProfile from '@lukso/lsp-smart-contracts/artifacts/UniversalProfile.json';
import { INTERFACE_IDS } from '@lukso/lsp-smart-contracts/constants';
import { ethers } from 'ethers';
const provider = new ethers.JsonRpcProvider('https://rpc.testnet.lukso.network');
const universalProfileAddress = '0x...'; // The address of the contract that you are verifying
const universalProfile = new ethers.Contract(universalProfileAddress, UniversalProfile.abi, provider);
const supportsLSP0Interface = await universalProfile.supportsInterface(INTERFACE_IDS.LSP0ERC725Account);
// true or false -> if false, this address is not a Universal Profile.
if (!supportsLSP0Interface) {
throw new Error('Contract does not support LSP0ERC725Account interface');
}
Step 3 - Check supported standard
Last but not least we should perform a check over LSP3UniversalProfile
standard. For this we need to call getData
with the SupportedStandards:LSP3UniversalProfile
key.
Universal Profiles inherit ERC725Y, therefore by creating an instance of the Universal Profile contract you have access to the getData(..)
method.
- web3.js
- ethers.js
import UniversalProfile from '@lukso/lsp-smart-contracts/artifacts/UniversalProfile.json';
import { SupportedStandards } from '@lukso/lsp-smart-contracts/constants';
import Web3 from 'web3';
const web3 = new Web3('https://rpc.testnet.lukso.network');
const universalProfileAddress = "0x..."; // The address of the contract that you are verifying
const universalProfile = new web3.eth.Contract(UniversalProfile.abi, universalProfileAddress);
const supportedStandard = await universalProfile.methods['getData(bytes32)'](SupportedStandards.LSP3UniversalProfile.key).call();
if (supportedStandard !== SupportedStandards.LSP3UniversalProfile.value) {
throw new Error('Address does not support LSP3UniversalProfile standard');
}
import UniversalProfile from '@lukso/lsp-smart-contracts/artifacts/UniversalProfile.json';
import { SupportedStandards } from '@lukso/lsp-smart-contracts/constants';
import { ethers } from 'ethers';
const provider = new ethers.JsonRpcProvider('https://rpc.testnet.lukso.network');
const universalProfileAddress = '0x...'; // The address of the contract that you are verifying
const universalProfile = new ethers.Contract(universalProfileAddress, UniversalProfile.abi, provider);
const supportedStandard = await universalProfile['getData(bytes32)'](SupportedStandards.LSP3UniversalProfile.key);
if (supportedStandard !== SupportedStandards.LSP3UniversalProfile.value) {
throw new Error('Address does not support LSP3UniversalProfile standard');
}
Final Code
- web3.js
- ethers.js
import UniversalProfile from '@lukso/lsp-smart-contracts/artifacts/UniversalProfile.json';
import { INTERFACE_IDS, SupportedStandards } from '@lukso/lsp-smart-contracts/constants';
import Web3 from 'web3';
const web3 = new Web3('https://rpc.testnet.lukso.network');
if (!web3.utils.isAddress(address)) {
throw new Error('Invalid address');
}
// We assume that the contract is a Universal Profile
const universalProfileAddress = '0x...'; // The address of the contract that you are verifying
const universalProfile = new web3.eth.Contract(UniversalProfile.abi, universalProfileAddress);
const supportsLSP0Interface = await universalProfile.methods.supportsInterface(INTERFACE_IDS.LSP0ERC725Account).call();
// true or false -> if false, this address is not a Universal Profile.
if (!supportsLSP0Interface) {
throw new Error('Contract does not support LSP0ERC725Account interface');
}
const supportedStandard = await universalProfile.methods['getData(bytes32)'](SupportedStandards.LSP3UniversalProfile.key).call();
if (supportedStandard !== SupportedStandards.LSP3UniversalProfile.value) {
throw new Error('Address does not support LSP3UniversalProfile standard');
}
import UniversalProfile from '@lukso/lsp-smart-contracts/artifacts/UniversalProfile.json';
import { INTERFACE_IDS, SupportedStandards } from '@lukso/lsp-smart-contracts/constants';
import { ethers } from 'ethers';
const provider = new ethers.providers.JsonRpcProvider('https://rpc.testnet.lukso.network');
if (!ethers.utils.isAddress(address)) {
throw new Error('Invalid address');
}
// We assume that the contract is a Universal Profile
const universalProfileAddress = '0x...'; // The address of the contract that you are verifying
const universalProfile = new ethers.Contract(universalProfileAddress, UniversalProfile.abi, provider);
const supportsLSP0Interface = await universalProfile.supportsInterface(INTERFACE_IDS.LSP0ERC725Account);
// true or false -> if false, this address is not a Universal Profile.
if (!supportsLSP0Interface) {
throw new Error('Contract does not support LSP0ERC725Account interface');
}
const supportedStandard = await universalProfile['getData(bytes32)'](SupportedStandards.LSP3UniversalProfile.key);
if (supportedStandard !== SupportedStandards.LSP3UniversalProfile.value) {
throw new Error('Address does not support LSP3UniversalProfile standard');
}