mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2026-10-29 08:52:04 +00:00
cross-impl: live Python-publishes -> TS-restores relay round trip
Phase F starts the in-process NIP-01 relay, has the real Python NostrClient publish a chunked snapshot to it, then restores that snapshot with the TS CLI on a clean profile and checks the secrets survive. It immediately caught a genuine restore bug: Python's index files wrap the ciphertext in a kdf/ct JSON envelope, and a published snapshot carries whatever the local file held. TS decrypted the fetched bytes directly, so it failed on anything Python published -- invisible to the TS-only tests because TS writes bare ciphertext. Restore (and delta replay) now parse the wrapper first, exactly as decrypt_and_save_index_from_nostr does. Regression test in relay.test.ts publishes a wrapper-format payload through a live relay and restores it. Cutover plan updated: gate 4 (sync protocol) now cites this end-to-end evidence, and gate 5's remaining list drops SSH and migrations. 171 core + 46 CLI tests green; 19/19 cross-implementation checks green. Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
1 parent
1eee053ff0
commit
3ebaced2e3
5 files changed
+173
-11
No files matched your search
@@ -37,6 +37,7 @@ import {
|
||||
fetchLatestSnapshot,
|
||||
fetchDeltasSince,
|
||||
decryptPayload,
|
||||
parseEncryptedFile,
|
||||
mergeIndexPayloads,
|
||||
parseVaultIndex,
|
||||
sha256Hex,
|
||||
@@ -813,8 +814,13 @@ export function buildProgram(io: ProgramIo = defaultIo): Command {
|
||||
const fetched = await fetchLatestSnapshot(pool, keys.privateKeyHex);
|
||||
if (!fetched) throw new Error("no snapshot found on the configured relays");
|
||||
const indexKey = deriveIndexKeyBytes(mnemonic);
|
||||
// A published snapshot carries whatever the local index file held.
|
||||
// Python's index files wrap the ciphertext in a kdf/ct JSON envelope
|
||||
// (TS writes bare ciphertext), so parse the wrapper first — exactly
|
||||
// as Python's decrypt_and_save_index_from_nostr does.
|
||||
const snapshotPayload = parseEncryptedFile(fetched.encrypted).ciphertext;
|
||||
let state = JSON.parse(
|
||||
new TextDecoder().decode(await decryptPayload(indexKey, fetched.encrypted)),
|
||||
new TextDecoder().decode(await decryptPayload(indexKey, snapshotPayload)),
|
||||
) as Record<string, unknown>;
|
||||
|
||||
let deltaCount = 0;
|
||||
@@ -826,7 +832,9 @@ export function buildProgram(io: ProgramIo = defaultIo): Command {
|
||||
);
|
||||
for (const delta of deltas) {
|
||||
const incoming = JSON.parse(
|
||||
new TextDecoder().decode(await decryptPayload(indexKey, delta)),
|
||||
new TextDecoder().decode(
|
||||
await decryptPayload(indexKey, parseEncryptedFile(delta).ciphertext),
|
||||
),
|
||||
);
|
||||
state = mergeIndexPayloads(state, incoming, sha256Hex(delta).slice(0, 16));
|
||||
deltaCount++;
|
||||
|
||||
Reference in new issue
Block a user