sealevel-tools

Crates.iosealevel-tools
lib.rssealevel-tools
version0.7.0
sourcesrc
created_at2024-10-14 14:22:25.498616
updated_at2024-12-09 23:22:49.995195
descriptionTools for safe, CU-optimized Solana program development
homepage
repositoryhttps://github.com/rtrombone/safer-solana
max_upload_size
id1408351
size267,985
Russell (rtrombone)

documentation

README

license crates.io docs.rs

Sealevel Tools

Tools for safer and CU-optimized Solana development.

This crate is not an attempt to create a new framework for writing Solana programs. Instead, it is a set of tools that should help a developer write a Solana program without prescribing any specific way of doing so. By using these tools, a developer can write a lightweight program with functionality found in other frameworks.

See crate documentation for more information.

Dependencies

Minimum-supported Rust version: 1.79, which matches MSRV of Solana-related crates with version ^2.1.4. Keep in mind that with future Solana versions, MSRV may uptick.

Currently, this package leverages sealevel-nostd-entrypoint, which is a fork of solana-nostd-entrypoint (an optimized no-std program entrypoint library) updated to use Solana ^2.0. Its contents are re-exported for convenience into the entrypoint submodule.

Feature Flags

When you add this package, the following features are enabled by default:

default = [
    "alloc",
    "borsh",
    "token"
]

To disable these defaults (e.g. using a heapless environment via noalloc_allocator), use default-features = false in your Cargo.toml and add the features you need for your program:

sealevel-tools = { version = "0.7", default-features = false, features = ["noalloc-default"] }

features = ["alloc"]

Using the Rust's core allocation library, enable this feature. If this feature is disabled, be aware that error resolution decreases. For example, with alloc on, you may encounter a program log resembling:

Program log: Custom error: AccountInfo
Program log: Account key mismatch at index 1...
Program log:   Found: 7UbHLbKLfvh3maXuCZMWqKjzMCeLczaJwWTSLVpYV38z
Program log:   Expected: CjasN94JjDrDeZkxenJGNrN1sqBeHauNkJDp48VQdrtm

NOTE: With the above example, any referenced index is based on zero-indexed account enumeration.

And without it, the same error would produce:

Program log: Custom error: AccountInfo
Program log: Account does not match expected key

Having no allocator is extreme. You can still write a program that does not allocate to the heap and keep this feature enabled so that the program logs have more colorful error messages. There would only be a cost to process these errors if preflight were skipped when sending the transaction and you wanted these failed transactions to persist on-chain.

See alloc documentation for more information.

features = ["borsh"]

Account handling relating to borsh serialization. It is up to you to determine whether there is too much overhead to use this serialization library and whether it is worth the time to write your own serde.

It should be no cost to have this feature enabled. And as an integrator with another program, you will have the option to deserialize accounts of programs written with frameworks like anchor-lang.

features = ["token"]

Account and CPI handling relating to the SPL Token programs (legacy and Extensions).

There are convenient methods that create mints and token accounts, which basically pair a System program's create account with an initialize mint or initialize token account instruction to allow these operations to happen atomically in your program's instruction (as opposed to having to create an account in an instruction prior to invoking your program's).

Philosophy

The tools found in this crate are meant to allow a developer to keep things as simple as possible while providing some guardrails. These guardrails are not meant to enforce any specific way of iterating through entrypoint accounts, account serialization/deserialization (serde), how instruction discriminators should be set, etc.

The developer should write a program without any artificial constraints. For example, a developer may want instruction selectors to be the first 4-bytes of a Keccak256 hash similar to how Solidity for EVM works. Or to be consistent with how anchor-lang and spl-discriminator define discriminators as the first 8-bytes of Sha256 (sha2).

What this crate does not attempt to do is generate an IDL. While convenient when using frameworks like anchor-lang and shank (where a front-end language-agnostic developer can take an IDL and build an SDK using it), these tools are meant to focus on safer program development. Writing instruction builders is trivial, and any time spent trying to resolve headaches having an IDL build using any of these frameworks can be saved by writing custom instruction builders in whichever language you want to support.

Solana program frameworks attempt to remove boilerplate from writing instruction processors. But with that comes the price of having to learn how these specific macros work. And these macros can add a lot of bloat to your program, where your program size can easily be double the size of a program with the same logic but without a specific framework.

Commit count: 59

cargo fmt