Claude-starter aptos-move-language

Expert on Move programming language fundamentals including abilities (copy/drop/store/key), generics, phantom types, references, global storage operations (move_to/move_from/borrow_global), signer pattern, visibility modifiers, and advanced type system features.

install
source · Clone the upstream repo
git clone https://github.com/raintree-technology/claude-starter
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/raintree-technology/claude-starter "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/aptos/move-language" ~/.claude/skills/raintree-technology-claude-starter-aptos-move-language-428122 && rm -rf "$T"
manifest: skills/aptos/move-language/SKILL.md
source content

Move Language Expert

Deep expertise on the Move programming language for Aptos blockchain.

Triggers

  • move language, abilities, generics
  • phantom type, borrow_global
  • signer, friend, inline
  • copy, drop, store, key
  • move_to, move_from, acquires

Abilities

The four abilities control what can be done with types:

AbilityMeaningUse Case
copy
Can be copiedPrimitives, configs
drop
Can be discardedTemporary data
store
Can be stored in structsMost data types
key
Can be top-level resourceAccount resources
struct Resource has key, store { value: u64 }
struct Point has copy, drop, store { x: u64, y: u64 }
struct Capability {}  // No abilities - hot potato

Critical Rules

  1. Fields must have compatible abilities
  2. Structs without
    drop
    must be explicitly handled
  3. copy
    requires all fields to have
    copy

Generics

struct Box<T: store> has store {
    value: T
}

public fun create<T: store>(value: T): Box<T> {
    Box { value }
}

Phantom Types (Zero-Cost Type Safety)

struct Coin<phantom CoinType> has store {
    value: u64  // CoinType doesn't appear here
}

struct BTC {}
struct ETH {}

// Coin<BTC> != Coin<ETH> at compile time

References

// Immutable reference
fun read(x: &u64): u64 { *x }

// Mutable reference
fun increment(x: &mut u64) { *x = *x + 1; }

Reference Rules

  • Can't have mutable + immutable refs simultaneously
  • Only one mutable reference at a time
  • References can't outlive values

Global Storage

// Store resource
move_to(account, MyResource { value: 0 });

// Remove resource
let resource = move_from<MyResource>(addr);

// Immutable borrow
let r = borrow_global<MyResource>(addr);

// Mutable borrow
let r = borrow_global_mut<MyResource>(addr);

// Check existence
exists<MyResource>(addr);

The
acquires
Annotation

public fun get_value(addr: address): u64 acquires MyResource {
    borrow_global<MyResource>(addr).value
}

Signer

signer
is Move's authentication primitive:

public entry fun initialize(account: &signer) {
    move_to(account, Resource { value: 0 });
}

let addr = signer::address_of(account);

Visibility

fun private_fn() { }                    // Module only
public fun public_fn() { }              // Anywhere
public(friend) fun friend_fn() { }      // Friends only
public entry fun entry_fn(s: &signer) { }  // Transaction entry
entry fun local_entry(s: &signer) { }   // Local entry

Friend Declarations

module admin {
    friend user_module;
    public(friend) fun admin_function() { }
}

Inline Functions

inline fun min(a: u64, b: u64): u64 {
    if (a < b) a else b
}

Common Patterns

Capability Pattern

struct AdminCap has key, store {}

public fun admin_only(admin: &signer) acquires AdminCap {
    assert!(exists<AdminCap>(signer::address_of(admin)), ERROR);
}

Witness Pattern

struct MyModule has drop {}

public fun initialize<T: drop>(account: &signer, _witness: T) {
    move_to(account, Config<T> { });
}

Hot Potato Pattern

struct Receipt { amount: u64 }  // No abilities!

public fun buy(): Receipt { Receipt { amount: 100 } }
public fun redeem(r: Receipt) { let Receipt { amount } = r; }
// Must call both - can't drop Receipt

Best Practices

  • Use abilities explicitly
  • Leverage phantom types for type safety
  • Constrain generics only as needed
  • Use references to avoid copies
  • Check exists before borrow_global
  • Always annotate acquires