anchor_lang/accounts/
unchecked_account.rs

1//! Explicit wrapper for AccountInfo types to emphasize
2//! that no checks are performed
3
4use crate::error::ErrorCode;
5use crate::{Accounts, AccountsExit, Key, Result, ToAccountInfos, ToAccountMetas};
6use solana_program::account_info::AccountInfo;
7use solana_program::instruction::AccountMeta;
8use solana_program::pubkey::Pubkey;
9use std::collections::BTreeSet;
10use std::ops::Deref;
11
12/// Explicit wrapper for AccountInfo types to emphasize
13/// that no checks are performed
14#[derive(Debug, Clone)]
15pub struct UncheckedAccount<'info>(&'info AccountInfo<'info>);
16
17impl<'info> UncheckedAccount<'info> {
18    pub fn try_from(acc_info: &'info AccountInfo<'info>) -> Self {
19        Self(acc_info)
20    }
21}
22
23impl<'info, B> Accounts<'info, B> for UncheckedAccount<'info> {
24    fn try_accounts(
25        _program_id: &Pubkey,
26        accounts: &mut &'info [AccountInfo<'info>],
27        _ix_data: &[u8],
28        _bumps: &mut B,
29        _reallocs: &mut BTreeSet<Pubkey>,
30    ) -> Result<Self> {
31        if accounts.is_empty() {
32            return Err(ErrorCode::AccountNotEnoughKeys.into());
33        }
34        let account = &accounts[0];
35        *accounts = &accounts[1..];
36        Ok(UncheckedAccount(account))
37    }
38}
39
40impl ToAccountMetas for UncheckedAccount<'_> {
41    fn to_account_metas(&self, is_signer: Option<bool>) -> Vec<AccountMeta> {
42        let is_signer = is_signer.unwrap_or(self.is_signer);
43        let meta = match self.is_writable {
44            false => AccountMeta::new_readonly(*self.key, is_signer),
45            true => AccountMeta::new(*self.key, is_signer),
46        };
47        vec![meta]
48    }
49}
50
51impl<'info> ToAccountInfos<'info> for UncheckedAccount<'info> {
52    fn to_account_infos(&self) -> Vec<AccountInfo<'info>> {
53        vec![self.0.clone()]
54    }
55}
56
57impl<'info> AccountsExit<'info> for UncheckedAccount<'info> {}
58
59impl<'info> AsRef<AccountInfo<'info>> for UncheckedAccount<'info> {
60    fn as_ref(&self) -> &AccountInfo<'info> {
61        self.0
62    }
63}
64
65impl<'info> Deref for UncheckedAccount<'info> {
66    type Target = AccountInfo<'info>;
67
68    fn deref(&self) -> &Self::Target {
69        self.0
70    }
71}
72
73impl Key for UncheckedAccount<'_> {
74    fn key(&self) -> Pubkey {
75        *self.0.key
76    }
77}