Skip to content

Commit

Permalink
Merge branch 'main' into landing-page
Browse files Browse the repository at this point in the history
  • Loading branch information
kpyszkowski committed May 9, 2024
2 parents a6b63d9 + f4e29b1 commit ed28606
Show file tree
Hide file tree
Showing 53 changed files with 1,229 additions and 570 deletions.
2 changes: 2 additions & 0 deletions dapp/.env
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ VITE_REFERRAL=123

# TODO: Pass this value as an environment variable during the build process.
VITE_DEFENDER_RELAYER_WEBHOOK_URL="https://api.defender.openzeppelin.com/actions/a0d6d2e2-ce9c-4619-aa2b-6c874fe97af7/runs/webhook/b1f17c89-8230-46e3-866f-a3213887974c/Sbddsy54cJ6sPg2bLPyuHJ"

VITE_ACRE_SUBGRAPH_URL="https://api.studio.thegraph.com/query/73600/acre/version/latest"
3 changes: 3 additions & 0 deletions dapp/src/acre-react/contexts/AcreSdkContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import React, { useCallback, useMemo, useState } from "react"
import { LedgerLiveEthereumSigner } from "#/web3"
import { Acre, EthereumNetwork } from "@acre-btc/sdk"

const TBTC_API_ENDPOINT = import.meta.env.VITE_TBTC_API_ENDPOINT

type AcreSdkContextValue = {
acre?: Acre
init: (ethereumAddress: string, network: EthereumNetwork) => Promise<void>
Expand All @@ -25,6 +27,7 @@ export function AcreSdkProvider({ children }: { children: React.ReactNode }) {
const sdk = await Acre.initializeEthereum(
await LedgerLiveEthereumSigner.fromAddress(ethereumAddress),
network,
TBTC_API_ENDPOINT,
)
setAcre(sdk)
setIsInitialized(true)
Expand Down
4 changes: 0 additions & 4 deletions dapp/src/acre-react/hooks/useStakeFlow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { useCallback, useState } from "react"
import {
StakeInitialization,
EthereumAddress,
DepositorProxy,
DepositReceipt,
} from "@acre-btc/sdk"
import { useAcreContext } from "./useAcreContext"
Expand All @@ -12,7 +11,6 @@ export type UseStakeFlowReturn = {
bitcoinRecoveryAddress: string,
ethereumAddress: string,
referral: number,
depositor?: DepositorProxy,
) => Promise<void>
btcAddress?: string
depositReceipt?: DepositReceipt
Expand All @@ -36,15 +34,13 @@ export function useStakeFlow(): UseStakeFlowReturn {
bitcoinRecoveryAddress: string,
ethereumAddress: string,
referral: number,
depositor?: DepositorProxy,
) => {
if (!acre || !isInitialized) throw new Error("Acre SDK not defined")

const initializedStakeFlow = await acre.staking.initializeStake(
bitcoinRecoveryAddress,
EthereumAddress.from(ethereumAddress),
referral,
depositor,
)

const btcDepositAddress = await initializedStakeFlow.getBitcoinAddress()
Expand Down
11 changes: 1 addition & 10 deletions dapp/src/contexts/StakeFlowContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import {
useStakeFlow,
} from "#/acre-react/hooks"
import { REFERRAL } from "#/constants"
import { RelayerDepositorProxy } from "#/web3"
import { EthereumBitcoinDepositor } from "@acre-btc/sdk"

type StakeFlowContextValue = Omit<UseStakeFlowReturn, "initStake"> & {
initStake: (
Expand Down Expand Up @@ -35,14 +33,7 @@ export function StakeFlowProvider({ children }: { children: React.ReactNode }) {
async (bitcoinRecoveryAddress: string, ethereumAddress: string) => {
if (!acre) throw new Error("Acre SDK not defined")

await acreInitStake(
bitcoinRecoveryAddress,
ethereumAddress,
REFERRAL,
RelayerDepositorProxy.fromEthereumBitcoinDepositor(
acre.contracts.bitcoinDepositor as EthereumBitcoinDepositor,
),
)
await acreInitStake(bitcoinRecoveryAddress, ethereumAddress, REFERRAL)
},
[acreInitStake, acre],
)
Expand Down
1 change: 1 addition & 0 deletions dapp/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export * from "./store"
export * from "./toasts"
export * from "./sdk"
export * from "./subgraph"
export * from "./useDetectThemeMode"
export * from "./useRequestBitcoinAccount"
export * from "./useRequestEthereumAccount"
Expand Down
2 changes: 2 additions & 0 deletions dapp/src/hooks/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ export * from "./useAppSelector"
export * from "./useEstimatedBTCBalance"
export * from "./useSharesBalance"
export * from "./useMinDepositAmount"
// TODO: Rename when the old hook is deleted.
export { useActivities as useActivitiesNEW } from "./useActivities"
6 changes: 6 additions & 0 deletions dapp/src/hooks/store/useActivities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { selectActivities } from "#/store/wallet"
import { useAppSelector } from "./useAppSelector"

export function useActivities() {
return useAppSelector(selectActivities)
}
2 changes: 2 additions & 0 deletions dapp/src/hooks/subgraph/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./useInitDataFromSubgraph"
export * from "./useFetchActivities"
24 changes: 24 additions & 0 deletions dapp/src/hooks/subgraph/useFetchActivities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { useCallback } from "react"
import { subgraphAPI } from "#/utils"
import { setActivities } from "#/store/wallet"
import { useAppDispatch } from "../store/useAppDispatch"
import { useWalletContext } from "../useWalletContext"

// TODO: Use the correct function from SDK
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const calculateEthAddress = (btcAddress: string) =>
"0x4c9e39e5ff458a811708c03aea21b8327118cf13"

export function useFetchActivities() {
const dispatch = useAppDispatch()
const { btcAccount } = useWalletContext()

return useCallback(async () => {
if (!btcAccount) return

const ethAddress = calculateEthAddress(btcAccount.address)
const result = await subgraphAPI.fetchActivityData(ethAddress)

dispatch(setActivities(result))
}, [btcAccount, dispatch])
}
15 changes: 15 additions & 0 deletions dapp/src/hooks/subgraph/useInitDataFromSubgraph.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { useEffect } from "react"
import { logPromiseFailure } from "#/utils"
import { useFetchActivities } from "./useFetchActivities"
import { useWalletContext } from "../useWalletContext"

export function useInitDataFromSubgraph() {
const { btcAccount } = useWalletContext()
const fetchActivities = useFetchActivities()

useEffect(() => {
if (btcAccount) {
logPromiseFailure(fetchActivities())
}
}, [btcAccount, fetchActivities])
}
5 changes: 4 additions & 1 deletion dapp/src/hooks/useInitApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ import { useInitDataFromSdk, useInitializeAcreSdk } from "./sdk"
import { useSentry } from "./sentry"
import { useFetchBTCPriceUSD } from "./useFetchBTCPriceUSD"
import { useInitGlobalToasts } from "./toasts/useInitGlobalToasts"
import { useInitDataFromSubgraph } from "./subgraph"

export function useInitApp() {
// TODO: Let's uncomment when dark mode is ready
// useDetectThemeMode()
useSentry()
useInitializeAcreSdk()
useInitDataFromSdk()
useFetchBTCPriceUSD()
useInitGlobalToasts()

useInitDataFromSdk()
useInitDataFromSubgraph()
}
2 changes: 2 additions & 0 deletions dapp/src/store/reducer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { combineReducers } from "@reduxjs/toolkit"
import { btcSlice } from "./btc/btcSlice"
import { walletSlice } from "./wallet/walletSlice"

export const reducer = combineReducers({
btc: btcSlice.reducer,
wallet: walletSlice.reducer,
})
2 changes: 2 additions & 0 deletions dapp/src/store/wallet/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./walletSelector"
export * from "./walletSlice"
5 changes: 5 additions & 0 deletions dapp/src/store/wallet/walletSelector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Activity } from "#/types"
import { RootState } from ".."

export const selectActivities = (state: RootState): Activity[] =>
state.wallet.activities
22 changes: 22 additions & 0 deletions dapp/src/store/wallet/walletSlice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Activity } from "#/types"
import { PayloadAction, createSlice } from "@reduxjs/toolkit"

type WalletState = {
activities: Activity[]
}

const initialState: WalletState = {
activities: [],
}

export const walletSlice = createSlice({
name: "wallet",
initialState,
reducers: {
setActivities(state, action: PayloadAction<Activity[]>) {
state.activities = action.payload
},
},
})

export const { setActivities } = walletSlice.actions
7 changes: 7 additions & 0 deletions dapp/src/types/activity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,10 @@ export type ActivityInfo = {
txHash: string
status: ActivityInfoStatus
}

export type Activity = {
txHash: string
amount: bigint
type: "deposit" | "withdraw"
status: "completed" | "pending"
}
1 change: 1 addition & 0 deletions dapp/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ export * from "./toast"
export * from "./core"
export * from "./fee"
export * from "./navigation"
export * from "./subgraphAPI"
6 changes: 6 additions & 0 deletions dapp/src/types/subgraphAPI.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export type ActivityDataResponse = {
id: string
bitcoinTransactionId: string
amountToDeposit: string
events: { type: "Initialized" | "Finalized" }[]
}
1 change: 1 addition & 0 deletions dapp/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export * from "./promise"
export * from "./exchangeApi"
export * from "./verifyDepositAddress"
export * from "./json"
export * from "./subgraphAPI"
58 changes: 58 additions & 0 deletions dapp/src/utils/subgraphAPI.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import axios from "axios"
import { Activity, ActivityDataResponse } from "#/types"

const ACRE_SUBGRAPH_URL = import.meta.env.VITE_ACRE_SUBGRAPH_URL

const mapToActivity = (activityData: ActivityDataResponse): Activity => {
const { bitcoinTransactionId: txHash, amountToDeposit, events } = activityData

const status = events.some(({ type }) => type === "Finalized")
? "completed"
: "pending"

return {
txHash,
amount: BigInt(amountToDeposit),
type: "deposit",
status,
}
}

// TODO: Fetch transactions for withdrawals
/**
* Returns the activities for a given account.
* @param account The Ethereum address for which the activities will be fetched.
*/
async function fetchActivityData(account: string): Promise<Activity[]> {
const response = await axios.post<{
errors?: unknown
data: { activityDatas: ActivityDataResponse[] }
}>(ACRE_SUBGRAPH_URL, {
query: `query {
activityDatas(
where: {depositOwner_: {id: "${account}"}}
) {
id
bitcoinTransactionId
events {
type
}
... on Deposit {
amountToDeposit
}
}
}`,
})

if (response.data && response.data.errors) {
const errorMsg = "Failed to fetch data from Acre subgraph API."
console.error(errorMsg, response.data.errors)
throw new Error(errorMsg)
}

return response.data.data.activityDatas.map(mapToActivity)
}

export const subgraphAPI = {
fetchActivityData,
}
3 changes: 2 additions & 1 deletion dapp/src/vite-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ interface ImportMetaEnv {
readonly VITE_SENTRY_DSN: string
readonly VITE_ETH_HOSTNAME_HTTP: string
readonly VITE_REFERRAL: number
readonly VITE_DEFENDER_RELAYER_WEBHOOK_URL: string
readonly VITE_TBTC_API_ENDPOINT: string
readonly VITE_ACRE_SUBGRAPH_URL: string
}

interface ImportMeta {
Expand Down
1 change: 0 additions & 1 deletion dapp/src/web3/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export * from "./ledger-live-signer"
export * from "./relayer-depositor-proxy"
Loading

0 comments on commit ed28606

Please sign in to comment.