Skip to content

Commit

Permalink
Submit ledger network tx (#230)
Browse files Browse the repository at this point in the history
  • Loading branch information
dgca authored Aug 7, 2024
1 parent 1827b8c commit 597b34e
Show file tree
Hide file tree
Showing 14 changed files with 472 additions and 241 deletions.
18 changes: 13 additions & 5 deletions main/api/ledger/utils/ledger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { z } from "zod";
import { ledgerStore } from "../../../stores/ledgerStore";
import { handleImportAccount } from "../../accounts/handleImportAccount";
import { logger } from "../../ironfish/logger";
import { manager } from "../../manager";
import { handleSendTransactionInput } from "../../transactions/handleSendTransaction";
import { PromiseQueue } from "../../utils/promiseQueue";
import { createUnsignedTransaction } from "../../utils/transactions";
Expand Down Expand Up @@ -409,13 +410,20 @@ class LedgerManager {
throw new Error(signResponse.errorMessage || "No signature returned");
}

const splitSignParams = {
unsignedTransaction: unsignedTransactionBuffer,
const ironfish = await manager.getIronfish();
const rpcClient = await ironfish.rpcClient();

const addSignatureResponse = await rpcClient.wallet.addSignature({
unsignedTransaction,
signature: signResponse.signature.toString("hex"),
};
});

const addTransactionResponse = await rpcClient.wallet.addTransaction({
transaction: addSignatureResponse.content.transaction,
broadcast: true,
});

// @todo: Sign and submit the transaction once addSignature is available from the RPC client
return splitSignParams;
return addTransactionResponse.content;
} catch (err) {
const message =
err instanceof Error ? err.message : "Failed to import account";
Expand Down
2 changes: 1 addition & 1 deletion main/api/transactions/handleSendTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const handleSendTransactionInput = z.object({
toAccount: z.string(),
assetId: z.string(),
amount: z.string(),
fee: z.number(),
fee: z.number().nullable(),
memo: z.string().optional(),
});

Expand Down
4 changes: 2 additions & 2 deletions main/api/utils/transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const createTransactionInput = z.object({
toAccount: z.string(),
assetId: z.string(),
amount: z.string(),
fee: z.number(),
fee: z.number().nullable(),
memo: z.string().optional(),
});

Expand Down Expand Up @@ -67,7 +67,7 @@ export async function createRawTransaction({
assetId: assetId,
},
],
fee: CurrencyUtils.encode(BigInt(fee)),
fee: fee ? CurrencyUtils.encode(BigInt(fee)) : null,
feeRate: null,
expiration: undefined,
confirmations: undefined,
Expand Down
98 changes: 59 additions & 39 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
},
"license": "MPL-2.0",
"dependencies": {
"@ironfish/sdk": "2.4.1",
"@ironfish/sdk": "2.5.0",
"@ledgerhq/hw-transport-node-hid": "^6.29.1",
"electron-serve": "^1.1.0",
"keccak": "^3.0.4"
Expand Down
25 changes: 16 additions & 9 deletions renderer/components/AccountAssets/AccountAssets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const messages = defineMessages({

export function AccountAssets({ accountName }: { accountName: string }) {
const { formatMessage } = useIntl();
const { data } = trpcReact.getAccount.useQuery({
const { data: accountData } = trpcReact.getAccount.useQuery({
name: accountName,
});

Expand All @@ -63,11 +63,14 @@ export function AccountAssets({ accountName }: { accountName: string }) {
},
);

if (!data) {
if (!accountData) {
// @todo: Error handling
return null;
}

const isAccountSendEligible =
!accountData.status.viewOnly || accountData.isLedger;

return (
<Box>
<LightMode>
Expand Down Expand Up @@ -98,19 +101,19 @@ export function AccountAssets({ accountName }: { accountName: string }) {
$IRON
</Text>
<Heading as="span" color="black" mb={5}>
{formatOre(data.balances.iron.confirmed)}
{formatOre(accountData.balances.iron.confirmed)}
</Heading>
<HStack alignItems="stretch" justifyContent="center">
<ChakraLink
href={
data.status.viewOnly
!isAccountSendEligible
? "#"
: `/send?account=${accountName}`
}
>
<Tooltip
label={
data.status.viewOnly
!isAccountSendEligible
? formatMessage(messages.viewOnlySendDisabled)
: !isSynced.synced
? formatMessage(messages.syncingSendDisabled)
Expand All @@ -122,7 +125,9 @@ export function AccountAssets({ accountName }: { accountName: string }) {
<PillButton
size="sm"
as="div"
isDisabled={data.status.viewOnly || !isSynced.synced}
isDisabled={
!isAccountSendEligible || !isSynced.synced
}
>
<ArrowSend transform="scale(0.8)" />
{formatMessage(messages.sendButton)}
Expand All @@ -141,7 +146,7 @@ export function AccountAssets({ accountName }: { accountName: string }) {
<Image alt="" src={treasureChest} />
</HStack>

{data.balances.custom.length > 0 && (
{accountData.balances.custom.length > 0 && (
<Box
bg="rgba(255, 255, 255, 0.15)"
p={8}
Expand All @@ -155,10 +160,12 @@ export function AccountAssets({ accountName }: { accountName: string }) {
<Grid
gap={4}
templateColumns={
data.balances.custom.length > 1 ? "repeat(2, 1fr)" : "1fr"
accountData.balances.custom.length > 1
? "repeat(2, 1fr)"
: "1fr"
}
>
{data.balances.custom.map((balance) => {
{accountData.balances.custom.map((balance) => {
const { confirmed, assetId, asset } = balance;
const majorString = CurrencyUtils.render(
confirmed,
Expand Down
10 changes: 6 additions & 4 deletions renderer/components/AccountRow/AccountRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ export function AccountRow({
refetchInterval: 5000,
},
);

const isAccountSendEligible = !viewOnly || isLedger;
return (
<ChakraLink href={`/accounts/${name}`} w="100%">
<ShadowCard hoverable>
Expand Down Expand Up @@ -105,7 +107,7 @@ export function AccountRow({
<HStack gap={3}>
<Text as="h3">{name}</Text>
{isLedger && <LedgerChip />}
{!isLedger && viewOnly && <ViewOnlyChip />}
{!isAccountSendEligible && <ViewOnlyChip />}
</HStack>
<Heading as="span" fontWeight="regular" fontSize="2xl">
{formatOre(balance)} $IRON
Expand All @@ -120,7 +122,7 @@ export function AccountRow({
>
<Tooltip
label={
viewOnly
!isAccountSendEligible
? formatMessage(messages.viewOnlySendDisabled)
: !isSynced.synced
? formatMessage(messages.syncingSendDisabled)
Expand All @@ -131,11 +133,11 @@ export function AccountRow({
<VStack w="100%" alignItems="stretch">
<PillButton
size="sm"
isDisabled={viewOnly || !isSynced.synced}
isDisabled={!isAccountSendEligible || !isSynced.synced}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
if (viewOnly || !isSynced.synced) return;
if (!isAccountSendEligible || !isSynced.synced) return;
router.push(`/send?account=${name}`);
}}
>
Expand Down
Loading

0 comments on commit 597b34e

Please sign in to comment.