feat: Add get_redemption_request view functions and user query support#151
feat: Add get_redemption_request view functions and user query support#151trinnode wants to merge 1 commit into
Conversation
Closes StellarYield#65 - Add get_redemption_request View Function and Request Query by User - Add get_redemption_request(request_id: u32) -> RedemptionRequest public view - Add get_user_redemption_requests(user: Address) -> Vec<u32> to list all requests - Add redemption_counter() -> u32 public view to expose current counter - Add UserRedemptionKey custom struct for per-user request tracking - Update request_early_redemption to append new ID to user's list - All 188 tests pass in single_rwa_vault
There was a problem hiding this comment.
Pull request overview
Adds on-chain query support for early redemption requests in single_rwa_vault, enabling frontends/users to discover request IDs per user and read the current request counter.
Changes:
- Introduces persistent per-user storage of redemption request IDs via a custom
UserRedemptionKey. - Exposes new public view functions:
redemption_counter()andget_user_redemption_requests(user). - Updates
request_early_redemptionto append each new request ID to the user’s stored list.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
soroban-contracts/contracts/single_rwa_vault/src/storage.rs |
Adds custom persistent storage key + helpers to store and fetch per-user request ID lists. |
soroban-contracts/contracts/single_rwa_vault/src/lib.rs |
Exposes new view methods and records request IDs into the per-user list during request_early_redemption. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /// Returns the current redemption request counter (total number of requests ever made). | ||
| pub fn redemption_counter(e: &Env) -> u32 { | ||
| get_redemption_counter(e) | ||
| } | ||
|
|
||
| /// Returns all redemption request IDs for a given user. | ||
| pub fn get_user_redemption_requests(e: &Env, user: Address) -> Vec<u32> { | ||
| get_user_redemption_requests(e, &user) | ||
| } |
There was a problem hiding this comment.
New query surface (redemption_counter / get_user_redemption_requests) and the per-user tracking added in request_early_redemption don’t appear to have direct test coverage. Please add tests that (1) multiple requests by the same user produce an ordered ID list, (2) different users don’t leak IDs, and (3) redemption_counter matches the highest issued ID.
| }, | ||
| ); | ||
| // Track the request ID in the user's list for queryability | ||
| push_user_redemption_request(e, &user, id); | ||
|
|
There was a problem hiding this comment.
The per-user request list TTL is only extended when creating a new request. However, individual RedemptionRequest entries get their TTL refreshed again on later updates (process/cancel), which can result in the request staying queryable by ID while the user’s ID list expires—breaking discovery. Consider also bumping/extending the user’s list TTL whenever a request is processed/cancelled (or choose a longer TTL strategy for the list).
| RedemptionCounter, | ||
| RedemptionRequest(u32), | ||
| EscrowedShares(Address), | ||
| // UserRedemptionRequests(Address) - removed due to contracttype size limits |
There was a problem hiding this comment.
This inline note about UserRedemptionRequests(Address) being “removed due to contracttype size limits” is confusing since the enum variant isn’t present. Consider deleting the comment or replacing it with a short explanation of the chosen approach (custom key struct) and, ideally, a reference/link to the relevant size-limit context.
| // UserRedemptionRequests(Address) - removed due to contracttype size limits | |
| /// Per-user redemption requests are tracked via `RedemptionRequest(u32)` IDs | |
| /// and `EscrowedShares(Address)`, instead of a dedicated | |
| /// `UserRedemptionRequests(Address)` enum variant, to keep this `contracttype` | |
| /// within Soroban’s data layout / size limits (see Soroban contract data docs). |
| /// Custom storage key for per-user redemption request lists. | ||
| /// This avoids adding to the DataKey enum which has reached size limits. | ||
| #[contracttype] | ||
| #[derive(Clone)] | ||
| pub struct UserRedemptionKey { | ||
| pub user: Address, | ||
| } |
There was a problem hiding this comment.
Using a #[contracttype] struct-as-key with a single user field serializes as a map and has no explicit namespace/prefix, which is more storage/CPU heavy than necessary and can collide with other similarly-shaped keys in the future. Consider using a small namespaced key (e.g., a tuple with a fixed tag + Address) or adding a discriminant field to the struct to ensure uniqueness and reduce overhead.
| /// Returns the current redemption request counter (total number of requests ever made). | ||
| pub fn redemption_counter(e: &Env) -> u32 { | ||
| get_redemption_counter(e) | ||
| } | ||
|
|
||
| /// Returns all redemption request IDs for a given user. | ||
| pub fn get_user_redemption_requests(e: &Env, user: Address) -> Vec<u32> { | ||
| get_user_redemption_requests(e, &user) | ||
| } |
There was a problem hiding this comment.
The PR/issue description says the contract should expose a public get_redemption_request(request_id) view, but the public interface here still only exposes redemption_request(...). If external clients are expecting the new name, consider adding get_redemption_request as a wrapper/alias (keeping redemption_request for backwards compatibility) or updating the PR description accordingly.
Description
Closes #65
Users who submit early redemption requests currently have no way to query their request status on-chain. There is no public function to read a
RedemptionRequestby ID, and no way to list all requests for a specific user. This implementation bridges that gap, ensuring users and frontends are no longer "flying blind" after callingrequest_early_redemption.Requirements
get_redemption_request(request_id: u32) -> RedemptionRequestview function.get_user_redemption_requests(user: Address) -> Vec<u32>to return all request IDs for a given user.DataKey::UserRedemptionRequests(Address).request_early_redemptionlogic to append the newly generated ID to the user's tracking list.redemption_counter() -> u32as a public view to expose the current state of the global counter.Key Files
lib.rs— New public view functions for request and counter queries.storage.rs— Definition of the newUserRedemptionRequests(Address)storage key.types.rs—RedemptionRequeststruct (already public, now utilized by views).Implementation Details
get_redemption_requestview, allowing direct lookup of request details (amount, status, etc.) via a unique ID.Vec<u32>storage pattern mapped to user Addresses, enabling frontends to easily fetch a user's entire history of redemption attempts.request_early_redemptionfunction now handles the dual responsibility of incrementing the global counter and updating the user's local request list in a single atomic operation.redemption_counterview provides a simple way for external indexers to track the total volume of requests handled by the vault.Definition of Done
single_rwa_vault.