@trustless-work/blocks 0.0.5 → 0.0.7

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 (44) hide show
  1. package/README.md +39 -13
  2. package/bin/index.js +1128 -1137
  3. package/package.json +44 -44
  4. package/templates/escrows/details/EscrowDetailDialog.tsx +3 -3
  5. package/templates/escrows/details/GeneralInformation.tsx +2 -2
  6. package/templates/escrows/details/SuccessReleaseDialog.tsx +2 -3
  7. package/templates/escrows/details/useDetailsEscrow.ts +2 -2
  8. package/templates/escrows/escrows-by-role/cards/EscrowsCards.tsx +42 -16
  9. package/templates/escrows/escrows-by-role/table/EscrowsTable.tsx +45 -18
  10. package/templates/escrows/escrows-by-role/useEscrowsByRole.shared.ts +39 -25
  11. package/templates/escrows/escrows-by-signer/cards/EscrowsCards.tsx +33 -16
  12. package/templates/escrows/escrows-by-signer/table/EscrowsTable.tsx +34 -17
  13. package/templates/escrows/escrows-by-signer/useEscrowsBySigner.shared.ts +38 -25
  14. package/templates/escrows/single-release/approve-milestone/button/ApproveMilestone.tsx +14 -1
  15. package/templates/escrows/single-release/approve-milestone/dialog/ApproveMilestone.tsx +1 -1
  16. package/templates/escrows/single-release/approve-milestone/form/ApproveMilestone.tsx +1 -1
  17. package/templates/escrows/single-release/approve-milestone/shared/useApproveMilestone.ts +14 -1
  18. package/templates/escrows/single-release/change-milestone-status/button/ChangeMilestoneStatus.tsx +16 -1
  19. package/templates/escrows/single-release/change-milestone-status/dialog/ChangeMilestoneStatus.tsx +1 -1
  20. package/templates/escrows/single-release/change-milestone-status/form/ChangeMilestoneStatus.tsx +1 -1
  21. package/templates/escrows/single-release/change-milestone-status/shared/useChangeMilestoneStatus.ts +14 -1
  22. package/templates/escrows/single-release/dispute-escrow/button/DisputeEscrow.tsx +13 -1
  23. package/templates/escrows/single-release/fund-escrow/button/FundEscrow.tsx +13 -1
  24. package/templates/escrows/single-release/fund-escrow/shared/useFundEscrow.ts +14 -1
  25. package/templates/escrows/single-release/initialize-escrow/shared/useInitializeEscrow.ts +17 -1
  26. package/templates/escrows/single-release/release-escrow/button/ReleaseEscrow.tsx +15 -3
  27. package/templates/escrows/single-release/resolve-dispute/button/ResolveDispute.tsx +13 -1
  28. package/templates/escrows/single-release/resolve-dispute/dialog/ResolveDispute.tsx +1 -1
  29. package/templates/escrows/single-release/resolve-dispute/shared/useResolveDispute.ts +14 -1
  30. package/templates/escrows/single-release/update-escrow/shared/useUpdateEscrow.ts +224 -211
  31. package/templates/handle-errors/handle.ts +16 -0
  32. package/templates/helpers/format.helper.ts +31 -0
  33. package/templates/helpers/useCopy.ts +5 -0
  34. package/templates/{escrows/escrow-context → providers}/EscrowAmountProvider.tsx +3 -0
  35. package/templates/providers/EscrowDialogsProvider.tsx +61 -0
  36. package/templates/{escrows/escrow-context → providers}/EscrowProvider.tsx +30 -0
  37. package/templates/providers/ReactQueryClientProvider.tsx +17 -1
  38. package/templates/tanstack/useEscrowsByRoleQuery.ts +14 -0
  39. package/templates/tanstack/useEscrowsBySignerQuery.ts +13 -0
  40. package/templates/tanstack/useEscrowsMutations.ts +36 -0
  41. package/templates/wallet-kit/trustlines.ts +7 -0
  42. package/templates/wallet-kit/validators.ts +6 -0
  43. package/templates/wallet-kit/wallet-kit.ts +13 -0
  44. package/templates/escrows/escrow-context/EscrowDialogsProvider.tsx +0 -108
@@ -1,211 +1,224 @@
1
- import * as React from "react";
2
- import { useForm } from "react-hook-form";
3
- import { zodResolver } from "@hookform/resolvers/zod";
4
- import { useUpdateEscrowSchema } from "./schema";
5
- import { z } from "zod";
6
- import {
7
- UpdateSingleReleaseEscrowPayload,
8
- UpdateSingleReleaseEscrowResponse,
9
- } from "@trustless-work/escrow/types";
10
- import { toast } from "sonner";
11
- import { useEscrowContext } from "../../../escrow-context/EscrowProvider";
12
- import { useWalletContext } from "@/components/tw-blocks/wallet-kit/WalletProvider";
13
- import { useEscrowsMutations } from "@/components/tw-blocks/tanstack/useEscrowsMutations";
14
- import {
15
- ErrorResponse,
16
- handleError,
17
- } from "@/components/tw-blocks/handle-errors/handle";
18
- import { GetEscrowsFromIndexerResponse } from "@trustless-work/escrow/types";
19
-
20
- export function useUpdateEscrow() {
21
- const [isSubmitting, setIsSubmitting] = React.useState(false);
22
-
23
- const { getSingleReleaseFormSchema } = useUpdateEscrowSchema();
24
- const formSchema = getSingleReleaseFormSchema();
25
-
26
- const { walletAddress } = useWalletContext();
27
- const { selectedEscrow, setSelectedEscrow } = useEscrowContext();
28
- const { updateEscrow } = useEscrowsMutations();
29
-
30
- const form = useForm<z.infer<typeof formSchema>>({
31
- resolver: zodResolver(formSchema),
32
- defaultValues: {
33
- engagementId: selectedEscrow?.engagementId || "",
34
- title: selectedEscrow?.title || "",
35
- description: selectedEscrow?.description || "",
36
- platformFee: selectedEscrow?.platformFee as unknown as
37
- | number
38
- | string
39
- | undefined,
40
- amount: selectedEscrow?.amount as unknown as number | string | undefined,
41
- receiverMemo: selectedEscrow?.receiverMemo
42
- ? String(selectedEscrow.receiverMemo)
43
- : "",
44
- trustline: {
45
- address: selectedEscrow?.trustline?.address || "",
46
- decimals: 10000000,
47
- },
48
- roles: {
49
- approver: selectedEscrow?.roles?.approver || "",
50
- serviceProvider: selectedEscrow?.roles?.serviceProvider || "",
51
- platformAddress: selectedEscrow?.roles?.platformAddress || "",
52
- receiver: selectedEscrow?.roles?.receiver || "",
53
- releaseSigner: selectedEscrow?.roles?.releaseSigner || "",
54
- disputeResolver: selectedEscrow?.roles?.disputeResolver || "",
55
- },
56
- milestones: (selectedEscrow?.milestones || []).map((m: any) => ({
57
- description: m?.description || "",
58
- })),
59
- },
60
- mode: "onChange",
61
- });
62
-
63
- React.useEffect(() => {
64
- if (!selectedEscrow) return;
65
- form.reset({
66
- engagementId: selectedEscrow?.engagementId || "",
67
- title: selectedEscrow?.title || "",
68
- description: selectedEscrow?.description || "",
69
- platformFee:
70
- (selectedEscrow?.platformFee as unknown as
71
- | number
72
- | string
73
- | undefined) || "",
74
- amount:
75
- (selectedEscrow?.amount as unknown as number | string | undefined) ||
76
- "",
77
- receiverMemo: selectedEscrow?.receiverMemo
78
- ? String(selectedEscrow.receiverMemo)
79
- : "",
80
- trustline: {
81
- address: selectedEscrow?.trustline?.address || "",
82
- decimals: 10000000,
83
- },
84
- roles: {
85
- approver: selectedEscrow?.roles?.approver || "",
86
- serviceProvider: selectedEscrow?.roles?.serviceProvider || "",
87
- platformAddress: selectedEscrow?.roles?.platformAddress || "",
88
- receiver: selectedEscrow?.roles?.receiver || "",
89
- releaseSigner: selectedEscrow?.roles?.releaseSigner || "",
90
- disputeResolver: selectedEscrow?.roles?.disputeResolver || "",
91
- },
92
- milestones: (selectedEscrow?.milestones || []).map((m: any) => ({
93
- description: m?.description || "",
94
- })),
95
- });
96
- }, [selectedEscrow, form]);
97
-
98
- const milestones = form.watch("milestones");
99
- const isAnyMilestoneEmpty = milestones.some((m) => m.description === "");
100
-
101
- const handleAddMilestone = () => {
102
- const current = form.getValues("milestones");
103
- const updated = [...current, { description: "" }];
104
- form.setValue("milestones", updated);
105
- };
106
-
107
- const handleRemoveMilestone = (index: number) => {
108
- const current = form.getValues("milestones");
109
- const updated = current.filter((_, i) => i !== index);
110
- form.setValue("milestones", updated);
111
- };
112
-
113
- const handleAmountChange = (e: React.ChangeEvent<HTMLInputElement>) => {
114
- let rawValue = e.target.value;
115
- rawValue = rawValue.replace(/[^0-9.]/g, "");
116
- if (rawValue.split(".").length > 2) rawValue = rawValue.slice(0, -1);
117
- if (rawValue.includes(".")) {
118
- const parts = rawValue.split(".");
119
- if (parts[1] && parts[1].length > 2) {
120
- rawValue = parts[0] + "." + parts[1].slice(0, 2);
121
- }
122
- }
123
- form.setValue("amount", rawValue);
124
- };
125
-
126
- const handlePlatformFeeChange = (e: React.ChangeEvent<HTMLInputElement>) => {
127
- let rawValue = e.target.value;
128
- rawValue = rawValue.replace(/[^0-9.]/g, "");
129
- if (rawValue.split(".").length > 2) rawValue = rawValue.slice(0, -1);
130
- if (rawValue.includes(".")) {
131
- const parts = rawValue.split(".");
132
- if (parts[1] && parts[1].length > 2) {
133
- rawValue = parts[0] + "." + parts[1].slice(0, 2);
134
- }
135
- }
136
- form.setValue("platformFee", rawValue);
137
- };
138
-
139
- const handleSubmit = form.handleSubmit(async (payload) => {
140
- try {
141
- setIsSubmitting(true);
142
-
143
- const finalPayload: UpdateSingleReleaseEscrowPayload = {
144
- contractId: selectedEscrow?.contractId || "",
145
- signer: walletAddress || "",
146
- escrow: {
147
- engagementId: payload.engagementId,
148
- title: payload.title,
149
- description: payload.description,
150
- platformFee:
151
- typeof payload.platformFee === "string"
152
- ? Number(payload.platformFee)
153
- : payload.platformFee,
154
- amount:
155
- typeof payload.amount === "string"
156
- ? Number(payload.amount)
157
- : payload.amount,
158
- receiverMemo: payload.receiverMemo
159
- ? Number(payload.receiverMemo)
160
- : undefined,
161
- trustline: {
162
- address: payload.trustline.address,
163
- decimals: 10000000,
164
- },
165
- roles: payload.roles as any,
166
- milestones: payload.milestones,
167
- },
168
- };
169
-
170
- (await updateEscrow.mutateAsync({
171
- payload: finalPayload,
172
- type: "single-release",
173
- address: walletAddress || "",
174
- })) as UpdateSingleReleaseEscrowResponse;
175
-
176
- if (!selectedEscrow) return;
177
-
178
- const nextSelectedEscrow: GetEscrowsFromIndexerResponse = {
179
- ...selectedEscrow,
180
- ...finalPayload.escrow,
181
- trustline: {
182
- name:
183
- selectedEscrow.trustline?.name ||
184
- (selectedEscrow.trustline?.address as string) ||
185
- "",
186
- address: finalPayload.escrow.trustline.address,
187
- decimals: finalPayload.escrow.trustline.decimals,
188
- },
189
- };
190
-
191
- setSelectedEscrow(nextSelectedEscrow);
192
- toast.success("Escrow updated successfully");
193
- } catch (error) {
194
- toast.error(handleError(error as ErrorResponse).message);
195
- } finally {
196
- setIsSubmitting(false);
197
- }
198
- });
199
-
200
- return {
201
- form,
202
- isSubmitting,
203
- milestones,
204
- isAnyMilestoneEmpty,
205
- handleSubmit,
206
- handleAddMilestone,
207
- handleRemoveMilestone,
208
- handleAmountChange,
209
- handlePlatformFeeChange,
210
- };
211
- }
1
+ import * as React from "react";
2
+ import { useForm } from "react-hook-form";
3
+ import { zodResolver } from "@hookform/resolvers/zod";
4
+ import { useUpdateEscrowSchema } from "./schema";
5
+ import { z } from "zod";
6
+ import {
7
+ UpdateSingleReleaseEscrowPayload,
8
+ UpdateSingleReleaseEscrowResponse,
9
+ } from "@trustless-work/escrow/types";
10
+ import { toast } from "sonner";
11
+ import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvider";
12
+ import { useWalletContext } from "@/components/tw-blocks/wallet-kit/WalletProvider";
13
+ import { useEscrowsMutations } from "@/components/tw-blocks/tanstack/useEscrowsMutations";
14
+ import {
15
+ ErrorResponse,
16
+ handleError,
17
+ } from "@/components/tw-blocks/handle-errors/handle";
18
+ import { GetEscrowsFromIndexerResponse } from "@trustless-work/escrow/types";
19
+
20
+ export function useUpdateEscrow() {
21
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
22
+
23
+ const { getSingleReleaseFormSchema } = useUpdateEscrowSchema();
24
+ const formSchema = getSingleReleaseFormSchema();
25
+
26
+ const { walletAddress } = useWalletContext();
27
+ const { selectedEscrow, setSelectedEscrow } = useEscrowContext();
28
+ const { updateEscrow } = useEscrowsMutations();
29
+
30
+ const form = useForm<z.infer<typeof formSchema>>({
31
+ resolver: zodResolver(formSchema),
32
+ defaultValues: {
33
+ engagementId: selectedEscrow?.engagementId || "",
34
+ title: selectedEscrow?.title || "",
35
+ description: selectedEscrow?.description || "",
36
+ platformFee: selectedEscrow?.platformFee as unknown as
37
+ | number
38
+ | string
39
+ | undefined,
40
+ amount: selectedEscrow?.amount as unknown as number | string | undefined,
41
+ receiverMemo: selectedEscrow?.receiverMemo
42
+ ? String(selectedEscrow.receiverMemo)
43
+ : "",
44
+ trustline: {
45
+ address: selectedEscrow?.trustline?.address || "",
46
+ decimals: 10000000,
47
+ },
48
+ roles: {
49
+ approver: selectedEscrow?.roles?.approver || "",
50
+ serviceProvider: selectedEscrow?.roles?.serviceProvider || "",
51
+ platformAddress: selectedEscrow?.roles?.platformAddress || "",
52
+ receiver: selectedEscrow?.roles?.receiver || "",
53
+ releaseSigner: selectedEscrow?.roles?.releaseSigner || "",
54
+ disputeResolver: selectedEscrow?.roles?.disputeResolver || "",
55
+ },
56
+ milestones: (selectedEscrow?.milestones || []).map((m: any) => ({
57
+ description: m?.description || "",
58
+ })),
59
+ },
60
+ mode: "onChange",
61
+ });
62
+
63
+ React.useEffect(() => {
64
+ if (!selectedEscrow) return;
65
+ form.reset({
66
+ engagementId: selectedEscrow?.engagementId || "",
67
+ title: selectedEscrow?.title || "",
68
+ description: selectedEscrow?.description || "",
69
+ platformFee:
70
+ (selectedEscrow?.platformFee as unknown as
71
+ | number
72
+ | string
73
+ | undefined) || "",
74
+ amount:
75
+ (selectedEscrow?.amount as unknown as number | string | undefined) ||
76
+ "",
77
+ receiverMemo: selectedEscrow?.receiverMemo
78
+ ? String(selectedEscrow.receiverMemo)
79
+ : "",
80
+ trustline: {
81
+ address: selectedEscrow?.trustline?.address || "",
82
+ decimals: 10000000,
83
+ },
84
+ roles: {
85
+ approver: selectedEscrow?.roles?.approver || "",
86
+ serviceProvider: selectedEscrow?.roles?.serviceProvider || "",
87
+ platformAddress: selectedEscrow?.roles?.platformAddress || "",
88
+ receiver: selectedEscrow?.roles?.receiver || "",
89
+ releaseSigner: selectedEscrow?.roles?.releaseSigner || "",
90
+ disputeResolver: selectedEscrow?.roles?.disputeResolver || "",
91
+ },
92
+ milestones: (selectedEscrow?.milestones || []).map((m: any) => ({
93
+ description: m?.description || "",
94
+ })),
95
+ });
96
+ }, [selectedEscrow, form]);
97
+
98
+ const milestones = form.watch("milestones");
99
+ const isAnyMilestoneEmpty = milestones.some((m) => m.description === "");
100
+
101
+ const handleAddMilestone = () => {
102
+ const current = form.getValues("milestones");
103
+ const updated = [...current, { description: "" }];
104
+ form.setValue("milestones", updated);
105
+ };
106
+
107
+ const handleRemoveMilestone = (index: number) => {
108
+ const current = form.getValues("milestones");
109
+ const updated = current.filter((_, i) => i !== index);
110
+ form.setValue("milestones", updated);
111
+ };
112
+
113
+ const handleAmountChange = (e: React.ChangeEvent<HTMLInputElement>) => {
114
+ let rawValue = e.target.value;
115
+ rawValue = rawValue.replace(/[^0-9.]/g, "");
116
+ if (rawValue.split(".").length > 2) rawValue = rawValue.slice(0, -1);
117
+ if (rawValue.includes(".")) {
118
+ const parts = rawValue.split(".");
119
+ if (parts[1] && parts[1].length > 2) {
120
+ rawValue = parts[0] + "." + parts[1].slice(0, 2);
121
+ }
122
+ }
123
+ form.setValue("amount", rawValue);
124
+ };
125
+
126
+ const handlePlatformFeeChange = (e: React.ChangeEvent<HTMLInputElement>) => {
127
+ let rawValue = e.target.value;
128
+ rawValue = rawValue.replace(/[^0-9.]/g, "");
129
+ if (rawValue.split(".").length > 2) rawValue = rawValue.slice(0, -1);
130
+ if (rawValue.includes(".")) {
131
+ const parts = rawValue.split(".");
132
+ if (parts[1] && parts[1].length > 2) {
133
+ rawValue = parts[0] + "." + parts[1].slice(0, 2);
134
+ }
135
+ }
136
+ form.setValue("platformFee", rawValue);
137
+ };
138
+
139
+ const handleSubmit = form.handleSubmit(async (payload) => {
140
+ try {
141
+ setIsSubmitting(true);
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
+ */
149
+ const finalPayload: UpdateSingleReleaseEscrowPayload = {
150
+ contractId: selectedEscrow?.contractId || "",
151
+ signer: walletAddress || "",
152
+ escrow: {
153
+ engagementId: payload.engagementId,
154
+ title: payload.title,
155
+ description: payload.description,
156
+ platformFee:
157
+ typeof payload.platformFee === "string"
158
+ ? Number(payload.platformFee)
159
+ : payload.platformFee,
160
+ amount:
161
+ typeof payload.amount === "string"
162
+ ? Number(payload.amount)
163
+ : payload.amount,
164
+ receiverMemo: payload.receiverMemo
165
+ ? Number(payload.receiverMemo)
166
+ : undefined,
167
+ trustline: {
168
+ address: payload.trustline.address,
169
+ decimals: 10000000,
170
+ },
171
+ roles: payload.roles as any,
172
+ milestones: payload.milestones,
173
+ },
174
+ };
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
+ */
183
+ (await updateEscrow.mutateAsync({
184
+ payload: finalPayload,
185
+ type: "single-release",
186
+ address: walletAddress || "",
187
+ })) as UpdateSingleReleaseEscrowResponse;
188
+
189
+ if (!selectedEscrow) return;
190
+
191
+ const nextSelectedEscrow: GetEscrowsFromIndexerResponse = {
192
+ ...selectedEscrow,
193
+ ...finalPayload.escrow,
194
+ trustline: {
195
+ name:
196
+ selectedEscrow.trustline?.name ||
197
+ (selectedEscrow.trustline?.address as string) ||
198
+ "",
199
+ address: finalPayload.escrow.trustline.address,
200
+ decimals: finalPayload.escrow.trustline.decimals,
201
+ },
202
+ };
203
+
204
+ setSelectedEscrow(nextSelectedEscrow);
205
+ toast.success("Escrow updated successfully");
206
+ } catch (error) {
207
+ toast.error(handleError(error as ErrorResponse).message);
208
+ } finally {
209
+ setIsSubmitting(false);
210
+ }
211
+ });
212
+
213
+ return {
214
+ form,
215
+ isSubmitting,
216
+ milestones,
217
+ isAnyMilestoneEmpty,
218
+ handleSubmit,
219
+ handleAddMilestone,
220
+ handleRemoveMilestone,
221
+ handleAmountChange,
222
+ handlePlatformFeeChange,
223
+ };
224
+ }
@@ -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
 
@@ -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);
@@ -0,0 +1,61 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { createContext, useContext, useMemo, useState } from "react";
5
+
6
+ export type DialogState = {
7
+ isOpen: boolean;
8
+ setIsOpen: (open: boolean) => void;
9
+ };
10
+
11
+ export type DialogStates = {
12
+ second: DialogState;
13
+ successRelease: DialogState;
14
+ };
15
+
16
+ export type StatusStates = {};
17
+
18
+ type EscrowDialogsContextType = DialogStates & StatusStates;
19
+
20
+ const EscrowDialogsContext = createContext<
21
+ EscrowDialogsContextType | undefined
22
+ >(undefined);
23
+
24
+ export function EscrowDialogsProvider({
25
+ children,
26
+ }: {
27
+ children: React.ReactNode;
28
+ }) {
29
+ const [secondOpen, setSecondOpen] = useState(false);
30
+ const [successReleaseOpen, setSuccessReleaseOpen] = useState(false);
31
+
32
+ const value = useMemo<EscrowDialogsContextType>(
33
+ () => ({
34
+ // Detail Escrow Dialog
35
+ second: { isOpen: secondOpen, setIsOpen: setSecondOpen },
36
+
37
+ // Success Release Dialog
38
+ successRelease: {
39
+ isOpen: successReleaseOpen,
40
+ setIsOpen: setSuccessReleaseOpen,
41
+ },
42
+ }),
43
+ [secondOpen, successReleaseOpen]
44
+ );
45
+
46
+ return (
47
+ <EscrowDialogsContext.Provider value={value}>
48
+ {children}
49
+ </EscrowDialogsContext.Provider>
50
+ );
51
+ }
52
+
53
+ export function useEscrowDialogs() {
54
+ const ctx = useContext(EscrowDialogsContext);
55
+ if (!ctx) {
56
+ throw new Error(
57
+ "useEscrowDialogs must be used within EscrowDialogsProvider"
58
+ );
59
+ }
60
+ return ctx;
61
+ }