From a459ee26c8bd2fb84b6c2e4dfb3e39351616d484 Mon Sep 17 00:00:00 2001 From: reid Date: Tue, 20 Oct 2026 10:54:35 -0500 Subject: [PATCH 1/2] Use shared wallet planner and pin tx-types 0.2.0 --- README.md | 6 + apps/desktop/src/transactions/Composer.svelte | 31 +- apps/desktop/src/transactions/composer.ts | 9 +- .../src/transactions/composer.worker.ts | 37 +- nockster-esp/Cargo.lock | 53 +- nockster-esp/Cargo.toml | 38 +- nockster-esp/Makefile | 4 +- nockster-esp/README.md | 13 + nockster-esp/crates/nockster-cli/Cargo.toml | 2 +- nockster-esp/crates/nockster-core/Cargo.toml | 2 +- .../examples/sign_test_fixture.rs | 25 + .../nockster-core/src/draft_sign/tip5.rs | 2 +- .../nockster-core/src/draft_sign/tx_v1.rs | 724 +--- .../nockster-core/tests/draft_sign_v1.rs | 92 +- nockster-esp/crates/nockster-fw/Cargo.toml | 2 +- .../crates/nockster-wasm/src/compose_v1.rs | 3835 +++-------------- nockster-esp/src-tauri/tauri.conf.json | 2 +- nockster-esp/web/src/composer/Composer.tsx | 44 +- nockster-esp/web/src/composer/nockblocks.ts | 1 + nockster-esp/web/src/composer/storage.ts | 1 + nockster-esp/web/src/composer/types.ts | 1 + packages/wallet-engine/Cargo.lock | 31 +- packages/wallet-engine/Cargo.toml | 10 +- packages/wallet-engine/src/planner.rs | 294 +- packages/wallet-engine/src/tx_engine.rs | 654 +-- packages/wallet-engine/src/tx_v1.rs | 3 +- scripts/update-signing-fixture.mjs | 38 + tests/desktop-composer.test.ts | 32 + tests/fixtures/README.md | 19 + tests/fixtures/nockster-signed.json | 9 +- 30 files changed, 1255 insertions(+), 4759 deletions(-) create mode 100644 nockster-esp/crates/nockster-core/examples/sign_test_fixture.rs create mode 100644 scripts/update-signing-fixture.mjs create mode 100644 tests/fixtures/README.md diff --git a/README.md b/README.md index ec9ef36..f501ae1 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,12 @@ build configuration, and native integrations. ## Wallet development +Rust workspaces pin the shared `tx-types` 0.2 transaction core and its matching +noun runtime to one Git revision. `packages/wallet-engine` and `nockster-esp` +call the same `tx_types::planner`; their adapters provide RPC note data, wallet envelopes, +and software or hardware signatures. Composer inputs include the actual +`note_data` map and an explicit candidate height for time-locked inputs. + Use Node and npm versions matching `package.json`. Install dependencies from this directory; npm workspaces share the root lockfile. The Rust engine pins its toolchain in `packages/wallet-engine/rust-toolchain.toml`; the desktop diff --git a/apps/desktop/src/transactions/Composer.svelte b/apps/desktop/src/transactions/Composer.svelte index 214fc5b..3d73814 100644 --- a/apps/desktop/src/transactions/Composer.svelte +++ b/apps/desktop/src/transactions/Composer.svelte @@ -45,7 +45,8 @@ commitments: '', refundAddress: '', refundHeight: '', - branch: 'claim' + branch: 'claim', + preimages: '' }; let outputs = [newOutput(1)]; let nextOutputId = 2; @@ -100,7 +101,7 @@ let selectionTimer: ReturnType | undefined; const composerWorker = createComposerWorker(); let height = ''; - let manual = { first: '', last: '', origin: '', amount: '' }; + let manual = { first: '', last: '', origin: '', amount: '', noteData: '{}' }; let notesLoading = false; let building = false; let error = ''; @@ -212,8 +213,9 @@ if (!alive || request !== noteRequest) return; notes = largestNotesFirst( loaded - .filter(note => Number(note.version) === 1) + .filter(note => note.version === '1') .map(note => ({ + note_data: note.noteData, name_first: note.firstName, name_last: note.lastName, origin_page: note.originPage, @@ -235,6 +237,7 @@ try { const wasm = await hardwareCrypto(); const note: Note = { + note_data: JSON.parse(manual.noteData), name_first: manual.first.trim(), name_last: manual.last.trim(), origin_page: wholeNumber(manual.origin, 'Origin block height'), @@ -248,7 +251,7 @@ throw new Error('This note is reserved by a pending transaction.'); notes = largestNotesFirst([...notes, note]); if (selectionMode === 'manual') selected = new Set([...selected, noteId(note)]); - manual = { first: '', last: '', origin: '', amount: '' }; + manual = { first: '', last: '', origin: '', amount: '', noteData: '{}' }; } catch (failure) { noteError = failure instanceof Error ? failure.message : String(failure); } @@ -291,6 +294,7 @@ const input: ComposeInput = { source_pkh: sourceAddress, notes: inputNotes, + manual_inputs: selectionMode === 'manual', outputs: [], current_height: wholeNumber(height, 'Current block height', 1) }; @@ -309,7 +313,12 @@ source.refundHeight, valid ), - spend_branch: source.branch === 'claim' ? 0 : 1 + spend_branch: source.branch === 'claim' ? 0 : 1, + preimages: source.preimages + .trim() + .split(/\s+/) + .filter(Boolean) + .map(value => Array.from(atob(value), ch => ch.charCodeAt(0))) }; input.outputs = outputs.map((output, index) => { try { @@ -499,6 +508,12 @@ +