Skip to content

Detect the connected wallet as a signer of a multisig authority - #220

Merged
luchobonatti merged 1 commit into
mainfrom
feat/219-signer-detection
Oct 9, 2026
Merged

luchobonatti merged 1 commit into
mainfrom
feat/219-signer-detection

Conversation

@luchobonatti

Copy link
Copy Markdown
Member

Summary

Closes #219

A signer of a multisig authority sees that authority's surfaces on /admin, with its signature standing.

Changes

  • Role holders are enumerated on chain (vault getters, get_role_member on the oracle and the share token, token admin)
  • Each account holder's signers and thresholds are read from Horizon; a wallet that is a signer is granted the holder's surfaces
  • Cards and the identity line show signs alone or 1 of N signatures; a single-key authority reads as before
  • A role held by a contract is never signable; a Horizon failure degrades to holder matching and says so
  • The local Horizon URL follows PUBLIC_STELLAR_HORIZON_URL

Acceptance criteria

  • Each role holder is read on chain and, when it is an account, its signers and thresholds are read from Horizon
  • A wallet that is a signer of an authority account is granted that authority's surfaces; the card and the identity line name the authority and show signs alone or 1 of N signatures
  • A role held by a contract is never treated as signable
  • A single-key authority keeps working unchanged
  • Tests cover signer, non-signer, threshold met and not met, contract-held role, and Horizon unavailable

Test plan

Automated tests

npm run test — 595 passing.

Manual verification

  1. On a local network, make governance a 2-of-2 multisig (setOptions: second signer weight 1, medium threshold 2).
  2. Open /admin as the second signer: Configuration and Governance read "Granted by vault governance — 1 of 2 signatures".
  3. Open /admin as the governance master key: same standing, since its weight is below the threshold.
  4. Open /admin as the single-key manager: "Granted by vault manager", no suffix.

Breaking changes

None.

Checklist

  • Self-reviewed my own diff
  • Tests added or updated
  • Docs updated (if applicable)
  • No unrelated changes bundled in

Screenshots

None.

Copilot AI balanced review requested due to automatic review settings October 8, 2026 13:43
@luchobonatti luchobonatti self-assigned this Oct 8, 2026
@vercel

vercel Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
strata-vault-kit-app Ready Ready Preview Oct 8, 2026 1:43pm UTC

Request Review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The multisig signer/threshold detection logic is non-trivial and security-adjacent (authority surface gating), warranting a final human review even though no defects were found and test coverage is thorough.

0 open findings

What changed in this PR

This PR teaches the /admin surface detection to recognise a wallet that is a signer of a multisig authority account, not only a wallet that is the authority address. It reworks useAdminAuthority to enumerate each role's on-chain holders (vault getters, get_admin, and get_role_member/get_role_member_count on the oracle and share token), then reads each account holder's signers and thresholds from Horizon via a new accountSigners helper. A wallet that signs for a holder account is granted that authority's surfaces, with the card and identity line showing signs alone, 1 of N signatures, or weight W of threshold T. Contract-held roles are never signable, and a Horizon failure degrades gracefully to holder matching while surfacing "Signer lookup unavailable." This is detection-only (execution with multiple signatures is tracked separately in #198/#199).

Changes:

  • New app-lib/accounts.ts (accountSigners) reads an account's ed25519 signers and thresholds from Horizon, returning null for contract addresses or on error.
  • useAdminAuthority now enumerates role members, matches the wallet against holder-account signers, and exposes grants + signersUnknown (replacing the prior roles/AuthorityReads shape).
  • AdminPanel renders signature standing on the identity line and cards; horizon is exported and the LOCAL Horizon host follows PUBLIC_STELLAR_HORIZON_URL.
File Description
app-lib/​accounts.ts New helper mapping an account's Horizon signers/thresholds; guards contract addresses and errors.
app-lib/​accounts.test.ts Unit tests for signer mapping, non-ed25519 filtering, missing account, and contract address.
app-lib/​wallet.ts Exports horizon and uses horizonUrl for the LOCAL host.
app-lib/​index.ts Re-exports the new accounts module.
app/​src/​hooks/​useAdminAuthority.ts Core rework: role-member enumeration, standingOf, readSigners, Grant/Standing types, signersUnknown.
app/​src/​hooks/​useAdminAuthority.test.ts Extensive tests for signer/non-signer, threshold, contract-held, and Horizon-unavailable cases.
app/​src/​pages/​AdminPanel.tsx Renders grant/standing descriptions and the "Signer lookup unavailable." note.
app/​src/​pages/​AdminPanel.test.tsx Tests identity line and card copy for the new standings.
app/​src/​App.test.tsx Updates the mock AdminAuthority shape (grants, signersUnknown).

🧠 Review effort: Balanced


Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.

@luchobonatti
luchobonatti added this pull request to stack #223 October 9, 2026 00:34
@luchobonatti
luchobonatti merged commit 077a9aa into main Oct 9, 2026
4 checks passed
@luchobonatti
luchobonatti deleted the feat/219-signer-detection branch October 9, 2026 13:37

This branch was successfully deployed

1 active deployment
Preview — 8fcfe610 Deployed Oct 8, 2026 by vercel[bot]
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.

Detect the connected wallet as a signer of a multisig authority

3 participants