Serviços
Definimos um serviço único e genérico para interagir com a API da Trustless Work.
Visão geral
Serviço Genérico de Escrow
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";
// Interface definindo as propriedades exigidas para operações do serviço de escrow
interface EscrowServiceProps<T extends EscrowPayloadService> {
payload: T;
endpoint: string;
method: HttpMethod;
requiresSignature?: boolean;
returnEscrowDataIsRequired?: boolean;
}
/**
* A classe EscrowService lida com todas as operações relacionadas a escrow
* incluindo a assinatura de transações e envio para a rede Stellar
*/
export class EscrowService {
private static instance: EscrowService;
private constructor() {}
/**
* Obtém a instância singleton de EscrowService
*/
public static getInstance(): EscrowService {
if (!EscrowService.instance) {
EscrowService.instance = new EscrowService();
}
return EscrowService.instance;
}
/**
* Manipula requisições GET que não requerem assinatura
*/
private async handleGetRequest<T extends EscrowPayloadService>(
endpoint: string,
payload: T
): Promise<EscrowRequestResponse> {
const { data } = await http.get<EscrowRequestResponse>(endpoint, {
params: payload,
});
return data;
}
/**
* Obtém o endereço da carteira para assinatura da transação
*/
private async getWalletAddress(): Promise<string> {
const { address } = await kit.getAddress();
return address;
}
/**
* Assina a transação usando a carteira
*/
private async signTransactionWithWallet(
unsignedTransaction: string,
address: string
): Promise<string> {
// Assina a transação usando o Stellar Wallet Kit
return await signTransaction({ unsignedTransaction, address });
}
/**
* Envia a transação assinada para a rede
*/
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 lidar com operações de escrow
*
* @Referência URL: https://surli.cc/rlyqso
*
* @Fluxo:
* 1. Obter o endereço da carteira
* 2. Fazer a requisição inicial para obter [transação não assinada]
* 3. [Assinar a transação] com a carteira
* 4. Enviar a [transação assinada] para a rede
* 5. Retornar [dados do escrow]
*
* @Note:
* - Este método lida tanto com requisições GET quanto POST
* - Ele também cuida da assinatura das transações
* - Retorna os dados do escrow se necessário
* - Trata tanto erros HTTP quanto erros da Carteira
*
*/
public async execute<T extends EscrowPayloadService>({
payload,
endpoint,
method,
requiresSignature = true,
returnEscrowDataIsRequired = true,
}: EscrowServiceProps<T>): Promise<EscrowRequestResponse | Escrow> {
try {
// Manipula requisições GET que não requerem assinatura
if (!requiresSignature && method === "get") {
return await this.handleGetRequest(endpoint, payload);
}
// Obtém o endereço da carteira e faz a requisição inicial
const address = await this.getWalletAddress();
const response = await http[method]<EscrowRequestResponse>(
endpoint,
payload
);
const { unsignedTransaction } = response.data;
// Valida que recebemos uma transação não assinada
if (!unsignedTransaction) {
throw new Error("Nenhuma transação não assinada recebida do servidor");
}
// Assina e envia a transação
const signedTxXdr = await this.signTransactionWithWallet(
unsignedTransaction,
endereço
);
// Envia a transação assinada para a rede
return await this.sendSignedTransaction(
signedTxXdr,
returnEscrowDataIsRequired
);
} catch (error: unknown) {
const mappedError = handleError(error as AxiosError | WalletError);
console.error("Erro:", mappedError.message);
throw new Error(mappedError.message);
}
}
}
// Exporta uma instância singleton para fácil acesso
export const escrowService = EscrowService.getInstance();
Atualizado