diff --git a/solana/anchor-bridge/programs/solitaire/src/lib.rs b/solana/anchor-bridge/programs/solitaire/src/lib.rs index f5c905a00..d0e7cdc18 100644 --- a/solana/anchor-bridge/programs/solitaire/src/lib.rs +++ b/solana/anchor-bridge/programs/solitaire/src/lib.rs @@ -77,6 +77,9 @@ pub use crate::{ types::*, }; +/// Library name and version to print in entrypoint. Must be evaluated in this crate in order to do the right thing +pub const PKG_NAME_VERSION: &'static str = concat!(env!("CARGO_PKG_NAME"), " ", env!("CARGO_PKG_VERSION")); + pub struct ExecutionContext<'a, 'b: 'a> { /// A reference to the program_id of the current program. pub program_id: &'a Pubkey, diff --git a/solana/anchor-bridge/programs/solitaire/src/macros.rs b/solana/anchor-bridge/programs/solitaire/src/macros.rs index a8dc3cf10..b0a6ccb6a 100644 --- a/solana/anchor-bridge/programs/solitaire/src/macros.rs +++ b/solana/anchor-bridge/programs/solitaire/src/macros.rs @@ -53,7 +53,7 @@ macro_rules! solitaire { } pub fn solitaire<'a, 'b: 'a>(p: &Pubkey, a: &'a [AccountInfo<'b>], d: &[u8]) -> ProgramResult { - solana_program::msg!(concat!(env!("CARGO_PKG_NAME"), " ", env!("CARGO_PKG_VERSION"))); + solana_program::msg!(solitaire::PKG_NAME_VERSION); if let Err(err) = dispatch(p, a, d) { solana_program::msg!("Error: {:?}", err); diff --git a/solana/anchor-bridge/programs/solitaire/src/types/accounts.rs b/solana/anchor-bridge/programs/solitaire/src/types/accounts.rs index c6b8c3a41..e19c58cee 100644 --- a/solana/anchor-bridge/programs/solitaire/src/types/accounts.rs +++ b/solana/anchor-bridge/programs/solitaire/src/types/accounts.rs @@ -28,7 +28,7 @@ use crate::{ /// A short alias for AccountInfo. pub type Info<'r> = AccountInfo<'r>; -#[derive(Eq, PartialEq)] +#[derive(Debug, Eq, PartialEq)] pub enum AccountState { Initialized, Uninitialized, diff --git a/solana/anchor-bridge/solitaire-client/src/lib.rs b/solana/anchor-bridge/solitaire-client/src/lib.rs index 91df92b13..a66b3be18 100644 --- a/solana/anchor-bridge/solitaire-client/src/lib.rs +++ b/solana/anchor-bridge/solitaire-client/src/lib.rs @@ -34,27 +34,34 @@ type StdResult = std::result::Result; pub type ErrBox = Box; /// The sum type for clearly specifying the accounts required on client side. +#[derive(Debug)] pub enum AccEntry { /// Least privileged account. Unprivileged(Pubkey), + /// Least privileged account, read-only. + UnprivilegedRO(Pubkey), /// Accounts that need to sign a Solana call Signer(Keypair), + /// Accounts that need to sign a Solana call, read-only. SignerRO(Keypair), - /// Program addresses for privileged/unprivileged cross calls + /// Program addresses for unprivileged cross calls CPIProgram(Pubkey), + /// Program addresses for privileged cross calls CPIProgramSigner(Keypair), - /// Key decided by Wrap implementation + /// Key decided from SPL constants Sysvar, + + /// Key derived from constants and/or program address Derived(Pubkey), + /// Key derived from constants and/or program address, read-only. DerivedRO(Pubkey), } /// Types implementing Wrap are those that can be turned into a -/// partial account vector tha -/// payload. +/// partial account vector for a program call. pub trait Wrap { fn wrap(_: &AccEntry) -> StdResult, ErrBox>; @@ -115,7 +122,27 @@ where T: BorshSerialize + Owned + Default, { fn wrap(a: &AccEntry) -> StdResult, ErrBox> { - todo!(); + use AccEntry::*; + use AccountState::*; + match IsInitialized { + Initialized => match a { + Unprivileged(k) => Ok(vec![AccountMeta::new(*k, false)]), + UnprivilegedRO(k) => Ok(vec![AccountMeta::new_readonly(*k, false)]), + Signer(pair) => Ok(vec![AccountMeta::new(pair.pubkey(), true)]), + SignerRO(pair) => Ok(vec![AccountMeta::new_readonly(pair.pubkey(), true)]), + _other => Err(format!("{} with IsInitialized = {:?} must be passed as Unprivileged, Signer or the respective read-only variant", std::any::type_name::(), a).into()) + }, + Uninitialized => match a { + Unprivileged(k) => Ok(vec![AccountMeta::new(*k, false)]), + Signer(pair) => Ok(vec![AccountMeta::new(pair.pubkey(), true)]), + _other => Err(format!("{} with IsInitialized = {:?} must be passed as Unprivileged or Signer (write access required for initialization)", std::any::type_name::(), a).into() ) + } + MaybeInitialized => match a { + Unprivileged(k) => Ok(vec![AccountMeta::new(*k, false)]), + Signer(pair) => Ok(vec![AccountMeta::new(pair.pubkey(), true)]), + _other => Err(format!("{} with IsInitialized = {:?} must be passed as Unprivileged or Signer (write access required in case of initialization)", std::any::type_name::(), a).into() ) + } + } } }