From e3ae42bdab5eaec56aeb6fe6bcf519dad17ee9e6 Mon Sep 17 00:00:00 2001 From: emmet-bot Date: Wed, 4 Mar 2026 10:13:01 +0100 Subject: [PATCH 01/10] docs: Add Type ID generation and data encoding explanations - Add 'How Type IDs are generated' section explaining keccak256(name) - Add 'TypeID generation' row to each type ID table - Add 'Data encoding' section for each type ID showing abi.encode params - Note LSP26 uses abi.encodePacked (20 bytes) vs abi.encode (32 bytes) - Rename page title and sidebar: 'Universal Receiver Type IDs' -> 'LSP1 Notification Type IDs' Follow-up to PR #1332 based on review from @CJ42. --- docs/contracts/type-ids.md | 178 ++++++++++++++++++++++++++++++++++++- 1 file changed, 176 insertions(+), 2 deletions(-) diff --git a/docs/contracts/type-ids.md b/docs/contracts/type-ids.md index e952fac3f4..cc8281fe94 100644 --- a/docs/contracts/type-ids.md +++ b/docs/contracts/type-ids.md @@ -1,8 +1,9 @@ --- -title: Universal Receiver Type IDs +title: LSP1 Notification Type IDs +sidebar_label: LSP1 Notification Type IDs --- -# Universal Receiver Type IDs +# LSP1 Notification Type IDs The **LSP1 Type IDs** listed below are unique identifiers used across the LSP standards for the [Universal Receiver](../standards/accounts/lsp1-universal-receiver.md) notification mechanism. @@ -14,6 +15,26 @@ For instance: - Notify a recipient about receiving LSP7 tokens - Notify a profile that they have a new follower +### How Type IDs are generated + +Each Type ID is a `bytes32` value computed as the **keccak256 hash of the Type ID name string**. For example: + +``` +keccak256("LSP7Tokens_SenderNotification") = 0x429ac7a06903dbc9c13dfcb3c9d11df8194581fa047c96d7a4171fc7402958ea +``` + +You can verify any Type ID by hashing its name: + +```solidity +bytes32 typeId = keccak256("LSP7Tokens_SenderNotification"); +``` + +```js +import { keccak256, toUtf8Bytes } from 'ethers'; + +const typeId = keccak256(toUtf8Bytes('LSP7Tokens_SenderNotification')); +``` + ## Using Type IDs in JavaScript The Type IDs are available as constants from the [`@lukso/lsp-smart-contracts`](https://www.npmjs.com/package/@lukso/lsp-smart-contracts) npm package: @@ -49,40 +70,68 @@ LSP1_TYPE_IDS.LSP26FollowerSystem_FollowNotification; | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Name** | `"LSP0ValueReceived"` | | **TypeID** | `0x9c4705229491d365fb5434052e12a386d6771d976bea61070a8c694e8affea3d` | +| **TypeID generation** | `keccak256("LSP0ValueReceived")` | | **Used in:** | [`constructor(address)`](./contracts/LSP0ERC725Account/LSP0ERC725Account.md#constructor), [`receive()`](./contracts/LSP0ERC725Account/LSP0ERC725Account.md#receive), [`fallback(bytes)`](./contracts/LSP0ERC725Account/LSP0ERC725Account.md#fallback), [`execute(uint256,address,uint256,bytes)`](./contracts/LSP0ERC725Account/LSP0ERC725Account.md#execute), [`executeBatch(uint256[],address[],uint256[],bytes[])`](./contracts/LSP0ERC725Account/LSP0ERC725Account.md#executebatch), [`setData(bytes32,bytes)`](./contracts/LSP0ERC725Account/LSP0ERC725Account.md#setdata), [`setDataBatch(bytes32[],bytes[])`](./contracts/LSP0ERC725Account/LSP0ERC725Account.md#setdatabatch) | | **Solidity constant:** | `_TYPEID_LSP0_VALUE_RECEIVED` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP0ValueReceived` | +**Data encoding:** Empty bytes (`""`) — no additional data is sent with this notification. + ### `LSP0OwnershipTransferStarted` | | | | ------------------------ | ---------------------------------------------------------------------------------------------------- | | **Name** | `"LSP0OwnershipTransferStarted"` | | **TypeID** | `0xe17117c9d2665d1dbeb479ed8058bbebde3c50ac50e2e65619f60006caac6926` | +| **TypeID generation** | `keccak256("LSP0OwnershipTransferStarted")` | | **Used in:** | [`transferOwnership(address)`](./contracts/LSP0ERC725Account/LSP0ERC725Account.md#transferownership) | | **Solidity constant:** | `_TYPEID_LSP0_OwnershipTransferStarted` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP0OwnershipTransferStarted` | +**Data encoding:** + +```solidity +abi.encode(address currentOwner, address pendingNewOwner) +``` + ### `LSP0OwnershipTransferred_SenderNotification` | | | | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Name** | `"LSP0OwnershipTransferred_SenderNotification"` | | **TypeID** | `0xa4e59c931d14f7c8a7a35027f92ee40b5f2886b9fdcdb78f30bc5ecce5a2f814` | +| **TypeID generation** | `keccak256("LSP0OwnershipTransferred_SenderNotification")` | | **Used in:** | [`acceptOwnership()`](./contracts/LSP0ERC725Account/LSP0ERC725Account.md#acceptownership)
[`renounceOwnership()`](./contracts/LSP0ERC725Account/LSP0ERC725Account.md#renounceownership) | | **Solidity constant:** | `_TYPEID_LSP0_OwnershipTransferred_SenderNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP0OwnershipTransferred_SenderNotification` | +**Data encoding:** + +```solidity +// On acceptOwnership(): +abi.encode(address previousOwner, address newOwner) + +// On renounceOwnership(): +abi.encode(address previousOwner, address(0)) +``` + ### `LSP0OwnershipTransferred_RecipientNotification` | | | | ------------------------ | ----------------------------------------------------------------------------------------- | | **Name** | `"LSP0OwnershipTransferred_RecipientNotification"` | | **TypeID** | `0xceca317f109c43507871523e82dc2a3cc64dfa18f12da0b6db14f6e23f995538` | +| **TypeID generation** | `keccak256("LSP0OwnershipTransferred_RecipientNotification")` | | **Used in:** | [`acceptOwnership()`](./contracts/LSP0ERC725Account/LSP0ERC725Account.md#acceptownership) | | **Solidity constant:** | `_TYPEID_LSP0_OwnershipTransferred_RecipientNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP0OwnershipTransferred_RecipientNotification` | +**Data encoding:** + +```solidity +abi.encode(address previousOwner, address newOwner) +``` + --- ## LSP7 - Digital Asset @@ -93,30 +142,57 @@ LSP1_TYPE_IDS.LSP26FollowerSystem_FollowNotification; | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Name** | `"LSP7Tokens_SenderNotification"` | | **TypeID** | `0x429ac7a06903dbc9c13dfcb3c9d11df8194581fa047c96d7a4171fc7402958ea` | +| **TypeID generation** | `keccak256("LSP7Tokens_SenderNotification")` | | **Used in:** | [`_burn(address,uint256,bytes)`](./contracts/LSP7DigitalAsset/LSP7DigitalAsset.md#_burn),
[`_transfer(address,address,uint256,bool,bytes)`](./contracts/LSP7DigitalAsset/LSP7DigitalAsset.md#_transfer) | | **Solidity constant:** | `_TYPEID_LSP7_TOKENSSENDER` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP7Tokens_SenderNotification` | +**Data encoding:** + +```solidity +abi.encode(address operator, address from, address to, uint256 amount, bytes data) +// `to` is address(0) when burning +``` + ### `LSP7Tokens_RecipientNotification` | | | | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Name** | `"LSP7Tokens_RecipientNotification"` | | **TypeID** | `0x20804611b3e2ea21c480dc465142210acf4a2485947541770ec1fb87dee4a55c` | +| **TypeID generation** | `keccak256("LSP7Tokens_RecipientNotification")` | | **Used in:** | [`_mint(address,uint256,bool,bytes)`](./contracts/LSP7DigitalAsset/LSP7DigitalAsset.md#_mint),
[`_transfer(address,address,uint256,bool,bytes)`](./contracts/LSP7DigitalAsset/LSP7DigitalAsset.md#_transfer) | | **Solidity constant:** | `_TYPEID_LSP7_TOKENSRECIPIENT` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP7Tokens_RecipientNotification` | +**Data encoding:** + +```solidity +abi.encode(address operator, address from, address to, uint256 amount, bytes data) +// `from` is address(0) when minting +``` + ### `LSP7Tokens_OperatorNotification` | | | | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Name** | `"LSP7Tokens_OperatorNotification"` | | **TypeID** | `0x386072cc5a58e61263b434c722725f21031cd06e7c552cfaa06db5de8a320dbc` | +| **TypeID generation** | `keccak256("LSP7Tokens_OperatorNotification")` | | **Used in:** | [`authorizeOperator(address,uint256,bytes)`](./contracts/LSP7DigitalAsset/LSP7DigitalAsset.md#authorizeoperator), [`revokeOperator(address,bool,bytes)`](./contracts/LSP7DigitalAsset/LSP7DigitalAsset.md#revokeoperator), [`increaseAllowance(address,uint256,bytes)`](./contracts/LSP7DigitalAsset/LSP7DigitalAsset.md#increaseallowance), [`decreaseAllowance(address,uint256,bytes)`](./contracts/LSP7DigitalAsset/LSP7DigitalAsset.md#decreaseallowance) | | **Solidity constant:** | `_TYPEID_LSP7_TOKENOPERATOR` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP7Tokens_OperatorNotification` | +**Data encoding:** + +```solidity +// On authorizeOperator / increaseAllowance / decreaseAllowance: +abi.encode(address tokenOwner, uint256 allowance, bytes operatorNotificationData) + +// On revokeOperator: +abi.encode(address tokenOwner, uint256 0, bytes operatorNotificationData) +``` + --- ## LSP8 - Identifiable Digital Asset @@ -127,30 +203,57 @@ LSP1_TYPE_IDS.LSP26FollowerSystem_FollowNotification; | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Name** | `"LSP8Tokens_SenderNotification"` | | **TypeID** | `0xb23eae7e6d1564b295b4c3e3be402d9a2f0776c57bdf365903496f6fa481ab00` | +| **TypeID generation** | `keccak256("LSP8Tokens_SenderNotification")` | | **Used in:** | [`_burn(bytes32,bytes)`](./contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.md#_burn),
[`_transfer(address,address,bytes32,bool,bytes)`](./contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.md#_transfer) | | **Solidity constant:** | `_TYPEID_LSP8_TOKENSSENDER` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP8Tokens_SenderNotification` | +**Data encoding:** + +```solidity +abi.encode(address operator, address from, address to, bytes32 tokenId, bytes data) +// `to` is address(0) when burning +``` + ### `LSP8Tokens_RecipientNotification` | | | | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Name** | `"LSP8Tokens_RecipientNotification"` | | **TypeID** | `0x0b084a55ebf70fd3c06fd755269dac2212c4d3f0f4d09079780bfa50c1b2984d` | +| **TypeID generation** | `keccak256("LSP8Tokens_RecipientNotification")` | | **Used in:** | [`_mint(address,bytes32,bool,bytes)`](./contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.md#_mint),
[`_transfer(address,address,bytes32,bool,bytes)`](./contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.md#_transfer) | | **Solidity constant:** | `_TYPEID_LSP8_TOKENSRECIPIENT` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP8Tokens_RecipientNotification` | +**Data encoding:** + +```solidity +abi.encode(address operator, address from, address to, bytes32 tokenId, bytes data) +// `from` is address(0) when minting +``` + ### `LSP8Tokens_OperatorNotification` | | | | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Name** | `"LSP8Tokens_OperatorNotification"` | | **TypeID** | `0x468cd1581d7bc001c3b685513d2b929b55437be34700410383d58f3aa1ea0abc` | +| **TypeID generation** | `keccak256("LSP8Tokens_OperatorNotification")` | | **Used in:** | [`authorizeOperator(address,bytes32,bytes)`](./contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.md#authorizeoperator), [`revokeOperator(address,bytes32,bool,bytes)`](./contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.md#revokeoperator) | | **Solidity constant:** | `_TYPEID_LSP8_TOKENOPERATOR` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP8Tokens_OperatorNotification` | +**Data encoding:** + +```solidity +// On authorizeOperator: +abi.encode(address tokenOwner, bytes32 tokenId, bool true, bytes operatorNotificationData) + +// On revokeOperator: +abi.encode(address tokenOwner, bytes32 tokenId, bool false, bytes operatorNotificationData) +``` + --- ## LSP9 - Vault @@ -161,40 +264,68 @@ LSP1_TYPE_IDS.LSP26FollowerSystem_FollowNotification; | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Name** | `"LSP9ValueReceived"` | | **TypeID** | `0x468cd1581d7bc001c3b685513d2b929b55437be34700410383d58f3aa1ea0abc` | +| **TypeID generation** | `keccak256("LSP9ValueReceived")` | | **Used in:** | [`constructor(address)`](./contracts/LSP9Vault/LSP9Vault.md#constructor), [`receive()`](./contracts/LSP9Vault/LSP9Vault.md#receive), [`fallback(bytes)`](./contracts/LSP9Vault/LSP9Vault.md#fallback), [`execute(uint256,address,uint256,bytes)`](./contracts/LSP9Vault/LSP9Vault.md#execute), [`executeBatch(uint256[],address[],uint256[],bytes[])`](./contracts/LSP9Vault/LSP9Vault.md#executebatch) | | **Solidity constant:** | `_TYPEID_LSP9_VALUE_RECEIVED` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP9ValueReceived` | +**Data encoding:** Empty bytes (`""`) — no additional data is sent with this notification. + ### `LSP9OwnershipTransferStarted` | | | | ------------------------ | ------------------------------------------------------------------------------------ | | **Name** | `"LSP9OwnershipTransferStarted"` | | **TypeID** | `0xaefd43f45fed1bcd8992f23c803b6f4ec45cf6b62b0d404d565f290a471e763f` | +| **TypeID generation** | `keccak256("LSP9OwnershipTransferStarted")` | | **Used in:** | [`transferOwnership(address)`](./contracts/LSP9Vault/LSP9Vault.md#transferownership) | | **Solidity constant:** | `_TYPEID_LSP9_OwnershipTransferStarted` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP9OwnershipTransferStarted` | +**Data encoding:** + +```solidity +abi.encode(address currentOwner, address pendingNewOwner) +``` + ### `LSP9OwnershipTransferred_SenderNotification` | | | | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Name** | `"LSP9OwnershipTransferred_SenderNotification"` | | **TypeID** | `0x0c622e58e6b7089ae35f1af1c86d997be92fcdd8c9509652022d41aa65169471` | +| **TypeID generation** | `keccak256("LSP9OwnershipTransferred_SenderNotification")` | | **Used in:** | [`acceptOwnership()`](./contracts/LSP9Vault/LSP9Vault.md#acceptownership)
[`renounceOwnership()`](./contracts/LSP9Vault/LSP9Vault.md#renounceownership) | | **Solidity constant:** | `_TYPEID_LSP9_OwnershipTransferred_SenderNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP9OwnershipTransferred_SenderNotification` | +**Data encoding:** + +```solidity +// On acceptOwnership(): +abi.encode(address previousOwner, address newOwner) + +// On renounceOwnership(): +abi.encode(address previousOwner, address(0)) +``` + ### `LSP9OwnershipTransferred_RecipientNotification` | | | | ------------------------ | ------------------------------------------------------------------------- | | **Name** | `"LSP9OwnershipTransferred_RecipientNotification"` | | **TypeID** | `0x79855c97dbc259ce395421d933d7bc0699b0f1561f988f09a9e8633fd542fe5c` | +| **TypeID generation** | `keccak256("LSP9OwnershipTransferred_RecipientNotification")` | | **Used in:** | [`acceptOwnership()`](./contracts/LSP9Vault/LSP9Vault.md#acceptownership) | | **Solidity constant:** | `_TYPEID_LSP9_OwnershipTransferred_RecipientNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP9OwnershipTransferred_RecipientNotification` | +**Data encoding:** + +```solidity +abi.encode(address previousOwner, address newOwner) +``` + --- ## LSP14 - Ownable 2-Step @@ -205,30 +336,55 @@ LSP1_TYPE_IDS.LSP26FollowerSystem_FollowNotification; | ------------------------ | ---------------------------------------------------------------------------------------------------- | | **Name** | `"LSP14OwnershipTransferStarted"` | | **TypeID** | `0xee9a7c0924f740a2ca33d59b7f0c2929821ea9837ce043ce91c1823e9c4e52c0` | +| **TypeID generation** | `keccak256("LSP14OwnershipTransferStarted")` | | **Used in:** | [`transferOwnership(address)`](./contracts/LSP14Ownable2Step/LSP14Ownable2Step.md#transferownership) | | **Solidity constant:** | `_TYPEID_LSP14_OwnershipTransferStarted` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP14OwnershipTransferStarted` | +**Data encoding:** + +```solidity +abi.encode(address currentOwner, address pendingNewOwner) +``` + #### `LSP14OwnershipTransferred_SenderNotification` | | | | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Name** | `"LSP14OwnershipTransferred_SenderNotification"` | | **TypeID** | `0xa124442e1cc7b52d8e2ede2787d43527dc1f3ae0de87f50dd03e27a71834f74c` | +| **TypeID generation** | `keccak256("LSP14OwnershipTransferred_SenderNotification")` | | **Used in:** | [`acceptOwnership()`](./contracts/LSP14Ownable2Step/LSP14Ownable2Step.md#acceptownership)
[`renounceOwnership()`](./contracts/LSP14Ownable2Step/LSP14Ownable2Step.md#renounceownership) | | **Solidity constant:** | `_TYPEID_LSP14_OwnershipTransferred_SenderNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP14OwnershipTransferred_SenderNotification` | +**Data encoding:** + +```solidity +// On acceptOwnership(): +abi.encode(address previousOwner, address newOwner) + +// On renounceOwnership(): +abi.encode(address previousOwner, address(0)) +``` + #### `LSP14OwnershipTransferred_RecipientNotification` | | | | ------------------------ | ----------------------------------------------------------------------------------------- | | **Name** | `"LSP14OwnershipTransferred_RecipientNotification"` | | **TypeID** | `0xe32c7debcb817925ba4883fdbfc52797187f28f73f860641dab1a68d9b32902c` | +| **TypeID generation** | `keccak256("LSP14OwnershipTransferred_RecipientNotification")` | | **Used in:** | [`acceptOwnership()`](./contracts/LSP14Ownable2Step/LSP14Ownable2Step.md#acceptownership) | | **Solidity constant:** | `_TYPEID_LSP14_OwnershipTransferred_RecipientNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP14OwnershipTransferred_RecipientNotification` | +**Data encoding:** + +```solidity +abi.encode(address previousOwner, address newOwner) +``` + --- ## LSP26 - Follower System @@ -239,16 +395,34 @@ LSP1_TYPE_IDS.LSP26FollowerSystem_FollowNotification; | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------- | | **Name** | `"LSP26FollowerSystem_FollowNotification"` | | **TypeID** | `0x71e02f9f05bcd5816ec4f3134aa2e5a916669537ec6c77fe66ea595fabc2d51a` | +| **TypeID generation** | `keccak256("LSP26FollowerSystem_FollowNotification")` | | **Used in:** | [`follow(address)`](../standards/accounts/lsp26-follower-system.md) — notifies the followed address that they have a new follower | | **Solidity constant:** | `_TYPEID_LSP26_FOLLOW` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP26FollowerSystem_FollowNotification` | +**Data encoding:** + +```solidity +abi.encodePacked(address follower) +``` + +> **Note:** LSP26 uses `abi.encodePacked` (not `abi.encode`), so the data is 20 bytes (the raw address) rather than 32 bytes (ABI-padded). + ### `LSP26FollowerSystem_UnfollowNotification` | | | | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------- | | **Name** | `"LSP26FollowerSystem_UnfollowNotification"` | | **TypeID** | `0x9d3c0b4012b69658977b099bdaa51eff0f0460f421fba96d15669506c00d1c4f` | +| **TypeID generation** | `keccak256("LSP26FollowerSystem_UnfollowNotification")` | | **Used in:** | [`unfollow(address)`](../standards/accounts/lsp26-follower-system.md) — notifies the unfollowed address that they lost a follower | | **Solidity constant:** | `_TYPEID_LSP26_UNFOLLOW` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP26FollowerSystem_UnfollowNotification` | + +**Data encoding:** + +```solidity +abi.encodePacked(address unfollower) +``` + +> **Note:** LSP26 uses `abi.encodePacked` (not `abi.encode`), so the data is 20 bytes (the raw address) rather than 32 bytes (ABI-padded). From 1feb34b2a284b2aa722936390b6aabe449239904 Mon Sep 17 00:00:00 2001 From: emmet-bot Date: Mon, 16 Mar 2026 11:35:06 +0100 Subject: [PATCH 02/10] fix: Address review comments from Leo - Fix wrong TypeID for LSP8Tokens_OperatorNotification (was showing LSP9ValueReceived hash 0x468cd... instead of correct 0x8a1c15a8...) - Replace 'bool true'/'bool false' with named 'bool authorized' param in LSP8 operator data encoding - Replace 'uint256 0' with named 'uint256 allowance' param in LSP7 operator revokeOperator data encoding - Add ethers v6 version comment and viem alternative for keccak256 example --- docs/contracts/type-ids.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/docs/contracts/type-ids.md b/docs/contracts/type-ids.md index cc8281fe94..47e74c956b 100644 --- a/docs/contracts/type-ids.md +++ b/docs/contracts/type-ids.md @@ -30,11 +30,17 @@ bytes32 typeId = keccak256("LSP7Tokens_SenderNotification"); ``` ```js +// ethers v6 import { keccak256, toUtf8Bytes } from 'ethers'; - const typeId = keccak256(toUtf8Bytes('LSP7Tokens_SenderNotification')); ``` +```js +// viem +import { keccak256, toHex } from 'viem'; +const typeId = keccak256(toHex('LSP7Tokens_SenderNotification')); +``` + ## Using Type IDs in JavaScript The Type IDs are available as constants from the [`@lukso/lsp-smart-contracts`](https://www.npmjs.com/package/@lukso/lsp-smart-contracts) npm package: @@ -189,8 +195,8 @@ abi.encode(address operator, address from, address to, uint256 amount, bytes dat // On authorizeOperator / increaseAllowance / decreaseAllowance: abi.encode(address tokenOwner, uint256 allowance, bytes operatorNotificationData) -// On revokeOperator: -abi.encode(address tokenOwner, uint256 0, bytes operatorNotificationData) +// On revokeOperator (allowance is always 0): +abi.encode(address tokenOwner, uint256 allowance, bytes operatorNotificationData) ``` --- @@ -238,7 +244,7 @@ abi.encode(address operator, address from, address to, bytes32 tokenId, bytes da | | | | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Name** | `"LSP8Tokens_OperatorNotification"` | -| **TypeID** | `0x468cd1581d7bc001c3b685513d2b929b55437be34700410383d58f3aa1ea0abc` | +| **TypeID** | `0x8a1c15a8799f71b547e08e2bcb2e85257e81b0a07eee2ce6712549eef1f00970` | | **TypeID generation** | `keccak256("LSP8Tokens_OperatorNotification")` | | **Used in:** | [`authorizeOperator(address,bytes32,bytes)`](./contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.md#authorizeoperator), [`revokeOperator(address,bytes32,bool,bytes)`](./contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.md#revokeoperator) | | **Solidity constant:** | `_TYPEID_LSP8_TOKENOPERATOR` | @@ -247,11 +253,11 @@ abi.encode(address operator, address from, address to, bytes32 tokenId, bytes da **Data encoding:** ```solidity -// On authorizeOperator: -abi.encode(address tokenOwner, bytes32 tokenId, bool true, bytes operatorNotificationData) +// On authorizeOperator (authorized = true): +abi.encode(address tokenOwner, bytes32 tokenId, bool authorized, bytes operatorNotificationData) -// On revokeOperator: -abi.encode(address tokenOwner, bytes32 tokenId, bool false, bytes operatorNotificationData) +// On revokeOperator (authorized = false): +abi.encode(address tokenOwner, bytes32 tokenId, bool authorized, bytes operatorNotificationData) ``` --- From a568c1bafeedd30d611469c7741c75b5bbacad3b Mon Sep 17 00:00:00 2001 From: emmet-bot Date: Mon, 16 Mar 2026 13:03:12 +0100 Subject: [PATCH 03/10] refactor: Address Jean's review - tabs, TOC, collapsible, decoding examples - Add Tabs (Solidity/ethers/viem) for all code snippets matching docs pattern - Add 'Notification Type IDs list' table with anchor links to all 19 type IDs - Wrap 'How Type IDs are generated' in collapsible
- Rename 'Using Type IDs in JavaScript' -> 'Using Type ID' with Solidity + JS tabs - Replace data encoding sections with encoding AND decoding examples in all three languages (Solidity abi.decode, ethers AbiCoder, viem decodeAbiParameters) - LSP26: show address(bytes20(data)) pattern for abi.encodePacked decoding - Use existing CSS tab classes (tab_ethers, tab_viem) with groupId sync --- docs/contracts/type-ids.md | 891 ++++++++++++++++++++++++++++++++++--- 1 file changed, 820 insertions(+), 71 deletions(-) diff --git a/docs/contracts/type-ids.md b/docs/contracts/type-ids.md index 47e74c956b..676f1f0673 100644 --- a/docs/contracts/type-ids.md +++ b/docs/contracts/type-ids.md @@ -3,6 +3,9 @@ title: LSP1 Notification Type IDs sidebar_label: LSP1 Notification Type IDs --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + # LSP1 Notification Type IDs The **LSP1 Type IDs** listed below are unique identifiers used across the LSP standards for the [Universal Receiver](../standards/accounts/lsp1-universal-receiver.md) notification mechanism. @@ -15,7 +18,85 @@ For instance: - Notify a recipient about receiving LSP7 tokens - Notify a profile that they have a new follower -### How Type IDs are generated +## Notification Type IDs list + +| Standard | Type ID Name | Link | +| -------- | ------------------------------------------------- | ----------------------------------------------------- | +| LSP0 | `LSP0ValueReceived` | [↓](#lsp0valuereceived) | +| LSP0 | `LSP0OwnershipTransferStarted` | [↓](#lsp0ownershiptransferstarted) | +| LSP0 | `LSP0OwnershipTransferred_SenderNotification` | [↓](#lsp0ownershiptransferred_sendernotification) | +| LSP0 | `LSP0OwnershipTransferred_RecipientNotification` | [↓](#lsp0ownershiptransferred_recipientnotification) | +| LSP7 | `LSP7Tokens_SenderNotification` | [↓](#lsp7tokens_sendernotification) | +| LSP7 | `LSP7Tokens_RecipientNotification` | [↓](#lsp7tokens_recipientnotification) | +| LSP7 | `LSP7Tokens_OperatorNotification` | [↓](#lsp7tokens_operatornotification) | +| LSP8 | `LSP8Tokens_SenderNotification` | [↓](#lsp8tokens_sendernotification) | +| LSP8 | `LSP8Tokens_RecipientNotification` | [↓](#lsp8tokens_recipientnotification) | +| LSP8 | `LSP8Tokens_OperatorNotification` | [↓](#lsp8tokens_operatornotification) | +| LSP9 | `LSP9ValueReceived` | [↓](#lsp9valuereceived) | +| LSP9 | `LSP9OwnershipTransferStarted` | [↓](#lsp9ownershiptransferstarted) | +| LSP9 | `LSP9OwnershipTransferred_SenderNotification` | [↓](#lsp9ownershiptransferred_sendernotification) | +| LSP9 | `LSP9OwnershipTransferred_RecipientNotification` | [↓](#lsp9ownershiptransferred_recipientnotification) | +| LSP14 | `LSP14OwnershipTransferStarted` | [↓](#lsp14ownershiptransferstarted) | +| LSP14 | `LSP14OwnershipTransferred_SenderNotification` | [↓](#lsp14ownershiptransferred_sendernotification) | +| LSP14 | `LSP14OwnershipTransferred_RecipientNotification` | [↓](#lsp14ownershiptransferred_recipientnotification) | +| LSP26 | `LSP26FollowerSystem_FollowNotification` | [↓](#lsp26followersystem_follownotification) | +| LSP26 | `LSP26FollowerSystem_UnfollowNotification` | [↓](#lsp26followersystem_unfollownotification) | + +## Using Type ID + + + + +```solidity +import { _TYPEID_LSP7_TOKENSSENDER } from "@lukso/lsp7-contracts/contracts/LSP7Constants.sol"; + +function universalReceiverDelegate( + address sender, + uint256 value, + bytes32 typeId, + bytes memory data +) external returns (bytes memory) { + if (typeId == _TYPEID_LSP7_TOKENSSENDER) { + // handle LSP7 token sent notification + } +} +``` + + + + +```js +import { LSP1_TYPE_IDS } from '@lukso/lsp-smart-contracts'; + +// Type ID for receiving native tokens (LYX) +LSP1_TYPE_IDS.LSP0ValueReceived; + +// Type ID for receiving LSP7 tokens +LSP1_TYPE_IDS.LSP7Tokens_RecipientNotification; + +// Type ID for follow notifications +LSP1_TYPE_IDS.LSP26FollowerSystem_FollowNotification; +``` + + + + +```js +import { LSP1_TYPE_IDS } from '@lukso/lsp-smart-contracts'; + +// The constants are the same — they are plain bytes32 hex strings +LSP1_TYPE_IDS.LSP7Tokens_RecipientNotification; +``` + + + + +> **Note:** The JavaScript constants are exported from the `@lukso/lsp-smart-contracts` package. The corresponding Solidity constants are defined in each LSP's contract constants file (e.g., `LSP7Constants.sol`, `LSP26Constants.sol`). +> +> See the [lsp-smart-contracts repository](https://github.com/lukso-network/lsp-smart-contracts) for the full source code. + +
+ How Type IDs are generated Each Type ID is a `bytes32` value computed as the **keccak256 hash of the Type ID name string**. For example: @@ -25,46 +106,33 @@ keccak256("LSP7Tokens_SenderNotification") = 0x429ac7a06903dbc9c13dfcb3c9d11df81 You can verify any Type ID by hashing its name: + + + ```solidity bytes32 typeId = keccak256("LSP7Tokens_SenderNotification"); ``` + + + ```js -// ethers v6 -import { keccak256, toUtf8Bytes } from 'ethers'; +import { keccak256, toUtf8Bytes } from 'ethers'; // ethers v6 const typeId = keccak256(toUtf8Bytes('LSP7Tokens_SenderNotification')); ``` + + + ```js -// viem import { keccak256, toHex } from 'viem'; const typeId = keccak256(toHex('LSP7Tokens_SenderNotification')); ``` -## Using Type IDs in JavaScript + + -The Type IDs are available as constants from the [`@lukso/lsp-smart-contracts`](https://www.npmjs.com/package/@lukso/lsp-smart-contracts) npm package: - -```bash -npm install @lukso/lsp-smart-contracts -``` - -```js -import { LSP1_TYPE_IDS } from '@lukso/lsp-smart-contracts'; - -// Type ID for receiving native tokens (LYX) -LSP1_TYPE_IDS.LSP0ValueReceived; - -// Type ID for receiving LSP7 tokens -LSP1_TYPE_IDS.LSP7Tokens_RecipientNotification; - -// Type ID for follow notifications -LSP1_TYPE_IDS.LSP26FollowerSystem_FollowNotification; -``` - -> **Note:** The JavaScript constants are exported from the `@lukso/lsp-smart-contracts` package. The corresponding Solidity constants are defined in each LSP's contract constants file (e.g., `LSP7Constants.sol`, `LSP26Constants.sol`). -> -> See the [lsp-smart-contracts repository](https://github.com/lukso-network/lsp-smart-contracts) for the full source code. +
--- @@ -94,12 +162,47 @@ LSP1_TYPE_IDS.LSP26FollowerSystem_FollowNotification; | **Solidity constant:** | `_TYPEID_LSP0_OwnershipTransferStarted` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP0OwnershipTransferStarted` | -**Data encoding:** +**Data encoding and decoding:** + + + ```solidity -abi.encode(address currentOwner, address pendingNewOwner) +// Encoding (inside the contract): +bytes memory encodedData = abi.encode(address currentOwner, address pendingNewOwner); + +// Decoding (inside a Universal Receiver Delegate): +(address currentOwner, address pendingNewOwner) = abi.decode(data, (address, address)); ``` + + + +```js +import { AbiCoder } from 'ethers'; + +const abiCoder = new AbiCoder(); +const [currentOwner, pendingNewOwner] = abiCoder.decode( + ['address', 'address'], + data, +); +``` + + + + +```js +import { decodeAbiParameters } from 'viem'; + +const [currentOwner, pendingNewOwner] = decodeAbiParameters( + [{ type: 'address' }, { type: 'address' }], + data, +); +``` + + + + ### `LSP0OwnershipTransferred_SenderNotification` | | | @@ -111,16 +214,49 @@ abi.encode(address currentOwner, address pendingNewOwner) | **Solidity constant:** | `_TYPEID_LSP0_OwnershipTransferred_SenderNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP0OwnershipTransferred_SenderNotification` | -**Data encoding:** +**Data encoding and decoding:** + + + ```solidity +// Encoding (inside the contract): // On acceptOwnership(): -abi.encode(address previousOwner, address newOwner) - +bytes memory encodedData = abi.encode(address previousOwner, address newOwner); // On renounceOwnership(): -abi.encode(address previousOwner, address(0)) +bytes memory encodedData = abi.encode(address previousOwner, address(0)); + +// Decoding (inside a Universal Receiver Delegate): +(address previousOwner, address newOwner) = abi.decode(data, (address, address)); ``` + + + +```js +import { AbiCoder } from 'ethers'; + +const abiCoder = new AbiCoder(); +const [previousOwner, newOwner] = abiCoder.decode(['address', 'address'], data); +// newOwner is address(0) on renounceOwnership +``` + + + + +```js +import { decodeAbiParameters } from 'viem'; + +const [previousOwner, newOwner] = decodeAbiParameters( + [{ type: 'address' }, { type: 'address' }], + data, +); +// newOwner is address(0) on renounceOwnership +``` + + + + ### `LSP0OwnershipTransferred_RecipientNotification` | | | @@ -132,12 +268,44 @@ abi.encode(address previousOwner, address(0)) | **Solidity constant:** | `_TYPEID_LSP0_OwnershipTransferred_RecipientNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP0OwnershipTransferred_RecipientNotification` | -**Data encoding:** +**Data encoding and decoding:** + + + ```solidity -abi.encode(address previousOwner, address newOwner) +// Encoding: +bytes memory encodedData = abi.encode(address previousOwner, address newOwner); + +// Decoding: +(address previousOwner, address newOwner) = abi.decode(data, (address, address)); +``` + + + + +```js +import { AbiCoder } from 'ethers'; + +const abiCoder = new AbiCoder(); +const [previousOwner, newOwner] = abiCoder.decode(['address', 'address'], data); ``` + + + +```js +import { decodeAbiParameters } from 'viem'; + +const [previousOwner, newOwner] = decodeAbiParameters( + [{ type: 'address' }, { type: 'address' }], + data, +); +``` + + + + --- ## LSP7 - Digital Asset @@ -153,13 +321,67 @@ abi.encode(address previousOwner, address newOwner) | **Solidity constant:** | `_TYPEID_LSP7_TOKENSSENDER` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP7Tokens_SenderNotification` | -**Data encoding:** +**Data encoding and decoding:** + + + ```solidity -abi.encode(address operator, address from, address to, uint256 amount, bytes data) +// Encoding (inside the contract): +bytes memory encodedData = abi.encode( + address operator, + address from, + address to, // address(0) when burning + uint256 amount, + bytes memory data +); + +// Decoding (inside a Universal Receiver Delegate): +( + address operator, + address from, + address to, + uint256 amount, + bytes memory transferData +) = abi.decode(data, (address, address, address, uint256, bytes)); +``` + + + + +```js +import { AbiCoder } from 'ethers'; + +const abiCoder = new AbiCoder(); +const [operator, from, to, amount, transferData] = abiCoder.decode( + ['address', 'address', 'address', 'uint256', 'bytes'], + data, +); +// `to` is address(0) when burning +``` + + + + +```js +import { decodeAbiParameters } from 'viem'; + +const [operator, from, to, amount, transferData] = decodeAbiParameters( + [ + { type: 'address' }, + { type: 'address' }, + { type: 'address' }, + { type: 'uint256' }, + { type: 'bytes' }, + ], + data, +); // `to` is address(0) when burning ``` + + + ### `LSP7Tokens_RecipientNotification` | | | @@ -171,13 +393,67 @@ abi.encode(address operator, address from, address to, uint256 amount, bytes dat | **Solidity constant:** | `_TYPEID_LSP7_TOKENSRECIPIENT` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP7Tokens_RecipientNotification` | -**Data encoding:** +**Data encoding and decoding:** + + + ```solidity -abi.encode(address operator, address from, address to, uint256 amount, bytes data) +// Encoding (inside the contract): +bytes memory encodedData = abi.encode( + address operator, + address from, // address(0) when minting + address to, + uint256 amount, + bytes memory data +); + +// Decoding (inside a Universal Receiver Delegate): +( + address operator, + address from, + address to, + uint256 amount, + bytes memory transferData +) = abi.decode(data, (address, address, address, uint256, bytes)); +``` + + + + +```js +import { AbiCoder } from 'ethers'; + +const abiCoder = new AbiCoder(); +const [operator, from, to, amount, transferData] = abiCoder.decode( + ['address', 'address', 'address', 'uint256', 'bytes'], + data, +); // `from` is address(0) when minting ``` + + + +```js +import { decodeAbiParameters } from 'viem'; + +const [operator, from, to, amount, transferData] = decodeAbiParameters( + [ + { type: 'address' }, + { type: 'address' }, + { type: 'address' }, + { type: 'uint256' }, + { type: 'bytes' }, + ], + data, +); +// `from` is address(0) when minting +``` + + + + ### `LSP7Tokens_OperatorNotification` | | | @@ -189,16 +465,65 @@ abi.encode(address operator, address from, address to, uint256 amount, bytes dat | **Solidity constant:** | `_TYPEID_LSP7_TOKENOPERATOR` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP7Tokens_OperatorNotification` | -**Data encoding:** +**Data encoding and decoding:** + + + ```solidity +// Encoding (inside the contract): // On authorizeOperator / increaseAllowance / decreaseAllowance: -abi.encode(address tokenOwner, uint256 allowance, bytes operatorNotificationData) +bytes memory encodedData = abi.encode( + address tokenOwner, + uint256 allowance, + bytes memory operatorNotificationData +); // On revokeOperator (allowance is always 0): -abi.encode(address tokenOwner, uint256 allowance, bytes operatorNotificationData) +bytes memory encodedData = abi.encode( + address tokenOwner, + uint256 allowance, // 0 + bytes memory operatorNotificationData +); + +// Decoding (inside a Universal Receiver Delegate): +( + address tokenOwner, + uint256 allowance, + bytes memory operatorNotificationData +) = abi.decode(data, (address, uint256, bytes)); +``` + + + + +```js +import { AbiCoder } from 'ethers'; + +const abiCoder = new AbiCoder(); +const [tokenOwner, allowance, operatorNotificationData] = abiCoder.decode( + ['address', 'uint256', 'bytes'], + data, +); +// allowance is 0 on revokeOperator ``` + + + +```js +import { decodeAbiParameters } from 'viem'; + +const [tokenOwner, allowance, operatorNotificationData] = decodeAbiParameters( + [{ type: 'address' }, { type: 'uint256' }, { type: 'bytes' }], + data, +); +// allowance is 0 on revokeOperator +``` + + + + --- ## LSP8 - Identifiable Digital Asset @@ -214,13 +539,67 @@ abi.encode(address tokenOwner, uint256 allowance, bytes operatorNotificationData | **Solidity constant:** | `_TYPEID_LSP8_TOKENSSENDER` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP8Tokens_SenderNotification` | -**Data encoding:** +**Data encoding and decoding:** + + + ```solidity -abi.encode(address operator, address from, address to, bytes32 tokenId, bytes data) +// Encoding (inside the contract): +bytes memory encodedData = abi.encode( + address operator, + address from, + address to, // address(0) when burning + bytes32 tokenId, + bytes memory data +); + +// Decoding (inside a Universal Receiver Delegate): +( + address operator, + address from, + address to, + bytes32 tokenId, + bytes memory transferData +) = abi.decode(data, (address, address, address, bytes32, bytes)); +``` + + + + +```js +import { AbiCoder } from 'ethers'; + +const abiCoder = new AbiCoder(); +const [operator, from, to, tokenId, transferData] = abiCoder.decode( + ['address', 'address', 'address', 'bytes32', 'bytes'], + data, +); // `to` is address(0) when burning ``` + + + +```js +import { decodeAbiParameters } from 'viem'; + +const [operator, from, to, tokenId, transferData] = decodeAbiParameters( + [ + { type: 'address' }, + { type: 'address' }, + { type: 'address' }, + { type: 'bytes32' }, + { type: 'bytes' }, + ], + data, +); +// `to` is address(0) when burning +``` + + + + ### `LSP8Tokens_RecipientNotification` | | | @@ -232,13 +611,67 @@ abi.encode(address operator, address from, address to, bytes32 tokenId, bytes da | **Solidity constant:** | `_TYPEID_LSP8_TOKENSRECIPIENT` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP8Tokens_RecipientNotification` | -**Data encoding:** +**Data encoding and decoding:** + + + ```solidity -abi.encode(address operator, address from, address to, bytes32 tokenId, bytes data) +// Encoding (inside the contract): +bytes memory encodedData = abi.encode( + address operator, + address from, // address(0) when minting + address to, + bytes32 tokenId, + bytes memory data +); + +// Decoding (inside a Universal Receiver Delegate): +( + address operator, + address from, + address to, + bytes32 tokenId, + bytes memory transferData +) = abi.decode(data, (address, address, address, bytes32, bytes)); +``` + + + + +```js +import { AbiCoder } from 'ethers'; + +const abiCoder = new AbiCoder(); +const [operator, from, to, tokenId, transferData] = abiCoder.decode( + ['address', 'address', 'address', 'bytes32', 'bytes'], + data, +); // `from` is address(0) when minting ``` + + + +```js +import { decodeAbiParameters } from 'viem'; + +const [operator, from, to, tokenId, transferData] = decodeAbiParameters( + [ + { type: 'address' }, + { type: 'address' }, + { type: 'address' }, + { type: 'bytes32' }, + { type: 'bytes' }, + ], + data, +); +// `from` is address(0) when minting +``` + + + + ### `LSP8Tokens_OperatorNotification` | | | @@ -250,16 +683,72 @@ abi.encode(address operator, address from, address to, bytes32 tokenId, bytes da | **Solidity constant:** | `_TYPEID_LSP8_TOKENOPERATOR` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP8Tokens_OperatorNotification` | -**Data encoding:** +**Data encoding and decoding:** + + + ```solidity +// Encoding (inside the contract): // On authorizeOperator (authorized = true): -abi.encode(address tokenOwner, bytes32 tokenId, bool authorized, bytes operatorNotificationData) +bytes memory encodedData = abi.encode( + address tokenOwner, + bytes32 tokenId, + bool authorized, // true + bytes memory operatorNotificationData +); // On revokeOperator (authorized = false): -abi.encode(address tokenOwner, bytes32 tokenId, bool authorized, bytes operatorNotificationData) +bytes memory encodedData = abi.encode( + address tokenOwner, + bytes32 tokenId, + bool authorized, // false + bytes memory operatorNotificationData +); + +// Decoding (inside a Universal Receiver Delegate): +( + address tokenOwner, + bytes32 tokenId, + bool authorized, + bytes memory operatorNotificationData +) = abi.decode(data, (address, bytes32, bool, bytes)); +``` + + + + +```js +import { AbiCoder } from 'ethers'; + +const abiCoder = new AbiCoder(); +const [tokenOwner, tokenId, authorized, operatorNotificationData] = + abiCoder.decode(['address', 'bytes32', 'bool', 'bytes'], data); +// authorized = true on authorizeOperator, false on revokeOperator ``` + + + +```js +import { decodeAbiParameters } from 'viem'; + +const [tokenOwner, tokenId, authorized, operatorNotificationData] = + decodeAbiParameters( + [ + { type: 'address' }, + { type: 'bytes32' }, + { type: 'bool' }, + { type: 'bytes' }, + ], + data, + ); +// authorized = true on authorizeOperator, false on revokeOperator +``` + + + + --- ## LSP9 - Vault @@ -288,12 +777,47 @@ abi.encode(address tokenOwner, bytes32 tokenId, bool authorized, bytes operatorN | **Solidity constant:** | `_TYPEID_LSP9_OwnershipTransferStarted` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP9OwnershipTransferStarted` | -**Data encoding:** +**Data encoding and decoding:** + + + ```solidity -abi.encode(address currentOwner, address pendingNewOwner) +// Encoding: +bytes memory encodedData = abi.encode(address currentOwner, address pendingNewOwner); + +// Decoding: +(address currentOwner, address pendingNewOwner) = abi.decode(data, (address, address)); +``` + + + + +```js +import { AbiCoder } from 'ethers'; + +const abiCoder = new AbiCoder(); +const [currentOwner, pendingNewOwner] = abiCoder.decode( + ['address', 'address'], + data, +); +``` + + + + +```js +import { decodeAbiParameters } from 'viem'; + +const [currentOwner, pendingNewOwner] = decodeAbiParameters( + [{ type: 'address' }, { type: 'address' }], + data, +); ``` + + + ### `LSP9OwnershipTransferred_SenderNotification` | | | @@ -305,16 +829,49 @@ abi.encode(address currentOwner, address pendingNewOwner) | **Solidity constant:** | `_TYPEID_LSP9_OwnershipTransferred_SenderNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP9OwnershipTransferred_SenderNotification` | -**Data encoding:** +**Data encoding and decoding:** + + + ```solidity +// Encoding: // On acceptOwnership(): -abi.encode(address previousOwner, address newOwner) - +bytes memory encodedData = abi.encode(address previousOwner, address newOwner); // On renounceOwnership(): -abi.encode(address previousOwner, address(0)) +bytes memory encodedData = abi.encode(address previousOwner, address(0)); + +// Decoding: +(address previousOwner, address newOwner) = abi.decode(data, (address, address)); +``` + + + + +```js +import { AbiCoder } from 'ethers'; + +const abiCoder = new AbiCoder(); +const [previousOwner, newOwner] = abiCoder.decode(['address', 'address'], data); +// newOwner is address(0) on renounceOwnership +``` + + + + +```js +import { decodeAbiParameters } from 'viem'; + +const [previousOwner, newOwner] = decodeAbiParameters( + [{ type: 'address' }, { type: 'address' }], + data, +); +// newOwner is address(0) on renounceOwnership ``` + + + ### `LSP9OwnershipTransferred_RecipientNotification` | | | @@ -326,12 +883,44 @@ abi.encode(address previousOwner, address(0)) | **Solidity constant:** | `_TYPEID_LSP9_OwnershipTransferred_RecipientNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP9OwnershipTransferred_RecipientNotification` | -**Data encoding:** +**Data encoding and decoding:** + + + ```solidity -abi.encode(address previousOwner, address newOwner) +// Encoding: +bytes memory encodedData = abi.encode(address previousOwner, address newOwner); + +// Decoding: +(address previousOwner, address newOwner) = abi.decode(data, (address, address)); +``` + + + + +```js +import { AbiCoder } from 'ethers'; + +const abiCoder = new AbiCoder(); +const [previousOwner, newOwner] = abiCoder.decode(['address', 'address'], data); ``` + + + +```js +import { decodeAbiParameters } from 'viem'; + +const [previousOwner, newOwner] = decodeAbiParameters( + [{ type: 'address' }, { type: 'address' }], + data, +); +``` + + + + --- ## LSP14 - Ownable 2-Step @@ -347,12 +936,47 @@ abi.encode(address previousOwner, address newOwner) | **Solidity constant:** | `_TYPEID_LSP14_OwnershipTransferStarted` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP14OwnershipTransferStarted` | -**Data encoding:** +**Data encoding and decoding:** + + + ```solidity -abi.encode(address currentOwner, address pendingNewOwner) +// Encoding: +bytes memory encodedData = abi.encode(address currentOwner, address pendingNewOwner); + +// Decoding: +(address currentOwner, address pendingNewOwner) = abi.decode(data, (address, address)); ``` + + + +```js +import { AbiCoder } from 'ethers'; + +const abiCoder = new AbiCoder(); +const [currentOwner, pendingNewOwner] = abiCoder.decode( + ['address', 'address'], + data, +); +``` + + + + +```js +import { decodeAbiParameters } from 'viem'; + +const [currentOwner, pendingNewOwner] = decodeAbiParameters( + [{ type: 'address' }, { type: 'address' }], + data, +); +``` + + + + #### `LSP14OwnershipTransferred_SenderNotification` | | | @@ -364,16 +988,49 @@ abi.encode(address currentOwner, address pendingNewOwner) | **Solidity constant:** | `_TYPEID_LSP14_OwnershipTransferred_SenderNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP14OwnershipTransferred_SenderNotification` | -**Data encoding:** +**Data encoding and decoding:** + + + ```solidity +// Encoding: // On acceptOwnership(): -abi.encode(address previousOwner, address newOwner) - +bytes memory encodedData = abi.encode(address previousOwner, address newOwner); // On renounceOwnership(): -abi.encode(address previousOwner, address(0)) +bytes memory encodedData = abi.encode(address previousOwner, address(0)); + +// Decoding: +(address previousOwner, address newOwner) = abi.decode(data, (address, address)); +``` + + + + +```js +import { AbiCoder } from 'ethers'; + +const abiCoder = new AbiCoder(); +const [previousOwner, newOwner] = abiCoder.decode(['address', 'address'], data); +// newOwner is address(0) on renounceOwnership ``` + + + +```js +import { decodeAbiParameters } from 'viem'; + +const [previousOwner, newOwner] = decodeAbiParameters( + [{ type: 'address' }, { type: 'address' }], + data, +); +// newOwner is address(0) on renounceOwnership +``` + + + + #### `LSP14OwnershipTransferred_RecipientNotification` | | | @@ -385,12 +1042,44 @@ abi.encode(address previousOwner, address(0)) | **Solidity constant:** | `_TYPEID_LSP14_OwnershipTransferred_RecipientNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP14OwnershipTransferred_RecipientNotification` | -**Data encoding:** +**Data encoding and decoding:** + + + ```solidity -abi.encode(address previousOwner, address newOwner) +// Encoding: +bytes memory encodedData = abi.encode(address previousOwner, address newOwner); + +// Decoding: +(address previousOwner, address newOwner) = abi.decode(data, (address, address)); +``` + + + + +```js +import { AbiCoder } from 'ethers'; + +const abiCoder = new AbiCoder(); +const [previousOwner, newOwner] = abiCoder.decode(['address', 'address'], data); +``` + + + + +```js +import { decodeAbiParameters } from 'viem'; + +const [previousOwner, newOwner] = decodeAbiParameters( + [{ type: 'address' }, { type: 'address' }], + data, +); ``` + + + --- ## LSP26 - Follower System @@ -406,13 +1095,43 @@ abi.encode(address previousOwner, address newOwner) | **Solidity constant:** | `_TYPEID_LSP26_FOLLOW` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP26FollowerSystem_FollowNotification` | -**Data encoding:** +**Data encoding and decoding:** + +> **Note:** LSP26 uses `abi.encodePacked` (not `abi.encode`), so the data is 20 bytes (the raw address) rather than 32 bytes (ABI-padded). + + + ```solidity -abi.encodePacked(address follower) +// Encoding (inside the LSP26 contract): +bytes memory encodedData = abi.encodePacked(address follower); + +// Decoding (inside a Universal Receiver Delegate): +address follower = address(bytes20(data)); ``` -> **Note:** LSP26 uses `abi.encodePacked` (not `abi.encode`), so the data is 20 bytes (the raw address) rather than 32 bytes (ABI-padded). + + + +```js +import { dataSlice, getAddress } from 'ethers'; + +// data is 20 bytes (not ABI-padded) +const follower = getAddress(dataSlice(data, 0, 20)); +``` + + + + +```js +import { getAddress, slice } from 'viem'; + +// data is 20 bytes (not ABI-padded) +const follower = getAddress(slice(data, 0, 20)); +``` + + + ### `LSP26FollowerSystem_UnfollowNotification` @@ -425,10 +1144,40 @@ abi.encodePacked(address follower) | **Solidity constant:** | `_TYPEID_LSP26_UNFOLLOW` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP26FollowerSystem_UnfollowNotification` | -**Data encoding:** +**Data encoding and decoding:** + +> **Note:** LSP26 uses `abi.encodePacked` (not `abi.encode`), so the data is 20 bytes (the raw address) rather than 32 bytes (ABI-padded). + + + ```solidity -abi.encodePacked(address unfollower) +// Encoding (inside the LSP26 contract): +bytes memory encodedData = abi.encodePacked(address unfollower); + +// Decoding (inside a Universal Receiver Delegate): +address unfollower = address(bytes20(data)); ``` -> **Note:** LSP26 uses `abi.encodePacked` (not `abi.encode`), so the data is 20 bytes (the raw address) rather than 32 bytes (ABI-padded). + + + +```js +import { dataSlice, getAddress } from 'ethers'; + +// data is 20 bytes (not ABI-padded) +const unfollower = getAddress(dataSlice(data, 0, 20)); +``` + + + + +```js +import { getAddress, slice } from 'viem'; + +// data is 20 bytes (not ABI-padded) +const unfollower = getAddress(slice(data, 0, 20)); +``` + + + From 6dc9c606e89eb9d462634dfa568aef2c0fde35eb Mon Sep 17 00:00:00 2001 From: emmet-bot Date: Mon, 16 Mar 2026 13:29:46 +0100 Subject: [PATCH 04/10] refactor: Address Jean's second round of review comments - Remove 'Standard' column from TOC, rename to 'Notification Type' with brief descriptions (e.g., 'When receiving LSP7 tokens') - Add 'TypeId value' column with word + hex in TOC, all anchor-linked - Move note text under respective tabs (JS note under ethers/viem, Solidity note under Solidity tab) - Add recommendation to import from package in Solidity tab - Remove standalone note block and 'See repository' line - Solidity tab moved to last position in all tab groups - Data sections now show ONLY decoding (not encoding) - All decoding sections wrapped in green :::success collapsible ('How to decode notification data?') --- docs/contracts/type-ids.md | 616 ++++++++++++++++--------------------- 1 file changed, 267 insertions(+), 349 deletions(-) diff --git a/docs/contracts/type-ids.md b/docs/contracts/type-ids.md index 676f1f0673..30ca9cffc5 100644 --- a/docs/contracts/type-ids.md +++ b/docs/contracts/type-ids.md @@ -20,51 +20,35 @@ For instance: ## Notification Type IDs list -| Standard | Type ID Name | Link | -| -------- | ------------------------------------------------- | ----------------------------------------------------- | -| LSP0 | `LSP0ValueReceived` | [↓](#lsp0valuereceived) | -| LSP0 | `LSP0OwnershipTransferStarted` | [↓](#lsp0ownershiptransferstarted) | -| LSP0 | `LSP0OwnershipTransferred_SenderNotification` | [↓](#lsp0ownershiptransferred_sendernotification) | -| LSP0 | `LSP0OwnershipTransferred_RecipientNotification` | [↓](#lsp0ownershiptransferred_recipientnotification) | -| LSP7 | `LSP7Tokens_SenderNotification` | [↓](#lsp7tokens_sendernotification) | -| LSP7 | `LSP7Tokens_RecipientNotification` | [↓](#lsp7tokens_recipientnotification) | -| LSP7 | `LSP7Tokens_OperatorNotification` | [↓](#lsp7tokens_operatornotification) | -| LSP8 | `LSP8Tokens_SenderNotification` | [↓](#lsp8tokens_sendernotification) | -| LSP8 | `LSP8Tokens_RecipientNotification` | [↓](#lsp8tokens_recipientnotification) | -| LSP8 | `LSP8Tokens_OperatorNotification` | [↓](#lsp8tokens_operatornotification) | -| LSP9 | `LSP9ValueReceived` | [↓](#lsp9valuereceived) | -| LSP9 | `LSP9OwnershipTransferStarted` | [↓](#lsp9ownershiptransferstarted) | -| LSP9 | `LSP9OwnershipTransferred_SenderNotification` | [↓](#lsp9ownershiptransferred_sendernotification) | -| LSP9 | `LSP9OwnershipTransferred_RecipientNotification` | [↓](#lsp9ownershiptransferred_recipientnotification) | -| LSP14 | `LSP14OwnershipTransferStarted` | [↓](#lsp14ownershiptransferstarted) | -| LSP14 | `LSP14OwnershipTransferred_SenderNotification` | [↓](#lsp14ownershiptransferred_sendernotification) | -| LSP14 | `LSP14OwnershipTransferred_RecipientNotification` | [↓](#lsp14ownershiptransferred_recipientnotification) | -| LSP26 | `LSP26FollowerSystem_FollowNotification` | [↓](#lsp26followersystem_follownotification) | -| LSP26 | `LSP26FollowerSystem_UnfollowNotification` | [↓](#lsp26followersystem_unfollownotification) | +| Notification Type | TypeId value | Details | +| --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | +| When receiving native LYX (ERC725Account) | [`LSP0ValueReceived`](#lsp0valuereceived) ➡ `0x9c4705229491d365fb5434052e12a386d6771d976bea61070a8c694e8affea3d` | [↓](#lsp0valuereceived) | +| When ownership transfer starts (ERC725Account) | [`LSP0OwnershipTransferStarted`](#lsp0ownershiptransferstarted) ➡ `0xe17117c9d2665d1dbeb479ed8058bbebde3c50ac50e2e65619f60006caac6926` | [↓](#lsp0ownershiptransferstarted) | +| When previous owner is notified of ownership transfer (ERC725Account) | [`LSP0OwnershipTransferred_SenderNotification`](#lsp0ownershiptransferred_sendernotification) ➡ `0xa4e59c931d14f7c8a7a35027f92ee40b5f2886b9fdcdb78f30bc5ecce5a2f814` | [↓](#lsp0ownershiptransferred_sendernotification) | +| When new owner is notified of ownership transfer (ERC725Account) | [`LSP0OwnershipTransferred_RecipientNotification`](#lsp0ownershiptransferred_recipientnotification) ➡ `0xceca317f109c43507871523e82dc2a3cc64dfa18f12da0b6db14f6e23f995538` | [↓](#lsp0ownershiptransferred_recipientnotification) | +| When sending LSP7 tokens | [`LSP7Tokens_SenderNotification`](#lsp7tokens_sendernotification) ➡ `0x429ac7a06903dbc9c13dfcb3c9d11df8194581fa047c96d7a4171fc7402958ea` | [↓](#lsp7tokens_sendernotification) | +| When receiving LSP7 tokens | [`LSP7Tokens_RecipientNotification`](#lsp7tokens_recipientnotification) ➡ `0x20804611b3e2ea21c480dc465142210acf4a2485947541770ec1fb87dee4a55c` | [↓](#lsp7tokens_recipientnotification) | +| When an LSP7 operator is authorized or revoked | [`LSP7Tokens_OperatorNotification`](#lsp7tokens_operatornotification) ➡ `0x386072cc5a58e61263b434c722725f21031cd06e7c552cfaa06db5de8a320dbc` | [↓](#lsp7tokens_operatornotification) | +| When sending an LSP8 NFT | [`LSP8Tokens_SenderNotification`](#lsp8tokens_sendernotification) ➡ `0xb23eae7e6d1564b295b4c3e3be402d9a2f0776c57bdf365903496f6fa481ab00` | [↓](#lsp8tokens_sendernotification) | +| When receiving an LSP8 NFT | [`LSP8Tokens_RecipientNotification`](#lsp8tokens_recipientnotification) ➡ `0x0b084a55ebf70fd3c06fd755269dac2212c4d3f0f4d09079780bfa50c1b2984d` | [↓](#lsp8tokens_recipientnotification) | +| When an LSP8 operator is authorized or revoked | [`LSP8Tokens_OperatorNotification`](#lsp8tokens_operatornotification) ➡ `0x8a1c15a8799f71b547e08e2bcb2e85257e81b0a07eee2ce6712549eef1f00970` | [↓](#lsp8tokens_operatornotification) | +| When receiving native LYX (Vault) | [`LSP9ValueReceived`](#lsp9valuereceived) ➡ `0x468cd1581d7bc001c3b685513d2b929b55437be34700410383d58f3aa1ea0abc` | [↓](#lsp9valuereceived) | +| When ownership transfer starts (Vault) | [`LSP9OwnershipTransferStarted`](#lsp9ownershiptransferstarted) ➡ `0xaefd43f45fed1bcd8992f23c803b6f4ec45cf6b62b0d404d565f290a471e763f` | [↓](#lsp9ownershiptransferstarted) | +| When previous owner is notified of Vault ownership transfer | [`LSP9OwnershipTransferred_SenderNotification`](#lsp9ownershiptransferred_sendernotification) ➡ `0x0c622e58e6b7089ae35f1af1c86d997be92fcdd8c9509652022d41aa65169471` | [↓](#lsp9ownershiptransferred_sendernotification) | +| When new owner is notified of Vault ownership transfer | [`LSP9OwnershipTransferred_RecipientNotification`](#lsp9ownershiptransferred_recipientnotification) ➡ `0x79855c97dbc259ce395421d933d7bc0699b0f1561f988f09a9e8633fd542fe5c` | [↓](#lsp9ownershiptransferred_recipientnotification) | +| When ownership transfer starts (Ownable2Step) | [`LSP14OwnershipTransferStarted`](#lsp14ownershiptransferstarted) ➡ `0xee9a7c0924f740a2ca33d59b7f0c2929821ea9837ce043ce91c1823e9c4e52c0` | [↓](#lsp14ownershiptransferstarted) | +| When previous owner is notified of Ownable2Step transfer | [`LSP14OwnershipTransferred_SenderNotification`](#lsp14ownershiptransferred_sendernotification) ➡ `0xa124442e1cc7b52d8e2ede2787d43527dc1f3ae0de87f50dd03e27a71834f74c` | [↓](#lsp14ownershiptransferred_sendernotification) | +| When new owner is notified of Ownable2Step transfer | [`LSP14OwnershipTransferred_RecipientNotification`](#lsp14ownershiptransferred_recipientnotification) ➡ `0xe32c7debcb817925ba4883fdbfc52797187f28f73f860641dab1a68d9b32902c` | [↓](#lsp14ownershiptransferred_recipientnotification) | +| When someone follows you | [`LSP26FollowerSystem_FollowNotification`](#lsp26followersystem_follownotification) ➡ `0x71e02f9f05bcd5816ec4f3134aa2e5a916669537ec6c77fe66ea595fabc2d51a` | [↓](#lsp26followersystem_follownotification) | +| When someone unfollows you | [`LSP26FollowerSystem_UnfollowNotification`](#lsp26followersystem_unfollownotification) ➡ `0x9d3c0b4012b69658977b099bdaa51eff0f0460f421fba96d15669506c00d1c4f` | [↓](#lsp26followersystem_unfollownotification) | ## Using Type ID - - -```solidity -import { _TYPEID_LSP7_TOKENSSENDER } from "@lukso/lsp7-contracts/contracts/LSP7Constants.sol"; - -function universalReceiverDelegate( - address sender, - uint256 value, - bytes32 typeId, - bytes memory data -) external returns (bytes memory) { - if (typeId == _TYPEID_LSP7_TOKENSSENDER) { - // handle LSP7 token sent notification - } -} -``` - - +The JavaScript constants are exported from the [`@lukso/lsp-smart-contracts`](https://github.com/lukso-network/lsp-smart-contracts) package. + ```js import { LSP1_TYPE_IDS } from '@lukso/lsp-smart-contracts'; @@ -81,19 +65,37 @@ LSP1_TYPE_IDS.LSP26FollowerSystem_FollowNotification; +The JavaScript constants are exported from the [`@lukso/lsp-smart-contracts`](https://github.com/lukso-network/lsp-smart-contracts) package. + ```js import { LSP1_TYPE_IDS } from '@lukso/lsp-smart-contracts'; -// The constants are the same — they are plain bytes32 hex strings +// The constants are plain bytes32 hex strings LSP1_TYPE_IDS.LSP7Tokens_RecipientNotification; ``` - + + +The Solidity constants are defined in each LSP's contract constants file (e.g., `LSP7Constants.sol`, `LSP26Constants.sol`). It is recommended to import them from the [`@lukso/lsp-smart-contracts`](https://github.com/lukso-network/lsp-smart-contracts) package to ensure the correct Type IDs are used. -> **Note:** The JavaScript constants are exported from the `@lukso/lsp-smart-contracts` package. The corresponding Solidity constants are defined in each LSP's contract constants file (e.g., `LSP7Constants.sol`, `LSP26Constants.sol`). -> -> See the [lsp-smart-contracts repository](https://github.com/lukso-network/lsp-smart-contracts) for the full source code. +```solidity +import { _TYPEID_LSP7_TOKENSSENDER } from "@lukso/lsp7-contracts/contracts/LSP7Constants.sol"; + +function universalReceiverDelegate( + address sender, + uint256 value, + bytes32 typeId, + bytes memory data +) external returns (bytes memory) { + if (typeId == _TYPEID_LSP7_TOKENSSENDER) { + // handle LSP7 token sent notification + } +} +``` + + +
How Type IDs are generated @@ -107,13 +109,6 @@ keccak256("LSP7Tokens_SenderNotification") = 0x429ac7a06903dbc9c13dfcb3c9d11df81 You can verify any Type ID by hashing its name: - - -```solidity -bytes32 typeId = keccak256("LSP7Tokens_SenderNotification"); -``` - - ```js @@ -127,6 +122,13 @@ const typeId = keccak256(toUtf8Bytes('LSP7Tokens_SenderNotification')); ```js import { keccak256, toHex } from 'viem'; const typeId = keccak256(toHex('LSP7Tokens_SenderNotification')); +``` + + + + +```solidity +bytes32 typeId = keccak256("LSP7Tokens_SenderNotification"); ``` @@ -149,7 +151,7 @@ const typeId = keccak256(toHex('LSP7Tokens_SenderNotification')); | **Solidity constant:** | `_TYPEID_LSP0_VALUE_RECEIVED` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP0ValueReceived` | -**Data encoding:** Empty bytes (`""`) — no additional data is sent with this notification. +No additional data is sent with this notification (empty bytes `""`). ### `LSP0OwnershipTransferStarted` @@ -162,20 +164,9 @@ const typeId = keccak256(toHex('LSP7Tokens_SenderNotification')); | **Solidity constant:** | `_TYPEID_LSP0_OwnershipTransferStarted` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP0OwnershipTransferStarted` | -**Data encoding and decoding:** +:::success How to decode notification data? - - -```solidity -// Encoding (inside the contract): -bytes memory encodedData = abi.encode(address currentOwner, address pendingNewOwner); - -// Decoding (inside a Universal Receiver Delegate): -(address currentOwner, address pendingNewOwner) = abi.decode(data, (address, address)); -``` - - ```js @@ -198,11 +189,20 @@ const [currentOwner, pendingNewOwner] = decodeAbiParameters( [{ type: 'address' }, { type: 'address' }], data, ); +``` + + + + +```solidity +(address currentOwner, address pendingNewOwner) = abi.decode(data, (address, address)); ``` +::: + ### `LSP0OwnershipTransferred_SenderNotification` | | | @@ -214,23 +214,9 @@ const [currentOwner, pendingNewOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP0_OwnershipTransferred_SenderNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP0OwnershipTransferred_SenderNotification` | -**Data encoding and decoding:** +:::success How to decode notification data? - - -```solidity -// Encoding (inside the contract): -// On acceptOwnership(): -bytes memory encodedData = abi.encode(address previousOwner, address newOwner); -// On renounceOwnership(): -bytes memory encodedData = abi.encode(address previousOwner, address(0)); - -// Decoding (inside a Universal Receiver Delegate): -(address previousOwner, address newOwner) = abi.decode(data, (address, address)); -``` - - ```js @@ -252,11 +238,21 @@ const [previousOwner, newOwner] = decodeAbiParameters( data, ); // newOwner is address(0) on renounceOwnership +``` + + + + +```solidity +(address previousOwner, address newOwner) = abi.decode(data, (address, address)); +// newOwner is address(0) on renounceOwnership ``` +::: + ### `LSP0OwnershipTransferred_RecipientNotification` | | | @@ -268,20 +264,9 @@ const [previousOwner, newOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP0_OwnershipTransferred_RecipientNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP0OwnershipTransferred_RecipientNotification` | -**Data encoding and decoding:** +:::success How to decode notification data? - - -```solidity -// Encoding: -bytes memory encodedData = abi.encode(address previousOwner, address newOwner); - -// Decoding: -(address previousOwner, address newOwner) = abi.decode(data, (address, address)); -``` - - ```js @@ -301,11 +286,20 @@ const [previousOwner, newOwner] = decodeAbiParameters( [{ type: 'address' }, { type: 'address' }], data, ); +``` + + + + +```solidity +(address previousOwner, address newOwner) = abi.decode(data, (address, address)); ``` +::: + --- ## LSP7 - Digital Asset @@ -321,32 +315,9 @@ const [previousOwner, newOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP7_TOKENSSENDER` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP7Tokens_SenderNotification` | -**Data encoding and decoding:** +:::success How to decode notification data? - - -```solidity -// Encoding (inside the contract): -bytes memory encodedData = abi.encode( - address operator, - address from, - address to, // address(0) when burning - uint256 amount, - bytes memory data -); - -// Decoding (inside a Universal Receiver Delegate): -( - address operator, - address from, - address to, - uint256 amount, - bytes memory transferData -) = abi.decode(data, (address, address, address, uint256, bytes)); -``` - - ```js @@ -377,11 +348,27 @@ const [operator, from, to, amount, transferData] = decodeAbiParameters( data, ); // `to` is address(0) when burning +``` + + + + +```solidity +( + address operator, + address from, + address to, + uint256 amount, + bytes memory transferData +) = abi.decode(data, (address, address, address, uint256, bytes)); +// `to` is address(0) when burning ``` +::: + ### `LSP7Tokens_RecipientNotification` | | | @@ -393,32 +380,9 @@ const [operator, from, to, amount, transferData] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP7_TOKENSRECIPIENT` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP7Tokens_RecipientNotification` | -**Data encoding and decoding:** +:::success How to decode notification data? - - -```solidity -// Encoding (inside the contract): -bytes memory encodedData = abi.encode( - address operator, - address from, // address(0) when minting - address to, - uint256 amount, - bytes memory data -); - -// Decoding (inside a Universal Receiver Delegate): -( - address operator, - address from, - address to, - uint256 amount, - bytes memory transferData -) = abi.decode(data, (address, address, address, uint256, bytes)); -``` - - ```js @@ -449,11 +413,27 @@ const [operator, from, to, amount, transferData] = decodeAbiParameters( data, ); // `from` is address(0) when minting +``` + + + + +```solidity +( + address operator, + address from, + address to, + uint256 amount, + bytes memory transferData +) = abi.decode(data, (address, address, address, uint256, bytes)); +// `from` is address(0) when minting ``` +::: + ### `LSP7Tokens_OperatorNotification` | | | @@ -465,36 +445,9 @@ const [operator, from, to, amount, transferData] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP7_TOKENOPERATOR` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP7Tokens_OperatorNotification` | -**Data encoding and decoding:** +:::success How to decode notification data? - - -```solidity -// Encoding (inside the contract): -// On authorizeOperator / increaseAllowance / decreaseAllowance: -bytes memory encodedData = abi.encode( - address tokenOwner, - uint256 allowance, - bytes memory operatorNotificationData -); - -// On revokeOperator (allowance is always 0): -bytes memory encodedData = abi.encode( - address tokenOwner, - uint256 allowance, // 0 - bytes memory operatorNotificationData -); - -// Decoding (inside a Universal Receiver Delegate): -( - address tokenOwner, - uint256 allowance, - bytes memory operatorNotificationData -) = abi.decode(data, (address, uint256, bytes)); -``` - - ```js @@ -519,11 +472,25 @@ const [tokenOwner, allowance, operatorNotificationData] = decodeAbiParameters( data, ); // allowance is 0 on revokeOperator +``` + + + + +```solidity +( + address tokenOwner, + uint256 allowance, + bytes memory operatorNotificationData +) = abi.decode(data, (address, uint256, bytes)); +// allowance is 0 on revokeOperator ``` +::: + --- ## LSP8 - Identifiable Digital Asset @@ -539,32 +506,9 @@ const [tokenOwner, allowance, operatorNotificationData] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP8_TOKENSSENDER` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP8Tokens_SenderNotification` | -**Data encoding and decoding:** +:::success How to decode notification data? - - -```solidity -// Encoding (inside the contract): -bytes memory encodedData = abi.encode( - address operator, - address from, - address to, // address(0) when burning - bytes32 tokenId, - bytes memory data -); - -// Decoding (inside a Universal Receiver Delegate): -( - address operator, - address from, - address to, - bytes32 tokenId, - bytes memory transferData -) = abi.decode(data, (address, address, address, bytes32, bytes)); -``` - - ```js @@ -595,11 +539,27 @@ const [operator, from, to, tokenId, transferData] = decodeAbiParameters( data, ); // `to` is address(0) when burning +``` + + + + +```solidity +( + address operator, + address from, + address to, + bytes32 tokenId, + bytes memory transferData +) = abi.decode(data, (address, address, address, bytes32, bytes)); +// `to` is address(0) when burning ``` +::: + ### `LSP8Tokens_RecipientNotification` | | | @@ -611,32 +571,9 @@ const [operator, from, to, tokenId, transferData] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP8_TOKENSRECIPIENT` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP8Tokens_RecipientNotification` | -**Data encoding and decoding:** +:::success How to decode notification data? - - -```solidity -// Encoding (inside the contract): -bytes memory encodedData = abi.encode( - address operator, - address from, // address(0) when minting - address to, - bytes32 tokenId, - bytes memory data -); - -// Decoding (inside a Universal Receiver Delegate): -( - address operator, - address from, - address to, - bytes32 tokenId, - bytes memory transferData -) = abi.decode(data, (address, address, address, bytes32, bytes)); -``` - - ```js @@ -667,11 +604,27 @@ const [operator, from, to, tokenId, transferData] = decodeAbiParameters( data, ); // `from` is address(0) when minting +``` + + + + +```solidity +( + address operator, + address from, + address to, + bytes32 tokenId, + bytes memory transferData +) = abi.decode(data, (address, address, address, bytes32, bytes)); +// `from` is address(0) when minting ``` +::: + ### `LSP8Tokens_OperatorNotification` | | | @@ -683,39 +636,9 @@ const [operator, from, to, tokenId, transferData] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP8_TOKENOPERATOR` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP8Tokens_OperatorNotification` | -**Data encoding and decoding:** +:::success How to decode notification data? - - -```solidity -// Encoding (inside the contract): -// On authorizeOperator (authorized = true): -bytes memory encodedData = abi.encode( - address tokenOwner, - bytes32 tokenId, - bool authorized, // true - bytes memory operatorNotificationData -); - -// On revokeOperator (authorized = false): -bytes memory encodedData = abi.encode( - address tokenOwner, - bytes32 tokenId, - bool authorized, // false - bytes memory operatorNotificationData -); - -// Decoding (inside a Universal Receiver Delegate): -( - address tokenOwner, - bytes32 tokenId, - bool authorized, - bytes memory operatorNotificationData -) = abi.decode(data, (address, bytes32, bool, bytes)); -``` - - ```js @@ -744,11 +667,26 @@ const [tokenOwner, tokenId, authorized, operatorNotificationData] = data, ); // authorized = true on authorizeOperator, false on revokeOperator +``` + + + + +```solidity +( + address tokenOwner, + bytes32 tokenId, + bool authorized, + bytes memory operatorNotificationData +) = abi.decode(data, (address, bytes32, bool, bytes)); +// authorized = true on authorizeOperator, false on revokeOperator ``` +::: + --- ## LSP9 - Vault @@ -764,7 +702,7 @@ const [tokenOwner, tokenId, authorized, operatorNotificationData] = | **Solidity constant:** | `_TYPEID_LSP9_VALUE_RECEIVED` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP9ValueReceived` | -**Data encoding:** Empty bytes (`""`) — no additional data is sent with this notification. +No additional data is sent with this notification (empty bytes `""`). ### `LSP9OwnershipTransferStarted` @@ -777,20 +715,9 @@ const [tokenOwner, tokenId, authorized, operatorNotificationData] = | **Solidity constant:** | `_TYPEID_LSP9_OwnershipTransferStarted` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP9OwnershipTransferStarted` | -**Data encoding and decoding:** +:::success How to decode notification data? - - -```solidity -// Encoding: -bytes memory encodedData = abi.encode(address currentOwner, address pendingNewOwner); - -// Decoding: -(address currentOwner, address pendingNewOwner) = abi.decode(data, (address, address)); -``` - - ```js @@ -813,11 +740,20 @@ const [currentOwner, pendingNewOwner] = decodeAbiParameters( [{ type: 'address' }, { type: 'address' }], data, ); +``` + + + + +```solidity +(address currentOwner, address pendingNewOwner) = abi.decode(data, (address, address)); ``` +::: + ### `LSP9OwnershipTransferred_SenderNotification` | | | @@ -829,23 +765,9 @@ const [currentOwner, pendingNewOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP9_OwnershipTransferred_SenderNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP9OwnershipTransferred_SenderNotification` | -**Data encoding and decoding:** +:::success How to decode notification data? - - -```solidity -// Encoding: -// On acceptOwnership(): -bytes memory encodedData = abi.encode(address previousOwner, address newOwner); -// On renounceOwnership(): -bytes memory encodedData = abi.encode(address previousOwner, address(0)); - -// Decoding: -(address previousOwner, address newOwner) = abi.decode(data, (address, address)); -``` - - ```js @@ -867,11 +789,21 @@ const [previousOwner, newOwner] = decodeAbiParameters( data, ); // newOwner is address(0) on renounceOwnership +``` + + + + +```solidity +(address previousOwner, address newOwner) = abi.decode(data, (address, address)); +// newOwner is address(0) on renounceOwnership ``` +::: + ### `LSP9OwnershipTransferred_RecipientNotification` | | | @@ -883,20 +815,9 @@ const [previousOwner, newOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP9_OwnershipTransferred_RecipientNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP9OwnershipTransferred_RecipientNotification` | -**Data encoding and decoding:** +:::success How to decode notification data? - - -```solidity -// Encoding: -bytes memory encodedData = abi.encode(address previousOwner, address newOwner); - -// Decoding: -(address previousOwner, address newOwner) = abi.decode(data, (address, address)); -``` - - ```js @@ -916,11 +837,20 @@ const [previousOwner, newOwner] = decodeAbiParameters( [{ type: 'address' }, { type: 'address' }], data, ); +``` + + + + +```solidity +(address previousOwner, address newOwner) = abi.decode(data, (address, address)); ``` +::: + --- ## LSP14 - Ownable 2-Step @@ -936,20 +866,9 @@ const [previousOwner, newOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP14_OwnershipTransferStarted` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP14OwnershipTransferStarted` | -**Data encoding and decoding:** +:::success How to decode notification data? - - -```solidity -// Encoding: -bytes memory encodedData = abi.encode(address currentOwner, address pendingNewOwner); - -// Decoding: -(address currentOwner, address pendingNewOwner) = abi.decode(data, (address, address)); -``` - - ```js @@ -972,11 +891,20 @@ const [currentOwner, pendingNewOwner] = decodeAbiParameters( [{ type: 'address' }, { type: 'address' }], data, ); +``` + + + + +```solidity +(address currentOwner, address pendingNewOwner) = abi.decode(data, (address, address)); ``` +::: + #### `LSP14OwnershipTransferred_SenderNotification` | | | @@ -988,23 +916,9 @@ const [currentOwner, pendingNewOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP14_OwnershipTransferred_SenderNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP14OwnershipTransferred_SenderNotification` | -**Data encoding and decoding:** +:::success How to decode notification data? - - -```solidity -// Encoding: -// On acceptOwnership(): -bytes memory encodedData = abi.encode(address previousOwner, address newOwner); -// On renounceOwnership(): -bytes memory encodedData = abi.encode(address previousOwner, address(0)); - -// Decoding: -(address previousOwner, address newOwner) = abi.decode(data, (address, address)); -``` - - ```js @@ -1026,11 +940,21 @@ const [previousOwner, newOwner] = decodeAbiParameters( data, ); // newOwner is address(0) on renounceOwnership +``` + + + + +```solidity +(address previousOwner, address newOwner) = abi.decode(data, (address, address)); +// newOwner is address(0) on renounceOwnership ``` +::: + #### `LSP14OwnershipTransferred_RecipientNotification` | | | @@ -1042,20 +966,9 @@ const [previousOwner, newOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP14_OwnershipTransferred_RecipientNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP14OwnershipTransferred_RecipientNotification` | -**Data encoding and decoding:** +:::success How to decode notification data? - - -```solidity -// Encoding: -bytes memory encodedData = abi.encode(address previousOwner, address newOwner); - -// Decoding: -(address previousOwner, address newOwner) = abi.decode(data, (address, address)); -``` - - ```js @@ -1075,11 +988,20 @@ const [previousOwner, newOwner] = decodeAbiParameters( [{ type: 'address' }, { type: 'address' }], data, ); +``` + + + + +```solidity +(address previousOwner, address newOwner) = abi.decode(data, (address, address)); ``` +::: + --- ## LSP26 - Follower System @@ -1095,22 +1017,11 @@ const [previousOwner, newOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP26_FOLLOW` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP26FollowerSystem_FollowNotification` | -**Data encoding and decoding:** +:::success How to decode notification data? > **Note:** LSP26 uses `abi.encodePacked` (not `abi.encode`), so the data is 20 bytes (the raw address) rather than 32 bytes (ABI-padded). - - -```solidity -// Encoding (inside the LSP26 contract): -bytes memory encodedData = abi.encodePacked(address follower); - -// Decoding (inside a Universal Receiver Delegate): -address follower = address(bytes20(data)); -``` - - ```js @@ -1128,11 +1039,20 @@ import { getAddress, slice } from 'viem'; // data is 20 bytes (not ABI-padded) const follower = getAddress(slice(data, 0, 20)); +``` + + + + +```solidity +address follower = address(bytes20(data)); ``` +::: + ### `LSP26FollowerSystem_UnfollowNotification` | | | @@ -1144,22 +1064,11 @@ const follower = getAddress(slice(data, 0, 20)); | **Solidity constant:** | `_TYPEID_LSP26_UNFOLLOW` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP26FollowerSystem_UnfollowNotification` | -**Data encoding and decoding:** +:::success How to decode notification data? > **Note:** LSP26 uses `abi.encodePacked` (not `abi.encode`), so the data is 20 bytes (the raw address) rather than 32 bytes (ABI-padded). - - -```solidity -// Encoding (inside the LSP26 contract): -bytes memory encodedData = abi.encodePacked(address unfollower); - -// Decoding (inside a Universal Receiver Delegate): -address unfollower = address(bytes20(data)); -``` - - ```js @@ -1177,7 +1086,16 @@ import { getAddress, slice } from 'viem'; // data is 20 bytes (not ABI-padded) const unfollower = getAddress(slice(data, 0, 20)); +``` + + + + +```solidity +address unfollower = address(bytes20(data)); ``` + +::: From ecd942015d0f4716d6de2135252a098b02ab31bc Mon Sep 17 00:00:00 2001 From: emmet-bot Date: Mon, 16 Mar 2026 13:40:16 +0100 Subject: [PATCH 05/10] docs: Add orientation paragraph and See also section - Replace bullet examples with LSP1 Delegate explanation paragraph covering use cases: auto-register assets, auto-swap, tip followers, split tokens, subscriber lists for airdrops - Add 'See also' section linking to LSP1 Delegate, LSP1 standard, and lsp-smart-contracts repo --- docs/contracts/type-ids.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/docs/contracts/type-ids.md b/docs/contracts/type-ids.md index 30ca9cffc5..54cade7b58 100644 --- a/docs/contracts/type-ids.md +++ b/docs/contracts/type-ids.md @@ -12,11 +12,14 @@ The **LSP1 Type IDs** listed below are unique identifiers used across the LSP st These Type IDs are sent as the `typeId` parameter when calling the `universalReceiver(bytes32 typeId, bytes data)` function on contracts implementing [LSP1](../standards/accounts/lsp1-universal-receiver.md). They allow contracts to identify what type of notification they are receiving and react accordingly. -For instance: +When a Universal Profile receives a notification, its Universal Receiver function ([LSP1](../standards/accounts/lsp1-universal-receiver.md)) is called with a `typeId` and `data`. A connected [LSP1 Delegate](../standards/accounts/lsp1-universal-receiver-delegate.md) inspects the `typeId` to decide how to react. For example: -- Notify a sender that LSP7 tokens are being transferred from their balance -- Notify a recipient about receiving LSP7 tokens -- Notify a profile that they have a new follower +- Auto-register a received token / NFT in your list of received assets +- Swap automatically a token received +- Send a tip or an NFT to a new follower +- Auto-split received LYX / LSP7 tokens between collaborators +- Save a new follower to a subscriber list for future airdrops (NFT music tracks, vouchers, newsletter, etc...) +- Any customisation you might want ## Notification Type IDs list @@ -1099,3 +1102,11 @@ address unfollower = address(bytes20(data)); ::: + +--- + +## See also + +- [Build a Universal Receiver Delegate](../standards/accounts/lsp1-universal-receiver-delegate.md) +- [LSP1 Universal Receiver standard](../standards/accounts/lsp1-universal-receiver.md) +- [lsp-smart-contracts constants reference](https://github.com/lukso-network/lsp-smart-contracts) From ad4467e367b9cc8bc4ca8a304f2b193665a67d18 Mon Sep 17 00:00:00 2001 From: emmet-bot Date: Mon, 16 Mar 2026 13:49:30 +0100 Subject: [PATCH 06/10] fix: Add br tag before arrow in TOC table for readability Arrow emoji now on its own line before the bytes32 hex value using
for cleaner visual separation in the Notification Type IDs table. --- docs/contracts/type-ids.md | 42 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/docs/contracts/type-ids.md b/docs/contracts/type-ids.md index 54cade7b58..cc5b3652db 100644 --- a/docs/contracts/type-ids.md +++ b/docs/contracts/type-ids.md @@ -23,27 +23,27 @@ When a Universal Profile receives a notification, its Universal Receiver functio ## Notification Type IDs list -| Notification Type | TypeId value | Details | -| --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | -| When receiving native LYX (ERC725Account) | [`LSP0ValueReceived`](#lsp0valuereceived) ➡ `0x9c4705229491d365fb5434052e12a386d6771d976bea61070a8c694e8affea3d` | [↓](#lsp0valuereceived) | -| When ownership transfer starts (ERC725Account) | [`LSP0OwnershipTransferStarted`](#lsp0ownershiptransferstarted) ➡ `0xe17117c9d2665d1dbeb479ed8058bbebde3c50ac50e2e65619f60006caac6926` | [↓](#lsp0ownershiptransferstarted) | -| When previous owner is notified of ownership transfer (ERC725Account) | [`LSP0OwnershipTransferred_SenderNotification`](#lsp0ownershiptransferred_sendernotification) ➡ `0xa4e59c931d14f7c8a7a35027f92ee40b5f2886b9fdcdb78f30bc5ecce5a2f814` | [↓](#lsp0ownershiptransferred_sendernotification) | -| When new owner is notified of ownership transfer (ERC725Account) | [`LSP0OwnershipTransferred_RecipientNotification`](#lsp0ownershiptransferred_recipientnotification) ➡ `0xceca317f109c43507871523e82dc2a3cc64dfa18f12da0b6db14f6e23f995538` | [↓](#lsp0ownershiptransferred_recipientnotification) | -| When sending LSP7 tokens | [`LSP7Tokens_SenderNotification`](#lsp7tokens_sendernotification) ➡ `0x429ac7a06903dbc9c13dfcb3c9d11df8194581fa047c96d7a4171fc7402958ea` | [↓](#lsp7tokens_sendernotification) | -| When receiving LSP7 tokens | [`LSP7Tokens_RecipientNotification`](#lsp7tokens_recipientnotification) ➡ `0x20804611b3e2ea21c480dc465142210acf4a2485947541770ec1fb87dee4a55c` | [↓](#lsp7tokens_recipientnotification) | -| When an LSP7 operator is authorized or revoked | [`LSP7Tokens_OperatorNotification`](#lsp7tokens_operatornotification) ➡ `0x386072cc5a58e61263b434c722725f21031cd06e7c552cfaa06db5de8a320dbc` | [↓](#lsp7tokens_operatornotification) | -| When sending an LSP8 NFT | [`LSP8Tokens_SenderNotification`](#lsp8tokens_sendernotification) ➡ `0xb23eae7e6d1564b295b4c3e3be402d9a2f0776c57bdf365903496f6fa481ab00` | [↓](#lsp8tokens_sendernotification) | -| When receiving an LSP8 NFT | [`LSP8Tokens_RecipientNotification`](#lsp8tokens_recipientnotification) ➡ `0x0b084a55ebf70fd3c06fd755269dac2212c4d3f0f4d09079780bfa50c1b2984d` | [↓](#lsp8tokens_recipientnotification) | -| When an LSP8 operator is authorized or revoked | [`LSP8Tokens_OperatorNotification`](#lsp8tokens_operatornotification) ➡ `0x8a1c15a8799f71b547e08e2bcb2e85257e81b0a07eee2ce6712549eef1f00970` | [↓](#lsp8tokens_operatornotification) | -| When receiving native LYX (Vault) | [`LSP9ValueReceived`](#lsp9valuereceived) ➡ `0x468cd1581d7bc001c3b685513d2b929b55437be34700410383d58f3aa1ea0abc` | [↓](#lsp9valuereceived) | -| When ownership transfer starts (Vault) | [`LSP9OwnershipTransferStarted`](#lsp9ownershiptransferstarted) ➡ `0xaefd43f45fed1bcd8992f23c803b6f4ec45cf6b62b0d404d565f290a471e763f` | [↓](#lsp9ownershiptransferstarted) | -| When previous owner is notified of Vault ownership transfer | [`LSP9OwnershipTransferred_SenderNotification`](#lsp9ownershiptransferred_sendernotification) ➡ `0x0c622e58e6b7089ae35f1af1c86d997be92fcdd8c9509652022d41aa65169471` | [↓](#lsp9ownershiptransferred_sendernotification) | -| When new owner is notified of Vault ownership transfer | [`LSP9OwnershipTransferred_RecipientNotification`](#lsp9ownershiptransferred_recipientnotification) ➡ `0x79855c97dbc259ce395421d933d7bc0699b0f1561f988f09a9e8633fd542fe5c` | [↓](#lsp9ownershiptransferred_recipientnotification) | -| When ownership transfer starts (Ownable2Step) | [`LSP14OwnershipTransferStarted`](#lsp14ownershiptransferstarted) ➡ `0xee9a7c0924f740a2ca33d59b7f0c2929821ea9837ce043ce91c1823e9c4e52c0` | [↓](#lsp14ownershiptransferstarted) | -| When previous owner is notified of Ownable2Step transfer | [`LSP14OwnershipTransferred_SenderNotification`](#lsp14ownershiptransferred_sendernotification) ➡ `0xa124442e1cc7b52d8e2ede2787d43527dc1f3ae0de87f50dd03e27a71834f74c` | [↓](#lsp14ownershiptransferred_sendernotification) | -| When new owner is notified of Ownable2Step transfer | [`LSP14OwnershipTransferred_RecipientNotification`](#lsp14ownershiptransferred_recipientnotification) ➡ `0xe32c7debcb817925ba4883fdbfc52797187f28f73f860641dab1a68d9b32902c` | [↓](#lsp14ownershiptransferred_recipientnotification) | -| When someone follows you | [`LSP26FollowerSystem_FollowNotification`](#lsp26followersystem_follownotification) ➡ `0x71e02f9f05bcd5816ec4f3134aa2e5a916669537ec6c77fe66ea595fabc2d51a` | [↓](#lsp26followersystem_follownotification) | -| When someone unfollows you | [`LSP26FollowerSystem_UnfollowNotification`](#lsp26followersystem_unfollownotification) ➡ `0x9d3c0b4012b69658977b099bdaa51eff0f0460f421fba96d15669506c00d1c4f` | [↓](#lsp26followersystem_unfollownotification) | +| Notification Type | TypeId value | Details | +| --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | +| When receiving native LYX (ERC725Account) | [`LSP0ValueReceived`](#lsp0valuereceived)
➡ `0x9c4705229491d365fb5434052e12a386d6771d976bea61070a8c694e8affea3d` | [↓](#lsp0valuereceived) | +| When ownership transfer starts (ERC725Account) | [`LSP0OwnershipTransferStarted`](#lsp0ownershiptransferstarted)
➡ `0xe17117c9d2665d1dbeb479ed8058bbebde3c50ac50e2e65619f60006caac6926` | [↓](#lsp0ownershiptransferstarted) | +| When previous owner is notified of ownership transfer (ERC725Account) | [`LSP0OwnershipTransferred_SenderNotification`](#lsp0ownershiptransferred_sendernotification)
➡ `0xa4e59c931d14f7c8a7a35027f92ee40b5f2886b9fdcdb78f30bc5ecce5a2f814` | [↓](#lsp0ownershiptransferred_sendernotification) | +| When new owner is notified of ownership transfer (ERC725Account) | [`LSP0OwnershipTransferred_RecipientNotification`](#lsp0ownershiptransferred_recipientnotification)
➡ `0xceca317f109c43507871523e82dc2a3cc64dfa18f12da0b6db14f6e23f995538` | [↓](#lsp0ownershiptransferred_recipientnotification) | +| When sending LSP7 tokens | [`LSP7Tokens_SenderNotification`](#lsp7tokens_sendernotification)
➡ `0x429ac7a06903dbc9c13dfcb3c9d11df8194581fa047c96d7a4171fc7402958ea` | [↓](#lsp7tokens_sendernotification) | +| When receiving LSP7 tokens | [`LSP7Tokens_RecipientNotification`](#lsp7tokens_recipientnotification)
➡ `0x20804611b3e2ea21c480dc465142210acf4a2485947541770ec1fb87dee4a55c` | [↓](#lsp7tokens_recipientnotification) | +| When an LSP7 operator is authorized or revoked | [`LSP7Tokens_OperatorNotification`](#lsp7tokens_operatornotification)
➡ `0x386072cc5a58e61263b434c722725f21031cd06e7c552cfaa06db5de8a320dbc` | [↓](#lsp7tokens_operatornotification) | +| When sending an LSP8 NFT | [`LSP8Tokens_SenderNotification`](#lsp8tokens_sendernotification)
➡ `0xb23eae7e6d1564b295b4c3e3be402d9a2f0776c57bdf365903496f6fa481ab00` | [↓](#lsp8tokens_sendernotification) | +| When receiving an LSP8 NFT | [`LSP8Tokens_RecipientNotification`](#lsp8tokens_recipientnotification)
➡ `0x0b084a55ebf70fd3c06fd755269dac2212c4d3f0f4d09079780bfa50c1b2984d` | [↓](#lsp8tokens_recipientnotification) | +| When an LSP8 operator is authorized or revoked | [`LSP8Tokens_OperatorNotification`](#lsp8tokens_operatornotification)
➡ `0x8a1c15a8799f71b547e08e2bcb2e85257e81b0a07eee2ce6712549eef1f00970` | [↓](#lsp8tokens_operatornotification) | +| When receiving native LYX (Vault) | [`LSP9ValueReceived`](#lsp9valuereceived)
➡ `0x468cd1581d7bc001c3b685513d2b929b55437be34700410383d58f3aa1ea0abc` | [↓](#lsp9valuereceived) | +| When ownership transfer starts (Vault) | [`LSP9OwnershipTransferStarted`](#lsp9ownershiptransferstarted)
➡ `0xaefd43f45fed1bcd8992f23c803b6f4ec45cf6b62b0d404d565f290a471e763f` | [↓](#lsp9ownershiptransferstarted) | +| When previous owner is notified of Vault ownership transfer | [`LSP9OwnershipTransferred_SenderNotification`](#lsp9ownershiptransferred_sendernotification)
➡ `0x0c622e58e6b7089ae35f1af1c86d997be92fcdd8c9509652022d41aa65169471` | [↓](#lsp9ownershiptransferred_sendernotification) | +| When new owner is notified of Vault ownership transfer | [`LSP9OwnershipTransferred_RecipientNotification`](#lsp9ownershiptransferred_recipientnotification)
➡ `0x79855c97dbc259ce395421d933d7bc0699b0f1561f988f09a9e8633fd542fe5c` | [↓](#lsp9ownershiptransferred_recipientnotification) | +| When ownership transfer starts (Ownable2Step) | [`LSP14OwnershipTransferStarted`](#lsp14ownershiptransferstarted)
➡ `0xee9a7c0924f740a2ca33d59b7f0c2929821ea9837ce043ce91c1823e9c4e52c0` | [↓](#lsp14ownershiptransferstarted) | +| When previous owner is notified of Ownable2Step transfer | [`LSP14OwnershipTransferred_SenderNotification`](#lsp14ownershiptransferred_sendernotification)
➡ `0xa124442e1cc7b52d8e2ede2787d43527dc1f3ae0de87f50dd03e27a71834f74c` | [↓](#lsp14ownershiptransferred_sendernotification) | +| When new owner is notified of Ownable2Step transfer | [`LSP14OwnershipTransferred_RecipientNotification`](#lsp14ownershiptransferred_recipientnotification)
➡ `0xe32c7debcb817925ba4883fdbfc52797187f28f73f860641dab1a68d9b32902c` | [↓](#lsp14ownershiptransferred_recipientnotification) | +| When someone follows you | [`LSP26FollowerSystem_FollowNotification`](#lsp26followersystem_follownotification)
➡ `0x71e02f9f05bcd5816ec4f3134aa2e5a916669537ec6c77fe66ea595fabc2d51a` | [↓](#lsp26followersystem_follownotification) | +| When someone unfollows you | [`LSP26FollowerSystem_UnfollowNotification`](#lsp26followersystem_unfollownotification)
➡ `0x9d3c0b4012b69658977b099bdaa51eff0f0460f421fba96d15669506c00d1c4f` | [↓](#lsp26followersystem_unfollownotification) | ## Using Type ID From 21f09845f7ce35401ef7865cce2b33ff8dc8cb35 Mon Sep 17 00:00:00 2001 From: emmet-bot Date: Mon, 16 Mar 2026 13:50:51 +0100 Subject: [PATCH 07/10] fix: Change decode collapsibles from green (success) to blue (info) --- docs/contracts/type-ids.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/contracts/type-ids.md b/docs/contracts/type-ids.md index cc5b3652db..3349f88933 100644 --- a/docs/contracts/type-ids.md +++ b/docs/contracts/type-ids.md @@ -167,7 +167,7 @@ No additional data is sent with this notification (empty bytes `""`). | **Solidity constant:** | `_TYPEID_LSP0_OwnershipTransferStarted` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP0OwnershipTransferStarted` | -:::success How to decode notification data? +:::info How to decode notification data? @@ -217,7 +217,7 @@ const [currentOwner, pendingNewOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP0_OwnershipTransferred_SenderNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP0OwnershipTransferred_SenderNotification` | -:::success How to decode notification data? +:::info How to decode notification data? @@ -267,7 +267,7 @@ const [previousOwner, newOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP0_OwnershipTransferred_RecipientNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP0OwnershipTransferred_RecipientNotification` | -:::success How to decode notification data? +:::info How to decode notification data? @@ -318,7 +318,7 @@ const [previousOwner, newOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP7_TOKENSSENDER` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP7Tokens_SenderNotification` | -:::success How to decode notification data? +:::info How to decode notification data? @@ -383,7 +383,7 @@ const [operator, from, to, amount, transferData] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP7_TOKENSRECIPIENT` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP7Tokens_RecipientNotification` | -:::success How to decode notification data? +:::info How to decode notification data? @@ -448,7 +448,7 @@ const [operator, from, to, amount, transferData] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP7_TOKENOPERATOR` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP7Tokens_OperatorNotification` | -:::success How to decode notification data? +:::info How to decode notification data? @@ -509,7 +509,7 @@ const [tokenOwner, allowance, operatorNotificationData] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP8_TOKENSSENDER` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP8Tokens_SenderNotification` | -:::success How to decode notification data? +:::info How to decode notification data? @@ -574,7 +574,7 @@ const [operator, from, to, tokenId, transferData] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP8_TOKENSRECIPIENT` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP8Tokens_RecipientNotification` | -:::success How to decode notification data? +:::info How to decode notification data? @@ -639,7 +639,7 @@ const [operator, from, to, tokenId, transferData] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP8_TOKENOPERATOR` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP8Tokens_OperatorNotification` | -:::success How to decode notification data? +:::info How to decode notification data? @@ -718,7 +718,7 @@ No additional data is sent with this notification (empty bytes `""`). | **Solidity constant:** | `_TYPEID_LSP9_OwnershipTransferStarted` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP9OwnershipTransferStarted` | -:::success How to decode notification data? +:::info How to decode notification data? @@ -768,7 +768,7 @@ const [currentOwner, pendingNewOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP9_OwnershipTransferred_SenderNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP9OwnershipTransferred_SenderNotification` | -:::success How to decode notification data? +:::info How to decode notification data? @@ -818,7 +818,7 @@ const [previousOwner, newOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP9_OwnershipTransferred_RecipientNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP9OwnershipTransferred_RecipientNotification` | -:::success How to decode notification data? +:::info How to decode notification data? @@ -869,7 +869,7 @@ const [previousOwner, newOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP14_OwnershipTransferStarted` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP14OwnershipTransferStarted` | -:::success How to decode notification data? +:::info How to decode notification data? @@ -919,7 +919,7 @@ const [currentOwner, pendingNewOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP14_OwnershipTransferred_SenderNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP14OwnershipTransferred_SenderNotification` | -:::success How to decode notification data? +:::info How to decode notification data? @@ -969,7 +969,7 @@ const [previousOwner, newOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP14_OwnershipTransferred_RecipientNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP14OwnershipTransferred_RecipientNotification` | -:::success How to decode notification data? +:::info How to decode notification data? @@ -1020,7 +1020,7 @@ const [previousOwner, newOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP26_FOLLOW` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP26FollowerSystem_FollowNotification` | -:::success How to decode notification data? +:::info How to decode notification data? > **Note:** LSP26 uses `abi.encodePacked` (not `abi.encode`), so the data is 20 bytes (the raw address) rather than 32 bytes (ABI-padded). @@ -1067,7 +1067,7 @@ address follower = address(bytes20(data)); | **Solidity constant:** | `_TYPEID_LSP26_UNFOLLOW` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP26FollowerSystem_UnfollowNotification` | -:::success How to decode notification data? +:::info How to decode notification data? > **Note:** LSP26 uses `abi.encodePacked` (not `abi.encode`), so the data is 20 bytes (the raw address) rather than 32 bytes (ABI-padded). From 29bc745522b0574dfcdee993f44383c812a6bcef Mon Sep 17 00:00:00 2001 From: emmet-bot Date: Mon, 16 Mar 2026 13:54:26 +0100 Subject: [PATCH 08/10] fix: Use HTML details/summary collapsible instead of admonition Replace :::info callouts with
for the decode sections as requested. --- docs/contracts/type-ids.md | 85 +++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/docs/contracts/type-ids.md b/docs/contracts/type-ids.md index 3349f88933..7572bdadf6 100644 --- a/docs/contracts/type-ids.md +++ b/docs/contracts/type-ids.md @@ -167,7 +167,8 @@ No additional data is sent with this notification (empty bytes `""`). | **Solidity constant:** | `_TYPEID_LSP0_OwnershipTransferStarted` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP0OwnershipTransferStarted` | -:::info How to decode notification data? +
+How to decode notification data? @@ -204,7 +205,7 @@ const [currentOwner, pendingNewOwner] = decodeAbiParameters( -::: +
### `LSP0OwnershipTransferred_SenderNotification` @@ -217,7 +218,8 @@ const [currentOwner, pendingNewOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP0_OwnershipTransferred_SenderNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP0OwnershipTransferred_SenderNotification` | -:::info How to decode notification data? +
+How to decode notification data? @@ -254,7 +256,7 @@ const [previousOwner, newOwner] = decodeAbiParameters( -::: +
### `LSP0OwnershipTransferred_RecipientNotification` @@ -267,7 +269,8 @@ const [previousOwner, newOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP0_OwnershipTransferred_RecipientNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP0OwnershipTransferred_RecipientNotification` | -:::info How to decode notification data? +
+How to decode notification data? @@ -301,7 +304,7 @@ const [previousOwner, newOwner] = decodeAbiParameters( -::: +
--- @@ -318,7 +321,8 @@ const [previousOwner, newOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP7_TOKENSSENDER` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP7Tokens_SenderNotification` | -:::info How to decode notification data? +
+How to decode notification data? @@ -370,7 +374,7 @@ const [operator, from, to, amount, transferData] = decodeAbiParameters( -::: +
### `LSP7Tokens_RecipientNotification` @@ -383,7 +387,8 @@ const [operator, from, to, amount, transferData] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP7_TOKENSRECIPIENT` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP7Tokens_RecipientNotification` | -:::info How to decode notification data? +
+How to decode notification data? @@ -435,7 +440,7 @@ const [operator, from, to, amount, transferData] = decodeAbiParameters( -::: +
### `LSP7Tokens_OperatorNotification` @@ -448,7 +453,8 @@ const [operator, from, to, amount, transferData] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP7_TOKENOPERATOR` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP7Tokens_OperatorNotification` | -:::info How to decode notification data? +
+How to decode notification data? @@ -492,7 +498,7 @@ const [tokenOwner, allowance, operatorNotificationData] = decodeAbiParameters( -::: +
--- @@ -509,7 +515,8 @@ const [tokenOwner, allowance, operatorNotificationData] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP8_TOKENSSENDER` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP8Tokens_SenderNotification` | -:::info How to decode notification data? +
+How to decode notification data? @@ -561,7 +568,7 @@ const [operator, from, to, tokenId, transferData] = decodeAbiParameters( -::: +
### `LSP8Tokens_RecipientNotification` @@ -574,7 +581,8 @@ const [operator, from, to, tokenId, transferData] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP8_TOKENSRECIPIENT` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP8Tokens_RecipientNotification` | -:::info How to decode notification data? +
+How to decode notification data? @@ -626,7 +634,7 @@ const [operator, from, to, tokenId, transferData] = decodeAbiParameters( -::: +
### `LSP8Tokens_OperatorNotification` @@ -639,7 +647,8 @@ const [operator, from, to, tokenId, transferData] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP8_TOKENOPERATOR` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP8Tokens_OperatorNotification` | -:::info How to decode notification data? +
+How to decode notification data? @@ -688,7 +697,7 @@ const [tokenOwner, tokenId, authorized, operatorNotificationData] = -::: +
--- @@ -718,7 +727,8 @@ No additional data is sent with this notification (empty bytes `""`). | **Solidity constant:** | `_TYPEID_LSP9_OwnershipTransferStarted` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP9OwnershipTransferStarted` | -:::info How to decode notification data? +
+How to decode notification data? @@ -755,7 +765,7 @@ const [currentOwner, pendingNewOwner] = decodeAbiParameters( -::: +
### `LSP9OwnershipTransferred_SenderNotification` @@ -768,7 +778,8 @@ const [currentOwner, pendingNewOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP9_OwnershipTransferred_SenderNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP9OwnershipTransferred_SenderNotification` | -:::info How to decode notification data? +
+How to decode notification data? @@ -805,7 +816,7 @@ const [previousOwner, newOwner] = decodeAbiParameters( -::: +
### `LSP9OwnershipTransferred_RecipientNotification` @@ -818,7 +829,8 @@ const [previousOwner, newOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP9_OwnershipTransferred_RecipientNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP9OwnershipTransferred_RecipientNotification` | -:::info How to decode notification data? +
+How to decode notification data? @@ -852,7 +864,7 @@ const [previousOwner, newOwner] = decodeAbiParameters( -::: +
--- @@ -869,7 +881,8 @@ const [previousOwner, newOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP14_OwnershipTransferStarted` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP14OwnershipTransferStarted` | -:::info How to decode notification data? +
+How to decode notification data? @@ -906,7 +919,7 @@ const [currentOwner, pendingNewOwner] = decodeAbiParameters( -::: +
#### `LSP14OwnershipTransferred_SenderNotification` @@ -919,7 +932,8 @@ const [currentOwner, pendingNewOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP14_OwnershipTransferred_SenderNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP14OwnershipTransferred_SenderNotification` | -:::info How to decode notification data? +
+How to decode notification data? @@ -956,7 +970,7 @@ const [previousOwner, newOwner] = decodeAbiParameters( -::: +
#### `LSP14OwnershipTransferred_RecipientNotification` @@ -969,7 +983,8 @@ const [previousOwner, newOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP14_OwnershipTransferred_RecipientNotification` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP14OwnershipTransferred_RecipientNotification` | -:::info How to decode notification data? +
+How to decode notification data? @@ -1003,7 +1018,7 @@ const [previousOwner, newOwner] = decodeAbiParameters( -::: +
--- @@ -1020,7 +1035,8 @@ const [previousOwner, newOwner] = decodeAbiParameters( | **Solidity constant:** | `_TYPEID_LSP26_FOLLOW` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP26FollowerSystem_FollowNotification` | -:::info How to decode notification data? +
+How to decode notification data? > **Note:** LSP26 uses `abi.encodePacked` (not `abi.encode`), so the data is 20 bytes (the raw address) rather than 32 bytes (ABI-padded). @@ -1054,7 +1070,7 @@ address follower = address(bytes20(data)); -::: +
### `LSP26FollowerSystem_UnfollowNotification` @@ -1067,7 +1083,8 @@ address follower = address(bytes20(data)); | **Solidity constant:** | `_TYPEID_LSP26_UNFOLLOW` | | **JavaScript constant:** | `LSP1_TYPE_IDS.LSP26FollowerSystem_UnfollowNotification` | -:::info How to decode notification data? +
+How to decode notification data? > **Note:** LSP26 uses `abi.encodePacked` (not `abi.encode`), so the data is 20 bytes (the raw address) rather than 32 bytes (ABI-padded). @@ -1101,7 +1118,7 @@ address unfollower = address(bytes20(data)); -::: +
--- From 40e14108274d641c1999c32725179b8054dbccb3 Mon Sep 17 00:00:00 2001 From: CJ42 Date: Mon, 16 Mar 2026 13:57:42 +0100 Subject: [PATCH 09/10] chore: add extra mention for type ID import --- docs/contracts/type-ids.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/contracts/type-ids.md b/docs/contracts/type-ids.md index 7572bdadf6..62b2faac99 100644 --- a/docs/contracts/type-ids.md +++ b/docs/contracts/type-ids.md @@ -47,6 +47,12 @@ When a Universal Profile receives a notification, its Universal Receiver functio ## Using Type ID +:::success Recommendation + +It is recommended to import each notification type ID from the [`@lukso/lsp-smart-contracts`](https://github.com/lukso-network/lsp-smart-contracts) package to ensure the logic of your dApp or smart contract checks against the correct Type ID values. + +::: + @@ -80,7 +86,7 @@ LSP1_TYPE_IDS.LSP7Tokens_RecipientNotification; -The Solidity constants are defined in each LSP's contract constants file (e.g., `LSP7Constants.sol`, `LSP26Constants.sol`). It is recommended to import them from the [`@lukso/lsp-smart-contracts`](https://github.com/lukso-network/lsp-smart-contracts) package to ensure the correct Type IDs are used. +The Solidity constants are defined in each LSP's contract constants file (e.g., `LSP7Constants.sol`, `LSP26Constants.sol`). ```solidity import { _TYPEID_LSP7_TOKENSSENDER } from "@lukso/lsp7-contracts/contracts/LSP7Constants.sol"; From 3de950bc4ec56e9bbcc378e076248a4851bf8d91 Mon Sep 17 00:00:00 2001 From: CJ42 Date: Mon, 16 Mar 2026 14:02:56 +0100 Subject: [PATCH 10/10] chore: remove arrow emoji --- docs/contracts/type-ids.md | 42 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/docs/contracts/type-ids.md b/docs/contracts/type-ids.md index 62b2faac99..17bf08f76c 100644 --- a/docs/contracts/type-ids.md +++ b/docs/contracts/type-ids.md @@ -23,27 +23,27 @@ When a Universal Profile receives a notification, its Universal Receiver functio ## Notification Type IDs list -| Notification Type | TypeId value | Details | -| --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | -| When receiving native LYX (ERC725Account) | [`LSP0ValueReceived`](#lsp0valuereceived)
➡ `0x9c4705229491d365fb5434052e12a386d6771d976bea61070a8c694e8affea3d` | [↓](#lsp0valuereceived) | -| When ownership transfer starts (ERC725Account) | [`LSP0OwnershipTransferStarted`](#lsp0ownershiptransferstarted)
➡ `0xe17117c9d2665d1dbeb479ed8058bbebde3c50ac50e2e65619f60006caac6926` | [↓](#lsp0ownershiptransferstarted) | -| When previous owner is notified of ownership transfer (ERC725Account) | [`LSP0OwnershipTransferred_SenderNotification`](#lsp0ownershiptransferred_sendernotification)
➡ `0xa4e59c931d14f7c8a7a35027f92ee40b5f2886b9fdcdb78f30bc5ecce5a2f814` | [↓](#lsp0ownershiptransferred_sendernotification) | -| When new owner is notified of ownership transfer (ERC725Account) | [`LSP0OwnershipTransferred_RecipientNotification`](#lsp0ownershiptransferred_recipientnotification)
➡ `0xceca317f109c43507871523e82dc2a3cc64dfa18f12da0b6db14f6e23f995538` | [↓](#lsp0ownershiptransferred_recipientnotification) | -| When sending LSP7 tokens | [`LSP7Tokens_SenderNotification`](#lsp7tokens_sendernotification)
➡ `0x429ac7a06903dbc9c13dfcb3c9d11df8194581fa047c96d7a4171fc7402958ea` | [↓](#lsp7tokens_sendernotification) | -| When receiving LSP7 tokens | [`LSP7Tokens_RecipientNotification`](#lsp7tokens_recipientnotification)
➡ `0x20804611b3e2ea21c480dc465142210acf4a2485947541770ec1fb87dee4a55c` | [↓](#lsp7tokens_recipientnotification) | -| When an LSP7 operator is authorized or revoked | [`LSP7Tokens_OperatorNotification`](#lsp7tokens_operatornotification)
➡ `0x386072cc5a58e61263b434c722725f21031cd06e7c552cfaa06db5de8a320dbc` | [↓](#lsp7tokens_operatornotification) | -| When sending an LSP8 NFT | [`LSP8Tokens_SenderNotification`](#lsp8tokens_sendernotification)
➡ `0xb23eae7e6d1564b295b4c3e3be402d9a2f0776c57bdf365903496f6fa481ab00` | [↓](#lsp8tokens_sendernotification) | -| When receiving an LSP8 NFT | [`LSP8Tokens_RecipientNotification`](#lsp8tokens_recipientnotification)
➡ `0x0b084a55ebf70fd3c06fd755269dac2212c4d3f0f4d09079780bfa50c1b2984d` | [↓](#lsp8tokens_recipientnotification) | -| When an LSP8 operator is authorized or revoked | [`LSP8Tokens_OperatorNotification`](#lsp8tokens_operatornotification)
➡ `0x8a1c15a8799f71b547e08e2bcb2e85257e81b0a07eee2ce6712549eef1f00970` | [↓](#lsp8tokens_operatornotification) | -| When receiving native LYX (Vault) | [`LSP9ValueReceived`](#lsp9valuereceived)
➡ `0x468cd1581d7bc001c3b685513d2b929b55437be34700410383d58f3aa1ea0abc` | [↓](#lsp9valuereceived) | -| When ownership transfer starts (Vault) | [`LSP9OwnershipTransferStarted`](#lsp9ownershiptransferstarted)
➡ `0xaefd43f45fed1bcd8992f23c803b6f4ec45cf6b62b0d404d565f290a471e763f` | [↓](#lsp9ownershiptransferstarted) | -| When previous owner is notified of Vault ownership transfer | [`LSP9OwnershipTransferred_SenderNotification`](#lsp9ownershiptransferred_sendernotification)
➡ `0x0c622e58e6b7089ae35f1af1c86d997be92fcdd8c9509652022d41aa65169471` | [↓](#lsp9ownershiptransferred_sendernotification) | -| When new owner is notified of Vault ownership transfer | [`LSP9OwnershipTransferred_RecipientNotification`](#lsp9ownershiptransferred_recipientnotification)
➡ `0x79855c97dbc259ce395421d933d7bc0699b0f1561f988f09a9e8633fd542fe5c` | [↓](#lsp9ownershiptransferred_recipientnotification) | -| When ownership transfer starts (Ownable2Step) | [`LSP14OwnershipTransferStarted`](#lsp14ownershiptransferstarted)
➡ `0xee9a7c0924f740a2ca33d59b7f0c2929821ea9837ce043ce91c1823e9c4e52c0` | [↓](#lsp14ownershiptransferstarted) | -| When previous owner is notified of Ownable2Step transfer | [`LSP14OwnershipTransferred_SenderNotification`](#lsp14ownershiptransferred_sendernotification)
➡ `0xa124442e1cc7b52d8e2ede2787d43527dc1f3ae0de87f50dd03e27a71834f74c` | [↓](#lsp14ownershiptransferred_sendernotification) | -| When new owner is notified of Ownable2Step transfer | [`LSP14OwnershipTransferred_RecipientNotification`](#lsp14ownershiptransferred_recipientnotification)
➡ `0xe32c7debcb817925ba4883fdbfc52797187f28f73f860641dab1a68d9b32902c` | [↓](#lsp14ownershiptransferred_recipientnotification) | -| When someone follows you | [`LSP26FollowerSystem_FollowNotification`](#lsp26followersystem_follownotification)
➡ `0x71e02f9f05bcd5816ec4f3134aa2e5a916669537ec6c77fe66ea595fabc2d51a` | [↓](#lsp26followersystem_follownotification) | -| When someone unfollows you | [`LSP26FollowerSystem_UnfollowNotification`](#lsp26followersystem_unfollownotification)
➡ `0x9d3c0b4012b69658977b099bdaa51eff0f0460f421fba96d15669506c00d1c4f` | [↓](#lsp26followersystem_unfollownotification) | +| Notification Type | TypeId value | Details | +| --------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | +| When receiving native LYX (ERC725Account) | [`LSP0ValueReceived`](#lsp0valuereceived)
`0x9c4705229491d365fb5434052e12a386d6771d976bea61070a8c694e8affea3d` | [↓](#lsp0valuereceived) | +| When ownership transfer starts (ERC725Account) | [`LSP0OwnershipTransferStarted`](#lsp0ownershiptransferstarted)
`0xe17117c9d2665d1dbeb479ed8058bbebde3c50ac50e2e65619f60006caac6926` | [↓](#lsp0ownershiptransferstarted) | +| When previous owner is notified of ownership transfer (ERC725Account) | [`LSP0OwnershipTransferred_SenderNotification`](#lsp0ownershiptransferred_sendernotification)
`0xa4e59c931d14f7c8a7a35027f92ee40b5f2886b9fdcdb78f30bc5ecce5a2f814` | [↓](#lsp0ownershiptransferred_sendernotification) | +| When new owner is notified of ownership transfer (ERC725Account) | [`LSP0OwnershipTransferred_RecipientNotification`](#lsp0ownershiptransferred_recipientnotification)
`0xceca317f109c43507871523e82dc2a3cc64dfa18f12da0b6db14f6e23f995538` | [↓](#lsp0ownershiptransferred_recipientnotification) | +| When sending LSP7 tokens | [`LSP7Tokens_SenderNotification`](#lsp7tokens_sendernotification)
`0x429ac7a06903dbc9c13dfcb3c9d11df8194581fa047c96d7a4171fc7402958ea` | [↓](#lsp7tokens_sendernotification) | +| When receiving LSP7 tokens | [`LSP7Tokens_RecipientNotification`](#lsp7tokens_recipientnotification)
`0x20804611b3e2ea21c480dc465142210acf4a2485947541770ec1fb87dee4a55c` | [↓](#lsp7tokens_recipientnotification) | +| When an LSP7 operator is authorized or revoked | [`LSP7Tokens_OperatorNotification`](#lsp7tokens_operatornotification)
`0x386072cc5a58e61263b434c722725f21031cd06e7c552cfaa06db5de8a320dbc` | [↓](#lsp7tokens_operatornotification) | +| When sending an LSP8 NFT | [`LSP8Tokens_SenderNotification`](#lsp8tokens_sendernotification)
`0xb23eae7e6d1564b295b4c3e3be402d9a2f0776c57bdf365903496f6fa481ab00` | [↓](#lsp8tokens_sendernotification) | +| When receiving an LSP8 NFT | [`LSP8Tokens_RecipientNotification`](#lsp8tokens_recipientnotification)
`0x0b084a55ebf70fd3c06fd755269dac2212c4d3f0f4d09079780bfa50c1b2984d` | [↓](#lsp8tokens_recipientnotification) | +| When an LSP8 operator is authorized or revoked | [`LSP8Tokens_OperatorNotification`](#lsp8tokens_operatornotification)
`0x8a1c15a8799f71b547e08e2bcb2e85257e81b0a07eee2ce6712549eef1f00970` | [↓](#lsp8tokens_operatornotification) | +| When receiving native LYX (Vault) | [`LSP9ValueReceived`](#lsp9valuereceived)
`0x468cd1581d7bc001c3b685513d2b929b55437be34700410383d58f3aa1ea0abc` | [↓](#lsp9valuereceived) | +| When ownership transfer starts (Vault) | [`LSP9OwnershipTransferStarted`](#lsp9ownershiptransferstarted)
`0xaefd43f45fed1bcd8992f23c803b6f4ec45cf6b62b0d404d565f290a471e763f` | [↓](#lsp9ownershiptransferstarted) | +| When previous owner is notified of Vault ownership transfer | [`LSP9OwnershipTransferred_SenderNotification`](#lsp9ownershiptransferred_sendernotification)
`0x0c622e58e6b7089ae35f1af1c86d997be92fcdd8c9509652022d41aa65169471` | [↓](#lsp9ownershiptransferred_sendernotification) | +| When new owner is notified of Vault ownership transfer | [`LSP9OwnershipTransferred_RecipientNotification`](#lsp9ownershiptransferred_recipientnotification)
`0x79855c97dbc259ce395421d933d7bc0699b0f1561f988f09a9e8633fd542fe5c` | [↓](#lsp9ownershiptransferred_recipientnotification) | +| When ownership transfer starts (Ownable2Step) | [`LSP14OwnershipTransferStarted`](#lsp14ownershiptransferstarted)
`0xee9a7c0924f740a2ca33d59b7f0c2929821ea9837ce043ce91c1823e9c4e52c0` | [↓](#lsp14ownershiptransferstarted) | +| When previous owner is notified of Ownable2Step transfer | [`LSP14OwnershipTransferred_SenderNotification`](#lsp14ownershiptransferred_sendernotification)
`0xa124442e1cc7b52d8e2ede2787d43527dc1f3ae0de87f50dd03e27a71834f74c` | [↓](#lsp14ownershiptransferred_sendernotification) | +| When new owner is notified of Ownable2Step transfer | [`LSP14OwnershipTransferred_RecipientNotification`](#lsp14ownershiptransferred_recipientnotification)
`0xe32c7debcb817925ba4883fdbfc52797187f28f73f860641dab1a68d9b32902c` | [↓](#lsp14ownershiptransferred_recipientnotification) | +| When someone follows you | [`LSP26FollowerSystem_FollowNotification`](#lsp26followersystem_follownotification)
`0x71e02f9f05bcd5816ec4f3134aa2e5a916669537ec6c77fe66ea595fabc2d51a` | [↓](#lsp26followersystem_follownotification) | +| When someone unfollows you | [`LSP26FollowerSystem_UnfollowNotification`](#lsp26followersystem_unfollownotification)
`0x9d3c0b4012b69658977b099bdaa51eff0f0460f421fba96d15669506c00d1c4f` | [↓](#lsp26followersystem_unfollownotification) | ## Using Type ID