#solana #spl #nostd-entrypoint

no-std sealevel-tools

Tools for Solana program development

7 unstable releases (3 breaking)

new 0.4.0 Nov 12, 2024
0.3.1 Nov 4, 2024
0.2.0 Oct 25, 2024
0.1.0 Oct 17, 2024
0.0.1 Oct 14, 2024

#571 in Magic Beans

Download history 326/week @ 2024-10-13 120/week @ 2024-10-20 24/week @ 2024-10-27 242/week @ 2024-11-03 124/week @ 2024-11-10

521 downloads per month

MIT license

190KB
3.5K SLoC

license crates.io docs.rs

Sealevel Tools

Tools for safer 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.75.

Currently, this package only supports Solana version ^1.18 to match Solana dependencies found in solana-nostd-entrypoint, meaning that this package does not yet support Solana 2.0.

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.4.0", 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.

Dependencies

~20–30MB
~433K SLoC