Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sdk/multisig/src/rpc/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export * from "./configTransactionAccountsClose.js";
export * from "./configTransactionCreate.js";
export * from "./configTransactionExecute.js";
export * from "./multisigAddMember.js";
export * from "./multisigChangeThreshold.js";
export * from "./multisigRemoveMember.js";
export * from "./multisigAddSpendingLimit.js";
export * from "./multisigRemoveSpendingLimit.js";
Expand Down
53 changes: 53 additions & 0 deletions sdk/multisig/src/rpc/multisigChangeThreshold.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {
Connection,
PublicKey,
SendOptions,
Signer,
TransactionSignature,
} from "@solana/web3.js";
import * as transactions from "../transactions";
import { translateAndThrowAnchorError } from "../errors";

/** Change the `threshold` of a controlled multisig. */
export async function multisigChangeThreshold({
connection,
multisigPda,
configAuthority,
rentPayer,
newThreshold,
memo,
signers,
sendOptions,
programId,
}: {
connection: Connection;
multisigPda: PublicKey;
configAuthority: PublicKey;
/** Pays the transaction fee. */
rentPayer: Signer;
newThreshold: number;
memo?: string;
signers?: Signer[];
sendOptions?: SendOptions;
programId?: PublicKey;
}): Promise<TransactionSignature> {
const blockhash = (await connection.getLatestBlockhash()).blockhash;

const tx = transactions.multisigChangeThreshold({
blockhash,
multisigPda,
configAuthority,
rentPayer: rentPayer.publicKey,
newThreshold,
memo,
programId,
});

tx.sign([rentPayer, ...(signers ?? [])]);

try {
return await connection.sendTransaction(tx, sendOptions);
} catch (err) {
translateAndThrowAnchorError(err);
}
}
3 changes: 2 additions & 1 deletion sdk/multisig/src/transactions/multisigChangeThreshold.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ export function multisigChangeThreshold({
}: {
blockhash: string;
multisigPda: PublicKey;
spendingLimit: PublicKey;
/** Unused. */
spendingLimit?: PublicKey;
configAuthority: PublicKey;
rentPayer: PublicKey;
newThreshold: number;
Expand Down
59 changes: 59 additions & 0 deletions tests/suites/multisig-sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,65 @@ describe("Multisig SDK", () => {
});
});

describe("multisig_change_threshold for a controlled multisig", () => {
let multisigPda: PublicKey;
let configAuthority: Keypair;
let wrongConfigAuthority: Keypair;
before(async () => {
configAuthority = await generateFundedKeypair(connection);
wrongConfigAuthority = await generateFundedKeypair(connection);

// Create new controlled multisig.
multisigPda = (
await createControlledMultisig({
connection,
createKey: Keypair.generate(),
members,
threshold: 1,
configAuthority: configAuthority.publicKey,
timeLock: 0,
programId,
})
)[0];
});

it("error: invalid authority", async () => {
const rentPayer = await generateFundedKeypair(connection);
await assert.rejects(
multisig.rpc.multisigChangeThreshold({
connection,
multisigPda,
configAuthority: wrongConfigAuthority.publicKey,
rentPayer,
newThreshold: 2,
signers: [wrongConfigAuthority],
programId,
}),
/Attempted to perform an unauthorized action/
);
});

it("change `threshold` for the controlled multisig", async () => {
const rentPayer = await generateFundedKeypair(connection);
const signature = await multisig.rpc.multisigChangeThreshold({
connection,
multisigPda,
configAuthority: configAuthority.publicKey,
rentPayer,
newThreshold: 2,
signers: [configAuthority],
programId,
});
await connection.confirmTransaction(signature);

const multisigAccount = await Multisig.fromAccountAddress(
connection,
multisigPda
);
assert.strictEqual(multisigAccount.threshold, 2);
});
});

describe("multisig_set_config_authority", () => {
let multisigPda: PublicKey;
let configAuthority: Keypair;
Expand Down