# Introducción

{% hint style="info" %}
¿Quieres personalizar los bloques?

Edita los componentes generados como quieras.
{% endhint %}

***

### Lo que obtienes

* Bloques de UI (tarjetas/tablas/dialogos/formularios) para listar y gestionar escrows
* Proveedores para config de API, contexto de wallet, diálogos y montos
* Hooks de TanStack Query para obtener y mutar escrows
* Helpers de wallet-kit y utilidades de manejo de errores

### Enlaces

{% embed url="<https://blocks.trustlesswork.com>" %}

{% embed url="<https://github.com/Trustless-Work/react-library-trustless-work-blocks>" %}

{% embed url="<https://www.npmjs.com/package/@trustless-work/blocks>" %}

### Lista todos los bloques disponibles

Usa la CLI para imprimir todos los bloques disponibles:

{% code title="CLI" %}

```sh
npx trustless-work list
```

{% endcode %}

Esta es la forma más rápida de descubrir rutas de carpetas para `npx trustless-work add ...`.

### API de Contexto

La API de contexto es un almacenamiento global de escrows. Se usa para guardar los escrows que se obtienen desde la API. También se usa para guardar el escrow seleccionado.

{% hint style="info" %}
No tienes que usar este enfoque de contexto.

Puedes usar Redux, Zustand, o cualquier otra cosa.\
Solo asegúrate de que los datos del escrow objetivo estén disponibles para cada hook de endpoint.
{% endhint %}

#### Cómo los hooks de endpoint usan el contexto

Al implementar los endpoints, necesitamos pasar los datos de un escrow específico a cada endpoint. ¿Pero cómo lo hacemos? Nuestra librería proporciona un contexto llamado `EscrowContext`, que incluye algunas utilidades muy importantes. Entre ellas están`selectedEscrow`y `setSelectedEscrow`, que nos permiten hacer lo siguiente:

#### `selectedEscrow`

Actualmente, `selectedEscrow` mantiene un escrow específico al que estamos apuntando. Con esto, todos los hooks de endpoint interactúan con ese estado para extraer datos de él, como contractId, roles, etc. Por ejemplo, en el selector de cambio de estado del milestone, los `milestoneIndex` valores se cargan en función del escrow actualmente seleccionado. Por lo tanto, si`setSelectedEscrow` está indefinido, no se cargarán.

{% code title="useChangeMilestoneStatus.ts" overflow="wrap" %}

```ts
const { selectedEscrow } = useEscrowContext();

const handleSubmit = form.handleSubmit(async (payload) => {             
  /**
   * Crea el payload final para la mutación de cambio de estado del milestone
   *
   * @param payload - El payload del formulario
   * @returns El payload final para la mutación de cambio de estado del milestone
  */
  const finalPayload: ChangeMilestoneStatusPayload = {
    contractId: selectedEscrow?.contractId || '', // contractId del selectedEscrow
    milestoneIndex: payload.milestoneIndex,
    newStatus: payload.status,
    newEvidence: payload.evidence || undefined,
    serviceProvider: walletAddress || '',
  };

  /**
   * Llama a la mutación de cambio de estado del milestone
   *
   * @param payload - El payload final para la mutación de cambio de estado del milestone
   * @param type - El tipo del escrow
   * @param address - La dirección del escrow
  */
  await changeMilestoneStatus.mutateAsync({
    payload: finalPayload,
    type: selectedEscrow?.type || 'multi-release',
    address: walletAddress || '',
  });
}
```

{% endcode %}

#### `setSelectedEscrow`

`setSelectedEscrow` almacena el escrow seleccionado en el contexto.

Otros hooks y bloques de UI pueden entonces leer `selectedEscrow` para obtener `contractId`, roles, etc.\
Ejemplo: la vista de tarjetas almacena el escrow seleccionado antes de abrir el diálogo de detalles.

{% code title="EscrowsCards.tsx" overflow="wrap" %}

```ts
const { setSelectedEscrow } = useEscrowContext();

const onCardClick = (escrow: Escrow) => {
  setSelectedEscrow(escrow);
  dialogStates.second.setIsOpen(true);
};
```

{% endcode %}

#### `updateEscrow`

Nuestra `updateEscrow` función actualiza el selectedEscrow existente en el contexto. Es útil para actualizar una bandera u otros campos. Por ejemplo, la usamos para actualizar el estado del escrow después de una mutación de cambio de estado del milestone.

{% code title="useChangeMilestoneStatus.ts" overflow="wrap" %}

```ts
const { selectedEscrow, updateEscrow } = useEscrowContext();

const handleSubmit = form.handleSubmit(async (payload) => { 
  /**
    * Llama a la mutación de cambio de estado del milestone
    *
    * @param payload - El payload final para la mutación de cambio de estado del milestone
    * @param type - El tipo del escrow
    * @param address - La dirección del escrow
  */
  await changeMilestoneStatus.mutateAsync({
    payload: finalPayload,
    type: selectedEscrow?.type || "multi-release", // tipo del selectedEscrow
    address: walletAddress || "",
  });

  toast.success("Estado del milestone actualizado con éxito");

  // Actualiza el escrow seleccionado en el contexto con el nuevo estado y evidencia
  updateEscrow({
    ...selectedEscrow,
    milestones: selectedEscrow?.milestones.map((milestone, index) => {
      if (index === Number(payload.milestoneIndex)) {
        return {
          ...milestone,
          status: payload.status,
          evidence: payload.evidence || undefined,
        };
      }
      return milestone;
    }),
  });
}
```

{% endcode %}

### Instalar bloques por ruta de carpeta

Puedes instalar carpetas enteras (y todos los bloques hijos) con un solo comando.

#### Instalar un directorio padre

```sh
npx trustless-work add escrows
```

Instala todos los bloques de escrow.

#### Instalar una subcarpeta específica

```sh
npx trustless-work add escrows/single-release
```

Instala solo los bloques de escrow single-release.

{% hint style="success" %}
Cuanto más profunda la ruta de la carpeta, más específica es la instalación.

Empieza amplio (`escrows`), luego afiná según sea necesario (`escrows/single-release/...`).
{% endhint %}

[Guía de instalación](https://blocks.trustlesswork.com/get-started/installation)
