Multi-sig

M-of-N threshold signature wallet for secure group transactions

Pending Anchor 0.32
Program ID 3AZTsn99QJnAVJ7gJE5QWgbWgj5jJ8D6wEBn89fKJvJH
Binary Size 254K
Cluster Devnet

Instructions

IX create_multisig

Creates a new multi-signature wallet with a list of owners and a required approval threshold.

ParameterTypeDescription
ownersVec<Pubkey>List of owner wallet addresses (max 10)
thresholdu8Number of approvals required to execute a transaction
IX propose_transfer

Proposes a new token transfer from the multisig vault. The proposer's approval is automatically counted.

ParameterTypeDescription
amountu64Token amount to transfer
IX approve

Approves a pending transaction. Each owner can only approve once.

ParameterTypeDescription
No parameters
IX execute

Executes the transfer once the required number of approvals has been reached.

ParameterTypeDescription
No parameters

Accounts

Multisig

FieldTypeDescription
ownersVec<Pubkey>List of owner wallet addresses
thresholdu8Required number of approvals
tx_countu64Total transactions proposed
bumpu8PDA bump seed

Transaction

FieldTypeDescription
multisigPubkeyThe multisig wallet this transaction belongs to
proposerPubkeyWallet that proposed the transaction
idu64Sequential transaction ID
destinationPubkeyRecipient wallet address
mintPubkeyToken mint for the transfer
amountu64Token amount to transfer
approvalsVec<bool>Approval status for each owner (indexed by position)
executedboolWhether the transaction has been executed
created_ati64Unix timestamp when the transaction was proposed
bumpu8PDA bump seed

PDA Derivation

multisig
seeds = [b"multisig", creator]
tx
seeds = [b"tx", multisig, tx_count.to_le_bytes()]

Error Codes

InvalidThreshold Threshold must be between 1 and the number of owners
TooManyOwners Maximum of 10 owners allowed per multisig
NotOwner The signer is not an owner of this multisig
AlreadyApproved This owner has already approved the transaction
ThresholdNotMet Not enough approvals to execute the transaction
AlreadyExecuted This transaction has already been executed
Overflow Arithmetic overflow in transaction processing

Usage Example

import { Program, BN } from "@coral-xyz/anchor";
import { PublicKey } from "@solana/web3.js";

// Create a 2-of-3 multisig
const owners = [owner1.publicKey, owner2.publicKey, owner3.publicKey];
const threshold = 2;

const [multisigPda] = PublicKey.findProgramAddressSync(
  [Buffer.from("multisig"), owner1.publicKey.toBuffer()],
  program.programId
);

await program.methods
  .createMultisig(owners, threshold)
  .accounts({
    multisig: multisigPda,
    creator: owner1.publicKey,
  })
  .signers([owner1])
  .rpc();

// Propose a transfer of 5000 tokens
await program.methods
  .proposeTransfer(new BN(5_000_000_000))
  .accounts({
    multisig: multisigPda,
    proposer: owner1.publicKey,
    destination: recipient.publicKey,
    mint,
  })
  .signers([owner1])
  .rpc();