Repository navigation
Detect the connected wallet as a signer of a multisig authority - #220
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
🔵 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, returningnullfor contract addresses or on error. useAdminAuthoritynow enumerates role members, matches the wallet against holder-account signers, and exposesgrants+signersUnknown(replacing the priorroles/AuthorityReadsshape).AdminPanelrenders signature standing on the identity line and cards;horizonis exported and the LOCAL Horizon host followsPUBLIC_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.
Summary
Closes #219
A signer of a multisig authority sees that authority's surfaces on
/admin, with its signature standing.Changes
get_role_memberon the oracle and the share token, token admin)signs aloneor1 of N signatures; a single-key authority reads as beforePUBLIC_STELLAR_HORIZON_URLAcceptance criteria
signs aloneor1 of N signaturesTest plan
Automated tests
npm run test— 595 passing.Manual verification
setOptions: second signer weight 1, medium threshold 2)./adminas the second signer: Configuration and Governance read "Granted by vault governance — 1 of 2 signatures"./adminas the governance master key: same standing, since its weight is below the threshold./adminas the single-key manager: "Granted by vault manager", no suffix.Breaking changes
None.
Checklist
Screenshots
None.