Compare commits

...

1 Commits

Author SHA1 Message Date
f411159f15 Use 4 tab size and remove unused event constructor params 2024-11-01 00:30:14 +00:00
48 changed files with 7613 additions and 7187 deletions

View File

@@ -1,66 +1,44 @@
module.exports = {
"env": {
"es2021": true,
"node": true
env: {
es2021: true,
node: true,
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:import/recommended",
"plugin:import/typescript",
"prettier",
"plugin:prettier/recommended",
extends: [
'prettier',
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:import/recommended',
'plugin:import/typescript',
'plugin:prettier/recommended',
],
"overrides": [
overrides: [
{
"env": {
"node": true
env: {
node: true,
},
files: ['.eslintrc.{js,cjs}'],
parserOptions: {
sourceType: 'script',
},
"files": [
".eslintrc.{js,cjs}"
],
"parserOptions": {
"sourceType": "script"
}
}
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [
"@typescript-eslint",
"prettier"
],
"rules": {
"prettier/prettier": [
"error",
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
plugins: ['@typescript-eslint', 'prettier'],
rules: {
'prettier/prettier': [
'error',
{
tabWidth: 4,
printWidth: 120,
singleQuote: true,
printWidth: 120
}
},
],
"import/order": ["error"],
/**
"indent": [
"error",
2
],
**/
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
],
"@typescript-eslint/no-unused-vars": ["warn"],
"@typescript-eslint/no-unused-expressions": ["off"]
}
}
'import/order': ['error'],
'@typescript-eslint/no-unused-vars': ['warn'],
'@typescript-eslint/no-unused-expressions': ['off'],
},
};

View File

@@ -1,7 +1,6 @@
import { EthEncryptedData } from '@metamask/eth-sig-util';
import { Signer, Wallet } from 'ethers';
import { EchoEvents, EncryptedNotesEvents } from './events';
import type { NetIdType } from './networkConfig';
export interface NoteToEncrypt {
address: string;
noteHex: string;
@@ -16,17 +15,15 @@ export declare function unpackEncryptedMessage(encryptedMessage: string): EthEnc
messageBuff: string;
};
export interface NoteAccountConstructor {
netId: NetIdType;
blockNumber?: number;
recoveryKey?: string;
}
export declare class NoteAccount {
netId: NetIdType;
blockNumber?: number;
recoveryKey: string;
recoveryAddress: string;
recoveryPublicKey: string;
constructor({ netId, blockNumber, recoveryKey }: NoteAccountConstructor);
constructor({ blockNumber, recoveryKey }: NoteAccountConstructor);
/**
* Intends to mock eth_getEncryptionPublicKey behavior from MetaMask
* In order to make the recoveryKey retrival from Echoer possible from the bare private key
@@ -39,7 +36,7 @@ export declare class NoteAccount {
/**
* Decrypt Echoer backuped note encryption account with private keys
*/
decryptSignerNoteAccounts(signer: Signer | Wallet, events: EchoEvents[]): Promise<NoteAccount[]>;
static decryptSignerNoteAccounts(signer: Signer | Wallet, events: EchoEvents[]): Promise<NoteAccount[]>;
decryptNotes(events: EncryptedNotesEvents[]): DecryptedNotes[];
encryptNote({ address, noteHex }: NoteToEncrypt): string;
}

View File

@@ -120,7 +120,7 @@ export declare class BaseTornadoService extends BaseEventsService<DepositsEvents
validateEvents<S>({ events, hasNewEvents, }: BaseEvents<DepositsEvents | WithdrawalsEvents> & {
hasNewEvents?: boolean;
}): Promise<S>;
getLatestEvents({ fromBlock }: {
getLatestEvents({ fromBlock, }: {
fromBlock: number;
}): Promise<BaseEvents<DepositsEvents | WithdrawalsEvents>>;
}

174
dist/index.js vendored
View File

@@ -778,7 +778,12 @@ async function getAllRegisters({
// eslint-disable-next-line prefer-const
block: { number: currentBlock }
}
} = await getRegisters({ graphApi, subgraphName, fromBlock, fetchDataOptions: fetchDataOptions2 });
} = await getRegisters({
graphApi,
subgraphName,
fromBlock,
fetchDataOptions: fetchDataOptions2
});
lastSyncBlock = currentBlock;
if (isEmptyArray(result2)) {
break;
@@ -867,7 +872,14 @@ async function getAllDeposits({
// eslint-disable-next-line prefer-const
block: { number: currentBlock }
}
} = await getDeposits({ graphApi, subgraphName, currency, amount, fromBlock, fetchDataOptions: fetchDataOptions2 });
} = await getDeposits({
graphApi,
subgraphName,
currency,
amount,
fromBlock,
fetchDataOptions: fetchDataOptions2
});
lastSyncBlock = currentBlock;
if (isEmptyArray(result2)) {
break;
@@ -962,7 +974,14 @@ async function getAllWithdrawals({
// eslint-disable-next-line prefer-const
block: { number: currentBlock }
}
} = await getWithdrawals({ graphApi, subgraphName, currency, amount, fromBlock, fetchDataOptions: fetchDataOptions2 });
} = await getWithdrawals({
graphApi,
subgraphName,
currency,
amount,
fromBlock,
fetchDataOptions: fetchDataOptions2
});
lastSyncBlock = currentBlock;
if (isEmptyArray(result2)) {
break;
@@ -1085,7 +1104,12 @@ async function getAllGraphEchoEvents({
// eslint-disable-next-line prefer-const
block: { number: currentBlock }
}
} = await getGraphEchoEvents({ graphApi, subgraphName, fromBlock, fetchDataOptions: fetchDataOptions2 });
} = await getGraphEchoEvents({
graphApi,
subgraphName,
fromBlock,
fetchDataOptions: fetchDataOptions2
});
lastSyncBlock = currentBlock;
if (isEmptyArray(result2)) {
break;
@@ -1172,7 +1196,12 @@ async function getAllEncryptedNotes({
// eslint-disable-next-line prefer-const
block: { number: currentBlock }
}
} = await getEncryptedNotes({ graphApi, subgraphName, fromBlock, fetchDataOptions: fetchDataOptions2 });
} = await getEncryptedNotes({
graphApi,
subgraphName,
fromBlock,
fetchDataOptions: fetchDataOptions2
});
lastSyncBlock = currentBlock;
if (isEmptyArray(result2)) {
break;
@@ -1257,14 +1286,29 @@ async function getAllGovernanceEvents({
_meta: {
block: { number: currentBlock }
}
} = await getGovernanceEvents({ graphApi, subgraphName, fromBlock, fetchDataOptions: fetchDataOptions2 });
} = await getGovernanceEvents({
graphApi,
subgraphName,
fromBlock,
fetchDataOptions: fetchDataOptions2
});
lastSyncBlock = currentBlock;
const eventsLength = proposals.length + votes.length + delegates.length + undelegates.length;
if (eventsLength === 0) {
break;
}
const formattedProposals = proposals.map(
({ blockNumber, logIndex, transactionHash, proposalId, proposer, target, startTime, endTime, description }) => {
({
blockNumber,
logIndex,
transactionHash,
proposalId,
proposer,
target,
startTime,
endTime,
description
}) => {
return {
blockNumber: Number(blockNumber),
logIndex: Number(logIndex),
@@ -1526,7 +1570,11 @@ class BatchTransactionService {
results.push(...chunksResult);
txCount += chunks.length;
if (typeof this.onProgress === "function") {
this.onProgress({ percentage: txCount / txs.length, currentIndex: txCount, totalIndex: txs.length });
this.onProgress({
percentage: txCount / txs.length,
currentIndex: txCount,
totalIndex: txs.length
});
}
}
return results;
@@ -2265,8 +2313,14 @@ const addressSchemaType = {
isAddress: true
};
const bnSchemaType = { type: "string", BN: true };
const proofSchemaType = { type: "string", pattern: "^0x[a-fA-F0-9]{512}$" };
const bytes32SchemaType = { type: "string", pattern: "^0x[a-fA-F0-9]{64}$" };
const proofSchemaType = {
type: "string",
pattern: "^0x[a-fA-F0-9]{512}$"
};
const bytes32SchemaType = {
type: "string",
pattern: "^0x[a-fA-F0-9]{64}$"
};
const bytes32BNSchemaType = { ...bytes32SchemaType, BN: true };
const baseEventsSchemaProperty = {
@@ -2319,7 +2373,16 @@ const governanceEventsSchema = {
from: addressSchemaType,
input: { type: "string" }
},
required: [...baseEventsSchemaRequired, "event", "proposalId", "voter", "support", "votes", "from", "input"],
required: [
...baseEventsSchemaRequired,
"event",
"proposalId",
"voter",
"support",
"votes",
"from",
"input"
],
additionalProperties: false
},
{
@@ -2488,10 +2551,13 @@ function getStatusSchema(netId, config, tovarish) {
properties: {
instanceAddress: {
type: "object",
properties: amounts.reduce((acc2, cur) => {
properties: amounts.reduce(
(acc2, cur) => {
acc2[cur] = addressSchemaType;
return acc2;
}, {}),
},
{}
),
required: amounts.filter((amount) => !optionalInstances.includes(amount))
},
decimals: { enum: [decimals] }
@@ -2664,7 +2730,10 @@ class RelayerClient {
return;
}
try {
const status = await this.askRelayerStatus({ hostname, relayerAddress });
const status = await this.askRelayerStatus({
hostname,
relayerAddress
});
return {
netId: status.netId,
url: status.url,
@@ -2690,7 +2759,8 @@ class RelayerClient {
}
async getValidRelayers(relayers) {
const invalidRelayers = [];
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(relayer)))).filter((r) => {
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(relayer)))).filter(
(r) => {
if (!r) {
return false;
}
@@ -2699,7 +2769,8 @@ class RelayerClient {
return false;
}
return true;
});
}
);
return {
validRelayers,
invalidRelayers
@@ -2918,7 +2989,11 @@ class BaseEventsService {
}
this.updateEventProgress({ percentage: 0, type: this.getType() });
const events = await this.formatEvents(
await this.batchEventsService.getBatchEvents({ fromBlock, toBlock, type: this.getType() })
await this.batchEventsService.getBatchEvents({
fromBlock,
toBlock,
type: this.getType()
})
);
return {
events,
@@ -2945,7 +3020,9 @@ class BaseEventsService {
}
const graphEvents = await this.getEventsFromGraph({ fromBlock });
const lastSyncBlock = graphEvents.lastBlock && graphEvents.lastBlock >= fromBlock ? graphEvents.lastBlock : fromBlock;
const rpcEvents = await this.getEventsFromRpc({ fromBlock: lastSyncBlock });
const rpcEvents = await this.getEventsFromRpc({
fromBlock: lastSyncBlock
});
return {
events: [...graphEvents.events, ...rpcEvents.events],
lastBlock: rpcEvents.lastBlock
@@ -3111,7 +3188,9 @@ class BaseTornadoService extends BaseEventsService {
}
return void 0;
}
async getLatestEvents({ fromBlock }) {
async getLatestEvents({
fromBlock
}) {
if (this.tovarishClient?.selectedRelayer) {
const { events, lastSyncBlock: lastBlock } = await this.tovarishClient.getEvents({
type: this.getTovarishType(),
@@ -3257,7 +3336,11 @@ 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 data = Governance.interface.encodeFunctionData(
// @ts-expect-error encodeFunctionData is broken lol
"castDelegatedVote",
result
);
const length = ethers.dataLength(data);
const str = abiCoder.decode(["string"], ethers.dataSlice(calldata, length))[0];
const [contact, message] = JSON.parse(str);
@@ -3746,7 +3829,9 @@ async function loadDBEvents({
lastBlock: 0
};
}
const events = (await idb.getAll({ storeName: instanceName })).map((e) => {
const events = (await idb.getAll({
storeName: instanceName
})).map((e) => {
delete e.eid;
return e;
});
@@ -9373,7 +9458,10 @@ class Deposit {
const bytes = bnToBytes(parsedNoteHex);
const nullifier = BigInt(leBuff2Int(bytes.slice(0, 31)).toString());
const secret = BigInt(leBuff2Int(bytes.slice(31, 62)).toString());
const { noteHex, commitmentHex, nullifierHex } = await createDeposit({ nullifier, secret });
const { noteHex, commitmentHex, nullifierHex } = await createDeposit({
nullifier,
secret
});
const invoice = `tornadoInvoice-${currency}-${amount}-${netId}-${commitmentHex}`;
const newDeposit = new Deposit({
currency,
@@ -9444,7 +9532,6 @@ function unpackEncryptedMessage(encryptedMessage) {
};
}
class NoteAccount {
netId;
blockNumber;
// Dedicated 32 bytes private key only used for note encryption, backed up to an Echoer and local for future derivation
// Note that unlike the private key it shouldn't have the 0x prefix
@@ -9453,11 +9540,10 @@ class NoteAccount {
recoveryAddress;
// Note encryption public key derived from recoveryKey
recoveryPublicKey;
constructor({ netId, blockNumber, recoveryKey }) {
constructor({ blockNumber, recoveryKey }) {
if (!recoveryKey) {
recoveryKey = rHex(32).slice(2);
}
this.netId = Math.floor(Number(netId));
this.blockNumber = blockNumber;
this.recoveryKey = recoveryKey;
this.recoveryAddress = ethers.computeAddress("0x" + recoveryKey);
@@ -9500,7 +9586,7 @@ class NoteAccount {
/**
* Decrypt Echoer backuped note encryption account with private keys
*/
async decryptSignerNoteAccounts(signer, events) {
static async decryptSignerNoteAccounts(signer, events) {
const signerAddress = signer.address;
const decryptedEvents = [];
for (const event of events) {
@@ -9534,7 +9620,6 @@ class NoteAccount {
}
decryptedEvents.push(
new NoteAccount({
netId: this.netId,
blockNumber: event.blockNumber,
recoveryKey
})
@@ -10570,7 +10655,9 @@ class TokenPriceOracle {
const price = await this.oracle.getRateToEth(tokenAddress, true);
return price * BigInt(10 ** decimals) / BigInt(10 ** 18);
} catch (err) {
console.log(`Failed to fetch oracle price for ${tokenAddress}, will use fallback price ${this.fallbackPrice}`);
console.log(
`Failed to fetch oracle price for ${tokenAddress}, will use fallback price ${this.fallbackPrice}`
);
console.log(err);
return this.fallbackPrice;
}
@@ -10670,7 +10757,11 @@ class TovarishClient extends RelayerClient {
url,
relayerAddress
}) {
const status = await super.askRelayerStatus({ hostname, url, relayerAddress });
const status = await super.askRelayerStatus({
hostname,
url,
relayerAddress
});
if (!status.version.includes("tovarish")) {
throw new Error("Not a tovarish relayer!");
}
@@ -10706,7 +10797,14 @@ class TovarishClient extends RelayerClient {
for (const rawStatus of statusArray) {
const netId = rawStatus.netId;
const config = getConfig(netId);
const statusValidator = ajv.compile(getStatusSchema(rawStatus.netId, config, this.tovarish));
const statusValidator = ajv.compile(
getStatusSchema(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
rawStatus.netId,
config,
this.tovarish
)
);
if (!statusValidator) {
continue;
}
@@ -10737,7 +10835,10 @@ class TovarishClient extends RelayerClient {
}
const hostname = `${tovarishHost}/${this.netId}`;
try {
const status = await this.askRelayerStatus({ hostname, relayerAddress });
const status = await this.askRelayerStatus({
hostname,
relayerAddress
});
return {
netId: status.netId,
url: status.url,
@@ -10769,7 +10870,8 @@ class TovarishClient extends RelayerClient {
}
async getValidRelayers(relayers) {
const invalidRelayers = [];
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(relayer)))).filter((r) => {
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(relayer)))).filter(
(r) => {
if (!r) {
return false;
}
@@ -10778,7 +10880,8 @@ class TovarishClient extends RelayerClient {
return false;
}
return true;
});
}
);
return {
validRelayers,
invalidRelayers
@@ -10791,7 +10894,10 @@ class TovarishClient extends RelayerClient {
relayers.filter((r) => r.tovarishHost && r.tovarishNetworks?.length).map(async (relayer) => {
const { ensName, relayerAddress, tovarishHost } = relayer;
try {
const statusArray = await this.askAllStatus({ hostname: tovarishHost, relayerAddress });
const statusArray = await this.askAllStatus({
hostname: tovarishHost,
relayerAddress
});
for (const status of statusArray) {
validRelayers.push({
netId: status.netId,

174
dist/index.mjs vendored
View File

@@ -757,7 +757,12 @@ async function getAllRegisters({
// eslint-disable-next-line prefer-const
block: { number: currentBlock }
}
} = await getRegisters({ graphApi, subgraphName, fromBlock, fetchDataOptions: fetchDataOptions2 });
} = await getRegisters({
graphApi,
subgraphName,
fromBlock,
fetchDataOptions: fetchDataOptions2
});
lastSyncBlock = currentBlock;
if (isEmptyArray(result2)) {
break;
@@ -846,7 +851,14 @@ async function getAllDeposits({
// eslint-disable-next-line prefer-const
block: { number: currentBlock }
}
} = await getDeposits({ graphApi, subgraphName, currency, amount, fromBlock, fetchDataOptions: fetchDataOptions2 });
} = await getDeposits({
graphApi,
subgraphName,
currency,
amount,
fromBlock,
fetchDataOptions: fetchDataOptions2
});
lastSyncBlock = currentBlock;
if (isEmptyArray(result2)) {
break;
@@ -941,7 +953,14 @@ async function getAllWithdrawals({
// eslint-disable-next-line prefer-const
block: { number: currentBlock }
}
} = await getWithdrawals({ graphApi, subgraphName, currency, amount, fromBlock, fetchDataOptions: fetchDataOptions2 });
} = await getWithdrawals({
graphApi,
subgraphName,
currency,
amount,
fromBlock,
fetchDataOptions: fetchDataOptions2
});
lastSyncBlock = currentBlock;
if (isEmptyArray(result2)) {
break;
@@ -1064,7 +1083,12 @@ async function getAllGraphEchoEvents({
// eslint-disable-next-line prefer-const
block: { number: currentBlock }
}
} = await getGraphEchoEvents({ graphApi, subgraphName, fromBlock, fetchDataOptions: fetchDataOptions2 });
} = await getGraphEchoEvents({
graphApi,
subgraphName,
fromBlock,
fetchDataOptions: fetchDataOptions2
});
lastSyncBlock = currentBlock;
if (isEmptyArray(result2)) {
break;
@@ -1151,7 +1175,12 @@ async function getAllEncryptedNotes({
// eslint-disable-next-line prefer-const
block: { number: currentBlock }
}
} = await getEncryptedNotes({ graphApi, subgraphName, fromBlock, fetchDataOptions: fetchDataOptions2 });
} = await getEncryptedNotes({
graphApi,
subgraphName,
fromBlock,
fetchDataOptions: fetchDataOptions2
});
lastSyncBlock = currentBlock;
if (isEmptyArray(result2)) {
break;
@@ -1236,14 +1265,29 @@ async function getAllGovernanceEvents({
_meta: {
block: { number: currentBlock }
}
} = await getGovernanceEvents({ graphApi, subgraphName, fromBlock, fetchDataOptions: fetchDataOptions2 });
} = await getGovernanceEvents({
graphApi,
subgraphName,
fromBlock,
fetchDataOptions: fetchDataOptions2
});
lastSyncBlock = currentBlock;
const eventsLength = proposals.length + votes.length + delegates.length + undelegates.length;
if (eventsLength === 0) {
break;
}
const formattedProposals = proposals.map(
({ blockNumber, logIndex, transactionHash, proposalId, proposer, target, startTime, endTime, description }) => {
({
blockNumber,
logIndex,
transactionHash,
proposalId,
proposer,
target,
startTime,
endTime,
description
}) => {
return {
blockNumber: Number(blockNumber),
logIndex: Number(logIndex),
@@ -1505,7 +1549,11 @@ class BatchTransactionService {
results.push(...chunksResult);
txCount += chunks.length;
if (typeof this.onProgress === "function") {
this.onProgress({ percentage: txCount / txs.length, currentIndex: txCount, totalIndex: txs.length });
this.onProgress({
percentage: txCount / txs.length,
currentIndex: txCount,
totalIndex: txs.length
});
}
}
return results;
@@ -2244,8 +2292,14 @@ const addressSchemaType = {
isAddress: true
};
const bnSchemaType = { type: "string", BN: true };
const proofSchemaType = { type: "string", pattern: "^0x[a-fA-F0-9]{512}$" };
const bytes32SchemaType = { type: "string", pattern: "^0x[a-fA-F0-9]{64}$" };
const proofSchemaType = {
type: "string",
pattern: "^0x[a-fA-F0-9]{512}$"
};
const bytes32SchemaType = {
type: "string",
pattern: "^0x[a-fA-F0-9]{64}$"
};
const bytes32BNSchemaType = { ...bytes32SchemaType, BN: true };
const baseEventsSchemaProperty = {
@@ -2298,7 +2352,16 @@ const governanceEventsSchema = {
from: addressSchemaType,
input: { type: "string" }
},
required: [...baseEventsSchemaRequired, "event", "proposalId", "voter", "support", "votes", "from", "input"],
required: [
...baseEventsSchemaRequired,
"event",
"proposalId",
"voter",
"support",
"votes",
"from",
"input"
],
additionalProperties: false
},
{
@@ -2467,10 +2530,13 @@ function getStatusSchema(netId, config, tovarish) {
properties: {
instanceAddress: {
type: "object",
properties: amounts.reduce((acc2, cur) => {
properties: amounts.reduce(
(acc2, cur) => {
acc2[cur] = addressSchemaType;
return acc2;
}, {}),
},
{}
),
required: amounts.filter((amount) => !optionalInstances.includes(amount))
},
decimals: { enum: [decimals] }
@@ -2643,7 +2709,10 @@ class RelayerClient {
return;
}
try {
const status = await this.askRelayerStatus({ hostname, relayerAddress });
const status = await this.askRelayerStatus({
hostname,
relayerAddress
});
return {
netId: status.netId,
url: status.url,
@@ -2669,7 +2738,8 @@ class RelayerClient {
}
async getValidRelayers(relayers) {
const invalidRelayers = [];
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(relayer)))).filter((r) => {
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(relayer)))).filter(
(r) => {
if (!r) {
return false;
}
@@ -2678,7 +2748,8 @@ class RelayerClient {
return false;
}
return true;
});
}
);
return {
validRelayers,
invalidRelayers
@@ -2897,7 +2968,11 @@ class BaseEventsService {
}
this.updateEventProgress({ percentage: 0, type: this.getType() });
const events = await this.formatEvents(
await this.batchEventsService.getBatchEvents({ fromBlock, toBlock, type: this.getType() })
await this.batchEventsService.getBatchEvents({
fromBlock,
toBlock,
type: this.getType()
})
);
return {
events,
@@ -2924,7 +2999,9 @@ class BaseEventsService {
}
const graphEvents = await this.getEventsFromGraph({ fromBlock });
const lastSyncBlock = graphEvents.lastBlock && graphEvents.lastBlock >= fromBlock ? graphEvents.lastBlock : fromBlock;
const rpcEvents = await this.getEventsFromRpc({ fromBlock: lastSyncBlock });
const rpcEvents = await this.getEventsFromRpc({
fromBlock: lastSyncBlock
});
return {
events: [...graphEvents.events, ...rpcEvents.events],
lastBlock: rpcEvents.lastBlock
@@ -3090,7 +3167,9 @@ class BaseTornadoService extends BaseEventsService {
}
return void 0;
}
async getLatestEvents({ fromBlock }) {
async getLatestEvents({
fromBlock
}) {
if (this.tovarishClient?.selectedRelayer) {
const { events, lastSyncBlock: lastBlock } = await this.tovarishClient.getEvents({
type: this.getTovarishType(),
@@ -3236,7 +3315,11 @@ 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 data = Governance.interface.encodeFunctionData(
// @ts-expect-error encodeFunctionData is broken lol
"castDelegatedVote",
result
);
const length = dataLength(data);
const str = abiCoder.decode(["string"], dataSlice(calldata, length))[0];
const [contact, message] = JSON.parse(str);
@@ -3725,7 +3808,9 @@ async function loadDBEvents({
lastBlock: 0
};
}
const events = (await idb.getAll({ storeName: instanceName })).map((e) => {
const events = (await idb.getAll({
storeName: instanceName
})).map((e) => {
delete e.eid;
return e;
});
@@ -9352,7 +9437,10 @@ class Deposit {
const bytes = bnToBytes(parsedNoteHex);
const nullifier = BigInt(leBuff2Int(bytes.slice(0, 31)).toString());
const secret = BigInt(leBuff2Int(bytes.slice(31, 62)).toString());
const { noteHex, commitmentHex, nullifierHex } = await createDeposit({ nullifier, secret });
const { noteHex, commitmentHex, nullifierHex } = await createDeposit({
nullifier,
secret
});
const invoice = `tornadoInvoice-${currency}-${amount}-${netId}-${commitmentHex}`;
const newDeposit = new Deposit({
currency,
@@ -9423,7 +9511,6 @@ function unpackEncryptedMessage(encryptedMessage) {
};
}
class NoteAccount {
netId;
blockNumber;
// Dedicated 32 bytes private key only used for note encryption, backed up to an Echoer and local for future derivation
// Note that unlike the private key it shouldn't have the 0x prefix
@@ -9432,11 +9519,10 @@ class NoteAccount {
recoveryAddress;
// Note encryption public key derived from recoveryKey
recoveryPublicKey;
constructor({ netId, blockNumber, recoveryKey }) {
constructor({ blockNumber, recoveryKey }) {
if (!recoveryKey) {
recoveryKey = rHex(32).slice(2);
}
this.netId = Math.floor(Number(netId));
this.blockNumber = blockNumber;
this.recoveryKey = recoveryKey;
this.recoveryAddress = computeAddress("0x" + recoveryKey);
@@ -9479,7 +9565,7 @@ class NoteAccount {
/**
* Decrypt Echoer backuped note encryption account with private keys
*/
async decryptSignerNoteAccounts(signer, events) {
static async decryptSignerNoteAccounts(signer, events) {
const signerAddress = signer.address;
const decryptedEvents = [];
for (const event of events) {
@@ -9513,7 +9599,6 @@ class NoteAccount {
}
decryptedEvents.push(
new NoteAccount({
netId: this.netId,
blockNumber: event.blockNumber,
recoveryKey
})
@@ -10549,7 +10634,9 @@ class TokenPriceOracle {
const price = await this.oracle.getRateToEth(tokenAddress, true);
return price * BigInt(10 ** decimals) / BigInt(10 ** 18);
} catch (err) {
console.log(`Failed to fetch oracle price for ${tokenAddress}, will use fallback price ${this.fallbackPrice}`);
console.log(
`Failed to fetch oracle price for ${tokenAddress}, will use fallback price ${this.fallbackPrice}`
);
console.log(err);
return this.fallbackPrice;
}
@@ -10649,7 +10736,11 @@ class TovarishClient extends RelayerClient {
url,
relayerAddress
}) {
const status = await super.askRelayerStatus({ hostname, url, relayerAddress });
const status = await super.askRelayerStatus({
hostname,
url,
relayerAddress
});
if (!status.version.includes("tovarish")) {
throw new Error("Not a tovarish relayer!");
}
@@ -10685,7 +10776,14 @@ class TovarishClient extends RelayerClient {
for (const rawStatus of statusArray) {
const netId = rawStatus.netId;
const config = getConfig(netId);
const statusValidator = ajv.compile(getStatusSchema(rawStatus.netId, config, this.tovarish));
const statusValidator = ajv.compile(
getStatusSchema(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
rawStatus.netId,
config,
this.tovarish
)
);
if (!statusValidator) {
continue;
}
@@ -10716,7 +10814,10 @@ class TovarishClient extends RelayerClient {
}
const hostname = `${tovarishHost}/${this.netId}`;
try {
const status = await this.askRelayerStatus({ hostname, relayerAddress });
const status = await this.askRelayerStatus({
hostname,
relayerAddress
});
return {
netId: status.netId,
url: status.url,
@@ -10748,7 +10849,8 @@ class TovarishClient extends RelayerClient {
}
async getValidRelayers(relayers) {
const invalidRelayers = [];
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(relayer)))).filter((r) => {
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(relayer)))).filter(
(r) => {
if (!r) {
return false;
}
@@ -10757,7 +10859,8 @@ class TovarishClient extends RelayerClient {
return false;
}
return true;
});
}
);
return {
validRelayers,
invalidRelayers
@@ -10770,7 +10873,10 @@ class TovarishClient extends RelayerClient {
relayers.filter((r) => r.tovarishHost && r.tovarishNetworks?.length).map(async (relayer) => {
const { ensName, relayerAddress, tovarishHost } = relayer;
try {
const statusArray = await this.askAllStatus({ hostname: tovarishHost, relayerAddress });
const statusArray = await this.askAllStatus({
hostname: tovarishHost,
relayerAddress
});
for (const status of statusArray) {
validRelayers.push({
netId: status.netId,

174
dist/tornado.umd.js vendored
View File

@@ -58681,7 +58681,11 @@ class BatchTransactionService {
results.push(...chunksResult);
txCount += chunks.length;
if (typeof this.onProgress === "function") {
this.onProgress({ percentage: txCount / txs.length, currentIndex: txCount, totalIndex: txs.length });
this.onProgress({
percentage: txCount / txs.length,
currentIndex: txCount,
totalIndex: txs.length
});
}
}
return results;
@@ -58920,7 +58924,10 @@ class Deposit {
const bytes = (0,_utils__WEBPACK_IMPORTED_MODULE_0__/* .bnToBytes */ .jm)(parsedNoteHex);
const nullifier = BigInt((0,_utils__WEBPACK_IMPORTED_MODULE_0__/* .leBuff2Int */ .ae)(bytes.slice(0, 31)).toString());
const secret = BigInt((0,_utils__WEBPACK_IMPORTED_MODULE_0__/* .leBuff2Int */ .ae)(bytes.slice(31, 62)).toString());
const { noteHex, commitmentHex, nullifierHex } = await createDeposit({ nullifier, secret });
const { noteHex, commitmentHex, nullifierHex } = await createDeposit({
nullifier,
secret
});
const invoice = `tornadoInvoice-${currency}-${amount}-${netId}-${commitmentHex}`;
const newDeposit = new Deposit({
currency,
@@ -59012,7 +59019,6 @@ function unpackEncryptedMessage(encryptedMessage) {
};
}
class NoteAccount {
netId;
blockNumber;
// Dedicated 32 bytes private key only used for note encryption, backed up to an Echoer and local for future derivation
// Note that unlike the private key it shouldn't have the 0x prefix
@@ -59021,11 +59027,10 @@ class NoteAccount {
recoveryAddress;
// Note encryption public key derived from recoveryKey
recoveryPublicKey;
constructor({ netId, blockNumber, recoveryKey }) {
constructor({ blockNumber, recoveryKey }) {
if (!recoveryKey) {
recoveryKey = (0,_utils__WEBPACK_IMPORTED_MODULE_1__/* .rHex */ .G9)(32).slice(2);
}
this.netId = Math.floor(Number(netId));
this.blockNumber = blockNumber;
this.recoveryKey = recoveryKey;
this.recoveryAddress = (0,ethers__WEBPACK_IMPORTED_MODULE_2__/* .computeAddress */ .K)("0x" + recoveryKey);
@@ -59068,7 +59073,7 @@ class NoteAccount {
/**
* Decrypt Echoer backuped note encryption account with private keys
*/
async decryptSignerNoteAccounts(signer, events) {
static async decryptSignerNoteAccounts(signer, events) {
const signerAddress = signer.address;
const decryptedEvents = [];
for (const event of events) {
@@ -59102,7 +59107,6 @@ class NoteAccount {
}
decryptedEvents.push(
new NoteAccount({
netId: this.netId,
blockNumber: event.blockNumber,
recoveryKey
})
@@ -59435,7 +59439,11 @@ class BaseEventsService {
}
this.updateEventProgress({ percentage: 0, type: this.getType() });
const events = await this.formatEvents(
await this.batchEventsService.getBatchEvents({ fromBlock, toBlock, type: this.getType() })
await this.batchEventsService.getBatchEvents({
fromBlock,
toBlock,
type: this.getType()
})
);
return {
events,
@@ -59462,7 +59470,9 @@ class BaseEventsService {
}
const graphEvents = await this.getEventsFromGraph({ fromBlock });
const lastSyncBlock = graphEvents.lastBlock && graphEvents.lastBlock >= fromBlock ? graphEvents.lastBlock : fromBlock;
const rpcEvents = await this.getEventsFromRpc({ fromBlock: lastSyncBlock });
const rpcEvents = await this.getEventsFromRpc({
fromBlock: lastSyncBlock
});
return {
events: [...graphEvents.events, ...rpcEvents.events],
lastBlock: rpcEvents.lastBlock
@@ -59628,7 +59638,9 @@ class BaseTornadoService extends BaseEventsService {
}
return void 0;
}
async getLatestEvents({ fromBlock }) {
async getLatestEvents({
fromBlock
}) {
if (this.tovarishClient?.selectedRelayer) {
const { events, lastSyncBlock: lastBlock } = await this.tovarishClient.getEvents({
type: this.getTovarishType(),
@@ -59774,7 +59786,11 @@ 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 data = Governance.interface.encodeFunctionData(
// @ts-expect-error encodeFunctionData is broken lol
"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);
@@ -60236,7 +60252,9 @@ async function loadDBEvents({
lastBlock: 0
};
}
const events = (await idb.getAll({ storeName: instanceName })).map((e) => {
const events = (await idb.getAll({
storeName: instanceName
})).map((e) => {
delete e.eid;
return e;
});
@@ -61051,7 +61069,12 @@ async function getAllRegisters({
// eslint-disable-next-line prefer-const
block: { number: currentBlock }
}
} = await getRegisters({ graphApi, subgraphName, fromBlock, fetchDataOptions: fetchDataOptions2 });
} = await getRegisters({
graphApi,
subgraphName,
fromBlock,
fetchDataOptions: fetchDataOptions2
});
lastSyncBlock = currentBlock;
if (isEmptyArray(result2)) {
break;
@@ -61140,7 +61163,14 @@ async function getAllDeposits({
// eslint-disable-next-line prefer-const
block: { number: currentBlock }
}
} = await getDeposits({ graphApi, subgraphName, currency, amount, fromBlock, fetchDataOptions: fetchDataOptions2 });
} = await getDeposits({
graphApi,
subgraphName,
currency,
amount,
fromBlock,
fetchDataOptions: fetchDataOptions2
});
lastSyncBlock = currentBlock;
if (isEmptyArray(result2)) {
break;
@@ -61235,7 +61265,14 @@ async function getAllWithdrawals({
// eslint-disable-next-line prefer-const
block: { number: currentBlock }
}
} = await getWithdrawals({ graphApi, subgraphName, currency, amount, fromBlock, fetchDataOptions: fetchDataOptions2 });
} = await getWithdrawals({
graphApi,
subgraphName,
currency,
amount,
fromBlock,
fetchDataOptions: fetchDataOptions2
});
lastSyncBlock = currentBlock;
if (isEmptyArray(result2)) {
break;
@@ -61358,7 +61395,12 @@ async function getAllGraphEchoEvents({
// eslint-disable-next-line prefer-const
block: { number: currentBlock }
}
} = await getGraphEchoEvents({ graphApi, subgraphName, fromBlock, fetchDataOptions: fetchDataOptions2 });
} = await getGraphEchoEvents({
graphApi,
subgraphName,
fromBlock,
fetchDataOptions: fetchDataOptions2
});
lastSyncBlock = currentBlock;
if (isEmptyArray(result2)) {
break;
@@ -61445,7 +61487,12 @@ async function getAllEncryptedNotes({
// eslint-disable-next-line prefer-const
block: { number: currentBlock }
}
} = await getEncryptedNotes({ graphApi, subgraphName, fromBlock, fetchDataOptions: fetchDataOptions2 });
} = await getEncryptedNotes({
graphApi,
subgraphName,
fromBlock,
fetchDataOptions: fetchDataOptions2
});
lastSyncBlock = currentBlock;
if (isEmptyArray(result2)) {
break;
@@ -61530,14 +61577,29 @@ async function getAllGovernanceEvents({
_meta: {
block: { number: currentBlock }
}
} = await getGovernanceEvents({ graphApi, subgraphName, fromBlock, fetchDataOptions: fetchDataOptions2 });
} = await getGovernanceEvents({
graphApi,
subgraphName,
fromBlock,
fetchDataOptions: fetchDataOptions2
});
lastSyncBlock = currentBlock;
const eventsLength = proposals.length + votes.length + delegates.length + undelegates.length;
if (eventsLength === 0) {
break;
}
const formattedProposals = proposals.map(
({ blockNumber, logIndex, transactionHash, proposalId, proposer, target, startTime, endTime, description }) => {
({
blockNumber,
logIndex,
transactionHash,
proposalId,
proposer,
target,
startTime,
endTime,
description
}) => {
return {
blockNumber: Number(blockNumber),
logIndex: Number(logIndex),
@@ -63661,7 +63723,9 @@ class TokenPriceOracle {
const price = await this.oracle.getRateToEth(tokenAddress, true);
return price * BigInt(10 ** decimals) / BigInt(10 ** 18);
} catch (err) {
console.log(`Failed to fetch oracle price for ${tokenAddress}, will use fallback price ${this.fallbackPrice}`);
console.log(
`Failed to fetch oracle price for ${tokenAddress}, will use fallback price ${this.fallbackPrice}`
);
console.log(err);
return this.fallbackPrice;
}
@@ -71151,7 +71215,10 @@ class RelayerClient {
return;
}
try {
const status = await this.askRelayerStatus({ hostname, relayerAddress });
const status = await this.askRelayerStatus({
hostname,
relayerAddress
});
return {
netId: status.netId,
url: status.url,
@@ -71177,7 +71244,8 @@ class RelayerClient {
}
async getValidRelayers(relayers) {
const invalidRelayers = [];
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(relayer)))).filter((r) => {
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(relayer)))).filter(
(r) => {
if (!r) {
return false;
}
@@ -71186,7 +71254,8 @@ class RelayerClient {
return false;
}
return true;
});
}
);
return {
validRelayers,
invalidRelayers
@@ -71343,8 +71412,14 @@ const addressSchemaType = {
isAddress: true
};
const bnSchemaType = { type: "string", BN: true };
const proofSchemaType = { type: "string", pattern: "^0x[a-fA-F0-9]{512}$" };
const bytes32SchemaType = { type: "string", pattern: "^0x[a-fA-F0-9]{64}$" };
const proofSchemaType = {
type: "string",
pattern: "^0x[a-fA-F0-9]{512}$"
};
const bytes32SchemaType = {
type: "string",
pattern: "^0x[a-fA-F0-9]{64}$"
};
const bytes32BNSchemaType = { ...bytes32SchemaType, BN: true };
;// ./src/schemas/events.ts
@@ -71402,7 +71477,16 @@ const governanceEventsSchema = {
from: addressSchemaType,
input: { type: "string" }
},
required: [...baseEventsSchemaRequired, "event", "proposalId", "voter", "support", "votes", "from", "input"],
required: [
...baseEventsSchemaRequired,
"event",
"proposalId",
"voter",
"support",
"votes",
"from",
"input"
],
additionalProperties: false
},
{
@@ -71577,10 +71661,13 @@ function getStatusSchema(netId, config, tovarish) {
properties: {
instanceAddress: {
type: "object",
properties: amounts.reduce((acc2, cur) => {
properties: amounts.reduce(
(acc2, cur) => {
acc2[cur] = addressSchemaType;
return acc2;
}, {}),
},
{}
),
required: amounts.filter((amount) => !optionalInstances.includes(amount))
},
decimals: { enum: [decimals] }
@@ -71781,7 +71868,11 @@ class TovarishClient extends _relayerClient__WEBPACK_IMPORTED_MODULE_0__/* .Rela
url,
relayerAddress
}) {
const status = await super.askRelayerStatus({ hostname, url, relayerAddress });
const status = await super.askRelayerStatus({
hostname,
url,
relayerAddress
});
if (!status.version.includes("tovarish")) {
throw new Error("Not a tovarish relayer!");
}
@@ -71817,7 +71908,14 @@ class TovarishClient extends _relayerClient__WEBPACK_IMPORTED_MODULE_0__/* .Rela
for (const rawStatus of statusArray) {
const netId = rawStatus.netId;
const config = (0,_networkConfig__WEBPACK_IMPORTED_MODULE_3__/* .getConfig */ .zj)(netId);
const statusValidator = _schemas__WEBPACK_IMPORTED_MODULE_2__/* .ajv */ .SS.compile((0,_schemas__WEBPACK_IMPORTED_MODULE_2__/* .getStatusSchema */ .c_)(rawStatus.netId, config, this.tovarish));
const statusValidator = _schemas__WEBPACK_IMPORTED_MODULE_2__/* .ajv */ .SS.compile(
(0,_schemas__WEBPACK_IMPORTED_MODULE_2__/* .getStatusSchema */ .c_)(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
rawStatus.netId,
config,
this.tovarish
)
);
if (!statusValidator) {
continue;
}
@@ -71848,7 +71946,10 @@ class TovarishClient extends _relayerClient__WEBPACK_IMPORTED_MODULE_0__/* .Rela
}
const hostname = `${tovarishHost}/${this.netId}`;
try {
const status = await this.askRelayerStatus({ hostname, relayerAddress });
const status = await this.askRelayerStatus({
hostname,
relayerAddress
});
return {
netId: status.netId,
url: status.url,
@@ -71880,7 +71981,8 @@ class TovarishClient extends _relayerClient__WEBPACK_IMPORTED_MODULE_0__/* .Rela
}
async getValidRelayers(relayers) {
const invalidRelayers = [];
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(relayer)))).filter((r) => {
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(relayer)))).filter(
(r) => {
if (!r) {
return false;
}
@@ -71889,7 +71991,8 @@ class TovarishClient extends _relayerClient__WEBPACK_IMPORTED_MODULE_0__/* .Rela
return false;
}
return true;
});
}
);
return {
validRelayers,
invalidRelayers
@@ -71902,7 +72005,10 @@ class TovarishClient extends _relayerClient__WEBPACK_IMPORTED_MODULE_0__/* .Rela
relayers.filter((r) => r.tovarishHost && r.tovarishNetworks?.length).map(async (relayer) => {
const { ensName, relayerAddress, tovarishHost } = relayer;
try {
const statusArray = await this.askAllStatus({ hostname: tovarishHost, relayerAddress });
const statusArray = await this.askAllStatus({
hostname: tovarishHost,
relayerAddress
});
for (const status of statusArray) {
validRelayers.push({
netId: status.netId,

File diff suppressed because one or more lines are too long

View File

@@ -191,7 +191,11 @@ export class BatchTransactionService {
txCount += chunks.length;
if (typeof this.onProgress === 'function') {
this.onProgress({ percentage: txCount / txs.length, currentIndex: txCount, totalIndex: txs.length });
this.onProgress({
percentage: txCount / txs.length,
currentIndex: txCount,
totalIndex: txs.length,
});
}
}

View File

@@ -208,7 +208,10 @@ export class Deposit {
const nullifier = BigInt(leBuff2Int(bytes.slice(0, 31)).toString());
const secret = BigInt(leBuff2Int(bytes.slice(31, 62)).toString());
const { noteHex, commitmentHex, nullifierHex } = await createDeposit({ nullifier, secret });
const { noteHex, commitmentHex, nullifierHex } = await createDeposit({
nullifier,
secret,
});
const invoice = `tornadoInvoice-${currency}-${amount}-${netId}-${commitmentHex}`;

View File

@@ -2,7 +2,6 @@ import { getEncryptionPublicKey, encrypt, decrypt, EthEncryptedData } from '@met
import { JsonRpcApiProvider, Signer, Wallet, computeAddress, getAddress } from 'ethers';
import { base64ToBytes, bytesToBase64, bytesToHex, hexToBytes, toFixedHex, concatBytes, rHex } from './utils';
import { EchoEvents, EncryptedNotesEvents } from './events';
import type { NetIdType } from './networkConfig';
export interface NoteToEncrypt {
address: string;
@@ -43,14 +42,12 @@ export function unpackEncryptedMessage(encryptedMessage: string) {
}
export interface NoteAccountConstructor {
netId: NetIdType;
blockNumber?: number;
// hex
recoveryKey?: string;
}
export class NoteAccount {
netId: NetIdType;
blockNumber?: number;
// Dedicated 32 bytes private key only used for note encryption, backed up to an Echoer and local for future derivation
// Note that unlike the private key it shouldn't have the 0x prefix
@@ -60,12 +57,11 @@ export class NoteAccount {
// Note encryption public key derived from recoveryKey
recoveryPublicKey: string;
constructor({ netId, blockNumber, recoveryKey }: NoteAccountConstructor) {
constructor({ blockNumber, recoveryKey }: NoteAccountConstructor) {
if (!recoveryKey) {
recoveryKey = rHex(32).slice(2);
}
this.netId = Math.floor(Number(netId));
this.blockNumber = blockNumber;
this.recoveryKey = recoveryKey;
this.recoveryAddress = computeAddress('0x' + recoveryKey);
@@ -117,7 +113,7 @@ export class NoteAccount {
/**
* Decrypt Echoer backuped note encryption account with private keys
*/
async decryptSignerNoteAccounts(signer: Signer | Wallet, events: EchoEvents[]): Promise<NoteAccount[]> {
static async decryptSignerNoteAccounts(signer: Signer | Wallet, events: EchoEvents[]): Promise<NoteAccount[]> {
const signerAddress = (signer as (Signer & { address: string }) | Wallet).address;
const decryptedEvents = [];
@@ -134,7 +130,8 @@ export class NoteAccount {
if ((signer as Wallet).privateKey) {
const wallet = signer as Wallet;
const privateKey = wallet.privateKey.slice(0, 2) === '0x' ? wallet.privateKey.slice(2) : wallet.privateKey;
const privateKey =
wallet.privateKey.slice(0, 2) === '0x' ? wallet.privateKey.slice(2) : wallet.privateKey;
recoveryKey = decrypt({
encryptedData: unpackedMessage,
@@ -161,7 +158,6 @@ export class NoteAccount {
decryptedEvents.push(
new NoteAccount({
netId: this.netId,
blockNumber: event.blockNumber,
recoveryKey,
}),

View File

@@ -256,7 +256,11 @@ export class BaseEventsService<EventType extends MinimalEvents> {
this.updateEventProgress({ percentage: 0, type: this.getType() });
const events = await this.formatEvents(
await this.batchEventsService.getBatchEvents({ fromBlock, toBlock, type: this.getType() }),
await this.batchEventsService.getBatchEvents({
fromBlock,
toBlock,
type: this.getType(),
}),
);
return {
@@ -288,7 +292,9 @@ export class BaseEventsService<EventType extends MinimalEvents> {
const graphEvents = await this.getEventsFromGraph({ fromBlock });
const lastSyncBlock =
graphEvents.lastBlock && graphEvents.lastBlock >= fromBlock ? graphEvents.lastBlock : fromBlock;
const rpcEvents = await this.getEventsFromRpc({ fromBlock: lastSyncBlock });
const rpcEvents = await this.getEventsFromRpc({
fromBlock: lastSyncBlock,
});
return {
events: [...graphEvents.events, ...rpcEvents.events],
lastBlock: rpcEvents.lastBlock,
@@ -490,7 +496,9 @@ export class BaseTornadoService extends BaseEventsService<DepositsEvents | Withd
async validateEvents<S>({
events,
hasNewEvents,
}: BaseEvents<DepositsEvents | WithdrawalsEvents> & { hasNewEvents?: boolean }) {
}: BaseEvents<DepositsEvents | WithdrawalsEvents> & {
hasNewEvents?: boolean;
}) {
if (events.length && this.getType().toLowerCase() === DEPOSIT) {
const depositEvents = events as DepositsEvents[];
@@ -509,7 +517,11 @@ export class BaseTornadoService extends BaseEventsService<DepositsEvents | Withd
return undefined as S;
}
async getLatestEvents({ fromBlock }: { fromBlock: number }): Promise<BaseEvents<DepositsEvents | WithdrawalsEvents>> {
async getLatestEvents({
fromBlock,
}: {
fromBlock: number;
}): Promise<BaseEvents<DepositsEvents | WithdrawalsEvents>> {
if (this.tovarishClient?.selectedRelayer) {
const { events, lastSyncBlock: lastBlock } = await this.tovarishClient.getEvents<
DepositsEvents | WithdrawalsEvents
@@ -697,8 +709,11 @@ function parseComment(Governance: Governance, calldata: string): { contact: stri
try {
const methodLength = 4;
const result = abiCoder.decode(['address[]', 'uint256', 'bool'], dataSlice(calldata, methodLength));
const data = Governance.interface.encodeFunctionData(
// @ts-expect-error encodeFunctionData is broken lol
const data = Governance.interface.encodeFunctionData('castDelegatedVote', result);
'castDelegatedVote',
result,
);
const length = dataLength(data);
const str: string = abiCoder.decode(['string'], dataSlice(calldata, length))[0];

View File

@@ -71,7 +71,10 @@ export async function loadDBEvents<T extends MinimalEvents>({
instanceName: string;
}): Promise<BaseEvents<T>> {
try {
const lastBlockStore = await idb.getItem<{ blockNumber: number; name: string }>({
const lastBlockStore = await idb.getItem<{
blockNumber: number;
name: string;
}>({
storeName: 'lastEvents',
key: instanceName,
});
@@ -83,7 +86,11 @@ export async function loadDBEvents<T extends MinimalEvents>({
};
}
const events = (await idb.getAll<(T & { eid?: string })[]>({ storeName: instanceName })).map((e) => {
const events = (
await idb.getAll<(T & { eid?: string })[]>({
storeName: instanceName,
})
).map((e) => {
delete e.eid;
return e;
});

View File

@@ -146,7 +146,8 @@ export async function getStatistic({
return {
events,
lastSyncBlock: lastEvent && lastEvent.blockNumber >= lastSyncBlock ? lastEvent.blockNumber + 1 : lastSyncBlock,
lastSyncBlock:
lastEvent && lastEvent.blockNumber >= lastSyncBlock ? lastEvent.blockNumber + 1 : lastSyncBlock,
};
} catch (err) {
console.log('Error from getStatistic query');
@@ -266,7 +267,12 @@ export async function getAllRegisters({
// eslint-disable-next-line prefer-const
block: { number: currentBlock },
},
} = await getRegisters({ graphApi, subgraphName, fromBlock, fetchDataOptions });
} = await getRegisters({
graphApi,
subgraphName,
fromBlock,
fetchDataOptions,
});
lastSyncBlock = currentBlock;
@@ -397,7 +403,14 @@ export async function getAllDeposits({
// eslint-disable-next-line prefer-const
block: { number: currentBlock },
},
} = await getDeposits({ graphApi, subgraphName, currency, amount, fromBlock, fetchDataOptions });
} = await getDeposits({
graphApi,
subgraphName,
currency,
amount,
fromBlock,
fetchDataOptions,
});
lastSyncBlock = currentBlock;
@@ -453,7 +466,8 @@ export async function getAllDeposits({
return {
events: result,
lastSyncBlock: lastEvent && lastEvent.blockNumber >= lastSyncBlock ? lastEvent.blockNumber + 1 : lastSyncBlock,
lastSyncBlock:
lastEvent && lastEvent.blockNumber >= lastSyncBlock ? lastEvent.blockNumber + 1 : lastSyncBlock,
};
} catch (err) {
console.log('Error from getAllDeposits query');
@@ -535,7 +549,14 @@ export async function getAllWithdrawals({
// eslint-disable-next-line prefer-const
block: { number: currentBlock },
},
} = await getWithdrawals({ graphApi, subgraphName, currency, amount, fromBlock, fetchDataOptions });
} = await getWithdrawals({
graphApi,
subgraphName,
currency,
amount,
fromBlock,
fetchDataOptions,
});
lastSyncBlock = currentBlock;
@@ -591,7 +612,8 @@ export async function getAllWithdrawals({
return {
events: result,
lastSyncBlock: lastEvent && lastEvent.blockNumber >= lastSyncBlock ? lastEvent.blockNumber + 1 : lastSyncBlock,
lastSyncBlock:
lastEvent && lastEvent.blockNumber >= lastSyncBlock ? lastEvent.blockNumber + 1 : lastSyncBlock,
};
} catch (err) {
console.log('Error from getAllWithdrawals query');
@@ -731,7 +753,12 @@ export async function getAllGraphEchoEvents({
// eslint-disable-next-line prefer-const
block: { number: currentBlock },
},
} = await getGraphEchoEvents({ graphApi, subgraphName, fromBlock, fetchDataOptions });
} = await getGraphEchoEvents({
graphApi,
subgraphName,
fromBlock,
fetchDataOptions,
});
lastSyncBlock = currentBlock;
@@ -785,7 +812,8 @@ export async function getAllGraphEchoEvents({
return {
events: result,
lastSyncBlock: lastEvent && lastEvent.blockNumber >= lastSyncBlock ? lastEvent.blockNumber + 1 : lastSyncBlock,
lastSyncBlock:
lastEvent && lastEvent.blockNumber >= lastSyncBlock ? lastEvent.blockNumber + 1 : lastSyncBlock,
};
} catch (err) {
console.log('Error from getAllGraphEchoEvents query');
@@ -857,7 +885,12 @@ export async function getAllEncryptedNotes({
// eslint-disable-next-line prefer-const
block: { number: currentBlock },
},
} = await getEncryptedNotes({ graphApi, subgraphName, fromBlock, fetchDataOptions });
} = await getEncryptedNotes({
graphApi,
subgraphName,
fromBlock,
fetchDataOptions,
});
lastSyncBlock = currentBlock;
@@ -906,7 +939,8 @@ export async function getAllEncryptedNotes({
return {
events: result,
lastSyncBlock: lastEvent && lastEvent.blockNumber >= lastSyncBlock ? lastEvent.blockNumber + 1 : lastSyncBlock,
lastSyncBlock:
lastEvent && lastEvent.blockNumber >= lastSyncBlock ? lastEvent.blockNumber + 1 : lastSyncBlock,
};
} catch (err) {
console.log('Error from getAllEncryptedNotes query');
@@ -1011,7 +1045,12 @@ export async function getAllGovernanceEvents({
_meta: {
block: { number: currentBlock },
},
} = await getGovernanceEvents({ graphApi, subgraphName, fromBlock, fetchDataOptions });
} = await getGovernanceEvents({
graphApi,
subgraphName,
fromBlock,
fetchDataOptions,
});
lastSyncBlock = currentBlock;
@@ -1022,7 +1061,17 @@ export async function getAllGovernanceEvents({
}
const formattedProposals: GovernanceProposalCreatedEvents[] = proposals.map(
({ blockNumber, logIndex, transactionHash, proposalId, proposer, target, startTime, endTime, description }) => {
({
blockNumber,
logIndex,
transactionHash,
proposalId,
proposer,
target,
startTime,
endTime,
description,
}) => {
return {
blockNumber: Number(blockNumber),
logIndex: Number(logIndex),
@@ -1126,7 +1175,8 @@ export async function getAllGovernanceEvents({
return {
events: result,
lastSyncBlock: lastEvent && lastEvent.blockNumber >= lastSyncBlock ? lastEvent.blockNumber + 1 : lastSyncBlock,
lastSyncBlock:
lastEvent && lastEvent.blockNumber >= lastSyncBlock ? lastEvent.blockNumber + 1 : lastSyncBlock,
};
} catch (err) {
console.log('Error from getAllGovernance query');

View File

@@ -58,7 +58,9 @@ export class TokenPriceOracle {
return (price * BigInt(10 ** decimals)) / BigInt(10 ** 18);
} catch (err) {
console.log(`Failed to fetch oracle price for ${tokenAddress}, will use fallback price ${this.fallbackPrice}`);
console.log(
`Failed to fetch oracle price for ${tokenAddress}, will use fallback price ${this.fallbackPrice}`,
);
console.log(err);
return this.fallbackPrice;
}

View File

@@ -262,7 +262,10 @@ export class RelayerClient {
}
try {
const status = await this.askRelayerStatus({ hostname, relayerAddress });
const status = await this.askRelayerStatus({
hostname,
relayerAddress,
});
return {
netId: status.netId,
@@ -295,7 +298,8 @@ export class RelayerClient {
}> {
const invalidRelayers: RelayerError[] = [];
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(relayer)))).filter((r) => {
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(relayer)))).filter(
(r) => {
if (!r) {
return false;
}
@@ -304,7 +308,8 @@ export class RelayerClient {
return false;
}
return true;
}) as RelayerInfo[];
},
) as RelayerInfo[];
return {
validRelayers,

View File

@@ -54,7 +54,16 @@ export const governanceEventsSchema = {
from: addressSchemaType,
input: { type: 'string' },
},
required: [...baseEventsSchemaRequired, 'event', 'proposalId', 'voter', 'support', 'votes', 'from', 'input'],
required: [
...baseEventsSchemaRequired,
'event',
'proposalId',
'voter',
'support',
'votes',
'from',
'input',
],
additionalProperties: false,
},
{

View File

@@ -148,10 +148,18 @@ export function getStatusSchema(netId: NetIdType, config: Config, tovarish: bool
properties: {
instanceAddress: {
type: 'object',
properties: amounts.reduce((acc: { [key in string]: typeof addressSchemaType }, cur) => {
properties: amounts.reduce(
(
acc: {
[key in string]: typeof addressSchemaType;
},
cur,
) => {
acc[cur] = addressSchemaType;
return acc;
}, {}),
},
{},
),
required: amounts.filter((amount) => !optionalInstances.includes(amount)),
},
decimals: { enum: [decimals] },

View File

@@ -4,6 +4,12 @@ export const addressSchemaType = {
isAddress: true,
} as const;
export const bnSchemaType = { type: 'string', BN: true } as const;
export const proofSchemaType = { type: 'string', pattern: '^0x[a-fA-F0-9]{512}$' } as const;
export const bytes32SchemaType = { type: 'string', pattern: '^0x[a-fA-F0-9]{64}$' } as const;
export const proofSchemaType = {
type: 'string',
pattern: '^0x[a-fA-F0-9]{512}$',
} as const;
export const bytes32SchemaType = {
type: 'string',
pattern: '^0x[a-fA-F0-9]{64}$',
} as const;
export const bytes32BNSchemaType = { ...bytes32SchemaType, BN: true } as const;

View File

@@ -100,7 +100,11 @@ export class TovarishClient extends RelayerClient {
// relayerAddress from registry contract to prevent cheating
relayerAddress?: string;
}): Promise<TovarishStatus> {
const status = (await super.askRelayerStatus({ hostname, url, relayerAddress })) as TovarishStatus;
const status = (await super.askRelayerStatus({
hostname,
url,
relayerAddress,
})) as TovarishStatus;
if (!status.version.includes('tovarish')) {
throw new Error('Not a tovarish relayer!');
@@ -151,8 +155,14 @@ export class TovarishClient extends RelayerClient {
const netId = (rawStatus as any).netId as NetIdType;
const config = getConfig(netId);
const statusValidator = ajv.compile(
getStatusSchema(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const statusValidator = ajv.compile(getStatusSchema((rawStatus as any).netId, config, this.tovarish));
(rawStatus as any).netId,
config,
this.tovarish,
),
);
if (!statusValidator) {
continue;
@@ -195,7 +205,10 @@ export class TovarishClient extends RelayerClient {
const hostname = `${tovarishHost}/${this.netId}`;
try {
const status = await this.askRelayerStatus({ hostname, relayerAddress });
const status = await this.askRelayerStatus({
hostname,
relayerAddress,
});
return {
netId: status.netId,
@@ -235,7 +248,8 @@ export class TovarishClient extends RelayerClient {
}> {
const invalidRelayers: RelayerError[] = [];
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(relayer)))).filter((r) => {
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(relayer)))).filter(
(r) => {
if (!r) {
return false;
}
@@ -244,7 +258,8 @@ export class TovarishClient extends RelayerClient {
return false;
}
return true;
}) as TovarishInfo[];
},
) as TovarishInfo[];
return {
validRelayers,
@@ -266,7 +281,10 @@ export class TovarishClient extends RelayerClient {
const { ensName, relayerAddress, tovarishHost } = relayer;
try {
const statusArray = await this.askAllStatus({ hostname: tovarishHost as string, relayerAddress });
const statusArray = await this.askAllStatus({
hostname: tovarishHost as string,
relayerAddress,
});
for (const status of statusArray) {
validRelayers.push({

View File

@@ -31,9 +31,15 @@ describe('./src/deposit.ts', function () {
const netId = Number((await owner.provider.getNetwork()).chainId);
const deposit = await Deposit.createNote({ currency: 'eth', amount: formatEther(1), netId });
const deposit = await Deposit.createNote({
currency: 'eth',
amount: formatEther(1),
netId,
});
const resp = await Instance.deposit(deposit.commitmentHex, { value: 1n });
const resp = await Instance.deposit(deposit.commitmentHex, {
value: 1n,
});
await expect(resp).to.emit(Instance, 'Deposit').withArgs(deposit.commitmentHex, 0, anyValue);
@@ -44,7 +50,11 @@ describe('./src/deposit.ts', function () {
const notes = (await Promise.all(
// eslint-disable-next-line prefer-spread
Array.apply(null, Array(NOTES_COUNT)).map(() =>
Deposit.createNote({ currency: 'eth', amount: '0.1', netId: 31337 }),
Deposit.createNote({
currency: 'eth',
amount: '0.1',
netId: 31337,
}),
),
)) as Deposit[];