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@latestNavega hasta el directorio de tu proyecto:
cd my-trustless-appInstalar Trustless Work Blocks#
Instala el paquete principal de la librería:
npm
npm install @trustless-work/blocksEjecuta la configuración del CLI
Inicializa tu proyecto con el CLI de Trustless Work:
npx trustless-work initQué 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.jsonarchivo de configuraciónOpcionalmente conecta proveedores en tu Next.js
app/layout.tsx
Configuración del entorno
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_hereAgregar conectividad de billetera
Agrega conectividad de billetera a tu app:
npx trustless-work add wallet-kitEnvuelve 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 helpersAgregar Tanstack Query
Agrega Tanstack Query a tu app:
npx trustless-work add tanstackAgregar manejo de errores
Agrega Manejo de Errores a tu app:
npx trustless-work add handle-errorsAgregar proveedores (si omitiste el comando init)
Agrega Proveedores a tu app:
npx trustless-work add providersAgregar componentes de Escrows de Liberación Única
Agrega Escrows de Liberación Única a tu app:
npx trustless-work add escrows/single-releaseAgregar 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-releaseAgregar tarjetas de Escrows por Rol
Agrega Tarjetas de Escrows por Rol a tu app:
npx trustless-work add escrows/escrows-by-role/cardsImportar 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:

Tarjetas por rol
Muestra las tarjetas por rol:

Diálogo de inicializar escrow
Muestra el diálogo de inicializar escrow:

Diálogo de detalles del escrow
Muestra el diálogo de detalles del escrow:

La forma más fácil de implementar escrows en blockchain."
Última actualización
¿Te fue útil?