Ironwood (NU6.3) SDK + Orchard→Ironwood migration bridge#71
Draft
peachbits wants to merge 5 commits into
Draft
Conversation
No tagged SDK release carries the Ironwood hardfork yet, so this pins the tip of upstream's integration line: zcash-swift-wallet-sdk @ a9637998 (branch michal/MOB-1455-6-integration-with-final-zodl, minus its top two external-signer commits, which require an unmerged migration-crate branch and are not bridged here). The libzcashlc binary is an Edge-hosted one-time build from that commit's own Rust source plus its pinned sibling migration crate (ZODLIronwoodMigrationRust @ 17be9388) - provenance and rebuild commands in scripts/build-ironwood-ffi.md; the download stays sha256-pinned. The checkout's Package.swift binaryTarget is patched to the same asset so the vendored-deps SwiftPM build resolves the new zcashlc_migration_* symbols. copySwift grows two Ironwood-line fixes: Rust/Voting sources are skipped (upstream gates voting off on this line - the FFI exports no zcashlc_voting_* symbols), and the new regtest checkpoint Bundle.module reference is neutralized (the path is never read; RegtestCheckpointSource synthesizes its checkpoint). This supersedes the 2.6.0-alpha.6 pins: the Ironwood line forked from ~alpha.4, and alpha.6's voting module is gated off on it. When an Ironwood SDK release tags, the swap back to upstream pins is a pins-only commit (commit hash, asset URL, sha256, drop the Package.swift patch). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ironwoodAvailableZatoshi / ironwoodTotalZatoshi join the per-pool balance split (zero until NU6.3 activates; zero on Android until its SDK ships Ironwood - the JS side defaults missing fields). The deprecated summed fields include the ironwood pool, so a migrating wallet's funds never vanish from them mid-migration. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fifteen Synchronizer methods covering the SDK's migration lifecycle: state/progress polls, note split (prepare/submit), schedule proposal for both product paths (proposeMigrationTransfers = randomized denominated transfers over time; proposeImmediateMigration = one whole-balance transfer executable now), one-time pre-signing (signAndStoreMigrationSchedule), height-due execution (executeNextPendingTransfer - no seed, transfers are pre-signed), and detection/recovery (hasOverdue/hasInvalid/refreshStale/restartCurrentMigrationStep, initializeIronwoodPostUpgrade). Conventions: the mnemonic crosses the bridge per call and is never stored (as createTransfer/shieldFunds); proposals and schedules round-trip as opaque base64 of the SDK's own Codable JSON, so the user signs exactly the plan they confirmed (a re-proposal would produce different randomized amounts); Swift enums flatten to discriminated unions (no serde tagging leaks to JS); TransferResult non-success outcomes resolve rather than reject - rejections are reserved for thrown ZcashError, whose message (rustMigration* detail) is carried to JS. No fullySynced gate: executeNextPendingTransfer is designed to run without full sync, and isSyncRequiredBeforeNextTransfer is the SDK's own gate. The surface is pull-based by design; the SDK persists all migration state in its own database. The external-signer PCZT quartet is deliberately not bridged (Edge holds seeds locally). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
zcash-android-sdk has no Ironwood release yet. These mirror the iOS bridge signatures exactly (the JS API is the contract) and reject with the stable code IronwoodMigrationUnsupported so the app can feature-gate per platform. Fill in against the android SDK's migration API when it ships - its ironwood branches mirror the Swift names. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Jul 16, 2026
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.
Ironwood (NU6.3) SDK + Orchard→Ironwood migration bridge
Stacked on #69 (
zcash-spm-deps-binary) — review only the top five commits.Why
Zcash's Ironwood hardfork (NU6.3) activates ~end of July and introduces a new shielded pool. Without an Ironwood-capable SDK, wallets stop syncing correctly at activation; and users must migrate Orchard funds to the new pool. No upstream SDK release carries Ironwood yet — the work lives on upstream branches — so this PR pins branch hashes and swaps to release pins later (a pins-only commit, same shape as the alpha.6 bump).
What
4049a04— Pin the Ironwood SDK + prebuilt FFI. Vendorszcash-swift-wallet-sdk @ a9637998(upstream'smichal/MOB-1455-6integration line, minus its two external-signer commits which require an unmerged crate branch and aren't bridged here).libzcashlcis an Edge-hosted one-time build from that commit's own Rust source + the pinnedZODLIronwoodMigrationRust @ 17be9388crate — provenance/rebuild commands inscripts/build-ironwood-ffi.md, hosted at theironwood-ffi-a9637998pre-release, sha256-pinned. The checkout'sPackage.swiftbinaryTarget is patched to the same asset so the vendored-deps SwiftPM build resolves the new FFI. copySwift gains two Ironwood-line fixes (skipRust/Voting— upstream gates voting off on this line; neutralize the new regtestBundle.modulereference). Supersedes the alpha.6 pins: the Ironwood line forked from ~alpha.4 and gates alpha.6's voting module off.10a04d3— BalanceEvent: Ironwood pool fields (ironwood{Available,Total}Zatoshi, zero until activation; deprecated sums include the new pool so funds never vanish mid-migration).a1555bd— Bridge the migration API (iOS), 15 methods: state/progress polls, note split, schedule proposal for both product paths (proposeMigrationTransfers= randomized denominated transfers over time;proposeImmediateMigration= one whole-balance transfer now), one-time pre-signing, height-due execution (executeNextPendingTransfer— seedless, transfers are pre-signed), detection/recovery (hasOverdue/hasInvalid/refreshStale/restartCurrentMigrationStep,initializeIronwoodPostUpgrade). Conventions: per-call seed (never stored); opaque base64 round-trip of the SDK's own Codable models so the user signs exactly the plan they confirmed; Swift enums flatten to discriminated unions;TransferResultnon-success outcomes resolve (engine-driven retry UX); ZcashError messages carried to JS. The external-signer PCZT quartet is deliberately not bridged (Edge holds seeds).e6da919— Android stubs: all 15 methods mirrored, rejecting with stable codeIronwoodMigrationUnsupported(zcash-android-sdk has no Ironwood release; its branches mirror the Swift names, so filling these in later is mechanical).a416a51— Changelog.Validation
npm run update-sourcesat the pins: full regen green — 138 SDK files vendored incl.Migration.swift, 0 voting files, 17zcashlc_migration_*decls in the header, vendored SwiftPM deps rebuilt (dep graph unchanged vs alpha.6 — grpc 1.27.3/NIO 2.95.0 — so no piratechain Handle potential throw in synchronizer.latestHeight() #22 lockstep bump needed).develop(RN 0.79, iOS 15.6) Release build with piratechain co-installed (consumer mode): BUILD SUCCEEDED, 0 undefined, 0 duplicate-symbol errors; 36 migration-FFI references linked into the app.npm run prepare(tsc + rollup + lint) green.Honest limits
-6branch has no upstream PR yet; re-pin deliberately if upstream moves.Package.resolved(open dependabot PRs would bump NIO → piratechain lockstep + joint regen).Consumed next by edge-currency-accountbased (engine orchestration) and edge-react-gui (migration UX) — see the project plan.
🤖 Generated with Claude Code