forked from tornado-packages/tornado-core
Added Governance Event Functions
This commit is contained in:
parent
0e2da438ca
commit
8600bd8842
38
dist/events/base.d.ts
vendored
38
dist/events/base.d.ts
vendored
@ -5,7 +5,8 @@ import { fetchDataOptions } from '../providers';
|
||||
import { type NetIdType, type SubdomainMap } from '../networkConfig';
|
||||
import { RelayerParams } from '../relayerClient';
|
||||
import type { TovarishClient } from '../tovarishClient';
|
||||
import type { BaseEvents, CachedEvents, MinimalEvents, DepositsEvents, WithdrawalsEvents, EncryptedNotesEvents, AllGovernanceEvents, RegistersEvents, EchoEvents } from './types';
|
||||
import type { ReverseRecords } from '../typechain';
|
||||
import type { BaseEvents, CachedEvents, MinimalEvents, DepositsEvents, WithdrawalsEvents, EncryptedNotesEvents, AllGovernanceEvents, GovernanceProposalCreatedEvents, GovernanceVotedEvents, RegistersEvents, EchoEvents } from './types';
|
||||
export declare const DEPOSIT = "deposit";
|
||||
export declare const WITHDRAWAL = "withdrawal";
|
||||
export interface BaseEventsServiceConstructor {
|
||||
@ -137,10 +138,31 @@ export declare class BaseEncryptedNotesService extends BaseEventsService<Encrypt
|
||||
getGraphMethod(): string;
|
||||
formatEvents(events: EventLog[]): Promise<EncryptedNotesEvents[]>;
|
||||
}
|
||||
export declare const proposalState: {
|
||||
[key: string]: string;
|
||||
};
|
||||
export interface GovernanceProposals extends GovernanceProposalCreatedEvents {
|
||||
title: string;
|
||||
forVotes: bigint;
|
||||
againstVotes: bigint;
|
||||
executed: boolean;
|
||||
extended: boolean;
|
||||
quorum: string;
|
||||
state: string;
|
||||
}
|
||||
export interface GovernanceVotes extends GovernanceVotedEvents {
|
||||
contact: string;
|
||||
message: string;
|
||||
}
|
||||
export interface BaseGovernanceServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
|
||||
Governance: Governance;
|
||||
Aggregator: Aggregator;
|
||||
ReverseRecords: ReverseRecords;
|
||||
}
|
||||
export declare class BaseGovernanceService extends BaseEventsService<AllGovernanceEvents> {
|
||||
Governance: Governance;
|
||||
Aggregator: Aggregator;
|
||||
ReverseRecords: ReverseRecords;
|
||||
batchTransactionService: BatchTransactionService;
|
||||
constructor(serviceConstructor: BaseGovernanceServiceConstructor);
|
||||
getInstanceName(): string;
|
||||
@ -150,6 +172,20 @@ export declare class BaseGovernanceService extends BaseEventsService<AllGovernan
|
||||
getEventsFromGraph({ fromBlock }: {
|
||||
fromBlock: number;
|
||||
}): Promise<BaseEvents<AllGovernanceEvents>>;
|
||||
getAllProposals(): Promise<GovernanceProposals[]>;
|
||||
getVotes(proposalId: number): Promise<{
|
||||
votes: GovernanceVotes[];
|
||||
ensNames: {
|
||||
[key: string]: string;
|
||||
};
|
||||
}>;
|
||||
getDelegatedBalance(ethAccount: string): Promise<{
|
||||
delegatedAccs: string[];
|
||||
undelegatedAccs: string[];
|
||||
uniq: string[];
|
||||
balances: bigint[];
|
||||
balance: bigint;
|
||||
}>;
|
||||
}
|
||||
export declare function getTovarishNetworks(registryService: BaseRegistryService, relayers: CachedRelayerInfo[]): Promise<void>;
|
||||
/**
|
||||
|
159
dist/index.js
vendored
159
dist/index.js
vendored
@ -3158,15 +3158,91 @@ class BaseEncryptedNotesService extends BaseEventsService {
|
||||
}).filter((e) => e);
|
||||
}
|
||||
}
|
||||
const abiCoder = ethers.AbiCoder.defaultAbiCoder();
|
||||
const proposalState = {
|
||||
0: "Pending",
|
||||
1: "Active",
|
||||
2: "Defeated",
|
||||
3: "Timelocked",
|
||||
4: "AwaitingExecution",
|
||||
5: "Executed",
|
||||
6: "Expired"
|
||||
};
|
||||
function parseDescription(id, text) {
|
||||
switch (id) {
|
||||
case 1:
|
||||
return {
|
||||
title: text,
|
||||
description: "See: https://torn.community/t/proposal-1-enable-torn-transfers/38"
|
||||
};
|
||||
case 10:
|
||||
text = text.replace("\n", "\\n\\n");
|
||||
break;
|
||||
case 11:
|
||||
text = text.replace('"description"', ',"description"');
|
||||
break;
|
||||
case 13:
|
||||
text = text.replace(/\\\\n\\\\n(\s)?(\\n)?/g, "\\n");
|
||||
break;
|
||||
case 15:
|
||||
text = text.replaceAll("'", '"');
|
||||
text = text.replace('"description"', ',"description"');
|
||||
break;
|
||||
case 16:
|
||||
text = text.replace("#16: ", "");
|
||||
break;
|
||||
case 21:
|
||||
return {
|
||||
title: "Proposal #21: Restore Governance",
|
||||
description: ""
|
||||
};
|
||||
}
|
||||
let title, description, rest;
|
||||
try {
|
||||
({ title, description } = JSON.parse(text));
|
||||
} catch {
|
||||
[title, ...rest] = text.split("\n", 2);
|
||||
description = rest.join("\n");
|
||||
}
|
||||
return {
|
||||
title,
|
||||
description
|
||||
};
|
||||
}
|
||||
function parseComment(Governance, calldata) {
|
||||
try {
|
||||
const methodLength = 4;
|
||||
const result = abiCoder.decode(["address[]", "uint256", "bool"], ethers.dataSlice(calldata, methodLength));
|
||||
const data = Governance.interface.encodeFunctionData("castDelegatedVote", result);
|
||||
const length = ethers.dataLength(data);
|
||||
const str = abiCoder.decode(["string"], ethers.dataSlice(calldata, length))[0];
|
||||
const [contact, message] = JSON.parse(str);
|
||||
return {
|
||||
contact,
|
||||
message
|
||||
};
|
||||
} catch {
|
||||
return {
|
||||
contact: "",
|
||||
message: ""
|
||||
};
|
||||
}
|
||||
}
|
||||
class BaseGovernanceService extends BaseEventsService {
|
||||
Governance;
|
||||
Aggregator;
|
||||
ReverseRecords;
|
||||
batchTransactionService;
|
||||
constructor(serviceConstructor) {
|
||||
const { Governance: contract, provider } = serviceConstructor;
|
||||
const { Governance, Aggregator, ReverseRecords, provider } = serviceConstructor;
|
||||
super({
|
||||
...serviceConstructor,
|
||||
contract,
|
||||
contract: Governance,
|
||||
type: "*"
|
||||
});
|
||||
this.Governance = Governance;
|
||||
this.Aggregator = Aggregator;
|
||||
this.ReverseRecords = ReverseRecords;
|
||||
this.batchTransactionService = new BatchTransactionService({
|
||||
provider,
|
||||
onProgress: this.updateTransactionProgress
|
||||
@ -3259,6 +3335,84 @@ class BaseGovernanceService extends BaseEventsService {
|
||||
}
|
||||
return super.getEventsFromGraph({ fromBlock });
|
||||
}
|
||||
async getAllProposals() {
|
||||
const { events } = await this.updateEvents();
|
||||
const [QUORUM_VOTES, proposalStatus] = await Promise.all([
|
||||
this.Governance.QUORUM_VOTES(),
|
||||
this.Aggregator.getAllProposals(this.Governance.target)
|
||||
]);
|
||||
return events.filter((e) => e.event === "ProposalCreated").map(
|
||||
(event, index) => {
|
||||
const { id, description: text } = event;
|
||||
const status = proposalStatus[index];
|
||||
const { forVotes, againstVotes, executed, extended, state } = status;
|
||||
const { title, description } = parseDescription(id, text);
|
||||
const quorum = (Number(forVotes + againstVotes) / Number(QUORUM_VOTES) * 100).toFixed(0) + "%";
|
||||
return {
|
||||
...event,
|
||||
title,
|
||||
description,
|
||||
forVotes,
|
||||
againstVotes,
|
||||
executed,
|
||||
extended,
|
||||
quorum,
|
||||
state: proposalState[String(state)]
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
async getVotes(proposalId) {
|
||||
const { events } = await this.getSavedEvents();
|
||||
const votedEvents = events.filter(
|
||||
(e) => e.event === "Voted" && e.proposalId === proposalId
|
||||
);
|
||||
const votes = votedEvents.map((event) => {
|
||||
const { contact, message } = parseComment(this.Governance, event.input);
|
||||
return {
|
||||
...event,
|
||||
contact,
|
||||
message
|
||||
};
|
||||
});
|
||||
const allVoters = [...new Set(votedEvents.map((e) => [e.from, e.voter]).flat())];
|
||||
const names = await this.ReverseRecords.getNames(allVoters);
|
||||
const ensNames = allVoters.reduce(
|
||||
(acc, address, index) => {
|
||||
if (names[index]) {
|
||||
acc[address] = names[index];
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
return {
|
||||
votes,
|
||||
ensNames
|
||||
};
|
||||
}
|
||||
async getDelegatedBalance(ethAccount) {
|
||||
const { events } = await this.getSavedEvents();
|
||||
const delegatedAccs = events.filter((e) => e.event === "Delegated" && e.delegateTo === ethAccount).map((e) => e.account);
|
||||
const undelegatedAccs = events.filter((e) => e.event === "Undelegated" && e.delegateFrom === ethAccount).map((e) => e.account);
|
||||
const undel = [...undelegatedAccs];
|
||||
const uniq = delegatedAccs.filter((acc) => {
|
||||
const indexUndelegated = undel.indexOf(acc);
|
||||
if (indexUndelegated !== -1) {
|
||||
undel.splice(indexUndelegated, 1);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
const balances = await this.Aggregator.getGovernanceBalances(this.Governance.target, uniq);
|
||||
return {
|
||||
delegatedAccs,
|
||||
undelegatedAccs,
|
||||
uniq,
|
||||
balances,
|
||||
balance: balances.reduce((acc, curr) => acc + curr, BigInt(0))
|
||||
};
|
||||
}
|
||||
}
|
||||
async function getTovarishNetworks(registryService, relayers) {
|
||||
await Promise.all(
|
||||
@ -7412,6 +7566,7 @@ exports.pedersen = pedersen;
|
||||
exports.pickWeightedRandomRelayer = pickWeightedRandomRelayer;
|
||||
exports.populateTransaction = populateTransaction;
|
||||
exports.proofSchemaType = proofSchemaType;
|
||||
exports.proposalState = proposalState;
|
||||
exports.queryGraph = queryGraph;
|
||||
exports.rBigInt = rBigInt;
|
||||
exports.registeredEventsSchema = registeredEventsSchema;
|
||||
|
162
dist/index.mjs
vendored
162
dist/index.mjs
vendored
@ -1,4 +1,4 @@
|
||||
import { FetchRequest, JsonRpcProvider, Network, EnsPlugin, GasCostPlugin, Wallet, HDNodeWallet, VoidSigner, JsonRpcSigner, BrowserProvider, getAddress, isAddress, parseEther, namehash, formatEther, Interface, Contract, computeAddress, parseUnits, Transaction, ZeroAddress } from 'ethers';
|
||||
import { FetchRequest, JsonRpcProvider, Network, EnsPlugin, GasCostPlugin, Wallet, HDNodeWallet, VoidSigner, JsonRpcSigner, BrowserProvider, getAddress, isAddress, parseEther, AbiCoder, namehash, formatEther, dataSlice, dataLength, Interface, Contract, computeAddress, parseUnits, Transaction, ZeroAddress } from 'ethers';
|
||||
import crossFetch from 'cross-fetch';
|
||||
import { webcrypto } from 'crypto';
|
||||
import BN from 'bn.js';
|
||||
@ -3137,15 +3137,91 @@ class BaseEncryptedNotesService extends BaseEventsService {
|
||||
}).filter((e) => e);
|
||||
}
|
||||
}
|
||||
const abiCoder = AbiCoder.defaultAbiCoder();
|
||||
const proposalState = {
|
||||
0: "Pending",
|
||||
1: "Active",
|
||||
2: "Defeated",
|
||||
3: "Timelocked",
|
||||
4: "AwaitingExecution",
|
||||
5: "Executed",
|
||||
6: "Expired"
|
||||
};
|
||||
function parseDescription(id, text) {
|
||||
switch (id) {
|
||||
case 1:
|
||||
return {
|
||||
title: text,
|
||||
description: "See: https://torn.community/t/proposal-1-enable-torn-transfers/38"
|
||||
};
|
||||
case 10:
|
||||
text = text.replace("\n", "\\n\\n");
|
||||
break;
|
||||
case 11:
|
||||
text = text.replace('"description"', ',"description"');
|
||||
break;
|
||||
case 13:
|
||||
text = text.replace(/\\\\n\\\\n(\s)?(\\n)?/g, "\\n");
|
||||
break;
|
||||
case 15:
|
||||
text = text.replaceAll("'", '"');
|
||||
text = text.replace('"description"', ',"description"');
|
||||
break;
|
||||
case 16:
|
||||
text = text.replace("#16: ", "");
|
||||
break;
|
||||
case 21:
|
||||
return {
|
||||
title: "Proposal #21: Restore Governance",
|
||||
description: ""
|
||||
};
|
||||
}
|
||||
let title, description, rest;
|
||||
try {
|
||||
({ title, description } = JSON.parse(text));
|
||||
} catch {
|
||||
[title, ...rest] = text.split("\n", 2);
|
||||
description = rest.join("\n");
|
||||
}
|
||||
return {
|
||||
title,
|
||||
description
|
||||
};
|
||||
}
|
||||
function parseComment(Governance, calldata) {
|
||||
try {
|
||||
const methodLength = 4;
|
||||
const result = abiCoder.decode(["address[]", "uint256", "bool"], dataSlice(calldata, methodLength));
|
||||
const data = Governance.interface.encodeFunctionData("castDelegatedVote", result);
|
||||
const length = dataLength(data);
|
||||
const str = abiCoder.decode(["string"], dataSlice(calldata, length))[0];
|
||||
const [contact, message] = JSON.parse(str);
|
||||
return {
|
||||
contact,
|
||||
message
|
||||
};
|
||||
} catch {
|
||||
return {
|
||||
contact: "",
|
||||
message: ""
|
||||
};
|
||||
}
|
||||
}
|
||||
class BaseGovernanceService extends BaseEventsService {
|
||||
Governance;
|
||||
Aggregator;
|
||||
ReverseRecords;
|
||||
batchTransactionService;
|
||||
constructor(serviceConstructor) {
|
||||
const { Governance: contract, provider } = serviceConstructor;
|
||||
const { Governance, Aggregator, ReverseRecords, provider } = serviceConstructor;
|
||||
super({
|
||||
...serviceConstructor,
|
||||
contract,
|
||||
contract: Governance,
|
||||
type: "*"
|
||||
});
|
||||
this.Governance = Governance;
|
||||
this.Aggregator = Aggregator;
|
||||
this.ReverseRecords = ReverseRecords;
|
||||
this.batchTransactionService = new BatchTransactionService({
|
||||
provider,
|
||||
onProgress: this.updateTransactionProgress
|
||||
@ -3238,6 +3314,84 @@ class BaseGovernanceService extends BaseEventsService {
|
||||
}
|
||||
return super.getEventsFromGraph({ fromBlock });
|
||||
}
|
||||
async getAllProposals() {
|
||||
const { events } = await this.updateEvents();
|
||||
const [QUORUM_VOTES, proposalStatus] = await Promise.all([
|
||||
this.Governance.QUORUM_VOTES(),
|
||||
this.Aggregator.getAllProposals(this.Governance.target)
|
||||
]);
|
||||
return events.filter((e) => e.event === "ProposalCreated").map(
|
||||
(event, index) => {
|
||||
const { id, description: text } = event;
|
||||
const status = proposalStatus[index];
|
||||
const { forVotes, againstVotes, executed, extended, state } = status;
|
||||
const { title, description } = parseDescription(id, text);
|
||||
const quorum = (Number(forVotes + againstVotes) / Number(QUORUM_VOTES) * 100).toFixed(0) + "%";
|
||||
return {
|
||||
...event,
|
||||
title,
|
||||
description,
|
||||
forVotes,
|
||||
againstVotes,
|
||||
executed,
|
||||
extended,
|
||||
quorum,
|
||||
state: proposalState[String(state)]
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
async getVotes(proposalId) {
|
||||
const { events } = await this.getSavedEvents();
|
||||
const votedEvents = events.filter(
|
||||
(e) => e.event === "Voted" && e.proposalId === proposalId
|
||||
);
|
||||
const votes = votedEvents.map((event) => {
|
||||
const { contact, message } = parseComment(this.Governance, event.input);
|
||||
return {
|
||||
...event,
|
||||
contact,
|
||||
message
|
||||
};
|
||||
});
|
||||
const allVoters = [...new Set(votedEvents.map((e) => [e.from, e.voter]).flat())];
|
||||
const names = await this.ReverseRecords.getNames(allVoters);
|
||||
const ensNames = allVoters.reduce(
|
||||
(acc, address, index) => {
|
||||
if (names[index]) {
|
||||
acc[address] = names[index];
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
return {
|
||||
votes,
|
||||
ensNames
|
||||
};
|
||||
}
|
||||
async getDelegatedBalance(ethAccount) {
|
||||
const { events } = await this.getSavedEvents();
|
||||
const delegatedAccs = events.filter((e) => e.event === "Delegated" && e.delegateTo === ethAccount).map((e) => e.account);
|
||||
const undelegatedAccs = events.filter((e) => e.event === "Undelegated" && e.delegateFrom === ethAccount).map((e) => e.account);
|
||||
const undel = [...undelegatedAccs];
|
||||
const uniq = delegatedAccs.filter((acc) => {
|
||||
const indexUndelegated = undel.indexOf(acc);
|
||||
if (indexUndelegated !== -1) {
|
||||
undel.splice(indexUndelegated, 1);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
const balances = await this.Aggregator.getGovernanceBalances(this.Governance.target, uniq);
|
||||
return {
|
||||
delegatedAccs,
|
||||
undelegatedAccs,
|
||||
uniq,
|
||||
balances,
|
||||
balance: balances.reduce((acc, curr) => acc + curr, BigInt(0))
|
||||
};
|
||||
}
|
||||
}
|
||||
async function getTovarishNetworks(registryService, relayers) {
|
||||
await Promise.all(
|
||||
@ -7257,4 +7411,4 @@ async function calculateSnarkProof(input, circuit, provingKey) {
|
||||
return { proof, args };
|
||||
}
|
||||
|
||||
export { BaseEchoService, BaseEncryptedNotesService, BaseEventsService, BaseGovernanceService, BaseRegistryService, BaseTornadoService, BatchBlockService, BatchEventsService, BatchTransactionService, DBTornadoService, DEPOSIT, Deposit, ENS__factory, ERC20__factory, GET_DEPOSITS, GET_ECHO_EVENTS, GET_ENCRYPTED_NOTES, GET_GOVERNANCE_APY, GET_GOVERNANCE_EVENTS, GET_NOTE_ACCOUNTS, GET_REGISTERED, GET_STATISTIC, GET_WITHDRAWALS, INDEX_DB_ERROR, IndexedDB, Invoice, MAX_FEE, MAX_TOVARISH_EVENTS, MIN_FEE, MIN_STAKE_BALANCE, MerkleTreeService, Mimc, Multicall__factory, NetId, NoteAccount, OffchainOracle__factory, OvmGasPriceOracle__factory, Pedersen, RelayerClient, ReverseRecords__factory, TokenPriceOracle, TornadoBrowserProvider, TornadoFeeOracle, TornadoRpcSigner, TornadoVoidSigner, TornadoWallet, TovarishClient, WITHDRAWAL, _META, addNetwork, addressSchemaType, ajv, base64ToBytes, bigIntReplacer, bnSchemaType, bnToBytes, buffPedersenHash, bufferToBytes, bytes32BNSchemaType, bytes32SchemaType, bytesToBN, bytesToBase64, bytesToHex, calculateScore, calculateSnarkProof, chunk, concatBytes, convertETHToTokenAmount, createDeposit, crypto, customConfig, defaultConfig, defaultUserAgent, depositsEventsSchema, digest, downloadZip, echoEventsSchema, enabledChains, encryptedNotesSchema, index as factories, fetch, fetchData, fetchGetUrlFunc, gasZipID, gasZipInbounds, gasZipInput, gasZipMinMax, getActiveTokenInstances, getActiveTokens, getAllDeposits, getAllEncryptedNotes, getAllGovernanceEvents, getAllGraphEchoEvents, getAllRegisters, getAllWithdrawals, getConfig, getDeposits, getEncryptedNotes, getEventsSchemaValidator, getGovernanceEvents, getGraphEchoEvents, getHttpAgent, getIndexedDB, getInstanceByAddress, getMeta, getNetworkConfig, getNoteAccounts, getProvider, getProviderWithNetId, getRegisters, getRelayerEnsSubdomains, getStatistic, getStatusSchema, getSupportedInstances, getTokenBalances, getTovarishNetworks, getWeightRandom, getWithdrawals, governanceEventsSchema, hexToBytes, initGroth16, isNode, jobRequestSchema, jobsSchema, leBuff2Int, leInt2Buff, loadDBEvents, loadRemoteEvents, mimc, multicall, packEncryptedMessage, pedersen, pickWeightedRandomRelayer, populateTransaction, proofSchemaType, queryGraph, rBigInt, registeredEventsSchema, saveDBEvents, sleep, substring, toFixedHex, toFixedLength, unpackEncryptedMessage, unzipAsync, validateUrl, withdrawalsEventsSchema, zipAsync };
|
||||
export { BaseEchoService, BaseEncryptedNotesService, BaseEventsService, BaseGovernanceService, BaseRegistryService, BaseTornadoService, BatchBlockService, BatchEventsService, BatchTransactionService, DBTornadoService, DEPOSIT, Deposit, ENS__factory, ERC20__factory, GET_DEPOSITS, GET_ECHO_EVENTS, GET_ENCRYPTED_NOTES, GET_GOVERNANCE_APY, GET_GOVERNANCE_EVENTS, GET_NOTE_ACCOUNTS, GET_REGISTERED, GET_STATISTIC, GET_WITHDRAWALS, INDEX_DB_ERROR, IndexedDB, Invoice, MAX_FEE, MAX_TOVARISH_EVENTS, MIN_FEE, MIN_STAKE_BALANCE, MerkleTreeService, Mimc, Multicall__factory, NetId, NoteAccount, OffchainOracle__factory, OvmGasPriceOracle__factory, Pedersen, RelayerClient, ReverseRecords__factory, TokenPriceOracle, TornadoBrowserProvider, TornadoFeeOracle, TornadoRpcSigner, TornadoVoidSigner, TornadoWallet, TovarishClient, WITHDRAWAL, _META, addNetwork, addressSchemaType, ajv, base64ToBytes, bigIntReplacer, bnSchemaType, bnToBytes, buffPedersenHash, bufferToBytes, bytes32BNSchemaType, bytes32SchemaType, bytesToBN, bytesToBase64, bytesToHex, calculateScore, calculateSnarkProof, chunk, concatBytes, convertETHToTokenAmount, createDeposit, crypto, customConfig, defaultConfig, defaultUserAgent, depositsEventsSchema, digest, downloadZip, echoEventsSchema, enabledChains, encryptedNotesSchema, index as factories, fetch, fetchData, fetchGetUrlFunc, gasZipID, gasZipInbounds, gasZipInput, gasZipMinMax, getActiveTokenInstances, getActiveTokens, getAllDeposits, getAllEncryptedNotes, getAllGovernanceEvents, getAllGraphEchoEvents, getAllRegisters, getAllWithdrawals, getConfig, getDeposits, getEncryptedNotes, getEventsSchemaValidator, getGovernanceEvents, getGraphEchoEvents, getHttpAgent, getIndexedDB, getInstanceByAddress, getMeta, getNetworkConfig, getNoteAccounts, getProvider, getProviderWithNetId, getRegisters, getRelayerEnsSubdomains, getStatistic, getStatusSchema, getSupportedInstances, getTokenBalances, getTovarishNetworks, getWeightRandom, getWithdrawals, governanceEventsSchema, hexToBytes, initGroth16, isNode, jobRequestSchema, jobsSchema, leBuff2Int, leInt2Buff, loadDBEvents, loadRemoteEvents, mimc, multicall, packEncryptedMessage, pedersen, pickWeightedRandomRelayer, populateTransaction, proofSchemaType, proposalState, queryGraph, rBigInt, registeredEventsSchema, saveDBEvents, sleep, substring, toFixedHex, toFixedLength, unpackEncryptedMessage, unzipAsync, validateUrl, withdrawalsEventsSchema, zipAsync };
|
||||
|
170
dist/tornado.umd.js
vendored
170
dist/tornado.umd.js
vendored
@ -59057,11 +59057,14 @@ class NoteAccount {
|
||||
/* harmony export */ cE: () => (/* binding */ BaseRegistryService),
|
||||
/* harmony export */ e0: () => (/* binding */ BaseTornadoService),
|
||||
/* harmony export */ oW: () => (/* binding */ WITHDRAWAL),
|
||||
/* harmony export */ sf: () => (/* binding */ proposalState),
|
||||
/* harmony export */ uw: () => (/* binding */ BaseEventsService)
|
||||
/* harmony export */ });
|
||||
/* harmony import */ var ethers__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(30031);
|
||||
/* harmony import */ var ethers__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(64563);
|
||||
/* harmony import */ var ethers__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(99770);
|
||||
/* harmony import */ var ethers__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(35273);
|
||||
/* harmony import */ var ethers__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(36212);
|
||||
/* harmony import */ var ethers__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(64563);
|
||||
/* harmony import */ var ethers__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(99770);
|
||||
/* harmony import */ var _graphql__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(52049);
|
||||
/* harmony import */ var _batch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9723);
|
||||
/* harmony import */ var _providers__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(68434);
|
||||
@ -59471,15 +59474,91 @@ class BaseEncryptedNotesService extends BaseEventsService {
|
||||
}).filter((e) => e);
|
||||
}
|
||||
}
|
||||
const abiCoder = ethers__WEBPACK_IMPORTED_MODULE_6__/* .AbiCoder */ .y.defaultAbiCoder();
|
||||
const proposalState = {
|
||||
0: "Pending",
|
||||
1: "Active",
|
||||
2: "Defeated",
|
||||
3: "Timelocked",
|
||||
4: "AwaitingExecution",
|
||||
5: "Executed",
|
||||
6: "Expired"
|
||||
};
|
||||
function parseDescription(id, text) {
|
||||
switch (id) {
|
||||
case 1:
|
||||
return {
|
||||
title: text,
|
||||
description: "See: https://torn.community/t/proposal-1-enable-torn-transfers/38"
|
||||
};
|
||||
case 10:
|
||||
text = text.replace("\n", "\\n\\n");
|
||||
break;
|
||||
case 11:
|
||||
text = text.replace('"description"', ',"description"');
|
||||
break;
|
||||
case 13:
|
||||
text = text.replace(/\\\\n\\\\n(\s)?(\\n)?/g, "\\n");
|
||||
break;
|
||||
case 15:
|
||||
text = text.replaceAll("'", '"');
|
||||
text = text.replace('"description"', ',"description"');
|
||||
break;
|
||||
case 16:
|
||||
text = text.replace("#16: ", "");
|
||||
break;
|
||||
case 21:
|
||||
return {
|
||||
title: "Proposal #21: Restore Governance",
|
||||
description: ""
|
||||
};
|
||||
}
|
||||
let title, description, rest;
|
||||
try {
|
||||
({ title, description } = JSON.parse(text));
|
||||
} catch {
|
||||
[title, ...rest] = text.split("\n", 2);
|
||||
description = rest.join("\n");
|
||||
}
|
||||
return {
|
||||
title,
|
||||
description
|
||||
};
|
||||
}
|
||||
function parseComment(Governance, calldata) {
|
||||
try {
|
||||
const methodLength = 4;
|
||||
const result = abiCoder.decode(["address[]", "uint256", "bool"], (0,ethers__WEBPACK_IMPORTED_MODULE_7__/* .dataSlice */ .ZG)(calldata, methodLength));
|
||||
const data = Governance.interface.encodeFunctionData("castDelegatedVote", result);
|
||||
const length = (0,ethers__WEBPACK_IMPORTED_MODULE_7__/* .dataLength */ .pO)(data);
|
||||
const str = abiCoder.decode(["string"], (0,ethers__WEBPACK_IMPORTED_MODULE_7__/* .dataSlice */ .ZG)(calldata, length))[0];
|
||||
const [contact, message] = JSON.parse(str);
|
||||
return {
|
||||
contact,
|
||||
message
|
||||
};
|
||||
} catch {
|
||||
return {
|
||||
contact: "",
|
||||
message: ""
|
||||
};
|
||||
}
|
||||
}
|
||||
class BaseGovernanceService extends BaseEventsService {
|
||||
Governance;
|
||||
Aggregator;
|
||||
ReverseRecords;
|
||||
batchTransactionService;
|
||||
constructor(serviceConstructor) {
|
||||
const { Governance: contract, provider } = serviceConstructor;
|
||||
const { Governance, Aggregator, ReverseRecords, provider } = serviceConstructor;
|
||||
super({
|
||||
...serviceConstructor,
|
||||
contract,
|
||||
contract: Governance,
|
||||
type: "*"
|
||||
});
|
||||
this.Governance = Governance;
|
||||
this.Aggregator = Aggregator;
|
||||
this.ReverseRecords = ReverseRecords;
|
||||
this.batchTransactionService = new _batch__WEBPACK_IMPORTED_MODULE_1__/* .BatchTransactionService */ .AF({
|
||||
provider,
|
||||
onProgress: this.updateTransactionProgress
|
||||
@ -59572,6 +59651,84 @@ class BaseGovernanceService extends BaseEventsService {
|
||||
}
|
||||
return super.getEventsFromGraph({ fromBlock });
|
||||
}
|
||||
async getAllProposals() {
|
||||
const { events } = await this.updateEvents();
|
||||
const [QUORUM_VOTES, proposalStatus] = await Promise.all([
|
||||
this.Governance.QUORUM_VOTES(),
|
||||
this.Aggregator.getAllProposals(this.Governance.target)
|
||||
]);
|
||||
return events.filter((e) => e.event === "ProposalCreated").map(
|
||||
(event, index) => {
|
||||
const { id, description: text } = event;
|
||||
const status = proposalStatus[index];
|
||||
const { forVotes, againstVotes, executed, extended, state } = status;
|
||||
const { title, description } = parseDescription(id, text);
|
||||
const quorum = (Number(forVotes + againstVotes) / Number(QUORUM_VOTES) * 100).toFixed(0) + "%";
|
||||
return {
|
||||
...event,
|
||||
title,
|
||||
description,
|
||||
forVotes,
|
||||
againstVotes,
|
||||
executed,
|
||||
extended,
|
||||
quorum,
|
||||
state: proposalState[String(state)]
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
async getVotes(proposalId) {
|
||||
const { events } = await this.getSavedEvents();
|
||||
const votedEvents = events.filter(
|
||||
(e) => e.event === "Voted" && e.proposalId === proposalId
|
||||
);
|
||||
const votes = votedEvents.map((event) => {
|
||||
const { contact, message } = parseComment(this.Governance, event.input);
|
||||
return {
|
||||
...event,
|
||||
contact,
|
||||
message
|
||||
};
|
||||
});
|
||||
const allVoters = [...new Set(votedEvents.map((e) => [e.from, e.voter]).flat())];
|
||||
const names = await this.ReverseRecords.getNames(allVoters);
|
||||
const ensNames = allVoters.reduce(
|
||||
(acc, address, index) => {
|
||||
if (names[index]) {
|
||||
acc[address] = names[index];
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
return {
|
||||
votes,
|
||||
ensNames
|
||||
};
|
||||
}
|
||||
async getDelegatedBalance(ethAccount) {
|
||||
const { events } = await this.getSavedEvents();
|
||||
const delegatedAccs = events.filter((e) => e.event === "Delegated" && e.delegateTo === ethAccount).map((e) => e.account);
|
||||
const undelegatedAccs = events.filter((e) => e.event === "Undelegated" && e.delegateFrom === ethAccount).map((e) => e.account);
|
||||
const undel = [...undelegatedAccs];
|
||||
const uniq = delegatedAccs.filter((acc) => {
|
||||
const indexUndelegated = undel.indexOf(acc);
|
||||
if (indexUndelegated !== -1) {
|
||||
undel.splice(indexUndelegated, 1);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
const balances = await this.Aggregator.getGovernanceBalances(this.Governance.target, uniq);
|
||||
return {
|
||||
delegatedAccs,
|
||||
undelegatedAccs,
|
||||
uniq,
|
||||
balances,
|
||||
balance: balances.reduce((acc, curr) => acc + curr, BigInt(0))
|
||||
};
|
||||
}
|
||||
}
|
||||
async function getTovarishNetworks(registryService, relayers) {
|
||||
await Promise.all(
|
||||
@ -59678,7 +59835,7 @@ class BaseRegistryService extends BaseEventsService {
|
||||
}
|
||||
return false;
|
||||
});
|
||||
const relayerNameHashes = uniqueRegisters.map((r) => (0,ethers__WEBPACK_IMPORTED_MODULE_6__/* .namehash */ .kM)(r.ensName));
|
||||
const relayerNameHashes = uniqueRegisters.map((r) => (0,ethers__WEBPACK_IMPORTED_MODULE_8__/* .namehash */ .kM)(r.ensName));
|
||||
const [relayersData, timestamp] = await Promise.all([
|
||||
this.Aggregator.relayersData.staticCall(relayerNameHashes, subdomains.concat("tovarish-relayer")),
|
||||
this.provider.getBlock(lastBlock).then((b) => Number(b?.timestamp))
|
||||
@ -59705,7 +59862,7 @@ class BaseRegistryService extends BaseEventsService {
|
||||
relayerAddress,
|
||||
isRegistered,
|
||||
owner,
|
||||
stakeBalance: (0,ethers__WEBPACK_IMPORTED_MODULE_7__/* .formatEther */ .ck)(stakeBalance),
|
||||
stakeBalance: (0,ethers__WEBPACK_IMPORTED_MODULE_9__/* .formatEther */ .ck)(stakeBalance),
|
||||
hostnames,
|
||||
tovarishHost
|
||||
};
|
||||
@ -59900,6 +60057,7 @@ __webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ getTovarishNetworks: () => (/* reexport safe */ _base__WEBPACK_IMPORTED_MODULE_1__.EU),
|
||||
/* harmony export */ loadDBEvents: () => (/* reexport safe */ _db__WEBPACK_IMPORTED_MODULE_2__.w8),
|
||||
/* harmony export */ loadRemoteEvents: () => (/* reexport safe */ _db__WEBPACK_IMPORTED_MODULE_2__.Oz),
|
||||
/* harmony export */ proposalState: () => (/* reexport safe */ _base__WEBPACK_IMPORTED_MODULE_1__.sf),
|
||||
/* harmony export */ saveDBEvents: () => (/* reexport safe */ _db__WEBPACK_IMPORTED_MODULE_2__.Fb)
|
||||
/* harmony export */ });
|
||||
/* harmony import */ var _types__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(61060);
|
||||
|
2
dist/tornado.umd.min.js
vendored
2
dist/tornado.umd.min.js
vendored
File diff suppressed because one or more lines are too long
@ -8,6 +8,9 @@ import {
|
||||
ContractEventName,
|
||||
namehash,
|
||||
formatEther,
|
||||
AbiCoder,
|
||||
dataLength,
|
||||
dataSlice,
|
||||
} from 'ethers';
|
||||
|
||||
import type {
|
||||
@ -35,6 +38,7 @@ import { enabledChains, type NetIdType, type SubdomainMap } from '../networkConf
|
||||
import { RelayerParams, MIN_STAKE_BALANCE } from '../relayerClient';
|
||||
import type { TovarishClient } from '../tovarishClient';
|
||||
|
||||
import type { ReverseRecords } from '../typechain';
|
||||
import type {
|
||||
BaseEvents,
|
||||
CachedEvents,
|
||||
@ -597,22 +601,130 @@ export class BaseEncryptedNotesService extends BaseEventsService<EncryptedNotesE
|
||||
}
|
||||
}
|
||||
|
||||
const abiCoder = AbiCoder.defaultAbiCoder();
|
||||
|
||||
export const proposalState: { [key: string]: string } = {
|
||||
0: 'Pending',
|
||||
1: 'Active',
|
||||
2: 'Defeated',
|
||||
3: 'Timelocked',
|
||||
4: 'AwaitingExecution',
|
||||
5: 'Executed',
|
||||
6: 'Expired',
|
||||
};
|
||||
|
||||
function parseDescription(id: number, text: string): { title: string; description: string } {
|
||||
switch (id) {
|
||||
case 1:
|
||||
return {
|
||||
title: text,
|
||||
description: 'See: https://torn.community/t/proposal-1-enable-torn-transfers/38',
|
||||
};
|
||||
case 10:
|
||||
text = text.replace('\n', '\\n\\n');
|
||||
break;
|
||||
case 11:
|
||||
text = text.replace('"description"', ',"description"');
|
||||
break;
|
||||
case 13:
|
||||
text = text.replace(/\\\\n\\\\n(\s)?(\\n)?/g, '\\n');
|
||||
break;
|
||||
// Fix invalid JSON in proposal 15: replace single quotes with double and add comma before description
|
||||
case 15:
|
||||
// eslint-disable-next-line prettier/prettier
|
||||
text = text.replaceAll('\'', '"');
|
||||
text = text.replace('"description"', ',"description"');
|
||||
break;
|
||||
case 16:
|
||||
text = text.replace('#16: ', '');
|
||||
break;
|
||||
// Add title to empty (without title and description) hacker proposal 21
|
||||
case 21:
|
||||
return {
|
||||
title: 'Proposal #21: Restore Governance',
|
||||
description: '',
|
||||
};
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
let title: string, description: string, rest: any;
|
||||
try {
|
||||
({ title, description } = JSON.parse(text));
|
||||
} catch {
|
||||
[title, ...rest] = text.split('\n', 2);
|
||||
description = rest.join('\n');
|
||||
}
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
};
|
||||
}
|
||||
|
||||
function parseComment(Governance: Governance, calldata: string): { contact: string; message: string } {
|
||||
try {
|
||||
const methodLength = 4;
|
||||
const result = abiCoder.decode(['address[]', 'uint256', 'bool'], dataSlice(calldata, methodLength));
|
||||
// @ts-expect-error encodeFunctionData is broken lol
|
||||
const data = Governance.interface.encodeFunctionData('castDelegatedVote', result);
|
||||
const length = dataLength(data);
|
||||
|
||||
const str: string = abiCoder.decode(['string'], dataSlice(calldata, length))[0];
|
||||
const [contact, message] = JSON.parse(str) as string[];
|
||||
|
||||
return {
|
||||
contact,
|
||||
message,
|
||||
};
|
||||
} catch {
|
||||
return {
|
||||
contact: '',
|
||||
message: '',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface GovernanceProposals extends GovernanceProposalCreatedEvents {
|
||||
title: string;
|
||||
forVotes: bigint;
|
||||
againstVotes: bigint;
|
||||
executed: boolean;
|
||||
extended: boolean;
|
||||
quorum: string;
|
||||
state: string;
|
||||
}
|
||||
|
||||
export interface GovernanceVotes extends GovernanceVotedEvents {
|
||||
contact: string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface BaseGovernanceServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
|
||||
Governance: Governance;
|
||||
Aggregator: Aggregator;
|
||||
ReverseRecords: ReverseRecords;
|
||||
}
|
||||
|
||||
export class BaseGovernanceService extends BaseEventsService<AllGovernanceEvents> {
|
||||
Governance: Governance;
|
||||
Aggregator: Aggregator;
|
||||
ReverseRecords: ReverseRecords;
|
||||
|
||||
batchTransactionService: BatchTransactionService;
|
||||
|
||||
constructor(serviceConstructor: BaseGovernanceServiceConstructor) {
|
||||
const { Governance: contract, provider } = serviceConstructor;
|
||||
const { Governance, Aggregator, ReverseRecords, provider } = serviceConstructor;
|
||||
|
||||
super({
|
||||
...serviceConstructor,
|
||||
contract,
|
||||
contract: Governance,
|
||||
type: '*',
|
||||
});
|
||||
|
||||
this.Governance = Governance;
|
||||
this.Aggregator = Aggregator;
|
||||
this.ReverseRecords = ReverseRecords;
|
||||
|
||||
this.batchTransactionService = new BatchTransactionService({
|
||||
provider,
|
||||
onProgress: this.updateTransactionProgress,
|
||||
@ -729,6 +841,116 @@ export class BaseGovernanceService extends BaseEventsService<AllGovernanceEvents
|
||||
|
||||
return super.getEventsFromGraph({ fromBlock });
|
||||
}
|
||||
|
||||
async getAllProposals(): Promise<GovernanceProposals[]> {
|
||||
const { events } = await this.updateEvents();
|
||||
|
||||
const [QUORUM_VOTES, proposalStatus] = await Promise.all([
|
||||
this.Governance.QUORUM_VOTES(),
|
||||
this.Aggregator.getAllProposals(this.Governance.target),
|
||||
]);
|
||||
|
||||
return (events.filter((e) => e.event === 'ProposalCreated') as GovernanceProposalCreatedEvents[]).map(
|
||||
(event, index) => {
|
||||
const { id, description: text } = event;
|
||||
|
||||
const status = proposalStatus[index];
|
||||
|
||||
const { forVotes, againstVotes, executed, extended, state } = status;
|
||||
|
||||
const { title, description } = parseDescription(id, text);
|
||||
|
||||
const quorum = ((Number(forVotes + againstVotes) / Number(QUORUM_VOTES)) * 100).toFixed(0) + '%';
|
||||
|
||||
return {
|
||||
...event,
|
||||
title,
|
||||
description,
|
||||
forVotes,
|
||||
againstVotes,
|
||||
executed,
|
||||
extended,
|
||||
quorum,
|
||||
state: proposalState[String(state)],
|
||||
};
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
async getVotes(proposalId: number): Promise<{
|
||||
votes: GovernanceVotes[];
|
||||
ensNames: {
|
||||
[key: string]: string;
|
||||
};
|
||||
}> {
|
||||
const { events } = await this.getSavedEvents();
|
||||
|
||||
const votedEvents = events.filter(
|
||||
(e) => e.event === 'Voted' && (e as GovernanceVotedEvents).proposalId === proposalId,
|
||||
) as GovernanceVotedEvents[];
|
||||
|
||||
const votes = votedEvents.map((event) => {
|
||||
const { contact, message } = parseComment(this.Governance, event.input);
|
||||
|
||||
return {
|
||||
...event,
|
||||
contact,
|
||||
message,
|
||||
};
|
||||
});
|
||||
|
||||
const allVoters = [...new Set(votedEvents.map((e) => [e.from, e.voter]).flat())];
|
||||
|
||||
const names = await this.ReverseRecords.getNames(allVoters);
|
||||
|
||||
const ensNames = allVoters.reduce(
|
||||
(acc, address, index) => {
|
||||
if (names[index]) {
|
||||
acc[address] = names[index];
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{} as { [key: string]: string },
|
||||
);
|
||||
|
||||
return {
|
||||
votes,
|
||||
ensNames,
|
||||
};
|
||||
}
|
||||
|
||||
async getDelegatedBalance(ethAccount: string) {
|
||||
const { events } = await this.getSavedEvents();
|
||||
|
||||
const delegatedAccs = events
|
||||
.filter((e) => e.event === 'Delegated' && (e as GovernanceDelegatedEvents).delegateTo === ethAccount)
|
||||
.map((e) => (e as GovernanceDelegatedEvents).account);
|
||||
|
||||
const undelegatedAccs = events
|
||||
.filter((e) => e.event === 'Undelegated' && (e as GovernanceUndelegatedEvents).delegateFrom === ethAccount)
|
||||
.map((e) => (e as GovernanceUndelegatedEvents).account);
|
||||
|
||||
const undel = [...undelegatedAccs];
|
||||
|
||||
const uniq = delegatedAccs.filter((acc) => {
|
||||
const indexUndelegated = undel.indexOf(acc);
|
||||
if (indexUndelegated !== -1) {
|
||||
undel.splice(indexUndelegated, 1);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
const balances = await this.Aggregator.getGovernanceBalances(this.Governance.target, uniq);
|
||||
|
||||
return {
|
||||
delegatedAccs,
|
||||
undelegatedAccs,
|
||||
uniq,
|
||||
balances,
|
||||
balance: balances.reduce((acc, curr) => acc + curr, BigInt(0)),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function getTovarishNetworks(registryService: BaseRegistryService, relayers: CachedRelayerInfo[]) {
|
||||
|
Loading…
Reference in New Issue
Block a user