@astonic-io/astonic-sdk
Version:
Official SDK for interacting with the Astonic Protocol
148 lines (147 loc) • 7.02 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { Signer, providers } from 'ethers';
import { AstonicGovernor__factory, } from '@astonic-io/astonic-bindings-ts';
import { ChainClient } from './ChainClient';
import { TestChainClient } from './TestChainClient';
import { ProposalState } from './enums';
import { addresses } from './constants';
export class Governance {
constructor(arg) {
// TODO: Remove use of TestChainClient in future this is only meant for testing
if (arg instanceof ChainClient || arg instanceof TestChainClient) {
this.chainClient = arg;
}
else if (Signer.isSigner(arg) || providers.Provider.isProvider(arg)) {
this.chainClient = new ChainClient(arg);
}
else {
throw new Error('Invalid constructor argument');
}
}
/**
* This function retrieves the AstonicGovernor contract.
* @returns The AstonicGovernor contract.
*/
getGovernorContract() {
return __awaiter(this, void 0, void 0, function* () {
const chainId = yield this.chainClient.getChainId();
const contracts = addresses[chainId];
if (!contracts) {
throw new Error(`Contracts not deployed on network with chain id ${chainId}`);
}
const astonicGovernorAddress = contracts.AstonicGovernor;
return AstonicGovernor__factory.connect(astonicGovernorAddress, yield this.chainClient.getSigner());
});
}
/**
* Generates a transaction that submits a proposal to be created to the Astonic Governor contract using the specified values.
* @param targets The addresses of the contracts to be called during proposal execution.
* @param values The values to be passed to the calls to the target contracts.
* @param calldatas The calldata to be passed to the calls to the target contracts.
* @param description A human readable description of the proposal.
* @returns The transaction request.
*/
createProposal(targets, values, calldatas, description) {
return __awaiter(this, void 0, void 0, function* () {
this.validateProposalArgs(targets, values, calldatas, description);
const governor = yield this.getGovernorContract();
const tx = yield governor.populateTransaction['propose(address[],uint256[],bytes[],string)'](targets, values, calldatas, description);
return yield this.chainClient.populateTransaction(tx);
});
}
/**
* Generates a transaction that will queue the proposal with the specified id to be executed.
* @param proposalId The id of the proposal to queue.
* @returns The transaction request.
*/
queueProposal(proposalId) {
return __awaiter(this, void 0, void 0, function* () {
const governor = yield this.getGovernorContract();
const tx = yield governor.populateTransaction['queue(uint256)'](proposalId);
return yield this.chainClient.populateTransaction(tx);
});
}
/**
* Executes the proposal with the specified id.
* @param proposalId The id of the proposal to execute.
* @returns The transaction request.
*/
executeProposal(proposalId) {
return __awaiter(this, void 0, void 0, function* () {
const governor = yield this.getGovernorContract();
const tx = yield governor.populateTransaction['execute(uint256)'](proposalId);
return yield this.chainClient.populateTransaction(tx);
});
}
/**
* Submits a vote to the Astonic Governor contract for the specified proposal.
* @param proposalId The id of the proposal to vote on.
* @param support Whether or not to support the proposal.
* @returns The transaction request.
*/
castVote(proposalId, support) {
return __awaiter(this, void 0, void 0, function* () {
const governor = yield this.getGovernorContract();
const tx = yield governor.populateTransaction.castVote(proposalId, support);
return yield this.chainClient.populateTransaction(tx);
});
}
/**
* Cancels the proposal with the specified id.
* @param proposalId The id of the proposal to vote on.
* @param support Whether or not to support the proposal.
* @returns The transaction request.
*/
cancelProposal(proposalId) {
return __awaiter(this, void 0, void 0, function* () {
const governor = yield this.getGovernorContract();
const tx = yield governor.populateTransaction.cancel(proposalId);
return yield this.chainClient.populateTransaction(tx);
});
}
/**
* Returns the state of the proposal with the specified id.
* @param proposalId The id of the proposal to get the state of.
* @returns The state of the proposal.
*/
getProposalState(proposalId) {
return __awaiter(this, void 0, void 0, function* () {
const governor = yield this.getGovernorContract();
const state = (yield governor.functions.state(proposalId))[0];
return ProposalState[state];
});
}
/**
* This function validates the args that are to be used in the createProposal function.
* @param targets The addresses of the contracts to be called during proposal execution.
* @param values The values to be passed to the calls to the target contracts.
* @param calldatas The calldata to be passed to the calls to the target contracts.
* @param description A human readable description of the proposal.
*/
validateProposalArgs(targets, values, calldatas, description) {
if (!targets || targets.length === 0) {
throw new Error('Targets must be specified');
}
if (!values || values.length === 0) {
throw new Error('Values must be specified');
}
if (!calldatas || calldatas.length === 0) {
throw new Error('Calldatas must be specified');
}
if (!description) {
throw new Error('Description must be specified');
}
if (targets.length !== values.length ||
targets.length !== calldatas.length) {
throw new Error('Targets, values, and calldatas must all have the same length');
}
}
}