I would make a point, that the interface function isNonTransferable(uint256 tokenId)
like suggested (ERC-6454: Minimalistic Non-Transferable NFTs) is elegant due to its simplicity (hence flexibility).
IMO it should stay an interface only, NOT a guide on how it shall be implemented.
isNonTransferable(tokenId)
is - besides NFT marketplaces - particularily interesting for DeFi, when an NFT shall be used as security e.g. for loans, lending etc. It can only serve as a security, as long as it cannot be transferred (unconditionally).
A side benefit is imho that the implementing contract becomes easy to read/review, as it is easy to grasp the contracts behavior, when isNonTransferable(tokenId) can trivially be used in ERC721’s _beforeTokenTransfer(tokenId)
, enforcing compliance with the “external” view on the transferability.
For disclosure, we drafted an EIP, where we need a similar mechanism and would rather prefer referencing an already existing standard interface rather than proposing another competitor method. In our case for example the required events of EIP-5192