feat(examples): add R1-K1 hardware recovery wallet - #152
Open
sirdeggen wants to merge 12 commits into
Open
Conversation
25 tasks
There was a problem hiding this comment.
Pull request overview
Adds a new advanced example contract (“R1-K1 Wallet”) that demonstrates a stateless dual-spend-path wallet: a primary NIST P‑256 (YubiKey PIV–friendly) path bound to a BIP-143 preimage, plus an independent secp256k1 recovery path. The PR also integrates the example into Rúnar’s conformance + verification gates (including script-size baselines) and updates a few tooling paths to keep CI efficient with ~1 MB scripts.
Changes:
- Introduces the R1-K1 wallet example across all nine Rúnar source frontends (TS/Go/Rust/Ruby/Python/Zig/Java/Sol/Move) plus a focused TypeScript test suite and documentation.
- Adds a multi-format conformance fixture + real-crypto witness coverage and updates verification inventory/counts and decompiler “pathological” skips to account for the new large script.
- Improves tooling robustness/perf (reuse existing
tsxloader invocation; normalize expected hex ingestion) and pins the dependency-audit workflow’s Go patch version.
Reviewed changes
Copilot reviewed 27 out of 31 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| runar-verification/tests/PipelineGolden.lean | Registers r1-k1-wallet in Lean verification buckets and updates expected fixture totals. |
| runar-verification/scripts/cross-compiler-diff.sh | Normalizes expected hex handling and switches report assembly to file-based jq --rawfile/--slurpfile to avoid large in-memory JSON strings. |
| runar-verification/README.md | Updates the Lean-recognized fixture count to 72/72. |
| README.md | Adds R1K1Wallet to the top-level example table and updates cross-format example counts/notes. |
| packages/runar-compiler/src/tests/examples.test.ts | Caches compiled example results to avoid repeated expensive compilation in structural assertions. |
| packages/decompiler/scripts/coverage-matrix.ts | Marks r1-k1-wallet as a pathological decompile case for coverage matrix runs. |
| packages/decompiler/tests/roundtrip.test.ts | Skips r1-k1-wallet in byte-match roundtrip due to pathological decompile runtime. |
| examples/zig/r1-k1-wallet/R1K1Wallet.runar.zig | Adds Zig frontend version of the R1-K1 wallet contract. |
| examples/ts/r1-k1-wallet/README.md | Documents the wallet’s security model, enrollment, and spend flows (R1 + K1). |
| examples/ts/r1-k1-wallet/R1K1Wallet.test.ts | Adds focused tests including real P-256 signing and cross-frontend script byte equality checks. |
| examples/ts/r1-k1-wallet/R1K1Wallet.runar.ts | Adds the TypeScript reference contract implementation. |
| examples/sol/r1-k1-wallet/R1K1Wallet.runar.sol | Adds Solidity-like frontend version of the contract. |
| examples/rust/r1-k1-wallet/R1K1Wallet.runar.rs | Adds Rust DSL frontend version of the contract. |
| examples/ruby/r1-k1-wallet/R1K1Wallet.runar.rb | Adds Ruby frontend version of the contract. |
| examples/README.md | Updates examples overview and lists the new R1-K1 wallet in the catalog. |
| examples/python/r1-k1-wallet/R1K1Wallet.runar.py | Adds Python frontend version of the contract. |
| examples/move/r1-k1-wallet/R1K1Wallet.runar.move | Adds Move-style frontend version of the contract. |
| examples/java/src/main/java/runar/examples/r1-k1-wallet/R1K1Wallet.runar.java | Adds Java frontend version of the contract. |
| examples/go/r1-k1-wallet/R1K1Wallet.runar.go | Adds Go DSL frontend version of the contract. |
| conformance/witnesses/real-crypto/r1-k1-wallet.json | Adds real-crypto witness coverage for the K1 recovery branch. |
| conformance/tests/r1-k1-wallet/source.json | Registers the nine-source mapping for the new conformance fixture. |
| conformance/tests/r1-k1-wallet/expected-ir.json | Adds the pinned expected ANF IR for cross-compiler parity. |
| conformance/sdk-output/runner/sdk-runner.ts | Uses the existing tsx loader (via process.execArgv) for TypeScript SDK tool execution instead of npx. |
| conformance/sdk-output/generate-inputs.ts | Uses the existing tsx loader for CLI compilation during sdk-output input generation; adds r1-k1-wallet test spec. |
| conformance/script-size-baseline.json | Adds script-size baseline entry for r1-k1-wallet (959,592 bytes). |
| conformance/golden-provenance-allowlist.json | Registers new goldens/provenance hashes for the added fixture and sdk-output pin. |
| .github/workflows/dependency-audit.yml | Pins Go to 1.26.6 for dependency audit to avoid the referenced vulnerability. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Security model
Either key can spend independently. The P-256 private key may be generated inside a YubiKey PIV slot and never exported. The K1 key is the loss-recovery bypass and should be derived from an offline mnemonic plus passphrase.
Each output uses a private, high-entropy salt. A locking script exposes only the salted R1 commitment, so even a known or reused PIV public key does not link unspent outputs. The relevant salt and public key are disclosed if that output uses the R1 path. Losing an output salt disables only its R1 path; K1 recovery remains available.
Testing
Deployment note
The synthesized P-256 verifier makes the locking script 959,592 bytes, above common 500 KB policy limits. Test against the intended miner policy before production use.