sui-move-patternslisted
Install: claude install-skill widnyana/eyay-toolkits
## 1. Events
Emit events for all state-changing operations that clients need to observe:
```move
use sui::event;
public struct LiquidityAdded has copy, drop {
pool_id: ID,
amount_x: u64,
amount_y: u64,
lp_minted: u64,
}
// Inside function:
event::emit(LiquidityAdded {
pool_id: object::id(pool),
amount_x,
amount_y,
lp_minted,
});
```
---
## 2. Error Handling
Error constants use `EPascalCase` and `u64` values:
```move
const EInsufficientLiquidity: u64 = 0;
const EZeroAmount: u64 = 1;
assert!(amount > 0, EZeroAmount);
```
### Clever errors
Annotating a constant with `#[error]` allows it to carry a human-readable message. The value can be any valid constant type — `vector<u8>` is most common for string messages:
```move
#[error]
const EInsufficientLiquidity: vector<u8> = b"Insufficient liquidity in pool";
assert!(reserves > 0, EInsufficientLiquidity);
abort EInsufficientLiquidity
```
At runtime, the Sui CLI and GraphQL server automatically decode these into a readable message:
```
Error from '0x2::amm::swap' (line 42), abort 'EInsufficientLiquidity': "Insufficient liquidity in pool"
```
**Gotcha**: clever error abort codes encode the source line number, so their `u64` value can change if the file is reformatted or lines shift. Don't hardcode clever error abort codes in tests or off-chain tooling — match by constant name instead.
`**assert!` without an abort code** is also valid and auto-derives a clever abort code from the source l