Compare commits
1 Commits
f02a205e05
...
fdd464960e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fdd464960e |
24
Dockerfile
Normal file
24
Dockerfile
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# FROM node 14.21.3-bullseye-slim
|
||||||
|
FROM node@sha256:0f5b374fae506741ff14db84daff2937ae788e88fb48a6c66d15de5ee808ccd3
|
||||||
|
|
||||||
|
RUN apt update && apt install --yes --no-install-recommends wget git apt-transport-https ca-certificates && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
WORKDIR /home/root/tornado-cli
|
||||||
|
|
||||||
|
ENV GIT_REPOSITORY=https://git.tornado.ws/tornadosto/tornado-cli.git
|
||||||
|
ENV GIT_COMMIT_HASH=1ae2aec71d3cfb28911ce4c60bdd35650e93e5e4
|
||||||
|
|
||||||
|
RUN git init && \
|
||||||
|
git remote add origin $GIT_REPOSITORY && \
|
||||||
|
git fetch --depth 1 origin $GIT_COMMIT_HASH && \
|
||||||
|
git checkout $GIT_COMMIT_HASH
|
||||||
|
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
RUN npm install -g pkg@5.8.1
|
||||||
|
|
||||||
|
RUN node scripts/createDeterministicExecutable.js
|
||||||
|
|
||||||
|
RUN printf '#!/bin/sh\ncp /home/root/tornado-cli/tornado-cli.exe /output/' > /copy_out.sh && chmod +x /copy_out.sh
|
||||||
|
|
||||||
|
CMD ["/bin/bash"]
|
||||||
18
README.md
18
README.md
@ -163,3 +163,21 @@ View transaction on block explorer https://goerli.etherscan.io/tx/0x6ded443caed8
|
|||||||
Tornado contract balance is xxx.x ETH
|
Tornado contract balance is xxx.x ETH
|
||||||
Sender account balance is x.xxxxxxx ETH
|
Sender account balance is x.xxxxxxx ETH
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### To verify:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker build -t tornado-cli:latest .
|
||||||
|
```
|
||||||
|
wait for docker to build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker run --rm -v %cd%/output:/output tornado-cli:latest /copy_out.sh
|
||||||
|
```
|
||||||
|
copy exe to current folder in windows
|
||||||
|
|
||||||
|
```bash
|
||||||
|
CertUtil -hashfile output/tornado-cli.exe SHA256
|
||||||
|
CertUtil -hashfile tornado-cli.exe SHA256
|
||||||
|
```
|
||||||
|
compare with the exe in git
|
||||||
|
|||||||
102
cli.js
102
cli.js
@ -74,7 +74,8 @@ const relayerSubdomains = Object.values(config.deployments).map(({ ensSubdomainK
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/** @type {ProgramGlobals} */
|
/** @type {ProgramGlobals} */
|
||||||
const globals = {
|
const globals =
|
||||||
|
{
|
||||||
privateKey: undefined,
|
privateKey: undefined,
|
||||||
web3Instance: undefined,
|
web3Instance: undefined,
|
||||||
relayerWeb3Instance: undefined,
|
relayerWeb3Instance: undefined,
|
||||||
@ -288,7 +289,8 @@ async function generateTransaction(to, encodedData, value = 0, txType = 'other')
|
|||||||
/**
|
/**
|
||||||
* Create deposit object from secret and nullifier
|
* Create deposit object from secret and nullifier
|
||||||
*/
|
*/
|
||||||
function createDeposit({ nullifier, secret }) {
|
function createDeposit({ nullifier, secret })
|
||||||
|
{
|
||||||
let deposit = { nullifier, secret };
|
let deposit = { nullifier, secret };
|
||||||
deposit.preimage = Buffer.concat([deposit.nullifier.leInt2Buff(31), deposit.secret.leInt2Buff(31)]);
|
deposit.preimage = Buffer.concat([deposit.nullifier.leInt2Buff(31), deposit.secret.leInt2Buff(31)]);
|
||||||
deposit.commitment = pedersenHash(deposit.preimage);
|
deposit.commitment = pedersenHash(deposit.preimage);
|
||||||
@ -328,7 +330,8 @@ async function backupInvoice({ currency, amount, netId, commitmentNote, invoiceS
|
|||||||
* @param currency Сurrency
|
* @param currency Сurrency
|
||||||
* @param amount Deposit amount
|
* @param amount Deposit amount
|
||||||
*/
|
*/
|
||||||
async function createInvoice({ currency, amount, chainId }) {
|
async function createInvoice({ currency, amount, chainId })
|
||||||
|
{
|
||||||
const deposit = createDeposit({
|
const deposit = createDeposit({
|
||||||
nullifier: rbigint(31),
|
nullifier: rbigint(31),
|
||||||
secret: rbigint(31)
|
secret: rbigint(31)
|
||||||
@ -422,7 +425,8 @@ async function deposit({ currency, amount, commitmentNote }) {
|
|||||||
* @param {number} amount Tornado instance amount, like 0.1 (ETH or BNB) or 10
|
* @param {number} amount Tornado instance amount, like 0.1 (ETH or BNB) or 10
|
||||||
* @return {Promise<MerkleProof>} Calculated valid merkle tree (proof)
|
* @return {Promise<MerkleProof>} Calculated valid merkle tree (proof)
|
||||||
*/
|
*/
|
||||||
async function generateMerkleProof(deposit, currency, amount) {
|
async function generateMerkleProof(deposit, currency, amount)
|
||||||
|
{
|
||||||
const { web3Instance, multiCallAddress, tornadoInstanceContract } = globals;
|
const { web3Instance, multiCallAddress, tornadoInstanceContract } = globals;
|
||||||
|
|
||||||
// Get all deposit events from smart contract and assemble merkle tree from them
|
// Get all deposit events from smart contract and assemble merkle tree from them
|
||||||
@ -469,13 +473,16 @@ async function generateMerkleProof(deposit, currency, amount) {
|
|||||||
* @param {MerkleProof} [args.merkleProof] Valid merkle tree proof
|
* @param {MerkleProof} [args.merkleProof] Valid merkle tree proof
|
||||||
* @returns {Promise<ProofData>} Proof data
|
* @returns {Promise<ProofData>} Proof data
|
||||||
*/
|
*/
|
||||||
async function generateProof({ deposit, currency, amount, recipient, relayerAddress = 0, fee = 0, refund = 0, merkleProof }) {
|
async function generateProof({ deposit, currency, amount, recipient, relayerAddress = 0, fee = 0, refund = 0, merkleProof })
|
||||||
|
{
|
||||||
// Compute merkle proof of our commitment
|
// Compute merkle proof of our commitment
|
||||||
if (merkleProof === undefined) merkleProof = await generateMerkleProof(deposit, currency, amount);
|
if (merkleProof === undefined)
|
||||||
|
merkleProof = await generateMerkleProof(deposit, currency, amount);
|
||||||
const { root, pathElements, pathIndices } = merkleProof;
|
const { root, pathElements, pathIndices } = merkleProof;
|
||||||
|
|
||||||
// Prepare circuit input
|
// Prepare circuit input
|
||||||
const input = {
|
const input =
|
||||||
|
{
|
||||||
// Public snark inputs
|
// Public snark inputs
|
||||||
root: root,
|
root: root,
|
||||||
nullifierHash: deposit.nullifierHash,
|
nullifierHash: deposit.nullifierHash,
|
||||||
@ -518,65 +525,86 @@ async function generateProof({ deposit, currency, amount, recipient, relayerAddr
|
|||||||
* @param noteString Note to withdraw
|
* @param noteString Note to withdraw
|
||||||
* @param recipient Recipient address
|
* @param recipient Recipient address
|
||||||
*/
|
*/
|
||||||
async function withdraw({ deposit, currency, amount, recipient, relayerURL, refund, privateKey }) {
|
async function withdraw({ deposit, currency, amount, recipient, relayerURL, refund, privateKey })
|
||||||
|
{
|
||||||
const { web3Instance, signerAddress, tornadoProxyAddress, requestOptions, feeOracle, tornadoInstanceAddress, tornadoProxyContract, netSymbol, netId, shouldPromptConfirmation } = globals;
|
const { web3Instance, signerAddress, tornadoProxyAddress, requestOptions, feeOracle, tornadoInstanceAddress, tornadoProxyContract, netSymbol, netId, shouldPromptConfirmation } = globals;
|
||||||
if (currency === netSymbol.toLowerCase() && refund && refund !== '0') {
|
if (currency === netSymbol.toLowerCase() && refund && refund !== '0')
|
||||||
|
{
|
||||||
throw new Error('The ETH purchase is supposed to be 0 for ETH withdrawals');
|
throw new Error('The ETH purchase is supposed to be 0 for ETH withdrawals');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isNaN(Number(refund))) refund = toWei(refund, 'ether');
|
if (!isNaN(Number(refund)))
|
||||||
else refund = toBN(await feeOracle.fetchRefundInETH(currency.toLowerCase()));
|
refund = toWei(refund, 'ether');
|
||||||
|
else
|
||||||
|
refund = toBN(await feeOracle.fetchRefundInETH(currency.toLowerCase()));
|
||||||
|
|
||||||
if (!web3Utils.isAddress(recipient)) {
|
if (!web3Utils.isAddress(recipient))
|
||||||
|
{
|
||||||
throw new Error('Recipient address is not valid');
|
throw new Error('Recipient address is not valid');
|
||||||
}
|
}
|
||||||
|
|
||||||
const depositInfo = await loadDepositData({ amount, currency, deposit });
|
const depositInfo = await loadDepositData({ amount, currency, deposit });
|
||||||
const allDeposits = loadCachedEvents({ type: "deposit", currency, amount });
|
const allDeposits = loadCachedEvents({ type: "deposit", currency, amount });
|
||||||
if ((depositInfo.leafIndex > allDeposits[allDeposits.length - 1].leafIndex - 10) && allDeposits.length > 10){
|
if ((depositInfo.leafIndex > allDeposits[allDeposits.length - 1].leafIndex - 10)
|
||||||
|
&& allDeposits.length > 10)
|
||||||
|
{
|
||||||
console.log("\nWARNING: you're trying to withdraw your deposit too early, there are not enough subsequent deposits to ensure good anonymity level. Read: https://docs.tornado.ws/general/guides/opsec.html");
|
console.log("\nWARNING: you're trying to withdraw your deposit too early, there are not enough subsequent deposits to ensure good anonymity level. Read: https://docs.tornado.ws/general/guides/opsec.html");
|
||||||
if (shouldPromptConfirmation) await promptConfirmation("Continue withdrawal with risks to anonymity? [Y/n]: ")
|
if (shouldPromptConfirmation)
|
||||||
|
await promptConfirmation("Continue withdrawal with risks to anonymity? [Y/n]: ")
|
||||||
}
|
}
|
||||||
const withdrawInfo = await loadWithdrawalData({ amount, currency, deposit });
|
const withdrawInfo = await loadWithdrawalData({ amount, currency, deposit });
|
||||||
if(withdrawInfo) {
|
if(withdrawInfo)
|
||||||
|
{
|
||||||
console.error("\nError: note has already been withdrawn. Use `compliance` command to check deposit and withdrawal info.\n");
|
console.error("\nError: note has already been withdrawn. Use `compliance` command to check deposit and withdrawal info.\n");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (privateKey || globals.privateKey) {
|
if (privateKey || globals.privateKey)
|
||||||
|
{
|
||||||
// using private key
|
// using private key
|
||||||
|
|
||||||
// check if the address of recepient matches with the account of provided private key from environment to prevent accidental use of deposit address for withdrawal transaction.
|
// check if the address of recepient matches with the account of provided private key from environment to prevent accidental use of deposit address for withdrawal transaction.
|
||||||
assert(
|
assert
|
||||||
|
(
|
||||||
recipient.toLowerCase() == signerAddress.toLowerCase(),
|
recipient.toLowerCase() == signerAddress.toLowerCase(),
|
||||||
'Withdrawal recepient mismatches with the account of provided private key from environment file'
|
'Withdrawal recepient mismatches with the account of provided private key from environment file'
|
||||||
);
|
);
|
||||||
const checkBalance = await web3Instance.getBalance(signerAddress);
|
const checkBalance = await web3Instance.getBalance(signerAddress);
|
||||||
assert(checkBalance !== 0, 'You have 0 balance, make sure to fund account by withdrawing from tornado using relayer first');
|
assert
|
||||||
|
(
|
||||||
|
checkBalance !== 0,
|
||||||
|
'You have 0 balance, make sure to fund account by withdrawing from tornado using relayer first'
|
||||||
|
);
|
||||||
|
|
||||||
const { proof, args } = await generateProof({ deposit, currency, amount, recipient, refund });
|
const { proof, args } = await generateProof({ deposit, currency, amount, recipient, refund });
|
||||||
|
|
||||||
console.log('Submitting withdraw transaction');
|
console.log('Submitting withdraw transaction');
|
||||||
await generateTransaction(
|
await generateTransaction
|
||||||
|
(
|
||||||
tornadoProxyAddress,
|
tornadoProxyAddress,
|
||||||
tornadoProxyContract.methods.withdraw(tornadoInstanceAddress, proof, ...args).encodeABI(),
|
tornadoProxyContract.methods.withdraw(tornadoInstanceAddress, proof, ...args).encodeABI(),
|
||||||
toBN(args[5]),
|
toBN(args[5]),
|
||||||
'user_withdrawal'
|
'user_withdrawal'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
let relayerInfo;
|
let relayerInfo;
|
||||||
if (relayerURL) {
|
if (relayerURL)
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
relayerURL = new URL(relayerURL).origin;
|
relayerURL = new URL(relayerURL).origin;
|
||||||
res = await axios.get(relayerURL + '/status', requestOptions);
|
res = await axios.get(relayerURL + '/status', requestOptions);
|
||||||
relayerInfo = res.data;
|
relayerInfo = res.data;
|
||||||
} catch (err) {
|
} catch (err)
|
||||||
|
{
|
||||||
console.error(err);
|
console.error(err);
|
||||||
throw new Error('Cannot get relayer status');
|
throw new Error('Cannot get relayer status');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
const availableRelayers = await getRelayers(netId);
|
const availableRelayers = await getRelayers(netId);
|
||||||
if(availableRelayers.length === 0) throw new Error("Cannot automatically pick a relayer to withdraw your note. Provide relayer manually with `--relayer` cmd option or use private key withdrawal")
|
if(availableRelayers.length === 0) throw new Error("Cannot automatically pick a relayer to withdraw your note. Provide relayer manually with `--relayer` cmd option or use private key withdrawal")
|
||||||
relayerInfo = pickWeightedRandomRelayer(availableRelayers);
|
relayerInfo = pickWeightedRandomRelayer(availableRelayers);
|
||||||
@ -667,9 +695,12 @@ async function withdraw({ deposit, currency, amount, recipient, relayerURL, refu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currency === netSymbol.toLowerCase()) {
|
if (currency === netSymbol.toLowerCase())
|
||||||
|
{
|
||||||
await printETHBalance({ address: recipient, name: 'Recipient' });
|
await printETHBalance({ address: recipient, name: 'Recipient' });
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
await printERC20Balance({ address: recipient, name: 'Recipient' });
|
await printERC20Balance({ address: recipient, name: 'Recipient' });
|
||||||
}
|
}
|
||||||
console.log('Done withdrawal from Tornado Cash');
|
console.log('Done withdrawal from Tornado Cash');
|
||||||
@ -870,6 +901,10 @@ function toDecimals(value, decimals, fixed) {
|
|||||||
// List fetched from https://github.com/ethereum-lists/chains/blob/master/_data/chains
|
// List fetched from https://github.com/ethereum-lists/chains/blob/master/_data/chains
|
||||||
function getExplorerLink() {
|
function getExplorerLink() {
|
||||||
switch (globals.netId) {
|
switch (globals.netId) {
|
||||||
|
case 61:
|
||||||
|
return 'etc.blockscout.com';
|
||||||
|
case 11155111:
|
||||||
|
return 'sepolia.etherscan.io';
|
||||||
case 56:
|
case 56:
|
||||||
return 'bscscan.com';
|
return 'bscscan.com';
|
||||||
case 100:
|
case 100:
|
||||||
@ -894,6 +929,10 @@ function getExplorerLink() {
|
|||||||
// List fetched from https://github.com/trustwallet/assets/tree/master/blockchains
|
// List fetched from https://github.com/trustwallet/assets/tree/master/blockchains
|
||||||
function getCurrentNetworkName() {
|
function getCurrentNetworkName() {
|
||||||
switch (globals.netId) {
|
switch (globals.netId) {
|
||||||
|
case 61:
|
||||||
|
return 'EthereumClassic';
|
||||||
|
case 11155111:
|
||||||
|
return 'Sepolia';
|
||||||
case 56:
|
case 56:
|
||||||
return 'BinanceSmartChain';
|
return 'BinanceSmartChain';
|
||||||
case 100:
|
case 100:
|
||||||
@ -920,6 +959,8 @@ function getCurrentNetworkName() {
|
|||||||
*/
|
*/
|
||||||
function getCurrentNetworkSymbol(chainId) {
|
function getCurrentNetworkSymbol(chainId) {
|
||||||
switch (Number(chainId)) {
|
switch (Number(chainId)) {
|
||||||
|
case 61:
|
||||||
|
return 'ETC';
|
||||||
case 56:
|
case 56:
|
||||||
return 'BNB';
|
return 'BNB';
|
||||||
case 100:
|
case 100:
|
||||||
@ -1399,10 +1440,12 @@ async function fetchEvents({ type, currency, amount }) {
|
|||||||
* Parses Tornado Cash note
|
* Parses Tornado Cash note
|
||||||
* @param {string} noteString the note
|
* @param {string} noteString the note
|
||||||
*/
|
*/
|
||||||
function parseNote(noteString) {
|
function parseNote(noteString)
|
||||||
|
{
|
||||||
const noteRegex = /tornado-(?<currency>\w+)-(?<amount>[\d.]+)-(?<netId>\d+)-0x(?<note>[0-9a-fA-F]{124})/g;
|
const noteRegex = /tornado-(?<currency>\w+)-(?<amount>[\d.]+)-(?<netId>\d+)-0x(?<note>[0-9a-fA-F]{124})/g;
|
||||||
const match = noteRegex.exec(noteString);
|
const match = noteRegex.exec(noteString);
|
||||||
if (!match) {
|
if (!match)
|
||||||
|
{
|
||||||
throw new Error('The note has invalid format');
|
throw new Error('The note has invalid format');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1563,7 +1606,7 @@ async function initNetwork({rpc, chainId, privateKey, torPort, onlyRpc, eventTyp
|
|||||||
}
|
}
|
||||||
|
|
||||||
globals.web3Instance = await createWeb3Instance(rpc)
|
globals.web3Instance = await createWeb3Instance(rpc)
|
||||||
globals.netId = await globals.web3Instance.net.getId();
|
globals.netId = await globals.web3Instance.getChainId()
|
||||||
globals.netName = getCurrentNetworkName();
|
globals.netName = getCurrentNetworkName();
|
||||||
globals.netSymbol = getCurrentNetworkSymbol(globals.netId);
|
globals.netSymbol = getCurrentNetworkSymbol(globals.netId);
|
||||||
|
|
||||||
@ -1635,6 +1678,7 @@ async function init({ rpc, chainId, currency = 'dai', amount = '100', privateKey
|
|||||||
await initNetwork({rpc, chainId, privateKey, torPort, onlyRpc, eventType, relayer});
|
await initNetwork({rpc, chainId, privateKey, torPort, onlyRpc, eventType, relayer});
|
||||||
|
|
||||||
const { netId, web3Instance } = globals;
|
const { netId, web3Instance } = globals;
|
||||||
|
// console.log(netId, chainId);
|
||||||
if (chainId && Number(chainId) !== netId) {
|
if (chainId && Number(chainId) !== netId) {
|
||||||
throw new Error('This note is for a different network. Specify the --rpc option explicitly');
|
throw new Error('This note is for a different network. Specify the --rpc option explicitly');
|
||||||
}
|
}
|
||||||
|
|||||||
91
config.js
91
config.js
@ -114,9 +114,15 @@ module.exports = {
|
|||||||
relayerAggregator: '0xE8F47A78A6D52D317D0D2FFFac56739fE14D1b49',
|
relayerAggregator: '0xE8F47A78A6D52D317D0D2FFFac56739fE14D1b49',
|
||||||
proxy: '0xd90e2f925DA726b50C4Ed8D0Fb90Ad053324F31b',
|
proxy: '0xd90e2f925DA726b50C4Ed8D0Fb90Ad053324F31b',
|
||||||
multicall: '0xeefBa1e63905eF1D7ACbA5a8513c70307C1cE441',
|
multicall: '0xeefBa1e63905eF1D7ACbA5a8513c70307C1cE441',
|
||||||
subgraphs: ['https://gateway.thegraph.com/api/6a217817dd87d33db10beed79b044a91/subgraphs/id/Ec6fVMDVqXTDQZ3c4jxcyV3zBXqkdgMWfhdtCgtqn7Sh', 'https://gateway.thegraph.com/api/8b164501e1862078eff5fb9dda136c6c/subgraphs/id/Ec6fVMDVqXTDQZ3c4jxcyV3zBXqkdgMWfhdtCgtqn7Sh', 'https://tornadocash-rpc.com/subgraphs/name/tornadocash/mainnet-tornado-subgraph'],
|
subgraphs: ['https://gateway.thegraph.com/api/6a217817dd87d33db10beed79b044a91/subgraphs/id/Ec6fVMDVqXTDQZ3c4jxcyV3zBXqkdgMWfhdtCgtqn7Sh',
|
||||||
|
'https://gateway.thegraph.com/api/8b164501e1862078eff5fb9dda136c6c/subgraphs/id/Ec6fVMDVqXTDQZ3c4jxcyV3zBXqkdgMWfhdtCgtqn7Sh',
|
||||||
|
'https://tornadocash-rpc.com/subgraphs/name/tornadocash/mainnet-tornado-subgraph'],
|
||||||
relayerSubgraphs: ['https://gateway.thegraph.com/api/6a217817dd87d33db10beed79b044a91/subgraphs/id/DgKwfAbLfynpiq7fDJy59LDnVnia4Y5nYeRDBYi9qezc', 'https://gateway.thegraph.com/api/8b164501e1862078eff5fb9dda136c6c/subgraphs/id/DgKwfAbLfynpiq7fDJy59LDnVnia4Y5nYeRDBYi9qezc', 'https://tornadocash-rpc.com/subgraphs/name/tornadocash/tornado-relayer-registry'],
|
relayerSubgraphs: ['https://gateway.thegraph.com/api/6a217817dd87d33db10beed79b044a91/subgraphs/id/DgKwfAbLfynpiq7fDJy59LDnVnia4Y5nYeRDBYi9qezc', 'https://gateway.thegraph.com/api/8b164501e1862078eff5fb9dda136c6c/subgraphs/id/DgKwfAbLfynpiq7fDJy59LDnVnia4Y5nYeRDBYi9qezc', 'https://tornadocash-rpc.com/subgraphs/name/tornadocash/tornado-relayer-registry'],
|
||||||
defaultRpcs: ['https://ethereum.blockpi.network/v1/rpc/public', 'https://eth.drpc.org', 'https://ethereum-rpc.publicnode.com', 'https://mainnet.chainnodes.org/3ae3d849-a613-4917-a56e-080f181aa4da', 'https://tornadocash-rpc.com']
|
defaultRpcs: ['https://ethereum.blockpi.network/v1/rpc/public',
|
||||||
|
'https://eth.drpc.org',
|
||||||
|
'https://ethereum-rpc.publicnode.com',
|
||||||
|
'https://mainnet.chainnodes.org/3ae3d849-a613-4917-a56e-080f181aa4da',
|
||||||
|
'https://tornadocash-rpc.com']
|
||||||
},
|
},
|
||||||
netId56: {
|
netId56: {
|
||||||
tokens: {
|
tokens: {
|
||||||
@ -143,7 +149,12 @@ module.exports = {
|
|||||||
proxy: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
|
proxy: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
|
||||||
multicall: '0x41263cBA59EB80dC200F3E2544eda4ed6A90E76C',
|
multicall: '0x41263cBA59EB80dC200F3E2544eda4ed6A90E76C',
|
||||||
subgraphs: ['https://gateway.thegraph.com/api/6a217817dd87d33db10beed79b044a91/subgraphs/id/CiwGzefDBZCavXRPnwarnnF8xDDoLw4boBuySomJWYnV', 'https://tornadocash-rpc.com/subgraphs/name/tornadocash/bsc-tornado-subgraph', 'https://gateway.thegraph.com/api/8b164501e1862078eff5fb9dda136c6c/subgraphs/id/CiwGzefDBZCavXRPnwarnnF8xDDoLw4boBuySomJWYnV'],
|
subgraphs: ['https://gateway.thegraph.com/api/6a217817dd87d33db10beed79b044a91/subgraphs/id/CiwGzefDBZCavXRPnwarnnF8xDDoLw4boBuySomJWYnV', 'https://tornadocash-rpc.com/subgraphs/name/tornadocash/bsc-tornado-subgraph', 'https://gateway.thegraph.com/api/8b164501e1862078eff5fb9dda136c6c/subgraphs/id/CiwGzefDBZCavXRPnwarnnF8xDDoLw4boBuySomJWYnV'],
|
||||||
defaultRpcs: ['https://bsc-rpc.publicnode.com', 'https://endpoints.omniatech.io/v1/bsc/mainnet/public', 'https://bsc-mainnet.chainnodes.org/3ae3d849-a613-4917-a56e-080f181aa4da', 'https://bsc-dataseed1.ninicoin.io', 'https://bsc.drpc.org', 'https://bsc-mainnet.public.blastapi.io']
|
defaultRpcs: ['https://bsc-rpc.publicnode.com',
|
||||||
|
'https://endpoints.omniatech.io/v1/bsc/mainnet/public',
|
||||||
|
'https://bsc-mainnet.chainnodes.org/3ae3d849-a613-4917-a56e-080f181aa4da',
|
||||||
|
'https://bsc-dataseed1.ninicoin.io',
|
||||||
|
'https://bsc.drpc.org',
|
||||||
|
'https://bsc-mainnet.public.blastapi.io']
|
||||||
},
|
},
|
||||||
netId100: {
|
netId100: {
|
||||||
tokens: {
|
tokens: {
|
||||||
@ -277,6 +288,80 @@ module.exports = {
|
|||||||
multicall: '0x142E2FEaC30d7fc3b61f9EE85FCCad8e560154cc',
|
multicall: '0x142E2FEaC30d7fc3b61f9EE85FCCad8e560154cc',
|
||||||
subgraphs: ['https://gateway.thegraph.com/api/6a217817dd87d33db10beed79b044a91/subgraphs/id/GvkbnEVhLD6KArXpEzLFtSKRmspBW29ApKFqR5FjuP2P', 'https://gateway.thegraph.com/api/8b164501e1862078eff5fb9dda136c6c/subgraphs/id/GvkbnEVhLD6KArXpEzLFtSKRmspBW29ApKFqR5FjuP2P', 'https://tornadocash-rpc.com/subgraphs/name/tornadocash/optimism-tornado-subgraph'],
|
subgraphs: ['https://gateway.thegraph.com/api/6a217817dd87d33db10beed79b044a91/subgraphs/id/GvkbnEVhLD6KArXpEzLFtSKRmspBW29ApKFqR5FjuP2P', 'https://gateway.thegraph.com/api/8b164501e1862078eff5fb9dda136c6c/subgraphs/id/GvkbnEVhLD6KArXpEzLFtSKRmspBW29ApKFqR5FjuP2P', 'https://tornadocash-rpc.com/subgraphs/name/tornadocash/optimism-tornado-subgraph'],
|
||||||
defaultRpcs: ['https://optimism.blockpi.network/v1/rpc/public', 'https://optimism-mainnet.chainnodes.org/3ae3d849-a613-4917-a56e-080f181aa4da', 'https://endpoints.omniatech.io/v1/op/mainnet/public', 'https://optimism-mainnet.public.blastapi.io', 'https://optimism.drpc.org']
|
defaultRpcs: ['https://optimism.blockpi.network/v1/rpc/public', 'https://optimism-mainnet.chainnodes.org/3ae3d849-a613-4917-a56e-080f181aa4da', 'https://endpoints.omniatech.io/v1/op/mainnet/public', 'https://optimism-mainnet.public.blastapi.io', 'https://optimism.drpc.org']
|
||||||
|
},
|
||||||
|
netId11155111: {
|
||||||
|
tokens:
|
||||||
|
{
|
||||||
|
eth:
|
||||||
|
{
|
||||||
|
instanceAddress:
|
||||||
|
{
|
||||||
|
0.1: '0x8C4A04d872a6C1BE37964A21ba3a138525dFF50b',
|
||||||
|
1: '0x8cc930096B4Df705A007c4A039BDFA1320Ed2508',
|
||||||
|
10: '0x8D10d506D29Fc62ABb8A290B99F66dB27Fc43585',
|
||||||
|
},
|
||||||
|
deployedBlockNumber:
|
||||||
|
{
|
||||||
|
0.1: 5594400,
|
||||||
|
1: 5594401,
|
||||||
|
10: 5594402,
|
||||||
|
},
|
||||||
|
miningEnabled: false,
|
||||||
|
symbol: 'ETH',
|
||||||
|
decimals: 18
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ensSubdomainKey: 'sepolia-tornado',
|
||||||
|
firstDeploymentTransaction: '0x7c7260a119bd0682b785da8860def277877ffaa50c2068ee78d6cb51f50bdc1f',
|
||||||
|
proxy: '0x1572AFE6949fdF51Cb3E0856216670ae9Ee160Ee',
|
||||||
|
multicall: '0x53c43764255c17bd724f74c4ef150724ac50a3ed',
|
||||||
|
subgraphs: ['https://gateway.thegraph.com/api/6a217817dd87d33db10beed79b044a91/subgraphs/id/8kJGz92AYUm72wfyUoze1as3E11ynDSTZM8emiRWrRPy',
|
||||||
|
'https://gateway.thegraph.com/api/8b164501e1862078eff5fb9dda136c6c/subgraphs/id/8kJGz92AYUm72wfyUoze1as3E11ynDSTZM8emiRWrRPy',
|
||||||
|
'https://tornadocash-rpc.com/subgraphs/name/tornadocash/sepolia-tornado-subgraph'
|
||||||
|
],
|
||||||
|
defaultRpcs: ['https://ethereum-sepolia-rpc.publicnode.com',
|
||||||
|
'https://sepolia.chainnodes.org/61b7de01-6cc4-40dc-a6c2-b6e4a61bb042',
|
||||||
|
'https://sepolia.drpc.org',
|
||||||
|
'https://eth-sepolia.g.alchemy.com/v2/demo',
|
||||||
|
'https://eth-sepolia.public.blastapi.io',
|
||||||
|
'https://eth-sepolia.api.onfinality.io/public']
|
||||||
|
|
||||||
|
},
|
||||||
|
netId61:
|
||||||
|
{
|
||||||
|
tokens:
|
||||||
|
{
|
||||||
|
etc:
|
||||||
|
{
|
||||||
|
instanceAddress:
|
||||||
|
{
|
||||||
|
1: '0x2f56d5aFC058B8734350B162EFEe75ee48f034e0',
|
||||||
|
10: '0x59fCB629A23e8eD0a60A0188771E221042260118',
|
||||||
|
100: '0x784B3a7a7981B959bd8d9D9e73c2013BE819Fbf2',
|
||||||
|
},
|
||||||
|
deployedBlockNumber:
|
||||||
|
{
|
||||||
|
1: 22385618,
|
||||||
|
10: 22385618,
|
||||||
|
100: 22385618,
|
||||||
|
},
|
||||||
|
miningEnabled: false,
|
||||||
|
symbol: 'ETC',
|
||||||
|
decimals: 18
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ensSubdomainKey: 'etc-tornado',
|
||||||
|
firstDeploymentTransaction: '0x4d9232046d3503138525bb3b921e131153d02b436f9f81426f52929e50ab359e',
|
||||||
|
proxy: '0xac97AB4fBd872ea762974CbBB0Ee72351afe16F3',
|
||||||
|
multicall: '0xA52EE88C0F24EF8b96C3989cAb42cfC6008041A8',
|
||||||
|
subgraphs: ['https://graph.torndao.com/subgraphs/name/tornadocash/etc-tornado-subgraph'],
|
||||||
|
defaultRpcs: ['https://etc.etcdesktop.com',
|
||||||
|
'https://etc.rivet.link',
|
||||||
|
'https://etc.mytokenpocket.vip',
|
||||||
|
'https://0xrpc.io/etc',
|
||||||
|
'https://geth-at.etc-network.info',
|
||||||
|
'https://besu-at.etc-network.info'],
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
BIN
tornado-cli.exe
BIN
tornado-cli.exe
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user