Complete reference for all Trustless Work React SDK hooks with detailed usage examples.
Deploy and initialize an escrow contract.
import { useInitializeEscrow } from "@trustless-work/escrow/hooks";
import { InitializeSingleReleaseEscrowPayload, InitializeMultiReleaseEscrowPayload } from "@trustless-work/escrow/types";
const { deployEscrow } = useInitializeEscrow();
// Returns unsigned transaction
const { unsignedTransaction } = await deployEscrow(payload, "multi-release");
// or
const { unsignedTransaction } = await deployEscrow(payload, "single-release");Builds and returns an unsigned transaction based on the provided payload.
Parameters:
- type:
"multi-release"or"single-release"- Escrow type (must match payload type) - payload:
InitializeSingleReleaseEscrowPayloadorInitializeMultiReleaseEscrowPayload
Return Value:
unsignedTransaction: Object representing the constructed transaction, ready to be signed
import {
useInitializeEscrow,
useSendTransaction,
} from "@trustless-work/escrow/hooks";
import {
InitializeMultiReleaseEscrowPayload,
InitializeSingleReleaseEscrowPayload
} from "@trustless-work/escrow/types";
export const useInitializeEscrowForm = () => {
const { deployEscrow } = useInitializeEscrow();
const { sendTransaction } = useSendTransaction();
const onSubmit = async (
payload: InitializeSingleReleaseEscrowPayload | InitializeMultiReleaseEscrowPayload
) => {
try {
// Step 1: Get unsigned transaction
const { unsignedTransaction } = await deployEscrow(
payload,
"multi-release" // or "single-release"
);
if (!unsignedTransaction) {
throw new Error("Unsigned transaction is missing from deployEscrow response.");
}
// Step 2: Sign transaction
const signedXdr = await signTransaction({
unsignedTransaction,
address: walletAddress || "",
});
if (!signedXdr) {
throw new Error("Signed transaction is missing.");
}
// Step 3: Send transaction
const data = await sendTransaction(signedXdr);
if (data.status === "SUCCESS") {
toast.success("Escrow Created");
// data contains: { status, message, contractId, escrow }
}
} catch (error: unknown) {
// Handle error
}
};
};Deposit funds into an existing escrow contract.
import { useFundEscrow } from "@trustless-work/escrow/hooks";
import { FundEscrowPayload } from "@trustless-work/escrow/types";
const { fundEscrow } = useFundEscrow();
const { unsignedTransaction } = await fundEscrow(payload, "multi-release");Returns an unsigned transaction based on the provided payload.
Parameters:
- type:
"multi-release"or"single-release"- Escrow type - payload:
FundEscrowPayload- Applicable for both escrow types
Return Value:
unsignedTransaction: Object ready to be signed and broadcast
import {
useFundEscrow,
useSendTransaction,
} from "@trustless-work/escrow/hooks";
import { FundEscrowPayload } from "@trustless-work/escrow/types";
export const useFundEscrowForm = () => {
const { fundEscrow } = useFundEscrow();
const { sendTransaction } = useSendTransaction();
const onSubmit = async (payload: FundEscrowPayload) => {
try {
const { unsignedTransaction } = await fundEscrow(
payload,
"multi-release"
);
if (!unsignedTransaction) {
throw new Error("Unsigned transaction is missing from fundEscrow response.");
}
const signedXdr = await signTransaction({
unsignedTransaction,
address: walletAddress || "",
});
const data = await sendTransaction(signedXdr);
if (data.status === "SUCCESS") {
toast.success("Escrow Funded");
}
} catch (error: unknown) {
// Handle error
}
};
};Update the custom status of a milestone (service provider action).
import { useChangeMilestoneStatus } from "@trustless-work/escrow/hooks";
import { ChangeMilestoneStatusPayload } from "@trustless-work/escrow/types";
const { changeMilestoneStatus } = useChangeMilestoneStatus();
const { unsignedTransaction } = await changeMilestoneStatus(payload, "multi-release");Returns an unsigned transaction based on the provided payload.
Parameters:
- type:
"multi-release"or"single-release"- Escrow type (must match payload) - payload:
ChangeMilestoneStatusPayload- Applicable for both escrow types
Return Value:
unsignedTransaction: Object ready to be signed and broadcast
import {
useChangeMilestoneStatus,
useSendTransaction,
} from "@trustless-work/escrow/hooks";
import { ChangeMilestoneStatusPayload } from "@trustless-work/escrow/types";
export const useChangeMilestoneStatusForm = () => {
const { changeMilestoneStatus } = useChangeMilestoneStatus();
const { sendTransaction } = useSendTransaction();
const onSubmit = async (payload: ChangeMilestoneStatusPayload) => {
try {
const { unsignedTransaction } = await changeMilestoneStatus(
payload,
"multi-release"
);
if (!unsignedTransaction) {
throw new Error("Unsigned transaction is missing.");
}
const signedXdr = await signTransaction({
unsignedTransaction,
address: walletAddress || "",
});
const data = await sendTransaction(signedXdr);
if (data.status === "SUCCESS") {
toast.success(
`Milestone index - ${payload.milestoneIndex} updated to ${payload.newStatus}`
);
}
} catch (error: unknown) {
// Handle error
}
};
};Approve a milestone for release (approver action).
import { useApproveMilestone } from "@trustless-work/escrow/hooks";
import { ApproveMilestonePayload } from "@trustless-work/escrow/types";
const { approveMilestone, isPending, isError, isSuccess } = useApproveMilestone();
const { unsignedTransaction } = await approveMilestone(payload, "multi-release");Returns an unsigned transaction based on the provided payload.
Status Flags:
isPending: Operation in progressisError: Operation failedisSuccess: Operation completed successfully
Parameters:
- type:
"multi-release"or"single-release"- Escrow type (must match payload) - payload:
ApproveMilestonePayload- Applicable for both escrow types
Return Value:
unsignedTransaction: Object ready to be signed and broadcast
import {
useApproveMilestone,
useSendTransaction,
} from "@trustless-work/escrow/hooks";
import { ApproveMilestonePayload } from "@trustless-work/escrow/types";
export const useApproveMilestoneForm = () => {
const { approveMilestone } = useApproveMilestone();
const { sendTransaction } = useSendTransaction();
const onSubmit = async (payload: ApproveMilestonePayload) => {
try {
const { unsignedTransaction } = await approveMilestone(
payload,
"multi-release"
);
if (!unsignedTransaction) {
throw new Error("Unsigned transaction is missing from approveMilestone response.");
}
const signedXdr = await signTransaction({
unsignedTransaction,
address: walletAddress || "",
});
const data = await sendTransaction(signedXdr);
if (data.status === "SUCCESS") {
toast.success(
`Milestone index - ${payload.milestoneIndex} has been approved`
);
}
} catch (error: unknown) {
// Handle error
}
};
};Release escrow funds to the service provider.
import { useReleaseFunds } from "@trustless-work/escrow/hooks";
import { SingleReleaseReleaseFundsPayload, MultiReleaseReleaseFundsPayload } from "@trustless-work/escrow/types";
const { releaseFunds } = useReleaseFunds();
// Single-release
const { unsignedTransaction } = await releaseFunds(payload, "single-release");
// Multi-release (per milestone)
const { unsignedTransaction } = await releaseFunds(payload, "multi-release");Builds and returns an unsigned transaction based on the provided payload.
Parameters:
- type:
"multi-release"or"single-release"- Escrow type (must match payload) - payload:
SingleReleaseReleaseFundsPayloadorMultiReleaseReleaseFundsPayload
Return Value:
unsignedTransaction: Object ready to be signed and broadcast
import {
useReleaseFunds,
useSendTransaction,
} from "@trustless-work/escrow/hooks";
import {
SingleReleaseReleaseFundsPayload,
MultiReleaseReleaseFundsPayload
} from "@trustless-work/escrow/types";
export const useReleaseFundsForm = () => {
const { releaseFunds } = useReleaseFunds();
const { sendTransaction } = useSendTransaction();
const onSubmit = async (
payload: MultiReleaseReleaseFundsPayload | SingleReleaseReleaseFundsPayload
) => {
try {
const { unsignedTransaction } = await releaseFunds(
payload,
"multi-release"
);
if (!unsignedTransaction) {
throw new Error("Unsigned transaction is missing from useReleaseFunds.");
}
const signedXdr = await signTransaction({
unsignedTransaction,
address: walletAddress || "",
});
const data = await sendTransaction(signedXdr);
if (data.status === "SUCCESS") {
toast.success("The escrow has been released");
}
} catch (error: unknown) {
// Handle error
}
};
};Initiate a dispute for an escrow.
import { useStartDispute } from "@trustless-work/escrow/hooks";
import { SingleReleaseStartDisputePayload, MultiReleaseStartDisputePayload } from "@trustless-work/escrow/types";
const { startDispute } = useStartDispute();
// Single-release (disputes entire escrow)
const { unsignedTransaction } = await startDispute(payload, "single-release");
// Multi-release (disputes specific milestone)
const { unsignedTransaction } = await startDispute(payload, "multi-release");Builds and returns an unsigned transaction based on the provided payload.
Parameters:
- type:
"multi-release"or"single-release"- Escrow type (must match payload) - payload:
SingleReleaseStartDisputePayloadorMultiReleaseStartDisputePayload
Return Value:
unsignedTransaction: Object ready to be signed and broadcast
import {
useStartDispute,
useSendTransaction,
} from "@trustless-work/escrow/hooks";
import {
SingleReleaseStartDisputePayload,
MultiReleaseStartDisputePayload
} from "@trustless-work/escrow/types";
export const useStartDisputeForm = () => {
const { startDispute } = useStartDispute();
const { sendTransaction } = useSendTransaction();
const onSubmit = async (
payload: SingleReleaseStartDisputePayload | MultiReleaseStartDisputePayload
) => {
try {
const { unsignedTransaction } = await startDispute(
payload,
"multi-release"
);
if (!unsignedTransaction) {
throw new Error("Unsigned transaction is missing from startDispute.");
}
const signedXdr = await signTransaction({
unsignedTransaction,
address: walletAddress || "",
});
const data = await sendTransaction(signedXdr);
if (data.status === "SUCCESS") {
toast.success("Dispute Started");
}
} catch (error: unknown) {
// Handle error
}
};
};Resolve a dispute by distributing funds.
import { useResolveDispute } from "@trustless-work/escrow/hooks";
import { MultiReleaseResolveDisputePayload, SingleReleaseResolveDisputePayload } from "@trustless-work/escrow/types";
const { resolveDispute } = useResolveDispute();
const { unsignedTransaction } = await resolveDispute(payload, "multi-release");Builds and returns an unsigned transaction based on the provided payload.
Parameters:
- type:
"multi-release"or"single-release"- Escrow type (must match payload) - payload:
SingleReleaseResolveDisputePayloadorMultiReleaseResolveDisputePayload
Return Value:
unsignedTransaction: Object ready to be signed and broadcast
import {
useResolveDispute,
useSendTransaction,
} from "@trustless-work/escrow/hooks";
import {
MultiReleaseResolveDisputePayload,
SingleReleaseResolveDisputePayload
} from "@trustless-work/escrow/types";
export const useResolveDisputeForm = () => {
const { resolveDispute } = useResolveDispute();
const { sendTransaction } = useSendTransaction();
const onSubmit = async (
payload: MultiReleaseResolveDisputePayload | SingleReleaseResolveDisputePayload
) => {
try {
const { unsignedTransaction } = await resolveDispute(
payload,
"multi-release"
);
if (!unsignedTransaction) {
throw new Error("Unsigned transaction is missing from resolveDispute.");
}
const signedXdr = await signTransaction({
unsignedTransaction,
address: walletAddress || "",
});
const data = await sendTransaction(signedXdr);
if (data.status === "SUCCESS") {
toast.success("Dispute Resolved");
}
} catch (error: unknown) {
// Handle error
}
};
};Update escrow properties (title, description, milestones, etc.).
import { useUpdateEscrow } from "@trustless-work/escrow/hooks";
import { UpdateSingleReleaseEscrowPayload, UpdateMultiReleaseEscrowPayload } from "@trustless-work/escrow/types";
const { updateEscrow } = useUpdateEscrow();
const { unsignedTransaction } = await updateEscrow(payload, "multi-release");Builds and returns an unsigned transaction based on the provided payload.
Parameters:
- type:
"multi-release"or"single-release"- Escrow type (must match payload) - payload:
UpdateSingleReleaseEscrowPayloadorUpdateMultiReleaseEscrowPayload
Return Value:
unsignedTransaction: Object ready to be signed and broadcast
import {
useUpdateEscrow,
useSendTransaction,
} from "@trustless-work/escrow/hooks";
import {
UpdateSingleReleaseEscrowPayload,
UpdateMultiReleaseEscrowPayload
} from "@trustless-work/escrow/types";
export const useUpdateEscrowForm = () => {
const { updateEscrow } = useUpdateEscrow();
const { sendTransaction } = useSendTransaction();
const onSubmit = async (
payload: UpdateSingleReleaseEscrowPayload | UpdateMultiReleaseEscrowPayload
) => {
try {
const { unsignedTransaction } = await updateEscrow(
payload,
"multi-release"
);
if (!unsignedTransaction) {
throw new Error("Unsigned transaction is missing from updateEscrow response.");
}
const signedXdr = await signTransaction({
unsignedTransaction,
address: walletAddress || "",
});
const data = await sendTransaction(signedXdr);
if (data.status === "SUCCESS") {
toast.success("Escrow Updated");
}
} catch (error: unknown) {
// Handle error
}
};
};Withdraw remaining funds from a multi-release escrow (after completion or resolution).
import { useWithdrawRemainingFunds } from "@trustless-work/escrow/hooks";
import { WithdrawRemainingFundsPayload } from "@trustless-work/escrow/types";
const { withdrawRemainingFunds } = useWithdrawRemainingFunds();
// Only works with multi-release escrows
const { unsignedTransaction } = await withdrawRemainingFunds(payload);Builds and returns an unsigned transaction based on the provided payload.
Important: Only allows multi-release escrows.
Parameters:
- payload:
WithdrawRemainingFundsPayload- Contains distributions array
Return Value:
unsignedTransaction: Object ready to be signed and broadcast
import {
useWithdrawRemainingFunds,
useSendTransaction,
} from "@trustless-work/escrow/hooks";
import { WithdrawRemainingFundsPayload } from "@trustless-work/escrow/types";
export const useWithdrawRemainingFundsForm = () => {
const { withdrawRemainingFunds } = useWithdrawRemainingFunds();
const { sendTransaction } = useSendTransaction();
const onSubmit = async (payload: WithdrawRemainingFundsPayload) => {
try {
const { unsignedTransaction } = await withdrawRemainingFunds(payload);
if (!unsignedTransaction) {
throw new Error("Unsigned transaction is missing from withdrawRemainingFunds.");
}
const signedXdr = await signTransaction({
unsignedTransaction,
address: walletAddress || "",
});
const data = await sendTransaction(signedXdr);
if (data.status === "SUCCESS") {
toast.success("Withdrawal successful");
}
} catch (error: unknown) {
// Handle error
}
};
};Send a signed transaction to the network. Must be used after all mutation hooks.
{% hint style="info" %} This endpoint must be used for all endpoints after executing them, except:
getEscrowBalancesgetEscrowsByContractIdgetEscrowsByRolegetEscrowsBySigner{% endhint %}
import { useSendTransaction } from "@trustless-work/escrow/hooks";
const { sendTransaction } = useSendTransaction();
// signedXdr is a string from wallet.signTransaction()
const data = await sendTransaction(signedXdr);Sends a signed transaction to the network and returns the response.
Parameters:
- payload:
string- Signed XDR transaction from wallet
Return Value:
For: Fund Escrow, Resolve Dispute, Change Milestone Status, Start Dispute, Release Funds:
SendTransactionResponsewithstatusandmessage
For: Initialize Escrow:
SendTransactionResponseorInitializeEscrowResponse(containscontractIdandescrow)
For: Update Escrow:
SendTransactionResponseorUpdateEscrowResponse(containscontractIdandescrow)
// Standard response
type SendTransactionResponse = {
status: "SUCCESS" | "FAILED";
message: string;
};
// Initialize Escrow response
type InitializeEscrowResponse = SendTransactionResponse & {
contractId: string;
escrow: SingleReleaseEscrow | MultiReleaseEscrow;
};
// Update Escrow response
type UpdateEscrowResponse = SendTransactionResponse & {
contractId: string;
escrow: SingleReleaseEscrow | MultiReleaseEscrow;
};import {
useFundEscrow,
useSendTransaction,
} from "@trustless-work/escrow/hooks";
import { FundEscrowPayload } from "@trustless-work/escrow/types";
export const useSomeEndpointForm = () => {
const { someFunction } = useSomeEndpoint();
const { sendTransaction } = useSendTransaction();
const onSubmit = async (payload: SomeEndpointPayload) => {
try {
// Step 1: Get unsigned transaction
const { unsignedTransaction } = await someFunction(payload, "multi-release");
// Step 2: Sign transaction
const signedXdr = await signTransaction({
unsignedTransaction,
address: walletAddress || "",
});
if (!signedXdr) {
throw new Error("Signed transaction is missing.");
}
// Step 3: Send transaction
const data = await sendTransaction(signedXdr);
// Handle response
if (data.status === "SUCCESS") {
toast.success("Operation successful");
}
} catch (error: unknown) {
// Handle error
}
};
};All mutation hooks follow this 3-step pattern:
- Execute hook function → Get unsigned transaction
- Sign with wallet → Create signed XDR
- Send transaction → Broadcast to network
// Step 1: Execute hook
const { unsignedTransaction } = await hookFunction(payload, escrowType);
// Step 2: Sign transaction
const signedXdr = await wallet.signTransaction({
unsignedTransaction,
address: walletAddress,
});
// Step 3: Send transaction
const response = await sendTransaction(signedXdr);Critical: The type parameter must match the payload type:
"single-release"→ UseSingleRelease*Payloadtypes"multi-release"→ UseMultiRelease*Payloadtypes
Examples:
- ✅
deployEscrow(singlePayload, "single-release") - ✅
deployEscrow(multiPayload, "multi-release") - ❌
deployEscrow(singlePayload, "multi-release")- Type mismatch!