@trustless-work/blocks 1.2.0 → 1.2.1

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 (19) hide show
  1. package/package.json +1 -1
  2. package/templates/escrows/details/GeneralInformation.tsx +10 -7
  3. package/templates/escrows/details/MilestoneCard.tsx +4 -1
  4. package/templates/escrows/escrows-by-role/cards/EscrowsCards.tsx +4 -4
  5. package/templates/escrows/escrows-by-role/table/EscrowsTable.tsx +2 -2
  6. package/templates/escrows/escrows-by-signer/cards/EscrowsCards.tsx +4 -4
  7. package/templates/escrows/escrows-by-signer/table/EscrowsTable.tsx +2 -2
  8. package/templates/escrows/multi-release/resolve-dispute/dialog/ResolveDispute.tsx +1 -1
  9. package/templates/escrows/multi-release/resolve-dispute/form/ResolveDispute.tsx +1 -1
  10. package/templates/escrows/multi-release/resolve-dispute/shared/useResolveDispute.ts +22 -4
  11. package/templates/escrows/multi-release/update-escrow/shared/schema.ts +3 -0
  12. package/templates/escrows/multi-release/update-escrow/shared/useUpdateEscrow.ts +3 -7
  13. package/templates/escrows/multi-release/withdraw-remaining-funds/dialog/WithdrawRemainingFunds.tsx +1 -1
  14. package/templates/escrows/multi-release/withdraw-remaining-funds/form/WithdrawRemainingFunds.tsx +1 -1
  15. package/templates/escrows/single-release/initialize-escrow/dialog/InitializeEscrow.tsx +1 -0
  16. package/templates/escrows/single-release/initialize-escrow/form/InitializeEscrow.tsx +1 -0
  17. package/templates/escrows/single-release/resolve-dispute/dialog/ResolveDispute.tsx +1 -1
  18. package/templates/escrows/single-release/update-escrow/shared/useUpdateEscrow.ts +2 -6
  19. package/templates/wallet-kit/trustlines.ts +5 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trustless-work/blocks",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "author": "Trustless Work",
5
5
  "keywords": [
6
6
  "react",
@@ -96,7 +96,10 @@ export const GeneralInformation = ({
96
96
  <StatisticsCard
97
97
  title="Amount"
98
98
  icon={CircleDollarSign}
99
- value={formatCurrency(totalAmount, selectedEscrow.trustline?.name)}
99
+ value={formatCurrency(
100
+ totalAmount,
101
+ selectedEscrow.trustline?.symbol
102
+ )}
100
103
  />
101
104
 
102
105
  <StatisticsCard
@@ -104,7 +107,7 @@ export const GeneralInformation = ({
104
107
  icon={Wallet}
105
108
  value={formatCurrency(
106
109
  selectedEscrow.balance ?? 0,
107
- selectedEscrow.trustline?.name
110
+ selectedEscrow.trustline?.symbol
108
111
  )}
109
112
  />
110
113
  </div>
@@ -136,7 +139,7 @@ export const GeneralInformation = ({
136
139
  <div className="flex-1 min-w-0">
137
140
  <div className="flex items-center justify-between mb-2">
138
141
  <span className="text-sm font-medium text-muted-foreground">
139
- {selectedEscrow.trustline?.name || "No Trustline"} |
142
+ {selectedEscrow.trustline?.symbol || "No Trustline"} |
140
143
  Escrow ID
141
144
  </span>
142
145
  <button
@@ -237,7 +240,7 @@ export const GeneralInformation = ({
237
240
  <span className="font-medium">
238
241
  {formatCurrency(
239
242
  selectedEscrow.amount,
240
- selectedEscrow.trustline?.name
243
+ selectedEscrow.trustline?.symbol
241
244
  )}
242
245
  </span>
243
246
  </div>
@@ -256,7 +259,7 @@ export const GeneralInformation = ({
256
259
  <span className="font-medium">
257
260
  {formatCurrency(
258
261
  Number(receiverAmount.toFixed(2)),
259
- selectedEscrow.trustline?.name
262
+ selectedEscrow.trustline?.symbol
260
263
  )}
261
264
  </span>
262
265
  </div>
@@ -276,7 +279,7 @@ export const GeneralInformation = ({
276
279
  <span className="font-medium">
277
280
  {formatCurrency(
278
281
  Number(platformFeeAmount.toFixed(2)),
279
- selectedEscrow.trustline?.name
282
+ selectedEscrow.trustline?.symbol
280
283
  )}
281
284
  </span>
282
285
  </div>
@@ -297,7 +300,7 @@ export const GeneralInformation = ({
297
300
  <span className="font-medium">
298
301
  {formatCurrency(
299
302
  Number(trustlessWorkAmount.toFixed(2)),
300
- selectedEscrow.trustline?.name
303
+ selectedEscrow.trustline?.symbol
301
304
  )}
302
305
  </span>
303
306
  </div>
@@ -202,7 +202,10 @@ const MilestoneCardComponent = ({
202
202
  {"amount" in milestone && (
203
203
  <div className="flex items-center gap-2 py-2">
204
204
  <span className="text-2xl font-bold text-foreground">
205
- {formatCurrency(milestone.amount, selectedEscrow.trustline?.name)}
205
+ {formatCurrency(
206
+ milestone.amount,
207
+ selectedEscrow.trustline?.symbol
208
+ )}
206
209
  </span>
207
210
  </div>
208
211
  )}
@@ -293,7 +293,7 @@ export const EscrowsByRoleCards = () => {
293
293
  {escrow.type === "single-release"
294
294
  ? formatCurrency(
295
295
  escrow.amount,
296
- escrow.trustline.name
296
+ escrow.trustline.symbol
297
297
  )
298
298
  : formatCurrency(
299
299
  escrow.milestones.reduce(
@@ -303,7 +303,7 @@ export const EscrowsByRoleCards = () => {
303
303
  .amount,
304
304
  0
305
305
  ),
306
- escrow.trustline.name
306
+ escrow.trustline.symbol
307
307
  )}
308
308
  </span>
309
309
  </div>
@@ -316,7 +316,7 @@ export const EscrowsByRoleCards = () => {
316
316
  <span className="font-medium text-green-800 dark:text-green-600">
317
317
  {formatCurrency(
318
318
  escrow.balance,
319
- escrow.trustline.name
319
+ escrow.trustline.symbol
320
320
  )}
321
321
  </span>
322
322
  </div>
@@ -362,7 +362,7 @@ export const EscrowsByRoleCards = () => {
362
362
  <span className="text-muted-foreground">
363
363
  {formatCurrency(
364
364
  milestone.amount,
365
- escrow.trustline.name
365
+ escrow.trustline.symbol
366
366
  )}
367
367
  </span>
368
368
 
@@ -160,9 +160,9 @@ export const EscrowsByRoleTable = () => {
160
160
  cell: ({ row }) => (
161
161
  <span
162
162
  className="max-w-[220px] truncate block"
163
- title={`${row.original.trustline.name} (${row.original.trustline.address})`}
163
+ title={`${row.original.trustline.symbol} (${row.original.trustline.address})`}
164
164
  >
165
- {row.original.trustline.name}
165
+ {row.original.trustline.symbol}
166
166
  </span>
167
167
  ),
168
168
  },
@@ -281,7 +281,7 @@ export const EscrowsBySignerCards = () => {
281
281
  {escrow.type === "single-release"
282
282
  ? formatCurrency(
283
283
  escrow.amount,
284
- escrow.trustline.name
284
+ escrow.trustline.symbol
285
285
  )
286
286
  : formatCurrency(
287
287
  escrow.milestones.reduce(
@@ -291,7 +291,7 @@ export const EscrowsBySignerCards = () => {
291
291
  .amount,
292
292
  0
293
293
  ),
294
- escrow.trustline.name
294
+ escrow.trustline.symbol
295
295
  )}
296
296
  </span>
297
297
  </div>
@@ -304,7 +304,7 @@ export const EscrowsBySignerCards = () => {
304
304
  <span className="font-medium text-green-800 dark:text-green-600">
305
305
  {formatCurrency(
306
306
  escrow.balance,
307
- escrow.trustline.name
307
+ escrow.trustline.symbol
308
308
  )}
309
309
  </span>
310
310
  </div>
@@ -350,7 +350,7 @@ export const EscrowsBySignerCards = () => {
350
350
  <span className="text-muted-foreground">
351
351
  {formatCurrency(
352
352
  milestone.amount,
353
- escrow.trustline.name
353
+ escrow.trustline.symbol
354
354
  )}
355
355
  </span>
356
356
 
@@ -150,9 +150,9 @@ export const EscrowsBySignerTable = () => {
150
150
  cell: ({ row }) => (
151
151
  <span
152
152
  className="max-w-[220px] truncate block"
153
- title={`${row.original.trustline.name} (${row.original.trustline.address})`}
153
+ title={`${row.original.trustline.symbol} (${row.original.trustline.address})`}
154
154
  >
155
- {row.original.trustline.name}
155
+ {row.original.trustline.symbol}
156
156
  </span>
157
157
  ),
158
158
  },
@@ -204,7 +204,7 @@ export const ResolveDisputeDialog = ({
204
204
  <span className="font-bold">Total Balance: </span>
205
205
  {formatCurrency(
206
206
  selectedEscrow?.balance || 0,
207
- selectedEscrow?.trustline.name || ""
207
+ selectedEscrow?.trustline.symbol || ""
208
208
  )}
209
209
  </p>
210
210
  </div>
@@ -184,7 +184,7 @@ export const ResolveDisputeForm = ({
184
184
  <span className="font-bold">Total Balance: </span>
185
185
  {formatCurrency(
186
186
  selectedEscrow?.balance || 0,
187
- selectedEscrow?.trustline.name || ""
187
+ selectedEscrow?.trustline.symbol || ""
188
188
  )}
189
189
  </p>
190
190
  </div>
@@ -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 useResolveDispute({ onSuccess }: { onSuccess?: () => void } = {}) {
20
+ export function useResolveDispute({
21
+ onSuccess,
22
+ }: { onSuccess?: () => void } = {}) {
21
23
  const { resolveDispute } = useEscrowsMutations();
22
24
  const { selectedEscrow, updateEscrow } = useEscrowContext();
23
25
  const { walletAddress } = useWalletContext();
@@ -50,7 +52,12 @@ export function useResolveDispute({ onSuccess }: { onSuccess?: () => void } = {}
50
52
  const idx = Number(milestoneIndexWatch);
51
53
  const milestones = selectedEscrow.milestones as MultiReleaseMilestone[];
52
54
  const m = milestones?.[idx];
53
- return Number((m?.amount as unknown as number) || 0);
55
+ const amount = m?.amount;
56
+ // Handle both string and number types
57
+ if (amount === undefined || amount === null) return 0;
58
+ const numAmount =
59
+ typeof amount === "string" ? Number(amount) : Number(amount);
60
+ return isNaN(numAmount) ? 0 : numAmount;
54
61
  }, [selectedEscrow, milestoneIndexWatch]);
55
62
 
56
63
  const distributions = form.watch("distributions") as DistributionInput[];
@@ -63,11 +70,22 @@ export function useResolveDispute({ onSuccess }: { onSuccess?: () => void } = {}
63
70
  }, [distributions]);
64
71
 
65
72
  const isExactMatch = React.useMemo(() => {
66
- return Number(allowedAmount) === Number(distributedSum);
73
+ const allowed = Number(allowedAmount);
74
+ const distributed = Number(distributedSum);
75
+ // Use epsilon comparison for floating point numbers
76
+ // Round to 2 decimal places to avoid precision issues
77
+ const roundedAllowed = Math.round(allowed * 100) / 100;
78
+ const roundedDistributed = Math.round(distributed * 100) / 100;
79
+ return Math.abs(roundedAllowed - roundedDistributed) < 0.01;
67
80
  }, [allowedAmount, distributedSum]);
68
81
 
69
82
  const difference = React.useMemo(() => {
70
- return Math.abs(Number(allowedAmount) - Number(distributedSum));
83
+ const allowed = Number(allowedAmount);
84
+ const distributed = Number(distributedSum);
85
+ // Round to 2 decimal places to avoid precision issues
86
+ const roundedAllowed = Math.round(allowed * 100) / 100;
87
+ const roundedDistributed = Math.round(distributed * 100) / 100;
88
+ return Math.abs(roundedAllowed - roundedDistributed);
71
89
  }, [allowedAmount, distributedSum]);
72
90
 
73
91
  const [isSubmitting, setIsSubmitting] = React.useState(false);
@@ -8,6 +8,9 @@ export const useUpdateEscrowSchema = () => {
8
8
  address: z.string().min(1, {
9
9
  message: "Trustline address is required.",
10
10
  }),
11
+ symbol: z.string().min(1, {
12
+ message: "Trustline symbol is required.",
13
+ }),
11
14
  }),
12
15
  roles: z.object({
13
16
  approver: z
@@ -47,7 +47,6 @@ export function useUpdateEscrow({
47
47
  | undefined,
48
48
  trustline: {
49
49
  address: selectedEscrow?.trustline?.address || "",
50
- symbol: selectedEscrow?.trustline?.name || "",
51
50
  },
52
51
  roles: {
53
52
  approver: selectedEscrow?.roles?.approver || "",
@@ -87,7 +86,6 @@ export function useUpdateEscrow({
87
86
  | undefined) || "",
88
87
  trustline: {
89
88
  address: selectedEscrow?.trustline?.address || "",
90
- symbol: selectedEscrow?.trustline?.name || "",
91
89
  },
92
90
  roles: {
93
91
  approver: selectedEscrow?.roles?.approver || "",
@@ -207,9 +205,10 @@ export function useUpdateEscrow({
207
205
  : payload.platformFee,
208
206
  trustline: {
209
207
  address: payload.trustline.address,
208
+ symbol: payload.trustline.symbol,
210
209
  },
211
210
  roles: payload.roles,
212
- milestones: payload.milestones.map((milestone, index) => ({
211
+ milestones: payload.milestones.map((milestone, index: number) => ({
213
212
  ...milestone,
214
213
  amount:
215
214
  typeof milestone.amount === "string"
@@ -240,10 +239,7 @@ export function useUpdateEscrow({
240
239
  ...selectedEscrow,
241
240
  ...finalPayload.escrow,
242
241
  trustline: {
243
- name:
244
- selectedEscrow.trustline?.name ||
245
- (selectedEscrow.trustline?.address as string) ||
246
- "",
242
+ symbol: selectedEscrow?.trustline?.symbol || "",
247
243
  address: finalPayload.escrow.trustline.address,
248
244
  },
249
245
  };
@@ -145,7 +145,7 @@ export const WithdrawRemainingFundsDialog = () => {
145
145
  <span className="font-bold">Total Balance: </span>
146
146
  {formatCurrency(
147
147
  selectedEscrow?.balance || 0,
148
- selectedEscrow?.trustline.name || ""
148
+ selectedEscrow?.trustline.symbol || ""
149
149
  )}
150
150
  </p>
151
151
  </div>
@@ -125,7 +125,7 @@ export const WithdrawRemainingFundsForm = () => {
125
125
  <span className="font-bold">Total Balance: </span>
126
126
  {formatCurrency(
127
127
  selectedEscrow?.balance || 0,
128
- selectedEscrow?.trustline.name || ""
128
+ selectedEscrow?.trustline.symbol || ""
129
129
  )}
130
130
  </p>
131
131
  </div>
@@ -466,6 +466,7 @@ export const InitializeEscrowDialog = () => {
466
466
  onClick={() => handleRemoveMilestone(index)}
467
467
  className="p-2 bg-transparent text-destructive rounded-md border-none shadow-none hover:bg-transparent hover:shadow-none hover:text-destructive focus:ring-0 active:ring-0 self-start sm:self-center cursor-pointer"
468
468
  disabled={milestones.length === 1}
469
+ type="button"
469
470
  >
470
471
  <Trash2 className="h-5 w-5" />
471
472
  </Button>
@@ -445,6 +445,7 @@ export const InitializeEscrowForm = () => {
445
445
  onClick={() => handleRemoveMilestone(index)}
446
446
  className="p-2 bg-transparent text-destructive rounded-md border-none shadow-none hover:bg-transparent hover:shadow-none hover:text-destructive focus:ring-0 active:ring-0 self-start sm:self-center cursor-pointer"
447
447
  disabled={milestones.length === 1}
448
+ type="button"
448
449
  >
449
450
  <Trash2 className="h-5 w-5" />
450
451
  </Button>
@@ -145,7 +145,7 @@ export const ResolveDisputeDialog = () => {
145
145
  <span className="font-bold">Total Balance: </span>
146
146
  {formatCurrency(
147
147
  selectedEscrow?.balance || 0,
148
- selectedEscrow?.trustline.name || ""
148
+ selectedEscrow?.trustline.symbol || ""
149
149
  )}
150
150
  </p>
151
151
  </div>
@@ -50,7 +50,6 @@ export function useUpdateEscrow({
50
50
  amount: selectedEscrow?.amount as unknown as number | string | undefined,
51
51
  trustline: {
52
52
  address: selectedEscrow?.trustline?.address || "",
53
- symbol: selectedEscrow?.trustline?.name || "",
54
53
  },
55
54
  roles: {
56
55
  approver: selectedEscrow?.roles?.approver || "",
@@ -87,7 +86,6 @@ export function useUpdateEscrow({
87
86
  "",
88
87
  trustline: {
89
88
  address: selectedEscrow?.trustline?.address || "",
90
- symbol: selectedEscrow?.trustline?.name || "",
91
89
  },
92
90
  roles: {
93
91
  approver: selectedEscrow?.roles?.approver || "",
@@ -181,6 +179,7 @@ export function useUpdateEscrow({
181
179
  : payload.amount,
182
180
  trustline: {
183
181
  address: payload.trustline.address,
182
+ symbol: selectedEscrow?.trustline?.symbol || "",
184
183
  },
185
184
  roles: payload.roles,
186
185
  milestones: payload.milestones.map((milestone, index) => ({
@@ -210,10 +209,7 @@ export function useUpdateEscrow({
210
209
  ...selectedEscrow,
211
210
  ...finalPayload.escrow,
212
211
  trustline: {
213
- name:
214
- selectedEscrow.trustline?.name ||
215
- (selectedEscrow.trustline?.address as string) ||
216
- "",
212
+ symbol: selectedEscrow.trustline?.address,
217
213
  address: finalPayload.escrow.trustline.address,
218
214
  },
219
215
  };
@@ -8,23 +8,23 @@
8
8
  export const trustlines = [
9
9
  // TESTNET
10
10
  {
11
- name: "USDC",
11
+ symbol: "USDC",
12
12
  address: "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5",
13
13
  network: "testnet",
14
14
  },
15
15
  {
16
- name: "EURC",
16
+ symbol: "EURC",
17
17
  address: "GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN",
18
18
  network: "testnet",
19
19
  },
20
20
  // MAINNET
21
21
  {
22
- name: "USDC",
22
+ symbol: "USDC",
23
23
  address: "GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN",
24
24
  network: "mainnet",
25
25
  },
26
26
  {
27
- name: "EURC",
27
+ symbol: "EURC",
28
28
  address: "GDHU6WRG4IEQXM5NZ4BMPKOXHW76MZM4Y2IEMFDVXBSDP6SJY4ITNPP2",
29
29
  network: "mainnet",
30
30
  },
@@ -37,7 +37,7 @@ export const trustlineOptions = Array.from(
37
37
  .filter((trustline) => trustline.network === "testnet")
38
38
  .map((trustline) => [
39
39
  trustline.address,
40
- { value: trustline.address, label: trustline.name },
40
+ { value: trustline.address, label: trustline.symbol },
41
41
  ])
42
42
  ).values()
43
43
  );