Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create tuktuk tasks to resolve proposals and close expired vote markers #195

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 22 additions & 19 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@
"lint": "next lint"
},
"dependencies": {
"@coral-xyz/anchor": "^0.29.0",
"@helium/account-fetch-cache": "^0.9.23",
"@helium/account-fetch-cache-hooks": "^0.9.23",
"@helium/helium-react-hooks": "^0.9.23",
"@helium/modular-governance-hooks": "^0.0.13",
"@helium/modular-governance-idls": "^0.0.13",
"@helium/organization-sdk": "^0.0.13",
"@helium/spl-utils": "^0.9.23",
"@helium/state-controller-sdk": "^0.0.13",
"@helium/voter-stake-registry-hooks": "^0.9.23",
"@helium/voter-stake-registry-sdk": "^0.9.23",
"@coral-xyz/anchor": "^0.30.1",
"@helium/account-fetch-cache": "^0.10.0-alpha.13",
"@helium/account-fetch-cache-hooks": "^0.10.0-alpha.13",
"@helium/helium-react-hooks": "^0.10.0-alpha.13",
"@helium/modular-governance-hooks": "^0.1.4",
"@helium/modular-governance-idls": "^0.1.4",
"@helium/organization-sdk": "^0.1.4",
"@helium/spl-utils": "^0.10.0-alpha.13",
"@helium/state-controller-sdk": "^0.1.4",
"@helium/voter-stake-registry-hooks": "^0.10.0-alpha.13",
"@helium/voter-stake-registry-sdk": "^0.10.0-alpha.13",
"@hookform/resolvers": "^3.3.4",
"@metaplex-foundation/mpl-token-metadata": "2.10.0",
"@project-serum/anchor": "^0.26.0",
Expand All @@ -41,6 +41,9 @@
"@solana/wallet-adapter-react": "^0.15.35",
"@solana/wallet-adapter-react-ui": "^0.9.35",
"@solana/wallet-adapter-wallets": "^0.19.32",
"@helium/hpl-crons-sdk": "^0.10.0-alpha.13",
"@helium/no-emit-sdk": "^0.10.0-alpha.13",
"@helium/tuktuk-sdk": "^0.0.2",
"@solana/web3.js": "^1.95.4",
"@sqds/sdk": "^2.0.4",
"@tanstack/react-query": "5.45.1",
Expand Down Expand Up @@ -73,15 +76,15 @@
"resolutions": {
"@tanstack/react-query": "5.45.1",
"@solana/web3.js": "^1.90.0",
"@helium/account-fetch-cache": "^0.9.23",
"@helium/account-fetch-cache-hooks": "^0.9.23",
"@helium/helium-react-hooks": "^0.9.23",
"@helium/voter-stake-registry-hooks": "^0.9.23",
"@helium/modular-governance-idls": "^0.0.13",
"@helium/spl-utils": "^0.9.23",
"@helium/modular-governance-hooks": "^0.0.13",
"@helium/account-fetch-cache": "^0.10.0-alpha.13",
"@helium/account-fetch-cache-hooks": "^0.10.0-alpha.13",
"@helium/helium-react-hooks": "^0.10.0-alpha.13",
"@helium/voter-stake-registry-hooks": "^0.10.0-alpha.13",
"@helium/modular-governance-idls": "^0.1.4",
"@helium/spl-utils": "^0.10.0-alpha.13",
"@helium/modular-governance-hooks": "^0.1.4",
"@solana/wallet-adapter-react": "^0.15.35",
"@helium/voter-stake-registry-sdk": "^0.9.23"
"@helium/voter-stake-registry-sdk": "^0.10.0-alpha.13"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.10",
Expand Down
2 changes: 1 addition & 1 deletion scripts/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ export async function run(args: any = process.argv) {
uri: null,
authority,
})
.accounts({ organization, authority: organizationAcc.authority })
.accountsPartial({ organization, authority: organizationAcc.authority })
.instruction();

await sendInstructionsOrSquads({
Expand Down
59 changes: 55 additions & 4 deletions scripts/bulk-create-proposal.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
import * as anchor from "@coral-xyz/anchor";
import { init as initOrg, organizationKey, proposalKey } from "@helium/organization-sdk";
import {
init as initOrg,
organizationKey,
proposalKey,
} from "@helium/organization-sdk";
import os from "os";
import yargs from "yargs/yargs";
import { init as initState } from "@helium/state-controller-sdk";
import Squads from "@sqds/sdk";
import { PublicKey, TransactionInstruction } from "@solana/web3.js";
import { PublicKey, SystemProgram, TransactionInstruction } from "@solana/web3.js";
import { loadKeypair, sendInstructionsOrSquads } from "./utils";
import fs from "fs";
import { init as initTuktuk, taskKey } from "@helium/tuktuk-sdk";
import {
nextAvailableTaskIds,
TASK_QUEUE_ID,
init as initHplCrons,
queueAuthorityKey,
} from "@helium/hpl-crons-sdk";

interface Choice {
uri: string;
Expand Down Expand Up @@ -79,11 +90,31 @@ export async function run(args: any = process.argv) {
const fileData = fs.readFileSync(argv.file, "utf8");
const proposals: Proposal[] = JSON.parse(fileData);

const queueAuthority = queueAuthorityKey()[0];
console.log(
`Queue authority: ${queueAuthority.toBase58()} (Fund with Sol to pay task rent)`
);

const instructions: TransactionInstruction[] = [];
const organizationK = organizationKey(argv.orgName)[0];
const organization = await orgProgram.account.organizationV0.fetch(
organizationK
);
const tuktukProgram = await initTuktuk(provider);
const hplCronsProgram = await initHplCrons(provider);

const queue = await tuktukProgram.account.taskQueueV0.fetch(TASK_QUEUE_ID);
const freeTasks = nextAvailableTaskIds(
queue.taskBitmap,
proposals.length - organization.numProposals
)[0];
let freeTaskIdx = 0;
const proposalConfig = argv.proposalConfig
? new PublicKey(argv.proposalConfig)
: organization.defaultProposalConfig;
const proposalConfigAcc = await stateProgram.account.proposalConfigV0.fetch(
proposalConfig
);

let i = 0;
for (const proposalData of proposals) {
Expand All @@ -93,7 +124,7 @@ export async function run(args: any = process.argv) {
pubkeys: { proposal },
} = await orgProgram.methods
.initializeProposalV0(proposalData)
.accounts({
.accountsPartial({
organization: organizationK,
owner: authority,
authority,
Expand All @@ -103,10 +134,11 @@ export async function run(args: any = process.argv) {
.prepare();

const { instruction: setState } = await stateProgram.methods
// @ts-ignore
.updateStateV0({
newState: { voting: {} },
})
.accounts({
.accountsPartial({
proposal,
owner: authority,
proposalConfig: proposalData.proposalConfig
Expand All @@ -116,6 +148,25 @@ export async function run(args: any = process.argv) {
})
.prepare();

const resolveIx = await hplCronsProgram.methods
.queueResolveProposalV0({
freeTaskId: freeTasks[freeTaskIdx],
})
.accountsPartial({
proposal: proposal!,
taskQueue: TASK_QUEUE_ID,
namespace: organizationK,
task: taskKey(TASK_QUEUE_ID, freeTasks[freeTaskIdx])[0],
proposalConfig,
stateController: proposalConfigAcc.stateController,
payer: authority,
systemProgram: SystemProgram.programId,
queueAuthority,
tuktukProgram: tuktukProgram.programId,
})
.instruction();

freeTaskIdx++;
instructions.push(instruction, setState);
}
i++;
Expand Down
2 changes: 1 addition & 1 deletion scripts/cancel-proposal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export async function run(args: any = process.argv) {
.updateStateV0({
newState: { cancelled: {} },
})
.accounts({
.accountsPartial({
proposal,
owner,
})
Expand Down
55 changes: 47 additions & 8 deletions scripts/create-proposal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@ import os from "os";
import yargs from "yargs/yargs";
import { init as initState } from "@helium/state-controller-sdk";
import Squads from "@sqds/sdk";
import { PublicKey } from "@solana/web3.js";
import { PublicKey, SystemProgram } from "@solana/web3.js";
import { loadKeypair, sendInstructionsOrSquads } from "./utils";
import { init as initTuktuk, taskKey } from "@helium/tuktuk-sdk";
import {
nextAvailableTaskIds,
queueAuthorityKey,
TASK_QUEUE_ID,
} from "@helium/hpl-crons-sdk";
import { init as initHplCrons } from "@helium/hpl-crons-sdk";

export async function run(args: any = process.argv) {
const yarg = yargs(args).options({
Expand Down Expand Up @@ -69,6 +76,8 @@ export async function run(args: any = process.argv) {
const wallet = new anchor.Wallet(walletKP);
const orgProgram = await initOrg(provider);
const stateProgram = await initState(provider);
const tuktukProgram = await initTuktuk(provider);
const hplCronsProgram = await initHplCrons(provider);
const organizationK = organizationKey(argv.orgName)[0];
const organization = await orgProgram.account.organizationV0.fetch(
organizationK
Expand Down Expand Up @@ -97,31 +106,61 @@ export async function run(args: any = process.argv) {
})),
tags: ["test", "tags"],
})
.accounts({
.accountsPartial({
payer: authority,
authority,
organization: organizationK,
owner: authority,
})
.prepare();

const proposalConfig = argv.proposalConfig
? new PublicKey(argv.proposalConfig)
: organization.defaultProposalConfig;
const proposalConfigAcc = await stateProgram.account.proposalConfigV0.fetch(
proposalConfig
);
const queueAuthority = queueAuthorityKey()[0];
console.log(
`Queue authority: ${queueAuthority.toBase58()} (Fund with Sol to pay task rent)`
);
const { instruction: setState } = await stateProgram.methods
// @ts-ignore
.updateStateV0({
newState: { voting: {} },
})
.accounts({
proposal,
.accountsStrict({
proposal: proposal!,
owner: authority,
proposalConfig: argv.proposalConfig
? new PublicKey(argv.proposalConfig)
: organization.defaultProposalConfig,
proposalConfig,
proposalProgram: organization.proposalProgram,
stateController: proposalConfigAcc.stateController,
})
.prepare();

const queue = await tuktukProgram.account.taskQueueV0.fetch(TASK_QUEUE_ID);
const freeTask = nextAvailableTaskIds(queue.taskBitmap, 1)[0];
const resolveIx = await hplCronsProgram.methods
.queueResolveProposalV0({
freeTaskId: freeTask,
})
.accountsPartial({
proposal: proposal!,
taskQueue: TASK_QUEUE_ID,
namespace: organizationK,
task: taskKey(TASK_QUEUE_ID, freeTask)[0],
proposalConfig,
stateController: proposalConfigAcc.stateController,
payer: authority,
systemProgram: SystemProgram.programId,
queueAuthority,
tuktukProgram: tuktukProgram.programId,
})
.instruction();

await sendInstructionsOrSquads({
provider,
instructions: [instruction, setState],
instructions: [instruction, setState, resolveIx],
executeTransaction: false,
squads,
multisig: argv.multisig ? new PublicKey(argv.multisig) : undefined,
Expand Down
2 changes: 1 addition & 1 deletion scripts/resolve-proposals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export async function run(args: any = process.argv) {

const resolveIxs = await Promise.all(openProposals.map(async p => {
return await stateProgram.methods.resolveV0()
.accounts({
.accountsPartial({
proposal: p.pubkey,
})
.instruction()
Expand Down
1 change: 1 addition & 0 deletions src/components/Positions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ export const Positions: FC = () => {
toast("Rewards claimed!");
refetchState();
} catch (e: any) {
console.error(e);
if (!(e instanceof WalletSignTransactionError)) {
toast(e.message || "Claiming rewards failed, please try again");
}
Expand Down
2 changes: 2 additions & 0 deletions src/components/VoteOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export const VoteOptions: FC<{
});
toast("Vote submitted");
} catch (e: any) {
console.error(e);
if (!(e instanceof WalletSignTransactionError)) {
setCurrVote(0);
toast(e.message || "Vote failed, please try again");
Expand All @@ -81,6 +82,7 @@ export const VoteOptions: FC<{
});
toast("Vote relinquished");
} catch (e: any) {
console.error(e);
if (!(e instanceof WalletSignTransactionError)) {
setCurrVote(0);
toast(e.message || "Relinquish vote failed, please try again");
Expand Down
21 changes: 20 additions & 1 deletion src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,26 @@ export const onInstructions =
useFirstEstimateForAll = false,
}: { useFirstEstimateForAll?: boolean } = {}
) =>
async (instructions: TransactionInstruction[], sigs?: Keypair[]) => {
async (
instructions: TransactionInstruction[] | TransactionInstruction[][],
sigs?: Keypair[]
) => {
if (useFirstEstimateForAll) {
// Sort instructions array so longest groups are first
instructions.sort((a, b) => {
const lengthA = Array.isArray(a) ? a.length : 1;
const lengthB = Array.isArray(b) ? b.length : 1;
return lengthB - lengthA;
});
}

// Sort instructions array so longest groups are first
instructions.sort((a, b) => {
const lengthA = Array.isArray(a) ? a.length : 1;
const lengthB = Array.isArray(b) ? b.length : 1;
return lengthB - lengthA;
});

if (provider) {
if (sigs) {
const transactions = await batchInstructionsToTxsWithPriorityFee(
Expand Down
Loading
Loading