Ciclo de vida de liberación única del escrow

Guía paso a paso para implementar el ciclo de vida de Liberación Única de Escrow

Importante

No funciona para un caso de uso real, solo para fines de prueba. Pero si deseas implementarlo, puedes usar el código a continuación como referencia y personalizarlo según tus necesidades.

Crear un proyecto Next.js#

Comienza creando un nuevo proyecto Next.js con TypeScript y Tailwind CSS. Para facilitar la configuración, por favor usa el alias de ruta con "@/":

npx create-next-app@latest

Navega hasta el directorio de tu proyecto:

cd my-trustless-app

Instalar Trustless Work Blocks#

Instala el paquete principal de la librería:

npm

npm install @trustless-work/blocks

Ejecuta la configuración del CLI

Inicializa tu proyecto con el CLI de Trustless Work:

npx trustless-work init

Qué hace el comando init:

  • Instala componentes shadcn/ui (con indicaciones interactivas)

  • Instala dependencias requeridas: @tanstack/react-query, @trustless-work/escrow, axios, zod, react-hook-form, @creit.tech/stellar-wallets-kit, react-day-picker, etc.

  • Crea .twblocks.json archivo de configuración

  • Opcionalmente conecta proveedores en tu Next.js app/layout.tsx

Configuración del entorno

Documentación

Crea un .env archivo en la raíz de tu proyecto:

.env

# Obligatorio: Tu clave de API de Trustless Work 
NEXT_PUBLIC_API_KEY=your_api_key_here

Agregar conectividad de billetera

Agrega conectividad de billetera a tu app:

npx trustless-work add wallet-kit

Envuelve tu app con el WalletProvider:

Envuelve tu app con el WalletProvider en tu layout.tsx:

app/layout.tsx

return (
    <WalletProvider>{children}</WalletProvider> 
);

Ejemplo de uso en una página:

Agrega conectividad de billetera a tu app:

app/page.tsx

"use client";

import { WalletButton } from "@/components/tw-blocks/wallet-kit/WalletButtons";

export default function Home() {
  return (
    <div className="font-sans grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20">
      <header className="flex justify-between items-center w-full">
        <h2 className="text-2xl font-bold">Trustless Work</h2>

        {/* Botón de billetera */}
        <WalletButton />
      </header>
    </div>
  );
}

Agregar utilidades

Agrega utilidades a tu app:

npx trustless-work add helpers

Agregar Tanstack Query

Agrega Tanstack Query a tu app:

npx trustless-work add tanstack

Agregar manejo de errores

Agrega Manejo de Errores a tu app:

npx trustless-work add handle-errors

Agregar proveedores (si omitiste el comando init)

Agrega Proveedores a tu app:

npx trustless-work add providers

Agregar componentes de Escrows de Liberación Única

Agrega Escrows de Liberación Única a tu app:

npx trustless-work add escrows/single-release

Agregar componentes de Escrows de Liberación Única-Múltiple

Agrega Escrows de Liberación Única-Múltiple a tu app:

npx trustless-work add escrows/single-multi-release

Agregar tarjetas de Escrows por Rol

Agrega Tarjetas de Escrows por Rol a tu app:

npx trustless-work add escrows/escrows-by-role/cards

Importar acciones

En el código, hay algunas acciones comentadas. Puedes descomentarlas e importarlas desde el bloque single-release. Consulta las notas en los componentes de escrows por rol o por firmante.

Código comentado

escrows/escrows-by-role/details/Actions.tsx

return (
    <div className="flex items-start justify-start flex-col gap-2 w-full">
      {/* Puedes agregar los botones aquí, usando los botones de los bloques. Estas acciones son condicionales en función de las banderas del escrow y los roles de usuario. */}
      {hasConditionalButtons && (
        <div className="flex flex-col gap-2 w-full">
          {/* El componente UpdateEscrowDialog debe renderizarse según el tipo de escrow. Significa que si selectedEscrow.type es "single-release", entonces debe renderizarse el componente UpdateEscrowDialog (del bloque single-release). Si selectedEscrow.type es "multi-release", entonces debe renderizarse el componente UpdateEscrowDialog (del bloque multi-release). */}
          {/* {shouldShowEditButton && <UpdateEscrowDialog />} */}

          {/* Funciona solo con escrows single-release */}
          {/* Solo aparece si el escrow tiene balance */}
          {/* {shouldShowDisputeButton && <DisputeEscrowButton />} */}

          {/* Funciona solo con escrows single-release */}
          {/* Solo aparece si el escrow está en disputa */}
          {/* {shouldShowResolveButton && <ResolveDisputeDialog />} */}

          {/* Funciona solo con escrows single-release */}
          {/* Solo aparece si todos los hitos están aprobados */}
          {/* {shouldShowReleaseFundsButton && <ReleaseEscrowButton />} */}
        </div>
      )}

      <FundEscrowDialog />
    </div>
  );

Acciones importadas

escrows/escrows-by-role/details/Actions.tsx

// Si necesitas ambos tipos, deberías importar ambas versiones para actualizar el escrow
import { UpdateEscrowDialog } from "../../single-release/update-escrow/dialog/UpdateEscrow";
/* import { UpdateEscrowDialog as UpdateEscrowDialogMultiRelease } from "../../multi-release/update-escrow/dialog/UpdateEscrow"; */
import { FundEscrowDialog } from "../../single-multi-release/fund-escrow/dialog/FundEscrow";
import { DisputeEscrowButton } from "../../single-release/dispute-escrow/button/DisputeEscrow";
import { ResolveDisputeDialog } from "../../single-release/resolve-dispute/dialog/ResolveDispute";
import { ReleaseEscrowButton } from "../../single-release/release-escrow/button/ReleaseEscrow";

return (
    <div className="flex items-start justify-start flex-col gap-2 w-full">
      {/* Puedes agregar los botones aquí, usando los botones de los bloques. Estas acciones son condicionales en función de las banderas del escrow y los roles de usuario. */}
      {hasConditionalButtons && (
        <div className="flex flex-col gap-2 w-full">
          {/* El componente UpdateEscrowDialog debe renderizarse según el tipo de escrow. Significa que si selectedEscrow.type es "single-release", entonces debe renderizarse el componente UpdateEscrowDialog (del bloque single-release). Si selectedEscrow.type es "multi-release", entonces debe renderizarse el componente UpdateEscrowDialog (del bloque multi-release). */}
          {shouldShowEditButton && <UpdateEscrowDialog />}

          {/* Funciona solo con escrows single-release */}
          {shouldShowDisputeButton && <DisputeEscrowButton />}

          {/* Funciona solo con escrows single-release */}
          {shouldShowResolveButton && <ResolveDisputeDialog />}

          {/* Funciona solo con escrows single-release */}
          {shouldShowReleaseFundsButton && <ReleaseEscrowButton />}
        </div>
      )}

      <FundEscrowDialog />
    </div>
  );

Configuración manual de proveedores

Envuelve tu app con los proveedores requeridos en este orden específico:

app/layout.tsx

import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import { ReactQueryClientProvider } from "@/components/tw-blocks/providers/ReactQueryClientProvider";
import { TrustlessWorkProvider } from "@/components/tw-blocks/providers/TrustlessWork";
import { WalletProvider } from "@/components/tw-blocks/wallet-kit/WalletProvider";
import { EscrowProvider } from "@/components/tw-blocks/providers/EscrowProvider";
import { EscrowDialogsProvider } from "@/components/tw-blocks/providers/EscrowDialogsProvider";
import { EscrowAmountProvider } from "@/components/tw-blocks/providers/EscrowAmountProvider";
import { Toaster } from "@/components/ui/sonner";

const geistSans = Geist({
  variable: "--font-geist-sans",
  subsets: ["latin"],
});

const geistMono = Geist_Mono({
  variable: "--font-geist-mono",
  subsets: ["latin"],
});

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body
        // opcional: usa geistSans.variable y geistMono.variable
        className="antialiased"
      >
        <ReactQueryClientProvider>
          <TrustlessWorkProvider>
            <WalletProvider>
              <EscrowProvider>
                <EscrowDialogsProvider>
                  <EscrowAmountProvider>
                    {children}

                    <Toaster />
                  </EscrowAmountProvider>
                </EscrowDialogsProvider>
              </EscrowProvider>
            </WalletProvider>
          </TrustlessWorkProvider>
        </ReactQueryClientProvider>
      </body>
    </html>
  );
}

El orden de los proveedores importaLos proveedores deben anidarse en este orden exacto para un funcionamiento correcto.

Ejemplo de uso en una página:

Ahora, puedes interactuar con todo el ciclo de vida del escrow.

app/page.tsx

"use client";

import { EscrowsByRoleCards } from "@/components/tw-blocks/escrows/escrows-by-role/cards/EscrowsCards";
import { InitializeEscrowDialog } from "@/components/tw-blocks/escrows/single-release/initialize-escrow/dialog/InitializeEscrow";
import { WalletButton } from "@/components/tw-blocks/wallet-kit/WalletButtons";

export default function Home() {
  return (
    <div className="font-sans grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20">
      <header className="flex justify-between items-center w-full">
        <h2 className="text-2xl font-bold">Trustless Work</h2>
        <WalletButton />
      </header>
      <main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start">
        <div className="container">
          <div className="flex w-full mb-4 justify-end">
            <div className="flex w-1/6">
              <InitializeEscrowDialog />
            </div>
          </div>

          <EscrowsByRoleCards />
        </div>
      </main>
    </div>
  );
}

Todos los bloques fueron agregados, ¡ahora úsalos!Ya tienes todos los bloques requeridos para comenzar a usar el ciclo de vida de escrow single-release.

UI final

Al usar estos componentes, podrás completar todo el ciclo de vida del escrow.

Consejo importante de uso- Estos componentes de tarjetas funcionan por rol. En la sección de filtros, puedes seleccionar el rol para el que quieres ver los escrows. En base a eso, se renderizarán los botones de acciones. - Antes de empezar a usar la UI, debes agregar el USDC activo a tu billetera. Si no, no podrás interactuar con Trustless Work.

Diálogo de conexión de billetera

Muestra el diálogo de conexión de billetera:

Escrow Lifecycle

Tarjetas por rol

Muestra las tarjetas por rol:

Escrow Lifecycle

Diálogo de inicializar escrow

Muestra el diálogo de inicializar escrow:

Escrow Lifecycle

Diálogo de detalles del escrow

Muestra el diálogo de detalles del escrow:

Escrow Lifecycle

La forma más fácil de implementar escrows en blockchain."

Última actualización

¿Te fue útil?