# Serviços

## Visão geral

Para ter um código de boa qualidade e limpo, geramos um serviço genérico que interage com o Trustless Work.

## Serviço Genérico de Escrow

Cada resposta e payload são completamente tipados com as entidades que definimos anteriormente.

```typescript
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();

```

Este serviço será usado nos hooks personalizados onde enviamos submissões com os formulários adaptados a cada endpoint do Trustless Work.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.trustlesswork.com/trustless-work/v1-pt/dapps-oss/escrow-lab/servicos.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
