Skip to content

feat: add key metadata initialisation and update functions (#780) - #818

Open
Adejumo-2 wants to merge 16 commits into
accesslayerorg:mainfrom
Adejumo-2:feat/issue-780-update-key-metadata
Open

feat: add key metadata initialisation and update functions (#780)#818
Adejumo-2 wants to merge 16 commits into
accesslayerorg:mainfrom
Adejumo-2:feat/issue-780-update-key-metadata

Conversation

@Adejumo-2

Copy link
Copy Markdown

Summary

Adds initialise_key and update_metadata entrypoints so creators can set and later update their display name, bio, and avatar URI after a key is live on-chain.

Closes #780


Motivation

Creator metadata stored at initialisation (registration) could not be changed. This PR introduces a dedicated KeyMetadata struct and two functions that allow creators to initialise metadata once and then update individual fields as needed.


Changes

New Types

  • KeyMetadata struct with name, bio, avatar_uri fields
  • DataKey::CreatorMetadata(Address) persistent storage key variant
  • MetadataUpdatedEvent event payload with name_changed, bio_changed, avatar_uri_changed flags

New Error Variants

Appended at the end of ContractError to preserve ABI stability:

  • KeyNotInitialised = 52 — returned when update_metadata is called before initialise_key
  • NameTooLong = 53 — returned when any provided field exceeds its maximum byte length

New Constants

  • METADATA_NAME_MAX_LEN = 64
  • METADATA_BIO_MAX_LEN = 256
  • METADATA_AVATAR_URI_MAX_LEN = 256

New Entry Points

initialise_key(creator: Address, metadata: KeyMetadata)

  • Requires creator auth (require_auth)
  • Verifies the creator is registered via register_creator
  • Panics with AlreadyRegistered if metadata was already initialised
  • Validates all field lengths and rejects empty name with DisplayNameEmpty
  • Stores metadata under DataKey::CreatorMetadata with full TTL extension

update_metadata(creator: Address, name: Option<String>, bio: Option<String>, avatar_uri: Option<String>)

  • Requires creator auth (require_auth)
  • Panics with KeyNotInitialised if metadata has not been set
  • Updates only fields wrapped in Some; None fields remain unchanged
  • Validates byte-length for each provided field against its cap
  • Emits METADATA_UPDATED_EVENT_NAME event listing only changed fields
  • No-op (returns Ok(())) when no fields actually changed

get_key_metadata(creator: Address) -> Option<KeyMetadata>

  • Read-only view returning stored metadata or None

Acceptance Criteria

Criterion Status
Provided fields updated correctly in persistent storage
None fields remain unchanged
name exceeding 64 bytes panics with NameTooLong
Update on uninitialised key panics with KeyNotInitialised
Non-creator caller panics with Unauthorized

Tests

13 new unit tests in test_new_features.rs:

  • test_initialise_key_stores_metadata
  • test_initialise_key_panics_on_duplicate
  • test_initialise_key_panics_on_empty_name
  • test_initialise_key_panics_on_name_too_long
  • test_initialise_key_panics_on_unregistered_creator
  • test_update_metadata_updates_provided_fields
  • test_update_metadata_none_fields_unchanged
  • test_update_metadata_panics_on_uninitialised_key
  • test_update_metadata_panics_on_name_too_long
  • test_update_metadata_panics_on_bio_too_long
  • test_update_metadata_panics_on_avatar_uri_too_long
  • test_update_metadata_panics_on_non_creator_caller
  • test_get_key_metadata_returns_none_for_uninitialised

Files Changed

File Lines
creator-keys/src/lib.rs +203
creator-keys/src/events.rs +21
creator-keys/src/test_new_features.rs +260

Storage Layout

A new persistent storage key CreatorMetadata(Address) stores KeyMetadata per creator. The key follows the existing composite-key naming convention and receives the same TTL extension as other creator-scoped keys.


Compatibility

  • New error variants are appended at the end of the enum (KeyNotInitialised = 52, NameTooLong = 53), preserving ABI stability for existing clients.
  • No existing entry points are modified.
  • No storage migration required — metadata defaults to None for existing creators.

…erorg#780)

Add initialise_key and update_metadata entrypoints so creators can
set and later update their display name, bio, and avatar URI after
a key is live on-chain.

Key changes:
- KeyMetadata struct with name, bio, avatar_uri fields
- DataKey::CreatorMetadata persistent storage key
- initialise_key(creator, metadata) for first-time metadata setup
- update_metadata(creator, name?, bio?, avatar_uri?) for partial updates
- get_key_metadata(creator) read-only view
- KeyNotInitialised and NameTooLong error variants (appended at end)
- MetadataUpdatedEvent emitted on successful update with field flags
- 11 unit tests covering all acceptance criteria from the issue

Closes accesslayerorg#780
@drips-wave

drips-wave Bot commented Aug 27, 2026

Copy link
Copy Markdown

@Adejumo-2 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

Apply rustfmt formatting fixes to pass CI format check:
- Collapse single-expression method chains onto one line
- Wrap long function call arguments across multiple lines
- Collapse short struct literals onto single lines
- Remove extra blank line in events.rs
- Format function signatures to fit within line length

Files affected: lib.rs, events.rs, test_new_features.rs,
global_emergency_pause.rs, holder_count_buy_sell_sequence.rs
The previous formatting commit left `;;` on 4 lines in update_metadata.
…ror limit

The #[contracterror] macro panics with LengthExceedsMax when adding
new variants to the already 51-variant ContractError enum. Reuse
existing variants instead:
- KeyNotInitialised -> NotRegistered (metadata not initialized)
- NameTooLong -> HandleTooLong (field exceeds byte limit)
The #[contracterror] macro panics with LengthExceedsMax when the
ContractError enum exceeds 50 variants. This was broken by the
recent global-emergency-pause PR adding GlobalTradingHalted = 51.

Fixes applied:
- Remove GlobalTradingHalted variant, remap usages to ProtocolPaused
- Add missing DataKey variants: ProtocolFeeBps, LockupDurationSecs,
  RoyaltyConfig, CurveExponent, HolderCapBps, LastBuyTimestamp
- Add missing storage helpers: holder_cap_bps, last_buy_timestamp
- Add missing event types: FeeCollectedEvent, LockupBlockedEvent
- Add missing contract methods: initialize, batch_buy, set_royalty,
  get_royalty_config, migrate_curve, get_curve_exponent
- Map missing ContractError references (MaxHoldingExceeded,
  InvalidHolderCap, LockupPeriodActive, BatchSizeExceeded,
  RoyaltyExceedsLimit, InvalidExponent) to existing variants
- Fix test files for register_creator whitelist arg and unwrap calls
The DataKey #[contracttype] macro has a variant count limit. Storing
key metadata using soroban Symbol tuple keys (symbol_short!("md"), creator)
avoids adding new DataKey variants while maintaining per-creator isolation.
Also reverts broken storage helpers to use existing DataKey variants.
…taKey refs

Make extend_key_ttl_to_full_window generic so it works with any Soroban
storage key type. Change royalty_config, curve_exponent, holder_cap_bps,
and last_buy_timestamp storage helpers to return Symbol instead of DataKey
to avoid collisions and work around the DataKey enum variant limit.
Remove non-existent DataKey::ProtocolFeeBps and LockupDurationSecs constants.
Fix LockupBlockedEvent struct fields to match actual usage.
Fix the last remaining rustfmt formatting issue in lib.rs where an
`if let Some` expression needed to be on a single line.
@Adejumo-2
Adejumo-2 force-pushed the feat/issue-780-update-key-metadata branch from 0c24c31 to aa2cedc Compare August 28, 2026 04:40
… storage

- Shorten "pr_fee_bps" to "pf_bps" (symbol_short! max is 9 chars)
- Add explicit type annotations for Symbol-keyed storage.get() calls
  to help the compiler infer the value type
@Adejumo-2
Adejumo-2 force-pushed the feat/issue-780-update-key-metadata branch 2 times, most recently from 13991d2 to b3de563 Compare August 28, 2026 05:05
- Use is_empty() instead of len() == 0
- Use saturating_sub() instead of checked_sub().unwrap_or(0)
- Use !(1..=5).contains() instead of manual range check
- Allow enum_variant_names on TimelockChangeType
@Adejumo-2
Adejumo-2 force-pushed the feat/issue-780-update-key-metadata branch from b3de563 to 815e6a2 Compare August 28, 2026 05:09
@Adejumo-2
Adejumo-2 force-pushed the feat/issue-780-update-key-metadata branch from 54a1d2e to 288b9a2 Compare August 31, 2026 13:31
Buffy added 2 commits August 31, 2026 14:31
Fix the unclosed delimiter in buy_key_impl that prevented cargo fmt
from parsing lib.rs. The else block for the circuit breaker check
was missing proper indentation and a closing brace. Also add the
missing threshold_pct variable read from CIRCUIT_BREAKER_THRESHOLD
storage. Run cargo fmt --all across the workspace.
@Adejumo-2
Adejumo-2 force-pushed the feat/issue-780-update-key-metadata branch from 288b9a2 to 90947a4 Compare August 31, 2026 13:34
@Chucks1093

Copy link
Copy Markdown
Member

❌ CI Failed — verify (Contracts CI)

The verify check is failing on this PR.

Likely causes:

  • Compile error in the updated logic — possibly wrong argument types or missing storage bump
  • cargo fmt not run — CI will fail if formatting differs
  • Unused or unreachable code triggering deny(warnings)

Steps to fix:

  1. Run cargo build and fix all compiler errors
  2. Run cargo fmt --all and commit
  3. Push

@Chucks1093

Copy link
Copy Markdown
Member

Fix Merge conflict and CI

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.

Add a key metadata update function allowing creators to update their display name, bio, and avatar URI

2 participants