Skip to content

Commit 56573c5

Browse files
JoshJosh
authored andcommitted
Fix compile blockers and issues across all 12 skills
- ckbtc: Fix Nat.fromNat64 -> Nat64.toNat, add missing import - icrc-ledger: Add missing Nat8 import, fix icrc1_symbol return format - internet-identity: mo:base -> mo:core, Debug.trap -> Runtime.trap, persistent actor - https-outcalls: Add missing Nat64 import - multi-canister: Fix Principal.fromActor(this), fix std::env::var, fix caller-after-await pitfall - stable-memory: Fix 64GB -> 500GB limit, remove unused Nat import - evm-rpc: Add missing Text import, remove dead code, remove unused Cycles import - sns-launch: Fix YAML pseudo-units to plain numbers, add upgrade warning - vetkd: Fix Blob/Text type mismatch, add cycles to mgmt calls, replace fabricated frontend API - certified-variables: Replace nonexistent SHA256 module with mo:sha2, fix Text.toBlob/Blob.concat - wallet: Add missing Principal import, remove unused CanisterInstallMode - asset-canister: Fix 2GB -> 4GB limit, remove allow_raw_access on wildcard - All skills: Update ic-cdk to 0.18, remove unused dependencies
1 parent 38853c5 commit 56573c5

12 files changed

Lines changed: 121 additions & 199 deletions

File tree

skills/asset-canister/SKILL.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Access patterns:
3434

3535
5. **Deploying to the wrong canister name.** If dfx.json has `"frontend"` but you run `dfx deploy assets`, it creates a new canister instead of updating the existing one.
3636

37-
6. **Exceeding the 2GB canister storage limit.** The asset canister stores all files in a single canister. Large media files (videos, datasets) will exhaust canister storage. Use a dedicated storage solution for large files.
37+
6. **Exceeding the 4GB Wasm heap memory limit.** The asset canister stores all files in a single canister. Large media files (videos, datasets) will exhaust canister storage. Use a dedicated storage solution for large files.
3838

3939
7. **Not configuring `allow_raw_access` for API responses.** By default, the asset canister serves certified responses through the `ic0.app` domain. If you need raw (uncertified) access for specific assets, configure it in `.ic-assets.json5`.
4040

@@ -74,13 +74,11 @@ Recommended approach: place the file in your `public/` or `static/` folder so yo
7474
```json5
7575
[
7676
{
77-
// Rewrite all paths to index.html for SPA routing
77+
// Set default cache headers for all paths
7878
"match": "**/*",
7979
"headers": {
8080
"Cache-Control": "public, max-age=0, must-revalidate"
81-
},
82-
// Enable SPA fallback: any path without a file extension serves index.html
83-
"allow_raw_access": true
81+
}
8482
},
8583
{
8684
// Cache static assets aggressively (they have content hashes in filenames)
@@ -269,7 +267,7 @@ dfx canister call frontend http_request '(record {
269267

270268
# 6. Get canister ID
271269
dfx canister id frontend
272-
# Expected: prints the canister ID (e.g., "rrkah-fqaaa-aaaaa-aaaaq-cai")
270+
# Expected: prints the canister ID (e.g., "bkyz2-fmaaa-aaaaa-qaaaq-cai")
273271

274272
# 7. Check storage usage
275273
dfx canister info frontend

skills/certified-variables/SKILL.md

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Query responses on the Internet Computer come from a single replica and are NOT
99

1010
- `dfx` >= 0.24.0
1111
- Rust: `ic-certified-map` crate (for Merkle tree), `ic-cdk` (for `set_certified_data` / `data_certificate`)
12-
- Motoko: `CertifiedData` module (included in mo:core/mo:base)
12+
- Motoko: `CertifiedData` module (included in mo:core/mo:base), `sha2` package (`mops add sha2`) for hashing
1313
- Frontend: `@dfinity/certificate-verification` or `@dfinity/agent` (includes verification)
1414

1515
## Canister IDs
@@ -69,7 +69,7 @@ CLIENT VERIFICATION:
6969
```toml
7070
[dependencies]
7171
candid = "0.10"
72-
ic-cdk = "0.16"
72+
ic-cdk = "0.18"
7373
ic-certified-map = "0.4"
7474
serde = { version = "1", features = ["derive"] }
7575
serde_bytes = "0.11"
@@ -81,7 +81,7 @@ serde_cbor = "0.11"
8181
```rust
8282
use candid::{CandidType, Deserialize};
8383
use ic_cdk::{init, post_upgrade, query, update};
84-
use ic_certified_map::{HashTree, RbTree, leaf_hash};
84+
use ic_certified_map::{HashTree, RbTree};
8585
use serde_bytes::ByteBuf;
8686
use std::cell::RefCell;
8787

@@ -236,7 +236,8 @@ import Text "mo:core/Text";
236236
import Map "mo:core/Map";
237237
import Array "mo:core/Array";
238238
import Iter "mo:core/Iter";
239-
import SHA256 "mo:core/SHA256";
239+
// Requires: mops add sha2
240+
import Sha256 "mo:sha2/Sha256";
240241
241242
persistent actor {
242243
@@ -247,7 +248,7 @@ persistent actor {
247248
public func setCertifiedValue(value : Text) : async () {
248249
certifiedValue := value;
249250
// Hash the value and set as certified data (max 32 bytes)
250-
let hash = SHA256.fromBlob(#sha256, Text.toBlob(value));
251+
let hash = Sha256.fromBlob(#sha256, Text.encodeUtf8(value));
251252
CertifiedData.set(hash);
252253
};
253254
@@ -274,31 +275,37 @@ import Blob "mo:core/Blob";
274275
import Text "mo:core/Text";
275276
import Map "mo:core/Map";
276277
import Array "mo:core/Array";
277-
import SHA256 "mo:core/SHA256";
278+
// Requires: mops add sha2
279+
import Sha256 "mo:sha2/Sha256";
278280
import Nat "mo:core/Nat";
279281
280282
persistent actor {
281283
282284
// Store key-value pairs
283285
let store = Map.empty<Text, Text>();
284286
287+
// Concatenate two Blobs (mo:core has no Blob.concat)
288+
func blobConcat(a : Blob, b : Blob) : Blob {
289+
Blob.fromArray(Array.concat(Blob.toArray(a), Blob.toArray(b)))
290+
};
291+
285292
// Compute a root hash over all entries
286293
// (Simple approach: hash the concatenation of all key-value hashes, sorted)
287294
func computeRootHash() : Blob {
288295
let entries = Array.fromIter<(Text, Text)>(Map.entries(store));
289296
if (entries.size() == 0) {
290-
return SHA256.fromBlob(#sha256, "");
297+
return Sha256.fromBlob(#sha256, Text.encodeUtf8(""));
291298
};
292299
293300
// Hash each entry
294301
let hashes = Array.map<(Text, Text), Blob>(entries, func((k, v)) {
295-
SHA256.fromBlob(#sha256, Text.toBlob(k # "=" # v))
302+
Sha256.fromBlob(#sha256, Text.encodeUtf8(k # "=" # v))
296303
});
297304
298305
// Combine all hashes into a single root hash
299306
var combined : Blob = "";
300307
for (h in Array.values(hashes)) {
301-
combined := SHA256.fromBlob(#sha256, Blob.concat(combined, h));
308+
combined := Sha256.fromBlob(#sha256, blobConcat(combined, h));
302309
};
303310
combined
304311
};

skills/ckbtc/SKILL.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: Use when building apps that accept, send, or manage Bitcoin on the
44
---
55

66
# Chain-Key Bitcoin (ckBTC) Integration
7-
> version: 1.0.0 | requires: [dfx >= 0.24.0, mops, ic-cdk >= 0.17]
7+
> version: 1.0.0 | requires: [dfx >= 0.24.0, mops, ic-cdk >= 0.18]
88
99
## What This Is
1010

@@ -128,6 +128,7 @@ import Principal "mo:core/Principal";
128128
import Blob "mo:core/Blob";
129129
import Nat "mo:core/Nat";
130130
import Nat8 "mo:core/Nat8";
131+
import Nat64 "mo:core/Nat64";
131132
import Array "mo:core/Array";
132133
import Result "mo:core/Result";
133134
import Error "mo:core/Error";
@@ -323,7 +324,7 @@ persistent actor {
323324
owner = Principal.fromText("mqygn-kiaaa-aaaar-qaadq-cai");
324325
subaccount = null;
325326
};
326-
amount = Nat.fromNat64(amount);
327+
amount = Nat64.toNat(amount);
327328
fee = ?10;
328329
memo = null;
329330
created_at_time = null;
@@ -357,8 +358,8 @@ edition = "2021"
357358
crate-type = ["cdylib"]
358359

359360
[dependencies]
360-
ic-cdk = "0.17"
361-
ic-cdk-timers = "0.11"
361+
ic-cdk = "0.18"
362+
ic-cdk-timers = "0.12"
362363
candid = "0.10"
363364
serde = { version = "1", features = ["derive"] }
364365
serde_bytes = "0.11"

skills/evm-rpc/SKILL.md

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: Use when building apps that read from or write to Ethereum and EVM-
44
---
55

66
# EVM RPC Canister — Calling Ethereum from IC
7-
> version: 1.0.0 | requires: [dfx >= 0.24.0, mops, ic-cdk >= 0.17]
7+
> version: 1.0.0 | requires: [dfx >= 0.24.0, mops, ic-cdk >= 0.18]
88
99
## What This Is
1010

@@ -146,8 +146,8 @@ core = "2.0.0"
146146

147147
```motoko
148148
import EvmRpc "canister:evm_rpc";
149-
import Cycles "mo:core/Cycles";
150149
import Runtime "mo:core/Runtime";
150+
import Text "mo:core/Text";
151151
152152
persistent actor {
153153
@@ -210,15 +210,6 @@ persistent actor {
210210
211211
// Encode: balanceOf(address) = 0x70a08231 + address padded to 32 bytes
212212
// walletAddress should be like "0xABC..." — strip 0x and left-pad to 64 hex chars
213-
let addressHex = if (walletAddress.size() > 2) {
214-
// Simple: assume address is already 0x-prefixed 40-char hex
215-
let stripped = switch (walletAddress.chars().next()) {
216-
case (?"0") { /* skip 0x prefix handling in real code */ walletAddress };
217-
case _ { walletAddress };
218-
};
219-
stripped
220-
} else { walletAddress };
221-
222213
let calldata = "0x70a08231000000000000000000000000" # stripHexPrefix(walletAddress);
223214
224215
let result = await (with cycles = 10_000_000_000) EvmRpc.eth_call(
@@ -383,7 +374,7 @@ edition = "2021"
383374
crate-type = ["cdylib"]
384375

385376
[dependencies]
386-
ic-cdk = "0.17"
377+
ic-cdk = "0.18"
387378
candid = "0.10"
388379
serde = { version = "1", features = ["derive"] }
389380
serde_json = "1"

skills/https-outcalls/SKILL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ You do not deploy anything extra. The management canister is built into every su
4747
import Blob "mo:base/Blob";
4848
import Cycles "mo:base/ExperimentalCycles";
4949
import Debug "mo:base/Debug";
50+
import Nat64 "mo:base/Nat64";
5051
import Text "mo:base/Text";
5152
5253
actor {
@@ -176,8 +177,7 @@ actor {
176177
```toml
177178
# Cargo.toml
178179
[dependencies]
179-
ic-cdk = "0.17"
180-
ic-cdk-macros = "0.17"
180+
ic-cdk = "0.18"
181181
candid = "0.10"
182182
serde = { version = "1", features = ["derive"] }
183183
serde_json = "1"

skills/icrc-ledger/SKILL.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# ICRC Ledger Standards
2-
> version: 1.0.0 | requires: [dfx >= 0.24.0, mops, ic-cdk >= 0.17]
2+
> version: 1.0.0 | requires: [dfx >= 0.24.0, mops, ic-cdk >= 0.18]
33
44
## What This Is
55
ICRC-1 is the fungible token standard on Internet Computer, defining transfer, balance, and metadata interfaces. ICRC-2 extends it with approve/transferFrom (allowance) mechanics, enabling third-party spending like ERC-20 on Ethereum.
66

77
## Prerequisites
88
- dfx >= 0.24.0
99
- For Motoko: mops with `core = "2.0.0"` in mops.toml
10-
- For Rust: `ic-cdk = "0.17"`, `candid = "0.10"`, `icrc-ledger-types = "0.1"` in Cargo.toml
10+
- For Rust: `ic-cdk = "0.18"`, `candid = "0.10"`, `icrc-ledger-types = "0.1"` in Cargo.toml
1111

1212
## Canister IDs
1313

@@ -47,6 +47,7 @@ Index canisters (for transaction history):
4747
```motoko
4848
import Principal "mo:core/Principal";
4949
import Nat "mo:core/Nat";
50+
import Nat8 "mo:core/Nat8";
5051
import Nat64 "mo:core/Nat64";
5152
import Blob "mo:core/Blob";
5253
import Time "mo:core/Time";
@@ -219,8 +220,7 @@ persistent actor {
219220

220221
```toml
221222
[dependencies]
222-
ic-cdk = "0.17"
223-
ic-cdk-timers = "0.11"
223+
ic-cdk = "0.18"
224224
candid = "0.10"
225225
icrc-ledger-types = "0.1"
226226
serde = { version = "1", features = ["derive"] }
@@ -234,7 +234,7 @@ use icrc_ledger_types::icrc1::account::Account;
234234
use icrc_ledger_types::icrc1::transfer::{TransferArg, TransferError};
235235
use icrc_ledger_types::icrc2::approve::{ApproveArgs, ApproveError};
236236
use icrc_ledger_types::icrc2::transfer_from::{TransferFromArgs, TransferFromError};
237-
use ic_cdk::{update, query};
237+
use ic_cdk::update;
238238

239239
const ICP_LEDGER: &str = "ryjl3-tyaaa-aaaaa-aaaba-cai";
240240
const ICP_FEE: u64 = 10_000; // 10000 e8s
@@ -456,7 +456,7 @@ dfx canister call icrc1_ledger icrc1_decimals '()'
456456

457457
# 4. Check symbol
458458
dfx canister call icrc1_ledger icrc1_symbol '()'
459-
# Expected: (record { symbol = "TEST" })
459+
# Expected: ("TEST")
460460

461461
# 5. Transfer to another identity
462462
dfx identity new test-recipient --storage-mode=plaintext 2>/dev/null
@@ -483,13 +483,13 @@ dfx canister call icrc1_ledger icrc1_balance_of \
483483
```bash
484484
# Verify ICP ledger is reachable
485485
dfx canister call ryjl3-tyaaa-aaaaa-aaaba-cai icrc1_symbol '()' --network ic
486-
# Expected: (record { symbol = "ICP" })
486+
# Expected: ("ICP")
487487

488488
# Verify ckBTC ledger is reachable
489489
dfx canister call mxzaz-hqaaa-aaaar-qaada-cai icrc1_symbol '()' --network ic
490-
# Expected: (record { symbol = "ckBTC" })
490+
# Expected: ("ckBTC")
491491

492492
# Verify ckETH ledger is reachable
493493
dfx canister call ss2fx-dyaaa-aaaar-qacoq-cai icrc1_symbol '()' --network ic
494-
# Expected: (record { symbol = "ckETH" })
494+
# Expected: ("ckETH")
495495
```

skills/internet-identity/SKILL.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -143,16 +143,17 @@ if (isAuthenticated) {
143143
### Backend: Motoko
144144

145145
```motoko
146-
import Principal "mo:base/Principal";
146+
import Principal "mo:core/Principal";
147+
import Runtime "mo:core/Runtime";
147148
148-
actor {
149-
// Stable variable to track owner/admin
150-
stable var owner : ?Principal = null;
149+
persistent actor {
150+
// Owner/admin principal
151+
var owner : ?Principal = null;
151152
152153
// Helper: reject anonymous callers
153154
func requireAuth(caller : Principal) : () {
154155
if (Principal.isAnonymous(caller)) {
155-
Debug.trap("Anonymous principal not allowed. Please authenticate.");
156+
Runtime.trap("Anonymous principal not allowed. Please authenticate.");
156157
};
157158
};
158159
@@ -176,12 +177,12 @@ actor {
176177
switch (owner) {
177178
case (?o) {
178179
if (o != msg.caller) {
179-
Debug.trap("Only the owner can call this function.");
180+
Runtime.trap("Only the owner can call this function.");
180181
};
181182
"Admin action performed";
182183
};
183184
case (null) {
184-
Debug.trap("Owner not set. Call initOwner first.");
185+
Runtime.trap("Owner not set. Call initOwner first.");
185186
};
186187
};
187188
};
@@ -210,8 +211,7 @@ actor {
210211
```toml
211212
# Cargo.toml
212213
[dependencies]
213-
ic-cdk = "0.17"
214-
ic-cdk-macros = "0.17"
214+
ic-cdk = "0.18"
215215
candid = "0.10"
216216
serde = { version = "1", features = ["derive"] }
217217
```
@@ -282,7 +282,7 @@ async fn protected_async_action() -> String {
282282
let caller = require_auth(); // Capture HERE, before any await
283283

284284
// After this await, ic_cdk::caller() would return wrong principal
285-
let _result = some_async_operation().await;
285+
let _result = some_async_operation().await; // (pseudocode — replace with your actual async call)
286286

287287
// Use the captured `caller` variable, NOT ic_cdk::caller()
288288
format!("Action completed by {}", caller)

0 commit comments

Comments
 (0)