Commit 2f18ae5
feat(wasm-utxo): wire v6 (Ironwood) build/sign/combine into ZcashBitGoPsbt
Add a dedicated Zcash v6 (Ironwood / NU6.3) shielding flow on ZcashBitGoPsbt,
mirroring the microservice build → sign → combine PSBT lifecycle. The ~20
generic BitGoPsbt::Zcash dispatch arms are left untouched; v6 uses dedicated
methods.
propkv: add ProprietaryKeySubtype::ZecIronwoodPczt (0x07, the serialized
orchard PCZT) and ZecV6Params (0x08, versionGroupId + expiryHeight); the latter
marks a PSBT as v6 so it round-trips through a plain PSBT serialization.
ZcashBitGoPsbt v6 methods:
- new_v6 / new_v6_at_height: version-6, Ironwood VGID, NU6.3 branch.
- add_ironwood_output (Constructor): build the shielded note as an orchard PCZT
and store it in the PSBT.
- ironwood_action_data / v6_txid / v6_transparent_sighash: derive the ZIP-244
txid and per-input transparent sighash from the transparent skeleton + stored
PCZT action data.
- add_v6_transparent_signature: verify a client/HSM signature against the v6
sighash and insert it into partial_sigs.
- combine_ironwood_proof (Extractor): finalize the transparent inputs, splice in
the external prover's zkproof, apply the binding signature, and encode the
broadcast-ready v6 transaction.
- serialize_v6 / deserialize_v6: round-trip the v6 PSBT (transparent skeleton +
PCZT + params).
BitGoPsbt::new_zcash_v6_at_height: a builder so transparent inputs/outputs use
the existing add_wallet_input / add_wallet_output machinery.
Hardening (from review): reject v6 PSBTs on the v4/Sapling-shaped paths instead
of silently producing a bad result; enforce the 2-of-3 signature threshold in
finalized_transparent_tx instead of pushing every collected signature (which
overflows OP_CHECKMULTISIG's exact-two pop); check new_v6_at_height's height
against NU6.3 activation instead of any post-Overwinter height; validate
version_group_id on deserialize_v6 instead of trusting it; replace panicking
index access across parallel psbt.inputs/unsigned_tx.input vectors with errors
(a WASM panic aborts rather than raising a JS exception); error instead of
silently overwriting an existing note in add_ironwood_output; reject signing
keys absent from the input's redeem script in add_v6_transparent_signature.
Tests (native):
- build a 2-of-3 P2SH → Ironwood shield PSBT, round-trip it, sign the
transparent input over the ZIP-244 sighash, combine with a placeholder proof,
and assert the result decodes, keeps a stable txid across signing, and is
accepted by zebra-chain.
- golden oracle: reproduce the on-chain shield1zec transaction inside a PSBT,
sourced from the v6_shield1zec_details.json fixture, and assert its
v6_transparent_sighash both equals the codec-golden sighash, verifies the
transaction's real ECDSA signature, and that the PSBT-derived v6_txid matches
the real on-chain txid.
- propkv round-trip unit test.
- regression tests for each hardening fix above, including that the v4 paths
reject a v6 PSBT and leave partial_sigs empty.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>1 parent c7b0dff commit 2f18ae5
5 files changed
Lines changed: 1379 additions & 2 deletions
File tree
- packages/wasm-utxo
- src
- fixed_script_wallet/bitgo_psbt
- zcash
- test/fixtures/zcash
Lines changed: 63 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
497 | 497 | | |
498 | 498 | | |
499 | 499 | | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
500 | 525 | | |
501 | 526 | | |
502 | 527 | | |
| |||
1966 | 1991 | | |
1967 | 1992 | | |
1968 | 1993 | | |
| 1994 | + | |
1969 | 1995 | | |
1970 | 1996 | | |
1971 | 1997 | | |
| |||
2291 | 2317 | | |
2292 | 2318 | | |
2293 | 2319 | | |
| 2320 | + | |
2294 | 2321 | | |
2295 | 2322 | | |
2296 | 2323 | | |
| |||
2394 | 2421 | | |
2395 | 2422 | | |
2396 | 2423 | | |
| 2424 | + | |
| 2425 | + | |
| 2426 | + | |
| 2427 | + | |
| 2428 | + | |
| 2429 | + | |
| 2430 | + | |
| 2431 | + | |
| 2432 | + | |
| 2433 | + | |
| 2434 | + | |
| 2435 | + | |
| 2436 | + | |
| 2437 | + | |
| 2438 | + | |
2397 | 2439 | | |
2398 | 2440 | | |
2399 | 2441 | | |
| |||
2420 | 2462 | | |
2421 | 2463 | | |
2422 | 2464 | | |
| 2465 | + | |
| 2466 | + | |
| 2467 | + | |
| 2468 | + | |
| 2469 | + | |
| 2470 | + | |
| 2471 | + | |
| 2472 | + | |
| 2473 | + | |
| 2474 | + | |
| 2475 | + | |
| 2476 | + | |
2423 | 2477 | | |
2424 | 2478 | | |
2425 | 2479 | | |
| |||
2438 | 2492 | | |
2439 | 2493 | | |
2440 | 2494 | | |
| 2495 | + | |
2441 | 2496 | | |
2442 | 2497 | | |
2443 | 2498 | | |
| |||
2503 | 2558 | | |
2504 | 2559 | | |
2505 | 2560 | | |
| 2561 | + | |
2506 | 2562 | | |
2507 | 2563 | | |
2508 | 2564 | | |
| |||
2840 | 2896 | | |
2841 | 2897 | | |
2842 | 2898 | | |
| 2899 | + | |
| 2900 | + | |
| 2901 | + | |
| 2902 | + | |
| 2903 | + | |
| 2904 | + | |
| 2905 | + | |
2843 | 2906 | | |
2844 | 2907 | | |
2845 | 2908 | | |
| |||
Lines changed: 154 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
246 | 246 | | |
247 | 247 | | |
248 | 248 | | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
249 | 344 | | |
250 | 345 | | |
251 | 346 | | |
| |||
310 | 405 | | |
311 | 406 | | |
312 | 407 | | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
313 | 467 | | |
314 | 468 | | |
315 | 469 | | |
| |||
0 commit comments