From 20d783239447139fef559e679c5e5d3a686edb9d Mon Sep 17 00:00:00 2001 From: zacharyyyyyyy <63769232+multipletwigs@users.noreply.github.com> Date: Sat, 1 Aug 2026 14:04:45 +0800 Subject: [PATCH 1/2] feat(sdp-web): PART 1 stepped tokenization-engine chooser in the deploy modal (#1039) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(sdp-web): stepped tokenization-engine chooser in the deploy modal Deploying a token now opens a two-step modal behind the alphaledger-tokenization-engine flag: step 1 offers Vulcan Forge (coming soon, disabled) and SDP with Mosaic as engine cards, step 2 is the signer/fee panel with Back navigation, animated transitions, and grid-stacked steps so the card height never shifts. The Kora button and hint copy leave the deploy panel; wallet deploy becomes the primary CTA. Local dev flag evaluations kept falling back to defaultValue because the Vercel flags stream misses its 3s init timeout off-Vercel, so dev now uses a polling client (30s interval) via @vercel/flags-core while deploys keep the default streaming adapter. * chore(sdp-web): drop localized catalog edits per catalog policy * feat(sdp-web): Vulcan Forge onboarding toggle in the deploy step Behind the same flag, the deploy step shows an AlphaLedger banner with a switch: a Mosaic deploy can opt into onboarding the token to Vulcan Forge as a registered twin. UI only for now — the registration call lands with the backend integration. * refactor(sdp-web): Vulcan Forge onboarding as a one-liner below the signer * refactor(sdp-web): card-style onboarding banner and full-height engine cards * copy(sdp-web): shorten Vulcan Forge onboarding description to one line * feat(sdp-web): concentric ring pattern behind engine card logos --- .../messages/en/dashboard-issuance.json | 14 +- apps/sdp-web/package.json | 1 + .../public/provider-logos/alphaledger.svg | 5 + .../asset-management-workspace.tsx | 245 ++++++++++++++---- .../app/dashboard/issuance/[tokenId]/page.tsx | 17 +- pnpm-lock.yaml | 165 ++++++------ 6 files changed, 313 insertions(+), 134 deletions(-) create mode 100644 apps/sdp-web/public/provider-logos/alphaledger.svg diff --git a/apps/sdp-web/messages/en/dashboard-issuance.json b/apps/sdp-web/messages/en/dashboard-issuance.json index bfa2c2516..a5ee9a639 100644 --- a/apps/sdp-web/messages/en/dashboard-issuance.json +++ b/apps/sdp-web/messages/en/dashboard-issuance.json @@ -476,10 +476,22 @@ "tokenIdCopied": "Token ID copied", "loadingAuthorityWalletAccess": "Loading authority wallet access…", "loadingComplianceControls": "Loading compliance controls…", - "deploySignerHint": "Pay the transaction and account fees from the signer wallet, or with Kora sponsorship.", + "deploySignerHint": "Transaction and account fees are paid from the signer wallet.", "deployWithWallet": "Deploy with Wallet", "koraUnavailable": "Kora sponsorship is unavailable right now.", "deployWithKora": "Deploy with Kora", + "tokenizationEngineTitle": "Tokenization engine", + "tokenizationEngineHint": "Choose which engine deploys and manages this token onchain.", + "engineVulcanForgeName": "Vulcan Forge", + "engineVulcanForgeDescription": "Deploy onchain and tokenize on Vulcan Forge with built-in registry and indexing.", + "engineMosaicName": "SDP with Mosaic", + "engineMosaicDescription": "Deploy with SDP's built-in Mosaic engine on Token-2022.", + "comingSoon": "Coming soon", + "stepProgress": "Step {current} of {total}", + "vulcanForgeOnboardTitle": "Onboard token to Vulcan Forge", + "vulcanForgeOnboardDescription": "AlphaLedger keeps a registered offline twin for indexing and reporting.", + "engineStepLabel": "Engine", + "deployStepLabel": "Deploy", "destinationNotAllowlisted": "Destination is not on this token's allowlist.", "destinationDenylisted": "Destination is on this token's denylist.", "actionPaused": "Token is paused. Unpause it to {action}.", diff --git a/apps/sdp-web/package.json b/apps/sdp-web/package.json index ca2adde95..0d02f5c22 100644 --- a/apps/sdp-web/package.json +++ b/apps/sdp-web/package.json @@ -30,6 +30,7 @@ "@solana/design-system": "1.0.1", "@solana/fixed-points": "7.0.0", "@solana/qr-code-styling": "1.6.0", + "@vercel/flags-core": "1.7.0", "clsx": "2.1.1", "flags": "4.2.0", "lucide-react": "1.17.0", diff --git a/apps/sdp-web/public/provider-logos/alphaledger.svg b/apps/sdp-web/public/provider-logos/alphaledger.svg new file mode 100644 index 000000000..0b9643fff --- /dev/null +++ b/apps/sdp-web/public/provider-logos/alphaledger.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/apps/sdp-web/src/app/dashboard/issuance/[tokenId]/asset-profile/asset-management-workspace.tsx b/apps/sdp-web/src/app/dashboard/issuance/[tokenId]/asset-profile/asset-management-workspace.tsx index 34d3d05b0..43d40e820 100644 --- a/apps/sdp-web/src/app/dashboard/issuance/[tokenId]/asset-profile/asset-management-workspace.tsx +++ b/apps/sdp-web/src/app/dashboard/issuance/[tokenId]/asset-profile/asset-management-workspace.tsx @@ -2,11 +2,14 @@ import type { AssetProfile, Token } from "@sdp/types"; import { Tab, TabList, Tabs } from "@solana/design-system/tabs"; -import { Loader2, Play, SparklesIcon, WalletIcon } from "lucide-react"; +import { Loader2, Play, WalletIcon } from "lucide-react"; import { motion } from "motion/react"; +import Image from "next/image"; import { useSearchParams } from "next/navigation"; -import { useCallback, useEffect, useState } from "react"; +import { type ReactNode, useCallback, useEffect, useState } from "react"; import { Button } from "@/components/ui/button"; +import { ToggleSwitch } from "@/components/ui/toggle-switch"; +import { WizardStepProgress } from "@/components/ui/wizard-step-progress"; import { useDashboardWorkspace } from "@/contexts/dashboard-workspace-context"; import { useTranslations } from "@/i18n/provider"; import { useDashboardUrlState } from "@/lib/dashboard-url-state"; @@ -68,6 +71,147 @@ function resolveTab(value: string | null): AssetManagementTab { return "overview"; } +/** + * The deploy modal's card, stepped when the AlphaLedger engine flag is on: + * step 1 is a tokenization-engine chooser with Vulcan Forge (coming soon, + * disabled) and SDP with Mosaic, step 2 is the signer/fee deploy panel passed + * as children, with wizard step pills and a Back affordance between them. + * When the flag is off the card renders the deploy panel directly with no + * step chrome. Mounted only while the deploy modal is open, so closing the + * modal discards the choice and a reopen starts back at the chooser. + * + * @param enabled - Whether the chooser step and step chrome are shown. + * @param children - Renders the signer/fee deploy panel content below the deploy title; receives a go-back handler for returning to the engine step, or null when the flow is not stepped. + * @returns The stepped deploy modal card. + */ +function TokenizationEngineGate({ + enabled, + children, +}: { + enabled: boolean; + children: (goBack: (() => void) | null) => ReactNode; +}) { + const t = useTranslations(); + const [engineChosen, setEngineChosen] = useState(!enabled); + + const deployStepContent = ( + <> +

+ {t("DashboardIssuance.workspace.deployToken")} +

+

+ {t("DashboardIssuance.workspace.deployHint")} +

+ {children(enabled ? () => setEngineChosen(false) : null)} + + ); + + const engineStepContent = ( +
+

+ {t("DashboardIssuance.management.tokenizationEngineTitle")} +

+

+ {t("DashboardIssuance.management.tokenizationEngineHint")} +

+
+
+
+ + + +
+
+
+

+ {t("DashboardIssuance.management.engineVulcanForgeName")} + + {t("DashboardIssuance.management.comingSoon")} + +

+

+ {t("DashboardIssuance.management.engineVulcanForgeDescription")} +

+
+
+ +
+
+ ); + + if (!enabled) { + return ( +
+ {deployStepContent} +
+ ); + } + + return ( +
+
+ +
+ {/* Both steps stay mounted in the same grid cell so the card keeps the + taller step's height across transitions — no layout shift. */} +
+ + {engineChosen ? deployStepContent : engineStepContent} + + +
+
+ ); +} + export function shouldOpenPendingFundManagementModal({ activeTab, pendingFundManagementModalAction, @@ -82,10 +226,12 @@ export function AssetManagementWorkspace({ token, assetProfile, tokenError, + alphaledgerEngineEnabled, }: { token: Token; assetProfile: AssetProfile; tokenError: string | null; + alphaledgerEngineEnabled: boolean; }) { const t = useTranslations(); const { dashboardAccess } = useDashboardWorkspace(); @@ -107,6 +253,7 @@ export function AssetManagementWorkspace({ const [pendingFundManagementModalAction, setPendingFundManagementModalAction] = useState< "deploy" | "mint" | "burn" | null >(null); + const [onboardToVulcanForge, setOnboardToVulcanForge] = useState(false); const ops = useTokenOperations({ token, @@ -329,59 +476,67 @@ export function AssetManagementWorkspace({ onClose={ops.closeFundManagementModal} > {ops.fundManagementModalAction === "deploy" ? ( -
-

- {t("DashboardIssuance.workspace.deployToken")} -

-

- {t("DashboardIssuance.workspace.deployHint")} -

-
- - {/* Two signers, two buttons: the selected wallet pays the fees, or - Kora sponsors them. Kora stays disabled until sponsorship is - wired up, so the tooltip explains the gap. */} -
- -
+ + {(goBack) => ( +
+ + {alphaledgerEngineEnabled ? ( +
+
+ + + +
+

+ {t("DashboardIssuance.management.vulcanForgeOnboardTitle")} +

+

+ {t("DashboardIssuance.management.vulcanForgeOnboardDescription")} +

+
+
+ +
+ ) : null} +
+ - - -
-
-
+ )} + ) : ops.fundManagementModalAction ? ( Date: Sat, 1 Aug 2026 02:29:52 -0300 Subject: [PATCH 2/2] feat(i18n): add complete Latin American Spanish (es) UI translation catalogs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds full es catalogs for all 3,639 UI strings across the 8 message files, including dashboard-private-channels (not yet covered by fr). Registers the locale in supportedLocales/messagesByLocale, extends the i18n unit tests, and adds the locales.es terminology block (voice, glossary-driven terminology, forbiddenTerms) to translation-guidance.json so catalog validation enforces the conventions from day one. Terminology follows solanabr/solana-glossary and the established fr precedent: Token, Wallet, mint/burn, allowlist/blocklist, endpoint, API Playground and friends stay in English; generic finance/CS vocabulary uses neutral Latin American Spanish (activo, contraparte, transferencia, cotización, proveedor). Register: tú, never vosotros. --- .github/translation-guidance.json | 179 +++ apps/sdp-web/messages/es.json | 33 + .../messages/es/dashboard-approvals.json | 113 ++ .../messages/es/dashboard-custody.json | 795 ++++++++++ .../messages/es/dashboard-issuance.json | 1276 +++++++++++++++++ .../messages/es/dashboard-payments.json | 1043 ++++++++++++++ .../messages/es/dashboard-policies.json | 49 + .../es/dashboard-private-channels.json | 298 ++++ apps/sdp-web/messages/es/shared.json | 262 ++++ apps/sdp-web/src/i18n/README.md | 6 +- apps/sdp-web/src/i18n/config.ts | 2 +- apps/sdp-web/src/i18n/messages.ts | 22 + apps/sdp-web/src/i18n/messages.unit.test.ts | 2 + 13 files changed, 4076 insertions(+), 4 deletions(-) create mode 100644 apps/sdp-web/messages/es.json create mode 100644 apps/sdp-web/messages/es/dashboard-approvals.json create mode 100644 apps/sdp-web/messages/es/dashboard-custody.json create mode 100644 apps/sdp-web/messages/es/dashboard-issuance.json create mode 100644 apps/sdp-web/messages/es/dashboard-payments.json create mode 100644 apps/sdp-web/messages/es/dashboard-policies.json create mode 100644 apps/sdp-web/messages/es/dashboard-private-channels.json create mode 100644 apps/sdp-web/messages/es/shared.json diff --git a/.github/translation-guidance.json b/.github/translation-guidance.json index 3d08df1ed..3265ad5e6 100644 --- a/.github/translation-guidance.json +++ b/.github/translation-guidance.json @@ -10,6 +10,185 @@ ] }, "locales": { + "es": { + "localeName": "español (Latinoamérica)", + "voice": [ + "Use natural professional Latin American Spanish and address the user with tú; use ustedes for plural and never vosotros.", + "Use inverted opening punctuation (¿ ¡) in questions and exclamations.", + "Keep established Web3 terms in English when Spanish-speaking practitioners normally use the English term.", + "Use standard Latin American financial vocabulary, such as activo and contraparte." + ], + "terminology": [ + { + "source": "token / tokens", + "preferred": "Token / Tokens", + "avoid": "ficha / fichas", + "note": "Token is the established Web3 product noun. Use Spanish grammar around it." + }, + { + "source": "wallet / wallets", + "preferred": "Wallet / Wallets", + "avoid": "billetera / monedero / cartera", + "note": "Wallet is the established product noun in this dashboard." + }, + { + "source": "mint / burn", + "preferred": "mint / burn", + "avoid": "acuñar / acuñación", + "note": "Keep protocol action names recognizable; write natural Spanish around them, for example hacer mint de Tokens." + }, + { + "source": "allowlist / blocklist", + "preferred": "allowlist / blocklist", + "avoid": "lista blanca / lista negra / lista de permitidos / lista de bloqueo", + "note": "Keep the neutral technical terms used by the product." + }, + { + "source": "on-chain / off-chain", + "preferred": "on-chain / off-chain" + }, + { + "source": "stablecoin, API, RPC, webhook, blockchain, staking, airdrop", + "preferred": "Keep these established technical terms unchanged." + }, + { + "source": "endpoint / API Playground", + "preferred": "endpoint / API Playground", + "avoid": "punto de conexión / punto final / zona de pruebas", + "note": "Use the established developer-facing product terms." + }, + { + "source": "dashboard", + "preferred": "Dashboard", + "avoid": "panel / panel de control", + "note": "Dashboard is the product surface name." + }, + { + "source": "asset / counterparty", + "preferred": "activo / contraparte", + "note": "These have natural, standard Latin American financial equivalents." + }, + { + "source": "transfer / provider / quote", + "preferred": "transferencia / proveedor / cotización", + "note": "Use the standard Spanish product and financial terms, including in API error copy." + }, + { + "source": "draft / deploy", + "preferred": "borrador / desplegar or despliegue", + "note": "Use the verb or noun that fits the sentence; do not insert the English word into Spanish grammar." + }, + { + "source": "custody", + "preferred": "Custody for the product category; custodia in explanatory prose", + "note": "Choose from context instead of forcing one translation everywhere." + }, + { + "source": "validator / account / transaction / signature / keypair / epoch", + "preferred": "validador / cuenta / transacción / firma / par de claves / época", + "note": "Follow the solanabr/solana-glossary conventions for protocol vocabulary with standard Spanish equivalents." + }, + { + "source": "decimals", + "preferred": "decimales", + "note": "Generic noun in this product; always translate." + }, + { + "source": "custodian", + "preferred": "custodio", + "note": "Standard regulated-finance vocabulary." + }, + { + "source": "Mint Authority / Freeze Authority / Update Authority / Metadata Authority / Permanent Delegate", + "preferred": "Keep the whole SPL authority family in English as noun labels; verbs describing the action are written in Spanish." + }, + { + "source": "compliance / payout / funding", + "preferred": "cumplimiento / pago saliente / fondeo", + "note": "Never retiro for payout (retiro is reserved for withdraw); never financiamiento for funding." + }, + { + "source": "fee", + "preferred": "tarifa for network and transaction fees; comisión for provider and management fees", + "note": "Keep the split consistent." + }, + { + "source": "ramp / on-ramp / off-ramp / rails / rent / block explorer", + "preferred": "ramp / on-ramp / off-ramp / rails / rent / explorador", + "note": "Ramp family, rails and Solana rent stay in English; block explorer translates to explorador (Solana Explorer stays as the brand name)." + }, + { + "source": "Token-2022 extension names (Transfer Fee, Interest Bearing, Scaled UI Amount, Transfer Hook, Non-transferable, Default Account State)", + "preferred": "Keep extension names in English as labels; translate their descriptions and helper text." + }, + { + "source": "enable / disable / enabled / disabled", + "preferred": "habilitar / deshabilitar / habilitado / deshabilitado", + "note": "Match the English form per string: infinitive action versus participle state. Never mix in the desactivar family for these senses." + }, + { + "source": "expires / manage / remove / clear", + "preferred": "vencer y vencimiento / administrar / quitar / borrar", + "note": "Quitar detaches without destroying; eliminar is reserved for delete." + } + ], + "forbiddenTerms": [ + { + "label": "billetera / monedero", + "pattern": "\\b(?:billeteras?|monederos?)\\b", + "flags": "iu", + "preferred": "Wallet / Wallets" + }, + { + "label": "cartera / carteras", + "pattern": "\\bcarteras?\\b", + "flags": "iu", + "preferred": "Wallet / Wallets" + }, + { + "label": "ficha / fichas", + "pattern": "\\bfichas?\\b", + "flags": "iu", + "preferred": "Token / Tokens" + }, + { + "label": "punto de conexión / punto final", + "pattern": "\\bpuntos? (?:de conexión|finales?)\\b", + "flags": "iu", + "preferred": "endpoint / endpoints" + }, + { + "label": "zona de pruebas", + "pattern": "\\bzona de pruebas\\b", + "flags": "iu", + "preferred": "API Playground" + }, + { + "label": "lista blanca / lista negra", + "pattern": "\\blistas? (?:blancas?|negras?)\\b", + "flags": "iu", + "preferred": "allowlist / blocklist" + }, + { + "label": "lista de permitidos / lista de bloqueo", + "pattern": "\\blistas? de (?:permitidos|bloqueados|bloqueos?)\\b", + "flags": "iu", + "preferred": "allowlist / blocklist" + }, + { + "label": "allow list", + "pattern": "\\ballow list\\b", + "flags": "iu", + "preferred": "allowlist" + }, + { + "label": "acuñar / acuñación", + "pattern": "\\bacuñ(?:ar|ación)\\b", + "flags": "iu", + "preferred": "mint" + } + ] + }, "fr": { "localeName": "français (France)", "voice": [ diff --git a/apps/sdp-web/messages/es.json b/apps/sdp-web/messages/es.json new file mode 100644 index 000000000..ceca85332 --- /dev/null +++ b/apps/sdp-web/messages/es.json @@ -0,0 +1,33 @@ +{ + "Metadata": { + "title": "Solana Developer Platform", + "description": "Dashboard SDP" + }, + "Home": { + "solanaLogo": "Solana", + "docs": "Docs", + "dashboard": "Dashboard", + "title": "Construye cualquier producto financiero sin preocuparte por la infraestructura", + "description": "Ya sea que estés emitiendo una stablecoin, orquestando pagos transfronterizos o tokenizando activos del mundo real, SDP ofrece las APIs y la infraestructura más confiables para lograrlo.", + "trySdp": "Prueba SDP", + "contactUs": "Contáctanos", + "joinWaitlist": "Únete a la lista de espera" + }, + "NotFound": { + "solanaLogo": "Solana", + "title": "Página no encontrada", + "description": "La página que buscas no existe o es posible que se haya movido.", + "backToDashboard": "Volver al dashboard", + "goHome": "Ir al inicio" + }, + "Feedback": { + "label": "Comentarios" + }, + "Error": { + "tryAgain": "Reintentar", + "reportIssue": "Reportar este problema", + "viewTitle": "No se pudo cargar esta vista", + "viewDescription": "Ocurrió un error al cargar esta página. El resto del dashboard sigue funcionando, así que puedes reintentarlo o continuar.", + "reference": "Referencia {digest}" + } +} diff --git a/apps/sdp-web/messages/es/dashboard-approvals.json b/apps/sdp-web/messages/es/dashboard-approvals.json new file mode 100644 index 000000000..f8bf9ce39 --- /dev/null +++ b/apps/sdp-web/messages/es/dashboard-approvals.json @@ -0,0 +1,113 @@ +{ + "DashboardApprovals": { + "pendingCount": "Pendientes: {count}", + "pendingTab": "Pendientes", + "historyTab": "Historial", + "walletFilter": "Wallet", + "allWallets": "Todas las Wallets", + "statusFilter": "Estado", + "allStatuses": "Todos los estados", + "operationFilter": "Operación", + "allOperations": "Todas las operaciones", + "apiKeyFilter": "Clave de API", + "allApiKeys": "Todas las claves de API", + "fromFilter": "Desde", + "toFilter": "Hasta", + "dateRangeLabel": "Fecha", + "dateAllTime": "Todo el historial", + "dateLast7": "7 días", + "dateLast30": "30 días", + "dateLast90": "90 días", + "dateCustom": "Personalizado", + "statusColumn": "Estado", + "walletColumn": "Wallet", + "operationColumn": "Operación", + "amountAssetColumn": "Monto / activo", + "destinationColumn": "Destino", + "requestedByColumn": "Solicitado por", + "policyReasonColumn": "Motivo de política", + "submittedColumn": "Enviado", + "openRequest": "Abrir solicitud de aprobación", + "emptyPending": "No hay solicitudes en espera de aprobación", + "emptyPendingDescription": "Las nuevas operaciones retenidas por política aparecerán aquí en cuanto se envíen.", + "emptyHistory": "Aún no hay historial de aprobaciones", + "emptyHistoryDescription": "Las solicitudes aprobadas, rechazadas, canceladas, vencidas y fallidas aparecerán aquí.", + "emptyFiltered": "Ninguna solicitud coincide con estos filtros", + "emptyFilteredDescription": "Borra uno o más filtros para ver más solicitudes de aprobación.", + "range": "{from}-{to} de {total} solicitudes", + "unableToLoad": "No se pudieron cargar las solicitudes de aprobación", + "unableToLoadDescription": "No se pudo obtener la lista de solicitudes. Intenta cargarla de nuevo.", + "reload": "Recargar", + "autoRefresh": "Actualizando cada 5 segundos", + "refreshFailed": "Las solicitudes de aprobación no se pudieron actualizar. Se muestran los últimos resultados cargados.", + "viewOnly": "Puedes revisar las solicitudes de aprobación, pero tu rol no puede decidir sobre ellas.", + "noAccess": "Las solicitudes de aprobación no están disponibles para tu rol.", + "noAccessDescription": "Solicita a un administrador de la organización acceso de lectura a las Wallets.", + "backToApprovals": "Volver a Aprobaciones", + "reviewTitle": "Revisar {operation}", + "reviewDescription": "Confirma el contexto de la política y los detalles de la operación antes de tomar una decisión.", + "approve": "Aprobar", + "reject": "Rechazar", + "cancel": "Cancelar", + "approveTitle": "¿Aprobar esta solicitud?", + "approveDescription": "La operación se liberará para su ejecución. Esta decisión no se puede deshacer.", + "approveConfirm": "Aprobar solicitud", + "rejectTitle": "¿Rechazar esta solicitud?", + "rejectDescription": "La operación se cancelará y no podrá reanudarse desde esta solicitud.", + "rejectConfirm": "Rechazar solicitud", + "cancelTitle": "¿Cancelar esta solicitud?", + "cancelDescription": "La operación pendiente se cancelará sin una decisión de aprobación.", + "cancelConfirm": "Cancelar solicitud", + "notNow": "Ahora no", + "decisionInProgress": "Actualizando solicitud...", + "approvedToast": "Solicitud aprobada", + "rejectedToast": "Solicitud rechazada", + "canceledToast": "Solicitud cancelada", + "alreadyDecided": "Esta solicitud ya fue decidida. Ahora se muestra el estado más reciente.", + "forbiddenDecision": "Tu rol no tiene permiso para decidir sobre solicitudes de aprobación.", + "decisionFailed": "No se pudo actualizar la solicitud. Intenta de nuevo.", + "requestSection": "Solicitud", + "policyDecisionSection": "Decisión de política", + "operationDetailsSection": "Detalles de la operación", + "matchedControlsSection": "Controles coincidentes", + "timelineSection": "Línea de tiempo", + "submittedBy": "Enviado por", + "submittedAt": "Enviado el", + "expiresAt": "Vence el", + "policyDecision": "Decisión", + "policyReason": "Motivo", + "reasonCode": "Código de motivo", + "operationFamily": "Familia de operaciones", + "operationType": "Tipo de operación", + "amount": "Monto", + "asset": "Activo", + "destination": "Destino", + "source": "Origen", + "noMatchedControls": "No se reportaron controles coincidentes para esta evaluación.", + "matchedControl": "Control coincidente {number}", + "submittedEvent": "Solicitud enviada", + "submittedEventDescription": "La operación se pausó para su aprobación.", + "resolvedEvent": "Solicitud {status}", + "resolvedEventDescription": "Decisión registrada por {actor}.", + "metadata": "Contexto de la solicitud", + "wallet": "Wallet", + "walletAddress": "Dirección de la Wallet", + "requester": "Solicitante", + "apiKey": "Clave de API", + "walletRevision": "Revisión de la Wallet", + "apiKeyRevision": "Revisión de la clave de API", + "provider": "Proveedor", + "providerStatus": "Estado del proveedor", + "requestId": "ID de solicitud", + "submitted": "Enviado", + "currentStatus": "Estado actual", + "resolvedBy": "Resuelto por", + "resolvedAt": "Resuelto el", + "notReported": "No reportado", + "directRequest": "Solicitud directa", + "approvalRequiredByPolicy": "Aprobación requerida por política", + "copyRequestId": "Copiar ID de solicitud", + "requestIdCopied": "ID de solicitud copiado", + "loading": "Cargando aprobaciones..." + } +} diff --git a/apps/sdp-web/messages/es/dashboard-custody.json b/apps/sdp-web/messages/es/dashboard-custody.json new file mode 100644 index 000000000..19fd8f549 --- /dev/null +++ b/apps/sdp-web/messages/es/dashboard-custody.json @@ -0,0 +1,795 @@ +{ + "DashboardCustody": { + "actions": "Acciones", + "rotateKey": "Rotar clave ({hours} h de gracia)", + "deleteKey": "Eliminar clave", + "editApiKey": "Editar clave de API", + "actionFailed": "Acción fallida", + "notice": "Aviso", + "existingApiKeys": "Claves de API existentes", + "apiKeysDescription": "Claves activas e históricas de este espacio de trabajo.", + "newApiKey": "Nueva clave de API", + "noApiKeysFound": "No se encontraron claves de API.", + "name": "Nombre", + "prefix": "Prefijo", + "access": "Acceso", + "status": "Estado", + "lastUsed": "Último uso", + "expires": "Vence", + "created": "Creado", + "never": "Nunca", + "admin": "Administrador", + "developer": "Desarrollador", + "readOnly": "Solo lectura", + "allWallets": "Todas las Wallets", + "selectedWallets": "Wallets seleccionadas", + "selected": "Seleccionadas: {count}", + "selectedWallet": "Wallet seleccionada", + "selectedLabel": "Seleccionada", + "noApiKeyPolicy": "Sin política de clave de API", + "noAdditionalApiKeyPolicy": "No hay una política adicional de clave de API asociada.", + "policyBinding": "Vinculación de política", + "policyBindingCount": "{count} vinculación de política", + "policyBindingsCount": "{count} vinculaciones de política", + "apiProfile": "Perfil de API {id}{revision}", + "walletProfile": "Perfil de Wallet {id}{revision}", + "revision": " rev {id}", + "roleAccess": "Acceso de {role}", + "createApiKey": "Crear clave de API", + "reviewApiKey": "Revisar clave de API", + "walletAccess": "Acceso a la Wallet", + "walletAccessDescription": "Elige si esta clave puede usar todas las Wallets del alcance o solo las Wallets seleccionadas.", + "allWalletsDescription": "Esta clave puede usar todas las Wallets disponibles en su alcance de organización o proyecto.", + "selectedWalletsDescription": "Restringe esta clave a un conjunto específico de Wallets y elige su Wallet de firma predeterminada.", + "operationPolicy": "Política de operaciones", + "noActiveWallets": "Aún no hay Wallets activas disponibles para vincular.", + "defaultSigningWallet": "Wallet de firma predeterminada", + "nameLabel": "Nombre", + "namePlaceholder": "Clave de despliegue de CI", + "role": "Rol", + "environment": "Entorno", + "expirationOptional": "Vencimiento (opcional)", + "production": "Producción", + "sandbox": "Sandbox", + "none": "Ninguno", + "invalidDate": "Fecha inválida", + "endpointPermissions": "Permisos de endpoints", + "policy": "Política", + "securityNote": "Nota de seguridad", + "creating": "Creando...", + "createKey": "Crear clave", + "createApiKeyDescription": "Define los detalles de la clave y el acceso a la Wallet, luego confirma.", + "reviewApiKeyDescription": "Revisa la solicitud antes de crear la clave.", + "deleteApiKey": "Eliminar clave de API", + "deleteApiKeyPlaceholder": "Escribe el nombre exacto de la clave", + "deleting": "Eliminando...", + "deleteKeyConfirm": "Eliminar clave", + "apiKeyGenerated": "Clave de API generada", + "keyPrefix": "Prefijo de la clave", + "fullKeyShownOnce": "Tu clave completa (se muestra una sola vez)", + "apiKeyPlaygroundSession": "Esta sesión del navegador ya puede usar esta clave en el API Playground sin pegarla de nuevo.", + "dismiss": "Descartar", + "copyValue": "Copiar", + "copied": "Copiado", + "closeGeneratedKeyModal": "Cerrar el modal de la clave generada", + "closeConfirmationModal": "Cerrar el modal de confirmación", + "delete": "Eliminar", + "deleteApiKeyDescription": "Esto elimina la clave sin eliminar la fila.", + "typeKeyNameToConfirm": "Escribe {name} para confirmar.", + "confirmKeyName": "Confirmar el nombre de la clave", + "cancel": "Cancelar", + "organizationName": "Nombre de la organización", + "organizationSlug": "Slug de la organización", + "clerkOrganizationId": "ID de organización de Clerk", + "unavailable": "No disponible", + "unableToLoadWalletProviders": "No se pudieron cargar los proveedores de Wallet", + "unableToLoadWallets": "No se pudieron cargar las Wallets", + "trackedBalancesUnavailable": "Los saldos rastreados no están disponibles en este momento. Mostrando el saldo reportado por la Wallet.", + "walletControlsUnavailable": "Los controles de la Wallet no están disponibles en este momento.", + "createWallet": "Crear Wallet", + "walletSearchPlaceholder": "Buscar por nombre, ID de Wallet, dirección, proveedor o propósito", + "clearWalletSearch": "Borrar búsqueda de Wallets", + "clearWalletSearchAction": "Borrar búsqueda", + "walletSearchResults": "Mostrando {count} de {total} Wallets", + "noWalletSearchResults": "Ninguna Wallet coincide con esta búsqueda", + "noWalletSearchResultsDescription": "Prueba con otro nombre, ID de Wallet, dirección, proveedor o propósito.", + "wallet": "Wallet", + "balance": "Saldo", + "purpose": "Propósito", + "issuance": "Emisión", + "compliance": "Cumplimiento", + "mintAuthority": "Mint Authority", + "freezeAuthority": "Freeze Authority", + "feePayer": "Pagador de tarifas", + "transfers": "Transferencias", + "address": "Dirección", + "walletId": "ID de Wallet", + "manage": "Administrar", + "createFirstWallet": "Crea tu primera Wallet", + "noWalletsAvailable": "No hay Wallets disponibles", + "createWalletDescription": "Elige el proveedor que creará la Wallet y firmará en su nombre.", + "walletCreationLimited": "La creación de Wallets está limitada a los administradores. Una vez creada, puedes seguir usando la Wallet en todo el dashboard.", + "noWalletProvidersEnabled": "No hay proveedores de Wallet habilitados", + "noWalletProvidersEnabledDescription": "Habilita un proveedor para esta organización antes de crear una Wallet.", + "backToWallets": "Volver a Wallets", + "chooseProvider": "Elegir proveedor", + "walletDetails": "Detalles de la Wallet", + "walletLabel": "Etiqueta de la Wallet", + "walletLabelPlaceholder": "Tesorería", + "project": "Proyecto", + "projectValue": "Proyecto actual", + "environmentValue": "Entorno actual", + "connectedProviderDescription": "{provider} usa su Wallet ya configurada en este flujo.", + "chooseEnabledProvider": "Elige un proveedor habilitado para continuar.", + "back": "Atrás", + "next": "Siguiente", + "continue": "Continuar", + "createWalletPending": "Creando...", + "saveWalletLabel": "Guardar etiqueta de la Wallet", + "cancelWalletLabelEdit": "Cancelar edición de la etiqueta de la Wallet", + "editWalletLabel": "Editar etiqueta de la Wallet", + "untitled": "Sin título", + "updatingWalletLabel": "Actualizando la etiqueta de la Wallet.", + "walletLabelUpdated": "Etiqueta de la Wallet actualizada.", + "unableToUpdateWalletLabel": "No se pudo actualizar la etiqueta de la Wallet.", + "unknownError": "Error desconocido", + "requestFailed": "La solicitud falló", + "httpRequestFailed": "{error} (HTTP {status})", + "walletIdRequired": "El ID de Wallet es obligatorio.", + "validWalletAddressRequired": "Una dirección de Wallet válida es obligatoria.", + "signInToRequestDevnetSol": "Inicia sesión para solicitar SOL de devnet.", + "devnetFaucetHttpError": "El proveedor de RPC {provider} del faucet de devnet devolvió HTTP {status}.", + "devnetFaucetEmptyResponse": "El faucet de devnet devolvió una respuesta de RPC vacía.", + "devnetFaucetProviderError": "El proveedor de RPC {provider} del faucet de devnet devolvió: {error}", + "devnetFaucetProviderGenericError": "El proveedor de RPC {provider} del faucet de devnet devolvió un error.", + "devnetFaucetNoSignature": "El faucet de devnet no devolvió ninguna firma de transacción.", + "walletAddress": "Dirección de la Wallet", + "walletMetadataCopied": "Se copió {label}.", + "unableToCopy": "No se pudo copiar {label}.", + "copy": "Copiar {label}", + "recentActivity": "Actividad reciente", + "recentActivityDescription": "Actividad de transferencias y operaciones de Token para esta Wallet.", + "refreshing": "Actualizando...", + "refresh": "Actualizar", + "noWalletActivity": "Aún no se encontró actividad de la Wallet.", + "activity": "Actividad", + "asset": "Activo", + "direction": "Dirección", + "counterparty": "Contraparte", + "signature": "Firma", + "unknownAsset": "Activo desconocido", + "unknown": "Desconocido", + "pending": "Pendiente", + "incoming": "Entrante", + "outgoing": "Saliente", + "transfer": "Transferencia", + "unableToLoadIssuanceActivity": "No se pudo cargar la actividad de emisión", + "paymentsActivityUnavailable": "La actividad de pagos no está disponible en este momento.", + "issuanceActivityUnavailable": "La actividad de emisión no está disponible en este momento.", + "noActivitySources": "No hay fuentes de actividad disponibles para esta Wallet.", + "walletActivityUnavailable": "La actividad de la Wallet no está disponible en este momento.", + "unableToVerifyWalletVisibility": "No se pudo verificar la visibilidad de la Wallet.", + "invalidWalletId": "ID de Wallet inválido.", + "walletActivityRequestFailed": "Falló la solicitud de actividad de la Wallet.", + "previous": "Anterior", + "active": "Activo", + "noWalletProvidersTier": "No hay proveedores de Wallet habilitados para este nivel de organización en este momento.", + "newWallet": "Nueva Wallet", + "providerAdditionalWalletUnavailable": "{provider} ya está conectado, pero aún no hay Wallets adicionales disponibles.", + "walletCreationAvailable": "La creación de Wallets está disponible después de habilitar un proveedor de custodia para esta organización.", + "stale": "(desactualizado)", + "organizationSettings": "Configuración de la organización", + "organizationSettingsDescription": "Configura el proveedor de RPC utilizado en toda esta organización.", + "appearance": "Apariencia", + "appearanceDescription": "Elige cómo se ve el dashboard. Esta preferencia se guarda solo en este dispositivo.", + "themeSystem": "Sistema", + "themeLight": "Claro", + "themeDark": "Oscuro", + "themeSystemHint": "El dashboard sigue la configuración de apariencia de tu dispositivo.", + "themeLightHint": "El dashboard siempre usa el tema claro en este dispositivo.", + "themeDarkHint": "El dashboard siempre usa el tema oscuro en este dispositivo.", + "failedToLoadOrganizationSettings": "No se pudo cargar la configuración de la organización.", + "organizationNotFound": "Organización no encontrada.", + "organizationNotLinked": "Esta organización de Clerk aún no está vinculada a una organización de SDP.", + "editingOrganization": "Editando organización: {name}", + "viewOnlyRpcSettings": "Puedes ver la configuración de RPC de la organización, pero solo los administradores pueden cambiarla.", + "noRpcProviders": "No hay proveedores de RPC habilitados para esta organización en el entorno actual.", + "rpcFallback": "El proveedor de RPC guardado para esta organización ya no está disponible en el nivel actual. El formulario volvió a {provider} hasta que guardes un proveedor habilitado.", + "saving": "Guardando...", + "saveFallback": "Guardar alternativa", + "rpcProvider": "Proveedor de RPC", + "testing": "Probando...", + "testRpc": "Probar RPC", + "rpcDetailTitle": "Última prueba", + "rpcDetailReachable": "Accesible", + "rpcDetailUnreachable": "Inaccesible", + "rpcDetailResolvedProvider": "Proveedor resuelto", + "rpcDetailSelectionMode": "Modo de selección", + "rpcDetailEndpoint": "Endpoint", + "rpcDetailUpstream": "Estado del upstream", + "rpcDetailLatency": "Latencia", + "rpcDetailLatencyValue": "{ms} ms", + "saveInProgress": "Guardado en curso.", + "tryAgainSoon": "Vuelve a intentarlo en un momento.", + "checkingRpcProvider": "Verificando el proveedor de RPC.", + "rpcCheckPassed": "La verificación de RPC fue exitosa.", + "providerMismatch": "Discrepancia de proveedor.", + "rpcCheckFailed": "La verificación de RPC falló.", + "anotherProvider": "otro proveedor", + "failedToSaveRpcSettings": "No se pudo guardar la configuración de RPC.", + "missingOrganizationId": "Falta el ID de la organización.", + "rpcProviderSaveMismatch": "Discrepancia al guardar el proveedor de RPC (solicitado {requested}, guardado {persisted}).", + "rpcSettingsSaved": "Configuración de RPC guardada.", + "failedToTestRpcProvider": "No se pudo probar el proveedor de RPC.", + "rpcTestFailed": "La prueba de RPC falló.", + "rpcTestFailedStatus": "La prueba de RPC falló ({status}).", + "rpcTestMismatch": "Discrepancia en la prueba de RPC (solicitado {requested}, resuelto {resolved}).", + "rpcUpstreamReturned": "El upstream de RPC devolvió {status} {statusText}.", + "rpcTestPassed": "La prueba de RPC fue exitosa ({status} {statusText}) en {latency}ms.", + "missingApiKeyIdForDeletion": "Falta el ID de la clave de API para eliminar.", + "missingApiKeyNameForDeletion": "Falta el nombre de la clave de API para confirmar la eliminación.", + "confirmApiKeyDeletion": "Escribe el nombre de la clave para confirmar la eliminación de la clave de API.", + "apiKeyConfirmationMismatch": "La confirmación no coincide con el nombre de la clave.", + "apiKeyDeactivated": "La clave de API \"{name}\" ha sido desactivada.", + "apiKeyDeleteFailed": "Error al eliminar: {error}", + "apiKeyNameRequired": "El nombre de la clave de API es obligatorio.", + "apiKeyWalletScopeRequired": "Elige si esta clave puede acceder a todas las Wallets o solo a las Wallets seleccionadas.", + "apiKeyWalletRequired": "Selecciona al menos una Wallet para una clave de API con alcance de Wallet.", + "invalidExpirationDate": "Fecha de vencimiento inválida.", + "apiKeyCreated": "Clave de API \"{name}\" creada. Guárdala ahora; no se volverá a mostrar.", + "apiKeyCreateFailed": "Error al crear: {error}", + "missingApiKeyIdForRotation": "Falta el ID de la clave de API para rotarla.", + "apiKeyRotated": "Clave de API rotada. La clave anterior sigue siendo válida hasta {deadline}.", + "apiKeyRotateFailed": "Error al rotar: {error}", + "providerLocalDescription": "Firmante autoalojado con par de claves Ed25519 a partir de CUSTODY_PRIVATE_KEY.", + "providerPrivyDescription": "Infraestructura de Wallet alojada para firmar mediante API.", + "providerFireblocksDescription": "Custodia con MPC y controles de Wallet basados en bóveda.", + "providerCoinbaseCdpDescription": "Aprovisionamiento programático de Wallets mediante Coinbase CDP.", + "providerParaDescription": "Custodia de Wallet integrada para operaciones a nivel de organización.", + "providerTurnkeyDescription": "Custodia de claves basada en políticas para cargas de firma en producción.", + "providerDfnsDescription": "Orquestación de Wallets con MPC y firma segura basada en API.", + "providerIbmHavenDescription": "Custodia institucional en IBM Digital Asset Haven.", + "providerAnchorageDescription": "Custodia institucional con gestión del ciclo de vida de la Wallet.", + "providerUtilaDescription": "Firma de Wallets de Solana respaldada por bóveda mediante cuentas de servicio de Utila.", + "providerCredentialLabel": "Etiqueta de credencial", + "providerCredentialLabelDescription": "Elige un nombre editable para esta credencial de proveedor.", + "providerCredentialScope": "Alcance de la credencial", + "providerCredentialScopeDescription": "Las credenciales de organización pueden compartirse por referencia; las credenciales de proyecto permanecen aisladas al proyecto seleccionado.", + "providerCredentialScopeOrganization": "Organización", + "providerCredentialScopeProject": "Proyecto", + "providerPrivyAppId": "ID de app de Privy", + "providerPrivyAppIdDescription": "Ingresa el ID de la app desde tu dashboard de Privy. SDP solo muestra metadatos enmascarados después del envío.", + "providerPrivyAppSecret": "Secreto de app de Privy", + "providerPrivyAppSecretDescription": "Ingresa el secreto de la app desde tu dashboard de Privy. Este valor es de solo escritura y nunca se vuelve a mostrar.", + "providerInitialWalletLabel": "Etiqueta inicial de la Wallet", + "providerInitialWalletLabelDescription": "Opcionalmente, nombra la Wallet predeterminada creada cuando la verificación de conexión tiene éxito.", + "apiKeyAdminDescription": "Administrador incluye privilegios de custodia y a nivel de plataforma. Desarrollador excluye las acciones de custodia.", + "apiKeyEnvironmentDescription": "Cambia el entorno del espacio de trabajo en la barra lateral para crear una clave en el otro entorno.", + "expiresOn": "Vence el {date}", + "default": "Predeterminado:", + "fullKeyOnlyShownOnce": "La clave completa solo se mostrará una vez después de crearla.", + "closeApiKeyCreationModal": "Cerrar el modal de creación de clave de API", + "policyDraftSaveFailed": "El borrador no se pudo guardar.", + "policyDraftSaveFailedDescription": "Puedes seguir configurando, pero los cambios podrían perderse si sales.", + "policyDraftSaved": "Borrador guardado.", + "policyDraftSavedDescription": "El perfil aún no está activo.", + "policyChooseRestriction": "Elige al menos una categoría de restricción.", + "policyCheckDestinations": "Revisa las direcciones de destino.", + "policyCheckDestinationsDescription": "Usa direcciones de Solana válidas antes de revisar.", + "policyChooseOperations": "Elige los controles de acceso de operaciones.", + "policyChooseOperationsDescription": "Selecciona al menos una familia de operaciones para bloquear.", + "policyCheckLimits": "Revisa los límites de transferencia.", + "policyCheckLimitsDescription": "Ingresa un número positivo para cada límite configurado.", + "policyChooseApprovals": "Elige las verificaciones de aprobación.", + "policyChooseApprovalsDescription": "Selecciona al menos una familia de operaciones que deba requerir aprobación.", + "policyChooseAdvanced": "Elige los controles avanzados de firma.", + "policyChooseAdvancedDescription": "Selecciona firma en bruto, interacciones de programa o ambas.", + "policyActivating": "Activando los controles de la Wallet.", + "policyActive": "Controles de la Wallet activos.", + "policyActiveDescription": "Las restricciones seleccionadas ahora están activas.", + "policyActivationFailed": "La activación falló.", + "policySaveFailed": "Los controles de la Wallet no se pudieron guardar.", + "policyDisabling": "Deshabilitando los controles de la Wallet.", + "policyDisabled": "Controles de la Wallet deshabilitados.", + "policyDisabledDescription": "La Wallet volvió a permitir por defecto.", + "policyDisableFailed": "La deshabilitación falló.", + "policyAuthoringIntentTitle": "¿Qué debe controlar esta Wallet?", + "policyAuthoringIntentDescription": "Define la decisión predeterminada y luego elige las áreas que necesitan controles explícitos.", + "policyAuthoringLimitsTitle": "Límites y activos", + "policyAuthoringLimitsDescription": "Define límites de transferencia genéricos y elige los activos cubiertos por este perfil.", + "policyAuthoringDestinationsTitle": "Destinos y operaciones", + "policyAuthoringDestinationsDescription": "Controla dónde puede actuar esta Wallet y qué operaciones necesitan una decisión específica.", + "policyAuthoringReviewTitle": "Revisar y activar", + "policyAuthoringReviewDescription": "Confirma el perfil completo antes de que cambien los controles vigentes.", + "policyDefaultAction": "Decisión predeterminada", + "policyDefaultActionDescription": "Se aplica solo cuando ninguna regla coincide.", + "policyDefaultAllow": "Permitir por defecto", + "policyDefaultApproval": "Requerir aprobación por defecto", + "policyDefaultDeny": "Denegar por defecto", + "policyRestrictionCategories": "Categorías de restricción", + "policyRestrictionCategoriesDescription": "Elige las áreas de control que quieres configurar en este perfil.", + "policyRestrictionRequired": "Con Permitir por defecto, la política no cambia nada hasta que agregues una restricción.", + "policyCategoryLimitsDescription": "Define un máximo por transacción o por día.", + "policyAllowedAssets": "Activos permitidos", + "policyAllowedAssetsDescription": "Limita este perfil a los activos seleccionados de la Wallet o a cualquier dirección de mint de Solana.", + "policyDestinationControls": "Controles de destino", + "policyDestinationControlsDescription": "Mantén una allowlist o blocklist ordenada de direcciones de Solana.", + "policyOperationControls": "Controles de operación", + "policyOperationControlsDescription": "Elige una decisión para las familias de operaciones de la Wallet y los tipos de operación exactos.", + "policyPerTransaction": "Por transacción", + "policyAssetBadgeIssued": "Emitido", + "policyAssetBadgeCustom": "Personalizado", + "policySummarySelectedCount": "Seleccionados: {count}", + "policyDailyTotal": "Total diario", + "policyTransferLimitsHint": "Limita el monto por transacción o por día. Los límites se aplican al monto enviado, sin importar qué activo se use.", + "policyInvalidDecimal": "Ingresa un valor decimal positivo.", + "policyDailyBelowTransaction": "El total diario no puede ser menor que el monto por transacción.", + "policySearchAssets": "Busca activos de la Wallet o ingresa cualquier dirección de mint", + "policyWalletAssets": "Activos de la Wallet", + "policySelectedAssets": "Activos seleccionados", + "policyCustomMint": "Mint personalizado", + "policyNoMatchingAssets": "No hay activos coincidentes.", + "policyAddCustomMint": "Agregar mint personalizado", + "policyInvalidMint": "Ingresa una dirección de mint de Solana válida.", + "policyDuplicateAsset": "Este activo ya está seleccionado.", + "policyRemoveAsset": "Quitar {asset}", + "policyNoStepControls": "No se seleccionó ningún control en este paso. Puedes continuar o volver a Intención para agregarlos.", + "policyAllowList": "Allowlist", + "policyBlockList": "Blocklist", + "policyWalletAddresses": "Direcciones de Wallet", + "policyDuplicateDestination": "Esta dirección ya está en la lista.", + "policyDestinationInvalid": "Ingresa una dirección de Solana válida.", + "policyDestinationSearchPlaceholder": "Busca contrapartes o pega direcciones separadas por comas", + "policyDestinationCounterparties": "Contrapartes", + "policyDestinationExternal": "Dirección externa", + "policyDestinationAddExternal": "Agregar dirección", + "policyNoMatchingDestinations": "No hay contrapartes coincidentes.", + "policyDestinationAllowlistDescription": "Solo las direcciones a continuación pueden recibir desde esta Wallet.", + "policyDestinationBlocklistDescription": "Las direcciones a continuación nunca pueden recibir desde esta Wallet.", + "policyBulkAddSummary": "{added} agregadas · {flagged} marcadas para revisión", + "policyBulkNothingToAdd": "No se encontraron direcciones válidas nuevas en el texto pegado.", + "policyRemoveDestination": "Quitar {address}", + "policyTransfers": "Transferencias", + "policyProgramOperations": "Operaciones de programa", + "policyProviderAdministration": "Administración de proveedor", + "policyTransfersDescription": "Transferencias de Wallet a Wallet firmadas directamente por esta Wallet.", + "policyPaymentsDescription": "Envíos de pagos individuales, por lote y recurrentes.", + "policyRampsDescription": "Operaciones de on-ramp y off-ramp, incluidas las cotizaciones de proveedor.", + "policyIssuanceDescription": "Acciones de emisión de Tokens, como hacer mint y actualizar autoridades.", + "policyRawSigningDescription": "Solicitudes de firma de bajo nivel, incluidas las verificaciones del firmante de custodia.", + "policyProgramOperationsDescription": "Interacciones directas con programas de Solana fuera de los flujos administrados.", + "policyProviderAdministrationDescription": "Cambios administrativos al proveedor de custodia de esta Wallet.", + "policyActionAllow": "Permitir", + "policyActionDeny": "Denegar", + "policyActionApproval": "Requerir aprobación", + "policyAdvancedOperationTypes": "Tipos de operación avanzados", + "policyAdvancedOperationDescription": "Agrega cadenas exactas de tipo de operación cuando una decisión a nivel de familia no sea suficientemente específica.", + "policyViewOperationPermissions": "Ver todos los permisos de operación admitidos", + "policyOperationTypePlaceholder": "p. ej., payment_transfer_execute", + "policyOperationTypeTooLong": "Los tipos de operación deben tener 120 caracteres o menos.", + "policySummary": "Resumen de la política", + "policySummaryWallet": "Wallet", + "policySummaryAddress": "Dirección", + "policySummaryStatus": "Estado", + "policySummaryDefaultAction": "Decisión predeterminada", + "policySummaryControlAreas": "Áreas de control", + "policySummaryAllowedAssets": "Activos permitidos", + "policySummaryDestinations": "Entradas de destino", + "policySummaryApprovals": "Verificaciones de aprobación", + "policySummaryProvider": "Mapeo del proveedor", + "policyCopyAddress": "Copiar dirección de la Wallet", + "policyAddressCopied": "Dirección de la Wallet copiada.", + "policyStatusDefaultAllow": "Permitir por defecto", + "policyStatusNotActivated": "No activado", + "policyStatusActive": "Activo", + "policyStatusDraft": "Borrador", + "policyStatusDisabled": "Deshabilitado", + "policyStatusArchived": "Archivado", + "policyNotConfigured": "No configurado", + "policyEdit": "Editar", + "policyReviewTransferLimits": "Límites de transferencia", + "policyReviewAllowedAssets": "Activos permitidos", + "policyReviewDestinationControls": "Controles de destino", + "policyReviewOperationControls": "Controles de operación", + "policyReviewPerTransaction": "Por transacción {amount}", + "policyReviewDailyTotal": "Total diario {amount}", + "policyReviewPreservedRules": "Reglas avanzadas existentes incluidas: {count}", + "policyReviewNoRestrictions": "Nada está restringido todavía — activar no cambiaría nada.", + "policySaveDraft": "Guardar borrador", + "policyActivateControls": "Activar controles", + "policyControlsActive": "Controles activos", + "policyMoreActions": "Más acciones de política", + "policyDisableControls": "Deshabilitar controles", + "policyDisableTitle": "¿Deshabilitar los controles de la Wallet?", + "policyDisableConfirmation": "¿Deshabilitar los controles de {wallet}? Esto restablece la Wallet a permitir por defecto.", + "policyCancel": "Cancelar", + "policyConfirmDisable": "Deshabilitar controles", + "policyDraftStoredLocally": "Guardado en este dispositivo {date}", + "policyActivationValidation": "Revisa los campos de política resaltados antes de la activación.", + "policyProviderWarning": "Algunos controles no están completamente mapeados al proveedor de custodia y permanecen aplicados por SDP.", + "wallets": "Wallets", + "playgroundListWallets": "Listar Wallets", + "playgroundListWalletConfigs": "Listar configuraciones de Wallet", + "playgroundGetWallet": "Obtener Wallet", + "playgroundGetWalletPublicKey": "Obtener clave pública de la Wallet", + "playgroundAggregateBalances": "Consultar saldos agregados de Wallets", + "playgroundCreateWallet": "Crear Wallet", + "playgroundSignerCheck": "Verificación de firmante", + "rootWallet": "Wallet raíz", + "mainWallet": "Wallet principal", + "mainSettlementWallet": "Wallet principal de liquidación", + "selectWalletPurpose": "Selecciona el propósito de la Wallet", + "ownershipProof": "Prueba de propiedad desde el Playground de Wallets", + "untitledWallet": "Wallet sin título", + "publicKey": "Clave pública", + "provider": "Proveedor", + "totalBalance": "Saldo total", + "balances": "Saldos", + "noTrackedBalances": "Aún no se encontraron saldos rastreados para esta Wallet.", + "walletControls": "Controles de la Wallet", + "walletRestrictionsActive": "Esta Wallet tiene restricciones de pago saliente activas.", + "walletDefaultAllow": "Esta Wallet comienza en permitir por defecto. Agrega restricciones solo donde se necesite control.", + "destinations": "Destinos", + "open": "Abrir", + "perTransfer": "Por transferencia", + "daily": "Diario", + "noCap": "Sin límite", + "reviewControls": "Revisar controles", + "startProfile": "Iniciar perfil", + "policyIntent": "Intención", + "policySetWalletPolicies": "Establecer políticas de la Wallet", + "policyIntentDescription": "Elige a dónde pueden ir los fondos y cuánto puede transferir esta Wallet.", + "policyRules": "Reglas", + "policyStartingRules": "Reglas iniciales", + "policyRulesDescription": "Configura las áreas de reglas seleccionadas antes de la revisión.", + "policyReview": "Revisión", + "policyFinalReview": "Revisión final", + "policyReviewDescription": "Revisa los cambios antes de aplicar los controles de la Wallet.", + "policyOperationAccess": "Acceso a operaciones", + "policyOperationAccessDescription": "Bloquea familias de operaciones de alto riesgo mientras mantienes disponible el uso normal.", + "policyAllowedDestinations": "Destinos permitidos", + "policyAllowedDestinationsDescription": "Úsalo cuando esta Wallet solo deba pagar a direcciones conocidas.", + "policyTransferLimits": "Límites de transferencia", + "policyAdvancedSigning": "Firma avanzada", + "policyAdvancedSigningDescription": "Restringe la firma sin procesar y las rutas de interacción directa con programas.", + "policyPayments": "Pagos", + "policyRamps": "Ramps", + "policyIssuance": "Emisión", + "policyProviderAdmin": "Administración del proveedor", + "policyRawSigning": "Firma sin procesar", + "policyProgramInteractions": "Interacciones con programas", + "policyAllowed": "Permitido", + "policyDenied": "Denegado", + "policyApprovalRequired": "Aprobación requerida", + "policyProviderApprovalRequired": "Aprobación del proveedor requerida", + "policyNotEvaluated": "No evaluado", + "policyFailed": "Fallido", + "recentPolicyDecisions": "Decisiones de política recientes", + "policyEvaluationsShown": "Evaluaciones mostradas para esta Wallet: {count}", + "needsApproval": "Necesita aprobación", + "stepOf": "Paso {current} de {total}", + "onboardingEyebrow": "Configuración de la organización", + "onboardingTitle": "Configura tu espacio de trabajo", + "onboardingDescription": "Elige la infraestructura que usará tu organización.", + "onboardingChooseRpc": "Elige tu proveedor de RPC", + "onboardingChooseCustody": "Elige tu proveedor de custodia", + "onboardingProvidersChangeLater": "Puedes cambiar de proveedor en cualquier momento en Configuración.", + "onboardingNoRpcProviders": "No hay proveedores de RPC disponibles para esta organización en el entorno actual. Contacta a tu administrador de SDP antes de continuar.", + "onboardingNoCustodyProviders": "No hay proveedores de custodia disponibles para esta organización en el entorno actual. Contacta a tu administrador de SDP antes de continuar.", + "onboardingFinish": "Finalizar configuración", + "onboardingDefaultWalletLabel": "Wallet predeterminada", + "onboardingFinishError": "No se pudo finalizar la configuración de la organización.", + "onboardingSaving": "Guardando...", + "onboardingPreparingTitle": "Tu espacio de trabajo se está atando los cordones", + "onboardingPreparingDescription": "Espera un momento mientras el logo de Solana estira las piernas. Entrarás automáticamente en cuanto tu espacio de trabajo esté listo.", + "onboardingAdminTitle": "Un administrador está configurando este espacio de trabajo", + "onboardingAdminDescription": "Podrás usar el dashboard en cuanto un administrador de la organización elija los proveedores de RPC y custodia.", + "onboardingRpcDefaultDescription": "Usa la infraestructura de RPC administrada por SDP sin necesidad de configurar credenciales.", + "onboardingRpcAlchemyDescription": "Enruta las solicitudes de Solana a través de tu conexión configurada con Alchemy.", + "onboardingRpcHeliusDescription": "Usa la infraestructura de Helius para las solicitudes de RPC de Solana.", + "onboardingRpcNoditDescription": "Usa Nodit para tu tráfico de RPC de Solana.", + "onboardingRpcQuickNodeDescription": "Usa tu endpoint de QuickNode configurado para el RPC de Solana.", + "onboardingRpcTritonDescription": "Enruta las solicitudes de Solana a través de la infraestructura de Triton.", + "onboardingRpcValidationCloudDescription": "Usa Validation Cloud para tu tráfico de RPC de Solana.", + "collapse": "Contraer", + "expand": "Expandir", + "policyActivationOutcome": "Resultado de la activación", + "policyDefault": "Predeterminado", + "policyAllowUnmatched": "Permitir operaciones no coincidentes", + "policyRevision": "Revisión", + "policyProviderMapping": "Mapeo del proveedor", + "policySdpEnforced": "Aplicado por SDP", + "policyNoRestrictionCategory": "No se seleccionó ninguna categoría de restricción.", + "policyNoOperationsBlocked": "Ninguna familia de operaciones bloqueada", + "policyNoAddresses": "Sin direcciones", + "policyNoApprovalChecks": "Sin verificaciones de aprobación", + "policyNoAdvancedControls": "Sin controles de firma avanzada", + "savedDraft": "Borrador guardado", + "policyApplyControls": "Aplicar controles", + "policyChooseOperationFamilies": "Elige las familias de operaciones para bloquear.", + "policyPasteAddresses": "Pega las direcciones de Solana aprobadas o una columna CSV de direcciones.", + "policySetCaps": "Establece un límite por transferencia, un límite diario, o ambos.", + "policyChooseApprovalFamilies": "Elige las familias de operaciones que deben pausarse para aprobación.", + "policyBlockAdvanced": "Bloquea la firma sin procesar, las interacciones con programas, o ambas.", + "new": "Nuevo", + "policyProviderMappingPending": "Mapeo del proveedor pendiente", + "policyProviderMapped": "Proveedor mapeado", + "policyProviderPartiallyMapped": "Parcialmente mapeado con el proveedor", + "policyProviderMappingFailed": "Falló el mapeo del proveedor", + "policyBlockFamilies": "Bloquear {families}", + "policyDenyFamilies": "Denegar {families}", + "policyDestinationCount": "Direcciones: {count}", + "policyInvalidCount": "Inválidas: {count}", + "policyAllowedCount": "Permitidas: {count}", + "policyPerTransferValue": "Por transferencia {value}", + "policyDailyValue": "Diario {value}", + "policyAuditTitle": "Auditoría de política", + "policyAuditBreadcrumb": "Navegación de auditoría de política", + "policyAuditEvaluation": "Evaluación", + "policyAuditBackToWalletControls": "Volver a los controles de la Wallet", + "policyAuditBackToAudit": "Volver a la auditoría", + "policyAuditRevisionHistory": "Historial de revisiones", + "policyAuditWalletHistory": "Historial de política de {wallet}", + "policyAuditWalletHistoryDescription": "Revisa las decisiones de política usando la revisión que se aplicó cuando se evaluó cada operación.", + "policyAuditDecision": "Decisión", + "policyAuditAllowed": "Permitido", + "policyAuditBlocked": "Bloqueado", + "policyAuditApprovalRequired": "Aprobación requerida", + "policyAuditReview": "Revisión", + "policyAuditNotEvaluated": "No evaluado", + "policyAuditAllDecisions": "Todas las decisiones", + "policyAuditOperationStatus": "Estado de la operación", + "policyAuditAllStatuses": "Todos los estados", + "policyAuditOperationFamily": "Familia de operaciones", + "policyAuditAllFamilies": "Todas las familias", + "policyAuditReasonCode": "Código de motivo", + "policyAuditAllReasons": "Todos los motivos", + "policyAuditFromDate": "Fecha desde", + "policyAuditToDate": "Fecha hasta", + "policyAuditApplyFilters": "Aplicar filtros", + "policyAuditClearFilters": "Borrar filtros", + "policyAuditMoreFilters": "Más filtros", + "policyAuditOperation": "Operación", + "policyAuditAssetAmount": "Activo / monto", + "policyAuditDestination": "Destino", + "policyAuditApiKeyActor": "Clave de API / actor", + "policyAuditAppliedRevision": "Revisión aplicada", + "policyAuditActiveRevision": "Revisión activa", + "policyAuditEvaluated": "Evaluado", + "policyAuditOpenEvaluation": "Abrir evaluación", + "policyAuditEmpty": "Aún no hay evaluaciones de política", + "policyAuditEmptyDescription": "Las decisiones de política aparecerán aquí después de que se evalúen las operaciones de la Wallet.", + "policyAuditEmptyFiltered": "Ninguna evaluación coincide con los filtros activos.", + "policyAuditDefaultAllow": "Permitir por defecto", + "policyAuditNoActiveRevision": "Sin revisión activa", + "policyAuditUnavailable": "No disponible", + "policyAuditUnavailableApiKey": "Clave de API no disponible", + "policyAuditRange": "{from}-{to} de {total}", + "policyAuditPreviousPage": "Página anterior", + "policyAuditNextPage": "Página siguiente", + "policyAuditPageOf": "Página {page} de {pageCount}", + "policyAuditTransferAllowed": "Transferencia permitida", + "policyAuditTransferBlocked": "Transferencia bloqueada", + "policyAuditSentToReview": "Enviado a revisión", + "policyAuditPrevious": "Anterior", + "policyAuditNext": "Siguiente", + "policyAuditRequest": "Solicitud", + "policyAuditRevisions": "Revisiones", + "policyAuditDetailTabs": "Detalle de auditoría de política", + "policyAuditEvaluationSequence": "Secuencia de evaluación", + "policyAuditWalletPolicyEvaluation": "Evaluación de política de la Wallet", + "policyAuditApiKeyPolicyEvaluation": "Evaluación de política de la clave de API", + "policyAuditMatchedRule": "Regla coincidente", + "policyAuditObservedValueContext": "Valor observado / contexto", + "policyAuditEffectiveLimitExpectation": "Límite efectivo / expectativa", + "policyAuditFinalDecision": "Decisión final", + "policyAuditRecorded": "Registrado", + "policyAuditApplied": "Aplicado", + "policyAuditRawDetails": "Ver detalles sin procesar", + "policyAuditNoRecordedValues": "No se registró ningún valor.", + "policyAuditYes": "Sí", + "policyAuditNo": "No", + "policyAuditNone": "Ninguno", + "policyAuditAppliedRevisionAtEvaluation": "Revisión aplicada en la evaluación", + "policyAuditCurrentlyActiveRevision": "Revisión actualmente activa", + "policyAuditHistoricalRevisionNotice": "Esta decisión histórica usó una revisión diferente de la que está activa ahora.", + "policyAuditApiKeyAppliedRevision": "Revisión de la clave de API en la evaluación", + "policyAuditApiKeyActiveRevision": "Revisión de clave de API actualmente activa", + "policyAuditNoAdditionalRestriction": "Sin restricción adicional", + "policyAuditEvaluatedAt": "Evaluado {date}", + "policyAuditRevisionId": "ID de revisión", + "policyAuditEvaluationId": "ID de evaluación", + "policyAuditOperationId": "ID de operación", + "policyAuditRequestId": "ID de solicitud", + "policyAuditApiKeyId": "ID de clave de API", + "policyAuditRequestContext": "Contexto de la solicitud", + "policyAuditRedactedContext": "Contexto redactado registrado con esta evaluación.", + "policyAuditLegacyContextEmpty": "No se registró ningún contexto de solicitud estructurado para esta evaluación.", + "policyAuditEvaluationContext": "Contexto de evaluación", + "policyAuditApiKey": "Clave de API", + "policyAuditActor": "Actor", + "policyAuditProviderMapping": "Mapeo del proveedor", + "policyAuditApprovalRequest": "Solicitud de aprobación", + "policyAuditProviderPending": "Mapeo del proveedor pendiente", + "policyAuditProviderPartial": "Parcialmente mapeado", + "policyAuditProviderFailed": "Falló el mapeo del proveedor", + "policyAuditProviderApproval": "Aprobación del proveedor requerida", + "policyAuditSdpEnforced": "Aplicado por SDP", + "policyAuditViewWalletControls": "Ver controles de la Wallet", + "policyAuditViewApiKey": "Ver clave de API", + "policyAuditViewApprovalRequest": "Ver solicitud de aprobación", + "policyAuditUnavailableTitle": "Historial de política no disponible", + "policyAuditUnavailableDescription": "No se pudo cargar el historial de política de la Wallet en este momento.", + "policyRevisionsTitle": "Revisiones de política", + "policyRevisionsWalletHistory": "Historial de revisiones de {wallet}", + "policyRevisionsDescription": "Inspecciona instantáneas inmutables de reglas sin cambiar los controles activos de la Wallet.", + "policyRevisionsEmpty": "Aún no hay revisiones de política", + "policyRevisionsEmptyDescription": "Una revisión aparecerá después de que se guarden los controles de la Wallet.", + "policyRevisionsNewestFirst": "Revisión más reciente primero", + "policyRevisionNumber": "Revisión v{number}", + "policyRevisionsCreated": "Creado", + "policyRevisionsActivated": "Activado", + "policyRevisionsRules": "Reglas", + "policyRevisionsCreator": "Creador", + "policyRevisionsSystem": "Sistema", + "policyRevisionsActive": "Activa", + "policyRevisionsHistorical": "Histórica", + "policyRevisionsDraft": "Borrador", + "policyRevisionsRuleSnapshot": "Instantánea de reglas de solo lectura", + "policyRevisionsSnapshotDescription": "Esta instantánea inmutable se muestra exactamente como se almacenó para esta revisión.", + "policyRevisionsDefaultAction": "Acción predeterminada", + "policyRevisionsNoRules": "No se almacenó ninguna regla explícita en esta revisión.", + "policyRevisionsRuleNumber": "Regla {number}", + "policyRevisionsRawRule": "Ver datos de regla sin procesar", + "sandboxProjectUnavailable": "El proyecto de Sandbox no está disponible. Vuelve a cargar el dashboard e inténtalo de nuevo.", + "sendingSignerCheck": "Enviando verificación de firmante.", + "signerCheckFailed": "Falló la verificación de firmante.", + "signerCheckSent": "Verificación de firmante enviada.", + "memoTransactionSubmitted": "Transacción memo enviada.", + "viewOnSolanaExplorer": "Ver en Solana Explorer", + "requestingDevnetSol": "Solicitando SOL de devnet.", + "devnetFaucetFailed": "Falló el faucet de devnet.", + "devnetSolRequested": "Se solicitaron {amount} SOL de devnet.", + "faucetTransactionSubmitted": "Transacción de faucet enviada.", + "walletActionsFor": "Acciones de la Wallet para {wallet}", + "proving": "Demostrando...", + "proveOwnershipUnsupported": "Demostrar propiedad (no disponible)", + "proveOwnership": "Demostrar propiedad", + "proveOwnershipAdminOnly": "Demostrar propiedad (solo administradores)", + "requesting": "Solicitando...", + "requestDevnetSol": "Solicitar SOL de devnet", + "policyRuleAllowedDestinations": "Destinos permitidos", + "policyRulePerTransferLimit": "Límite por transferencia", + "policyRuleApprovalChecks": "Verificaciones de aprobación", + "policyRevisionNew": "Nuevo", + "policyPerTransferCap": "Límite por transferencia", + "policyDailyCap": "Límite diario", + "policyPositiveNumber": "Ingresa un número positivo.", + "policyAddressPlaceholder": "dirección 9xQeWvG816bUx9EPfuxEzHh9VY5k...", + "policyDisable": "Deshabilitar", + "policyApprovalRequest": " / Aprobación {id}", + "playgroundProviderField": "Proveedor", + "playgroundLabelField": "Etiqueta", + "playgroundPurposeField": "Propósito", + "playgroundMemoField": "Memo", + "policyOperationEditorDescription": "Las familias seleccionadas se deniegan antes de la firma o ejecución. Las familias no seleccionadas continúan usando permitir por defecto a menos que se aplique otra regla.", + "policyDestinationEditorDescription": "Pega direcciones de Solana separadas por saltos de línea, comas, punto y coma, tabulaciones, o una columna CSV.", + "policyInvalidAddress": "Dirección inválida: {addresses}", + "policyInvalidAddresses": "Direcciones inválidas: {addresses}", + "policyApprovalEditorDescription": "Las familias seleccionadas se pausan con una decisión de política de aprobación requerida. El enrutamiento a la bandeja de aprobaciones se gestiona mediante el flujo de aprobación posterior.", + "policyAdvancedEditorDescription": "Estos controles son intencionalmente estrictos porque pueden eludir la intención de pago de alto nivel.", + "providerCategoryApi": "API", + "providerCategoryApiDescription": "Infraestructura de Wallet para productos, operaciones y flujos automatizados basados en API.", + "providerCategoryInstitutional": "Institucional", + "providerCategoryInstitutionalDescription": "Custodia basada en políticas para tesorería, liquidación y flujos de aprobación multiparte.", + "existingApiKeysDescription": "Claves activas e históricas para este espacio de trabajo.", + "apiKeysViewOnly": "Puedes ver las claves de API, pero solo los administradores pueden crearlas, rotarlas o eliminarlas.", + "apiKeyRotationHint": "Sugerencia de rotación: rota solo claves activas. El dashboard usa un período de gracia de 24 horas; usa la API para valores de gracia personalizados (0-168h). Los secretos de las claves nuevas se muestran una sola vez.", + "apiKeyStepDetails": "Detalles", + "apiKeyStepPermissions": "Permisos", + "apiKeyStepWalletAccess": "Acceso a la Wallet", + "apiKeyStepReview": "Revisión", + "apiKeyAuthoringProgress": "Progreso de creación de la clave de API", + "apiKeyDetailsTitle": "Detalles de la clave", + "apiKeyDetailsDescription": "Nombra la clave y elige cuándo debe vencer.", + "apiKeyIdentity": "Identidad de la clave", + "apiKeyPermissionsTitle": "Permisos de endpoints", + "apiKeyPermissionsDescription": "Elige a qué endpoints de SDP puede acceder esta clave.", + "apiKeyRoleFixedOnEdit": "El rol permanece fijo después de la creación. El alcance de Wallet y política aún se puede actualizar.", + "apiKeyRoleDescription": { + "api_admin": "Acceso completo a los endpoints, incluidas las operaciones administrativas.", + "api_developer": "Acceso estándar a Tokens, pagos, contrapartes, Wallets, cumplimiento y webhooks.", + "api_readonly": "Acceso de solo lectura a los recursos operativos y los datos de auditoría." + }, + "apiKeyFullEndpointAccess": "Acceso completo a los endpoints", + "apiKeyPermissionCount": "Permisos de endpoint: {count}", + "apiKeyPermissionsSeparateFromPolicy": "Los permisos de endpoint determinan el alcance. Los controles de la Wallet y las restricciones de la clave de API se evalúan por separado para cada operación.", + "apiKeyWalletPolicyTitle": "Acceso a la Wallet y política", + "apiKeyWalletPolicyDescription": "Elige dónde puede firmar esta clave y qué controles adicionales se aplican.", + "apiKeyAllWalletsHelper": "Esta clave puede acceder a las Wallets permitidas por sus permisos de endpoint.", + "apiKeySelectedWalletCount": "Wallets seleccionadas ({count})", + "apiKeySearchWallets": "Buscar Wallets", + "apiKeyNoWalletSearchResults": "Ninguna Wallet coincide con esta búsqueda.", + "apiKeySelectWallet": "Seleccionar {wallet}", + "apiKeyMakeDefaultWallet": "Convertir {wallet} en la Wallet de firma predeterminada", + "apiKeyMakeDefaultSigningWallet": "Convertir en Wallet de firma predeterminada", + "apiKeyWalletControlsEnforced": "Los controles de la Wallet siempre se aplican.", + "apiKeyWalletControlsDescription": "Las restricciones de la clave de API pueden acotar estos controles, pero no pueden eludirlos ni reemplazarlos.", + "apiKeyNoWalletBaseline": "No hay una línea base de controles de Wallet disponible hasta que se seleccione una Wallet.", + "apiKeyPolicyStatusDefaultAllow": "Permitir por defecto", + "apiKeyPolicyStatusDraft": "Borrador", + "apiKeyPolicyStatusDisabled": "Deshabilitado", + "apiKeyActiveRevision": "Revisión {revision}", + "apiKeyRestrictionsTitle": "Restricciones de la clave de API", + "apiKeyAddRestrictions": "Agregar restricciones de la clave de API", + "apiKeyNoAdditionalRestrictions": "Sin restricciones adicionales de la clave de API", + "apiKeyRestrictionsNarrowCopy": "Estas restricciones acotan el acceso además de los controles de la Wallet.", + "apiKeyExistingRestrictionsActive": "Restricciones activas de la clave de API", + "apiKeyExistingRestrictionsPreserved": "El perfil activo permanece sin cambios hasta que reemplaces explícitamente los detalles de su restricción.", + "apiKeyExistingRestrictionsPreservedShort": "Restricciones existentes preservadas", + "apiKeyReplaceRestrictionDetails": "Reemplazar detalles de restricción", + "apiKeyAdditionalDefaultAction": "Restricción adicional: acción predeterminada", + "apiKeyAdditionalOperationFamilies": "Restricción adicional: familias de operaciones", + "apiKeyAdditionalOperationTypes": "Restricción adicional: tipos de operación", + "apiKeyAdditionalAssets": "Restricción adicional: activos", + "apiKeyAdditionalAmounts": "Restricción adicional: límites de monto", + "apiKeyAdditionalDestinations": "Restricción adicional: destinos", + "apiKeyAdditionalApprovals": "Restricción adicional: requisitos de aprobación", + "apiKeyFamilyTransfer": "Transferencias", + "apiKeyFamilyPayment": "Pagos", + "apiKeyFamilyRamp": "Ramps", + "apiKeyFamilyIssuance": "Emisión", + "apiKeyFamilyRawSign": "Firma sin procesar", + "apiKeyFamilyProgram": "Interacciones con programas", + "apiKeyFamilyProviderAdmin": "Administración del proveedor", + "apiKeyOperationTypesPlaceholder": "payment_transfer_execute, token_mint", + "apiKeyAssetsPlaceholder": "USDC, SOL", + "apiKeyMaximumAmount": "Monto máximo de la operación", + "apiKeyMaximumAmountPlaceholder": "2500", + "apiKeyDestinationsPlaceholder": "Pega las direcciones de Solana permitidas", + "apiKeyRequireApproval": "Requerir aprobación para las operaciones alcanzables", + "apiKeyRequireApprovalDescription": "Las operaciones coincidentes se pausan hasta que se registre una decisión de aprobación.", + "apiKeyRestrictionAmountInvalid": "Ingresa un monto decimal positivo.", + "apiKeyReviewTitle": "Revisar clave de API", + "apiKeyReviewDescription": "Confirma la identidad, el alcance de endpoints, los controles de la Wallet y las restricciones adicionales.", + "apiKeyReviewIdentity": "Identidad de la clave", + "apiKeyReviewPermissions": "Permisos de endpoints", + "apiKeyReviewWalletAccess": "Acceso a la Wallet", + "apiKeyReviewWalletBaseline": "Línea base de controles de la Wallet", + "apiKeyReviewRestrictions": "Restricciones adicionales de la clave de API", + "apiKeyReviewBindingChanges": "Cambios de vinculación", + "apiKeyRestrictionRuleCount": "Reglas de restricción adicionales: {count}", + "apiKeyDefaultAllowWarning": "Los controles de la Wallet usan Permitir por defecto para: {wallets}.", + "apiKeyRestrictionNoReachableWalletWarning": "Las restricciones de la clave de API están configuradas, pero ninguna Wallet seleccionada es alcanzable.", + "apiKeySummaryTitle": "Resumen de la clave", + "apiKeySummaryPermissions": "Permisos", + "apiKeySummarySelectedWallets": "Wallets seleccionadas", + "apiKeySummaryWalletBaseline": "Línea base de controles de la Wallet", + "apiKeySummaryRestrictions": "Restricciones de la clave de API", + "apiKeySummaryBindingScope": "Alcance de vinculación", + "apiKeyAllReachableWallets": "Todas las Wallets alcanzables", + "apiKeyWalletControlsAlwaysApply": "Los controles de la Wallet siempre se aplican. Las restricciones de la clave de API solo acotan el acceso resultante.", + "apiKeyNoPolicyBindings": "No se creará ninguna vinculación de política", + "apiKeyBindingsUnchanged": "Las vinculaciones existentes permanecen sin cambios", + "apiKeyBindingsWillClear": "Las vinculaciones existentes se eliminarán después de la confirmación", + "apiKeyBindingsWillCreate": "Las restricciones se vincularán a este alcance de Wallet", + "apiKeyBindingsWillReplace": "Las vinculaciones existentes se reemplazarán después de la confirmación", + "apiKeyRestrictionReplacementRequired": "Reemplaza los detalles de restricción existentes antes de cambiar el alcance de Wallet de esta clave.", + "apiKeyAffectedWallets": "Wallets afectadas", + "apiKeyReplaceBindings": "Reemplazar vinculaciones", + "apiKeyClearBindings": "Eliminar vinculaciones", + "apiKeyReplaceBindingsTitle": "¿Reemplazar vinculaciones de política?", + "apiKeyClearBindingsTitle": "¿Eliminar vinculaciones de política?", + "apiKeyReplaceBindingsDescription": "Las vinculaciones actuales de estas Wallets se eliminarán y se reemplazarán con el alcance propuesto.", + "apiKeyClearBindingsDescription": "Las vinculaciones actuales de estas Wallets se eliminarán. Los controles de la Wallet seguirán aplicándose.", + "apiKeySaveChanges": "Guardar cambios", + "apiKeyUpdated": "Clave de API \"{name}\" actualizada.", + "apiKeySaveFailed": "No se pudo guardar la clave de API: {error}", + "apiKeyEditMissingId": "El ID de la clave de API es obligatorio para guardar los cambios.", + "apiKeyReplaceBindingsConfirmationRequired": "Confirma Reemplazar vinculaciones antes de guardar este cambio de vinculación.", + "apiKeyClearBindingsConfirmationRequired": "Confirma Eliminar vinculaciones antes de guardar este cambio de vinculación.", + "policyAssetsInWallet": "En esta Wallet", + "policyAssetsCommon": "Tokens comunes", + "policyAssetsIssued": "Tus Tokens" + } +} diff --git a/apps/sdp-web/messages/es/dashboard-issuance.json b/apps/sdp-web/messages/es/dashboard-issuance.json new file mode 100644 index 000000000..09f05ebc7 --- /dev/null +++ b/apps/sdp-web/messages/es/dashboard-issuance.json @@ -0,0 +1,1276 @@ +{ + "DashboardIssuance": { + "transactions": { + "title": "Transacciones", + "description": "Operaciones recientes con Tokens", + "loading": "Cargando historial de operaciones…", + "empty": "Aún no hay transacciones.", + "type": "Tipo", + "status": "Estado", + "signature": "Firma", + "created": "Creado", + "showing": "Mostrando las primeras {count} transacciones{total}. Usa la paginación para ver registros anteriores.", + "loadError": "No se pudieron cargar las transacciones.", + "noMatches": "No hay transacciones que coincidan con estos filtros.", + "filterByType": "Filtrar por tipo", + "filterAllTypes": "Todos los tipos", + "filterByStatus": "Filtrar por estado", + "filterAllStatuses": "Todos los estados" + }, + "pagination": { + "range": "{start}–{end} de {total}", + "rangeAssets": "Activos · {start}–{end} de {total}" + }, + "errors": { + "unknown": "Error desconocido", + "requestFailed": "La solicitud falló", + "unavailable": "no disponible", + "apiRequestFailed": "API de {resource} {status}: {error}", + "tokenResource": "Token", + "templateResource": "Plantilla", + "walletResource": "Wallet", + "tokenListRetry": "No pudimos cargar la lista de Tokens en este momento. Actualiza la página para volver a intentarlo.", + "tokenListCreateOrRetry": "No pudimos cargar la lista de Tokens en este momento. Aún puedes crear un Token o volver a intentarlo en breve.", + "unableToLoadTemplates": "No se pudieron cargar las plantillas", + "unableToLoadTokens": "No se pudieron cargar los Tokens", + "unableToLoadSignerWallets": "No se pudieron cargar las Wallets firmantes.", + "mintUnavailable": "Mint no disponible — {reason}", + "burnUnavailable": "Burn no disponible — {reason}", + "assetProfileNotFound": "Perfil de activo no encontrado.", + "assetProfileLoadFailed": "No se pudo cargar el perfil del activo ({status}): {error}", + "tokenDetailsSaveFailed": "No se pudieron guardar los detalles del Token ({status}): {error}", + "assetProfileUpdateFailed": "Se guardaron los detalles del Token, pero la actualización del perfil del activo falló ({status}): {error}. Vuelve a intentarlo.", + "changesSaved": "Cambios guardados.", + "unableToSaveChanges": "No se pudieron guardar los cambios.", + "assetProfilesDisabled": "Los perfiles de activo no están habilitados para este entorno.", + "assetDraftCreateFailed": "No se pudo crear el borrador del activo ({status}): {error}", + "assetDraftCreated": "Borrador de activo creado.", + "unableToCreateAssetDraft": "No se pudo crear el borrador del activo.", + "metadataUriHttp": "La URI de metadatos debe usar http o https.", + "metadataUriValid": "La URI de metadatos debe ser una URL válida.", + "tokenNameRequired": "El nombre del Token es obligatorio.", + "symbolFormat": "El símbolo debe tener entre 1 y 10 caracteres, usando letras, números o puntos.", + "invalidTemplate": "Selección de plantilla no válida.", + "decimalsRange": "Los decimales deben estar entre 0 y 18.", + "createFailed": "Error al crear ({status}): {error}", + "draftCreated": "Borrador {name} creado. Despliégalo on-chain desde la página del Token.", + "unexpected": "Error inesperado", + "symbolRequired": "El símbolo es obligatorio.", + "symbolCharacters": "Usa entre 1 y 10 letras, números o puntos.", + "decimalsWholeNumber": "Ingresa un número entero entre 0 y 18.", + "maxSupplyPositive": "Ingresa un monto mayor que cero, o deja el campo vacío para ilimitado.", + "maxSupplyPrecision": "Usa como máximo {decimals} decimal(es) para coincidir con los decimales de este Token.", + "descriptionRequired": "La descripción es obligatoria.", + "descriptionTooLong": "La descripción debe tener como máximo {max} caracteres.", + "validUrl": "Ingresa una URL válida (https://…).", + "fieldRequired": "{field} es obligatorio.", + "field": "Campo", + "classificationRequired": "Elige una clasificación y un subtipo de activo.", + "assetNameRequired": "El nombre del activo es obligatorio.", + "settingValuesRequired": "Ingresa los valores requeridos para la configuración seleccionada.", + "settingValueRequired": "Obligatorio", + "settingConflict": "Algunas configuraciones seleccionadas no se pueden combinar. Elimina una para continuar.", + "signerRequiredForSettings": "Selecciona una Wallet firmante — es obligatoria para la configuración avanzada que elegiste." + }, + "controlLists": { + "title": "Listas de control", + "controlList": "Lista de control", + "entriesTitle": "Entradas de {label}", + "descriptionWithList": "Entradas de {label} y estado de cuentas congeladas", + "descriptionWithoutList": "Estado de cuentas congeladas", + "entriesCount": "Entradas: {count}", + "showingEntries": "Mostrando las primeras {count} entradas.", + "frozenAccounts": "Cuentas congeladas", + "accountsCount": "Cuentas: {count}", + "showingAccounts": "Mostrando las primeras {count} cuentas.", + "searchPlaceholder": "Buscar {label}…", + "allLabels": "Todas las etiquetas", + "noMatches": "Ninguna entrada coincide con tu búsqueda.", + "filterByLabel": "Filtrar por etiqueta", + "loading": "Cargando entradas…", + "loadError": "No se pudieron cargar las entradas." + }, + "wallet": { + "none": "Ninguna", + "unlabeled": "Wallet sin etiqueta", + "walletId": "ID de Wallet", + "publicKey": "Clave pública", + "copy": "Copiar {label}", + "copied": "Se copió {label}", + "unableToCopy": "No se pudo copiar {label}", + "customAddress": "Dirección personalizada", + "chooseOrPaste": "Elige una Wallet o pega una dirección de Solana", + "clear": "Borrar {label}", + "selectExisting": "Selecciona una Wallet existente", + "filterHint": "Escribe para filtrar las Wallets existentes, usa el menú desplegable o pega cualquier dirección de Solana." + }, + "saveBar": { + "unsaved": "Tienes cambios sin guardar", + "unsavedWithErrors": "Cambios sin guardar — {count} campo{suffix} por revisar", + "discard": "Descartar", + "save": "Guardar cambios", + "saving": "Guardando…" + }, + "confirmation": { + "notNow": "Ahora no" + }, + "modal": { + "close": "Cerrar modal", + "closeConfirmation": "Cerrar modal de confirmación", + "tokenManagementAction": "Acción de gestión del Token" + }, + "signer": { + "label": "Firmante", + "select": "Selecciona una Wallet firmante", + "requiredAuthorityHint": "SDP firmará esta acción con la Wallet de autoridad requerida.", + "selectedWalletHint": "SDP firmará esta transacción con la Wallet seleccionada.", + "defaultSignerHint": "No hay Wallets firmantes disponibles — SDP usará el firmante predeterminado del proyecto.", + "noneAvailable": "No hay Wallets firmantes disponibles." + }, + "header": { + "tokenLogo": "Logo del Token {name}", + "notDeployed": "No desplegado", + "copyTokenAddress": "Copiar dirección del Token", + "tokenId": "ID de Token", + "copyTokenId": "Copiar ID de Token", + "explorer": "Explorador", + "deploy": "Desplegar", + "unpause": "Reanudar" + }, + "create": { + "title": "Crear nuevo borrador de Token", + "closeModal": "Cerrar modal de creación de Token", + "createDraft": "Crear borrador", + "requiredFields": "Los campos marcados con * son obligatorios.", + "required": "(obligatorio)", + "tokenName": "Nombre del Token", + "tokenNamePlaceholder": "p. ej., USD Coin", + "symbol": "Símbolo", + "symbolPlaceholder": "p. ej., USDC", + "decimals": "Decimales", + "decimalsPlaceholder": "p. ej., 6", + "decimalsError": "Ingresa un número entero entre 0 y 18.", + "stablecoinDecimalsHelper": "Stablecoin usa 6 decimales por defecto, pero puedes elegir cualquier valor entre 0 y 18.", + "customDecimalsHelper": "Los Tokens personalizados usan 9 decimales por defecto. Elige cualquier valor entre 0 y 18.", + "tokenizedSecurityDecimalsHelper": "Valor tokenizado usa 8 decimales por defecto, pero puedes elegir cualquier valor entre 0 y 18.", + "decimalsHelper": "Elige cualquier valor entre 0 y 18.", + "back": "Atrás", + "continue": "Continuar", + "mainSigner": "Firmante principal", + "selectSignerWallet": "Selecciona la Wallet firmante", + "mainSignerHint": "Esta Wallet se usará como firmante principal del Token para el despliegue y las acciones posteriores.", + "loadingSignerWallets": "Cargando Wallets firmantes…", + "noControlledWallets": "Aún no hay Wallets controladas disponibles. El Token usará el firmante predeterminado actual.", + "transferControls": "Controles de transferencia", + "transferControlsHint": "Elige cómo debe tratar este Token las direcciones de destino aprobadas o bloqueadas.", + "creating": "Creando...", + "creatingDraft": "Creando borrador de Token.", + "unableToLoadSignerWallets": "No se pudieron cargar las Wallets firmantes.", + "unableToCreateDraft": "No se pudo crear el borrador del Token.", + "draftCreated": "Borrador creado. Despliégalo on-chain desde la página del Token.", + "configureDraft": "Configura el borrador ahora y luego despliégalo on-chain desde la página del Token.", + "chooseTemplate": "Elige una plantilla para crear primero un borrador y luego despliégalo on-chain.", + "stablecoinTemplateName": "Stablecoin", + "tokenizedSecurityTemplateName": "Valor tokenizado", + "customTemplateName": "Token personalizado", + "stablecoinTemplateDescription": "Crea una stablecoin conforme a la normativa, con restricciones de transferencia.", + "tokenizedSecurityTemplateDescription": "Crea un Token de valor conforme a la normativa, con montos de UI escalados y controles principales.", + "customTemplateDescription": "Construye tu propio Token con control total sobre extensiones y parámetros.", + "createStablecoinDraft": "Crear borrador de Stablecoin", + "createTokenizedSecurityDraft": "Crear borrador de valor tokenizado", + "createCustomTokenDraft": "Crear borrador de Token personalizado", + "createTokenDraft": "Crear borrador de Token", + "denylist": "Denylist", + "allowlist": "Allowlist", + "disabled": "Deshabilitado", + "denylistDescription": "Los destinos incluidos en la lista quedan bloqueados antes de poder recibir acciones controladas.", + "allowlistDescription": "Solo los destinos aprobados pueden recibir acciones controladas del Token.", + "disabledDescription": "Este Token no usará una lista de control de transferencias.", + "stablecoinDenylistNote": "Opción predeterminada recomendada para Stablecoins.", + "stablecoinAllowlistNote": "Úsalo cuando las transferencias deban limitarse a un conjunto conocido de Wallets.", + "securityAllowlistNote": "Predeterminado para valores tokenizados.", + "securityDenylistNote": "Úsalo cuando el Token deba permanecer abierto, excepto para las Wallets bloqueadas.", + "customDisabledNote": "Ideal para Tokens personalizados sin restricciones.", + "customAllowlistNote": "Habilita esta opción cuando el Token necesite acceso de transferencia restringido." + }, + "status": { + "draft": "Borrador", + "active": "Activo", + "paused": "Pausado", + "revoked": "Revocado" + }, + "tabs": { + "overview": "Resumen", + "details": "Detalles", + "publicInformation": "Información pública", + "compliance": "Cumplimiento", + "operations": "Operaciones", + "permissions": "Permisos", + "activity": "Actividad" + }, + "activity": { + "title": "Historial de auditoría", + "description": "Todas las acciones de gestión registradas para este activo.", + "filterLabel": "Acción", + "filterAll": "Todas las acciones", + "filterAllStatuses": "Todos los estados", + "filterAllTypes": "Todos los tipos", + "columnAction": "Acción", + "columnActor": "Actor", + "columnActorType": "Tipo", + "columnStatus": "Estado", + "columnTime": "Hora", + "actorWorkflow": "Flujo de trabajo", + "actorApiKey": "Clave de API", + "actorUser": "Miembro del equipo", + "statusSuccess": "Éxito", + "statusFailure": "Fallido", + "empty": "Aún no hay actividad registrada.", + "loading": "Cargando actividad…", + "error": "No se pudo cargar la actividad.", + "recentTitle": "Actividad reciente", + "viewAll": "Ver todo" + }, + "permissions": { + "managedBadge": "Administrado por SDP", + "externalBadge": "Externo", + "externalWarningTitle": "Se detectaron autoridades externas para", + "externalWarningBody": "SDP no puede firmar en nombre de autoridades que estén fuera de custodia, por lo que las acciones relacionadas permanecen no disponibles hasta que se transfieran a una Wallet de custodia de SDP.", + "externalRemediationTarget": "Transfiere estas autoridades a tu Wallet de custodia de SDP:", + "externalRemediationNoWallet": "Crea una Wallet de custodia de SDP y luego transfiere estas autoridades a ella.", + "externalRemediationNote": "El titular actual de la autoridad debe firmar la transferencia desde su propia Wallet — SDP no puede hacerlo.", + "createWallet": "Crear Wallet de custodia" + }, + "workspace": { + "tokenLoadWarning": "Advertencia de carga del Token", + "tokenPaused": "El Token está pausado", + "pausedHint": "Las acciones de mint, burn y transferencia administrativa están deshabilitadas hasta que se reanude el Token.", + "unpauseToken": "Reanudar Token", + "deployToken": "Desplegar Token", + "deployHint": "Esto desplegará el Token on-chain para que las operaciones puedan ejecutarse.", + "cancel": "Cancelar", + "deployNow": "Desplegar ahora", + "runningAction": "Ejecutando acción...", + "tokenListUnavailable": "Lista de Tokens no disponible", + "search": "Buscar", + "createDraft": "Crear borrador", + "addNewToken": "Agregar nuevo Token", + "noTokensMatch": "Ningún activo coincide con tu búsqueda o filtros actuales.", + "tokenLogo": "Logo de {name}", + "type": "Tipo", + "supply": "Suministro", + "created": "Creado", + "manage": "Administrar", + "viewSwitchToList": "Cambiar a vista de lista", + "viewSwitchToGrid": "Cambiar a vista de cuadrícula", + "collapseAll": "Contraer todo", + "expandAll": "Expandir todo", + "manageAsset": "Administrar {name}", + "active": "Activo", + "draft": "Borrador", + "filters": "Filtros", + "filtersTitle": "Filtrar y ordenar", + "filterStatus": "Estado", + "filterTemplate": "Plantilla", + "filterDate": "Creado", + "filterSort": "Ordenar por", + "statusAll": "Todos los estados", + "templateAll": "Todas las plantillas", + "dateAll": "Todo el historial", + "date7d": "Últimos 7 días", + "date30d": "Últimos 30 días", + "date12m": "Últimos 12 meses", + "sortNewest": "Más recientes primero", + "sortOldest": "Más antiguos primero", + "sortNameAsc": "Nombre A–Z", + "sortNameDesc": "Nombre Z–A", + "clearFilters": "Borrar todo", + "noTokensOnPage": "No hay activos en esta página.", + "loadingAssets": "Cargando activos…" + }, + "list": { + "toggleDetails": "Alternar detalles de {name}", + "closeDetails": "Cerrar detalles de {name}", + "close": "Cerrar", + "assetsCount": "Activos · {count}", + "manageThisAsset": "Administrar este activo", + "viewOnExplorer": "Ver en el explorador", + "copyMintAddress": "Copiar dirección de mint", + "copied": "Copiado", + "unableToCopy": "No se pudo copiar la dirección", + "type": "Tipo", + "decimals": "Decimales", + "supply": "Suministro", + "maxSupply": "Suministro máximo", + "unlimited": "Ilimitado", + "transfers": "Transferencias", + "restricted": "Restringido", + "unrestricted": "No restringido", + "website": "Sitio web", + "mintAddress": "Dirección de mint", + "created": "Creado", + "yes": "Sí", + "no": "No" + }, + "management": { + "tokenAmountDescription": "Unidades de Token (por ejemplo, 1 o 1.5). Se convertirán a unidades base usando los decimales de este Token.", + "untitledToken": "Token sin título", + "allowlist": "Allowlist", + "denylist": "Denylist", + "allowlistDescription": "Administra las direcciones de destino aprobadas para este Token.", + "denylistDescription": "Administra las direcciones de destino bloqueadas para este Token.", + "allowlistSummaryDescription": "Entradas de la allowlist y estado de cuentas congeladas", + "denylistSummaryDescription": "Entradas de la denylist y estado de cuentas congeladas", + "allowlistEntries": "Entradas de la Allowlist", + "denylistEntries": "Entradas de la Denylist", + "addAllowlistEntry": "Agregar entrada a la allowlist", + "addDenylistEntry": "Agregar entrada a la denylist", + "removeEntry": "Quitar entrada", + "noAllowlistEntries": "Aún no hay entradas en la allowlist.", + "noDenylistEntries": "Aún no hay entradas en la denylist.", + "allowlistAddressRequired": "La dirección de la allowlist es obligatoria.", + "denylistAddressRequired": "La dirección de la denylist es obligatoria.", + "allowlistExtensionHelper": "Los destinos de mint y de transferencias controladas deben estar en la allowlist del Token.", + "denylistExtensionHelper": "Las direcciones incluidas en la denylist quedan bloqueadas para operaciones de mint y transferencias controladas.", + "denylistFreezeHint": "¿Necesitas restringir una Wallet antes de que tenga una cuenta de Token? Agrégala primero a la denylist.", + "defaultAccountState": "Default Account State", + "defaultAccountStateHelper": "Estado predeterminado para las cuentas de Token recién creadas.", + "transferFee": "Transfer Fee", + "transferFeeHelper": "Configuración de tarifas para las transferencias de Tokens.", + "scaledUiAmount": "Scaled UI Amount", + "scaledUiAmountHelper": "Controles del multiplicador de suministro en la UI.", + "transferHook": "Transfer Hook", + "transferHookHelper": "Hook de programa personalizado para la lógica de transferencia.", + "interestBearing": "Interest Bearing", + "interestBearingHelper": "Actualizaciones de saldo basadas en una tasa de interés.", + "nonTransferable": "Non-transferable", + "nonTransferableHelper": "Deshabilita las transferencias estándar entre cuentas.", + "template": "Plantilla", + "templateHelper": "Plantilla base aplicada a este Token.", + "mintable": "Permite mint", + "mintableHelper": "Permite operaciones de mint después del despliegue.", + "freezable": "Congelable", + "freezableHelper": "Permite los controles para congelar o descongelar cuentas.", + "configured": "Configurado", + "enabled": "Habilitado", + "disabled": "Deshabilitado", + "overview": "Resumen", + "permissions": "Permisos", + "permissionsDescription": "Claves on-chain que controlan el mint, el congelamiento y los metadatos de este Token.", + "extensions": "Extensiones", + "extensionsDescription": "Se configuran en la creación y son de solo lectura después del despliegue.", + "edit": "Editar", + "compliance": "Cumplimiento", + "metadata": "Metadatos", + "operations": "Operaciones", + "mintTokens": "Hacer mint de Tokens", + "mintHelper": "Crea nuevo suministro en una Wallet o cuenta de Token de destino.", + "mint": "Mint", + "burnTokens": "Hacer burn de Tokens", + "burnHelper": "Elimina suministro de una Wallet o cuenta de Token de origen.", + "burn": "Burn", + "lockSupplyTitle": "Bloquear el suministro on-chain", + "lockSupplyHelper": "Haz mint del resto hasta alcanzar tu suministro máximo y luego revoca de forma permanente la Mint Authority.", + "lockSupplyAction": "Bloquear", + "lockSupplyDescription": "Esto hace mint del suministro restante y luego revoca la Mint Authority, convirtiendo tu suministro máximo en un límite real on-chain en lugar de un límite de política de SDP.", + "lockSupplyDescriptionRevokeOnly": "El suministro ya alcanzó tu máximo. Esto revoca la Mint Authority y hace que el total actual sea permanente on-chain.", + "lockSupplyCurrentSupply": "Suministro actual", + "lockSupplyMaxSupply": "Suministro máximo", + "lockSupplyWillMint": "Se hará mint ahora", + "lockSupplyDestination": "Destino", + "lockSupplyDestinationHint": "Wallet o cuenta de Token que recibe el suministro recién creado mediante el mint.", + "lockSupplyImpact": "Nunca más se podrá crear {symbol}, ni siquiera por parte de SDP. Esta acción no se puede deshacer.", + "lockSupplyConfirm": "Bloquear suministro", + "lockSupplyRetryRevoke": "Reintentar revocación", + "lockSupplyPartialTitle": "Completado parcialmente", + "lockSupplyPartialBody": "El suministro se generó mediante mint, pero la Mint Authority no se revocó, por lo que sigue activa. Reintenta para finalizar: el resto no se volverá a generar mediante mint.", + "lockSupplyMintLabel": "Hacer mint del suministro restante", + "lockSupplyRevokeLabel": "Revocar la Mint Authority", + "lockSupplyMinting": "Haciendo mint de {amount}…", + "lockSupplyMinted": "Se hizo mint de {amount}. A continuación, se revocará la Mint Authority…", + "lockSupplyRevoking": "Revocando la Mint Authority…", + "lockSupplyLocked": "El suministro ahora está bloqueado on-chain.", + "lockSupplyNoMaxSupply": "Define un suministro máximo antes de bloquear el suministro on-chain.", + "lockSupplyAlreadyLocked": "El suministro ya está bloqueado: la Mint Authority fue revocada.", + "lockSupplyAmountUnavailable": "No se pudo calcular el suministro restante para este Token.", + "lockSupplyDestinationRequired": "Ingresa un destino para el suministro recién generado mediante mint.", + "unableToLoadData": "No se pudieron cargar los datos de administración del Token.", + "supportingDataRequestFailed": "La solicitud de datos complementarios del Token falló ({status}).", + "supportingDataEmpty": "La respuesta de datos complementarios del Token estaba vacía.", + "authorityWalletRequestFailed": "La solicitud de la Wallet de autoridad falló ({status}).", + "unableToLoadSignerWallets": "No se pudieron cargar las Wallets firmantes.", + "loadingSignerWallets": "Cargando Wallets firmantes…", + "onlyAdminsCanEditAuthorities": "Solo los administradores pueden editar las autoridades del Token.", + "deployToken": "Desplegar Token", + "deployHelper": "Despliega este Token on-chain antes de ejecutar otras operaciones de fondos.", + "deployConfirmationTitle": "¿Desplegar Token?", + "deployConfirmationDescription": "Esto enviará la transacción de despliegue on-chain.", + "deployNow": "Desplegar ahora", + "copied": "Copiado", + "unableToCopy": "No se pudo copiar", + "tokenNameRequired": "El nombre del Token es obligatorio.", + "updateToken": "Actualizar Token", + "submittingDeploy": "Enviando la transacción de despliegue...", + "deployFinalized": "Transacción de despliegue finalizada.", + "refreshSupply": "Actualizar suministro", + "mintDetailsRequired": "El destino y el monto del mint son obligatorios.", + "amountPositive": "El monto debe ser un número positivo.", + "mintConfirmationTitle": "¿Hacer mint de Tokens?", + "mintConfirmationDescription": "Esto enviará una transacción de mint on-chain.", + "mintNow": "Hacer mint ahora", + "submittingMint": "Enviando la transacción de mint...", + "mintFinalized": "Transacción de mint finalizada.", + "burnDetailsRequired": "El origen y el monto del burn son obligatorios.", + "burnConfirmationTitle": "¿Hacer burn de Tokens?", + "burnConfirmationDescription": "Esto enviará una transacción de burn on-chain.", + "burnNow": "Hacer burn ahora", + "submittingBurn": "Enviando la transacción de burn...", + "burnFinalized": "Transacción de burn finalizada.", + "seizeDetailsRequired": "El origen, el destino y el monto de la transferencia forzada son obligatorios.", + "seizeConfirmationTitle": "¿Forzar transferencia?", + "seizeConfirmationDescription": "Esto enviará una transacción de transferencia forzada (incautación) on-chain.", + "transferNow": "Forzar transferencia ahora", + "submittingForceTransfer": "Enviando la transacción de transferencia forzada...", + "forceTransferFinalized": "Transacción de transferencia forzada finalizada.", + "forceBurnDetailsRequired": "El origen y el monto del burn forzado son obligatorios.", + "forceBurnConfirmationTitle": "¿Forzar el burn de Tokens?", + "forceBurnConfirmationDescription": "Esto enviará una transacción de burn forzado on-chain.", + "forceBurnNow": "Forzar burn ahora", + "submittingForceBurn": "Enviando la transacción de burn forzado...", + "forceBurnFinalized": "Transacción de burn forzado finalizada.", + "updateAuthority": "Actualizar autoridad", + "updateAuthorityLabel": "Actualizar {authority}", + "updatingAuthority": "Actualizando {authority}...", + "authorityUpdated": "{authority} actualizada.", + "authorityConfirmationTitle": "¿Actualizar autoridad?", + "authorityConfirmationDescription": "Esto enviará una transacción de actualización de autoridad on-chain.", + "updateNow": "Actualizar ahora", + "submittingAuthority": "Enviando la transacción de actualización de autoridad...", + "authorityFinalized": "Actualización de autoridad finalizada.", + "pauseToken": "Pausar Token", + "unpauseToken": "Reanudar Token", + "pauseConfirmationTitle": "¿Pausar Token?", + "unpauseConfirmationTitle": "¿Reanudar Token?", + "pauseConfirmationDescription": "Esto enviará una transacción de pausa on-chain.", + "unpauseConfirmationDescription": "Esto enviará una transacción de reanudación on-chain.", + "pauseNow": "Pausar ahora", + "unpauseNow": "Reanudar ahora", + "submittingPause": "Enviando la transacción de pausa...", + "submittingUnpause": "Enviando la transacción de reanudación...", + "pauseFinalized": "Transacción de pausa finalizada.", + "unpauseFinalized": "Transacción de reanudación finalizada.", + "accountAddressRequired": "La dirección de la cuenta es obligatoria.", + "unfreezeAccount": "Descongelar cuenta", + "unfreezeConfirmationTitle": "¿Descongelar cuenta?", + "unfreezeConfirmationDescription": "Esto enviará una transacción de descongelamiento on-chain.", + "unfreezeNow": "Descongelar ahora", + "submittingUnfreeze": "Enviando la transacción de descongelamiento...", + "unfreezeFinalized": "Transacción de descongelamiento finalizada.", + "freezeAccount": "Congelar cuenta", + "freezeConfirmationTitle": "¿Congelar cuenta?", + "freezeConfirmationDescription": "Esto enviará una transacción de congelamiento on-chain.", + "freezeNow": "Congelar ahora", + "submittingFreeze": "Enviando la transacción de congelamiento...", + "freezeFinalized": "Transacción de congelamiento finalizada.", + "removeAllowlistEntry": "Quitar entrada de la allowlist", + "tokenIdCopied": "ID del Token copiado", + "loadingAuthorityWalletAccess": "Cargando el acceso de la Wallet de autoridad…", + "loadingComplianceControls": "Cargando los controles de cumplimiento…", + "deploySignerHint": "Las tarifas de transacción y de cuenta se pagan desde la Wallet firmante.", + "deployWithWallet": "Desplegar con Wallet", + "koraUnavailable": "El patrocinio de Kora no está disponible en este momento.", + "deployWithKora": "Desplegar con Kora", + "tokenizationEngineTitle": "Motor de tokenización", + "tokenizationEngineHint": "Elige qué motor despliega y administra este Token on-chain.", + "engineVulcanForgeName": "Vulcan Forge", + "engineVulcanForgeDescription": "Despliega on-chain y tokeniza en Vulcan Forge, con registro e indexación integrados.", + "engineMosaicName": "SDP con Mosaic", + "engineMosaicDescription": "Despliega con el motor Mosaic integrado de SDP en Token-2022.", + "comingSoon": "Próximamente", + "stepProgress": "Paso {current} de {total}", + "vulcanForgeOnboardTitle": "Incorporar el Token a Vulcan Forge", + "vulcanForgeOnboardDescription": "AlphaLedger mantiene una réplica offline registrada para indexación y reportes.", + "engineStepLabel": "Motor", + "deployStepLabel": "Despliegue", + "destinationNotAllowlisted": "El destino no está en la allowlist de este Token.", + "destinationDenylisted": "El destino está en la denylist de este Token.", + "actionPaused": "El Token está pausado. Reanúdalo para {action}.", + "actionRequiresActive": "El Token debe estar activo para {action}.", + "actionRevoked": "El Token fue revocado y ya no puede {action}.", + "forceTransfer": "forzar la transferencia", + "forceBurn": "forzar el burn", + "mintingDisabled": "El mint está deshabilitado para este Token.", + "noMintAuthorityConfigured": "No hay ninguna Mint Authority configurada.", + "maximumSupplyReached": "Ya se alcanzó el suministro máximo.", + "supplyZero": "El suministro es cero.", + "noPermanentDelegateAuthority": "No hay ninguna Permanent Delegate Authority configurada.", + "noSupplyHeld": "Actualmente no se posee suministro.", + "revokedTokensCannotPause": "Los Tokens revocados no se pueden pausar ni reanudar.", + "pauseRequiresActiveToken": "El Token debe estar desplegado y activo antes de que los controles de pausa estén disponibles.", + "noPauseAuthorityConfigured": "No hay ninguna Pause Authority configurada. Establece primero una autoridad pausable o una Mint Authority.", + "freezingDisabled": "El congelamiento está deshabilitado para este Token.", + "noFreezeAuthorityConfigured": "No hay ninguna Freeze Authority configurada.", + "unknownError": "Error desconocido", + "unknown": "desconocido", + "ok": "ok", + "executionRouteFailed": "La ruta de ejecución falló ({status})", + "actionFailed": "{action} falló ({status}): {error}", + "actionSucceeded": "{action} se completó correctamente ({status})", + "requestFailed": "La solicitud falló", + "mintAuthorityHelper": "Puede hacer mint de nuevos Tokens.", + "freezeAuthorityHelper": "Puede congelar y descongelar cuentas de Token.", + "metadataAuthorityHelper": "Puede actualizar los metadatos del Token.", + "permanentDelegateHelper": "Puede realizar operaciones delegadas de transferencia o burn.", + "noControlledWalletsAvailable": "No hay Wallets controladas disponibles para firmar esta acción.", + "noSignerConfigured": "No hay ningún firmante configurado para esta acción.", + "requiredSignerNotControlled": "El firmante requerido no es una de tus Wallets controladas.", + "mintAuthorityNotControlled": "Mint Authority no es una de tus Wallets controladas.", + "permanentDelegateNotControlled": "Permanent Delegate Authority no es una de tus Wallets controladas.", + "authority": "autoridad", + "noAuthorityConfigured": "No hay {authority} configurada.", + "authorityNotControlled": "{authority} no es una de tus Wallets controladas.", + "freezeAuthorityNotControlled": "Freeze Authority no es una de tus Wallets controladas.", + "pauseAuthorityNotControlled": "Pause Authority no es una de tus Wallets controladas.", + "validMintAmount": "Ingresa un monto de mint válido para este Token.", + "mintAmountPositive": "El monto de mint debe ser mayor que cero.", + "mintAmountExceedsSupplyCap": "El monto de mint supera el límite de suministro restante de {amount} {symbol}.", + "validBurnAmount": "Ingresa un monto de burn válido para este Token.", + "burnAmountPositive": "El monto de burn debe ser mayor que cero.", + "burnAmountExceedsSupply": "El monto de burn supera el suministro actual de {amount} {symbol}.", + "standardBurnSignerOnly": "El burn estándar solo funciona desde la Wallet firmante seleccionada. Usa Forzar burn para una Wallet diferente.", + "selectedSignerDoesNotHoldToken": "La Wallet firmante seleccionada actualmente no posee este Token.", + "selectedWalletOnlyShows": "La Wallet seleccionada solo muestra {amount} {symbol}.", + "destinationMustDiffer": "El destino debe ser diferente del origen.", + "validTransferAmount": "Ingresa un monto de transferencia válido para este Token.", + "transferAmountPositive": "El monto de transferencia debe ser mayor que cero.", + "selectedSourceDoesNotHoldToken": "La Wallet de origen seleccionada actualmente no posee este Token.", + "forceBurnAmountPositive": "El monto del burn forzado debe ser mayor que cero.", + "forceBurnAmountExceedsSupply": "El monto del burn forzado supera el suministro actual de {amount} {symbol}.", + "submittingAction": "Enviando {action}...", + "transactionFinalized": "Transacción finalizada correctamente.", + "transactionFailed": "La transacción falló.", + "sendTransaction": "¿Enviar transacción?", + "sendTransactionDescription": "Esto enviará una transacción on-chain. ¿Deseas continuar?", + "goAhead": "Continuar", + "token": "Token" + }, + "forms": { + "saveMetadata": "Guardar metadatos", + "updateMetadata": "Actualizar metadatos", + "updateMetadataDescription": "Edita los metadatos del Token.", + "name": "Nombre", + "enterTokenName": "Ingresa un nombre para el Token.", + "description": "Descripción", + "uri": "URI", + "imageUrl": "URL de la imagen", + "mintDescription": "Haz mint hacia una Wallet o cuenta de Token de destino.", + "destination": "Destino", + "enterSolanaAddress": "Ingresa una dirección de Solana válida.", + "destinationPlaceholder": "Wallet o cuenta de Token de destino", + "amount": "Monto", + "memo": "Memo", + "burnDescription": "Haz burn desde una Wallet o cuenta de Token de origen.", + "source": "Origen", + "sourcePlaceholder": "Wallet firmante o su cuenta de Token", + "sourceWalletPlaceholder": "Wallet o cuenta de Token de origen", + "forceTransferDescription": "Transferencia administrativa forzada (incautación) entre cuentas.", + "forceBurnDescription": "Burn forzado administrativo desde la cuenta de origen.", + "mintAuthority": "Mint Authority", + "freezeAuthority": "Freeze Authority", + "permanentDelegate": "Permanent delegate", + "metadataAuthority": "Metadata Authority", + "updateAuthority": "Actualizar autoridad", + "updateAuthorityDescription": "Rota o elimina las autoridades del Token.", + "role": "Rol", + "currentAuthorityOptional": "Autoridad actual (opcional)", + "newAuthorityEmptyToRemove": "Nueva autoridad (vacío para eliminar)", + "pauseControls": "Controles de pausa", + "pauseControlsDescription": "Pausa o reanuda las transferencias de todo el Token.", + "alreadyPaused": "El Token ya está pausado.", + "notPaused": "El Token no está pausado.", + "freezeControls": "Controles de congelamiento", + "freezeControlsDescription": "Congela o descongela las tenencias de Token de una Wallet para este mint.", + "walletAddress": "Dirección de la Wallet", + "enterWalletAddress": "Ingresa la dirección de la Wallet. SDP derivará automáticamente la cuenta de Token asociada para este mint.", + "walletAddressPlaceholder": "Dirección de la Wallet que posee este Token", + "walletAddressInstruction": "Ingresa la dirección de la Wallet que posee este Token. SDP deriva automáticamente la cuenta de Token asociada para este mint.", + "freezeReason": "Motivo (solo para congelar)", + "controlListDescription": "Administra las direcciones de destino aprobadas para este Token.", + "address": "Dirección", + "label": "Etiqueta", + "enterLabel": "Ingresa una etiqueta o deja esto en blanco.", + "noLabel": "Sin etiqueta", + "removeEntry": "Quitar entrada" + }, + "authority": { + "resolvedAutomatically": "Se resuelve automáticamente a partir del estado del Token", + "closeModal": "Cerrar modal de autoridad", + "save": "Guardar autoridad", + "current": "Autoridad actual", + "whatThisMeans": "Qué significa esto", + "confirmNone": "Sí, establecer en Ninguna", + "new": "Nueva autoridad", + "selectWallet": "Selecciona una Wallet controlada", + "custom": "Autoridad personalizada", + "solanaAddress": "Dirección de Solana", + "noneWalletWarning": "Elegir Ninguna borrará esta autoridad. Confirmarás este cambio antes de enviarlo.", + "noneDescription": "Esta autoridad se borrará si guardas este cambio.", + "controlledWalletHint": "Las Wallets controladas son los destinos recomendados para la autoridad.", + "useCustom": "Usar dirección personalizada", + "chooseWallet": "Elegir Wallet controlada", + "solanaAddressOrNone": "Dirección de Solana o deja esto vacío para establecer Ninguna", + "enterAddressOrNone": "Ingresa una dirección de Solana válida o deja esto en blanco para establecer la autoridad en Ninguna.", + "noWalletsHint": "Todavía no hay Wallets controladas disponibles. Ingresa una dirección manualmente o déjala en blanco para establecer la autoridad en Ninguna.", + "noneFieldWarning": "Establecer este campo en Ninguna borrará la autoridad. Confirmarás este cambio antes de enviarlo.", + "mintNoneTitle": "¿Establecer la Mint Authority en Ninguna?", + "mintNoneDescription": "Esto borrará la Mint Authority del Token.", + "mintNoneImpact": "Ninguna Wallet podrá hacer mint de suministro adicional después de este cambio.", + "freezeNoneTitle": "¿Establecer la Freeze Authority en Ninguna?", + "freezeNoneDescription": "Esto borrará la Freeze Authority del Token.", + "freezeNoneImpact": "Las cuentas de Token ya no podrán congelarse ni descongelarse después de este cambio.", + "delegateNoneTitle": "¿Establecer la Permanent Delegate Authority en Ninguna?", + "delegateNoneDescription": "Esto borrará la Permanent Delegate Authority del Token.", + "delegateNoneImpact": "Las acciones administrativas de transferencia y burn delegadas ya no estarán disponibles después de este cambio.", + "metadataNoneTitle": "¿Establecer la Metadata Authority en Ninguna?", + "metadataNoneDescription": "Esto borrará la Metadata Authority del Token.", + "metadataNoneImpact": "Las actualizaciones de metadatos ya no estarán disponibles a través de esta autoridad después de este cambio." + }, + "wizard": { + "stepOf": "Paso {current} de {total}", + "creatingDraft": "Creando el borrador del activo…", + "draftCreated": "Borrador del activo creado.", + "failedToCreate": "No se pudo crear el borrador.", + "creating": "Creando…", + "reviewAndFinish": "Revisar y finalizar", + "reviewDescription": "Revisa todos los detalles a continuación. Puedes editar cualquier sección antes de crear tu borrador." + }, + "confirmDraft": { + "ariaLabel": "Crear borrador del activo", + "title": "¿Crear este borrador de activo?", + "descriptionStart": "Esto crea un borrador", + "of": "de", + "descriptionEnd": ". Puedes seguir editándolo y publicarlo cuando quieras." + }, + "summary": { + "title": "Resumen", + "assetCategory": "Categoría del activo", + "assetType": "Tipo de activo", + "peggedTo": "Vinculado a", + "accessControl": "Control de acceso", + "transferRestrictions": "Restricciones de transferencia", + "investorReporting": "Reportes para inversionistas", + "enabled": "Habilitado", + "lastUpdated": "Última actualización", + "resolveBeforeCreating": "Resolver antes de crear", + "readyToCreate": "Todo listo para crear un borrador", + "readyDescription": "Puedes revisar, editar y publicar cuando quieras.", + "privateByDefault": "Privado por defecto", + "privateDescription": "Los detalles que proporcionas son privados y solo se usan para configurar tu activo." + }, + "classificationRail": { + "title": "Cómo funciona esto", + "assetProfile": "Perfil del activo", + "assetProfileDescription": "Tú seleccionas la categoría y el tipo. SDP almacena los metadatos canónicos de tu emisión.", + "issuanceMetadata": "Metadatos de la emisión", + "issuanceMetadataDescription": "Incluye campos de activo, cumplimiento, cadena y personalizados (cliente/integración).", + "publicProjection": "Proyección pública", + "publicProjectionDescription": "SDP proyecta un subconjunto público seguro hacia los metadatos del Token.", + "tokenMetadataUri": "URI de metadatos del Token", + "tokenMetadataUriDescription": "SDP aloja la URI predeterminada que devuelve solo los metadatos públicos.", + "privateDescription": "Los metadatos de cumplimiento y los personalizados permanecen privados a menos que se incluyan explícitamente en la proyección pública de metadatos." + }, + "assetProfileForm": { + "fixHighlightedFields": "Corrige los campos resaltados antes de guardar." + }, + "templates": { + "stablecoinName": "Stablecoin", + "stablecoinDescription": "Stablecoins respaldadas en USD con controles de cumplimiento.", + "stablecoinHelper": "Ideal para activos vinculados a moneda fiduciaria con controles de transferencia y soporte de congelamiento administrativo.", + "tokenizedSecurityName": "Valor tokenizado", + "tokenizedSecurityDescription": "Activos regulados con allowlist predeterminada.", + "tokenizedSecurityHelper": "Diseñado para instrumentos regulados en los que los controles de participantes son obligatorios.", + "customName": "Personalizado", + "customDescription": "Configuración de Token-2022 totalmente personalizable.", + "customHelper": "Comienza desde un perfil en blanco y ajusta la configuración de emisión para requisitos avanzados." + }, + "overview": { + "title": "Resumen del Token", + "tokenAddress": "Dirección del Token", + "mintAuthority": "Mint Authority", + "supply": "Suministro", + "template": "Plantilla", + "totalSupply": "Suministro total", + "readyForDeploy": "Listo para desplegar", + "readyForDeployDescription": "Este activo está listo para desplegarse — continúa en la pestaña Operaciones.", + "mintAddress": "Dirección de mint", + "notDeployedYet": "Aún no desplegado", + "noDescription": "Aún no hay descripción — agrega una en la pestaña Detalles.", + "authoritiesControlled": "Autoridades administradas", + "authoritiesIncompleteTooltip": "No todas las autoridades están administradas por SDP, por lo que algunas acciones no se pueden firmar desde el dashboard.", + "authoritiesIncompleteLink": "Revisar en Permisos", + "authorities": "Autoridades", + "control": "Control", + "signerWallet": "Wallet firmante", + "signerDefault": "Predeterminado del proyecto", + "signerDefaultHint": "Se elige en el momento de la firma", + "signerUnavailable": "Wallet no disponible", + "deployed": "Desplegado", + "draftCreated": "Borrador creado", + "createdTooltip": "Cuándo se creó el borrador", + "deployedTooltip": "Cuándo se desplegó el Token on-chain", + "sdpManaged": "Administrado por SDP", + "accessAllowlist": "Allowlist", + "accessBlocklist": "Blocklist", + "authorityExternal": "Mantenida externamente", + "authorityExternalHint": "SDP no puede firmar por ella, por lo que las acciones relacionadas permanecen no disponibles.", + "authorityNotSet": "No configurada" + }, + "operations": { + "deployHelper": "Despliega este Token on-chain antes de ejecutar otras operaciones de fondos.", + "subtitle": "Realiza cambios en el suministro del Token y revisa la actividad reciente." + }, + "taxonomy": { + "stablecoin": "Stablecoin", + "stablecoinDescription": "Activos diseñados para mantener un valor estable, generalmente respaldados por moneda fiduciaria u otros activos líquidos.", + "fiatBacked": "Respaldado por fiat", + "fiatBackedDescription": "Respaldado 1:1 por reservas en moneda fiduciaria mantenidas en instituciones financieras reguladas.", + "cryptoBacked": "Respaldado por cripto", + "cryptoBackedDescription": "Garantizado por criptoactivos mantenidos en custodia para conservar la paridad.", + "tokenizedSecurity": "Valor tokenizado", + "tokenizedSecurityDescription": "Instrumentos financieros regulados o representaciones digitales de valores.", + "equity": "Acciones", + "equityDescription": "Acciones tokenizadas o participaciones similares al capital en una empresa.", + "debt": "Deuda / Bono", + "debtDescription": "Bonos, pagarés u otros instrumentos de deuda.", + "fund": "Fondo / ETF", + "fundDescription": "Participaciones de fondos o acciones de fondos cotizados (ETF).", + "generic": "Activo digital que no es un valor", + "genericDescription": "Otros activos tokenizados que no encajan en las categorías anteriores.", + "commodities": "Materias primas", + "commoditiesDescription": "Derechos sobre materias primas físicas o recursos naturales.", + "realEstate": "Bienes raíces", + "realEstateDescription": "Participaciones o propiedades inmobiliarias tokenizadas.", + "collectibles": "Coleccionables", + "collectiblesDescription": "Activos coleccionables únicos o de edición limitada." + }, + "config": { + "advanced": "Avanzado", + "advancedCapacitiesDescription": "Las capacidades recomendadas se preseleccionan según el perfil del activo.", + "usd": "USD", + "eur": "EUR", + "gbp": "GBP", + "jpy": "JPY", + "sgd": "SGD", + "unitedStates": "Estados Unidos", + "europeanUnion": "Unión Europea", + "unitedKingdom": "Reino Unido", + "singapore": "Singapur", + "other": "Otro", + "regD": "Reg D", + "regS": "Reg S", + "regA": "Reg A+", + "publicOffering": "Oferta pública", + "commodityBacked": "Respaldado por materias primas", + "algorithmic": "Algorítmico", + "financialDetails": "Detalles financieros", + "financialDetailsDescription": "Atributos financieros clave del activo.", + "collateralOracleDetails": "Colateral y oráculo", + "collateralOracleDetailsDescription": "Colateral on-chain que respalda este Token y la fuente de precios utilizada para valorarlo.", + "issuerName": "Nombre del emisor", + "issuerNamePlaceholder": "p. ej., Acme Financial Inc.", + "backingType": "Tipo de respaldo", + "currency": "Moneda", + "selectField": "Selecciona {field}", + "searchCurrencies": "Buscar monedas", + "pegTarget": "Paridad u objetivo", + "pegTargetPlaceholder": "1.00 USD", + "reserveAsset": "Activo de reserva", + "reserveAssetPlaceholder": "p. ej., efectivo y bonos del Tesoro de EE. UU.", + "reserveAssetPlaceholderCrypto": "p. ej., SOL, wBTC, ETH, SOL en staking", + "reserveCustodian": "Custodio de la reserva", + "reserveCustodianPlaceholder": "p. ej., banco o custodio regulado", + "reserveCustodianPlaceholderCrypto": "p. ej., bóveda on-chain o dirección de programa", + "collateralizationRatio": "Ratio de colateralización", + "collateralizationRatioPlaceholder": "p. ej., 150", + "collateralizationRatioHelp": "Valor de colateral objetivo en relación con los Tokens emitidos, expresado como porcentaje.", + "oracleProvider": "Oráculo de precios", + "oracleProviderPlaceholder": "p. ej., Pyth, Switchboard", + "minCollateralRatio": "Ratio mínimo de colateral", + "minCollateralRatioPlaceholder": "p. ej., 120", + "minCollateralRatioHelp": "Ratio de colateral más bajo que puede alcanzar una posición antes de ser liquidada, expresado como porcentaje.", + "redemption": "Redención", + "redemptionHelp": "Los titulares pueden redimir sus Tokens por las reservas subyacentes.", + "securityDetails": "Detalles del valor", + "securityDetailsDescription": "Información del emisor y de la oferta.", + "equityDetails": "Términos de las acciones", + "equityDetailsDescription": "Clase de acción y derechos de los titulares.", + "debtDetails": "Términos de deuda", + "debtDetailsDescription": "Términos del instrumento de deuda.", + "fundDetails": "Términos del fondo", + "fundDetailsDescription": "Estrategia y estructura de comisiones.", + "shareClass": "Clase de acción", + "shareClassPlaceholder": "p. ej., Clase A común", + "votingRights": "Derechos de voto", + "votingRightsHelp": "Los titulares de esta clase tienen derechos de voto.", + "couponRate": "Tasa de cupón", + "couponRatePlaceholder": "p. ej., 5.25% anual", + "maturityDate": "Fecha de vencimiento", + "maturityDatePlaceholder": "AAAA-MM-DD", + "seniority": "Prelación", + "seniorSecured": "Senior garantizada", + "seniorUnsecured": "Senior no garantizada", + "subordinated": "Subordinada", + "mezzanine": "Mezzanine", + "unsecured": "No garantizada", + "fundStrategy": "Estrategia", + "strategyMoneyMarket": "Mercado monetario", + "strategyFixedIncome": "Renta fija", + "strategyEquity": "Renta variable", + "strategyMultiAsset": "Multiactivo", + "managementFee": "Comisión de gestión", + "managementFeePlaceholder": "p. ej., 0.75% anual", + "netAssetValue": "Valor neto de los activos (NAV)", + "netAssetValuePlaceholder": "p. ej., 100.00 USD por acción", + "jurisdiction": "Jurisdicción", + "offeringType": "Tipo de oferta", + "categoryAssetDetails": "Detalles del activo", + "categoryAssetDetailsDescription": "Qué respalda o representa este activo.", + "realEstateDetails": "Detalles de la propiedad", + "realEstateDetailsDescription": "Tipo de propiedad y ubicación.", + "propertyType": "Tipo de propiedad", + "propertyResidential": "Residencial", + "propertyCommercial": "Comercial", + "propertyIndustrial": "Industrial", + "propertyLand": "Terreno", + "propertyMixedUse": "Uso mixto", + "propertyLocation": "Ubicación", + "propertyLocationPlaceholder": "p. ej., Ciudad de México, CDMX, México", + "underlyingAsset": "Activo subyacente", + "underlyingAssetPlaceholder": "p. ej., oro, plata, petróleo crudo", + "underlyingAssetPlaceholderCollectible": "p. ej., cartas coleccionables, obras de arte, relojes", + "custodian": "Custodio", + "custodianPlaceholder": "p. ej., Acme Custody", + "custodianPlaceholderCollectible": "p. ej., bóveda o socio de autenticación", + "custodianPlaceholderRealEstate": "p. ej., SPV o titular del título", + "allowList": "Allowlist", + "blockList": "Blocklist", + "kyc": "Titulares verificados", + "kycExpert": "KYC", + "kycDescription": "Exige verificación de identidad antes de que un inversionista pueda mantener o transferir este activo.", + "kycDescriptionExpert": "Exige verificación de identidad antes de que una Wallet pueda mantener o transferir Tokens.", + "restrictTradingHours": "Restringir horario de negociación", + "restrictTradingHoursDescription": "Permite transferencias solo en los días y horarios establecidos.", + "restrictTradingHoursDescriptionExpert": "Limita las transferencias de Tokens a días y franjas horarias específicas.", + "freezeTransfers": "Congelar transferencias", + "freezeTransfersDescription": "Congela Tokens en respuesta a eventos de cumplimiento o investigaciones.", + "pauseTransfers": "Pausar todas las transferencias", + "pauseTransfersDescription": "Detiene de inmediato todas las transferencias de este Token y permite reanudarlas después. Afecta a todos los titulares.", + "freezeAccounts": "Freeze Authority", + "freezeAccountsDescription": "Congela y descongela la cuenta de Token de un titular a la vez.", + "issueRetireControls": "Controles de suministro", + "issueRetireControlsExpert": "Controles de mint y burn", + "issueRetireControlsDescription": "Controla quién puede emitir nuevas unidades o retirar las existentes.", + "issueRetireControlsDescriptionExpert": "Controla quién puede hacer mint de nuevos Tokens o burn del suministro existente.", + "redemptionApprovals": "Aprobaciones de redención", + "redemptionApprovalsDescription": "Exige aprobación antes de que un inversionista pueda redimir sus tenencias.", + "redemptionApprovalsDescriptionExpert": "Exige aprobación antes de que los Tokens se canjeen por reservas.", + "investorReporting": "Reportes para inversionistas", + "investorReportingDescription": "Comparte reportes periódicos de tenencias y actividad con los inversionistas.", + "transferApprovals": "Aprobaciones de transferencia", + "transferApprovalsDescription": "Exige aprobación antes de que una transferencia pueda completarse.", + "capacityConfig": { + "configure": "Configurar", + "notConfigured": "Aún no configurado", + "editTitle": "Configurar {policy}", + "cancel": "Cancelar", + "save": "Guardar", + "tradingHours": { + "scheduleLabel": "Horario de negociación", + "scheduleAlways": "24/7", + "scheduleMarket": "Horario de mercado", + "scheduleCustom": "Personalizado", + "daysLabel": "Días habilitados", + "opensLabel": "Abre", + "closesLabel": "Cierra", + "hoursColumnLabel": "Horas", + "minutesColumnLabel": "Minutos", + "timezoneLabel": "Zona horaria", + "summaryAlways": "Abierto 24/7", + "summaryMarket": "Horario de mercado", + "summaryCustom": "{days} · {open}–{close}", + "summaryCustomDaysOnly": "{days}", + "summaryUnset": "Horario no definido" + }, + "transferApprovals": { + "ruleLabel": "Requerir aprobación para", + "ruleAll": "Todas", + "ruleAbove": "Por encima de un monto", + "ruleNewCounterparty": "Para nuevas contrapartes", + "amountLabel": "Umbral", + "amountSuffix": "Tokens", + "amountPlaceholder": "p. ej. 10000", + "approversLabel": "Aprobadores", + "approversHint": "Direcciones de Wallet o nombres de roles. Se pueden agregar después del lanzamiento.", + "addApprover": "Agregar aprobador", + "approverPlaceholder": "Dirección de Wallet o rol", + "removeApprover": "Quitar aprobador", + "summaryAll": "Todas las transferencias", + "summaryAbove": "Más de {amount} Tokens", + "summaryAboveUnset": "Por encima de un umbral", + "summaryNewCounterparty": "Nuevas contrapartes" + }, + "redemptionApprovals": { + "ruleLabel": "Requerir aprobación para", + "ruleAll": "Todas las redenciones", + "ruleAbove": "Redenciones por encima de un monto", + "amountLabel": "Umbral", + "amountSuffix": "Tokens", + "amountPlaceholder": "p. ej. 10000", + "approversLabel": "Aprobadores", + "approversHint": "Direcciones de Wallet o nombres de roles. Se pueden agregar después del lanzamiento.", + "addApprover": "Agregar aprobador", + "approverPlaceholder": "Dirección de Wallet o rol", + "removeApprover": "Quitar aprobador", + "summaryAll": "Todas las redenciones", + "summaryAbove": "Más de {amount} Tokens", + "summaryAboveUnset": "Por encima de un umbral" + }, + "investorReporting": { + "cadenceLabel": "Frecuencia de reportes", + "cadenceMonthly": "Mensual", + "cadenceQuarterly": "Trimestral", + "cadenceAnnual": "Anual", + "formatLabel": "Formato de reporte", + "formatPdf": "PDF", + "formatCsv": "CSV", + "formatXlsx": "Excel", + "recipientsLabel": "Destinatarios", + "recipientsHint": "Direcciones de correo electrónico o grupos de inversionistas. Se pueden agregar después del lanzamiento.", + "addRecipient": "Agregar destinatario", + "recipientPlaceholder": "Correo electrónico o grupo de inversionistas", + "removeRecipient": "Quitar destinatario", + "summaryWithFormat": "{cadence} · {format}" + }, + "weekdays": { + "mon": "Lun", + "tue": "Mar", + "wed": "Mié", + "thu": "Jue", + "fri": "Vie", + "sat": "Sáb", + "sun": "Dom" + }, + "timezones": { + "utc": "UTC", + "newYork": "Nueva York (ET)", + "losAngeles": "Los Ángeles (PT)", + "london": "Londres (GMT/BST)", + "zurich": "Zúrich (CET)", + "singapore": "Singapur (SGT)", + "tokyo": "Tokio (JST)" + } + }, + "permanentDelegate": "Recuperar Tokens", + "permanentDelegateDescription": "Permite que una autoridad de control incaute o recupere Tokens en respuesta a eventos de cumplimiento.", + "transferFee": "Transfer fee", + "transferFeeDescription": "Retiene un porcentaje como tarifa en cada transferencia de Tokens.", + "transferFeeBasisPoints": "Tarifa (puntos básicos)", + "transferFeeBasisPointsHint": "En puntos básicos: 100 pb = 1% (p. ej. 50 = 0.5%).", + "transferFeeMaxFee": "Tarifa máxima", + "interestBearing": "Interest-bearing", + "interestBearingDescription": "Acumula interés sobre los saldos de Tokens a una tasa fija.", + "interestBearingRate": "Tasa de interés", + "interestBearingRateHint": "Tasa anual en puntos básicos: 100 pb = 1%.", + "scaledUiAmount": "Monto de visualización escalado", + "scaledUiAmountDescription": "Ajusta los saldos mostrados según un factor definido, por ejemplo, para splits de acciones o cambios de clase de acción.", + "scaledUiAmountMultiplier": "Multiplicador", + "nonTransferable": "Non-transferable", + "nonTransferableDescription": "Impide que los Tokens se transfieran una vez que se poseen.", + "transferHook": "Reglas de transferencia personalizadas", + "transferHookDescription": "Enruta las transferencias a través de un programa de reglas que tú proporcionas para validaciones adicionales.", + "transferHookProgramId": "ID del programa", + "advancedSettingsTitle": "Configuración avanzada", + "showTechnicalDetail": "Ver", + "deployPreview": "Vista previa del despliegue", + "quickFillLabel": "Empezar desde un escenario", + "quickFillHint": "Elige una configuración para prellenar los controles a continuación — ajusta lo que necesites después.", + "accessPolicyPrompt": "Elige quién puede mantener y transferir este Token.", + "accessPolicyAllowlistEffect": "Solo las Wallets aprobadas pueden recibir o mantener este Token.", + "accessPolicyBlocklistEffect": "Cualquiera puede mantenerlo, excepto las Wallets que bloquees.", + "accessPolicyDisabledEffect": "Cualquiera puede mantener y transferir este Token libremente.", + "accessPolicyTechnical": "La allowlist congela las cuentas nuevas en el despliegue y es permanente una vez lanzado. La blocklist y la opción deshabilitada se aplican solo por política.", + "settingGroupEconomics": "Economía", + "settingGroupCompliance": "Cumplimiento", + "settingGroupControls": "Controles", + "settingLockedHint": "Bloqueado — esta configuración es fija y no se puede cambiar", + "settingRecommended": "Recomendado", + "settingRequired": "Obligatorio", + "settingAdvancedOptions": "Opciones avanzadas", + "settingsModeBasic": "Básico", + "settingsModeDetailed": "Detallado", + "settingsModeExpert": "Experto", + "settingsModeAria": "Nivel de detalle de la configuración", + "settingsPermanentTitle": "Permanente", + "settingsPermanentSubtitle": "Se define al crear el Token — no se puede cambiar después del lanzamiento.", + "settingsPermanentLockedSubtitle": "Permanente una vez desplegado — no se puede cambiar.", + "settingsOngoingTitle": "Continuo", + "settingsOngoingSubtitle": "Cada política se puede ajustar o configurar en cualquier momento.", + "settingsOngoingSubtitleDraft": "Un conjunto inicial. Cada política se configura después en la pestaña de cumplimiento y se puede cambiar en cualquier momento.", + "settingsOnchainTitle": "On-chain", + "settingsOffchainTitle": "Off-chain", + "settingConfigureInExpert": "Cambia a la vista Experto para configurar sus opciones.", + "settingExpertExtensionsLabel": "Extensiones", + "settingExpertActionsLabel": "Desbloqueos", + "settingExpertActionsNone": "Ninguno (solo configuración)", + "settingExpertMechanismLabel": "Mecanismo", + "settingExpertUnlocks": "Desbloqueos", + "settingConflictsWith": "No se puede combinar con", + "comboCustomSelection": "Personalizaste la configuración individual — abre Detallado para revisarla. Ninguna plantilla predefinida coincide exactamente con esta combinación.", + "comboConflictReasonBalanceDisplay": "un Token solo puede aplicar una regla de visualización de saldo.", + "comboConflictReasonNonTransferableFee": "un Token no transferible nunca se transfiere, por lo que una tarifa de transferencia nunca aplicaría.", + "comboConflictReasonNonTransferableHook": "un Token no transferible nunca se transfiere, por lo que las reglas de transferencia personalizadas nunca se ejecutarían.", + "comboRegulatedStablecoin": "Stablecoin regulada", + "comboRegulatedStablecoinDescription": "Una moneda pública respaldada por moneda fiduciaria, abierta a todos excepto a Wallets sancionadas: blocklist, KYC, suministro controlado, revisión de redención y reportes de reservas.", + "comboPermissionedStablecoin": "Stablecoin con permisos", + "comboPermissionedStablecoinDescription": "Una moneda de red cerrada solo para instituciones aprobadas: allowlist on-chain, KYC, suministro controlado y revisión de transferencias.", + "comboRegulatedSecurity": "Valor regulado", + "comboRegulatedSecurityDescription": "La base de cumplimiento para una acción o bono tokenizado: inversionistas verificados, transferencias revisadas, negociación en horario de mercado y reportes continuos.", + "comboFundOperations": "Operaciones de fondo", + "comboFundOperationsDescription": "Agrega suscripciones y redenciones con suministro gestionado por el emisor — combínalo con un valor regulado para operar un fondo.", + "comboVerifiedHolders": "Exigir titulares verificados", + "comboVerifiedHoldersDescription": "Solo las Wallets aprobadas pueden mantener o transferir este activo — titulares verificados (KYC) más una allowlist on-chain.", + "comboControlledAsset": "Activo controlado", + "comboControlledAssetDescription": "El emisor conserva el control de cumplimiento — congelar cuentas y recuperar Tokens — limitado a titulares verificados.", + "comboLoyaltyRewards": "Lealtad y recompensas", + "comboLoyaltyRewardsDescription": "Puntos o recompensas no transferibles, con mint controlado por el emisor.", + "comboYieldNote": "Nota que genera rendimiento", + "comboYieldNoteDescription": "Un instrumento que acumula interés para titulares verificados, con suministro controlado.", + "comboRevenueShare": "Token de participación en ingresos", + "comboRevenueShareDescription": "Captura una pequeña tarifa en cada transferencia, con suministro controlado.", + "comboGatedAccess": "Token de acceso restringido", + "comboGatedAccessDescription": "Token con permisos: las cuentas nuevas comienzan congeladas hasta que las apruebes, limitado a titulares verificados y horario de negociación definido." + }, + "playground": { + "viewApiContext": "API Playground", + "openInPlayground": "Abrir en API Playground", + "tokenNameExample": "Acme Dollar", + "tokenSymbolExample": "ACME", + "selectTemplate": "Seleccionar plantilla", + "settlementAssetExample": "Activo de liquidación respaldado por USD", + "metadataUriExample": "https://example.com/metadata/acme-usd.json", + "optionalHostedUri": "uri (opcional — SDP la aloja si se omite)", + "updatedTokenName": "Nombre de Token actualizado", + "updatedTokenDescription": "Descripción de Token actualizada", + "updatedMetadataUri": "https://example.com/updated-metadata.json", + "tokenImageUrl": "https://example.com/token.png", + "selectStatus": "Seleccionar estado", + "active": "Activo", + "paused": "Pausado", + "productName": "Emisión", + "none": "Ninguno", + "low": "Bajo", + "medium": "Medio", + "high": "Alto", + "true": "Verdadero", + "false": "Falso", + "selectPriorityFee": "Seleccionar valor de priorityFee", + "selectSimulate": "Seleccionar valor de simulate", + "amountPlaceholder": "p. ej. 1000", + "listTemplates": "Listar plantillas", + "getTemplate": "Obtener plantilla", + "createToken": "Crear Token", + "listTokens": "Listar Tokens", + "getToken": "Obtener Token", + "updateToken": "Actualizar Token", + "listTokenTransactions": "Listar transacciones del Token", + "refreshTotalSupply": "Actualizar suministro total", + "deployToken": "Desplegar Token", + "mintTokens": "Hacer mint de Tokens", + "burnTokens": "Hacer burn de Tokens", + "seizeTokens": "Incautar Tokens", + "forceBurn": "Forzar burn", + "updateAuthority": "Actualizar autoridad", + "pauseToken": "Pausar Token", + "unpauseToken": "Reanudar Token", + "freezeAccount": "Congelar cuenta", + "unfreezeAccount": "Descongelar cuenta", + "listFrozenAccounts": "Listar cuentas congeladas", + "listAllowlist": "Listar allowlist", + "listAllowlistLabels": "Listar etiquetas de la allowlist", + "addAllowlistEntry": "Agregar entrada a la allowlist", + "removeAllowlistEntry": "Quitar entrada de la allowlist", + "tokenIdPlaceholder": "ID de Token (p. ej. tok_abc123)", + "templateIdPlaceholder": "ID de plantilla (p. ej. stablecoin)", + "authorityRoleMint": "Mint", + "authorityRoleFreeze": "Freeze", + "authorityRolePermanentDelegate": "Permanent Delegate", + "authorityRoleMetadata": "Metadata", + "solanaAddressPlaceholder": "Dirección de Solana (32-44 caracteres)", + "optionalMemo": "Memo opcional", + "tokenAccountAddressPlaceholder": "Dirección de cuenta de Token (32-44 caracteres)", + "sourceTokenAccountAddress": "Dirección de la cuenta de Token de origen", + "destinationTokenAccountAddress": "Dirección de la cuenta de Token de destino", + "delegateAuthorityAddress": "Dirección de la autoridad delegada", + "tokenAccountAddress": "Dirección de cuenta de Token", + "selectAuthorityRole": "Seleccionar rol de autoridad", + "currentAuthorityAddress": "Dirección de autoridad actual", + "newAuthorityAddress": "Nueva dirección de autoridad", + "walletAddressToFreeze": "Dirección de Wallet a congelar", + "optionalFreezeReason": "Motivo de congelamiento opcional", + "walletAddressToUnfreeze": "Dirección de Wallet a descongelar", + "treasuryExample": "Tesorería", + "addressToAllowlist": "Dirección para agregar a la allowlist", + "optionalLabel": "Etiqueta opcional", + "allowlistEntryIdPlaceholder": "ID de entrada de la allowlist (p. ej. allow_123)" + }, + "compliance": { + "forceTransfer": "Forzar transferencia", + "forceBurn": "Forzar burn", + "freeze": "Congelar", + "pause": "Pausar", + "accessPolicy": "Política de acceso", + "accessPolicyDescription": "Documenta la política de acceso prevista para este activo.", + "accessControl": "Control de acceso", + "notSet": "No definido", + "lockReason": "Bloqueado después del despliegue — la aplicación on-chain no se puede cambiar.", + "selectAccessControl": "Seleccionar control de acceso", + "appliedOnDeploy": "Se aplica on-chain cuando se despliega el Token.", + "controls": "Controles", + "controlsDescription": "Acciones on-chain que surten efecto de inmediato." + }, + "classification": { + "title": "¿Qué es este activo?", + "description": "Empieza contándonos qué representa este activo y cómo debe clasificarse.", + "name": "Nombre", + "namePlaceholder": "p. ej., USD Workshop Money Market Fund", + "nameHint": "Un nombre claro para identificar este activo.", + "chooseClassification": "Elige una clasificación", + "notSure": "No sé qué elegir", + "chooseAssetType": "Elige el tipo de activo" + }, + "review": { + "assetTitle": "Activo", + "assetDescription": "El activo y cómo se representará.", + "assetCategory": "Categoría del activo", + "assetType": "Tipo de activo", + "name": "Nombre", + "symbol": "Símbolo", + "assetDetailsTitle": "Detalles del activo", + "assetDetailsDescription": "Información clave sobre el activo.", + "description": "Descripción", + "issuerName": "Nombre del emisor", + "decimals": "Decimales", + "website": "Sitio web", + "complianceAccessTitle": "Cumplimiento y acceso", + "complianceAccessDescription": "Cómo se controlará el activo y quién puede interactuar con él.", + "accessControl": "Control de acceso", + "allowlist": "Allowlist", + "blocklist": "Blocklist", + "none": "Ninguno", + "allowlistHint": "Solo las direcciones aprobadas pueden mantener o transferir.", + "blocklistHint": "Las direcciones bloqueadas no pueden mantener ni transferir.", + "transferRestrictions": "Restricciones de transferencia", + "enabled": "Habilitado", + "disabled": "Deshabilitado", + "transferRestrictionsHint": "Transferencias limitadas a participantes aprobados.", + "investorReporting": "Reportes para inversionistas", + "investorReportingHint": "Reportes de actividad disponibles para inversionistas y partes interesadas.", + "publicInformationTitle": "Información pública", + "publicInformationDescription": "La información segura que será visible para cualquiera.", + "publicName": "Nombre público", + "publicSymbol": "Símbolo público", + "logo": "Logo", + "publicDescription": "Descripción (pública)", + "edit": "Editar", + "notProvided": "—" + }, + "publicInfo": { + "name": "Nombre", + "symbol": "Símbolo", + "description": "Descripción", + "decimals": "Decimales", + "category": "Categoría", + "assetType": "Tipo de activo", + "logo": "Logo", + "untitledAsset": "Activo sin título", + "notProvided": "—", + "publicTokenInformation": "Información pública del Token", + "publicTokenInfoHelp": "Así es como aparecerá tu activo en Wallets, exploradores y ante el público.", + "includedInPublicView": "Incluido en la vista pública", + "publicCount": "Públicos: {count}", + "publicCoverage": "{publicCount} de {totalCount} campos públicos", + "notIncludedByDefault": "No incluido por defecto", + "notIncludedHelp": "Estos campos permanecen privados a menos que elijas incluirlos.", + "preview": "Vista previa", + "token": "Token", + "explorer": "Explorador", + "wallet": "Wallet", + "assetLogo": "Logo de {name}", + "asset": "Activo", + "mintAddress": "Dirección de mint", + "copyMintAddress": "Copiar dirección de mint", + "viewOnExplorer": "Ver en el explorador", + "copied": "Copiado", + "noPublicDescription": "Sin descripción pública", + "decimalsValue": "Decimales: {count}", + "alwaysPublic": "Siempre público — no se puede ocultar", + "hidePublicField": "Público — ocultar este campo", + "showPublicField": "Oculto — mostrar este campo públicamente" + }, + "assetDetails": { + "title": "Detalles del activo", + "description": "Agrega la información clave sobre este activo. Puedes actualizar estos detalles en cualquier momento.", + "tabs": { + "overview": "Resumen", + "compliance": "Cumplimiento y acceso", + "operational": "Operativo", + "custom": "Campos personalizados" + }, + "about": "Acerca de este activo", + "namePlaceholder": "p. ej., Verde Dollar", + "lockedAfterDeploy": "Bloqueado después del despliegue", + "aboutDescription": "Información básica que describe qué es este activo.", + "symbolPlaceholder": "p. ej., vUSD", + "descriptionLabel": "Descripción", + "descriptionPlaceholder": "Describe qué representa este activo.", + "website": "Sitio web", + "websitePlaceholder": "https://…", + "logoImageUrl": "URL de la imagen del logo", + "logoPlaceholder": "https://…/logo.png", + "logoHint": "Se muestra junto a tu Token en Wallets y exploradores.", + "supplyControls": "Suministro", + "supplyControlsDescription": "Cuánto de este activo puede existir en total.", + "maxSupply": "Suministro máximo", + "maxSupplyPlaceholder": "Ilimitado", + "maxSupplyHint": "En blanco = ilimitado. Se aplica mediante SDP mientras conserva la Mint Authority, y puede bloquearse de forma permanente on-chain.", + "documents": "Documentos y referencias", + "documentsDescription": "Documentos y referencias importantes relacionados con este activo.", + "accessControlDescription": "Elige cómo trata este Token las direcciones de destino aprobadas o bloqueadas.", + "learnLists": "Conoce en qué se diferencian la allowlist y la blocklist", + "operational": "Operativo", + "operationalDescription": "Configuración operativa opcional.", + "signingWallet": "Wallet de firma", + "optionalSignerHint": "Opcional — deja sin seleccionar para usar el firmante predeterminado del proyecto.", + "customFields": "Campos personalizados", + "customFieldsDescription": "Agrega tus propios campos privados, almacenados bajo custom.customer.", + "projectDefaultSigner": "Firmante predeterminado del proyecto", + "signingWalletLockReason": "Se define al crear — cada operación puede usar un firmante distinto.", + "documentTypePlaceholder": "Tipo de documento", + "documentNamePlaceholder": "Nombre", + "removeDocument": "Quitar documento", + "addDocument": "Agregar documento", + "hideJson": "Ocultar JSON", + "viewJson": "Ver JSON", + "copied": "¡Copiado!", + "customFieldKey": "Clave", + "customFieldValue": "Valor", + "removeCustomField": "Quitar campo", + "addCustomField": "Agregar campo", + "copyJson": "Copiar JSON", + "deployConfigAuthorityNote": "Las autoridades (mint, freeze, delegate) se asignan en el despliegue desde la custodia de tu Wallet de firma." + }, + "assetProfileDetails": { + "privateByDefault": "Esta información es privada por defecto y no será visible para el público a menos que elijas incluirla." + } + } +} diff --git a/apps/sdp-web/messages/es/dashboard-payments.json b/apps/sdp-web/messages/es/dashboard-payments.json new file mode 100644 index 000000000..83f4cd224 --- /dev/null +++ b/apps/sdp-web/messages/es/dashboard-payments.json @@ -0,0 +1,1043 @@ +{ + "DashboardPayments": { + "page": { + "unavailableStatus": "no disponible", + "unknownError": "Error desconocido", + "walletApiError": "API de Wallet {status}: {error}", + "walletAggregateApiError": "API de agregado de Wallet {status}: {error}", + "transferApiError": "API de transferencia {status}: {error}" + }, + "workspace": { + "walletListRequestFailed": "La solicitud de lista de Wallets falló ({status}).", + "walletAggregateRequestFailed": "La solicitud de agregado de Wallet falló ({status}).", + "walletAggregateMissing": "La respuesta de agregado de Wallet no incluye los detalles del agregado.", + "walletPolicyRequestFailed": "La solicitud de política de la Wallet falló ({status}).", + "transferListRequestFailed": "La solicitud de lista de transferencias falló ({status}).", + "transferListMissing": "La respuesta de lista de transferencias no incluye los datos de la transferencia.", + "transferLookupFailed": "La búsqueda de la transferencia falló ({status}).", + "transferLookupMissing": "La respuesta de búsqueda de la transferencia no incluye los datos de la transferencia.", + "transferLookupMultiple": "La búsqueda de la transferencia devolvió múltiples transferencias.", + "transferCancellationFailed": "La cancelación de la transferencia falló ({status}).", + "rampEstimateRequestFailed": "La solicitud de estimación del ramp falló ({status}).", + "rampEstimateMissing": "La respuesta de estimación del ramp no incluye las estimaciones.", + "walletBalancesRequestFailed": "La solicitud de saldos de la Wallet falló ({status}).", + "walletBalancesMissing": "La respuesta de saldos de la Wallet no incluye los detalles del saldo.", + "walletPolicyUpdateFailed": "La actualización de política de la Wallet falló ({status}).", + "walletPolicyUpdateEmpty": "La actualización de política de la Wallet devolvió una respuesta vacía.", + "transferRequestFailed": "La solicitud de transferencia falló ({status}).", + "transferMissing": "La respuesta de la transferencia no incluye los detalles de la transferencia.", + "recipientListRequestFailed": "La solicitud de lista de destinatarios falló ({status}).", + "recipientListMissing": "La respuesta de lista de destinatarios no incluye destinatarios.", + "batchEstimateRequestFailed": "La solicitud de estimación por lote falló ({status}).", + "batchEstimateMissing": "La respuesta de estimación por lote no incluye los detalles de la estimación.", + "batchTransferRequestFailed": "La solicitud de transferencia por lote falló ({status}).", + "batchTransferMissing": "La respuesta de transferencia por lote no incluye los detalles del lote.", + "rampEventRequestFailed": "La solicitud de evento de {provider} falló ({status}).", + "rampEventMissing": "La respuesta de evento de {provider} no incluye los detalles de la transferencia.", + "counterpartyAccountsRequestFailed": "No se pudieron cargar las cuentas ({status}).", + "sandboxSimulationRequestFailed": "La simulación en Sandbox falló ({status}).", + "requirementsRequestFailed": "La solicitud de requisitos falló ({status}).", + "requirementsAdvanceFailed": "El avance de requisitos falló ({status}).", + "requirementsContextMissing": "No se pueden avanzar los requisitos sin un proveedor y una contraparte.", + "complianceCheckFailed": "La verificación de cumplimiento falló.", + "complianceNotEnabled": "La verificación de cumplimiento con Range, Elliptic, TRM y Chainalysis está disponible en el plan empresarial. Contáctanos para habilitarla en tu organización.", + "destinationRequired": "La dirección de destino es obligatoria.", + "transferBlocked": "Transferencia bloqueada.", + "transferBlockedDescription": "Ejecuta la verificación de cumplimiento o usa un destino que ya esté en la allowlist de la Wallet de origen.", + "transactionSent": "Transacción enviada.", + "viewOnSolanaExplorer": "Ver en Solana Explorer", + "walletsLoadFailed": "No se pudieron cargar las Wallets.", + "walletPolicyLoadFailed": "No se pudo cargar la política de la Wallet.", + "addressRequired": "La dirección es obligatoria.", + "complianceCheckRequired": "Ejecuta la verificación de cumplimiento antes de agregar la dirección.", + "addressAlreadyAllowlisted": "La dirección ya está en la allowlist de destino.", + "addressAddedToAllowlist": "Dirección agregada a la allowlist de destino de la Wallet.", + "destinationAddressAddFailed": "No se pudo agregar la dirección de destino.", + "sourceWalletRequired": "Selecciona primero una Wallet de origen.", + "destinationAllowlistLoadFailed": "No se pudo cargar la allowlist de destino." + }, + "paymentMethods": { + "onchainTransfer": "Transferencia on-chain", + "onchainTransferDescription": "Envía criptomonedas desde una Wallet de SDP a la dirección de Solana de una contraparte.", + "payWithFiat": "Pagar con fiat", + "payWithFiatDescription": "Convierte criptomonedas a fiat y paga a través de un proveedor.", + "onchainDeposit": "Depósito on-chain", + "onchainDepositDescription": "Recibe criptomonedas directamente en una dirección de Wallet de SDP.", + "depositWithFiat": "Depositar con fiat", + "depositWithFiatDescription": "Compra criptomonedas con fiat a través de un proveedor y deposítalas en una Wallet." + }, + "cancelTransaction": { + "ariaLabel": "Cancelar transacción", + "title": "¿Cancelar esta transacción?", + "description": "Esta transacción ya se inició. Si la cancelas ahora, saldrás del flujo.", + "keepGoing": "Seguir con la transacción", + "cancel": "Cancelar transacción" + }, + "sendMode": { + "single": "Individual", + "batch": "Lote", + "onchain": "On-chain" + }, + "ramps": { + "max": "MÁX", + "recentTransfersRequestFailed": "La solicitud de transferencias recientes falló.", + "recentTransfers": "Transferencias recientes", + "noRecentTransactions": "No hay transacciones recientes.", + "chooseProvider": "Elige un proveedor", + "unavailableCount": "No disponibles: {count}", + "noProvidersAvailable": "No hay proveedores disponibles para esta selección.", + "unavailableProviders": "Proveedores no disponibles", + "walletAddressQrCode": "Código QR de la dirección de la Wallet", + "walletReceiveDescription": "Escanea este código QR o copia la dirección para recibir USDC o cualquier Token SPL en Solana en la Wallet seleccionada.", + "addressCopied": "Dirección copiada.", + "copyAddress": "Copiar dirección", + "convertTo": "Convertir a", + "currency": "Moneda", + "selectCurrency": "Selecciona una moneda", + "searchCurrencies": "Buscar monedas", + "searchAssets": "Buscar activos", + "balanceAvailable": "{amount} disponible", + "amount": "Monto", + "destinationWallet": "Wallet de destino", + "sourceWallet": "Wallet de origen", + "memoViewJson": "Ver JSON", + "memoJsonTitle": "JSON del memo", + "memoJsonDescription": "Los campos del memo tal como se incluirán en la solicitud.", + "memoDescription": "Agrega campos clave-valor para la conciliación off-chain. Pega filas separadas por tabulaciones o comas en cualquier lugar.", + "memoKey": "Clave", + "memoValue": "Valor", + "memoKeyPlaceholder": "factura", + "memoValuePlaceholder": "FAC-123", + "removeMemoRow": "Eliminar fila de memo {row}", + "addMemoRow": "Agregar fila", + "memoErrorKeyRequired": "La clave es obligatoria.", + "memoErrorKeyTooLong": "La clave debe tener {limit} caracteres o menos.", + "memoErrorKeyDuplicate": "Las claves deben ser únicas.", + "memoErrorValueRequired": "El valor es obligatorio.", + "memoErrorValueTooLong": "El valor debe tener {limit} caracteres o menos.", + "memoErrorTooManyFields": "El memo puede contener como máximo {limit} campos.", + "rampMemoStep": "Memo", + "rampMemoStepTitle": "Agrega un memo (opcional)", + "detailsStep": "Detalles", + "onrampDepositStep": "Depósito", + "onrampDepositTitle": "¿Cuánto te gustaría depositar?", + "onrampProviderTitle": "Completa tu depósito", + "onrampRequirementsTitle": "Algunos detalles para continuar", + "offrampWalletStep": "Wallet", + "offrampWalletTitle": "¿Desde qué Wallet estás retirando?", + "offrampWithdrawStep": "Retiro", + "offrampWithdrawTitle": "¿Cuánto te gustaría retirar?", + "offrampCompleteStep": "Finalización", + "offrampCompleteTitle": "Completa tu pago saliente", + "payoutDetailsStep": "Detalles del pago saliente", + "payoutDetailsTitle": "¿Adónde debemos enviar el pago saliente?", + "selectDestinationWallet": "Selecciona una Wallet de destino", + "selectSourceWallet": "Selecciona una Wallet de origen", + "searchWallets": "Buscar Wallets", + "fees": "Tarifas {providerFee} {providerCurrency} + {networkFee} {networkCurrency}", + "noFees": "Sin tarifas", + "fee": "Tarifa {amount} {currency}", + "estimatedReceived": "Recibido (est.)", + "rateKnownAtQuote": "Tasa conocida al cotizar", + "unavailable": "No disponible", + "acceptTerms": "Aceptar términos", + "completeVerification": "Completar verificación", + "tryAgain": "Reintentar", + "quoteMissingInstructions": "La cotización del ramp no incluye instrucciones de pago.", + "sendCrypto": "Enviar {amount} {token}", + "quoteExpired": "Cotización vencida", + "sending": "Enviando...", + "transferSubmitted": "Transferencia enviada", + "transferFailed": "La transferencia falló.", + "transactionSentSuccessfully": "Transacción enviada correctamente.", + "transferStatus": "Estado: {status}", + "submittingOnchainTransfer": "Enviando transferencia on-chain.", + "simulatingQuoteFunding": "Simulando el fondeo de la cotización.", + "quoteFundingSimulated": "Fondeo de la cotización simulado.", + "quoteSimulationFailed": "La simulación de la cotización falló.", + "sandboxSimulationFailed": "La simulación en Sandbox falló.", + "muralSandboxCurrencyUnsupported": "El ingreso de Mural en Sandbox no admite {currency}.", + "transferSignatureMissing": "La transferencia no devolvió una firma (estado: {status}).", + "offrampManualDescription": "Envía {amount} {token} a la dirección de depósito que aparece abajo antes de que expire la cotización. El proveedor lo convertirá a la tasa fijada y pagará automáticamente a la cuenta bancaria guardada.", + "noPayoutProviders": "No hay proveedores de pagos salientes habilitados para esta organización.", + "providerPayout": "Pago saliente de {provider}", + "noDepositProviders": "No hay proveedores de depósito habilitados para esta organización.", + "providerDeposit": "Depósito de {provider}", + "quoteRequestFailedStatus": "La solicitud de cotización del ramp falló ({status}).", + "quoteResponseMissingDetails": "La respuesta de cotización del ramp no incluye los detalles de la cotización.", + "creatingQuote": "Creando cotización.", + "widgetReady": "Widget listo.", + "quoteReady": "Cotización lista.", + "unableToCreateQuote": "No se pudo crear la cotización.", + "quoteRequestFailed": "La solicitud de cotización del ramp falló.", + "settingUpAccount": "Configurando tu cuenta.", + "moreDetailsNeeded": "Necesitamos algunos detalles más antes de continuar.", + "unableToStartOnboarding": "No se pudo iniciar la incorporación.", + "requirementsRequestFailed": "La solicitud de requisitos falló.", + "nextStepSoon": "El próximo paso estará disponible pronto.", + "cannotCancelWithoutQuote": "No se puede cancelar sin una cotización activa.", + "cancelingTransaction": "Cancelando transacción.", + "transactionCanceled": "Transacción cancelada.", + "unableToCancelTransaction": "No se pudo cancelar la transacción.", + "cancellationFailed": "La cancelación falló.", + "funded": "Fondeado", + "sent": "Enviado", + "provider": "Proveedor", + "finalFundedAmount": "Monto final fondeado", + "finalSentAmount": "Monto final enviado", + "finalReceivedAmount": "Monto final recibido", + "finalPayoutAmount": "Monto final del pago saliente", + "completed": "Completado", + "transferId": "ID de transferencia", + "quoteId": "ID de cotización", + "depositComplete": "Depósito completado", + "payoutComplete": "Pago saliente completado", + "depositCompleteDescription": "Los fondos se liquidaron en la Wallet de destino.", + "payoutCompleteDescription": "El pago saliente se liquidó en la cuenta bancaria del destinatario.", + "fundedWith": "fondeado con", + "from": "desde", + "newPayeeHint": "Crea un nuevo beneficiario si aún no está en la lista.", + "newBuyerHint": "Crea un nuevo comprador si aún no está en la lista.", + "destinationAccount": "Cuenta de destino", + "selectCounterpartyFirst": "Selecciona primero una contraparte", + "noSolanaAccounts": "No hay cuentas de Solana registradas", + "selectDestinationAccount": "Selecciona una cuenta de destino", + "searchAccounts": "Buscar cuentas", + "assetBreakdown": "Desglose de activos", + "total": "{amount} en total", + "selectCounterparty": "Selecciona una contraparte", + "searchCounterparties": "Buscar contrapartes", + "counterpartiesLoadFailed": "No se pudieron cargar las contrapartes.", + "openFullScreen": "Abrir en pantalla completa", + "selectField": "Selecciona {field}", + "search": "Buscar…", + "stripeLoadError": "No se pudo cargar el Checkout de Stripe", + "stripeLoadHelp": "El Checkout de Stripe no se pudo cargar. Verifica tu conexión e intenta de nuevo.", + "moneygramEventFailed": "No se pudo registrar el evento de MoneyGram.", + "eventRequestFailed": "La solicitud del evento falló.", + "moneygramCompletionBeforeTransfer": "MoneyGram reportó la finalización antes de que se registrara la transferencia de criptomonedas.", + "moneygramWidgetLoadFailed": "No se pudo cargar el widget de MoneyGram.", + "unsupportedMoneygramTransaction": "Transacción no compatible: {asset} en {chain}.", + "sourceWalletNoUsdc": "La Wallet de origen no tiene saldo de USDC para enviar.", + "coinbaseEventFailed": "No se pudo registrar el evento de Coinbase.", + "coinbaseOnramp": "Onramp de Coinbase", + "status": { + "waitingForFunding": "Esperando el fondeo", + "waitingToSend": "Esperando el envío", + "waitingForFundingDescription": "Envía los fondos siguiendo las instrucciones anteriores. Actualizaremos este depósito automáticamente en cuanto el proveedor reciba el pago.", + "waitingToSendDescription": "Completa el pago saliente siguiendo las instrucciones anteriores. Actualizaremos esta transferencia saliente automáticamente en cuanto el proveedor reciba tus criptomonedas.", + "depositReceived": "Depósito recibido", + "sendingPayout": "Enviando pago saliente", + "depositReceivedDescription": "El proveedor recibió los fondos y está liquidando el depósito en la Wallet de destino.", + "sendingPayoutDescription": "El proveedor recibió tus criptomonedas y está liquidando el pago saliente al destinatario.", + "transferComplete": "Transferencia completada", + "payoutSent": "Pago saliente enviado", + "transferCompleteDescription": "El depósito se completó. Puedes revisar la transferencia desde el registro de la contraparte.", + "payoutSentDescription": "El pago saliente se liquidó. Puedes revisar esta transferencia desde el registro de la contraparte.", + "transferFailed": "Transferencia fallida", + "payoutFailed": "Pago saliente fallido", + "transferFailedDescription": "El proveedor reportó que este depósito falló. Revisa el registro de la contraparte para conocer el estado más reciente de la transferencia.", + "payoutFailedDescription": "El proveedor reportó que este pago saliente falló. Revisa el registro de la contraparte para conocer el estado más reciente de la transferencia.", + "quoteExpired": "Cotización vencida", + "quoteExpiredFundingDescription": "Esta cotización venció antes de que se completara la transferencia. Crea una nueva cotización para continuar con el fondeo.", + "quoteExpiredPayoutDescription": "Esta cotización venció antes de que se completara el pago saliente. Crea una nueva cotización para continuar con el retiro.", + "updated": "Estado de la transferencia actualizado", + "currentProviderStatus": "Estado actual del proveedor: {status}.", + "preparing": "Preparando el estado de la transferencia", + "preparingDescription": "Estamos esperando el registro de la transferencia asociado a esta cotización." + } + }, + "onchainSend": { + "noAssets": "Esta Wallet no tiene activos disponibles para enviar.", + "addSolanaAddress": "Agregar dirección de Solana", + "counterpartyNoAddress": "{counterparty} aún no tiene una dirección de Solana registrada.", + "thisCounterparty": "Esta contraparte", + "attachDestination": "Adjunta otra dirección de destino para esta contraparte.", + "sourceWallet": "Wallet de origen", + "selectSourceWallet": "Selecciona una Wallet de origen", + "searchWallets": "Buscar Wallets", + "amount": "Monto", + "asset": "Activo", + "selectAsset": "Seleccionar", + "memoOptional": "Memo (opcional)", + "memoPlaceholder": "Agrega una nota para esta transferencia", + "to": "Para", + "destination": "Destino", + "destinationTitle": "¿Adónde deben ir los fondos?", + "details": "Detalles", + "detailsTitle": "¿Qué te gustaría enviar?", + "review": "Revisar", + "reviewTitle": "Revisar transferencia", + "submittingTransfer": "Enviando transferencia.", + "memo": "Memo", + "counterparty": "contraparte", + "toCounterparty": "a {counterparty}", + "transferSubmitted": "Transferencia enviada", + "transactionSent": "Transacción enviada correctamente.", + "transferFailed": "La transferencia falló.", + "transferSuccess": "Tu transferencia se envió correctamente.", + "transferStatus": "Estado: {status}", + "viewOnExplorer": "Ver en el explorador" + }, + "onchainReceive": { + "wallet": "Wallet", + "walletTitle": "¿Qué Wallet debe recibir los fondos?", + "receive": "Recibir", + "receiveTitle": "Recibir fondos on-chain" + }, + "bvnk": { + "verificationRequiredTitle": "Verifica tu identidad", + "verificationRequiredDescription": "BVNK se asocia con Sumsub para confirmar tu identidad antes de activar tu cuenta de fondeo. Presiona “Completar verificación” para comenzar — esta página se actualiza automáticamente en cuanto te aprueben, y tus instrucciones aparecerán justo aquí.", + "verificationInReviewTitle": "Verificación en revisión", + "verificationInReviewDescription": "Sumsub está revisando tus datos — esto suele tardar solo unos minutos. Puedes volver más tarde; tus instrucciones aparecerán aquí en cuanto te aprueben.", + "verificationFailedTitle": "La verificación de identidad no fue aprobada", + "verificationFailedDescription": "BVNK no pudo verificar tu identidad, por lo que esta cuenta de fondeo no se puede activar. Contacta a soporte si crees que esto es un error.", + "fundingAccountProvisioningTitle": "Configurando tu cuenta de fondeo", + "fundingAccountProvisioningDescription": "Ya casi está listo — estamos aprovisionando tu cuenta virtual. Tus instrucciones aparecerán aquí en un momento.", + "provisioningFailedTitle": "No pudimos terminar de configurar tu cuenta", + "provisioningFailedDescription": "Algo salió mal al aprovisionar tu cuenta de fondeo. Intenta de nuevo.", + "readyTitle": "Preparando tus instrucciones", + "readyDescription": "Tu cuenta de fondeo está lista — obteniendo tus datos ahora.", + "onrampProvisioningDetail": "Aprovisionando una Wallet de BVNK y una regla de pago fiat→cripto para esta cotización.", + "offrampProvisioningDetail": "Aprovisionando una Wallet de pagos salientes dedicada de BVNK para esta moneda.", + "simulateDeposit": "Simular depósito", + "simulating": "Simulando...", + "depositSimulated": "Depósito simulado" + }, + "lightspark": { + "verificationRequiredTitle": "Verifica tu identidad", + "verificationRequiredDescription": "Necesitamos confirmar tu identidad antes de activar tu cuenta de fondeo. Esta página se actualiza automáticamente en cuanto te aprueben.", + "verificationInReviewTitle": "Verificación en revisión", + "verificationInReviewDescription": "Tus datos están en revisión — esto suele tardar solo unos minutos. Tus instrucciones aparecerán aquí en cuanto te aprueben.", + "verificationFailedTitle": "La verificación de identidad no fue aprobada", + "verificationFailedDescription": "No pudimos verificar tu identidad, por lo que esta cuenta de fondeo no se puede activar. Contacta a soporte si crees que esto es un error.", + "fundingAccountProvisioningTitle": "Configurando tu cuenta", + "fundingAccountProvisioningDescription": "Ya casi está listo — estamos preparando tu cuenta de fondeo. Tus instrucciones aparecerán aquí en un momento.", + "provisioningFailedTitle": "No pudimos terminar de configurar tu cuenta", + "provisioningFailedDescription": "Algo salió mal al preparar tu cuenta de fondeo. Intenta de nuevo.", + "readyTitle": "Preparando tus instrucciones", + "readyDescription": "Tu cuenta está lista — obteniendo tus datos ahora.", + "onrampProvisioningDetail": "Aprovisionando tu cliente de Lightspark y los detalles de depósito para esta cotización.", + "offrampProvisioningDetail": "Aprovisionando una cuenta de pagos salientes de Lightspark bajo demanda para este retiro.", + "simulateQuote": "Simular cotización", + "simulating": "Simulando...", + "quoteSimulated": "Cotización simulada" + }, + "mural": { + "termsTitle": "Acepta los términos de Mural Pay", + "termsDescription": "Mural Pay requiere que la contraparte acepte los términos alojados antes de que pueda comenzar la verificación de identidad.", + "verificationRequiredTitle": "Verifica tu identidad", + "verificationRequiredDescription": "Mural Pay necesita que la contraparte complete la verificación alojada antes de activar una cuenta de fondeo.", + "verificationInReviewTitle": "Verificación en revisión", + "verificationInReviewDescription": "Mural Pay está revisando a la contraparte. Las instrucciones de fondeo aparecerán una vez aprobada la verificación.", + "verificationFailedTitle": "La verificación de identidad no fue aprobada", + "verificationFailedDescription": "Mural Pay no pudo aprobar a esta contraparte, por lo que no se puede activar una cuenta de fondeo.", + "fundingAccountProvisioningTitle": "Configurando tu cuenta de fondeo", + "fundingAccountProvisioningDescription": "Mural Pay está activando una cuenta de fondeo. Los datos bancarios aparecerán aquí cuando esté lista.", + "readyTitle": "Preparando tus instrucciones", + "readyDescription": "Tu cuenta de fondeo de Mural Pay está lista. Obteniendo los detalles más recientes ahora.", + "onrampProvisioningDetail": "Aprovisionando una cuenta de fondeo de Mural Pay para esta contraparte.", + "offrampProvisioningDetail": "Comprobando la verificación de la organización en Mural Pay antes del retiro.", + "simulateDeposit": "Simular depósito", + "simulating": "Simulando...", + "depositSimulated": "Depósito simulado" + }, + "batchSend": { + "recipientStatusPending": "Pendiente", + "recipientStatusProcessing": "Procesando", + "recipientStatusConfirmed": "Completado", + "recipientStatusFailed": "Fallido", + "recipientStatusArchived": "Archivado", + "resultConfirmed": "Lote enviado", + "resultPartiallyFailed": "Lote parcialmente fallido", + "resultFailed": "Lote fallido", + "resultSubmitted": "Lote registrado", + "recipientsStep": "Destinatarios", + "recipientsTitle": "Pagar a varios destinatarios", + "reviewStep": "Revisión", + "reviewTitle": "Revisar lote", + "customToken": "Token personalizado", + "tokenUnavailableOnNetwork": "{currency} no está disponible en esta red.", + "importExceedsMaximumRecipients": "Un lote puede tener como máximo {max} destinatarios. Esta importación llevaría el total a {total}.", + "submitting": "Enviando lote.", + "someRecipientsDidNotReceiveFunds": "Algunos destinatarios no recibieron fondos.", + "status": "Estado: {status}", + "estimateFailed": "Error al estimar.", + "recipientSingular": "{count} destinatario", + "recipientPlural": "{count} destinatarios", + "yourWallet": "tu Wallet", + "maximumRecipients": "Un lote puede tener como máximo {count} destinatarios.", + "insufficientBalance": "Saldo insuficiente", + "walletsSelectedSingular": "{count} Wallet seleccionada", + "walletsSelectedPlural": "{count} Wallets seleccionadas", + "from": "Desde", + "reference": "Referencia", + "referenceOptional": "Opcional", + "selectSourceWallet": "Selecciona una Wallet de origen", + "searchWallets": "Buscar Wallets", + "asset": "Activo", + "selectAsset": "Selecciona un activo", + "noAssets": "Esta Wallet no tiene activos disponibles para enviar.", + "selectRecipientWallets": "Selecciona las Wallets de los destinatarios", + "bulkImport": "O importar en bloque", + "searchCounterparty": "Buscar contraparte", + "paginationSummary": "{page} / {pageCount}", + "noCounterpartiesWithSolanaAddress": "No hay contrapartes con una dirección de Solana.", + "noMatches": "No hay coincidencias.", + "addRecipient": "Agregar a {name}", + "totalAmount": "Total {total} {asset}", + "totalOfAmount": " de {available} {asset}", + "reviewSummary": "{total} {asset} → {recipients}", + "transactionCountSingular": "{count} transacción", + "transactionCountPlural": "{count} transacciones", + "source": "Origen", + "transactionFees": "Tarifas de transacción", + "rentFees": "Tarifas de rent", + "total": "Total", + "sponsoredFee": "0 SOL", + "sponsoredBy": "Patrocinado por SDP a través de Kora", + "estimating": "Estimando…", + "resultSummary": "{recipients} destinatarios · {transactions} transacciones", + "viewOnExplorer": "Ver en el explorador", + "bulkImportAriaLabel": "Importar destinatarios en bloque", + "bulkImportTitle": "Importar destinatarios en bloque", + "bulkImportDescriptionBefore": "Pega filas de ", + "bulkImportFields": "counterparty_wallet_id, moneda reconocida ('well-known') o dirección de mint, monto", + "bulkImportDescriptionAfter": " en cualquier campo, o agrégalos de uno en uno.", + "counterpartyWalletIdPlaceholder": "counterparty_wallet_id", + "currencyOrMintPlaceholder": "moneda o mint", + "amountPlaceholder": "monto", + "removeRow": "Eliminar fila {row}", + "addRecipientRow": "Agregar destinatario", + "rowError": "Fila {row}: {message}", + "addAtLeastOneRecipient": "Agrega al menos un destinatario.", + "oneCurrencyRequired": "Todas las filas deben usar una sola moneda o dirección de mint (se encontraron {currencies}).", + "walletNotFound": "Wallet no encontrada: {id}", + "importFailed": "Error al importar.", + "cancel": "Cancelar", + "importing": "Importando…", + "import": "Importar" + }, + "manualInstructions": { + "copied": "Se copió {label}.", + "copyFailed": "No se pudo copiar {label}.", + "copy": "Copiar", + "instructions": "Instrucciones", + "quoteSummary": "Resumen de la cotización", + "quoteSummaryDescription": "Precio bloqueado para esta instrucción de fondeo.", + "finalAmount": "Monto final", + "depositAmount": "Monto del depósito", + "feesIncluded": "Tarifas incluidas", + "exchangeRate": "Tipo de cambio", + "expires": "Vence", + "bankName": "Nombre del banco", + "routingNumber": "Número de ruta", + "accountNumber": "Número de cuenta", + "walletAddress": "Dirección de la Wallet", + "reference": "Referencia", + "supportedRails": "Rails admitidos", + "notes": "Notas", + "depositAddress": "Dirección de depósito", + "bankCode": "Código del banco", + "paymentReference": "Referencia de pago", + "identityVerificationRequired": "Se requiere verificación de identidad", + "completeVerification": "Completar verificación", + "provisioningAccount": "BVNK está aprovisionando tu cuenta bancaria virtual", + "verificationInReview": "Verificación en revisión", + "provisioningFundingAccount": "Aprovisionando cuenta de fondeo", + "checkingVerificationStatus": "Verificando el estado de la verificación", + "manualFundingInstructions": "Instrucciones de fondeo manual", + "defaultDescription": "Envía {amount} usando uno de los rails admitidos. Incluye la referencia exactamente para que el proveedor pueda vincular el depósito con esta cotización.", + "quotedAmount": "el monto cotizado", + "cryptoDeposit": "Depósito de {currency}", + "virtualAccount": "Cuenta virtual de {currency}", + "payin": "Ingreso de {currency}" + }, + "providerRisk": { + "close": "Cerrar {title}", + "description": "Esta verificación evalúa factores de riesgo importantes, como la exposición a sanciones y otras señales de cumplimiento de los proveedores conectados.", + "provider": "Proveedor", + "analysis": "Análisis", + "noTrmAttribution": "Sin atribución de TRM", + "unavailable": "No disponible", + "error": "Error", + "notAvailable": "N/D", + "dismiss": "Descartar" + }, + "counterparty": { + "loadFailed": "No se pudieron cargar las contrapartes", + "metadataMissing": "La respuesta de metadatos de la contraparte estaba vacía.", + "validation": { + "required": "Obligatorio", + "invalidEmail": "Correo electrónico inválido", + "invalidDate": "Ingresa una fecha en formato AAAA-MM-DD.", + "dateMustBePast": "Debe ser una fecha en el pasado.", + "invalidPhone": "Ingresa un número de teléfono en formato E.164 (por ejemplo, +14155551234).", + "selectCountry": "Selecciona un país.", + "selectState": "Selecciona un estado." + }, + "addExternalAccount": "Agregar cuenta externa", + "addExternalAccountDescription": "Vincula una Wallet cripto para esta contraparte. La dirección se verifica por riesgo antes de agregarla.", + "addCounterparty": "Agregar contraparte", + "created": "Se creó {name}", + "createdSuccess": "Contraparte creada", + "transferType": "Tipo", + "transferProvider": "Proveedor", + "transferWallet": "Wallet", + "transferAmount": "Monto", + "transferStatus": "Estado", + "transferDate": "Fecha", + "allProviders": "Todos los proveedores", + "noFilteredTransactions": "No hay transacciones que coincidan con los filtros seleccionados.", + "fullName": "Nombre completo", + "createdLabel": "Creado", + "youDeposit": "Depositas", + "youSend": "Envías", + "recipientGets": "El destinatario recibe", + "viewOnExplorer": "Ver en el explorador", + "deleted": "Se eliminó {name}", + "createdButUnavailable": "La contraparte se creó, pero no se pudo cargar.", + "somethingWentWrong": "Algo salió mal", + "addCryptoAccount": "Agregar una cuenta cripto", + "addCryptoAccountDescription": "Opcionalmente, agrega una Wallet cripto para esta contraparte. Puedes omitir este paso y agregar cuentas más tarde.", + "cryptoWallet": "Wallet cripto", + "done": "Listo", + "skip": "Omitir", + "displayName": "Nombre para mostrar", + "individualNamePlaceholder": "María González", + "businessNamePlaceholder": "Acme Corp", + "email": "Correo electrónico", + "emailPlaceholder": "contacto@ejemplo.com", + "externalId": "ID externo", + "optional": "(opcional)", + "externalIdPlaceholder": "tu-id-interno", + "firstName": "Nombre", + "firstNamePlaceholder": "María", + "lastName": "Apellido", + "lastNamePlaceholder": "González", + "dateOfBirth": "Fecha de nacimiento", + "phone": "Teléfono", + "phonePlaceholder": "+52 55 0000 0000", + "line1": "Línea 1", + "line1Placeholder": "Calle Principal 123", + "line2": "Línea 2", + "line2Placeholder": "Oficina 400", + "city": "Ciudad", + "cityPlaceholder": "Ciudad de México", + "postalCode": "Código postal", + "country": "País", + "selectCountry": "Seleccionar país", + "searchCountries": "Buscar países…", + "state": "Estado", + "selectState": "Seleccionar estado", + "searchStates": "Buscar estados…", + "stateProvince": "Estado / Provincia", + "statePlaceholder": "CDMX", + "basics": "Datos básicos", + "entityType": "Tipo de entidad", + "individual": "Persona natural", + "business": "Persona jurídica", + "personalInfo": "Información personal", + "address": "Dirección", + "back": "Atrás", + "creating": "Creando", + "create": "Crear", + "next": "Siguiente", + "stepProgress": "Paso {current} de {total}", + "deleteCounterparty": "Eliminar contraparte", + "deleteNamedCounterparty": "¿Seguro que quieres eliminar a {name}? Esto archivará la contraparte y sus cuentas.", + "deleteThisCounterparty": "¿Seguro que quieres eliminar esta contraparte?", + "cancel": "Cancelar", + "deleting": "Eliminando", + "delete": "Eliminar", + "basicInfo": "Información básica", + "basicInfoDescription": "Ingresa el nombre y los datos de contacto de la contraparte.", + "personal": "Personal", + "personalDetails": "Datos personales", + "personalDetailsDescription": "Información de identidad de esta persona.", + "location": "Ubicación", + "locationDescription": "Nos ayuda a verificar quién es y dónde se encuentra.", + "review": "Revisión", + "reviewCreate": "Revisar y crear", + "reviewCreateDescription": "Confirma que todo esté correcto antes de crear.", + "adding": "Agregando", + "screening": "Verificación", + "addAccount": "Agregar cuenta", + "cryptoAccountAttached": "Cuenta cripto vinculada", + "label": "Etiqueta", + "accountLabelPlaceholder": "p. ej., Wallet de Solana de Alice", + "network": "Red", + "selectNetwork": "Seleccionar red", + "walletAddress": "Dirección de la Wallet", + "destinationWalletAddress": "Dirección de la Wallet de destino", + "screeningUnavailable": "No pudimos revisar esta dirección: la verificación de cumplimiento no está disponible. ¿Deseas agregarla de todos modos?", + "screeningWarning": "Una o más verificaciones marcaron esta Wallet o no se pudieron completar. ¿Deseas agregarla de todos modos?", + "holdToAddAnyway": "Mantén presionado para agregar de todos modos", + "searchAddress": "Buscar dirección", + "searchAddressPlaceholder": "Buscar dirección o empresa…", + "failedToLoadPlaceDetails": "No se pudieron cargar los detalles del lugar", + "searchFailed": "Error al buscar.", + "searching": "Buscando…", + "noMatches": "No se encontraron coincidencias.", + "updating": "Actualizando…", + "searchToPreviewAddress": "Busca para previsualizar la dirección", + "complianceScreening": "Verificación de cumplimiento", + "checking": "Verificando…", + "directory": "Directorio", + "directoryDescription": "Personas y empresas registradas en tu espacio de trabajo.", + "noCounterparties": "Aún no hay contrapartes", + "noCounterpartiesDescription": "Agrega tu primera persona o empresa para comenzar.", + "type": "Tipo", + "manageCounterparty": "Administrar contraparte", + "counterpartyActions": "Acciones de contraparte", + "transactionDetails": "Detalles de la transacción", + "playgroundProductName": "Contraparte", + "playgroundCounterpartyIdPlaceholder": "ID de contraparte (p. ej., cpty_abc123)", + "listCounterparties": "Listar contrapartes", + "getCounterparty": "Obtener contraparte", + "createCounterparty": "Crear contraparte", + "playgroundEmailPlaceholder": "contact@acme.com", + "playgroundIndividualOnly": "Obligatorio cuando entityType es individual; déjalo en blanco para business.", + "playgroundAddressRequired": "Obligatorio para todos los tipos de entidad.", + "playgroundDateOfBirthPlaceholder": "1990-01-15", + "playgroundPhonePlaceholder": "+14155551234", + "selectEntityType": "Seleccionar tipo de entidad", + "updateCounterparty": "Actualizar contraparte", + "updatedDisplayNamePlaceholder": "Nombre para mostrar actualizado", + "updatedEmailPlaceholder": "actualizado@ejemplo.com", + "noTransactions": "Aún no hay transacciones asociadas a esta contraparte.", + "allTypes": "Todos los tipos", + "identity": "Identidad", + "personalInformation": "Información personal", + "noPersonalInformation": "No hay información personal registrada.", + "externalAccounts": "Cuentas externas", + "noExternalAccounts": "Aún no hay cuentas externas.", + "addExternalAccountTitle": "Agregar cuenta externa", + "manage": "Administrar", + "details": "Detalles", + "transactions": "Transacciones", + "copyAddress": "Copiar dirección", + "addressCopied": "Dirección copiada" + }, + "playground": { + "moonPay": "MoonPay", + "lightspark": "Lightspark", + "bvnk": "BVNK", + "walletIdPlaceholder": "ID de Wallet (p. ej., wal_ops_123)", + "transferIdPlaceholder": "ID de transferencia (p. ej., xfr_123)", + "custodyWalletIdPlaceholder": "ID de Wallet de custodia (p. ej., wal_ops_123)", + "destinationWalletIdPlaceholder": "ID de la Wallet de destino", + "sourceWalletIdPlaceholder": "ID de la Wallet de origen", + "getWalletBalances": "Obtener saldos de Wallet", + "getWalletPolicy": "Obtener política de Wallet", + "updateWalletPolicy": "Actualizar política de Wallet", + "destinationAllowlistPlaceholder": "Direcciones de destino separadas por comas", + "executeTransfer": "Ejecutar transferencia", + "solanaAddressPlaceholder": "Dirección de Solana (32-44 caracteres)", + "usdc": "USDC", + "optionalMemo": "Memo opcional", + "listTransfers": "Listar transferencias", + "getTransfer": "Obtener transferencia", + "createOnrampQuote": "Crear cotización de Onramp", + "selectProvider": "Seleccionar proveedor", + "counterpartyIdPlaceholder": "ID de contraparte (p. ej., cpty_abc123)", + "selectFiatCurrency": "Seleccionar moneda fiat", + "onrampRedirectUrlPlaceholder": "https://app.example.com/payments/onramp/complete", + "createOfframpQuote": "Crear cotización de Offramp", + "offrampRedirectUrlPlaceholder": "https://app.example.com/payments/offramp/complete" + }, + "commandCenter": { + "moveMoney": "Mover dinero", + "moveMoneyDescription": "Inicia el flujo de pago que se ajuste a lo que necesitas hacer.", + "payDescription": "On-chain o fiat", + "depositDescription": "Recibe cripto o fiat", + "requestPayment": "Solicitar pago", + "requestPaymentDescription": "Comparte un QR o enlace patrocinado", + "schedule": "Programar", + "scheduleDescription": "Crea un pago recurrente", + "availableBalance": "Saldo disponible", + "availableBalanceDescription": "Distribuido en {count} {walletLabel}", + "balanceUnavailable": "El saldo no está disponible temporalmente.", + "activity": "Actividad", + "activityDescription": "Últimas transferencias, lotes, depósitos y pagos salientes.", + "activityUnavailable": "La actividad no está disponible temporalmente.", + "transfers": "Transferencias", + "batches": "Lotes", + "typeDirection": "Tipo", + "amount": "Monto", + "upcomingOpen": "Próximos y abiertos", + "upcomingOpenDescription": "Tareas que podrían necesitar tu atención.", + "activeSchedules": "Programaciones activas", + "openRequests": "Solicitudes de pago abiertas", + "upcomingUnavailable": "Los próximos pagos no están disponibles temporalmente.", + "paymentNetwork": "Red de pagos", + "paymentNetworkDescription": "Contrapartes guardadas y destinos de pagos salientes.", + "counterpartiesReady": "Contrapartes listas: {count}", + "counterparties": "contrapartes", + "providersEnabled": "proveedores habilitados", + "networkUnavailable": "La red de pagos no está disponible temporalmente.", + "manageCounterparties": "Administrar contrapartes", + "viewRecurring": "Ver pagos recurrentes", + "viewRequests": "Ver solicitudes de pago" + }, + "totalSdpBalance": "Saldo total de SDP", + "aggregatedAcrossWallets": "Sumado en {count} {walletLabel}.", + "wallet": "Wallet", + "wallets": "Wallets", + "noUsdValuedAssets": "Aún no hay filas de activos valorados en USD.", + "recentTransactions": "Transacciones recientes", + "recentTransactionsDescription": "Última actividad de transferencias en todas las Wallets de la organización.", + "viewAllTransactions": "Ver todas las transacciones", + "refreshing": "Actualizando...", + "refresh": "Actualizar", + "noTransactions": "Aún no se encontraron transacciones.", + "status": "Estado", + "transfer": "Transferencia", + "asset": "Activo", + "direction": "Dirección", + "counterpartyLabel": "Contraparte", + "signature": "Firma", + "createdLabel": "Creado", + "pending": "Pendiente", + "expired": "Vencida", + "unknown": "Desconocido", + "unavailable": "No disponible", + "deposit": "Depositar", + "pay": "Pagar", + "transferDetails": { + "providerFee": "Comisión del proveedor", + "networkFee": "Tarifa de red", + "exchangeRate": "Tipo de cambio", + "fees": "Tarifas", + "provider": "Proveedor", + "transactionId": "ID de transacción", + "providerReference": "Referencia del proveedor", + "memo": "Memo", + "cashPickupCode": "Código de retiro en efectivo", + "moneygramTransactionId": "ID de transacción de MoneyGram", + "payoutStatus": "Estado del pago saliente", + "payoutAmount": "Monto del pago saliente", + "cryptoTransferId": "ID de transferencia cripto", + "solanaSignature": "Firma de Solana", + "moneygramError": "Error de MoneyGram", + "lastUpdated": "Última actualización", + "copy": "Copiar {label}" + }, + "requestFailed": "La solicitud falló.", + "submitting": "Enviando...", + "sendTransfer": "Enviar transferencia", + "sendBatch": "Enviar lote", + "reviewAction": "Revisar", + "processing": "Procesando", + "verificationPending": "Verificación pendiente", + "completeVerification": "Completar verificación", + "previous": "Anterior", + "goToTransaction": "Ir a la transacción", + "method": "Método", + "wizardSummaryTitle": "Tus selecciones", + "viewSummary": "Ver resumen", + "payoutCurrency": "Moneda del pago saliente", + "whoAreYouPaying": "¿A quién le estás pagando?", + "whoIsThisDepositFrom": "¿De quién es este depósito?", + "howWouldYouLikeToPay": "¿Cómo te gustaría pagar?", + "howWouldYouLikeToDeposit": "¿Cómo te gustaría depositar?", + "playgroundProductName": "Pagos", + "recurring": { + "emptyResponse": "{request} devolvió una respuesta vacía.", + "counterpartyStepTitle": "¿Para quién es este pago recurrente?", + "destination": "Destino", + "destinationStepTitle": "¿Adónde deben ir los pagos?", + "details": "Detalles", + "detailsStepTitle": "Configura los detalles del pago", + "reviewStepTitle": "Revisar pago recurrente", + "everyDay": "Cada día", + "collectDaily": "Cobrar una vez al día.", + "everyWeek": "Cada semana", + "collectWeekly": "Cobrar una vez por semana.", + "everyThirtyDays": "Cada 30 días", + "collectMonthly": "Cobrar aproximadamente una vez al mes.", + "custom": "Personalizado", + "customScheduleDescription": "Ingresa un intervalo en horas.", + "notSet": "No configurado", + "customInterval": "Intervalo personalizado", + "everyHour": "Cada hora", + "everyHours": "Cada {count} horas", + "notSelected": "No seleccionado", + "destinationAccount": "Cuenta de destino", + "fundingWallet": "Wallet de fondeo", + "amount": "Monto", + "billingInterval": "Intervalo de facturación", + "firstPayment": "Primer pago", + "afterActivation": "Después de la activación", + "metadata": "Metadatos", + "creatingPayment": "Creando pago recurrente.", + "paymentCreated": "Pago recurrente creado.", + "pendingActivationDescription": "Está pendiente de activación.", + "unableToCreate": "No se pudo crear el pago recurrente.", + "paymentNotCreated": "El pago recurrente no se creó.", + "createPayment": "Crear pago recurrente", + "loadingAccounts": "Cargando cuentas", + "noSolanaAccounts": "No hay cuentas de Solana registradas", + "selectDestinationAccount": "Selecciona una cuenta de destino", + "searchAccounts": "Buscar cuentas", + "needsCryptoAccount": "Esta contraparte necesita una cuenta de Wallet cripto activa en Solana antes de que puedas crear un pago recurrente.", + "addSolanaAddress": "Agregar dirección de Solana", + "noDestinationWallet": "{name} aún no tiene una Wallet de destino registrada.", + "attachDestinationWallet": "Vincula otra Wallet de destino para esta contraparte.", + "selectFundingWallet": "Selecciona una Wallet de fondeo", + "searchWallets": "Buscar Wallets", + "asset": "Activo", + "noTokenBalances": "No hay saldos de Tokens compatibles", + "selectAsset": "Selecciona un activo", + "selectWalletFirst": "Primero selecciona una Wallet", + "searchAssets": "Buscar activos", + "unresolvedTokenBalances": "Esta Wallet tiene saldos de Tokens, pero aún no se pudieron resolver sus símbolos.", + "nativeSolUnsupported": "Los pagos recurrentes requieren un saldo de Token. SOL nativo no es compatible.", + "invalidAmount": "Ingresa un monto mayor que cero.", + "intervalHours": "Intervalo en horas", + "invalidInterval": "Ingresa un número entero de horas entre 1 y 8760.", + "invalidFirstPayment": "Elige una fecha y hora futuras.", + "startAfterActivation": "Deja en blanco para comenzar después de la activación.", + "metadataUrl": "URL de metadatos", + "metadataUrlPlaceholder": "https://example.com/metadata.json", + "invalidMetadataUrl": "Ingresa una URL válida de menos de 128 caracteres.", + "optional": "Opcional.", + "pendingRecordDescription": "Esto crea un registro de pago recurrente pendiente. La activación es un paso independiente.", + "pendingActivation": "Activación pendiente", + "activating": "Activando", + "active": "Activo", + "updating": "Actualizando", + "canceling": "Cancelando", + "resuming": "Reanudando", + "paused": "Pausado", + "canceled": "Cancelado", + "expired": "Vencido", + "pending": "Pendiente", + "processing": "Procesando", + "collected": "Cobrado", + "failed": "Fallido", + "skipped": "Omitido", + "recurringPayments": "Programaciones de pago", + "recurringPaymentCount": "Pagos recurrentes: {count}", + "oneRecurringPayment": "1 pago recurrente", + "unableToLoad": "No se pudieron cargar los pagos recurrentes", + "noPayments": "Aún no hay pagos recurrentes.", + "paymentsAppearHere": "Los registros de pagos recurrentes creados aparecerán aquí.", + "interval": "Intervalo", + "nextPayment": "Próximo pago", + "counterpartyUnavailable": "Contraparte no disponible", + "payment": "Pago recurrente", + "receivingWallet": "Wallet receptora", + "starts": "Inicia", + "currency": "Moneda", + "paymentReference": "Referencia de pago", + "openMetadata": "Abrir metadatos", + "created": "Creado", + "updated": "Actualizado", + "edit": "Editar", + "copyValue": "Copiar valor", + "copied": "Copiado", + "openSignature": "Abrir firma", + "collectionHistory": "Historial de cobros", + "showingAttempts": "Mostrando {shown} de {total} intentos", + "oneAttempt": "1 intento", + "attempts": "Intentos: {count}", + "unableToLoadCollectionHistory": "No se pudo cargar el historial de cobros: {error}", + "noCollectionAttempts": "Aún no hay intentos de cobro. El próximo cobro programado se muestra arriba.", + "due": "Vence", + "attempted": "Intentado", + "transfer": "Transferencia", + "explorer": "Explorador", + "everyWeeks": "Cada {count} semanas", + "everyDays": "Cada {count} días", + "paymentActivated": "Pago recurrente activado.", + "collectionSubmitted": "Cobro del pago recurrente enviado.", + "paymentCanceled": "Pago recurrente cancelado.", + "paymentResumed": "Pago recurrente reanudado.", + "activationFailed": "Error de activación", + "collectionFailed": "Error de cobro", + "cancellationFailed": "Error de cancelación", + "resumeFailed": "Error al reanudar", + "retryActivation": "Reintentar activación", + "activate": "Activar", + "retryCollection": "Reintentar cobro", + "collectNow": "Cobrar ahora", + "retryResume": "Reintentar reanudación", + "resume": "Reanudar", + "retryCancellation": "Reintentar cancelación", + "cancel": "Cancelar", + "actions": "Acciones", + "editPayment": "Editar pago", + "stopFutureCollections": "Detener cobros futuros", + "copyError": "Copiar error", + "readyToActivate": "Listo para activar", + "readyToActivateDescription": "Crea la suscripción y programa el primer pago.", + "lifecycleActionUnavailable": "Acción de ciclo de vida no disponible", + "lifecycleActionUnavailableDescription": "Este pago recurrente no se puede modificar desde su estado actual.", + "updatingPayment": "Actualizando pago recurrente.", + "actionFailed": "La acción del pago recurrente falló.", + "alreadyFundingWallet": "{wallet} ya es la Wallet de fondeo.", + "updatingFundingWallet": "Actualizando Wallet de fondeo.", + "fundingWalletUpdated": "Wallet de fondeo actualizada.", + "fundingWalletUpdateFailed": "Error al actualizar la Wallet de fondeo", + "paymentUpdateFailed": "Error al actualizar el pago recurrente.", + "selectReceivingWallet": "Selecciona una Wallet receptora.", + "alreadyReceivingWallet": "{wallet} ya es la Wallet receptora.", + "updatingReceivingWallet": "Actualizando Wallet receptora.", + "receivingWalletUpdated": "Wallet receptora actualizada.", + "receivingWalletUpdateFailed": "Error al actualizar la Wallet receptora", + "alreadySet": "{value} ya está configurado.", + "updatingBillingInterval": "Actualizando intervalo de facturación.", + "billingIntervalUpdated": "Intervalo de facturación actualizado.", + "billingIntervalUpdateFailed": "Error al actualizar el intervalo de facturación", + "selectCurrency": "Selecciona una moneda.", + "alreadyCurrency": "{currency} ya es la moneda.", + "updatingCurrency": "Actualizando moneda.", + "currencyUpdated": "Moneda actualizada.", + "currencyUpdateFailed": "Error al actualizar la moneda", + "updatingAmount": "Actualizando monto.", + "amountUpdated": "Monto actualizado.", + "amountUpdateFailed": "Error al actualizar el monto", + "editFundingWallet": "Editar Wallet de fondeo", + "editFundingWalletDescription": "Elige la Wallet usada para fondear este pago recurrente.", + "editReceivingWallet": "Editar Wallet receptora", + "editReceivingWalletDescription": "Elige hacia dónde este pago recurrente envía los fondos.", + "editAmount": "Editar monto", + "editAmountDescription": "Configura el monto que se cobra en cada período de facturación.", + "editBillingInterval": "Editar intervalo de facturación", + "editBillingIntervalDescription": "Elige con qué frecuencia debe cobrar este pago recurrente.", + "editCurrency": "Editar moneda", + "editCurrencyDescription": "Elige un saldo de Token de la Wallet de fondeo.", + "cancelPaymentTitle": "¿Cancelar pago recurrente?", + "cancelPaymentDescription": "Esto detiene los cobros futuros para {counterparty}. Puedes reanudar el pago más tarde desde el menú Acciones.", + "keepPayment": "Mantener pago", + "cancelPayment": "Cancelar pago", + "save": "Guardar" + }, + "transactions": { + "searchPlaceholder": "Busca ID, firma, dirección, referencia o contraparte (3 o más caracteres)", + "clearSearch": "Borrar búsqueda de transacciones", + "filters": "Filtros", + "activeFilters": "Filtros activos: {count}", + "clearFilters": "Borrar filtros", + "allStatuses": "Todos los estados", + "allDirections": "Todas las direcciones", + "allTypes": "Todos los tipos", + "allWallets": "Todas las Wallets", + "allCounterparties": "Todas las contrapartes", + "allProviders": "Todos los proveedores", + "assetPlaceholder": "Activo o mint", + "fromDate": "Fecha desde", + "toDate": "Fecha hasta", + "sort": "Ordenar", + "newest": "Más recientes primero", + "oldest": "Más antiguos primero", + "amountHigh": "Monto: de mayor a menor", + "amountLow": "Monto: de menor a mayor", + "statusAscending": "Estado: A a Z", + "inbound": "Entrante", + "outbound": "Saliente", + "transfer": "Transferencia", + "confidentialTransfer": "Transferencia confidencial", + "batchTransfer": "Transferencia por lotes", + "onramp": "On-ramp", + "offramp": "Off-ramp", + "pending": "Pendiente", + "processing": "Procesando", + "confirmed": "Confirmada", + "finalized": "Finalizada", + "failed": "Fallida", + "awaitingPayment": "Esperando pago", + "settling": "Liquidando", + "completed": "Completada", + "canceled": "Cancelada", + "expired": "Vencida", + "transaction": "Transacción", + "status": "Estado", + "amount": "Monto", + "direction": "Dirección", + "counterparty": "Contraparte", + "counterpartyId": "ID de contraparte", + "wallet": "Wallet", + "provider": "Proveedor", + "created": "Creado", + "range": "{start}–{end} de {total}", + "noMatches": "Ninguna transacción coincide con estos filtros.", + "emptyProject": "Aún no hay transacciones.", + "loadError": "No se pudieron cargar las transacciones.", + "retry": "Reintentar", + "viewDetails": "Ver transacción {id}", + "details": "Detalles de la transacción", + "loadingDetails": "Cargando detalles de la transacción", + "detailLoadError": "No se pudieron cargar los detalles de la transacción.", + "transactionId": "ID de transacción", + "type": "Tipo", + "source": "Origen", + "destination": "Destino", + "signature": "Firma", + "providerReference": "Referencia del proveedor", + "memo": "Memo", + "updated": "Actualizado", + "viewOnExplorer": "Ver en Solana Explorer", + "unavailable": "No disponible", + "loadingOptions": "Cargando opciones…", + "includeObserved": "Incluir depósitos on-chain", + "filterType": "Tipo", + "filterDirection": "Dirección", + "filterWallet": "Wallet", + "filterCounterparty": "Contraparte", + "filterProvider": "Proveedor", + "filterAsset": "Activo" + }, + "requests": { + "loadFailed": "No se pudieron cargar las solicitudes de pago", + "awaitingPayment": "Esperando pago", + "paid": "Pagada", + "canceled": "Cancelada", + "expired": "Vencida", + "paymentLinkCreated": "Enlace de pago creado", + "createPaymentRequest": "Crear solicitud de pago", + "createPaymentLink": "Crear enlace de pago", + "createPaymentLinkDescription": "Solicita un pago fijo a una de tus Wallets.", + "amount": "Monto", + "token": "Token", + "selectToken": "Selecciona un Token", + "destinationWallet": "Wallet de destino", + "selectWallet": "Selecciona una Wallet", + "fromCounterparty": "De (contraparte)", + "anyoneWithLink": "Cualquiera con el enlace", + "loadingCryptoAccount": "Cargando cuenta cripto…", + "paysFrom": "Paga desde", + "noCryptoAccount": "No hay una cuenta cripto registrada.", + "add": "Agregar", + "linkExpires": "El enlace vence", + "noExpiry": "Sin vencimiento", + "oneHour": "1 hora", + "twentyFourHours": "24 horas", + "sevenDays": "7 días", + "thirtyDays": "30 días", + "cancel": "Cancelar", + "creating": "Creando…", + "createLink": "Crear enlace", + "paymentRequests": "Solicitudes de pago", + "paymentRequestsDescription": "Enlaces compartibles que solicitan un pago fijo.", + "create": "Crear", + "noPaymentRequests": "Aún no hay solicitudes de pago", + "noPaymentRequestsDescription": "Crea un enlace de pago para solicitar un pago fijo.", + "from": "De", + "to": "A", + "paymentRequestDetails": "Detalles de la solicitud de pago", + "paymentRequest": "Solicitud de pago", + "amountRequested": "Monto solicitado", + "paymentLinkCopied": "Enlace de pago copiado", + "copy": "Copiar", + "reference": "Referencia", + "expires": "Vence", + "destinationWalletId": "ID de la Wallet de destino", + "splMintAddress": "Dirección de mint SPL", + "listRequests": "Listar solicitudes de pago", + "createRequest": "Crear solicitud de pago", + "playgroundProductName": "Solicitudes de pago" + } + } +} diff --git a/apps/sdp-web/messages/es/dashboard-policies.json b/apps/sdp-web/messages/es/dashboard-policies.json new file mode 100644 index 000000000..5cbe1e6c2 --- /dev/null +++ b/apps/sdp-web/messages/es/dashboard-policies.json @@ -0,0 +1,49 @@ +{ + "DashboardPolicies": { + "all": "Todos", + "wallets": "Wallets", + "apiKeys": "Claves de API", + "searchPlaceholder": "Buscar Wallets o claves de API", + "clearSearch": "Borrar búsqueda", + "allStatuses": "Todos los estados", + "defaultAllow": "Permitir por defecto", + "draft": "Borrador", + "active": "Activo", + "disabled": "Deshabilitado", + "configureControls": "Configurar controles", + "walletControls": "Controles de la Wallet", + "apiKeyControls": "Controles de la clave de API", + "target": "Objetivo", + "status": "Estado", + "defaultAction": "Acción predeterminada", + "rules": "Reglas", + "bindings": "Vinculaciones", + "lastUpdated": "Última actualización", + "actions": "Acciones", + "wallet": "Wallet", + "apiKey": "Clave de API", + "allow": "Permitir", + "deny": "Denegar", + "approvalRequired": "Aprobación requerida", + "review": "Revisar", + "noRestrictions": "Sin restricciones", + "ruleCount": "Reglas: {count}", + "singleRule": "1 regla", + "allWallets": "Todas las Wallets", + "selectedWalletCount": "Wallets seleccionadas: {count}", + "singleSelectedWallet": "1 Wallet seleccionada", + "configureWalletControls": "Configurar controles", + "viewAudit": "Ver auditoría", + "viewRevisions": "Ver revisiones", + "configureScope": "Configurar alcance", + "viewBindings": "Ver vinculaciones", + "noMatches": "Ningún control coincide con estos filtros.", + "clearFilters": "Borrar filtros", + "emptyProject": "No hay controles de Wallet o de clave de API configurados.", + "emptyProjectWallets": "No hay controles de Wallet configurados.", + "emptyProjectApiKeys": "No hay controles de clave de API configurados.", + "loadError": "No se pudieron cargar los controles de políticas.", + "retry": "Reintentar", + "range": "{start}–{end} de {total}" + } +} diff --git a/apps/sdp-web/messages/es/dashboard-private-channels.json b/apps/sdp-web/messages/es/dashboard-private-channels.json new file mode 100644 index 000000000..41ccbce1d --- /dev/null +++ b/apps/sdp-web/messages/es/dashboard-private-channels.json @@ -0,0 +1,298 @@ +{ + "DashboardPrivateChannels": { + "tabs": { + "overview": "Resumen", + "channels": "Canales", + "deposit": "Depositar", + "transfer": "Transferir", + "withdraw": "Retirar", + "members": "Miembros", + "events": "Eventos", + "instance": "Instancia" + }, + "common": { + "loadError": "Ocurrió un error al cargar esta sección.", + "cancel": "Cancelar", + "amountUsdc": "Monto (USDC)", + "amountPlaceholder": "1.5", + "onChainBalance": "On-chain:", + "channelBalance": "Saldo del canal:", + "amountRequired": "Ingresa un monto de USDC.", + "amountInvalid": "Ingresa un monto de USDC mayor que cero con hasta 6 decimales.", + "amountWithUnit": "{amount} USDC" + }, + "overview": { + "title": "Resumen", + "description": "Estado en vivo de tu instancia conectada.", + "gateway": "Gateway", + "solanaVersion": "Versión de Solana", + "slot": "Slot", + "latestBlockhash": "Blockhash más reciente", + "escrowInstance": "Instancia de escrow", + "escrowProgram": "Programa de escrow", + "authService": "Servicio de autenticación", + "ready": "Listo", + "degraded": "Degradado — {reason}", + "unreachable": "Inaccesible — {error}", + "onChain": "On-chain", + "notExecutable": "No ejecutable", + "reachable": "Accesible", + "notReachable": "Inaccesible", + "ownerMismatch": "discrepancia de propietario" + }, + "verifiedWallets": { + "title": "Wallets verificadas", + "description": "Verifica una Wallet de custodia contra esta instancia para desbloquear transacciones. Verificar firma un desafío con la Wallet; revocar la elimina.", + "loadError": "No se pudieron cargar tus Wallets. Actualiza la página para volver a intentarlo.", + "noWallets": "No se encontraron Wallets para el usuario, crea una.", + "createWallet": "Crear una Wallet", + "verified": "Verificada", + "verify": "Verificar", + "revokeTitle": "Revocar verificación", + "revokeAria": "Revocar verificación para {pubkey}", + "orphaned": "Wallet de custodia ya no aparece en la lista", + "verifySuccess": "Wallet {key} verificada.", + "revokeSuccess": "Verificación de {key} revocada.", + "channelBalanceTooltip": "Saldo del canal para el mint {mint}", + "channelBalanceAmount": "{amount} USDC" + }, + "channels": { + "title": "Canales", + "description": "Los canales lógicos agrupan la actividad dentro de tu instancia conectada. El canal predeterminado se crea automáticamente y no se puede eliminar.", + "newChannel": "Nuevo canal", + "namePlaceholder": "Nombre del canal (por ejemplo, Tesorería)", + "descriptionPlaceholder": "Descripción (opcional)", + "add": "Agregar", + "empty": "Aún no hay canales.", + "defaultBadge": "Predeterminado", + "created": "Creado el {date}", + "deleteAria": "Eliminar {name}", + "deleteDefaultTitle": "El canal predeterminado no se puede eliminar", + "deleteTitle": "Eliminar canal", + "nameRequired": "El nombre del canal es obligatorio.", + "createSuccess": "Canal “{name}” creado.", + "deleteSuccess": "Canal “{name}” eliminado." + }, + "members": { + "title": "Miembros", + "description": "Invita a usuarios del proyecto SDP a tu espacio de trabajo de Canales Privados y administra a qué canales pertenecen.", + "countOne": "{count} miembro invitado a este espacio de trabajo.", + "countOther": "{count} miembros invitados a este espacio de trabajo.", + "inviteMember": "Invitar miembro", + "empty": "Aún no hay miembros. Invita a un usuario del proyecto SDP para comenzar.", + "columnEmail": "Correo", + "columnName": "Nombre", + "columnVerifiedWallets": "Wallets verificadas", + "columnChannels": "Canales", + "columnActions": "Acciones", + "verifiedCount": "Verificadas: {count}", + "addToChannel": "Agregar al canal", + "defaultSuffix": "(predeterminado)", + "removeFromAria": "Quitar de {label}", + "delete": "Eliminar", + "inviteAria": "Invitar miembro", + "inviteTitle": "Invitar miembro", + "inviteDescription": "Elige un usuario del proyecto SDP para invitar. Se creará una credencial de SPC para esa persona.", + "projectUser": "Usuario del proyecto", + "selectUser": "Selecciona un usuario…", + "pickedName": "Nombre: {name}", + "inviting": "Invitando…", + "invite": "Invitar", + "inviteSuccess": "Se invitó a {email}.", + "inviteUrlCopied": "URL de invitación copiada al portapapeles.", + "deleteAria": "Eliminar miembro", + "removeTitle": "Quitar miembro", + "removeDescription": "Quita a {email} del espacio de trabajo y de todos los canales a los que pertenece. Su credencial de SPC se conserva (SPC no tiene un endpoint para eliminar usuarios), pero queda huérfana respecto a SDP.", + "removing": "Quitando…", + "remove": "Quitar", + "removeSuccess": "Miembro quitado." + }, + "deposit": { + "title": "Depositar", + "description": "Mueve USDC desde una Wallet de custodia hacia el escrow del canal en devnet. Sigue su progreso desde el contrato de escrow hasta la confirmación on-chain.", + "fromWallet": "Desde la Wallet", + "fromWalletHelp": "El depósito se firma desde esta Wallet. Debe tener USDC de devnet (y un poco de SOL).", + "recipient": "Destinatario (opcional)", + "recipientPlaceholder": "Por defecto, la Wallet depositante", + "recipientHelp": "Una dirección de Wallet o walletId para acreditar en el canal. Déjalo en blanco para acreditar esta Wallet.", + "submit": "Depositar", + "submitToast": "Depósito enviado", + "progressLabel": "Depositando", + "failed": "El depósito falló.", + "viewTransaction": "Ver transacción en Solana Explorer", + "newDeposit": "Nuevo depósito", + "stageSentTitle": "Enviado al escrow de devnet", + "stageSentDescription": "Transmitiendo el depósito al programa de escrow en devnet.", + "stageConfirmedTitle": "Confirmado en devnet", + "stageConfirmedDescription": "La transacción de depósito se confirmó on-chain.", + "statusSubmitted": "Enviado", + "statusConfirmed": "Confirmado", + "statusFailed": "Fallido", + "noWalletsBefore": "Aún no tienes Wallets verificadas. Verifica una Wallet de custodia en ", + "noWalletsLink": "Resumen de Canales Privados", + "noWalletsAfter": " y fondéala con USDC de devnet, luego vuelve para depositar.", + "statusPending": "Preparando", + "statusSettled": "Liquidado", + "selectWallet": "Selecciona una Wallet desde la cual depositar." + }, + "withdraw": { + "title": "Retirar", + "description": "Haz burn del saldo del canal de una Wallet de custodia para que el operador libere el USDC correspondiente en devnet. Sigue su progreso desde el burn hasta la liberación en devnet.", + "fromWallet": "Retirar desde", + "fromWalletHelp": "El burn se firma desde esta Wallet. Se debita su saldo del canal.", + "destination": "Liberar a (opcional)", + "destinationPlaceholder": "Por defecto, la Wallet que retira", + "destinationHelp": "Una dirección de devnet o walletId para recibir el USDC liberado. Déjalo en blanco para liberarlo a esta Wallet.", + "submit": "Retirar", + "submitToast": "Retiro enviado", + "progressLabel": "Retirando", + "failed": "El retiro falló.", + "burnSignature": "Firma del burn:", + "viewRelease": "Ver liberación en Solana Explorer", + "newWithdrawal": "Nuevo retiro", + "stageBurnSentTitle": "Burn enviado al canal", + "stageBurnSentDescription": "Transmitiendo el burn a la cadena del canal.", + "stageBurnConfirmedTitle": "Burn confirmado (saldo debitado)", + "stageBurnConfirmedDescription": "El burn se confirmó y se debitó tu saldo del canal.", + "stageReleasedTitle": "Liberado en devnet", + "stageReleasedDescription": "El operador liberó el USDC correspondiente al destino.", + "statusPending": "Pendiente", + "statusSubmitted": "Enviado", + "statusBurnConfirmed": "Burn confirmado", + "statusFailed": "Fallido", + "noWalletsBefore": "Aún no tienes Wallets verificadas. Verifica una Wallet de custodia en ", + "noWalletsLink": "Resumen de Canales Privados", + "noWalletsAfter": " y deposita en el canal, luego vuelve para retirar.", + "statusSettled": "Liquidado", + "selectWallet": "Selecciona una Wallet desde la cual retirar." + }, + "transfer": { + "title": "Transferir", + "description": "Transfiere USDC desde tu Wallet de custodia verificada seleccionada hacia otra Wallet de miembro verificada dentro del mismo canal lógico. Los saldos pertenecen a la Wallet y se comparten entre canales lógicos.", + "noChannels": "No eres miembro de ningún canal privado activo. Pídele a un administrador del canal que te agregue antes de hacer una transferencia.", + "noSourceWallets": "No tienes ninguna Wallet de custodia verificada con la que SDP pueda firmar. Verifica una Wallet aprovisionada en Resumen antes de hacer una transferencia.", + "channel": "Canal", + "channelDefaultSuffix": " (Predeterminado)", + "fromWallet": "Desde la Wallet verificada", + "fromWalletHelp": "La transferencia se firma desde esta Wallet. Se debita su saldo del canal.", + "recipientWallet": "Wallet de destinatario", + "recipientsLoading": "Cargando Wallets de destinatarios verificadas…", + "recipientsRetry": "Reintentar destinatarios", + "recipientsLoadFailed": "No se pudieron cargar las Wallets de destinatarios verificadas.", + "recipientsEmpty": "Ningún otro miembro del canal tiene una Wallet verificada elegible para recibir esta transferencia.", + "selectChannel": "Selecciona un canal.", + "selectSourceWallet": "Selecciona una Wallet de origen verificada.", + "selectRecipient": "Selecciona una Wallet de destinatario verificada.", + "selectChannelForRecipients": "Selecciona un canal para cargar los destinatarios verificados.", + "incomplete": "Completa todos los campos de la transferencia.", + "submit": "Transferir USDC", + "submitFailed": "No se pudo enviar la transferencia. Vuelve a intentarlo con los mismos datos.", + "confirmedToast": "Transferencia confirmada", + "submittedToast": "Transferencia enviada, resultado pendiente", + "failedToast": "La transferencia del canal privado falló.", + "progressLabel": "Transferido", + "senderFallback": "Wallet de origen verificada", + "recipientFallback": "Wallet de destinatario verificada", + "toMemberWallet": "A la Wallet de miembro verificada", + "signature": "Firma de SPC", + "stageConfirmedTitle": "Transferencia confirmada", + "stageConfirmedDescription": "SPC ejecutó la transferencia y se actualizó el saldo del destinatario. Esto es definitivo.", + "stageSubmittedTitle": "Esperando el resultado de la transferencia", + "stageSubmittedDescription": "SPC aceptó la transferencia, pero aún no informó el resultado. Verifica el saldo del destinatario antes de reintentar, para no enviar dos veces.", + "stagePendingTitle": "Resultado del envío desconocido", + "stagePendingDescription": "La transferencia quedó registrada, pero su resultado nunca se registró. Verifica el saldo del destinatario antes de reintentar.", + "stageFailedTitle": "Transferencia fallida", + "stageFailedDescription": "SPC no completó la transferencia, por lo que no se movieron fondos. Puedes intentarlo de nuevo.", + "statusPending": "Pendiente", + "statusSubmitted": "Enviado", + "statusConfirmed": "Confirmado", + "statusFailed": "Fallido", + "newTransfer": "Nueva transferencia", + "tryAgain": "Reintentar" + }, + "events": { + "title": "Eventos", + "description": "Actividad del proyecto para Canales Privados, incluidos eventos de ciclo de vida, miembros, transferencias y errores. El historial se conserva incluso después de que una instancia se desconecta o se elimina.", + "empty": "Aún no hay eventos. Conecta una instancia o crea un canal para iniciar el feed de actividad.", + "columnEvent": "Evento", + "columnCategory": "Categoría", + "columnStatus": "Estado", + "columnWhen": "Cuándo", + "loadMore": "Cargar más", + "familyLifecycle": "Ciclo de vida", + "familyMember": "Miembro", + "familyTransfer": "Transferencia", + "familyError": "Error", + "statusPending": "Pendiente", + "statusConfirmed": "Confirmado", + "statusFailed": "Fallido", + "statusStale": "Desactualizado", + "statusInfo": "Info", + "typeInstanceConnected": "Instancia conectada", + "typeInstanceDisconnected": "Instancia desconectada", + "typeChannelCreated": "Canal creado", + "typeChannelArchived": "Canal archivado", + "typeMemberAdded": "Miembro agregado", + "typeMemberRevoked": "Miembro revocado", + "typeMemberRoleChanged": "Rol de miembro cambiado", + "typeWalletChallengeRequested": "Desafío de Wallet solicitado", + "typeWalletVerified": "Wallet verificada", + "typeWalletVerificationRevoked": "Verificación de Wallet revocada", + "typeDepositSubmitted": "Depósito enviado", + "typeWithdrawalSubmitted": "Retiro enviado", + "typeSpcUnreachable": "Canales Privados inaccesibles", + "typeDepositConfirmed": "Depósito confirmado", + "typeDepositSettled": "Depósito liquidado", + "typeDepositFailed": "Depósito fallido", + "typeWithdrawalConfirmed": "Burn de retiro confirmado", + "typeTransferSubmitted": "Transferencia de miembro enviada", + "typeTransferConfirmed": "Transferencia de miembro confirmada", + "typeTransferFailed": "Transferencia de miembro fallida", + "typeWithdrawalSettled": "Retiro liquidado", + "typeWithdrawalFailed": "Retiro fallido", + "typeDepositAwaitingSpcCredit": "Esperando acreditación en el canal", + "typeWithdrawalReleaseAttemptFailed": "Intento de liberación fallido", + "typeStuckWarning": "Transferencia atascada", + "typeNeedsManualReview": "Requiere revisión manual" + }, + "instance": { + "title": "Conectar canal privado", + "description": "Apunta SDP a una instancia de Canales Privados de Solana.", + "gatewayUrl": "URL del Gateway", + "gatewayPlaceholder": "http://gateway.example:8899", + "chainRpcUrl": "URL del RPC de la cadena", + "chainRpcPlaceholder": "https://devnet.helius-rpc.com/?api-key=…", + "authUrl": "URL de autenticación", + "authPlaceholder": "http://auth.example:8903", + "escrowProgramId": "ID del programa de escrow", + "withdrawProgramId": "ID del programa de retiro", + "escrowInstanceAddr": "Dirección de la instancia de escrow", + "testConnection": "Probar conexión", + "testing": "Probando…", + "connect": "Conectar", + "connecting": "Conectando…", + "disconnect": "Desconectar", + "disconnecting": "Desconectando…", + "delete": "Eliminar", + "deleting": "Eliminando…", + "statusReady": "Listo", + "statusDegraded": "Degradado", + "statusUnreachable": "Inaccesible", + "statusFailed": "Fallido", + "latency": "{ms} ms", + "latencyWithVersion": "{ms} ms · v{version}", + "connectSuccess": "Canal privado conectado.", + "disconnectSuccess": "Canal privado desconectado. Puedes editarlo y volver a conectarlo.", + "deleteSuccess": "Instancia de canal privado eliminada.", + "gatewayLabel": "Gateway:", + "reactivateAria": "Reactivar instancia existente", + "reactivateTitle": "Reactivar instancia existente", + "reactivateDescription": "Esta URL de Gateway ya se conectó a este proyecto anteriormente. Reactivarla sobrescribirá la configuración almacenada en el registro de instancia existente. Todos los datos derivados asociados a ella pasarán a pertenecer a la nueva configuración. Continúa bajo tu propia responsabilidad.", + "reactivate": "Reactivar", + "reactivating": "Reactivando…", + "deleteAria": "Eliminar instancia de canal privado", + "deleteTitle": "Eliminar instancia de canal privado", + "deleteDescription": "Esto eliminará permanentemente el registro de la instancia y todos los datos derivados vinculados a ella (canales, depósitos, transferencias). Esta acción no se puede deshacer." + } + } +} diff --git a/apps/sdp-web/messages/es/shared.json b/apps/sdp-web/messages/es/shared.json new file mode 100644 index 000000000..9e669c1eb --- /dev/null +++ b/apps/sdp-web/messages/es/shared.json @@ -0,0 +1,262 @@ +{ + "tabs": { + "overview": "Resumen", + "apiPlayground": "API Playground" + }, + "authTerms": { + "prefix": "Al usar la aplicación, aceptas los", + "link": "Términos de servicio de la Solana Foundation" + }, + "homeSignedIn": { + "loading": "Cargando...", + "selectOrganization": "Selecciona tu organización", + "selectOrganizationDescription": "Elige o crea una organización para continuar.", + "loadingDashboard": "Cargando tu dashboard..." + }, + "allowlist": { + "comingSoon": "Próximamente", + "description": "La gestión de la Allowlist estará disponible en una futura actualización." + }, + "members": { + "title": "Miembros", + "description": "Personas con acceso a esta organización.", + "invite": "Invitar miembro", + "inviteEmail": "Correo electrónico", + "inviteEmailPlaceholder": "colega@empresa.com", + "inviteRole": "Rol", + "roleAdmin": "Administrador", + "roleMember": "Miembro", + "inviteSubmit": "Enviar invitación", + "inviteSending": "Enviando…", + "inviteSent": "Invitación enviada a {email}.", + "inviteFailed": "No se pudo enviar la invitación: {error}", + "emailRequired": "Ingresa un correo electrónico.", + "columnMember": "Miembro", + "columnRole": "Rol", + "columnJoined": "Fecha de ingreso", + "empty": "Todavía no hay miembros.", + "loadFailed": "No se pudieron cargar los miembros: {error}", + "unnamed": "Sin nombre", + "unnamedMember": "Miembro sin nombre", + "emailUnavailable": "Correo electrónico no disponible", + "statusPending": "Pendiente", + "invitedOn": "Invitado el {date}", + "columnActions": "Acciones", + "copyInviteLink": "Copiar enlace de invitación", + "inviteLinkCopied": "Enlace de invitación copiado.", + "inviteLinkCopyFailed": "No se pudo copiar el enlace de invitación.", + "revokeInvite": "Revocar invitación", + "revoking": "Revocando…", + "revoked": "Invitación a {email} revocada.", + "revokeFailed": "No se pudo revocar la invitación: {error}", + "invitationActions": "Acciones para {email}", + "memberActions": "Acciones para {member}", + "removeMember": "Quitar miembro", + "removeConfirm": "{member} perderá el acceso a esta organización de inmediato. Esta acción no se puede deshacer.", + "removing": "Quitando…", + "removed": "Se eliminó a {member}.", + "removeFailed": "No se pudo eliminar al miembro: {error}", + "cannotRemoveSelf": "No puedes eliminarte", + "cannotRemoveLastAdmin": "No se puede eliminar al último administrador", + "cancel": "Cancelar" + }, + "SharedComponents": { + "copied": "Copiado", + "copy": "Copiar", + "apiDebugLogs": "Registros de depuración de la API", + "pause": "Pausar", + "resume": "Reanudar", + "requestSummary": "Método de la solicitud, duración, resumen para copiar", + "query": "Consulta", + "requestBody": "Cuerpo de la solicitud", + "response": "Respuesta", + "createApiKey": "Crear clave de API", + "selectApiKey": "Seleccionar clave de API", + "selectOrganization": "Seleccionar organización", + "organizations": "Organizaciones", + "projects": "Proyectos", + "current": "Actual", + "noOrganizations": "Todavía no hay organizaciones.", + "noProjects": "Todavía no hay proyectos.", + "locked": "Bloqueado", + "sandboxOnly": "Por ahora solo se admite el modo Sandbox.", + "mainnetSoon": "Compatibilidad con Mainnet próximamente.", + "createOrganization": "Crear organización", + "manageOrganization": "Administrar organización", + "clear": "Borrar", + "disable": "Deshabilitar", + "collapse": "Contraer", + "close": "Cerrar", + "closeModal": "Cerrar modal", + "noRequests": "Todavía no se han capturado solicitudes.", + "noPayload": "No se ha capturado ninguna consulta, cuerpo de solicitud ni respuesta.", + "selectApiEndpoint": "Seleccionar endpoint de la API", + "request": "Solicitud", + "output": "Salida", + "pathParameters": "Parámetros de ruta", + "noPathParameters": "Este endpoint no requiere parámetros de ruta.", + "selectValue": "Seleccionar valor", + "noRequestBody": "Este endpoint no requiere un cuerpo de solicitud JSON.", + "status": "Estado:", + "apiKeyRequired": "Crea primero una clave de API para habilitar solicitudes en vivo en el API Playground.", + "runRequest": "Ejecutar solicitud", + "reset": "Restablecer", + "retry": "Reintentar", + "copyCode": "Copiar código", + "code": "Código", + "example": "Ejemplo", + "pending": "Pendiente", + "durationMilliseconds": "{duration}ms", + "networkDebugSummary": "Pendientes: {pending} · Completadas: {completed}", + "aiInstructions": "Instrucciones de IA", + "pageOf": "Página {page} de {pageCount}", + "previousPage": "Página anterior", + "nextPage": "Página siguiente", + "rowsPerPage": "Filas por página", + "loading": "Cargando…", + "noOptionsAvailable": "No hay opciones disponibles.", + "noSearchMatches": "No hay coincidencias para tu búsqueda.", + "required": "(obligatorio)", + "selectAnOption": "Selecciona una opción", + "search": "Buscar…", + "fillBeforeSending": "completar antes de enviar", + "noValue": "- ninguno", + "aiInstructionIntro": "Usa el endpoint de la API de {productName} {method} {path}.", + "aiPathParameters": "Parámetros de ruta:", + "aiRequestBody": "Cuerpo de la solicitud:", + "aiInstructionOutro": "Devuelve el cuerpo de la respuesta como JSON con formato y señala cualquier error de validación o autenticación.", + "runRequestToInspectOutput": "Ejecuta la solicitud para inspeccionar la salida en vivo de la API de este endpoint.", + "requestFailed": "La solicitud falló", + "ready": "Listo", + "completeRequiredFields": "Completa los campos obligatorios: {fields}", + "invalidJsonField": "{field} debe contener un JSON válido.", + "invalidApiKeyFormat": "Formato de clave de API inválido. Usa un valor de clave sin procesar como sk_test_... o sk_live_... con un sufijo válido.", + "playgroundExecutionFailed": "La ejecución en el Playground falló.", + "requestExecutionFailed": "La ejecución de la solicitud falló." + }, + "dashboardShell": { + "workspace": "Espacio de trabajo", + "openNavigation": "Abrir navegación", + "primaryNavigation": "Principal", + "more": "Más", + "moreDescription": "Ve al resto del dashboard.", + "closeNavigation": "Cerrar navegación", + "sandbox": "Sandbox", + "loadingDashboard": "Cargando dashboard...", + "reloadDashboard": "Recargar dashboard", + "signInToContinue": "Inicia sesión para continuar", + "signInDescription": "Accede al espacio de trabajo de tu organización y a los controles de la Wallet.", + "signIn": "Iniciar sesión", + "selectOrganization": "Selecciona una organización", + "selectOrganizationDescription": "Necesitas una organización para continuar.", + "counterparty": "Contraparte", + "transactions": "Transacciones", + "pay": "Pagar", + "deposit": "Depositar", + "requests": "Solicitudes", + "recurring": "Recurrentes", + "privateChannels": "Canales Privados", + "create": "Crear", + "manage": "Administrar", + "home": "Inicio", + "wallets": "Wallets", + "issuance": "Emisión", + "payments": "Pagos", + "apiKeys": "Claves de API", + "policies": "Políticas", + "newApiKey": "Nueva clave de API", + "editApiKey": "Editar clave de API", + "backToApiKeys": "Volver a claves de API", + "approvals": "Aprobaciones", + "pendingApprovals": "Aprobaciones pendientes: {count}", + "apiDocs": "Docs de API", + "settings": "Configuración", + "language": "Idioma", + "colorTheme": "Tema de color", + "chooseLanguage": "Elegir idioma", + "moreLanguagesHint": "Aquí aparecerán más idiomas a medida que estén disponibles.", + "collapseSidebar": "Contraer barra lateral", + "expandSidebar": "Expandir barra lateral", + "expandPaymentsMenu": "Expandir menú de pagos", + "collapsePaymentsMenu": "Contraer menú de pagos", + "closeNavigationOverlay": "Cerrar superposición de navegación", + "newCounterparty": "Nueva contraparte", + "manageCounterparty": "Administrar contraparte", + "backToCounterparty": "Volver a contraparte", + "backToWallets": "Volver a Wallets", + "backToWalletDetail": "Volver al detalle de la Wallet", + "backToWallet": "Volver a la Wallet", + "walletControls": "Controles de la Wallet", + "createWallet": "Crear Wallet", + "activateProvider": "Activar proveedor", + "newAsset": "Nuevo activo", + "assetManagement": "Administración de activos", + "backToOverview": "Volver al resumen", + "recurringPayments": "Pagos recurrentes", + "recurringPayment": "Pago recurrente", + "backToRecurringPayments": "Volver a pagos recurrentes", + "receive": "Recibir", + "send": "Enviar", + "backToPayments": "Volver a pagos", + "backToApprovals": "Volver a Aprobaciones", + "members": "Miembros", + "allowlist": "Allowlist" + }, + "validation": { + "allowlistValueRequired": "El valor de la Allowlist es obligatorio", + "allowlistEntryIdRequired": "El ID de la entrada de la Allowlist es obligatorio", + "emailRequired": "El correo electrónico es obligatorio" + }, + "pay": { + "productName": "Solana Developer Platform", + "paymentReceived": "Pago recibido", + "paymentReceivedDescription": "Esta solicitud ya fue pagada. No hay nada más que hacer.", + "linkExpired": "Enlace vencido", + "linkExpiredDescription": "Este enlace de pago ya no es válido. Pide al remitente uno nuevo.", + "requestCanceled": "Solicitud cancelada", + "requestCanceledDescription": "Esta solicitud de pago fue cancelada por el remitente.", + "paymentRequest": "Solicitud de pago", + "scanWallet": "Escanea con una Wallet de Solana para pagar", + "openWallet": "Abrir en la Wallet", + "to": "Para", + "token": "Token", + "expires": "Vence", + "noExpiry": "Sin vencimiento", + "securedBySolanaPay": "Protegido por Solana Pay", + "qrCode": "Código QR de Solana Pay" + }, + "homeWorkspace": { + "unavailable": "No disponible", + "createFirstWalletBalances": "Crea tu primera Wallet para empezar a rastrear saldos.", + "noTrackedBalances": "Todavía no se han encontrado saldos rastreados.", + "activityUnavailable": "La actividad no está disponible en este momento.", + "paymentActivityAfterWallet": "La actividad de pagos aparecerá después de que crees una Wallet.", + "noPaymentVolume": "Todavía no se ha registrado volumen de pagos.", + "loadingPaymentActivity": "Cargando actividad de pagos...", + "createFirstWalletActivity": "Crea tu primera Wallet para empezar a rastrear saldos y actividad.", + "noRecentActivity": "Todavía no se ha encontrado actividad reciente.", + "loadingRecentActivity": "Cargando actividad reciente...", + "createWallet": "Crear Wallet", + "totalBalance": "Saldo total", + "todaysVolume": "Volumen de hoy", + "recentTransactions": "Transacciones recientes", + "activityDescription": "Última actividad de Wallets y de emisión en toda la organización.", + "seeAllPayments": "Ver todos los pagos", + "time": "Hora", + "activity": "Actividad", + "type": "Tipo", + "token": "Token", + "amount": "Monto", + "address": "Dirección", + "send": "Enviar", + "receive": "Recibir", + "transfer": "Transferencia", + "untitledToken": "Token sin título", + "unableToLoadIssuanceTokens": "No se pudieron cargar los Tokens de emisión", + "someIssuanceActivityUnavailable": "No se pudo cargar parte de la actividad de emisión.", + "paymentsActivityUnavailable": "La actividad de pagos no está disponible en este momento.", + "issuanceActivityUnavailable": "La actividad de emisión no está disponible en este momento.", + "failedToLoadActivity": "No se pudo cargar la actividad del dashboard", + "balanceDataUnavailable": "Los datos de saldo no están disponibles en este momento." + } +} diff --git a/apps/sdp-web/src/i18n/README.md b/apps/sdp-web/src/i18n/README.md index 6345b1f07..f34a11875 100644 --- a/apps/sdp-web/src/i18n/README.md +++ b/apps/sdp-web/src/i18n/README.md @@ -2,11 +2,11 @@ The dashboard keeps its supported BCP-47 locales in `config.ts` and its English source catalog in `../../messages/en.json`. -Supported locales today: `en`, `fr`. French catalogs live under `../../messages/fr/`. The release workflow restores 100% key parity with English before release; at runtime, a temporarily missing localized key falls back to its English source value. +Supported locales today: `en`, `es`, `fr`. Latin American Spanish catalogs live under `../../messages/es/` and French catalogs under `../../messages/fr/`. The release workflow restores 100% key parity with English before release; at runtime, a temporarily missing localized key falls back to its English source value. -Product PRs add or change copy only in the English source catalogs. Do not update French in the same PR: the release workflow asks Eve to fill missing locale keys on the repository-owned `codex/release-main` branch. The catalog policy verifies both that branch name and its source repository before allowing mixed catalog changes. A dedicated translation-quality PR may change localized catalogs as long as it does not also introduce English source changes. +Product PRs add or change copy only in the English source catalogs. Do not update localized catalogs in the same PR: the release workflow asks Eve to fill missing locale keys on the repository-owned `codex/release-main` branch. The catalog policy verifies both that branch name and its source repository before allowing mixed catalog changes. A dedicated translation-quality PR may change localized catalogs as long as it does not also introduce English source changes. -Eve receives the locale rules in `.github/translation-guidance.json` plus the namespace and nearby approved translations for every new string. That guidance is the terminology source of truth. In French, established product terms such as `Token` and `Wallet` stay in English; literal `jeton` and `portefeuille` variants are rejected by catalog validation. +Eve receives the locale rules in `.github/translation-guidance.json` plus the namespace and nearby approved translations for every new string. That guidance is the terminology source of truth. In French, established product terms such as `Token` and `Wallet` stay in English; literal `jeton` and `portefeuille` variants are rejected by catalog validation. Spanish follows the same convention, rejecting literal `billetera`, `cartera`, and `ficha` variants. Use `await getTranslations()` in Server Components and `useTranslations()` in Client Components. Both accept only keys that exist in the English catalog. For dates, numbers, lists, and relative time, construct the native `Intl` formatter with the resolved locale rather than pinning it to `en-US`. diff --git a/apps/sdp-web/src/i18n/config.ts b/apps/sdp-web/src/i18n/config.ts index 51ebd22df..b4742f273 100644 --- a/apps/sdp-web/src/i18n/config.ts +++ b/apps/sdp-web/src/i18n/config.ts @@ -1,4 +1,4 @@ -export const supportedLocales = ["en", "fr"] as const; +export const supportedLocales = ["en", "es", "fr"] as const; export type AppLocale = (typeof supportedLocales)[number]; diff --git a/apps/sdp-web/src/i18n/messages.ts b/apps/sdp-web/src/i18n/messages.ts index 2a4b2ee0c..7fe47f7eb 100644 --- a/apps/sdp-web/src/i18n/messages.ts +++ b/apps/sdp-web/src/i18n/messages.ts @@ -7,6 +7,14 @@ import dashboardPolicies from "../../messages/en/dashboard-policies.json"; import dashboardPrivateChannels from "../../messages/en/dashboard-private-channels.json"; import shared from "../../messages/en/shared.json"; import en from "../../messages/en.json"; +import esDashboardApprovals from "../../messages/es/dashboard-approvals.json"; +import esDashboardCustody from "../../messages/es/dashboard-custody.json"; +import esDashboardIssuance from "../../messages/es/dashboard-issuance.json"; +import esDashboardPayments from "../../messages/es/dashboard-payments.json"; +import esDashboardPolicies from "../../messages/es/dashboard-policies.json"; +import esDashboardPrivateChannels from "../../messages/es/dashboard-private-channels.json"; +import esShared from "../../messages/es/shared.json"; +import es from "../../messages/es.json"; import frDashboardApprovals from "../../messages/fr/dashboard-approvals.json"; import frDashboardCustody from "../../messages/fr/dashboard-custody.json"; import frDashboardIssuance from "../../messages/fr/dashboard-issuance.json"; @@ -59,6 +67,19 @@ function mergeLocalizedValue(fallback: unknown, localized: unknown): unknown { ); } +const esCatalog = { + ...es, + ...esDashboardApprovals, + ...esDashboardCustody, + ...esDashboardIssuance, + ...esDashboardPayments, + ...esDashboardPolicies, + ...esDashboardPrivateChannels, + Shared: esShared, +} satisfies LocalizedMessages; + +const esMessages = mergeLocalizedMessages(enMessages, esCatalog); + const frCatalog = { ...fr, ...frDashboardApprovals, @@ -84,6 +105,7 @@ export type TranslationValues = Record; const messagesByLocale: Record = { en: enMessages, + es: esMessages, fr: frMessages, }; diff --git a/apps/sdp-web/src/i18n/messages.unit.test.ts b/apps/sdp-web/src/i18n/messages.unit.test.ts index 986125dbb..25b44da24 100644 --- a/apps/sdp-web/src/i18n/messages.unit.test.ts +++ b/apps/sdp-web/src/i18n/messages.unit.test.ts @@ -20,12 +20,14 @@ function flattenKeys(value: unknown, prefix = ""): string[] { describe("i18n messages", () => { it("only accepts configured locales", () => { expect(isAppLocale("en")).toBe(true); + expect(isAppLocale("es")).toBe(true); expect(isAppLocale("fr")).toBe(true); expect(isAppLocale("de")).toBe(false); }); it("resolves typed catalog entries", () => { expect(translate(getMessages("en"), "Home.trySdp")).toBe("Try SDP"); + expect(translate(getMessages("es"), "Home.contactUs")).toBe("Contáctanos"); expect(translate(getMessages("fr"), "Home.contactUs")).toBe("Nous contacter"); });