@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.
- package/README.md +39 -13
- package/bin/index.js +1128 -1137
- package/package.json +44 -44
- package/templates/escrows/details/EscrowDetailDialog.tsx +3 -3
- package/templates/escrows/details/GeneralInformation.tsx +2 -2
- package/templates/escrows/details/SuccessReleaseDialog.tsx +2 -3
- package/templates/escrows/details/useDetailsEscrow.ts +2 -2
- package/templates/escrows/escrows-by-role/cards/EscrowsCards.tsx +42 -16
- package/templates/escrows/escrows-by-role/table/EscrowsTable.tsx +45 -18
- package/templates/escrows/escrows-by-role/useEscrowsByRole.shared.ts +39 -25
- package/templates/escrows/escrows-by-signer/cards/EscrowsCards.tsx +33 -16
- package/templates/escrows/escrows-by-signer/table/EscrowsTable.tsx +34 -17
- package/templates/escrows/escrows-by-signer/useEscrowsBySigner.shared.ts +38 -25
- package/templates/escrows/single-release/approve-milestone/button/ApproveMilestone.tsx +14 -1
- package/templates/escrows/single-release/approve-milestone/dialog/ApproveMilestone.tsx +1 -1
- package/templates/escrows/single-release/approve-milestone/form/ApproveMilestone.tsx +1 -1
- package/templates/escrows/single-release/approve-milestone/shared/useApproveMilestone.ts +14 -1
- package/templates/escrows/single-release/change-milestone-status/button/ChangeMilestoneStatus.tsx +16 -1
- package/templates/escrows/single-release/change-milestone-status/dialog/ChangeMilestoneStatus.tsx +1 -1
- package/templates/escrows/single-release/change-milestone-status/form/ChangeMilestoneStatus.tsx +1 -1
- package/templates/escrows/single-release/change-milestone-status/shared/useChangeMilestoneStatus.ts +14 -1
- package/templates/escrows/single-release/dispute-escrow/button/DisputeEscrow.tsx +13 -1
- package/templates/escrows/single-release/fund-escrow/button/FundEscrow.tsx +13 -1
- package/templates/escrows/single-release/fund-escrow/shared/useFundEscrow.ts +14 -1
- package/templates/escrows/single-release/initialize-escrow/shared/useInitializeEscrow.ts +17 -1
- package/templates/escrows/single-release/release-escrow/button/ReleaseEscrow.tsx +15 -3
- package/templates/escrows/single-release/resolve-dispute/button/ResolveDispute.tsx +13 -1
- package/templates/escrows/single-release/resolve-dispute/dialog/ResolveDispute.tsx +1 -1
- package/templates/escrows/single-release/resolve-dispute/shared/useResolveDispute.ts +14 -1
- package/templates/escrows/single-release/update-escrow/shared/useUpdateEscrow.ts +224 -211
- package/templates/handle-errors/handle.ts +16 -0
- package/templates/helpers/format.helper.ts +31 -0
- package/templates/helpers/useCopy.ts +5 -0
- package/templates/{escrows/escrow-context → providers}/EscrowAmountProvider.tsx +3 -0
- package/templates/providers/EscrowDialogsProvider.tsx +61 -0
- package/templates/{escrows/escrow-context → providers}/EscrowProvider.tsx +30 -0
- package/templates/providers/ReactQueryClientProvider.tsx +17 -1
- package/templates/tanstack/useEscrowsByRoleQuery.ts +14 -0
- package/templates/tanstack/useEscrowsBySignerQuery.ts +13 -0
- package/templates/tanstack/useEscrowsMutations.ts +36 -0
- package/templates/wallet-kit/trustlines.ts +7 -0
- package/templates/wallet-kit/validators.ts +6 -0
- package/templates/wallet-kit/wallet-kit.ts +13 -0
- 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 "
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
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
|
}
|
|
@@ -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
|
+
}
|