@tribecahq/tribeca-sdk
Version:
The TypeScript SDK for Tribeca, an open standard and toolkit for launching DAOs on Solana.
173 lines • 6.42 kB
JavaScript
import { findTransactionAddress, GOKI_ADDRESSES, GOKI_CODERS, } from "@gokiprotocol/client";
import { TransactionEnvelope } from "@saberhq/solana-contrib";
import { u64 } from "@saberhq/token-utils";
import { SystemProgram } from "@solana/web3.js";
import { findProposalAddress, findProposalMetaAddress, findVoteAddress, } from "./pda";
/**
* Wrapper around a Governor.
*/
export class GovernorWrapper {
constructor(sdk, governorKey) {
this.sdk = sdk;
this.governorKey = governorKey;
this._governor = null;
}
get provider() {
return this.sdk.provider;
}
get program() {
return this.sdk.programs.Govern;
}
async reload() {
return await this.program.account.governor.fetch(this.governorKey);
}
async data() {
if (!this._governor) {
this._governor = await this.reload();
}
return this._governor;
}
async findProposalAddress(index) {
const [key] = await findProposalAddress(this.governorKey, index);
return key;
}
async fetchProposalByKey(key) {
return await this.program.account.proposal.fetch(key);
}
async fetchProposal(index) {
const key = await this.findProposalAddress(index);
return await this.fetchProposalByKey(key);
}
async fetchProposalMeta(proposalKey) {
const [key] = await findProposalMetaAddress(proposalKey);
return await this.program.account.proposalMeta.fetch(key);
}
/**
* Creates a ProposalMeta for a proposal.
* Only the Proposer may call this.
*
* @returns
*/
async createProposalMeta({ proposal, proposer = this.sdk.provider.wallet.publicKey, title, descriptionLink, }) {
const [proposalMetaKey, bump] = await findProposalMetaAddress(proposal);
const ix = this.sdk.programs.Govern.instruction.createProposalMeta(bump, title, descriptionLink, {
accounts: {
proposal,
proposer,
proposalMeta: proposalMetaKey,
payer: this.provider.wallet.publicKey,
systemProgram: SystemProgram.programId,
},
});
return this.provider.newTX([ix]);
}
/**
* Creates a new Proposal.
* @returns
*/
async createProposal({ proposer = this.sdk.provider.wallet.publicKey, instructions, }) {
const { provider } = this.sdk;
const governorData = await this.reload();
const index = new u64(governorData.proposalCount);
const [proposal, bump] = await findProposalAddress(this.governorKey, index);
const ixs = [];
ixs.push(this.sdk.programs.Govern.instruction.createProposal(bump, instructions, {
accounts: {
governor: this.governorKey,
proposal,
proposer,
payer: provider.wallet.publicKey,
systemProgram: SystemProgram.programId,
},
}));
return {
proposal,
index,
tx: this.provider.newTX(ixs),
};
}
/**
* Queues a Proposal for execution by the Smart Wallet.
* @returns
*/
async queueProposal({ index, smartWalletProgram = GOKI_ADDRESSES.SmartWallet, payer = this.provider.wallet.publicKey, }) {
const governorData = await this.data();
const [proposal] = await findProposalAddress(this.governorKey, index);
const smartWalletDataRaw = await this.program.provider.connection.getAccountInfo(governorData.smartWallet);
if (!smartWalletDataRaw) {
throw new Error("smart wallet not found");
}
const smartWalletData = GOKI_CODERS.SmartWallet.accountParsers.smartWallet(smartWalletDataRaw.data);
const [txKey, txBump] = await findTransactionAddress(governorData.smartWallet, smartWalletData.numTransactions.toNumber());
return new TransactionEnvelope(this.sdk.provider, [
this.program.instruction.queueProposal(txBump, {
accounts: {
governor: this.governorKey,
proposal,
smartWallet: governorData.smartWallet,
smartWalletProgram,
transaction: txKey,
payer,
systemProgram: SystemProgram.programId,
},
}),
]);
}
/**
* Cancel a new Proposal.
* @returns
*/
cancelProposal({ proposal, proposer = this.sdk.provider.wallet.publicKey, }) {
return new TransactionEnvelope(this.sdk.provider, [
this.sdk.programs.Govern.instruction.cancelProposal({
accounts: {
governor: this.governorKey,
proposal,
proposer,
},
}),
]);
}
async getOrCreateVote({ proposal, voter = this.sdk.provider.wallet.publicKey, payer = this.sdk.provider.wallet.publicKey, }) {
const [voteKey, bump] = await findVoteAddress(proposal, voter);
try {
await this.program.account.vote.fetch(voteKey);
return { voteKey, instruction: null };
}
catch {
return {
voteKey,
instruction: await this.createVoteIx({
proposal,
voteKeyAndBump: [voteKey, bump],
voter,
payer,
}),
};
}
}
async createVoteIx({ proposal, voteKeyAndBump, voter = this.sdk.provider.wallet.publicKey, payer = this.sdk.provider.wallet.publicKey, }) {
if (!voteKeyAndBump) {
voteKeyAndBump = await findVoteAddress(proposal, voter);
}
const [voteKey, bump] = voteKeyAndBump;
return this.program.instruction.newVote(bump, voter, {
accounts: {
vote: voteKey,
proposal,
payer,
systemProgram: SystemProgram.programId,
},
});
}
async setGovernanceParamsIx(newParams) {
const { smartWallet } = await this.data();
return this.program.instruction.setGovernanceParams(newParams, {
accounts: {
governor: this.governorKey,
smartWallet,
},
});
}
}
//# sourceMappingURL=governor.js.map