Fetch events from API and remove external fee oracles #37

Open
tornadocontrib wants to merge 1 commits from tornadocontrib/classic-ui:development into development
30 changed files with 480 additions and 189 deletions

@ -1,7 +1,7 @@
PINATA_API_KEY= PINATA_API_KEY=
PINATA_SECRET_API_KEY= PINATA_SECRET_API_KEY=
CHAINNODES_KEY= DEFAULT_RPC=
WC_BRIDGE= WC_BRIDGE=

@ -32,7 +32,6 @@ jobs:
- name: Build - name: Build
run: yarn generate run: yarn generate
env: env:
CHAINNODES_KEY: ${{ secrets.CHAINNODES_KEY }}
WC_BRIDGE: ${{ secrets.WC_BRIDGE }} WC_BRIDGE: ${{ secrets.WC_BRIDGE }}
OLD_STORE_NAME: ${{ secrets.OLD_STORE_NAME }} OLD_STORE_NAME: ${{ secrets.OLD_STORE_NAME }}
STORE_NAME: ${{ secrets.STORE_NAME }} STORE_NAME: ${{ secrets.STORE_NAME }}

@ -18,9 +18,9 @@
</template> </template>
<template v-slot:description>{{ notice.description }}</template> <template v-slot:description>{{ notice.description }}</template>
</i18n> </i18n>
<a v-if="notice.nova" href="https://nova.tornado.ws/" target="_blank" rel="noopener noreferrer"> <!-- a v-if="notice.nova" href="https://nova.tornado.ws/" target="_blank" rel="noopener noreferrer">
Tornado Cash Nova Tornado Cash Nova
</a> </a -->
<a <a
v-if="notice.txHash" v-if="notice.txHash"
:href="txExplorerUrl(notice.txHash)" :href="txExplorerUrl(notice.txHash)"

@ -4,10 +4,7 @@
<div class="box-modal-title">{{ $t('withdrawalSettings') }}</div> <div class="box-modal-title">{{ $t('withdrawalSettings') }}</div>
<button type="button" class="delete" @click="$parent.cancel('escape')" /> <button type="button" class="delete" @click="$parent.cancel('escape')" />
</header> </header>
<b-tabs v-if="isRelayersAvailable" v-model="withdrawType" :animated="false" class="is-modal"> <b-tabs v-model="withdrawType" :animated="false" class="is-modal">
<RelayerTab />
</b-tabs>
<b-tabs v-else v-model="withdrawType" :animated="false" class="is-modal">
<RelayerTab /> <RelayerTab />
<WalletTab /> <WalletTab />
</b-tabs> </b-tabs>
@ -49,11 +46,7 @@ export default {
computed: { computed: {
...mapState('application', { ...mapState('application', {
defaultWithdrawType: 'withdrawType' defaultWithdrawType: 'withdrawType'
}), })
...mapState('relayer', ['isLoadingRelayers', 'validRelayers']),
isRelayersAvailable() {
return !this.isLoadingRelayers && this.validRelayers.length > 0
}
}, },
created() { created() {
this.withdrawType = this.defaultWithdrawType this.withdrawType = this.defaultWithdrawType

@ -200,7 +200,7 @@ export default {
return false return false
}, },
shouldSettingsShow() { shouldSettingsShow() {
return !this.isLoading && !this.error.type && !this.hasErrorNote return !this.hasErrorNote && !this.error.message
}, },
hasErrorNote() { hasErrorNote() {
const note = this.withdrawNote.split('-')[4] const note = this.withdrawNote.split('-')[4]

@ -64,7 +64,7 @@ export default {
}, },
created() { created() {
this.checkRecoveryKey() this.checkRecoveryKey()
this.newNotify() // this.newNotify()
this.$store.dispatch('fees/setDefaultGasPrice') this.$store.dispatch('fees/setDefaultGasPrice')
}, },
mounted() { mounted() {
@ -125,6 +125,7 @@ export default {
width: 440 width: 440
}) })
}, },
/**
newNotify() { newNotify() {
const hasNotify = window.localStorage.getItem('hasNotify') const hasNotify = window.localStorage.getItem('hasNotify')
@ -144,6 +145,7 @@ export default {
window.localStorage.setItem('hasNotify', true) window.localStorage.setItem('hasNotify', true)
} }
}, },
**/
handleOpenModal() { handleOpenModal() {
const recoveryKey = this.$sessionStorage.getItem(this.accounts.encrypt) const recoveryKey = this.$sessionStorage.getItem(this.accounts.encrypt)
if (recoveryKey) { if (recoveryKey) {

@ -53,7 +53,7 @@ export async function _encryptFormatTx({ dispatch, getters, rootGetters }, { eve
return getDeposit({ event, netId, service, instance }) return getDeposit({ event, netId, service, instance })
}) })
const proceedDeposits = await Promise.all(depositPromises) const proceedDeposits = (await Promise.all(depositPromises)).filter((d) => d)
console.log({ proceedDeposits }) console.log({ proceedDeposits })
dispatch( dispatch(

@ -1,4 +1,4 @@
import { graph } from '@/services' import { fetchEvents } from '@/services'
import networkConfig from '@/networkConfig' import networkConfig from '@/networkConfig'
function createMutation({ commit, rootState }, { type, payload }) { function createMutation({ commit, rootState }, { type, payload }) {
@ -16,7 +16,13 @@ function clearState({ dispatch }, { key }) {
async function getEventsFromBlockPart({ echoContract, address, currentBlockNumber, netId }) { async function getEventsFromBlockPart({ echoContract, address, currentBlockNumber, netId }) {
try { try {
const { events: graphEvents, lastSyncBlock } = await graph.getNoteAccounts({ address, netId }) // const { events: graphEvents, lastSyncBlock } = await graph.getNoteAccounts({ address, netId })
const { events: allEvents, lastSyncBlock } = await fetchEvents({
type: 'echo',
netId
})
const graphEvents = allEvents.filter((el) => address === el.address)
if (graphEvents.length) { if (graphEvents.length) {
return graphEvents return graphEvents

@ -25,10 +25,6 @@ export default {
name: 'Tornado RPC', name: 'Tornado RPC',
url: 'https://tornadocash-rpc.com/mainnet' url: 'https://tornadocash-rpc.com/mainnet'
}, },
chainnodes: {
name: 'Chainnodes RPC',
url: 'https://mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
},
mevblockerRPC: { mevblockerRPC: {
name: 'MevblockerRPC', name: 'MevblockerRPC',
url: 'https://rpc.mevblocker.io' url: 'https://rpc.mevblocker.io'
@ -38,7 +34,7 @@ export default {
url: 'https://1rpc.io/eth' url: 'https://1rpc.io/eth'
} }
}, },
multicall: '0xeefba1e63905ef1d7acba5a8513c70307c1ce441', multicall: '0xcA11bde05977b3631167028862bE2a173976CA11',
routerContract: '0xd90e2f925DA726b50C4Ed8D0Fb90Ad053324F31b', routerContract: '0xd90e2f925DA726b50C4Ed8D0Fb90Ad053324F31b',
registryContract: '0x58E8dCC13BE9780fC42E8723D8EaD4CF46943dF2', registryContract: '0x58E8dCC13BE9780fC42E8723D8EaD4CF46943dF2',
echoContractAccount: '0x9B27DD5Bb15d42DC224FCD0B7caEbBe16161Df42', echoContractAccount: '0x9B27DD5Bb15d42DC224FCD0B7caEbBe16161Df42',
@ -145,17 +141,13 @@ export default {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292', emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Binance Smart Chain', networkName: 'Binance Smart Chain',
deployedBlock: 8158799, deployedBlock: 8158799,
multicall: '0x41263cba59eb80dc200f3e2544eda4ed6a90e76c', multicall: '0xcA11bde05977b3631167028862bE2a173976CA11',
echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4', echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
rpcUrls: { rpcUrls: {
tornadoRPC: { tornadoRPC: {
name: 'Tornado RPC', name: 'Tornado RPC',
url: 'https://tornadocash-rpc.com/bsc' url: 'https://tornadocash-rpc.com/bsc'
}, },
chainnodes: {
name: 'Chainnodes RPC',
url: 'https://bsc-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
},
oneRPC: { oneRPC: {
name: '1RPC', name: '1RPC',
url: 'https://1rpc.io/bnb' url: 'https://1rpc.io/bnb'
@ -171,6 +163,32 @@ export default {
}, },
symbol: 'BNB', symbol: 'BNB',
decimals: 18 decimals: 18
},
usdt: {
instanceAddress: {
'10': '0x261fB4f84bb0BdEe7E035B6a8a08e5c35AdacdDD',
'100': '0x3957861d4897d883C9b944C0b4E22bBd0DDE6e21',
'1000': '0x6D180403AdFb39F70983eB51A033C5e52eb9BB69',
'10000': '0x3722662D8AaB07B216B14C02eF0ee940d14A4200'
},
instanceApproval: true,
tokenAddress: '0x55d398326f99059fF775485246999027B3197955',
symbol: 'USDT',
decimals: 18,
gasLimit: '700000'
},
btcb: {
instanceAddress: {
'0.0001': '0x736dABbFc8101Ae75287104eCcf67e45D7369Ae1',
'0.001': '0x82c7Ce6f1F158cEC5536d591a2BC19864b3CA823',
'0.01': '0x8284c96679037d8081E498d8F767cA5a140BFAAf',
'0.1': '0x2bcD128Ce23ee30Ee945E613ff129c4DE1102C79'
},
instanceApproval: true,
tokenAddress: '0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c',
symbol: 'BTCB',
decimals: 18,
gasLimit: '700000'
} }
}, },
ensSubdomainKey: 'bsc-tornado', ensSubdomainKey: 'bsc-tornado',
@ -200,13 +218,9 @@ export default {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292', emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Polygon (Matic) Network', networkName: 'Polygon (Matic) Network',
deployedBlock: 16257962, deployedBlock: 16257962,
multicall: '0x11ce4B23bD875D7F5C6a31084f55fDe1e9A87507', multicall: '0xcA11bde05977b3631167028862bE2a173976CA11',
echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4', echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
rpcUrls: { rpcUrls: {
chainnodes: {
name: 'Chainnodes RPC',
url: 'https://polygon-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
},
oneRpc: { oneRpc: {
name: '1RPC', name: '1RPC',
url: 'https://1rpc.io/matic' url: 'https://1rpc.io/matic'
@ -251,18 +265,10 @@ export default {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292', emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Optimism', networkName: 'Optimism',
deployedBlock: 2243689, deployedBlock: 2243689,
multicall: '0x35A6Cdb2C9AD4a45112df4a04147EB07dFA01aB7', multicall: '0xcA11bde05977b3631167028862bE2a173976CA11',
echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4', echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
ovmGasPriceOracleContract: '0x420000000000000000000000000000000000000F', ovmGasPriceOracleContract: '0x420000000000000000000000000000000000000F',
rpcUrls: { 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: { oneRpc: {
name: '1RPC', name: '1RPC',
url: 'https://1rpc.io/op' url: 'https://1rpc.io/op'
@ -307,17 +313,13 @@ export default {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292', emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Arbitrum One', networkName: 'Arbitrum One',
deployedBlock: 3430648, deployedBlock: 3430648,
multicall: '0x842eC2c7D803033Edf55E478F461FC547Bc54EB2', multicall: '0xcA11bde05977b3631167028862bE2a173976CA11',
echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4', echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
rpcUrls: { rpcUrls: {
tornadoRPC: { tornadoRPC: {
name: 'Tornado RPC', name: 'Tornado RPC',
url: 'https://tornadocash-rpc.com/arbitrum' url: 'https://tornadocash-rpc.com/arbitrum'
}, },
chainnodes: {
name: 'Chainnodes RPC',
url: 'https://arbitrum-one.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
},
oneRpc: { oneRpc: {
name: '1rpc', name: '1rpc',
url: 'https://1rpc.io/arb' url: 'https://1rpc.io/arb'
@ -366,17 +368,13 @@ export default {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292', emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Gnosis Chain', networkName: 'Gnosis Chain',
deployedBlock: 17754561, deployedBlock: 17754561,
multicall: '0xb5b692a88bdfc81ca69dcb1d924f59f0413a602a', multicall: '0xcA11bde05977b3631167028862bE2a173976CA11',
echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4', echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
rpcUrls: { rpcUrls: {
tornadoRPC: { tornadoRPC: {
name: 'Tornado RPC', name: 'Tornado RPC',
url: 'https://tornadocash-rpc.com/gnosis' url: 'https://tornadocash-rpc.com/gnosis'
}, },
chainnodes: {
name: 'Chainnodes RPC',
url: 'https://gnosis-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
},
blockPi: { blockPi: {
name: 'BlockPi', name: 'BlockPi',
url: 'https://gnosis.blockpi.network/v1/rpc/public' url: 'https://gnosis.blockpi.network/v1/rpc/public'
@ -421,7 +419,7 @@ export default {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292', emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Avalanche Mainnet', networkName: 'Avalanche Mainnet',
deployedBlock: 4429818, deployedBlock: 4429818,
multicall: '0xe86e3989c74293Acc962156cd3F525c07b6a1B6e', multicall: '0xcA11bde05977b3631167028862bE2a173976CA11',
echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4', echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
rpcUrls: { rpcUrls: {
publicRpc: { publicRpc: {
@ -486,10 +484,6 @@ export default {
sepolia: { sepolia: {
name: 'Sepolia RPC', name: 'Sepolia RPC',
url: 'https://rpc.sepolia.org' url: 'https://rpc.sepolia.org'
},
chainnodes: {
name: 'Chainnodes RPC',
url: 'https://sepolia.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
} }
}, },
tokens: { tokens: {

@ -187,7 +187,7 @@ export default {
new webpack.IgnorePlugin(/worker_threads/), new webpack.IgnorePlugin(/worker_threads/),
new webpack.DefinePlugin({ new webpack.DefinePlugin({
'process.env': JSON.stringify({ 'process.env': JSON.stringify({
CHAINNODES_KEY: process.env.CHAINNODES_KEY, DEFAULT_RPC: process.env.DEFAULT_RPC,
WC_BRIDGE: process.env.WC_BRIDGE, WC_BRIDGE: process.env.WC_BRIDGE,
OLD_STORE_NAME: process.env.OLD_STORE_NAME, OLD_STORE_NAME: process.env.OLD_STORE_NAME,
STORE_NAME: process.env.STORE_NAME, STORE_NAME: process.env.STORE_NAME,
@ -225,7 +225,7 @@ export default {
}, },
provider: { provider: {
rpcUrl: `https://mainnet.chainnodes.org/${process.env.CHAINNODES_KEY}` rpcUrl: process.env.DEFAULT_RPC || 'https://tornadocash-rpc.com'
}, },
// todo make custom loading page // todo make custom loading page

@ -30,7 +30,7 @@
"@nuxtjs/moment": "^1.6.0", "@nuxtjs/moment": "^1.6.0",
"@tornado/fixed-merkle-tree": "0.7", "@tornado/fixed-merkle-tree": "0.7",
"@tornado/snarkjs": "0.1.20", "@tornado/snarkjs": "0.1.20",
"@tornado/tornado-oracles": "^2.1.0", "@tornado/tornado-oracles": "git+https://git.tornado.ws/tornadocontrib/tornado-oracles.git#c9f43ff29266c48dc030a3b66e818201ff4cfc8d",
"@tornado/websnark": "0.0.4", "@tornado/websnark": "0.0.4",
"@walletconnect/web3-provider": "1.7.8", "@walletconnect/web3-provider": "1.7.8",
"ajv": "^6.10.2", "ajv": "^6.10.2",

@ -314,7 +314,7 @@ export default {
const { timestamp, txHash, isSpent } = event const { timestamp, txHash, isSpent } = event
const receipt = await this.getTransactionReceipt(txHash) const from = event.from || (await this.getTransactionReceipt(txHash)).from
const { nullifierHex, commitmentHex } = parseNote(withdrawNote) const { nullifierHex, commitmentHex } = parseNote(withdrawNote)
@ -324,19 +324,23 @@ export default {
isSpent, isSpent,
txHash, txHash,
timestamp, timestamp,
from: receipt.from, from,
commitment: commitmentHex commitment: commitmentHex
} }
if (isSpent) { if (isSpent) {
const { withdrawalBlock, txHash, to, fee, amount } = await this.$store.dispatch( const {
'application/loadWithdrawalData', withdrawalBlock,
{ txHash,
withdrawNote to,
} fee,
) amount,
timestamp: eventTimestamp
} = await this.$store.dispatch('application/loadWithdrawalData', {
withdrawNote
})
const { timestamp } = await this.getBlock(withdrawalBlock) const timestamp = eventTimestamp || (await this.getBlock(withdrawalBlock)).timestamp
this.txWithdrawalInfo = { this.txWithdrawalInfo = {
amount, amount,

28
relayers.json Normal file

@ -0,0 +1,28 @@
[
{
"ensName": "tornadowithdraw.eth",
"hostnames": {
"bsc-tornado": "tornadowithdraw.com/56",
"polygon-tornado": "tornadowithdraw.com/137",
"optimism-tornado": "tornadowithdraw.com/10",
"arbitrum-tornado": "tornadowithdraw.com/42161",
"gnosis-tornado": "tornadowithdraw.com/100",
"avalanche-tornado": "tornadowithdraw.com/43114",
"sepolia-tornado": "tornadowithdraw.com/11155111"
},
"relayerAddress": "0x40c3d1656a26C9266f4A10fed0D87EFf79F54E64"
},
{
"ensName": "rpc.tornadowithdraw.eth",
"hostnames": {
"bsc-tornado": "tornadocash-rpc.com/56",
"polygon-tornado": "tornadocash-rpc.com/137",
"optimism-tornado": "tornadocash-rpc.com/10",
"arbitrum-tornado": "tornadocash-rpc.com/42161",
"gnosis-tornado": "tornadocash-rpc.com/100",
"avalanche-tornado": "tornadocash-rpc.com/43114",
"sepolia-tornado": "tornadocash-rpc.com/11155111"
},
"relayerAddress": "0xFF787B7A5cd8a88508361E3B7bcE791Aa2796526"
}
]

@ -37,7 +37,7 @@ export function loadCachedEvents({ name, directory, deployedBlock }) {
export async function getPastEvents({ type, fromBlock, netId, events, contractAttrs }) { export async function getPastEvents({ type, fromBlock, netId, events, contractAttrs }) {
let downloadedEvents = events let downloadedEvents = events
let [{ url: rpcUrl }] = Object.values(networkConfig[`netId${netId}`].rpcUrls) const [{ url: rpcUrl }] = Object.values(networkConfig[`netId${netId}`].rpcUrls)
const provider = new Web3.providers.HttpProvider(rpcUrl) const provider = new Web3.providers.HttpProvider(rpcUrl)
const web3 = new Web3(provider) const web3 = new Web3(provider)
@ -49,7 +49,7 @@ export async function getPastEvents({ type, fromBlock, netId, events, contractAt
const blockDifference = Math.ceil(blockNumberBuffer - fromBlock) const blockDifference = Math.ceil(blockNumberBuffer - fromBlock)
// eth_logs and eth_filter are restricted > 10,000 block queries // eth_logs and eth_filter are restricted > 10,000 block queries
const blockRange = blockSyncInterval ? blockSyncInterval : 10_000 const blockRange = blockSyncInterval || 10_000
let chunksCount = blockDifference === 0 ? 1 : Math.ceil(blockDifference / blockRange) let chunksCount = blockDifference === 0 ? 1 : Math.ceil(blockDifference / blockRange)
const chunkSize = Math.ceil(blockDifference / chunksCount) const chunkSize = Math.ceil(blockDifference / chunksCount)

@ -86,7 +86,7 @@ async function main(netId, chosenToken, chosenEvent) {
let events = await getPastEvents({ let events = await getPastEvents({
type: eventName, type: eventName,
fromBlock: cachedEvents.lastBlock + 1, fromBlock: cachedEvents.lastBlock + 1,
netId: netId, netId,
events: [], events: [],
contractAttrs: [ABI, address] contractAttrs: [ABI, address]
}) })

@ -1,6 +1,6 @@
/** /**
* Manually patch vuex to support Node.js >= 18.x * Manually patch vuex to support Node.js >= 18.x
* *
* See issue https://github.com/vuejs/vuex/issues/2160 * See issue https://github.com/vuejs/vuex/issues/2160
* https://github.com/vuejs/vuex/commit/397e9fba45c8b4ec0c4a33d2578e34829bd348d7 * https://github.com/vuejs/vuex/commit/397e9fba45c8b4ec0c4a33d2578e34829bd348d7
*/ */
@ -17,7 +17,6 @@ if (!pkgJson.exports['./*']) {
changes = true changes = true
} }
if (changes) { if (changes) {
fs.writeFileSync('./node_modules/vuex/package.backup.json', backupJson + '\n') fs.writeFileSync('./node_modules/vuex/package.backup.json', backupJson + '\n')
fs.writeFileSync('./node_modules/vuex/package.json', JSON.stringify(pkgJson, null, 2) + '\n') fs.writeFileSync('./node_modules/vuex/package.json', JSON.stringify(pkgJson, null, 2) + '\n')

82
services/eventApi.js Normal file

@ -0,0 +1,82 @@
// Maximum of 5K events can be returned from the single query (to prevent DDOS)
const first = 5000
const EVENT_API_ROOT = 'https://tornadocash-rpc.com'
export async function fetchEvents({ netId = 1, type, currency, amount, fromBlock = 0, recent }) {
try {
const url = `${EVENT_API_ROOT}/${netId}/events`
const events = []
let lastSyncBlock = fromBlock
// Iterate if we have more than 4.9K events
while (true) {
const resp = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
type,
currency,
amount,
fromBlock,
recent
})
})
if (!resp.ok) {
const errMsg = `${url} failed with error ${resp.status}: ${await resp.text()}`
throw new Error(errMsg)
}
// eslint-disable-next-line prefer-const
let { events: fetchedEvents, lastSyncBlock: currentBlock } = await resp.json()
if (recent) {
return {
events: fetchedEvents,
lastSyncBlock: currentBlock
}
}
lastSyncBlock = currentBlock
if (!Array.isArray(fetchedEvents) || !fetchedEvents.length) {
break
}
fetchedEvents = fetchedEvents.sort((a, b) => {
if (a.blockNumber === b.blockNumber) {
return a.logIndex - b.logIndex
}
return a.blockNumber - b.blockNumber
})
const [lastEvent] = fetchedEvents.slice(-1)
if (fetchedEvents.length < first - 100) {
events.push(...fetchedEvents)
break
}
fetchedEvents = fetchedEvents.filter((e) => e.blockNumber !== lastEvent.blockNumber)
fromBlock = Number(lastEvent.blockNumber)
events.push(...fetchedEvents)
}
return {
events,
lastSyncBlock
}
} catch (err) {
console.log('Error from events api')
console.log(err)
return {
events: [],
lastSyncBlock: fromBlock
}
}
}

@ -1,6 +1,7 @@
import Web3 from 'web3' import Web3 from 'web3'
import graph from '@/services/graph' // import graph from '@/services/graph'
import { fetchEvents } from '@/services'
import { download } from '@/store/snark' import { download } from '@/store/snark'
import networkConfig, { enabledChains, blockSyncInterval } from '@/networkConfig' import networkConfig, { enabledChains, blockSyncInterval } from '@/networkConfig'
import InstanceABI from '@/abis/Instance.abi.json' import InstanceABI from '@/abis/Instance.abi.json'
@ -220,12 +221,27 @@ class EventService {
async getEventsFromGraph({ fromBlock, methodName }) { async getEventsFromGraph({ fromBlock, methodName }) {
try { try {
/**
const { events, lastSyncBlock } = await graph[methodName]({ const { events, lastSyncBlock } = await graph[methodName]({
fromBlock, fromBlock,
netId: this.netId, netId: this.netId,
amount: this.amount, amount: this.amount,
currency: this.currency currency: this.currency
}) })
**/
methodName = methodName.substr(6)
methodName = methodName.substr(0, methodName.length - 1).toLowerCase()
const { events, lastSyncBlock } = await fetchEvents({
fromBlock,
netId: this.netId,
amount: this.amount,
currency: this.currency,
type: methodName
})
return { return {
events, events,
lastBlock: lastSyncBlock lastBlock: lastSyncBlock

@ -10,6 +10,7 @@ export { default as graph } from './graph'
export { default as schema } from './schema' export { default as schema } from './schema'
export { default as walletConnectConnector } from './walletConnect' export { default as walletConnectConnector } from './walletConnect'
export * from './lookupAddress' export * from './lookupAddress'
export * from './eventApi'
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
window.graph = graph window.graph = graph

@ -3,13 +3,14 @@ import namehash from 'eth-ens-namehash'
import { BigNumber as BN } from 'bignumber.js' import { BigNumber as BN } from 'bignumber.js'
import { toChecksumAddress, isAddress } from 'web3-utils' import { toChecksumAddress, isAddress } from 'web3-utils'
import { graph } from '@/services' import { fetchEvents } from '@/services'
import networkConfig from '@/networkConfig' import networkConfig from '@/networkConfig'
import { REGISTRY_DEPLOYED_BLOCK } from '@/constants' import { REGISTRY_DEPLOYED_BLOCK } from '@/constants'
import { sleep, flattenNArray } from '@/utils' import { sleep, flattenNArray } from '@/utils'
import AggregatorABI from '@/abis/Aggregator.abi.json' import AggregatorABI from '@/abis/Aggregator.abi.json'
import RelayerRegistryABI from '@/abis/RelayerRegistry.abi.json' import RelayerRegistryABI from '@/abis/RelayerRegistry.abi.json'
import STATIC_RELAYER from '@/relayers.json'
const MIN_STAKE_BALANCE = '0X1B1AE4D6E2EF500000' // 500 TORN const MIN_STAKE_BALANCE = '0X1B1AE4D6E2EF500000' // 500 TORN
@ -174,13 +175,20 @@ class RelayerRegister {
let allRelayers = cachedEvents let allRelayers = cachedEvents
if (!cachedEvents || !cachedEvents.length) { if (!cachedEvents || !cachedEvents.length) {
const { lastSyncBlock, events } = await graph.getAllRegisters(blockFrom) // const { lastSyncBlock, events } = await graph.getAllRegisters(blockFrom)
const { events: apiEvents, lastSyncBlock } = await fetchEvents({
type: 'registry',
netId: 1,
fromBlock: blockFrom
})
const events = apiEvents.filter(({ event }) => event === 'RelayerRegistered')
if (events.length) { if (events.length) {
blockTo = lastSyncBlock + 1 blockTo = lastSyncBlock + 1
cachedEvents = events.map((el) => ({ cachedEvents = events.map((el) => ({
ensName: el.ensName, ensName: el.ensName,
relayerAddress: toChecksumAddress(el.address) relayerAddress: toChecksumAddress(el.relayerAddress)
})) }))
} }
} }
@ -240,6 +248,7 @@ class RelayerRegister {
const isOwner = relayer.relayerAddress === curr.owner const isOwner = relayer.relayerAddress === curr.owner
const hasMinBalance = new BN(curr.balance).gte(MIN_STAKE_BALANCE) const hasMinBalance = new BN(curr.balance).gte(MIN_STAKE_BALANCE)
const hasRelayer = acc.find(({ ensName }) => ensName === relayer.ensName)
if ( if (
hostname && hostname &&
@ -247,7 +256,8 @@ class RelayerRegister {
mainnetSubdomain && mainnetSubdomain &&
curr.isRegistered && curr.isRegistered &&
hasMinBalance && hasMinBalance &&
!isHostWithProtocol !isHostWithProtocol &&
!hasRelayer
) { ) {
acc.push({ acc.push({
hostname, hostname,
@ -279,7 +289,18 @@ class RelayerRegister {
[] []
) )
return validRelayers const staticRelayers = STATIC_RELAYER.reduce((acc, relayer) => {
if (relayer.hostnames[ensSubdomainKey]) {
acc.push({
...relayer,
hostname: relayer.hostnames[ensSubdomainKey],
stakeBalance: MIN_STAKE_BALANCE
})
}
return acc
}, [])
return [...staticRelayers, ...validRelayers]
} }
getRelayers = async (ensSubdomainKey) => { getRelayers = async (ensSubdomainKey) => {

@ -32,6 +32,9 @@ function getRelayerValidateFunction(netId) {
case 42161: case 42161:
return ajv.getSchema('l2Relayer') return ajv.getSchema('l2Relayer')
case 11155111:
return ajv.getSchema('sepoliaRelayer')
default: default:
return ajv.getSchema('defaultRelayer') return ajv.getSchema('defaultRelayer')
} }

@ -5,11 +5,15 @@ import { statusSchema as defaultRelayer } from './default'
import { statusSchema as polygonRelayer } from './polygon' import { statusSchema as polygonRelayer } from './polygon'
import { statusSchema as avalancheRelayer } from './avalanche' import { statusSchema as avalancheRelayer } from './avalanche'
const sepoliaRelayer = JSON.parse(JSON.stringify(defaultRelayer))
sepoliaRelayer.properties.ethPrices.required = ['dai']
export default { export default {
l2Relayer, l2Relayer,
bscRelayer, bscRelayer,
xdaiRelayer, xdaiRelayer,
defaultRelayer, defaultRelayer,
polygonRelayer, polygonRelayer,
avalancheRelayer avalancheRelayer,
sepoliaRelayer
} }

@ -9,7 +9,7 @@ import MulticallABI from '@/abis/Multicall.json'
import InstanceABI from '@/abis/Instance.abi.json' import InstanceABI from '@/abis/Instance.abi.json'
import TornadoProxyABI from '@/abis/TornadoProxy.abi.json' import TornadoProxyABI from '@/abis/TornadoProxy.abi.json'
import { graph, treesInterface, EventsFactory } from '@/services' import { treesInterface, EventsFactory, fetchEvents } from '@/services'
import { import {
randomBN, randomBN,
@ -233,8 +233,15 @@ const actions = {
const netId = rootGetters['metamask/netId'] const netId = rootGetters['metamask/netId']
const { currency, amount } = state.selectedStatistic const { currency, amount } = state.selectedStatistic
const eventService = getters.eventsInterface.getService({ netId, amount, currency }) // const eventService = getters.eventsInterface.getService({ netId, amount, currency })
const graphEvents = await eventService.getEventsFromGraph({ methodName: 'getStatistic' }) // const graphEvents = await eventService.getEventsFromGraph({ methodName: 'getStatistic' })
const graphEvents = await fetchEvents({
netId,
type: 'deposit',
currency,
amount,
recent: true
})
let statistic = graphEvents?.events let statistic = graphEvents?.events
@ -435,10 +442,17 @@ const actions = {
let events = [] let events = []
/**
const { events: graphEvents, lastSyncBlock } = await graph.getAllEncryptedNotes({ const { events: graphEvents, lastSyncBlock } = await graph.getAllEncryptedNotes({
netId, netId,
fromBlock: deployedBlock fromBlock: deployedBlock
}) })
**/
const { events: graphEvents, lastSyncBlock } = await fetchEvents({
netId,
type: 'encrypted_notes',
fromBlock: deployedBlock
})
if (lastSyncBlock) { if (lastSyncBlock) {
deployedBlock = lastSyncBlock deployedBlock = lastSyncBlock
@ -869,7 +883,8 @@ const actions = {
timestamp: lastEvent.timestamp, timestamp: lastEvent.timestamp,
leafIndex: lastEvent.leafIndex, leafIndex: lastEvent.leafIndex,
txHash: lastEvent.transactionHash, txHash: lastEvent.transactionHash,
depositBlock: lastEvent.blockNumber depositBlock: lastEvent.blockNumber,
from: lastEvent.from
} }
} }
} catch (err) { } catch (err) {
@ -893,7 +908,8 @@ const actions = {
to: lastEvent.to, to: lastEvent.to,
fee: lastEvent.fee, fee: lastEvent.fee,
txHash: lastEvent.transactionHash, txHash: lastEvent.transactionHash,
blockNumber: lastEvent.blockNumber blockNumber: lastEvent.blockNumber,
timestamp: lastEvent.timestamp
} }
} }
} catch (err) { } catch (err) {

@ -1,6 +1,6 @@
/* eslint-disable no-console */ /* eslint-disable no-console */
import { toWei, fromWei, toBN } from 'web3-utils' import { toWei, fromWei, toBN } from 'web3-utils'
import { TornadoFeeOracleV4, TornadoFeeOracleV5 } from '@tornado/tornado-oracles' import { TornadoFeeOracleV6 } from '@tornado/tornado-oracles'
export const state = () => { export const state = () => {
return { return {
@ -14,12 +14,12 @@ export const getters = {
oracle: (state, getters, rootState, rootGetters) => { oracle: (state, getters, rootState, rootGetters) => {
const netId = Number(rootGetters['metamask/netId']) const netId = Number(rootGetters['metamask/netId'])
const { url: rpcUrl } = rootState.settings[`netId${netId}`].rpc const { url: rpcUrl } = rootState.settings[`netId${netId}`].rpc
const { gasPrices } = rootGetters['metamask/networkConfig']
// Compatibility with old BSC relayers
const overrideGasPrice = netId === 56 ? { gasPrice: toWei('3.3', 'gwei').toString() } : undefined
// Return old oracle for backwards compatibility, if chain is ETH Mainnet // Return old oracle for backwards compatibility, if chain is ETH Mainnet
return netId === 1 return new TornadoFeeOracleV6(netId, rpcUrl, overrideGasPrice)
? new TornadoFeeOracleV4(netId, rpcUrl, gasPrices)
: new TornadoFeeOracleV5(netId, rpcUrl, gasPrices)
}, },
getGasPriceParams: (state) => { getGasPriceParams: (state) => {
return state.gasPriceParams return state.gasPriceParams
@ -77,16 +77,16 @@ export const actions = {
if (currency !== nativeCurrency) if (currency !== nativeCurrency)
await dispatch('application/setDefaultEthToReceive', { currency }, { root: true }) await dispatch('application/setDefaultEthToReceive', { currency }, { root: true })
const withdrawalFee = await getters.oracle.calculateWithdrawalFeeViaRelayer( const withdrawalFee = await getters.oracle.calculateWithdrawalFeeViaRelayer({
'user_withdrawal',
tx, tx,
feePercent, txType: 'user_withdrawal',
currency.toLowerCase(), relayerFeePercent: feePercent,
currency: currency.toLowerCase(),
amount, amount,
decimals, decimals,
rootState.application.ethToReceive || 0, refundInEth: rootState.application.ethToReceive || 0,
rootState.price.prices[currency.toLowerCase()] tokenPriceInEth: rootState.price.prices[currency.toLowerCase()]
) })
commit('SAVE_WITHDRAWAL_FEE_VIA_RELAYER', toBN(withdrawalFee)) commit('SAVE_WITHDRAWAL_FEE_VIA_RELAYER', toBN(withdrawalFee))
} }

@ -12,6 +12,8 @@ import AggregatorABI from '@/abis/Aggregator.abi.json'
import { httpConfig } from '@/constants' import { httpConfig } from '@/constants'
import { fetchEvents } from '@/services'
const { numberToHex, toWei, fromWei, toBN, hexToNumber, hexToNumberString } = require('web3-utils') const { numberToHex, toWei, fromWei, toBN, hexToNumber, hexToNumberString } = require('web3-utils')
const state = () => { const state = () => {
@ -682,10 +684,26 @@ const actions = {
} }
const [events, statuses] = await Promise.all([ const [events, statuses] = await Promise.all([
govInstance.getPastEvents('ProposalCreated', { (async () => {
fromBlock: config.constants.GOVERNANCE_BLOCK, try {
toBlock: 'latest' const { events } = await fetchEvents({
}), netId,
type: 'governance',
fromBlock: config.constants.GOVERNANCE_BLOCK
})
if (!events?.length) {
throw new Error('0 length')
}
return events.filter((e) => e.event === 'ProposalCreated')
} catch {
return govInstance.getPastEvents('ProposalCreated', {
fromBlock: config.constants.GOVERNANCE_BLOCK,
toBlock: 'latest'
})
}
})(),
aggregatorContract.methods.getAllProposals(govInstance._address).call() aggregatorContract.methods.getAllProposals(govInstance._address).call()
]) ])
@ -735,17 +753,41 @@ const actions = {
} }
proposals = events proposals = events
.map(({ returnValues, blockNumber }, index) => { .map((event, index) => {
const id = Number(returnValues.id) const { returnValues, blockNumber } = event
if (returnValues) {
const id = Number(returnValues.id)
const { state, startTime, endTime, forVotes, againstVotes } = statuses[index]
const { title, description } = parseDescription({ id, text: returnValues.description })
return {
id,
title,
description,
target: returnValues.target,
proposer: returnValues.proposer,
endTime: Number(endTime),
startTime: Number(startTime),
status: ProposalState[Number(state)],
blockNumber,
results: {
for: fromWei(forVotes),
against: fromWei(againstVotes)
}
}
}
const id = event.id
const { state, startTime, endTime, forVotes, againstVotes } = statuses[index] const { state, startTime, endTime, forVotes, againstVotes } = statuses[index]
const { title, description } = parseDescription({ id, text: returnValues.description }) const { title, description } = parseDescription({ id, text: event.description })
return { return {
id, id,
title, title,
description, description,
target: returnValues.target, target: event.target,
proposer: returnValues.proposer, proposer: event.proposer,
endTime: Number(endTime), endTime: Number(endTime),
startTime: Number(startTime), startTime: Number(startTime),
status: ProposalState[Number(state)], status: ProposalState[Number(state)],
@ -844,22 +886,44 @@ const actions = {
const aggregatorContract = getters.aggregatorContract const aggregatorContract = getters.aggregatorContract
const govInstance = getters.govContract({ netId }) const govInstance = getters.govContract({ netId })
let delegatedAccs = await govInstance.getPastEvents('Delegated', { let delegatedAccs, undelegatedAccs
filter: {
to: ethAccount try {
}, const { events } = await fetchEvents({
fromBlock: config.constants.GOVERNANCE_BLOCK, netId,
toBlock: 'latest' type: 'governance',
}) fromBlock: config.constants.GOVERNANCE_BLOCK
let undelegatedAccs = await govInstance.getPastEvents('Undelegated', { })
filter: {
from: ethAccount if (!events?.length) {
}, throw new Error('0 length')
fromBlock: config.constants.GOVERNANCE_BLOCK, }
toBlock: 'latest'
}) delegatedAccs = events
delegatedAccs = delegatedAccs.map((acc) => acc.returnValues.account) .filter((e) => e.event === 'Delegated' && e.delegateTo === ethAccount)
undelegatedAccs = undelegatedAccs.map((acc) => acc.returnValues.account) .map((e) => e.account)
undelegatedAccs = events
.filter((e) => e.event === 'Undelegated' && e.delegateFrom === ethAccount)
.map((e) => e.account)
} catch {
delegatedAccs = await govInstance.getPastEvents('Delegated', {
filter: {
to: ethAccount
},
fromBlock: config.constants.GOVERNANCE_BLOCK,
toBlock: 'latest'
})
undelegatedAccs = await govInstance.getPastEvents('Undelegated', {
filter: {
from: ethAccount
},
fromBlock: config.constants.GOVERNANCE_BLOCK,
toBlock: 'latest'
})
delegatedAccs = delegatedAccs.map((acc) => acc.returnValues.account)
undelegatedAccs = undelegatedAccs.map((acc) => acc.returnValues.account)
}
const uniq = delegatedAccs.filter((obj, index, self) => { const uniq = delegatedAccs.filter((obj, index, self) => {
const indexUndelegated = undelegatedAccs.indexOf(obj) const indexUndelegated = undelegatedAccs.indexOf(obj)
if (indexUndelegated !== -1) { if (indexUndelegated !== -1) {

@ -5,7 +5,7 @@ import { utils } from 'ethers'
import uniqBy from 'lodash/uniqBy' import uniqBy from 'lodash/uniqBy'
import chunk from 'lodash/chunk' import chunk from 'lodash/chunk'
import { lookupAddresses, createBatchRequestCallback } from '@/services' import { lookupAddresses, createBatchRequestCallback, fetchEvents } from '@/services'
import { CHUNK_COUNT_PER_BATCH_REQUEST } from '@/constants' import { CHUNK_COUNT_PER_BATCH_REQUEST } from '@/constants'
const { toWei, fromWei, toBN } = require('web3-utils') const { toWei, fromWei, toBN } = require('web3-utils')
@ -36,21 +36,50 @@ const parseComment = (calldata, govInstance) => {
const createProposalComment = (resultAll, votedEvent) => { const createProposalComment = (resultAll, votedEvent) => {
const { transactionHash, returnValues, blockNumber } = votedEvent const { transactionHash, returnValues, blockNumber } = votedEvent
const { voter } = returnValues
if (returnValues) {
const { voter } = returnValues
const comment = parseComment()
const percentage =
toBN(votedEvent.returnValues.votes)
.mul(toBN(10000))
.divRound(resultAll)
.toNumber() / 100
return {
id: `${transactionHash}-${voter}`,
percentage,
...returnValues,
votes: fromWei(returnValues.votes),
transactionHash,
blockNumber,
...comment,
ens: {
delegator: null,
voter: null
},
delegator: null,
timestamp: null
}
}
const comment = parseComment() const comment = parseComment()
const percentage = const percentage =
toBN(votedEvent.returnValues.votes) toBN(votedEvent.votes)
.mul(toBN(10000)) .mul(toBN(10000))
.divRound(resultAll) .divRound(resultAll)
.toNumber() / 100 .toNumber() / 100
return { return {
id: `${transactionHash}-${voter}`, id: `${transactionHash}-${votedEvent.voter}`,
percentage, percentage,
...returnValues, ...votedEvent,
votes: fromWei(returnValues.votes), votes: fromWei(votedEvent.votes),
transactionHash, transactionHash,
blockNumber, blockNumber,
@ -186,21 +215,45 @@ const actions = {
} }
try { try {
let votedEvents = await govInstance.getPastEvents('Voted', { let votedEvents
filter: {
// support: [false],
proposalId: proposal.id
},
fromBlock,
toBlock: 'latest'
})
console.log('fetchVotedEvents', votedEvents.length) try {
const { events } = await fetchEvents({
netId,
type: 'governance'
})
votedEvents = votedEvents.sort((a, b) => b.blockNumber - a.blockNumber) if (!events?.length) {
votedEvents = uniqBy(votedEvents, 'returnValues.voter') throw new Error('0 length')
}
console.log('fetchVotedEvents uniq', votedEvents.length) votedEvents = events.filter(
({ event, proposalId }) => event === 'Voted' && proposalId === proposal.id
)
console.log('fetchVotedEvents', votedEvents.length)
votedEvents = votedEvents.sort((a, b) => b.blockNumber - a.blockNumber)
votedEvents = uniqBy(votedEvents, 'voter')
console.log('fetchVotedEvents uniq', votedEvents.length)
} catch {
votedEvents = await govInstance.getPastEvents('Voted', {
filter: {
// support: [false],
proposalId: proposal.id
},
fromBlock,
toBlock: 'latest'
})
console.log('fetchVotedEvents', votedEvents.length)
votedEvents = votedEvents.sort((a, b) => b.blockNumber - a.blockNumber)
votedEvents = uniqBy(votedEvents, 'returnValues.voter')
console.log('fetchVotedEvents uniq', votedEvents.length)
}
const resultAll = toBN(toWei(proposal.results.for)).add(toBN(toWei(proposal.results.against))) const resultAll = toBN(toWei(proposal.results.for)).add(toBN(toWei(proposal.results.against)))
let newComments = votedEvents.map((votedEvent) => createProposalComment(resultAll, votedEvent)) let newComments = votedEvents.map((votedEvent) => createProposalComment(resultAll, votedEvent))

@ -19,7 +19,7 @@ export const getters = {
const netId = Number(rootGetters['metamask/netId']) const netId = Number(rootGetters['metamask/netId'])
const { url: rpcUrl } = rootState.settings[`netId${netId}`].rpc const { url: rpcUrl } = rootState.settings[`netId${netId}`].rpc
return new TokenPriceOracle(rpcUrl) return new TokenPriceOracle(rpcUrl, undefined, undefined, netId)
}, },
tokenRate: (state, getters, rootState) => { tokenRate: (state, getters, rootState) => {
return state.prices[rootState.application.selectedStatistic.currency] return state.prices[rootState.application.selectedStatistic.currency]
@ -44,13 +44,34 @@ export const mutations = {
} }
export const actions = { export const actions = {
async fetchTokenPrice({ getters, commit, dispatch, rootState }) { async fetchTokenPrice({ rootGetters, getters, commit, dispatch, rootState }) {
if (getters.isPriceWatcherDisabled) { if (getters.isPriceWatcherDisabled) {
return return
} }
const config = rootGetters['metamask/networkConfig']
const tokens = Object.entries(config.tokens).reduce((acc, [symbol, { tokenAddress, decimals }]) => {
if (tokenAddress) {
acc.push({
tokenAddress,
symbol,
decimals
})
}
return acc
}, [])
if (config['torn.contract.tornadocash.eth']) {
tokens.push({
tokenAddress: config['torn.contract.tornadocash.eth'],
symbol: 'torn',
decimals: 18
})
}
try { try {
const prices = await getters.priceOracle.fetchPrices() const prices = await getters.priceOracle.fetchPrices(tokens)
console.log('prices', prices) console.log('prices', prices)
commit('SAVE_TOKEN_PRICES', prices) commit('SAVE_TOKEN_PRICES', prices)

@ -5,7 +5,7 @@ import namehash from 'eth-ens-namehash'
import { httpConfig } from '@/constants' import { httpConfig } from '@/constants'
import { schema, relayerRegisterService } from '@/services' import { schema, relayerRegisterService } from '@/services'
import { createChainIdState, parseNote, parseSemanticVersion } from '@/utils' import { createChainIdState, parseNote } from '@/utils'
import ENSABI from '@/abis/ENS.abi.json' import ENSABI from '@/abis/ENS.abi.json'
import networkConfig from '@/networkConfig' import networkConfig from '@/networkConfig'
@ -43,7 +43,6 @@ const pickWeightedRandomRelayer = (items, netId) => {
if (netId !== 1) { if (netId !== 1) {
minFee = 0.01 minFee = 0.01
maxFee = 0.3
} }
const weightsScores = items.map((el) => calculateScore(el, minFee, maxFee)) const weightsScores = items.map((el) => calculateScore(el, minFee, maxFee))
@ -196,7 +195,7 @@ export const mutations = {
export const actions = { export const actions = {
async askRelayerStatus( async askRelayerStatus(
{ rootState, dispatch, rootGetters }, { rootState, dispatch, rootGetters },
{ hostname, relayerAddress, stakeBalance, ensName } { url, hostname, relayerAddress, stakeBalance, ensName }
) { ) {
try { try {
const axios = await getAxios() const axios = await getAxios()
@ -205,7 +204,10 @@ export const actions = {
hostname += '/' hostname += '/'
} }
const url = `${window.location.protocol}//${hostname}` if (!url) {
url = `${window.location.protocol}//${hostname}`
}
const reqConfig = { const reqConfig = {
headers: { headers: {
'Content-Type': 'application/json, application/x-www-form-urlencoded' 'Content-Type': 'application/json, application/x-www-form-urlencoded'
@ -240,6 +242,7 @@ export const actions = {
throw new Error(this.app.i18n.t('canNotFetchStatusFromTheRelayer')) throw new Error(this.app.i18n.t('canNotFetchStatusFromTheRelayer'))
} }
/**
const isRelayerUpdated = () => { const isRelayerUpdated = () => {
const relayerVersion = response.data.version const relayerVersion = response.data.version
@ -255,6 +258,7 @@ export const actions = {
if (!isRelayerUpdated()) { if (!isRelayerUpdated()) {
throw new Error('Outdated version.') throw new Error('Outdated version.')
} }
**/
return { return {
isValid, isValid,
@ -335,10 +339,11 @@ export const actions = {
async getKnownRelayerData({ rootGetters, getters }, { relayerAddress, name }) { async getKnownRelayerData({ rootGetters, getters }, { relayerAddress, name }) {
const { ensSubdomainKey } = rootGetters['metamask/networkConfig'] const { ensSubdomainKey } = rootGetters['metamask/networkConfig']
const [validRelayer] = await relayerRegisterService(getters.ethProvider).getValidRelayers( const validRelayers = await relayerRegisterService(getters.ethProvider).getValidRelayers(
[{ relayerAddress, ensName: name.replace(`${ensSubdomainKey}.`, '') }], [{ relayerAddress, ensName: name.replace(`${ensSubdomainKey}.`, '') }],
ensSubdomainKey ensSubdomainKey
) )
const validRelayer = validRelayers.find((r) => r.relayerAddress === relayerAddress)
console.warn('validRelayer', validRelayer) console.warn('validRelayer', validRelayer)
return validRelayer return validRelayer
}, },
@ -378,7 +383,7 @@ export const actions = {
const hostname = urlParser.host const hostname = urlParser.host
return { hostname, ensName, stakeBalance: 0 } return { url, hostname, ensName, stakeBalance: 0 }
}, },
async getRelayerData({ state, dispatch }, { url, name }) { async getRelayerData({ state, dispatch }, { url, name }) {
const knownRelayer = state.validRelayers.find((el) => el.name === name) const knownRelayer = state.validRelayers.find((el) => el.name === name)

@ -149,8 +149,12 @@ export const actions = {
async approve({ rootState, getters, dispatch, rootGetters, state }) { async approve({ rootState, getters, dispatch, rootGetters, state }) {
try { try {
const netId = rootGetters['metamask/netId'] const netId = rootGetters['metamask/netId']
const { currency } = rootState.application.selectedInstance const { currency, amount } = rootState.application.selectedInstance
const { decimals } = rootGetters['metamask/networkConfig'].tokens[currency] const {
decimals,
instanceAddress: { [amount]: instanceAddress },
instanceApproval
} = rootGetters['metamask/networkConfig'].tokens[currency]
const tokenInstance = getters.tokenContract({ currency, netId }) const tokenInstance = getters.tokenContract({ currency, netId })
const tornadoProxy = rootGetters['application/tornadoProxyContract']({ netId }) const tornadoProxy = rootGetters['application/tornadoProxyContract']({ netId })
@ -160,10 +164,10 @@ export const actions = {
? toBN('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff') ? toBN('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff')
: toBN(getters.fromDecimals(state.approvalAmount, decimals)) : toBN(getters.fromDecimals(state.approvalAmount, decimals))
const data = tokenInstance.methods const data = tokenInstance.methods
.approve(tornadoProxy._address, amountToApprove.toString()) .approve(instanceApproval ? instanceAddress : tornadoProxy._address, amountToApprove.toString())
.encodeABI() .encodeABI()
const gas = await tokenInstance.methods const gas = await tokenInstance.methods
.approve(tornadoProxy._address, amountToApprove.toString()) .approve(instanceApproval ? instanceAddress : tornadoProxy._address, amountToApprove.toString())
.estimateGas({ .estimateGas({
from: ethAccount from: ethAccount
}) })
@ -190,14 +194,20 @@ export const actions = {
}, },
async fetchTokenAllowance({ getters, rootGetters, commit, rootState }) { async fetchTokenAllowance({ getters, rootGetters, commit, rootState }) {
const netId = rootGetters['metamask/netId'] const netId = rootGetters['metamask/netId']
const { currency } = rootState.application.selectedInstance const { currency, amount } = rootState.application.selectedInstance
const { ethAccount } = rootState.metamask const { ethAccount } = rootState.metamask
try { try {
const {
instanceAddress: { [amount]: instanceAddress },
instanceApproval
} = rootGetters['metamask/networkConfig'].tokens[currency]
const tornadoInstance = rootGetters['application/tornadoProxyContract']({ netId }) const tornadoInstance = rootGetters['application/tornadoProxyContract']({ netId })
const nativeCurrency = rootGetters['metamask/nativeCurrency'] const nativeCurrency = rootGetters['metamask/nativeCurrency']
if (currency !== nativeCurrency && ethAccount) { if (currency !== nativeCurrency && ethAccount) {
const tokenInstance = getters.tokenContract({ currency, netId }) const tokenInstance = getters.tokenContract({ currency, netId })
const allowance = await tokenInstance.methods.allowance(ethAccount, tornadoInstance._address).call() const allowance = await tokenInstance.methods
.allowance(ethAccount, instanceApproval ? instanceAddress : tornadoInstance._address)
.call()
commit('SAVE_ALLOWANCE', { allowance }) commit('SAVE_ALLOWANCE', { allowance })
} }
} catch (e) { } catch (e) {

@ -2456,15 +2456,6 @@
resolved "https://git.tornado.ws/api/packages/tornado-packages/npm/%40tornado%2Ffixed-merkle-tree/-/0.7.3/fixed-merkle-tree-0.7.3.tgz#6636ce9d334553c5f17e5a564fd22f2e9ec04472" resolved "https://git.tornado.ws/api/packages/tornado-packages/npm/%40tornado%2Ffixed-merkle-tree/-/0.7.3/fixed-merkle-tree-0.7.3.tgz#6636ce9d334553c5f17e5a564fd22f2e9ec04472"
integrity sha512-8UWvIzz0/rMGBkzXACwmCv/5I1VJmnshAKc4C+nkTfOdmnX8Pf1bBa0GlxUIZ25ZFGiU/h2IKEHYckmHovwzEA== integrity sha512-8UWvIzz0/rMGBkzXACwmCv/5I1VJmnshAKc4C+nkTfOdmnX8Pf1bBa0GlxUIZ25ZFGiU/h2IKEHYckmHovwzEA==
"@tornado/gas-price-oracle@^0.5.3":
version "0.5.3"
resolved "https://git.tornado.ws/api/packages/tornado-packages/npm/%40tornado%2Fgas-price-oracle/-/0.5.3/gas-price-oracle-0.5.3.tgz#fb5423dddee2f52edbc16174c5ddce90bea5413d"
integrity sha512-LpVfPiPIz3FOmJdiqJf/yoeO5n9/Pd5jgtdY+6hB9lNW0AiWhylhpScojICViS+3OL9QC8CoTlgr+kbfGeO9pQ==
dependencies:
axios "^0.21.2"
bignumber.js "^9.0.0"
node-cache "^5.1.2"
"@tornado/snarkjs@0.1.20", "@tornado/snarkjs@^0.1.20": "@tornado/snarkjs@0.1.20", "@tornado/snarkjs@^0.1.20":
version "0.1.20" version "0.1.20"
resolved "https://git.tornado.ws/api/packages/tornado-packages/npm/%40tornado%2Fsnarkjs/-/0.1.20/snarkjs-0.1.20.tgz#d7610cd3c8dc10598da7dc3e40e5d7470c3aa8c7" resolved "https://git.tornado.ws/api/packages/tornado-packages/npm/%40tornado%2Fsnarkjs/-/0.1.20/snarkjs-0.1.20.tgz#d7610cd3c8dc10598da7dc3e40e5d7470c3aa8c7"
@ -2482,12 +2473,10 @@
resolved "https://git.tornado.ws/api/packages/tornado-packages/npm/%40tornado%2Ftornado-config/-/2.0.0/tornado-config-2.0.0.tgz#52bbc179ecb2385f71b4d56e060b68e7dd6fb8b4" resolved "https://git.tornado.ws/api/packages/tornado-packages/npm/%40tornado%2Ftornado-config/-/2.0.0/tornado-config-2.0.0.tgz#52bbc179ecb2385f71b4d56e060b68e7dd6fb8b4"
integrity sha512-7EkpWNfEm34VEOrbLnPpvd/aUJYnA1L+6/qx2fZ/AfmuJFkjSZ18Z4jvVGNY7ktKIhTu3/Tbze+9l3eNueCNIA== integrity sha512-7EkpWNfEm34VEOrbLnPpvd/aUJYnA1L+6/qx2fZ/AfmuJFkjSZ18Z4jvVGNY7ktKIhTu3/Tbze+9l3eNueCNIA==
"@tornado/tornado-oracles@^2.1.0": "@tornado/tornado-oracles@git+https://git.tornado.ws/tornadocontrib/tornado-oracles.git#c9f43ff29266c48dc030a3b66e818201ff4cfc8d":
version "2.1.0" version "3.4.0"
resolved "https://git.tornado.ws/api/packages/tornado-packages/npm/%40tornado%2Ftornado-oracles/-/2.1.0/tornado-oracles-2.1.0.tgz#2aa0d8c9288992e6d194d4bb28acb37c2035c453" resolved "git+https://git.tornado.ws/tornadocontrib/tornado-oracles.git#c9f43ff29266c48dc030a3b66e818201ff4cfc8d"
integrity sha512-Y6FPAGnCvHLWzUnNYgGoOv+X7KY3CF02rRSawataYaLyl+v2ivh7RYZZZ3G/B5hXf+pD3IFeCdm4PDnTNyNe1g==
dependencies: dependencies:
"@tornado/gas-price-oracle" "^0.5.3"
"@tornado/tornado-config" "^2.0.0" "@tornado/tornado-config" "^2.0.0"
"@types/node" "^20.5.1" "@types/node" "^20.5.1"
bignumber.js "^9.1.1" bignumber.js "^9.1.1"
@ -3682,13 +3671,6 @@ axios@^0.19.0:
follow-redirects "1.5.10" follow-redirects "1.5.10"
is-buffer "^2.0.2" is-buffer "^2.0.2"
axios@^0.21.2:
version "0.21.4"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575"
integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==
dependencies:
follow-redirects "^1.14.0"
b4a@^1.0.1: b4a@^1.0.1:
version "1.3.1" version "1.3.1"
resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.3.1.tgz#5ead1402bd4a2dcfea35cc83928815d53315ff32" resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.3.1.tgz#5ead1402bd4a2dcfea35cc83928815d53315ff32"
@ -8037,11 +8019,6 @@ follow-redirects@1.5.10:
dependencies: dependencies:
debug "=3.1.0" debug "=3.1.0"
follow-redirects@^1.14.0:
version "1.15.2"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
for-in@^1.0.1, for-in@^1.0.2: for-in@^1.0.1, for-in@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
@ -11448,13 +11425,6 @@ node-cache@^4.1.1:
clone "2.x" clone "2.x"
lodash "^4.17.15" lodash "^4.17.15"
node-cache@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/node-cache/-/node-cache-5.1.2.tgz#f264dc2ccad0a780e76253a694e9fd0ed19c398d"
integrity sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==
dependencies:
clone "2.x"
node-fetch@2.6.1, node-fetch@^2.6.1: node-fetch@2.6.1, node-fetch@^2.6.1:
version "2.6.1" version "2.6.1"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"