anchor_lang/accounts/
signer.rs1use crate::error::ErrorCode;
3use crate::{Accounts, AccountsExit, Key, Result, ToAccountInfos, ToAccountMetas};
4use solana_program::account_info::AccountInfo;
5use solana_program::instruction::AccountMeta;
6use solana_program::pubkey::Pubkey;
7use std::collections::BTreeSet;
8use std::ops::Deref;
9
10#[derive(Debug, Clone)]
38pub struct Signer<'info> {
39 info: &'info AccountInfo<'info>,
40}
41
42impl<'info> Signer<'info> {
43 fn new(info: &'info AccountInfo<'info>) -> Signer<'info> {
44 Self { info }
45 }
46
47 #[inline(never)]
49 pub fn try_from(info: &'info AccountInfo<'info>) -> Result<Signer<'info>> {
50 if !info.is_signer {
51 return Err(ErrorCode::AccountNotSigner.into());
52 }
53 Ok(Signer::new(info))
54 }
55}
56
57impl<'info, B> Accounts<'info, B> for Signer<'info> {
58 #[inline(never)]
59 fn try_accounts(
60 _program_id: &Pubkey,
61 accounts: &mut &'info [AccountInfo<'info>],
62 _ix_data: &[u8],
63 _bumps: &mut B,
64 _reallocs: &mut BTreeSet<Pubkey>,
65 ) -> Result<Self> {
66 if accounts.is_empty() {
67 return Err(ErrorCode::AccountNotEnoughKeys.into());
68 }
69 let account = &accounts[0];
70 *accounts = &accounts[1..];
71 Signer::try_from(account)
72 }
73}
74
75impl<'info> AccountsExit<'info> for Signer<'info> {}
76
77impl ToAccountMetas for Signer<'_> {
78 fn to_account_metas(&self, is_signer: Option<bool>) -> Vec<AccountMeta> {
79 let is_signer = is_signer.unwrap_or(self.info.is_signer);
80 let meta = match self.info.is_writable {
81 false => AccountMeta::new_readonly(*self.info.key, is_signer),
82 true => AccountMeta::new(*self.info.key, is_signer),
83 };
84 vec![meta]
85 }
86}
87
88impl<'info> ToAccountInfos<'info> for Signer<'info> {
89 fn to_account_infos(&self) -> Vec<AccountInfo<'info>> {
90 vec![self.info.clone()]
91 }
92}
93
94impl<'info> AsRef<AccountInfo<'info>> for Signer<'info> {
95 fn as_ref(&self) -> &AccountInfo<'info> {
96 self.info
97 }
98}
99
100impl<'info> Deref for Signer<'info> {
101 type Target = AccountInfo<'info>;
102
103 fn deref(&self) -> &Self::Target {
104 self.info
105 }
106}
107
108impl Key for Signer<'_> {
109 fn key(&self) -> Pubkey {
110 *self.info.key
111 }
112}