6

I want to define pubkeys of certain mints as constants to use throughout my Anchor program, how would I go about it?

I remember seeing some code using declare_id but I'm not sure.

4 Answers 4

7

You can use pubkey macro, defined here.

#[cfg(not(feature = "devnet"))]
pub mod mints {
    use solana_program::{pubkey, pubkey::Pubkey};
    pub const SOL: Pubkey = pubkey!("So11111111111111111111111111111111111111112");
    pub const USDC: Pubkey = pubkey!("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
}

#[cfg(feature = "devnet")]
pub mod mints {
    use solana_program::{pubkey, pubkey::Pubkey};
    pub const SOL: Pubkey = pubkey!("57z5KG1EHj5SV79xR1GVzEvkjWSJHgA7XMuPE457Rain");
    pub const USDC: Pubkey = pubkey!("Hqyx6oJbZ2LBdshEP9ApdSMoo1xKQSgBjEAAbzJhMbZY");
}


Also note that if you are using Anchor you would need to add solana_program into Cargo.toml, otherwise macro would not be exported. To use the same version Anchor uses you can add solana_program in this way:

[dependencies]
anchor-lang = "0.24.2"
solana-program = "*" # Will be resolved to the same version as in `anchor-lang`.

2

A way to do it is to define the key as a const with type &str. To use it in your program as a Pubkey you'd only need to parse it into a Pubkey. For example:

const MINT: &str = "2TPExuywxs4K7J2WAE8N8FiAMTPANvNXg9AV3ds7iybv";   

And to use in say your validator:

constraint = mint.key() == MINT.parse::<Pubkey>().unwrap()

or

constraint = mint.key() == Pubkey::new(MINT.as_bytes())
3
  • Thanks! This seems like the obvious way to do it as well. I am wondering if declare_id has any other benefit apart from giving a Pubkey directly?
    – sayantank
    Jul 30, 2022 at 7:51
  • You're welcome. So far as I know, declare_id only sets your program's Pubkey. Anchor says it can only be defined once so I assume that means it doesn't have any other use
    – Ademola
    Jul 30, 2022 at 8:20
  • 1
    bas58 decoding is very expensive and should be discouraged at runtime, especially in an on-chain program
    – trent.sol
    Aug 2, 2022 at 0:39
2

Edit: Per @trent.sol comment, there is an even more natural macro that can be used:

use solana_program::{pubkey, pubkey::Pubkey};

static ID: Pubkey = pubkey!("My11111111111111111111111111111111111111111");

OG answer: You can use declare_id for that. For example:

use anchor_lang::solana_program::declare_id;

mod my_mint {
    declare_id("....");
}

Under the hood, declare_id just generates a Pubkey with the base 58 encoded string you provide turned into a byte array.


Tangentially, if you are going to use a mint in your Anchor program, in all likelihood, you have to pass into the instruction. At which point, you will have access to the Account or AccountInfo struct, which would carry the public key under key field already.

5
  • Thank you! But how can I store it as a variable though? I would want to use it to check whether the passed mint in the Context struct is in fact the constant I defined
    – sayantank
    Jul 30, 2022 at 7:48
  • I just remembered about this piece of code in the Anchor repo, github.com/coral-xyz/anchor/blob/master/spl/src/mint.rs which I believe shows how we can use it as variables
    – sayantank
    Jul 30, 2022 at 7:54
  • Yep, that macro generates an ID in that module which you can later reference.
    – sohrab
    Jul 30, 2022 at 9:24
  • 1
    the pubkey!() wrapper for declare_id!() offers better self-documentation and should be preferred here.
    – trent.sol
    Aug 2, 2022 at 0:38
  • @trent.sol, good one! I didn't know about that one. Updated the answer.
    – sohrab
    Aug 2, 2022 at 12:30
0

A neat way to initialize constant Pubkeys in an organized way.

Lib.rs

// Program Id
declare_id!("e8zpvHybTbjMjoDR7CWjBUj1ttxQwRMUebhAf2z52ba");

mod pubkeys {
    use anchor_lang::prelude::*;

    // User Publickey
    pub mod user {
        use super::*;
        declare_id!("a8zpvHybTbjMjoDR7CWjBUj1ttxQwRMUebhAf2z5aaa");
    }

    // Vault Publickey
    pub mod vault {
        use super::*;
        declare_id!("b8zpvHybTbjMjoDR7CWjBUj1ttxQwRMUebhAf2z5bbb");
    }
}

Usage

use crate::*;

msg!("{}", ID)                   // prints Program Id
msg!("{}", pubkeys::user::ID);   // user User Address
msg!("{}", pubkeys::vault::ID);  // vault Vault Address

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.