Abehjati/simplify-multisig-cli (#361)

* Move some configs to a config file inside code

* Remove redundant ledger logs

* Use getSquads for execute too

* Refactor ledger logging removal

* update Readme
This commit is contained in:
Ali Behjati 2022-10-25 14:45:26 +02:00 committed by GitHub
parent 4629f689e4
commit eea42578b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 72 additions and 109 deletions

View File

@ -15,32 +15,31 @@ Note:
- Node.js v17.15.0 or higher is required as it [introduces support for fetch API](https://nodejs.org/tr/blog/release/v17.5.0/). - Node.js v17.15.0 or higher is required as it [introduces support for fetch API](https://nodejs.org/tr/blog/release/v17.5.0/).
- When using with Ledger, please enable [blind signing](https://www.ledger.com/academy/enable-blind-signing-why-when-and-how-to-stay-safe) in the Solana app settings. TLDR: When you enable blind signing, you enable your device to approve a smart contract transaction, even though it hasnt been able to display full contract data to you. In other words, youre agreeing to trust, instead of verify, the transaction. You still have to manually approve each transactions. - When using with Ledger, please enable [blind signing](https://www.ledger.com/academy/enable-blind-signing-why-when-and-how-to-stay-safe) in the Solana app settings. TLDR: When you enable blind signing, you enable your device to approve a smart contract transaction, even though it hasnt been able to display full contract data to you. In other words, youre agreeing to trust, instead of verify, the transaction. You still have to manually approve each transactions.
- Information about ledger derivation can be found [here](https://github.com/LedgerHQ/ledger-live-common/blob/master/docs/derivation.md). - Information about ledger derivation can be found [here](https://github.com/LedgerHQ/ledger-live-common/blob/master/docs/derivation.md).
- RPC URLs can be found [here](https://book.wormhole.com/reference/rpcnodes.html).
### Create a multisig transaction ### Create a multisig transaction
``` ```
npm start -- create -c <CLUSTER> -v <VAULT_ADDRESS> -l -lda <LEDGER_DERIVATION_ACCOUNT> -ldc <LEDGER_DERIVATION_CHANGE> -w <WALLET_SECRET_KEY_FILEPATH> -p <PAYLOAD> npm start -- create -c <CLUSTER: [mainnet|devnet]> -l -lda <LEDGER_DERIVATION_ACCOUNT> -ldc <LEDGER_DERIVATION_CHANGE> -w <WALLET_SECRET_KEY_FILEPATH> -p <PAYLOAD>
``` ```
To use ledger with default derivation account and change: To use ledger with default derivation account and change:
``` ```
npm start -- create -c devnet -v HezRVdwZmKpdKbksxFytKnHTQVztiTmL3GHdNadMFYui -l -p hello npm start -- create -c devnet -l -p hello
``` ```
To use ledger with custom derivation account and/or change: To use ledger with custom derivation account and/or change:
``` ```
npm start -- create -c devnet -v HezRVdwZmKpdKbksxFytKnHTQVztiTmL3GHdNadMFYui -l -lda 0 -p hello npm start -- create -c devnet -l -lda 0 -p hello
npm start -- create -c devnet -v HezRVdwZmKpdKbksxFytKnHTQVztiTmL3GHdNadMFYui -l -lda 0 -ldc 1 -p hello npm start -- create -c devnet -l -lda 0 -ldc 1 -p hello
``` ```
To use hot wallet : To use hot wallet :
``` ```
npm start -- create -c devnet -v HezRVdwZmKpdKbksxFytKnHTQVztiTmL3GHdNadMFYui -w keys/key.json -p hello npm start -- create -c devnet -w keys/key.json -p hello
``` ```
--- ---
@ -48,27 +47,27 @@ npm start -- create -c devnet -v HezRVdwZmKpdKbksxFytKnHTQVztiTmL3GHdNadMFYui -w
### Execute a multisig transaction ### Execute a multisig transaction
``` ```
npm start -- execute -c <CLUSTER> -v <VAULT_ADDRESS> -w <WALLET_SECRET_KEY_FILEPATH> -m <MESSAGE_SECRET_KEY_FILEPATH> -t <TX_ID> -u <RPC_URL> npm start -- execute -c <CLUSTER: [mainnet|devnet]> -w <WALLET_SECRET_KEY_FILEPATH> -t <TX_ID>
``` ```
To use ledger with default derivation account and change: To use ledger with default derivation account and change:
``` ```
npm start -- execute -c devnet -v HezRVdwZmKpdKbksxFytKnHTQVztiTmL3GHdNadMFYui -l -m keys/message.json -t GSC8r7Qsi9pc698fckaQgzHufG6LqVq3vZijyu5KsXLh -u https://wormhole-v2-testnet-api.certus.one/ npm start -- execute -c devnet -l -m keys/message.json -t GSC8r7Qsi9pc698fckaQgzHufG6LqVq3vZijyu5KsXLh
``` ```
To use ledger with custom derivation account and/or change: To use ledger with custom derivation account and/or change:
``` ```
npm start -- execute -c devnet -v HezRVdwZmKpdKbksxFytKnHTQVztiTmL3GHdNadMFYui -l -lda 0 -m keys/message.json -t GSC8r7Qsi9pc698fckaQgzHufG6LqVq3vZijyu5KsXLh -u https://wormhole-v2-testnet-api.certus.one/ npm start -- execute -c devnet -l -lda 0 -m keys/message.json -t GSC8r7Qsi9pc698fckaQgzHufG6LqVq3vZijyu5KsXLh
npm start -- execute -c devnet -v HezRVdwZmKpdKbksxFytKnHTQVztiTmL3GHdNadMFYui -l -lda 0 -ldc 1 -m keys/message.json -t GSC8r7Qsi9pc698fckaQgzHufG6LqVq3vZijyu5KsXLh -u https://wormhole-v2-testnet-api.certus.one/ npm start -- execute -c devnet -l -lda 0 -ldc 1 -m keys/message.json -t GSC8r7Qsi9pc698fckaQgzHufG6LqVq3vZijyu5KsXLh
``` ```
Example: Example:
``` ```
npm start -- execute -c devnet -v HezRVdwZmKpdKbksxFytKnHTQVztiTmL3GHdNadMFYui -w keys/key.json -m keys/message.json -t GSC8r7Qsi9pc698fckaQgzHufG6LqVq3vZijyu5KsXLh -u https://wormhole-v2-testnet-api.certus.one/ npm start -- execute -c devnet -w keys/key.json -m keys/message.json -t GSC8r7Qsi9pc698fckaQgzHufG6LqVq3vZijyu5KsXLh
``` ```
https://github.com/LedgerHQ/ledger-live/wiki/LLC:derivation https://github.com/LedgerHQ/ledger-live/wiki/LLC:derivation

View File

@ -23,6 +23,28 @@ import { LedgerNodeWallet } from "./wallet";
setDefaultWasm("node"); setDefaultWasm("node");
type Cluster = "devnet" | "mainnet";
type WormholeNetwork = "TESTNET" | "MAINNET";
type Config = {
wormholeClusterName: WormholeNetwork,
wormholeRpcEndpoint: string,
vault: PublicKey,
};
const CONFIG: Record<Cluster, Config> = {
devnet: {
wormholeClusterName: "TESTNET",
vault: new PublicKey("6baWtW1zTUVMSJHJQVxDUXWzqrQeYBr6mu31j3bTKwY3"),
wormholeRpcEndpoint: "https://wormhole-v2-testnet-api.certus.one"
},
mainnet: {
wormholeClusterName: "MAINNET",
vault: new PublicKey("FVQyHcooAtThJ83XFrNnv74BcinbRH3bRmfFamAHBfuj"),
wormholeRpcEndpoint: "https://wormhole-v2-mainnet-api.certus.one"
}
};
program program
.name("pyth-multisig") .name("pyth-multisig")
.description("CLI to creating and executing multisig transactions for pyth") .description("CLI to creating and executing multisig transactions for pyth")
@ -32,7 +54,6 @@ program
.command("create") .command("create")
.description("Create a new multisig transaction") .description("Create a new multisig transaction")
.option("-c, --cluster <network>", "solana cluster to use", "devnet") .option("-c, --cluster <network>", "solana cluster to use", "devnet")
.requiredOption("-v, --vault-address <address>", "multisig vault address")
.option("-l, --ledger", "use ledger") .option("-l, --ledger", "use ledger")
.option( .option(
"-lda, --ledger-derivation-account <number>", "-lda, --ledger-derivation-account <number>",
@ -49,8 +70,9 @@ program
) )
.option("-p, --payload <hex-string>", "payload to sign", "0xdeadbeef") .option("-p, --payload <hex-string>", "payload to sign", "0xdeadbeef")
.action(async (options) => { .action(async (options) => {
const cluster: Cluster = options.cluster;
const squad = await getSquadsClient( const squad = await getSquadsClient(
options.cluster, cluster,
options.ledger, options.ledger,
options.ledgerDerivationAccount, options.ledgerDerivationAccount,
options.ledgerDerivationChange, options.ledgerDerivationChange,
@ -59,8 +81,7 @@ program
await createWormholeMsgMultisigTx( await createWormholeMsgMultisigTx(
options.cluster, options.cluster,
squad, squad,
options.ledger, CONFIG[cluster].vault,
new PublicKey(options.vaultAddress),
options.payload options.payload
); );
}); });
@ -71,7 +92,6 @@ program
"Create a new multisig transaction to set the attester is-active flag" "Create a new multisig transaction to set the attester is-active flag"
) )
.option("-c, --cluster <network>", "solana cluster to use", "devnet") .option("-c, --cluster <network>", "solana cluster to use", "devnet")
.requiredOption("-v, --vault-address <address>", "multisig vault address")
.option("-l, --ledger", "use ledger") .option("-l, --ledger", "use ledger")
.option( .option(
"-lda, --ledger-derivation-account <number>", "-lda, --ledger-derivation-account <number>",
@ -93,16 +113,16 @@ program
"true" "true"
) )
.action(async (options) => { .action(async (options) => {
const cluster = options.cluster as Cluster;
const squad = await getSquadsClient( const squad = await getSquadsClient(
options.cluster, cluster,
options.ledger, options.ledger,
options.ledgerDerivationAccount, options.ledgerDerivationAccount,
options.ledgerDerivationChange, options.ledgerDerivationChange,
options.wallet options.wallet
); );
const msAccount = await squad.getMultisig( const vaultPubkey = CONFIG[cluster].vault;
new PublicKey(options.vaultAddress) const msAccount = await squad.getMultisig(vaultPubkey);
);
const vaultAuthority = squad.getAuthorityPDA( const vaultAuthority = squad.getAuthorityPDA(
msAccount.publicKey, msAccount.publicKey,
@ -111,8 +131,7 @@ program
const attesterProgramId = new PublicKey(options.attester); const attesterProgramId = new PublicKey(options.attester);
const txKey = await createTx( const txKey = await createTx(
squad, squad,
options.ledger, vaultPubkey
new PublicKey(options.vaultAddress)
); );
let isActive = undefined; let isActive = undefined;
@ -139,7 +158,6 @@ program
await addInstructionsToTx( await addInstructionsToTx(
options.cluster, options.cluster,
squad, squad,
options.ledger,
msAccount.publicKey, msAccount.publicKey,
txKey, txKey,
squadIxs squadIxs
@ -150,7 +168,6 @@ program
.command("execute") .command("execute")
.description("Execute a multisig transaction that is ready") .description("Execute a multisig transaction that is ready")
.option("-c, --cluster <network>", "solana cluster to use", "devnet") .option("-c, --cluster <network>", "solana cluster to use", "devnet")
.requiredOption("-v, --vault-address <address>", "multisig vault address")
.option("-l, --ledger", "use ledger") .option("-l, --ledger", "use ledger")
.option( .option(
"-lda, --ledger-derivation-account <number>", "-lda, --ledger-derivation-account <number>",
@ -166,17 +183,21 @@ program
"keys/key.json" "keys/key.json"
) )
.requiredOption("-t, --tx-pda <address>", "transaction PDA") .requiredOption("-t, --tx-pda <address>", "transaction PDA")
.requiredOption("-u, --rpc-url <url>", "wormhole RPC URL") .action(async (options) => {
.action((options) => { const cluster: Cluster = options.cluster;
executeMultisigTx( const squad = await getSquadsClient(
options.cluster, cluster,
new PublicKey(options.vaultAddress),
options.ledger, options.ledger,
options.ledgerDerivationAccount, options.ledgerDerivationAccount,
options.ledgerDerivationChange, options.ledgerDerivationChange,
options.wallet, options.wallet
);
executeMultisigTx(
cluster,
squad,
CONFIG[cluster].vault,
new PublicKey(options.txPda), new PublicKey(options.txPda),
options.rpcUrl CONFIG[cluster].wormholeRpcEndpoint
); );
}); });
@ -184,7 +205,6 @@ program
.command("change-threshold") .command("change-threshold")
.description("Change threshold of multisig") .description("Change threshold of multisig")
.option("-c, --cluster <network>", "solana cluster to use", "devnet") .option("-c, --cluster <network>", "solana cluster to use", "devnet")
.requiredOption("-v, --vault-address <address>", "multisig vault address")
.option("-l, --ledger", "use ledger") .option("-l, --ledger", "use ledger")
.option( .option(
"-lda, --ledger-derivation-account <number>", "-lda, --ledger-derivation-account <number>",
@ -201,8 +221,9 @@ program
) )
.option("-t, --threshold <number>", "new threshold") .option("-t, --threshold <number>", "new threshold")
.action(async (options) => { .action(async (options) => {
const cluster: Cluster = options.cluster;
const squad = await getSquadsClient( const squad = await getSquadsClient(
options.cluster, cluster,
options.ledger, options.ledger,
options.ledgerDerivationAccount, options.ledgerDerivationAccount,
options.ledgerDerivationChange, options.ledgerDerivationChange,
@ -211,8 +232,7 @@ program
await changeThreshold( await changeThreshold(
options.cluster, options.cluster,
squad, squad,
options.ledger, CONFIG[cluster].vault,
new PublicKey(options.vaultAddress),
options.threshold options.threshold
); );
}); });
@ -221,7 +241,6 @@ program
.command("add-member") .command("add-member")
.description("Add member to multisig") .description("Add member to multisig")
.option("-c, --cluster <network>", "solana cluster to use", "devnet") .option("-c, --cluster <network>", "solana cluster to use", "devnet")
.requiredOption("-v, --vault-address <address>", "multisig vault address")
.option("-l, --ledger", "use ledger") .option("-l, --ledger", "use ledger")
.option( .option(
"-lda, --ledger-derivation-account <number>", "-lda, --ledger-derivation-account <number>",
@ -238,8 +257,9 @@ program
) )
.option("-m, --member <address>", "new member address") .option("-m, --member <address>", "new member address")
.action(async (options) => { .action(async (options) => {
const cluster: Cluster = options.cluster;
const squad = await getSquadsClient( const squad = await getSquadsClient(
options.cluster, cluster,
options.ledger, options.ledger,
options.ledgerDerivationAccount, options.ledgerDerivationAccount,
options.ledgerDerivationChange, options.ledgerDerivationChange,
@ -248,8 +268,7 @@ program
await addMember( await addMember(
options.cluster, options.cluster,
squad, squad,
options.ledger, CONFIG[cluster].vault,
new PublicKey(options.vaultAddress),
new PublicKey(options.member) new PublicKey(options.member)
); );
}); });
@ -258,7 +277,6 @@ program
.command("remove-member") .command("remove-member")
.description("Remove member from multisig") .description("Remove member from multisig")
.option("-c, --cluster <network>", "solana cluster to use", "devnet") .option("-c, --cluster <network>", "solana cluster to use", "devnet")
.requiredOption("-v, --vault-address <address>", "multisig vault address")
.option("-l, --ledger", "use ledger") .option("-l, --ledger", "use ledger")
.option( .option(
"-lda, --ledger-derivation-account <number>", "-lda, --ledger-derivation-account <number>",
@ -275,8 +293,9 @@ program
) )
.option("-m, --member <address>", "old member address") .option("-m, --member <address>", "old member address")
.action(async (options) => { .action(async (options) => {
const cluster: Cluster = options.cluster;
const squad = await getSquadsClient( const squad = await getSquadsClient(
options.cluster, cluster,
options.ledger, options.ledger,
options.ledgerDerivationAccount, options.ledgerDerivationAccount,
options.ledgerDerivationChange, options.ledgerDerivationChange,
@ -285,8 +304,7 @@ program
await removeMember( await removeMember(
options.cluster, options.cluster,
squad, squad,
options.ledger, CONFIG[cluster].vault,
new PublicKey(options.vaultAddress),
new PublicKey(options.member) new PublicKey(options.member)
); );
}); });
@ -295,17 +313,6 @@ program
program.parse(); program.parse();
// custom solana cluster type
type Cluster = "devnet" | "mainnet";
type WormholeNetwork = "TESTNET" | "MAINNET";
// solana cluster mapping to wormhole cluster
const solanaClusterMappingToWormholeNetwork: Record<Cluster, WormholeNetwork> =
{
devnet: "TESTNET",
mainnet: "MAINNET",
};
async function getSquadsClient( async function getSquadsClient(
cluster: Cluster, cluster: Cluster,
ledger: boolean, ledger: boolean,
@ -336,15 +343,11 @@ async function getSquadsClient(
async function createTx( async function createTx(
squad: Squads, squad: Squads,
ledger: boolean,
vault: PublicKey vault: PublicKey
): Promise<PublicKey> { ): Promise<PublicKey> {
const msAccount = await squad.getMultisig(vault); const msAccount = await squad.getMultisig(vault);
console.log("Creating new transaction..."); console.log("Creating new transaction...");
if (ledger) {
console.log("Please approve the transaction on your ledger device...");
}
const newTx = await squad.createTransaction( const newTx = await squad.createTransaction(
msAccount.publicKey, msAccount.publicKey,
msAccount.authorityIndex msAccount.authorityIndex
@ -365,7 +368,6 @@ type SquadInstruction = {
async function addInstructionsToTx( async function addInstructionsToTx(
cluster: Cluster, cluster: Cluster,
squad: Squads, squad: Squads,
ledger: boolean,
vault: PublicKey, vault: PublicKey,
txKey: PublicKey, txKey: PublicKey,
instructions: SquadInstruction[] instructions: SquadInstruction[]
@ -374,9 +376,6 @@ async function addInstructionsToTx(
console.log( console.log(
`Adding instruction ${i + 1}/${instructions.length} to transaction...` `Adding instruction ${i + 1}/${instructions.length} to transaction...`
); );
if (ledger) {
console.log("Please approve the transaction on your ledger device...");
}
await squad.addInstruction( await squad.addInstruction(
txKey, txKey,
instructions[i].instruction, instructions[i].instruction,
@ -387,13 +386,9 @@ async function addInstructionsToTx(
} }
console.log("Activating transaction..."); console.log("Activating transaction...");
if (ledger)
console.log("Please approve the transaction on your ledger device...");
await squad.activateTransaction(txKey); await squad.activateTransaction(txKey);
console.log("Transaction created."); console.log("Transaction created.");
console.log("Approving transaction..."); console.log("Approving transaction...");
if (ledger)
console.log("Please approve the transaction on your ledger device...");
await squad.approveTransaction(txKey); await squad.approveTransaction(txKey);
console.log("Transaction approved."); console.log("Transaction approved.");
console.log( console.log(
@ -450,9 +445,9 @@ async function getWormholeMessageIx(
connection: anchor.web3.Connection, connection: anchor.web3.Connection,
payload: string payload: string
) { ) {
const wormholeNetwork: WormholeNetwork = const wormholeClusterName: WormholeNetwork =
solanaClusterMappingToWormholeNetwork[cluster]; CONFIG[cluster].wormholeClusterName;
const wormholeAddress = wormholeUtils.CONTRACTS[wormholeNetwork].solana.core; const wormholeAddress = wormholeUtils.CONTRACTS[wormholeClusterName].solana.core;
const { post_message_ix, fee_collector_address, state_address, parse_state } = const { post_message_ix, fee_collector_address, state_address, parse_state } =
await importCoreWasm(); await importCoreWasm();
const feeCollector = new PublicKey(fee_collector_address(wormholeAddress)); const feeCollector = new PublicKey(fee_collector_address(wormholeAddress));
@ -488,7 +483,6 @@ async function getWormholeMessageIx(
async function createWormholeMsgMultisigTx( async function createWormholeMsgMultisigTx(
cluster: Cluster, cluster: Cluster,
squad: Squads, squad: Squads,
ledger: boolean,
vault: PublicKey, vault: PublicKey,
payload: string payload: string
) { ) {
@ -499,7 +493,7 @@ async function createWormholeMsgMultisigTx(
); );
console.log(`Emitter Address: ${emitter.toBase58()}`); console.log(`Emitter Address: ${emitter.toBase58()}`);
const txKey = await createTx(squad, ledger, vault); const txKey = await createTx(squad, vault);
const [messagePDA, messagePdaBump] = getIxAuthorityPDA( const [messagePDA, messagePdaBump] = getIxAuthorityPDA(
txKey, txKey,
@ -531,7 +525,6 @@ async function createWormholeMsgMultisigTx(
await addInstructionsToTx( await addInstructionsToTx(
cluster, cluster,
squad, squad,
ledger,
msAccount.publicKey, msAccount.publicKey,
txKey, txKey,
squadIxs squadIxs
@ -540,33 +533,11 @@ async function createWormholeMsgMultisigTx(
async function executeMultisigTx( async function executeMultisigTx(
cluster: string, cluster: string,
squad: Squads,
vault: PublicKey, vault: PublicKey,
ledger: boolean,
ledgerDerivationAccount: number | undefined,
ledgerDerivationChange: number | undefined,
walletPath: string,
txPDA: PublicKey, txPDA: PublicKey,
rpcUrl: string rpcUrl: string
) { ) {
let wallet: LedgerNodeWallet | NodeWallet;
if (ledger) {
console.log("Please connect to ledger...");
wallet = await LedgerNodeWallet.createWallet(
ledgerDerivationAccount,
ledgerDerivationChange
);
console.log(`Ledger connected! ${wallet.publicKey.toBase58()}`);
} else {
wallet = new NodeWallet(
Keypair.fromSecretKey(
Uint8Array.from(JSON.parse(fs.readFileSync(walletPath, "ascii")))
)
);
console.log(`Loaded wallet with address: ${wallet.publicKey.toBase58()}`);
}
const squad =
cluster === "devnet" ? Squads.devnet(wallet) : Squads.mainnet(wallet);
const msAccount = await squad.getMultisig(vault); const msAccount = await squad.getMultisig(vault);
const emitter = squad.getAuthorityPDA( const emitter = squad.getAuthorityPDA(
@ -576,7 +547,7 @@ async function executeMultisigTx(
const executeIx = await squad.buildExecuteTransaction( const executeIx = await squad.buildExecuteTransaction(
txPDA, txPDA,
wallet.publicKey squad.wallet.publicKey
); );
// airdrop 0.1 SOL to emitter if on devnet // airdrop 0.1 SOL to emitter if on devnet
@ -601,17 +572,15 @@ async function executeMultisigTx(
const executeTx = new anchor.web3.Transaction({ const executeTx = new anchor.web3.Transaction({
blockhash, blockhash,
lastValidBlockHeight, lastValidBlockHeight,
feePayer: wallet.publicKey, feePayer: squad.wallet.publicKey,
}); });
const provider = new anchor.AnchorProvider(squad.connection, wallet, { const provider = new anchor.AnchorProvider(squad.connection, squad.wallet, {
commitment: "confirmed", commitment: "confirmed",
preflightCommitment: "confirmed", preflightCommitment: "confirmed",
}); });
executeTx.add(executeIx); executeTx.add(executeIx);
console.log("Sending transaction..."); console.log("Sending transaction...");
if (ledger)
console.log("Please approve the transaction on your ledger device...");
const signature = await provider.sendAndConfirm(executeTx); const signature = await provider.sendAndConfirm(executeTx);
console.log( console.log(
@ -662,12 +631,11 @@ async function executeMultisigTx(
async function changeThreshold( async function changeThreshold(
cluster: Cluster, cluster: Cluster,
squad: Squads, squad: Squads,
ledger: boolean,
vault: PublicKey, vault: PublicKey,
threshold: number threshold: number
) { ) {
const msAccount = await squad.getMultisig(vault); const msAccount = await squad.getMultisig(vault);
const txKey = await createTx(squad, ledger, vault); const txKey = await createTx(squad, vault);
const ix = await squad.buildChangeThresholdMember( const ix = await squad.buildChangeThresholdMember(
msAccount.publicKey, msAccount.publicKey,
msAccount.externalAuthority, msAccount.externalAuthority,
@ -678,7 +646,6 @@ async function changeThreshold(
await addInstructionsToTx( await addInstructionsToTx(
cluster, cluster,
squad, squad,
ledger,
msAccount.publicKey, msAccount.publicKey,
txKey, txKey,
squadIxs squadIxs
@ -688,12 +655,11 @@ async function changeThreshold(
async function addMember( async function addMember(
cluster: Cluster, cluster: Cluster,
squad: Squads, squad: Squads,
ledger: boolean,
vault: PublicKey, vault: PublicKey,
member: PublicKey member: PublicKey
) { ) {
const msAccount = await squad.getMultisig(vault); const msAccount = await squad.getMultisig(vault);
const txKey = await createTx(squad, ledger, vault); const txKey = await createTx(squad, vault);
const ix = await squad.buildAddMember( const ix = await squad.buildAddMember(
msAccount.publicKey, msAccount.publicKey,
msAccount.externalAuthority, msAccount.externalAuthority,
@ -704,7 +670,6 @@ async function addMember(
await addInstructionsToTx( await addInstructionsToTx(
cluster, cluster,
squad, squad,
ledger,
msAccount.publicKey, msAccount.publicKey,
txKey, txKey,
squadIxs squadIxs
@ -714,12 +679,11 @@ async function addMember(
async function removeMember( async function removeMember(
cluster: Cluster, cluster: Cluster,
squad: Squads, squad: Squads,
ledger: boolean,
vault: PublicKey, vault: PublicKey,
member: PublicKey member: PublicKey
) { ) {
const msAccount = await squad.getMultisig(vault); const msAccount = await squad.getMultisig(vault);
const txKey = await createTx(squad, ledger, vault); const txKey = await createTx(squad, vault);
const ix = await squad.buildRemoveMember( const ix = await squad.buildRemoveMember(
msAccount.publicKey, msAccount.publicKey,
msAccount.externalAuthority, msAccount.externalAuthority,
@ -730,7 +694,6 @@ async function removeMember(
await addInstructionsToTx( await addInstructionsToTx(
cluster, cluster,
squad, squad,
ledger,
msAccount.publicKey, msAccount.publicKey,
txKey, txKey,
squadIxs squadIxs

View File

@ -34,6 +34,7 @@ export class LedgerNodeWallet implements Wallet {
} }
async signTransaction(transaction: Transaction): Promise<Transaction> { async signTransaction(transaction: Transaction): Promise<Transaction> {
console.log("Please approve the transaction on your ledger device...");
const transport = this._transport; const transport = this._transport;
const publicKey = this.publicKey; const publicKey = this.publicKey;