From c2e30286a5c1617994c64a79043966f402ef744c Mon Sep 17 00:00:00 2001 From: zpoken <82594516+zpoken@users.noreply.github.com> Date: Tue, 11 Feb 2025 14:38:19 +0200 Subject: [PATCH 01/14] Rename solana devnet test scripts --- solana/.gitignore | 1 + solana/app/deploy/{01_init_staking.ts => 011_initConfig.ts} | 4 ++-- ..._account_lookup_table.ts => 012_initAddressLookupTable.ts} | 4 ++-- .../{03_create_airlock.ts => 013_initializeSpokeAirlock.ts} | 4 ++-- ...a_collector.ts => 014_initializeSpokeMetadataCollector.ts} | 4 ++-- ...dowLengths.ts => 015_initializeVoteWeightWindowLengths.ts} | 4 ++-- ...sage_executor.ts => 016_initializeSpokeMessageExecutor.ts} | 4 ++-- ...ubProposalMetadata.ts => 021_updateHubProposalMetadata.ts} | 4 ++-- .../{08_create_stake_account.ts => 031_createStakeAccount.ts} | 4 ++-- solana/app/deploy/{09_deposit.ts => 032_deposit.ts} | 4 ++-- solana/app/deploy/{10_withdraw.ts => 033_withdrawTokens.ts} | 4 ++-- solana/app/deploy/{11_delegate.ts => 034_delegate.ts} | 4 ++-- solana/app/deploy/{12_addProposal.ts => 041_addProposal.ts} | 4 ++-- solana/app/deploy/{14_castVote.ts => 042_castVote.ts} | 4 ++-- .../app/deploy/{10_proposalVotes.ts => 043_proposalVotes.ts} | 4 ++-- ...ProposalAccountData.ts => 044_fetchProposalAccountData.ts} | 4 ++-- solana/app/deploy/{tx_list.ts => 051_tx_list.ts} | 4 +++- solana/app/deploy/{tx_events.ts => 052_tx_events.ts} | 4 +++- solana/app/deploy/{tx_details.ts => 053_tx_details.ts} | 4 +++- solana/app/deploy/bridge-script.ts | 2 +- solana/app/deploy/{devnet.ts => devnet_consts.ts} | 0 solana/app/deploy/receive_message.ts | 2 +- solana/app/deploy/test_vesting.ts | 2 +- solana/app/deploy/transfer_W_token.ts | 2 +- solana/app/e2e/01_createProposeWithSolanaExecution.ts | 2 +- solana/app/e2e/02_addProposal.ts | 2 +- solana/app/e2e/03_castVote.ts | 2 +- solana/app/e2e/external_program/initializeConfigPDA.ts | 2 +- 28 files changed, 48 insertions(+), 41 deletions(-) rename solana/app/deploy/{01_init_staking.ts => 011_initConfig.ts} (92%) rename solana/app/deploy/{02_create_account_lookup_table.ts => 012_initAddressLookupTable.ts} (88%) rename solana/app/deploy/{03_create_airlock.ts => 013_initializeSpokeAirlock.ts} (90%) rename solana/app/deploy/{04_create_spoke_metadata_collector.ts => 014_initializeSpokeMetadataCollector.ts} (86%) rename solana/app/deploy/{05_initializeVoteWeightWindowLengths.ts => 015_initializeVoteWeightWindowLengths.ts} (84%) rename solana/app/deploy/{06_create_message_executor.ts => 016_initializeSpokeMessageExecutor.ts} (91%) rename solana/app/deploy/{07_update_HubProposalMetadata.ts => 021_updateHubProposalMetadata.ts} (89%) rename solana/app/deploy/{08_create_stake_account.ts => 031_createStakeAccount.ts} (86%) rename solana/app/deploy/{09_deposit.ts => 032_deposit.ts} (95%) rename solana/app/deploy/{10_withdraw.ts => 033_withdrawTokens.ts} (91%) rename solana/app/deploy/{11_delegate.ts => 034_delegate.ts} (95%) rename solana/app/deploy/{12_addProposal.ts => 041_addProposal.ts} (94%) rename solana/app/deploy/{14_castVote.ts => 042_castVote.ts} (90%) rename solana/app/deploy/{10_proposalVotes.ts => 043_proposalVotes.ts} (90%) rename solana/app/deploy/{13_fetchProposalAccountData.ts => 044_fetchProposalAccountData.ts} (92%) rename solana/app/deploy/{tx_list.ts => 051_tx_list.ts} (91%) rename solana/app/deploy/{tx_events.ts => 052_tx_events.ts} (92%) rename solana/app/deploy/{tx_details.ts => 053_tx_details.ts} (90%) rename solana/app/deploy/{devnet.ts => devnet_consts.ts} (100%) diff --git a/solana/.gitignore b/solana/.gitignore index 562f4e35..4ddd32ff 100644 --- a/solana/.gitignore +++ b/solana/.gitignore @@ -9,3 +9,4 @@ snapshots /artifacts package-lock.json yarn.lock +/app/e2e/log/*.json diff --git a/solana/app/deploy/01_init_staking.ts b/solana/app/deploy/011_initConfig.ts similarity index 92% rename from solana/app/deploy/01_init_staking.ts rename to solana/app/deploy/011_initConfig.ts index 68925f76..f97db148 100644 --- a/solana/app/deploy/01_init_staking.ts +++ b/solana/app/deploy/011_initConfig.ts @@ -1,8 +1,8 @@ -// Usage: npx ts-node app/deploy/01_init_staking.ts +// Usage: npx ts-node app/deploy/011_initConfig.ts import { Wallet, AnchorProvider, Program } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; -import { DEPLOYER_AUTHORITY_KEYPAIR, WORMHOLE_TOKEN, RPC_NODE } from "./devnet"; +import { DEPLOYER_AUTHORITY_KEYPAIR, WORMHOLE_TOKEN, RPC_NODE } from "./devnet_consts"; import { CHECKPOINTS_ACCOUNT_LIMIT, STAKING_ADDRESS } from "../constants"; import { Staking } from "../../target/types/staking"; import fs from "fs"; diff --git a/solana/app/deploy/02_create_account_lookup_table.ts b/solana/app/deploy/012_initAddressLookupTable.ts similarity index 88% rename from solana/app/deploy/02_create_account_lookup_table.ts rename to solana/app/deploy/012_initAddressLookupTable.ts index 3f2603e0..c89991d3 100644 --- a/solana/app/deploy/02_create_account_lookup_table.ts +++ b/solana/app/deploy/012_initAddressLookupTable.ts @@ -1,8 +1,8 @@ -// Usage: npx ts-node app/deploy/02_create_account_lookup_table.ts +// Usage: npx ts-node app/deploy/012_initAddressLookupTable.ts import { Wallet, AnchorProvider } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; -import { DEPLOYER_AUTHORITY_KEYPAIR, WORMHOLE_TOKEN, RPC_NODE } from "./devnet"; +import { DEPLOYER_AUTHORITY_KEYPAIR, WORMHOLE_TOKEN, RPC_NODE } from "./devnet_consts"; import { initAddressLookupTable } from "../../tests/utils/utils"; async function main() { diff --git a/solana/app/deploy/03_create_airlock.ts b/solana/app/deploy/013_initializeSpokeAirlock.ts similarity index 90% rename from solana/app/deploy/03_create_airlock.ts rename to solana/app/deploy/013_initializeSpokeAirlock.ts index bac7784c..57fe1d31 100644 --- a/solana/app/deploy/03_create_airlock.ts +++ b/solana/app/deploy/013_initializeSpokeAirlock.ts @@ -1,9 +1,9 @@ -// Usage: npx ts-node app/deploy/03_create_airlock.ts +// Usage: npx ts-node app/deploy/013_initializeSpokeAirlock.ts import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; import { Connection, PublicKey, SystemProgram } from "@solana/web3.js"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet"; +import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; import { Staking } from "../../target/types/staking"; import fs from "fs"; diff --git a/solana/app/deploy/04_create_spoke_metadata_collector.ts b/solana/app/deploy/014_initializeSpokeMetadataCollector.ts similarity index 86% rename from solana/app/deploy/04_create_spoke_metadata_collector.ts rename to solana/app/deploy/014_initializeSpokeMetadataCollector.ts index c6dae61a..7dc78e3d 100644 --- a/solana/app/deploy/04_create_spoke_metadata_collector.ts +++ b/solana/app/deploy/014_initializeSpokeMetadataCollector.ts @@ -1,10 +1,10 @@ -// Usage: npx ts-node app/deploy/04_create_spoke_metadata_collector.ts +// Usage: npx ts-node app/deploy/014_initializeSpokeMetadataCollector.ts import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; import { HUB_CHAIN_ID, hubProposalMetadataUint8Array } from "../constants"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet"; +import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; import { Staking } from "../../target/types/staking"; import fs from "fs"; diff --git a/solana/app/deploy/05_initializeVoteWeightWindowLengths.ts b/solana/app/deploy/015_initializeVoteWeightWindowLengths.ts similarity index 84% rename from solana/app/deploy/05_initializeVoteWeightWindowLengths.ts rename to solana/app/deploy/015_initializeVoteWeightWindowLengths.ts index cc7c1f28..033393e7 100644 --- a/solana/app/deploy/05_initializeVoteWeightWindowLengths.ts +++ b/solana/app/deploy/015_initializeVoteWeightWindowLengths.ts @@ -1,9 +1,9 @@ -// Usage: npx ts-node app/deploy/05_initializeVoteWeightWindowLengths.ts +// Usage: npx ts-node app/deploy/015_initializeVoteWeightWindowLengths.ts import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet"; +import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; import { Staking } from "../../target/types/staking"; import fs from "fs"; import BN from "bn.js"; diff --git a/solana/app/deploy/06_create_message_executor.ts b/solana/app/deploy/016_initializeSpokeMessageExecutor.ts similarity index 91% rename from solana/app/deploy/06_create_message_executor.ts rename to solana/app/deploy/016_initializeSpokeMessageExecutor.ts index b5f970cf..0a9faacf 100644 --- a/solana/app/deploy/06_create_message_executor.ts +++ b/solana/app/deploy/016_initializeSpokeMessageExecutor.ts @@ -1,4 +1,4 @@ -// Usage: npx ts-node app/deploy/06_create_message_executor.ts +// Usage: npx ts-node app/deploy/016_initializeSpokeMessageExecutor.ts import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; @@ -7,7 +7,7 @@ import { hubSolanaMessageDispatcherPublicKey, HUB_CHAIN_ID, } from "../constants"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet"; +import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; import { Staking } from "../../target/types/staking"; import fs from "fs"; import { wasm } from "../StakeConnection"; diff --git a/solana/app/deploy/07_update_HubProposalMetadata.ts b/solana/app/deploy/021_updateHubProposalMetadata.ts similarity index 89% rename from solana/app/deploy/07_update_HubProposalMetadata.ts rename to solana/app/deploy/021_updateHubProposalMetadata.ts index b12a5878..2ba25191 100644 --- a/solana/app/deploy/07_update_HubProposalMetadata.ts +++ b/solana/app/deploy/021_updateHubProposalMetadata.ts @@ -1,10 +1,10 @@ -// Usage: npx ts-node app/deploy/07_update_HubProposalMetadata.ts +// Usage: npx ts-node app/deploy/021_updateHubProposalMetadata.ts import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; import { Connection, PublicKey, SystemProgram } from "@solana/web3.js"; import { hubProposalMetadataUint8Array } from "../constants"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet"; +import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; import { Staking } from "../../target/types/staking"; import fs from "fs"; diff --git a/solana/app/deploy/08_create_stake_account.ts b/solana/app/deploy/031_createStakeAccount.ts similarity index 86% rename from solana/app/deploy/08_create_stake_account.ts rename to solana/app/deploy/031_createStakeAccount.ts index b648933f..8e84e00d 100644 --- a/solana/app/deploy/08_create_stake_account.ts +++ b/solana/app/deploy/031_createStakeAccount.ts @@ -1,4 +1,4 @@ -// Usage: npx ts-node app/deploy/08_create_stake_account.ts +// Usage: npx ts-node app/deploy/031_createStakeAccount.ts import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; @@ -6,7 +6,7 @@ import { Connection } from "@solana/web3.js"; import * as wasm from "@wormhole/staking-wasm"; import { StakeConnection } from "../StakeConnection"; import { STAKING_ADDRESS } from "../constants"; -import { USER2_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet"; +import { USER2_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; import { Staking } from "../../target/types/staking"; async function main() { diff --git a/solana/app/deploy/09_deposit.ts b/solana/app/deploy/032_deposit.ts similarity index 95% rename from solana/app/deploy/09_deposit.ts rename to solana/app/deploy/032_deposit.ts index ed06b5ce..0dc90faf 100644 --- a/solana/app/deploy/09_deposit.ts +++ b/solana/app/deploy/032_deposit.ts @@ -1,4 +1,4 @@ -// Usage: npx ts-node app/deploy/09_deposit.ts +// Usage: npx ts-node app/deploy/032_deposit.ts import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; @@ -9,7 +9,7 @@ import { import { PublicKey, Transaction, Connection } from "@solana/web3.js"; import * as wasm from "@wormhole/staking-wasm"; import { STAKING_ADDRESS } from "../constants"; -import { USER_AUTHORITY_KEYPAIR, WORMHOLE_TOKEN, RPC_NODE } from "./devnet"; +import { USER_AUTHORITY_KEYPAIR, WORMHOLE_TOKEN, RPC_NODE } from "./devnet_consts"; async function main() { try { diff --git a/solana/app/deploy/10_withdraw.ts b/solana/app/deploy/033_withdrawTokens.ts similarity index 91% rename from solana/app/deploy/10_withdraw.ts rename to solana/app/deploy/033_withdrawTokens.ts index 564565bb..7b8a37d8 100644 --- a/solana/app/deploy/10_withdraw.ts +++ b/solana/app/deploy/033_withdrawTokens.ts @@ -1,4 +1,4 @@ -// Usage: npx ts-node app/deploy/10_withdraw.ts +// Usage: npx ts-node app/deploy/033_withdrawTokens.ts import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; @@ -6,7 +6,7 @@ import { Connection } from "@solana/web3.js"; import { StakeConnection } from "../StakeConnection"; import { WHTokenBalance } from "../whTokenBalance"; import { STAKING_ADDRESS } from "../constants"; -import { USER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet"; +import { USER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; async function main() { try { diff --git a/solana/app/deploy/11_delegate.ts b/solana/app/deploy/034_delegate.ts similarity index 95% rename from solana/app/deploy/11_delegate.ts rename to solana/app/deploy/034_delegate.ts index 7ebaf612..54ab2bf5 100644 --- a/solana/app/deploy/11_delegate.ts +++ b/solana/app/deploy/034_delegate.ts @@ -1,4 +1,4 @@ -// Usage: npx ts-node app/deploy/11_delegate.ts +// Usage: npx ts-node app/deploy/034_delegate.ts import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; @@ -10,7 +10,7 @@ import { USER_AUTHORITY_KEYPAIR, USER2_AUTHORITY_KEYPAIR, RPC_NODE, -} from "./devnet"; +} from "./devnet_consts"; function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); diff --git a/solana/app/deploy/12_addProposal.ts b/solana/app/deploy/041_addProposal.ts similarity index 94% rename from solana/app/deploy/12_addProposal.ts rename to solana/app/deploy/041_addProposal.ts index 1abf636d..1b2155d7 100644 --- a/solana/app/deploy/12_addProposal.ts +++ b/solana/app/deploy/041_addProposal.ts @@ -1,11 +1,11 @@ -// Usage: npx ts-node app/deploy/12_addProposal.ts +// Usage: npx ts-node app/deploy/041_addProposal.ts import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; import { Connection, Keypair } from "@solana/web3.js"; import { StakeConnection } from "../StakeConnection"; import { STAKING_ADDRESS, CORE_BRIDGE_ADDRESS } from "../constants"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet"; +import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; import { getWormholeBridgeData } from "../helpers/wormholeBridgeConfig"; async function main() { diff --git a/solana/app/deploy/14_castVote.ts b/solana/app/deploy/042_castVote.ts similarity index 90% rename from solana/app/deploy/14_castVote.ts rename to solana/app/deploy/042_castVote.ts index 2a190372..29ffb9f6 100644 --- a/solana/app/deploy/14_castVote.ts +++ b/solana/app/deploy/042_castVote.ts @@ -1,11 +1,11 @@ -// Usage: npx ts-node app/deploy/14_castVote.ts +// Usage: npx ts-node app/deploy/042_castVote.ts import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; import { StakeConnection } from "../StakeConnection"; import { STAKING_ADDRESS } from "../constants"; -import { USER2_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet"; +import { USER2_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; import BN from "bn.js"; import input from "@inquirer/input"; diff --git a/solana/app/deploy/10_proposalVotes.ts b/solana/app/deploy/043_proposalVotes.ts similarity index 90% rename from solana/app/deploy/10_proposalVotes.ts rename to solana/app/deploy/043_proposalVotes.ts index 0fef765b..dd1e1d4d 100644 --- a/solana/app/deploy/10_proposalVotes.ts +++ b/solana/app/deploy/043_proposalVotes.ts @@ -1,11 +1,11 @@ -// Usage: npx ts-node app/deploy/10_proposalVotes.ts +// Usage: npx ts-node app/deploy/043_proposalVotes.ts import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; import { StakeConnection } from "../StakeConnection"; import { STAKING_ADDRESS } from "../constants"; -import { USER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet"; +import { USER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; async function main() { try { diff --git a/solana/app/deploy/13_fetchProposalAccountData.ts b/solana/app/deploy/044_fetchProposalAccountData.ts similarity index 92% rename from solana/app/deploy/13_fetchProposalAccountData.ts rename to solana/app/deploy/044_fetchProposalAccountData.ts index caae7876..b07f7e5c 100644 --- a/solana/app/deploy/13_fetchProposalAccountData.ts +++ b/solana/app/deploy/044_fetchProposalAccountData.ts @@ -1,11 +1,11 @@ -// Usage: npx ts-node app/deploy/13_fetchProposalAccountData.ts +// Usage: npx ts-node app/deploy/044_fetchProposalAccountData.ts import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; import { StakeConnection } from "../StakeConnection"; import { STAKING_ADDRESS } from "../constants"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet"; +import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; import BN from "bn.js"; import { ethers } from "ethers"; diff --git a/solana/app/deploy/tx_list.ts b/solana/app/deploy/051_tx_list.ts similarity index 91% rename from solana/app/deploy/tx_list.ts rename to solana/app/deploy/051_tx_list.ts index 6605a3a8..d0fa9f6b 100644 --- a/solana/app/deploy/tx_list.ts +++ b/solana/app/deploy/051_tx_list.ts @@ -1,5 +1,7 @@ +// Usage: npx ts-node app/deploy/051_tx_list.ts + import { Connection } from "@solana/web3.js"; -import { RPC_NODE } from "./devnet"; +import { RPC_NODE } from "./devnet_consts"; import { getProgramTransactions } from "../utils/parse_transactions"; async function main() { diff --git a/solana/app/deploy/tx_events.ts b/solana/app/deploy/052_tx_events.ts similarity index 92% rename from solana/app/deploy/tx_events.ts rename to solana/app/deploy/052_tx_events.ts index 3bab75dc..833915d1 100644 --- a/solana/app/deploy/tx_events.ts +++ b/solana/app/deploy/052_tx_events.ts @@ -1,5 +1,7 @@ +// Usage: npx ts-node app/deploy/052_tx_events.ts + import { Connection } from "@solana/web3.js"; -import { RPC_NODE } from "./devnet"; +import { RPC_NODE } from "./devnet_consts"; import { getProgramTransactions, printTransactionEvents, diff --git a/solana/app/deploy/tx_details.ts b/solana/app/deploy/053_tx_details.ts similarity index 90% rename from solana/app/deploy/tx_details.ts rename to solana/app/deploy/053_tx_details.ts index 7e2c6614..97b1cfdb 100644 --- a/solana/app/deploy/tx_details.ts +++ b/solana/app/deploy/053_tx_details.ts @@ -1,5 +1,7 @@ +// Usage: npx ts-node app/deploy/053_tx_details.ts + import { Connection } from "@solana/web3.js"; -import { RPC_NODE } from "./devnet"; +import { RPC_NODE } from "./devnet_consts"; import { getProgramTransactions, printTransactionDetails, diff --git a/solana/app/deploy/bridge-script.ts b/solana/app/deploy/bridge-script.ts index 8dcd7829..074c3606 100644 --- a/solana/app/deploy/bridge-script.ts +++ b/solana/app/deploy/bridge-script.ts @@ -23,7 +23,7 @@ import { HUB_CHAIN_ID, HUB_PROPOSAL_METADATA_ADDRESS, } from "../constants"; -import { RPC_NODE } from "./devnet"; +import { RPC_NODE } from "./devnet_consts"; import { getWormholeBridgeData } from "../helpers/wormholeBridgeConfig"; import { deriveGuardianSetKey } from "../helpers/guardianSet"; diff --git a/solana/app/deploy/devnet.ts b/solana/app/deploy/devnet_consts.ts similarity index 100% rename from solana/app/deploy/devnet.ts rename to solana/app/deploy/devnet_consts.ts diff --git a/solana/app/deploy/receive_message.ts b/solana/app/deploy/receive_message.ts index b30c37f1..0c01c23b 100644 --- a/solana/app/deploy/receive_message.ts +++ b/solana/app/deploy/receive_message.ts @@ -6,7 +6,7 @@ import { PublicKey, SystemProgram, } from "@solana/web3.js"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet"; +import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; import { Staking } from "../../target/types/staking"; import fs from "fs"; import BN from "bn.js"; diff --git a/solana/app/deploy/test_vesting.ts b/solana/app/deploy/test_vesting.ts index 9e99cba3..983fb5f6 100644 --- a/solana/app/deploy/test_vesting.ts +++ b/solana/app/deploy/test_vesting.ts @@ -10,7 +10,7 @@ import { USER_AUTHORITY_KEYPAIR, WORMHOLE_TOKEN, RPC_NODE, -} from "./devnet"; +} from "./devnet_consts"; import { STAKING_ADDRESS } from "../constants"; import { StakeConnection } from "../StakeConnection"; import { WHTokenBalance } from "../whTokenBalance"; diff --git a/solana/app/deploy/transfer_W_token.ts b/solana/app/deploy/transfer_W_token.ts index 1412d3b7..ea588a9f 100644 --- a/solana/app/deploy/transfer_W_token.ts +++ b/solana/app/deploy/transfer_W_token.ts @@ -7,7 +7,7 @@ import { USER2_AUTHORITY_KEYPAIR, WORMHOLE_TOKEN, RPC_NODE, -} from "./devnet"; +} from "./devnet_consts"; import { createTransferInstruction, getAssociatedTokenAddressSync, diff --git a/solana/app/e2e/01_createProposeWithSolanaExecution.ts b/solana/app/e2e/01_createProposeWithSolanaExecution.ts index c882d7cd..65cbe3a4 100644 --- a/solana/app/e2e/01_createProposeWithSolanaExecution.ts +++ b/solana/app/e2e/01_createProposeWithSolanaExecution.ts @@ -16,7 +16,7 @@ import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE, AIRLOCK_PDA_ADDRESS, -} from "../deploy/devnet"; +} from "../deploy/devnet_consts"; import { v4 as uuidv4 } from "uuid"; // Define the ABI types diff --git a/solana/app/e2e/02_addProposal.ts b/solana/app/e2e/02_addProposal.ts index 02cc1712..20ce2105 100644 --- a/solana/app/e2e/02_addProposal.ts +++ b/solana/app/e2e/02_addProposal.ts @@ -21,7 +21,7 @@ import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; import { Connection, Keypair } from "@solana/web3.js"; import { StakeConnection } from "../StakeConnection"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "../deploy/devnet"; +import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "../deploy/devnet_consts"; import { getWormholeBridgeData } from "../helpers/wormholeBridgeConfig"; import * as fs from "fs"; diff --git a/solana/app/e2e/03_castVote.ts b/solana/app/e2e/03_castVote.ts index 16b6067f..54ee550f 100644 --- a/solana/app/e2e/03_castVote.ts +++ b/solana/app/e2e/03_castVote.ts @@ -5,7 +5,7 @@ import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; import { StakeConnection } from "../StakeConnection"; import { STAKING_ADDRESS } from "../constants"; -import { USER2_AUTHORITY_KEYPAIR, RPC_NODE } from "../deploy/devnet"; +import { USER2_AUTHORITY_KEYPAIR, RPC_NODE } from "../deploy/devnet_consts"; import BN from "bn.js"; import { WHTokenBalance } from "../whTokenBalance"; import input from "@inquirer/input"; diff --git a/solana/app/e2e/external_program/initializeConfigPDA.ts b/solana/app/e2e/external_program/initializeConfigPDA.ts index 4bd15452..4cf48cf9 100644 --- a/solana/app/e2e/external_program/initializeConfigPDA.ts +++ b/solana/app/e2e/external_program/initializeConfigPDA.ts @@ -5,7 +5,7 @@ import { USER2_AUTHORITY_KEYPAIR, RPC_NODE, AIRLOCK_PDA_ADDRESS, -} from "../../deploy/devnet"; +} from "../../deploy/devnet_consts"; import { ExternalProgram } from "./idl/external_program"; import externalProgramIdl from "./idl/external_program.json"; From a5c31115cf4d607b400b46364449961a3cb84420 Mon Sep 17 00:00:00 2001 From: zpoken <82594516+zpoken@users.noreply.github.com> Date: Tue, 11 Feb 2025 17:58:08 +0200 Subject: [PATCH 02/14] Update Program ID --- solana/Anchor.toml | 4 ++-- solana/app/constants.ts | 2 +- solana/app/deploy/051_tx_list.ts | 2 +- solana/app/deploy/052_tx_events.ts | 2 +- solana/app/deploy/053_tx_details.ts | 2 +- solana/programs/staking/src/lib.rs | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/solana/Anchor.toml b/solana/Anchor.toml index 9cd77a2f..4d26d210 100644 --- a/solana/Anchor.toml +++ b/solana/Anchor.toml @@ -7,10 +7,10 @@ seeds = true members = ["programs/staking"] [programs.localnet] -staking = "DgCSKsLDXXufYeEkvf21YSX5DMnFK89xans5WdSsUbeY" +staking = "AFuHPdrQGsW8rNQ4oEFF35sm5fg36gwrxyqjkjKvi6ap" [programs.devnet] -staking = "DgCSKsLDXXufYeEkvf21YSX5DMnFK89xans5WdSsUbeY" +staking = "AFuHPdrQGsW8rNQ4oEFF35sm5fg36gwrxyqjkjKvi6ap" external_program = "eLUV8cwhgUC2Bcu4UA16uhuMwK8zPkx3XSzt4hd3JJ3" [registry] diff --git a/solana/app/constants.ts b/solana/app/constants.ts index 5b21423b..af84b7f7 100644 --- a/solana/app/constants.ts +++ b/solana/app/constants.ts @@ -1,7 +1,7 @@ import { PublicKey } from "@solana/web3.js"; export const STAKING_ADDRESS = new PublicKey( - "DgCSKsLDXXufYeEkvf21YSX5DMnFK89xans5WdSsUbeY", + "AFuHPdrQGsW8rNQ4oEFF35sm5fg36gwrxyqjkjKvi6ap", ); export const CORE_BRIDGE_ADDRESS = new PublicKey( diff --git a/solana/app/deploy/051_tx_list.ts b/solana/app/deploy/051_tx_list.ts index d0fa9f6b..232131c3 100644 --- a/solana/app/deploy/051_tx_list.ts +++ b/solana/app/deploy/051_tx_list.ts @@ -6,7 +6,7 @@ import { getProgramTransactions } from "../utils/parse_transactions"; async function main() { const connection = new Connection(RPC_NODE, "confirmed"); - const programId = "DgCSKsLDXXufYeEkvf21YSX5DMnFK89xans5WdSsUbeY"; + const programId = "AFuHPdrQGsW8rNQ4oEFF35sm5fg36gwrxyqjkjKvi6ap"; const limit = 15; getProgramTransactions(connection, programId, limit) diff --git a/solana/app/deploy/052_tx_events.ts b/solana/app/deploy/052_tx_events.ts index 833915d1..3b92571d 100644 --- a/solana/app/deploy/052_tx_events.ts +++ b/solana/app/deploy/052_tx_events.ts @@ -12,7 +12,7 @@ async function main() { // const transactionSignature = '3er1rCAdfVkKjmyURX4HJJxqFsY4EjnCdyC3M4NCqMb4RErKh7USgacYQAsb42W6Syf9Dx1hn4kk3wzSPQrcGpsw'; // await printTransactionEvents(connection, transactionSignature); - const programId = "DgCSKsLDXXufYeEkvf21YSX5DMnFK89xans5WdSsUbeY"; + const programId = "AFuHPdrQGsW8rNQ4oEFF35sm5fg36gwrxyqjkjKvi6ap"; const limit = 3; try { diff --git a/solana/app/deploy/053_tx_details.ts b/solana/app/deploy/053_tx_details.ts index 97b1cfdb..1630e3f1 100644 --- a/solana/app/deploy/053_tx_details.ts +++ b/solana/app/deploy/053_tx_details.ts @@ -9,7 +9,7 @@ import { async function main() { const connection = new Connection(RPC_NODE, "confirmed"); - const programId = "DgCSKsLDXXufYeEkvf21YSX5DMnFK89xans5WdSsUbeY"; + const programId = "AFuHPdrQGsW8rNQ4oEFF35sm5fg36gwrxyqjkjKvi6ap"; const limit = 2; try { diff --git a/solana/programs/staking/src/lib.rs b/solana/programs/staking/src/lib.rs index 86acb09a..d05dfa43 100644 --- a/solana/programs/staking/src/lib.rs +++ b/solana/programs/staking/src/lib.rs @@ -75,7 +75,7 @@ pub struct ProposalCreated { pub vote_start: u64, } -declare_id!("DgCSKsLDXXufYeEkvf21YSX5DMnFK89xans5WdSsUbeY"); +declare_id!("AFuHPdrQGsW8rNQ4oEFF35sm5fg36gwrxyqjkjKvi6ap"); #[program] pub mod staking { /// Creates a global config for the program From 19c61e5fd30ba1540fccc49caf796ea341004cba Mon Sep 17 00:00:00 2001 From: zpoken <82594516+zpoken@users.noreply.github.com> Date: Wed, 12 Feb 2025 13:19:30 +0200 Subject: [PATCH 03/14] Add GovernanceAuthority update script --- .../deploy/022_updateGovernanceAuthority.ts | 46 +++++++++++++++++++ solana/app/deploy/devnet_consts.ts | 5 ++ 2 files changed, 51 insertions(+) create mode 100644 solana/app/deploy/022_updateGovernanceAuthority.ts diff --git a/solana/app/deploy/022_updateGovernanceAuthority.ts b/solana/app/deploy/022_updateGovernanceAuthority.ts new file mode 100644 index 00000000..808e59a8 --- /dev/null +++ b/solana/app/deploy/022_updateGovernanceAuthority.ts @@ -0,0 +1,46 @@ +// Usage: npx ts-node app/deploy/022_updateGovernanceAuthority.ts + +import * as anchor from "@coral-xyz/anchor"; +import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; +import { Connection } from "@solana/web3.js"; +import { DEPLOYER_AUTHORITY_KEYPAIR, GOVERNANCE_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; +import { Staking } from "../../target/types/staking"; +import fs from "fs"; + +async function main() { + try { + const DEBUG = true; + const connection = new Connection(RPC_NODE); + const provider = new AnchorProvider( + connection, + new Wallet(DEPLOYER_AUTHORITY_KEYPAIR), + {}, + ); + + let program: Program; + program = new Program( + JSON.parse(fs.readFileSync("./target/idl/staking.json").toString()), + provider, + ); + + await program.methods + .updateGovernanceAuthority() + .accounts({ + governanceSigner: DEPLOYER_AUTHORITY_KEYPAIR.publicKey, + newAuthority: GOVERNANCE_AUTHORITY_KEYPAIR.publicKey, + }) + .rpc(); + + await program.methods + .claimGovernanceAuthority() + .accounts({ + newAuthority: GOVERNANCE_AUTHORITY_KEYPAIR.publicKey, + }) + .signers([GOVERNANCE_AUTHORITY_KEYPAIR]) + .rpc(); + } catch (err) { + console.error("Error:", err); + } +} + +main(); diff --git a/solana/app/deploy/devnet_consts.ts b/solana/app/deploy/devnet_consts.ts index 6a6d4f8f..1bf7854e 100644 --- a/solana/app/deploy/devnet_consts.ts +++ b/solana/app/deploy/devnet_consts.ts @@ -7,6 +7,11 @@ export const DEPLOYER_AUTHORITY_KEYPAIR = loadKeypair( homedir() + DEPLOYER_AUTHORITY_PATH, ); +export const GOVERNANCE_AUTHORITY_PATH = "/.config/solana/governanceAuthority.json"; +export const GOVERNANCE_AUTHORITY_KEYPAIR = loadKeypair( + homedir() + GOVERNANCE_AUTHORITY_PATH, +); + export const USER_AUTHORITY_PATH = "/.config/solana/user.json"; export const USER_AUTHORITY_KEYPAIR = loadKeypair( homedir() + USER_AUTHORITY_PATH, From dff3684c7ae8b736b6b72bb0a4e848f8fb1dad9d Mon Sep 17 00:00:00 2001 From: zpoken <82594516+zpoken@users.noreply.github.com> Date: Wed, 12 Feb 2025 14:47:10 +0200 Subject: [PATCH 04/14] Add config.vesting_admin update script --- solana/app/deploy/023_updateVestingAdmin.ts | 40 +++++++++++++++++++++ solana/app/deploy/devnet_consts.ts | 5 +++ solana/app/deploy/new_wallet.ts | 7 ++-- 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 solana/app/deploy/023_updateVestingAdmin.ts diff --git a/solana/app/deploy/023_updateVestingAdmin.ts b/solana/app/deploy/023_updateVestingAdmin.ts new file mode 100644 index 00000000..0ae3a7bd --- /dev/null +++ b/solana/app/deploy/023_updateVestingAdmin.ts @@ -0,0 +1,40 @@ +// Usage: npx ts-node app/deploy/023_updateVestingAdmin.ts + +import * as anchor from "@coral-xyz/anchor"; +import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; +import { Connection } from "@solana/web3.js"; +import { DEPLOYER_AUTHORITY_KEYPAIR, VESTING_ADMIN_KEYPAIR, RPC_NODE } from "./devnet_consts"; +import { Staking } from "../../target/types/staking"; +import fs from "fs"; + +async function main() { + try { + const connection = new Connection(RPC_NODE); + const provider = new AnchorProvider( + connection, + new Wallet(DEPLOYER_AUTHORITY_KEYPAIR), + {}, + ); + + let program: Program; + program = new Program( + JSON.parse(fs.readFileSync("./target/idl/staking.json").toString()), + provider, + ); + + await program.methods + .updateVestingAdmin() + .accounts({ newVestingAdmin: VESTING_ADMIN_KEYPAIR.publicKey }) + .rpc(); + + await program.methods + .claimVestingAdmin() + .accounts({ newVestingAdmin: VESTING_ADMIN_KEYPAIR.publicKey }) + .signers([VESTING_ADMIN_KEYPAIR]) + .rpc(); + } catch (err) { + console.error("Error:", err); + } +} + +main(); diff --git a/solana/app/deploy/devnet_consts.ts b/solana/app/deploy/devnet_consts.ts index 1bf7854e..756073a7 100644 --- a/solana/app/deploy/devnet_consts.ts +++ b/solana/app/deploy/devnet_consts.ts @@ -12,6 +12,11 @@ export const GOVERNANCE_AUTHORITY_KEYPAIR = loadKeypair( homedir() + GOVERNANCE_AUTHORITY_PATH, ); +export const VESTING_ADMIN_PATH = "/.config/solana/vestingAdmin.json"; +export const VESTING_ADMIN_KEYPAIR = loadKeypair( + homedir() + VESTING_ADMIN_PATH, +); + export const USER_AUTHORITY_PATH = "/.config/solana/user.json"; export const USER_AUTHORITY_KEYPAIR = loadKeypair( homedir() + USER_AUTHORITY_PATH, diff --git a/solana/app/deploy/new_wallet.ts b/solana/app/deploy/new_wallet.ts index 288d837e..5e684d96 100644 --- a/solana/app/deploy/new_wallet.ts +++ b/solana/app/deploy/new_wallet.ts @@ -1,3 +1,5 @@ +// Usage: npx ts-node app/deploy/new_wallet.ts + import { Keypair } from '@solana/web3.js'; import fs from 'fs'; @@ -12,5 +14,6 @@ console.log('Public Key:', publicKey); console.log('Secret Key (base64):', secretKey); // Save the secret key to a file -fs.writeFileSync('app/deploy/user3.json', JSON.stringify([...newWallet.secretKey])); -console.log('Wallet saved to app/deploy/user3.json'); +const fileName = `app/keypairs/secretKey_${publicKey}.json`; +fs.writeFileSync(fileName, JSON.stringify([...newWallet.secretKey])); +console.log(`Wallet secret key saved to ${fileName}`); From ff4c7b81c90af5da654022e03da2814d4d0d693c Mon Sep 17 00:00:00 2001 From: zpoken <82594516+zpoken@users.noreply.github.com> Date: Thu, 13 Feb 2025 13:22:53 +0200 Subject: [PATCH 05/14] Add script for fetch GlobalConfig --- solana/app/deploy/011_initConfig.ts | 4 +- solana/app/deploy/017_fetchGlobalConfig.ts | 48 ++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 solana/app/deploy/017_fetchGlobalConfig.ts diff --git a/solana/app/deploy/011_initConfig.ts b/solana/app/deploy/011_initConfig.ts index f97db148..03c66076 100644 --- a/solana/app/deploy/011_initConfig.ts +++ b/solana/app/deploy/011_initConfig.ts @@ -8,9 +8,9 @@ import { Staking } from "../../target/types/staking"; import fs from "fs"; async function main() { - const client = new Connection(RPC_NODE); + const connection = new Connection(RPC_NODE); const provider = new AnchorProvider( - client, + connection, new Wallet(DEPLOYER_AUTHORITY_KEYPAIR), {}, ); diff --git a/solana/app/deploy/017_fetchGlobalConfig.ts b/solana/app/deploy/017_fetchGlobalConfig.ts new file mode 100644 index 00000000..2b6bc308 --- /dev/null +++ b/solana/app/deploy/017_fetchGlobalConfig.ts @@ -0,0 +1,48 @@ +// Usage: npx ts-node app/deploy/017_fetchGlobalConfig.ts + +import { Wallet, AnchorProvider, utils } from "@coral-xyz/anchor"; +import { Connection, PublicKey } from "@solana/web3.js"; +import * as wasm from "@wormhole/staking-wasm"; +import { + DEPLOYER_AUTHORITY_KEYPAIR, + WORMHOLE_TOKEN, + GOVERNANCE_AUTHORITY_KEYPAIR, + VESTING_ADMIN_KEYPAIR, + RPC_NODE +} from "./devnet_consts"; +import { CHECKPOINTS_ACCOUNT_LIMIT, STAKING_ADDRESS } from "../constants"; +import { StakeConnection } from "../StakeConnection"; +import fs from "fs"; + +async function main() { + const connection = new Connection(RPC_NODE); + const provider = new AnchorProvider( + connection, + new Wallet(DEPLOYER_AUTHORITY_KEYPAIR), + {}, + ); + const stakeConnection = await StakeConnection.createStakeConnection( + connection, + provider.wallet as Wallet, + STAKING_ADDRESS, + ); + + console.log("DEPLOYER_AUTHORITY_KEYPAIR.publicKey:", DEPLOYER_AUTHORITY_KEYPAIR.publicKey); + console.log("WORMHOLE_TOKEN.publicKey:", WORMHOLE_TOKEN); + console.log("GOVERNANCE_AUTHORITY_KEYPAIR.publicKey:", GOVERNANCE_AUTHORITY_KEYPAIR.publicKey); + console.log("VESTING_ADMIN_KEYPAIR.publicKey:", VESTING_ADMIN_KEYPAIR.publicKey); + console.log("CHECKPOINTS_ACCOUNT_LIMIT:", CHECKPOINTS_ACCOUNT_LIMIT); + + const [configAccount, bump] = PublicKey.findProgramAddressSync( + [utils.bytes.utf8.encode(wasm.Constants.CONFIG_SEED())], + stakeConnection.program.programId, + ); + console.log("bump:", bump); + console.log("configAccount:", configAccount); + + let configAccountData = + await stakeConnection.program.account.globalConfig.fetch(configAccount); + console.log("configAccountData:", configAccountData); +} + +main(); From 29f95f4281dc0f9802bcd1619e4efc4ec4b9be85 Mon Sep 17 00:00:00 2001 From: zpoken <82594516+zpoken@users.noreply.github.com> Date: Thu, 13 Feb 2025 14:09:16 +0200 Subject: [PATCH 06/14] Add script for fetch SpokeMetadataCollector --- .../deploy/018_fetchSpokeMetadataCollector.ts | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 solana/app/deploy/018_fetchSpokeMetadataCollector.ts diff --git a/solana/app/deploy/018_fetchSpokeMetadataCollector.ts b/solana/app/deploy/018_fetchSpokeMetadataCollector.ts new file mode 100644 index 00000000..f06b0d1a --- /dev/null +++ b/solana/app/deploy/018_fetchSpokeMetadataCollector.ts @@ -0,0 +1,41 @@ +// Usage: npx ts-node app/deploy/018_fetchSpokeMetadataCollector.ts + +import { Wallet, AnchorProvider, utils } from "@coral-xyz/anchor"; +import { Connection, PublicKey } from "@solana/web3.js"; +import * as wasm from "@wormhole/staking-wasm"; +import { + DEPLOYER_AUTHORITY_KEYPAIR, + RPC_NODE +} from "./devnet_consts"; +import { STAKING_ADDRESS, HUB_CHAIN_ID, hubProposalMetadataUint8Array } from "../constants"; +import { StakeConnection } from "../StakeConnection"; +import fs from "fs"; + +async function main() { + const connection = new Connection(RPC_NODE); + const provider = new AnchorProvider( + connection, + new Wallet(DEPLOYER_AUTHORITY_KEYPAIR), + {}, + ); + const stakeConnection = await StakeConnection.createStakeConnection( + connection, + provider.wallet as Wallet, + STAKING_ADDRESS, + ); + + console.log("HUB_CHAIN_ID:", HUB_CHAIN_ID); + console.log("hubProposalMetadataUint8Array:", hubProposalMetadataUint8Array); + + const [spokeMetadataCollector, _] = PublicKey.findProgramAddressSync( + [utils.bytes.utf8.encode(wasm.Constants.SPOKE_METADATA_COLLECTOR_SEED())], + stakeConnection.program.programId, + ); + console.log("spokeMetadataCollector:", spokeMetadataCollector); + + let spokeMetadataCollectorAccountData = + await stakeConnection.program.account.spokeMetadataCollector.fetch(spokeMetadataCollector); + console.log("spokeMetadataCollectorAccountData:", spokeMetadataCollectorAccountData); +} + +main(); From e97938742f996af1d233c4ba9f8e1d0ff1c6fb6d Mon Sep 17 00:00:00 2001 From: zpoken <82594516+zpoken@users.noreply.github.com> Date: Thu, 13 Feb 2025 17:22:04 +0200 Subject: [PATCH 07/14] Add script for fetch VoteWeightWindowLengths --- .../015_initializeVoteWeightWindowLengths.ts | 4 +- solana/app/deploy/017_fetchGlobalConfig.ts | 1 - .../deploy/018_fetchSpokeMetadataCollector.ts | 1 - .../019_fetchVoteWeightWindowLengths.ts | 53 +++++++++++++++++++ .../deploy/044_fetchProposalAccountData.ts | 1 - solana/app/deploy/devnet_consts.ts | 2 + 6 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 solana/app/deploy/019_fetchVoteWeightWindowLengths.ts diff --git a/solana/app/deploy/015_initializeVoteWeightWindowLengths.ts b/solana/app/deploy/015_initializeVoteWeightWindowLengths.ts index 033393e7..977d5f98 100644 --- a/solana/app/deploy/015_initializeVoteWeightWindowLengths.ts +++ b/solana/app/deploy/015_initializeVoteWeightWindowLengths.ts @@ -3,7 +3,7 @@ import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; +import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE, VOTE_WEIGHT_WINDOW_LENGTHS } from "./devnet_consts"; import { Staking } from "../../target/types/staking"; import fs from "fs"; import BN from "bn.js"; @@ -24,7 +24,7 @@ async function main() { provider, ); - await program.methods.initializeVoteWeightWindowLengths(new BN(10)).rpc(); + await program.methods.initializeVoteWeightWindowLengths(new BN(VOTE_WEIGHT_WINDOW_LENGTHS)).rpc(); } catch (err) { console.error("Error:", err); } diff --git a/solana/app/deploy/017_fetchGlobalConfig.ts b/solana/app/deploy/017_fetchGlobalConfig.ts index 2b6bc308..b4d0c06f 100644 --- a/solana/app/deploy/017_fetchGlobalConfig.ts +++ b/solana/app/deploy/017_fetchGlobalConfig.ts @@ -12,7 +12,6 @@ import { } from "./devnet_consts"; import { CHECKPOINTS_ACCOUNT_LIMIT, STAKING_ADDRESS } from "../constants"; import { StakeConnection } from "../StakeConnection"; -import fs from "fs"; async function main() { const connection = new Connection(RPC_NODE); diff --git a/solana/app/deploy/018_fetchSpokeMetadataCollector.ts b/solana/app/deploy/018_fetchSpokeMetadataCollector.ts index f06b0d1a..d79d83ec 100644 --- a/solana/app/deploy/018_fetchSpokeMetadataCollector.ts +++ b/solana/app/deploy/018_fetchSpokeMetadataCollector.ts @@ -9,7 +9,6 @@ import { } from "./devnet_consts"; import { STAKING_ADDRESS, HUB_CHAIN_ID, hubProposalMetadataUint8Array } from "../constants"; import { StakeConnection } from "../StakeConnection"; -import fs from "fs"; async function main() { const connection = new Connection(RPC_NODE); diff --git a/solana/app/deploy/019_fetchVoteWeightWindowLengths.ts b/solana/app/deploy/019_fetchVoteWeightWindowLengths.ts new file mode 100644 index 00000000..525d1c48 --- /dev/null +++ b/solana/app/deploy/019_fetchVoteWeightWindowLengths.ts @@ -0,0 +1,53 @@ +// Usage: npx ts-node app/deploy/019_fetchVoteWeightWindowLengths.ts + +import { Wallet, AnchorProvider, utils } from "@coral-xyz/anchor"; +import { Connection, PublicKey } from "@solana/web3.js"; +import * as wasm from "@wormhole/staking-wasm"; +import { + DEPLOYER_AUTHORITY_KEYPAIR, + RPC_NODE, + VOTE_WEIGHT_WINDOW_LENGTHS +} from "./devnet_consts"; +import { STAKING_ADDRESS } from "../constants"; +import { StakeConnection } from "../StakeConnection"; +import { + readWindowLengths, + WindowLengthsAccount, +} from "../vote_weight_window_lengths"; + +async function main() { + const connection = new Connection(RPC_NODE); + const provider = new AnchorProvider( + connection, + new Wallet(DEPLOYER_AUTHORITY_KEYPAIR), + {}, + ); + const stakeConnection = await StakeConnection.createStakeConnection( + connection, + provider.wallet as Wallet, + STAKING_ADDRESS, + ); + + console.log("VOTE_WEIGHT_WINDOW_LENGTHS:", VOTE_WEIGHT_WINDOW_LENGTHS); + + const [voteWeightWindowLengthsAccountAddress, _] = + PublicKey.findProgramAddressSync( + [ + utils.bytes.utf8.encode( + wasm.Constants.VOTE_WEIGHT_WINDOW_LENGTHS_SEED(), + ), + ], + stakeConnection.program.programId, + ); + console.log("voteWeightWindowLengthsAccountAddress:", voteWeightWindowLengthsAccountAddress); + + let windowLengthsAccount: WindowLengthsAccount = await readWindowLengths( + connection, + voteWeightWindowLengthsAccountAddress, + ); + console.log("windowLengthsAccount.getWindowLengthCount():", windowLengthsAccount.getWindowLengthCount()); + console.log("windowLengthsAccount.voteWeightWindowLengths.nextIndex:", windowLengthsAccount.voteWeightWindowLengths.nextIndex); + console.log("windowLengthsAccount.getLastWindowLength().value.toString():", windowLengthsAccount.getLastWindowLength().value.toString()); +} + +main(); diff --git a/solana/app/deploy/044_fetchProposalAccountData.ts b/solana/app/deploy/044_fetchProposalAccountData.ts index b07f7e5c..575f9d38 100644 --- a/solana/app/deploy/044_fetchProposalAccountData.ts +++ b/solana/app/deploy/044_fetchProposalAccountData.ts @@ -6,7 +6,6 @@ import { Connection } from "@solana/web3.js"; import { StakeConnection } from "../StakeConnection"; import { STAKING_ADDRESS } from "../constants"; import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; -import BN from "bn.js"; import { ethers } from "ethers"; async function main() { diff --git a/solana/app/deploy/devnet_consts.ts b/solana/app/deploy/devnet_consts.ts index 756073a7..dd9699b3 100644 --- a/solana/app/deploy/devnet_consts.ts +++ b/solana/app/deploy/devnet_consts.ts @@ -36,3 +36,5 @@ export const RPC_NODE = "https://api.devnet.solana.com"; export const AIRLOCK_PDA_ADDRESS = new PublicKey( "2ejzW2eFPedskg1KcrjcFs9g1JorRVcMes1TBPpGbhdy", ); + +export const VOTE_WEIGHT_WINDOW_LENGTHS = 10 * 60; // 10 minutes From 71ffa8c6b8834cb343fc33b0b6fbdaf92c20b5c9 Mon Sep 17 00:00:00 2001 From: zpoken <82594516+zpoken@users.noreply.github.com> Date: Thu, 13 Feb 2025 19:52:17 +0200 Subject: [PATCH 08/14] Add script for fetch SpokeMessageExecutor --- ...obalConfig.ts => 061_fetchGlobalConfig.ts} | 2 +- ....ts => 062_fetchSpokeMetadataCollector.ts} | 2 +- ...ts => 063_fetchVoteWeightWindowLengths.ts} | 2 +- ...ata.ts => 064_fetchProposalAccountData.ts} | 2 +- .../deploy/065_fetchSpokeMessageExecutor.ts | 44 +++++++++++++++++++ solana/programs/staking/src/wasm.rs | 1 + 6 files changed, 49 insertions(+), 4 deletions(-) rename solana/app/deploy/{017_fetchGlobalConfig.ts => 061_fetchGlobalConfig.ts} (96%) rename solana/app/deploy/{018_fetchSpokeMetadataCollector.ts => 062_fetchSpokeMetadataCollector.ts} (95%) rename solana/app/deploy/{019_fetchVoteWeightWindowLengths.ts => 063_fetchVoteWeightWindowLengths.ts} (96%) rename solana/app/deploy/{044_fetchProposalAccountData.ts => 064_fetchProposalAccountData.ts} (96%) create mode 100644 solana/app/deploy/065_fetchSpokeMessageExecutor.ts diff --git a/solana/app/deploy/017_fetchGlobalConfig.ts b/solana/app/deploy/061_fetchGlobalConfig.ts similarity index 96% rename from solana/app/deploy/017_fetchGlobalConfig.ts rename to solana/app/deploy/061_fetchGlobalConfig.ts index b4d0c06f..87aac350 100644 --- a/solana/app/deploy/017_fetchGlobalConfig.ts +++ b/solana/app/deploy/061_fetchGlobalConfig.ts @@ -1,4 +1,4 @@ -// Usage: npx ts-node app/deploy/017_fetchGlobalConfig.ts +// Usage: npx ts-node app/deploy/061_fetchGlobalConfig.ts import { Wallet, AnchorProvider, utils } from "@coral-xyz/anchor"; import { Connection, PublicKey } from "@solana/web3.js"; diff --git a/solana/app/deploy/018_fetchSpokeMetadataCollector.ts b/solana/app/deploy/062_fetchSpokeMetadataCollector.ts similarity index 95% rename from solana/app/deploy/018_fetchSpokeMetadataCollector.ts rename to solana/app/deploy/062_fetchSpokeMetadataCollector.ts index d79d83ec..08ae8feb 100644 --- a/solana/app/deploy/018_fetchSpokeMetadataCollector.ts +++ b/solana/app/deploy/062_fetchSpokeMetadataCollector.ts @@ -1,4 +1,4 @@ -// Usage: npx ts-node app/deploy/018_fetchSpokeMetadataCollector.ts +// Usage: npx ts-node app/deploy/062_fetchSpokeMetadataCollector.ts import { Wallet, AnchorProvider, utils } from "@coral-xyz/anchor"; import { Connection, PublicKey } from "@solana/web3.js"; diff --git a/solana/app/deploy/019_fetchVoteWeightWindowLengths.ts b/solana/app/deploy/063_fetchVoteWeightWindowLengths.ts similarity index 96% rename from solana/app/deploy/019_fetchVoteWeightWindowLengths.ts rename to solana/app/deploy/063_fetchVoteWeightWindowLengths.ts index 525d1c48..55d7d3aa 100644 --- a/solana/app/deploy/019_fetchVoteWeightWindowLengths.ts +++ b/solana/app/deploy/063_fetchVoteWeightWindowLengths.ts @@ -1,4 +1,4 @@ -// Usage: npx ts-node app/deploy/019_fetchVoteWeightWindowLengths.ts +// Usage: npx ts-node app/deploy/063_fetchVoteWeightWindowLengths.ts import { Wallet, AnchorProvider, utils } from "@coral-xyz/anchor"; import { Connection, PublicKey } from "@solana/web3.js"; diff --git a/solana/app/deploy/044_fetchProposalAccountData.ts b/solana/app/deploy/064_fetchProposalAccountData.ts similarity index 96% rename from solana/app/deploy/044_fetchProposalAccountData.ts rename to solana/app/deploy/064_fetchProposalAccountData.ts index 575f9d38..bb4492c0 100644 --- a/solana/app/deploy/044_fetchProposalAccountData.ts +++ b/solana/app/deploy/064_fetchProposalAccountData.ts @@ -1,4 +1,4 @@ -// Usage: npx ts-node app/deploy/044_fetchProposalAccountData.ts +// Usage: npx ts-node app/deploy/064_fetchProposalAccountData.ts import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; diff --git a/solana/app/deploy/065_fetchSpokeMessageExecutor.ts b/solana/app/deploy/065_fetchSpokeMessageExecutor.ts new file mode 100644 index 00000000..7cf237e2 --- /dev/null +++ b/solana/app/deploy/065_fetchSpokeMessageExecutor.ts @@ -0,0 +1,44 @@ +// Usage: npx ts-node app/deploy/065_fetchSpokeMessageExecutor.ts + +import { Wallet, AnchorProvider, utils } from "@coral-xyz/anchor"; +import { Connection, PublicKey } from "@solana/web3.js"; +import * as wasm from "@wormhole/staking-wasm"; +import { + DEPLOYER_AUTHORITY_KEYPAIR, + RPC_NODE +} from "./devnet_consts"; +import { + STAKING_ADDRESS, + HUB_CHAIN_ID, + hubSolanaMessageDispatcherPublicKey, +} from "../constants"; +import { StakeConnection } from "../StakeConnection"; + +async function main() { + const connection = new Connection(RPC_NODE); + const provider = new AnchorProvider( + connection, + new Wallet(DEPLOYER_AUTHORITY_KEYPAIR), + {}, + ); + const stakeConnection = await StakeConnection.createStakeConnection( + connection, + provider.wallet as Wallet, + STAKING_ADDRESS, + ); + + console.log("HUB_CHAIN_ID:", HUB_CHAIN_ID); + console.log("hubSolanaMessageDispatcherPublicKey:", hubSolanaMessageDispatcherPublicKey); + + const [spokeMessageExecutorAccountAddress, _] = PublicKey.findProgramAddressSync( + [utils.bytes.utf8.encode(wasm.Constants.SPOKE_MESSAGE_EXECUTOR_SEED())], + stakeConnection.program.programId, + ); + console.log("spokeMessageExecutorAccountAddress:", spokeMessageExecutorAccountAddress); + + let spokeMessageExecutorAccountData = + await stakeConnection.program.account.spokeMessageExecutor.fetch(spokeMessageExecutorAccountAddress); + console.log("spokeMessageExecutorAccountData:", spokeMessageExecutorAccountData); +} + +main(); diff --git a/solana/programs/staking/src/wasm.rs b/solana/programs/staking/src/wasm.rs index dee1e624..69d73291 100644 --- a/solana/programs/staking/src/wasm.rs +++ b/solana/programs/staking/src/wasm.rs @@ -179,6 +179,7 @@ reexport_seed_const!(VEST_SEED); reexport_seed_const!(SPOKE_METADATA_COLLECTOR_SEED); reexport_seed_const!(VOTE_WEIGHT_WINDOW_LENGTHS_SEED); reexport_seed_const!(GUARDIAN_SIGNATURES_SEED); +reexport_seed_const!(SPOKE_MESSAGE_EXECUTOR_SEED); #[wasm_bindgen] impl Constants { From 585b91607a1b2b8d903896e895a672b2443b551e Mon Sep 17 00:00:00 2001 From: zpoken <82594516+zpoken@users.noreply.github.com> Date: Thu, 20 Feb 2025 03:46:32 +0200 Subject: [PATCH 09/14] Update scripts for vesting tests --- ..._vesting.ts => 071_createVestingConfig.ts} | 118 +++++--------- solana/app/deploy/072_delegateWithVest.ts | 41 +++++ solana/app/deploy/073_claimVesting.ts | 147 ++++++++++++++++++ 3 files changed, 231 insertions(+), 75 deletions(-) rename solana/app/deploy/{test_vesting.ts => 071_createVestingConfig.ts} (70%) create mode 100644 solana/app/deploy/072_delegateWithVest.ts create mode 100644 solana/app/deploy/073_claimVesting.ts diff --git a/solana/app/deploy/test_vesting.ts b/solana/app/deploy/071_createVestingConfig.ts similarity index 70% rename from solana/app/deploy/test_vesting.ts rename to solana/app/deploy/071_createVestingConfig.ts index 983fb5f6..bdcded91 100644 --- a/solana/app/deploy/test_vesting.ts +++ b/solana/app/deploy/071_createVestingConfig.ts @@ -1,3 +1,5 @@ +// Usage: npx ts-node app/deploy/071_createVestingConfig.ts + import { Wallet, AnchorProvider } from "@coral-xyz/anchor"; import { Connection, @@ -6,7 +8,7 @@ import { Transaction, } from "@solana/web3.js"; import { - DEPLOYER_AUTHORITY_KEYPAIR, + VESTING_ADMIN_KEYPAIR, USER_AUTHORITY_KEYPAIR, WORMHOLE_TOKEN, RPC_NODE, @@ -25,23 +27,17 @@ import { } from "@solana/spl-token"; async function main() { - const admin = DEPLOYER_AUTHORITY_KEYPAIR; + const admin = VESTING_ADMIN_KEYPAIR; const vester = USER_AUTHORITY_KEYPAIR; const connection = new Connection(RPC_NODE); const provider = new AnchorProvider(connection, new Wallet(admin), {}); - const vesterProvider = new AnchorProvider(connection, new Wallet(vester), {}); const stakeConnection = await StakeConnection.createStakeConnection( connection, provider.wallet as Wallet, STAKING_ADDRESS, ); - const vesterStakeConnection = await StakeConnection.createStakeConnection( - connection, - vesterProvider.wallet as Wallet, - STAKING_ADDRESS, - ); const confirm = async (signature: string): Promise => { const block = @@ -57,24 +53,29 @@ async function main() { const NOW = new BN(Math.floor(new Date().getTime() / 1000)); const LATER = NOW.add(new BN(1000)); const EVEN_LATER = LATER.add(new BN(1000)); + console.log("Vesting claim times:"); + console.log(`NOW: ${NOW.toString()} (${new Date(NOW.toNumber() * 1000).toISOString()})`); + console.log(`LATER: ${LATER.toString()} (${new Date(LATER.toNumber() * 1000).toISOString()})`); + console.log(`EVEN_LATER: ${EVEN_LATER.toString()} (${new Date(EVEN_LATER.toNumber() * 1000).toISOString()})`); const seed = new BN(randomBytes(8)); + console.log("Vesting config random seed:", seed); const config = PublicKey.findProgramAddressSync( [ Buffer.from(wasm.Constants.VESTING_CONFIG_SEED()), - admin.publicKey.toBuffer(), WORMHOLE_TOKEN.toBuffer(), seed.toBuffer("le", 8), ], stakeConnection.program.programId, )[0]; + console.log("Vesting config account:", config); + const vault = getAssociatedTokenAddressSync( WORMHOLE_TOKEN, config, true, TOKEN_PROGRAM_ID, ); - const vesterTa = getAssociatedTokenAddressSync( WORMHOLE_TOKEN, vester.publicKey, @@ -88,25 +89,6 @@ async function main() { TOKEN_PROGRAM_ID, ); - const vestNow = PublicKey.findProgramAddressSync( - [ - Buffer.from(wasm.Constants.VEST_SEED()), - config.toBuffer(), - vesterTa.toBuffer(), - NOW.toBuffer("le", 8), - ], - stakeConnection.program.programId, - )[0]; - const vestLater = PublicKey.findProgramAddressSync( - [ - Buffer.from(wasm.Constants.VEST_SEED()), - config.toBuffer(), - vesterTa.toBuffer(), - LATER.toBuffer("le", 8), - ], - stakeConnection.program.programId, - )[0]; - const vestingBalance = PublicKey.findProgramAddressSync( [ Buffer.from(wasm.Constants.VESTING_BALANCE_SEED()), @@ -115,24 +97,10 @@ async function main() { ], stakeConnection.program.programId, )[0]; - - let adminStakeAccountCheckpointsAddress = - await stakeConnection.getStakeAccountCheckpointsAddress(admin.publicKey); - if (!adminStakeAccountCheckpointsAddress) { - await stakeConnection.createStakeAccount(); - } - - let vesterStakeAccountCheckpointsAddress = - await vesterStakeConnection.getStakeAccountCheckpointsAddress( - vester.publicKey, - ); - if (!vesterStakeAccountCheckpointsAddress) { - await vesterStakeConnection.createStakeAccount(); - } + console.log("Vesting balance account for vester:", vestingBalance); let accounts = { admin: admin.publicKey, - payer: admin.publicKey, mint: WORMHOLE_TOKEN, config, vault, @@ -143,53 +111,74 @@ async function main() { associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, tokenProgram: TOKEN_PROGRAM_ID, systemProgram: SystemProgram.programId, - vestingBalance: vestingBalance, + vestingBalance, }; + console.log("Initializing vesting config..."); await stakeConnection.program.methods .initializeVestingConfig(seed) .accounts({ ...accounts }) .signers([admin]) .rpc() .then(confirm); + console.log("Vesting config initialized"); + console.log("Creating vesting balance for vester..."); await stakeConnection.program.methods .createVestingBalance() .accounts({ ...accounts }) .signers([admin]) .rpc() .then(confirm); + console.log("Vesting balance for vester created"); + console.log(`Creating vest for vester at NOW (${NOW.toString()})...`); await stakeConnection.program.methods .createVesting(NOW, new BN(20e6)) .accounts({ ...accounts }) .signers([admin]) - .rpc({ - skipPreflight: true, - }) + .rpc() .then(confirm); + console.log(`Vest for vester at NOW (${NOW.toString()}) created`); + console.log(`Creating vest for vester at LATER (${LATER.toString()})...`); await stakeConnection.program.methods .createVesting(LATER, new BN(20e6)) .accounts({ ...accounts }) .signers([admin]) .rpc() .then(confirm); + console.log(`Vest for vester at LATER (${LATER.toString()}) created`); + console.log(`Creating vest for vester at EVEN_LATER (${EVEN_LATER.toString()})...`); await stakeConnection.program.methods .createVesting(EVEN_LATER, new BN(20e6)) .accounts({ ...accounts }) .signers([admin]) .rpc() .then(confirm); + console.log(`Vest for vester at EVEN_LATER (${EVEN_LATER.toString()}) created`); + + const vestLater = PublicKey.findProgramAddressSync( + [ + Buffer.from(wasm.Constants.VEST_SEED()), + config.toBuffer(), + vesterTa.toBuffer(), + LATER.toBuffer("le", 8), + ], + stakeConnection.program.programId, + )[0]; + console.log(`Canceling vest for vester at LATER (${LATER.toString()})...`); await stakeConnection.program.methods .cancelVesting() .accountsPartial({ ...accounts, vest: vestLater }) .signers([admin]) .rpc() .then(confirm); + console.log(`Vest for vester at LATER (${LATER.toString()}) canceled`); + console.log("Transferring WH tokens to Vault..."); const tx = new Transaction(); tx.add( createTransferCheckedInstruction( @@ -197,53 +186,32 @@ async function main() { WORMHOLE_TOKEN, vault, admin.publicKey, - 50e6, + 100e6, 6, undefined, TOKEN_PROGRAM_ID, ), ); await stakeConnection.provider.sendAndConfirm(tx, [admin]); + console.log("WH tokens transferred to Vault"); + console.log("Withdrawing surplus..."); await stakeConnection.program.methods .withdrawSurplus() .accounts({ ...accounts }) .signers([admin]) .rpc() .then(confirm); + console.log("Surplus withdrawn"); + console.log("Finalizing vesting config..."); await stakeConnection.program.methods .finalizeVestingConfig() .accounts({ ...accounts }) .signers([admin]) .rpc() .then(confirm); - - let stakeAccountCheckpointsAddress = - await vesterStakeConnection.delegateWithVest( - vester.publicKey, - WHTokenBalance.fromString("0"), - true, - config, - ); - - let stakeAccountMetadataAddress = - await vesterStakeConnection.getStakeMetadataAddress( - stakeAccountCheckpointsAddress, - ); - - await stakeConnection.program.methods - .claimVesting() - .accountsPartial({ - ...accounts, - vest: vestNow, - stakeAccountCheckpoints: stakeAccountCheckpointsAddress, - stakeAccountMetadata: stakeAccountMetadataAddress, - globalConfig: stakeConnection.configAddress, - }) - .signers([vester]) - .rpc({ skipPreflight: true }) - .then(confirm); + console.log("Vesting config finalized"); } main(); diff --git a/solana/app/deploy/072_delegateWithVest.ts b/solana/app/deploy/072_delegateWithVest.ts new file mode 100644 index 00000000..f953285c --- /dev/null +++ b/solana/app/deploy/072_delegateWithVest.ts @@ -0,0 +1,41 @@ +// Usage: npx ts-node app/deploy/072_delegateWithVest.ts + +import { Wallet, AnchorProvider } from "@coral-xyz/anchor"; +import { + Connection, + PublicKey, +} from "@solana/web3.js"; +import { + USER_AUTHORITY_KEYPAIR, + RPC_NODE, +} from "./devnet_consts"; +import { STAKING_ADDRESS } from "../constants"; +import { StakeConnection } from "../StakeConnection"; +import { WHTokenBalance } from "../whTokenBalance"; + +async function main() { + const vester = USER_AUTHORITY_KEYPAIR; + + const connection = new Connection(RPC_NODE); + const vesterProvider = new AnchorProvider(connection, new Wallet(vester), {}); + const vesterStakeConnection = await StakeConnection.createStakeConnection( + connection, + vesterProvider.wallet as Wallet, + STAKING_ADDRESS, + ); + + const config = new PublicKey( + "BcJSiMQLggZxJ3v7kLLnQemB7Z6XJABV5Bci5LX7KhA3", + ); + + console.log(`Delegate WH tokens with vests`); + await vesterStakeConnection.delegateWithVest( + vester.publicKey, + WHTokenBalance.fromString("10"), + true, + config, + ); + console.log(`WH tokens with vests successfully delegated`); +} + +main(); diff --git a/solana/app/deploy/073_claimVesting.ts b/solana/app/deploy/073_claimVesting.ts new file mode 100644 index 00000000..2c0eaca2 --- /dev/null +++ b/solana/app/deploy/073_claimVesting.ts @@ -0,0 +1,147 @@ +// Usage: npx ts-node app/deploy/073_claimVesting.ts + +import { Wallet, AnchorProvider } from "@coral-xyz/anchor"; +import { + Connection, + PublicKey, + SystemProgram, + Transaction, +} from "@solana/web3.js"; +import { + VESTING_ADMIN_KEYPAIR, + USER_AUTHORITY_KEYPAIR, + WORMHOLE_TOKEN, + RPC_NODE, +} from "./devnet_consts"; +import { STAKING_ADDRESS } from "../constants"; +import { StakeConnection } from "../StakeConnection"; +import { WHTokenBalance } from "../whTokenBalance"; +import BN from "bn.js"; +import { randomBytes } from "crypto"; +import * as wasm from "@wormhole/staking-wasm"; +import { + ASSOCIATED_TOKEN_PROGRAM_ID, + TOKEN_PROGRAM_ID, + createTransferCheckedInstruction, + getAssociatedTokenAddressSync, +} from "@solana/spl-token"; + +async function main() { + const admin = VESTING_ADMIN_KEYPAIR; + const vester = USER_AUTHORITY_KEYPAIR; + + const connection = new Connection(RPC_NODE); + const vesterProvider = new AnchorProvider(connection, new Wallet(vester), {}); + const vesterStakeConnection = await StakeConnection.createStakeConnection( + connection, + vesterProvider.wallet as Wallet, + STAKING_ADDRESS, + ); + + const confirm = async (signature: string): Promise => { + const block = + await vesterStakeConnection.provider.connection.getLatestBlockhash(); + await vesterStakeConnection.provider.connection.confirmTransaction({ + signature, + ...block, + }); + + return signature; + }; + + const NOW = new BN(1740006704); + const config = new PublicKey( + "BcJSiMQLggZxJ3v7kLLnQemB7Z6XJABV5Bci5LX7KhA3", + ); + + const vault = getAssociatedTokenAddressSync( + WORMHOLE_TOKEN, + config, + true, + TOKEN_PROGRAM_ID, + ); + const vesterTa = getAssociatedTokenAddressSync( + WORMHOLE_TOKEN, + vester.publicKey, + false, + TOKEN_PROGRAM_ID, + ); + const adminAta = getAssociatedTokenAddressSync( + WORMHOLE_TOKEN, + admin.publicKey, + false, + TOKEN_PROGRAM_ID, + ); + + const vestNow = PublicKey.findProgramAddressSync( + [ + Buffer.from(wasm.Constants.VEST_SEED()), + config.toBuffer(), + vesterTa.toBuffer(), + NOW.toBuffer("le", 8), + ], + vesterStakeConnection.program.programId, + )[0]; + + const vestingBalance = PublicKey.findProgramAddressSync( + [ + Buffer.from(wasm.Constants.VESTING_BALANCE_SEED()), + config.toBuffer(), + vester.publicKey.toBuffer(), + ], + vesterStakeConnection.program.programId, + )[0]; + + let accounts = { + admin: admin.publicKey, + mint: WORMHOLE_TOKEN, + config, + vault, + vester: vester.publicKey, + vesterTa, + adminAta, + recovery: adminAta, + associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, + tokenProgram: TOKEN_PROGRAM_ID, + systemProgram: SystemProgram.programId, + vestingBalance: vestingBalance, + }; + + let stakeAccountMetadataAddress = + await vesterStakeConnection.getStakeMetadataAddress( + vester.publicKey, + ); + let stakeAccountMetadataData = + await vesterStakeConnection.fetchStakeAccountMetadata( + vester.publicKey, + ); + let delegateStakeAccountCheckpointsOwner = + stakeAccountMetadataData.delegate; + let delegateStakeAccountMetadataAddress = + await vesterStakeConnection.getStakeMetadataAddress( + delegateStakeAccountCheckpointsOwner, + ); + let delegateStakeAccountCheckpointsAddress = + await vesterStakeConnection.getStakeAccountCheckpointsAddressByMetadata( + delegateStakeAccountMetadataAddress, + false, + ); + + console.log("Starting claimVesting..."); + await vesterStakeConnection.program.methods + .claimVesting() + .accountsPartial({ + ...accounts, + vest: vestNow, + delegateStakeAccountCheckpoints: delegateStakeAccountCheckpointsAddress, + delegateStakeAccountMetadata: stakeAccountMetadataAddress, + stakeAccountMetadata: stakeAccountMetadataAddress, + globalConfig: vesterStakeConnection.configAddress, + }) + .signers([vester]) + .rpc() + .then(confirm); + console.log("claimVesting completed successfully."); +} + +main(); From 880b0c1492553d49bcb67c1eec5815c16d9ad225 Mon Sep 17 00:00:00 2001 From: zpoken <82594516+zpoken@users.noreply.github.com> Date: Wed, 5 Mar 2025 16:14:49 +0200 Subject: [PATCH 10/14] Reorganization of scripts, constants, and folders. Remove unnecessary code --- solana/app/StakeConnection.ts | 15 +++-- solana/app/{ => deploy/devnet}/constants.ts | 44 ++++++++++++- .../initialize/initAddressLookupTable.ts} | 12 +++- .../initialize/initConfig.ts} | 13 ++-- .../initialize/initializeSpokeAirlock.ts} | 7 +-- .../initializeSpokeMessageExecutor.ts} | 13 ++-- .../initializeSpokeMetadataCollector.ts} | 14 +++-- .../initializeVoteWeightWindowLengths.ts} | 8 +-- .../tests/11_createStakeAccount.ts} | 12 +--- .../tests/12_deposit.ts} | 10 ++- .../tests/13_withdrawTokens.ts} | 14 ++--- .../tests/14_delegate.ts} | 14 ++--- .../tests/15_addProposal.ts} | 20 +++--- .../tests/16_castVote.ts} | 9 +-- .../tests/17_proposalVotes.ts} | 9 +-- .../tests/21_fetchGlobalConfig.ts} | 11 ++-- .../tests/22_fetchSpokeMetadataCollector.ts} | 12 ++-- .../tests/23_fetchVoteWeightWindowLengths.ts} | 12 ++-- .../tests/24_fetchProposalAccountData.ts} | 14 ++--- .../tests/25_fetchSpokeMessageExecutor.ts} | 10 +-- .../tests/31_tx_list.ts} | 6 +- .../tests/32_tx_events.ts} | 6 +- .../tests/33_tx_details.ts} | 6 +- .../{ => devnet/tests}/bridge-script.ts | 17 +++-- .../deploy/{ => devnet/tests}/new_wallet.ts | 2 +- .../{ => devnet/tests}/receive_message.ts | 10 +-- .../{ => devnet/tests}/transfer_W_token.ts | 3 +- .../update/updateGovernanceAuthority.ts} | 8 +-- .../update/updateHubProposalMetadata.ts} | 15 ++--- .../update/updateVestingAdmin.ts} | 11 ++-- .../vesting/claimVesting.ts} | 12 +--- .../vesting/createVestingConfig.ts} | 9 +-- .../vesting/delegateWithVest.ts} | 10 ++- solana/app/deploy/devnet_consts.ts | 40 ------------ .../app/deploy/{ => mainnet}/mainnet_beta.ts | 0 .../01_createProposeWithSolanaExecution.ts | 10 ++- solana/app/e2e/02_addProposal.ts | 19 +++--- solana/app/e2e/03_castVote.ts | 9 ++- solana/app/e2e/04_crossChainVoteSolana.ts | 7 +-- solana/app/e2e/05_proposalQueue.ts | 3 +- solana/app/e2e/06_proposalExecute.ts | 3 +- .../external_program/initializeConfigPDA.ts | 3 +- solana/app/helpers/utils/lookup_table.ts | 62 +++++++++++++++++++ .../{ => helpers}/utils/parse_transactions.ts | 0 solana/app/index.ts | 1 - solana/tests/api_test.ts | 2 +- solana/tests/config.ts | 16 +++-- solana/tests/executor.ts | 13 ++-- solana/tests/utils/api_utils.ts | 13 ++-- solana/tests/utils/before.ts | 15 ++--- solana/tests/utils/constants.ts | 22 +++++++ solana/tests/utils/utils.ts | 55 ---------------- solana/tests/vesting.ts | 1 - solana/tests/voter_votes_test.ts | 2 - 54 files changed, 340 insertions(+), 344 deletions(-) rename solana/app/{ => deploy/devnet}/constants.ts (56%) rename solana/app/deploy/{012_initAddressLookupTable.ts => devnet/initialize/initAddressLookupTable.ts} (65%) rename solana/app/deploy/{011_initConfig.ts => devnet/initialize/initConfig.ts} (71%) rename solana/app/deploy/{013_initializeSpokeAirlock.ts => devnet/initialize/initializeSpokeAirlock.ts} (81%) rename solana/app/deploy/{016_initializeSpokeMessageExecutor.ts => devnet/initialize/initializeSpokeMessageExecutor.ts} (79%) rename solana/app/deploy/{014_initializeSpokeMetadataCollector.ts => devnet/initialize/initializeSpokeMetadataCollector.ts} (68%) rename solana/app/deploy/{015_initializeVoteWeightWindowLengths.ts => devnet/initialize/initializeVoteWeightWindowLengths.ts} (76%) rename solana/app/deploy/{031_createStakeAccount.ts => devnet/tests/11_createStakeAccount.ts} (56%) rename solana/app/deploy/{032_deposit.ts => devnet/tests/12_deposit.ts} (88%) rename solana/app/deploy/{033_withdrawTokens.ts => devnet/tests/13_withdrawTokens.ts} (73%) rename solana/app/deploy/{034_delegate.ts => devnet/tests/14_delegate.ts} (77%) rename solana/app/deploy/{041_addProposal.ts => devnet/tests/15_addProposal.ts} (81%) rename solana/app/deploy/{042_castVote.ts => devnet/tests/16_castVote.ts} (77%) rename solana/app/deploy/{043_proposalVotes.ts => devnet/tests/17_proposalVotes.ts} (77%) rename solana/app/deploy/{061_fetchGlobalConfig.ts => devnet/tests/21_fetchGlobalConfig.ts} (85%) rename solana/app/deploy/{062_fetchSpokeMetadataCollector.ts => devnet/tests/22_fetchSpokeMetadataCollector.ts} (80%) rename solana/app/deploy/{063_fetchVoteWeightWindowLengths.ts => devnet/tests/23_fetchVoteWeightWindowLengths.ts} (81%) rename solana/app/deploy/{064_fetchProposalAccountData.ts => devnet/tests/24_fetchProposalAccountData.ts} (73%) rename solana/app/deploy/{065_fetchSpokeMessageExecutor.ts => devnet/tests/25_fetchSpokeMessageExecutor.ts} (86%) rename solana/app/deploy/{051_tx_list.ts => devnet/tests/31_tx_list.ts} (84%) rename solana/app/deploy/{052_tx_events.ts => devnet/tests/32_tx_events.ts} (87%) rename solana/app/deploy/{053_tx_details.ts => devnet/tests/33_tx_details.ts} (85%) rename solana/app/deploy/{ => devnet/tests}/bridge-script.ts (95%) rename solana/app/deploy/{ => devnet/tests}/new_wallet.ts (91%) rename solana/app/deploy/{ => devnet/tests}/receive_message.ts (92%) rename solana/app/deploy/{ => devnet/tests}/transfer_W_token.ts (95%) rename solana/app/deploy/{022_updateGovernanceAuthority.ts => devnet/update/updateGovernanceAuthority.ts} (82%) rename solana/app/deploy/{021_updateHubProposalMetadata.ts => devnet/update/updateHubProposalMetadata.ts} (68%) rename solana/app/deploy/{023_updateVestingAdmin.ts => devnet/update/updateVestingAdmin.ts} (77%) rename solana/app/deploy/{073_claimVesting.ts => devnet/vesting/claimVesting.ts} (91%) rename solana/app/deploy/{071_createVestingConfig.ts => devnet/vesting/createVestingConfig.ts} (95%) rename solana/app/deploy/{072_delegateWithVest.ts => devnet/vesting/delegateWithVest.ts} (76%) delete mode 100644 solana/app/deploy/devnet_consts.ts rename solana/app/deploy/{ => mainnet}/mainnet_beta.ts (100%) create mode 100644 solana/app/helpers/utils/lookup_table.ts rename solana/app/{ => helpers}/utils/parse_transactions.ts (100%) create mode 100644 solana/tests/utils/constants.ts diff --git a/solana/app/StakeConnection.ts b/solana/app/StakeConnection.ts index a7047f9b..e4f1497c 100644 --- a/solana/app/StakeConnection.ts +++ b/solana/app/StakeConnection.ts @@ -25,7 +25,7 @@ import BN from "bn.js"; import { Staking } from "../target/types/staking"; import IDL from "../target/idl/staking.json"; import { WHTokenBalance } from "./whTokenBalance"; -import { CORE_BRIDGE_ADDRESS, STAKING_ADDRESS } from "./constants"; +import { contracts } from "@wormhole-foundation/sdk-base"; import { PriorityFeeConfig, sendTransactions, @@ -92,7 +92,6 @@ export class StakeConnection { return await StakeConnection.createStakeConnection( connection, wallet, - STAKING_ADDRESS, ); } @@ -102,7 +101,6 @@ export class StakeConnection { public static async createStakeConnection( connection: Connection, wallet: Wallet, - stakingProgramAddress: PublicKey, addressLookupTable?: PublicKey, priorityFeeConfig?: PriorityFeeConfig, ): Promise { @@ -386,7 +384,6 @@ export class StakeConnection { /** Creates a new stake account and sends the transaction for confirmation. */ public async createStakeAccount(): Promise { const instructions: TransactionInstruction[] = []; - instructions.push( await this.program.methods .createStakeAccount() @@ -395,6 +392,7 @@ export class StakeConnection { }) .instruction(), ); + await this.sendAndConfirmAsVersionedTransaction(instructions); } @@ -754,7 +752,12 @@ export class StakeConnection { unoptimized?: boolean, ): Promise { const { proposalAccount } = await this.fetchProposalAccount(proposalId); - + const networkType = this.provider.connection.rpcEndpoint.includes('mainnet') + ? 'Mainnet' + : 'Testnet'; + const coreBridge = new PublicKey( + contracts.coreBridge.get(networkType, "Solana"), // Testnet - 3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5 + ); const methodsBuilder = this.program.methods .addProposal( Buffer.from(ethProposalResponseBytes), @@ -765,7 +768,7 @@ export class StakeConnection { proposal: proposalAccount, guardianSignatures: guardianSignatures, guardianSet: deriveGuardianSetKey( - CORE_BRIDGE_ADDRESS, + coreBridge, guardianSetIndex, ), }); diff --git a/solana/app/constants.ts b/solana/app/deploy/devnet/constants.ts similarity index 56% rename from solana/app/constants.ts rename to solana/app/deploy/devnet/constants.ts index af84b7f7..21593863 100644 --- a/solana/app/constants.ts +++ b/solana/app/deploy/devnet/constants.ts @@ -1,11 +1,16 @@ import { PublicKey } from "@solana/web3.js"; +import { homedir } from "os"; +import { loadKeypair } from "../../../tests/utils/keys"; +import { contracts } from "@wormhole-foundation/sdk-base"; + +export const RPC_NODE = "https://api.devnet.solana.com"; export const STAKING_ADDRESS = new PublicKey( "AFuHPdrQGsW8rNQ4oEFF35sm5fg36gwrxyqjkjKvi6ap", ); -export const CORE_BRIDGE_ADDRESS = new PublicKey( - "3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5", +export const CORE_BRIDGE_PID = new PublicKey( + contracts.coreBridge.get("Testnet", "Solana")!, // 3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5 ); /// Wormhole Hub Proposal Metadata Contract (sepolia ethereum address) @@ -53,3 +58,38 @@ export const HUB_SOLANA_SPOKE_VOTE_DECODER_ADDRESS = /// Wormhole HubVotePool Contract (sepolia ethereum address) export const HUB_VOTE_POOL_ADDRESS = "0x1004c781763c70f5f11aa64b0e5b34e1442a3c02"; + +export const DEPLOYER_AUTHORITY_PATH = "/.config/solana/deployer.json"; +export const DEPLOYER_AUTHORITY_KEYPAIR = loadKeypair( + homedir() + DEPLOYER_AUTHORITY_PATH, +); + +export const GOVERNANCE_AUTHORITY_PATH = "/.config/solana/governanceAuthority.json"; +export const GOVERNANCE_AUTHORITY_KEYPAIR = loadKeypair( + homedir() + GOVERNANCE_AUTHORITY_PATH, +); + +export const VESTING_ADMIN_PATH = "/.config/solana/vestingAdmin.json"; +export const VESTING_ADMIN_KEYPAIR = loadKeypair( + homedir() + VESTING_ADMIN_PATH, +); + +export const USER_AUTHORITY_PATH = "/.config/solana/user.json"; +export const USER_AUTHORITY_KEYPAIR = loadKeypair( + homedir() + USER_AUTHORITY_PATH, +); + +export const USER2_AUTHORITY_PATH = "/.config/solana/secretKey_617X3kwJzjfAbr6zHMa4rzbjaHQN8mzST8VAb8oE8xo8.json"; +export const USER2_AUTHORITY_KEYPAIR = loadKeypair( + homedir() + USER2_AUTHORITY_PATH, +); + +export const WORMHOLE_TOKEN = new PublicKey( + "Exne2kdeGToBnC2WVSdt1gLy6fjnNftbPtsCPx8AuL7V", +); + +export const AIRLOCK_PDA_ADDRESS = new PublicKey( + "2ejzW2eFPedskg1KcrjcFs9g1JorRVcMes1TBPpGbhdy", +); + +export const VOTE_WEIGHT_WINDOW_LENGTHS = 10 * 60; // 10 minutes diff --git a/solana/app/deploy/012_initAddressLookupTable.ts b/solana/app/deploy/devnet/initialize/initAddressLookupTable.ts similarity index 65% rename from solana/app/deploy/012_initAddressLookupTable.ts rename to solana/app/deploy/devnet/initialize/initAddressLookupTable.ts index c89991d3..4af71f9d 100644 --- a/solana/app/deploy/012_initAddressLookupTable.ts +++ b/solana/app/deploy/devnet/initialize/initAddressLookupTable.ts @@ -1,9 +1,14 @@ -// Usage: npx ts-node app/deploy/012_initAddressLookupTable.ts +// Usage: npx ts-node app/deploy/devnet/initialize/initAddressLookupTable.ts import { Wallet, AnchorProvider } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; -import { DEPLOYER_AUTHORITY_KEYPAIR, WORMHOLE_TOKEN, RPC_NODE } from "./devnet_consts"; -import { initAddressLookupTable } from "../../tests/utils/utils"; +import { + DEPLOYER_AUTHORITY_KEYPAIR, + RPC_NODE, + STAKING_ADDRESS, + WORMHOLE_TOKEN, +} from "../constants"; +import { initAddressLookupTable } from "../../../helpers/utils/lookup_table"; async function main() { try { @@ -17,6 +22,7 @@ async function main() { const lookupTableAddress = await initAddressLookupTable( provider, WORMHOLE_TOKEN, + STAKING_ADDRESS, ); console.log("Lookup table address: ", lookupTableAddress.toBase58()); diff --git a/solana/app/deploy/011_initConfig.ts b/solana/app/deploy/devnet/initialize/initConfig.ts similarity index 71% rename from solana/app/deploy/011_initConfig.ts rename to solana/app/deploy/devnet/initialize/initConfig.ts index 03c66076..e1c64044 100644 --- a/solana/app/deploy/011_initConfig.ts +++ b/solana/app/deploy/devnet/initialize/initConfig.ts @@ -1,11 +1,14 @@ -// Usage: npx ts-node app/deploy/011_initConfig.ts +// Usage: npx ts-node app/deploy/devnet/initialize/initConfig.ts import { Wallet, AnchorProvider, Program } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; -import { DEPLOYER_AUTHORITY_KEYPAIR, WORMHOLE_TOKEN, RPC_NODE } from "./devnet_consts"; -import { CHECKPOINTS_ACCOUNT_LIMIT, STAKING_ADDRESS } from "../constants"; -import { Staking } from "../../target/types/staking"; -import fs from "fs"; +import { + CHECKPOINTS_ACCOUNT_LIMIT, + STAKING_ADDRESS, + DEPLOYER_AUTHORITY_KEYPAIR, + WORMHOLE_TOKEN, + RPC_NODE, +} from "../constants"; async function main() { const connection = new Connection(RPC_NODE); diff --git a/solana/app/deploy/013_initializeSpokeAirlock.ts b/solana/app/deploy/devnet/initialize/initializeSpokeAirlock.ts similarity index 81% rename from solana/app/deploy/013_initializeSpokeAirlock.ts rename to solana/app/deploy/devnet/initialize/initializeSpokeAirlock.ts index 18c25628..efb3d228 100644 --- a/solana/app/deploy/013_initializeSpokeAirlock.ts +++ b/solana/app/deploy/devnet/initialize/initializeSpokeAirlock.ts @@ -1,10 +1,9 @@ -// Usage: npx ts-node app/deploy/013_initializeSpokeAirlock.ts +// Usage: npx ts-node app/deploy/devnet/initialize/initializeSpokeAirlock.ts -import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; import { Connection, PublicKey, SystemProgram } from "@solana/web3.js"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; -import { Staking } from "../../target/types/staking"; +import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "../constants"; +import { Staking } from "../../../../target/types/staking"; import fs from "fs"; async function main() { diff --git a/solana/app/deploy/016_initializeSpokeMessageExecutor.ts b/solana/app/deploy/devnet/initialize/initializeSpokeMessageExecutor.ts similarity index 79% rename from solana/app/deploy/016_initializeSpokeMessageExecutor.ts rename to solana/app/deploy/devnet/initialize/initializeSpokeMessageExecutor.ts index 0a9faacf..a109a9ed 100644 --- a/solana/app/deploy/016_initializeSpokeMessageExecutor.ts +++ b/solana/app/deploy/devnet/initialize/initializeSpokeMessageExecutor.ts @@ -1,20 +1,19 @@ -// Usage: npx ts-node app/deploy/016_initializeSpokeMessageExecutor.ts +// Usage: npx ts-node app/deploy/devnet/initialize/initializeSpokeMessageExecutor.ts -import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; import { Connection, PublicKey, SystemProgram } from "@solana/web3.js"; import { + DEPLOYER_AUTHORITY_KEYPAIR, hubSolanaMessageDispatcherPublicKey, HUB_CHAIN_ID, + RPC_NODE, } from "../constants"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; -import { Staking } from "../../target/types/staking"; +import { Staking } from "../../../../target/types/staking"; import fs from "fs"; -import { wasm } from "../StakeConnection"; +import { wasm } from "../../../StakeConnection"; async function main() { try { - const DEBUG = true; const connection = new Connection(RPC_NODE); const provider = new AnchorProvider( connection, @@ -47,7 +46,7 @@ async function main() { hubDispatcher: hubSolanaMessageDispatcherPublicKey, systemProgram: SystemProgram.programId, }) - .rpc({ skipPreflight: DEBUG }); + .rpc(); } catch (err) { console.error("Error:", err); } diff --git a/solana/app/deploy/014_initializeSpokeMetadataCollector.ts b/solana/app/deploy/devnet/initialize/initializeSpokeMetadataCollector.ts similarity index 68% rename from solana/app/deploy/014_initializeSpokeMetadataCollector.ts rename to solana/app/deploy/devnet/initialize/initializeSpokeMetadataCollector.ts index 7dc78e3d..123c43d7 100644 --- a/solana/app/deploy/014_initializeSpokeMetadataCollector.ts +++ b/solana/app/deploy/devnet/initialize/initializeSpokeMetadataCollector.ts @@ -1,16 +1,18 @@ -// Usage: npx ts-node app/deploy/014_initializeSpokeMetadataCollector.ts +// Usage: npx ts-node app/deploy/devnet/initialize/initializeSpokeMetadataCollector.ts -import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; -import { HUB_CHAIN_ID, hubProposalMetadataUint8Array } from "../constants"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; -import { Staking } from "../../target/types/staking"; +import { + DEPLOYER_AUTHORITY_KEYPAIR, + HUB_CHAIN_ID, + hubProposalMetadataUint8Array, + RPC_NODE, +} from "../constants"; +import { Staking } from "../../../../target/types/staking"; import fs from "fs"; async function main() { try { - const DEBUG = true; const connection = new Connection(RPC_NODE); const provider = new AnchorProvider( connection, diff --git a/solana/app/deploy/015_initializeVoteWeightWindowLengths.ts b/solana/app/deploy/devnet/initialize/initializeVoteWeightWindowLengths.ts similarity index 76% rename from solana/app/deploy/015_initializeVoteWeightWindowLengths.ts rename to solana/app/deploy/devnet/initialize/initializeVoteWeightWindowLengths.ts index 977d5f98..0059e189 100644 --- a/solana/app/deploy/015_initializeVoteWeightWindowLengths.ts +++ b/solana/app/deploy/devnet/initialize/initializeVoteWeightWindowLengths.ts @@ -1,16 +1,14 @@ -// Usage: npx ts-node app/deploy/015_initializeVoteWeightWindowLengths.ts +// Usage: npx ts-node app/deploy/devnet/initialize/initializeVoteWeightWindowLengths.ts -import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE, VOTE_WEIGHT_WINDOW_LENGTHS } from "./devnet_consts"; -import { Staking } from "../../target/types/staking"; +import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE, VOTE_WEIGHT_WINDOW_LENGTHS } from "../constants"; +import { Staking } from "../../../../target/types/staking"; import fs from "fs"; import BN from "bn.js"; async function main() { try { - const DEBUG = true; const connection = new Connection(RPC_NODE); const provider = new AnchorProvider( connection, diff --git a/solana/app/deploy/031_createStakeAccount.ts b/solana/app/deploy/devnet/tests/11_createStakeAccount.ts similarity index 56% rename from solana/app/deploy/031_createStakeAccount.ts rename to solana/app/deploy/devnet/tests/11_createStakeAccount.ts index 8e84e00d..d1c73505 100644 --- a/solana/app/deploy/031_createStakeAccount.ts +++ b/solana/app/deploy/devnet/tests/11_createStakeAccount.ts @@ -1,17 +1,12 @@ -// Usage: npx ts-node app/deploy/031_createStakeAccount.ts +// Usage: npx ts-node app/deploy/devnet/tests/11_createStakeAccount.ts -import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; -import * as wasm from "@wormhole/staking-wasm"; -import { StakeConnection } from "../StakeConnection"; -import { STAKING_ADDRESS } from "../constants"; -import { USER2_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; -import { Staking } from "../../target/types/staking"; +import { StakeConnection } from "../../../StakeConnection"; +import { RPC_NODE, USER2_AUTHORITY_KEYPAIR } from "../constants"; async function main() { try { - const DEBUG = true; const connection = new Connection(RPC_NODE); const provider = new AnchorProvider( connection, @@ -22,7 +17,6 @@ async function main() { const stakeConnection = await StakeConnection.createStakeConnection( connection, provider.wallet as Wallet, - STAKING_ADDRESS, ); await stakeConnection.createStakeAccount(); diff --git a/solana/app/deploy/032_deposit.ts b/solana/app/deploy/devnet/tests/12_deposit.ts similarity index 88% rename from solana/app/deploy/032_deposit.ts rename to solana/app/deploy/devnet/tests/12_deposit.ts index 0dc90faf..42b61dce 100644 --- a/solana/app/deploy/032_deposit.ts +++ b/solana/app/deploy/devnet/tests/12_deposit.ts @@ -1,4 +1,4 @@ -// Usage: npx ts-node app/deploy/032_deposit.ts +// Usage: npx ts-node app/deploy/devnet/tests/12_deposit.ts import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; @@ -8,8 +8,12 @@ import { } from "@solana/spl-token"; import { PublicKey, Transaction, Connection } from "@solana/web3.js"; import * as wasm from "@wormhole/staking-wasm"; -import { STAKING_ADDRESS } from "../constants"; -import { USER_AUTHORITY_KEYPAIR, WORMHOLE_TOKEN, RPC_NODE } from "./devnet_consts"; +import { + RPC_NODE, + STAKING_ADDRESS, + USER_AUTHORITY_KEYPAIR, + WORMHOLE_TOKEN, +} from "../constants"; async function main() { try { diff --git a/solana/app/deploy/033_withdrawTokens.ts b/solana/app/deploy/devnet/tests/13_withdrawTokens.ts similarity index 73% rename from solana/app/deploy/033_withdrawTokens.ts rename to solana/app/deploy/devnet/tests/13_withdrawTokens.ts index 7b8a37d8..b3296ce9 100644 --- a/solana/app/deploy/033_withdrawTokens.ts +++ b/solana/app/deploy/devnet/tests/13_withdrawTokens.ts @@ -1,12 +1,10 @@ -// Usage: npx ts-node app/deploy/033_withdrawTokens.ts +// Usage: npx ts-node app/deploy/devnet/tests/13_withdrawTokens.ts -import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; -import { StakeConnection } from "../StakeConnection"; -import { WHTokenBalance } from "../whTokenBalance"; -import { STAKING_ADDRESS } from "../constants"; -import { USER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; +import { StakeConnection } from "../../../StakeConnection"; +import { WHTokenBalance } from "../../../whTokenBalance"; +import { RPC_NODE, USER_AUTHORITY_KEYPAIR } from "../constants"; async function main() { try { @@ -19,7 +17,6 @@ async function main() { const stakeConnection = await StakeConnection.createStakeConnection( connection, provider.wallet as Wallet, - STAKING_ADDRESS, ); const user = provider.wallet.publicKey; @@ -30,6 +27,9 @@ async function main() { stakeAccountMetadataAddress, false, ); + if (!stakeAccountCheckpointsAddress) { + throw new Error(`stakeAccountCheckpointsAddress is not defined`); + } let stakeAccount = await stakeConnection.loadStakeAccount( stakeAccountCheckpointsAddress, ); diff --git a/solana/app/deploy/034_delegate.ts b/solana/app/deploy/devnet/tests/14_delegate.ts similarity index 77% rename from solana/app/deploy/034_delegate.ts rename to solana/app/deploy/devnet/tests/14_delegate.ts index 54ab2bf5..6bf7d967 100644 --- a/solana/app/deploy/034_delegate.ts +++ b/solana/app/deploy/devnet/tests/14_delegate.ts @@ -1,16 +1,14 @@ -// Usage: npx ts-node app/deploy/034_delegate.ts +// Usage: npx ts-node app/deploy/devnet/tests/14_delegate.ts -import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; -import { PublicKey, Connection } from "@solana/web3.js"; -import { StakeConnection } from "../StakeConnection"; -import { WHTokenBalance } from "../whTokenBalance"; -import { STAKING_ADDRESS } from "../constants"; +import { Connection } from "@solana/web3.js"; +import { StakeConnection } from "../../../StakeConnection"; +import { WHTokenBalance } from "../../../whTokenBalance"; import { USER_AUTHORITY_KEYPAIR, USER2_AUTHORITY_KEYPAIR, RPC_NODE, -} from "./devnet_consts"; +} from "../constants"; function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); @@ -27,7 +25,6 @@ async function main() { const stakeConnection = await StakeConnection.createStakeConnection( connection, provider.wallet as Wallet, - STAKING_ADDRESS, ); await stakeConnection.delegate( @@ -44,7 +41,6 @@ async function main() { const user2StakeConnection = await StakeConnection.createStakeConnection( connection, user2Provider.wallet as Wallet, - STAKING_ADDRESS, ); await user2StakeConnection.delegate( diff --git a/solana/app/deploy/041_addProposal.ts b/solana/app/deploy/devnet/tests/15_addProposal.ts similarity index 81% rename from solana/app/deploy/041_addProposal.ts rename to solana/app/deploy/devnet/tests/15_addProposal.ts index 1b2155d7..b0f524e9 100644 --- a/solana/app/deploy/041_addProposal.ts +++ b/solana/app/deploy/devnet/tests/15_addProposal.ts @@ -1,12 +1,15 @@ -// Usage: npx ts-node app/deploy/041_addProposal.ts +// Usage: npx ts-node app/deploy/devnet/tests/15_addProposal.ts -import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; -import { Connection, Keypair } from "@solana/web3.js"; -import { StakeConnection } from "../StakeConnection"; -import { STAKING_ADDRESS, CORE_BRIDGE_ADDRESS } from "../constants"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; -import { getWormholeBridgeData } from "../helpers/wormholeBridgeConfig"; +import { Connection } from "@solana/web3.js"; +import { StakeConnection } from "../../../StakeConnection"; +import { + CORE_BRIDGE_PID, + DEPLOYER_AUTHORITY_KEYPAIR, + RPC_NODE, +} from "../constants"; +import { getWormholeBridgeData } from "../../../helpers/wormholeBridgeConfig"; +import input from "@inquirer/input"; async function main() { try { @@ -21,10 +24,9 @@ async function main() { const stakeConnection = await StakeConnection.createStakeConnection( connection, provider.wallet as Wallet, - STAKING_ADDRESS, ); - const info = await getWormholeBridgeData(connection, CORE_BRIDGE_ADDRESS); + const info = await getWormholeBridgeData(connection, CORE_BRIDGE_PID); let guardianSetIndex = info.guardianSetIndex; const sepoliaEthProposalResponse = { diff --git a/solana/app/deploy/042_castVote.ts b/solana/app/deploy/devnet/tests/16_castVote.ts similarity index 77% rename from solana/app/deploy/042_castVote.ts rename to solana/app/deploy/devnet/tests/16_castVote.ts index 29ffb9f6..a6ca4d4d 100644 --- a/solana/app/deploy/042_castVote.ts +++ b/solana/app/deploy/devnet/tests/16_castVote.ts @@ -1,11 +1,9 @@ -// Usage: npx ts-node app/deploy/042_castVote.ts +// Usage: npx ts-node app/deploy/devnet/tests/16_castVote.ts -import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; -import { StakeConnection } from "../StakeConnection"; -import { STAKING_ADDRESS } from "../constants"; -import { USER2_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; +import { StakeConnection } from "../../../StakeConnection"; +import { USER2_AUTHORITY_KEYPAIR, RPC_NODE } from "../constants"; import BN from "bn.js"; import input from "@inquirer/input"; @@ -26,7 +24,6 @@ async function main() { const user2StakeConnection = await StakeConnection.createStakeConnection( connection, user2Provider.wallet as Wallet, - STAKING_ADDRESS, ); await user2StakeConnection.castVote( diff --git a/solana/app/deploy/043_proposalVotes.ts b/solana/app/deploy/devnet/tests/17_proposalVotes.ts similarity index 77% rename from solana/app/deploy/043_proposalVotes.ts rename to solana/app/deploy/devnet/tests/17_proposalVotes.ts index dd1e1d4d..b4a29888 100644 --- a/solana/app/deploy/043_proposalVotes.ts +++ b/solana/app/deploy/devnet/tests/17_proposalVotes.ts @@ -1,11 +1,9 @@ -// Usage: npx ts-node app/deploy/043_proposalVotes.ts +// Usage: npx ts-node app/deploy/devnet/tests/17_proposalVotes.ts -import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; -import { StakeConnection } from "../StakeConnection"; -import { STAKING_ADDRESS } from "../constants"; -import { USER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; +import { StakeConnection } from "../../../StakeConnection"; +import { USER_AUTHORITY_KEYPAIR, RPC_NODE } from "../constants"; async function main() { try { @@ -19,7 +17,6 @@ async function main() { const stakeConnection = await StakeConnection.createStakeConnection( connection, provider.wallet as Wallet, - STAKING_ADDRESS, ); const proposalIdHex = diff --git a/solana/app/deploy/061_fetchGlobalConfig.ts b/solana/app/deploy/devnet/tests/21_fetchGlobalConfig.ts similarity index 85% rename from solana/app/deploy/061_fetchGlobalConfig.ts rename to solana/app/deploy/devnet/tests/21_fetchGlobalConfig.ts index 87aac350..e708c431 100644 --- a/solana/app/deploy/061_fetchGlobalConfig.ts +++ b/solana/app/deploy/devnet/tests/21_fetchGlobalConfig.ts @@ -1,17 +1,17 @@ -// Usage: npx ts-node app/deploy/061_fetchGlobalConfig.ts +// Usage: npx ts-node app/deploy/devnet/tests/21_fetchGlobalConfig.ts import { Wallet, AnchorProvider, utils } from "@coral-xyz/anchor"; import { Connection, PublicKey } from "@solana/web3.js"; import * as wasm from "@wormhole/staking-wasm"; import { + CHECKPOINTS_ACCOUNT_LIMIT, DEPLOYER_AUTHORITY_KEYPAIR, WORMHOLE_TOKEN, GOVERNANCE_AUTHORITY_KEYPAIR, VESTING_ADMIN_KEYPAIR, - RPC_NODE -} from "./devnet_consts"; -import { CHECKPOINTS_ACCOUNT_LIMIT, STAKING_ADDRESS } from "../constants"; -import { StakeConnection } from "../StakeConnection"; + RPC_NODE, +} from "../constants"; +import { StakeConnection } from "../../../StakeConnection"; async function main() { const connection = new Connection(RPC_NODE); @@ -23,7 +23,6 @@ async function main() { const stakeConnection = await StakeConnection.createStakeConnection( connection, provider.wallet as Wallet, - STAKING_ADDRESS, ); console.log("DEPLOYER_AUTHORITY_KEYPAIR.publicKey:", DEPLOYER_AUTHORITY_KEYPAIR.publicKey); diff --git a/solana/app/deploy/062_fetchSpokeMetadataCollector.ts b/solana/app/deploy/devnet/tests/22_fetchSpokeMetadataCollector.ts similarity index 80% rename from solana/app/deploy/062_fetchSpokeMetadataCollector.ts rename to solana/app/deploy/devnet/tests/22_fetchSpokeMetadataCollector.ts index 08ae8feb..fa208c9c 100644 --- a/solana/app/deploy/062_fetchSpokeMetadataCollector.ts +++ b/solana/app/deploy/devnet/tests/22_fetchSpokeMetadataCollector.ts @@ -1,14 +1,15 @@ -// Usage: npx ts-node app/deploy/062_fetchSpokeMetadataCollector.ts +// Usage: npx ts-node app/deploy/devnet/tests/22_fetchSpokeMetadataCollector.ts import { Wallet, AnchorProvider, utils } from "@coral-xyz/anchor"; import { Connection, PublicKey } from "@solana/web3.js"; import * as wasm from "@wormhole/staking-wasm"; import { DEPLOYER_AUTHORITY_KEYPAIR, - RPC_NODE -} from "./devnet_consts"; -import { STAKING_ADDRESS, HUB_CHAIN_ID, hubProposalMetadataUint8Array } from "../constants"; -import { StakeConnection } from "../StakeConnection"; + HUB_CHAIN_ID, + hubProposalMetadataUint8Array, + RPC_NODE, +} from "../constants"; +import { StakeConnection } from "../../../StakeConnection"; async function main() { const connection = new Connection(RPC_NODE); @@ -20,7 +21,6 @@ async function main() { const stakeConnection = await StakeConnection.createStakeConnection( connection, provider.wallet as Wallet, - STAKING_ADDRESS, ); console.log("HUB_CHAIN_ID:", HUB_CHAIN_ID); diff --git a/solana/app/deploy/063_fetchVoteWeightWindowLengths.ts b/solana/app/deploy/devnet/tests/23_fetchVoteWeightWindowLengths.ts similarity index 81% rename from solana/app/deploy/063_fetchVoteWeightWindowLengths.ts rename to solana/app/deploy/devnet/tests/23_fetchVoteWeightWindowLengths.ts index 55d7d3aa..560c2283 100644 --- a/solana/app/deploy/063_fetchVoteWeightWindowLengths.ts +++ b/solana/app/deploy/devnet/tests/23_fetchVoteWeightWindowLengths.ts @@ -1,4 +1,4 @@ -// Usage: npx ts-node app/deploy/063_fetchVoteWeightWindowLengths.ts +// Usage: npx ts-node app/deploy/devnet/tests/23_fetchVoteWeightWindowLengths.ts import { Wallet, AnchorProvider, utils } from "@coral-xyz/anchor"; import { Connection, PublicKey } from "@solana/web3.js"; @@ -7,13 +7,12 @@ import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE, VOTE_WEIGHT_WINDOW_LENGTHS -} from "./devnet_consts"; -import { STAKING_ADDRESS } from "../constants"; -import { StakeConnection } from "../StakeConnection"; +} from "../constants"; +import { StakeConnection } from "../../../StakeConnection"; import { readWindowLengths, WindowLengthsAccount, -} from "../vote_weight_window_lengths"; +} from "../../../vote_weight_window_lengths"; async function main() { const connection = new Connection(RPC_NODE); @@ -25,7 +24,6 @@ async function main() { const stakeConnection = await StakeConnection.createStakeConnection( connection, provider.wallet as Wallet, - STAKING_ADDRESS, ); console.log("VOTE_WEIGHT_WINDOW_LENGTHS:", VOTE_WEIGHT_WINDOW_LENGTHS); @@ -47,7 +45,7 @@ async function main() { ); console.log("windowLengthsAccount.getWindowLengthCount():", windowLengthsAccount.getWindowLengthCount()); console.log("windowLengthsAccount.voteWeightWindowLengths.nextIndex:", windowLengthsAccount.voteWeightWindowLengths.nextIndex); - console.log("windowLengthsAccount.getLastWindowLength().value.toString():", windowLengthsAccount.getLastWindowLength().value.toString()); + console.log("windowLengthsAccount.getLastWindowLength().value.toString():", windowLengthsAccount.getLastWindowLength()?.value.toString()); } main(); diff --git a/solana/app/deploy/064_fetchProposalAccountData.ts b/solana/app/deploy/devnet/tests/24_fetchProposalAccountData.ts similarity index 73% rename from solana/app/deploy/064_fetchProposalAccountData.ts rename to solana/app/deploy/devnet/tests/24_fetchProposalAccountData.ts index bb4492c0..b72f9568 100644 --- a/solana/app/deploy/064_fetchProposalAccountData.ts +++ b/solana/app/deploy/devnet/tests/24_fetchProposalAccountData.ts @@ -1,12 +1,11 @@ -// Usage: npx ts-node app/deploy/064_fetchProposalAccountData.ts +// Usage: npx ts-node app/deploy/devnet/tests/24_fetchProposalAccountData.ts -import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; -import { StakeConnection } from "../StakeConnection"; -import { STAKING_ADDRESS } from "../constants"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; +import { StakeConnection } from "../../../StakeConnection"; +import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "../constants"; import { ethers } from "ethers"; +import input from "@inquirer/input"; async function main() { try { @@ -17,15 +16,14 @@ async function main() { {}, ); - const proposalId = await input({ message: "Enter the proposal id:" }); - const proposalIdHex = BigInt(proposalId).toString(16).padStart(64, "0"); + const inputProposalId = await input({ message: "Enter the proposal id:" }); + const proposalIdHex = BigInt(inputProposalId).toString(16).padStart(64, "0"); // console.log("proposalIdHex:", proposalIdHex); const proposalIdArray = Buffer.from(proposalIdHex, "hex"); const stakeConnection = await StakeConnection.createStakeConnection( connection, provider.wallet as Wallet, - STAKING_ADDRESS, ); const { proposalAccountData } = diff --git a/solana/app/deploy/065_fetchSpokeMessageExecutor.ts b/solana/app/deploy/devnet/tests/25_fetchSpokeMessageExecutor.ts similarity index 86% rename from solana/app/deploy/065_fetchSpokeMessageExecutor.ts rename to solana/app/deploy/devnet/tests/25_fetchSpokeMessageExecutor.ts index 7cf237e2..aae9e6c4 100644 --- a/solana/app/deploy/065_fetchSpokeMessageExecutor.ts +++ b/solana/app/deploy/devnet/tests/25_fetchSpokeMessageExecutor.ts @@ -1,18 +1,15 @@ -// Usage: npx ts-node app/deploy/065_fetchSpokeMessageExecutor.ts +// Usage: npx ts-node app/deploy/devnet/tests/25_fetchSpokeMessageExecutor.ts import { Wallet, AnchorProvider, utils } from "@coral-xyz/anchor"; import { Connection, PublicKey } from "@solana/web3.js"; import * as wasm from "@wormhole/staking-wasm"; import { DEPLOYER_AUTHORITY_KEYPAIR, - RPC_NODE -} from "./devnet_consts"; -import { - STAKING_ADDRESS, HUB_CHAIN_ID, hubSolanaMessageDispatcherPublicKey, + RPC_NODE, } from "../constants"; -import { StakeConnection } from "../StakeConnection"; +import { StakeConnection } from "../../../StakeConnection"; async function main() { const connection = new Connection(RPC_NODE); @@ -24,7 +21,6 @@ async function main() { const stakeConnection = await StakeConnection.createStakeConnection( connection, provider.wallet as Wallet, - STAKING_ADDRESS, ); console.log("HUB_CHAIN_ID:", HUB_CHAIN_ID); diff --git a/solana/app/deploy/051_tx_list.ts b/solana/app/deploy/devnet/tests/31_tx_list.ts similarity index 84% rename from solana/app/deploy/051_tx_list.ts rename to solana/app/deploy/devnet/tests/31_tx_list.ts index 232131c3..61d01f94 100644 --- a/solana/app/deploy/051_tx_list.ts +++ b/solana/app/deploy/devnet/tests/31_tx_list.ts @@ -1,8 +1,8 @@ -// Usage: npx ts-node app/deploy/051_tx_list.ts +// Usage: npx ts-node app/deploy/devnet/tests/31_tx_list.ts import { Connection } from "@solana/web3.js"; -import { RPC_NODE } from "./devnet_consts"; -import { getProgramTransactions } from "../utils/parse_transactions"; +import { RPC_NODE } from "../constants"; +import { getProgramTransactions } from "../../../helpers/utils/parse_transactions"; async function main() { const connection = new Connection(RPC_NODE, "confirmed"); diff --git a/solana/app/deploy/052_tx_events.ts b/solana/app/deploy/devnet/tests/32_tx_events.ts similarity index 87% rename from solana/app/deploy/052_tx_events.ts rename to solana/app/deploy/devnet/tests/32_tx_events.ts index 3b92571d..af8b10f0 100644 --- a/solana/app/deploy/052_tx_events.ts +++ b/solana/app/deploy/devnet/tests/32_tx_events.ts @@ -1,11 +1,11 @@ -// Usage: npx ts-node app/deploy/052_tx_events.ts +// Usage: npx ts-node app/deploy/devnet/tests/32_tx_events.ts import { Connection } from "@solana/web3.js"; -import { RPC_NODE } from "./devnet_consts"; +import { RPC_NODE } from "../constants"; import { getProgramTransactions, printTransactionEvents, -} from "../utils/parse_transactions"; +} from "../../../helpers/utils/parse_transactions"; async function main() { const connection = new Connection(RPC_NODE, "confirmed"); diff --git a/solana/app/deploy/053_tx_details.ts b/solana/app/deploy/devnet/tests/33_tx_details.ts similarity index 85% rename from solana/app/deploy/053_tx_details.ts rename to solana/app/deploy/devnet/tests/33_tx_details.ts index 1630e3f1..cc24c3f6 100644 --- a/solana/app/deploy/053_tx_details.ts +++ b/solana/app/deploy/devnet/tests/33_tx_details.ts @@ -1,11 +1,11 @@ -// Usage: npx ts-node app/deploy/053_tx_details.ts +// Usage: npx ts-node app/deploy/devnet/tests/33_tx_details.ts import { Connection } from "@solana/web3.js"; -import { RPC_NODE } from "./devnet_consts"; +import { RPC_NODE } from "../constants"; import { getProgramTransactions, printTransactionDetails, -} from "../utils/parse_transactions"; +} from "../../../helpers/utils/parse_transactions"; async function main() { const connection = new Connection(RPC_NODE, "confirmed"); diff --git a/solana/app/deploy/bridge-script.ts b/solana/app/deploy/devnet/tests/bridge-script.ts similarity index 95% rename from solana/app/deploy/bridge-script.ts rename to solana/app/deploy/devnet/tests/bridge-script.ts index 074c3606..5c0eb4de 100644 --- a/solana/app/deploy/bridge-script.ts +++ b/solana/app/deploy/devnet/tests/bridge-script.ts @@ -1,4 +1,4 @@ -// Usage: npx ts-node app/deploy/bridge-script.ts +// Usage: npx ts-node app/deploy/devnet/tests/bridge-script.ts import { EthCallData, @@ -7,7 +7,6 @@ import { QueryRequest, signaturesToEvmStruct, QueryResponse, - QueryProxyQueryResponse, signaturesToSolanaArray, } from "@wormhole-foundation/wormhole-query-sdk"; import axios from "axios"; @@ -15,17 +14,15 @@ import { ethers } from "ethers"; import select from "@inquirer/select"; import input from "@inquirer/input"; import "dotenv/config"; - import { Keypair } from "@solana/web3.js"; import { Connection } from "@solana/web3.js"; import { - CORE_BRIDGE_ADDRESS, - HUB_CHAIN_ID, + CORE_BRIDGE_PID, HUB_PROPOSAL_METADATA_ADDRESS, + RPC_NODE, } from "../constants"; -import { RPC_NODE } from "./devnet_consts"; -import { getWormholeBridgeData } from "../helpers/wormholeBridgeConfig"; -import { deriveGuardianSetKey } from "../helpers/guardianSet"; +import { getWormholeBridgeData } from "../../../helpers/wormholeBridgeConfig"; +import { deriveGuardianSetKey } from "../../../helpers/guardianSet"; const API_KEY = process.env.WORMHOLE_API_KEY as string; @@ -76,11 +73,11 @@ const scripts: { const connection = new Connection(RPC_NODE); - const info = await getWormholeBridgeData(connection, CORE_BRIDGE_ADDRESS); + const info = await getWormholeBridgeData(connection, CORE_BRIDGE_PID); let guardianSetIndex = info.guardianSetIndex; const guardianSet = deriveGuardianSetKey( - CORE_BRIDGE_ADDRESS, + CORE_BRIDGE_PID, guardianSetIndex, ); diff --git a/solana/app/deploy/new_wallet.ts b/solana/app/deploy/devnet/tests/new_wallet.ts similarity index 91% rename from solana/app/deploy/new_wallet.ts rename to solana/app/deploy/devnet/tests/new_wallet.ts index 5e684d96..9c6a8c53 100644 --- a/solana/app/deploy/new_wallet.ts +++ b/solana/app/deploy/devnet/tests/new_wallet.ts @@ -1,4 +1,4 @@ -// Usage: npx ts-node app/deploy/new_wallet.ts +// Usage: npx ts-node app/deploy/devnet/tests/new_wallet.ts import { Keypair } from '@solana/web3.js'; import fs from 'fs'; diff --git a/solana/app/deploy/receive_message.ts b/solana/app/deploy/devnet/tests/receive_message.ts similarity index 92% rename from solana/app/deploy/receive_message.ts rename to solana/app/deploy/devnet/tests/receive_message.ts index ecf89348..1d3952f7 100644 --- a/solana/app/deploy/receive_message.ts +++ b/solana/app/deploy/devnet/tests/receive_message.ts @@ -1,4 +1,3 @@ -import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; import { AccountMeta, @@ -6,11 +5,14 @@ import { PublicKey, SystemProgram, } from "@solana/web3.js"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; -import { Staking } from "../../target/types/staking"; +import { + CORE_BRIDGE_PID, + DEPLOYER_AUTHORITY_KEYPAIR, + RPC_NODE +} from "../constants"; +import { Staking } from "../../../../target/types/staking"; import fs from "fs"; import BN from "bn.js"; -import { CORE_BRIDGE_PID } from "../../tests/executor"; import { hubSolanaMessageDispatcherPublicKey, HUB_CHAIN_ID, diff --git a/solana/app/deploy/transfer_W_token.ts b/solana/app/deploy/devnet/tests/transfer_W_token.ts similarity index 95% rename from solana/app/deploy/transfer_W_token.ts rename to solana/app/deploy/devnet/tests/transfer_W_token.ts index ea588a9f..bc9f28be 100644 --- a/solana/app/deploy/transfer_W_token.ts +++ b/solana/app/deploy/devnet/tests/transfer_W_token.ts @@ -1,4 +1,3 @@ -import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; import { PublicKey, Connection, Transaction } from "@solana/web3.js"; import { @@ -7,7 +6,7 @@ import { USER2_AUTHORITY_KEYPAIR, WORMHOLE_TOKEN, RPC_NODE, -} from "./devnet_consts"; +} from "../constants"; import { createTransferInstruction, getAssociatedTokenAddressSync, diff --git a/solana/app/deploy/022_updateGovernanceAuthority.ts b/solana/app/deploy/devnet/update/updateGovernanceAuthority.ts similarity index 82% rename from solana/app/deploy/022_updateGovernanceAuthority.ts rename to solana/app/deploy/devnet/update/updateGovernanceAuthority.ts index 808e59a8..2822323a 100644 --- a/solana/app/deploy/022_updateGovernanceAuthority.ts +++ b/solana/app/deploy/devnet/update/updateGovernanceAuthority.ts @@ -1,15 +1,13 @@ -// Usage: npx ts-node app/deploy/022_updateGovernanceAuthority.ts +// Usage: npx ts-node app/deploy/devnet/update/updateGovernanceAuthority.ts -import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; -import { DEPLOYER_AUTHORITY_KEYPAIR, GOVERNANCE_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; -import { Staking } from "../../target/types/staking"; +import { DEPLOYER_AUTHORITY_KEYPAIR, GOVERNANCE_AUTHORITY_KEYPAIR, RPC_NODE } from "../constants"; +import { Staking } from "../../../../target/types/staking"; import fs from "fs"; async function main() { try { - const DEBUG = true; const connection = new Connection(RPC_NODE); const provider = new AnchorProvider( connection, diff --git a/solana/app/deploy/021_updateHubProposalMetadata.ts b/solana/app/deploy/devnet/update/updateHubProposalMetadata.ts similarity index 68% rename from solana/app/deploy/021_updateHubProposalMetadata.ts rename to solana/app/deploy/devnet/update/updateHubProposalMetadata.ts index 2ba25191..76eab318 100644 --- a/solana/app/deploy/021_updateHubProposalMetadata.ts +++ b/solana/app/deploy/devnet/update/updateHubProposalMetadata.ts @@ -1,16 +1,17 @@ -// Usage: npx ts-node app/deploy/021_updateHubProposalMetadata.ts +// Usage: npx ts-node app/deploy/devnet/update/updateHubProposalMetadata.ts -import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; -import { Connection, PublicKey, SystemProgram } from "@solana/web3.js"; -import { hubProposalMetadataUint8Array } from "../constants"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "./devnet_consts"; -import { Staking } from "../../target/types/staking"; +import { Connection, PublicKey } from "@solana/web3.js"; +import { + DEPLOYER_AUTHORITY_KEYPAIR, + hubProposalMetadataUint8Array, + RPC_NODE, +} from "../constants"; +import { Staking } from "../../../../target/types/staking"; import fs from "fs"; async function main() { try { - const DEBUG = true; const connection = new Connection(RPC_NODE); const provider = new AnchorProvider( connection, diff --git a/solana/app/deploy/023_updateVestingAdmin.ts b/solana/app/deploy/devnet/update/updateVestingAdmin.ts similarity index 77% rename from solana/app/deploy/023_updateVestingAdmin.ts rename to solana/app/deploy/devnet/update/updateVestingAdmin.ts index 0ae3a7bd..b1e26704 100644 --- a/solana/app/deploy/023_updateVestingAdmin.ts +++ b/solana/app/deploy/devnet/update/updateVestingAdmin.ts @@ -1,10 +1,13 @@ -// Usage: npx ts-node app/deploy/023_updateVestingAdmin.ts +// Usage: npx ts-node app/deploy/devnet/update/updateVestingAdmin.ts -import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; -import { DEPLOYER_AUTHORITY_KEYPAIR, VESTING_ADMIN_KEYPAIR, RPC_NODE } from "./devnet_consts"; -import { Staking } from "../../target/types/staking"; +import { + DEPLOYER_AUTHORITY_KEYPAIR, + RPC_NODE, + VESTING_ADMIN_KEYPAIR, +} from "../constants"; +import { Staking } from "../../../../target/types/staking"; import fs from "fs"; async function main() { diff --git a/solana/app/deploy/073_claimVesting.ts b/solana/app/deploy/devnet/vesting/claimVesting.ts similarity index 91% rename from solana/app/deploy/073_claimVesting.ts rename to solana/app/deploy/devnet/vesting/claimVesting.ts index 2c0eaca2..94c4f50f 100644 --- a/solana/app/deploy/073_claimVesting.ts +++ b/solana/app/deploy/devnet/vesting/claimVesting.ts @@ -1,28 +1,23 @@ -// Usage: npx ts-node app/deploy/073_claimVesting.ts +// Usage: npx ts-node app/deploy/devnet/vesting/claimVesting.ts import { Wallet, AnchorProvider } from "@coral-xyz/anchor"; import { Connection, PublicKey, SystemProgram, - Transaction, } from "@solana/web3.js"; import { VESTING_ADMIN_KEYPAIR, USER_AUTHORITY_KEYPAIR, WORMHOLE_TOKEN, RPC_NODE, -} from "./devnet_consts"; -import { STAKING_ADDRESS } from "../constants"; -import { StakeConnection } from "../StakeConnection"; -import { WHTokenBalance } from "../whTokenBalance"; +} from "../constants"; +import { StakeConnection } from "../../../StakeConnection"; import BN from "bn.js"; -import { randomBytes } from "crypto"; import * as wasm from "@wormhole/staking-wasm"; import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, - createTransferCheckedInstruction, getAssociatedTokenAddressSync, } from "@solana/spl-token"; @@ -35,7 +30,6 @@ async function main() { const vesterStakeConnection = await StakeConnection.createStakeConnection( connection, vesterProvider.wallet as Wallet, - STAKING_ADDRESS, ); const confirm = async (signature: string): Promise => { diff --git a/solana/app/deploy/071_createVestingConfig.ts b/solana/app/deploy/devnet/vesting/createVestingConfig.ts similarity index 95% rename from solana/app/deploy/071_createVestingConfig.ts rename to solana/app/deploy/devnet/vesting/createVestingConfig.ts index bdcded91..642af294 100644 --- a/solana/app/deploy/071_createVestingConfig.ts +++ b/solana/app/deploy/devnet/vesting/createVestingConfig.ts @@ -1,4 +1,4 @@ -// Usage: npx ts-node app/deploy/071_createVestingConfig.ts +// Usage: npx ts-node app/deploy/devnet/vesting/createVestingConfig.ts import { Wallet, AnchorProvider } from "@coral-xyz/anchor"; import { @@ -12,10 +12,8 @@ import { USER_AUTHORITY_KEYPAIR, WORMHOLE_TOKEN, RPC_NODE, -} from "./devnet_consts"; -import { STAKING_ADDRESS } from "../constants"; -import { StakeConnection } from "../StakeConnection"; -import { WHTokenBalance } from "../whTokenBalance"; +} from "../constants"; +import { StakeConnection } from "../../../StakeConnection"; import BN from "bn.js"; import { randomBytes } from "crypto"; import * as wasm from "@wormhole/staking-wasm"; @@ -36,7 +34,6 @@ async function main() { const stakeConnection = await StakeConnection.createStakeConnection( connection, provider.wallet as Wallet, - STAKING_ADDRESS, ); const confirm = async (signature: string): Promise => { diff --git a/solana/app/deploy/072_delegateWithVest.ts b/solana/app/deploy/devnet/vesting/delegateWithVest.ts similarity index 76% rename from solana/app/deploy/072_delegateWithVest.ts rename to solana/app/deploy/devnet/vesting/delegateWithVest.ts index f953285c..342678d2 100644 --- a/solana/app/deploy/072_delegateWithVest.ts +++ b/solana/app/deploy/devnet/vesting/delegateWithVest.ts @@ -1,4 +1,4 @@ -// Usage: npx ts-node app/deploy/072_delegateWithVest.ts +// Usage: npx ts-node app/deploy/devnet/vesting/delegateWithVest.ts import { Wallet, AnchorProvider } from "@coral-xyz/anchor"; import { @@ -8,10 +8,9 @@ import { import { USER_AUTHORITY_KEYPAIR, RPC_NODE, -} from "./devnet_consts"; -import { STAKING_ADDRESS } from "../constants"; -import { StakeConnection } from "../StakeConnection"; -import { WHTokenBalance } from "../whTokenBalance"; +} from "../constants"; +import { StakeConnection } from "../../../StakeConnection"; +import { WHTokenBalance } from "../../../whTokenBalance"; async function main() { const vester = USER_AUTHORITY_KEYPAIR; @@ -21,7 +20,6 @@ async function main() { const vesterStakeConnection = await StakeConnection.createStakeConnection( connection, vesterProvider.wallet as Wallet, - STAKING_ADDRESS, ); const config = new PublicKey( diff --git a/solana/app/deploy/devnet_consts.ts b/solana/app/deploy/devnet_consts.ts deleted file mode 100644 index dd9699b3..00000000 --- a/solana/app/deploy/devnet_consts.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { PublicKey } from "@solana/web3.js"; -import { homedir } from "os"; -import { loadKeypair } from "../../tests/utils/keys"; - -export const DEPLOYER_AUTHORITY_PATH = "/.config/solana/deployer.json"; -export const DEPLOYER_AUTHORITY_KEYPAIR = loadKeypair( - homedir() + DEPLOYER_AUTHORITY_PATH, -); - -export const GOVERNANCE_AUTHORITY_PATH = "/.config/solana/governanceAuthority.json"; -export const GOVERNANCE_AUTHORITY_KEYPAIR = loadKeypair( - homedir() + GOVERNANCE_AUTHORITY_PATH, -); - -export const VESTING_ADMIN_PATH = "/.config/solana/vestingAdmin.json"; -export const VESTING_ADMIN_KEYPAIR = loadKeypair( - homedir() + VESTING_ADMIN_PATH, -); - -export const USER_AUTHORITY_PATH = "/.config/solana/user.json"; -export const USER_AUTHORITY_KEYPAIR = loadKeypair( - homedir() + USER_AUTHORITY_PATH, -); - -export const USER2_AUTHORITY_PATH = "/.config/solana/user2.json"; -export const USER2_AUTHORITY_KEYPAIR = loadKeypair( - homedir() + USER2_AUTHORITY_PATH, -); - -export const WORMHOLE_TOKEN = new PublicKey( - "Exne2kdeGToBnC2WVSdt1gLy6fjnNftbPtsCPx8AuL7V", -); - -export const RPC_NODE = "https://api.devnet.solana.com"; - -export const AIRLOCK_PDA_ADDRESS = new PublicKey( - "2ejzW2eFPedskg1KcrjcFs9g1JorRVcMes1TBPpGbhdy", -); - -export const VOTE_WEIGHT_WINDOW_LENGTHS = 10 * 60; // 10 minutes diff --git a/solana/app/deploy/mainnet_beta.ts b/solana/app/deploy/mainnet/mainnet_beta.ts similarity index 100% rename from solana/app/deploy/mainnet_beta.ts rename to solana/app/deploy/mainnet/mainnet_beta.ts diff --git a/solana/app/e2e/01_createProposeWithSolanaExecution.ts b/solana/app/e2e/01_createProposeWithSolanaExecution.ts index 65cbe3a4..dd70fbfe 100644 --- a/solana/app/e2e/01_createProposeWithSolanaExecution.ts +++ b/solana/app/e2e/01_createProposeWithSolanaExecution.ts @@ -3,11 +3,6 @@ import { ethers } from "ethers"; import * as fs from "fs"; import "dotenv/config"; -import { - HUB_SOLANA_MESSAGE_DISPATCHER_ADDRESS, - HUB_GOVERNOR_ADDRESS, - HUB_CHAIN_ID, -} from "../constants"; import { Connection } from "@solana/web3.js"; import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; import { ExternalProgram } from "./external_program/idl/external_program"; @@ -16,7 +11,10 @@ import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE, AIRLOCK_PDA_ADDRESS, -} from "../deploy/devnet_consts"; + HUB_SOLANA_MESSAGE_DISPATCHER_ADDRESS, + HUB_GOVERNOR_ADDRESS, + HUB_CHAIN_ID, +} from "../deploy/devnet/constants"; import { v4 as uuidv4 } from "uuid"; // Define the ABI types diff --git a/solana/app/e2e/02_addProposal.ts b/solana/app/e2e/02_addProposal.ts index 20ce2105..40faf0af 100644 --- a/solana/app/e2e/02_addProposal.ts +++ b/solana/app/e2e/02_addProposal.ts @@ -14,14 +14,14 @@ import "dotenv/config"; import { HUB_CHAIN_ID, HUB_PROPOSAL_METADATA_ADDRESS, - STAKING_ADDRESS, - CORE_BRIDGE_ADDRESS, -} from "../constants"; -import * as anchor from "@coral-xyz/anchor"; + CORE_BRIDGE_PID, + DEPLOYER_AUTHORITY_KEYPAIR, + RPC_NODE, +} from "../deploy/devnet/constants"; + import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; -import { Connection, Keypair } from "@solana/web3.js"; +import { Connection } from "@solana/web3.js"; import { StakeConnection } from "../StakeConnection"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "../deploy/devnet_consts"; import { getWormholeBridgeData } from "../helpers/wormholeBridgeConfig"; import * as fs from "fs"; @@ -118,7 +118,7 @@ async function getProposalMetadata( data: encodeCalldata(encodedSignature, encodedParameters), }; - const latestFinalizedBlock = await getLatestFinalizedBlock(rpcUrl); + const latestFinalizedBlock = await getLatestFinalizedBlock(rpcUrl!); console.log( "latestFinalizedBlock:", parseInt(latestFinalizedBlock.toString(), 16), @@ -154,7 +154,6 @@ async function addProposal() { const stakeConnection = await StakeConnection.createStakeConnection( connection, provider.wallet as Wallet, - STAKING_ADDRESS, ); const proposalId = await input({ message: "Enter the proposal id:" }); @@ -169,7 +168,7 @@ async function addProposal() { while (true) { const latestFinalizedBlockInt = parseInt( - (await getLatestFinalizedBlock(rpcUrl)).toString(), + (await getLatestFinalizedBlock(rpcUrl!)).toString(), 16, ); console.log("Latest finalized block:", latestFinalizedBlockInt); @@ -203,7 +202,7 @@ async function addProposal() { sepoliaEthProposalResponse.signatures, ); - const info = await getWormholeBridgeData(connection, CORE_BRIDGE_ADDRESS); + const info = await getWormholeBridgeData(connection, CORE_BRIDGE_PID); const guardianSetIndex = info.guardianSetIndex; await stakeConnection.addProposal( diff --git a/solana/app/e2e/03_castVote.ts b/solana/app/e2e/03_castVote.ts index 54ee550f..f3f8dfa0 100644 --- a/solana/app/e2e/03_castVote.ts +++ b/solana/app/e2e/03_castVote.ts @@ -1,12 +1,12 @@ // Usage: npx ts-node app/e2e/03_castVote.ts -import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; import { StakeConnection } from "../StakeConnection"; -import { STAKING_ADDRESS } from "../constants"; -import { USER2_AUTHORITY_KEYPAIR, RPC_NODE } from "../deploy/devnet_consts"; -import BN from "bn.js"; +import { + USER2_AUTHORITY_KEYPAIR, + RPC_NODE, +} from "../deploy/devnet/constants"; import { WHTokenBalance } from "../whTokenBalance"; import input from "@inquirer/input"; @@ -27,7 +27,6 @@ async function castVote() { const user2StakeConnection = await StakeConnection.createStakeConnection( connection, user2Provider.wallet as Wallet, - STAKING_ADDRESS, ); await user2StakeConnection.castVote( diff --git a/solana/app/e2e/04_crossChainVoteSolana.ts b/solana/app/e2e/04_crossChainVoteSolana.ts index 3ec11e62..fc171ba4 100644 --- a/solana/app/e2e/04_crossChainVoteSolana.ts +++ b/solana/app/e2e/04_crossChainVoteSolana.ts @@ -3,7 +3,6 @@ import { ethers } from "ethers"; import * as fs from "fs"; import "dotenv/config"; -import { PublicKey } from "@solana/web3.js"; import axios from "axios"; import { PerChainQueryRequest, @@ -11,7 +10,6 @@ import { QueryRequest, QueryResponse, SolanaPdaQueryRequest, - SolanaPdaQueryResponse, signaturesToEvmStruct, } from "@wormhole-foundation/wormhole-query-sdk"; import { @@ -20,7 +18,7 @@ import { HUB_SOLANA_SPOKE_VOTE_DECODER_ADDRESS, HUB_VOTE_POOL_ADDRESS, HUB_CHAIN_ID, -} from "../constants"; +} from "../deploy/devnet/constants"; import * as wasm from "@wormhole/staking-wasm"; import input from "@inquirer/input"; @@ -76,7 +74,8 @@ async function getSolanaQueryResponse(): Promise<{ ).data; // console.log("queryResponse: ", queryResponse); - // const queryResponseHex = QueryResponse.from(Buffer.from(queryResponse.bytes, "hex")); + const queryResponseHex = QueryResponse.from(Buffer.from(queryResponse.bytes, "hex")); + console.log("queryResponseHex: ", queryResponseHex); const bytes = "0x" + queryResponse["bytes"]; const signatures = queryResponse["signatures"]; diff --git a/solana/app/e2e/05_proposalQueue.ts b/solana/app/e2e/05_proposalQueue.ts index 6c19faf8..c2fca514 100644 --- a/solana/app/e2e/05_proposalQueue.ts +++ b/solana/app/e2e/05_proposalQueue.ts @@ -3,12 +3,11 @@ import { ethers } from "ethers"; import * as fs from "fs"; import "dotenv/config"; -import { signaturesToEvmStruct } from "@wormhole-foundation/wormhole-query-sdk"; import { HUB_SOLANA_MESSAGE_DISPATCHER_ADDRESS, HUB_GOVERNOR_ADDRESS, HUB_CHAIN_ID, -} from "../constants"; +} from "../deploy/devnet/constants"; import input from "@inquirer/input"; const HubGovernorAbiPath = "./app/e2e/abi/HubGovernor.json"; diff --git a/solana/app/e2e/06_proposalExecute.ts b/solana/app/e2e/06_proposalExecute.ts index 5a660137..73d60ba1 100644 --- a/solana/app/e2e/06_proposalExecute.ts +++ b/solana/app/e2e/06_proposalExecute.ts @@ -3,12 +3,11 @@ import { ethers } from "ethers"; import * as fs from "fs"; import "dotenv/config"; -import { signaturesToEvmStruct } from "@wormhole-foundation/wormhole-query-sdk"; import { HUB_SOLANA_MESSAGE_DISPATCHER_ADDRESS, HUB_GOVERNOR_ADDRESS, HUB_CHAIN_ID, -} from "../constants"; +} from "../deploy/devnet/constants"; import input from "@inquirer/input"; const HubGovernorAbiPath = "./app/e2e/abi/HubGovernor.json"; diff --git a/solana/app/e2e/external_program/initializeConfigPDA.ts b/solana/app/e2e/external_program/initializeConfigPDA.ts index 4cf48cf9..71f42ac5 100644 --- a/solana/app/e2e/external_program/initializeConfigPDA.ts +++ b/solana/app/e2e/external_program/initializeConfigPDA.ts @@ -1,11 +1,10 @@ -import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; import { Connection, PublicKey, SystemProgram } from "@solana/web3.js"; import { USER2_AUTHORITY_KEYPAIR, RPC_NODE, AIRLOCK_PDA_ADDRESS, -} from "../../deploy/devnet_consts"; +} from "../../deploy/devnet/constants"; import { ExternalProgram } from "./idl/external_program"; import externalProgramIdl from "./idl/external_program.json"; diff --git a/solana/app/helpers/utils/lookup_table.ts b/solana/app/helpers/utils/lookup_table.ts new file mode 100644 index 00000000..2cae909b --- /dev/null +++ b/solana/app/helpers/utils/lookup_table.ts @@ -0,0 +1,62 @@ +import { + TOKEN_PROGRAM_ID, +} from "@solana/spl-token"; +import { + PublicKey, + SystemProgram, + AddressLookupTableProgram, + ComputeBudgetProgram, + SYSVAR_RENT_PUBKEY, + VersionedTransaction, + TransactionMessage, +} from "@solana/web3.js"; +import * as anchor from "@coral-xyz/anchor"; +import * as wasm from "@wormhole/staking-wasm"; + +function getConfigAccount(programId: PublicKey): PublicKey { + return PublicKey.findProgramAddressSync( + [anchor.utils.bytes.utf8.encode(wasm.Constants.CONFIG_SEED())], + programId, + )[0]; +} + +export async function initAddressLookupTable( + provider: anchor.AnchorProvider, + mint: PublicKey, + stakingPID: PublicKey, +) { + const configAccount = getConfigAccount(stakingPID); + + const [loookupTableInstruction, lookupTableAddress] = + AddressLookupTableProgram.createLookupTable({ + authority: provider.publicKey, + payer: provider.publicKey, + recentSlot: await provider.connection.getSlot(), + }); + const extendInstruction = AddressLookupTableProgram.extendLookupTable({ + payer: provider.publicKey, + authority: provider.publicKey, + lookupTable: lookupTableAddress, + addresses: [ + ComputeBudgetProgram.programId, + SystemProgram.programId, + stakingPID, + mint, + configAccount, + SYSVAR_RENT_PUBKEY, + TOKEN_PROGRAM_ID, + ], + }); + const createLookupTableTx = new VersionedTransaction( + new TransactionMessage({ + instructions: [loookupTableInstruction, extendInstruction], + payerKey: provider.publicKey, + recentBlockhash: (await provider.connection.getLatestBlockhash()) + .blockhash, + }).compileToV0Message(), + ); + await provider.sendAndConfirm(createLookupTableTx, [], { + skipPreflight: true, + }); + return lookupTableAddress; +} diff --git a/solana/app/utils/parse_transactions.ts b/solana/app/helpers/utils/parse_transactions.ts similarity index 100% rename from solana/app/utils/parse_transactions.ts rename to solana/app/helpers/utils/parse_transactions.ts diff --git a/solana/app/index.ts b/solana/app/index.ts index 6f0c89c7..98a235ba 100644 --- a/solana/app/index.ts +++ b/solana/app/index.ts @@ -1,3 +1,2 @@ export { StakeAccount, StakeConnection } from "./StakeConnection"; -export * from "./constants"; export { WH_TOKEN_DECIMALS, WHTokenBalance } from "./whTokenBalance"; diff --git a/solana/tests/api_test.ts b/solana/tests/api_test.ts index 51996f2d..ca6e686c 100644 --- a/solana/tests/api_test.ts +++ b/solana/tests/api_test.ts @@ -29,8 +29,8 @@ import { import { StakeConnection, WHTokenBalance, - TEST_CHECKPOINTS_ACCOUNT_LIMIT, } from "../app"; +import { TEST_CHECKPOINTS_ACCOUNT_LIMIT } from "./utils/constants"; import { CheckpointAccount } from "../app/checkpoints"; import crypto from "crypto"; import { diff --git a/solana/tests/config.ts b/solana/tests/config.ts index 9972b632..120dbe5d 100644 --- a/solana/tests/config.ts +++ b/solana/tests/config.ts @@ -12,16 +12,16 @@ import BN from "bn.js"; import path from "path"; import { StakeConnection, - TEST_CHECKPOINTS_ACCOUNT_LIMIT, - WH_TOKEN_DECIMALS, WHTokenBalance, + WH_TOKEN_DECIMALS, } from "../app"; import { - CORE_BRIDGE_ADDRESS, + CORE_BRIDGE_PID, HUB_CHAIN_ID, hubProposalMetadataUint8Array, -} from "../app/constants"; -import { StakeAccountMetadata } from "../app/StakeConnection.ts"; + TEST_CHECKPOINTS_ACCOUNT_LIMIT, +} from "./utils/constants"; +import { StakeAccountMetadata } from "../app/StakeConnection"; import { readWindowLengths, WindowLengthsAccount, @@ -234,7 +234,7 @@ describe("config", async () => { ); assert.equal( spokeMetadataCollectorAccountData.wormholeCore.toString("hex"), - CORE_BRIDGE_ADDRESS.toString("hex"), + CORE_BRIDGE_PID.toString("hex"), ); }); @@ -344,7 +344,7 @@ describe("config", async () => { ); assert.equal( spokeMetadataCollectorAccountData.wormholeCore.toString("hex"), - CORE_BRIDGE_ADDRESS.toString("hex"), + CORE_BRIDGE_PID.toString("hex"), ); }); @@ -434,7 +434,6 @@ describe("config", async () => { const samConnection = await StakeConnection.createStakeConnection( program.provider.connection, new Wallet(sam), - program.programId, ); await samConnection.program.provider.connection.requestAirdrop( @@ -467,7 +466,6 @@ describe("config", async () => { const vestingAdminConnection = await StakeConnection.createStakeConnection( program.provider.connection, new Wallet(vestingAdminKeypair), - program.programId, ); await vestingAdminConnection.program.provider.connection.requestAirdrop( diff --git a/solana/tests/executor.ts b/solana/tests/executor.ts index bbf0406a..60b19482 100644 --- a/solana/tests/executor.ts +++ b/solana/tests/executor.ts @@ -26,29 +26,24 @@ import { mocks } from "@wormhole-foundation/sdk-definitions/testing"; import { SolanaWormholeCore, utils as coreUtils, - derivePostedVaaKey, } from "@wormhole-foundation/sdk-solana-core"; import { SolanaSendSigner } from "@wormhole-foundation/sdk-solana"; import { signAndSendWait } from "@wormhole-foundation/sdk-connect"; -import { Chain, contracts } from "@wormhole-foundation/sdk-base"; +import { Chain } from "@wormhole-foundation/sdk-base"; import { AnchorError, Program, utils } from "@coral-xyz/anchor"; -import { ExternalProgram } from "./artifacts/external_program.ts"; +import { ExternalProgram } from "./artifacts/external_program"; import externalProgramIdl from "./artifacts/external_program.json"; import BN from "bn.js"; import * as wasm from "@wormhole/staking-wasm"; import { readWindowLengths, WindowLengthsAccount, -} from "../app/vote_weight_window_lengths.ts"; +} from "../app/vote_weight_window_lengths"; +import { CORE_BRIDGE_PID } from "./utils/constants"; // Define the port number for the test const portNumber = getPortNumber(path.basename(__filename)); -// Constants -export const CORE_BRIDGE_PID = new PublicKey( - contracts.coreBridge.get("Testnet", "Solana")!, -); - export const GUARDIAN_KEY = "cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0"; export const MOCK_GUARDIANS = new mocks.MockGuardians(0, [GUARDIAN_KEY]); diff --git a/solana/tests/utils/api_utils.ts b/solana/tests/utils/api_utils.ts index 09be7f19..a835aa38 100644 --- a/solana/tests/utils/api_utils.ts +++ b/solana/tests/utils/api_utils.ts @@ -1,10 +1,10 @@ -import { StakeAccount, StakeConnection } from "../../app/StakeConnection"; +import { StakeConnection } from "../../app/StakeConnection"; import { PublicKey } from "@solana/web3.js"; import { WHTokenBalance } from "../../app"; import { HUB_CHAIN_ID, HUB_PROPOSAL_METADATA_ADDRESS, -} from "../../app/constants"; +} from "./constants"; import assert from "assert"; import { QueryRequest, @@ -42,8 +42,13 @@ export async function assertBalanceMatches( owner: PublicKey, expected: WHTokenBalance, ) { - const stakeAccountCheckpointsAddress = - await stakeConnection.getStakeAccountCheckpointsAddress(owner); + let stakeAccountMetadataAddress = + await stakeConnection.getStakeMetadataAddress(owner); + let stakeAccountCheckpointsAddress = + await stakeConnection.getStakeAccountCheckpointsAddressByMetadata( + stakeAccountMetadataAddress, + false, + ); let stakeAccount = await stakeConnection.loadStakeAccount( stakeAccountCheckpointsAddress, ); diff --git a/solana/tests/utils/before.ts b/solana/tests/utils/before.ts index d08b5943..ba85aefc 100644 --- a/solana/tests/utils/before.ts +++ b/solana/tests/utils/before.ts @@ -26,16 +26,17 @@ import { StakeConnection, WHTokenBalance, WH_TOKEN_DECIMALS, - CHECKPOINTS_ACCOUNT_LIMIT, - TEST_CHECKPOINTS_ACCOUNT_LIMIT, } from "../../app"; import { GlobalConfig } from "../../app/StakeConnection"; -import { createMint, initAddressLookupTable } from "./utils"; +import { createMint } from "./utils"; +import { initAddressLookupTable } from "../../app/helpers/utils/lookup_table"; import { loadKeypair } from "./keys"; import { HUB_CHAIN_ID, hubProposalMetadataUint8Array, -} from "../../app/constants"; + CHECKPOINTS_ACCOUNT_LIMIT, + TEST_CHECKPOINTS_ACCOUNT_LIMIT, +} from "./constants"; export const ANCHOR_CONFIG_PATH = "./Anchor.toml"; export interface AnchorConfig { @@ -343,7 +344,6 @@ export async function newUserStakeConnection( const userStakeConnection = await StakeConnection.createStakeConnection( connection, provider.wallet as Wallet, - new PublicKey(config.programs.localnet.staking), ); await transferSolFromValidatorWallet( @@ -438,8 +438,9 @@ export async function standardSetup( const lookupTableAddress = await initAddressLookupTable( provider, whMintAccount.publicKey, + program.programId, ); - // console.log("Lookup table address: ", lookupTableAddress.toBase58()); + // console.log("Lookup table address: ", lookupTableAddress.toBase58()); await program.methods .initializeSpokeMetadataCollector( @@ -475,7 +476,7 @@ export async function standardSetup( const stakeConnection = await StakeConnection.createStakeConnection( connection, provider.wallet as Wallet, - new PublicKey(config.programs.localnet.staking), + lookupTableAddress, ); return { controller, stakeConnection }; diff --git a/solana/tests/utils/constants.ts b/solana/tests/utils/constants.ts new file mode 100644 index 00000000..f0a95f37 --- /dev/null +++ b/solana/tests/utils/constants.ts @@ -0,0 +1,22 @@ +import { contracts } from "@wormhole-foundation/sdk-base"; +import { PublicKey } from "@solana/web3.js"; + +/// Wormhole Hub Proposal Metadata Contract (sepolia ethereum address) +export const HUB_PROPOSAL_METADATA_ADDRESS = + "0x1a3e5624769c3dc9106347a239523e4a08d85c38"; +export const hubProposalMetadataUint8Array = new Uint8Array( + HUB_PROPOSAL_METADATA_ADDRESS.slice(2) + .toLowerCase() + .match(/.{1,2}/g) + ?.map((byte) => parseInt(byte, 16)), +); + +/// Wormhole Hub Chain ID +export const HUB_CHAIN_ID = 10002; // SEPOLIA + +export const CHECKPOINTS_ACCOUNT_LIMIT = 654998; +export const TEST_CHECKPOINTS_ACCOUNT_LIMIT = 15; + +export const CORE_BRIDGE_PID = new PublicKey( + contracts.coreBridge.get("Testnet", "Solana")!, // 3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5 +); diff --git a/solana/tests/utils/utils.ts b/solana/tests/utils/utils.ts index ebc282df..5a925769 100644 --- a/solana/tests/utils/utils.ts +++ b/solana/tests/utils/utils.ts @@ -9,25 +9,10 @@ import { Keypair, Transaction, SystemProgram, - AddressLookupTableProgram, - ComputeBudgetProgram, - SYSVAR_RENT_PUBKEY, - VersionedTransaction, - TransactionMessage, } from "@solana/web3.js"; import * as anchor from "@coral-xyz/anchor"; import { AnchorError } from "@coral-xyz/anchor"; import assert from "assert"; -import * as wasm from "@wormhole/staking-wasm"; -import { Staking } from "../../target/types/staking"; -import { STAKING_ADDRESS } from "../../app"; - -export function getConfigAccount(programId: PublicKey): PublicKey { - return PublicKey.findProgramAddressSync( - [anchor.utils.bytes.utf8.encode(wasm.Constants.CONFIG_SEED())], - programId, - )[0]; -} /** * Creates new spl-token at a random keypair @@ -71,46 +56,6 @@ export async function createMint( }); } -export async function initAddressLookupTable( - provider: anchor.AnchorProvider, - mint: PublicKey, -) { - const configAccount = getConfigAccount(STAKING_ADDRESS); - - const [loookupTableInstruction, lookupTableAddress] = - AddressLookupTableProgram.createLookupTable({ - authority: provider.publicKey, - payer: provider.publicKey, - recentSlot: await provider.connection.getSlot(), - }); - const extendInstruction = AddressLookupTableProgram.extendLookupTable({ - payer: provider.publicKey, - authority: provider.publicKey, - lookupTable: lookupTableAddress, - addresses: [ - ComputeBudgetProgram.programId, - SystemProgram.programId, - STAKING_ADDRESS, - mint, - configAccount, - SYSVAR_RENT_PUBKEY, - TOKEN_PROGRAM_ID, - ], - }); - const createLookupTableTx = new VersionedTransaction( - new TransactionMessage({ - instructions: [loookupTableInstruction, extendInstruction], - payerKey: provider.publicKey, - recentBlockhash: (await provider.connection.getLatestBlockhash()) - .blockhash, - }).compileToV0Message(), - ); - await provider.sendAndConfirm(createLookupTableTx, [], { - skipPreflight: true, - }); - return lookupTableAddress; -} - /** * Sends the rpc call and check whether the error message matches the provided string * @param rpcCall : anchor rpc call diff --git a/solana/tests/vesting.ts b/solana/tests/vesting.ts index bd6d0345..5268d9ee 100644 --- a/solana/tests/vesting.ts +++ b/solana/tests/vesting.ts @@ -385,7 +385,6 @@ describe("vesting", () => { ], stakeConnection.program.programId, )[0]; - vestingBalanceWithoutAccount = PublicKey.findProgramAddressSync( [ Buffer.from(wasm.Constants.VESTING_BALANCE_SEED()), diff --git a/solana/tests/voter_votes_test.ts b/solana/tests/voter_votes_test.ts index dcc103b7..1ad6bd97 100644 --- a/solana/tests/voter_votes_test.ts +++ b/solana/tests/voter_votes_test.ts @@ -4,13 +4,11 @@ import { getPortNumber, makeDefaultConfig, readAnchorConfig, - requestWHTokenAirdrop, standardSetup, } from "./utils/before"; import path from "path"; import { Keypair, PublicKey } from "@solana/web3.js"; import { StakeConnection, WHTokenBalance } from "../app"; -import { BN, Wallet } from "@coral-xyz/anchor"; import assert from "assert"; const portNumber = getPortNumber(path.basename(__filename)); From ab25355c5e9dd4793ac70e0bb9e68ccef820aaad Mon Sep 17 00:00:00 2001 From: zpoken <82594516+zpoken@users.noreply.github.com> Date: Wed, 5 Mar 2025 16:37:18 +0200 Subject: [PATCH 11/14] Apply yarn format --- solana/app/StakeConnection.ts | 16 +- solana/app/deploy/devnet/constants.ts | 6 +- .../initializeVoteWeightWindowLengths.ts | 10 +- .../devnet/tests/21_fetchGlobalConfig.ts | 15 +- .../tests/22_fetchSpokeMetadataCollector.ts | 9 +- .../tests/23_fetchVoteWeightWindowLengths.ts | 24 +- .../tests/24_fetchProposalAccountData.ts | 4 +- .../tests/25_fetchSpokeMessageExecutor.ts | 26 +- .../app/deploy/devnet/tests/bridge-script.ts | 5 +- solana/app/deploy/devnet/tests/new_wallet.ts | 10 +- .../deploy/devnet/tests/receive_message.ts | 2 +- .../update/updateGovernanceAuthority.ts | 6 +- .../update/updateHubProposalMetadata.ts | 5 +- .../app/deploy/devnet/vesting/claimVesting.ts | 21 +- .../devnet/vesting/createVestingConfig.ts | 20 +- .../deploy/devnet/vesting/delegateWithVest.ts | 14 +- solana/app/e2e/03_castVote.ts | 5 +- solana/app/e2e/04_crossChainVoteSolana.ts | 4 +- solana/app/helpers/utils/lookup_table.ts | 4 +- .../staking/src/contexts/cancel_vesting.rs | 4 +- .../programs/staking/src/contexts/finalize.rs | 4 +- .../staking/src/contexts/transfer_vesting.rs | 38 ++- .../staking/src/contexts/withdraw_surplus.rs | 4 +- solana/programs/staking/src/lib.rs | 25 +- solana/tests/api_test.ts | 60 ++-- solana/tests/config.ts | 6 +- solana/tests/utils/api_utils.ts | 5 +- solana/tests/utils/before.ts | 6 +- solana/tests/vesting.ts | 279 +++++++----------- 29 files changed, 320 insertions(+), 317 deletions(-) diff --git a/solana/app/StakeConnection.ts b/solana/app/StakeConnection.ts index e4f1497c..badd6da2 100644 --- a/solana/app/StakeConnection.ts +++ b/solana/app/StakeConnection.ts @@ -89,10 +89,7 @@ export class StakeConnection { connection: Connection, wallet: Wallet, ): Promise { - return await StakeConnection.createStakeConnection( - connection, - wallet, - ); + return await StakeConnection.createStakeConnection(connection, wallet); } /** Creates a program connection and loads the staking config @@ -752,9 +749,9 @@ export class StakeConnection { unoptimized?: boolean, ): Promise { const { proposalAccount } = await this.fetchProposalAccount(proposalId); - const networkType = this.provider.connection.rpcEndpoint.includes('mainnet') - ? 'Mainnet' - : 'Testnet'; + const networkType = this.provider.connection.rpcEndpoint.includes("mainnet") + ? "Mainnet" + : "Testnet"; const coreBridge = new PublicKey( contracts.coreBridge.get(networkType, "Solana"), // Testnet - 3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5 ); @@ -767,10 +764,7 @@ export class StakeConnection { .accountsPartial({ proposal: proposalAccount, guardianSignatures: guardianSignatures, - guardianSet: deriveGuardianSetKey( - coreBridge, - guardianSetIndex, - ), + guardianSet: deriveGuardianSetKey(coreBridge, guardianSetIndex), }); if (unoptimized) { diff --git a/solana/app/deploy/devnet/constants.ts b/solana/app/deploy/devnet/constants.ts index 21593863..db64349e 100644 --- a/solana/app/deploy/devnet/constants.ts +++ b/solana/app/deploy/devnet/constants.ts @@ -64,7 +64,8 @@ export const DEPLOYER_AUTHORITY_KEYPAIR = loadKeypair( homedir() + DEPLOYER_AUTHORITY_PATH, ); -export const GOVERNANCE_AUTHORITY_PATH = "/.config/solana/governanceAuthority.json"; +export const GOVERNANCE_AUTHORITY_PATH = + "/.config/solana/governanceAuthority.json"; export const GOVERNANCE_AUTHORITY_KEYPAIR = loadKeypair( homedir() + GOVERNANCE_AUTHORITY_PATH, ); @@ -79,7 +80,8 @@ export const USER_AUTHORITY_KEYPAIR = loadKeypair( homedir() + USER_AUTHORITY_PATH, ); -export const USER2_AUTHORITY_PATH = "/.config/solana/secretKey_617X3kwJzjfAbr6zHMa4rzbjaHQN8mzST8VAb8oE8xo8.json"; +export const USER2_AUTHORITY_PATH = + "/.config/solana/secretKey_617X3kwJzjfAbr6zHMa4rzbjaHQN8mzST8VAb8oE8xo8.json"; export const USER2_AUTHORITY_KEYPAIR = loadKeypair( homedir() + USER2_AUTHORITY_PATH, ); diff --git a/solana/app/deploy/devnet/initialize/initializeVoteWeightWindowLengths.ts b/solana/app/deploy/devnet/initialize/initializeVoteWeightWindowLengths.ts index 0059e189..cf7f3033 100644 --- a/solana/app/deploy/devnet/initialize/initializeVoteWeightWindowLengths.ts +++ b/solana/app/deploy/devnet/initialize/initializeVoteWeightWindowLengths.ts @@ -2,7 +2,11 @@ import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE, VOTE_WEIGHT_WINDOW_LENGTHS } from "../constants"; +import { + DEPLOYER_AUTHORITY_KEYPAIR, + RPC_NODE, + VOTE_WEIGHT_WINDOW_LENGTHS, +} from "../constants"; import { Staking } from "../../../../target/types/staking"; import fs from "fs"; import BN from "bn.js"; @@ -22,7 +26,9 @@ async function main() { provider, ); - await program.methods.initializeVoteWeightWindowLengths(new BN(VOTE_WEIGHT_WINDOW_LENGTHS)).rpc(); + await program.methods + .initializeVoteWeightWindowLengths(new BN(VOTE_WEIGHT_WINDOW_LENGTHS)) + .rpc(); } catch (err) { console.error("Error:", err); } diff --git a/solana/app/deploy/devnet/tests/21_fetchGlobalConfig.ts b/solana/app/deploy/devnet/tests/21_fetchGlobalConfig.ts index e708c431..ee4f2002 100644 --- a/solana/app/deploy/devnet/tests/21_fetchGlobalConfig.ts +++ b/solana/app/deploy/devnet/tests/21_fetchGlobalConfig.ts @@ -25,10 +25,19 @@ async function main() { provider.wallet as Wallet, ); - console.log("DEPLOYER_AUTHORITY_KEYPAIR.publicKey:", DEPLOYER_AUTHORITY_KEYPAIR.publicKey); + console.log( + "DEPLOYER_AUTHORITY_KEYPAIR.publicKey:", + DEPLOYER_AUTHORITY_KEYPAIR.publicKey, + ); console.log("WORMHOLE_TOKEN.publicKey:", WORMHOLE_TOKEN); - console.log("GOVERNANCE_AUTHORITY_KEYPAIR.publicKey:", GOVERNANCE_AUTHORITY_KEYPAIR.publicKey); - console.log("VESTING_ADMIN_KEYPAIR.publicKey:", VESTING_ADMIN_KEYPAIR.publicKey); + console.log( + "GOVERNANCE_AUTHORITY_KEYPAIR.publicKey:", + GOVERNANCE_AUTHORITY_KEYPAIR.publicKey, + ); + console.log( + "VESTING_ADMIN_KEYPAIR.publicKey:", + VESTING_ADMIN_KEYPAIR.publicKey, + ); console.log("CHECKPOINTS_ACCOUNT_LIMIT:", CHECKPOINTS_ACCOUNT_LIMIT); const [configAccount, bump] = PublicKey.findProgramAddressSync( diff --git a/solana/app/deploy/devnet/tests/22_fetchSpokeMetadataCollector.ts b/solana/app/deploy/devnet/tests/22_fetchSpokeMetadataCollector.ts index fa208c9c..2b0184aa 100644 --- a/solana/app/deploy/devnet/tests/22_fetchSpokeMetadataCollector.ts +++ b/solana/app/deploy/devnet/tests/22_fetchSpokeMetadataCollector.ts @@ -33,8 +33,13 @@ async function main() { console.log("spokeMetadataCollector:", spokeMetadataCollector); let spokeMetadataCollectorAccountData = - await stakeConnection.program.account.spokeMetadataCollector.fetch(spokeMetadataCollector); - console.log("spokeMetadataCollectorAccountData:", spokeMetadataCollectorAccountData); + await stakeConnection.program.account.spokeMetadataCollector.fetch( + spokeMetadataCollector, + ); + console.log( + "spokeMetadataCollectorAccountData:", + spokeMetadataCollectorAccountData, + ); } main(); diff --git a/solana/app/deploy/devnet/tests/23_fetchVoteWeightWindowLengths.ts b/solana/app/deploy/devnet/tests/23_fetchVoteWeightWindowLengths.ts index 560c2283..31d53e0f 100644 --- a/solana/app/deploy/devnet/tests/23_fetchVoteWeightWindowLengths.ts +++ b/solana/app/deploy/devnet/tests/23_fetchVoteWeightWindowLengths.ts @@ -6,7 +6,7 @@ import * as wasm from "@wormhole/staking-wasm"; import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE, - VOTE_WEIGHT_WINDOW_LENGTHS + VOTE_WEIGHT_WINDOW_LENGTHS, } from "../constants"; import { StakeConnection } from "../../../StakeConnection"; import { @@ -26,7 +26,7 @@ async function main() { provider.wallet as Wallet, ); - console.log("VOTE_WEIGHT_WINDOW_LENGTHS:", VOTE_WEIGHT_WINDOW_LENGTHS); + console.log("VOTE_WEIGHT_WINDOW_LENGTHS:", VOTE_WEIGHT_WINDOW_LENGTHS); const [voteWeightWindowLengthsAccountAddress, _] = PublicKey.findProgramAddressSync( @@ -37,15 +37,27 @@ async function main() { ], stakeConnection.program.programId, ); - console.log("voteWeightWindowLengthsAccountAddress:", voteWeightWindowLengthsAccountAddress); + console.log( + "voteWeightWindowLengthsAccountAddress:", + voteWeightWindowLengthsAccountAddress, + ); let windowLengthsAccount: WindowLengthsAccount = await readWindowLengths( connection, voteWeightWindowLengthsAccountAddress, ); - console.log("windowLengthsAccount.getWindowLengthCount():", windowLengthsAccount.getWindowLengthCount()); - console.log("windowLengthsAccount.voteWeightWindowLengths.nextIndex:", windowLengthsAccount.voteWeightWindowLengths.nextIndex); - console.log("windowLengthsAccount.getLastWindowLength().value.toString():", windowLengthsAccount.getLastWindowLength()?.value.toString()); + console.log( + "windowLengthsAccount.getWindowLengthCount():", + windowLengthsAccount.getWindowLengthCount(), + ); + console.log( + "windowLengthsAccount.voteWeightWindowLengths.nextIndex:", + windowLengthsAccount.voteWeightWindowLengths.nextIndex, + ); + console.log( + "windowLengthsAccount.getLastWindowLength().value.toString():", + windowLengthsAccount.getLastWindowLength()?.value.toString(), + ); } main(); diff --git a/solana/app/deploy/devnet/tests/24_fetchProposalAccountData.ts b/solana/app/deploy/devnet/tests/24_fetchProposalAccountData.ts index b72f9568..da2e9f83 100644 --- a/solana/app/deploy/devnet/tests/24_fetchProposalAccountData.ts +++ b/solana/app/deploy/devnet/tests/24_fetchProposalAccountData.ts @@ -17,7 +17,9 @@ async function main() { ); const inputProposalId = await input({ message: "Enter the proposal id:" }); - const proposalIdHex = BigInt(inputProposalId).toString(16).padStart(64, "0"); + const proposalIdHex = BigInt(inputProposalId) + .toString(16) + .padStart(64, "0"); // console.log("proposalIdHex:", proposalIdHex); const proposalIdArray = Buffer.from(proposalIdHex, "hex"); diff --git a/solana/app/deploy/devnet/tests/25_fetchSpokeMessageExecutor.ts b/solana/app/deploy/devnet/tests/25_fetchSpokeMessageExecutor.ts index aae9e6c4..b33285f3 100644 --- a/solana/app/deploy/devnet/tests/25_fetchSpokeMessageExecutor.ts +++ b/solana/app/deploy/devnet/tests/25_fetchSpokeMessageExecutor.ts @@ -24,17 +24,29 @@ async function main() { ); console.log("HUB_CHAIN_ID:", HUB_CHAIN_ID); - console.log("hubSolanaMessageDispatcherPublicKey:", hubSolanaMessageDispatcherPublicKey); + console.log( + "hubSolanaMessageDispatcherPublicKey:", + hubSolanaMessageDispatcherPublicKey, + ); - const [spokeMessageExecutorAccountAddress, _] = PublicKey.findProgramAddressSync( - [utils.bytes.utf8.encode(wasm.Constants.SPOKE_MESSAGE_EXECUTOR_SEED())], - stakeConnection.program.programId, + const [spokeMessageExecutorAccountAddress, _] = + PublicKey.findProgramAddressSync( + [utils.bytes.utf8.encode(wasm.Constants.SPOKE_MESSAGE_EXECUTOR_SEED())], + stakeConnection.program.programId, + ); + console.log( + "spokeMessageExecutorAccountAddress:", + spokeMessageExecutorAccountAddress, ); - console.log("spokeMessageExecutorAccountAddress:", spokeMessageExecutorAccountAddress); let spokeMessageExecutorAccountData = - await stakeConnection.program.account.spokeMessageExecutor.fetch(spokeMessageExecutorAccountAddress); - console.log("spokeMessageExecutorAccountData:", spokeMessageExecutorAccountData); + await stakeConnection.program.account.spokeMessageExecutor.fetch( + spokeMessageExecutorAccountAddress, + ); + console.log( + "spokeMessageExecutorAccountData:", + spokeMessageExecutorAccountData, + ); } main(); diff --git a/solana/app/deploy/devnet/tests/bridge-script.ts b/solana/app/deploy/devnet/tests/bridge-script.ts index 5c0eb4de..60b56cd8 100644 --- a/solana/app/deploy/devnet/tests/bridge-script.ts +++ b/solana/app/deploy/devnet/tests/bridge-script.ts @@ -76,10 +76,7 @@ const scripts: { const info = await getWormholeBridgeData(connection, CORE_BRIDGE_PID); let guardianSetIndex = info.guardianSetIndex; - const guardianSet = deriveGuardianSetKey( - CORE_BRIDGE_PID, - guardianSetIndex, - ); + const guardianSet = deriveGuardianSetKey(CORE_BRIDGE_PID, guardianSetIndex); console.log(` In Solana: diff --git a/solana/app/deploy/devnet/tests/new_wallet.ts b/solana/app/deploy/devnet/tests/new_wallet.ts index 9c6a8c53..aaf6013b 100644 --- a/solana/app/deploy/devnet/tests/new_wallet.ts +++ b/solana/app/deploy/devnet/tests/new_wallet.ts @@ -1,17 +1,17 @@ // Usage: npx ts-node app/deploy/devnet/tests/new_wallet.ts -import { Keypair } from '@solana/web3.js'; -import fs from 'fs'; +import { Keypair } from "@solana/web3.js"; +import fs from "fs"; // Generate a new Keypair const newWallet = Keypair.generate(); // Extract public and private keys const publicKey = newWallet.publicKey.toString(); -const secretKey = Buffer.from(newWallet.secretKey).toString('base64'); // keep it secure +const secretKey = Buffer.from(newWallet.secretKey).toString("base64"); // keep it secure -console.log('Public Key:', publicKey); -console.log('Secret Key (base64):', secretKey); +console.log("Public Key:", publicKey); +console.log("Secret Key (base64):", secretKey); // Save the secret key to a file const fileName = `app/keypairs/secretKey_${publicKey}.json`; diff --git a/solana/app/deploy/devnet/tests/receive_message.ts b/solana/app/deploy/devnet/tests/receive_message.ts index 1d3952f7..df07aaa5 100644 --- a/solana/app/deploy/devnet/tests/receive_message.ts +++ b/solana/app/deploy/devnet/tests/receive_message.ts @@ -8,7 +8,7 @@ import { import { CORE_BRIDGE_PID, DEPLOYER_AUTHORITY_KEYPAIR, - RPC_NODE + RPC_NODE, } from "../constants"; import { Staking } from "../../../../target/types/staking"; import fs from "fs"; diff --git a/solana/app/deploy/devnet/update/updateGovernanceAuthority.ts b/solana/app/deploy/devnet/update/updateGovernanceAuthority.ts index 2822323a..5808fdb3 100644 --- a/solana/app/deploy/devnet/update/updateGovernanceAuthority.ts +++ b/solana/app/deploy/devnet/update/updateGovernanceAuthority.ts @@ -2,7 +2,11 @@ import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; -import { DEPLOYER_AUTHORITY_KEYPAIR, GOVERNANCE_AUTHORITY_KEYPAIR, RPC_NODE } from "../constants"; +import { + DEPLOYER_AUTHORITY_KEYPAIR, + GOVERNANCE_AUTHORITY_KEYPAIR, + RPC_NODE, +} from "../constants"; import { Staking } from "../../../../target/types/staking"; import fs from "fs"; diff --git a/solana/app/deploy/devnet/update/updateHubProposalMetadata.ts b/solana/app/deploy/devnet/update/updateHubProposalMetadata.ts index 76eab318..9d87bab2 100644 --- a/solana/app/deploy/devnet/update/updateHubProposalMetadata.ts +++ b/solana/app/deploy/devnet/update/updateHubProposalMetadata.ts @@ -32,7 +32,10 @@ async function main() { await program.methods .updateHubProposalMetadata(Array.from(hubProposalMetadataUint8Array)) - .accounts({ payer: DEPLOYER_AUTHORITY_KEYPAIR.publicKey, airlock: airlockPDA }) + .accounts({ + payer: DEPLOYER_AUTHORITY_KEYPAIR.publicKey, + airlock: airlockPDA, + }) .rpc(); } catch (err) { console.error("Error:", err); diff --git a/solana/app/deploy/devnet/vesting/claimVesting.ts b/solana/app/deploy/devnet/vesting/claimVesting.ts index 94c4f50f..62da26d2 100644 --- a/solana/app/deploy/devnet/vesting/claimVesting.ts +++ b/solana/app/deploy/devnet/vesting/claimVesting.ts @@ -1,11 +1,7 @@ // Usage: npx ts-node app/deploy/devnet/vesting/claimVesting.ts import { Wallet, AnchorProvider } from "@coral-xyz/anchor"; -import { - Connection, - PublicKey, - SystemProgram, -} from "@solana/web3.js"; +import { Connection, PublicKey, SystemProgram } from "@solana/web3.js"; import { VESTING_ADMIN_KEYPAIR, USER_AUTHORITY_KEYPAIR, @@ -44,9 +40,7 @@ async function main() { }; const NOW = new BN(1740006704); - const config = new PublicKey( - "BcJSiMQLggZxJ3v7kLLnQemB7Z6XJABV5Bci5LX7KhA3", - ); + const config = new PublicKey("BcJSiMQLggZxJ3v7kLLnQemB7Z6XJABV5Bci5LX7KhA3"); const vault = getAssociatedTokenAddressSync( WORMHOLE_TOKEN, @@ -102,15 +96,10 @@ async function main() { }; let stakeAccountMetadataAddress = - await vesterStakeConnection.getStakeMetadataAddress( - vester.publicKey, - ); + await vesterStakeConnection.getStakeMetadataAddress(vester.publicKey); let stakeAccountMetadataData = - await vesterStakeConnection.fetchStakeAccountMetadata( - vester.publicKey, - ); - let delegateStakeAccountCheckpointsOwner = - stakeAccountMetadataData.delegate; + await vesterStakeConnection.fetchStakeAccountMetadata(vester.publicKey); + let delegateStakeAccountCheckpointsOwner = stakeAccountMetadataData.delegate; let delegateStakeAccountMetadataAddress = await vesterStakeConnection.getStakeMetadataAddress( delegateStakeAccountCheckpointsOwner, diff --git a/solana/app/deploy/devnet/vesting/createVestingConfig.ts b/solana/app/deploy/devnet/vesting/createVestingConfig.ts index 642af294..48d6f8ef 100644 --- a/solana/app/deploy/devnet/vesting/createVestingConfig.ts +++ b/solana/app/deploy/devnet/vesting/createVestingConfig.ts @@ -51,9 +51,15 @@ async function main() { const LATER = NOW.add(new BN(1000)); const EVEN_LATER = LATER.add(new BN(1000)); console.log("Vesting claim times:"); - console.log(`NOW: ${NOW.toString()} (${new Date(NOW.toNumber() * 1000).toISOString()})`); - console.log(`LATER: ${LATER.toString()} (${new Date(LATER.toNumber() * 1000).toISOString()})`); - console.log(`EVEN_LATER: ${EVEN_LATER.toString()} (${new Date(EVEN_LATER.toNumber() * 1000).toISOString()})`); + console.log( + `NOW: ${NOW.toString()} (${new Date(NOW.toNumber() * 1000).toISOString()})`, + ); + console.log( + `LATER: ${LATER.toString()} (${new Date(LATER.toNumber() * 1000).toISOString()})`, + ); + console.log( + `EVEN_LATER: ${EVEN_LATER.toString()} (${new Date(EVEN_LATER.toNumber() * 1000).toISOString()})`, + ); const seed = new BN(randomBytes(8)); console.log("Vesting config random seed:", seed); @@ -147,14 +153,18 @@ async function main() { .then(confirm); console.log(`Vest for vester at LATER (${LATER.toString()}) created`); - console.log(`Creating vest for vester at EVEN_LATER (${EVEN_LATER.toString()})...`); + console.log( + `Creating vest for vester at EVEN_LATER (${EVEN_LATER.toString()})...`, + ); await stakeConnection.program.methods .createVesting(EVEN_LATER, new BN(20e6)) .accounts({ ...accounts }) .signers([admin]) .rpc() .then(confirm); - console.log(`Vest for vester at EVEN_LATER (${EVEN_LATER.toString()}) created`); + console.log( + `Vest for vester at EVEN_LATER (${EVEN_LATER.toString()}) created`, + ); const vestLater = PublicKey.findProgramAddressSync( [ diff --git a/solana/app/deploy/devnet/vesting/delegateWithVest.ts b/solana/app/deploy/devnet/vesting/delegateWithVest.ts index 342678d2..d59c0ea6 100644 --- a/solana/app/deploy/devnet/vesting/delegateWithVest.ts +++ b/solana/app/deploy/devnet/vesting/delegateWithVest.ts @@ -1,14 +1,8 @@ // Usage: npx ts-node app/deploy/devnet/vesting/delegateWithVest.ts import { Wallet, AnchorProvider } from "@coral-xyz/anchor"; -import { - Connection, - PublicKey, -} from "@solana/web3.js"; -import { - USER_AUTHORITY_KEYPAIR, - RPC_NODE, -} from "../constants"; +import { Connection, PublicKey } from "@solana/web3.js"; +import { USER_AUTHORITY_KEYPAIR, RPC_NODE } from "../constants"; import { StakeConnection } from "../../../StakeConnection"; import { WHTokenBalance } from "../../../whTokenBalance"; @@ -22,9 +16,7 @@ async function main() { vesterProvider.wallet as Wallet, ); - const config = new PublicKey( - "BcJSiMQLggZxJ3v7kLLnQemB7Z6XJABV5Bci5LX7KhA3", - ); + const config = new PublicKey("BcJSiMQLggZxJ3v7kLLnQemB7Z6XJABV5Bci5LX7KhA3"); console.log(`Delegate WH tokens with vests`); await vesterStakeConnection.delegateWithVest( diff --git a/solana/app/e2e/03_castVote.ts b/solana/app/e2e/03_castVote.ts index f3f8dfa0..3dc86cf6 100644 --- a/solana/app/e2e/03_castVote.ts +++ b/solana/app/e2e/03_castVote.ts @@ -3,10 +3,7 @@ import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; import { StakeConnection } from "../StakeConnection"; -import { - USER2_AUTHORITY_KEYPAIR, - RPC_NODE, -} from "../deploy/devnet/constants"; +import { USER2_AUTHORITY_KEYPAIR, RPC_NODE } from "../deploy/devnet/constants"; import { WHTokenBalance } from "../whTokenBalance"; import input from "@inquirer/input"; diff --git a/solana/app/e2e/04_crossChainVoteSolana.ts b/solana/app/e2e/04_crossChainVoteSolana.ts index fc171ba4..bc471f24 100644 --- a/solana/app/e2e/04_crossChainVoteSolana.ts +++ b/solana/app/e2e/04_crossChainVoteSolana.ts @@ -74,7 +74,9 @@ async function getSolanaQueryResponse(): Promise<{ ).data; // console.log("queryResponse: ", queryResponse); - const queryResponseHex = QueryResponse.from(Buffer.from(queryResponse.bytes, "hex")); + const queryResponseHex = QueryResponse.from( + Buffer.from(queryResponse.bytes, "hex"), + ); console.log("queryResponseHex: ", queryResponseHex); const bytes = "0x" + queryResponse["bytes"]; diff --git a/solana/app/helpers/utils/lookup_table.ts b/solana/app/helpers/utils/lookup_table.ts index 2cae909b..1536e63c 100644 --- a/solana/app/helpers/utils/lookup_table.ts +++ b/solana/app/helpers/utils/lookup_table.ts @@ -1,6 +1,4 @@ -import { - TOKEN_PROGRAM_ID, -} from "@solana/spl-token"; +import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; import { PublicKey, SystemProgram, diff --git a/solana/programs/staking/src/contexts/cancel_vesting.rs b/solana/programs/staking/src/contexts/cancel_vesting.rs index fb9cba44..b6e27e84 100644 --- a/solana/programs/staking/src/contexts/cancel_vesting.rs +++ b/solana/programs/staking/src/contexts/cancel_vesting.rs @@ -2,10 +2,10 @@ use anchor_lang::prelude::*; use anchor_spl::associated_token::AssociatedToken; use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface}; -use crate::context::{VESTING_BALANCE_SEED, VESTING_CONFIG_SEED, VEST_SEED, CONFIG_SEED}; +use crate::context::{CONFIG_SEED, VESTING_BALANCE_SEED, VESTING_CONFIG_SEED, VEST_SEED}; use crate::error::VestingError; -use crate::state::{Vesting, VestingBalance, VestingConfig}; use crate::state::global_config::GlobalConfig; +use crate::state::{Vesting, VestingBalance, VestingConfig}; #[derive(Accounts)] pub struct CancelVesting<'info> { diff --git a/solana/programs/staking/src/contexts/finalize.rs b/solana/programs/staking/src/contexts/finalize.rs index 84ae620e..7a95dd90 100644 --- a/solana/programs/staking/src/contexts/finalize.rs +++ b/solana/programs/staking/src/contexts/finalize.rs @@ -1,9 +1,9 @@ -use crate::context::{VESTING_CONFIG_SEED, CONFIG_SEED}; +use crate::context::{CONFIG_SEED, VESTING_CONFIG_SEED}; use crate::error::VestingError; +use crate::state::global_config::GlobalConfig; use crate::state::VestingConfig; use anchor_lang::prelude::*; use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface}; -use crate::state::global_config::GlobalConfig; #[derive(Accounts)] pub struct Finalize<'info> { diff --git a/solana/programs/staking/src/contexts/transfer_vesting.rs b/solana/programs/staking/src/contexts/transfer_vesting.rs index f28a8c18..2efed6d4 100644 --- a/solana/programs/staking/src/contexts/transfer_vesting.rs +++ b/solana/programs/staking/src/contexts/transfer_vesting.rs @@ -120,8 +120,10 @@ impl<'info> crate::contexts::TransferVesting<'info> { return err!(VestingError::TransferVestToMyself); } - let sender_has_delegated_vest = self.vesting_balance.stake_account_metadata != Pubkey::default(); - let recipient_has_delegated_vest = self.new_vesting_balance.stake_account_metadata != Pubkey::default(); + let sender_has_delegated_vest = + self.vesting_balance.stake_account_metadata != Pubkey::default(); + let recipient_has_delegated_vest = + self.new_vesting_balance.stake_account_metadata != Pubkey::default(); // There are only 3 valid input account permutations. let delegate_votes_changed = match ( @@ -134,7 +136,14 @@ impl<'info> crate::contexts::TransferVesting<'info> { ) { // If the sender and recipient have delegated their vests, then we don't need the delegate accounts as we enforce below that the delegates // have to be the same. Thus, no there is no net change in delegate voting power and no new checkpoints are needed - (true, true, None, None, Some(stake_account_metadata), Some(new_stake_account_metadata)) => { + ( + true, + true, + None, + None, + Some(stake_account_metadata), + Some(new_stake_account_metadata), + ) => { // The sender must be delegated to the same address as the recipient. require!( stake_account_metadata.delegate == new_stake_account_metadata.delegate, @@ -178,16 +187,23 @@ impl<'info> crate::contexts::TransferVesting<'info> { transfer_vesting_events.new_stake_account_metadata = Some(StakeAccountMetadataEvents { recorded_vesting_balance_changed, - delegate_votes_changed + delegate_votes_changed, }); - + Ok(None) - }, + } // If the sender has delegated their vest, but the recipient hasn't then all bar the new_stake_account_metadata account must be provided - (true, false, Some(delegate_stake_account_checkpoints), Some(delegate_stake_account_metadata), Some(stake_account_metadata), None) => { + ( + true, + false, + Some(delegate_stake_account_checkpoints), + Some(delegate_stake_account_metadata), + Some(stake_account_metadata), + None, + ) => { // In this case the current delegate will have their voting balance reduced. That's what we do below. // We don't update the recorded vesting balance of the sender here, we instead do it later outside of the match cases - + // Check if stake account checkpoints is out of bounds let loaded_checkpoints = delegate_stake_account_checkpoints.load()?; require!( @@ -201,7 +217,7 @@ impl<'info> crate::contexts::TransferVesting<'info> { stake_account_metadata.delegate.key() == loaded_checkpoints.owner, VestingError::InvalidStakeAccountCheckpoints ); - drop(loaded_checkpoints); + drop(loaded_checkpoints); // Verify that the actual delegate_stake_account_metadata address matches the expected one require!( @@ -254,10 +270,10 @@ impl<'info> crate::contexts::TransferVesting<'info> { } Ok(delegate_votes_changed) - }, + } // If neither the sender or receiver has delegated their vests, then none of the optional accounts are needed // No changes need to be made to any accounts apart from the vesting balance accounts - (false, false, None, None, None, None) => { Ok(None) }, + (false, false, None, None, None, None) => Ok(None), // Any other combination is invalid _ => err!(VestingError::ErrorOfAccountParsing), }?; diff --git a/solana/programs/staking/src/contexts/withdraw_surplus.rs b/solana/programs/staking/src/contexts/withdraw_surplus.rs index b5af67c7..5e177e1a 100644 --- a/solana/programs/staking/src/contexts/withdraw_surplus.rs +++ b/solana/programs/staking/src/contexts/withdraw_surplus.rs @@ -1,12 +1,12 @@ -use crate::context::{VESTING_CONFIG_SEED, CONFIG_SEED}; +use crate::context::{CONFIG_SEED, VESTING_CONFIG_SEED}; use crate::error::VestingError; +use crate::state::global_config::GlobalConfig; use crate::state::VestingConfig; use anchor_lang::prelude::*; use anchor_spl::associated_token::AssociatedToken; use anchor_spl::token_interface::{ transfer_checked, Mint, TokenAccount, TokenInterface, TransferChecked, }; -use crate::state::global_config::GlobalConfig; #[derive(Accounts)] pub struct WithdrawSurplus<'info> { diff --git a/solana/programs/staking/src/lib.rs b/solana/programs/staking/src/lib.rs index 964bc416..d2639902 100644 --- a/solana/programs/staking/src/lib.rs +++ b/solana/programs/staking/src/lib.rs @@ -98,7 +98,10 @@ pub mod staking { // Solana accounts are 10MB maximum = 10485760 bytes // The checkpoint account contains 8 + 32 + 8 = 48 bytes of fixed data // Every checkpoint is 8 + 8 = 16 bytes, so we can fit in (10485760 - 48) / 16 = 655,357 checkpoints - require!(args.max_checkpoints_account_limit <= 655_000, ErrorCode::InvalidCheckpointAccountLimit); + require!( + args.max_checkpoints_account_limit <= 655_000, + ErrorCode::InvalidCheckpointAccountLimit + ); config_account.max_checkpoints_account_limit = args.max_checkpoints_account_limit; config_account.pending_governance_authority = None; config_account.pending_vesting_admin = None; @@ -485,14 +488,13 @@ pub mod staking { .current_delegate_stake_account_checkpoints .load()?; if loaded_checkpoints.next_index >= config.max_checkpoints_account_limit.into() { - if ctx.accounts.current_delegate_stake_account_metadata.key() + if ctx.accounts.current_delegate_stake_account_metadata.key() != ctx.accounts.stake_account_metadata.key() { ctx.accounts .current_delegate_stake_account_metadata .stake_account_checkpoints_last_index += 1; - } - else { + } else { ctx.accounts .stake_account_metadata .stake_account_checkpoints_last_index += 1; @@ -879,10 +881,15 @@ pub mod staking { let spoke_metadata_collector = &mut ctx.accounts.spoke_metadata_collector; if spoke_metadata_collector.updates_controlled_by_governance { - require!(ctx.accounts.payer.key() == ctx.accounts.config.governance_authority, ErrorCode::NotGovernanceAuthority); - } - else { - require!(ctx.accounts.airlock.to_account_info().is_signer, ErrorCode::AirlockNotSigner); + require!( + ctx.accounts.payer.key() == ctx.accounts.config.governance_authority, + ErrorCode::NotGovernanceAuthority + ); + } else { + require!( + ctx.accounts.airlock.to_account_info().is_signer, + ErrorCode::AirlockNotSigner + ); } let _ = spoke_metadata_collector.update_hub_proposal_metadata(new_hub_proposal_metadata); @@ -891,7 +898,7 @@ pub mod staking { } pub fn relinquish_admin_control_over_hub_proposal_metadata( - ctx: Context + ctx: Context, ) -> Result<()> { let spoke_metadata_collector = &mut ctx.accounts.spoke_metadata_collector; spoke_metadata_collector.updates_controlled_by_governance = false; diff --git a/solana/tests/api_test.ts b/solana/tests/api_test.ts index ca6e686c..73eb4c20 100644 --- a/solana/tests/api_test.ts +++ b/solana/tests/api_test.ts @@ -26,10 +26,7 @@ import { createProposalQueryResponseBytesWithInvalidChainSpecificResponse, createProposalQueryResponseBytesWithInvalidFunctionSignature, } from "./utils/api_utils"; -import { - StakeConnection, - WHTokenBalance, -} from "../app"; +import { StakeConnection, WHTokenBalance } from "../app"; import { TEST_CHECKPOINTS_ACCOUNT_LIMIT } from "./utils/constants"; import { CheckpointAccount } from "../app/checkpoints"; import crypto from "crypto"; @@ -196,12 +193,12 @@ describe("api", async () => { user8 = user8StakeConnection.provider.wallet.publicKey; user9StakeConnection = await newUserStakeConnection( - stakeConnection, - Keypair.generate(), - config, - whMintAccount, - whMintAuthority, - WHTokenBalance.fromString("1000"), + stakeConnection, + Keypair.generate(), + config, + whMintAccount, + whMintAuthority, + WHTokenBalance.fromString("1000"), ); user9 = user9StakeConnection.provider.wallet.publicKey; }); @@ -845,7 +842,7 @@ describe("api", async () => { ) .accounts({ currentDelegateStakeAccountCheckpoints: - currentDelegateStakeAccountCheckpointsAddress, + currentDelegateStakeAccountCheckpointsAddress, destination: toAccount, }) .rpc(); @@ -965,10 +962,15 @@ describe("api", async () => { currentStakeAccountCheckpointsAddress, ); - let currentCheckpointCount = currentStakeAccountCheckpoints.getCheckpointCount(); + let currentCheckpointCount = + currentStakeAccountCheckpoints.getCheckpointCount(); // Fill all bar 1 checkpoints in the limit. Leave 1 space for the withdraw checkpoint - for (currentCheckpointCount; currentCheckpointCount < TEST_CHECKPOINTS_ACCOUNT_LIMIT - 1; currentCheckpointCount++) { + for ( + currentCheckpointCount; + currentCheckpointCount < TEST_CHECKPOINTS_ACCOUNT_LIMIT - 1; + currentCheckpointCount++ + ) { await sleep(1000); await user8StakeConnection.delegate( user8StakeConnection.userPublicKey(), @@ -980,9 +982,13 @@ describe("api", async () => { currentStakeAccountCheckpointsAddress, ); - let stakeAccountMetadata = await user8StakeConnection.fetchStakeAccountMetadata(user8StakeConnection.userPublicKey()); + let stakeAccountMetadata = + await user8StakeConnection.fetchStakeAccountMetadata( + user8StakeConnection.userPublicKey(), + ); - let previousCheckpointAccountIndex = stakeAccountMetadata.stakeAccountCheckpointsLastIndex; + let previousCheckpointAccountIndex = + stakeAccountMetadata.stakeAccountCheckpointsLastIndex; let balanceBefore = stakeAccount.tokenBalance; // This withdraw action fills up the checkpoint account, which should increment the checkpoint account index @@ -996,19 +1002,21 @@ describe("api", async () => { currentStakeAccountCheckpointsAddress, ); - stakeAccountMetadata = await user8StakeConnection.fetchStakeAccountMetadata(user8StakeConnection.userPublicKey()); - + stakeAccountMetadata = + await user8StakeConnection.fetchStakeAccountMetadata( + user8StakeConnection.userPublicKey(), + ); - let newCheckpointAccountIndex = stakeAccountMetadata.stakeAccountCheckpointsLastIndex; + let newCheckpointAccountIndex = + stakeAccountMetadata.stakeAccountCheckpointsLastIndex; let balanceAfter = stakeAccount.tokenBalance; // Both the checkpoint index and the balance should be properly update - assert.equal(previousCheckpointAccountIndex + 1, newCheckpointAccountIndex); assert.equal( - balanceBefore - balanceAfter, - 5000000, + previousCheckpointAccountIndex + 1, + newCheckpointAccountIndex, ); - + assert.equal(balanceBefore - balanceAfter, 5000000); }); }); @@ -1503,19 +1511,19 @@ describe("api", async () => { let user9StakeAccountCheckpoints: CheckpointAccount = await user9StakeConnection.fetchCheckpointAccount( - user9StakeAccountCheckpointsAddress, + user9StakeAccountCheckpointsAddress, ); assert.equal( - user9StakeAccountCheckpoints.checkpoints[0].value.toString(), + user9StakeAccountCheckpoints.checkpoints[0].value.toString(), "0", ); assert.equal( - user9StakeAccountCheckpoints.checkpoints[1].value.toString(), + user9StakeAccountCheckpoints.checkpoints[1].value.toString(), "225000000", ); let proposalIdInput = await addTestProposal( - user9StakeConnection, + user9StakeConnection, Math.floor(Date.now() / 1000), ); const { proposalAccount } = diff --git a/solana/tests/config.ts b/solana/tests/config.ts index 120dbe5d..bc60546d 100644 --- a/solana/tests/config.ts +++ b/solana/tests/config.ts @@ -10,11 +10,7 @@ import * as wasm from "@wormhole/staking-wasm"; import assert from "assert"; import BN from "bn.js"; import path from "path"; -import { - StakeConnection, - WHTokenBalance, - WH_TOKEN_DECIMALS, -} from "../app"; +import { StakeConnection, WHTokenBalance, WH_TOKEN_DECIMALS } from "../app"; import { CORE_BRIDGE_PID, HUB_CHAIN_ID, diff --git a/solana/tests/utils/api_utils.ts b/solana/tests/utils/api_utils.ts index a835aa38..326d8b2c 100644 --- a/solana/tests/utils/api_utils.ts +++ b/solana/tests/utils/api_utils.ts @@ -1,10 +1,7 @@ import { StakeConnection } from "../../app/StakeConnection"; import { PublicKey } from "@solana/web3.js"; import { WHTokenBalance } from "../../app"; -import { - HUB_CHAIN_ID, - HUB_PROPOSAL_METADATA_ADDRESS, -} from "./constants"; +import { HUB_CHAIN_ID, HUB_PROPOSAL_METADATA_ADDRESS } from "./constants"; import assert from "assert"; import { QueryRequest, diff --git a/solana/tests/utils/before.ts b/solana/tests/utils/before.ts index ba85aefc..bedf3e10 100644 --- a/solana/tests/utils/before.ts +++ b/solana/tests/utils/before.ts @@ -22,11 +22,7 @@ import BN from "bn.js"; import toml from "toml"; import path from "path"; import os from "os"; -import { - StakeConnection, - WHTokenBalance, - WH_TOKEN_DECIMALS, -} from "../../app"; +import { StakeConnection, WHTokenBalance, WH_TOKEN_DECIMALS } from "../../app"; import { GlobalConfig } from "../../app/StakeConnection"; import { createMint } from "./utils"; import { initAddressLookupTable } from "../../app/helpers/utils/lookup_table"; diff --git a/solana/tests/vesting.ts b/solana/tests/vesting.ts index 5268d9ee..8f25c563 100644 --- a/solana/tests/vesting.ts +++ b/solana/tests/vesting.ts @@ -477,12 +477,13 @@ describe("vesting", () => { it("Airdrop", async () => { let tx = new Transaction(); tx.instructions = [ - ...[whMintAuthority, vester, vester2, vester3, fakeVestingAdmin].map((k) => - SystemProgram.transfer({ - fromPubkey: stakeConnection.provider.publicKey, - toPubkey: k.publicKey, - lamports: 10 * LAMPORTS_PER_SOL, - }), + ...[whMintAuthority, vester, vester2, vester3, fakeVestingAdmin].map( + (k) => + SystemProgram.transfer({ + fromPubkey: stakeConnection.provider.publicKey, + toPubkey: k.publicKey, + lamports: 10 * LAMPORTS_PER_SOL, + }), ), ]; await stakeConnection.provider.sendAndConfirm(tx, [ @@ -690,23 +691,25 @@ describe("vesting", () => { }); it("should fail to create vesting balance with invalid admin", async () => { - try { - await stakeConnection.program.methods - .createVestingBalance() - .accounts({ - ...accounts, - vestingBalance: vestingBalance, - admin: fakeVestingAdmin.publicKey, - }) - .signers([fakeVestingAdmin]) - .rpc() - .then(confirm); - - assert.fail("Expected error was not thrown"); - } catch (e) { - assert((e as AnchorError).error?.errorCode?.code === "InvalidVestingAdmin"); - } - fakeConfig = PublicKey.findProgramAddressSync( + try { + await stakeConnection.program.methods + .createVestingBalance() + .accounts({ + ...accounts, + vestingBalance: vestingBalance, + admin: fakeVestingAdmin.publicKey, + }) + .signers([fakeVestingAdmin]) + .rpc() + .then(confirm); + + assert.fail("Expected error was not thrown"); + } catch (e) { + assert( + (e as AnchorError).error?.errorCode?.code === "InvalidVestingAdmin", + ); + } + fakeConfig = PublicKey.findProgramAddressSync( [ Buffer.from(wasm.Constants.VESTING_CONFIG_SEED()), whMintAccount.publicKey.toBuffer(), @@ -817,7 +820,9 @@ describe("vesting", () => { assert.fail("Expected error was not thrown"); } catch (e) { - assert((e as AnchorError).error?.errorCode?.code === "InvalidVestingAdmin"); + assert( + (e as AnchorError).error?.errorCode?.code === "InvalidVestingAdmin", + ); } }); @@ -1064,7 +1069,9 @@ describe("vesting", () => { assert.fail("Expected error was not thrown"); } catch (e) { - assert((e as AnchorError).error?.errorCode?.code === "InvalidVestingAdmin"); + assert( + (e as AnchorError).error?.errorCode?.code === "InvalidVestingAdmin", + ); } }); @@ -1229,9 +1236,7 @@ describe("vesting", () => { ); let delegateeStakeAccountMetadataAddress = - await stakeConnection.getStakeMetadataAddress( - vester.publicKey, - ); + await stakeConnection.getStakeMetadataAddress(vester.publicKey); let delegateeStakeAccountCheckpointsAddress = await stakeConnection.getStakeAccountCheckpointsAddressByMetadata( delegateeStakeAccountMetadataAddress, @@ -1301,9 +1306,7 @@ describe("vesting", () => { ); let delegateeStakeAccountMetadataAddress = - await vesterStakeConnection.getStakeMetadataAddress( - vester.publicKey, - ); + await vesterStakeConnection.getStakeMetadataAddress(vester.publicKey); let delegateeStakeAccountCheckpointsAddress = await vesterStakeConnection.getStakeAccountCheckpointsAddressByMetadata( delegateeStakeAccountMetadataAddress, @@ -1311,9 +1314,7 @@ describe("vesting", () => { ); let currentDelegateStakeAccountOwner = - await vesterStakeConnection.delegates( - vester.publicKey, - ); + await vesterStakeConnection.delegates(vester.publicKey); let currentDelegateStakeAccountMetadataAddress = await vesterStakeConnection.getStakeMetadataAddress( currentDelegateStakeAccountOwner, @@ -1411,9 +1412,7 @@ describe("vesting", () => { ); let delegateeStakeAccountMetadataAddress = - await stakeConnection.getStakeMetadataAddress( - vester.publicKey, - ); + await stakeConnection.getStakeMetadataAddress(vester.publicKey); let delegateeStakeAccountCheckpointsAddress = await stakeConnection.getStakeAccountCheckpointsAddressByMetadata( delegateeStakeAccountMetadataAddress, @@ -1483,17 +1482,14 @@ describe("vesting", () => { assert.fail("Expected error was not thrown"); } catch (e) { assert( - (e as AnchorError).error?.errorCode?.code === - "ErrorOfAccountParsing", + (e as AnchorError).error?.errorCode?.code === "ErrorOfAccountParsing", ); } }); it("should fail to claim without stakeAccountCheckpoints", async () => { let stakeAccountMetadataAddress = - await vesterStakeConnection.getStakeMetadataAddress( - vester.publicKey, - ); + await vesterStakeConnection.getStakeMetadataAddress(vester.publicKey); try { await stakeConnection.program.methods .claimVesting() @@ -1512,8 +1508,7 @@ describe("vesting", () => { assert.fail("Expected error was not thrown"); } catch (e) { assert( - (e as AnchorError).error?.errorCode?.code === - "ErrorOfAccountParsing", + (e as AnchorError).error?.errorCode?.code === "ErrorOfAccountParsing", ); } }); @@ -1555,9 +1550,7 @@ describe("vesting", () => { it("should fail to claim with incorrect stakeAccountCheckpoints ", async () => { let stakeAccountMetadataAddress = - await vesterStakeConnection.getStakeMetadataAddress( - vester.publicKey, - ); + await vesterStakeConnection.getStakeMetadataAddress(vester.publicKey); let incorrectStakeAccountMetadataAddress = await stakeConnection.getStakeMetadataAddress( @@ -1596,9 +1589,7 @@ describe("vesting", () => { it("fails to create a new checkpoints account if the existing checkpoints account is not fully loaded and is used as input", async () => { let stakeAccountMetadataAddress = - await vesterStakeConnection.getStakeMetadataAddress( - vester.publicKey, - ); + await vesterStakeConnection.getStakeMetadataAddress(vester.publicKey); let notFulledStakeAccountCheckpointsAddress = await vesterStakeConnection.getStakeAccountCheckpointsAddressByMetadata( @@ -1643,13 +1634,9 @@ describe("vesting", () => { it("should successfully claim staked vest", async () => { let stakeAccountMetadataAddress = - await stakeConnection.getStakeMetadataAddress( - vester.publicKey, - ); + await stakeConnection.getStakeMetadataAddress(vester.publicKey); let stakeAccountMetadataData = - await stakeConnection.fetchStakeAccountMetadata( - vester.publicKey, - ); + await stakeConnection.fetchStakeAccountMetadata(vester.publicKey); let delegateStakeAccountCheckpointsOwner = stakeAccountMetadataData.delegate; @@ -1680,9 +1667,7 @@ describe("vesting", () => { .then(confirm); let vesterStakeMetadata: StakeAccountMetadata = - await vesterStakeConnection.fetchStakeAccountMetadata( - vester.publicKey, - ); + await vesterStakeConnection.fetchStakeAccountMetadata(vester.publicKey); let vesterStakeCheckpoints: CheckpointAccount = await vesterStakeConnection.fetchCheckpointAccount( @@ -1701,13 +1686,9 @@ describe("vesting", () => { it("should fail to claim if checkpoints account is fulled", async () => { let stakeAccountMetadataAddress = - await vesterStakeConnection.getStakeMetadataAddress( - vester.publicKey, - ); + await vesterStakeConnection.getStakeMetadataAddress(vester.publicKey); let vesterStakeAccountMetadata = - await vesterStakeConnection.fetchStakeAccountMetadata( - vester.publicKey, - ); + await vesterStakeConnection.fetchStakeAccountMetadata(vester.publicKey); // there is only one checkpoint account assert.equal( vesterStakeAccountMetadata.stakeAccountCheckpointsLastIndex, @@ -1748,9 +1729,7 @@ describe("vesting", () => { ); vesterStakeAccountMetadata = - await vesterStakeConnection.fetchStakeAccountMetadata( - vester.publicKey, - ); + await vesterStakeConnection.fetchStakeAccountMetadata(vester.publicKey); // a new checkpoint account must be created assert.equal( vesterStakeAccountMetadata.stakeAccountCheckpointsLastIndex, @@ -1845,10 +1824,7 @@ describe("vesting", () => { let currentDelegate = await vesterStakeConnection.delegates( vester.publicKey, ); - assert.equal( - currentDelegate.toBase58(), - vester.publicKey.toBase58(), - ); + assert.equal(currentDelegate.toBase58(), vester.publicKey.toBase58()); let currentDelegateStakeAccountAddress = await vesterStakeConnection.getStakeMetadataAddress(currentDelegate); let currentDelegateStakeAccountCheckpointsAddress = @@ -1947,9 +1923,7 @@ describe("vesting", () => { it("should successfully create a new checkpoints account", async () => { let stakeAccountMetadataAddress = - await vesterStakeConnection.getStakeMetadataAddress( - vester.publicKey, - ); + await vesterStakeConnection.getStakeMetadataAddress(vester.publicKey); let currentStakeAccountCheckpointsAddress = await vesterStakeConnection.getStakeAccountCheckpointsAddressByMetadata( @@ -1976,9 +1950,7 @@ describe("vesting", () => { ); let vesterStakeMetadata: StakeAccountMetadata = - await vesterStakeConnection.fetchStakeAccountMetadata( - vester.publicKey, - ); + await vesterStakeConnection.fetchStakeAccountMetadata(vester.publicKey); assert.equal( vesterStakeMetadata.recordedVestingBalance.toString(), @@ -2102,9 +2074,8 @@ describe("vesting", () => { let vesterDelegateStakeAccountOwner = await vesterStakeConnection.delegates( vester.publicKey, ); - let newVesterDelegateStakeAccountOwner = await newVesterStakeConnection.delegates( - newVester.publicKey, - ); + let newVesterDelegateStakeAccountOwner = + await newVesterStakeConnection.delegates(newVester.publicKey); assert.notEqual( vesterDelegateStakeAccountOwner.toBase58(), newVesterDelegateStakeAccountOwner.toBase58(), @@ -2128,9 +2099,7 @@ describe("vesting", () => { ); let stakeAccountMetadataAddress = - await vesterStakeConnection.getStakeMetadataAddress( - vester.publicKey, - ); + await vesterStakeConnection.getStakeMetadataAddress(vester.publicKey); let newStakeAccountMetadataAddress = await newVesterStakeConnection.getStakeMetadataAddress( newVester.publicKey, @@ -2166,7 +2135,8 @@ describe("vesting", () => { assert.fail("Expected error was not thrown"); } catch (e) { assert( - (e as AnchorError).error?.errorCode?.code === "StakeAccountDelegatesMismatch", + (e as AnchorError).error?.errorCode?.code === + "StakeAccountDelegatesMismatch", ); } }); @@ -2183,9 +2153,8 @@ describe("vesting", () => { let vesterDelegateStakeAccountOwner = await vesterStakeConnection.delegates( vester.publicKey, ); - let newVesterDelegateStakeAccountOwner = await newVesterStakeConnection.delegates( - newVester.publicKey, - ); + let newVesterDelegateStakeAccountOwner = + await newVesterStakeConnection.delegates(newVester.publicKey); assert.equal( vesterDelegateStakeAccountOwner.toBase58(), newVesterDelegateStakeAccountOwner.toBase58(), @@ -2209,9 +2178,7 @@ describe("vesting", () => { ); let vesterStakeAccountMetadata = - await vesterStakeConnection.fetchStakeAccountMetadata( - vester.publicKey, - ); + await vesterStakeConnection.fetchStakeAccountMetadata(vester.publicKey); let newVesterStakeAccountMetadata = await newVesterStakeConnection.fetchStakeAccountMetadata( newVester.publicKey, @@ -2222,9 +2189,7 @@ describe("vesting", () => { ); let stakeAccountMetadataAddress = - await vesterStakeConnection.getStakeMetadataAddress( - vester.publicKey, - ); + await vesterStakeConnection.getStakeMetadataAddress(vester.publicKey); let newStakeAccountMetadataAddress = await newVesterStakeConnection.getStakeMetadataAddress( newVester.publicKey, @@ -2238,7 +2203,7 @@ describe("vesting", () => { ], stakeConnection.program.programId, )[0]; - + try { await vesterStakeConnection.program.methods .transferVesting() @@ -2259,7 +2224,8 @@ describe("vesting", () => { assert.fail("Expected error was not thrown"); } catch (e) { assert( - (e as AnchorError).error?.errorCode?.code === "StakeAccountDelegationLoop", + (e as AnchorError).error?.errorCode?.code === + "StakeAccountDelegationLoop", ); } @@ -2274,13 +2240,9 @@ describe("vesting", () => { it("should successfully claim staked vest with created checkpoint account", async () => { let stakeAccountMetadataAddress = - await stakeConnection.getStakeMetadataAddress( - vester.publicKey, - ); + await stakeConnection.getStakeMetadataAddress(vester.publicKey); let stakeAccountMetadataData = - await stakeConnection.fetchStakeAccountMetadata( - vester.publicKey, - ); + await stakeConnection.fetchStakeAccountMetadata(vester.publicKey); let delegateStakeAccountCheckpointsOwner = stakeAccountMetadataData.delegate; @@ -2311,9 +2273,7 @@ describe("vesting", () => { .then(confirm); let vesterStakeMetadata: StakeAccountMetadata = - await vesterStakeConnection.fetchStakeAccountMetadata( - vester.publicKey, - ); + await vesterStakeConnection.fetchStakeAccountMetadata(vester.publicKey); let vesterStakeCheckpoints: CheckpointAccount = await vesterStakeConnection.fetchCheckpointAccount( @@ -2333,9 +2293,7 @@ describe("vesting", () => { it("should successfully create a new checkpoints account after claim", async () => { let stakeAccountMetadataAddress = - await vesterStakeConnection.getStakeMetadataAddress( - vester.publicKey, - ); + await vesterStakeConnection.getStakeMetadataAddress(vester.publicKey); let currentStakeAccountCheckpointsAddress = await vesterStakeConnection.getStakeAccountCheckpointsAddressByMetadata( stakeAccountMetadataAddress, @@ -2345,9 +2303,7 @@ describe("vesting", () => { assert.equal(currentStakeAccountCheckpointsAddress, undefined); let vesterStakeAccountMetadata = - await vesterStakeConnection.fetchStakeAccountMetadata( - vester.publicKey, - ); + await vesterStakeConnection.fetchStakeAccountMetadata(vester.publicKey); // a new checkpoint account must be created assert.equal( vesterStakeAccountMetadata.stakeAccountCheckpointsLastIndex, @@ -2395,9 +2351,7 @@ describe("vesting", () => { .then(confirm); vesterStakeAccountMetadata = - await vesterStakeConnection.fetchStakeAccountMetadata( - vester.publicKey, - ); + await vesterStakeConnection.fetchStakeAccountMetadata(vester.publicKey); previousStakeAccountCheckpointsAddress = await vesterStakeConnection.getStakeAccountCheckpointsAddressByMetadata( @@ -2492,9 +2446,7 @@ describe("vesting", () => { it("should fail to transfer without stakeAccountMetadata", async () => { let stakeAccountMetadataAddress = - await vesterStakeConnection.getStakeMetadataAddress( - vester.publicKey, - ); + await vesterStakeConnection.getStakeMetadataAddress(vester.publicKey); let stakeAccountCheckpointsAddress = await vesterStakeConnection.getStakeAccountCheckpointsAddressByMetadata( stakeAccountMetadataAddress, @@ -2526,17 +2478,14 @@ describe("vesting", () => { assert.fail("Expected error was not thrown"); } catch (e) { assert( - (e as AnchorError).error?.errorCode?.code === - "ErrorOfAccountParsing", + (e as AnchorError).error?.errorCode?.code === "ErrorOfAccountParsing", ); } }); it("should fail to transfer vest to myself", async () => { let stakeAccountMetadataAddress = - await vesterStakeConnection.getStakeMetadataAddress( - vester.publicKey, - ); + await vesterStakeConnection.getStakeMetadataAddress(vester.publicKey); let stakeAccountCheckpointsAddress = await vesterStakeConnection.getStakeAccountCheckpointsAddressByMetadata( stakeAccountMetadataAddress, @@ -2574,9 +2523,7 @@ describe("vesting", () => { it("should successfully transfer vest to another vester", async () => { let stakeAccountMetadataAddress = - await vesterStakeConnection.getStakeMetadataAddress( - vester.publicKey, - ); + await vesterStakeConnection.getStakeMetadataAddress(vester.publicKey); let newStakeAccountMetadataAddress = await newVesterStakeConnection.getStakeMetadataAddress( newVester.publicKey, @@ -2621,18 +2568,21 @@ describe("vesting", () => { vester.publicKey, ); let vesterDelegateStakeAccountMetadataAddress = - await vesterStakeConnection.getStakeMetadataAddress(vesterDelegateStakeAccountOwner); + await vesterStakeConnection.getStakeMetadataAddress( + vesterDelegateStakeAccountOwner, + ); let vesterDelegateStakeAccountCheckpointsAddress = await vesterStakeConnection.getStakeAccountCheckpointsAddressByMetadata( vesterDelegateStakeAccountMetadataAddress, false, ); - let newVesterDelegateStakeAccountOwner = await newVesterStakeConnection.delegates( - newVester.publicKey, - ); + let newVesterDelegateStakeAccountOwner = + await newVesterStakeConnection.delegates(newVester.publicKey); let newVesterDelegateStakeAccountMetadataAddress = - await newVesterStakeConnection.getStakeMetadataAddress(newVesterDelegateStakeAccountOwner); + await newVesterStakeConnection.getStakeMetadataAddress( + newVesterDelegateStakeAccountOwner, + ); let newVesterDelegateStakeAccountCheckpointsAddress = await newVesterStakeConnection.getStakeAccountCheckpointsAddressByMetadata( newVesterDelegateStakeAccountMetadataAddress, @@ -2651,7 +2601,8 @@ describe("vesting", () => { .createCheckpoints() .accounts({ payer: accounts.vester, - stakeAccountCheckpoints: previousNewVesterDelegateStakeAccountCheckpointsAddress, + stakeAccountCheckpoints: + previousNewVesterDelegateStakeAccountCheckpointsAddress, stakeAccountMetadata: newVesterDelegateStakeAccountMetadataAddress, }) .signers([vester]) @@ -2668,7 +2619,10 @@ describe("vesting", () => { let tx = new Transaction(); tx.instructions = [ await vesterStakeConnection.program.methods - .delegate(newVesterDelegateStakeAccountOwner, vesterDelegateStakeAccountOwner) + .delegate( + newVesterDelegateStakeAccountOwner, + vesterDelegateStakeAccountOwner, + ) .accountsPartial({ payer: vester.publicKey, currentDelegateStakeAccountCheckpoints: @@ -2696,7 +2650,10 @@ describe("vesting", () => { }) .instruction(), await vesterStakeConnection.program.methods - .delegate(vesterDelegateStakeAccountOwner, newVesterDelegateStakeAccountOwner) + .delegate( + vesterDelegateStakeAccountOwner, + newVesterDelegateStakeAccountOwner, + ) .accountsPartial({ payer: vester.publicKey, currentDelegateStakeAccountCheckpoints: @@ -2730,9 +2687,7 @@ describe("vesting", () => { ); let vesterStakeMetadata: StakeAccountMetadata = - await vesterStakeConnection.fetchStakeAccountMetadata( - vester.publicKey, - ); + await vesterStakeConnection.fetchStakeAccountMetadata(vester.publicKey); let stakeAccountCheckpointsAddress = await vesterStakeConnection.getStakeAccountCheckpointsAddressByMetadata( stakeAccountMetadataAddress, @@ -2821,9 +2776,7 @@ describe("vesting", () => { it("should successfully transfer vest to another vester with votes delegated to another user", async () => { let vester2StakeAccountMetadataAddress = - await vester2StakeConnection.getStakeMetadataAddress( - vester2.publicKey, - ); + await vester2StakeConnection.getStakeMetadataAddress(vester2.publicKey); let vester2StakeAccountCheckpointsAddress = await vester2StakeConnection.getStakeAccountCheckpointsAddressByMetadata( vester2StakeAccountMetadataAddress, @@ -2927,9 +2880,7 @@ describe("vesting", () => { ); let vester2StakeMetadata: StakeAccountMetadata = - await vester2StakeConnection.fetchStakeAccountMetadata( - vester2.publicKey, - ); + await vester2StakeConnection.fetchStakeAccountMetadata(vester2.publicKey); let vester2StakeCheckpoints: CheckpointAccount = await vester2StakeConnection.fetchCheckpointAccount( vester2StakeAccountCheckpointsAddress, @@ -3143,9 +3094,7 @@ describe("vesting", () => { it("should successfully transfer vest to another vester with an existing vest of the same kind", async () => { let stakeAccountMetadataAddress = - await vesterStakeConnection.getStakeMetadataAddress( - vester.publicKey, - ); + await vesterStakeConnection.getStakeMetadataAddress(vester.publicKey); let stakeAccountCheckpointsAddress = await vesterStakeConnection.getStakeAccountCheckpointsAddressByMetadata( stakeAccountMetadataAddress, @@ -3177,18 +3126,21 @@ describe("vesting", () => { vester.publicKey, ); let vesterDelegateStakeAccountMetadataAddress = - await vesterStakeConnection.getStakeMetadataAddress(vesterDelegateStakeAccountOwner); + await vesterStakeConnection.getStakeMetadataAddress( + vesterDelegateStakeAccountOwner, + ); let vesterDelegateStakeAccountCheckpointsAddress = await vesterStakeConnection.getStakeAccountCheckpointsAddressByMetadata( vesterDelegateStakeAccountMetadataAddress, false, ); - let newVesterDelegateStakeAccountOwner = await newVesterStakeConnection.delegates( - newVester.publicKey, - ); + let newVesterDelegateStakeAccountOwner = + await newVesterStakeConnection.delegates(newVester.publicKey); let newVesterDelegateStakeAccountMetadataAddress = - await newVesterStakeConnection.getStakeMetadataAddress(newVesterDelegateStakeAccountOwner); + await newVesterStakeConnection.getStakeMetadataAddress( + newVesterDelegateStakeAccountOwner, + ); let newVesterDelegateStakeAccountCheckpointsAddress = await newVesterStakeConnection.getStakeAccountCheckpointsAddressByMetadata( newVesterDelegateStakeAccountMetadataAddress, @@ -3198,7 +3150,10 @@ describe("vesting", () => { let tx = new Transaction(); tx.instructions = [ await vesterStakeConnection.program.methods - .delegate(newVesterDelegateStakeAccountOwner, vesterDelegateStakeAccountOwner) + .delegate( + newVesterDelegateStakeAccountOwner, + vesterDelegateStakeAccountOwner, + ) .accountsPartial({ payer: vester.publicKey, currentDelegateStakeAccountCheckpoints: @@ -3226,7 +3181,10 @@ describe("vesting", () => { }) .instruction(), await vesterStakeConnection.program.methods - .delegate(vesterDelegateStakeAccountOwner, newVesterDelegateStakeAccountOwner) + .delegate( + vesterDelegateStakeAccountOwner, + newVesterDelegateStakeAccountOwner, + ) .accountsPartial({ payer: vester.publicKey, currentDelegateStakeAccountCheckpoints: @@ -3260,9 +3218,7 @@ describe("vesting", () => { ); let vesterStakeMetadata: StakeAccountMetadata = - await vesterStakeConnection.fetchStakeAccountMetadata( - vester.publicKey, - ); + await vesterStakeConnection.fetchStakeAccountMetadata(vester.publicKey); let vesterStakeCheckpoints: CheckpointAccount = await vesterStakeConnection.fetchCheckpointAccount( stakeAccountCheckpointsAddress, @@ -3440,9 +3396,7 @@ describe("vesting", () => { it("should fail to transfer vest if newVestingBalance has stake account metadata and vestingBalance has no stake account metadata", async () => { let stakeAccountMetadataAddress = - await vester3StakeConnection.getStakeMetadataAddress( - vester3.publicKey, - ); + await vester3StakeConnection.getStakeMetadataAddress(vester3.publicKey); let stakeAccountCheckpointsAddress = await vester3StakeConnection.getStakeAccountCheckpointsAddressByMetadata( stakeAccountMetadataAddress, @@ -3494,12 +3448,7 @@ describe("vesting", () => { } }); - it("should fail to transfer vest if the sender hasn't delegated, but the recipient has", async () => { - - }); - - it("should successfully transfer a vest when both the sender and recipient haven't delegated", async () => { - - }); + it("should fail to transfer vest if the sender hasn't delegated, but the recipient has", async () => {}); + it("should successfully transfer a vest when both the sender and recipient haven't delegated", async () => {}); }); From 300336fbb25bd3255151199d9af356dd4083e4d5 Mon Sep 17 00:00:00 2001 From: zpoken <82594516+zpoken@users.noreply.github.com> Date: Thu, 6 Mar 2025 16:39:32 +0200 Subject: [PATCH 12/14] Update devnet test scripts for vesting. Add transferVesting script --- solana/.gitignore | 1 + solana/app/deploy/devnet/tests/12_deposit.ts | 6 +- .../deploy/devnet/tests/13_withdrawTokens.ts | 4 +- .../tests/22_fetchSpokeMetadataCollector.ts | 4 +- .../tests/23_fetchVoteWeightWindowLengths.ts | 4 +- .../tests/24_fetchProposalAccountData.ts | 4 +- .../tests/25_fetchSpokeMessageExecutor.ts | 4 +- .../app/deploy/devnet/vesting/claimVesting.ts | 58 ++-- .../devnet/vesting/createVestingConfig.ts | 18 +- .../deploy/devnet/vesting/delegateWithVest.ts | 2 +- solana/app/deploy/devnet/vesting/result.md | 62 ++++ .../deploy/devnet/vesting/transferVesting.ts | 265 ++++++++++++++++++ .../app/helpers/utils/parse_transactions.ts | 2 +- 13 files changed, 393 insertions(+), 41 deletions(-) create mode 100644 solana/app/deploy/devnet/vesting/result.md create mode 100644 solana/app/deploy/devnet/vesting/transferVesting.ts diff --git a/solana/.gitignore b/solana/.gitignore index 4ddd32ff..f28f724f 100644 --- a/solana/.gitignore +++ b/solana/.gitignore @@ -10,3 +10,4 @@ snapshots package-lock.json yarn.lock /app/e2e/log/*.json +app/keypairs/deployer.json diff --git a/solana/app/deploy/devnet/tests/12_deposit.ts b/solana/app/deploy/devnet/tests/12_deposit.ts index 42b61dce..260996bd 100644 --- a/solana/app/deploy/devnet/tests/12_deposit.ts +++ b/solana/app/deploy/devnet/tests/12_deposit.ts @@ -11,7 +11,7 @@ import * as wasm from "@wormhole/staking-wasm"; import { RPC_NODE, STAKING_ADDRESS, - USER_AUTHORITY_KEYPAIR, + USER2_AUTHORITY_KEYPAIR, WORMHOLE_TOKEN, } from "../constants"; @@ -20,7 +20,7 @@ async function main() { const connection = new Connection(RPC_NODE); const provider = new AnchorProvider( connection, - new Wallet(USER_AUTHORITY_KEYPAIR), + new Wallet(USER2_AUTHORITY_KEYPAIR), {}, ); const user = provider.wallet.publicKey; @@ -46,7 +46,7 @@ async function main() { from_account, toAccount, provider.wallet.publicKey, - 50, + 500000000, ); transaction.add(ix); diff --git a/solana/app/deploy/devnet/tests/13_withdrawTokens.ts b/solana/app/deploy/devnet/tests/13_withdrawTokens.ts index b3296ce9..95f47741 100644 --- a/solana/app/deploy/devnet/tests/13_withdrawTokens.ts +++ b/solana/app/deploy/devnet/tests/13_withdrawTokens.ts @@ -4,14 +4,14 @@ import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; import { StakeConnection } from "../../../StakeConnection"; import { WHTokenBalance } from "../../../whTokenBalance"; -import { RPC_NODE, USER_AUTHORITY_KEYPAIR } from "../constants"; +import { RPC_NODE, USER2_AUTHORITY_KEYPAIR } from "../constants"; async function main() { try { const connection = new Connection(RPC_NODE); const provider = new AnchorProvider( connection, - new Wallet(USER_AUTHORITY_KEYPAIR), + new Wallet(USER2_AUTHORITY_KEYPAIR), {}, ); const stakeConnection = await StakeConnection.createStakeConnection( diff --git a/solana/app/deploy/devnet/tests/22_fetchSpokeMetadataCollector.ts b/solana/app/deploy/devnet/tests/22_fetchSpokeMetadataCollector.ts index 2b0184aa..7f62ff12 100644 --- a/solana/app/deploy/devnet/tests/22_fetchSpokeMetadataCollector.ts +++ b/solana/app/deploy/devnet/tests/22_fetchSpokeMetadataCollector.ts @@ -4,7 +4,7 @@ import { Wallet, AnchorProvider, utils } from "@coral-xyz/anchor"; import { Connection, PublicKey } from "@solana/web3.js"; import * as wasm from "@wormhole/staking-wasm"; import { - DEPLOYER_AUTHORITY_KEYPAIR, + USER2_AUTHORITY_KEYPAIR, HUB_CHAIN_ID, hubProposalMetadataUint8Array, RPC_NODE, @@ -15,7 +15,7 @@ async function main() { const connection = new Connection(RPC_NODE); const provider = new AnchorProvider( connection, - new Wallet(DEPLOYER_AUTHORITY_KEYPAIR), + new Wallet(USER2_AUTHORITY_KEYPAIR), {}, ); const stakeConnection = await StakeConnection.createStakeConnection( diff --git a/solana/app/deploy/devnet/tests/23_fetchVoteWeightWindowLengths.ts b/solana/app/deploy/devnet/tests/23_fetchVoteWeightWindowLengths.ts index 31d53e0f..7f08cbbe 100644 --- a/solana/app/deploy/devnet/tests/23_fetchVoteWeightWindowLengths.ts +++ b/solana/app/deploy/devnet/tests/23_fetchVoteWeightWindowLengths.ts @@ -4,7 +4,7 @@ import { Wallet, AnchorProvider, utils } from "@coral-xyz/anchor"; import { Connection, PublicKey } from "@solana/web3.js"; import * as wasm from "@wormhole/staking-wasm"; import { - DEPLOYER_AUTHORITY_KEYPAIR, + USER2_AUTHORITY_KEYPAIR, RPC_NODE, VOTE_WEIGHT_WINDOW_LENGTHS, } from "../constants"; @@ -18,7 +18,7 @@ async function main() { const connection = new Connection(RPC_NODE); const provider = new AnchorProvider( connection, - new Wallet(DEPLOYER_AUTHORITY_KEYPAIR), + new Wallet(USER2_AUTHORITY_KEYPAIR), {}, ); const stakeConnection = await StakeConnection.createStakeConnection( diff --git a/solana/app/deploy/devnet/tests/24_fetchProposalAccountData.ts b/solana/app/deploy/devnet/tests/24_fetchProposalAccountData.ts index da2e9f83..cd009b68 100644 --- a/solana/app/deploy/devnet/tests/24_fetchProposalAccountData.ts +++ b/solana/app/deploy/devnet/tests/24_fetchProposalAccountData.ts @@ -3,7 +3,7 @@ import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; import { Connection } from "@solana/web3.js"; import { StakeConnection } from "../../../StakeConnection"; -import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "../constants"; +import { USER2_AUTHORITY_KEYPAIR, RPC_NODE } from "../constants"; import { ethers } from "ethers"; import input from "@inquirer/input"; @@ -12,7 +12,7 @@ async function main() { const connection = new Connection(RPC_NODE); const provider = new AnchorProvider( connection, - new Wallet(DEPLOYER_AUTHORITY_KEYPAIR), + new Wallet(USER2_AUTHORITY_KEYPAIR), {}, ); diff --git a/solana/app/deploy/devnet/tests/25_fetchSpokeMessageExecutor.ts b/solana/app/deploy/devnet/tests/25_fetchSpokeMessageExecutor.ts index b33285f3..f81c79cb 100644 --- a/solana/app/deploy/devnet/tests/25_fetchSpokeMessageExecutor.ts +++ b/solana/app/deploy/devnet/tests/25_fetchSpokeMessageExecutor.ts @@ -4,7 +4,7 @@ import { Wallet, AnchorProvider, utils } from "@coral-xyz/anchor"; import { Connection, PublicKey } from "@solana/web3.js"; import * as wasm from "@wormhole/staking-wasm"; import { - DEPLOYER_AUTHORITY_KEYPAIR, + USER2_AUTHORITY_KEYPAIR, HUB_CHAIN_ID, hubSolanaMessageDispatcherPublicKey, RPC_NODE, @@ -15,7 +15,7 @@ async function main() { const connection = new Connection(RPC_NODE); const provider = new AnchorProvider( connection, - new Wallet(DEPLOYER_AUTHORITY_KEYPAIR), + new Wallet(USER2_AUTHORITY_KEYPAIR), {}, ); const stakeConnection = await StakeConnection.createStakeConnection( diff --git a/solana/app/deploy/devnet/vesting/claimVesting.ts b/solana/app/deploy/devnet/vesting/claimVesting.ts index 62da26d2..af02e34e 100644 --- a/solana/app/deploy/devnet/vesting/claimVesting.ts +++ b/solana/app/deploy/devnet/vesting/claimVesting.ts @@ -39,8 +39,20 @@ async function main() { return signature; }; - const NOW = new BN(1740006704); - const config = new PublicKey("BcJSiMQLggZxJ3v7kLLnQemB7Z6XJABV5Bci5LX7KhA3"); + const NOW = new BN(1741270829); + + const seedBufferHex = "83cda9d4e2445bff"; + const seedBuffer = Buffer.from(seedBufferHex, 'hex'); + const config = PublicKey.findProgramAddressSync( + [ + Buffer.from(wasm.Constants.VESTING_CONFIG_SEED()), + WORMHOLE_TOKEN.toBuffer(), + seedBuffer, + ], + vesterStakeConnection.program.programId, + )[0]; +// const config = new PublicKey("AHfPLNVnRGoACwMfoRCwWnCEJWjMX4x7Yq3ufg3tpjQQ"); + console.log("Vesting config account:", config); const vault = getAssociatedTokenAddressSync( WORMHOLE_TOKEN, @@ -80,21 +92,6 @@ async function main() { vesterStakeConnection.program.programId, )[0]; - let accounts = { - admin: admin.publicKey, - mint: WORMHOLE_TOKEN, - config, - vault, - vester: vester.publicKey, - vesterTa, - adminAta, - recovery: adminAta, - associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, - tokenProgram: TOKEN_PROGRAM_ID, - systemProgram: SystemProgram.programId, - vestingBalance: vestingBalance, - }; - let stakeAccountMetadataAddress = await vesterStakeConnection.getStakeMetadataAddress(vester.publicKey); let stakeAccountMetadataData = @@ -110,17 +107,28 @@ async function main() { false, ); + let accounts = { + vester: vester.publicKey, + mint: WORMHOLE_TOKEN, + vault, + vesterTa, + config, + vest: vestNow, + vestingBalance, + delegateStakeAccountCheckpoints: delegateStakeAccountCheckpointsAddress, + delegateStakeAccountMetadata: stakeAccountMetadataAddress, + stakeAccountMetadata: stakeAccountMetadataAddress, + globalConfig: vesterStakeConnection.configAddress, + admin: admin.publicKey, + associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, + tokenProgram: TOKEN_PROGRAM_ID, + systemProgram: SystemProgram.programId, + }; + console.log("Starting claimVesting..."); await vesterStakeConnection.program.methods .claimVesting() - .accountsPartial({ - ...accounts, - vest: vestNow, - delegateStakeAccountCheckpoints: delegateStakeAccountCheckpointsAddress, - delegateStakeAccountMetadata: stakeAccountMetadataAddress, - stakeAccountMetadata: stakeAccountMetadataAddress, - globalConfig: vesterStakeConnection.configAddress, - }) + .accountsPartial({ ...accounts }) .signers([vester]) .rpc() .then(confirm); diff --git a/solana/app/deploy/devnet/vesting/createVestingConfig.ts b/solana/app/deploy/devnet/vesting/createVestingConfig.ts index 48d6f8ef..2def78a9 100644 --- a/solana/app/deploy/devnet/vesting/createVestingConfig.ts +++ b/solana/app/deploy/devnet/vesting/createVestingConfig.ts @@ -24,6 +24,10 @@ import { getAssociatedTokenAddressSync, } from "@solana/spl-token"; +function sleep(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + async function main() { const admin = VESTING_ADMIN_KEYPAIR; const vester = USER_AUTHORITY_KEYPAIR; @@ -63,11 +67,15 @@ async function main() { const seed = new BN(randomBytes(8)); console.log("Vesting config random seed:", seed); + const seedBuffer = seed.toBuffer("le", 8); + console.log("seedBuffer:", seedBuffer); + console.log("seedBufferHex:", seedBuffer.toString("hex")); + const config = PublicKey.findProgramAddressSync( [ Buffer.from(wasm.Constants.VESTING_CONFIG_SEED()), WORMHOLE_TOKEN.toBuffer(), - seed.toBuffer("le", 8), + seedBuffer, ], stakeConnection.program.programId, )[0]; @@ -125,6 +133,7 @@ async function main() { .rpc() .then(confirm); console.log("Vesting config initialized"); + await sleep(3000); console.log("Creating vesting balance for vester..."); await stakeConnection.program.methods @@ -134,6 +143,7 @@ async function main() { .rpc() .then(confirm); console.log("Vesting balance for vester created"); + await sleep(3000); console.log(`Creating vest for vester at NOW (${NOW.toString()})...`); await stakeConnection.program.methods @@ -143,6 +153,7 @@ async function main() { .rpc() .then(confirm); console.log(`Vest for vester at NOW (${NOW.toString()}) created`); + await sleep(3000); console.log(`Creating vest for vester at LATER (${LATER.toString()})...`); await stakeConnection.program.methods @@ -152,6 +163,7 @@ async function main() { .rpc() .then(confirm); console.log(`Vest for vester at LATER (${LATER.toString()}) created`); + await sleep(3000); console.log( `Creating vest for vester at EVEN_LATER (${EVEN_LATER.toString()})...`, @@ -165,6 +177,7 @@ async function main() { console.log( `Vest for vester at EVEN_LATER (${EVEN_LATER.toString()}) created`, ); + await sleep(3000); const vestLater = PublicKey.findProgramAddressSync( [ @@ -184,6 +197,7 @@ async function main() { .rpc() .then(confirm); console.log(`Vest for vester at LATER (${LATER.toString()}) canceled`); + await sleep(3000); console.log("Transferring WH tokens to Vault..."); const tx = new Transaction(); @@ -201,6 +215,7 @@ async function main() { ); await stakeConnection.provider.sendAndConfirm(tx, [admin]); console.log("WH tokens transferred to Vault"); + await sleep(3000); console.log("Withdrawing surplus..."); await stakeConnection.program.methods @@ -210,6 +225,7 @@ async function main() { .rpc() .then(confirm); console.log("Surplus withdrawn"); + await sleep(3000); console.log("Finalizing vesting config..."); await stakeConnection.program.methods diff --git a/solana/app/deploy/devnet/vesting/delegateWithVest.ts b/solana/app/deploy/devnet/vesting/delegateWithVest.ts index d59c0ea6..5de38fc6 100644 --- a/solana/app/deploy/devnet/vesting/delegateWithVest.ts +++ b/solana/app/deploy/devnet/vesting/delegateWithVest.ts @@ -16,7 +16,7 @@ async function main() { vesterProvider.wallet as Wallet, ); - const config = new PublicKey("BcJSiMQLggZxJ3v7kLLnQemB7Z6XJABV5Bci5LX7KhA3"); + const config = new PublicKey("AHfPLNVnRGoACwMfoRCwWnCEJWjMX4x7Yq3ufg3tpjQQ"); console.log(`Delegate WH tokens with vests`); await vesterStakeConnection.delegateWithVest( diff --git a/solana/app/deploy/devnet/vesting/result.md b/solana/app/deploy/devnet/vesting/result.md new file mode 100644 index 00000000..18fd44e0 --- /dev/null +++ b/solana/app/deploy/devnet/vesting/result.md @@ -0,0 +1,62 @@ +npx ts-node app/deploy/devnet/vesting/createVestingConfig.ts + +Vesting claim times: +NOW: 1741270829 (2025-03-06T14:20:29.000Z) +LATER: 1741271829 (2025-03-06T14:37:09.000Z) +EVEN_LATER: 1741272829 (2025-03-06T14:53:49.000Z) +Vesting config random seed: +seedBuffer: +seedBufferHex: 83cda9d4e2445bff +Vesting config account: PublicKey [PublicKey(AHfPLNVnRGoACwMfoRCwWnCEJWjMX4x7Yq3ufg3tpjQQ)] { + _bn: +} +Vesting balance account for vester: PublicKey [PublicKey(GCSubvJoUD5hDbzZeLVWzBGkbej22wUkT1aZgYPDLyzW)] { + _bn: +} +Initializing vesting config... +Vesting config initialized +Creating vesting balance for vester... +Vesting balance for vester created +Creating vest for vester at NOW (1741270829)... +Vest for vester at NOW (1741270829) created +Creating vest for vester at LATER (1741271829)... +Vest for vester at LATER (1741271829) created +Creating vest for vester at EVEN_LATER (1741272829)... +Vest for vester at EVEN_LATER (1741272829) created +Canceling vest for vester at LATER (1741271829)... +Vest for vester at LATER (1741271829) canceled +Transferring WH tokens to Vault... +WH tokens transferred to Vault +Withdrawing surplus... +Surplus withdrawn +Finalizing vesting config... +Vesting config finalized + +---------------- + +npx ts-node app/deploy/devnet/vesting/claimVesting.ts + +Vesting config account: PublicKey [PublicKey(AHfPLNVnRGoACwMfoRCwWnCEJWjMX4x7Yq3ufg3tpjQQ)] { + _bn: +} +Starting claimVesting... +claimVesting completed successfully. + +---------------- + +npx ts-node app/deploy/devnet/vesting/delegateWithVest.ts + +Delegate WH tokens with vests +WH tokens with vests successfully delegated + +---------------- + +npx ts-node app/deploy/devnet/vesting/transferVesting.ts + +vestingBalanceAccount.totalVestingBalance: 20000000 +Starting transferVesting... +transferVesting completed successfully. +vestingBalanceAccount.totalVestingBalance: 0 +newVestingBalanceAccount.totalVestingBalance: 20000000 +vesterStakeMetadata.recordedVestingBalance: 20000000 +vesterStakeMetadata.recordedBalance: 50000040000150 diff --git a/solana/app/deploy/devnet/vesting/transferVesting.ts b/solana/app/deploy/devnet/vesting/transferVesting.ts new file mode 100644 index 00000000..4e6c3177 --- /dev/null +++ b/solana/app/deploy/devnet/vesting/transferVesting.ts @@ -0,0 +1,265 @@ +// Usage: npx ts-node app/deploy/devnet/vesting/transferVesting.ts + +import { Wallet, AnchorProvider } from "@coral-xyz/anchor"; +import { Connection, PublicKey, SystemProgram, Transaction } from "@solana/web3.js"; +import { + VESTING_ADMIN_KEYPAIR, + USER_AUTHORITY_KEYPAIR, + USER2_AUTHORITY_KEYPAIR, + WORMHOLE_TOKEN, + RPC_NODE, +} from "../constants"; +import { StakeAccountMetadata, StakeConnection } from "../../../StakeConnection"; +import BN from "bn.js"; +import * as wasm from "@wormhole/staking-wasm"; +import { + ASSOCIATED_TOKEN_PROGRAM_ID, + TOKEN_PROGRAM_ID, + getAssociatedTokenAddressSync, +} from "@solana/spl-token"; +import { CheckpointAccount } from "../../../checkpoints"; +import { WHTokenBalance } from "../../../whTokenBalance"; + +function sleep(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +async function main() { + const admin = VESTING_ADMIN_KEYPAIR; + const vester = USER_AUTHORITY_KEYPAIR; + const newVester = USER2_AUTHORITY_KEYPAIR; + + const connection = new Connection(RPC_NODE); + const vesterProvider = new AnchorProvider(connection, new Wallet(vester), {}); + const vesterStakeConnection = await StakeConnection.createStakeConnection( + connection, + vesterProvider.wallet as Wallet, + ); + + const confirm = async (signature: string): Promise => { + const block = + await vesterStakeConnection.provider.connection.getLatestBlockhash(); + await vesterStakeConnection.provider.connection.confirmTransaction({ + signature, + ...block, + }); + + return signature; + }; + + const EVEN_LATER = new BN(1741272829); + const config = new PublicKey("AHfPLNVnRGoACwMfoRCwWnCEJWjMX4x7Yq3ufg3tpjQQ"); + + const vesterTa = getAssociatedTokenAddressSync( + WORMHOLE_TOKEN, + vester.publicKey, + false, + TOKEN_PROGRAM_ID, + ); + const newVesterTa = getAssociatedTokenAddressSync( + WORMHOLE_TOKEN, + newVester.publicKey, + false, + TOKEN_PROGRAM_ID, + ); + const adminAta = getAssociatedTokenAddressSync( + WORMHOLE_TOKEN, + admin.publicKey, + false, + TOKEN_PROGRAM_ID, + ); + + const vestEvenLater = PublicKey.findProgramAddressSync( + [ + Buffer.from(wasm.Constants.VEST_SEED()), + config.toBuffer(), + vesterTa.toBuffer(), + EVEN_LATER.toBuffer("le", 8), + ], + vesterStakeConnection.program.programId, + )[0]; + const newVestEvenLater = PublicKey.findProgramAddressSync( + [ + Buffer.from(wasm.Constants.VEST_SEED()), + config.toBuffer(), + newVesterTa.toBuffer(), + EVEN_LATER.toBuffer("le", 8), + ], + vesterStakeConnection.program.programId, + )[0]; + + const vestingBalance = PublicKey.findProgramAddressSync( + [ + Buffer.from(wasm.Constants.VESTING_BALANCE_SEED()), + config.toBuffer(), + vester.publicKey.toBuffer(), + ], + vesterStakeConnection.program.programId, + )[0]; + const newVestingBalance = PublicKey.findProgramAddressSync( + [ + Buffer.from(wasm.Constants.VESTING_BALANCE_SEED()), + config.toBuffer(), + newVester.publicKey.toBuffer(), + ], + vesterStakeConnection.program.programId, + )[0]; + + let stakeAccountMetadataAddress = + await vesterStakeConnection.getStakeMetadataAddress( + vester.publicKey + ); +// console.log("stakeAccountMetadataAddress:", stakeAccountMetadataAddress) + let newStakeAccountMetadataAddress = + await vesterStakeConnection.getStakeMetadataAddress( + newVester.publicKey, + ); + + let vestingBalanceAccount = + await vesterStakeConnection.program.account.vestingBalance.fetch( + vestingBalance, + ); + console.log("vestingBalanceAccount.totalVestingBalance: ", vestingBalanceAccount.totalVestingBalance.toString()) + + let vesterDelegateStakeAccountOwner = await vesterStakeConnection.delegates( + vester.publicKey, + ); + let vesterDelegateStakeAccountMetadataAddress = + await vesterStakeConnection.getStakeMetadataAddress( + vesterDelegateStakeAccountOwner, + ); + let vesterDelegateStakeAccountCheckpointsAddress = + await vesterStakeConnection.getStakeAccountCheckpointsAddressByMetadata( + vesterDelegateStakeAccountMetadataAddress, + false, + ); + + let newVesterDelegateStakeAccountOwner = + await vesterStakeConnection.delegates(newVester.publicKey); + let newVesterDelegateStakeAccountMetadataAddress = + await vesterStakeConnection.getStakeMetadataAddress( + newVesterDelegateStakeAccountOwner, + ); + let newVesterDelegateStakeAccountCheckpointsAddress = + await vesterStakeConnection.getStakeAccountCheckpointsAddressByMetadata( + newVesterDelegateStakeAccountMetadataAddress, + false, + ); + + let accounts = { + vester: vester.publicKey, + mint: WORMHOLE_TOKEN, + vesterTa, + newVesterTa, + config, + vest: vestEvenLater, + newVest: newVestEvenLater, + vestingBalance, + newVestingBalance, + globalConfig: vesterStakeConnection.configAddress, + delegateStakeAccountCheckpoints: newVesterDelegateStakeAccountCheckpointsAddress, + delegateStakeAccountMetadata: newVesterDelegateStakeAccountMetadataAddress, + stakeAccountMetadata: stakeAccountMetadataAddress, + newStakeAccountMetadata: null, + associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, + tokenProgram: TOKEN_PROGRAM_ID, + systemProgram: SystemProgram.programId, + }; + + console.log("Starting transferVesting..."); + let tx = new Transaction(); + tx.instructions = [ + await vesterStakeConnection.program.methods + .delegate( + newVesterDelegateStakeAccountOwner, + vesterDelegateStakeAccountOwner, + ) + .accountsPartial({ + payer: vester.publicKey, + currentDelegateStakeAccountCheckpoints: + vesterDelegateStakeAccountCheckpointsAddress, + delegateeStakeAccountCheckpoints: + newVesterDelegateStakeAccountCheckpointsAddress, + vestingConfig: config, + vestingBalance: vestingBalance, + mint: WORMHOLE_TOKEN, + }) + .instruction(), + await vesterStakeConnection.program.methods + .transferVesting() + .accountsPartial({ ...accounts }) + .instruction(), + await vesterStakeConnection.program.methods + .delegate( + vesterDelegateStakeAccountOwner, + newVesterDelegateStakeAccountOwner, + ) + .accountsPartial({ + payer: vester.publicKey, + currentDelegateStakeAccountCheckpoints: + newVesterDelegateStakeAccountCheckpointsAddress, + delegateeStakeAccountCheckpoints: + vesterDelegateStakeAccountCheckpointsAddress, + vestingConfig: config, + vestingBalance: vestingBalance, + mint: WORMHOLE_TOKEN, + }) + .instruction(), + ]; + await vesterStakeConnection.provider.sendAndConfirm(tx, [vester]); + console.log("transferVesting completed successfully."); + +// console.log(`Delegate WH tokens with vests`); +// await vesterStakeConnection.delegateWithVest( +// newVesterDelegateStakeAccountOwner, +// WHTokenBalance.fromString("0"), +// true, +// config, +// ); +// console.log(`WH tokens with vests successfully delegated`); +// await sleep(3000); +// +// console.log("Starting transferVesting..."); +// await vesterStakeConnection.program.methods +// .transferVesting() +// .accountsPartial({ +// ...accounts +// }) +// .rpc() +// .then(confirm); +// console.log("transferVesting completed successfully."); +// await sleep(3000); +// +// console.log(`Delegate WH tokens with vests`); +// await vesterStakeConnection.delegateWithVest( +// vesterDelegateStakeAccountOwner, +// WHTokenBalance.fromString("0"), +// true, +// config, +// ); +// console.log(`WH tokens with vests successfully delegated`); + + vestingBalanceAccount = + await vesterStakeConnection.program.account.vestingBalance.fetch( + vestingBalance, + ); + let newVestingBalanceAccount = + await vesterStakeConnection.program.account.vestingBalance.fetch( + newVestingBalance, + ); + console.log("vestingBalanceAccount.totalVestingBalance: ", vestingBalanceAccount.totalVestingBalance.toString()) + console.log("newVestingBalanceAccount.totalVestingBalance: ", newVestingBalanceAccount.totalVestingBalance.toString()) + + let vesterStakeMetadata: StakeAccountMetadata = + await vesterStakeConnection.fetchStakeAccountMetadata(vester.publicKey); + let stakeAccountCheckpointsAddress = + await vesterStakeConnection.getStakeAccountCheckpointsAddressByMetadata( + stakeAccountMetadataAddress, + false, + ); + + console.log("vesterStakeMetadata.recordedVestingBalance: ", vesterStakeMetadata.recordedVestingBalance.toString()) + console.log("vesterStakeMetadata.recordedBalance: ", vesterStakeMetadata.recordedBalance.toString()) +} + +main(); diff --git a/solana/app/helpers/utils/parse_transactions.ts b/solana/app/helpers/utils/parse_transactions.ts index 6402c78b..b8076d85 100644 --- a/solana/app/helpers/utils/parse_transactions.ts +++ b/solana/app/helpers/utils/parse_transactions.ts @@ -6,7 +6,7 @@ import { TransactionSignature, } from "@solana/web3.js"; import { BorshCoder } from "@coral-xyz/anchor"; -import IDL from "../../target/idl/staking.json"; +import IDL from "../../../target/idl/staking.json"; // Gets program transactions export async function getProgramTransactions( From 1cd1da174899562f3670a2147277fceaa4b0e299 Mon Sep 17 00:00:00 2001 From: zpoken <82594516+zpoken@users.noreply.github.com> Date: Thu, 6 Mar 2025 16:43:02 +0200 Subject: [PATCH 13/14] Apply yarn format --- .../app/deploy/devnet/vesting/claimVesting.ts | 4 +- .../deploy/devnet/vesting/transferVesting.ts | 108 +++++++++++------- solana/programs/staking/src/context.rs | 8 +- .../staking/src/contexts/cancel_vesting.rs | 6 +- .../staking/src/contexts/claim_vesting.rs | 2 +- .../staking/src/contexts/create_vesting.rs | 6 +- .../staking/src/contexts/withdraw_surplus.rs | 4 +- 7 files changed, 78 insertions(+), 60 deletions(-) diff --git a/solana/app/deploy/devnet/vesting/claimVesting.ts b/solana/app/deploy/devnet/vesting/claimVesting.ts index af02e34e..0f2f02f1 100644 --- a/solana/app/deploy/devnet/vesting/claimVesting.ts +++ b/solana/app/deploy/devnet/vesting/claimVesting.ts @@ -42,7 +42,7 @@ async function main() { const NOW = new BN(1741270829); const seedBufferHex = "83cda9d4e2445bff"; - const seedBuffer = Buffer.from(seedBufferHex, 'hex'); + const seedBuffer = Buffer.from(seedBufferHex, "hex"); const config = PublicKey.findProgramAddressSync( [ Buffer.from(wasm.Constants.VESTING_CONFIG_SEED()), @@ -51,7 +51,7 @@ async function main() { ], vesterStakeConnection.program.programId, )[0]; -// const config = new PublicKey("AHfPLNVnRGoACwMfoRCwWnCEJWjMX4x7Yq3ufg3tpjQQ"); + // const config = new PublicKey("AHfPLNVnRGoACwMfoRCwWnCEJWjMX4x7Yq3ufg3tpjQQ"); console.log("Vesting config account:", config); const vault = getAssociatedTokenAddressSync( diff --git a/solana/app/deploy/devnet/vesting/transferVesting.ts b/solana/app/deploy/devnet/vesting/transferVesting.ts index 4e6c3177..5e2f3233 100644 --- a/solana/app/deploy/devnet/vesting/transferVesting.ts +++ b/solana/app/deploy/devnet/vesting/transferVesting.ts @@ -1,7 +1,12 @@ // Usage: npx ts-node app/deploy/devnet/vesting/transferVesting.ts import { Wallet, AnchorProvider } from "@coral-xyz/anchor"; -import { Connection, PublicKey, SystemProgram, Transaction } from "@solana/web3.js"; +import { + Connection, + PublicKey, + SystemProgram, + Transaction, +} from "@solana/web3.js"; import { VESTING_ADMIN_KEYPAIR, USER_AUTHORITY_KEYPAIR, @@ -9,7 +14,10 @@ import { WORMHOLE_TOKEN, RPC_NODE, } from "../constants"; -import { StakeAccountMetadata, StakeConnection } from "../../../StakeConnection"; +import { + StakeAccountMetadata, + StakeConnection, +} from "../../../StakeConnection"; import BN from "bn.js"; import * as wasm from "@wormhole/staking-wasm"; import { @@ -106,20 +114,19 @@ async function main() { )[0]; let stakeAccountMetadataAddress = - await vesterStakeConnection.getStakeMetadataAddress( - vester.publicKey - ); -// console.log("stakeAccountMetadataAddress:", stakeAccountMetadataAddress) + await vesterStakeConnection.getStakeMetadataAddress(vester.publicKey); + // console.log("stakeAccountMetadataAddress:", stakeAccountMetadataAddress) let newStakeAccountMetadataAddress = - await vesterStakeConnection.getStakeMetadataAddress( - newVester.publicKey, - ); + await vesterStakeConnection.getStakeMetadataAddress(newVester.publicKey); let vestingBalanceAccount = await vesterStakeConnection.program.account.vestingBalance.fetch( vestingBalance, ); - console.log("vestingBalanceAccount.totalVestingBalance: ", vestingBalanceAccount.totalVestingBalance.toString()) + console.log( + "vestingBalanceAccount.totalVestingBalance: ", + vestingBalanceAccount.totalVestingBalance.toString(), + ); let vesterDelegateStakeAccountOwner = await vesterStakeConnection.delegates( vester.publicKey, @@ -157,7 +164,8 @@ async function main() { vestingBalance, newVestingBalance, globalConfig: vesterStakeConnection.configAddress, - delegateStakeAccountCheckpoints: newVesterDelegateStakeAccountCheckpointsAddress, + delegateStakeAccountCheckpoints: + newVesterDelegateStakeAccountCheckpointsAddress, delegateStakeAccountMetadata: newVesterDelegateStakeAccountMetadataAddress, stakeAccountMetadata: stakeAccountMetadataAddress, newStakeAccountMetadata: null, @@ -209,35 +217,35 @@ async function main() { await vesterStakeConnection.provider.sendAndConfirm(tx, [vester]); console.log("transferVesting completed successfully."); -// console.log(`Delegate WH tokens with vests`); -// await vesterStakeConnection.delegateWithVest( -// newVesterDelegateStakeAccountOwner, -// WHTokenBalance.fromString("0"), -// true, -// config, -// ); -// console.log(`WH tokens with vests successfully delegated`); -// await sleep(3000); -// -// console.log("Starting transferVesting..."); -// await vesterStakeConnection.program.methods -// .transferVesting() -// .accountsPartial({ -// ...accounts -// }) -// .rpc() -// .then(confirm); -// console.log("transferVesting completed successfully."); -// await sleep(3000); -// -// console.log(`Delegate WH tokens with vests`); -// await vesterStakeConnection.delegateWithVest( -// vesterDelegateStakeAccountOwner, -// WHTokenBalance.fromString("0"), -// true, -// config, -// ); -// console.log(`WH tokens with vests successfully delegated`); + // console.log(`Delegate WH tokens with vests`); + // await vesterStakeConnection.delegateWithVest( + // newVesterDelegateStakeAccountOwner, + // WHTokenBalance.fromString("0"), + // true, + // config, + // ); + // console.log(`WH tokens with vests successfully delegated`); + // await sleep(3000); + // + // console.log("Starting transferVesting..."); + // await vesterStakeConnection.program.methods + // .transferVesting() + // .accountsPartial({ + // ...accounts + // }) + // .rpc() + // .then(confirm); + // console.log("transferVesting completed successfully."); + // await sleep(3000); + // + // console.log(`Delegate WH tokens with vests`); + // await vesterStakeConnection.delegateWithVest( + // vesterDelegateStakeAccountOwner, + // WHTokenBalance.fromString("0"), + // true, + // config, + // ); + // console.log(`WH tokens with vests successfully delegated`); vestingBalanceAccount = await vesterStakeConnection.program.account.vestingBalance.fetch( @@ -247,8 +255,14 @@ async function main() { await vesterStakeConnection.program.account.vestingBalance.fetch( newVestingBalance, ); - console.log("vestingBalanceAccount.totalVestingBalance: ", vestingBalanceAccount.totalVestingBalance.toString()) - console.log("newVestingBalanceAccount.totalVestingBalance: ", newVestingBalanceAccount.totalVestingBalance.toString()) + console.log( + "vestingBalanceAccount.totalVestingBalance: ", + vestingBalanceAccount.totalVestingBalance.toString(), + ); + console.log( + "newVestingBalanceAccount.totalVestingBalance: ", + newVestingBalanceAccount.totalVestingBalance.toString(), + ); let vesterStakeMetadata: StakeAccountMetadata = await vesterStakeConnection.fetchStakeAccountMetadata(vester.publicKey); @@ -258,8 +272,14 @@ async function main() { false, ); - console.log("vesterStakeMetadata.recordedVestingBalance: ", vesterStakeMetadata.recordedVestingBalance.toString()) - console.log("vesterStakeMetadata.recordedBalance: ", vesterStakeMetadata.recordedBalance.toString()) + console.log( + "vesterStakeMetadata.recordedVestingBalance: ", + vesterStakeMetadata.recordedVestingBalance.toString(), + ); + console.log( + "vesterStakeMetadata.recordedBalance: ", + vesterStakeMetadata.recordedBalance.toString(), + ); } main(); diff --git a/solana/programs/staking/src/context.rs b/solana/programs/staking/src/context.rs index 8469c5f5..210415fb 100644 --- a/solana/programs/staking/src/context.rs +++ b/solana/programs/staking/src/context.rs @@ -441,8 +441,8 @@ pub struct UpdateGovernanceAuthority<'info> { #[derive(Accounts)] pub struct ClaimGovernanceAuthority<'info> { #[account( - mut, - seeds = [CONFIG_SEED.as_bytes()], + mut, + seeds = [CONFIG_SEED.as_bytes()], bump = config.bump, constraint = ( config.pending_governance_authority == Some(new_authority.key()) @@ -466,8 +466,8 @@ pub struct UpdateVestingAdmin<'info> { #[derive(Accounts)] pub struct ClaimVestingAdmin<'info> { #[account( - mut, - seeds = [CONFIG_SEED.as_bytes()], + mut, + seeds = [CONFIG_SEED.as_bytes()], bump = config.bump, constraint = ( config.pending_vesting_admin == Some(new_vesting_admin.key()) diff --git a/solana/programs/staking/src/contexts/cancel_vesting.rs b/solana/programs/staking/src/contexts/cancel_vesting.rs index 87589959..588676b5 100644 --- a/solana/programs/staking/src/contexts/cancel_vesting.rs +++ b/solana/programs/staking/src/contexts/cancel_vesting.rs @@ -1,10 +1,10 @@ -use anchor_lang::prelude::*; -use anchor_spl::associated_token::AssociatedToken; -use anchor_spl::token::{Mint, Token, TokenAccount}; use crate::context::{CONFIG_SEED, VESTING_BALANCE_SEED, VESTING_CONFIG_SEED, VEST_SEED}; use crate::error::VestingError; use crate::state::global_config::GlobalConfig; use crate::state::{Vesting, VestingBalance, VestingConfig}; +use anchor_lang::prelude::*; +use anchor_spl::associated_token::AssociatedToken; +use anchor_spl::token::{Mint, Token, TokenAccount}; #[derive(Accounts)] pub struct CancelVesting<'info> { diff --git a/solana/programs/staking/src/contexts/claim_vesting.rs b/solana/programs/staking/src/contexts/claim_vesting.rs index 1ae7b01b..e4f806cf 100644 --- a/solana/programs/staking/src/contexts/claim_vesting.rs +++ b/solana/programs/staking/src/contexts/claim_vesting.rs @@ -8,7 +8,7 @@ use crate::{ }; use anchor_lang::prelude::*; use anchor_spl::associated_token::AssociatedToken; -use anchor_spl::token::{Mint, Token, TokenAccount, transfer_checked, TransferChecked}; +use anchor_spl::token::{transfer_checked, Mint, Token, TokenAccount, TransferChecked}; use std::convert::TryInto; #[event_cpi] diff --git a/solana/programs/staking/src/contexts/create_vesting.rs b/solana/programs/staking/src/contexts/create_vesting.rs index 8e7f7719..673c807a 100644 --- a/solana/programs/staking/src/contexts/create_vesting.rs +++ b/solana/programs/staking/src/contexts/create_vesting.rs @@ -1,10 +1,10 @@ -use anchor_lang::prelude::*; -use anchor_spl::associated_token::AssociatedToken; -use anchor_spl::token::{Mint, Token, TokenAccount}; use crate::context::{CONFIG_SEED, VESTING_BALANCE_SEED, VESTING_CONFIG_SEED, VEST_SEED}; use crate::error::VestingError; use crate::state::global_config::GlobalConfig; use crate::state::{Vesting, VestingBalance, VestingConfig}; +use anchor_lang::prelude::*; +use anchor_spl::associated_token::AssociatedToken; +use anchor_spl::token::{Mint, Token, TokenAccount}; #[derive(Accounts)] #[instruction(maturation: i64)] diff --git a/solana/programs/staking/src/contexts/withdraw_surplus.rs b/solana/programs/staking/src/contexts/withdraw_surplus.rs index ee019e39..f9ab27a0 100644 --- a/solana/programs/staking/src/contexts/withdraw_surplus.rs +++ b/solana/programs/staking/src/contexts/withdraw_surplus.rs @@ -4,9 +4,7 @@ use crate::state::global_config::GlobalConfig; use crate::state::VestingConfig; use anchor_lang::prelude::*; use anchor_spl::associated_token::AssociatedToken; -use anchor_spl::token::{ - transfer_checked, Mint, TokenAccount, Token, TransferChecked, -}; +use anchor_spl::token::{transfer_checked, Mint, Token, TokenAccount, TransferChecked}; #[derive(Accounts)] pub struct WithdrawSurplus<'info> { From 681896492b3ac025363ab0cba8262760ff212fd0 Mon Sep 17 00:00:00 2001 From: zpoken <82594516+zpoken@users.noreply.github.com> Date: Thu, 6 Mar 2025 18:48:12 +0200 Subject: [PATCH 14/14] Add scripts for initialize staking program in mainnet --- solana/app/deploy/devnet/constants.ts | 14 ++-- solana/app/deploy/mainnet/constants.ts | 73 +++++++++++++++++++ .../initialize/initAddressLookupTable.ts | 34 +++++++++ .../deploy/mainnet/initialize/initConfig.ts | 36 +++++++++ .../initialize/initializeSpokeAirlock.ts | 44 +++++++++++ .../initializeSpokeMessageExecutor.ts | 55 ++++++++++++++ .../initializeSpokeMetadataCollector.ts | 40 ++++++++++ .../initializeVoteWeightWindowLengths.ts | 37 ++++++++++ solana/app/deploy/mainnet/mainnet_beta.ts | 11 --- 9 files changed, 327 insertions(+), 17 deletions(-) create mode 100644 solana/app/deploy/mainnet/constants.ts create mode 100644 solana/app/deploy/mainnet/initialize/initAddressLookupTable.ts create mode 100644 solana/app/deploy/mainnet/initialize/initConfig.ts create mode 100644 solana/app/deploy/mainnet/initialize/initializeSpokeAirlock.ts create mode 100644 solana/app/deploy/mainnet/initialize/initializeSpokeMessageExecutor.ts create mode 100644 solana/app/deploy/mainnet/initialize/initializeSpokeMetadataCollector.ts create mode 100644 solana/app/deploy/mainnet/initialize/initializeVoteWeightWindowLengths.ts delete mode 100644 solana/app/deploy/mainnet/mainnet_beta.ts diff --git a/solana/app/deploy/devnet/constants.ts b/solana/app/deploy/devnet/constants.ts index db64349e..74098f3f 100644 --- a/solana/app/deploy/devnet/constants.ts +++ b/solana/app/deploy/devnet/constants.ts @@ -5,6 +5,11 @@ import { contracts } from "@wormhole-foundation/sdk-base"; export const RPC_NODE = "https://api.devnet.solana.com"; +/// Wormhole Token (W) (devnet solana address) +export const WORMHOLE_TOKEN = new PublicKey( + "Exne2kdeGToBnC2WVSdt1gLy6fjnNftbPtsCPx8AuL7V", +); + export const STAKING_ADDRESS = new PublicKey( "AFuHPdrQGsW8rNQ4oEFF35sm5fg36gwrxyqjkjKvi6ap", ); @@ -24,11 +29,13 @@ export const hubProposalMetadataUint8Array = new Uint8Array( ); /// Wormhole Hub Chain ID +// https://wormhole.com/docs/build/reference/chain-ids/#__tabbed_1_2 export const HUB_CHAIN_ID = 10002; // SEPOLIA export const CHECKPOINTS_ACCOUNT_LIMIT = 654998; export const TEST_CHECKPOINTS_ACCOUNT_LIMIT = 15; +/// Wormhole hubSolanaMessageDispatcher Contract (sepolia ethereum address) export const HUB_SOLANA_MESSAGE_DISPATCHER_ADDRESS = "0xaeb78fb7ddedbbcab908e91e94f1fb04a23fbce5"; const hubSolanaMessageDispatcherHex20 = @@ -80,16 +87,11 @@ export const USER_AUTHORITY_KEYPAIR = loadKeypair( homedir() + USER_AUTHORITY_PATH, ); -export const USER2_AUTHORITY_PATH = - "/.config/solana/secretKey_617X3kwJzjfAbr6zHMa4rzbjaHQN8mzST8VAb8oE8xo8.json"; +export const USER2_AUTHORITY_PATH = "/.config/solana/user2.json"; export const USER2_AUTHORITY_KEYPAIR = loadKeypair( homedir() + USER2_AUTHORITY_PATH, ); -export const WORMHOLE_TOKEN = new PublicKey( - "Exne2kdeGToBnC2WVSdt1gLy6fjnNftbPtsCPx8AuL7V", -); - export const AIRLOCK_PDA_ADDRESS = new PublicKey( "2ejzW2eFPedskg1KcrjcFs9g1JorRVcMes1TBPpGbhdy", ); diff --git a/solana/app/deploy/mainnet/constants.ts b/solana/app/deploy/mainnet/constants.ts new file mode 100644 index 00000000..ea09623c --- /dev/null +++ b/solana/app/deploy/mainnet/constants.ts @@ -0,0 +1,73 @@ +import { PublicKey } from "@solana/web3.js"; +import { homedir } from "os"; +import { loadKeypair } from "../../../tests/utils/keys"; +import { contracts } from "@wormhole-foundation/sdk-base"; + +export const RPC_NODE = "https://api.mainnet-beta.solana.com"; + +/// Wormhole Token (W) (mainnet solana address) +export const WORMHOLE_TOKEN = new PublicKey( + "85VBFQZC9TZkfaptBWjvUw7YbZjy52A6mjtPGjstQAmQ", +); + +export const STAKING_ADDRESS = new PublicKey( + "AFuHPdrQGsW8rNQ4oEFF35sm5fg36gwrxyqjkjKvi6ap", +); + +export const CORE_BRIDGE_PID = new PublicKey( + contracts.coreBridge.get("Mainnet", "Solana")!, // worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth +); +console.log(CORE_BRIDGE_PID); + +/// Wormhole Hub Proposal Metadata Contract (mainnet ethereum address) +export const HUB_PROPOSAL_METADATA_ADDRESS = + "0x1a3e5624769c3dc9106347a239523e4a08d85c38"; // TODO: needs to be updated after a deployment to ethereum mainnet +export const hubProposalMetadataUint8Array = new Uint8Array( + HUB_PROPOSAL_METADATA_ADDRESS.slice(2) + .toLowerCase() + .match(/.{1,2}/g) + ?.map((byte) => parseInt(byte, 16)), +); + +/// Wormhole Hub Chain ID +// https://wormhole.com/docs/build/reference/chain-ids/#__tabbed_1_1 +export const HUB_CHAIN_ID = 2; // Mainnet + +export const CHECKPOINTS_ACCOUNT_LIMIT = 654998; + +/// Wormhole hubSolanaMessageDispatcher Contract (mainnet ethereum address) +export const HUB_SOLANA_MESSAGE_DISPATCHER_ADDRESS = + "0xaeb78fb7ddedbbcab908e91e94f1fb04a23fbce5"; // TODO: needs to be updated after a deployment to ethereum mainnet +const hubSolanaMessageDispatcherHex20 = + HUB_SOLANA_MESSAGE_DISPATCHER_ADDRESS.slice(2); +const hubSolanaMessageDispatcherHex32 = + "000000000000000000000000" + hubSolanaMessageDispatcherHex20.toLowerCase(); +const hubSolanaMessageDispatcherUint8Array32 = new Uint8Array( + hubSolanaMessageDispatcherHex32 + .match(/.{1,2}/g) + ?.map((byte) => parseInt(byte, 16)), +); +export const hubSolanaMessageDispatcherUint8Array20 = + hubSolanaMessageDispatcherUint8Array32.slice(-20); +export const hubSolanaMessageDispatcherPublicKey = new PublicKey( + hubSolanaMessageDispatcherUint8Array32, +); +// console.log("hubSolanaMessageDispatcherPublicKey:", hubSolanaMessageDispatcherPublicKey); + +export const DEPLOYER_AUTHORITY_PATH = "/.config/solana/deployer.json"; +export const DEPLOYER_AUTHORITY_KEYPAIR = loadKeypair( + homedir() + DEPLOYER_AUTHORITY_PATH, +); + +export const GOVERNANCE_AUTHORITY_PATH = + "/.config/solana/governanceAuthority.json"; +export const GOVERNANCE_AUTHORITY_KEYPAIR = loadKeypair( + homedir() + GOVERNANCE_AUTHORITY_PATH, +); + +export const VESTING_ADMIN_PATH = "/.config/solana/vestingAdmin.json"; +export const VESTING_ADMIN_KEYPAIR = loadKeypair( + homedir() + VESTING_ADMIN_PATH, +); + +export const VOTE_WEIGHT_WINDOW_LENGTHS = 10 * 60; // 10 minutes diff --git a/solana/app/deploy/mainnet/initialize/initAddressLookupTable.ts b/solana/app/deploy/mainnet/initialize/initAddressLookupTable.ts new file mode 100644 index 00000000..8af3de32 --- /dev/null +++ b/solana/app/deploy/mainnet/initialize/initAddressLookupTable.ts @@ -0,0 +1,34 @@ +// Usage: npx ts-node app/deploy/mainnet/initialize/initAddressLookupTable.ts + +import { Wallet, AnchorProvider } from "@coral-xyz/anchor"; +import { Connection } from "@solana/web3.js"; +import { + DEPLOYER_AUTHORITY_KEYPAIR, + RPC_NODE, + STAKING_ADDRESS, + WORMHOLE_TOKEN, +} from "../constants"; +import { initAddressLookupTable } from "../../../helpers/utils/lookup_table"; + +async function main() { + try { + const connection = new Connection(RPC_NODE); + const provider = new AnchorProvider( + connection, + new Wallet(DEPLOYER_AUTHORITY_KEYPAIR), + {}, + ); + + const lookupTableAddress = await initAddressLookupTable( + provider, + WORMHOLE_TOKEN, + STAKING_ADDRESS, + ); + + console.log("Lookup table address: ", lookupTableAddress.toBase58()); + } catch (err) { + console.error("Error:", err); + } +} + +main(); diff --git a/solana/app/deploy/mainnet/initialize/initConfig.ts b/solana/app/deploy/mainnet/initialize/initConfig.ts new file mode 100644 index 00000000..c43afb3a --- /dev/null +++ b/solana/app/deploy/mainnet/initialize/initConfig.ts @@ -0,0 +1,36 @@ +// Usage: npx ts-node app/deploy/mainnet/initialize/initConfig.ts + +import { Wallet, AnchorProvider, Program } from "@coral-xyz/anchor"; +import { Connection } from "@solana/web3.js"; +import { + CHECKPOINTS_ACCOUNT_LIMIT, + STAKING_ADDRESS, + DEPLOYER_AUTHORITY_KEYPAIR, + GOVERNANCE_AUTHORITY_KEYPAIR, + VESTING_ADMIN_KEYPAIR, + WORMHOLE_TOKEN, + RPC_NODE, +} from "../constants"; + +async function main() { + const connection = new Connection(RPC_NODE); + const provider = new AnchorProvider( + connection, + new Wallet(DEPLOYER_AUTHORITY_KEYPAIR), + {}, + ); + + const idl = (await Program.fetchIdl(STAKING_ADDRESS, provider))!; + const program = new Program(idl, provider); + + const globalConfig = { + bump: 255, + governanceAuthority: GOVERNANCE_AUTHORITY_KEYPAIR.publicKey, + votingTokenMint: WORMHOLE_TOKEN, + vestingAdmin: VESTING_ADMIN_KEYPAIR.publicKey, + maxCheckpointsAccountLimit: CHECKPOINTS_ACCOUNT_LIMIT, + }; + await program.methods.initConfig(globalConfig).rpc(); +} + +main(); diff --git a/solana/app/deploy/mainnet/initialize/initializeSpokeAirlock.ts b/solana/app/deploy/mainnet/initialize/initializeSpokeAirlock.ts new file mode 100644 index 00000000..c6d4b788 --- /dev/null +++ b/solana/app/deploy/mainnet/initialize/initializeSpokeAirlock.ts @@ -0,0 +1,44 @@ +// Usage: npx ts-node app/deploy/mainnet/initialize/initializeSpokeAirlock.ts + +import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; +import { Connection, PublicKey, SystemProgram } from "@solana/web3.js"; +import { DEPLOYER_AUTHORITY_KEYPAIR, RPC_NODE } from "../constants"; +import { Staking } from "../../../../target/types/staking"; +import fs from "fs"; + +async function main() { + try { + const DEBUG = true; + const connection = new Connection(RPC_NODE); + const provider = new AnchorProvider( + connection, + new Wallet(DEPLOYER_AUTHORITY_KEYPAIR), + {}, + ); + + let program: Program; + program = new Program( + JSON.parse(fs.readFileSync("./target/idl/staking.json").toString()), + provider, + ); + + const airlockPDA: PublicKey = PublicKey.findProgramAddressSync( + [Buffer.from("airlock")], + program.programId, + )[0]; + + await program.methods + .initializeSpokeAirlock() + .accounts({ + payer: DEPLOYER_AUTHORITY_KEYPAIR.publicKey, + // @ts-ignore + airlock: airlockPDA, + systemProgram: SystemProgram.programId, + }) + .rpc({ skipPreflight: DEBUG }); + } catch (err) { + console.error("Error:", err); + } +} + +main(); diff --git a/solana/app/deploy/mainnet/initialize/initializeSpokeMessageExecutor.ts b/solana/app/deploy/mainnet/initialize/initializeSpokeMessageExecutor.ts new file mode 100644 index 00000000..bf78b5e8 --- /dev/null +++ b/solana/app/deploy/mainnet/initialize/initializeSpokeMessageExecutor.ts @@ -0,0 +1,55 @@ +// Usage: npx ts-node app/deploy/mainnet/initialize/initializeSpokeMessageExecutor.ts + +import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; +import { Connection, PublicKey, SystemProgram } from "@solana/web3.js"; +import { + DEPLOYER_AUTHORITY_KEYPAIR, + hubSolanaMessageDispatcherPublicKey, + HUB_CHAIN_ID, + RPC_NODE, +} from "../constants"; +import { Staking } from "../../../../target/types/staking"; +import fs from "fs"; +import { wasm } from "../../../StakeConnection"; + +async function main() { + try { + const connection = new Connection(RPC_NODE); + const provider = new AnchorProvider( + connection, + new Wallet(DEPLOYER_AUTHORITY_KEYPAIR), + {}, + ); + + let program: Program; + program = new Program( + JSON.parse(fs.readFileSync("./target/idl/staking.json").toString()), + provider, + ); + + const messageExecutorPDA: PublicKey = PublicKey.findProgramAddressSync( + [Buffer.from("spoke_message_executor")], + program.programId, + )[0]; + const config: PublicKey = PublicKey.findProgramAddressSync( + [Buffer.from(wasm.Constants.CONFIG_SEED())], + program.programId, + )[0]; + + await program.methods + .initializeSpokeMessageExecutor(HUB_CHAIN_ID) + .accounts({ + governanceAuthority: DEPLOYER_AUTHORITY_KEYPAIR.publicKey, + // @ts-ignore + executor: messageExecutorPDA, + config: config, + hubDispatcher: hubSolanaMessageDispatcherPublicKey, + systemProgram: SystemProgram.programId, + }) + .rpc(); + } catch (err) { + console.error("Error:", err); + } +} + +main(); diff --git a/solana/app/deploy/mainnet/initialize/initializeSpokeMetadataCollector.ts b/solana/app/deploy/mainnet/initialize/initializeSpokeMetadataCollector.ts new file mode 100644 index 00000000..2cba674b --- /dev/null +++ b/solana/app/deploy/mainnet/initialize/initializeSpokeMetadataCollector.ts @@ -0,0 +1,40 @@ +// Usage: npx ts-node app/deploy/mainnet/initialize/initializeSpokeMetadataCollector.ts + +import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; +import { Connection } from "@solana/web3.js"; +import { + DEPLOYER_AUTHORITY_KEYPAIR, + HUB_CHAIN_ID, + hubProposalMetadataUint8Array, + RPC_NODE, +} from "../constants"; +import { Staking } from "../../../../target/types/staking"; +import fs from "fs"; + +async function main() { + try { + const connection = new Connection(RPC_NODE); + const provider = new AnchorProvider( + connection, + new Wallet(DEPLOYER_AUTHORITY_KEYPAIR), + {}, + ); + + let program: Program; + program = new Program( + JSON.parse(fs.readFileSync("./target/idl/staking.json").toString()), + provider, + ); + + await program.methods + .initializeSpokeMetadataCollector( + HUB_CHAIN_ID, + Array.from(hubProposalMetadataUint8Array), + ) + .rpc(); + } catch (err) { + console.error("Error:", err); + } +} + +main(); diff --git a/solana/app/deploy/mainnet/initialize/initializeVoteWeightWindowLengths.ts b/solana/app/deploy/mainnet/initialize/initializeVoteWeightWindowLengths.ts new file mode 100644 index 00000000..49354509 --- /dev/null +++ b/solana/app/deploy/mainnet/initialize/initializeVoteWeightWindowLengths.ts @@ -0,0 +1,37 @@ +// Usage: npx ts-node app/deploy/mainnet/initialize/initializeVoteWeightWindowLengths.ts + +import { AnchorProvider, Program, Wallet } from "@coral-xyz/anchor"; +import { Connection } from "@solana/web3.js"; +import { + DEPLOYER_AUTHORITY_KEYPAIR, + RPC_NODE, + VOTE_WEIGHT_WINDOW_LENGTHS, +} from "../constants"; +import { Staking } from "../../../../target/types/staking"; +import fs from "fs"; +import BN from "bn.js"; + +async function main() { + try { + const connection = new Connection(RPC_NODE); + const provider = new AnchorProvider( + connection, + new Wallet(DEPLOYER_AUTHORITY_KEYPAIR), + {}, + ); + + let program: Program; + program = new Program( + JSON.parse(fs.readFileSync("./target/idl/staking.json").toString()), + provider, + ); + + await program.methods + .initializeVoteWeightWindowLengths(new BN(VOTE_WEIGHT_WINDOW_LENGTHS)) + .rpc(); + } catch (err) { + console.error("Error:", err); + } +} + +main(); diff --git a/solana/app/deploy/mainnet/mainnet_beta.ts b/solana/app/deploy/mainnet/mainnet_beta.ts deleted file mode 100644 index 4af5bb2c..00000000 --- a/solana/app/deploy/mainnet/mainnet_beta.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { PublicKey } from "@solana/web3.js"; -import { homedir } from "os"; -import { loadKeypair } from "../../tests/utils/keys"; -export const AUTHORITY_PATH = "/.config/solana/deployer.json"; -export const AUTHORITY_KEYPAIR = loadKeypair(homedir() + AUTHORITY_PATH); - -export const WORMHOLE_TOKEN = new PublicKey( - "Exne2kdeGToBnC2WVSdt1gLy6fjnNftbPtsCPx8AuL7V", -); - -export const RPC_NODE = "https://api.mainnet-beta.solana.com";