Cómo Integrarnos

Here you'll find the basic flow in order to use Trustless Work API. In this flows tutorial, we'll use as an example the integration of Trustless Work in our dApp.

  • Estamos usando la librería de Stellar Wallet Kit.

  • Estamos usando la librería de axios con una preconfiguración con la URL de Trustless Work y Bearer como token.

import axios from "axios";

const http = axios.create({
  baseURL: process.env.API_URL || "", // Trustless Work API URL
  timeout: 60000, // time
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${process.env.API_KEY}`, // Trustless Work API Key
  },
});

export default http;
  • Deberías conectar tu wallet favorita. Si te encuentras desarrollando, la recomendación es Freighter.

Stellar Wallets
  • Podrás ver la entidad del escrow en la siguiente página.

Schema

Pasos

  1. Inicia el escrow

El contrato de escrow debe ser implementado, lo cual inicia el escrow con sus metadatos.

Payload Type:

export type EscrowPayload = Omit<
  Escrow,
  "user" | "createdAt" | "updatedAt" | "id"
>;

Ejecutar Endpoint:

interface EscrowPayloadWithSigner extends EscrowPayload {
  signer?: string;
}

export const initializeEscrow = async (
  payload: EscrowPayloadWithSigner,
) => {
  try {
  
    // Get the address
    const { address } = await kit.getAddress();
  
    // Add the signer
    const payloadWithSigner: EscrowPayloadWithSigner = {
      ...payload,
      signer: address,
    };

    // Execute the endpoint
    const response = await http.post(
      "/deployer/invoke-deployer-contract",
      payloadWithSigner,
    );

    // Get the unsigned transaction hash
    const { unsignedTransaction } = response.data;

    // Sign the transaction by wallet
    const { signedTxXdr } = await signTransaction(unsignedTransaction, {
      address,
      networkPassphrase: WalletNetwork.TESTNET,
    });

    // Send the transaction to Stellar Network
    const tx = await http.post("/helper/send-transaction", {
      signedXdr: signedTxXdr,
      returnValueIsRequired: true,
    });

    const { data } = tx;

    return data;
  } catch (error: unknown) {
    // catch code ...
  }
};

Referencias:

Inicia el escrowFase de Iniciación

  1. Financiar escrow

Cada escrow debe ser financiado antes de liberar fondos o resolver disputas. Es importante aclarar que puedes financias el escrow en cualquier momento, pero para este caso, lo financiaremos desde el principio.

Payload Type:

export type FundEscrowPayload = Pick<Escrow, "amount" | "contractId"> & {
  signer: string;
};

Ejecutar Endpoint:

export const fundEscrow = async (payload: FundEscrowPayload) => {
  try {
  
    // Get the address
    const { address } = await kit.getAddress();
  
    // Execute the endpoint
    const response = await http.post("/escrow/fund-escrow", payload);

    // Get the unsigned transaction hash
    const { unsignedTransaction } = response.data;

    // Sign the transaction by wallet
    const { signedTxXdr } = await signTransaction(unsignedTransaction, {
      address,
      networkPassphrase: WalletNetwork.TESTNET,
    });

    // Send the transaction to Stellar Network
    const tx = await http.post("/helper/send-transaction", {
      signedXdr: signedTxXdr,
    });

    const { data } = tx;
    return data;
  } catch (error: unknown) {
    // catch code...
  }
};

Referencias:

Financiar EscrowFase de Financiamiento


These endpoints don't have any specific order to execute them

  1. Editar Hitos

Puedes editar los hitos en cualquier momento, pero sólo la entidad de la plataforma (platform entity) podrá hacerlo. Sólo los hitos pendientes serán editables.

Payload Type:

export type EditMilestonesPayload = {
  contractId: string;
  escrow: EscrowPayload;
  signer: string;
};

Ejecutar Endpoint:

export const editMilestones = async (payload: EditMilestonesPayload) => {
  try {
  
    // Get the address
    const { address } = await kit.getAddress();
  
    // Execute the endpoint
    const response = await http.put(
      "/escrow/update-escrow-by-contract-id",
      payload,
    );

    // Get the unsigned transaction hash
    const { unsignedTransaction } = response.data;

    // Sign the transaction by wallet
    const { signedTxXdr } = await signTransaction(unsignedTransaction, {
      address,
      networkPassphrase: WalletNetwork.TESTNET,
    });

    // Send the transaction to Stellar Network
    const tx = await http.post("/helper/send-transaction", {
      signedXdr: signedTxXdr,
    });

    const { data } = tx;
    return data;
  } catch (error: unknown) {
    // catch code...
  }
};

Referencias:

ADD REFERENCES

  1. Cambiar el estado del hito

Con este endpoint podrás cambiar el estado de los hitos, pero sólo el proveedor de servicios (service provider) podrá hacerlo.

Payload Type:

export type ChangeMilestoneStatusPayload = {
  contractId?: string;
  milestoneIndex: string;
  newStatus: MilestoneStatus; // you can custom your status
  serviceProvider?: string;
};

Ejecutar Endpoint:

export const changeMilestoneStatus = async (
  payload: ChangeMilestoneStatusPayload,
) => {
  try {
  
    // Get the address
    const { address } = await kit.getAddress();
  
    // Execute the endpoint
    const response = await http.post(
      "/escrow/change-milestone-status",
      payload,
    );

    // Get the unsigned transaction hash
    const { unsignedTransaction } = response.data;

    // Sign the transaction by wallet
    const { signedTxXdr } = await signTransaction(unsignedTransaction, {
      address,
      networkPassphrase: WalletNetwork.TESTNET,
    });

    // Send the transaction to Stellar Network
    const tx = await http.post("/helper/send-transaction", {
      signedXdr: signedTxXdr,
    });

    const { data } = tx;
    return data;
  } catch (error: unknown) {
   // catch code...
  }
};

Referencias:

Fase de CompletamientoCambiar el Estado del Hito (Milestone)

  1. Cambiar flag del hito

Con este endpoint podrás aprobar los hitos, pero sólo el aprobador (approver) podrá hacerlo.

Payload Type:

export type ChangeMilestoneFlagPayload = Omit<
  ChangeMilestoneStatusPayload,
  "serviceProvider" | "newStatus"
> & {
  approver?: string;
  newFlag: boolean;
};

Ejecutar Endpoint:

export const changeMilestoneFlag = async (
  payload: ChangeMilestoneFlagPayload,
) => {
  try {
  
    // Get the address
    const { address } = await kit.getAddress();
  
    // Execute the endpoint
    const response = await http.post(
      "/escrow/change-milestone-flag",
      payload,
    );

    // Get the unsigned transaction hash
    const { unsignedTransaction } = response.data;

    // Sign the transaction by wallet
    const { signedTxXdr } = await signTransaction(unsignedTransaction, {
      address,
      networkPassphrase: WalletNetwork.TESTNET,
    });

    // Send the transaction to Stellar Network
    const tx = await http.post("/helper/send-transaction", {
      signedXdr: signedTxXdr,
    });

    const { data } = tx;
    return data;
  } catch (error: unknown) {
   // catch code...
  }
};

Referencias:

Fase de AprobaciónCambiar el Flag del Hito (Milestone)

  1. Cambiar flag de la disputa

En cualquier momento, el aprobador (approver) o proveedor de servicio (service provider) puede iniciar una disputa. Esto no puede ser ejecutado sin fondos en el balance del escrow.

Payload Type:

export type StartDisputePayload = Pick<Escrow, "contractId"> & {
  signer: string;
};

Ejecutar Endpoint:

export const startDispute = async (
  payload: StartDisputePayload,
) => {
  try {
  
    // Get the address
    const { address } = await kit.getAddress();
  
    // Execute the endpoint
    const response = await http.post(
      "/escrow/change-dispute-flag",
      payload,
    );

    // Get the unsigned transaction hash
    const { unsignedTransaction } = response.data;

    // Sign the transaction by wallet
    const { signedTxXdr } = await signTransaction(unsignedTransaction, {
      address,
      networkPassphrase: WalletNetwork.TESTNET,
    });

    // Send the transaction to Stellar Network
    const tx = await http.post("/helper/send-transaction", {
      signedXdr: signedTxXdr,
    });

    const { data } = tx;
    return data;
  } catch (error: unknown) {
   // catch code...
  }
};

Referencias:

Cambiar Flag de Disputa


  1. Distribuir ganancias del escrow

Cuando el escrow se encuentra listo para ser liberado, puedes hacerlo con este endpoint. Sólo el firmante de la liberación (release signer) puede hacerlo.

Payload Type:

export type DistributeEscrowEarningsEscrowPayload = Pick<Escrow, "contractId"> &
  Partial<Pick<Escrow, "serviceProvider" | "releaseSigner">> & {
    signer: string;
  };

Execute Endpoint:

export const distributeEscrowEarnings = async (
  payload: DistributeEscrowEarningsEscrowPayload,
) => {
  try {
  
    // Get the address
    const { address } = await kit.getAddress();
  
    // Execute the endpoint
    const response = await http.post(
      "/escrow/distribute-escrow-earnings",
      payload,
    );

    // Get the unsigned transaction hash
    const { unsignedTransaction } = response.data;

    // Sign the transaction by wallet
    const { signedTxXdr } = await signTransaction(unsignedTransaction, {
      address,
      networkPassphrase: WalletNetwork.TESTNET,
    });

    // Send the transaction to Stellar Network
    const tx = await http.post("/helper/send-transaction", {
      signedXdr: signedTxXdr,
    });

    const { data } = tx;
    return data;
  } catch (error: unknown) {
   // catch code...
  }
};

Referencias:

Fase de LiberaciónDistribuir Ganancias del Escrow

  1. Resolver disputa

Cuando el escrow se encuentra en disputa, podrás resolverlo con este endpoint. Sólo el resolutor de disputas (dispute resolver) puede hacerlo.

Payload Type:

export type ResolveDisputePayload = Pick<Escrow, "contractId"> &
  Partial<Pick<Escrow, "disputeResolver">> & {
    approverFunds: string;
    serviceProviderFunds: string;
  };

Execute Endpoint:

export const resolveDispute = async (
  payload: ResolveDisputePayload,
) => {
  try {
  
    // Get the address
    const { address } = await kit.getAddress();
  
    // Execute the endpoint
    const response = await http.post(
      "/escrow/resolving-disputes",
      payload,
    );

    // Get the unsigned transaction hash
    const { unsignedTransaction } = response.data;

    // Sign the transaction by wallet
    const { signedTxXdr } = await signTransaction(unsignedTransaction, {
      address,
      networkPassphrase: WalletNetwork.TESTNET,
    });

    // Send the transaction to Stellar Network
    const tx = await http.post("/helper/send-transaction", {
      signedXdr: signedTxXdr,
    });

    const { data } = tx;
    return data;
  } catch (error: unknown) {
   // catch code...
  }
};

Referencias:

Resolución de DisputasResolución de Disputas

Nota importante

Todos los endpoints relacionados con la gestión de escrows devuelven la transacción sin firmar. Esto se realiza mediante una cadena en formato XDR (External Data Representation), que es el formato que Stellar utiliza para codificar transacciones. Esta cadena XDR es la que debes usar para firmar la transacción con la billetera de tu elección. Una vez firmada, la transacción se devuelve firmada en el mismo formato, es decir, como un string en formato XDR.

  • Este string es el que debe ser enviado al siguiente endpoint para que la transacción sea enviado a la red de Stellar:

Eso es todo. Gracias.

Last updated

Was this helpful?