diff --git a/README.md b/README.md index de557c3ea..51f1d22c4 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,11 @@ This project includes the following apps / packages: -### Apps +### App -- `guardian-ui`: Web app experience for setting up and administering fedimints. This is used by the Fedimint guardians -- `gateway-ui`: Web app experience for managing Fedimint gateways. This is used by Gateway administrators +We've refactored the Fedimint UI into a single client side app that can run on the browser or on desktop using Electron. + +- `router`: This creates a homescreen that shows all your connected services: guardians or gateways. You can connect to other guardians or gateways by entering their baseUrl. You have to authenticate each service separately because the auth for each one is done differently. ### Packages diff --git a/apps/gateway-ui/public/index.html b/apps/gateway-ui/public/index.html deleted file mode 100644 index d4fb061d4..000000000 --- a/apps/gateway-ui/public/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - Gateway UI - - - -
- - - diff --git a/apps/gateway-ui/public/manifest.json b/apps/gateway-ui/public/manifest.json deleted file mode 100644 index 93068faa7..000000000 --- a/apps/gateway-ui/public/manifest.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "short_name": "Fedimint", - "name": "Fedimint Gateway UI", - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" -} diff --git a/apps/gateway-ui/src/ApiProvider.tsx b/apps/gateway-ui/src/ApiProvider.tsx deleted file mode 100644 index dacef0ace..000000000 --- a/apps/gateway-ui/src/ApiProvider.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react'; -import { GatewayApi } from './GatewayApi'; - -interface ApiContextProps { - // API to interact with the Gateway server - gateway: GatewayApi; -} - -export const ApiContext = React.createContext({ - gateway: new GatewayApi(), -}); - -export const ApiProvider = React.memo(function ApiProvider({ - props, - children, -}: { - props: ApiContextProps; - children: React.ReactNode; -}): JSX.Element { - return {children}; -}); diff --git a/apps/gateway-ui/src/App.tsx b/apps/gateway-ui/src/App.tsx deleted file mode 100644 index a84d30f0e..000000000 --- a/apps/gateway-ui/src/App.tsx +++ /dev/null @@ -1,176 +0,0 @@ -import React, { useState, useEffect, useMemo, useRef } from 'react'; -import { Flex } from '@chakra-ui/react'; -import { GatewayInfo, FederationInfo, GatewayBalances } from '@fedimint/types'; -import { ConnectFederationModal, LightningCard } from './components'; -import { GatewayApi } from './GatewayApi'; -import { ApiProvider } from './ApiProvider'; -import { Wrapper, Login } from '@fedimint/ui'; -import { FederationsTable } from './components/federations/FederationsTable'; -import { Loading } from './components/Loading'; -import { HeaderWithUnitSelector } from './components/HeaderWithUnitSelector'; -import { WalletCard } from './components/walletCard/WalletCard'; -import { - WalletModal, - WalletModalAction, - WalletModalState, - WalletModalType, -} from './components/walletModal/WalletModal'; -import { ErrorMessage } from './components/ErrorMessage'; - -export const UNIT_OPTIONS = ['msats', 'sats', 'btc'] as const; -export type Unit = (typeof UNIT_OPTIONS)[number]; - -export const App = React.memo(function Admin(): JSX.Element { - const gateway = useRef(() => new GatewayApi()); - const [balances, setBalances] = useState(null); - const [gatewayInfo, setGatewayInfo] = useState(null); - - // Whether the user has successfully authenticated with the gateway. - const [isAuthenticated, setIsAuthenticated] = useState(false); - // Whether we are currently checking the authentication status. - const [runningInitialAuthCheck, setRunningInitialAuthCheck] = useState(false); - - const [error, setError] = useState(''); - const [showConnectFed, setShowConnectFed] = useState(false); - const [unit, setUnit] = useState('sats'); - const [walletModalState, setWalletModalState] = useState({ - isOpen: false, - action: WalletModalAction.Receive, - type: WalletModalType.Onchain, - selectedFederation: null, - }); - - // Attempt to authenticate with the saved password on initial load and skip the login screen if successful. - useEffect(() => { - setRunningInitialAuthCheck(true); - gateway - .current() - .testPassword() - .then((authed) => { - setIsAuthenticated(authed); - }) - .catch((err) => { - console.error(err); - }) - .finally(() => setRunningInitialAuthCheck(false)); - }, []); - - useEffect(() => { - if (isAuthenticated) { - const fetchInfoAndConfigs = async () => { - try { - const gatewayInfo = await gateway.current().fetchInfo(); - - const configs = await gateway.current().fetchConfigs(); - - const updatedFederations = gatewayInfo.federations.map( - (federation) => ({ - ...federation, - config: configs.federations[federation.federation_id], - }) - ); - - setGatewayInfo({ ...gatewayInfo, federations: updatedFederations }); - } catch (error: unknown) { - console.error(error); - setError((error as Error).message); - } - }; - - const fetchBalances = () => { - gateway - .current() - .fetchBalances() - .then((balances) => { - setBalances(balances); - }) - .catch(({ message, error }) => { - console.error(error); - setError(message); - }); - }; - - fetchInfoAndConfigs(); - fetchBalances(); - - const interval = setInterval(fetchInfoAndConfigs, 5000); - return () => clearInterval(interval); - } - }, [isAuthenticated]); - - const content = useMemo(() => { - if (runningInitialAuthCheck) return ; - if (error) return ; - if (!isAuthenticated) { - return ( - setIsAuthenticated(true)} - parseError={(err) => (err as Error).message} - /> - ); - } - - if (!gatewayInfo) return ; - - return ( - - - {balances && ( - - )} - - setShowConnectFed(true)} - setWalletModalState={setWalletModalState} - /> - setShowConnectFed(false)} - renderConnectedFedCallback={(federation: FederationInfo) => { - setGatewayInfo({ - ...gatewayInfo, - federations: [...gatewayInfo.federations, federation], - }); - setShowConnectFed(false); - }} - /> - - - ); - }, [ - runningInitialAuthCheck, - isAuthenticated, - showConnectFed, - error, - gatewayInfo, - unit, - walletModalState, - balances, - ]); - - return ( - - {content} - - ); -}); diff --git a/apps/gateway-ui/src/index.tsx b/apps/gateway-ui/src/index.tsx deleted file mode 100644 index e122085eb..000000000 --- a/apps/gateway-ui/src/index.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import { SharedChakraProvider, theme, Fonts } from '@fedimint/ui'; -import spaceGroteskTtf from '@fedimint/ui/assets/fonts/SpaceGrotesk-Variable.ttf'; -import interTtf from '@fedimint/ui/assets/fonts/Inter-Variable.ttf'; -import { App } from './App'; -import { i18nProvider } from '@fedimint/utils'; -import { languages } from './languages'; - -i18nProvider(languages); - -const root = ReactDOM.createRoot( - document.getElementById('root') as HTMLElement -); - -root.render( - - - - - - -); diff --git a/apps/gateway-ui/tsconfig.json b/apps/gateway-ui/tsconfig.json deleted file mode 100644 index 4bf6bc5df..000000000 --- a/apps/gateway-ui/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "@fedimint/tsconfig/react-app.json", - "compilerOptions": { - "typeRoots": [ - "src/typings/", - "node_modules/@types/", - "../node_modules/@types/" - ] - }, - "exclude": ["dist", "node_modules"], - "include": ["src"] -} diff --git a/apps/guardian-ui/.eslintrc.js b/apps/guardian-ui/.eslintrc.js deleted file mode 100644 index 655414ac5..000000000 --- a/apps/guardian-ui/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@fedimint/eslint-config'); diff --git a/apps/guardian-ui/package.json b/apps/guardian-ui/package.json deleted file mode 100644 index a265282e3..000000000 --- a/apps/guardian-ui/package.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "name": "@fedimint/guardian-ui", - "version": "0.1.0", - "private": true, - "scripts": { - "start": "react-scripts start", - "dev": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test", - "eject": "react-scripts eject", - "lint": "eslint \"src/**/*.ts*\" --max-warnings 0", - "clean": "rm -rf build" - }, - "dependencies": { - "@chakra-ui/react": "^2.4.5", - "@codemirror/basic-setup": "^0.20.0", - "@codemirror/lang-json": "^6.0.1", - "@emotion/react": "^11", - "@emotion/styled": "^11", - "@fedimint/types": "*", - "@fedimint/ui": "*", - "@fedimint/utils": "*", - "@uiw/codemirror-theme-github": "^4.21.21", - "@uiw/react-codemirror": "^4.21.21", - "diff": "^5.2.0", - "framer-motion": "^6", - "jsonrpc-client-websocket": "^1.5.2", - "node": "^20.1.0", - "qrcode.react": "^3.1.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-icons": "^4.7.1", - "react-scripts": "5.0.1", - "react-use-websocket": "3.0.0" - }, - "devDependencies": { - "@fedimint/eslint-config": "*", - "@fedimint/tsconfig": "*", - "@testing-library/jest-dom": "^5.16.1", - "@testing-library/react": "^13.0.0", - "@testing-library/user-event": "^13.5.0", - "@types/diff": "^5.0.9", - "@types/jest": "^27.0.3", - "@types/node": "^16.11.14", - "@types/react": "^18.2.0", - "@types/react-dom": "^18.2.0", - "@typescript-eslint/eslint-plugin": "^5.48.1", - "@typescript-eslint/parser": "^5.48.2", - "eslint": "^8.4.1", - "prettier": "^2.8.3", - "typescript": "^5.1.6" - }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - } -} diff --git a/apps/guardian-ui/public/config.json.example b/apps/guardian-ui/public/config.json.example deleted file mode 100644 index 8a2befd3b..000000000 --- a/apps/guardian-ui/public/config.json.example +++ /dev/null @@ -1,4 +0,0 @@ -{ - "fm_config_api": "ws://127.0.0.1:18174", - "tos": "terms of service go here" -} \ No newline at end of file diff --git a/apps/guardian-ui/public/favicon.ico b/apps/guardian-ui/public/favicon.ico deleted file mode 100644 index be929f3b1..000000000 Binary files a/apps/guardian-ui/public/favicon.ico and /dev/null differ diff --git a/apps/guardian-ui/public/robots.txt b/apps/guardian-ui/public/robots.txt deleted file mode 100644 index e9e57dc4d..000000000 --- a/apps/guardian-ui/public/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -# https://www.robotstxt.org/robotstxt.html -User-agent: * -Disallow: diff --git a/apps/guardian-ui/src/App.tsx b/apps/guardian-ui/src/App.tsx deleted file mode 100644 index 4dae89913..000000000 --- a/apps/guardian-ui/src/App.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import React, { useMemo } from 'react'; -import { Box, Flex, Spinner, Heading, Text, Center } from '@chakra-ui/react'; -import { - theme, - Fonts, - SharedChakraProvider, - Wrapper, - Login, -} from '@fedimint/ui'; -import spaceGroteskTtf from '@fedimint/ui/assets/fonts/SpaceGrotesk-Variable.ttf'; -import interTtf from '@fedimint/ui/assets/fonts/Inter-Variable.ttf'; -import { SetupContextProvider } from './setup/SetupContext'; -import { AdminContextProvider } from './admin/AdminContext'; -import { FederationSetup } from './setup/FederationSetup'; -import { FederationAdmin } from './admin/FederationAdmin'; -import { useAppContext } from './hooks'; -import { useTranslation } from '@fedimint/utils'; -import { APP_ACTION_TYPE, Status } from './types'; -import { formatApiErrorMessage } from './utils/api'; -import { NotConfigured } from './components/NotConfigured'; - -export const App = React.memo(function App() { - const { t } = useTranslation(); - const { state, api, dispatch } = useAppContext(); - - const content = useMemo(() => { - if (state.appError) { - return ( - - - {t('common.error')} - - {state.appError} - - ); - } - - if (state.status === Status.NotConfigured) { - return ( - - - - ); - } - - if (state.needsAuth) { - return ( - - api.testPassword(password || '')} - setAuthenticated={() => - dispatch({ type: APP_ACTION_TYPE.SET_NEEDS_AUTH, payload: false }) - } - parseError={formatApiErrorMessage} - /> - - ); - } - - if (state.status === Status.Setup && state.initServerStatus) { - return ( - - - - - - ); - } - - if (state.status === Status.Admin) { - return ( - - - - - - ); - } - - return ( -
- -
- ); - }, [ - state.status, - state.appError, - state.needsAuth, - state.initServerStatus, - api, - dispatch, - t, - ]); - - return ( - - - -
- {content} -
-
-
- ); -}); diff --git a/apps/guardian-ui/src/AppContext.tsx b/apps/guardian-ui/src/AppContext.tsx deleted file mode 100644 index b9f9def3e..000000000 --- a/apps/guardian-ui/src/AppContext.tsx +++ /dev/null @@ -1,118 +0,0 @@ -import React, { - createContext, - Dispatch, - ReactNode, - useEffect, - useReducer, -} from 'react'; -import { ServerStatus } from '@fedimint/types'; -import { GuardianApi } from './GuardianApi'; -import { formatApiErrorMessage } from './utils/api'; -import { APP_ACTION_TYPE, AppAction, AppState, Status } from './types'; - -export interface AppContextValue { - api: GuardianApi; - state: AppState; - dispatch: Dispatch; -} - -const initialState = { - status: Status.Loading, - needsAuth: false, - initServerStatus: undefined, - appError: undefined, -}; - -const reducer = (state: AppState, action: AppAction): AppState => { - switch (action.type) { - case APP_ACTION_TYPE.SET_STATUS: - return { ...state, status: action.payload }; - case APP_ACTION_TYPE.SET_NEEDS_AUTH: - return { ...state, needsAuth: action.payload }; - case APP_ACTION_TYPE.SET_INIT_SERVER_STATUS: - return { ...state, initServerStatus: action.payload }; - case APP_ACTION_TYPE.SET_ERROR: - return { ...state, appError: action.payload }; - default: - return state; - } -}; - -const api = new GuardianApi(); - -export const AppContext = createContext({ - api: api, - state: initialState, - dispatch: () => null, -}); - -export interface AppContextProviderProps { - children: ReactNode; -} - -export const AppContextProvider: React.FC = ({ - children, -}: AppContextProviderProps) => { - const [state, dispatch] = useReducer(reducer, initialState); - - useEffect(() => { - const load = async () => { - try { - const guardianConfig = await api.getGuardianConfig(); - if (!guardianConfig?.fm_config_api) { - dispatch({ - type: APP_ACTION_TYPE.SET_STATUS, - payload: Status.NotConfigured, - }); - return; - } - await api.connect(guardianConfig.fm_config_api); - const server = (await api.status()).server; - - // If they're at a point where a password has been configured, make - // sure they have a valid password set. If not, set needsAuth. - if (server !== ServerStatus.AwaitingPassword) { - const password = api.getPassword(); - const hasValidPassword = password - ? await api.testPassword(password) - : false; - if (!hasValidPassword) { - dispatch({ type: APP_ACTION_TYPE.SET_NEEDS_AUTH, payload: true }); - } - } - - if (server === ServerStatus.ConsensusRunning) { - dispatch({ type: APP_ACTION_TYPE.SET_STATUS, payload: Status.Admin }); - } else { - dispatch({ type: APP_ACTION_TYPE.SET_STATUS, payload: Status.Setup }); - } - - dispatch({ - type: APP_ACTION_TYPE.SET_INIT_SERVER_STATUS, - payload: server, - }); - } catch (err) { - dispatch({ - type: APP_ACTION_TYPE.SET_ERROR, - payload: formatApiErrorMessage(err), - }); - } - }; - - if (state.status === Status.Loading) { - load().catch((err) => console.error(err)); - } - }, [state.status]); - - return ( - - {children} - - ); -}; diff --git a/apps/guardian-ui/src/admin/AdminContext.tsx b/apps/guardian-ui/src/admin/AdminContext.tsx deleted file mode 100644 index b8b4e4b2f..000000000 --- a/apps/guardian-ui/src/admin/AdminContext.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React, { createContext, ReactNode } from 'react'; -import { AdminApiInterface, GuardianApi } from '../GuardianApi'; - -export interface AdminContextValue { - api: AdminApiInterface; -} - -export const AdminContext = createContext({ - api: new GuardianApi(), -}); - -export interface AdminContextProviderProps { - api: AdminApiInterface; - children: ReactNode; -} - -export const AdminContextProvider: React.FC = ({ - api, - children, -}: AdminContextProviderProps) => { - return ( - - {children} - - ); -}; diff --git a/apps/guardian-ui/src/components/NotConfigured.tsx b/apps/guardian-ui/src/components/NotConfigured.tsx deleted file mode 100644 index bf7b74c38..000000000 --- a/apps/guardian-ui/src/components/NotConfigured.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React, { useCallback, useState } from 'react'; -import { - Button, - Flex, - Heading, - Input, - Text, - FormControl, - FormLabel, - FormErrorMessage, -} from '@chakra-ui/react'; -import { useTranslation } from '@fedimint/utils'; -import { GuardianApi } from '../GuardianApi'; -import { APP_ACTION_TYPE, Status, AppAction } from '../types'; - -interface NotConfiguredProps { - api: GuardianApi; - dispatch: React.Dispatch; -} - -export const NotConfigured: React.FC = ({ - api, - dispatch, -}) => { - const { t } = useTranslation(); - const [configUrl, setConfigUrl] = useState(''); - const [error, setError] = useState(null); - - const handleSubmit = useCallback( - async (e: React.FormEvent) => { - e.preventDefault(); - setError(null); - - try { - await api.setGuardianConfig({ fm_config_api: configUrl }); - dispatch({ type: APP_ACTION_TYPE.SET_STATUS, payload: Status.Loading }); - } catch (err) { - setError(t('errors.invalidConfig')); - } - }, - [api, configUrl, dispatch, t] - ); - - return ( -
- - - - {t('notConfigured.title')} - - - {t('notConfigured.description')} - - - - {t('notConfigured.urlLabel')} - setConfigUrl(e.target.value)} - /> - {error && {error}} - - - -
- ); -}; diff --git a/apps/guardian-ui/src/hooks/index.tsx b/apps/guardian-ui/src/hooks/index.tsx deleted file mode 100644 index f9b035094..000000000 --- a/apps/guardian-ui/src/hooks/index.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { useContext, useEffect, useState } from 'react'; -import { AppContextValue, AppContext } from '../AppContext'; -import { SetupContext, SetupContextValue } from '../setup/SetupContext'; -import { AdminContext, AdminContextValue } from '../admin/AdminContext'; - -export function useAppContext(): AppContextValue { - return useContext(AppContext); -} - -export function useSetupContext(): SetupContextValue { - return useContext(SetupContext); -} - -/** - * Tells the guardian context to poll for updates. Handles turning off polling - * on dismount. - */ -export function useConsensusPolling(shouldPoll = true) { - const { toggleConsensusPolling } = useSetupContext(); - - useEffect(() => { - if (!shouldPoll) return; - toggleConsensusPolling(true); - return () => toggleConsensusPolling(false); - }, [shouldPoll, toggleConsensusPolling]); -} - -export function useAdminContext(): AdminContextValue { - return useContext(AdminContext); -} - -export const useEllipsis = () => { - const [ellipsis, setEllipsis] = useState(''); - - useEffect(() => { - const interval = setInterval(() => { - setEllipsis((prev) => (prev.length < 3 ? prev + '.' : '')); - }, 500); - return () => clearInterval(interval); - }, []); - - return ellipsis; -}; diff --git a/apps/guardian-ui/src/index.tsx b/apps/guardian-ui/src/index.tsx deleted file mode 100644 index 7631e69d9..000000000 --- a/apps/guardian-ui/src/index.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { ColorModeScript } from '@chakra-ui/react'; -import * as React from 'react'; -import * as ReactDOM from 'react-dom/client'; -import { AppContextProvider } from './AppContext'; -import { App } from './App'; -import { i18nProvider } from '@fedimint/utils'; -import { languages } from './languages'; - -i18nProvider(languages); - -const container = document.getElementById('root'); -if (!container) throw new Error('Failed to find the root element'); -const root = ReactDOM.createRoot(container); - -root.render( - - - - - - -); diff --git a/apps/guardian-ui/src/languages/ca.json b/apps/guardian-ui/src/languages/ca.json deleted file mode 100644 index fe6128798..000000000 --- a/apps/guardian-ui/src/languages/ca.json +++ /dev/null @@ -1,344 +0,0 @@ -{ - "common": { - "bitcoin": "Bitcoin", - "next": "Següent", - "back": "Enrere", - "error": "Alguna cosa ha anat malament.", - "unknown": "Desconegut", - "remove": "Eliminar", - "copy": "Copia", - "copied": "Copiat!", - "cancel": "Cancel·la", - "review": "Revisió", - "approvals": "Aprovacions", - "approve": "Aprovar", - "threshold": "Llimite", - "confirm": "Confirmar", - "you": "Tu", - "close": "Tanca", - "save": "Desaureta", - "continue": "Continuar", - "submit": "Enviar" - }, - "notConfigured": { - "title": "No Configurat", - "description": "Introduïu l'URL de l'API de configuració de Fedimint per continuar." - }, - "connect-guardians": { - "invite-guardians": "Convida els seguidors", - "invite-guardians-help": "Comparteix aquest enllaç amb els altres Guardians.", - "approve": "Aprovar", - "approved": "Aprovat", - "pending": "Pendent", - "not-joined": "No unitat", - "waiting-for-guardian": "Esperant el guardian", - "table-title": "Guardians de la Federació", - "table-description": "Els guardians seran confirmats aquí un cop confirmin la configuració de la Federació.", - "meta-field-key": "Camp meta - {{key}}" - }, - "federation-dashboard": { - "invite-members": "Convida membres o autentica't com a guardian", - "invite-members-prompt": "Comparteix això per convidar membres a unir-se a la federació.", - "fed-info": { - "label": "Informació de la Federació", - "your-status-label": "Estat", - "block-count-label": "Alçada del bloc de consens", - "api-version-label": "versió de l'API", - "consensus-version-label": "Versió de consens", - "peer-id-label": "ID de companyia", - "session-info": { - "session-height": "Alçada de sessió", - "latest-session": "Última sessió" - } - }, - "balance": { - "label": "Balanç de situació" - }, - "bitcoin-node": { - "label": "Node de Bitcoin", - "url-label": "URL", - "network-label": "Xarxa" - }, - "guardians": { - "label": "Altres Guardians", - "id-name-label": "ID: Nom", - "status-label": "Estat de connexió", - "health-label": "Salut", - "health-issue": "Problema", - "health-good": "Bé", - "last-contribution-label": "Última contribució de sessió", - "api-url-label": "URL de l'API", - "fetching-announcement": "Obtenció d'anunci..." - }, - "gateways": { - "label": "Portes de llum", - "node-id-label": "ID de Node Lightning", - "gateway-id-label": "ID de passarel·la", - "fee-label": "Quota de pas", - "view-on-site": "Veure a {{site}}", - "no-gateways-info-title": "Encara no hi ha passarel·les connectades!", - "no-gateways-info-description": "Els operadors de nodes Lightning poden connectar-se a la vostra federació per proporcionar interoperabilitat de la Lightning Network. Un cop connectats, apareixeran aquí." - }, - "api-announcements": { - "label": "Anuncis de l'API", - "guardian": "Guardià", - "api-url": "URL de l'API", - "revision": "Revisió" - }, - "config": { - "label": "Configuració de la Federació", - "view-config": "Veure Configuració", - "missing-meta-module": "No és possible editar els camps Meta. El mòdul Meta no està disponible per a aquesta federació.", - "manage-meta": { - "label": "Gestiona Meta", - "cancel-button": "Cancel·la", - "confirm-modal": { - "title": "Confirmar aprovació", - "description": "La teva aprovació arribarà al llindar per adoptar aquest canvi meta. La teva nova meta tindrà aquest aspecte:" - }, - "consensus-meta-label": "Meta actual en consens.", - "revoke-button": "Revocar", - "no-consensus-meta-message": "no hi ha meta en el consens", - "proposed-meta-label": "Propostes Meta", - "propose-meta": "Proposa Meta", - "propose-new-meta-button": "Proposar Nou Meta", - "proposal-approved": "Has aprovat aquesta proposta", - "no-submitted-meta-message": "no hi ha edicions meta per revisar", - "edit-meta-label": "Edita meta", - "edit-consensus-meta-button": "Editar Consensus Meta", - "submit-meta-proposal": "Envia una proposta de Meta", - "peer-approvals": "Aprovacions entre iguals", - "actions": "Accions", - "revision": "Revisió", - "setup-meta-title": "Configurant un Meta per a la teva Federació", - "setup-meta-description": "Fedimint pot proporcionar informació addicional als clients en forma de camps meta: parells de clau-valor amb informació arbitrària que podríeu voler compartir amb els clients. Tot i que aquests camps meta no són interpretats per Fedimint, són rellevants per al consens, és a dir, no poden diferir entre els membres de la federació. D'aquesta manera, els clients poden confiar en la seva correcció.", - "propose-updates": "Com a guardià de fedimint, pots proposar actualitzacions al meta que seran acceptades pels altres guardians. Un cop l'actualització sigui acceptada per un llindar de guardians, serà adoptada com el nou meta de consens per a la federació.", - "core-meta-fields": "Els següents camps meta s'han definit com a part del protocol bàsic de Fedimint i són útils per incloure a la meta de la vostra federació:", - "meta-field-expiry": "Un segell de temps unix després del qual la federació es tancarà.", - "meta-field-name": "El nom llegible per a humans de la federació", - "meta-field-icon": "Una URL a un icona de logotip per a la federació", - "meta-field-welcome": "Un missatge de benvinguda per als nous usuaris que s'uneixen a la federació.", - "meta-field-gateways": "Una llista d'identificadors de passarel·la verificats per la federació", - "your-own-fields": "També pots afegir els teus propis camps meta arbitràries a la proposta. Aquests s'afegiran a la meta de tots els clients que es connectin a la teva federació i es podran utilitzar per a qualsevol propòsit que desitgis.", - "meta-effect-add": "Afegir", - "meta-effect-modify": "Modificar", - "meta-effect-unchanged": "Inalterat", - "proposals": "Propostes" - } - }, - "modal": { - "client-connect": "Connecta un Client" - }, - "danger-zone": { - "danger-zone-label": "Zona de perill", - "cancel": "Cancel·la", - "danger-zone-description": "Utilitzeu amb precaució!", - "guardian-warning-message": "AVÍS: No comparteu aquest codi amb ningú. Qualsevol persona amb aquest codi pot autenticar-se com a Guardian. Assegureu-vos que esteu en un lloc privat i que ningú estigui mirant la vostra pantalla.", - "guardian-acknowledge": "Reconèixer i Revelar Codi", - "acknowledge-and-download": "Reconèixer i continuar", - "guardian-authenticate": "Autentica't com a Guardian", - "guardian-connect-warning": "NO COMPARTIS AIXÒ", - "backup": { - "label": "Còpia de seguretat", - "title": "Descarregar còpia de seguretat", - "warning-title": "Advertència", - "warning-text": "La còpia de seguretat conté claus privades i material secret per al guardian de la federació i ha de ser mantinguda segura. La recuperació mitjançant aquesta còpia de seguretat requereix la teva contrasenya d'administrador!", - "cancelButton": "Cancel·la", - "acknowledgeButton": "Reconèixer i descarregar" - }, - "sign-api-announcement": { - "label": "Anunci de l'API de Sign", - "title": "Anunci de l'API de Sign", - "description": "Signa un nou anunci d'API.", - "current-api-url": "La teva URL d'API de la Configuració Local", - "announced-api-url": "La teva URL d'API dels Anuncis de Federació", - "urls-match": "La teva URL d'API actual coincideix amb la teva URL d'API anunciada.", - "urls-mismatch": "Has canviat l'URL de l'API a la teva configuració local i necessites fer un nou anunci de l'API.", - "sign-button": "Anunci de nova API", - "signing-in-progress": "Iniciant sessió...", - "sign-tooltip": "Signa l'anunci de l'API per anunciar la teva URL de l'API a la federació." - }, - "schedule-shutdown": { - "label": "Programar apagada", - "title": "Programar apagada", - "description": "Programa el teu node guardian perquè s'apagui després d'una alçada de sessió específica per a una actualització coordinada dels teus binaris de fedimintd.", - "current-session": "Sessió actual", - "session-to-shutdown": "Sessió per tancar a", - "confirm-shutdown": "Confirmar apagada", - "session-to-shutdown-helper": "Introdueix l'altura de sessió a la qual vols apagar el teu node guardian." - } - } - }, - "login": { - "title": "Ben tornat!", - "subtitle": "Si us plau, introdueix la teva contrasenya.", - "password": "Contrasenya", - "submit": "Enviar" - }, - "role-selector": { - "disclaimer-title": "Fedimint és un programari beta.", - "disclaimer-text": "Si us plau, informa de qualsevol problema a https://github.com/fedimint/fedimint/issues", - "leader": { - "label": "Configura el líder", - "description": "Introdueix la configuració que altres Guardians aproven. Un Guardian actua com a Líder de Configuració." - }, - "follower": { - "label": "Seguidor", - "description": "Un cop un Líder de Configuració estableix les configuracions, altres Guardians escullen aquesta opció per aprovar els ajustaments i crear la Federació." - }, - "solo": { - "label": "Solament", - "description": "Operar Fedimint com un Guardian Sol sense consens, tolerància a fallades, còpies de seguretat federades, o altres beneficis de resiliència de Fedimint. Procediu amb precaució, no està destinat per a ús en producció." - }, - "warning-modal": { - "title": "Està tothom a punt?", - "description": "Sortir de la cerimònia de configuració pot fer que la configuració falli i requerir que reinicieu el vostre guardian. Assegureu-vos que tothom estigui preparat per executar la configuració completa abans de continuar!" - } - }, - "run-dkg": { - "error-config": "No s'ha pogut executar la generació de claus distribuïdes. La configuració de la federació s'ha de reiniciar.", - "error-default": "No estàs preparat per a DKG, el teu estat actual és", - "error-header": "Alguna cosa ha anat malament.", - "waiting-header": "Esperant els companys...", - "generating-header": "Generant codis..." - }, - "set-config": { - "bft-explanation-title": "Tolerància a fallades bizantines de la teva federació", - "bft-explanation": "Una {{total}} Federació de Guardians crea un {{honest}}/{{total}} Llimitat.", - "bft-faulty": "La teva Federació podrà tolerar {{faulty}} Guardians defectuosos, fora de línia o maliciosos sense afectar les operacions de la Federació.", - "guardian-name": "Nom del guardian", - "guardian-name-help": "Aquest nom aleatori es mostrarà a altres Guardians durant la configuració.", - "admin-password": "Contrasenya d'administrador", - "admin-password-generate": "Generar", - "admin-password-set": "Fes clic a 'Generar' per crear una contrasenya segura. La pots modificar, però aquesta contrasenya ha de ser segura i estar respaldada!", - "admin-password-help": "Fes una còpia d'aquesta contrasenya i guarda-la bé! No pots recuperar aquesta contrasenya!", - "admin-password-backup": "Estic utilitzant una contrasenya forta i l'he fet una còpia de seguretat. (No podeu recuperar aquesta contrasenya!)", - "confirm-password": "Confirma la contrasenya", - "error-password-mismatch": "Les contrasenyes no coincideixen", - "join-federation": "Uneix-te al vincle de la Federació", - "join-federation-help": "Demana a la persona que va crear la Federació un enllaç i enganxa'l aquí.", - "basic-settings": "Fonaments", - "federation-settings": "Configuració de la federació", - "federation-name": "Nom de la federació", - "guardian-number": "Nombre de guardians", - "guardian-number-help": "Les federacions requereixen un mínim de 4 guardians. Això no es pot canviar més tard.", - "bitcoin-settings": "Configuració de Bitcoin", - "block-confirmations": "Confirmacions addicionals de blocs", - "block-confirmations-help": "Els guardians de Fedimint segueixen el bloc de la cadena amb diversos confirmacions per evitar reorganitzacions de blocs.", - "block-confirmations-warning": "Executar Fedimint amb menys de 5 confirmacions addicionals de blocs és extremadament arriscat! Fedimint NO POT gestionar reorganitzacions de blockchain.", - "bitcoin-network": "Xarxa Bitcoin", - "select-network": "Selecciona una xarxa", - "set-rpc-help": "Adreça RPC de Bitcoin configurada localment", - "bitcoin-rpc": "Bitcoin RPC", - "error-valid-number": "Si us plau, introdueix un número vàlid.", - "error-valid-min": "Si us plau, introdueix un número d'almenys {{min}}.", - "error-valid-max": "Si us plau, introdueix un número com a màxim {{max}}.", - "error-valid-min-max": "Si us plau, introdueix un número entre {{min}} i {{max}}.", - "meta-fields": "Meta camps", - "meta-fields-description": "Vegeu documentació per a més informació.", - "meta-fields-key": "Clau meta", - "meta-fields-value": "Valor", - "meta-fields-effect": "Efecte", - "meta-fields-add-another": "Afegeix un altre", - "meta-fields-title": "La teva proposta Meta:", - "password-warning": "Has de fer una còpia de seguretat de la teva contrasenya i guardar-la en un lloc segur. Aquesta contrasenya és necessària per accedir al teu tauler de guardians. No pots recuperar-la si la perds!", - "password-warning-title": "Fes una còpia de seguretat de la teva contrasenya!", - "acknowledge-backed-up": "Jo, {{guardianName}} (el teu nom de tutor), prometo que he fet una còpia de seguretat i he assegurat la meva contrasenya:", - "confirm-and-backup-password": "Confirma i copia la contrasenya", - "error-guardian-name-mismatch": "El nom del guardian no coincideix.", - "network": "Xarxa" - }, - "setup": { - "common": { - "restart-setup": "Reinicia la configuració", - "restart-setup-alert": "El líder de configuración ha reiniciado la ceremonia de configuración. Por favor, haga clic en \"Reiniciar\" a continuación para continuar.", - "confirm-restart-setup": "Estàs segur que vols reiniciar la Cerimònia d'Instal·lació?", - "confirm-restart-setup-alert": "Fent clic a \"Reiniciar\" es reiniciarà la cerimònia per a tots els Guardians." - }, - "progress": { - "tos": { - "title": "Termes de servei" - }, - "start": { - "title": "Benvingut, Guardian!", - "subtitle": "Anem a configurar la teva federació.", - "step": "Detalls de la federació" - }, - "set-config": { - "title": "Necessitem establir algunes configuracions per a la teva Federació.", - "title-solo": "Hem necessitat de configurar algunes opcions per a la teva Federació Solo.", - "subtitle-leader": "Els teus seguidors de la Federació confirmaran aquesta informació per la seva banda.", - "subtitle-solo": "Executar una Federació en Solitari perd molts dels beneficis de Fedimint. No tindràs tolerància a fallades en el consens si un guardian està fora de línia i no podràs fer còpies de seguretat federades. Procedeix amb precaució, no es recomana per a ús en producció ni per a l'ús amb Bitcoin de mainnet.", - "subtitle-follower": "El teu líder de federació establirà els detalls principals de la federació. Els confirmaràs aviat.", - "step": "Detalls de la federació" - }, - "connect-guardians": { - "title-leader": "Convida els teus Guardians", - "title-follower": "Confirma la teva informació de Federació", - "subtitle-leader": "Comparte el enlace amb els altres Guardians per fer que tothom estigui al mateix nivell. Un cop tots els Guardians s'uneixin, passaràs automàticament al següent pas.", - "subtitle-follower": "Assegura't que la informació aquí sigui correcta i que els Guardians de la Federació ho siguin. Fes clic al botó Aprovar quan estiguis segur que tot es veu bé.", - "step-leader": "Convida Guardians", - "step-follower": "Confirma informació" - }, - "run-dkg": { - "title": "Èxit!", - "subtitle": "Tots els Guardians han validat els detalls de configuració de la federació. Estic fent alguns càlculs..." - }, - "verify-guardians": { - "title": "Verifica els teus Guardians", - "subtitle": "Demana a cada Guardian el seu codi de verificació i enganxa'ls a continuació per comprovar la validesa. Ja estem gairebé acabats!", - "step": "Verifica guardians", - "leader-confirm-done": "Confirmeu que tots els Guardians seguidors han fet clic a \"Següent\" i veieu els seus taulers de guardians abans de continuar.", - "leader-confirm-done-emphasis": "Fent clic a \"Continuar\" es completarà la cerimònia de configuració." - }, - "setup-complete": { - "step": "Fet!" - }, - "error": { - "title": "Pas desconegut", - "subtitle": "Com vas arribar aquí?!" - } - }, - "warning": { - "title": "No sortiu ni actualitzeu durant la configuració!", - "description": "Sortir durant la configuració pot fer que la configuració falli i haureu de fer un reinici complet." - } - }, - "setup-complete": { - "header": "🎉 🎉 🎉", - "congratulations": "Felicitats", - "leader-message": "Tots els codis de verificació dels Guardians han estat verificats.", - "follower-message": "Ja ho has acabat! Fes saber als altres Guardians que estàs en marxa!", - "continue": "Continuar" - }, - "terms-of-service": { - "agree-and-continue": "Acceptar i continuar" - }, - "verify-guardians": { - "verified": "Verificat", - "verified-placeholder": "Enganxa codi aquí", - "error": "Alguna cosa ha anat malament.", - "error-peer-id": "No es pot determinar quin company ets. Si us plau, actualitza i torna a provar.", - "verification-code": "El teu codi de verificació", - "verification-code-help": "Comparte este codi amb altres guardians", - "table-title": "Codis de verificació del guardian", - "table-description": "Introduïu els codis de verificació de cada Guardian a continuació.", - "table-column-name": "Nom", - "table-column-status": "Estat", - "table-column-hash-input": "Enganxa el codi de verificació", - "wait-all-guardians-verification": "Esperant que tots els Guardians verifiquin els seus codis", - "all-guardians-verified": "Tots els Guardians han verificat els seus codis.", - "starting-consensus": "Iniciant consens..." - }, - "footer": { - "docs-section-header": "Docs", - "community-section-header": "Comunitat", - "contribute-section-header": "Contribuir", - "getting-started-link-text": "Començant", - "faq-link-text": "Preguntes Freqüents", - "blog-link-text": "Bloc", - "discord-link-text": "Discord", - "twitter-link-text": "Twitter", - "github-link-text": "GitHub" - } -} diff --git a/apps/guardian-ui/src/languages/de.json b/apps/guardian-ui/src/languages/de.json deleted file mode 100644 index 0f746bb4b..000000000 --- a/apps/guardian-ui/src/languages/de.json +++ /dev/null @@ -1,344 +0,0 @@ -{ - "common": { - "bitcoin": "Bitcoin", - "next": "Nächste", - "back": "Zurück", - "error": "Etwas ist schiefgegangen.", - "unknown": "Unbekannt", - "remove": "Entfernen", - "copy": "Kopieren", - "copied": "Kopiert!", - "cancel": "Stornieren", - "review": "Überprüfung", - "approvals": "Genehmigungen", - "approve": "Genehmigen", - "threshold": "Schwelle", - "confirm": "Bestätigen", - "you": "Du", - "close": "Schließen", - "save": "Speichern", - "continue": "Fortsetzen", - "submit": "Einreichen" - }, - "notConfigured": { - "title": "Nicht konfiguriert", - "description": "Bitte geben Sie die CONFIG_API_URL des Fedimint-Wächter-Servers ein, um fortzufahren." - }, - "connect-guardians": { - "invite-guardians": "Follower einladen", - "invite-guardians-help": "Teile diesen Link mit den anderen Wächtern.", - "approve": "Genehmigen", - "approved": "Genehmigt", - "pending": "Ausstehend", - "not-joined": "Nicht beigetreten", - "waiting-for-guardian": "Warten auf den Vormund", - "table-title": "Föderationswächter", - "table-description": "Wächter werden hier bestätigt, sobald sie die Föderationseinstellungen bestätigen.", - "meta-field-key": "Meta-Feld - {{key}}" - }, - "federation-dashboard": { - "invite-members": "Lade Mitglieder ein oder authentifiziere dich als Wächter", - "invite-members-prompt": "Teile dies, um Mitglieder einzuladen, der Föderation beizutreten.", - "fed-info": { - "label": "Föderationsinfo", - "your-status-label": "Status", - "block-count-label": "Konsens-Blockhöhe", - "api-version-label": "API-Version", - "consensus-version-label": "Konsensversion", - "peer-id-label": "Peer-ID", - "session-info": { - "session-height": "Sitzungshöhe", - "latest-session": "Neueste Sitzung" - } - }, - "balance": { - "label": "Bilanz" - }, - "bitcoin-node": { - "label": "Bitcoin-Knoten", - "url-label": "URL", - "network-label": "Netzwerk" - }, - "guardians": { - "label": "Andere Wächter", - "id-name-label": "ID: Name", - "status-label": "Verbindungsstatus", - "health-label": "Gesundheit", - "health-issue": "Problem", - "health-good": "Gut", - "last-contribution-label": "Letzter Sitzungsbeitrag", - "api-url-label": "API-URL", - "fetching-announcement": "Abrufen der Ankündigung..." - }, - "gateways": { - "label": "Blitz-Gateways", - "node-id-label": "Lightning-Knoten-ID", - "gateway-id-label": "Gateway-ID", - "fee-label": "Gateway-Gebühr", - "view-on-site": "Ansicht auf {{site}}", - "no-gateways-info-title": "Noch keine verbundenen Gateways!", - "no-gateways-info-description": "Lightning-Node-Betreiber können sich mit Ihrer Föderation verbinden, um die Interoperabilität des Lightning-Netzwerks bereitzustellen. Sobald sie verbunden sind, werden sie hier angezeigt." - }, - "api-announcements": { - "label": "API-Ankündigungen", - "guardian": "Wächter", - "api-url": "API-URL", - "revision": "Überarbeitung" - }, - "config": { - "label": "Föderationskonfiguration", - "view-config": "Konfiguration anzeigen", - "missing-meta-module": "Das Bearbeiten von Meta-Feldern ist nicht möglich. Das Meta-Modul ist für diese Föderation nicht verfügbar.", - "manage-meta": { - "label": "Meta verwalten", - "cancel-button": "Stornieren", - "confirm-modal": { - "title": "Genehmigung bestätigen", - "description": "Ihre Genehmigung wird die Schwelle erreichen, um diese Meta-Änderung anzunehmen. Ihre neue Meta wird folgendermaßen aussehen:" - }, - "consensus-meta-label": "Aktuelles Meta im Konsens", - "revoke-button": "Widerrufen", - "no-consensus-meta-message": "es gibt keine Metadaten im Konsens", - "proposed-meta-label": "Meta-Vorschläge", - "propose-meta": "Meta vorschlagen", - "propose-new-meta-button": "Neues Meta vorschlagen", - "proposal-approved": "Sie haben diesen Vorschlag genehmigt.", - "no-submitted-meta-message": "Es gibt keine Meta-Änderungen zu überprüfen.", - "edit-meta-label": "Meta bearbeiten", - "edit-consensus-meta-button": "Bearbeite Konsens-Meta", - "submit-meta-proposal": "Meta-Vorschlag einreichen", - "peer-approvals": "Peer-Genehmigungen", - "actions": "Aktionen", - "revision": "Überarbeitung", - "setup-meta-title": "Ein Meta für Ihre Föderation einrichten", - "setup-meta-description": "Fedimint kann zusätzlichen Informationen in Form von Metafeldern an Kunden bereitstellen: Schlüssel-Wert-Paare mit beliebigen Informationen, die Sie möglicherweise mit Kunden teilen möchten. Während diese Metafelder von Fedimint nicht interpretiert werden, sind sie konsensrelevant, d.h. sie dürfen zwischen den Mitgliedern der Föderation nicht abweichen. Auf diese Weise können sich die Kunden auf ihre Richtigkeit verlassen.", - "propose-updates": "Als Fedimint-Wächter kannst du Updates für das Meta vorschlagen, die von den anderen Wächtern akzeptiert werden. Sobald das Update von einer Schwelle von Wächtern akzeptiert wird, wird es als das neue Konsens-Meta für die Föderation angenommen.", - "core-meta-fields": "Die folgenden Metafelder wurden als Teil des Kernprotokolls von Fedimint definiert und sind nützlich, um sie in die Metadaten Ihrer Föderation aufzunehmen:", - "meta-field-expiry": "Ein Unix-Zeitstempel, nach dem die Föderation heruntergefahren wird.", - "meta-field-name": "Der menschenlesbare Name der Föderation", - "meta-field-icon": "Eine URL zu einem Logo-Icon für die Föderation", - "meta-field-welcome": "Eine Willkommensnachricht für neue Benutzer, die der Föderation beitreten.", - "meta-field-gateways": "Eine Liste von Gateway-Identifikatoren, die von der Föderation geprüft wurden.", - "your-own-fields": "Sie können auch Ihre eigenen beliebigen Metafelder zum Vorschlag hinzufügen. Diese werden dem Meta aller Clients hinzugefügt, die mit Ihrer Föderation verbunden sind, und können für jeden Zweck verwendet werden, den Sie wünschen.", - "meta-effect-add": "Hinzufügen", - "meta-effect-modify": "Ändern", - "meta-effect-unchanged": "Unverändert", - "proposals": "Vorschläge" - } - }, - "modal": { - "client-connect": "Einen Client verbinden" - }, - "danger-zone": { - "danger-zone-label": "Gefahrenzone", - "cancel": "Stornieren", - "danger-zone-description": "Vorsicht!", - "guardian-warning-message": "WARNUNG: Teilen Sie diesen Code nicht mit jemandem. Jeder, der diesen Code hat, kann sich als Guardian authentifizieren. Stellen Sie sicher, dass Sie sich an einem privaten Ort befinden und niemand Ihren Bildschirm beobachtet.", - "guardian-acknowledge": "Bestätigen und Enthüllen Code", - "acknowledge-and-download": "Bestätigen & Fortfahren", - "guardian-authenticate": "Als Guardian authentifizieren", - "guardian-connect-warning": "TEILEN SIE DAS NICHT", - "backup": { - "label": "Sicherung", - "title": "Backup herunterladen", - "warning-title": "Warnung", - "warning-text": "Das Backup enthält private Schlüssel und geheime Materialien für den Föderationswächter und muss sicher aufbewahrt werden. Die Wiederherstellung mit diesem Backup erfordert Ihr Administratorkennwort!", - "cancelButton": "Stornieren", - "acknowledgeButton": "Annehmen & Herunterladen" - }, - "sign-api-announcement": { - "label": "Sign API Ankündigung", - "title": "Sign API Ankündigung", - "description": "Unterzeichnen Sie eine neue API-Ankündigung.", - "current-api-url": "Ihre API-URL aus der lokalen Konfiguration", - "announced-api-url": "Ihre API-URL von den Föderationsankündigungen", - "urls-match": "Ihre aktuelle API-URL stimmt mit Ihrer angekündigten API-URL überein.", - "urls-mismatch": "Sie haben die API-URL in Ihrer lokalen Konfiguration geändert und müssen eine neue API-Ankündigung verbreiten.", - "sign-button": "Neue API-Ankündigung unterzeichnen", - "signing-in-progress": "Anmeldung läuft...", - "sign-tooltip": "Unterzeichnen Sie die API-Ankündigung, um Ihre API-URL an die Föderation bekannt zu geben." - }, - "schedule-shutdown": { - "label": "Geplante Abschaltung", - "title": "Geplante Abschaltung", - "description": "Planen Sie, dass Ihr Guardian-Knoten nach einer bestimmten Sitzungs-Höhe heruntergefahren wird, um ein koordiniertes Upgrade Ihrer Fedimintd-Binärdateien durchzuführen.", - "current-session": "Aktuelle Sitzung", - "session-to-shutdown": "Sitzung wird heruntergefahren um", - "confirm-shutdown": "Shutdown bestätigen", - "session-to-shutdown-helper": "Geben Sie die Sitzungsgröße ein, bei der Sie Ihren Guardian-Knoten herunterfahren möchten." - } - } - }, - "login": { - "title": "Willkommen zurück!", - "subtitle": "Bitte geben Sie Ihr Passwort ein.", - "password": "Passwort", - "submit": "Einreichen" - }, - "role-selector": { - "disclaimer-title": "Fedimint ist Beta-Software", - "disclaimer-text": "Bitte melde Probleme unter https://github.com/fedimint/fedimint/issues", - "leader": { - "label": "Einrichtungsleiter", - "description": "Geben Sie Konfigurationseinstellungen ein, die von anderen Hütern genehmigt werden. Ein Hüter fungiert als Setup-Leiter." - }, - "follower": { - "label": "Follower", - "description": "Sobald ein Setup-Leiter die Konfigurationen festgelegt hat, wählen andere Wächter diese Option, um die Einstellungen zu genehmigen und die Föderation zu gründen." - }, - "solo": { - "label": "Allein", - "description": "Betreiben Sie Fedimint als Solo Guardian ohne Konsens, Fehlertoleranz, föderierte Backups oder andere Resilienzvorteile von Fedimint. Gehen Sie vorsichtig vor, nicht für den produktiven Einsatz gedacht." - }, - "warning-modal": { - "title": "Ist jeder bereit?", - "description": "Das Verlassen der Einrichtungszeremonie kann dazu führen, dass die Einrichtung fehlschlägt und Sie Ihren Wächter neu starten müssen. Stellen Sie sicher, dass alle bereit sind, die vollständige Einrichtung durchzuführen, bevor Sie fortfahren!" - } - }, - "run-dkg": { - "error-config": "Fehler beim Ausführen der verteilten Schlüsselgenerierung. Die Federation-Konfiguration muss neu gestartet werden.", - "error-default": "Nicht bereit für DKG, Ihr aktueller Status ist", - "error-header": "Etwas ist schiefgelaufen.", - "waiting-header": "Warten auf Peers...", - "generating-header": "Codes generieren..." - }, - "set-config": { - "bft-explanation-title": "Byzantinische Fehlertoleranz Ihrer Föderation", - "bft-explanation": "Eine {{total}} Wächterföderation schafft einen {{honest}}/{{total}} Schwellenwert.", - "bft-faulty": "Ihre Föderation wird in der Lage sein, {{faulty}} fehlerhafte, offline oder böswillige Wächter zu tolerieren, ohne die Operationen der Föderation zu beeinträchtigen.", - "guardian-name": "Wächtername", - "guardian-name-help": "Dieser zufällige Name wird anderen Hütern während der Einrichtung angezeigt.", - "admin-password": "Admin-Passwort", - "admin-password-generate": "Generieren", - "admin-password-set": "Klicken Sie auf 'Generieren', um ein sicheres Passwort zu erstellen. Sie können es ändern, aber dieses Passwort muss sicher und gesichert sein!", - "admin-password-help": "Sichern Sie dieses Passwort und bewahren Sie es sicher auf! Sie können dieses Passwort nicht wiederherstellen!", - "admin-password-backup": "Ich benutze ein starkes Passwort und habe es gesichert. (Sie können dieses Passwort nicht wiederherstellen!)", - "confirm-password": "Passwort bestätigen", - "error-password-mismatch": "Passwörter stimmen nicht überein", - "join-federation": "Beitreten Föderationslink", - "join-federation-help": "Frag die Person, die die Föderation erstellt hat, nach einem Link und füge ihn hier ein.", - "basic-settings": "Grundlagen", - "federation-settings": "Föderationseinstellungen", - "federation-name": "Föderationsname", - "guardian-number": "Anzahl der Wächter", - "guardian-number-help": "Föderationen benötigen mindestens 4 Wächter. Dies kann später nicht geändert werden.", - "bitcoin-settings": "Bitcoin-Einstellungen", - "block-confirmations": "Zusätzliche Blockbestätigungen", - "block-confirmations-help": "Fedimint-Wächter verfolgen die Blockchain-Spitze mit mehreren Bestätigungen, um Blockumorganisationen zu vermeiden.", - "block-confirmations-warning": "Das Ausführen von Fedimint mit weniger als 5 zusätzlichen Blockbestätigungen ist äußerst riskant! Fedimint KANN keine Blockchain-Reorganisationen verarbeiten.", - "bitcoin-network": "Bitcoin-Netzwerk", - "select-network": "Wählen Sie ein Netzwerk aus", - "set-rpc-help": "Lokal konfigurierten Bitcoin RPC-Adresse", - "bitcoin-rpc": "Bitcoin RPC", - "error-valid-number": "Bitte geben Sie eine gültige Nummer ein.", - "error-valid-min": "Bitte geben Sie eine Zahl von mindestens {{min}} ein.", - "error-valid-max": "Bitte geben Sie eine Zahl von höchstens {{max}} ein.", - "error-valid-min-max": "Bitte geben Sie eine Zahl zwischen {{min}} und {{max}} ein.", - "meta-fields": "Meta-Felder", - "meta-fields-description": "Siehe Dokumentation für weitere Informationen.", - "meta-fields-key": "Meta-Taste", - "meta-fields-value": "Wert", - "meta-fields-effect": "Effekt", - "meta-fields-add-another": "Füge einen weiteren hinzu", - "meta-fields-title": "Ihr Meta-Vorschlag:", - "password-warning": "Sie müssen eine Sicherung Ihres Passworts machen und es sicher aufbewahren. Dieses Passwort ist erforderlich, um auf Ihren Wächter-Dashboard zuzugreifen. Sie können es nicht wiederherstellen, wenn Sie es verlieren!", - "password-warning-title": "Sichern Sie Ihr Passwort!", - "acknowledge-backed-up": "Ich, {{guardianName}} (dein Wächtername), verspreche, dass ich mein Passwort gesichert und gesichert habe:", - "confirm-and-backup-password": "Passwort bestätigen und sichern", - "error-guardian-name-mismatch": "Der Name des Vormunds stimmt nicht überein.", - "network": "Netzwerk" - }, - "setup": { - "common": { - "restart-setup": "Setup neu starten", - "restart-setup-alert": "Der Setup-Leiter hat die Setup-Zeremonie neu gestartet. Bitte klicken Sie unten auf \"Neustarten\", um fortzufahren.", - "confirm-restart-setup": "Sind Sie sicher, dass Sie die Einrichtungszeremonie neu starten möchten?", - "confirm-restart-setup-alert": "Durch Klicken auf \"Neustart\" wird die Zeremonie für alle Wächter neu gestartet." - }, - "progress": { - "tos": { - "title": "Nutzungsbedingungen" - }, - "start": { - "title": "Willkommen, Wächter!", - "subtitle": "Lass uns deine Föderation einrichten.", - "step": "Föderationsdetails" - }, - "set-config": { - "title": "Wir müssen einige Konfigurationen für Ihre Föderation festlegen.", - "title-solo": "Wir müssen einige Konfigurationen für Ihre Solo-Föderation festlegen.", - "subtitle-leader": "Ihre Föderationsanhänger werden diese Informationen auf ihrer Seite bestätigen.", - "subtitle-solo": "Das Betreiben einer Solo-Föderation verliert viele der Vorteile von Fedimint. Sie werden keine Fehlertoleranz-Konsens haben, wenn ein Guardian offline ist, und können keine föderierten Backups durchführen. Gehen Sie vorsichtig vor, nicht empfohlen für den Produktionsgebrauch oder die Verwendung mit Mainnet Bitcoin.", - "subtitle-follower": "Ihr Föderationsleiter wird die Hauptdetails der Föderation einrichten. Sie werden diese bald bestätigen.", - "step": "Föderationsdetails" - }, - "connect-guardians": { - "title-leader": "Lade deine Wächter ein", - "title-follower": "Bestätigen Sie Ihre Föderationsinformationen", - "subtitle-leader": "Teile den Link mit den anderen Wächtern, um alle auf denselben Stand zu bringen. Sobald alle Wächter beitreten, wirst du automatisch zum nächsten Schritt übergehen.", - "subtitle-follower": "Stellen Sie sicher, dass die Informationen hier korrekt sind und dass die Föderationswächter richtig sind. Klicken Sie auf die Schaltfläche Genehmigen, wenn Sie sicher sind, dass alles gut aussieht.", - "step-leader": "Lade Wächter ein", - "step-follower": "Bestätige Informationen" - }, - "run-dkg": { - "title": "Erfolg!", - "subtitle": "Alle Wächter haben die Details zur Einrichtung der Föderation validiert. Einige Zahlen werden berechnet..." - }, - "verify-guardians": { - "title": "Überprüfen Sie Ihre Wächter", - "subtitle": "Frage jeden Wächter nach seinem Verifizierungscode und füge ihn unten ein, um die Gültigkeit zu überprüfen. Wir sind fast fertig!", - "step": "Überprüfen Sie die Vormünder", - "leader-confirm-done": "Bestätigen Sie, dass alle nachfolgenden Wächter auf \"Weiter\" geklickt haben und sehen Sie sich ihre Wächter-Dashboards an, bevor Sie fortfahren.", - "leader-confirm-done-emphasis": "Durch Klicken auf \"Weiter\" wird die Einrichtungszeremonie abgeschlossen." - }, - "setup-complete": { - "step": "Fertig!" - }, - "error": { - "title": "Unbekannter Schritt", - "subtitle": "Wie bist du hierher gekommen?!" - } - }, - "warning": { - "title": "Verlassen Sie nicht oder aktualisieren Sie während der Einrichtung!", - "description": "Ein Abbruch während der Einrichtung kann dazu führen, dass die Einrichtung fehlschlägt, und Sie müssen einen neuen Neustart durchführen." - } - }, - "setup-complete": { - "header": "🎉 🎉 🎉", - "congratulations": "Herzlichen Glückwunsch", - "leader-message": "Alle Verifizierungscodes der Wächter wurden überprüft.", - "follower-message": "Du bist fertig! Lass die anderen Wächter wissen, dass du läufst!", - "continue": "Fortsetzen" - }, - "terms-of-service": { - "agree-and-continue": "Zustimmen & fortfahren" - }, - "verify-guardians": { - "verified": "Verifiziert", - "verified-placeholder": "Code hier einfügen", - "error": "Etwas ist schiefgelaufen.", - "error-peer-id": "Kann nicht bestimmt werden, welcher Peer Sie sind. Bitte aktualisieren Sie und versuchen Sie es erneut.", - "verification-code": "Ihr Bestätigungscode", - "verification-code-help": "Teile diesen Code mit anderen Wächtern.", - "table-title": "Guardian-Verifizierungscodes", - "table-description": "Geben Sie unten die Bestätigungscodes jedes Guardians ein.", - "table-column-name": "Name", - "table-column-status": "Status", - "table-column-hash-input": "Überprüfungs-Code einfügen", - "wait-all-guardians-verification": "Warten auf alle Wächter, um ihre Codes zu überprüfen", - "all-guardians-verified": "Alle Wächter haben ihre Codes verifiziert.", - "starting-consensus": "Konsens beginnen..." - }, - "footer": { - "docs-section-header": "Dokumente", - "community-section-header": "Gemeinschaft", - "contribute-section-header": "Beitragen", - "getting-started-link-text": "Erste Schritte", - "faq-link-text": "Häufig gestellte Fragen", - "blog-link-text": "Blog", - "discord-link-text": "Discord", - "twitter-link-text": "Twitter", - "github-link-text": "GitHub" - } -} diff --git a/apps/guardian-ui/src/languages/es.json b/apps/guardian-ui/src/languages/es.json deleted file mode 100644 index a086aa825..000000000 --- a/apps/guardian-ui/src/languages/es.json +++ /dev/null @@ -1,347 +0,0 @@ -{ - "label": "Firmar anuncio de API", - "title": "Firmar anuncio de API", - "description": "Firme un nuevo anuncio de API.", - "common": { - "bitcoin": "Bitcoin", - "next": "Siguiente", - "back": "Atrás", - "error": "Algo salió mal.", - "unknown": "Desconocido", - "remove": "Eliminar", - "copy": "Copiar", - "copied": "¡Copiado!", - "cancel": "Cancelar", - "review": "Revisión", - "approvals": "Aprobaciones", - "approve": "Aprobar", - "threshold": "Umbral", - "confirm": "Confirmar", - "you": "Tú", - "close": "Cerrar", - "save": "Guardar", - "continue": "Continuar", - "submit": "Enviar" - }, - "notConfigured": { - "title": "No configurado", - "description": "Por favor, ingrese la URL del servidor de configuración de Fedimint para continuar." - }, - "connect-guardians": { - "invite-guardians": "Invitar seguidores", - "invite-guardians-help": "Comparte este enlace con los otros Guardianes.", - "approve": "Aprobar", - "approved": "Aprobado", - "pending": "Pendiente", - "not-joined": "No unido", - "waiting-for-guardian": "Esperando al guardián", - "table-title": "Guardianes de la Federación", - "table-description": "Los guardianes se confirmarán aquí una vez que confirmen la configuración de la Federación.", - "meta-field-key": "Campo meta - {{key}}" - }, - "federation-dashboard": { - "invite-members": "Invitar miembros o autenticar como un guardián", - "invite-members-prompt": "Comparte esto para invitar a miembros a unirse a la federación.", - "fed-info": { - "label": "Información de la Federación", - "your-status-label": "Estado", - "block-count-label": "Altura del bloque de consenso", - "api-version-label": "versión de la API", - "consensus-version-label": "Versión de consenso", - "peer-id-label": "ID de compañero", - "session-info": { - "session-height": "Altura de la sesión", - "latest-session": "Última sesión" - } - }, - "balance": { - "label": "Balance General" - }, - "bitcoin-node": { - "label": "Nodo de Bitcoin", - "url-label": "URL", - "network-label": "Red" - }, - "guardians": { - "label": "Otros Guardianes", - "id-name-label": "ID: Nombre", - "status-label": "Estado de conexión", - "health-label": "Salud", - "health-issue": "Problema", - "health-good": "Bueno", - "last-contribution-label": "Última contribución de sesión", - "api-url-label": "URL de la API", - "fetching-announcement": "Obteniendo anuncio..." - }, - "gateways": { - "label": "Puertas Relámpago", - "node-id-label": "ID de Nodo Lightning", - "gateway-id-label": "ID de puerta de enlace", - "fee-label": "Tarifa de puerta", - "view-on-site": "Ver en {{site}}", - "no-gateways-info-title": "¡No hay puertas de enlace conectadas aún!", - "no-gateways-info-description": "Los operadores de nodos Lightning pueden conectarse a tu federación para proporcionar interoperabilidad de la Lightning Network. Una vez conectados, aparecerán aquí." - }, - "api-announcements": { - "label": "Anuncios de API", - "guardian": "Guardia", - "api-url": "URL de la API", - "revision": "Revisión" - }, - "config": { - "label": "Configuración de Federación", - "view-config": "Ver configuración", - "missing-meta-module": "No es posible editar los campos Meta. El módulo Meta no está disponible para esta federación.", - "manage-meta": { - "label": "Gestionar Meta", - "cancel-button": "Cancelar", - "confirm-modal": { - "title": "Confirmar Aprobación", - "description": "Su aprobación alcanzará el umbral para adoptar este cambio meta. Su nueva meta se verá así:" - }, - "consensus-meta-label": "Meta actual en consenso", - "revoke-button": "Revocar", - "no-consensus-meta-message": "no hay meta en el consenso", - "proposed-meta-label": "Propuestas Meta", - "propose-meta": "Proponer Meta", - "propose-new-meta-button": "Proponer nuevo meta", - "proposal-approved": "Has aprobado esta propuesta.", - "no-submitted-meta-message": "no hay ediciones meta para revisar", - "edit-meta-label": "Editar meta", - "edit-consensus-meta-button": "Editar Meta de Consenso", - "submit-meta-proposal": "Enviar propuesta de Meta", - "peer-approvals": "Aprobaciones de compañeros", - "actions": "Acciones", - "revision": "Revisión", - "setup-meta-title": "Configurando un Meta para tu Federación", - "setup-meta-description": "Fedimint puede proporcionar información adicional a los clientes en forma de campos meta: pares de clave-valor con información arbitraria que desees compartir con los clientes. Aunque estos campos meta no son interpretados por Fedimint, son relevantes para el consenso, es decir, no pueden diferir entre los miembros de la federación. De esta manera, los clientes pueden confiar en su corrección.", - "propose-updates": "Como guardián de fedimint, puedes proponer actualizaciones al meta que serán aceptadas por los otros guardianes. Una vez que la actualización sea aceptada por un umbral de guardianes, se adoptará como el nuevo meta de consenso para la federación.", - "core-meta-fields": "Los siguientes campos meta se han definido como parte del protocolo central de Fedimint y son útiles para incluir en el meta de su federación:", - "meta-field-expiry": "Un timestamp de Unix después del cual la federación se cerrará.", - "meta-field-name": "El nombre legible por humanos de la federación", - "meta-field-icon": "Una URL a un ícono de logo para la federación", - "meta-field-welcome": "Un mensaje de bienvenida para los nuevos usuarios que se unen a la federación.", - "meta-field-gateways": "Una lista de identificadores de puerta de enlace verificados por la federación", - "your-own-fields": "También puedes agregar tus propios campos meta arbitrarios a la propuesta. Estos se añadirán a la meta de todos los clientes que se conecten a tu federación y se pueden utilizar para cualquier propósito que desees.", - "meta-effect-add": "Agregar", - "meta-effect-modify": "Modificar", - "meta-effect-unchanged": "Sin cambios", - "proposals": "Propuestas" - } - }, - "modal": { - "client-connect": "Conectar un cliente" - }, - "danger-zone": { - "danger-zone-label": "Zona de Peligro", - "cancel": "Cancelar", - "danger-zone-description": "¡Usar con precaución!", - "guardian-warning-message": "ADVERTENCIA: No compartas este código con nadie. Cualquiera que tenga este código puede autenticarse como un Guardián. Asegúrate de estar en un lugar privado y de que nadie esté mirando tu pantalla.", - "guardian-acknowledge": "Reconocer y Revelar Código", - "acknowledge-and-download": "Reconocer y Proceder", - "guardian-authenticate": "Autenticarse como Guardián", - "guardian-connect-warning": "NO COMPARTAS ESTO", - "backup": { - "label": "Copia de seguridad", - "title": "Descargar copia de seguridad", - "warning-title": "Advertencia", - "warning-text": "La copia de seguridad contiene claves privadas y material secreto para el guardián de la federación y debe mantenerse seguro. ¡La recuperación utilizando esta copia de seguridad requiere tu contraseña de administrador!", - "cancelButton": "Cancelar", - "acknowledgeButton": "Reconocer y Descargar" - }, - "sign-api-announcement": { - "label": "Anuncio de la API de Firmas", - "title": "Anuncio de la API de Firmas", - "description": "Firmar un nuevo anuncio de API.", - "current-api-url": "Tu URL de API de Configuración Local", - "announced-api-url": "Tu URL de API de Anuncios de Federación", - "urls-match": "La URL de tu API actual coincide con la URL de tu API anunciada.", - "urls-mismatch": "Has cambiado la URL de la API en tu configuración local y necesitas hacer un nuevo anuncio de la API.", - "sign-button": "Anuncio de nueva API", - "signing-in-progress": "Iniciando sesión...", - "sign-tooltip": "Firma el anuncio de la API para anunciar tu URL de API a la federación." - }, - "schedule-shutdown": { - "label": "Programar Apagado", - "title": "Programar Apagado", - "description": "Programa tu nodo guardián para que se apague después de una altura de sesión específica para una actualización coordinada de tus binarios de fedimintd.", - "current-session": "Sesión actual", - "session-to-shutdown": "Sesión para apagar en", - "confirm-shutdown": "Confirmar apagado", - "session-to-shutdown-helper": "Ingresa la altura de la sesión en la que deseas apagar tu nodo guardián." - } - } - }, - "login": { - "title": "¡Bienvenido de nuevo!", - "subtitle": "Por favor, introduce tu contraseña.", - "password": "Contraseña", - "submit": "Enviar" - }, - "role-selector": { - "disclaimer-title": "Fedimint es un software beta.", - "disclaimer-text": "Por favor, informe de los problemas en https://github.com/fedimint/fedimint/issues", - "leader": { - "label": "Configuración de líder", - "description": "Ingrese la configuración que otros Guardianes aprueban. Un Guardián actúa como Líder de Configuración." - }, - "follower": { - "label": "Seguidor", - "description": "Una vez que un Líder de Configuración establece las configuraciones, otros Guardianes eligen esta opción para aprobar los ajustes y crear la Federación." - }, - "solo": { - "label": "Solo", - "description": "Opera Fedimint como un Guardián Solo sin consenso, tolerancia a fallos, copias de seguridad federadas u otros beneficios de resiliencia de Fedimint. Procede con precaución, no está destinado para uso en producción." - }, - "warning-modal": { - "title": "¿Está todo el mundo listo?", - "description": "Salir de la ceremonia de configuración puede hacer que la configuración falle y requerir que reinicies tu guardián. ¡Asegúrate de que todos estén listos para ejecutar la configuración completa antes de continuar!" - } - }, - "run-dkg": { - "error-config": "Error al ejecutar la generación de claves distribuida. La configuración de la federación debe reiniciarse.", - "error-default": "No estás listo para DKG, tu estado actual es", - "error-header": "Algo salió mal.", - "waiting-header": "Esperando a los compañeros...", - "generating-header": "Generando códigos..." - }, - "set-config": { - "bft-explanation-title": "Tolerancia a fallos bizantinos de su federación", - "bft-explanation": "Una {{total}} Federación de Guardianes crea un {{honesto}}/{{total}} Umbral.", - "bft-faulty": "Tu Federación podrá tolerar {{faulty}} Guardianes defectuosos, fuera de línea o maliciosos sin afectar las operaciones de la Federación.", - "guardian-name": "Nombre del guardián", - "guardian-name-help": "Este nombre aleatorio se mostrará a otros Guardianes durante la configuración.", - "admin-password": "Contraseña de administrador", - "admin-password-generate": "Generar", - "admin-password-set": "Haz clic en 'Generar' para crear una contraseña segura. Puedes modificarla, pero esta contraseña debe ser segura y estar respaldada.", - "admin-password-help": "¡Haz una copia de esta contraseña y guárdala en un lugar seguro! ¡No puedes recuperar esta contraseña!", - "admin-password-backup": "Estoy usando una contraseña fuerte y la he respaldado. (¡No puedes recuperar esta contraseña!)", - "confirm-password": "Confirmar contraseña", - "error-password-mismatch": "Las contraseñas no coinciden", - "join-federation": "Unirse al enlace de la Federación", - "join-federation-help": "Pide a la persona que creó la Federación un enlace y pégalo aquí.", - "basic-settings": "Conceptos básicos", - "federation-settings": "Configuraciones de la federación", - "federation-name": "Nombre de la federación", - "guardian-number": "Número de guardianes", - "guardian-number-help": "Las federaciones requieren un mínimo de 4 guardianes. Esto no se puede cambiar más tarde.", - "bitcoin-settings": "Configuraciones de Bitcoin", - "block-confirmations": "Confirmaciones de Bloque Adicionales", - "block-confirmations-help": "Los Guardianes de Fedimint siguen la punta de la blockchain por varias confirmaciones para evitar reorganizaciones de bloques.", - "block-confirmations-warning": "¡Ejecutar Fedimint con menos de 5 confirmaciones adicionales de bloque es extremadamente arriesgado! Fedimint NO PUEDE manejar reorganizaciones de blockchain.", - "bitcoin-network": "Red de Bitcoin", - "select-network": "Selecciona una red", - "set-rpc-help": "Dirección RPC de Bitcoin configurada localmente", - "bitcoin-rpc": "Bitcoin RPC", - "error-valid-number": "Por favor, introduce un número válido.", - "error-valid-min": "Por favor, introduce un número de al menos {{min}}.", - "error-valid-max": "Por favor, introduce un número de como máximo {{max}}.", - "error-valid-min-max": "Por favor, introduce un número entre {{min}} y {{max}}.", - "meta-fields": "Campos meta", - "meta-fields-description": "Consulta la documentación para más información.", - "meta-fields-key": "Clave meta", - "meta-fields-value": "Valor", - "meta-fields-effect": "Efecto", - "meta-fields-add-another": "Agregar otro", - "meta-fields-title": "Tu Propuesta Meta:", - "password-warning": "Debes hacer una copia de seguridad de tu contraseña y guardarla en un lugar seguro. Esta contraseña es necesaria para acceder a tu tablero de guardianes. ¡No puedes recuperarla si la pierdes!", - "password-warning-title": "¡Haz una copia de seguridad de tu contraseña!", - "acknowledge-backed-up": "Yo, {{guardianName}} (tu nombre de guardián), prometo que he respaldado y asegurado mi contraseña:", - "confirm-and-backup-password": "Confirmar y respaldar contraseña", - "error-guardian-name-mismatch": "El nombre del guardián no coincide.", - "network": "Red" - }, - "setup": { - "common": { - "restart-setup": "Reiniciar configuración", - "restart-setup-alert": "El Líder de Configuración ha reiniciado la Ceremonia de Configuración. Por favor, haga clic en \"Reiniciar\" a continuación para continuar.", - "confirm-restart-setup": "¿Estás seguro de que quieres reiniciar la Ceremonia de Configuración?", - "confirm-restart-setup-alert": "Hacer clic en \"Reiniciar\" reiniciará la ceremonia para todos los Guardianes." - }, - "progress": { - "tos": { - "title": "Términos de servicio" - }, - "start": { - "title": "¡Bienvenido, Guardián!", - "subtitle": "Vamos a configurar tu federación.", - "step": "Detalles de la federación" - }, - "set-config": { - "title": "Necesitamos establecer algunas configuraciones para tu Federación.", - "title-solo": "Necesitamos establecer algunas configuraciones para tu Federación Solo.", - "subtitle-leader": "Sus seguidores de la Federación confirmarán esta información por su parte.", - "subtitle-solo": "Ejecutar una Federación en solitario pierde muchos de los beneficios de Fedimint. No tendrás tolerancia a fallos en el consenso si un guardián está fuera de línea y no podrás realizar copias de seguridad federadas. Procede con precaución, no se recomienda para uso en producción o uso con Bitcoin en la red principal.", - "subtitle-follower": "Tu líder de Federación estará configurando los detalles principales de la Federación. Los confirmarás pronto.", - "step": "Detalles de la federación" - }, - "connect-guardians": { - "title-leader": "Invita a tus Guardianes", - "title-follower": "Confirma tu información de la Federación", - "subtitle-leader": "Comparte el enlace con los otros Guardianes para que todos estén en la misma página. Una vez que todos los Guardianes se unan, pasarás automáticamente al siguiente paso.", - "subtitle-follower": "Asegúrate de que la información aquí sea correcta y de que los Guardianes de la Federación estén correctos. Haz clic en el botón Aprobar cuando estés seguro de que se ve bien.", - "step-leader": "Invitar a los Guardianes", - "step-follower": "Confirmar información" - }, - "run-dkg": { - "title": "¡Éxito!", - "subtitle": "Todos los Guardianes han validado los detalles de configuración de la federación. Ejecutando algunos números..." - }, - "verify-guardians": { - "title": "Verifica tus Guardianes", - "subtitle": "Pide a cada Guardián su código de verificación y pégalo a continuación para comprobar su validez. ¡Estamos casi listos!", - "step": "Verificar tutores", - "leader-confirm-done": "Confirma que todos los Guardianes seguidores han hecho clic en \"Siguiente\" y ve sus paneles de control de guardianes antes de continuar.", - "leader-confirm-done-emphasis": "Hacer clic en \"Continuar\" completará la ceremonia de configuración." - }, - "setup-complete": { - "step": "¡Hecho!" - }, - "error": { - "title": "Paso desconocido", - "subtitle": "¿Cómo llegaste aquí?!" - } - }, - "warning": { - "title": "¡No salgas ni actualices durante la configuración!", - "description": "Salir durante la configuración puede hacer que la configuración falle y tendrás que reiniciar desde cero." - } - }, - "setup-complete": { - "header": "🎉 🎉 🎉", - "congratulations": "Felicidades", - "leader-message": "Todos los códigos de verificación de los Guardianes han sido verificados.", - "follower-message": "¡Ya has terminado! ¡Avisa a los otros Guardianes que estás en marcha!", - "continue": "Continuar" - }, - "terms-of-service": { - "agree-and-continue": "Aceptar y continuar" - }, - "verify-guardians": { - "verified": "Verificado", - "verified-placeholder": "Pega el código aquí", - "error": "Algo salió mal.", - "error-peer-id": "No se puede determinar qué par eres. Por favor, actualiza y vuelve a intentarlo.", - "verification-code": "Tu código de verificación", - "verification-code-help": "Comparte este código con otros guardianes.", - "table-title": "Códigos de verificación del guardián", - "table-description": "Ingresa los códigos de verificación de cada Guardián a continuación.", - "table-column-name": "Nombre", - "table-column-status": "Estado", - "table-column-hash-input": "Pegar el código de verificación", - "wait-all-guardians-verification": "Esperando a que todos los Guardianes verifiquen sus códigos", - "all-guardians-verified": "Todos los Guardianes han verificado sus códigos.", - "starting-consensus": "Iniciando consenso..." - }, - "footer": { - "docs-section-header": "Documentos", - "community-section-header": "Comunidad", - "contribute-section-header": "Contribuir", - "getting-started-link-text": "Comenzando", - "faq-link-text": "Preguntas Frecuentes", - "blog-link-text": "Blog", - "discord-link-text": "Discord", - "twitter-link-text": "Twitter", - "github-link-text": "GitHub" - } -} diff --git a/apps/guardian-ui/src/languages/fr.json b/apps/guardian-ui/src/languages/fr.json deleted file mode 100644 index ddf84e5e6..000000000 --- a/apps/guardian-ui/src/languages/fr.json +++ /dev/null @@ -1,344 +0,0 @@ -{ - "common": { - "bitcoin": "Bitcoin", - "next": "Suivant", - "back": "Retour", - "error": "Quelque chose a mal tourné.", - "unknown": "Inconnu", - "remove": "Retirer", - "copy": "Copier", - "copied": "Copié !", - "cancel": "Annuler", - "review": "Révision", - "approvals": "Approbations", - "approve": "Approuver", - "threshold": "Seuil", - "confirm": "Confirmer", - "you": "Vous", - "close": "Fermer", - "save": "Sauvegarder", - "continue": "Continuer", - "submit": "Envoyer" - }, - "notConfigured": { - "title": "Non configuré", - "description": "Veuillez entrer l'URL du serveur de configuration Fedimint pour continuer." - }, - "connect-guardians": { - "invite-guardians": "Inviter des abonnés", - "invite-guardians-help": "Partagez ce lien avec les autres Gardiens.", - "approve": "Approuver", - "approved": "Approuvé", - "pending": "En attente", - "not-joined": "Non rejoint", - "waiting-for-guardian": "En attente du gardien", - "table-title": "Gardiens de la Fédération", - "table-description": "Les gardiens seront confirmés ici une fois qu'ils auront confirmé les paramètres de la Fédération.", - "meta-field-key": "Champ méta - {{key}}" - }, - "federation-dashboard": { - "invite-members": "Invitez des membres ou authentifiez-vous en tant que gardien", - "invite-members-prompt": "Partagez ceci pour inviter des membres à rejoindre la fédération.", - "fed-info": { - "label": "Informations sur la fédération", - "your-status-label": "Statut", - "block-count-label": "Hauteur de bloc de consensus", - "api-version-label": "Version de l'API", - "consensus-version-label": "Version de consensus", - "peer-id-label": "ID de pair", - "session-info": { - "session-height": "Hauteur de la session", - "latest-session": "Dernière session" - } - }, - "balance": { - "label": "Bilan" - }, - "bitcoin-node": { - "label": "Nœud Bitcoin", - "url-label": "URL", - "network-label": "Réseau" - }, - "guardians": { - "label": "Autres Gardiens", - "id-name-label": "ID : Nom", - "status-label": "État de la connexion", - "health-label": "Santé", - "health-issue": "Problème", - "health-good": "Bon", - "last-contribution-label": "Dernière contribution de session", - "api-url-label": "URL de l'API", - "fetching-announcement": "Récupération de l'annonce..." - }, - "gateways": { - "label": "Passerelles Éclair", - "node-id-label": "ID de nœud Lightning", - "gateway-id-label": "ID de passerelle", - "fee-label": "Frais de passerelle", - "view-on-site": "Voir sur {{site}}", - "no-gateways-info-title": "Aucun passerelle connectée pour l'instant !", - "no-gateways-info-description": "Les opérateurs de nœuds Lightning peuvent se connecter à votre fédération pour fournir une interopérabilité avec le Lightning Network. Une fois connectés, ils apparaîtront ici." - }, - "api-announcements": { - "label": "Annonces API", - "guardian": "Gardien", - "api-url": "URL de l'API", - "revision": "Révision" - }, - "config": { - "label": "Configuration de la Fédération", - "view-config": "Afficher la configuration", - "missing-meta-module": "L'édition des champs Meta n'est pas possible. Le module Meta n'est pas disponible pour cette fédération.", - "manage-meta": { - "label": "Gérer Meta", - "cancel-button": "Annuler", - "confirm-modal": { - "title": "Confirmer l'approbation", - "description": "Votre approbation atteindra le seuil pour adopter ce changement de méta. Votre nouvelle méta ressemblera à :" - }, - "consensus-meta-label": "Meta actuel dans le consensus", - "revoke-button": "Révoquer", - "no-consensus-meta-message": "il n'y a pas de méta dans le consensus", - "proposed-meta-label": "Propositions Meta", - "propose-meta": "Proposer Meta", - "propose-new-meta-button": "Proposer un nouveau méta", - "proposal-approved": "Vous avez approuvé cette proposition.", - "no-submitted-meta-message": "il n'y a pas de modifications méta à examiner", - "edit-meta-label": "Modifier les métadonnées", - "edit-consensus-meta-button": "Modifier le consensus Meta", - "submit-meta-proposal": "Soumettre une proposition Meta", - "peer-approvals": "Approbations par les pairs", - "actions": "Actions", - "revision": "Révision", - "setup-meta-title": "Configurer un Meta pour votre Fédération", - "setup-meta-description": "Fedimint peut fournir des informations supplémentaires aux clients sous forme de champs méta : des paires clé-valeur avec des informations arbitraires que vous pourriez vouloir partager avec les clients. Bien que ces champs méta ne soient pas interprétés par Fedimint, ils sont pertinents pour le consensus, c'est-à-dire qu'ils ne peuvent pas différer entre les membres de la fédération. De cette manière, les clients peuvent compter sur leur exactitude.", - "propose-updates": "En tant que gardien de fedimint, vous pouvez proposer des mises à jour du méta qui seront acceptées par les autres gardiens. Une fois la mise à jour acceptée par un seuil de gardiens, elle sera adoptée comme le nouveau méta de consensus pour la fédération.", - "core-meta-fields": "Les champs méta suivants ont été définis dans le cadre du protocole Fedimint de base et sont utiles à inclure pour le méta de votre fédération :", - "meta-field-expiry": "Un horodatage Unix après lequel la fédération sera arrêtée.", - "meta-field-name": "Le nom lisible par l'homme de la fédération", - "meta-field-icon": "Une URL vers une icône de logo pour la fédération", - "meta-field-welcome": "Un message de bienvenue pour les nouveaux utilisateurs rejoignant la fédération.", - "meta-field-gateways": "Une liste d'identifiants de passerelle vérifiés par la fédération", - "your-own-fields": "Vous pouvez également ajouter vos propres champs méta arbitraires à la proposition. Ceux-ci seront ajoutés aux méta de tous les clients qui se connectent à votre fédération et peuvent être utilisés à toutes fins que vous souhaitez.", - "meta-effect-add": "Ajouter", - "meta-effect-modify": "Modifier", - "meta-effect-unchanged": "Inchangé", - "proposals": "Propositions" - } - }, - "modal": { - "client-connect": "Connecter un client" - }, - "danger-zone": { - "danger-zone-label": "Zone de danger", - "cancel": "Annuler", - "danger-zone-description": "Utilisez avec précaution !", - "guardian-warning-message": "AVERTISSEMENT : Ne partagez pas ce code avec qui que ce soit. Quiconque possède ce code peut s'authentifier en tant que Gardien. Assurez-vous d'être dans un endroit privé et que personne ne regarde votre écran.", - "guardian-acknowledge": "Reconnaître et révéler le code", - "acknowledge-and-download": "Reconnaître et continuer", - "guardian-authenticate": "S'authentifier en tant que Gardien", - "guardian-connect-warning": "NE PAS PARTAGER CECI", - "backup": { - "label": "Sauvegarde", - "title": "Télécharger la sauvegarde", - "warning-title": "Avertissement", - "warning-text": "La sauvegarde contient des clés privées et des matériaux secrets pour le gardien de la fédération et doit être conservée en sécurité. La récupération à l'aide de cette sauvegarde nécessite votre mot de passe administrateur !", - "cancelButton": "Annuler", - "acknowledgeButton": "Reconnaître et télécharger" - }, - "sign-api-announcement": { - "label": "Annonce de l'API de signature", - "title": "Annonce de l'API de signature", - "description": "Signer une nouvelle annonce d'API.", - "current-api-url": "Votre URL d'API depuis la configuration locale", - "announced-api-url": "Votre URL d'API des Annonces de Fédération", - "urls-match": "Votre URL d'API actuelle correspond à votre URL d'API annoncée.", - "urls-mismatch": "Vous avez changé l'URL de l'API dans votre configuration locale et devez diffuser une nouvelle annonce API.", - "sign-button": "Annonce de la nouvelle API", - "signing-in-progress": "Connexion en cours...", - "sign-tooltip": "Signez l'annonce de l'API pour annoncer votre URL d'API à la fédération." - }, - "schedule-shutdown": { - "label": "Planifier l'arrêt", - "title": "Planifier l'arrêt", - "description": "Programmez votre nœud de garde pour s'arrêter après une hauteur de session spécifique pour une mise à niveau coordonnée de vos binaires fedimintd.", - "current-session": "Session actuelle", - "session-to-shutdown": "Session à fermer à", - "confirm-shutdown": "Confirmer l'arrêt", - "session-to-shutdown-helper": "Entrez la hauteur de session à laquelle vous souhaitez éteindre votre nœud gardien." - } - } - }, - "login": { - "title": "Bienvenue de nouveau !", - "subtitle": "Veuillez entrer votre mot de passe.", - "password": "Mot de passe", - "submit": "Soumettre" - }, - "role-selector": { - "disclaimer-title": "Fedimint est un logiciel bêta", - "disclaimer-text": "Veuillez signaler les problèmes à https://github.com/fedimint/fedimint/issues", - "leader": { - "label": "Leader de configuration", - "description": "Entrez les paramètres de configuration que d'autres Gardiens approuvent. Un Gardien agit en tant que Leader de Configuration." - }, - "follower": { - "label": "Abonné", - "description": "Une fois qu'un Leader de Configuration a défini les configurations, d'autres Gardiens choisissent cette option pour approuver les paramètres et créer la Fédération." - }, - "solo": { - "label": "Seul", - "description": "Exécutez Fedimint en tant que Gardien Solo sans consensus, tolérance aux pannes, sauvegardes fédérées ou autres avantages de résilience de Fedimint. Procédez avec prudence, ce n'est pas destiné à un usage en production." - }, - "warning-modal": { - "title": "Tout le monde est prêt ?", - "description": "Sortir de la cérémonie de configuration peut entraîner l'échec de la configuration et nécessiter que vous redémarriez votre gardien. Assurez-vous que tout le monde est prêt à exécuter la configuration complète avant de continuer !" - } - }, - "run-dkg": { - "error-config": "Échec de l'exécution de la génération de clés distribuées. La configuration de la fédération doit être redémarrée.", - "error-default": "Pas prêt pour DKG, votre statut actuel est", - "error-header": "Quelque chose a mal tourné.", - "waiting-header": "En attente de pairs...", - "generating-header": "Génération de codes..." - }, - "set-config": { - "bft-explanation-title": "Tolérance aux fautes byzantines de votre fédération", - "bft-explanation": "Un {{total}} de la Fédération des Gardiens crée un {{honest}}/{{total}} Seuil.", - "bft-faulty": "Votre Fédération sera en mesure de tolérer {{faulty}} des Gardiens défectueux, hors ligne ou malveillants sans impacter les opérations de la Fédération.", - "guardian-name": "Nom du gardien", - "guardian-name-help": "Ce nom aléatoire sera affiché aux autres Gardiens pendant la configuration.", - "admin-password": "Mot de passe administrateur", - "admin-password-generate": "Générer", - "admin-password-set": "Cliquez sur 'Générer' pour créer un mot de passe sécurisé. Vous pouvez le modifier, mais ce mot de passe doit être sécurisé et sauvegardé !", - "admin-password-help": "Sauvegardez ce mot de passe et gardez-le en sécurité ! Vous ne pouvez pas récupérer ce mot de passe !", - "admin-password-backup": "J'utilise un mot de passe fort et je l'ai sauvegardé. (Vous ne pouvez pas récupérer ce mot de passe !)", - "confirm-password": "Confirmer le mot de passe", - "error-password-mismatch": "Les mots de passe ne correspondent pas.", - "join-federation": "Rejoindre le lien de la Fédération", - "join-federation-help": "Demandez à la personne qui a créé la Fédération un lien et collez-le ici.", - "basic-settings": "Bases", - "federation-settings": "Paramètres de la fédération", - "federation-name": "Nom de la fédération", - "guardian-number": "Nombre de gardiens", - "guardian-number-help": "Les fédérations nécessitent un minimum de 4 gardiens. Cela ne peut pas être modifié par la suite.", - "bitcoin-settings": "Paramètres Bitcoin", - "block-confirmations": "Confirmations de blocs supplémentaires", - "block-confirmations-help": "Les gardiens de Fedimint suivent le sommet de la blockchain avec plusieurs confirmations pour éviter les réorganisations de blocs.", - "block-confirmations-warning": "Exécuter Fedimint avec moins de 5 confirmations de bloc supplémentaires est extrêmement risqué ! Fedimint NE PEUT PAS gérer les réorganisations de blockchain.", - "bitcoin-network": "Réseau Bitcoin", - "select-network": "Sélectionnez un réseau", - "set-rpc-help": "Adresse RPC Bitcoin configurée localement", - "bitcoin-rpc": "Bitcoin RPC", - "error-valid-number": "Veuillez saisir un numéro valide.", - "error-valid-min": "Veuillez entrer un nombre d'au moins {{min}}.", - "error-valid-max": "Veuillez saisir un nombre d'au plus {{max}}.", - "error-valid-min-max": "Veuillez entrer un nombre entre {{min}} et {{max}}.", - "meta-fields": "Champs méta", - "meta-fields-description": "Voir documentation pour plus d'informations.", - "meta-fields-key": "Touche Meta", - "meta-fields-value": "Valeur", - "meta-fields-effect": "Effet", - "meta-fields-add-another": "Ajouter un autre", - "meta-fields-title": "Votre proposition Meta :", - "password-warning": "Vous devez faire une sauvegarde de votre mot de passe et le conserver en sécurité. Ce mot de passe est nécessaire pour accéder à votre tableau de bord de gardien. Vous ne pouvez pas le récupérer si vous le perdez !", - "password-warning-title": "Faites une sauvegarde de votre mot de passe !", - "acknowledge-backed-up": "Je, {{guardianName}} (votre nom de gardien), promets que j'ai sauvegardé et sécurisé mon mot de passe :", - "confirm-and-backup-password": "Confirmer et sauvegarder le mot de passe", - "error-guardian-name-mismatch": "Le nom du tuteur ne correspond pas.", - "network": "Réseau" - }, - "setup": { - "common": { - "restart-setup": "Redémarrer l'installation", - "restart-setup-alert": "Le Responsable de la Configuration a redémarré la Cérémonie de Configuration. Veuillez cliquer sur \"Redémarrer\" ci-dessous pour continuer.", - "confirm-restart-setup": "Êtes-vous sûr de vouloir redémarrer la cérémonie de configuration ?", - "confirm-restart-setup-alert": "Cliquer sur \"Redémarrer\" redémarrera la cérémonie pour tous les Gardiens." - }, - "progress": { - "tos": { - "title": "Conditions d'utilisation" - }, - "start": { - "title": "Bienvenue, Gardien !", - "subtitle": "Mettons en place votre fédération.", - "step": "Détails de la fédération" - }, - "set-config": { - "title": "Nous devons définir certaines configurations pour votre Fédération.", - "title-solo": "Nous devons définir certaines configurations pour votre Fédération Solo.", - "subtitle-leader": "Vos abonnés de la Fédération confirmeront cette information de leur côté.", - "subtitle-solo": "Exécuter une fédération solo perd de nombreux avantages de Fedimint. Vous n'aurez pas de consensus de tolérance aux pannes si un gardien est hors ligne et vous ne pourrez pas effectuer de sauvegardes fédérées. Proceed with caution, non recommandé pour une utilisation en production ou avec le Bitcoin sur le réseau principal.", - "subtitle-follower": "Votre leader de la fédération va configurer les détails principaux de la fédération. Vous les confirmerez bientôt.", - "step": "Détails de la fédération" - }, - "connect-guardians": { - "title-leader": "Invitez vos Gardiens", - "title-follower": "Confirmez vos informations de fédération", - "subtitle-leader": "Partagez le lien avec les autres Gardiens pour que tout le monde soit sur la même longueur d'onde. Une fois que tous les Gardiens auront rejoint, vous passerez automatiquement à l'étape suivante.", - "subtitle-follower": "Assurez-vous que les informations ici sont correctes et que les Gardiens de la Fédération le sont également. Cliquez sur le bouton Approuver lorsque vous êtes sûr que tout semble bon.", - "step-leader": "Inviter les Gardiens", - "step-follower": "Confirmer les informations" - }, - "run-dkg": { - "title": "Succès !", - "subtitle": "Tous les Gardiens ont validé les détails de configuration de la fédération. En train de faire quelques calculs..." - }, - "verify-guardians": { - "title": "Vérifiez vos Gardiens", - "subtitle": "Demandez à chaque Gardien leur code de vérification et collez-les ci-dessous pour vérifier leur validité. Nous y sommes presque !", - "step": "Vérifier les tuteurs", - "leader-confirm-done": "Confirmez que tous les Gardiens suiveurs ont cliqué sur \"Suivant\" et consultez leurs tableaux de bord de gardien avant de continuer.", - "leader-confirm-done-emphasis": "Cliquer sur \"Continuer\" complétera la cérémonie de configuration." - }, - "setup-complete": { - "step": "Fait !" - }, - "error": { - "title": "Étape inconnue", - "subtitle": "Comment es-tu arrivé ici ?!" - } - }, - "warning": { - "title": "Ne quittez pas et ne rafraîchissez pas pendant la configuration !", - "description": "Quitter pendant la configuration peut entraîner un échec de la configuration et vous devrez effectuer un redémarrage complet." - } - }, - "setup-complete": { - "header": "🎉 🎉 🎉", - "congratulations": "Félicitations", - "leader-message": "Tous les codes de vérification des Gardiens ont été vérifiés.", - "follower-message": "Vous avez terminé ! Faites savoir aux autres Gardiens que vous êtes opérationnel !", - "continue": "Continuer" - }, - "terms-of-service": { - "agree-and-continue": "Accepter et continuer" - }, - "verify-guardians": { - "verified": "Vérifié", - "verified-placeholder": "Collez le code ici", - "error": "Quelque chose a mal tourné.", - "error-peer-id": "Impossible de déterminer quel pair vous êtes. Veuillez actualiser et réessayer.", - "verification-code": "Votre code de vérification", - "verification-code-help": "Partagez ce code avec d'autres gardiens.", - "table-title": "Codes de vérification Guardian", - "table-description": "Entrez les codes de vérification de chaque Gardien ci-dessous.", - "table-column-name": "Nom", - "table-column-status": "Statut", - "table-column-hash-input": "Collez le code de vérification", - "wait-all-guardians-verification": "En attente que tous les Gardiens vérifient leurs codes", - "all-guardians-verified": "Tous les Gardiens ont vérifié leurs codes.", - "starting-consensus": "Consensus de départ..." - }, - "footer": { - "docs-section-header": "Documents", - "community-section-header": "Communauté", - "contribute-section-header": "Contribuer", - "getting-started-link-text": "Commencer", - "faq-link-text": "Questions Fréquemment Posées", - "blog-link-text": "Blog", - "discord-link-text": "Discord", - "twitter-link-text": "Twitter", - "github-link-text": "GitHub" - } -} diff --git a/apps/guardian-ui/src/languages/hu.json b/apps/guardian-ui/src/languages/hu.json deleted file mode 100644 index 3df7fe256..000000000 --- a/apps/guardian-ui/src/languages/hu.json +++ /dev/null @@ -1,344 +0,0 @@ -{ - "common": { - "bitcoin": "Bitcoin", - "next": "Következő", - "back": "Vissza", - "error": "Valami hiba történt.", - "unknown": "Ismeretlen", - "remove": "Eltávolítás", - "copy": "Másolat", - "copied": "Másolt!", - "cancel": "Törlés", - "review": "Felülvizsgálat", - "approvals": "Jóváhagyások", - "approve": "Jóváhagyás", - "threshold": "Küszöb", - "confirm": "Megerősít", - "you": "Te", - "close": "Bezárás", - "save": "Mentés", - "continue": "Folytatás", - "submit": "Küldés" - }, - "notConfigured": { - "title": "Nincs konfigurálva", - "description": "Kérjük, adja meg a Fedimint konfigurációs szerver URL-jét a folytatáshoz." - }, - "connect-guardians": { - "invite-guardians": "Kövesd a követőket", - "invite-guardians-help": "Oszd meg ezt a linket a többi Őrzővel.", - "approve": "Jóváhagyás", - "approved": "Jóváhagyva", - "pending": "Függőben", - "not-joined": "Nem csatlakozott", - "waiting-for-guardian": "Várakozás a gyámra", - "table-title": "Szövetségi Őrzők", - "table-description": "A Őrzők itt lesznek megerősítve, amint megerősítik a Szövetség beállításait.", - "meta-field-key": "Meta mező - {{key}}" - }, - "federation-dashboard": { - "invite-members": "Hívj meg tagokat vagy hitelesítsd magad mint őrző", - "invite-members-prompt": "Oszd meg ezt, hogy meghívj tagokat a szövetségbe való csatlakozásra.", - "fed-info": { - "label": "Szövetségi Információ", - "your-status-label": "Állapot", - "block-count-label": "Konszenzus Blokk Magasság", - "api-version-label": "API verzió", - "consensus-version-label": "Konszenzus verzió", - "peer-id-label": "Felhasználói azonosító", - "session-info": { - "session-height": "Ülés magasság", - "latest-session": "Legutóbbi ülés" - } - }, - "balance": { - "label": "Mérleg" - }, - "bitcoin-node": { - "label": "Bitcoin Csomópont", - "url-label": "URL", - "network-label": "Hálózat" - }, - "guardians": { - "label": "Más Őrzők", - "id-name-label": "AZ: Név", - "status-label": "Kapcsolati állapot", - "health-label": "Egészség", - "health-issue": "Kérdés", - "health-good": "Jó", - "last-contribution-label": "Utolsó Munkamenet Hozzájárulás", - "api-url-label": "API URL", - "fetching-announcement": "Bejelentés lekérése..." - }, - "gateways": { - "label": "Villámkapuk", - "node-id-label": "Villámcsomópont azonosító", - "gateway-id-label": "Kapunyitó azonosító", - "fee-label": "Átjáró díj", - "view-on-site": "Nézd meg a {{site}} oldalon", - "no-gateways-info-title": "Még nincsenek csatlakoztatott átjárók!", - "no-gateways-info-description": "A Lightning csomópont üzemeltetők csatlakozhatnak a szövetségedhez, hogy biztosítsák a Lightning Network interoperabilitását. Miután csatlakoztak, itt fognak megjelenni." - }, - "api-announcements": { - "label": "API Bejelentések", - "guardian": "Őrző", - "api-url": "API URL", - "revision": "Felülvizsgálat" - }, - "config": { - "label": "Szövetségi beállítások", - "view-config": "Nézet beállítások", - "missing-meta-module": "A Meta mezők szerkesztése nem lehetséges. A Meta modul nem elérhető ehhez a szövetséghez.", - "manage-meta": { - "label": "Meta kezelése", - "cancel-button": "Törlés", - "confirm-modal": { - "title": "Jóváhagyás megerősítése", - "description": "A jóváhagyása eléri a küszöböt ennek a meta változásnak az elfogadásához. Az új meta így fog kinézni:" - }, - "consensus-meta-label": "Jelenlegi meta a konszenzusban", - "revoke-button": "Visszavonás", - "no-consensus-meta-message": "nincs meta a konszenzusban", - "proposed-meta-label": "Meta Javaslatok", - "propose-meta": "Javasolj Meta", - "propose-new-meta-button": "Javasolj új metát", - "proposal-approved": "Jóváhagytad ezt a javaslatot.", - "no-submitted-meta-message": "nincsenek felülvizsgálatra váró meta módosítások", - "edit-meta-label": "Meta szerkesztése", - "edit-consensus-meta-button": "Szerkesztés Konszenzus Meta", - "submit-meta-proposal": "Meta Javaslat Beküldése", - "peer-approvals": "Társaik jóváhagyása", - "actions": "Cselekvések", - "revision": "Felülvizsgálat", - "setup-meta-title": "Meta beállítása a Szövetségedhez", - "setup-meta-description": "A Fedimint kiegészítő információkat tud szolgáltatni az ügyfeleknek meta mezők formájában: kulcs-érték párok tetszőleges információkkal, amelyeket meg szeretne osztani az ügyfelekkel. Bár ezeket a meta mezőket a Fedimint nem értelmezi, konszenzus szempontjából relevánsak, azaz nem térhetnek el a szövetségi tagok között. Így az ügyfelek támaszkodhatnak a helyességükre.", - "propose-updates": "Fedimint őrzőként javaslatot tehetsz a meta frissítésekre, amelyeket a többi őrző elfogad. Miután a frissítést egy küszöbnyi őrző elfogadta, az új konszenzus meta lesz a szövetség számára.", - "core-meta-fields": "A következő meta mezők a Fedimint protokoll részeként lettek definiálva, és hasznosak a szövetséged meta adatainak tartalmazásához:", - "meta-field-expiry": "Egy unix időbélyeg, amely után a szövetség leáll.", - "meta-field-name": "A szövetség emberi olvasásra alkalmas neve", - "meta-field-icon": "Egy URL a szövetség logó ikonjához", - "meta-field-welcome": "Üdvözlő üzenet az új felhasználók számára, akik csatlakoznak a szövetséghez.", - "meta-field-gateways": "A szövetség által ellenőrzött átjáróazonosítók listája", - "your-own-fields": "A javaslathoz saját tetszőleges meta mezőket is hozzáadhatsz. Ezeket hozzáadják az összes olyan kliens metaadataihoz, amely csatlakozik a szövetségedhez, és bármilyen célra felhasználhatók, amit szeretnél.", - "meta-effect-add": "Hozzáadás", - "meta-effect-modify": "Módosít", - "meta-effect-unchanged": "Változatlan", - "proposals": "Javaslatok" - } - }, - "modal": { - "client-connect": "Kapcsolódj egy klienshez" - }, - "danger-zone": { - "danger-zone-label": "Veszélyzóna", - "cancel": "Törlés", - "danger-zone-description": "Használja óvatosan!", - "guardian-warning-message": "FIGYELEM: Ne oszd meg ezt a kódot senkivel. Aki rendelkezik ezzel a kóddal, az az Őrzőként hitelesítheti magát. Győződj meg róla, hogy egy privát helyen vagy, és senki sem figyeli a képernyődet.", - "guardian-acknowledge": "Ismerje el és fedje fel a kódot", - "acknowledge-and-download": "Elismerés és folytatás", - "guardian-authenticate": "Hitelesítés Őrként", - "guardian-connect-warning": "NE OSZD MEG EZT", - "backup": { - "label": "Biztonsági másolat", - "title": "Biztonsági mentés letöltése", - "warning-title": "Figyelem", - "warning-text": "A biztonsági mentés tartalmazza a szövetségi őr privát kulcsait és titkos anyagait, és biztonságban kell tartani. A helyreállításhoz ezzel a biztonsági mentéssel szükség van az admin jelszavadra!", - "cancelButton": "Mégse", - "acknowledgeButton": "Elismerés és Letöltés" - }, - "sign-api-announcement": { - "label": "Aláírás API Bejelentés", - "title": "Aláírás API Bejelentés", - "description": "Írj alá egy új API bejelentést.", - "current-api-url": "Az API URL-je a Helyi Beállításokból", - "announced-api-url": "Az API URL-je a Szövetségi Bejelentésekből", - "urls-match": "A jelenlegi API URL címed megegyezik a bejelentett API URL címmel.", - "urls-mismatch": "Megváltoztattad az API URL-t a helyi konfigurációdban, és új API bejelentést kell tenned.", - "sign-button": "Új API bejelentés aláírása", - "signing-in-progress": "Bejelentkezés folyamatban...", - "sign-tooltip": "Írd alá az API bejelentést, hogy bejelentsd az API URL-edet a szövetségnek." - }, - "schedule-shutdown": { - "label": "Ütemezett leállítás", - "title": "Ütemezett leállítás", - "description": "Ütemezze a felügyelő csomópont leállítását egy adott session magasság után a fedimintd binárisok koordinált frissítése érdekében.", - "current-session": "Aktuális ülés", - "session-to-shutdown": "A munkamenet leállítása:", - "confirm-shutdown": "Leállítás megerősítése", - "session-to-shutdown-helper": "Írd be a session magasságát, amelynél le szeretnéd állítani a guardian node-odat." - } - } - }, - "login": { - "title": "Üdvözöljük vissza!", - "subtitle": "Kérjük, adja meg a jelszavát.", - "password": "Jelszó", - "submit": "Benyújtás" - }, - "role-selector": { - "disclaimer-title": "A Fedimint béta szoftver.", - "disclaimer-text": "Kérjük, jelezze a problémákat a https://github.com/fedimint/fedimint/issues oldalon.", - "leader": { - "label": "Beállító vezető", - "description": "Írja be a konfigurációs beállításokat, amelyeket más Őrzők jóváhagynak. Egy Őrző a Beállítási Vezető." - }, - "follower": { - "label": "Követő", - "description": "Miután egy Beállítási Vezető beállította a konfigurációkat, a többi Őrző ezt az opciót választja a beállítások jóváhagyására és a Szövetség létrehozására." - }, - "solo": { - "label": "Egyedül", - "description": "Működtesse a Fedimintot egyéni őrként konszenzus, hibatűrés, szövetségi biztonsági mentések vagy a Fedimint egyéb ellenállósági előnyei nélkül. Járjon el óvatosan, nem termelési használatra készült." - }, - "warning-modal": { - "title": "Mindenki készen áll?", - "description": "A beállítási ceremónia elhagyása a beállítás kudarcát okozhatja, és szükségessé teheti a védelmező újraindítását. Győződj meg róla, hogy mindenki készen áll a teljes beállítás futtatására, mielőtt folytatnád!" - } - }, - "run-dkg": { - "error-config": "Sikertelen a megosztott kulcsgenerálás futtatása. A szövetség beállítását újra kell indítani.", - "error-default": "Nem készen a DKG-ra, a jelenlegi státuszod", - "error-header": "Valami hiba történt.", - "waiting-header": "Várok a társakra...", - "generating-header": "Kódok generálása..." - }, - "set-config": { - "bft-explanation-title": "A Te Szövetséged Bizánci Hiba Toleranciája", - "bft-explanation": "Egy {{total}} Őrző Szövetség létrehoz egy {{honest}}/{{total}} Küszöböt.", - "bft-faulty": "A Szövetséged képes lesz tolerálni a {{faulty}} hibás, offline vagy rosszindulatú Őrzőket anélkül, hogy ez hatással lenne a Szövetség működésére.", - "guardian-name": "Őrző neve", - "guardian-name-help": "Ez a véletlenszerű név megjelenik más Őrzőknek a beállítás során.", - "admin-password": "Admin jelszó", - "admin-password-generate": "Generálás", - "admin-password-set": "Kattints a 'Generálás' gombra egy biztonságos jelszó létrehozásához. Módosíthatod, de ennek a jelszónak biztonságosnak és mentettnek kell lennie!", - "admin-password-help": "Biztosítsd ezt a jelszót és tartsd biztonságban! Ezt a jelszót nem tudod visszaállítani!", - "admin-password-backup": "Erős jelszót használok, és elmentettem. (Ezt a jelszót nem tudod visszaállítani!)", - "confirm-password": "Jelszó megerősítése", - "error-password-mismatch": "A jelszavak nem egyeznek.", - "join-federation": "Csatlakozz a Szövetséghez link", - "join-federation-help": "Kérdezd meg azt a személyt, aki létrehozta a Szövetséget, hogy adjon egy linket, és másold be ide.", - "basic-settings": "Alapok", - "federation-settings": "Szövetségi beállítások", - "federation-name": "Szövetség neve", - "guardian-number": "Őrzők száma", - "guardian-number-help": "A szövetségekhez minimum 4 őrző szükséges. Ezen később nem lehet változtatni.", - "bitcoin-settings": "Bitcoin beállítások", - "block-confirmations": "További blokk megerősítések", - "block-confirmations-help": "A Fedimint őrzők több megerősítéssel követik a blokklánc csúcsát, hogy elkerüljék a blokkújraszervezéseket.", - "block-confirmations-warning": "A Fedimint futtatása kevesebb mint 5 további blokk megerősítéssel rendkívül kockázatos! A Fedimint NEM képes kezelni a blokklánc átszervezéseket.", - "bitcoin-network": "Bitcoin Hálózat", - "select-network": "Válasszon egy hálózatot", - "set-rpc-help": "Helyileg beállított Bitcoin RPC cím", - "bitcoin-rpc": "Bitcoin RPC", - "error-valid-number": "Kérjük, adjon meg egy érvényes számot.", - "error-valid-min": "Kérjük, adjon meg legalább {{min}} számot.", - "error-valid-max": "Kérjük, adjon meg legfeljebb {{max}} számot.", - "error-valid-min-max": "Kérjük, adjon meg egy számot {{min}} és {{max}} között.", - "meta-fields": "Meta mezők", - "meta-fields-description": "Lásd a dokumentációt a további információkért.", - "meta-fields-key": "Meta kulcs", - "meta-fields-value": "Érték", - "meta-fields-effect": "Hatás", - "meta-fields-add-another": "Adj hozzá egy másikat", - "meta-fields-title": "A te Meta Javaslatod:", - "password-warning": "Meg kell őrizned a jelszavadat, és biztonságos helyen kell tárolnod. Ez a jelszó szükséges a Őrző irányítópultjának eléréséhez. Nem tudod visszaállítani, ha elveszíted!", - "password-warning-title": "Jelszó biztonsági mentése!", - "acknowledge-backed-up": "Én, {{guardianName}} (a te őrződ neve), ígérem, hogy biztonsági másolatot készítettem és megvédtem a jelszavamat:", - "confirm-and-backup-password": "Jelszó megerősítése és biztonsági mentés", - "error-guardian-name-mismatch": "A gondnok neve nem egyezik.", - "network": "Hálózat" - }, - "setup": { - "common": { - "restart-setup": "Újraindítás beállításai", - "restart-setup-alert": "A Beállítási Vezető újraindította a Beállítási Ceremóniát. Kérjük, kattintson az alábbi \"Újraindítás\" gombra a folytatáshoz.", - "confirm-restart-setup": "Biztos benne, hogy újra szeretné indítani a Telepítési Ceremóniát?", - "confirm-restart-setup-alert": "A \"Újraindítás\" gombra kattintva újraindul a szertartás minden Őrző számára." - }, - "progress": { - "tos": { - "title": "Szolgáltatási feltételek" - }, - "start": { - "title": "Üdvözöljük, Őrző!", - "subtitle": "Állítsuk be a szövetségedet.", - "step": "Szövetségi adatok" - }, - "set-config": { - "title": "Be kell állítanunk néhány konfigurációt a Szövetségedhez.", - "title-solo": "Néhány beállítást kell megadnunk a Solo Szövetségedhez.", - "subtitle-leader": "A Szövetséged Követői megerősítik ezt az információt a saját oldalukon.", - "subtitle-solo": "A Szóló Szövetség működtetése sok előnyét elveszíti a Fedimintnek. Nem lesz hibatűrő konszenzus egy őrző offline állapotára, és nem tudsz szövetségi biztonsági mentéseket végezni. Óvatosan járj el, nem ajánlott termelési használatra vagy a főhálózati Bitcoin használatára.", - "subtitle-follower": "A Szövetség vezetője beállítja a fő Szövetségi részleteket. Hamarosan megerősíted őket.", - "step": "Szövetségi adatok" - }, - "connect-guardians": { - "title-leader": "Hívd meg a Őrzőidet", - "title-follower": "Erősítse meg a Szövetségi Információit", - "subtitle-leader": "Oszd meg a linket a többi Őrzővel, hogy mindenki egy oldalon legyen. Miután minden Őrző csatlakozik, automatikusan a következő lépésre lépsz.", - "subtitle-follower": "Győződjön meg róla, hogy az itt található információk helyesek, és hogy a Szövetség Őrzői pontosak. Kattintson az Engedélyezés gombra, amikor biztos benne, hogy jól néz ki.", - "step-leader": "Hívj meg Őrzőket", - "step-follower": "Információ megerősítése" - }, - "run-dkg": { - "title": "Siker!", - "subtitle": "Minden Őrző érvényesítette a szövetségi beállítások részleteit. Számolok egy kicsit..." - }, - "verify-guardians": { - "title": "Ellenőrizd a Őrzőidet", - "subtitle": "Kérd meg minden Őrt, hogy adja meg a hitelesítési kódját, és másold be őket alább a érvényesség ellenőrzéséhez. Már majdnem kész vagyunk!", - "step": "Ellenőrizze a gyámokat", - "leader-confirm-done": "Erősítse meg, hogy az összes követő Őrző rákattintott a \"Tovább\" gombra, és nézze meg az őrzői irányítópultjaikat, mielőtt folytatná.", - "leader-confirm-done-emphasis": "A \"Tovább\" gombra kattintva befejezi a beállítási ceremóniát." - }, - "setup-complete": { - "step": "Kész!" - }, - "error": { - "title": "Ismeretlen lépés", - "subtitle": "Hogy kerültél ide?!" - } - }, - "warning": { - "title": "Ne lépj ki vagy frissíts a telepítés alatt!", - "description": "A telepítés közben való kilépés a telepítés kudarcát okozhatja, és friss újraindítást kell végeznie." - } - }, - "setup-complete": { - "header": "🎉 🎉 🎉", - "congratulations": "Gratulálok", - "leader-message": "Minden Őr ellenőrző kódját ellenőrizték.", - "follower-message": "Minden készen áll! Értesítsd a többi Őrzőt, hogy működésben vagy!", - "continue": "Folytatás" - }, - "terms-of-service": { - "agree-and-continue": "Egyetértek és folytatom" - }, - "verify-guardians": { - "verified": "Ellenőrzött", - "verified-placeholder": "Illessze be a kódot ide", - "error": "Valami hiba történt.", - "error-peer-id": "Nem tudjuk meghatározni, hogy melyik partner vagy. Kérlek, frissítsd az oldalt, és próbáld újra.", - "verification-code": "A megerősítő kódod", - "verification-code-help": "Oszd meg ezt a kódot más őrzőkkel.", - "table-title": "Őrzői ellenőrző kódok", - "table-description": "Írd be az egyes Őrzők ellenőrző kódjait az alábbiakba.", - "table-column-name": "Név", - "table-column-status": "Állapot", - "table-column-hash-input": "Illessze be a hitelesítési kódot", - "wait-all-guardians-verification": "Várakozás, amíg az összes Őrző megerősíti a kódját", - "all-guardians-verified": "Minden Őr ellenőrizte a kódját.", - "starting-consensus": "Kezdő konszenzus..." - }, - "footer": { - "docs-section-header": "Dokumentumok", - "community-section-header": "Közösség", - "contribute-section-header": "Hozzájárulás", - "getting-started-link-text": "Kezdő lépések", - "faq-link-text": "Gyakran Ismételt Kérdések", - "blog-link-text": "Blog", - "discord-link-text": "Discord", - "twitter-link-text": "Twitter", - "github-link-text": "GitHub" - } -} diff --git a/apps/guardian-ui/src/languages/it.json b/apps/guardian-ui/src/languages/it.json deleted file mode 100644 index f1bebdda4..000000000 --- a/apps/guardian-ui/src/languages/it.json +++ /dev/null @@ -1,344 +0,0 @@ -{ - "common": { - "bitcoin": "Bitcoin", - "next": "Siguiente", - "back": "Volver", - "error": "Algo salió mal.", - "unknown": "Unknown", - "remove": "Eliminar", - "copy": "Copiar", - "copied": "¡Copiado!", - "cancel": "Annuler", - "review": "Revisar", - "approvals": "Aprobaciones", - "approve": "أوافق", - "threshold": "Umbral", - "confirm": "Confirmer", - "you": "Tu", - "close": "Cerrar", - "save": "Guardar", - "continue": "Continuar", - "submit": "Enviar" - }, - "notConfigured": { - "title": "Non configurato", - "description": "Per favore, inserisci l'URL del server di configurazione Fedimint per continuare." - }, - "connect-guardians": { - "invite-guardians": "Invitar seguidores", - "invite-guardians-help": "Teilen Sie diesen Link mit den anderen Wächtern.", - "approve": "أوافق", - "approved": "أُعْتُمِدَ", - "pending": "Pendiente", - "not-joined": "No unido", - "waiting-for-guardian": "In attesa del guardiano", - "table-title": "Federación Guardianes", - "table-description": "Los guardianes se confirmarán aquí una vez que confirmen la configuración de la Federación.", - "meta-field-key": "Campo meta - {{key}}" - }, - "federation-dashboard": { - "invite-members": "Invitar a miembros o autenticar como guardián", - "invite-members-prompt": "Teilen Sie dies, um Mitglieder einzuladen, der Föderation beizutreten.", - "fed-info": { - "label": "信息联邦", - "your-status-label": "Estado", - "block-count-label": "Consensus Block Height", - "api-version-label": "API版本", - "consensus-version-label": "Versión de consenso", - "peer-id-label": "ID de par", - "session-info": { - "session-height": "Sesión Altura", - "latest-session": "Última sesión" - } - }, - "balance": { - "label": "Hoja de Balance" - }, - "bitcoin-node": { - "label": "Bitcoin Knoten", - "url-label": "URL", - "network-label": "Redes" - }, - "guardians": { - "label": "Otros Guardianes", - "id-name-label": "ID: Nombre", - "status-label": "Estado de conexión", - "health-label": "Salud", - "health-issue": "Problema", - "health-good": "Bien", - "last-contribution-label": "Ultimo contributo alla sessione", - "api-url-label": "API URL", - "fetching-announcement": "Fetching announcement..." - }, - "gateways": { - "label": "Lightning Gateways", - "node-id-label": "Lightning Node ID", - "gateway-id-label": "ID de puerta de enlace", - "fee-label": "Tarifa de puerta", - "view-on-site": "Vedi su {{site}}", - "no-gateways-info-title": "¡Aún no hay puertas de enlace conectadas!", - "no-gateways-info-description": "Los operadores de nodos Lightning pueden conectarse a tu federación para proporcionar interoperabilidad de la Lightning Network. Una vez conectados, aparecerán aquí." - }, - "api-announcements": { - "label": "API Announcements", - "guardian": "Guardián", - "api-url": "API URL", - "revision": "Revisión" - }, - "config": { - "label": "Federación Config", - "view-config": "Ver Configuración", - "missing-meta-module": "Editing Meta fields is not possible. The Meta module is not available for this federation.", - "manage-meta": { - "label": "Gérer Meta", - "cancel-button": "Annuler", - "confirm-modal": { - "title": "Konfirmasi Persetujuan", - "description": "Tu aprobación alcanzará el umbral para adoptar este cambio meta. Tu nueva meta se verá así:" - }, - "consensus-meta-label": "Meta actuel dans le consensus", - "revoke-button": "Revocar", - "no-consensus-meta-message": "no hay meta en el consenso", - "proposed-meta-label": "Meta Vorschläge", - "propose-meta": "Propose Meta", - "propose-new-meta-button": "Proponer Nuevo Meta", - "proposal-approved": "Has aprobado esta propuesta.", - "no-submitted-meta-message": "no hay ediciones meta para revisar", - "edit-meta-label": "Edit meta", - "edit-consensus-meta-button": "Edit Consensus Meta", - "submit-meta-proposal": "提交元提案", - "peer-approvals": "Aprobaciones de Pares", - "actions": "Actions", - "revision": "Revisión", - "setup-meta-title": "Configurar un Meta para tu Federación", - "setup-meta-description": "Fedimint puede proporcionar información adicional a los clientes en forma de campos meta: pares de clave-valor con información arbitraria que desees compartir con los clientes. Aunque estos campos meta no son interpretados por Fedimint, son relevantes para el consenso, es decir, no pueden diferir entre los miembros de la federación. De esta manera, los clientes pueden confiar en su corrección.", - "propose-updates": "Como guardián de fedimint, puedes proponer actualizaciones al meta que serán aceptadas por los otros guardianes. Una vez que la actualización sea aceptada por un umbral de guardianes, se adoptará como el nuevo meta de consenso para la federación.", - "core-meta-fields": "Los siguientes campos meta se han definido como parte del protocolo central de Fedimint y son útiles para incluir en el meta de su federación:", - "meta-field-expiry": "Un timestamp de Unix después del cual la federación se cerrará.", - "meta-field-name": "El nombre legible por humanos de la federación", - "meta-field-icon": "Une URL vers une icône de logo pour la fédération", - "meta-field-welcome": "Un mensaje de bienvenida para los nuevos usuarios que se unen a la federación.", - "meta-field-gateways": "Una lista de identificadores de puerta de enlace verificados por la federación", - "your-own-fields": "También puedes agregar tus propios campos meta arbitrarios a la propuesta. Estos se agregarán a la meta de todos los clientes que se conecten a tu federación y se pueden utilizar para cualquier propósito que desees.", - "meta-effect-add": "Añadir", - "meta-effect-modify": "Modificar", - "meta-effect-unchanged": "Unverändert", - "proposals": "Propuestas" - } - }, - "modal": { - "client-connect": "Conectar un cliente" - }, - "danger-zone": { - "danger-zone-label": "Zona de Peligro", - "cancel": "Annuler", - "danger-zone-description": "¡Usa con precaución!", - "guardian-warning-message": "AVISO: No compartas este código con nadie. Cualquiera que tenga este código puede autenticarse como un Guardián. Asegúrate de estar en un lugar privado y de que nadie esté mirando tu pantalla.", - "guardian-acknowledge": "Acknowledge and Reveal Code", - "acknowledge-and-download": "Reconocer y Proceder", - "guardian-authenticate": "Authenticate as Guardian", - "guardian-connect-warning": "NO COMPARTAS ESTO", - "backup": { - "label": "Copia de seguridad", - "title": "Télécharger la sauvegarde", - "warning-title": "Advertencia", - "warning-text": "El respaldo contiene claves privadas y material secreto para el guardián de la federación y debe mantenerse seguro. ¡La recuperación utilizando este respaldo requiere tu contraseña de administrador!", - "cancelButton": "Annuler", - "acknowledgeButton": "Reconocer y Descargar" - }, - "sign-api-announcement": { - "label": "Sign API Ankündigung", - "title": "Sign API Ankündigung", - "description": "Signa un nou anunci d'API.", - "current-api-url": "Tu URL de API de Configuración Local", - "announced-api-url": "Tu URL de API de Anuncios de Federación", - "urls-match": "Your current API URL matches your announced API URL.", - "urls-mismatch": "Has cambiado la URL de la API en tu configuración local y necesitas difundir un nuevo anuncio de la API.", - "sign-button": "Signo de nuevo anuncio de API", - "signing-in-progress": "Iniciando sesión...", - "sign-tooltip": "Signa l'annuncio API per annunciare il tuo URL API alla federazione." - }, - "schedule-shutdown": { - "label": "Programar Apagado", - "title": "Programar Apagado", - "description": "Programma il tuo nodo guardiano per spegnersi dopo un'altezza di sessione specifica per un aggiornamento coordinato dei tuoi binari fedimintd.", - "current-session": "Sesión Actual", - "session-to-shutdown": "Sesión para apagar en", - "confirm-shutdown": "Confirmar Apagado", - "session-to-shutdown-helper": "Ingrese la altura de la sesión a la que desea apagar su nodo guardián." - } - } - }, - "login": { - "title": "¡Bienvenido de nuevo!", - "subtitle": "Por favor, ingrese su contraseña.", - "password": "Contraseña", - "submit": "Enviar" - }, - "role-selector": { - "disclaimer-title": "Fedimint è un software beta", - "disclaimer-text": "Segnala problemi su https://github.com/fedimint/fedimint/issues", - "leader": { - "label": "Configurador de Líder", - "description": "Ingrese la configuración que otros Guardianes aprueban. Un Guardián actúa como Líder de Configuración." - }, - "follower": { - "label": "Seguidor", - "description": "Sobald ein Setup-Leiter die Konfigurationen festgelegt hat, wählen andere Wächter diese Option, um die Einstellungen zu genehmigen und die Föderation zu gründen." - }, - "solo": { - "label": "Sólo", - "description": "Fedimint'i konsensüs, hata toleransı, federatif yedeklemeler veya Fedimint'in diğer dayanıklılık avantajları olmadan Tekil Koruyucu olarak çalıştırın. Dikkatli ilerleyin, üretim kullanımı için tasarlanmamıştır." - }, - "warning-modal": { - "title": "¿Está todo el mundo listo?", - "description": "Salir de la ceremonia de configuración puede hacer que la configuración falle y requerir que reinicies tu guardián. ¡Asegúrate de que todos estén listos para ejecutar la configuración completa antes de continuar!" - } - }, - "run-dkg": { - "error-config": "Échec de l'exécution de la génération de clés distribuées. La configuration de la fédération doit être redémarrée.", - "error-default": "Not ready for DKG, your current status is", - "error-header": "Algo salió mal.", - "waiting-header": "Warten auf Peers...", - "generating-header": "Generando códigos..." - }, - "set-config": { - "bft-explanation-title": "Tolerancia a fallos bizantinos de tu federación", - "bft-explanation": "Un {{total}} Fédération des Gardiens crée un {{honest}}/{{total}} Seuil.", - "bft-faulty": "Your Federation will be able to tolerate {{faulty}} faulty, offline, or malicious Guardians without impacting the Federation's operations.", - "guardian-name": "Guardian name", - "guardian-name-help": "Este nombre aleatorio se mostrará a otros Guardianes durante la configuración.", - "admin-password": "Admin-Passwort", - "admin-password-generate": "Generar", - "admin-password-set": "Clicca su 'Genera' per creare una password sicura. Puoi modificarla, ma questa password deve essere sicura e salvata!", - "admin-password-help": "¡Haz una copia de esta contraseña y mantenla a salvo! ¡No puedes recuperar esta contraseña!", - "admin-password-backup": "Estoy usando una contraseña fuerte y la he respaldado. (¡No puedes recuperar esta contraseña!)", - "confirm-password": "Confirmer le mot de passe", - "error-password-mismatch": "Las contraseñas no coinciden", - "join-federation": "Join Federation link", - "join-federation-help": "Pide a la persona que creó la Federación un enlace y pégalo aquí.", - "basic-settings": "Fundamentos", - "federation-settings": "Federación de configuraciones", - "federation-name": "Federation name", - "guardian-number": "Número de guardianes", - "guardian-number-help": "Las federaciones requieren un mínimo de 4 guardianes. Esto no se puede cambiar más tarde.", - "bitcoin-settings": "Bitcoin-Einstellungen", - "block-confirmations": "Confirmaciones de Bloque Adicionales", - "block-confirmations-help": "Fedimint Guardians siguen la punta de la blockchain por varias confirmaciones para evitar reorganizaciones de bloques.", - "block-confirmations-warning": "¡Ejecutar Fedimint con menos de 5 confirmaciones de bloque adicionales es extremadamente arriesgado! Fedimint NO PUEDE manejar reorganizaciones de blockchain.", - "bitcoin-network": "Red de Bitcoin", - "select-network": "Sélectionnez un réseau", - "set-rpc-help": "Dirección RPC de Bitcoin configurada localmente", - "bitcoin-rpc": "Bitcoin RPC", - "error-valid-number": "Por favor, ingrese un número válido.", - "error-valid-min": "Por favor, ingrese un número de al menos {{min}}.", - "error-valid-max": "Por favor, ingrese un número de como máximo {{max}}.", - "error-valid-min-max": "Por favor, ingrese un número entre {{min}} y {{max}}.", - "meta-fields": "Meta campos", - "meta-fields-description": "Veja documentação para mais informações.", - "meta-fields-key": "Meta key", - "meta-fields-value": "Valor", - "meta-fields-effect": "Efecto", - "meta-fields-add-another": "Fügen Sie einen weiteren hinzu", - "meta-fields-title": "Ваше предложение Meta:", - "password-warning": "Devi fare una copia di backup della tua password e conservarla in un luogo sicuro. Questa password è necessaria per accedere alla tua dashboard dei guardiani. Non puoi recuperarla se la perdi!", - "password-warning-title": "Fai una copia di backup della tua password!", - "acknowledge-backed-up": "Yo, {{guardianName}} (tu nombre de guardián), prometo que he respaldado y asegurado mi contraseña:", - "confirm-and-backup-password": "Bestätigen und Sichern Sie das Passwort", - "error-guardian-name-mismatch": "El nombre del guardián no coincide.", - "network": "Redes" - }, - "setup": { - "common": { - "restart-setup": "Reiniciar Configuración", - "restart-setup-alert": "El Líder de Configuración ha reiniciado la Ceremonia de Configuración. Por favor, haga clic en \"Reiniciar\" a continuación para continuar.", - "confirm-restart-setup": "¿Estás seguro de que quieres reiniciar la Ceremonia de Configuración?", - "confirm-restart-setup-alert": "Clicando em \"Reiniciar\" reiniciará a cerimônia para todos os Guardiões." - }, - "progress": { - "tos": { - "title": "Términos de servicio" - }, - "start": { - "title": "Bienvenido, Guardián!", - "subtitle": "Vamos a configurar tu federación.", - "step": "Detalles de la federación" - }, - "set-config": { - "title": "Necesitamos establecer algunas configuraciones para tu Federación.", - "title-solo": "Necesitamos establecer algunas configuraciones para tu Federación Solo.", - "subtitle-leader": "Ваши последователи Федерации подтвердят эту информацию с их стороны.", - "subtitle-solo": "Running a Solo Federation loses many of the benefits of Fedimint. You will not have fault tolerance consensus to a guardian being offline and not be able to do federated backups. Proceed with caution, not recommended for production use or use with mainnet Bitcoin.", - "subtitle-follower": "Ваш лидер Федерации будет настраивать основные детали Федерации. Вы скоро их подтвердите.", - "step": "Detalles de la federación" - }, - "connect-guardians": { - "title-leader": "Invita a tus Guardianes", - "title-follower": "Confirme su información de la Federación", - "subtitle-leader": "Teile den Link mit den anderen Wächtern, um alle auf denselben Stand zu bringen. Sobald alle Wächter beitreten, wirst du automatisch zum nächsten Schritt übergehen.", - "subtitle-follower": "Asegúrate de que la información aquí sea correcta y de que los Guardianes de la Federación estén correctos. Haz clic en el botón Aprobar cuando estés seguro de que se ve bien.", - "step-leader": "Invitar Guardianes", - "step-follower": "Confirmar información" - }, - "run-dkg": { - "title": "¡Éxito!", - "subtitle": "Todos los Guardianes han validado los detalles de configuración de la federación. Ejecutando algunos números..." - }, - "verify-guardians": { - "title": "Verifica tus Guardianes", - "subtitle": "Frage jeden Wächter nach seinem Verifizierungscode und füge ihn unten ein, um die Gültigkeit zu überprüfen. Wir sind fast fertig!", - "step": "Verificar tutores", - "leader-confirm-done": "Confirma que todos los Guardianes seguidores han hecho clic en \"Siguiente\" y revisa sus paneles de guardianes antes de continuar.", - "leader-confirm-done-emphasis": "Clicando em \"Continuar\" você completará a cerimônia de configuração." - }, - "setup-complete": { - "step": "¡Hecho!" - }, - "error": { - "title": "Unbekannter Schritt", - "subtitle": "¿¡Cómo llegaste aquí!?" - } - }, - "warning": { - "title": "¡No salgas ni actualices durante la configuración!", - "description": "Salir durante la configuración puede hacer que la configuración falle y tendrás que reiniciar desde cero." - } - }, - "setup-complete": { - "header": "🎉 🎉 🎉", - "congratulations": "Felicidades", - "leader-message": "Todos los códigos de verificación de los Guardianes han sido verificados.", - "follower-message": "Hai finito! Fai sapere agli altri Guardiani che sei operativo!", - "continue": "Continuar" - }, - "terms-of-service": { - "agree-and-continue": "Acuerdo y continuar" - }, - "verify-guardians": { - "verified": "Verificado", - "verified-placeholder": "Pegar código aqui", - "error": "Algo salió mal.", - "error-peer-id": "No se puede determinar qué par eres. Por favor, actualiza y vuelve a intentarlo.", - "verification-code": "Tu código de verificación", - "verification-code-help": "Teilen Sie diesen Code mit anderen Wächtern.", - "table-title": "Código de verificación del guardián", - "table-description": "Ingrese los códigos de verificación de cada Guardián a continuación.", - "table-column-name": "Nombre", - "table-column-status": "Estado", - "table-column-hash-input": "Colle il codice di verifica", - "wait-all-guardians-verification": "Aguardando todos os Guardiões para verificar seus códigos", - "all-guardians-verified": "Todos los Guardianes han verificado sus códigos.", - "starting-consensus": "Iniciando consenso..." - }, - "footer": { - "docs-section-header": "文档", - "community-section-header": "Comunidad", - "contribute-section-header": "Contribuir", - "getting-started-link-text": "Comenzando", - "faq-link-text": "Preguntas Frecuentes", - "blog-link-text": "Blog", - "discord-link-text": "Discord", - "twitter-link-text": "Twitter", - "github-link-text": "GitHub" - } -} diff --git a/apps/guardian-ui/src/languages/ja.json b/apps/guardian-ui/src/languages/ja.json deleted file mode 100644 index 9b40dbb5b..000000000 --- a/apps/guardian-ui/src/languages/ja.json +++ /dev/null @@ -1,344 +0,0 @@ -{ - "common": { - "bitcoin": "ビットコイン", - "next": "次へ", - "back": "戻る", - "error": "何かがうまくいきませんでした。", - "unknown": "不明", - "remove": "削除", - "copy": "コピー", - "copied": "コピーしました!", - "cancel": "キャンセル", - "review": "レビュー", - "approvals": "承認", - "approve": "承認する", - "threshold": "閾値", - "confirm": "確認する", - "you": "あなた", - "close": "閉じる", - "save": "保存", - "continue": "続ける", - "submit": "送信" - }, - "notConfigured": { - "title": "未構成", - "description": "Fedimintの構成サーバーのURLを入力してください。" - }, - "connect-guardians": { - "invite-guardians": "フォロワーを招待する", - "invite-guardians-help": "このリンクを他のガーディアンと共有してください。", - "approve": "承認する", - "approved": "承認済み", - "pending": "保留中", - "not-joined": "参加していない", - "waiting-for-guardian": "守護者を待っています", - "table-title": "連邦の守護者", - "table-description": "ガーディアンは、連邦設定を確認するとここで確認されます。", - "meta-field-key": "メタフィールド - {{key}}" - }, - "federation-dashboard": { - "invite-members": "メンバーを招待するか、ガーディアンとして認証する", - "invite-members-prompt": "このリンクを共有して、メンバーを連邦に招待してください。", - "fed-info": { - "label": "連邦情報", - "your-status-label": "ステータス", - "block-count-label": "コンセンサスブロック高", - "api-version-label": "API バージョン", - "consensus-version-label": "コンセンサス版", - "peer-id-label": "ピアID", - "session-info": { - "session-height": "セッションの高さ", - "latest-session": "最新のセッション" - } - }, - "balance": { - "label": "バランスシート" - }, - "bitcoin-node": { - "label": "ビットコインノード", - "url-label": "URL", - "network-label": "ネットワーク" - }, - "guardians": { - "label": "他の守護者", - "id-name-label": "ID: 名前", - "status-label": "接続状況", - "health-label": "健康", - "health-issue": "問題", - "health-good": "良い", - "last-contribution-label": "最後のセッション貢献", - "api-url-label": "APIのURL", - "fetching-announcement": "お知らせを取得中..." - }, - "gateways": { - "label": "ライトニングゲートウェイ", - "node-id-label": "ライトニングノードID", - "gateway-id-label": "ゲートウェイID", - "fee-label": "ゲートウェイ手数料", - "view-on-site": "{{site}}で表示", - "no-gateways-info-title": "まだ接続されたゲートウェイはありません!", - "no-gateways-info-description": "ライトニングノードオペレーターは、ライトニングネットワークの相互運用性を提供するためにあなたのフェデレーションに接続できます。接続されると、ここに表示されます。" - }, - "api-announcements": { - "label": "APIのお知らせ", - "guardian": "守護者", - "api-url": "APIのURL", - "revision": "改訂" - }, - "config": { - "label": "連邦設定", - "view-config": "設定を表示", - "missing-meta-module": "メタフィールドの編集はできません。このフェデレーションではメタモジュールは利用できません。", - "manage-meta": { - "label": "メタを管理する", - "cancel-button": "キャンセル", - "confirm-modal": { - "title": "承認を確認する", - "description": "あなたの承認は、このメタ変更を採用するための閾値に達します。あなたの新しいメタは次のようになります:" - }, - "consensus-meta-label": "現在のコンセンサスにおけるメタ", - "revoke-button": "取り消す", - "no-consensus-meta-message": "コンセンサスにはメタがありません。", - "proposed-meta-label": "メタ提案", - "propose-meta": "メタを提案する", - "propose-new-meta-button": "新しいメタを提案する", - "proposal-approved": "あなたはこの提案を承認しました。", - "no-submitted-meta-message": "レビューするメタ編集はありません。", - "edit-meta-label": "メタを編集", - "edit-consensus-meta-button": "コンセンサスメタを編集する", - "submit-meta-proposal": "メタ提案を提出する", - "peer-approvals": "ピア承認", - "actions": "アクション", - "revision": "改訂", - "setup-meta-title": "連合のためのメタを設定する", - "setup-meta-description": "Fedimintは、クライアントにメタフィールドの形で追加情報を提供できます:クライアントと共有したい任意の情報を持つキー-バリューのペアです。これらのメタフィールドはFedimintによって解釈されることはありませんが、コンセンサスに関連しているため、連合メンバー間で異なることはできません。このようにして、クライアントはその正確性に依存できます。", - "propose-updates": "フェディミントのガーディアンとして、あなたは他のガーディアンによって受け入れられるメタの更新を提案することができます。更新が一定数のガーディアンによって受け入れられると、それは連合の新しいコンセンサスメタとして採用されます。", - "core-meta-fields": "次のメタフィールドは、コアFedimintプロトコルの一部として定義されており、あなたの連合のメタに含めると便利です:", - "meta-field-expiry": "フェデレーションがシャットダウンするUnixタイムスタンプ。", - "meta-field-name": "連合の人間が読み取れる名前", - "meta-field-icon": "連盟のロゴアイコンのURL", - "meta-field-welcome": "連邦に参加する新しいユーザーへの歓迎メッセージ", - "meta-field-gateways": "連合によって審査されたゲートウェイ識別子のリスト", - "your-own-fields": "提案に独自の任意のメタフィールドを追加することもできます。これらは、あなたのフェデレーションに接続するすべてのクライアントのメタに追加され、あなたの好きな目的に使用できます。", - "meta-effect-add": "追加", - "meta-effect-modify": "修正する", - "meta-effect-unchanged": "変更なし", - "proposals": "提案" - } - }, - "modal": { - "client-connect": "クライアントを接続する" - }, - "danger-zone": { - "danger-zone-label": "危険地帯", - "cancel": "キャンセル", - "danger-zone-description": "注意して使用してください!", - "guardian-warning-message": "警告:このコードを誰とも共有しないでください。このコードを持っている人は誰でもガーディアンとして認証できます。プライベートな場所にいることを確認し、誰もあなたの画面を見ていないことを確認してください。", - "guardian-acknowledge": "コードを認識して公開する", - "acknowledge-and-download": "承認して進む", - "guardian-authenticate": "ガーディアンとして認証する", - "guardian-connect-warning": "これを共有しないでください", - "backup": { - "label": "バックアップ", - "title": "バックアップをダウンロード", - "warning-title": "警告", - "warning-text": "バックアップには、連合ガーディアンのプライベートキーと秘密の資料が含まれており、安全に保管する必要があります。このバックアップを使用して復旧するには、管理者パスワードが必要です!", - "cancelButton": "キャンセル", - "acknowledgeButton": "承認してダウンロード" - }, - "sign-api-announcement": { - "label": "サインAPI発表", - "title": "サインAPI発表", - "description": "新しいAPIの発表にサインしてください。", - "current-api-url": "ローカル設定からのAPI URL", - "announced-api-url": "連邦発表からのAPI URL", - "urls-match": "現在のAPI URLは、発表されたAPI URLと一致しています。", - "urls-mismatch": "ローカル設定でAPI URLを変更したため、新しいAPIのお知らせを配信する必要があります。", - "sign-button": "新しいAPI発表にサインする", - "signing-in-progress": "サインイン中...", - "sign-tooltip": "API URLを連合に通知するために、API発表にサインしてください。" - }, - "schedule-shutdown": { - "label": "スケジュールシャットダウン", - "title": "スケジュールシャットダウン", - "description": "特定のセッションの高さの後にガーディアンノードをシャットダウンするようにスケジュールして、fedimintdバイナリの調整されたアップグレードを行ってください。", - "current-session": "現在のセッション", - "session-to-shutdown": "シャットダウンするセッションは", - "confirm-shutdown": "シャットダウンを確認する", - "session-to-shutdown-helper": "シャットダウンしたいガーディアンノードのセッションの高さを入力してください。" - } - } - }, - "login": { - "title": "お帰りなさい!", - "subtitle": "パスワードを入力してください。", - "password": "パスワード", - "submit": "提出する" - }, - "role-selector": { - "disclaimer-title": "Fedimintはベータ版ソフトウェアです", - "disclaimer-text": "問題はhttps://github.com/fedimint/fedimint/issuesで報告してください。", - "leader": { - "label": "セットアップリーダー", - "description": "他のガーディアンが承認する設定を入力してください。1人のガーディアンがセットアップリーダーとして行動します。" - }, - "follower": { - "label": "フォロワー", - "description": "セットアップリーダーが設定を行うと、他のガーディアンはこのオプションを選択して設定を承認し、連邦を作成します。" - }, - "solo": { - "label": "ソロ", - "description": "Fedimintをコンセンサス、フォールトトレランス、連合バックアップ、またはFedimintのその他の耐障害性の利点なしでソロガーディアンとして操作します。注意して進めてください。生産用途には適していません。" - }, - "warning-modal": { - "title": "皆さん、準備はいいですか?", - "description": "セットアップセレモニーを終了すると、セットアップが失敗し、ガーディアンを再起動する必要が生じる可能性があります。続行する前に、全員がフルセットアップを実行する準備ができていることを確認してください!" - } - }, - "run-dkg": { - "error-config": "分散鍵生成の実行に失敗しました。フェデレーションのセットアップを再起動する必要があります。", - "error-default": "DKGの準備ができていません。あなたの現在のステータスは", - "error-header": "何かがうまくいきませんでした。", - "waiting-header": "ピアを待っています...", - "generating-header": "コードを生成中..." - }, - "set-config": { - "bft-explanation-title": "あなたの連合のビザンチン耐障害性", - "bft-explanation": "{{total}}のガーディアン連邦が{{honest}}/{{total}}のしきい値を作成します。", - "bft-faulty": "あなたの連邦は、連邦の運営に影響を与えることなく、{{faulty}} 不良、オフライン、または悪意のあるガーディアンを許容できるようになります。", - "guardian-name": "ガーディアン名", - "guardian-name-help": "このランダムな名前は、設定中に他のガーディアンに表示されます。", - "admin-password": "管理者パスワード", - "admin-password-generate": "生成する", - "admin-password-set": "「生成」をクリックして、安全なパスワードを作成してください。変更することはできますが、このパスワードは安全でバックアップされている必要があります!", - "admin-password-help": "このパスワードをバックアップして、安全に保管してください!このパスワードは復元できません!", - "admin-password-backup": "私は強力なパスワードを使用しており、それをバックアップしました。(このパスワードは復元できません!)", - "confirm-password": "パスワードを確認してください", - "error-password-mismatch": "パスワードが一致しません", - "join-federation": "連邦参加リンク", - "join-federation-help": "連邦を作成した人にリンクを尋ねて、ここに貼り付けてください。", - "basic-settings": "基本事項", - "federation-settings": "連邦設定", - "federation-name": "連邦名", - "guardian-number": "保護者の数", - "guardian-number-help": "連邦には最低4人の守護者が必要です。これは後で変更することはできません。", - "bitcoin-settings": "ビットコイン設定", - "block-confirmations": "追加ブロック確認", - "block-confirmations-help": "Fedimintガーディアンは、ブロック再編成を避けるために、いくつかの確認を経てブロックチェーンの先端を追跡します。", - "block-confirmations-warning": "5回未満の追加ブロック確認でFedimintを運用することは非常に危険です!Fedimintはブロックチェーンの再編成に対応できません。", - "bitcoin-network": "ビットコインネットワーク", - "select-network": "ネットワークを選択してください", - "set-rpc-help": "ローカルに設定されたBitcoin RPCアドレス", - "bitcoin-rpc": "ビットコインRPC", - "error-valid-number": "有効な番号を入力してください。", - "error-valid-min": "{{min}}以上の数字を入力してください。", - "error-valid-max": "{{max}}以下の数を入力してください。", - "error-valid-min-max": "{{min}}と{{max}}の間の数字を入力してください。", - "meta-fields": "メタフィールド", - "meta-fields-description": "詳細についてはドキュメントをご覧ください。", - "meta-fields-key": "メタキー", - "meta-fields-value": "価値", - "meta-fields-effect": "効果", - "meta-fields-add-another": "もう一つ追加する", - "meta-fields-title": "あなたのメタ提案:", - "password-warning": "パスワードをバックアップして、安全に保管してください。このパスワードは復元できません!", - "password-warning-title": "パスワードのバックアップをしてください!", - "acknowledge-backed-up": "私は、{{guardianName}}(あなたの保護者名)として、私のパスワードをバックアップし、安全に保管したことを約束します。", - "confirm-and-backup-password": "パスワードの確認とバックアップ", - "error-guardian-name-mismatch": "保護者の名前が一致しません", - "network": "ネットワーク" - }, - "setup": { - "common": { - "restart-setup": "再設定を再起動", - "restart-setup-alert": "セットアップリーダーがセットアップセレモニーを再起動しました。続行するには、下の「再起動」をクリックしてください。", - "confirm-restart-setup": "セットアップセレモニーを再起動してもよろしいですか?", - "confirm-restart-setup-alert": "「再起動」をクリックすると、すべてのガーディアンの儀式が再起動します。" - }, - "progress": { - "tos": { - "title": "利用規約" - }, - "start": { - "title": "ようこそ、ガーディアン!", - "subtitle": "あなたの連合を設定しましょう。", - "step": "連邦の詳細" - }, - "set-config": { - "title": "あなたのフェデレーションのためにいくつかの設定を行う必要があります。", - "title-solo": "あなたのソロ連邦のためにいくつかの設定を行う必要があります。", - "subtitle-leader": "あなたの連邦フォロワーが彼らの側でこの情報を確認します。", - "subtitle-solo": "ソロフェデレーションを運営すると、Fedimintの多くの利点を失います。ガーディアンがオフラインの場合のフォールトトレランスコンセンサスがなく、フェデレーテッドバックアップもできません。注意して進めてください。プロダクション用途やメインネットビットコインとの使用は推奨されません。", - "subtitle-follower": "あなたの連邦のリーダーが主な連邦の詳細を設定します。すぐにそれを確認します。", - "step": "連邦の詳細" - }, - "connect-guardians": { - "title-leader": "あなたのガーディアンを招待してください", - "title-follower": "連邦情報を確認してください", - "subtitle-leader": "他のガーディアンとリンクを共有して、全員が同じページにいるようにしましょう。すべてのガーディアンが参加すると、自動的に次のステップに進みます。", - "subtitle-follower": "ここの情報が正しいことを確認し、連邦ガーディアンが正しいことを確認してください。問題ないと思ったら、承認ボタンをクリックしてください。", - "step-leader": "ガーディアンを招待する", - "step-follower": "情報を確認する" - }, - "run-dkg": { - "title": "成功!", - "subtitle": "すべてのガーディアンが連邦の設定詳細を確認しました。いくつかの数値を計算中です..." - }, - "verify-guardians": { - "title": "ガーディアンを確認してください", - "subtitle": "各ガーディアンに確認コードを尋ね、それを下に貼り付けて有効性を確認してください。もう少しで完了です!", - "step": "保護者を確認する", - "leader-confirm-done": "すべてのフォロワーガーディアンが「次へ」をクリックし、続行する前に彼らのガーディアンダッシュボードを確認してください。", - "leader-confirm-done-emphasis": "「続ける」をクリックすると、セットアップの儀式が完了します。" - }, - "setup-complete": { - "step": "完了!" - }, - "error": { - "title": "未知のステップ", - "subtitle": "どうやってここに来たの?!" - } - }, - "warning": { - "title": "セットアップ中は終了したりリフレッシュしたりしないでください!", - "description": "セットアップ中に終了すると、セットアップが失敗する可能性があり、再起動を行う必要があります。" - } - }, - "setup-complete": { - "header": "🎉 🎉 🎉", - "congratulations": "おめでとうございます", - "leader-message": "すべてのガーディアンの確認コードが確認されました。", - "follower-message": "すべて完了しました!他のガーディアンにあなたが稼働していることを知らせてください!", - "continue": "続ける" - }, - "terms-of-service": { - "agree-and-continue": "同意して続行" - }, - "verify-guardians": { - "verified": "確認済み", - "verified-placeholder": "コードをここに貼り付けてください", - "error": "何かがうまくいかなかった。", - "error-peer-id": "どのピアであるかを特定できません。リフレッシュして再試行してください。", - "verification-code": "あなたの確認コード", - "verification-code-help": "このコードを他のガーディアンと共有してください", - "table-title": "ガーディアン認証コード", - "table-description": "各ガーディアンの確認コードを下に入力してください。", - "table-column-name": "名前", - "table-column-status": "ステータス", - "table-column-hash-input": "確認コードを貼り付けてください", - "wait-all-guardians-verification": "すべてのガーディアンがコードを確認するのを待っています", - "all-guardians-verified": "すべてのガーディアンがコードを確認しました", - "starting-consensus": "コンセンサスを開始しています..." - }, - "footer": { - "docs-section-header": "ドキュメント", - "community-section-header": "コミュニティ", - "contribute-section-header": "貢献する", - "getting-started-link-text": "始めに", - "faq-link-text": "よくある質問", - "blog-link-text": "ブログ", - "discord-link-text": "ディスコード", - "twitter-link-text": "ツイッター", - "github-link-text": "ギットハブ" - } -} diff --git a/apps/guardian-ui/src/languages/ko.json b/apps/guardian-ui/src/languages/ko.json deleted file mode 100644 index 04fc6496f..000000000 --- a/apps/guardian-ui/src/languages/ko.json +++ /dev/null @@ -1,357 +0,0 @@ -{ - "common": { - "back": "이전", - "bitcoin": "비트코인", - "error": "문제가 발생했습니다.", - "next": "다음", - "unknown": "알려지지 않은", - "remove": "제거하다", - "copy": "복사", - "copied": "복사됨!", - "cancel": "취소", - "review": "리뷰", - "approvals": "승인", - "approve": "승인하다", - "threshold": "임계값", - "confirm": "확인", - "you": "당신", - "close": "닫기", - "save": "저장", - "continue": "계속하다", - "submit": "제출" - }, - "notConfigured": { - "title": "미구성", - "description": "Fedimint 구성 서버의 URL을 입력하세요." - }, - "connect-guardians": { - "approve": "승인", - "approved": "승인됨", - "invite-guardians": "팔로워 초대", - "invite-guardians-help": "이 링크를 다른 가디언과 공유하세요.", - "not-joined": "참여하지 않음", - "pending": "대기 중", - "table-description": "보호자는 페더레이션 설정을 확인하면 여기에서 확인됩니다.", - "table-title": "페더레이션 가디언", - "meta-field-key": "메타 필드 - {{key}}", - "waiting-for-guardian": "보호자를 기다리는 중" - }, - "federation-dashboard": { - "balance": { - "label": "균형" - }, - "bitcoin-node": { - "label": "비트코인 노드", - "network-label": "회로망", - "url-label": "URL" - }, - "fed-info": { - "api-version-label": "API 버전", - "consensus-version-label": "합의 버전", - "block-count-label": "합의 블록 높이", - "label": "연맹 정보", - "your-status-label": "상태", - "peer-id-label": "피어 ID", - "session-info": { - "session-height": "세션 높이", - "latest-session": "최신 세션" - } - }, - "gateways": { - "fee-label": "게이트웨이 수수료", - "gateway-id-label": "게이트웨이 ID", - "label": "라이트닝 게이트웨이", - "node-id-label": "노드 ID", - "view-on-site": "{{site}}에서 보기", - "no-gateways-info-title": "아직 연결된 게이트웨이가 없습니다.", - "no-gateways-info-description": "라이트닝 노드 운영자는 연합에 연결하여 라이트닝 네트워크 상호 운용성을 제공할 수 있습니다. 연결되면 여기에 표시됩니다." - }, - "guardians": { - "health-good": "좋은", - "health-issue": "문제", - "health-label": "건강", - "label": "수호자", - "last-contribution-label": "마지막 세션 기여", - "name-label": "이름", - "status-label": "연결 상태", - "id-name-label": "ID: 이름", - "api-url-label": "API URL", - "fetching-announcement": "공지사항을 가져오는 중..." - }, - "config": { - "label": "연합 설정", - "view-config": "보기", - "missing-meta-module": "", - "manage-meta": { - "tab-label": "", - "consensus-meta-label": "", - "submitted-meta-label": "", - "edit-meta-label": "", - "submit-meta-edits-button": "", - "label": "메타 관리", - "cancel-button": "취소", - "confirm-modal": { - "title": "승인 확인", - "description": "귀하의 승인이 이 메타 변경을 채택하는 기준에 도달할 것입니다. 귀하의 새로운 메타는 다음과 같이 보일 것입니다:" - }, - "revoke-button": "취소", - "no-consensus-meta-message": "합의에는 메타가 없다.", - "proposed-meta-label": "메타 제안", - "propose-meta": "메타 제안", - "propose-new-meta-button": "새로운 메타 제안", - "proposal-approved": "이 제안을 승인하셨습니다.", - "no-submitted-meta-message": "검토할 메타 편집이 없습니다.", - "edit-consensus-meta-button": "편집 합의 메타", - "submit-meta-proposal": "메타 제안 제출", - "peer-approvals": "동료 승인", - "actions": "행동", - "revision": "수정", - "setup-meta-title": "연합을 위한 메타 설정하기", - "setup-meta-description": "Fedimint는 클라이언트에게 메타 필드 형태로 추가 정보를 제공할 수 있습니다: 클라이언트와 공유하고자 하는 임의의 정보가 포함된 키-값 쌍입니다. 이러한 메타 필드는 Fedimint에 의해 해석되지 않지만, 합의와 관련이 있습니다. 즉, 연합 구성원 간에 다를 수 없습니다. 이렇게 함으로써 클라이언트는 그 정확성을 신뢰할 수 있습니다.", - "propose-updates": "페디민트 가디언으로서, 당신은 다른 가디언들이 수용할 메타 업데이트를 제안할 수 있습니다. 업데이트가 일정 수의 가디언들에 의해 수용되면, 그것은 연합의 새로운 합의 메타로 채택됩니다.", - "core-meta-fields": "다음 메타 필드는 핵심 페디민트 프로토콜의 일환으로 정의되었으며, 귀하의 연합 메타에 포함하는 것이 유용합니다:", - "meta-field-expiry": "연합이 종료될 유닉스 타임스탬프.", - "meta-field-name": "연합의 사람이 읽을 수 있는 이름", - "meta-field-icon": "연합의 로고 아이콘에 대한 URL", - "meta-field-welcome": "연합에 가입하는 신규 사용자에게 보내는 환영 메시지", - "meta-field-gateways": "연합에 의해 검증된 게이트웨이 식별자 목록", - "your-own-fields": "제안에 임의의 메타 필드를 추가할 수도 있습니다. 이러한 필드는 귀하의 연합에 연결되는 모든 클라이언트의 메타에 추가되며, 원하는 용도로 사용할 수 있습니다.", - "meta-effect-add": "추가하다", - "meta-effect-modify": "수정하다", - "meta-effect-unchanged": "변경되지 않음", - "proposals": "제안" - }, - "downloadBackup": { - "button": "", - "warningTitle": "", - "warningText": "", - "cancelButton": "", - "acknowledgeButton": "" - } - }, - "invite-members": "회원 초대", - "invite-members-prompt": "이 내용을 공유하여 회원을 연맹에 가입하도록 초대하세요.", - "api-announcements": { - "label": "API 공지사항", - "guardian": "가디언", - "api-url": "API URL", - "revision": "수정" - }, - "modal": { - "client-connect": "클라이언트 연결" - }, - "danger-zone": { - "danger-zone-label": "위험 지역", - "cancel": "취소", - "danger-zone-description": "주의해서 사용하세요!", - "guardian-warning-message": "경고: 이 코드를 누구와도 공유하지 마십시오. 이 코드를 가진 사람은 누구나 Guardian으로 인증할 수 있습니다. 개인적인 장소에 있고 누군가 당신의 화면을 보고 있지 않은지 확인하십시오.", - "guardian-acknowledge": "코드를 인식하고 공개하다", - "acknowledge-and-download": "인정하고 진행하기", - "guardian-authenticate": "가디언으로 인증하기", - "guardian-connect-warning": "이것을 공유하지 마세요", - "backup": { - "label": "백업", - "title": "백업 다운로드", - "warning-title": "경고", - "warning-text": "백업에는 연합 수호자를 위한 개인 키와 비밀 자료가 포함되어 있으며 안전하게 보관해야 합니다. 이 백업을 사용한 복구는 귀하의 관리자 비밀번호가 필요합니다!", - "cancelButton": "취소", - "acknowledgeButton": "인정하고 다운로드" - }, - "sign-api-announcement": { - "label": "서명 API 발표", - "title": "서명 API 발표", - "description": "새 API 발표에 서명하세요.", - "current-api-url": "로컬 구성의 API URL", - "announced-api-url": "연합 발표에서의 API URL", - "urls-match": "현재 API URL이 발표한 API URL과 일치합니다.", - "urls-mismatch": "로컬 구성에서 API URL을 변경했으며 새로운 API 공지를 전파해야 합니다.", - "sign-button": "새 API 발표 서명", - "signing-in-progress": "로그인 진행 중...", - "sign-tooltip": "API URL을 연합에 알리기 위해 API 발표에 서명하세요." - }, - "schedule-shutdown": { - "label": "일정 종료", - "title": "예약 종료", - "description": "특정 세션 높이 이후에 가디언 노드가 종료되도록 예약하여 fedimintd 바이너리의 조정된 업그레이드를 진행하세요.", - "current-session": "현재 세션", - "session-to-shutdown": "세션 종료 시각", - "confirm-shutdown": "종료 확인", - "session-to-shutdown-helper": "가드리안 노드를 종료하려는 세션 높이를 입력하세요." - } - } - }, - "footer": { - "blog-link-text": "블로그", - "community-section-header": "지역 사회", - "contribute-section-header": "기여하다", - "discord-link-text": "불화", - "docs-section-header": "문서", - "faq-link-text": "자주 묻는 질문", - "getting-started-link-text": "시작하기", - "github-link-text": "GitHub", - "twitter-link-text": "트위터" - }, - "login": { - "password": "비밀번호", - "submit": "제출", - "subtitle": "비밀번호를 입력해주세요.", - "title": "돌아온 것을 환영합니다!" - }, - "role-selector": { - "disclaimer-text": "문제점은 https://github.com/fedimint/fedimint/issues 에 보고해 주세요.", - "disclaimer-title": "Fedimint는 베타 소프트웨어입니다", - "follower": { - "description": "구성 리더가 구성을 설정하면 다른 보호자가 이 옵션을 선택하여 설정을 승인하고 연합을 만듭니다.", - "label": "팔로워" - }, - "leader": { - "description": "다른 보호자가 승인한 구성 설정을 입력하세요. 한 명의 보호자가 설정 리더 역할을 합니다.", - "label": "구성 리더" - }, - "solo": { - "label": "독주", - "description": "합의, 내결함성, 통합 백업 또는 Fedimint의 기타 탄력성 이점 없이 Fedimint를 Solo Guardian으로 운영하십시오. 프로덕션 용도로 사용할 수 없으므로 주의해서 진행하세요." - }, - "warning-modal": { - "title": "모두 준비됐나요?", - "description": "설정 의식을 종료하면 설정이 실패할 수 있으며 가디언을 다시 시작해야 할 수 있습니다. 계속 진행하기 전에 모든 사람이 전체 설정을 실행할 준비가 되었는지 확인하세요!" - } - }, - "run-dkg": { - "error-config": "분산 키 생성에 실패했습니다. 연합 설정을 다시 시작해야 합니다.", - "error-default": "DKG를 위한 준비가 되지 않았습니다. 현재 상태는 다음과 같습니다:", - "error-header": "문제가 발생했습니다.", - "generating-header": "코드 생성 중...", - "waiting-header": "피어 대기 중..." - }, - "set-config": { - "admin-password": "관리자 비밀번호", - "admin-password-help": "강력한 비밀번호를 사용하고 백업하세요! 이 비밀번호는 복구할 수 없습니다!", - "confirm-password": "비밀번호 확인", - "error-password-mismatch": "비밀번호가 일치하지 않습니다", - "bitcoin-settings": "비트코인 설정", - "bitcoin-network": "비트코인 네트워크", - "bitcoin-rpc": "비트코인 RPC", - "block-confirmations": "블록 확인", - "block-confirmations-help": "확인하기 전에 필요한 블록 확인 횟수는 몇 개인가요?", - "error-valid-number": "유효한 숫자를 입력해주세요.", - "error-valid-min": "최소한 {{min}} 이상의 숫자를 입력해주세요.", - "error-valid-max": "최대한 {{max}} 이하의 숫자를 입력해주세요.", - "error-valid-min-max": "{{min}}에서 {{max}} 사이의 숫자를 입력해주세요.", - "federation-name": "연합 이름", - "basic-settings": "기본 설정", - "federation-settings": "연합 설정", - "guardian-name": "가디언 이름", - "guardian-name-help": "다른 가디언에게 표시될 이름입니다.", - "guardian-number": "가디언 수", - "guardian-number-help": "연맹에는 최소 4명의 보호자가 필요합니다. 나중에 변경할 수 없습니다.", - "join-federation": "연합 가입 링크", - "join-federation-help": "연합을 생성한 사람에게 링크를 요청하고 여기에 붙여넣으세요.", - "select-network": "네트워크 선택", - "set-rpc-help": "로컬로 구성된 비트코인 RPC 주소", - "block-confirmations-warning": "6개 미만의 블록 확인으로 Fedimint를 실행하는 것은 매우 위험합니다!", - "meta-fields": "메타 필드", - "meta-fields-description": "Fedimint 클라이언트에 추가 구성이 전송되었습니다. 자세한 내용은 문서를 참조하세요.", - "meta-fields-key": "메타 키", - "meta-fields-value": "값", - "meta-fields-add-another": "다른 것을 추가하세요", - "bft-explanation-title": "귀하의 연합의 비잔틴 결함 허용성", - "bft-explanation": "A {{total}} 가디언 연합이 {{honest}}/{{total}} 임계값을 생성합니다.", - "bft-faulty": "귀하의 연합은 {{faulty}} 결함이 있는, 오프라인 상태이거나 악의적인 가디언을 연합의 운영에 영향을 주지 않고 견딜 수 있습니다.", - "admin-password-generate": "생성하다", - "admin-password-set": "생성'을 클릭하여 안전한 비밀번호를 만드세요. 수정할 수 있지만, 이 비밀번호는 안전하고 백업되어야 합니다!", - "admin-password-backup": "나는 강력한 비밀번호를 사용하고 있으며 백업해 두었습니다. (이 비밀번호는 복구할 수 없습니다!)", - "meta-fields-effect": "효과", - "meta-fields-title": "귀하의 메타 제안:", - "password-warning": "비밀번호를 백업하고 안전하게 보관하세요. 이 비밀번호는 복구할 수 없습니다!", - "password-warning-title": "비밀번호 백업!", - "acknowledge-backed-up": "저는 {{guardianName}} (귀하의 보호자 이름)이며, 제 비밀번호를 백업하고 안전하게 보관했음을 약속합니다:", - "confirm-and-backup-password": "비밀번호 확인 및 백업", - "error-guardian-name-mismatch": "보호자 이름이 일치하지 않습니다.", - "network": "네트워크" - }, - "setup": { - "common": { - "restart-setup": "설정 다시 시작", - "restart-setup-alert": "피어가 설정 프로세스를 다시 시작하도록 요청했습니다. 이렇게 하면 Fedimint 노드에 대해 이미 선택한 모든 구성이 재설정됩니다", - "confirm-restart-setup": "설치 행사를 다시 시작하시겠습니까?", - "confirm-restart-setup-alert": "다시 시작\"을 클릭하면 모든 수호자의 의식이 다시 시작됩니다." - }, - "auth": {}, - "progress": { - "connect-guardians": { - "step-follower": "정보 확인", - "step-leader": "보호자 초대", - "subtitle-follower": "여기에 있는 정보가 정확하고 가디언이 올바른지 확인하세요. 확인해 보기 좋을 때 승인 버튼을 클릭하세요.", - "subtitle-leader": "모두가 동일한 페이지에서 작업하기 위해 링크를 다른 가디언들과 공유하세요. 모든 가디언이 가입하면 자동으로 다음 단계로 넘어갑니다.", - "title-follower": "연합 정보를 확인하세요", - "title-leader": "가디언을 초대하세요" - }, - "error": { - "subtitle": "여기에 어떻게 왔나요?!", - "title": "알 수 없는 단계" - }, - "run-dkg": { - "subtitle": "모든 가디언이 연합 설정 정보를 검증했습니다. 몇 가지 계산 중...", - "title": "성공!" - }, - "set-config": { - "step": "제휴 세부정보", - "subtitle-follower": "리더 가디언은 연합의 주요 정보를 설정할 것입니다. 곧 이 정보를 확인하게 됩니다.", - "subtitle-leader": "팔로워 가디언들은 이 정보를 확인하게 됩니다.", - "title": "페더레이션에 대한 몇 가지 구성을 설정해야 합니다", - "title-solo": "솔로 페더레이션을 위한 몇 가지 구성을 설정해야 합니다.", - "subtitle-solo": "Solo Federation을 운영하면 Fedimint의 많은 이점이 사라집니다. 오프라인 상태인 보호자에 대한 내결함성 합의가 없으며 통합 백업을 수행할 수 없습니다. 주의해서 진행하세요. 프로덕션 용도나 메인넷 비트코인과 함께 사용하는 것은 권장되지 않습니다." - }, - "setup-complete": { - "step": "완료!" - }, - "start": { - "step": "제휴 세부정보", - "subtitle": "연맹을 설정합시다.", - "title": "Fedimint에 오신 것을 환영합니다!" - }, - "verify-guardians": { - "step": "보호자 확인", - "subtitle": "각 가디언으로부터 검증 코드를 요청하고 아래에 붙여넣어 유효성을 확인하세요. 거의 끝났습니다!", - "title": "가디언 확인", - "leader-confirm-done": "모든 팔로워 가디언이 \"다음\"을 클릭하고 가디언 대시보드를 확인했는지 확인한 후 계속 진행하세요.", - "leader-confirm-done-emphasis": "계속\"을 클릭하면 설정 절차가 완료됩니다." - }, - "tos": { - "title": "서비스 약관" - } - }, - "warning": { - "title": "설치 중에는 종료하거나 새로 고침하지 마세요!", - "description": "설치 중에 종료하면 설치가 실패할 수 있으며, 새로 시작해야 할 수 있습니다." - } - }, - "setup-complete": { - "congratulations": "축하합니다", - "continue": "계속", - "header": "🎉 🎉 🎉", - "sentence-one": "모든 가디언의 검증 코드가 확인되었습니다.", - "leader-message": "모든 수호자의 인증 코드가 확인되었습니다.", - "follower-message": "모두 완료되었습니다! 다른 가디언들에게 당신이 실행 중이라고 알려주세요!" - }, - "verify-guardians": { - "all-guardians-verified": "모든 보호자가 코드를 확인했습니다", - "error": "문제가 발생했습니다.", - "error-peer-id": "어떤 피어인지 확인할 수 없습니다. 새로 고침 후 다시 시도하세요.", - "starting-consensus": "합의 시작 중...", - "table-column-hash-input": "검증 코드 붙여넣기", - "table-column-name": "이름", - "table-column-status": "상태", - "table-description": "각 가디언의 검증 코드를 아래에 입력하세요.", - "table-title": "가디언 검증 코드", - "verification-code": "검증 코드", - "verification-code-help": "이 코드를 다른 가디언과 공유하세요.", - "verified": "확인됨", - "verified-placeholder": "여기에 코드를 입력하세요", - "wait-all-guardians-verification": "모든 보호자가 코드를 확인하기를 기다리는 중" - }, - "terms-of-service": { - "agree-and-continue": "동의하고 계속하세요" - } -} diff --git a/apps/guardian-ui/src/languages/pt.json b/apps/guardian-ui/src/languages/pt.json deleted file mode 100644 index 973113ea4..000000000 --- a/apps/guardian-ui/src/languages/pt.json +++ /dev/null @@ -1,344 +0,0 @@ -{ - "common": { - "bitcoin": "Bitcoin", - "next": "Próximo", - "back": "Voltar", - "error": "Algo deu errado.", - "unknown": "Desconhecido", - "remove": "Remover", - "copy": "Copiar", - "copied": "Copiado!", - "cancel": "Cancelar", - "review": "Revisão", - "approvals": "Aprovações", - "approve": "Aprovar", - "threshold": "Limite", - "confirm": "Confirmar", - "you": "Você", - "close": "Fechar", - "save": "Salvar", - "continue": "Continuar", - "submit": "Enviar" - }, - "notConfigured": { - "title": "Não configurado", - "description": "Por favor, insira a URL do servidor de configuração Fedimint para continuar." - }, - "connect-guardians": { - "invite-guardians": "Convidar Seguidores", - "invite-guardians-help": "Compartilhe este link com os outros Guardiões.", - "approve": "Aprovar", - "approved": "Aprovado", - "pending": "Pendente", - "not-joined": "Não unido", - "waiting-for-guardian": "Aguardando o guardião", - "table-title": "Guardiões da Federação", - "table-description": "Os guardiões serão confirmados aqui assim que confirmarem as configurações da Federação.", - "meta-field-key": "Campo meta - {{key}}" - }, - "federation-dashboard": { - "invite-members": "Convide membros ou autentique-se como um guardião", - "invite-members-prompt": "Compartilhe isso para convidar membros a se juntarem à federação.", - "fed-info": { - "label": "Informações da Federação", - "your-status-label": "Status", - "block-count-label": "Altura do Bloco de Consenso", - "api-version-label": "Versão da API", - "consensus-version-label": "Versão de consenso", - "peer-id-label": "ID do Parceria", - "session-info": { - "session-height": "Altura da Sessão", - "latest-session": "Última Sessão" - } - }, - "balance": { - "label": "Balanço Patrimonial" - }, - "bitcoin-node": { - "label": "Nó Bitcoin", - "url-label": "URL", - "network-label": "Rede" - }, - "guardians": { - "label": "Outros Guardiões", - "id-name-label": "ID: Nome", - "status-label": "Status da Conexão", - "health-label": "Saúde", - "health-issue": "Problema", - "health-good": "Bom", - "last-contribution-label": "Última Contribuição de Sessão", - "api-url-label": "URL da API", - "fetching-announcement": "Buscando anúncio..." - }, - "gateways": { - "label": "Portais de Relâmpago", - "node-id-label": "ID do Nó Lightning", - "gateway-id-label": "ID do Gateway", - "fee-label": "Taxa de gateway", - "view-on-site": "Ver em {{site}}", - "no-gateways-info-title": "Nenhum gateway conectado ainda!", - "no-gateways-info-description": "Os operadores de nós Lightning podem se conectar à sua federação para fornecer interoperabilidade da Lightning Network. Uma vez conectados, eles aparecerão aqui." - }, - "api-announcements": { - "label": "Anúncios da API", - "guardian": "Guardião", - "api-url": "URL da API", - "revision": "Revisão" - }, - "config": { - "label": "Configuração da Federação", - "view-config": "Ver Configuração", - "missing-meta-module": "A edição de campos Meta não é possível. O módulo Meta não está disponível para esta federação.", - "manage-meta": { - "label": "Gerenciar Meta", - "cancel-button": "Cancelar", - "confirm-modal": { - "title": "Confirmar Aprovação", - "description": "Sua aprovação atingirá o limite para adotar essa mudança meta. Sua nova meta será assim:" - }, - "consensus-meta-label": "Meta atual em consenso", - "revoke-button": "Revogar", - "no-consensus-meta-message": "não há meta no consenso", - "proposed-meta-label": "Propostas Meta", - "propose-meta": "Propor Meta", - "propose-new-meta-button": "Propor Novo Meta", - "proposal-approved": "Você aprovou esta proposta.", - "no-submitted-meta-message": "não há edições meta para revisar", - "edit-meta-label": "Editar meta", - "edit-consensus-meta-button": "Editar Meta de Consenso", - "submit-meta-proposal": "Enviar Proposta Meta", - "peer-approvals": "Aprovações de Colegas", - "actions": "Ações", - "revision": "Revisão", - "setup-meta-title": "Configurando um Meta para sua Federação", - "setup-meta-description": "Fedimint pode fornecer informações adicionais aos clientes na forma de campos meta: pares de chave-valor com informações arbitrárias que você pode querer compartilhar com os clientes. Embora esses campos meta não sejam interpretados pelo Fedimint, eles são relevantes para o consenso, ou seja, não podem diferir entre os membros da federação. Dessa forma, os clientes podem confiar em sua correção.", - "propose-updates": "Como um guardião do fedimint, você pode propor atualizações para o meta que serão aceitas pelos outros guardiões. Uma vez que a atualização é aceita por um limite de guardiões, ela será adotada como o novo meta de consenso para a federação.", - "core-meta-fields": "Os seguintes campos meta foram definidos como parte do protocolo central Fedimint e são úteis para incluir nos meta da sua federação:", - "meta-field-expiry": "Um timestamp Unix após o qual a federação será encerrada.", - "meta-field-name": "O nome legível por humanos da federação", - "meta-field-icon": "Uma URL para um ícone de logo para a federação", - "meta-field-welcome": "Uma mensagem de boas-vindas para novos usuários que estão se juntando à federação.", - "meta-field-gateways": "Uma lista de identificadores de gateway aprovados pela federação", - "your-own-fields": "Você também pode adicionar seus próprios campos meta arbitrários à proposta. Estes serão adicionados ao meta de todos os clientes que se conectam à sua federação e podem ser usados para qualquer propósito que você desejar.", - "meta-effect-add": "Adicionar", - "meta-effect-modify": "Modificar", - "meta-effect-unchanged": "Inalterado", - "proposals": "Propostas" - } - }, - "modal": { - "client-connect": "Conectar um Cliente" - }, - "danger-zone": { - "danger-zone-label": "Zona de Perigo", - "cancel": "Cancelar", - "danger-zone-description": "Use com cautela!", - "guardian-warning-message": "AVISO: Não compartilhe este código com ninguém. Qualquer pessoa com este código pode se autenticar como um Guardião. Certifique-se de que você está em um local privado e que ninguém está olhando para a sua tela.", - "guardian-acknowledge": "Reconhecer e Revelar Código", - "acknowledge-and-download": "Reconhecer e Prosseguir", - "guardian-authenticate": "Autenticar como Guardião", - "guardian-connect-warning": "NÃO COMPARTILHE ISSO", - "backup": { - "label": "Cópia de segurança", - "title": "Baixar Backup", - "warning-title": "Aviso", - "warning-text": "O backup contém chaves privadas e material secreto para o guardião da federação e deve ser mantido seguro. A recuperação usando este backup requer sua senha de administrador!", - "cancelButton": "Cancelar", - "acknowledgeButton": "Reconhecer e Baixar" - }, - "sign-api-announcement": { - "label": "Anúncio da API de Assinatura", - "title": "Anúncio da API de Assinatura", - "description": "Assine um novo anúncio de API.", - "current-api-url": "Sua URL da API da Configuração Local", - "announced-api-url": "Sua URL da API de Anúncios da Federação", - "urls-match": "Sua URL de API atual corresponde à sua URL de API anunciada.", - "urls-mismatch": "Você alterou a URL da API em sua configuração local e precisa fazer um novo anúncio da API.", - "sign-button": "Anúncio da nova API", - "signing-in-progress": "Fazendo login...", - "sign-tooltip": "Assine o anúncio da API para anunciar sua URL da API à federação." - }, - "schedule-shutdown": { - "label": "Agendar Desligamento", - "title": "Agendar Desligamento", - "description": "Programe seu nó guardião para desligar após uma altura de sessão específica para uma atualização coordenada de seus binários fedimintd.", - "current-session": "Sessão Atual", - "session-to-shutdown": "Sessão para desligar em", - "confirm-shutdown": "Confirmar Desligamento", - "session-to-shutdown-helper": "Insira a altura da sessão na qual você deseja desligar seu nó guardião." - } - } - }, - "login": { - "title": "Bem-vindo de volta!", - "subtitle": "Por favor, insira sua senha.", - "password": "Senha", - "submit": "Enviar" - }, - "role-selector": { - "disclaimer-title": "Fedimint é um software beta.", - "disclaimer-text": "Por favor, reporte problemas em https://github.com/fedimint/fedimint/issues", - "leader": { - "label": "Configuração do Líder", - "description": "Insira as configurações que outros Guardiões aprovam. Um Guardião atua como Líder de Configuração." - }, - "follower": { - "label": "Seguidor", - "description": "Uma vez que um Líder de Configuração define as configurações, outros Guardiões escolhem esta opção para aprovar as definições e criar a Federação." - }, - "solo": { - "label": "Solo", - "description": "Operar o Fedimint como um Guardião Solo sem consenso, tolerância a falhas, backups federados ou outros benefícios de resiliência do Fedimint. Proceda com cautela, não é destinado para uso em produção." - }, - "warning-modal": { - "title": "Está todo mundo pronto?", - "description": "Sair da cerimônia de configuração pode fazer com que a configuração falhe e exigir que você reinicie seu guardião. Certifique-se de que todos estejam prontos para executar a configuração completa antes de continuar!" - } - }, - "run-dkg": { - "error-config": "Falha ao executar a geração de chaves distribuídas. A configuração da federação deve ser reiniciada.", - "error-default": "Não está pronto para DKG, seu status atual é", - "error-header": "Algo deu errado.", - "waiting-header": "Aguardando pares...", - "generating-header": "Gerando códigos..." - }, - "set-config": { - "bft-explanation-title": "Tolerância a Falhas Bizantinas da Sua Federação", - "bft-explanation": "Uma {{total}} Federação dos Guardiões cria um {{honesto}}/{{total}} Limite.", - "bft-faulty": "Sua Federação será capaz de tolerar {{faulty}} Guardiões com defeito, offline ou maliciosos, sem impactar as operações da Federação.", - "guardian-name": "Nome do guardião", - "guardian-name-help": "Este nome aleatório será mostrado a outros Guardiões durante a configuração.", - "admin-password": "Senha de administrador", - "admin-password-generate": "Gerar", - "admin-password-set": "Clique em 'Gerar' para criar uma senha segura. Você pode modificá-la, mas esta senha deve ser segura e ter um backup!", - "admin-password-help": "Faça backup desta senha e mantenha-a segura! Você não pode recuperar esta senha!", - "admin-password-backup": "Estou usando uma senha forte e a fiz backup. (Você não pode recuperar esta senha!)", - "confirm-password": "Confirmar senha", - "error-password-mismatch": "As senhas não coincidem", - "join-federation": "Junte-se ao link da Federação", - "join-federation-help": "Peça à pessoa que criou a Federação um link e cole-o aqui.", - "basic-settings": "Noções básicas", - "federation-settings": "Configurações da federação", - "federation-name": "Nome da federação", - "guardian-number": "Número de guardiões", - "guardian-number-help": "As federações exigem um mínimo de 4 guardiões. Isso não pode ser alterado posteriormente.", - "bitcoin-settings": "Configurações do Bitcoin", - "block-confirmations": "Confirmações de Bloco Adicionais", - "block-confirmations-help": "Os Guardiões do Fedimint seguem a ponta da blockchain por várias confirmações para evitar reorganizações de blocos.", - "block-confirmations-warning": "Executar o Fedimint com menos de 5 confirmações de bloco adicionais é extremamente arriscado! O Fedimint NÃO consegue lidar com reorganizações de blockchain.", - "bitcoin-network": "Rede Bitcoin", - "select-network": "Selecione uma rede", - "set-rpc-help": "Endereço RPC do Bitcoin configurado localmente", - "bitcoin-rpc": "Bitcoin RPC", - "error-valid-number": "Por favor, insira um número válido.", - "error-valid-min": "Por favor, insira um número de pelo menos {{min}}.", - "error-valid-max": "Por favor, insira um número de no máximo {{max}}.", - "error-valid-min-max": "Por favor, insira um número entre {{min}} e {{max}}.", - "meta-fields": "Campos meta", - "meta-fields-description": "Veja documentação para mais informações.", - "meta-fields-key": "Chave meta", - "meta-fields-value": "Valor", - "meta-fields-effect": "Efeito", - "meta-fields-add-another": "Adicionar outro", - "meta-fields-title": "Sua Proposta Meta:", - "password-warning": "Você deve fazer um backup da sua senha e mantê-la segura. Esta senha é necessária para acessar seu painel de guardião. Você não pode recuperá-la se perder!", - "password-warning-title": "Faça um backup da sua senha!", - "acknowledge-backed-up": "Eu, {{guardianName}} (seu nome de guardião), prometo que fiz backup e protegi minha senha:", - "confirm-and-backup-password": "Confirmar e Fazer Backup da Senha", - "error-guardian-name-mismatch": "O nome do guardião não corresponde.", - "network": "Rede" - }, - "setup": { - "common": { - "restart-setup": "Reiniciar Configuração", - "restart-setup-alert": "O Líder de Configuração reiniciou a Cerimônia de Configuração. Por favor, clique em \"Reiniciar\" abaixo para continuar.", - "confirm-restart-setup": "Você tem certeza de que deseja reiniciar a Cerimônia de Configuração?", - "confirm-restart-setup-alert": "Clicar em \"Reiniciar\" reiniciará a cerimônia para todos os Guardiões." - }, - "progress": { - "tos": { - "title": "Termos de serviço" - }, - "start": { - "title": "Bem-vindo, Guardião!", - "subtitle": "Vamos configurar sua federação.", - "step": "Detalhes da federação" - }, - "set-config": { - "title": "Precisamos definir algumas configurações para sua Federação.", - "title-solo": "Precisamos definir algumas configurações para sua Federação Solo.", - "subtitle-leader": "Seus Seguidores da Federação confirmarão essas informações do lado deles.", - "subtitle-solo": "Executar uma Federação Solo perde muitos dos benefícios do Fedimint. Você não terá consenso de tolerância a falhas se um guardião estiver offline e não poderá fazer backups federados. Prossiga com cautela, não recomendado para uso em produção ou uso com Bitcoin na mainnet.", - "subtitle-follower": "Seu Líder da Federação estará configurando os principais detalhes da Federação. Você os confirmará em breve.", - "step": "Detalhes da federação" - }, - "connect-guardians": { - "title-leader": "Convide seus Guardiões", - "title-follower": "Confirme suas Informações de Federação", - "subtitle-leader": "Compartilhe o link com os outros Guardiões para que todos estejam na mesma página. Assim que todos os Guardiões se juntarem, você avançará automaticamente para a próxima etapa.", - "subtitle-follower": "Certifique-se de que as informações aqui estão corretas e que os Guardiões da Federação estão certos. Clique no botão Aprovar quando tiver certeza de que está tudo certo.", - "step-leader": "Convide Guardiões", - "step-follower": "Confirmar informações" - }, - "run-dkg": { - "title": "Sucesso!", - "subtitle": "Todos os Guardiões validaram os detalhes da configuração da federação. Executando alguns cálculos..." - }, - "verify-guardians": { - "title": "Verifique seus Guardiões", - "subtitle": "Peça a cada Guardião o seu código de verificação e cole-os abaixo para verificar a validade. Estamos quase lá!", - "step": "Verificar guardiões", - "leader-confirm-done": "Confirme que todos os Guardiões seguidores clicaram em \"Próximo\" e veja seus painéis de guardião antes de continuar.", - "leader-confirm-done-emphasis": "Clicar em \"Continuar\" completará a cerimônia de configuração." - }, - "setup-complete": { - "step": "Feito!" - }, - "error": { - "title": "Passo desconhecido", - "subtitle": "Como você chegou aqui?!" - } - }, - "warning": { - "title": "Não saia ou atualize durante a configuração!", - "description": "Sair durante a configuração pode fazer com que a configuração falhe e você terá que reiniciar do zero." - } - }, - "setup-complete": { - "header": "🎉 🎉 🎉", - "congratulations": "Parabéns", - "leader-message": "Todos os códigos de verificação dos Guardiões foram verificados.", - "follower-message": "Você terminou! Avise os outros Guardiões que você está em execução!", - "continue": "Continuar" - }, - "terms-of-service": { - "agree-and-continue": "Concordar e continuar" - }, - "verify-guardians": { - "verified": "Verificado", - "verified-placeholder": "Cole o código aqui", - "error": "Algo deu errado.", - "error-peer-id": "Não foi possível determinar qual é o seu par. Por favor, atualize e tente novamente.", - "verification-code": "Seu código de verificação", - "verification-code-help": "Compartilhe este código com outros guardiões.", - "table-title": "Códigos de verificação do Guardião", - "table-description": "Insira os códigos de verificação de cada Guardião abaixo.", - "table-column-name": "Nome", - "table-column-status": "Status", - "table-column-hash-input": "Cole o código de verificação", - "wait-all-guardians-verification": "Aguardando todos os Guardiões verificarem seus códigos", - "all-guardians-verified": "Todos os Guardiões verificaram seus códigos.", - "starting-consensus": "Iniciando consenso..." - }, - "footer": { - "docs-section-header": "Documentos", - "community-section-header": "Comunidade", - "contribute-section-header": "Contribuir", - "getting-started-link-text": "Começando", - "faq-link-text": "Perguntas Frequentes", - "blog-link-text": "Blogue", - "discord-link-text": "Discord", - "twitter-link-text": "Twitter", - "github-link-text": "GitHub" - } -} diff --git a/apps/guardian-ui/src/languages/ru.json b/apps/guardian-ui/src/languages/ru.json deleted file mode 100644 index 2ae946ffc..000000000 --- a/apps/guardian-ui/src/languages/ru.json +++ /dev/null @@ -1,344 +0,0 @@ -{ - "common": { - "bitcoin": "Биткойн", - "next": "Далее", - "back": "Назад", - "error": "Что-то пошло не так.", - "unknown": "Неизвестно", - "remove": "Удалить", - "copy": "Копировать", - "copied": "Скопировано!", - "cancel": "Отмена", - "review": "Обзор", - "approvals": "Утверждения", - "approve": "Одобрить", - "threshold": "Порог", - "confirm": "Подтвердить", - "you": "Ты", - "close": "Закрыть", - "save": "Сохранить", - "continue": "Продолжить", - "submit": "Отправить" - }, - "notConfigured": { - "title": "Не настроен", - "description": "Пожалуйста, введите URL сервера конфигурации Fedimint для продолжения." - }, - "connect-guardians": { - "invite-guardians": "Пригласить подписчиков", - "invite-guardians-help": "Поделитесь этой ссылкой с другими Стражами", - "approve": "Утвердить", - "approved": "Утверждено", - "pending": "В ожидании", - "not-joined": "Не присоединился", - "waiting-for-guardian": "Ожидание опекуна", - "table-title": "Стражи Федерации", - "table-description": "Стражи будут подтверждены здесь, как только они подтвердят настройки Федерации.", - "meta-field-key": "Метаполе - {{key}}" - }, - "federation-dashboard": { - "invite-members": "Пригласите участников или аутентифицируйтесь как опекун", - "invite-members-prompt": "Поделитесь этим, чтобы пригласить участников присоединиться к федерации.", - "fed-info": { - "label": "Информация о Федерации", - "your-status-label": "Статус", - "block-count-label": "Консенсусная высота блока", - "api-version-label": "Версия API", - "consensus-version-label": "Версия консенсуса", - "peer-id-label": "Идентификатор участника", - "session-info": { - "session-height": "Высота сессии", - "latest-session": "Последняя сессия" - } - }, - "balance": { - "label": "Баланс" - }, - "bitcoin-node": { - "label": "Биткойн-узел", - "url-label": "URL", - "network-label": "Сеть" - }, - "guardians": { - "label": "Другие Стражи", - "id-name-label": "ИД: Имя", - "status-label": "Статус соединения", - "health-label": "Здоровье", - "health-issue": "Проблема", - "health-good": "Хорошо", - "last-contribution-label": "Последний вклад в сессию", - "api-url-label": "API URL", - "fetching-announcement": "Получение объявления..." - }, - "gateways": { - "label": "Молниеносные шлюзы", - "node-id-label": "Идентификатор узла Lightning", - "gateway-id-label": "Идентификатор шлюза", - "fee-label": "Плата за шлюз", - "view-on-site": "Просмотр на {{site}}", - "no-gateways-info-title": "Пока нет подключенных шлюзов!", - "no-gateways-info-description": "Операторы узлов Lightning могут подключиться к вашей федерации для обеспечения совместимости с сетью Lightning. После подключения они появятся здесь." - }, - "api-announcements": { - "label": "Объявления API", - "guardian": "Страж", - "api-url": "API URL", - "revision": "Ревизия" - }, - "config": { - "label": "Конфигурация Федерации", - "view-config": "Просмотр конфигурации", - "missing-meta-module": "Редактирование метаполей невозможно. Модуль Meta недоступен для этой федерации.", - "manage-meta": { - "label": "Управление Meta", - "cancel-button": "Отмена", - "confirm-modal": { - "title": "Подтвердить одобрение", - "description": "Ваше одобрение достигнет порога для принятия этого мета-изменения. Ваш новый мета будет выглядеть так:" - }, - "consensus-meta-label": "Текущая мета в консенсусе", - "revoke-button": "Отозвать", - "no-consensus-meta-message": "в консенсусе нет мета", - "proposed-meta-label": "Метапредложения", - "propose-meta": "Предложить Meta", - "propose-new-meta-button": "Предложить новый мета", - "proposal-approved": "Вы одобрили это предложение.", - "no-submitted-meta-message": "нет мета-правок для проверки", - "edit-meta-label": "Редактировать мета", - "edit-consensus-meta-button": "Редактировать Консенсус Мета", - "submit-meta-proposal": "Отправить мета-предложение", - "peer-approvals": "Одобрения коллег", - "actions": "Действия", - "revision": "Ревизия", - "setup-meta-title": "Настройка меты для вашей Федерации", - "setup-meta-description": "Fedimint может предоставить дополнительную информацию клиентам в виде метаполей: пар ключ-значение с произвольной информацией, которую вы можете захотеть поделиться с клиентами. Хотя эти метаполя не интерпретируются Fedimint, они имеют значение для консенсуса, т.е. они не могут отличаться между членами федерации. Таким образом, клиенты могут полагаться на их корректность.", - "propose-updates": "В качестве хранителя fedimint вы можете предлагать обновления метаданных, которые будут приняты другими хранителями. Как только обновление будет принято порогом хранителей, оно будет принято в качестве нового консенсусного мета для федерации.", - "core-meta-fields": "Следующие метаполя были определены как часть основного протокола Fedimint и полезны для включения в метаданные вашей федерации:", - "meta-field-expiry": "Универсальная метка времени, после которой федерация будет закрыта.", - "meta-field-name": "Читаемое человеком название федерации", - "meta-field-icon": "URL для логотипа федерации", - "meta-field-welcome": "Приветственное сообщение для новых пользователей, присоединяющихся к федерации", - "meta-field-gateways": "Список идентификаторов шлюзов, проверенных федерацией", - "your-own-fields": "Вы также можете добавить свои произвольные метаполя к предложению. Они будут добавлены к метаданных всех клиентов, которые подключаются к вашей федерации, и могут использоваться для любых целей, которые вам нравятся.", - "meta-effect-add": "Добавить", - "meta-effect-modify": "Изменить", - "meta-effect-unchanged": "Без изменений", - "proposals": "Предложения" - } - }, - "modal": { - "client-connect": "Подключить клиента" - }, - "danger-zone": { - "danger-zone-label": "Зона опасности", - "cancel": "Отменить", - "danger-zone-description": "Используйте с осторожностью!", - "guardian-warning-message": "ПРЕДУПРЕЖДЕНИЕ: Не делитесь этим кодом ни с кем. Любой, у кого есть этот код, может аутентифицироваться как Хранитель. Убедитесь, что вы находитесь в уединенном месте и никто не смотрит на ваш экран.", - "guardian-acknowledge": "Признайте и раскройте код", - "acknowledge-and-download": "Принять и продолжить", - "guardian-authenticate": "Аутентификация как Хранитель", - "guardian-connect-warning": "НЕ ДЕЛИТЕСЬ ЭТИМ", - "backup": { - "label": "Резервное копирование", - "title": "Скачать резервную копию", - "warning-title": "Предупреждение", - "warning-text": "Резервная копия содержит приватные ключи и секретные материалы для федеративного хранителя и должна храниться в безопасности. Восстановление с использованием этой резервной копии требует вашего административного пароля!", - "cancelButton": "Отменить", - "acknowledgeButton": "Принять и скачать" - }, - "sign-api-announcement": { - "label": "Объявление о Sign API", - "title": "Объявление API Sign", - "description": "Подпишите новое объявление API.", - "current-api-url": "Ваш URL API из локальной конфигурации", - "announced-api-url": "Ваш URL API из объявлений Федерации", - "urls-match": "Ваш текущий URL API соответствует вашему объявленному URL API.", - "urls-mismatch": "Вы изменили URL API в вашей локальной конфигурации и необходимо сделать новое объявление API.", - "sign-button": "Подпишите новое объявление API", - "signing-in-progress": "Вход в систему...", - "sign-tooltip": "Подпишите объявление API, чтобы объявить ваш URL API федерации." - }, - "schedule-shutdown": { - "label": "Запланировать отключение", - "title": "Запланировать отключение", - "description": "Запланируйте отключение вашего узла-стража после достижения определенной высоты сессии для координированного обновления ваших бинарных файлов fedimintd.", - "current-session": "Текущая сессия", - "session-to-shutdown": "Сессия для завершения работы в", - "confirm-shutdown": "Подтвердить завершение работы", - "session-to-shutdown-helper": "Введите высоту сессии, при которой вы хотите отключить свой узел-страж." - } - } - }, - "login": { - "title": "С возвращением!", - "subtitle": "Пожалуйста, введите ваш пароль.", - "password": "Пароль", - "submit": "Отправить" - }, - "role-selector": { - "disclaimer-title": "Fedimint - это бета-версия программного обеспечения.", - "disclaimer-text": "Пожалуйста, сообщайте о проблемах по адресу https://github.com/fedimint/fedimint/issues", - "leader": { - "label": "Настройка лидера", - "description": "Введите настройки конфигурации, которые одобряют другие Стражи. Один Страж выступает в роли Руководителя настройки." - }, - "follower": { - "label": "Подписчик", - "description": "Как только Лидер Настройки устанавливает конфигурации, другие Стражи выбирают эту опцию, чтобы одобрить настройки и создать Федерацию." - }, - "solo": { - "label": "Соло", - "description": "Управляйте Fedimint как одиночный хранитель без консенсуса, отказоустойчивости, федеративных резервных копий или других преимуществ устойчивости Fedimint. Действуйте осторожно, не предназначено для производственного использования." - }, - "warning-modal": { - "title": "Все готовы?", - "description": "Выход из церемонии настройки может привести к сбою настройки и потребовать перезапуска вашего устройства. Убедитесь, что все готовы пройти полную настройку перед продолжением!" - } - }, - "run-dkg": { - "error-config": "Не удалось выполнить распределенную генерацию ключей. Настройку федерации необходимо перезапустить.", - "error-default": "Не готов к DKG, ваш текущий статус -", - "error-header": "Что-то пошло не так.", - "waiting-header": "Ожидание пиров...", - "generating-header": "Генерация кодов..." - }, - "set-config": { - "bft-explanation-title": "Византийская устойчивость к сбоям вашей федерации", - "bft-explanation": "{{total}} Федерация Стражей создает {{честный}}/{{total}} Порог.", - "bft-faulty": "Ваша Федерация сможет терпеть {{faulty}} неисправные, отключенные или злонамеренные Стражи, не влияя на операции Федерации.", - "guardian-name": "Имя хранителя", - "guardian-name-help": "Это случайное имя будет показано другим Стражам во время настройки.", - "admin-password": "Пароль администратора", - "admin-password-generate": "Сгенерировать", - "admin-password-set": "Нажмите 'Сгенерировать', чтобы создать надежный пароль. Вы можете его изменить, но этот пароль должен быть надежным и сохраненным!", - "admin-password-help": "Сохраните этот пароль и держите его в безопасности! Вы не сможете восстановить этот пароль!", - "admin-password-backup": "Я использую надежный пароль и сделал его резервную копию. (Вы не можете восстановить этот пароль!)", - "confirm-password": "Подтвердите пароль", - "error-password-mismatch": "Пароли не совпадают", - "join-federation": "Присоединиться к ссылке Федерации", - "join-federation-help": "Попросите человека, который создал Федерацию, предоставить ссылку и вставьте её сюда.", - "basic-settings": "Основы", - "federation-settings": "Настройки федерации", - "federation-name": "Название федерации", - "guardian-number": "Количество опекунов", - "guardian-number-help": "Федерации требуют минимум 4 хранителей. Это нельзя изменить позже.", - "bitcoin-settings": "Настройки биткойна", - "block-confirmations": "Дополнительные подтверждения блока", - "block-confirmations-help": "Fedimint Guardians отслеживают вершину блокчейна с несколькими подтверждениями, чтобы избежать реорганизаций блоков.", - "block-confirmations-warning": "Запуск Fedimint с менее чем 5 дополнительными подтверждениями блока крайне рискован! Fedimint НЕ может справляться с реорганизациями блокчейна.", - "bitcoin-network": "Биткойн-сеть", - "select-network": "Выберите сеть", - "set-rpc-help": "Локально настроенный адрес Bitcoin RPC", - "bitcoin-rpc": "Биткойн RPC", - "error-valid-number": "Пожалуйста, введите действительное число.", - "error-valid-min": "Пожалуйста, введите число не менее {{min}}.", - "error-valid-max": "Пожалуйста, введите число не более {{max}}.", - "error-valid-min-max": "Пожалуйста, введите число между {{min}} и {{max}}.", - "meta-fields": "Метаполя", - "meta-fields-description": "Смотрите документацию для получения дополнительной информации.", - "meta-fields-key": "Метаключ", - "meta-fields-value": "Значение", - "meta-fields-effect": "Эффект", - "meta-fields-add-another": "Добавить еще один", - "meta-fields-title": "Ваше предложение Meta:", - "password-warning": "Вы должны сделать резервную копию своего пароля и сохранить его в безопасном месте. Этот пароль необходим для доступа к панели управления Стражем. Вы не сможете восстановить его, если потеряете!", - "password-warning-title": "Сделайте резервную копию своего пароля!", - "acknowledge-backed-up": "Я, {{guardianName}} (ваше имя опекуна), обещаю, что я сохранил и защитил свой пароль:", - "confirm-and-backup-password": "Подтвердите и создайте резервную копию пароля", - "error-guardian-name-mismatch": "Имя опекуна не совпадает", - "network": "Сеть" - }, - "setup": { - "common": { - "restart-setup": "Перезапустить установку", - "restart-setup-alert": "Лидер настройки перезапустил церемонию настройки. Пожалуйста, нажмите \"Перезапустить\" ниже, чтобы продолжить.", - "confirm-restart-setup": "Вы уверены, что хотите перезапустить Церемонию Настройки?", - "confirm-restart-setup-alert": "Нажатие \"Перезапустить\" перезапустит церемонию для всех Стражей." - }, - "progress": { - "tos": { - "title": "Условия обслуживания" - }, - "start": { - "title": "Добро пожаловать, Страж!", - "subtitle": "Давайте настроим вашу федерацию.", - "step": "Детали федерации" - }, - "set-config": { - "title": "Нам нужно настроить некоторые параметры для вашей Федерации.", - "title-solo": "Нам нужно настроить некоторые параметры для вашей Solo Federation.", - "subtitle-leader": "Ваши последователи Федерации подтвердят эту информацию с их стороны.", - "subtitle-solo": "Запуск Solo Federation теряет многие преимущества Fedimint. У вас не будет согласия с отказоустойчивостью, если один из хранителей будет офлайн, и вы не сможете выполнять федеративные резервные копии. Будьте осторожны, не рекомендуется для использования в производстве или с основной сетью Bitcoin.", - "subtitle-follower": "Ваш лидер Федерации будет настраивать основные детали Федерации. Вы подтвердите их скоро.", - "step": "Детали федерации" - }, - "connect-guardians": { - "title-leader": "Пригласите своих Стражей", - "title-follower": "Подтвердите вашу информацию о Федерации", - "subtitle-leader": "Поделитесь ссылкой с другими Стражами, чтобы все были в курсе. Как только все Стражи присоединятся, вы автоматически перейдете к следующему шагу.", - "subtitle-follower": "Убедитесь, что информация здесь выглядит правильно и что Хранители Федерации указаны верно. Нажмите кнопку \"Одобрить\", когда будете уверены, что все выглядит хорошо.", - "step-leader": "Пригласить Стражей", - "step-follower": "Подтвердите информацию" - }, - "run-dkg": { - "title": "Успех!", - "subtitle": "Все Стражи подтвердили детали настройки федерации. Запускаю расчеты..." - }, - "verify-guardians": { - "title": "Проверьте своих Стражей", - "subtitle": "Попросите каждого Стража их код подтверждения и вставьте их ниже, чтобы проверить действительность. Мы почти закончили!", - "step": "Проверьте опекунов", - "leader-confirm-done": "Подтвердите, что все подписчики-Стражи нажали \"Далее\" и просмотрите их панели управления Стражами перед продолжением.", - "leader-confirm-done-emphasis": "Нажатие \"Продолжить\" завершит церемонию настройки." - }, - "setup-complete": { - "step": "Готово!" - }, - "error": { - "title": "Неизвестный шаг", - "subtitle": "Как ты сюда попал?!" - } - }, - "warning": { - "title": "Не выходите и не обновляйте страницу во время настройки!", - "description": "Выход во время установки может привести к сбою установки, и вам придется выполнить новый перезапуск." - } - }, - "setup-complete": { - "header": "🎉 🎉 🎉", - "congratulations": "Поздравляю", - "leader-message": "Все коды подтверждения Стражей были проверены.", - "follower-message": "Вы все закончили! Дайте знать другим Стражам, что вы работаете!", - "continue": "Продолжить" - }, - "terms-of-service": { - "agree-and-continue": "Согласен и продолжить" - }, - "verify-guardians": { - "verified": "Проверено", - "verified-placeholder": "Вставьте код сюда", - "error": "Что-то пошло не так.", - "error-peer-id": "Не удалось определить, кто вы. Пожалуйста, обновите страницу и попробуйте снова.", - "verification-code": "Ваш код подтверждения", - "verification-code-help": "Поделитесь этим кодом с другими хранителями.", - "table-title": "Коды проверки Guardian", - "table-description": "Введите коды подтверждения каждого Стража ниже.", - "table-column-name": "Имя", - "table-column-status": "Статус", - "table-column-hash-input": "Вставьте код подтверждения", - "wait-all-guardians-verification": "Ожидание, пока все Стражи подтвердят свои коды", - "all-guardians-verified": "Все Стражи подтвердили свои коды", - "starting-consensus": "Начало консенсуса..." - }, - "footer": { - "docs-section-header": "Документы", - "community-section-header": "Сообщество", - "contribute-section-header": "Содействовать", - "getting-started-link-text": "Начало работы", - "faq-link-text": "Часто задаваемые вопросы", - "blog-link-text": "Блог", - "discord-link-text": "Дискорд", - "twitter-link-text": "Твиттер", - "github-link-text": "ГитХаб" - } -} diff --git a/apps/guardian-ui/src/languages/zh.json b/apps/guardian-ui/src/languages/zh.json deleted file mode 100644 index d5cc4e7e2..000000000 --- a/apps/guardian-ui/src/languages/zh.json +++ /dev/null @@ -1,344 +0,0 @@ -{ - "common": { - "bitcoin": "比特币", - "next": "下一个", - "back": "返回", - "error": "出了点问题。", - "unknown": "未知", - "remove": "移除", - "copy": "复制", - "copied": "复制成功!", - "cancel": "取消", - "review": "审查", - "approvals": "批准", - "approve": "批准", - "threshold": "阈值", - "confirm": "确认", - "you": "你", - "close": "关闭", - "save": "保存", - "continue": "继续", - "submit": "提交" - }, - "notConfigured": { - "title": "未配置", - "description": "请输入Fedimint配置服务器的URL以继续。" - }, - "connect-guardians": { - "invite-guardians": "邀请关注者", - "invite-guardians-help": "将此链接分享给其他守护者", - "approve": "批准", - "approved": "批准", - "pending": "待处理", - "not-joined": "未加入", - "waiting-for-guardian": "等待监护人", - "table-title": "联邦守护者", - "table-description": "守护者将在此处确认,一旦他们确认联邦设置。", - "meta-field-key": "元字段 - {{key}}" - }, - "federation-dashboard": { - "invite-members": "邀请成员或验证为监护人", - "invite-members-prompt": "分享此内容以邀请成员加入联邦", - "fed-info": { - "label": "联邦信息", - "your-status-label": "状态", - "block-count-label": "共识区块高度", - "api-version-label": "API版本", - "consensus-version-label": "共识版本", - "peer-id-label": "对等体ID", - "session-info": { - "session-height": "会话高度", - "latest-session": "最新会议" - } - }, - "balance": { - "label": "资产负债表" - }, - "bitcoin-node": { - "label": "比特币节点", - "url-label": "网址", - "network-label": "网络" - }, - "guardians": { - "label": "其他守护者", - "id-name-label": "ID:名称", - "status-label": "连接状态", - "health-label": "健康", - "health-issue": "问题", - "health-good": "好", - "last-contribution-label": "最后会话贡献", - "api-url-label": "API网址", - "fetching-announcement": "获取公告中..." - }, - "gateways": { - "label": "闪电网关", - "node-id-label": "闪电节点 ID", - "gateway-id-label": "网关ID", - "fee-label": "网关费用", - "view-on-site": "在{{site}}上查看", - "no-gateways-info-title": "还没有连接的网关!", - "no-gateways-info-description": "闪电节点运营商可以连接到您的联盟,以提供闪电网络的互操作性。一旦连接,他们将出现在这里。" - }, - "api-announcements": { - "label": "API公告", - "guardian": "守护者", - "api-url": "API网址", - "revision": "修订" - }, - "config": { - "label": "联邦配置", - "view-config": "查看配置", - "missing-meta-module": "无法编辑元字段。此联合体不支持元模块。", - "manage-meta": { - "label": "管理元数据", - "cancel-button": "取消", - "confirm-modal": { - "title": "确认批准", - "description": "您的批准将达到采纳此元变更的门槛。您的新元将如下所示:" - }, - "consensus-meta-label": "当前共识中的元数据", - "revoke-button": "撤销", - "no-consensus-meta-message": "共识中没有元数据。", - "proposed-meta-label": "元提案", - "propose-meta": "提议元宇宙", - "propose-new-meta-button": "提出新元宇宙", - "proposal-approved": "您已批准此提案", - "no-submitted-meta-message": "没有需要审核的元编辑。", - "edit-meta-label": "编辑元数据", - "edit-consensus-meta-button": "编辑共识元数据", - "submit-meta-proposal": "提交元提案", - "peer-approvals": "同行批准", - "actions": "行动", - "revision": "修订", - "setup-meta-title": "为您的联邦设置一个Meta", - "setup-meta-description": "Fedimint 可以以元字段的形式向客户提供额外信息:键值对,包含您可能想与客户分享的任意信息。虽然这些元字段不会被 Fedimint 解释,但它们与共识相关,即它们不能在联盟成员之间有所不同。这样,客户可以依赖它们的正确性。", - "propose-updates": "作为一个fedimint守护者,您可以提出对元数据的更新,其他守护者将接受这些更新。一旦更新获得一定数量守护者的接受,它将被采纳为联邦的新共识元数据。", - "core-meta-fields": "以下元字段已被定义为核心Fedimint协议的一部分,并且对于您的联盟元数据来说是有用的:", - "meta-field-expiry": "一个联合体将在此时间戳之后关闭。", - "meta-field-name": "联邦的人类可读名称", - "meta-field-icon": "联邦徽标图标的URL", - "meta-field-welcome": "欢迎新用户加入联邦的消息", - "meta-field-gateways": "经过联盟审核的网关标识符列表", - "your-own-fields": "您还可以向提案添加您自己的任意元字段。这些字段将被添加到连接到您的联盟的所有客户端的元数据中,可以用于您喜欢的任何目的。", - "meta-effect-add": "添加", - "meta-effect-modify": "修改", - "meta-effect-unchanged": "不变", - "proposals": "提案" - } - }, - "modal": { - "client-connect": "连接客户端" - }, - "danger-zone": { - "danger-zone-label": "危险区域", - "cancel": "取消", - "danger-zone-description": "请谨慎使用!", - "guardian-warning-message": "警告:请勿与任何人分享此代码。任何拥有此代码的人都可以作为守护者进行身份验证。确保您处于私密地点,且没有人监视您的屏幕。", - "guardian-acknowledge": "确认并揭示代码", - "acknowledge-and-download": "确认并继续", - "guardian-authenticate": "以守护者身份进行身份验证", - "guardian-connect-warning": "请勿分享此内容", - "backup": { - "label": "备份", - "title": "下载备份", - "warning-title": "警告", - "warning-text": "备份包含联邦守护者的私钥和秘密材料,必须妥善保管。使用此备份进行恢复需要您的管理员密码!", - "cancelButton": "取消", - "acknowledgeButton": "确认并下载" - }, - "sign-api-announcement": { - "label": "签名API公告", - "title": "签名 API 公告", - "description": "签署新的API公告。", - "current-api-url": "您从本地配置获取的 API URL", - "announced-api-url": "来自联邦公告的您的API网址", - "urls-match": "您当前的 API URL 与您公布的 API URL 匹配。", - "urls-mismatch": "您已在本地配置中更改了 API URL,需要广播新的 API 通告。", - "sign-button": "签署新的API公告", - "signing-in-progress": "正在登录...", - "sign-tooltip": "签署API公告以向联盟宣布您的API网址。" - }, - "schedule-shutdown": { - "label": "计划关机", - "title": "计划关机", - "description": "安排您的守护节点在特定会话高度后关闭,以便协调升级您的 fedimintd 二进制文件。", - "current-session": "当前会话", - "session-to-shutdown": "会话将在此时关闭", - "confirm-shutdown": "确认关机", - "session-to-shutdown-helper": "输入您希望关闭守护节点的会话高度。" - } - } - }, - "login": { - "title": "欢迎回来!", - "subtitle": "请输入您的密码。", - "password": "密码", - "submit": "提交" - }, - "role-selector": { - "disclaimer-title": "Fedimint是测试版软件", - "disclaimer-text": "请在https://github.com/fedimint/fedimint/issues报告问题", - "leader": { - "label": "设置领导者", - "description": "输入其他守护者批准的配置设置。一个守护者担任设置领导。" - }, - "follower": { - "label": "追随者", - "description": "一旦设置领导者配置了设置,其他守护者选择此选项以批准设置并创建联邦。" - }, - "solo": { - "label": "独奏", - "description": "以单独守护者身份操作 Fedimint,不使用共识、容错、联邦备份或其他 Fedimint 的弹性优势。请谨慎进行,不适合生产环境使用。" - }, - "warning-modal": { - "title": "大家准备好了吗?", - "description": "退出设置仪式可能会导致设置失败,并需要您重新启动守护者。在继续之前,请确保每个人都准备好进行完整的设置!" - } - }, - "run-dkg": { - "error-config": "无法运行分布式密钥生成。必须重新启动联邦设置。", - "error-default": "尚未准备好进行DKG,您当前的状态是", - "error-header": "出了点问题。", - "waiting-header": "等待对等体...", - "generating-header": "生成代码中..." - }, - "set-config": { - "bft-explanation-title": "您的联邦的拜占庭容错性", - "bft-explanation": "一个{{total}}守护者联邦创建了一个{{honest}}/{{total}}阈值。", - "bft-faulty": "您的联邦将能够容忍{{faulty}}故障、离线或恶意的守护者,而不会影响联邦的运作。", - "guardian-name": "守护者名称", - "guardian-name-help": "此随机名称将在设置过程中显示给其他守护者。", - "admin-password": "管理员密码", - "admin-password-generate": "生成", - "admin-password-set": "点击“生成”以创建一个安全的密码。您可以对其进行修改,但此密码必须安全并备份!", - "admin-password-help": "备份此密码并妥善保管!您无法恢复此密码!", - "admin-password-backup": "我正在使用一个强密码并已备份。(您无法恢复此密码!)", - "confirm-password": "确认密码", - "error-password-mismatch": "密码不匹配", - "join-federation": "加入联邦链接", - "join-federation-help": "请向创建联邦的人索要一个链接,并将其粘贴在这里。", - "basic-settings": "基础知识", - "federation-settings": "联邦设置", - "federation-name": "联邦名称", - "guardian-number": "监护人数量", - "guardian-number-help": "联邦需要至少4名守护者。这一点无法更改。", - "bitcoin-settings": "比特币设置", - "block-confirmations": "额外区块确认", - "block-confirmations-help": "Fedimint Guardians 在区块链的顶端滞后几个确认,以避免区块重组。", - "block-confirmations-warning": "在少于5个额外区块确认的情况下运行Fedimint是极其危险的!Fedimint无法处理区块链重组。", - "bitcoin-network": "比特币网络", - "select-network": "选择一个网络", - "set-rpc-help": "本地配置的比特币RPC地址", - "bitcoin-rpc": "比特币 RPC", - "error-valid-number": "请输入一个有效的数字。", - "error-valid-min": "请输入至少{{min}}的数字。", - "error-valid-max": "请输入一个最多为{{max}}的数字。", - "error-valid-min-max": "请输入一个介于{{min}}和{{max}}之间的数字。", - "meta-fields": "元字段", - "meta-fields-description": "请参阅文档以获取更多信息。", - "meta-fields-key": "元键", - "meta-fields-value": "价值", - "meta-fields-effect": "效果", - "meta-fields-add-another": "再添加一个", - "meta-fields-title": "您的元提案:", - "password-warning": "您必须备份您的密码并将其安全保存。此密码是访问您的守护者仪表板的必要条件。如果您丢失了它,您将无法恢复它!", - "password-warning-title": "备份您的密码!", - "acknowledge-backed-up": "我,{{guardianName}}(你的监护人姓名),承诺我已经备份并保护了我的密码:", - "confirm-and-backup-password": "确认并备份密码", - "error-guardian-name-mismatch": "监护人姓名不匹配", - "network": "网络" - }, - "setup": { - "common": { - "restart-setup": "重新启动设置", - "restart-setup-alert": "设置领导已重新启动设置仪式。请点击下面的“重新启动”以继续。", - "confirm-restart-setup": "您确定要重新启动设置仪式吗?", - "confirm-restart-setup-alert": "点击“重启”将为所有守护者重新开始仪式。" - }, - "progress": { - "tos": { - "title": "服务条款" - }, - "start": { - "title": "欢迎,守护者!", - "subtitle": "让我们设置您的联邦。", - "step": "联邦详情" - }, - "set-config": { - "title": "我们需要为您的联邦设置一些配置。", - "title-solo": "我们需要为您的单人联邦设置一些配置。", - "subtitle-leader": "您的联邦追随者将在他们那边确认此信息。", - "subtitle-solo": "运行单独的联邦会失去许多 Fedimint 的好处。您将无法对守护者离线进行容错共识,也无法进行联合备份。请谨慎行事,不建议用于生产环境或与主网比特币一起使用。", - "subtitle-follower": "您的联邦领袖将设置主要的联邦细节。您很快会确认它们。", - "step": "联邦详情" - }, - "connect-guardians": { - "title-leader": "邀请你的守护者", - "title-follower": "确认您的联邦信息", - "subtitle-leader": "与其他守护者分享链接,以便大家达成共识。一旦所有守护者加入,您将自动进入下一步。", - "subtitle-follower": "确保这里的信息正确无误,并且联邦守护者信息无误。当你确认一切看起来都不错时,请点击批准按钮。", - "step-leader": "邀请守护者", - "step-follower": "确认信息" - }, - "run-dkg": { - "title": "成功!", - "subtitle": "所有守护者都已验证联邦设置详情。正在计算一些数据……" - }, - "verify-guardians": { - "title": "验证您的守护者", - "subtitle": "请向每位守护者索取他们的验证代码,并将其粘贴在下面以检查有效性。我们快完成了!", - "step": "验证监护人", - "leader-confirm-done": "确认所有跟随的守护者已点击“下一步”,并查看他们的守护者仪表板,然后再继续。", - "leader-confirm-done-emphasis": "点击“继续”将完成设置仪式。" - }, - "setup-complete": { - "step": "完成!" - }, - "error": { - "title": "未知步骤", - "subtitle": "你是怎么到这里的?!" - } - }, - "warning": { - "title": "设置过程中请勿退出或刷新!", - "description": "在设置过程中退出可能会导致设置失败,您将不得不重新启动。" - } - }, - "setup-complete": { - "header": "🎉 🎉 🎉", - "congratulations": "恭喜", - "leader-message": "所有守护者的验证代码已被验证。", - "follower-message": "你已全部完成!让其他守护者知道你正在运行!", - "continue": "继续" - }, - "terms-of-service": { - "agree-and-continue": "同意并继续" - }, - "verify-guardians": { - "verified": "已验证", - "verified-placeholder": "粘贴代码在这里", - "error": "出了点问题。", - "error-peer-id": "无法确定您是哪个对等方。请刷新并重试。", - "verification-code": "您的验证码", - "verification-code-help": "与其他守护者分享此代码", - "table-title": "守护者验证代码", - "table-description": "在下面输入每个守护者的验证代码。", - "table-column-name": "名字", - "table-column-status": "状态", - "table-column-hash-input": "粘贴验证码", - "wait-all-guardians-verification": "等待所有守护者验证他们的代码", - "all-guardians-verified": "所有守护者都已验证他们的代码", - "starting-consensus": "开始共识..." - }, - "footer": { - "docs-section-header": "文档", - "community-section-header": "社区", - "contribute-section-header": "贡献", - "getting-started-link-text": "开始使用", - "faq-link-text": "常见问题", - "blog-link-text": "博客", - "discord-link-text": "Discord", - "twitter-link-text": "推特", - "github-link-text": "GitHub" - } -} diff --git a/apps/guardian-ui/src/setup/SetupContext.tsx b/apps/guardian-ui/src/setup/SetupContext.tsx deleted file mode 100644 index 035d602fc..000000000 --- a/apps/guardian-ui/src/setup/SetupContext.tsx +++ /dev/null @@ -1,334 +0,0 @@ -import React, { - createContext, - Dispatch, - ReactNode, - useCallback, - useEffect, - useReducer, - useState, -} from 'react'; -import { ConfigGenParams, ServerStatus } from '@fedimint/types'; -import { - SetupState, - SetupAction, - SETUP_ACTION_TYPE, - SetupProgress, -} from '../types'; -import { GuardianApi } from '../GuardianApi'; -import { isConsensusparams } from '../utils/validators'; -import { randomNames } from './randomNames'; - -const LOCAL_STORAGE_SETUP_KEY = 'setup-guardian-ui-state'; - -/** - * Creates the initial state using loaded state from local storage. - */ -function makeInitialState(loadFromStorage = true): SetupState { - const randomName = - randomNames[Math.floor(Math.random() * randomNames.length)] + - Math.floor(Math.random() * 10000) - .toString() - .padStart(4, '0'); - let state: SetupState = { - role: null, - progress: SetupProgress.Start, - myName: randomName, - configGenParams: null, - password: null, - numPeers: 0, - peers: [], - tosConfig: { showTos: false, tos: undefined }, - ourCurrentId: null, - }; - if (loadFromStorage) { - try { - const storageJson = localStorage.getItem(LOCAL_STORAGE_SETUP_KEY); - if (storageJson) { - state = JSON.parse(storageJson) as SetupState; - } - } catch (err) { - console.warn('Encountered error while fetching storage state', err); - } - } - - if ( - state.progress !== SetupProgress.Start && - state.configGenParams !== null && - isConsensusparams(state.configGenParams) - ) { - const peers = Object.values(state.configGenParams.peers); - state.peers = peers; - state.numPeers = state.numPeers ? state.numPeers : peers.length; - } - - return state; -} - -const initialState = makeInitialState(); - -const reducer = (state: SetupState, action: SetupAction): SetupState => { - switch (action.type) { - case SETUP_ACTION_TYPE.SET_INITIAL_STATE: - return makeInitialState(false); - case SETUP_ACTION_TYPE.SET_ROLE: - return { ...state, role: action.payload }; - case SETUP_ACTION_TYPE.SET_PROGRESS: - return { ...state, progress: action.payload }; - case SETUP_ACTION_TYPE.SET_MY_NAME: - return { ...state, myName: action.payload }; - case SETUP_ACTION_TYPE.SET_CONFIG_GEN_PARAMS: - return { ...state, configGenParams: action.payload }; - case SETUP_ACTION_TYPE.SET_PASSWORD: - return { ...state, password: action.payload }; - case SETUP_ACTION_TYPE.SET_NUM_PEERS: - return { ...state, numPeers: action.payload }; - case SETUP_ACTION_TYPE.SET_PEERS: - return { ...state, peers: action.payload }; - case SETUP_ACTION_TYPE.SET_OUR_CURRENT_ID: - return { ...state, ourCurrentId: action.payload }; - case SETUP_ACTION_TYPE.SET_TOS_CONFIG: - return { ...state, tosConfig: action.payload }; - default: - return state; - } -}; - -export interface SetupContextValue { - api: GuardianApi; - state: SetupState; - dispatch: Dispatch; - submitConfiguration(config: { - myName: string; - password: string; - configs: T; - }): Promise; - connectToHost(url: string): Promise; - fetchConsensusState(): Promise; - toggleConsensusPolling(toggle: boolean): void; -} - -type HostConfigs = ConfigGenParams & { - numPeers: number; -}; - -type FollowerConfigs = ConfigGenParams & { - hostServerUrl: string; -}; - -const isHostConfigs = ( - configs: HostConfigs | FollowerConfigs -): configs is HostConfigs => { - return (configs as HostConfigs).numPeers !== undefined; -}; - -const isFollowerConfigs = ( - configs: HostConfigs | FollowerConfigs -): configs is FollowerConfigs => { - return (configs as FollowerConfigs).hostServerUrl !== undefined; -}; - -export const SetupContext = createContext({ - api: new GuardianApi(), - state: initialState, - dispatch: () => null, - submitConfiguration: () => Promise.reject(), - connectToHost: () => Promise.reject(), - fetchConsensusState: () => Promise.reject(), - toggleConsensusPolling: () => null, -}); - -export interface SetupContextProviderProps { - api: GuardianApi; - initServerStatus: ServerStatus; - children: ReactNode; -} - -export const SetupContextProvider: React.FC = ({ - api, - initServerStatus, - children, -}: SetupContextProviderProps) => { - const [state, dispatch] = useReducer(reducer, { - ...initialState, - password: api.getPassword() || initialState.password, - }); - const { password, myName } = state; - const [isPollingConsensus, setIsPollingConsensus] = useState(false); - - useEffect(() => { - switch (initServerStatus) { - case ServerStatus.AwaitingPassword: - // If we're still waiting for a password, restart the whole thing. - dispatch({ - type: SETUP_ACTION_TYPE.SET_INITIAL_STATE, - payload: null, - }); - break; - case ServerStatus.ReadyForConfigGen: - // If we're ready for DKG, move them to approve the config to start. - dispatch({ - type: SETUP_ACTION_TYPE.SET_PROGRESS, - payload: SetupProgress.ConnectGuardians, - }); - break; - case ServerStatus.VerifyingConfigs: - case ServerStatus.VerifiedConfigs: - // If we're supposed to be verifying, or have verified, jump to peer validation screen - dispatch({ - type: SETUP_ACTION_TYPE.SET_PROGRESS, - payload: SetupProgress.VerifyGuardians, - }); - break; - case ServerStatus.ConsensusRunning: - default: - // We should never boot into these states with the setup UI. We probably should show error - // For now, skip past all setup, and transition to admin. - dispatch({ - type: SETUP_ACTION_TYPE.SET_IS_SETUP_COMPLETE, - payload: true, - }); - break; - } - }, [initServerStatus]); - - // Update local storage on state changes. - useEffect(() => { - localStorage.setItem( - LOCAL_STORAGE_SETUP_KEY, - JSON.stringify({ - role: state.role, - progress: state.progress, - myName: state.myName, - numPeers: state.numPeers, - configGenParams: state.configGenParams, - ourCurrentId: state.ourCurrentId, - }) - ); - - return () => { - // Clear local storage on setup complete. - // This happens when we transition to admin experience. - if (state.progress === SetupProgress.SetupComplete) { - localStorage.removeItem(LOCAL_STORAGE_SETUP_KEY); - } - }; - }, [ - state.role, - state.progress, - state.myName, - state.numPeers, - state.configGenParams, - state.ourCurrentId, - ]); - - // Fetch consensus state, dispatch updates with it. - const fetchConsensusState = useCallback(async () => { - const consensusState = await api.getConsensusConfigGenParams(); - dispatch({ - type: SETUP_ACTION_TYPE.SET_OUR_CURRENT_ID, - payload: consensusState.our_current_id, - }); - dispatch({ - type: SETUP_ACTION_TYPE.SET_PEERS, - payload: Object.values(consensusState.consensus.peers), - }); - dispatch({ - type: SETUP_ACTION_TYPE.SET_CONFIG_GEN_PARAMS, - payload: consensusState.consensus, - }); - }, [api]); - - // Poll for peer state every 2 seconds when isPollingPeers. - useEffect(() => { - if (!isPollingConsensus) return; - let timeout: ReturnType; - const pollPeers = () => { - fetchConsensusState() - .catch((err) => { - console.warn('Failed to poll for peers', err); - }) - .finally(() => { - timeout = setTimeout(pollPeers, 2000); - }); - }; - pollPeers(); - return () => clearTimeout(timeout); - }, [isPollingConsensus, fetchConsensusState]); - - // Single call to save all of the host / follower configurations - const submitConfiguration: SetupContextValue['submitConfiguration'] = - useCallback( - async ({ password: newPassword, myName, configs }) => { - if (!password) { - await api.setPassword(newPassword); - - dispatch({ - type: SETUP_ACTION_TYPE.SET_PASSWORD, - payload: newPassword, - }); - } - - dispatch({ - type: SETUP_ACTION_TYPE.SET_MY_NAME, - payload: myName, - }); - - if (isHostConfigs(configs)) { - dispatch({ - type: SETUP_ACTION_TYPE.SET_NUM_PEERS, - payload: configs.numPeers, - }); - - // Hosts set their own connection name only. - await api.setConfigGenConnections(myName); - - // Hosts submit both their local and the consensus config gen params. - await api.setConfigGenParams(configs); - dispatch({ - type: SETUP_ACTION_TYPE.SET_CONFIG_GEN_PARAMS, - payload: configs, - }); - } - - if (isFollowerConfigs(configs)) { - // Followers set their own connection name, and hosts server URL to connect to. - await api.setConfigGenConnections(myName, configs.hostServerUrl); - - // Followers submit ONLY their local config gen params. - await api.setConfigGenParams(configs); - - // Followers fetch consensus config gen params from the host. - await fetchConsensusState(); - } - }, - [password, api, dispatch, fetchConsensusState] - ); - - const connectToHost = useCallback( - async (url: string) => { - await api.setConfigGenConnections(myName, url); - return await fetchConsensusState(); - }, - [myName, api, fetchConsensusState] - ); - - const toggleConsensusPolling = useCallback((poll: boolean) => { - setIsPollingConsensus(poll); - }, []); - - return ( - - {children} - - ); -}; diff --git a/apps/guardian-ui/tsconfig.json b/apps/guardian-ui/tsconfig.json deleted file mode 100644 index 4bf6bc5df..000000000 --- a/apps/guardian-ui/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "@fedimint/tsconfig/react-app.json", - "compilerOptions": { - "typeRoots": [ - "src/typings/", - "node_modules/@types/", - "../node_modules/@types/" - ] - }, - "exclude": ["dist", "node_modules"], - "include": ["src"] -} diff --git a/apps/gateway-ui/.eslintrc.js b/apps/router/.eslintrc.js similarity index 100% rename from apps/gateway-ui/.eslintrc.js rename to apps/router/.eslintrc.js diff --git a/apps/gateway-ui/package.json b/apps/router/package.json similarity index 73% rename from apps/gateway-ui/package.json rename to apps/router/package.json index a09206f52..58ded72f0 100644 --- a/apps/gateway-ui/package.json +++ b/apps/router/package.json @@ -1,5 +1,5 @@ { - "name": "@fedimint/gateway-ui", + "name": "@fedimint/router", "version": "0.1.0", "private": true, "scripts": { @@ -8,26 +8,25 @@ "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", - "lint": "eslint \"src/**/*.ts*\"", + "lint": "eslint \"src/**/*.ts*\" --max-warnings 0", "clean": "rm -rf build" }, "dependencies": { - "@chakra-ui/react": "^2.4.5", - "@emotion/react": "^11", - "@emotion/styled": "^11", + "@codemirror/lang-json": "^6.0.1", "@fedimint/types": "*", "@fedimint/ui": "*", "@fedimint/utils": "*", - "framer-motion": "^6", - "jsonrpc-client-websocket": "^1.5.2", - "node": "^20.1.0", - "qrcode.react": "^3.1.0", + "@uiw/codemirror-theme-github": "^4.23.2", + "@uiw/react-codemirror": "^4.23.2", + "framer-motion": "^11.5.4", + "jsonrpc-client-websocket": "^1.5.5", + "qrcode.react": "^4.0.1", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-icons": "^4.7.1", + "react-icons": "^5.3.0", "react-minimal-pie-chart": "^8.4.0", - "react-scripts": "5.0.1", - "react-use-websocket": "3.0.0" + "react-router-dom": "^6.26.2", + "react-scripts": "5.0.1" }, "devDependencies": { "@fedimint/eslint-config": "*", @@ -35,9 +34,9 @@ "@testing-library/jest-dom": "^5.16.1", "@testing-library/react": "^13.0.0", "@testing-library/user-event": "^13.5.0", + "@types/diff": "^5.0.9", "@types/jest": "^27.0.3", "@types/node": "^16.11.14", - "@types/qrcode.react": "^1.0.2", "@types/react": "^18.2.0", "@types/react-dom": "^18.2.0", "@typescript-eslint/eslint-plugin": "^5.48.1", diff --git a/apps/router/public/config.json b/apps/router/public/config.json new file mode 100644 index 000000000..e69de29bb diff --git a/apps/gateway-ui/public/favicon.ico b/apps/router/public/favicon.ico similarity index 100% rename from apps/gateway-ui/public/favicon.ico rename to apps/router/public/favicon.ico diff --git a/apps/guardian-ui/public/index.html b/apps/router/public/index.html similarity index 98% rename from apps/guardian-ui/public/index.html rename to apps/router/public/index.html index 97be97717..01e5134ff 100644 --- a/apps/guardian-ui/public/index.html +++ b/apps/router/public/index.html @@ -21,7 +21,7 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - Guardian UI + Fedimint UI diff --git a/apps/guardian-ui/public/manifest.json b/apps/router/public/manifest.json similarity index 100% rename from apps/guardian-ui/public/manifest.json rename to apps/router/public/manifest.json diff --git a/apps/gateway-ui/public/robots.txt b/apps/router/public/robots.txt similarity index 100% rename from apps/gateway-ui/public/robots.txt rename to apps/router/public/robots.txt diff --git a/apps/router/src/context/AppContext.tsx b/apps/router/src/context/AppContext.tsx new file mode 100644 index 000000000..367e2a368 --- /dev/null +++ b/apps/router/src/context/AppContext.tsx @@ -0,0 +1,210 @@ +import React, { + createContext, + Dispatch, + ReactNode, + useEffect, + useReducer, +} from 'react'; +import { GuardianConfig } from '../guardian-ui/GuardianApi'; + +import { GatewayConfig } from '../gateway-ui/types'; +import { sha256Hash } from '@fedimint/utils'; + +type Service = GuardianConfig | GatewayConfig; + +export interface Guardian { + config: GuardianConfig; +} + +export interface Gateway { + config: GatewayConfig; +} + +export interface AppContextValue { + guardians: Record; + gateways: Record; + dispatch: Dispatch; +} + +const makeInitialState = (): AppContextValue => { + const storedState = localStorage.getItem('fedimint_ui_state'); + if (storedState) { + try { + const parsedState = JSON.parse(storedState); + return { + ...parsedState, + dispatch: () => null, + }; + } catch (error) { + console.error('Failed to parse stored state:', error); + } + } + return { + guardians: {}, + gateways: {}, + dispatch: () => null, + }; +}; + +export enum APP_ACTION_TYPE { + SET_SELECTED_SERVICE = 'SET_SELECTED_SERVICE', + ADD_GUARDIAN = 'ADD_GUARDIAN', + ADD_GATEWAY = 'ADD_GATEWAY', + REMOVE_GUARDIAN = 'REMOVE_GUARDIAN', + REMOVE_GATEWAY = 'REMOVE_GATEWAY', +} + +export type AppAction = + | { + type: APP_ACTION_TYPE.ADD_GUARDIAN; + payload: { + id: string; + guardian: Guardian; + }; + } + | { + type: APP_ACTION_TYPE.ADD_GATEWAY; + payload: { + id: string; + gateway: Gateway; + }; + } + | { + type: APP_ACTION_TYPE.REMOVE_GUARDIAN; + payload: string; + } + | { + type: APP_ACTION_TYPE.REMOVE_GATEWAY; + payload: string; + }; + +const saveToLocalStorage = (state: AppContextValue) => { + localStorage.setItem('fedimint_ui_state', JSON.stringify(state)); +}; + +const reducer = ( + state: AppContextValue, + action: AppAction +): AppContextValue => { + switch (action.type) { + case APP_ACTION_TYPE.ADD_GUARDIAN: + return { + ...state, + guardians: { + ...state.guardians, + [action.payload.id]: action.payload.guardian, + }, + }; + case APP_ACTION_TYPE.ADD_GATEWAY: + return { + ...state, + gateways: { + ...state.gateways, + [action.payload.id]: action.payload.gateway, + }, + }; + case APP_ACTION_TYPE.REMOVE_GUARDIAN: + return { + ...state, + guardians: Object.fromEntries( + Object.entries(state.guardians).filter( + ([key]) => key !== action.payload + ) + ), + }; + case APP_ACTION_TYPE.REMOVE_GATEWAY: + return { + ...state, + gateways: Object.fromEntries( + Object.entries(state.gateways).filter( + ([key]) => key !== action.payload + ) + ), + }; + } +}; + +const reducerWithMiddleware = ( + state: AppContextValue, + action: AppAction +): AppContextValue => { + const newState = reducer(state, action); + saveToLocalStorage(newState); + return newState; +}; + +export const AppContext = createContext(makeInitialState()); + +export interface AppContextProviderProps { + children: ReactNode; +} + +export const AppContextProvider: React.FC = ({ + children, +}: AppContextProviderProps) => { + const [state, dispatch] = useReducer( + reducerWithMiddleware, + makeInitialState() + ); + + useEffect(() => { + const isGuardian = (service: Service): service is GuardianConfig => + service.baseUrl.startsWith('ws'); + const isGateway = (service: Service): service is GatewayConfig => + service.baseUrl.startsWith('http'); + const addService = async (service: Service) => { + const id = await sha256Hash(service.baseUrl); + + if (isGuardian(service)) { + dispatch({ + type: APP_ACTION_TYPE.ADD_GUARDIAN, + payload: { id, guardian: { config: service as GuardianConfig } }, + }); + } else if (isGateway(service)) { + dispatch({ + type: APP_ACTION_TYPE.ADD_GATEWAY, + payload: { id, gateway: { config: service as GatewayConfig } }, + }); + } else { + throw new Error(`Invalid service baseUrl in config.json: ${service}`); + } + }; + + const handleConfig = (data: Service | Service[]) => { + const services = Array.isArray(data) ? data : [data]; + services.forEach((service) => { + addService(service); + }); + }; + + fetch('/config.json') + .then((response) => { + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + return response.text(); + }) + .then((text) => { + if (!text.trim()) { + console.warn('Config file is empty'); + return; + } + try { + const data = JSON.parse(text); + handleConfig(data); + } catch (error) { + console.error('Error parsing config JSON:', error); + console.log('Raw config content:', text); + } + }) + .catch((error) => { + console.error('Error fetching or processing config:', error); + }); + }, []); + + return ( + + {children} + + ); +}; diff --git a/apps/router/src/context/gateway/GatewayContext.tsx b/apps/router/src/context/gateway/GatewayContext.tsx new file mode 100644 index 000000000..11d00e08a --- /dev/null +++ b/apps/router/src/context/gateway/GatewayContext.tsx @@ -0,0 +1,83 @@ +import React, { + createContext, + Dispatch, + ReactNode, + useMemo, + useReducer, +} from 'react'; +import { useGatewayConfig } from '../hooks'; +import { GatewayApi } from '../../gateway-ui/GatewayApi'; +import { + GATEWAY_APP_ACTION_TYPE, + GatewayAppAction, + GatewayAppState, + GatewayStatus, +} from '../../gateway-ui/types'; +import { useLocation } from 'react-router-dom'; + +export interface GatewayContextValue { + id: string; + api: GatewayApi; + state: GatewayAppState; + dispatch: Dispatch; +} + +const initialState: GatewayAppState = { + status: GatewayStatus.Loading, + needsAuth: true, + gatewayError: undefined, + balances: null, + gatewayInfo: null, + unit: 'msats', +}; + +const reducer = ( + state: GatewayAppState, + action: GatewayAppAction +): GatewayAppState => { + switch (action.type) { + case GATEWAY_APP_ACTION_TYPE.SET_STATUS: + return { ...state, status: action.payload }; + case GATEWAY_APP_ACTION_TYPE.SET_NEEDS_AUTH: + return { ...state, needsAuth: action.payload }; + case GATEWAY_APP_ACTION_TYPE.SET_ERROR: + return { ...state, gatewayError: action.payload }; + case GATEWAY_APP_ACTION_TYPE.SET_BALANCES: + return { ...state, balances: action.payload }; + case GATEWAY_APP_ACTION_TYPE.SET_GATEWAY_INFO: + return { ...state, gatewayInfo: action.payload }; + case GATEWAY_APP_ACTION_TYPE.SET_UNIT: + return { ...state, unit: action.payload }; + default: + return state; + } +}; + +export const GatewayContext = createContext(null); + +export interface GatewayContextProviderProps { + children: ReactNode; +} + +export const GatewayContextProvider: React.FC = ({ + children, +}) => { + const [state, dispatch] = useReducer(reducer, initialState); + const location = useLocation(); + const gatewayId = location.pathname.split('/')[2]; + const config = useGatewayConfig(gatewayId); + const gatewayApi = useMemo(() => new GatewayApi(config), [config]); + + return ( + + {children} + + ); +}; diff --git a/apps/router/src/context/guardian/AdminContext.tsx b/apps/router/src/context/guardian/AdminContext.tsx new file mode 100644 index 000000000..50c49d5e1 --- /dev/null +++ b/apps/router/src/context/guardian/AdminContext.tsx @@ -0,0 +1,23 @@ +import React, { createContext, ReactNode } from 'react'; +// import { AdminApiInterface } from '../guardian-ui/GuardianApi'; +import { useGuardianStatus } from '../hooks'; +import { GuardianStatus } from '../../guardian-ui/types'; + +// export interface AdminContextValue {} + +export const AdminContext = createContext(null); + +export interface AdminContextProviderProps { + children: ReactNode; +} + +export const AdminContextProvider: React.FC = ({ + children, +}: AdminContextProviderProps) => { + const status = useGuardianStatus(); + if (status !== GuardianStatus.Admin) { + return null; + } + + return {children}; +}; diff --git a/apps/router/src/context/guardian/GuardianContext.tsx b/apps/router/src/context/guardian/GuardianContext.tsx new file mode 100644 index 000000000..d21ab73b5 --- /dev/null +++ b/apps/router/src/context/guardian/GuardianContext.tsx @@ -0,0 +1,78 @@ +import React, { + createContext, + Dispatch, + ReactNode, + useMemo, + useReducer, +} from 'react'; +import { GuardianApi } from '../../guardian-ui/GuardianApi'; +import { + GUARDIAN_APP_ACTION_TYPE, + GuardianAppAction, + GuardianAppState, + GuardianStatus, +} from '../../guardian-ui/types'; +import { useGuardianConfig } from '../hooks'; +import { useLocation } from 'react-router-dom'; + +export interface GuardianContextValue { + id: string; + api: GuardianApi; + state: GuardianAppState; + dispatch: Dispatch; +} + +const initialState = { + status: GuardianStatus.Loading, + needsAuth: false, + initServerStatus: undefined, + guardianError: undefined, +}; + +const reducer = ( + state: GuardianAppState, + action: GuardianAppAction +): GuardianAppState => { + switch (action.type) { + case GUARDIAN_APP_ACTION_TYPE.SET_STATUS: + return { ...state, status: action.payload }; + case GUARDIAN_APP_ACTION_TYPE.SET_NEEDS_AUTH: + return { ...state, needsAuth: action.payload }; + case GUARDIAN_APP_ACTION_TYPE.SET_INIT_SERVER_STATUS: + return { ...state, initServerStatus: action.payload }; + case GUARDIAN_APP_ACTION_TYPE.SET_ERROR: + return { ...state, guardianError: action.payload }; + default: + return state; + } +}; + +export const GuardianContext = createContext(null); + +export interface GuardianContextProviderProps { + children: ReactNode; +} + +export const GuardianContextProvider: React.FC< + GuardianContextProviderProps +> = ({ children }) => { + const [state, dispatch] = useReducer(reducer, initialState); + const location = useLocation(); + console.log('location', location); + const guardianId = location.pathname.split('/')[2]; + const config = useGuardianConfig(guardianId); + const guardianApi = useMemo(() => new GuardianApi(config), [config]); + + return ( + + {children} + + ); +}; diff --git a/apps/router/src/context/guardian/SetupContext.tsx b/apps/router/src/context/guardian/SetupContext.tsx new file mode 100644 index 000000000..f74f7408e --- /dev/null +++ b/apps/router/src/context/guardian/SetupContext.tsx @@ -0,0 +1,158 @@ +import React, { createContext, Dispatch, ReactNode, useReducer } from 'react'; +import { GuardianServerStatus } from '@fedimint/types'; +import { + SetupState, + SetupAction, + SETUP_ACTION_TYPE, + SetupProgress, +} from '../../guardian-ui/types'; +import { isConsensusparams } from '../../guardian-ui/utils/validators'; +import { randomNames } from '../../guardian-ui/setup/randomNames'; +import { + FollowerConfigs, + HostConfigs, + useGuardianApi, + useHandleBackgroundGuardianSetupActions, + useHandleSetupServerStatus, + useUpdateLocalStorageOnSetupStateChange, +} from '../hooks'; + +export const LOCAL_STORAGE_SETUP_KEY = 'setup-guardian-ui-state'; + +/** + * Creates the initial state using loaded state from local storage. + */ +function makeInitialState(loadFromStorage = true): SetupState { + const randomName = + randomNames[Math.floor(Math.random() * randomNames.length)] + + Math.floor(Math.random() * 10000) + .toString() + .padStart(4, '0'); + let state: SetupState = { + role: null, + progress: SetupProgress.Start, + myName: randomName, + configGenParams: null, + password: null, + numPeers: 0, + peers: [], + tosConfig: { showTos: false, tos: undefined }, + ourCurrentId: null, + }; + if (loadFromStorage) { + try { + const storageJson = localStorage.getItem(LOCAL_STORAGE_SETUP_KEY); + if (storageJson) { + state = JSON.parse(storageJson) as SetupState; + } + } catch (err) { + console.warn('Encountered error while fetching storage state', err); + } + } + + if ( + state.progress !== SetupProgress.Start && + state.configGenParams !== null && + isConsensusparams(state.configGenParams) + ) { + const peers = Object.values(state.configGenParams.peers); + state.peers = peers; + state.numPeers = state.numPeers ? state.numPeers : peers.length; + } + + return state; +} + +const initialState = makeInitialState(); + +const reducer = (state: SetupState, action: SetupAction): SetupState => { + switch (action.type) { + case SETUP_ACTION_TYPE.SET_INITIAL_STATE: + return makeInitialState(false); + case SETUP_ACTION_TYPE.SET_ROLE: + return { ...state, role: action.payload }; + case SETUP_ACTION_TYPE.SET_PROGRESS: + return { ...state, progress: action.payload }; + case SETUP_ACTION_TYPE.SET_MY_NAME: + return { ...state, myName: action.payload }; + case SETUP_ACTION_TYPE.SET_CONFIG_GEN_PARAMS: + return { ...state, configGenParams: action.payload }; + case SETUP_ACTION_TYPE.SET_PASSWORD: + return { ...state, password: action.payload }; + case SETUP_ACTION_TYPE.SET_NUM_PEERS: + return { ...state, numPeers: action.payload }; + case SETUP_ACTION_TYPE.SET_PEERS: + return { ...state, peers: action.payload }; + case SETUP_ACTION_TYPE.SET_OUR_CURRENT_ID: + return { ...state, ourCurrentId: action.payload }; + case SETUP_ACTION_TYPE.SET_TOS_CONFIG: + return { ...state, tosConfig: action.payload }; + default: + return state; + } +}; + +export interface SetupContextValue { + state: SetupState; + dispatch: Dispatch; + submitConfiguration(config: { + myName: string; + password: string; + configs: T; + }): Promise; + connectToHost(url: string): Promise; + fetchConsensusState(): Promise; + toggleConsensusPolling(toggle: boolean): void; +} + +export const SetupContext = createContext({ + state: initialState, + dispatch: () => null, + submitConfiguration: () => Promise.reject(), + connectToHost: () => Promise.reject(), + fetchConsensusState: () => Promise.reject(), + toggleConsensusPolling: () => null, +}); + +export interface SetupContextProviderProps { + initServerStatus: GuardianServerStatus; + children: ReactNode; +} + +export const SetupContextProvider: React.FC = ({ + initServerStatus, + children, +}: SetupContextProviderProps) => { + const api = useGuardianApi(); + const [state, dispatch] = useReducer(reducer, { + ...initialState, + password: api.getPassword() || initialState.password, + }); + + useHandleSetupServerStatus(initServerStatus, dispatch); + + // Update local storage on state changes. + useUpdateLocalStorageOnSetupStateChange(state); + + const { + submitConfiguration, + connectToHost, + fetchConsensusState, + toggleConsensusPolling, + } = useHandleBackgroundGuardianSetupActions(state, dispatch); + + return ( + + {children} + + ); +}; diff --git a/apps/router/src/context/hooks.tsx b/apps/router/src/context/hooks.tsx new file mode 100644 index 000000000..5c77eab05 --- /dev/null +++ b/apps/router/src/context/hooks.tsx @@ -0,0 +1,507 @@ +import { Dispatch, useCallback, useContext, useEffect, useState } from 'react'; +import { AppContext, AppContextValue } from './AppContext'; +import { + GuardianContext, + GuardianContextValue, +} from './guardian/GuardianContext'; +import { + GUARDIAN_APP_ACTION_TYPE, + GuardianAppAction, + GuardianAppState, + GuardianStatus, + SETUP_ACTION_TYPE, + SetupAction, + SetupProgress, + SetupState, +} from '../guardian-ui/types'; +import { + AdminApiInterface, + GuardianApi, + GuardianConfig, + SetupApiInterface, +} from '../guardian-ui/GuardianApi'; +import { + ConfigGenParams, + GatewayInfo, + GuardianServerStatus, +} from '@fedimint/types'; +import { formatApiErrorMessage } from '../guardian-ui/utils/api'; +import { + LOCAL_STORAGE_SETUP_KEY, + SetupContext, + SetupContextValue, +} from './guardian/SetupContext'; +import { + GATEWAY_APP_ACTION_TYPE, + GatewayAppAction, + GatewayAppState, + GatewayConfig, +} from '../gateway-ui/types'; +import { GatewayContext, GatewayContextValue } from './gateway/GatewayContext'; +import { GatewayApi } from '../gateway-ui/GatewayApi'; + +export function useAppContext(): AppContextValue { + return useContext(AppContext); +} + +export function useAppGuardianConfigs(): GuardianConfig[] { + const { guardians } = useAppContext(); + return Object.values(guardians).map((guardian) => guardian.config); +} + +export function useNumberOfGuardians(): number { + return Object.keys(useAppContext().guardians).length; +} + +export function useNumberOfGateways(): number { + return Object.keys(useAppContext().gateways).length; +} + +export const useGuardianConfig = (id: string): GuardianConfig => { + const { guardians } = useAppContext(); + if (!guardians[id]) + throw new Error('useGuardianConfig must be used with a selected guardian'); + return guardians[id].config; +}; + +export const useGatewayConfig = (id: string): GatewayConfig => { + const { gateways } = useAppContext(); + if (!gateways[id]) + throw new Error('useGatewayConfig must be used with a selected gateway'); + return gateways[id].config; +}; + +export const useGuardianDispatch = (): Dispatch => { + const guardian = useGuardianContext(); + if (!guardian) + throw new Error( + 'useGuardianDispatch must be used within a GuardianContextProvider' + ); + return guardian.dispatch; +}; + +export const useLoadGuardian = (): void => { + const guardianApi = useGuardianApi(); + const guardianState = useGuardianState(); + const dispatch = useGuardianDispatch(); + useEffect(() => { + const load = async () => { + try { + await guardianApi.connect(); + const server = (await guardianApi.status()).server; + + // If they're at a point where a password has been configured, make + // sure they have a valid password set. If not, set needsAuth. + if (server !== GuardianServerStatus.AwaitingPassword) { + const password = guardianApi.getPassword(); + const hasValidPassword = password + ? await guardianApi.testPassword(password) + : false; + if (!hasValidPassword) { + dispatch({ + type: GUARDIAN_APP_ACTION_TYPE.SET_NEEDS_AUTH, + payload: true, + }); + } + } + + if (server === GuardianServerStatus.ConsensusRunning) { + dispatch({ + type: GUARDIAN_APP_ACTION_TYPE.SET_STATUS, + payload: GuardianStatus.Admin, + }); + } else { + dispatch({ + type: GUARDIAN_APP_ACTION_TYPE.SET_STATUS, + payload: GuardianStatus.Setup, + }); + } + + dispatch({ + type: GUARDIAN_APP_ACTION_TYPE.SET_INIT_SERVER_STATUS, + payload: server, + }); + } catch (err) { + dispatch({ + type: GUARDIAN_APP_ACTION_TYPE.SET_ERROR, + payload: formatApiErrorMessage(err), + }); + } + }; + + if (guardianState.status === GuardianStatus.Loading) { + load().catch((err) => console.error(err)); + } + }, [guardianState.status, guardianApi, dispatch]); +}; + +export const useGuardianContext = (): GuardianContextValue => { + const guardian = useContext(GuardianContext); + if (!guardian) + throw new Error( + 'useGuardianContext must be used within a GuardianContextProvider' + ); + return guardian; +}; + +export const useGuardianApi = (): GuardianApi => { + const guardian = useGuardianContext(); + return guardian.api; +}; + +export const useGuardianState = (): GuardianAppState => { + const guardian = useGuardianContext(); + return guardian.state; +}; + +export const useGuardianStatus = (): GuardianStatus => { + const guardian = useGuardianContext(); + if (!guardian) return GuardianStatus.Loading; + return guardian.state.status; +}; + +export const useGuardianAdminApi = (): AdminApiInterface => { + const guardian = useGuardianContext(); + return guardian.api; +}; + +export const useGuardianSetupContext = (): SetupContextValue => { + const setup = useContext(SetupContext); + if (!setup) + throw new Error( + 'useGuardianSetupContext must be used within a SetupContextProvider' + ); + return setup; +}; + +export const useGuardianSetupApi = (): SetupApiInterface => { + const guardian = useGuardianContext(); + return guardian.api; +}; + +/** + * Tells the guardian context to poll for updates. Handles turning off polling + * on dismount. + */ +export function useConsensusPolling(shouldPoll = true) { + const { toggleConsensusPolling } = useGuardianSetupContext(); + + useEffect(() => { + if (!shouldPoll) return; + toggleConsensusPolling(true); + return () => toggleConsensusPolling(false); + }, [shouldPoll, toggleConsensusPolling]); +} + +export const useHandleSetupServerStatus = ( + initServerStatus: GuardianServerStatus, + dispatch: Dispatch +): void => { + useEffect(() => { + switch (initServerStatus) { + case GuardianServerStatus.AwaitingPassword: + // If we're still waiting for a password, restart the whole thing. + dispatch({ + type: SETUP_ACTION_TYPE.SET_INITIAL_STATE, + payload: null, + }); + break; + case GuardianServerStatus.ReadyForConfigGen: + // If we're ready for DKG, move them to approve the config to start. + dispatch({ + type: SETUP_ACTION_TYPE.SET_PROGRESS, + payload: SetupProgress.ConnectGuardians, + }); + break; + case GuardianServerStatus.VerifyingConfigs: + case GuardianServerStatus.VerifiedConfigs: + // If we're supposed to be verifying, or have verified, jump to peer validation screen + dispatch({ + type: SETUP_ACTION_TYPE.SET_PROGRESS, + payload: SetupProgress.VerifyGuardians, + }); + break; + case GuardianServerStatus.ConsensusRunning: + default: + // We should never boot into these states with the setup UI. We probably should show error + // For now, skip past all setup, and transition to admin. + dispatch({ + type: SETUP_ACTION_TYPE.SET_IS_SETUP_COMPLETE, + payload: true, + }); + break; + } + }, [initServerStatus, dispatch]); +}; + +export const useUpdateLocalStorageOnSetupStateChange = ( + state: SetupState +): void => { + useEffect(() => { + localStorage.setItem( + LOCAL_STORAGE_SETUP_KEY, + JSON.stringify({ + role: state.role, + progress: state.progress, + myName: state.myName, + numPeers: state.numPeers, + configGenParams: state.configGenParams, + ourCurrentId: state.ourCurrentId, + }) + ); + + return () => { + // Clear local storage on setup complete. + // This happens when we transition to admin experience. + if (state.progress === SetupProgress.SetupComplete) { + localStorage.removeItem(LOCAL_STORAGE_SETUP_KEY); + } + }; + }, [ + state.role, + state.progress, + state.myName, + state.numPeers, + state.configGenParams, + state.ourCurrentId, + ]); +}; + +export type HostConfigs = ConfigGenParams & { + numPeers: number; +}; + +export type FollowerConfigs = ConfigGenParams & { + hostServerUrl: string; +}; + +const isHostConfigs = ( + configs: HostConfigs | FollowerConfigs +): configs is HostConfigs => { + return (configs as HostConfigs).numPeers !== undefined; +}; + +const isFollowerConfigs = ( + configs: HostConfigs | FollowerConfigs +): configs is FollowerConfigs => { + return (configs as FollowerConfigs).hostServerUrl !== undefined; +}; + +export const useHandleBackgroundGuardianSetupActions = ( + state: SetupState, + dispatch: Dispatch +): { + submitConfiguration: SetupContextValue['submitConfiguration']; + connectToHost: SetupContextValue['connectToHost']; + fetchConsensusState: SetupContextValue['fetchConsensusState']; + toggleConsensusPolling: SetupContextValue['toggleConsensusPolling']; +} => { + const api = useGuardianApi(); + const { password, myName } = state; + const [isPollingConsensus, setIsPollingConsensus] = useState(false); + + // Fetch consensus state, dispatch updates with it. + const fetchConsensusState = useCallback(async () => { + const consensusState = await api.getConsensusConfigGenParams(); + dispatch({ + type: SETUP_ACTION_TYPE.SET_OUR_CURRENT_ID, + payload: consensusState.our_current_id, + }); + dispatch({ + type: SETUP_ACTION_TYPE.SET_PEERS, + payload: Object.values(consensusState.consensus.peers), + }); + dispatch({ + type: SETUP_ACTION_TYPE.SET_CONFIG_GEN_PARAMS, + payload: consensusState.consensus, + }); + }, [api, dispatch]); + + // Poll for peer state every 2 seconds when isPollingPeers. + useEffect(() => { + if (!isPollingConsensus) return; + let timeout: ReturnType; + const pollPeers = () => { + fetchConsensusState() + .catch((err) => { + console.warn('Failed to poll for peers', err); + }) + .finally(() => { + timeout = setTimeout(pollPeers, 2000); + }); + }; + pollPeers(); + return () => clearTimeout(timeout); + }, [isPollingConsensus, fetchConsensusState]); + + // Single call to save all of the host / follower configurations + const submitConfiguration: SetupContextValue['submitConfiguration'] = + useCallback( + async ({ password: newPassword, myName, configs }) => { + if (!password) { + await api.setPassword(newPassword); + + dispatch({ + type: SETUP_ACTION_TYPE.SET_PASSWORD, + payload: newPassword, + }); + } + + dispatch({ + type: SETUP_ACTION_TYPE.SET_MY_NAME, + payload: myName, + }); + + if (isHostConfigs(configs)) { + dispatch({ + type: SETUP_ACTION_TYPE.SET_NUM_PEERS, + payload: configs.numPeers, + }); + + // Hosts set their own connection name only. + await api.setConfigGenConnections(myName); + + // Hosts submit both their local and the consensus config gen params. + await api.setConfigGenParams(configs); + dispatch({ + type: SETUP_ACTION_TYPE.SET_CONFIG_GEN_PARAMS, + payload: configs, + }); + } + + if (isFollowerConfigs(configs)) { + // Followers set their own connection name, and hosts server URL to connect to. + await api.setConfigGenConnections(myName, configs.hostServerUrl); + + // Followers submit ONLY their local config gen params. + await api.setConfigGenParams(configs); + + // Followers fetch consensus config gen params from the host. + await fetchConsensusState(); + } + }, + [password, api, dispatch, fetchConsensusState] + ); + + const connectToHost = useCallback( + async (url: string) => { + await api.setConfigGenConnections(myName, url); + return await fetchConsensusState(); + }, + [myName, api, fetchConsensusState] + ); + + const toggleConsensusPolling = useCallback((poll: boolean) => { + setIsPollingConsensus(poll); + }, []); + + return { + submitConfiguration, + connectToHost, + fetchConsensusState, + toggleConsensusPolling, + }; +}; + +export const useGatewayContext = (): GatewayContextValue => { + const gateway = useContext(GatewayContext); + if (!gateway) + throw new Error( + 'useGatewayContext must be used within a GatewayContextProvider' + ); + return gateway; +}; + +export const useGatewayApi = (): GatewayApi => { + const gateway = useGatewayContext(); + return gateway.api; +}; + +export const useGatewayState = (): GatewayAppState => { + const gateway = useGatewayContext(); + return gateway.state; +}; + +export const useGatewayDispatch = (): Dispatch => { + const gateway = useGatewayContext(); + if (!gateway) + throw new Error( + 'useGatewayDispatch must be used within a GatewayContextProvider' + ); + return gateway.dispatch; +}; + +export const useGatewayInfo = (): GatewayInfo => { + const gateway = useGatewayContext(); + if (!gateway.state.gatewayInfo) + throw new Error( + 'useGatewayInfo must be used within a GatewayContextProvider' + ); + return gateway.state.gatewayInfo; +}; + +export const useLoadGateway = () => { + const state = useGatewayState(); + const dispatch = useGatewayDispatch(); + + const api = useGatewayApi(); + + useEffect(() => { + if (!state.needsAuth) { + const fetchInfoAndConfigs = async () => { + try { + const gatewayInfo = await api.fetchInfo(); + + const configs = await api.fetchConfigs(); + + const updatedFederations = gatewayInfo.federations.map( + (federation) => ({ + ...federation, + config: configs.federations[federation.federation_id], + }) + ); + + const updatedGatewayInfo = { + ...gatewayInfo, + federations: updatedFederations, + }; + + dispatch({ + type: GATEWAY_APP_ACTION_TYPE.SET_GATEWAY_INFO, + payload: updatedGatewayInfo, + }); + } catch (error: unknown) { + console.error(error); + dispatch({ + type: GATEWAY_APP_ACTION_TYPE.SET_ERROR, + payload: (error as Error).message, + }); + } + }; + + const fetchBalances = () => { + api + .fetchBalances() + .then((balances) => { + dispatch({ + type: GATEWAY_APP_ACTION_TYPE.SET_BALANCES, + payload: balances, + }); + }) + .catch(({ message, error }) => { + console.error(error); + dispatch({ + type: GATEWAY_APP_ACTION_TYPE.SET_ERROR, + payload: message, + }); + }); + }; + + fetchInfoAndConfigs(); + fetchBalances(); + + const interval = setInterval(fetchInfoAndConfigs, 5000); + return () => clearInterval(interval); + } + }, [state.needsAuth, api, dispatch]); +}; diff --git a/apps/router/src/gateway-ui/Gateway.tsx b/apps/router/src/gateway-ui/Gateway.tsx new file mode 100644 index 000000000..0139b432a --- /dev/null +++ b/apps/router/src/gateway-ui/Gateway.tsx @@ -0,0 +1,87 @@ +import React, { useState } from 'react'; +import { Flex } from '@chakra-ui/react'; +import { ConnectFederationModal, LightningCard } from './components'; +import { FederationsTable } from './components/federations/FederationsTable'; +import { Loading } from './components/Loading'; +import { HeaderWithUnitSelector } from './components/HeaderWithUnitSelector'; +import { WalletCard } from './components/walletCard/WalletCard'; +import { + WalletModal, + WalletModalAction, + WalletModalState, + WalletModalType, +} from './components/walletModal/WalletModal'; +import { useGatewayContext, useLoadGateway } from '../context/hooks'; +import { ErrorMessage } from './components/ErrorMessage'; +import { Login } from '@fedimint/ui'; +import { GATEWAY_APP_ACTION_TYPE } from './types'; + +export const UNIT_OPTIONS = ['msats', 'sats', 'btc'] as const; +export type Unit = (typeof UNIT_OPTIONS)[number]; + +export const Gateway = () => { + const { state, dispatch, api } = useGatewayContext(); + const [showConnectFed, setShowConnectFed] = useState(false); + const [walletModalState, setWalletModalState] = useState({ + isOpen: false, + action: WalletModalAction.Receive, + type: WalletModalType.Onchain, + selectedFederation: null, + }); + + useLoadGateway(); + if (state.needsAuth) { + return ( + + dispatch({ + type: GATEWAY_APP_ACTION_TYPE.SET_NEEDS_AUTH, + payload: false, + }) + } + parseError={(err) => (err as Error).message} + /> + ); + } + if (state.gatewayError) return ; + if (state.gatewayInfo === null) return ; + + return ( + + + {state.balances && ( + + )} + + setShowConnectFed(true)} + setWalletModalState={setWalletModalState} + /> + setShowConnectFed(false)} + /> + + + ); +}; diff --git a/apps/gateway-ui/src/GatewayApi.ts b/apps/router/src/gateway-ui/GatewayApi.ts similarity index 98% rename from apps/gateway-ui/src/GatewayApi.ts rename to apps/router/src/gateway-ui/GatewayApi.ts index a909d4bf7..b3feedf3c 100644 --- a/apps/gateway-ui/src/GatewayApi.ts +++ b/apps/router/src/gateway-ui/GatewayApi.ts @@ -14,12 +14,17 @@ import { ReceiveEcashResponse, GatewayBalances, } from '@fedimint/types'; +import { GatewayConfig } from './types'; export const SESSION_STORAGE_KEY = 'gateway-ui-key'; // GatewayApi is an implementation of the ApiInterface export class GatewayApi { - private baseUrl: string | undefined = process.env.REACT_APP_FM_GATEWAY_API; + private baseUrl: string; + + constructor(config: GatewayConfig) { + this.baseUrl = config.baseUrl; + } // Tests a provided password or the one in session storage testPassword = async (password?: string): Promise => { diff --git a/apps/gateway-ui/README.md b/apps/router/src/gateway-ui/README.md similarity index 100% rename from apps/gateway-ui/README.md rename to apps/router/src/gateway-ui/README.md diff --git a/apps/gateway-ui/src/assets/svgs/check-circle.svg b/apps/router/src/gateway-ui/assets/svgs/check-circle.svg similarity index 100% rename from apps/gateway-ui/src/assets/svgs/check-circle.svg rename to apps/router/src/gateway-ui/assets/svgs/check-circle.svg diff --git a/apps/gateway-ui/src/assets/svgs/copy.svg b/apps/router/src/gateway-ui/assets/svgs/copy.svg similarity index 100% rename from apps/gateway-ui/src/assets/svgs/copy.svg rename to apps/router/src/gateway-ui/assets/svgs/copy.svg diff --git a/apps/gateway-ui/src/assets/svgs/info-solid.svg b/apps/router/src/gateway-ui/assets/svgs/info-solid.svg similarity index 100% rename from apps/gateway-ui/src/assets/svgs/info-solid.svg rename to apps/router/src/gateway-ui/assets/svgs/info-solid.svg diff --git a/apps/gateway-ui/src/assets/svgs/linkIcon.svg b/apps/router/src/gateway-ui/assets/svgs/linkIcon.svg similarity index 100% rename from apps/gateway-ui/src/assets/svgs/linkIcon.svg rename to apps/router/src/gateway-ui/assets/svgs/linkIcon.svg diff --git a/apps/gateway-ui/src/assets/svgs/x-circle.svg b/apps/router/src/gateway-ui/assets/svgs/x-circle.svg similarity index 100% rename from apps/gateway-ui/src/assets/svgs/x-circle.svg rename to apps/router/src/gateway-ui/assets/svgs/x-circle.svg diff --git a/apps/gateway-ui/src/components/ConnectFederationModal.tsx b/apps/router/src/gateway-ui/components/ConnectFederationModal.tsx similarity index 85% rename from apps/gateway-ui/src/components/ConnectFederationModal.tsx rename to apps/router/src/gateway-ui/components/ConnectFederationModal.tsx index cb2fcaa17..d53f5f4c5 100644 --- a/apps/gateway-ui/src/components/ConnectFederationModal.tsx +++ b/apps/router/src/gateway-ui/components/ConnectFederationModal.tsx @@ -13,26 +13,31 @@ import { ModalContent, ModalCloseButton, } from '@chakra-ui/react'; -import { FederationInfo } from '@fedimint/types'; +import { GatewayInfo } from '@fedimint/types'; import { useTranslation } from '@fedimint/utils'; -import { ApiContext } from '../ApiProvider'; +import { + useGatewayApi, + useGatewayContext, + useGatewayInfo, +} from '../../context/hooks'; +import { GATEWAY_APP_ACTION_TYPE } from '../types'; export type ConnectFederationModalProps = { isOpen: boolean; onClose: () => void; - renderConnectedFedCallback: (federation: FederationInfo) => void; }; export const ConnectFederationModal = React.memo( function ConnectFederationModal({ isOpen, onClose, - renderConnectedFedCallback, }: ConnectFederationModalProps) { const { t } = useTranslation(); - const { gateway } = React.useContext(ApiContext); - const [errorMsg, setErrorMsg] = useState(''); + const api = useGatewayApi(); + const { dispatch } = useGatewayContext(); + const gatewayInfo = useGatewayInfo(); const [connectInfo, setConnectInfo] = useState(''); + const [errorMsg, setErrorMsg] = useState(''); const [loading, setLoading] = useState(false); const theme = useTheme(); @@ -45,10 +50,16 @@ export const ConnectFederationModal = React.memo( const handleConnectFederation = () => { setLoading(true); - gateway + api .connectFederation(connectInfo.trim()) .then((federation) => { - renderConnectedFedCallback(federation); + dispatch({ + type: GATEWAY_APP_ACTION_TYPE.SET_GATEWAY_INFO, + payload: { + ...gatewayInfo, + federations: [...gatewayInfo.federations, federation], + } as GatewayInfo, + }); setConnectInfo(''); }) .catch(({ message, error }) => { diff --git a/apps/gateway-ui/src/components/ErrorMessage.tsx b/apps/router/src/gateway-ui/components/ErrorMessage.tsx similarity index 100% rename from apps/gateway-ui/src/components/ErrorMessage.tsx rename to apps/router/src/gateway-ui/components/ErrorMessage.tsx diff --git a/apps/gateway-ui/src/components/GatewayCard.tsx b/apps/router/src/gateway-ui/components/GatewayCard.tsx similarity index 100% rename from apps/gateway-ui/src/components/GatewayCard.tsx rename to apps/router/src/gateway-ui/components/GatewayCard.tsx diff --git a/apps/gateway-ui/src/components/HeaderWithUnitSelector.tsx b/apps/router/src/gateway-ui/components/HeaderWithUnitSelector.tsx similarity index 70% rename from apps/gateway-ui/src/components/HeaderWithUnitSelector.tsx rename to apps/router/src/gateway-ui/components/HeaderWithUnitSelector.tsx index 81a014b7b..e36992ae1 100644 --- a/apps/gateway-ui/src/components/HeaderWithUnitSelector.tsx +++ b/apps/router/src/gateway-ui/components/HeaderWithUnitSelector.tsx @@ -1,15 +1,12 @@ import React from 'react'; import { Flex, Heading, Tabs, TabList, Tab, useTheme } from '@chakra-ui/react'; import { useTranslation } from '@fedimint/utils'; -import { Unit, UNIT_OPTIONS } from '../App'; +import { UNIT_OPTIONS } from '../Gateway'; +import { useGatewayContext } from '../../context/hooks'; +import { GATEWAY_APP_ACTION_TYPE } from '../types'; -interface HeaderWithUnitSelectorProps { - setUnit: (unit: Unit) => void; -} - -export const HeaderWithUnitSelector: React.FC = ({ - setUnit, -}) => { +export const HeaderWithUnitSelector: React.FC = () => { + const { dispatch } = useGatewayContext(); const theme = useTheme(); const { t } = useTranslation(); @@ -31,7 +28,12 @@ export const HeaderWithUnitSelector: React.FC = ({ size='sm' variant='soft-rounded' defaultIndex={1} - onChange={(index) => setUnit(UNIT_OPTIONS[index])} + onChange={(index) => { + dispatch({ + type: GATEWAY_APP_ACTION_TYPE.SET_UNIT, + payload: UNIT_OPTIONS[index], + }); + }} > {UNIT_OPTIONS.map((option) => ( diff --git a/apps/gateway-ui/src/components/Loading.tsx b/apps/router/src/gateway-ui/components/Loading.tsx similarity index 100% rename from apps/gateway-ui/src/components/Loading.tsx rename to apps/router/src/gateway-ui/components/Loading.tsx diff --git a/apps/gateway-ui/src/components/federations/ConnectFederation.tsx b/apps/router/src/gateway-ui/components/federations/ConnectFederation.tsx similarity index 97% rename from apps/gateway-ui/src/components/federations/ConnectFederation.tsx rename to apps/router/src/gateway-ui/components/federations/ConnectFederation.tsx index ecc63a620..7935df2f0 100644 --- a/apps/gateway-ui/src/components/federations/ConnectFederation.tsx +++ b/apps/router/src/gateway-ui/components/federations/ConnectFederation.tsx @@ -18,7 +18,7 @@ import { } from '@chakra-ui/react'; import { FederationInfo } from '@fedimint/types'; import { useTranslation } from '@fedimint/utils'; -import { ApiContext } from '../../ApiProvider'; +import { useGatewayApi } from '../../../context/hooks'; export interface ConnectFedModalProps { isOpen: boolean; @@ -84,7 +84,7 @@ export const ConnectFederation = React.memo(function ConnectFederation({ onClose, }: ConnectFederationProps) { const { t } = useTranslation(); - const { gateway } = React.useContext(ApiContext); + const api = useGatewayApi(); const [errorMsg, setErrorMsg] = useState(''); const [connectInfo, setConnectInfo] = useState(''); const [loading, setLoading] = useState(false); @@ -97,7 +97,7 @@ export const ConnectFederation = React.memo(function ConnectFederation({ const handleConnectFederation = () => { setLoading(true); - gateway + api .connectFederation(connectInfo.trim()) .then((federation) => { renderConnectedFedCallback(federation); diff --git a/apps/gateway-ui/src/components/federations/FederationsTable.tsx b/apps/router/src/gateway-ui/components/federations/FederationsTable.tsx similarity index 98% rename from apps/gateway-ui/src/components/federations/FederationsTable.tsx rename to apps/router/src/gateway-ui/components/federations/FederationsTable.tsx index 702d7cd27..3ba493f1f 100644 --- a/apps/gateway-ui/src/components/federations/FederationsTable.tsx +++ b/apps/router/src/gateway-ui/components/federations/FederationsTable.tsx @@ -13,7 +13,7 @@ import { FederationInfo, MSats } from '@fedimint/types'; import { useTranslation, formatEllipsized, formatValue } from '@fedimint/utils'; import { Table, TableColumn, TableRow } from '@fedimint/ui'; import { ViewConfigModal } from './ViewConfig'; -import { Unit } from '../../App'; +import { Unit } from '../../Gateway'; import { WalletModalAction, WalletModalState, diff --git a/apps/gateway-ui/src/components/federations/ViewConfig.tsx b/apps/router/src/gateway-ui/components/federations/ViewConfig.tsx similarity index 100% rename from apps/gateway-ui/src/components/federations/ViewConfig.tsx rename to apps/router/src/gateway-ui/components/federations/ViewConfig.tsx diff --git a/apps/gateway-ui/src/components/index.tsx b/apps/router/src/gateway-ui/components/index.tsx similarity index 100% rename from apps/gateway-ui/src/components/index.tsx rename to apps/router/src/gateway-ui/components/index.tsx diff --git a/apps/gateway-ui/src/components/lightning/LightningCard.tsx b/apps/router/src/gateway-ui/components/lightning/LightningCard.tsx similarity index 99% rename from apps/gateway-ui/src/components/lightning/LightningCard.tsx rename to apps/router/src/gateway-ui/components/lightning/LightningCard.tsx index 026591059..44b5efc07 100644 --- a/apps/gateway-ui/src/components/lightning/LightningCard.tsx +++ b/apps/router/src/gateway-ui/components/lightning/LightningCard.tsx @@ -47,7 +47,7 @@ export const LightningCard = React.memo(function LightningCard({ {label}: - {value} + {value} ); diff --git a/apps/gateway-ui/src/components/walletCard/WalletCard.tsx b/apps/router/src/gateway-ui/components/walletCard/WalletCard.tsx similarity index 99% rename from apps/gateway-ui/src/components/walletCard/WalletCard.tsx rename to apps/router/src/gateway-ui/components/walletCard/WalletCard.tsx index 9ec5b5db6..6cc3e5697 100644 --- a/apps/gateway-ui/src/components/walletCard/WalletCard.tsx +++ b/apps/router/src/gateway-ui/components/walletCard/WalletCard.tsx @@ -10,7 +10,7 @@ import { WalletModalState, WalletModalType, } from '../walletModal/WalletModal'; -import { Unit } from '../../App'; +import { Unit } from '../../Gateway'; interface WalletCardProps { unit: Unit; diff --git a/apps/gateway-ui/src/components/walletModal/FederationSelector.tsx b/apps/router/src/gateway-ui/components/walletModal/FederationSelector.tsx similarity index 100% rename from apps/gateway-ui/src/components/walletModal/FederationSelector.tsx rename to apps/router/src/gateway-ui/components/walletModal/FederationSelector.tsx diff --git a/apps/gateway-ui/src/components/walletModal/WalletActionSelector.tsx b/apps/router/src/gateway-ui/components/walletModal/WalletActionSelector.tsx similarity index 100% rename from apps/gateway-ui/src/components/walletModal/WalletActionSelector.tsx rename to apps/router/src/gateway-ui/components/walletModal/WalletActionSelector.tsx diff --git a/apps/gateway-ui/src/components/walletModal/WalletModal.tsx b/apps/router/src/gateway-ui/components/walletModal/WalletModal.tsx similarity index 100% rename from apps/gateway-ui/src/components/walletModal/WalletModal.tsx rename to apps/router/src/gateway-ui/components/walletModal/WalletModal.tsx diff --git a/apps/gateway-ui/src/components/walletModal/WalletTypeButtons.tsx b/apps/router/src/gateway-ui/components/walletModal/WalletTypeButtons.tsx similarity index 100% rename from apps/gateway-ui/src/components/walletModal/WalletTypeButtons.tsx rename to apps/router/src/gateway-ui/components/walletModal/WalletTypeButtons.tsx diff --git a/apps/gateway-ui/src/components/walletModal/index.tsx b/apps/router/src/gateway-ui/components/walletModal/index.tsx similarity index 98% rename from apps/gateway-ui/src/components/walletModal/index.tsx rename to apps/router/src/gateway-ui/components/walletModal/index.tsx index db6d29c3f..aeb9fae38 100644 --- a/apps/gateway-ui/src/components/walletModal/index.tsx +++ b/apps/router/src/gateway-ui/components/walletModal/index.tsx @@ -18,7 +18,7 @@ import { import { useTranslation } from '@fedimint/utils'; import { FederationInfo, Sats } from '@fedimint/types'; import { WalletModalState } from './WalletModal'; -import QRCode from 'qrcode.react'; +import { QRCodeSVG } from 'qrcode.react'; import { FiCheck, FiCopy } from 'react-icons/fi'; import { motion } from 'framer-motion'; @@ -132,7 +132,7 @@ const QRCodePanel: React.FC<{ value: string; onCopy: () => void }> = ({ justifyContent='center' width='100%' > - + = ({ setShowSelector }) => { const { t } = useTranslation(); const [ecashNote, setEcashNote] = useState(''); const [claimedAmount, setClaimedAmount] = useState(null); - const gatewayApi = new GatewayApi(); + const api = useGatewayApi(); const handlePaste = async () => { try { const text = await navigator.clipboard.readText(); setEcashNote(text); - const result = await gatewayApi.receiveEcash(text); + const result = await api.receiveEcash(text); setClaimedAmount(result); setShowSelector(false); } catch (err) { diff --git a/apps/gateway-ui/src/components/walletModal/receive/ReceiveLightning.tsx b/apps/router/src/gateway-ui/components/walletModal/receive/ReceiveLightning.tsx similarity index 93% rename from apps/gateway-ui/src/components/walletModal/receive/ReceiveLightning.tsx rename to apps/router/src/gateway-ui/components/walletModal/receive/ReceiveLightning.tsx index cfb68f251..586124ba4 100644 --- a/apps/gateway-ui/src/components/walletModal/receive/ReceiveLightning.tsx +++ b/apps/router/src/gateway-ui/components/walletModal/receive/ReceiveLightning.tsx @@ -4,8 +4,8 @@ import { useTranslation } from '@fedimint/utils'; import { FederationInfo, IncomingContract, Sats } from '@fedimint/types'; import { WalletModalState } from '../WalletModal'; import FederationSelector from '../FederationSelector'; -import { ApiContext } from '../../../ApiProvider'; import { AmountInput, CreateButton, QRCodeTabs } from '..'; +import { useGatewayApi } from '../../../../context/hooks'; interface ReceiveLightningProps { federations: FederationInfo[]; @@ -21,7 +21,7 @@ const ReceiveLightning: React.FC = ({ setShowSelector, }) => { const { t } = useTranslation(); - const { gateway } = React.useContext(ApiContext); + const api = useGatewayApi(); const [amount, setAmount] = useState(0 as Sats); const [invoice, setInvoice] = useState(); const [showInvoiceInfo, setShowInvoiceInfo] = useState(false); @@ -33,7 +33,7 @@ const ReceiveLightning: React.FC = ({ commitment: 'test', ciphertext: 'test', }; - const invoice = await gateway.createBolt11InvoiceV2({ + const invoice = await api.createBolt11InvoiceV2({ federation_id: walletModalState.selectedFederation?.federation_id ?? '', contract: incomingContract, invoice_amount: amount as number, @@ -47,7 +47,7 @@ const ReceiveLightning: React.FC = ({ console.error('Failed to create invoice:', error); } }, [ - gateway, + api, setShowSelector, setShowInvoiceInfo, walletModalState.selectedFederation?.federation_id, diff --git a/apps/gateway-ui/src/components/walletModal/receive/ReceiveOnchain.tsx b/apps/router/src/gateway-ui/components/walletModal/receive/ReceiveOnchain.tsx similarity index 91% rename from apps/gateway-ui/src/components/walletModal/receive/ReceiveOnchain.tsx rename to apps/router/src/gateway-ui/components/walletModal/receive/ReceiveOnchain.tsx index 9a5203ec9..60d96b747 100644 --- a/apps/gateway-ui/src/components/walletModal/receive/ReceiveOnchain.tsx +++ b/apps/router/src/gateway-ui/components/walletModal/receive/ReceiveOnchain.tsx @@ -4,8 +4,8 @@ import { useTranslation } from '@fedimint/utils'; import { Bip21Uri, FederationInfo, Sats } from '@fedimint/types'; import { WalletModalState } from '../WalletModal'; import FederationSelector from '../FederationSelector'; -import { ApiContext } from '../../../ApiProvider'; import { AmountInput, CreateButton, QRCodeTabs } from '..'; +import { useGatewayApi } from '../../../../context/hooks'; interface ReceiveOnchainProps { federations: FederationInfo[]; @@ -21,7 +21,7 @@ const ReceiveOnchain: React.FC = ({ setShowSelector, }) => { const { t } = useTranslation(); - const { gateway } = React.useContext(ApiContext); + const api = useGatewayApi(); const [amount, setAmount] = useState(0 as Sats); const [bip21Uri, setBip21Uri] = useState(); const [showAddressInfo, setShowAddressInfo] = useState(false); @@ -30,9 +30,9 @@ const ReceiveOnchain: React.FC = ({ const handleCreateDepositAddress = useCallback(() => { if (!walletModalState.selectedFederation) return; - gateway + api .fetchPegInAddress(walletModalState.selectedFederation.federation_id) - .then((newAddress) => { + .then((newAddress: string) => { const bip21Uri = new Bip21Uri(newAddress, amount); setBip21Uri(bip21Uri); setShowSelector(false); @@ -42,13 +42,7 @@ const ReceiveOnchain: React.FC = ({ console.error(error, message); alert(t('wallet-modal.receive.address-error', { error: message })); }); - }, [ - gateway, - walletModalState.selectedFederation, - amount, - setShowSelector, - t, - ]); + }, [api, walletModalState.selectedFederation, amount, setShowSelector, t]); if (showAddressInfo) { return ( diff --git a/apps/gateway-ui/src/components/walletModal/send/SendEcash.tsx b/apps/router/src/gateway-ui/components/walletModal/send/SendEcash.tsx similarity index 91% rename from apps/gateway-ui/src/components/walletModal/send/SendEcash.tsx rename to apps/router/src/gateway-ui/components/walletModal/send/SendEcash.tsx index d13c78df5..b67626d27 100644 --- a/apps/gateway-ui/src/components/walletModal/send/SendEcash.tsx +++ b/apps/router/src/gateway-ui/components/walletModal/send/SendEcash.tsx @@ -5,7 +5,7 @@ import { FederationInfo, Sats } from '@fedimint/types'; import { WalletModalState } from '../WalletModal'; import FederationSelector from '../FederationSelector'; import { AmountInput, CreateButton, QRCodeTabs } from '..'; -import { ApiContext } from '../../../ApiProvider'; +import { useGatewayApi } from '../../../../context/hooks'; interface SendEcashProps { federations: FederationInfo[]; @@ -21,7 +21,7 @@ const SendEcash: React.FC = ({ setShowSelector, }) => { const { t } = useTranslation(); - const { gateway } = React.useContext(ApiContext); + const api = useGatewayApi(); const [amount, setAmount] = useState(0 as Sats); const [ecash, setEcash] = useState(''); const [showEcash, setShowEcash] = useState(false); @@ -29,7 +29,7 @@ const SendEcash: React.FC = ({ const handleCreateEcash = useCallback(() => { if (!walletModalState.selectedFederation) return; - gateway + api .spendEcash(walletModalState.selectedFederation.federation_id, amount) .then((newEcash) => { setEcash(newEcash); @@ -40,13 +40,7 @@ const SendEcash: React.FC = ({ console.error(error, message); alert(t('wallet-modal.send.ecash-error', { error: message })); }); - }, [ - gateway, - walletModalState.selectedFederation, - amount, - setShowSelector, - t, - ]); + }, [api, walletModalState.selectedFederation, amount, setShowSelector, t]); if (showEcash) { return ( diff --git a/apps/gateway-ui/src/components/walletModal/send/SendLightning.tsx b/apps/router/src/gateway-ui/components/walletModal/send/SendLightning.tsx similarity index 100% rename from apps/gateway-ui/src/components/walletModal/send/SendLightning.tsx rename to apps/router/src/gateway-ui/components/walletModal/send/SendLightning.tsx diff --git a/apps/gateway-ui/src/components/walletModal/send/SendOnchain.tsx b/apps/router/src/gateway-ui/components/walletModal/send/SendOnchain.tsx similarity index 94% rename from apps/gateway-ui/src/components/walletModal/send/SendOnchain.tsx rename to apps/router/src/gateway-ui/components/walletModal/send/SendOnchain.tsx index a75eebf05..f0fbee450 100644 --- a/apps/gateway-ui/src/components/walletModal/send/SendOnchain.tsx +++ b/apps/router/src/gateway-ui/components/walletModal/send/SendOnchain.tsx @@ -1,4 +1,4 @@ -import React, { useState, useContext } from 'react'; +import React, { useState } from 'react'; import { Flex, Input, @@ -12,8 +12,8 @@ import { WalletModalState } from '../WalletModal'; import { FederationInfo, Sats } from '@fedimint/types'; import FederationSelector from '../FederationSelector'; import { AmountInput } from '..'; -import { ApiContext } from '../../../ApiProvider'; import SendOnchainSuccess from './SendOnchainSuccess'; +import { useGatewayApi } from '../../../../context/hooks'; interface SendOnchainProps { federations: FederationInfo[]; @@ -29,7 +29,7 @@ const SendOnchain: React.FC = ({ setShowSelector, }) => { const { t } = useTranslation(); - const { gateway } = useContext(ApiContext); + const api = useGatewayApi(); const [bitcoinAddress, setBitcoinAddress] = useState(''); const [amountSats, setAmountSats] = useState(0 as Sats); const [successTxid, setSuccessTxid] = useState(null); @@ -67,7 +67,7 @@ const SendOnchain: React.FC = ({ } try { - const txid = await gateway.submitPegOut({ + const txid = await api.submitPegOut({ federationId: walletModalState.selectedFederation.federation_id, satAmountOrAll: amountSats, address: bitcoinAddress, diff --git a/apps/gateway-ui/src/components/walletModal/send/SendOnchainSuccess.tsx b/apps/router/src/gateway-ui/components/walletModal/send/SendOnchainSuccess.tsx similarity index 100% rename from apps/gateway-ui/src/components/walletModal/send/SendOnchainSuccess.tsx rename to apps/router/src/gateway-ui/components/walletModal/send/SendOnchainSuccess.tsx diff --git a/apps/gateway-ui/src/languages/ca.json b/apps/router/src/gateway-ui/languages/ca.json similarity index 100% rename from apps/gateway-ui/src/languages/ca.json rename to apps/router/src/gateway-ui/languages/ca.json diff --git a/apps/gateway-ui/src/languages/de.json b/apps/router/src/gateway-ui/languages/de.json similarity index 100% rename from apps/gateway-ui/src/languages/de.json rename to apps/router/src/gateway-ui/languages/de.json diff --git a/apps/gateway-ui/src/languages/en.json b/apps/router/src/gateway-ui/languages/en.json similarity index 100% rename from apps/gateway-ui/src/languages/en.json rename to apps/router/src/gateway-ui/languages/en.json diff --git a/apps/gateway-ui/src/languages/es.json b/apps/router/src/gateway-ui/languages/es.json similarity index 100% rename from apps/gateway-ui/src/languages/es.json rename to apps/router/src/gateway-ui/languages/es.json diff --git a/apps/gateway-ui/src/languages/fr.json b/apps/router/src/gateway-ui/languages/fr.json similarity index 100% rename from apps/gateway-ui/src/languages/fr.json rename to apps/router/src/gateway-ui/languages/fr.json diff --git a/apps/gateway-ui/src/languages/hu.json b/apps/router/src/gateway-ui/languages/hu.json similarity index 100% rename from apps/gateway-ui/src/languages/hu.json rename to apps/router/src/gateway-ui/languages/hu.json diff --git a/apps/gateway-ui/src/languages/index.ts b/apps/router/src/gateway-ui/languages/index.ts similarity index 100% rename from apps/gateway-ui/src/languages/index.ts rename to apps/router/src/gateway-ui/languages/index.ts diff --git a/apps/gateway-ui/src/languages/it.json b/apps/router/src/gateway-ui/languages/it.json similarity index 100% rename from apps/gateway-ui/src/languages/it.json rename to apps/router/src/gateway-ui/languages/it.json diff --git a/apps/gateway-ui/src/languages/ja.json b/apps/router/src/gateway-ui/languages/ja.json similarity index 100% rename from apps/gateway-ui/src/languages/ja.json rename to apps/router/src/gateway-ui/languages/ja.json diff --git a/apps/gateway-ui/src/languages/ko.json b/apps/router/src/gateway-ui/languages/ko.json similarity index 100% rename from apps/gateway-ui/src/languages/ko.json rename to apps/router/src/gateway-ui/languages/ko.json diff --git a/apps/gateway-ui/src/languages/pt.json b/apps/router/src/gateway-ui/languages/pt.json similarity index 100% rename from apps/gateway-ui/src/languages/pt.json rename to apps/router/src/gateway-ui/languages/pt.json diff --git a/apps/gateway-ui/src/languages/ru.json b/apps/router/src/gateway-ui/languages/ru.json similarity index 100% rename from apps/gateway-ui/src/languages/ru.json rename to apps/router/src/gateway-ui/languages/ru.json diff --git a/apps/gateway-ui/src/languages/zh.json b/apps/router/src/gateway-ui/languages/zh.json similarity index 100% rename from apps/gateway-ui/src/languages/zh.json rename to apps/router/src/gateway-ui/languages/zh.json diff --git a/apps/gateway-ui/src/react-app-env.d.ts b/apps/router/src/gateway-ui/react-app-env.d.ts similarity index 100% rename from apps/gateway-ui/src/react-app-env.d.ts rename to apps/router/src/gateway-ui/react-app-env.d.ts diff --git a/apps/gateway-ui/src/setupTests.ts b/apps/router/src/gateway-ui/setupTests.ts similarity index 100% rename from apps/gateway-ui/src/setupTests.ts rename to apps/router/src/gateway-ui/setupTests.ts diff --git a/apps/router/src/gateway-ui/types.ts b/apps/router/src/gateway-ui/types.ts new file mode 100644 index 000000000..4de45fbeb --- /dev/null +++ b/apps/router/src/gateway-ui/types.ts @@ -0,0 +1,59 @@ +import { GatewayBalances, GatewayInfo } from '@fedimint/types'; +import { Unit } from './Gateway'; + +export type GatewayConfig = { + baseUrl: string; +}; + +export enum GatewayStatus { + Loading, + Initializing, + Configuring, + Connected, + Running, + Disconnected, +} + +export interface GatewayAppState { + status: GatewayStatus; + needsAuth: boolean; + gatewayError: string | undefined; + balances: GatewayBalances | null; + gatewayInfo: GatewayInfo | null; + unit: Unit; +} + +export enum GATEWAY_APP_ACTION_TYPE { + SET_STATUS = 'SET_STATUS', + SET_NEEDS_AUTH = 'SET_NEEDS_AUTH', + SET_ERROR = 'SET_ERROR', + SET_BALANCES = 'SET_BALANCES', + SET_GATEWAY_INFO = 'SET_GATEWAY_INFO', + SET_UNIT = 'SET_UNIT', +} + +export type GatewayAppAction = + | { + type: GATEWAY_APP_ACTION_TYPE.SET_STATUS; + payload: GatewayStatus; + } + | { + type: GATEWAY_APP_ACTION_TYPE.SET_NEEDS_AUTH; + payload: boolean; + } + | { + type: GATEWAY_APP_ACTION_TYPE.SET_ERROR; + payload: string; + } + | { + type: GATEWAY_APP_ACTION_TYPE.SET_BALANCES; + payload: GatewayBalances; + } + | { + type: GATEWAY_APP_ACTION_TYPE.SET_GATEWAY_INFO; + payload: GatewayInfo; + } + | { + type: GATEWAY_APP_ACTION_TYPE.SET_UNIT; + payload: Unit; + }; diff --git a/apps/gateway-ui/src/typings/i18next.d.ts b/apps/router/src/gateway-ui/typings/i18next.d.ts similarity index 100% rename from apps/gateway-ui/src/typings/i18next.d.ts rename to apps/router/src/gateway-ui/typings/i18next.d.ts diff --git a/apps/gateway-ui/src/utils/index.ts b/apps/router/src/gateway-ui/utils/index.ts similarity index 100% rename from apps/gateway-ui/src/utils/index.ts rename to apps/router/src/gateway-ui/utils/index.ts diff --git a/apps/router/src/guardian-ui/Guardian.tsx b/apps/router/src/guardian-ui/Guardian.tsx new file mode 100644 index 000000000..3e7927769 --- /dev/null +++ b/apps/router/src/guardian-ui/Guardian.tsx @@ -0,0 +1,88 @@ +import React, { useMemo } from 'react'; +import { Box, Flex, Spinner, Heading, Text, Center } from '@chakra-ui/react'; +import { Login } from '@fedimint/ui'; +import { SetupContextProvider } from '../context/guardian/SetupContext'; +import { AdminContextProvider } from '../context/guardian/AdminContext'; +import { FederationSetup } from './setup/FederationSetup'; +import { FederationAdmin } from './admin/FederationAdmin'; +import { useGuardianContext, useLoadGuardian } from '../context/hooks'; +import { useTranslation } from '@fedimint/utils'; +import { GUARDIAN_APP_ACTION_TYPE, GuardianStatus } from './types'; +import { formatApiErrorMessage } from './utils/api'; + +export const Guardian: React.FC = () => { + const { api, state, dispatch } = useGuardianContext(); + useLoadGuardian(); + const { t } = useTranslation(); + + const content = useMemo(() => { + if (state.guardianError) { + return ( + + + {t('common.error')} + + {state.guardianError} + + ); + } + + if (state.needsAuth) { + return ( + api.testPassword(password || '')} + setAuthenticated={() => + dispatch({ + type: GUARDIAN_APP_ACTION_TYPE.SET_NEEDS_AUTH, + payload: false, + }) + } + parseError={formatApiErrorMessage} + /> + ); + } + + if (state.status === GuardianStatus.Setup && state.initServerStatus) { + return ( + + + + ); + } + + if (state.status === GuardianStatus.Admin) { + return ( + + + + ); + } + + return ( +
+ +
+ ); + }, [ + state.status, + state.needsAuth, + state.guardianError, + state.initServerStatus, + api, + dispatch, + t, + ]); + + return ( +
+ {content} +
+ ); +}; diff --git a/apps/guardian-ui/src/GuardianApi.ts b/apps/router/src/guardian-ui/GuardianApi.ts similarity index 87% rename from apps/guardian-ui/src/GuardianApi.ts rename to apps/router/src/guardian-ui/GuardianApi.ts index b854dbce8..29be87249 100644 --- a/apps/guardian-ui/src/GuardianApi.ts +++ b/apps/router/src/guardian-ui/GuardianApi.ts @@ -8,7 +8,7 @@ import { FederationStatus, ModuleKind, PeerHashMap, - ServerStatus, + GuardianServerStatus, SignedApiAnnouncement, StatusResponse, Versions, @@ -18,40 +18,18 @@ import { AdminRpc, ModuleRpc, SetupRpc, SharedRpc } from './types'; export const SESSION_STORAGE_KEY = 'guardian-ui-key'; export type GuardianConfig = { - fm_config_api?: string; - tos?: string; + baseUrl: string; }; export class GuardianApi { private websocket: JsonRpcWebsocket | null = null; private connectPromise: Promise | null = null; - private guardianConfig: GuardianConfig | null = null; - public getGuardianConfig = async (): Promise => { - if (this.guardianConfig === null) { - const response = await fetch('/config.json'); - if (!response.ok) { - throw new Error('Could not find config.json'); - } - const config: GuardianConfig = await response.json(); - if ( - config.fm_config_api === 'config api not set' || - !config.fm_config_api - ) { - config.fm_config_api = undefined; - } - this.guardianConfig = config; - } - return this.guardianConfig; - }; - - public setGuardianConfig = (config: GuardianConfig) => { - this.guardianConfig = config; - }; + constructor(private guardianConfig: GuardianConfig) {} /*** WebSocket methods ***/ - public connect = async (websocketUrl: string): Promise => { + public connect = async (): Promise => { if (this.websocket !== null) { return this.websocket; } @@ -62,7 +40,7 @@ export class GuardianApi { this.connectPromise = new Promise((resolve, reject) => { const requestTimeoutMs = 1000 * 60 * 60 * 5; // 5 minutes, dkg can take a while const websocket = new JsonRpcWebsocket( - websocketUrl, + this.guardianConfig.baseUrl, requestTimeoutMs, (error: JsonRpcError) => { console.error('failed to create websocket', error); @@ -201,13 +179,13 @@ export class GuardianApi { const maxTries = 10; const attemptConfirmConsensusRunning = async (): Promise => { try { - if (!this.guardianConfig?.fm_config_api) { - throw new Error('fm_config_api not found in config.json'); + if (!this.guardianConfig?.baseUrl) { + throw new Error('guardian baseUrl not found in config'); } - await this.connect(this.guardianConfig?.fm_config_api); + await this.connect(); await this.shutdown_internal(); const status = await this.status(); - if (status.server === ServerStatus.ConsensusRunning) { + if (status.server === GuardianServerStatus.ConsensusRunning) { return; } else { throw new Error( @@ -317,10 +295,10 @@ export class GuardianApi { params: unknown = null ): Promise => { try { - if (!this.guardianConfig?.fm_config_api) { - throw new Error('fm_config_api not found in config.json'); + if (!this.guardianConfig?.baseUrl) { + throw new Error('guardian baseUrl not found in config'); } - const websocket = await this.connect(this.guardianConfig?.fm_config_api); + const websocket = await this.connect(); // console.log('method', method); const response = await websocket.call(method, [ { diff --git a/apps/guardian-ui/README.md b/apps/router/src/guardian-ui/README.md similarity index 100% rename from apps/guardian-ui/README.md rename to apps/router/src/guardian-ui/README.md diff --git a/apps/guardian-ui/src/admin/FederationAdmin.tsx b/apps/router/src/guardian-ui/admin/FederationAdmin.tsx similarity index 97% rename from apps/guardian-ui/src/admin/FederationAdmin.tsx rename to apps/router/src/guardian-ui/admin/FederationAdmin.tsx index f37715fdf..562220e85 100644 --- a/apps/guardian-ui/src/admin/FederationAdmin.tsx +++ b/apps/router/src/guardian-ui/admin/FederationAdmin.tsx @@ -5,7 +5,6 @@ import { SignedApiAnnouncement, StatusResponse, } from '@fedimint/types'; -import { useAdminContext } from '../hooks'; import { GatewaysCard } from '../components/dashboard/gateways/GatewaysCard'; import { GuardiansCard } from '../components/dashboard/guardians/GuardiansCard'; import { FederationInfoCard } from '../components/dashboard/admin/FederationInfoCard'; @@ -15,6 +14,7 @@ import { InviteCode } from '../components/dashboard/admin/InviteCode'; import { FederationTabsCard } from '../components/dashboard/tabs/FederationTabsCard'; import { BftInfo } from '../components/BftInfo'; import { DangerZone } from '../components/dashboard/danger/DangerZone'; +import { useGuardianAdminApi } from '../../context/hooks'; const findOurPeerId = ( configPeerIds: number[], @@ -24,7 +24,7 @@ const findOurPeerId = ( }; export const FederationAdmin: React.FC = () => { - const { api } = useAdminContext(); + const api = useGuardianAdminApi(); const [status, setStatus] = useState(); const [inviteCode, setInviteCode] = useState(''); const [config, setConfig] = useState(); diff --git a/apps/guardian-ui/src/assets/images/Fedimint-Full.png b/apps/router/src/guardian-ui/assets/images/Fedimint-Full.png similarity index 100% rename from apps/guardian-ui/src/assets/images/Fedimint-Full.png rename to apps/router/src/guardian-ui/assets/images/Fedimint-Full.png diff --git a/apps/guardian-ui/src/assets/svgs/account.svg b/apps/router/src/guardian-ui/assets/svgs/account.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/account.svg rename to apps/router/src/guardian-ui/assets/svgs/account.svg diff --git a/apps/guardian-ui/src/assets/svgs/arrow-left.svg b/apps/router/src/guardian-ui/assets/svgs/arrow-left.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/arrow-left.svg rename to apps/router/src/guardian-ui/assets/svgs/arrow-left.svg diff --git a/apps/guardian-ui/src/assets/svgs/arrow-right.svg b/apps/router/src/guardian-ui/assets/svgs/arrow-right.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/arrow-right.svg rename to apps/router/src/guardian-ui/assets/svgs/arrow-right.svg diff --git a/apps/guardian-ui/src/assets/svgs/banknotes.svg b/apps/router/src/guardian-ui/assets/svgs/banknotes.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/banknotes.svg rename to apps/router/src/guardian-ui/assets/svgs/banknotes.svg diff --git a/apps/guardian-ui/src/assets/svgs/bitcoin-white.svg b/apps/router/src/guardian-ui/assets/svgs/bitcoin-white.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/bitcoin-white.svg rename to apps/router/src/guardian-ui/assets/svgs/bitcoin-white.svg diff --git a/apps/guardian-ui/src/assets/svgs/bitcoin.svg b/apps/router/src/guardian-ui/assets/svgs/bitcoin.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/bitcoin.svg rename to apps/router/src/guardian-ui/assets/svgs/bitcoin.svg diff --git a/apps/guardian-ui/src/assets/svgs/calendar.svg b/apps/router/src/guardian-ui/assets/svgs/calendar.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/calendar.svg rename to apps/router/src/guardian-ui/assets/svgs/calendar.svg diff --git a/apps/guardian-ui/src/assets/svgs/check-circle.svg b/apps/router/src/guardian-ui/assets/svgs/check-circle.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/check-circle.svg rename to apps/router/src/guardian-ui/assets/svgs/check-circle.svg diff --git a/apps/guardian-ui/src/assets/svgs/check.svg b/apps/router/src/guardian-ui/assets/svgs/check.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/check.svg rename to apps/router/src/guardian-ui/assets/svgs/check.svg diff --git a/apps/guardian-ui/src/assets/svgs/chevron-down.svg b/apps/router/src/guardian-ui/assets/svgs/chevron-down.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/chevron-down.svg rename to apps/router/src/guardian-ui/assets/svgs/chevron-down.svg diff --git a/apps/guardian-ui/src/assets/svgs/chevron-up.svg b/apps/router/src/guardian-ui/assets/svgs/chevron-up.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/chevron-up.svg rename to apps/router/src/guardian-ui/assets/svgs/chevron-up.svg diff --git a/apps/guardian-ui/src/assets/svgs/copy.svg b/apps/router/src/guardian-ui/assets/svgs/copy.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/copy.svg rename to apps/router/src/guardian-ui/assets/svgs/copy.svg diff --git a/apps/guardian-ui/src/assets/svgs/ecash.svg b/apps/router/src/guardian-ui/assets/svgs/ecash.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/ecash.svg rename to apps/router/src/guardian-ui/assets/svgs/ecash.svg diff --git a/apps/guardian-ui/src/assets/svgs/fedimint.svg b/apps/router/src/guardian-ui/assets/svgs/fedimint.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/fedimint.svg rename to apps/router/src/guardian-ui/assets/svgs/fedimint.svg diff --git a/apps/guardian-ui/src/assets/svgs/guardians.svg b/apps/router/src/guardian-ui/assets/svgs/guardians.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/guardians.svg rename to apps/router/src/guardian-ui/assets/svgs/guardians.svg diff --git a/apps/guardian-ui/src/assets/svgs/home.svg b/apps/router/src/guardian-ui/assets/svgs/home.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/home.svg rename to apps/router/src/guardian-ui/assets/svgs/home.svg diff --git a/apps/guardian-ui/src/assets/svgs/info.svg b/apps/router/src/guardian-ui/assets/svgs/info.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/info.svg rename to apps/router/src/guardian-ui/assets/svgs/info.svg diff --git a/apps/guardian-ui/src/assets/svgs/intersect-square.svg b/apps/router/src/guardian-ui/assets/svgs/intersect-square.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/intersect-square.svg rename to apps/router/src/guardian-ui/assets/svgs/intersect-square.svg diff --git a/apps/guardian-ui/src/assets/svgs/lightbulb.svg b/apps/router/src/guardian-ui/assets/svgs/lightbulb.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/lightbulb.svg rename to apps/router/src/guardian-ui/assets/svgs/lightbulb.svg diff --git a/apps/guardian-ui/src/assets/svgs/lightningIcon.svg b/apps/router/src/guardian-ui/assets/svgs/lightningIcon.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/lightningIcon.svg rename to apps/router/src/guardian-ui/assets/svgs/lightningIcon.svg diff --git a/apps/guardian-ui/src/assets/svgs/linkIcon.svg b/apps/router/src/guardian-ui/assets/svgs/linkIcon.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/linkIcon.svg rename to apps/router/src/guardian-ui/assets/svgs/linkIcon.svg diff --git a/apps/guardian-ui/src/assets/svgs/modules.svg b/apps/router/src/guardian-ui/assets/svgs/modules.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/modules.svg rename to apps/router/src/guardian-ui/assets/svgs/modules.svg diff --git a/apps/guardian-ui/src/assets/svgs/plus.svg b/apps/router/src/guardian-ui/assets/svgs/plus.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/plus.svg rename to apps/router/src/guardian-ui/assets/svgs/plus.svg diff --git a/apps/guardian-ui/src/assets/svgs/qr.svg b/apps/router/src/guardian-ui/assets/svgs/qr.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/qr.svg rename to apps/router/src/guardian-ui/assets/svgs/qr.svg diff --git a/apps/guardian-ui/src/assets/svgs/settings.svg b/apps/router/src/guardian-ui/assets/svgs/settings.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/settings.svg rename to apps/router/src/guardian-ui/assets/svgs/settings.svg diff --git a/apps/guardian-ui/src/assets/svgs/solo.svg b/apps/router/src/guardian-ui/assets/svgs/solo.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/solo.svg rename to apps/router/src/guardian-ui/assets/svgs/solo.svg diff --git a/apps/guardian-ui/src/assets/svgs/stars.svg b/apps/router/src/guardian-ui/assets/svgs/stars.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/stars.svg rename to apps/router/src/guardian-ui/assets/svgs/stars.svg diff --git a/apps/guardian-ui/src/assets/svgs/trash.svg b/apps/router/src/guardian-ui/assets/svgs/trash.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/trash.svg rename to apps/router/src/guardian-ui/assets/svgs/trash.svg diff --git a/apps/guardian-ui/src/assets/svgs/warning.svg b/apps/router/src/guardian-ui/assets/svgs/warning.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/warning.svg rename to apps/router/src/guardian-ui/assets/svgs/warning.svg diff --git a/apps/guardian-ui/src/assets/svgs/white-check.svg b/apps/router/src/guardian-ui/assets/svgs/white-check.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/white-check.svg rename to apps/router/src/guardian-ui/assets/svgs/white-check.svg diff --git a/apps/guardian-ui/src/assets/svgs/x-circle.svg b/apps/router/src/guardian-ui/assets/svgs/x-circle.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/x-circle.svg rename to apps/router/src/guardian-ui/assets/svgs/x-circle.svg diff --git a/apps/guardian-ui/src/assets/svgs/x.svg b/apps/router/src/guardian-ui/assets/svgs/x.svg similarity index 100% rename from apps/guardian-ui/src/assets/svgs/x.svg rename to apps/router/src/guardian-ui/assets/svgs/x.svg diff --git a/apps/guardian-ui/src/components/BftInfo.tsx b/apps/router/src/guardian-ui/components/BftInfo.tsx similarity index 100% rename from apps/guardian-ui/src/components/BftInfo.tsx rename to apps/router/src/guardian-ui/components/BftInfo.tsx diff --git a/apps/guardian-ui/src/components/NumberFormControl.tsx b/apps/router/src/guardian-ui/components/NumberFormControl.tsx similarity index 100% rename from apps/guardian-ui/src/components/NumberFormControl.tsx rename to apps/router/src/guardian-ui/components/NumberFormControl.tsx diff --git a/apps/guardian-ui/src/components/TermsOfService.tsx b/apps/router/src/guardian-ui/components/TermsOfService.tsx similarity index 100% rename from apps/guardian-ui/src/components/TermsOfService.tsx rename to apps/router/src/guardian-ui/components/TermsOfService.tsx diff --git a/apps/guardian-ui/src/components/dashboard/admin/BalanceCard.tsx b/apps/router/src/guardian-ui/components/dashboard/admin/BalanceCard.tsx similarity index 94% rename from apps/guardian-ui/src/components/dashboard/admin/BalanceCard.tsx rename to apps/router/src/guardian-ui/components/dashboard/admin/BalanceCard.tsx index db30a9d27..4bb6c7538 100644 --- a/apps/guardian-ui/src/components/dashboard/admin/BalanceCard.tsx +++ b/apps/router/src/guardian-ui/components/dashboard/admin/BalanceCard.tsx @@ -10,12 +10,12 @@ import { } from '@chakra-ui/react'; import { AuditSummary } from '@fedimint/types'; import { useTranslation } from '@fedimint/utils'; -import { useAdminContext } from '../../../hooks'; import { BalanceTable } from './BalanceTable'; +import { useGuardianAdminApi } from '../../../../context/hooks'; export const BalanceCard: React.FC = () => { const { t } = useTranslation(); - const { api } = useAdminContext(); + const api = useGuardianAdminApi(); const [auditSummary, setAuditSummary] = useState(); const [unit, setUnit] = useState<'msats' | 'sats' | 'btc'>('msats'); diff --git a/apps/guardian-ui/src/components/dashboard/admin/BalanceTable.tsx b/apps/router/src/guardian-ui/components/dashboard/admin/BalanceTable.tsx similarity index 98% rename from apps/guardian-ui/src/components/dashboard/admin/BalanceTable.tsx rename to apps/router/src/guardian-ui/components/dashboard/admin/BalanceTable.tsx index 7301648f2..f007b8f6d 100644 --- a/apps/guardian-ui/src/components/dashboard/admin/BalanceTable.tsx +++ b/apps/router/src/guardian-ui/components/dashboard/admin/BalanceTable.tsx @@ -75,6 +75,7 @@ export const BalanceTable: React.FC = ({ + {/* TODO: make locales for all these */} {totalAssets - totalLiabilities > 0 && ( diff --git a/apps/guardian-ui/src/components/dashboard/admin/BitcoinNodeCard.tsx b/apps/router/src/guardian-ui/components/dashboard/admin/BitcoinNodeCard.tsx similarity index 100% rename from apps/guardian-ui/src/components/dashboard/admin/BitcoinNodeCard.tsx rename to apps/router/src/guardian-ui/components/dashboard/admin/BitcoinNodeCard.tsx diff --git a/apps/guardian-ui/src/components/dashboard/admin/FederationInfoCard.tsx b/apps/router/src/guardian-ui/components/dashboard/admin/FederationInfoCard.tsx similarity index 96% rename from apps/guardian-ui/src/components/dashboard/admin/FederationInfoCard.tsx rename to apps/router/src/guardian-ui/components/dashboard/admin/FederationInfoCard.tsx index 85da7636c..11405827b 100644 --- a/apps/guardian-ui/src/components/dashboard/admin/FederationInfoCard.tsx +++ b/apps/router/src/guardian-ui/components/dashboard/admin/FederationInfoCard.tsx @@ -10,7 +10,7 @@ import { import { ClientConfig, StatusResponse, Versions } from '@fedimint/types'; import { useTranslation } from '@fedimint/utils'; import { KeyValues } from '@fedimint/ui'; -import { useAdminContext } from '../../../hooks'; +import { useGuardianAdminApi } from '../../../../context/hooks'; interface Props { status: StatusResponse | undefined; @@ -24,7 +24,7 @@ export const FederationInfoCard: React.FC = ({ latestSession, }) => { const { t } = useTranslation(); - const { api } = useAdminContext(); + const api = useGuardianAdminApi(); const [versions, setVersions] = useState(); const [blockCount, setBlockCount] = useState(); diff --git a/apps/guardian-ui/src/components/dashboard/admin/InviteCode.tsx b/apps/router/src/guardian-ui/components/dashboard/admin/InviteCode.tsx similarity index 97% rename from apps/guardian-ui/src/components/dashboard/admin/InviteCode.tsx rename to apps/router/src/guardian-ui/components/dashboard/admin/InviteCode.tsx index e6e96218f..0fc1ed57b 100644 --- a/apps/guardian-ui/src/components/dashboard/admin/InviteCode.tsx +++ b/apps/router/src/guardian-ui/components/dashboard/admin/InviteCode.tsx @@ -17,7 +17,7 @@ import { CopyInput } from '@fedimint/ui'; import { useTranslation } from '@fedimint/utils'; import { ReactComponent as CopyIcon } from '../../../assets/svgs/copy.svg'; import { ReactComponent as QrIcon } from '../../../assets/svgs/qr.svg'; -import QRCode from 'qrcode.react'; +import { QRCodeSVG } from 'qrcode.react'; const QR_CODE_SIZE = 256; @@ -72,7 +72,7 @@ export const InviteCode: React.FC = ({ inviteCode }) => { alignItems='center' direction='column' > - { const theme = useTheme(); const [isWarningModalOpen, setIsWarningModalOpen] = useState(false); - const { api } = useAdminContext(); + const api = useGuardianAdminApi(); const { t } = useTranslation(); const handleConfirmDownload = async () => { diff --git a/apps/guardian-ui/src/components/dashboard/danger/GuardianAuthenticationCode.tsx b/apps/router/src/guardian-ui/components/dashboard/danger/GuardianAuthenticationCode.tsx similarity index 97% rename from apps/guardian-ui/src/components/dashboard/danger/GuardianAuthenticationCode.tsx rename to apps/router/src/guardian-ui/components/dashboard/danger/GuardianAuthenticationCode.tsx index 909e708d4..e436ba5e4 100644 --- a/apps/guardian-ui/src/components/dashboard/danger/GuardianAuthenticationCode.tsx +++ b/apps/router/src/guardian-ui/components/dashboard/danger/GuardianAuthenticationCode.tsx @@ -12,7 +12,7 @@ import { Button, } from '@chakra-ui/react'; import { useTranslation } from '@fedimint/utils'; -import QRCode from 'qrcode.react'; +import { QRCodeSVG } from 'qrcode.react'; const QR_CODE_SIZE = 256; const FEDIMINT_GUARDIAN_PREFIX = 'fedimint:guardian:'; @@ -89,7 +89,7 @@ export const GuardianAuthenticationCode: React.FC< > {t( - 'federation-dashboard.danger-zone.guardian-warning-message', + 'federation-dashboard.danger-zone.guardian-warning-message' )} {t( - 'federation-dashboard.danger-zone.acknowledge-and-download', + 'federation-dashboard.danger-zone.acknowledge-and-download' )} @@ -124,7 +124,7 @@ export const GuardianAuthenticationCode: React.FC< alignItems='center' direction='column' > - {t( - 'federation-dashboard.danger-zone.guardian-connect-warning', + 'federation-dashboard.danger-zone.guardian-connect-warning' )}
diff --git a/apps/guardian-ui/src/components/dashboard/danger/ScheduleShutdown.tsx b/apps/router/src/guardian-ui/components/dashboard/danger/ScheduleShutdown.tsx similarity index 100% rename from apps/guardian-ui/src/components/dashboard/danger/ScheduleShutdown.tsx rename to apps/router/src/guardian-ui/components/dashboard/danger/ScheduleShutdown.tsx diff --git a/apps/guardian-ui/src/components/dashboard/danger/SignApiAnnouncement.tsx b/apps/router/src/guardian-ui/components/dashboard/danger/SignApiAnnouncement.tsx similarity index 98% rename from apps/guardian-ui/src/components/dashboard/danger/SignApiAnnouncement.tsx rename to apps/router/src/guardian-ui/components/dashboard/danger/SignApiAnnouncement.tsx index 437991d2a..e04b956e4 100644 --- a/apps/guardian-ui/src/components/dashboard/danger/SignApiAnnouncement.tsx +++ b/apps/router/src/guardian-ui/components/dashboard/danger/SignApiAnnouncement.tsx @@ -21,7 +21,7 @@ import { useTranslation } from '@fedimint/utils'; import { SignedApiAnnouncement } from '@fedimint/types'; import { normalizeUrl } from '../../../utils'; import { FiCheckCircle, FiAlertTriangle, FiEdit2 } from 'react-icons/fi'; -import { useAdminContext } from '../../../hooks'; +import { useGuardianAdminApi } from '../../../../context/hooks'; interface SignApiAnnouncementProps { ourPeer: { id: number; name: string }; @@ -34,7 +34,7 @@ export const SignApiAnnouncement: React.FC = ({ signedApiAnnouncements, currentApiUrl, }) => { - const { api } = useAdminContext(); + const api = useGuardianAdminApi(); const { t } = useTranslation(); const [isSigningNew, setIsSigningNew] = useState(false); const [isEditing, setIsEditing] = useState(false); diff --git a/apps/guardian-ui/src/components/dashboard/gateways/GatewaysCard.tsx b/apps/router/src/guardian-ui/components/dashboard/gateways/GatewaysCard.tsx similarity index 97% rename from apps/guardian-ui/src/components/dashboard/gateways/GatewaysCard.tsx rename to apps/router/src/guardian-ui/components/dashboard/gateways/GatewaysCard.tsx index 798e0dbd4..fddf3bd1d 100644 --- a/apps/guardian-ui/src/components/dashboard/gateways/GatewaysCard.tsx +++ b/apps/router/src/guardian-ui/components/dashboard/gateways/GatewaysCard.tsx @@ -17,8 +17,8 @@ import { ClientConfig, Gateway, ModuleKind } from '@fedimint/types'; import { Table, TableColumn, TableRow } from '@fedimint/ui'; import { useTranslation, formatEllipsized } from '@fedimint/utils'; import { ModuleRpc } from '../../../types'; -import { useAdminContext } from '../../../hooks'; import { ReactComponent as InfoIcon } from '../../../assets/svgs/info.svg'; +import { useGuardianAdminApi } from '../../../../context/hooks'; type TableKey = 'nodeId' | 'gatewayId' | 'fee'; @@ -29,7 +29,7 @@ interface GatewaysCardProps { export const GatewaysCard: React.FC = ({ config }) => { const theme = useTheme(); const { t } = useTranslation(); - const { api } = useAdminContext(); + const api = useGuardianAdminApi(); const [gateways, setGateways] = useState([]); // TODO: This is a hack to get the ln module id, extract this logic into the api interface like block count diff --git a/apps/guardian-ui/src/components/dashboard/guardians/GuardiansCard.tsx b/apps/router/src/guardian-ui/components/dashboard/guardians/GuardiansCard.tsx similarity index 100% rename from apps/guardian-ui/src/components/dashboard/guardians/GuardiansCard.tsx rename to apps/router/src/guardian-ui/components/dashboard/guardians/GuardiansCard.tsx diff --git a/apps/guardian-ui/src/components/dashboard/tabs/ApiAnnouncements.tsx b/apps/router/src/guardian-ui/components/dashboard/tabs/ApiAnnouncements.tsx similarity index 100% rename from apps/guardian-ui/src/components/dashboard/tabs/ApiAnnouncements.tsx rename to apps/router/src/guardian-ui/components/dashboard/tabs/ApiAnnouncements.tsx diff --git a/apps/guardian-ui/src/components/dashboard/tabs/FederationTabsCard.tsx b/apps/router/src/guardian-ui/components/dashboard/tabs/FederationTabsCard.tsx similarity index 100% rename from apps/guardian-ui/src/components/dashboard/tabs/FederationTabsCard.tsx rename to apps/router/src/guardian-ui/components/dashboard/tabs/FederationTabsCard.tsx diff --git a/apps/guardian-ui/src/components/dashboard/tabs/meta/EditMetaField.tsx b/apps/router/src/guardian-ui/components/dashboard/tabs/meta/EditMetaField.tsx similarity index 100% rename from apps/guardian-ui/src/components/dashboard/tabs/meta/EditMetaField.tsx rename to apps/router/src/guardian-ui/components/dashboard/tabs/meta/EditMetaField.tsx diff --git a/apps/guardian-ui/src/components/dashboard/tabs/meta/MetaManager.tsx b/apps/router/src/guardian-ui/components/dashboard/tabs/meta/MetaManager.tsx similarity index 98% rename from apps/guardian-ui/src/components/dashboard/tabs/meta/MetaManager.tsx rename to apps/router/src/guardian-ui/components/dashboard/tabs/meta/MetaManager.tsx index b43215054..ac7c9b406 100644 --- a/apps/guardian-ui/src/components/dashboard/tabs/meta/MetaManager.tsx +++ b/apps/router/src/guardian-ui/components/dashboard/tabs/meta/MetaManager.tsx @@ -19,8 +19,8 @@ import { MetaFields } from '@fedimint/types'; import { ViewConsensusMeta, ConsensusMetaFields } from './ViewConsensusMeta'; import { ProposedMetas } from './ProposedMetas'; import { EditMetaField } from './EditMetaField'; -import { useAdminContext } from '../../../../hooks'; import { ModuleRpc } from '../../../../types'; +import { useGuardianAdminApi } from '../../../../../context/hooks'; export const DEFAULT_META_KEY = 0; const POLL_TIMEOUT_MS = 2000; @@ -54,7 +54,7 @@ export const MetaManager = React.memo(function MetaManager({ setEditedMetaFields, }: MetaManagerProps): JSX.Element { const { t } = useTranslation(); - const { api } = useAdminContext(); + const api = useGuardianAdminApi(); const { isOpen, onOpen: originalOnOpen, onClose } = useDisclosure(); const theme = useTheme(); diff --git a/apps/guardian-ui/src/components/dashboard/tabs/meta/ProposedMetas.tsx b/apps/router/src/guardian-ui/components/dashboard/tabs/meta/ProposedMetas.tsx similarity index 99% rename from apps/guardian-ui/src/components/dashboard/tabs/meta/ProposedMetas.tsx rename to apps/router/src/guardian-ui/components/dashboard/tabs/meta/ProposedMetas.tsx index c936e7237..c47784817 100644 --- a/apps/guardian-ui/src/components/dashboard/tabs/meta/ProposedMetas.tsx +++ b/apps/router/src/guardian-ui/components/dashboard/tabs/meta/ProposedMetas.tsx @@ -25,11 +25,11 @@ import { } from '@fedimint/utils'; import { MetaFields, MetaSubmissions } from '@fedimint/types'; -import { useAdminContext } from '../../../../hooks'; import { ModuleRpc } from '../../../../types'; import { Table, TableColumn } from '@fedimint/ui'; import { DEFAULT_META_KEY } from './MetaManager'; import { bftHonest, generateSimpleHash } from '../../../../utils'; +import { useGuardianAdminApi } from '../../../../../context/hooks'; type MetaSubmissionMap = { [key: string]: { @@ -59,7 +59,7 @@ export const ProposedMetas = React.memo(function ProposedMetas({ consensusMeta, }: ProposedMetasProps): JSX.Element { const { t } = useTranslation(); - const { api } = useAdminContext(); + const api = useGuardianAdminApi(); const { isOpen, onOpen: openModal, onClose } = useDisclosure(); const [metaSubmissions, setMetaSubmissions] = useState(); const [hasVoted, setHasVoted] = useState(false); diff --git a/apps/guardian-ui/src/components/dashboard/tabs/meta/ViewConsensusMeta.tsx b/apps/router/src/guardian-ui/components/dashboard/tabs/meta/ViewConsensusMeta.tsx similarity index 97% rename from apps/guardian-ui/src/components/dashboard/tabs/meta/ViewConsensusMeta.tsx rename to apps/router/src/guardian-ui/components/dashboard/tabs/meta/ViewConsensusMeta.tsx index 20687330d..b0cebe618 100644 --- a/apps/guardian-ui/src/components/dashboard/tabs/meta/ViewConsensusMeta.tsx +++ b/apps/router/src/guardian-ui/components/dashboard/tabs/meta/ViewConsensusMeta.tsx @@ -2,9 +2,9 @@ import React, { useEffect, useMemo } from 'react'; import { Flex, Text, useTheme } from '@chakra-ui/react'; import { useTranslation, hexToMeta, metaToFields } from '@fedimint/utils'; import { ConsensusMeta, MetaFields } from '@fedimint/types'; -import { useAdminContext } from '../../../../hooks'; import { ModuleRpc } from '../../../../types'; import { Table, TableColumn, TableRow } from '@fedimint/ui'; +import { useGuardianAdminApi } from '../../../../../context/hooks'; interface ViewConsensusMetaProps { metaKey: number; @@ -29,7 +29,7 @@ export const ViewConsensusMeta = React.memo(function ConsensusMetaFields({ updateConsensusMeta, }: ViewConsensusMetaProps): JSX.Element { const { t } = useTranslation(); - const { api } = useAdminContext(); + const api = useGuardianAdminApi(); const theme = useTheme(); useEffect(() => { diff --git a/apps/guardian-ui/src/components/setup/RunDKG.tsx b/apps/router/src/guardian-ui/components/setup/RunDKG.tsx similarity index 83% rename from apps/guardian-ui/src/components/setup/RunDKG.tsx rename to apps/router/src/guardian-ui/components/setup/RunDKG.tsx index 1720e8ebe..6cb5c991b 100644 --- a/apps/guardian-ui/src/components/setup/RunDKG.tsx +++ b/apps/router/src/guardian-ui/components/setup/RunDKG.tsx @@ -7,10 +7,15 @@ import { Flex, useTheme, } from '@chakra-ui/react'; -import { ServerStatus } from '@fedimint/types'; +import { GuardianServerStatus } from '@fedimint/types'; import { useTranslation } from '@fedimint/utils'; -import { useConsensusPolling, useEllipsis, useSetupContext } from '../../hooks'; +import { useEllipsis } from '../../hooks'; import { formatApiErrorMessage } from '../../utils/api'; +import { + useConsensusPolling, + useGuardianSetupApi, + useGuardianSetupContext, +} from '../../../context/hooks'; interface Props { next(): void; @@ -18,10 +23,10 @@ interface Props { export const RunDKG: React.FC = ({ next }) => { const { t } = useTranslation(); + const api = useGuardianSetupApi(); const { - api, state: { peers }, - } = useSetupContext(); + } = useGuardianSetupContext(); const theme = useTheme(); const [isWaitingForOthers, setIsWaitingForOthers] = useState(false); const [error, setError] = useState(); @@ -40,20 +45,20 @@ export const RunDKG: React.FC = ({ next }) => { const status = await api.status(); if (canceled) return; switch (status.server) { - case ServerStatus.SharingConfigGenParams: + case GuardianServerStatus.SharingConfigGenParams: await api.runDkg().catch((err) => { // If we timed out, np just try again if (err.code === -32002) return; throw err; }); break; - case ServerStatus.ReadyForConfigGen: + case GuardianServerStatus.ReadyForConfigGen: setIsWaitingForOthers(true); break; - case ServerStatus.VerifyingConfigs: + case GuardianServerStatus.VerifyingConfigs: next(); break; - case ServerStatus.ConfigGenFailed: + case GuardianServerStatus.ConfigGenFailed: setError(`${t('run-dkg.error-config')}`); break; default: @@ -75,7 +80,7 @@ export const RunDKG: React.FC = ({ next }) => { const progress = useMemo(() => { if (!peers.length) return 0; const peersWaiting = peers.filter( - (p) => p.status === ServerStatus.ReadyForConfigGen + (p) => p.status === GuardianServerStatus.ReadyForConfigGen ); return Math.round((peersWaiting.length / peers.length) * 100); }, [peers]); diff --git a/apps/guardian-ui/src/components/setup/SetupProgress.tsx b/apps/router/src/guardian-ui/components/setup/SetupProgress.tsx similarity index 100% rename from apps/guardian-ui/src/components/setup/SetupProgress.tsx rename to apps/router/src/guardian-ui/components/setup/SetupProgress.tsx diff --git a/apps/guardian-ui/src/components/setup/screens/connectGuardians/ConnectGuardians.tsx b/apps/router/src/guardian-ui/components/setup/screens/connectGuardians/ConnectGuardians.tsx similarity index 93% rename from apps/guardian-ui/src/components/setup/screens/connectGuardians/ConnectGuardians.tsx rename to apps/router/src/guardian-ui/components/setup/screens/connectGuardians/ConnectGuardians.tsx index 2f540a568..f948784cf 100644 --- a/apps/guardian-ui/src/components/setup/screens/connectGuardians/ConnectGuardians.tsx +++ b/apps/router/src/guardian-ui/components/setup/screens/connectGuardians/ConnectGuardians.tsx @@ -15,12 +15,15 @@ import { Icon, } from '@chakra-ui/react'; import { CopyInput, Table, TableRow } from '@fedimint/ui'; -import { ModuleKind, ServerStatus } from '@fedimint/types'; +import { ModuleKind, GuardianServerStatus } from '@fedimint/types'; import { useTranslation } from '@fedimint/utils'; -import { useConsensusPolling, useSetupContext } from '../../../../hooks'; import { GuardianRole } from '../../../../types'; import { getModuleParamsFromConfig } from '../../../../utils/api'; import { ReactComponent as CopyIcon } from '../../../../assets/svgs/copy.svg'; +import { + useConsensusPolling, + useGuardianSetupContext, +} from '../../../../../context/hooks'; interface Props { next(): void; @@ -30,7 +33,7 @@ export const ConnectGuardians: React.FC = ({ next }) => { const { t } = useTranslation(); const { state: { role, peers, numPeers, configGenParams, ourCurrentId }, - } = useSetupContext(); + } = useGuardianSetupContext(); const guardianLink = ourCurrentId !== null ? peers[ourCurrentId].api_url : ''; @@ -40,8 +43,9 @@ export const ConnectGuardians: React.FC = ({ next }) => { const isAllConnected = numPeers && numPeers == peers.length; const isAllAccepted = isAllConnected && - peers.filter((peer) => peer.status === ServerStatus.ReadyForConfigGen) - .length >= + peers.filter( + (peer) => peer.status === GuardianServerStatus.ReadyForConfigGen + ).length >= numPeers - 1; // For hosts, once all peers have connected, run DKG immediately. @@ -169,7 +173,7 @@ export const ConnectGuardians: React.FC = ({ next }) => { peers[i].name + (ourCurrentId === i ? ` (${t('common.you')})` : ''), status: - peers[i].status === ServerStatus.ReadyForConfigGen || + peers[i].status === GuardianServerStatus.ReadyForConfigGen || ourCurrentId === i ? ( {t('connect-guardians.approved')} ) : ( diff --git a/apps/guardian-ui/src/components/setup/screens/roleSelector/RoleSelector.tsx b/apps/router/src/guardian-ui/components/setup/screens/roleSelector/RoleSelector.tsx similarity index 96% rename from apps/guardian-ui/src/components/setup/screens/roleSelector/RoleSelector.tsx rename to apps/router/src/guardian-ui/components/setup/screens/roleSelector/RoleSelector.tsx index 8ccb91db9..7ef7024ef 100644 --- a/apps/guardian-ui/src/components/setup/screens/roleSelector/RoleSelector.tsx +++ b/apps/router/src/guardian-ui/components/setup/screens/roleSelector/RoleSelector.tsx @@ -17,9 +17,9 @@ import { ReactComponent as StarsIcon } from '../../../../assets/svgs/stars.svg'; import { ReactComponent as IntersectSquareIcon } from '../../../../assets/svgs/intersect-square.svg'; import { ReactComponent as WarningIcon } from '../../../../assets/svgs/warning.svg'; import { ReactComponent as SoloIcon } from '../../../../assets/svgs/solo.svg'; -import { useSetupContext } from '../../../../hooks'; import { useTranslation } from '@fedimint/utils'; import { WarningModal } from './WarningModal'; +import { useGuardianSetupContext } from '../../../../../context/hooks'; interface Props { next: () => void; @@ -29,7 +29,7 @@ export const RoleSelector = React.memo(function RoleSelector({ next, }: Props) { const { t } = useTranslation(); - const { dispatch } = useSetupContext(); + const { dispatch } = useGuardianSetupContext(); const [role, setRole] = useState(); const [isModalOpen, setIsModalOpen] = useState(false); diff --git a/apps/guardian-ui/src/components/setup/screens/roleSelector/WarningModal.tsx b/apps/router/src/guardian-ui/components/setup/screens/roleSelector/WarningModal.tsx similarity index 100% rename from apps/guardian-ui/src/components/setup/screens/roleSelector/WarningModal.tsx rename to apps/router/src/guardian-ui/components/setup/screens/roleSelector/WarningModal.tsx diff --git a/apps/guardian-ui/src/components/setup/screens/setConfiguration/BasicSettingsForm.tsx b/apps/router/src/guardian-ui/components/setup/screens/setConfiguration/BasicSettingsForm.tsx similarity index 100% rename from apps/guardian-ui/src/components/setup/screens/setConfiguration/BasicSettingsForm.tsx rename to apps/router/src/guardian-ui/components/setup/screens/setConfiguration/BasicSettingsForm.tsx diff --git a/apps/guardian-ui/src/components/setup/screens/setConfiguration/BitcoinSettingsForm.tsx b/apps/router/src/guardian-ui/components/setup/screens/setConfiguration/BitcoinSettingsForm.tsx similarity index 100% rename from apps/guardian-ui/src/components/setup/screens/setConfiguration/BitcoinSettingsForm.tsx rename to apps/router/src/guardian-ui/components/setup/screens/setConfiguration/BitcoinSettingsForm.tsx diff --git a/apps/guardian-ui/src/components/setup/screens/setConfiguration/ConfirmPasswordModal.tsx b/apps/router/src/guardian-ui/components/setup/screens/setConfiguration/ConfirmPasswordModal.tsx similarity index 100% rename from apps/guardian-ui/src/components/setup/screens/setConfiguration/ConfirmPasswordModal.tsx rename to apps/router/src/guardian-ui/components/setup/screens/setConfiguration/ConfirmPasswordModal.tsx diff --git a/apps/guardian-ui/src/components/setup/screens/setConfiguration/FederationSettingsForm.tsx b/apps/router/src/guardian-ui/components/setup/screens/setConfiguration/FederationSettingsForm.tsx similarity index 100% rename from apps/guardian-ui/src/components/setup/screens/setConfiguration/FederationSettingsForm.tsx rename to apps/router/src/guardian-ui/components/setup/screens/setConfiguration/FederationSettingsForm.tsx diff --git a/apps/guardian-ui/src/components/setup/screens/setConfiguration/SetConfiguration.tsx b/apps/router/src/guardian-ui/components/setup/screens/setConfiguration/SetConfiguration.tsx similarity index 98% rename from apps/guardian-ui/src/components/setup/screens/setConfiguration/SetConfiguration.tsx rename to apps/router/src/guardian-ui/components/setup/screens/setConfiguration/SetConfiguration.tsx index 2eb4cd753..32632691c 100644 --- a/apps/guardian-ui/src/components/setup/screens/setConfiguration/SetConfiguration.tsx +++ b/apps/router/src/guardian-ui/components/setup/screens/setConfiguration/SetConfiguration.tsx @@ -14,7 +14,6 @@ import { Network, } from '@fedimint/types'; import { useTranslation } from '@fedimint/utils'; -import { useSetupContext } from '../../../../hooks'; import { GuardianRole } from '../../../../types'; import { ReactComponent as ArrowRightIcon } from '../../../../assets/svgs/arrow-right.svg'; import { @@ -27,6 +26,10 @@ import { BasicSettingsForm } from './BasicSettingsForm'; import { FederationSettingsForm } from './FederationSettingsForm'; import { BitcoinSettingsForm } from './BitcoinSettingsForm'; import { ConfirmPasswordModal } from './ConfirmPasswordModal'; +import { + useGuardianSetupApi, + useGuardianSetupContext, +} from '../../../../../context/hooks'; interface Props { next: () => void; @@ -36,6 +39,7 @@ const MIN_BFT_NUM_PEERS = '4'; export const SetConfiguration: React.FC = ({ next }: Props) => { const { t } = useTranslation(); + const api = useGuardianSetupApi(); const { state: { role, @@ -44,9 +48,8 @@ export const SetConfiguration: React.FC = ({ next }: Props) => { password: statePassword, numPeers: stateNumPeers, }, - api, submitConfiguration, - } = useSetupContext(); + } = useGuardianSetupContext(); const theme = useTheme(); const isHost = role === GuardianRole.Host; const isSolo = role === GuardianRole.Solo; diff --git a/apps/guardian-ui/src/components/setup/screens/setupComplete/SetupComplete.tsx b/apps/router/src/guardian-ui/components/setup/screens/setupComplete/SetupComplete.tsx similarity index 77% rename from apps/guardian-ui/src/components/setup/screens/setupComplete/SetupComplete.tsx rename to apps/router/src/guardian-ui/components/setup/screens/setupComplete/SetupComplete.tsx index 43c81d0f4..bc0f9a1cc 100644 --- a/apps/guardian-ui/src/components/setup/screens/setupComplete/SetupComplete.tsx +++ b/apps/router/src/guardian-ui/components/setup/screens/setupComplete/SetupComplete.tsx @@ -1,8 +1,12 @@ import React, { useEffect } from 'react'; import { Flex, Heading, Text, Spinner } from '@chakra-ui/react'; -import { useAppContext } from '../../../../hooks'; import { useTranslation } from '@fedimint/utils'; -import { APP_ACTION_TYPE, GuardianRole, Status } from '../../../../types'; +import { + GUARDIAN_APP_ACTION_TYPE, + GuardianRole, + GuardianStatus, +} from '../../../../types'; +import { useGuardianContext } from '../../../../../context/hooks'; interface SetupCompleteProps { role: GuardianRole; @@ -10,11 +14,14 @@ interface SetupCompleteProps { export const SetupComplete: React.FC = ({ role }) => { const { t } = useTranslation(); - const { dispatch } = useAppContext(); + const { dispatch } = useGuardianContext(); useEffect(() => { const timer = setTimeout(() => { - dispatch({ type: APP_ACTION_TYPE.SET_STATUS, payload: Status.Admin }); + dispatch({ + type: GUARDIAN_APP_ACTION_TYPE.SET_STATUS, + payload: GuardianStatus.Admin, + }); }, 3000); return () => clearTimeout(timer); diff --git a/apps/guardian-ui/src/components/setup/screens/verifyGuardians/VerifyGuardians.tsx b/apps/router/src/guardian-ui/components/setup/screens/verifyGuardians/VerifyGuardians.tsx similarity index 96% rename from apps/guardian-ui/src/components/setup/screens/verifyGuardians/VerifyGuardians.tsx rename to apps/router/src/guardian-ui/components/setup/screens/verifyGuardians/VerifyGuardians.tsx index d6a434ce1..fc26b2ced 100644 --- a/apps/guardian-ui/src/components/setup/screens/verifyGuardians/VerifyGuardians.tsx +++ b/apps/router/src/guardian-ui/components/setup/screens/verifyGuardians/VerifyGuardians.tsx @@ -27,16 +27,20 @@ import { ModalBody, ModalCloseButton, } from '@chakra-ui/react'; -import { ServerStatus, Peer } from '@fedimint/types'; +import { GuardianServerStatus, Peer } from '@fedimint/types'; import { useTranslation } from '@fedimint/utils'; import { CopyInput, Table } from '@fedimint/ui'; -import { useConsensusPolling, useSetupContext } from '../../../../hooks'; import { GuardianRole } from '../../../../types'; import { ReactComponent as ArrowRightIcon } from '../../../../assets/svgs/arrow-right.svg'; import { ReactComponent as CopyIcon } from '../../../../assets/svgs/copy.svg'; import { formatApiErrorMessage } from '../../../../utils/api'; import { ReactComponent as CheckCircleIcon } from '../../../../assets/svgs/check-circle.svg'; import { ReactComponent as XCircleIcon } from '../../../../assets/svgs/x-circle.svg'; +import { + useConsensusPolling, + useGuardianSetupApi, + useGuardianSetupContext, +} from '../../../../../context/hooks'; interface PeerWithHash { id: string; @@ -50,11 +54,11 @@ interface Props { export const VerifyGuardians: React.FC = ({ next }) => { const { t } = useTranslation(); + const api = useGuardianSetupApi(); const { - api, state: { role, numPeers, peers, ourCurrentId }, toggleConsensusPolling, - } = useSetupContext(); + } = useGuardianSetupContext(); const theme = useTheme(); const isHost = role === GuardianRole.Host; const [myHash, setMyHash] = useState(''); @@ -70,7 +74,11 @@ export const VerifyGuardians: React.FC = ({ next }) => { useConsensusPolling(); useEffect(() => { - if (peers.every((peer) => peer.status === ServerStatus.VerifiedConfigs)) { + if ( + peers.every( + (peer) => peer.status === GuardianServerStatus.VerifiedConfigs + ) + ) { setVerifiedConfigs(true); } @@ -102,7 +110,9 @@ export const VerifyGuardians: React.FC = ({ next }) => { ); // If we're already at the VerifiedConfigs state, prefill all the other hashes with the correct values - if (peers[ourCurrentId].status === ServerStatus.VerifiedConfigs) { + if ( + peers[ourCurrentId].status === GuardianServerStatus.VerifiedConfigs + ) { const otherPeers = Object.entries(peers).filter( ([id]) => id !== ourCurrentId.toString() ); diff --git a/apps/router/src/guardian-ui/hooks/index.tsx b/apps/router/src/guardian-ui/hooks/index.tsx new file mode 100644 index 000000000..1e347acc3 --- /dev/null +++ b/apps/router/src/guardian-ui/hooks/index.tsx @@ -0,0 +1,14 @@ +import { useEffect, useState } from 'react'; + +export const useEllipsis = () => { + const [ellipsis, setEllipsis] = useState(''); + + useEffect(() => { + const interval = setInterval(() => { + setEllipsis((prev) => (prev.length < 3 ? prev + '.' : '')); + }, 500); + return () => clearInterval(interval); + }, []); + + return ellipsis; +}; diff --git a/apps/guardian-ui/src/react-app-env.d.ts b/apps/router/src/guardian-ui/react-app-env.d.ts similarity index 100% rename from apps/guardian-ui/src/react-app-env.d.ts rename to apps/router/src/guardian-ui/react-app-env.d.ts diff --git a/apps/guardian-ui/src/setup/FederationSetup.tsx b/apps/router/src/guardian-ui/setup/FederationSetup.tsx similarity index 93% rename from apps/guardian-ui/src/setup/FederationSetup.tsx rename to apps/router/src/guardian-ui/setup/FederationSetup.tsx index 662e6b634..941d06887 100644 --- a/apps/guardian-ui/src/setup/FederationSetup.tsx +++ b/apps/router/src/guardian-ui/setup/FederationSetup.tsx @@ -1,7 +1,6 @@ -import React, { useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useState } from 'react'; import { Box, Button, Text, Heading, Icon, Flex } from '@chakra-ui/react'; import { useTranslation } from '@fedimint/utils'; -import { useSetupContext } from '../hooks'; import { GuardianRole, SetupProgress, @@ -19,8 +18,12 @@ import { TermsOfService } from '../components/TermsOfService'; import { ReactComponent as ArrowLeftIcon } from '../assets/svgs/arrow-left.svg'; import { ReactComponent as CancelIcon } from '../assets/svgs/x-circle.svg'; -import { ServerStatus } from '@fedimint/types'; +import { GuardianServerStatus } from '@fedimint/types'; import { RestartModals } from './RestartModals'; +import { + useGuardianSetupApi, + useGuardianSetupContext, +} from '../../context/hooks'; const PROGRESS_ORDER: SetupProgress[] = [ SetupProgress.Start, @@ -33,11 +36,11 @@ const PROGRESS_ORDER: SetupProgress[] = [ export const FederationSetup: React.FC = () => { const { t } = useTranslation(); + const api = useGuardianSetupApi(); const { state: { progress, role, peers, tosConfig }, dispatch, - api, - } = useSetupContext(); + } = useGuardianSetupContext(); const [confirmRestart, setConfirmRestart] = useState(false); const setTosConfig = useCallback( @@ -47,14 +50,6 @@ export const FederationSetup: React.FC = () => { [dispatch] ); - useEffect(() => { - async function getTos() { - const tos = (await api.getGuardianConfig()).tos; - setTosConfig({ showTos: !!tos, tos }); - } - getTos(); - }, [api, setTosConfig]); - const isHost = role === GuardianRole.Host; const isSolo = role === GuardianRole.Solo; const progressIdx = PROGRESS_ORDER.indexOf(progress); @@ -155,7 +150,7 @@ export const FederationSetup: React.FC = () => { const isPeerRestarted = canRestart && peers && - peers.some((peer) => peer.status === ServerStatus.SetupRestarted); + peers.some((peer) => peer.status === GuardianServerStatus.SetupRestarted); return ( void; +} + +export const ConnectServiceModal: React.FC = ({ + isOpen, + onClose, +}) => { + const { t } = useTranslation(); + const [configUrl, setConfigUrl] = useState(''); + const [isLoading, setIsLoading] = useState(false); + const { guardians, gateways, dispatch } = useAppContext(); + + const handleSubmit = async () => { + setIsLoading(true); + const isWebSocket = + configUrl.startsWith('ws://') || configUrl.startsWith('wss://'); + const isHttp = + configUrl.startsWith('http://') || configUrl.startsWith('https://'); + + const configUrlHash = await sha256Hash(configUrl); + + if (isWebSocket) { + if (Object.hasOwn(guardians, configUrlHash)) { + console.error('Guardian already exists'); + return; + } + const guardianConfig: GuardianConfig = { baseUrl: configUrl }; + dispatch({ + type: APP_ACTION_TYPE.ADD_GUARDIAN, + payload: { + id: configUrlHash, + guardian: { config: guardianConfig }, + }, + }); + } else if (isHttp) { + if (Object.hasOwn(gateways, configUrlHash)) { + console.error('Gateway already exists'); + return; + } + const gatewayConfig: GatewayConfig = { baseUrl: configUrl }; + dispatch({ + type: APP_ACTION_TYPE.ADD_GATEWAY, + payload: { + id: configUrlHash, + gateway: { config: gatewayConfig }, + }, + }); + } else { + console.error('Invalid URL format'); + return; + } + setIsLoading(false); + setConfigUrl(''); + onClose(); + }; + + return ( + + + + {t('home.addService', 'Add Service')} + + + + {t('notConfigured.urlLabel')} + setConfigUrl(e.target.value)} + /> + + + + + + ); +}; diff --git a/apps/router/src/home/HomePage.tsx b/apps/router/src/home/HomePage.tsx new file mode 100644 index 000000000..62a430d80 --- /dev/null +++ b/apps/router/src/home/HomePage.tsx @@ -0,0 +1,124 @@ +import React, { useContext, useMemo } from 'react'; +import { Link } from 'react-router-dom'; +import { + Box, + Button, + Card, + CardBody, + CardHeader, + Flex, + Heading, + Table, + Tbody, + Td, + Text, + Th, + Thead, + Tr, + useDisclosure, +} from '@chakra-ui/react'; +import { useTranslation } from '@fedimint/utils'; +import { AppContext } from '../context/AppContext'; +import { ConnectServiceModal } from './ConnectServiceModal'; + +export const HomePage: React.FC = () => { + const { t } = useTranslation(); + const { guardians, gateways } = useContext(AppContext); + const { isOpen, onOpen, onClose } = useDisclosure(); + + const content = useMemo(() => { + return ( + + + + {t('home.services', 'Services')} + + + + + {Object.keys(guardians).length > 0 && ( + + + {t('home.guardians', 'Guardians')} + + + + + + + + + + + {Object.entries(guardians).map( + ([guardianIndex, guardian]) => ( + + + + + ) + )} + +
{t('home.guardianUrl', 'Guardian URL')}{t('home.actions', 'Actions')}
{guardian.config.baseUrl} + + + +
+
+
+ )} + + {Object.keys(gateways).length > 0 && ( + + + {t('home.gateways', 'Gateways')} + + + + + + + + + + + {Object.entries(gateways).map(([gatewayIndex, gateway]) => ( + + + + + ))} + +
{t('home.gatewayUrl', 'Gateway URL')}{t('home.actions', 'Actions')}
{gateway.config.baseUrl} + + + +
+
+
+ )} + + {Object.keys(guardians).length + Object.keys(gateways).length === 0 && ( + {t('home.noServices', 'No services connected yet.')} + )} +
+ ); + }, [guardians, gateways, t, onOpen]); + + return ( + <> + {content} + + + ); +}; diff --git a/apps/router/src/index.tsx b/apps/router/src/index.tsx new file mode 100644 index 000000000..45d110c52 --- /dev/null +++ b/apps/router/src/index.tsx @@ -0,0 +1,62 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; +import { Guardian } from './guardian-ui/Guardian'; +import { Gateway } from './gateway-ui/Gateway'; +import { Fonts, SharedChakraProvider, theme, Wrapper } from '@fedimint/ui'; +import spaceGroteskTtf from '@fedimint/ui/assets/fonts/SpaceGrotesk-Variable.ttf'; +import interTtf from '@fedimint/ui/assets/fonts/Inter-Variable.ttf'; +import { ColorModeScript } from '@chakra-ui/react'; + +import { i18nProvider } from '@fedimint/utils'; +import { languages } from './languages'; +import { AppContextProvider } from './context/AppContext'; +import { HomePage } from './home/HomePage'; +import { GuardianContextProvider } from './context/guardian/GuardianContext'; +import { GatewayContextProvider } from './context/gateway/GatewayContext'; + +i18nProvider(languages); + +const App = () => { + return ( + + + } /> + + + + } + /> + + + + } + /> + + + ); +}; + +const root = ReactDOM.createRoot( + document.getElementById('root') as HTMLElement +); + +root.render( + + + + + + + + + + + +); diff --git a/apps/router/src/languages/ca.json b/apps/router/src/languages/ca.json new file mode 100644 index 000000000..9708f1723 --- /dev/null +++ b/apps/router/src/languages/ca.json @@ -0,0 +1,486 @@ +{ + "common": { + "bitcoin": "Bitcoin", + "next": "Següent", + "back": "Enrere", + "unknown": "Desconegut", + "remove": "Eliminar", + "copy": "Còpia", + "copied": "Copiat!", + "cancel": "Cancel·la", + "review": "Revisió", + "approvals": "Aprovacions", + "approve": "Aprovar", + "threshold": "Llindar", + "confirm": "Confirma", + "you": "Tu", + "close": "Tancar", + "save": "Desa", + "continue": "Continua", + "submit": "Enviar", + "address": "Adreça", + "amount": "Quantitat", + "btc": "BTC", + "error": "Error", + "sats": "sats", + "msats": "msats", + "uri": "URI", + "view-on-mempool": "Veure a Mempool", + "ecash": "Efectiu digital" + }, + "notConfigured": { + "title": "No configurat", + "description": "Introduïu l'CONFIG_API_URL del servidor guardià de Fedimint al qual voleu apuntar." + }, + "connect-guardians": { + "invite-guardians": "Convida Seguidors", + "invite-guardians-help": "Comparteix aquest enllaç amb els altres Guardians", + "approve": "Aprovar", + "approved": "Aprovat", + "pending": "Pendent", + "not-joined": "No unit", + "waiting-for-guardian": "Esperant el guardià", + "table-title": "Guardians de la Federació", + "table-description": "Els guardians seran confirmats aquí un cop confirmades les configuracions de la Federació.", + "meta-field-key": "Camp de metadades - {{clau}}" + }, + "federation-dashboard": { + "invite-members": "Convida membres o autentica't com a tutor", + "invite-members-prompt": "Comparteix això per convidar membres a unir-se a la federació", + "fed-info": { + "label": "Informació de la Federació", + "your-status-label": "Estat", + "block-count-label": "Alçada del Bloc de Consens", + "api-version-label": "Versió de l'API", + "consensus-version-label": "Versió de consens", + "peer-id-label": "ID del company", + "session-info": { + "session-height": "Alçada de la Sessió", + "latest-session": "Última sessió" + } + }, + "balance": { + "label": "Balanç general" + }, + "bitcoin-node": { + "label": "Node de Bitcoin", + "url-label": "URL", + "network-label": "Xarxa" + }, + "guardians": { + "label": "Altres Guardians", + "id-name-label": "ID: Nom", + "status-label": "Estat de la connexió", + "health-label": "Salut", + "health-issue": "Problema", + "health-good": "Bo", + "last-contribution-label": "Última Contribució de la Sessió", + "api-url-label": "URL de l'API", + "fetching-announcement": "Recuperant anuncis..." + }, + "gateways": { + "label": "Passarel·les de Llampec", + "node-id-label": "ID del node de llamps", + "gateway-id-label": "ID de la passarel·la", + "fee-label": "Quota de passarel·la", + "view-on-site": "Veure a {{site}}", + "no-gateways-info-title": "Encara no hi ha passarel·les connectades!", + "no-gateways-info-description": "Els operadors de nodes Lightning poden connectar-se a la vostra federació per proporcionar interoperabilitat de la xarxa Lightning. Un cop connectats, apareixeran aquí." + }, + "api-announcements": { + "label": "Anuncis d'API", + "guardian": "Tutor", + "api-url": "URL de l'API", + "revision": "Revisió" + }, + "config": { + "label": "Configuració de la Federació", + "view-config": "Veure Configuració", + "missing-meta-module": "No és possible editar els camps Meta. El mòdul Meta no està disponible per a aquesta federació.", + "manage-meta": { + "label": "Gestiona Meta", + "cancel-button": "Cancel·la", + "confirm-modal": { + "title": "Confirma l'aprovació", + "description": "La vostra aprovació arribarà al llindar per adoptar aquest canvi meta. El vostre nou meta es veurà així:" + }, + "consensus-meta-label": "Metadades actuals en consens", + "revoke-button": "Revocar", + "no-consensus-meta-message": "no hi ha metadades en consens", + "proposed-meta-label": "Propostes Meta", + "propose-meta": "Proposa Meta", + "propose-new-meta-button": "Proposa Nova Meta", + "proposal-approved": "Heu aprovat aquesta proposta.", + "no-submitted-meta-message": "no hi ha edicions meta per revisar", + "edit-meta-label": "Edita meta", + "edit-consensus-meta-button": "Edita Consens Meta", + "submit-meta-proposal": "Enviar proposta Meta", + "peer-approvals": "Aprovacions dels companys", + "actions": "Accions", + "revision": "Revisió", + "setup-meta-title": "Configurant un Meta per a la vostra Federació", + "setup-meta-description": "Fedimint pot proporcionar informació addicional als clients en forma de camps meta: parells de claus-valors amb informació arbitrària que potser voldríeu compartir amb els clients. Encara que aquests camps meta no són interpretats per Fedimint, són rellevants per al consens, és a dir, no poden diferir entre els membres de la federació. D'aquesta manera, els clients poden confiar en la seva correcció.", + "propose-updates": "Com a guardià de fedimint, pots proposar actualitzacions a la meta que seran acceptades pels altres guardians. Un cop l'actualització és acceptada per un llindar de guardians, es adoptarà com a nova meta de consens per a la federació.", + "core-meta-fields": "Els següents camps meta s'han definit com a part del protocol principal de Fedimint i són útils per incloure en el meta de la vostra federació:", + "meta-field-expiry": "Una marca de temps Unix després de la qual la federació es tancarà.", + "meta-field-name": "El nom llegible per humans de la federació", + "meta-field-icon": "Una URL a una icona de logotip per a la federació", + "meta-field-welcome": "Un missatge de benvinguda per als nous usuaris que s'uneixen a la federació.", + "meta-field-gateways": "Una llista d'identificadors de passarel·la aprovats per la federació", + "your-own-fields": "També podeu afegir els vostres propis camps meta arbitraris a la proposta. Aquests s'afegiran al meta de tots els clients que es connectin a la vostra federació i es poden utilitzar per a qualsevol propòsit que desitgeu.", + "meta-effect-add": "Afegir", + "meta-effect-modify": "Modifica", + "meta-effect-unchanged": "Sense canvis", + "proposals": "Propostes" + } + }, + "modal": { + "client-connect": "Connecta un Client" + }, + "danger-zone": { + "danger-zone-label": "Zona de Perill", + "cancel": "Cancel·la", + "danger-zone-description": "Utilitzeu amb precaució!", + "guardian-warning-message": "ADVERTÈNCIA: No comparteixis aquest codi amb ningú. Qualsevol persona amb aquest codi pot autenticar-se com a Guardià. Assegura't que estàs en un lloc privat i que ningú està mirant la teva pantalla.", + "guardian-acknowledge": "Reconeix i revela el codi", + "acknowledge-and-download": "Reconeix i procedeix", + "guardian-authenticate": "Autentica't com a Tutor", + "guardian-connect-warning": "NO COMPARTIU AIXÒ", + "backup": { + "label": "Còpia de seguretat", + "title": "Descarrega la còpia de seguretat", + "warning-title": "Advertència", + "warning-text": "La còpia de seguretat conté claus privades i material secret per al guardià de la federació i s'ha de mantenir segura. La recuperació utilitzant aquesta còpia de seguretat requereix la vostra contrasenya d'administrador!", + "cancelButton": "Cancel·la", + "acknowledgeButton": "Reconeix i descarrega" + }, + "sign-api-announcement": { + "label": "Anunci de l'API de signatura", + "title": "Anunci de l'API de Signatura", + "description": "Signa un nou anunci d'API.", + "current-api-url": "La URL de la vostra API de la configuració local", + "announced-api-url": "La URL de la vostra API dels Anuncis de la Federació", + "urls-match": "La URL de la vostra API actual coincideix amb la URL de la vostra API anunciada.", + "urls-mismatch": "Heu canviat l'URL de l'API a la vostra configuració local i cal que difongueu un nou anunci d'API.", + "sign-button": "Anunci de la nova API", + "signing-in-progress": "Inici de sessió en curs...", + "sign-tooltip": "Signeu l'anunci de l'API per anunciar la vostra URL de l'API a la federació." + }, + "schedule-shutdown": { + "label": "Programa l'aturada", + "title": "Programa l'apagada", + "description": "Planifiqueu que el vostre node de guardian es tanqui després d'una alçada de sessió específica per a una actualització coordinada dels vostres binaris fedimintd.", + "current-session": "Sessió actual", + "session-to-shutdown": "Sessió per tancar a", + "confirm-shutdown": "Confirma l'aturada", + "session-to-shutdown-helper": "Introduïu l'alçada de la sessió en què voleu tancar el vostre node de guardian." + } + } + }, + "login": { + "title": "Benvingut de nou!", + "subtitle": "Si us plau, introdueix la teva contrasenya.", + "password": "Contrasenya", + "submit": "Enviar" + }, + "role-selector": { + "disclaimer-title": "Fedimint és un programari beta.", + "disclaimer-text": "Si us plau, informeu de qualsevol problema a https://github.com/fedimint/fedimint/issues", + "leader": { + "label": "Configura el Líder", + "description": "Introduïu la configuració que altres Guardians aproven. Un Guardian actua com a Líder de Configuració." + }, + "follower": { + "label": "Seguidor", + "description": "Una vegada que un Líder de Configuració estableix les configuracions, altres Guardians trien aquesta opció per aprovar la configuració i crear la Federació." + }, + "solo": { + "label": "Només", + "description": "Operi Fedimint com a Guardian en solitari sense consens, tolerància a fallades, còpies de seguretat federades o altres avantatges de resistència de Fedimint. Procediu amb precaució, no està destinat a l'ús de producció." + }, + "warning-modal": { + "title": "Tothom està a punt?", + "description": "Sortir de la cerimònia de configuració pot provocar que la configuració falli i requereixi que reinicieu el vostre guardià. Assegureu-vos que tothom està preparat per executar la configuració completa abans de continuar!" + } + }, + "run-dkg": { + "error-config": "No s'ha pogut executar la generació de claus distribuïda. S'ha de reiniciar la configuració de la federació.", + "error-default": "No estàs preparat per a DKG, el teu estat actual és", + "error-header": "Alguna cosa ha anat malament.", + "waiting-header": "Esperant companys", + "generating-header": "Generant codis" + }, + "set-config": { + "bft-explanation-title": "Tolerància a Fallades Bizantines de la vostra Federació", + "bft-explanation": "Una Federació de Guardians {{total}} crea un Llindar {{honest}}/{{total}}.", + "bft-faulty": "La vostra Federació podrà tolerar {{faulty}} Guardians defectuosos, fora de línia o maliciosos sense afectar les operacions de la Federació.", + "guardian-name": "Nom del tutor", + "guardian-name-help": "Aquest nom aleatori es mostrarà a altres Guardians durant la configuració.", + "acknowledge-backed-up": "Jo, {{guardianName}} (el teu nom de tutor), prometo que he fet una còpia de seguretat i he assegurat la meva contrasenya:", + "admin-password": "Contrasenya d'administrador", + "admin-password-generate": "Genera", + "admin-password-set": "Feu clic a 'Generar' per crear una contrasenya segura. Podeu modificar-la, però aquesta contrasenya ha de ser segura i tenir una còpia de seguretat!", + "admin-password-help": "Feu una còpia de seguretat d'aquesta contrasenya i guardeu-la en un lloc segur! No podeu recuperar aquesta contrasenya!", + "admin-password-backup": "Estic utilitzant una contrasenya forta i l'he fet una còpia de seguretat. (No pots recuperar aquesta contrasenya!)", + "confirm-and-backup-password": "Confirma i Respalda la Contrasenya", + "confirm-password": "Confirma la contrasenya", + "error-password-mismatch": "Les contrasenyes no coincideixen", + "join-federation": "Uniu-vos a l'enllaç de la Federació", + "join-federation-help": "Demaneu a la persona que va crear la Federació un enllaç i enganxeu-lo aquí.", + "basic-settings": "Conceptes bàsics", + "federation-settings": "Configuració de la federació", + "federation-name": "Nom de la federació", + "guardian-number": "Nombre de guardians", + "guardian-number-help": "Les federacions requereixen un mínim de 4 guardians. Això no es pot canviar més tard.", + "bitcoin-settings": "Configuració de Bitcoin", + "block-confirmations": "Confirmacions addicionals de blocs", + "block-confirmations-help": "Els Guardians de Fedimint segueixen la punta de la cadena de blocs amb diverses confirmacions per evitar la reorganització de blocs.", + "block-confirmations-help-mainnet": "L'execució a Mainnet requereix almenys 5 confirmacions addicionals.", + "block-confirmations-warning": "Executar Fedimint amb menys de 5 confirmacions de bloc addicionals és extremadament arriscat! Fedimint NO pot gestionar les reorganitzacions de blockchain.", + "bitcoin-network": "Xarxa Bitcoin", + "select-network": "Seleccioneu una xarxa", + "bitcoin-rpc-kind": "Tipus Bitcoin RPC", + "set-rpc-help": "Font de dades de bloc de bitcoin per al vostre node de guardià", + "bitcoin-rpc": "URL de RPC de Bitcoin", + "read-from-env": "(Detectat a partir de variables d'entorn)", + "error-valid-number": "Si us plau, introdueix un número vàlid.", + "error-valid-min": "Si us plau, introduïu un número d'au menys {{min}}.", + "error-valid-max": "Si us plau, introduïu un número com a màxim de {{max}}.", + "error-valid-min-max": "Si us plau, introdueixi un número entre {{min}} i {{max}}.", + "error-guardian-name-mismatch": "El nom del tutor no coincideix", + "meta-fields": "Camps de metadades", + "meta-fields-description": "Consulteu la documentació per a més informació.", + "meta-fields-key": "Clau Meta", + "meta-fields-value": "Valor", + "meta-fields-effect": "Efecte", + "meta-fields-add-another": "Afegeix un altre", + "meta-fields-title": "La vostra proposta Meta:", + "network": "Xarxa", + "password-warning-title": "Feu una còpia de seguretat de la vostra contrasenya!", + "password-warning": "Heu de fer una còpia de seguretat de la vostra contrasenya i guardar-la en un lloc segur. Aquesta contrasenya és necessària per accedir al vostre tauler de control de guardià. NO la podeu recuperar si la perdeu!" + }, + "setup": { + "warning": { + "title": "No surti ni actualitzis durant la configuració!", + "description": "Sortir durant la configuració pot provocar que aquesta falli i hauràs de fer un nou inici." + }, + "common": { + "restart-setup": "Reinicia la configuració", + "restart-setup-alert": "El Líder de Configuració ha reiniciat la Cerimònia de Configuració. Si us plau, feu clic a \"Reinicia\" a continuació per continuar.", + "confirm-restart-setup": "Esteu segurs que voleu reiniciar la Cerimònia de Configuració?", + "confirm-restart-setup-alert": "En fer clic a \"Reiniciar\" es reiniciarà la cerimònia per a tots els Guardians." + }, + "progress": { + "tos": { + "title": "Termes del servei" + }, + "start": { + "title": "Benvingut, Guardià!", + "subtitle": "Anem a configurar la vostra federació.", + "step": "Detalls de la federació" + }, + "set-config": { + "title": "Hem de configurar algunes configuracions per a la vostra Federació.", + "title-solo": "Hem de configurar algunes configuracions per a la vostra Federació Solo.", + "subtitle-leader": "Els vostres seguidors de la Federació confirmaran aquesta informació al seu final.", + "subtitle-solo": "Executar una Federació en Solitari perd molts dels avantatges de Fedimint. No tindràs consens de tolerància a fallades a un guardià que estigui fora de línia i no podràs fer còpies de seguretat federades. Procedeix amb precaució, no es recomana per a ús en producció o ús amb Bitcoin de la xarxa principal.", + "subtitle-follower": "El vostre Líder de la Federació establirà els detalls principals de la Federació. Els confirmareu aviat.", + "step": "Detalls de la federació" + }, + "connect-guardians": { + "title-leader": "Convidi els teus Guardians", + "title-follower": "Confirma la teva informació de Federació", + "subtitle-leader": "Comparteix l'enllaç amb els altres Guardians perquè tothom estigui a la mateixa pàgina. Un cop tots els Guardians s'hi hagin unit, passaràs automàticament al següent pas.", + "subtitle-follower": "Assegureu-vos que la informació d'aquí sembla correcta i que els Guardians de la Federació són correctes. Feu clic al botó Aprova quan estigueu segurs que sembla bé.", + "step-leader": "Convidar Guardians", + "step-follower": "Confirma la informació" + }, + "run-dkg": { + "title": "Èxit!", + "subtitle": "Tots els Guardians han validat els detalls de la configuració de la federació. Executant alguns números..." + }, + "verify-guardians": { + "title": "Verifiqueu els vostres Guardians", + "subtitle": "Demaneu a cada Guardià el seu codi de verificació i enganxeu-los a continuació per comprovar la validesa. Ja quasi hem acabat!", + "step": "Verifiqueu els tutors", + "leader-confirm-done": "Confirmeu que tots els Guardians seguidors hagin fet clic a \"Següent\" i vist els seus taulers de control de guardian abans de continuar.", + "leader-confirm-done-emphasis": "En fer clic a \"Continuar\" es completarà la cerimònia de configuració." + }, + "setup-complete": { + "step": "Fet!" + }, + "error": { + "title": "Pas desconegut", + "subtitle": "Com has arribat aquí?!" + } + } + }, + "setup-complete": { + "header": "🎉 🎉 🎉", + "congratulations": "Felicitacions", + "leader-message": "Tots els codis de verificació dels Guardians s'han verificat.", + "follower-message": "Ja has acabat! Deixa que els altres Guardians sàpiguen que estàs corrent!", + "continue": "Continua" + }, + "terms-of-service": { + "agree-and-continue": "D'acord i continua" + }, + "verify-guardians": { + "verified": "Verificat", + "verified-placeholder": "Enganxa el codi aquí", + "error": "Alguna cosa ha anat malament.", + "error-peer-id": "No es pot determinar quin company ets. Si us plau, actualitza i torna-ho a provar.", + "verification-code": "El vostre codi de verificació ({{peerName}})", + "verification-code-help": "Compartiu aquest codi amb altres guardians", + "table-title": "Codi de verificació del guardià", + "table-description": "Introduïu els codis de verificació de cada Guardià a continuació.", + "table-column-name": "Nom", + "table-column-status": "Estat", + "table-column-hash-input": "Enganxa el codi de verificació", + "wait-all-guardians-verification": "Esperant que tots els Guardians verifiquin els seus codis", + "all-guardians-verified": "Tots els Guardians han verificat els seus codis", + "starting-consensus": "Iniciant consens..." + }, + "footer": { + "docs-section-header": "Documents", + "community-section-header": "Comunitat", + "contribute-section-header": "Contribueix", + "getting-started-link-text": "Començant", + "faq-link-text": "Preguntes Freqüents", + "blog-link-text": "Bloc", + "discord-link-text": "Discord", + "twitter-link-text": "Twitter", + "github-link-text": "GitHub" + }, + "admin": { + "fetch-info-modal-text": "Comprovant detalls de federació..." + }, + "balance-card": { + "card_header": "Saldo eCash", + "sentence": "Denominat en Sats", + "your-balance": "El vostre saldo d'eCash en aquesta federació:" + }, + "connect-federation": { + "connect": "Connecta 🚀", + "connect-federation-button": "Afegir Federació", + "connection-string-placeholder": "Enganxa el codi d'invitació a la federació", + "heading": "Connecta a una federació utilitzant un codi d'invitació", + "information-bar-text": "El nombre de federacions a les quals pots connectar-te està limitat a una. La connexió a múltiples federacions es suportarà aviat.", + "label": "Cadena de connexió:", + "progress-modal-text": "Connectant a la federació...", + "sub-heading": "El codi d'invitació és una cadena llarga que comença amb 'fed1", + "error-message": "Error en connectar a la federació: {{error}}" + }, + "wallet": { + "title": "Cartera", + "ecash": "Ecash", + "lightning": "Llampec", + "onchain": "En cadena", + "total": "Total", + "balance": "Equilibri", + "address": "Adreça", + "invoice": "Factura", + "receive": "Rebre", + "send": "Enviar", + "create-address": "Crear adreça", + "to-federation": "A Federació", + "from-federation": "Des de la Federació", + "sent": "Enviat", + "sent-amount": "Enviat {{amount}}", + "to-address": "Per a l'adreça", + "txid": "ID de la transacció", + "claimed-note": "Nota Reclamada", + "claimed-amount": "Quantitat Reclamada" + }, + "wallet-modal": { + "title": "Accions de la cartera", + "receive": { + "ecash-instructions": "Enganxeu la vostra nota d'efectiu electrònic aquí.", + "paste-ecash-placeholder": "Enganxa la nota d'efectiu electrònic aquí", + "redeem": "Redimir", + "paste-invoice": "Enganxa la factura aquí", + "enter-amount": "Introduïu la quantitat en {{unit}}", + "lightning-instructions": "Introduïu una quantitat en sats per crear una factura de Lightning", + "create-peg-in-address": "Crea l'adreça Peg-in", + "create-lightning-invoice": "Crea una factura de Lightning", + "paste-ecash-button": "Enganxa la nota d'efectiu electrònic", + "peg-in-instructions": "Envia Bitcoin a aquesta adreça per ancorar al teu saldo Ecash de {{federationName}}", + "ecash-claimed-success": "Ecash reclamat amb èxit!", + "address-error": "Error en crear l'adreça: {{error}}" + }, + "send": { + "submit": "Enviar", + "to-onchain-address": "A l'adreça Onchain", + "address-placeholder": "As an AI developed by OpenAI, I need to inform you that the text you provided \"bc1p...\" is not recognizable in any language, therefore it can't be translated into Catalan or any other language. It seems like it might be a part of a Bitcoin address or some other kind of code. Please provide a valid sentence or phrase for translation.", + "peg-out-to-onchain": "Peg Out Ecash a Onchain", + "peg-out-success": "Peg Out TX Enviat!", + "create-ecash": "Crear nota Ecash", + "ecash-created": "S'ha retirat una nota d'ecash de {{amount}} del teu saldo de {{federationName}}. Envia-la al destinatari per reclamar-la.", + "ecash-error": "Error en crear la nota d'efectiu: {{error}}" + } + }, + "federation-card": { + "table-title": "Federacions", + "id": "ID", + "name": "Nom", + "balance": "Equilibri", + "actions": "Accions", + "receive": "Rebre", + "send": "Envia", + "default-federation-name": "Federació", + "view-link-on": "Veure a {{host}}", + "leave-fed-error": "No podeu deixar la federació amb sats al vostre saldo. Si us plau, retireu els vostres sats primer.", + "leave-fed-modal-title": "Deixar la Federació", + "leave-fed-modal-text": "Esteu segur que voleu desconnectar-vos de", + "view-config": "Veure Configuració", + "config-for": "Configuració per a {{federationId}}" + }, + "header": { + "active": "Actiu", + "all": "Tots", + "archived": "Arxivat", + "ascending": "Ascendent", + "connect": "Connecta Federació", + "date-created": "Data de creació", + "descending": "Descendent", + "filter": "Filtre", + "sort": "Ordena", + "title": "Tauler de Control de la Passarel·la de Llamps" + }, + "info-card": { + "card-header": "Informació del Node de Llampec", + "node-id": "ID del node", + "alias": "Àlies", + "mode": "Mode", + "pubkey": "Clau pública", + "network": "Xarxa", + "block-height": "Alçada del bloc", + "synced-to-chain": "Sincronitzat a la Cadena" + }, + "withdraw-card": { + "address-label": "La teva adreça:", + "address-placeholder": "Introduïu la vostra adreça btc", + "amount-label": "Quantitat (sats):", + "amount-placeholder": "Introdueixi la quantitat en sats", + "card-header": "Retira Bitcoin", + "close": "Tancar", + "confirm-withdraw": "Confirma Retirada", + "error": "Error", + "error-address": "La quantitat o l'adreça no poden estar buides.", + "error-amount": "La quantitat no pot estar buida o ser igual a zero.", + "error-request": "No s'ha pogut sol·licitar la retirada", + "request-from": "Sol·licitud de retirada de", + "requested-withdrawal": "Sol·licitud de retirada", + "to": "a", + "total_bitcoin": "Total Bitcoin:", + "transaction-sent": "Transacció enviada!", + "view": "Veure", + "view-it-on": "Vegeu-ho a", + "withdraw": "Retirar", + "withdraw-all": "Retira-ho tot", + "withdrawal-created": "Retirada creada.", + "withdrawal-created-description": "Si us plau, comprova el teu historial de transaccions.", + "withdrawal-history": "Historial de retirada", + "your-transaction": "La vostra ID de transacció:" + } +} diff --git a/apps/router/src/languages/de.json b/apps/router/src/languages/de.json new file mode 100644 index 000000000..d83806d6a --- /dev/null +++ b/apps/router/src/languages/de.json @@ -0,0 +1,486 @@ +{ + "common": { + "bitcoin": "Bitcoin", + "next": "Nächste", + "back": "Zurück", + "unknown": "Unbekannt", + "remove": "Entfernen", + "copy": "Kopieren", + "copied": "Kopiert!", + "cancel": "Abbrechen", + "review": "Rezension", + "approvals": "Genehmigungen", + "approve": "Genehmigen", + "threshold": "Schwelle", + "confirm": "Bestätigen", + "you": "Du", + "close": "Schließen", + "save": "Speichern", + "continue": "Fortsetzen", + "submit": "Einreichen", + "address": "Adresse", + "amount": "Menge", + "btc": "BTC", + "error": "Fehler", + "sats": "Sats", + "msats": "msats", + "uri": "URI", + "view-on-mempool": "Ansicht auf Mempool", + "ecash": "Ecash" + }, + "notConfigured": { + "title": "Nicht konfiguriert", + "description": "Bitte geben Sie die CONFIG_API_URL des Fedimint Guardian-Servers ein, auf den Sie verweisen möchten." + }, + "connect-guardians": { + "invite-guardians": "Follower einladen", + "invite-guardians-help": "Teilen Sie diesen Link mit den anderen Wächtern", + "approve": "Genehmigen", + "approved": "Genehmigt", + "pending": "Ausstehend", + "not-joined": "Nicht beigetreten", + "waiting-for-guardian": "Warten auf Vormund", + "table-title": "Bundeswächter", + "table-description": "Wächter werden hier bestätigt, sobald sie die Föderationseinstellungen bestätigen.", + "meta-field-key": "Metafeld - {{key}}" + }, + "federation-dashboard": { + "invite-members": "Laden Sie Mitglieder ein oder authentifizieren Sie sich als Vormund", + "invite-members-prompt": "Teilen Sie dies, um Mitglieder einzuladen, dem Verband beizutreten.", + "fed-info": { + "label": "Föderationsinfo", + "your-status-label": "Status", + "block-count-label": "Konsens-Blockhöhe", + "api-version-label": "API-Version", + "consensus-version-label": "Konsensversion", + "peer-id-label": "Peer-ID", + "session-info": { + "session-height": "Sitzungshöhe", + "latest-session": "Letzte Sitzung" + } + }, + "balance": { + "label": "Bilanz" + }, + "bitcoin-node": { + "label": "Bitcoin-Knotenpunkt", + "url-label": "URL", + "network-label": "Netzwerk" + }, + "guardians": { + "label": "Andere Wächter", + "id-name-label": "ID: Name", + "status-label": "Verbindungsstatus", + "health-label": "Gesundheit", + "health-issue": "Ausgabe", + "health-good": "Gut", + "last-contribution-label": "Letzte Sitzungsbeitrag", + "api-url-label": "API-URL", + "fetching-announcement": "Ankündigung wird abgerufen..." + }, + "gateways": { + "label": "Blitz-Gateways", + "node-id-label": "Blitz-Knoten-ID", + "gateway-id-label": "Gateway-ID", + "fee-label": "Gateway-Gebühr", + "view-on-site": "Ansicht auf {{site}}", + "no-gateways-info-title": "Noch keine verbundenen Gateways!", + "no-gateways-info-description": "Blitz-Knotenbetreiber können sich mit Ihrer Föderation verbinden, um die Interoperabilität des Lightning-Netzwerks zu gewährleisten. Sobald sie verbunden sind, werden sie hier erscheinen." + }, + "api-announcements": { + "label": "API-Ankündigungen", + "guardian": "Wächter", + "api-url": "API-URL", + "revision": "Überarbeitung" + }, + "config": { + "label": "Föderationskonfiguration", + "view-config": "Konfiguration anzeigen", + "missing-meta-module": "Das Bearbeiten von Meta-Feldern ist nicht möglich. Das Meta-Modul ist für diesen Verband nicht verfügbar.", + "manage-meta": { + "label": "Meta verwalten", + "cancel-button": "Stornieren", + "confirm-modal": { + "title": "Genehmigung bestätigen", + "description": "Ihre Zustimmung wird die Schwelle erreichen, um diese Meta-Änderung zu übernehmen. Ihr neues Meta wird so aussehen:" + }, + "consensus-meta-label": "Aktuelle Meta im Konsens", + "revoke-button": "Widerrufen", + "no-consensus-meta-message": "Es gibt keine Meta im Konsens", + "proposed-meta-label": "Meta-Vorschläge", + "propose-meta": "Meta vorschlagen", + "propose-new-meta-button": "Neuen Meta vorschlagen", + "proposal-approved": "Sie haben diesen Vorschlag genehmigt.", + "no-submitted-meta-message": "Es gibt keine Meta-Bearbeitungen zur Überprüfung.", + "edit-meta-label": "Meta bearbeiten", + "edit-consensus-meta-button": "Bearbeiten Konsens Meta", + "submit-meta-proposal": "Meta-Vorschlag einreichen", + "peer-approvals": "Peer-Bestätigungen", + "actions": "Aktionen", + "revision": "Überarbeitung", + "setup-meta-title": "Einrichten einer Meta für Ihren Verband", + "setup-meta-description": "Fedimint kann Kunden zusätzliche Informationen in Form von Metafeldern liefern: Schlüssel-Wert-Paare mit beliebigen Informationen, die Sie möglicherweise mit Kunden teilen möchten. Obwohl diese Metafelder von Fedimint nicht interpretiert werden, sind sie konsensrelevant, d.h. sie können sich nicht zwischen Mitgliedern der Föderation unterscheiden. Auf diese Weise können sich Kunden auf deren Korrektheit verlassen.", + "propose-updates": "Als Fedimint-Wächter können Sie Aktualisierungen des Metas vorschlagen, die von den anderen Wächtern akzeptiert werden. Sobald die Aktualisierung von einer Schwelle von Wächtern akzeptiert wird, wird sie als neues Konsens-Meta für den Verband übernommen.", + "core-meta-fields": "Die folgenden Metafelder wurden als Teil des Kern-Fedimint-Protokolls definiert und sind nützlich, um sie in das Meta Ihrer Föderation einzubeziehen:", + "meta-field-expiry": "Ein Unix-Zeitstempel, nach dem der Verband heruntergefahren wird.", + "meta-field-name": "Der menschenlesbare Name des Bundes", + "meta-field-icon": "Eine URL zu einem Logo-Symbol für den Verband", + "meta-field-welcome": "Eine Willkommensnachricht für neue Benutzer, die dem Verband beitreten", + "meta-field-gateways": "Eine Liste von Gateway-Identifikatoren, die von der Föderation geprüft wurden", + "your-own-fields": "Sie können auch Ihre eigenen willkürlichen Meta-Felder zum Vorschlag hinzufügen. Diese werden zu den Meta-Daten aller Clients hinzugefügt, die sich mit Ihrer Föderation verbinden, und können für jeden Zweck verwendet werden, den Sie möchten.", + "meta-effect-add": "Hinzufügen", + "meta-effect-modify": "Ändern", + "meta-effect-unchanged": "Unverändert", + "proposals": "Vorschläge" + } + }, + "modal": { + "client-connect": "Verbinden Sie einen Client" + }, + "danger-zone": { + "danger-zone-label": "Gefahrenzone", + "cancel": "Stornieren", + "danger-zone-description": "Mit Vorsicht verwenden!", + "guardian-warning-message": "WARNUNG: Teilen Sie diesen Code nicht mit jemandem. Jeder mit diesem Code kann sich als Wächter authentifizieren. Stellen Sie sicher, dass Sie sich an einem privaten Ort befinden und niemand Ihren Bildschirm beobachtet.", + "guardian-acknowledge": "Anerkennen und Code offenlegen", + "acknowledge-and-download": "Anerkennen & Fortfahren", + "guardian-authenticate": "Authentifizieren Sie sich als Vormund", + "guardian-connect-warning": "TEILEN SIE DIES NICHT", + "backup": { + "label": "Sicherung", + "title": "Backup herunterladen", + "warning-title": "Warnung", + "warning-text": "Die Sicherung enthält private Schlüssel und geheimes Material für den Föderationswächter und muss sicher aufbewahrt werden. Die Wiederherstellung mit dieser Sicherung erfordert Ihr Admin-Passwort!", + "cancelButton": "Stornieren", + "acknowledgeButton": "Bestätigen & Herunterladen" + }, + "sign-api-announcement": { + "label": "Ankündigung der Sign API", + "title": "Ankündigung der Sign API", + "description": "Unterzeichnen Sie eine neue API-Ankündigung.", + "current-api-url": "Ihre API-URL aus der lokalen Konfiguration", + "announced-api-url": "Ihre API-URL von Federation-Ankündigungen", + "urls-match": "Ihre aktuelle API-URL stimmt mit Ihrer angekündigten API-URL überein.", + "urls-mismatch": "Sie haben die API-URL in Ihrer lokalen Konfiguration geändert und müssen eine neue API-Ankündigung senden.", + "sign-button": "Ankündigung für neue API unterschreiben", + "signing-in-progress": "Anmeldung läuft...", + "sign-tooltip": "Unterschreiben Sie die API-Ankündigung, um Ihre API-URL dem Verbund mitzuteilen." + }, + "schedule-shutdown": { + "label": "Herunterfahren planen", + "title": "Herunterfahren planen", + "description": "Planen Sie Ihren Wächterknoten so ein, dass er nach einer bestimmten Sitzungshöhe herunterfährt, um ein koordiniertes Upgrade Ihrer Fedimintd-Binärdateien durchzuführen.", + "current-session": "Aktuelle Sitzung", + "session-to-shutdown": "Sitzung zum Herunterfahren um", + "confirm-shutdown": "Herunterfahren bestätigen", + "session-to-shutdown-helper": "Geben Sie die Sitzungshöhe ein, bei der Sie Ihren Guardian-Knoten herunterfahren möchten." + } + } + }, + "login": { + "title": "Willkommen zurück!", + "subtitle": "Bitte geben Sie Ihr Passwort ein.", + "password": "Passwort", + "submit": "Einreichen" + }, + "role-selector": { + "disclaimer-title": "Fedimint ist Beta-Software", + "disclaimer-text": "Bitte melden Sie Probleme unter https://github.com/fedimint/fedimint/issues", + "leader": { + "label": "Setup-Leiter", + "description": "Geben Sie Konfigurationseinstellungen ein, die andere Wächter genehmigen. Ein Wächter fungiert als Einrichtungsleiter." + }, + "follower": { + "label": "Anhänger", + "description": "Sobald ein Einrichtungsleiter die Konfigurationen festlegt, wählen andere Wächter diese Option, um die Einstellungen zu genehmigen und die Föderation zu erstellen." + }, + "solo": { + "label": "Solo", + "description": "Betreiben Sie Fedimint als Solo-Guardian ohne Konsens, Fehlertoleranz, föderierte Backups oder andere Resilienzvorteile von Fedimint. Vorsicht walten lassen, nicht für den Produktionsgebrauch vorgesehen." + }, + "warning-modal": { + "title": "Ist jeder bereit?", + "description": "Das Verlassen der Einrichtungszeremonie kann dazu führen, dass die Einrichtung fehlschlägt und Sie Ihren Wächter neu starten müssen. Stellen Sie sicher, dass jeder bereit ist, die vollständige Einrichtung durchzuführen, bevor Sie fortfahren!" + } + }, + "run-dkg": { + "error-config": "Fehler beim Ausführen der verteilten Schlüsselgenerierung. Der Verbundsetup muss neu gestartet werden.", + "error-default": "Nicht bereit für DKG, Ihr aktueller Status ist", + "error-header": "Etwas ist schief gelaufen.", + "waiting-header": "Warten auf Gleichgesinnte", + "generating-header": "Generierung von Codes" + }, + "set-config": { + "bft-explanation-title": "Byzantinische Fehler-Toleranz Ihrer Föderation", + "bft-explanation": "Eine {{total}} Guardian Federation erstellt eine {{ehrliche}}/{{total}} Schwelle.", + "bft-faulty": "Ihr Verband wird in der Lage sein, {{fehlerhafte}} fehlerhafte, offline oder bösartige Wächter zu tolerieren, ohne die Operationen des Verbands zu beeinträchtigen.", + "guardian-name": "Name des Vormunds", + "guardian-name-help": "Dieser zufällige Name wird anderen Wächtern während der Einrichtung angezeigt.", + "acknowledge-backed-up": "Ich, {{guardianName}} (Ihr Schutzpatron Name), verspreche, dass ich mein Passwort gesichert und gespeichert habe:", + "admin-password": "Admin-Passwort", + "admin-password-generate": "Erzeugen", + "admin-password-set": "Klicken Sie auf 'Generieren', um ein sicheres Passwort zu erstellen. Sie können es ändern, aber dieses Passwort muss sicher sein und gesichert werden!", + "admin-password-help": "Sichern Sie dieses Passwort und bewahren Sie es sicher auf! Sie können dieses Passwort nicht wiederherstellen!", + "admin-password-backup": "Ich verwende ein starkes Passwort und habe es gesichert. (Sie können dieses Passwort nicht wiederherstellen!)", + "confirm-and-backup-password": "Passwort bestätigen und sichern", + "confirm-password": "Passwort bestätigen", + "error-password-mismatch": "Passwörter stimmen nicht überein", + "join-federation": "Beitrittslink zur Föderation", + "join-federation-help": "Bitten Sie die Person, die die Föderation erstellt hat, um einen Link und fügen Sie ihn hier ein.", + "basic-settings": "Grundlagen", + "federation-settings": "Verbandseinstellungen", + "federation-name": "Bundesname", + "guardian-number": "Anzahl der Vormünder", + "guardian-number-help": "Verbände erfordern mindestens 4 Wächter. Dies kann später nicht geändert werden.", + "bitcoin-settings": "Bitcoin-Einstellungen", + "block-confirmations": "Zusätzliche Blockbestätigungen", + "block-confirmations-help": "Fedimint Guardians verfolgen die Spitze der Blockchain um mehrere Bestätigungen, um Block-Reorganisationen zu vermeiden.", + "block-confirmations-help-mainnet": "Das Laufen auf Mainnet erfordert mindestens 5 zusätzliche Bestätigungen.", + "block-confirmations-warning": "Das Ausführen von Fedimint mit weniger als 5 zusätzlichen Blockbestätigungen ist äußerst riskant! Fedimint KANN keine Blockchain-Reorganisationen bewältigen.", + "bitcoin-network": "Bitcoin-Netzwerk", + "select-network": "Wählen Sie ein Netzwerk aus", + "bitcoin-rpc-kind": "Bitcoin RPC Art", + "set-rpc-help": "Quelle der Bitcoin-Blockdaten für Ihren Guardian-Knoten", + "bitcoin-rpc": "Bitcoin RPC URL", + "read-from-env": "(Erkannt aus Umgebungsvariablen)", + "error-valid-number": "Bitte geben Sie eine gültige Nummer ein.", + "error-valid-min": "Bitte geben Sie eine Zahl ein, die mindestens {{min}} beträgt.", + "error-valid-max": "Bitte geben Sie eine Zahl ein, die höchstens {{max}} beträgt.", + "error-valid-min-max": "Bitte geben Sie eine Zahl zwischen {{min}} und {{max}} ein.", + "error-guardian-name-mismatch": "Name des Vormunds stimmt nicht überein", + "meta-fields": "Metafelder", + "meta-fields-description": "Siehe Dokumentation für weitere Informationen.", + "meta-fields-key": "Meta-Taste", + "meta-fields-value": "Wert", + "meta-fields-effect": "Wirkung", + "meta-fields-add-another": "Fügen Sie ein weiteres hinzu", + "meta-fields-title": "Ihr Meta-Vorschlag:", + "network": "Netzwerk", + "password-warning-title": "Sichern Sie Ihr Passwort!", + "password-warning": "Sie MÜSSEN Ihr Passwort sichern und sicher aufbewahren. Dieses Passwort wird benötigt, um auf Ihr Guardian-Dashboard zuzugreifen. Sie KÖNNEN es nicht wiederherstellen, wenn Sie es verlieren!" + }, + "setup": { + "warning": { + "title": "Verlassen oder aktualisieren Sie nicht während der Einrichtung!", + "description": "Ein Ausstieg während der Einrichtung kann dazu führen, dass die Einrichtung fehlschlägt und Sie einen vollständigen Neustart durchführen müssen." + }, + "common": { + "restart-setup": "Setup neu starten", + "restart-setup-alert": "Der Setup-Leiter hat die Setup-Zeremonie neu gestartet. Bitte klicken Sie unten auf \"Neustart\", um fortzufahren.", + "confirm-restart-setup": "Sind Sie sicher, dass Sie die Einrichtungszeremonie neu starten möchten?", + "confirm-restart-setup-alert": "Durch Klicken auf \"Neustart\" wird die Zeremonie für alle Wächter neu gestartet." + }, + "progress": { + "tos": { + "title": "Nutzungsbedingungen" + }, + "start": { + "title": "Willkommen, Wächter!", + "subtitle": "Lassen Sie uns Ihren Verband einrichten.", + "step": "Details zur Föderation" + }, + "set-config": { + "title": "Wir müssen einige Konfigurationen für Ihre Föderation festlegen.", + "title-solo": "Wir müssen einige Konfigurationen für Ihre Solo Federation einstellen.", + "subtitle-leader": "Ihre Föderationsanhänger werden diese Informationen an ihrem Ende bestätigen.", + "subtitle-solo": "Der Betrieb einer Solo-Föderation geht mit vielen Vorteilen von Fedimint verloren. Sie werden keine Fehlertoleranz-Konsens für einen offline gegangenen Wächter haben und können keine föderierten Backups durchführen. Gehen Sie mit Vorsicht vor, nicht empfohlen für den Produktionsgebrauch oder den Gebrauch mit mainnet Bitcoin.", + "subtitle-follower": "Ihr Föderationsleiter wird die Hauptdetails der Föderation einrichten. Sie werden diese bald bestätigen.", + "step": "Details zur Föderation" + }, + "connect-guardians": { + "title-leader": "Laden Sie Ihre Wächter ein", + "title-follower": "Bestätigen Sie Ihre Verbandsinformationen", + "subtitle-leader": "Teilen Sie den Link mit den anderen Wächtern, um alle auf den gleichen Stand zu bringen. Sobald alle Wächter beigetreten sind, gehen Sie automatisch zum nächsten Schritt über.", + "subtitle-follower": "Stellen Sie sicher, dass die Informationen hier korrekt aussehen und dass die Wächter der Föderation korrekt sind. Klicken Sie auf die Schaltfläche Genehmigen, wenn Sie sicher sind, dass es gut aussieht.", + "step-leader": "Lade Wächter ein", + "step-follower": "Bestätigen Sie die Informationen" + }, + "run-dkg": { + "title": "Erfolg!", + "subtitle": "Alle Wächter haben die Einrichtungsdetails der Föderation validiert. Einige Zahlen werden berechnet..." + }, + "verify-guardians": { + "title": "Überprüfen Sie Ihre Wächter", + "subtitle": "Fragen Sie jeden Wächter nach seinem Verifizierungscode und fügen Sie diese unten ein, um die Gültigkeit zu überprüfen. Wir sind fast fertig!", + "step": "Überprüfen Sie die Vormünder", + "leader-confirm-done": "Bestätigen Sie, dass alle nachfolgenden Wächter auf \"Weiter\" geklickt haben und ihre Wächter-Dashboards sehen, bevor Sie fortfahren.", + "leader-confirm-done-emphasis": "Durch Klicken auf \"Weiter\" wird die Einrichtungszeremonie abgeschlossen." + }, + "setup-complete": { + "step": "Erledigt!" + }, + "error": { + "title": "Unbekannter Schritt", + "subtitle": "Wie bist du hierher gekommen?!" + } + } + }, + "setup-complete": { + "header": "🎉 🎉 🎉", + "congratulations": "Glückwunsch", + "leader-message": "Alle Verifizierungscodes der Wächter wurden überprüft.", + "follower-message": "Du bist fertig! Lass die anderen Wächter wissen, dass du läufst!", + "continue": "Fortsetzen" + }, + "terms-of-service": { + "agree-and-continue": "Zustimmen & weiterfahren" + }, + "verify-guardians": { + "verified": "Verifiziert", + "verified-placeholder": "Fügen Sie hier den Code ein", + "error": "Etwas ist schief gelaufen.", + "error-peer-id": "Es konnte nicht festgestellt werden, welcher Peer Sie sind. Bitte aktualisieren Sie die Seite und versuchen Sie es erneut.", + "verification-code": "Ihr ({{peerName}}) Bestätigungscode", + "verification-code-help": "Teilen Sie diesen Code mit anderen Wächtern", + "table-title": "Guardian-Bestätigungscodes", + "table-description": "Geben Sie unten die Bestätigungscodes jedes Guardians ein.", + "table-column-name": "Name", + "table-column-status": "Status", + "table-column-hash-input": "Fügen Sie den Bestätigungscode ein", + "wait-all-guardians-verification": "Warten auf die Bestätigung aller Wächter ihrer Codes", + "all-guardians-verified": "Alle Wächter haben ihre Codes überprüft", + "starting-consensus": "Start des Konsenses..." + }, + "footer": { + "docs-section-header": "Dokumente", + "community-section-header": "Gemeinschaft", + "contribute-section-header": "Beitragen", + "getting-started-link-text": "Einstieg", + "faq-link-text": "Häufig gestellte Fragen", + "blog-link-text": "Blog", + "discord-link-text": "Unstimmigkeit", + "twitter-link-text": "Twitter", + "github-link-text": "GitHub" + }, + "admin": { + "fetch-info-modal-text": "Überprüfung der Föderationsdetails..." + }, + "balance-card": { + "card_header": "eCash-Guthaben", + "sentence": "In Sats denominiert", + "your-balance": "Ihr eCash-Guthaben in diesem Verband:" + }, + "connect-federation": { + "connect": "Verbinden 🚀", + "connect-federation-button": "Föderation hinzufügen", + "connection-string-placeholder": "Fügen Sie den Einladungscode des Verbands ein", + "heading": "Verbinden Sie sich mit einem Verband mit einem Einladungscode", + "information-bar-text": "Die Anzahl der Verbände, mit denen Sie sich verbinden können, ist auf einen begrenzt. Die Verbindung zu mehreren Verbänden wird bald unterstützt.", + "label": "Verbindungszeichenfolge:", + "progress-modal-text": "Verbindung zur Föderation wird hergestellt...", + "sub-heading": "Der Einladungscode ist eine lange Zeichenfolge, die mit 'fed1' beginnt.", + "error-message": "Fehler beim Verbinden mit der Föderation: {{error}}" + }, + "wallet": { + "title": "Geldbörse", + "ecash": "Ecash", + "lightning": "Blitz", + "onchain": "Onchain", + "total": "Insgesamt", + "balance": "Gleichgewicht", + "address": "Adresse", + "invoice": "Rechnung", + "receive": "Empfangen", + "send": "Senden", + "create-address": "Adresse erstellen", + "to-federation": "Zur Föderation", + "from-federation": "Von der Föderation", + "sent": "Gesendet", + "sent-amount": "Gesendet {{amount}}", + "to-address": "An Adresse", + "txid": "Transaktions-ID", + "claimed-note": "Anspruchsvolle Notiz", + "claimed-amount": "Geltend gemachter Betrag" + }, + "wallet-modal": { + "title": "Wallet-Aktionen", + "receive": { + "ecash-instructions": "Fügen Sie hier Ihre ecash-Notiz ein", + "paste-ecash-placeholder": "Fügen Sie hier die ecash-Notiz ein", + "redeem": "Einlösen", + "paste-invoice": "Rechnung hier einfügen", + "enter-amount": "Geben Sie den Betrag in {{unit}} ein", + "lightning-instructions": "Geben Sie einen Betrag in Sats ein, um eine Lightning-Rechnung zu erstellen.", + "create-peg-in-address": "Erstellen Sie eine Peg-in-Adresse", + "create-lightning-invoice": "Erstellen Sie eine Lightning-Rechnung", + "paste-ecash-button": "Fügen Sie ecash Notiz ein", + "peg-in-instructions": "Senden Sie Bitcoin an diese Adresse, um sie in Ihr {{federationName}} Ecash-Guthaben einzubinden.", + "ecash-claimed-success": "Ecash erfolgreich eingelöst!", + "address-error": "Fehler beim Erstellen der Adresse: {{error}}" + }, + "send": { + "submit": "Einreichen", + "to-onchain-address": "An Onchain Adresse", + "address-placeholder": "bc1p...", + "peg-out-to-onchain": "Peg Out Ecash zu Onchain", + "peg-out-success": "Peg Out TX gesendet!", + "create-ecash": "Erstelle Ecash Note", + "ecash-created": "Haben eine {{amount}} ecash-Note von Ihrem {{federationName}}-Guthaben abgehoben. Senden Sie es an den Empfänger, um es einzufordern.", + "ecash-error": "Fehler beim Erstellen der ecash-Notiz: {{error}}" + } + }, + "federation-card": { + "table-title": "Verbände", + "id": "ID", + "name": "Name", + "balance": "Gleichgewicht", + "actions": "Aktionen", + "receive": "Empfangen", + "send": "Senden", + "default-federation-name": "Föderation:", + "view-link-on": "Ansicht auf {{host}}", + "leave-fed-error": "Kann den Verband nicht verlassen, solange sich Sats in Ihrem Guthaben befinden. Bitte heben Sie zuerst Ihre Sats ab.", + "leave-fed-modal-title": "Verlassen Sie den Verband", + "leave-fed-modal-text": "Sind Sie sicher, dass Sie die Verbindung trennen möchten von", + "view-config": "Konfiguration anzeigen", + "config-for": "Konfiguration für {{federationId}}" + }, + "header": { + "active": "Aktiv", + "all": "Alle", + "archived": "Archiviert", + "ascending": "Aufsteigend", + "connect": "Verbindungsföderation", + "date-created": "Erstellungsdatum", + "descending": "Absteigend", + "filter": "Filter", + "sort": "Sortieren", + "title": "Blitz Gateway Dashboard" + }, + "info-card": { + "card-header": "Blitzknoten-Informationen", + "node-id": "Knoten-ID", + "alias": "Alias", + "mode": "Mode", + "pubkey": "Pubkey", + "network": "Netzwerk", + "block-height": "Blockhöhe", + "synced-to-chain": "Synchronisiert mit Kette" + }, + "withdraw-card": { + "address-label": "Ihre Adresse:", + "address-placeholder": "Geben Sie Ihre BTC-Adresse ein", + "amount-label": "Betrag (Sats):", + "amount-placeholder": "Geben Sie den Betrag in Sats ein", + "card-header": "Bitcoin abheben", + "close": "Schließen", + "confirm-withdraw": "Bestätigen Sie die Auszahlung", + "error": "Fehler", + "error-address": "Betrag oder Adresse dürfen nicht leer sein", + "error-amount": "Der Betrag darf nicht leer oder gleich null sein.", + "error-request": "Fehler bei der Anforderung der Auszahlung", + "request-from": "Angeforderte Abhebung von", + "requested-withdrawal": "Beantragte Auszahlung", + "to": "zu", + "total_bitcoin": "Gesamt Bitcoin:", + "transaction-sent": "Transaktion gesendet!", + "view": "Ansicht", + "view-it-on": "Sieh es dir an", + "withdraw": "Abheben", + "withdraw-all": "Heben Sie alles ab", + "withdrawal-created": "Abhebung erstellt.", + "withdrawal-created-description": "Bitte überprüfen Sie Ihren Transaktionsverlauf", + "withdrawal-history": "Abhebungsverlauf", + "your-transaction": "Ihre Transaktions-ID:" + } +} diff --git a/apps/guardian-ui/src/languages/en.json b/apps/router/src/languages/en.json similarity index 77% rename from apps/guardian-ui/src/languages/en.json rename to apps/router/src/languages/en.json index 77e5c4fc0..08ef43074 100644 --- a/apps/guardian-ui/src/languages/en.json +++ b/apps/router/src/languages/en.json @@ -3,7 +3,6 @@ "bitcoin": "Bitcoin", "next": "Next", "back": "Back", - "error": "Something went wrong.", "unknown": "Unknown", "remove": "Remove", "copy": "Copy", @@ -18,7 +17,16 @@ "close": "Close", "save": "Save", "continue": "Continue", - "submit": "Submit" + "submit": "Submit", + "address": "Address", + "amount": "Amount", + "btc": "BTC", + "error": "Error", + "sats": "sats", + "msats": "msats", + "uri": "URI", + "view-on-mempool": "View on Mempool", + "ecash": "Ecash" }, "notConfigured": { "title": "Not Configured", @@ -343,5 +351,136 @@ "discord-link-text": "Discord", "twitter-link-text": "Twitter", "github-link-text": "GitHub" + }, + "admin": { + "fetch-info-modal-text": "Checking federation details..." + }, + "balance-card": { + "card_header": "eCash balance", + "sentence": "Denominated in Sats", + "your-balance": "Your eCash balance on this federation:" + }, + "connect-federation": { + "connect": "Connect 🚀", + "connect-federation-button": "Add Federation", + "connection-string-placeholder": "Paste federation invite code", + "heading": "Connect to a federation using an invite code", + "information-bar-text": "The number of federations you can connect to is limited to one. Connecting to multiple federations will be supported soon.", + "label": "Connect String:", + "progress-modal-text": "Connecting to federation...", + "sub-heading": "The invite code is a long string that begins with ‘fed1’", + "error-message": "Error connecting to federation: {{error}}" + }, + "wallet": { + "title": "Wallet", + "ecash": "Ecash", + "lightning": "Lightning", + "onchain": "Onchain", + "total": "Total", + "balance": "Balance", + "address": "Address", + "invoice": "Invoice", + "receive": "Receive", + "send": "Send", + "create-address": "Create Address", + "to-federation": "To Federation", + "from-federation": "From Federation", + "sent": "Sent", + "sent-amount": "Sent {{amount}}", + "to-address": "To Address", + "txid": "Transaction ID", + "claimed-note": "Claimed Note", + "claimed-amount": "Claimed Amount" + }, + "wallet-modal": { + "title": "Wallet Actions", + "receive": { + "ecash-instructions": "Paste your ecash note here", + "paste-ecash-placeholder": "Paste ecash note here", + "redeem": "Redeem", + "paste-invoice": "Paste invoice here", + "enter-amount": "Enter amount in {{unit}}", + "lightning-instructions": "Enter an amount in sats to create a Lightning invoice for", + "create-peg-in-address": "Create Peg-in Address", + "create-lightning-invoice": "Create Lightning invoice", + "paste-ecash-button": "Paste ecash note", + "peg-in-instructions": "Send Bitcoin to this address to peg into your {{federationName}} Ecash Balance", + "ecash-claimed-success": "Ecash claimed successfully!", + "address-error": "Error creating address: {{error}}" + }, + "send": { + "submit": "Submit", + "to-onchain-address": "To Onchain Address", + "address-placeholder": "bc1p...", + "peg-out-to-onchain": "Peg Out Ecash to Onchain", + "peg-out-success": "Peg Out TX Sent!", + "create-ecash": "Create Ecash Note", + "ecash-created": "Pulled a {{amount}} ecash note from your {{federationName}} balance. Send it to the recipient to claim.", + "ecash-error": "Error creating ecash note: {{error}}" + } + }, + "federation-card": { + "table-title": "Federations", + "id": "ID", + "name": "Name", + "balance": "Balance", + "actions": "Actions", + "receive": "Receive", + "send": "Send", + "default-federation-name": "Federation: ", + "view-link-on": "View on {{host}}", + "leave-fed-error": "Cannot leave federation with sats in your balance. Please withdraw your sats first.", + "leave-fed-modal-title": "Leave Federation", + "leave-fed-modal-text": "Are you sure you want to disconnect from", + "view-config": "View Config", + "config-for": "Config for {{federationId}}" + }, + "header": { + "active": "Active", + "all": "All", + "archived": "Archived", + "ascending": "Ascending", + "connect": "Connect Federation", + "date-created": "Date Created", + "descending": "Descending", + "filter": "Filter", + "sort": "Sort", + "title": "Lightning Gateway Dashboard" + }, + "info-card": { + "card-header": "Lightning Node Info", + "node-id": "Node ID", + "alias": "Alias", + "mode": "Mode", + "pubkey": "Pubkey", + "network": "Network", + "block-height": "Block Height", + "synced-to-chain": "Synced to Chain" + }, + "withdraw-card": { + "address-label": "Your address:", + "address-placeholder": "Enter your btc address", + "amount-label": "Amount (sats):", + "amount-placeholder": "Enter amount in sats", + "card-header": "Withdraw Bitcoin", + "close": "Close", + "confirm-withdraw": "Confirm Withdraw", + "error": "Error", + "error-address": "Amount or address cannot be empty", + "error-amount": "Amount cannot be empty or equal to zero", + "error-request": "Failed to request withdrawal", + "request-from": "Requested Withdrawal from", + "requested-withdrawal": "Requested Withdrawal", + "to": "to", + "total_bitcoin": "Total Bitcoin:", + "transaction-sent": "Transaction Sent!", + "view": "View", + "view-it-on": "View it on", + "withdraw": "Withdraw", + "withdraw-all": "Withdraw all", + "withdrawal-created": "Withdrawal created.", + "withdrawal-created-description": "Please check your transaction history", + "withdrawal-history": "Withdrawal History", + "your-transaction": "Your transaction ID:" } } diff --git a/apps/router/src/languages/es.json b/apps/router/src/languages/es.json new file mode 100644 index 000000000..3015197ae --- /dev/null +++ b/apps/router/src/languages/es.json @@ -0,0 +1,486 @@ +{ + "common": { + "bitcoin": "Bitcoin", + "next": "Siguiente", + "back": "Atrás", + "unknown": "Desconocido", + "remove": "Eliminar", + "copy": "Copia", + "copied": "¡Copiado!", + "cancel": "Cancelar", + "review": "Revisión", + "approvals": "Aprobaciones", + "approve": "Aprobar", + "threshold": "Umbral", + "confirm": "Confirmar", + "you": "Tú", + "close": "Cerrar", + "save": "Guardar", + "continue": "Continuar", + "submit": "Enviar", + "address": "Dirección", + "amount": "Cantidad", + "btc": "BTC", + "error": "Error", + "sats": "sats", + "msats": "msats", + "uri": "URI", + "view-on-mempool": "Vista en Mempool", + "ecash": "Efectivo digital" + }, + "notConfigured": { + "title": "No Configurado", + "description": "Por favor, ingrese el CONFIG_API_URL del servidor guardián de Fedimint al que desea apuntar." + }, + "connect-guardians": { + "invite-guardians": "Invita a Seguidores", + "invite-guardians-help": "Comparte este enlace con los otros Guardianes", + "approve": "Aprobar", + "approved": "Aprobado", + "pending": "Pendiente", + "not-joined": "No unido", + "waiting-for-guardian": "Esperando al guardián", + "table-title": "Guardianes de la Federación", + "table-description": "Los guardianes serán confirmados aquí una vez que confirmen la configuración de la Federación.", + "meta-field-key": "Campo meta - {{key}}" + }, + "federation-dashboard": { + "invite-members": "Invita a miembros o autentícate como un tutor", + "invite-members-prompt": "Comparte esto para invitar a miembros a unirse a la federación", + "fed-info": { + "label": "Información de la Federación", + "your-status-label": "Estado", + "block-count-label": "Altura de Bloque de Consenso", + "api-version-label": "Versión de API", + "consensus-version-label": "Versión de consenso", + "peer-id-label": "ID de par", + "session-info": { + "session-height": "Altura de la Sesión", + "latest-session": "Última Sesión" + } + }, + "balance": { + "label": "Hoja de Balance" + }, + "bitcoin-node": { + "label": "Nodo de Bitcoin", + "url-label": "URL", + "network-label": "Red" + }, + "guardians": { + "label": "Otros Guardianes", + "id-name-label": "ID: Nombre", + "status-label": "Estado de Conexión", + "health-label": "Salud", + "health-issue": "Problema", + "health-good": "Bueno", + "last-contribution-label": "Contribución de la Última Sesión", + "api-url-label": "URL de API", + "fetching-announcement": "Obteniendo anuncio..." + }, + "gateways": { + "label": "Portales de Rayos", + "node-id-label": "ID del Nodo Lightning", + "gateway-id-label": "ID de la Pasarela", + "fee-label": "Tarifa de pasarela", + "view-on-site": "Ver en {{site}}", + "no-gateways-info-title": "¡Aún no hay puertas de enlace conectadas!", + "no-gateways-info-description": "Los operadores de nodos Lightning pueden conectarse a su federación para proporcionar interoperabilidad con la Red Lightning. Una vez conectados, aparecerán aquí." + }, + "api-announcements": { + "label": "Anuncios de API", + "guardian": "Guardián", + "api-url": "URL de API", + "revision": "Revisión" + }, + "config": { + "label": "Configuración de Federación", + "view-config": "Ver Configuración", + "missing-meta-module": "No es posible editar los campos Meta. El módulo Meta no está disponible para esta federación.", + "manage-meta": { + "label": "Gestionar Meta", + "cancel-button": "Cancelar", + "confirm-modal": { + "title": "Confirmar Aprobación", + "description": "Su aprobación alcanzará el umbral para adoptar este cambio meta. Su nuevo meta se verá así:" + }, + "consensus-meta-label": "Meta actual en consenso", + "revoke-button": "Revocar", + "no-consensus-meta-message": "no hay metadatos en el consenso", + "proposed-meta-label": "Propuestas Meta", + "propose-meta": "Propón Meta", + "propose-new-meta-button": "Proponer Nueva Meta", + "proposal-approved": "Has aprobado esta propuesta", + "no-submitted-meta-message": "no hay ediciones meta para revisar", + "edit-meta-label": "Editar meta", + "edit-consensus-meta-button": "Editar Consenso Meta", + "submit-meta-proposal": "Enviar Propuesta Meta", + "peer-approvals": "Aprobaciones de Pares", + "actions": "Acciones", + "revision": "Revisión", + "setup-meta-title": "Configurando un Meta para tu Federación", + "setup-meta-description": "Fedimint puede proporcionar información adicional a los clientes en forma de campos meta: pares de valores clave con información arbitraria que podría querer compartir con los clientes. Aunque estos campos meta no son interpretados por Fedimint, son relevantes para el consenso, es decir, no pueden diferir entre los miembros de la federación. De esta manera, los clientes pueden confiar en su corrección.", + "propose-updates": "Como guardián de fedimint, puedes proponer actualizaciones al meta que serán aceptadas por los otros guardianes. Una vez que la actualización es aceptada por un umbral de guardianes, se adoptará como el nuevo meta de consenso para la federación.", + "core-meta-fields": "Los siguientes campos meta han sido definidos como parte del protocolo central de Fedimint y son útiles para incluir en la meta de tu federación:", + "meta-field-expiry": "Un sello de tiempo Unix después del cual la federación se cerrará.", + "meta-field-name": "El nombre legible por humanos de la federación", + "meta-field-icon": "Una URL a un icono de logotipo para la federación", + "meta-field-welcome": "Un mensaje de bienvenida para los nuevos usuarios que se unen a la federación", + "meta-field-gateways": "Una lista de identificadores de puerta de enlace verificados por la federación", + "your-own-fields": "También puedes agregar tus propios campos meta arbitrarios a la propuesta. Estos se agregarán al meta de todos los clientes que se conecten a tu federación y se pueden usar para cualquier propósito que desees.", + "meta-effect-add": "Añadir", + "meta-effect-modify": "Modificar", + "meta-effect-unchanged": "Inalterado", + "proposals": "Propuestas" + } + }, + "modal": { + "client-connect": "Conectar un Cliente" + }, + "danger-zone": { + "danger-zone-label": "Zona de Peligro", + "cancel": "Cancelar", + "danger-zone-description": "¡Usar con precaución!", + "guardian-warning-message": "ADVERTENCIA: No comparta este código con nadie. Cualquiera con este código puede autenticarse como un Guardián. Asegúrese de estar en un lugar privado y que nadie esté mirando su pantalla.", + "guardian-acknowledge": "Reconocer y Revelar Código", + "acknowledge-and-download": "Reconocer y Proceder", + "guardian-authenticate": "Autenticarse como Guardián", + "guardian-connect-warning": "NO COMPARTAS ESTO", + "backup": { + "label": "Copia de seguridad", + "title": "Descargar Copia de Seguridad", + "warning-title": "Advertencia", + "warning-text": "La copia de seguridad contiene claves privadas y material secreto para el guardián de la federación y debe mantenerse segura. ¡La recuperación usando esta copia de seguridad requiere tu contraseña de administrador!", + "cancelButton": "Cancelar", + "acknowledgeButton": "Reconocer y Descargar" + }, + "sign-api-announcement": { + "label": "Anuncio de API de Firma", + "title": "Anuncio de API de firma", + "description": "Firme un nuevo anuncio de API.", + "current-api-url": "La URL de tu API desde la Configuración Local", + "announced-api-url": "La URL de su API de Anuncios de Federación", + "urls-match": "La URL de su API actual coincide con la URL de su API anunciada.", + "urls-mismatch": "Has cambiado la URL de la API en tu configuración local y necesitas transmitir un nuevo anuncio de API.", + "sign-button": "Anuncio de nueva API firmada", + "signing-in-progress": "Iniciando sesión...", + "sign-tooltip": "Firme el anuncio de API para anunciar su URL de API a la federación." + }, + "schedule-shutdown": { + "label": "Programar Apagado", + "title": "Programar Apagado", + "description": "Programe su nodo guardián para que se apague después de una altura de sesión específica para una actualización coordinada de sus binarios fedimintd.", + "current-session": "Sesión Actual", + "session-to-shutdown": "Sesión para Apagar a las", + "confirm-shutdown": "Confirmar Apagado", + "session-to-shutdown-helper": "Ingrese la altura de la sesión en la que desea apagar su nodo guardián." + } + } + }, + "login": { + "title": "¡Bienvenido de nuevo!", + "subtitle": "Por favor, ingrese su contraseña.", + "password": "Contraseña", + "submit": "Enviar" + }, + "role-selector": { + "disclaimer-title": "Fedimint es un software beta.", + "disclaimer-text": "Por favor, informe de los problemas en https://github.com/fedimint/fedimint/issues", + "leader": { + "label": "Líder de Configuración", + "description": "Ingrese la configuración que otros Guardianes aprueban. Un Guardián actúa como Líder de Configuración." + }, + "follower": { + "label": "Seguidor", + "description": "Una vez que un Líder de Configuración establece las configuraciones, otros Guardianes eligen esta opción para aprobar los ajustes y crear la Federación." + }, + "solo": { + "label": "Sólo", + "description": "Opere Fedimint como un Guardián en solitario sin consenso, tolerancia a fallos, copias de seguridad federadas u otros beneficios de resistencia de Fedimint. Proceda con precaución, no está destinado para uso en producción." + }, + "warning-modal": { + "title": "¿Están todos listos?", + "description": "Salir de la ceremonia de configuración puede causar que la configuración falle y requiera que reinicies tu guardián. ¡Asegúrate de que todos estén listos para ejecutar la configuración completa antes de continuar!" + } + }, + "run-dkg": { + "error-config": "No se pudo ejecutar la generación de clave distribuida. Se debe reiniciar la configuración de la federación.", + "error-default": "No está listo para DKG, su estado actual es", + "error-header": "Algo salió mal.", + "waiting-header": "Esperando a los compañeros", + "generating-header": "Generando códigos" + }, + "set-config": { + "bft-explanation-title": "Tolerancia a Fallos Bizantinos de Tu Federación", + "bft-explanation": "Una Federación Guardian {{total}} crea un Umbral {{honesto}}/{{total}}.", + "bft-faulty": "Su Federación podrá tolerar {{faulty}} Guardianes defectuosos, desconectados o malintencionados sin afectar las operaciones de la Federación.", + "guardian-name": "Nombre del tutor", + "guardian-name-help": "Este nombre aleatorio se mostrará a otros Guardianos durante la configuración", + "acknowledge-backed-up": "Yo, {{guardianName}} (tu nombre de guardián), prometo que he respaldado y asegurado mi contraseña:", + "admin-password": "Contraseña de administrador", + "admin-password-generate": "Generar", + "admin-password-set": "Haz clic en 'Generar' para crear una contraseña segura. Puedes modificarla, ¡pero esta contraseña debe ser segura y tener una copia de seguridad!", + "admin-password-help": "¡Haz una copia de seguridad de esta contraseña y guárdala en un lugar seguro! ¡No puedes recuperar esta contraseña!", + "admin-password-backup": "Estoy usando una contraseña fuerte y la he respaldado. (¡No puedes recuperar esta contraseña!)", + "confirm-and-backup-password": "Confirmar y respaldar contraseña", + "confirm-password": "Confirmar contraseña", + "error-password-mismatch": "Las contraseñas no coinciden", + "join-federation": "Unirse al enlace de la Federación", + "join-federation-help": "Pide a la persona que creó la Federación un enlace y pégalo aquí.", + "basic-settings": "Conceptos básicos", + "federation-settings": "Configuración de la federación", + "federation-name": "Nombre de la federación", + "guardian-number": "Número de tutores", + "guardian-number-help": "Las federaciones requieren un mínimo de 4 guardianes. Esto no se puede cambiar más tarde.", + "bitcoin-settings": "Configuraciones de Bitcoin", + "block-confirmations": "Confirmaciones Adicionales de Bloque", + "block-confirmations-help": "Los Guardianes de Fedimint siguen la punta de la cadena de bloques con varias confirmaciones para evitar reorganizaciones de bloques.", + "block-confirmations-help-mainnet": "Ejecutar en Mainnet requiere al menos 5 confirmaciones adicionales.", + "block-confirmations-warning": "Ejecutar Fedimint con menos de 5 confirmaciones de bloques adicionales es extremadamente arriesgado! Fedimint NO PUEDE manejar reorganizaciones de blockchain.", + "bitcoin-network": "Red de Bitcoin", + "select-network": "Selecciona una red", + "bitcoin-rpc-kind": "Tipo de RPC de Bitcoin", + "set-rpc-help": "Fuente de datos de bloque de bitcoin para tu nodo guardián", + "bitcoin-rpc": "URL de RPC de Bitcoin", + "read-from-env": "(Detectado desde las variables de entorno)", + "error-valid-number": "Por favor, ingrese un número válido.", + "error-valid-min": "Por favor, introduzca un número de al menos {{min}}.", + "error-valid-max": "Por favor, ingrese un número de como máximo {{max}}.", + "error-valid-min-max": "Por favor, ingrese un número entre {{min}} y {{max}}.", + "error-guardian-name-mismatch": "El nombre del tutor no coincide", + "meta-fields": "Campos meta", + "meta-fields-description": "Consulte la documentación para obtener más información.", + "meta-fields-key": "Tecla Meta", + "meta-fields-value": "Valor", + "meta-fields-effect": "Efecto", + "meta-fields-add-another": "Añadir otro", + "meta-fields-title": "Tu Propuesta Meta:", + "network": "Red", + "password-warning-title": "¡Haz una copia de seguridad de tu contraseña!", + "password-warning": "DEBES hacer una copia de seguridad de tu contraseña y mantenerla segura. Esta contraseña es necesaria para acceder a tu panel de control de guardian. ¡NO puedes recuperarla si la pierdes!" + }, + "setup": { + "warning": { + "title": "¡No salga ni actualice durante la configuración!", + "description": "Salir durante la configuración puede causar que la configuración falle y tendrás que hacer un reinicio completo." + }, + "common": { + "restart-setup": "Reiniciar Configuración", + "restart-setup-alert": "El Líder de Configuración ha reiniciado la Ceremonia de Configuración. Por favor, haga clic en \"Reiniciar\" a continuación para continuar.", + "confirm-restart-setup": "¿Estás seguro de que quieres reiniciar la Ceremonia de Configuración?", + "confirm-restart-setup-alert": "Hacer clic en \"Reiniciar\" reiniciará la ceremonia para todos los Guardianes." + }, + "progress": { + "tos": { + "title": "Términos de servicio" + }, + "start": { + "title": "¡Bienvenido, Guardián!", + "subtitle": "Vamos a configurar tu federación.", + "step": "Detalles de la federación" + }, + "set-config": { + "title": "Necesitamos establecer algunas configuraciones para su Federación", + "title-solo": "Necesitamos establecer algunas configuraciones para tu Federación Solo.", + "subtitle-leader": "Tus seguidores de la Federación confirmarán esta información por su parte.", + "subtitle-solo": "La ejecución de una Federación en solitario pierde muchos de los beneficios de Fedimint. No tendrá tolerancia a fallos en el consenso a un guardián estando desconectado y no podrá hacer copias de seguridad federadas. Proceda con precaución, no se recomienda para uso en producción o uso con Bitcoin en mainnet.", + "subtitle-follower": "Tu líder de la Federación estará estableciendo los detalles principales de la Federación. Los confirmarás pronto.", + "step": "Detalles de la federación" + }, + "connect-guardians": { + "title-leader": "Invita a tus Guardianes", + "title-follower": "Confirma tu Información de Federación", + "subtitle-leader": "Comparte el enlace con los demás Guardianes para que todos estén en la misma página. Una vez que todos los Guardianes se unan, avanzarás automáticamente al siguiente paso.", + "subtitle-follower": "Asegúrate de que la información aquí se vea correcta, y que los Guardianes de la Federación sean correctos. Haz clic en el botón Aprobar cuando estés seguro de que se ve bien.", + "step-leader": "Invita a los Guardianes", + "step-follower": "Confirmar información" + }, + "run-dkg": { + "title": "¡Éxito!", + "subtitle": "Todos los Guardianes han validado los detalles de configuración de la federación. Ejecutando algunos números..." + }, + "verify-guardians": { + "title": "Verifica tus Guardianes", + "subtitle": "Pide a cada Guardián su código de verificación y pégalo a continuación para comprobar su validez. ¡Ya casi hemos terminado!", + "step": "Verificar tutores", + "leader-confirm-done": "Confirme que todos los Guardianes seguidores han hecho clic en \"Siguiente\" y vean sus tableros de guardianes antes de continuar.", + "leader-confirm-done-emphasis": "Hacer clic en \"Continuar\" completará la ceremonia de configuración." + }, + "setup-complete": { + "step": "¡Hecho!" + }, + "error": { + "title": "Paso desconocido", + "subtitle": "¿Cómo llegaste aquí?!" + } + } + }, + "setup-complete": { + "header": "🎉 🎉 🎉", + "congratulations": "Felicidades", + "leader-message": "Todos los códigos de verificación de los Guardianes han sido verificados.", + "follower-message": "¡Ya has terminado! ¡Haz saber a los otros Guardianes que estás en marcha!", + "continue": "Continuar" + }, + "terms-of-service": { + "agree-and-continue": "Aceptar y continuar" + }, + "verify-guardians": { + "verified": "Verificado", + "verified-placeholder": "Pega el código aquí", + "error": "Algo salió mal.", + "error-peer-id": "No se puede determinar qué par eres. Por favor, actualiza e intenta de nuevo.", + "verification-code": "Tu código de verificación ({{peerName}})", + "verification-code-help": "Comparte este código con otros guardianos", + "table-title": "Códigos de verificación del guardián", + "table-description": "Ingrese los códigos de verificación de cada Guardián a continuación.", + "table-column-name": "Nombre", + "table-column-status": "Estado", + "table-column-hash-input": "Pega el código de verificación", + "wait-all-guardians-verification": "Esperando a que todos los Guardianes verifiquen sus códigos", + "all-guardians-verified": "Todos los Guardianes han verificado sus códigos", + "starting-consensus": "Iniciando consenso..." + }, + "footer": { + "docs-section-header": "Documentos", + "community-section-header": "Comunidad", + "contribute-section-header": "Contribuir", + "getting-started-link-text": "Comenzando", + "faq-link-text": "Preguntas Frecuentes", + "blog-link-text": "Blog", + "discord-link-text": "Discordia", + "twitter-link-text": "Twitter", + "github-link-text": "GitHub" + }, + "admin": { + "fetch-info-modal-text": "Verificando detalles de federación..." + }, + "balance-card": { + "card_header": "Saldo de eCash", + "sentence": "Denominado en Sats", + "your-balance": "Su saldo de eCash en esta federación:" + }, + "connect-federation": { + "connect": "Conectar 🚀", + "connect-federation-button": "Añadir Federación", + "connection-string-placeholder": "Pegar el código de invitación de la federación", + "heading": "Conéctate a una federación utilizando un código de invitación", + "information-bar-text": "El número de federaciones a las que puedes conectarte está limitado a una. Pronto se admitirá la conexión a múltiples federaciones.", + "label": "Cadena de Conexión:", + "progress-modal-text": "Conectando a la federación...", + "sub-heading": "El código de invitación es una cadena larga que comienza con 'fed1", + "error-message": "Error al conectar con la federación: {{error}}" + }, + "wallet": { + "title": "Cartera", + "ecash": "Efectivo electrónico", + "lightning": "Relámpago", + "onchain": "En cadena", + "total": "Total", + "balance": "Equilibrio", + "address": "Dirección", + "invoice": "Factura", + "receive": "Recibir", + "send": "Enviar", + "create-address": "Crear Dirección", + "to-federation": "A la Federación", + "from-federation": "Desde la Federación", + "sent": "Enviado", + "sent-amount": "Enviado {{amount}}", + "to-address": "Para Dirigirse", + "txid": "ID de transacción", + "claimed-note": "Nota Reclamada", + "claimed-amount": "Cantidad Reclamada" + }, + "wallet-modal": { + "title": "Acciones de la Cartera", + "receive": { + "ecash-instructions": "Pega tu nota de ecash aquí", + "paste-ecash-placeholder": "Pegue la nota de efectivo electrónico aquí", + "redeem": "Canjear", + "paste-invoice": "Pegue la factura aquí", + "enter-amount": "Ingrese la cantidad en {{unit}}", + "lightning-instructions": "Ingrese una cantidad en sats para crear una factura de Lightning", + "create-peg-in-address": "Crear Dirección de Peg-in", + "create-lightning-invoice": "Crear factura de Lightning", + "paste-ecash-button": "Pegar nota de efectivo electrónico", + "peg-in-instructions": "Envía Bitcoin a esta dirección para anclarlo a tu saldo Ecash de {{federationName}}", + "ecash-claimed-success": "¡Ecash reclamado con éxito!", + "address-error": "Error al crear la dirección: {{error}}" + }, + "send": { + "submit": "Enviar", + "to-onchain-address": "A la dirección Onchain", + "address-placeholder": "bc1p...", + "peg-out-to-onchain": "Peg Out Ecash a Onchain", + "peg-out-success": "¡Peg Out TX Enviado!", + "create-ecash": "Crear Nota de Ecash", + "ecash-created": "Retiró una nota de ecash de {{amount}} de su saldo de {{federationName}}. Envíelo al destinatario para reclamarlo.", + "ecash-error": "Error al crear nota de ecash: {{error}}" + } + }, + "federation-card": { + "table-title": "Federaciones", + "id": "ID", + "name": "Nombre", + "balance": "Equilibrio", + "actions": "Acciones", + "receive": "Recibir", + "send": "Enviar", + "default-federation-name": "Federación:", + "view-link-on": "Ver en {{host}}", + "leave-fed-error": "No puede abandonar la federación con sats en su saldo. Por favor, retire sus sats primero.", + "leave-fed-modal-title": "Abandonar la Federación", + "leave-fed-modal-text": "¿Estás seguro de que quieres desconectar de", + "view-config": "Ver Configuración", + "config-for": "Configuración para {{federationId}}" + }, + "header": { + "active": "Activo", + "all": "Todo", + "archived": "Archivado", + "ascending": "Ascendiendo", + "connect": "Conectar Federación", + "date-created": "Fecha de Creación", + "descending": "Descendiendo", + "filter": "Filtro", + "sort": "Ordenar", + "title": "Panel de Control de Lightning Gateway" + }, + "info-card": { + "card-header": "Información del Nodo de Lightning", + "node-id": "ID de nodo", + "alias": "Alias", + "mode": "Modo", + "pubkey": "Clave pública", + "network": "Red", + "block-height": "Altura de Bloque", + "synced-to-chain": "Sincronizado con la Cadena" + }, + "withdraw-card": { + "address-label": "Tu dirección:", + "address-placeholder": "Ingrese su dirección de btc", + "amount-label": "Cantidad (sats):", + "amount-placeholder": "Ingrese la cantidad en sats", + "card-header": "Retirar Bitcoin", + "close": "Cerrar", + "confirm-withdraw": "Confirmar Retiro", + "error": "Error", + "error-address": "La cantidad o la dirección no pueden estar vacías", + "error-amount": "La cantidad no puede estar vacía o ser igual a cero", + "error-request": "No se pudo solicitar la retirada", + "request-from": "Solicitud de Retiro de", + "requested-withdrawal": "Retiro Solicitado", + "to": "a", + "total_bitcoin": "Total de Bitcoin:", + "transaction-sent": "¡Transacción enviada!", + "view": "Vista", + "view-it-on": "Véalo en", + "withdraw": "Retirar", + "withdraw-all": "Retirar todo", + "withdrawal-created": "Retiro creado.", + "withdrawal-created-description": "Por favor, revisa tu historial de transacciones", + "withdrawal-history": "Historial de Retiros", + "your-transaction": "Tu ID de transacción:" + } +} diff --git a/apps/router/src/languages/fr.json b/apps/router/src/languages/fr.json new file mode 100644 index 000000000..f625e3d51 --- /dev/null +++ b/apps/router/src/languages/fr.json @@ -0,0 +1,486 @@ +{ + "common": { + "bitcoin": "Bitcoin", + "next": "Suivant", + "back": "Retour", + "unknown": "Inconnu", + "remove": "Supprimer", + "copy": "Copier", + "copied": "Copié !", + "cancel": "Annuler", + "review": "Critique", + "approvals": "Approbations", + "approve": "Approuver", + "threshold": "Seuil", + "confirm": "Confirmer", + "you": "Tu", + "close": "Fermer", + "save": "Sauvegarder", + "continue": "Continuer", + "submit": "Soumettre", + "address": "Adresse", + "amount": "Montant", + "btc": "BTC", + "error": "Erreur", + "sats": "sats", + "msats": "msats", + "uri": "URI", + "view-on-mempool": "Vue sur Mempool", + "ecash": "Ecash" + }, + "notConfigured": { + "title": "Non configuré", + "description": "Veuillez entrer le CONFIG_API_URL du serveur gardien Fedimint à pointer." + }, + "connect-guardians": { + "invite-guardians": "Invitez des abonnés", + "invite-guardians-help": "Partagez ce lien avec les autres Gardiens", + "approve": "Approuver", + "approved": "Approuvé", + "pending": "En attente", + "not-joined": "Non joint", + "waiting-for-guardian": "En attente du tuteur", + "table-title": "Gardiens de la Fédération", + "table-description": "Les gardiens seront confirmés ici une fois qu'ils confirment les paramètres de la Fédération.", + "meta-field-key": "Champ Meta - {{clé}}" + }, + "federation-dashboard": { + "invite-members": "Invitez des membres ou authentifiez-vous en tant que tuteur", + "invite-members-prompt": "Partagez ceci pour inviter des membres à rejoindre la fédération", + "fed-info": { + "label": "Informations sur la Fédération", + "your-status-label": "Statut", + "block-count-label": "Hauteur de Bloc Consensus", + "api-version-label": "Version de l'API", + "consensus-version-label": "Version consensuelle", + "peer-id-label": "ID de pair", + "session-info": { + "session-height": "Hauteur de la session", + "latest-session": "Dernière Session" + } + }, + "balance": { + "label": "Bilan comptable" + }, + "bitcoin-node": { + "label": "Nœud Bitcoin", + "url-label": "URL", + "network-label": "Réseau" + }, + "guardians": { + "label": "Autres Gardiens", + "id-name-label": "ID : Nom", + "status-label": "Statut de la connexion", + "health-label": "Santé", + "health-issue": "Problème", + "health-good": "Bon", + "last-contribution-label": "Contribution de la Dernière Session", + "api-url-label": "URL de l'API", + "fetching-announcement": "Récupération de l'annonce..." + }, + "gateways": { + "label": "Passerelles Éclair", + "node-id-label": "ID du nœud Lightning", + "gateway-id-label": "ID de la passerelle", + "fee-label": "Frais de passerelle", + "view-on-site": "Vue sur {{site}}", + "no-gateways-info-title": "Aucune passerelle connectée pour l'instant !", + "no-gateways-info-description": "Les opérateurs de nœuds Lightning peuvent se connecter à votre fédération pour fournir l'interopérabilité du réseau Lightning. Une fois connectés, ils apparaîtront ici." + }, + "api-announcements": { + "label": "Annonces API", + "guardian": "Gardien", + "api-url": "URL de l'API", + "revision": "Révision" + }, + "config": { + "label": "Configuration de la Fédération", + "view-config": "Voir la configuration", + "missing-meta-module": "La modification des champs Meta n'est pas possible. Le module Meta n'est pas disponible pour cette fédération.", + "manage-meta": { + "label": "Gérer Meta", + "cancel-button": "Annuler", + "confirm-modal": { + "title": "Confirmer l'approbation", + "description": "Votre approbation atteindra le seuil pour adopter ce changement méta. Votre nouveau méta ressemblera à :" + }, + "consensus-meta-label": "Méta actuel en consensus", + "revoke-button": "Révoquer", + "no-consensus-meta-message": "il n'y a pas de meta dans le consensus", + "proposed-meta-label": "Propositions Meta", + "propose-meta": "Propose Meta", + "propose-new-meta-button": "Proposer un nouveau Meta", + "proposal-approved": "Vous avez approuvé cette proposition", + "no-submitted-meta-message": "il n'y a pas de modifications meta à examiner", + "edit-meta-label": "Modifier le méta", + "edit-consensus-meta-button": "Modifier le Consensus Meta", + "submit-meta-proposal": "Soumettre une proposition Meta", + "peer-approvals": "Approbations des pairs", + "actions": "Actions", + "revision": "Révision", + "setup-meta-title": "Configuration d'un Meta pour votre Fédération", + "setup-meta-description": "Fedimint peut fournir des informations supplémentaires aux clients sous forme de champs meta : des paires de clés-valeurs avec des informations arbitraires que vous pourriez vouloir partager avec les clients. Bien que ces champs meta ne soient pas interprétés par Fedimint, ils sont pertinents pour le consensus, c'est-à-dire qu'ils ne peuvent pas différer entre les membres de la fédération. De cette façon, les clients peuvent compter sur leur exactitude.", + "propose-updates": "En tant que gardien de fedimint, vous pouvez proposer des mises à jour du meta qui seront acceptées par les autres gardiens. Une fois la mise à jour acceptée par un seuil de gardiens, elle sera adoptée comme le nouveau meta de consensus pour la fédération.", + "core-meta-fields": "Les champs méta suivants ont été définis comme faisant partie du protocole de base Fedimint et sont utiles à inclure pour la méta de votre fédération :", + "meta-field-expiry": "Un timestamp Unix après lequel la fédération s'arrêtera.", + "meta-field-name": "Le nom lisible par l'homme de la fédération", + "meta-field-icon": "Une URL vers une icône de logo pour la fédération", + "meta-field-welcome": "Un message de bienvenue pour les nouveaux utilisateurs rejoignant la fédération", + "meta-field-gateways": "Une liste d'identifiants de passerelle validés par la fédération", + "your-own-fields": "Vous pouvez également ajouter vos propres champs méta arbitraires à la proposition. Ceux-ci seront ajoutés aux métadonnées de tous les clients qui se connectent à votre fédération et peuvent être utilisés à n'importe quelle fin que vous souhaitez.", + "meta-effect-add": "Ajouter", + "meta-effect-modify": "Modifier", + "meta-effect-unchanged": "Inchangé", + "proposals": "Propositions" + } + }, + "modal": { + "client-connect": "Connecter un Client" + }, + "danger-zone": { + "danger-zone-label": "Zone de Danger", + "cancel": "Annuler", + "danger-zone-description": "Utilisez avec prudence !", + "guardian-warning-message": "AVERTISSEMENT : Ne partagez pas ce code avec quiconque. Toute personne en possession de ce code peut s'authentifier en tant que Gardien. Assurez-vous d'être dans un lieu privé et que personne ne regarde votre écran.", + "guardian-acknowledge": "Reconnaître et Révéler le Code", + "acknowledge-and-download": "Reconnaître & Procéder", + "guardian-authenticate": "Authentifiez-vous en tant que Gardien", + "guardian-connect-warning": "NE PARTAGEZ PAS CECI", + "backup": { + "label": "Sauvegarde", + "title": "Télécharger la sauvegarde", + "warning-title": "Avertissement", + "warning-text": "La sauvegarde contient des clés privées et des matériaux secrets pour le gardien de la fédération et doit être conservée en toute sécurité. La récupération à l'aide de cette sauvegarde nécessite votre mot de passe administrateur !", + "cancelButton": "Annuler", + "acknowledgeButton": "Reconnaître & Télécharger" + }, + "sign-api-announcement": { + "label": "Annonce de l'API Sign", + "title": "Annonce de l'API Sign", + "description": "Signez une nouvelle annonce d'API.", + "current-api-url": "Votre URL d'API à partir de la configuration locale", + "announced-api-url": "Votre URL d'API des Annonces de la Fédération", + "urls-match": "Votre URL d'API actuelle correspond à votre URL d'API annoncée.", + "urls-mismatch": "Vous avez modifié l'URL de l'API dans votre configuration locale et devez diffuser une nouvelle annonce d'API.", + "sign-button": "Annonce de la nouvelle API", + "signing-in-progress": "Connexion en cours...", + "sign-tooltip": "Signez l'annonce de l'API pour annoncer votre URL d'API à la fédération." + }, + "schedule-shutdown": { + "label": "Planifier l'arrêt", + "title": "Programmer l'arrêt", + "description": "Planifiez l'arrêt de votre nœud gardien après une hauteur de session spécifique pour une mise à niveau coordonnée de vos binaires fedimintd.", + "current-session": "Session actuelle", + "session-to-shutdown": "Session à fermer à", + "confirm-shutdown": "Confirmer l'arrêt", + "session-to-shutdown-helper": "Entrez la hauteur de session à laquelle vous souhaitez éteindre votre nœud gardien." + } + } + }, + "login": { + "title": "Bienvenue de retour !", + "subtitle": "Veuillez entrer votre mot de passe.", + "password": "Mot de passe", + "submit": "Soumettre" + }, + "role-selector": { + "disclaimer-title": "Fedimint est un logiciel bêta", + "disclaimer-text": "Veuillez signaler les problèmes à https://github.com/fedimint/fedimint/issues", + "leader": { + "label": "Configuration du Leader", + "description": "Entrez les paramètres de configuration approuvés par d'autres Gardiens. Un Gardien agit en tant que Leader de configuration." + }, + "follower": { + "label": "Abonné", + "description": "Une fois qu'un Responsable de configuration a défini les configurations, les autres Gardiens choisissent cette option pour approuver les paramètres et créer la Fédération." + }, + "solo": { + "label": "Solo", + "description": "Exploitez Fedimint en tant que Gardien Solo sans consensus, tolérance aux pannes, sauvegardes fédérées, ou autres avantages de résilience de Fedimint. Procédez avec prudence, non destiné à une utilisation en production." + }, + "warning-modal": { + "title": "Tout le monde est-il prêt ?", + "description": "Quitter la cérémonie de configuration peut entraîner l'échec de la configuration et vous obliger à redémarrer votre gardien. Assurez-vous que tout le monde est prêt à exécuter la configuration complète avant de continuer !" + } + }, + "run-dkg": { + "error-config": "Échec de l'exécution de la génération de clé distribuée. La configuration de la fédération doit être redémarrée.", + "error-default": "Pas prêt pour DKG, votre statut actuel est", + "error-header": "Quelque chose s'est mal passé.", + "waiting-header": "En attente de pairs", + "generating-header": "Génération de codes" + }, + "set-config": { + "bft-explanation-title": "Tolérance aux pannes byzantines de votre fédération", + "bft-explanation": "Une Fédération de Gardiens {{total}} crée un Seuil {{honest}}/{{total}}.", + "bft-faulty": "Votre Fédération sera capable de tolérer {{faulty}} Gardiens défectueux, hors ligne ou malveillants sans impacter les opérations de la Fédération.", + "guardian-name": "Nom du tuteur", + "guardian-name-help": "Ce nom aléatoire sera affiché aux autres Gardiens lors de la configuration", + "acknowledge-backed-up": "Moi, {{guardianName}} (votre nom de tuteur), je promets que j'ai sauvegardé et sécurisé mon mot de passe :", + "admin-password": "Mot de passe administrateur", + "admin-password-generate": "Générer", + "admin-password-set": "Cliquez sur 'Générer' pour créer un mot de passe sécurisé. Vous pouvez le modifier, mais ce mot de passe doit être sécurisé et sauvegardé !", + "admin-password-help": "Sauvegardez ce mot de passe et gardez-le en sécurité ! Vous ne pouvez pas récupérer ce mot de passe !", + "admin-password-backup": "J'utilise un mot de passe fort et je l'ai sauvegardé. (Vous ne pouvez pas récupérer ce mot de passe !)", + "confirm-and-backup-password": "Confirmer et Sauvegarder le Mot de Passe", + "confirm-password": "Confirmer le mot de passe", + "error-password-mismatch": "Les mots de passe ne correspondent pas", + "join-federation": "Rejoignez le lien de la Fédération", + "join-federation-help": "Demandez à la personne qui a créé la Fédération un lien, et collez-le ici.", + "basic-settings": "Les bases", + "federation-settings": "Paramètres de la fédération", + "federation-name": "Nom de la fédération", + "guardian-number": "Nombre de gardiens", + "guardian-number-help": "Les fédérations exigent un minimum de 4 gardiens. Cela ne peut pas être modifié ultérieurement.", + "bitcoin-settings": "Paramètres Bitcoin", + "block-confirmations": "Confirmations supplémentaires de bloc", + "block-confirmations-help": "Les gardiens de Fedimint suivent la pointe de la blockchain avec plusieurs confirmations pour éviter les réorganisations de blocs.", + "block-confirmations-help-mainnet": "L'exécution sur Mainnet nécessite au moins 5 confirmations supplémentaires.", + "block-confirmations-warning": "Exécuter Fedimint avec moins de 5 confirmations de blocs supplémentaires est extrêmement risqué ! Fedimint NE PEUT PAS gérer les réorganisations de la blockchain.", + "bitcoin-network": "Réseau Bitcoin", + "select-network": "Sélectionnez un réseau", + "bitcoin-rpc-kind": "Type RPC Bitcoin", + "set-rpc-help": "Source de données de bloc bitcoin pour votre nœud gardien", + "bitcoin-rpc": "URL RPC Bitcoin", + "read-from-env": "(Détecté à partir des variables d'environnement)", + "error-valid-number": "Veuillez entrer un numéro valide.", + "error-valid-min": "Veuillez entrer un nombre d'au moins {{min}}.", + "error-valid-max": "Veuillez entrer un nombre au maximum de {{max}}.", + "error-valid-min-max": "Veuillez entrer un nombre entre {{min}} et {{max}}.", + "error-guardian-name-mismatch": "Le nom du tuteur ne correspond pas", + "meta-fields": "Champs Meta", + "meta-fields-description": "Voir documentation pour plus d'informations.", + "meta-fields-key": "Clé Meta", + "meta-fields-value": "Valeur", + "meta-fields-effect": "Effet", + "meta-fields-add-another": "Ajouter un autre", + "meta-fields-title": "Votre proposition Meta :", + "network": "Réseau", + "password-warning-title": "Sauvegardez votre mot de passe !", + "password-warning": "Vous DEVEZ sauvegarder votre mot de passe et le garder en sécurité. Ce mot de passe est nécessaire pour accéder à votre tableau de bord de gardien. Vous NE POUVEZ PAS le récupérer si vous le perdez !" + }, + "setup": { + "warning": { + "title": "Ne quittez pas ou ne rafraîchissez pas pendant l'installation !", + "description": "Quitter pendant l'installation peut entraîner l'échec de celle-ci et vous devrez effectuer un redémarrage complet." + }, + "common": { + "restart-setup": "Redémarrez l'installation", + "restart-setup-alert": "Le Responsable de la Configuration a redémarré la Cérémonie de Configuration. Veuillez cliquer sur \"Redémarrer\" ci-dessous pour continuer.", + "confirm-restart-setup": "Êtes-vous sûr de vouloir redémarrer la Cérémonie de Configuration ?", + "confirm-restart-setup-alert": "Cliquer sur \"Redémarrer\" redémarrera la cérémonie pour tous les Gardiens." + }, + "progress": { + "tos": { + "title": "Conditions d'utilisation" + }, + "start": { + "title": "Bienvenue, Gardien !", + "subtitle": "Configurons votre fédération.", + "step": "Détails de la fédération" + }, + "set-config": { + "title": "Nous devons définir certaines configurations pour votre Fédération", + "title-solo": "Nous devons définir certaines configurations pour votre Fédération Solo", + "subtitle-leader": "Vos abonnés de la Fédération confirmeront cette information de leur côté.", + "subtitle-solo": "L'exploitation d'une Fédération Solo perd de nombreux avantages de Fedimint. Vous n'aurez pas de consensus de tolérance aux pannes pour un gardien hors ligne et ne pourrez pas effectuer de sauvegardes fédérées. Procédez avec prudence, déconseillé pour une utilisation en production ou avec le réseau principal de Bitcoin.", + "subtitle-follower": "Votre dirigeant de la Fédération mettra en place les détails principaux de la Fédération. Vous les confirmerez bientôt.", + "step": "Détails de la fédération" + }, + "connect-guardians": { + "title-leader": "Invitez vos Gardiens", + "title-follower": "Confirmez vos informations de Fédération", + "subtitle-leader": "Partagez le lien avec les autres Gardiens pour que tout le monde soit sur la même longueur d'onde. Une fois que tous les Gardiens ont rejoint, vous passerez automatiquement à l'étape suivante.", + "subtitle-follower": "Assurez-vous que les informations ici sont correctes, et que les Gardiens de la Fédération sont corrects. Cliquez sur le bouton Approuver lorsque vous êtes sûr que cela semble bon.", + "step-leader": "Invitez les Gardiens", + "step-follower": "Confirmer les informations" + }, + "run-dkg": { + "title": "Succès !", + "subtitle": "Tous les Gardiens ont validé les détails de configuration de la fédération. En train de calculer quelques chiffres..." + }, + "verify-guardians": { + "title": "Vérifiez vos Gardiens", + "subtitle": "Demandez à chaque Gardien son code de vérification et collez-les ci-dessous pour vérifier leur validité. Nous avons presque fini !", + "step": "Vérifier les tuteurs", + "leader-confirm-done": "Confirmez que tous les Gardiens suivants ont cliqué sur \"Suivant\" et ont vu leurs tableaux de bord de gardien avant de continuer.", + "leader-confirm-done-emphasis": "Cliquer sur \"Continuer\" terminera la cérémonie de configuration." + }, + "setup-complete": { + "step": "Terminé !" + }, + "error": { + "title": "Étape inconnue", + "subtitle": "Comment es-tu arrivé ici ?!" + } + } + }, + "setup-complete": { + "header": "🎉 🎉 🎉", + "congratulations": "Félicitations", + "leader-message": "Tous les codes de vérification des Gardiens ont été vérifiés.", + "follower-message": "Vous avez terminé ! Faites savoir aux autres Gardiens que vous êtes en marche !", + "continue": "Continuer" + }, + "terms-of-service": { + "agree-and-continue": "Accepter & continuer" + }, + "verify-guardians": { + "verified": "Vérifié", + "verified-placeholder": "Collez le code ici", + "error": "Quelque chose s'est mal passé.", + "error-peer-id": "Impossible de déterminer quel pair vous êtes. Veuillez actualiser et réessayer.", + "verification-code": "Votre code de vérification ({{peerName}})", + "verification-code-help": "Partagez ce code avec d'autres gardiens", + "table-title": "Codes de vérification du gardien", + "table-description": "Entrez les codes de vérification de chaque gardien ci-dessous.", + "table-column-name": "Nom", + "table-column-status": "Statut", + "table-column-hash-input": "Collez le code de vérification", + "wait-all-guardians-verification": "En attente de la vérification de leurs codes par tous les Gardiens", + "all-guardians-verified": "Tous les gardiens ont vérifié leurs codes", + "starting-consensus": "Démarrage du consensus..." + }, + "footer": { + "docs-section-header": "Docs", + "community-section-header": "Communauté", + "contribute-section-header": "Contribuer", + "getting-started-link-text": "Commencer", + "faq-link-text": "Questions Fréquemment Posées", + "blog-link-text": "Blog", + "discord-link-text": "Discord", + "twitter-link-text": "Twitter", + "github-link-text": "GitHub" + }, + "admin": { + "fetch-info-modal-text": "Vérification des détails de la fédération..." + }, + "balance-card": { + "card_header": "Solde eCash", + "sentence": "Dénominé en Sats", + "your-balance": "Votre solde eCash sur cette fédération :" + }, + "connect-federation": { + "connect": "Connecter 🚀", + "connect-federation-button": "Ajouter une Fédération", + "connection-string-placeholder": "Collez le code d'invitation de la fédération", + "heading": "Connectez-vous à une fédération en utilisant un code d'invitation", + "information-bar-text": "Le nombre de fédérations auxquelles vous pouvez vous connecter est limité à une. La connexion à plusieurs fédérations sera bientôt prise en charge.", + "label": "Chaîne de connexion :", + "progress-modal-text": "Connexion à la fédération...", + "sub-heading": "Le code d'invitation est une longue chaîne qui commence par 'fed1", + "error-message": "Erreur de connexion à la fédération : {{error}}" + }, + "wallet": { + "title": "Portefeuille", + "ecash": "Ecash", + "lightning": "Éclair", + "onchain": "Sur la chaîne", + "total": "Total", + "balance": "Équilibre", + "address": "Adresse", + "invoice": "Facture", + "receive": "Recevoir", + "send": "Envoyer", + "create-address": "Créer une adresse", + "to-federation": "À la Fédération", + "from-federation": "De la Fédération", + "sent": "Envoyé", + "sent-amount": "Envoyé {{amount}}", + "to-address": "À l'adresse", + "txid": "ID de transaction", + "claimed-note": "Note revendiquée", + "claimed-amount": "Montant revendiqué" + }, + "wallet-modal": { + "title": "Actions de Portefeuille", + "receive": { + "ecash-instructions": "Collez votre note ecash ici", + "paste-ecash-placeholder": "Collez la note ecash ici", + "redeem": "Échanger", + "paste-invoice": "Collez la facture ici", + "enter-amount": "Entrez le montant en {{unit}}", + "lightning-instructions": "Entrez un montant en sats pour créer une facture Lightning pour", + "create-peg-in-address": "Créer une adresse Peg-in", + "create-lightning-invoice": "Créer une facture Lightning", + "paste-ecash-button": "Collez la note ecash", + "peg-in-instructions": "Envoyez du Bitcoin à cette adresse pour l'ancrer à votre solde Ecash de {{federationName}}", + "ecash-claimed-success": "Ecash revendiqué avec succès !", + "address-error": "Erreur lors de la création de l'adresse : {{error}}" + }, + "send": { + "submit": "Soumettre", + "to-onchain-address": "À l'adresse Onchain", + "address-placeholder": "bc1p...", + "peg-out-to-onchain": "Convertir Peg Out Ecash en Onchain", + "peg-out-success": "Peg Out TX Envoyé !", + "create-ecash": "Créer une Note Ecash", + "ecash-created": "Retiré une note d'ecash de {{amount}} de votre solde {{federationName}}. Envoyez-le au destinataire pour réclamer.", + "ecash-error": "Erreur lors de la création de la note ecash : {{error}}" + } + }, + "federation-card": { + "table-title": "Fédérations", + "id": "ID", + "name": "Nom", + "balance": "Équilibre", + "actions": "Actions", + "receive": "Recevoir", + "send": "Envoyer", + "default-federation-name": "Fédération:", + "view-link-on": "Vue sur {{host}}", + "leave-fed-error": "Impossible de quitter la fédération avec des sats dans votre solde. Veuillez d'abord retirer vos sats.", + "leave-fed-modal-title": "Quitter la Fédération", + "leave-fed-modal-text": "Êtes-vous sûr de vouloir vous déconnecter de", + "view-config": "Voir Config", + "config-for": "Configuration pour {{federationId}}" + }, + "header": { + "active": "Actif", + "all": "Tout", + "archived": "Archivé", + "ascending": "Ascendant", + "connect": "Fédération Connect", + "date-created": "Date de création", + "descending": "Descendant", + "filter": "Filtre", + "sort": "Trier", + "title": "Tableau de bord de la passerelle Lightning" + }, + "info-card": { + "card-header": "Informations sur le Nœud Lightning", + "node-id": "ID de nœud", + "alias": "Alias", + "mode": "Mode", + "pubkey": "Clé publique", + "network": "Réseau", + "block-height": "Hauteur de bloc", + "synced-to-chain": "Synchronisé à la Chaîne" + }, + "withdraw-card": { + "address-label": "Votre adresse :", + "address-placeholder": "Entrez votre adresse btc", + "amount-label": "Montant (sats) :", + "amount-placeholder": "Entrez le montant en sats", + "card-header": "Retirer Bitcoin", + "close": "Fermer", + "confirm-withdraw": "Confirmer le Retrait", + "error": "Erreur", + "error-address": "Le montant ou l'adresse ne peuvent pas être vides", + "error-amount": "Le montant ne peut pas être vide ou égal à zéro", + "error-request": "Échec de la demande de retrait", + "request-from": "Demande de retrait de", + "requested-withdrawal": "Demande de Retrait", + "to": "à", + "total_bitcoin": "Total Bitcoin :", + "transaction-sent": "Transaction envoyée !", + "view": "Vue", + "view-it-on": "Voir sur", + "withdraw": "Retirer", + "withdraw-all": "Retirer tout", + "withdrawal-created": "Retrait créé.", + "withdrawal-created-description": "Veuillez vérifier votre historique de transactions", + "withdrawal-history": "Historique des retraits", + "your-transaction": "Votre ID de transaction :" + } +} diff --git a/apps/router/src/languages/hu.json b/apps/router/src/languages/hu.json new file mode 100644 index 000000000..fe26658e3 --- /dev/null +++ b/apps/router/src/languages/hu.json @@ -0,0 +1,486 @@ +{ + "common": { + "bitcoin": "Bitcoin", + "next": "Következő", + "back": "Hátul", + "unknown": "Ismeretlen", + "remove": "Eltávolítás", + "copy": "Másolás", + "copied": "Másolva!", + "cancel": "Törlés", + "review": "Véleményezés", + "approvals": "Jóváhagyások", + "approve": "Jóváhagy", + "threshold": "Küszöb", + "confirm": "Megerősít", + "you": "Te", + "close": "Bezárás", + "save": "Mentés", + "continue": "Folytatás", + "submit": "Beküldés", + "address": "Cím", + "amount": "Összeg", + "btc": "BTC", + "error": "Hiba", + "sats": "szatsz", + "msats": "msats", + "uri": "URI", + "view-on-mempool": "Megtekintés a Mempool-on", + "ecash": "Ecash" + }, + "notConfigured": { + "title": "Nincs beállítva", + "description": "Kérjük, adja meg a Fedimint guardian szerver CONFIG_API_URL-jét, amelyre mutatni szeretne." + }, + "connect-guardians": { + "invite-guardians": "Hívj meg követőket", + "invite-guardians-help": "Ossza meg ezt a linket a többi Őrzővel.", + "approve": "Jóváhagy", + "approved": "Jóváhagyott", + "pending": "Függőben", + "not-joined": "Nem csatlakozott", + "waiting-for-guardian": "Várakozás a gondviselőre", + "table-title": "Szövetségi Őrzők", + "table-description": "Az őrzők itt lesznek megerősítve, amint megerősítik a Szövetség beállításait.", + "meta-field-key": "Meta mező - {{key}}" + }, + "federation-dashboard": { + "invite-members": "Hívjon meg tagokat vagy hitelesítse magát mint gondviselő.", + "invite-members-prompt": "Ossza meg ezt, hogy meghívja a tagokat a szövetséghez csatlakozásra.", + "fed-info": { + "label": "Szövetségi Információ", + "your-status-label": "Státusz", + "block-count-label": "Konszenzus Blokk Magasság", + "api-version-label": "API verzió", + "consensus-version-label": "Konszenzusos verzió", + "peer-id-label": "Peer azonosító", + "session-info": { + "session-height": "Munkamenet Magasság", + "latest-session": "Legutóbbi munkamenet" + } + }, + "balance": { + "label": "Mérleg" + }, + "bitcoin-node": { + "label": "Bitcoin csomópont", + "url-label": "URL", + "network-label": "Hálózat" + }, + "guardians": { + "label": "Más Őrzők", + "id-name-label": "Azonosító: Név", + "status-label": "Kapcsolat állapota", + "health-label": "Egészség", + "health-issue": "Kérdés", + "health-good": "Jó", + "last-contribution-label": "Utolsó Munkamenet Hozzájárulás", + "api-url-label": "API URL", + "fetching-announcement": "Bejelentés letöltése..." + }, + "gateways": { + "label": "Villám Kapuk", + "node-id-label": "Villám Csomópont ID", + "gateway-id-label": "Átjáró azonosító", + "fee-label": "Kapu díj", + "view-on-site": "Megtekintés a {{site}} oldalon", + "no-gateways-info-title": "Még nincsenek csatlakoztatott átjárók!", + "no-gateways-info-description": "A villámcsomópont-üzemeltetők csatlakozhatnak a szövetségéhez a Villám Hálózat összeférhetőségének biztosítása érdekében. Miután csatlakoztak, itt fognak megjelenni." + }, + "api-announcements": { + "label": "API bejelentések", + "guardian": "Őrző", + "api-url": "API URL", + "revision": "Felülvizsgálat" + }, + "config": { + "label": "Szövetségi Konfiguráció", + "view-config": "Konfiguráció megtekintése", + "missing-meta-module": "A Meta mezők szerkesztése nem lehetséges. A Meta modul nem érhető el ehhez a szövetséghez.", + "manage-meta": { + "label": "Kezelje a Meta-t", + "cancel-button": "Törlés", + "confirm-modal": { + "title": "Jóváhagyás megerősítése", + "description": "Az Ön jóváhagyása eléri a küszöbértéket, hogy elfogadja ezt a meta-változtatást. Az új meta így fog kinézni:" + }, + "consensus-meta-label": "Jelenlegi meta a konszenzusban", + "revoke-button": "Visszavon", + "no-consensus-meta-message": "nincs meta az egyetértésben", + "proposed-meta-label": "Meta Javaslatok", + "propose-meta": "Javasolj Meta", + "propose-new-meta-button": "Javasolj Új Meta-t", + "proposal-approved": "Jóváhagyta ezt a javaslatot", + "no-submitted-meta-message": "nincsenek meta szerkesztések áttekintésre", + "edit-meta-label": "Szerkesztés meta", + "edit-consensus-meta-button": "Szerkesztési Konszenzus Meta", + "submit-meta-proposal": "Nyújts be Meta Javaslatot", + "peer-approvals": "Társi Jóváhagyások", + "actions": "Cselekvések", + "revision": "Felülvizsgálat", + "setup-meta-title": "Meta beállítása a Szövetségének", + "setup-meta-description": "A Fedimint további információkat szolgáltathat az ügyfeleknek meta mezők formájában: kulcs-érték párok, amelyek tetszőleges információkat tartalmazhatnak, amelyeket meg szeretne osztani az ügyfelekkel. Bár ezeket a meta mezőket a Fedimint nem értelmezi, konszenzusra vonatkoznak, azaz nem különbözhetnek a szövetségi tagok között. Így az ügyfelek megbízhatnak a helyesség", + "propose-updates": "Fedimint őrként javaslatokat tehet a meta frissítésére, amelyeket a többi őr elfogad. Amint a frissítést egy bizonyos számú őr elfogadja, az lesz az új konszenzus meta az egész szövetség számára.", + "core-meta-fields": "A következő meta mezők a Fedimint protokoll alapvető részeként lettek definiálva, és hasznosak lehetnek a szövetség meta adatainak belefoglalásához:", + "meta-field-expiry": "Egy unix időbélyeg, amely után a szövetség leáll.", + "meta-field-name": "A szövetség emberi olvasásra alkalmas neve", + "meta-field-icon": "Egy URL a szövetség logó ikonjához", + "meta-field-welcome": "Üdvözlő üzenet az új felhasználóknak, akik csatlakoznak a szövetséghez", + "meta-field-gateways": "A szövetség által ellenőrzött átjáró azonosítók listája", + "your-own-fields": "Saját tetszőleges meta mezőket is hozzáadhat a javaslatához. Ezeket hozzáadják minden olyan kliens meta adataihoz, amelyek csatlakoznak a szövetségéhez, és bármilyen célra felhasználhatók, amelyet szeretne.", + "meta-effect-add": "Adj hozzá", + "meta-effect-modify": "Módosít", + "meta-effect-unchanged": "Változatlan", + "proposals": "Javaslatok" + } + }, + "modal": { + "client-connect": "Csatlakoztassa a Klienst" + }, + "danger-zone": { + "danger-zone-label": "Veszélyes Zóna", + "cancel": "Törlés", + "danger-zone-description": "Óvatosan használja!", + "guardian-warning-message": "FIGYELEM: Ne ossza meg ezt a kódot senkivel. Bárki, aki rendelkezik ezzel a kóddal, hitelesítheti magát Guardian-ként. Győződjön meg róla, hogy privát helyen tartózkodik és senki sem figyeli a képernyőjét.", + "guardian-acknowledge": "Ismerd el és Tárj fel Kódot", + "acknowledge-and-download": "Tudomásul vesz & Folytat", + "guardian-authenticate": "Hitelesítés mint Őrző", + "guardian-connect-warning": "NE OSZD MEG EZT", + "backup": { + "label": "Biztonsági mentés", + "title": "Biztonsági mentés letöltése", + "warning-title": "Figyelmeztetés", + "warning-text": "A biztonsági mentés tartalmazza a szövetségi őrző privát kulcsait és titkos anyagait, és biztonságban kell tartani. A helyreállítás ehhez a biztonsági mentéshez az adminisztrátori jelszavadat igényli!", + "cancelButton": "Mégsem", + "acknowledgeButton": "Elfogad és Letölt" + }, + "sign-api-announcement": { + "label": "API bejelentés aláírása", + "title": "API bejelentés aláírása", + "description": "Írjon alá egy új API bejelentést.", + "current-api-url": "Az API URL-je a helyi konfigurációból", + "announced-api-url": "Az API URL-címed a Szövetségi Közleményekből", + "urls-match": "A jelenlegi API URL-címed megegyezik a bejelentett API URL-címeddel.", + "urls-mismatch": "Megváltoztatta az API URL-jét a helyi konfigurációban, és szüksége van egy új API bejelentés közvetítésére.", + "sign-button": "Új API bejelentés aláírása", + "signing-in-progress": "Bejelentkezés folyamatban...", + "sign-tooltip": "Írja al az API bejelentést, hogy bejelentse az API URL-jét a szövetségnek." + }, + "schedule-shutdown": { + "label": "Leállítás ütemezése", + "title": "Leállítás ütemezése", + "description": "Ütemezze be a őrző csomópontját, hogy egy adott munkamenet magasság után leálljon, így koordináltan frissítheti a fedimintd binárisait.", + "current-session": "Aktuális munkamenet", + "session-to-shutdown": "Ülés leállítása -nál/nél", + "confirm-shutdown": "Leállítás megerősítése", + "session-to-shutdown-helper": "Adja meg azt a munkamenet magasságot, amelynél le szeretné állítani a guardian csomópontját." + } + } + }, + "login": { + "title": "Üdvözöllek újra!", + "subtitle": "Kérjük, adja meg a jelszavát.", + "password": "Jelszó", + "submit": "Beküldés" + }, + "role-selector": { + "disclaimer-title": "A Fedimint bétaszoftver.", + "disclaimer-text": "Kérjük, jelezze a problémákat a következő címen: https://github.com/fedimint/fedimint/issues", + "leader": { + "label": "Vezető beállítása", + "description": "Adjon meg konfigurációs beállításokat, amelyeket más Őrzők is jóváhagynak. Egy Őrző a Beállításvezető szerepét tölti be." + }, + "follower": { + "label": "Követő", + "description": "Amint egy Beállításvezető beállítja a konfigurációkat, a többi Őrző ezt az opciót választja a beállítások jóváhagyásához és a Szövetség létrehozásához." + }, + "solo": { + "label": "Szóló", + "description": "Üzemeltessen Fedimint-et egyedül, mint Solo Guardian, konszenzus, hibatűrés, szövetségi biztonsági mentések vagy a Fedimint egyéb ellenállóképességi előnyei nélkül. Folytassa óvatosan, nem a termelési használatra szánva." + }, + "warning-modal": { + "title": "Mindenki kész?", + "description": "A beállítási ceremónia elhagyása meghiúsíthatja a beállítást, és szükségessé teheti a védelmező újraindítását. Győződjön meg róla, hogy mindenki készen áll a teljes beállítás futtatására, mielőtt folytatná!" + } + }, + "run-dkg": { + "error-config": "Nem sikerült elindítani a disztribuált kulcsgenerálást. Újra kell indítani a szövetségi beállítást.", + "error-default": "Nem áll készen a DKG-ra, jelenlegi állapota:", + "error-header": "Valami hiba történt.", + "waiting-header": "Várakozás társakra", + "generating-header": "Kódok generálása" + }, + "set-config": { + "bft-explanation-title": "A Szövetséged Bizánci Hibatűrése", + "bft-explanation": "Egy {{total}} Őrző Szövetség létrehoz egy {{honest}}/{{total}} Küszöböt.", + "bft-faulty": "Az Ön Szövetsége képes lesz tolerálni a {{faulty}} hibás, offline vagy rosszindulatú Őrzőket anélkül, hogy ez befolyásolná a Szövetség működését.", + "guardian-name": "Őrző neve", + "guardian-name-help": "Ezt a véletlenszerű nevet más Őrzők láthatják a beállítások során.", + "acknowledge-backed-up": "Én, {{guardianName}} (a te gyámneved), megígérem, hogy biztonságosan elmentettem és megőriztem a jelszavam:", + "admin-password": "Admin jelszó", + "admin-password-generate": "Generálj", + "admin-password-set": "Kattintson a 'Generálás' gombra, hogy biztonságos jelszót hozzon létre. Módosíthatja, de ez a jelszó biztonságosnak és biztonsági mentésnek kell lennie!", + "admin-password-help": "Mentsd el és tartsd biztonságban ezt a jelszót! Nem tudod visszaszerezni ezt a jelszót!", + "admin-password-backup": "Erős jelszót használok, és biztonsági mentést készítettem róla. (Ezt a jelszót nem lehet visszaállítani!)", + "confirm-and-backup-password": "Jelszó megerősítése és biztonsági mentése", + "confirm-password": "Jelszó megerősítése", + "error-password-mismatch": "A jelszavak nem egyeznek meg", + "join-federation": "Csatlakozás a Szövetséghez link", + "join-federation-help": "Kérje meg azt a személyt, aki a Szövetséget létrehozta, hogy küldje el a linket, és illessze be ide.", + "basic-settings": "Alapok", + "federation-settings": "Szövetségi beállítások", + "federation-name": "Szövetség neve", + "guardian-number": "Őrzők száma", + "guardian-number-help": "A szövetségeknek minimum 4 őrzőre van szükségük. Ezt később nem lehet megváltoztatni.", + "bitcoin-settings": "Bitcoin beállítások", + "block-confirmations": "További blokk megerősítések", + "block-confirmations-help": "A Fedimint Őrzők több megerősítéssel követik a blokklánc csúcsát, hogy elkerüljék a blokkok újraszervezését.", + "block-confirmations-help-mainnet": "A Mainneten való futtatáshoz legalább 5 további megerősítés szükséges.", + "block-confirmations-warning": "A Fedimint futtatása 5-nél kevesebb további blokk megerősítéssel rendkívül kockázatos! A Fedimint NEM képes kezelni a blokklánc újraszervezéseket.", + "bitcoin-network": "Bitcoin Hálózat", + "select-network": "Válasszon egy hálózatot", + "bitcoin-rpc-kind": "Bitcoin RPC típus", + "set-rpc-help": "Bitcoin blokk adatok forrása az őrző csomópontod számára", + "bitcoin-rpc": "Bitcoin RPC URL", + "read-from-env": "(Környezeti változókból észlelve)", + "error-valid-number": "Kérjük, adjon meg egy érvényes számot.", + "error-valid-min": "Kérjük, adjon meg egy számot, ami legalább {{min}}.", + "error-valid-max": "Kérjük, adjon meg egy számot, ami legfeljebb {{max}}.", + "error-valid-min-max": "Kérjük, adjon meg egy számot {{min}} és {{max}} között.", + "error-guardian-name-mismatch": "A gondviselő neve nem egyezik meg", + "meta-fields": "Meta mezők", + "meta-fields-description": "Tekintse meg a dokumentációt további információkért.", + "meta-fields-key": "Meta kulcs", + "meta-fields-value": "Érték", + "meta-fields-effect": "Hatás", + "meta-fields-add-another": "Adj hozzá még egyet", + "meta-fields-title": "Az Ön Meta Javaslata:", + "network": "Hálózat", + "password-warning-title": "Mentse el a jelszavát!", + "password-warning": "Kötelező biztonságba helyezni a jelszavát és biztonságban tartani. Ez a jelszó szükséges a védelmi irányítópultjához való hozzáféréshez. NEM tudja visszaszerezni, ha elveszíti!" + }, + "setup": { + "warning": { + "title": "Ne lépjen ki vagy frissítsen a beállítások közben!", + "description": "A beállítás közbeni kilépés hibát okozhat a beállításban, és újra kell indítania a rendszert." + }, + "common": { + "restart-setup": "Indítsa újra a beállítást", + "restart-setup-alert": "A Beállítási Vezető újraindította a Beállítási Ceremóniát. Kérjük, kattintson az \"Újraindítás\" gombra az alábbiakban a folytatáshoz.", + "confirm-restart-setup": "Biztosan újra szeretné indítani a Beállítási Ceremóniát?", + "confirm-restart-setup-alert": "A \"Újraindítás\" gombra kattintva újraindul a ceremónia minden Őrző számára." + }, + "progress": { + "tos": { + "title": "Szolgáltatási feltételek" + }, + "start": { + "title": "Üdvözlünk, Őrző!", + "subtitle": "Állítsuk be a szövetségét.", + "step": "Szövetség részletek" + }, + "set-config": { + "title": "Be kell állítanunk néhány konfigurációt az Ön Szövetségéhez.", + "title-solo": "Be kell állítanunk néhány konfigurációt a Solo Szövetséghez.", + "subtitle-leader": "A Szövetségi Követőid megerősítik ezt az információt a saját végükön.", + "subtitle-solo": "Egyedül futtatott Szövetség esetén sok Fedimint előny nem érvényesül. Nem lesz hibatűrő konszenzus, ha egy őrző offline állapotban van, és nem lesz képes szövetségi biztonsági mentéseket készíteni. Óvatosan járjon el, nem ajánlott termelési használatra vagy fő hálózati Bitcoin használatra.", + "subtitle-follower": "A Szövetségi Vezetőd beállítja a fő Szövetségi részleteket. Hamarosan megerősíted őket.", + "step": "Szövetségi részletek" + }, + "connect-guardians": { + "title-leader": "Hívja meg az őrzőit", + "title-follower": "Erősítse meg a Szövetségi Információit", + "subtitle-leader": "Ossza meg a linket a többi Őrzővel, hogy mindenki ugyanazon az oldalon legyen. Amint minden Őrző csatlakozott, automatikusan továbblép a következő lépésre.", + "subtitle-follower": "Győződjön meg róla, hogy az itt található információk helyesek, és hogy a Szövetségi Őrzők megfelelőek. Kattintson az Jóváhagyás gombra, amikor biztos benne, hogy minden rendben van.", + "step-leader": "Hívj meg Őrzőket", + "step-follower": "Megerősítési információ" + }, + "run-dkg": { + "title": "Siker!", + "subtitle": "Minden Őrző megerősítette a szövetségi beállítások adatait. Számok futtatása..." + }, + "verify-guardians": { + "title": "Ellenőrizze a Gondviselőit", + "subtitle": "Kérje el minden Őrzőtől a hitelesítő kódjukat, és illessze be őket alább a érvényesség ellenőrzéséhez. Majdnem kész vagyunk!", + "step": "Ellenőrizze a gondviselőket", + "leader-confirm-done": "Erősítse meg, hogy minden követő Őrző rákattintott a \"Tovább\" gombra, és látták a saját őrzői irányítópultjukat, mielőtt folytatnák.", + "leader-confirm-done-emphasis": "A \"Folytatás\" gombra kattintva befejeződik a beállítási ceremónia." + }, + "setup-complete": { + "step": "Kész!" + }, + "error": { + "title": "Ismeretlen lépés", + "subtitle": "Hogy jutottál ide?!" + } + } + }, + "setup-complete": { + "header": "🎉 🎉 🎉", + "congratulations": "Gratulálok", + "leader-message": "Minden Őrző hitelesítő kódját ellenőrizték.", + "follower-message": "Minden kész! Mondd el a többi Őrzőnek, hogy futtatod!", + "continue": "Folytatás" + }, + "terms-of-service": { + "agree-and-continue": "Egyetértek és folytatom" + }, + "verify-guardians": { + "verified": "Ellenőrzött", + "verified-placeholder": "Illessz ide kódot", + "error": "Valami hiba történt.", + "error-peer-id": "Nem sikerült meghatározni, hogy melyik társaságban vagy. Kérjük, frissítse az oldalt és próbálja újra.", + "verification-code": "Az Ön ({{peerName}}) ellenőrző kódja", + "verification-code-help": "Ossza meg ezt a kódot más őrzőkkel", + "table-title": "Guardian ellenőrző kódok", + "table-description": "Írja be minden Őrző ellenőrző kódját alább.", + "table-column-name": "Név", + "table-column-status": "Státusz", + "table-column-hash-input": "Illessze be az ellenőrző kódot", + "wait-all-guardians-verification": "Várakozás, hogy minden Őrző ellenőrizze a kódjait", + "all-guardians-verified": "Minden Őrző ellenőrizte a kódjait.", + "starting-consensus": "Konszenzus indítása..." + }, + "footer": { + "docs-section-header": "Dokumentumok", + "community-section-header": "Közösség", + "contribute-section-header": "Hozzájárulás", + "getting-started-link-text": "Kezdő lépések", + "faq-link-text": "Gyakran Ismételt Kérdések", + "blog-link-text": "Blog", + "discord-link-text": "Discord", + "twitter-link-text": "Twitter", + "github-link-text": "GitHub" + }, + "admin": { + "fetch-info-modal-text": "Szövetségi adatok ellenőrzése..." + }, + "balance-card": { + "card_header": "eCash egyenleg", + "sentence": "Satsban denominált", + "your-balance": "Az eCash egyenleged ezen a szövetségen:" + }, + "connect-federation": { + "connect": "Csatlakozz 🚀", + "connect-federation-button": "Adj hozzá Föderációt", + "connection-string-placeholder": "Illessze be a szövetségi meghívó kódot", + "heading": "Csatlakozzon egy szövetséghez meghívó kód segítségével", + "information-bar-text": "Csatlakozható szövetségek száma korlátozva van egyre. A több szövetséghez való csatlakozás hamarosan támogatott lesz.", + "label": "Csatlakozási karakterlánc:", + "progress-modal-text": "Csatlakozás a szövetséghez...", + "sub-heading": "A meghívó kód egy hosszú karakterlánc, amely a 'fed1'-el kezdődik.", + "error-message": "Hiba a szövetséghez való csatlakozáskor: {{error}}" + }, + "wallet": { + "title": "Pénztárca", + "ecash": "Ecash", + "lightning": "Villám", + "onchain": "Onchain", + "total": "Összesen", + "balance": "Egyensúly", + "address": "Cím", + "invoice": "Számla", + "receive": "Fogadja el", + "send": "Küldj", + "create-address": "Cím létrehozása", + "to-federation": "Szövetséghez", + "from-federation": "Szövetségből", + "sent": "Küldve", + "sent-amount": "Küldött {{amount}}", + "to-address": "Címzéshez", + "txid": "Tranzakció azonosító", + "claimed-note": "Állítólagos Megjegyzés", + "claimed-amount": "Igényelt összeg" + }, + "wallet-modal": { + "title": "Pénztárca Műveletek", + "receive": { + "ecash-instructions": "Illessze ide az e-pénzjegyét", + "paste-ecash-placeholder": "Illessze ide az ecash jegyzetet", + "redeem": "Vált be", + "paste-invoice": "Illessze ide a számlát", + "enter-amount": "Adja meg a mennyiséget {{unit}}-ban/ben", + "lightning-instructions": "Adjon meg egy összeget satoshikban, hogy létrehozzon egy Lightning számlát.", + "create-peg-in-address": "Hozzon létre Peg-in címet", + "create-lightning-invoice": "Hozzon létre Lightning számlát", + "paste-ecash-button": "Illessz ecash jegyzetet", + "peg-in-instructions": "Küldjön Bitcoint erre a címre, hogy beilleszkedjen az Ön {{federationName}} Ecash egyenlegébe.", + "ecash-claimed-success": "Sikeresen igényelték az Ecash-t!", + "address-error": "Hiba történt a cím létrehozásakor: {{error}}" + }, + "send": { + "submit": "Beküldés", + "to-onchain-address": "Onchain címre", + "address-placeholder": "bc1p...", + "peg-out-to-onchain": "Peg Out Ecash-t Onchain-re", + "peg-out-success": "Peg Out TX elküldve!", + "create-ecash": "Hozzon létre Ecash jegyzetet", + "ecash-created": "Levontottam egy {{amount}} ecash jegyet a {{federationName}} egyenlegedről. Küldd el a címzettnek, hogy igénybe vehesse.", + "ecash-error": "Hiba történt az ecash jegyzet létrehozásakor: {{error}}" + } + }, + "federation-card": { + "table-title": "Szövetségek", + "id": "Azonosító", + "name": "Név", + "balance": "Egyensúly", + "actions": "Cselekvések", + "receive": "Fogadja el", + "send": "Küldj", + "default-federation-name": "Szövetség:", + "view-link-on": "Megtekintés a {{host}} oldalon", + "leave-fed-error": "Nem hagyhatja el a szövetséget, ha még vannak satjai az egyenlegén. Kérjük, először vonja ki a satjait.", + "leave-fed-modal-title": "Hagyja el a Szövetséget", + "leave-fed-modal-text": "Biztosan szeretne lecsatlakozni a következőről:", + "view-config": "Konfiguráció megtekintése", + "config-for": "Beállítás a következőhöz: {{federationId}}" + }, + "header": { + "active": "Aktív", + "all": "Minden", + "archived": "Archivált", + "ascending": "Emelkedő", + "connect": "Csatlakozás a Szövetséghez", + "date-created": "Létrehozás dátuma", + "descending": "Leereszkedő", + "filter": "Szűrő", + "sort": "Rendezés", + "title": "Villám Kapu Műszerfal" + }, + "info-card": { + "card-header": "Villám Csúcs Információ", + "node-id": "Csomópont azonosító", + "alias": "Álnév", + "mode": "Mód", + "pubkey": "Publikus kulcs", + "network": "Hálózat", + "block-height": "Blokk magasság", + "synced-to-chain": "Szinkronizálva a láncra" + }, + "withdraw-card": { + "address-label": "Az Ön címe:", + "address-placeholder": "Adja meg a btc címét", + "amount-label": "Összeg (sats):", + "amount-placeholder": "Adja meg az összeget satoshikban", + "card-header": "Bitcoin kivonása", + "close": "Bezárás", + "confirm-withdraw": "Visszavonás megerősítése", + "error": "Hiba", + "error-address": "Az összeg vagy a cím nem lehet üres.", + "error-amount": "Az összeg nem lehet üres vagy nulla.", + "error-request": "Nem sikerült a kifizetési kérelmet benyújtani", + "request-from": "Kifizetési kérelem benyújtása", + "requested-withdrawal": "Kért kifizetés", + "to": "hozzá", + "total_bitcoin": "Összes Bitcoin:", + "transaction-sent": "Tranzakció elküldve!", + "view": "Megtekintés", + "view-it-on": "Tekintse meg azt", + "withdraw": "Visszavonás", + "withdraw-all": "Vonja ki mindent", + "withdrawal-created": "Létrehozott visszavonás.", + "withdrawal-created-description": "Kérjük, ellenőrizze tranzakcióinak előzményeit.", + "withdrawal-history": "Kifizetési előzmények", + "your-transaction": "Az Ön tranzakciós azonosítója:" + } +} diff --git a/apps/guardian-ui/src/languages/index.ts b/apps/router/src/languages/index.ts similarity index 100% rename from apps/guardian-ui/src/languages/index.ts rename to apps/router/src/languages/index.ts diff --git a/apps/router/src/languages/it.json b/apps/router/src/languages/it.json new file mode 100644 index 000000000..21b204560 --- /dev/null +++ b/apps/router/src/languages/it.json @@ -0,0 +1,486 @@ +{ + "common": { + "bitcoin": "Bitcoin", + "next": "Successivo", + "back": "Indietro", + "unknown": "Sconosciuto", + "remove": "Rimuovi", + "copy": "Copia", + "copied": "Copiato!", + "cancel": "Annulla", + "review": "Recensione", + "approvals": "Approvazioni", + "approve": "Approva", + "threshold": "Soglia", + "confirm": "Conferma", + "you": "Tu", + "close": "Chiudi", + "save": "Salva", + "continue": "Continua", + "submit": "Invia", + "address": "Indirizzo", + "amount": "Quantità", + "btc": "BTC", + "error": "Errore", + "sats": "esami", + "msats": "msats", + "uri": "URI", + "view-on-mempool": "Visualizza su Mempool", + "ecash": "Efectivo electrónico" + }, + "notConfigured": { + "title": "Non configurato", + "description": "Inserisci il CONFIG_API_URL del server guardian di Fedimint a cui puntare." + }, + "connect-guardians": { + "invite-guardians": "Invita Seguaci", + "invite-guardians-help": "Condividi questo link con gli altri Guardiani", + "approve": "Approva", + "approved": "Approvato", + "pending": "In sospeso", + "not-joined": "Non unito", + "waiting-for-guardian": "In attesa del tutore", + "table-title": "Federazione Guardiani", + "table-description": "I guardiani verranno confermati qui una volta che confermano le impostazioni della Federazione.", + "meta-field-key": "Meta campo - {{key}}" + }, + "federation-dashboard": { + "invite-members": "Invita membri o autenticati come un tutore", + "invite-members-prompt": "Condividi questo per invitare i membri a unirsi alla federazione", + "fed-info": { + "label": "Informazioni sulla Federazione", + "your-status-label": "Stato", + "block-count-label": "Consensus Block Height", + "api-version-label": "Versione API", + "consensus-version-label": "Versione di consenso", + "peer-id-label": "ID del pari", + "session-info": { + "session-height": "Altezza della sessione", + "latest-session": "Ultima sessione" + } + }, + "balance": { + "label": "Bilancio" + }, + "bitcoin-node": { + "label": "Nodo Bitcoin", + "url-label": "URL", + "network-label": "Rete" + }, + "guardians": { + "label": "Altri Guardiani", + "id-name-label": "ID: Nome", + "status-label": "Stato della connessione", + "health-label": "Salute", + "health-issue": "Problema", + "health-good": "Buono", + "last-contribution-label": "Ultima Contribuzione alla Sessione", + "api-url-label": "URL dell'API", + "fetching-announcement": "Recuperando annuncio..." + }, + "gateways": { + "label": "Porte del Fulmine", + "node-id-label": "ID del nodo Lightning", + "gateway-id-label": "ID del gateway", + "fee-label": "Tariffa gateway", + "view-on-site": "Vista su {{site}}", + "no-gateways-info-title": "Ancora nessun gateway connesso!", + "no-gateways-info-description": "Gli operatori dei nodi Lightning possono collegarsi alla tua federazione per fornire l'interoperabilità della Lightning Network. Una volta connessi, appariranno qui." + }, + "api-announcements": { + "label": "Annunci API", + "guardian": "Tutore", + "api-url": "URL dell'API", + "revision": "Rivedere" + }, + "config": { + "label": "Configurazione Federazione", + "view-config": "Visualizza Configurazione", + "missing-meta-module": "La modifica dei campi Meta non è possibile. Il modulo Meta non è disponibile per questa federazione.", + "manage-meta": { + "label": "Gestisci Meta", + "cancel-button": "Annulla", + "confirm-modal": { + "title": "Conferma approvazione", + "description": "La tua approvazione raggiungerà la soglia per adottare questa modifica meta. Il tuo nuovo meta sarà così:" + }, + "consensus-meta-label": "Attuale meta in consenso", + "revoke-button": "Revocare", + "no-consensus-meta-message": "non ci sono meta nel consenso", + "proposed-meta-label": "Proposte Meta", + "propose-meta": "Proporre Meta", + "propose-new-meta-button": "Proporre Nuovo Meta", + "proposal-approved": "Hai approvato questa proposta", + "no-submitted-meta-message": "non ci sono modifiche meta da rivedere", + "edit-meta-label": "Modifica meta", + "edit-consensus-meta-button": "Modifica Consenso Meta", + "submit-meta-proposal": "Invia Proposta Meta", + "peer-approvals": "Approvazioni dei pari", + "actions": "Aktionen", + "revision": "Rivedere", + "setup-meta-title": "Configurando un Meta para tu Federación", + "setup-meta-description": "Fedimint può fornire informazioni aggiuntive ai clienti sotto forma di campi meta: coppie chiave-valore con informazioni arbitrarie che potresti voler condividere con i clienti. Sebbene questi campi meta non siano interpretati da Fedimint, sono rilevanti per il consenso, cioè non possono differire tra i membri della federazione. In questo modo i clienti possono fare affidamento sulla loro correttezza.", + "propose-updates": "Come guardiano di fedimint, puoi proporre aggiornamenti al meta che saranno accettati dagli altri guardiani. Una volta che l'aggiornamento viene accettato da una soglia di guardiani, verrà adottato come il nuovo meta di consenso per la federazione.", + "core-meta-fields": "I seguenti campi meta sono stati definiti come parte del protocollo core di Fedimint e sono utili da includere per i metadati della tua federazione:", + "meta-field-expiry": "Un timestamp Unix dopo il quale la federazione si spegnerà.", + "meta-field-name": "Il nome leggibile dell'umano della federazione", + "meta-field-icon": "Un URL a un'icona del logo per la federazione", + "meta-field-welcome": "Un messaggio di benvenuto per i nuovi utenti che si uniscono alla federazione", + "meta-field-gateways": "Un elenco di identificatori di gateway verificati dalla federazione", + "your-own-fields": "Puoi anche aggiungere i tuoi campi meta arbitrari alla proposta. Questi verranno aggiunti ai metadati di tutti i client che si connettono alla tua federazione e possono essere utilizzati per qualsiasi scopo tu desideri.", + "meta-effect-add": "Aggiungi", + "meta-effect-modify": "Modifica", + "meta-effect-unchanged": "Inalterato", + "proposals": "Proposte" + } + }, + "modal": { + "client-connect": "Collega un Cliente" + }, + "danger-zone": { + "danger-zone-label": "Zona di pericolo", + "cancel": "Annulla", + "danger-zone-description": "Usa con cautela!", + "guardian-warning-message": "AVVERTIMENTO: Non condividere questo codice con nessuno. Chiunque abbia questo codice può autenticarsi come un Guardiano. Assicurati di essere in un luogo privato e che nessuno stia guardando il tuo schermo.", + "guardian-acknowledge": "Riconosci e Rivela il Codice", + "acknowledge-and-download": "Riconosci e procedi", + "guardian-authenticate": "Autenticati come Guardiano", + "guardian-connect-warning": "NON CONDIVIDERE QUESTO", + "backup": { + "label": "Copia di sicurezza", + "title": "Scarica il backup", + "warning-title": "Avvertimento", + "warning-text": "Il backup contiene chiavi private e materiale segreto per il guardiano della federazione e deve essere mantenuto sicuro. Il recupero utilizzando questo backup richiede la tua password di amministratore!", + "cancelButton": "Annulla", + "acknowledgeButton": "Riconosci e Scarica" + }, + "sign-api-announcement": { + "label": "Annuncio API di segno", + "title": "Annuncio API firma", + "description": "Firma un nuovo annuncio API.", + "current-api-url": "Il tuo URL API da Config Locale", + "announced-api-url": "Il tuo URL API dagli annunci della Federazione", + "urls-match": "Il tuo attuale URL API corrisponde al tuo URL API annunciato.", + "urls-mismatch": "Hai cambiato l'URL dell'API nella tua configurazione locale e devi trasmettere un nuovo annuncio API.", + "sign-button": "Firma nuovo annuncio API", + "signing-in-progress": "Accesso in corso...", + "sign-tooltip": "Firma l'annuncio API per annunciare il tuo URL API alla federazione." + }, + "schedule-shutdown": { + "label": "Programma Spegnimento", + "title": "Pianifica Spegnimento", + "description": "Programma il tuo nodo guardiano per spegnere dopo un'altezza di sessione specifica per un aggiornamento coordinato dei tuoi binari fedimintd.", + "current-session": "Sessione corrente", + "session-to-shutdown": "Sessione per spegnere alle", + "confirm-shutdown": "Conferma spegnimento", + "session-to-shutdown-helper": "Inserisci l'altezza della sessione alla quale vuoi spegnere il tuo nodo guardiano." + } + } + }, + "login": { + "title": "Ben tornato!", + "subtitle": "Inserisci la tua password.", + "password": "Contraseña", + "submit": "Invia" + }, + "role-selector": { + "disclaimer-title": "Fedimint è un software beta", + "disclaimer-text": "Segnala problemi su https://github.com/fedimint/fedimint/issues", + "leader": { + "label": "Imposta Leader", + "description": "Inserisci le impostazioni di configurazione che altri Guardiani approvano. Un Guardiano agisce come Leader di Configurazione." + }, + "follower": { + "label": "Seguace", + "description": "Una volta che un Leader di Configurazione imposta le configurazioni, altri Guardiani scelgono questa opzione per approvare le impostazioni e creare la Federazione." + }, + "solo": { + "label": "Alone", + "description": "Operare Fedimint come un Guardiano Solo senza consenso, tolleranza agli errori, backup federati o altri benefici di resilienza di Fedimint. Procedere con cautela, non è destinato all'uso in produzione." + }, + "warning-modal": { + "title": "Tutti sono pronti?", + "description": "Uscire dalla cerimonia di configurazione può causare il fallimento della configurazione e richiedere il riavvio del tuo guardiano. Assicurati che tutti siano pronti a eseguire la configurazione completa prima di continuare!" + } + }, + "run-dkg": { + "error-config": "Impossibile eseguire la generazione di chiave distribuita. L'installazione della federazione deve essere riavviata.", + "error-default": "Non pronto per DKG, il tuo stato attuale è", + "error-header": "Qualcosa è andato storto.", + "waiting-header": "In attesa di coetanei", + "generating-header": "Generando codici" + }, + "set-config": { + "bft-explanation-title": "Tolleranza ai guasti bizantini della tua federazione", + "bft-explanation": "Una Federazione Guardian {{total}} crea una Soglia {{honest}}/{{total}}.", + "bft-faulty": "La tua Federazione sarà in grado di tollerare {{faulty}} Guardiani difettosi, offline o malevoli senza influire sulle operazioni della Federazione.", + "guardian-name": "Nome del tutore", + "guardian-name-help": "Questo nome casuale verrà mostrato ad altri Guardiani durante l'installazione", + "acknowledge-backed-up": "Io, {{guardianName}} (il tuo nome di guardiano), prometto che ho fatto il backup e ho messo in sicurezza la mia password:", + "admin-password": "Password dell'amministratore", + "admin-password-generate": "Generare", + "admin-password-set": "Fai clic su 'Genera' per creare una password sicura. Puoi modificarla, ma questa password deve essere sicura e salvata!", + "admin-password-help": "Esegui il backup di questa password e tienila al sicuro! Non puoi recuperare questa password!", + "admin-password-backup": "Sto utilizzando una password forte e l'ho salvata. (Non puoi recuperare questa password!)", + "confirm-and-backup-password": "Conferma e Backup della Password", + "confirm-password": "Conferma password", + "error-password-mismatch": "Le password non corrispondono", + "join-federation": "Unisciti al link della Federazione", + "join-federation-help": "Chiedi alla persona che ha creato la Federazione un link e incollalo qui.", + "basic-settings": "Fondamentali", + "federation-settings": "Impostazioni della federazione", + "federation-name": "Nome della federazione", + "guardian-number": "Numero di guardiani", + "guardian-number-help": "Le federazioni richiedono un minimo di 4 guardiani. Questo non può essere modificato in seguito.", + "bitcoin-settings": "Impostazioni Bitcoin", + "block-confirmations": "Conferme aggiuntive del blocco", + "block-confirmations-help": "I guardiani di Fedimint seguono la punta della blockchain con diverse conferme per evitare riorganizzazioni di blocchi.", + "block-confirmations-help-mainnet": "Eseguire su Mainnet richiede almeno 5 conferme aggiuntive.", + "block-confirmations-warning": "Eseguire Fedimint con meno di 5 conferme di blocchi aggiuntive è estremamente rischioso! Fedimint NON può gestire le riorganizzazioni della blockchain.", + "bitcoin-network": "Rete Bitcoin", + "select-network": "Seleziona una rete", + "bitcoin-rpc-kind": "Tipo di RPC Bitcoin", + "set-rpc-help": "Fonte di dati del blocco bitcoin per il tuo nodo guardiano", + "bitcoin-rpc": "URL RPC Bitcoin", + "read-from-env": "(Rilevato dalle variabili di ambiente)", + "error-valid-number": "Inserisci un numero valido.", + "error-valid-min": "Inserisci un numero di almeno {{min}}.", + "error-valid-max": "Inserisci un numero al massimo di {{max}}.", + "error-valid-min-max": "Inserisci un numero tra {{min}} e {{max}}.", + "error-guardian-name-mismatch": "Il nome del tutore non corrisponde", + "meta-fields": "Campi meta", + "meta-fields-description": "Vedi documentazione per ulteriori informazioni.", + "meta-fields-key": "Chiave Meta", + "meta-fields-value": "Valore", + "meta-fields-effect": "Effetto", + "meta-fields-add-another": "Aggiungi un altro", + "meta-fields-title": "La tua proposta Meta:", + "network": "Rete", + "password-warning-title": "Esegui il backup della tua password!", + "password-warning": "Devi ASSOLUTAMENTE fare un backup della tua password e tenerla al sicuro. Questa password è necessaria per accedere al tuo pannello di controllo del guardiano. NON puoi recuperarla se la perdi!" + }, + "setup": { + "warning": { + "title": "Non uscire o aggiornare durante l'installazione!", + "description": "Uscire durante l'impostazione può causare il fallimento dell'impostazione e dovrai fare un nuovo riavvio." + }, + "common": { + "restart-setup": "Riavvia Configurazione", + "restart-setup-alert": "Il Leader dell'installazione ha riavviato la Cerimonia di Installazione. Si prega di fare clic su \"Riavvia\" qui sotto per continuare.", + "confirm-restart-setup": "Sei sicuro di voler riavviare la Cerimonia di Configurazione?", + "confirm-restart-setup-alert": "Fare clic su \"Riavvia\" riavvierà la cerimonia per tutti i Guardiani." + }, + "progress": { + "tos": { + "title": "Termini di servizio" + }, + "start": { + "title": "Benvenuto, Guardiano!", + "subtitle": "Impostiamo la tua federazione.", + "step": "Dettagli della federazione" + }, + "set-config": { + "title": "Dobbiamo impostare alcune configurazioni per la tua Federazione", + "title-solo": "Dobbiamo impostare alcune configurazioni per la tua Federazione Solo.", + "subtitle-leader": "I tuoi seguaci della Federazione confermeranno queste informazioni dal loro lato.", + "subtitle-solo": "Eseguire una Federazione Solista perde molti dei vantaggi di Fedimint. Non avrai tolleranza agli errori di consenso a un guardiano offline e non sarai in grado di fare backup federati. Procedi con cautela, non consigliato per l'uso in produzione o per l'uso con Bitcoin mainnet.", + "subtitle-follower": "Il tuo Leader della Federazione sta impostando i dettagli principali della Federazione. Li confermerai presto.", + "step": "Dettagli della federazione" + }, + "connect-guardians": { + "title-leader": "Invita i tuoi Guardiani", + "title-follower": "Conferma le tue informazioni sulla Federazione", + "subtitle-leader": "Condividi il link con gli altri Guardiani per mettere tutti sulla stessa pagina. Una volta che tutti i Guardiani si uniscono, passerai automaticamente al passaggio successivo.", + "subtitle-follower": "Assicurati che le informazioni qui presenti siano corrette e che i Guardiani della Federazione siano giusti. Clicca sul pulsante Approva quando sei sicuro che tutto sia in ordine.", + "step-leader": "Invita Guardiani", + "step-follower": "Conferma le informazioni" + }, + "run-dkg": { + "title": "¡Éxito!", + "subtitle": "Tutti i Guardiani hanno convalidato i dettagli della configurazione della federazione. Esecuzione di alcuni numeri..." + }, + "verify-guardians": { + "title": "Verifica i tuoi Guardiani", + "subtitle": "Chiedi a ciascun Guardiano il loro codice di verifica e incollalo qui sotto per controllare la validità. Abbiamo quasi finito!", + "step": "Verifica i tutori", + "leader-confirm-done": "Conferma che tutti i Guardiani seguaci abbiano cliccato su \"Avanti\" e visualizzato i loro cruscotti di guardiani prima di continuare.", + "leader-confirm-done-emphasis": "Fare clic su \"Continua\" completerà la cerimonia di configurazione." + }, + "setup-complete": { + "step": "Fatto!" + }, + "error": { + "title": "Passo sconosciuto", + "subtitle": "Come sei arrivato qui?!" + } + } + }, + "setup-complete": { + "header": "🎉 🎉 🎉", + "congratulations": "Complimenti", + "leader-message": "Tutti i codici di verifica dei Guardiani sono stati verificati.", + "follower-message": "Hai finito tutto! Fai sapere agli altri Guardiani che stai correndo!", + "continue": "Continua" + }, + "terms-of-service": { + "agree-and-continue": "Accetta & continua" + }, + "verify-guardians": { + "verified": "Verificato", + "verified-placeholder": "Incolla il codice qui", + "error": "Qualcosa è andato storto.", + "error-peer-id": "Impossibile determinare quale peer tu sia. Si prega di aggiornare e riprovare.", + "verification-code": "Il tuo codice di verifica ({{peerName}})", + "verification-code-help": "Condividi questo codice con altri guardiani", + "table-title": "Codici di verifica del Guardian", + "table-description": "Inserisci di seguito i codici di verifica di ogni Guardiano.", + "table-column-name": "Nome", + "table-column-status": "Stato", + "table-column-hash-input": "Incolla il codice di verifica", + "wait-all-guardians-verification": "In attesa che tutti i Guardiani verifichino i loro codici", + "all-guardians-verified": "Tutti i Guardiani hanno verificato i loro codici", + "starting-consensus": "Iniziando il consenso..." + }, + "footer": { + "docs-section-header": "Documenti", + "community-section-header": "Comunità", + "contribute-section-header": "Contribuire", + "getting-started-link-text": "Iniziare", + "faq-link-text": "Domande Frequenti", + "blog-link-text": "Blog", + "discord-link-text": "Discordia", + "twitter-link-text": "Twitter", + "github-link-text": "GitHub" + }, + "admin": { + "fetch-info-modal-text": "Verifica dei dettagli della federazione..." + }, + "balance-card": { + "card_header": "Saldo eCash", + "sentence": "Denominato in Sats", + "your-balance": "Il saldo del tuo eCash su questa federazione:" + }, + "connect-federation": { + "connect": "Collega 🚀", + "connect-federation-button": "Aggiungi Federazione", + "connection-string-placeholder": "Incolla il codice di invito della federazione", + "heading": "Connettiti a una federazione utilizzando un codice di invito", + "information-bar-text": "Il numero di federazioni a cui puoi connetterti è limitato a uno. La connessione a più federazioni sarà supportata presto.", + "label": "Stringa di connessione:", + "progress-modal-text": "Collegamento alla federazione...", + "sub-heading": "Il codice di invito è una lunga stringa che inizia con 'fed1", + "error-message": "Errore durante la connessione alla federazione: {{error}}" + }, + "wallet": { + "title": "Portafoglio", + "ecash": "Efectivo electrónico", + "lightning": "Fulmine", + "onchain": "Sulla catena", + "total": "Totale", + "balance": "Equilibrio", + "address": "Indirizzo", + "invoice": "Fattura", + "receive": "Ricevi", + "send": "Invia", + "create-address": "Crea indirizzo", + "to-federation": "Alla Federazione", + "from-federation": "Dalla Federazione", + "sent": "Inviato", + "sent-amount": "Inviato {{amount}}", + "to-address": "All'indirizzo", + "txid": "ID della transazione", + "claimed-note": "Nota rivendicata", + "claimed-amount": "Importo rivendicato" + }, + "wallet-modal": { + "title": "Azioni del portafoglio", + "receive": { + "ecash-instructions": "Incolla qui la tua nota ecash.", + "paste-ecash-placeholder": "Incolla qui la nota ecash", + "redeem": "Riscatta", + "paste-invoice": "Incolla qui la fattura", + "enter-amount": "Inserisci l'importo in {{unit}}", + "lightning-instructions": "Inserisci un importo in sats per creare una fattura Lightning.", + "create-peg-in-address": "Crea un indirizzo Peg-in", + "create-lightning-invoice": "Crea fattura Lightning", + "paste-ecash-button": "Incolla la nota ecash", + "peg-in-instructions": "Invia Bitcoin a questo indirizzo per ancorare al tuo saldo Ecash di {{federationName}}", + "ecash-claimed-success": "Ecash rivendicato con successo!", + "address-error": "Errore nella creazione dell'indirizzo: {{error}}" + }, + "send": { + "submit": "Invia", + "to-onchain-address": "All'indirizzo Onchain", + "address-placeholder": "As an AI, I'm unable to translate this text as it appears to be a Bitcoin address or a part of it, which doesn't have a linguistic translation.", + "peg-out-to-onchain": "Collega l'Ecash all'Onchain", + "peg-out-success": "Inviato Peg Out TX!", + "create-ecash": "Crea nota Ecash", + "ecash-created": "Hai prelevato una nota ecash di {{amount}} dal tuo saldo {{federationName}}. Inviala al destinatario per richiederla.", + "ecash-error": "Errore nella creazione della nota ecash: {{error}}" + } + }, + "federation-card": { + "table-title": "Federazioni", + "id": "ID", + "name": "Nome", + "balance": "Equilibrio", + "actions": "Azione", + "receive": "Ricevi", + "send": "Invia", + "default-federation-name": "Federazione:", + "view-link-on": "Visualizza su {{host}}", + "leave-fed-error": "Non è possibile lasciare la federazione con sats nel tuo saldo. Si prega di ritirare prima i tuoi sats.", + "leave-fed-modal-title": "Lascia la Federazione", + "leave-fed-modal-text": "Sei sicuro di voler interrompere la connessione da", + "view-config": "Visualizza Configurazione", + "config-for": "Configurazione per {{federationId}}" + }, + "header": { + "active": "Attivo", + "all": "Tutti", + "archived": "Archiviato", + "ascending": "Salendo", + "connect": "Collegare la Federazione", + "date-created": "Data di creazione", + "descending": "Scendendo", + "filter": "Filtro", + "sort": "Ordina", + "title": "Portale di controllo Lightning Gateway" + }, + "info-card": { + "card-header": "Informazioni sul Nodo Lightning", + "node-id": "ID del nodo", + "alias": "Pseudonimo", + "mode": "Modalità", + "pubkey": "Chiave pubblica", + "network": "Rete", + "block-height": "Altezza del blocco", + "synced-to-chain": "Sincronizzato alla Catena" + }, + "withdraw-card": { + "address-label": "Il tuo indirizzo:", + "address-placeholder": "Inserisci il tuo indirizzo btc", + "amount-label": "Quantità (sats):", + "amount-placeholder": "Inserisci l'importo in sats", + "card-header": "Preleva Bitcoin", + "close": "Chiudi", + "confirm-withdraw": "Conferma il prelievo", + "error": "Errore", + "error-address": "L'importo o l'indirizzo non possono essere vuoti", + "error-amount": "La quantità non può essere vuota o uguale a zero", + "error-request": "Impossibile richiedere il prelievo", + "request-from": "Richiesta di prelievo da", + "requested-withdrawal": "Richiesta di prelievo", + "to": "a", + "total_bitcoin": "Totale Bitcoin:", + "transaction-sent": "Transazione inviata!", + "view": "Vista", + "view-it-on": "Visualizzalo su", + "withdraw": "Ritirare", + "withdraw-all": "Ritira tutto", + "withdrawal-created": "Creazione del prelievo effettuata.", + "withdrawal-created-description": "Per favore controlla la tua cronologia delle transazioni", + "withdrawal-history": "Storia dei prelievi", + "your-transaction": "Il tuo ID transazione:" + } +} diff --git a/apps/router/src/languages/ja.json b/apps/router/src/languages/ja.json new file mode 100644 index 000000000..aa48219e2 --- /dev/null +++ b/apps/router/src/languages/ja.json @@ -0,0 +1,486 @@ +{ + "common": { + "bitcoin": "ビットコイン", + "next": "次の", + "back": "バック", + "unknown": "不明", + "remove": "削除する", + "copy": "コピー", + "copied": "コピーしました!", + "cancel": "キャンセル", + "review": "レビュー", + "approvals": "承認", + "approve": "承認する", + "threshold": "閾値", + "confirm": "確認する", + "you": "あなた", + "close": "閉じる", + "save": "保存", + "continue": "続ける", + "submit": "提出する", + "address": "住所", + "amount": "金額", + "btc": "BTC", + "error": "エラー", + "sats": "サツ", + "msats": "ミサツ", + "uri": "URI", + "view-on-mempool": "Mempoolを表示する", + "ecash": "電子マネー" + }, + "notConfigured": { + "title": "設定されていません", + "description": "Fedimintガーディアンサーバーを指すためのCONFIG_API_URLを入力してください。" + }, + "connect-guardians": { + "invite-guardians": "フォロワーを招待する", + "invite-guardians-help": "このリンクを他のガーディアンと共有してください。", + "approve": "承認する", + "approved": "承認済み", + "pending": "保留中", + "not-joined": "参加していません", + "waiting-for-guardian": "保護者を待っています", + "table-title": "連邦ガーディアンズ", + "table-description": "ガーディアンは、連盟の設定を確認するとここで確認されます。", + "meta-field-key": "メタフィールド - {{key}}" + }, + "federation-dashboard": { + "invite-members": "メンバーを招待するか、保護者として認証する", + "invite-members-prompt": "これを共有して、連盟にメンバーを招待します。", + "fed-info": { + "label": "連盟情報", + "your-status-label": "ステータス", + "block-count-label": "合意ブロック高さ", + "api-version-label": "APIバージョン", + "consensus-version-label": "合意版", + "peer-id-label": "ピアID", + "session-info": { + "session-height": "セッションの高さ", + "latest-session": "最新のセッション" + } + }, + "balance": { + "label": "貸借対照表" + }, + "bitcoin-node": { + "label": "ビットコインノード", + "url-label": "URL", + "network-label": "ネットワーク" + }, + "guardians": { + "label": "他のガーディアンズ", + "id-name-label": "ID:名前", + "status-label": "接続状況", + "health-label": "健康", + "health-issue": "問題", + "health-good": "良い", + "last-contribution-label": "最終セッションの貢献", + "api-url-label": "API URL", + "fetching-announcement": "アナウンスを取得中..." + }, + "gateways": { + "label": "ライトニングゲートウェイ", + "node-id-label": "ライトニングノードID", + "gateway-id-label": "ゲートウェイID", + "fee-label": "ゲートウェイ料金", + "view-on-site": "{{site}}で表示する", + "no-gateways-info-title": "まだ接続されたゲートウェイはありません!", + "no-gateways-info-description": "ライトニングノードの運用者は、ライトニングネットワークの相互運用性を提供するためにあなたの連合に接続することができます。接続されると、彼らはここに表示されます。" + }, + "api-announcements": { + "label": "APIのお知らせ", + "guardian": "ガーディアン", + "api-url": "API URL", + "revision": "改訂" + }, + "config": { + "label": "連邦設定", + "view-config": "設定を表示", + "missing-meta-module": "メタフィールドの編集はできません。この連合ではメタモジュールが利用できません。", + "manage-meta": { + "label": "メタを管理する", + "cancel-button": "キャンセル", + "confirm-modal": { + "title": "承認を確認する", + "description": "あなたの承認により、このメタの変更を採用する閾値に達します。あなたの新しいメタは次のようになります:" + }, + "consensus-meta-label": "現在のメタコンセンサス", + "revoke-button": "取り消す", + "no-consensus-meta-message": "合意にメタは存在しません", + "proposed-meta-label": "メタ提案", + "propose-meta": "メタを提案する", + "propose-new-meta-button": "新しいメタを提案する", + "proposal-approved": "あなたはこの提案を承認しました", + "no-submitted-meta-message": "レビューするメタ編集はありません", + "edit-meta-label": "メタを編集する", + "edit-consensus-meta-button": "編集合意メタ", + "submit-meta-proposal": "メタ提案を提出する", + "peer-approvals": "ピア承認", + "actions": "行動", + "revision": "改訂", + "setup-meta-title": "あなたの連盟のためのメタを設定する", + "setup-meta-description": "Fedimintは、クライアントと共有したい任意の情報を持つキー値ペアの形式のメタフィールドとして、クライアントに追加情報を提供することができます。これらのメタフィールドはFedimintによって解釈されませんが、合意が必要であり、つまり、連邦メンバー間で異なることはできません。このようにして、クライアントはその正確さに依存することができ", + "propose-updates": "フェディミントガーディアンとして、他のガーディアンに受け入れられるメタへの更新を提案することができます。更新がガーディアンの閾値によって受け入れられると、それは連邦の新しいコンセンサスメタとして採用されます。", + "core-meta-fields": "次のメタフィールドは、コアFedimintプロトコルの一部として定義されており、あなたの連合のメタに含めると便利です:", + "meta-field-expiry": "連邦がシャットダウンするUnixタイムスタンプ。", + "meta-field-name": "連邦の人間が読める名前", + "meta-field-icon": "連盟のロゴアイコンへのURL", + "meta-field-welcome": "連盟に参加する新規ユーザーへの歓迎メッセージ", + "meta-field-gateways": "連盟が審査したゲートウェイ識別子のリスト", + "your-own-fields": "あなたは提案に独自の任意のメタフィールドを追加することもできます。これらは、あなたの連合に接続するすべてのクライアントのメタに追加され、あなたが好きな目的で使用することができます。", + "meta-effect-add": "追加する", + "meta-effect-modify": "修正する", + "meta-effect-unchanged": "変わらず", + "proposals": "提案" + } + }, + "modal": { + "client-connect": "クライアントを接続する" + }, + "danger-zone": { + "danger-zone-label": "危険地帯", + "cancel": "キャンセル", + "danger-zone-description": "注意して使用してください!", + "guardian-warning-message": "警告:このコードを誰とも共有しないでください。このコードを持っている人は誰でもガーディアンとして認証できます。プライベートな場所にいて、誰もあなたの画面を見ていないことを確認してください。", + "guardian-acknowledge": "コードを認識し、公開する", + "acknowledge-and-download": "認識して進む", + "guardian-authenticate": "ガーディアンとして認証する", + "guardian-connect-warning": "この情報を共有しないでください", + "backup": { + "label": "バックアップ", + "title": "バックアップをダウンロードする", + "warning-title": "警告", + "warning-text": "このバックアップには、連邦ガーディアンのプライベートキーと秘密情報が含まれており、安全に保管する必要があります。このバックアップを使用した復旧には、あなたの管理者パスワードが必要です!", + "cancelButton": "キャンセル", + "acknowledgeButton": "認識してダウンロードする" + }, + "sign-api-announcement": { + "label": "APIのお知らせ", + "title": "APIの発表に関するサイン", + "description": "新しいAPI発表の署名を行う。", + "current-api-url": "ローカル設定からのAPI URL", + "announced-api-url": "連盟アナウンスからのあなたのAPI URL", + "urls-match": "あなたの現在のAPI URLは、発表されたAPI URLと一致しています。", + "urls-mismatch": "あなたはローカル設定でAPI URLを変更し、新しいAPIアナウンスをブロードキャストする必要があります。", + "sign-button": "新しいAPIの発表を署名する", + "signing-in-progress": "サインイン進行中...", + "sign-tooltip": "連盟にあなたのAPI URLを発表するために、API発表に署名してください。" + }, + "schedule-shutdown": { + "label": "シャットダウンのスケジュール設定", + "title": "シャットダウンのスケジュール設定", + "description": "特定のセッション高さ後にガーディアンノードのシャットダウンをスケジュールし、fedimintdバイナリの調整されたアップグレードを行ってください。", + "current-session": "現在のセッション", + "session-to-shutdown": "セッションをシャットダウンするために", + "confirm-shutdown": "シャットダウンの確認", + "session-to-shutdown-helper": "ガーディアンノードをシャットダウンしたいセッションの高さを入力してください。" + } + } + }, + "login": { + "title": "おかえりなさい!", + "subtitle": "パスワードを入力してください。", + "password": "パスワード", + "submit": "提出する" + }, + "role-selector": { + "disclaimer-title": "Fedimintはベータ版ソフトウェアです", + "disclaimer-text": "問題はhttps://github.com/fedimint/fedimint/issues で報告してください。", + "leader": { + "label": "リーダーの設定", + "description": "他のガーディアンが承認する設定を入力します。1人のガーディアンがセットアップリーダーとして行動します。" + }, + "follower": { + "label": "フォロワー", + "description": "セットアップリーダーが設定を行うと、他のガーディアンはこのオプションを選択して設定を承認し、連邦を作成します。" + }, + "solo": { + "label": "ソロ", + "description": "Fedimintを単独のガーディアンとして、合意形成、フォールトトレランス、連携バックアップ、またはFedimintのその他のレジリエンスの利点なしで運用します。注意して進めてください、本番環境での使用は意図されていません。" + }, + "warning-modal": { + "title": "皆さん、準備はできていますか?", + "description": "セットアップの儀式を途中で終了すると、セットアップが失敗し、ガーディアンの再起動が必要になる可能性があります。続行する前に、全員が完全なセットアップを実行する準備ができていることを確認してください!" + } + }, + "run-dkg": { + "error-config": "分散キー生成の実行に失敗しました。連携設定を再開する必要があります。", + "error-default": "DKGに対して準備ができていません、あなたの現在のステータスは", + "error-header": "何かが間違ってしまった。", + "waiting-header": "ピアを待っています", + "generating-header": "コードを生成する" + }, + "set-config": { + "bft-explanation-title": "あなたの連盟のビザンチン障害許容性", + "bft-explanation": "{{total}}ガーディアン連盟は{{honest}}/{{total}}の閾値を作ります。", + "bft-faulty": "あなたの連盟は、故障している、オフラインの、または悪意のあるガーディアンを{{faulty}}人まで許容することができ、連盟の運営に影響を与えません。", + "guardian-name": "保護者の名前", + "guardian-name-help": "このランダムな名前は、セットアップ中に他のガーディアンに表示されます。", + "acknowledge-backed-up": "私、{{guardianName}}(あなたの保護者の名前)は、パスワードをバックアップし、安全に保管したことを約束します。", + "admin-password": "管理者パスワード", + "admin-password-generate": "生成する", + "admin-password-set": "生成'をクリックして、安全なパスワードを作成します。それを修正することはできますが、このパスワードは安全でバックアップが必要です!", + "admin-password-help": "このパスワードをバックアップして安全に保管してください!このパスワードは回復できません!", + "admin-password-backup": "私は強力なパスワードを使用しており、バックアップも取っています。(このパスワードは回復できません!)", + "confirm-and-backup-password": "パスワードの確認とバックアップ", + "confirm-password": "パスワードを確認する", + "error-password-mismatch": "パスワードが一致しません", + "join-federation": "連盟リンクに参加する", + "join-federation-help": "連盟を作成した人にリンクを求め、それをここに貼り付けてください。", + "basic-settings": "基本事項", + "federation-settings": "連邦設定", + "federation-name": "連盟名", + "guardian-number": "保護者の数", + "guardian-number-help": "連盟は最低4人のガーディアンが必要です。これは後から変更することはできません。", + "bitcoin-settings": "ビットコインの設定", + "block-confirmations": "追加のブロック確認", + "block-confirmations-help": "Fedimint Guardiansはブロックの再編成を避けるために、ブロックチェーンの先端をいくつかの確認で後追いします。", + "block-confirmations-help-mainnet": "メインネットでの実行には少なくとも5つの追加確認が必要です。", + "block-confirmations-warning": "5つ未満の追加ブロック確認でFedimintを実行することは非常にリスキーです!Fedimintはブロックチェーンの再編成を処理できません。", + "bitcoin-network": "ビットコインネットワーク", + "select-network": "ネットワークを選択してください", + "bitcoin-rpc-kind": "Bitcoin RPCの種類", + "set-rpc-help": "あなたのガーディアンノードのためのビットコインブロックデータのソース", + "bitcoin-rpc": "Bitcoin RPC URL", + "read-from-env": "(環境変数から検出されました)", + "error-valid-number": "有効な数字を入力してください。", + "error-valid-min": "少なくとも{{min}}の数値を入力してください。", + "error-valid-max": "最大で{{max}}までの数値を入力してください。", + "error-valid-min-max": "{{min}} と {{max}} の間の数字を入力してください。", + "error-guardian-name-mismatch": "保護者の名前が一致しません", + "meta-fields": "メタフィールド", + "meta-fields-description": "詳細については、ドキュメンテーションをご覧ください。", + "meta-fields-key": "メタキー", + "meta-fields-value": "価値", + "meta-fields-effect": "効果", + "meta-fields-add-another": "別のを追加する", + "meta-fields-title": "あなたのメタ提案:", + "network": "ネットワーク", + "password-warning-title": "パスワードをバックアップしてください!", + "password-warning": "パスワードをバックアップし、安全に保管する必要があります。このパスワードはガーディアンダッシュボードにアクセスするために必要です。それを失った場合、回復することはできません!" + }, + "setup": { + "warning": { + "title": "セットアップ中は終了または更新しないでください!", + "description": "セットアップ中に終了すると、セットアップが失敗し、最初からやり直す必要があります。" + }, + "common": { + "restart-setup": "セットアップを再開する", + "restart-setup-alert": "セットアップリーダーがセットアップセレモニーを再開しました。続行するには下の「再開」をクリックしてください。", + "confirm-restart-setup": "セットアップセレモニーを再開しますか、本当によろしいですか?", + "confirm-restart-setup-alert": "再開\"をクリックすると、すべてのガーディアンのための式典が再開されます。" + }, + "progress": { + "tos": { + "title": "利用規約" + }, + "start": { + "title": "ようこそ、ガーディアン!", + "subtitle": "あなたの連邦を設定しましょう。", + "step": "連盟の詳細" + }, + "set-config": { + "title": "あなたの連盟のためにいくつかの設定を行う必要があります。", + "title-solo": "あなたのソロフェデレーションのためのいくつかの設定を行う必要があります。", + "subtitle-leader": "あなたの連盟のフォロワーは、彼らの側でこの情報を確認します。", + "subtitle-solo": "ソロフェデレーションを運用すると、Fedimintの多くの利点が失われます。ガーディアンがオフラインであるときのフォールトトレランスコンセンサスが利用できず、連携バックアップもできません。注意して進めてください、本番環境やメインネットのビットコインでの使用は推奨されません。", + "subtitle-follower": "あなたの連盟リーダーが主要な連盟の詳細を設定します。まもなくそれらを確認します。", + "step": "連邦詳細" + }, + "connect-guardians": { + "title-leader": "あなたのガーディアンを招待してください", + "title-follower": "あなたの連盟情報を確認してください", + "subtitle-leader": "リンクを他のガーディアンと共有して、全員を同じページに揃えましょう。全てのガーディアンが参加したら、自動的に次のステップに進みます。", + "subtitle-follower": "ここに表示される情報が正しいこと、そして連邦ガーディアンが正確であることを確認してください。それが良好に見えることを確認したら、承認ボタンをクリックしてください。", + "step-leader": "ガーディアンを招待する", + "step-follower": "情報を確認する" + }, + "run-dkg": { + "title": "成功!", + "subtitle": "すべてのガーディアンが連邦設定の詳細を検証しました。いくつかの数字を計算中..." + }, + "verify-guardians": { + "title": "あなたのガーディアンを確認してください", + "subtitle": "各ガーディアンに確認コードを尋ね、それを以下に貼り付けて有効性を確認してください。もうすぐ終わります!", + "step": "ガーディアンを確認する", + "leader-confirm-done": "すべてのフォロワーのガーディアンが「次へ」をクリックし、そのガーディアンダッシュボードを確認したことを確認してから続けてください。", + "leader-confirm-done-emphasis": "続行\"をクリックすると、セットアップの儀式が完了します。" + }, + "setup-complete": { + "step": "完了!" + }, + "error": { + "title": "未知のステップ", + "subtitle": "あなたはどうやってここに来たの?!" + } + } + }, + "setup-complete": { + "header": "🎉 🎉 🎉", + "congratulations": "おめでとうございます", + "leader-message": "すべてのガーディアンの確認コードが確認されました。", + "follower-message": "すべて終わりました!他のガーディアンにあなたが走っていることを知らせてください!", + "continue": "続ける" + }, + "terms-of-service": { + "agree-and-continue": "同意して続行" + }, + "verify-guardians": { + "verified": "確認済み", + "verified-placeholder": "ここにコードを貼り付けてください。", + "error": "何かが間違ってしまいました。", + "error-peer-id": "あなたがどのピアであるかを判断できません。リフレッシュしてもう一度お試しください。", + "verification-code": "あなたの({{peerName}})確認コード", + "verification-code-help": "このコードを他のガーディアンと共有してください。", + "table-title": "ガーディアン確認コード", + "table-description": "以下に各ガーディアンの確認コードを入力してください。", + "table-column-name": "名前", + "table-column-status": "ステータス", + "table-column-hash-input": "確認コードを貼り付けてください", + "wait-all-guardians-verification": "すべてのガーディアンがコードを確認するのを待っています", + "all-guardians-verified": "すべてのガーディアンが自分のコードを確認しました", + "starting-consensus": "合意形成を開始します..." + }, + "footer": { + "docs-section-header": "ドキュメント", + "community-section-header": "コミュニティ", + "contribute-section-header": "貢献する", + "getting-started-link-text": "開始する", + "faq-link-text": "よくある質問", + "blog-link-text": "ブログ", + "discord-link-text": "ディスコード", + "twitter-link-text": "ツイッター", + "github-link-text": "GitHub" + }, + "admin": { + "fetch-info-modal-text": "連邦詳細を確認中..." + }, + "balance-card": { + "card_header": "eCash残高", + "sentence": "サトシで表記された", + "your-balance": "この連盟でのあなたのeCash残高:" + }, + "connect-federation": { + "connect": "接続 🚀", + "connect-federation-button": "連邦を追加", + "connection-string-placeholder": "連携招待コードを貼り付けてください", + "heading": "招待コードを使用して連邦に接続します", + "information-bar-text": "あなたが接続できる連盟の数は1つに制限されています。複数の連盟への接続は近くサポートされる予定です。", + "label": "接続文字列:", + "progress-modal-text": "連盟に接続中...", + "sub-heading": "招待コードは「fed1」で始まる長い文字列です。", + "error-message": "連搭先への接続エラー:{{error}}" + }, + "wallet": { + "title": "財布", + "ecash": "電子マネー", + "lightning": "稲妻", + "onchain": "オンチェーン", + "total": "合計", + "balance": "バランス", + "address": "住所", + "invoice": "請求書", + "receive": "受け取る", + "send": "送信する", + "create-address": "住所を作成する", + "to-federation": "連邦へ", + "from-federation": "連邦から", + "sent": "返信", + "sent-amount": "{{amount}}を送信しました", + "to-address": "宛先に", + "txid": "取引ID", + "claimed-note": "主張されたノート", + "claimed-amount": "請求額" + }, + "wallet-modal": { + "title": "ウォレットの操作", + "receive": { + "ecash-instructions": "ここにあなたの電子現金ノートを貼り付けてください。", + "paste-ecash-placeholder": "ここに電子現金ノートを貼り付けてください。", + "redeem": "兌換する", + "paste-invoice": "ここに請求書を貼り付けてください。", + "enter-amount": "{{unit}}で金額を入力してください", + "lightning-instructions": "Lightning請求書を作成するためにsatsで金額を入力してください。", + "create-peg-in-address": "ペグインアドレスを作成する", + "create-lightning-invoice": "ライトニングインボイスを作成する", + "paste-ecash-button": "電子現金ノートを貼り付ける", + "peg-in-instructions": "このアドレスにビットコインを送信して、{{federationName}} Ecashバランスにペグインしてください。", + "ecash-claimed-success": "Ecashの請求に成功しました!", + "address-error": "アドレスの作成エラー: {{error}}" + }, + "send": { + "submit": "提出する", + "to-onchain-address": "オンチェーンアドレスへ", + "address-placeholder": "bc1p...", + "peg-out-to-onchain": "Peg Out EcashをOnchainに変換する", + "peg-out-success": "Peg Out TX送信完了!", + "create-ecash": "Ecashノートを作成する", + "ecash-created": "あなたの{{federationName}}の残高から{{amount}} ecashのノートを引き出しました。受取人に送って請求してください。", + "ecash-error": "ecashノートの作成エラー: {{error}}" + } + }, + "federation-card": { + "table-title": "連盟", + "id": "ID", + "name": "名前", + "balance": "バランス", + "actions": "行動", + "receive": "受け取る", + "send": "送信する", + "default-federation-name": "連邦", + "view-link-on": "{{host}}を表示する", + "leave-fed-error": "あなたの残高にサトシがある状態では連邦を離れることはできません。まずサトシを引き出してください。", + "leave-fed-modal-title": "連邦を離れる", + "leave-fed-modal-text": "あなたは本当に切断したいですか?", + "view-config": "設定を表示", + "config-for": "{{federationId}}の設定" + }, + "header": { + "active": "アクティブ", + "all": "すべて", + "archived": "アーカイブ済み", + "ascending": "上昇する", + "connect": "フェデレーションを接続する", + "date-created": "作成日", + "descending": "降下する", + "filter": "フィルター", + "sort": "ソート", + "title": "ライトニングゲートウェイダッシュボード" + }, + "info-card": { + "card-header": "ライトニングノード情報", + "node-id": "ノードID", + "alias": "別名", + "mode": "モード", + "pubkey": "公開鍵", + "network": "ネットワーク", + "block-height": "ブロックの高さ", + "synced-to-chain": "チェーンに同期済み" + }, + "withdraw-card": { + "address-label": "あなたの住所:", + "address-placeholder": "あなたのbtcアドレスを入力してください", + "amount-label": "金額(sats):", + "amount-placeholder": "satsで金額を入力してください", + "card-header": "ビットコインを引き出す", + "close": "閉じる", + "confirm-withdraw": "引き出しを確認する", + "error": "エラー", + "error-address": "金額または住所は空欄にできません", + "error-amount": "金額は空白またはゼロにすることはできません", + "error-request": "引き出しのリクエストに失敗しました", + "request-from": "出金の申請から", + "requested-withdrawal": "出金リクエスト", + "to": "へ", + "total_bitcoin": "合計ビットコイン:", + "transaction-sent": "取引が送信されました!", + "view": "表示", + "view-it-on": "それを見るには", + "withdraw": "引き出す", + "withdraw-all": "すべてを引き出す", + "withdrawal-created": "引き出しが作成されました。", + "withdrawal-created-description": "あなたの取引履歴を確認してください。", + "withdrawal-history": "引き出し履歴", + "your-transaction": "あなたの取引ID:" + } +} diff --git a/apps/router/src/languages/ko.json b/apps/router/src/languages/ko.json new file mode 100644 index 000000000..b28ebd750 --- /dev/null +++ b/apps/router/src/languages/ko.json @@ -0,0 +1,486 @@ +{ + "common": { + "bitcoin": "비트코인", + "next": "다음", + "back": "뒤로", + "unknown": "알 수 없음", + "remove": "제거하다", + "copy": "복사", + "copied": "복사됨!", + "cancel": "취소", + "review": "리뷰", + "approvals": "승인들", + "approve": "승인하다", + "threshold": "임계값", + "confirm": "확인하다", + "you": "당신", + "close": "닫기", + "save": "저장", + "continue": "계속하다", + "submit": "제출하다", + "address": "주소", + "amount": "금액", + "btc": "BTC", + "error": "오류", + "sats": "새츠", + "msats": "msats", + "uri": "URI", + "view-on-mempool": "Mempool에서 보기", + "ecash": "전자현금" + }, + "notConfigured": { + "title": "구성되지 않음", + "description": "Fedimint 가디언 서버를 가리키려면 CONFIG_API_URL을 입력해 주세요." + }, + "connect-guardians": { + "invite-guardians": "팔로워 초대하기", + "invite-guardians-help": "이 링크를 다른 가디언들과 공유하세요.", + "approve": "승인하다", + "approved": "승인됨", + "pending": "보류 중", + "not-joined": "가입하지 않음", + "waiting-for-guardian": "보호자를 기다리는 중", + "table-title": "연합 수호자들", + "table-description": "가디언들은 연맹 설정을 확인하면 여기에서 확인됩니다.", + "meta-field-key": "메타 필드 - {{key}}" + }, + "federation-dashboard": { + "invite-members": "회원을 초대하거나 보호자로 인증하세요.", + "invite-members-prompt": "이것을 공유하여 회원들이 연합에 가입하도록 초대하세요", + "fed-info": { + "label": "연합 정보", + "your-status-label": "상태", + "block-count-label": "합의 블록 높이", + "api-version-label": "API 버전", + "consensus-version-label": "합의된 버전", + "peer-id-label": "피어 ID", + "session-info": { + "session-height": "세션 높이", + "latest-session": "최근 세션" + } + }, + "balance": { + "label": "대차대조표" + }, + "bitcoin-node": { + "label": "비트코인 노드", + "url-label": "URL", + "network-label": "네트워크" + }, + "guardians": { + "label": "다른 수호자들", + "id-name-label": "ID: 이름", + "status-label": "연결 상태", + "health-label": "건강", + "health-issue": "문제", + "health-good": "좋은", + "last-contribution-label": "마지막 세션 기여", + "api-url-label": "API URL", + "fetching-announcement": "공지사항 가져오는 중..." + }, + "gateways": { + "label": "번개 게이트웨이", + "node-id-label": "번개 노드 ID", + "gateway-id-label": "게이트웨이 ID", + "fee-label": "게이트웨이 수수료", + "view-on-site": "{{site}}에서 보기", + "no-gateways-info-title": "아직 연결된 게이트웨이가 없습니다!", + "no-gateways-info-description": "라이트닝 노드 운영자는 여러분의 연합에 연결하여 라이트닝 네트워크 상호 운용성을 제공할 수 있습니다. 연결되면 그들은 여기에 표시될 것입니다." + }, + "api-announcements": { + "label": "API 공지사항", + "guardian": "가디언", + "api-url": "API URL", + "revision": "개정" + }, + "config": { + "label": "연합 구성", + "view-config": "구성 보기", + "missing-meta-module": "메타 필드를 편집하는 것은 불가능합니다. 이 연합에는 메타 모듈이 사용할 수 없습니다.", + "manage-meta": { + "label": "메타 관리", + "cancel-button": "취소", + "confirm-modal": { + "title": "승인 확인", + "description": "당신의 승인이 이 메타 변경을 채택하기 위한 임계점에 도달할 것입니다. 당신의 새로운 메타는 다음과 같이 보일 것입니다:" + }, + "consensus-meta-label": "현재 합의에 대한 메타", + "revoke-button": "철회하다", + "no-consensus-meta-message": "합의에 메타는 없습니다", + "proposed-meta-label": "메타 제안들", + "propose-meta": "메타 제안하기", + "propose-new-meta-button": "새 메타 제안하기", + "proposal-approved": "이 제안을 승인하셨습니다.", + "no-submitted-meta-message": "리뷰할 메타 편집이 없습니다.", + "edit-meta-label": "메타 편집", + "edit-consensus-meta-button": "편집 합의 메타", + "submit-meta-proposal": "메타 제안 제출", + "peer-approvals": "동료 승인", + "actions": "행동들", + "revision": "개정", + "setup-meta-title": "당신의 연합을 위한 메타 설정하기", + "setup-meta-description": "Fedimint는 메타 필드 형태로 클라이언트에게 추가 정보를 제공할 수 있습니다: 클라이언트와 공유하고 싶은 임의의 정보를 가진 키-값 쌍입니다. 이 메타 필드는 Fedimint에 의해 해석되지 않지만, 합의에 관련된 것이므로 연합 회원 간에 차이가 있을 수 없습니다. 이런 방식으로 클라이언트는 그들의 정확성에 의존할 수 있습니다.", + "propose-updates": "페디민트 가디언으로서, 다른 가디언들이 수락할 메타에 대한 업데이트를 제안할 수 있습니다. 업데이트가 일정 수준의 가디언들에 의해 수락되면, 그것은 연합의 새로운 합의 메타로 채택될 것입니다.", + "core-meta-fields": "다음 메타 필드는 핵심 Fedimint 프로토콜의 일부로 정의되었으며, 귀하의 연합의 메타에 포함하는 것이 유용합니다:", + "meta-field-expiry": "연합이 종료될 유닉스 타임스탬프.", + "meta-field-name": "연합의 사람이 읽을 수 있는 이름", + "meta-field-icon": "연맹을 위한 로고 아이콘의 URL", + "meta-field-welcome": "연합에 가입하는 새로운 사용자를 위한 환영 메시지", + "meta-field-gateways": "연맹이 검증한 게이트웨이 식별자 목록", + "your-own-fields": "제안서에 임의의 메타 필드를 추가할 수도 있습니다. 이들은 연합에 연결된 모든 클라이언트의 메타에 추가되며, 원하는 목적에 따라 사용할 수 있습니다.", + "meta-effect-add": "추가", + "meta-effect-modify": "수정하다", + "meta-effect-unchanged": "변경되지 않음", + "proposals": "제안들" + } + }, + "modal": { + "client-connect": "클라이언트 연결" + }, + "danger-zone": { + "danger-zone-label": "위험 지역", + "cancel": "취소", + "danger-zone-description": "주의해서 사용하십시오!", + "guardian-warning-message": "경고: 이 코드를 누구와도 공유하지 마십시오. 이 코드를 가진 사람은 가디언으로 인증할 수 있습니다. 개인적인 장소에 있고 화면을 보는 사람이 없는지 확인하십시오.", + "guardian-acknowledge": "인정하고 코드를 공개하다", + "acknowledge-and-download": "인정하고 진행하십시오", + "guardian-authenticate": "보호자로 인증하십시오", + "guardian-connect-warning": "이것을 공유하지 마세요", + "backup": { + "label": "백업", + "title": "백업 다운로드", + "warning-title": "경고", + "warning-text": "백업에는 연합 가디언의 개인 키와 비밀 자료가 포함되어 있으며, 안전하게 보관해야 합니다. 이 백업을 사용한 복구는 관리자 비밀번호가 필요합니다!", + "cancelButton": "취소", + "acknowledgeButton": "인정 및 다운로드" + }, + "sign-api-announcement": { + "label": "API 공지 사항", + "title": "API 공지 사항", + "description": "새로운 API 공지 사항에 서명하십시오.", + "current-api-url": "로컬 설정에서의 API URL", + "announced-api-url": "연합 공지사항에서의 API URL", + "urls-match": "현재 API URL이 공지된 API URL과 일치합니다.", + "urls-mismatch": "당신은 로컬 설정에서 API URL을 변경했고 새로운 API 공지를 전송해야 합니다.", + "sign-button": "새 API 공지 사항 서명", + "signing-in-progress": "로그인 진행 중...", + "sign-tooltip": "연합에게 당신의 API URL을 알리기 위해 API 공지를 서명하세요." + }, + "schedule-shutdown": { + "label": "컴퓨터 종료 예약", + "title": "컴퓨터 종료 일정 설정", + "description": "특정 세션 높이 후에 가디언 노드를 종료하도록 스케줄링하여 fedimintd 바이너리의 조정된 업그레이드를 진행하세요.", + "current-session": "현재 세션", + "session-to-shutdown": "세션 종료 예정 시간에", + "confirm-shutdown": "종료 확인", + "session-to-shutdown-helper": "가디언 노드를 종료하려는 세션 높이를 입력하세요." + } + } + }, + "login": { + "title": "다시 오신 것을 환영합니다!", + "subtitle": "비밀번호를 입력해 주세요.", + "password": "비밀번호", + "submit": "제출하다" + }, + "role-selector": { + "disclaimer-title": "Fedimint는 베타 소프트웨어입니다", + "disclaimer-text": "문제점은 https://github.com/fedimint/fedimint/issues 에 보고해 주세요.", + "leader": { + "label": "리더 설정", + "description": "다른 가디언들이 승인하는 구성 설정을 입력하세요. 한 명의 가디언이 설정 리더로 활동합니다." + }, + "follower": { + "label": "팔로워", + "description": "설정 리더가 구성을 설정하면 다른 가디언들이 이 옵션을 선택하여 설정을 승인하고 연합을 만듭니다." + }, + "solo": { + "label": "솔로", + "description": "Fedimint를 합의, 장애 허용, 연합 백업 또는 Fedimint의 기타 복원력 이점 없이 Solo Guardian으로 운영하십시오. 주의해서 진행하십시오, 생산용으로 사용하기 위한 것이 아닙니다." + }, + "warning-modal": { + "title": "모두 준비되셨나요?", + "description": "설정 절차를 중단하면 설정이 실패하고 보호자를 다시 시작해야 할 수 있습니다. 계속하기 전에 모두가 전체 설정을 실행할 준비가 되었는지 확인하세요!" + } + }, + "run-dkg": { + "error-config": "분산 키 생성을 실행하는 데 실패했습니다. 연합 설정을 다시 시작해야 합니다.", + "error-default": "DKG에 대비되지 않았습니다, 현재 상태는", + "error-header": "뭔가 잘못되었습니다.", + "waiting-header": "피어들을 기다리는 중", + "generating-header": "코드 생성 중" + }, + "set-config": { + "bft-explanation-title": "당신의 연합의 비잔틴 장애 허용", + "bft-explanation": "{{total}} 가디언 연맹은 {{honest}}/{{total}} 임계치를 만듭니다.", + "bft-faulty": "당신의 연합은 {{faulty}}개의 결함이 있는, 오프라인 상태인, 또는 악의적인 가디언들을 운영에 영향을 주지 않고 용인할 수 있을 것입니다.", + "guardian-name": "보호자 이름", + "guardian-name-help": "이 무작위 이름은 설정 중에 다른 가디언들에게 표시됩니다.", + "acknowledge-backed-up": "나, {{guardianName}} (당신의 보호자 이름),는 내 비밀번호를 백업하고 안전하게 보관했다는 것을 약속합니다.", + "admin-password": "관리자 비밀번호", + "admin-password-generate": "생성하다", + "admin-password-set": "생성'을 클릭하여 안전한 비밀번호를 생성하세요. 수정할 수 있지만, 이 비밀번호는 안전해야 하며 백업이 되어야 합니다!", + "admin-password-help": "이 비밀번호를 백업하고 안전하게 보관하세요! 이 비밀번호는 복구할 수 없습니다!", + "admin-password-backup": "나는 강력한 비밀번호를 사용하고 백업해 두었습니다. (이 비밀번호는 복구할 수 없습니다!)", + "confirm-and-backup-password": "비밀번호 확인 및 백업", + "confirm-password": "비밀번호 확인", + "error-password-mismatch": "비밀번호가 일치하지 않습니다.", + "join-federation": "연합 가입 링크", + "join-federation-help": "연합을 만든 사람에게 링크를 요청하고, 여기에 붙여넣으세요.", + "basic-settings": "기본 사항", + "federation-settings": "연합 설정", + "federation-name": "연합 이름", + "guardian-number": "보호자의 수", + "guardian-number-help": "연맹은 최소 4명의 보호자가 필요합니다. 이는 나중에 변경할 수 없습니다.", + "bitcoin-settings": "비트코인 설정", + "block-confirmations": "추가 블록 확인", + "block-confirmations-help": "Fedimint 가디언들은 블록 재구성을 피하기 위해 블록체인의 끝을 몇 번의 확인을 거쳐 추적합니다.", + "block-confirmations-help-mainnet": "메인넷에서 실행하려면 최소 5회 추가 확인이 필요합니다.", + "block-confirmations-warning": "5개 미만의 추가 블록 확인으로 Fedimint를 실행하는 것은 매우 위험합니다! Fedimint는 블록체인 재구성을 처리할 수 없습니다.", + "bitcoin-network": "비트코인 네트워크", + "select-network": "네트워크 선택", + "bitcoin-rpc-kind": "비트코인 RPC 종류", + "set-rpc-help": "당신의 가디언 노드를 위한 비트코인 블록 데이터의 출처", + "bitcoin-rpc": "비트코인 RPC URL", + "read-from-env": "(환경 변수에서 감지됨)", + "error-valid-number": "유효한 숫자를 입력해 주세요.", + "error-valid-min": "적어도 {{min}}의 숫자를 입력해 주세요.", + "error-valid-max": "{{max}} 이하의 숫자를 입력해 주세요.", + "error-valid-min-max": "{{min}}과 {{max}} 사이의 숫자를 입력해 주세요.", + "error-guardian-name-mismatch": "보호자 이름이 일치하지 않습니다", + "meta-fields": "메타 필드", + "meta-fields-description": "자세한 정보는 문서를 참조하세요.", + "meta-fields-key": "메타 키", + "meta-fields-value": "가치", + "meta-fields-effect": "효과", + "meta-fields-add-another": "다른 것을 추가하다", + "meta-fields-title": "당신의 메타 제안:", + "network": "네트워크", + "password-warning-title": "비밀번호를 백업하세요!", + "password-warning": "반드시 비밀번호를 백업하고 안전하게 보관해야 합니다. 이 비밀번호는 가디언 대시보드에 접근하는 데 필요합니다. 잃어버리면 복구할 수 없습니다!" + }, + "setup": { + "warning": { + "title": "설치 중에 종료하거나 새로 고치지 마세요!", + "description": "설정 중에 종료하면 설정이 실패할 수 있으며, 처음부터 다시 시작해야 할 수 있습니다." + }, + "common": { + "restart-setup": "설정 다시 시작", + "restart-setup-alert": "설정 리더가 설정 의식을 다시 시작했습니다. 계속하려면 아래의 \"다시 시작\"을 클릭해 주세요.", + "confirm-restart-setup": "설정 의식을 다시 시작하길 원하는지 확실한가요?", + "confirm-restart-setup-alert": "재시작\"을 클릭하면 모든 가디언들에 대한 의식이 다시 시작됩니다." + }, + "progress": { + "tos": { + "title": "서비스 이용 약관" + }, + "start": { + "title": "환영합니다, 수호자님!", + "subtitle": "당신의 연합을 설정합시다.", + "step": "연합 세부 사항" + }, + "set-config": { + "title": "우리는 귀하의 연합을 위한 몇 가지 설정을 해야 합니다.", + "title-solo": "당신의 솔로 연맹에 대한 몇 가지 설정을 해야 합니다.", + "subtitle-leader": "당신의 연합 팔로워들이 그들 쪽에서 이 정보를 확인할 것입니다.", + "subtitle-solo": "솔로 페더레이션을 운영하면 Fedimint의 많은 이점을 잃게 됩니다. 가디언이 오프라인 상태일 때 장애 허용 합의를 가질 수 없으며 연합 백업을 수행할 수 없습니다. 주의해서 진행하십시오, 프로덕션 사용이나 메인넷 비트코인 사용에는 권장되지 않습니다.", + "subtitle-follower": "당신의 연합 리더가 주요 연합 세부사항을 설정할 예정입니다. 곧 그것들을 확인하게 될 것입니다.", + "step": "연합 세부사항" + }, + "connect-guardians": { + "title-leader": "당신의 가디언들을 초대하세요", + "title-follower": "연합 정보를 확인하세요", + "subtitle-leader": "다른 가디언들과 링크를 공유하여 모두가 같은 페이지에 있도록 하세요. 모든 가디언들이 참여하면 자동으로 다음 단계로 넘어갑니다.", + "subtitle-follower": "여기의 정보가 올바르게 보이는지, 연합 수호자들이 정확한지 확인하세요. 확실하게 보일 때 승인 버튼을 클릭하세요.", + "step-leader": "가디언들을 초대하십시오", + "step-follower": "정보 확인" + }, + "run-dkg": { + "title": "성공!", + "subtitle": "모든 가디언들이 연방 설정 세부사항을 확인했습니다. 일부 숫자를 실행 중..." + }, + "verify-guardians": { + "title": "당신의 가디언을 확인하세요", + "subtitle": "각 가디언에게 그들의 인증 코드를 요청하고, 아래에 붙여넣어 유효성을 확인하세요. 거의 다 끝났습니다!", + "step": "보호자 확인", + "leader-confirm-done": "모든 팔로워 가디언들이 \"다음\"을 클릭하고 그들의 가디언 대시보드를 확인한 후에 계속 진행하십시오.", + "leader-confirm-done-emphasis": "계속\"을 클릭하면 설정 절차가 완료됩니다." + }, + "setup-complete": { + "step": "완료!" + }, + "error": { + "title": "알 수 없는 단계", + "subtitle": "여기 어떻게 왔어요?!" + } + } + }, + "setup-complete": { + "header": "🎉 🎉 🎉", + "congratulations": "축하합니다", + "leader-message": "모든 가디언의 인증 코드가 확인되었습니다.", + "follower-message": "다 끝났어! 다른 수호자들에게 네가 달리고 있다고 알려줘!", + "continue": "계속하다" + }, + "terms-of-service": { + "agree-and-continue": "동의하고 계속하기" + }, + "verify-guardians": { + "verified": "인증된", + "verified-placeholder": "여기에 코드를 붙여넣으세요.", + "error": "무언가 잘못되었습니다.", + "error-peer-id": "어떤 피어인지 확인할 수 없습니다. 새로 고치고 다시 시도해 주세요.", + "verification-code": "당신({{peerName}})의 인증 코드", + "verification-code-help": "이 코드를 다른 보호자들과 공유하세요.", + "table-title": "가디언 인증 코드", + "table-description": "아래에 각 가디언의 인증 코드를 입력하세요.", + "table-column-name": "이름", + "table-column-status": "상태", + "table-column-hash-input": "인증 코드를 붙여넣기", + "wait-all-guardians-verification": "모든 가디언이 코드를 확인하는 것을 기다리고 있습니다.", + "all-guardians-verified": "모든 가디언들이 그들의 코드를 확인했습니다.", + "starting-consensus": "합의를 시작합니다..." + }, + "footer": { + "docs-section-header": "문서", + "community-section-header": "커뮤니티", + "contribute-section-header": "기여하다", + "getting-started-link-text": "시작하기", + "faq-link-text": "자주 묻는 질문", + "blog-link-text": "블로그", + "discord-link-text": "디스코드", + "twitter-link-text": "트위터", + "github-link-text": "GitHub" + }, + "admin": { + "fetch-info-modal-text": "연합 정보 확인 중..." + }, + "balance-card": { + "card_header": "eCash 잔액", + "sentence": "Sats로 표시된", + "your-balance": "이 연합에서의 귀하의 eCash 잔액:" + }, + "connect-federation": { + "connect": "연결 🚀", + "connect-federation-button": "연합 추가", + "connection-string-placeholder": "연합 초대 코드를 붙여넣으세요.", + "heading": "초대 코드를 사용하여 연합에 연결하세요.", + "information-bar-text": "연결할 수 있는 연맹의 수는 하나로 제한됩니다. 곧 여러 연맹에 연결하는 것이 지원될 예정입니다.", + "label": "연결 문자열:", + "progress-modal-text": "연합에 연결 중...", + "sub-heading": "초대 코드는 'fed1'로 시작하는 긴 문자열입니다.", + "error-message": "연합에 연결하는 중 오류 발생: {{error}}" + }, + "wallet": { + "title": "지갑", + "ecash": "이캐시", + "lightning": "번개", + "onchain": "온체인", + "total": "총계", + "balance": "균형", + "address": "주소", + "invoice": "송장", + "receive": "받다", + "send": "보내다", + "create-address": "주소 생성", + "to-federation": "연합에게", + "from-federation": "연합에서", + "sent": "보냈습니다.", + "sent-amount": "{{amount}} 보냄", + "to-address": "주소 지정하기", + "txid": "거래 ID", + "claimed-note": "주장된 메모", + "claimed-amount": "청구 금액" + }, + "wallet-modal": { + "title": "지갑 작업", + "receive": { + "ecash-instructions": "여기에 전자현금 메모를 붙여넣으세요.", + "paste-ecash-placeholder": "여기에 전자현금 메모를 붙여넣으세요.", + "redeem": "환급하다", + "paste-invoice": "여기에 송장을 붙여넣으세요.", + "enter-amount": "{{unit}} 단위로 금액을 입력하세요.", + "lightning-instructions": "Lightning 인보이스를 생성하기 위해 sats로 금액을 입력하십시오.", + "create-peg-in-address": "페그-인 주소 생성하기", + "create-lightning-invoice": "라이트닝 인보이스 생성", + "paste-ecash-button": "ecash 노트를 붙여넣기", + "peg-in-instructions": "이 주소로 비트코인을 보내서 {{federationName}} 이캐시 잔액에 연동하세요.", + "ecash-claimed-success": "성공적으로 Ecash를 청구했습니다!", + "address-error": "주소 생성 오류: {{error}}" + }, + "send": { + "submit": "제출하다", + "to-onchain-address": "온체인 주소로", + "address-placeholder": "bc1p...", + "peg-out-to-onchain": "Peg Out Ecash를 Onchain에 연결하다", + "peg-out-success": "Peg Out TX 전송 완료!", + "create-ecash": "Ecash 노트 생성하기", + "ecash-created": "당신의 {{federationName}} 잔액에서 {{amount}} ecash 노트를 인출했습니다. 수령인에게 보내서 청구하세요.", + "ecash-error": "ecash 메모 생성 오류: {{error}}" + } + }, + "federation-card": { + "table-title": "연맹들", + "id": "ID", + "name": "이름", + "balance": "균형", + "actions": "행동들", + "receive": "받다", + "send": "보내기", + "default-federation-name": "연합", + "view-link-on": "{{host}}에서 보기", + "leave-fed-error": "당신의 잔고에 사트가 있으면 연맹을 떠날 수 없습니다. 먼저 사트를 인출해 주세요.", + "leave-fed-modal-title": "연합을 떠나다", + "leave-fed-modal-text": "정말로 연결을 끊고 싶으신가요?", + "view-config": "구성 보기", + "config-for": "{{federationId}}에 대한 설정" + }, + "header": { + "active": "활성화된", + "all": "모두", + "archived": "보관된", + "ascending": "오름차순", + "connect": "연합 연결", + "date-created": "생성된 날짜", + "descending": "하강하는", + "filter": "필터", + "sort": "정렬", + "title": "번개 게이트웨이 대시보드" + }, + "info-card": { + "card-header": "번개 노드 정보", + "node-id": "노드 ID", + "alias": "별명", + "mode": "모드", + "pubkey": "공개키", + "network": "네트워크", + "block-height": "블록 높이", + "synced-to-chain": "체인에 동기화됨" + }, + "withdraw-card": { + "address-label": "당신의 주소:", + "address-placeholder": "당신의 btc 주소를 입력하세요", + "amount-label": "금액 (sats):", + "amount-placeholder": "sats로 금액을 입력하세요", + "card-header": "비트코인 인출", + "close": "닫기", + "confirm-withdraw": "출금 확인", + "error": "오류", + "error-address": "금액 또는 주소는 비어 있을 수 없습니다.", + "error-amount": "금액은 비어 있거나 0이 될 수 없습니다.", + "error-request": "출금 요청에 실패했습니다", + "request-from": "출금 요청함에서", + "requested-withdrawal": "출금 요청", + "to": "에", + "total_bitcoin": "총 비트코인:", + "transaction-sent": "거래 전송됨!", + "view": "보기", + "view-it-on": "그것을 보세요", + "withdraw": "인출하다", + "withdraw-all": "모두 출금하다", + "withdrawal-created": "출금 생성됨.", + "withdrawal-created-description": "거래 내역을 확인해 주세요.", + "withdrawal-history": "출금 내역", + "your-transaction": "당신의 거래 ID:" + } +} diff --git a/apps/router/src/languages/pt.json b/apps/router/src/languages/pt.json new file mode 100644 index 000000000..fd6b47553 --- /dev/null +++ b/apps/router/src/languages/pt.json @@ -0,0 +1,486 @@ +{ + "common": { + "bitcoin": "Bitcoin", + "next": "Próximo", + "back": "De volta", + "unknown": "Desconhecido", + "remove": "Remover", + "copy": "Cópia", + "copied": "Copiado!", + "cancel": "Cancelar", + "review": "Revisão", + "approvals": "Aprovações", + "approve": "Aprovar", + "threshold": "Limiar", + "confirm": "Confirmar", + "you": "Você", + "close": "Fechar", + "save": "Salvar", + "continue": "Continue", + "submit": "Enviar", + "address": "Endereço", + "amount": "Quantidade", + "btc": "BTC", + "error": "Erro", + "sats": "sats", + "msats": "msats", + "uri": "URI", + "view-on-mempool": "Visualizar no Mempool", + "ecash": "Ecash" + }, + "notConfigured": { + "title": "Não Configurado", + "description": "Por favor, insira o CONFIG_API_URL do servidor guardião Fedimint para apontar." + }, + "connect-guardians": { + "invite-guardians": "Convide Seguidores", + "invite-guardians-help": "Compartilhe este link com os outros Guardiões", + "approve": "Aprovar", + "approved": "Aprovado", + "pending": "Pendente", + "not-joined": "Não associado", + "waiting-for-guardian": "Esperando pelo guardião", + "table-title": "Guardiões da Federação", + "table-description": "Os guardiões serão confirmados aqui assim que confirmarem as configurações da Federação.", + "meta-field-key": "Campo Meta - {{key}}" + }, + "federation-dashboard": { + "invite-members": "Convide membros ou autentique-se como um guardião", + "invite-members-prompt": "Compartilhe isso para convidar membros a se juntarem à federação", + "fed-info": { + "label": "Informações da Federação", + "your-status-label": "Estado", + "block-count-label": "Altura do Bloco de Consenso", + "api-version-label": "Versão da API", + "consensus-version-label": "Versão de consenso", + "peer-id-label": "ID do Par", + "session-info": { + "session-height": "Altura da Sessão", + "latest-session": "Última Sessão" + } + }, + "balance": { + "label": "Balanço Patrimonial" + }, + "bitcoin-node": { + "label": "Nó Bitcoin", + "url-label": "URL", + "network-label": "Rede" + }, + "guardians": { + "label": "Outros Guardiões", + "id-name-label": "ID: Nome", + "status-label": "Status da Conexão", + "health-label": "Saúde", + "health-issue": "Problema", + "health-good": "Bom", + "last-contribution-label": "Contribuição da Última Sessão", + "api-url-label": "URL da API", + "fetching-announcement": "Buscando anúncio..." + }, + "gateways": { + "label": "Portais de Relâmpago", + "node-id-label": "ID do Nó de Relâmpago", + "gateway-id-label": "ID do Gateway", + "fee-label": "Taxa de gateway", + "view-on-site": "Visualizar no {{site}}", + "no-gateways-info-title": "Ainda não há gateways conectados!", + "no-gateways-info-description": "Operadores de nós Lightning podem se conectar à sua federação para fornecer interoperabilidade da Lightning Network. Uma vez conectados, eles aparecerão aqui." + }, + "api-announcements": { + "label": "Anúncios de API", + "guardian": "Guardião", + "api-url": "URL da API", + "revision": "Revisão" + }, + "config": { + "label": "Configuração da Federação", + "view-config": "Visualizar Configuração", + "missing-meta-module": "A edição de campos Meta não é possível. O módulo Meta não está disponível para esta federação.", + "manage-meta": { + "label": "Gerenciar Meta", + "cancel-button": "Cancelar", + "confirm-modal": { + "title": "Confirme a Aprovação", + "description": "Sua aprovação alcançará o limite para adotar essa mudança meta. Seu novo meta será assim:" + }, + "consensus-meta-label": "Meta atual em consenso", + "revoke-button": "Revogar", + "no-consensus-meta-message": "não há meta no consenso", + "proposed-meta-label": "Propostas de Meta", + "propose-meta": "Propor Meta", + "propose-new-meta-button": "Propor Novo Meta", + "proposal-approved": "Você aprovou esta proposta", + "no-submitted-meta-message": "não há edições meta para revisar", + "edit-meta-label": "Editar meta", + "edit-consensus-meta-button": "Editar Consenso Meta", + "submit-meta-proposal": "Envie Proposta Meta", + "peer-approvals": "Aprovações de Pares", + "actions": "Ações", + "revision": "Revisão", + "setup-meta-title": "Configurando um Meta para a sua Federação", + "setup-meta-description": "A Fedimint pode fornecer informações adicionais aos clientes na forma de campos meta: pares de chave-valor com informações arbitrárias que você pode querer compartilhar com os clientes. Embora esses campos meta não sejam interpretados pela Fedimint, eles são relevantes para o consenso, ou seja, não podem diferir entre os membros da federação. Desta forma, os clientes podem confiar em sua correção.", + "propose-updates": "Como um guardião fedimint, você pode propor atualizações para o meta que serão aceitas pelos outros guardiões. Uma vez que a atualização é aceita por um limite de guardiões, ela será adotada como o novo meta de consenso para a federação.", + "core-meta-fields": "Os seguintes campos meta foram definidos como parte do protocolo central do Fedimint e são úteis para incluir no meta da sua federação:", + "meta-field-expiry": "Um timestamp unix após o qual a federação será desligada.", + "meta-field-name": "O nome legível por humanos da federação", + "meta-field-icon": "Um URL para um ícone de logotipo para a federação", + "meta-field-welcome": "Uma mensagem de boas-vindas para novos usuários que se juntam à federação", + "meta-field-gateways": "Uma lista de identificadores de gateway validados pela federação", + "your-own-fields": "Você também pode adicionar seus próprios campos meta arbitrários à proposta. Estes serão adicionados ao meta de todos os clientes que se conectam à sua federação e podem ser usados para qualquer finalidade que você desejar.", + "meta-effect-add": "Adicionar", + "meta-effect-modify": "Modificar", + "meta-effect-unchanged": "Inalterado", + "proposals": "Propostas" + } + }, + "modal": { + "client-connect": "Conecte um Cliente" + }, + "danger-zone": { + "danger-zone-label": "Zona de Perigo", + "cancel": "Cancelar", + "danger-zone-description": "Use com cautela!", + "guardian-warning-message": "AVISO: Não compartilhe este código com ninguém. Qualquer pessoa com este código pode se autenticar como um Guardião. Certifique-se de que está em um local privado e que ninguém está observando sua tela.", + "guardian-acknowledge": "Reconhecer e Revelar Código", + "acknowledge-and-download": "Reconhecer & Prosseguir", + "guardian-authenticate": "Autenticar como Guardião", + "guardian-connect-warning": "NÃO COMPARTILHE ISSO", + "backup": { + "label": "Cópia de segurança", + "title": "Baixar Backup", + "warning-title": "Aviso", + "warning-text": "O backup contém chaves privadas e material secreto para o guardião da federação e deve ser mantido em segurança. A recuperação usando este backup requer sua senha de administrador!", + "cancelButton": "Cancelar", + "acknowledgeButton": "Reconhecer & Baixar" + }, + "sign-api-announcement": { + "label": "Anúncio da API de Assinatura", + "title": "Anúncio da API de Assinatura", + "description": "Assine um novo anúncio de API.", + "current-api-url": "O URL da sua API da Configuração Local", + "announced-api-url": "O URL da sua API dos Anúncios da Federação", + "urls-match": "A sua URL da API atual corresponde à sua URL da API anunciada.", + "urls-mismatch": "Você alterou a URL da API em sua configuração local e precisa transmitir um novo anúncio de API.", + "sign-button": "Anúncio de nova API", + "signing-in-progress": "Iniciando sessão...", + "sign-tooltip": "Assine o anúncio da API para anunciar o URL da sua API para a federação." + }, + "schedule-shutdown": { + "label": "Agendar Desligamento", + "title": "Agendar Desligamento", + "description": "Agende seu nó guardião para desligar após uma altura de sessão específica para um upgrade coordenado de seus binários fedimintd.", + "current-session": "Sessão Atual", + "session-to-shutdown": "Sessão para Desligar às", + "confirm-shutdown": "Confirmar Desligamento", + "session-to-shutdown-helper": "Insira a altura da sessão na qual você deseja desligar seu nó guardião." + } + } + }, + "login": { + "title": "Bem-vindo de volta!", + "subtitle": "Por favor, insira sua senha.", + "password": "Senha", + "submit": "Enviar" + }, + "role-selector": { + "disclaimer-title": "Fedimint é um software beta", + "disclaimer-text": "Por favor, reporte problemas em https://github.com/fedimint/fedimint/issues", + "leader": { + "label": "Líder de Configuração", + "description": "Insira as configurações que outros Guardiões aprovam. Um Guardião atua como Líder de Configuração." + }, + "follower": { + "label": "Seguidor", + "description": "Assim que um Líder de Configuração define as configurações, outros Guardiões escolhem esta opção para aprovar as configurações e criar a Federação." + }, + "solo": { + "label": "Sozinho", + "description": "Opere o Fedimint como um Guardião Solo sem consenso, tolerância a falhas, backups federados ou outros benefícios de resiliência do Fedimint. Prossiga com cautela, não é destinado para uso em produção." + }, + "warning-modal": { + "title": "Todos estão prontos?", + "description": "Sair da cerimônia de configuração pode fazer com que a configuração falhe e exija que você reinicie seu guardião. Certifique-se de que todos estão prontos para executar a configuração completa antes de continuar!" + } + }, + "run-dkg": { + "error-config": "Falha ao executar a geração de chave distribuída. A configuração da federação deve ser reiniciada.", + "error-default": "Não está pronto para DKG, seu status atual é", + "error-header": "Algo deu errado.", + "waiting-header": "Aguardando pelos pares", + "generating-header": "Gerando códigos" + }, + "set-config": { + "bft-explanation-title": "Tolerância a Falhas Bizantinas da Sua Federação", + "bft-explanation": "Uma Federação Guardiã {{total}} cria um Limiar {{honesto}}/{{total}}.", + "bft-faulty": "A sua Federação será capaz de tolerar {{faulty}} Guardiões defeituosos, offline ou maliciosos sem impactar as operações da Federação.", + "guardian-name": "Nome do responsável", + "guardian-name-help": "Este nome aleatório será mostrado a outros Guardiões durante a configuração", + "acknowledge-backed-up": "Eu, {{guardianName}} (seu nome de guardião), prometo que fiz backup e protegi minha senha:", + "admin-password": "Senha do administrador", + "admin-password-generate": "Gerar", + "admin-password-set": "Clique em 'Gerar' para criar uma senha segura. Você pode modificá-la, mas essa senha deve ser segura e ter backup!", + "admin-password-help": "Faça backup desta senha e mantenha-a segura! Você não pode recuperar esta senha!", + "admin-password-backup": "Estou usando uma senha forte e fiz um backup dela. (Você não pode recuperar essa senha!)", + "confirm-and-backup-password": "Confirme e Faça Backup da Senha", + "confirm-password": "Confirme a senha", + "error-password-mismatch": "As senhas não correspondem", + "join-federation": "Junte-se ao link da Federação", + "join-federation-help": "Peça à pessoa que criou a Federação um link e cole-o aqui.", + "basic-settings": "Noções básicas", + "federation-settings": "Configurações da federação", + "federation-name": "Nome da federação", + "guardian-number": "Número de guardiões", + "guardian-number-help": "As federações requerem um mínimo de 4 guardiões. Isso não pode ser alterado posteriormente.", + "bitcoin-settings": "Configurações do Bitcoin", + "block-confirmations": "Confirmações Adicionais de Bloco", + "block-confirmations-help": "Os Guardiões da Fedimint seguem a ponta do blockchain por várias confirmações para evitar reorganizações de blocos.", + "block-confirmations-help-mainnet": "Executar na Mainnet requer pelo menos 5 confirmações adicionais.", + "block-confirmations-warning": "Executar o Fedimint com menos de 5 confirmações de bloco adicionais é extremamente arriscado! O Fedimint NÃO pode lidar com reorganizações de blockchain.", + "bitcoin-network": "Rede Bitcoin", + "select-network": "Selecione uma rede", + "bitcoin-rpc-kind": "Tipo de RPC Bitcoin", + "set-rpc-help": "Fonte de dados de bloco bitcoin para o seu nó guardião", + "bitcoin-rpc": "URL do RPC do Bitcoin", + "read-from-env": "(Detectado a partir de variáveis de ambiente)", + "error-valid-number": "Por favor, insira um número válido.", + "error-valid-min": "Por favor, insira um número de pelo menos {{min}}.", + "error-valid-max": "Por favor, insira um número de no máximo {{max}}.", + "error-valid-min-max": "Por favor, insira um número entre {{min}} e {{max}}.", + "error-guardian-name-mismatch": "O nome do guardião não corresponde", + "meta-fields": "Campos meta", + "meta-fields-description": "Veja a documentação para mais informações.", + "meta-fields-key": "Tecla Meta", + "meta-fields-value": "Valor", + "meta-fields-effect": "Efeito", + "meta-fields-add-another": "Adicione outro", + "meta-fields-title": "A Sua Proposta Meta:", + "network": "Rede", + "password-warning-title": "Faça backup da sua senha!", + "password-warning": "Você DEVE fazer backup da sua senha e mantê-la segura. Esta senha é necessária para acessar o painel do seu guardião. Você NÃO pode recuperá-la se a perder!" + }, + "setup": { + "warning": { + "title": "Não saia ou atualize durante a configuração!", + "description": "Sair durante a configuração pode fazer com que a configuração falhe e você terá que fazer um novo reinício." + }, + "common": { + "restart-setup": "Reinicie a Configuração", + "restart-setup-alert": "O Líder de Configuração reiniciou a Cerimônia de Configuração. Por favor, clique em \"Reiniciar\" abaixo para continuar.", + "confirm-restart-setup": "Tem certeza de que deseja reiniciar a Cerimônia de Configuração?", + "confirm-restart-setup-alert": "Clicar em \"Reiniciar\" reiniciará a cerimônia para todos os Guardiões." + }, + "progress": { + "tos": { + "title": "Termos de serviço" + }, + "start": { + "title": "Bem-vindo, Guardião!", + "subtitle": "Vamos configurar a sua federação.", + "step": "Detalhes da Federação" + }, + "set-config": { + "title": "Precisamos definir algumas configurações para a sua Federação", + "title-solo": "Precisamos definir algumas configurações para a sua Federação Solo.", + "subtitle-leader": "Os seus seguidores da Federação confirmarão essa informação do lado deles.", + "subtitle-solo": "Executar uma Federação Solo perde muitos dos benefícios do Fedimint. Você não terá tolerância a falhas de consenso para um guardião estar offline e não poderá fazer backups federados. Prossiga com cautela, não recomendado para uso em produção ou uso com Bitcoin mainnet.", + "subtitle-follower": "O seu Líder da Federação estará configurando os principais detalhes da Federação. Você irá confirmá-los em breve.", + "step": "Detalhes da Federação" + }, + "connect-guardians": { + "title-leader": "Convide seus Guardiões", + "title-follower": "Confirme suas Informações de Federação", + "subtitle-leader": "Compartilhe o link com os outros Guardiões para colocar todos na mesma página. Assim que todos os Guardiões se juntarem, você avançará automaticamente para a próxima etapa.", + "subtitle-follower": "Certifique-se de que as informações aqui estão corretas e que os Guardiões da Federação estão corretos. Clique no botão Aprovar quando tiver certeza de que está bom.", + "step-leader": "Convide Guardiões", + "step-follower": "Confirmar informações" + }, + "run-dkg": { + "title": "Sucesso!", + "subtitle": "Todos os Guardiões validaram os detalhes de configuração da federação. Executando alguns números..." + }, + "verify-guardians": { + "title": "Verifique seus Guardiões", + "subtitle": "Peça a cada Guardião o seu código de verificação e cole-os abaixo para verificar a validade. Estamos quase terminando!", + "step": "Verifique os guardiões", + "leader-confirm-done": "Confirme que todos os Guardiões seguidores clicaram em \"Próximo\" e vejam seus painéis de controle de guardião antes de continuar.", + "leader-confirm-done-emphasis": "Clicar em \"Continuar\" completará a cerimônia de configuração." + }, + "setup-complete": { + "step": "Feito!" + }, + "error": { + "title": "Passo desconhecido", + "subtitle": "Como você chegou aqui?!" + } + } + }, + "setup-complete": { + "header": "🎉 🎉 🎉", + "congratulations": "Parabéns", + "leader-message": "Todos os códigos de verificação dos Guardiões foram verificados.", + "follower-message": "Você terminou! Avise aos outros Guardiões que você está correndo!", + "continue": "Continue" + }, + "terms-of-service": { + "agree-and-continue": "Concordar & continuar" + }, + "verify-guardians": { + "verified": "Verificado", + "verified-placeholder": "Cole o código aqui", + "error": "Algo deu errado.", + "error-peer-id": "Incapaz de determinar qual par você é. Por favor, atualize e tente novamente.", + "verification-code": "O seu ({{peerName}}) código de verificação", + "verification-code-help": "Compartilhe este código com outros guardiões", + "table-title": "Códigos de verificação do guardião", + "table-description": "Insira os códigos de verificação de cada Guardião abaixo.", + "table-column-name": "Nome", + "table-column-status": "Status", + "table-column-hash-input": "Cole o código de verificação", + "wait-all-guardians-verification": "Aguardando que todos os Guardiões verifiquem seus códigos", + "all-guardians-verified": "Todos os Guardiões verificaram seus códigos", + "starting-consensus": "Iniciando consenso..." + }, + "footer": { + "docs-section-header": "Documentos", + "community-section-header": "Comunidade", + "contribute-section-header": "Contribua", + "getting-started-link-text": "Começando", + "faq-link-text": "Perguntas Frequentes", + "blog-link-text": "Blog", + "discord-link-text": "Discórdia", + "twitter-link-text": "Twitter", + "github-link-text": "GitHub" + }, + "admin": { + "fetch-info-modal-text": "Verificando detalhes da federação..." + }, + "balance-card": { + "card_header": "Saldo eCash", + "sentence": "Denominado em Sats", + "your-balance": "O saldo do seu eCash nesta federação:" + }, + "connect-federation": { + "connect": "Conectar 🚀", + "connect-federation-button": "Adicionar Federação", + "connection-string-placeholder": "Cole o código de convite da federação", + "heading": "Conecte-se a uma federação usando um código de convite", + "information-bar-text": "O número de federações às quais você pode se conectar é limitado a uma. A conexão com várias federações será suportada em breve.", + "label": "String de Conexão:", + "progress-modal-text": "Conectando à federação...", + "sub-heading": "O código de convite é uma longa sequência que começa com 'fed1", + "error-message": "Erro ao conectar à federação: {{error}}" + }, + "wallet": { + "title": "Carteira", + "ecash": "Ecash", + "lightning": "Relâmpago", + "onchain": "Onchain", + "total": "Total", + "balance": "Equilíbrio", + "address": "Endereço", + "invoice": "Fatura", + "receive": "Receba", + "send": "Enviar", + "create-address": "Criar Endereço", + "to-federation": "Para a Federação", + "from-federation": "Da Federação", + "sent": "Enviado", + "sent-amount": "Enviado {{amount}}", + "to-address": "Para Endereço", + "txid": "ID da Transação", + "claimed-note": "Nota Reivindicada", + "claimed-amount": "Valor Reivindicado" + }, + "wallet-modal": { + "title": "Ações da Carteira", + "receive": { + "ecash-instructions": "Cole seu bilhete de ecash aqui", + "paste-ecash-placeholder": "Cole aqui a nota de ecash", + "redeem": "Resgatar", + "paste-invoice": "Cole aqui a fatura", + "enter-amount": "Insira a quantidade em {{unit}}", + "lightning-instructions": "Insira um valor em sats para criar uma fatura Lightning para", + "create-peg-in-address": "Criar Endereço Peg-in", + "create-lightning-invoice": "Crie uma fatura Lightning", + "paste-ecash-button": "Cole nota de ecash", + "peg-in-instructions": "Envie Bitcoin para este endereço para vincular ao seu saldo Ecash da {{federationName}}", + "ecash-claimed-success": "Ecash reivindicado com sucesso!", + "address-error": "Erro ao criar endereço: {{error}}" + }, + "send": { + "submit": "Enviar", + "to-onchain-address": "Para Endereço Onchain", + "address-placeholder": "bc1p...", + "peg-out-to-onchain": "Transferir Ecash para Onchain", + "peg-out-success": "Peg Out TX Enviado!", + "create-ecash": "Criar Nota Ecash", + "ecash-created": "Retirou uma nota de ecash de {{amount}} do seu saldo {{federationName}}. Envie-a para o destinatário para reivindicar.", + "ecash-error": "Erro ao criar nota ecash: {{error}}" + } + }, + "federation-card": { + "table-title": "Federações", + "id": "ID", + "name": "Nome", + "balance": "Equilíbrio", + "actions": "Ações", + "receive": "Receber", + "send": "Enviar", + "default-federation-name": "Federação:", + "view-link-on": "Visualizar em {{host}}", + "leave-fed-error": "Não pode sair da federação com sats no seu saldo. Por favor, retire seus sats primeiro.", + "leave-fed-modal-title": "Deixe a Federação", + "leave-fed-modal-text": "Tem certeza de que deseja se desconectar de", + "view-config": "Visualizar Configuração", + "config-for": "Configuração para {{federationId}}" + }, + "header": { + "active": "Ativo", + "all": "Todos", + "archived": "Arquivado", + "ascending": "Ascendendo", + "connect": "Conectar Federação", + "date-created": "Data de Criação", + "descending": "Descendente", + "filter": "Filtro", + "sort": "Ordenar", + "title": "Painel de Controle do Gateway de Relâmpago" + }, + "info-card": { + "card-header": "Informações do Nó de Relâmpago", + "node-id": "ID do Nó", + "alias": "Apelido", + "mode": "Modo", + "pubkey": "Chave pública", + "network": "Rede", + "block-height": "Altura do Bloco", + "synced-to-chain": "Sincronizado com a Corrente" + }, + "withdraw-card": { + "address-label": "O seu endereço:", + "address-placeholder": "Insira o seu endereço btc", + "amount-label": "Quantidade (sats):", + "amount-placeholder": "Insira a quantidade em sats", + "card-header": "Retirar Bitcoin", + "close": "Fechar", + "confirm-withdraw": "Confirmar Retirada", + "error": "Erro", + "error-address": "O valor ou endereço não podem estar vazios", + "error-amount": "O valor não pode estar vazio ou ser igual a zero", + "error-request": "Falha ao solicitar a retirada", + "request-from": "Solicitada Retirada de", + "requested-withdrawal": "Solicitação de Saque", + "to": "para", + "total_bitcoin": "Total de Bitcoin:", + "transaction-sent": "Transação Enviada!", + "view": "Visualizar", + "view-it-on": "Veja isso em", + "withdraw": "Retirar", + "withdraw-all": "Retirar tudo", + "withdrawal-created": "Saque criado.", + "withdrawal-created-description": "Por favor, verifique seu histórico de transações", + "withdrawal-history": "Histórico de Saques", + "your-transaction": "O ID da sua transação:" + } +} diff --git a/apps/router/src/languages/ru.json b/apps/router/src/languages/ru.json new file mode 100644 index 000000000..a278f9860 --- /dev/null +++ b/apps/router/src/languages/ru.json @@ -0,0 +1,486 @@ +{ + "common": { + "bitcoin": "Биткоин", + "next": "Следующий", + "back": "Назад", + "unknown": "Неизвестно", + "remove": "Удалить", + "copy": "Копировать", + "copied": "Скопировано!", + "cancel": "Отменить", + "review": "Обзор", + "approvals": "Одобрения", + "approve": "Одобрить", + "threshold": "Порог", + "confirm": "Подтвердить", + "you": "Вы", + "close": "Закрыть", + "save": "Сохранить", + "continue": "Продолжить", + "submit": "Отправить", + "address": "Адрес", + "amount": "Количество", + "btc": "BTC", + "error": "Ошибка", + "sats": "сатоши", + "msats": "мсатс", + "uri": "URI", + "view-on-mempool": "Просмотр Mempool", + "ecash": "Электронные деньги" + }, + "notConfigured": { + "title": "Не настроено", + "description": "Пожалуйста, введите CONFIG_API_URL сервера-хранителя Fedimint, на который следует указать." + }, + "connect-guardians": { + "invite-guardians": "Пригласить подписчиков", + "invite-guardians-help": "Поделитесь этой ссылкой с другими Стражами", + "approve": "Одобрить", + "approved": "Одобрено", + "pending": "В ожидании", + "not-joined": "Не присоединился", + "waiting-for-guardian": "Ожидание опекуна", + "table-title": "Стражи Федерации", + "table-description": "Опекуны будут подтверждены здесь после того, как они подтвердят настройки Федерации.", + "meta-field-key": "Мета-поле - {{key}}" + }, + "federation-dashboard": { + "invite-members": "Пригласите участников или авторизуйтесь как опекун", + "invite-members-prompt": "Поделитесь этим, чтобы пригласить участников присоединиться к федерации", + "fed-info": { + "label": "Информация о Федерации", + "your-status-label": "Статус", + "block-count-label": "Высота блока по консенсусу", + "api-version-label": "Версия API", + "consensus-version-label": "Версия по согласию", + "peer-id-label": "Идентификатор участника", + "session-info": { + "session-height": "Высота сессии", + "latest-session": "Последняя сессия" + } + }, + "balance": { + "label": "Балансовый отчет" + }, + "bitcoin-node": { + "label": "Узел Bitcoin", + "url-label": "URL", + "network-label": "Сеть" + }, + "guardians": { + "label": "Другие Стражи", + "id-name-label": "ID: Имя", + "status-label": "Статус подключения", + "health-label": "Здоровье", + "health-issue": "Проблема", + "health-good": "Хорошо", + "last-contribution-label": "Вклад последней сессии", + "api-url-label": "URL API", + "fetching-announcement": "Получение объявления..." + }, + "gateways": { + "label": "Ворота Молний", + "node-id-label": "ID узла молнии", + "gateway-id-label": "Идентификатор шлюза", + "fee-label": "Плата за использование шлюза", + "view-on-site": "Просмотр на {{site}}", + "no-gateways-info-title": "Пока нет подключенных шлюзов!", + "no-gateways-info-description": "Операторы узлов Lightning могут подключиться к вашему федеративному серверу для обеспечения взаимодействия в сети Lightning. После подключения они появятся здесь." + }, + "api-announcements": { + "label": "Объявления API", + "guardian": "Страж", + "api-url": "URL API", + "revision": "Редакция" + }, + "config": { + "label": "Конфигурация Федерации", + "view-config": "Просмотр конфигурации", + "missing-meta-module": "Редактирование мета-полей невозможно. Мета-модуль недоступен для этого федеративного узла.", + "manage-meta": { + "label": "Управление Мета", + "cancel-button": "Отменить", + "confirm-modal": { + "title": "Подтвердить утверждение", + "description": "Ваше одобрение достигнет порога для принятия этого мета-изменения. Ваша новая мета будет выглядеть так:" + }, + "consensus-meta-label": "Текущий мета в консенсусе", + "revoke-button": "Отозвать", + "no-consensus-meta-message": "в консенсусе нет мета", + "proposed-meta-label": "Предложения Meta", + "propose-meta": "Предложить Мета", + "propose-new-meta-button": "Предложить новую Мету", + "proposal-approved": "Вы одобрили это предложение", + "no-submitted-meta-message": "нет мета-правок для проверки", + "edit-meta-label": "Редактировать мета", + "edit-consensus-meta-button": "Редактировать Мета-консенсус", + "submit-meta-proposal": "Предложить мета-предложение", + "peer-approvals": "Одобрения коллег", + "actions": "Действия", + "revision": "Редакция", + "setup-meta-title": "Настройка Меты для вашего Союза", + "setup-meta-description": "Fedimint может предоставлять дополнительную информацию клиентам в виде мета-полей: пар ключ-значение с произвольной информацией, которой вы, возможно, захотите поделиться с клиентами. Хотя эти мета-поля не интерпретируются Fedimint, они имеют значение для консенсуса, т.е. они не могут отличаться между членами федерации. Таким образом, клиенты могут полагаться на и", + "propose-updates": "В качестве стража федиминта вы можете предлагать обновления метаданных, которые будут приняты другими стражами. Как только обновление будет принято пороговым числом стражей, оно будет принято в качестве нового консенсуса метаданных для федерации.", + "core-meta-fields": "Следующие мета-поля были определены как часть основного протокола Fedimint и могут быть полезны для включения в метаданные вашего федеративного объединения:", + "meta-field-expiry": "Unix-временная метка, после которой федерация будет отключена.", + "meta-field-name": "Человекочитаемое название федерации", + "meta-field-icon": "URL-адрес значка логотипа для федерации", + "meta-field-welcome": "Приветственное сообщение для новых пользователей, присоединяющихся к федерации", + "meta-field-gateways": "Список идентификаторов шлюзов, проверенных федерацией", + "your-own-fields": "Вы также можете добавить свои собственные произвольные мета-поля в предложение. Они будут добавлены в метаданные всех клиентов, которые подключаются к вашему федеративному серверу, и могут быть использованы для любых целей на ваше усмотрение.", + "meta-effect-add": "Добавить", + "meta-effect-modify": "Изменить", + "meta-effect-unchanged": "Неизменный", + "proposals": "Предложения" + } + }, + "modal": { + "client-connect": "Подключить клиента" + }, + "danger-zone": { + "danger-zone-label": "Зона опасности", + "cancel": "Отменить", + "danger-zone-description": "Используйте с осторожностью!", + "guardian-warning-message": "ПРЕДУПРЕЖДЕНИЕ: Не делитесь этим кодом с кем-либо. Любой человек, обладающий этим кодом, может аутентифицироваться как Guardian. Убедитесь, что вы находитесь в частном месте и никто не наблюдает за вашим экраном.", + "guardian-acknowledge": "Признать и Раскрыть Код", + "acknowledge-and-download": "Подтвердить и продолжить", + "guardian-authenticate": "Аутентифицируйтесь как Опекун", + "guardian-connect-warning": "НЕ РАСПРОСТРАНЯЙТЕ ЭТО", + "backup": { + "label": "Резервное копирование", + "title": "Скачать резервную копию", + "warning-title": "Предупреждение", + "warning-text": "Резервная копия содержит закрытые ключи и секретные материалы для стража федерации и должна храниться в безопасном месте. Восстановление с использованием этой резервной копии требует вашего административного пароля!", + "cancelButton": "Отменить", + "acknowledgeButton": "Подтвердить и Скачать" + }, + "sign-api-announcement": { + "label": "Объявление о API для подписи", + "title": "Объявление о API для подписей", + "description": "Подпишите новое объявление об API.", + "current-api-url": "URL вашего API из локальной конфигурации", + "announced-api-url": "URL вашего API из объявлений Федерации", + "urls-match": "Текущий URL вашего API совпадает с объявленным URL вашего API.", + "urls-mismatch": "Вы изменили URL API в вашей локальной конфигурации и вам нужно опубликовать новое объявление API.", + "sign-button": "Объявление о новом API", + "signing-in-progress": "Вход в систему...", + "sign-tooltip": "Подпишите объявление API, чтобы объявить о вашем URL API для федерации." + }, + "schedule-shutdown": { + "label": "Планирование выключения", + "title": "Планирование выключения", + "description": "Запланируйте выключение вашего узла-хранителя после определенной высоты сессии для согласованного обновления ваших двоичных файлов fedimintd.", + "current-session": "Текущая сессия", + "session-to-shutdown": "Сессия будет завершена в", + "confirm-shutdown": "Подтвердите выключение", + "session-to-shutdown-helper": "Введите высоту сессии, при достижении которой вы хотите выключить свой узел-хранитель." + } + } + }, + "login": { + "title": "Добро пожаловать обратно!", + "subtitle": "Пожалуйста, введите ваш пароль.", + "password": "Пароль", + "submit": "Отправить" + }, + "role-selector": { + "disclaimer-title": "Fedimint - это бета-версия программного обеспечения.", + "disclaimer-text": "Пожалуйста, сообщайте о проблемах по адресу https://github.com/fedimint/fedimint/issues", + "leader": { + "label": "Настройка лидера", + "description": "Введите настройки конфигурации, которые одобряют другие Гардианы. Один Гардиан действует в качестве лидера настройки." + }, + "follower": { + "label": "Последователь", + "description": "Как только Лидер настройки устанавливает конфигурации, другие Стражи выбирают эту опцию, чтобы одобрить настройки и создать Федерацию." + }, + "solo": { + "label": "Соло", + "description": "Управляйте Fedimint как единственным Гардианом без консенсуса, отказоустойчивости, федеративных резервных копий или других преимуществ устойчивости Fedimint. Действуйте с осторожностью, не предназначено для использования в производственной среде." + }, + "warning-modal": { + "title": "Все готовы?", + "description": "Выход из процедуры настройки может привести к сбою в работе настройки и потребовать от вас перезапуска вашего сторожевого устройства. Убедитесь, что все готовы выполнить полную настройку перед продолжением!" + } + }, + "run-dkg": { + "error-config": "Не удалось запустить распределенное создание ключей. Необходимо перезапустить настройку федерации.", + "error-default": "Не готовы к DKG, ваш текущий статус -", + "error-header": "Что-то пошло не так.", + "waiting-header": "Ожидание сверстников", + "generating-header": "Генерация кодов" + }, + "set-config": { + "bft-explanation-title": "Толерантность к византийским ошибкам вашего союза", + "bft-explanation": "Федерация Гардианов создает Чертог {{honest}}/{{total}}.", + "bft-faulty": "Ваша Федерация сможет терпеть {{faulty}} неисправных, отключенных или злонамеренных стражей, не влияя на работу Федерации.", + "guardian-name": "Имя опекуна", + "guardian-name-help": "Это случайное имя будет показано другим стражам во время настройки.", + "acknowledge-backed-up": "Я, {{guardianName}} (ваше имя опекуна), обещаю, что я сделал резервную копию и обезопасил свой пароль:", + "admin-password": "Пароль администратора", + "admin-password-generate": "Генерировать", + "admin-password-set": "Нажмите \"Создать\", чтобы создать безопасный пароль. Вы можете его изменить, но этот пароль должен быть безопасным и иметь резервную копию!", + "admin-password-help": "Сохраните этот пароль и храните его в безопасном месте! Вы не сможете восстановить этот пароль!", + "admin-password-backup": "Я использую надежный пароль и сделал его резервную копию. (Вы не сможете восстановить этот пароль!)", + "confirm-and-backup-password": "Подтвердите и создайте резервную копию пароля", + "confirm-password": "Подтвердите пароль", + "error-password-mismatch": "Пароли не совпадают", + "join-federation": "Присоединиться к ссылке Федерации", + "join-federation-help": "Попросите человека, который создал Федерацию, дать вам ссылку и вставьте ее здесь.", + "basic-settings": "Основы", + "federation-settings": "Настройки федерации", + "federation-name": "Название федерации", + "guardian-number": "Количество опекунов", + "guardian-number-help": "Федерации требуют минимум 4-х стражей. Это не может быть изменено позже.", + "bitcoin-settings": "Настройки Bitcoin", + "block-confirmations": "Дополнительные подтверждения блоков", + "block-confirmations-help": "Стражи Fedimint отстают от вершины блокчейна на несколько подтверждений, чтобы избежать переорганизации блоков.", + "block-confirmations-help-mainnet": "Для работы в Mainnet требуется как минимум 5 дополнительных подтверждений.", + "block-confirmations-warning": "Запуск Fedimint с менее чем 5 дополнительными подтверждениями блоков чрезвычайно рискован! Fedimint НЕ СПОСОБЕН обрабатывать реорганизацию блокчейна.", + "bitcoin-network": "Сеть Bitcoin", + "select-network": "Выберите сеть", + "bitcoin-rpc-kind": "Вид Bitcoin RPC", + "set-rpc-help": "Источник данных блока биткоина для вашего узла-хранителя", + "bitcoin-rpc": "URL Bitcoin RPC", + "read-from-env": "(Обнаружено из переменных окружения)", + "error-valid-number": "Пожалуйста, введите действительный номер.", + "error-valid-min": "Пожалуйста, введите число не меньше {{min}}.", + "error-valid-max": "Пожалуйста, введите число не больше {{max}}.", + "error-valid-min-max": "Пожалуйста, введите число между {{min}} и {{max}}.", + "error-guardian-name-mismatch": "Имя опекуна не совпадает", + "meta-fields": "Мета-поля", + "meta-fields-description": "Смотрите документацию для получения дополнительной информации.", + "meta-fields-key": "Мета-ключ", + "meta-fields-value": "Ценность", + "meta-fields-effect": "Эффект", + "meta-fields-add-another": "Добавить еще один", + "meta-fields-title": "Ваше предложение для Мета:", + "network": "Сеть", + "password-warning-title": "Сделайте резервную копию вашего пароля!", + "password-warning": "Вы ОБЯЗАНЫ сделать резервную копию своего пароля и хранить его в безопасном месте. Этот пароль необходим для доступа к вашей панели управления опекуном. Вы НЕ СМОЖЕТЕ восстановить его, если потеряете!" + }, + "setup": { + "warning": { + "title": "Не выходите и не обновляйте страницу во время установки!", + "description": "Выход во время установки может привести к сбою установки, и вам придется начать все заново." + }, + "common": { + "restart-setup": "Перезапустите установку", + "restart-setup-alert": "Лидер настройки перезапустил церемонию настройки. Пожалуйста, нажмите \"Перезапустить\" ниже, чтобы продолжить.", + "confirm-restart-setup": "Вы уверены, что хотите перезапустить церемонию настройки?", + "confirm-restart-setup-alert": "Нажатие на \"Перезапуск\" перезапустит церемонию для всех Стражей." + }, + "progress": { + "tos": { + "title": "Условия предоставления услуг" + }, + "start": { + "title": "Добро пожаловать, Страж!", + "subtitle": "Давайте настроим ваш федеративный сервис.", + "step": "Детали федерации" + }, + "set-config": { + "title": "Нам нужно установить некоторые конфигурации для вашего Федеративного управления", + "title-solo": "Нам нужно установить некоторые конфигурации для вашего Solo Federation", + "subtitle-leader": "Ваши последователи из Федерации подтвердят эту информацию с их стороны.", + "subtitle-solo": "Запуск Одиночной Федерации лишает вас многих преимуществ Fedimint. У вас не будет отказоустойчивого консенсуса в отношении оффлайн-статуса гардиана и возможности делать федеративные резервные копии. Будьте осторожны, не рекомендуется для использования в производственной среде или с основной сетью Bitcoin.", + "subtitle-follower": "Ваш лидер Федерации будет настраивать основные детали Федерации. Вы подтвердите их в ближайшее время.", + "step": "Детали федерации" + }, + "connect-guardians": { + "title-leader": "Пригласите своих Стражей", + "title-follower": "Подтвердите информацию о вашем союзе", + "subtitle-leader": "Поделитесь ссылкой с другими Хранителями, чтобы все были в курсе. Как только все Хранители присоединятся, вы автоматически перейдете к следующему шагу.", + "subtitle-follower": "Убедитесь, что информация здесь выглядит правильно и что Стражи Федерации указаны верно. Нажмите кнопку \"Утвердить\", когда будете уверены, что все выглядит хорошо.", + "step-leader": "Пригласить стражей", + "step-follower": "Подтвердите информацию" + }, + "run-dkg": { + "title": "Успех!", + "subtitle": "Все стражи подтвердили детали настройки федерации. Производим расчеты..." + }, + "verify-guardians": { + "title": "Проверьте своих Стражей", + "subtitle": "Спросите у каждого Гардиана его проверочный код и вставьте их ниже, чтобы проверить их действительность. Мы почти закончили!", + "step": "Проверьте опекунов", + "leader-confirm-done": "Подтвердите, что все следующие за вами Стражи нажали \"Далее\" и увидели свои панели управления стражей перед тем, как продолжить.", + "leader-confirm-done-emphasis": "Нажатие на кнопку \"Продолжить\" завершит процедуру настройки." + }, + "setup-complete": { + "step": "Готово!" + }, + "error": { + "title": "Неизвестный шаг", + "subtitle": "Как ты сюда попал(а)?!" + } + } + }, + "setup-complete": { + "header": "🎉 🎉 🎉", + "congratulations": "Поздравляем", + "leader-message": "Все проверочные коды стражей были проверены.", + "follower-message": "Вы все сделали! Дайте знать другим Стражам, что вы в деле!", + "continue": "Продолжить" + }, + "terms-of-service": { + "agree-and-continue": "Согласиться и продолжить" + }, + "verify-guardians": { + "verified": "Проверено", + "verified-placeholder": "Вставьте код здесь", + "error": "Что-то пошло не так.", + "error-peer-id": "Не удалось определить, какой узел вы представляете. Пожалуйста, обновите страницу и попробуйте снова.", + "verification-code": "Ваш ({{peerName}}) код подтверждения", + "verification-code-help": "Поделитесь этим кодом с другими стражами", + "table-title": "Коды верификации Guardian", + "table-description": "Введите ниже проверочные коды каждого опекуна.", + "table-column-name": "Имя", + "table-column-status": "Статус", + "table-column-hash-input": "Вставьте код подтверждения", + "wait-all-guardians-verification": "Ожидание подтверждения кодов всеми Хранителями", + "all-guardians-verified": "Все опекуны проверили свои коды", + "starting-consensus": "Запуск консенсуса..." + }, + "footer": { + "docs-section-header": "Документы", + "community-section-header": "Сообщество", + "contribute-section-header": "Внести свой вклад", + "getting-started-link-text": "Начало работы", + "faq-link-text": "Часто Задаваемые Вопросы", + "blog-link-text": "Блог", + "discord-link-text": "Дискорд", + "twitter-link-text": "Твиттер", + "github-link-text": "GitHub" + }, + "admin": { + "fetch-info-modal-text": "Проверка деталей федерации..." + }, + "balance-card": { + "card_header": "Баланс eCash", + "sentence": "Номинированный в Сатоши", + "your-balance": "Ваш баланс eCash в этом федерации:" + }, + "connect-federation": { + "connect": "Подключить 🚀", + "connect-federation-button": "Добавить Федерацию", + "connection-string-placeholder": "Вставьте код приглашения в федерацию", + "heading": "Подключитесь к федерации с использованием кода приглашения", + "information-bar-text": "Количество федераций, к которым вы можете подключиться, ограничено одной. Поддержка подключения к нескольким федерациям будет реализована в ближайшее время.", + "label": "Строка подключения:", + "progress-modal-text": "Подключение к федерации...", + "sub-heading": "Пригласительный код - это длинная строка, которая начинается с «fed1»", + "error-message": "Ошибка подключения к федерации: {{error}}" + }, + "wallet": { + "title": "Кошелек", + "ecash": "Электронные деньги", + "lightning": "Молния", + "onchain": "Onchain", + "total": "Всего", + "balance": "Баланс", + "address": "Адрес", + "invoice": "Счет-фактура", + "receive": "Получить", + "send": "Отправить", + "create-address": "Создать адрес", + "to-federation": "В Федерацию", + "from-federation": "От Федерации", + "sent": "Отправлено", + "sent-amount": "Отправлено {{amount}}", + "to-address": "Для адреса", + "txid": "ID транзакции", + "claimed-note": "Заявленная записка", + "claimed-amount": "Заявленная сумма" + }, + "wallet-modal": { + "title": "Действия с кошельком", + "receive": { + "ecash-instructions": "Вставьте сюда вашу электронную денежную записку", + "paste-ecash-placeholder": "Вставьте сюда электронную денежную записку", + "redeem": "Выкупить", + "paste-invoice": "Вставьте счет-фактуру здесь", + "enter-amount": "Введите количество в {{unit}}", + "lightning-instructions": "Введите сумму в сатоши для создания инвойса в Lightning", + "create-peg-in-address": "Создать адрес Peg-in", + "create-lightning-invoice": "Создать инвойс Lightning", + "paste-ecash-button": "Вставьте электронную денежную записку", + "peg-in-instructions": "Отправьте Биткоин на этот адрес, чтобы привязать его к балансу Ecash вашего {{federationName}}", + "ecash-claimed-success": "Электронные деньги успешно получены!", + "address-error": "Ошибка создания адреса: {{error}}" + }, + "send": { + "submit": "Отправить", + "to-onchain-address": "На Onchain адрес", + "address-placeholder": "bc1p...", + "peg-out-to-onchain": "Перевести Ecash в Onchain", + "peg-out-success": "Отправлен Peg Out TX!", + "create-ecash": "Создать Электронную Денежную Записку", + "ecash-created": "Вынул {{amount}} е-денежную купюру из вашего баланса {{federationName}}. Отправьте ее получателю для получения.", + "ecash-error": "Ошибка создания электронной купюры: {{error}}" + } + }, + "federation-card": { + "table-title": "Федерации", + "id": "ID", + "name": "Имя", + "balance": "Баланс", + "actions": "Действия", + "receive": "Получить", + "send": "Отправить", + "default-federation-name": "Федерация:", + "view-link-on": "Просмотр на {{host}}", + "leave-fed-error": "Невозможно покинуть федерацию, имея сатоши на балансе. Пожалуйста, сначала выведите свои сатоши.", + "leave-fed-modal-title": "Покинуть Федерацию", + "leave-fed-modal-text": "Вы уверены, что хотите отключиться от", + "view-config": "Просмотр конфигурации", + "config-for": "Конфигурация для {{federationId}}" + }, + "header": { + "active": "Активный", + "all": "Все", + "archived": "Архивировано", + "ascending": "Восхождение", + "connect": "Подключить Федерацию", + "date-created": "Дата создания", + "descending": "Спускающийся", + "filter": "Фильтр", + "sort": "Сортировать", + "title": "Панель управления Lightning Gateway" + }, + "info-card": { + "card-header": "Информация о узле Lightning", + "node-id": "ID узла", + "alias": "Псевдоним", + "mode": "Режим", + "pubkey": "Публичный ключ", + "network": "Сеть", + "block-height": "Высота блока", + "synced-to-chain": "Синхронизировано с цепью" + }, + "withdraw-card": { + "address-label": "Ваш адрес:", + "address-placeholder": "Введите ваш btc адрес", + "amount-label": "Количество (сатоши):", + "amount-placeholder": "Введите сумму в сатоши", + "card-header": "Вывести Биткоин", + "close": "Закрыть", + "confirm-withdraw": "Подтвердить вывод средств", + "error": "Ошибка", + "error-address": "Сумма или адрес не могут быть пустыми", + "error-amount": "Сумма не может быть пустой или равной нулю", + "error-request": "Не удалось запросить вывод средств", + "request-from": "Запрошено снятие средств из", + "requested-withdrawal": "Запрошенное снятие средств", + "to": "к", + "total_bitcoin": "Всего Биткоинов:", + "transaction-sent": "Транзакция отправлена!", + "view": "Просмотр", + "view-it-on": "Посмотрите это на", + "withdraw": "Вывести", + "withdraw-all": "Вывести все", + "withdrawal-created": "Создан вывод средств.", + "withdrawal-created-description": "Пожалуйста, проверьте историю ваших транзакций.", + "withdrawal-history": "История вывода средств", + "your-transaction": "Ваш идентификатор транзакции:" + } +} diff --git a/apps/router/src/languages/zh.json b/apps/router/src/languages/zh.json new file mode 100644 index 000000000..946a41482 --- /dev/null +++ b/apps/router/src/languages/zh.json @@ -0,0 +1,486 @@ +{ + "common": { + "bitcoin": "比特币", + "next": "下一个", + "back": "背部", + "unknown": "未知", + "remove": "移除", + "copy": "复制", + "copied": "已复制!", + "cancel": "取消", + "review": "评论", + "approvals": "批准", + "approve": "批准", + "threshold": "阈值", + "confirm": "确认", + "you": "你", + "close": "关闭", + "save": "保存", + "continue": "继续", + "submit": "提交", + "address": "地址", + "amount": "金额", + "btc": "比特币", + "error": "错误", + "sats": "卫星", + "msats": "msats", + "uri": "统一资源标识符", + "view-on-mempool": "查看Mempool", + "ecash": "电子现金" + }, + "notConfigured": { + "title": "未配置", + "description": "请输入指向Fedimint守护服务器的CONFIG_API_URL。" + }, + "connect-guardians": { + "invite-guardians": "邀请关注者", + "invite-guardians-help": "将此链接分享给其他守护者", + "approve": "批准", + "approved": "批准", + "pending": "待定", + "not-joined": "未加入", + "waiting-for-guardian": "等待监护人", + "table-title": "联邦守护者", + "table-description": "一旦他们确认联邦设置,监护人将在此处得到确认。", + "meta-field-key": "元字段 - {{key}}" + }, + "federation-dashboard": { + "invite-members": "邀请成员或作为监护人进行身份验证", + "invite-members-prompt": "分享此内容以邀请成员加入联盟", + "fed-info": { + "label": "联邦信息", + "your-status-label": "状态", + "block-count-label": "共识区块高度", + "api-version-label": "API版本", + "consensus-version-label": "共识版本", + "peer-id-label": "对等ID", + "session-info": { + "session-height": "会议高度", + "latest-session": "最新会议" + } + }, + "balance": { + "label": "资产负债表" + }, + "bitcoin-node": { + "label": "比特币节点", + "url-label": "网址", + "network-label": "网络" + }, + "guardians": { + "label": "其他守护者", + "id-name-label": "ID:名称", + "status-label": "连接状态", + "health-label": "健康", + "health-issue": "问题", + "health-good": "好的", + "last-contribution-label": "上次会议贡献", + "api-url-label": "API网址", + "fetching-announcement": "获取公告..." + }, + "gateways": { + "label": "闪电网关", + "node-id-label": "闪电节点ID", + "gateway-id-label": "网关ID", + "fee-label": "网关费用", + "view-on-site": "在{{site}}上查看", + "no-gateways-info-title": "尚未连接任何网关!", + "no-gateways-info-description": "闪电网络节点运营商可以连接到您的联盟,以提供闪电网络的互操作性。一旦连接,他们将会出现在这里。" + }, + "api-announcements": { + "label": "API 公告", + "guardian": "守护者", + "api-url": "API网址", + "revision": "修订" + }, + "config": { + "label": "联邦配置", + "view-config": "查看配置", + "missing-meta-module": "无法编辑元字段。元模块对此联邦不可用。", + "manage-meta": { + "label": "管理元数据", + "cancel-button": "取消", + "confirm-modal": { + "title": "确认批准", + "description": "您的批准将达到采纳这个元更改的阈值。您的新元将看起来像:" + }, + "consensus-meta-label": "当前的共识元数据", + "revoke-button": "撤销", + "no-consensus-meta-message": "共识中没有元数据", + "proposed-meta-label": "元提案", + "propose-meta": "提议元数据", + "propose-new-meta-button": "提议新的元数据", + "proposal-approved": "您已批准了这个提案。", + "no-submitted-meta-message": "没有元编辑供审查。", + "edit-meta-label": "编辑元数据", + "edit-consensus-meta-button": "编辑共识元数据", + "submit-meta-proposal": "提交元提案", + "peer-approvals": "同行认可", + "actions": "行动", + "revision": "修订", + "setup-meta-title": "为您的联邦设置元数据", + "setup-meta-description": "Fedimint可以以元字段的形式向客户提供额外信息:您可能想要与客户分享的任意信息的键值对。虽然这些元字段不会被Fedimint解读,但它们对于共识是相关的,即它们在联盟成员之间不能有差异。这样,客户可以依赖它们的正确性。", + "propose-updates": "作为联邦守护者,您可以提出对元数据的更新,这些更新将被其他守护者接受。一旦更新被一定数量的守护者接受,它将被采纳为联邦的新共识元数据。", + "core-meta-fields": "以下元字段已被定义为Fedimint核心协议的一部分,并且对于您的联邦元数据来说非常有用:", + "meta-field-expiry": "联邦将在此Unix时间戳之后关闭。", + "meta-field-name": "联邦的可读名称", + "meta-field-icon": "联邦徽标图标的URL", + "meta-field-welcome": "欢迎新用户加入联邦的欢迎信息", + "meta-field-gateways": "由联邦审核的网关标识符列表", + "your-own-fields": "您也可以向提案添加自定义的元字段。这些将被添加到所有连接到您的联盟的客户端的元数据中,可以用于您喜欢的任何目的。", + "meta-effect-add": "添加", + "meta-effect-modify": "修改", + "meta-effect-unchanged": "未改变", + "proposals": "提案" + } + }, + "modal": { + "client-connect": "连接客户端" + }, + "danger-zone": { + "danger-zone-label": "危险区域", + "cancel": "取消", + "danger-zone-description": "小心使用!", + "guardian-warning-message": "警告:不要与任何人分享此代码。任何拥有此代码的人都可以作为监护人进行身份验证。请确保您处于私密的位置,没有人在看您的屏幕。", + "guardian-acknowledge": "确认并揭示代码", + "acknowledge-and-download": "确认并继续", + "guardian-authenticate": "作为监护人进行身份验证", + "guardian-connect-warning": "不要分享这个", + "backup": { + "label": "备份", + "title": "下载备份", + "warning-title": "警告", + "warning-text": "备份包含联邦监护人的私钥和秘密材料,必须保持安全。使用此备份进行恢复需要您的管理员密码!", + "cancelButton": "取消", + "acknowledgeButton": "确认并下载" + }, + "sign-api-announcement": { + "label": "签名API公告", + "title": "签名API公告", + "description": "签署新的API公告。", + "current-api-url": "来自本地配置的API URL", + "announced-api-url": "您的API URL来自联邦公告", + "urls-match": "您当前的API URL与您公布的API URL相匹配。", + "urls-mismatch": "您已在本地配置中更改了API URL,需要广播新的API公告。", + "sign-button": "签署新API公告", + "signing-in-progress": "正在登录中...", + "sign-tooltip": "签署API公告,向联盟公布您的API URL。" + }, + "schedule-shutdown": { + "label": "安排关机", + "title": "安排关机", + "description": "安排您的监护节点在特定会话高度后关闭,以协调升级您的fedimintd二进制文件。", + "current-session": "当前会话", + "session-to-shutdown": "会话将在关闭", + "confirm-shutdown": "确认关机", + "session-to-shutdown-helper": "输入您希望关闭守护节点的会话高度。" + } + } + }, + "login": { + "title": "欢迎回来!", + "subtitle": "请输入您的密码。", + "password": "密码", + "submit": "提交" + }, + "role-selector": { + "disclaimer-title": "Fedimint是测试版软件", + "disclaimer-text": "请在https://github.com/fedimint/fedimint/issues报告问题。", + "leader": { + "label": "设置领导者", + "description": "输入其他守护者批准的配置设置。一个守护者充当设置领导者。" + }, + "follower": { + "label": "追随者", + "description": "一旦设置领导者设定了配置,其他守护者选择此选项来批准设置并创建联邦。" + }, + "solo": { + "label": "独奏", + "description": "以单人守护者的身份运行Fedimint,无需达成共识,无需容错,联邦备份或Fedimint的其他恢复能力。请谨慎进行,不建议用于生产使用。" + }, + "warning-modal": { + "title": "大家都准备好了吗?", + "description": "退出设置仪式可能会导致设置失败,并需要您重新启动您的守护者。请确保每个人都准备好进行完整设置再继续!" + } + }, + "run-dkg": { + "error-config": "无法运行分布式密钥生成。必须重新启动联邦设置。", + "error-default": "尚未准备好DKG,您当前的状态是", + "error-header": "发生了错误。", + "waiting-header": "等待同伴", + "generating-header": "生成代码" + }, + "set-config": { + "bft-explanation-title": "您的联盟的拜占庭容错性", + "bft-explanation": "一个{{total}}守护者联盟创建了一个{{honest}}/{{total}}阈值。", + "bft-faulty": "您的联盟将能够容忍{{faulty}}个故障、离线或恶意的守护者,而不影响联盟的运营。", + "guardian-name": "监护人姓名", + "guardian-name-help": "在设置过程中,这个随机名称将会展示给其他守护者。", + "acknowledge-backed-up": "我,{{guardianName}}(您的监护人姓名),承诺我已备份并保护好我的密码:", + "admin-password": "管理员密码", + "admin-password-generate": "生成", + "admin-password-set": "点击“生成”以创建安全密码。您可以修改它,但这个密码必须是安全的并且备份!", + "admin-password-help": "备份此密码并妥善保管!您无法找回此密码!", + "admin-password-backup": "我正在使用一个强密码并已经备份。 (你无法恢复这个密码!)", + "confirm-and-backup-password": "确认并备份密码", + "confirm-password": "确认密码", + "error-password-mismatch": "密码不匹配", + "join-federation": "加入联邦链接", + "join-federation-help": "向创建联邦的人请求链接,并在此处粘贴。", + "basic-settings": "基础知识", + "federation-settings": "联邦设置", + "federation-name": "联邦名称", + "guardian-number": "监护人的数量", + "guardian-number-help": "联邦需要至少4名监护人。这个规定以后不能更改。", + "bitcoin-settings": "比特币设置", + "block-confirmations": "额外区块确认", + "block-confirmations-help": "Fedimint Guardians通过几次确认来跟踪区块链的尖端,以避免区块重组。", + "block-confirmations-help-mainnet": "在主网上运行至少需要额外的5个确认。", + "block-confirmations-warning": "以少于5个额外区块确认运行Fedimint非常危险!Fedimint无法处理区块链重组。", + "bitcoin-network": "比特币网络", + "select-network": "选择一个网络", + "bitcoin-rpc-kind": "比特币RPC种类", + "set-rpc-help": "为您的守护节点提供比特币区块数据的来源", + "bitcoin-rpc": "比特币RPC网址", + "read-from-env": "(从环境变量中检测到)", + "error-valid-number": "请输入有效的数字。", + "error-valid-min": "请输入一个至少为{{min}}的数字。", + "error-valid-max": "请输入一个最大不超过{{max}}的数字。", + "error-valid-min-max": "请输入一个介于{{min}}和{{max}}之间的数字。", + "error-guardian-name-mismatch": "监护人姓名不匹配", + "meta-fields": "元字段", + "meta-fields-description": "有关更多信息,请参阅文档。", + "meta-fields-key": "元键", + "meta-fields-value": "价值", + "meta-fields-effect": "效果", + "meta-fields-add-another": "添加另一个", + "meta-fields-title": "您的元提案:", + "network": "网络", + "password-warning-title": "备份您的密码!", + "password-warning": "您必须备份您的密码并妥善保管。这个密码是访问您的监护人仪表板所必需的。如果您丢失了它,您将无法恢复!" + }, + "setup": { + "warning": { + "title": "在设置过程中请勿退出或刷新!", + "description": "在设置过程中退出可能会导致设置失败,您将不得不重新启动。" + }, + "common": { + "restart-setup": "重新启动设置", + "restart-setup-alert": "设置负责人已重新启动设置仪式。请点击下方的“重新开始”以继续。", + "confirm-restart-setup": "您确定要重新开始设置仪式吗?", + "confirm-restart-setup-alert": "点击“重新开始”将为所有守护者重新开始仪式。" + }, + "progress": { + "tos": { + "title": "服务条款" + }, + "start": { + "title": "欢迎,守护者!", + "subtitle": "让我们来设置您的联邦。", + "step": "联邦详情" + }, + "set-config": { + "title": "我们需要为您的联邦设置一些配置。", + "title-solo": "我们需要为您的Solo联盟设置一些配置。", + "subtitle-leader": "您的联盟追随者将在他们那端确认这些信息。", + "subtitle-solo": "运行单个联盟将失去许多Fedimint的优点。您将无法容忍监护人离线的故障共识,并且无法进行联合备份。请谨慎进行,不建议用于生产使用或与主网比特币一起使用。", + "subtitle-follower": "您的联盟领导将会设置主要的联盟详情。您将很快确认它们。", + "step": "联邦详情" + }, + "connect-guardians": { + "title-leader": "邀请你的监护人", + "title-follower": "确认您的联邦信息", + "subtitle-leader": "与其他守护者分享链接,以便让所有人达到共识。一旦所有的守护者加入,你将自动进入下一步。", + "subtitle-follower": "请确保这里的信息正确无误,联邦守护者也是正确的。当你确定一切都好时,点击批准按钮。", + "step-leader": "邀请守护者", + "step-follower": "确认信息" + }, + "run-dkg": { + "title": "成功!", + "subtitle": "所有守护者都已验证联邦设置详情。正在运行一些数字..." + }, + "verify-guardians": { + "title": "验证您的监护人", + "subtitle": "向每个监护人询问他们的验证码,并将其粘贴在下方以检查有效性。我们快完成了!", + "step": "验证监护人", + "leader-confirm-done": "确认所有的追随者守护者已点击“下一步”并查看他们的守护者仪表板后再继续。", + "leader-confirm-done-emphasis": "点击“继续”将完成设置仪式。" + }, + "setup-complete": { + "step": "完成!" + }, + "error": { + "title": "未知步骤", + "subtitle": "你是怎么来到这里的?!" + } + } + }, + "setup-complete": { + "header": "🎉 🎉 🎉", + "congratulations": "祝贺你", + "leader-message": "所有监护人的验证代码已经过验证。", + "follower-message": "你已经完成了!让其他守护者知道你正在运行!", + "continue": "继续" + }, + "terms-of-service": { + "agree-and-continue": "同意并继续" + }, + "verify-guardians": { + "verified": "已验证", + "verified-placeholder": "在这里粘贴代码", + "error": "发生了错误。", + "error-peer-id": "无法确定您是哪位用户。请刷新并再试一次。", + "verification-code": "您({{peerName}})的验证码", + "verification-code-help": "与其他监护人分享此代码", + "table-title": "监护人验证代码", + "table-description": "在下方输入每个监护人的验证代码。", + "table-column-name": "姓名", + "table-column-status": "状态", + "table-column-hash-input": "粘贴验证码", + "wait-all-guardians-verification": "等待所有守护者验证他们的代码", + "all-guardians-verified": "所有守护者都已验证他们的代码", + "starting-consensus": "开始达成共识..." + }, + "footer": { + "docs-section-header": "文档", + "community-section-header": "社区", + "contribute-section-header": "贡献", + "getting-started-link-text": "开始入门", + "faq-link-text": "常见问题", + "blog-link-text": "博客", + "discord-link-text": "Discord", + "twitter-link-text": "推特", + "github-link-text": "GitHub" + }, + "admin": { + "fetch-info-modal-text": "检查联邦详情..." + }, + "balance-card": { + "card_header": "电子现金余额", + "sentence": "以Sats计价", + "your-balance": "您在此联盟的电子现金余额:" + }, + "connect-federation": { + "connect": "连接 🚀", + "connect-federation-button": "添加联盟", + "connection-string-placeholder": "粘贴联盟邀请码", + "heading": "使用邀请码连接到联盟", + "information-bar-text": "您可以连接的联盟数量仅限于一个。即将支持连接到多个联盟。", + "label": "连接字符串:", + "progress-modal-text": "正在连接到联邦...", + "sub-heading": "邀请码是一个以‘fed1’开头的长字符串。", + "error-message": "连接联邦时出错:{{error}}" + }, + "wallet": { + "title": "钱包", + "ecash": "电子现金", + "lightning": "闪电", + "onchain": "Onchain", + "total": "总计", + "balance": "平衡", + "address": "地址", + "invoice": "发票", + "receive": "接收", + "send": "发送", + "create-address": "创建地址", + "to-federation": "至联邦", + "from-federation": "来自联邦", + "sent": "发送", + "sent-amount": "发送了{{amount}}", + "to-address": "致地址", + "txid": "交易ID", + "claimed-note": "声称的笔记", + "claimed-amount": "声称金额" + }, + "wallet-modal": { + "title": "钱包操作", + "receive": { + "ecash-instructions": "在此处粘贴您的电子现金票据", + "paste-ecash-placeholder": "在此处粘贴电子现金票据", + "redeem": "兑换", + "paste-invoice": "在此处粘贴发票", + "enter-amount": "输入{{unit}}的金额", + "lightning-instructions": "输入sats金额以创建闪电发票", + "create-peg-in-address": "创建锚定地址", + "create-lightning-invoice": "创建Lightning发票", + "paste-ecash-button": "粘贴电子现金票据", + "peg-in-instructions": "将比特币发送到此地址,以便将其锚定到您的{{federationName}}电子现金余额中。", + "ecash-claimed-success": "成功领取电子现金!", + "address-error": "创建地址错误:{{error}}" + }, + "send": { + "submit": "提交", + "to-onchain-address": "至Onchain地址", + "address-placeholder": "bc1p...", + "peg-out-to-onchain": "将Peg Out Ecash转移到Onchain", + "peg-out-success": "发送Peg Out TX!", + "create-ecash": "创建电子现金票据", + "ecash-created": "从您的{{federationName}}余额中提取了{{amount}}电子现金票据。将其发送给收款人进行认领。", + "ecash-error": "创建电子现金票据时出错:{{error}}" + } + }, + "federation-card": { + "table-title": "联邦", + "id": "ID", + "name": "姓名", + "balance": "平衡", + "actions": "行动", + "receive": "接收", + "send": "发送", + "default-federation-name": "联邦", + "view-link-on": "在{{host}}上查看", + "leave-fed-error": "无法在余额中还有sats的情况下离开联盟。请先提取您的sats。", + "leave-fed-modal-title": "离开联邦", + "leave-fed-modal-text": "您确定要断开连接吗?", + "view-config": "查看配置", + "config-for": "{{federationId}}的配置" + }, + "header": { + "active": "活跃", + "all": "所有", + "archived": "已归档", + "ascending": "上升", + "connect": "联合联接", + "date-created": "创建日期", + "descending": "下降", + "filter": "过滤器", + "sort": "排序", + "title": "闪电网关仪表板" + }, + "info-card": { + "card-header": "闪电节点信息", + "node-id": "节点ID", + "alias": "别名", + "mode": "模式", + "pubkey": "公钥", + "network": "网络", + "block-height": "区块高度", + "synced-to-chain": "同步到链条" + }, + "withdraw-card": { + "address-label": "您的地址:", + "address-placeholder": "输入您的比特币地址", + "amount-label": "金额(sats):", + "amount-placeholder": "输入sats金额", + "card-header": "提取比特币", + "close": "关闭", + "confirm-withdraw": "确认提款", + "error": "错误", + "error-address": "金额或地址不能为空", + "error-amount": "金额不能为空或等于零", + "error-request": "无法请求提款", + "request-from": "要求提款自", + "requested-withdrawal": "要求提款", + "to": "至", + "total_bitcoin": "总比特币:", + "transaction-sent": "交易已发送!", + "view": "查看", + "view-it-on": "在上面查看它", + "withdraw": "取款", + "withdraw-all": "提取全部", + "withdrawal-created": "已创建提款。", + "withdrawal-created-description": "请检查您的交易历史记录", + "withdrawal-history": "提款历史", + "your-transaction": "您的交易ID:" + } +} diff --git a/apps/router/src/react-app-env.d.ts b/apps/router/src/react-app-env.d.ts new file mode 100644 index 000000000..7a99ee99a --- /dev/null +++ b/apps/router/src/react-app-env.d.ts @@ -0,0 +1,7 @@ +/// + +// Fonts are handled by react-scripts as well +declare module '*.ttf' { + const src: string; + export default src; +} diff --git a/apps/router/src/setupProxy.js b/apps/router/src/setupProxy.js new file mode 100644 index 000000000..413f1f4cb --- /dev/null +++ b/apps/router/src/setupProxy.js @@ -0,0 +1,13 @@ +module.exports = function (app) { + app.get('/config.json', (req, res) => { + if (process.env.REACT_APP_FM_CONFIG_API) { + res.json({ + baseUrl: process.env.REACT_APP_FM_CONFIG_API, + }); + } else if (process.env.REACT_APP_FM_GATEWAY_API) { + res.json({ + baseUrl: process.env.REACT_APP_FM_GATEWAY_API, + }); + } + }); +}; diff --git a/apps/router/tsconfig.json b/apps/router/tsconfig.json new file mode 100644 index 000000000..e7ff0b0fa --- /dev/null +++ b/apps/router/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "@fedimint/tsconfig/react-app.json", + "compilerOptions": { + "typeRoots": ["node_modules/@types/", "../node_modules/@types/"] + }, + "exclude": ["dist", "node_modules"], + "include": ["src", "../../packages/ui/src/Header.tsx"] +} diff --git a/mprocs-nix-guardian.yml b/mprocs-nix-guardian.yml index c7cbf7cdf..be0178b1f 100644 --- a/mprocs-nix-guardian.yml +++ b/mprocs-nix-guardian.yml @@ -19,25 +19,25 @@ procs: devimint: shell: tail -n +0 -F $FM_LOGS_DIR/devimint.log guardian-ui-1: - shell: yarn dev:guardian-ui + shell: yarn dev env: PORT: '3000' REACT_APP_FM_CONFIG_API: ws://127.0.0.1:18138 BROWSER: none guardian-ui-2: - shell: yarn dev:guardian-ui + shell: yarn dev env: PORT: '3001' REACT_APP_FM_CONFIG_API: ws://127.0.0.1:18140 BROWSER: none guardian-ui-3: - shell: yarn dev:guardian-ui + shell: yarn dev env: PORT: '3002' REACT_APP_FM_CONFIG_API: ws://127.0.0.1:18142 BROWSER: none guardian-ui-4: - shell: yarn dev:guardian-ui + shell: yarn dev env: PORT: '3003' REACT_APP_FM_CONFIG_API: ws://127.0.0.1:18144 diff --git a/package.json b/package.json index 3bf1cee40..26a082570 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,8 @@ { "private": true, "scripts": { - "dev:gateway-ui": "turbo run dev --filter=gateway-ui...", - "dev:guardian-ui": "turbo run dev --filter=guardian-ui...", + "dev": "turbo run dev", "build": "turbo run build", - "build:gateway-ui": "turbo run build --filter=gateway-ui...", - "build:guardian-ui": "turbo run build --filter=guardian-ui...", "clean": "turbo run clean", "format": "prettier --write \"**/*.{ts,tsx,md}\"", "lint": "turbo run lint", diff --git a/packages/types/src/federation.ts b/packages/types/src/federation.ts index 64a665778..769b3b06e 100644 --- a/packages/types/src/federation.ts +++ b/packages/types/src/federation.ts @@ -2,7 +2,7 @@ import type { MSats } from './bitcoin'; import { AnyModuleParams, ModuleConfigs, ModuleKind } from './modules'; import { MetaConfig } from './meta'; -export enum ServerStatus { +export enum GuardianServerStatus { AwaitingPassword = 'awaiting_password', SharingConfigGenParams = 'sharing_config_gen_params', ReadyForConfigGen = 'ready_for_config_gen', @@ -30,7 +30,7 @@ export interface Peer { cert: string; api_url: string; p2p_url: string; - status: ServerStatus; + status: GuardianServerStatus; } export type PeerHashMap = Record; @@ -44,7 +44,7 @@ export interface FederationStatus { } export interface StatusResponse { - server: ServerStatus; + server: GuardianServerStatus; federation?: FederationStatus; } diff --git a/packages/ui/src/Header.tsx b/packages/ui/src/Header.tsx index 0d6c9c46d..2bfc371cf 100644 --- a/packages/ui/src/Header.tsx +++ b/packages/ui/src/Header.tsx @@ -19,7 +19,7 @@ export const Header = React.memo(function Header({ justifyContent={['center', 'flex-start']} gap='2' > - <> + - +
{endChildrenSlot} diff --git a/packages/ui/src/Wrapper.tsx b/packages/ui/src/Wrapper.tsx index aad036bf3..556281b9f 100644 --- a/packages/ui/src/Wrapper.tsx +++ b/packages/ui/src/Wrapper.tsx @@ -1,19 +1,18 @@ import React, { memo } from 'react'; -import { Box, Flex } from '@chakra-ui/react'; +import { Box, Flex, useBreakpointValue } from '@chakra-ui/react'; import { Header, HeaderProps } from './Header'; import { Footer } from './Footer'; export interface WrapperProps { headerProps?: HeaderProps; children: React.ReactNode; - size?: 'md' | 'lg'; } export const Wrapper = memo(function Wrapper({ headerProps, children, - size = 'md', }: WrapperProps): JSX.Element { + const size = useBreakpointValue({ base: 'md', lg: 'lg' }); return ( => { + const hashBuffer = await window.crypto.subtle.digest( + 'SHA-256', + new TextEncoder().encode(input) + ); + return Array.from(new Uint8Array(hashBuffer)) + .map((b) => b.toString(16).padStart(2, '0')) + .join(''); +}; diff --git a/scripts/mprocs-nix-gateway.sh b/scripts/mprocs-nix-gateway.sh index 7c992cbab..afdc6baa3 100644 --- a/scripts/mprocs-nix-gateway.sh +++ b/scripts/mprocs-nix-gateway.sh @@ -41,4 +41,4 @@ echo "Local gateway api addr: $LOCAL_GATEWAY_API_ADDR" export REACT_APP_FM_GATEWAY_API=$LOCAL_GATEWAY_API_ADDR export REACT_APP_FM_GATEWAY_PASSWORD=$FM_GATEWAY_PASSWORD -yarn dev:gateway-ui +yarn dev diff --git a/scripts/mprocs-nix-guardian-manual.sh b/scripts/mprocs-nix-guardian-manual.sh index a4ff84f58..d76c16492 100644 --- a/scripts/mprocs-nix-guardian-manual.sh +++ b/scripts/mprocs-nix-guardian-manual.sh @@ -24,4 +24,4 @@ fi export REACT_APP_FM_CONFIG_API="ws://127.0.0.1:$CONFIG_PORT" # Start the guardian UI -yarn dev:guardian-ui +yarn dev diff --git a/scripts/mprocs-nix-guardian.sh b/scripts/mprocs-nix-guardian.sh index 9cfe4f8be..df1ecfbda 100644 --- a/scripts/mprocs-nix-guardian.sh +++ b/scripts/mprocs-nix-guardian.sh @@ -17,4 +17,4 @@ fi CONFIG_PORT=$(($FM_PORT_FEDIMINTD_BASE + $FM_SERVER)) # Fedimintd 0 config AOU port is always base + 1 export REACT_APP_FM_CONFIG_API="ws://127.0.0.1:$CONFIG_PORT" -yarn dev:guardian-ui +yarn dev diff --git a/scripts/translate.js b/scripts/translate.js index 9c017df02..858107352 100644 --- a/scripts/translate.js +++ b/scripts/translate.js @@ -16,22 +16,8 @@ const languages = [ 'zh', ]; -let srcPaths = []; -const targetFile = process.argv[2]; -switch (targetFile) { - case 'gateway': - srcPaths = ['apps/gateway-ui/src/languages']; - break; - case 'guardian': - srcPaths = ['apps/guardian-ui/src/languages']; - break; - default: - srcPaths = [ - 'apps/gateway-ui/src/languages', - 'apps/guardian-ui/src/languages', - ]; -} -const targetKey = process.argv[3]; +let srcPaths = ['apps/router/src/languages']; +const targetKey = false; async function installOpenAI() { console.log('Installing OpenAI package...'); diff --git a/turbo.json b/turbo.json index 671d9c6eb..00e899889 100644 --- a/turbo.json +++ b/turbo.json @@ -20,11 +20,25 @@ "dependsOn": ["^build"], "env": ["REACT_APP_FM_GATEWAY_API", "REACT_APP_FM_GATEWAY_PASSWORD"] }, + "router#build": { + "outputs": ["build/**", "dist/**"], + "dependsOn": ["^build", "^guardian-ui#build", "^gateway-ui#build"], + "env": [ + "REACT_APP_FM_CONFIG_API", + "REACT_APP_TOS", + "REACT_APP_FM_GATEWAY_API", + "REACT_APP_FM_GATEWAY_PASSWORD" + ] + }, "test": { "outputs": ["coverage/**"], "dependsOn": [] }, - "lint": {}, + "lint": { + "outputs": [], + "dependsOn": ["^build"], + "cache": false + }, "dev": { "cache": false, "persistent": true @@ -57,6 +71,14 @@ "@fedimint/ui#build" ] }, + "@fedimint/router#dev": { + "cache": false, + "dependsOn": [ + "@fedimint/types#build", + "@fedimint/utils#build", + "@fedimint/ui#build" + ] + }, "clean": { "cache": false } diff --git a/vercel.json b/vercel.json new file mode 100644 index 000000000..e69de29bb diff --git a/yarn.lock b/yarn.lock index f39ea7814..93fd7d7fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1046,9 +1046,9 @@ regenerator-runtime "^0.13.11" "@babel/runtime@^7.18.6": - version "7.23.9" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7" - integrity sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw== + version "7.25.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.6.tgz#9afc3289f7184d8d7f98b099884c26317b9264d2" + integrity sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ== dependencies: regenerator-runtime "^0.14.0" @@ -1897,57 +1897,24 @@ resolved "https://registry.yarnpkg.com/@chakra-ui/visually-hidden/-/visually-hidden-2.0.15.tgz#60df64e0ab97d95fee4e6c61ccabd15fd5ace398" integrity sha512-WWULIiucYRBIewHKFA7BssQ2ABLHLVd9lrUo3N3SZgR0u4ZRDDVEUNOy+r+9ruDze8+36dGbN9wsN1IdELtdOw== -"@codemirror/autocomplete@^0.20.0": - version "0.20.3" - resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-0.20.3.tgz#affe2d7e2b2e0be42ee1ac5fb74a1c84a6f1bfd7" - integrity sha512-lYB+NPGP+LEzAudkWhLfMxhTrxtLILGl938w+RcFrGdrIc54A+UgmCoz+McE3IYRFp4xyQcL4uFJwo+93YdgHw== - dependencies: - "@codemirror/language" "^0.20.0" - "@codemirror/state" "^0.20.0" - "@codemirror/view" "^0.20.0" - "@lezer/common" "^0.16.0" - "@codemirror/autocomplete@^6.0.0": - version "6.12.0" - resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-6.12.0.tgz#3fa620a8a3f42ded7751749916e8375f6bbbb333" - integrity sha512-r4IjdYFthwbCQyvqnSlx0WBHRHi8nBvU+WjJxFUij81qsBfhNudf/XKKmmC2j3m0LaOYUQTf3qiEK1J8lO1sdg== + version "6.18.0" + resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-6.18.0.tgz#5f39b05daca04c95e990b70024144df47b2aa635" + integrity sha512-5DbOvBbY4qW5l57cjDsmmpDh3/TeK1vXfTHa+BUMrRzdWdcxKZ4U4V7vQaTtOpApNU4kLS4FQ6cINtLg245LXA== dependencies: "@codemirror/language" "^6.0.0" "@codemirror/state" "^6.0.0" "@codemirror/view" "^6.17.0" "@lezer/common" "^1.0.0" -"@codemirror/basic-setup@^0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@codemirror/basic-setup/-/basic-setup-0.20.0.tgz#ed331e0b2d29efc0a09317de9e10467b992b0c7b" - integrity sha512-W/ERKMLErWkrVLyP5I8Yh8PXl4r+WFNkdYVSzkXYPQv2RMPSkWpr2BgggiSJ8AHF/q3GuApncDD8I4BZz65fyg== - dependencies: - "@codemirror/autocomplete" "^0.20.0" - "@codemirror/commands" "^0.20.0" - "@codemirror/language" "^0.20.0" - "@codemirror/lint" "^0.20.0" - "@codemirror/search" "^0.20.0" - "@codemirror/state" "^0.20.0" - "@codemirror/view" "^0.20.0" - -"@codemirror/commands@^0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@codemirror/commands/-/commands-0.20.0.tgz#51405d442e6b8687b63e8fa27effc28179917c88" - integrity sha512-v9L5NNVA+A9R6zaFvaTbxs30kc69F6BkOoiEbeFw4m4I0exmDEKBILN6mK+GksJtvTzGBxvhAPlVFTdQW8GB7Q== - dependencies: - "@codemirror/language" "^0.20.0" - "@codemirror/state" "^0.20.0" - "@codemirror/view" "^0.20.0" - "@lezer/common" "^0.16.0" - "@codemirror/commands@^6.0.0", "@codemirror/commands@^6.1.0": - version "6.3.3" - resolved "https://registry.yarnpkg.com/@codemirror/commands/-/commands-6.3.3.tgz#03face5bf5f3de0fc4e09b177b3c91eda2ceb7e9" - integrity sha512-dO4hcF0fGT9tu1Pj1D2PvGvxjeGkbC6RGcZw6Qs74TH+Ed1gw98jmUgd2axWvIZEqTeTuFrg1lEB1KV6cK9h1A== + version "6.6.1" + resolved "https://registry.yarnpkg.com/@codemirror/commands/-/commands-6.6.1.tgz#6beaf2f94df1af1e7d4a811dff4fea2ac227b49c" + integrity sha512-iBfKbyIoXS1FGdsKcZmnrxmbc8VcbMrSgD7AVrsnX+WyAYjmUDWvE93dt5D874qS4CCVu4O1JpbagHdXbbLiOw== dependencies: "@codemirror/language" "^6.0.0" "@codemirror/state" "^6.4.0" - "@codemirror/view" "^6.0.0" + "@codemirror/view" "^6.27.0" "@lezer/common" "^1.1.0" "@codemirror/lang-json@^6.0.1": @@ -1958,22 +1925,10 @@ "@codemirror/language" "^6.0.0" "@lezer/json" "^1.0.0" -"@codemirror/language@^0.20.0": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@codemirror/language/-/language-0.20.2.tgz#31c3712eac2251810986272dcd6a50510e0c1529" - integrity sha512-WB3Bnuusw0xhVvhBocieYKwJm04SOk5bPoOEYksVHKHcGHFOaYaw+eZVxR4gIqMMcGzOIUil0FsCmFk8yrhHpw== - dependencies: - "@codemirror/state" "^0.20.0" - "@codemirror/view" "^0.20.0" - "@lezer/common" "^0.16.0" - "@lezer/highlight" "^0.16.0" - "@lezer/lr" "^0.16.0" - style-mod "^4.0.0" - "@codemirror/language@^6.0.0": - version "6.10.0" - resolved "https://registry.yarnpkg.com/@codemirror/language/-/language-6.10.0.tgz#2d0e818716825ee2ed0dacd04595eaa61bae8f23" - integrity sha512-2vaNn9aPGCRFKWcHPFksctzJ8yS5p7YoaT+jHpc0UGKzNuAIx4qy6R5wiqbP+heEEdyaABA582mNqSHzSoYdmg== + version "6.10.2" + resolved "https://registry.yarnpkg.com/@codemirror/language/-/language-6.10.2.tgz#4056dc219619627ffe995832eeb09cea6060be61" + integrity sha512-kgbTYTo0Au6dCSc/TFy7fK3fpJmgHDv1sG1KNQKJXVi+xBTEeBPY/M30YXiU6mMXeH+YIDLsbrT4ZwNRdtF+SA== dependencies: "@codemirror/state" "^6.0.0" "@codemirror/view" "^6.23.0" @@ -1982,51 +1937,28 @@ "@lezer/lr" "^1.0.0" style-mod "^4.0.0" -"@codemirror/lint@^0.20.0": - version "0.20.3" - resolved "https://registry.yarnpkg.com/@codemirror/lint/-/lint-0.20.3.tgz#34c0fd45c5acd522637f68602e3a416162e03a15" - integrity sha512-06xUScbbspZ8mKoODQCEx6hz1bjaq9m8W8DxdycWARMiiX1wMtfCh/MoHpaL7ws/KUMwlsFFfp2qhm32oaCvVA== - dependencies: - "@codemirror/state" "^0.20.0" - "@codemirror/view" "^0.20.2" - crelt "^1.0.5" - "@codemirror/lint@^6.0.0": - version "6.4.2" - resolved "https://registry.yarnpkg.com/@codemirror/lint/-/lint-6.4.2.tgz#c13be5320bde9707efdc94e8bcd3c698abae0b92" - integrity sha512-wzRkluWb1ptPKdzlsrbwwjYCPLgzU6N88YBAmlZi8WFyuiEduSd05MnJYNogzyc8rPK7pj6m95ptUApc8sHKVA== + version "6.8.1" + resolved "https://registry.yarnpkg.com/@codemirror/lint/-/lint-6.8.1.tgz#6427848815baaf68c08e98c7673b804d3d8c0e7f" + integrity sha512-IZ0Y7S4/bpaunwggW2jYqwLuHj0QtESf5xcROewY6+lDNwZ/NzvR4t+vpYgg9m7V8UXLPYqG+lu3DF470E5Oxg== dependencies: "@codemirror/state" "^6.0.0" "@codemirror/view" "^6.0.0" crelt "^1.0.5" -"@codemirror/search@^0.20.0": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@codemirror/search/-/search-0.20.1.tgz#9eba0514218a673e29501a889a4fcb7da7ce24ad" - integrity sha512-ROe6gRboQU5E4z6GAkNa2kxhXqsGNbeLEisbvzbOeB7nuDYXUZ70vGIgmqPu0tB+1M3F9yWk6W8k2vrFpJaD4Q== - dependencies: - "@codemirror/state" "^0.20.0" - "@codemirror/view" "^0.20.0" - crelt "^1.0.5" - "@codemirror/search@^6.0.0": - version "6.5.5" - resolved "https://registry.yarnpkg.com/@codemirror/search/-/search-6.5.5.tgz#cf97e201da364da2285c2a250167af25bbd2a4a2" - integrity sha512-PIEN3Ke1buPod2EHbJsoQwlbpkz30qGZKcnmH1eihq9+bPQx8gelauUwLYaY4vBOuBAuEhmpDLii4rj/uO0yMA== + version "6.5.6" + resolved "https://registry.yarnpkg.com/@codemirror/search/-/search-6.5.6.tgz#8f858b9e678d675869112e475f082d1e8488db93" + integrity sha512-rpMgcsh7o0GuCDUXKPvww+muLA1pDJaFrpq/CCHtpQJYz8xopu4D1hPcKRoDD0YlF8gZaqTNIRa4VRBWyhyy7Q== dependencies: "@codemirror/state" "^6.0.0" "@codemirror/view" "^6.0.0" crelt "^1.0.5" -"@codemirror/state@^0.20.0": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-0.20.1.tgz#de5c6dc0de3e216eaa3a9ee9391c926b766f6b46" - integrity sha512-ms0tlV5A02OK0pFvTtSUGMLkoarzh1F8mr6jy1cD7ucSC2X/VLHtQCxfhdSEGqTYlQF2hoZtmLv+amqhdgbwjQ== - "@codemirror/state@^6.0.0", "@codemirror/state@^6.1.1", "@codemirror/state@^6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.4.0.tgz#8bc3e096c84360b34525a84696a84f86b305363a" - integrity sha512-hm8XshYj5Fo30Bb922QX9hXB/bxOAVH+qaqHBzw5TKa72vOeslyGwd4X8M0c1dJ9JqxlaMceOQ8RsL9tC7gU0A== + version "6.4.1" + resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.4.1.tgz#da57143695c056d9a3c38705ed34136e2b68171b" + integrity sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A== "@codemirror/theme-one-dark@^6.0.0": version "6.1.2" @@ -2038,19 +1970,10 @@ "@codemirror/view" "^6.0.0" "@lezer/highlight" "^1.0.0" -"@codemirror/view@^0.20.0", "@codemirror/view@^0.20.2": - version "0.20.7" - resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-0.20.7.tgz#1d0acc740f71f92abef4b437c030d4e6c39ab6dc" - integrity sha512-pqEPCb9QFTOtHgAH5XU/oVy9UR/Anj6r+tG5CRmkNVcqSKEPmBU05WtN/jxJCFZBXf6HumzWC9ydE4qstO3TxQ== - dependencies: - "@codemirror/state" "^0.20.0" - style-mod "^4.0.0" - w3c-keyname "^2.2.4" - -"@codemirror/view@^6.0.0", "@codemirror/view@^6.17.0", "@codemirror/view@^6.23.0": - version "6.23.1" - resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-6.23.1.tgz#1ce3039a588d6b93f153b7c4c035c2075ede34a6" - integrity sha512-J2Xnn5lFYT1ZN/5ewEoMBCmLlL71lZ3mBdb7cUEuHhX2ESoSrNEucpsDXpX22EuTGm9LOgC9v4Z0wx+Ez8QmGA== +"@codemirror/view@^6.0.0", "@codemirror/view@^6.17.0", "@codemirror/view@^6.23.0", "@codemirror/view@^6.27.0": + version "6.33.0" + resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-6.33.0.tgz#51e270410fc3af92a6e38798e80ebf8add7dc3ec" + integrity sha512-AroaR3BvnjRW8fiZBalAaK+ZzB5usGgI014YKElYZvQdNH5ZIidHlO+cyf/2rWzyBFRkvG6VhiXeAEbC53P2YQ== dependencies: "@codemirror/state" "^6.4.0" style-mod "^4.1.0" @@ -2200,13 +2123,6 @@ resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43" integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ== -"@emotion/is-prop-valid@^0.8.2": - version "0.8.8" - resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" - integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== - dependencies: - "@emotion/memoize" "0.7.4" - "@emotion/is-prop-valid@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz#23116cf1ed18bfeac910ec6436561ecb1a3885cc" @@ -2214,11 +2130,6 @@ dependencies: "@emotion/memoize" "^0.8.1" -"@emotion/memoize@0.7.4": - version "0.7.4" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" - integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== - "@emotion/memoize@^0.8.1": version "0.8.1" resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" @@ -2644,27 +2555,15 @@ resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== -"@lezer/common@^0.16.0": - version "0.16.1" - resolved "https://registry.yarnpkg.com/@lezer/common/-/common-0.16.1.tgz#3b98b42fdb11454b89e8a340da10bee1b0f94071" - integrity sha512-qPmG7YTZ6lATyTOAWf8vXE+iRrt1NJd4cm2nJHK+v7X9TsOF6+HtuU/ctaZy2RCrluxDb89hI6KWQ5LfQGQWuA== - "@lezer/common@^1.0.0", "@lezer/common@^1.1.0", "@lezer/common@^1.2.0": version "1.2.1" resolved "https://registry.yarnpkg.com/@lezer/common/-/common-1.2.1.tgz#198b278b7869668e1bebbe687586e12a42731049" integrity sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ== -"@lezer/highlight@^0.16.0": - version "0.16.0" - resolved "https://registry.yarnpkg.com/@lezer/highlight/-/highlight-0.16.0.tgz#95f7b7ee3c32c8a0f6ce499c085e8b1f927ffbdc" - integrity sha512-iE5f4flHlJ1g1clOStvXNLbORJoiW4Kytso6ubfYzHnaNo/eo5SKhxs4wv/rtvwZQeZrK3we8S9SyA7OGOoRKQ== - dependencies: - "@lezer/common" "^0.16.0" - "@lezer/highlight@^1.0.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@lezer/highlight/-/highlight-1.2.0.tgz#e5898c3644208b4b589084089dceeea2966f7780" - integrity sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA== + version "1.2.1" + resolved "https://registry.yarnpkg.com/@lezer/highlight/-/highlight-1.2.1.tgz#596fa8f9aeb58a608be0a563e960c373cbf23f8b" + integrity sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA== dependencies: "@lezer/common" "^1.0.0" @@ -2677,73 +2576,13 @@ "@lezer/highlight" "^1.0.0" "@lezer/lr" "^1.0.0" -"@lezer/lr@^0.16.0": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@lezer/lr/-/lr-0.16.3.tgz#1e4cc581d2725c498e6a731fc83c379114ba3a70" - integrity sha512-pau7um4eAw94BEuuShUIeQDTf3k4Wt6oIUOYxMmkZgDHdqtIcxWND4LRxi8nI9KuT4I1bXQv67BCapkxt7Ywqw== - dependencies: - "@lezer/common" "^0.16.0" - "@lezer/lr@^1.0.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@lezer/lr/-/lr-1.4.0.tgz#ed52a75dbbfbb0d1eb63710ea84c35ee647cb67e" - integrity sha512-Wst46p51km8gH0ZUmeNrtpRYmdlRHUpN1DQd3GFAyKANi8WVz8c2jHYTf1CVScFaCjQw1iO3ZZdqGDxQPRErTg== + version "1.4.2" + resolved "https://registry.yarnpkg.com/@lezer/lr/-/lr-1.4.2.tgz#931ea3dea8e9de84e90781001dae30dea9ff1727" + integrity sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA== dependencies: "@lezer/common" "^1.0.0" -"@motionone/animation@^10.12.0": - version "10.15.1" - resolved "https://registry.yarnpkg.com/@motionone/animation/-/animation-10.15.1.tgz#4a85596c31cbc5100ae8eb8b34c459fb0ccf6807" - integrity sha512-mZcJxLjHor+bhcPuIFErMDNyrdb2vJur8lSfMCsuCB4UyV8ILZLvK+t+pg56erv8ud9xQGK/1OGPt10agPrCyQ== - dependencies: - "@motionone/easing" "^10.15.1" - "@motionone/types" "^10.15.1" - "@motionone/utils" "^10.15.1" - tslib "^2.3.1" - -"@motionone/dom@10.12.0": - version "10.12.0" - resolved "https://registry.yarnpkg.com/@motionone/dom/-/dom-10.12.0.tgz#ae30827fd53219efca4e1150a5ff2165c28351ed" - integrity sha512-UdPTtLMAktHiqV0atOczNYyDd/d8Cf5fFsd1tua03PqTwwCe/6lwhLSQ8a7TbnQ5SN0gm44N1slBfj+ORIhrqw== - dependencies: - "@motionone/animation" "^10.12.0" - "@motionone/generators" "^10.12.0" - "@motionone/types" "^10.12.0" - "@motionone/utils" "^10.12.0" - hey-listen "^1.0.8" - tslib "^2.3.1" - -"@motionone/easing@^10.15.1": - version "10.15.1" - resolved "https://registry.yarnpkg.com/@motionone/easing/-/easing-10.15.1.tgz#95cf3adaef34da6deebb83940d8143ede3deb693" - integrity sha512-6hIHBSV+ZVehf9dcKZLT7p5PEKHGhDwky2k8RKkmOvUoYP3S+dXsKupyZpqx5apjd9f+php4vXk4LuS+ADsrWw== - dependencies: - "@motionone/utils" "^10.15.1" - tslib "^2.3.1" - -"@motionone/generators@^10.12.0": - version "10.15.1" - resolved "https://registry.yarnpkg.com/@motionone/generators/-/generators-10.15.1.tgz#dc6abb11139d1bafe758a41c134d4c753a9b871c" - integrity sha512-67HLsvHJbw6cIbLA/o+gsm7h+6D4Sn7AUrB/GPxvujse1cGZ38F5H7DzoH7PhX+sjvtDnt2IhFYF2Zp1QTMKWQ== - dependencies: - "@motionone/types" "^10.15.1" - "@motionone/utils" "^10.15.1" - tslib "^2.3.1" - -"@motionone/types@^10.12.0", "@motionone/types@^10.15.1": - version "10.15.1" - resolved "https://registry.yarnpkg.com/@motionone/types/-/types-10.15.1.tgz#89441b54285012795cbba8612cbaa0fa420db3eb" - integrity sha512-iIUd/EgUsRZGrvW0jqdst8st7zKTzS9EsKkP+6c6n4MPZoQHwiHuVtTQLD6Kp0bsBLhNzKIBlHXponn/SDT4hA== - -"@motionone/utils@^10.12.0", "@motionone/utils@^10.15.1": - version "10.15.1" - resolved "https://registry.yarnpkg.com/@motionone/utils/-/utils-10.15.1.tgz#6b5f51bde75be88b5411e084310299050368a438" - integrity sha512-p0YncgU+iklvYr/Dq4NobTRdAPv9PveRDUXabPEeOjBLSO/1FNB2phNTZxOxpi1/GZwYpAoECEa0Wam+nsmhSw== - dependencies: - "@motionone/types" "^10.15.1" - hey-listen "^1.0.8" - tslib "^2.3.1" - "@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1": version "5.1.1-v1" resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129" @@ -2792,6 +2631,11 @@ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.7.tgz#ccab5c8f7dc557a52ca3288c10075c9ccd37fff7" integrity sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw== +"@remix-run/router@1.19.2": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.19.2.tgz#0c896535473291cb41f152c180bedd5680a3b273" + integrity sha512-baiMx18+IMuD1yyvOGaHM9QrVUPGGG0jC+z+IPHnRJWUAUvaKuWKyE8gjDj2rzv3sz9zOGoRSPgeBVHRhZnBlA== + "@rollup/plugin-babel@^5.2.0": version "5.3.1" resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283" @@ -3276,13 +3120,6 @@ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.5.tgz#75a2a8e7d8ab4b230414505d92335d1dcb53a6df" integrity sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ== -"@types/qrcode.react@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/qrcode.react/-/qrcode.react-1.0.2.tgz#f892432cc41b5dac52e3ca8873b717c8bfea6002" - integrity sha512-I9Oq5Cjlkgy3Tw7krCnCXLw2/zMhizkTere49OOcta23tkvH0xBTP0yInimTh0gstLRtb8Ki9NZVujE5UI6ffQ== - dependencies: - "@types/react" "*" - "@types/qs@*": version "6.9.7" resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" @@ -3500,10 +3337,10 @@ "@typescript-eslint/types" "5.59.5" eslint-visitor-keys "^3.3.0" -"@uiw/codemirror-extensions-basic-setup@4.21.21": - version "4.21.21" - resolved "https://registry.yarnpkg.com/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.21.21.tgz#243ef309cb53253b14187649a7abc0d996420a20" - integrity sha512-+0i9dPrRSa8Mf0CvyrMvnAhajnqwsP3IMRRlaHDRgsSGL8igc4z7MhvUPn+7cWFAAqWzQRhMdMSWzo6/TEa3EA== +"@uiw/codemirror-extensions-basic-setup@4.23.2": + version "4.23.2" + resolved "https://registry.yarnpkg.com/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.23.2.tgz#90772ca73424d797bfae94aaa9a1b61ce0203c6c" + integrity sha512-eacivkj7wzskl2HBYs4rfN0CbYlsSQh5ADtOYWTpc8Txm4ONw8RTi4/rxF6Ks2vdaovizewU5QaHximbxoNTrw== dependencies: "@codemirror/autocomplete" "^6.0.0" "@codemirror/commands" "^6.0.0" @@ -3513,32 +3350,32 @@ "@codemirror/state" "^6.0.0" "@codemirror/view" "^6.0.0" -"@uiw/codemirror-theme-github@^4.21.21": - version "4.21.21" - resolved "https://registry.yarnpkg.com/@uiw/codemirror-theme-github/-/codemirror-theme-github-4.21.21.tgz#0e0fd13500e6c17032a9b9fccb276e13f6681a91" - integrity sha512-msrpNrKk/CZQHk58TshI8aH7FpEyL404m/vWlGUdL2jGW7IRKm0nXn1lXXQ/snzk65h88GO6u9fiiv0pxRuZfQ== +"@uiw/codemirror-theme-github@^4.23.2": + version "4.23.2" + resolved "https://registry.yarnpkg.com/@uiw/codemirror-theme-github/-/codemirror-theme-github-4.23.2.tgz#9f2e9667faf133bb5395ce82f0e866ab3db46c47" + integrity sha512-CFH6JVwQ8MPRiY32Fy13I+iiD56eYE8jBpGjtPZPiYDcxAmRNU++x79vCguO3dpXUvqSJ9bPjcHbz4wOXxCVEw== dependencies: - "@uiw/codemirror-themes" "4.21.21" + "@uiw/codemirror-themes" "4.23.2" -"@uiw/codemirror-themes@4.21.21": - version "4.21.21" - resolved "https://registry.yarnpkg.com/@uiw/codemirror-themes/-/codemirror-themes-4.21.21.tgz#26efb06ecce9a51aa73d39311c90f8fcb06fdc43" - integrity sha512-ljVcMGdaxo75UaH+EqxJ+jLyMVVgeSfW2AKyT1VeLy+4SDpuqNQ7wq5XVxktsG6LH+OvgSFndWXgPANf4+gQcA== +"@uiw/codemirror-themes@4.23.2": + version "4.23.2" + resolved "https://registry.yarnpkg.com/@uiw/codemirror-themes/-/codemirror-themes-4.23.2.tgz#67c40eed4675fa803289068f54ef4f97e1cd31d1" + integrity sha512-g8x+oPqgbzxXSkHhRf7e1AM1mI9/Nl3URReS89pHitRKv8MZNrE+ey+HE8ycfNXRUatrb6zTSRV3M75uoZwNYw== dependencies: "@codemirror/language" "^6.0.0" "@codemirror/state" "^6.0.0" "@codemirror/view" "^6.0.0" -"@uiw/react-codemirror@^4.21.21": - version "4.21.21" - resolved "https://registry.yarnpkg.com/@uiw/react-codemirror/-/react-codemirror-4.21.21.tgz#986b18dbd6dc69aa470fc3d4e47b89b504af6778" - integrity sha512-PaxBMarufMWoR0qc5zuvBSt76rJ9POm9qoOaJbqRmnNL2viaF+d+Paf2blPSlm1JSnqn7hlRjio+40nZJ9TKzw== +"@uiw/react-codemirror@^4.23.2": + version "4.23.2" + resolved "https://registry.yarnpkg.com/@uiw/react-codemirror/-/react-codemirror-4.23.2.tgz#0b9078d0fc086ca7b75a3aa0eb3942c42919c156" + integrity sha512-MmFL6P5V1Mr81JLkJyWNedfxENKdRhsvyU7Izji9wp337m8dqRAz7rCF5XWarGKx+iQ7q2H5ryl07nLqKLSvtQ== dependencies: "@babel/runtime" "^7.18.6" "@codemirror/commands" "^6.1.0" "@codemirror/state" "^6.1.1" "@codemirror/theme-one-dark" "^6.0.0" - "@uiw/codemirror-extensions-basic-setup" "4.21.21" + "@uiw/codemirror-extensions-basic-setup" "4.23.2" codemirror "^6.0.0" "@vitalets/google-translate-api@^9.2.0": @@ -4361,9 +4198,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001449, caniuse-lite@^1.0.30001464: - version "1.0.30001486" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001486.tgz#56a08885228edf62cbe1ac8980f2b5dae159997e" - integrity sha512-uv7/gXuHi10Whlj0pp5q/tsK/32J2QSqVRKQhs2j8VsDCjgyruAh/eEXHF822VqO9yT6iZKw3nRwZRSPBE9OQg== + version "1.0.30001660" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001660.tgz" + integrity sha512-GacvNTTuATm26qC74pt+ad1fW15mlQ/zuTzzY1ZoIzECTP8HURDfF43kNxPgf7H1jmelCBQTTbBNxdSXOA7Bqg== case-sensitive-paths-webpack-plugin@^2.4.0: version "2.4.0" @@ -5075,11 +4912,6 @@ diff-sequences@^29.4.3: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2" integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA== -diff@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531" - integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A== - dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -6130,26 +5962,12 @@ fraction.js@^4.2.0: resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== -framer-motion@^6: - version "6.5.1" - resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-6.5.1.tgz#802448a16a6eb764124bf36d8cbdfa6dd6b931a7" - integrity sha512-o1BGqqposwi7cgDrtg0dNONhkmPsUFDaLcKXigzuTFC5x58mE8iyTazxSudFzmT6MEyJKfjjU8ItoMe3W+3fiw== +framer-motion@^11.5.4: + version "11.5.4" + resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-11.5.4.tgz#521b551bb6003918e7b24af3141626f6f443e2b3" + integrity sha512-E+tb3/G6SO69POkdJT+3EpdMuhmtCh9EWuK4I1DnIC23L7tFPrl8vxP+LSovwaw6uUr73rUbpb4FgK011wbRJQ== dependencies: - "@motionone/dom" "10.12.0" - framesync "6.0.1" - hey-listen "^1.0.8" - popmotion "11.0.3" - style-value-types "5.0.0" - tslib "^2.1.0" - optionalDependencies: - "@emotion/is-prop-valid" "^0.8.2" - -framesync@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/framesync/-/framesync-6.0.1.tgz#5e32fc01f1c42b39c654c35b16440e07a25d6f20" - integrity sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA== - dependencies: - tslib "^2.1.0" + tslib "^2.4.0" framesync@6.1.2: version "6.1.2" @@ -6451,11 +6269,6 @@ he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -hey-listen@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68" - integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q== - hoist-non-react-statics@^3.3.1: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" @@ -7718,10 +7531,10 @@ jsonpointer@^5.0.0: resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559" integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== -jsonrpc-client-websocket@^1.5.2: - version "1.5.4" - resolved "https://registry.yarnpkg.com/jsonrpc-client-websocket/-/jsonrpc-client-websocket-1.5.4.tgz#74a09a3d984ca9e3da9a96c8edc6fea50061ec88" - integrity sha512-6hvA+FVBNvdw/jr/yC/mFnB9ftw08rMV7iRivKUciLOEC3rrNBJdsRS1DkPDfVhiL+gbNUGbZKkJc2W2ynz+7A== +jsonrpc-client-websocket@^1.5.5: + version "1.5.5" + resolved "https://registry.yarnpkg.com/jsonrpc-client-websocket/-/jsonrpc-client-websocket-1.5.5.tgz#ad27879f65f4c37060ca219d82369e2f0e10d3c9" + integrity sha512-VauPiNUOkGyqWF4LV8NR84YL4M9LG+oJyfi8wyx6xItt4VG+ZitsSlJurNxFA0ge219nGzi9yVhu8PhZ9AFKzQ== dependencies: get-parameter-names "^0.3.0" @@ -8139,11 +7952,6 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" -node-bin-setup@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/node-bin-setup/-/node-bin-setup-1.1.3.tgz#d45d5220e3b2ecc3a94263a56116f727f6c1bb14" - integrity sha512-opgw9iSCAzT2+6wJOETCpeRYAQxSopqQ2z+N6BXwIMsQQ7Zj5M8MaafQY8JMlolRR6R1UXg2WmhKp0p9lSOivg== - node-fetch@^2.6.7: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" @@ -8166,13 +7974,6 @@ node-releases@^2.0.8: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== -node@^20.1.0: - version "20.1.0" - resolved "https://registry.yarnpkg.com/node/-/node-20.1.0.tgz#3a6b2ca2413d31f8aa8d1b5d84deea990183a3de" - integrity sha512-KEdvvfuL5jfQTFN6Evul7qqI1zYQ/eljdsIHkQOS+FW86l7ZTNfOEru/OzprVP1X0jLfRDPDz0wvucCOWOotQg== - dependencies: - node-bin-setup "^1.0.0" - normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -8532,16 +8333,6 @@ pkg-up@^3.1.0: dependencies: find-up "^3.0.0" -popmotion@11.0.3: - version "11.0.3" - resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-11.0.3.tgz#565c5f6590bbcddab7a33a074bb2ba97e24b0cc9" - integrity sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA== - dependencies: - framesync "6.0.1" - hey-listen "^1.0.8" - style-value-types "5.0.0" - tslib "^2.1.0" - postcss-attribute-case-insensitive@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz#03d761b24afc04c09e757e92ff53716ae8ea2741" @@ -9237,10 +9028,10 @@ qr-scanner@^1.4.2: dependencies: "@types/offscreencanvas" "^2019.6.4" -qrcode.react@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/qrcode.react/-/qrcode.react-3.1.0.tgz#5c91ddc0340f768316fbdb8fff2765134c2aecd8" - integrity sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q== +qrcode.react@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/qrcode.react/-/qrcode.react-4.0.1.tgz#1caf1d3f45bf1b6d9cf800cb0f0d671f6a89e68f" + integrity sha512-Lpj0tPBn561WiQ3QQWXbkx8xTtB8BZkJeMZWLJIL8iaPBCoWzW1IpCeU3gY5MDqsb0+efCvEGkl9O0naP64crA== qrloop@^1.4.1: version "1.4.1" @@ -9383,10 +9174,10 @@ react-i18next@^13.0.2: "@babel/runtime" "^7.22.5" html-parse-stringify "^3.0.1" -react-icons@^4.7.1: - version "4.8.0" - resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.8.0.tgz#621e900caa23b912f737e41be57f27f6b2bff445" - integrity sha512-N6+kOLcihDiAnj5Czu637waJqSnwlMNROzVZMhfX68V/9bu9qHaMIJC4UdozWoOk57gahFCNHwVvWzm0MTzRjg== +react-icons@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.3.0.tgz#ccad07a30aebd40a89f8cfa7d82e466019203f1c" + integrity sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg== react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" @@ -9434,6 +9225,21 @@ react-remove-scroll@^2.5.5: use-callback-ref "^1.3.0" use-sidecar "^1.1.2" +react-router-dom@^6.26.2: + version "6.26.2" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.26.2.tgz#a6e3b0cbd6bfd508e42b9342099d015a0ac59680" + integrity sha512-z7YkaEW0Dy35T3/QKPYB1LjMK2R1fxnHO8kWpUMTBdfVzZrWOiY9a7CtN8HqdWtDUWd5FY6Dl8HFsqVwH4uOtQ== + dependencies: + "@remix-run/router" "1.19.2" + react-router "6.26.2" + +react-router@6.26.2: + version "6.26.2" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.26.2.tgz#2f0a68999168954431cdc29dd36cec3b6fa44a7e" + integrity sha512-tvN1iuT03kHgOFnLPfLJ8V95eijteveqdOSk+srqfePtQvqCExB8eHOYnlilbOcyJyKnYkr1vJvf7YqotAJu1A== + dependencies: + "@remix-run/router" "1.19.2" + react-scripts@5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-5.0.1.tgz#6285dbd65a8ba6e49ca8d651ce30645a6d980003" @@ -9498,11 +9304,6 @@ react-style-singleton@^2.2.1: invariant "^2.2.4" tslib "^2.0.0" -react-use-websocket@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/react-use-websocket/-/react-use-websocket-3.0.0.tgz#754cb8eea76f55d31c5676d4abe3e573bc2cea04" - integrity sha512-BInlbhXYrODBPKIplDAmI0J1VPM+1KhCLN09o+dzgQ8qMyrYs4t5kEYmCrTqyRuMTmpahylHFZWQXpfYyDkqOw== - react@^18.2.0: version "18.2.0" resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" @@ -10256,17 +10057,9 @@ style-loader@^3.3.1: integrity sha512-RHs/vcrKdQK8wZliteNK4NKzxvLBzpuHMqYmUVWeKa6MkaIQ97ZTOS0b+zapZhy6GcrgWnvWYCMHRirC3FsUmw== style-mod@^4.0.0, style-mod@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/style-mod/-/style-mod-4.1.0.tgz#a313a14f4ae8bb4d52878c0053c4327fb787ec09" - integrity sha512-Ca5ib8HrFn+f+0n4N4ScTIA9iTOQ7MaGS1ylHcoVqW9J7w2w8PzN6g9gKmTYgGEBH8e120+RCmhpje6jC5uGWA== - -style-value-types@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-5.0.0.tgz#76c35f0e579843d523187989da866729411fc8ad" - integrity sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA== - dependencies: - hey-listen "^1.0.8" - tslib "^2.1.0" + version "4.1.2" + resolved "https://registry.yarnpkg.com/style-mod/-/style-mod-4.1.2.tgz#ca238a1ad4786520f7515a8539d5a63691d7bf67" + integrity sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw== stylehacks@^5.1.1: version "5.1.1" @@ -10587,11 +10380,16 @@ tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.1: +tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== +tslib@^2.4.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" + integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== + tsup@^5.10.1: version "5.12.9" resolved "https://registry.yarnpkg.com/tsup/-/tsup-5.12.9.tgz#8cdd9b4bc6493317cb92edf5f3476920dddcdb18"