Skip to content

feat: craft the legacy wallet upgrade from the wallet's actual state; 0.19.0 - #21

Merged
kalepail merged 1 commit into
mainfrom
feat/legacy-upgrade-helpers
Sep 17, 2026
Merged

kalepail merged 1 commit into
mainfrom
feat/legacy-upgrade-helpers

Conversation

@kalepail

Copy link
Copy Markdown
Contributor

What

The kit cannot connect to a pre-1.0 wallet (LegacyWalletError, #19), but it can now build the one transaction such a wallet needs, from the wallet's actual on-chain state.

  • inspectLegacyWallet(id) — code hash, status (vulnerable / legacy / current / unknown), storage cohort, which of the instance / current-code / target-code entries are archived, and a plain recommendation. Read-only.
  • buildLegacyUpgradeTx(id)update_contract_code(<legacy-line target>); refused for wallets not on a pre-1.0 build; restores archived entries first when restoreSource is configured, else throws RESTORE_REQUIRED with guidance.
  • buildLegacyMigrateTx(id, keys)migrate_signers for the bare cohort.
  • signLegacyUpgradeTx(tx, id, signer?) — signs the wallet's auth entry with an existing passkey or Ed25519 signer without a connected wallet. The entry must root at exactly the transaction's own call on this wallet with no sub-invocations.
const { inspection, tx } = await kit.buildLegacyUpgradeTx(contractId);
if (inspection.upgradeRequired) {
  await server.send(await kit.signLegacyUpgradeTx(tx, contractId, new PasskeySigner(keyId)));
  if (inspection.migrateRequired) {
    const keys = (await server.getSigners(contractId)).map((s) => s.key);
    await server.send(await kit.buildLegacyMigrateTx(contractId, keys));
  }
}

Also records the mainnet upload of the legacy-line target (tx 501bd5d5…), cuts CHANGELOG 0.19.0, and bumps the package version. Bindings are unchanged (verify:bindings passes against the canonical v1 WASM).

Tests

11 new tests: classification, inspection against mocked ledger state, the exact shape of both transactions, and signing with a real Ed25519 signer through the real signAuthEntries path (address-bound V2 credentials), plus the refusal of a foreign-rooted entry. Full suite: 360 passing.

🤖 Generated with Claude Code

… 0.19.0

The kit cannot connect to a pre-1.0 wallet, but it can now build the one
transaction such a wallet needs. New kit methods:

- inspectLegacyWallet(id): code hash, status (vulnerable / legacy / current
  / unknown), storage cohort, which of the instance / current-code /
  target-code entries are archived, and a plain recommendation. Read-only.
- buildLegacyUpgradeTx(id): update_contract_code(<legacy-line target>),
  refused for wallets not on a pre-1.0 build; restores archived entries
  first when restoreSource is configured, else throws RESTORE_REQUIRED
  with guidance.
- buildLegacyMigrateTx(id, keys): migrate_signers for the bare cohort.
- signLegacyUpgradeTx(tx, id, signer?): signs the wallet's auth entry with
  an existing passkey or Ed25519 signer without a connected wallet; the
  entry must root at exactly the transaction's own call on this wallet
  with no sub-invocations.

Records the mainnet upload of the legacy-line target (tx 501bd5d5…) in the
docs. Cuts CHANGELOG 0.19.0 and bumps the package version.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings September 17, 2026 20:02

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The signing path can authorize unintended wallet-admin calls, and restoration and cohort tracking have correctness gaps.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds tooling to inspect and upgrade pre-1.0 wallets from their on-chain state.

Changes:

  • Adds legacy wallet inspection, upgrade, migration, restoration, and signing helpers.
  • Adds 11 focused tests.
  • Releases version 0.19.0 and documents the mainnet upgrade target.
File summaries
File Description
src/version.ts Updates the generated version.
src/kit/legacy-ops.ts Implements legacy wallet operations.
src/kit/legacy-ops.test.ts Tests the new helpers.
src/kit.ts Exposes helpers through PasskeyKit.
src/index.ts Exports legacy inspection types and utilities.
SECURITY.md Records upgrade tooling and mainnet upload.
package.json Bumps the package version.
docs/releasing.md Updates release documentation.
docs/legacy-wallet-upgrade.md Documents the SDK upgrade workflow.
CHANGELOG.md Adds the 0.19.0 release notes.
Review details
  • Files reviewed: 10/10 changed files
  • Comments generated: 4
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/kit/legacy-ops.ts
Comment on lines +101 to +103
if (LEGACY_WALLET_WASM_HASHES.includes(hash)) {
return { status: "legacy", cohort: "wrapped" };
}
Comment thread src/kit/legacy-ops.ts
Comment on lines +356 to +360
const ok =
expected !== undefined &&
actual !== undefined &&
root.subInvocations().length === 0 &&
Address.fromScAddress(actual.contractAddress()).toString() === contractId &&
Comment thread src/kit.ts
Comment on lines +968 to +970
let tx = await build();
const simulation = tx.simulation;
if (simulation && Api.isSimulationRestore(simulation)) {
Comment thread src/kit/legacy-ops.ts
Comment on lines +91 to +94
const hash = wasmHash.toLowerCase();
if (acceptedWasmHashes.includes(hash)) {
return { status: "current", cohort: null };
}
@kalepail
kalepail merged commit b26d25b into main Sep 17, 2026
10 checks passed
@kalepail
kalepail deleted the feat/legacy-upgrade-helpers branch September 17, 2026 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants