@trustless-work/blocks 1.0.9 → 1.1.0
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/bin/index.js +38 -1
- package/package.json +1 -1
- package/templates/deps.json +1 -1
- package/templates/escrows/multi-release/initialize-escrow/dialog/InitializeEscrow.tsx +3 -2
- package/templates/escrows/multi-release/initialize-escrow/shared/useInitializeEscrow.ts +3 -1
- package/templates/escrows/multi-release/resolve-dispute/dialog/ResolveDispute.tsx +3 -2
- package/templates/escrows/multi-release/resolve-dispute/shared/useResolveDispute.ts +3 -1
- package/templates/escrows/multi-release/update-escrow/dialog/UpdateEscrow.tsx +3 -2
- package/templates/escrows/multi-release/update-escrow/shared/useUpdateEscrow.ts +2 -1
- package/templates/escrows/multi-release/withdraw-remaining-funds/dialog/WithdrawRemainingFunds.tsx +3 -2
- package/templates/escrows/multi-release/withdraw-remaining-funds/shared/useWithdrawRemainingFunds.ts +5 -1
- package/templates/escrows/single-multi-release/approve-milestone/dialog/ApproveMilestone.tsx +5 -2
- package/templates/escrows/single-multi-release/approve-milestone/shared/useApproveMilestone.ts +5 -1
- package/templates/escrows/single-multi-release/change-milestone-status/dialog/ChangeMilestoneStatus.tsx +5 -2
- package/templates/escrows/single-multi-release/change-milestone-status/shared/useChangeMilestoneStatus.ts +5 -1
- package/templates/escrows/single-multi-release/fund-escrow/dialog/FundEscrow.tsx +5 -2
- package/templates/escrows/single-multi-release/fund-escrow/shared/useFundEscrow.ts +3 -1
- package/templates/escrows/single-release/initialize-escrow/dialog/InitializeEscrow.tsx +3 -2
- package/templates/escrows/single-release/initialize-escrow/shared/useInitializeEscrow.ts +3 -1
- package/templates/escrows/single-release/resolve-dispute/dialog/ResolveDispute.tsx +3 -2
- package/templates/escrows/single-release/resolve-dispute/shared/useResolveDispute.ts +3 -1
- package/templates/escrows/single-release/update-escrow/dialog/UpdateEscrow.tsx +3 -2
- package/templates/escrows/single-release/update-escrow/shared/useUpdateEscrow.ts +2 -1
- package/templates/wallet-kit/useWallet.ts +23 -16
- package/templates/wallet-kit/wallet-kit.ts +79 -24
package/bin/index.js
CHANGED
|
@@ -167,6 +167,7 @@ function installDeps({ dependencies = {}, devDependencies = {} }) {
|
|
|
167
167
|
"postcss",
|
|
168
168
|
"autoprefixer",
|
|
169
169
|
"postcss-import",
|
|
170
|
+
"@creit-tech/stellar-wallets-kit",
|
|
170
171
|
]);
|
|
171
172
|
const depList = Object.entries(dependencies)
|
|
172
173
|
.filter(([k]) => !BLOCKED.has(k))
|
|
@@ -421,6 +422,10 @@ function copyTemplate(name, { uiBase, shouldInstall = false } = {}) {
|
|
|
421
422
|
if (shouldInstall && fs.existsSync(GLOBAL_DEPS_FILE)) {
|
|
422
423
|
const meta = JSON.parse(fs.readFileSync(GLOBAL_DEPS_FILE, "utf8"));
|
|
423
424
|
installDeps(meta);
|
|
425
|
+
// Install @creit-tech/stellar-wallets-kit using jsr after all other deps are installed
|
|
426
|
+
if (meta.dependencies && meta.dependencies["@creit-tech/stellar-wallets-kit"]) {
|
|
427
|
+
run("npx", ["jsr", "add", "@creit-tech/stellar-wallets-kit"]);
|
|
428
|
+
}
|
|
424
429
|
}
|
|
425
430
|
currentEscrowType = null;
|
|
426
431
|
return;
|
|
@@ -1302,6 +1307,10 @@ function copyTemplate(name, { uiBase, shouldInstall = false } = {}) {
|
|
|
1302
1307
|
if (shouldInstall && fs.existsSync(GLOBAL_DEPS_FILE)) {
|
|
1303
1308
|
const meta = JSON.parse(fs.readFileSync(GLOBAL_DEPS_FILE, "utf8"));
|
|
1304
1309
|
installDeps(meta);
|
|
1310
|
+
// Install @creit-tech/stellar-wallets-kit using jsr after all other deps are installed
|
|
1311
|
+
if (meta.dependencies && meta.dependencies["@creit-tech/stellar-wallets-kit"]) {
|
|
1312
|
+
run("npx", ["jsr", "add", "@creit-tech/stellar-wallets-kit"]);
|
|
1313
|
+
}
|
|
1305
1314
|
}
|
|
1306
1315
|
}
|
|
1307
1316
|
|
|
@@ -1579,7 +1588,29 @@ function injectProvidersIntoLayout(
|
|
|
1579
1588
|
}
|
|
1580
1589
|
}
|
|
1581
1590
|
|
|
1591
|
+
function cleanJsrDeps() {
|
|
1592
|
+
const pkgPath = path.join(PROJECT_ROOT, "package.json");
|
|
1593
|
+
if (!fs.existsSync(pkgPath)) return;
|
|
1594
|
+
try {
|
|
1595
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
1596
|
+
let modified = false;
|
|
1597
|
+
const target = "@creit-tech/stellar-wallets-kit";
|
|
1598
|
+
if (pkg.dependencies && pkg.dependencies[target]) {
|
|
1599
|
+
delete pkg.dependencies[target];
|
|
1600
|
+
modified = true;
|
|
1601
|
+
}
|
|
1602
|
+
if (pkg.devDependencies && pkg.devDependencies[target]) {
|
|
1603
|
+
delete pkg.devDependencies[target];
|
|
1604
|
+
modified = true;
|
|
1605
|
+
}
|
|
1606
|
+
if (modified) {
|
|
1607
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2), "utf8");
|
|
1608
|
+
}
|
|
1609
|
+
} catch (e) {}
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1582
1612
|
if (args[0] === "init") {
|
|
1613
|
+
cleanJsrDeps();
|
|
1583
1614
|
console.log("\n▶ Setting up shadcn/ui components...");
|
|
1584
1615
|
const doInit = await promptYesNo("Run shadcn init now?", true);
|
|
1585
1616
|
if (doInit) {
|
|
@@ -1632,13 +1663,19 @@ if (args[0] === "init") {
|
|
|
1632
1663
|
}
|
|
1633
1664
|
const meta = JSON.parse(fs.readFileSync(GLOBAL_DEPS_FILE, "utf8"));
|
|
1634
1665
|
const installLibs = await promptYesNo(
|
|
1635
|
-
"Install (react-hook-form, @tanstack/react-query, @tanstack/react-query-devtools, @trustless-work/escrow, @hookform/resolvers, axios, @creit
|
|
1666
|
+
"Install (react-hook-form, @tanstack/react-query, @tanstack/react-query-devtools, @trustless-work/escrow, @hookform/resolvers, axios, @creit-tech/stellar-wallets-kit, react-day-picker, recharts & zod) dependencies now?",
|
|
1636
1667
|
true
|
|
1637
1668
|
);
|
|
1638
1669
|
if (installLibs) {
|
|
1639
1670
|
await withSpinner("Installing required dependencies", async () => {
|
|
1640
1671
|
installDeps(meta);
|
|
1641
1672
|
});
|
|
1673
|
+
// Install @creit-tech/stellar-wallets-kit using jsr after all other deps are installed
|
|
1674
|
+
if (meta.dependencies && meta.dependencies["@creit-tech/stellar-wallets-kit"]) {
|
|
1675
|
+
await withSpinner("Installing @creit-tech/stellar-wallets-kit from JSR", async () => {
|
|
1676
|
+
run("npx", ["jsr", "add", "@creit-tech/stellar-wallets-kit"]);
|
|
1677
|
+
});
|
|
1678
|
+
}
|
|
1642
1679
|
} else {
|
|
1643
1680
|
console.log("\x1b[90m– Skipped installing required dependencies\x1b[0m");
|
|
1644
1681
|
}
|
package/package.json
CHANGED
package/templates/deps.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"tsup": "^8.3.5",
|
|
12
12
|
"typescript": "^5.6.3",
|
|
13
13
|
"@hookform/resolvers": "^3.10.0",
|
|
14
|
-
"@creit
|
|
14
|
+
"@creit-tech/stellar-wallets-kit": "^1.8.0",
|
|
15
15
|
"axios": "^1.7.9",
|
|
16
16
|
"@tanstack/react-table": "^8.21.3",
|
|
17
17
|
"react-day-picker": "^9.5.0",
|
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
import { Separator } from "__UI_BASE__/separator";
|
|
33
33
|
|
|
34
34
|
export const InitializeEscrowDialog = () => {
|
|
35
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
35
36
|
const {
|
|
36
37
|
form,
|
|
37
38
|
isSubmitting,
|
|
@@ -41,7 +42,7 @@ export const InitializeEscrowDialog = () => {
|
|
|
41
42
|
handleAddMilestone,
|
|
42
43
|
handleRemoveMilestone,
|
|
43
44
|
fillTemplateForm,
|
|
44
|
-
} = useInitializeEscrow();
|
|
45
|
+
} = useInitializeEscrow({ onSuccess: () => setIsOpen(false) });
|
|
45
46
|
|
|
46
47
|
const handleMilestoneAmountChange = (
|
|
47
48
|
index: number,
|
|
@@ -92,7 +93,7 @@ export const InitializeEscrowDialog = () => {
|
|
|
92
93
|
};
|
|
93
94
|
|
|
94
95
|
return (
|
|
95
|
-
<Dialog>
|
|
96
|
+
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
|
96
97
|
<DialogTrigger asChild>
|
|
97
98
|
<Button type="button" className="cursor-pointer w-full">
|
|
98
99
|
Initialize
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvider";
|
|
18
18
|
import { trustlineOptions } from "@/components/tw-blocks/wallet-kit/trustlines";
|
|
19
19
|
|
|
20
|
-
export function useInitializeEscrow() {
|
|
20
|
+
export function useInitializeEscrow({ onSuccess }: { onSuccess?: () => void } = {}) {
|
|
21
21
|
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
22
22
|
|
|
23
23
|
const { getMultiReleaseFormSchema } = useInitializeEscrowSchema();
|
|
@@ -161,6 +161,8 @@ export function useInitializeEscrow() {
|
|
|
161
161
|
toast.success("Escrow initialized successfully");
|
|
162
162
|
|
|
163
163
|
setSelectedEscrow({ ...finalPayload, contractId: response.contractId });
|
|
164
|
+
|
|
165
|
+
onSuccess?.();
|
|
164
166
|
} catch (error) {
|
|
165
167
|
toast.error(handleError(error as ErrorResponse).message);
|
|
166
168
|
} finally {
|
|
@@ -35,6 +35,7 @@ export const ResolveDisputeDialog = ({
|
|
|
35
35
|
showSelectMilestone?: boolean;
|
|
36
36
|
milestoneIndex?: number | string;
|
|
37
37
|
}) => {
|
|
38
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
38
39
|
const {
|
|
39
40
|
form,
|
|
40
41
|
handleSubmit,
|
|
@@ -50,7 +51,7 @@ export const ResolveDisputeDialog = ({
|
|
|
50
51
|
distributedSum,
|
|
51
52
|
isExactMatch,
|
|
52
53
|
difference,
|
|
53
|
-
} = useResolveDispute();
|
|
54
|
+
} = useResolveDispute({ onSuccess: () => setIsOpen(false) });
|
|
54
55
|
const { selectedEscrow } = useEscrowContext();
|
|
55
56
|
|
|
56
57
|
React.useEffect(() => {
|
|
@@ -64,7 +65,7 @@ export const ResolveDisputeDialog = ({
|
|
|
64
65
|
}, [showSelectMilestone, milestoneIndex, form]);
|
|
65
66
|
|
|
66
67
|
return (
|
|
67
|
-
<Dialog>
|
|
68
|
+
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
|
68
69
|
<DialogTrigger asChild>
|
|
69
70
|
<Button type="button" className="cursor-pointer w-full">
|
|
70
71
|
Resolve Dispute
|
|
@@ -17,7 +17,7 @@ import { useWalletContext } from "@/components/tw-blocks/wallet-kit/WalletProvid
|
|
|
17
17
|
|
|
18
18
|
type DistributionInput = { address: string; amount: string | number };
|
|
19
19
|
|
|
20
|
-
export function useResolveDispute() {
|
|
20
|
+
export function useResolveDispute({ onSuccess }: { onSuccess?: () => void } = {}) {
|
|
21
21
|
const { resolveDispute } = useEscrowsMutations();
|
|
22
22
|
const { selectedEscrow, updateEscrow } = useEscrowContext();
|
|
23
23
|
const { walletAddress } = useWalletContext();
|
|
@@ -142,6 +142,8 @@ export function useResolveDispute() {
|
|
|
142
142
|
|
|
143
143
|
toast.success("Dispute resolved successfully");
|
|
144
144
|
|
|
145
|
+
onSuccess?.();
|
|
146
|
+
|
|
145
147
|
const sumDistributed = payload.distributions.reduce((acc, d) => {
|
|
146
148
|
const n = Number(d.amount || 0);
|
|
147
149
|
return acc + (isNaN(n) ? 0 : n);
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
} from "__UI_BASE__/dialog";
|
|
32
32
|
|
|
33
33
|
export const UpdateEscrowDialog = () => {
|
|
34
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
34
35
|
const {
|
|
35
36
|
form,
|
|
36
37
|
isSubmitting,
|
|
@@ -43,10 +44,10 @@ export const UpdateEscrowDialog = () => {
|
|
|
43
44
|
handleMilestoneAmountChange,
|
|
44
45
|
isEscrowLocked,
|
|
45
46
|
initialMilestonesCount,
|
|
46
|
-
} = useUpdateEscrow();
|
|
47
|
+
} = useUpdateEscrow({ onSuccess: () => setIsOpen(false) });
|
|
47
48
|
|
|
48
49
|
return (
|
|
49
|
-
<Dialog>
|
|
50
|
+
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
|
50
51
|
<DialogTrigger asChild>
|
|
51
52
|
<Button type="button" className="cursor-pointer w-full">
|
|
52
53
|
Update
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
} from "@/components/tw-blocks/handle-errors/handle";
|
|
19
19
|
import { GetEscrowsFromIndexerResponse } from "@trustless-work/escrow/types";
|
|
20
20
|
|
|
21
|
-
export function useUpdateEscrow() {
|
|
21
|
+
export function useUpdateEscrow({ onSuccess }: { onSuccess?: () => void } = {}) {
|
|
22
22
|
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
23
23
|
|
|
24
24
|
const { getMultiReleaseFormSchema } = useUpdateEscrowSchema();
|
|
@@ -246,6 +246,7 @@ export function useUpdateEscrow() {
|
|
|
246
246
|
|
|
247
247
|
setSelectedEscrow(nextSelectedEscrow);
|
|
248
248
|
toast.success("Escrow updated successfully");
|
|
249
|
+
onSuccess?.();
|
|
249
250
|
} catch (error) {
|
|
250
251
|
toast.error(handleError(error as ErrorResponse).message);
|
|
251
252
|
} finally {
|
package/templates/escrows/multi-release/withdraw-remaining-funds/dialog/WithdrawRemainingFunds.tsx
CHANGED
|
@@ -22,6 +22,7 @@ import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvide
|
|
|
22
22
|
import { formatCurrency } from "../../../../helpers/format.helper";
|
|
23
23
|
|
|
24
24
|
export const WithdrawRemainingFundsDialog = () => {
|
|
25
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
25
26
|
const {
|
|
26
27
|
form,
|
|
27
28
|
handleSubmit,
|
|
@@ -36,11 +37,11 @@ export const WithdrawRemainingFundsDialog = () => {
|
|
|
36
37
|
distributedSum,
|
|
37
38
|
isExactMatch,
|
|
38
39
|
difference,
|
|
39
|
-
} = useWithdrawRemainingFunds();
|
|
40
|
+
} = useWithdrawRemainingFunds({ onSuccess: () => setIsOpen(false) });
|
|
40
41
|
const { selectedEscrow } = useEscrowContext();
|
|
41
42
|
|
|
42
43
|
return (
|
|
43
|
-
<Dialog>
|
|
44
|
+
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
|
44
45
|
<DialogTrigger asChild>
|
|
45
46
|
<Button type="button" className="cursor-pointer w-full">
|
|
46
47
|
Withdraw Remaining
|
package/templates/escrows/multi-release/withdraw-remaining-funds/shared/useWithdrawRemainingFunds.ts
CHANGED
|
@@ -17,7 +17,9 @@ import { useWalletContext } from "@/components/tw-blocks/wallet-kit/WalletProvid
|
|
|
17
17
|
|
|
18
18
|
type DistributionInput = { address: string; amount: string | number };
|
|
19
19
|
|
|
20
|
-
export function useWithdrawRemainingFunds(
|
|
20
|
+
export function useWithdrawRemainingFunds({
|
|
21
|
+
onSuccess,
|
|
22
|
+
}: { onSuccess?: () => void } = {}) {
|
|
21
23
|
const { withdrawRemainingFunds } = useEscrowsMutations();
|
|
22
24
|
const { selectedEscrow, updateEscrow } = useEscrowContext();
|
|
23
25
|
const { walletAddress } = useWalletContext();
|
|
@@ -124,6 +126,8 @@ export function useWithdrawRemainingFunds() {
|
|
|
124
126
|
|
|
125
127
|
toast.success("Withdraw successful");
|
|
126
128
|
|
|
129
|
+
onSuccess?.();
|
|
130
|
+
|
|
127
131
|
const sumDistributed = payload.distributions.reduce((acc, d) => {
|
|
128
132
|
const n = Number(d.amount || 0);
|
|
129
133
|
return acc + (isNaN(n) ? 0 : n);
|
package/templates/escrows/single-multi-release/approve-milestone/dialog/ApproveMilestone.tsx
CHANGED
|
@@ -27,11 +27,14 @@ import {
|
|
|
27
27
|
} from "__UI_BASE__/select";
|
|
28
28
|
|
|
29
29
|
export const ApproveMilestoneDialog = () => {
|
|
30
|
-
const
|
|
30
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
31
|
+
const { form, handleSubmit, isSubmitting } = useApproveMilestone({
|
|
32
|
+
onSuccess: () => setIsOpen(false),
|
|
33
|
+
});
|
|
31
34
|
const { selectedEscrow } = useEscrowContext();
|
|
32
35
|
|
|
33
36
|
return (
|
|
34
|
-
<Dialog>
|
|
37
|
+
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
|
35
38
|
<DialogTrigger asChild>
|
|
36
39
|
<Button type="button" className="cursor-pointer w-full">
|
|
37
40
|
Approve Milestone
|
package/templates/escrows/single-multi-release/approve-milestone/shared/useApproveMilestone.ts
CHANGED
|
@@ -15,7 +15,9 @@ import {
|
|
|
15
15
|
} from "@/components/tw-blocks/handle-errors/handle";
|
|
16
16
|
import { useWalletContext } from "@/components/tw-blocks/wallet-kit/WalletProvider";
|
|
17
17
|
|
|
18
|
-
export function useApproveMilestone(
|
|
18
|
+
export function useApproveMilestone({
|
|
19
|
+
onSuccess,
|
|
20
|
+
}: { onSuccess?: () => void } = {}) {
|
|
19
21
|
const { approveMilestone } = useEscrowsMutations();
|
|
20
22
|
const { selectedEscrow, updateEscrow } = useEscrowContext();
|
|
21
23
|
const { walletAddress } = useWalletContext();
|
|
@@ -48,6 +50,8 @@ export function useApproveMilestone() {
|
|
|
48
50
|
|
|
49
51
|
toast.success("Milestone approved flag updated successfully");
|
|
50
52
|
|
|
53
|
+
onSuccess?.();
|
|
54
|
+
|
|
51
55
|
updateEscrow({
|
|
52
56
|
...selectedEscrow,
|
|
53
57
|
milestones: selectedEscrow?.milestones.map((milestone, index) => {
|
|
@@ -35,7 +35,10 @@ export const ChangeMilestoneStatusDialog = ({
|
|
|
35
35
|
showSelectMilestone?: boolean;
|
|
36
36
|
milestoneIndex?: number | string;
|
|
37
37
|
}) => {
|
|
38
|
-
const
|
|
38
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
39
|
+
const { form, handleSubmit, isSubmitting } = useChangeMilestoneStatus({
|
|
40
|
+
onSuccess: () => setIsOpen(false),
|
|
41
|
+
});
|
|
39
42
|
const { selectedEscrow } = useEscrowContext();
|
|
40
43
|
|
|
41
44
|
React.useEffect(() => {
|
|
@@ -49,7 +52,7 @@ export const ChangeMilestoneStatusDialog = ({
|
|
|
49
52
|
}, [showSelectMilestone, milestoneIndex, form]);
|
|
50
53
|
|
|
51
54
|
return (
|
|
52
|
-
<Dialog>
|
|
55
|
+
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
|
53
56
|
<DialogTrigger asChild>
|
|
54
57
|
<Button type="button" className="cursor-pointer w-full">
|
|
55
58
|
Update Status
|
|
@@ -15,7 +15,9 @@ import {
|
|
|
15
15
|
} from "@/components/tw-blocks/handle-errors/handle";
|
|
16
16
|
import { useWalletContext } from "@/components/tw-blocks/wallet-kit/WalletProvider";
|
|
17
17
|
|
|
18
|
-
export function useChangeMilestoneStatus(
|
|
18
|
+
export function useChangeMilestoneStatus({
|
|
19
|
+
onSuccess,
|
|
20
|
+
}: { onSuccess?: () => void } = {}) {
|
|
19
21
|
const { changeMilestoneStatus } = useEscrowsMutations();
|
|
20
22
|
const { selectedEscrow, updateEscrow } = useEscrowContext();
|
|
21
23
|
const { walletAddress } = useWalletContext();
|
|
@@ -65,6 +67,8 @@ export function useChangeMilestoneStatus() {
|
|
|
65
67
|
|
|
66
68
|
toast.success("Milestone status updated successfully");
|
|
67
69
|
|
|
70
|
+
onSuccess?.();
|
|
71
|
+
|
|
68
72
|
updateEscrow({
|
|
69
73
|
...selectedEscrow,
|
|
70
74
|
milestones: selectedEscrow?.milestones.map((milestone, index) => {
|
|
@@ -20,10 +20,13 @@ import { Loader2 } from "lucide-react";
|
|
|
20
20
|
import { useFundEscrow } from "./useFundEscrow";
|
|
21
21
|
|
|
22
22
|
export const FundEscrowDialog = () => {
|
|
23
|
-
const
|
|
23
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
24
|
+
const { form, handleSubmit, isSubmitting } = useFundEscrow({
|
|
25
|
+
onSuccess: () => setIsOpen(false),
|
|
26
|
+
});
|
|
24
27
|
|
|
25
28
|
return (
|
|
26
|
-
<Dialog>
|
|
29
|
+
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
|
27
30
|
<DialogTrigger asChild>
|
|
28
31
|
<Button type="button" className="cursor-pointer w-full">
|
|
29
32
|
Fund
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from "@/components/tw-blocks/handle-errors/handle";
|
|
13
13
|
import { useWalletContext } from "@/components/tw-blocks/wallet-kit/WalletProvider";
|
|
14
14
|
|
|
15
|
-
export function useFundEscrow() {
|
|
15
|
+
export function useFundEscrow({ onSuccess }: { onSuccess?: () => void } = {}) {
|
|
16
16
|
const { fundEscrow } = useEscrowsMutations();
|
|
17
17
|
const { selectedEscrow, updateEscrow } = useEscrowContext();
|
|
18
18
|
const { walletAddress } = useWalletContext();
|
|
@@ -66,6 +66,8 @@ export function useFundEscrow() {
|
|
|
66
66
|
|
|
67
67
|
toast.success("Escrow funded successfully");
|
|
68
68
|
|
|
69
|
+
onSuccess?.();
|
|
70
|
+
|
|
69
71
|
// do something with the response ...
|
|
70
72
|
} catch (error) {
|
|
71
73
|
toast.error(handleError(error as ErrorResponse).message);
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
} from "__UI_BASE__/dialog";
|
|
32
32
|
|
|
33
33
|
export const InitializeEscrowDialog = () => {
|
|
34
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
34
35
|
const {
|
|
35
36
|
form,
|
|
36
37
|
isSubmitting,
|
|
@@ -40,7 +41,7 @@ export const InitializeEscrowDialog = () => {
|
|
|
40
41
|
handleAddMilestone,
|
|
41
42
|
handleRemoveMilestone,
|
|
42
43
|
fillTemplateForm,
|
|
43
|
-
} = useInitializeEscrow();
|
|
44
|
+
} = useInitializeEscrow({ onSuccess: () => setIsOpen(false) });
|
|
44
45
|
|
|
45
46
|
const handleAmountChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
46
47
|
let rawValue = e.target.value;
|
|
@@ -83,7 +84,7 @@ export const InitializeEscrowDialog = () => {
|
|
|
83
84
|
};
|
|
84
85
|
|
|
85
86
|
return (
|
|
86
|
-
<Dialog>
|
|
87
|
+
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
|
87
88
|
<DialogTrigger asChild>
|
|
88
89
|
<Button type="button" className="cursor-pointer w-full">
|
|
89
90
|
Initialize
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvider";
|
|
18
18
|
import { trustlineOptions } from "@/components/tw-blocks/wallet-kit/trustlines";
|
|
19
19
|
|
|
20
|
-
export function useInitializeEscrow() {
|
|
20
|
+
export function useInitializeEscrow({ onSuccess }: { onSuccess?: () => void } = {}) {
|
|
21
21
|
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
22
22
|
|
|
23
23
|
const { getSingleReleaseFormSchema } = useInitializeEscrowSchema();
|
|
@@ -145,6 +145,8 @@ export function useInitializeEscrow() {
|
|
|
145
145
|
toast.success("Escrow initialized successfully");
|
|
146
146
|
|
|
147
147
|
setSelectedEscrow({ ...finalPayload, contractId: response.contractId });
|
|
148
|
+
|
|
149
|
+
onSuccess?.();
|
|
148
150
|
} catch (error) {
|
|
149
151
|
toast.error(handleError(error as ErrorResponse).message);
|
|
150
152
|
} finally {
|
|
@@ -22,6 +22,7 @@ import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvide
|
|
|
22
22
|
import { formatCurrency } from "../../../../helpers/format.helper";
|
|
23
23
|
|
|
24
24
|
export const ResolveDisputeDialog = () => {
|
|
25
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
25
26
|
const {
|
|
26
27
|
form,
|
|
27
28
|
handleSubmit,
|
|
@@ -36,11 +37,11 @@ export const ResolveDisputeDialog = () => {
|
|
|
36
37
|
distributedSum,
|
|
37
38
|
isExactMatch,
|
|
38
39
|
difference,
|
|
39
|
-
} = useResolveDispute();
|
|
40
|
+
} = useResolveDispute({ onSuccess: () => setIsOpen(false) });
|
|
40
41
|
const { selectedEscrow } = useEscrowContext();
|
|
41
42
|
|
|
42
43
|
return (
|
|
43
|
-
<Dialog>
|
|
44
|
+
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
|
44
45
|
<DialogTrigger asChild>
|
|
45
46
|
<Button type="button" className="cursor-pointer w-full">
|
|
46
47
|
Resolve Dispute
|
|
@@ -14,7 +14,7 @@ import { useWalletContext } from "@/components/tw-blocks/wallet-kit/WalletProvid
|
|
|
14
14
|
|
|
15
15
|
type DistributionInput = { address: string; amount: string | number };
|
|
16
16
|
|
|
17
|
-
export function useResolveDispute() {
|
|
17
|
+
export function useResolveDispute({ onSuccess }: { onSuccess?: () => void } = {}) {
|
|
18
18
|
const { resolveDispute } = useEscrowsMutations();
|
|
19
19
|
const { selectedEscrow, updateEscrow } = useEscrowContext();
|
|
20
20
|
const { walletAddress } = useWalletContext();
|
|
@@ -122,6 +122,8 @@ export function useResolveDispute() {
|
|
|
122
122
|
|
|
123
123
|
toast.success("Dispute resolved successfully");
|
|
124
124
|
|
|
125
|
+
onSuccess?.();
|
|
126
|
+
|
|
125
127
|
const sumDistributed = payload.distributions.reduce((acc, d) => {
|
|
126
128
|
const n = Number(d.amount || 0);
|
|
127
129
|
return acc + (isNaN(n) ? 0 : n);
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
} from "__UI_BASE__/dialog";
|
|
32
32
|
|
|
33
33
|
export const UpdateEscrowDialog = () => {
|
|
34
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
34
35
|
const {
|
|
35
36
|
form,
|
|
36
37
|
isSubmitting,
|
|
@@ -43,10 +44,10 @@ export const UpdateEscrowDialog = () => {
|
|
|
43
44
|
handlePlatformFeeChange,
|
|
44
45
|
isEscrowLocked,
|
|
45
46
|
initialMilestonesCount,
|
|
46
|
-
} = useUpdateEscrow();
|
|
47
|
+
} = useUpdateEscrow({ onSuccess: () => setIsOpen(false) });
|
|
47
48
|
|
|
48
49
|
return (
|
|
49
|
-
<Dialog>
|
|
50
|
+
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
|
50
51
|
<DialogTrigger asChild>
|
|
51
52
|
<Button type="button" className="cursor-pointer w-full">
|
|
52
53
|
Update
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
handleError,
|
|
21
21
|
} from "@/components/tw-blocks/handle-errors/handle";
|
|
22
22
|
|
|
23
|
-
export function useUpdateEscrow() {
|
|
23
|
+
export function useUpdateEscrow({ onSuccess }: { onSuccess?: () => void } = {}) {
|
|
24
24
|
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
25
25
|
|
|
26
26
|
const { getSingleReleaseFormSchema } = useUpdateEscrowSchema();
|
|
@@ -216,6 +216,7 @@ export function useUpdateEscrow() {
|
|
|
216
216
|
|
|
217
217
|
setSelectedEscrow(nextSelectedEscrow);
|
|
218
218
|
toast.success("Escrow updated successfully");
|
|
219
|
+
onSuccess?.();
|
|
219
220
|
} catch (error) {
|
|
220
221
|
toast.error(handleError(error as ErrorResponse).message);
|
|
221
222
|
} finally {
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
openAuthModal,
|
|
3
|
+
disconnectWalletKit,
|
|
4
|
+
getSelectedWallet,
|
|
5
|
+
} from "./wallet-kit";
|
|
2
6
|
import { useWalletContext } from "./WalletProvider";
|
|
3
|
-
import { ISupportedWallet } from "@creit.tech/stellar-wallets-kit";
|
|
4
7
|
|
|
5
8
|
/**
|
|
6
9
|
* Custom hook that provides wallet connection and disconnection functionality
|
|
@@ -16,20 +19,14 @@ export const useWallet = () => {
|
|
|
16
19
|
* Automatically sets wallet information in the context upon successful connection
|
|
17
20
|
*/
|
|
18
21
|
const connectWallet = async () => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
onWalletSelected: async (option: ISupportedWallet) => {
|
|
22
|
-
// Set the selected wallet as the active wallet
|
|
23
|
-
kit.setWallet(option.id);
|
|
22
|
+
// Open the auth modal and wait for the user to connect
|
|
23
|
+
const { address } = await openAuthModal();
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const { name } = option;
|
|
25
|
+
// Get the selected wallet details (name)
|
|
26
|
+
const { productName } = await getSelectedWallet();
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
},
|
|
32
|
-
});
|
|
28
|
+
// Store wallet information in the context and localStorage
|
|
29
|
+
setWalletInfo(address, productName);
|
|
33
30
|
};
|
|
34
31
|
|
|
35
32
|
/**
|
|
@@ -38,7 +35,7 @@ export const useWallet = () => {
|
|
|
38
35
|
* Disconnects the wallet from the Stellar Wallet Kit
|
|
39
36
|
*/
|
|
40
37
|
const disconnectWallet = async () => {
|
|
41
|
-
await
|
|
38
|
+
await disconnectWalletKit();
|
|
42
39
|
clearWalletInfo();
|
|
43
40
|
};
|
|
44
41
|
|
|
@@ -49,7 +46,17 @@ export const useWallet = () => {
|
|
|
49
46
|
const handleConnect = async () => {
|
|
50
47
|
try {
|
|
51
48
|
await connectWallet();
|
|
52
|
-
} catch (error) {
|
|
49
|
+
} catch (error: unknown) {
|
|
50
|
+
// Skip error if the user closes the modal
|
|
51
|
+
if (
|
|
52
|
+
typeof error === "object" &&
|
|
53
|
+
error !== null &&
|
|
54
|
+
"code" in error &&
|
|
55
|
+
(error as { code: number }).code === -1
|
|
56
|
+
) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
53
60
|
console.error("Error connecting wallet:", error);
|
|
54
61
|
// You can add additional error handling here, such as showing user notifications
|
|
55
62
|
}
|
|
@@ -1,23 +1,52 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import type { ModuleInterface } from "@creit-tech/stellar-wallets-kit/types";
|
|
2
|
+
type SdkModule = typeof import("@creit-tech/stellar-wallets-kit/sdk");
|
|
3
|
+
type TypesModule = typeof import("@creit-tech/stellar-wallets-kit/types");
|
|
4
|
+
type ModulesUtilsModule =
|
|
5
|
+
typeof import("@creit-tech/stellar-wallets-kit/modules/utils");
|
|
6
|
+
type StellarWalletsKitStatic = SdkModule["StellarWalletsKit"];
|
|
7
|
+
type NetworksEnum = TypesModule["Networks"];
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* Stellar Wallet Kit
|
|
10
|
+
* Stellar Wallet Kit helpers
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* @description The Stellar Wallet Kit is used to get the wallet address
|
|
12
|
+
* We only load and initialize the kit
|
|
13
|
+
* on the client, and only in response to effects or user actions.
|
|
15
14
|
*/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
let walletKitPromise: Promise<{
|
|
16
|
+
StellarWalletsKit: StellarWalletsKitStatic;
|
|
17
|
+
Networks: NetworksEnum;
|
|
18
|
+
}> | null = null;
|
|
19
|
+
|
|
20
|
+
const loadWalletKit = async () => {
|
|
21
|
+
if (typeof window === "undefined") {
|
|
22
|
+
throw new Error("StellarWalletsKit is only available in the browser");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!walletKitPromise) {
|
|
26
|
+
walletKitPromise = (async () => {
|
|
27
|
+
const [sdk, types, modules] = await Promise.all([
|
|
28
|
+
import("@creit-tech/stellar-wallets-kit/sdk") as Promise<SdkModule>,
|
|
29
|
+
import("@creit-tech/stellar-wallets-kit/types") as Promise<TypesModule>,
|
|
30
|
+
import(
|
|
31
|
+
"@creit-tech/stellar-wallets-kit/modules/utils"
|
|
32
|
+
) as Promise<ModulesUtilsModule>,
|
|
33
|
+
]);
|
|
34
|
+
|
|
35
|
+
const { StellarWalletsKit } = sdk;
|
|
36
|
+
const { Networks } = types;
|
|
37
|
+
const { defaultModules } = modules;
|
|
38
|
+
|
|
39
|
+
StellarWalletsKit.init({
|
|
40
|
+
network: Networks.TESTNET, // Adjust this to the network you are using
|
|
41
|
+
modules: defaultModules(),
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return { StellarWalletsKit, Networks };
|
|
45
|
+
})();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return walletKitPromise;
|
|
49
|
+
};
|
|
21
50
|
|
|
22
51
|
interface SignTransactionParams {
|
|
23
52
|
unsignedTransaction: string;
|
|
@@ -25,19 +54,45 @@ interface SignTransactionParams {
|
|
|
25
54
|
}
|
|
26
55
|
|
|
27
56
|
/**
|
|
28
|
-
*
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
57
|
+
* Open the authentication modal and request the user's address.
|
|
58
|
+
*/
|
|
59
|
+
export const openAuthModal = async (): Promise<{ address: string }> => {
|
|
60
|
+
const { StellarWalletsKit } = await loadWalletKit();
|
|
61
|
+
return StellarWalletsKit.authModal();
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Get the currently selected wallet module.
|
|
66
|
+
*/
|
|
67
|
+
export const getSelectedWallet = async (): Promise<ModuleInterface> => {
|
|
68
|
+
const { StellarWalletsKit } = await loadWalletKit();
|
|
69
|
+
return StellarWalletsKit.selectedModule;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Disconnect the current wallet.
|
|
74
|
+
*/
|
|
75
|
+
export const disconnectWalletKit = async (): Promise<void> => {
|
|
76
|
+
const { StellarWalletsKit } = await loadWalletKit();
|
|
77
|
+
return StellarWalletsKit.disconnect();
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Helper to sign a transaction XDR with the active wallet.
|
|
32
82
|
*/
|
|
33
83
|
export const signTransaction = async ({
|
|
34
84
|
unsignedTransaction,
|
|
35
85
|
address,
|
|
36
86
|
}: SignTransactionParams): Promise<string> => {
|
|
37
|
-
const {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
87
|
+
const { StellarWalletsKit, Networks } = await loadWalletKit();
|
|
88
|
+
|
|
89
|
+
const { signedTxXdr } = await StellarWalletsKit.signTransaction(
|
|
90
|
+
unsignedTransaction,
|
|
91
|
+
{
|
|
92
|
+
address,
|
|
93
|
+
networkPassphrase: Networks.TESTNET, // Adjust this to the network you are using
|
|
94
|
+
}
|
|
95
|
+
);
|
|
41
96
|
|
|
42
97
|
return signedTxXdr;
|
|
43
98
|
};
|