Packages
Compass

Compass Provider

To query Compass, a simple request wrapper is provided. To initialize it you'll need an API key.

import { PoapCompass } from '@poap-xyz/providers';
 
const compass = new PoapCompass({
  apiKey: 'my-secret-api-key',
});

Requests

Query requests can be made by giving the query in string and optionally the variables to pass. All success requests are returned as an object with a data property which the structure differs depending on the query done. When the request fail, errors are thrown instead.

Quering

To do a query request, a response data type is needed and, in the case the query accepts variables, a type for its structure is also needed.

For example, if we want to retrieve the last POAP token ids we could have the query:

const query = `
  query LastTokenIds($limit: Int!) {
    poaps(limit: $limit, order_by: { id: desc }) {
      id
    }
  }
`;

Which will return the type:

type LastTokenIdsResponse = {
  poaps: Array<{
    id: number;
  }>;
};

And have the variables type:

type LastTokenIdsVariables = {
  limit: number;
};

Then the query can be executed:

const lastTokenIds: number[] = [];
try {
  const { data } = await compass.request<
    LastTokenIdsResponse,
    LastTokenIdsVariables
  >(query, { limit: 3 });
 
  lastTokenIds.push(
    ...data.poaps.map((poap) => poap.id)
  );
} catch (error: unknown) {
  console.error(error)
}

Errors

There are two types of errors, HTTP errors and requests errors. The former are thrown when there is an issue with the HTTP requests itself and the later when the query has some malformed or unavailable structure.

HTTP errors

When the HTTP request is malformed a CompassBadRequestError is thrown, which should not happen unless there is a migration to be made. When the API key given is incorrect or expired, then a CompassUnauthorizedError error will be thrown.

Query errors

All errors derived from a malformed structure on the query will throw a CompassRequestError which has a public property called errors of the type CompassError with more information about what went wrong.

Batch Requests

It is possible to do many requests that only differs on the variables given to the same query. Such requests will be done in batch not to overload the server.

For example, if what we want is to retrieve collectors of a drop:

const total = 800; // Number of collectors we want to retrieve
const limit = 100; // Number of collectors we retrieve per page
 
const MY_DROP_COLLECTORS_QUERY = `
  query MyDropCollectors(
    $offset: Int
    $limit: Int
  ) {
    poaps(
      where: {
        drop_id: { _eq: 151249 }
      }
      offset: $offset
      limit: $limit
    ) {
      collector_address
    }
  }
`;
 
type CollectorsQueryResponse = {
  poaps: Array<{
    collector_address: string;
  }>;
};
 
const responses = await compass.batch<
  CollectorsQueryResponse,
  PaginatedVariables
>(
  MY_DROP_COLLECTORS_QUERY,
  Array.from(
    { length: Math.ceil(total / limit) },
    (_, page): PaginatedVariables => ({
      offset: page * limit,
      limit: limit,
    }),
  ),
);
 
const collectors = responses.reduce(
  (addresses, response) => [
    ...addresses,
    ...response.data.poaps.map((poap) => poap.collector_address),
  ],
  [],
);

In this case, we are doing eight requests but in two groups requested in parallel, one of five and one of three requests.