aboutsummaryrefslogtreecommitdiffstats
path: root/ui/app/helpers/with-token-tracker.js
blob: 8608b15f47ddc83df1e07f97ac177e25ad80165e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import TokenTracker from 'eth-token-tracker'

const withTokenTracker = WrappedComponent => {
  return class TokenTrackerWrappedComponent extends Component {
    static propTypes = {
      userAddress: PropTypes.string.isRequired,
      token: PropTypes.object.isRequired,
    }

    constructor (props) {
      super(props)

      this.state = {
        string: '',
        symbol: '',
        error: null,
      }

      this.tracker = null
      this.updateBalance = this.updateBalance.bind(this)
      this.setError = this.setError.bind(this)
    }

    componentDidMount () {
      this.createFreshTokenTracker()
    }

    componentDidUpdate (prevProps) {
      const { userAddress: newAddress, token: { address: newTokenAddress } } = this.props
      const { userAddress: oldAddress, token: { address: oldTokenAddress } } = prevProps

      if ((oldAddress === newAddress) && (oldTokenAddress === newTokenAddress)) {
        return
      }

      if ((!oldAddress || !newAddress) && (!oldTokenAddress || !newTokenAddress)) {
        return
      }

      this.createFreshTokenTracker()
    }

    componentWillUnmount () {
      this.removeListeners()
    }

    createFreshTokenTracker () {
      this.removeListeners()

      if (!global.ethereumProvider) {
        return
      }

      const { userAddress, token } = this.props

      this.tracker = new TokenTracker({
        userAddress,
        provider: global.ethereumProvider,
        tokens: [token],
        pollingInterval: 8000,
      })

      this.tracker.on('update', this.updateBalance)
      this.tracker.on('error', this.setError)

      this.tracker.updateBalances()
        .then(() => this.updateBalance(this.tracker.serialize()))
        .catch(error => this.setState({ error: error.message }))
    }

    setError (error) {
      this.setState({ error })
    }

    updateBalance (tokens = []) {
      if (!this.tracker.running) {
        return
      }
      const [{ string, symbol }] = tokens
      this.setState({ string, symbol, error: null })
    }

    removeListeners () {
      if (this.tracker) {
        this.tracker.stop()
        this.tracker.removeListener('update', this.updateBalance)
        this.tracker.removeListener('error', this.setError)
      }
    }

    render () {
      const { string, symbol, error } = this.state

      return (
        <WrappedComponent
          { ...this.props }
          string={string}
          symbol={symbol}
          error={error}
        />
      )
    }
  }
}

module.exports = withTokenTracker