docs: translate README into Spanish - #666
ositaemmanuel653-netizen wants to merge 1 commit into
Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughAdded ChangesSpanish README
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related issues
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@AbdulmalikAlayande Recreated this contribution from the latest main to avoid the merge conflicts. Please review the new PR instead. |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@README.es.md`:
- Around line 1-2: Update the README.es.md opening banner so the file begins
with the Markdown top-level heading “# Sorokeep” instead of the HTML paragraph
wrapper, or apply the existing documented MD041 exception consistently to both
README files.
- Around line 594-596: Correct the Spanish wording in the Núcleo architecture
description by replacing “Probable sin red o CLI” with “Probablemente sin red ni
CLI”, while leaving the surrounding architecture descriptions unchanged.
- Around line 132-144: README.es.md requires language tags on all three fenced
blocks: add the text language identifier to the fences for the output example at
lines 132-144, webhook header example at lines 421-423, and project tree at
lines 549-590.
- Around line 16-24: Update the navigation links at README.es.md lines 16-24 to
use the Spanish heading fragments, or add stable explicit anchors for those
headings. Also update README.es.md line 209 so the webhook-signing link targets
the fragment for “Firma de Webhook” or its explicit anchor.
- Line 54: Update the “Local Primero” description in README.es.md to state that
all state is stored locally in a SQLite database, replacing the claim that it is
stored in a queue while preserving the existing Stellar RPC endpoint qualifier.
- Around line 48-50: Reconcile the documented alert-channel support across
README.es.md:48-50, README.es.md:371-379, README.es.md:634-637, and
README.es.md:668-670. Ensure the overview, alerting section, test-coverage
claims, and FAQ consistently list only implemented channels, or add the missing
channel documentation and support; do not leave claims that Webhook and Slack
are the only supported integrations while other channels are advertised.
- Around line 430-434: Update verifySignature to extract the fixed-length
32-byte SHA-256 MAC from the signature, reject invalid formatting without
comparing variable-length values, and use crypto.timingSafeEqual for the MAC
comparison. Ensure the comparison only occurs when both extracted and expected
MAC buffers are exactly 32 bytes.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: c8872368-9d58-4536-905e-587d12da26e3
📒 Files selected for processing (1)
README.es.md
📜 Review details
🧰 Additional context used
🪛 LanguageTool
README.es.md
[style] ~204-~204: Considere alternativas para este anglicismo (recomendable sobre todo en contextos más formales).
Context: ...ck(requerido) | |--url ` | URL POST del webhook (requerido para webhook) | ...
(POST)
[style] ~393-~393: Considere alternativas para este anglicismo (recomendable sobre todo en contextos más formales).
Context: ...bhook se entregan como solicitudes HTTP POST con un cuerpo JSON: ```json { "type"...
(POST)
🪛 markdownlint-cli2 (0.23.2)
README.es.md
[warning] 1-1: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
[warning] 132-132: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
[warning] 209-209: Link fragments should be valid
(MD051, link-fragments)
[warning] 421-421: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
[warning] 549-549: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (1)
README.es.md (1)
4-8: 🗄️ Data Integrity & IntegrationVerify the reciprocal language-switcher links.
The PR objective requires both README files to link to the Spanish version. Confirm that
README.mdlinks toREADME.es.md, and verify thatREADME.pt.mdexists before merge.
| <p align="center"> | ||
| <h1 align="center">Sorokeep</h1> |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Resolve the MD041 heading warning.
markdownlint reports MD041 because the file starts with <p> instead of a Markdown top-level heading. Replace the banner with # Sorokeep, or configure the same documented exception for both README files.
🧰 Tools
🪛 markdownlint-cli2 (0.23.2)
[warning] 1-1: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@README.es.md` around lines 1 - 2, Update the README.es.md opening banner so
the file begins with the Markdown top-level heading “# Sorokeep” instead of the
HTML paragraph wrapper, or apply the existing documented MD041 exception
consistently to both README files.
Source: Linters/SAST tools
| <a href="#install">Instalación</a> | ||
| · | ||
| <a href="#quick-start">Inicio Rápido</a> | ||
| · | ||
| <a href="#commands">Comandos</a> | ||
| · | ||
| <a href="#alerting">Alertas</a> | ||
| · | ||
| <a href="#contributing">Contribución</a> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Fix the translated heading fragments.
The navigation still uses English fragments after the headings were translated. These links do not resolve in README.es.md.
README.es.md#L16-L24: update the links to the Spanish heading fragments or add explicit stable anchors.README.es.md#L209-L209: replace#webhook-signingwith the fragment forFirma de Webhook, or add an explicit anchor.
📍 Affects 1 file
README.es.md#L16-L24(this comment)README.es.md#L209-L209
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@README.es.md` around lines 16 - 24, Update the navigation links at
README.es.md lines 16-24 to use the Spanish heading fragments, or add stable
explicit anchors for those headings. Also update README.es.md line 209 so the
webhook-signing link targets the fragment for “Firma de Webhook” or its explicit
anchor.
Source: Linters/SAST tools
| - **Alertas** — Notificaciones multicanal respaldadas por colas y desacopladas (Webhook con HMAC-SHA256, Slack Block Kit, Discord, Telegram, PagerDuty) con una robusta lógica de reintentos para TTLs bajos, picos de uso de recursos y cambios de estado | ||
| - **Auto-Extensión** — Extensión automática del TTL basada en políticas con simulación de transacciones antes del envío a través de `ExtendFootprintTTLOp` | ||
| - **Restauración** — Recupera entradas archivadas a través de `RestoreFootprintOp` con simulación previa al envío |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Reconcile the documented alert-channel support.
The overview and alerting sections list Webhook, Slack, Discord, Telegram, and PagerDuty. The FAQ says that only Webhook and Slack are supported. This contradiction can cause users to configure unsupported integrations.
README.es.md#L48-L50: document only implemented channels, or add documentation for the additional channels.README.es.md#L371-L379: align the alerting overview with actual channel support.README.es.md#L634-L637: align the test-coverage claims with implemented channels.README.es.md#L668-L670: update the FAQ or remove unsupported channels from the earlier sections.
📍 Affects 1 file
README.es.md#L48-L50(this comment)README.es.md#L371-L379README.es.md#L634-L637README.es.md#L668-L670
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@README.es.md` around lines 48 - 50, Reconcile the documented alert-channel
support across README.es.md:48-50, README.es.md:371-379, README.es.md:634-637,
and README.es.md:668-670. Ensure the overview, alerting section, test-coverage
claims, and FAQ consistently list only implemented channels, or add the missing
channel documentation and support; do not leave claims that Webhook and Slack
are the only supported integrations while other channels are advertised.
| - **Seguimiento de Costos y Recursos** — Rastrea el historial de extensiones, costos en XLM, proyecciones a 30 días, registros de uso de recursos e impone presupuestos mensuales configurables para evitar gastos descontrolados | ||
| - **Inspección** — Inspecciona el estado en la cadena, analiza saldos de tokens SAC y compara cambios de estado | ||
| - **Canales** — Gestiona cuentas de canal financiadas para envíos de transacciones concurrentes sin cuellos de botella en la secuencia | ||
| - **Local Primero** — Todo el estado se almacena en una cola respaldada por una base de datos SQLite. Sin servicios externos más allá de un endpoint RPC de Stellar |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Describe SQLite as the state store.
Line [54] says that all state is stored in a queue backed by SQLite. A queue is only one subsystem. This contradicts Line [521]. Use: Todo el estado se almacena localmente en una base de datos SQLite.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@README.es.md` at line 54, Update the “Local Primero” description in
README.es.md to state that all state is stored locally in a SQLite database,
replacing the claim that it is stored in a queue while preserving the existing
Stellar RPC endpoint qualifier.
| ``` | ||
| $ sorokeep watch CDLZFC3S...CYSC --network testnet --name "XLM Native Token" | ||
|
|
||
| ✔ Contract XLM Native Token registered successfully. | ||
|
|
||
| Contract: XLM Native Token (CDLZFC3S...CYSC) | ||
| Network: testnet | ||
| Entries: 1 discovered | ||
| Instance TTL: 113,918 ledgers (~7d 6h) OK | ||
|
|
||
| Run 'sorokeep status CDLZFC3S...CYSC' to check TTLs anytime. | ||
| Run 'sorokeep guard CDLZFC3S...CYSC' to enable auto-extension. | ||
| ``` |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Add language tags to the fenced blocks.
markdownlint reports MD040 for these blocks. Add text to the fences.
README.es.md#L132-L144: output example.README.es.md#L421-L423: webhook header example.README.es.md#L549-L590: project tree.
🧰 Tools
🪛 markdownlint-cli2 (0.23.2)
[warning] 132-132: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
📍 Affects 1 file
README.es.md#L132-L144(this comment)README.es.md#L421-L423README.es.md#L549-L590
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@README.es.md` around lines 132 - 144, README.es.md requires language tags on
all three fenced blocks: add the text language identifier to the fences for the
output example at lines 132-144, webhook header example at lines 421-423, and
project tree at lines 549-590.
Source: Linters/SAST tools
| function verifySignature(payload, signature, secret) { | ||
| const expected = "sha256=" + createHmac("sha256", secret) | ||
| .update(payload) | ||
| .digest("hex"); | ||
| return signature === expected; |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Locate README files and relevant excerpt:"
fd -a '^README\.es\.md$' . | sed 's#^\./##'
echo
if [ -f README.es.md ]; then
wc -l README.es.md
sed -n '410,445p' README.es.md | nl -ba -v410
fi
echo
echo "Search for similar webhook signature examples in README files:"
rg -n "verifySignature|sha256=|timingSafeEqual|createHmac" README* || true
echo
echo "Check Node crypto timingSafeEqual availability (no repo code execution):"
node - <<'JS'
const { createHmac, timingSafeEqual } = require('node:crypto');
console.log('timingSafeEqual exported:', typeof timingSafeEqual === 'function');
const secret = 'abc';
const payload = 'xyz';
const expected = 'sha256=' + createHmac('sha256', secret).update(payload).digest('hex');
const validSig = expected;
const invalidSig = expected.slice(0, 64) + '000000000000000000000000000000000000000000000000';
const formatUnsafe = 'sha256=' + expected.slice('sha256='.length, 50) + '0000000000000000000000000000000000000000000000000000000000000000';
console.log('valid ===:', validSig === expected);
console.log('invalid ===:', invalidSig === expected);
console.log('valid timingSafeEqual:', timingSafeEqual(Buffer.from(validSig.slice(7), 'hex'), Buffer.from(expected.slice(7), 'hex')));
console.log('invalid timingSafeEqual:', timingSafeEqual(Buffer.from(invalidSig.slice(7), 'hex'), Buffer.from(expected.slice(7), 'hex')));
console.log('formatUnsafe ===:', formatUnsafe === expected);
try {
timingSafeEqual(Buffer.from(formatUnsafe.slice(7), 'hex'), Buffer.from(expected.slice(7), 'hex'));
console.log('formatUnsafe timingSafeEqual:', true);
} catch (e) {
console.log('formatUnsafe timingSafeEqual error:', e.name + ': ' + e.message);
}
JSRepository: AbdulmalikAlayande/sorokeep
Length of output: 297
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Inspect surrounding README context for webhook secret guidance:"
sed -n '1,90p' README.es.md | nl -ba -v1
echo "---"
sed -n '340,460p' README.es.md | nl -ba -v340Repository: AbdulmalikAlayande/sorokeep
Length of output: 269
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "README.es.md excerpt around webhook example:"
sed -n '410,448p' README.es.md
echo
echo "Search for related signature/secret guidance:"
rg -n "verifySignature|sha256=|timingSafeEqual|createHmac|webhook|secre|secret" README.es.m* || true
echo
echo "Node crypto timingSafeEqual behavior:"
node - <<'JS'
const { createHmac, timingSafeEqual } = require('node:crypto');
const secret = 'abc';
const payload = 'xyz';
const expected = 'sha256=' + createHmac('sha256', secret).update(payload).digest('hex');
const validSig = expected;
const invalidSig = expected.slice(0, 64) + '000000000000000000000000000000000000000000000000';
const formatUnsafe = 'sha256=' + expected.slice('sha256='.length, 50) + '0000000000000000000000000000000000000000000000000000000000000000';
console.log('timingSafeEqual exported:', typeof timingSafeEqual === 'function');
console.log('valid ===:', validSig === expected);
console.log('invalid ===:', invalidSig === expected);
console.log('valid timingSafeEqual:', timingSafeEqual(Buffer.from(validSig.slice(7), 'hex'), Buffer.from(expected.slice(7), 'hex')));
console.log('invalid timingSafeEqual:', timingSafeEqual(Buffer.from(invalidSig.slice(7), 'hex'), Buffer.from(expected.slice(7), 'hex')));
console.log('formatUnsafe ===:', formatUnsafe === expected);
try {
timingSafeEqual(Buffer.from(formatUnsafe.slice(7), 'hex'), Buffer.from(expected.slice(7), 'hex'));
console.log('formatUnsafe timingSafeEqual:', true);
} catch (e) {
console.log('formatUnsafe timingSafeEqual error:', e.name + ': ' + e.message);
}
JSRepository: AbdulmalikAlayande/sorokeep
Length of output: 5764
Use a timing-safe webhook signature comparison.
The verifier returns early on bad sha256= formatting, which leaks validation time. Use a fixed-length MAC extraction, then compare only the 32 MAC bytes with crypto.timingSafeEqual.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@README.es.md` around lines 430 - 434, Update verifySignature to extract the
fixed-length 32-byte SHA-256 MAC from the signature, reject invalid formatting
without comparing variable-length values, and use crypto.timingSafeEqual for the
MAC comparison. Ensure the comparison only occurs when both extracted and
expected MAC buffers are exactly 32 bytes.
| - **Comandos** (`src/commands/`) — Capa fina de la CLI. Analiza argumentos, llama al núcleo (core), formatea la salida en la terminal. Sin lógica de negocio. | ||
| - **Núcleo** (`src/core/`) — Lógica de negocio pura. Probable sin red o CLI. El demonio reutiliza las mismas funciones. | ||
| - **RPC** (`src/rpc/`) — Envoltura del SDK de Stellar. Todas las llamadas de red pasan por aquí. Maneja la creación, simulación, firma y envío de transacciones. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Correct the Spanish grammar in the architecture description.
Line [595] says Probable sin red o CLI. Use Probablemente sin red ni CLI.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@README.es.md` around lines 594 - 596, Correct the Spanish wording in the
Núcleo architecture description by replacing “Probable sin red o CLI” with
“Probablemente sin red ni CLI”, while leaving the surrounding architecture
descriptions unchanged.
Adds README.es.md and a language-switcher link in README.md. Ported the contributor's translation of PR #666 (the cleaner of two duplicate submissions — #665 carried unrelated stale-branch commits). Their translation was based on a slightly older README.md (43 of 46 sections) — missing Global Options, the 'contracts' command, and the Supported Channels Comparison table, and the Alerting intro paragraph still listed only 5 of the 11 now-supported channels. Translated the missing sections and corrected the channel list to bring it to full parity with the issue's "every section, no drops" acceptance criterion, keeping the contributor's translation for everything else unchanged. Added tests/docs/readme-spanish.test.ts mirroring the existing readme-portuguese.test.ts coverage pattern.
|
Merged via 7dc567a on main. Thanks for this — the translation quality and register were solid. Your fork was based on a slightly older README.md, so it was missing 3 sections that landed since: Global Options, the Went with your branch over #665 since it was a single clean commit off current main rather than carrying unrelated stale history — closing that one as a duplicate. |
What does this PR do?
Closes #475
README.es.mdcontaining a complete Spanish translation ofREADME.md.README.mdandREADME.es.mdso readers can easily navigate between the English and Spanish versions.Why?
This PR makes Sorokeep more accessible to the Spanish-speaking Stellar and Soroban developer community, particularly across Latin America. It lowers the barrier to entry for developers who prefer reading documentation in Spanish while keeping technical commands consistent with the English documentation.
As noted in the issue, documentation translations require ongoing maintenance as the English README evolves. I'm willing to help keep the Spanish translation in sync with future updates.
Does this touch secret-key handling or transaction submission?
Checklist
npm test) (Not applicable — documentation-only changes.)npx tsc --noEmit) (Not applicable — documentation-only changes.)npm run lint) (Not applicable — documentation-only changes.)console.login core logicNotes
README.es.mdincludes every section present inREADME.md.