Home / Vacuum Labs / cardano-hw-cli
Jun 05, 1-2 PM (0)
Jun 05, 2-3 PM (0)
Jun 05, 3-4 PM (0)
Jun 05, 4-5 PM (0)
Jun 05, 5-6 PM (0)
Jun 05, 6-7 PM (0)
Jun 05, 7-8 PM (0)
Jun 05, 8-9 PM (0)
Jun 05, 9-10 PM (0)
Jun 05, 10-11 PM (0)
Jun 05, 11-12 AM (0)
Jun 06, 12-1 AM (0)
Jun 06, 1-2 AM (0)
Jun 06, 2-3 AM (0)
Jun 06, 3-4 AM (0)
Jun 06, 4-5 AM (0)
Jun 06, 5-6 AM (0)
Jun 06, 6-7 AM (0)
Jun 06, 7-8 AM (0)
Jun 06, 8-9 AM (0)
Jun 06, 9-10 AM (0)
Jun 06, 10-11 AM (0)
Jun 06, 11-12 PM (0)
Jun 06, 12-1 PM (0)
Jun 06, 1-2 PM (0)
Jun 06, 2-3 PM (0)
Jun 06, 3-4 PM (0)
Jun 06, 4-5 PM (0)
Jun 06, 5-6 PM (0)
Jun 06, 6-7 PM (0)
Jun 06, 7-8 PM (0)
Jun 06, 8-9 PM (0)
Jun 06, 9-10 PM (0)
Jun 06, 10-11 PM (0)
Jun 06, 11-12 AM (0)
Jun 07, 12-1 AM (0)
Jun 07, 1-2 AM (0)
Jun 07, 2-3 AM (0)
Jun 07, 3-4 AM (0)
Jun 07, 4-5 AM (0)
Jun 07, 5-6 AM (0)
Jun 07, 6-7 AM (0)
Jun 07, 7-8 AM (0)
Jun 07, 8-9 AM (0)
Jun 07, 9-10 AM (0)
Jun 07, 10-11 AM (0)
Jun 07, 11-12 PM (0)
Jun 07, 12-1 PM (0)
Jun 07, 1-2 PM (0)
Jun 07, 2-3 PM (0)
Jun 07, 3-4 PM (0)
Jun 07, 4-5 PM (0)
Jun 07, 5-6 PM (0)
Jun 07, 6-7 PM (0)
Jun 07, 7-8 PM (0)
Jun 07, 8-9 PM (0)
Jun 07, 9-10 PM (0)
Jun 07, 10-11 PM (0)
Jun 07, 11-12 AM (0)
Jun 08, 12-1 AM (0)
Jun 08, 1-2 AM (0)
Jun 08, 2-3 AM (0)
Jun 08, 3-4 AM (0)
Jun 08, 4-5 AM (0)
Jun 08, 5-6 AM (0)
Jun 08, 6-7 AM (0)
Jun 08, 7-8 AM (0)
Jun 08, 8-9 AM (0)
Jun 08, 9-10 AM (0)
Jun 08, 10-11 AM (0)
Jun 08, 11-12 PM (0)
Jun 08, 12-1 PM (0)
Jun 08, 1-2 PM (0)
Jun 08, 2-3 PM (0)
Jun 08, 3-4 PM (0)
Jun 08, 4-5 PM (0)
Jun 08, 5-6 PM (0)
Jun 08, 6-7 PM (0)
Jun 08, 7-8 PM (0)
Jun 08, 8-9 PM (0)
Jun 08, 9-10 PM (0)
Jun 08, 10-11 PM (0)
Jun 08, 11-12 AM (0)
Jun 09, 12-1 AM (0)
Jun 09, 1-2 AM (0)
Jun 09, 2-3 AM (0)
Jun 09, 3-4 AM (0)
Jun 09, 4-5 AM (0)
Jun 09, 5-6 AM (0)
Jun 09, 6-7 AM (0)
Jun 09, 7-8 AM (0)
Jun 09, 8-9 AM (0)
Jun 09, 9-10 AM (0)
Jun 09, 10-11 AM (0)
Jun 09, 11-12 PM (0)
Jun 09, 12-1 PM (0)
Jun 09, 1-2 PM (0)
Jun 09, 2-3 PM (0)
Jun 09, 3-4 PM (0)
Jun 09, 4-5 PM (0)
Jun 09, 5-6 PM (0)
Jun 09, 6-7 PM (0)
Jun 09, 7-8 PM (0)
Jun 09, 8-9 PM (0)
Jun 09, 9-10 PM (0)
Jun 09, 10-11 PM (0)
Jun 09, 11-12 AM (0)
Jun 10, 12-1 AM (0)
Jun 10, 1-2 AM (0)
Jun 10, 2-3 AM (0)
Jun 10, 3-4 AM (0)
Jun 10, 4-5 AM (0)
Jun 10, 5-6 AM (0)
Jun 10, 6-7 AM (0)
Jun 10, 7-8 AM (0)
Jun 10, 8-9 AM (0)
Jun 10, 9-10 AM (0)
Jun 10, 10-11 AM (0)
Jun 10, 11-12 PM (0)
Jun 10, 12-1 PM (0)
Jun 10, 1-2 PM (0)
Jun 10, 2-3 PM (0)
Jun 10, 3-4 PM (3)
Jun 10, 4-5 PM (0)
Jun 10, 5-6 PM (0)
Jun 10, 6-7 PM (0)
Jun 10, 7-8 PM (0)
Jun 10, 8-9 PM (0)
Jun 10, 9-10 PM (0)
Jun 10, 10-11 PM (0)
Jun 10, 11-12 AM (0)
Jun 11, 12-1 AM (0)
Jun 11, 1-2 AM (0)
Jun 11, 2-3 AM (0)
Jun 11, 3-4 AM (0)
Jun 11, 4-5 AM (0)
Jun 11, 5-6 AM (0)
Jun 11, 6-7 AM (0)
Jun 11, 7-8 AM (0)
Jun 11, 8-9 AM (8)
Jun 11, 9-10 AM (0)
Jun 11, 10-11 AM (2)
Jun 11, 11-12 PM (0)
Jun 11, 12-1 PM (0)
Jun 11, 1-2 PM (0)
Jun 11, 2-3 PM (0)
Jun 11, 3-4 PM (0)
Jun 11, 4-5 PM (0)
Jun 11, 5-6 PM (0)
Jun 11, 6-7 PM (0)
Jun 11, 7-8 PM (0)
Jun 11, 8-9 PM (1)
Jun 11, 9-10 PM (1)
Jun 11, 10-11 PM (0)
Jun 11, 11-12 AM (0)
Jun 12, 12-1 AM (0)
Jun 12, 1-2 AM (0)
Jun 12, 2-3 AM (0)
Jun 12, 3-4 AM (0)
Jun 12, 4-5 AM (0)
Jun 12, 5-6 AM (0)
Jun 12, 6-7 AM (0)
Jun 12, 7-8 AM (0)
Jun 12, 8-9 AM (0)
Jun 12, 9-10 AM (0)
Jun 12, 10-11 AM (0)
Jun 12, 11-12 PM (0)
Jun 12, 12-1 PM (0)
Jun 12, 1-2 PM (0)
15 commits this week Jun 05, 2026 - Jun 12, 2026
refactor: auto-apply unrestricted mode via --allow-unrestricted-mode
The flag becomes a permission instead of a request: determineSigningMode
picks the mode the tx shape and signing files point at, and falls back
to unrestricted mode only when that mode cannot sign the tx. The
canSignWith*Mode predicates mirror the per-signing-mode rejection rules
of ledgerjs parsing/transaction.ts clause by clause, which is verifiable
rule by rule — unlike the previous approach of enumerating tx shapes
that require unrestricted mode, which missed combinations (script
credentials without multisig files, path-resolvable credentials with
multisig files, reference inputs without collateral).

commandExecutor asserts the permission: signing in unrestricted mode
without --allow-unrestricted-mode or on a device that does not support
it (CryptoProvider.supportsUnrestrictedTransaction, named after the
ledgerjs compatibility field) is refused with a clear error.

Pool registration txs never fall back to unrestricted mode (it rejects
pool registration certs, too); they keep their POOL_REGISTRATION_* mode
so per-mode validation reports the violated rule precisely.

Co-Authored-By: Claude Fable 5 <[email protected]>
fix: allow bare key-hash committee hot credential in multisig mode
The ledgerjs per-mode rules constrain only the cold credential of
committee certs; the hot credential is the cert's subject, not its
authorizer, and its form is unconstrained in every signing mode. hw-cli
still refused to send it as a bare key hash outside ordinary mode, so a
multisig committee hot authorization whose hot key is not on the device
failed with a missing-signing-file error. Predates this branch.

Co-Authored-By: Claude Fable 5 <[email protected]>
fix: allow bare key-hash committee hot credential in multisig mode
The ledgerjs per-mode rules constrain only the cold credential of
committee certs; the hot credential is the cert's subject, not its
authorizer, and its form is unconstrained in every signing mode. hw-cli
still refused to send it as a bare key hash outside ordinary mode, so a
multisig committee hot authorization whose hot key is not on the device
failed with a missing-signing-file error. Predates this branch.

Co-Authored-By: Claude Fable 5 <[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]>
refactor: auto-apply unrestricted mode via --allow-unrestricted-mode
The flag becomes a permission instead of a request: determineSigningMode
picks the mode the tx shape and signing files point at, and falls back
to unrestricted mode only when that mode cannot sign the tx. The
canSignWith*Mode predicates mirror the per-signing-mode rejection rules
of ledgerjs parsing/transaction.ts clause by clause, which is verifiable
rule by rule — unlike the previous approach of enumerating tx shapes
that require unrestricted mode, which missed combinations (script
credentials without multisig files, path-resolvable credentials with
multisig files, reference inputs without collateral).

commandExecutor asserts the permission: signing in unrestricted mode
without --allow-unrestricted-mode or on a device that does not support
it (CryptoProvider.supportsUnrestrictedTransaction, named after the
ledgerjs compatibility field) is refused with a clear error.

Pool registration txs never fall back to unrestricted mode (it rejects
pool registration certs, too); they keep their POOL_REGISTRATION_* mode
so per-mode validation reports the violated rule precisely.

Co-Authored-By: Claude Fable 5 <[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-beta for Ledger app v8 support
Pull in @cardano-foundation/ledgerjs-hw-app-cardano 8.0.0-beta from npm
(Ledger app v8: unrestricted signing mode, combined certificates).

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]>
Co-Authored-By: Claude Fable 5 <[email protected]>
fix: allow bare key-hash committee hot credential in multisig mode
The ledgerjs per-mode rules constrain only the cold credential of
committee certs; the hot credential is the cert's subject, not its
authorizer, and its form is unconstrained in every signing mode. hw-cli
still refused to send it as a bare key hash outside ordinary mode, so a
multisig committee hot authorization whose hot key is not on the device
failed with a missing-signing-file error. Predates this branch.

Co-Authored-By: Claude Fable 5 <[email protected]>
refactor: auto-apply unrestricted mode via --allow-unrestricted-mode
The flag becomes a permission instead of a request: determineSigningMode
picks the mode the tx shape and signing files point at, and falls back
to unrestricted mode only when that mode cannot sign the tx. The
canSignWith*Mode predicates mirror the per-signing-mode rejection rules
of ledgerjs parsing/transaction.ts clause by clause, which is verifiable
rule by rule — unlike the previous approach of enumerating tx shapes
that require unrestricted mode, which missed combinations (script
credentials without multisig files, path-resolvable credentials with
multisig files, reference inputs without collateral).

commandExecutor asserts the permission: signing in unrestricted mode
without --allow-unrestricted-mode or on a device that does not support
it (CryptoProvider.supportsUnrestrictedTransaction, named after the
ledgerjs compatibility field) is refused with a clear error.

Pool registration txs never fall back to unrestricted mode (it rejects
pool registration certs, too); they keep their POOL_REGISTRATION_* mode
so per-mode validation reports the violated rule precisely.

Co-Authored-By: Claude Fable 5 <[email protected]>