Skip to content

Commit

Permalink
Connect the dApp with Ethereum account
Browse files Browse the repository at this point in the history
  • Loading branch information
kkosiorowska committed Nov 16, 2023
1 parent 98e4412 commit 3139bc8
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 41 deletions.
4 changes: 3 additions & 1 deletion dapp/manifest-ledger-live-app.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
],
"currencies": [
"bitcoin",
"bitcoin_testnet"
"bitcoin_testnet",
"ethereum",
"ethereum_goerli"
],
"content": {
"shortDescription": {
Expand Down
16 changes: 16 additions & 0 deletions dapp/src/assets/ethereum.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 0 additions & 34 deletions dapp/src/components/Navbar/AccountInfo.tsx

This file was deleted.

84 changes: 84 additions & 0 deletions dapp/src/components/Navbar/ConnectWallet.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React, { useContext } from "react"
import { Box, Button, Image, Text } from "@chakra-ui/react"
import { Account } from "@ledgerhq/wallet-api-client"
import BitcoinIcon from "../../assets/bitcoin.svg"
import EthereumIcon from "../../assets/ethereum.svg"
import InfoIcon from "../../assets/info.svg"
import { truncateAddress } from "../../utils"
import { BITCOIN } from "../../constants"
import {
useEmbedFeatureFlag,
useRequestBitcoinAccount,
useRequestEthereumAccount,
} from "../../hooks"
import { LedgerLiveAppContext } from "../../contexts/LedgerLiveAppProvider"

export type ConnectButtonsProps = {
leftIcon: string
rightIcon: string
account: Account | null
requestAccount: () => Promise<void>
}

function ConnectButton({
leftIcon,
rightIcon,
account,
requestAccount,
}: ConnectButtonsProps) {
return (
<Button
variant="outline"
leftIcon={<Image src={leftIcon} />}
rightIcon={!account ? <Image src={rightIcon} /> : undefined}
onClick={requestAccount}
>
{account ? truncateAddress(account.address) : "Not connected"}
</Button>
)
}

function LedgerLiveAppConnectWallet() {
const requestBitcoinAccount = useRequestBitcoinAccount()
const requestEthereumAccount = useRequestEthereumAccount()

return (
<>
<ConnectButton
leftIcon={BitcoinIcon}
rightIcon={InfoIcon}
account={requestBitcoinAccount.account}
requestAccount={async () => {
await requestBitcoinAccount.requestAccount()
}}
/>
<ConnectButton
leftIcon={EthereumIcon}
rightIcon={InfoIcon}
account={requestEthereumAccount.account}
requestAccount={async () => {
await requestEthereumAccount.requestAccount()
}}
/>
</>
)
}

export default function ConnectWallet() {
const { isEmbed } = useEmbedFeatureFlag()
// TODO: If isEmbed is set to false, let's use a different context
const { btcAccount } = useContext(LedgerLiveAppContext)

return (
<Box display="flex" alignItems="center" gap="4">
<Box display="flex" gap="2">
<Text>Balance</Text>
<Text as="b">
{!btcAccount ? "0.00" : btcAccount.balance.toString()}
</Text>
<Text>{BITCOIN.token}</Text>
</Box>
{isEmbed && <LedgerLiveAppConnectWallet />}
</Box>
)
}
4 changes: 2 additions & 2 deletions dapp/src/components/Navbar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from "react"
import { Box } from "@chakra-ui/react"
import AccountInfo from "./AccountInfo"
import ConnectWallet from "./ConnectWallet"

export default function Navbar() {
return (
<Box p={4} display="flex" justifyContent="end">
<AccountInfo />
<ConnectWallet />
</Box>
)
}
3 changes: 3 additions & 0 deletions dapp/src/constants/chains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ export const BITCOIN = {

export const CURRENCY_ID_BITCOIN =
import.meta.env.VITE_USE_TESTNET === "true" ? "bitcoin_testnet" : "bitcoin"

export const CURRENCY_ID_ETHEREUM =
import.meta.env.VITE_USE_TESTNET === "true" ? "ethereum_goerli" : "ethereum"
9 changes: 8 additions & 1 deletion dapp/src/contexts/LedgerLiveAppProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ import React, { createContext, useMemo, useState } from "react"
type LedgerLiveAppContextValue = {
btcAccount: Account | undefined
setBtcAccount: React.Dispatch<React.SetStateAction<Account | undefined>>
ethAccount: Account | undefined
setEthAccount: React.Dispatch<React.SetStateAction<Account | undefined>>
}

export const LedgerLiveAppContext = createContext<LedgerLiveAppContextValue>({
btcAccount: undefined,
setBtcAccount: () => {},
ethAccount: undefined,
setEthAccount: () => {},
})

export function LedgerLiveAppProvider({
Expand All @@ -17,14 +21,17 @@ export function LedgerLiveAppProvider({
children: React.ReactNode
}): React.ReactElement {
const [btcAccount, setBtcAccount] = useState<Account | undefined>(undefined)
const [ethAccount, setEthAccount] = useState<Account | undefined>(undefined)

const contextValue: LedgerLiveAppContextValue =
useMemo<LedgerLiveAppContextValue>(
() => ({
btcAccount,
setBtcAccount,
ethAccount,
setEthAccount,
}),
[btcAccount, setBtcAccount],
[btcAccount, setBtcAccount, ethAccount, setEthAccount],
)

return (
Expand Down
23 changes: 20 additions & 3 deletions dapp/src/hooks/account-hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@ import { Account, WalletAPIClient } from "@ledgerhq/wallet-api-client"
import { useRequestAccount } from "@ledgerhq/wallet-api-client-react"
import { useCallback, useContext, useEffect } from "react"
import { LedgerLiveAppContext } from "../contexts/LedgerLiveAppProvider"
import { CURRENCY_ID_BITCOIN } from "../constants"
import { CURRENCY_ID_BITCOIN, CURRENCY_ID_ETHEREUM } from "../constants"

type UseRequestAccount = {
pending: boolean
account: Account | null
error: unknown
}

type RequestAccountParams = Parameters<WalletAPIClient["account"]["request"]>
export type RequestAccountParams = Parameters<
WalletAPIClient["account"]["request"]
>

type UseRequestAccountReturn = {
requestAccount: (...params: RequestAccountParams) => Promise<void>
} & UseRequestAccount

// eslint-disable-next-line import/prefer-default-export
export function useRequestBitcoinAccount(): UseRequestAccountReturn {
const { setBtcAccount } = useContext(LedgerLiveAppContext)
const requestAccountResponse = useRequestAccount()
Expand All @@ -32,3 +33,19 @@ export function useRequestBitcoinAccount(): UseRequestAccountReturn {

return { ...requestAccountResponse, requestAccount: requestBitcoinAccount }
}

export function useRequestEthereumAccount(): UseRequestAccountReturn {
const { setEthAccount } = useContext(LedgerLiveAppContext)
const requestAccountResponse = useRequestAccount()
const { account, requestAccount } = requestAccountResponse

useEffect(() => {
setEthAccount(account || undefined)
}, [account, setEthAccount])

const requestEthereumAccount = useCallback(async () => {
await requestAccount({ currencyIds: [CURRENCY_ID_ETHEREUM] })
}, [requestAccount])

return { ...requestAccountResponse, requestAccount: requestEthereumAccount }
}

0 comments on commit 3139bc8

Please sign in to comment.