Skip to content

Commit

Permalink
Merge pull request #870 from invariant-labs/concentration-in-url
Browse files Browse the repository at this point in the history
Concentration in url
  • Loading branch information
wojciech-cichocki authored Jan 31, 2025
2 parents 333a5be + 32cd079 commit 7138372
Show file tree
Hide file tree
Showing 8 changed files with 279 additions and 95 deletions.
4 changes: 3 additions & 1 deletion src/components/NewPosition/NewPosition.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ export const Primary: Story = {
noConnectedBlockerProps: {
onConnect: fn()
},
canNavigate: true
canNavigate: true,
initialConcentration: '30'
},
render: () => {
return (
Expand Down Expand Up @@ -183,6 +184,7 @@ export const Primary: Story = {
onConnect: fn()
}}
canNavigate={true}
initialConcentration='30'
/>
)
}
Expand Down
100 changes: 94 additions & 6 deletions src/components/NewPosition/NewPosition.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
calculateConcentrationRange,
convertBalanceToBN,
determinePositionTokenBlock,
getConcentrationIndex,
parseFeeToPathFee,
printBN,
trimLeadingZeros,
Expand Down Expand Up @@ -49,6 +50,7 @@ export interface INewPosition {
initialTokenFrom: string
initialTokenTo: string
initialFee: string
initialConcentration: string
poolAddress: string
calculatePoolAddress: () => Promise<string>
copyPoolAddressHandler: (message: string, variant: VariantType) => void
Expand Down Expand Up @@ -132,6 +134,7 @@ export const NewPosition: React.FC<INewPosition> = ({
initialTokenFrom,
initialTokenTo,
initialFee,
initialConcentration,
poolAddress,
calculatePoolAddress,
copyPoolAddressHandler,
Expand Down Expand Up @@ -208,8 +211,6 @@ export const NewPosition: React.FC<INewPosition> = ({
const [slippTolerance, setSlippTolerance] = React.useState<string>(initialSlippage)
const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null)

const [concentrationIndex, setConcentrationIndex] = useState(0)

const [minimumSliderIndex, setMinimumSliderIndex] = useState<number>(0)

const [shouldResetPlot, setShouldResetPlot] = useState(true)
Expand All @@ -224,6 +225,10 @@ export const NewPosition: React.FC<INewPosition> = ({
return getConcentrationArray(tickSpacing, 2, validatedMidPrice).sort((a, b) => a - b)
}, [tickSpacing, midPrice.index])

const [concentrationIndex, setConcentrationIndex] = useState(
getConcentrationIndex(concentrationArray, initialConcentration ? +initialConcentration : 34)
)

const setRangeBlockerInfo = () => {
if (tokenA === null || tokenB === null) {
return 'Select tokens to set price range.'
Expand Down Expand Up @@ -446,11 +451,34 @@ export const NewPosition: React.FC<INewPosition> = ({
onSlippageChange(slippage)
}

const updatePath = (address1: PublicKey | null, address2: PublicKey | null, fee: number) => {
const updatePath = (
address1: PublicKey | null,
address2: PublicKey | null,
fee: number,
concentration?: number,
isRange?: boolean
) => {
if (canNavigate) {
const parsedFee = parseFeeToPathFee(+ALL_FEE_TIERS_DATA[fee].tier.fee)

if (address1 != null && address2 != null) {
const mappedIndex = getConcentrationIndex(concentrationArray, concentration)

const validIndex = Math.max(
minimumSliderIndex,
Math.min(mappedIndex, concentrationArray.length - 1)
)

const concParam = concentration ? `?conc=${concentrationArray[validIndex].toFixed(0)}` : ''
const rangeParam =
isRange === undefined
? initialOpeningPositionMethod === 'range'
? '&range=true'
: '&range=false'
: isRange
? '&range=true'
: '&range=false'

const token1Symbol = addressToTicker(
network,
tokens[address1.toString()].assetAddress.toString()
Expand All @@ -459,7 +487,13 @@ export const NewPosition: React.FC<INewPosition> = ({
network,
tokens[address2.toString()].assetAddress.toString()
)
navigate(`/newPosition/${token1Symbol}/${token2Symbol}/${parsedFee}`, { replace: true })

navigate(
`/newPosition/${token1Symbol}/${token2Symbol}/${parsedFee}${concParam}${rangeParam}`,
{
replace: true
}
)
} else if (address1 != null) {
const tokenSymbol = addressToTicker(
network,
Expand Down Expand Up @@ -588,9 +622,25 @@ export const NewPosition: React.FC<INewPosition> = ({
if (val) {
setPositionOpeningMethod('concentration')
onPositionOpeningMethodChange('concentration')

updatePath(
tokenA,
tokenB,
currentFeeIndex,
+concentrationArray[concentrationIndex].toFixed(0),
false
)
} else {
setPositionOpeningMethod('range')
onPositionOpeningMethodChange('range')

updatePath(
tokenA,
tokenB,
currentFeeIndex,
+concentrationArray[concentrationIndex].toFixed(0),
true
)
}
}}
className={classes.switch}
Expand Down Expand Up @@ -635,7 +685,15 @@ export const NewPosition: React.FC<INewPosition> = ({
setTokenB(address2)
onChangePositionTokens(address1, address2, fee)

updatePath(address1, address2, fee)
if (!isLoadingTokens) {
updatePath(
address1,
address2,
fee,
+concentrationArray[concentrationIndex].toFixed(0)
),
positionOpeningMethod === 'range'
}
}}
onAddLiquidity={() => {
if (tokenA !== null && tokenB !== null) {
Expand Down Expand Up @@ -730,7 +788,13 @@ export const NewPosition: React.FC<INewPosition> = ({
onChangePositionTokens(tokenB, tokenA, currentFeeIndex)

if (!isLoadingTokens) {
updatePath(tokenB, tokenA, currentFeeIndex)
updatePath(
tokenB,
tokenA,
currentFeeIndex,
+concentrationArray[concentrationIndex].toFixed(0),
positionOpeningMethod === 'range'
)
}
}}
poolIndex={poolIndex}
Expand Down Expand Up @@ -768,9 +832,23 @@ export const NewPosition: React.FC<INewPosition> = ({
if (val) {
setPositionOpeningMethod('concentration')
onPositionOpeningMethodChange('concentration')
updatePath(
tokenA,
tokenB,
currentFeeIndex,
+concentrationArray[concentrationIndex].toFixed(0),
false
)
} else {
setPositionOpeningMethod('range')
onPositionOpeningMethodChange('range')
updatePath(
tokenA,
tokenB,
currentFeeIndex,
+concentrationArray[concentrationIndex].toFixed(0),
true
)
}
}}
className={classes.switch}
Expand All @@ -785,6 +863,16 @@ export const NewPosition: React.FC<INewPosition> = ({
tokenA.equals(tokenB) ||
isWaitingForNewPool ? (
<RangeSelector
updatePath={(concIndex: number) =>
updatePath(
tokenA,
tokenB,
currentFeeIndex,
+concentrationArray[concIndex].toFixed(0),
positionOpeningMethod === 'range'
)
}
initialConcentration={initialConcentration}
poolIndex={poolIndex}
onChangeRange={onChangeRange}
blocked={
Expand Down
3 changes: 1 addition & 2 deletions src/components/NewPosition/PoolInit/PoolInit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ export const PoolInit: React.FC<IPoolInit> = ({

useEffect(() => {
if (positionOpeningMethod === 'concentration') {
setConcentrationIndex(0)
const { leftRange, rightRange } = calculateConcentrationRange(
tickSpacing,
concentrationArray[0],
Expand All @@ -203,7 +202,7 @@ export const PoolInit: React.FC<IPoolInit> = ({
concentrationIndex > concentrationArray.length - 1
? concentrationArray.length - 1
: concentrationIndex
setConcentrationIndex(index)

const { leftRange, rightRange } = calculateConcentrationRange(
tickSpacing,
concentrationArray[index],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ export const Primary: Story = {
onlyUserPositions: false,
setOnlyUserPositions: fn(),
setShouldResetPlot: fn(),
shouldResetPlot: false
shouldResetPlot: false,
initialConcentration: '40',
updatePath: fn()
},
render: args => <PrimaryComponent {...args} />
}
Loading

0 comments on commit 7138372

Please sign in to comment.