Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
01bd3e2
Integrate staking amount requirement
flopez7 Oct 24, 2025
23be3be
Add stake eligibility checks in Human App
flopez7 Oct 24, 2025
bc96490
- Added new ExchangeApiKeys module in Human App.
flopez7 Oct 28, 2025
c3a6886
simplify error handling in Gate and Mexc
flopez7 Oct 28, 2025
65fe558
add AES encryption key to .env.example and improve error handling in …
flopez7 Oct 28, 2025
b58f09f
add staking eligibility env var to enable or disable this functionality
flopez7 Oct 28, 2025
853833a
Generate unit tests for AesEncriptionService, AuthService, GateExchan…
flopez7 Oct 29, 2025
e796253
Refactor GateExchangeClient and MexcExchangeClient to use fetchWithHa…
flopez7 Oct 30, 2025
d9f9dd4
Add unit tests for staking requirement in HUMAN App
flopez7 Oct 30, 2025
5b92eac
Refactor exchange client methods to improve error handling and code s…
flopez7 Oct 31, 2025
a7880a9
Refactor GateExchangeClient and MexcExchangeClient tests for improved…
flopez7 Dec 11, 2025
d6736cf
Merge branch 'develop' into feat/staking-requirement
flopez7 Dec 12, 2025
14e0cb8
Add exchange stake summary retrieval and allowed exchanges
flopez7 Dec 15, 2025
0944144
Add endpoints for retrieving exchange API keys stake summary and supp…
flopez7 Dec 16, 2025
997411f
Fix ExchangeProviderResponseError status to UNPROCESSABLE_ENTITY
flopez7 Dec 16, 2025
d6e5c44
Refactor exchange API keys and create new staking module
flopez7 Dec 16, 2025
d5463e8
Merge branch 'develop' into feat/staking-requirement
flopez7 Dec 17, 2025
03e0416
implement stake formatting utility and improve some unit tests
flopez7 Dec 17, 2025
06e6916
update error handling for exchange stake retrieval in StakingService
flopez7 Dec 17, 2025
d729ef8
update error handling in ExchangeApiKeysController and StakingService…
flopez7 Dec 17, 2025
8a1bc29
update CORS methods and remove unused error class; enhance key enroll…
flopez7 Dec 17, 2025
64664db
add eligibilityEnabled property to StakeSummaryResponse and related D…
flopez7 Dec 19, 2025
3df929f
add stake configuration endpoint
flopez7 Dec 19, 2025
93e96b2
[Human App FE] Staking Requirements UI (#3725)
KirillKirill Dec 22, 2025
7f3ba72
update PostgreSQL volume path in docker-compose for correct data storage
flopez7 Jan 5, 2026
897efd1
Merge branch 'develop' into feat/staking-requirement
flopez7 Jan 5, 2026
89c8fa4
add minimum staking threshold to UI configuration response
flopez7 Jan 5, 2026
84391d0
chore: retrieving minThreshold from uiConfig
KirillKirill Jan 5, 2026
ae6f80b
minor fix
KirillKirill Jan 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/apps/human-app/frontend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ VITE_H_CAPTCHA_ORACLE_TASK_TYPES=image_points,image_boxes
# Other
VITE_HUMAN_PROTOCOL_HELP_URL=https://docs.humanprotocol.org/
VITE_HUMAN_PROTOCOL_URL=https://humanprotocol.org/
VITE_STAKING_DASHBOARD_URL=https://staking.humanprotocol.org/
VITE_HUMAN_SUPPORT_EMAIL=support@local.app
VITE_NAVBAR__LINK__HOW_IT_WORK_URL=https://humanprotocol.org/
VITE_NAVBAR__LINK__PROTOCOL_URL=https://humanprotocol.org/
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 25 additions & 19 deletions packages/apps/human-app/frontend/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { HomePageStateProvider } from '@/shared/contexts/homepage-state';
import { NotificationProvider } from '@/shared/providers/notifications-provider';
import { ModalProvider } from './shared/contexts/modal-context';
import { GlobalModal } from './shared/components/ui/modal/global-modal';
import { UiConfigProvider } from './shared/providers/ui-config-provider';

const root = document.getElementById('root');
if (!root) throw Error('root element is undefined');
Expand All @@ -39,25 +40,30 @@ createRoot(root).render(
<ColorModeProvider>
<CssBaseline />
<QueryClientProvider client={queryClient}>
<NotificationProvider>
<BrowserRouter>
<WalletConnectProvider>
<HomePageStateProvider>
<ModalProvider>
<Web3AuthProvider>
<AuthProvider>
<GlobalModal />
<JWTExpirationCheck>
<Router />
</JWTExpirationCheck>
</AuthProvider>
</Web3AuthProvider>
</ModalProvider>
</HomePageStateProvider>
<ReactQueryDevtools client={queryClient} initialIsOpen={false} />
</WalletConnectProvider>
</BrowserRouter>
</NotificationProvider>
<UiConfigProvider>
<NotificationProvider>
<BrowserRouter>
<WalletConnectProvider>
<HomePageStateProvider>
<ModalProvider>
<Web3AuthProvider>
<AuthProvider>
<GlobalModal />
<JWTExpirationCheck>
<Router />
</JWTExpirationCheck>
</AuthProvider>
</Web3AuthProvider>
</ModalProvider>
</HomePageStateProvider>
<ReactQueryDevtools
client={queryClient}
initialIsOpen={false}
/>
</WalletConnectProvider>
</BrowserRouter>
</NotificationProvider>
</UiConfigProvider>
</QueryClientProvider>
</ColorModeProvider>
</StrictMode>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const userDataSchema = z.object({
user_id: z.number(),
reputation_network: z.string(),
exp: z.number(),
is_stake_eligible: z.boolean(),
});

export type UserData = z.infer<typeof userDataSchema>;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import {
deleteExchangeApiKeys,
enrollExchangeApiKeys,
getExchangeApiKeys,
getSupportedExchanges,
} from '../services/exchangeApiKeys.service';

function useGetSupportedExchanges() {
return useQuery({
queryKey: ['supported-exchanges'],
queryFn: () => getSupportedExchanges(),
});
}

function useGetExchangeApiKeys() {
return useQuery({
queryKey: ['exchange-api-keys'],
queryFn: () => getExchangeApiKeys(),
});
}

function useEnrollExchangeApiKeys() {
const queryClient = useQueryClient();

return useMutation({
mutationKey: ['enroll-exchange-api-keys'],
mutationFn: (data: {
exchange: string;
apiKey: string;
secretKey: string;
}) => enrollExchangeApiKeys(data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['exchange-api-keys'] });
queryClient.invalidateQueries({ queryKey: ['staking-summary'] });
},
});
}

function useDeleteExchangeApiKeys() {
const queryClient = useQueryClient();

return useMutation({
mutationKey: ['delete-exchange-api-keys'],
mutationFn: () => deleteExchangeApiKeys(),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['exchange-api-keys'] });
queryClient.invalidateQueries({ queryKey: ['staking-summary'] });
},
});
}

export {
useGetSupportedExchanges,
useDeleteExchangeApiKeys,
useGetExchangeApiKeys,
useEnrollExchangeApiKeys,
};

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { useQuery } from '@tanstack/react-query';
import { getStakingSummary } from '../services/staking.service';

function useGetStakingSummary() {
return useQuery({
queryKey: ['staking-summary'],
queryFn: () => getStakingSummary(),
});
}

export { useGetStakingSummary };
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,5 @@ export const shouldNavigateToRegistration = (
oracle: Oracle,
registrationData?: RegistrationResult
): boolean =>
Boolean(
oracle.registrationNeeded &&
!registrationData?.oracle_addresses.includes(oracle.address)
);
!!oracle.registrationNeeded &&
!registrationData?.oracle_addresses.includes(oracle.address);
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { useModal } from '@/shared/contexts/modal-context';
import { useGetUiConfig } from '@/shared/hooks';
import { useUiConfig } from '@/shared/providers/ui-config-provider';
import { AvailableJobsFilterModal } from '../available-jobs-filter-modal';

export function useAvailableJobsFilterModal() {
const { openModal, closeModal } = useModal();
const { data: uiConfigData } = useGetUiConfig();
const { uiConfig } = useUiConfig();

return {
openModal: () => {
openModal({
content: (
<AvailableJobsFilterModal
chainIdsEnabled={uiConfigData?.chainIdsEnabled ?? []}
chainIdsEnabled={uiConfig?.chainIdsEnabled ?? []}
close={closeModal}
/>
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useIsMobile } from '@/shared/hooks/use-is-mobile';
import { useColorMode } from '@/shared/contexts/color-mode';
import { NoRecords } from '@/shared/components/ui/no-records';
import { PageCardLoader } from '@/shared/components/ui/page-card';
import { useGetUiConfig } from '@/shared/hooks';
import { useUiConfig } from '@/shared/providers/ui-config-provider';
import { useGetOracles } from '../hooks';
import { useGetOraclesNotifications } from '../hooks/use-get-oracles-notifications';
import { TabPanel } from './components';
Expand All @@ -30,19 +30,15 @@ export function JobsPage() {
error,
} = useGetOracles();

const {
data: uiConfigData,
isPending: isPendingUiConfig,
isError: isErrorUiConfig,
} = useGetUiConfig();
const { uiConfig, isUiConfigLoading, isUiConfigError } = useUiConfig();

const { address: oracle_address } = useParams<{ address: string }>();
const { t } = useTranslation();
const [activeTab, setActiveTab] = useState(0);
const isMobile = useIsMobile();

const isError = isErrorGetOracles || isErrorUiConfig;
const isPending = isPendingGetOracles || isPendingUiConfig;
const isError = isErrorGetOracles || isUiConfigError;
const isPending = isPendingGetOracles || isUiConfigLoading;
const { onError } = useGetOraclesNotifications();

const handleTabChange = (_event: React.SyntheticEvent, newValue: number) => {
Expand Down Expand Up @@ -119,7 +115,7 @@ export function JobsPage() {
<NoRecords />
) : (
<AvailableJobsView
chainIdsEnabled={uiConfigData.chainIdsEnabled}
chainIdsEnabled={uiConfig?.chainIdsEnabled ?? []}
/>
)}
</TabPanel>
Expand All @@ -128,7 +124,7 @@ export function JobsPage() {
<NoRecords />
) : (
<MyJobsView
chainIdsEnabled={uiConfigData.chainIdsEnabled}
chainIdsEnabled={uiConfig?.chainIdsEnabled ?? []}
/>
)}
</TabPanel>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { useModal } from '@/shared/contexts/modal-context';
import { useGetUiConfig } from '@/shared/hooks';
import { MyJobsFilterModal } from '../components/mobile/my-jobs-filter-modal';
import { useUiConfig } from '@/shared/providers/ui-config-provider';

export function useMyJobFilterModal() {
const { openModal, closeModal } = useModal();
const { data: uiConfigData } = useGetUiConfig();
const { uiConfig } = useUiConfig();

return {
openModal: () => {
openModal({
content: (
<MyJobsFilterModal
chainIdsEnabled={uiConfigData?.chainIdsEnabled ?? []}
chainIdsEnabled={uiConfig?.chainIdsEnabled ?? []}
close={closeModal}
/>
),
Expand Down
Loading
Loading