init
This commit is contained in:
commit
44f31f8b9f
402 changed files with 47865 additions and 0 deletions
688
store/relayer.js
Normal file
688
store/relayer.js
Normal file
|
@ -0,0 +1,688 @@
|
|||
/* eslint-disable no-console */
|
||||
import Web3 from 'web3'
|
||||
import BN from 'bignumber.js'
|
||||
import namehash from 'eth-ens-namehash'
|
||||
|
||||
import { schema, relayerRegisterService } from '@/services'
|
||||
import { createChainIdState, parseNote, parseSemanticVersion } from '@/utils'
|
||||
|
||||
import ENSABI from '@/abis/ENS.abi.json'
|
||||
import networkConfig from '@/networkConfig'
|
||||
|
||||
const getAxios = () => {
|
||||
return import('axios')
|
||||
}
|
||||
|
||||
const calculateScore = ({ stakeBalance, tornadoServiceFee }, minFee = 0.33, maxFee = 0.53) => {
|
||||
if (tornadoServiceFee < minFee) {
|
||||
tornadoServiceFee = minFee
|
||||
} else if (tornadoServiceFee >= maxFee) {
|
||||
return new BN(0)
|
||||
}
|
||||
|
||||
const serviceFeeCoefficient = (tornadoServiceFee - minFee) ** 2
|
||||
const feeDiffCoefficient = 1 / (maxFee - minFee) ** 2
|
||||
const coefficientsMultiplier = 1 - feeDiffCoefficient * serviceFeeCoefficient
|
||||
|
||||
return new BN(stakeBalance).multipliedBy(coefficientsMultiplier)
|
||||
}
|
||||
|
||||
const getWeightRandom = (weightsScores, random) => {
|
||||
for (let i = 0; i < weightsScores.length; i++) {
|
||||
if (random.isLessThan(weightsScores[i])) {
|
||||
return i
|
||||
}
|
||||
random = random.minus(weightsScores[i])
|
||||
}
|
||||
return Math.floor(Math.random() * weightsScores.length)
|
||||
}
|
||||
|
||||
const pickWeightedRandomRelayer = (items, netId) => {
|
||||
let minFee, maxFee
|
||||
|
||||
if (netId !== 1) {
|
||||
minFee = 0.01
|
||||
maxFee = 0.3
|
||||
}
|
||||
|
||||
const weightsScores = items.map((el) => calculateScore(el, minFee, maxFee))
|
||||
const totalWeight = weightsScores.reduce((acc, curr) => {
|
||||
return (acc = acc.plus(curr))
|
||||
}, new BN('0'))
|
||||
|
||||
const random = totalWeight.multipliedBy(Math.random())
|
||||
const weightRandomIndex = getWeightRandom(weightsScores, random)
|
||||
|
||||
return items[weightRandomIndex]
|
||||
}
|
||||
|
||||
const initialJobsState = createChainIdState({
|
||||
tornado: {}
|
||||
})
|
||||
|
||||
export const state = () => {
|
||||
return {
|
||||
prices: {
|
||||
dai: '6700000000000000'
|
||||
},
|
||||
selectedRelayer: {
|
||||
url: '',
|
||||
name: '',
|
||||
stakeBalance: 0,
|
||||
tornadoServiceFee: 0.05,
|
||||
miningServiceFee: 0.05,
|
||||
address: null,
|
||||
ethPrices: {
|
||||
torn: '1'
|
||||
}
|
||||
},
|
||||
isLoadingRelayers: false,
|
||||
validRelayers: [],
|
||||
jobs: initialJobsState,
|
||||
jobWatchers: {}
|
||||
}
|
||||
}
|
||||
|
||||
export const getters = {
|
||||
ethProvider: (state, getters, rootState) => {
|
||||
const { url } = rootState.settings.netId1.rpc
|
||||
|
||||
return new Web3(url)
|
||||
},
|
||||
jobs: (state, getters, rootState, rootGetters) => (type) => {
|
||||
const netId = rootGetters['metamask/netId']
|
||||
const jobsToRender = Object.entries(state.jobs[`netId${netId}`][type])
|
||||
.reverse()
|
||||
.map(
|
||||
([
|
||||
id,
|
||||
{
|
||||
action,
|
||||
relayerUrl,
|
||||
amount,
|
||||
currency,
|
||||
fee,
|
||||
timestamp,
|
||||
txHash,
|
||||
confirmations,
|
||||
status,
|
||||
failedReason
|
||||
}
|
||||
]) => {
|
||||
return {
|
||||
id,
|
||||
action,
|
||||
relayerUrl,
|
||||
amount,
|
||||
currency,
|
||||
fee,
|
||||
timestamp,
|
||||
txHash,
|
||||
confirmations,
|
||||
status,
|
||||
failedReason
|
||||
}
|
||||
}
|
||||
)
|
||||
return jobsToRender
|
||||
}
|
||||
}
|
||||
|
||||
export const mutations = {
|
||||
SET_SELECTED_RELAYER(state, payload) {
|
||||
this._vm.$set(state, 'selectedRelayer', payload)
|
||||
},
|
||||
SAVE_VALIDATED_RELAYERS(state, relayers) {
|
||||
state.validRelayers = relayers
|
||||
},
|
||||
SAVE_JOB(
|
||||
state,
|
||||
{
|
||||
id,
|
||||
netId,
|
||||
type,
|
||||
action,
|
||||
relayerUrl,
|
||||
amount,
|
||||
currency,
|
||||
fee,
|
||||
commitmentHex,
|
||||
timestamp,
|
||||
note,
|
||||
accountAfter,
|
||||
account
|
||||
}
|
||||
) {
|
||||
this._vm.$set(state.jobs[`netId${netId}`][type], id, {
|
||||
action,
|
||||
relayerUrl,
|
||||
amount,
|
||||
currency,
|
||||
fee,
|
||||
commitmentHex,
|
||||
timestamp,
|
||||
note,
|
||||
accountAfter,
|
||||
account
|
||||
})
|
||||
},
|
||||
UPDATE_JOB(state, { id, netId, type, txHash, confirmations, status, failedReason }) {
|
||||
const job = state.jobs[`netId${netId}`][type][id]
|
||||
this._vm.$set(state.jobs[`netId${netId}`][type], id, {
|
||||
...job,
|
||||
txHash,
|
||||
confirmations,
|
||||
status,
|
||||
failedReason
|
||||
})
|
||||
},
|
||||
DELETE_JOB(state, { id, netId, type }) {
|
||||
this._vm.$delete(state.jobs[`netId${netId}`][type], id)
|
||||
},
|
||||
ADD_JOB_WATCHER(state, { id, timerId }) {
|
||||
this._vm.$set(state.jobWatchers, id, {
|
||||
timerId
|
||||
})
|
||||
},
|
||||
DELETE_JOB_WATCHER(state, { id }) {
|
||||
this._vm.$delete(state.jobWatchers, id)
|
||||
},
|
||||
SET_IS_LOADING_RELAYERS(state, isLoadingRelayers) {
|
||||
state.isLoadingRelayers = isLoadingRelayers
|
||||
}
|
||||
}
|
||||
|
||||
export const actions = {
|
||||
async askRelayerStatus(
|
||||
{ rootState, dispatch, rootGetters },
|
||||
{ hostname, relayerAddress, stakeBalance, ensName }
|
||||
) {
|
||||
try {
|
||||
const axios = await getAxios()
|
||||
|
||||
if (!hostname.endsWith('/')) {
|
||||
hostname += '/'
|
||||
}
|
||||
|
||||
const url = `${window.location.protocol}//${hostname}`
|
||||
const response = await axios.get(`${url}status`, { timeout: 5000 }).catch(() => {
|
||||
throw new Error(this.app.i18n.t('canNotFetchStatusFromTheRelayer'))
|
||||
})
|
||||
|
||||
if (Number(response.data.currentQueue) > 5) {
|
||||
throw new Error(this.app.i18n.t('withdrawalQueueIsOverloaded'))
|
||||
}
|
||||
|
||||
const netId = Number(rootGetters['metamask/netId'])
|
||||
|
||||
if (Number(response.data.netId) !== netId) {
|
||||
throw new Error(this.app.i18n.t('thisRelayerServesADifferentNetwork'))
|
||||
}
|
||||
|
||||
const validate = schema.getRelayerValidateFunction(netId)
|
||||
|
||||
// check rewardAccount === relayerAddress for TORN burn, custom relayer - exception
|
||||
if (netId === 1 && relayerAddress && response.data.rewardAccount !== relayerAddress) {
|
||||
throw new Error('The Relayer reward address must match registered address')
|
||||
}
|
||||
|
||||
const isValid = validate(response.data)
|
||||
if (!isValid) {
|
||||
console.error('askRelayerStatus', ensName, validate?.errors)
|
||||
|
||||
throw new Error(this.app.i18n.t('canNotFetchStatusFromTheRelayer'))
|
||||
}
|
||||
|
||||
const hasEnabledLightProxy = rootGetters['application/hasEnabledLightProxy']
|
||||
|
||||
const getIsUpdated = () => {
|
||||
const requiredMajor = hasEnabledLightProxy ? '5' : '4'
|
||||
const { major, prerelease } = parseSemanticVersion(response.data.version)
|
||||
|
||||
const isUpdatedMajor = major === requiredMajor
|
||||
|
||||
if (isUpdatedMajor && prerelease && netId === 42161) {
|
||||
const minimalBeta = 10
|
||||
const [betaVersion] = prerelease.split('.').slice(-1)
|
||||
return Number(betaVersion) >= minimalBeta
|
||||
}
|
||||
|
||||
return isUpdatedMajor
|
||||
}
|
||||
|
||||
if (!getIsUpdated()) {
|
||||
throw new Error('Outdated version.')
|
||||
}
|
||||
|
||||
return {
|
||||
isValid,
|
||||
realUrl: url,
|
||||
stakeBalance,
|
||||
name: ensName,
|
||||
relayerAddress,
|
||||
netId: response.data.netId,
|
||||
ethPrices: response.data.ethPrices,
|
||||
address: response.data.rewardAccount,
|
||||
currentQueue: response.data.currentQueue,
|
||||
miningServiceFee: response.data.miningServiceFee,
|
||||
tornadoServiceFee: response.data.tornadoServiceFee
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('askRelayerStatus', ensName, e.message)
|
||||
return { isValid: false, error: e.message }
|
||||
}
|
||||
},
|
||||
async observeRelayer({ dispatch }, { relayer }) {
|
||||
const result = await dispatch('askRelayerStatus', relayer)
|
||||
|
||||
return result
|
||||
},
|
||||
async pickRandomRelayer({ rootGetters, commit, dispatch, getters }) {
|
||||
const netId = rootGetters['metamask/netId']
|
||||
const { ensSubdomainKey } = rootGetters['metamask/networkConfig']
|
||||
|
||||
commit('SET_IS_LOADING_RELAYERS', true)
|
||||
|
||||
const registeredRelayers = await relayerRegisterService(getters.ethProvider).getRelayers(ensSubdomainKey)
|
||||
|
||||
const requests = []
|
||||
for (const registeredRelayer of registeredRelayers) {
|
||||
requests.push(dispatch('observeRelayer', { relayer: registeredRelayer }))
|
||||
}
|
||||
let statuses = await Promise.all(requests)
|
||||
|
||||
statuses = statuses.filter((status) => status.isValid)
|
||||
// const validRelayerENSnames = statuses.map((relayer) => relayer.name)
|
||||
commit('SAVE_VALIDATED_RELAYERS', statuses)
|
||||
console.log('filtered statuses ', statuses)
|
||||
|
||||
try {
|
||||
const {
|
||||
name,
|
||||
realUrl,
|
||||
address,
|
||||
ethPrices,
|
||||
stakeBalance,
|
||||
tornadoServiceFee,
|
||||
miningServiceFee
|
||||
} = pickWeightedRandomRelayer(statuses, netId)
|
||||
|
||||
console.log('Selected relayer', name, tornadoServiceFee)
|
||||
commit('SET_SELECTED_RELAYER', {
|
||||
name,
|
||||
address,
|
||||
ethPrices,
|
||||
url: realUrl,
|
||||
stakeBalance,
|
||||
tornadoServiceFee,
|
||||
miningServiceFee
|
||||
})
|
||||
} catch {
|
||||
console.error('Method pickRandomRelayer has not picked relayer')
|
||||
}
|
||||
|
||||
commit('SET_IS_LOADING_RELAYERS', false)
|
||||
},
|
||||
async getKnownRelayerData({ rootGetters, getters }, { relayerAddress, name }) {
|
||||
const { ensSubdomainKey } = rootGetters['metamask/networkConfig']
|
||||
|
||||
const [validRelayer] = await relayerRegisterService(getters.ethProvider).getValidRelayers(
|
||||
[{ relayerAddress, ensName: name.replace(`${ensSubdomainKey}.`, '') }],
|
||||
ensSubdomainKey
|
||||
)
|
||||
console.warn('validRelayer', validRelayer)
|
||||
return validRelayer
|
||||
},
|
||||
async getCustomRelayerData({ rootState, state, getters, rootGetters, dispatch }, { url, name }) {
|
||||
const provider = getters.ethProvider.eth
|
||||
|
||||
if (!url.startsWith('https:') && !url.startsWith('http:')) {
|
||||
if (url.includes('.onion')) {
|
||||
url = `http://${url}`
|
||||
} else {
|
||||
url = `https://${url}`
|
||||
}
|
||||
}
|
||||
const urlParser = new URL(url)
|
||||
urlParser.href = url
|
||||
let ensName = name
|
||||
|
||||
if (urlParser.hostname.endsWith('.eth')) {
|
||||
ensName = urlParser.hostname
|
||||
let resolverInstance = await provider.ens.getResolver(ensName)
|
||||
|
||||
if (new BN(resolverInstance._address).isZero()) {
|
||||
throw new Error('missingENSSubdomain')
|
||||
}
|
||||
resolverInstance = new provider.Contract(ENSABI, resolverInstance._address)
|
||||
|
||||
const ensNameHash = namehash.hash(ensName)
|
||||
const hostname = await resolverInstance.methods.text(ensNameHash, 'url').call()
|
||||
|
||||
if (!hostname) {
|
||||
throw new Error('canNotFetchStatusFromTheRelayer')
|
||||
}
|
||||
urlParser.host = hostname
|
||||
}
|
||||
|
||||
const hostname = urlParser.host
|
||||
|
||||
return { hostname, ensName, stakeBalance: 0 }
|
||||
},
|
||||
async getRelayerData({ state, dispatch }, { url, name }) {
|
||||
const knownRelayer = state.validRelayers.find((el) => el.name === name)
|
||||
|
||||
if (knownRelayer) {
|
||||
const knownRelayerData = await dispatch('getKnownRelayerData', knownRelayer)
|
||||
return knownRelayerData
|
||||
}
|
||||
|
||||
const customRelayerData = await dispatch('getCustomRelayerData', { url, name })
|
||||
return customRelayerData
|
||||
},
|
||||
async setupRelayer({ commit, rootState, dispatch }, { url, name }) {
|
||||
try {
|
||||
const relayerData = await dispatch('getRelayerData', { url, name })
|
||||
|
||||
const {
|
||||
error,
|
||||
isValid,
|
||||
realUrl,
|
||||
address,
|
||||
ethPrices,
|
||||
miningServiceFee,
|
||||
tornadoServiceFee
|
||||
} = await dispatch('askRelayerStatus', relayerData)
|
||||
|
||||
if (!isValid) {
|
||||
return { error, isValid: false }
|
||||
}
|
||||
|
||||
return {
|
||||
isValid,
|
||||
name,
|
||||
url: realUrl || '',
|
||||
address: address || '',
|
||||
tornadoServiceFee: tornadoServiceFee || 0.0,
|
||||
miningServiceFee: miningServiceFee || 0.0,
|
||||
ethPrices: ethPrices || { torn: '1' }
|
||||
}
|
||||
} catch (err) {
|
||||
return {
|
||||
isValid: false,
|
||||
error: this.app.i18n.t(err.message)
|
||||
}
|
||||
}
|
||||
},
|
||||
async relayTornadoWithdraw({ state, commit, dispatch, rootState }, { note }) {
|
||||
const { currency, netId, amount, commitmentHex } = parseNote(note)
|
||||
|
||||
const config = networkConfig[`netId${netId}`]
|
||||
const contract = config.tokens[currency].instanceAddress[amount]
|
||||
|
||||
try {
|
||||
const { proof, args } = rootState.application.notes[note]
|
||||
const message = {
|
||||
args,
|
||||
proof,
|
||||
contract
|
||||
}
|
||||
|
||||
dispatch(
|
||||
'loading/changeText',
|
||||
{ message: this.app.i18n.t('relayerIsNowSendingYourTransaction') },
|
||||
{ root: true }
|
||||
)
|
||||
|
||||
const response = await fetch(state.selectedRelayer.url + 'v1/tornadoWithdraw', {
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
cache: 'no-cache',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
redirect: 'error',
|
||||
body: JSON.stringify(message)
|
||||
})
|
||||
|
||||
if (response.status === 400) {
|
||||
const { error } = await response.json()
|
||||
throw new Error(error)
|
||||
}
|
||||
|
||||
if (response.status === 200) {
|
||||
const { id } = await response.json()
|
||||
const timestamp = Math.round(new Date().getTime() / 1000)
|
||||
commit('SAVE_JOB', {
|
||||
id,
|
||||
netId,
|
||||
type: 'tornado',
|
||||
action: 'Deposit',
|
||||
relayerUrl: state.selectedRelayer.url,
|
||||
commitmentHex,
|
||||
amount,
|
||||
currency,
|
||||
timestamp,
|
||||
note
|
||||
})
|
||||
|
||||
dispatch('runJobWatcherWithNotifications', { id, type: 'tornado', netId })
|
||||
} else {
|
||||
throw new Error(this.app.i18n.t('unknownError'))
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('relayTornadoWithdraw', e)
|
||||
const { name, url } = state.selectedRelayer
|
||||
throw new Error(this.app.i18n.t('relayRequestFailed', { relayerName: name === 'custom' ? url : name }))
|
||||
}
|
||||
},
|
||||
async runJobWatcherWithNotifications({ dispatch, state }, { routerLink, id, netId, type }) {
|
||||
const { amount, currency } = state.jobs[`netId${netId}`][type][id]
|
||||
const noticeId = await dispatch(
|
||||
'notice/addNotice',
|
||||
{
|
||||
notice: {
|
||||
title: {
|
||||
path: 'withdrawing',
|
||||
amount,
|
||||
currency
|
||||
},
|
||||
type: 'loading',
|
||||
routerLink
|
||||
}
|
||||
},
|
||||
{ root: true }
|
||||
)
|
||||
|
||||
try {
|
||||
await dispatch('runJobWatcher', { id, netId, type, noticeId })
|
||||
dispatch('deleteJob', { id, netId, type })
|
||||
} catch (err) {
|
||||
dispatch(
|
||||
'notice/updateNotice',
|
||||
{
|
||||
id: noticeId,
|
||||
notice: {
|
||||
title: 'transactionFailed',
|
||||
type: 'danger',
|
||||
routerLink: undefined
|
||||
}
|
||||
},
|
||||
{ root: true }
|
||||
)
|
||||
dispatch(
|
||||
'notice/addNoticeWithInterval',
|
||||
{
|
||||
notice: {
|
||||
title: 'relayerError',
|
||||
type: 'danger'
|
||||
}
|
||||
},
|
||||
{ root: true }
|
||||
)
|
||||
}
|
||||
},
|
||||
deleteJob({ state, dispatch, commit }, { id, netId, type }) {
|
||||
dispatch('stopFinishJobWatcher', { id })
|
||||
const { amount, currency, action, fee, txHash, note } = state.jobs[`netId${netId}`][type][id]
|
||||
|
||||
commit('DELETE_JOB', { id, netId, type })
|
||||
|
||||
dispatch(
|
||||
'txHashKeeper/updateDeposit',
|
||||
{ amount, currency, netId, type, action, note, txHash, fee },
|
||||
{ root: true }
|
||||
)
|
||||
},
|
||||
runJobWatcher({ state, dispatch }, { id, netId, type, noticeId }) {
|
||||
console.log('runJobWatcher started for job', id)
|
||||
return new Promise((resolve, reject) => {
|
||||
const getConfirmations = async ({ id, netId, type, noticeId, retryAttempt = 0, noticeCalls = 0 }) => {
|
||||
try {
|
||||
const job = state.jobs[`netId${netId}`][type][id]
|
||||
|
||||
if (job.status === 'FAILED') {
|
||||
retryAttempt = 6
|
||||
throw new Error('Relayer is not responding')
|
||||
}
|
||||
|
||||
const response = await fetch(`${job.relayerUrl}v1/jobs/${id}`, {
|
||||
method: 'GET',
|
||||
mode: 'cors',
|
||||
cache: 'no-cache',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
redirect: 'error'
|
||||
})
|
||||
if (response.status === 400) {
|
||||
const { error } = await response.json()
|
||||
console.error('runJobWatcher', error)
|
||||
throw new Error(this.app.i18n.t('relayerError'))
|
||||
}
|
||||
|
||||
if (response.status === 200) {
|
||||
await dispatch('handleResponse', {
|
||||
id,
|
||||
response,
|
||||
job,
|
||||
type,
|
||||
netId,
|
||||
retryAttempt,
|
||||
noticeId,
|
||||
noticeCalls,
|
||||
resolve,
|
||||
getConfirmations
|
||||
})
|
||||
} else {
|
||||
throw new Error(this.app.i18n.t('unknownError'))
|
||||
}
|
||||
} catch (e) {
|
||||
if (retryAttempt < 5) {
|
||||
retryAttempt++
|
||||
|
||||
setTimeout(
|
||||
() =>
|
||||
getConfirmations({
|
||||
id,
|
||||
netId,
|
||||
type,
|
||||
noticeId,
|
||||
retryAttempt,
|
||||
noticeCalls
|
||||
}),
|
||||
3000
|
||||
)
|
||||
}
|
||||
reject(e.message)
|
||||
}
|
||||
}
|
||||
getConfirmations({ id, netId, type, noticeId })
|
||||
dispatch('finishJobWatcher', { id, netId, type })
|
||||
})
|
||||
},
|
||||
async handleResponse(
|
||||
{ state, rootGetters, commit, dispatch, getters, rootState },
|
||||
{ response, id, job, type, netId, retryAttempt, resolve, getConfirmations, noticeId, noticeCalls }
|
||||
) {
|
||||
const { amount, currency } = job
|
||||
const { txHash, confirmations, status, failedReason } = await response.json()
|
||||
console.log('txHash, confirmations, status, failedReason', txHash, confirmations, status, failedReason)
|
||||
commit('UPDATE_JOB', { id, netId, type, txHash, confirmations, status, failedReason })
|
||||
|
||||
if (status === 'FAILED') {
|
||||
dispatch('stopFinishJobWatcher', { id })
|
||||
commit('DELETE_JOB', { id, netId, type })
|
||||
retryAttempt = 6
|
||||
console.error('runJobWatcher.handleResponse', failedReason)
|
||||
|
||||
throw new Error(this.app.i18n.t('relayerError'))
|
||||
}
|
||||
|
||||
if (txHash && noticeCalls === 0 && (Number(confirmations) > 0 || status === 'CONFIRMED')) {
|
||||
noticeCalls++
|
||||
|
||||
dispatch(
|
||||
'notice/updateNotice',
|
||||
{
|
||||
id: noticeId,
|
||||
notice: {
|
||||
title: {
|
||||
path: 'withdrawnValue',
|
||||
amount,
|
||||
currency
|
||||
},
|
||||
type: 'success',
|
||||
txHash
|
||||
},
|
||||
interval: 10000
|
||||
},
|
||||
{ root: true }
|
||||
)
|
||||
}
|
||||
|
||||
if (status === 'CONFIRMED') {
|
||||
console.log(`Job ${id} has enough confirmations`)
|
||||
resolve(txHash)
|
||||
} else {
|
||||
setTimeout(() => getConfirmations({ id, netId, type, noticeId, retryAttempt, noticeCalls }), 3000)
|
||||
}
|
||||
},
|
||||
finishJobWatcher({ state, rootGetters, commit, dispatch, getters, rootState }, { id, netId, type }) {
|
||||
const timerId = setTimeout(() => {
|
||||
const { txHash, confirmations } = state.jobs[`netId${netId}`][type][id]
|
||||
commit('UPDATE_JOB', {
|
||||
id,
|
||||
netId,
|
||||
type,
|
||||
txHash,
|
||||
confirmations,
|
||||
status: 'FAILED',
|
||||
failedReason: this.app.i18n.t('relayerIsNotResponding')
|
||||
})
|
||||
commit('DELETE_JOB_WATCHER', { id })
|
||||
}, 15 * 60 * 1000)
|
||||
commit('ADD_JOB_WATCHER', { id, timerId })
|
||||
},
|
||||
stopFinishJobWatcher({ state, rootGetters, commit, dispatch, getters, rootState }, { id }) {
|
||||
console.log(`Stop finishJobWatcher ${id}`)
|
||||
const { timerId } = state.jobWatchers[id]
|
||||
clearTimeout(timerId)
|
||||
commit('DELETE_JOB_WATCHER', { id })
|
||||
},
|
||||
runAllJobs({ state, commit, dispatch, rootState }) {
|
||||
const netId = rootState.metamask.netId
|
||||
const jobs = state.jobs[`netId${netId}`]
|
||||
|
||||
for (const type in jobs) {
|
||||
for (const [id, { status }] of Object.entries(jobs[type])) {
|
||||
const job = { id, netId, type }
|
||||
if (status === 'FAILED') {
|
||||
commit('DELETE_JOB', job)
|
||||
} else {
|
||||
dispatch('runJobWatcherWithNotifications', job)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue