diff --git a/.gitignore b/.gitignore
index cee20a5c..f6be50b5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,6 +22,10 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
+# not pnpm lockfiles
+package-lock.json
+yarn.lock
+
# others
.env*.local
.vercel
diff --git a/content/contracts-sui/1.x/access.mdx b/content/contracts-sui/1.x/access.mdx
new file mode 100644
index 00000000..d2672cee
--- /dev/null
+++ b/content/contracts-sui/1.x/access.mdx
@@ -0,0 +1,55 @@
+---
+title: Access
+---
+
+The `openzeppelin_access` package provides ownership-transfer wrappers for privileged Sui objects (`T: key + store`), such as admin and treasury capabilities.
+
+Use this package when direct object transfer is too permissive for your protocol. It gives you explicit transfer workflows that are easier to review, monitor, and constrain with policy.
+
+
+This package is designed for single-owned objects. In `two_step_transfer`, `ctx.sender()` is stored as the owner-of-record for pending requests. Avoid using this policy directly in shared-object executor flows unless your design explicitly maps signer identity to cancel authority.
+
+
+## Usage
+
+Add the dependency in `Move.toml`:
+
+```toml
+[dependencies]
+openzeppelin_access = { r.mvr = "@openzeppelin-move/access" }
+```
+
+Import the transfer policy module you want to use:
+
+```move
+use openzeppelin_access::two_step_transfer;
+```
+
+## Examples
+
+```move
+module my_sui_app::admin;
+
+use openzeppelin_access::two_step_transfer;
+
+public struct AdminCap has key, store {
+ id: object::UID,
+}
+
+public fun wrap_admin_cap(
+ cap: AdminCap,
+ ctx: &mut TxContext,
+): two_step_transfer::TwoStepTransferWrapper {
+ // Wrap the capability object to force a two-step transfer policy.
+ two_step_transfer::wrap(cap, ctx)
+}
+```
+
+## Choosing a transfer policy
+
+- Use `two_step_transfer` when the signer triggering transfer initiation is the same principal that should retain cancel authority.
+- Use `delayed_transfer` when protocol safety requires on-chain lead time before transfer or unwrap execution, and when initial wrapper custody should be assigned explicitly at wrap time.
+
+## API Reference
+
+Use the full function-level reference here: [Access API](/contracts-sui/1.x/api/access).
diff --git a/content/contracts-sui/1.x/api/access.mdx b/content/contracts-sui/1.x/api/access.mdx
new file mode 100644
index 00000000..fe819308
--- /dev/null
+++ b/content/contracts-sui/1.x/api/access.mdx
@@ -0,0 +1,599 @@
+---
+title: Access API Reference
+---
+
+This page documents the public API of `openzeppelin_access` for OpenZeppelin Contracts for Sui `v1.x`.
+
+### `two_step_transfer` [toc] [#two_step_transfer]
+
+
+
+```move
+use openzeppelin_access::two_step_transfer;
+```
+
+Two-step ownership wrapper for `T: key + store` objects. Transfers require explicit initiation and acceptance, with cancellation authority bound to the recorded initiator (`ctx.sender()` at initiation time).
+
+This module is designed for flows with a single logical owner. Avoid using it directly in shared-object custody flows where arbitrary executors can trigger `initiate_transfer`, because the initiator becomes the recorded cancel authority.
+
+Types
+
+- [`WrappedKey`](#two_step_transfer-WrappedKey)
+- [`TwoStepTransferWrapper`](#two_step_transfer-TwoStepTransferWrapper)
+- [`PendingOwnershipTransfer`](#two_step_transfer-PendingOwnershipTransfer)
+- [`Borrow`](#two_step_transfer-Borrow)
+- [`RequestBorrow`](#two_step_transfer-RequestBorrow)
+
+Functions
+
+- [`wrap(obj, ctx)`](#two_step_transfer-wrap)
+- [`borrow(self)`](#two_step_transfer-borrow)
+- [`borrow_mut(self)`](#two_step_transfer-borrow_mut)
+- [`borrow_val(self)`](#two_step_transfer-borrow_val)
+- [`return_val(self, obj, borrow)`](#two_step_transfer-return_val)
+- [`unwrap(self, ctx)`](#two_step_transfer-unwrap)
+- [`initiate_transfer(self, new_owner, ctx)`](#two_step_transfer-initiate_transfer)
+- [`accept_transfer(request, wrapper_ticket, ctx)`](#two_step_transfer-accept_transfer)
+- [`cancel_transfer(request, wrapper_ticket, ctx)`](#two_step_transfer-cancel_transfer)
+- [`request_borrow_val(request, wrapper_ticket, ctx)`](#two_step_transfer-request_borrow_val)
+- [`request_return_val(request, wrapper, borrow)`](#two_step_transfer-request_return_val)
+
+Events
+
+- [`WrapExecuted`](#two_step_transfer-WrapExecuted)
+- [`UnwrapExecuted`](#two_step_transfer-UnwrapExecuted)
+- [`TransferInitiated`](#two_step_transfer-TransferInitiated)
+- [`TransferAccepted`](#two_step_transfer-TransferAccepted)
+- [`TransferCancelled`](#two_step_transfer-TransferCancelled)
+
+Errors
+
+- [`EInvalidTransferRequest`](#two_step_transfer-EInvalidTransferRequest)
+- [`EWrongTwoStepTransferWrapper`](#two_step_transfer-EWrongTwoStepTransferWrapper)
+- [`EWrongTwoStepTransferObject`](#two_step_transfer-EWrongTwoStepTransferObject)
+- [`ENotOwner`](#two_step_transfer-ENotOwner)
+- [`ENotNewOwner`](#two_step_transfer-ENotNewOwner)
+
+#### Types [!toc] [#two_step_transfer-Types]
+
+
+Dynamic object-field key used to store the wrapped object under the wrapper.
+
+
+
+Wrapper object that custody-locks an underlying object and controls transfer flow.
+
+The wrapper intentionally omits `store` so transfer paths stay constrained to this module's logic.
+
+
+
+Shared pending-transfer object storing wrapper identity, current owner (`from`), and prospective owner (`to`).
+
+Wrapper custody is held by this request object through transfer-to-object (TTO) until accept/cancel resolution.
+
+
+
+Hot-potato guard proving that a value taken via `borrow_val` is returned to the same wrapper.
+
+
+
+Hot-potato guard proving a wrapper borrowed through a pending request is returned to that request.
+
+
+#### Functions [!toc] [#two_step_transfer-Functions]
+
+
+Wraps `obj` in a new transfer wrapper.
+The wrapped object is stored as a dynamic object field so off-chain indexers can still discover the underlying object ID.
+
+Emits a `WrapExecuted` event.
+
+
+
+Returns immutable access to the wrapped object.
+
+
+
+Returns mutable access to the wrapped object without changing ownership state.
+
+
+
+Temporarily extracts the wrapped object and returns a `Borrow` guard that must be consumed by `return_val`.
+
+
+
+Returns a previously borrowed object to the wrapper.
+
+Aborts when wrapper/object identity checks fail.
+
+
+
+Destroys the wrapper and returns the underlying object directly to the caller.
+
+This bypasses pending-request flow and recovers direct ownership of the wrapped object.
+
+Emits an `UnwrapExecuted` event.
+
+
+
+Starts a transfer by creating a shared request and transferring wrapper custody to that request.
+
+Security note: cancellation authority is tied to the initiating signer recorded as `from`.
+Only use this flow when the signer executing initiation is intentionally the logical owner/cancel authority.
+
+Emits a `TransferInitiated` event.
+
+
+
+Completes a pending transfer and sends the wrapper to the designated new owner.
+
+Aborts if caller is not `request.to` or wrapper identity does not match.
+
+Emits a `TransferAccepted` event.
+
+
+
+Cancels a pending transfer and returns the wrapper to `request.from`.
+
+Aborts if caller is not `request.from` or wrapper identity does not match.
+
+Emits a `TransferCancelled` event.
+
+
+
+Receives wrapper custody from a shared request so the recorded owner can operate on the wrapped object during a pending transfer.
+
+Aborts if caller is not `request.from` or if request/wrapper identity checks fail.
+
+
+
+Returns a wrapper borrowed via `request_borrow_val` back to the pending request.
+
+Aborts if either `wrapper` or `borrow` does not match the target request.
+
+
+#### Events [!toc] [#two_step_transfer-Events]
+
+
+Emitted when an object is wrapped.
+
+
+
+Emitted when an object is unwrapped.
+
+
+
+Emitted when a two-step transfer request is created.
+
+
+
+Emitted when a pending transfer is accepted and ownership moves to the new owner.
+
+
+
+Emitted when a pending transfer is cancelled.
+
+
+#### Errors [!toc] [#two_step_transfer-Errors]
+
+
+Raised when request and wrapper identities do not match.
+
+
+
+Raised when a `Borrow` guard is used against a different wrapper.
+
+
+
+Raised when returning an object different from the one originally borrowed.
+
+
+
+Raised when caller is not authorized as the current owner for the requested operation.
+
+
+
+Raised when caller is not the designated prospective owner in `accept_transfer`.
+
+
+### `delayed_transfer` [toc] [#delayed_transfer]
+
+
+
+```move
+use openzeppelin_access::delayed_transfer;
+```
+
+Time-locked ownership wrapper for `T: key + store`. The wrapped object is placed under a wrapper that is immediately transferred to a chosen recipient. After that, transfers and unwraps must be scheduled and can only execute after `min_delay_ms` elapses.
+
+Types
+
+- [`WrappedKey`](#delayed_transfer-WrappedKey)
+- [`DelayedTransferWrapper`](#delayed_transfer-DelayedTransferWrapper)
+- [`PendingTransfer`](#delayed_transfer-PendingTransfer)
+- [`Borrow`](#delayed_transfer-Borrow)
+
+Functions
+
+- [`wrap(obj, min_delay_ms, recipient, ctx)`](#delayed_transfer-wrap)
+- [`borrow(self)`](#delayed_transfer-borrow)
+- [`borrow_mut(self)`](#delayed_transfer-borrow_mut)
+- [`borrow_val(self)`](#delayed_transfer-borrow_val)
+- [`return_val(self, obj, borrow)`](#delayed_transfer-return_val)
+- [`schedule_transfer(self, new_owner, clock, ctx)`](#delayed_transfer-schedule_transfer)
+- [`schedule_unwrap(self, clock, ctx)`](#delayed_transfer-schedule_unwrap)
+- [`execute_transfer(self, clock, ctx)`](#delayed_transfer-execute_transfer)
+- [`unwrap(self, clock, ctx)`](#delayed_transfer-unwrap)
+- [`cancel_schedule(self)`](#delayed_transfer-cancel_schedule)
+
+Events
+
+- [`WrapExecuted`](#delayed_transfer-WrapExecuted)
+- [`TransferScheduled`](#delayed_transfer-TransferScheduled)
+- [`UnwrapScheduled`](#delayed_transfer-UnwrapScheduled)
+- [`OwnershipTransferred`](#delayed_transfer-OwnershipTransferred)
+- [`PendingTransferCancelled`](#delayed_transfer-PendingTransferCancelled)
+- [`UnwrapExecuted`](#delayed_transfer-UnwrapExecuted)
+
+Errors
+
+- [`ETransferAlreadyScheduled`](#delayed_transfer-ETransferAlreadyScheduled)
+- [`ENoPendingTransfer`](#delayed_transfer-ENoPendingTransfer)
+- [`EDelayNotElapsed`](#delayed_transfer-EDelayNotElapsed)
+- [`EWrongPendingAction`](#delayed_transfer-EWrongPendingAction)
+- [`EWrongDelayedTransferWrapper`](#delayed_transfer-EWrongDelayedTransferWrapper)
+- [`EWrongDelayedTransferObject`](#delayed_transfer-EWrongDelayedTransferObject)
+
+#### Types [!toc] [#delayed_transfer-Types]
+
+
+Dynamic object-field key used to store the wrapped object under the wrapper.
+
+
+
+Wrapper object storing `min_delay_ms` and optional pending schedule state.
+
+
+
+Represents a scheduled transfer (`recipient = some`) or scheduled unwrap (`recipient = none`).
+
+
+
+Hot-potato guard proving a value extracted with `borrow_val` is returned to the same wrapper.
+
+
+#### Functions [!toc] [#delayed_transfer-Functions]
+
+
+Wraps `obj` in a delayed-transfer wrapper, records the minimum execution delay, and transfers initial wrapper custody to `recipient`.
+
+The wrapped object is stored under a dynamic object field so object ID discovery remains straightforward for indexers.
+
+Emits a `WrapExecuted` event.
+
+
+
+Returns immutable access to the wrapped object.
+
+
+
+Returns mutable access to the wrapped object.
+
+
+
+Temporarily extracts the wrapped object and returns a guard that must be consumed by `return_val`.
+
+
+
+Returns a previously borrowed object to its wrapper.
+
+Aborts when wrapper/object identity checks fail.
+
+
+
+Schedules a transfer to `new_owner` at `clock.timestamp_ms() + min_delay_ms`.
+
+Aborts when another action is already scheduled.
+
+Emits a `TransferScheduled` event.
+
+
+
+Schedules delayed self-recovery (unwrap) of the wrapped object.
+
+Aborts when another action is already scheduled.
+
+Emits an `UnwrapScheduled` event.
+
+
+
+Executes a scheduled transfer once delay has elapsed.
+
+Consumes the wrapper.
+
+Aborts when no transfer is scheduled, wrong action type is scheduled, or delay has not elapsed.
+
+Emits an `OwnershipTransferred` event on success.
+
+
+
+Executes a scheduled unwrap once delay has elapsed and returns the wrapped object.
+
+Aborts when no unwrap is scheduled, wrong action type is scheduled, or delay has not elapsed.
+
+Emits an `UnwrapExecuted` event.
+
+
+
+Cancels the currently scheduled transfer or unwrap action.
+
+Aborts when no action is pending.
+
+Emits a `PendingTransferCancelled` event.
+
+
+#### Events [!toc] [#delayed_transfer-Events]
+
+
+Emitted when an object is wrapped.
+
+
+
+Emitted when a delayed transfer is scheduled.
+
+
+
+Emitted when delayed unwrap is scheduled.
+
+
+
+Emitted when scheduled transfer execution completes.
+
+
+
+Emitted when pending schedule is cancelled.
+
+
+
+Emitted when delayed unwrap execution completes.
+
+
+#### Errors [!toc] [#delayed_transfer-Errors]
+
+
+Raised when trying to schedule while another action is already pending.
+
+
+
+Raised when execution/cancellation is requested without pending state.
+
+
+
+Raised when execution occurs before `execute_after_ms`.
+
+
+
+Raised when calling transfer execution on unwrap state (or vice versa).
+
+
+
+Raised when a `Borrow` guard is used against a different wrapper.
+
+
+
+Raised when returning an object different from the one originally borrowed.
+
diff --git a/content/contracts-sui/1.x/api/math.mdx b/content/contracts-sui/1.x/api/math.mdx
new file mode 100644
index 00000000..3f9456e6
--- /dev/null
+++ b/content/contracts-sui/1.x/api/math.mdx
@@ -0,0 +1,422 @@
+---
+title: Integer Math API Reference
+---
+
+This page documents the public API of `openzeppelin_math` for OpenZeppelin Contracts for Sui `v1.x`.
+
+### `rounding` [toc] [#rounding]
+
+
+
+```move
+use openzeppelin_math::rounding;
+```
+
+Rounding strategy helpers shared by arithmetic operations across width-specific modules.
+
+Types
+
+- [`RoundingMode`](#rounding-RoundingMode)
+
+Functions
+
+- [`down()`](#rounding-down)
+- [`up()`](#rounding-up)
+- [`nearest()`](#rounding-nearest)
+
+#### Types [!toc] [#rounding-Types]
+
+
+`Down` always rounds toward zero, `Up` rounds toward ceiling, and `Nearest` rounds to the closest integer with ties rounded up.
+
+
+#### Functions [!toc] [#rounding-Functions]
+
+
+Returns `RoundingMode::Down`.
+
+
+
+Returns `RoundingMode::Up`.
+
+
+
+Returns `RoundingMode::Nearest` (round-half-up behavior).
+
+
+### `decimal_scaling` [toc] [#decimal_scaling]
+
+
+
+```move
+use openzeppelin_math::decimal_scaling;
+```
+
+Helpers for converting balances between decimal precisions while enforcing safe casts and explicit truncation semantics.
+
+Functions
+
+- [`safe_downcast_balance(raw_amount, source_decimals, target_decimals)`](#decimal_scaling-safe_downcast_balance)
+- [`safe_upcast_balance(amount, source_decimals, target_decimals)`](#decimal_scaling-safe_upcast_balance)
+
+Errors
+
+- [`ESafeDowncastOverflowedInt`](#decimal_scaling-ESafeDowncastOverflowedInt)
+- [`EInvalidDecimals`](#decimal_scaling-EInvalidDecimals)
+
+#### Functions [!toc] [#decimal_scaling-Functions]
+
+
+Converts a `u256` amount to `u64` across decimal domains. When scaling down (`source_decimals > target_decimals`), fractional residue is truncated, not rounded.
+
+Aborts when decimals exceed 24 or when the scaled value cannot fit in `u64`.
+
+
+
+Converts a `u64` amount to `u256` across decimal domains.
+
+Scaling up preserves precision. Scaling down truncates fractional residue (no rounding). Aborts when decimal values exceed the supported range.
+
+
+#### Errors [!toc] [#decimal_scaling-Errors]
+
+
+Raised when a downcast path would require representing a value larger than `u64::MAX`.
+
+
+
+Raised when either decimal argument is greater than the package limit (`24`).
+
+
+### Unsigned width modules [toc] [#unsigned-width-modules]
+
+These modules expose a consistent API surface across unsigned widths.
+
+Each module wraps shared arithmetic helpers with width-specific bit limits and representability checks.
+
+Source modules:
+
+- [`u8.move`](https://github.com/OpenZeppelin/contracts-sui/blob/v1.0.0/math/core/sources/u8.move)
+- [`u16.move`](https://github.com/OpenZeppelin/contracts-sui/blob/v1.0.0/math/core/sources/u16.move)
+- [`u32.move`](https://github.com/OpenZeppelin/contracts-sui/blob/v1.0.0/math/core/sources/u32.move)
+- [`u64.move`](https://github.com/OpenZeppelin/contracts-sui/blob/v1.0.0/math/core/sources/u64.move)
+- [`u128.move`](https://github.com/OpenZeppelin/contracts-sui/blob/v1.0.0/math/core/sources/u128.move)
+- [`u256.move`](https://github.com/OpenZeppelin/contracts-sui/blob/v1.0.0/math/core/sources/u256.move)
+
+Functions
+
+- [`average(a, b, rounding_mode)`](#width-average)
+- [`checked_shl(value, shift)`](#width-checked_shl)
+- [`checked_shr(value, shift)`](#width-checked_shr)
+- [`mul_div(a, b, denominator, rounding_mode)`](#width-mul_div)
+- [`mul_shr(a, b, shift, rounding_mode)`](#width-mul_shr)
+- [`clz(value)`](#width-clz)
+- [`msb(value)`](#width-msb)
+- [`log2(value, rounding_mode)`](#width-log2)
+- [`log256(value, rounding_mode)`](#width-log256)
+- [`log10(value, rounding_mode)`](#width-log10)
+- [`sqrt(value, rounding_mode)`](#width-sqrt)
+- [`inv_mod(value, modulus)`](#width-inv_mod)
+- [`mul_mod(a, b, modulus)`](#width-mul_mod)
+
+#### Functions [!toc] [#width-Functions]
+
+
+Returns the arithmetic mean of `a` and `b` for `Int in {u8, u16, u32, u64, u128, u256}`, rounded according to `rounding_mode`.
+
+
+
+Performs a lossless left shift. Returns `none()` when shifting would consume non-zero bits.
+
+
+
+Performs a lossless right shift. Returns `none()` when shifting would consume non-zero bits.
+
+
+
+Computes `(a * b) / denominator` with configured rounding. Returns `none()` when the rounded value is not representable in the target width.
+
+Aborts when `denominator` is zero.
+
+
+
+Computes `(a * b) >> shift` with configured rounding and returns `none()` when the rounded result overflows the target width.
+
+
+
+Counts leading zero bits. For `u256`, the return type is `u16`; for other widths it is `u8`.
+
+
+
+Returns the zero-based index of the most significant set bit. By convention returns `0` for `value = 0`.
+
+
+
+Computes base-2 logarithm with configured rounding. For `u256`, the return type is `u16`; for other widths it is `u8`.
+
+
+
+Computes base-256 logarithm with configured rounding.
+
+
+
+Computes base-10 logarithm with configured rounding.
+
+
+
+Computes square root with configured rounding.
+
+
+
+Computes modular multiplicative inverse.
+
+Returns `none()` when inverse does not exist (including `modulus = 1`).
+
+Aborts when `modulus` is zero.
+
+
+
+Computes `(a * b) mod modulus`.
+
+Aborts when `modulus` is zero.
+
+
+### `u512` [toc] [#u512]
+
+
+
+```move
+use openzeppelin_math::u512;
+```
+
+Wide-integer helper module used by high-precision arithmetic paths where `u256` intermediates may overflow.
+
+Types
+
+- [`U512`](#u512-U512)
+
+Functions
+
+- [`new(hi, lo)`](#u512-new)
+- [`zero()`](#u512-zero)
+- [`from_u256(value)`](#u512-from_u256)
+- [`hi(value)`](#u512-hi)
+- [`lo(value)`](#u512-lo)
+- [`ge(value, other)`](#u512-ge)
+- [`mul_u256(a, b)`](#u512-mul_u256)
+- [`div_rem_u256(numerator, divisor)`](#u512-div_rem_u256)
+
+Errors
+
+- [`ECarryOverflow`](#u512-ECarryOverflow)
+- [`EUnderflow`](#u512-EUnderflow)
+- [`EDivideByZero`](#u512-EDivideByZero)
+- [`EInvalidRemainder`](#u512-EInvalidRemainder)
+
+#### Types [!toc] [#u512-Types]
+
+
+Represents a 512-bit unsigned integer as two `u256` limbs.
+
+
+#### Functions [!toc] [#u512-Functions]
+
+
+Builds a `U512` value from explicit high and low limbs.
+
+
+
+Returns the all-zero `U512` value.
+
+
+
+Embeds a `u256` value as `U512 { hi: 0, lo: value }`.
+
+
+
+Returns the upper 256-bit limb.
+
+
+
+Returns the lower 256-bit limb.
+
+
+
+Lexicographic greater-or-equal comparison between two wide integers.
+
+
+
+Computes full-width product `a * b` as a 512-bit result.
+
+Aborts with `ECarryOverflow` if an internal carry invariant is violated.
+
+
+
+Divides a 512-bit numerator by a non-zero `u256` divisor.
+
+Returns `(overflow, quotient, remainder)`, where `overflow = true` indicates the exact quotient does not fit in `u256`.
+In overflow cases, `quotient` is returned as `0` while `remainder` remains correct.
+
+
+#### Errors [!toc] [#u512-Errors]
+
+
+Raised when cross-limb accumulation produces an out-of-range final carry.
+
+
+
+Raised when an internal borrow operation would underflow the high limb.
+
+
+
+Raised when `div_rem_u256` is called with `divisor = 0`.
+
+
+
+Raised when internal division remainder invariants are violated.
+
diff --git a/content/contracts-sui/1.x/index.mdx b/content/contracts-sui/1.x/index.mdx
new file mode 100644
index 00000000..6c035768
--- /dev/null
+++ b/content/contracts-sui/1.x/index.mdx
@@ -0,0 +1,75 @@
+---
+title: Contracts for Sui 1.x
+---
+
+**OpenZeppelin Contracts for Sui v1.x** ships two core packages:
+
+- `openzeppelin_math` for deterministic arithmetic, configurable rounding, and decimal scaling.
+- `openzeppelin_access` for ownership-transfer wrappers around privileged `key + store` objects.
+
+## Quickstart
+
+### Prerequisites
+
+- Sui CLI installed.
+- MVR CLI installed.
+- A new or existing Move package.
+
+### 1. Create a Move Package
+
+```bash
+sui move new my_sui_app
+cd my_sui_app
+```
+
+### 2. Add OpenZeppelin Dependencies from MVR
+
+```bash
+mvr add @openzeppelin-move/access
+mvr add @openzeppelin-move/integer-math
+```
+
+### 3. Verify `Move.toml`
+
+`mvr add` updates `Move.toml` automatically. It should include:
+
+```toml
+[dependencies]
+openzeppelin_access = { r.mvr = "@openzeppelin-move/access" }
+openzeppelin_math = { r.mvr = "@openzeppelin-move/integer-math" }
+```
+
+### 4. Add a Minimal Module
+
+Create `sources/quickstart.move`:
+
+```move
+module my_sui_app::quickstart;
+
+use openzeppelin_math::{rounding, u64};
+use std::option;
+
+// === Functions ===
+
+public fun quote_with_fee(amount: u64): u64 {
+ // 2.5% fee, rounded to nearest.
+ let quoted = amount.mul_div(1025u64, 1000u64, rounding::nearest());
+ quoted.destroy_some()
+}
+
+public fun sqrt_floor(value: u64): u64 {
+ value.sqrt(rounding::down())
+}
+```
+
+### 5. Build and Test
+
+```bash
+sui move build
+sui move test
+```
+
+## Next Steps
+
+- Read package guides: [Integer Math](/contracts-sui/1.x/math), [Access](/contracts-sui/1.x/access).
+- Use API docs: [Integer Math](/contracts-sui/1.x/api/math), [Access](/contracts-sui/1.x/api/access).
diff --git a/content/contracts-sui/1.x/math.mdx b/content/contracts-sui/1.x/math.mdx
new file mode 100644
index 00000000..352b11b3
--- /dev/null
+++ b/content/contracts-sui/1.x/math.mdx
@@ -0,0 +1,80 @@
+---
+title: Integer Math
+---
+
+The `openzeppelin_math` package is the numeric foundation for OpenZeppelin Contracts for Sui. It provides deterministic arithmetic across unsigned integer widths, explicit rounding controls, and helpers for decimal normalization.
+
+Use this package when your app needs arithmetic behavior that is predictable, auditable, and safe around overflow and precision boundaries. Instead of hiding rounding and truncation inside implementation details, `openzeppelin_math` makes those decisions explicit so they can be part of your protocol rules.
+
+## Usage
+
+Add the dependency in `Move.toml`:
+
+```toml
+[dependencies]
+openzeppelin_math = { r.mvr = "@openzeppelin-move/integer-math" }
+```
+
+Import the modules you need:
+
+```move
+use openzeppelin_math::{rounding, u64};
+```
+
+## Examples
+
+### Fee quote with explicit rounding
+
+```move
+module my_sui_app::pricing;
+
+use openzeppelin_math::{rounding, u64};
+
+const EMathOverflow: u64 = 0;
+
+public fun quote_with_fee(amount: u64): u64 {
+ u64::mul_div(amount, 1025u64, 1000u64, rounding::nearest())
+ .destroy_or!(abort EMathOverflow)
+}
+```
+
+### Square root with deterministic rounding
+
+```move
+module my_sui_app::analytics;
+
+use openzeppelin_math::{rounding, u64};
+
+public fun sqrt_floor(value: u64): u64 {
+ u64::sqrt(value, rounding::down())
+}
+```
+
+### Decimal normalization between precisions
+
+```move
+module my_sui_app::scaling;
+
+use openzeppelin_math::decimal_scaling;
+
+// === Functions ===
+
+public fun scale_up_6_to_9(amount: u64): u256 {
+ decimal_scaling::safe_upcast_balance(amount, 6u8, 9u8)
+}
+
+public fun scale_down_9_to_6(amount: u256): u64 {
+ decimal_scaling::safe_downcast_balance(amount, 9u8, 6u8)
+}
+```
+
+## Picking the right primitives
+
+- `rounding`: shared rounding policy (`Down`, `Up`, `Nearest`) for value-sensitive paths.
+- `u8`, `u16`, `u32`, `u64`, `u128`, `u256`: same API surface across widths for portability.
+- `decimal_scaling`: decimal conversion between systems using different precision.
+- `u512`: wide intermediate support for high-precision arithmetic paths.
+
+## API Reference
+
+Use the full function-level reference here: [Integer Math API](/contracts-sui/1.x/api/math).
diff --git a/content/contracts-sui/AGENTS.md b/content/contracts-sui/AGENTS.md
new file mode 100644
index 00000000..8883700e
--- /dev/null
+++ b/content/contracts-sui/AGENTS.md
@@ -0,0 +1,102 @@
+# AGENTS.md - Contracts for Sui Docs Conventions
+
+## Scope
+- Applies to files under `content/contracts-sui/`.
+- Applies to Move snippets embedded in Markdown/MDX docs.
+
+## Move code quality checklist
+- Apply Sui Move code quality best practices to all examples and snippets.
+- Prefer `movefmt` in editor and CI to keep style consistent.
+
+## Package manifest
+- Use Move 2024 edition in `Move.toml` (`edition = "2024"` or `edition = "2024.beta"`).
+- Do not add explicit framework dependencies in modern Sui manifests unless strictly required.
+- Prefix named addresses to avoid collisions (for example `my_protocol_math` instead of `math`).
+
+## Modules, imports, and constants
+- Prefer module declarations with `;` (`module my_package::my_module;`) over brace-wrapped module declarations.
+- Do not use `use x::{Self};`; use `use x;`.
+- When importing a module and one of its members, prefer `use x::{Self, Member};`.
+- Error constants use `E` + PascalCase (for example `ENotAuthorized`).
+- Regular constants use `ALL_CAPS` (for example `MY_CONSTANT`).
+
+## Move Import Style
+- Prefer combining symbols from the same module into one `use` statement.
+- Avoid nested grouped imports.
+- Keep grouped imports compact:
+ - One line when readable.
+ - If wrapped, use at most 3 lines.
+- If a grouped import would require more than 3 lines, split it into multiple `use` statements.
+- When splitting, group imports by semantic compatibility (similar concern/purpose), not arbitrarily.
+
+## Examples
+
+Preferred single line:
+```move
+use openzeppelin_math::{rounding, u64};
+```
+
+Allowed wrapped form (max 3 lines):
+```move
+use openzeppelin_math::{
+ rounding, u64, u128
+};
+```
+
+If it exceeds 3 lines, split by semantics:
+```move
+use openzeppelin_math::{rounding, u64, u128};
+use openzeppelin_math::{decimal_scaling, u256};
+```
+
+## Struct and event naming
+- Capability types end with `Cap` (for example `AdminCap`).
+- Do not use `Potato` suffix for hot-potato values.
+- Event structs are past tense (for example `UserRegistered`).
+- Dynamic field keys use positional structs with `Key` suffix (for example `DynamicFieldKey()`).
+
+## Function signatures and API shape
+- Do not use `public entry`; use either `public` or `entry`.
+- Prefer composable functions for PTBs; keep non-composable entry points explicit.
+- Parameter ordering:
+ - Objects first (except `Clock`).
+ - Capability parameters second.
+ - Pure values after objects/caps.
+ - `ctx: &mut TxContext` last.
+- Getter naming:
+ - Use field-based names (`name`), not `get_name`.
+ - Mutable getters end in `_mut` (`details_mut`).
+
+## API Reference entry order
+- In API Reference function entries, place behavior description paragraphs first.
+- Place `Aborts ...` text after the description.
+- Place `Emits ...` text after `Aborts ...`.
+- If both are present, the order is always: description, then `Aborts`, then `Emits`.
+- After `Aborts`/`Emits`, only `NOTE`, `INFO`, or `WARNING` blocks can appear.
+
+## Function body idioms
+- Prefer dot notation (`x.y(...)`) over function-call notation (`y(x, ...)`) whenever Move supports method syntax for the first argument.
+- Prefer method-style calls when available (for example `id.delete()`, `ctx.sender()`, `payment.split(...).into_balance()`).
+- Do not import `std::string::utf8`; use `b"...".to_string()` or `b"...".to_ascii_string()`.
+- Prefer vector literal/index/method style over legacy `vector::empty/push_back/borrow/length`.
+- Use index syntax for compatible collections (for example `&x[&10]`, `&mut x[&10]`).
+
+## Macro-first control flow
+- Prefer macros over manual `while` loops where available:
+ - Option: `do!`, `destroy_or!`.
+ - Repetition: `N.do!`.
+ - Vector construction/iteration: `vector::tabulate!`, `do_ref!`, `destroy!`, `fold!`, `filter!`.
+
+## Testing
+- Combine test attributes in one line (`#[test, expected_failure(...)]`).
+- In `expected_failure` tests, do not add cleanup past the failure point.
+- In `_tests` modules, do not prefix test function names with `test_`.
+- Do not use `test_scenario` when only a context is needed; prefer `tx_context::dummy()`.
+- Do not pass abort codes to `assert!`.
+- Use `assert_eq!` whenever possible.
+- Prefer `sui::test_utils::destroy` for cleanup in tests.
+
+## Pattern matching and comments
+- Use 2024 unpack shorthand (`let MyStruct { id, .. } = value;`) when ignoring fields.
+- Doc comments use `///` (not JavaDoc-style comments).
+- Add short `//` comments around non-obvious logic, assumptions, and TODOs.
diff --git a/content/contracts-sui/index.mdx b/content/contracts-sui/index.mdx
new file mode 100644
index 00000000..850497c3
--- /dev/null
+++ b/content/contracts-sui/index.mdx
@@ -0,0 +1,37 @@
+---
+title: Contracts for Sui
+---
+
+import { latestStable } from "./latest-versions.js";
+
+**OpenZeppelin Contracts for Sui** is a Move library for building secure applications on Sui with production-oriented access and math primitives.
+
+## Getting Started
+
+
+
+ Install packages, set up a Move project, and run a first end-to-end integration.
+
+
+
+## Packages
+
+
+
+ Package-level guide for math primitives, including intent, module map, and usage boundaries.
+
+
+ Package-level guide for access primitives, including transfer policy selection and safety models.
+
+
+
+## API Reference
+
+
+
+ Explore the complete math API, including all functions and types.
+
+
+ Explore the complete access API reference, including module-level functions, core types, emitted events, and expected error conditions for integration.
+
+
diff --git a/content/contracts-sui/latest-versions.js b/content/contracts-sui/latest-versions.js
new file mode 100644
index 00000000..403f2bc4
--- /dev/null
+++ b/content/contracts-sui/latest-versions.js
@@ -0,0 +1 @@
+export const latestStable = "1.x";
diff --git a/source.config.ts b/source.config.ts
index cf9c9c88..c1c81411 100644
--- a/source.config.ts
+++ b/source.config.ts
@@ -13,6 +13,8 @@ export const docs = defineDocs({
// Async mode - enables runtime compilation for faster dev server startup
docs: {
async: true,
+ // Restrict docs pages to MDX content files.
+ files: ["**/*.mdx"],
},
// To switch back to sync mode (pre-compilation), comment out the docs config above and uncomment below:
// (sync mode - pre-compiles all content at build time)
diff --git a/src/app/page.tsx b/src/app/page.tsx
index ebe274ac..57449272 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -23,6 +23,7 @@ import {
RelayersIcon,
StarknetIcon,
StellarIcon,
+ SuiIcon,
TransactionProposalIcon,
UniswapIcon,
ZamaIcon,
@@ -102,6 +103,9 @@ export default function HomePage() {
+
+
+
@@ -113,8 +117,8 @@ export default function HomePage() {
- Contracts libraries are also available for Starknet, Stellar,
- Zama FHEVM, and more blockchains
+ Contracts libraries are also available for Starknet, Sui,
+ Stellar, Zama FHEVM, and more blockchains