@tribecahq/tribeca-sdk
Version:
The TypeScript SDK for Tribeca, an open standard and toolkit for launching DAOs on Solana.
289 lines • 12.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LockerWrapper = void 0;
const tslib_1 = require("tslib");
const solana_contrib_1 = require("@saberhq/solana-contrib");
const token_utils_1 = require("@saberhq/token-utils");
const web3_js_1 = require("@solana/web3.js");
const tiny_invariant_1 = tslib_1.__importDefault(require("tiny-invariant"));
const constants_1 = require("../../constants");
const governor_1 = require("../govern/governor");
const _1 = require(".");
const pda_1 = require("./pda");
/**
* Helper methods around a Locked Voter electorate.
*/
class LockerWrapper {
constructor(sdk, locker, governorKey) {
this.sdk = sdk;
this.locker = locker;
this.governorKey = governorKey;
this._lockerData = null;
this.program = sdk.programs.LockedVoter;
this.governor = new governor_1.GovernorWrapper(sdk, governorKey);
}
static async load(sdk, lockerKey, governorKey) {
const wrapper = new LockerWrapper(sdk, lockerKey, governorKey);
await wrapper.data();
return wrapper;
}
/**
* Fetches the data of the locker.
* @returns
*/
async reload() {
return this.program.account.locker.fetch(this.locker);
}
async fetchProposalData(proposalKey) {
return await this.sdk.govern.program.account.proposal.fetch(proposalKey);
}
async fetchEscrow(escrowKey) {
return await this.program.account.escrow.fetch(escrowKey);
}
async fetchEscrowByAuthority(authority = this.sdk.provider.wallet.publicKey) {
const [escrowKey] = await (0, pda_1.findEscrowAddress)(this.locker, authority);
return this.fetchEscrow(escrowKey);
}
/**
* Fetches the data of the locker.
* @returns
*/
async data() {
if (!this._lockerData) {
this._lockerData = await this.reload();
}
return this._lockerData;
}
async getOrCreateEscrow(authority = this.sdk.provider.wallet.publicKey) {
const [escrow] = await (0, pda_1.findEscrowAddress)(this.locker, authority);
const escrowData = await this.program.account.escrow.fetchNullable(escrow);
if (escrowData) {
return { escrow: escrow, instruction: null };
}
else {
return {
escrow: escrow,
instruction: await this.newEscrowIX(authority),
};
}
}
/**
* Creates the instruction to build a new Escrow.
* @param authority
* @returns
*/
async newEscrowIX(authority = this.sdk.provider.wallet.publicKey) {
const [escrow, bump] = await (0, pda_1.findEscrowAddress)(this.locker, authority);
return this.program.instruction.newEscrow(bump, {
accounts: {
locker: this.locker,
escrow,
escrowOwner: authority,
payer: this.sdk.provider.wallet.publicKey,
systemProgram: web3_js_1.SystemProgram.programId,
},
});
}
async activateProposal({ proposal, authority = this.sdk.provider.wallet.publicKey, }) {
const [escrow] = await (0, pda_1.findEscrowAddress)(this.locker, authority);
const ix = this.program.instruction.activateProposal({
accounts: {
locker: this.locker,
governor: this.governorKey,
proposal,
escrow,
escrowOwner: authority,
governProgram: constants_1.TRIBECA_ADDRESSES.Govern,
},
});
return new solana_contrib_1.TransactionEnvelope(this.sdk.provider, [ix]);
}
async lockTokensV1({ amount, duration, authority = this.sdk.provider.wallet.publicKey, }) {
(0, tiny_invariant_1.default)(this.locker, "locker not set");
const { escrow, instruction: initEscrowIx } = await this.getOrCreateEscrow(authority);
const { govTokenAccount, govTokenVault, instructions } = await this._getOrCreateGovTokenATAsInternal(authority, escrow);
if (initEscrowIx) {
instructions.push(initEscrowIx);
}
const lockerData = await this.reload();
instructions.push(this.program.instruction.lock(amount, duration, {
accounts: {
locker: this.locker,
escrow: escrow,
escrowOwner: authority,
escrowTokens: govTokenVault,
sourceTokens: govTokenAccount,
tokenProgram: token_utils_1.TOKEN_PROGRAM_ID,
},
remainingAccounts: lockerData.params.whitelistEnabled
? [
{
pubkey: web3_js_1.SYSVAR_INSTRUCTIONS_PUBKEY,
isSigner: false,
isWritable: false,
},
{
pubkey: web3_js_1.PublicKey.default,
isSigner: false,
isWritable: false,
},
]
: [],
}));
return new solana_contrib_1.TransactionEnvelope(this.sdk.provider, instructions);
}
async lockTokens({ amount, duration, authority = this.sdk.provider.wallet.publicKey, }) {
(0, tiny_invariant_1.default)(this.locker, "locker not set");
const { escrow, instruction: initEscrowIx } = await this.getOrCreateEscrow(authority);
const { govTokenAccount, govTokenVault, instructions } = await this._getOrCreateGovTokenATAsInternal(authority, escrow);
if (initEscrowIx) {
instructions.push(initEscrowIx);
}
const lockerData = await this.reload();
const lockAccounts = {
locker: this.locker,
escrow: escrow,
escrowOwner: authority,
escrowTokens: govTokenVault,
sourceTokens: govTokenAccount,
tokenProgram: token_utils_1.TOKEN_PROGRAM_ID,
};
if (lockerData.params.whitelistEnabled) {
instructions.push(this.program.instruction.lockWithWhitelist(amount, duration, {
accounts: {
lock: lockAccounts,
instructionsSysvar: web3_js_1.SYSVAR_INSTRUCTIONS_PUBKEY,
},
}));
}
else {
instructions.push(this.program.instruction.lockPermissionless(amount, duration, {
accounts: lockAccounts,
}));
}
return new solana_contrib_1.TransactionEnvelope(this.sdk.provider, instructions);
}
async exit({ authority = this.sdk.provider.wallet.publicKey, }) {
(0, tiny_invariant_1.default)(this.locker, "locker not set");
const [escrow] = await (0, pda_1.findEscrowAddress)(this.locker, authority);
const escrowData = await this.fetchEscrow(escrow);
const { govTokenAccount, instructions } = await this._getOrCreateGovTokenATAsInternal(authority, escrow);
instructions.push(this.program.instruction.exit({
accounts: {
locker: this.locker,
escrow,
escrowOwner: authority,
escrowTokens: escrowData.tokens,
destinationTokens: govTokenAccount,
payer: this.sdk.provider.wallet.publicKey,
tokenProgram: token_utils_1.TOKEN_PROGRAM_ID,
},
}));
return new solana_contrib_1.TransactionEnvelope(this.sdk.provider, instructions);
}
async castVotes({ voteSide, proposal, authority = this.sdk.provider.wallet.publicKey, reason, }) {
const ixs = [];
const { escrow, instruction: escrowIx } = await this.getOrCreateEscrow(authority);
if (escrowIx) {
ixs.push(escrowIx);
}
const { voteKey, instruction: createVoteIX } = await this.governor.getOrCreateVote({
proposal,
voter: authority,
});
if (createVoteIX) {
ixs.push(createVoteIX);
}
ixs.push(this.program.instruction.castVote(voteSide, {
accounts: {
locker: this.locker,
escrow: escrow,
voteDelegate: authority !== null && authority !== void 0 ? authority : this.sdk.provider.wallet.publicKey,
proposal,
vote: voteKey,
governor: this.governorKey,
governProgram: constants_1.TRIBECA_ADDRESSES.Govern,
},
}));
if (reason === null || reason === void 0 ? void 0 : reason.length) {
ixs.push((0, solana_contrib_1.createMemoInstruction)(reason, [authority]));
}
return new solana_contrib_1.TransactionEnvelope(this.sdk.provider, ixs);
}
async setVoteDelegate(newDelegate, authority = this.sdk.provider.wallet.publicKey) {
const [escrow] = await (0, pda_1.findEscrowAddress)(this.locker, authority);
return new solana_contrib_1.TransactionEnvelope(this.sdk.provider, [
this.program.instruction.setVoteDelegate(newDelegate, {
accounts: {
escrow,
escrowOwner: authority,
},
}),
]);
}
async createApproveProgramLockPrivilegeIx(programId, owner) {
const [whitelistEntry, bump] = await (0, _1.findWhitelistAddress)(this.locker, programId, owner);
const lockerData = await this.reload();
const governorData = await this.sdk.programs.Govern.account.governor.fetch(lockerData.governor);
return this.program.instruction.approveProgramLockPrivilege(bump, {
accounts: {
locker: this.locker,
whitelistEntry,
governor: lockerData.governor,
smartWallet: governorData.smartWallet,
executableId: programId,
whitelistedOwner: owner !== null && owner !== void 0 ? owner : web3_js_1.SystemProgram.programId,
payer: this.sdk.provider.wallet.publicKey,
systemProgram: web3_js_1.SystemProgram.programId,
},
});
}
async createRevokeProgramLockPrivilegeIx(programId, owner) {
const [whitelistEntry] = await (0, _1.findWhitelistAddress)(this.locker, programId, owner);
const lockerData = await this.reload();
const governorData = await this.sdk.programs.Govern.account.governor.fetch(lockerData.governor);
return this.program.instruction.revokeProgramLockPrivilege({
accounts: {
locker: this.locker,
whitelistEntry,
governor: lockerData.governor,
smartWallet: governorData.smartWallet,
payer: this.sdk.provider.wallet.publicKey,
},
});
}
async setLockerParamsIx(args) {
const lockerData = await this.reload();
const governorData = await this.sdk.programs.Govern.account.governor.fetch(lockerData.governor);
return this.program.instruction.setLockerParams(args, {
accounts: {
locker: this.locker,
governor: lockerData.governor,
smartWallet: governorData.smartWallet,
},
});
}
async _getOrCreateGovTokenATAsInternal(authority, escrow) {
const { provider } = this.sdk;
const lockerData = await this.data();
const { address: govTokenAccount, instruction: ix1 } = await (0, token_utils_1.getOrCreateATA)({
provider,
mint: lockerData.tokenMint,
owner: authority,
payer: authority,
});
const { address: govTokenVault, instruction: ix2 } = await (0, token_utils_1.getOrCreateATA)({
provider,
mint: lockerData.tokenMint,
owner: escrow,
payer: authority,
});
return {
govTokenAccount,
govTokenVault,
instructions: [ix1, ix2].filter((ix) => !!ix),
};
}
}
exports.LockerWrapper = LockerWrapper;
//# sourceMappingURL=locker.js.map