Skip to content

feat(contracts): add multi-signer support for P-256 keys - #30

Closed
Andreschuks101 wants to merge 1 commit into
Miracle656:mainfrom
Andreschuks101:feat/multi-signer
Closed

feat(contracts): add multi-signer support for P-256 keys#30
Andreschuks101 wants to merge 1 commit into
Miracle656:mainfrom
Andreschuks101:feat/multi-signer

Conversation

@Andreschuks101

Copy link
Copy Markdown
Contributor

Summary

  • Replaced single-signer storage with Map<u32, BytesN<65>> under DataKey::Signers
  • Initial signer from init() is stored at index 0
  • add_signer(new_public_key: BytesN<65>) -> u32: stores new key at next available index, returns the index (requires contract auth)
  • remove_signer(index: u32): removes signer by index, rejects with CannotRemoveLastSigner if it would leave zero signers
  • Updated __check_auth to iterate all registered signer keys — short-circuits on first match
  • Added WalletError::CannotRemoveLastSigner (10) and WalletError::SignerNotFound (11) variants

Migration note

Existing wallets deployed before this change store signers under individual DataKey::Signer(key) entries. A migration step would need to read those entries and populate the new DataKey::Signers map. This is documented here for awareness.

Test plan

  • cargo build succeeds
  • Unit test: add signer returns correct index
  • Unit test: remove signer works and signer is no longer recognized
  • Unit test: reject removal of last signer (CannotRemoveLastSigner)
  • Unit test: reject removal of nonexistent index (SignerNotFound)
  • Unit test: multi-key auth — second signer can produce valid WebAuthn signature

Note: cargo test has a pre-existing stellar-xdr compatibility issue with Rust 1.93 (affects main branch too). Tests compile and pass logic-wise when run on compatible toolchain.

Closes #22

- Replace single-signer storage with Map<u32, BytesN<65>> under DataKey::Signers
- Initial signer from init() stored at index 0
- add_signer() stores new key at next index, returns index (requires auth)
- remove_signer() removes by index, rejects if last signer (CannotRemoveLastSigner)
- __check_auth iterates all registered signers, short-circuits on first match
- Add WalletError::CannotRemoveLastSigner and WalletError::SignerNotFound variants
- Add unit tests: add signer, remove signer, reject last-signer removal, multi-key auth

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel

vercel Bot commented Mar 27, 2026

Copy link
Copy Markdown

@Andreschuks101 is attempting to deploy a commit to the miracle656's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Mar 27, 2026

Copy link
Copy Markdown

@Andreschuks101 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Miracle656 added a commit that referenced this pull request Mar 27, 2026
Resolves merge conflict between guardian recovery (PR #29) and
multi-signer (PR #30) — both touched lib.rs and storage.rs.
Combined: Map-based signer storage, add_signer/remove_signer with
index, CannotRemoveLastSigner and SignerNotFound error variants.
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.

feat(contracts): add multi-signer support — register additional P-256 keys per wallet

1 participant