token-client: memo now explicitly declares signers

This commit is contained in:
hanako mumei 2022-09-07 13:51:55 -07:00 committed by hana
parent 8e6caf45ac
commit 4dfd23e0b6
3 changed files with 40 additions and 8 deletions

View File

@ -393,7 +393,7 @@ async fn command_create_token(
}
if let Some(text) = memo {
token.with_memo(text);
token.with_memo(text, vec![config.default_signer.pubkey()]);
}
let res = token
@ -1073,7 +1073,7 @@ async fn command_burn(
let token = token_client_from_config(config, &mint_info.program_id, &mint_info.address);
if let Some(text) = memo {
token.with_memo(text);
token.with_memo(text, vec![config.default_signer.pubkey()]);
}
let res = token
@ -1120,7 +1120,7 @@ async fn command_mint(
let token = token_client_from_config(config, &mint_info.program_id, &mint_info.address);
if let Some(text) = memo {
token.with_memo(text);
token.with_memo(text, vec![config.default_signer.pubkey()]);
}
let res = token

View File

@ -60,6 +60,8 @@ pub enum TokenError {
AccountDecryption,
#[error("not enough funds in account")]
NotEnoughFunds,
#[error("missing memo signer")]
MissingMemoSigner,
}
impl PartialEq for TokenError {
fn eq(&self, other: &Self) -> bool {
@ -77,6 +79,7 @@ impl PartialEq for TokenError {
) => true,
(Self::AccountDecryption, Self::AccountDecryption) => true,
(Self::NotEnoughFunds, Self::NotEnoughFunds) => true,
(Self::MissingMemoSigner, Self::MissingMemoSigner) => true,
_ => false,
}
}
@ -172,6 +175,20 @@ impl ExtensionInitializationParams {
pub type TokenResult<T> = Result<T, TokenError>;
#[derive(Debug)]
struct TokenMemo {
text: String,
signers: Vec<Pubkey>,
}
impl TokenMemo {
pub fn to_instruction(&self) -> Instruction {
spl_memo::build_memo(
self.text.as_bytes(),
&self.signers.iter().collect::<Vec<_>>(),
)
}
}
pub struct Token<T> {
client: Arc<dyn ProgramClient<T>>,
pubkey: Pubkey, /*token mint*/
@ -179,7 +196,7 @@ pub struct Token<T> {
program_id: Pubkey,
nonce_account: Option<Pubkey>,
nonce_authority: Option<Pubkey>,
memo: Arc<RwLock<Option<String>>>,
memo: Arc<RwLock<Option<TokenMemo>>>,
}
impl<T> fmt::Debug for Token<T> {
@ -187,6 +204,9 @@ impl<T> fmt::Debug for Token<T> {
f.debug_struct("Token")
.field("pubkey", &self.pubkey)
.field("payer", &self.payer.pubkey())
.field("program_id", &self.program_id)
.field("nonce_account", &self.nonce_account)
.field("nonce_authority", &self.nonce_authority)
.field("memo", &self.memo.read().unwrap())
.finish()
}
@ -242,9 +262,12 @@ where
}
}
pub fn with_memo<M: AsRef<str>>(&self, memo: M) -> &Self {
pub fn with_memo<M: AsRef<str>>(&self, memo: M, signers: Vec<Pubkey>) -> &Self {
let mut w_memo = self.memo.write().unwrap();
*w_memo = Some(memo.as_ref().to_string());
*w_memo = Some(TokenMemo {
text: memo.as_ref().to_string(),
signers,
});
self
}
@ -305,7 +328,16 @@ where
{
let mut w_memo = self.memo.write().unwrap();
if let Some(memo) = w_memo.take() {
instructions.push(spl_memo::build_memo(memo.as_bytes(), &[&payer_key]));
let signing_pubkeys = signing_keypairs.pubkeys();
if !memo
.signers
.iter()
.all(|signer| signing_pubkeys.contains(signer))
{
return Err(TokenError::MissingMemoSigner);
}
instructions.push(memo.to_instruction());
}
}

View File

@ -131,7 +131,7 @@ async fn test_memo_transfers(
// transfer with memo
token
.with_memo("🦖")
.with_memo("🦖", vec![alice.pubkey()])
.transfer(
&alice_account,
&bob_account,