diff --git a/packages/crons/yarn.deploy.lock b/packages/crons/yarn.deploy.lock index 9cbfcf379..2b1664dcb 100644 --- a/packages/crons/yarn.deploy.lock +++ b/packages/crons/yarn.deploy.lock @@ -316,6 +316,7 @@ __metadata: "@coral-xyz/anchor": ^0.28.0 "@helium/anchor-resolvers": ^0.9.18 "@helium/circuit-breaker-sdk": ^0.9.18 + "@helium/nft-proxy-sdk": ^0.0.15 "@helium/spl-utils": ^0.9.18 "@helium/treasury-management-sdk": ^0.9.18 "@helium/voter-stake-registry-sdk": ^0.9.18 diff --git a/packages/data-credits-sdk/yarn.deploy.lock b/packages/data-credits-sdk/yarn.deploy.lock index 89dfcd2e7..169b25c00 100644 --- a/packages/data-credits-sdk/yarn.deploy.lock +++ b/packages/data-credits-sdk/yarn.deploy.lock @@ -160,6 +160,7 @@ __metadata: "@coral-xyz/anchor": ^0.28.0 "@helium/anchor-resolvers": ^0.9.18 "@helium/circuit-breaker-sdk": ^0.9.18 + "@helium/nft-proxy-sdk": ^0.0.15 "@helium/spl-utils": ^0.9.18 "@helium/treasury-management-sdk": ^0.9.18 "@helium/voter-stake-registry-sdk": ^0.9.18 diff --git a/packages/distributor-oracle/yarn.deploy.lock b/packages/distributor-oracle/yarn.deploy.lock index 8149950c4..58b141bef 100644 --- a/packages/distributor-oracle/yarn.deploy.lock +++ b/packages/distributor-oracle/yarn.deploy.lock @@ -259,6 +259,7 @@ __metadata: "@coral-xyz/anchor": ^0.28.0 "@helium/anchor-resolvers": ^0.9.18 "@helium/circuit-breaker-sdk": ^0.9.18 + "@helium/nft-proxy-sdk": ^0.0.15 "@helium/spl-utils": ^0.9.18 "@helium/treasury-management-sdk": ^0.9.18 "@helium/voter-stake-registry-sdk": ^0.9.18 diff --git a/packages/entity-invalidator/yarn.deploy.lock b/packages/entity-invalidator/yarn.deploy.lock index 999e3cb2b..7cfac6781 100644 --- a/packages/entity-invalidator/yarn.deploy.lock +++ b/packages/entity-invalidator/yarn.deploy.lock @@ -205,6 +205,7 @@ __metadata: "@coral-xyz/anchor": ^0.28.0 "@helium/anchor-resolvers": ^0.9.18 "@helium/circuit-breaker-sdk": ^0.9.18 + "@helium/nft-proxy-sdk": ^0.0.15 "@helium/spl-utils": ^0.9.18 "@helium/treasury-management-sdk": ^0.9.18 "@helium/voter-stake-registry-sdk": ^0.9.18 diff --git a/packages/helium-admin-cli/src/add-expiration-to-delegations.ts b/packages/helium-admin-cli/src/add-expiration-to-delegations.ts new file mode 100644 index 000000000..5d8bb8669 --- /dev/null +++ b/packages/helium-admin-cli/src/add-expiration-to-delegations.ts @@ -0,0 +1,127 @@ +import * as anchor from "@coral-xyz/anchor"; +import { daoKey, init as initHsd, subDaoEpochInfoKey } from "@helium/helium-sub-daos-sdk"; +import { init as initProxy } from "@helium/nft-proxy-sdk"; +import { batchParallelInstructionsWithPriorityFee, HNT_MINT } from "@helium/spl-utils"; +import { init as initVsr } from "@helium/voter-stake-registry-sdk"; +import { AccountInfo, PublicKey, SystemProgram, SYSVAR_CLOCK_PUBKEY, TransactionInstruction } from "@solana/web3.js"; +import { min } from "bn.js"; +import os from "os"; +import yargs from "yargs/yargs"; +import { loadKeypair } from "./utils"; + +export async function run(args: any = process.argv) { + const yarg = yargs(args).options({ + wallet: { + alias: "k", + describe: "Anchor wallet keypair", + default: `${os.homedir()}/.config/solana/id.json`, + }, + url: { + alias: "u", + default: "http://127.0.0.1:8899", + describe: "The solana url", + }, + hntMint: { + type: "string", + describe: "HNT mint of the dao to be updated", + default: HNT_MINT.toBase58(), + }, + }); + const argv = await yarg.argv; + process.env.ANCHOR_WALLET = argv.wallet; + process.env.ANCHOR_PROVIDER_URL = argv.url; + anchor.setProvider(anchor.AnchorProvider.local(argv.url)); + const provider = anchor.getProvider() as anchor.AnchorProvider; + const wallet = new anchor.Wallet(loadKeypair(argv.wallet)); + const proxyProgram = await initProxy(provider); + const vsrProgram = await initVsr(provider); + const hsdProgram = await initHsd(provider); + + + const hntMint = new PublicKey(argv.hntMint); + const dao = daoKey(hntMint)[0]; + const registrarK = (await hsdProgram.account.daoV0.fetch(dao)).registrar; + const registrar = await vsrProgram.account.registrar.fetch(registrarK); + const proxyConfig = await proxyProgram.account.proxyConfigV0.fetch( + registrar.proxyConfig + ); + + const instructions: TransactionInstruction[] = []; + const delegations = await hsdProgram.account.delegatedPositionV0.all() + const needsMigration = delegations.filter(d => d.account.expirationTs.isZero()); + const positionKeys = needsMigration.map(d => d.account.position); + const coder = hsdProgram.coder.accounts + const positionAccs = (await getMultipleAccounts({ + connection: provider.connection, + keys: positionKeys, + })).map(a => coder.decode("positionV0", a.data)); + + const currTs = await getSolanaUnixTimestamp(provider); + const currTsBN = new anchor.BN(currTs.toString()); + const proxyEndTs = proxyConfig.seasons.find(s => currTsBN.gt(s.start))?.end; + for (const [delegation, position] of zip(needsMigration, positionAccs)) { + const subDao = delegation.account.subDao; + instructions.push( + await hsdProgram.methods + .addExpirationTs() + .accountsStrict({ + payer: wallet.publicKey, + position: delegation.account.position, + delegatedPosition: delegation.publicKey, + registrar: registrarK, + dao, + subDao: delegation.account.subDao, + oldClosingTimeSubDaoEpochInfo: subDaoEpochInfoKey( + subDao, + position.lockup.endTs + )[0], + closingTimeSubDaoEpochInfo: subDaoEpochInfoKey( + subDao, + min(position.lockup.endTs, proxyEndTs!) + )[0], + genesisEndSubDaoEpochInfo: subDaoEpochInfoKey( + subDao, + position.genesisEnd + )[0], + proxyConfig: registrar.proxyConfig, + systemProgram: SystemProgram.programId, + }) + .instruction() + ); + } + + await batchParallelInstructionsWithPriorityFee(provider, instructions, { + onProgress: (status) => { + console.log(status); + }, + }); +} + +async function getMultipleAccounts({ + connection, + keys, +}): Promise[]> { + const batchSize = 100; + const batches = Math.ceil(keys.length / batchSize); + const results: AccountInfo[] = []; + + for (let i = 0; i < batches; i++) { + const batchKeys = keys.slice(i * batchSize, (i + 1) * batchSize); + const batchResults = await connection.getMultipleAccountsInfo(batchKeys); + results.push(...batchResults); + } + + return results; +} + +function zip(a: T[], b: U[]): [T, U][] { + return a.map((_, i) => [a[i], b[i]]); +} + +async function getSolanaUnixTimestamp( + provider: anchor.AnchorProvider +): Promise { + const clock = await provider.connection.getAccountInfo(SYSVAR_CLOCK_PUBKEY); + const unixTime = clock!.data.readBigInt64LE(8 * 4); + return unixTime; +} \ No newline at end of file diff --git a/packages/helium-admin-cli/yarn.deploy.lock b/packages/helium-admin-cli/yarn.deploy.lock index 982bdb426..a0fc77c24 100644 --- a/packages/helium-admin-cli/yarn.deploy.lock +++ b/packages/helium-admin-cli/yarn.deploy.lock @@ -382,6 +382,7 @@ __metadata: "@coral-xyz/anchor": ^0.28.0 "@helium/anchor-resolvers": ^0.9.18 "@helium/circuit-breaker-sdk": ^0.9.18 + "@helium/nft-proxy-sdk": ^0.0.15 "@helium/spl-utils": ^0.9.18 "@helium/treasury-management-sdk": ^0.9.18 "@helium/voter-stake-registry-sdk": ^0.9.18 diff --git a/packages/helium-entity-manager-sdk/yarn.deploy.lock b/packages/helium-entity-manager-sdk/yarn.deploy.lock index 77a8e687e..6c2413f0a 100644 --- a/packages/helium-entity-manager-sdk/yarn.deploy.lock +++ b/packages/helium-entity-manager-sdk/yarn.deploy.lock @@ -174,6 +174,7 @@ __metadata: "@coral-xyz/anchor": ^0.28.0 "@helium/anchor-resolvers": ^0.9.18 "@helium/circuit-breaker-sdk": ^0.9.18 + "@helium/nft-proxy-sdk": ^0.0.15 "@helium/spl-utils": ^0.9.18 "@helium/treasury-management-sdk": ^0.9.18 "@helium/voter-stake-registry-sdk": ^0.9.18 diff --git a/packages/helium-sub-daos-sdk/package.json b/packages/helium-sub-daos-sdk/package.json index 1911d8ce5..4f14a04ec 100644 --- a/packages/helium-sub-daos-sdk/package.json +++ b/packages/helium-sub-daos-sdk/package.json @@ -34,10 +34,10 @@ "@coral-xyz/anchor": "^0.28.0", "@helium/anchor-resolvers": "^0.9.18", "@helium/circuit-breaker-sdk": "^0.9.18", + "@helium/nft-proxy-sdk": "^0.0.15", "@helium/spl-utils": "^0.9.18", "@helium/treasury-management-sdk": "^0.9.18", "@helium/voter-stake-registry-sdk": "^0.9.18", - "@helium/nft-proxy-sdk": "^0.0.15", "bn.js": "^5.2.0", "bs58": "^4.0.1" }, diff --git a/packages/helium-sub-daos-sdk/yarn.deploy.lock b/packages/helium-sub-daos-sdk/yarn.deploy.lock index 69559a7ae..dc9679ce4 100644 --- a/packages/helium-sub-daos-sdk/yarn.deploy.lock +++ b/packages/helium-sub-daos-sdk/yarn.deploy.lock @@ -139,6 +139,7 @@ __metadata: "@coral-xyz/anchor": ^0.28.0 "@helium/anchor-resolvers": ^0.9.18 "@helium/circuit-breaker-sdk": ^0.9.18 + "@helium/nft-proxy-sdk": ^0.0.15 "@helium/spl-utils": ^0.9.18 "@helium/treasury-management-sdk": ^0.9.18 "@helium/voter-stake-registry-sdk": ^0.9.18 diff --git a/packages/hexboosting-sdk/yarn.deploy.lock b/packages/hexboosting-sdk/yarn.deploy.lock index 646efd58f..78a3e8c2d 100644 --- a/packages/hexboosting-sdk/yarn.deploy.lock +++ b/packages/hexboosting-sdk/yarn.deploy.lock @@ -139,6 +139,7 @@ __metadata: "@coral-xyz/anchor": ^0.28.0 "@helium/anchor-resolvers": ^0.9.18 "@helium/circuit-breaker-sdk": ^0.9.18 + "@helium/nft-proxy-sdk": ^0.0.15 "@helium/spl-utils": ^0.9.18 "@helium/treasury-management-sdk": ^0.9.18 "@helium/voter-stake-registry-sdk": ^0.9.18 diff --git a/packages/hotspot-utils/yarn.deploy.lock b/packages/hotspot-utils/yarn.deploy.lock index 9fcdfb8b8..63f928cdf 100644 --- a/packages/hotspot-utils/yarn.deploy.lock +++ b/packages/hotspot-utils/yarn.deploy.lock @@ -174,6 +174,7 @@ __metadata: "@coral-xyz/anchor": ^0.28.0 "@helium/anchor-resolvers": ^0.9.18 "@helium/circuit-breaker-sdk": ^0.9.18 + "@helium/nft-proxy-sdk": ^0.0.15 "@helium/spl-utils": ^0.9.18 "@helium/treasury-management-sdk": ^0.9.18 "@helium/voter-stake-registry-sdk": ^0.9.18 diff --git a/packages/metadata-service/yarn.deploy.lock b/packages/metadata-service/yarn.deploy.lock index 2a7a3c3e9..190b8a0ed 100644 --- a/packages/metadata-service/yarn.deploy.lock +++ b/packages/metadata-service/yarn.deploy.lock @@ -263,6 +263,7 @@ __metadata: "@coral-xyz/anchor": ^0.28.0 "@helium/anchor-resolvers": ^0.9.18 "@helium/circuit-breaker-sdk": ^0.9.18 + "@helium/nft-proxy-sdk": ^0.0.15 "@helium/spl-utils": ^0.9.18 "@helium/treasury-management-sdk": ^0.9.18 "@helium/voter-stake-registry-sdk": ^0.9.18 diff --git a/packages/migration-service/yarn.deploy.lock b/packages/migration-service/yarn.deploy.lock index 30ce7d8a9..5e6d2a65a 100644 --- a/packages/migration-service/yarn.deploy.lock +++ b/packages/migration-service/yarn.deploy.lock @@ -336,6 +336,7 @@ __metadata: "@coral-xyz/anchor": ^0.28.0 "@helium/anchor-resolvers": ^0.9.18 "@helium/circuit-breaker-sdk": ^0.9.18 + "@helium/nft-proxy-sdk": ^0.0.15 "@helium/spl-utils": ^0.9.18 "@helium/treasury-management-sdk": ^0.9.18 "@helium/voter-stake-registry-sdk": ^0.9.18 diff --git a/packages/mobile-entity-manager-sdk/yarn.deploy.lock b/packages/mobile-entity-manager-sdk/yarn.deploy.lock index 3df487164..34675767f 100644 --- a/packages/mobile-entity-manager-sdk/yarn.deploy.lock +++ b/packages/mobile-entity-manager-sdk/yarn.deploy.lock @@ -174,6 +174,7 @@ __metadata: "@coral-xyz/anchor": ^0.28.0 "@helium/anchor-resolvers": ^0.9.18 "@helium/circuit-breaker-sdk": ^0.9.18 + "@helium/nft-proxy-sdk": ^0.0.15 "@helium/spl-utils": ^0.9.18 "@helium/treasury-management-sdk": ^0.9.18 "@helium/voter-stake-registry-sdk": ^0.9.18 diff --git a/packages/monitor-service/yarn.deploy.lock b/packages/monitor-service/yarn.deploy.lock index b45c8e9be..054809bdb 100644 --- a/packages/monitor-service/yarn.deploy.lock +++ b/packages/monitor-service/yarn.deploy.lock @@ -229,6 +229,7 @@ __metadata: "@coral-xyz/anchor": ^0.28.0 "@helium/anchor-resolvers": ^0.9.18 "@helium/circuit-breaker-sdk": ^0.9.18 + "@helium/nft-proxy-sdk": ^0.0.15 "@helium/spl-utils": ^0.9.18 "@helium/treasury-management-sdk": ^0.9.18 "@helium/voter-stake-registry-sdk": ^0.9.18 diff --git a/packages/voter-stake-registry-hooks/yarn.deploy.lock b/packages/voter-stake-registry-hooks/yarn.deploy.lock index 59f45958f..36a6abdd7 100644 --- a/packages/voter-stake-registry-hooks/yarn.deploy.lock +++ b/packages/voter-stake-registry-hooks/yarn.deploy.lock @@ -233,6 +233,7 @@ __metadata: "@coral-xyz/anchor": ^0.28.0 "@helium/anchor-resolvers": ^0.9.18 "@helium/circuit-breaker-sdk": ^0.9.18 + "@helium/nft-proxy-sdk": ^0.0.15 "@helium/spl-utils": ^0.9.18 "@helium/treasury-management-sdk": ^0.9.18 "@helium/voter-stake-registry-sdk": ^0.9.18 diff --git a/programs/helium-sub-daos/src/instructions/delegation/add_expiration_ts.rs b/programs/helium-sub-daos/src/instructions/delegation/add_expiration_ts.rs index 42f32c2ef..a2087e66d 100644 --- a/programs/helium-sub-daos/src/instructions/delegation/add_expiration_ts.rs +++ b/programs/helium-sub-daos/src/instructions/delegation/add_expiration_ts.rs @@ -1,4 +1,4 @@ -use std::{i64, str::FromStr}; +use std::{cmp::min, str::FromStr}; use anchor_lang::prelude::*; use nft_proxy::ProxyConfigV0; @@ -57,7 +57,7 @@ pub struct AddExpirationTs<'info> { payer = payer, space = SubDaoEpochInfoV0::SIZE, seeds = ["sub_dao_epoch_info".as_bytes(), sub_dao.key().as_ref(), ¤t_epoch( - proxy_config.get_current_season(registrar.clock_unix_timestamp()).unwrap().end + min(proxy_config.get_current_season(registrar.clock_unix_timestamp()).unwrap().end, position.lockup.end_ts) ).to_le_bytes()], bump, )] diff --git a/programs/helium-sub-daos/src/instructions/delegation/close_delegation_v0.rs b/programs/helium-sub-daos/src/instructions/delegation/close_delegation_v0.rs index b724d1340..d461baa15 100644 --- a/programs/helium-sub-daos/src/instructions/delegation/close_delegation_v0.rs +++ b/programs/helium-sub-daos/src/instructions/delegation/close_delegation_v0.rs @@ -2,7 +2,6 @@ use std::cmp::min; use anchor_lang::prelude::*; use anchor_spl::token::{Mint, TokenAccount}; -use nft_proxy::ProxyConfigV0; use voter_stake_registry::{ state::{LockupKind, PositionV0, Registrar}, VoterStakeRegistry, diff --git a/yarn.lock b/yarn.lock index e21f55de3..06f08c1b8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1011,6 +1011,7 @@ __metadata: "@coral-xyz/anchor": ^0.28.0 "@helium/anchor-resolvers": ^0.9.18 "@helium/circuit-breaker-sdk": ^0.9.18 + "@helium/nft-proxy-sdk": ^0.0.15 "@helium/spl-utils": ^0.9.18 "@helium/treasury-management-sdk": ^0.9.18 "@helium/voter-stake-registry-sdk": ^0.9.18