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