From bf39501ebb12c5727c310ec92af831fb29497f1e Mon Sep 17 00:00:00 2001 From: katspaugh Date: Thu, 27 May 2021 09:53:28 +0200 Subject: [PATCH 01/10] Fix typo (#2335) --- src/routes/safe/components/Transactions/TxList/QueueTxList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/safe/components/Transactions/TxList/QueueTxList.tsx b/src/routes/safe/components/Transactions/TxList/QueueTxList.tsx index 1ef22bf5..88acd9d0 100644 --- a/src/routes/safe/components/Transactions/TxList/QueueTxList.tsx +++ b/src/routes/safe/components/Transactions/TxList/QueueTxList.tsx @@ -86,7 +86,7 @@ export const QueueTxList = ({ transactions }: QueueTxListProps): ReactElement => const title = txLocation === 'queued.next' ? 'NEXT TRANSACTION' - : `QUEUE - Transaction with nonce ${nonce} needs to be executed fisrt` + : `QUEUE - Transaction with nonce ${nonce} needs to be executed first` const { lastItemId, setLastItemId } = useContext(TxsInfiniteScrollContext) if (transactions.length) { From 12edb5b988608e84a9b8f5ccf8c06c600b943275 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Thu, 27 May 2021 12:54:18 +0400 Subject: [PATCH 02/10] Feature: Allow passing additional context to CodedException (#2334) * Allow passing context to CodedException * create a test for context * update test * sentryContext > context * rename sentryContext in test --- src/logic/exceptions/CodedException.test.ts | 29 ++++++++++++++++++- src/logic/exceptions/CodedException.ts | 22 ++++++++++---- src/logic/exceptions/registry.ts | 2 ++ .../tokens/store/actions/fetchSafeTokens.ts | 2 +- src/logic/tokens/store/actions/fetchTokens.ts | 2 +- 5 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/logic/exceptions/CodedException.test.ts b/src/logic/exceptions/CodedException.test.ts index 4934d4db..b38c6170 100644 --- a/src/logic/exceptions/CodedException.test.ts +++ b/src/logic/exceptions/CodedException.test.ts @@ -26,6 +26,33 @@ describe('CodedException', () => { expect(err.code).toBe(100) }) + it('creates an error with an extra message and a context', () => { + const context = { + tags: { + error_category: 'Safe Apps', + }, + contexts: { + safeApp: { + name: 'Zorbed.Finance', + url: 'https://zorbed.finance', + }, + message: { + method: 'getSafeBalance', + params: { + address: '0x000000', + }, + }, + }, + } + + const err = new CodedException(Errors._901, 'getSafeBalance: Server responded with 429 Too Many Requests', context) + expect(err.message).toBe( + '901: Error processing Safe Apps SDK request (getSafeBalance: Server responded with 429 Too Many Requests)', + ) + expect(err.code).toBe(901) + expect(err.context).toEqual(context) + }) + describe('Logging', () => { beforeAll(() => { jest.mock('console') @@ -70,7 +97,7 @@ describe('CodedException', () => { it("doesn't track when isTracked is false", () => { ;(constants as any).IS_PRODUCTION = true - logError(Errors._100, '', false) + logError(Errors._100, '', undefined, false) expect(Sentry.captureException).not.toHaveBeenCalled() }) diff --git a/src/logic/exceptions/CodedException.ts b/src/logic/exceptions/CodedException.ts index bf383300..af423417 100644 --- a/src/logic/exceptions/CodedException.ts +++ b/src/logic/exceptions/CodedException.ts @@ -1,23 +1,28 @@ import * as Sentry from '@sentry/react' +import { CaptureContext } from '@sentry/types' import ErrorCodes from './registry' import { IS_PRODUCTION } from 'src/utils/constants' export class CodedException extends Error { - public readonly message: string public readonly code: number + // the context allows to enrich events, for the list of allowed context keys/data, please check the type or go to + // https://docs.sentry.io/platforms/javascript/enriching-events/context/ + // The context is not searchable, that means its goal is just to provide additional data for the error + public readonly context?: CaptureContext - constructor(content: ErrorCodes, extraMessage?: string) { + constructor(content: ErrorCodes, extraMessage?: string, context?: CaptureContext) { super() const codePrefix = content.split(':')[0] const code = Number(codePrefix) if (isNaN(code)) { - throw new CodedException(ErrorCodes.___0, codePrefix) + throw new CodedException(ErrorCodes.___0, codePrefix, context) } const extraInfo = extraMessage ? ` (${extraMessage})` : '' this.message = `${content}${extraInfo}` this.code = code + this.context = context } /** @@ -28,13 +33,18 @@ export class CodedException extends Error { console.error(IS_PRODUCTION ? this.message : this) if (IS_PRODUCTION && isTracked) { - Sentry.captureException(this) + Sentry.captureException(this, this.context) } } } -export function logError(content: ErrorCodes, extraMessage?: string, isTracked?: boolean): CodedException { - const error = new CodedException(content, extraMessage) +export function logError( + content: ErrorCodes, + extraMessage?: string, + context?: CaptureContext, + isTracked?: boolean, +): CodedException { + const error = new CodedException(content, extraMessage, context) error.log(isTracked) return error } diff --git a/src/logic/exceptions/registry.ts b/src/logic/exceptions/registry.ts index 18c3d3b0..65b45c85 100644 --- a/src/logic/exceptions/registry.ts +++ b/src/logic/exceptions/registry.ts @@ -9,6 +9,8 @@ enum ErrorCodes { _100 = '100: Invalid input in the address field', _600 = '600: Error fetching token list', _601 = '601: Error fetching balances', + _900 = '900: Error loading Safe App', + _901 = '901: Error processing Safe Apps SDK request', } export default ErrorCodes diff --git a/src/logic/tokens/store/actions/fetchSafeTokens.ts b/src/logic/tokens/store/actions/fetchSafeTokens.ts index 2c67a39a..13164414 100644 --- a/src/logic/tokens/store/actions/fetchSafeTokens.ts +++ b/src/logic/tokens/store/actions/fetchSafeTokens.ts @@ -70,7 +70,7 @@ export const fetchSafeTokens = (safeAddress: string, currencySelected?: string) selectedCurrency: currencySelected ?? selectedCurrency, }) } catch (e) { - logError(Errors._601, e.message, false) + logError(Errors._601, e.message, undefined, false) return } diff --git a/src/logic/tokens/store/actions/fetchTokens.ts b/src/logic/tokens/store/actions/fetchTokens.ts index cf47e94f..b47b88ad 100644 --- a/src/logic/tokens/store/actions/fetchTokens.ts +++ b/src/logic/tokens/store/actions/fetchTokens.ts @@ -61,7 +61,7 @@ export const fetchTokens = () => async ( const resp = await fetchErc20AndErc721AssetsList() tokenList = resp.data.results } catch (e) { - logError(Errors._600, e.message, false) + logError(Errors._600, e.message, undefined, false) return } From be39e4a8e3dfd50aa70d64f296b45489d1b34054 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Thu, 27 May 2021 13:29:46 +0400 Subject: [PATCH 03/10] Feature: Allow apps to request safe balances (#2316) * add api function fetchTokenBalances, code improvements * update test * Update sdk version * handle getSafeBalances call * console.log > console.error * rename declaration file * rename declaration file, fix types * use logError func to log error in communicator * accept currency for getSafeBalance * sort imports * add generic error for processing safe apps requests * add error codes for safe apps * add usage of error 900 * fix logError usage in getAppInfo --- package.json | 2 +- .../fetchTokenCurrenciesBalances.test.ts} | 61 ++++---- .../safe/api/fetchSafeTxGasEstimation.ts | 5 +- .../safe/api/fetchTokenCurrenciesBalances.ts | 4 +- .../components/Apps/__tests__/utils.test.ts | 2 +- .../safe/components/Apps/communicator.ts | 12 +- .../Apps/components/AddAppForm/AppUrl.tsx | 2 +- .../components/AddAppForm/FormButtons.tsx | 2 +- .../Apps/components/AddAppForm/index.tsx | 2 +- .../components/Apps/components/AppFrame.tsx | 21 ++- .../components/Apps/components/AppsList.tsx | 2 +- .../Apps/components/ConfirmTxModal/index.tsx | 2 +- .../safe/components/Apps/hooks/useAppList.ts | 2 +- .../Apps/hooks/useIframeMessageHandler.ts | 2 +- .../components/Apps/{types.d.ts => types.ts} | 0 src/routes/safe/components/Apps/utils.ts | 7 +- yarn.lock | 132 +++--------------- 17 files changed, 89 insertions(+), 171 deletions(-) rename src/logic/safe/{__tests__/fetchSafeTokens.test.ts => api/__tests__/fetchTokenCurrenciesBalances.test.ts} (51%) rename src/routes/safe/components/Apps/{types.d.ts => types.ts} (100%) diff --git a/package.json b/package.json index 535a4531..24f21853 100644 --- a/package.json +++ b/package.json @@ -158,7 +158,7 @@ ] }, "dependencies": { - "@gnosis.pm/safe-apps-sdk": "1.0.3", + "@gnosis.pm/safe-apps-sdk": "3.0.0-alpha.5", "@gnosis.pm/safe-apps-sdk-v1": "npm:@gnosis.pm/safe-apps-sdk@0.4.2", "@gnosis.pm/safe-contracts": "1.1.1-dev.2", "@gnosis.pm/safe-react-components": "https://github.com/gnosis/safe-react-components.git#4864ebb", diff --git a/src/logic/safe/__tests__/fetchSafeTokens.test.ts b/src/logic/safe/api/__tests__/fetchTokenCurrenciesBalances.test.ts similarity index 51% rename from src/logic/safe/__tests__/fetchSafeTokens.test.ts rename to src/logic/safe/api/__tests__/fetchTokenCurrenciesBalances.test.ts index 4b9a4901..84fa49cf 100644 --- a/src/logic/safe/__tests__/fetchSafeTokens.test.ts +++ b/src/logic/safe/api/__tests__/fetchTokenCurrenciesBalances.test.ts @@ -2,50 +2,53 @@ import axios from 'axios' import { getSafeClientGatewayBaseUrl } from 'src/config' import { fetchTokenCurrenciesBalances } from 'src/logic/safe/api/fetchTokenCurrenciesBalances' -import { aNewStore } from 'src/store' jest.mock('axios') describe('fetchTokenCurrenciesBalances', () => { - let store const safeAddress = '0xdfA693da0D16F5E7E78FdCBeDe8FC6eBEa44f1Cf' const excludeSpamTokens = true - beforeEach(() => { - store = aNewStore() - }) + afterAll(() => { jest.unmock('axios') }) it('Given a safe address, calls the API and returns token balances', async () => { // given - const expectedResult = [ - { - tokenAddress: '', - balance: '849890000000000000', - fiatBalance: '337.2449', - fiatConversion: '396.81', - fiatCode: 'USD', - }, - { - tokenAddress: '0x5592EC0cfb4dbc12D3aB100b257153436a1f0FEa', - token: { - address: '0x5592EC0cfb4dbc12D3aB100b257153436a1f0FEa', - balance: '24698677800000000000', - name: 'Dai', - symbol: 'DAI', - decimals: 18, - logoUri: 'https://gnosis-safe-token-logos.s3.amazonaws.com/0x5592EC0cfb4dbc12D3aB100b257153436a1f0FEa.png', + const expectedResult = { + fiatTotal: '104.32679999999999', + items: [ + { + tokenInfo: { + type: 'ERC20', + address: '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e', + decimals: 18, + symbol: 'YFI', + name: 'yearn.finance', + logoUri: 'https://gnosis-safe-token-logos.s3.amazonaws.com/0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e.png', + }, + balance: '465000000000000', + fiatBalance: '24.0178', + fiatConversion: '51651.1013', }, - balance: '24698677800000000000', - fiatBalance: '29.3432', - fiatConversion: '1.188', - fiatCode: 'USD', - }, - ] + { + tokenInfo: { + type: 'ETHER', + address: '0x0000000000000000000000000000000000000000', + decimals: 18, + symbol: 'ETH', + name: 'Ether', + logoUri: null, + }, + balance: '4035779634142020', + fiatBalance: '10.9702', + fiatConversion: '2718.2447', + }, + ], + } const apiUrl = getSafeClientGatewayBaseUrl(safeAddress) - // @ts-ignore + // @ts-expect-error mocking get method axios.get.mockImplementationOnce(() => Promise.resolve({ data: expectedResult })) // when diff --git a/src/logic/safe/api/fetchSafeTxGasEstimation.ts b/src/logic/safe/api/fetchSafeTxGasEstimation.ts index b0a4759e..c8b46d90 100644 --- a/src/logic/safe/api/fetchSafeTxGasEstimation.ts +++ b/src/logic/safe/api/fetchSafeTxGasEstimation.ts @@ -15,10 +15,7 @@ type FetchSafeTxGasEstimationProps = { operation: number } -export const fetchSafeTxGasEstimation = async ({ - safeAddress, - ...body -}: FetchSafeTxGasEstimationProps): Promise => { +export const fetchSafeTxGasEstimation = ({ safeAddress, ...body }: FetchSafeTxGasEstimationProps): Promise => { const url = `${getSafeServiceBaseUrl(checksumAddress(safeAddress))}/multisig-transactions/estimations/` return axios.post(url, body).then(({ data }) => data.safeTxGas) diff --git a/src/logic/safe/api/fetchTokenCurrenciesBalances.ts b/src/logic/safe/api/fetchTokenCurrenciesBalances.ts index d1185a3d..b600c3ba 100644 --- a/src/logic/safe/api/fetchTokenCurrenciesBalances.ts +++ b/src/logic/safe/api/fetchTokenCurrenciesBalances.ts @@ -5,7 +5,7 @@ import { TokenProps } from 'src/logic/tokens/store/model/token' import { checksumAddress } from 'src/utils/checksumAddress' export type TokenBalance = { - tokenInfo: TokenProps + tokenInfo: Omit balance: string fiatBalance: string fiatConversion: string @@ -23,7 +23,7 @@ type FetchTokenCurrenciesBalancesProps = { trustedTokens?: boolean } -export const fetchTokenCurrenciesBalances = async ({ +export const fetchTokenCurrenciesBalances = ({ safeAddress, selectedCurrency, excludeSpamTokens = true, diff --git a/src/routes/safe/components/Apps/__tests__/utils.test.ts b/src/routes/safe/components/Apps/__tests__/utils.test.ts index e4349b9e..795f53ef 100644 --- a/src/routes/safe/components/Apps/__tests__/utils.test.ts +++ b/src/routes/safe/components/Apps/__tests__/utils.test.ts @@ -1,5 +1,5 @@ import { isAppManifestValid } from '../utils' -import { SafeApp } from '../types.d' +import { SafeApp } from '../types' describe('SafeApp manifest', () => { it('It should return true given a manifest with mandatory values supplied', async () => { diff --git a/src/routes/safe/components/Apps/communicator.ts b/src/routes/safe/components/Apps/communicator.ts index 839c6bbf..95bd7a98 100644 --- a/src/routes/safe/components/Apps/communicator.ts +++ b/src/routes/safe/components/Apps/communicator.ts @@ -7,8 +7,10 @@ import { ErrorResponse, MessageFormatter, METHODS, + RequestId, } from '@gnosis.pm/safe-apps-sdk' -import { SafeApp } from './types.d' +import { logError, Errors } from 'src/logic/exceptions/CodedException' +import { SafeApp } from './types' type MessageHandler = ( msg: SDKMessageEvent, @@ -42,10 +44,10 @@ class AppCommunicator { return Boolean(this.handlers.get(msg.data.method)) } - send = (data, requestId, error = false): void => { + send = (data: unknown, requestId: RequestId, error = false): void => { const sdkVersion = getSDKVersion() const msg = error - ? MessageFormatter.makeErrorResponse(requestId, data, sdkVersion) + ? MessageFormatter.makeErrorResponse(requestId, data as string, sdkVersion) : MessageFormatter.makeResponse(requestId, data, sdkVersion) this.iframeRef.current?.contentWindow?.postMessage(msg, '*') @@ -66,8 +68,10 @@ class AppCommunicator { this.send(response, msg.data.id) } } catch (err) { - console.log({ err }) this.send(err.message, msg.data.id, true) + // TODO: Allow passing method/message as an extra context + // Tweak CodedException class to accept it as a second argument + logError(Errors._901, `${msg.data.method} ${err.message}`) } } } diff --git a/src/routes/safe/components/Apps/components/AddAppForm/AppUrl.tsx b/src/routes/safe/components/Apps/components/AddAppForm/AppUrl.tsx index 5573cb33..4e1a7e44 100644 --- a/src/routes/safe/components/Apps/components/AddAppForm/AppUrl.tsx +++ b/src/routes/safe/components/Apps/components/AddAppForm/AppUrl.tsx @@ -4,7 +4,7 @@ import React from 'react' import { useField, useFormState } from 'react-final-form' import styled from 'styled-components' -import { SafeApp } from 'src/routes/safe/components/Apps/types.d' +import { SafeApp } from 'src/routes/safe/components/Apps/types' import { getAppInfoFromUrl, getIpfsLinkFromEns, uniqueApp } from 'src/routes/safe/components/Apps/utils' import { composeValidators, required } from 'src/components/forms/validator' import Field from 'src/components/forms/Field' diff --git a/src/routes/safe/components/Apps/components/AddAppForm/FormButtons.tsx b/src/routes/safe/components/Apps/components/AddAppForm/FormButtons.tsx index 0d060e92..24b93635 100644 --- a/src/routes/safe/components/Apps/components/AddAppForm/FormButtons.tsx +++ b/src/routes/safe/components/Apps/components/AddAppForm/FormButtons.tsx @@ -2,7 +2,7 @@ import React, { ReactElement, useMemo } from 'react' import { useFormState } from 'react-final-form' import { Modal } from 'src/components/Modal' -import { SafeApp } from 'src/routes/safe/components/Apps/types.d' +import { SafeApp } from 'src/routes/safe/components/Apps/types' import { isAppManifestValid } from 'src/routes/safe/components/Apps/utils' interface Props { diff --git a/src/routes/safe/components/Apps/components/AddAppForm/index.tsx b/src/routes/safe/components/Apps/components/AddAppForm/index.tsx index a540bace..12eadd58 100644 --- a/src/routes/safe/components/Apps/components/AddAppForm/index.tsx +++ b/src/routes/safe/components/Apps/components/AddAppForm/index.tsx @@ -2,7 +2,7 @@ import { Icon, Link, Loader, Text, TextField } from '@gnosis.pm/safe-react-compo import React, { useState, ReactElement } from 'react' import styled from 'styled-components' -import { SafeApp } from 'src/routes/safe/components/Apps/types.d' +import { SafeApp } from 'src/routes/safe/components/Apps/types' import GnoForm from 'src/components/forms/GnoForm' import Img from 'src/components/layout/Img' import { Modal } from 'src/components/Modal' diff --git a/src/routes/safe/components/Apps/components/AppFrame.tsx b/src/routes/safe/components/Apps/components/AppFrame.tsx index 1367cfb2..8ac749a3 100644 --- a/src/routes/safe/components/Apps/components/AppFrame.tsx +++ b/src/routes/safe/components/Apps/components/AppFrame.tsx @@ -1,7 +1,7 @@ import React, { ReactElement, useState, useRef, useCallback, useEffect } from 'react' import styled from 'styled-components' import { FixedIcon, Loader, Title, Card } from '@gnosis.pm/safe-react-components' -import { MethodToResponse, RPCPayload } from '@gnosis.pm/safe-apps-sdk' +import { GetBalanceParams, MethodToResponse, RPCPayload } from '@gnosis.pm/safe-apps-sdk' import { useHistory } from 'react-router-dom' import { useSelector } from 'react-redux' import { INTERFACE_MESSAGES, Transaction, RequestId, LowercaseNetworks } from '@gnosis.pm/safe-apps-sdk-v1' @@ -26,8 +26,9 @@ import { useIframeMessageHandler } from '../hooks/useIframeMessageHandler' import { useLegalConsent } from '../hooks/useLegalConsent' import LegalDisclaimer from './LegalDisclaimer' import { getAppInfoFromUrl } from '../utils' -import { SafeApp } from '../types.d' +import { SafeApp } from '../types' import { useAppCommunicator } from '../communicator' +import { fetchTokenCurrenciesBalances } from 'src/logic/safe/api/fetchTokenCurrenciesBalances' const OwnerDisclaimer = styled.div` display: flex; @@ -65,7 +66,7 @@ export type TransactionParams = { type ConfirmTransactionModalState = { isOpen: boolean txs: Transaction[] - requestId?: RequestId + requestId: RequestId params?: TransactionParams } @@ -79,7 +80,7 @@ const NETWORK_ID = getNetworkId() const INITIAL_CONFIRM_TX_MODAL_STATE: ConfirmTransactionModalState = { isOpen: false, txs: [], - requestId: undefined, + requestId: '', params: undefined, } @@ -170,6 +171,14 @@ const AppFrame = ({ appUrl }: Props): ReactElement => { chainId: NETWORK_ID, })) + communicator?.on('getSafeBalances', async (msg) => { + const { currency = 'usd' } = msg.data.params as GetBalanceParams + + const balances = await fetchTokenCurrenciesBalances({ safeAddress, selectedCurrency: currency }) + + return balances + }) + communicator?.on('rpcCall', async (msg) => { const params = msg.data.params as RPCPayload @@ -218,7 +227,7 @@ const AppFrame = ({ appUrl }: Props): ReactElement => { ) // Safe Apps SDK V2 Handler - communicator?.send({ safeTxHash }, confirmTransactionModal.requestId) + communicator?.send({ safeTxHash }, confirmTransactionModal.requestId as string) } const onTxReject = () => { @@ -229,7 +238,7 @@ const AppFrame = ({ appUrl }: Props): ReactElement => { ) // Safe Apps SDK V2 Handler - communicator?.send('Transaction was rejected', confirmTransactionModal.requestId, true) + communicator?.send('Transaction was rejected', confirmTransactionModal.requestId as string, true) } useEffect(() => { diff --git a/src/routes/safe/components/Apps/components/AppsList.tsx b/src/routes/safe/components/Apps/components/AppsList.tsx index 7355a12f..6ae24fc4 100644 --- a/src/routes/safe/components/Apps/components/AppsList.tsx +++ b/src/routes/safe/components/Apps/components/AppsList.tsx @@ -12,7 +12,7 @@ import { useRouteMatch, Link } from 'react-router-dom' import { SAFELIST_ADDRESS } from 'src/routes/routes' import { useAppList } from '../hooks/useAppList' -import { SAFE_APP_FETCH_STATUS, SafeApp } from '../types.d' +import { SAFE_APP_FETCH_STATUS, SafeApp } from '../types' import AddAppForm from './AddAppForm' import { AppData } from '../api/fetchSafeAppsList' diff --git a/src/routes/safe/components/Apps/components/ConfirmTxModal/index.tsx b/src/routes/safe/components/Apps/components/ConfirmTxModal/index.tsx index ebadeded..13fa7354 100644 --- a/src/routes/safe/components/Apps/components/ConfirmTxModal/index.tsx +++ b/src/routes/safe/components/Apps/components/ConfirmTxModal/index.tsx @@ -2,7 +2,7 @@ import React, { ReactElement, useState } from 'react' import { Transaction } from '@gnosis.pm/safe-apps-sdk-v1' import Modal from 'src/components/Modal' -import { SafeApp } from 'src/routes/safe/components/Apps/types.d' +import { SafeApp } from 'src/routes/safe/components/Apps/types' import { TransactionParams } from 'src/routes/safe/components/Apps/components/AppFrame' import { mustBeEthereumAddress } from 'src/components/forms/validator' import { SafeAppLoadError } from './SafeAppLoadError' diff --git a/src/routes/safe/components/Apps/hooks/useAppList.ts b/src/routes/safe/components/Apps/hooks/useAppList.ts index 7dd6d835..68c7f19c 100644 --- a/src/routes/safe/components/Apps/hooks/useAppList.ts +++ b/src/routes/safe/components/Apps/hooks/useAppList.ts @@ -2,7 +2,7 @@ import { useState, useEffect, useCallback } from 'react' import { loadFromStorage, saveToStorage } from 'src/utils/storage' import { APPS_STORAGE_KEY, getAppInfoFromUrl, getAppsList, getEmptySafeApp } from '../utils' import { AppData } from '../api/fetchSafeAppsList' -import { SafeApp, StoredSafeApp, SAFE_APP_FETCH_STATUS } from '../types.d' +import { SafeApp, StoredSafeApp, SAFE_APP_FETCH_STATUS } from '../types' import { getNetworkId } from 'src/config' type UseAppListReturnType = { diff --git a/src/routes/safe/components/Apps/hooks/useIframeMessageHandler.ts b/src/routes/safe/components/Apps/hooks/useIframeMessageHandler.ts index a87a3ab8..8d325f65 100644 --- a/src/routes/safe/components/Apps/hooks/useIframeMessageHandler.ts +++ b/src/routes/safe/components/Apps/hooks/useIframeMessageHandler.ts @@ -19,7 +19,7 @@ import { safeParamAddressFromStateSelector, } from 'src/logic/safe/store/selectors' import { TransactionParams } from '../components/AppFrame' -import { SafeApp } from 'src/routes/safe/components/Apps/types.d' +import { SafeApp } from 'src/routes/safe/components/Apps/types' type InterfaceMessageProps = { messageId: T diff --git a/src/routes/safe/components/Apps/types.d.ts b/src/routes/safe/components/Apps/types.ts similarity index 100% rename from src/routes/safe/components/Apps/types.d.ts rename to src/routes/safe/components/Apps/types.ts diff --git a/src/routes/safe/components/Apps/utils.ts b/src/routes/safe/components/Apps/utils.ts index 68fda5a1..506eabd1 100644 --- a/src/routes/safe/components/Apps/utils.ts +++ b/src/routes/safe/components/Apps/utils.ts @@ -1,16 +1,17 @@ import axios from 'axios' import memoize from 'lodash.memoize' -import { SafeApp, SAFE_APP_FETCH_STATUS } from './types.d' +import { SafeApp, SAFE_APP_FETCH_STATUS } from './types' import { getContentFromENS } from 'src/logic/wallets/getWeb3' import appsIconSvg from 'src/assets/icons/apps.svg' import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' +import { logError, Errors } from 'src/logic/exceptions/CodedException' import { AppData, fetchSafeAppsList } from './api/fetchSafeAppsList' export const APPS_STORAGE_KEY = 'APPS_STORAGE_KEY' -const removeLastTrailingSlash = (url) => { +const removeLastTrailingSlash = (url: string): string => { if (url.substr(-1) === '/') { return url.substr(0, url.length - 1) } @@ -273,7 +274,7 @@ export const getAppInfoFromUrl = memoize( } return res } catch (error) { - console.error(`It was not possible to fetch app from ${res.url}: ${error.message}`) + logError(Errors._900, `${res.url}: ${error.message}`, undefined, false) return res } }, diff --git a/yarn.lock b/yarn.lock index 04f0804a..5afa3cf1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1393,7 +1393,7 @@ ripemd160 "^2.0.2" sha3 "^2.1.3" -"@eslint/eslintrc@^0.4.0", "@eslint/eslintrc@^0.4.1": +"@eslint/eslintrc@^0.4.1": version "0.4.1" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.1.tgz#442763b88cecbe3ee0ec7ca6d6dd6168550cbf14" integrity sha512-5v7TDE9plVhvxQeWLXDTvFvJBdH6pEsdnl2g/dAptmuFEPedQ4Erq5rsDsX+mvAM610IhNaO2W5V1dOOnDKxkQ== @@ -1617,13 +1617,12 @@ resolved "https://registry.yarnpkg.com/@gnosis.pm/safe-apps-sdk/-/safe-apps-sdk-0.4.2.tgz#ae87b2164931c006cb0efdede3d82ff210df1648" integrity sha512-BwA2dyCebPMdi4JhhTkp6EjkhEM6vAIviKdhqHiHnSmL+sDfxtP1jdOuE8ME2/4+5TiLSS8k8qscYjLSlf1LLw== -"@gnosis.pm/safe-apps-sdk@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@gnosis.pm/safe-apps-sdk/-/safe-apps-sdk-1.0.3.tgz#006d709700419302af490f6beaac67b1db4b36fb" - integrity sha512-77c6lg4SfCbQtMjgB2vVPKQglUCOjSpwweNeoD4m0c5hnd5lFg0Dlcc45LwtcUL8j5XhDf+aBxT8LDD+XGDSNw== +"@gnosis.pm/safe-apps-sdk@3.0.0-alpha.5": + version "3.0.0-alpha.5" + resolved "https://registry.yarnpkg.com/@gnosis.pm/safe-apps-sdk/-/safe-apps-sdk-3.0.0-alpha.5.tgz#f939e3a5719f51686151b76cb40af2ca4d410d30" + integrity sha512-yVvnJCl3B9Xk68vh+03rej4REx7cTfiR55b9TjqPaBtZLtY+c57UHCslUmkK+0MRMF4SyKaV5S9BOqI/iX9a3Q== dependencies: - semver "^7.3.2" - web3-core "^1.3.0" + semver "7.1.1" "@gnosis.pm/safe-contracts@1.1.1-dev.2": version "1.1.1-dev.2" @@ -1903,7 +1902,7 @@ dependencies: invariant "2" -"@ledgerhq/devices@^5.50.0", "@ledgerhq/devices@^5.51.1": +"@ledgerhq/devices@^5.51.1": version "5.51.1" resolved "https://registry.yarnpkg.com/@ledgerhq/devices/-/devices-5.51.1.tgz#d741a4a5d8f17c2f9d282fd27147e6fe1999edb7" integrity sha512-4w+P0VkbjzEXC7kv8T1GJ/9AVaP9I6uasMZ/JcdwZBS3qwvKo5A5z9uGhP5c7TvItzcmPb44b5Mw2kT+WjUuAA== @@ -3822,18 +3821,6 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/experimental-utils@4.22.1": - version "4.22.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.22.1.tgz#3938a5c89b27dc9a39b5de63a62ab1623ab27497" - integrity sha512-svYlHecSMCQGDO2qN1v477ax/IDQwWhc7PRBiwAdAMJE7GXk5stF4Z9R/8wbRkuX/5e9dHqbIWxjeOjckK3wLQ== - dependencies: - "@types/json-schema" "^7.0.3" - "@typescript-eslint/scope-manager" "4.22.1" - "@typescript-eslint/types" "4.22.1" - "@typescript-eslint/typescript-estree" "4.22.1" - eslint-scope "^5.0.0" - eslint-utils "^2.0.0" - "@typescript-eslint/experimental-utils@4.23.0", "@typescript-eslint/experimental-utils@^4.0.1": version "4.23.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.23.0.tgz#f2059434cd6e5672bfeab2fb03b7c0a20622266f" @@ -3867,14 +3854,6 @@ "@typescript-eslint/typescript-estree" "4.23.0" debug "^4.1.1" -"@typescript-eslint/scope-manager@4.22.1": - version "4.22.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.22.1.tgz#5bb357f94f9cd8b94e6be43dd637eb73b8f355b4" - integrity sha512-d5bAiPBiessSmNi8Amq/RuLslvcumxLmyhf1/Xa9IuaoFJ0YtshlJKxhlbY7l2JdEk3wS0EnmnfeJWSvADOe0g== - dependencies: - "@typescript-eslint/types" "4.22.1" - "@typescript-eslint/visitor-keys" "4.22.1" - "@typescript-eslint/scope-manager@4.23.0": version "4.23.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.23.0.tgz#8792ef7eacac122e2ec8fa2d30a59b8d9a1f1ce4" @@ -3888,11 +3867,6 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.10.1.tgz#1d7463fa7c32d8a23ab508a803ca2fe26e758727" integrity sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ== -"@typescript-eslint/types@4.22.1": - version "4.22.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.22.1.tgz#bf99c6cec0b4a23d53a61894816927f2adad856a" - integrity sha512-2HTkbkdAeI3OOcWbqA8hWf/7z9c6gkmnWNGz0dKSLYLWywUlkOAQ2XcjhlKLj5xBFDf8FgAOF5aQbnLRvgNbCw== - "@typescript-eslint/types@4.23.0": version "4.23.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.23.0.tgz#da1654c8a5332f4d1645b2d9a1c64193cae3aa3b" @@ -3912,19 +3886,6 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/typescript-estree@4.22.1": - version "4.22.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.22.1.tgz#dca379eead8cdfd4edc04805e83af6d148c164f9" - integrity sha512-p3We0pAPacT+onSGM+sPR+M9CblVqdA9F1JEdIqRVlxK5Qth4ochXQgIyb9daBomyQKAXbygxp1aXQRV0GC79A== - dependencies: - "@typescript-eslint/types" "4.22.1" - "@typescript-eslint/visitor-keys" "4.22.1" - debug "^4.1.1" - globby "^11.0.1" - is-glob "^4.0.1" - semver "^7.3.2" - tsutils "^3.17.1" - "@typescript-eslint/typescript-estree@4.23.0": version "4.23.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.23.0.tgz#0753b292097523852428a6f5a1aa8ccc1aae6cd9" @@ -3945,14 +3906,6 @@ dependencies: eslint-visitor-keys "^1.1.0" -"@typescript-eslint/visitor-keys@4.22.1": - version "4.22.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.22.1.tgz#6045ae25a11662c671f90b3a403d682dfca0b7a6" - integrity sha512-WPkOrIRm+WCLZxXQHCi+WG8T2MMTUFR70rWjdWYddLT7cEfb2P4a3O/J2U1FBVsSFTocXLCoXWY6MZGejeStvQ== - dependencies: - "@typescript-eslint/types" "4.22.1" - eslint-visitor-keys "^2.0.0" - "@typescript-eslint/visitor-keys@4.23.0": version "4.23.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.23.0.tgz#7215cc977bd3b4ef22467b9023594e32f9e4e455" @@ -4707,7 +4660,7 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= -array.prototype.flat@^1.2.1, array.prototype.flat@^1.2.3, array.prototype.flat@^1.2.4: +array.prototype.flat@^1.2.1, array.prototype.flat@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz#6ef638b43312bd401b4c6199fdec7e2dc9e9a123" integrity sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg== @@ -6969,11 +6922,6 @@ constants-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= -contains-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" - integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= - contains-path@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-1.0.0.tgz#3458b332185603e8eed18f518d4a10888a3abc91" @@ -7995,14 +7943,6 @@ dns-txt@^2.0.2: dependencies: buffer-indexof "^1.0.0" -doctrine@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" - integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" @@ -8513,7 +8453,7 @@ errno@^0.1.3, errno@~0.1.1, errno@~0.1.7: dependencies: prr "~1.0.1" -error-ex@^1.2.0, error-ex@^1.3.1: +error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== @@ -8702,7 +8642,7 @@ eslint-import-resolver-node@^0.3.4: debug "^2.6.9" resolve "^1.13.1" -eslint-module-utils@^2.6.0, eslint-module-utils@^2.6.1: +eslint-module-utils@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz#b51be1e473dd0de1c5ea638e22429c2490ea8233" integrity sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A== @@ -13205,16 +13145,6 @@ listr2@^3.2.2: through "^2.3.8" wrap-ansi "^7.0.0" -load-json-file@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - strip-bom "^3.0.0" - load-json-file@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" @@ -14630,7 +14560,7 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" -object.values@^1.1.0, object.values@^1.1.1, object.values@^1.1.3: +object.values@^1.1.0, object.values@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.3.tgz#eaa8b1e17589f02f698db093f7c62ee1699742ee" integrity sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw== @@ -14986,13 +14916,6 @@ parse-headers@^2.0.0: resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.3.tgz#5e8e7512383d140ba02f0c7aa9f49b4399c92515" integrity sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA== -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - parse-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" @@ -15156,13 +15079,6 @@ path-to-regexp@^1.7.0: dependencies: isarray "0.0.1" -path-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= - dependencies: - pify "^2.0.0" - path-type@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" @@ -17101,14 +17017,6 @@ read-config-file@6.0.0: json5 "^2.1.2" lazy-val "^1.0.4" -read-pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= - dependencies: - find-up "^2.0.0" - read-pkg "^2.0.0" - read-pkg-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" @@ -17126,15 +17034,6 @@ read-pkg-up@^7.0.1: read-pkg "^5.2.0" type-fest "^0.8.1" -read-pkg@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= - dependencies: - load-json-file "^2.0.0" - normalize-package-data "^2.3.2" - path-type "^2.0.0" - read-pkg@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" @@ -17839,7 +17738,7 @@ rustbn.js@~0.2.0: resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== -rxjs@6, rxjs@^6.1.0, rxjs@^6.4.0, rxjs@^6.6.0, rxjs@^6.6.3, rxjs@^6.6.7: +rxjs@6, rxjs@^6.1.0, rxjs@^6.4.0, rxjs@^6.6.0, rxjs@^6.6.3: version "6.6.7" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== @@ -18089,6 +17988,11 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== +semver@7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.1.1.tgz#29104598a197d6cbe4733eeecbe968f7b43a9667" + integrity sha512-WfuG+fl6eh3eZ2qAf6goB7nhiCd7NPXhmyFxigB/TOkQyeLP8w8GsVehvtGNtnNmyboz4TgeK40B1Kbql/8c5A== + semver@7.3.2: version "7.3.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" @@ -20651,7 +20555,7 @@ web3-core@1.2.9: web3-core-requestmanager "1.2.9" web3-utils "1.2.9" -web3-core@1.3.4, web3-core@^1.2.11, web3-core@^1.3.0: +web3-core@1.3.4, web3-core@^1.2.11: version "1.3.4" resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.3.4.tgz#2cc7ba7f35cc167f7a0a46fd5855f86e51d34ce8" integrity sha512-7OJu46RpCEfTerl+gPvHXANR2RkLqAfW7l2DAvQ7wN0pnCzl9nEfdgW6tMhr31k3TR2fWucwKzCyyxMGzMHeSA== From 15d3cb8ff4ba01ef33c67751fbf7059e4c16ae2d Mon Sep 17 00:00:00 2001 From: nicolas Date: Thu, 27 May 2021 06:34:24 -0300 Subject: [PATCH 04/10] Tx decoded data, fix addresses array (#2309) --- .../Transactions/TxList/MethodValue.tsx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/routes/safe/components/Transactions/TxList/MethodValue.tsx b/src/routes/safe/components/Transactions/TxList/MethodValue.tsx index a33e6647..840b7899 100644 --- a/src/routes/safe/components/Transactions/TxList/MethodValue.tsx +++ b/src/routes/safe/components/Transactions/TxList/MethodValue.tsx @@ -49,8 +49,23 @@ const GenericValue = ({ method, type, value }: RenderValueProps): React.ReactEle } const Value = ({ type, ...props }: RenderValueProps): React.ReactElement => { - const explorerUrl = getExplorerInfo(props.value as string) + if (isArrayParameter(type) && isAddress(type)) { + return ( +
+ [ + + {(props.value as string[]).map((address) => { + const explorerUrl = getExplorerInfo(address) + return + })} + + ] +
+ ) + } + if (isAddress(type)) { + const explorerUrl = getExplorerInfo(props.value as string) return ( ) From 2fdc5e05a94180b34903f73e70986455a65c0e39 Mon Sep 17 00:00:00 2001 From: katspaugh Date: Fri, 28 May 2021 11:28:31 +0200 Subject: [PATCH 05/10] Add an API key in the ETHGasStation URL (#2332) * Add an API key in the ETHGasStation URL * Fix typo * Revert mainnet api key * Add the env var in github actions * Revert "Fix typo" This reverts commit c9b463099d9b38d481d21f42b4cedb8eafb0b83c. --- .env.example | 1 + .github/workflows/deploy-rinkeby.yml | 1 + src/config/networks/mainnet.ts | 1 + src/config/networks/rinkeby.ts | 3 ++- src/utils/constants.ts | 1 + 5 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.env.example b/.env.example index ba240349..28c8161c 100644 --- a/.env.example +++ b/.env.example @@ -16,6 +16,7 @@ REACT_APP_FORTMATIC_KEY= REACT_APP_OPENSEA_API_KEY= REACT_APP_COLLECTIBLES_SOURCE= REACT_APP_ETHERSCAN_API_KEY= +REACT_APP_ETHGASSTATION_API_KEY= # Versions REACT_APP_LATEST_SAFE_VERSION= diff --git a/.github/workflows/deploy-rinkeby.yml b/.github/workflows/deploy-rinkeby.yml index 4d35a09a..aebd3849 100644 --- a/.github/workflows/deploy-rinkeby.yml +++ b/.github/workflows/deploy-rinkeby.yml @@ -21,6 +21,7 @@ env: REACT_APP_SENTRY_DSN: ${{ secrets.SENTRY_DSN_RINKEBY }} REACT_APP_GOOGLE_ANALYTICS: ${{ secrets.REACT_APP_GOOGLE_ANALYTICS_ID_RINKEBY }} REACT_APP_GNOSIS_APPS_URL: ${{ secrets.REACT_APP_GNOSIS_APPS_URL_PROD }} + REACT_APP_ETHGASSTATION_API_KEY: ${{ secrets.REACT_APP_ETHGASSTATION_API_KEY_RINKEBY }} jobs: debug: diff --git a/src/config/networks/mainnet.ts b/src/config/networks/mainnet.ts index b4333c05..2c404a89 100644 --- a/src/config/networks/mainnet.ts +++ b/src/config/networks/mainnet.ts @@ -1,5 +1,6 @@ import EtherLogo from 'src/config/assets/token_eth.svg' import { EnvironmentSettings, ETHEREUM_NETWORK, NetworkConfig } from 'src/config/networks/network.d' +import { ETHGASSTATION_API_KEY } from 'src/utils/constants' const baseConfig: EnvironmentSettings = { clientGatewayUrl: 'https://safe-client.mainnet.staging.gnosisdev.com/v1', diff --git a/src/config/networks/rinkeby.ts b/src/config/networks/rinkeby.ts index f1ffcc7f..81cedee7 100644 --- a/src/config/networks/rinkeby.ts +++ b/src/config/networks/rinkeby.ts @@ -1,12 +1,13 @@ import EtherLogo from 'src/config/assets/token_eth.svg' import { EnvironmentSettings, ETHEREUM_NETWORK, NetworkConfig, WALLETS } from 'src/config/networks/network.d' +import { ETHGASSTATION_API_KEY } from 'src/utils/constants' const baseConfig: EnvironmentSettings = { clientGatewayUrl: 'https://safe-client.rinkeby.staging.gnosisdev.com/v1', txServiceUrl: 'https://safe-transaction.rinkeby.staging.gnosisdev.com/api/v1', safeAppsUrl: 'https://safe-apps.dev.gnosisdev.com', gasPriceOracle: { - url: 'https://ethgasstation.info/json/ethgasAPI.json', + url: `https://ethgasstation.info/json/ethgasAPI.json?api-key=${ETHGASSTATION_API_KEY}`, gasParameter: 'average', }, rpcServiceUrl: 'https://rinkeby.infura.io:443/v3', diff --git a/src/utils/constants.ts b/src/utils/constants.ts index cc889658..b595eda6 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -23,6 +23,7 @@ export const OPENSEA_API_KEY = process.env.REACT_APP_OPENSEA_API_KEY || '' export const COLLECTIBLES_SOURCE = process.env.REACT_APP_COLLECTIBLES_SOURCE || 'Gnosis' export const TIMEOUT = process.env.NODE_ENV === 'test' ? 1500 : 5000 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 EXCHANGE_RATE_URL = 'https://api.exchangeratesapi.io/latest' export const EXCHANGE_RATE_URL_FALLBACK = 'https://api.coinbase.com/v2/exchange-rates' export const SAFE_APPS_LIST_URL = From c1dd274ede3c30bcd2654505c9d7635af049a544 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 May 2021 18:04:41 +0200 Subject: [PATCH 06/10] Bump dns-packet from 1.3.1 to 1.3.4 (#2338) Bumps [dns-packet](https://github.com/mafintosh/dns-packet) from 1.3.1 to 1.3.4. - [Release notes](https://github.com/mafintosh/dns-packet/releases) - [Changelog](https://github.com/mafintosh/dns-packet/blob/master/CHANGELOG.md) - [Commits](https://github.com/mafintosh/dns-packet/compare/v1.3.1...v1.3.4) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 5afa3cf1..9b39e4c3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7929,9 +7929,9 @@ dns-equal@^1.0.0: integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= dns-packet@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" - integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg== + version "1.3.4" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f" + integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA== dependencies: ip "^1.1.0" safe-buffer "^5.0.1" From f1851d47a4d6e4147b6b6f9b8b93ba2f372fa723 Mon Sep 17 00:00:00 2001 From: Daniel Sanchez Date: Tue, 1 Jun 2021 10:28:44 +0200 Subject: [PATCH 07/10] Fix crash with Coinbase Wallet after upgrade to latest version (#2363) * Fix name changing in bnc-onboard Coinbase Wallet * Add comment in wallet provider list to explain the use --- .../WalletIcon/icons/icon-coinbase.svg | 35 +++---------------- .../components/WalletIcon/icons/index.ts | 2 +- src/logic/wallets/getWeb3.ts | 4 ++- 3 files changed, 8 insertions(+), 33 deletions(-) diff --git a/src/components/AppLayout/Header/components/WalletIcon/icons/icon-coinbase.svg b/src/components/AppLayout/Header/components/WalletIcon/icons/icon-coinbase.svg index 7c6cb2e2..04739158 100644 --- a/src/components/AppLayout/Header/components/WalletIcon/icons/icon-coinbase.svg +++ b/src/components/AppLayout/Header/components/WalletIcon/icons/icon-coinbase.svg @@ -1,31 +1,4 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + \ No newline at end of file diff --git a/src/components/AppLayout/Header/components/WalletIcon/icons/index.ts b/src/components/AppLayout/Header/components/WalletIcon/icons/index.ts index 71642f95..dfef4337 100644 --- a/src/components/AppLayout/Header/components/WalletIcon/icons/index.ts +++ b/src/components/AppLayout/Header/components/WalletIcon/icons/index.ts @@ -65,7 +65,7 @@ const WALLET_ICONS: WalletObjectsProps = { src: operaIcon, height: 25, }, - [WALLET_PROVIDER.WALLETLINK]: { + [WALLET_PROVIDER.COINBASE_WALLET]: { src: coinbaseIcon, height: 25, }, diff --git a/src/logic/wallets/getWeb3.ts b/src/logic/wallets/getWeb3.ts index ffd5f007..ab1e8a5b 100644 --- a/src/logic/wallets/getWeb3.ts +++ b/src/logic/wallets/getWeb3.ts @@ -9,6 +9,7 @@ import { getRpcServiceUrl } from 'src/config' import { isValidCryptoDomainName } from 'src/logic/wallets/ethAddresses' import { getAddressFromUnstoppableDomain } from './utils/unstoppableDomains' +// This providers have direct relation with name assigned in bnc-onboard configuration export const WALLET_PROVIDER = { SAFE: 'SAFE', METAMASK: 'METAMASK', @@ -19,7 +20,8 @@ export const WALLET_PROVIDER = { SQUARELINK: 'SQUARELINK', WALLETCONNECT: 'WALLETCONNECT', OPERA: 'OPERA', - WALLETLINK: 'WALLETLINK', + // This is the provider for WALLET_LINK configuration on bnc-onboard + COINBASE_WALLET: 'COINBASE WALLET', AUTHEREUM: 'AUTHEREUM', LEDGER: 'LEDGER', TREZOR: 'TREZOR', From 8c40f43730bbd64508593f92de1fbebd5f39c981 Mon Sep 17 00:00:00 2001 From: Daniel Sanchez Date: Tue, 1 Jun 2021 10:28:44 +0200 Subject: [PATCH 08/10] Fix crash with Coinbase Wallet after upgrade to latest version (#2363) * Fix name changing in bnc-onboard Coinbase Wallet * Add comment in wallet provider list to explain the use --- .../WalletIcon/icons/icon-coinbase.svg | 35 +++---------------- .../components/WalletIcon/icons/index.ts | 2 +- src/logic/wallets/getWeb3.ts | 4 ++- 3 files changed, 8 insertions(+), 33 deletions(-) diff --git a/src/components/AppLayout/Header/components/WalletIcon/icons/icon-coinbase.svg b/src/components/AppLayout/Header/components/WalletIcon/icons/icon-coinbase.svg index 7c6cb2e2..04739158 100644 --- a/src/components/AppLayout/Header/components/WalletIcon/icons/icon-coinbase.svg +++ b/src/components/AppLayout/Header/components/WalletIcon/icons/icon-coinbase.svg @@ -1,31 +1,4 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + \ No newline at end of file diff --git a/src/components/AppLayout/Header/components/WalletIcon/icons/index.ts b/src/components/AppLayout/Header/components/WalletIcon/icons/index.ts index 71642f95..dfef4337 100644 --- a/src/components/AppLayout/Header/components/WalletIcon/icons/index.ts +++ b/src/components/AppLayout/Header/components/WalletIcon/icons/index.ts @@ -65,7 +65,7 @@ const WALLET_ICONS: WalletObjectsProps = { src: operaIcon, height: 25, }, - [WALLET_PROVIDER.WALLETLINK]: { + [WALLET_PROVIDER.COINBASE_WALLET]: { src: coinbaseIcon, height: 25, }, diff --git a/src/logic/wallets/getWeb3.ts b/src/logic/wallets/getWeb3.ts index ffd5f007..ab1e8a5b 100644 --- a/src/logic/wallets/getWeb3.ts +++ b/src/logic/wallets/getWeb3.ts @@ -9,6 +9,7 @@ import { getRpcServiceUrl } from 'src/config' import { isValidCryptoDomainName } from 'src/logic/wallets/ethAddresses' import { getAddressFromUnstoppableDomain } from './utils/unstoppableDomains' +// This providers have direct relation with name assigned in bnc-onboard configuration export const WALLET_PROVIDER = { SAFE: 'SAFE', METAMASK: 'METAMASK', @@ -19,7 +20,8 @@ export const WALLET_PROVIDER = { SQUARELINK: 'SQUARELINK', WALLETCONNECT: 'WALLETCONNECT', OPERA: 'OPERA', - WALLETLINK: 'WALLETLINK', + // This is the provider for WALLET_LINK configuration on bnc-onboard + COINBASE_WALLET: 'COINBASE WALLET', AUTHEREUM: 'AUTHEREUM', LEDGER: 'LEDGER', TREZOR: 'TREZOR', From 6bc73b744ac0875c6111a0d3e064712d315918c3 Mon Sep 17 00:00:00 2001 From: Daniel Sanchez Date: Tue, 1 Jun 2021 10:29:56 +0200 Subject: [PATCH 09/10] Set v3.6.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 535a4531..6163a9eb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "safe-react", - "version": "3.6.5", + "version": "3.6.6", "description": "Allowing crypto users manage funds in a safer way", "website": "https://github.com/gnosis/safe-react#readme", "bugs": { From cc345946e66d1f32cd43490ad3895a4d590658f8 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Tue, 1 Jun 2021 14:10:57 +0400 Subject: [PATCH 10/10] Feature: Better error handling for Safe apps things (#2340) * handle request/app fetch errors * shorted extraMessage for app fetch error * use context instead of extra for safe app url exception when fetching * app -> safeApp for sentry context --- src/routes/safe/components/Apps/communicator.ts | 9 ++++++--- src/routes/safe/components/Apps/utils.ts | 8 +++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/routes/safe/components/Apps/communicator.ts b/src/routes/safe/components/Apps/communicator.ts index 95bd7a98..df31d8bb 100644 --- a/src/routes/safe/components/Apps/communicator.ts +++ b/src/routes/safe/components/Apps/communicator.ts @@ -69,9 +69,12 @@ class AppCommunicator { } } catch (err) { this.send(err.message, msg.data.id, true) - // TODO: Allow passing method/message as an extra context - // Tweak CodedException class to accept it as a second argument - logError(Errors._901, `${msg.data.method} ${err.message}`) + logError(Errors._901, err.message, { + contexts: { + safeApp: this.app, + request: msg.data, + }, + }) } } } diff --git a/src/routes/safe/components/Apps/utils.ts b/src/routes/safe/components/Apps/utils.ts index 506eabd1..feb0d6da 100644 --- a/src/routes/safe/components/Apps/utils.ts +++ b/src/routes/safe/components/Apps/utils.ts @@ -274,7 +274,13 @@ export const getAppInfoFromUrl = memoize( } return res } catch (error) { - logError(Errors._900, `${res.url}: ${error.message}`, undefined, false) + logError(Errors._900, error.message, { + contexts: { + safeApp: { + url: appUrl, + }, + }, + }) return res } },