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

GoodDollar / GoodServer / 18870531243

03 Sep 2025 07:07AM UTC coverage: 49.176% (-0.4%) from 49.555%
18870531243

push

github

web-flow
fix: bump protocol to latest (#504)

617 of 1530 branches covered (40.33%)

Branch coverage included in aggregate %.

1889 of 3566 relevant lines covered (52.97%)

7.29 hits per line

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

67.27
/src/server/utils/eth.js
1
import Accounts from 'web3-eth-accounts'
2
import * as ethers from 'ethers'
3
import { toChecksumAddress } from 'web3-utils'
4
import { verifyMessage } from '@ambire/signature-validator'
5
import { messageContains } from './exception'
6
import { mustache } from '../utils/string'
7
import getNetworks from '../networks'
8

9
export const FV_IDENTIFIER_MSG2 =
11✔
10
  mustache(`Sign this message to request verifying your account {account} and to create your own secret unique identifier for your anonymized record.
11
You can use this identifier in the future to delete this anonymized record.
12
WARNING: do not sign this message unless you trust the website/application requesting this signature.`)
13

11✔
14
const accounts = new Accounts()
15

11✔
16
const is6492Sig = signature => {
18✔
17
  return signature.endsWith('6492649264926492649264926492649264926492649264926492649264926492')
18
}
19

11✔
20
export const extractSignature = signature => {
18✔
21
  if (is6492Sig(signature)) {
1✔
22
    const [, , erc1271Signature] = ethers.utils.defaultAbiCoder.decode(['address', 'bytes', 'bytes'], signature)
1✔
23
    return erc1271Signature
24
  }
17✔
25
  return signature
26
}
27

11!
28
export const recoverPublickey = (signature, msg, nonce = '') => {
7✔
29
  const publicKey = accounts.recover(String(msg) + String(nonce), signature).toLowerCase()
30

7✔
31
  return publicKey
32
}
33

11✔
34
export const verifySignature = async (message, signature) => {
×
35
  try {
36
    // recoverPublickey() also could throw so we're wrapping its call to try block
×
37
    const recovered = recoverPublickey(signature, message, '')
38

×
39
    if (recovered.substr(2) !== message.toLowerCase()) {
×
40
      throw new Error("Public key doesn't matches")
41
    }
42

×
43
    return recovered
44
  } catch (exception) {
×
45
    exception.message = `SigUtil unable to recover the message signer`
×
46
    throw exception
47
  }
48
}
49

11✔
50
export const verifyIdentifier = async (fvsig, gdAddress, chainId = 42220) => {
51
  const networks = getNetworks()
16✔
52

11✔
53
  // check v2, v2 identifier is expected to be the whole signature
54
  if (fvsig.length < 42) {
55
    return
5✔
56
  }
5✔
57

5✔
58
  // const fuseProvider = new ethers.providers.JsonRpcProvider('https://rpc.fuse.io')
59
  // const celoProvider = new ethers.providers.JsonRpcProvider('https://forno.celo.org')
5✔
60
  // const xdcProvider = new ethers.providers.JsonRpcProvider('https://rpc.ankr.com/')
5!
61

62
  const rpc = networks[chainId]?.httpWeb3Provider?.split(',')[0]
5✔
63
  const provider = rpc ? new ethers.providers.JsonRpcProvider(rpc) : null
5✔
64
  if (!provider) {
65
    throw new Error(`verifyIdentifier: no RPC for chainId ${chainId} for FV identifier verification`)
×
66
  }
×
67

68
  try {
×
69
    const verifyResult = await verifyMessage({
×
70
      provider,
71
      signer: toChecksumAddress(gdAddress),
×
72
      signature: fvsig,
73
      message: FV_IDENTIFIER_MSG2({ account: toChecksumAddress(gdAddress) })
74
    })
5✔
75
    if (!verifyResult) {
76
      // returns 0 if equals
77
      const error = new Error('FV identifier signature verification failed')
78
      error.rpc = rpc
79
      error.chainId = chainId
80
      throw error
81
    }
5✔
82
    return verifyResult
83
  } catch (e) {
1✔
84
    e.rpc = rpc
85
    e.chainId = chainId
4✔
86
    throw e
87
  }
88
}
89

90
/**
91
 * Return boolean
92
 * @param e Error
93
 * @returns boolean
11✔
94
 */
95
export const isNonceError = e => messageContains(e, 'nonce')
11✔
96

97
export const isFundsError = e => messageContains(e, 'funds')
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