> ## Documentation Index
> Fetch the complete documentation index at: https://frenglish.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# API de Sequence Analytics en Dune

> Aprenda cómo usar la función de analíticas de Sequence Builder para consultar datos de usuarios del proyecto con un Cloudflare Worker sin servidor.

Tiempo para completar: 20-30 minutos

En esta guía, mostraremos cómo utilizar la función de analíticas de [Sequence Builder](https://sequence.build/) para consultar información sobre el uso de los usuarios en el proyecto específico, aprovechando un [Cloudflare Worker](https://www.cloudflare.com/) sin servidor.

Muestre a la comunidad el rendimiento del proyecto mediante un panel de [Dune](https://dune.com/) para mostrar la conectividad, o utilice la API generada para incorporar bucles de retroalimentación inteligente en su juego impulsados por analíticas de usuario.

Puede ver un ejemplo del resultado de esta guía [aquí](https://dune.com/mmhorizon/dungeon-minter-analytics)

1. Gestión de claves de acceso: Solicite una clave de acceso secreta para interactuar con el stack de Sequence
2. Cloudflare Worker: Cree una función que consulte el stack de Sequence y genere puntos de datos específicos del proyecto
3. Panel de Dune: Cree una vista de los datos como un panel que se puede compartir

<Note>
  Puede encontrar una referencia al código de plantilla
  [aquí](https://github.com/0xsequence-demos/template-cloudflare-worker-wallets-analytics)
</Note>

## 1. Gestión de claves de acceso

Necesitará obtener una clave de acceso secreta para el proyecto con el fin de autenticar la aplicación con el stack de Sequence. Siga estos pasos:

### Creación de clave de acceso secreta

<Steps>
  <Step title="Acceder a configuración">
    Primero, acceda a la configuración y seleccione la tarjeta de API Keys:

    <Frame>
      <img src="https://mintcdn.com/frenglish/HG-orp76LeGEg_IA/images/builder/builder_settings_access_keys.png?fit=max&auto=format&n=HG-orp76LeGEg_IA&q=85&s=011b7eb42e7df37722bbc5b64e7054dd" alt="builder settings access keys" width="1757" height="771" data-path="images/builder/builder_settings_access_keys.png" />
    </Frame>
  </Step>

  <Step title="Agregar cuenta de servicio">
    Desplácese hacia abajo y seleccione `+ Add Service Account`:

    <Frame>
      <img src="https://mintcdn.com/frenglish/HG-orp76LeGEg_IA/images/builder/builder_settings_add_service_account.png?fit=max&auto=format&n=HG-orp76LeGEg_IA&q=85&s=48fbd0a901ca441db88e6089f2404bfd" alt="builder settings add service account" width="2033" height="805" data-path="images/builder/builder_settings_add_service_account.png" />
    </Frame>
  </Step>

  <Step title="Seleccionar permiso de escritura">
    Luego cambie el permiso a `Write`, haga clic en `+ Add Service Account` y seleccione `Confirm`:

    <Frame>
      <img src="https://mintcdn.com/frenglish/HG-orp76LeGEg_IA/images/builder/builder_settings_add_service_account_confirm.png?fit=max&auto=format&n=HG-orp76LeGEg_IA&q=85&s=adcd5c96435a562f72c2cf4f78dbae7c" alt="builder settings add service account" width="2033" height="771" data-path="images/builder/builder_settings_add_service_account_confirm.png" />
    </Frame>

    Finalmente, `copie` la clave y guárdela en un lugar seguro, ya que no podrá acceder a ella nuevamente desde Sequence Builder.
  </Step>
</Steps>

## 2. Cloudflare Worker

En este ejemplo, utilizamos un Cloudflare Worker para aprovechar el escalado automático según el uso del panel y despliegues sencillos desde la CLI, pero por supuesto puede usar su propio backend u otras alternativas sin servidor.

<Steps>
  <Step title="Crear proyecto">
    Para crear el proyecto desde cero, primero cree una carpeta con `mkdir`, ingrese a la carpeta con `cd` y ejecute `pnpm init` para crear un `package.json`.
  </Step>

  <Step title="Worker 'Hello World'">
    Asegúrese de tener instalado el CLI de wrangler en su proyecto y defina la palabra clave `wrangler` como un alias en su sesión local de bash.

    ```shell theme={null}
    pnpm install wrangler --save-dev
    alias wrangler='./node_modules/.bin/wrangler'
    ```

    Cree una cuenta en el [sitio de Cloudflare](https://cloudflare.com/) e inicie sesión en su panel de Cloudflare para conectar la plataforma Cloudflare con su entorno de desarrollo local.

    ```shell theme={null}
    wrangler login
    ```

    Una vez que haya iniciado sesión, inicialice el proyecto en el directorio con el comando `wrangler init` y acepte uno de los nombres de carpeta generados aleatoriamente que prefiera, siguiendo las indicaciones para inicializar su aplicación `"Hello World" Worker` con seguimiento en git y TypeScript.

    ```shell theme={null}
    wrangler init
    ```

    Para completar este paso, presione enter 4 veces después de `wrangler init`, respondiendo `No` en los últimos 2 pasos para rechazar el versionado con git y el despliegue.

    Esto clonará un repositorio inicial que puede usar para desplegar código en la nube.

    <Note>
      Pruebas locales de la API <br />
      En cualquier momento de la guía, puede usar el comando `wrangler dev` en la carpeta del proyecto para
      realizar pruebas locales
    </Note>

    #### Despliegue de prueba

    Finalmente, cambie al directorio del proyecto generado aleatoriamente usando `cd` y ejecute el comando `wrangler deploy`.

    Esto debería mostrar una URL, que puede ingresar en el navegador como `https://<app>.<account>.workers.dev` para ver el resultado `Hello World!`.
  </Step>

  <Step title="Configurar la configuración, las rutas y las funciones simuladas">
    Una vez que tenga el proyecto listo, actualice su `wrangler.toml` con las siguientes variables, donde `DAYS` es el periodo de tiempo que desea consultar:

    ```shell theme={null}
    [vars]
    SECRET_API_ACCESS_KEY = "<SECRET_API_ACCESS_KEY>"
    PROJECT_ID = <PROJECT_ID>
    DAYS = <DAYS>
    ```

    Luego incluya el tipo `Env` con las variables en `index.ts`:

    ```ts theme={null}
    export interface Env {
      PROJECT_ID: number;
      SECRET_API_ACCESS_KEY: string;
      DAYS: number;
    }
    ```

    Reemplace la función `fetch` existente con las siguientes llamadas a funciones simuladas:

    ```ts theme={null}
    export default {
      async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
        const url = new URL(request.url);

        // Handle different endpoints
        if (url.pathname === "/dailyActiveUsers") {
          return handleDailyWallets(env, request);
        } else if (url.pathname === "/totalTransactionsSent") {
          return handleTotalTxns(env, request);
        } else {
          return new Response("No function for this URL", {status: 405});
        }
      }
    };
    ```

    Utilizando las siguientes funciones:

    ```ts theme={null}
    const handleDailyWallets = async (env: Env, request: Request) => {
      return new Response(JSON.stringify({endpoint: "daily"}), {status: 200});
    };

    const handleTotalTxns = async (env: Env, request: Request) => {
      return new Response(JSON.stringify({endpoint: "total"}), {status: 200});
    };
    ```
  </Step>

  <Step title="Formateo de fechas">
    A continuación, incluya las siguientes funciones utilitarias para analizar la fecha correcta a partir del valor actualizado en el `wrangler.toml` para la variable `DAYS`:

    ```ts theme={null}
    const endDate = () => {
      const today = new Date();
      return today.toISOString().substring(0, 10); // only including the YYYY-MM-DD date
    };

    const startDate = (env: Env) => {
      const today = new Date();

      // Format today's date as a string
      const daysBefore = new Date(today);
      daysBefore.setDate(daysBefore.getDate() - env.DAYS);

      // Format the date 7 days before as a string by only including the YYYY-MM-DD date
      const daysBeforeString = daysBefore.toISOString().substring(0, 10);
      return daysBeforeString;
    };
    ```
  </Step>

  <Step title="Usuarios activos diarios">
    Ahora, gestione la solicitud de `Daily Active Users` usando la siguiente función, que llama a la API de Sequence Analytics:

    ```ts theme={null}
    const handleDailyWallets = async (env: Env, request: Request) => {
      const resp = await fetch(`https://api.sequence.build/rpc/Analytics/WalletsDaily`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${env.SECRET_API_ACCESS_KEY}`
        },
        body: JSON.stringify({
          filter: {
            dateInterval: "DAY",
            endDate: endDate(),
            projectId: env.PROJECT_ID,
            startDate: startDate(env)
          }
        })
      });

      const data: any = await resp.json();
      return new Response(JSON.stringify(data.walletStats), {status: 200});
    };
    ```
  </Step>

  <Step title="Total de transacciones enviadas">
    Por último, agregue la siguiente función para el `Total Transactions Sent`:

    ```ts theme={null}
    const handleTotalTxns = async (env: Env, request: Request) => {
      const resp = await fetch(
        `https://api.sequence.build/rpc/Analytics/WalletsTxnSentTotal`,
        {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            Authorization: `Bearer ${env.SECRET_API_ACCESS_KEY}`
          },
          body: JSON.stringify({
            filter: {
              dateInterval: "DAY",
              endDate: endDate(),
              projectId: env.PROJECT_ID,
              startDate: startDate(env)
            }
          })
        }
      );

      const data: any = await resp.json();
      return new Response(JSON.stringify(data.walletStats), {status: 200});
    };
    ```
  </Step>

  <Step title="Espaciado incluido para días sin datos">
    En la API de Sequence Analytics, los días sin actividad se eliminan de la respuesta. Sin embargo, si desea incluir días sin datos en sus consultas de Dune para mostrar el espaciado temporal en relación con los datos, puede usar la siguiente función para completar los días que no muestran datos en el formato de fecha correcto:

    ```typescript theme={null}
    const fillMissingDates = (data: any[], startDate: string, endDate: string) => {
      const filledData: {value: number; label: string}[] = [];
      const start = new Date(startDate);
      const end = new Date(endDate);

      for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
        const dateString = d.toISOString().substring(0, 10);
        const existingData = data.find((entry) => entry.label === dateString);
        if (existingData) {
          filledData.push(existingData);
        } else {
          filledData.push({value: 0, label: dateString});
        }
      }

      return filledData;
    };
    ```

    Luego, para **ambas** respuestas de llamada, incluya la siguiente llamada de método pasando los datos de `walletStats`:

    ```typescript theme={null}
    	...
    	const data: any = await resp.json();
    	const filledData = fillMissingDates(data.walletStats, startDate(env), endDate());
    	return new Response(JSON.stringify(filledData), { status: 200 });
    }
    ```
  </Step>
</Steps>

Ahora puede probar su API llamando a las rutas correspondientes con el nombre del host (`/dailyActiveUsers` y `/totalTransactionsSent`) una vez que haya vuelto a desplegar con `wrangler deploy`.

<Note>
  Para más ejemplos de endpoints disponibles a través de la API de Analytics, consulte la página de
  [descripción general](/api-references/analytics/overview).
</Note>

## 3. Panel de Dune

<Steps>
  <Step title="Registro en Dune">
    Primero, regístrese en [Dune](https://dune.com/)
  </Step>

  <Step title="Crear consulta">
    Acceda a su cuenta en `https://dune.com/<account>` y seleccione el botón `Create` y luego `New query`.

    <Frame>
      <img src="https://mintcdn.com/frenglish/rJzmbbAZ0zAOHkS5/images/guides/analytics/dune_create_query.png?fit=max&auto=format&n=rJzmbbAZ0zAOHkS5&q=85&s=17349a4b95990c9b690d9f44ca718fcd" alt="dune create query" width="1985" height="553" data-path="images/guides/analytics/dune_create_query.png" />
    </Frame>
  </Step>

  <Step title="Consulta de usuarios activos diarios">
    Ingrese la siguiente consulta SQL en la consola y seleccione `Run`:

    ```sql theme={null}
    SELECT
      t.label as "Date", -- converting the label to "Date"
      t.value as "Count" -- converting the value field to "Count"
    FROM UNNEST(
      TRY_CAST(
        JSON_PARSE(HTTP_GET('https://<URL>/dailyActiveUsers')) AS ARRAY(ROW(label VARCHAR, value DOUBLE))
      )
    ) AS t(label, value)

    ```

    Una vez que se muestren los resultados, cree una `New visualization`.

    Luego, seleccione `Add visualization` después de que el `Bar chart` predeterminado esté seleccionado en el menú desplegable (aunque puede personalizarlo si lo desea).

    <Frame>
      <img src="https://mintcdn.com/frenglish/rJzmbbAZ0zAOHkS5/images/guides/analytics/dune_add_visualization.png?fit=max&auto=format&n=rJzmbbAZ0zAOHkS5&q=85&s=7ffac4d7cb6161eaa92c32f9450464fe" alt="add visualization" width="1795" height="749" data-path="images/guides/analytics/dune_add_visualization.png" />
    </Frame>

    Finalmente, haga clic en `Save` y asigne un nombre a su consulta.

    <Frame>
      <img src="https://mintcdn.com/frenglish/rJzmbbAZ0zAOHkS5/images/guides/analytics/dune_query_save.png?fit=max&auto=format&n=rJzmbbAZ0zAOHkS5&q=85&s=86dab341769c006f351083beb161a8a1" alt="save query" width="1873" height="648" data-path="images/guides/analytics/dune_query_save.png" />
    </Frame>
  </Step>

  <Step title="Consulta de total de transacciones enviadas">
    Repita los pasos del [paso anterior](/guides/analytics-guide#create-query) y utilice la siguiente consulta SQL:

    ```sql theme={null}
    SELECT
      t.label,
      t.value
    FROM UNNEST(
      TRY_CAST(
        JSON_PARSE(HTTP_GET('https://<URL>/totalTransactionsSent')) AS ARRAY(ROW(label VARCHAR, value DOUBLE))
      )
    ) AS t(label, value)

    ```

    Una vez que se muestren los resultados, cree una `New visualization`.

    Luego, seleccione `Add visualization` y desplácese hacia abajo hasta `Counter` para crear un widget contador que muestre el total absoluto devuelto por la API.
  </Step>

  <Step title="Crear nuevo panel">
    Acceda a los botones que dicen `Create` > `New dashboard` e ingrese un nombre para el nuevo panel.

    <Frame>
      <img src="https://mintcdn.com/frenglish/rJzmbbAZ0zAOHkS5/images/guides/analytics/dune_create_dashboard.png?fit=max&auto=format&n=rJzmbbAZ0zAOHkS5&q=85&s=a967c0ec2910bbf8b1644de0df9a4964" alt="dune create dashboard" width="1610" height="450" data-path="images/guides/analytics/dune_create_dashboard.png" />
    </Frame>

    Una vez creado, agregue las 2 consultas anteriores seleccionando `Edit` y `Add visualization`.

    <Frame>
      <img src="https://mintcdn.com/frenglish/rJzmbbAZ0zAOHkS5/images/guides/analytics/dune_edit_dashboard.png?fit=max&auto=format&n=rJzmbbAZ0zAOHkS5&q=85&s=d3ae2756d389668ba3341abf32f40a30" alt="dune edit dashboard" width="1636" height="552" data-path="images/guides/analytics/dune_edit_dashboard.png" />
    </Frame>

    <Frame>
      <img src="https://mintcdn.com/frenglish/rJzmbbAZ0zAOHkS5/images/guides/analytics/dune_add_visualization_from_dashboard.png?fit=max&auto=format&n=rJzmbbAZ0zAOHkS5&q=85&s=3176abca403a0b4ec0448e6b60ea30ff" alt="dune add visualization from dashboard" width="1432" height="554" data-path="images/guides/analytics/dune_add_visualization_from_dashboard.png" />
    </Frame>

    Para cada consulta, busque el nombre en el modal y seleccione `Add` para cada una, luego `Done` en el modal y `Done` en el panel.
  </Step>
</Steps>

¡Felicidades! Ahora puedes compartir el uso de datos de tu proyecto con tu equipo o comunidad. Finaliza haciendo clic en el botón `Share`.

<Frame>
  <img src="https://mintcdn.com/frenglish/rJzmbbAZ0zAOHkS5/images/guides/analytics/dune_share_dashboard.png?fit=max&auto=format&n=rJzmbbAZ0zAOHkS5&q=85&s=985ac621a61b121ae9e2eb35d48bda26" alt="dune share dashboard" width="1616" height="683" data-path="images/guides/analytics/dune_share_dashboard.png" />
</Frame>
