• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

GoodDollar / GoodServer / 12903998428

14 Jan 2025 12:39PM UTC coverage: 49.574% (+0.2%) from 49.344%
12903998428

push

github

sirpy
fix: remove unused

579 of 1453 branches covered (39.85%)

Branch coverage included in aggregate %.

1863 of 3473 relevant lines covered (53.64%)

8.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

24.71
/src/server/blockchain/MultiWallet.js
1
// @flow
2
import { assign, every, forOwn, isEmpty, isError, map, some } from 'lodash'
3
import AdminWallet from './AdminWallet'
4
import { CeloAdminWallet } from './CeloAdminWallet'
5
import { BaseAdminWallet } from './BaseAdminWallet'
6
import { XdcAdminWallet } from './XdcAdminWallet'
7

8
import conf from '../server.config'
9
import logger from '../../imports/logger'
10
import { DefenderRelayer } from './DefenderRelayer'
4✔
11
const multiLogger = logger.child({ from: 'MultiWallet' })
12

13
class MultiWallet {
4✔
14
  mainWallet = null
4✔
15
  otherWallets = []
4✔
16
  wallets = []
4✔
17
  walletsMap = {}
4✔
18
  defaultChainId = null
4✔
19
  signer: DefenderRelayer = null
20

21
  get ready() {
3✔
22
    return Promise.all(map(this.wallets, 'ready')).then(() => this.mainWallet.addresses)
23
  }
24

25
  constructor(walletsMap) {
26
    let mainWallet
27
    let defaultChainId
4✔
28
    this.signer = DefenderRelayer.getInstance()
29

4✔
30
    forOwn(walletsMap, (wallet, chainId) => {
4✔
31
      this.wallets.push(wallet)
32

4!
33
      if (mainWallet) {
×
34
        this.otherWallets.push(wallet)
35
      } else {
4✔
36
        mainWallet = wallet
4✔
37
        defaultChainId = chainId
38
      }
39
    })
40

4✔
41
    multiLogger.debug('MultiWallet constructor:', {
42
      wallets: Object.keys(walletsMap),
43
      mainWallet: mainWallet.networkId,
×
44
      otherWallets: this.otherWallets.map(_ => _.networkId)
45
    })
46

4✔
47
    assign(this, { walletsMap, mainWallet, defaultChainId })
48
  }
49

50
  signMessage(message: string) {
×
51
    return this.signer.signMessage(message)
52
  }
53

×
54
  async banInFaucet(account, chainId = 'all', log = multiLogger) {
×
55
    const runTx = wallet => wallet.banInFaucet(account, log)
56

×
57
    log.debug('MultiWallet: banInFaucet request:', { account, chainId })
×
58
    if (chainId === 'all') {
59
      // ban on chains that have ubi
×
60
      const results = await Promise.all(
×
61
        this.wallets.filter(_ => Number(_.UBIContract?._address) > 0).map(wallet => runTx(wallet).catch(e => e))
62
      )
×
63
      const error = results.find(isError)
64

×
65
      if (error) {
×
66
        throw error
67
      }
68

×
69
      return results
70
    }
71

×
72
    const { walletsMap } = this
73

×
74
    if (chainId in walletsMap) return runTx(walletsMap[chainId])
75

×
76
    throw new Error(`unsupported chain ${chainId}`)
77
  }
78

×
79
  async topWallet(account, chainId = null, log = multiLogger) {
×
80
    const runTx = wallet => wallet.topWallet(account, log)
81

82
    log.debug('MultiWallet: topWallet request:', { account, chainId })
83
    if (chainId === 'all') {
×
84
      // topwallet on chains that have ubi
85
      const results = await Promise.all(
86
        this.wallets.filter(_ => Number(_.UBIContract?._address) > 0).map(wallet => runTx(wallet).catch(e => e))
87
      )
×
88
      const error = results.find(isError)
×
89

90
      if (error) {
91
        throw error
92
      }
93

×
94
      return results
95
    }
96

97
    const { walletsMap } = this
×
98

99
    if (chainId in walletsMap) return runTx(walletsMap[chainId])
100

×
101
    throw new Error(`unsupported chain ${chainId}`)
×
102
  }
×
103

104
  async whitelistUser(account, did, chainId = null, log = multiLogger) {
×
105
    return Promise.all(this.wallets.map(wallet => wallet.whitelistUser(account, did, chainId, 0, log)))
106
  }
×
107

×
108
  async removeWhitelisted(account) {
109
    return Promise.all(this.wallets.map(wallet => wallet.removeWhitelisted(account)))
110
  }
×
111

112
  async verifiedStatus(account) {
×
113
    return Promise.all(
×
114
      this.wallets.map(wallet => wallet.isVerified(account).then(status => ({ chainId: wallet.networkId, status })))
×
115
    )
116
  }
×
117

118
  async isVerified(account) {
×
119
    return this.mainWallet.isVerified(account)
120
  }
×
121

122
  async lastAuthenticated(account) {
×
123
    return this.mainWallet.getLastAuthenticated(account)
×
124
  }
×
125

126
  async syncWhitelist(account, log = multiLogger) {
127
    try {
×
128
      const isVerified = await Promise.all(this.wallets.map(wallet => wallet.isVerified(account)))
129

130
      log.debug('syncwhitelist isVerified:', { account, isVerified })
131

×
132
      if (isEmpty(isVerified) || every(isVerified) || !some(isVerified)) {
133
        return false
×
134
      }
×
135

136
      const mainWallet = this.wallets[isVerified.findIndex(_ => _)]
137

138
      const [did, lastAuthenticated] = await Promise.all([
139
        mainWallet.getDID(account).catch(() => account),
×
140
        mainWallet.getLastAuthenticated(account).catch(() => 0)
141
      ])
142
      const chainId = mainWallet.networkId
×
143

1✔
144
      log.debug('syncwhitelist did:', { account, did, lastAuthenticated, chainId })
145

146
      await Promise.all(
147
        isVerified.map(async (status, index) => {
4✔
148
          log.debug('syncwhitelist whitelisting on wallet:', { status, index, account })
4!
149
          if (status) {
×
150
            return
×
151
          }
152

153
          await this.wallets[index].whitelistUser(account, did, chainId, lastAuthenticated, log)
154
        })
155
      )
156

157
      return true
158
    } catch (e) {
159
      log.error('syncwhitelist failed:', e.message, e, { account })
160
      throw e
161
    }
162
  }
163

164
  async getAuthenticationPeriod() {
165
    return this.mainWallet.getAuthenticationPeriod()
166
  }
167

168
  async registerRedtent(account: string, countryCode: string, log = multiLogger) {
169
    return Promise.all(this.wallets.map(wallet => wallet.registerRedtent(account, countryCode, log)))
170
  }
171
}
172

173
let otherWallets = {}
174
if (conf.env !== 'test') {
175
  const celoWallet = new CeloAdminWallet()
176
  otherWallets = {
177
    42220: celoWallet,
178
    8453: new BaseAdminWallet({}, celoWallet),
179
    50: new XdcAdminWallet({})
180
  }
181
}
182

183
export default new MultiWallet({
184
  122: AdminWallet, // "main" wallet goes first
185
  ...otherWallets
186
})
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc