This document outlines SolScript's current capabilities, known limitations, and planned improvements.
SolScript is functional for common smart contract patterns. The compiler generates valid Anchor/Rust code that compiles and deploys to Solana.
| Feature | Status | Notes |
|---|---|---|
| State variables | ✅ Complete | All primitive types, structs, arrays |
| Mappings → PDAs | ✅ Complete | Automatic transformation with seeds |
| Events | ✅ Complete | Full Anchor event support |
| Custom errors | ✅ Complete | Error codes with parameters, empty errors supported |
| Modifiers | ✅ Complete | Inlined into functions |
| View functions | ✅ Complete | Read-only account access |
| Access control | ✅ Complete | Via modifiers and require |
| CPI (interfaces) | ✅ Complete | Cross-program calls |
| SPL Token | ✅ Complete | Transfer, mint, burn |
msg.sender |
✅ Complete | Signer account |
block.timestamp |
✅ Complete | Clock sysvar |
| Rent handling | ✅ Complete | Auto rent-exempt accounts |
| Structs in contracts | ✅ Complete | Define inside or outside contracts |
| Enums in contracts | ✅ Complete | Define inside or outside contracts |
| Direct SOL transfers | ✅ Complete | transfer(to, amount) built-in |
| PDA account closing | ✅ Complete | delete mapping[key] closes PDAs |
| Token 2022 | ❌ Not implemented | Only SPL Token |
| Compute budget | ❌ Not implemented | Uses defaults |
Status: Implemented!
Use the transfer(to, amount) built-in function to transfer SOL:
function withdraw(address to, uint64 amount) public {
require(msg.sender == owner, "Unauthorized");
transfer(to, amount); // Transfers SOL to recipient
}How it works:
- Generates Anchor
system_program::transferCPI - Automatically adds
recipientaccount to context - Validates recipient matches the
toaddress - Rent is deducted from signer's account
Note: msg.value still returns 0 for incoming payments. Use SPL Token (wrapped SOL) for receiving payments.
Current behavior: Only SPL Token program is supported.
Impact: Cannot use Token 2022 features (transfer fees, interest-bearing, etc.)
Workaround: Extend generated code manually for Token 2022.
Planned remediation:
- Add Token 2022 interface definitions
- Support extension detection
- Generate proper Token 2022 CPI calls
- Target: v0.4.0
Status: Implemented!
You can now define structs and enums inside contracts:
contract Token {
// Struct inside contract
struct Balance {
uint256 amount;
uint64 lastUpdate;
}
// Enum inside contract
enum Status { Active, Paused, Closed }
mapping(address => Balance) public balances;
Status public status;
}Both inside-contract and outside-contract definitions work seamlessly.
Status: Implemented!
You can now define errors with empty parameter lists:
// All of these work
error Unauthorized(); // Empty parentheses
error NotOwner; // No parentheses
error InsufficientBalance(uint256 available, uint256 required); // With params
function withdraw() public {
if (msg.sender != owner) {
revert Unauthorized();
}
}Status: Implemented!
Use delete mapping[key] to close a mapping PDA and reclaim rent:
contract UserRegistry {
mapping(address => uint64) public scores;
function removeUser(address user) public {
delete scores[user]; // Closes PDA, refunds rent to signer
}
}How it works:
- Generates
close = signeraccount constraint - PDA is closed automatically by Anchor
- Lamports (rent) returned to the transaction signer
- Works with nested mappings too
Current behavior: Uses Solana's default compute budget.
Impact: Complex operations may exceed limits.
Workaround: Request additional compute units client-side.
Planned remediation:
- Add
@computeBudget(units)function attribute - Generate compute budget instructions
- Target: v0.4.0
Current behavior: Modifier bodies are copied into each function.
Impact: Code duplication, larger program size.
Workaround: Keep modifiers small.
Planned remediation:
- Generate separate validation functions
- Call validation before main logic
- Share common checks across functions
- Target: v0.3.0
Current behavior: Standard transaction format only.
Impact: Cannot use address lookup tables for account compression.
Workaround: Build versioned transactions client-side.
Planned remediation:
- Support lookup table references
- Generate v0 transaction metadata
- Target: v0.5.0
Current behavior: Only Clock and Rent sysvars.
Impact: Cannot access recent blockhashes, stake history, etc.
Workaround: Access via CPI to system program.
Planned remediation:
- Add
blockhash,epochSchedule,feesbuilt-ins - Generate proper sysvar account includes
- Target: v0.4.0
- Structs inside contracts
- Enums inside contracts
- Empty error declarations
- Improved error messages
- Direct SOL transfers (
transfer(to, amount)) - PDA account closing for mappings (
delete mapping[key]) - Modifier function generation (not inlining)
- Account constraints improvements
- Token 2022 support
- Compute budget control
- Additional sysvars
- Metaplex integration
- Versioned transactions
- Address lookup tables
- State compression
- Cross-chain messaging (Wormhole)
We welcome contributions! Priority areas:
- Parser improvements - Grammar extensions for in-contract types
- Codegen - SOL transfer and Token 2022 CPI generation
- Testing - Integration tests for all features
- Documentation - Examples and tutorials
See CONTRIBUTING.md for guidelines.
Found a bug or have a feature request?
- GitHub Issues - Bug reports and features
- Discussions - Questions and ideas