(Fix) Modules not shown in Advanced Settings (#1516)
This commit is contained in:
parent
4ce8917f34
commit
aa181fb9a1
|
@ -1,8 +1,9 @@
|
|||
import memoize from 'lodash.memoize'
|
||||
|
||||
import networks from 'src/config/networks'
|
||||
import { EnvironmentSettings, ETHEREUM_NETWORK, NetworkSettings, SafeFeatures, Wallets, GasPriceOracle } from 'src/config/networks/network.d'
|
||||
import { APP_ENV, ETHERSCAN_API_KEY, GOOGLE_ANALYTICS_ID, INFURA_TOKEN, NETWORK, NODE_ENV } from 'src/utils/constants'
|
||||
import { ensureOnce } from 'src/utils/singleton'
|
||||
import memoize from 'lodash.memoize'
|
||||
|
||||
export const getNetworkId = (): ETHEREUM_NETWORK => ETHEREUM_NETWORK[NETWORK]
|
||||
|
||||
|
@ -57,11 +58,11 @@ const configuration = (): NetworkSpecificConfiguration => {
|
|||
|
||||
const getConfig: () => NetworkSpecificConfiguration = ensureOnce(configuration)
|
||||
|
||||
export const getTxServiceUrl = (): string => getConfig()?.txServiceUrl
|
||||
export const getTxServiceUrl = (): string => getConfig().txServiceUrl
|
||||
|
||||
export const getRelayUrl = (): string | undefined => getConfig()?.relayApiUrl
|
||||
export const getRelayUrl = (): string | undefined => getConfig().relayApiUrl
|
||||
|
||||
export const getGnosisSafeAppsUrl = (): string => getConfig()?.safeAppsUrl
|
||||
export const getGnosisSafeAppsUrl = (): string => getConfig().safeAppsUrl
|
||||
|
||||
export const getGasPrice = (): number | undefined => getConfig()?.gasPrice
|
||||
|
||||
|
@ -71,31 +72,27 @@ export const getRpcServiceUrl = (): string => {
|
|||
const usesInfuraRPC = [ETHEREUM_NETWORK.MAINNET, ETHEREUM_NETWORK.RINKEBY].includes(getNetworkId())
|
||||
|
||||
if (usesInfuraRPC) {
|
||||
return `${getConfig()?.rpcServiceUrl}/${INFURA_TOKEN}`
|
||||
return `${getConfig().rpcServiceUrl}/${INFURA_TOKEN}`
|
||||
}
|
||||
|
||||
return getConfig()?.rpcServiceUrl
|
||||
return getConfig().rpcServiceUrl
|
||||
}
|
||||
|
||||
export const getSafeServiceBaseUrl = (safeAddress: string) => `${getTxServiceUrl()}/safes/${safeAddress}`
|
||||
|
||||
export const getTokensServiceBaseUrl = () => `${getTxServiceUrl()}/tokens`
|
||||
|
||||
export const getNetworkExplorerInfo = (): { name: string; url: string; apiUrl: string } => ({
|
||||
name: getConfig()?.networkExplorerName,
|
||||
url: getConfig()?.networkExplorerUrl,
|
||||
apiUrl: getConfig()?.networkExplorerApiUrl,
|
||||
name: getConfig().networkExplorerName,
|
||||
url: getConfig().networkExplorerUrl,
|
||||
apiUrl: getConfig().networkExplorerApiUrl,
|
||||
})
|
||||
|
||||
export const getNetworkConfigDisabledFeatures = (): SafeFeatures => getConfig()?.disabledFeatures || []
|
||||
export const getNetworkConfigDisabledFeatures = (): SafeFeatures => getConfig().disabledFeatures || []
|
||||
|
||||
export const getNetworkConfigDisabledWallets = (): Wallets => getConfig()?.disabledWallets || []
|
||||
|
||||
export const getNetworkInfo = (): NetworkSettings => getConfig()?.network
|
||||
|
||||
export const getTxServiceUriFrom = (safeAddress: string) => `/safes/${safeAddress}/transactions/`
|
||||
|
||||
export const getIncomingTxServiceUriTo = (safeAddress: string) => `/safes/${safeAddress}/incoming-transfers/`
|
||||
|
||||
export const getAllTransactionsUriFrom = (safeAddress: string) => `/safes/${safeAddress}/all-transactions/`
|
||||
|
||||
export const getSafeCreationTxUri = (safeAddress: string) => `/safes/${safeAddress}/creation/`
|
||||
export const getNetworkInfo = (): NetworkSettings => getConfig().network
|
||||
|
||||
export const getGoogleAnalyticsTrackingID = (): string => GOOGLE_ANALYTICS_ID
|
||||
|
||||
|
@ -163,11 +160,11 @@ export const getExplorerInfo = (hash: string): BlockScanInfo => {
|
|||
|
||||
switch (networkInfo.id) {
|
||||
default: {
|
||||
const type = hash.length > 42 ? 'tx' : 'address'
|
||||
const type = hash.length > 42 ? 'tx' : 'address'
|
||||
return () => ({
|
||||
url: `${url}/${type}/${hash}`,
|
||||
alt: name || '',
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { aNewStore } from 'src/store'
|
||||
import { fetchTokenCurrenciesBalances } from 'src/logic/currencyValues/api/fetchTokenCurrenciesBalances'
|
||||
import axios from 'axios'
|
||||
import { getTxServiceUrl } from 'src/config'
|
||||
|
||||
import { getSafeServiceBaseUrl } from 'src/config'
|
||||
import { fetchTokenCurrenciesBalances } from 'src/logic/currencyValues/api/fetchTokenCurrenciesBalances'
|
||||
import { aNewStore } from 'src/store'
|
||||
|
||||
jest.mock('axios')
|
||||
describe('fetchTokenCurrenciesBalances', () => {
|
||||
|
@ -40,7 +41,7 @@ describe('fetchTokenCurrenciesBalances', () => {
|
|||
fiatCode: 'USD',
|
||||
},
|
||||
]
|
||||
const apiUrl = getTxServiceUrl()
|
||||
const apiUrl = getSafeServiceBaseUrl(safeAddress)
|
||||
|
||||
// @ts-ignore
|
||||
axios.get.mockImplementationOnce(() => Promise.resolve(expectedResult))
|
||||
|
@ -51,6 +52,6 @@ describe('fetchTokenCurrenciesBalances', () => {
|
|||
// then
|
||||
expect(result).toStrictEqual(expectedResult)
|
||||
expect(axios.get).toHaveBeenCalled()
|
||||
expect(axios.get).toBeCalledWith(`${apiUrl}/safes/${safeAddress}/balances/usd/?exclude_spam=${excludeSpamTokens}`)
|
||||
expect(axios.get).toBeCalledWith(`${apiUrl}/balances/usd/?exclude_spam=${excludeSpamTokens}`)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import axios, { AxiosResponse } from 'axios'
|
||||
|
||||
import { getTxServiceUrl } from 'src/config'
|
||||
import { getSafeServiceBaseUrl } from 'src/config'
|
||||
import { TokenProps } from 'src/logic/tokens/store/model/token'
|
||||
|
||||
export type BalanceEndpoint = {
|
||||
|
@ -16,8 +16,7 @@ export const fetchTokenCurrenciesBalances = (
|
|||
safeAddress: string,
|
||||
excludeSpamTokens = true,
|
||||
): Promise<AxiosResponse<BalanceEndpoint[]>> => {
|
||||
const apiUrl = getTxServiceUrl()
|
||||
const url = `${apiUrl}/safes/${safeAddress}/balances/usd/?exclude_spam=${excludeSpamTokens}`
|
||||
const url = `${getSafeServiceBaseUrl(safeAddress)}/balances/usd/?exclude_spam=${excludeSpamTokens}`
|
||||
|
||||
return axios.get(url)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import axios, { AxiosResponse } from 'axios'
|
||||
|
||||
import { getAllTransactionsUriFrom, getTxServiceUrl } from 'src/config'
|
||||
import { getSafeServiceBaseUrl } from 'src/config'
|
||||
import { checksumAddress } from 'src/utils/checksumAddress'
|
||||
import { Transaction } from '../../models/types/transactions.d'
|
||||
import { Transaction } from 'src/logic/safe/store/models/types/transactions.d'
|
||||
|
||||
export type ServiceUriParams = {
|
||||
safeAddress: string
|
||||
|
@ -21,11 +21,8 @@ type TransactionDTO = {
|
|||
}
|
||||
|
||||
const getAllTransactionsUri = (safeAddress: string): string => {
|
||||
const host = getTxServiceUrl()
|
||||
const address = checksumAddress(safeAddress)
|
||||
const base = getAllTransactionsUriFrom(address)
|
||||
|
||||
return `${host}/${base}`
|
||||
return `${getSafeServiceBaseUrl(address)}/all-transactions/`
|
||||
}
|
||||
|
||||
const fetchAllTransactions = async (
|
||||
|
|
|
@ -13,10 +13,11 @@ import removeSafeOwner from 'src/logic/safe/store/actions/removeSafeOwner'
|
|||
import updateSafe from 'src/logic/safe/store/actions/updateSafe'
|
||||
import { makeOwner } from 'src/logic/safe/store/models/owner'
|
||||
import { checksumAddress } from 'src/utils/checksumAddress'
|
||||
import { ModulePair, SafeOwner, SafeRecordProps } from 'src/logic/safe/store/models/safe'
|
||||
import { SENTINEL_ADDRESS } from 'src/logic/contracts/safeContracts'
|
||||
import { SafeOwner, SafeRecordProps } from 'src/logic/safe/store/models/safe'
|
||||
import { AppReduxState } from 'src/store'
|
||||
import { latestMasterContractVersionSelector } from '../selectors'
|
||||
import { latestMasterContractVersionSelector } from 'src/logic/safe/store/selectors'
|
||||
import { getSafeInfo } from 'src/logic/safe/utils/safeInformation'
|
||||
import { getModules } from 'src/logic/safe/utils/modules'
|
||||
|
||||
const buildOwnersFrom = (safeOwners: string[], localSafe?: SafeRecordProps): List<SafeOwner> => {
|
||||
const ownersList = safeOwners.map((ownerAddress) => {
|
||||
|
@ -40,16 +41,6 @@ const buildOwnersFrom = (safeOwners: string[], localSafe?: SafeRecordProps): Lis
|
|||
return List(ownersList)
|
||||
}
|
||||
|
||||
const buildModulesLinkedList = (modules?: string[], nextModule?: string): Array<ModulePair> | null => {
|
||||
if (modules?.length && nextModule) {
|
||||
return modules.map((moduleAddress, index, modules) => {
|
||||
const prevModule = modules[index + 1]
|
||||
return [moduleAddress, prevModule !== undefined ? prevModule : nextModule]
|
||||
})
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export const buildSafe = async (
|
||||
safeAdd: string,
|
||||
safeName: string,
|
||||
|
@ -58,12 +49,18 @@ export const buildSafe = async (
|
|||
const safeAddress = checksumAddress(safeAdd)
|
||||
|
||||
const safeParams = ['getThreshold', 'nonce', 'VERSION', 'getOwners']
|
||||
const [[, thresholdStr, nonceStr, currentVersion, remoteOwners = []], localSafe, ethBalance] = await Promise.all([
|
||||
const [
|
||||
[, thresholdStr, nonceStr, currentVersion, remoteOwners = []],
|
||||
safeInfo,
|
||||
localSafe,
|
||||
ethBalance,
|
||||
] = await Promise.all([
|
||||
generateBatchRequests<[undefined, string | undefined, string | undefined, string | undefined, string[]]>({
|
||||
abi: GnosisSafeSol.abi as AbiItem[],
|
||||
address: safeAddress,
|
||||
methods: safeParams,
|
||||
}),
|
||||
getSafeInfo(safeAddress),
|
||||
getLocalSafe(safeAddress),
|
||||
getBalanceInEtherOf(safeAddress),
|
||||
])
|
||||
|
@ -73,6 +70,7 @@ export const buildSafe = async (
|
|||
const owners = buildOwnersFrom(remoteOwners, localSafe)
|
||||
const needsUpdate = safeNeedsUpdate(currentVersion, latestMasterContractVersion)
|
||||
const featuresEnabled = enabledFeatures(currentVersion)
|
||||
const modules = await getModules(safeInfo)
|
||||
|
||||
return {
|
||||
address: safeAddress,
|
||||
|
@ -90,51 +88,34 @@ export const buildSafe = async (
|
|||
activeTokens: Set(),
|
||||
blacklistedAssets: Set(),
|
||||
blacklistedTokens: Set(),
|
||||
modules: null,
|
||||
modules,
|
||||
}
|
||||
}
|
||||
|
||||
export const checkAndUpdateSafe = (safeAdd: string) => async (dispatch: Dispatch): Promise<void> => {
|
||||
const safeAddress = checksumAddress(safeAdd)
|
||||
// Check if the owner's safe did change and update them
|
||||
const safeParams = [
|
||||
'getThreshold',
|
||||
'nonce',
|
||||
'getOwners',
|
||||
// TODO: 100 is an arbitrary large number, to avoid the need for pagination. But pagination must be properly handled
|
||||
{ method: 'getModulesPaginated', args: [SENTINEL_ADDRESS, 100] },
|
||||
]
|
||||
const [[, remoteThreshold, remoteNonce, remoteOwners, modules], localSafe] = await Promise.all([
|
||||
generateBatchRequests<
|
||||
[
|
||||
undefined,
|
||||
string | undefined,
|
||||
string | undefined,
|
||||
string[],
|
||||
(
|
||||
| {
|
||||
array: string[]
|
||||
next: string
|
||||
}
|
||||
| undefined
|
||||
),
|
||||
]
|
||||
>({
|
||||
const safeParams = ['getThreshold', 'nonce', 'getOwners']
|
||||
const [[, remoteThreshold, remoteNonce, remoteOwners = []], safeInfo, localSafe] = await Promise.all([
|
||||
generateBatchRequests<[undefined, string | undefined, string | undefined, string[]]>({
|
||||
abi: GnosisSafeSol.abi as AbiItem[],
|
||||
address: safeAddress,
|
||||
methods: safeParams,
|
||||
}),
|
||||
getSafeInfo(safeAddress),
|
||||
getLocalSafe(safeAddress),
|
||||
])
|
||||
|
||||
// Converts from [ { address, ownerName} ] to address array
|
||||
const localOwners = localSafe ? localSafe.owners.map((localOwner) => localOwner.address) : []
|
||||
|
||||
const modules = await getModules(safeInfo)
|
||||
|
||||
dispatch(
|
||||
updateSafe({
|
||||
address: safeAddress,
|
||||
name: localSafe?.name,
|
||||
modules: buildModulesLinkedList(modules?.array, modules?.next),
|
||||
modules,
|
||||
nonce: Number(remoteNonce),
|
||||
threshold: Number(remoteThreshold),
|
||||
featuresEnabled: localSafe?.currentVersion
|
||||
|
|
|
@ -14,7 +14,7 @@ export type SafeRecordProps = {
|
|||
threshold: number
|
||||
ethBalance: string
|
||||
owners: List<SafeOwner>
|
||||
modules: ModulePair[] | null
|
||||
modules?: ModulePair[] | null
|
||||
activeTokens: Set<string>
|
||||
activeAssets: Set<string>
|
||||
blacklistedTokens: Set<string>
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import { getIncomingTxServiceUriTo, getTxServiceUrl } from 'src/config'
|
||||
import { getSafeServiceBaseUrl } from 'src/config'
|
||||
import { checksumAddress } from 'src/utils/checksumAddress'
|
||||
|
||||
export const buildIncomingTxServiceUrl = (safeAddress: string): string => {
|
||||
const host = getTxServiceUrl()
|
||||
const address = checksumAddress(safeAddress)
|
||||
const base = getIncomingTxServiceUriTo(address)
|
||||
|
||||
return `${host}/${base}`
|
||||
return `${getSafeServiceBaseUrl(address)}/incoming-transfers/`
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import axios from 'axios'
|
||||
|
||||
import { GnosisSafe } from 'src/types/contracts/GnosisSafe.d'
|
||||
import { getTxServiceUrl, getTxServiceUriFrom } from 'src/config'
|
||||
import { getSafeServiceBaseUrl } from 'src/config'
|
||||
import { checksumAddress } from 'src/utils/checksumAddress'
|
||||
|
||||
const calculateBodyFrom = async (
|
||||
|
@ -45,10 +45,8 @@ const calculateBodyFrom = async (
|
|||
}
|
||||
|
||||
export const buildTxServiceUrl = (safeAddress: string): string => {
|
||||
const host = getTxServiceUrl()
|
||||
const address = checksumAddress(safeAddress)
|
||||
const base = getTxServiceUriFrom(address)
|
||||
return `${host}/${base}?has_confirmations=True`
|
||||
return `${getSafeServiceBaseUrl(address)}/transactions/?has_confirmations=True`
|
||||
}
|
||||
|
||||
const SUCCESS_STATUS = 201 // CREATED status
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import { getTxServiceUrl, getSafeCreationTxUri } from 'src/config'
|
||||
import { getSafeServiceBaseUrl } from 'src/config'
|
||||
import { checksumAddress } from 'src/utils/checksumAddress'
|
||||
|
||||
export const buildSafeCreationTxUrl = (safeAddress: string): string => {
|
||||
const host = getTxServiceUrl()
|
||||
const address = checksumAddress(safeAddress)
|
||||
const base = getSafeCreationTxUri(address)
|
||||
|
||||
return `${host}/${base}`
|
||||
return `${getSafeServiceBaseUrl(address)}/creation/`
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import { getSafeServiceBaseUrl } from 'src/config'
|
||||
import { checksumAddress } from 'src/utils/checksumAddress'
|
||||
|
||||
export const buildSafeInformationUrl = (safeAddress: string): string => {
|
||||
const address = checksumAddress(safeAddress)
|
||||
const url = getSafeServiceBaseUrl(address)
|
||||
return `${url}/`
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
import semverLessThan from 'semver/functions/lt'
|
||||
|
||||
import { getGnosisSafeInstanceAt, SENTINEL_ADDRESS } from 'src/logic/contracts/safeContracts'
|
||||
import { ModulePair } from 'src/logic/safe/store/models/safe'
|
||||
import { SafeInfo } from 'src/logic/safe/utils/safeInformation'
|
||||
|
||||
type ModulesPaginated = {
|
||||
array: string[]
|
||||
next: string
|
||||
}
|
||||
|
||||
const buildModulesLinkedList = (modules: string[], nextModule: string = SENTINEL_ADDRESS): Array<ModulePair> | null => {
|
||||
if (modules?.length) {
|
||||
return modules.map((moduleAddress, index, modules) => {
|
||||
const prevModule = modules[index + 1]
|
||||
return [moduleAddress, prevModule !== undefined ? prevModule : nextModule]
|
||||
})
|
||||
}
|
||||
|
||||
// no modules
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of Modules if there's any, in the form of [module, prevModule][]
|
||||
* so we have an easy track of the prevModule and the currentModule when calling `disableModule`
|
||||
*
|
||||
* There's a slight difference on how many modules `getModules` return, depending on the Safe's version we're in:
|
||||
* - for >= v1.1.1 it will return a list of up to 10 modules
|
||||
* - for previous version it will return a list of all the modules enabled
|
||||
*
|
||||
* As we're using the safe-transactions service, and it's querying `getModules`,
|
||||
* we'll fallback to `getModulesPaginated` RPC call when needed.
|
||||
*
|
||||
* @todo: Implement pagination for `getModulesPaginated`. We're passing an arbitrary large number to avoid pagination.
|
||||
*
|
||||
* @param {SafeInfo | undefined } safeInfo
|
||||
* @returns Array<ModulePair> | null | undefined
|
||||
*/
|
||||
export const getModules = async (safeInfo: SafeInfo | void): Promise<Array<ModulePair> | null | undefined> => {
|
||||
if (!safeInfo) {
|
||||
return
|
||||
}
|
||||
|
||||
if (semverLessThan(safeInfo.version, '1.1.1')) {
|
||||
// we can use the `safeInfo.modules`, as versions previous to 1.1.1 return the whole list of modules
|
||||
return buildModulesLinkedList(safeInfo.modules)
|
||||
} else {
|
||||
// newer versions `getModules` call returns up to 10 modules
|
||||
if (safeInfo.modules.length < 10) {
|
||||
// we're sure that we got all the modules
|
||||
return buildModulesLinkedList(safeInfo.modules)
|
||||
}
|
||||
|
||||
try {
|
||||
// lastly, if `safeInfo.modules` have 10 items,
|
||||
// we'll fallback to `getModulesPaginated` RPC call
|
||||
// as we're not sure if there are more than 10 modules enabled for the current Safe
|
||||
const safeInstance = getGnosisSafeInstanceAt(safeInfo.address)
|
||||
|
||||
// TODO: 100 is an arbitrary large number, to avoid the need for pagination. But pagination must be properly handled
|
||||
const modules: ModulesPaginated = await safeInstance.methods.getModulesPaginated(SENTINEL_ADDRESS, 100).call()
|
||||
|
||||
return buildModulesLinkedList(modules.array, modules.next)
|
||||
} catch (e) {
|
||||
console.error('Failed to retrieve Safe modules', e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const getDisableModuleTxData = (modulePair: ModulePair, safeAddress: string): string => {
|
||||
const [module, previousModule] = modulePair
|
||||
const safeInstance = getGnosisSafeInstanceAt(safeAddress)
|
||||
|
||||
return safeInstance.methods.disableModule(previousModule, module).encodeABI()
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
import axios, { AxiosError, AxiosResponse } from 'axios'
|
||||
import { buildSafeInformationUrl } from './buildSafeInformationUrl'
|
||||
|
||||
export type SafeInfo = {
|
||||
address: string
|
||||
nonce: number
|
||||
threshold: number
|
||||
owners: string[]
|
||||
masterCopy: string
|
||||
modules: string[]
|
||||
fallbackHandler: string
|
||||
version: string
|
||||
}
|
||||
|
||||
export type SafeInfoError = {
|
||||
code: number
|
||||
message: string
|
||||
arguments: string[]
|
||||
}
|
||||
|
||||
export const getSafeInfo = (safeAddress: string): Promise<void | SafeInfo> => {
|
||||
const safeInfoUrl = buildSafeInformationUrl(safeAddress)
|
||||
return axios
|
||||
.get<SafeInfo, AxiosResponse<SafeInfo>>(safeInfoUrl)
|
||||
.then((response) => response.data)
|
||||
.catch((error: AxiosError<SafeInfoError>) => {
|
||||
console.error(
|
||||
'Failed to retrieve safe Information',
|
||||
error.response?.statusText ?? error.response?.data.message ?? error,
|
||||
)
|
||||
})
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import axios, { AxiosResponse } from 'axios'
|
||||
|
||||
import { getTxServiceUrl } from 'src/config'
|
||||
import { getTokensServiceBaseUrl } from 'src/config'
|
||||
|
||||
export type TokenResult = {
|
||||
address: string
|
||||
|
@ -12,11 +12,9 @@ export type TokenResult = {
|
|||
}
|
||||
|
||||
export const fetchErc20AndErc721AssetsList = async (): Promise<AxiosResponse<{ results: TokenResult[] }>> => {
|
||||
const apiUrl = getTxServiceUrl()
|
||||
const url = getTokensServiceBaseUrl()
|
||||
|
||||
const url = `${apiUrl}/tokens/`
|
||||
|
||||
return axios.get<{ results: TokenResult[] }>(url, {
|
||||
return axios.get<{ results: TokenResult[] }>(`${url}/`, {
|
||||
params: {
|
||||
limit: 3000,
|
||||
},
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import axios, { AxiosResponse } from 'axios'
|
||||
|
||||
import { getTxServiceUrl } from 'src/config'
|
||||
import { getSafeServiceBaseUrl } from 'src/config'
|
||||
import { checksumAddress } from 'src/utils/checksumAddress'
|
||||
|
||||
export type CollectibleResult = {
|
||||
address: string
|
||||
|
@ -16,9 +17,8 @@ export type CollectibleResult = {
|
|||
}
|
||||
|
||||
export const fetchSafeCollectibles = async (safeAddress: string): Promise<AxiosResponse<CollectibleResult[]>> => {
|
||||
const apiUrl = getTxServiceUrl()
|
||||
|
||||
const url = `${apiUrl}/safes/${safeAddress}/collectibles/`
|
||||
const address = checksumAddress(safeAddress)
|
||||
const url = `${getSafeServiceBaseUrl(address)}/collectibles/`
|
||||
|
||||
return axios.get(url)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import axios, { AxiosResponse } from 'axios'
|
||||
|
||||
import { getTxServiceUrl } from 'src/config'
|
||||
import { getSafeServiceBaseUrl } from 'src/config'
|
||||
import { TokenProps } from 'src/logic/tokens/store/model/token'
|
||||
import { checksumAddress } from 'src/utils/checksumAddress'
|
||||
|
||||
type BalanceResult = {
|
||||
tokenAddress: string
|
||||
|
@ -10,8 +11,8 @@ type BalanceResult = {
|
|||
}
|
||||
|
||||
export const fetchTokenBalanceList = (safeAddress: string): Promise<AxiosResponse<{ results: BalanceResult[] }>> => {
|
||||
const apiUrl = getTxServiceUrl()
|
||||
const url = `${apiUrl}/safes/${safeAddress}/balances/`
|
||||
const address = checksumAddress(safeAddress)
|
||||
const url = `${getSafeServiceBaseUrl(address)}/balances/`
|
||||
|
||||
return axios.get(url)
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ import OpenInNew from '@material-ui/icons/OpenInNew'
|
|||
import cn from 'classnames'
|
||||
import React from 'react'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import Identicon from 'src/components/Identicon'
|
||||
import Block from 'src/components/layout/Block'
|
||||
import Col from 'src/components/layout/Col'
|
||||
|
@ -15,14 +17,13 @@ import Paragraph from 'src/components/layout/Paragraph'
|
|||
import Row from 'src/components/layout/Row'
|
||||
import Modal from 'src/components/Modal'
|
||||
import { getExplorerInfo } from 'src/config'
|
||||
import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts'
|
||||
import { getDisableModuleTxData } from 'src/logic/safe/utils/modules'
|
||||
import createTransaction from 'src/logic/safe/store/actions/createTransaction'
|
||||
|
||||
import { ModulePair } from 'src/logic/safe/store/models/safe'
|
||||
import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors'
|
||||
import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions'
|
||||
import { md, secondary } from 'src/theme/variables'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import { styles } from './style'
|
||||
|
||||
|
@ -46,7 +47,7 @@ interface RemoveModuleModal {
|
|||
const RemoveModuleModal = ({ onClose, selectedModule }: RemoveModuleModal): React.ReactElement => {
|
||||
const classes = useStyles()
|
||||
|
||||
const safeAddress = useSelector(safeParamAddressFromStateSelector) as string
|
||||
const safeAddress = useSelector(safeParamAddressFromStateSelector)
|
||||
const dispatch = useDispatch()
|
||||
|
||||
const explorerInfo = getExplorerInfo(selectedModule[0])
|
||||
|
@ -54,9 +55,7 @@ const RemoveModuleModal = ({ onClose, selectedModule }: RemoveModuleModal): Reac
|
|||
|
||||
const removeSelectedModule = async (): Promise<void> => {
|
||||
try {
|
||||
const safeInstance = await getGnosisSafeInstanceAt(safeAddress)
|
||||
const [module, prevModule] = selectedModule
|
||||
const txData = safeInstance.methods.disableModule(prevModule, module).encodeABI()
|
||||
const txData = getDisableModuleTxData(selectedModule, safeAddress)
|
||||
|
||||
dispatch(
|
||||
createTransaction({
|
||||
|
|
|
@ -83,7 +83,7 @@ const Advanced = (): React.ReactElement => {
|
|||
.
|
||||
</InfoText>
|
||||
|
||||
{moduleData === null ? (
|
||||
{!moduleData ? (
|
||||
<NoModuleLegend />
|
||||
) : moduleData?.length === 0 ? (
|
||||
<LoadingModules />
|
||||
|
|
Loading…
Reference in New Issue