Servicios
Establecimos un servicio único y genérico para interactuar con la API de Trustless Work.
Resumen
Con el fin de tener un código de buena calidad y limpio, hemos generado un servicio genérico que interactúa con Trustless Work.
Servicio genérico de escrow
Cada respuesta y payload están completamente tipados con las entidades que habíamos definido antes.
import http from "@/config/axios";
import { AxiosError } from "axios";
import { signTransaction } from "../../auth/helpers/stellar-wallet-kit.helper";
import { handleError } from "@/errors/utils/handle-errors";
import { WalletError } from "@/@types/errors.entity";
import { kit } from "@/config/wallet-kit";
import { EscrowRequestResponse } from "@/@types/escrows/escrow-response.entity";
import { EscrowPayloadService } from "@/@types/escrows/escrow-payload.entity";
import { Escrow } from "@/@types/escrows/escrow.entity";
import { HttpMethod } from "@/@types/http.entity";
// Interfaz que define las propiedades requeridas para las operaciones del servicio de escrow
interface EscrowServiceProps<T extends EscrowPayloadService> {
payload: T;
endpoint: string;
method: HttpMethod;
requiresSignature?: boolean;
returnEscrowDataIsRequired?: boolean;
}
/**
* La clase EscrowService maneja todas las operaciones relacionadas con escrow
* incluidos la firma de transacciones y el envío a la red Stellar
*/
export class EscrowService {
private static instance: EscrowService;
private constructor() {}
/**
* Obtener la instancia singleton de EscrowService
*/
public static getInstance(): EscrowService {
if (!EscrowService.instance) {
EscrowService.instance = new EscrowService();
}
return EscrowService.instance;
}
/**
* Manejar solicitudes GET que no requieren firma
*/
private async handleGetRequest<T extends EscrowPayloadService>(
endpoint: string,
payload: T
): Promise<EscrowRequestResponse> {
const { data } = await http.get<EscrowRequestResponse>(endpoint, {
params: payload,
});
return data;
}
/**
* Obtener la dirección de la wallet para la firma de la transacción
*/
private async getWalletAddress(): Promise<string> {
const { address } = await kit.getAddress();
return address;
}
/**
* Firmar la transacción usando la wallet
*/
private async signTransactionWithWallet(
unsignedTransaction: string,
address: string
): Promise<string> {
// Firmar la transacción usando el Stellar Wallet Kit
return await signTransaction({ unsignedTransaction, address });
}
/**
* Enviar la transacción firmada a la red
*/
private async sendSignedTransaction(
signedXdr: string,
returnEscrowDataIsRequired: boolean
): Promise<EscrowRequestResponse> {
const tx = await http.post("/helper/send-transaction", {
signedXdr,
returnEscrowDataIsRequired,
});
return tx.data;
}
/**
*
* Método principal para manejar las operaciones de escrow
*
* @Reference URL: https://surli.cc/rlyqso
*
* @Flow:
* 1. Obtener la dirección de la wallet
* 2. Hacer la solicitud inicial para obtener [transacción sin firmar]
* 3. [Firmar la transacción] con la wallet
* 4. Enviar la [transacción firmada] a la red
* 5. Devolver [datos del escrow]
*
* @Nota:
* - Este método maneja tanto solicitudes GET como POST
* - También maneja la firma de transacciones
* - Devuelve los datos del escrow si se requieren
* - Maneja tanto errores HTTP como de Wallet
*
*/
public async execute<T extends EscrowPayloadService>({
payload,
endpoint,
method,
requiresSignature = true,
returnEscrowDataIsRequired = true,
}: EscrowServiceProps<T>): Promise<EscrowRequestResponse | Escrow> {
try {
// Manejar solicitudes GET que no requieren firma
if (!requiresSignature && method === "get") {
return await this.handleGetRequest(endpoint, payload);
}
// Obtener la dirección de la wallet y hacer la solicitud inicial
const address = await this.getWalletAddress();
const response = await http[method]<EscrowRequestResponse>(
endpoint,
payload
);
const { unsignedTransaction } = response.data;
// Validar que recibimos una transacción sin firmar
if (!unsignedTransaction) {
throw new Error("No unsigned transaction received from the server");
}
// Firmar y enviar la transacción
const signedTxXdr = await this.signTransactionWithWallet(
unsignedTransaction,
dirección
);
// Enviar la transacción firmada a la red
return await this.sendSignedTransaction(
signedTxXdr,
returnEscrowDataIsRequired
);
} catch (error: unknown) {
const mappedError = handleError(error as AxiosError | WalletError);
console.error("Error:", mappedError.message);
throw new Error(mappedError.message);
}
}
}
// Exportar una instancia singleton para un acceso fácil
export const escrowService = EscrowService.getInstance();
Este servicio será usado en los hooks personalizados donde enviamos envíos con los formularios adaptados a cada endpoint de Trustless Work.
Última actualización
¿Te fue útil?