From 71e82da39cc4fb77bacb006337cde8bd9ab1bafc Mon Sep 17 00:00:00 2001 From: jeremy-babylonchain Date: Thu, 4 Sep 2025 07:00:35 +0700 Subject: [PATCH 1/6] feat: bsn fp allowlist --- src/ui/common/api/getBsn.ts | 74 +++++++++- .../FinalityProviderModal.tsx | 9 +- .../FinalityProviderFilter.tsx | 25 ++-- .../FinalityProviderSearch.tsx | 8 +- .../common/state/FinalityProviderBsnState.tsx | 136 +++++++++++++++--- src/ui/common/types/bsn.ts | 4 + 6 files changed, 220 insertions(+), 36 deletions(-) diff --git a/src/ui/common/api/getBsn.ts b/src/ui/common/api/getBsn.ts index 156d8eeba..fc88468b7 100644 --- a/src/ui/common/api/getBsn.ts +++ b/src/ui/common/api/getBsn.ts @@ -1,13 +1,77 @@ -import { Bsn } from "../types/bsn"; +import { getNetworkConfigBBN } from "@/ui/common/config/network/bbn"; + +import { Bsn, BsnType } from "../types/bsn"; import { getBsnLogoUrl } from "../utils/bsnLogo"; import { apiWrapper } from "./apiWrapper"; +export const BSN_TYPE_COSMOS: BsnType = "COSMOS"; +export const BSN_TYPE_ROLLUP: BsnType = "ROLLUP"; + +const { chainId: BBN_CHAIN_ID } = getNetworkConfigBBN(); + +// BSN Configuration for different types and behaviors +export interface BsnConfig { + modalTitle: string; + filterLabels: { + primary: string; + secondary: string; + }; + fpFilterBehavior: "active-inactive" | "allowlist-based"; +} + +export const BSN_CONFIGS: Record = { + // Babylon Genesis + [BBN_CHAIN_ID]: { + modalTitle: "Select Babylon Genesis Finality Provider", + filterLabels: { + primary: "Active", + secondary: "Inactive", + }, + fpFilterBehavior: "active-inactive", + }, + // Cosmos BSN config + COSMOS: { + modalTitle: "Select Cosmos Finality Provider", + filterLabels: { + primary: "Active", + secondary: "Inactive", + }, + fpFilterBehavior: "active-inactive", + }, + // Roll-up BSN config + ROLLUP: { + modalTitle: "Select Roll Up Finality Provider", + filterLabels: { + primary: "Allow listed", + secondary: "Non-Allow listed", + }, + fpFilterBehavior: "allowlist-based", + }, +}; + +/** + * Get BSN configuration based on BSN object + */ +export const getBsnConfig = (bsn?: Bsn): BsnConfig => { + if (!bsn) return BSN_CONFIGS.COSMOS; + + // Check if it's Babylon Genesis first + if (bsn.id === BBN_CHAIN_ID) { + return BSN_CONFIGS[BBN_CHAIN_ID]; + } + + // Use type-based config + return BSN_CONFIGS[bsn.type] || BSN_CONFIGS.COSMOS; +}; + interface BsnAPI { id: string; name: string; description: string; active_tvl: number; + type: BsnType; + allowlist?: string[]; // BTC FP pubkeys (hex) } interface BsnDataResponse { @@ -20,8 +84,16 @@ const createBSN = (bsn: BsnAPI): Bsn => ({ description: bsn.description, activeTvl: bsn.active_tvl, logoUrl: getBsnLogoUrl(bsn.id), + type: bsn.type, + allowlist: bsn.allowlist, }); +/** + * Determines if a BSN is Babylon Genesis + */ +export const isBabylonGenesisBsn = (bsn: Bsn): boolean => + bsn.id === BBN_CHAIN_ID; + export const getBSNs = async (): Promise => { const response = await apiWrapper( "GET", diff --git a/src/ui/common/components/Multistaking/FinalityProviderField/FinalityProviderModal.tsx b/src/ui/common/components/Multistaking/FinalityProviderField/FinalityProviderModal.tsx index 6e7af5dfc..d60568a25 100644 --- a/src/ui/common/components/Multistaking/FinalityProviderField/FinalityProviderModal.tsx +++ b/src/ui/common/components/Multistaking/FinalityProviderField/FinalityProviderModal.tsx @@ -4,10 +4,12 @@ import { DialogFooter, DialogHeader, } from "@babylonlabs-io/core-ui"; -import { useState } from "react"; +import { useMemo, useState } from "react"; +import { getBsnConfig } from "@/ui/common/api/getBsn"; import { ResponsiveDialog } from "@/ui/common/components/Modals/ResponsiveDialog"; import { FinalityProviders } from "@/ui/common/components/Multistaking/FinalityProviderField/FinalityProviders"; +import { useFinalityProviderBsnState } from "@/ui/common/state/FinalityProviderBsnState"; interface Props { open: boolean; @@ -27,6 +29,9 @@ export const FinalityProviderModal = ({ onBack, }: Props) => { const [selectedFP, setSelectedFp] = useState(defaultFinalityProvider); + const { selectedBsn } = useFinalityProviderBsnState(); + + const bsnConfig = useMemo(() => getBsnConfig(selectedBsn), [selectedBsn]); const handleClose = () => { onClose(); @@ -36,7 +41,7 @@ export const FinalityProviderModal = ({ return ( diff --git a/src/ui/common/components/Multistaking/FinalityProviders/FinalityProviderFilter.tsx b/src/ui/common/components/Multistaking/FinalityProviders/FinalityProviderFilter.tsx index 7dc97bf11..9a0b95b7a 100644 --- a/src/ui/common/components/Multistaking/FinalityProviders/FinalityProviderFilter.tsx +++ b/src/ui/common/components/Multistaking/FinalityProviders/FinalityProviderFilter.tsx @@ -1,22 +1,29 @@ import { Select } from "@babylonlabs-io/core-ui"; +import { useMemo } from "react"; +import { getBsnConfig } from "@/ui/common/api/getBsn"; import { useFinalityProviderBsnState } from "@/ui/common/state/FinalityProviderBsnState"; -const options = [ - { value: "active", label: "Active" }, - { value: "inactive", label: "Inactive" }, -]; - export const FinalityProviderFilter = () => { - const { filter, handleFilter } = useFinalityProviderBsnState(); + const { filter, handleFilter, selectedBsn } = useFinalityProviderBsnState(); + + const bsnConfig = useMemo(() => getBsnConfig(selectedBsn), [selectedBsn]); + + const options = useMemo( + () => [ + { value: "active", label: bsnConfig.filterLabels.primary }, + { value: "inactive", label: bsnConfig.filterLabels.secondary }, + ], + [bsnConfig.filterLabels], + ); return ( diff --git a/src/ui/common/state/FinalityProviderBsnState.tsx b/src/ui/common/state/FinalityProviderBsnState.tsx index fddcbfc41..112396629 100644 --- a/src/ui/common/state/FinalityProviderBsnState.tsx +++ b/src/ui/common/state/FinalityProviderBsnState.tsx @@ -2,6 +2,7 @@ import { useDebounce } from "@uidotdev/usehooks"; import { useCallback, useMemo, useState, type PropsWithChildren } from "react"; import { useSearchParams } from "react-router"; +import { BSN_TYPE_COSMOS, getBsnConfig } from "@/ui/common/api/getBsn"; import { getNetworkConfigBBN } from "@/ui/common/config/network/bbn"; import { useBsn } from "@/ui/common/hooks/client/api/useBsn"; import { useFinalityProvidersV2 } from "@/ui/common/hooks/client/api/useFinalityProvidersV2"; @@ -14,14 +15,18 @@ import { createStateUtils } from "@/ui/common/utils/createStateUtils"; import { getBsnLogoUrl } from "../utils/bsnLogo"; +const normalizeHex = (hex?: string): string => + (hex ?? "").trim().toLowerCase().replace(/^0x/, ""); + interface SortState { field?: string; direction?: "asc" | "desc"; } interface FilterState { - search: string; - status: "active" | "inactive" | ""; + searchTerm: string; + providerStatus: "active" | "inactive" | ""; + allowlistStatus: "allowlisted" | "not-allowlisted" | ""; } const { chainId: BBN_CHAIN_ID } = getNetworkConfigBBN(); @@ -31,6 +36,7 @@ const defaultBabylonBsn: Bsn = { name: "Babylon Genesis", description: "Babylon Genesis", logoUrl: getBsnLogoUrl(BBN_CHAIN_ID), + type: BSN_TYPE_COSMOS, }; interface FinalityProviderBsnState { @@ -45,6 +51,7 @@ interface FinalityProviderBsnState { bsnLoading: boolean; bsnError: boolean; selectedBsnId: string | undefined; + selectedBsn: Bsn | undefined; setSelectedBsnId: (id: string | undefined) => void; // Modal stakingModalPage: StakingModalPage; @@ -80,22 +87,82 @@ const STATUS_FILTERS = { fp.state !== FinalityProviderStateEnum.ACTIVE, }; +const createAllowlistFilters = (selectedBsn: Bsn | undefined) => { + const allowSet = new Set((selectedBsn?.allowlist || []).map(normalizeHex)); + + return { + allowlisted: (fp: FinalityProvider) => allowSet.has(normalizeHex(fp.btcPk)), + "not-allowlisted": (fp: FinalityProvider) => + !allowSet.has(normalizeHex(fp.btcPk)), + }; +}; + +const filterFinalityProvidersByBsn = ( + providers: FinalityProvider[], + filter: FilterState, + selectedBsn: Bsn | undefined, +): FinalityProvider[] => { + let filtered = providers; + + // Apply BSN-aware filtering based on provider status + if (filter.providerStatus) { + const bsnConfig = getBsnConfig(selectedBsn); + if (bsnConfig.fpFilterBehavior === "allowlist-based") { + // For rollup BSNs: filter all FPs by allowlist (regardless of active/inactive state) + const allowSet = new Set( + (selectedBsn?.allowlist || []).map(normalizeHex), + ); + + filtered = filtered.filter((fp) => { + const isAllowlisted = allowSet.has(normalizeHex(fp.btcPk)); + + if (filter.providerStatus === "active") { + return isAllowlisted; + } else { + return !isAllowlisted; + } + }); + } else { + // For cosmos/babylon BSNs: filter by active/inactive status + const statusFilter = + STATUS_FILTERS[filter.providerStatus as keyof typeof STATUS_FILTERS]; + if (statusFilter) { + filtered = filtered.filter(statusFilter); + } + } + } + + if (filter.allowlistStatus) { + const allowlistFilters = createAllowlistFilters(selectedBsn); + const allowlistFilter = + allowlistFilters[filter.allowlistStatus as keyof typeof allowlistFilters]; + if (allowlistFilter) { + filtered = filtered.filter(allowlistFilter); + } + } + + return filtered; +}; + const FILTERS = { - search: (fp: FinalityProvider, filter: FilterState) => { - const searchTerm = filter.search.toLowerCase(); + searchTerm: (fp: FinalityProvider, filter: FilterState) => { + const searchTerm = filter.searchTerm.toLowerCase(); return ( (fp.description?.moniker?.toLowerCase().includes(searchTerm) ?? false) || fp.btcPk.toLowerCase().includes(searchTerm) ); }, - status: (fp: FinalityProvider, filter: FilterState) => - filter.status && !filter.search ? STATUS_FILTERS[filter.status](fp) : true, + providerStatus: (fp: FinalityProvider, filter: FilterState) => + filter.providerStatus && !filter.searchTerm + ? STATUS_FILTERS[filter.providerStatus](fp) + : true, }; const defaultState: FinalityProviderBsnState = { filter: { - search: "", - status: "active", + searchTerm: "", + providerStatus: "active", + allowlistStatus: "", }, finalityProviders: [], isFetching: false, @@ -106,6 +173,7 @@ const defaultState: FinalityProviderBsnState = { bsnLoading: false, bsnError: false, selectedBsnId: undefined, + selectedBsn: undefined, setSelectedBsnId: () => {}, isRowSelectable: () => false, handleSort: () => {}, @@ -126,11 +194,12 @@ export function FinalityProviderBsnState({ children }: PropsWithChildren) { ); const [filter, setFilter] = useState({ - search: fpParam || "", - status: "active", + searchTerm: fpParam || "", + providerStatus: "active", + allowlistStatus: "", }); const [sortState, setSortState] = useState({}); - const debouncedSearch = useDebounce(filter.search, 300); + const debouncedSearch = useDebounce(filter.searchTerm, 300); const [selectedBsnId, setSelectedBsnId] = useState( BBN_CHAIN_ID, @@ -155,6 +224,11 @@ export function FinalityProviderBsnState({ children }: PropsWithChildren) { enabled: stakingModalPage === StakingModalPage.BSN, }); + const selectedBsn = useMemo( + () => bsnList.find((bsn) => bsn.id === selectedBsnId), + [bsnList, selectedBsnId], + ); + const finalityProviders = useMemo(() => { if (!data?.finalityProviders) { return []; @@ -195,18 +269,38 @@ export function FinalityProviderBsnState({ children }: PropsWithChildren) { ); }, []); - const isRowSelectable = useCallback((row: FinalityProvider) => { - return ( - row.state === FinalityProviderStateEnum.ACTIVE || - row.state === FinalityProviderStateEnum.INACTIVE - ); - }, []); + const isRowSelectable = useCallback( + (row: FinalityProvider) => { + const statusAllowed = + row.state === FinalityProviderStateEnum.ACTIVE || + row.state === FinalityProviderStateEnum.INACTIVE; + + // For selection (not filtering), only restrict based on allowlist for non-Babylon BSNs + const allowlistAllowed = + !selectedBsnId || + selectedBsnId === BBN_CHAIN_ID || + (selectedBsn?.allowlist || []).some( + (allowedPk) => normalizeHex(allowedPk) === normalizeHex(row.btcPk), + ); + + return statusAllowed && allowlistAllowed; + }, + [selectedBsnId, selectedBsn], + ); const filteredFinalityProviders = useMemo(() => { - return finalityProviders.filter((fp: FinalityProvider) => - Object.values(FILTERS).every((filterFn) => filterFn(fp, filter)), + // First apply search filter + const filtered = finalityProviders.filter((fp: FinalityProvider) => + FILTERS.searchTerm(fp, filter), ); - }, [finalityProviders, filter]); + + // If search is active, return all matching results without status filtering + if (filter.searchTerm) { + return filtered; + } + + return filterFinalityProvidersByBsn(filtered, filter, selectedBsn); + }, [finalityProviders, filter, selectedBsn]); const state = useMemo( () => ({ @@ -218,6 +312,7 @@ export function FinalityProviderBsnState({ children }: PropsWithChildren) { hasNextPage, fetchNextPage, selectedBsnId, + selectedBsn, setSelectedBsnId, selectedProviderIds, setSelectedProviderIds, @@ -238,6 +333,7 @@ export function FinalityProviderBsnState({ children }: PropsWithChildren) { hasNextPage, fetchNextPage, selectedBsnId, + selectedBsn, setSelectedBsnId, selectedProviderIds, setSelectedProviderIds, diff --git a/src/ui/common/types/bsn.ts b/src/ui/common/types/bsn.ts index 0a93f6d4e..a69f1afdb 100644 --- a/src/ui/common/types/bsn.ts +++ b/src/ui/common/types/bsn.ts @@ -1,7 +1,11 @@ +export type BsnType = "COSMOS" | "ROLLUP"; + export interface Bsn { id: string; name: string; description: string; logoUrl: string; activeTvl?: number; + type: BsnType; + allowlist?: string[]; // BTC FP pubkeys (hex) } From b854b89e215eada1c7451596ba85eb069a1e7b9a Mon Sep 17 00:00:00 2001 From: jeremy-babylonchain Date: Thu, 4 Sep 2025 17:54:39 +0700 Subject: [PATCH 2/6] fix: resolve comments --- src/ui/common/api/getBsn.ts | 47 ++++++++++--------- .../FinalityProviderFilter.tsx | 7 +-- .../common/state/FinalityProviderBsnState.tsx | 10 ++-- 3 files changed, 34 insertions(+), 30 deletions(-) diff --git a/src/ui/common/api/getBsn.ts b/src/ui/common/api/getBsn.ts index fc88468b7..08b96a2b5 100644 --- a/src/ui/common/api/getBsn.ts +++ b/src/ui/common/api/getBsn.ts @@ -11,41 +11,44 @@ export const BSN_TYPE_ROLLUP: BsnType = "ROLLUP"; const { chainId: BBN_CHAIN_ID } = getNetworkConfigBBN(); // BSN Configuration for different types and behaviors +export interface BsnFilterOption { + value: string; + label: string; +} + export interface BsnConfig { modalTitle: string; - filterLabels: { - primary: string; - secondary: string; - }; - fpFilterBehavior: "active-inactive" | "allowlist-based"; + filterOptions: BsnFilterOption[]; + fpFilterBehavior: "status-based" | "allowlist-based"; } export const BSN_CONFIGS: Record = { // Babylon Genesis [BBN_CHAIN_ID]: { modalTitle: "Select Babylon Genesis Finality Provider", - filterLabels: { - primary: "Active", - secondary: "Inactive", - }, - fpFilterBehavior: "active-inactive", + filterOptions: [ + { value: "active", label: "Active" }, + { value: "inactive", label: "Inactive" }, + { value: "jailed", label: "Jailed" }, + { value: "slashed", label: "Slashed" }, + ], + fpFilterBehavior: "status-based", }, - // Cosmos BSN config COSMOS: { modalTitle: "Select Cosmos Finality Provider", - filterLabels: { - primary: "Active", - secondary: "Inactive", - }, - fpFilterBehavior: "active-inactive", + filterOptions: [ + { value: "active", label: "Active" }, + { value: "inactive", label: "Inactive" }, + ], + fpFilterBehavior: "status-based", }, // Roll-up BSN config ROLLUP: { modalTitle: "Select Roll Up Finality Provider", - filterLabels: { - primary: "Allow listed", - secondary: "Non-Allow listed", - }, + filterOptions: [ + { value: "active", label: "Allowlisted" }, + { value: "inactive", label: "Not Allowlisted" }, + ], fpFilterBehavior: "allowlist-based", }, }; @@ -54,7 +57,7 @@ export const BSN_CONFIGS: Record = { * Get BSN configuration based on BSN object */ export const getBsnConfig = (bsn?: Bsn): BsnConfig => { - if (!bsn) return BSN_CONFIGS.COSMOS; + if (!bsn) return BSN_CONFIGS[BBN_CHAIN_ID]; // Check if it's Babylon Genesis first if (bsn.id === BBN_CHAIN_ID) { @@ -62,7 +65,7 @@ export const getBsnConfig = (bsn?: Bsn): BsnConfig => { } // Use type-based config - return BSN_CONFIGS[bsn.type] || BSN_CONFIGS.COSMOS; + return BSN_CONFIGS[bsn.type] || BSN_CONFIGS[BBN_CHAIN_ID]; }; interface BsnAPI { diff --git a/src/ui/common/components/Multistaking/FinalityProviders/FinalityProviderFilter.tsx b/src/ui/common/components/Multistaking/FinalityProviders/FinalityProviderFilter.tsx index 9a0b95b7a..b5963f509 100644 --- a/src/ui/common/components/Multistaking/FinalityProviders/FinalityProviderFilter.tsx +++ b/src/ui/common/components/Multistaking/FinalityProviders/FinalityProviderFilter.tsx @@ -10,11 +10,8 @@ export const FinalityProviderFilter = () => { const bsnConfig = useMemo(() => getBsnConfig(selectedBsn), [selectedBsn]); const options = useMemo( - () => [ - { value: "active", label: bsnConfig.filterLabels.primary }, - { value: "inactive", label: bsnConfig.filterLabels.secondary }, - ], - [bsnConfig.filterLabels], + () => bsnConfig.filterOptions, + [bsnConfig.filterOptions], ); return ( diff --git a/src/ui/common/state/FinalityProviderBsnState.tsx b/src/ui/common/state/FinalityProviderBsnState.tsx index 112396629..cf7b20b9b 100644 --- a/src/ui/common/state/FinalityProviderBsnState.tsx +++ b/src/ui/common/state/FinalityProviderBsnState.tsx @@ -84,7 +84,11 @@ const STATUS_FILTERS = { active: (fp: FinalityProvider) => fp.state === FinalityProviderStateEnum.ACTIVE, inactive: (fp: FinalityProvider) => - fp.state !== FinalityProviderStateEnum.ACTIVE, + fp.state === FinalityProviderStateEnum.INACTIVE, + jailed: (fp: FinalityProvider) => + fp.state === FinalityProviderStateEnum.JAILED, + slashed: (fp: FinalityProvider) => + fp.state === FinalityProviderStateEnum.SLASHED, }; const createAllowlistFilters = (selectedBsn: Bsn | undefined) => { @@ -122,8 +126,8 @@ const filterFinalityProvidersByBsn = ( return !isAllowlisted; } }); - } else { - // For cosmos/babylon BSNs: filter by active/inactive status + } else if (bsnConfig.fpFilterBehavior === "status-based") { + // For status-based BSNs: filter by finality provider state (active/inactive/jailed/slashed) const statusFilter = STATUS_FILTERS[filter.providerStatus as keyof typeof STATUS_FILTERS]; if (statusFilter) { From 27e38105c3adfa6e7349671c9ba5c39b62f1e2c9 Mon Sep 17 00:00:00 2001 From: jeremy-babylonchain Date: Thu, 4 Sep 2025 18:56:05 +0700 Subject: [PATCH 3/6] fix: resolve comments --- src/ui/common/api/getBsn.ts | 88 +-------------- .../FinalityProviderModal.tsx | 9 +- .../FinalityProviderFilter.tsx | 13 +-- src/ui/common/hooks/client/api/useBsn.ts | 2 +- src/ui/common/services/bsnService.ts | 94 ++++++++++++++++ .../common/state/FinalityProviderBsnState.tsx | 105 +++++++++++++++--- 6 files changed, 195 insertions(+), 116 deletions(-) create mode 100644 src/ui/common/services/bsnService.ts diff --git a/src/ui/common/api/getBsn.ts b/src/ui/common/api/getBsn.ts index 08b96a2b5..84377fb4e 100644 --- a/src/ui/common/api/getBsn.ts +++ b/src/ui/common/api/getBsn.ts @@ -1,74 +1,11 @@ -import { getNetworkConfigBBN } from "@/ui/common/config/network/bbn"; - -import { Bsn, BsnType } from "../types/bsn"; -import { getBsnLogoUrl } from "../utils/bsnLogo"; +import { BsnType } from "../types/bsn"; import { apiWrapper } from "./apiWrapper"; export const BSN_TYPE_COSMOS: BsnType = "COSMOS"; export const BSN_TYPE_ROLLUP: BsnType = "ROLLUP"; -const { chainId: BBN_CHAIN_ID } = getNetworkConfigBBN(); - -// BSN Configuration for different types and behaviors -export interface BsnFilterOption { - value: string; - label: string; -} - -export interface BsnConfig { - modalTitle: string; - filterOptions: BsnFilterOption[]; - fpFilterBehavior: "status-based" | "allowlist-based"; -} - -export const BSN_CONFIGS: Record = { - // Babylon Genesis - [BBN_CHAIN_ID]: { - modalTitle: "Select Babylon Genesis Finality Provider", - filterOptions: [ - { value: "active", label: "Active" }, - { value: "inactive", label: "Inactive" }, - { value: "jailed", label: "Jailed" }, - { value: "slashed", label: "Slashed" }, - ], - fpFilterBehavior: "status-based", - }, - COSMOS: { - modalTitle: "Select Cosmos Finality Provider", - filterOptions: [ - { value: "active", label: "Active" }, - { value: "inactive", label: "Inactive" }, - ], - fpFilterBehavior: "status-based", - }, - // Roll-up BSN config - ROLLUP: { - modalTitle: "Select Roll Up Finality Provider", - filterOptions: [ - { value: "active", label: "Allowlisted" }, - { value: "inactive", label: "Not Allowlisted" }, - ], - fpFilterBehavior: "allowlist-based", - }, -}; - -/** - * Get BSN configuration based on BSN object - */ -export const getBsnConfig = (bsn?: Bsn): BsnConfig => { - if (!bsn) return BSN_CONFIGS[BBN_CHAIN_ID]; - - // Check if it's Babylon Genesis first - if (bsn.id === BBN_CHAIN_ID) { - return BSN_CONFIGS[BBN_CHAIN_ID]; - } - - // Use type-based config - return BSN_CONFIGS[bsn.type] || BSN_CONFIGS[BBN_CHAIN_ID]; -}; - -interface BsnAPI { +export interface BsnAPI { id: string; name: string; description: string; @@ -81,29 +18,12 @@ interface BsnDataResponse { data: BsnAPI[]; } -const createBSN = (bsn: BsnAPI): Bsn => ({ - id: bsn.id, - name: bsn.name, - description: bsn.description, - activeTvl: bsn.active_tvl, - logoUrl: getBsnLogoUrl(bsn.id), - type: bsn.type, - allowlist: bsn.allowlist, -}); - -/** - * Determines if a BSN is Babylon Genesis - */ -export const isBabylonGenesisBsn = (bsn: Bsn): boolean => - bsn.id === BBN_CHAIN_ID; - -export const getBSNs = async (): Promise => { +export const getBsnAPI = async (): Promise => { const response = await apiWrapper( "GET", "/v2/bsn", "Error getting BSN list", ); - const { data } = response.data; - return data.map(createBSN); + return response.data.data; }; diff --git a/src/ui/common/components/Multistaking/FinalityProviderField/FinalityProviderModal.tsx b/src/ui/common/components/Multistaking/FinalityProviderField/FinalityProviderModal.tsx index d60568a25..dbbcd73fa 100644 --- a/src/ui/common/components/Multistaking/FinalityProviderField/FinalityProviderModal.tsx +++ b/src/ui/common/components/Multistaking/FinalityProviderField/FinalityProviderModal.tsx @@ -4,9 +4,8 @@ import { DialogFooter, DialogHeader, } from "@babylonlabs-io/core-ui"; -import { useMemo, useState } from "react"; +import { useState } from "react"; -import { getBsnConfig } from "@/ui/common/api/getBsn"; import { ResponsiveDialog } from "@/ui/common/components/Modals/ResponsiveDialog"; import { FinalityProviders } from "@/ui/common/components/Multistaking/FinalityProviderField/FinalityProviders"; import { useFinalityProviderBsnState } from "@/ui/common/state/FinalityProviderBsnState"; @@ -29,9 +28,7 @@ export const FinalityProviderModal = ({ onBack, }: Props) => { const [selectedFP, setSelectedFp] = useState(defaultFinalityProvider); - const { selectedBsn } = useFinalityProviderBsnState(); - - const bsnConfig = useMemo(() => getBsnConfig(selectedBsn), [selectedBsn]); + const { modalTitle } = useFinalityProviderBsnState(); const handleClose = () => { onClose(); @@ -41,7 +38,7 @@ export const FinalityProviderModal = ({ return ( diff --git a/src/ui/common/components/Multistaking/FinalityProviders/FinalityProviderFilter.tsx b/src/ui/common/components/Multistaking/FinalityProviders/FinalityProviderFilter.tsx index b5963f509..c519d7571 100644 --- a/src/ui/common/components/Multistaking/FinalityProviders/FinalityProviderFilter.tsx +++ b/src/ui/common/components/Multistaking/FinalityProviders/FinalityProviderFilter.tsx @@ -1,22 +1,13 @@ import { Select } from "@babylonlabs-io/core-ui"; -import { useMemo } from "react"; -import { getBsnConfig } from "@/ui/common/api/getBsn"; import { useFinalityProviderBsnState } from "@/ui/common/state/FinalityProviderBsnState"; export const FinalityProviderFilter = () => { - const { filter, handleFilter, selectedBsn } = useFinalityProviderBsnState(); - - const bsnConfig = useMemo(() => getBsnConfig(selectedBsn), [selectedBsn]); - - const options = useMemo( - () => bsnConfig.filterOptions, - [bsnConfig.filterOptions], - ); + const { filter, handleFilter, filterOptions } = useFinalityProviderBsnState(); return (