From 84165cde8d015ee7415310775306c46a1f9a8dec Mon Sep 17 00:00:00 2001 From: matepal00 Date: Fri, 10 Jan 2025 14:09:07 +0100 Subject: [PATCH 01/13] referral modal --- .../Modals/RefferalModal/ReferralModal.tsx | 114 +++++++++++++ src/components/Modals/RefferalModal/style.ts | 159 ++++++++++++++++++ src/pages/LeaderboardPage/LeaderboardPage.tsx | 2 + .../components/LeaderboardWrapper.tsx | 2 + .../components/Referrals/Referrals.tsx | 35 ++++ .../components/Switcher/Switcher.tsx | 7 + .../components/Switcher/styles.ts | 6 +- 7 files changed, 323 insertions(+), 2 deletions(-) create mode 100644 src/components/Modals/RefferalModal/ReferralModal.tsx create mode 100644 src/components/Modals/RefferalModal/style.ts create mode 100644 src/pages/LeaderboardPage/components/Referrals/Referrals.tsx diff --git a/src/components/Modals/RefferalModal/ReferralModal.tsx b/src/components/Modals/RefferalModal/ReferralModal.tsx new file mode 100644 index 00000000..49e043b4 --- /dev/null +++ b/src/components/Modals/RefferalModal/ReferralModal.tsx @@ -0,0 +1,114 @@ +import useStyles from './style' +import { Box, Button, Divider, Grid, Hidden, Popover, Typography } from '@mui/material' +import AnimatedButton, { ProgressState } from '@components/AnimatedButton/AnimatedButton' +import classNames from 'classnames' +import { useEffect, useState } from 'react' + +export interface IRefferalModal { + open: boolean + onClose: () => void + onConfirm: () => void + success: boolean + inProgress: boolean + referrerAddress: string +} +export const ReferralModal = ({ + open, + onClose, + onConfirm, + success, + inProgress, + referrerAddress +}: IRefferalModal) => { + const { classes } = useStyles() + const [progress, setProgress] = useState('none') + + useEffect(() => { + let timeoutId1: NodeJS.Timeout + let timeoutId2: NodeJS.Timeout + + if (!inProgress && progress === 'progress') { + setProgress(success ? 'approvedWithSuccess' : 'approvedWithFail') + + timeoutId1 = setTimeout(() => { + setProgress(success ? 'success' : 'failed') + }, 1000) + + timeoutId2 = setTimeout(() => { + setProgress('none') + }, 3000) + } + + return () => { + clearTimeout(timeoutId1) + clearTimeout(timeoutId2) + } + }, [success, inProgress]) + + return ( + + + + + Confirm your invitation + + + ) +} + +export default Referrals diff --git a/src/pages/LeaderboardPage/components/Switcher/Switcher.tsx b/src/pages/LeaderboardPage/components/Switcher/Switcher.tsx index 300d13bf..bb416f43 100644 --- a/src/pages/LeaderboardPage/components/Switcher/Switcher.tsx +++ b/src/pages/LeaderboardPage/components/Switcher/Switcher.tsx @@ -46,6 +46,13 @@ export const Switcher: React.FC = ({ alignment, setAlignment }) style={{ fontWeight: alignment === 'claim' ? 700 : 400 }}> Claim + + Referrals + ) diff --git a/src/pages/LeaderboardPage/components/Switcher/styles.ts b/src/pages/LeaderboardPage/components/Switcher/styles.ts index 641f2b45..3ae79d86 100644 --- a/src/pages/LeaderboardPage/components/Switcher/styles.ts +++ b/src/pages/LeaderboardPage/components/Switcher/styles.ts @@ -15,6 +15,8 @@ const useStyles = makeStyles()((theme, { alignment }) => { return '100%' case 'claim': return '200%' + case 'referrals': + return '300%' default: return '0' } @@ -40,7 +42,7 @@ const useStyles = makeStyles()((theme, { alignment }) => { position: 'absolute', top: 0, bottom: 0, - width: 'calc(100% / 3)', + width: 'calc(100% / 4)', backgroundColor: colors.invariant.light, borderRadius: 10, transition: 'transform 0.3s ease', @@ -61,7 +63,7 @@ const useStyles = makeStyles()((theme, { alignment }) => { alignItems: 'center', color: 'white', flex: 1, - width: 'calc(100% / 3)', // Ustawienie dokładnej szerokości dla każdego przycisku + width: 'calc(100% / 4)', // Ustawienie dokładnej szerokości dla każdego przycisku minWidth: 'unset', // Usuwa domyślny minWidth z MUI textTransform: 'none', textWrap: 'nowrap', From 5b28ced7b6498adaf3c2dcf08f4de346adc52a3a Mon Sep 17 00:00:00 2001 From: matepal00 Date: Fri, 10 Jan 2025 17:38:10 +0100 Subject: [PATCH 02/13] display button regarding wallet connection --- .../Modals/RefferalModal/ReferralModal.tsx | 36 ++++++++++++------- .../components/Referrals/Referrals.tsx | 17 ++++++++- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/components/Modals/RefferalModal/ReferralModal.tsx b/src/components/Modals/RefferalModal/ReferralModal.tsx index 49e043b4..a0ed8cd2 100644 --- a/src/components/Modals/RefferalModal/ReferralModal.tsx +++ b/src/components/Modals/RefferalModal/ReferralModal.tsx @@ -11,6 +11,8 @@ export interface IRefferalModal { success: boolean inProgress: boolean referrerAddress: string + connected: boolean + handleConnectWallet: () => void } export const ReferralModal = ({ open, @@ -18,7 +20,9 @@ export const ReferralModal = ({ onConfirm, success, inProgress, - referrerAddress + referrerAddress, + connected, + handleConnectWallet }: IRefferalModal) => { const { classes } = useStyles() const [progress, setProgress] = useState('none') @@ -93,18 +97,24 @@ export const ReferralModal = ({ • Benefit - { - onConfirm() - setProgress('progress') - }} - progress={progress} - /> + {connected ? ( + { + onConfirm() + setProgress('progress') + }} + progress={progress} + /> + ) : ( + + )} diff --git a/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx b/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx index 72407b63..ed402f77 100644 --- a/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx +++ b/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx @@ -1,11 +1,24 @@ import ReferralModal from '@components/Modals/RefferalModal/ReferralModal' import { Box, Button } from '@mui/material' import { blurContent, unblurContent } from '@utils/uiUtils' -import { useState } from 'react' +import { useState, useMemo } from 'react' +import { Status, actions as walletActions } from '@store/reducers/solanaWallet' +import { useDispatch, useSelector } from 'react-redux' +import { status } from '@store/selectors/solanaWallet' const Referrals = () => { const [isModalOpen, setIsModalOpen] = useState(false) + const walletStatus = useSelector(status) + const dispatch = useDispatch() + + const handleConnectWallet = () => { + setIsModalOpen(false) + dispatch(walletActions.connect(false)) + } + const connected = useMemo(() => { + return walletStatus === Status.Initialized + }, [walletStatus]) const onReferralModalOpen = () => { setIsModalOpen(true) blurContent() @@ -24,6 +37,8 @@ const Referrals = () => { success={false} inProgress={false} referrerAddress={'asd'} + connected={connected} + handleConnectWallet={handleConnectWallet} /> + null} + className={classes.confirmButton} + /> )} diff --git a/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx b/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx index ed402f77..7ef0786c 100644 --- a/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx +++ b/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx @@ -13,20 +13,23 @@ const Referrals = () => { const dispatch = useDispatch() const handleConnectWallet = () => { - setIsModalOpen(false) dispatch(walletActions.connect(false)) } + const connected = useMemo(() => { return walletStatus === Status.Initialized }, [walletStatus]) + const onReferralModalOpen = () => { setIsModalOpen(true) blurContent() } + const onReferralModalClose = () => { setIsModalOpen(false) unblurContent() } + return ( From 95172af148e090027724f0c3b34af702c88ef066 Mon Sep 17 00:00:00 2001 From: matepal00 Date: Fri, 10 Jan 2025 20:21:14 +0100 Subject: [PATCH 04/13] sagas for referrals --- .../components/Referrals/Referrals.tsx | 22 ++++-- src/store/reducers/referral.ts | 72 +++++++++++++++++++ src/store/sagas/referral.ts | 68 ++++++++++++++++++ src/store/selectors/referral.ts | 19 +++++ 4 files changed, 176 insertions(+), 5 deletions(-) create mode 100644 src/store/reducers/referral.ts create mode 100644 src/store/sagas/referral.ts create mode 100644 src/store/selectors/referral.ts diff --git a/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx b/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx index 7ef0786c..188eed49 100644 --- a/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx +++ b/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx @@ -1,12 +1,16 @@ import ReferralModal from '@components/Modals/RefferalModal/ReferralModal' import { Box, Button } from '@mui/material' import { blurContent, unblurContent } from '@utils/uiUtils' -import { useState, useMemo } from 'react' +import { useState, useMemo, useEffect } from 'react' import { Status, actions as walletActions } from '@store/reducers/solanaWallet' import { useDispatch, useSelector } from 'react-redux' import { status } from '@store/selectors/solanaWallet' +import { proceeding, success } from '@store/selectors/referral' +import { actions } from '@store/reducers/referral' const Referrals = () => { + const address = 'mocked string' + const code = '' const [isModalOpen, setIsModalOpen] = useState(false) const walletStatus = useSelector(status) @@ -15,6 +19,8 @@ const Referrals = () => { const handleConnectWallet = () => { dispatch(walletActions.connect(false)) } + const inProgress = useSelector(proceeding) + const succed = useSelector(success) const connected = useMemo(() => { return walletStatus === Status.Initialized @@ -30,16 +36,22 @@ const Referrals = () => { unblurContent() } + useEffect(() => { + if (succed && !inProgress) { + onReferralModalClose() + } + }, [succed, inProgress]) + return ( null} - success={false} - inProgress={false} - referrerAddress={'asd'} + onConfirm={() => dispatch(actions.useCode({ code }))} + success={succed} + inProgress={inProgress} + referrerAddress={address} connected={connected} handleConnectWallet={handleConnectWallet} /> diff --git a/src/store/reducers/referral.ts b/src/store/reducers/referral.ts new file mode 100644 index 00000000..fbd38cd0 --- /dev/null +++ b/src/store/reducers/referral.ts @@ -0,0 +1,72 @@ +import { createSlice, PayloadAction } from '@reduxjs/toolkit' +import { PayloadType } from '@store/consts/types' + +export interface IReferralStore { + code: string | null + codeUsed: string | null + proceeding: boolean + user: string + success: boolean +} + +export const defaultState: IReferralStore = { + code: null, + codeUsed: null, + proceeding: false, + user: '', + success: false +} + +export const referralSliceName = 'leaderboard' + +const referralSlice = createSlice({ + name: referralSliceName, + initialState: defaultState, + reducers: { + setUserCode( + state, + action: PayloadAction<{ + code: string + }> + ) { + state.code = action.payload.code + return state + }, + getUserCode( + state, + action: PayloadAction<{ + address: string + }> + ) { + state.proceeding = true + state.user = action.payload.address + return state + }, + useCode( + state, + action: PayloadAction<{ + code: string + }> + ) { + state.proceeding = true + state.codeUsed = action.payload.code + return state + }, + setCodeUsed(state, action: PayloadAction<{ codeUsed: string }>) { + state.codeUsed = action.payload.codeUsed + return state + }, + setSuccessState(state, action: PayloadAction) { + state.success = action.payload + return state + }, + setProceedingState(state, action: PayloadAction) { + state.proceeding = action.payload + return state + } + } +}) + +export const actions = referralSlice.actions +export const reducer = referralSlice.reducer +export type PayloadTypes = PayloadType diff --git a/src/store/sagas/referral.ts b/src/store/sagas/referral.ts new file mode 100644 index 00000000..317c8bd7 --- /dev/null +++ b/src/store/sagas/referral.ts @@ -0,0 +1,68 @@ +import { PayloadAction } from '@reduxjs/toolkit' +import { actions } from '@store/reducers/referral' +import { all, call, put, spawn, takeEvery } from 'typed-redux-saga' +import { handleRpcError } from './connection' + +async function fetchRefferalCode(address: string) { + const response = await fetch(`http://localhost:3000/api/leaderboard/get-code/${address}`) + if (!response.ok) { + throw new Error('Failed to fetch referral code') + } + return response.json() as Promise +} +async function useReferralCode(code: string) { + const response = await fetch(`https://points.invariant.app/api/config`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ code }) + }) + + if (!response.ok) { + throw new Error('Failed to use code') + } + + return response +} +export function* getCode(action: PayloadAction<{ address: string }>): Generator { + try { + const code = yield* call(fetchRefferalCode, action.payload.address) + + yield* put(actions.setUserCode({ code })) + yield* put(actions.setProceedingState(false)) + } catch (error) { + yield* put(actions.setProceedingState(false)) + console.log(error) + yield* call(handleRpcError, (error as Error).message) + } +} + +export function* useCode(action: PayloadAction<{ code: string }>): Generator { + try { + yield* call(useReferralCode, action.payload.code) + + yield* put( + actions.setCodeUsed({ + codeUsed: action.payload.code + }) + ) + yield* put(actions.setProceedingState(false)) + yield* put(actions.setSuccessState(true)) + } catch (error) { + yield* put(actions.setProceedingState(false)) + console.log(error) + } +} + +export function* getCodeHandler(): Generator { + yield* takeEvery(actions.getUserCode, getCode) +} + +export function* useCodeHandler(): Generator { + yield* takeEvery(actions.useCode, useCode) +} + +export function* leaderboardSaga(): Generator { + yield all([getCodeHandler, useCodeHandler].map(spawn)) +} diff --git a/src/store/selectors/referral.ts b/src/store/selectors/referral.ts new file mode 100644 index 00000000..0907a2b8 --- /dev/null +++ b/src/store/selectors/referral.ts @@ -0,0 +1,19 @@ +import { AnyProps, keySelectors } from './helpers' +import { IReferralStore, referralSliceName } from '@store/reducers/referral' + +const store = (s: AnyProps) => s[referralSliceName] as IReferralStore + +// Basic selectors +export const { proceeding, code, codeUsed, success } = keySelectors(store, [ + 'proceeding', + 'code', + 'codeUsed', + 'success' +]) + +export const referralSelectors = { + proceeding, + code, + codeUsed, + success +} From f53288899be2eba87c23e0717c90c828db2294d7 Mon Sep 17 00:00:00 2001 From: matepal00 Date: Sat, 11 Jan 2025 20:55:38 +0100 Subject: [PATCH 05/13] bump --- .../Modals/RefferalModal/ReferralModal.tsx | 11 +++------- .../components/Referrals/Referrals.tsx | 20 ++++++++++++++++++- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/components/Modals/RefferalModal/ReferralModal.tsx b/src/components/Modals/RefferalModal/ReferralModal.tsx index b4ad1a0d..a0ed8cd2 100644 --- a/src/components/Modals/RefferalModal/ReferralModal.tsx +++ b/src/components/Modals/RefferalModal/ReferralModal.tsx @@ -3,7 +3,6 @@ import { Box, Button, Divider, Grid, Hidden, Popover, Typography } from '@mui/ma import AnimatedButton, { ProgressState } from '@components/AnimatedButton/AnimatedButton' import classNames from 'classnames' import { useEffect, useState } from 'react' -import ChangeWalletButton from '@components/Header/HeaderButton/ChangeWalletButton' export interface IRefferalModal { open: boolean @@ -112,13 +111,9 @@ export const ReferralModal = ({ progress={progress} /> ) : ( - null} - className={classes.confirmButton} - /> + )} diff --git a/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx b/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx index 188eed49..62ffbede 100644 --- a/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx +++ b/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx @@ -7,17 +7,20 @@ import { useDispatch, useSelector } from 'react-redux' import { status } from '@store/selectors/solanaWallet' import { proceeding, success } from '@store/selectors/referral' import { actions } from '@store/reducers/referral' +import SelectWalletModal from '@components/Modals/SelectWalletModal/SelectWalletModal' const Referrals = () => { const address = 'mocked string' const code = '' const [isModalOpen, setIsModalOpen] = useState(false) + const [isOpenSelectWalletModal, setIsOpenSelectWalletModal] = useState(false) const walletStatus = useSelector(status) const dispatch = useDispatch() const handleConnectWallet = () => { - dispatch(walletActions.connect(false)) + setIsOpenSelectWalletModal(true) + setIsModalOpen(false) } const inProgress = useSelector(proceeding) const succed = useSelector(success) @@ -45,6 +48,21 @@ const Referrals = () => { return ( + { + setIsOpenSelectWalletModal(false) + unblurContent() + }} + setIsOpenSelectWallet={() => { + setIsOpenSelectWalletModal(false) + unblurContent() + }} + handleConnect={() => dispatch(walletActions.connect(false))} + open={isOpenSelectWalletModal} + isChangeWallet={false} + onDisconnect={() => null} + /> Date: Sat, 11 Jan 2025 21:06:19 +0100 Subject: [PATCH 06/13] sign message --- src/store/sagas/referral.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/store/sagas/referral.ts b/src/store/sagas/referral.ts index 317c8bd7..0194f015 100644 --- a/src/store/sagas/referral.ts +++ b/src/store/sagas/referral.ts @@ -2,6 +2,7 @@ import { PayloadAction } from '@reduxjs/toolkit' import { actions } from '@store/reducers/referral' import { all, call, put, spawn, takeEvery } from 'typed-redux-saga' import { handleRpcError } from './connection' +import { getWallet } from './wallet' async function fetchRefferalCode(address: string) { const response = await fetch(`http://localhost:3000/api/leaderboard/get-code/${address}`) @@ -10,13 +11,13 @@ async function fetchRefferalCode(address: string) { } return response.json() as Promise } -async function useReferralCode(code: string) { +async function useReferralCode(code: string, address: string, signature: string) { const response = await fetch(`https://points.invariant.app/api/config`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ code }) + body: JSON.stringify({ address, code, signature }) }) if (!response.ok) { @@ -40,7 +41,11 @@ export function* getCode(action: PayloadAction<{ address: string }>): Generator export function* useCode(action: PayloadAction<{ code: string }>): Generator { try { - yield* call(useReferralCode, action.payload.code) + const wallet = yield* call(getWallet) + const encoder = new TextEncoder() + const message = encoder.encode('Sign message below').buffer + const sig = yield* call(wallet.signMessage, message) + yield* call(useReferralCode, action.payload.code, wallet.publicKey.toString(), sig.toString()) yield* put( actions.setCodeUsed({ From 08b46b04f16c90b8a86644a1af2caab3e08a40fb Mon Sep 17 00:00:00 2001 From: matepal00 Date: Sat, 11 Jan 2025 21:16:16 +0100 Subject: [PATCH 07/13] saga fixes --- .../LeaderboardPage/components/Referrals/Referrals.tsx | 2 +- src/store/sagas/index.ts | 4 +++- src/store/sagas/referral.ts | 6 +++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx b/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx index 62ffbede..09b8bd59 100644 --- a/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx +++ b/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx @@ -11,7 +11,7 @@ import SelectWalletModal from '@components/Modals/SelectWalletModal/SelectWallet const Referrals = () => { const address = 'mocked string' - const code = '' + const code = 'asd' const [isModalOpen, setIsModalOpen] = useState(false) const [isOpenSelectWalletModal, setIsOpenSelectWalletModal] = useState(false) const walletStatus = useSelector(status) diff --git a/src/store/sagas/index.ts b/src/store/sagas/index.ts index 2ebeefe9..e9fabf0a 100644 --- a/src/store/sagas/index.ts +++ b/src/store/sagas/index.ts @@ -8,6 +8,7 @@ import { statsHandler } from './stats' import { creatorSaga } from './creator' import { lockerSaga } from './locker' import { leaderboardSaga } from './leaderboard' +import { referralSaga } from './referral' // import { farmsSaga } from './farms' // import { bondsSaga } from './bonds' @@ -22,7 +23,8 @@ export function* rootSaga(): Generator { statsHandler, creatorSaga, leaderboardSaga, - lockerSaga + lockerSaga, + referralSaga // bondsSaga, // farmsSaga ].map(spawn) diff --git a/src/store/sagas/referral.ts b/src/store/sagas/referral.ts index 0194f015..682418a9 100644 --- a/src/store/sagas/referral.ts +++ b/src/store/sagas/referral.ts @@ -5,14 +5,14 @@ import { handleRpcError } from './connection' import { getWallet } from './wallet' async function fetchRefferalCode(address: string) { - const response = await fetch(`http://localhost:3000/api/leaderboard/get-code/${address}`) + const response = await fetch(`http://localhost:3000/api/referral/get-code/${address}`) if (!response.ok) { throw new Error('Failed to fetch referral code') } return response.json() as Promise } async function useReferralCode(code: string, address: string, signature: string) { - const response = await fetch(`https://points.invariant.app/api/config`, { + const response = await fetch(`http://localhost:3000/api/referral/use-code`, { method: 'POST', headers: { 'Content-Type': 'application/json' @@ -68,6 +68,6 @@ export function* useCodeHandler(): Generator { yield* takeEvery(actions.useCode, useCode) } -export function* leaderboardSaga(): Generator { +export function* referralSaga(): Generator { yield all([getCodeHandler, useCodeHandler].map(spawn)) } From e8475e9d961087951053b84e39319f50b37388b1 Mon Sep 17 00:00:00 2001 From: matepal00 Date: Sat, 11 Jan 2025 21:47:24 +0100 Subject: [PATCH 08/13] bump --- .../LeaderboardPage/components/Referrals/Referrals.tsx | 5 ++++- src/store/reducers/referral.ts | 10 +--------- src/store/sagas/referral.ts | 7 ++++--- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx b/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx index 09b8bd59..0e18dd95 100644 --- a/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx +++ b/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx @@ -10,8 +10,8 @@ import { actions } from '@store/reducers/referral' import SelectWalletModal from '@components/Modals/SelectWalletModal/SelectWalletModal' const Referrals = () => { + const [code, setCode] = useState('') const address = 'mocked string' - const code = 'asd' const [isModalOpen, setIsModalOpen] = useState(false) const [isOpenSelectWalletModal, setIsOpenSelectWalletModal] = useState(false) const walletStatus = useSelector(status) @@ -73,6 +73,9 @@ const Referrals = () => { connected={connected} handleConnectWallet={handleConnectWallet} /> + diff --git a/src/store/reducers/referral.ts b/src/store/reducers/referral.ts index fbd38cd0..5c9037c3 100644 --- a/src/store/reducers/referral.ts +++ b/src/store/reducers/referral.ts @@ -5,7 +5,6 @@ export interface IReferralStore { code: string | null codeUsed: string | null proceeding: boolean - user: string success: boolean } @@ -13,7 +12,6 @@ export const defaultState: IReferralStore = { code: null, codeUsed: null, proceeding: false, - user: '', success: false } @@ -32,14 +30,8 @@ const referralSlice = createSlice({ state.code = action.payload.code return state }, - getUserCode( - state, - action: PayloadAction<{ - address: string - }> - ) { + getUserCode(state) { state.proceeding = true - state.user = action.payload.address return state }, useCode( diff --git a/src/store/sagas/referral.ts b/src/store/sagas/referral.ts index 682418a9..5036f209 100644 --- a/src/store/sagas/referral.ts +++ b/src/store/sagas/referral.ts @@ -26,10 +26,11 @@ async function useReferralCode(code: string, address: string, signature: string) return response } -export function* getCode(action: PayloadAction<{ address: string }>): Generator { +export function* getCode(): Generator { try { - const code = yield* call(fetchRefferalCode, action.payload.address) - + const wallet = yield* call(getWallet) + const code = yield* call(fetchRefferalCode, wallet.publicKey.toString()) + console.log(code) yield* put(actions.setUserCode({ code })) yield* put(actions.setProceedingState(false)) } catch (error) { From 5a921ef4a8bad25fede254b56c96d78ecd510175 Mon Sep 17 00:00:00 2001 From: matepal00 Date: Sat, 11 Jan 2025 21:52:35 +0100 Subject: [PATCH 09/13] bump v2 --- .../LeaderboardPage/components/Referrals/Referrals.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx b/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx index 0e18dd95..58f31d5d 100644 --- a/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx +++ b/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx @@ -1,5 +1,5 @@ import ReferralModal from '@components/Modals/RefferalModal/ReferralModal' -import { Box, Button } from '@mui/material' +import { Box, Button, TextField } from '@mui/material' import { blurContent, unblurContent } from '@utils/uiUtils' import { useState, useMemo, useEffect } from 'react' import { Status, actions as walletActions } from '@store/reducers/solanaWallet' @@ -73,11 +73,14 @@ const Referrals = () => { connected={connected} handleConnectWallet={handleConnectWallet} /> - + setCode(e.target.value)} /> ) From d36cd755face07c694bf4346f0193f50436b6d77 Mon Sep 17 00:00:00 2001 From: matepal00 Date: Sat, 11 Jan 2025 22:27:59 +0100 Subject: [PATCH 10/13] endpoint change --- src/store/sagas/referral.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/store/sagas/referral.ts b/src/store/sagas/referral.ts index 5036f209..7479a9c7 100644 --- a/src/store/sagas/referral.ts +++ b/src/store/sagas/referral.ts @@ -5,14 +5,14 @@ import { handleRpcError } from './connection' import { getWallet } from './wallet' async function fetchRefferalCode(address: string) { - const response = await fetch(`http://localhost:3000/api/referral/get-code/${address}`) + const response = await fetch(`http://localhost:3000/api/leaderboard/get-code/${address}`) if (!response.ok) { throw new Error('Failed to fetch referral code') } return response.json() as Promise } async function useReferralCode(code: string, address: string, signature: string) { - const response = await fetch(`http://localhost:3000/api/referral/use-code`, { + const response = await fetch(`http://localhost:3000/api/leaderboard/use-code`, { method: 'POST', headers: { 'Content-Type': 'application/json' From 56bcbc6edb2d4bfafde35cb55de7f4b56b014173 Mon Sep 17 00:00:00 2001 From: matepal00 Date: Sat, 11 Jan 2025 22:58:58 +0100 Subject: [PATCH 11/13] api change --- src/store/sagas/referral.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/store/sagas/referral.ts b/src/store/sagas/referral.ts index 7479a9c7..ffe7c993 100644 --- a/src/store/sagas/referral.ts +++ b/src/store/sagas/referral.ts @@ -6,6 +6,7 @@ import { getWallet } from './wallet' async function fetchRefferalCode(address: string) { const response = await fetch(`http://localhost:3000/api/leaderboard/get-code/${address}`) + console.log(response) if (!response.ok) { throw new Error('Failed to fetch referral code') } From 2ef39870be221cad875cf17b6fc9a38dfaee8923 Mon Sep 17 00:00:00 2001 From: matepal00 Date: Sat, 11 Jan 2025 23:43:28 +0100 Subject: [PATCH 12/13] saga changes / fixes --- .../LeaderboardPage/components/Referrals/Referrals.tsx | 8 +++++--- src/store/reducers/index.ts | 4 +++- src/store/reducers/referral.ts | 8 ++------ src/store/sagas/referral.ts | 9 ++++----- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx b/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx index 58f31d5d..0d979818 100644 --- a/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx +++ b/src/pages/LeaderboardPage/components/Referrals/Referrals.tsx @@ -5,7 +5,7 @@ import { useState, useMemo, useEffect } from 'react' import { Status, actions as walletActions } from '@store/reducers/solanaWallet' import { useDispatch, useSelector } from 'react-redux' import { status } from '@store/selectors/solanaWallet' -import { proceeding, success } from '@store/selectors/referral' +import { referralSelectors } from '@store/selectors/referral' import { actions } from '@store/reducers/referral' import SelectWalletModal from '@components/Modals/SelectWalletModal/SelectWalletModal' @@ -22,8 +22,9 @@ const Referrals = () => { setIsOpenSelectWalletModal(true) setIsModalOpen(false) } - const inProgress = useSelector(proceeding) - const succed = useSelector(success) + + const inProgress = useSelector(referralSelectors.proceeding) + const succed = useSelector(referralSelectors.success) const connected = useMemo(() => { return walletStatus === Status.Initialized @@ -40,6 +41,7 @@ const Referrals = () => { } useEffect(() => { + console.log(succed, inProgress) if (succed && !inProgress) { onReferralModalClose() } diff --git a/src/store/reducers/index.ts b/src/store/reducers/index.ts index d4f14990..763ace9d 100644 --- a/src/store/reducers/index.ts +++ b/src/store/reducers/index.ts @@ -17,6 +17,7 @@ import { RPC } from '@utils/web3/connection' import { reducer as creatorReducer, creatorSliceName } from './creator' import { reducer as lockerReducer, lockerSliceName } from './locker' import { reducer as leaderboardReducer, leaderboardSliceName } from './leaderboard' +import { reducer as referralReducer, referralSliceName } from './referral' // import { farmsSliceName, reducer as farmsReducer } from './farms' // import { bondsSliceName, reducer as bondsReducer } from './bonds' @@ -84,7 +85,8 @@ const combinedReducers = combineReducers({ [statsSliceName]: statsReducer, [leaderboardSliceName]: leaderboardReducer, [creatorSliceName]: creatorReducer, - [lockerSliceName]: lockerReducer + [lockerSliceName]: lockerReducer, + [referralSliceName]: referralReducer // [farmsSliceName]: farmsReducer // [bondsSliceName]: bondsReducer }) diff --git a/src/store/reducers/referral.ts b/src/store/reducers/referral.ts index 5c9037c3..7925da3d 100644 --- a/src/store/reducers/referral.ts +++ b/src/store/reducers/referral.ts @@ -15,7 +15,7 @@ export const defaultState: IReferralStore = { success: false } -export const referralSliceName = 'leaderboard' +export const referralSliceName = 'referral' const referralSlice = createSlice({ name: referralSliceName, @@ -31,7 +31,6 @@ const referralSlice = createSlice({ return state }, getUserCode(state) { - state.proceeding = true return state }, useCode( @@ -49,12 +48,9 @@ const referralSlice = createSlice({ return state }, setSuccessState(state, action: PayloadAction) { + state.proceeding = false state.success = action.payload return state - }, - setProceedingState(state, action: PayloadAction) { - state.proceeding = action.payload - return state } } }) diff --git a/src/store/sagas/referral.ts b/src/store/sagas/referral.ts index ffe7c993..d7f633aa 100644 --- a/src/store/sagas/referral.ts +++ b/src/store/sagas/referral.ts @@ -33,9 +33,7 @@ export function* getCode(): Generator { const code = yield* call(fetchRefferalCode, wallet.publicKey.toString()) console.log(code) yield* put(actions.setUserCode({ code })) - yield* put(actions.setProceedingState(false)) } catch (error) { - yield* put(actions.setProceedingState(false)) console.log(error) yield* call(handleRpcError, (error as Error).message) } @@ -45,7 +43,9 @@ export function* useCode(action: PayloadAction<{ code: string }>): Generator { try { const wallet = yield* call(getWallet) const encoder = new TextEncoder() - const message = encoder.encode('Sign message below').buffer + const message = encoder.encode( + `${wallet.publicKey.toString()} is using referral ${action.payload.code}` + ) const sig = yield* call(wallet.signMessage, message) yield* call(useReferralCode, action.payload.code, wallet.publicKey.toString(), sig.toString()) @@ -54,10 +54,9 @@ export function* useCode(action: PayloadAction<{ code: string }>): Generator { codeUsed: action.payload.code }) ) - yield* put(actions.setProceedingState(false)) yield* put(actions.setSuccessState(true)) } catch (error) { - yield* put(actions.setProceedingState(false)) + yield* put(actions.setSuccessState(false)) console.log(error) } } From 4deb35f63843872cc948ba9efc94aa7e7208f534 Mon Sep 17 00:00:00 2001 From: matepal00 Date: Sun, 12 Jan 2025 14:12:23 +0100 Subject: [PATCH 13/13] change sig casting --- src/store/sagas/referral.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/store/sagas/referral.ts b/src/store/sagas/referral.ts index d7f633aa..d04de4c8 100644 --- a/src/store/sagas/referral.ts +++ b/src/store/sagas/referral.ts @@ -47,7 +47,12 @@ export function* useCode(action: PayloadAction<{ code: string }>): Generator { `${wallet.publicKey.toString()} is using referral ${action.payload.code}` ) const sig = yield* call(wallet.signMessage, message) - yield* call(useReferralCode, action.payload.code, wallet.publicKey.toString(), sig.toString()) + yield* call( + useReferralCode, + action.payload.code, + wallet.publicKey.toString(), + Buffer.from(sig).toString('base64') + ) yield* put( actions.setCodeUsed({