@surec/oracle
Version:
Typescript SDK for the Sure Oracle to be used to bring off-chain data on-chain
212 lines • 7.66 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Vote = exports.revealVote = exports.createVoteHash = void 0;
const tslib_1 = require("tslib");
const sha3_1 = require("sha3");
const randombytes_1 = tslib_1.__importDefault(require("randombytes"));
const constants_js_1 = require("./constants.js");
const utils_js_1 = require("./utils.js");
const spl = tslib_1.__importStar(require("@solana/spl-token"));
const createVoteHash = ({ vote, salt, }) => {
const hash = new sha3_1.SHA3(256);
const voteCandidate = vote.toString() + salt.toString('utf8');
hash.update(voteCandidate);
return hash.digest();
};
exports.createVoteHash = createVoteHash;
const revealVote = ({ expectedVoteHash, vote, salt, }) => {
const expectedVoteHashB = Buffer.from(expectedVoteHash);
const voteHash = (0, exports.createVoteHash)({ vote, salt });
return voteHash.equals(expectedVoteHashB);
};
exports.revealVote = revealVote;
class Vote {
constructor(sdk) {
this.sdk = sdk;
this.program = sdk.program;
}
/**
* submit a vote to a proposal
*
* @param mint - mint of proposal vault
* @param proposal - the proposal to vote on
* @param locker - locker used to lock tokens, see Tribeca
* @param userEscrow - escrow that holds the locked tokens
* @returns
*/
async submitVote({ vote, mint, proposal, locker, userEscrow, }) {
const tokenMint = mint !== null && mint !== void 0 ? mint : constants_js_1.SURE_MINT;
(0, utils_js_1.validateKeys)([
{ v: tokenMint, n: 'tokenMint' },
{ v: proposal, n: 'proposal' },
{ v: locker, n: 'lcoker' },
{ v: userEscrow, n: 'escrow' },
]);
const salt = (0, randombytes_1.default)(16);
const voteHash = (0, exports.createVoteHash)({ vote, salt });
let ixs = [];
const createATA = await (0, utils_js_1.getOrCreateAssociatedTokenAccountIx)({
connection: this.sdk.provider.connection,
payer: this.sdk.provider.wallet.payer,
mint: tokenMint,
owner: this.sdk.provider.walletKey,
});
const [proposalVault] = await this.sdk.pda.findProposalVault({ proposal });
if (createATA.instruction) {
ixs.push(createATA.instruction);
}
ixs.push(await this.program.methods
.submitVote(voteHash)
.accounts({
voterAccount: createATA.address,
locker,
userEscrow,
proposal,
proposalVault: proposalVault,
proposalVaultMint: tokenMint,
})
.instruction());
return {
salt: salt,
transactionEnvelope: this.sdk.provider.newTX(ixs),
};
}
/**
* update vote
*
* @param mint - mint of proposal vault
* @param proposal - the proposal to vote on
* @returns
*/
async updateVote({ vote, proposal, }) {
(0, utils_js_1.validateKeys)([{ v: proposal, n: 'proposal' }]);
const salt = (0, randombytes_1.default)(16);
const voteHash = (0, exports.createVoteHash)({ vote, salt });
const voter = this.sdk.provider.wallet.publicKey;
const [voteAccount] = await this.sdk.pda.findVoteAccount({
proposal,
voter,
});
let ixs = [];
ixs.push(await this.program.methods
.updateVote(voteHash)
.accounts({
proposal,
voteAccount,
})
.instruction());
return {
salt: salt,
transactionEnvelope: this.sdk.provider.newTX(ixs),
};
}
/**
* cancel vote
*
* @param voteAccout - the account used to vote with
* @returns
*/
async cancelVote({ voteAccount }) {
(0, utils_js_1.validateKeys)([{ v: voteAccount, n: 'voteAccount' }]);
const voter = this.sdk.provider.wallet.publicKey;
const voteAccountLoaded = await this.program.account.voteAccount.fetch(voteAccount);
const stakeMint = voteAccountLoaded.stakeMint;
const proposal = voteAccountLoaded.proposal;
const [proposalVault] = await this.sdk.pda.findProposalVault({ proposal });
const voterAccount = await spl.getAssociatedTokenAddress(voteAccountLoaded.tokenMint, voter);
let ixs = [];
ixs.push(await this.program.methods
.cancelVote()
.accounts({
voterAccount: voterAccount,
proposalVault,
proposalVaultMint: stakeMint,
proposal: voteAccountLoaded.proposal,
voteAccount,
})
.instruction());
return this.sdk.provider.newTX(ixs);
}
/**
* cancel vote
*
* @param voteAccount - the account used to vote with
* @returns
*/
async revealVote({ voteAccount, vote, salt, }) {
(0, utils_js_1.validateKeys)([{ v: voteAccount, n: 'voteAccount' }]);
const voteAccountLoaded = await this.program.account.voteAccount.fetch(voteAccount);
const proposal = voteAccountLoaded.proposal;
const [voteArray] = await this.sdk.pda.findRevealVoteArrayAddress({
proposal,
});
let ixs = [];
ixs.push(await this.program.methods
.revealVote(salt.toString(), vote)
.accounts({
proposal,
revealVoteArray: voteArray,
voteAccount,
})
.instruction());
return this.sdk.provider.newTX(ixs);
}
/**
* finalize vote
*
* @param voteAccount - the account used to vote with
* @returns
*/
async finalizeVote({ voteAccount, }) {
(0, utils_js_1.validateKeys)([{ v: voteAccount, n: 'voteAccount' }]);
const voteAccountLoaded = await this.program.account.voteAccount.fetch(voteAccount);
const proposal = voteAccountLoaded.proposal;
let ixs = [];
ixs.push(await this.program.methods
.finalizeVote()
.accounts({
proposal,
voteAccount,
})
.instruction());
return this.sdk.provider.newTX(ixs);
}
/**
* collect vote rewards
*
* @param voteAccount - the account used to vote with
* @returns
*/
async collectRewards({ voteAccount, tokenMint, }) {
(0, utils_js_1.validateKeys)([{ v: voteAccount, n: 'voteAccount' }]);
const voteAccountLoaded = await this.program.account.voteAccount.fetch(voteAccount);
const proposal = voteAccountLoaded.proposal;
const mint = voteAccountLoaded.stakeMint;
const voterAccount = await (0, utils_js_1.getOrCreateAssociatedTokenAccountIx)({
connection: this.sdk.provider.connection,
payer: this.sdk.provider.wallet.payer,
mint,
owner: this.sdk.provider.walletKey,
});
const [config] = this.sdk.pda.findOracleConfig({ tokenMint });
const [proposalVault] = this.sdk.pda.findProposalVault({ proposal });
let ixs = [];
if (voterAccount.instruction) {
ixs.push(voterAccount.instruction);
}
ixs.push(await this.program.methods
.collectVoteReward()
.accounts({
config,
voterAccount: voterAccount.address,
voteAccount,
proposal,
proposalVaultMint: mint,
proposalVault,
})
.instruction());
return this.sdk.provider.newTX(ixs);
}
}
exports.Vote = Vote;
//# sourceMappingURL=vote.js.map