tovarish-relayer/lib/services/schema.js

201 lines
6.7 KiB
JavaScript
Raw Normal View History

2024-11-13 04:42:13 +03:00
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.treeNameSchema = exports.eventsSchema = exports.withdrawBodySchema = exports.idParamsSchema = void 0;
exports.getWithdrawSchema = getWithdrawSchema;
exports.getEventsSchema = getEventsSchema;
exports.getWithdrawKeyword = getWithdrawKeyword;
exports.getEventsKeyword = getEventsKeyword;
exports.getTreeNameKeyword = getTreeNameKeyword;
exports.getAllWithdrawKeyword = getAllWithdrawKeyword;
exports.getAllEventsKeyword = getAllEventsKeyword;
const ethers_1 = require("ethers");
const core_1 = require("@tornado/core");
exports.idParamsSchema = {
params: {
type: 'object',
properties: {
id: { type: 'string', format: 'uuid' },
},
required: ['id'],
additionalProperties: false,
},
};
exports.withdrawBodySchema = {
body: {
type: 'object',
properties: {
proof: core_1.proofSchemaType,
contract: core_1.addressSchemaType,
args: {
type: 'array',
maxItems: 6,
minItems: 6,
items: [
core_1.bytes32SchemaType,
core_1.bytes32SchemaType,
core_1.addressSchemaType,
core_1.addressSchemaType,
core_1.bytes32BNSchemaType,
core_1.bytes32BNSchemaType,
],
},
},
additionalProperties: false,
required: ['proof', 'contract', 'args'],
},
};
const stringParamsType = {
type: 'string',
minLength: 1,
maxLength: 30,
};
exports.eventsSchema = {
body: {
type: 'object',
properties: {
type: stringParamsType,
currency: stringParamsType,
amount: stringParamsType,
fromBlock: { type: 'number' },
recent: { type: 'boolean' },
},
additionalProperties: false,
required: ['type', 'fromBlock'],
},
};
exports.treeNameSchema = {
params: {
type: 'object',
properties: {
treeName: {
type: 'string',
minLength: 1,
maxLength: 60,
TreeName: true,
},
},
additionalProperties: false,
required: ['treeName'],
},
};
function getWithdrawSchema(netId) {
const keyword = `withdraw${netId}`;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const schema = JSON.parse(JSON.stringify(exports.withdrawBodySchema));
schema.body[keyword] = true;
return schema;
}
function getEventsSchema(netId) {
const keyword = `events${netId}`;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const schema = JSON.parse(JSON.stringify(exports.eventsSchema));
schema.body[keyword] = true;
return schema;
}
function getWithdrawKeyword(netId, rewardAccount) {
const keyword = `withdraw${netId}`;
const config = (0, core_1.getConfig)(netId);
return {
keyword,
validate: (schema, data) => {
try {
const { contract, args } = data;
const instance = (0, core_1.getInstanceByAddress)(config, contract);
// Unknown instance contract is unsupported
if (!instance) {
return false;
}
// Fee recipient should be a reward account
2024-11-20 14:00:07 +03:00
if ((0, ethers_1.getAddress)(args[3]) !== rewardAccount) {
2024-11-13 04:42:13 +03:00
return false;
}
const { amount, currency } = instance;
const { nativeCurrency, tokens: { [currency]: { decimals }, }, } = config;
const denomination = (0, ethers_1.parseUnits)(amount, decimals);
const fee = BigInt(args[4]);
// Fees can't exceed denomination
if (!fee || fee >= denomination) {
return false;
}
// ETHTornado instances can't have refunds
if (currency === nativeCurrency && BigInt(args[5])) {
return false;
}
return true;
}
catch {
return false;
}
},
errors: true,
};
}
function getEventsKeyword(netId) {
const keyword = `events${netId}`;
const config = (0, core_1.getConfig)(netId);
const { governanceContract, registryContract } = config;
return {
keyword,
validate: (schema, data) => {
try {
const { type, currency, amount } = data;
2024-11-19 13:22:27 +03:00
if (['deposit', 'withdrawal'].includes(type)) {
2024-11-13 04:42:13 +03:00
const instanceAddress = config.tokens[String(currency)]?.instanceAddress?.[String(amount)];
if (!instanceAddress) {
return false;
}
return true;
}
if (type === 'governance') {
if (!governanceContract) {
return false;
}
return true;
}
// todo: remove this after some time, remains for legacy client connection
if (['registered', 'registry', 'revenue'].includes(type)) {
if (!registryContract) {
return false;
}
return true;
}
2024-11-19 13:22:27 +03:00
return ['tornado', 'echo', 'encrypted_notes'].includes(type);
2024-11-13 04:42:13 +03:00
}
catch {
return false;
}
},
errors: true,
};
}
function getTreeNameKeyword() {
return {
keyword: 'TreeName',
validate: (schema, data) => {
try {
const treeRegex = /deposits_(?<netId>\d+)_(?<currency>\w+)_(?<amount>[\d.]+)_(?<part>\w+).json.zip/g;
const { netId, currency, amount, part } = treeRegex.exec(data)?.groups || {};
const config = (0, core_1.getConfig)(Number(netId));
if (!currency || !amount || !part || currency !== config.nativeCurrency) {
return false;
}
const instanceAddress = config.tokens[String(currency)]?.instanceAddress?.[String(amount)];
if (!instanceAddress) {
return false;
}
return true;
}
catch {
return false;
}
},
errors: true,
};
}
function getAllWithdrawKeyword(rewardAccount) {
return core_1.enabledChains.map((netId) => getWithdrawKeyword(netId, rewardAccount));
}
function getAllEventsKeyword() {
return core_1.enabledChains.map((netId) => getEventsKeyword(netId));
}