mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-12-18 10:02:45 -05:00
feat(defaults, gui): add bluewallet and cakewallet electrum servers (#686)
* feat(defaults, gui): add bluewallet and cakewallet electrum servers * progress * fix circular dependency * detect import cycles * add changelog entry * move DEFAULT_RENDEZVOUS_POINTS into defaults.ts * move defaults.rs and types.ts one level higher * rename * collapse PRESET_RENDEZVOUS_POINTS and DEFAULT_RENDEZVOUS_POINTS
This commit is contained in:
parent
294b9985cf
commit
27d81aad1e
15 changed files with 510 additions and 100 deletions
|
|
@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
- GUI + SWAP + ASB: Reduce the confirmations required to spend a Monero transaction from 22 to 15. We believe the risks of re-orgs is low again and this is safe to do. This may increase the chances of swap being successful and will reduce the time a swap takes.
|
||||
- GUI: Fix an issue where we a manual resume of a swap would be necessary if we failed to fetch certain Bitcoin transactions due to network issues.
|
||||
- GUI: Remove the following default Electrum servers: `tcp://electrum.blockstream.info:50001`, `tcp://electrum.coinucopia.io:50001`, `tcp://se-mma-crypto-payments-001.mullvad.net:50001`, `tcp://electrum2.bluewallet.io:50777` due to them being unreliable. Add the following new default Electrum servers: `tcp://electrum1.bluewallet.io:50001`, `tcp://electrum2.bluewallet.io:50001`, `tcp://electrum3.bluewallet.io:50001`, `ssl://btc-electrum.cakewallet.com:50002`, `tcp://bitcoin.aranguren.org:50001`.
|
||||
|
||||
## [3.2.9] - 2025-11-05
|
||||
|
||||
|
|
|
|||
212
dev-scripts/health_check_default_electrum_servers.py
Normal file
212
dev-scripts/health_check_default_electrum_servers.py
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
#!/usr/bin/env python3
|
||||
# /// script
|
||||
# requires-python = ">=3.11"
|
||||
# dependencies = []
|
||||
# ///
|
||||
|
||||
"""
|
||||
Check electrum server availability.
|
||||
Usage: uv run check_electrum_servers.py
|
||||
"""
|
||||
|
||||
import json
|
||||
import re
|
||||
import socket
|
||||
import ssl
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from urllib.parse import urlparse
|
||||
from typing import List, Tuple
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
|
||||
|
||||
def extract_servers_from_rust(file_path: Path) -> List[str]:
|
||||
"""Extract electrum server URLs from Rust defaults.rs file."""
|
||||
servers = []
|
||||
content = file_path.read_text()
|
||||
|
||||
# Find all Url::parse() calls
|
||||
pattern = r'Url::parse\("([^"]+)"\)'
|
||||
matches = re.findall(pattern, content)
|
||||
servers.extend(matches)
|
||||
|
||||
return servers
|
||||
|
||||
|
||||
def extract_servers_from_typescript(file_path: Path) -> List[str]:
|
||||
"""Extract electrum server URLs from TypeScript defaults.ts file."""
|
||||
servers = []
|
||||
content = file_path.read_text()
|
||||
|
||||
# Find all server strings in the arrays
|
||||
pattern = r'"((?:tcp|ssl)://[^"]+)"'
|
||||
matches = re.findall(pattern, content)
|
||||
servers.extend(matches)
|
||||
|
||||
return servers
|
||||
|
||||
|
||||
def check_tcp_server(host: str, port: int, timeout: int = 2) -> Tuple[bool, str]:
|
||||
"""Check TCP electrum server."""
|
||||
request = json.dumps({"id": 1, "method": "blockchain.headers.subscribe", "params": []}) + "\n"
|
||||
|
||||
try:
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
|
||||
sock.settimeout(timeout)
|
||||
sock.connect((host, port))
|
||||
sock.sendall(request.encode())
|
||||
|
||||
response = b""
|
||||
while True:
|
||||
chunk = sock.recv(4096)
|
||||
if not chunk:
|
||||
break
|
||||
response += chunk
|
||||
if b"\n" in response:
|
||||
break
|
||||
|
||||
response_str = response.decode().strip()
|
||||
if response_str:
|
||||
data = json.loads(response_str)
|
||||
if 'result' in data or 'error' in data:
|
||||
return True, "OK"
|
||||
|
||||
return False, "No valid response"
|
||||
except socket.timeout:
|
||||
return False, "Timeout"
|
||||
except ConnectionRefusedError:
|
||||
return False, "Connection refused"
|
||||
except Exception as e:
|
||||
return False, str(e)
|
||||
|
||||
|
||||
def check_ssl_server(host: str, port: int, timeout: int = 2) -> Tuple[bool, str]:
|
||||
"""Check SSL/TLS electrum server."""
|
||||
request = json.dumps({"id": 1, "method": "blockchain.headers.subscribe", "params": []}) + "\n"
|
||||
|
||||
try:
|
||||
context = ssl.create_default_context()
|
||||
# Don't verify certificates for testing purposes
|
||||
context.check_hostname = False
|
||||
context.verify_mode = ssl.CERT_NONE
|
||||
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
|
||||
sock.settimeout(timeout)
|
||||
with context.wrap_socket(sock, server_hostname=host) as ssock:
|
||||
ssock.connect((host, port))
|
||||
ssock.sendall(request.encode())
|
||||
|
||||
response = b""
|
||||
while True:
|
||||
chunk = ssock.recv(4096)
|
||||
if not chunk:
|
||||
break
|
||||
response += chunk
|
||||
if b"\n" in response:
|
||||
break
|
||||
|
||||
response_str = response.decode().strip()
|
||||
if response_str:
|
||||
data = json.loads(response_str)
|
||||
if 'result' in data or 'error' in data:
|
||||
return True, "OK"
|
||||
|
||||
return False, "No valid response"
|
||||
except socket.timeout:
|
||||
return False, "Timeout"
|
||||
except ConnectionRefusedError:
|
||||
return False, "Connection refused"
|
||||
except ssl.SSLError as e:
|
||||
return False, f"SSL error: {str(e)}"
|
||||
except Exception as e:
|
||||
return False, str(e)
|
||||
|
||||
|
||||
def check_server(url: str) -> Tuple[str, bool, str]:
|
||||
"""Check a single electrum server."""
|
||||
parsed = urlparse(url)
|
||||
protocol = parsed.scheme
|
||||
host = parsed.hostname
|
||||
port = parsed.port
|
||||
|
||||
if not host or not port:
|
||||
return url, False, "Invalid URL format"
|
||||
|
||||
if protocol == "tcp":
|
||||
success, message = check_tcp_server(host, port)
|
||||
elif protocol == "ssl":
|
||||
success, message = check_ssl_server(host, port)
|
||||
else:
|
||||
return url, False, f"Unknown protocol: {protocol}"
|
||||
|
||||
return url, success, message
|
||||
|
||||
|
||||
def main():
|
||||
# Find the files
|
||||
base_dir = Path(__file__).parent
|
||||
rust_file = base_dir / "swap-env" / "src" / "defaults.rs"
|
||||
ts_file = base_dir / "src-gui" / "src" / "store" / "features" / "defaults.ts"
|
||||
|
||||
if not rust_file.exists():
|
||||
print(f"❌ Rust defaults file not found: {rust_file}")
|
||||
sys.exit(1)
|
||||
|
||||
if not ts_file.exists():
|
||||
print(f"❌ TypeScript defaults file not found: {ts_file}")
|
||||
sys.exit(1)
|
||||
|
||||
# Extract servers
|
||||
print("📋 Extracting server URLs...")
|
||||
rust_servers = extract_servers_from_rust(rust_file)
|
||||
ts_servers = extract_servers_from_typescript(ts_file)
|
||||
|
||||
# Combine and deduplicate
|
||||
all_servers = list(set(rust_servers + ts_servers))
|
||||
all_servers.sort()
|
||||
|
||||
print(f"\n📊 Found {len(all_servers)} unique servers\n")
|
||||
|
||||
# Check servers in parallel
|
||||
print("🔍 Checking servers (this may take a minute)...\n")
|
||||
|
||||
working = []
|
||||
broken = []
|
||||
|
||||
with ThreadPoolExecutor(max_workers=10) as executor:
|
||||
futures = {executor.submit(check_server, url): url for url in all_servers}
|
||||
|
||||
for future in as_completed(futures):
|
||||
url, success, message = future.result()
|
||||
|
||||
status = "✅" if success else "❌"
|
||||
print(f"{status} {url:60s} {message}")
|
||||
|
||||
if success:
|
||||
working.append(url)
|
||||
else:
|
||||
broken.append((url, message))
|
||||
|
||||
# Summary
|
||||
print("\n" + "="*80)
|
||||
print(f"\n📊 Summary:")
|
||||
print(f" ✅ Working: {len(working)}/{len(all_servers)}")
|
||||
print(f" ❌ Broken: {len(broken)}/{len(all_servers)}")
|
||||
|
||||
if broken:
|
||||
print(f"\n⚠️ Broken servers:")
|
||||
for url, reason in broken:
|
||||
print(f" • {url} - {reason}")
|
||||
|
||||
# Check if the newly added server is working
|
||||
new_server = "tcp://bitcoin.aranguren.org:50001"
|
||||
if new_server in all_servers:
|
||||
is_working = new_server in working
|
||||
status = "✅ WORKING" if is_working else "❌ BROKEN"
|
||||
print(f"\n🆕 Newly added server: {new_server} - {status}")
|
||||
|
||||
sys.exit(0 if len(broken) == 0 else 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -2,6 +2,7 @@ import globals from "globals";
|
|||
import js from "@eslint/js";
|
||||
import tseslint from "typescript-eslint";
|
||||
import pluginReact from "eslint-plugin-react";
|
||||
import importPlugin from "eslint-plugin-import";
|
||||
|
||||
export default [
|
||||
{ ignores: ["node_modules", "dist"] },
|
||||
|
|
@ -12,12 +13,16 @@ export default [
|
|||
languageOptions: {
|
||||
globals: globals.browser,
|
||||
},
|
||||
plugins: {
|
||||
import: importPlugin,
|
||||
},
|
||||
rules: {
|
||||
"react/react-in-jsx-scope": "off",
|
||||
"react/no-unescaped-entities": "off",
|
||||
"react/no-children-prop": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
"@typescript-eslint/no-empty-object-type": "off",
|
||||
"import/no-cycle": ["error", { maxDepth: 10 }],
|
||||
"no-restricted-globals": [
|
||||
"warn",
|
||||
{
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@
|
|||
"virtua": "^0.33.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react-redux": "^7.1.34",
|
||||
"@eslint/js": "^9.9.0",
|
||||
"@redux-devtools/remote": "^0.9.5",
|
||||
"@tauri-apps/cli": "^2.0.0",
|
||||
|
|
@ -60,9 +59,11 @@
|
|||
"@types/react": "^19.1.6",
|
||||
"@types/react-dom": "^19.1.5",
|
||||
"@types/react-is": "^19.0.0",
|
||||
"@types/react-redux": "^7.1.34",
|
||||
"@types/semver": "^7.5.8",
|
||||
"@vitejs/plugin-react": "^4.2.1",
|
||||
"eslint": "^9.9.0",
|
||||
"eslint-plugin-import": "^2.32.0",
|
||||
"eslint-plugin-react": "^7.35.0",
|
||||
"globals": "^15.9.0",
|
||||
"internal-ip": "^7.0.0",
|
||||
|
|
|
|||
|
|
@ -34,6 +34,12 @@ import {
|
|||
setHistory,
|
||||
setSyncProgress,
|
||||
} from "store/features/walletSlice";
|
||||
import { applyDefaultNodes } from "store/features/settingsSlice";
|
||||
import {
|
||||
DEFAULT_NODES,
|
||||
NEGATIVE_NODES_MAINNET,
|
||||
NEGATIVE_NODES_TESTNET,
|
||||
} from "store/defaults";
|
||||
|
||||
const TAURI_UNIFIED_EVENT_CHANNEL_NAME = "tauri-unified-event";
|
||||
|
||||
|
|
@ -64,6 +70,15 @@ function setIntervalImmediate(callback: () => void, interval: number): void {
|
|||
}
|
||||
|
||||
export async function setupBackgroundTasks(): Promise<void> {
|
||||
// Apply default nodes on startup (removes broken nodes, adds new ones)
|
||||
store.dispatch(
|
||||
applyDefaultNodes({
|
||||
defaultNodes: DEFAULT_NODES,
|
||||
negativeNodesMainnet: NEGATIVE_NODES_MAINNET,
|
||||
negativeNodesTestnet: NEGATIVE_NODES_TESTNET,
|
||||
}),
|
||||
);
|
||||
|
||||
// Setup periodic fetch tasks
|
||||
setIntervalImmediate(updatePublicRegistry, PROVIDER_UPDATE_INTERVAL);
|
||||
setIntervalImmediate(updateAllNodeStatuses, STATUS_UPDATE_INTERVAL);
|
||||
|
|
|
|||
|
|
@ -26,11 +26,9 @@ import {
|
|||
import {
|
||||
addNode,
|
||||
addRendezvousPoint,
|
||||
Blockchain,
|
||||
DonateToDevelopmentTip,
|
||||
FiatCurrency,
|
||||
moveUpNode,
|
||||
Network,
|
||||
removeNode,
|
||||
removeRendezvousPoint,
|
||||
resetSettings,
|
||||
|
|
@ -48,6 +46,7 @@ import {
|
|||
RedeemPolicy,
|
||||
RefundPolicy,
|
||||
} from "store/features/settingsSlice";
|
||||
import { Blockchain, Network } from "store/types";
|
||||
import { useAppDispatch, useNodes, useSettings } from "store/hooks";
|
||||
import ValidatedTextField from "renderer/components/other/ValidatedTextField";
|
||||
import HelpIcon from "@mui/icons-material/HelpOutline";
|
||||
|
|
|
|||
|
|
@ -72,15 +72,13 @@ import { MoneroRecoveryResponse } from "models/rpcModel";
|
|||
import { ListSellersResponse } from "../models/tauriModel";
|
||||
import logger from "utils/logger";
|
||||
import { getNetwork, isTestnet } from "store/config";
|
||||
import {
|
||||
Blockchain,
|
||||
DonateToDevelopmentTip,
|
||||
Network,
|
||||
} from "store/features/settingsSlice";
|
||||
import { DonateToDevelopmentTip } from "store/features/settingsSlice";
|
||||
import { Blockchain, Network } from "store/types";
|
||||
import { setStatus } from "store/features/nodesSlice";
|
||||
import { discoveredMakersByRendezvous } from "store/features/makersSlice";
|
||||
import { CliLog } from "models/cliModel";
|
||||
import { logsToRawString, parseLogsFromString } from "utils/parseUtils";
|
||||
import { DEFAULT_RENDEZVOUS_POINTS } from "store/defaults";
|
||||
|
||||
/// These are the official donation address for the eigenwallet/core project
|
||||
const DONATION_ADDRESS_MAINNET =
|
||||
|
|
@ -115,17 +113,6 @@ KM0Pp53f
|
|||
-----END PGP SIGNATURE-----
|
||||
`;
|
||||
|
||||
export const PRESET_RENDEZVOUS_POINTS = [
|
||||
"/dns4/discover.unstoppableswap.net/tcp/8888/p2p/12D3KooWA6cnqJpVnreBVnoro8midDL9Lpzmg8oJPoAGi7YYaamE",
|
||||
"/dns4/discover2.unstoppableswap.net/tcp/8888/p2p/12D3KooWGRvf7qVQDrNR5nfYD6rKrbgeTi9x8RrbdxbmsPvxL4mw",
|
||||
"/dns4/darkness.su/tcp/8888/p2p/12D3KooWFQAgVVS9t9UgL6v1sLprJVM7am5hFK7vy9iBCCoCBYmU",
|
||||
"/dns4/eigen.center/tcp/8888/p2p/12D3KooWS5RaYJt4ANKMH4zczGVhNcw5W214e2DDYXnjs5Mx5zAT",
|
||||
"/dns4/swapanarchy.cfd/tcp/8888/p2p/12D3KooWRtyVpmyvwzPYXuWyakFbRKhyXGrjhq6tP7RrBofpgQGp",
|
||||
"/dns4/rendezvous.observer/tcp/8888/p2p/12D3KooWMjceGXrYuGuDMGrfmJxALnSDbK4km6s1i1sJEgDTgGQa",
|
||||
"/dns4/aswap.click/tcp/8888/p2p/12D3KooWQzW52mdsLHTMu1EPiz3APumG6vGwpCuyy494MAQoEa5X",
|
||||
"/dns4/getxmr.st/tcp/8888/p2p/12D3KooWHHwiz6WDThPT8cEurstomg3kDSxzL2L8pwxfyX2fpxVk",
|
||||
];
|
||||
|
||||
async function invoke<ARGS, RESPONSE>(
|
||||
command: string,
|
||||
args: ARGS,
|
||||
|
|
@ -141,7 +128,7 @@ async function invokeNoArgs<RESPONSE>(command: string): Promise<RESPONSE> {
|
|||
|
||||
export async function fetchSellersAtPresetRendezvousPoints() {
|
||||
await Promise.all(
|
||||
PRESET_RENDEZVOUS_POINTS.map(async (rendezvousPoint) => {
|
||||
DEFAULT_RENDEZVOUS_POINTS.map(async (rendezvousPoint) => {
|
||||
const response = await listSellersAtRendezvousPoint([rendezvousPoint]);
|
||||
store.dispatch(discoveredMakersByRendezvous(response.sellers));
|
||||
|
||||
|
|
@ -241,7 +228,7 @@ export async function buyXmr() {
|
|||
}
|
||||
|
||||
await invoke<BuyXmrArgs, BuyXmrResponse>("buy_xmr", {
|
||||
rendezvous_points: PRESET_RENDEZVOUS_POINTS,
|
||||
rendezvous_points: DEFAULT_RENDEZVOUS_POINTS,
|
||||
sellers,
|
||||
monero_receive_pool: address_pool,
|
||||
// We convert null to undefined because typescript
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { ExtendedMakerStatus } from "models/apiModel";
|
||||
import { splitPeerIdFromMultiAddress } from "utils/parseUtils";
|
||||
import { CliMatches, getMatches } from "@tauri-apps/plugin-cli";
|
||||
import { Network } from "./features/settingsSlice";
|
||||
import { Network } from "./types";
|
||||
|
||||
let matches: CliMatches;
|
||||
try {
|
||||
|
|
|
|||
62
src-gui/src/store/defaults.ts
Normal file
62
src-gui/src/store/defaults.ts
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import { Network, Blockchain } from "./types";
|
||||
|
||||
export const DEFAULT_RENDEZVOUS_POINTS = [
|
||||
"/dns4/discover.unstoppableswap.net/tcp/8888/p2p/12D3KooWA6cnqJpVnreBVnoro8midDL9Lpzmg8oJPoAGi7YYaamE",
|
||||
"/dns4/discover2.unstoppableswap.net/tcp/8888/p2p/12D3KooWGRvf7qVQDrNR5nfYD6rKrbgeTi9x8RrbdxbmsPvxL4mw",
|
||||
"/dns4/darkness.su/tcp/8888/p2p/12D3KooWFQAgVVS9t9UgL6v1sLprJVM7am5hFK7vy9iBCCoCBYmU",
|
||||
"/dns4/eigen.center/tcp/8888/p2p/12D3KooWS5RaYJt4ANKMH4zczGVhNcw5W214e2DDYXnjs5Mx5zAT",
|
||||
"/dns4/swapanarchy.cfd/tcp/8888/p2p/12D3KooWRtyVpmyvwzPYXuWyakFbRKhyXGrjhq6tP7RrBofpgQGp",
|
||||
"/dns4/rendezvous.observer/tcp/8888/p2p/12D3KooWMjceGXrYuGuDMGrfmJxALnSDbK4km6s1i1sJEgDTgGQa",
|
||||
"/dns4/aswap.click/tcp/8888/p2p/12D3KooWQzW52mdsLHTMu1EPiz3APumG6vGwpCuyy494MAQoEa5X",
|
||||
"/dns4/getxmr.st/tcp/8888/p2p/12D3KooWHHwiz6WDThPT8cEurstomg3kDSxzL2L8pwxfyX2fpxVk",
|
||||
];
|
||||
|
||||
// Known broken nodes to remove when applying defaults
|
||||
export const NEGATIVE_NODES_MAINNET = [
|
||||
"tcp://electrum.blockstream.info:50001",
|
||||
"tcp://electrum.coinucopia.io:50001",
|
||||
"tcp://se-mma-crypto-payments-001.mullvad.net:50001",
|
||||
"tcp://electrum2.bluewallet.io:50777",
|
||||
];
|
||||
|
||||
export const NEGATIVE_NODES_TESTNET = [
|
||||
"ssl://ax101.blockeng.ch:60002",
|
||||
"tcp://electrum.blockstream.info:60001",
|
||||
"tcp://blockstream.info:143",
|
||||
"ssl://testnet.qtornado.com:50002",
|
||||
"ssl://testnet.qtornado.com:51002",
|
||||
"tcp://testnet.qtornado.com:51001",
|
||||
];
|
||||
|
||||
export const DEFAULT_NODES: Record<Network, Record<Blockchain, string[]>> = {
|
||||
[Network.Testnet]: {
|
||||
[Blockchain.Bitcoin]: [
|
||||
"ssl://blackie.c3-soft.com:57006",
|
||||
"ssl://v22019051929289916.bestsrv.de:50002",
|
||||
"tcp://v22019051929289916.bestsrv.de:50001",
|
||||
"ssl://electrum.blockstream.info:60002",
|
||||
"ssl://blockstream.info:993",
|
||||
"tcp://testnet.aranguren.org:51001",
|
||||
"ssl://testnet.aranguren.org:51002",
|
||||
"ssl://bitcoin.devmole.eu:5010",
|
||||
"tcp://bitcoin.devmole.eu:5000",
|
||||
],
|
||||
[Blockchain.Monero]: [],
|
||||
},
|
||||
[Network.Mainnet]: {
|
||||
[Blockchain.Bitcoin]: [
|
||||
"ssl://electrum.blockstream.info:50002",
|
||||
"ssl://bitcoin.stackwallet.com:50002",
|
||||
"ssl://b.1209k.com:50002",
|
||||
"ssl://mainnet.foundationdevices.com:50002",
|
||||
"tcp://bitcoin.lu.ke:50001",
|
||||
"ssl://electrum.coinfinity.co:50002",
|
||||
"tcp://electrum1.bluewallet.io:50001",
|
||||
"tcp://electrum2.bluewallet.io:50001",
|
||||
"tcp://electrum3.bluewallet.io:50001",
|
||||
"ssl://btc-electrum.cakewallet.com:50002",
|
||||
"tcp://bitcoin.aranguren.org:50001",
|
||||
],
|
||||
[Blockchain.Monero]: [],
|
||||
},
|
||||
};
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||
import { Blockchain } from "./settingsSlice";
|
||||
import { Blockchain } from "../types";
|
||||
|
||||
export interface NodesSlice {
|
||||
nodes: Record<Blockchain, Record<string, boolean>>;
|
||||
|
|
|
|||
|
|
@ -1,16 +1,11 @@
|
|||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||
import { Theme } from "renderer/components/theme";
|
||||
import { DEFAULT_NODES, DEFAULT_RENDEZVOUS_POINTS } from "../defaults";
|
||||
import { Network, Blockchain } from "../types";
|
||||
|
||||
export type DonateToDevelopmentTip = false | 0.0005 | 0.0075;
|
||||
|
||||
const DEFAULT_RENDEZVOUS_POINTS = [
|
||||
"/dns4/discover.unstoppableswap.net/tcp/8888/p2p/12D3KooWA6cnqJpVnreBVnoro8midDL9Lpzmg8oJPoAGi7YYaamE",
|
||||
"/dns4/discover2.unstoppableswap.net/tcp/8888/p2p/12D3KooWGRvf7qVQDrNR5nfYD6rKrbgeTi9x8RrbdxbmsPvxL4mw",
|
||||
"/dns4/darkness.su/tcp/8888/p2p/12D3KooWFQAgVVS9t9UgL6v1sLprJVM7am5hFK7vy9iBCCoCBYmU",
|
||||
"/dns4/eigen.center/tcp/8888/p2p/12D3KooWS5RaYJt4ANKMH4zczGVhNcw5W214e2DDYXnjs5Mx5zAT",
|
||||
"/dns4/swapanarchy.cfd/tcp/8888/p2p/12D3KooWRtyVpmyvwzPYXuWyakFbRKhyXGrjhq6tP7RrBofpgQGp",
|
||||
"/dns4/rendezvous.observer/tcp/8888/p2p/12D3KooWMjceGXrYuGuDMGrfmJxALnSDbK4km6s1i1sJEgDTgGQa",
|
||||
];
|
||||
const MIN_TIME_BETWEEN_DEFAULT_NODES_APPLY = 14 * 24 * 60 * 60 * 1000; // 14 days
|
||||
|
||||
export interface SettingsState {
|
||||
/// This is an ordered list of node urls for each network and blockchain
|
||||
|
|
@ -42,6 +37,8 @@ export interface SettingsState {
|
|||
externalMoneroRedeemAddress: string;
|
||||
/// The external Bitcoin refund address
|
||||
externalBitcoinRefundAddress: string;
|
||||
/// UTC timestamp (in milliseconds) when default nodes were last applied
|
||||
lastAppliedDefaultNodes?: number | null;
|
||||
}
|
||||
|
||||
export enum RedeemPolicy {
|
||||
|
|
@ -104,53 +101,8 @@ export enum FiatCurrency {
|
|||
Zar = "ZAR",
|
||||
}
|
||||
|
||||
export enum Network {
|
||||
Testnet = "testnet",
|
||||
Mainnet = "mainnet",
|
||||
}
|
||||
|
||||
export enum Blockchain {
|
||||
Bitcoin = "bitcoin",
|
||||
Monero = "monero",
|
||||
}
|
||||
|
||||
const initialState: SettingsState = {
|
||||
nodes: {
|
||||
[Network.Testnet]: {
|
||||
[Blockchain.Bitcoin]: [
|
||||
"ssl://ax101.blockeng.ch:60002",
|
||||
"ssl://blackie.c3-soft.com:57006",
|
||||
"ssl://v22019051929289916.bestsrv.de:50002",
|
||||
"tcp://v22019051929289916.bestsrv.de:50001",
|
||||
"tcp://electrum.blockstream.info:60001",
|
||||
"ssl://electrum.blockstream.info:60002",
|
||||
"ssl://blockstream.info:993",
|
||||
"tcp://blockstream.info:143",
|
||||
"ssl://testnet.qtornado.com:51002",
|
||||
"tcp://testnet.qtornado.com:51001",
|
||||
"tcp://testnet.aranguren.org:51001",
|
||||
"ssl://testnet.aranguren.org:51002",
|
||||
"ssl://testnet.qtornado.com:50002",
|
||||
"ssl://bitcoin.devmole.eu:5010",
|
||||
"tcp://bitcoin.devmole.eu:5000",
|
||||
],
|
||||
[Blockchain.Monero]: [],
|
||||
},
|
||||
[Network.Mainnet]: {
|
||||
[Blockchain.Bitcoin]: [
|
||||
"ssl://electrum.blockstream.info:50002",
|
||||
"tcp://electrum.blockstream.info:50001",
|
||||
"ssl://bitcoin.stackwallet.com:50002",
|
||||
"ssl://b.1209k.com:50002",
|
||||
"tcp://electrum.coinucopia.io:50001",
|
||||
"ssl://mainnet.foundationdevices.com:50002",
|
||||
"tcp://bitcoin.lu.ke:50001",
|
||||
"tcp://se-mma-crypto-payments-001.mullvad.net:50001",
|
||||
"ssl://electrum.coinfinity.co:50002",
|
||||
],
|
||||
[Blockchain.Monero]: [],
|
||||
},
|
||||
},
|
||||
nodes: DEFAULT_NODES,
|
||||
theme: Theme.Dark,
|
||||
fetchFiatPrices: false,
|
||||
fiatCurrency: FiatCurrency.Usd,
|
||||
|
|
@ -158,12 +110,14 @@ const initialState: SettingsState = {
|
|||
enableMoneroTor: false, // Default to not routing Monero traffic through Tor
|
||||
useMoneroRpcPool: true, // Default to using RPC pool
|
||||
userHasSeenIntroduction: false,
|
||||
// TODO: Apply these regularly (like the default nodes)
|
||||
rendezvousPoints: DEFAULT_RENDEZVOUS_POINTS,
|
||||
donateToDevelopment: false, // Default to no donation
|
||||
moneroRedeemPolicy: RedeemPolicy.Internal,
|
||||
bitcoinRefundPolicy: RefundPolicy.Internal,
|
||||
externalMoneroRedeemAddress: "",
|
||||
externalBitcoinRefundAddress: "",
|
||||
lastAppliedDefaultNodes: null,
|
||||
};
|
||||
|
||||
const alertsSlice = createSlice({
|
||||
|
|
@ -273,6 +227,62 @@ const alertsSlice = createSlice({
|
|||
setBitcoinRefundAddress(slice, action: PayloadAction<string>) {
|
||||
slice.externalBitcoinRefundAddress = action.payload;
|
||||
},
|
||||
applyDefaultNodes(
|
||||
slice,
|
||||
action: PayloadAction<{
|
||||
defaultNodes: Record<Network, Record<Blockchain, string[]>>;
|
||||
negativeNodesMainnet: string[];
|
||||
negativeNodesTestnet: string[];
|
||||
}>,
|
||||
) {
|
||||
const now = Date.now();
|
||||
const twoWeeksInMs = 14 * 24 * 60 * 60 * 1000;
|
||||
|
||||
// Check if we should apply defaults (first time or more than 2 weeks)
|
||||
if (
|
||||
slice.lastAppliedDefaultNodes == null ||
|
||||
now - slice.lastAppliedDefaultNodes > MIN_TIME_BETWEEN_DEFAULT_NODES_APPLY
|
||||
) {
|
||||
// Remove negative nodes from mainnet
|
||||
slice.nodes[Network.Mainnet][Blockchain.Bitcoin] = slice.nodes[
|
||||
Network.Mainnet
|
||||
][Blockchain.Bitcoin].filter(
|
||||
(node) => !action.payload.negativeNodesMainnet.includes(node),
|
||||
);
|
||||
|
||||
// Remove negative nodes from testnet
|
||||
slice.nodes[Network.Testnet][Blockchain.Bitcoin] = slice.nodes[
|
||||
Network.Testnet
|
||||
][Blockchain.Bitcoin].filter(
|
||||
(node) => !action.payload.negativeNodesTestnet.includes(node),
|
||||
);
|
||||
|
||||
// Add new default nodes if they don't exist (mainnet)
|
||||
action.payload.defaultNodes[Network.Mainnet][
|
||||
Blockchain.Bitcoin
|
||||
].forEach((node) => {
|
||||
if (
|
||||
!slice.nodes[Network.Mainnet][Blockchain.Bitcoin].includes(node)
|
||||
) {
|
||||
slice.nodes[Network.Mainnet][Blockchain.Bitcoin].push(node);
|
||||
}
|
||||
});
|
||||
|
||||
// Add new default nodes if they don't exist (testnet)
|
||||
action.payload.defaultNodes[Network.Testnet][
|
||||
Blockchain.Bitcoin
|
||||
].forEach((node) => {
|
||||
if (
|
||||
!slice.nodes[Network.Testnet][Blockchain.Bitcoin].includes(node)
|
||||
) {
|
||||
slice.nodes[Network.Testnet][Blockchain.Bitcoin].push(node);
|
||||
}
|
||||
});
|
||||
|
||||
// Update the timestamp
|
||||
slice.lastAppliedDefaultNodes = now;
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -295,6 +305,7 @@ export const {
|
|||
setBitcoinRefundPolicy,
|
||||
setMoneroRedeemAddress,
|
||||
setBitcoinRefundAddress,
|
||||
applyDefaultNodes,
|
||||
} = alertsSlice.actions;
|
||||
|
||||
export default alertsSlice.reducer;
|
||||
|
|
|
|||
|
|
@ -23,9 +23,8 @@ import {
|
|||
setFetchFiatPrices,
|
||||
setFiatCurrency,
|
||||
setUseMoneroRpcPool,
|
||||
Blockchain,
|
||||
Network,
|
||||
} from "store/features/settingsSlice";
|
||||
import { Blockchain, Network } from "store/types";
|
||||
import { fetchFeedbackMessagesViaHttp, updateRates } from "renderer/api";
|
||||
import { RootState, store } from "renderer/store/storeRenderer";
|
||||
import { swapProgressEventReceived } from "store/features/swapSlice";
|
||||
|
|
|
|||
9
src-gui/src/store/types.ts
Normal file
9
src-gui/src/store/types.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
export enum Network {
|
||||
Testnet = "testnet",
|
||||
Mainnet = "mainnet",
|
||||
}
|
||||
|
||||
export enum Blockchain {
|
||||
Bitcoin = "bitcoin",
|
||||
Monero = "monero",
|
||||
}
|
||||
|
|
@ -826,6 +826,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.47.1.tgz#e5e0a0bae2c9d4858cc9b8dc508b2e10d7f0df8b"
|
||||
integrity sha512-CpKnYa8eHthJa3c+C38v/E+/KZyF1Jdh2Cz3DyKZqEWYgrM1IHFArXNWvBLPQCKUEsAqqKX27tTqVEFbDNUcOA==
|
||||
|
||||
"@rtsao/scc@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8"
|
||||
integrity sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==
|
||||
|
||||
"@standard-schema/spec@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.0.0.tgz#f193b73dc316c4170f2e82a881da0f550d551b9c"
|
||||
|
|
@ -1127,6 +1132,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
|
||||
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
|
||||
|
||||
"@types/json5@^0.0.29":
|
||||
version "0.0.29"
|
||||
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
||||
integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
|
||||
|
||||
"@types/lodash@^4.17.6":
|
||||
version "4.17.20"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.20.tgz#1ca77361d7363432d29f5e55950d9ec1e1c6ea93"
|
||||
|
|
@ -1424,7 +1434,7 @@ array-buffer-byte-length@^1.0.1, array-buffer-byte-length@^1.0.2:
|
|||
call-bound "^1.0.3"
|
||||
is-array-buffer "^3.0.5"
|
||||
|
||||
array-includes@^3.1.6, array-includes@^3.1.8:
|
||||
array-includes@^3.1.6, array-includes@^3.1.8, array-includes@^3.1.9:
|
||||
version "3.1.9"
|
||||
resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.9.tgz#1f0ccaa08e90cdbc3eb433210f903ad0f17c3f3a"
|
||||
integrity sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==
|
||||
|
|
@ -1450,7 +1460,20 @@ array.prototype.findlast@^1.2.5:
|
|||
es-object-atoms "^1.0.0"
|
||||
es-shim-unscopables "^1.0.2"
|
||||
|
||||
array.prototype.flat@^1.3.1:
|
||||
array.prototype.findlastindex@^1.2.6:
|
||||
version "1.2.6"
|
||||
resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz#cfa1065c81dcb64e34557c9b81d012f6a421c564"
|
||||
integrity sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==
|
||||
dependencies:
|
||||
call-bind "^1.0.8"
|
||||
call-bound "^1.0.4"
|
||||
define-properties "^1.2.1"
|
||||
es-abstract "^1.23.9"
|
||||
es-errors "^1.3.0"
|
||||
es-object-atoms "^1.1.1"
|
||||
es-shim-unscopables "^1.1.0"
|
||||
|
||||
array.prototype.flat@^1.3.1, array.prototype.flat@^1.3.3:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz#534aaf9e6e8dd79fb6b9a9917f839ef1ec63afe5"
|
||||
integrity sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==
|
||||
|
|
@ -1783,6 +1806,13 @@ dayjs@^1.11.13:
|
|||
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c"
|
||||
integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==
|
||||
|
||||
debug@^3.2.7:
|
||||
version "3.2.7"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
|
||||
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.7:
|
||||
version "4.4.1"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b"
|
||||
|
|
@ -1996,7 +2026,7 @@ es-set-tostringtag@^2.0.3, es-set-tostringtag@^2.1.0:
|
|||
has-tostringtag "^1.0.2"
|
||||
hasown "^2.0.2"
|
||||
|
||||
es-shim-unscopables@^1.0.2:
|
||||
es-shim-unscopables@^1.0.2, es-shim-unscopables@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz#438df35520dac5d105f3943d927549ea3b00f4b5"
|
||||
integrity sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==
|
||||
|
|
@ -2051,6 +2081,47 @@ escape-string-regexp@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
|
||||
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
|
||||
|
||||
eslint-import-resolver-node@^0.3.9:
|
||||
version "0.3.9"
|
||||
resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac"
|
||||
integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==
|
||||
dependencies:
|
||||
debug "^3.2.7"
|
||||
is-core-module "^2.13.0"
|
||||
resolve "^1.22.4"
|
||||
|
||||
eslint-module-utils@^2.12.1:
|
||||
version "2.12.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz#f76d3220bfb83c057651359295ab5854eaad75ff"
|
||||
integrity sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==
|
||||
dependencies:
|
||||
debug "^3.2.7"
|
||||
|
||||
eslint-plugin-import@^2.32.0:
|
||||
version "2.32.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz#602b55faa6e4caeaa5e970c198b5c00a37708980"
|
||||
integrity sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==
|
||||
dependencies:
|
||||
"@rtsao/scc" "^1.1.0"
|
||||
array-includes "^3.1.9"
|
||||
array.prototype.findlastindex "^1.2.6"
|
||||
array.prototype.flat "^1.3.3"
|
||||
array.prototype.flatmap "^1.3.3"
|
||||
debug "^3.2.7"
|
||||
doctrine "^2.1.0"
|
||||
eslint-import-resolver-node "^0.3.9"
|
||||
eslint-module-utils "^2.12.1"
|
||||
hasown "^2.0.2"
|
||||
is-core-module "^2.16.1"
|
||||
is-glob "^4.0.3"
|
||||
minimatch "^3.1.2"
|
||||
object.fromentries "^2.0.8"
|
||||
object.groupby "^1.0.3"
|
||||
object.values "^1.2.1"
|
||||
semver "^6.3.1"
|
||||
string.prototype.trimend "^1.0.9"
|
||||
tsconfig-paths "^3.15.0"
|
||||
|
||||
eslint-plugin-react@^7.35.0:
|
||||
version "7.37.5"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz#2975511472bdda1b272b34d779335c9b0e877065"
|
||||
|
|
@ -2578,7 +2649,7 @@ is-callable@^1.2.7:
|
|||
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
|
||||
integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
|
||||
|
||||
is-core-module@^2.13.0, is-core-module@^2.16.0:
|
||||
is-core-module@^2.13.0, is-core-module@^2.16.0, is-core-module@^2.16.1:
|
||||
version "2.16.1"
|
||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4"
|
||||
integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==
|
||||
|
|
@ -2813,6 +2884,13 @@ json-stable-stringify-without-jsonify@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
|
||||
integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
|
||||
|
||||
json5@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593"
|
||||
integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==
|
||||
dependencies:
|
||||
minimist "^1.2.0"
|
||||
|
||||
json5@^2.2.3:
|
||||
version "2.2.3"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
|
||||
|
|
@ -3018,6 +3096,11 @@ minimatch@^9.0.4:
|
|||
dependencies:
|
||||
brace-expansion "^2.0.1"
|
||||
|
||||
minimist@^1.2.0, minimist@^1.2.6:
|
||||
version "1.2.8"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
|
||||
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
|
||||
|
||||
ms@^2.1.1, ms@^2.1.3:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||
|
|
@ -3127,6 +3210,15 @@ object.fromentries@^2.0.8:
|
|||
es-abstract "^1.23.2"
|
||||
es-object-atoms "^1.0.0"
|
||||
|
||||
object.groupby@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.3.tgz#9b125c36238129f6f7b61954a1e7176148d5002e"
|
||||
integrity sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==
|
||||
dependencies:
|
||||
call-bind "^1.0.7"
|
||||
define-properties "^1.2.1"
|
||||
es-abstract "^1.23.2"
|
||||
|
||||
object.values@^1.1.6, object.values@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.2.1.tgz#deed520a50809ff7f75a7cfd4bc64c7a038c6216"
|
||||
|
|
@ -3458,6 +3550,15 @@ resolve@^1.19.0:
|
|||
path-parse "^1.0.7"
|
||||
supports-preserve-symlinks-flag "^1.0.0"
|
||||
|
||||
resolve@^1.22.4:
|
||||
version "1.22.11"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.11.tgz#aad857ce1ffb8bfa9b0b1ac29f1156383f68c262"
|
||||
integrity sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==
|
||||
dependencies:
|
||||
is-core-module "^2.16.1"
|
||||
path-parse "^1.0.7"
|
||||
supports-preserve-symlinks-flag "^1.0.0"
|
||||
|
||||
resolve@^2.0.0-next.5:
|
||||
version "2.0.0-next.5"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c"
|
||||
|
|
@ -3802,6 +3903,11 @@ string_decoder@~1.1.1:
|
|||
dependencies:
|
||||
safe-buffer "~5.1.0"
|
||||
|
||||
strip-bom@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
||||
integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==
|
||||
|
||||
strip-final-newline@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
|
||||
|
|
@ -3879,6 +3985,16 @@ tsconfck@^3.0.3:
|
|||
resolved "https://registry.yarnpkg.com/tsconfck/-/tsconfck-3.1.6.tgz#da1f0b10d82237ac23422374b3fce1edb23c3ead"
|
||||
integrity sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==
|
||||
|
||||
tsconfig-paths@^3.15.0:
|
||||
version "3.15.0"
|
||||
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4"
|
||||
integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==
|
||||
dependencies:
|
||||
"@types/json5" "^0.0.29"
|
||||
json5 "^1.0.2"
|
||||
minimist "^1.2.6"
|
||||
strip-bom "^3.0.0"
|
||||
|
||||
type-check@^0.4.0, type-check@~0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
|
||||
|
|
|
|||
|
|
@ -57,49 +57,42 @@ pub fn default_electrum_servers_mainnet() -> Vec<Url> {
|
|||
vec![
|
||||
Url::parse("ssl://electrum.blockstream.info:50002")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("tcp://electrum.blockstream.info:50001")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("ssl://bitcoin.stackwallet.com:50002")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("ssl://b.1209k.com:50002").expect("default electrum server url to be valid"),
|
||||
Url::parse("tcp://electrum.coinucopia.io:50001")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("ssl://mainnet.foundationdevices.com:50002")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("tcp://bitcoin.lu.ke:50001").expect("default electrum server url to be valid"),
|
||||
Url::parse("tcp://se-mma-crypto-payments-001.mullvad.net:50001")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("ssl://electrum.coinfinity.co:50002")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("tcp://electrum1.bluewallet.io:50001")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("tcp://electrum2.bluewallet.io:50001")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("tcp://electrum3.bluewallet.io:50001")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("ssl://btc-electrum.cakewallet.com:50002")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("tcp://bitcoin.aranguren.org:50001")
|
||||
.expect("default electrum server url to be valid"),
|
||||
]
|
||||
}
|
||||
|
||||
pub fn default_electrum_servers_testnet() -> Vec<Url> {
|
||||
vec![
|
||||
Url::parse("ssl://ax101.blockeng.ch:60002")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("ssl://blackie.c3-soft.com:57006")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("ssl://v22019051929289916.bestsrv.de:50002")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("tcp://v22019051929289916.bestsrv.de:50001")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("tcp://electrum.blockstream.info:60001")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("ssl://electrum.blockstream.info:60002")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("ssl://blockstream.info:993").expect("default electrum server url to be valid"),
|
||||
Url::parse("tcp://blockstream.info:143").expect("default electrum server url to be valid"),
|
||||
Url::parse("ssl://testnet.qtornado.com:51002")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("tcp://testnet.qtornado.com:51001")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("tcp://testnet.aranguren.org:51001")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("ssl://testnet.aranguren.org:51002")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("ssl://testnet.qtornado.com:50002")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("ssl://bitcoin.devmole.eu:5010")
|
||||
.expect("default electrum server url to be valid"),
|
||||
Url::parse("tcp://bitcoin.devmole.eu:5000")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue