Overview
Create a Squads multisig account with members, permissions, and threshold configuration.Use
multisigCreateV2 instead of the deprecated multisigCreate. The current program source rejects multisigCreate with a MultisigCreateDeprecated error.Prerequisites
@sqds/multisigand@solana/web3.jspackages installed- A Solana RPC endpoint
- SOL for transaction fees
Quick Example
import * as multisig from "@sqds/multisig";
import { Connection, Keypair } from "@solana/web3.js";
const { Permission, Permissions } = multisig.types;
const connection = new Connection("<your rpc url>");
const createKey = Keypair.generate();
const creator = Keypair.generate();
const [multisigPda] = multisig.getMultisigPda({
createKey: createKey.publicKey,
});
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
createKey | PublicKey | Yes | Random public key used to derive the multisig PDA. Must be a signer. |
creator | PublicKey | Yes | Creator and fee payer of the multisig |
multisigPda | PublicKey | Yes | PDA of the multisig, derived from createKey |
configAuthority | PublicKey | null | Yes | Authority for config changes. Set to null for autonomous multisig |
timeLock | number | Yes | Seconds between voting settlement and execution. Use 0 for no time lock |
members | Member[] | Yes | Array of members with their keys and permissions |
threshold | number | Yes | Number of votes required to approve transactions |
treasury | PublicKey | Yes | Program config treasury account |
rentCollector | PublicKey | null | Yes | Account to receive reclaimed rent. Set to null to turn off rent reclamation |
Full Example
import * as multisig from "@sqds/multisig";
import { Connection, Keypair } from "@solana/web3.js";
// Defines permissions enum
const { Permission, Permissions } = multisig.types;
async function main() {
// Cluster Connection
// Required argument if you use the .rpc method
const connection = new Connection("< your rpc here >");
// Random Public Key that will be used to derive a multisig PDA
// This will need to be a signer on the transaction
const createKey = Keypair.generate();
// Creator should be a Keypair or a Wallet Adapter wallet
const creator = Keypair.generate();
// Second member of the multisig
const secondMember = Keypair.generate();
// Derive the multisig PDA
const [multisigPda] = multisig.getMultisigPda({
createKey: createKey.publicKey,
});
const programConfigPda = multisig.getProgramConfigPda({})[0];
const programConfig =
await multisig.accounts.ProgramConfig.fromAccountAddress(
connection,
programConfigPda
);
const configTreasury = programConfig.treasury;
const ix = await multisig.instructions.multisigCreateV2({
// Must sign the transaction, unless the .rpc method is used.
createKey: createKey.publicKey,
// The creator & fee payer
creator: creator.publicKey,
// The PDA of the multisig you are creating, derived by a random PublicKey
multisigPda,
// Here the config authority will be the system program
configAuthority: null,
// Create without any time-lock
timeLock: 0,
// List of the members to add to the multisig
members: [{
// Members Public Key
key: creator.publicKey,
// Granted Proposer, Voter, and Executor permissions
permissions: Permissions.all(),
},
{
key: secondMember.publicKey,
// Member can only add votes to proposed transactions
permissions: Permissions.fromPermissions([Permission.Vote]),
},
],
// This means that there needs to be 2 votes for a transaction proposal to be approved
threshold: 2,
// This is for the program config treasury account
treasury: configTreasury,
// Rent reclaim account
rentCollector: null
});
}
Error Handling
| Error | Cause | Solution |
|---|---|---|
| PDA already in use | createKey collision | Generate a new createKey |
| Insufficient funds | Not enough SOL | Fund the creator account |