Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 1 addition & 21 deletions DEVELOPMENT_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,27 +94,7 @@ import { isAddress, isAddressEqual, zeroAddress, type Address } from 'viem'
enforce(isAddress(data.rewardTokenId)).isTruthy()
```

## 6. BigDecimal

A custom `BigDecimal` implementation is used for precise numerical operations:

- Use `BigDecimal` for all financial calculations to avoid floating-point errors
- Implement utility functions that work with `BigDecimal` for common operations

## 7. Custom Hooks

Several custom hooks are used throughout the project:

- Create hooks for reusable logic (e.g., `useChainId`, `useCurve`)
- Implement hooks that combine multiple queries for complex data fetching scenarios

Example:

```typescript
const { data: curve } = useCurve()
```

## 8. TypeScript
## 6. TypeScript

The project heavily uses TypeScript:

Expand Down
1 change: 0 additions & 1 deletion apps/main/src/dao/store/createAppSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ const createAppSlice = (set: SetState<State>, get: GetState<State>): AppSlice =>
const isNetworkSwitched = prevApi?.chainId != api.chainId

log('Hydrating DAO', api?.chainId, {
wallet: wallet?.chainId ?? '',
isNetworkSwitched,
})

Expand Down
3 changes: 1 addition & 2 deletions apps/main/src/dex/store/createGlobalSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,14 @@ const createGlobalSlice = (set: SetState<State>, get: GetState<State>): GlobalSl
}),
)
},
hydrate: async (curveApi, prevCurveApi, wallet) => {
hydrate: async (curveApi, prevCurveApi) => {
if (!curveApi) return

const state = get()
const isNetworkSwitched = prevCurveApi?.chainId !== curveApi.chainId
const isUserSwitched = prevCurveApi?.signerAddress !== curveApi.signerAddress
const { chainId } = curveApi
log('Hydrating DEX', curveApi?.chainId, {
wallet: wallet?.chainId ?? '',
isNetworkSwitched,
isUserSwitched,
hasRPC: !curveApi.isNoRPC,
Expand Down
3 changes: 1 addition & 2 deletions apps/main/src/lend/store/createAppSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const createAppSlice = (set: SetState<State>, get: GetState<State>): AppSlice =>
}),
)
},
hydrate: async (api, prevApi, wallet) => {
hydrate: async (api, prevApi) => {
get().updateGlobalStoreByKey('hydratedChainId', null)
if (!api) return

Expand All @@ -49,7 +49,6 @@ const createAppSlice = (set: SetState<State>, get: GetState<State>): AppSlice =>
const state = get()

log('Hydrating Lend', api.chainId, {
wallet: wallet?.chainId ?? '',
chainId: [prevApi?.chainId, api.chainId],
signerAddress: [prevApi?.signerAddress, api.signerAddress],
})
Expand Down
3 changes: 1 addition & 2 deletions apps/main/src/loan/store/createAppSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,14 @@ const createAppSlice = (set: SetState<State>, get: GetState<State>): AppSlice =>
)
},

hydrate: async (curveApi, prevCurveApi, wallet) => {
hydrate: async (curveApi, prevCurveApi) => {
if (!curveApi) return

const { loans, collaterals } = get()

const isNetworkSwitched = !!prevCurveApi?.chainId && prevCurveApi.chainId !== curveApi.chainId
const isUserSwitched = !!prevCurveApi?.signerAddress && prevCurveApi.signerAddress !== curveApi.signerAddress
log('Hydrate crvUSD', curveApi?.chainId, {
wallet: wallet?.chainId ?? '',
isNetworkSwitched,
isUserSwitched,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,10 @@ export function useWagmiWallet() {
client?.transport.request && {
provider: { request: client.transport.request },
account: { address }, // the ensName is set later when detected
chainId: client.chain.id,
}
hackSignerInCypress(wallet)
return { wallet, provider: wallet ? new BrowserProvider(wallet.provider) : null }
}, [address, client?.chain.id, client?.transport.request]) ?? null),
}, [address, client?.transport.request]) ?? null),
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { type ReactNode, useEffect, useState } from 'react'
import { useSwitchChain } from 'wagmi'
import { useChainId, useSwitchChain } from 'wagmi'
import type { NetworkDef } from '@ui/utils'
import { ConnectionContext, useWagmiWallet } from '@ui-kit/features/connect-wallet/lib/ConnectionContext'
import { ConnectState } from '@ui-kit/features/connect-wallet/lib/types'
Expand Down Expand Up @@ -27,6 +27,7 @@ export const ConnectionProvider = <TChainId extends number, NetworkConfig extend
children: ReactNode
}) => {
const [connectState, setConnectState] = useState<ConnectState>(LOADING)
const chainId = useChainId()
const { switchChainAsync } = useSwitchChain()
const { wallet, provider, isReconnecting } = useWagmiWallet()
const isFocused = useIsDocumentFocused()
Expand All @@ -38,12 +39,12 @@ export const ConnectionProvider = <TChainId extends number, NetworkConfig extend
* This is separate from the rest of initApp to avoid unnecessary reinitialization, as isFocused can change frequently.
*/
async function updateWalletChain() {
const chainId = Number(network.chainId) as TChainId
if (wallet && wallet?.chainId !== chainId) {
const networkChainId = Number(network.chainId) as TChainId
if (networkChainId !== chainId) {
setConnectState(LOADING)
if (isFocused && !(await switchChainAsync({ chainId: chainId as WagmiChainId }))) {
if (isFocused && !(await switchChainAsync({ chainId: networkChainId as WagmiChainId }))) {
setConnectState(FAILURE)
onChainUnavailable([chainId, wallet?.chainId as TChainId])
onChainUnavailable([networkChainId, chainId as TChainId])
}
return // hook is called again after since it depends on walletChainId
}
Expand All @@ -52,7 +53,7 @@ export const ConnectionProvider = <TChainId extends number, NetworkConfig extend
console.error('Error updating wallet chain', e)
setConnectState(FAILURE)
})
}, [isFocused, network.chainId, onChainUnavailable, switchChainAsync, wallet])
}, [isFocused, chainId, network.chainId, onChainUnavailable, switchChainAsync, wallet])

useEffect(() => {
if (isReconnecting) return // wait for wagmi to auto-reconnect
Expand All @@ -63,14 +64,14 @@ export const ConnectionProvider = <TChainId extends number, NetworkConfig extend
* Initialize the app by connecting to the wallet and setting up the library.
*/
const initApp = async () => {
const chainId = Number(network.chainId) as TChainId
const networkChainId = Number(network.chainId) as TChainId
try {
if (wallet && wallet?.chainId !== chainId) {
if (chainId !== networkChainId) {
return // wait for the wallet to be connected to the right chain
}

const prevLib = globalLibs.get(libKey)
if (isWalletMatching(wallet, prevLib, chainId)) {
if (isWalletMatching(wallet, prevLib, networkChainId)) {
setConnectState(SUCCESS)
return // already connected to the right chain and wallet, no need to reinitialize
}
Expand All @@ -79,7 +80,7 @@ export const ConnectionProvider = <TChainId extends number, NetworkConfig extend
setConnectState(LOADING)
console.info(
`Initializing ${libKey} for ${network.name} (${network.chainId})`,
wallet ? `Wallet ${wallet?.account?.address} with chain ${wallet?.chainId}` : 'without wallet',
wallet ? `Wallet ${wallet?.account?.address} with chain ${chainId}` : 'without wallet',
prevLib
? `Old library had ${prevLib.signerAddress ? `signer ${prevLib.signerAddress}` : 'no signer'} with chain ${prevLib.chainId}`
: `First initialization`,
Expand All @@ -97,7 +98,7 @@ export const ConnectionProvider = <TChainId extends number, NetworkConfig extend
}
void initApp()
return () => abort.abort()
}, [isReconnecting, libKey, network, wallet])
}, [chainId, isReconnecting, libKey, network, wallet])

const curveApi = globalLibs.getMatching('curveApi', wallet, network?.chainId)
const llamaApi = globalLibs.getMatching('llamaApi', wallet, network?.chainId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ import type { IChainId as CurveChainId, INetworkName as CurveNetworkId } from '@
import { type default as llamaApi } from '@curvefi/llamalend-api'
import type { IChainId as LlamaChainId, INetworkName as LlamaNetworkId } from '@curvefi/llamalend-api/lib/interfaces'

export type Wallet<TChainId extends number = number> = {
export type Wallet = {
readonly provider?: Eip1193Provider
readonly account: { address: Address; ensName?: string }
readonly chainId: TChainId
}

export enum ConnectState {
Expand Down
13 changes: 0 additions & 13 deletions packages/curve-ui-kit/src/lib/validation/validation.d.ts

This file was deleted.