Querying Data

Learn common patterns for querying Lens data.


The Lens API, utilizing the versatility of GraphQL, enables diverse data querying methods. This page delves into common patterns for querying data through Lens, including:

  • Media Snapshots: Fetch optimized media content

  • Exchange Rates: Retrieve conversion rates from cryptocurrency to fiat currency

  • Statistics: Access profile and publication statistics

Media Snapshots

The Lens API takes snapshots of media content referenced by Profile Metadata and Publication Metadata objects. These snapshots are then served from a Content Delivery Network (CDN) to ensure quick and reliable access.

In the specific it snapshots the following media content:

  • Profile pictures

  • Profile cover pictures

  • Publication media content: images, audio, and video

The media content referenced from the Marketplace section of the Publication Metadata is not fully snapshotted. This is because it's primarily intended for use by NFT marketplaces, such as OpenSea, that deal with NFTs from collected publications, rather than for direct use by Lens applications.

There are some limits to the size of the media content that can be snapshotted. The Lens API will not snapshot media content that exceeds the following limits:

CategoryLimit
Image100MB with GIFs limited to 1.2MB
Audio200MB
Video1GB

Images

Image snapshots are delivered through ImageKit, a powerful image optimization and delivery service. ImageKit automatically optimizes the images for web use and serves them from a global CDN.

When querying image data from the Lens API, you can retrieve the original image URI, a CDN-optimized image URL, and additional image URLs that specify certain transformations to adapt the images to your application's requirements.

When you retrieve publication image data using either the React SDK or the JavaScript SDK, you will encounter ImageSet and EncryptableImageSet objects. In the case of the JavaScript SDK, these are named ImageSetFragment and EncryptableImageSetFragment, respectively.

type ImageSet = {  raw: Image;  optimized: Image | null;  small: Image | null;  medium: Image | null;};
type EncryptableImageSet = {  raw: EncryptableImage;  optimized: Image | null;  small: Image | null;  medium: Image | null;};

These object have the following properties:

  • raw contains the original image URI, along with its type and dimensions (if available).

  • optimized, if present, contains the URL of an optimized version of the image. Optimizations may include lossless compression, resizing, and format conversion. It also includes the image's type and dimensions.

  • small, if present, contains the URL of a small-sized version of the image, along with its type and dimensions.

  • medium, if present, contains the URL of a medium-sized version of the image, along with its type and dimensions.

These different sizes can be used in various ways within your application. For example, the small size might be used for thumbnails, the medium size for listing views, and the optimized size for full images. Additionally, the raw original can be used to enable users to download the image, which can be especially useful for collected publications.

The suffix Encryptable suggests that the provided URI could potentially be an encrypted string. To verify if the image URI is indeed encrypted, examine the isEncrypted property at the Post level (or at the Comment or Quote level in case of comments and quotes).

When you access profile image data, you will encounter ProfilePictureSet and ProfileCoverSet objects (named ProfilePictureSetFragment and ProfileCoverSetFragment in the case of the JavaScript SDK).

type ProfileCoverSet = {  raw: Image;  optimized: Image | null;  transformed: Image | null;};
type ProfilePictureSet = {  raw: Image;  optimized: Image | null;  thumbnail: Image | null;};

As with publication images:

  • raw contains the original image URI, along with its type and dimensions (if available).

  • optimized, if present, contains the URL of an optimized version of the image. Optimizations may include lossless compression, resizing, and format conversion. It also includes the image's type and dimensions.

  • transformed, if present, contains the URL of a resized version of the image, along with its type and dimensions.

  • thumbnail, if present, contains the URL of a thumbnail-sized version of the image, along with its type and dimensions.

Both the React SDK and the Lens SDK allows you to specify the image transformations when creating the LensConfig object during the respective initialization process.

config.ts
const lensConfig: LensConfig = {  // ...
  params: {    image: {      small: {        width: "300px",        height: "200px",        keepAspectRatio: true,      },
      medium: {        width: "640px",        height: "480px",        keepAspectRatio: true,      },    },
    profile: {      thumbnail: {        width: "100px",        height: "100px",        keepAspectRatio: true,      },
      cover: {        width: "100%",        keepAspectRatio: true,      },    },  },};

You have control over:

  • params.image.small and params.image.medium: These parameters allow you to specify respectively the small and medium sizes for any ImageSet or EncryptableImageSet.

  • params.profile.thumbnail: This parameter allows you to specify a thumbnail size for any ProfilePictureSet.

  • params.profile.cover: This parameter allows you to specify the transformed size for any ProfileCoverSet.

Each of the four sizes mentioned above can be adjusted using an ImageTransform object. This object allows you to customize the dimensions of each image transformation.

PropertyDescriptionDefault Value
widthDefines the width of the transformed image. You can specify a size in pixels (e.g., 100px), a percentage (e.g., 50%), or auto for automatic sizing.auto
heightDefines the height of the transformed image. You can specify a size in pixels (e.g., 100px), a percentage (e.g., 50%), or auto for automatic sizing.auto
keepAspectRatioDetermines whether to preserve the image's original aspect ratio. If set to false, the image will stretch to fit the specified width and height.true

If one of the image sizes is omitted, the following default values will be used:

PropertyWidthHeightKeep Aspect Ratio
params.image.small400pxautotrue
params.image.medium700pxautotrue
params.profile.thumbnail256pxautotrue
params.profile.cover1100pxautotrue

Audios

Audio snapshots are delivered through CloudFront, Amazon CDN service.

When you query audio data, you can retrieve both the original audio URI and an CDN-optimized URL provided by CloudFront.

Specifically, when you retrieve publication audo data, you will encounter EncryptableAudioSet objects. The respective types for each type of integration are detailed below.

type EncryptableAudioSet = {  raw: EncryptableAudio;  optimized: Audio | null;};

These object have the following properties:

  • raw contains the original audio URI along with its type.

  • optimized, if present, contains the URL of an optimized version of the audio.

The raw original can be used to enable users to download the original audio, which can be especially useful for collected publications.

The suffix Encryptable suggests that the provided URI could potentially be an encrypted string. To verify if the audio URI is indeed encrypted, examine the isEncrypted property at the Post level (or at the Comment or Quote level in case of comments and quotes).

Videos

Video snapshots are delivered through Livepeer, an open-source video streaming network that offers transcoding and delivery services.

When you query video data, you can retrieve both the original video URI and an optimized HLS URL provided by Livepeer.

The optimized URL is the outcome of a video transcoding process on the Livepeer Network. This process is more time-consuming than image optimization, so it may take several minutes before the optimized URL becomes available.

Specifically, when you retrieve publication video data, you will encounter EncryptableVideoSet objects. The respective types for each type of integration are detailed below.

type EncryptableVideoSet = {  raw: EncryptableVideo;  optimized: Video | null;};

These object have the following properties:

  • raw contains the original video URI along with its type.

  • optimized, if present, contains the URL of an optimized HLS version of the video.

The raw original can be used to enable users to download the original video, which can be especially useful for collected publications.

The suffix Encryptable suggests that the provided URI could potentially be an encrypted string. To verify if the video URI is indeed encrypted, examine the isEncrypted property at the Post level (or at the Comment or Quote level in case of comments and quotes).

URL Resolution

When working with media snapshots, it's important to understand that the snapshot version of the media content may not always be available. This could be because the data was requested before the snapshotting process finished, or because the media URI was end-to-end encrypted, which prevents the snapshotting process from taking place.

You always want to ensure that you have a fallback strategy in place to handle these scenarios, like the following example.

getSmallImage.ts
function getSmallImage(set: ImageSet): string {  return set.small?.uri || set.optimized?.uri || set.raw.uri;}

It's also important to note that media URIs may not be directly usable URLs. They could be IPFS or Arweave URIs, which in many circumstances require resolution into URLs before use.

The following example illustrates a strategy you can use to resolve media URLs under various circumstances.

resolveUrl.ts
function resolveUrl(uri: string): string {  try {    const { protocol } = new URL(uri);
    switch (protocol) {      case "ar:":        return `${trustedArweaveGateway}${uri.replace("ar://", "")}`;
      case "ipfs:":        return `${trustedIpfsGateway}${uri.replace("ipfs://", "")}`;
      default:        return uri;    }  } catch {    // in the case of malformed URIs or encrypted URIs fallback to a placeholder    return "/assets/placeholder.jpg";  }}

Where trustedArweaveGateway and trustedIpfsGateway are the URLs of the gateways you want to use to resolve Arweave and IPFS URIs, respectively.

Exchange Rates

The Lens API provides contextual crypto-to-fiat exchange rates for any cryptocurrency amount, whether it's a fee (collect fee, follow fee) or a reward (collect reward, follow reward, mirror reward). This feature is particularly beneficial for applications aiming to offer a more intuitive user experience by displaying amounts in a familiar fiat currency.

The Lens React SDK includes a useful helper type, Amount. This type facilitates arithmetic operations on amount values, such as addition, subtraction, multiplication, and division, while considering the precision required by the respective currency.

The Amount type proves particularly useful when handling exchange rates and currency conversions.

Example
const usdAmount = maticAmount.convert(maticUsdRate);
console.log(usdAmount.toString()); // "42.56 USD"

The React SDK includes helper functions that extract amounts and exchange rates from the Lens API responses, converting them into Amount instances. You may have come across these when working with Collect criteria, Follow policy, Collect revenues, and Follow revenues.

You can control the fiat currency used for the exchange rate by setting the params.fxRateFor property of the LensConfig object during the initialization process.

config.ts
import { LensConfig, SupportedFiatType } from '@lens-protocol/react-web';
const lensConfig: LensConfig = {  // ...
  params: {    fxRateFor: SupportedFiatType.Gbp,  },};

All exchange rates returned from any query will be in the specified fiat currency.

SupportedFiatType available in @lens-protocol/react-web and @lens-protocol/react-native

Statistics

The Lens API offers a range of statistics that can provide valuable insights into a Profile or a Publication.

Publication statistics include:

  • Number of comments, quotes, and mirrors

  • Number of collects

  • Number of reactions

Profile statistics include:

  • Number of followers and followings

  • Number of posts, comments, mirrors, and quotes

  • Number of collects

By default, any number related to publications (such as post counts and comment counts) encompasses the entire Lens ecosystem. However, you can tailor these statistics to specific apps by specifying the App IDs to be counted.

Both the React SDK and the Lens SDK allow you to globally control this behavior. You can set the params.statsFor property of the LensConfig object during their respective initialization processes.

import { appId, LensConfig } from '@lens-protocol/react-web';
const lensConfig: LensConfig = {  // ...
  params: {    statsFor: [appId('hey'), appId('orb')],  },};

Any Profile or Publication statistics returned from any query will be tailored to the specified App IDs. Additionally, the React SDKs expose an alias named globalStats that always returns statistics for the entire Lens ecosystem, regardless of the provided App IDs.