Skip to content

Commit

Permalink
fix: token check bug (#286)
Browse files Browse the repository at this point in the history
Resolves a bug introduced with the PR #282 which upgrades the starknetjs
version but ignores @starknet-react/core and @starknet-react/chains
packages.
I had to make changes to a few files to be able upgrade it, since there
are API changes with the newer versions.
I also fixed minor warnings in the tg-bot package.
I also created 2 new CI jobs for core & hooks packages.

## Package version changes
- starknet peer dependency upgraded from >=5.0.0 to >=6.8.0
- @starknet-react/core dependency upgraded from 2.2.4 to 3.6.2
- @starknet-react/core peer dependency upgraded from >=2.0.0 to >=3.0.0
- @starknet-react/chains dependency upgraded from 0.1.0 to 3.1.0
- @tanstack/react-query dependency upgraded from 5.0.1 to 5.25.0
- @starknet-io/types-js dependency installed with version ^0.7.10
  • Loading branch information
ugur-eren authored Dec 3, 2024
1 parent 0eecbd9 commit 7e83489
Show file tree
Hide file tree
Showing 21 changed files with 314 additions and 169 deletions.
39 changes: 39 additions & 0 deletions .github/workflows/core.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Core

on:
push:
paths: [packages/core/**]
pull_request:
paths: [packages/core/**]

permissions: read-all

jobs:
check:
defaults:
run:
working-directory: packages/core

runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '18'

- name: Install dependencies
run: yarn install
working-directory: ./

- name: Lint
run: yarn lint

- name: Test
run: yarn test

- name: Build
run: yarn build
44 changes: 44 additions & 0 deletions .github/workflows/hooks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Hooks

on:
push:
paths: [packages/hooks/**]
pull_request:
paths: [packages/hooks/**]

permissions: read-all

jobs:
check:
defaults:
run:
working-directory: packages/hooks

runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '18'

- name: Install dependencies
run: yarn install
working-directory: ./

# Core package is required for hooks to test and build
- name: Build Core
run: yarn build
working-directory: ./packages/core

- name: Lint
run: yarn lint

- name: Test
run: yarn test

- name: Build Hooks
run: yarn build
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"moment": "^2.30.1"
},
"peerDependencies": {
"starknet": ">=5.0.0"
"starknet": ">=6.8.0"
},
"devDependencies": {
"@uniswap/eslint-config": "^1.2.0",
Expand Down
19 changes: 10 additions & 9 deletions packages/core/src/constants/contracts.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,50 @@
import { MultichainAddress } from 'src/types'
import { constants, json } from 'starknet'

import EkuboPositions from '../abis/EkuboPositions.json'
import JediswapPair from '../abis/JediswapPair.json'
import Multicall from '../abis/Multicall.json'

export const TOKEN_CLASS_HASH = {
export const TOKEN_CLASS_HASH: MultichainAddress = {
[constants.StarknetChainId.SN_SEPOLIA]: '0x063ee878d3559583ceae80372c6088140e1180d9893aa65fbefc81f45ddaaa17',
[constants.StarknetChainId.SN_MAIN]: '0x063ee878d3559583ceae80372c6088140e1180d9893aa65fbefc81f45ddaaa17',
}

export const FACTORY_ADDRESSES = {
export const FACTORY_ADDRESSES: MultichainAddress = {
[constants.StarknetChainId.SN_SEPOLIA]: '0x06b5096ba5a3c30e231e7b74ca565594d167a0a22d71cce0ebf9ae2b06584097',
[constants.StarknetChainId.SN_MAIN]: '0x01a46467a9246f45c8c340f1f155266a26a71c07bd55d36e8d1c7d0d438a2dbc',
}

export const EKUBO_POSITIONS_ADDRESSES = {
export const EKUBO_POSITIONS_ADDRESSES: MultichainAddress = {
[constants.StarknetChainId.SN_SEPOLIA]: '0x06a2aee84bb0ed5dded4384ddd0e40e9c1372b818668375ab8e3ec08807417e5',
[constants.StarknetChainId.SN_MAIN]: '0x02e0af29598b407c8716b17f6d2795eca1b471413fa03fb145a5e33722184067',
}

export const ETH_ADDRESSES = {
export const ETH_ADDRESSES: MultichainAddress = {
[constants.StarknetChainId.SN_SEPOLIA]: '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',
[constants.StarknetChainId.SN_MAIN]: '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',
}
export const STRK_ADDRESSES = {
export const STRK_ADDRESSES: MultichainAddress = {
[constants.StarknetChainId.SN_SEPOLIA]: '0x4718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d',
[constants.StarknetChainId.SN_MAIN]: '0x4718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d',
}

export const USDC_ADDRESSES = {
export const USDC_ADDRESSES: MultichainAddress = {
[constants.StarknetChainId.SN_SEPOLIA]: '0x5a643907b9a4bc6a55e9069c4fd5fd1f5c79a22470690f75556c4736e34426',
[constants.StarknetChainId.SN_MAIN]: '0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8',
}

export const MULTICALL_ADDRESSES = {
export const MULTICALL_ADDRESSES: MultichainAddress = {
[constants.StarknetChainId.SN_SEPOLIA]: '0x01a33330996310a1e3fa1df5b16c1e07f0491fdd20c441126e02613b948f0225',
[constants.StarknetChainId.SN_MAIN]: '0x01a33330996310a1e3fa1df5b16c1e07f0491fdd20c441126e02613b948f0225',
}

export const JEDISWAP_ETH_USDC = {
export const JEDISWAP_ETH_USDC: MultichainAddress = {
[constants.StarknetChainId.SN_SEPOLIA]: '0x05a2b2b37f66157f767ea711cb4e034c40d41f2f5acf9ff4a19049fa11c1a884',
[constants.StarknetChainId.SN_MAIN]: '0x04d0390b777b424e43839cd1e744799f3de6c176c7e32c1812a41dbd9c19db6a',
}

export const JEDISWAP_STRK_USDC = {
export const JEDISWAP_STRK_USDC: MultichainAddress = {
[constants.StarknetChainId.SN_SEPOLIA]: '0x018b129b1a372b3288077521ad8749f5a2b2ddfb67ef5a37e2d02190fa11c40f',
[constants.StarknetChainId.SN_MAIN]: '0x5726725e9507c3586cc0516449e2c74d9b201ab2747752bb0251aaa263c9a26',
}
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/types/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ export type Token = {
}

export type MultichainToken = { [chainId in constants.StarknetChainId]: Token }

export type MultichainAddress = { [chainId in constants.StarknetChainId]: `0x${string}` }
7 changes: 4 additions & 3 deletions packages/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
"dependencies": {
"@avnu/avnu-sdk": "^2.0.0",
"@hookform/resolvers": "^3.3.2",
"@starknet-react/chains": "^0.1.0",
"@starknet-react/core": "^2.2.4",
"@tanstack/react-query": "^5.0.1",
"@starknet-io/types-js": "^0.7.10",
"@starknet-react/chains": "^3.1.0",
"@starknet-react/core": "^3.6.2",
"@tanstack/react-query": "^5.25.0",
"@types/react-dom": "^18.2.1",
"@uniswap/sdk-core": "^4.0.9",
"@vanilla-extract/css": "^1.11.0",
Expand Down
26 changes: 13 additions & 13 deletions packages/frontend/src/components/TransactionModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useContractWrite, useWaitForTransaction } from '@starknet-react/core'
import { useSendTransaction, useTransactionReceipt } from '@starknet-react/core'
import { useEffect, useMemo, useState } from 'react'
import { STARKNET_POLLING } from 'src/constants/misc'
import { useCloseModal, useTransactionModal } from 'src/hooks/useModal'
Expand All @@ -15,8 +15,8 @@ import Overlay from '../Modal/Overlay'
import Spinner from '../Spinner'
import * as styles from './style.css'

type UseWaitForTransactionResponse = Omit<ReturnType<typeof useWaitForTransaction>, 'data'> & {
data?: { finality_status?: TransactionStatus }
type UseWaitForTransactionResponse = Omit<ReturnType<typeof useTransactionReceipt>, 'data'> & {
data?: { value?: { finality_status?: TransactionStatus } }
}

export function TransactionModal() {
Expand All @@ -31,21 +31,21 @@ export function TransactionModal() {
const close = useCloseModal()

// starknet
const { writeAsync } = useContractWrite({})
const { sendAsync } = useSendTransaction({})

// calls
const [invokeTransactionDetails, resetTransaction] = useTransaction()

// transaction status
const { data, refetch } = useWaitForTransaction({
const { data, refetch } = useTransactionReceipt({
retry: true,
retryDelay: STARKNET_POLLING,
refetchInterval: STARKNET_POLLING,
hash: isOpen ? transactionHash ?? undefined : undefined,
}) as UseWaitForTransactionResponse

const statusComponent = useMemo(() => {
switch (data?.finality_status) {
switch (data?.value?.finality_status) {
// Success
case TransactionStatus.ACCEPTED_ON_L1:
case TransactionStatus.ACCEPTED_ON_L2:
Expand All @@ -69,11 +69,11 @@ export function TransactionModal() {
}

return
}, [data?.finality_status])
}, [data?.value?.finality_status])

// refetch
useEffect(() => {
if (!isOpen || (data?.finality_status && data.finality_status !== TransactionStatus.RECEIVED)) return
if (!isOpen || (data?.value?.finality_status && data.value.finality_status !== TransactionStatus.RECEIVED)) return

const intervalId = setInterval(() => {
setTransactionHash((state) => {
Expand All @@ -86,21 +86,21 @@ export function TransactionModal() {
}, STARKNET_POLLING)

return () => clearInterval(intervalId)
}, [data?.finality_status, isOpen, refetch])
}, [data?.value?.finality_status, isOpen, refetch])

// onSuccess callback
useEffect(() => {
if (accepted || !currentInvokeTransactionDetails?.onSuccess) return

switch (data?.finality_status) {
switch (data?.value?.finality_status) {
// Success
case TransactionStatus.ACCEPTED_ON_L1:
case TransactionStatus.ACCEPTED_ON_L2:
setAccepted(true)
currentInvokeTransactionDetails.onSuccess()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [accepted, data?.finality_status, currentInvokeTransactionDetails?.onSuccess])
}, [accepted, data?.value?.finality_status, currentInvokeTransactionDetails?.onSuccess])

// error component
const errorComponent = useMemo(() => {
Expand All @@ -123,7 +123,7 @@ export function TransactionModal() {
useEffect(() => {
if (!currentInvokeTransactionDetails) return

writeAsync({ calls: currentInvokeTransactionDetails.calls })
sendAsync(currentInvokeTransactionDetails.calls)
.then((res) => {
setTransactionHash(res.transaction_hash)
})
Expand All @@ -134,7 +134,7 @@ export function TransactionModal() {
})

resetTransaction()
}, [resetTransaction, currentInvokeTransactionDetails, writeAsync])
}, [resetTransaction, currentInvokeTransactionDetails, sendAsync])

// updating current invoke transaction details
useEffect(() => {
Expand Down
4 changes: 2 additions & 2 deletions packages/frontend/src/components/WalletModal/Option.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ interface OptionProps {
}

function Option({ connection, activate }: OptionProps) {
const icon = connection.icon.dark
const icon = typeof connection.icon === 'string' ? connection.icon : connection.icon.dark
const isSvg = icon?.startsWith('<svg')

return (
<Row gap="12" className={styles.option} onClick={activate}>
{isSvg ? (
<Box width="32" height="32" dangerouslySetInnerHTML={{ __html: icon ?? '' }} /> /* display svg */
) : (
<Box as="img" width="32" height="32" src={connection.icon.dark} />
<Box as="img" width="32" height="32" src={icon} />
)}
<Text.Body>{connection.name}</Text.Body>
</Row>
Expand Down
12 changes: 10 additions & 2 deletions packages/frontend/src/components/Web3Provider/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { argent, braavos, StarknetConfig, starkscan, useInjectedConnectors, useNetwork } from '@starknet-react/core'
import {
argent,
braavos,
Connector,
StarknetConfig,
starkscan,
useInjectedConnectors,
useNetwork,
} from '@starknet-react/core'
import { QueryClient } from '@tanstack/react-query'
import { Provider as HooksProvider } from 'hooks'
import { useMemo } from 'react'
Expand All @@ -22,7 +30,7 @@ export function StarknetProvider({ children }: React.PropsWithChildren) {
...injected,
new WebWalletConnector({ url: 'https://web.argent.xyz' }),
new ArgentMobileConnector(),
]
] as Connector[]

return (
<StarknetConfig
Expand Down
8 changes: 4 additions & 4 deletions packages/frontend/src/constants/networks.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Chain, goerli, mainnet } from '@starknet-react/chains'
import { Chain, mainnet, sepolia } from '@starknet-react/chains'
import { ChainProviderFactory } from '@starknet-react/core'
import { RpcProvider } from 'starknet'

export const SUPPORTED_STARKNET_NETWORKS = [mainnet, goerli]
export const SUPPORTED_STARKNET_NETWORKS = [mainnet, sepolia]

const NETHERMIND_KEY = process.env.REACT_APP_NETHERMIND_KEY as string
if (typeof NETHERMIND_KEY === 'undefined') {
Expand All @@ -18,9 +18,9 @@ if (typeof DEFAULT_NETWORK_NAME === 'undefined') {

export const nethermindRpcProviders: ChainProviderFactory = (chain: Chain) => {
switch (chain.id) {
case goerli.id:
case sepolia.id:
return new RpcProvider({
nodeUrl: `https://rpc.nethermind.io/goerli-juno/?apikey=${NETHERMIND_KEY}`,
nodeUrl: `https://rpc.nethermind.io/sepolia-juno/?apikey=${NETHERMIND_KEY}`,
})

case mainnet.id:
Expand Down
16 changes: 9 additions & 7 deletions packages/frontend/src/hooks/useBalances.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useAccount, useContractRead, UseContractReadResult } from '@starknet-react/core'
import { useAccount, useReadContract, UseReadContractResult } from '@starknet-react/core'
import { Fraction } from '@uniswap/sdk-core'
import { Token } from 'core'
import { compiledMulticall, Entrypoint, MULTICALL_ADDRESSES } from 'core/constants'
Expand All @@ -11,7 +11,7 @@ import useChainId from './useChainId'
type Balance = Fraction
type Balances = Record<string, Balance>

interface UseBalancesResult extends Pick<UseContractReadResult, 'error' | 'refetch'> {
interface UseBalancesResult extends Pick<UseReadContractResult<any, any>, 'error' | 'refetch'> {
data?: Balances
loading: boolean
}
Expand All @@ -23,7 +23,7 @@ export default function useBalances(tokens: UseBalancesToken[]): UseBalancesResu
const { address: accountAddress } = useAccount()
const chainId = useChainId()

const res = useContractRead({
const res = useReadContract({
abi: compiledMulticall, // call is not send if abi is undefined
address: accountAddress && chainId ? MULTICALL_ADDRESSES[chainId] : undefined,
functionName: 'aggregate',
Expand All @@ -37,12 +37,14 @@ export default function useBalances(tokens: UseBalancesToken[]): UseBalancesResu
}),
),
],
}) as UseContractReadResult & { data?: [bigint, [bigint, bigint][]] }
})

const resData: [bigint, [bigint, bigint][]] | undefined = res.data

const data = useMemo(() => {
if (!res.data) return undefined
if (!resData) return undefined

return res.data[1].reduce<Record<string, Fraction>>((acc, balance, index) => {
return resData[1].reduce<Record<string, Fraction>>((acc, balance, index) => {
const token = tokens[index]
acc[token.address] = new Fraction(
uint256.uint256ToBN({ low: balance[0], high: balance[1] }).toString(),
Expand All @@ -52,7 +54,7 @@ export default function useBalances(tokens: UseBalancesToken[]): UseBalancesResu
return acc
}, {})
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [res.data?.[0].toString()])
}, [resData?.[0].toString()])

return { data, loading: res.fetchStatus === 'fetching', error: res.error, refetch: res.refetch }
}
Expand Down
3 changes: 2 additions & 1 deletion packages/frontend/src/hooks/useChainId.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { starknetChainId, useNetwork } from '@starknet-react/core'
import { useMemo } from 'react'
import { constants } from 'starknet'

export default function useChainId() {
export default function useChainId(): constants.StarknetChainId | undefined {
const { chain } = useNetwork()
return useMemo(() => (chain.id ? starknetChainId(chain.id) : undefined), [chain.id])
}
Loading

0 comments on commit 7e83489

Please sign in to comment.