Compare commits

...

2 Commits

Author SHA1 Message Date
cf530416a0 Merge pull request '1. Modify the subgraph of config.js, delete unused chains, and add ensSubdomainKey to each chain' () from nanli777torn/tornado-cli:master into master
Reviewed-on: 
2025-03-20 20:16:49 +03:00
nanli777torn
792961d821 1. Modify the subgraph of config.js, delete unused chains, and add ensSubdomainKey to each chain
2. Modify cli.js to support subgraph use
3. Add relayerslist to allow users to obtain relayers data
2025-03-12 02:50:29 +08:00
5 changed files with 356 additions and 116 deletions

208
abis/Aggregator.abi.json Normal file

@ -0,0 +1,208 @@
[
{
"inputs": [],
"name": "ensRegistry",
"outputs": [
{
"internalType": "contract ENSRegistry",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract Governance",
"name": "governance",
"type": "address"
}
],
"name": "getAllProposals",
"outputs": [
{
"components": [
{
"internalType": "address",
"name": "proposer",
"type": "address"
},
{
"internalType": "address",
"name": "target",
"type": "address"
},
{
"internalType": "uint256",
"name": "startTime",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "endTime",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "forVotes",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "againstVotes",
"type": "uint256"
},
{
"internalType": "bool",
"name": "executed",
"type": "bool"
},
{
"internalType": "bool",
"name": "extended",
"type": "bool"
},
{
"internalType": "enum Governance.ProposalState",
"name": "state",
"type": "uint8"
}
],
"internalType": "struct GovernanceAggregator.Proposal[]",
"name": "proposals",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract Governance",
"name": "governance",
"type": "address"
},
{
"internalType": "address[]",
"name": "accs",
"type": "address[]"
}
],
"name": "getGovernanceBalances",
"outputs": [
{
"internalType": "uint256[]",
"name": "amounts",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract Governance",
"name": "governance",
"type": "address"
},
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "getUserData",
"outputs": [
{
"internalType": "uint256",
"name": "balance",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "latestProposalId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "latestProposalIdState",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "timelock",
"type": "uint256"
},
{
"internalType": "address",
"name": "delegatee",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "relayerRegistry",
"outputs": [
{
"internalType": "contract RelayerRegistry",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32[]",
"name": "_relayers",
"type": "bytes32[]"
},
{
"internalType": "string[]",
"name": "_subdomains",
"type": "string[]"
}
],
"name": "relayersData",
"outputs": [
{
"components": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "uint256",
"name": "balance",
"type": "uint256"
},
{
"internalType": "bool",
"name": "isRegistered",
"type": "bool"
},
{
"internalType": "string[20]",
"name": "records",
"type": "string[20]"
}
],
"internalType": "struct Relayer[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
}
]

2
cli.js

@ -1201,7 +1201,7 @@ async function fetchEvents({ type, currency, amount, filterEvents }) {
}
await fetchGraphEvents();
}
if (!privateRpc && !subgraph && !isTestRPC) {
if (!privateRpc && subgraph && !isTestRPC) {
await syncGraphEvents();
} else {
await syncEvents();

127
config.js Normal file → Executable file

@ -106,121 +106,12 @@ module.exports = {
gasLimit: '85000'
}
},
ensSubdomainKey: 'mainnet-tornado',
proxy: '0xd90e2f925DA726b50C4Ed8D0Fb90Ad053324F31b',
multicall: '0xeefBa1e63905eF1D7ACbA5a8513c70307C1cE441',
subgraph: 'https://api.thegraph.com/subgraphs/name/tornadocash/mainnet-tornado-subgraph',
subgraph: 'https://gateway.thegraph.com/api/6a217817dd87d33db10beed79b044a91/subgraphs/id/Ec6fVMDVqXTDQZ3c4jxcyV3zBXqkdgMWfhdtCgtqn7Sh',
defaultRpc: 'https://mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
},
netId5: {
tokens: {
eth: {
instanceAddress: {
0.1: '0x6Bf694a291DF3FeC1f7e69701E3ab6c592435Ae7',
1: '0x3aac1cC67c2ec5Db4eA850957b967Ba153aD6279',
10: '0x723B78e67497E85279CB204544566F4dC5d2acA0',
100: '0x0E3A09dDA6B20aFbB34aC7cD4A6881493f3E7bf7'
},
deployedBlockNumber: {
0.1: 3782581,
1: 3782590,
10: 3782593,
100: 3782596
},
miningEnabled: true,
symbol: 'ETH',
decimals: 18
},
dai: {
instanceAddress: {
100: '0x76D85B4C0Fc497EeCc38902397aC608000A06607',
1000: '0xCC84179FFD19A1627E79F8648d09e095252Bc418',
10000: '0xD5d6f8D9e784d0e26222ad3834500801a68D027D',
100000: '0x407CcEeaA7c95d2FE2250Bf9F2c105aA7AAFB512'
},
deployedBlockNumber: {
100: 4339088,
1000: 4367659,
10000: 4441492,
100000: 4441488
},
miningEnabled: true,
tokenAddress: '0xdc31Ee1784292379Fbb2964b3B9C4124D8F89C60',
symbol: 'DAI',
decimals: 18,
gasLimit: '55000'
},
cdai: {
instanceAddress: {
5000: '0x833481186f16Cece3f1Eeea1a694c42034c3a0dB',
50000: '0xd8D7DE3349ccaA0Fde6298fe6D7b7d0d34586193',
500000: '0x8281Aa6795aDE17C8973e1aedcA380258Bc124F9',
5000000: '0x57b2B8c82F065de8Ef5573f9730fC1449B403C9f'
},
deployedBlockNumber: {
5000: 4441443,
50000: 4441489,
500000: 4441493,
5000000: 4441489
},
miningEnabled: true,
tokenAddress: '0x822397d9a55d0fefd20F5c4bCaB33C5F65bd28Eb',
symbol: 'cDAI',
decimals: 8,
gasLimit: '425000'
},
usdc: {
instanceAddress: {
100: '0x05E0b5B40B7b66098C2161A5EE11C5740A3A7C45',
1000: '0x23173fE8b96A4Ad8d2E17fB83EA5dcccdCa1Ae52'
},
deployedBlockNumber: {
100: 4441426,
1000: 4441492
},
miningEnabled: false,
tokenAddress: '0xD87Ba7A50B2E7E660f678A895E4B72E7CB4CCd9C',
symbol: 'USDC',
decimals: 6,
gasLimit: '80000'
},
usdt: {
instanceAddress: {
100: '0x538Ab61E8A9fc1b2f93b3dd9011d662d89bE6FE6',
1000: '0x94Be88213a387E992Dd87DE56950a9aef34b9448'
},
deployedBlockNumber: {
100: 4441490,
1000: 4441492
},
miningEnabled: false,
tokenAddress: '0xb7FC2023D96AEa94Ba0254AA5Aeb93141e4aad66',
symbol: 'USDT',
decimals: 6,
gasLimit: '100000'
},
wbtc: {
instanceAddress: {
0.1: '0x242654336ca2205714071898f67E254EB49ACdCe',
1: '0x776198CCF446DFa168347089d7338879273172cF',
10: '0xeDC5d01286f99A066559F60a585406f3878a033e'
},
deployedBlockNumber: {
0.1: 4441488,
1: 4441490,
10: 4441490
},
miningEnabled: true,
tokenAddress: '0xC04B0d3107736C32e19F1c62b2aF67BE61d63a05',
symbol: 'WBTC',
decimals: 8,
gasLimit: '85000'
}
},
proxy: '0x454d870a72e29d5e5697f635128d18077bd04c60',
multicall: '0x77dCa2C955b15e9dE4dbBCf1246B4B85b651e50e',
subgraph: 'https://api.thegraph.com/subgraphs/name/tornadocash/goerli-tornado-subgraph',
defaultRpc: 'https://goerli.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
},
netId56: {
tokens: {
bnb: {
@ -241,9 +132,10 @@ module.exports = {
decimals: 18
}
},
ensSubdomainKey: 'bsc-tornado',
proxy: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
multicall: '0x41263cBA59EB80dC200F3E2544eda4ed6A90E76C',
subgraph: 'https://api.thegraph.com/subgraphs/name/tornadocash/bsc-tornado-subgraph',
subgraph: 'https://gateway.thegraph.com/api/6a217817dd87d33db10beed79b044a91/subgraphs/id/CiwGzefDBZCavXRPnwarnnF8xDDoLw4boBuySomJWYnV',
defaultRpc: 'https://bsc-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
},
netId100: {
@ -266,6 +158,7 @@ module.exports = {
decimals: 18
}
},
ensSubdomainKey: 'gnosis-tornado',
proxy: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
multicall: '0xb5b692a88BDFc81ca69dcB1d924f59f0413A602a',
subgraph: 'https://api.thegraph.com/subgraphs/name/tornadocash/xdai-tornado-subgraph',
@ -291,9 +184,10 @@ module.exports = {
decimals: 18
}
},
ensSubdomainKey: 'polygon-tornado',
proxy: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
multicall: '0x11ce4B23bD875D7F5C6a31084f55fDe1e9A87507',
subgraph: 'https://api.thegraph.com/subgraphs/name/tornadocash/matic-tornado-subgraph',
subgraph: 'https://gateway.thegraph.com/api/d2db349f28c895aa2272421996404c8d/subgraphs/id/HUMgwMYNrPQpnBJgesFXyy5u6jSiJ6u5nNWQng9ayCmD',
defaultRpc: 'https://polygon-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
},
netId42161: {
@ -316,9 +210,10 @@ module.exports = {
decimals: 18
}
},
ensSubdomainKey: 'arbitrum-tornado',
proxy: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
multicall: '0xB064Fe785d8131653eE12f3581F9A55F6D6E1ca3',
subgraph: 'https://api.thegraph.com/subgraphs/name/tornadocash/arbitrum-tornado-subgraph',
subgraph: 'https://gateway.thegraph.com/api/d2db349f28c895aa2272421996404c8d/subgraphs/id/8x8o6XFAqYZmiPwrJ51UxGTaZLYyW1fFtghvsEy7a1KJ',
defaultRpc: 'https://arbitrum-one.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
},
netId43114: {
@ -339,9 +234,10 @@ module.exports = {
decimals: 18
}
},
ensSubdomainKey: 'avalanche-tornado',
proxy: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
multicall: '0x98e2060F672FD1656a07bc12D7253b5e41bF3876',
subgraph: 'https://api.thegraph.com/subgraphs/name/tornadocash/avalanche-tornado-subgraph',
subgraph: 'https://gateway.thegraph.com/api/d2db349f28c895aa2272421996404c8d/subgraphs/id/CqUYVKJT9Jsyt7qnGNrf4FJNHw75ZbFGuzaJgqdaFASo',
defaultRpc: 'https://avalanche-rpc.tornado.ws/ext/bc/C/rpc'
},
netId10: {
@ -364,6 +260,7 @@ module.exports = {
decimals: 18
}
},
ensSubdomainKey: 'optimism-tornado',
proxy: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
multicall: '0x142E2FEaC30d7fc3b61f9EE85FCCad8e560154cc',
subgraph: 'https://api.thegraph.com/subgraphs/name/tornadocash/optimism-tornado-subgraph',

@ -22,6 +22,7 @@
"commander": "^5.1.0",
"dotenv": "^8.6.0",
"es5-ext": "0.10.53",
"eth-ens-namehash": "^2.0.8",
"private-ip": "^2.3.3",
"socks-proxy-agent": "^6.1.1",
"web3": "^1.10.2"

134
relayerslist.js Normal file

@ -0,0 +1,134 @@
const axios = require('axios');
const namehash = require('eth-ens-namehash');
const BigNumber = require('bignumber.js');
const apikey = '6a217817dd87d33db10beed79b044a91';
const api = 'https://gateway.thegraph.com/api/' + apikey + '/subgraphs/id/DgKwfAbLfynpiq7fDJy59LDnVnia4Y5nYeRDBYi9qezc';
const Web3 = require('web3');
const web3 = new Web3('https://rpc.mevblocker.io');
const aggregatorContract = '0xE8F47A78A6D52D317D0D2FFFac56739fE14D1b49';
const AggregatorABI = require('./abis/Aggregator.abi');
const aggregator = new web3.eth.Contract(AggregatorABI, aggregatorContract);
const MIN_STAKE_BALANCE = '0X1B1AE4D6E2EF500000'; // 500 TORN
const networkConfig = require('./config.js');
const subdomains = Object.values(networkConfig.deployments).map(({ ensSubdomainKey }) => ensSubdomainKey);
async function fetchRelayers() {
return new Promise(async (resolve, reject) => {
axios.post(api, { 'query': '{ relayers(first: 1000) {\n id\n address\n ensName\n ensHash\n }\n}' }
).then(res => {
if (res.data.errors) {
console.log(res.data);
return;
}
if (res.data.data.relayers.length > 0) {
resolve(res.data.data.relayers);
}
});
});
}
function filterRelayer(acc, curr, ensSubdomainKey, relayer) {
const subdomainIndex = subdomains.indexOf(ensSubdomainKey);
const mainnetSubdomain = curr.records[0];
const hostname = curr.records[subdomainIndex];
const isHostWithProtocol = hostname.includes('http');
const isOwner = relayer.address.toLowerCase() === curr.owner.toLowerCase();
const hasMinBalance = new BigNumber(curr.balance).gte(MIN_STAKE_BALANCE);
if (
hostname &&
isOwner &&
mainnetSubdomain &&
curr.isRegistered &&
hasMinBalance &&
!isHostWithProtocol
) {
acc.push({
hostname,
ensName: relayer.ensName,
stakeBalance: curr.balance,
relayerAddress: relayer.address.toLowerCase()
});
}
return acc;
}
async function getValidRelayers(relayers, ensSubdomainKey) {
const relayerNameHashes = relayers.map((r) => namehash.hash(r.ensName));
const relayersData = await aggregator.methods.relayersData(relayerNameHashes, subdomains).call();
const validRelayers = relayersData.reduce(
(acc, curr, index) => filterRelayer(acc, curr, ensSubdomainKey, relayers[index]),
[]
);
return validRelayers;
}
async function getRelayers(ensSubdomainKey) {
let relayers = await fetchRelayers();
const validRelayers = await getValidRelayers(relayers, ensSubdomainKey);
return validRelayers;
}
async function load() {
console.log('Please enter the relay number of the chain you want to obtain:');
console.log('1. Eth, 2. Bsc, 3. Gnosis, 4. Polygon, 5. Arb, 6. Avax, 7. Op');
process.stdin.on('data', async (data) => {
const input = data.toString().trim(); // 将输入转换为字符串并去除多余空格
if (/^[1-7]$/.test(input)) {
let ensSubdomainKey = Object.values(networkConfig.deployments)[input - 1].ensSubdomainKey;
console.log('Start requesting data');
const registeredRelayers = await getRelayers(ensSubdomainKey);
const axiosInstance = axios.create({
timeout: 3000
});
let statuses = [];
for (const registeredRelayer of registeredRelayers) {
try {
console.log(`https://${registeredRelayer.hostname}/status`);
const res = await axiosInstance.get(`https://${registeredRelayer.hostname}/status`);
const statusData = res.data;
if (statusData.rewardAccount && statusData.health.status == 'true') {
statuses.push({
...registeredRelayer,
statusData
});
}
} catch (e) {
console.error(`Failed to fetch status for ${registeredRelayer.hostname}:`);
}
}
statuses.forEach(item => {
console.log({
'hostname': 'https://' + item.hostname + '/',
'ensName': item.ensName,
'stakeBalance': Number(web3.utils.fromWei(item.stakeBalance, 'ether')).toFixed(2)+" TORN",
'tornadoServiceFee': item.statusData.tornadoServiceFee
});
});
} else {
console.log('Invalid input! Please enter a single number between 1-7');
}
});
}
load();