diff --git a/.github/workflows/core.yaml b/.github/workflows/core.yaml index 7addece4a..f6113780d 100644 --- a/.github/workflows/core.yaml +++ b/.github/workflows/core.yaml @@ -58,6 +58,40 @@ jobs: core/typechain/ if-no-files-found: error + core-slither: + needs: [core-build] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version-file: "core/.nvmrc" + cache: "yarn" + cache-dependency-path: "core/yarn.lock" + + - name: Install Dependencies + run: yarn install --prefer-offline --frozen-lockfile + + - uses: actions/setup-python@v4 + with: + python-version: 3.11 + + - name: Install Slither + env: + SLITHER_VERSION: 0.9.6 + run: pip3 install slither-analyzer==$SLITHER_VERSION + + - name: Download Build Artifacts + uses: actions/download-artifact@v3 + with: + name: core-build + path: core/ + + - name: Run Slither + run: slither --hardhat-ignore-compile . + core-test: needs: [core-build] runs-on: ubuntu-latest diff --git a/.github/workflows/dapp.yaml b/.github/workflows/dapp.yaml new file mode 100644 index 000000000..81dc9c31c --- /dev/null +++ b/.github/workflows/dapp.yaml @@ -0,0 +1,50 @@ +name: dApp + +on: + push: + branches: + - main + paths: + - "dapp/**" + pull_request: + +defaults: + run: + working-directory: ./dapp + +jobs: + dapp-format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version-file: "dapp/.nvmrc" + cache: "yarn" + cache-dependency-path: "dapp/yarn.lock" + + - name: Install Dependencies + run: yarn install --prefer-offline --frozen-lockfile + + - name: Format + run: yarn format + + dapp-build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version-file: "dapp/.nvmrc" + cache: "yarn" + cache-dependency-path: "dapp/yarn.lock" + + - name: Install Dependencies + run: yarn install --prefer-offline --frozen-lockfile + + - name: Build + run: yarn build diff --git a/.github/workflows/website.yaml b/.github/workflows/website.yaml new file mode 100644 index 000000000..89583fbb3 --- /dev/null +++ b/.github/workflows/website.yaml @@ -0,0 +1,50 @@ +name: Website + +on: + push: + branches: + - main + paths: + - "website/**" + pull_request: + +defaults: + run: + working-directory: ./website + +jobs: + website-format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version-file: "website/.nvmrc" + cache: "yarn" + cache-dependency-path: "website/yarn.lock" + + - name: Install Dependencies + run: yarn install --prefer-offline --frozen-lockfile + + - name: Format + run: yarn format + + website-build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version-file: "website/.nvmrc" + cache: "yarn" + cache-dependency-path: "website/yarn.lock" + + - name: Install Dependencies + run: yarn install --prefer-offline --frozen-lockfile + + - name: Build + run: yarn build diff --git a/README.md b/README.md index de2f62834..df7d13b8b 100644 --- a/README.md +++ b/README.md @@ -34,3 +34,24 @@ pre-commit run --all-files # Execute hooks for specific files (e.g. Acre.sol): pre-commit run --files ./core/contracts/Acre.sol ``` + +### Slither + +[Slither](https://github.com/crytic/slither) is a static analysis framework used +for Solidity contracts verification. + +#### Install + +To install Slither execute: + +```sh +pip3 install slither-analyzer +``` + +#### Usage + +To run Slither execute: + +```sh +slither . +``` diff --git a/core/slither.config.json b/core/slither.config.json index 684a9b7cb..fed211ee1 100644 --- a/core/slither.config.json +++ b/core/slither.config.json @@ -1,4 +1,5 @@ { + "detectors_to_exclude": "assembly,naming-convention,timestamp,pragma,solc-version", "hardhat_artifacts_directory": "build", "filter_paths": "node_modules/.*" } diff --git a/dapp/README.md b/dapp/README.md index 1f77042dd..882e0e8fa 100644 --- a/dapp/README.md +++ b/dapp/README.md @@ -1,10 +1,26 @@ # Acre dApp -## Installation +The application is compatible with Ledger Live and allows people to earn yield on their Bitcoin via yield farming on Ethereum. -1. Install dependencies and start the app. - ```bash +This project was bootstrapped with [Create Vite](https://github.com/vitejs/vite/tree/main/packages/create-vite). + +## Quickstart + +Install dependencies and start the app. + + ```bash yarn install yarn start - ``` -2. Open [http://localhost:5173](http://localhost:5173) to view it in the browser. +``` + +Once the build is running, you can import the manifest on desktop: + +1. [Install Ledger Live Desktop](https://www.ledger.com/ledger-live) +2. Enable the Developer mode + + Go to the **Settings -> About** section, and click 10 times on the Ledger Live version. A new Developer section appears in the settings menu. Turn on **Enable platform dev** tools to use the developer tools window to inspect your app. +3. Add your manifest + + Click on Browse next to **Add a local app** and select the manifest file. The app is now visible in the menu. + +If you have any problems, take a look [here](https://developers.ledger.com/docs/non-dapp/tutorial/3-import/#desktop). diff --git a/dapp/src/DApp.tsx b/dapp/src/DApp.tsx index 77c6b995f..453c6c172 100644 --- a/dapp/src/DApp.tsx +++ b/dapp/src/DApp.tsx @@ -1,9 +1,8 @@ import React from "react" import { ChakraProvider, Box } from "@chakra-ui/react" import { useDetectThemeMode } from "./hooks" -import { LedgerWalletAPIProvider } from "./providers" import theme from "./theme" -import { LedgerLiveAppProvider } from "./contexts/LedgerLiveAppContext" +import { LedgerWalletAPIProvider, WalletContextProvider } from "./contexts" import Navbar from "./components/Navbar" import Overview from "./components/Overview" @@ -21,11 +20,11 @@ function DApp() { function DAppProviders() { return ( - + - + ) } diff --git a/dapp/src/components/Navbar/ConnectWallet.tsx b/dapp/src/components/Navbar/ConnectWallet.tsx index ae6583498..14a20eae5 100644 --- a/dapp/src/components/Navbar/ConnectWallet.tsx +++ b/dapp/src/components/Navbar/ConnectWallet.tsx @@ -1,4 +1,4 @@ -import React, { useContext } from "react" +import React from "react" import { Button, HStack, @@ -13,14 +13,14 @@ import { BITCOIN } from "../../constants" import { useRequestBitcoinAccount, useRequestEthereumAccount, + useWalletContext, } from "../../hooks" -import { LedgerLiveAppContext } from "../../contexts/LedgerLiveAppContext" import { formatSatoshiAmount, truncateAddress } from "../../utils" export type ConnectButtonsProps = { leftIcon: typeof Icon rightIcon: typeof Icon - account: Account | null + account: Account | undefined requestAccount: () => Promise } @@ -54,9 +54,9 @@ function ConnectButton({ } export default function ConnectWallet() { - const requestBitcoinAccount = useRequestBitcoinAccount() - const requestEthereumAccount = useRequestEthereumAccount() - const { btcAccount } = useContext(LedgerLiveAppContext) + const { requestAccount: requestBitcoinAccount } = useRequestBitcoinAccount() + const { requestAccount: requestEthereumAccount } = useRequestEthereumAccount() + const { btcAccount, ethAccount } = useWalletContext() return ( @@ -72,17 +72,17 @@ export default function ConnectWallet() { { - await requestBitcoinAccount.requestAccount() + await requestBitcoinAccount() }} /> { - await requestEthereumAccount.requestAccount() + await requestEthereumAccount() }} /> diff --git a/dapp/src/contexts/LedgerLiveAppContext.tsx b/dapp/src/contexts/LedgerLiveAppContext.tsx deleted file mode 100644 index 576462abe..000000000 --- a/dapp/src/contexts/LedgerLiveAppContext.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { Account } from "@ledgerhq/wallet-api-client" -import React, { createContext, useMemo, useState } from "react" - -type LedgerLiveAppContextValue = { - btcAccount: Account | undefined - setBtcAccount: React.Dispatch> - ethAccount: Account | undefined - setEthAccount: React.Dispatch> -} - -export const LedgerLiveAppContext = createContext({ - btcAccount: undefined, - setBtcAccount: () => {}, - ethAccount: undefined, - setEthAccount: () => {}, -}) - -export function LedgerLiveAppProvider({ - children, -}: { - children: React.ReactNode -}): React.ReactElement { - const [btcAccount, setBtcAccount] = useState(undefined) - const [ethAccount, setEthAccount] = useState(undefined) - - const contextValue: LedgerLiveAppContextValue = - useMemo( - () => ({ - btcAccount, - setBtcAccount, - ethAccount, - setEthAccount, - }), - [btcAccount, setBtcAccount, ethAccount, setEthAccount], - ) - - return ( - - {children} - - ) -} diff --git a/dapp/src/providers/LedgerWalletAPIProvider.tsx b/dapp/src/contexts/LedgerWalletAPIProvider.tsx similarity index 93% rename from dapp/src/providers/LedgerWalletAPIProvider.tsx rename to dapp/src/contexts/LedgerWalletAPIProvider.tsx index 3581cad6f..492f4ee45 100644 --- a/dapp/src/providers/LedgerWalletAPIProvider.tsx +++ b/dapp/src/contexts/LedgerWalletAPIProvider.tsx @@ -19,7 +19,7 @@ type LedgerWalletAPIProviderProps = { children: React.ReactElement } -export default function LedgerWalletAPIProvider({ +export function LedgerWalletAPIProvider({ children, }: LedgerWalletAPIProviderProps): JSX.Element { const transport = getWalletAPITransport() diff --git a/dapp/src/contexts/WalletContext.tsx b/dapp/src/contexts/WalletContext.tsx new file mode 100644 index 000000000..f327ce0bd --- /dev/null +++ b/dapp/src/contexts/WalletContext.tsx @@ -0,0 +1,38 @@ +import { Account } from "@ledgerhq/wallet-api-client" +import React, { createContext, useMemo, useState } from "react" + +type WalletContextValue = { + btcAccount: Account | undefined + setBtcAccount: React.Dispatch> + ethAccount: Account | undefined + setEthAccount: React.Dispatch> +} + +export const WalletContext = createContext( + undefined, +) + +export function WalletContextProvider({ + children, +}: { + children: React.ReactNode +}): React.ReactElement { + const [btcAccount, setBtcAccount] = useState(undefined) + const [ethAccount, setEthAccount] = useState(undefined) + + const contextValue: WalletContextValue = useMemo( + () => ({ + btcAccount, + setBtcAccount, + ethAccount, + setEthAccount, + }), + [btcAccount, setBtcAccount, ethAccount, setEthAccount], + ) + + return ( + + {children} + + ) +} diff --git a/dapp/src/contexts/index.tsx b/dapp/src/contexts/index.tsx new file mode 100644 index 000000000..3ea3058ed --- /dev/null +++ b/dapp/src/contexts/index.tsx @@ -0,0 +1,2 @@ +export * from "./WalletContext" +export * from "./LedgerWalletAPIProvider" diff --git a/dapp/src/hooks/index.ts b/dapp/src/hooks/index.ts index f07366688..038388476 100644 --- a/dapp/src/hooks/index.ts +++ b/dapp/src/hooks/index.ts @@ -1,3 +1,4 @@ export * from "./useDetectThemeMode" export * from "./useRequestBitcoinAccount" export * from "./useRequestEthereumAccount" +export * from "./useWalletContext" diff --git a/dapp/src/hooks/useRequestBitcoinAccount.ts b/dapp/src/hooks/useRequestBitcoinAccount.ts index 3f7a0d120..971a3f9ef 100644 --- a/dapp/src/hooks/useRequestBitcoinAccount.ts +++ b/dapp/src/hooks/useRequestBitcoinAccount.ts @@ -1,21 +1,20 @@ import { useRequestAccount } from "@ledgerhq/wallet-api-client-react" import { useCallback, useContext, useEffect } from "react" -import { LedgerLiveAppContext } from "../contexts/LedgerLiveAppContext" import { CURRENCY_ID_BITCOIN } from "../constants" import { UseRequestAccountReturn } from "../types" +import { WalletContext } from "../contexts" export function useRequestBitcoinAccount(): UseRequestAccountReturn { - const { setBtcAccount } = useContext(LedgerLiveAppContext) - const requestAccountResponse = useRequestAccount() - const { account, requestAccount } = requestAccountResponse + const walletContext = useContext(WalletContext) + const { account, requestAccount } = useRequestAccount() useEffect(() => { - setBtcAccount(account || undefined) - }, [account, setBtcAccount]) + walletContext?.setBtcAccount(account || undefined) + }, [account, walletContext]) const requestBitcoinAccount = useCallback(async () => { await requestAccount({ currencyIds: [CURRENCY_ID_BITCOIN] }) }, [requestAccount]) - return { ...requestAccountResponse, requestAccount: requestBitcoinAccount } + return { requestAccount: requestBitcoinAccount } } diff --git a/dapp/src/hooks/useRequestEthereumAccount.ts b/dapp/src/hooks/useRequestEthereumAccount.ts index b3c674d4c..ebeb1f268 100644 --- a/dapp/src/hooks/useRequestEthereumAccount.ts +++ b/dapp/src/hooks/useRequestEthereumAccount.ts @@ -1,21 +1,20 @@ import { useRequestAccount } from "@ledgerhq/wallet-api-client-react" import { useCallback, useContext, useEffect } from "react" -import { LedgerLiveAppContext } from "../contexts/LedgerLiveAppContext" import { CURRENCY_ID_ETHEREUM } from "../constants" import { UseRequestAccountReturn } from "../types" +import { WalletContext } from "../contexts" export function useRequestEthereumAccount(): UseRequestAccountReturn { - const { setEthAccount } = useContext(LedgerLiveAppContext) - const requestAccountResponse = useRequestAccount() - const { account, requestAccount } = requestAccountResponse + const walletContext = useContext(WalletContext) + const { account, requestAccount } = useRequestAccount() useEffect(() => { - setEthAccount(account || undefined) - }, [account, setEthAccount]) + walletContext?.setEthAccount(account || undefined) + }, [account, walletContext]) const requestEthereumAccount = useCallback(async () => { await requestAccount({ currencyIds: [CURRENCY_ID_ETHEREUM] }) }, [requestAccount]) - return { ...requestAccountResponse, requestAccount: requestEthereumAccount } + return { requestAccount: requestEthereumAccount } } diff --git a/dapp/src/hooks/useWalletContext.ts b/dapp/src/hooks/useWalletContext.ts new file mode 100644 index 000000000..0da19204b --- /dev/null +++ b/dapp/src/hooks/useWalletContext.ts @@ -0,0 +1,12 @@ +import { useContext } from "react" +import { WalletContext } from "../contexts" + +export function useWalletContext() { + const context = useContext(WalletContext) + + if (!context) { + throw new Error("WalletContext used outside of WalletContext component") + } + + return context +} diff --git a/dapp/src/providers/index.ts b/dapp/src/providers/index.ts deleted file mode 100644 index c8f56e2c2..000000000 --- a/dapp/src/providers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as LedgerWalletAPIProvider } from "./LedgerWalletAPIProvider" diff --git a/dapp/src/theme/index.ts b/dapp/src/theme/index.ts index bedf1ea49..1445d60d4 100644 --- a/dapp/src/theme/index.ts +++ b/dapp/src/theme/index.ts @@ -12,10 +12,9 @@ const defaultTheme = { colors, styles: { global: (props: StyleFunctionProps) => ({ - "html, body, #root, #root > div": { + body: { backgroundColor: mode("grey.100", "grey.300")(props), color: mode("black", "grey.80")(props), - minHeight: "100vh", }, }), }, diff --git a/dapp/src/types/ledger-live-app.ts b/dapp/src/types/ledger-live-app.ts index 84dc9fec8..c63368d3e 100644 --- a/dapp/src/types/ledger-live-app.ts +++ b/dapp/src/types/ledger-live-app.ts @@ -1,13 +1,7 @@ -import { Account, WalletAPIClient } from "@ledgerhq/wallet-api-client" - -type UseRequestAccount = { - pending: boolean - account: Account | null - error: unknown -} +import { WalletAPIClient } from "@ledgerhq/wallet-api-client" type RequestAccountParams = Parameters export type UseRequestAccountReturn = { requestAccount: (...params: RequestAccountParams) => Promise -} & UseRequestAccount +}