⚓ Solana Sealevel Framework

Overview

Anchor

Build Status Docs Chat License

Anchor is a framework for Solana's Sealevel runtime providing several convenient developer tools.

  • Rust eDSL for writing Solana programs
  • IDL specification
  • TypeScript package for generating clients from IDL
  • CLI and workspace management for developing complete applications

If you're familiar with developing in Ethereum's Solidity, Truffle, web3.js or Parity's Ink!, then the experience will be familiar. Although the DSL syntax and semantics are targeted at Solana, the high level flow of writing RPC request handlers, emitting an IDL, and generating clients from IDL is the same.

Getting Started

For a quickstart guide and in depth tutorials, see the guided documentation. To jump straight to examples, go here. For the latest Rust API documentation, see docs.rs.

Packages

Package Description Version Docs
anchor-lang Rust primitives for writing programs on Solana Crates.io Docs.rs
anchor-spl CPI clients for SPL programs on Solana crates Docs.rs
anchor-client Rust client for Anchor programs crates Docs.rs
@project-serum/anchor TypeScript client for Anchor programs npm Docs

Note

  • Anchor is in active development, so all APIs are subject to change.
  • This code is unaudited. Use at your own risk.

Examples

Build stateful programs on Solana by defining a state struct with associated methods. Here's a classic counter example, where only the designated authority can increment the count.

#[program]
mod counter {

    #[state]
    pub struct Counter {
      authority: Pubkey,
      count: u64,
    }

    pub fn new(ctx: Context<Auth>) -> Result<Self> {
        Ok(Self {
            auth: *ctx.accounts.authority.key
        })
    }

    pub fn increment(&mut self, ctx: Context<Auth>) -> Result<()> {
        if &self.authority != ctx.accounts.authority.key {
            return Err(ErrorCode::Unauthorized.into());
        }

        self.count += 1;

        Ok(())
    }
}

#[derive(Accounts)]
pub struct Auth<'info> {
    #[account(signer)]
    authority: AccountInfo<'info>,
}

#[error]
pub enum ErrorCode {
    #[msg("You are not authorized to perform this action.")]
    Unauthorized,
}

Additionally, one can utilize the full power of Solana's parallel execution model by keeping the program stateless and working with accounts directly. The above example can be rewritten as follows.

use anchor::prelude::*;

#[program]
mod counter {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>, authority: Pubkey) -> Result<()> {
        let counter = &mut ctx.accounts.counter;

        counter.authority = authority;
        counter.count = 0;

        Ok(())
    }

    pub fn increment(ctx: Context<Increment>) -> Result<()> {
        let counter = &mut ctx.accounts.counter;

        counter += 1;

        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(init)]
    pub counter: ProgramAccount<'info, Counter>,
    pub rent: Sysvar<'info, Rent>,
}

#[derive(Accounts)]
pub struct Increment<'info> {
    #[account(mut, has_one = authority)]
    pub counter: ProgramAccount<'info, Counter>,
    #[account(signer)]
    pub authority: AccountInfo<'info>,
}

#[account]
pub struct Counter {
    pub authority: Pubkey,
    pub count: u64,
}

#[error]
pub enum ErrorCode {
    #[msg("You are not authorized to perform this action.")]
    Unauthorized,
}

Due to the fact that account sizes on Solana are fixed, some combination of the above is often required. For example, one can store store global state associated with the entire program in the #[state] struct and local state assocated with each user in individual #[account] structs.

For more, see the examples directory.

License

Anchor is licensed under Apache 2.0.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Anchor by you, as defined in the Apache-2.0 license, shall be licensed as above, without any additional terms or conditions.

Comments
  • unable to use anchor on arm

    unable to use anchor on arm

    Description

    When trying to use anchor on a m1 based mac I get the below error:

    ❯ anchor     
    [1]    97137 illegal hardware instruction  anchor
    

    Not sure if this is because of a dependency but its odd because rust is emulated to use x86 instructions.

    priority:1 
    opened by tac0turtle 36
  • devnet deploy error: unrecognized signer source

    devnet deploy error: unrecognized signer source

    I created setup project using anchor init testproject --javascript in $HOME/solana project directory. After:

    1. setting up to devnet using solana config set --url devnet
    2. changing localnet to devnet in Anchor.toml
    3. changing program id in lib.rs and Anchor.toml file same as solana address -k target/deploy/testproject-keypair.json
    4. anchor build --> success
    5. anchor deploy --> error

    anchor deploy error:

    Deploying workspace: https://api.devnet.solana.com
    Upgrade authority: $HOME/.config/solana/id.json
    Deploying program "testproject"...
    Program path: $HOME/solana project/target/deploy/testproject.so...
    error: Invalid value for '--program-id <PROGRAM_ID>': unrecognized signer source
    There was a problem deploying: Output { status: ExitStatus(ExitStatus(256)), stdout: "", stderr: "" }.
    

    I have followed same steps as above but created project in $HOME/solana_project directory, anchor deploy worked properly.

    Observation: project path containing space could have caused the whole issue.

    Analysis: In the solana program deploy.... command here for 2nd project command will be solana program deploy ... --program-id ... $HOME/solana_project/... for 1st project command will be solana program deploy ... --program-id ... $HOME/solana project/... a space in the whole command is causing the issue similar to how a copy/move command errors out in linux

    cli 
    opened by shivam-agarwal-0 30
  • Add support for `anchor idl fetch` to work outside anchor workspace

    Add support for `anchor idl fetch` to work outside anchor workspace

    Context

    Closes #1453 (Refer to this issue for context)

    Changes

    1. anchor idl fetch can now be run outside an anchor workspace.
    2. If it is run outside workspace, provider.cluster option has to be provided.
    opened by NBNARADHYA 24
  • Issues w/ anchor test

    Issues w/ anchor test

    Hey there! On anchor-cli 0.18.0.

    Trying to run anchor test but when I do so, I get hit with:

    Failed to run test: ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts: No such file or directory (os error 2).

    So, I then did npm install ts-mocha -g to see if that would change anything.

    Running the test again, I get

    node: --dns-result-order= is not allowed in NODE_OPTIONS.

    Just running a boilerplate hello-world project from the docs via anchor init helloworld.

    I also tried doing anchor init helloworld --javascript, then do anchor test, and still get: node: --dns-result-order= is not allowed in NODE_OPTIONS.

    opened by farzaa 24
  • docs: Add sealevel-exploits along with descriptions to docs

    docs: Add sealevel-exploits along with descriptions to docs

    In the process of adding the contents of: https://github.com/coral-xyz/sealevel-attacks to the docs.

    This PR will add all of the exploits, as well as describe them in detail, instead of providing just the code.

    progress

    • [x] - signer authorization
    • [x] account data matching
    • [x] - owner checks
    • [x] - type cosplay
    • [x] - initialization
    • [x] - arbitrary cpi
    • [x] - duplicate mutable accounts
    • [x] - bump seed canonicalization
    • [x] - pda sharing
    • [x] - Closing accounts (kinda...No explanation here, but all code examples displayed for easy comparison)
    opened by nheingit 22
  • cli: `anchor account` subcommand to read program account

    cli: `anchor account` subcommand to read program account

    Fixes #1

    Features

    • account subcommand that can deserialize an on-chain account and output it
    • --idl that can be used to feed any idl to use to deserialize the account

    Example Usage

    anchor account prog1.Balance DiuUL66WXc6cQFYSvAKmSxZ4izwsDJbm7yxY6DDtAdBm
    

    The above command will deserialize the given account pubkey with the Balance struct from prog1 program. Output as show below.

    {
      "balance": 9
    }
    

    Notes

    • As the anchor_client in rust requires the user to import concrete type definitions from the program itself, we cannot use it since we only have access to the idl in order to deserialize the account. Hence, we need to deserialize the account without the use of concrete struct/enum definitions.
    • This means, we need to fetch and deserialize the accounts manually into a struct that can hold any type. serde_json library was chosen for this.
    • The account will first be converted into a JsonValue and then printed out
    waiting for tests to run 
    opened by AdithyaNarayan 21
  • npm: Invalid anchor version

    npm: Invalid anchor version

    npm package 0.18.0 have invalid anchor binary :disappointed:

    $ npm ls @project-serum/anchor-cli
    [email protected] /home/kirill/projects/x-project
    └── @project-serum/[email protected]
    
    $ npx anchor --version
    Package binary version is not correct. Expected "anchor-cli 0.18.0", found "anchor-cli 0.17.0".
    Trying globally installed anchor.
    Failed to get version of global binary: Error: spawnSync undefined/anchor ENOENT
    
    opened by fanatid 20
  • Anchor Events Are Extremely Compute Intensive When Used Without Maximal Compiler Optimizations

    Anchor Events Are Extremely Compute Intensive When Used Without Maximal Compiler Optimizations

    Overview

    With the default compiler optimizations, logging the same information through emit! is approximately 2x more expensive in compute units, than it is to directly use msg!.

    When using maximal compiler optimizations as follows, the cost increase is drastically reduced, but is still more expensive.

    lto = "fat"
    codegen-units = 1
    [profile.release.build-override]
    opt-level = 3
    incremental = false
    codegen-units = 1
    

    While this can solve compute unit usage issues within your own programs, it still leaves programs at risk of reaching compute unit limits when making CPI to third-party programs that emit events, without these compiler optimizations.

    As it stands this is more of an edge-case issue, however if the current event system is kept in place I think once more programs are deployed onto Solana, and there is more interconnectivity between programs, this will probably start to become a real issue.

    Proposed Solution - Avoid Borsh Serialization And Base64 Encoding Completely

    Personally speaking I think the best option is to remove serialization and encoding of events, and use proc macros to format the event into a JSON string which is what gets logged. This has the added bonus of being human readable on block explorers.

    Alternative Solutions

    • update anchor docs to recommend using the aforementioned compiler optimizations when using anchor events
    • when running anchor init add the aforementioned compiler optimizations to the default workspace file.

    Optimize The Process Of Emitting Events

    Not exactly sure what this would look like, but there's probably something that can be done. At a quick glance, changing this function to preallocate the vector entirely would help, but im not sure if this is possible.

    Add Compiler Optimizations To Default Workspace File Generated By Anchor

    help wanted lang ts 
    opened by bonedaddy 20
  • anchor provider depends on fs module

    anchor provider depends on fs module

    Bundling the anchor package for usage inside a browser-based react app is currently causing build failures. These can be circumvented by configuring webpack, but I think this kind of solutions is far from ideal, as it increases the friction for a first time anchor user. What would we need to change, to prevent the following issue?

    I am using roughly the following code to create a new Program inside a react app

    import * as anchor from '@project-serum/anchor'
    import poolIdl from '../idls/ido_pool'
    
    const provider = new anchor.Provider(connection, wallet, anchor.Provider.defaultOptions())
    const programId = new anchor.web3.PublicKey('E5s3D6B3PJinuB9kb3dicxfi3qUNLUGX6hoPawhbqagt')
    const program = new anchor.Program(poolIdl, programId, provider);
    

    This will result in the following error:

    ./node_modules/@project-serum/anchor/dist/esm/provider.js:87:0
    Module not found: Can't resolve 'fs'
    null
    

    I found a common workaround for this issue in this stack overflow post: https://stackoverflow.com/questions/57161839/module-not-found-error-cant-resolve-fs-in

    help wanted priority:1 ts 
    opened by mschneider 19
  • Add option for jest test scaffolding

    Add option for jest test scaffolding

    I typically always manually change tests from mocha to jest when starting a new project. As jest is a commonly used testing framework, I added a scaffolding option, --jest, which scaffolds tests as jest tests instead of mocha. I kept this as a flag so that the prior behavior to create mocha tests by default was maintained.

    How to test:

    1. Build the CLI by running make build-cli from repo root
    2. Use the newly built cli to create a project (TS and JS); ./anchor/cli/npm-package/anchor init test-ts --jest and ./anchor/cli/npm-package/anchor init test-js --jest --javascript
    3. cd test-ts
    4. anchor test and observe success
    5. cd ../test-js
    6. anchor test and observe success
    waiting for review 
    opened by kgilliam125 17
  • ts: Program upgrade event crashes existing listeners

    ts: Program upgrade event crashes existing listeners

    So, we have custom event inside our program and appropriate listener in our client. Problem is that when we upgrade our program (or run anchor test) our client program crashes and gives us following error:

    /Users/zeke/WebstormProjects/marketplace-server/node_modules/@project-serum/anchor/src/program/event.ts:266
          throw new Error(`Could not find program invocation log line`);
                ^
    Error: Could not find program invocation log line
        at new ExecutionContext (/Users/zeke/WebstormProjects/marketplace-server/node_modules/@project-serum/anchor/src/program/event.ts:266:13)
        at EventParser.parseLogs (/Users/zeke/WebstormProjects/marketplace-server/node_modules/@project-serum/anchor/src/program/event.ts:177:23)
        at Object.callback (/Users/zeke/WebstormProjects/marketplace-server/node_modules/@project-serum/anchor/src/program/event.ts:103:27)
        at Connection._wsOnLogsNotification (/Users/zeke/WebstormProjects/marketplace-server/node_modules/@solana/web3.js/src/connection.ts:4360:13)
        at Client.emit (/Users/zeke/WebstormProjects/marketplace-server/node_modules/eventemitter3/index.js:181:35)
        at /Users/zeke/WebstormProjects/marketplace-server/node_modules/rpc-websockets/dist/lib/client.js:446:22
        at processTicksAndRejections (node:internal/process/task_queues:96:5)
    error Command failed with exit code 1.
    
    

    So when we upgrade program, following regex fails /^Program (.*) invoke.*$/g, because log starts with: Upgraded program **** and causes our client to crash.

    Class name is ExecutionContext where this regex is used. We can fix it by simply wrapping creation of this class in try/catch, but there could be better solutions, because we don't want to change it inside node_modules

    Our client code:

     program.addEventListener("ListingClosed", (event: ListingClosedEvent) => {
            console.log('event', event.accountAddress.toBase58())
     });
    
    bug ts 
    opened by dfl-zeke 14
  • Add example for remaining_accounts in anchor doc

    Add example for remaining_accounts in anchor doc

    Created a section for remaining_accounts in the program-module.md Added code example of distribution of lamports from PDA to dynamic number of accounts

    (Useful to have in doc to highlight the feature of keeping number of accounts variable in solana through remaining_accounts which is otherwise difficult)

    Let me know your suggestions on PR (any other place to add the code example if the current one doesn't look apt)

    opened by Purva-Chaudhari 2
  • Remove `rent_exempt` constraint

    Remove `rent_exempt` constraint

    Solana removed the abilityto create accounts are not rent exempt, so we can get rid of the rent_exempt=false constraint option.

    Not sure if removing it will be beneficial or not. Ideally less code is better so long as it doesn't complicate existing implementations.

    opened by Henry-E 0
  • lang: add the InitSpace macro

    lang: add the InitSpace macro

    Adds a new macro to automatically calculate the space.

    #[account]
    pub struct DataAccount {
        pub data: u64,
    }
    
    #[derive(Accounts)]
    pub struct Initialize<'info> {
        #[account(mut)]
        pub payer: Signer<'info>,
        pub system_program: Program<'info, System>,
        #[account(init, payer=payer, space= 8 + DataAccount::INIT_SPACE)]
        pub data: Account<'info, DataAccount>,
    }
    
    
    

    What remains to be done is:

    • [x] Fix the naming and the other stuffs like this (if needed)
    • [x] Implement the macro directly in the account attribute
    • [x] Add some docs in the proc macro
    • [x] Fix the issue with max_len when the type is Vec<Vec<>>
    • [x] Fix the bugs
    opened by Aursen 2
  • Chore: Use reusable workflows for GitHub actions

    Chore: Use reusable workflows for GitHub actions

    The tests and no-caching-tests workflows are nearly identical. The only difference currently is one caches dependencies, while the other doesn't. The rest is just duplicated code. This makes it harder to add new tests or modify existing ones as you need to change both files. This has caused issues in the past. This PR uses reusable workflows to call to the tests-reusable workflow and conditionally cache stuff based on inputs from the existing workflows.

    I also updated the install-solana action to be a bit more efficient.

    opened by stegaBOB 1
Releases(v0.26.0)
Demonstrates Solana data account versioning used in supporting the Solana Cookbook article: Account Data Versioning

versioning-solana This repo demonstrates ONE rudimentary way to upgrade/migrate account data changes with solana program changes. What is data version

Frank V. Castellucci 6 Sep 30, 2022
My attempt at learning Solana program (smart contract) development through RareSkill's Solana course.

60-days-of-solana My attempt at learning Solana program (smart contract) development through RareSkill's Solana course. Originally, I was trying to cr

Jasper 3 Feb 25, 2024
A framework for creating PoC's for Solana Smart Contracts in a painless and intuitive way

Solana PoC Framework DISCLAIMER: any illegal usage of this framework is heavily discouraged. Most projects on Solana offer a more than generous bug bo

Neodyme 165 Dec 18, 2022
The Voting example based on MoonZoon and Solana + Anchor framework.

The Voting example based on MoonZoon and Solana + Anchor framework.

Martin Kavík 6 Aug 13, 2022
Glommio Messaging Framework (GMF) is a high-performance RPC system designed to work with the Glommio framework.

Glommio Messaging Framework (GMF) The GMF library is a powerful and innovative framework developed for facilitating Remote Procedure Calls (RPCs) in R

Mohsen Zainalpour 29 Jun 13, 2023
Metaplex is a protocol built on top of Solana that allows: Creating/Minting non-fungible tokens;

Metaplex is a protocol built on top of Solana that allows: Creating/Minting non-fungible tokens; Starting a variety of auctions for primary/secondary

Metaplex Foundation 3.2k Jan 4, 2023
⛏ An open protocol for launching liquidity mining programs on Solana.

⛏ Quarry An open protocol for launching liquidity mining programs on Solana. Background Quarry was built with the intention of helping more Solana pro

Quarry Protocol 207 Dec 19, 2022
Generate Nice Solana Address By Template

Yes, I know about GPU generators. https://smith-mcf.medium.com/solana-vanity-address-using-gpus-5a68ad94d1d4 ./solana-nice-address --help solana-nice-

Kirill Fomichev 18 Jun 18, 2022
sandbox to play around numerous functionalities on Solana

Solana Sandbox This sandbox is for verifying smart contracts(programs) implemented on Solana for a self-study purpose. Programs Currently implemented

Tomoaki Imai 22 May 11, 2022
Solana Escrow Program written by RUST.

Environment Setup Install Rust from https://rustup.rs/ Install Solana from https://docs.solana.com/cli/install-solana-cli-tools#use-solanas-install-to

Blockchain*Lover* 5 Mar 10, 2022
A suite of programs for Solana key management and security.

?? goki Goki is a suite of programs for Solana key management and security. It currently features: Goki Smart Wallet: A wallet loosely based on the Se

Goki Protocol 157 Dec 8, 2022
Testing a smart contract on the Solana blockchain

Environment Setup Install Rust from https://rustup.rs/ Install Solana from https://docs.solana.com/cli/install-solana-cli-tools#use-solanas-install-to

Maurice 1 Oct 25, 2021
Solana NFT generative artwork program

resin Solana NFT generative artwork program Installation Depends on imagemagick for art generation, which can be installed here: https://imagemagick.o

null 4 Jun 24, 2022
Simple template for building smart contract(Rust) and RPC Client(web3.js) on Solana (WIP) ⛏👷🚧⚠️

Solana BPF Boilerplate Simple template for building smart contract(Rust) and RPC Client(web3.js) on Solana This boilerplate provides the following. Si

ono 6 Jan 30, 2022
Examples of Solana on-chain programs

spl-examples List of Solana on-chain programs which demonstrate different aspects of Solana architecture. 01__state It's a counter program. Each user

Max Block 51 Dec 6, 2022
🧑‍✈ Version control and key management for Solana programs.

captain ??‍✈️ Version control and key management for Solana programs. Automatic versioning of program binaries based on Cargo Separation of deployer a

Saber 35 Mar 1, 2022
Synchronized shadow state of Solana programs available for off-chain processing.

Solana Shadow The Solana Shadow crate adds shadows to solana on-chain accounts for off-chain processing. This create synchronises all accounts and the

null 40 Oct 30, 2022
Battery-included Solana/Anchor project skeleton.

Anchor Skeleton Battery-included Solana/Anchor project skeleton. Features Rust test only: All tests (integration, unit) are written in Rust, so the co

Weiyuan Wu 5 Feb 23, 2022
A solana program designed to mint Metaplex compliant NFTs.

Solana Minter My program used to mint Amoebits & Amoebit Minis. I wrote it from scratch using the hello-world program as an example & base. Features C

vlawmz 35 Sep 22, 2022