Skip to content

feat: course content hash, per-address minting, claim history, pause events - #363

Merged
DeFiVC merged 4 commits into
ChainLearnOfficial:mainfrom
Johnalex-hub:feat/235-238-contract-enhancements
Aug 29, 2026
Merged

feat: course content hash, per-address minting, claim history, pause events#363
DeFiVC merged 4 commits into
ChainLearnOfficial:mainfrom
Johnalex-hub:feat/235-238-contract-enhancements

Conversation

@Johnalex-hub

Copy link
Copy Markdown
Contributor

Bundles four contract enhancements. Detail is in the individual commit messages.

Closes #235
Closes #236
Closes #237
Closes #238

Changes

Notes for review

  • enroll signature is unchanged. . Add course content hash verification #235 says "verify hash in enrollment", but changing enroll would break ~40 call sites plus cross-contract calls from credential-nft and learn-token. enroll_checked takes the optional hash instead, which also matches the "hash verification is optional" criterion.
  • . Add contract pause events #238 needed a pause mechanism. The issue scopes it to events only, but no pause code existed anywhere in contracts/ or packages/. Events with no operation to emit them would be dead code, so this adds the admin pause/unpause surface and enforces the flag on the six state-changing entrypoints. Read-only calls stay available while paused. Happy to trim this back to event definitions alone if you'd prefer.
  • Fixes a pre-existing build break. tests/unit/progress_tests.rs constructed Course without the archived field added in Add course archiving #210, so the progress_tests target did not compile on main.
  • main is not cargo fmt clean, so formatting was deliberately left untouched on lines unrelated to these changes to keep the diff scoped.

Testing

cargo test --workspace — 208 pass, 0 fail. learn-token 35 → 52 tests, progress-tracker 24 → 32.

Add a content_hash field to Course so clients can verify that off-chain
course content matches what the course was published with.

- Course gains `content_hash: Symbol`, defaulting to the `none` sentinel
  meaning "unset", which keeps verification optional.
- `set_course_content_hash` (admin only) sets or updates the hash and
  emits a `content_hash_set` event. Passing `none` unsets it again.
- `get_course_content_hash` exposes it for querying.
- `enroll_checked` enrolls with optional verification. `enroll` keeps its
  existing signature and never verifies, so the ~40 existing call sites
  and the cross-contract calls from credential-nft and learn-token are
  unaffected.

Verification only runs when the course has a hash set AND the caller
supplies one, so it is opt-in on both sides.

Also fixes a pre-existing build break: tests/unit/progress_tests.rs
constructed Course without the `archived` field added in ChainLearnOfficial#210, so the
progress_tests target failed to compile on main.

Closes ChainLearnOfficial#235
Add `total_minted_to(address)` returning the cumulative amount ever
minted to an address, so analytics can break minting down per address
instead of only seeing the global total supply.

- New `TokenDataKey::TotalMintedTo(Address)` persistent entry, with
  `get_total_minted_to` / `add_total_minted_to` storage helpers that
  extend TTL on write like the other per-address entries.
- Updated on both minting paths: `mint` and `claim_reward`. Reward
  claims mint tokens too, so omitting them would undercount.
- The counter is monotonic: transfers and burns leave it untouched, so
  it reflects total minting rather than current holdings.

Reads are a single storage get and writes piggyback on paths that
already touch storage, so there is no added cost on non-minting calls.

Also fixes a pre-existing build break: tests/unit/progress_tests.rs
constructed Course without the `archived` field added in ChainLearnOfficial#210, so the
progress_tests target failed to compile on main.

Closes ChainLearnOfficial#236
Add `get_claim_history(learner)` returning every reward the learner has
claimed, so users can see their reward history rather than only their
current balance.

- New `ClaimRecord` type holding course_id, quiz_id, amount, and the
  ledger timestamp of the claim.
- New `TokenDataKey::ClaimHistory(Address)` persistent entry, appended to
  by `claim_reward` and read back in claim order.
- History is immutable in practice: `claim_reward` rejects double-claims
  before recording, so entries are only ever appended, never modified or
  removed. A rejected duplicate claim leaves the history untouched.

Returns the full list with no pagination, per the issue.

Also fixes a pre-existing build break: tests/unit/progress_tests.rs
constructed Course without the `archived` field added in ChainLearnOfficial#210, so the
progress_tests target failed to compile on main.

Closes ChainLearnOfficial#237
Add `paused(admin, timestamp)` and `unpaused(admin, timestamp)` events so
pause activity can be audited and monitored.

The issue scoped this to events only, but the contract had no pause
mechanism at all -- grep for pause/halt across contracts/ and packages/
returns nothing. Events with no operation to emit them would be dead
code and could not satisfy "events are emitted", so this adds the
minimal pause surface the events attach to:

- `pause` / `unpause`, admin-only, rejecting redundant transitions, each
  emitting its event with the acting admin and ledger timestamp.
- `is_paused` for querying the current state.
- A `Paused` persistent flag, defaulting to unpaused.

Both events follow the existing Symbol::new topic convention used by the
other events here, so indexers can match on them consistently.

The flag is enforced on the state-changing entrypoints -- transfer,
transfer_from, burn, burn_from, mint, and claim_reward -- since a pause
flag that blocked nothing would misrepresent the contract as pausable.
Read-only calls stay available while paused.

Also fixes a pre-existing build break: tests/unit/progress_tests.rs
constructed Course without the `archived` field added in ChainLearnOfficial#210, so the
progress_tests target failed to compile on main.

Closes ChainLearnOfficial#238
@Johnalex-hub
Johnalex-hub force-pushed the feat/235-238-contract-enhancements branch from 08e36ac to 13a9b0e Compare August 29, 2026 23:33
@drips-wave

drips-wave Bot commented Aug 29, 2026

Copy link
Copy Markdown

@Johnalex-hub 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

@DeFiVC
DeFiVC merged commit 2e377c6 into ChainLearnOfficial:main Aug 29, 2026
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 contract pause events . Add reward claiming history . Add token supply tracking by address . Add course content hash verification

2 participants