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