feat(lite): lite wallet foundation (inherited working-tree state)
Preserve the previously-uncommitted lite wallet implementation and related dev WIP under version control: - src/wallet/ lite services: client bridge, bridge runtime, connection, lifecycle, sync, gateway, result parsers, state mapper, artifact contract/resolver, refresh services, UI adapters, wallet_backend/capabilities. (Includes two small M1 fixes: lifecycle walletReady now parses the response; default chain name -> "main".) - src/chat/ chat protocol; tests/fixtures/ (lite + hushchat); tools/hushchat_fixture_check.cpp; scripts/build-lite-backend-artifact.sh. - Pre-existing modified app_network/security/wizard, network_refresh_service, sidebar, mining_tab, bootstrap dialog, and version headers captured as-is. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
27
tests/fixtures/hushchat/CAPTURE_MANIFEST.md
vendored
Normal file
27
tests/fixtures/hushchat/CAPTURE_MANIFEST.md
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# HushChat Capture Manifest
|
||||
|
||||
The capture manifest is a redacted provenance file for a staged directory of real, disposable, non-sensitive SilentDragonXLite HushChat vectors. It does not replace fixture validation; it records that the staged directory was handled under the safety rules required before the Batch 11 strict replacement dry run.
|
||||
|
||||
Copy `templates/capture-manifest.template.json` into the staged fixture directory as `capture-manifest.json`, then change `status` to `staged` and each category `status` to `ready`. Keep the file limited to provenance, handling flags, category filenames, and the dry-run command.
|
||||
|
||||
Validate only the manifest metadata with:
|
||||
|
||||
```sh
|
||||
./build/bin/HushChatFixtureCheck --validate-capture-manifest /path/to/staged/hushchat-fixtures
|
||||
```
|
||||
|
||||
The validator accepts a directory containing `capture-manifest.json` or a direct manifest file path. It prints only a redacted report with schema status, category coverage, handling-flag counts, basenames, and error names.
|
||||
|
||||
The manifest must include:
|
||||
- schema `dragonx.hushchat.capture-manifest.v1`
|
||||
- status `staged`
|
||||
- a redacted manifest id
|
||||
- staged fixture directory name
|
||||
- dry-run command containing `HushChatFixtureCheck --replacement-dry-run`
|
||||
- provenance fields for source client, source client version or commit, capture date, network, and capture method
|
||||
- all required handling flags set to `true`
|
||||
- exactly one entry for each required fixture category
|
||||
|
||||
The manifest must not include passphrases, plaintext, memo contents, private keys, wallet files, ciphertext byte dumps, stored chat key fields, public-key fields, secretstream headers, derived keys, session keys, or any fixture object. The manifest validator rejects known prohibited field names, but it is still a metadata guard rather than a secret scanner.
|
||||
|
||||
After the manifest validates, run the strict replacement dry run against the same staged directory. Pending checked-in fixtures must not be replaced until both commands succeed.
|
||||
40
tests/fixtures/hushchat/IMPORT_CHECKLIST.md
vendored
Normal file
40
tests/fixtures/hushchat/IMPORT_CHECKLIST.md
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
# HushChat Fixture Import Checklist
|
||||
|
||||
This checklist is for replacing the pending placeholders with real, non-sensitive SilentDragonXLite compatibility vectors.
|
||||
|
||||
Do not commit passphrases, plaintext, memo contents from real wallets, private keys, wallet files, or arbitrary ciphertext dumps. Use only disposable test wallets and non-sensitive test messages. The checked-in ready files must contain only the schema fields required by the loader.
|
||||
|
||||
Required categories:
|
||||
- `incoming_memo`: received encrypted Memo vector, expected `ClientRx`
|
||||
- `outgoing_memo`: outgoing-history encrypted Memo vector, expected `ServerTx`
|
||||
- `seed_public_key_projection`: vector proving the SDXL UTF-8-hex seed projection matches the recorded local public key
|
||||
- `corrupted_auth_failure`: structurally valid Memo vector reserved for future authentication-failure verification
|
||||
- `cont_exclusion`: contact request vector that remains excluded from encrypted Memo decrypt preparation
|
||||
|
||||
Capture rules:
|
||||
- Use disposable SilentDragonXLite wallets only.
|
||||
- Use a fixed non-sensitive test phrase and record only its hash if a plaintext expectation is needed.
|
||||
- Do not store decrypted message text in fixture files.
|
||||
- Do not include private keys, viewing keys, spending keys, wallet seed phrases, or wallet database contents.
|
||||
- Keep the top-level `schema` value as `dragonx.hushchat.compat-fixture.v1`.
|
||||
- Change `status` from `pending` to `ready` only when the fixture has the full `fixture` object documented in the protocol spec.
|
||||
- Preserve one fixture file per required category.
|
||||
- For every ready non-`Cont` vector, the stored SDXL chat key string must project to the declared local public key using SDXL's first-32-UTF-8-bytes seed behavior.
|
||||
- The projection check records only byte lengths and match status; it must not write passphrases, plaintext, derived secret keys, memo contents, or ciphertext bytes.
|
||||
- A ready `corrupted_auth_failure` vector must be structurally valid through the same loader, verifier, and projection checks, then marked as requiring a future secretstream authentication failure.
|
||||
- The corrupted-auth marker is not a decrypt result and is not an authentication result.
|
||||
- Run the strict replacement dry-run report against a staged directory before copying any ready files over the checked-in pending placeholders.
|
||||
- The dry-run report must remain redacted; it may contain category names, basenames, status/error names, boolean flags, and counts only.
|
||||
- Add `capture-manifest.json` to the staged directory from `templates/capture-manifest.template.json` and validate it before strict replacement dry-run checks.
|
||||
- The capture manifest records provenance, handling flags, category filenames, and dry-run instructions only; it must not contain fixture objects or sensitive fields.
|
||||
|
||||
Verification flow:
|
||||
|
||||
```sh
|
||||
./build/bin/HushChatFixtureCheck --allow-pending tests/fixtures/hushchat
|
||||
./build/bin/HushChatFixtureCheck --validate-capture-manifest /path/to/staged/hushchat-fixtures
|
||||
./build/bin/HushChatFixtureCheck --replacement-dry-run /path/to/staged/hushchat-fixtures
|
||||
./build/bin/HushChatFixtureCheck tests/fixtures/hushchat
|
||||
```
|
||||
|
||||
The first command is for the current scaffold state and allows pending files. The manifest command validates only redacted staged-directory metadata. The dry-run command is strict, refuses `--allow-pending`, performs no file replacement, and must fail until the staged directory contains all five real ready vectors with no pending, malformed, mismatched, projection-failed, auth-not-ready, or Cont-not-excluded entries. The final command is the post-copy strict check on the checked-in fixture directory; it must report `future_auth_required=1` and `auth_structural_ready=1`. A ready import is acceptable only when the manifest command and both strict fixture commands exit successfully.
|
||||
31
tests/fixtures/hushchat/README.md
vendored
Normal file
31
tests/fixtures/hushchat/README.md
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# HushChat Compatibility Fixtures
|
||||
|
||||
This directory contains the checked-in fixture-file schema for non-sensitive HushChat compatibility vectors.
|
||||
|
||||
The current files are intentionally marked `pending`. They define the exact vector categories and required fields without pretending that real SilentDragonXLite compatibility data has been captured yet.
|
||||
|
||||
Use the developer checker after building:
|
||||
|
||||
```sh
|
||||
./build/bin/HushChatFixtureCheck --allow-pending tests/fixtures/hushchat
|
||||
```
|
||||
|
||||
The command above is expected to pass while files are still pending. Before replacing pending placeholders with real `ready` vectors, run the same command without `--allow-pending`; it exits successfully only when all five required categories are supplied exactly once, pass the fixture loader/import checklist, satisfy the seed/public-key projection verifier, and mark the corrupted-auth vector as structurally ready for a future authentication-failure check.
|
||||
|
||||
For a strict replacement dry run against a staged directory of real vectors, use:
|
||||
|
||||
```sh
|
||||
./build/bin/HushChatFixtureCheck --replacement-dry-run /path/to/staged/hushchat-fixtures
|
||||
```
|
||||
|
||||
The dry-run mode refuses pending vectors and prints only a redacted replacement report with categories, basenames, status/error names, boolean flags, and aggregate counts. It does not copy files or print key material, memo contents, plaintext, ciphertext bytes, or hashes.
|
||||
|
||||
Before running the strict replacement dry run on real staged vectors, add a redacted capture manifest and validate it:
|
||||
|
||||
```sh
|
||||
./build/bin/HushChatFixtureCheck --validate-capture-manifest /path/to/staged/hushchat-fixtures
|
||||
```
|
||||
|
||||
The manifest template lives at `templates/capture-manifest.template.json`. See `CAPTURE_MANIFEST.md` for the metadata rules.
|
||||
|
||||
See `IMPORT_CHECKLIST.md` for the capture rules.
|
||||
7
tests/fixtures/hushchat/cont-exclusion.pending.json
vendored
Normal file
7
tests/fixtures/hushchat/cont-exclusion.pending.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"schema": "dragonx.hushchat.compat-fixture.v1",
|
||||
"status": "pending",
|
||||
"kind": "cont_exclusion",
|
||||
"id": "sdxl-cont-exclusion",
|
||||
"pending_reason": "Needs a non-sensitive Cont fixture proving contact requests remain outside encrypted Memo decrypt handling."
|
||||
}
|
||||
7
tests/fixtures/hushchat/corrupted-auth-failure.pending.json
vendored
Normal file
7
tests/fixtures/hushchat/corrupted-auth-failure.pending.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"schema": "dragonx.hushchat.compat-fixture.v1",
|
||||
"status": "pending",
|
||||
"kind": "corrupted_auth_failure",
|
||||
"id": "sdxl-corrupted-auth-failure",
|
||||
"pending_reason": "Needs a non-sensitive Memo vector that passes structural Batch 1-6 validation but is expected to fail future secretstream authentication."
|
||||
}
|
||||
7
tests/fixtures/hushchat/incoming-memo.pending.json
vendored
Normal file
7
tests/fixtures/hushchat/incoming-memo.pending.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"schema": "dragonx.hushchat.compat-fixture.v1",
|
||||
"status": "pending",
|
||||
"kind": "incoming_memo",
|
||||
"id": "sdxl-incoming-memo",
|
||||
"pending_reason": "Needs a non-sensitive incoming Memo vector captured from SilentDragonXLite with stored chat key hex, public keys, header memo, ciphertext memo, expected role, byte lengths, and plaintext hash only."
|
||||
}
|
||||
7
tests/fixtures/hushchat/outgoing-memo.pending.json
vendored
Normal file
7
tests/fixtures/hushchat/outgoing-memo.pending.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"schema": "dragonx.hushchat.compat-fixture.v1",
|
||||
"status": "pending",
|
||||
"kind": "outgoing_memo",
|
||||
"id": "sdxl-outgoing-memo",
|
||||
"pending_reason": "Needs a non-sensitive outgoing-history Memo vector captured from SilentDragonXLite with stored chat key hex, local and peer public keys, header memo, ciphertext memo, expected server_tx role, byte lengths, and plaintext hash only."
|
||||
}
|
||||
7
tests/fixtures/hushchat/seed-public-key-projection.pending.json
vendored
Normal file
7
tests/fixtures/hushchat/seed-public-key-projection.pending.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"schema": "dragonx.hushchat.compat-fixture.v1",
|
||||
"status": "pending",
|
||||
"kind": "seed_public_key_projection",
|
||||
"id": "sdxl-seed-public-key-projection",
|
||||
"pending_reason": "Needs a non-sensitive vector proving the SilentDragonXLite UTF-8-hex seed projection produces the observed local public key without storing the original passphrase or plaintext."
|
||||
}
|
||||
54
tests/fixtures/hushchat/templates/capture-manifest.template.json
vendored
Normal file
54
tests/fixtures/hushchat/templates/capture-manifest.template.json
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"schema": "dragonx.hushchat.capture-manifest.v1",
|
||||
"status": "template",
|
||||
"id": "replace-with-redacted-capture-manifest-id",
|
||||
"fixture_directory": "replace-with-staged-fixture-directory",
|
||||
"dry_run_command": "./build/bin/HushChatFixtureCheck --replacement-dry-run replace-with-staged-fixture-directory",
|
||||
"provenance": {
|
||||
"source_client": "SilentDragonXLite",
|
||||
"source_client_version": "replace-with-release-or-commit",
|
||||
"capture_date": "YYYY-MM-DD",
|
||||
"network": "replace-with-disposable-test-network",
|
||||
"capture_method": "replace-with-redacted-capture-procedure-name"
|
||||
},
|
||||
"handling": {
|
||||
"disposable_wallets_only": true,
|
||||
"non_sensitive_vectors_only": true,
|
||||
"no_passphrases": true,
|
||||
"no_plaintext": true,
|
||||
"no_memo_contents": true,
|
||||
"no_private_keys": true,
|
||||
"no_wallet_files": true,
|
||||
"no_ciphertext_byte_dumps": true,
|
||||
"no_derived_keys": true,
|
||||
"no_session_keys": true,
|
||||
"redacted_report_only": true
|
||||
},
|
||||
"categories": [
|
||||
{
|
||||
"kind": "incoming_memo",
|
||||
"staged_filename": "incoming-memo.ready.json",
|
||||
"status": "template"
|
||||
},
|
||||
{
|
||||
"kind": "outgoing_memo",
|
||||
"staged_filename": "outgoing-memo.ready.json",
|
||||
"status": "template"
|
||||
},
|
||||
{
|
||||
"kind": "seed_public_key_projection",
|
||||
"staged_filename": "seed-public-key-projection.ready.json",
|
||||
"status": "template"
|
||||
},
|
||||
{
|
||||
"kind": "corrupted_auth_failure",
|
||||
"staged_filename": "corrupted-auth-failure.ready.json",
|
||||
"status": "template"
|
||||
},
|
||||
{
|
||||
"kind": "cont_exclusion",
|
||||
"staged_filename": "cont-exclusion.ready.json",
|
||||
"status": "template"
|
||||
}
|
||||
]
|
||||
}
|
||||
60
tests/fixtures/lite/release_package_manifest.json
vendored
Normal file
60
tests/fixtures/lite/release_package_manifest.json
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"schema": "dragonx.lite.release-package-manifest.v1",
|
||||
"source": "generated-package-manifest-fixture",
|
||||
"generated": true,
|
||||
"packages": [
|
||||
{
|
||||
"name": "ObsidianDragon-full-linux-fixture",
|
||||
"build_kind": "full-node",
|
||||
"format": "linux-zip",
|
||||
"pool_mining_supported": true,
|
||||
"solo_mining_available": true,
|
||||
"full_node_lifecycle_actions_available": true,
|
||||
"expect": {
|
||||
"dragonxd": true,
|
||||
"dragonx_cli": true,
|
||||
"dragonx_tx": true,
|
||||
"sapling_params": true,
|
||||
"asmap": true,
|
||||
"xmrig_when_available": true
|
||||
},
|
||||
"assets": [
|
||||
{ "kind": "app-binary", "path": "ObsidianDragon", "present": true, "executable": true },
|
||||
{ "kind": "dragonxd", "path": "usr/bin/dragonxd", "present": true, "executable": true },
|
||||
{ "kind": "dragonx-cli", "path": "usr/bin/dragonx-cli", "present": true, "executable": true },
|
||||
{ "kind": "dragonx-tx", "path": "usr/bin/dragonx-tx", "present": true, "executable": true },
|
||||
{ "kind": "sapling-spend.params", "path": "usr/bin/sapling-spend.params", "present": true, "executable": false },
|
||||
{ "kind": "sapling-output.params", "path": "usr/bin/sapling-output.params", "present": true, "executable": false },
|
||||
{ "kind": "asmap.dat", "path": "usr/bin/asmap.dat", "present": true, "executable": false },
|
||||
{ "kind": "xmrig", "path": "usr/bin/xmrig", "present": true, "executable": true },
|
||||
{ "kind": "resources", "path": "usr/share/ObsidianDragon/res", "present": true, "executable": false }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ObsidianDragonLite-linux-fixture",
|
||||
"build_kind": "lite",
|
||||
"format": "linux-zip",
|
||||
"pool_mining_supported": true,
|
||||
"solo_mining_available": false,
|
||||
"full_node_lifecycle_actions_available": false,
|
||||
"assets": [
|
||||
{ "kind": "app-binary", "path": "ObsidianDragonLite", "present": true, "executable": true },
|
||||
{ "kind": "xmrig", "path": "xmrig", "present": true, "executable": true },
|
||||
{ "kind": "resources", "path": "res", "present": true, "executable": false }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ObsidianDragonLite-windows-fixture",
|
||||
"build_kind": "lite",
|
||||
"format": "windows-zip",
|
||||
"pool_mining_supported": true,
|
||||
"solo_mining_available": false,
|
||||
"full_node_lifecycle_actions_available": false,
|
||||
"assets": [
|
||||
{ "kind": "app-binary", "path": "ObsidianDragonLite.exe", "present": true, "executable": true },
|
||||
{ "kind": "other", "path": "tools/xmrig.exe", "present": true, "executable": true },
|
||||
{ "kind": "resources", "path": "res", "present": true, "executable": false }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
107
tests/fixtures/lite/result_parsers.json
vendored
Normal file
107
tests/fixtures/lite/result_parsers.json
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
{
|
||||
"info": {
|
||||
"chain_name": "dragonx",
|
||||
"version": "0.1.0",
|
||||
"vendor": "SilentDragonXLite",
|
||||
"latest_block_height": 250001,
|
||||
"difficulty": 42,
|
||||
"longestchain": 250003,
|
||||
"notarized": 249990
|
||||
},
|
||||
"height_object": {
|
||||
"height": 250004
|
||||
},
|
||||
"height_number": 250005,
|
||||
"balance": {
|
||||
"tbalance": 125000000,
|
||||
"zbalance": 230000000,
|
||||
"unconfirmed": 5000000,
|
||||
"verified_zbalance": 180000000,
|
||||
"spendable_zbalance": 170000000
|
||||
},
|
||||
"addresses": {
|
||||
"z_addresses": [
|
||||
"zs1parserfixture0000000000000000000000000000000000000000000000000000",
|
||||
"zs1parserfixture1111111111111111111111111111111111111111111111111111"
|
||||
],
|
||||
"t_addresses": [
|
||||
"RParserFixtureTransparentAddress0000000000001"
|
||||
]
|
||||
},
|
||||
"notes": {
|
||||
"unspent_notes": [
|
||||
{
|
||||
"address": "zs1parserfixture0000000000000000000000000000000000000000000000000000",
|
||||
"created_in_block": 249900,
|
||||
"created_in_txid": "note-txid-1",
|
||||
"value": 100000000,
|
||||
"spent": false,
|
||||
"unconfirmed_spent": false
|
||||
}
|
||||
],
|
||||
"utxos": [
|
||||
{
|
||||
"address": "RParserFixtureTransparentAddress0000000000001",
|
||||
"created_in_block": 249901,
|
||||
"created_in_txid": "utxo-txid-1",
|
||||
"value": 25000000,
|
||||
"spent": false,
|
||||
"unconfirmed_spent": true
|
||||
}
|
||||
],
|
||||
"pending_notes": [
|
||||
{
|
||||
"address": "zs1parserfixture1111111111111111111111111111111111111111111111111111",
|
||||
"created_in_block": 0,
|
||||
"created_in_txid": "pending-note-txid-1",
|
||||
"value": 30000000,
|
||||
"spent": false,
|
||||
"unconfirmed_spent": false
|
||||
}
|
||||
],
|
||||
"pending_utxos": [
|
||||
{
|
||||
"address": "RParserFixtureTransparentAddress0000000000001",
|
||||
"created_in_block": 0,
|
||||
"created_in_txid": "pending-utxo-txid-1",
|
||||
"value": 12000000,
|
||||
"spent": false,
|
||||
"unconfirmed_spent": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"list": [
|
||||
{
|
||||
"txid": "sent-txid-1",
|
||||
"datetime": 1710000000,
|
||||
"block_height": 249950,
|
||||
"unconfirmed": false,
|
||||
"outgoing_metadata": [
|
||||
{
|
||||
"address": "zs1recipientfixture0000000000000000000000000000000000000000000000",
|
||||
"value": 75000000,
|
||||
"memo": "outgoing memo"
|
||||
},
|
||||
{
|
||||
"address": "RRecipientTransparentFixture000000000000001",
|
||||
"value": 5000000,
|
||||
"memo": "transparent memo"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"txid": "receive-txid-1",
|
||||
"datetime": 1710001000,
|
||||
"block_height": 0,
|
||||
"unconfirmed": true,
|
||||
"address": "zs1parserfixture1111111111111111111111111111111111111111111111111111",
|
||||
"amount": 42000000,
|
||||
"memo": "incoming memo",
|
||||
"position": 2
|
||||
}
|
||||
],
|
||||
"syncstatus": {
|
||||
"synced_blocks": 125002,
|
||||
"total_blocks": 250004
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user