This repository has been archived by the owner on Nov 10, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 365
/
Copy pathsafeVersion.ts
89 lines (75 loc) · 3.05 KB
/
safeVersion.ts
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
import semverLessThan from 'semver/functions/lt'
import semverSatisfies from 'semver/functions/satisfies'
import semverValid from 'semver/functions/valid'
import { FEATURES } from '@gnosis.pm/safe-react-gateway-sdk'
import { GnosisSafe } from 'src/types/contracts/gnosis_safe.d'
import { getSafeMasterContract } from 'src/logic/contracts/safeContracts'
import { LATEST_SAFE_VERSION } from 'src/utils/constants'
import { Errors, logError } from 'src/logic/exceptions/CodedException'
import { getChainInfo } from 'src/config'
const FEATURES_BY_VERSION: Record<string, string> = {
[FEATURES.ERC1155]: '>=1.1.1',
[FEATURES.SAFE_TX_GAS_OPTIONAL]: '>=1.3.0',
}
export const safeNeedsUpdate = (currentVersion?: string, latestVersion?: string): boolean => {
if (!currentVersion || !latestVersion) {
return false
}
const current = semverValid(currentVersion) as string
const latest = semverValid(latestVersion) as string
return latest ? semverLessThan(current, latest) : false
}
export const getCurrentSafeVersion = (gnosisSafeInstance: GnosisSafe): Promise<string> =>
gnosisSafeInstance.methods.VERSION().call()
const isEnabledByVersion = (feature: FEATURES, version: string): boolean => {
if (!(feature in FEATURES_BY_VERSION)) return true
return semverSatisfies(version, FEATURES_BY_VERSION[feature])
}
/**
* Get a combined list of features enabled per chain and per version
*/
export const enabledFeatures = (version?: string): FEATURES[] => {
const chainFeatures = getChainInfo().features
if (!version) return chainFeatures
return chainFeatures.filter((feat) => isEnabledByVersion(feat, version))
}
export const hasFeature = (name: FEATURES, version?: string): boolean => {
return enabledFeatures(version).includes(name)
}
interface SafeVersionInfo {
current: string
latest: string
needUpdate: boolean
}
export const checkIfSafeNeedsUpdate = async (
safeVersion: string,
lastSafeVersion: string,
): Promise<SafeVersionInfo> => {
if (!safeVersion || !lastSafeVersion) {
throw new Error('checkIfSafeNeedsUpdate: No Safe Instance or version provided')
}
const current = semverValid(safeVersion) as string
const latest = semverValid(lastSafeVersion) as string
const needUpdate = safeNeedsUpdate(safeVersion, lastSafeVersion)
return { current, latest, needUpdate }
}
export const getCurrentMasterContractLastVersion = async (): Promise<string> => {
let safeMasterVersion: string
try {
const safeMaster = await getSafeMasterContract()
safeMasterVersion = await safeMaster.methods.VERSION().call()
} catch (err) {
// Default in case that it's not possible to obtain the version from the contract, returns a hardcoded value or an
// env variable
safeMasterVersion = LATEST_SAFE_VERSION
}
return safeMasterVersion
}
export const getSafeVersionInfo = async (safeVersion: string): Promise<SafeVersionInfo | undefined> => {
try {
const lastSafeVersion = await getCurrentMasterContractLastVersion()
return checkIfSafeNeedsUpdate(safeVersion, lastSafeVersion)
} catch (err) {
logError(Errors._606, err.message)
}
}