Initial commit
This commit is contained in:
commit
e9d78d3a7f
27
.eslintrc.js
Normal file
27
.eslintrc.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
module.exports = {
|
||||||
|
'env': {
|
||||||
|
'browser': false,
|
||||||
|
'node': true,
|
||||||
|
'commonjs': true,
|
||||||
|
'es2022': true
|
||||||
|
},
|
||||||
|
'extends': 'eslint:recommended',
|
||||||
|
'rules': {
|
||||||
|
'indent': [
|
||||||
|
'error',
|
||||||
|
2
|
||||||
|
],
|
||||||
|
'linebreak-style': [
|
||||||
|
'error',
|
||||||
|
'unix'
|
||||||
|
],
|
||||||
|
'quotes': [
|
||||||
|
'error',
|
||||||
|
'single'
|
||||||
|
],
|
||||||
|
'semi': [
|
||||||
|
'error',
|
||||||
|
'always'
|
||||||
|
],
|
||||||
|
}
|
||||||
|
};
|
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
node_modules
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
|
backup*
|
||||||
|
*.zip
|
24
README.md
Normal file
24
README.md
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Offline Tornado Cash Note Generation Tool
|
||||||
|
|
||||||
|
This tool allows you to create Tornado Cash deposit transaction data offline (So your note data is never exposed to online!)
|
||||||
|
|
||||||
|
### How to use?
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# This will install all the necessary libraries
|
||||||
|
yarn
|
||||||
|
|
||||||
|
node ./tornadoNote.js <CHAIN_ID> <CURRENCY> <AMOUNT>
|
||||||
|
|
||||||
|
node ./tornadoNote.js --help
|
||||||
|
|
||||||
|
node ./tornadoNote.js 1 eth 0.1
|
||||||
|
|
||||||
|
node ./tornadoNote.js 1 dai 10000
|
||||||
|
|
||||||
|
node ./tornadoNote.js 56 bnb 100
|
||||||
|
```
|
||||||
|
|
||||||
|
Will also create backup similar with how Tornado UI or tornado-cli generates it
|
||||||
|
|
||||||
|
Use Transaction Data to submit ethereum transaction on https://myetherwallet.com, https://mycrypto.com, or https://remix.ethereum.org
|
228
abi/ERC20.abi.json
Normal file
228
abi/ERC20.abi.json
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [],
|
||||||
|
"name": "totalSupply",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [],
|
||||||
|
"name": "_totalSupply",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "who",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "balanceOf",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "to",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "value",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "transfer",
|
||||||
|
"outputs": [],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"anonymous": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "owner",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "spender",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "value",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "Approval",
|
||||||
|
"type": "event"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"anonymous": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "from",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "to",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "value",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "Transfer",
|
||||||
|
"type": "event"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "owner",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "spender",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "allowance",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "from",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "to",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "value",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "transferFrom",
|
||||||
|
"outputs": [],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "spender",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "value",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "approve",
|
||||||
|
"outputs": [],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "owner",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "nonces",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{ "internalType": "address", "name": "owner", "type": "address" },
|
||||||
|
{ "internalType": "address", "name": "spender", "type": "address" },
|
||||||
|
{ "internalType": "uint256", "name": "amount", "type": "uint256" },
|
||||||
|
{ "internalType": "uint256", "name": "deadline", "type": "uint256" },
|
||||||
|
{ "internalType": "uint8", "name": "v", "type": "uint8" },
|
||||||
|
{ "internalType": "bytes32", "name": "r", "type": "bytes32" },
|
||||||
|
{ "internalType": "bytes32", "name": "s", "type": "bytes32" }
|
||||||
|
],
|
||||||
|
"name": "permit",
|
||||||
|
"outputs": [],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
}
|
||||||
|
]
|
237
abi/TornadoProxy.abi.json
Normal file
237
abi/TornadoProxy.abi.json
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "bytes32",
|
||||||
|
"name": "_tornadoTrees",
|
||||||
|
"type": "bytes32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "bytes32",
|
||||||
|
"name": "_governance",
|
||||||
|
"type": "bytes32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "bytes32[]",
|
||||||
|
"name": "_instances",
|
||||||
|
"type": "bytes32[]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "constructor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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": "bytes32[]",
|
||||||
|
"name": "domains",
|
||||||
|
"type": "bytes32[]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "bulkResolve",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address[]",
|
||||||
|
"name": "result",
|
||||||
|
"type": "address[]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "governance",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "contract ITornadoInstance",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "instances",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "bool",
|
||||||
|
"name": "",
|
||||||
|
"type": "bool"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "bytes32",
|
||||||
|
"name": "node",
|
||||||
|
"type": "bytes32"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "resolve",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "tornadoTrees",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "contract ITornadoTrees",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"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": "_instance",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "bool",
|
||||||
|
"name": "_update",
|
||||||
|
"type": "bool"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "updateInstance",
|
||||||
|
"outputs": [],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"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"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "contract IERC20",
|
||||||
|
"name": "_token",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address payable",
|
||||||
|
"name": "_to",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "_balance",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "rescueTokens",
|
||||||
|
"outputs": [],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
}
|
||||||
|
]
|
533
networkConfig.js
Normal file
533
networkConfig.js
Normal file
@ -0,0 +1,533 @@
|
|||||||
|
const blockSyncInterval = 10000;
|
||||||
|
const enabledChains = ['1', '10', '56', '100', '137', '42161', '43114', '11155111'];
|
||||||
|
const networkConfig = {
|
||||||
|
netId1: {
|
||||||
|
rpcCallRetryAttempt: 15,
|
||||||
|
gasPrices: {
|
||||||
|
instant: 80,
|
||||||
|
fast: 50,
|
||||||
|
standard: 25,
|
||||||
|
low: 8
|
||||||
|
},
|
||||||
|
nativeCurrency: 'eth',
|
||||||
|
currencyName: 'ETH',
|
||||||
|
explorerUrl: {
|
||||||
|
tx: 'https://etherscan.io/tx/',
|
||||||
|
address: 'https://etherscan.io/address/',
|
||||||
|
block: 'https://etherscan.io/block/'
|
||||||
|
},
|
||||||
|
merkleTreeHeight: 20,
|
||||||
|
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
|
||||||
|
networkName: 'Ethereum Mainnet',
|
||||||
|
deployedBlock: 9116966,
|
||||||
|
rpcUrls: {
|
||||||
|
tornadoRPC: {
|
||||||
|
name: 'Tornado RPC',
|
||||||
|
url: 'https://tornadocash-rpc.com/mainnet'
|
||||||
|
},
|
||||||
|
chainnodes: {
|
||||||
|
name: 'Chainnodes RPC',
|
||||||
|
url: 'https://mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
|
||||||
|
},
|
||||||
|
mevblockerRPC: {
|
||||||
|
name: 'MevblockerRPC',
|
||||||
|
url: 'https://rpc.mevblocker.io'
|
||||||
|
},
|
||||||
|
oneRPC: {
|
||||||
|
name: '1RPC',
|
||||||
|
url: 'https://1rpc.io/eth'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
multicall: '0xeefba1e63905ef1d7acba5a8513c70307c1ce441',
|
||||||
|
routerContract: '0xd90e2f925DA726b50C4Ed8D0Fb90Ad053324F31b',
|
||||||
|
registryContract: '0x58E8dCC13BE9780fC42E8723D8EaD4CF46943dF2',
|
||||||
|
echoContractAccount: '0x9B27DD5Bb15d42DC224FCD0B7caEbBe16161Df42',
|
||||||
|
aggregatorContract: '0xE8F47A78A6D52D317D0D2FFFac56739fE14D1b49',
|
||||||
|
tokens: {
|
||||||
|
eth: {
|
||||||
|
instanceAddress: {
|
||||||
|
'0.1': '0x12D66f87A04A9E220743712cE6d9bB1B5616B8Fc',
|
||||||
|
'1': '0x47CE0C6eD5B0Ce3d3A51fdb1C52DC66a7c3c2936',
|
||||||
|
'10': '0x910Cbd523D972eb0a6f4cAe4618aD62622b39DbF',
|
||||||
|
'100': '0xA160cdAB225685dA1d56aa342Ad8841c3b53f291'
|
||||||
|
},
|
||||||
|
symbol: 'ETH',
|
||||||
|
decimals: 18
|
||||||
|
},
|
||||||
|
dai: {
|
||||||
|
instanceAddress: {
|
||||||
|
'100': '0xD4B88Df4D29F5CedD6857912842cff3b20C8Cfa3',
|
||||||
|
'1000': '0xFD8610d20aA15b7B2E3Be39B396a1bC3516c7144',
|
||||||
|
'10000': '0x07687e702b410Fa43f4cB4Af7FA097918ffD2730',
|
||||||
|
'100000': '0x23773E65ed146A459791799d01336DB287f25334'
|
||||||
|
},
|
||||||
|
tokenAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
|
||||||
|
symbol: 'DAI',
|
||||||
|
decimals: 18,
|
||||||
|
gasLimit: '55000'
|
||||||
|
},
|
||||||
|
cdai: {
|
||||||
|
instanceAddress: {
|
||||||
|
'5000': '0x22aaA7720ddd5388A3c0A3333430953C68f1849b',
|
||||||
|
'50000': '0x03893a7c7463AE47D46bc7f091665f1893656003',
|
||||||
|
'500000': '0x2717c5e28cf931547B621a5dddb772Ab6A35B701',
|
||||||
|
'5000000': '0xD21be7248e0197Ee08E0c20D4a96DEBdaC3D20Af'
|
||||||
|
},
|
||||||
|
tokenAddress: '0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643',
|
||||||
|
symbol: 'cDAI',
|
||||||
|
decimals: 8,
|
||||||
|
gasLimit: '425000'
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Instances frozen due to sanctions
|
||||||
|
usdc: {
|
||||||
|
instanceAddress: {
|
||||||
|
'100': '0xd96f2B1c14Db8458374d9Aca76E26c3D18364307',
|
||||||
|
'1000': '0x4736dCf1b7A3d580672CcE6E7c65cd5cc9cFBa9D'
|
||||||
|
},
|
||||||
|
tokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
|
||||||
|
symbol: 'USDC',
|
||||||
|
decimals: 6,
|
||||||
|
gasLimit: '80000'
|
||||||
|
},
|
||||||
|
usdt: {
|
||||||
|
instanceAddress: {
|
||||||
|
'100': '0x169AD27A470D064DEDE56a2D3ff727986b15D52B',
|
||||||
|
'1000': '0x0836222F2B2B24A3F36f98668Ed8F0B38D1a872f'
|
||||||
|
},
|
||||||
|
tokenAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
|
||||||
|
symbol: 'USDT',
|
||||||
|
decimals: 6,
|
||||||
|
gasLimit: '100000'
|
||||||
|
},
|
||||||
|
**/
|
||||||
|
wbtc: {
|
||||||
|
instanceAddress: {
|
||||||
|
'0.1': '0x178169B423a011fff22B9e3F3abeA13414dDD0F1',
|
||||||
|
'1': '0x610B717796ad172B316836AC95a2ffad065CeaB4',
|
||||||
|
'10': '0xbB93e510BbCD0B7beb5A853875f9eC60275CF498'
|
||||||
|
},
|
||||||
|
tokenAddress: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
|
||||||
|
symbol: 'WBTC',
|
||||||
|
decimals: 8,
|
||||||
|
gasLimit: '85000'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ensSubdomainKey: 'mainnet-tornado',
|
||||||
|
pollInterval: 15,
|
||||||
|
constants: {
|
||||||
|
GOVERNANCE_BLOCK: 11474695,
|
||||||
|
NOTE_ACCOUNT_BLOCK: 11842486,
|
||||||
|
ENCRYPTED_NOTES_BLOCK: 14248730,
|
||||||
|
MINING_BLOCK_TIME: 15
|
||||||
|
},
|
||||||
|
'torn.contract.tornadocash.eth': '0x77777FeDdddFfC19Ff86DB637967013e6C6A116C',
|
||||||
|
'governance.contract.tornadocash.eth': '0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce',
|
||||||
|
'tornado-router.contract.tornadocash.eth': '0xd90e2f925DA726b50C4Ed8D0Fb90Ad053324F31b',
|
||||||
|
'staking-rewards.contract.tornadocash.eth': '0x5B3f656C80E8ddb9ec01Dd9018815576E9238c29'
|
||||||
|
},
|
||||||
|
netId56: {
|
||||||
|
rpcCallRetryAttempt: 15,
|
||||||
|
gasPrices: {
|
||||||
|
instant: 5,
|
||||||
|
fast: 5,
|
||||||
|
standard: 5,
|
||||||
|
low: 5
|
||||||
|
},
|
||||||
|
nativeCurrency: 'bnb',
|
||||||
|
currencyName: 'BNB',
|
||||||
|
explorerUrl: {
|
||||||
|
tx: 'https://bscscan.com/tx/',
|
||||||
|
address: 'https://bscscan.com/address/',
|
||||||
|
block: 'https://bscscan.com/block/'
|
||||||
|
},
|
||||||
|
merkleTreeHeight: 20,
|
||||||
|
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
|
||||||
|
networkName: 'Binance Smart Chain',
|
||||||
|
deployedBlock: 8158799,
|
||||||
|
multicall: '0x41263cba59eb80dc200f3e2544eda4ed6a90e76c',
|
||||||
|
echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
|
||||||
|
rpcUrls: {
|
||||||
|
tornadoRPC: {
|
||||||
|
name: 'Tornado RPC',
|
||||||
|
url: 'https://tornadocash-rpc.com/bsc'
|
||||||
|
},
|
||||||
|
chainnodes: {
|
||||||
|
name: 'Chainnodes RPC',
|
||||||
|
url: 'https://bsc-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
|
||||||
|
},
|
||||||
|
oneRPC: {
|
||||||
|
name: '1RPC',
|
||||||
|
url: 'https://1rpc.io/bnb'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tokens: {
|
||||||
|
bnb: {
|
||||||
|
instanceAddress: {
|
||||||
|
'0.1': '0x84443CFd09A48AF6eF360C6976C5392aC5023a1F',
|
||||||
|
'1': '0xd47438C816c9E7f2E2888E060936a499Af9582b3',
|
||||||
|
'10': '0x330bdFADE01eE9bF63C209Ee33102DD334618e0a',
|
||||||
|
'100': '0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD'
|
||||||
|
},
|
||||||
|
symbol: 'BNB',
|
||||||
|
decimals: 18
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ensSubdomainKey: 'bsc-tornado',
|
||||||
|
pollInterval: 10,
|
||||||
|
constants: {
|
||||||
|
NOTE_ACCOUNT_BLOCK: 8159269,
|
||||||
|
ENCRYPTED_NOTES_BLOCK: 8159269
|
||||||
|
},
|
||||||
|
'tornado-proxy-light.contract.tornadocash.eth': '0x0D5550d52428E7e3175bfc9550207e4ad3859b17'
|
||||||
|
},
|
||||||
|
netId137: {
|
||||||
|
rpcCallRetryAttempt: 15,
|
||||||
|
gasPrices: {
|
||||||
|
instant: 100,
|
||||||
|
fast: 75,
|
||||||
|
standard: 50,
|
||||||
|
low: 30
|
||||||
|
},
|
||||||
|
nativeCurrency: 'matic',
|
||||||
|
currencyName: 'MATIC',
|
||||||
|
explorerUrl: {
|
||||||
|
tx: 'https://polygonscan.com/tx/',
|
||||||
|
address: 'https://polygonscan.com/address/',
|
||||||
|
block: 'https://polygonscan.com/block/'
|
||||||
|
},
|
||||||
|
merkleTreeHeight: 20,
|
||||||
|
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
|
||||||
|
networkName: 'Polygon (Matic) Network',
|
||||||
|
deployedBlock: 16257962,
|
||||||
|
multicall: '0x11ce4B23bD875D7F5C6a31084f55fDe1e9A87507',
|
||||||
|
echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
|
||||||
|
rpcUrls: {
|
||||||
|
chainnodes: {
|
||||||
|
name: 'Chainnodes RPC',
|
||||||
|
url: 'https://polygon-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
|
||||||
|
},
|
||||||
|
oneRpc: {
|
||||||
|
name: '1RPC',
|
||||||
|
url: 'https://1rpc.io/matic'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tokens: {
|
||||||
|
matic: {
|
||||||
|
instanceAddress: {
|
||||||
|
'100': '0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD',
|
||||||
|
'1000': '0xdf231d99Ff8b6c6CBF4E9B9a945CBAcEF9339178',
|
||||||
|
'10000': '0xaf4c0B70B2Ea9FB7487C7CbB37aDa259579fe040',
|
||||||
|
'100000': '0xa5C2254e4253490C54cef0a4347fddb8f75A4998'
|
||||||
|
},
|
||||||
|
symbol: 'MATIC',
|
||||||
|
decimals: 18
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ensSubdomainKey: 'polygon-tornado',
|
||||||
|
pollInterval: 10,
|
||||||
|
constants: {
|
||||||
|
NOTE_ACCOUNT_BLOCK: 16257996,
|
||||||
|
ENCRYPTED_NOTES_BLOCK: 16257996
|
||||||
|
},
|
||||||
|
'tornado-proxy-light.contract.tornadocash.eth': '0x0D5550d52428E7e3175bfc9550207e4ad3859b17'
|
||||||
|
},
|
||||||
|
netId10: {
|
||||||
|
rpcCallRetryAttempt: 15,
|
||||||
|
gasPrices: {
|
||||||
|
instant: 0.001,
|
||||||
|
fast: 0.001,
|
||||||
|
standard: 0.001,
|
||||||
|
low: 0.001
|
||||||
|
},
|
||||||
|
nativeCurrency: 'eth',
|
||||||
|
currencyName: 'ETH',
|
||||||
|
explorerUrl: {
|
||||||
|
tx: 'https://optimistic.etherscan.io/tx/',
|
||||||
|
address: 'https://optimistic.etherscan.io/address/',
|
||||||
|
block: 'https://optimistic.etherscan.io/block/'
|
||||||
|
},
|
||||||
|
merkleTreeHeight: 20,
|
||||||
|
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
|
||||||
|
networkName: 'Optimism',
|
||||||
|
deployedBlock: 2243689,
|
||||||
|
multicall: '0x35A6Cdb2C9AD4a45112df4a04147EB07dFA01aB7',
|
||||||
|
echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
|
||||||
|
ovmGasPriceOracleContract: '0x420000000000000000000000000000000000000F',
|
||||||
|
rpcUrls: {
|
||||||
|
tornadoRPC: {
|
||||||
|
name: 'Tornado RPC',
|
||||||
|
url: 'https://tornadocash-rpc.com/op'
|
||||||
|
},
|
||||||
|
chainnodes: {
|
||||||
|
name: 'Chainnodes RPC',
|
||||||
|
url: 'https://optimism-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
|
||||||
|
},
|
||||||
|
oneRpc: {
|
||||||
|
name: '1RPC',
|
||||||
|
url: 'https://1rpc.io/op'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tokens: {
|
||||||
|
eth: {
|
||||||
|
instanceAddress: {
|
||||||
|
'0.1': '0x84443CFd09A48AF6eF360C6976C5392aC5023a1F',
|
||||||
|
'1': '0xd47438C816c9E7f2E2888E060936a499Af9582b3',
|
||||||
|
'10': '0x330bdFADE01eE9bF63C209Ee33102DD334618e0a',
|
||||||
|
'100': '0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD'
|
||||||
|
},
|
||||||
|
symbol: 'ETH',
|
||||||
|
decimals: 18
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ensSubdomainKey: 'optimism-tornado',
|
||||||
|
pollInterval: 15,
|
||||||
|
constants: {
|
||||||
|
NOTE_ACCOUNT_BLOCK: 2243694,
|
||||||
|
ENCRYPTED_NOTES_BLOCK: 2243694
|
||||||
|
},
|
||||||
|
'tornado-proxy-light.contract.tornadocash.eth': '0x0D5550d52428E7e3175bfc9550207e4ad3859b17'
|
||||||
|
},
|
||||||
|
netId42161: {
|
||||||
|
rpcCallRetryAttempt: 15,
|
||||||
|
gasPrices: {
|
||||||
|
instant: 4,
|
||||||
|
fast: 3,
|
||||||
|
standard: 2.52,
|
||||||
|
low: 2.29
|
||||||
|
},
|
||||||
|
nativeCurrency: 'eth',
|
||||||
|
currencyName: 'ETH',
|
||||||
|
explorerUrl: {
|
||||||
|
tx: 'https://arbiscan.io/tx/',
|
||||||
|
address: 'https://arbiscan.io/address/',
|
||||||
|
block: 'https://arbiscan.io/block/'
|
||||||
|
},
|
||||||
|
merkleTreeHeight: 20,
|
||||||
|
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
|
||||||
|
networkName: 'Arbitrum One',
|
||||||
|
deployedBlock: 3430648,
|
||||||
|
multicall: '0x842eC2c7D803033Edf55E478F461FC547Bc54EB2',
|
||||||
|
echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
|
||||||
|
rpcUrls: {
|
||||||
|
tornadoRPC: {
|
||||||
|
name: 'Tornado RPC',
|
||||||
|
url: 'https://tornadocash-rpc.com/arbitrum'
|
||||||
|
},
|
||||||
|
chainnodes: {
|
||||||
|
name: 'Chainnodes RPC',
|
||||||
|
url: 'https://arbitrum-one.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
|
||||||
|
},
|
||||||
|
oneRpc: {
|
||||||
|
name: '1rpc',
|
||||||
|
url: 'https://1rpc.io/arb'
|
||||||
|
},
|
||||||
|
Arbitrum: {
|
||||||
|
name: 'Arbitrum RPC',
|
||||||
|
url: 'https://arb1.arbitrum.io/rpc'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tokens: {
|
||||||
|
eth: {
|
||||||
|
instanceAddress: {
|
||||||
|
'0.1': '0x84443CFd09A48AF6eF360C6976C5392aC5023a1F',
|
||||||
|
'1': '0xd47438C816c9E7f2E2888E060936a499Af9582b3',
|
||||||
|
'10': '0x330bdFADE01eE9bF63C209Ee33102DD334618e0a',
|
||||||
|
'100': '0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD'
|
||||||
|
},
|
||||||
|
symbol: 'ETH',
|
||||||
|
decimals: 18
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ensSubdomainKey: 'arbitrum-tornado',
|
||||||
|
pollInterval: 15,
|
||||||
|
constants: {
|
||||||
|
NOTE_ACCOUNT_BLOCK: 3430605,
|
||||||
|
ENCRYPTED_NOTES_BLOCK: 3430605
|
||||||
|
},
|
||||||
|
'tornado-proxy-light.contract.tornadocash.eth': '0x0D5550d52428E7e3175bfc9550207e4ad3859b17'
|
||||||
|
},
|
||||||
|
netId100: {
|
||||||
|
rpcCallRetryAttempt: 15,
|
||||||
|
gasPrices: {
|
||||||
|
instant: 6,
|
||||||
|
fast: 5,
|
||||||
|
standard: 4,
|
||||||
|
low: 1
|
||||||
|
},
|
||||||
|
nativeCurrency: 'xdai',
|
||||||
|
currencyName: 'xDAI',
|
||||||
|
explorerUrl: {
|
||||||
|
tx: 'https://blockscout.com/xdai/mainnet/tx/',
|
||||||
|
address: 'https://blockscout.com/xdai/mainnet/address/',
|
||||||
|
block: 'https://blockscout.com/xdai/mainnet/block/'
|
||||||
|
},
|
||||||
|
merkleTreeHeight: 20,
|
||||||
|
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
|
||||||
|
networkName: 'Gnosis Chain',
|
||||||
|
deployedBlock: 17754561,
|
||||||
|
multicall: '0xb5b692a88bdfc81ca69dcb1d924f59f0413a602a',
|
||||||
|
echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
|
||||||
|
rpcUrls: {
|
||||||
|
tornadoRPC: {
|
||||||
|
name: 'Tornado RPC',
|
||||||
|
url: 'https://tornadocash-rpc.com/gnosis'
|
||||||
|
},
|
||||||
|
chainnodes: {
|
||||||
|
name: 'Chainnodes RPC',
|
||||||
|
url: 'https://gnosis-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
|
||||||
|
},
|
||||||
|
blockPi: {
|
||||||
|
name: 'BlockPi',
|
||||||
|
url: 'https://gnosis.blockpi.network/v1/rpc/public'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tokens: {
|
||||||
|
xdai: {
|
||||||
|
instanceAddress: {
|
||||||
|
'100': '0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD',
|
||||||
|
'1000': '0xdf231d99Ff8b6c6CBF4E9B9a945CBAcEF9339178',
|
||||||
|
'10000': '0xaf4c0B70B2Ea9FB7487C7CbB37aDa259579fe040',
|
||||||
|
'100000': '0xa5C2254e4253490C54cef0a4347fddb8f75A4998'
|
||||||
|
},
|
||||||
|
symbol: 'xDAI',
|
||||||
|
decimals: 18
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ensSubdomainKey: 'gnosis-tornado',
|
||||||
|
pollInterval: 15,
|
||||||
|
constants: {
|
||||||
|
NOTE_ACCOUNT_BLOCK: 17754564,
|
||||||
|
ENCRYPTED_NOTES_BLOCK: 17754564
|
||||||
|
},
|
||||||
|
'tornado-proxy-light.contract.tornadocash.eth': '0x0D5550d52428E7e3175bfc9550207e4ad3859b17'
|
||||||
|
},
|
||||||
|
netId43114: {
|
||||||
|
rpcCallRetryAttempt: 15,
|
||||||
|
gasPrices: {
|
||||||
|
instant: 225,
|
||||||
|
fast: 35,
|
||||||
|
standard: 25,
|
||||||
|
low: 25
|
||||||
|
},
|
||||||
|
nativeCurrency: 'avax',
|
||||||
|
currencyName: 'AVAX',
|
||||||
|
explorerUrl: {
|
||||||
|
tx: 'https://snowtrace.io/tx/',
|
||||||
|
address: 'https://snowtrace.io/address/',
|
||||||
|
block: 'https://snowtrace.io/block/'
|
||||||
|
},
|
||||||
|
merkleTreeHeight: 20,
|
||||||
|
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
|
||||||
|
networkName: 'Avalanche Mainnet',
|
||||||
|
deployedBlock: 4429818,
|
||||||
|
multicall: '0xe86e3989c74293Acc962156cd3F525c07b6a1B6e',
|
||||||
|
echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
|
||||||
|
rpcUrls: {
|
||||||
|
publicRpc: {
|
||||||
|
name: 'Avalanche RPC',
|
||||||
|
url: 'https://api.avax.network/ext/bc/C/rpc'
|
||||||
|
},
|
||||||
|
meowRPC: {
|
||||||
|
name: 'Meow RPC',
|
||||||
|
url: 'https://avax.meowrpc.com'
|
||||||
|
},
|
||||||
|
oneRPC: {
|
||||||
|
name: 'OneRPC',
|
||||||
|
url: 'https://1rpc.io/avax/c'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tokens: {
|
||||||
|
avax: {
|
||||||
|
instanceAddress: {
|
||||||
|
'10': '0x330bdFADE01eE9bF63C209Ee33102DD334618e0a',
|
||||||
|
'100': '0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD',
|
||||||
|
'500': '0xaf8d1839c3c67cf571aa74B5c12398d4901147B3'
|
||||||
|
},
|
||||||
|
symbol: 'AVAX',
|
||||||
|
decimals: 18
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ensSubdomainKey: 'avalanche-tornado',
|
||||||
|
pollInterval: 10,
|
||||||
|
constants: {
|
||||||
|
NOTE_ACCOUNT_BLOCK: 4429813,
|
||||||
|
ENCRYPTED_NOTES_BLOCK: 4429813
|
||||||
|
},
|
||||||
|
'tornado-proxy-light.contract.tornadocash.eth': '0x0D5550d52428E7e3175bfc9550207e4ad3859b17'
|
||||||
|
},
|
||||||
|
netId11155111: {
|
||||||
|
rpcCallRetryAttempt: 15,
|
||||||
|
gasPrices: {
|
||||||
|
instant: 2,
|
||||||
|
fast: 2,
|
||||||
|
standard: 2,
|
||||||
|
low: 2
|
||||||
|
},
|
||||||
|
nativeCurrency: 'eth',
|
||||||
|
currencyName: 'ETH',
|
||||||
|
explorerUrl: {
|
||||||
|
tx: 'https://sepolia.etherscan.io/tx/',
|
||||||
|
address: 'https://sepolia.etherscan.io/address/',
|
||||||
|
block: 'https://sepolia.etherscan.io/block/'
|
||||||
|
},
|
||||||
|
merkleTreeHeight: 20,
|
||||||
|
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
|
||||||
|
networkName: 'Ethereum Sepolia',
|
||||||
|
deployedBlock: 5594395,
|
||||||
|
multicall: '0xcA11bde05977b3631167028862bE2a173976CA11',
|
||||||
|
echoContractAccount: '0xcDD1fc3F5ac2782D83449d3AbE80D6b7B273B0e5',
|
||||||
|
aggregatorContract: '0x4088712AC9fad39ea133cdb9130E465d235e9642',
|
||||||
|
rpcUrls: {
|
||||||
|
tornadoRPC: {
|
||||||
|
name: 'Tornado RPC',
|
||||||
|
url: 'https://tornadocash-rpc.com/sepolia'
|
||||||
|
},
|
||||||
|
sepolia: {
|
||||||
|
name: 'Sepolia RPC',
|
||||||
|
url: 'https://rpc.sepolia.org'
|
||||||
|
},
|
||||||
|
chainnodes: {
|
||||||
|
name: 'Chainnodes RPC',
|
||||||
|
url: 'https://sepolia.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tokens: {
|
||||||
|
eth: {
|
||||||
|
instanceAddress: {
|
||||||
|
'0.1': '0x8C4A04d872a6C1BE37964A21ba3a138525dFF50b',
|
||||||
|
'1': '0x8cc930096B4Df705A007c4A039BDFA1320Ed2508',
|
||||||
|
'10': '0x8D10d506D29Fc62ABb8A290B99F66dB27Fc43585',
|
||||||
|
'100': '0x44c5C92ed73dB43888210264f0C8b36Fd68D8379'
|
||||||
|
},
|
||||||
|
symbol: 'ETH',
|
||||||
|
decimals: 18
|
||||||
|
},
|
||||||
|
dai: {
|
||||||
|
instanceAddress: {
|
||||||
|
'100': '0x6921fd1a97441dd603a997ED6DDF388658daf754',
|
||||||
|
'1000': '0x50a637770F5d161999420F7d70d888DE47207145',
|
||||||
|
'10000': '0xecD649870407cD43923A816Cc6334a5bdf113621',
|
||||||
|
'100000': '0x73B4BD04bF83206B6e979BE2507098F92EDf4F90'
|
||||||
|
},
|
||||||
|
tokenAddress: '0xFF34B3d4Aee8ddCd6F9AFFFB6Fe49bD371b8a357',
|
||||||
|
symbol: 'DAI',
|
||||||
|
decimals: 18,
|
||||||
|
gasLimit: '55000'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ensSubdomainKey: 'sepolia-tornado',
|
||||||
|
pollInterval: 15,
|
||||||
|
constants: {
|
||||||
|
GOVERNANCE_BLOCK: 5594395,
|
||||||
|
NOTE_ACCOUNT_BLOCK: 5594395,
|
||||||
|
ENCRYPTED_NOTES_BLOCK: 5594395,
|
||||||
|
MINING_BLOCK_TIME: 15
|
||||||
|
},
|
||||||
|
'torn.contract.tornadocash.eth': '0x3AE6667167C0f44394106E197904519D808323cA',
|
||||||
|
'governance.contract.tornadocash.eth': '0xe5324cD7602eeb387418e594B87aCADee08aeCAD',
|
||||||
|
'tornado-router.contract.tornadocash.eth': '0x1572AFE6949fdF51Cb3E0856216670ae9Ee160Ee'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = { blockSyncInterval, enabledChains, networkConfig };
|
33
package.json
Normal file
33
package.json
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"name": "tornado-offline-deposit",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Command line tool to create Tornado Cash notes offline",
|
||||||
|
"main": "tornadoOffline.js",
|
||||||
|
"bin": {
|
||||||
|
"tornadoOffline": "tornadoOffline.js"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"lint": "eslint *.js",
|
||||||
|
"start": "node tornadoOffline.js",
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "Tornado Cash Community",
|
||||||
|
"license": "MIT",
|
||||||
|
"files": [
|
||||||
|
"abi",
|
||||||
|
".eslintrc.js",
|
||||||
|
".gitignore",
|
||||||
|
"networkConfig.js",
|
||||||
|
"tornadoOffline.js",
|
||||||
|
"README.md"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"bn.js": "^5.2.1",
|
||||||
|
"circomlibjs": "0.1.7",
|
||||||
|
"commander": "^12.1.0",
|
||||||
|
"ethers": "^6.13.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "^8.57.0"
|
||||||
|
}
|
||||||
|
}
|
229
tornadoOffline.js
Normal file
229
tornadoOffline.js
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
const fs = require('fs');
|
||||||
|
const crypto = require('crypto').webcrypto;
|
||||||
|
const BN = require('bn.js');
|
||||||
|
const { Command } = require('commander');
|
||||||
|
const circomlibjs = require('circomlibjs');
|
||||||
|
const { MaxUint256, Interface } = require('ethers');
|
||||||
|
|
||||||
|
const ERC20ABI = require('./abi/ERC20.abi.json');
|
||||||
|
const RouterABI = require('./abi/TornadoProxy.abi.json');
|
||||||
|
const { enabledChains, networkConfig } = require('./networkConfig');
|
||||||
|
const { description, version } = require('./package.json');
|
||||||
|
|
||||||
|
const program = new Command();
|
||||||
|
|
||||||
|
const erc20Interface = new Interface(ERC20ABI);
|
||||||
|
const routerInterface = new Interface(RouterABI);
|
||||||
|
|
||||||
|
const bytesToHex = (bytes) => '0x' + Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
|
||||||
|
|
||||||
|
// Convert BE encoded bytes (Buffer | Uint8Array) array to BigInt
|
||||||
|
const bytesToBN = (bytes) => BigInt(bytesToHex(bytes));
|
||||||
|
|
||||||
|
// Convert LE encoded bytes (Buffer | Uint8Array) array to BigInt
|
||||||
|
// const leBuff2Int = (bytes) => new BN(bytes, 16, 'le');
|
||||||
|
|
||||||
|
// Convert BigInt to LE encoded Uint8Array type
|
||||||
|
const leInt2Buff = (bigint) => Uint8Array.from(new BN(bigint).toArray('le', 31));
|
||||||
|
|
||||||
|
const toFixedHex = (numberish, length = 32) => {
|
||||||
|
return '0x' + BigInt(numberish).toString(16).padStart(length * 2, '0');
|
||||||
|
};
|
||||||
|
|
||||||
|
const rBigInt = (nbytes = 31) => bytesToBN(crypto.getRandomValues(new Uint8Array(nbytes)));
|
||||||
|
|
||||||
|
// https://github.com/tornadocash/tornado-classic-ui/blob/master/services/pedersen.js
|
||||||
|
class Pedersen {
|
||||||
|
constructor() {
|
||||||
|
this.pedersenPromise = this.initPedersen();
|
||||||
|
}
|
||||||
|
|
||||||
|
async initPedersen() {
|
||||||
|
this.pedersenHash = await circomlibjs.buildPedersenHash();
|
||||||
|
this.babyJub = this.pedersenHash.babyJub;
|
||||||
|
}
|
||||||
|
|
||||||
|
async unpackPoint(buffer) {
|
||||||
|
await this.pedersenPromise;
|
||||||
|
return this.babyJub?.unpackPoint(this.pedersenHash?.hash(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
toStringBuffer(bytes) {
|
||||||
|
return this.babyJub.F.toString(bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const pedersen = new Pedersen();
|
||||||
|
|
||||||
|
const buffPedersenHash = async (bytes) => {
|
||||||
|
const [hash] = await pedersen.unpackPoint(bytes);
|
||||||
|
return pedersen.toStringBuffer(hash);
|
||||||
|
};
|
||||||
|
|
||||||
|
const createDeposit = async ({ nullifier, secret }) => {
|
||||||
|
const preimage = new Uint8Array([...leInt2Buff(nullifier), ...leInt2Buff(secret)]);
|
||||||
|
const noteHex = toFixedHex(bytesToBN(preimage), 62);
|
||||||
|
const commitment = BigInt(await buffPedersenHash(preimage));
|
||||||
|
const commitmentHex = toFixedHex(commitment);
|
||||||
|
const nullifierHash = BigInt(await buffPedersenHash(leInt2Buff(nullifier)));
|
||||||
|
const nullifierHex = toFixedHex(nullifierHash);
|
||||||
|
|
||||||
|
return {
|
||||||
|
preimage,
|
||||||
|
noteHex,
|
||||||
|
commitment,
|
||||||
|
commitmentHex,
|
||||||
|
nullifierHash,
|
||||||
|
nullifierHex,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Tornado Deposit Note and Invoice
|
||||||
|
*/
|
||||||
|
const createNote = async ({ netId, currency, amount }) => {
|
||||||
|
const nullifier = rBigInt(31);
|
||||||
|
const secret = rBigInt(31);
|
||||||
|
|
||||||
|
const depositObject = await createDeposit({
|
||||||
|
nullifier,
|
||||||
|
secret,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
currency,
|
||||||
|
amount,
|
||||||
|
netId,
|
||||||
|
note: `tornado-${currency}-${amount}-${netId}-${depositObject.noteHex}`,
|
||||||
|
invoice: `tornadoInvoice-${currency}-${amount}-${netId}-${depositObject.commitmentHex}`,
|
||||||
|
nullifier,
|
||||||
|
secret,
|
||||||
|
...depositObject,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const getInstanceInfo = ({ netId, currency, amount }) => {
|
||||||
|
const networkObject = networkConfig[`netId${netId}`];
|
||||||
|
|
||||||
|
const routerAddress = networkObject['tornado-router.contract.tornadocash.eth']
|
||||||
|
|| networkObject['tornado-proxy-light.contract.tornadocash.eth']
|
||||||
|
|| networkObject['tornado-proxy.contract.tornadocash.eth'];
|
||||||
|
|
||||||
|
const instanceAddress = networkObject.tokens[currency]?.instanceAddress[amount];
|
||||||
|
|
||||||
|
const instanceDecimals = Number(networkObject.tokens[currency]?.decimals);
|
||||||
|
|
||||||
|
const tokenAddress = networkObject.tokens[currency]?.tokenAddress;
|
||||||
|
|
||||||
|
const isNativeCurrency = networkObject.nativeCurrency === currency;
|
||||||
|
|
||||||
|
if (!instanceAddress) {
|
||||||
|
const errMsg = `Could not find a tornado instance ${netId} ${currency} ${amount}`;
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
const denomination = BigInt(amount * 10 ** instanceDecimals);
|
||||||
|
|
||||||
|
return {
|
||||||
|
routerAddress,
|
||||||
|
instanceAddress,
|
||||||
|
instanceDecimals,
|
||||||
|
tokenAddress,
|
||||||
|
isNativeCurrency,
|
||||||
|
denomination,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const newDeposit = async ({ netId, currency, amount }) => {
|
||||||
|
currency = String(currency).toLowerCase();
|
||||||
|
amount = Number(amount);
|
||||||
|
netId = Number(netId);
|
||||||
|
|
||||||
|
if (!enabledChains.includes(netId.toString())) {
|
||||||
|
const errMsg = `Unsupported chain ${netId}`;
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
routerAddress,
|
||||||
|
instanceAddress,
|
||||||
|
tokenAddress,
|
||||||
|
isNativeCurrency,
|
||||||
|
denomination,
|
||||||
|
} = getInstanceInfo({ netId, currency, amount });
|
||||||
|
|
||||||
|
const {
|
||||||
|
note,
|
||||||
|
noteHex,
|
||||||
|
invoice,
|
||||||
|
commitmentHex: commitment,
|
||||||
|
nullifierHex: nullifierHash
|
||||||
|
} = await createNote({ netId, currency, amount });
|
||||||
|
|
||||||
|
const depositData = routerInterface.encodeFunctionData('deposit', [instanceAddress, commitment, '0x']);
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`New deposit: ${JSON.stringify({
|
||||||
|
note,
|
||||||
|
invoice,
|
||||||
|
commitment,
|
||||||
|
nullifierHash
|
||||||
|
}, null, 2)}\n`
|
||||||
|
);
|
||||||
|
|
||||||
|
// Backup locally
|
||||||
|
fs.writeFileSync(`./backup-tornado-${currency}-${amount}-${netId}-${noteHex.slice(0, 10)}.txt`, note, { encoding: 'utf8' });
|
||||||
|
|
||||||
|
if (isNativeCurrency) {
|
||||||
|
console.log(
|
||||||
|
`Transaction Data: ${JSON.stringify({
|
||||||
|
to: routerAddress,
|
||||||
|
value: denomination.toString(),
|
||||||
|
data: depositData
|
||||||
|
}, null, 2)}`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const approveData = erc20Interface.encodeFunctionData('approve', [routerAddress, MaxUint256]);
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`Approve Data: ${JSON.stringify({
|
||||||
|
to: tokenAddress,
|
||||||
|
data: approveData
|
||||||
|
}, null, 2)}]\n`
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`Transaction Data: ${JSON.stringify({
|
||||||
|
to: routerAddress,
|
||||||
|
data: depositData
|
||||||
|
}, null, 2)}`
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
program
|
||||||
|
.name('tornadoOffline')
|
||||||
|
.description(description)
|
||||||
|
.version(version)
|
||||||
|
.argument('<netId>', 'netId of the supported network (Ethereum Mainnet: 1, Goerli Testnet: 5, BSC: 56)')
|
||||||
|
.argument('<currency>', 'Native Currency or Token supported by Tornado Cash')
|
||||||
|
.argument('<amount>', 'Amount to deposit (Check the UI for supported amount)')
|
||||||
|
.action((netId, currency, amount) => {
|
||||||
|
console.log('Creating offline Tornado Cash Note\n');
|
||||||
|
newDeposit({ netId, currency, amount });
|
||||||
|
});
|
||||||
|
|
||||||
|
program
|
||||||
|
.command('list')
|
||||||
|
.description('List tornado cash backup notes on local')
|
||||||
|
.action(() => {
|
||||||
|
const backups = fs.readdirSync('.').filter(f => f.includes('backup'));
|
||||||
|
|
||||||
|
const context = backups.map(b => fs.readFileSync(b, { encoding: 'utf8' })).join('\n');
|
||||||
|
|
||||||
|
console.log(context);
|
||||||
|
});
|
||||||
|
|
||||||
|
program.parse();
|
Loading…
Reference in New Issue
Block a user