Remove initialize signers (#84)
* Remove initialize signers * update js to do initialize atomically
This commit is contained in:
parent
271073e67b
commit
666b0b75e3
|
@ -38,9 +38,13 @@ typedef enum Token_TokenInstruction_Tag {
|
|||
/**
|
||||
* Initializes a new mint and optionally deposits all the newly minted tokens in an account.
|
||||
*
|
||||
* The `InitializeWrappedAccount` instruction requires no signers and MUST be included within
|
||||
* the Transaction that creates the uninitialized account with the system program. Otherwise
|
||||
* another party can acquire ownership of the uninitialized token account.
|
||||
*
|
||||
* Accounts expected by this instruction:
|
||||
*
|
||||
* 0. `[writable, signer]` The mint to initialize.
|
||||
* 0. `[writable]` The mint to initialize.
|
||||
* 1.
|
||||
* * If supply is non-zero: `[writable]` The account to hold all the newly minted tokens.
|
||||
* * If supply is zero: `[]` The owner/multisignature of the mint.
|
||||
|
@ -52,9 +56,13 @@ typedef enum Token_TokenInstruction_Tag {
|
|||
/**
|
||||
* Initializes a new account to hold tokens.
|
||||
*
|
||||
* The `InitializeWrappedAccount` instruction requires no signers and MUST be included within
|
||||
* the Transaction that creates the uninitialized account with the system program. Otherwise
|
||||
* another party can acquire ownership of the uninitialized token account.
|
||||
*
|
||||
* Accounts expected by this instruction:
|
||||
*
|
||||
* 0. `[writable, signer]` The account to initialize.
|
||||
* 0. `[writable]` The account to initialize.
|
||||
* 1. `[]` The mint this account will be associated with.
|
||||
* 2. `[]` The new account's owner/multisignature.
|
||||
*/
|
||||
|
@ -66,9 +74,13 @@ typedef enum Token_TokenInstruction_Tag {
|
|||
* token instruction that require an owner/delegate to be present. The variant field represents the
|
||||
* number of signers (M) required to validate this multisignature account.
|
||||
*
|
||||
* The `InitializeWrappedAccount` instruction requires no signers and MUST be included within
|
||||
* the Transaction that creates the uninitialized account with the system program. Otherwise
|
||||
* another party can acquire ownership of the uninitialized token account.
|
||||
*
|
||||
* Accounts expected by this instruction:
|
||||
*
|
||||
* 0. `[signer, writable]` The multisignature account to initialize.
|
||||
* 0. `[writable]` The multisignature account to initialize.
|
||||
* 1. ..1+N. `[]` The signer accounts, must equal to N where 1 <= N <= 11.
|
||||
*/
|
||||
InitializeMultisig,
|
||||
|
|
|
@ -196,9 +196,6 @@ export async function invalidApprove(): Promise<void> {
|
|||
}
|
||||
|
||||
export async function failOnApproveOverspend(): Promise<void> {
|
||||
const connection = await getConnection();
|
||||
const balanceNeeded =
|
||||
(await Token.getMinBalanceRentForExemptAccount(connection)) * 3;
|
||||
const owner = new Account();
|
||||
const account1 = await testToken.createAccount(owner.publicKey);
|
||||
const account2 = await testToken.createAccount(owner.publicKey);
|
||||
|
@ -324,10 +321,6 @@ export async function multisig(): Promise<void> {
|
|||
const m = 2;
|
||||
const n = 5;
|
||||
|
||||
const connection = await getConnection();
|
||||
const balanceNeeded = await Token.getMinBalanceRentForExemptAccount(
|
||||
connection,
|
||||
);
|
||||
let signerAccounts = [];
|
||||
for (var i = 0; i < n; i++) {
|
||||
signerAccounts.push(new Account());
|
||||
|
|
|
@ -289,17 +289,10 @@ export class Token {
|
|||
space: MintLayout.span,
|
||||
programId,
|
||||
});
|
||||
await sendAndConfirmTransaction(
|
||||
'createAccount',
|
||||
connection,
|
||||
transaction,
|
||||
payer,
|
||||
mintAccount,
|
||||
);
|
||||
|
||||
// Create the mint
|
||||
let keys = [
|
||||
{pubkey: mintAccount.publicKey, isSigner: true, isWritable: false},
|
||||
{pubkey: mintAccount.publicKey, isSigner: false, isWritable: true},
|
||||
];
|
||||
if (supply.toNumber() != 0) {
|
||||
keys.push({pubkey: initialAccountPublicKey, isSigner: false, isWritable: true});
|
||||
|
@ -324,18 +317,19 @@ export class Token {
|
|||
);
|
||||
data = data.slice(0, encodeLength);
|
||||
}
|
||||
|
||||
transaction = new Transaction().add({
|
||||
transaction.add({
|
||||
keys,
|
||||
programId,
|
||||
data,
|
||||
});
|
||||
|
||||
// Send the two instructions
|
||||
await sendAndConfirmTransaction(
|
||||
'InitializeMint',
|
||||
'createAccount and InitializeMint',
|
||||
connection,
|
||||
transaction,
|
||||
payer,
|
||||
mintAccount,
|
||||
mintAccount
|
||||
);
|
||||
|
||||
return [token, initialAccountPublicKey];
|
||||
|
@ -371,21 +365,13 @@ export class Token {
|
|||
space: AccountLayout.span,
|
||||
programId: this.programId,
|
||||
});
|
||||
await sendAndConfirmTransaction(
|
||||
'createAccount',
|
||||
this.connection,
|
||||
transaction,
|
||||
this.payer,
|
||||
mintAccount,
|
||||
);
|
||||
|
||||
// create the new account
|
||||
const keys = [
|
||||
{pubkey: mintAccount.publicKey, isSigner: true, isWritable: true},
|
||||
{pubkey: mintAccount.publicKey, isSigner: false, isWritable: true},
|
||||
{pubkey: this.publicKey, isSigner: false, isWritable: false},
|
||||
{pubkey: owner, isSigner: false, isWritable: false},
|
||||
];
|
||||
|
||||
const dataLayout = BufferLayout.struct([BufferLayout.u8('instruction')]);
|
||||
const data = Buffer.alloc(dataLayout.span);
|
||||
dataLayout.encode(
|
||||
|
@ -394,17 +380,19 @@ export class Token {
|
|||
},
|
||||
data,
|
||||
);
|
||||
transaction = new Transaction().add({
|
||||
transaction.add({
|
||||
keys,
|
||||
programId: this.programId,
|
||||
data,
|
||||
});
|
||||
|
||||
// Send the two instructions
|
||||
await sendAndConfirmTransaction(
|
||||
'InitializeAccount',
|
||||
'createAccount and InitializeAccount',
|
||||
this.connection,
|
||||
transaction,
|
||||
this.payer,
|
||||
mintAccount,
|
||||
mintAccount
|
||||
);
|
||||
|
||||
return mintAccount.publicKey;
|
||||
|
@ -436,20 +424,12 @@ export class Token {
|
|||
space: MultisigLayout.span,
|
||||
programId: this.programId,
|
||||
});
|
||||
await sendAndConfirmTransaction(
|
||||
'createAccount',
|
||||
this.connection,
|
||||
transaction,
|
||||
this.payer,
|
||||
multisigAccount,
|
||||
);
|
||||
|
||||
// create the new account
|
||||
let keys = [
|
||||
{pubkey: multisigAccount.publicKey, isSigner: true, isWritable: true},
|
||||
{pubkey: multisigAccount.publicKey, isSigner: false, isWritable: true},
|
||||
];
|
||||
signers.forEach(signer => keys.push({pubkey: signer, isSigner: false, isWritable: false}));
|
||||
|
||||
const dataLayout = BufferLayout.struct(
|
||||
[
|
||||
BufferLayout.u8('instruction'),
|
||||
|
@ -464,17 +444,19 @@ export class Token {
|
|||
},
|
||||
data,
|
||||
);
|
||||
transaction = new Transaction().add({
|
||||
transaction.add({
|
||||
keys,
|
||||
programId: this.programId,
|
||||
data,
|
||||
});
|
||||
|
||||
// Send the two instructions
|
||||
await sendAndConfirmTransaction(
|
||||
'InitializeMultisig',
|
||||
'createAccount and InitializeMultisig',
|
||||
this.connection,
|
||||
transaction,
|
||||
this.payer,
|
||||
multisigAccount,
|
||||
multisigAccount
|
||||
);
|
||||
|
||||
return multisigAccount.publicKey;
|
||||
|
|
|
@ -29,9 +29,13 @@ pub struct TokenInfo {
|
|||
pub enum TokenInstruction {
|
||||
/// Initializes a new mint and optionally deposits all the newly minted tokens in an account.
|
||||
///
|
||||
/// The `InitializeWrappedAccount` instruction requires no signers and MUST be included within
|
||||
/// the Transaction that creates the uninitialized account with the system program. Otherwise
|
||||
/// another party can acquire ownership of the uninitialized token account.
|
||||
///
|
||||
/// Accounts expected by this instruction:
|
||||
///
|
||||
/// 0. `[writable, signer]` The mint to initialize.
|
||||
/// 0. `[writable]` The mint to initialize.
|
||||
/// 1.
|
||||
/// * If supply is non-zero: `[writable]` The account to hold all the newly minted tokens.
|
||||
/// * If supply is zero: `[]` The owner/multisignature of the mint.
|
||||
|
@ -41,9 +45,13 @@ pub enum TokenInstruction {
|
|||
InitializeMint(TokenInfo),
|
||||
/// Initializes a new account to hold tokens.
|
||||
///
|
||||
/// The `InitializeWrappedAccount` instruction requires no signers and MUST be included within
|
||||
/// the Transaction that creates the uninitialized account with the system program. Otherwise
|
||||
/// another party can acquire ownership of the uninitialized token account.
|
||||
///
|
||||
/// Accounts expected by this instruction:
|
||||
///
|
||||
/// 0. `[writable, signer]` The account to initialize.
|
||||
/// 0. `[writable]` The account to initialize.
|
||||
/// 1. `[]` The mint this account will be associated with.
|
||||
/// 2. `[]` The new account's owner/multisignature.
|
||||
InitializeAccount,
|
||||
|
@ -53,9 +61,13 @@ pub enum TokenInstruction {
|
|||
/// token instruction that require an owner/delegate to be present. The variant field represents the
|
||||
/// number of signers (M) required to validate this multisignature account.
|
||||
///
|
||||
/// The `InitializeWrappedAccount` instruction requires no signers and MUST be included within
|
||||
/// the Transaction that creates the uninitialized account with the system program. Otherwise
|
||||
/// another party can acquire ownership of the uninitialized token account.
|
||||
///
|
||||
/// Accounts expected by this instruction:
|
||||
///
|
||||
/// 0. `[signer, writable]` The multisignature account to initialize.
|
||||
/// 0. `[writable]` The multisignature account to initialize.
|
||||
/// 1. ..1+N. `[]` The signer accounts, must equal to N where 1 <= N <= 11.
|
||||
InitializeMultisig(u8),
|
||||
/// Transfers tokens from one account to another either directly or via a delegate.
|
||||
|
@ -254,7 +266,7 @@ pub fn initialize_mint(
|
|||
) -> Result<Instruction, ProgramError> {
|
||||
let data = TokenInstruction::InitializeMint(token_info).serialize()?;
|
||||
|
||||
let mut accounts = vec![AccountMeta::new(*mint_pubkey, true)];
|
||||
let mut accounts = vec![AccountMeta::new(*mint_pubkey, false)];
|
||||
if token_info.supply != 0 {
|
||||
match account_pubkey {
|
||||
Some(pubkey) => accounts.push(AccountMeta::new(*pubkey, false)),
|
||||
|
@ -289,7 +301,7 @@ pub fn initialize_account(
|
|||
let data = TokenInstruction::InitializeAccount.serialize()?;
|
||||
|
||||
let accounts = vec![
|
||||
AccountMeta::new(*account_pubkey, true),
|
||||
AccountMeta::new(*account_pubkey, false),
|
||||
AccountMeta::new_readonly(*mint_pubkey, false),
|
||||
AccountMeta::new_readonly(*owner_pubkey, false),
|
||||
];
|
||||
|
@ -317,7 +329,7 @@ pub fn initialize_multisig(
|
|||
let data = TokenInstruction::InitializeMultisig(m).serialize()?;
|
||||
|
||||
let mut accounts = Vec::with_capacity(1 + signer_pubkeys.len());
|
||||
accounts.push(AccountMeta::new(*multisig_pubkey, true));
|
||||
accounts.push(AccountMeta::new(*multisig_pubkey, false));
|
||||
for signer_pubkey in signer_pubkeys.iter() {
|
||||
accounts.push(AccountMeta::new_readonly(**signer_pubkey, false));
|
||||
}
|
||||
|
|
|
@ -97,10 +97,6 @@ impl State {
|
|||
let account_info_iter = &mut accounts.iter();
|
||||
let mint_info = next_account_info(account_info_iter)?;
|
||||
|
||||
if !mint_info.is_signer {
|
||||
return Err(ProgramError::MissingRequiredSignature);
|
||||
}
|
||||
|
||||
if State::Unallocated != State::deserialize(&mint_info.data.borrow())? {
|
||||
return Err(TokenError::AlreadyInUse.into());
|
||||
}
|
||||
|
@ -140,10 +136,6 @@ impl State {
|
|||
let mint_info = next_account_info(account_info_iter)?;
|
||||
let owner_info = next_account_info(account_info_iter)?;
|
||||
|
||||
if !new_account_info.is_signer {
|
||||
return Err(ProgramError::MissingRequiredSignature);
|
||||
}
|
||||
|
||||
let mut new_account_data = new_account_info.data.borrow_mut();
|
||||
if State::Unallocated != State::deserialize(&new_account_data)? {
|
||||
return Err(TokenError::AlreadyInUse.into());
|
||||
|
@ -713,18 +705,6 @@ mod tests {
|
|||
let mint_key = pubkey_rand();
|
||||
let mut mint_account = Account::new(0, size_of::<State>(), &program_id);
|
||||
|
||||
// missing signer
|
||||
let mut instruction =
|
||||
initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap();
|
||||
instruction.accounts[0].is_signer = false;
|
||||
assert_eq!(
|
||||
Err(ProgramError::MissingRequiredSignature),
|
||||
do_process_instruction(
|
||||
instruction,
|
||||
vec![&mut account_account, &mut mint_account, &mut owner_account],
|
||||
)
|
||||
);
|
||||
|
||||
// create account
|
||||
do_process_instruction(
|
||||
initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
|
||||
|
|
Loading…
Reference in New Issue