Home / Vacuum Labs / cardano-hw-cli
May 27, 9-10 AM (0)
May 27, 10-11 AM (0)
May 27, 11-12 PM (0)
May 27, 12-1 PM (0)
May 27, 1-2 PM (0)
May 27, 2-3 PM (0)
May 27, 3-4 PM (0)
May 27, 4-5 PM (0)
May 27, 5-6 PM (0)
May 27, 6-7 PM (0)
May 27, 7-8 PM (0)
May 27, 8-9 PM (0)
May 27, 9-10 PM (0)
May 27, 10-11 PM (0)
May 27, 11-12 AM (0)
May 28, 12-1 AM (0)
May 28, 1-2 AM (0)
May 28, 2-3 AM (0)
May 28, 3-4 AM (0)
May 28, 4-5 AM (0)
May 28, 5-6 AM (0)
May 28, 6-7 AM (0)
May 28, 7-8 AM (0)
May 28, 8-9 AM (0)
May 28, 9-10 AM (0)
May 28, 10-11 AM (1)
May 28, 11-12 PM (0)
May 28, 12-1 PM (0)
May 28, 1-2 PM (0)
May 28, 2-3 PM (0)
May 28, 3-4 PM (0)
May 28, 4-5 PM (0)
May 28, 5-6 PM (0)
May 28, 6-7 PM (0)
May 28, 7-8 PM (1)
May 28, 8-9 PM (0)
May 28, 9-10 PM (0)
May 28, 10-11 PM (0)
May 28, 11-12 AM (0)
May 29, 12-1 AM (0)
May 29, 1-2 AM (0)
May 29, 2-3 AM (0)
May 29, 3-4 AM (0)
May 29, 4-5 AM (0)
May 29, 5-6 AM (0)
May 29, 6-7 AM (0)
May 29, 7-8 AM (0)
May 29, 8-9 AM (0)
May 29, 9-10 AM (0)
May 29, 10-11 AM (0)
May 29, 11-12 PM (0)
May 29, 12-1 PM (0)
May 29, 1-2 PM (0)
May 29, 2-3 PM (0)
May 29, 3-4 PM (11)
May 29, 4-5 PM (0)
May 29, 5-6 PM (0)
May 29, 6-7 PM (0)
May 29, 7-8 PM (0)
May 29, 8-9 PM (0)
May 29, 9-10 PM (0)
May 29, 10-11 PM (0)
May 29, 11-12 AM (0)
May 30, 12-1 AM (0)
May 30, 1-2 AM (0)
May 30, 2-3 AM (0)
May 30, 3-4 AM (0)
May 30, 4-5 AM (0)
May 30, 5-6 AM (0)
May 30, 6-7 AM (0)
May 30, 7-8 AM (0)
May 30, 8-9 AM (0)
May 30, 9-10 AM (0)
May 30, 10-11 AM (0)
May 30, 11-12 PM (0)
May 30, 12-1 PM (0)
May 30, 1-2 PM (0)
May 30, 2-3 PM (0)
May 30, 3-4 PM (0)
May 30, 4-5 PM (0)
May 30, 5-6 PM (0)
May 30, 6-7 PM (0)
May 30, 7-8 PM (0)
May 30, 8-9 PM (0)
May 30, 9-10 PM (0)
May 30, 10-11 PM (0)
May 30, 11-12 AM (0)
May 31, 12-1 AM (0)
May 31, 1-2 AM (0)
May 31, 2-3 AM (0)
May 31, 3-4 AM (0)
May 31, 4-5 AM (0)
May 31, 5-6 AM (0)
May 31, 6-7 AM (0)
May 31, 7-8 AM (0)
May 31, 8-9 AM (0)
May 31, 9-10 AM (0)
May 31, 10-11 AM (0)
May 31, 11-12 PM (0)
May 31, 12-1 PM (0)
May 31, 1-2 PM (0)
May 31, 2-3 PM (0)
May 31, 3-4 PM (0)
May 31, 4-5 PM (0)
May 31, 5-6 PM (0)
May 31, 6-7 PM (0)
May 31, 7-8 PM (0)
May 31, 8-9 PM (0)
May 31, 9-10 PM (0)
May 31, 10-11 PM (0)
May 31, 11-12 AM (0)
Jun 01, 12-1 AM (0)
Jun 01, 1-2 AM (0)
Jun 01, 2-3 AM (0)
Jun 01, 3-4 AM (0)
Jun 01, 4-5 AM (0)
Jun 01, 5-6 AM (0)
Jun 01, 6-7 AM (0)
Jun 01, 7-8 AM (0)
Jun 01, 8-9 AM (0)
Jun 01, 9-10 AM (0)
Jun 01, 10-11 AM (0)
Jun 01, 11-12 PM (0)
Jun 01, 12-1 PM (0)
Jun 01, 1-2 PM (0)
Jun 01, 2-3 PM (0)
Jun 01, 3-4 PM (0)
Jun 01, 4-5 PM (0)
Jun 01, 5-6 PM (0)
Jun 01, 6-7 PM (0)
Jun 01, 7-8 PM (0)
Jun 01, 8-9 PM (0)
Jun 01, 9-10 PM (0)
Jun 01, 10-11 PM (0)
Jun 01, 11-12 AM (0)
Jun 02, 12-1 AM (0)
Jun 02, 1-2 AM (0)
Jun 02, 2-3 AM (0)
Jun 02, 3-4 AM (0)
Jun 02, 4-5 AM (0)
Jun 02, 5-6 AM (0)
Jun 02, 6-7 AM (0)
Jun 02, 7-8 AM (0)
Jun 02, 8-9 AM (0)
Jun 02, 9-10 AM (0)
Jun 02, 10-11 AM (0)
Jun 02, 11-12 PM (0)
Jun 02, 12-1 PM (0)
Jun 02, 1-2 PM (0)
Jun 02, 2-3 PM (2)
Jun 02, 3-4 PM (1)
Jun 02, 4-5 PM (0)
Jun 02, 5-6 PM (0)
Jun 02, 6-7 PM (0)
Jun 02, 7-8 PM (0)
Jun 02, 8-9 PM (0)
Jun 02, 9-10 PM (0)
Jun 02, 10-11 PM (0)
Jun 02, 11-12 AM (0)
Jun 03, 12-1 AM (0)
Jun 03, 1-2 AM (0)
Jun 03, 2-3 AM (0)
Jun 03, 3-4 AM (0)
Jun 03, 4-5 AM (0)
Jun 03, 5-6 AM (0)
Jun 03, 6-7 AM (0)
Jun 03, 7-8 AM (0)
Jun 03, 8-9 AM (0)
Jun 03, 9-10 AM (0)
16 commits this week May 27, 2026 - Jun 03, 2026
feat: comprehensive requiresUnrestrictedMode detection
Previous detection had two problems: it only checked required_signers
without collateral, and that check was wrong — required_signers is
actually allowed in ORDINARY/MULTISIG by the v8 lib (only POOL_REGISTRATION
modes forbid it). Replace with detection that mirrors the lib's per-mode
rejection rules in parsing/transaction.ts:

- Pool registration combined with any other cert (POOL_REGISTRATION_*
  requires a sole pool reg cert; lib AUTO throws CANNOT_DETERMINE).
- Pool registration alongside Plutus signals (mutual exclusion).
- Any cert/withdrawal/voter credential that resolves to a bare KEY_HASH
  (no matching signing file). ORDINARY needs KEY_PATH, MULTISIG needs
  SCRIPT_HASH; nothing else accepts KEY_HASH outside PLUTUS (only
  auto-inferred via collateral or other Plutus signals).
- Mixed KEY_PATH + SCRIPT_HASH signals (lib AUTO can't decide ORDINARY
  vs MULTISIG, throws CANNOT_DETERMINE).
- Pool retirement in a multisig-shape tx (MULTISIG rejects pool retirement).

A new collectCertCredentials helper enumerates the credential fields a
non-unrestricted mode actually validates per cert (stakeCredential,
dRepCredential, coldCredential — but not the hotCredential on
AUTHORIZE_COMMITTEE_HOT, which the lib doesn't constrain per mode).

Known gap: device-owned outputs in a multisig-shape tx (MULTISIG forbids
device-owned outputs). Detecting this needs change-output path → address
resolution and is deferred; the lib catches it with a clear per-rule
error if hit.

Tests rewritten to use the new auto-detect triggers (pool reg + extra
cert; key-hash credential with no matching signing file), constructed by
mutating decoded bodies to avoid hand-crafted CBOR.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
chore: refresh yarn.lock to cardano-hw-interop-lib 3.1.0
Recent develop commits (test: network params and usedCostModelLanguages,
feat: pass protocol params to transform transaction) added source code
that uses 3.1.0-only exports (CostModels, PLUTUS_LANGUAGES,
CostModelLanguageName) but didn't refresh yarn.lock, so CI's yarn install
keeps the lockfile-pinned 3.0.2 and tsc fails. The dependency range
^3.0.2 already allows 3.1.0; this commit just re-resolves the lockfile.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
refactor: --unrestricted -> --allow-unrestricted-mode (auto-apply + assert)
Rework the user-facing API per review:

- Rename the flag to --allow-unrestricted-mode. It is now a *permission*,
  not a request: it authorizes hw-cli to use unrestricted mode if the tx
  requires it, but never forces it on a tx that doesn't.
- Auto-apply unrestricted mode when the tx structurally requires it (i.e.
  when no other mode would accept it). A new requiresUnrestrictedMode
  helper in util.ts encapsulates the detection; the initial trigger is a
  required_signers field without collateral inputs (ORDINARY and MULTISIG
  forbid required_signers, and PLUTUS is only auto-inferred when collateral
  is present). The set is extensible.
- determineSigningMode no longer takes the flag; it returns UNRESTRICTED
  automatically when required. The permission check now lives in
  commandExecutor: if the inferred mode is UNRESTRICTED, refuse unless
  --allow-unrestricted-mode was passed, and refuse if the connected
  device/app does not support unrestricted signing. The previous "graceful
  ignore + warn" path is removed; the flag is permission so an unsupported
  device must fail (the tx is unsignable anywhere else).
- New errors: UnrestrictedModeRequiredError and
  UnrestrictedModeUnsupportedByDeviceError.
- README and unit tests updated for the new flag and auto-detect semantics.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
fix: gracefully ignore --unrestricted on unsupported targets
Addresses PR review: instead of throwing when --unrestricted is used on a
device/app that can't honor it, fall back to the auto-inferred signing mode
and log a warning. This keeps callers device-agnostic - a script can always
pass --unrestricted without first branching on device kind or app version.

- Add downgradeUnsupportedUnrestricted helper (crypto-providers/util.ts).
- Trezor and Keystone: warn + ignore instead of erroring.
- Ledger: check compatibility.supportsUnrestrictedTransaction from
  getVersion(); on app v7 and older, warn + fall back.
- Remove the now-unused Trezor/Keystone "not supported" errors.
- Reword the --unrestricted help (code + README): "Ledger app v8 or newer";
  "ignored (with a warning)" on Trezor/Keystone/older apps.
- Unit tests for the fallback helper.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
refactor: decide unrestricted support when picking the signing mode
Per review: instead of picking UNRESTRICTED and then undoing it per-provider,
decide up front whether unrestricted is actually applicable, so the signing
mode is never UNRESTRICTED on a device/app that can't honor it.

- Add supportsUnrestrictedTxSigning() to the CryptoProvider interface
  (Ledger: compatibility.supportsUnrestrictedTransaction from getVersion;
  Trezor/Keystone: false).
- commandExecutor consults it before determineSigningMode and, if
  --unrestricted was requested but unsupported, warns and ignores it. So
  validateWitnessing already sees the effective mode.
- Remove the per-provider downgrade and the downgradeUnsupportedUnrestricted
  helper (and its now-redundant tests).

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
test: cover --unrestricted signing mode
Unit tests for the new unrestricted signing mode (no device needed):
- command parser sets unrestricted: true when --unrestricted is passed
- determineSigningMode returns UNRESTRICTED_TRANSACTION when requested and
  takes precedence over auto-inference (even over a pool registration tx),
  and is unaffected when the flag is absent/false
- validateWitnessing accepts an ordinary tx in unrestricted mode and rejects
  a tx carrying a pool registration certificate

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
fix: bundle @ledgerhq/devices/hid-framing in the pkg build
The ledgerjs/transport bump pulled @ledgerhq/devices up to 8.x.
@ledgerhq/hw-transport-node-hid-noevents loads it via the exports-map
subpath `require("@ledgerhq/devices/hid-framing")`, which resolves to
lib/hid-framing.js. pkg's static analysis does not follow that exports
subpath into the snapshot, so the packaged binary failed at startup with
"Cannot find module .../@ledgerhq/devices/lib/hid-framing.js" (CI test-bin).

Add the devices lib to pkg.scripts so it is compiled into the snapshot.
Verified by packaging the macOS arm64 binary and running --help: it now
starts cleanly with no missing-module error.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
feat: add --unrestricted signing mode for Ledger app v8
Expose the new unrestricted transaction signing mode (Ledger app v8 with
expert mode) via a `--unrestricted` flag on `transaction witness`.

- SigningMode.UNRESTRICTED_TRANSACTION enum value + mapping to the ledgerjs
  TransactionSigningMode in the Ledger provider.
- determineSigningMode takes precedence for unrestricted when requested; it
  is never auto-inferred (per the lib's contract).
- Trezor and Keystone reject it explicitly (Ledger-v8-only).
- Expert mode is enabled by ledgerjs itself before signing, so no extra
  device plumbing is needed here.

Security-relevant relaxations (please review): unrestricted mode is a
superset of ordinary allowances, so device-owned address params and
key-hash credentials are permitted (areAddressParamsAllowed / allowKeyHash),
and witnessing validation only enforces the one invariant the Ledger app
keeps - no pool registration certificate. The device shows every element
for the expert user to review.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
feat: bump ledgerjs to 8.0.0-rc.2 for Ledger app v8 support
Pull in @cardano-foundation/ledgerjs-hw-app-cardano 8.0.0-rc.2 (Ledger
app v8: unrestricted signing mode, combined certificates). Sourced from
the vacuumlabs GitHub pre-release tarball since 8.x is not yet on npm;
repoint to the npm version once published.

The 8.x lib requires @ledgerhq/hw-transport ^6.31.2, which adds tracing
methods to Transport. Bump hw-transport and the node-hid-noevents /
node-speculos impl packages so the whole tree dedupes to a single
hw-transport (6.35.2) and the Ledger(transport) type matches. No hw-cli
source changes were needed; build, lint and unit tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
refactor: decide unrestricted support when picking the signing mode
Per review: instead of picking UNRESTRICTED and then undoing it per-provider,
decide up front whether unrestricted is actually applicable, so the signing
mode is never UNRESTRICTED on a device/app that can't honor it.

- Add supportsUnrestrictedTxSigning() to the CryptoProvider interface
  (Ledger: compatibility.supportsUnrestrictedTransaction from getVersion;
  Trezor/Keystone: false).
- commandExecutor consults it before determineSigningMode and, if
  --unrestricted was requested but unsupported, warns and ignores it. So
  validateWitnessing already sees the effective mode.
- Remove the per-provider downgrade and the downgradeUnsupportedUnrestricted
  helper (and its now-redundant tests).

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
fix: gracefully ignore --unrestricted on unsupported targets
Addresses PR review: instead of throwing when --unrestricted is used on a
device/app that can't honor it, fall back to the auto-inferred signing mode
and log a warning. This keeps callers device-agnostic - a script can always
pass --unrestricted without first branching on device kind or app version.

- Add downgradeUnsupportedUnrestricted helper (crypto-providers/util.ts).
- Trezor and Keystone: warn + ignore instead of erroring.
- Ledger: check compatibility.supportsUnrestrictedTransaction from
  getVersion(); on app v7 and older, warn + fall back.
- Remove the now-unused Trezor/Keystone "not supported" errors.
- Reword the --unrestricted help (code + README): "Ledger app v8 or newer";
  "ignored (with a warning)" on Trezor/Keystone/older apps.
- Unit tests for the fallback helper.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>