Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions modules/stablecoin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,23 @@ The result contains `accumulatedRateAtLastAccrual`, `lastAccruedAt`,
string. Projection uses saturating timestamp subtraction and the on-chain
seven-day compounding-window clamp. The method accepts no caller-provided time.

### `redemptionRateUpdateQuote()`

Reads Protocol Parameters, Redemption Price State, the configured market-price
oracle, and canonical `CLOCK_01` account, then quotes the next controller tick
without submitting a transaction. It projects the current redemption price
with the stored rate before calling the same pure controller used on-chain.

Ready quotes return `canSubmit: true`, `code: "ready"`, the current redemption
and market prices, elapsed milliseconds, next redemption rate, next controller
integral term, and integral/rate clamp bounds. All numeric values are exact
decimal strings.

A stale oracle, zero oracle price, or not-yet-due update returns a successful
read-only quote with `canSubmit: false`, `code: "blocked"`, machine-readable
`errors`, and explicit `null` next-controller values. Multiple blockers are
reported in on-chain gate order. The frozen flag does not block this operation.

### `initializeProgram(request)`

Required request fields:
Expand Down
8 changes: 8 additions & 0 deletions modules/stablecoin/ffi/include/stablecoin_ffi.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ char *stablecoin_decode_redemption_price_state(const char *request_json);
*/
char *stablecoin_current_global_state(const char *request_json);

/**
* Quotes the next redemption-rate controller update without submitting it.
*
* # Safety
* `request_json` must be null or point to a live NUL-terminated byte string.
*/
char *stablecoin_redemption_rate_update_quote(const char *request_json);

/**
* Builds the exact wallet submission plan for `InitializeProgram`.
*
Expand Down
3 changes: 3 additions & 0 deletions modules/stablecoin/ffi/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod decode;
mod plan;
mod program;
mod projection;
mod quote;
mod request;

#[cfg(test)]
Expand All @@ -17,9 +18,11 @@ pub use decode::{
pub use plan::initialize_program_plan;
pub use program::program_info;
pub use projection::current_global_state;
pub use quote::redemption_rate_update_quote;
pub use request::{
CurrentGlobalStateRequest, DecodeProtocolParametersRequest, DecodeRedemptionPriceStateRequest,
DecodeStabilityFeeAccumulatorRequest, InitializeProgramPlanRequest, ProgramInfoRequest,
RedemptionRateUpdateQuoteRequest,
};
use serde_json::Value;

Expand Down
2 changes: 1 addition & 1 deletion modules/stablecoin/ffi/src/api/projection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub fn current_global_state(request: CurrentGlobalStateRequest) -> StablecoinRes
}))
}

fn clock_timestamp(read: &crate::AccountRead) -> Result<u64, StablecoinApiError> {
pub(super) fn clock_timestamp(read: &crate::AccountRead) -> Result<u64, StablecoinApiError> {
let (account_id, account) =
decode_account(read).map_err(|_| StablecoinApiError::new("account_read_failed"))?;
if account_id != CLOCK_01_PROGRAM_ACCOUNT_ID {
Expand Down
Loading
Loading