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:
parent
4629f689e4
commit
eea42578b0
|
@ -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 hasn’t been able to display full contract data to you. In other words, you’re 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 hasn’t been able to display full contract data to you. In other words, you’re 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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue