This commit is contained in:
smart_ex 2022-05-13 17:05:38 +10:00
parent 9f17840034
commit 8e3f20f76c
21 changed files with 588 additions and 2672 deletions

256
contracts/ProxyLightABI.ts Normal file
View File

@ -0,0 +1,256 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type {
BaseContract,
BigNumber,
BigNumberish,
BytesLike,
CallOverrides,
ContractTransaction,
Overrides,
PayableOverrides,
PopulatedTransaction,
Signer,
utils,
} from "ethers";
import type {
FunctionFragment,
Result,
EventFragment,
} from "@ethersproject/abi";
import type { Listener, Provider } from "@ethersproject/providers";
import type {
TypedEventFilter,
TypedEvent,
TypedListener,
OnEvent,
} from "./common";
export interface ProxyLightABIInterface extends utils.Interface {
contractName: "ProxyLightABI";
functions: {
"backupNotes(bytes[])": FunctionFragment;
"deposit(address,bytes32,bytes)": FunctionFragment;
"withdraw(address,bytes,bytes32,bytes32,address,address,uint256,uint256)": FunctionFragment;
};
getFunction(
nameOrSignatureOrTopic: "backupNotes" | "deposit" | "withdraw"
): FunctionFragment;
encodeFunctionData(
functionFragment: "backupNotes",
values: [BytesLike[]]
): string;
encodeFunctionData(
functionFragment: "deposit",
values: [string, BytesLike, BytesLike]
): string;
encodeFunctionData(
functionFragment: "withdraw",
values: [
string,
BytesLike,
BytesLike,
BytesLike,
string,
string,
BigNumberish,
BigNumberish
]
): string;
decodeFunctionResult(
functionFragment: "backupNotes",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "deposit", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "withdraw", data: BytesLike): Result;
events: {
"EncryptedNote(address,bytes)": EventFragment;
};
getEvent(nameOrSignatureOrTopic: "EncryptedNote"): EventFragment;
}
export interface EncryptedNoteEventObject {
sender: string;
encryptedNote: string;
}
export type EncryptedNoteEvent = TypedEvent<
[string, string],
EncryptedNoteEventObject
>;
export type EncryptedNoteEventFilter = TypedEventFilter<EncryptedNoteEvent>;
export interface ProxyLightABI extends BaseContract {
contractName: "ProxyLightABI";
connect(signerOrProvider: Signer | Provider | string): this;
attach(addressOrName: string): this;
deployed(): Promise<this>;
interface: ProxyLightABIInterface;
queryFilter<TEvent extends TypedEvent>(
event: TypedEventFilter<TEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TEvent>>;
listeners<TEvent extends TypedEvent>(
eventFilter?: TypedEventFilter<TEvent>
): Array<TypedListener<TEvent>>;
listeners(eventName?: string): Array<Listener>;
removeAllListeners<TEvent extends TypedEvent>(
eventFilter: TypedEventFilter<TEvent>
): this;
removeAllListeners(eventName?: string): this;
off: OnEvent<this>;
on: OnEvent<this>;
once: OnEvent<this>;
removeListener: OnEvent<this>;
functions: {
backupNotes(
_encryptedNotes: BytesLike[],
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
deposit(
_tornado: string,
_commitment: BytesLike,
_encryptedNote: BytesLike,
overrides?: PayableOverrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
withdraw(
_tornado: string,
_proof: BytesLike,
_root: BytesLike,
_nullifierHash: BytesLike,
_recipient: string,
_relayer: string,
_fee: BigNumberish,
_refund: BigNumberish,
overrides?: PayableOverrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
};
backupNotes(
_encryptedNotes: BytesLike[],
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
deposit(
_tornado: string,
_commitment: BytesLike,
_encryptedNote: BytesLike,
overrides?: PayableOverrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
withdraw(
_tornado: string,
_proof: BytesLike,
_root: BytesLike,
_nullifierHash: BytesLike,
_recipient: string,
_relayer: string,
_fee: BigNumberish,
_refund: BigNumberish,
overrides?: PayableOverrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
callStatic: {
backupNotes(
_encryptedNotes: BytesLike[],
overrides?: CallOverrides
): Promise<void>;
deposit(
_tornado: string,
_commitment: BytesLike,
_encryptedNote: BytesLike,
overrides?: CallOverrides
): Promise<void>;
withdraw(
_tornado: string,
_proof: BytesLike,
_root: BytesLike,
_nullifierHash: BytesLike,
_recipient: string,
_relayer: string,
_fee: BigNumberish,
_refund: BigNumberish,
overrides?: CallOverrides
): Promise<void>;
};
filters: {
"EncryptedNote(address,bytes)"(
sender?: string | null,
encryptedNote?: null
): EncryptedNoteEventFilter;
EncryptedNote(
sender?: string | null,
encryptedNote?: null
): EncryptedNoteEventFilter;
};
estimateGas: {
backupNotes(
_encryptedNotes: BytesLike[],
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<BigNumber>;
deposit(
_tornado: string,
_commitment: BytesLike,
_encryptedNote: BytesLike,
overrides?: PayableOverrides & { from?: string | Promise<string> }
): Promise<BigNumber>;
withdraw(
_tornado: string,
_proof: BytesLike,
_root: BytesLike,
_nullifierHash: BytesLike,
_recipient: string,
_relayer: string,
_fee: BigNumberish,
_refund: BigNumberish,
overrides?: PayableOverrides & { from?: string | Promise<string> }
): Promise<BigNumber>;
};
populateTransaction: {
backupNotes(
_encryptedNotes: BytesLike[],
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<PopulatedTransaction>;
deposit(
_tornado: string,
_commitment: BytesLike,
_encryptedNote: BytesLike,
overrides?: PayableOverrides & { from?: string | Promise<string> }
): Promise<PopulatedTransaction>;
withdraw(
_tornado: string,
_proof: BytesLike,
_root: BytesLike,
_nullifierHash: BytesLike,
_recipient: string,
_relayer: string,
_fee: BigNumberish,
_refund: BigNumberish,
overrides?: PayableOverrides & { from?: string | Promise<string> }
): Promise<PopulatedTransaction>;
};
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,126 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import { Contract, Signer, utils } from "ethers";
import type { Provider } from "@ethersproject/providers";
import type { ProxyLightABI, ProxyLightABIInterface } from "../ProxyLightABI";
const _abi = [
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "sender",
type: "address",
},
{
indexed: false,
internalType: "bytes",
name: "encryptedNote",
type: "bytes",
},
],
name: "EncryptedNote",
type: "event",
},
{
inputs: [
{
internalType: "bytes[]",
name: "_encryptedNotes",
type: "bytes[]",
},
],
name: "backupNotes",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{
internalType: "contract ITornadoInstance",
name: "_tornado",
type: "address",
},
{
internalType: "bytes32",
name: "_commitment",
type: "bytes32",
},
{
internalType: "bytes",
name: "_encryptedNote",
type: "bytes",
},
],
name: "deposit",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{
internalType: "contract ITornadoInstance",
name: "_tornado",
type: "address",
},
{
internalType: "bytes",
name: "_proof",
type: "bytes",
},
{
internalType: "bytes32",
name: "_root",
type: "bytes32",
},
{
internalType: "bytes32",
name: "_nullifierHash",
type: "bytes32",
},
{
internalType: "address payable",
name: "_recipient",
type: "address",
},
{
internalType: "address payable",
name: "_relayer",
type: "address",
},
{
internalType: "uint256",
name: "_fee",
type: "uint256",
},
{
internalType: "uint256",
name: "_refund",
type: "uint256",
},
],
name: "withdraw",
outputs: [],
stateMutability: "payable",
type: "function",
},
];
export class ProxyLightABI__factory {
static readonly abi = _abi;
static createInterface(): ProxyLightABIInterface {
return new utils.Interface(_abi) as ProxyLightABIInterface;
}
static connect(
address: string,
signerOrProvider: Signer | Provider
): ProxyLightABI {
return new Contract(address, _abi, signerOrProvider) as ProxyLightABI;
}
}

View File

@ -1,11 +1,9 @@
/* Autogenerated file. Do not edit manually. */ /* Autogenerated file. Do not edit manually. */
/* tslint:disable */ /* tslint:disable */
/* eslint-disable */ /* eslint-disable */
export { AggregatorAbi__factory } from "./AggregatorAbi__factory"; export { AggregatorAbi__factory } from './AggregatorAbi__factory';
export { MulticallAbi__factory } from "./MulticallAbi__factory"; export { MulticallAbi__factory } from './MulticallAbi__factory';
export { OffchainOracleAbi__factory } from "./OffchainOracleAbi__factory"; export { OffchainOracleAbi__factory } from './OffchainOracleAbi__factory';
export { MiningAbi__factory } from "./MiningAbi__factory"; export { ProxyLightABI__factory } from './ProxyLightABI__factory';
export { ProxyLightABI__factory } from "./ProxyLightABI__factory"; export { TornadoABI__factory } from './TornadoABI__factory';
export { SwapAbi__factory } from "./SwapAbi__factory"; export { TornadoProxyABI__factory } from './TornadoProxyABI__factory';
export { TornadoABI__factory } from "./TornadoABI__factory";
export { TornadoProxyABI__factory } from "./TornadoProxyABI__factory";

View File

@ -9,7 +9,6 @@ export type { TornadoABI } from './TornadoABI';
export type { TornadoProxyABI } from './TornadoProxyABI'; export type { TornadoProxyABI } from './TornadoProxyABI';
export * as factories from './factories'; export * as factories from './factories';
export { AggregatorAbi__factory } from './factories/AggregatorAbi__factory'; export { AggregatorAbi__factory } from './factories/AggregatorAbi__factory';
export { MiningAbi__factory } from './factories/MiningAbi__factory';
export { MulticallAbi__factory } from './factories/MulticallAbi__factory'; export { MulticallAbi__factory } from './factories/MulticallAbi__factory';
export { OffchainOracleAbi__factory } from './factories/OffchainOracleAbi__factory'; export { OffchainOracleAbi__factory } from './factories/OffchainOracleAbi__factory';
export { ProxyLightABI__factory } from './factories/ProxyLightABI__factory'; export { ProxyLightABI__factory } from './factories/ProxyLightABI__factory';

View File

@ -31,7 +31,7 @@
"json-schema-to-ts": "^2.2.0", "json-schema-to-ts": "^2.2.0",
"node-fetch": "^2.6.7", "node-fetch": "^2.6.7",
"torn-token": "link:../torn-token", "torn-token": "link:../torn-token",
"tx-manager": "^0.4.6", "tx-manager": "link:../tx-manager",
"uuid": "^8.3.0", "uuid": "^8.3.0",
"web3": "^1.3.0", "web3": "^1.3.0",
"web3-core-promievent": "^1.3.0", "web3-core-promievent": "^1.3.0",

View File

@ -1,33 +1,53 @@
import { FastifyInstance } from 'fastify'; import { FastifyInstance } from 'fastify';
import { statusSchema, withdrawBodySchema, withdrawSchema } from './schema'; import { statusSchema, withdrawBodySchema } from './schema';
import { FromSchema } from 'json-schema-to-ts'; import { FromSchema } from 'json-schema-to-ts';
import { rewardAccount, tornadoServiceFee } from '../config';
import { version } from '../../package.json';
import { configService } from '../services';
export function relayerHandler(server: FastifyInstance, options, next) { export function mainHandler(server: FastifyInstance, options, next) {
/*
write some code here, please
*/
server.get('/', server.get('/',
async (req, res) => { async (req, res) => {
res.send({}); res.send('hello fellows');
}); });
server.get('/status', server.get('/status',
{ schema: statusSchema }, { schema: statusSchema },
async (req, res) => { async (req, res) => {
res.send({ status: 'status' }); server.log.info(req.method, 'status');
res.send({
rewardAccount,
instances: configService.instances,
netId: configService.netId,
ethPrices: {
dai: '488750716084282',
cdai: '10750196909100',
usdc: '488744421966526',
usdt: '486409579105158',
wbtc: '14586361452511510343',
torn: '18624781058055820',
},
tornadoServiceFee,
miningServiceFee: 0,
version,
health: {
status: true,
error: '',
},
currentQueue: 0,
});
}); });
server.post<{ Body: FromSchema<typeof withdrawBodySchema> }>('/relay', next();
{ schema: withdrawSchema }, }
async (req, res) => {
res.send({});
},
);
export function relayerHandler(server: FastifyInstance, options, next) {
server.get('/jobs/:id', server.get('/jobs/:id',
async (req, res) => { async (req, res) => {
res.send({}); res.send({});
}); });
server.post('/tornadoWithdraw', server.post<{ Body: FromSchema<typeof withdrawBodySchema> }>('/tornadoWithdraw',
async (req, res) => { async (req, res) => {
console.log(req.body);
res.send({}); res.send({});
}); });
next(); next();

View File

@ -1,6 +1,6 @@
const addressType = { type: 'string', pattern: '^0x[a-fA-F0-9]{40}$', isAddress: true } as const; const addressType = { type: 'string', pattern: '^0x[a-fA-F0-9]{40}$', isAddress: true } as const;
const proofType = { type: 'string', pattern: '^0x[a-fA-F0-9]{512}$' } as const; const proofType = { type: 'string', pattern: '^0x[a-fA-F0-9]{512}$' } as const;
const encryptedAccountType = { type: 'string', pattern: '^0x[a-fA-F0-9]{392}$' } as const; // const encryptedAccountType = { type: 'string', pattern: '^0x[a-fA-F0-9]{392}$' } as const;
const bytes32Type = { type: 'string', pattern: '^0x[a-fA-F0-9]{64}$' } as const; const bytes32Type = { type: 'string', pattern: '^0x[a-fA-F0-9]{64}$' } as const;
const instanceType = { ...addressType, isKnownContract: true } as const; const instanceType = { ...addressType, isKnownContract: true } as const;
const relayerType = { ...addressType, isFeeRecipient: true } as const; const relayerType = { ...addressType, isFeeRecipient: true } as const;
@ -25,14 +25,25 @@ export const withdrawSchema = {
body: withdrawBodySchema, body: withdrawBodySchema,
response: { response: {
200: { 200: {
type: 'boolean', type: 'object',
properties: {
jobId: { type: 'string', format: 'uuid' },
},
}, },
}, },
}; };
const statusResponseSchema = { const statusResponseSchema = {
type: 'object', type: 'object',
properties: { properties: {
status: { type: 'string' }, rewardAccount: addressType,
netId: { type: 'integer' },
version: { type: 'string' },
tornadoServiceFee: { type: 'number' },
miningServiceFee: { type: 'number' },
currentQueue: { type: 'number' },
ethPrices: { type: 'object', additionalProperties: true },
instances: { type: 'object', additionalProperties: true },
health: { type: 'object', additionalProperties: true },
}, },
} as const; } as const;
@ -41,109 +52,3 @@ export const statusSchema = {
200: statusResponseSchema, 200: statusResponseSchema,
}, },
}; };
const miningRewardSchema = {
type: 'object',
properties: {
proof: proofType,
args: {
type: 'object',
properties: {
rate: bytes32Type,
fee: bytes32Type,
instance: instanceType,
rewardNullifier: bytes32Type,
extDataHash: bytes32Type,
depositRoot: bytes32Type,
withdrawalRoot: bytes32Type,
extData: {
type: 'object',
properties: {
relayer: relayerType,
encryptedAccount: encryptedAccountType,
},
additionalProperties: false,
required: ['relayer', 'encryptedAccount'],
},
account: {
type: 'object',
properties: {
inputRoot: bytes32Type,
inputNullifierHash: bytes32Type,
outputRoot: bytes32Type,
outputPathIndices: bytes32Type,
outputCommitment: bytes32Type,
},
additionalProperties: false,
required: [
'inputRoot',
'inputNullifierHash',
'outputRoot',
'outputPathIndices',
'outputCommitment',
],
},
},
additionalProperties: false,
required: [
'rate',
'fee',
'instance',
'rewardNullifier',
'extDataHash',
'depositRoot',
'withdrawalRoot',
'extData',
'account',
],
},
},
additionalProperties: false,
required: ['proof', 'args'],
} as const;
const miningWithdrawSchema = {
type: 'object',
properties: {
proof: proofType,
args: {
type: 'object',
properties: {
amount: bytes32Type,
extDataHash: bytes32Type,
extData: {
type: 'object',
properties: {
fee: bytes32Type,
recipient: addressType,
relayer: relayerType,
encryptedAccount: encryptedAccountType,
},
additionalProperties: false,
required: ['fee', 'relayer', 'encryptedAccount', 'recipient'],
},
account: {
type: 'object',
properties: {
inputRoot: bytes32Type,
inputNullifierHash: bytes32Type,
outputRoot: bytes32Type,
outputPathIndices: bytes32Type,
outputCommitment: bytes32Type,
},
additionalProperties: false,
required: [
'inputRoot',
'inputNullifierHash',
'outputRoot',
'outputPathIndices',
'outputCommitment',
],
},
},
additionalProperties: false,
required: ['amount', 'extDataHash', 'extData', 'account'],
},
},
additionalProperties: false,
required: ['proof', 'args'],
};

View File

@ -1,7 +1,7 @@
import fastify from 'fastify'; import fastify from 'fastify';
import cors from 'fastify-cors'; import cors from 'fastify-cors';
import validator from './plugins/validator'; import validator from './plugins/validator';
import { relayerHandler } from './routes'; import { mainHandler, relayerHandler } from './routes';
function createServer() { function createServer() {
@ -12,7 +12,8 @@ function createServer() {
}); });
server.register(cors); server.register(cors);
server.register(validator); server.register(validator);
server.register(relayerHandler); server.register(mainHandler);
server.register(relayerHandler, { prefix: '/v1' });
server.setErrorHandler((error, req, res) => { server.setErrorHandler((error, req, res) => {

View File

@ -17,7 +17,7 @@ export const instances = tornConfig.instances;
export const torn = tornConfig; export const torn = tornConfig;
export const port = process.env.APP_PORT || 8000; export const port = process.env.APP_PORT || 8000;
export const tornadoServiceFee = Number(process.env.REGULAR_TORNADO_WITHDRAW_FEE); export const tornadoServiceFee = Number(process.env.REGULAR_TORNADO_WITHDRAW_FEE);
// export const miningServiceFee = Number(process.env.MINING_SERVICE_FEE); export const miningServiceFee = Number(process.env.MINING_SERVICE_FEE);
export const rewardAccount = process.env.REWARD_ACCOUNT; export const rewardAccount = process.env.REWARD_ACCOUNT;
export const governanceAddress = '0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce'; export const governanceAddress = '0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce';
export const tornadoGoerliProxy = '0x454d870a72e29d5E5697f635128D18077BD04C60'; export const tornadoGoerliProxy = '0x454d870a72e29d5E5697f635128D18077BD04C60';

View File

@ -1,8 +1,8 @@
import Redis from 'ioredis'; import Redis from 'ioredis';
import { redisUrl } from '../config'; import { redisUrl } from '../config';
const redisClient = new Redis(redisUrl); const redisClient = new Redis(redisUrl, { maxRetriesPerRequest: null });
const redisSubscriber = new Redis(redisUrl); const redisSubscriber = new Redis(redisUrl, { maxRetriesPerRequest: null });
export const getClient = () => redisClient; export const getClient = () => redisClient;
export const getSubscriber = () => redisSubscriber; export const getSubscriber = () => redisSubscriber;

View File

@ -1,8 +1,8 @@
import priceService from '../services/PriceService'; import { priceService } from '../services';
import { Job } from 'bullmq'; import { Job } from 'bullmq';
export const priceProcessor = async (job: Job) => { export const priceProcessor = async (job: Job) => {
const { tokens } = job.data; const prices = await priceService.fetchPrices(job.data);
const prices = await priceService.getPrices(tokens); console.log(job.name, prices);
console.log(prices); return prices;
}; };

View File

@ -0,0 +1,6 @@
import { Job } from 'bullmq';
export const relayerProcessor = async (job: Job) => {
console.log(job.data);
return {};
};

View File

@ -1,8 +1,12 @@
import { redis } from '../modules'; import { getPriceWorker, getRelayerWorker } from './';
import { Worker } from 'bullmq';
const connection = redis.getClient();
const worker = new Worker('proof', async (job) => { export default async () => {
// do some processing const priceWorker = getPriceWorker();
}, { connection }); priceWorker.on('completed', (job, result) => console.log(result));
priceWorker.on('failed', (job, error) => console.log(error));
const relayerWorker = getRelayerWorker();
relayerWorker.on('completed', (job, result) => console.log(result));
relayerWorker.on('failed', (job, error) => console.log(error));
};

View File

@ -1,9 +1,9 @@
import { instances, netId, torn, tornadoGoerliProxy, tornToken } from '../config'; import { httpRpcUrl, instances, netId, privateKey, torn, tornadoGoerliProxy, tornToken } from '../config';
import { Token } from '../types'; import { Token } from '../types';
import { getProvider, getTornadoProxyContract, getTornadoProxyLightContract } from '../modules/contracts'; import { getProvider, getTornadoProxyContract, getTornadoProxyLightContract } from '../modules/contracts';
import { EnsResolver } from '../modules'; import { EnsResolver } from '../modules';
import { ProxyLightABI, TornadoProxyABI } from '../../contracts'; import { ProxyLightABI, TornadoProxyABI } from '../../contracts';
import { availableIds, netIds } from '../../../torn-token'; import { availableIds, netIds, NetInstances } from '../../../torn-token';
import { getAddress } from 'ethers/lib/utils'; import { getAddress } from 'ethers/lib/utils';
const resolver = new EnsResolver(getProvider()); const resolver = new EnsResolver(getProvider());
@ -14,24 +14,32 @@ export class ConfigService {
netId: availableIds; netId: availableIds;
netIdKey: netIds; netIdKey: netIds;
tokens: Token[]; tokens: Token[];
privateKey: string;
rpcUrl: string;
private _proxyAddress: string; private _proxyAddress: string;
private _proxyContract: TornadoProxyABI | ProxyLightABI; private _proxyContract: TornadoProxyABI | ProxyLightABI;
addressMap = new Map<string, InstanceProps>(); addressMap = new Map<string, InstanceProps>();
isLightMode: boolean; isLightMode: boolean;
instances: NetInstances;
constructor() { constructor() {
this.netId = netId; this.netId = netId;
this.netIdKey = `netId${this.netId}`; this.netIdKey = `netId${this.netId}`;
this.isLightMode = ![1, 5].includes(netId); this.isLightMode = ![1, 5].includes(netId);
this.privateKey = privateKey;
for (const [currency, { instanceAddress, symbol, decimals }] of Object.entries(instances[this.netIdKey])) { this.rpcUrl = httpRpcUrl;
Object.entries(instanceAddress).forEach(([amount, address]) => this.instances = instances[this.netIdKey];
this.addressMap.set(getAddress(address), { for (const [currency, { instanceAddress, symbol, decimals }] of Object.entries(this.instances)) {
currency, Object.entries(instanceAddress).forEach(([amount, address]) => {
amount, if (address) {
symbol, this.addressMap.set(getAddress(address), {
decimals, currency,
}), amount,
symbol,
decimals,
});
}
},
); );
} }
} }

View File

@ -4,6 +4,9 @@ import { MultiCall } from '../../contracts/MulticallAbi';
import { BigNumber } from 'ethers'; import { BigNumber } from 'ethers';
import { defaultAbiCoder } from 'ethers/lib/utils'; import { defaultAbiCoder } from 'ethers/lib/utils';
import { Token } from '../types'; import { Token } from '../types';
import { redis } from '../modules';
const redisClient = redis.getClient();
export class PriceService { export class PriceService {
oracle: OffchainOracleAbi; oracle: OffchainOracleAbi;
@ -23,7 +26,7 @@ export class PriceService {
})); }));
} }
async getPrices(tokens: Token[]) { async fetchPrices(tokens: Token[]) {
const names = tokens.reduce((p, c) => { const names = tokens.reduce((p, c) => {
p[c.address] = c.symbol; p[c.address] = c.symbol;
return p; return p;
@ -43,6 +46,10 @@ export class PriceService {
} }
return prices; return prices;
} }
async getPrice(symbol: string) {
return await redisClient.hget('prices', symbol);
}
} }
export default new PriceService(); export default new PriceService();

46
src/services/TxService.ts Normal file
View File

@ -0,0 +1,46 @@
import { TxManager } from 'tx-manager';
import { configService } from './index';
import { ProxyLightABI, TornadoProxyABI } from '../../contracts';
import { parseEther } from 'ethers/lib/utils';
import { gasLimits } from '../config';
export class TxService {
txManager: TxManager;
tornadoProxy: TornadoProxyABI | ProxyLightABI;
constructor() {
const { privateKey, rpcUrl, proxyContract } = configService;
this.txManager = new TxManager({ privateKey, rpcUrl });
this.tornadoProxy = proxyContract;
}
async init() {
const currentTx = this.txManager.createTx({
nonce: 123,
to: '0x2f04c418e91585222a7042FFF4aB7281D34FdfCC',
value: parseEther('1'),
});
const receipt = await currentTx.send()
.on('transactionHash', txHash => console.log({ txHash }))
.on('mined', receipt => console.log('Mined in block', receipt.blockNumber))
.on('confirmations', confirmations => console.log({ confirmations }));
console.log(receipt);
await Promise.resolve();
}
private async prepareCallData(data) {
// const calldata = this.tornadoProxy.interface.encodeFunctionData('withdraw', );
return {
value: data.args[5],
to: this.tornadoProxy.address,
data: [],
gasLimit: gasLimits['WITHDRAW_WITH_EXTRA'],
};
}
}
export default new TxService();

View File

@ -1,2 +1,3 @@
export { default as priceService } from './PriceService'; export { default as priceService } from './PriceService';
export { default as configService } from './ConfigService'; export { default as configService } from './ConfigService';
export { default as txService } from './TxService';

View File

@ -90,16 +90,12 @@ async function start() {
BASE_FEE_RESERVE_PERCENTAGE: baseFeeReserve, BASE_FEE_RESERVE_PERCENTAGE: baseFeeReserve,
}, },
}); });
swap = new web3.eth.Contract(swapABI, await resolver.resolve(torn.rewardSwap.address));
minerContract = new web3.eth.Contract(miningABI, await resolver.resolve(torn.miningV2.address));
redisSubscribe.subscribe('treeUpdate', fetchTree);
await fetchTree();
const provingKeys = { const provingKeys = {
treeUpdateCircuit: require('../keys/TreeUpdate.json'), treeUpdateCircuit: require('../keys/TreeUpdate.json'),
treeUpdateProvingKey: fs.readFileSync('./keys/TreeUpdate_proving_key.bin').buffer, treeUpdateProvingKey: fs.readFileSync('./keys/TreeUpdate_proving_key.bin').buffer,
}; };
controller = new Controller({ provingKeys }); // controller = new Controller({ provingKeys });
await controller.init(); // await controller.init();
queue.process(processJob); queue.process(processJob);
console.log('Worker started'); console.log('Worker started');
} catch (e) { } catch (e) {
@ -198,31 +194,13 @@ async function checkTornadoFee({ args, contract }) {
// } // }
// } // }
async function isLatestProposalExecuted() {
const PROPOSAL_EXECUTED_STATUS = 5;
const expectedProposalId = 10;
try {
const aggregator = new web3.eth.Contract(aggregatorAbi, aggregatorAddress);
const proposals = await aggregator.methods.getAllProposals(governanceAddress).call();
const expectedProposal = proposals[expectedProposalId - 1];
return expectedProposal && Number(expectedProposal['state']) === PROPOSAL_EXECUTED_STATUS;
} catch (e) {
console.error(e.message);
return false;
}
}
async function getProxyContract() { async function getProxyContract() {
let proxyAddress; let proxyAddress;
if (netId === 5) { if (netId === 5) {
proxyAddress = tornadoGoerliProxy; proxyAddress = tornadoGoerliProxy;
} else { } else {
const latestProposalExecuted = await isLatestProposalExecuted(); proxyAddress = await resolver.resolve(torn.tornadoRouter.address)
proxyAddress = latestProposalExecuted
? await resolver.resolve(torn.tornadoRouter.address)
: await resolver.resolve(torn.tornadoProxy.address);
} }
const contract = new web3.eth.Contract(tornadoProxyABI, proxyAddress); const contract = new web3.eth.Contract(tornadoProxyABI, proxyAddress);

3
src/worker.ts Normal file
View File

@ -0,0 +1,3 @@
import initWorker from './queue/worker';
initWorker();

1434
yarn.lock

File diff suppressed because it is too large Load Diff