SHA256
Отключить репосты и добавить Solana-модуль
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
#!/usr/bin/env node
|
||||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const BN = require("bn.js");
|
||||
const { Connection, Keypair, PublicKey, Transaction, sendAndConfirmTransaction, clusterApiUrl } = require("@solana/web3.js");
|
||||
const {
|
||||
PROGRAM_VERSION_V3,
|
||||
InstructionData,
|
||||
AccountMetaData,
|
||||
withRevokeGoverningTokens,
|
||||
withExecuteTransaction,
|
||||
} = require("@solana/spl-governance");
|
||||
|
||||
function parseEnvConfig(configPath) {
|
||||
const raw = fs.readFileSync(configPath, "utf8");
|
||||
const out = {};
|
||||
for (const line of raw.split("\n")) {
|
||||
const trimmed = line.trim();
|
||||
if (!trimmed || trimmed.startsWith("#")) continue;
|
||||
const eq = trimmed.indexOf("=");
|
||||
if (eq === -1) continue;
|
||||
const key = trimmed.slice(0, eq).trim();
|
||||
let val = trimmed.slice(eq + 1).trim();
|
||||
if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) {
|
||||
val = val.slice(1, -1);
|
||||
}
|
||||
val = val.replace(/\$HOME/g, process.env.HOME || "");
|
||||
out[key] = val;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function loadKeypair(filePath) {
|
||||
const arr = JSON.parse(fs.readFileSync(filePath, "utf8"));
|
||||
return Keypair.fromSecretKey(Uint8Array.from(arr));
|
||||
}
|
||||
|
||||
function toGovernanceInstructionData(ix) {
|
||||
return new InstructionData({
|
||||
programId: ix.programId,
|
||||
accounts: ix.keys.map(
|
||||
(k) =>
|
||||
new AccountMetaData({
|
||||
pubkey: k.pubkey,
|
||||
isSigner: !!k.isSigner,
|
||||
isWritable: !!k.isWritable,
|
||||
})
|
||||
),
|
||||
data: Uint8Array.from(ix.data),
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const configPath = process.argv[2] ? path.resolve(process.argv[2]) : path.resolve(__dirname, "dao.config.env");
|
||||
const realm = new PublicKey(process.argv[3]);
|
||||
const governance = new PublicKey(process.argv[4]);
|
||||
const proposal = new PublicKey(process.argv[5]);
|
||||
const proposalTx = new PublicKey(process.argv[6]);
|
||||
const mint = new PublicKey(process.argv[7]);
|
||||
const targetOwner = new PublicKey(process.argv[8]);
|
||||
const amount = new BN(process.argv[9] || "1");
|
||||
if (!process.argv[8]) {
|
||||
throw new Error(
|
||||
"Использование: node scripts/dao/execute_revoke_transaction_full_exec.js <config.env> <realm> <governance> <proposal> <proposal_tx> <mint> <target_owner> [amount]"
|
||||
);
|
||||
}
|
||||
const cfg = parseEnvConfig(configPath);
|
||||
const cluster = cfg.DAO_CLUSTER || "devnet";
|
||||
const governanceProgramId = new PublicKey(cfg.SPL_GOVERNANCE_PROGRAM_ID);
|
||||
const signer = loadKeypair(path.resolve(cfg.DAO_ISSUER_KEYPAIR));
|
||||
const connection = new Connection(clusterApiUrl(cluster), "confirmed");
|
||||
|
||||
const ixRawRevoke = [];
|
||||
await withRevokeGoverningTokens(
|
||||
ixRawRevoke,
|
||||
governanceProgramId,
|
||||
PROGRAM_VERSION_V3,
|
||||
realm,
|
||||
targetOwner,
|
||||
mint,
|
||||
governance,
|
||||
amount
|
||||
);
|
||||
const revokeInstructionData = toGovernanceInstructionData(ixRawRevoke[0]);
|
||||
|
||||
const ixExecute = [];
|
||||
await withExecuteTransaction(
|
||||
ixExecute,
|
||||
governanceProgramId,
|
||||
PROGRAM_VERSION_V3,
|
||||
governance,
|
||||
proposal,
|
||||
proposalTx,
|
||||
[revokeInstructionData]
|
||||
);
|
||||
const sig = await sendAndConfirmTransaction(connection, new Transaction().add(...ixExecute), [signer], {
|
||||
commitment: "confirmed",
|
||||
});
|
||||
console.log("Execute success. Tx:", sig);
|
||||
}
|
||||
|
||||
main().catch((e) => {
|
||||
console.error("Ошибка execute revoke:", e?.message || e);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user