mirror of
https://github.com/RoboSats/robosats.git
synced 2025-07-19 17:23:19 +00:00
Fix testnet connections
This commit is contained in:
@ -20,7 +20,6 @@ import {
|
|||||||
type UseFederationStoreType,
|
type UseFederationStoreType,
|
||||||
FederationContext,
|
FederationContext,
|
||||||
} from '../../../../contexts/FederationContext';
|
} from '../../../../contexts/FederationContext';
|
||||||
import { type UseAppStoreType, AppContext } from '../../../../contexts/AppContext';
|
|
||||||
|
|
||||||
const audioPath =
|
const audioPath =
|
||||||
window.NativeRobosats === undefined
|
window.NativeRobosats === undefined
|
||||||
@ -56,7 +55,6 @@ const EncryptedSocketChat: React.FC<Props> = ({
|
|||||||
}: Props): React.JSX.Element => {
|
}: Props): React.JSX.Element => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { origin, hostUrl, settings } = useContext<UseAppStoreType>(AppContext);
|
|
||||||
const { garage, slotUpdatedAt } = useContext<UseGarageStoreType>(GarageContext);
|
const { garage, slotUpdatedAt } = useContext<UseGarageStoreType>(GarageContext);
|
||||||
const { federation } = useContext<UseFederationStoreType>(FederationContext);
|
const { federation } = useContext<UseFederationStoreType>(FederationContext);
|
||||||
|
|
||||||
@ -115,13 +113,11 @@ const EncryptedSocketChat: React.FC<Props> = ({
|
|||||||
|
|
||||||
if (!slot?.token) return;
|
if (!slot?.token) return;
|
||||||
|
|
||||||
const { url, basePath } = federation
|
const url = federation.getCoordinator(order.shortAlias).url;
|
||||||
.getCoordinator(order.shortAlias)
|
|
||||||
.getEndpoint(settings.network, origin, settings.selfhostedClient, hostUrl);
|
|
||||||
|
|
||||||
websocketClient
|
websocketClient
|
||||||
.open(
|
.open(
|
||||||
`${url.replace(/^https?:\/\//, 'ws://') + basePath}/ws/chat/${
|
`${url.replace(/^https?:\/\//, 'ws://')}/ws/chat/${
|
||||||
order.id
|
order.id
|
||||||
}/?token_sha256_hex=${sha256(slot?.token)}`,
|
}/?token_sha256_hex=${sha256(slot?.token)}`,
|
||||||
)
|
)
|
||||||
|
@ -13,7 +13,6 @@ import ChatHeader from '../ChatHeader';
|
|||||||
import { type EncryptedChatMessage, type ServerMessage } from '..';
|
import { type EncryptedChatMessage, type ServerMessage } from '..';
|
||||||
import { apiClient } from '../../../../services/api';
|
import { apiClient } from '../../../../services/api';
|
||||||
import ChatBottom from '../ChatBottom';
|
import ChatBottom from '../ChatBottom';
|
||||||
import { type UseAppStoreType, AppContext } from '../../../../contexts/AppContext';
|
|
||||||
import {
|
import {
|
||||||
type UseFederationStoreType,
|
type UseFederationStoreType,
|
||||||
FederationContext,
|
FederationContext,
|
||||||
@ -55,7 +54,6 @@ const EncryptedTurtleChat: React.FC<Props> = ({
|
|||||||
}: Props): React.JSX.Element => {
|
}: Props): React.JSX.Element => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { origin, hostUrl, settings } = useContext<UseAppStoreType>(AppContext);
|
|
||||||
const { federation } = useContext<UseFederationStoreType>(FederationContext);
|
const { federation } = useContext<UseFederationStoreType>(FederationContext);
|
||||||
const { garage } = useContext<UseGarageStoreType>(GarageContext);
|
const { garage } = useContext<UseGarageStoreType>(GarageContext);
|
||||||
|
|
||||||
@ -95,11 +93,9 @@ const EncryptedTurtleChat: React.FC<Props> = ({
|
|||||||
|
|
||||||
if (!shortAlias) return;
|
if (!shortAlias) return;
|
||||||
|
|
||||||
const { url, basePath } = federation
|
const url = federation.getCoordinator(shortAlias).url;
|
||||||
.getCoordinator(shortAlias)
|
|
||||||
.getEndpoint(settings.network, origin, settings.selfhostedClient, hostUrl);
|
|
||||||
apiClient
|
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 ?? '',
|
tokenSHA256: garage.getSlot()?.getRobot()?.tokenSHA256 ?? '',
|
||||||
})
|
})
|
||||||
.then((results: object) => {
|
.then((results: object) => {
|
||||||
@ -197,13 +193,11 @@ const EncryptedTurtleChat: React.FC<Props> = ({
|
|||||||
}
|
}
|
||||||
// If input string contains '#' send unencrypted and unlogged message
|
// If input string contains '#' send unencrypted and unlogged message
|
||||||
else if (value.substring(0, 1) === '#') {
|
else if (value.substring(0, 1) === '#') {
|
||||||
const { url, basePath } = federation
|
const url = federation.getCoordinator(garage.getSlot()?.activeOrder?.shortAlias ?? '').url;
|
||||||
.getCoordinator(garage.getSlot()?.activeOrder?.shortAlias ?? '')
|
|
||||||
.getEndpoint(settings.network, origin, settings.selfhostedClient, hostUrl);
|
|
||||||
onSendMessage(value);
|
onSendMessage(value);
|
||||||
apiClient
|
apiClient
|
||||||
.post(
|
.post(
|
||||||
url + basePath,
|
url,
|
||||||
`/api/chat/`,
|
`/api/chat/`,
|
||||||
{
|
{
|
||||||
PGP_message: value,
|
PGP_message: value,
|
||||||
@ -232,12 +226,12 @@ const EncryptedTurtleChat: React.FC<Props> = ({
|
|||||||
onSendMessage(value);
|
onSendMessage(value);
|
||||||
encryptMessage(value, robot?.pubKey, peerPubKey ?? '', robot?.encPrivKey, slot?.token)
|
encryptMessage(value, robot?.pubKey, peerPubKey ?? '', robot?.encPrivKey, slot?.token)
|
||||||
.then((encryptedMessage) => {
|
.then((encryptedMessage) => {
|
||||||
const { url, basePath } = federation
|
const url = federation.getCoordinator(
|
||||||
.getCoordinator(garage.getSlot()?.activeOrder?.shortAlias ?? '')
|
garage.getSlot()?.activeOrder?.shortAlias ?? '',
|
||||||
.getEndpoint(settings.network, origin, settings.selfhostedClient, hostUrl);
|
).url;
|
||||||
apiClient
|
apiClient
|
||||||
.post(
|
.post(
|
||||||
url + basePath,
|
url,
|
||||||
`/api/chat/`,
|
`/api/chat/`,
|
||||||
{
|
{
|
||||||
PGP_message: String(encryptedMessage).split('\n').join('\\'),
|
PGP_message: String(encryptedMessage).split('\n').join('\\'),
|
||||||
|
@ -49,14 +49,8 @@ const EncryptedChat: React.FC<Props> = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// const slot = garage.getSlot();
|
// 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);
|
// const since = new Date(order.created_at);
|
||||||
// since.setDate(since.getDate() - 2);
|
// since.setDate(since.getDate() - 2);
|
||||||
|
|
||||||
// federation.roboPool.subscribeChat(
|
// federation.roboPool.subscribeChat(
|
||||||
// [order.maker_nostr_pubkey, order.taker_nostr_pubkey],
|
// [order.maker_nostr_pubkey, order.taker_nostr_pubkey],
|
||||||
// Math.floor((since.getTime() / 1000)),
|
// Math.floor((since.getTime() / 1000)),
|
||||||
|
@ -164,7 +164,7 @@ export interface UseAppStoreType {
|
|||||||
export const initialAppContext: UseAppStoreType = {
|
export const initialAppContext: UseAppStoreType = {
|
||||||
theme: undefined,
|
theme: undefined,
|
||||||
torStatus: 'STARTING',
|
torStatus: 'STARTING',
|
||||||
settings: new Settings(),
|
settings: getSettings(),
|
||||||
setSettings: () => {},
|
setSettings: () => {},
|
||||||
page: entryPage,
|
page: entryPage,
|
||||||
setPage: () => {},
|
setPage: () => {},
|
||||||
@ -202,7 +202,7 @@ export const AppContextProvider = ({ children }: AppContextProviderProps): React
|
|||||||
const origin = initialAppContext.origin;
|
const origin = initialAppContext.origin;
|
||||||
const [client, view] = window.RobosatsSettings.split('-');
|
const [client, view] = window.RobosatsSettings.split('-');
|
||||||
|
|
||||||
const [settings, setSettings] = useState<Settings>(getSettings());
|
const [settings, setSettings] = useState<Settings>(initialAppContext.settings);
|
||||||
const [theme, setTheme] = useState<Theme>(() => {
|
const [theme, setTheme] = useState<Theme>(() => {
|
||||||
return makeTheme(settings);
|
return makeTheme(settings);
|
||||||
});
|
});
|
||||||
|
@ -23,8 +23,10 @@ export interface UseFederationStoreType {
|
|||||||
addNewCoordinator: (alias: string, url: string) => void;
|
addNewCoordinator: (alias: string, url: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const initialFederation = new Federation('onion', new Settings(), '');
|
||||||
|
|
||||||
export const initialFederationContext: UseFederationStoreType = {
|
export const initialFederationContext: UseFederationStoreType = {
|
||||||
federation: new Federation('onion', new Settings(), ''),
|
federation: initialFederation,
|
||||||
coordinatorUpdatedAt: '',
|
coordinatorUpdatedAt: '',
|
||||||
federationUpdatedAt: '',
|
federationUpdatedAt: '',
|
||||||
addNewCoordinator: () => {},
|
addNewCoordinator: () => {},
|
||||||
@ -38,7 +40,7 @@ export const FederationContextProvider = ({
|
|||||||
const { settings, page, origin, hostUrl, open, torStatus, client, fav } =
|
const { settings, page, origin, hostUrl, open, torStatus, client, fav } =
|
||||||
useContext<UseAppStoreType>(AppContext);
|
useContext<UseAppStoreType>(AppContext);
|
||||||
const { setMaker, garage } = useContext<UseGarageStoreType>(GarageContext);
|
const { setMaker, garage } = useContext<UseGarageStoreType>(GarageContext);
|
||||||
const [federation] = useState(new Federation(origin, settings, hostUrl));
|
const [federation] = useState(initialFederationContext.federation);
|
||||||
const [coordinatorUpdatedAt, setCoordinatorUpdatedAt] = useState<string>(
|
const [coordinatorUpdatedAt, setCoordinatorUpdatedAt] = useState<string>(
|
||||||
new Date().toISOString(),
|
new Date().toISOString(),
|
||||||
);
|
);
|
||||||
@ -55,9 +57,7 @@ export const FederationContextProvider = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (client !== 'mobile' || torStatus === 'ON' || !settings.useProxy) {
|
if (client !== 'mobile' || torStatus === 'ON' || !settings.useProxy) {
|
||||||
void federation.updateUrl(origin, settings, hostUrl);
|
federation.setConnection(origin, settings, hostUrl, fav.coordinator);
|
||||||
void federation.loadLimits();
|
|
||||||
federation.setConnection(settings, fav.coordinator);
|
|
||||||
}
|
}
|
||||||
}, [settings.network, settings.useProxy, torStatus, settings.connection]);
|
}, [settings.network, settings.useProxy, torStatus, settings.connection]);
|
||||||
|
|
||||||
|
@ -141,7 +141,6 @@ export class Coordinator {
|
|||||||
this.testnetNodesPubkeys = value.testnetNodesPubkeys;
|
this.testnetNodesPubkeys = value.testnetNodesPubkeys;
|
||||||
this.nostrHexPubkey = value.nostrHexPubkey;
|
this.nostrHexPubkey = value.nostrHexPubkey;
|
||||||
this.url = '';
|
this.url = '';
|
||||||
this.basePath = '';
|
|
||||||
|
|
||||||
this.updateUrl(origin, settings, hostUrl);
|
this.updateUrl(origin, settings, hostUrl);
|
||||||
}
|
}
|
||||||
@ -164,7 +163,6 @@ export class Coordinator {
|
|||||||
public mainnetNodesPubkeys: string[] | undefined;
|
public mainnetNodesPubkeys: string[] | undefined;
|
||||||
public testnetNodesPubkeys: string[] | undefined;
|
public testnetNodesPubkeys: string[] | undefined;
|
||||||
public url: string;
|
public url: string;
|
||||||
public basePath: string;
|
|
||||||
public nostrHexPubkey: string;
|
public nostrHexPubkey: string;
|
||||||
|
|
||||||
// These properties are fetched from coordinator API
|
// These properties are fetched from coordinator API
|
||||||
@ -177,11 +175,9 @@ export class Coordinator {
|
|||||||
|
|
||||||
updateUrl = (origin: Origin, settings: Settings, hostUrl: string): void => {
|
updateUrl = (origin: Origin, settings: Settings, hostUrl: string): void => {
|
||||||
if (settings.selfhostedClient && this.shortAlias !== 'local') {
|
if (settings.selfhostedClient && this.shortAlias !== 'local') {
|
||||||
this.url = hostUrl;
|
this.url = `${hostUrl}/${settings.network}/${this.shortAlias}`;
|
||||||
this.basePath = `/${settings.network}/${this.shortAlias}`;
|
|
||||||
} else {
|
} else {
|
||||||
this.url = String(this[settings.network]?.[origin]);
|
this.url = String(this[settings.network]?.[origin]);
|
||||||
this.basePath = '';
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -200,7 +196,7 @@ export class Coordinator {
|
|||||||
this.book = {};
|
this.book = {};
|
||||||
|
|
||||||
apiClient
|
apiClient
|
||||||
.get(this.url, `${this.basePath}/api/book/`)
|
.get(this.url, `/api/book/`)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (!data?.not_found) {
|
if (!data?.not_found) {
|
||||||
this.book = (data as PublicOrder[]).reduce<Record<string, PublicOrder>>((book, order) => {
|
this.book = (data as PublicOrder[]).reduce<Record<string, PublicOrder>>((book, order) => {
|
||||||
@ -229,7 +225,7 @@ export class Coordinator {
|
|||||||
this.loadingLimits = true;
|
this.loadingLimits = true;
|
||||||
|
|
||||||
apiClient
|
apiClient
|
||||||
.get(this.url, `${this.basePath}/api/limits/`)
|
.get(this.url, `/api/limits/`)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (data !== null) {
|
if (data !== null) {
|
||||||
const newLimits = data as LimitList;
|
const newLimits = data as LimitList;
|
||||||
@ -258,7 +254,7 @@ export class Coordinator {
|
|||||||
this.loadingInfo = true;
|
this.loadingInfo = true;
|
||||||
|
|
||||||
apiClient
|
apiClient
|
||||||
.get(this.url, `${this.basePath}/api/info/`)
|
.get(this.url, `/api/info/`)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (data !== null) {
|
if (data !== null) {
|
||||||
this.info = data as Info;
|
this.info = data as Info;
|
||||||
@ -287,30 +283,9 @@ export class Coordinator {
|
|||||||
this.book = {};
|
this.book = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
getBaseUrl = (): string => {
|
getRelayUrl = (hostUrl: string): string => {
|
||||||
return this.url + this.basePath;
|
const protocol = hostUrl.includes('https') ? 'wss://' : 'ws://';
|
||||||
};
|
return this.url.replace(/^https?:\/\//, protocol) + '/relay/';
|
||||||
|
|
||||||
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/`;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,10 +62,10 @@ export class Federation {
|
|||||||
const tesnetHost = Object.values(this.coordinators).find((coor) => {
|
const tesnetHost = Object.values(this.coordinators).find((coor) => {
|
||||||
return Object.values(coor.testnet).includes(url);
|
return Object.values(coor.testnet).includes(url);
|
||||||
});
|
});
|
||||||
if (tesnetHost) settings.network = 'testnet';
|
this.network = settings.network;
|
||||||
|
if (tesnetHost) this.network = 'testnet';
|
||||||
this.connection = null;
|
this.connection = null;
|
||||||
|
this.roboPool = new RoboPool(settings);
|
||||||
this.roboPool = new RoboPool(settings, hostUrl, Object.values(this.coordinators));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private coordinators: Record<string, Coordinator>;
|
private coordinators: Record<string, Coordinator>;
|
||||||
@ -73,23 +73,38 @@ export class Federation {
|
|||||||
public book: Record<string, PublicOrder | undefined>;
|
public book: Record<string, PublicOrder | undefined>;
|
||||||
public loading: boolean;
|
public loading: boolean;
|
||||||
public connection: 'api' | 'nostr' | null;
|
public connection: 'api' | 'nostr' | null;
|
||||||
|
public network: 'testnet' | 'mainnet';
|
||||||
|
|
||||||
public hooks: Record<FederationHooks, Array<() => void>>;
|
public hooks: Record<FederationHooks, Array<() => void>>;
|
||||||
|
|
||||||
public roboPool: RoboPool;
|
public roboPool: RoboPool;
|
||||||
|
|
||||||
setConnection = (settings: Settings, coordinator: string): void => {
|
setConnection = (
|
||||||
|
origin: Origin,
|
||||||
|
settings: Settings,
|
||||||
|
hostUrl: string,
|
||||||
|
coordinator: string,
|
||||||
|
): void => {
|
||||||
this.connection = settings.connection;
|
this.connection = settings.connection;
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.book = {};
|
this.book = {};
|
||||||
this.exchange.loadingCache = this.roboPool.relays.length;
|
this.exchange.loadingCache = this.roboPool.relays.length;
|
||||||
|
this.network = settings.network;
|
||||||
|
|
||||||
|
const coordinators = Object.values(this.coordinators);
|
||||||
|
coordinators.forEach((c) => c.updateUrl(origin, settings, hostUrl));
|
||||||
|
this.roboPool.updateRelays(hostUrl, Object.values(this.coordinators));
|
||||||
|
|
||||||
|
void this.loadLimits();
|
||||||
|
|
||||||
if (this.connection === 'nostr') {
|
if (this.connection === 'nostr') {
|
||||||
this.roboPool.connect();
|
|
||||||
this.loadBookNostr(coordinator !== 'any');
|
this.loadBookNostr(coordinator !== 'any');
|
||||||
} else {
|
} else {
|
||||||
this.roboPool.close();
|
|
||||||
void this.loadBook();
|
void this.loadBook();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const federationUrls = Object.values(this.coordinators).map((c) => c.url);
|
||||||
|
systemClient.setCookie('federation', JSON.stringify(federationUrls));
|
||||||
};
|
};
|
||||||
|
|
||||||
refreshBookHosts: (robosatsOnly: boolean) => void = (robosatsOnly) => {
|
refreshBookHosts: (robosatsOnly: boolean) => void = (robosatsOnly) => {
|
||||||
@ -101,8 +116,10 @@ export class Federation {
|
|||||||
loadBookNostr = (robosatsOnly: boolean): void => {
|
loadBookNostr = (robosatsOnly: boolean): void => {
|
||||||
this.roboPool.subscribeBook(robosatsOnly, {
|
this.roboPool.subscribeBook(robosatsOnly, {
|
||||||
onevent: (event) => {
|
onevent: (event) => {
|
||||||
const { dTag, publicOrder } = eventToPublicOrder(event);
|
const { dTag, publicOrder, network } = eventToPublicOrder(event);
|
||||||
if (publicOrder) {
|
console.log(network);
|
||||||
|
console.log(this.network);
|
||||||
|
if (publicOrder && network == this.network) {
|
||||||
this.book[dTag] = publicOrder;
|
this.book[dTag] = publicOrder;
|
||||||
} else {
|
} else {
|
||||||
this.book[dTag] = undefined;
|
this.book[dTag] = undefined;
|
||||||
@ -160,20 +177,6 @@ export class Federation {
|
|||||||
this.triggerHook('onFederationUpdate');
|
this.triggerHook('onFederationUpdate');
|
||||||
};
|
};
|
||||||
|
|
||||||
updateUrl = async (origin: Origin, settings: Settings, hostUrl: string): Promise<void> => {
|
|
||||||
const federationUrls = {};
|
|
||||||
for (const coor of Object.values(this.coordinators)) {
|
|
||||||
const { url, basePath } = coor.getEndpoint(
|
|
||||||
settings.network,
|
|
||||||
origin,
|
|
||||||
settings.selfhostedClient,
|
|
||||||
hostUrl,
|
|
||||||
);
|
|
||||||
federationUrls[coor.shortAlias] = url + basePath;
|
|
||||||
}
|
|
||||||
systemClient.setCookie('federation', JSON.stringify(federationUrls));
|
|
||||||
};
|
|
||||||
|
|
||||||
loadInfo = async (): Promise<void> => {
|
loadInfo = async (): Promise<void> => {
|
||||||
this.exchange.info = {
|
this.exchange.info = {
|
||||||
num_public_buy_orders: 0,
|
num_public_buy_orders: 0,
|
||||||
|
@ -203,11 +203,10 @@ class Order {
|
|||||||
|
|
||||||
if (slot) {
|
if (slot) {
|
||||||
const coordinator = federation.getCoordinator(this.shortAlias);
|
const coordinator = federation.getCoordinator(this.shortAlias);
|
||||||
const { basePath, url } = coordinator;
|
|
||||||
const authHeaders = slot.getRobot()?.getAuthHeaders();
|
const authHeaders = slot.getRobot()?.getAuthHeaders();
|
||||||
if (!authHeaders) return this;
|
if (!authHeaders) return this;
|
||||||
const data = await apiClient
|
const data = await apiClient
|
||||||
.post(url + basePath, '/api/make/', body, authHeaders)
|
.post(coordinator.url, '/api/make/', body, authHeaders)
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
});
|
});
|
||||||
@ -234,9 +233,8 @@ class Order {
|
|||||||
|
|
||||||
if (slot) {
|
if (slot) {
|
||||||
const coordinator = federation.getCoordinator(this.shortAlias);
|
const coordinator = federation.getCoordinator(this.shortAlias);
|
||||||
const { basePath, url } = coordinator;
|
|
||||||
const data = await apiClient
|
const data = await apiClient
|
||||||
.post(url + basePath, `/api/order/?order_id=${Number(this.id)}`, action, {
|
.post(coordinator.url, `/api/order/?order_id=${Number(this.id)}`, action, {
|
||||||
tokenSHA256: slot?.getRobot()?.tokenSHA256 ?? '',
|
tokenSHA256: slot?.getRobot()?.tokenSHA256 ?? '',
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
@ -254,9 +252,8 @@ class Order {
|
|||||||
const coordinator = federation.getCoordinator(this.shortAlias);
|
const coordinator = federation.getCoordinator(this.shortAlias);
|
||||||
const authHeaders = slot.getRobot()?.getAuthHeaders();
|
const authHeaders = slot.getRobot()?.getAuthHeaders();
|
||||||
if (!authHeaders) return this;
|
if (!authHeaders) return this;
|
||||||
const { basePath, url } = coordinator;
|
|
||||||
const data = await apiClient
|
const data = await apiClient
|
||||||
.get(url + basePath, `/api/order/?order_id=${this.id}`, authHeaders)
|
.get(coordinator.url, `/api/order/?order_id=${this.id}`, authHeaders)
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
});
|
});
|
||||||
|
@ -55,7 +55,7 @@ class Robot {
|
|||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
|
||||||
await apiClient
|
await apiClient
|
||||||
.get(coordinator.url, `${coordinator.basePath}/api/robot/`, authHeaders)
|
.get(coordinator.url, '/api/robot/', authHeaders)
|
||||||
.then((data: object) => {
|
.then((data: object) => {
|
||||||
if (data?.bad_request) {
|
if (data?.bad_request) {
|
||||||
console.error(data?.bad_request);
|
console.error(data?.bad_request);
|
||||||
@ -99,7 +99,7 @@ class Robot {
|
|||||||
const data = await apiClient
|
const data = await apiClient
|
||||||
.post(
|
.post(
|
||||||
coordinator.url,
|
coordinator.url,
|
||||||
`${coordinator.basePath}/api/reward/`,
|
'/api/reward/',
|
||||||
{
|
{
|
||||||
invoice: signedInvoice,
|
invoice: signedInvoice,
|
||||||
},
|
},
|
||||||
@ -118,12 +118,7 @@ class Robot {
|
|||||||
|
|
||||||
const coordinator = federation.getCoordinator(this.shortAlias);
|
const coordinator = federation.getCoordinator(this.shortAlias);
|
||||||
await apiClient
|
await apiClient
|
||||||
.post(
|
.post(coordinator.url, '/api/stealth/', { wantsStealth }, { tokenSHA256: this.tokenSHA256 })
|
||||||
coordinator.url,
|
|
||||||
`${coordinator.basePath}/api/stealth/`,
|
|
||||||
{ wantsStealth },
|
|
||||||
{ tokenSHA256: this.tokenSHA256 },
|
|
||||||
)
|
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
});
|
});
|
||||||
@ -143,7 +138,7 @@ class Robot {
|
|||||||
};
|
};
|
||||||
|
|
||||||
apiClient
|
apiClient
|
||||||
.post(coordinator.url, `${coordinator.basePath}/api/review/`, body, {
|
.post(coordinator.url, '/api/review/', body, {
|
||||||
tokenSHA256: this.tokenSHA256,
|
tokenSHA256: this.tokenSHA256,
|
||||||
})
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
|
@ -10,21 +10,24 @@ interface RoboPoolEvents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class RoboPool {
|
class RoboPool {
|
||||||
constructor(settings: Settings, hostUrl: string, coordinators: Coordinator[]) {
|
constructor(settings: Settings) {
|
||||||
this.network = settings.network ?? 'mainnet';
|
this.network = settings.network ?? 'mainnet';
|
||||||
|
|
||||||
this.relays = [];
|
this.relays = [];
|
||||||
const federationRelays = coordinators.map((coord) =>
|
}
|
||||||
coord.getRelayUrl(settings.network, hostUrl, settings.selfhostedClient),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (settings.host) {
|
public relays: string[];
|
||||||
const protocol = hostUrl.includes('https') ? 'wss' : 'ws';
|
public network: string;
|
||||||
const hostNostr = `${protocol}://${settings.host.replace(/^https?:\/\//, '')}/relay/`;
|
|
||||||
if (federationRelays.includes(hostNostr)) {
|
public webSockets: Record<string, WebsocketConnection | null> = {};
|
||||||
this.relays.push(hostNostr);
|
private readonly messageHandlers: Array<(url: string, event: MessageEvent) => void> = [];
|
||||||
}
|
|
||||||
}
|
updateRelays = (hostUrl: string, coordinators: Coordinator[]) => {
|
||||||
|
this.close();
|
||||||
|
this.relays = [];
|
||||||
|
const federationRelays = coordinators.map((coord) => coord.getRelayUrl(hostUrl));
|
||||||
|
const hostRelay = federationRelays.find((relay) => relay.includes(hostUrl));
|
||||||
|
if (hostRelay) this.relays.push(hostRelay);
|
||||||
|
|
||||||
while (this.relays.length < 3) {
|
while (this.relays.length < 3) {
|
||||||
const randomRelay =
|
const randomRelay =
|
||||||
@ -33,13 +36,8 @@ class RoboPool {
|
|||||||
this.relays.push(randomRelay);
|
this.relays.push(randomRelay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
this.connect();
|
||||||
|
};
|
||||||
public relays: string[];
|
|
||||||
public network: string;
|
|
||||||
|
|
||||||
public webSockets: Record<string, WebsocketConnection | null> = {};
|
|
||||||
private readonly messageHandlers: Array<(url: string, event: MessageEvent) => void> = [];
|
|
||||||
|
|
||||||
connect = (relays: string[] = this.relays): void => {
|
connect = (relays: string[] = this.relays): void => {
|
||||||
relays.forEach((url: string) => {
|
relays.forEach((url: string) => {
|
||||||
|
@ -7,7 +7,9 @@ import thirdParties from '../../static/thirdparties.json';
|
|||||||
import currencyDict from '../../static/assets/currencies.json';
|
import currencyDict from '../../static/assets/currencies.json';
|
||||||
import defaultFederation from '../../static/federation.json';
|
import defaultFederation from '../../static/federation.json';
|
||||||
|
|
||||||
const eventToPublicOrder = (event: Event): { dTag: string; publicOrder: PublicOrder | null } => {
|
const eventToPublicOrder = (
|
||||||
|
event: Event,
|
||||||
|
): { dTag: string; publicOrder: PublicOrder | null; network: string } => {
|
||||||
const publicOrder: PublicOrder = {
|
const publicOrder: PublicOrder = {
|
||||||
id: 0,
|
id: 0,
|
||||||
coordinatorShortAlias: '',
|
coordinatorShortAlias: '',
|
||||||
@ -36,10 +38,12 @@ const eventToPublicOrder = (event: Event): { dTag: string; publicOrder: PublicOr
|
|||||||
|
|
||||||
const statusTag = event.tags.find((t) => t[0] === 's') ?? [];
|
const statusTag = event.tags.find((t) => t[0] === 's') ?? [];
|
||||||
const dTag = event.tags.find((t) => t[0] === 'd') ?? [];
|
const dTag = event.tags.find((t) => t[0] === 'd') ?? [];
|
||||||
|
const network = event.tags.find((t) => t[0] === 'network') ?? [];
|
||||||
const coordinator = [...Object.values(defaultFederation), ...Object.values(thirdParties)].find(
|
const coordinator = [...Object.values(defaultFederation), ...Object.values(thirdParties)].find(
|
||||||
(coord) => coord.nostrHexPubkey === event.pubkey,
|
(coord) => coord.nostrHexPubkey === event.pubkey,
|
||||||
);
|
);
|
||||||
if (!coordinator || statusTag[1] !== 'pending') return { dTag: dTag[1], publicOrder: null };
|
if (!coordinator || statusTag[1] !== 'pending')
|
||||||
|
return { dTag: dTag[1], publicOrder: null, network: network[1] };
|
||||||
|
|
||||||
publicOrder.coordinatorShortAlias = coordinator?.shortAlias;
|
publicOrder.coordinatorShortAlias = coordinator?.shortAlias;
|
||||||
publicOrder.federated = coordinator?.federated ?? false;
|
publicOrder.federated = coordinator?.federated ?? false;
|
||||||
@ -104,7 +108,7 @@ const eventToPublicOrder = (event: Event): { dTag: string; publicOrder: PublicOr
|
|||||||
if (!publicOrder.maker_hash_id)
|
if (!publicOrder.maker_hash_id)
|
||||||
publicOrder.maker_hash_id = `${publicOrder.id}${coordinator?.shortAlias}`;
|
publicOrder.maker_hash_id = `${publicOrder.id}${coordinator?.shortAlias}`;
|
||||||
|
|
||||||
return { dTag: dTag[1], publicOrder };
|
return { dTag: dTag[1], publicOrder, network: network[1] };
|
||||||
};
|
};
|
||||||
|
|
||||||
export const verifyCoordinatorToken: (event: Event) => boolean = (event) => {
|
export const verifyCoordinatorToken: (event: Event) => boolean = (event) => {
|
||||||
|
Reference in New Issue
Block a user