Skip to content

keeper, front: hosted deployment (Vercel + Railway) with write authorization and durable session - #28

Merged
Lagouze merged 8 commits into
integration/finalfrom
deploy/vercel-railway
Oct 26, 2026
Merged

Lagouze merged 8 commits into
integration/finalfrom
deploy/vercel-railway

Conversation

@Lagouze

@Lagouze Lagouze commented Oct 26, 2026

Copy link
Copy Markdown
Owner

Ce qui change

Prépare l'hébergement public de Keystone : site statique sur Vercel, keeper dans un conteneur sur Railway. Rien n'est déployé par cette PR. Elle est empilée sur integration/final (PR #27) : son diff ne montre que le déploiement.

  • Autorisation serveur : toute route POST exige Authorization: Bearer <code> (KEEPER_ACCESS_TOKENS, 32 caractères minimum, comparaison à temps constant). Le code n'est jamais dans le bundle : la page le demande une fois et le garde dans le navigateur.
  • Keeper hébergé verrouillé (keeper/src/hosted.ts) : refuse SIGNER=keeper, FUND_SECRET, les origines localhost, l'absence de codes/origines/hôtes, et un dossier de données non inscriptible. Écoute 0.0.0.0 via KEEPER_HOST, hôtes et origines exacts, sonde Railway limitée à GET /api/health.
  • Session durable (keeper/src/store.ts) : sauvegardée dans KEEPER_DATA_DIR, rechargée au démarrage et relue sur la chaîne.
  • Transactions incertaines réconciliées par hash : le hash d'une transaction signée par le keeper est enregistré (sur disque) avant l'envoi. Tant qu'une transaction n'est pas tranchée (SUCCESS / FAILED / hors fenêtre de 200 s), toute écriture et toute préparation de signature sont refusées (PendingTransaction). Aucune double transaction involontaire.
  • /api/config annonce backend et writeAuth ; la page signale un backend factice.
  • Build Vercel : échoue si VITE_KEEPER_URL n'est pas une adresse HTTPS (jamais d'appel vers localhost depuis le site hébergé).
  • Ajoute Dockerfile, railway.json, vercel.json, docs/deploy.md (mode d'emploi, actions humaines, coûts), interfaces v1.4.

Revue

Niveau renforcé (autorisations, interface). Deux passes de sous-agents neufs (diff seul) avec la grille de la section 7.

  • Passe 1 : le hash d'une transaction signée par le keeper n'était pas capturé (le SDK ne l'expose pas) ; la garde se perdait sur un redémarrage pendant l'attente ; une session valide était jetée sur une panne réseau au démarrage ; un échec d'écriture disque était silencieux. Corrigés (hook sur le signataire, vérifié sans envoi sur Testnet : hash identique, 404 sur Horizon).
  • Passe 2 : chain() effaçait la garde pour toute erreur autre qu'un timeout ; save silencieux ; DUPLICATE pris pour un refus ; pas de borne de validité sur les transactions signées dans Freighter ; localhost accepté dans KEEPER_ALLOWED_ORIGINS. Corrigés, avec tests.
  • Reste à la main de l'humain : relecture du diff du keeper (autorisations) par Grégoire/Liel ; aucun changement de contrat.

Tests

  • npm run typecheck : OK. npm test : app 29, keeper 114, shared 16, scripts 13, tous verts. npm run build -w @keystone/app : OK.
  • Keeper hébergé lancé sur le backend fake (aucune transaction) : /health 200, /config indique backend: fake, writeAuth: token, POST sans code ou avec un mauvais code 401 (avec en-tête CORS), mauvais Host/Origin 403, SSE correct.
  • Build avec VERCEL=1 : refusé sans URL, avec localhost ou en HTTP ; accepté en HTTPS.
  • Non testé : docker build (démon Docker arrêté ; étapes rejouées à la main dans un dossier temporaire), comportement chez Railway et Vercel, Yahoo Finance depuis l'adresse du serveur, Freighter depuis le domaine hébergé. Aucune transaction Stellar envoyée par cette PR.

Interfaces

Ajout compatible (v1.4), consommateur : front. KeystoneConfig.backend? et writeAuth?, codes d'erreur Unauthorized (401) et PendingTransaction (409), Authorization: Bearer sur les routes d'écriture d'un keeper hébergé. Comportement local inchangé.

Documentation

README (variables, section « Hosted deployment », limites), docs/deploy.md (nouveau), docs/interfaces.md v1.4, .env.example, .gitignore.

Checklist

  • Revue au niveau requis (sous-agent neuf ; grille renforcée selon AGENTS.md §7)
  • Tests lancés et résultat collé ci-dessus
  • README et documents liés vérifiés et mis à jour si nécessaire
  • Aucun impact non approuvé sur un autre pôle
  • Aucun secret dans le diff

🤖 Generated with Claude Code

Lagouze and others added 5 commits October 26, 2026 06:51
…lway)

Write routes need a team access code, hosted mode refuses the fund key, the session is saved and
reloaded, unconfirmed transactions are reconciled by hash before any new write, /config states the
backend, the front asks for the access code. Adds Dockerfile, railway.json, vercel.json,
docs/deploy.md and interfaces v1.4.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…n network errors

Review fixes: the hash of a keeper-signed transaction is captured at signing through the wallet signer
and saved before the send; a pending entry found after a restart blocks writes; a session is dropped only
when the vault is gone; SIGTERM waits for the write in progress; the data directory is probed at start-up;
streams are capped per address; hosted start-up rules moved to hosted.ts with tests.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ore send, tighten hosted rules

Second review fixes: chain() releases the guard only on a definite outcome; a hash that cannot be
saved stops the send; DUPLICATE is not a refusal; wallet-signed transactions must expire within 200 s;
localhost origins are refused on a hosted keeper; restore no longer holds the listening socket;
the Euribor seed is copied into a fresh data directory; send() is tested with the real signer.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…th on a hosted keeper, add the Render variant

GET /api/health skips the Host check on a hosted keeper only (nothing else does); deploy guide gains a
Render + UptimeRobot variant and the cost/limits of the free tier.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
keystone Ready Ready Preview Oct 26, 2026 8:47am UTC

…rom the landing page

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@Lagouze

Lagouze commented Oct 26, 2026

Copy link
Copy Markdown
Owner Author

[agent:front] Commit 730e764: le Market Advisor s'ouvre aussi depuis la barre du haut du tableau de bord (bouton « Market » quand une session existe), pour pouvoir le montrer sans effacer la session. Lecture seule, aucune route d'écriture. Revue légère par un sous-agent neuf : texte du bouton de fermeture adapté, libellé d'accessibilité ajouté, README mis à jour. Typecheck, 29 tests app et build OK. Vérifié en mode démo dans le navigateur ; non testé sur mobile (375 px) ni sur la Preview Vercel au moment de ce commit.

Lagouze and others added 2 commits October 26, 2026 08:41
…osted proofs), ?demo mode

README: project status, live demo section, architecture diagram, demo instructions, Freighter and hosted-keeper
proofs (read back from Horizon), progress table, known limits. App: ?demo plays the flow on the in-browser mock on
any build, with a link from the access-code window.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…I and third-party disclosure, contract-audit limit

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@Lagouze
Lagouze merged commit 7a57667 into integration/final Oct 26, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant