@trustless-work/blocks 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/package.json +1 -1
  2. package/templates/escrows/details/EscrowDetailDialog.tsx +1 -1
  3. package/templates/escrows/escrow-context/EscrowAmountProvider.tsx +3 -0
  4. package/templates/escrows/escrow-context/EscrowDialogsProvider.tsx +4 -51
  5. package/templates/escrows/escrow-context/EscrowProvider.tsx +30 -0
  6. package/templates/escrows/escrows-by-role/cards/EscrowsCards.tsx +10 -0
  7. package/templates/escrows/escrows-by-role/table/EscrowsTable.tsx +11 -0
  8. package/templates/escrows/escrows-by-role/useEscrowsByRole.shared.ts +6 -0
  9. package/templates/escrows/escrows-by-signer/cards/EscrowsCards.tsx +11 -0
  10. package/templates/escrows/escrows-by-signer/table/EscrowsTable.tsx +11 -0
  11. package/templates/escrows/escrows-by-signer/useEscrowsBySigner.shared.ts +6 -0
  12. package/templates/escrows/single-release/approve-milestone/button/ApproveMilestone.tsx +13 -0
  13. package/templates/escrows/single-release/approve-milestone/shared/useApproveMilestone.ts +13 -0
  14. package/templates/escrows/single-release/change-milestone-status/button/ChangeMilestoneStatus.tsx +15 -0
  15. package/templates/escrows/single-release/change-milestone-status/shared/useChangeMilestoneStatus.ts +13 -0
  16. package/templates/escrows/single-release/dispute-escrow/button/DisputeEscrow.tsx +12 -0
  17. package/templates/escrows/single-release/fund-escrow/button/FundEscrow.tsx +12 -0
  18. package/templates/escrows/single-release/fund-escrow/shared/useFundEscrow.ts +13 -0
  19. package/templates/escrows/single-release/initialize-escrow/shared/useInitializeEscrow.ts +17 -1
  20. package/templates/escrows/single-release/release-escrow/button/ReleaseEscrow.tsx +12 -0
  21. package/templates/escrows/single-release/resolve-dispute/button/ResolveDispute.tsx +12 -0
  22. package/templates/escrows/single-release/resolve-dispute/shared/useResolveDispute.ts +13 -0
  23. package/templates/escrows/single-release/update-escrow/shared/useUpdateEscrow.ts +13 -0
  24. package/templates/handle-errors/handle.ts +16 -0
  25. package/templates/helpers/format.helper.ts +31 -0
  26. package/templates/helpers/useCopy.ts +5 -0
  27. package/templates/providers/ReactQueryClientProvider.tsx +14 -0
  28. package/templates/tanstack/useEscrowsByRoleQuery.ts +14 -0
  29. package/templates/tanstack/useEscrowsBySignerQuery.ts +13 -0
  30. package/templates/tanstack/useEscrowsMutations.ts +36 -0
  31. package/templates/wallet-kit/trustlines.ts +7 -0
  32. package/templates/wallet-kit/validators.ts +6 -0
  33. package/templates/wallet-kit/wallet-kit.ts +13 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trustless-work/blocks",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "author": "Trustless Work",
5
5
  "keywords": [
6
6
  "react",
@@ -59,7 +59,7 @@ const EscrowDetailDialog = ({
59
59
  return (
60
60
  <>
61
61
  <Dialog open={isDialogOpen} onOpenChange={handleClose}>
62
- <DialogContent className="!w-full sm:!max-w-4xl max-h-[95vh] overflow-y-auto">
62
+ <DialogContent className="w-11/12 sm:w-3/4 h-[95vh] overflow-y-auto flex flex-col !max-w-none">
63
63
  <DialogHeader className="flex-shrink-0">
64
64
  <div className="w-full">
65
65
  <div className="flex flex-col gap-2">
@@ -37,7 +37,10 @@ export const EscrowAmountProvider = ({ children }: { children: ReactNode }) => {
37
37
 
38
38
  const setAmounts: AmountEscrowStore["setAmounts"] = useCallback(
39
39
  (totalAmount, platformFee) => {
40
+ // Trustless Work percentage
40
41
  const trustlessPercentage = 0.3;
42
+
43
+ // Receiver percentage
41
44
  const receiverPercentage = 100 - (trustlessPercentage + platformFee);
42
45
 
43
46
  setReceiverAmount((totalAmount * receiverPercentage) / 100);
@@ -10,14 +10,7 @@ export type DialogState = {
10
10
 
11
11
  export type DialogStates = {
12
12
  second: DialogState;
13
- completeMilestone: DialogState;
14
- qr: DialogState;
15
- resolveDispute: DialogState;
16
- editMilestone: DialogState;
17
- editEntities: DialogState;
18
- editBasicProperties: DialogState;
19
13
  successRelease: DialogState;
20
- successResolveDispute: DialogState;
21
14
  };
22
15
 
23
16
  export type StatusStates = {};
@@ -34,60 +27,20 @@ export function EscrowDialogsProvider({
34
27
  children: React.ReactNode;
35
28
  }) {
36
29
  const [secondOpen, setSecondOpen] = useState(false);
37
- const [completeMilestoneOpen, setCompleteMilestoneOpen] = useState(false);
38
- const [qrOpen, setQrOpen] = useState(false);
39
- const [resolveDisputeOpen, setResolveDisputeOpen] = useState(false);
40
- const [editMilestoneOpen, setEditMilestoneOpen] = useState(false);
41
- const [editEntitiesOpen, setEditEntitiesOpen] = useState(false);
42
- const [editBasicPropertiesOpen, setEditBasicPropertiesOpen] = useState(false);
43
30
  const [successReleaseOpen, setSuccessReleaseOpen] = useState(false);
44
- const [successResolveDisputeOpen, setSuccessResolveDisputeOpen] =
45
- useState(false);
46
31
 
47
32
  const value = useMemo<EscrowDialogsContextType>(
48
33
  () => ({
34
+ // Detail Escrow Dialog
49
35
  second: { isOpen: secondOpen, setIsOpen: setSecondOpen },
50
- completeMilestone: {
51
- isOpen: completeMilestoneOpen,
52
- setIsOpen: setCompleteMilestoneOpen,
53
- },
54
- qr: { isOpen: qrOpen, setIsOpen: setQrOpen },
55
- resolveDispute: {
56
- isOpen: resolveDisputeOpen,
57
- setIsOpen: setResolveDisputeOpen,
58
- },
59
- editMilestone: {
60
- isOpen: editMilestoneOpen,
61
- setIsOpen: setEditMilestoneOpen,
62
- },
63
- editEntities: {
64
- isOpen: editEntitiesOpen,
65
- setIsOpen: setEditEntitiesOpen,
66
- },
67
- editBasicProperties: {
68
- isOpen: editBasicPropertiesOpen,
69
- setIsOpen: setEditBasicPropertiesOpen,
70
- },
36
+
37
+ // Success Release Dialog
71
38
  successRelease: {
72
39
  isOpen: successReleaseOpen,
73
40
  setIsOpen: setSuccessReleaseOpen,
74
41
  },
75
- successResolveDispute: {
76
- isOpen: successResolveDisputeOpen,
77
- setIsOpen: setSuccessResolveDisputeOpen,
78
- },
79
42
  }),
80
- [
81
- secondOpen,
82
- completeMilestoneOpen,
83
- qrOpen,
84
- resolveDisputeOpen,
85
- editMilestoneOpen,
86
- editEntitiesOpen,
87
- editBasicPropertiesOpen,
88
- successReleaseOpen,
89
- successResolveDisputeOpen,
90
- ]
43
+ [secondOpen, successReleaseOpen]
91
44
  );
92
45
 
93
46
  return (
@@ -35,6 +35,9 @@ export const EscrowProvider = ({ children }: { children: ReactNode }) => {
35
35
  );
36
36
  const [userRolesInEscrow, setUserRolesInEscrowState] = useState<string[]>([]);
37
37
 
38
+ /**
39
+ * Get the selected escrow from the local storage
40
+ */
38
41
  useEffect(() => {
39
42
  try {
40
43
  const stored = localStorage.getItem(LOCAL_STORAGE_KEY);
@@ -47,6 +50,11 @@ export const EscrowProvider = ({ children }: { children: ReactNode }) => {
47
50
  }
48
51
  }, []);
49
52
 
53
+ /**
54
+ * Persist the selected escrow to the local storage
55
+ *
56
+ * @param value - The escrow to persist
57
+ */
50
58
  const persist = (value: Escrow | null) => {
51
59
  if (value) {
52
60
  localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(value));
@@ -55,6 +63,11 @@ export const EscrowProvider = ({ children }: { children: ReactNode }) => {
55
63
  }
56
64
  };
57
65
 
66
+ /**
67
+ * Update the selected escrow
68
+ *
69
+ * @param updater - The updater function
70
+ */
58
71
  const updateEscrow: EscrowContextType["updateEscrow"] = (updater) => {
59
72
  setSelectedEscrowState((current) => {
60
73
  if (!current) return current;
@@ -67,6 +80,12 @@ export const EscrowProvider = ({ children }: { children: ReactNode }) => {
67
80
  });
68
81
  };
69
82
 
83
+ /**
84
+ * Set a field of the selected escrow
85
+ *
86
+ * @param key - The key of the field to set
87
+ * @param value - The value to set
88
+ */
70
89
  const setEscrowField: EscrowContextType["setEscrowField"] = (key, value) => {
71
90
  setSelectedEscrowState((current) => {
72
91
  if (!current) return current;
@@ -76,11 +95,19 @@ export const EscrowProvider = ({ children }: { children: ReactNode }) => {
76
95
  });
77
96
  };
78
97
 
98
+ /**
99
+ * Clear the selected escrow
100
+ */
79
101
  const clearEscrow = () => {
80
102
  setSelectedEscrowState(null);
81
103
  persist(null);
82
104
  };
83
105
 
106
+ /**
107
+ * Set the user roles in the escrow
108
+ *
109
+ * @param roles - The roles to set
110
+ */
84
111
  const setUserRolesInEscrow = useCallback((roles: string[]) => {
85
112
  setUserRolesInEscrowState((prev) => {
86
113
  // Avoid unnecessary updates to prevent re-renders
@@ -94,6 +121,9 @@ export const EscrowProvider = ({ children }: { children: ReactNode }) => {
94
121
  });
95
122
  }, []);
96
123
 
124
+ /**
125
+ * Check if the user has an escrow
126
+ */
97
127
  const hasEscrow = useMemo(() => Boolean(selectedEscrow), [selectedEscrow]);
98
128
 
99
129
  return (
@@ -119,6 +119,16 @@ export function EscrowsByRoleCards() {
119
119
  dialogStates.second.setIsOpen(true);
120
120
  };
121
121
 
122
+ /**
123
+ * Based on the provided roles -> https://docs.trustlesswork.com/trustless-work/technology-overview/roles-in-trustless-work
124
+ *
125
+ * You must pass one or more roles according to requirements. Acctually it's coming from the select filter.
126
+ *
127
+ * For example:
128
+ * - If the user is a freelancer, you must pass the "serviceProvider" and "receiver" role
129
+ *
130
+ * Depending of the role, you'll have different actions buttons
131
+ */
122
132
  const activeRole: Role[] = role.split(",") as Role[];
123
133
 
124
134
  return (
@@ -202,7 +202,18 @@ export function EscrowsByRoleTable() {
202
202
  enableSortingRemoval: true,
203
203
  });
204
204
 
205
+ /**
206
+ * Based on the provided roles -> https://docs.trustlesswork.com/trustless-work/technology-overview/roles-in-trustless-work
207
+ *
208
+ * You must pass one or more roles according to requirements. Acctually it's coming from the select filter.
209
+ *
210
+ * For example:
211
+ * - If the user is a freelancer, you must pass the "serviceProvider" and "receiver" role
212
+ *
213
+ * Depending of the role, you'll have different actions buttons
214
+ */
205
215
  const activeRole: Role[] = role.split(",") as Role[];
216
+
206
217
  const escrows = data ?? [];
207
218
 
208
219
  return (
@@ -234,6 +234,12 @@ export function useEscrowsByRole() {
234
234
  dateRange,
235
235
  ]);
236
236
 
237
+ /**
238
+ * Call the query to get the escrows from the Trustless Work Indexer
239
+ *
240
+ * @param params - The parameters for the query
241
+ * @returns The query result
242
+ */
237
243
  const query = useEscrowsByRoleQuery(params);
238
244
  const nextPageQuery = useEscrowsByRoleQuery({ ...params, page: page + 1 });
239
245
 
@@ -116,7 +116,18 @@ export function EscrowsBySignerCards() {
116
116
  dialogStates.second.setIsOpen(true);
117
117
  };
118
118
 
119
+ /**
120
+ * Based on the provided roles -> https://docs.trustlesswork.com/trustless-work/technology-overview/roles-in-trustless-work
121
+ *
122
+ * You must pass one or more roles according to requirements
123
+ *
124
+ * For example:
125
+ * - If the user is a freelancer, you must pass the "serviceProvider" and "receiver" role
126
+ *
127
+ * Depending of the role, you'll have different actions buttons
128
+ */
119
129
  const activeRole: Role[] = ["approver"];
130
+
120
131
  const escrows: Escrow[] = data ?? [];
121
132
 
122
133
  return (
@@ -199,7 +199,18 @@ export function EscrowsBySignerTable() {
199
199
  enableSortingRemoval: true,
200
200
  });
201
201
 
202
+ /**
203
+ * Based on the provided roles -> https://docs.trustlesswork.com/trustless-work/technology-overview/roles-in-trustless-work
204
+ *
205
+ * You must pass one or more roles according to requirements
206
+ *
207
+ * For example:
208
+ * - If the user is a freelancer, you must pass the "serviceProvider" and "receiver" role
209
+ *
210
+ * Depending of the role, you'll have different actions buttons
211
+ */
202
212
  const activeRole: Role[] = ["approver"];
213
+
203
214
  const escrows = data ?? [];
204
215
 
205
216
  return (
@@ -221,6 +221,12 @@ export function useEscrowsBySigner() {
221
221
  dateRange,
222
222
  ]);
223
223
 
224
+ /**
225
+ * Call the query to get the escrows from the Trustless Work Indexer
226
+ *
227
+ * @param params - The parameters for the query
228
+ * @returns The query result
229
+ */
224
230
  const query = useEscrowsBySignerQuery(params);
225
231
  const nextPageQuery = useEscrowsBySignerQuery({ ...params, page: page + 1 });
226
232
 
@@ -27,6 +27,12 @@ export default function ApproveMilestoneButton({
27
27
  try {
28
28
  setIsSubmitting(true);
29
29
 
30
+ /**
31
+ * Create the payload for the approve milestone mutation
32
+ *
33
+ * @param milestoneIndex - The index of the milestone to approve
34
+ * @returns The payload for the approve milestone mutation
35
+ */
30
36
  const payload: ApproveMilestonePayload = {
31
37
  contractId: selectedEscrow?.contractId || "",
32
38
  milestoneIndex: String(milestoneIndex),
@@ -34,6 +40,13 @@ export default function ApproveMilestoneButton({
34
40
  newFlag: true,
35
41
  };
36
42
 
43
+ /**
44
+ * Call the approve milestone mutation
45
+ *
46
+ * @param payload - The payload for the approve milestone mutation
47
+ * @param type - The type of the escrow
48
+ * @param address - The address of the escrow
49
+ */
37
50
  await approveMilestone.mutateAsync({
38
51
  payload,
39
52
  type: "single-release",
@@ -31,6 +31,12 @@ export function useApproveMilestone() {
31
31
  try {
32
32
  setIsSubmitting(true);
33
33
 
34
+ /**
35
+ * Create the final payload for the approve milestone mutation
36
+ *
37
+ * @param payload - The payload from the form
38
+ * @returns The final payload for the approve milestone mutation
39
+ */
34
40
  const finalPayload: ApproveMilestonePayload = {
35
41
  contractId: selectedEscrow?.contractId || "",
36
42
  milestoneIndex: payload.milestoneIndex,
@@ -38,6 +44,13 @@ export function useApproveMilestone() {
38
44
  newFlag: true,
39
45
  };
40
46
 
47
+ /**
48
+ * Call the approve milestone mutation
49
+ *
50
+ * @param payload - The final payload for the approve milestone mutation
51
+ * @param type - The type of the escrow
52
+ * @param address - The address of the escrow
53
+ */
41
54
  await approveMilestone.mutateAsync({
42
55
  payload: finalPayload,
43
56
  type: "single-release",
@@ -36,6 +36,14 @@ export default function ChangeMilestoneStatusButton({
36
36
 
37
37
  setIsSubmitting(true);
38
38
 
39
+ /**
40
+ * Create the payload for the change milestone status mutation
41
+ *
42
+ * @param status - The status to change
43
+ * @param evidence - The evidence to change
44
+ * @param milestoneIndex - The index of the milestone to change
45
+ * @returns The payload for the change milestone status mutation
46
+ */
39
47
  const payload: ChangeMilestoneStatusPayload = {
40
48
  contractId: selectedEscrow?.contractId || "",
41
49
  milestoneIndex: String(milestoneIndex),
@@ -44,6 +52,13 @@ export default function ChangeMilestoneStatusButton({
44
52
  serviceProvider: walletAddress || "",
45
53
  };
46
54
 
55
+ /**
56
+ * Call the change milestone status mutation
57
+ *
58
+ * @param payload - The payload for the change milestone status mutation
59
+ * @param type - The type of the escrow
60
+ * @param address - The address of the escrow
61
+ */
47
62
  await changeMilestoneStatus.mutateAsync({
48
63
  payload,
49
64
  type: "single-release",
@@ -36,6 +36,12 @@ export function useChangeMilestoneStatus() {
36
36
  try {
37
37
  setIsSubmitting(true);
38
38
 
39
+ /**
40
+ * Create the final payload for the change milestone status mutation
41
+ *
42
+ * @param payload - The payload from the form
43
+ * @returns The final payload for the change milestone status mutation
44
+ */
39
45
  const finalPayload: ChangeMilestoneStatusPayload = {
40
46
  contractId: selectedEscrow?.contractId || "",
41
47
  milestoneIndex: payload.milestoneIndex,
@@ -44,6 +50,13 @@ export function useChangeMilestoneStatus() {
44
50
  serviceProvider: walletAddress || "",
45
51
  };
46
52
 
53
+ /**
54
+ * Call the change milestone status mutation
55
+ *
56
+ * @param payload - The final payload for the change milestone status mutation
57
+ * @param type - The type of the escrow
58
+ * @param address - The address of the escrow
59
+ */
47
60
  await changeMilestoneStatus.mutateAsync({
48
61
  payload: finalPayload,
49
62
  type: "single-release",
@@ -21,11 +21,23 @@ export default function DisputeEscrowButton() {
21
21
  try {
22
22
  setIsSubmitting(true);
23
23
 
24
+ /**
25
+ * Create the payload for the dispute escrow mutation
26
+ *
27
+ * @returns The payload for the dispute escrow mutation
28
+ */
24
29
  const payload: SingleReleaseStartDisputePayload = {
25
30
  contractId: selectedEscrow?.contractId || "",
26
31
  signer: walletAddress || "",
27
32
  };
28
33
 
34
+ /**
35
+ * Call the dispute escrow mutation
36
+ *
37
+ * @param payload - The payload for the dispute escrow mutation
38
+ * @param type - The type of the escrow
39
+ * @param address - The address of the escrow
40
+ */
29
41
  await startDispute.mutateAsync({
30
42
  payload,
31
43
  type: "single-release",
@@ -35,12 +35,24 @@ export default function FundEscrowButton({ amount }: FundEscrowButtonProps) {
35
35
 
36
36
  setIsSubmitting(true);
37
37
 
38
+ /**
39
+ * Create the payload for the fund escrow mutation
40
+ *
41
+ * @returns The payload for the fund escrow mutation
42
+ */
38
43
  const payload: FundEscrowPayload = {
39
44
  amount: Number(amount),
40
45
  contractId: selectedEscrow?.contractId || "",
41
46
  signer: walletAddress || "",
42
47
  };
43
48
 
49
+ /**
50
+ * Call the fund escrow mutation
51
+ *
52
+ * @param payload - The payload for the fund escrow mutation
53
+ * @param type - The type of the escrow
54
+ * @param address - The address of the escrow
55
+ */
44
56
  await fundEscrow.mutateAsync({
45
57
  payload,
46
58
  type: "single-release",
@@ -31,6 +31,12 @@ export function useFundEscrow() {
31
31
  try {
32
32
  setIsSubmitting(true);
33
33
 
34
+ /**
35
+ * Create the final payload for the fund escrow mutation
36
+ *
37
+ * @param payload - The payload from the form
38
+ * @returns The final payload for the fund escrow mutation
39
+ */
34
40
  const finalPayload: FundEscrowPayload = {
35
41
  amount:
36
42
  typeof payload.amount === "string"
@@ -40,6 +46,13 @@ export function useFundEscrow() {
40
46
  signer: walletAddress || "",
41
47
  };
42
48
 
49
+ /**
50
+ * Call the fund escrow mutation
51
+ *
52
+ * @param payload - The final payload for the fund escrow mutation
53
+ * @param type - The type of the escrow
54
+ * @param address - The address of the escrow
55
+ */
43
56
  await fundEscrow.mutateAsync({
44
57
  payload: finalPayload,
45
58
  type: "single-release",
@@ -14,12 +14,14 @@ import {
14
14
  ErrorResponse,
15
15
  handleError,
16
16
  } from "@/components/tw-blocks/handle-errors/handle";
17
+ import { useEscrowContext } from "../../../escrow-context/EscrowProvider";
17
18
 
18
19
  export function useInitializeEscrow() {
19
20
  const [isSubmitting, setIsSubmitting] = React.useState(false);
20
21
 
21
22
  const { getSingleReleaseFormSchema } = useInitializeEscrowSchema();
22
23
  const formSchema = getSingleReleaseFormSchema();
24
+ const { setSelectedEscrow } = useEscrowContext();
23
25
 
24
26
  const { walletAddress } = useWalletContext();
25
27
  const { deployEscrow } = useEscrowsMutations();
@@ -71,6 +73,12 @@ export function useInitializeEscrow() {
71
73
  try {
72
74
  setIsSubmitting(true);
73
75
 
76
+ /**
77
+ * Create the final payload for the initialize escrow mutation
78
+ *
79
+ * @param payload - The payload from the form
80
+ * @returns The final payload for the initialize escrow mutation
81
+ */
74
82
  const finalPayload: InitializeSingleReleaseEscrowPayload = {
75
83
  ...payload,
76
84
  amount:
@@ -86,6 +94,13 @@ export function useInitializeEscrow() {
86
94
  milestones: payload.milestones,
87
95
  };
88
96
 
97
+ /**
98
+ * Call the initialize escrow mutation
99
+ *
100
+ * @param payload - The final payload for the initialize escrow mutation
101
+ * @param type - The type of the escrow
102
+ * @param address - The address of the escrow
103
+ */
89
104
  const response: InitializeSingleReleaseEscrowResponse =
90
105
  (await deployEscrow.mutateAsync({
91
106
  payload: finalPayload,
@@ -93,8 +108,9 @@ export function useInitializeEscrow() {
93
108
  address: walletAddress || "",
94
109
  })) as InitializeSingleReleaseEscrowResponse;
95
110
 
96
- console.log("response", response);
97
111
  toast.success("Escrow initialized successfully");
112
+
113
+ setSelectedEscrow(response);
98
114
  } catch (error) {
99
115
  toast.error(handleError(error as ErrorResponse).message);
100
116
  } finally {
@@ -25,11 +25,23 @@ export default function ReleaseEscrowButton() {
25
25
  try {
26
26
  setIsSubmitting(true);
27
27
 
28
+ /**
29
+ * Create the payload for the release escrow mutation
30
+ *
31
+ * @returns The payload for the release escrow mutation
32
+ */
28
33
  const payload: SingleReleaseReleaseFundsPayload = {
29
34
  contractId: selectedEscrow?.contractId || "",
30
35
  releaseSigner: walletAddress || "",
31
36
  };
32
37
 
38
+ /**
39
+ * Call the release escrow mutation
40
+ *
41
+ * @param payload - The payload for the release escrow mutation
42
+ * @param type - The type of the escrow
43
+ * @param address - The address of the escrow
44
+ */
33
45
  await releaseFunds.mutateAsync({
34
46
  payload,
35
47
  type: "single-release",
@@ -44,6 +44,11 @@ export default function ResolveDisputeButton({
44
44
 
45
45
  setIsSubmitting(true);
46
46
 
47
+ /**
48
+ * Create the payload for the resolve dispute mutation
49
+ *
50
+ * @returns The payload for the resolve dispute mutation
51
+ */
47
52
  const payload: SingleReleaseResolveDisputePayload = {
48
53
  contractId: selectedEscrow?.contractId || "",
49
54
  disputeResolver: walletAddress || "",
@@ -51,6 +56,13 @@ export default function ResolveDisputeButton({
51
56
  receiverFunds: Number(receiverFunds),
52
57
  };
53
58
 
59
+ /**
60
+ * Call the resolve dispute mutation
61
+ *
62
+ * @param payload - The payload for the resolve dispute mutation
63
+ * @param type - The type of the escrow
64
+ * @param address - The address of the escrow
65
+ */
54
66
  await resolveDispute.mutateAsync({
55
67
  payload,
56
68
  type: "single-release",
@@ -32,6 +32,12 @@ export function useResolveDispute() {
32
32
  try {
33
33
  setIsSubmitting(true);
34
34
 
35
+ /**
36
+ * Create the final payload for the resolve dispute mutation
37
+ *
38
+ * @param payload - The payload from the form
39
+ * @returns The final payload for the resolve dispute mutation
40
+ */
35
41
  const finalPayload: SingleReleaseResolveDisputePayload = {
36
42
  contractId: selectedEscrow?.contractId || "",
37
43
  disputeResolver: walletAddress || "",
@@ -39,6 +45,13 @@ export function useResolveDispute() {
39
45
  receiverFunds: Number(payload.receiverFunds),
40
46
  };
41
47
 
48
+ /**
49
+ * Call the resolve dispute mutation
50
+ *
51
+ * @param payload - The final payload for the resolve dispute mutation
52
+ * @param type - The type of the escrow
53
+ * @param address - The address of the escrow
54
+ */
42
55
  await resolveDispute.mutateAsync({
43
56
  payload: finalPayload,
44
57
  type: "single-release",
@@ -140,6 +140,12 @@ export function useUpdateEscrow() {
140
140
  try {
141
141
  setIsSubmitting(true);
142
142
 
143
+ /**
144
+ * Create the final payload for the update escrow mutation
145
+ *
146
+ * @param payload - The payload from the form
147
+ * @returns The final payload for the update escrow mutation
148
+ */
143
149
  const finalPayload: UpdateSingleReleaseEscrowPayload = {
144
150
  contractId: selectedEscrow?.contractId || "",
145
151
  signer: walletAddress || "",
@@ -167,6 +173,13 @@ export function useUpdateEscrow() {
167
173
  },
168
174
  };
169
175
 
176
+ /**
177
+ * Call the update escrow mutation
178
+ *
179
+ * @param payload - The final payload for the update escrow mutation
180
+ * @param type - The type of the escrow
181
+ * @param address - The address of the escrow
182
+ */
170
183
  (await updateEscrow.mutateAsync({
171
184
  payload: finalPayload,
172
185
  type: "single-release",
@@ -10,23 +10,33 @@ export type ErrorResponse = {
10
10
 
11
11
  export type WalletError = Pick<ErrorResponse, "message" | "code">;
12
12
 
13
+ /**
14
+ * Handle the error
15
+ *
16
+ * @param error - The error
17
+ * @returns The error response
18
+ */
13
19
  export const handleError = (error: AxiosError | WalletError): ErrorResponse => {
14
20
  if (axios.isAxiosError(error)) {
15
21
  const axiosError = error as AxiosError<ErrorResponse>;
16
22
  const code = axiosError.response?.status || 500;
17
23
  const message = axiosError.response?.data?.message || error.message;
24
+
25
+ // Map the status code to the error type
18
26
  return {
19
27
  message,
20
28
  code,
21
29
  type: mapStatusCodeToErrorType(code),
22
30
  };
23
31
  } else if (error.code === -4) {
32
+ // Wallet was closed before transaction was sent
24
33
  return {
25
34
  message: "Wallet was closed before transaction was sent",
26
35
  code: -4,
27
36
  type: ApiErrorTypes.WALLET_ERROR,
28
37
  };
29
38
  } else {
39
+ // Unknown error
30
40
  return {
31
41
  message: error.message,
32
42
  code: 500,
@@ -35,6 +45,12 @@ export const handleError = (error: AxiosError | WalletError): ErrorResponse => {
35
45
  }
36
46
  };
37
47
 
48
+ /**
49
+ * Map the status code to the error type
50
+ *
51
+ * @param code - The status code
52
+ * @returns The error type
53
+ */
38
54
  const mapStatusCodeToErrorType = (code: number): ApiErrorTypes => {
39
55
  switch (code) {
40
56
  case 404:
@@ -1,7 +1,20 @@
1
+ /**
2
+ * Format the currency
3
+ *
4
+ * @param value - The value
5
+ * @param currency - The currency
6
+ * @returns The formatted currency
7
+ */
1
8
  export const formatCurrency = (value: number, currency: string) => {
2
9
  return `${currency} ${value.toFixed(2)}`;
3
10
  };
4
11
 
12
+ /**
13
+ * Format the timestamp
14
+ *
15
+ * @param ts - The timestamp
16
+ * @returns The formatted timestamp
17
+ */
5
18
  export function formatTimestamp(ts?: {
6
19
  _seconds: number;
7
20
  _nanoseconds: number;
@@ -11,10 +24,22 @@ export function formatTimestamp(ts?: {
11
24
  return d.toLocaleString();
12
25
  }
13
26
 
27
+ /**
28
+ * Format the address
29
+ *
30
+ * @param address - The address
31
+ * @returns The formatted address
32
+ */
14
33
  export function formatAddress(address: string) {
15
34
  return `${address.slice(0, 10)}...${address.slice(-4)}`;
16
35
  }
17
36
 
37
+ /**
38
+ * Format the role
39
+ *
40
+ * @param role - The role
41
+ * @returns The formatted role
42
+ */
18
43
  export function formatRole(role: string) {
19
44
  return role
20
45
  .replace(/([A-Z])/g, " $1")
@@ -22,6 +47,12 @@ export function formatRole(role: string) {
22
47
  .trim();
23
48
  }
24
49
 
50
+ /**
51
+ * Format the text
52
+ *
53
+ * @param text - The text
54
+ * @returns The formatted text
55
+ */
25
56
  export function formatText(text: string) {
26
57
  return text.charAt(0).toUpperCase() + text.slice(1);
27
58
  }
@@ -1,5 +1,10 @@
1
1
  import { useState } from "react";
2
2
 
3
+ /**
4
+ * Use copy to clipboard
5
+ *
6
+ * @returns The copied key id and the function to copy to clipboard
7
+ */
3
8
  export const useCopy = () => {
4
9
  const [copiedKeyId, setCopiedKeyId] = useState(false);
5
10
 
@@ -3,6 +3,14 @@
3
3
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
4
4
  import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
5
5
 
6
+ /**
7
+ * Query Client, you can configure the default options for the query client
8
+ *
9
+ * - Stale Time: 5 minutes
10
+ * - GC Time: 30 minutes
11
+ * - Retry: 1
12
+ * - Refetch on Window Focus: false
13
+ */
6
14
  const queryClient = new QueryClient({
7
15
  defaultOptions: {
8
16
  queries: {
@@ -14,6 +22,12 @@ const queryClient = new QueryClient({
14
22
  },
15
23
  });
16
24
 
25
+ /**
26
+ * React Query Client Provider
27
+ *
28
+ * @param children - The children
29
+ * @returns The React Query Client Provider
30
+ */
17
31
  export function ReactQueryClientProvider({
18
32
  children,
19
33
  }: {
@@ -14,6 +14,12 @@ type UseEscrowsByRoleQueryParams = Omit<
14
14
  validateOnChain?: boolean;
15
15
  };
16
16
 
17
+ /**
18
+ * Use the query to get the escrows by role
19
+ *
20
+ * @param params - The parameters for the query
21
+ * @returns The query result
22
+ */
17
23
  export const useEscrowsByRoleQuery = ({
18
24
  role,
19
25
  roleAddress,
@@ -32,6 +38,7 @@ export const useEscrowsByRoleQuery = ({
32
38
  enabled = true,
33
39
  validateOnChain = true,
34
40
  }: UseEscrowsByRoleQueryParams) => {
41
+ // Get the escrows by role
35
42
  const { getEscrowsByRole } = useGetEscrowsFromIndexerByRole();
36
43
 
37
44
  return useQuery({
@@ -57,6 +64,13 @@ export const useEscrowsByRoleQuery = ({
57
64
  if (!role) {
58
65
  throw new Error("Role is required to fetch escrows by role");
59
66
  }
67
+
68
+ /**
69
+ * Call the query to get the escrows from the Trustless Work Indexer
70
+ *
71
+ * @param params - The parameters for the query
72
+ * @returns The query result
73
+ */
60
74
  const escrows = await getEscrowsByRole({
61
75
  role,
62
76
  roleAddress,
@@ -11,6 +11,12 @@ interface UseEscrowsBySignerQueryParams
11
11
  validateOnChain?: boolean;
12
12
  }
13
13
 
14
+ /**
15
+ * Use the query to get the escrows by signer
16
+ *
17
+ * @param params - The parameters for the query
18
+ * @returns The query result
19
+ */
14
20
  export const useEscrowsBySignerQuery = ({
15
21
  signer,
16
22
  isActive,
@@ -30,6 +36,7 @@ export const useEscrowsBySignerQuery = ({
30
36
  }: UseEscrowsBySignerQueryParams) => {
31
37
  const { getEscrowsBySigner } = useGetEscrowsFromIndexerBySigner();
32
38
 
39
+ // Get the escrows by signer
33
40
  return useQuery({
34
41
  queryKey: [
35
42
  "escrows",
@@ -49,6 +56,12 @@ export const useEscrowsBySignerQuery = ({
49
56
  validateOnChain,
50
57
  ],
51
58
  queryFn: async (): Promise<Escrow[]> => {
59
+ /**
60
+ * Call the query to get the escrows from the Trustless Work Indexer
61
+ *
62
+ * @param params - The parameters for the query
63
+ * @returns The query result
64
+ */
52
65
  const escrows = await getEscrowsBySigner({
53
66
  signer,
54
67
  isActive,
@@ -26,6 +26,18 @@ import {
26
26
  } from "@trustless-work/escrow";
27
27
  import { signTransaction } from "../wallet-kit/wallet-kit";
28
28
 
29
+ /**
30
+ * Use the mutations to interact with the escrows
31
+ *
32
+ * - Deploy Escrow
33
+ * - Update Escrow
34
+ * - Fund Escrow
35
+ * - Change Milestone Status
36
+ * - Approve Milestone
37
+ * - Start Dispute
38
+ * - Release Funds
39
+ * - Resolve Dispute
40
+ */
29
41
  export const useEscrowsMutations = () => {
30
42
  const queryClient = useQueryClient();
31
43
  const { deployEscrow } = useInitializeEscrow();
@@ -38,6 +50,9 @@ export const useEscrowsMutations = () => {
38
50
  const { releaseFunds } = useReleaseFunds();
39
51
  const { resolveDispute } = useResolveDispute();
40
52
 
53
+ /**
54
+ * Deploy Escrow
55
+ */
41
56
  const deployEscrowMutation = useMutation({
42
57
  mutationFn: async ({
43
58
  payload,
@@ -83,6 +98,9 @@ export const useEscrowsMutations = () => {
83
98
  },
84
99
  });
85
100
 
101
+ /**
102
+ * Update Escrow
103
+ */
86
104
  const updateEscrowMutation = useMutation({
87
105
  mutationFn: async ({
88
106
  payload,
@@ -128,6 +146,9 @@ export const useEscrowsMutations = () => {
128
146
  },
129
147
  });
130
148
 
149
+ /**
150
+ * Fund Escrow
151
+ */
131
152
  const fundEscrowMutation = useMutation({
132
153
  mutationFn: async ({
133
154
  payload,
@@ -174,6 +195,9 @@ export const useEscrowsMutations = () => {
174
195
  },
175
196
  });
176
197
 
198
+ /**
199
+ * Approve Milestone
200
+ */
177
201
  const approveMilestoneMutation = useMutation({
178
202
  mutationFn: async ({
179
203
  payload,
@@ -217,6 +241,9 @@ export const useEscrowsMutations = () => {
217
241
  },
218
242
  });
219
243
 
244
+ /**
245
+ * Change Milestone Status
246
+ */
220
247
  const changeMilestoneStatusMutation = useMutation({
221
248
  mutationFn: async ({
222
249
  payload,
@@ -263,6 +290,9 @@ export const useEscrowsMutations = () => {
263
290
  },
264
291
  });
265
292
 
293
+ /**
294
+ * Start Dispute
295
+ */
266
296
  const startDisputeMutation = useMutation({
267
297
  mutationFn: async ({
268
298
  payload,
@@ -308,6 +338,9 @@ export const useEscrowsMutations = () => {
308
338
  },
309
339
  });
310
340
 
341
+ /**
342
+ * Release Funds
343
+ */
311
344
  const releaseFundsMutation = useMutation({
312
345
  mutationFn: async ({
313
346
  payload,
@@ -353,6 +386,9 @@ export const useEscrowsMutations = () => {
353
386
  },
354
387
  });
355
388
 
389
+ /**
390
+ * Resolve Dispute
391
+ */
356
392
  const resolveDisputeMutation = useMutation({
357
393
  mutationFn: async ({
358
394
  payload,
@@ -1,3 +1,10 @@
1
+ /**
2
+ * Trustlines | Non-Native Tokens from Stellar
3
+ *
4
+ * @description Trustlines are the tokens that are used to pay for the escrow
5
+ * @description The trustlines are filtered by the network
6
+ * @description The trustlines are filtered by the network in the trustlineOptions
7
+ */
1
8
  export const trustlines = [
2
9
  // TESTNET
3
10
  {
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Validator for the wallet address
3
+ *
4
+ * @param wallet - The wallet address
5
+ * @returns True if the wallet address is valid, false otherwise
6
+ */
1
7
  export const isValidWallet = (wallet: string) => {
2
8
  if (wallet.length !== 56 || wallet[0] !== "G") {
3
9
  return false;
@@ -6,6 +6,13 @@ import {
6
6
  FreighterModule,
7
7
  } from "@creit.tech/stellar-wallets-kit";
8
8
 
9
+ /**
10
+ * Stellar Wallet Kit
11
+ *
12
+ * @description The Stellar Wallet Kit is used to connect to the wallet
13
+ * @description The Stellar Wallet Kit is used to sign transactions
14
+ * @description The Stellar Wallet Kit is used to get the wallet address
15
+ */
9
16
  export const kit: StellarWalletsKit = new StellarWalletsKit({
10
17
  network: WalletNetwork.TESTNET,
11
18
  selectedWalletId: FREIGHTER_ID,
@@ -17,6 +24,12 @@ interface SignTransactionParams {
17
24
  address: string;
18
25
  }
19
26
 
27
+ /**
28
+ * Sign Transaction Params
29
+ *
30
+ * @param unsignedTransaction - The unsigned transaction
31
+ * @param address - The address of the wallet
32
+ */
20
33
  export const signTransaction = async ({
21
34
  unsignedTransaction,
22
35
  address,