Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,47 @@ jobs:
working-directory: contracts
run: cargo test --workspace --locked

contracts-legacy:
name: legacy contract tests + canonical hash
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4

- uses: dtolnay/rust-toolchain@d1031067263f94b142dd6c0ce24c5eb9d02d52a0 # master
with:
toolchain: 1.89.0
targets: wasm32v1-none
components: rustfmt

- name: Check legacy contract formatting
working-directory: contracts-legacy
run: cargo fmt --all -- --check

# The committed artifact is the upgrade target published in SECURITY.md
# and docs/legacy-wallet-upgrade.md. Its hash must not drift, and the
# end-to-end tests run against exactly those bytes.
- name: Verify the canonical artifact and run the tests
working-directory: contracts-legacy
run: make test

# Informational: rebuild on this host and report. rustc's wasm codegen is
# host-dependent, so this hash is not expected to equal the canonical one;
# the step exists so a source change that silently alters the contract is
# visible in the log.
- name: Install stellar CLI 27.1.0
run: |
set -euo pipefail
curl -fsSL -o stellar-cli.tar.gz \
https://github.com/stellar/stellar-cli/releases/download/v27.1.0/stellar-cli-27.1.0-x86_64-unknown-linux-gnu.tar.gz
tar -xzf stellar-cli.tar.gz
sudo install -m 0755 stellar /usr/local/bin/stellar

- name: Rebuild on this host (informational)
working-directory: contracts-legacy
run: |
stellar contract build --locked --package smart-wallet --out-dir rebuilt
shasum -a 256 rebuilt/smart_wallet.wasm out/smart_wallet.wasm
Comment on lines +76 to +80

build:
name: test & build
runs-on: ubuntu-latest
Expand Down
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,11 @@ target/
ext/js-stellar-sdk/
# Local audit/review scratch — never committed
docs/history/

# legacy-line contract workspace: generated test snapshots
contracts-legacy/smart-wallet/test_snapshots/


# The canonical legacy-line artifact is committed (its hash is the published upgrade target).
!contracts-legacy/out/
!contracts-legacy/out/smart_wallet.wasm
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@ All notable changes to `passkey-kit` are recorded here. The `0.13.0` entry cover

## Unreleased

- **Added a safe in-place upgrade target for pre-fix legacy wallets.** New
`contracts-legacy/` workspace builds the last pre-1.0 wallet (`e45c42b9…`)
with signer reads that accept both pre-1.0 storage layouts, plus
`migrate_signers` and `get_signer`. Wallets on the four mainnet WASM hashes
whose `update_signer` lacks `require_auth` (`0c0a264d…`, `19868df3…`,
`b62f6221…`, `c5509dfa…`) can upgrade to
`c079d3a4136eb6ca68eb724acd3d8af11b0be4a0ed82605925a6dfd4dd83a97c` without
bricking. The artifact is committed at `contracts-legacy/out/smart_wallet.wasm`
and CI verifies its hash. Earlier post-fix builds brick the two bare-layout hashes. See
[`docs/legacy-wallet-upgrade.md`](./docs/legacy-wallet-upgrade.md) and the
new "Known-vulnerable wallet WASM hashes" section in `SECURITY.md`. The v1
contract is unchanged.
- **Named legacy wallets on connect.** `connectWallet` now throws
`LegacyWalletError` (code `2006`, `WALLET_LEGACY_CODE`) when a candidate
wallet runs pre-1.0 code, before birth verification would fail it for a less
useful reason. `vulnerable: true` carries the in-place upgrade target and the
guide URL; `vulnerable: false` points at the 0.10.20–0.12.x kit line. The
constructor rejects a known-vulnerable `walletWasmHash` or accepted hash.
New exports: `LegacyWalletError`, `KNOWN_VULNERABLE_WALLET_WASM_HASHES`,
`LEGACY_WALLET_WASM_HASHES`, `LEGACY_UPGRADE_TARGET_WASM_HASH`,
`LEGACY_WALLET_UPGRADE_GUIDE_URL`.
- **Updated the relayer development image dependency.** The standalone relayer
lock now requires `sharp@0.35.4`, which removes the development-only
`GHSA-rgj7-g3m4-5g8c` alert. This change does not affect the published package
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,7 @@ pnpm verify:bindings # assert the committed bindings match the canonical WASM
- **[CHANGELOG.md](./CHANGELOG.md)** — the v1 overhaul, by component.
- **[SECURITY.md](./SECURITY.md)** — supported versions and private vulnerability reporting.
- **[docs/migration-v1.md](./docs/migration-v1.md)** — upgrading from 0.12.x, with Before/After and a gap analysis.
- **[docs/legacy-wallet-upgrade.md](./docs/legacy-wallet-upgrade.md)** — in-place upgrade for pre-fix legacy wallets (known-vulnerable WASM hashes in [SECURITY.md](./SECURITY.md)).
- **[docs/releasing.md](./docs/releasing.md)** — the dependency-ordered publish flow.

## Resources
Expand Down
19 changes: 19 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,25 @@ Only the latest npm releases and the canonical smart-wallet WASM receive securit

The current [`deployment manifest`](./docs/deployments-2026-09-01.md) identifies the canonical WASM. Existing wallet instances do not upgrade automatically.

## Known-vulnerable wallet WASM hashes

Wallets deployed from the following mainnet WASM hashes run code in which `update_signer` has no authorization check. Anyone who knows a signer key can overwrite that signer. The defect was fixed in source in commit [`dcc6e3dc9c`](https://github.com/kalepail/passkey-kit/commit/dcc6e3dc9cfd32e64b98f23541cd2d96812b64c4) on 2025-03-27. Deployed wallets keep the old code until their owner upgrades them.

| WASM hash | Storage layout |
|---|---|
| `0c0a264d4cc0b3e79b8533e2a2e1f0ed21501a5a3f9f2455d2f18c232940b865` | bare (pre-`6a27d48`) |
| `19868df3653d427cafa1c30bdb6cec1ca5c8c815eeabab8a8bae6d83efb1fedd` | bare (pre-`6a27d48`) |
| `b62f62217ff256d557513793e9e44317b25b14401a8a6b6149a04d38d72d6c7c` | wrapped |
| `c5509dfa5f022deb8ae621f073adac5fd788feca0b24d15b5f392ab22c2ff222` | wrapped (not built from this repo) |

Do not deploy new wallets from these hashes, or from any Makefile or `.env` pin older than commit `da472f9`.

Upgrade affected wallets in place to the legacy-line build `c079d3a4136eb6ca68eb724acd3d8af11b0be4a0ed82605925a6dfd4dd83a97c`, built from [`contracts-legacy/`](./contracts-legacy). It reads both storage layouts. The earlier post-fix builds `ecd990f0…` and `e45c42b9…` and the v1 build read only the wrapped layout and brick a bare-layout wallet. See [`docs/legacy-wallet-upgrade.md`](./docs/legacy-wallet-upgrade.md) for the procedure.

Move funds out of any affected wallet you do not intend to upgrade.

The current SDK refuses to deploy from these hashes and throws `LegacyWalletError` with the upgrade guidance when `connectWallet` meets a wallet running one of them.

## Cargo advisory status

The lockfile retains `serde_with@3.14.0` and its inactive `time@0.3.41` optional dependency.
Expand Down
Loading
Loading