Skip to content

Guardian auth component unrecognized by miden-standards AccountInterface — getPublicKeyCommitments() returns [] for Guardian accounts #306

Description

@WiktorStarczewski

Summary

A Guardian account's authentication component (built by @openzeppelin/miden-multisig-client) is not recognized by the Miden SDK's AccountInterface, so Account.getPublicKeyCommitments() returns [] for Guardian accounts. Any consumer that derives an account's public key through the SDK gets nothing back for Guardian accounts, while plain single-sig accounts work fine.

Environment

  • @openzeppelin/miden-multisig-client@0.15.0-rc.0
  • @miden-sdk/miden-sdk@0.15.2 (links miden-standards / miden-protocol 0.15.3)

Root cause

AccountInterface::from_account (miden-standards) classifies an account's components by exact MAST-root subset containment against a fixed set of bundled standard component templates, whose procedures live in the miden::standards::auth::* namespace.

A Guardian account's auth component is compiled at runtime from OZ's own MASM (auth_tx_multisig_guardian_ecdsa, using openzeppelin::auth::multisig_ecdsa / openzeppelin::auth::guardian_ecdsa). That is a different implementation in a different namespace, so its procedure MAST roots don't match any standard template — the component is bucketed as Custom. Custom is not an auth component, so interface.auth() is empty and account.getPublicKeyCommitments() returns [].

(Note: miden-standards does ship an AuthGuardedMultisig template, but it's a different implementation — miden::standards::auth::*, different exported procedures — so its roots can't match the OZ component.)

Reproduction

  1. Create a Guardian account via MultisigClient.create(...).
  2. Fetch it and call account.getPublicKeyCommitments()[].

A plain AuthSingleSig (BasicWallet) account returns its commitment as expected, so this is specific to the OZ component.

Impact

Anything that reads a Guardian account's public key via the SDK breaks. In the Miden wallet this surfaced as dApp connections failing with NOT_GRANTED (the connect flow derives a session public key from getPublicKeyCommitments()), plus the reveal-private-key and public-key display views. Third-party dApps / SDK users reading a Guardian account's key hit the same.

Request

Either:

  • Expose an accessor on MultisigClient / Multisig (or the account inspector) to read a Guardian account's signer public-key commitments (hot/cold) directly, so consumers don't reach into storage; or
  • Ship the component so miden-standards' AccountInterface recognizes it — align with a standard guarded-multisig template, or provide a registration hook so from_account can classify the OZ component and return its approver commitments.

Wallet-side workaround we shipped

For accounts the SDK can't classify, we read the hot signer's commitment directly from the openzeppelin::multisig::signer_public_keys storage map (index 0). It works, but it hardcodes OZ's storage layout, which we'd rather not depend on long-term — hence this request.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions