Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
08d58d9
feat: Add Config PDA, Treasury Shard state & processors
onspeedhp Mar 9, 2026
43606fc
feat: Add collect_protocol_fee utility
onspeedhp Mar 9, 2026
04500cd
feat: Integrate protocol fee into existing processors
onspeedhp Mar 9, 2026
494424f
feat: Add CloseSession and CloseWallet processors
onspeedhp Mar 9, 2026
2925d0f
feat: Wire new instructions in entrypoint & IDL
onspeedhp Mar 9, 2026
897edcd
feat: Update SDK with new generated code & client methods
onspeedhp Mar 9, 2026
239a82b
fix: Correct Secp256r1 sysvar ordering and discriminators in tests
onspeedhp Mar 9, 2026
0320988
fix: Audit findings (CloseWallet account count, CloseSession optimiza…
onspeedhp Mar 9, 2026
5d86858
fix: Add missing protocol fee collection and fix account parsing in A…
onspeedhp Mar 9, 2026
e4d4a29
fix(audit): resolve critical security issues (SweepTreasury DoS, Conf…
onspeedhp Mar 10, 2026
8876579
docs: update README and Architecture with latest auth, config, and fe…
onspeedhp Mar 10, 2026
d0f0a4a
fix(audit): resolve critical security issue and add program_id to aut…
onspeedhp Mar 10, 2026
9df9bbd
feat: Implement security checklist, audit regression tests, and harde…
onspeedhp Mar 12, 2026
76f1876
feat: Implement and test global wallet discovery by credential hash w…
onspeedhp Mar 12, 2026
1b1fe92
feat: monorepo dual SDK layout and Rust IDL facade alignment with Shank
onspeedhp Mar 17, 2026
cef6373
feat: 100% Rust layout extraction and remove redundant patch layouts
onspeedhp Mar 17, 2026
6643be7
feat: introduce secp256r1 utilities, update program IDL for account m…
onspeedhp Mar 17, 2026
9e9ec2f
feat: complete solita v1 sdk test suite with 100% parity
onspeedhp Mar 18, 2026
6976c67
feat: introduce a high-level client for simplified contract interacti…
onspeedhp Mar 18, 2026
945683d
refactor: optimize LazorClient with Smart Defaults, Transaction Build…
onspeedhp Mar 19, 2026
a0d99ca
refactor: optimize sdk ergonomics and cleanup test infrastructure
onspeedhp Mar 20, 2026
2a49639
test: refactor solita-client test suite to 7 feature-based files and …
onspeedhp Mar 21, 2026
42bcf9b
refactor(sdk): fix misleading naming conventions
onspeedhp Mar 21, 2026
0a5a0bf
feat(sdk, tests): deep audit and refactor solita client SDK
onspeedhp Mar 23, 2026
c0d50ba
docs: update architecture, readme and development guidelines
onspeedhp Mar 23, 2026
a803925
fix: resolve secp256r1 signature verification and test setup sync
onspeedhp Mar 24, 2026
d89d0c5
chore: update all LazorKit project files and docs
onspeedhp Apr 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ target
node_modules
dist
build
test-ledger
test-ledger
.env
.env.*
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 30 additions & 26 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,59 @@

This document outlines the standard procedures for building, deploying, and testing the LazorKit program and its associated SDK.

## πŸš€ Local Quick Start (Recommended)
If you are developing locally, you can run everything (Build + Validator + Tests) with a single command:
```bash
./scripts/test.sh
```
This script ensures a clean environment, builds the latest program, and runs the full Vitest suite against a local validator.

## 1. Prerequisites
- [Solana Tool Suite](https://docs.solanalabs.com/cli/install) (latest stable)
- [Rust](https://www.rust-lang.org/tools/install)
- [Node.js & npm](https://nodejs.org/)
- [Shank CLI](https://github.com/metaplex-foundation/shank) (for IDL generation)
- [Codama CLI](https://github.com/metaplex-foundation/codama) (for SDK generation)
- [Node.js, npm & pnpm](https://nodejs.org/)
- [Solita](https://github.com/metaplex-foundation/solita) (for legacy web3.js v1 SDK generation)

## 2. Project Structure
- `/program`: Rust smart contract (Pinocchio-based)
- Highly optimized, zero-copy architecture (`NoPadding`).
- `/sdk/lazorkit-ts`: TypeScript SDK generated via Codama.
- Contains generated instructions for interaction with the contract.
- `/tests-real-rpc`: Integration tests running against a live RPC (Devnet/Localhost).
- `/scripts`: Automation utility scripts (e.g., syncing program IDs).
- `/sdk/solita-client`: TypeScript SDK generated via Solita & manually augmented.
- Contains generated instructions wrapped by a high-level `LazorClient` to manage derivations and Secp256r1 webauth payloads.
- `/tests-v1-rpc`: Integration tests running against a local test validator using Vitest and legacy `@solana/web3.js` (v1).
- `/scripts`: Automation utility scripts.

## 3. Core Workflows

### A. Program ID Synchronization
Whenever you redeploy the program to a new address, run the sync script to update all references across Rust, the SDK generator, and your tests:
```bash
./scripts/sync-program-id.sh <YOUR_NEW_PROGRAM_ID>
```
*Note: This script will update hardcoded IDs and typically trigger SDK regeneration automatically.*
Whenever you redeploy the program to a new address, ensure you update the `PROGRAM_ID` constants in:
- `program/src/lib.rs` (Declare id)
- `sdk/solita-client/src/utils/pdas.ts`

### B. IDL & SDK Generation
If you modify instruction parameters or account structures in the Rust program, you must regenerate both the IDL and the SDK:
1. **Update IDL** (using Shank):
### B. SDK Generation & Augmentation
If you modify instruction parameters or account structures in the Rust program, you must regenerate the SDK:
1. **Regenerate SDK** (using Solita):
```bash
cd program && shank idl -o . --out-filename idl.json -p <YOUR_PROGRAM_ID>
cd program && yarn solita
```
2. **Regenerate SDK** (using Codama):
2. **Rebuild Client Wrapper**:
Since the smart contract uses strict `[repr(C)]` / `NoPadding` layouts, the generated `beet` serializers from Solita often inject a 4-byte padding prefix. Lay out custom parameter inputs manually within `sdk/solita-client/src/utils/client.ts` to construct precise buffer offsets.
```bash
cd sdk/lazorkit-ts && npm run generate
cd sdk/solita-client && pnpm run build
```

### C. Testing & Validation
Tests are built to run against an actual RPC node (`tests-real-rpc`), ensuring realistic validation of behaviors like `SlotHashes` nonce verification and resource limits.
Tests run exclusively on a localized `solana-test-validator` to guarantee execution determinism, specifically for verifying the `SlotHashes` sysvar.

1. **Setup Env**: Ensure `.env` in `tests-real-rpc/` has your `PRIVATE_KEY`, `RPC_URL`, and `WS_URL`.
2. **Run All Tests**:
1. **Run Full Test Suite** (Recommended for full validation):
```bash
cd tests-real-rpc && npm run test:devnet
cd tests-v1-rpc && ./scripts/test-local.sh
```
3. **Run Single Test File** (Recommended for debugging):
*Note: This script will spawn the validator, await fee stabilization, and trigger all 69 Vitest endpoints sequentially.*

2. **Run Single Test File**:
```bash
cd tests-real-rpc && npm run test:devnet:file tests/instructions/create_wallet.test.ts
cd tests-v1-rpc && vitest run tests/06-ownership.test.ts
```

### D. Deployment & IDL Publishing
1. **Build the Program**:
```bash
cargo build-sbf
Expand Down
168 changes: 107 additions & 61 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,95 +1,141 @@
# ⚑ LazorKit Smart Wallet (V2)

**LazorKit** is a high-performance, security-focused Smart Wallet contract on Solana. It enables advanced account abstraction features like multi-signature support, session keys, and role-based access control (RBAC) with minimal on-chain overhead.
Modern, high-performance smart wallet protocol for Solana featuring multi-role RBAC (owner/admin/spender), extensible multi-protocol authentication (Passkey, Ed25519), stateless replay protection, and highly modular, scalable PDA-based storage. Built from the ground up for speed, security, and seamless account abstraction.

---

## 🌟 Key Features
## πŸš€ Key Features

### πŸ” Multi-Protocol Authentication
- **Ed25519**: Native Solana key support for standard wallets.
- **Secp256r1 (P-256)**: Native support for **Passkeys (WebAuthn)** and **Apple Secure Enclave**, enabling biometric signing directly on-chain.
- **Multi-Auth Protocols**: Support for both classic Ed25519 wallets and modern Passkey (WebAuthn/Secp256r1, Apple Secure Enclave), fully verified on-chain.
- **Dynamic Role-Based Access Control (RBAC):** Each authority is a uniquely derived PDA storing its role and type. Unlimited authorities, mapped cleanly by role: Owner (full), Admin (session mgmt), Spender (only execute). Strict role pruning & upgrades built-in.
- **Ephemeral Session Keys:** Issue temporary, slot-limited session sub-keys (with absolute expiry on Solana Slot) for programmable sessions and automation.
- **Treasury Sharding:** Protocol fees smartly distributed across `N` immutable treasury-shard PDAs for massively increased throughput and to avoid Solana's write-lock contention.
- **Deposit/Withdraw/Close:** Native destructibilityβ€”wallets and sessions can be safely closed, draining all SOL (including rent) back to the user, with full, secure authority checks.
- **Zero-Copy State, NoPadding:** Uses `pinocchio` for ultra-efficient raw-bytes interpretations, avoiding Borsh/Serde in all persistent state (drastically lowers CU cost and rent).
- **Full Security/Replay Protection:** All core Solana reentrancy/binding vectors covered: discriminator enforcement, explicit stack height guards, account/pubkey binding via hash, CPI replay guarded for cross-program safety, strict seed/path validation.
- **SDK & Compression:** TypeScript SDK with direct mapping to raw state layout (no prefix/padding mismatches!), plus transaction compression for extreme transaction packing (multiple calls, one TX).

### πŸ›‘οΈ Role-Based Access Control (RBAC)
Granular permission management for every key with strictly separated PDAs:
- **Owner (Role 0)**: Full control. Can add/remove authorities and transfer ownership.
- **Admin (Role 1)**: Can create Sessions and add Spenders. Cannot remove Owners.
- **Spender (Role 2)**: Limited to executing transactions. Ideal for hot wallets or automated bots.
---

## πŸ—οΈ On-chain Account Types

| Account | Seed(s) Format | Purpose |
|-----------------|--------------------------------------------------------------|-------------------------------------------------------------------------|
| Config PDA | `["config"]` | Global settings: admin pubkey, protocol fees, # treasury shards, version |
| Treasury Shard | `["treasury", shard_id]` | Sharded rent-exempt lamports storage, receives protocol fees |
| Wallet PDA | `["wallet", user_seed]` | Main anchor for a user wallet, supports upgrades/versioning |
| Vault PDA | `["vault", wallet_pda]` | Holds SOL/SPL owned by wallet (only signed by wallet PDA) |
| Authority PDA | `["authority", wallet, id_hash]` | Authority/role for wallet (Owner/Admin/Spender), can be Ed25519 or P256 |
| Session PDA | `["session", wallet, session_pubkey]` | Temporary authority, expires after given slot, can be Ed25519 |

---

## πŸ“‹ State / Structs

### ⏱️ Ephemeral Session Keys
- Create temporary, time-bound keys with specific expiry (`expires_at` defined by absolute slot height).
- Great for dApps (games, social) to offer "Log in once, act multiple times" UX without exposing the main key.
All persistent accounts use the `NoPadding` layout and versioned headers. Example core account headers (see `program/src/state/*.rs`):

### πŸš€ High Performance & Replay Protection
- **Zero-Copy Serialization**: Built on `pinocchio` casting raw bytes to Rust structs for maximum CU efficiency.
- **No-Padding Layout**: Optimized data structures (`NoPadding`) to reduce rent costs and ensure memory safety.
- **SlotHashes Nonce**: Secp256r1 replay protection uses the `SlotHashes` sysvar as a "Proof of Liveness" (valid within 150 slots) instead of expensive on-chain counters.
- **Transaction Compression**: Uses `CompactInstructions` to fit complex multi-call payloads into standard Solana transaction limits.
**ConfigAccount (global):**
```
pub struct ConfigAccount {
pub discriminator: u8, // 4
pub bump: u8,
pub version: u8,
pub num_shards: u8,
pub _padding: [u8; 4],
pub admin: Pubkey,
pub wallet_fee: u64,
pub action_fee: u64
}
```
**AuthorityAccountHeader:** (Ed25519 or Secp256r1)
```
pub struct AuthorityAccountHeader {
pub discriminator: u8, // 2
pub authority_type: u8, // 0=Ed25519, 1=Secp256r1
pub role: u8, // 0=Owner, 1=Admin, 2=Spender
pub bump: u8,
pub version: u8,
pub _padding: [u8; 3],
pub counter: u64,
pub wallet: Pubkey,
}
```
**SessionAccount:**
```
pub struct SessionAccount {
pub discriminator: u8, // 3
pub bump: u8,
pub version: u8,
pub _padding: [u8; 5],
pub wallet: Pubkey,
pub session_key: Pubkey,
pub expires_at: u64,
}
```
**WalletAccount:**
```
pub struct WalletAccount {
pub discriminator: u8, // 1
pub bump: u8, pub version: u8, pub _padding: [u8; 5],
}
```

---

## πŸ—οΈ Architecture
## πŸ“ Core Instruction Flow

The contract uses a highly modular PDA (Program Derived Address) architecture for separated storage and deterministic validation:
- **CreateWallet**: Initializes Config, Wallet, Vault, and Owner-Authority PDA. Fee routed to correct Treasury Shard. No pre-fund DoS possible.
- **Execute**: Authenticates via Ed25519, Secp256r1, or Session PDA. Fee auto-charged to payer, routed by sharding. Strict discriminator & owner checks. Batch multiple actions using compacted instructions.
- **Add/RemoveAuthority / ChangeRole**: Owner and Admins may add, remove or rebind authorities, upgrading or pruning them.
- **CreateSession**: Only Owner or Admin can issue. Derives a session PDA with corresponding authority, slot expiry and version.
- **CloseSession**: Anyone (protocol Admin for expired, Owner/Admin for active+expired) can close and reclaim rent from a session.
- **CloseWallet**: Only Owner may destroy; all SOL in wallet+vault sent atomically to destination; permanent, secure cleanup. All authorities/sessions orphaned.
- **Protocol Fees/Config**: Protocol Admin can update fees at any time by updating Config PDA. Treasury Shards subdivide by hash(payer pubkey) % num_shards.
- **Init/Sweep TreasuryShard**: Admin can initialize and consolidate multiple treasury shards for optimal rent/fund flows.

| Account Type | Description |
| :--- | :--- |
| **Wallet PDA** | The main identity anchor. Derived from `["wallet", user_seed]`. |
| **Vault PDA** | Holds assets (SOL/SPL Tokens). Only the Wallet PDA can sign for it. |
| **Authority PDA** | Separate PDA for each authorized key (unlimited distinct authorities). Stores role. Derived from `["authority", wallet_pda, id_hash]`. |
| **Session PDA** | Temporary authority (sub-key) with absolute slot-based expiry. Derived from `["session", wallet_pda, session_key]`. |
---

## πŸ” Security & Protections

*See [`docs/Architecture.md`](docs/Architecture.md) for deeper technical details.*
- **Discriminators Required:** All account loads must match the correct discriminator and layout.
- **Seed Enforcement:** All derived addresses are re-calculated and checked; spoofed config/wallet/authority is never possible.
- **Role Pruning:** Only protocol admin may reduce number of shards; authorities strictly match wallet+id.
- **Payload Binding:** All signature payloads are bound to concrete target accounts (destination when closing, self for session/exec). Execution hashes pubkeys for extra safety.
- **Reentrancy/Stack Checks:** All auth flows include stack height+slot introspection to block malicious CPIs.
- **SlotHashes Nonce:** For Passkey/Secp256r1: Each approval is valid strictly within +150 slots (approx. 75 seconds), leveraging on-chain sysvars & clientData reconstruction.
- **Rent/Destruct:** All PDA drains zero balances with safe arithmetic. Orphaned or unclaimed rent can only ever be collected by real wallet owner/admin.
- **Versioning:** All accounts are versioned, allowing smooth future upgrade paths.

---

## πŸ“‚ Project Structure
## πŸ“¦ Project Structure

- `program/src/`: Main contract source code.
- `processor/`: Instruction handlers (`create_wallet`, `execute`, `manage_authority`, etc.).
- `auth/`: Authentication logic for Ed25519 and Secp256r1 (with `slothashes` nonce).
- `state/`: Account data structures (`Wallet`, `Authority`, `Session`).
- `tests-e2e/`: Comprehensive End-to-End Test Suite.
- `scenarios/`: Test scenarios covering Happy Path, Failures, and Audit Retro.
- `scenarios/audit/`: Dedicated regression tests for security vulnerabilities.
- `program/src/` – Solana program core:
- `auth/` Multi-auth modules (Ed25519, Secp256r1, Passkey, ...)
- `processor/` – All instructions (wallet, authority, session, config, exec, treasury, ...)
- `state/` – Account structs, discriminators, versioning
- `utils.rs`, `compact.rs` – Support logic (fee collection, account compression, slot checks)
- `sdk/solita-client/` – Comprehensive TypeScript SDK supporting direct PDA/call logic
- `src/wrapper.ts`, `src/utils/` – `LazorClient`: full wrapped, ergonomic app API
- `tests-v1-rpc/` – End-to-end test suites (localnet simulation, cross-role/race/destroy/fee scenarios)

---

## πŸ› οΈ Usage
## πŸ›  Usage

### Build
**Build**
```bash
# Build SBF program
cargo build-sbf
```

### Test
Run the comprehensive E2E test suite (LiteSVM-based):
**Test**
```bash
cd tests-e2e
cargo run --bin lazorkit-tests-e2e
cd tests-v1-rpc
./scripts/test-local.sh
```

---

## πŸ”’ Security & Audit

LazorKit V2 has undergone a rigorous internal audit and security review.

**Status**: βœ… **17/17 Security Issues Resolved**

We have fixed and verified vulnerabilities including:
- **Critical**: Cross-Wallet Authority Deletion.
- **High**: Signature Replay, DoS prevention, OOB Reads.
- **Medium**: Rent Theft protections and Signature Binding.
- **CPI Protection**: Explicit `stack_height` checks prevent authentication instructions from being called maliciously via CPI.

### Security Features
- **Discriminator Checks**: All PDAs are strictly validated by type constant.
- **Signature Binding**: Payloads are strictly bound to target accounts and instructions to prevent replay/swapping attacks.
- **Reentrancy Guards**: Initialized to prevent CPI reentrancy.

---
## πŸ“‘ License

## πŸ“œ License
MIT
2 changes: 1 addition & 1 deletion assertions/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use pinocchio_pubkey::declare_id;
use pinocchio_system::ID as SYSTEM_ID;

// LazorKit Program ID
declare_id!("2m47smrvCRpuqAyX2dLqPxpAC1658n1BAQga1wRCsQiT");
declare_id!("DfmiYzJSaeW4yBinoAF6RNa14gGmhXHiX1DNUofkztY2");

#[allow(unused_imports)]
use std::mem::MaybeUninit;
Expand Down
Loading
Loading