Skip to main content

Register Issued Assets

Asset Authenticity

Within the LSP4 Metadata, Universal Profiles can be referenced asย creators. To authenticate the creators of an asset, their Universal Profiles must list the asset's address under the LSP12 Issued Assets. Services can then validate the on-chain cross-link to prove authenticity.

In this guide you will learn how to set or update digital assets (either LSP7 Digital Asset or LSP8 Identifiable Digital Asset) within the list of LSP12 Issued Assets of a Universal Profile.

Code Examples

The full code of this example can be found in the ๐Ÿ‘พ lukso-playground repository.

Setupโ€‹

You will need the address of an existing LSP7 or LSP8 Digital Asset in order to follow this tutorial. E.g:

The following code snippets require the installation of the following libraries:

npm install ethers @lukso/lsp-smart-contracts @erc725/erc725.js

Imports and constantsโ€‹

Import web3.js/ethers, the UniversalProfile ABI from @lukso/lsp-smart-contracts and create an instance of this contract with the UNIVERSAL_PROFILE_ADDRESS.

import { ethers } from 'ethers';

import { ERC725 } from '@erc725/erc725.js';
import LSP12Schema from '@erc725/erc725.js/schemas/LSP12IssuedAssets.json';

import UniversalProfileArtifact from '@lukso/lsp-smart-contracts/artifacts/UniversalProfile.json';
import { INTERFACE_IDS } from '@lukso/lsp-smart-contracts';

// We will register the issued assets by setting the following LSP12 data keys
// - LSP12IssuedAssets[]
// - LSP12IssuedAssetsMap:<asset-address>

// add the type of asset (LSP7 or LSP8) and their address in the object list below
const issuedAssets = [
{
interfaceId: INTERFACE_IDS.LSP7DigitalAsset,
address: '0xf7056bdE90f494F55967858F1e9E4AFB1026C5C8',
},
{
interfaceId: INTERFACE_IDS.LSP8IdentifiableDigitalAsset,
address: '0xf651b88925C0B6C81Ad6f658a2F104226d837F60',
},
// {
// interfaceId: LSP7 or LSP8 interface ID (or other),
// address: '0xasset-address',
// },
];

const provider = new ethers.BrowserProvider(window.lukso);
await provider.send('eth_requestAccounts', []);
const myWallet = await provider.getSigner();

Encode the data keysโ€‹

After setting up the array of assets, you can use the erc725.js library to encode the LSP12IssuedAssets[] data keys. There are two ways to encode data:

  • Set the full issued assets list: If you want to initially set issued assets on a Universal Profile or re-set all elements, you can encode the data without defining optional length or index parameters. Therefore, the issued assets will only consist of the asset addresses you provide in your array of assets.
  • add, update, or remove existing issued assets: If the Universal Profile already has issued assets, and you want to add, update, or remove certain assets, you can provide the startingIndex and totalArrayLength parameters. Therefore, your prepared array only represents a subset of all the issued assets listed in your Universal Profile.
Setting contract data

Please be careful when updating existing issued assets. Incorrect usage of startingIndex and totalArrayLength can lead to improperly encoded data that changes the intended structure of the data field.

info

You can read more about the encodeData function of erc725.js within the related ERC725 Documentation.

const erc725 = new ERC725(
LSP12Schema,
UNIVERSAL_PROFILE_ADDRESS,
RPC_ENDPOINT,
{
ipfsGateway: 'https://api.universalprofile.cloud/ipfs',
},
);

const allAssetAddresses = myIssuedAssets.map((asset) => asset.address);

const allIssuedAssetsMap = myIssuedAssets.map((asset, index) => {
return {
keyName: 'LSP12IssuedAssetsMap:<address>',
dynamicKeyParts: asset.address,
value: [
asset.interfaceId,
// index of the issued asset as uint128
// 1 => 0x00000000000000000000000000000001
ERC725.encodeValueType('uint128', index),
],
};
});

const { keys: lsp12DataKeys, values: lsp12Values } = erc725.encodeData([
{ keyName: 'LSP12IssuedAssets[]', value: allAssetAddresses },
...allIssuedAssetsMap,
]);

Instantiate the Universal Profile contractโ€‹

Create an instance of the Universal Profile contract to read or set the issued assets on:

const myUPContract = new ethers.Contract(
UNIVERSAL_PROFILE_ADDRESS,
UniversalProfileArtifact.abi,
myWallet,
);

Set data batchโ€‹

Next, use the setDataBatch(...) function of the Universal Profile to initially set or update multiple data keys.

await myUPContract.setDataBatch(lsp12DataKeys, lsp12Values);