Skip to content

Commit d041e4d

Browse files
authored
Update Ledger transaction rejected modal (#285)
1 parent d750cd1 commit d041e4d

File tree

5 files changed

+155
-40
lines changed

5 files changed

+155
-40
lines changed

main/api/ledger/utils/ledgerManager.ts

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { AccountFormat, encodeAccountImport } from "@ironfish/sdk";
44
import { z } from "zod";
55

66
import {
7+
LedgerActionRejected,
78
LedgerAppNotOpen,
89
LedgerClaNotSupportedError,
910
LedgerConnectError,
@@ -167,40 +168,48 @@ class LedgerManager {
167168
fee,
168169
memo,
169170
}: z.infer<typeof handleSendTransactionInput>) => {
170-
const unsignedTransaction = await createUnsignedTransaction({
171-
fromAccount,
172-
toAccount,
173-
assetId,
174-
amount,
175-
fee,
176-
memo,
177-
});
171+
try {
172+
const unsignedTransaction = await createUnsignedTransaction({
173+
fromAccount,
174+
toAccount,
175+
assetId,
176+
amount,
177+
fee,
178+
memo,
179+
});
178180

179-
const signature = await this.taskQueue.enqueue(async () => {
180-
this.signTransactionPromise =
181-
this.ledgerSingleSigner.sign(unsignedTransaction);
181+
const signature = await this.taskQueue.enqueue(async () => {
182+
this.signTransactionPromise =
183+
this.ledgerSingleSigner.sign(unsignedTransaction);
182184

183-
return this.signTransactionPromise;
184-
});
185+
return this.signTransactionPromise;
186+
});
185187

186-
if (!this.signTransactionPromise) {
187-
return null;
188-
}
188+
if (!this.signTransactionPromise) {
189+
return null;
190+
}
189191

190-
const ironfish = await manager.getIronfish();
191-
const rpcClient = await ironfish.rpcClient();
192+
const ironfish = await manager.getIronfish();
193+
const rpcClient = await ironfish.rpcClient();
192194

193-
const addSignatureResponse = await rpcClient.wallet.addSignature({
194-
unsignedTransaction,
195-
signature: signature.toString("hex"),
196-
});
195+
const addSignatureResponse = await rpcClient.wallet.addSignature({
196+
unsignedTransaction,
197+
signature: signature.toString("hex"),
198+
});
197199

198-
const addTransactionResponse = await rpcClient.wallet.addTransaction({
199-
transaction: addSignatureResponse.content.transaction,
200-
broadcast: true,
201-
});
200+
const addTransactionResponse = await rpcClient.wallet.addTransaction({
201+
transaction: addSignatureResponse.content.transaction,
202+
broadcast: true,
203+
});
202204

203-
return addTransactionResponse.content;
205+
return addTransactionResponse.content;
206+
} catch (err) {
207+
if (err instanceof LedgerActionRejected) {
208+
throw new Error("TRANSACTION_REJECTED");
209+
}
210+
211+
throw err;
212+
}
204213
};
205214

206215
cancelTransaction() {

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

renderer/components/SendAssetsForm/ConfirmLedgerModal/ConfirmLedgerModal.tsx

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { PillButton } from "@/ui/PillButton/PillButton";
1414

1515
import { StepConfirm } from "./Steps/StepConfirm";
1616
import { StepConnect } from "./Steps/StepConnect";
17+
import { TransactionRejected } from "./Steps/TransactionRejected";
1718
import { ReviewTransaction } from "../SharedConfirmSteps/ReviewTransaction";
1819
import { SubmissionError } from "../SharedConfirmSteps/SubmissionError";
1920
import { TransactionSubmitted } from "../SharedConfirmSteps/TransactionSubmitted";
@@ -202,17 +203,31 @@ export function ConfirmLedgerModal({
202203
handleClose={handleClose}
203204
/>
204205
)}
205-
{step === "SUBMISSION_ERROR" && (
206-
<SubmissionError
207-
errorMessage={error?.message ?? ""}
208-
isLoading={isLoading}
209-
handleClose={handleClose}
210-
handleSubmit={() => {
211-
submitTransaction(transactionData);
212-
setStep("CONFIRM_TRANSACTION");
213-
}}
214-
/>
215-
)}
206+
207+
{step === "SUBMISSION_ERROR" &&
208+
error?.message === "TRANSACTION_REJECTED" && (
209+
<TransactionRejected
210+
isLoading={isLoading}
211+
handleClose={handleClose}
212+
handleSubmit={() => {
213+
submitTransaction(transactionData);
214+
setStep("CONFIRM_TRANSACTION");
215+
}}
216+
/>
217+
)}
218+
219+
{step === "SUBMISSION_ERROR" &&
220+
error?.message !== "TRANSACTION_REJECTED" && (
221+
<SubmissionError
222+
errorMessage={error?.message ?? ""}
223+
isLoading={isLoading}
224+
handleClose={handleClose}
225+
handleSubmit={() => {
226+
submitTransaction(transactionData);
227+
setStep("CONFIRM_TRANSACTION");
228+
}}
229+
/>
230+
)}
216231
</ModalContent>
217232
</Modal>
218233
);
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { Box, ModalFooter, ModalBody, Heading, Text } from "@chakra-ui/react";
2+
import { defineMessages, useIntl } from "react-intl";
3+
4+
import { PillButton } from "@/ui/PillButton/PillButton";
5+
6+
const messages = defineMessages({
7+
heading: {
8+
defaultMessage: "Transaction Rejected",
9+
},
10+
message: {
11+
defaultMessage:
12+
"The transaction has been rejected from your Ledger device. Please try again if you'd like to continue.",
13+
},
14+
tryAgain: {
15+
defaultMessage: "Try Again",
16+
},
17+
cancel: {
18+
defaultMessage: "Cancel",
19+
},
20+
});
21+
22+
type Props = {
23+
isLoading: boolean;
24+
handleClose: () => void;
25+
handleSubmit: () => void;
26+
};
27+
28+
export function TransactionRejected({
29+
isLoading,
30+
handleClose,
31+
handleSubmit,
32+
}: Props) {
33+
const { formatMessage } = useIntl();
34+
35+
return (
36+
<>
37+
<ModalBody px={16} pt={16}>
38+
<Heading fontSize="2xl" mb={8}>
39+
{formatMessage(messages.heading)}
40+
</Heading>
41+
<Box
42+
bg="#FFF5F1"
43+
display="flex"
44+
justifyContent="center"
45+
py={10}
46+
borderRadius={4}
47+
>
48+
<Box
49+
bg="#FFE5DD"
50+
height="116px"
51+
width="116px"
52+
borderRadius="full"
53+
display="flex"
54+
alignItems="center"
55+
justifyContent="center"
56+
>
57+
<svg width="8" height="52" viewBox="0 0 8 52" fill="none">
58+
<path
59+
d="M0.375 33.25V0.625H7.625V33.25H0.375ZM0.375 51.375V44.125H7.625V51.375H0.375Z"
60+
fill="#F15929"
61+
/>
62+
</svg>
63+
</Box>
64+
</Box>
65+
<Text fontSize="md" mt={6} color="muted">
66+
{formatMessage(messages.message)}
67+
</Text>
68+
</ModalBody>
69+
<ModalFooter display="flex" gap={2} px={16} py={8}>
70+
<PillButton
71+
size="sm"
72+
isDisabled={isLoading}
73+
onClick={handleClose}
74+
variant="inverted"
75+
border={0}
76+
>
77+
{formatMessage(messages.cancel)}
78+
</PillButton>
79+
<PillButton size="sm" isDisabled={isLoading} onClick={handleSubmit}>
80+
{formatMessage(messages.tryAgain)}
81+
</PillButton>
82+
</ModalFooter>
83+
</>
84+
);
85+
}

renderer/intl/locales/en-US.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,9 @@
324324
"JM4YI+": {
325325
"message": "Are you sure you want to remove this account?"
326326
},
327+
"Jhtmlc": {
328+
"message": "The transaction has been rejected from your Ledger device. Please try again if you'd like to continue."
329+
},
327330
"Jjpq7w": {
328331
"message": "Block Sequence"
329332
},
@@ -339,6 +342,9 @@
339342
"K3r6DQ": {
340343
"message": "Delete"
341344
},
345+
"K6NOTC": {
346+
"message": "Transaction Rejected"
347+
},
342348
"KBiJ4L": {
343349
"message": "To proceed with connecting your account to the Iron Fish Node app, please approve the request on your Ledger device."
344350
},

0 commit comments

Comments
 (0)