mirror of
https://github.com/RoboSats/robosats.git
synced 2024-12-13 02:46:28 +00:00
Federation coordinators list refactor
This commit is contained in:
parent
3edd9280a5
commit
1695745cac
@ -25,7 +25,7 @@ const MakerPage = (): JSX.Element => {
|
||||
|
||||
const matches = useMemo(() => {
|
||||
return filterOrders({
|
||||
orders: Object.values(federation.book),
|
||||
federation,
|
||||
baseFilter: {
|
||||
currency: fav.currency === 0 ? 1 : fav.currency,
|
||||
type: fav.type,
|
||||
|
@ -26,7 +26,7 @@ import { GarageContext, type UseGarageStoreType } from '../../contexts/GarageCon
|
||||
const RobotPage = (): JSX.Element => {
|
||||
const { torStatus, windowSize, settings, page, client } = useContext<UseAppStoreType>(AppContext);
|
||||
const { garage } = useContext<UseGarageStoreType>(GarageContext);
|
||||
const { federation, sortedCoordinators } = useContext<UseFederationStoreType>(FederationContext);
|
||||
const { federation } = useContext<UseFederationStoreType>(FederationContext);
|
||||
const { t } = useTranslation();
|
||||
const params = useParams();
|
||||
const urlToken = settings.selfhostedClient ? params.token : null;
|
||||
@ -64,7 +64,7 @@ const RobotPage = (): JSX.Element => {
|
||||
setInputToken(token);
|
||||
genKey(token)
|
||||
.then((key) => {
|
||||
garage.createRobot(token, sortedCoordinators, {
|
||||
garage.createRobot(token, Object.keys(federation.coordinators), {
|
||||
token,
|
||||
pubKey: key.publicKeyArmored,
|
||||
encPrivKey: key.encryptedPrivateKeyArmored,
|
||||
|
@ -350,8 +350,9 @@ const BookControl = ({
|
||||
<FlagWithProps code='ANY' />
|
||||
</div>
|
||||
</MenuItem>
|
||||
{Object.values(federation.coordinators).map((coordinator) =>
|
||||
coordinator.enabled ? (
|
||||
{Object.values(federation.coordinators)
|
||||
.filter((coord) => coord.enabled)
|
||||
.map((coordinator) => (
|
||||
<MenuItem
|
||||
key={coordinator.shortAlias}
|
||||
value={coordinator.shortAlias}
|
||||
@ -367,10 +368,7 @@ const BookControl = ({
|
||||
/>
|
||||
</div>
|
||||
</MenuItem>
|
||||
) : (
|
||||
<></>
|
||||
),
|
||||
)}
|
||||
))}
|
||||
</Select>
|
||||
</Grid>
|
||||
</>
|
||||
|
@ -895,7 +895,7 @@ const BookTable = ({
|
||||
const filteredOrders = useMemo(() => {
|
||||
return showControls
|
||||
? filterOrders({
|
||||
orders,
|
||||
federation,
|
||||
baseFilter: fav,
|
||||
paymentMethods,
|
||||
})
|
||||
|
@ -21,8 +21,7 @@ const FederationTable = ({
|
||||
fillContainer = false,
|
||||
}: FederationTableProps): JSX.Element => {
|
||||
const { t } = useTranslation();
|
||||
const { federation, sortedCoordinators, federationUpdatedAt } =
|
||||
useContext<UseFederationStoreType>(FederationContext);
|
||||
const { federation, federationUpdatedAt } = useContext<UseFederationStoreType>(FederationContext);
|
||||
const { setOpen, settings } = useContext<UseAppStoreType>(AppContext);
|
||||
const theme = useTheme();
|
||||
const [pageSize, setPageSize] = useState<number>(0);
|
||||
@ -214,14 +213,6 @@ const FederationTable = ({
|
||||
}
|
||||
};
|
||||
|
||||
const reorderedCoordinators = useMemo(() => {
|
||||
return sortedCoordinators.reduce((coordinators, key) => {
|
||||
coordinators[key] = federation.coordinators[key];
|
||||
|
||||
return coordinators;
|
||||
}, {});
|
||||
}, [settings.network, federationUpdatedAt]);
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={
|
||||
@ -235,7 +226,7 @@ const FederationTable = ({
|
||||
localeText={localeText}
|
||||
rowHeight={3.714 * theme.typography.fontSize}
|
||||
headerHeight={3.25 * theme.typography.fontSize}
|
||||
rows={Object.values(reorderedCoordinators)}
|
||||
rows={Object.values(federation.coordinators)}
|
||||
getRowId={(params: Coordinator) => params.shortAlias}
|
||||
columns={columns}
|
||||
checkboxSelection={false}
|
||||
|
@ -26,7 +26,7 @@ const SelectCoordinator: React.FC<SelectCoordinatorProps> = ({
|
||||
setCoordinator,
|
||||
}) => {
|
||||
const { setOpen } = useContext<UseAppStoreType>(AppContext);
|
||||
const { federation, sortedCoordinators } = useContext<UseFederationStoreType>(FederationContext);
|
||||
const { federation } = useContext<UseFederationStoreType>(FederationContext);
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
|
||||
@ -109,18 +109,20 @@ const SelectCoordinator: React.FC<SelectCoordinatorProps> = ({
|
||||
onChange={handleCoordinatorChange}
|
||||
disableUnderline
|
||||
>
|
||||
{sortedCoordinators.map((shortAlias: string): JSX.Element | null => {
|
||||
let row: JSX.Element | null = null;
|
||||
const item = federation.getCoordinator(shortAlias);
|
||||
if (item.enabled === true) {
|
||||
row = (
|
||||
<MenuItem key={shortAlias} value={shortAlias}>
|
||||
<Typography>{item.longAlias}</Typography>
|
||||
</MenuItem>
|
||||
);
|
||||
}
|
||||
return row;
|
||||
})}
|
||||
{Object.keys(federation.coordinators).map(
|
||||
(shortAlias: string): JSX.Element | null => {
|
||||
let row: JSX.Element | null = null;
|
||||
const item = federation.getCoordinator(shortAlias);
|
||||
if (item.enabled === true) {
|
||||
row = (
|
||||
<MenuItem key={shortAlias} value={shortAlias}>
|
||||
<Typography>{item.longAlias}</Typography>
|
||||
</MenuItem>
|
||||
);
|
||||
}
|
||||
return row;
|
||||
},
|
||||
)}
|
||||
</Select>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
@ -27,7 +27,6 @@ export interface FederationContextProviderProps {
|
||||
|
||||
export interface UseFederationStoreType {
|
||||
federation: Federation;
|
||||
sortedCoordinators: string[];
|
||||
coordinatorUpdatedAt: string;
|
||||
federationUpdatedAt: string;
|
||||
addNewCoordinator: (alias: string, url: string) => void;
|
||||
@ -35,7 +34,6 @@ export interface UseFederationStoreType {
|
||||
|
||||
export const initialFederationContext: UseFederationStoreType = {
|
||||
federation: new Federation('onion', new Settings(), ''),
|
||||
sortedCoordinators: [],
|
||||
coordinatorUpdatedAt: '',
|
||||
federationUpdatedAt: '',
|
||||
addNewCoordinator: () => {},
|
||||
@ -50,7 +48,6 @@ export const FederationContextProvider = ({
|
||||
useContext<UseAppStoreType>(AppContext);
|
||||
const { setMaker, garage } = useContext<UseGarageStoreType>(GarageContext);
|
||||
const [federation] = useState(new Federation(origin, settings, hostUrl));
|
||||
const [sortedCoordinators, setSortedCoordinators] = useState(federationLottery(federation));
|
||||
const [coordinatorUpdatedAt, setCoordinatorUpdatedAt] = useState<string>(
|
||||
new Date().toISOString(),
|
||||
);
|
||||
@ -58,7 +55,7 @@ export const FederationContextProvider = ({
|
||||
|
||||
useEffect(() => {
|
||||
setMaker((maker) => {
|
||||
return { ...maker, coordinator: sortedCoordinators[0] };
|
||||
return { ...maker, coordinator: Object.keys(federation.coordinators)[0] };
|
||||
}); // default MakerForm coordinator is decided via sorted lottery
|
||||
federation.registerHook('onFederationUpdate', () => {
|
||||
setFederationUpdatedAt(new Date().toISOString());
|
||||
@ -122,7 +119,6 @@ export const FederationContextProvider = ({
|
||||
<FederationContext.Provider
|
||||
value={{
|
||||
federation,
|
||||
sortedCoordinators,
|
||||
coordinatorUpdatedAt,
|
||||
federationUpdatedAt,
|
||||
addNewCoordinator,
|
||||
|
@ -66,7 +66,7 @@ export const GarageContextProvider = ({ children }: GarageContextProviderProps):
|
||||
// All garage data structured
|
||||
const { settings, torStatus, open, page, client } = useContext<UseAppStoreType>(AppContext);
|
||||
const pageRef = useRef(page);
|
||||
const { federation, sortedCoordinators } = useContext<UseFederationStoreType>(FederationContext);
|
||||
const { federation } = useContext<UseFederationStoreType>(FederationContext);
|
||||
const [garage] = useState<Garage>(initialGarageContext.garage);
|
||||
const [maker, setMaker] = useState<Maker>(initialGarageContext.maker);
|
||||
const [slotUpdatedAt, setSlotUpdatedAt] = useState<string>(new Date().toISOString());
|
||||
@ -83,7 +83,7 @@ export const GarageContextProvider = ({ children }: GarageContextProviderProps):
|
||||
|
||||
useEffect(() => {
|
||||
setMaker((maker) => {
|
||||
return { ...maker, coordinator: sortedCoordinators[0] };
|
||||
return { ...maker, coordinator: Object.keys(federation.coordinators)[0] };
|
||||
}); // default MakerForm coordinator is decided via sorted lottery
|
||||
garage.registerHook('onSlotUpdate', onSlotUpdated);
|
||||
clearInterval(timer);
|
||||
|
@ -126,7 +126,7 @@ export class Coordinator {
|
||||
this.longAlias = value.longAlias;
|
||||
this.shortAlias = value.shortAlias;
|
||||
this.description = value.description;
|
||||
this.federated = value.federated;
|
||||
this.federated = value.federated ?? false;
|
||||
this.motto = value.motto;
|
||||
this.color = value.color;
|
||||
this.size_limit = value.badges.isFounder ? 21 * 100000000 : calculateSizeLimit(established);
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { SimplePool, VerifiedEvent, Event } from 'nostr-tools';
|
||||
import {
|
||||
Coordinator,
|
||||
type Exchange,
|
||||
@ -9,7 +8,7 @@ import {
|
||||
} from '.';
|
||||
import defaultFederation from '../../static/federation.json';
|
||||
import { systemClient } from '../services/System';
|
||||
import { getHost } from '../utils';
|
||||
import { federationLottery, getHost } from '../utils';
|
||||
import { coordinatorDefaultValues } from './Coordinator.model';
|
||||
import { updateExchangeInfo } from './Exchange.model';
|
||||
import eventToPublicOrder from '../utils/nostr';
|
||||
@ -20,19 +19,25 @@ type FederationHooks = 'onFederationUpdate';
|
||||
|
||||
export class Federation {
|
||||
constructor(origin: Origin, settings: Settings, hostUrl: string) {
|
||||
this.coordinators = Object.entries(defaultFederation).reduce(
|
||||
const coordinators = Object.entries(defaultFederation).reduce(
|
||||
(acc: Record<string, Coordinator>, [key, value]: [string, any]) => {
|
||||
if (getHost() !== '127.0.0.1:8000' && key === 'local') {
|
||||
// Do not add `Local Dev` unless it is running on localhost
|
||||
return acc;
|
||||
} else {
|
||||
acc[key] = new Coordinator(value, origin, settings, hostUrl);
|
||||
|
||||
acc[key].federated = true;
|
||||
return acc;
|
||||
}
|
||||
},
|
||||
{},
|
||||
);
|
||||
|
||||
this.coordinators = {};
|
||||
federationLottery().forEach((alias) => {
|
||||
if (coordinators[alias]) this.coordinators[alias] = coordinators[alias];
|
||||
});
|
||||
|
||||
this.exchange = {
|
||||
...defaultExchange,
|
||||
totalCoordinators: Object.keys(this.coordinators).length,
|
||||
@ -42,10 +47,10 @@ export class Federation {
|
||||
onFederationUpdate: [],
|
||||
};
|
||||
|
||||
Object.keys(defaultFederation).forEach((key) => {
|
||||
Object.keys(this.coordinators).forEach((key) => {
|
||||
if (key !== 'local' || getHost() === '127.0.0.1:8000') {
|
||||
// Do not add `Local Dev` unless it is running on localhost
|
||||
this.addCoordinator(origin, settings, hostUrl, defaultFederation[key]);
|
||||
this.addCoordinator(origin, settings, hostUrl, this.coordinators[key]);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -11,14 +11,14 @@
|
||||
// donate to the development fund. This is the only way envisioned to incentivize
|
||||
// donations to the development fund.
|
||||
|
||||
import { type Federation } from '../models';
|
||||
import defaultFederation from '../../static/federation.json';
|
||||
|
||||
export default function federationLottery(federation: Federation): string[] {
|
||||
export default function federationLottery(): string[] {
|
||||
// Create an array to store the coordinator short aliases and their corresponding weights (chance)
|
||||
const coordinatorChance: Array<{ shortAlias: string; chance: number }> = [];
|
||||
|
||||
// Convert the `federation` object into an array of {shortAlias, chance}
|
||||
Object.values(federation.coordinators).forEach((coor) => {
|
||||
Object.values(defaultFederation).forEach((coor) => {
|
||||
const chance = coor.badges.donatesToDevFund > 50 ? 50 : coor.badges?.donatesToDevFund;
|
||||
coordinatorChance.push({ shortAlias: coor.shortAlias, chance });
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { type PublicOrder, type Favorites } from '../models';
|
||||
import { type PublicOrder, type Favorites, Federation } from '../models';
|
||||
|
||||
interface AmountFilter {
|
||||
amount: string;
|
||||
@ -8,9 +8,9 @@ interface AmountFilter {
|
||||
}
|
||||
|
||||
interface FilterOrders {
|
||||
orders: PublicOrder[];
|
||||
federation: Federation;
|
||||
baseFilter: Favorites;
|
||||
premium: number | null;
|
||||
premium?: number | null;
|
||||
amountFilter?: AmountFilter | null;
|
||||
paymentMethods?: string[];
|
||||
}
|
||||
@ -60,13 +60,17 @@ const filterByPremium = function (order: PublicOrder, premium: number): boolean
|
||||
};
|
||||
|
||||
const filterOrders = function ({
|
||||
orders,
|
||||
federation,
|
||||
baseFilter,
|
||||
premium = null,
|
||||
paymentMethods = [],
|
||||
amountFilter = null,
|
||||
}: FilterOrders): PublicOrder[] {
|
||||
const filteredOrders = orders.filter((order) => {
|
||||
const enabledCoordinators = Object.values(federation.coordinators)
|
||||
.filter((coord) => coord.enabled)
|
||||
.map((coord) => coord.shortAlias);
|
||||
const filteredOrders = Object.values(federation.book).filter((order) => {
|
||||
const coordinatorCheck = enabledCoordinators.includes(order.coordinatorShortAlias ?? '');
|
||||
const typeChecks = order.type === baseFilter.type || baseFilter.type == null;
|
||||
const modeChecks = baseFilter.mode === 'fiat' ? !(order.currency === 1000) : true;
|
||||
const premiumChecks = premium !== null ? filterByPremium(order, premium) : true;
|
||||
@ -77,6 +81,7 @@ const filterOrders = function ({
|
||||
const hostChecks =
|
||||
baseFilter.coordinator !== 'any' ? filterByHost(order, baseFilter.coordinator) : true;
|
||||
return (
|
||||
coordinatorCheck &&
|
||||
typeChecks &&
|
||||
modeChecks &&
|
||||
premiumChecks &&
|
||||
|
Loading…
Reference in New Issue
Block a user