Skip to content

Commit de40ed9

Browse files
authored
[RDS-3165]: Scripts for adding new members to multisig (#6015)
1 parent 8cb8603 commit de40ed9

File tree

4 files changed

+128
-4
lines changed

4 files changed

+128
-4
lines changed

packages/solana-connector/package.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,12 @@
3434
"make-feed-table": "yarn global:ts-node scripts/make-feed-table.ts",
3535
"show-multi-sig-tx-details": "yarn global:ts-node scripts/ledger/show-multi-sig-tx-details.ts",
3636
"write-buffer": "yarn global:ts-node scripts/write-program-buffer.ts",
37-
"update-mmetadata-authority": "yarn global:ts-node scripts/update-metadata-authority.ts"
37+
"update-metadata-authority": "yarn global:ts-node scripts/update-metadata-authority.ts",
38+
"add-multi-sig-members": "yarn global:ts-node scripts/ledger/add-multi-sig-members.ts",
39+
"execute-config-tx": "yarn global:ts-node scripts/ledger/execute-config-tx.ts"
3840
},
3941
"dependencies": {
4042
"@coral-xyz/anchor": "0.30.1",
41-
"@metaplex-foundation/mpl-token-metadata": "^3.4.0",
42-
"@metaplex-foundation/umi": "^1.2.0",
43-
"@metaplex-foundation/umi-bundle-defaults": "^1.2.0",
4443
"@redstone-finance/sdk": "workspace:*",
4544
"@redstone-finance/utils": "workspace:*",
4645
"@solana/web3.js": "^1.98.2"
@@ -50,6 +49,9 @@
5049
"@babel/preset-typescript": "^7.23.2",
5150
"@ledgerhq/hw-app-solana": "^7.2.4",
5251
"@ledgerhq/hw-transport-node-hid": "^6.29.5",
52+
"@metaplex-foundation/mpl-token-metadata": "^3.4.0",
53+
"@metaplex-foundation/umi": "^1.2.0",
54+
"@metaplex-foundation/umi-bundle-defaults": "^1.2.0",
5355
"@redstone-finance/chain-configs": "workspace:*",
5456
"@sqds/multisig": "^2.1.3",
5557
"@types/bn.js": "^5.1.0",
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import {
2+
Keypair,
3+
PublicKey,
4+
TransactionMessage,
5+
VersionedTransaction,
6+
} from "@solana/web3.js";
7+
import "dotenv/config";
8+
import { makeConnection } from "../utils";
9+
import { LEDGER_ACCOUNT, SQUAD_ADDRESS } from "./config";
10+
import { makeSolana } from "./ledger-utils";
11+
import { SquadsMultisig } from "./multi-sig-utils";
12+
13+
const NEW_MEMBERS = [
14+
Keypair.generate().publicKey,
15+
Keypair.generate().publicKey,
16+
];
17+
const NEW_THRESHOLD = 2;
18+
19+
async function add_member(
20+
squadAddress: PublicKey,
21+
members: PublicKey[],
22+
newThreshold: number
23+
) {
24+
const connection = makeConnection();
25+
const solanaLedger = await makeSolana(LEDGER_ACCOUNT);
26+
const squadUtils = new SquadsMultisig(squadAddress, connection);
27+
const publicKey = (await solanaLedger.getPublicKey()).ed;
28+
29+
const ix = await squadUtils.addMembers(publicKey, members, newThreshold);
30+
31+
const tx = new VersionedTransaction(
32+
new TransactionMessage({
33+
payerKey: publicKey,
34+
recentBlockhash: (await connection.getLatestBlockhash()).blockhash,
35+
instructions: [ix],
36+
}).compileToV0Message()
37+
);
38+
39+
await solanaLedger.signTransaction(tx);
40+
console.log(await connection.sendTransaction(tx));
41+
}
42+
43+
void add_member(SQUAD_ADDRESS, NEW_MEMBERS, NEW_THRESHOLD);
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import {
2+
PublicKey,
3+
TransactionMessage,
4+
VersionedTransaction,
5+
} from "@solana/web3.js";
6+
import "dotenv/config";
7+
import { makeConnection } from "../utils";
8+
import { LEDGER_ACCOUNT, SQUAD_ADDRESS } from "./config";
9+
import { makeSolana } from "./ledger-utils";
10+
import { SquadsMultisig } from "./multi-sig-utils";
11+
12+
async function execute_config_tx(squadAddress: PublicKey) {
13+
const connection = makeConnection();
14+
const solanaLedger = await makeSolana(LEDGER_ACCOUNT);
15+
const squadUtils = new SquadsMultisig(squadAddress, connection);
16+
const publicKey = (await solanaLedger.getPublicKey()).ed;
17+
18+
const ix = await squadUtils.execute_config(publicKey, undefined);
19+
20+
const tx = new VersionedTransaction(
21+
new TransactionMessage({
22+
payerKey: publicKey,
23+
recentBlockhash: (await connection.getLatestBlockhash()).blockhash,
24+
instructions: [ix],
25+
}).compileToV0Message()
26+
);
27+
28+
await solanaLedger.signTransaction(tx);
29+
console.log(await connection.sendTransaction(tx));
30+
}
31+
32+
void execute_config_tx(SQUAD_ADDRESS);

packages/solana-connector/scripts/ledger/multi-sig-utils.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
TransactionMessage,
66
} from "@solana/web3.js";
77
import * as multisig from "@sqds/multisig";
8+
import { types } from "@sqds/multisig";
89

910
export class SquadsMultisig {
1011
constructor(
@@ -20,6 +21,36 @@ export class SquadsMultisig {
2021
return BigInt(Number(multisigInfo.transactionIndex));
2122
}
2223

24+
async addMembers(
25+
feePayer: PublicKey,
26+
newMembers: PublicKey[],
27+
newThreshold: number
28+
) {
29+
const actions = newMembers.map(
30+
(newMember) =>
31+
({
32+
__kind: "AddMember",
33+
newMember: {
34+
key: newMember,
35+
permissions: types.Permissions.all(),
36+
},
37+
}) as types.ConfigAction
38+
);
39+
actions.push({ __kind: "ChangeThreshold", newThreshold });
40+
41+
const transactionIndex = (await this.multisigTransactionIndex()) + 1n;
42+
43+
console.log(`Config actions:`, actions);
44+
45+
return multisig.instructions.configTransactionCreate({
46+
multisigPda: this.multisigPda,
47+
transactionIndex,
48+
creator: feePayer,
49+
rentPayer: feePayer,
50+
actions,
51+
});
52+
}
53+
2354
async createVaultTransaction(
2455
member: PublicKey,
2556
ix: TransactionInstruction,
@@ -98,6 +129,22 @@ export class SquadsMultisig {
98129
});
99130
}
100131

132+
async execute_config(member: PublicKey, transactionIdx: bigint | undefined) {
133+
const transactionIndex =
134+
transactionIdx ?? (await this.multisigTransactionIndex());
135+
136+
console.log(
137+
`Executing squads transaction with index = ${transactionIndex}`
138+
);
139+
140+
return multisig.instructions.configTransactionExecute({
141+
multisigPda: this.multisigPda,
142+
transactionIndex,
143+
member,
144+
rentPayer: member,
145+
});
146+
}
147+
101148
async txInfo(txIdx: number) {
102149
return await multisig.accounts.VaultTransaction.fromAccountAddress(
103150
this.connection,

0 commit comments

Comments
 (0)