Skip to content

Commit 14a7dad

Browse files
committed
Merge branch 'master' into change-domain-and-navbars
2 parents 2dab624 + 1ed4946 commit 14a7dad

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+357
-3293
lines changed

.github/workflows/test-protocol.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,7 @@ jobs:
8686
if: steps.cache-anchor.outputs.cache-hit != 'true'
8787
run: |
8888
export PATH="/home/runner/.local/share/solana/install/active_release/bin:$PATH"
89-
cargo install --git https://github.com/coral-xyz/anchor avm --locked --force
90-
avm install ${{ env.anchor_version }}
89+
cargo install --git https://github.com/project-serum/anchor --tag v${{ env.anchor_version }} anchor-cli --locked
9190
- name: build programs
9291
working-directory: ${{ env.protocol_path }}
9392
run: |

frontend/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"dependencies": {
1515
"@emotion/react": "^11.13.0",
1616
"@emotion/styled": "^11.13.0",
17-
"@invariant-labs/eclipse-link-sdk": "^0.1.1",
17+
"@invariant-labs/eclipse-link-sdk": "^0.1.3",
1818
"@invariant-labs/sdk-eclipse": "^0.0.17",
1919
"@mui/icons-material": "^5.16.7",
2020
"@mui/material": "^5.16.7",

frontend/src/components/Liquidity/Liquidity.tsx

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ import classNames from 'classnames'
2424
import FeeSwitch from './FeeSwitch/FeeSwitch'
2525
import Select from '@components/Inputs/Select/Select'
2626
import SwapList from '@static/svg/swap-list.svg'
27+
import { getMaxLiquidity, liquidityToLpTokenAmount } from '@invariant-labs/eclipse-link-sdk'
28+
import { getMaxTick, getMinTick } from '@invariant-labs/sdk-eclipse/lib/utils'
29+
import { Decimal } from '@invariant-labs/sdk-eclipse/lib/market'
2730

2831
export interface ILiquidity {
2932
initialTokenFrom: string
@@ -67,6 +70,7 @@ export interface ILiquidity {
6770
tokenBPriceData?: TokenPriceData
6871
priceALoading?: boolean
6972
priceBLoading?: boolean
73+
sqrtPrice: Decimal
7074
}
7175

7276
export const Liquidity: React.FC<ILiquidity> = ({
@@ -84,9 +88,9 @@ export const Liquidity: React.FC<ILiquidity> = ({
8488
noConnectedBlockerProps,
8589
progress,
8690
// isXtoY,
87-
// xDecimal,
88-
// yDecimal,
89-
// tickSpacing,
91+
xDecimal,
92+
yDecimal,
93+
tickSpacing,
9094
// isWaitingForNewPool,
9195
poolIndex,
9296
bestTiers,
@@ -102,7 +106,8 @@ export const Liquidity: React.FC<ILiquidity> = ({
102106
tokenAPriceData,
103107
tokenBPriceData,
104108
priceALoading,
105-
priceBLoading
109+
priceBLoading,
110+
sqrtPrice
106111
}) => {
107112
const { classes } = useStyles()
108113
const navigate = useNavigate()
@@ -246,6 +251,68 @@ export const Liquidity: React.FC<ILiquidity> = ({
246251
}
247252
}, [poolIndex])
248253

254+
const LPTokenReceive = useMemo(() => {
255+
if (
256+
tokenAIndex !== null &&
257+
tokenBIndex !== null &&
258+
tokenADeposit !== null &&
259+
tokenBDeposit !== null
260+
) {
261+
console.log('sqrt price', sqrtPrice.v.toString(), tickSpacing, getMaxTick(tickSpacing))
262+
263+
const maxLiquidity = getMaxLiquidity(
264+
{ v: printBNtoBN(tokenADeposit, xDecimal) },
265+
{ v: printBNtoBN(tokenBDeposit, yDecimal) },
266+
getMinTick(tickSpacing),
267+
getMaxTick(tickSpacing),
268+
sqrtPrice,
269+
true
270+
)
271+
272+
const lpTokenAmount = liquidityToLpTokenAmount(
273+
{ v: new BN(0) },
274+
{ v: new BN(0) },
275+
maxLiquidity.liquidity,
276+
false
277+
)
278+
279+
return printBN(lpTokenAmount.v.toString(), 6)
280+
}
281+
282+
return '0'
283+
}, [tokenADeposit, tokenBDeposit, poolIndex])
284+
285+
const LPTokenReceive = useMemo(() => {
286+
if (
287+
tokenAIndex !== null &&
288+
tokenBIndex !== null &&
289+
tokenADeposit !== null &&
290+
tokenBDeposit !== null
291+
) {
292+
console.log('sqrt price', sqrtPrice.v.toString(), tickSpacing, getMaxTick(tickSpacing))
293+
294+
const maxLiquidity = getMaxLiquidity(
295+
{ v: printBNtoBN(tokenADeposit, xDecimal) },
296+
{ v: printBNtoBN(tokenBDeposit, yDecimal) },
297+
getMinTick(tickSpacing),
298+
getMaxTick(tickSpacing),
299+
sqrtPrice,
300+
true
301+
)
302+
303+
const lpTokenAmount = liquidityToLpTokenAmount(
304+
{ v: new BN(0) },
305+
{ v: new BN(0) },
306+
maxLiquidity.liquidity,
307+
false
308+
)
309+
310+
return printBN(lpTokenAmount.v.toString(), 6)
311+
}
312+
313+
return '0'
314+
}, [tokenADeposit, tokenBDeposit, poolIndex])
315+
249316
useEffect(() => {
250317
// Temporary set best tier index as only available
251318
if (bestTierIndex) {
@@ -412,7 +479,7 @@ export const Liquidity: React.FC<ILiquidity> = ({
412479
feeTierIndex={currentFeeIndex}
413480
progress={progress}
414481
LPTokenName={lpTokenName ?? ''}
415-
LPTokenReceive={''}
482+
LPTokenReceive={LPTokenReceive}
416483
priceA={tokenAPriceData?.price}
417484
priceB={tokenBPriceData?.price}
418485
priceALoading={priceALoading}

frontend/src/containers/LiquidityWrapper/LiquidityWrapper.tsx

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
getLiquidityByYInFullRange
1717
} from '@invariant-labs/eclipse-link-sdk'
1818
import { FEE_TIERS, feeToTickSpacing } from '@invariant-labs/sdk-eclipse/lib/utils'
19-
import { poolsArraySortedByFees } from '@store/selectors/pools'
19+
import { lpPoolsArraySortedByFees, poolsArraySortedByFees } from '@store/selectors/pools'
2020
import { Pair } from '@invariant-labs/sdk-eclipse'
2121

2222
export interface IProps {
@@ -42,6 +42,7 @@ export const LiquidityWrapper: React.FC<IProps> = ({
4242

4343
const canUserCreateNewPool = useSelector(canCreateNewPool(currentNetwork))
4444
const [poolIndex, setPoolIndex] = useState<number | null>(null)
45+
const [lpPoolIndex, setLpPoolIndex] = useState<number | null>(null)
4546

4647
// const [progress, setProgress] = useState<ProgressState>('none')
4748
const [feeIndex, setFeeIndex] = useState(0)
@@ -153,6 +154,7 @@ export const LiquidityWrapper: React.FC<IProps> = ({
153154
localStorage.getItem('HIDE_UNKNOWN_TOKENS') === null
154155

155156
const allPools = useSelector(poolsArraySortedByFees)
157+
const allLpPools = useSelector(lpPoolsArraySortedByFees)
156158
const liquidityRef = useRef<any>({ v: new BN(0) })
157159
const isMountedRef = useRef(false)
158160

@@ -176,11 +178,13 @@ export const LiquidityWrapper: React.FC<IProps> = ({
176178

177179
useEffect(() => {
178180
if (tokenAIndex !== null && tokenBIndex !== null && tokenAIndex !== tokenBIndex) {
179-
dispatch(
180-
poolsActions.getPoolData(
181-
new Pair(tokens[tokenAIndex].address, tokens[tokenBIndex].address, FEE_TIERS[feeIndex])
182-
)
181+
const pair = new Pair(
182+
tokens[tokenAIndex].address,
183+
tokens[tokenBIndex].address,
184+
FEE_TIERS[feeIndex]
183185
)
186+
dispatch(poolsActions.getPoolData(pair))
187+
dispatch(poolsActions.getLpPoolData(pair))
184188
}
185189
}, [tokenAIndex, tokenBIndex, feeIndex])
186190

@@ -199,6 +203,23 @@ export const LiquidityWrapper: React.FC<IProps> = ({
199203
}
200204
}, [allPools])
201205

206+
useEffect(() => {
207+
if (tokenAIndex !== null && tokenBIndex !== null) {
208+
const index = allLpPools.findIndex(
209+
pool =>
210+
pool.fee.v.eq(fee) &&
211+
((pool.tokenX.equals(tokens[tokenAIndex].assetAddress) &&
212+
pool.tokenY.equals(tokens[tokenBIndex].assetAddress)) ||
213+
(pool.tokenX.equals(tokens[tokenBIndex].assetAddress) &&
214+
pool.tokenY.equals(tokens[tokenAIndex].assetAddress)))
215+
)
216+
217+
setLpPoolIndex(index !== -1 ? index : null)
218+
}
219+
}, [allLpPools])
220+
221+
console.log(lpPoolIndex)
222+
202223
useEffect(() => {
203224
isMountedRef.current = true
204225
return () => {
@@ -216,9 +237,7 @@ export const LiquidityWrapper: React.FC<IProps> = ({
216237
midPrice={10}
217238
setMidPrice={() => {}}
218239
addLiquidityHandler={() => {}}
219-
removeLiquidityHandler={(xAmount, yAmount) => {
220-
console.log(xAmount, yAmount)
221-
}}
240+
removeLiquidityHandler={() => {}}
222241
onChangePositionTokens={(tokenA, tokenB, feeTierIndex) => {
223242
setTokenAIndex(tokenA)
224243
setTokenBIndex(tokenB)
@@ -236,9 +255,9 @@ export const LiquidityWrapper: React.FC<IProps> = ({
236255
}}
237256
progress={'none'}
238257
isXtoY={true}
239-
xDecimal={12}
240-
yDecimal={10}
241-
tickSpacing={1}
258+
xDecimal={tokenAIndex !== null ? tokens[tokenAIndex]?.decimals : 0}
259+
yDecimal={tokenBIndex !== null ? tokens[tokenBIndex]?.decimals : 0}
260+
tickSpacing={tickSpacing}
242261
isWaitingForNewPool={false}
243262
poolIndex={poolIndex}
244263
bestTiers={bestTiers[currentNetwork]}
@@ -255,6 +274,7 @@ export const LiquidityWrapper: React.FC<IProps> = ({
255274
tokenBPriceData={{ price: 1 }}
256275
priceALoading={false}
257276
priceBLoading={false}
277+
sqrtPrice={poolIndex !== null ? allPools[poolIndex].sqrtPrice : { v: new BN(0) }}
258278
/>
259279
)
260280
}

frontend/src/store/reducers/pools.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { LpPoolStructure } from '@invariant-labs/eclipse-link-sdk/dist/types'
12
import { Pair } from '@invariant-labs/sdk-eclipse'
23
import { PoolStructure } from '@invariant-labs/sdk-eclipse/lib/market'
34
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
@@ -10,9 +11,14 @@ export interface PoolWithAddress extends PoolStructure {
1011
address: PublicKey
1112
}
1213

14+
export interface LpPoolWithAddress extends LpPoolStructure {
15+
address: PublicKey
16+
}
17+
1318
export interface IPoolsStore {
1419
tokens: Record<string, Token>
1520
pools: { [key in string]: PoolWithAddress }
21+
lpPools: { [key in string]: LpPoolWithAddress }
1622
// poolTicks: { [key in string]: Tick[] }
1723
// nearestPoolTicksForPair: { [key in string]: Tick[] }
1824
isLoadingLatestPoolsForTransaction: boolean
@@ -56,6 +62,7 @@ export interface FetchTicksAndTickMaps {
5662
export const defaultState: IPoolsStore = {
5763
tokens: {},
5864
pools: {},
65+
lpPools: {},
5966
// poolTicks: {},
6067
// nearestPoolTicksForPair: {},
6168
isLoadingLatestPoolsForTransaction: false
@@ -115,6 +122,23 @@ const poolsSlice = createSlice({
115122
getAllPoolsForPairData(state, _action: PayloadAction<PairTokens>) {
116123
state.isLoadingLatestPoolsForTransaction = true
117124

125+
return state
126+
},
127+
getLpPoolData(state, _action: PayloadAction<Pair>) {
128+
state.isLoadingLatestPoolsForTransaction = true
129+
130+
return state
131+
},
132+
addLpPools(state, action: PayloadAction<LpPoolWithAddress[]>) {
133+
const newData = action.payload.reduce(
134+
(acc, pool) => ({
135+
...acc,
136+
[pool.address.toString()]: pool
137+
}),
138+
{}
139+
)
140+
state.lpPools = R.merge(state.lpPools, newData)
141+
state.isLoadingLatestPoolsForTransaction = false
118142
return state
119143
}
120144
}

frontend/src/store/reducers/swap.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { PayloadType } from './types'
55

66
//TODO replace mock fromFee
77
export const fromFee = (fee: BN) => {
8-
console.log(fee)
8+
return fee
99
}
1010

1111
//TODO replace mock Decimal

frontend/src/store/sagas/pools.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { getMarketProgram } from '@web3/programs/amm'
66
import { getPools } from '@store/consts/utils'
77
import { Pair } from '@invariant-labs/sdk-eclipse'
88
import { FEE_TIERS } from '@invariant-labs/sdk-eclipse/lib/utils'
9+
import { getProtocolProgram } from '@web3/programs/protocol'
910

1011
export interface iTick {
1112
index: iTick[]
@@ -45,6 +46,30 @@ export function* fetchAllPoolsForPairData(action: PayloadAction<PairTokens>) {
4546
yield* put(actions.addPools(pools))
4647
}
4748

49+
export function* fetchLpPoolData(action: PayloadAction<Pair>) {
50+
const networkType = yield* select(network)
51+
const rpc = yield* select(rpcAddress)
52+
const protocolProgram = yield* call(getProtocolProgram, networkType, rpc)
53+
try {
54+
const poolData = yield* call([protocolProgram, protocolProgram.getLpPool], action.payload)
55+
const address = yield* call(
56+
[action.payload, action.payload.getAddress],
57+
protocolProgram.program.programId
58+
)
59+
60+
yield* put(
61+
actions.addLpPools([
62+
{
63+
...poolData,
64+
address
65+
}
66+
])
67+
)
68+
} catch (error) {
69+
yield* put(actions.addLpPools([]))
70+
}
71+
}
72+
4873
export function* getPoolDataHandler(): Generator {
4974
yield* takeLatest(actions.getPoolData, fetchPoolData)
5075
}
@@ -53,6 +78,10 @@ export function* getAllPoolsForPairDataHandler(): Generator {
5378
yield* takeLatest(actions.getAllPoolsForPairData, fetchAllPoolsForPairData)
5479
}
5580

81+
export function* getLpPoolDataHandler(): Generator {
82+
yield* takeLatest(actions.getLpPoolData, fetchLpPoolData)
83+
}
84+
5685
export function* poolsSaga(): Generator {
57-
yield all([getPoolDataHandler, getAllPoolsForPairDataHandler].map(spawn))
86+
yield all([getPoolDataHandler, getAllPoolsForPairDataHandler, getLpPoolDataHandler].map(spawn))
5887
}

frontend/src/store/selectors/pools.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,21 @@ import { keySelectors, AnyProps } from './helpers'
44

55
const store = (s: AnyProps) => s[poolsSliceName] as IPoolsStore
66

7-
export const { tokens, pools, isLoadingLatestPoolsForTransaction } = keySelectors(store, [
7+
export const { tokens, pools, lpPools, isLoadingLatestPoolsForTransaction } = keySelectors(store, [
88
'tokens',
99
'pools',
10+
'lpPools',
1011
'isLoadingLatestPoolsForTransaction'
1112
])
1213

1314
export const poolsArraySortedByFees = createSelector(pools, allPools =>
1415
Object.values(allPools).sort((a, b) => a.fee.v.sub(b.fee.v).toNumber())
1516
)
1617

18+
export const lpPoolsArraySortedByFees = createSelector(lpPools, allLpPools =>
19+
Object.values(allLpPools).sort((a, b) => a.fee.v.sub(b.fee.v).toNumber())
20+
)
21+
1722
export const hasTokens = createSelector(tokens, allTokens => !!Object.values(allTokens).length)
1823

1924
export const poolsSelectors = {

0 commit comments

Comments
 (0)