Skip to content

Commit 753630a

Browse files
authored
Merge pull request #1685 from mars-protocol/develop
v3.0.3
2 parents 2a54c31 + e5334cf commit 753630a

File tree

25 files changed

+196
-78
lines changed

25 files changed

+196
-78
lines changed

eslint.config.mjs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ export default tseslint.config(
5151
'linebreak-style': 'off',
5252
'no-undef': 'off',
5353
'prettier/prettier': 0,
54+
// Disable new stricter react-hooks rules from Next.js 15.5.4
55+
'react-hooks/set-state-in-effect': 'off',
56+
'react-hooks/immutability': 'off',
57+
'react-hooks/set-state-in-render': 'off',
58+
'react-hooks/static-components': 'off',
59+
'react-hooks/purity': 'off',
60+
'react-hooks/preserve-manual-memoization': 'off',
61+
'react-hooks/refs': 'off',
62+
'react-hooks/incompatible-library': 'warn',
5463
'sort-imports': [
5564
'warn',
5665
{

install_charting_library.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,20 @@ cp -r "$LATEST_HASH/charting_library" src/utils/
2424
cp -r "$LATEST_HASH/datafeeds" public/
2525
cp -r "$LATEST_HASH/datafeeds" src/utils/
2626

27+
# Create index.js to export widget for Next.js compatibility
28+
cat > "src/utils/charting_library/index.js" << 'JSEOF'
29+
// The charting library is loaded via a UMD bundle that attaches to window.TradingView
30+
// We provide a stub that resolves to the actual widget at runtime
31+
export const widget = (typeof window !== 'undefined' && typeof window.TradingView !== 'undefined')
32+
? window.TradingView.widget
33+
: class MockWidget {}
34+
JSEOF
35+
36+
# Create index.d.ts to re-export types
37+
cat > "src/utils/charting_library/index.d.ts" << 'DTSEOF'
38+
// Re-export all types from the charting library
39+
export * from './charting_library.d'
40+
export * from './datafeed-api.d'
41+
DTSEOF
42+
2743
remove_if_directory_exists "$LATEST_HASH"

next.config.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
const nextConfig = {
44
reactStrictMode: true,
5+
transpilePackages: ['bignumber.js'],
56
images: {
67
remotePatterns: [
78
{
@@ -98,13 +99,35 @@ const nextConfig = {
9899
},
99100
]
100101
},
101-
webpack(config) {
102+
webpack(config, { isServer }) {
102103
config.module.rules.push({
103104
test: /\.svg$/i,
104105
issuer: /\.[jt]sx?$/,
105106
use: ['@svgr/webpack'],
106107
})
107108

109+
// Handle charting library - it's a UMD bundle that needs special treatment
110+
// Use path.resolve instead of require.resolve to avoid issues when file doesn't exist yet
111+
const path = require('path')
112+
const fs = require('fs')
113+
const chartingLibraryPath = path.resolve(__dirname, 'src/utils/charting_library/index.js')
114+
115+
// Only add alias if the file exists (it's created by install-charting-library script)
116+
if (fs.existsSync(chartingLibraryPath)) {
117+
config.resolve.alias = {
118+
...config.resolve.alias,
119+
'utils/charting_library': chartingLibraryPath,
120+
}
121+
}
122+
123+
// Fix for packages with only "exports" field (like @cosmjs)
124+
// This ensures webpack can resolve them properly
125+
config.resolve.extensionAlias = {
126+
'.js': ['.js', '.ts', '.tsx'],
127+
'.mjs': ['.mjs', '.mts'],
128+
...config.resolve.extensionAlias,
129+
}
130+
108131
return config
109132
},
110133
}

package.json

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mars-v2-frontend",
3-
"version": "3.0.2",
3+
"version": "3.0.3",
44
"homepage": "./",
55
"private": false,
66
"license": "SEE LICENSE IN LICENSE FILE",
@@ -20,90 +20,90 @@
2020
]
2121
},
2222
"dependencies": {
23-
"@cosmjs/cosmwasm-stargate": "^0.36.0",
23+
"@cosmjs/cosmwasm-stargate": "^0.37.0",
2424
"@delphi-labs/shuttle-react": "^4.3.0",
25-
"@keplr-wallet/cosmos": "^0.12.275",
26-
"@next/eslint-plugin-next": "^15.5.4",
27-
"@skip-go/client": "^1.5.8",
25+
"@keplr-wallet/cosmos": "^0.12.285",
26+
"@next/eslint-plugin-next": "^16.0.1",
27+
"@react-native-async-storage/async-storage": "^2.2.0",
28+
"@skip-go/client": "^1.5.9",
2829
"@solana/web3.js": "^1.98.4",
29-
"@tanstack/react-query": "^5.90.2",
30+
"@tanstack/react-query": "^5.90.5",
3031
"@tanstack/react-table": "^8.21.3",
3132
"@tippyjs/react": "^4.2.6",
3233
"@vercel/analytics": "^1.5.0",
3334
"@vercel/og": "^0.8.5",
3435
"@web3modal/wagmi": "^5.1.11",
35-
"axios": "^1.12.2",
36+
"axios": "^1.13.1",
3637
"bignumber.js": "^9.3.1",
37-
"bitcoinjs-lib": "^6.1.7",
38+
"bitcoinjs-lib": "^7.0.0",
3839
"classnames": "^2.5.1",
3940
"debounce-promise": "^3.1.2",
40-
"graphql-request": "^7.2.0",
41+
"graphql-request": "^7.3.1",
4142
"ibc-domains-sdk": "^1.1.0",
4243
"isbot": "^5.1.31",
4344
"lodash": "^4.17.21",
4445
"lodash.debounce": "^4.0.8",
4546
"lodash.throttle": "^4.1.1",
46-
"mobx": "^6.13.7",
47+
"mobx": "^6.15.0",
4748
"moment": "^2.30.1",
48-
"next": "^15.5.4",
49+
"next": "15.5.4",
4950
"react": "19.2.0",
5051
"react-device-detect": "^2.2.3",
5152
"react-dom": "^19.2.0",
5253
"react-draggable": "^4.5.0",
5354
"react-helmet-async": "^2.0.5",
54-
"@react-native-async-storage/async-storage": "^2.0.0",
5555
"react-qr-code": "^2.0.18",
56-
"react-router-dom": "^7.9.2",
56+
"react-router-dom": "^7.9.5",
5757
"react-spring": "^10.0.3",
5858
"react-toastify": "^11.0.5",
5959
"react-use-clipboard": "^1.0.9",
60-
"recharts": "^3.2.1",
60+
"recharts": "^3.3.0",
6161
"sharp": "^0.34.4",
6262
"starknet": "^7.6.4",
6363
"swr": "^2.3.6",
64-
"viem": "^2.37.8",
65-
"wagmi": "^2.17.4",
64+
"viem": "^2.38.5",
65+
"wagmi": "^2.19.1",
6666
"zustand": "5.0.8"
6767
},
6868
"devDependencies": {
69-
"@babel/eslint-parser": "^7.28.4",
70-
"buffer": "^6.0.3",
71-
"crypto-browserify": "^3.12.0",
72-
"react-native-web": "^0.19.13",
73-
"stream-browserify": "^3.0.0",
74-
"@eslint/compat": "^1.4.0",
69+
"@babel/eslint-parser": "^7.28.5",
70+
"@eslint/compat": "^1.4.1",
7571
"@svgr/webpack": "^8.1.0",
7672
"@tailwindcss/container-queries": "^0.1.1",
77-
"@tailwindcss/postcss": "^4.1.13",
73+
"@tailwindcss/postcss": "^4.1.16",
7874
"@types/debounce-promise": "^3.1.9",
7975
"@types/lodash.debounce": "^4.0.9",
8076
"@types/lodash.throttle": "^4.1.9",
81-
"@types/node": "^24.5.2",
77+
"@types/node": "^24.9.2",
8278
"@types/react": "19.2.2",
8379
"@types/react-dom": "19.2.2",
8480
"@types/react-helmet": "^6.1.11",
85-
"@typescript-eslint/eslint-plugin": "^8.44.1",
86-
"@typescript-eslint/parser": "^8.44.1",
81+
"@typescript-eslint/eslint-plugin": "^8.46.2",
82+
"@typescript-eslint/parser": "^8.46.2",
8783
"autoprefixer": "^10.4.21",
88-
"dotenv": "^17.2.2",
89-
"dotenv-cli": "^10.0.0",
90-
"eslint": "^9.36.0",
84+
"buffer": "^6.0.3",
85+
"crypto-browserify": "^3.12.1",
86+
"dotenv": "^17.2.3",
87+
"dotenv-cli": "^11.0.0",
88+
"eslint": "^9.38.0",
9189
"eslint-config-prettier": "^10.1.8",
9290
"eslint-plugin-functional": "^9.0.2",
9391
"eslint-plugin-import": "^2.32.0",
9492
"eslint-plugin-prettier": "^5.5.4",
9593
"eslint-plugin-react": "^7.37.5",
96-
"eslint-plugin-react-hooks": "^5.2.0",
94+
"eslint-plugin-react-hooks": "^7.0.1",
9795
"husky": "^9.1.7",
9896
"identity-obj-proxy": "^3.0.0",
99-
"lint-staged": "^16.2.0",
97+
"lint-staged": "^16.2.6",
10098
"prettier": "^3.6.2",
101-
"prettier-plugin-tailwindcss": "^0.6.14",
99+
"prettier-plugin-tailwindcss": "^0.7.1",
100+
"react-native-web": "^0.21.2",
102101
"shelljs": "^0.10.0",
102+
"stream-browserify": "^3.0.0",
103103
"tailwind-scrollbar-hide": "^4.0.0",
104104
"tailwindcss": "3.4.1",
105-
"typescript": "^5.9.2",
106-
"typescript-eslint": "^8.44.1"
105+
"typescript": "^5.9.3",
106+
"typescript-eslint": "^8.46.2"
107107
},
108108
"overrides": {
109109
"chalk": "5.3.0",

src/api/campaign/getCampaignApys.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ import { fetchWithTimeout } from 'utils/fetch'
33
import { convertAprToApy } from 'utils/parsers'
44

55
function processApyData(aprOrApy: number, isApr: boolean, isPercent: boolean): number {
6-
if (!isApr && isPercent) return aprOrApy
7-
const percentApr = isPercent ? aprOrApy : aprOrApy * 100
6+
// Ensure the value is a number (API might return strings)
7+
const numericValue = typeof aprOrApy === 'string' ? parseFloat(aprOrApy) : aprOrApy
8+
if (!isApr && isPercent) return numericValue
9+
const percentApr = isPercent ? numericValue : numericValue * 100
810
const apy = isApr ? convertAprToApy(percentApr, 365) : percentApr
911
return apy
1012
}

src/chains/neutron/neutron-1.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ const Neutron1: ChainConfig = {
118118
campaignIds: ['lido'],
119119
campaignDenom: 'stETH',
120120
},
121+
{
122+
denom: 'ibc/0E293A7622DC9A6439DB60E6D234B5AF446962E27CA3AB44D0590603DFF6968E',
123+
campaignIds: ['ntrn-rewards'],
124+
campaignDenom: 'wbtc',
125+
},
121126
],
122127
deprecated: [
123128
'ibc/3649CE0C8A2C79048D8C6F31FF18FA69C9BC7EB193512E0BD03B733011290445',

src/components/Modals/Farm/FarmBorrowings.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,9 @@ export default function FarmBorrowings(props: FarmBorrowingsProps) {
130130

131131
function updateAssets(denom: string, amount: BigNumber) {
132132
const index = props.borrowings.findIndex((coin) => coin.denom === denom)
133-
props.borrowings[index].amount = amount
134-
props.onChangeBorrowings([...props.borrowings])
133+
const newBorrowings = [...props.borrowings]
134+
newBorrowings[index].amount = amount
135+
props.onChangeBorrowings(newBorrowings)
135136
}
136137

137138
function onDelete(denom: string) {

src/components/Modals/Farm/FarmDeposits.tsx

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,9 @@ export default function FarmDeposits(props: Props) {
163163
function handleSwitch() {
164164
const isCustomRatioNew = !props.isCustomRatio
165165
if (!isCustomRatioNew) {
166-
primaryCoin.amount = BN_ZERO
167-
secondaryCoin.amount = BN_ZERO
168-
onChangeDeposits([primaryCoin, secondaryCoin])
166+
const newPrimaryCoin = new BNCoin({ denom: primaryCoin.denom, amount: '0' })
167+
const newSecondaryCoin = new BNCoin({ denom: secondaryCoin.denom, amount: '0' })
168+
onChangeDeposits([newPrimaryCoin, newSecondaryCoin])
169169
setPercentage(0)
170170
}
171171
props.onChangeIsCustomRatio(isCustomRatioNew)
@@ -176,15 +176,17 @@ export default function FarmDeposits(props: Props) {
176176
if (amount.isGreaterThan(primaryMax)) {
177177
amount = primaryMax
178178
}
179-
primaryCoin.amount = amount
179+
const newPrimaryCoin = new BNCoin({ denom: primaryCoin.denom, amount: amount.toString() })
180180
setPercentage(amount.dividedBy(primaryMax).multipliedBy(100).decimalPlaces(0).toNumber())
181-
if (!props.isCustomRatio) {
182-
secondaryCoin.amount = secondaryMax
183-
.multipliedBy(amount.dividedBy(primaryMax))
184-
.integerValue()
185-
}
181+
const newSecondaryAmount = !props.isCustomRatio
182+
? secondaryMax.multipliedBy(amount.dividedBy(primaryMax)).integerValue()
183+
: secondaryCoin.amount
184+
const newSecondaryCoin = new BNCoin({
185+
denom: secondaryCoin.denom,
186+
amount: newSecondaryAmount.toString(),
187+
})
186188

187-
onChangeDeposits([primaryCoin, secondaryCoin])
189+
onChangeDeposits([newPrimaryCoin, newSecondaryCoin])
188190
},
189191
[primaryMax, secondaryMax, props.isCustomRatio, primaryCoin, secondaryCoin, onChangeDeposits],
190192
)
@@ -194,23 +196,36 @@ export default function FarmDeposits(props: Props) {
194196
if (amount.isGreaterThan(secondaryMax)) {
195197
amount = secondaryMax
196198
}
197-
secondaryCoin.amount = amount
199+
const newSecondaryCoin = new BNCoin({
200+
denom: secondaryCoin.denom,
201+
amount: amount.toString(),
202+
})
198203
setPercentage(amount.dividedBy(secondaryMax).multipliedBy(100).decimalPlaces(0).toNumber())
199-
if (!props.isCustomRatio) {
200-
primaryCoin.amount = primaryMax.multipliedBy(amount.dividedBy(secondaryMax)).integerValue()
201-
}
204+
const newPrimaryAmount = !props.isCustomRatio
205+
? primaryMax.multipliedBy(amount.dividedBy(secondaryMax)).integerValue()
206+
: primaryCoin.amount
207+
const newPrimaryCoin = new BNCoin({
208+
denom: primaryCoin.denom,
209+
amount: newPrimaryAmount.toString(),
210+
})
202211

203-
onChangeDeposits([primaryCoin, secondaryCoin])
212+
onChangeDeposits([newPrimaryCoin, newSecondaryCoin])
204213
},
205214
[primaryMax, secondaryMax, props.isCustomRatio, primaryCoin, secondaryCoin, onChangeDeposits],
206215
)
207216

208217
const onChangeSlider = useCallback(
209218
(value: number) => {
210219
if (percentage !== value) setPercentage(value)
211-
primaryCoin.amount = primaryMax.multipliedBy(value / 100).integerValue()
212-
secondaryCoin.amount = secondaryMax.multipliedBy(value / 100).integerValue()
213-
onChangeDeposits([primaryCoin, secondaryCoin])
220+
const newPrimaryCoin = new BNCoin({
221+
denom: primaryCoin.denom,
222+
amount: primaryMax.multipliedBy(value / 100).integerValue().toString(),
223+
})
224+
const newSecondaryCoin = new BNCoin({
225+
denom: secondaryCoin.denom,
226+
amount: secondaryMax.multipliedBy(value / 100).integerValue().toString(),
227+
})
228+
onChangeDeposits([newPrimaryCoin, newSecondaryCoin])
214229
},
215230
[percentage, primaryCoin, primaryMax, secondaryCoin, secondaryMax, onChangeDeposits],
216231
)

src/components/account/AccountBalancesTable/Columns/Apy.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export default function Apy(props: Props) {
2828
return (
2929
<div className='flex justify-end my-auto text-xs'>
3030
{hasLstApy ? (
31-
<Tooltip content='Includes underlying staking APY from Liquid Staking Token' type='info'>
31+
<Tooltip content='Includes underlying staking or rewards APY' type='info'>
3232
<div className='border-b border-dashed hover:cursor-help border-white/40 hover:border-transparent'>
3333
<FormattedNumber
3434
amount={totalApy}

src/components/common/Footer.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ export default function Footer() {
2222

2323
const version = `v${packageInfo.version}`
2424
return (
25-
<footer className='flex items-center justify-center w-full h-6 -mt-6'>
26-
<div className='w-full p-2 pt-0 text-right md:p-0 md:px-4'>
25+
<footer className='flex items-center justify-center w-full h-6 -mt-6 md:fixed md:bottom-0 md:right-0 md:justify-end md:w-auto'>
26+
<div className='w-full p-2 pt-0 text-right md:p-0 md:px-4 md:w-auto'>
2727
<TextLink
2828
className='text-xs text-white opacity-50 hover:text-white hover:opacity-80'
2929
href={`${DocURL.FEATURE_URL}${version}`}

0 commit comments

Comments
 (0)