Skip to content
This repository has been archived by the owner on Nov 10, 2023. It is now read-only.

Migrate Safe Apps endpoint to load directly from CGW #3195

Merged
merged 5 commits into from
Dec 21, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@
"@gnosis.pm/safe-core-sdk": "^1.1.1",
"@gnosis.pm/safe-deployments": "^1.5.0",
"@gnosis.pm/safe-react-components": "^0.9.0",
"@gnosis.pm/safe-react-gateway-sdk": "^2.5.8",
"@gnosis.pm/safe-react-gateway-sdk": "^2.6.0",
"@ledgerhq/hw-transport-node-hid-singleton": "6.3.0",
"@material-ui/core": "^4.12.3",
"@material-ui/icons": "^4.11.0",
Expand Down
21 changes: 0 additions & 21 deletions src/logic/config/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,8 @@
import axios from 'axios'
import { _getChainId, _setChainId } from 'src/config'
import { ChainId } from 'src/config/chain.d'
import { store } from 'src/store'
import { CONFIG_SERVICE_URL } from 'src/utils/constants'
import { setChainIdAction } from 'src/logic/config/store/actions'

export type RemoteAppData = {
id: number
url: string
name: string
iconUrl: string
description: string
chainIds: number[]
}

const enum Endpoints {
SAFE_APPS = '/safe-apps/',
}

// TODO: Migrate to GATEWAY_URL when CGW exposes it
export const fetchSafeAppsList = async (): Promise<RemoteAppData[]> => {
const { data } = await axios.get(`${CONFIG_SERVICE_URL}${Endpoints.SAFE_APPS}?chainId=${_getChainId()}`)
return data
}

export const setChainId = (newChainId: ChainId) => {
_setChainId(newChainId)
store.dispatch(setChainIdAction(newChainId))
Expand Down
8 changes: 8 additions & 0 deletions src/logic/safe/api/fetchSafeApps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { getSafeApps, SafeAppData } from '@gnosis.pm/safe-react-gateway-sdk'

import { _getChainId } from 'src/config'
import { GATEWAY_URL } from 'src/utils/constants'

export const fetchSafeAppsList = async (): Promise<SafeAppData[]> => {
return getSafeApps(GATEWAY_URL, _getChainId())
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const LoadedApp = (): React.ReactElement => (
iconUrl: 'https://cryptologos.cc/logos/versions/gnosis-gno-gno-logo-circle.svg?v=007',
description: 'Gnosis safe app',
fetchStatus: FETCH_STATUS.SUCCESS,
chainIds: ['4'],
}}
/>
)
54 changes: 29 additions & 25 deletions src/routes/safe/components/Apps/components/AppsList.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// import * as gateway from '@gnosis.pm/safe-react-gateway-sdk'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed! 😓 sorry for that!


import AppsList, { PINNED_APPS_LIST_TEST_ID, ALL_APPS_LIST_TEST_ID } from './AppsList'
import { render, screen, fireEvent, within, act, waitFor } from 'src/utils/test-utils'
import * as configServiceApi from 'src/logic/config/utils'

import * as appUtils from 'src/routes/safe/components/Apps/utils'
import { FETCH_STATUS } from 'src/utils/requests'
import { loadFromStorage, saveToStorage } from 'src/utils/storage'
Expand All @@ -16,23 +18,9 @@ jest.mock('src/routes/routes', () => {

const spyTrackEventGA = jest.fn()

beforeEach(async () => {
// Includes an id that doesn't exist in the remote apps to check that there's no error
saveToStorage(appUtils.PINNED_SAFE_APP_IDS, ['14', '24', '228'])

// populate custom app
saveToStorage(appUtils.APPS_STORAGE_KEY, [
{
url: 'https://apps.gnosis-safe.io/drain-safe',
},
])

jest.spyOn(googleAnalytics, 'useAnalytics').mockImplementation(() => ({
trackPage: jest.fn(),
trackEvent: spyTrackEventGA,
}))

jest.spyOn(configServiceApi, 'fetchSafeAppsList').mockImplementation(() =>
jest.mock('@gnosis.pm/safe-react-gateway-sdk', () => ({
__esModule: true,
getSafeApps: () =>
Promise.resolve([
{
id: 13,
Expand All @@ -42,7 +30,7 @@ beforeEach(async () => {
error: false,
description: 'Money markets on the Ethereum blockchain',
fetchStatus: 'SUCCESS',
chainIds: [1, 4],
chainIds: ['1', '4'],
provider: null,
},
{
Expand All @@ -53,7 +41,7 @@ beforeEach(async () => {

description: 'Decentralised naming for wallets, websites, & more.',
fetchStatus: 'SUCCESS',
chainIds: [1, 4],
chainIds: ['1', '4'],
provider: null,
},
{
Expand All @@ -63,7 +51,7 @@ beforeEach(async () => {
iconUrl: 'https://cloudflare-ipfs.com/ipfs/QmXLxxczMH4MBEYDeeN9zoiHDzVkeBmB5rBjA3UniPEFcA/Synthetix.png',
description: 'Trade synthetic assets on Ethereum',
fetchStatus: 'SUCCESS',
chainIds: [1, 4],
chainIds: ['1', '4'],
provider: null,
},
{
Expand All @@ -73,11 +61,27 @@ beforeEach(async () => {
iconUrl: 'https://cloudflare-ipfs.com/ipfs/QmdVaZxDov4bVARScTLErQSRQoxgqtBad8anWuw3YPQHCs/tx-builder.png',
description: 'A Safe app to compose custom transactions',
fetchStatus: 'SUCCESS',
chainIds: [1, 4, 56, 100, 137, 246, 73799],
chainIds: ['1', '4', '56', '100', '137', '246', '73799'],
provider: null,
},
]),
)
}))

beforeEach(() => {
// Includes an id that doesn't exist in the remote apps to check that there's no error
saveToStorage(appUtils.PINNED_SAFE_APP_IDS, ['14', '24', '228'])

// populate custom app
saveToStorage(appUtils.APPS_STORAGE_KEY, [
{
url: 'https://apps.gnosis-safe.io/drain-safe',
},
])

jest.spyOn(googleAnalytics, 'useAnalytics').mockImplementation(() => ({
trackPage: jest.fn(),
trackEvent: spyTrackEventGA,
}))

jest.spyOn(appUtils, 'getAppInfoFromUrl').mockReturnValueOnce(
Promise.resolve({
Expand All @@ -87,8 +91,8 @@ beforeEach(async () => {
iconUrl: 'https://apps.gnosis-safe.io/drain-safe/logo.svg',
error: false,
description: 'Transfer all your assets in batch',
chainIds: [4],
provider: null,
chainIds: ['4'],
provider: undefined,
fetchStatus: FETCH_STATUS.SUCCESS,
}),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import enqueueSnackbar from 'src/logic/notifications/store/actions/enqueueSnackb
import { NOTIFICATIONS } from 'src/logic/notifications'
import { FETCH_STATUS } from 'src/utils/requests'
import { SafeApp } from '../../types'
import { fetchSafeAppsList } from 'src/logic/config/utils'
import { fetchSafeAppsList } from 'src/logic/safe/api/fetchSafeApps'

type ReturnType = {
remoteSafeApps: SafeApp[]
Expand Down
7 changes: 2 additions & 5 deletions src/routes/safe/components/Apps/types.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { SafeAppData } from '@gnosis.pm/safe-react-gateway-sdk'
import { FETCH_STATUS } from 'src/utils/requests'

export type SafeApp = {
export type SafeApp = Omit<SafeAppData, 'id'> & {
id: string
url: string
name: string
iconUrl: string
disabled?: boolean
description: string
fetchStatus: FETCH_STATUS
custom?: boolean
}
Expand Down
1 change: 1 addition & 0 deletions src/routes/safe/components/Apps/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export const getEmptySafeApp = (url = ''): SafeApp => {
iconUrl: appsIconSvg,
description: '',
fetchStatus: FETCH_STATUS.LOADING,
chainIds: [],
}
}

Expand Down
4 changes: 0 additions & 4 deletions src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ export const COLLECTIBLES_SOURCE = process.env.REACT_APP_COLLECTIBLES_SOURCE ||
export const SAFE_POLLING_INTERVAL = process.env.NODE_ENV === 'test' ? 4500 : 15000
export const ETHERSCAN_API_KEY = process.env.REACT_APP_ETHERSCAN_API_KEY || ''
export const ETHGASSTATION_API_KEY = process.env.REACT_APP_ETHGASSTATION_API_KEY
export const CONFIG_SERVICE_URL =
process.env.CONFIG_SERVICE_URL || IS_PRODUCTION
? 'https://safe-config.gnosis.io/api/v1'
: 'https://safe-config.staging.gnosisdev.com/api/v1'
export const IPFS_GATEWAY = process.env.REACT_APP_IPFS_GATEWAY
export const SPENDING_LIMIT_MODULE_ADDRESS =
process.env.REACT_APP_SPENDING_LIMIT_MODULE_ADDRESS || '0xCFbFaC74C26F8647cBDb8c5caf80BB5b32E43134'
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2170,10 +2170,10 @@
dependencies:
isomorphic-unfetch "^3.1.0"

"@gnosis.pm/safe-react-gateway-sdk@^2.5.8":
version "2.5.8"
resolved "https://registry.yarnpkg.com/@gnosis.pm/safe-react-gateway-sdk/-/safe-react-gateway-sdk-2.5.8.tgz#e43b1346829a127f5e87c3e45bfc0afb3d28773c"
integrity sha512-ZMVblmKe4YEGoznNzZxKr2coXS3ZIRpLX80ErlcAauv1YbJgdIGpRyloiGkOtwshwI3y5pRm0FI1QU8mrcUlwg==
"@gnosis.pm/safe-react-gateway-sdk@^2.6.0":
version "2.6.0"
resolved "https://registry.yarnpkg.com/@gnosis.pm/safe-react-gateway-sdk/-/safe-react-gateway-sdk-2.6.0.tgz#347122ad67aa4a38caa40758ebf35a8f9e98358c"
integrity sha512-mGse0EJ4e77sgf5gtTvaYIToLmjxdIQ6YlV0VgLHTXb3WLm1dQ5bTiynU4Nr4guc27qu45puDx4sqXBUmuMybQ==
dependencies:
isomorphic-unfetch "^3.1.0"

Expand Down