De pagina van Evolu Relay op de lijst van de gebruiker
Negen punten uit echt gebruik met 0.4.0, alle negen gedaan. Twee ervan waren onderzoeksvragen en die staan onderaan. Evolu Relay 0.5.0 - Een tijdvenster van twee minuten voor nieuwe eigenaars, met een stopknop. De teller zit in het relay-proces en niet in de pagina: een teller in een tabblad dat je sluit, sluit de deur niet. policy.js kreeg learningUntil, isLearningOpen en expireLearning. - decideOwner kijkt naar isLearningOpen en niet naar het veld learning. De lus die een verlopen venster opruimt loopt elke twee seconden, en in dat gat zou een onbekende alsnog binnenkomen. - Zonder STATE_VERSION te verhogen, met een toets die dat verdedigt: een verhoging zou de allowlist van de draaiende installatie laten afwijzen en de deur sluiten voor eigenaars die er al in stonden. - Labels op een eigenaar-id, in een eigen labels.json met de agent als enige schrijver. Een label zegt niets over toegang, dus de relay hoeft het niet te weten; het is daardoor meteen opgeslagen en werkt ook als de relay omligt. - Geblokkeerde en geweigerde eigenaars in een kader, met een badge die zegt welke van de twee het is. De badge staat buiten het hover-blok, anders is dat onderscheid onzichtbaar tenzij je over de regel gaat. - Maatvoering gelijk aan Electrum Gate: 1760px, hetzelfde raster, icoon van 64 pixels, dezelfde kop, versienummer erachter. Uitleg uit de kaders, knoppen pas bij hover, geen voetregel. Electrum Gate 0.0.24 - Menu-item "About this app", in beide apps. - De statuswidget zei "Answering" met "answered in 7 ms, from inside the app" en zegt nu "Running" met de meting eronder. De nuance dat de controle van container naar container loopt is verplaatst naar een eigen kopje in die dialoog, waar er ruimte voor is; vier woorden waren te weinig. Toetsen en gereedschap - tests/test_relay_agent.py (nieuw, 65 toetsen) en tests/test_paginas_parsen.mjs (nieuw). Muteertests gedraaid op de beslissende regels. - Een dollarteken-toets in test_appstore_vorm.py. Het commentaar in drie bestanden beweerde al dat die test bestond; nu is dat waar. - Een toets dat er geen werkbestanden in een app-map staan. umbreld kopieert de hele map naar het apparaat en in de back-up. - tools/voorbeeldpagina.mjs maakt van een *.template een pagina die je in een browser kunt openen. Dat vond meteen twee echte opmaakfouten. De twee onderzoeksvragen - Een geweigerde eigenaar komt niet in de database: isOwnerAllowed zit in de WebSocket-upgrade, dus het is een 401 en een gesloten socket. Het gewenste gevolg treedt wel op, via de client: die is local-first en levert bij toelating de hele geschiedenis. Blokkeren werkt daarentegen pas bij de volgende verbinding, en dat staat als open punt. - De blobs zijn niet met een xpub te ontcijferen; een OwnerId komt daar niet uit. Met de SLIP-21-node van het apparaat kan het wel, maar die geeft volledige zeggenschap, dus dat hoort niet in een relay. Als plan-punt opgenomen bij de tool in HomeGit/Trezor. Nog niet uitgerold: de image 0.5.0 moet gebouwd en geduwd worden. De digest staat daarom niet in de compose, want een oude digest onder een nieuwe tag levert stil de oude relay. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,46 @@ Wat er nog moet gebeuren staat **niet** hier maar in de plannen; zie [CONTINUE_H
|
||||
Een lijst met geplande features op twee plekken loopt uit elkaar, en dan is geen van beide meer te
|
||||
vertrouwen.
|
||||
|
||||
## [0.0.24] - 2026-08-30
|
||||
|
||||
### Added
|
||||
|
||||
- **Een menu-item "About this app…", met een dialoog erachter.** De marketingtekst stond alleen in
|
||||
`umbrel-app.yml` en dus alleen in de winkel, terwijl je juist ná het installeren nog eens wil kunnen
|
||||
nalezen wat de app voor je doet. Vijf kopjes: waar het voor is, het certificaat, wat er niet in het midden
|
||||
zit, wat de statuswidget bewijst, en welke wallets.
|
||||
|
||||
**Dezelfde toevoeging zit in Evolu Relay**, op verzoek van de gebruiker: het is één store en de twee
|
||||
pagina's horen zich hetzelfde te gedragen.
|
||||
|
||||
### Changed
|
||||
|
||||
- **De statuswidget zei "Answering" en zegt nu "Running".** Gemeld door de gebruiker: die tegel is
|
||||
onduidelijk, en die van Evolu Relay leest meteen. Dat klopt om twee redenen die los van elkaar staan.
|
||||
|
||||
"Answering" is een tegenwoordig deelwoord en leest dus als een handeling die bezig is, niet als een
|
||||
toestand; "Checking" ernaast is er wél een, en dat maakt het erger. En de onderregel "answered in 7 ms,
|
||||
from inside the app" probeerde in vier woorden een nuance te dragen waar vier woorden te weinig voor zijn:
|
||||
wie het niet al weet, leest er niets uit.
|
||||
|
||||
De onderregel is nu "the TLS port answered in 7 ms". **De nuance is niet weggelaten maar verplaatst** naar
|
||||
de nieuwe dialoog, onder een eigen kopje: de controle loopt van container naar container, dus een router
|
||||
die de poort niet meer doorstuurt leest hier alsnog als Running. Haal dat kopje niet weg zonder in de
|
||||
widget iets terug te zetten, want dan staat die bewering nergens meer.
|
||||
|
||||
## [0.0.23] - 2026-08-28
|
||||
|
||||
### Fixed
|
||||
|
||||
- **De pagina kon leeg blijven of oude waarden tonen zodra er een tweede app uit deze store bijkwam.** Hij
|
||||
bereikte zijn agent via de korte containernaam `agent`, en Evolu Relay heeft er ook een op poort 8000.
|
||||
Alle apps van umbrelOS delen één Docker-netwerk, dus Docker verdeelde die naam over beide containers en
|
||||
ongeveer de helft van de verzoeken kwam bij de verkeerde app uit.
|
||||
|
||||
Beide apps wijzen nu naar de volledige naam `<app-id>_agent_1`, en die vorm is per app uniek.
|
||||
`tests/test_appstore_vorm.py` toetst dit voortaan voor élke app in de store, want dit is precies het soort
|
||||
fout dat stil terugkomt bij de volgende app die iemand toevoegt.
|
||||
|
||||
## [0.0.22] - 2026-08-27
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -4,6 +4,83 @@ Nieuwste bovenaan. Elke regel hier hoort bij een `version` in
|
||||
`whatsnext-evolu-relay/umbrel-app.yml`; zonder verhoging van dat nummer rolt umbrelOS een wijziging niet
|
||||
uit.
|
||||
|
||||
**Er hoort een tweede nummer bij: `VERSION` in `tools/evolu-relay/build.sh`, het etiket op de image.** Die
|
||||
twee horen gelijk te zijn. Ze mogen uiteenlopen als er alleen iets in de app-map wijzigt, want dan is er
|
||||
geen nieuwe image, maar sinds 0.5.0 worden ze gelijkgehouden: uiteenlopende nummers waren bij 0.4.0 al
|
||||
verwarrend (manifest 0.4.0, image 0.3.0).
|
||||
|
||||
> **Deze geschiedenis is op 30-08-2026 bijgewerkt en liep tot dat moment achter:** er stond alleen 0.0.1,
|
||||
> terwijl de app op 0.4.0 zat. De entries voor 0.2.0 tot en met 0.4.0 zijn met terugwerkende kracht
|
||||
> geschreven uit de `releaseNotes` in het manifest en uit `PROGRESS.md` van het plan **Umbrelapp**. Ze zijn
|
||||
> daarom korter dan de rest.
|
||||
|
||||
## 0.5.0 - 30-08-2026
|
||||
|
||||
**De statuspagina op de lijst van de gebruiker, na een week met 0.4.0 gewerkt te hebben.** Negen punten,
|
||||
alle negen gedaan.
|
||||
|
||||
**Een tijdvenster van twee minuten in plaats van een schakelaar.** Openzetten, apparaat koppelen, en de deur
|
||||
sluit zichzelf; vroegtijdig sluiten of de twee minuten opnieuw starten kan ook. **De teller loopt in het
|
||||
relay-proces en niet in de pagina**, want een teller in een tabblad dat je sluit, sluit de deur niet.
|
||||
`policy.js` heeft er `learningUntil`, `isLearningOpen` en `expireLearning` voor gekregen, zonder
|
||||
`STATE_VERSION` te verhogen: een verhoging zou de allowlist van de draaiende installatie laten afwijzen.
|
||||
|
||||
**Labels op een eigenaar-id.** Een `OwnerId` is een reeks tekens zonder betekenis; nu kun je er een naam aan
|
||||
hangen. De labels staan in een eigen `labels.json` met de agent als enige schrijver, dus ze zijn meteen
|
||||
opgeslagen en labelen werkt ook als de relay omgevallen is.
|
||||
|
||||
**Geblokkeerde en geweigerde eigenaars in één kader**, met een badge die zegt welke van de twee het is. Wat
|
||||
je ermee doet was toch hetzelfde: toelaten of vergeten.
|
||||
|
||||
**De pagina is gelijkgetrokken met Electrum Gate**: dezelfde breedte van 1760 pixels, hetzelfde raster,
|
||||
hetzelfde icoon van 64 pixels, dezelfde kop en het versienummer erachter. Knoppen verschijnen bij hover over
|
||||
een regel, de uitleggende alinea's zijn verdwenen, en de voetregel is vervangen door een menu-item "About
|
||||
this app" waar die uitleg nu staat.
|
||||
|
||||
**Wat er aan toetsen bij kwam**, want de pagina's waren met bijna drieduizend regels ongetoetst:
|
||||
`tests/test_relay_agent.py` (nieuw), `tests/test_paginas_parsen.mjs` (nieuw), een dollarteken-toets waarvan
|
||||
het commentaar al beweerde dat hij bestond, en een toets dat er geen werkbestanden in een app-map staan.
|
||||
Verder `tools/voorbeeldpagina.mjs`, waarmee een `*.template` in een browser te bekijken is; dat vond meteen
|
||||
twee echte fouten in de nieuwe pagina.
|
||||
|
||||
## 0.4.0 - 28-08-2026
|
||||
|
||||
**Reparatie.** De statuspagina wisselde tussen werken en een foutmelding: hij bereikte zijn agent via de
|
||||
korte containernaam `agent`, en Electrum Gate in deze store heeft er ook een. Ongeveer de helft van de
|
||||
verzoeken kwam bij de verkeerde app uit, en het maakte de pagina van Gate mee kapot. Beide apps wijzen nu
|
||||
naar `<app-id>_agent_1`.
|
||||
|
||||
Verder de tekst die de app aan één cliënt verbond eruit: het is een algemene Evolu-relay. En de uitleg onder
|
||||
de schakelaar voor nieuwe eigenaars klopte niet, die beschreef de open stand ook als hij dicht stond.
|
||||
|
||||
Let op: het manifest stond hier op 0.4.0 terwijl de image 0.3.0 bleef, want er wijzigde niets in het
|
||||
relay-programma.
|
||||
|
||||
## 0.3.0 - 28-08-2026
|
||||
|
||||
**De eerste versie die op de Umbrel draait en gebruikt wordt.** De eigen eigenaars-allowlist erin, met de
|
||||
statuspagina achter de umbrelOS-inlog, en TLS via Zoraxy op een eigen subdomein. Trezor Suite
|
||||
synchroniseert eroverheen, heen én terug; die tweede richting is gemeten met een tweede gebruikersaccount
|
||||
dat met een lege database alle labels binnenkreeg.
|
||||
|
||||
De poorten zijn omgedraaid ten opzichte van 0.0.2: de **pagina** hangt achter de app-proxy mét de inlog, en
|
||||
de **relay** publiceert zijn eigen host-poort 3852. Een sync-cliënt is geen browser met een sessiecookie en
|
||||
zou achter de inlog een inlogpagina krijgen.
|
||||
|
||||
## 0.2.0 - 28-08-2026
|
||||
|
||||
**De relay is vervangen.** Tot 0.0.2 pakketteerde deze app de eigen uitrol van een leverancier, met een
|
||||
quota-manager en een PostgreSQL erbij, en die kon buiten hun eigen dienst in de kern niet werken: cliënten
|
||||
slaan de quota-manager over zodra je ze naar een eigen relay wijst, terwijl die relay elke eigenaar weigert
|
||||
die de quota-manager nooit geregistreerd heeft.
|
||||
|
||||
Hiervoor in de plaats komt de relay van het Evolu-project zelf, aangeroepen uit ons eigen programma in
|
||||
`tools/evolu-relay/`. Gemeten en niet aangenomen: een cliënt synchroniseerde ernaartoe en de data kwam aan.
|
||||
Drie containers werden een relay plus een statuspagina, en de database met zijn wachtwoord is verdwenen.
|
||||
|
||||
Wat wij toevoegen zijn de twee terugroepfuncties die `createRelay` daarvoor heeft, `isOwnerAllowed` en
|
||||
`isOwnerWithinQuota`. De relay zelf is niet nagebouwd en niet aangepast.
|
||||
|
||||
## 0.0.1 - 25-08-2026
|
||||
|
||||
Eerste versie, nog niet geinstalleerd.
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
|
||||
| Plan | App | Volgende stap | Status |
|
||||
|-|-|-|-|
|
||||
| [Umbrelapp](Plannen/Actief/008-Umbrelapp/TAKEN.md) | Relay | **Van A naar B op 28-08-2026: het doel is gehaald.** De app draait als 0.3.0 met een eigen eigenaars-allowlist, een statuspagina achter de umbrelOS-inlog en TLS via Zoraxy op een eigen subdomein, en Trezor Suite synchroniseert eroverheen **heen én terug**; die tweede richting is bewezen met een tweede gebruikersaccount op de Mac dat met een lege database alle labels binnenkreeg. iOS doet niet mee en dat ligt niet aan dit pakket: de `OwnerId` wordt op de Trezor afgeleid, en een model dat niet aan een iPhone kan geeft geen sleutel (open punt 9, met bronregels). Wat nog openstaat is klein en wacht nergens op: een herstart van de app overleven, `python:3-alpine` en `nginx:alpine` pinnen, en data per eigenaar kunnen wissen | 🔶 |
|
||||
| [Umbrelapp](Plannen/Actief/008-Umbrelapp/TAKEN.md) | Relay | **De pagina is op 30-08-2026 verbouwd op de lijst van de gebruiker; 0.5.0 ligt klaar maar is nog niet uitgerold.** Er zit een tijdvenster van twee minuten voor nieuwe eigenaars in (teller in het relay-proces, niet in de browser), labels op een eigenaar-id, de twee lijsten met buitengesloten eigenaars samengevoegd, en de maatvoering gelijk aan Electrum Gate. **De volgende stap kan niet op een laptop en is van de gebruiker:** `sh tools/evolu-relay/build.sh` plus een push, en dan de digest in de compose. Die staat er bewust níet in, want een oude digest onder een nieuwe tag levert stil de oude relay. Verder open en klein: herstart overleven, `python:3-alpine` en `nginx:alpine` pinnen, data per eigenaar wissen | 🔶 |
|
||||
| [Proefopstelling](Plannen/Actief/007-Proefopstelling/TAKEN.md) | Relay | **Volledig ingehaald op 28-08-2026 en klaar voor het archief.** Beide vragen die het nog bezat zijn beantwoord door **Umbrelapp**: Trezor Suite accepteert een eigen relay, en een eigenaar registreren is niet meer nodig sinds de quota-manager eruit is. Wat er in fase 2 en 3 stond gaat over een pakket dat niet meer bestaat. **Eén beslissing van de gebruiker: opheffen of laten staan** | 🔶 |
|
||||
| [Webinterface](Plannen/Actief/005-Webinterface/TAKEN.md) | Gate | **De pagina is af en goedgekeurd, op een breed scherm én op een telefoon (27-08-2026).** Op 28-08-2026 kapotgegaan door de tweede app en gerepareerd in 0.0.23: de korte containernaam `agent` is op het gedeelde Docker-netwerk niet uniek. Van A naar B: wat er nog staat wacht op tijd (het activiteitenlog een etmaal laten lopen) of is een beslissing van de gebruiker (waar Nginx Proxy Manager zijn certificaten neerzet, en of Zoraxy een harde afhankelijkheid wordt) | 🔶 |
|
||||
| [Webinterface](Plannen/Actief/005-Webinterface/TAKEN.md) | Gate | **De pagina is af en goedgekeurd, op een breed scherm én op een telefoon (27-08-2026).** Op 28-08-2026 kapotgegaan door de tweede app en gerepareerd in 0.0.23. In 0.0.24 (30-08-2026) is de statuswidget van "Answering" naar "Running" gegaan en is er een menu-item "About this app" bij gekomen; dat kwam uit het werk aan Evolu Relay, waar de gebruiker de twee pagina's naast elkaar zag. **Nog nakijken op het apparaat, en dat is een blik en geen sessie.** Wat er verder staat wacht op tijd (het activiteitenlog een etmaal laten lopen) of is een beslissing van de gebruiker (waar Nginx Proxy Manager zijn certificaten neerzet, en of Zoraxy een harde afhankelijkheid wordt) | 🔶 |
|
||||
| [Appstore](Plannen/Actief/010-Appstore/TAKEN.md) | Gate | De repo `ElectrumTLS` weghalen op de Git-server; daar staat het domein nog in de historie. **De omschakeling naar Fulcrum is op 27-08-2026 gelukt zonder aanpassing**, dus daarvan is alleen de herstartcontrole nog over, en die komt vanzelf bij de eerstvolgende herstart | 🔶 |
|
||||
|
||||
## C - Wacht op afhankelijkheid
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# Voortgang - Webinterface
|
||||
|
||||
## 30-08-2026 - wat de buur duidelijker deed, is hier overgenomen
|
||||
|
||||
Geen gepland werk aan dit plan. Bij het verbouwen van de pagina van Evolu Relay zag de gebruiker de twee
|
||||
naast elkaar, en toen kwam eruit wat op deze pagina al maanden stond zonder dat iemand erover viel: de
|
||||
statuswidget zei "Answering" met "answered in 7 ms, from inside the app" eronder, en dat is in beide helften
|
||||
onduidelijk. Nu "Running", met de meting eronder.
|
||||
|
||||
**De nuance die daarin zat is niet weg maar verplaatst.** Dat "from inside the app" was er niet voor niets:
|
||||
de agent verbindt van container naar container, dus een router die de poort niet meer doorstuurt leest hier
|
||||
alsnog als in orde. Die bewering staat nu onder een eigen kopje in de nieuwe dialoog "About this app", waar
|
||||
er ruimte is om hem uit te schrijven. Vier woorden waren er te weinig voor.
|
||||
|
||||
Die dialoog is de tweede wijziging, en hij zit in beide apps: de marketingtekst stond alleen in het manifest
|
||||
en dus alleen in de winkel, terwijl je hem ná het installeren nog eens wil kunnen nalezen. Versie 0.0.24.
|
||||
|
||||
## 28-08-2026 - deze pagina ging kapot door een andere app, en dat was te voorzien
|
||||
|
||||
Geen werk aan dit plan; wel een reparatie die er thuishoort. `nginx.conf.template` proxyde naar
|
||||
|
||||
@@ -28,6 +28,22 @@
|
||||
|
||||
## Volgende stap
|
||||
|
||||
- [x] **De statuswidget verduidelijkt en een dialoog "About this app" toegevoegd (30-08-2026, 0.0.24).**
|
||||
Dit kwam niet uit dit plan maar uit het werk aan Evolu Relay: de gebruiker zag de twee pagina's naast
|
||||
elkaar en meldde dat de tegel "Answering / answered in 7 ms, from inside the app" onduidelijk is
|
||||
terwijl "Running" bij de relay meteen leest.
|
||||
|
||||
Dat was op twee losse punten terecht. "Answering" is een tegenwoordig deelwoord en leest als een
|
||||
handeling die bezig is, niet als een toestand, en "Checking" ernaast is er wél een. En "from inside
|
||||
the app" probeerde in vier woorden de nuance te dragen dat deze controle van container naar container
|
||||
loopt en dus niets zegt over de router; vier woorden zijn daar te weinig voor.
|
||||
|
||||
Nu: "Running", met "the TLS port answered in 7 ms" eronder. **De nuance is verplaatst en niet
|
||||
weggelaten**, naar een eigen kopje in de nieuwe dialoog. Dat kopje is dus geen sier: haal je het weg,
|
||||
dan staat die bewering nergens meer.
|
||||
- [ ] **0.0.24 op het apparaat nakijken. Eigenaar: gebruiker.** Alleen de dialoog en de widgettekst zijn
|
||||
gewijzigd, dus het is een blik en geen sessie: opent het menu-item, staat er "Running", en klopt het
|
||||
versienummer in de kop
|
||||
- [x] **0.0.10 op een telefoon nagekeken. In orde (20-08-2026).** De gebruiker meldt dat het er goed uitziet
|
||||
op mobiel. Eén ding kwam eruit: de kopieerknoppen stonden niet op één lijn, omdat de knop door het
|
||||
omvouwen de lengte van het adres volgde. Verholpen in 0.0.11 met `margin-left: auto` op de knop.
|
||||
|
||||
@@ -9,6 +9,50 @@
|
||||
|
||||
## Nog te beslissen
|
||||
|
||||
10. **Wat doen we ermee dat blokkeren pas bij de volgende verbinding werkt?**
|
||||
|
||||
Gevonden op 30-08-2026 bij het uitzoeken van open vraag over geweigerde eigenaars; de bronregels staan
|
||||
in [Upstream-evolu-relay.md](../../../Referenties/Upstream-evolu-relay.md) §10.
|
||||
|
||||
`isOwnerAllowed` wordt door de relay van Evolu aangeroepen in de **WebSocket-upgrade** en daarna nooit
|
||||
meer voor die verbinding. Gevolg: de knop **Block** op de statuspagina houdt een eigenaar buiten bij zijn
|
||||
volgende verbinding, maar niet nu. Zolang zijn socket openstaat, blijft hij schrijven. Bij een
|
||||
sync-cliënt die zijn verbinding lang openhoudt kan dat lang duren.
|
||||
|
||||
Wat er dus scheelt, is niet de knop maar wat hij belooft. Drie wegen, van goedkoop naar goed:
|
||||
|
||||
- **niets doen en het zeggen.** Een regel in de dialoog "About this app" dat blokkeren bij de volgende
|
||||
verbinding ingaat. Kost niets en het is eerlijk, maar het lost het niet op;
|
||||
- **de relay opnieuw laten starten na een block.** Dan vallen alle verbindingen weg en wordt de vraag
|
||||
voor iedereen opnieuw gesteld. Grof, want het raakt ook de eigenaars die niets gedaan hebben, en het
|
||||
is precies het soort ingreep waarvoor deze store geen Docker-socket wil hebben;
|
||||
- **kijken of Evolu een weg biedt om een verbinding te sluiten.** Niet uitgezocht. `createRelay` geeft
|
||||
een `Relay` terug en wat daarop zit is nog niet nagelezen. Dit is de enige weg die het echt oplost.
|
||||
|
||||
Er is nog geen aanleiding om dit nu te doen: er is één gebruiker en die blokkeert zijn eigen apparaten.
|
||||
Het staat hier zodat het niet als verrassing terugkomt.
|
||||
**Moment:** zodra iemand een eigenaar blokkeert die niet van hemzelf is · **Eigenaar:** gebruiker beslist
|
||||
welke van de drie
|
||||
|
||||
11. **Nemen we onderhoudsfuncties op die de inhoud kennen?** - **beslist op 30-08-2026: nee, niet in deze
|
||||
app.**
|
||||
|
||||
De vraag van de gebruiker was of de app de blobs kan ontcijferen, want dan zouden er onderhoudsfuncties
|
||||
bij kunnen. Technisch kan het, maar niet met een xpub: er is een 32-byte SLIP-21-node van het apparaat
|
||||
voor nodig, en die geeft **volledige** zeggenschap over de gegevens van die wallet, niet alleen
|
||||
leesrecht. Zie [Upstream-evolu-relay.md](../../../Referenties/Upstream-evolu-relay.md) §11.
|
||||
|
||||
De reden om het niet te doen is de reden dat deze app bestaat: de hele grond waarop je een relay bij wie
|
||||
dan ook kunt neerzetten, is dat hij de sleutel niet heeft. Zet je hem erin, dan is dat weg, en wel voor
|
||||
de kopie die op een apparaat staat dat aan het internet hangt. De beschrijving in het manifest zegt
|
||||
letterlijk dat de relay de sleutel nooit heeft; dat zou dan niet meer waar zijn.
|
||||
|
||||
**Waar het wél hoort is de tool in `HomeGit/Trezor`**, die al met `trezorlib` tegen het apparaat praat en
|
||||
de sleutel dus legitiem in handen heeft. Daar staat het als plan-punt bij **AdvancedUI**.
|
||||
|
||||
Wat deze app zónder sleutel wél kan blijven doen: rijen per `OwnerId` opruimen. Dat staat al als taak in
|
||||
[TAKEN.md](TAKEN.md) fase 5.
|
||||
|
||||
6. **Pakketteren we wel de juiste relay?** - **beslist op 28-08-2026 door de proef: nee, en het wordt de
|
||||
kale Evolu-relay.** Dit punt blijft hier staan tot de verbouwing gedaan is, want het beschrijft de reden
|
||||
waarom het huidige pakket eruit gaat. De volledige meting staat in [PLAN.md](PLAN.md) §6a.
|
||||
|
||||
@@ -3,6 +3,32 @@
|
||||
> Chronologisch sessielog, nieuwste bovenaan. Kort: 3 tot 6 regels per entry. Wat er is gebeurd en waarom,
|
||||
> niet wat er nog moet: dat staat in [TAKEN.md](TAKEN.md).
|
||||
|
||||
## 30-08-2026 - de pagina op de lijst van de gebruiker, plus twee onderzoeksvragen
|
||||
|
||||
De lijst waar taak "statuspagina verbeteren" op wachtte, kwam er: negen punten uit echt gebruik. Alle negen
|
||||
in één ronde gedaan, als 0.5.0. Het grootste stuk is het **tijdvenster van twee minuten** voor nieuwe
|
||||
eigenaars, en de bepalende keuze daarin is dat de teller in het relay-proces zit en niet in de pagina: een
|
||||
teller in een tabblad dat je sluit, sluit de deur niet. Verder labels op een eigenaar-id, de twee lijsten met
|
||||
buitengesloten eigenaars samengevoegd, en de pagina qua maatvoering gelijkgetrokken met Electrum Gate. Beide
|
||||
apps hebben nu een menu-item "About this app".
|
||||
|
||||
**De twee onderzoeksvragen zijn beantwoord en één premisse bleek fout.** Een geweigerde eigenaar komt níet in
|
||||
de database: `isOwnerAllowed` zit in de WebSocket-upgrade, dus het is een 401 en een gesloten socket. Wat de
|
||||
gebruiker wilde gebeurt alsnog, maar via de cliënt: die is local-first en levert bij toelating de hele
|
||||
geschiedenis. En de blobs zijn niet met een xpub te ontcijferen, want een `OwnerId` wordt niet uit een xpub
|
||||
gemaakt; daar is de SLIP-21-node van het apparaat voor nodig, en die geeft volledige zeggenschap. Dat hoort
|
||||
dus in de Trezor-tool en niet hier.
|
||||
|
||||
**Wat deze ronde onverwacht opleverde was gereedschap.** Een `*.template` is niet in een browser te openen,
|
||||
dus is er nu `tools/voorbeeldpagina.mjs` die er een bekijkbare versie van maakt met nagemaakte gegevens. Dat
|
||||
vond meteen twee echte fouten die ik anders op het apparaat had gevonden: de badges stonden in het hover-blok
|
||||
en waren dus onzichtbaar, en de onzichtbare knoppen namen wél ruimte in de kop waardoor er een kop over twee
|
||||
regels brak. Daarnaast drie nieuwe toetsen, waaronder de dollarteken-toets waarvan het commentaar in drie
|
||||
bestanden al beweerde dat hij bestond.
|
||||
|
||||
**Wat er nog moet en niet op een laptop kan:** de image 0.5.0 bouwen en duwen. De digest staat daarom niet in
|
||||
de compose, want een oude digest onder een nieuwe tag levert stil de oude relay.
|
||||
|
||||
## 28-08-2026 (slot) - de app draait en wordt gebruikt; iOS doet niet mee
|
||||
|
||||
Het pakket is af en geïnstalleerd als 0.3.0. De Mac synchroniseert eroverheen, over TLS via Zoraxy op een
|
||||
|
||||
@@ -16,6 +16,25 @@
|
||||
|
||||
## Volgende stap
|
||||
|
||||
- [ ] **De image 0.5.0 bouwen en duwen, en dan de digest in de compose zetten. Eigenaar: gebruiker.** Dit
|
||||
is de enige stap die 0.5.0 tegenhoudt, en hij kan niet op een laptop: er staat een wijziging in het
|
||||
relay-programma (het tijdvenster) en umbreld kan niet bij een image die alleen lokaal bestaat.
|
||||
|
||||
```
|
||||
sh tools/evolu-relay/build.sh
|
||||
docker login sc.kamenier-hamer.nl
|
||||
docker push sc.kamenier-hamer.nl/sysop/evolu-relay:0.5.0
|
||||
```
|
||||
|
||||
**De digest staat op dit moment níet in de compose**, en dat is met opzet: een oude digest onder een
|
||||
nieuwe tag levert stilzwijgend de oude relay, en dan werkt de timer niet zonder dat iets dat meldt.
|
||||
Ongepind faalt hard en zichtbaar. Zet de digest uit de push-uitvoer erachter zodra hij er is;
|
||||
`test_appstore_vorm.py` drukt de pinstatus af, dus de suite blijft het zeggen tot het gedaan is
|
||||
- [ ] **Daarna op het apparaat nakijken wat een browser moet bewijzen (30-08-2026).** De pagina is met
|
||||
nagemaakte gegevens bekeken en dat vond twee echte fouten, maar drie dingen kan alleen de app zelf
|
||||
zeggen: loopt de teller écht af en gaat de deur dan dicht, blijft een label na een herstart staan, en
|
||||
klopt het adres in het kader "Relay address" (dat gebruikt `window.location.hostname`, en achter de
|
||||
app-proxy is dat een ander adres dan op een laptop)
|
||||
- [x] **De kále Evolu-relay geprobeerd, en hij werkt (28-08-2026).** Trezor Suite op de desktop stuurde
|
||||
elf labels naar `docker.io/evoluhq/relay:latest` en die kwamen aan: de database in het volume groeide
|
||||
van 40960 naar 49152 bytes. **De protocolversie klopt**, en daarmee is de richting uit
|
||||
@@ -100,6 +119,91 @@ Wat er niet staat: iOS doet niets mee, en daardoor is de leeskant nooit gemeten.
|
||||
met de WebSocket-upgrade aan. De handshake-curl uit [PLAN.md](PLAN.md) §6a stap 3 geeft daar
|
||||
`101 Switching Protocols`, en de desktop synchroniseert eroverheen
|
||||
|
||||
## Fase 6 - De statuspagina op de lijst van de gebruiker (0.5.0)
|
||||
|
||||
**De lijst kwam op 30-08-2026, nadat de gebruiker met 0.4.0 gewerkt had.** Negen punten, en alle negen
|
||||
gedaan. Twee ervan waren onderzoeksvragen; die staan onderaan.
|
||||
|
||||
Waarom dit in één ronde kon: de pagina is een `*.template` en zit dus in de update-whitelist. Zodra hij in
|
||||
een eigen image zit (het plan **Eigenimage**) kost elke tweak een bouw plus een digest, en dán is dit
|
||||
duurder. Die volgorde stond als reden bij de vorige taak en is daarmee ingelost.
|
||||
|
||||
- [x] **Gelijkgetrokken met Electrum Gate.** Dezelfde `max-width: 1760px`, hetzelfde raster van twaalf
|
||||
kolommen, hetzelfde icoon van 64 pixels met terugval, dezelfde `t-h1` van 2rem, hetzelfde menu met
|
||||
drie punten, en het versienummer achter de tagline. De pagina leende dat ontwerp al maar op eigen maten
|
||||
- [x] **Een tijdvenster van twee minuten voor nieuwe eigenaars, met een stopknop.** **De teller zit in het
|
||||
relay-proces en niet in de pagina**, en dat is de kern van deze taak: een teller in een tabblad dat je
|
||||
sluit, sluit de deur niet. `policy.js` heeft er een veld `learningUntil` voor gekregen, plus
|
||||
`isLearningOpen` en `expireLearning`
|
||||
- [x] **`decideOwner` kijkt naar `isLearningOpen` en niet naar het veld `learning`.** Dat is geen
|
||||
netheid: de lus die het bestand opruimt loopt elke twee seconden, en in dat gat zou een onbekende
|
||||
alsnog binnenkomen. Muteertest gedaan: de juiste drie toetsen vielen om
|
||||
- [x] **Zonder `STATE_VERSION` te verhogen**, en met een toets die dat verdedigt. Een verhoging zou
|
||||
`normalizeState` het bestand van de draaiende installatie laten afwijzen, en dan schuift `store.js` de
|
||||
allowlist opzij en gaat de deur dicht voor eigenaars die er al in stonden
|
||||
- [x] **Geweigerde en geblokkeerde eigenaars in één kader.** Wat je ermee doet is hetzelfde: toelaten of
|
||||
vergeten. Welke van de twee een regel is, staat als badge op de regel, en die badge staat **buiten**
|
||||
het hover-blok. Dat was de eerste van de twee fouten die de voorbeeldweergave vond: erbinnen was het
|
||||
onderscheid onzichtbaar tenzij je over de regel ging, en dat is juist de informatie waarvoor de twee
|
||||
kaders zijn samengevoegd
|
||||
- [x] **De uitleggende regels eruit.** De koppen zeggen genoeg; wat er te weten valt staat in de nieuwe
|
||||
dialoog. Wat níet weggegooid is maar verplaatst: dat het adres met `http` moet beginnen en niet met
|
||||
`ws`, en wat de relay wel en niet kan zien
|
||||
- [x] **Knoppen alleen bij hover, per regel.** Met opacity en niet met `display: none`, zodat ze met de
|
||||
tab-toets bereikbaar blijven; `focus-within` maakt ze dan zichtbaar, en op een aanraakscherm staan ze
|
||||
altijd aan. Dit had één gevolg dat je niet ziet aankomen: onzichtbare knoppen houden hun ruimte, dus
|
||||
de kop "New owners" brak over twee regels en de waarde stond lager dan in de drie kaders ernaast.
|
||||
Opgelost met kortere knoptekst plus hetzelfde afbreekpunt van 1400px dat Gate gebruikt
|
||||
- [x] **Geen voetregel, en een menu-item "About this app" in plaats daarvan.** In **beide** apps, op verzoek
|
||||
van de gebruiker. Bij Gate staat daar bovendien wat de statuswidget wél en niet bewijst
|
||||
- [x] **Labels op een eigenaar-id, te onderhouden.** Hover een regel en klik **Label**: het veld komt in de
|
||||
plaats van de titel, Enter bewaart, Escape breekt af. **De labels staan in een eigen bestand
|
||||
`labels.json` met de agent als enige schrijver**, en niet in `owners.json`. Drie redenen: één schrijver
|
||||
per bestand blijft de afspraak, een label is meteen opgeslagen in plaats van na de volgende ronde van
|
||||
de relay, en labelen blijft werken als de relay omgevallen is. De relay hoeft dit niet te weten, want
|
||||
een label zegt niets over wie er binnen mag
|
||||
- [x] **De statuswidget van Electrum Gate verduidelijkt**, op de opmerking van de gebruiker dat die van
|
||||
Evolu Relay veel duidelijker is. Er stond "Answering" met "answered in 7 ms, from inside the app"; nu
|
||||
"Running" met de meting eronder, en de nuance staat onder een eigen kopje in de nieuwe dialoog
|
||||
|
||||
### Wat er aan toetsen bij kwam
|
||||
|
||||
De pagina's zijn samen bijna drieduizend regels en er stond geen enkele toets op. Dat blijft zo voor wat ze
|
||||
tonen, maar drie klassen fouten hoeven niet op het apparaat gevonden te worden:
|
||||
|
||||
- [x] **`tests/test_relay_agent.py`** (nieuw, 65 toetsen): de labels en het tijdvenster in de agent. Twee
|
||||
muteertests gedaan
|
||||
- [x] **`tests/test_paginas_parsen.mjs`** (nieuw): loopt de JavaScript van elke pagina, en loopt hij ook nog
|
||||
ná de invulling door umbreld. Muteertest gedaan met een echte syntaxfout
|
||||
- [x] **Een dollarteken-toets in `test_appstore_vorm.py`.** Dit is de valstrik van dit hele project, en het
|
||||
commentaar in drie bestanden beweerde al dat déze test hem dichthield terwijl dat niet zo was. Nu
|
||||
wel. Hij vond meteen twee valse positieven in de eigen opzet (een kaal dollarteken in een
|
||||
commentaarregel, en de exports van een afhankelijkheid), en die zijn in de toets opgelost en niet in
|
||||
de bestanden
|
||||
- [x] **Een toets dat er geen werkbestanden in een app-map staan.** umbreld kopieert de héle app-map naar
|
||||
het apparaat, dus een bewerkbestand van een icoon van 175 kB gaat mee in elke back-up. Die stond er
|
||||
op 30-08-2026
|
||||
- [x] **`tools/voorbeeldpagina.mjs`** (nieuw): maakt van een `*.template` een pagina die je in een browser
|
||||
kunt openen, met de variabelen ingevuld en nagemaakte gegevens erin. Geen toets en geen bewijs, maar
|
||||
het vond in één keer de twee fouten hierboven. Uitvoer komt in `voorbeeld/` en die map is gitignored
|
||||
|
||||
### De twee onderzoeksvragen
|
||||
|
||||
- [x] **"Komen geweigerde eigenaars toch met de hele blow aan instellingen in de database?" Nee.**
|
||||
`isOwnerAllowed` wordt in de WebSocket-**upgrade** aangeroepen; een weigering is een HTTP 401 en een
|
||||
gesloten socket, dus er wordt niets opgeslagen. **Maar het gewenste gevolg treedt wel op**: Evolu is
|
||||
local-first, de cliënt houdt alles zelf en probeert opnieuw, dus alsnog toelaten brengt de hele
|
||||
geschiedenis binnen. De redenering met bronregels staat in
|
||||
[Upstream-evolu-relay.md](../../../Referenties/Upstream-evolu-relay.md) §10, en daar staat ook de
|
||||
scherpe kant: **blokkeren werkt pas bij de volgende verbinding**, want voor een lopende verbinding
|
||||
wordt de vraag nooit opnieuw gesteld. Dat staat als open punt 10 in [OPEN.md](OPEN.md)
|
||||
- [x] **"Kunnen we de blobs ontcijferen met de xpub?" Nee, en de premisse klopt niet.** Een `OwnerId` wordt
|
||||
niet uit een xpub gemaakt: `OwnerId`, `OwnerEncryptionKey` en `OwnerWriteKey` komen alle drie met
|
||||
SLIP-21 uit één 32-byte node die het apparaat aflevert. Dat spoor loopt langs de seed en niet langs
|
||||
BIP32, dus uit een xpub is er niets te halen. **Met die node zelf kan het wél**, en `trezorlib` heeft
|
||||
er een functie voor. Waarom dat níet in deze app hoort, en waar het wél hoort, staat in §11 van
|
||||
hetzelfde document; het plan-punt staat in de repo `HomeGit/Trezor` bij **AdvancedUI**
|
||||
|
||||
## Fase 1 - De app-map
|
||||
|
||||
- [x] **`whatsnext-evolu-relay/` aangemaakt met `umbrel-app.yml` en `docker-compose.yml` (25-08-2026).**
|
||||
@@ -130,11 +234,8 @@ Wat er niet staat: iOS doet niets mee, en daardoor is de leeskant nooit gemeten.
|
||||
zie fase 4. **Let op dat dit één architectuur is** (amd64), want er is alleen amd64 geduwd. Voor de
|
||||
officiele store hoort er een multi-arch index-digest met arm64 in; dat staat bij **Publicatie-Relay**
|
||||
- [x] **De Postgres-pin is vervallen (28-08-2026):** die database zit niet meer in de app
|
||||
- [ ] **De statuspagina verbeteren, op een lijst van de gebruiker.** Hij gaat er eerst mee werken en komt
|
||||
dan met wat er beter moet (28-08-2026). Tot die lijst er is, is dit géén werk: de pagina doet wat hij
|
||||
moet doen. **Doe dit vóór het plan Eigenimage voor deze app**, want zolang de pagina een `*.template`
|
||||
is bereikt elke wijziging een installatie met een push plus versieverhoging; zit hij eenmaal in een
|
||||
image, dan kost elke tweak een bouw en een digest. **Eigenaar: gebruiker levert de lijst**
|
||||
- [x] **De statuspagina verbeteren, op een lijst van de gebruiker.** De lijst kwam op 30-08-2026 en is in
|
||||
één ronde uitgevoerd; zie fase 6 hieronder
|
||||
- [ ] **`python:3-alpine` en `nginx:alpine` pinnen op hun multi-arch index-digest.** Dat zijn de twee laatste
|
||||
ongepinde images van deze app, en ze staan als TODO in de compose. Met
|
||||
`docker buildx imagetools inspect` op de Umbrel. Electrum Gate heeft precies dezelfde twee openstaan,
|
||||
|
||||
@@ -404,3 +404,90 @@ mensen hier tegenaan lopen.
|
||||
waarna de rest lokaal blijft. Dat is een totaal, en het is de grens die hun quota-manager bewaakt. Een
|
||||
zelf-gehoste relay kent die grens niet: wij begrenzen alleen één schrijfactie (zie §8), en dat is dus een
|
||||
echt verschil in wat de app oplevert en geen detail.
|
||||
|
||||
## 10. Wat er met een geweigerde eigenaar gebeurt: niets
|
||||
|
||||
Uitgezocht op 30-08-2026 op de vraag van de gebruiker of een geweigerde eigenaar "toch met de hele blow
|
||||
aan instellingen in de database komt", want dan zou hem daarna toelaten meteen werken. **Het antwoord is
|
||||
nee, en de reden maakt de vraag onbelangrijk.**
|
||||
|
||||
`isOwnerAllowed` wordt aangeroepen in de **WebSocket-upgrade** en niet bij het verwerken van een bericht.
|
||||
De relevante regels uit `packages/nodejs/src/local-first/Relay.ts`:
|
||||
|
||||
```ts
|
||||
const ownerId = requestUrl ? parseOwnerIdFromOwnerWebSocketTransportUrl(requestUrl) : undefined;
|
||||
// ...
|
||||
if (!result.value) { respondAndDestroy(401); return; }
|
||||
```
|
||||
|
||||
Wat daaruit volgt, en elk punt heeft gevolgen voor het pakket:
|
||||
|
||||
1. **de `OwnerId` staat in de URL van de verbinding.** Hij is dus bekend vóórdat er één bericht over de
|
||||
lijn is, en dat is precies waarom deze goedkope toegangscontrole kan bestaan;
|
||||
2. **een weigering is een HTTP 401 en een gesloten socket.** Er komt geen verbinding tot stand, er wordt
|
||||
geen protocolbericht verwerkt, en er wordt **niets** in de SQLite van de relay geschreven. In
|
||||
`Protocol.ts` bestaat geen eigenaarscontrole; daar zit alleen de write-key-validatie, en die code wordt
|
||||
in dit geval nooit bereikt;
|
||||
3. **de wens van de gebruiker komt alsnog uit, alleen via een andere weg.** Evolu is local-first: de
|
||||
cliënt houdt alles zelf en probeert opnieuw. Laat je de eigenaar later toe, dan komt bij de volgende
|
||||
verbinding de héle geschiedenis binnen. Het werkt dus meteen, niet omdat de relay iets bewaard had maar
|
||||
omdat de cliënt niets kwijt was;
|
||||
4. **en dit is de scherpe kant: `isOwnerAllowed` wordt voor een lopende verbinding nooit opnieuw
|
||||
gesteld.** Iemand blokkeren werkt dus pas bij zijn volgende verbinding. Zolang zijn socket openstaat,
|
||||
blijft hij schrijven. Voor een app die "Block" als knop aanbiedt is dat een grens om te kennen; hij
|
||||
staat als open punt in het plan **Umbrelapp**.
|
||||
|
||||
Bron, geraadpleegd 30-08-2026:
|
||||
[`packages/nodejs/src/local-first/Relay.ts`](https://raw.githubusercontent.com/evoluhq/evolu/main/packages/nodejs/src/local-first/Relay.ts)
|
||||
en [`packages/common/src/local-first/Protocol.ts`](https://raw.githubusercontent.com/evoluhq/evolu/main/packages/common/src/local-first/Protocol.ts).
|
||||
|
||||
## 11. De blobs ontcijferen: niet met een xpub, wél met de OwnerSecret
|
||||
|
||||
Uitgezocht op 30-08-2026 op de gedachte van de gebruiker: we hebben de broncode van Trezor Suite en de
|
||||
xpub waarmee deze `OwnerId`'s gemaakt worden, dus zou de app de blobs kunnen ontcijferen en er
|
||||
onderhoudsfuncties bij kunnen krijgen?
|
||||
|
||||
**De premisse klopt niet, en dat is het hele antwoord: een `OwnerId` wordt niet uit een xpub gemaakt.**
|
||||
Uit `suite-common/suite-sync-evolu/src/createEvoluAppOwnerFromTrezorData.ts`, in de lokale kloon:
|
||||
|
||||
```ts
|
||||
const ownerIdBytes = OwnerIdBytes.from(createSlip21(secret, ['OwnerIdBytes']).slice(0, 16));
|
||||
const ownerEncryptionKey = OwnerEncryptionKey.from(createSlip21(secret, ['OwnerEncryptionKey']));
|
||||
const ownerWriteKey = OwnerWriteKey.from(createSlip21(secret, ['OwnerWriteKey']).slice(0, 16));
|
||||
```
|
||||
|
||||
Alle drie komen met **SLIP-21** uit één `secret`, en dat secret is een SLIP-21-node die het apparaat
|
||||
aflevert op het pad `['TREZOR', 'Evolu']` (`core/src/apps/evolu/get_node.py` in de firmware). SLIP-21 is
|
||||
symmetrische afleiding uit de **seed**, langs een heel ander spoor dan de BIP32-afleiding waar een xpub in
|
||||
zit. Een xpub bevat een publieke sleutel en een chaincode van één BIP32-tak; daar is de SLIP-21-wortel niet
|
||||
uit te halen, in geen enkele richting. Dat is geen implementatiedetail maar de bedoeling: §1b legt uit
|
||||
waarom de `OwnerId` juist géén geheim hoeft te zijn.
|
||||
|
||||
**Wat wél werkt is de `OwnerSecret` zelf**, en die is bereikbaar. Suite bewaart hem:
|
||||
`suite-common/suite-sync-storage/src/owner/suiteSyncOwner.ts` heeft naast `ownerId` een veld
|
||||
`ownerSecret` als hex, met in het commentaar "This is an SLIP21 node, it is provided by Trezor Device". En
|
||||
`trezorlib` kan hem opvragen: `python/src/trezorlib/evolu.py` heeft `get_node(session, proof, ...)`, met
|
||||
`get_delegated_identity_key` voor het bewijs dat het apparaat eist.
|
||||
|
||||
**Met die 32 bytes heb je alles**: `OwnerId` om te weten welke rijen bij welke wallet horen,
|
||||
`OwnerEncryptionKey` om te ontsleutelen, `OwnerWriteKey` om te schrijven. Dat is dus geen leesrecht maar
|
||||
volledige zeggenschap over de gegevens van die wallet.
|
||||
|
||||
**En daarom hoort dit niet in deze app.** De hele reden dat je een relay bij wie dan ook kunt neerzetten,
|
||||
is dat hij de sleutel niet heeft. Zet je hem erin, dan is dat weg, en wel voor de kopie die op een
|
||||
apparaat staat dat aan het internet hangt. Onderhoudsfuncties die de inhoud moeten kennen horen aan de
|
||||
kant die de sleutel al heeft. **Dat is de tool in `HomeGit/Trezor`**, die al met `trezorlib` tegen het
|
||||
apparaat praat; het staat daar als plan-punt bij **AdvancedUI**.
|
||||
|
||||
Wat een relay-app zónder sleutel wel kan, en dat is niet niks: rijen per `OwnerId` opruimen. `ownerId` is
|
||||
een systeemkolom in `evolu_message` en `evolu_history` (§8). Dat is schrijven in andermans schema, met de
|
||||
bezwaren die daar staan, maar het vraagt geen sleutel.
|
||||
|
||||
Bronnen, geraadpleegd 30-08-2026 in de lokale klonen (zie §7):
|
||||
|
||||
- `suite-common/suite-sync-evolu/src/createEvoluAppOwnerFromTrezorData.ts`
|
||||
- `suite-common/suite-sync-evolu/src/evoluCreateSuiteSyncOwner.ts`
|
||||
- `suite-common/suite-sync/src/owner/createRetrieveSuiteSyncOwner.ts`
|
||||
- `suite-common/suite-sync-storage/src/owner/suiteSyncOwner.ts`
|
||||
- `trezor-firmware/core/src/apps/evolu/get_node.py`
|
||||
- `trezor-firmware/python/src/trezorlib/evolu.py`
|
||||
|
||||
Reference in New Issue
Block a user