From f043d0f8419be7141955663c5a82a0e573152e7f Mon Sep 17 00:00:00 2001 From: Josh Date: Wed, 25 Feb 2026 21:40:19 -0800 Subject: [PATCH] Fix 4 verified skill content bugs from issue #1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add [package] + [lib] crate-type=["cdylib"] to 6 Rust Cargo.toml examples - Fix II Rust backend: StableCell for OWNER instead of thread_local! heap - Fix SNS token math: governance 5.2M → 5M to match 10M total - Standardize ic-stable-structures to 0.7 across all skills --- public/llms-full.txt | 72 +++++++++++++++++++++++++++---- public/sitemap.xml | 6 +-- skills/https-outcalls/SKILL.md | 8 ++++ skills/icrc-ledger/SKILL.md | 8 ++++ skills/internet-identity/SKILL.md | 26 ++++++++--- skills/multi-canister/SKILL.md | 4 +- skills/sns-launch/SKILL.md | 2 +- skills/stable-memory/SKILL.md | 8 ++++ skills/vetkd/SKILL.md | 8 ++++ skills/wallet/SKILL.md | 8 ++++ 10 files changed, 129 insertions(+), 21 deletions(-) diff --git a/public/llms-full.txt b/public/llms-full.txt index ff7de5c..b27dcf6 100644 --- a/public/llms-full.txt +++ b/public/llms-full.txt @@ -2559,6 +2559,14 @@ persistent actor { ```toml # Cargo.toml +[package] +name = "https_outcalls_backend" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + [dependencies] ic-cdk = "0.18" candid = "0.10" @@ -3055,6 +3063,14 @@ persistent actor { #### Cargo.toml Dependencies ```toml +[package] +name = "icrc_ledger_backend" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + [dependencies] ic-cdk = "0.18" candid = "0.10" @@ -3387,6 +3403,8 @@ Internet Identity (II) is the Internet Computer's native authentication system. 7. **Not calling `agent.fetchRootKey()` in local development.** Without this, certificate verification fails on localhost. Never call it in production -- it's a security risk on mainnet. +8. **Storing auth state in `thread_local!` without stable storage (Rust)** -- `thread_local! { RefCell }` is heap memory, wiped on every canister upgrade. Use `StableCell` from `ic-stable-structures` for any state that must persist across upgrades, especially ownership/auth data. + ## Implementation ### icp.json Configuration @@ -3566,19 +3584,31 @@ persistent actor { ```toml # Cargo.toml +[package] +name = "ii_backend" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + [dependencies] ic-cdk = "0.18" candid = "0.10" serde = { version = "1", features = ["derive"] } +ic-stable-structures = "0.7" ``` ```rust use candid::Principal; use ic_cdk::{caller, query, update}; +use ic_stable_structures::{DefaultMemoryImpl, StableCell}; use std::cell::RefCell; thread_local! { - static OWNER: RefCell> = RefCell::new(None); + static OWNER: RefCell, DefaultMemoryImpl>> = RefCell::new( + StableCell::init(DefaultMemoryImpl::default(), None).unwrap() + ); } /// Reject anonymous principal. Call this at the top of every protected endpoint. @@ -3597,10 +3627,10 @@ fn init_owner() -> String { let caller = require_auth(); OWNER.with(|owner| { - let mut owner = owner.borrow_mut(); - match *owner { + let mut cell = owner.borrow_mut(); + match cell.get() { None => { - *owner = Some(caller); + cell.set(Some(caller)).unwrap(); format!("Owner set to {}", caller) } Some(_) => "Owner already initialized".to_string(), @@ -3613,8 +3643,8 @@ fn admin_action() -> String { let caller = require_auth(); OWNER.with(|owner| { - let owner = owner.borrow(); - match *owner { + let cell = owner.borrow(); + match cell.get() { Some(o) if o == caller => "Admin action performed".to_string(), Some(_) => ic_cdk::trap("Only the owner can call this function."), None => ic_cdk::trap("Owner not set. Call init_owner first."), @@ -4089,7 +4119,7 @@ crate-type = ["cdylib"] ic-cdk = "0.18" candid = "0.10" serde = { version = "1", features = ["derive"] } -ic-stable-structures = "0.6" +ic-stable-structures = "0.7" ``` #### src/user_service/src/lib.rs @@ -4198,7 +4228,7 @@ crate-type = ["cdylib"] ic-cdk = "0.18" candid = "0.10" serde = { version = "1", features = ["derive"] } -ic-stable-structures = "0.6" +ic-stable-structures = "0.7" ``` #### src/content_service/src/lib.rs @@ -4830,7 +4860,7 @@ Distribution: vesting_period: 31_557_600 # seconds (12 months) InitialBalances: - governance: 520_000_000_000_000 # e8s (5_200_000 tokens) — Treasury (controlled by DAO) + governance: 500_000_000_000_000 # e8s (5_000_000 tokens) — Treasury (controlled by DAO) swap: 250_000_000_000_000 # e8s (2_500_000 tokens) — Sold during decentralization swap total: 1_000_000_000_000_000 # e8s (10_000_000 tokens) — Must equal sum of all allocations @@ -5213,6 +5243,14 @@ Rust canisters use `ic-stable-structures` for persistent storage. The `MemoryMan #### Cargo.toml ```toml +[package] +name = "stable_memory_backend" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + [dependencies] ic-cdk = "0.18" ic-stable-structures = "0.7" @@ -5570,6 +5608,14 @@ vetkd_derive_key : (record { **Cargo.toml:** ```toml +[package] +name = "vetkd_backend" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + [dependencies] candid = "0.10" ic-cdk = "0.18" @@ -6052,6 +6098,14 @@ persistent actor { #### Cargo.toml Dependencies ```toml +[package] +name = "wallet_backend" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + [dependencies] ic-cdk = "0.18" candid = "0.10" diff --git a/public/sitemap.xml b/public/sitemap.xml index adec432..99da199 100644 --- a/public/sitemap.xml +++ b/public/sitemap.xml @@ -2,7 +2,7 @@ https://dfinity.github.io/icskills/ - 2026-02-25 + 2026-02-26 weekly 1.0 @@ -80,13 +80,13 @@ https://dfinity.github.io/icskills/llms.txt - 2026-02-25 + 2026-02-26 weekly 0.8 https://dfinity.github.io/icskills/llms-full.txt - 2026-02-25 + 2026-02-26 weekly 0.8 diff --git a/skills/https-outcalls/SKILL.md b/skills/https-outcalls/SKILL.md index 6cdb00a..08bf824 100644 --- a/skills/https-outcalls/SKILL.md +++ b/skills/https-outcalls/SKILL.md @@ -187,6 +187,14 @@ persistent actor { ```toml # Cargo.toml +[package] +name = "https_outcalls_backend" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + [dependencies] ic-cdk = "0.18" candid = "0.10" diff --git a/skills/icrc-ledger/SKILL.md b/skills/icrc-ledger/SKILL.md index 17188f9..fdd7f01 100644 --- a/skills/icrc-ledger/SKILL.md +++ b/skills/icrc-ledger/SKILL.md @@ -234,6 +234,14 @@ persistent actor { #### Cargo.toml Dependencies ```toml +[package] +name = "icrc_ledger_backend" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + [dependencies] ic-cdk = "0.18" candid = "0.10" diff --git a/skills/internet-identity/SKILL.md b/skills/internet-identity/SKILL.md index 177c793..30fed13 100644 --- a/skills/internet-identity/SKILL.md +++ b/skills/internet-identity/SKILL.md @@ -48,6 +48,8 @@ Internet Identity (II) is the Internet Computer's native authentication system. 7. **Not calling `agent.fetchRootKey()` in local development.** Without this, certificate verification fails on localhost. Never call it in production -- it's a security risk on mainnet. +8. **Storing auth state in `thread_local!` without stable storage (Rust)** -- `thread_local! { RefCell }` is heap memory, wiped on every canister upgrade. Use `StableCell` from `ic-stable-structures` for any state that must persist across upgrades, especially ownership/auth data. + ## Implementation ### icp.json Configuration @@ -227,19 +229,31 @@ persistent actor { ```toml # Cargo.toml +[package] +name = "ii_backend" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + [dependencies] ic-cdk = "0.18" candid = "0.10" serde = { version = "1", features = ["derive"] } +ic-stable-structures = "0.7" ``` ```rust use candid::Principal; use ic_cdk::{caller, query, update}; +use ic_stable_structures::{DefaultMemoryImpl, StableCell}; use std::cell::RefCell; thread_local! { - static OWNER: RefCell> = RefCell::new(None); + static OWNER: RefCell, DefaultMemoryImpl>> = RefCell::new( + StableCell::init(DefaultMemoryImpl::default(), None).unwrap() + ); } /// Reject anonymous principal. Call this at the top of every protected endpoint. @@ -258,10 +272,10 @@ fn init_owner() -> String { let caller = require_auth(); OWNER.with(|owner| { - let mut owner = owner.borrow_mut(); - match *owner { + let mut cell = owner.borrow_mut(); + match cell.get() { None => { - *owner = Some(caller); + cell.set(Some(caller)).unwrap(); format!("Owner set to {}", caller) } Some(_) => "Owner already initialized".to_string(), @@ -274,8 +288,8 @@ fn admin_action() -> String { let caller = require_auth(); OWNER.with(|owner| { - let owner = owner.borrow(); - match *owner { + let cell = owner.borrow(); + match cell.get() { Some(o) if o == caller => "Admin action performed".to_string(), Some(_) => ic_cdk::trap("Only the owner can call this function."), None => ic_cdk::trap("Owner not set. Call init_owner first."), diff --git a/skills/multi-canister/SKILL.md b/skills/multi-canister/SKILL.md index 8018b73..653ad7a 100644 --- a/skills/multi-canister/SKILL.md +++ b/skills/multi-canister/SKILL.md @@ -382,7 +382,7 @@ crate-type = ["cdylib"] ic-cdk = "0.18" candid = "0.10" serde = { version = "1", features = ["derive"] } -ic-stable-structures = "0.6" +ic-stable-structures = "0.7" ``` #### src/user_service/src/lib.rs @@ -491,7 +491,7 @@ crate-type = ["cdylib"] ic-cdk = "0.18" candid = "0.10" serde = { version = "1", features = ["derive"] } -ic-stable-structures = "0.6" +ic-stable-structures = "0.7" ``` #### src/content_service/src/lib.rs diff --git a/skills/sns-launch/SKILL.md b/skills/sns-launch/SKILL.md index acd8023..1810a7b 100644 --- a/skills/sns-launch/SKILL.md +++ b/skills/sns-launch/SKILL.md @@ -143,7 +143,7 @@ Distribution: vesting_period: 31_557_600 # seconds (12 months) InitialBalances: - governance: 520_000_000_000_000 # e8s (5_200_000 tokens) — Treasury (controlled by DAO) + governance: 500_000_000_000_000 # e8s (5_000_000 tokens) — Treasury (controlled by DAO) swap: 250_000_000_000_000 # e8s (2_500_000 tokens) — Sold during decentralization swap total: 1_000_000_000_000_000 # e8s (10_000_000 tokens) — Must equal sum of all allocations diff --git a/skills/stable-memory/SKILL.md b/skills/stable-memory/SKILL.md index ff4ee7f..6b1ae1f 100644 --- a/skills/stable-memory/SKILL.md +++ b/skills/stable-memory/SKILL.md @@ -121,6 +121,14 @@ Rust canisters use `ic-stable-structures` for persistent storage. The `MemoryMan #### Cargo.toml ```toml +[package] +name = "stable_memory_backend" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + [dependencies] ic-cdk = "0.18" ic-stable-structures = "0.7" diff --git a/skills/vetkd/SKILL.md b/skills/vetkd/SKILL.md index 761fd46..76521ec 100644 --- a/skills/vetkd/SKILL.md +++ b/skills/vetkd/SKILL.md @@ -114,6 +114,14 @@ vetkd_derive_key : (record { **Cargo.toml:** ```toml +[package] +name = "vetkd_backend" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + [dependencies] candid = "0.10" ic-cdk = "0.18" diff --git a/skills/wallet/SKILL.md b/skills/wallet/SKILL.md index 0d1ef13..52dbaee 100644 --- a/skills/wallet/SKILL.md +++ b/skills/wallet/SKILL.md @@ -153,6 +153,14 @@ persistent actor { #### Cargo.toml Dependencies ```toml +[package] +name = "wallet_backend" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + [dependencies] ic-cdk = "0.18" candid = "0.10"