diff --git a/frontend/README.md b/frontend/README.md index 6bc7d532..900d9a4b 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -50,7 +50,7 @@ yarn clean # clear previous build artifacts ### Usage -The app is currently available in English and Simplified Chinese. +The app is currently available in English, Simplified Chinese and Spanish. For more details on the internationalization approach and usage see [Quasar I18n doc v.1.18.10](https://v1.quasar.dev/options/app-internationalization#introduction) and [Vue I18n v8.x doc for Vue2](https://kazupon.github.io/vue-i18n/introduction.html). [Basic usage](https://v1.quasar.dev/options/app-internationalization#how-to-use) is as follows: diff --git a/frontend/src/i18n/index.ts b/frontend/src/i18n/index.ts index 4e4bc840..9d87bc17 100644 --- a/frontend/src/i18n/index.ts +++ b/frontend/src/i18n/index.ts @@ -1,7 +1,9 @@ import English from './locales/en-US.json'; import Chinese from './locales/zh-CN.json'; +import Spanish from './locales/es-ES.json'; export default { 'en-US': English, 'zh-CN': Chinese, + 'es-ES': Spanish, }; diff --git a/frontend/src/i18n/locales/es-ES.json b/frontend/src/i18n/locales/es-ES.json new file mode 100644 index 00000000..b88ef8d0 --- /dev/null +++ b/frontend/src/i18n/locales/es-ES.json @@ -0,0 +1,511 @@ +{ + "Home": { + "header": "Envía Pagos Ocultos", + "description": "Solo el emisor y el receptor sabrán quien ha recibido los fondos", + "Tutorial": { + "tutorial": "Tutorial", + "receiving-funds": "Recibir fondos", + "receive-first": "Usa la página Configurar para empezar a configurar tu cuenta", + "receive-second": "Pídele a alguien que te envíe fondos a tu dirección, a tu ENS o a tu CNS a través de la dApp de Umbra", + "receive-third": "Consulta la página Recibir para retirar tus fondos", + "sending-funds": "Enviar fondos", + "send-first": "Consigue la dirección, el ENS o CNS de la persona a la que quieres enviar fondos", + "send-second": "Completa el formulario de la página Enviar" + }, + "banner-donate": "Por favor, considera donar a la {DevelopmentGrant} para Umbra en la ronda de Gitcoin. {LearnMore}", + "banner-passport": "Si donaste a Umbra durante la ronda de Gitcoin, debes {configurePassport} para optar. {LearnMore}", + "supporting": "apoyando", + "configure-passport": "configurar el pasaporte de Gitcoin", + "learn-more": "Aprende más", + "development-grant": "subvención de desarrollo" + }, + "Home-action-card": { + "send": "Enviar", + "send-description": "Enviar fondos a otro usuario", + "receive": "Recibir", + "receive-description": "Consultar y retirar los fondos recibidos", + "setup": "Configurar", + "setup-description": "Configurar tu cuenta para recibir fondos" + }, + "Header-Links": { + "home": "Inicio", + "FAQ": "FAQ", + "contact": "Contacto" + }, + "Base-Layout": { + "clear-local-storage": "Borrar almacenamiento local", + "clear-local-storage-description": "Borra todos los datos del almacenamiento local, incluido el historial de envíos, los anuncios de pago y la conexión a la wallet.", + "connect-wallet": "Conectar Wallet", + "settings": "Ajustes", + "dark-mode": "Modo oscuro", + "advanced-mode": "Modo pro", + "advanced-mode-description": "Habilita funciones avanzadas como la exportación de claves privadas, opciones adicionales de IDs del receptor y ajustes para escaneo de eventos.", + "caution": "¡Úsalo con cuidado, forastero!", + "on": "activado", + "off": "desactivado", + "about": "Acerca de", + "built-by": "Creado con ❤️ por {0}", + "links": "Enlaces", + "send-history": "Historial de envíos", + "send-history-description": "Permite guardar el historial de envíos localmente en el navegador para poder verlo en la página \"Historial de envíos\"." + }, + "Address-Settings": { + "advanced-mode-on": "Modo pro activado" + }, + "Contact": { + "contact": "Contacto", + "paragraph": "¿Has leído {0} y aún tienes preguntas? ¡No dudes en ponerte en contacto con nosotros! Probablemente te responderemos más rápido en Discord.", + "faq": "Preguntas frecuentes", + "discord": "{0} en Discord", + "join-us": "Únete a nosotros", + "twitter": "{0} Umbra en Twitter", + "follow": "Síguenos", + "email": "Envíanos un email a {0}" + }, + "Send": { + "sending-disabled": "El envío a través de Umbra se ha desactivado temporalmente mientras realizamos tareas de mantenimiento del sistema. ¡Volvemos pronto!", + "send": "Enviar", + "single-send": "Envío único", + "batch-send": "Envío por lotes", + "coming-soon": "¡Próximamente!", + "connect-your-wallet": "Conecta tu wallet para enviar fondos", + "connect-wallet": "Conectar Wallet", + "recipient": "ENS o dirección del receptor", + "recipient-pkey": "Enviar utilizando la clave pública estándar del receptor", + "question-circle": "Cuando esté marcado, la clave pública utilizada será la clave pública estándar para la dirección proporcionada. El receptor tendrá que introducir la clave privada de su cuenta en esta dApp para retirar sus fondos.", + "question-circle-warning": "No utilices esta función a menos que sepas lo que haces.", + "learn-more": "Aprende más", + "select-token": "Selecciona el token a enviar", + "slippage-exceeded": "La cantidad real enviada podría diferir materialmente de la estimada debido a los precios del gas. Por favor, inténtelo de nuevo.", + "token": "Token", + "amount": "Cantidad", + "summary": "Resumen", + "sending": "Enviando", + "fee": "Tarifa de Umbra", + "fee-explain": "Las transacciones en %{chainName} son muy baratas, por lo que se cobra una pequeña tarifa para evitar el spam en el protocolo.", + "total": "Total", + "max": "Max", + "max-native-less-than-toll": "No se puede enviar el máximo. El saldo es inferior al peaje de Umbra.", + "copy-payment-link": "Copiar enlace de pago", + "enter-an-amount": "Introduce una cantidad", + "enter-a-recipient": "Introduce un receptor", + "select-a-token": "Selecciona un token", + "select-a-token-for-send": "Selecciona un token para enviar", + "send-at-least": "Envía un mínimo", + "amount-exceeds-balance": "El importe supera el saldo disponible", + "total-amount-exceeds-balance": "El importe total enviado supera el saldo", + "please-complete-form": "Completa el formulario", + "wallet-not-connected": "Wallet no conectada", + "umbra-fee-exceeds-balance": "necesario para que la tarifa de Umbra supere el saldo disponible", + "advanced-send-warning": "El receptor tendrá que introducir la clave privada de su cuenta en esta dApp para retirar sus fondos. No utilices esta función a menos que sepas lo que haces.", + "acknowledge-risks": "Soy consciente de los riesgos", + "send-history": "Historial de envíos", + "add-send": "+ Añadir más", + "receiver-addr-ens": "ENS o dirección del receptor" + }, + "Receive": { + "receive": "Recibir", + "connect-your-wallet": "Conecta tu wallet para escanear los fondos recibidos", + "connect-wallet": "Conectar Wallet", + "need-signature-lately": "Firma para escanear los fondos recibidos recientemente", + "need-signature": "Esta dApp necesita de tu firma para escanear los fondos que has recibido", + "scan-funds": "Haz click a continuación para escanear los fondos que has recibido", + "sign": "Firmar", + "scan": "Escanear", + "scan-settings": "Ajustes de escaneo", + "start-end": "Introduce el bloque inicial o final que se utilizarán para buscar eventos. Un bloque inicial vacío escaneará desde el bloque cero, y un bloque final vacío escaneará hasta el bloque actual.", + "start-block": "Bloque inicial", + "end-block": "Bloque final", + "enter-prv-key": "Introduce la clave privada que se utilizará para buscar eventos. Una clave privada en blanco utilizará las generadas a partir de tu firma.", + "prv-key": "Clave privada", + "fetching": "Recuperando todos los anuncios de pago...", + "fetching-latest": "Recuperando los últimos 10.000 anuncios de pago...", + "fetching-latest-from-last-fetched-block": "Recuperando los últimos anuncios de pago...", + "scanning": "Escaneando todos los anuncios de pago en busca de fondos...", + "scanning-latest": "Escaneando los últimos anuncios de pago en busca de fondos...", + "scanning-latest-from-last-fetched-block": "Escaneando los últimos anuncios de pago...", + "wait": "Esto puede tardar un par de minutos dependiendo de tu conexión y dispositivo. Es normal— ten paciencia.", + "stop": "Detener" + }, + "Setup": { + "setup": "Configuración", + "connect-wallet": "Conecta tu wallet para configurar tu cuenta", + "generate-stealth": "Generar y publicar claves ocultas", + "paragraph": " Haz click en el siguiente botón para completar el proceso de configuración. Esto dará lugar a dos avisos en tu wallet:
  1. Firmar un mensaje para generar tu par de claves privadas específicas de Umbra. Estas claves, te permiten utilizar Umbra de forma segura sin comprometer las claves privadas de tu wallet conectada. ¡No es necesario que guardes estas claves en ningún sitio!
  2. Enviar una transacción que guarda las claves públicas correspondientes en el contrato, de modo que cualquiera pueda utilizarlas para enviarte pagos ocultos.
", + "setup-account": "Configurar cuenta", + "complete": "¡Configuración completada!", + "return-to-home": "Ahora puedes volver al {0} para enviar o recibir fondos", + "return-home": "inicio" + }, + "Error": { + "error": "¡Ups! Parece que aquí no están las claves privadas de Vitalik..." + }, + "FAQ": { + "faq": "Preguntas más frecuentes", + "intro": "Introducción", + "what-is-umbra": "¿Qué es Umbra?", + "what-is-umbra-answer": "

Umbra es un protocolo de direcciones ocultas para Ethereum. Esto significa que permite a un pagador enviar fondos a una dirección nueva. Esa dirección está controlada por el receptor previsto, pero sólo el pagador y el receptor lo saben.

Una manera de pensar en Umbra es la siguiente: Imagina que, antes de que alguien te envíe fondos, le envías una dirección nueva, nunca antes utilizada. Sólo el emisor sabría que controlas esa dirección, lo que añade una capa de privacidad al pago. Los pagos a través de Umbra funcionan de una forma similar, pero no son interactivos: no necesitas dar a nadie una dirección nueva, simplemente pueden generar una a la que saben que solo tú podrás acceder.

", + "an-example": "¿Me puedes poner un ejemplo?", + "an-example-answer": "

Alice tiene un negocio y contrata a Bob para que le haga de subcontratista. Alice acuerda pagar a Bob 1.000 DAI/semana por su trabajo. Bob posee el ENS bob.eth. Si Alice enviara los fondos cada semana a bob.eth, cualquiera que mirara la cadena podría saber de forma fácil que Alice está pagando a Bob 1.000 DAI cada semana.

En su lugar, Bob y Alice utilizarán Umbra para realizar pagos privados. La primera vez que Bob entra a la dApp de Umbra, crea su cuenta, lo que permite a cualquiera pagarle de forma privada utilizando su dirección. Entonces, Alice usa Umbra para enviar 1.000 DAI a Bob cada semana— solo necesita conocer su dirección o ENS.

On-chain, vemos que Alice paga 1.000 DAI a una nueva dirección vacía cada semana. Entre bastidores, Bob controla las claves de cada una de estas direcciones a través de Umbra, pero nadie excepto Alice y Bob lo sabe.

Bob usa Umbra para retirar sus 1.000 DAI cada semana. Sólo tiene que proporcionar una dirección a la que enviarlo. Lo mejor para él es utilizar una dirección que NO esté vinculada a su identidad. Suele optar por enviarlo directamente a un CEX, donde lo vende por FIAT cuando lo necesita. Esto significa que el CEX de Bob ahora sabe que este pago fue para él. Para el observador casual de la cadena— que no tiene acceso a la información privada del CEX— el hecho de que el pago de Alice fuera para Bob queda oculto.

Veamos otro ejemplo: Liza dirige un sitio web que solicita donaciones. Si todo el mundo donara enviando directamente sus fondos, todo el mundo sabría cuánto recibió Liza en donaciones. Si, por el contrario, las donaciones se enviaran con Umbra, cada donación se enviaría a una dirección diferente y sólo Liza sabría la cantidad total de donaciones que ha recibido.

", + "wen-token": "¿Tiene token Umbra?", + "wen-token-answer": "No.", + "how-does-it-work": "¿Cómo funciona?", + "how-does-it-work-answer": "

A continuación se presenta una descripción general de como funciona Umbra:

  1. Al crear tu cuenta, firmas un mensaje. El hash de este mensaje se utiliza para generar dos claves privadas: —una \"clave de gasto\" y una \"clave de visualización\".
  2. Las claves públicas correspondientes se publican en el contrato como registros asociados a tu dirección.
  3. Un pagador utiliza tu dirección o ENS para buscar tus dos claves públicas. Por separado, el pagador genera un número aleatorio.
  4. El número aleatorio se utiliza con la clave pública de gasto para generar una \"dirección oculta\" a la que enviar los fondos. El mismo número aleatorio se utiliza con la clave pública de visualización para cifrar el número aleatorio.
  5. Utilizando el contrato de Umbra, el pagador envía fondos a la dirección oculta y los datos cifrados se emiten como un evento de Anuncio de Pago.
  6. El receptor escanea todos los eventos de Anuncio de Pago del contrato de Umbra. Para cada uno de ellos, utiliza su clave privada de visualización logrando así descifrar el número aleatorio y, a continuación, multiplica ese número por su clave privada de gasto para generar la clave privada oculta. Si la clave privada oculta controla la dirección a la que se enviaron los fondos, este pago era para el receptor.
  7. Ahora, el receptor puede utilizar la clave privada para enviar directamente a otra dirección la transacción necesaria para retirar los fondos, o firmar una meta-transacción para que un relay procese la solicitud de retirada.
", + "how-does-it-work-see-the": "Revisa la sección {0} para más detalles.", + "how-does-it-work-technical-details": "Detalles técnicos: ¿Cómo funciona?", + "how-private": "¿Cómo de privada es Umbra?", + "how-private-answer": "

Umbra ofrece un conjunto limitado de garantías de privacidad y es importante entenderlas antes de utilizar el protocolo. Umbra NO ofrece \"completa\" privacidad como Aztec o Zcash. Simplemente hace que sea imposible para cualquier observador externo (es decir, cualquiera que no sea el emisor o el receptor) saber a quién pagó el emisor mirando la dirección de recepción.

Es importante entender que una mala higiene por parte del receptor— por ejemplo, enviar los fondos directamente a una dirección públicamente conocida— elimina las ventajas de privacidad tanto para el emisor como para el receptor.

Las propiedades de privacidad de Umbra también pueden verse mermadas si un observador puede reducir el conjunto de posibles receptores de una transacción determinada. Cualquier clave pública válida puede utilizarse como destinatario, y cualquiera que haya enviado una transacción en Ethereum tiene una clave pública disponible públicamente. Por tanto, por defecto, el \"conjunto de anonimato\"—el conjunto de posibles receptores de una transacción—¡es cualquiera que haya enviado alguna vez una transacción en Ethereum!

En la práctica, esto no es necesariamente así, y un observador puede reducir la lista de receptores de varias maneras:

  1. La mayoría de usuarios utilizarán el registro de claves ocultas de Umbra para enviar fondos, por lo que lo más probable es que el receptor tenga claves publicadas allí.
  2. Una mala higiene a la hora de retirar fondos de tus direcciones ocultas puede reducir o eliminar por completo las propiedades de privacidad que proporciona Umbra. Revisa la sección \"¿Qué direcciones son seguras para retirar fondos?\" para más detalles. ¡Ten siempre cuidado al retirar fondos!
", + "umbra-vs-mixer": "¿Es un mixer?", + "umbra-vs-mixer-answer": "

No. Umbra no es un mixer y no utiliza pruebas de cero conocimiento. En su lugar, Umbra se basa en criptografía de curva elíptica ordinaria. Está pensada para pagos entre dos entidades, y viene con un conjunto diferente de compensaciones de privacidad. En lugar de romper el vínculo entre la dirección emisora y la receptora, como un mixer, Umbra hace que ese vínculo carezca de sentido. Todo el mundo puede ver quién envió los fondos, y todo el mundo puede ver la dirección a la que se enviaron los fondos, pero esa dirección receptora nunca se ha visto en la blockchain, por lo que es imposible para cualquier observador externo saber quién la controla.

", + "account-setup": "Configuración", + "what-is-setup": "¿Qué es la configuración de la cuenta?", + "what-is-setup-answer": "

Un usuario firma un mensaje, y a partir de ese momento se generan las claves públicas y las claves privadas de Umbra. Se realiza una transacción en el registro de claves ocultas de Umbra, asociando las claves públicas a su dirección.

", + "is-setup-required": "¿Es necesario crear una cuenta?", + "is-setup-required-answer": "

Este paso no es técnicamente necesario, pero se recomienda encarecidamente por razones de seguridad. Para acceder a los fondos ocultos, la dApp de Umbra necesita tus claves privadas. Introducir tus claves privadas de tu wallet en cualquier sitio web es muy peligroso, ¡no queremos que lo hagas! Al pasar por el proceso de configuración de tu cuenta, firmas un mensaje para generar un conjunto de claves privadas de Umbra específico para la dApp. Esto es mucho más seguro, ya que Umbra nunca tiene la clave privada de tu wallet.

", + "why-setup-again": "¿Por qué tengo que volver a configurar mi cuenta?", + "why-setup-again-answer": "

Si configuraste tu cuenta de Umbra cuando el servicio aún estaba en beta—antes de Octubre de 2021—deberás rehacer la configuración. Esto requiere una firma y una transacción.

Este paso adicional se debe a una actualización del sistema de registros del resolver de ENS asociados a la dirección de un usuario. El nuevo sistema es mucho más sencillo y utiliza una simple correspondencia entre la dirección del usuario y sus claves ocultas.

El nuevo sistema se desarrolló en respuesta a los comentarios de los usuarios durante el periodo beta de Umbra. El nuevo sistema sólo requiere una transacción, y los emisores pueden proporcionar el ENS del receptor o su dirección normal. En general, el nuevo sistema es más sencillo de configurar y usar.

", + "why-setup-again-answer-issue": "Para una explicación aún más profunda y técnica de esta actualización, consulta {0} en el repositorio de Github de Umbra.", + "why-setup-again-answer-this-issue": "esta issue", + "sending-funds": "Enviar fondos", + "why-only-tokens": "¿Por qué sólo están disponibles algunos tokens?", + "why-only-tokens-answer": "

Cuando envías ETH, el ETH se envía directamente a la dirección oculta computada. Esa dirección oculta tiene ahora ETH, que se requiere para pagar el gas, por lo que el receptor puede transferir fácilmente ese ETH con un envío ordinario.

Cuando envías tokens, éstos no se envían directamente a la dirección oculta. Si fueran enviados, tendrías que conseguir ETH y enviarlo a la dirección oculta para pagar el gas y así poder retirar fondos (o utilizar alguno de los costosos esquemas CREATE2). En su lugar, los tokens son retenidos por el contrato y pueden ser liberados de dos formas:

  1. La dirección oculta llama directamente al método withdrawToken()
  2. Cualquier usuario llama al método withdrawTokenOnBehalf() y pasa una firma de la dirección oculta. Esto permite utilizar meta-transacciones con el relayer de tu elección.

Por defecto, la dApp de Umbra utiliza un relayer del equipo de Umbra. Gestionar los relayers y asegurarse de que se te reembolsan adecuadamente las tarifas de gas, puede ser complicado, así que para empezar sólo están habilitados unos pocos tokens y la lista de tokens soportados se irá ampliando.

", + "when-receive": "¿Cuándo recibirá el receptor sus fondos?", + "when-receive-answer": "

¡Inmediatamente! El receptor recibe y puede retirar fondos inmediatamente después de que la transacción de envío se haya minado.

", + "min-amount": "¿Por qué hay un importe mínimo de envío?", + "min-amount-answer": "

Cuando envías fondos con Umbra, la dirección del receptor es una dirección que nunca se ha utilizado antes. Esto significa que no tiene ni ETH ni tokens, por lo que debes pagar las retiradas utilizando los fondos que se te enviaron. Cuando se envía ETH, esto se hace con una transferencia normal. Cuando se envían tokens, esto se hace con un relayer para que las tarifas puedan ser pagadas con los tokens recibidos. Por lo tanto, hay una cantidad mínima de envío para asegurar que el receptor siempre pueda retirar sus fondos facilmente.

", + "umbra-fee": "¿Por qué a veces hay que pagar una tarifa de Umbra?", + "umbra-fee-answer": "

Para encontrar los fondos que has recibido a través de Umbra es necesario escanear todas las transacciones enviadas, y a continuación, comprobar cada una de ellas para saber cuáles son para tí.

En las redes con tarifas de transacción muy baratas, el contrato de Umbra cobra un pequeño peaje al enviar fondos para disuadir las transacciones de spam, ya que éste haría más dificil escanear todas las transacciones enviadas.

", + "payment-links": "¿Qué son los enlaces de pago?", + "payment-links-answer": "

Cuando en la página Enviar, rellenes una parte o la totalidad del formulario de envío y hagas click en el botón Copiar enlace de pago , esto copiará una URL al portapapeles que, cuando se visite, rellenará previamente el formulario de envío con los valores de la URL.

Ten cuidado al especificar una cantidad como parte de tu enlace de pago, ya que puede reducir la privacidad. Por ejemplo, si compartes un enlace de pago para que la gente pueda donarte 100 DAI, y de repente muchos envíos de 100 DAI empiezan a pasar por Umbra, los observadores sabrán que es muy probable que esas transferencias sean para tí.

", + "send-history-different-devices": "¿Por qué no puedo ver mi historial de envíos en distintos dispositivos?", + "send-history-different-devices-answer": "

On-chain, el receptor de tus transacciones de envío no es discernible. Esto es por diseño, y el punto de Umbra—dirección receptora, es una dirección oculta. Como resultado, no es posible sincronizar tu historial de envíos entre dispositivos observando el histórico on-chain.

En su lugar, tu historial de envíos está encriptado y almacenado en el almacenamiento local (localStorage) de tu navegador. Nunca sale de tu dispositivo, y por lo tanto, no se puede ver en otros dispositivos. Además, las transacciones enviadas antes de que se añadiera esta función a la dApp de Umbra en mayo del 2023 no se almacenan en ningún dispositivo.

", + "receiving-funds": "Recibir fondos", + "safe-address": "¿Qué direcciones son seguras para retirar fondos?", + "safe-address-answer": "

Te sugerimos 3 formas de retirar preservando tu privacidad. Ten en cuenta que cada una tiene sus propias ventajas e inconvenientes.

  1. Retirar a una dirección que no esté asociada públicamente con tu identidad (inconveniente: el emisor podrá deducir que controlas esa dirección)
  2. Generar una nueva dirección y retirar en ella (inconveniente: si has recibido tokens, tendrás que fundar esa dirección con ETH para pagar el gas para poder retirar)
  3. Retirar a una dirección de un CEX (inconveniente: si retiras a Coinbase, entonces Coinbase sabrá quien te envió los fondos)
", + "non-safe-address": "¿Qué direcciones NO son seguras para retirar fondos?", + "non-safe-address-answer": "

El riesgo que hay que tener en cuenta al retirar fondos es que si se hace a una dirección que está asociada a alguna identidad conocida públicamente, entonces se pierde la privacidad de la siguiente manera:

Digamos que Alice envía fondos a Bob a través de Umbra. Ahora, sólo Alice y Bob saben que Alice pagó a Bob. Cualquier otro observador sabe que Alice envió fondos a alguien, pero no saben quién es ese alguien.

Si Bob retira esos fondos a su dirección públicamente conocida bob.eth, que resuelve a 0x123...def, entonces los observadores saben que ha pasado una de estas cosas:

  1. Escenario 1: Alice envió fondos a Bob, entonces Bob los retiró a su propia dirección, O
  2. Escenario 2: Alice envió fondos a alguien que conoce a Bob, y pagó a Bob desde su dirección oculta

Además, considera el caso en el que Bob retira los fondos pagando directamente a su amigo Charlie—Charlie ahora sabe que Alice pagó a Bob.

Para ayudar a mitigar esto, la dApp de Umbra intentará advertirte si introduces una dirección de retirada que pueda reducir tu privacidad. Por lo tanto, verás advertencias si la dApp detecta que estás retirando a una dirección que:

  1. Está relacionada con un ENS o CNS
  2. Tiene tokens de POAP
  3. Es la wallet con la que estás conectado
  4. (Próximamente): Estás retirando a una dirección que ha contribuido a Gitcoin.

Esto no es una lista exhaustiva de direcciones de retirada potencialmente peligrosas, así que ten cuidado.

", + "umbra-withdrawal": "¿Puede Umbra facilitar la retirada de fondos preservando la privacidad?", + "umbra-withdrawal-answer": "

¡Si! Esta es un área en la que tenemos intención de hacer muchas mejoras en el futuro, sobre todo apoyándonos en la funcionalidad del hook post-retirada de Umbra.

Algunos ejemplos de cómo planeamos aprovechar esto incluyen:

  1. Cambiar automáticamente algunos tokens a ETH y enviarlos todos a una nueva dirección
  2. Retirar fondos directamente a los protocolos DeFi

Hay otras muchas opciones que podemos intentar a través de hooks para ampliar en gran medida la privacidad preservando las opciones de retirada.

", + "scan-time": "¿Por qué se tarda tanto en buscar mis fondos?", + "scan-time-answer": "

Para encontrar los pagos que se te han enviado, la dApp tiene que buscar en todos los pagos que se han enviado y comprobar si son para ti. Por tanto, cuantos más pagos se hayan enviado, más tiempo tardará.

", + "scan-time-answer-issue": "Se trata de un problema abierto con varias soluciones potenciales ({one}{two}), y esperamos mejorarlo con el tiempo.", + "when-withdrawal": "¿Cuándo puedo retirar mis fondos?", + "when-withdrawal-answer": "

¡Inmediatamente! Puedes retirar tus fondos inmediatamente después de que la transacción de envío sea minada.

", + "security": "Seguridad", + "audit": "¿Ha sido Umbra auditado?", + "audit-answer-contract": "Los {contracts} han sido auditados por ConsenSys Diligence, y el resultado de la auditoría puede encontrarse {here}.", + "audit-contracts": "contratos", + "audit-here": "aquí", + "audit-answer-umbra-js": "La {umbrajs} {library} responsable de gestionar la lógica off-chain y las operaciones de curva elíptica han sido auditadas por Least Authority, y el resultado de la auditoría puede consultarse {here}.", + "audit-library": "librería", + "audit-answer-umbra-off-chain": "Las operaciones de curva elíptica off-chain son una parte fundamental de la lógica de negocio de Umbra, por lo que confiamos en la sencilla librería {PaulMillers}, zero-dependency {nobleSecp256k1} para gestionarlas. Gracias a la {community}, pudimos recaudar fondos suficientes para pagar una auditoría de esta librería con Cure53. Puedes encontrar el resultado de la misma {here}.", + "audit-community": "comunidad", + "umbra-risk": "¿Cuáles son los riesgos de Umbra?", + "umbra-risk-answer": "

Como todo software en el ecosistema crypto, el uso de Umbra conlleva riesgos. Esto incluye riesgos de errores críticos, hackeos u otros ataques de actores maliciosos. Cualquiera de estos escenarios, o todos ellos, podría resultar en una pérdida de fondos.

Para ser más específicos, estos son algunos de los riesgos que hemos visto en otros proyectos del pasado:

  1. Vulnerabilidades en los contratos que permiten a los atacantes robar los fondos de los contratos o los dejan bloqueados.
  2. Un fallo en nuestro código off-chain que haga que los fondos se envíen a una dirección irrecuperable
  3. Un secuestro de DNS para robar las claves privadas de los usuarios.
  4. Ataques a los servicios de frontend para robar las claves privadas de los usuarios

Ni que decir tiene que estamos trabajando duro para evitarlos, pero eso no significa que vayamos a tener éxito. Los servicios de Umbra se proporcionan sin ninguna garantía, y debes utilizarlo bajo tu propia responsabilidad. [I] Añadir la explicación de que aunque exista un hackeo de los contratos, las claves públicas NO dan acceso a los fondos retirados ni a los fondos de la wallet firmante en el setup

", + "crypto-js": "¿Es segura la criptografía en JavaScript?", + "crypto-js-answer": "En general, un entorno de ejecución de JavaScript no es ideal para cumplir los requisitos de seguridad. Presenta desafíos a la hora de ocultar datos secretos en la memoria (por ejemplo, las claves privadas específicas de tu dApp) y en evitar que esos datos se escriban en el disco. Usar JavaScript también significa que la librería de criptografía subyacente puede ser susceptible a cosas como los {timingAttacks}. Umbra utiliza {nobleSecp256k1} para toda la criptografía, y puedes leer más sobre sus limitaciones y mitigación de tales vulnerabilidades {here}.", + "crypto-js-timing-attacks": "ataques de sincronización", + "crypto-js-here": "aquí", + "crypto-js-answer-rest": "

Sin embargo, el ecosistema de Ethereum consta de muchas wallets y aplicaciones que dependen de la criptografía en JavaScript y hasta ahora no ha habido problemas importantes, por lo que este enfoque es probablemente un compromiso adecuado para la mayoría de usuarios.

", + "tech-details": "Detalles técnicos", + "network-addrs": "¿En qué redes está desplegada Umbra y cuáles son las direcciones de sus contratos?", + "network-addrs-core": "El contrato principal de {umbra} está desplegado con esta dirección {umbraAddr} en {mainnet}, {sepolia}, {optimism}, {polygon}, {gnosis}, y {arbitrum}", + "network-addrs-registry": "El {stealthRegistry} está desplegado con esta dirección {stealthRegistryAddr} en {mainnet}, {sepolia}, {optimism}, {polygon}, {gnosis}, y {arbitrum}", + "how-it-works": "¿Cómo funciona?", + "how-it-works-answer": "

Visión general de las direcciones ocultas

Empecemos explicando como funciona el protocolo de Umbra (y más en general, cómo funcionan las direcciones ocultas) work:

El receptor tiene una clave pública P y una clave privada p. El emisor genera un número aleatorio r, y calcula una nueva clave pública oculta como P_oculta = P * r usando la multiplicación por curva elíptica. El emisor deriva la dirección a_oculta a partir de esa clave pública, y le envía los fondos. Gracias a la magia de las matemáticas de curva elíptica, el receptor puede generar la clave privada p_oculta necesaria para acceder a los fondos en a_oculta calculando p_oculta = p * r.

El primer problema que hay que resolver es cómo hace llegar el emisor el valor de r al receptor. Si r se conociera públicamente, los observadores de la cadena podrían determinar a quien se enviaron los fondos calculando P * r para varios valores de P publicados hasta encontrar la dirección oculta. Por tanto es necesario cifrar r.

", + "how-it-works-answer-ECDH": "El cifrado se realiza mediante {ECDH} (ECDH), lo que significa que el emisor utiliza la clave pública del receptor para cifrar el número aleatorio. El número aleatorio cifrado nos da el texto cifrado {c}. El número aleatorio cifrado {c} y la dirección oculta {aStealth} son emitidos como un evento de {announcement} del contrato de Umbra. ECDH requiere que el emisor genere una clave privada efímera para el cifrado, por lo que la clave pública efímera {PEphemeral} que el receptor necesitará para descifrar, también se emite en este evento.", + "how-it-works-answer-part-2": "

Ahora el receptor puede escanear a través de todos los eventos de Anuncio de Pago y encontrar sus fondos de la siguiente manera:

Clave privada de la dApp

Como se infiere de la explicación anterior, la dApp necesitará acceder a tu clave privada para realizar los cálculos necesarios. Pero cuando conectas tu wallet a una dApp, la wallet NO comparte tu clave privada con la dApp. Esto es bueno, porque si lo hiciera, ¡cualquier dApp que utilices podría robar tus fondos! Entonces, ¿cómo accede Umbra a tu clave? Hay varias opciones:

  1. Pedir al usuario que introduzca la clave privada de su wallet en un formulario. Esto es terrible, tanto desde el punto de vista de la seguridad como de la experiencia de usuario, así que \"Aquí no hacemos eso\"
  2. Generar una clave privada aleatoria y pedirte que hagas una copia de seguridad. Esto funciona, pero tener que hacer una copia de seguridad de un secreto específico de una dApp no es lo ideal.
  3. Pedir al usuario que firme un mensaje, hashear la firma y generar la clave a partir de la firma.
", + "how-it-works-answer-option-3": "La opción 3 resuelve los problemas de las opciones 1 y 2, y es la que utiliza la dApp. {loopring} and {zksync} también utilizan enfoques similares, que sirvieron de inspiración para este enfoque.", + "how-it-works-answer-end": "

Escaneo de fondos

La última consideración tiene que ver con el escaneo. Dado que hay que escanear todos y cada uno de los Anuncios de Pago, encontrar los tuyos puede llevar mucho tiempo.

Una forma de acelerarlo (desde la perspectiva del usuario) es delegar el escaneo en un servicio externo y hacer que le notifique cuando reciba fondos. Pero el servicio de escaneo necesita tu clave privada p para determinar si has recibido fondos, ¡y si tienen tú clave privada p pueden robarte los fondos!

Podemos resolver esto generando dos claves privadas. Una clave privada, será la de visualización, p_consulta, usada para encriptar el número aleatorio. La otra será la clave de gasto p_gasto, usada para calcular la dirección oculta y acceder a esos fondos. Por lo tanto, nuestro flujo de envío y recepción se modifica ahora un poco:

  1. El receptor tiene dos claves privadas, p_gasto y p_consulta, y publica las correspondientes claves públicas P_gasto y P_consulta.
  2. El emisor genera un número aleatorio r, lo cifra usando P_consulta y una clave privada efímera p_efímera para generar un texto cifrado c
  3. El emisor calcula la dirección oculta de esta forma P_oculta = P_gasto * r y envía los fondos a esa dirección
  4. El contrato inteligente de Umbra emite c, P_efímera, y la dirección oculta a_oculta
  5. Para cada evento, el receptor utiliza p_consulta y P_efímera para descifrar r, y luego comprueba si p_oculta = p_gasto * r es la clave privada que controla a_oculta

Con este enfoque, el receptor puede proporcionar a un servicio de análisis de terceros p_consulta y P_gasto. El servicio puede ahora comprobar si el destinatario ha recibido fondos sin tener la posibilidad de gastarlos.

", + "spend-view-keys": "¿Qué son las claves de gasto y de visualización?", + "spend-view-keys-answer-1": "Tomando prestada la {0} de Zcash, Umbra permite, pero no requiere, que los usuarios utilicen diferentes claves privadas para \"cifrar número aleatorio\" and \"calcular dirección oculta\". Este es el comportamiento por defecto de la dApp de Umbra, pero se puede anular utilizando el Modo Pro.", + "nomenclature": "nomenclatura", + "spend-view-keys-answer-2": "Consulta {0} para más detalles sobre el funcionamiento de las claves de gasto y visualización.", + "spend-view-keys-technical-details": "\"Detalles técnicos: ¿Cómo funciona?\"", + "advanced-mode": "Modo Pro", + "what-is-advanced": "¿Qué es el Modo Pro?", + "what-is-advanced-answer": "

Para los usuarios avanzados que entienden el protocolo, cómo funciona y los riesgos que implica, es posible que quieran activar el Modo Pro. Esto proporciona una serie de capacidades adicionales, pero el uso inadecuado puede resultar en la reducción de la privacidad o la pérdida de fondos. ¡Utilízalo con cuidado!

", + "send-to-pkey": "¿Cómo envío fondos a un usuario mediante su dirección o su clave pública?", + "send-to-pkey-answer": "

Siempre que un usuario haya enviado al menos una transacción en Ethereum, puedes enviar fondos a una dirección oculta que controle aunque no haya configurado su dirección para usarla con Umbra. Esto se hace de la siguiente manera:

  1. Activa el Modo Pro
  2. Ve a la página de Enviar y conecta tu wallet
  3. Marca la casilla que dice \"Enviar utilizando la clave pública estándar del receptor\"
  4. El campo Receptor normalmente sólo acepta direcciones que ya están guardadas en el registro de claves ocultas de Umbra, y utiliza las claves públicas publicadas allí para generar direcciones ocultas. Pero ahora, te permitirá poner cualquier dirección, y utilizar la clave pública estándar que subyace a esa dirección. También aceptará una clave pública, una dirección o ¡incluso un hash de una transacción! (Utilizar el hash de una transacción es lo mismo que introducir la dirección from (origen) de esa transacción)
  5. Continúa enviando fondos con normalidad

Ten en cuenta los siguientes inconvenientes al enviar fondos de esta forma:

  1. Esta transacción no utiliza claves de gasto y visualización separadas, y se utiliza la misma clave para cada una
  2. Para retirar los fondos de la dApp, el receptor debe activar el Modo Pro y pegar manualmente su clave privada en el sitio web. Este es el gran inconveniente, así que asegúrate de que el receptor está de acuerdo con esto antes de enviar los fondos de esta forma.
", + "access-funds": "¿Cómo puedo acceder a los fondos que se me envían utilizando mi dirección como identificador del receptor?", + "access-funds-answer": "

Si se te enviaron fondos utilizando directamente tu clave pública, tu dirección o un hash de transacción de una transacción que enviaste, todavía se puede acceder a tus fondos.

La forma más segura de hacerlo es localmente usando el paquete umbra-js :

  1. Configura un proyecto JavaScript con yarn init
  2. Instala ethers.js y umbra-js con yarn add ethers {'@'}umbra/umbra-js
  3. Crea un script del siguiente modo:
    1. Conectate a un provider de mainnet con ethers
    2. Inicializa una instancia de la clase Umbra con const umbra = new Umbra(provider, 1)
    3. Inicializa una instancia de la clase KeyPair con la clave privada de tu dirección, const keyPair = new KeyPair(myPrivateKey)
    4. Utiliza el método umbra.scan() para buscar tus fondos. El input viewingPrivateKey viene dado ahora por keyPair.privateKeyHex, y el input spendingPublicKey viene dado por keyPair.publicKeyHex
    5. Para cada Anuncio de Pago, puedes utilizar el método estático Umbra.computeStealthPrivateKey(keyPair.privateKeyHex, announcement.randomNumber) para calcular la clave privada oculta
  4. Ahora que tienes la(s) clave(s) privada(s), puedes firmar y retransmitir transacciones de retirada utilizando el método que prefieras. Consulta los distintos métodos de retirada de fondos de la clase Umbra que pueden ser útiles en este caso.

Si prefieres la comodidad a la seguridad, puedes retirar fondos utilizando la aplicación Umbra, pero ten cuidado—introducir tu clave privada en un sitio web nunca es buena idea! Si quieres seguir este camino:

  1. Activa el Modo Pro
  2. Ve a la página Recibir y conecta tu wallet
  3. Antes del escaneo, introduce la clave privada en el formulario
  4. Deja en blanco los campos de bloque inicial y bloque final si no los necesitas.
  5. Haz click en \"Escanear\" para buscar tus fondos
", + "scan-range": "¿Cómo puedo escanear un determinado rango de bloques?", + "scan-range-answer": "

Si tienes una idea aproximada de cuándo se te enviaron los fondos, puedes acelerar el proceso de escaneado consultando sólo los eventos que se encuentran dentro de un determinado rango de bloques. Para ello, haz esto:

  1. Activa el Modo Pro
  2. Ve a la página Recibir y conecta tu wallet
  3. Antes de escanear, introduce los números para el bloque de inicio y el bloque final acordes a tu búsqueda
  4. Deja en blanco el campo de la clave privada si no lo necesitas
  5. Haz click en \"Escanear\" para buscar tus fondos

Los números de bloque inicial y bloque final se guardarán en el almacenamiento local y se aplicarán automáticamente la próxima vez que escanees con el modo pro activado. Deja ambos campos en blanco para borrar los valores y utilizar los predeterminados.

", + "view-prvkey": "¿Cómo puedo ver las claves privadas ocultas?", + "view-prvkey-answer": "Si quieres ver las claves privadas ocultas de un determinado pago que has recibido haz lo siguiente:
  1. Activa el Modo Pro
  2. Ve a la página Recibir y busca los fondos
  3. Para las transacciones que no se han retirado, haz click en \"Retirar\" para expandir la fila
  4. Verás un texto que dice \"Mostrar clave privada de retirada\", que mostrará la clave privada oculta necesaria para retirar este pago
", + "for-developers": "Para desarrolladores", + "build-on-umbra": "¿Cómo puedo construir sobre Umbra?", + "build-on-umbra-answer": "

La documentación para desarrolladores aún no está escrita, pero todo el código está minuciosamente comentado, por lo que debería ser sencillo leer el código para entender cómo funcionan las cosas y construir sobre él.

La librería umbra-js es un buen punto de partida, ya que te dará una visión completa de como funciona Umbra, además de entrar en los detalles. Después, puedes echar un vistazo al contrato y entender donde encaja.

El siguiente debería ser un buen orden para recorrer la base del código de umbra-js. Si lo encuentras confuso, por favor, ¡haznos saber cuál sería un orden mejor!

  1. src/classes/Umbra.ts: La clase Umbra es una clase de alto nivel pensada para que los desarrolladores interactúen directamente con ella. Abstrae la complejidad del protocolo en unos pocos métodos principales:
    1. send() se utiliza para enviar fondos a otro usuario, y maneja automáticamente la criptografía subyacente requerida
    2. generatePrivateKeys() solicita al usuario una firma y genera sus claves de gasto y visualización. Nota: asegúrate de que la wallet utilizada soporta firmas ECDSA deterministas con RFC 6979.
    3. scan() te permite encontrar fondos enviados al usuario especificado, proporcionando sólo la clave pública de gasto y la clave privada de visualización
    4. withdraw() permite a una dirección oculta retirar directamente tanto tokens como ETH
    5. withdrawOnBehalf() utiliza meta-transacciones para retransmitir una transacción de retirada en nombre de otro usuario, y el método signWithdraw() se utiliza para obtener la firma requerida
    6. relayWithdrawOnBehalf() puede utilizarse para retransmitir una meta-transacción utilizando el relayer de Umbra por defecto
  2. src/classes/KeyPair.ts: Esta clase es donde reside el núcleo de la lógica de la criptografía. Una clase KeyPair se instancia con una clave privada o pública, y los métodos de la clase te ayudan a realizar varias operaciones con esas claves, incluyendo cifrado/descifrado, multiplicación, y compresión/descompresión de claves públicas
  3. src/classes/RandomNumber.ts: Esta sencilla clase se utiliza para generar nuestro número aleatorio de 32 bytes.
  4. src/utils/utils.ts contiene varios métodos de ayuda para una serie de tareas, principalmente relacionadas con la obtención de las claves públicas de un receptor
  5. src/types.ts: Verás que se usan algunos tipos personalizados, todos definidos aquí

Después de leer lo anterior, deberías estar bien equipado para entender el contrato Umbra.sol, que te darás cuenta de que es bastante simple. La única parte nueva del contrato de la que aún no habrás visto nada son los hooks. Puedes leer más sobre esto en la sección \"¿Qué son los hooks y cómo se usan?\".

", + "receive-vkey": "¿Cómo puedo recibir la clave de visualización de un usuario, pero no su clave de gasto?", + "receive-vkey-answer": "

Actualmente, la única forma de hacerlo es solicitar la firma de un usuario utilizando Umbra.generatePrivateKeys(), que devolverá tanto su clave de gasto como su clave de visualización. Depende de tí descartar la clave de gasto y no utilizarla. A continuación se muestra un ejemplo:

// Importa la clase de Umbra
import {'{'} Umbra {'}'} from '{'@'}umbra/umbra-js';

// Deja que `signer` sea un JsonRpcSigner de ethers generado cuando el usuario
// conectó su wallet. La línea siguiente solicitará una firma
// del usuario, calculará sus claves de gasto y visualización, pero
// sólo devolverá la instancia KeyPair de visualización al usuario.
const {'{'} viewingKeyPair {'}'} = await Umbra.generatePrivateKeys(signer);
", + "hooks": "¿Qué son los hooks y cómo se usan?", + "hooks-answer": "Si estás familiarizado con el {0} u otros estándares similares, ya conoces el concepto de hooks. Los hooks permiten al caller realizar otras acciones además de la lógica central del método al que se llama. En el caso del ERC-777, se puede usar un hook de transferencia para llamar a un método en un contrato después de transferir tokens a ese contrato.", + "hooks-answer-rest": "

Umbra funciona de forma similar— al retirar los fondos del contrato— los usuarios pueden querer depositarlos directamente en un protocolo DeFi o cambiar su DAI por ETH. Los hooks te permiten hacer esto.

Te darás cuenta que el contrato de Umbra expone múltiples métodos de retirada. Primero tenemos:

  1. withdrawToken() para retiradas estándar, es decir, transferencias simples
  2. withdrawTokenOnBehalf() tiene la misma funcionalidad que withdrawToken(), pero permite a un relayer enviar la retirada en tu nombre para soportar meta-transacciones.

Luego tenemos los dos métodos hook:

  1. withdrawTokenAndCall() es análogo a withdrawToken(), pero permite pasar la dirección de un contrato y la data para ejecutar en ese contrato.
  2. withdrawTokenAndCallOnBehalf() es análogo a withdrawTokenOnBehalf(), pero también permite pasar la dirección de un contrato y la data a ejecutar en ese contrato.

Para usar los hooks, primero necesitas escribir y desplegar un contrato hook que se ajuste a la interfaz IUmbraHookReceiver. Esto requiere que el contrato implemente un método llamado tokensWithdrawn() que recibe un puñado de parametros. La dirección de este contrato se pasaría como valor para el input _hook en los métodos anteriores.

", + "hooks-answer-encode-data": "Entonces necesitas codificar la calldata que el contrato hook recibirá y sobre el que puede operar. Consulta la sección {0} de la documentación de ethers.js para obtener información sobre cómo codificar los datos de la función.", + "hooks-answer-encoding-data": "Codificación de datos", + "hooks-answer-end": "

Y eso es todo. Con la dirección del contrato hook y el calldata codificado, estás listo para llamar a uno de los dos métodos basados en hooks.

" + }, + "AccountReceiveTable": { + "processing-results": "Procesando resultados...", + "configure-umbra": "No podrás recibir fondos hasta que no hayas configurado Umbra.", + "navigate-to-setup": "Ve a la página de {0} y hazlo", + "setup": "Configuración", + "keys-dont-match": "Las claves ocultas publicadas para esta cuenta no coinciden con las generadas por ella. Ve a la página de {0} y completa el flujo de configuración para asegurarte de que las claves publicadas coinciden con las de esta cuenta. Si no lo haces, los pagos enviados a tu cuenta pueden ser difíciles, o incluso imposibles de retirar. ", + "learn-more": "Aprende más", + "scan-settings": "Cambiar la configuración de escaneado", + "account-empty": "Esta cuenta no ha recibido fondos", + "received-funds": "Fondos recibidos", + "sender": "Emisor", + "stealth-receiver": "Receptor oculto", + "received": "Recibido", + "withdrawn": "Retirado", + "hide": "Ocultar", + "withdraw": "Retirar", + "receiver": "Receptor", + "scanning-complete": "Escaneo completado con éxito", + "custom-prv-key": " con una clave privada personalizada", + "scanned-from-block": "Escaneado desde el bloque", + "to": "al", + "all-blocks-scanned": "Se han escaneado todos los bloques", + "scanned-all-blocks-up-to": "Escaneados todos los bloques hasta", + "to-current-block": "al bloque actual", + "private-key-copied": "Clave privada copiada en el portapapeles", + "date-received": "Fecha de recepción", + "amount": "Cantidad", + "wallet-not-connected": "La wallet no está conectada. Intenta actualizar la página y conecta tu wallet", + "address-copied": "dirección copiada al portapapeles", + "umbra-instance-not-found": "Instancia de Umbra no encontrada", + "provider-not-found": "Provider no encontrado", + "no-announcement-selected": "No se ha seleccionado ningún anuncio de pago para retirar", + "signer-or-provider-not-found": "Signer o provider no encontrado", + "fee-not-set": "Tarifa no establecida", + "invalid-chain-id": "chainID inválido", + "receiver-tool-tip": "La dirección oculta que recibió estos fondos parece una dirección vacía, y no puede vincularse a tu cuenta, pero solo tú puedes generar su clave privada.", + "loss-warning": "Parece que estás intentando retirar tus fondos a un contrato inteligente de un token. Es muy probable que esto no sea lo que pretendes, y si lo haces probablemente resultará en una pérdida de fondos. No procedas a ello, a menos que sepas exactamente lo que estás haciendo.", + "i-know-what": "Sé perfectamente lo que estoy haciendo", + "danger": "Peligro", + "most-recent-announcement": "Bloque / timestamp del anuncio de pago más reciente:", + "most-recent-mined": "Bloque minado / timestamp más reciente:" + }, + "AccountReceiveTableWarning": { + "withdrawal-warning": "Estás retirando a {0}, que tiene las siguientes advertencias:", + "withdrawal-warning-rest": "No se recomienda continuar con la retirada a menos que sepas lo que estás haciendo, ya que esto puede reducir o eliminar por completo las propiedades de privacidad proporcionadas por Umbra.", + "learn-more": "Aprende más", + "acknowledge-risks": "Soy consciente de los riesgos" + }, + "AccountReceiveTableWithdrawConfirmation": { + "confirm": "Confirmar", + "cancel": "Cancelar", + "confirm-withdrawal": "Confirmar Retirada", + "to": "Retirando a", + "amount": "Cantidad", + "tx-fee": "Tarifa por transacción", + "relayer-gas-fee": "Tarifa de gas del relay", + "you-will-receive": "Recibirás", + "cannot-withdraw": "No se puede retirar, por favor corrige el error", + "withdraw-in-progress": "Retirada en curso...", + "view-transaction": "Ver transacción" + }, + "Argent": { + "warning": "Atención: Problemas de compatibilidad con Argent", + "warning-paragraph": "

Umbra no es compatible con el modelo de seguridad estándar de Argent. Aunque puedes seguir usando Umbra con Argent, corres el riesgo de perder tus fondos si cambias de dispositivo o tienes que recurrir a la recuperación social sin retirar antes los fondos que te hayan enviado a través de Umbra.

Umbra funciona generando claves específicas para la dApp derivadas de la clave privada de tu wallet. Argent es único en el sentido de que su seguridad no depende de tu clave privada. Esto es bueno en muchos sentidos.

Sin embargo, al usar Umbra, debes tener en cuenta lo siguiente:

  1. Si recuperas tu wallet Argent en un nuevo dispositivo, la nueva wallet tendrá la misma dirección pero una clave privada diferente. A menos que tengas acceso al dispositivo antiguo, los fondos enviados a través de Umbra que no hayas retirado serán irrecuperables.

  2. Como resultado, cuando consigas un nuevo dispositivo, deberás retirar todos los fondos primero usando tu antiguo dispositivo, repetir la configuración de tu cuenta Umbra y volver a publicar tus claves. Próximamente, la dApp intentará detectar cuando necesitas hacer esto para minimizar la posibilidad de pérdida de fondos, pero por ahora debes hacerlo manualmente.

  3. A diferencia de otras dApps, la seguridad de tus fondos recibidos por Umbra no está protegida por el modelo de seguridad estándar de Argent, en cambio sólo están protegidos por tu clave privada.
", + "acknowledge-risks": "Soy consciente de los riesgos" + }, + "AccountSendTable": { + "account-empty": "No se han enviado fondos en este navegador", + "address": "Dirección del receptor", + "amount": "Cantidad", + "date-sent": "Fecha del envío", + "receiver": "Receptor", + "sent-funds": "Enviar fondos", + "storage-description": "El historial de envíos es local a tu navegador actual y diferirá cuando se acceda desde un navegador diferente o un dispositivo diferente. Hacemos esto para maximizar tu seguridad y privacidad." + }, + "AccountSentTable": { + "address": "Dirección del receptor", + "account-empty": "No se han enviado fondos en este navegador", + "advanced-mode-on": "Enviado con el modo pro activado", + "amount": "Cantidad", + "cancel": "Cancelar", + "clear-history": "Borrar historial", + "clear-history-warning": "¡Esta acción no se puede deshacer! Tu historial encriptado de envíos sólo se almacena localmente en el dispositivo que envió la transacción y no puede recuperarse una vez borrado. ¿Estás seguro de que quieres continuar?", + "date-sent": "Fecha del envío", + "learn-more": "Aprende más", + "receiver": "Receptor", + "sent-funds": "Enviar fondos", + "storage-description": "El historial de envíos es local a tu navegador actual y diferirá cuando se acceda desde un navegador diferente o un dispositivo diferente. Hacemos esto para maximizar tu seguridad y privacidad.", + "stored-on-device": "El historial de envíos sólo se almacena localmente en este dispositivo", + "use-public-key-checked": "Enviado utilizando la clave pública estándar del receptor" + }, + "AccountSent": { + "clear-history": "Borrar historial", + "connect-wallet": "Conectar Wallet", + "connect-your-wallet": "Conecta tu wallet para ver los fondos enviados", + "fetching-send-history": "Recuperando el historial de envíos...", + + "need-signature": "Esta dApp necesita tu firma para descifrar tu historial de envíos almacenado localmente", + "sign": "Firmar" + }, + "ConnectWalletCard": { + "connect-wallet": "Conectar Wallet" + }, + "WalletRow": { + "account": "Cuenta", + "disconnect": "Desconectar", + "address-copied": "Dirección copiada al portapapeles", + "connected-with": "Conectado con", + "copy-address": "Copiar dirección", + "view-send-history": "Ver historial de envíos", + "view-on-explorer": "Ver en el explorador" + }, + "WithdrawForm": { + "need-signature": "Firmar y Retirar", + "withdraw-address": "Introduce la dirección a la que deseas retirar los fondos", + "address": "Dirección", + "fetching-fee-estimate": "Recuperando la tarifa estimada...", + "withdrawal-fee": "Tarifa de retirada:", + "estimated-withdrawal-fee": "Tarifa de retirada estimada:", + "withdraw-in-progress": "Retirada en curso...", + "warning": " ATENCIÓN: Asegúrate de entender las implicaciones de seguridad antes de introducir una dirección de retirada. Si retiras fondos a una dirección asociada a tí públicamente, se perderá la privacidad de esta transacción.", + "learn-more": "Aprende más", + "hide": "Ocultar", + "show": "Mostrar", + "stealth-prv-key": "clave privada de la dirección oculta", + "withdraw": "Retirar", + "enter-valid-address": "Introduce una dirección válida" + }, + "Utils": { + "Alerts": { + "transaction-pending": "Tu transacción está pendiente", + "transaction-succeeded": "Tu transacción se ha realizado correctamente", + "transaction-failed": "Tu transacción ha fallado" + }, + "Address": { + "might-be-token": "Puede ser un smart contract de un token, como un ERC-20 o un ERC-721", + "name-publicly-viewable": "Este nombre es visible públicamente", + "name-resolves-to-ens": "Este nombre resuelve al nombre público ENS ", + "name-resolves-to-cns": "Este nombre resuelve al nombre público CNS ", + "it": "Se", + "resolves-to": "resuelve a", + "is": "es", + "same-addr-as-wallet": "la misma dirección que la wallet conectada", + "same-addr-as-stealth": "la misma dirección que la dirección oculta", + "same-addr-as-sender": "la misma dirección que la del emisor", + "addr-is-registered": "una dirección inscrita en el registro de claves ocultas de Umbra", + "address-it-resolves-to": "La dirección a la que se resuelve", + "has-poap-tokens": "tiene tokens de POAP", + "gitcoin-contributor": "es contribuidor en Gitcoin" + }, + "Dialog": { + "warning": "Aviso" + } + }, + "connect": { + "selectingWallet": { + "header": "Wallets disponibles", + "sidebar": { + "heading": "Empezar", + "subheading": "Conecta tu wallet", + "paragraph": "Conectar tu wallet es como “iniciar sesión” en web3. Selecciona tu wallet entre las opciones para empezar." + }, + "recommendedWalletsPart1": "{app} solo es compatible", + "recommendedWalletsPart2": "en esta plataforma. Utiliza o instala una de las wallets compatibles para empezar", + "installWallet": "No tienes instalada ninguna wallet compatible con {app}, utiliza tu wallet compatible", + "agreement": { + "agree": "Acepto los", + "terms": "Términos y Condiciones", + "and": "y la", + "privacy": "Política de Privacidad" + } + }, + "connectingWallet": { + "header": "{connectionRejected, select, false {Connecting to {wallet}...} other {Connection Rejected}}", + "sidebar": { + "subheading": "Aprobar la conexión", + "paragraph": "Por favor, aprueba la conexión en tu wallet y autoriza el acceso para continuar." + }, + "mainText": "Conectando...", + "paragraph": "Asegúrate de seleccionar todas las cuentas a las que deseas conceder acceso.", + "previousConnection": "{wallet} ya tiene una solicitud de conexión pendiente, por favor abre la aplicación {wallet} para iniciar sesión y conectarte.", + "rejectedText": "¡Conexión rechazada!", + "rejectedCTA": "Haz click aquí para volver a intentarlo", + "primaryButton": "Volver" + }, + "connectedWallet": { + "header": "Conexión exitosa", + "sidebar": { + "subheading": "¡Conexión exitosa!", + "paragraph": "Tu wallet está ahora conectada a {app}" + }, + "mainText": "Conectada" + } + }, + "modals": { + "actionRequired": { + "heading": "Acción necesaria en {wallet}", + "paragraph": "Cambia la cuenta activa en tu wallet.", + "linkText": "Aprende más.", + "buttonText": "Vale" + }, + "switchChain": { + "heading": "Cambiar de Red", + "paragraph1": "{app} requiere que cambies tu wallet a la red {nextNetworkName} para continuar.", + "paragraph2": "*Es posible que algunas wallets no permitan cambiar de red. Si no puedes cambiar de red en tu wallet, puedes considerar cambiar a otra wallet." + }, + "confirmDisconnectAll": { + "heading": "Desconectar todas las wallets", + "description": "¿Estás seguro que quieres desconectar todas tus wallets?", + "confirm": "Confirmar", + "cancel": "Cancelar" + } + }, + "accountCenter": { + "connectAnotherWallet": "Conectar otra wallet", + "disconnectAllWallets": "Desconectar todas las wallets", + "currentNetwork": "Red actual", + "appInfo": "Info de la dApp", + "learnMore": "Aprende más", + "gettingStartedGuide": "Primeros pasos", + "smartContracts": "Contrato(s) inteligente(s)", + "explore": "Explorar", + "backToApp": "Volver a la dApp", + "poweredBy": "funciona gracias a", + "addAccount": "Añadir cuenta", + "setPrimaryAccount": "Establecer cuenta principal", + "disconnectWallet": "Desconectar wallet", + "copyAddress": "Copiar dirección de la wallet" + }, + "notify": { + "transaction": { + "txRequest": "Tu transacción está esperando a que la confirmes", + "nsfFail": "No tienes fondos suficientes para esta transacción", + "txUnderpriced": "El gas usado para tu transacción es demasiado bajo, prueba con uno más alto", + "txRepeat": "Podría ser una transacción repetida", + "txAwaitingApproval": "Tienes una transacción pendiente", + "txConfirmReminder": "Confirma tu transacción para continuar", + "txSendFail": "Has rechazado la transacción", + "txSent": "Tu transacción ha sido enviada a la red", + "txStallPending": "Tu transacción se ha bloqueado antes de ser enviada, por favor inténtalo de nuevo", + "txStuck": "Tu transacción está bloqueada debido a una diferencia de nonce", + "txPool": "Tu transacción ha comenzado", + "txStallConfirmed": "Tu transacción se ha bloqueado y no ha sido confirmada", + "txSpeedUp": "Tu transacción se ha acelerado", + "txCancel": "Tu transacción ha sido cancelada", + "txFailed": "Tu transacción ha fallado", + "txConfirmed": "Tu transacción se ha realizado correctamente", + "txError": "Ups algo salió mal, por favor inténtalo de nuevo", + "txReplaceError": "Se ha producido un error al reemplazar tu transacción, inténtalo de nuevo" + }, + "watched": { + "txPool": "Tu cuenta es {verb} {formattedValue} {asset} {preposition} {counterpartyShortened}", + "txSpeedUp": "Transacción para {formattedValue} {asset} {preposition} {counterpartyShortened} se ha acelerado", + "txCancel": "Transacción para {formattedValue} {asset} {preposition} {counterpartyShortened} ha sido cancelada", + "txConfirmed": "Tu cuenta acertó a {verb} {formattedValue} {asset} {preposition} {counterpartyShortened}", + "txFailed": "Tu cuenta no ha podido {verb} {formattedValue} {asset} {preposition} {counterpartyShortened}", + "txStuck": "Tu transacción está bloqueada debido a una diferencia de nonce" + }, + "time": { + "minutes": "min", + "seconds": "seg" + } + } +} diff --git a/frontend/src/store/settings.ts b/frontend/src/store/settings.ts index f6b6ac70..959250a3 100644 --- a/frontend/src/store/settings.ts +++ b/frontend/src/store/settings.ts @@ -15,8 +15,6 @@ const settings = { registeredBlockNumber: 'registered-block-number', }; - - // Shared state between instances const isDark = ref(false); // true if user has dark mode turned on const advancedMode = ref(false); // true if user has advanced mode turned on @@ -25,6 +23,7 @@ const language = ref({ label: '', value: '' }); //language code const supportedLanguages = [ { label: 'English', value: 'en-US' }, { label: '中文', value: 'zh-CN' }, + { label: 'Español', value: 'es-ES' }, ]; const startBlock = ref(undefined); // block number to start scanning from const endBlock = ref(undefined); // block number to scan through @@ -81,12 +80,22 @@ export default function useSettingsStore() { function setLanguage(newLanguage: Language) { // xx-yy was changed to xx-YY with the quasar v1 -> v2 upgrade, so we need to handle that. - if (newLanguage.value === 'en-us') newLanguage.value = 'en-US'; - else if (newLanguage.value === 'zh-cn') newLanguage.value = 'zh-CN'; + //Add more if needed. + switch (newLanguage.value) { + case 'en-us': + newLanguage.value = 'en-US'; + break; + case 'zh-cn': + newLanguage.value = 'zh-CN'; + break; + case 'es-es': + newLanguage.value = 'es-ES'; + break; + } // Now we set the language. language.value = newLanguage; - i18n.global.locale = <'en-US' | 'zh-CN'>language.value.value; + i18n.global.locale = <'en-US' | 'zh-CN' | 'es-ES'>language.value.value; LocalStorage.set(settings.language, language.value); } diff --git a/frontend/src/store/wallet.ts b/frontend/src/store/wallet.ts index 737ed505..bd425b50 100644 --- a/frontend/src/store/wallet.ts +++ b/frontend/src/store/wallet.ts @@ -26,6 +26,7 @@ import { notifyUser } from 'src/utils/alerts'; import useSettingsStore from 'src/store/settings'; import enLocal from 'src/i18n/locales/en-US.json'; import chLocal from 'src/i18n/locales/zh-CN.json'; +import esLocal from 'src/i18n/locales/es-ES.json'; // Wallet configurations. const injected = injectedModule(); @@ -115,6 +116,12 @@ export default function useWalletStore() { accountCenter: chLocal['accountCenter'], notify: chLocal['notify'], }, + 'es-ES': { + connect: esLocal['connect'], + modals: esLocal['modals'], + accountCenter: esLocal['accountCenter'], + notify: esLocal['notify'], + }, }, appMetadata: { name: 'Umbra', @@ -615,7 +622,7 @@ export default function useWalletStore() { tokens: computed(() => tokens.value), userDisplayName: computed(() => userDisplayName.value), connectedWalletLabel: computed(() => lastWallet), - needSignature: computed(() => !spendingKeyPair.value?.privateKeyHex || !viewingKeyPair.value?.privateKeyHex), + needSignature: computed(() => !spendingKeyPair.value?.privateKeyHex || !viewingKeyPair.value?.privateKeyHex), }; }