mirror of
https://github.com/RoboSats/robosats.git
synced 2025-02-07 13:59:06 +00:00
Some fixes
This commit is contained in:
parent
a92ca62bb1
commit
06fc2e8bd7
@ -13,11 +13,10 @@ const Routes: React.FC = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window.addEventListener('navigateToPage', (event) => {
|
window.addEventListener('navigateToPage', (event) => {
|
||||||
console.log('navigateToPage', JSON.stringify(event));
|
|
||||||
const orderId: string = event?.detail?.order_id;
|
const orderId: string = event?.detail?.order_id;
|
||||||
const coordinator: string = event?.detail?.coordinator;
|
const coordinator: string = event?.detail?.coordinator;
|
||||||
if (orderId && coordinator) {
|
if (orderId && coordinator) {
|
||||||
const slot = garage.getSlotByOrder(coordinator, orderId);
|
const slot = garage.getSlotByOrder(coordinator, parseInt(orderId, 10));
|
||||||
if (slot?.token) {
|
if (slot?.token) {
|
||||||
garage.setCurrentSlot(slot?.token);
|
garage.setCurrentSlot(slot?.token);
|
||||||
navigate(`/order/${coordinator}/${orderId}`);
|
navigate(`/order/${coordinator}/${orderId}`);
|
||||||
|
@ -319,12 +319,8 @@ const TakeButton = ({
|
|||||||
|
|
||||||
setLoadingTake(true);
|
setLoadingTake(true);
|
||||||
|
|
||||||
currentOrder
|
slot
|
||||||
.submitAction(federation, slot, {
|
.takeOrder(federation, currentOrder, takeAmount)
|
||||||
action: 'take',
|
|
||||||
amount:
|
|
||||||
currentOrder?.currency === 1000 ? Number(takeAmount) / 100000000 : Number(takeAmount),
|
|
||||||
})
|
|
||||||
.then((order) => {
|
.then((order) => {
|
||||||
if (order?.bad_request !== undefined) {
|
if (order?.bad_request !== undefined) {
|
||||||
setBadRequest(order.bad_request);
|
setBadRequest(order.bad_request);
|
||||||
|
@ -174,8 +174,8 @@ const OrderDetails = ({
|
|||||||
|
|
||||||
const isBuyer = (order.type === 0 && order.is_maker) || (order.type === 1 && !order.is_maker);
|
const isBuyer = (order.type === 0 && order.is_maker) || (order.type === 1 && !order.is_maker);
|
||||||
const tradeFee = order.is_maker
|
const tradeFee = order.is_maker
|
||||||
? coordinator.info?.maker_fee ?? 0
|
? (coordinator.info?.maker_fee ?? 0)
|
||||||
: coordinator.info?.taker_fee ?? 0;
|
: (coordinator.info?.taker_fee ?? 0);
|
||||||
const defaultRoutingBudget = 0.001;
|
const defaultRoutingBudget = 0.001;
|
||||||
const btc_now = order.satoshis_now / 100000000;
|
const btc_now = order.satoshis_now / 100000000;
|
||||||
const rate = Number(order.max_amount ?? order.amount) / btc_now;
|
const rate = Number(order.max_amount ?? order.amount) / btc_now;
|
||||||
|
@ -76,7 +76,11 @@ const makeTheme = function (settings: Settings): Theme {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getHostUrl = (network = 'mainnet'): string => {
|
const getHostUrl = (network = 'mainnet'): string => {
|
||||||
let host = defaultFederation.exp[network].onion;
|
const randomAlias =
|
||||||
|
Object.keys(defaultFederation)[
|
||||||
|
Math.floor(Math.random() * Object.keys(defaultFederation).length)
|
||||||
|
];
|
||||||
|
let host = defaultFederation[randomAlias][network].onion;
|
||||||
let protocol = 'http:';
|
let protocol = 'http:';
|
||||||
if (window.NativeRobosats === undefined) {
|
if (window.NativeRobosats === undefined) {
|
||||||
host = getHost();
|
host = getHost();
|
||||||
|
@ -8,7 +8,7 @@ import React, {
|
|||||||
type ReactNode,
|
type ReactNode,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
import { type Order, Federation, Settings } from '../models';
|
import { Federation, Settings } from '../models';
|
||||||
|
|
||||||
import { federationLottery } from '../utils';
|
import { federationLottery } from '../utils';
|
||||||
|
|
||||||
@ -28,10 +28,6 @@ export interface FederationContextProviderProps {
|
|||||||
export interface UseFederationStoreType {
|
export interface UseFederationStoreType {
|
||||||
federation: Federation;
|
federation: Federation;
|
||||||
sortedCoordinators: string[];
|
sortedCoordinators: string[];
|
||||||
setDelay: Dispatch<SetStateAction<number>>;
|
|
||||||
currentOrderId: CurrentOrderIdProps;
|
|
||||||
setCurrentOrderId: Dispatch<SetStateAction<CurrentOrderIdProps>>;
|
|
||||||
currentOrder: Order | null;
|
|
||||||
coordinatorUpdatedAt: string;
|
coordinatorUpdatedAt: string;
|
||||||
federationUpdatedAt: string;
|
federationUpdatedAt: string;
|
||||||
addNewCoordinator: (alias: string, url: string) => void;
|
addNewCoordinator: (alias: string, url: string) => void;
|
||||||
@ -40,10 +36,6 @@ export interface UseFederationStoreType {
|
|||||||
export const initialFederationContext: UseFederationStoreType = {
|
export const initialFederationContext: UseFederationStoreType = {
|
||||||
federation: new Federation('onion', new Settings(), ''),
|
federation: new Federation('onion', new Settings(), ''),
|
||||||
sortedCoordinators: [],
|
sortedCoordinators: [],
|
||||||
setDelay: () => {},
|
|
||||||
currentOrderId: { id: null, shortAlias: null },
|
|
||||||
setCurrentOrderId: () => {},
|
|
||||||
currentOrder: null,
|
|
||||||
coordinatorUpdatedAt: '',
|
coordinatorUpdatedAt: '',
|
||||||
federationUpdatedAt: '',
|
federationUpdatedAt: '',
|
||||||
addNewCoordinator: () => {},
|
addNewCoordinator: () => {},
|
||||||
@ -56,24 +48,13 @@ export const FederationContextProvider = ({
|
|||||||
}: FederationContextProviderProps): JSX.Element => {
|
}: FederationContextProviderProps): JSX.Element => {
|
||||||
const { settings, page, origin, hostUrl, open, torStatus } =
|
const { settings, page, origin, hostUrl, open, torStatus } =
|
||||||
useContext<UseAppStoreType>(AppContext);
|
useContext<UseAppStoreType>(AppContext);
|
||||||
const { setMaker, garage, setBadOrder } = useContext<UseGarageStoreType>(GarageContext);
|
const { setMaker, garage } = useContext<UseGarageStoreType>(GarageContext);
|
||||||
const [federation] = useState(new Federation(origin, settings, hostUrl));
|
const [federation] = useState(new Federation(origin, settings, hostUrl));
|
||||||
const [sortedCoordinators, setSortedCoordinators] = useState(federationLottery(federation));
|
const [sortedCoordinators, setSortedCoordinators] = useState(federationLottery(federation));
|
||||||
const [coordinatorUpdatedAt, setCoordinatorUpdatedAt] = useState<string>(
|
const [coordinatorUpdatedAt, setCoordinatorUpdatedAt] = useState<string>(
|
||||||
new Date().toISOString(),
|
new Date().toISOString(),
|
||||||
);
|
);
|
||||||
const [federationUpdatedAt, setFederationUpdatedAt] = useState<string>(new Date().toISOString());
|
const [federationUpdatedAt, setFederationUpdatedAt] = useState<string>(new Date().toISOString());
|
||||||
const [currentOrderId, setCurrentOrderId] = useState<CurrentOrderIdProps>(
|
|
||||||
initialFederationContext.currentOrderId,
|
|
||||||
);
|
|
||||||
const [currentOrder, setCurrentOrder] = useState<Order | null>(
|
|
||||||
initialFederationContext.currentOrder,
|
|
||||||
);
|
|
||||||
|
|
||||||
const [delay, setDelay] = useState<number>(defaultDelay);
|
|
||||||
const [timer, setTimer] = useState<NodeJS.Timer | undefined>(() =>
|
|
||||||
setInterval(() => null, delay),
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setMaker((maker) => {
|
setMaker((maker) => {
|
||||||
@ -82,65 +63,15 @@ export const FederationContextProvider = ({
|
|||||||
federation.registerHook('onFederationUpdate', () => {
|
federation.registerHook('onFederationUpdate', () => {
|
||||||
setFederationUpdatedAt(new Date().toISOString());
|
setFederationUpdatedAt(new Date().toISOString());
|
||||||
});
|
});
|
||||||
federation.registerHook('onCoordinatorUpdate', () => {
|
|
||||||
setCoordinatorUpdatedAt(new Date().toISOString());
|
|
||||||
});
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (window.NativeRobosats === undefined || torStatus === 'ON' || !settings.useProxy) {
|
if (window.NativeRobosats === undefined || torStatus === 'ON' || !settings.useProxy) {
|
||||||
void federation.updateUrl(origin, settings, hostUrl);
|
void federation.updateUrl(origin, settings, hostUrl);
|
||||||
void federation.update();
|
void federation.update();
|
||||||
|
|
||||||
const token = garage.getSlot()?.getRobot()?.token;
|
|
||||||
if (token) void federation.fetchRobot(garage, token);
|
|
||||||
}
|
}
|
||||||
}, [settings.network, settings.useProxy, torStatus]);
|
}, [settings.network, settings.useProxy, torStatus]);
|
||||||
|
|
||||||
const onOrderReceived = (order: Order): void => {
|
|
||||||
let newDelay = defaultDelay;
|
|
||||||
if (order?.bad_request) {
|
|
||||||
newDelay = 99999999;
|
|
||||||
setBadOrder(order.bad_request);
|
|
||||||
garage.updateOrder(null);
|
|
||||||
setCurrentOrder(null);
|
|
||||||
}
|
|
||||||
if (order?.id) {
|
|
||||||
newDelay =
|
|
||||||
order.status >= 0 && order.status <= 18
|
|
||||||
? page === 'order'
|
|
||||||
? statusToDelay[order.status]
|
|
||||||
: statusToDelay[order.status] * 5 // If user is not looking at "order" tab, refresh less often.
|
|
||||||
: 99999999;
|
|
||||||
garage.updateOrder(order);
|
|
||||||
setCurrentOrder(order);
|
|
||||||
setBadOrder(undefined);
|
|
||||||
}
|
|
||||||
clearInterval(timer);
|
|
||||||
console.log('New Delay:', newDelay);
|
|
||||||
setDelay(newDelay);
|
|
||||||
setTimer(setTimeout(fetchCurrentOrder, newDelay));
|
|
||||||
};
|
|
||||||
|
|
||||||
const fetchCurrentOrder: () => void = () => {
|
|
||||||
const slot = garage?.getSlot();
|
|
||||||
const robot = slot?.getRobot();
|
|
||||||
if (robot && slot?.token && currentOrderId.id && currentOrderId.shortAlias) {
|
|
||||||
const coordinator = federation.getCoordinator(currentOrderId.shortAlias);
|
|
||||||
void coordinator?.fetchOrder(currentOrderId.id, robot, slot?.token).then((order) => {
|
|
||||||
onOrderReceived(order as Order);
|
|
||||||
});
|
|
||||||
} else if (slot?.token && slot?.activeShortAlias && robot?.activeOrderId) {
|
|
||||||
const coordinator = federation.getCoordinator(slot.activeShortAlias);
|
|
||||||
void coordinator?.fetchOrder(robot.activeOrderId, robot, slot.token).then((order) => {
|
|
||||||
onOrderReceived(order as Order);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
clearInterval(timer);
|
|
||||||
setTimer(setTimeout(fetchCurrentOrder, defaultDelay));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const addNewCoordinator: (alias: string, url: string) => void = (alias, url) => {
|
const addNewCoordinator: (alias: string, url: string) => void = (alias, url) => {
|
||||||
if (!federation.coordinators[alias]) {
|
if (!federation.coordinators[alias]) {
|
||||||
const attributes: Record<any, any> = {
|
const attributes: Record<any, any> = {
|
||||||
@ -164,24 +95,12 @@ export const FederationContextProvider = ({
|
|||||||
newCoordinator.update(() => {
|
newCoordinator.update(() => {
|
||||||
setCoordinatorUpdatedAt(new Date().toISOString());
|
setCoordinatorUpdatedAt(new Date().toISOString());
|
||||||
});
|
});
|
||||||
garage.syncCoordinator(newCoordinator);
|
garage.syncCoordinator(federation, alias);
|
||||||
setSortedCoordinators(federationLottery(federation));
|
setSortedCoordinators(federationLottery(federation));
|
||||||
setFederationUpdatedAt(new Date().toISOString());
|
setFederationUpdatedAt(new Date().toISOString());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (currentOrderId.id && currentOrderId.shortAlias) {
|
|
||||||
setCurrentOrder(null);
|
|
||||||
setBadOrder(undefined);
|
|
||||||
clearInterval(timer);
|
|
||||||
fetchCurrentOrder();
|
|
||||||
}
|
|
||||||
return () => {
|
|
||||||
clearInterval(timer);
|
|
||||||
};
|
|
||||||
}, [currentOrderId]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (page === 'offers') void federation.updateBook();
|
if (page === 'offers') void federation.updateBook();
|
||||||
}, [page]);
|
}, [page]);
|
||||||
@ -191,7 +110,7 @@ export const FederationContextProvider = ({
|
|||||||
const slot = garage.getSlot();
|
const slot = garage.getSlot();
|
||||||
|
|
||||||
if (open.profile && slot?.hashId && slot?.token) {
|
if (open.profile && slot?.hashId && slot?.token) {
|
||||||
void federation.fetchRobot(garage, slot?.token); // refresh/update existing robot
|
void garage.fetchRobot(federation, slot?.token); // refresh/update existing robot
|
||||||
}
|
}
|
||||||
}, [open.profile]);
|
}, [open.profile]);
|
||||||
|
|
||||||
@ -200,10 +119,6 @@ export const FederationContextProvider = ({
|
|||||||
value={{
|
value={{
|
||||||
federation,
|
federation,
|
||||||
sortedCoordinators,
|
sortedCoordinators,
|
||||||
currentOrderId,
|
|
||||||
setCurrentOrderId,
|
|
||||||
currentOrder,
|
|
||||||
setDelay,
|
|
||||||
coordinatorUpdatedAt,
|
coordinatorUpdatedAt,
|
||||||
federationUpdatedAt,
|
federationUpdatedAt,
|
||||||
addNewCoordinator,
|
addNewCoordinator,
|
||||||
|
@ -79,7 +79,7 @@ class Garage {
|
|||||||
// Slots
|
// Slots
|
||||||
getSlot: (token?: string) => Slot | null = (token) => {
|
getSlot: (token?: string) => Slot | null = (token) => {
|
||||||
const currentToken = token ?? this.currentSlot;
|
const currentToken = token ?? this.currentSlot;
|
||||||
return currentToken ? this.slots[currentToken] ?? null : null;
|
return currentToken ? (this.slots[currentToken] ?? null) : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
deleteSlot: (token?: string) => void = (token) => {
|
deleteSlot: (token?: string) => void = (token) => {
|
||||||
@ -100,7 +100,7 @@ class Garage {
|
|||||||
if (attributes) {
|
if (attributes) {
|
||||||
if (attributes.copiedToken !== undefined) slot?.setCopiedToken(attributes.copiedToken);
|
if (attributes.copiedToken !== undefined) slot?.setCopiedToken(attributes.copiedToken);
|
||||||
this.save();
|
this.save();
|
||||||
this.triggerHook('onRobotUpdate');
|
this.triggerHook('onSlotUpdate');
|
||||||
}
|
}
|
||||||
return slot;
|
return slot;
|
||||||
};
|
};
|
||||||
@ -108,7 +108,7 @@ class Garage {
|
|||||||
setCurrentSlot: (currentSlot: string) => void = (currentSlot) => {
|
setCurrentSlot: (currentSlot: string) => void = (currentSlot) => {
|
||||||
this.currentSlot = currentSlot;
|
this.currentSlot = currentSlot;
|
||||||
this.save();
|
this.save();
|
||||||
this.triggerHook('onRobotUpdate');
|
this.triggerHook('onSlotUpdate');
|
||||||
};
|
};
|
||||||
|
|
||||||
getSlotByOrder: (coordinator: string, orderID: number) => Slot | null = (
|
getSlotByOrder: (coordinator: string, orderID: number) => Slot | null = (
|
||||||
@ -118,7 +118,7 @@ class Garage {
|
|||||||
return (
|
return (
|
||||||
Object.values(this.slots).find((slot) => {
|
Object.values(this.slots).find((slot) => {
|
||||||
const robot = slot.getRobot(coordinator);
|
const robot = slot.getRobot(coordinator);
|
||||||
return slot.activeShortAlias === coordinator && robot?.activeOrderId === orderID;
|
return slot.activeOrder?.shortAlias === coordinator && robot?.activeOrderId === orderID;
|
||||||
}) ?? null
|
}) ?? null
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import defaultFederation from '../../static/federation.json';
|
||||||
|
|
||||||
export interface Maker {
|
export interface Maker {
|
||||||
advancedOptions: boolean;
|
advancedOptions: boolean;
|
||||||
coordinator: string;
|
coordinator: string;
|
||||||
@ -23,7 +25,10 @@ export interface Maker {
|
|||||||
|
|
||||||
export const defaultMaker: Maker = {
|
export const defaultMaker: Maker = {
|
||||||
advancedOptions: false,
|
advancedOptions: false,
|
||||||
coordinator: 'exp',
|
coordinator:
|
||||||
|
Object.keys(defaultFederation)[
|
||||||
|
Math.floor(Math.random() * Object.keys(defaultFederation).length)
|
||||||
|
] ?? '',
|
||||||
isExplicit: false,
|
isExplicit: false,
|
||||||
amount: '',
|
amount: '',
|
||||||
paymentMethods: [],
|
paymentMethods: [],
|
||||||
@ -40,6 +45,8 @@ export const defaultMaker: Maker = {
|
|||||||
maxAmount: '',
|
maxAmount: '',
|
||||||
badPremiumText: '',
|
badPremiumText: '',
|
||||||
badSatoshisText: '',
|
badSatoshisText: '',
|
||||||
|
latitude: 0,
|
||||||
|
longitude: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Maker;
|
export default Maker;
|
||||||
|
@ -214,6 +214,17 @@ class Order {
|
|||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
take: (federation: Federation, slot: Slot, takeAmount: string) => Promise<this> = async (
|
||||||
|
federation,
|
||||||
|
slot,
|
||||||
|
takeAmount,
|
||||||
|
) => {
|
||||||
|
return this.submitAction(federation, slot, {
|
||||||
|
action: 'take',
|
||||||
|
amount: this?.currency === 1000 ? Number(takeAmount) / 100000000 : Number(takeAmount),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
submitAction: (federation: Federation, slot: Slot, action: SubmitActionProps) => Promise<this> =
|
submitAction: (federation: Federation, slot: Slot, action: SubmitActionProps) => Promise<this> =
|
||||||
async (federation, slot, action) => {
|
async (federation, slot, action) => {
|
||||||
if (this.id < 1) return this;
|
if (this.id < 1) return this;
|
||||||
|
@ -111,6 +111,12 @@ class Slot {
|
|||||||
this.updateSlotFromOrder(this.activeOrder);
|
this.updateSlotFromOrder(this.activeOrder);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
takeOrder = async (federation: Federation, order: Order, takeAmount: string): Promise<Order> => {
|
||||||
|
await order.take(federation, this, takeAmount);
|
||||||
|
this.updateSlotFromOrder(order);
|
||||||
|
return order;
|
||||||
|
};
|
||||||
|
|
||||||
makeOrder = async (federation: Federation, attributes: object): Promise<Order> => {
|
makeOrder = async (federation: Federation, attributes: object): Promise<Order> => {
|
||||||
const order = new Order(attributes);
|
const order = new Order(attributes);
|
||||||
await order.make(federation, this);
|
await order.make(federation, this);
|
||||||
@ -124,6 +130,7 @@ class Slot {
|
|||||||
if (newOrder) {
|
if (newOrder) {
|
||||||
// FIXME: API responses with bad_request should include also order's status
|
// FIXME: API responses with bad_request should include also order's status
|
||||||
if (newOrder?.bad_request?.includes('expired')) newOrder.status = 5;
|
if (newOrder?.bad_request?.includes('expired')) newOrder.status = 5;
|
||||||
|
if (newOrder?.bad_request?.includes('collaborativelly')) newOrder.status = 12;
|
||||||
if (
|
if (
|
||||||
newOrder.id === this.activeOrder?.id &&
|
newOrder.id === this.activeOrder?.id &&
|
||||||
newOrder.shortAlias === this.activeOrder?.shortAlias
|
newOrder.shortAlias === this.activeOrder?.shortAlias
|
||||||
|
@ -1,47 +1,4 @@
|
|||||||
{
|
{
|
||||||
"exp": {
|
|
||||||
"longAlias": "Experimental",
|
|
||||||
"shortAlias": "exp",
|
|
||||||
"description": "RoboSats node for development and experimentation. This is the original RoboSats coordinator operated by the RoboSats devs since 2022.",
|
|
||||||
"motto": "Original Robohost. P2P FTW!",
|
|
||||||
"color": "#1976d2",
|
|
||||||
"established": "2022-03-01",
|
|
||||||
"contact": {
|
|
||||||
"email": "robosats@protonmail.com",
|
|
||||||
"telegram": "robosats",
|
|
||||||
"twitter": "robosats",
|
|
||||||
"reddit": "r/robosats",
|
|
||||||
"matrix": "#robosats:matrix.org",
|
|
||||||
"website": "https://learn.robosats.com",
|
|
||||||
"nostr": "npub1p2psats79rypr8lpnl9t5qdekfp700x660qsgw284xvq4s09lqrqqk3m82",
|
|
||||||
"pgp": "/static/federation/pgp/B4AB5F19113D4125DDF217739C4585B561315571.asc",
|
|
||||||
"fingerprint": "B4AB5F19113D4125DDF217739C4585B561315571"
|
|
||||||
},
|
|
||||||
"badges": {
|
|
||||||
"isFounder": true,
|
|
||||||
"donatesToDevFund": 20,
|
|
||||||
"hasGoodOpSec": true,
|
|
||||||
"robotsLove": true,
|
|
||||||
"hasLargeLimits": true
|
|
||||||
},
|
|
||||||
"policies": {
|
|
||||||
"Experimental": "Experimental coordinator used for development. Use at your own risk.",
|
|
||||||
"Dispute Policy": "Evidence in Disputes: In the event of a dispute, users will be asked to provide transaction-related evidence. This could include transaction IDs, screenshots of payment confirmations, or other pertinent transaction records. Personal information or unrelated transaction details should be redacted to maintain privacy.",
|
|
||||||
"Non eligible countries": "USA citizens and residents are not allowed to use the Experimental coordinator. F2F transactions are explicitly blocked at creation time for US locations. If a US citizen or resident violates this rule and is found out to be using the Experimental coordinator during a dispute process, they will be denied further service and the dispute mediation will be terminated."
|
|
||||||
},
|
|
||||||
"mainnet": {
|
|
||||||
"onion": "http://robosats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion",
|
|
||||||
"clearnet": "https://unsafe.robosats.com",
|
|
||||||
"i2p": "http://r7r4sckft6ptmk4r2jajiuqbowqyxiwsle4iyg4fijtoordc6z7a.b32.i2p"
|
|
||||||
},
|
|
||||||
"testnet": {
|
|
||||||
"onion": "http://robotestagw3dcxmd66r4rgksb4nmmr43fh77bzn2ia2eucduyeafnyd.onion",
|
|
||||||
"clearnet": "https://unsafe.testnet.robosats.com",
|
|
||||||
"i2p": ""
|
|
||||||
},
|
|
||||||
"mainnetNodesPubkeys": ["0282eb467bc073833a039940392592bf10cf338a830ba4e392c1667d7697654c7e"],
|
|
||||||
"testnetNodesPubkeys": ["03ecb271b3e2e36f2b91c92c65bab665e5165f8cdfdada1b5f46cfdd3248c87fd6"]
|
|
||||||
},
|
|
||||||
"temple": {
|
"temple": {
|
||||||
"longAlias": "Temple of Sats",
|
"longAlias": "Temple of Sats",
|
||||||
"shortAlias": "temple",
|
"shortAlias": "temple",
|
||||||
|
Loading…
Reference in New Issue
Block a user