Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 5 additions & 1 deletion frontend/src/components/FederationTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,11 @@ const FederationTable = ({
}, [federationUpdatedAt]);

const loadRatings: () => void = () => {
if (settings.connection !== 'nostr') return;
if (settings.connection !== 'nostr') {
setLoading(false);
return;
}

setLoading(true);
federation.roboPool.subscribeRatings({
onevent: (event) => {
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/components/MakerForm/MakerForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const MakerForm = ({
onReset = () => {},
submitButtonLabel = 'Create Order',
}: MakerFormProps): React.JSX.Element => {
const { fav, setFav } = useContext<UseAppStoreType>(AppContext);
const { fav, setFav, settings } = useContext<UseAppStoreType>(AppContext);
const { federation, federationUpdatedAt } = useContext<UseFederationStoreType>(FederationContext);
const { maker, setMaker, garage } = useContext<UseGarageStoreType>(GarageContext);

Expand All @@ -68,7 +68,7 @@ const MakerForm = ({

const [badRequest, setBadRequest] = useState<string | null>(null);
const [amountLimits, setAmountLimits] = useState<number[]>([1, 1000]);
const [currentPrice, setCurrentPrice] = useState<number | string>('...');
const [currentPrice, setCurrentPrice] = useState<number>();
const [currencyCode, setCurrencyCode] = useState<string>('USD');

const [openDialogs, setOpenDialogs] = useState<boolean>(false);
Expand Down Expand Up @@ -411,6 +411,8 @@ const MakerForm = ({
}
};

const currencyFormatter = new Intl.NumberFormat(settings.language);

const SummaryText = (): React.JSX.Element => {
return (
<Typography
Expand Down Expand Up @@ -1031,7 +1033,7 @@ const MakerForm = ({
title={t("Your order's current exchange rate. Rate will move with the market.")}
>
<Typography align='center' variant='caption' color='text.secondary'>
{`${t('Order current rate:')} ${currentPrice ?? '-'} ${currencyCode}/BTC`}
{`${t('Order current rate:')} ${currentPrice ? currencyFormatter.format(currentPrice) : '-'} ${currencyCode}/BTC`}
</Typography>
</Tooltip>
</Collapse>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import {
type UseFederationStoreType,
FederationContext,
} from '../../../../contexts/FederationContext';
import { type UseAppStoreType, AppContext } from '../../../../contexts/AppContext';

const audioPath =
window.NativeRobosats === undefined
Expand Down Expand Up @@ -56,7 +55,6 @@ const EncryptedSocketChat: React.FC<Props> = ({
}: Props): React.JSX.Element => {
const { t } = useTranslation();
const theme = useTheme();
const { origin, hostUrl, settings } = useContext<UseAppStoreType>(AppContext);
const { garage, slotUpdatedAt } = useContext<UseGarageStoreType>(GarageContext);
const { federation } = useContext<UseFederationStoreType>(FederationContext);

Expand Down Expand Up @@ -115,13 +113,12 @@ const EncryptedSocketChat: React.FC<Props> = ({

if (!slot?.token) return;

const { url, basePath } = federation
.getCoordinator(order.shortAlias)
.getEndpoint(settings.network, origin, settings.selfhostedClient, hostUrl);
const url = federation.getCoordinator(order.shortAlias).url;
const protocol = url.includes('https') ? 'wss://' : 'ws://';

websocketClient
.open(
`${url.replace(/^https?:\/\//, 'ws://') + basePath}/ws/chat/${
`${url.replace(/^https?:\/\//, protocol)}/ws/chat/${
order.id
}/?token_sha256_hex=${sha256(slot?.token)}`,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import ChatHeader from '../ChatHeader';
import { type EncryptedChatMessage, type ServerMessage } from '..';
import { apiClient } from '../../../../services/api';
import ChatBottom from '../ChatBottom';
import { type UseAppStoreType, AppContext } from '../../../../contexts/AppContext';
import {
type UseFederationStoreType,
FederationContext,
Expand Down Expand Up @@ -55,7 +54,6 @@ const EncryptedTurtleChat: React.FC<Props> = ({
}: Props): React.JSX.Element => {
const { t } = useTranslation();
const theme = useTheme();
const { origin, hostUrl, settings } = useContext<UseAppStoreType>(AppContext);
const { federation } = useContext<UseFederationStoreType>(FederationContext);
const { garage } = useContext<UseGarageStoreType>(GarageContext);

Expand Down Expand Up @@ -95,11 +93,9 @@ const EncryptedTurtleChat: React.FC<Props> = ({

if (!shortAlias) return;

const { url, basePath } = federation
.getCoordinator(shortAlias)
.getEndpoint(settings.network, origin, settings.selfhostedClient, hostUrl);
const url = federation.getCoordinator(shortAlias).url;
apiClient
.get(url + basePath, `/api/chat/?order_id=${order.id}&offset=${lastIndex}`, {
.get(url, `/api/chat/?order_id=${order.id}&offset=${lastIndex}`, {
tokenSHA256: garage.getSlot()?.getRobot()?.tokenSHA256 ?? '',
})
.then((results: object) => {
Expand Down Expand Up @@ -197,13 +193,11 @@ const EncryptedTurtleChat: React.FC<Props> = ({
}
// If input string contains '#' send unencrypted and unlogged message
else if (value.substring(0, 1) === '#') {
const { url, basePath } = federation
.getCoordinator(garage.getSlot()?.activeOrder?.shortAlias ?? '')
.getEndpoint(settings.network, origin, settings.selfhostedClient, hostUrl);
const url = federation.getCoordinator(garage.getSlot()?.activeOrder?.shortAlias ?? '').url;
onSendMessage(value);
apiClient
.post(
url + basePath,
url,
`/api/chat/`,
{
PGP_message: value,
Expand Down Expand Up @@ -232,12 +226,12 @@ const EncryptedTurtleChat: React.FC<Props> = ({
onSendMessage(value);
encryptMessage(value, robot?.pubKey, peerPubKey ?? '', robot?.encPrivKey, slot?.token)
.then((encryptedMessage) => {
const { url, basePath } = federation
.getCoordinator(garage.getSlot()?.activeOrder?.shortAlias ?? '')
.getEndpoint(settings.network, origin, settings.selfhostedClient, hostUrl);
const url = federation.getCoordinator(
garage.getSlot()?.activeOrder?.shortAlias ?? '',
).url;
apiClient
.post(
url + basePath,
url,
`/api/chat/`,
{
PGP_message: String(encryptedMessage).split('\n').join('\\'),
Expand Down
6 changes: 0 additions & 6 deletions frontend/src/components/TradeBox/EncryptedChat/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,8 @@ const EncryptedChat: React.FC<Props> = ({

useEffect(() => {
// const slot = garage.getSlot();
const coordinator = federation.getCoordinator(order.shortAlias);
federation.roboPool.connect([
coordinator.getRelayUrl(settings.network, hostUrl, settings.selfhostedClient),
]);

// const since = new Date(order.created_at);
// since.setDate(since.getDate() - 2);

// federation.roboPool.subscribeChat(
// [order.maker_nostr_pubkey, order.taker_nostr_pubkey],
// Math.floor((since.getTime() / 1000)),
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/components/TradeBox/Prompts/Successful.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,13 @@ export const SuccessfulPrompt = ({
const coordinatorPubKey = federation.getCoordinator(order.shortAlias)?.nostrHexPubkey;

if (!coordinatorToken) {
console.error('Missing coordinator token');
setTokenError(true);
return;
}

if (!slot?.nostrPubKey || !slot.nostrSecKey || !coordinatorPubKey || !order.id) {
setHostRating(0);
console.error('Rating not valid');
return;
}

Expand Down
4 changes: 2 additions & 2 deletions frontend/src/contexts/AppContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ export interface UseAppStoreType {
export const initialAppContext: UseAppStoreType = {
theme: undefined,
torStatus: 'STARTING',
settings: new Settings(),
settings: getSettings(),
setSettings: () => {},
page: entryPage,
setPage: () => {},
Expand Down Expand Up @@ -202,7 +202,7 @@ export const AppContextProvider = ({ children }: AppContextProviderProps): React
const origin = initialAppContext.origin;
const [client, view] = window.RobosatsSettings.split('-');

const [settings, setSettings] = useState<Settings>(getSettings());
const [settings, setSettings] = useState<Settings>(initialAppContext.settings);
const [theme, setTheme] = useState<Theme>(() => {
return makeTheme(settings);
});
Expand Down
10 changes: 5 additions & 5 deletions frontend/src/contexts/FederationContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ export interface UseFederationStoreType {
addNewCoordinator: (alias: string, url: string) => void;
}

const initialFederation = new Federation('onion', new Settings(), '');

export const initialFederationContext: UseFederationStoreType = {
federation: new Federation('onion', new Settings(), ''),
federation: initialFederation,
coordinatorUpdatedAt: '',
federationUpdatedAt: '',
addNewCoordinator: () => {},
Expand All @@ -38,7 +40,7 @@ export const FederationContextProvider = ({
const { settings, page, origin, hostUrl, open, torStatus, client, fav } =
useContext<UseAppStoreType>(AppContext);
const { setMaker, garage } = useContext<UseGarageStoreType>(GarageContext);
const [federation] = useState(new Federation(origin, settings, hostUrl));
const [federation] = useState(initialFederationContext.federation);
const [coordinatorUpdatedAt, setCoordinatorUpdatedAt] = useState<string>(
new Date().toISOString(),
);
Expand All @@ -55,9 +57,7 @@ export const FederationContextProvider = ({

useEffect(() => {
if (client !== 'mobile' || torStatus === 'ON' || !settings.useProxy) {
void federation.updateUrl(origin, settings, hostUrl);
void federation.loadLimits();
federation.setConnection(settings, fav.coordinator);
federation.setConnection(origin, settings, hostUrl, fav.coordinator);
}
}, [settings.network, settings.useProxy, torStatus, settings.connection]);

Expand Down
39 changes: 7 additions & 32 deletions frontend/src/models/Coordinator.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ export class Coordinator {
this.testnetNodesPubkeys = value.testnetNodesPubkeys;
this.nostrHexPubkey = value.nostrHexPubkey;
this.url = '';
this.basePath = '';

this.updateUrl(origin, settings, hostUrl);
}
Expand All @@ -164,7 +163,6 @@ export class Coordinator {
public mainnetNodesPubkeys: string[] | undefined;
public testnetNodesPubkeys: string[] | undefined;
public url: string;
public basePath: string;
public nostrHexPubkey: string;

// These properties are fetched from coordinator API
Expand All @@ -177,11 +175,9 @@ export class Coordinator {

updateUrl = (origin: Origin, settings: Settings, hostUrl: string): void => {
if (settings.selfhostedClient && this.shortAlias !== 'local') {
this.url = hostUrl;
this.basePath = `/${settings.network}/${this.shortAlias}`;
this.url = `${hostUrl}/${settings.network}/${this.shortAlias}`;
} else {
this.url = String(this[settings.network]?.[origin]);
this.basePath = '';
}
};

Expand All @@ -200,7 +196,7 @@ export class Coordinator {
this.book = {};

apiClient
.get(this.url, `${this.basePath}/api/book/`)
.get(this.url, `/api/book/`)
.then((data) => {
if (!data?.not_found) {
this.book = (data as PublicOrder[]).reduce<Record<string, PublicOrder>>((book, order) => {
Expand Down Expand Up @@ -229,7 +225,7 @@ export class Coordinator {
this.loadingLimits = true;

apiClient
.get(this.url, `${this.basePath}/api/limits/`)
.get(this.url, `/api/limits/`)
.then((data) => {
if (data !== null) {
const newLimits = data as LimitList;
Expand Down Expand Up @@ -258,7 +254,7 @@ export class Coordinator {
this.loadingInfo = true;

apiClient
.get(this.url, `${this.basePath}/api/info/`)
.get(this.url, `/api/info/`)
.then((data) => {
if (data !== null) {
this.info = data as Info;
Expand Down Expand Up @@ -287,30 +283,9 @@ export class Coordinator {
this.book = {};
};

getBaseUrl = (): string => {
return this.url + this.basePath;
};

getEndpoint = (
network: 'mainnet' | 'testnet',
origin: Origin,
selfHosted: boolean,
hostUrl: string,
): { url: string; basePath: string } => {
if (selfHosted && this.shortAlias !== 'local') {
return { url: hostUrl, basePath: `/${network}/${this.shortAlias}` };
} else {
return { url: String(this[network][origin]), basePath: '' };
}
};

getRelayUrl = (network: 'mainnet' | 'testnet', hostUrl: string, selfHosted: boolean): string => {
const protocol = hostUrl.includes('https') ? 'wss' : 'ws';
if (selfHosted && this.shortAlias !== 'local') {
return `${protocol}://${hostUrl.replace(/^https?:\/\//, '')}/${network}/${this.shortAlias}/relay/`;
} else {
return `${protocol}://${this.url.replace(/^https?:\/\//, '')}/relay/`;
}
getRelayUrl = (hostUrl: string): string => {
const protocol = hostUrl.includes('https') ? 'wss://' : 'ws://';
return this.url.replace(/^https?:\/\//, protocol) + '/relay/';
};
}

Expand Down
Loading