UNPKG

@tribecahq/tribeca-sdk

Version:

The TypeScript SDK for Tribeca, an open standard and toolkit for launching DAOs on Solana.

178 lines 6.21 kB
import { getATAAddress, getOrCreateATA, TOKEN_PROGRAM_ID, } from "@saberhq/token-utils"; import { SystemProgram } from "@solana/web3.js"; import BN from "bn.js"; import { TRIBECA_ADDRESSES } from "../../constants"; import { findVoteAddress } from "../govern/pda"; export class VoteEscrow { constructor(sdk, locker, governorKey, escrowKey, owner) { this.sdk = sdk; this.locker = locker; this.governorKey = governorKey; this.escrowKey = escrowKey; this.owner = owner; this._lockerData = null; this._escrowData = null; } get provider() { return this.sdk.provider; } get lockerProgram() { return this.sdk.programs.LockedVoter; } /** * Locker data. */ async lockerData() { if (!this._lockerData) { this._lockerData = await this.lockerProgram.account.locker.fetch(this.locker); } return this._lockerData; } /** * Escrow data. */ async data() { if (!this._escrowData) { this._escrowData = await this.lockerProgram.account.escrow.fetch(this.escrowKey); } return this._escrowData; } /** * Creates a function to calculate the voting power of this escrow. * @returns */ async makeCalculateVotingPower() { const escrowData = await this.data(); const lockerData = await this.lockerData(); return (timestampSeconds) => { if (escrowData.escrowStartedAt.eq(new BN(0))) { return new BN(0); } if (timestampSeconds < escrowData.escrowStartedAt.toNumber() || timestampSeconds >= escrowData.escrowEndsAt.toNumber()) { return new BN(0); } const secondsUntilLockupExpiry = escrowData.escrowEndsAt .sub(new BN(timestampSeconds)) .toNumber(); const relevantSecondsUntilLockupExpiry = Math.min(secondsUntilLockupExpiry, lockerData.params.maxStakeDuration.toNumber()); const powerIfMaxLockup = escrowData.amount.mul(new BN(lockerData.params.maxStakeVoteMultiplier)); return powerIfMaxLockup .mul(new BN(relevantSecondsUntilLockupExpiry)) .div(lockerData.params.maxStakeDuration); }; } /** * Calculates the voting power of this escrow. * @param time Optional time to calculate power for. * @returns */ async calculateVotingPower(time = new Date()) { return (await this.makeCalculateVotingPower())(Math.floor(time.getTime() / 1000)); } /** * Activates a proposal. * @returns */ activateProposal(proposal) { return this.provider.newTX([ this.lockerProgram.instruction.activateProposal({ accounts: { locker: this.locker, governor: this.governorKey, proposal, escrow: this.escrowKey, escrowOwner: this.owner, governProgram: TRIBECA_ADDRESSES.Govern, }, }), ]); } /** * Casts a vote on a proposal. * @returns */ async castVote({ proposal, side, }) { const [voteKey, voteBump] = await findVoteAddress(proposal, this.owner); const vote = await this.provider.getAccountInfo(voteKey); let createVoteIX = null; if (!vote) { createVoteIX = this.sdk.programs.Govern.instruction.newVote(voteBump, this.owner, { accounts: { proposal, vote: voteKey, payer: this.provider.wallet.publicKey, systemProgram: SystemProgram.programId, }, }); } return this.provider.newTX([ createVoteIX, this.lockerProgram.instruction.castVote(side, { accounts: { locker: this.locker, escrow: this.escrowKey, voteDelegate: this.owner, proposal, vote: voteKey, governor: this.governorKey, governProgram: TRIBECA_ADDRESSES.Govern, }, }), ]); } /** * Locks tokens into the escrow. * @param amount * @param durationSeconds The duration of the lock, in seconds * @param authority * @returns */ async lock(amount, durationSeconds) { const escrowData = await this.data(); const sourceTokens = await getATAAddress({ mint: amount.token.mintAccount, owner: escrowData.owner, }); return this.provider.newTX([ this.lockerProgram.instruction.lock(amount.toU64(), new BN(durationSeconds), { accounts: { locker: this.locker, escrow: this.escrowKey, escrowTokens: escrowData.tokens, escrowOwner: escrowData.owner, sourceTokens, tokenProgram: TOKEN_PROGRAM_ID, }, }), ]); } /** * Exits the escrow. * @returns */ async exit() { const lockerData = await this.lockerData(); const escrowData = await this.data(); const destinationTokens = await getOrCreateATA({ provider: this.provider, mint: lockerData.tokenMint, owner: escrowData.owner, }); return this.provider.newTX([ destinationTokens.instruction, this.lockerProgram.instruction.exit({ accounts: { locker: this.locker, escrow: this.escrowKey, escrowOwner: escrowData.owner, escrowTokens: escrowData.tokens, destinationTokens: destinationTokens.address, payer: this.provider.wallet.publicKey, tokenProgram: TOKEN_PROGRAM_ID, }, }), ]); } } //# sourceMappingURL=escrow.js.map