new TXs tab (#1089)

* new TXs tab

* Removes coverage folder from git

* Adds getAllTxServiceUriTo
Adds types on fetchTransactions

* Adds loadAllTransactions method

* Adds types for allTransactions

* Adds types to loadAllTransactions
Adds urlParams to fetchAllTransactions

* Adds transactionsNew store

* Fetch all transactions endpoint and updates newTransactions store

* Updates transactions types

* Adds newTransactionsHelpers.ts

* Remove white spaces

* Removes immutableJS usage in NewTransactionsState

* Renames getAllTxServiceUriTo to getNewTransactionsServiceUriFrom

* Renames reducer TRANSACTIONS_NEW to TRANSACTIONS

* Removes newTransactions from fetchTransactions.ts

* Adds useFetchNewTransactions hook
Adds uriParams as parameter for loadAllTransactions

* Updates default state

* Adds newTransactionsSelector
Updates newTxsTab behaviour

* Renames eTag to responseEtag

* Fix missing Map type Import in AppReduxState

* Remove generic types

* Adds offset and limit to the NewTransactionsState
Adds currentPageSelector
Adds getNewTransactionsState

* Moves addNewTransactions action to actions/TransactionsNew

* Implements setPreviousPage, setNextPage

* Adds safeNewTransactionsSelector
Adds newTransactionsCurrentPageSelector

* Implements basic pagination on tabs layout

* Remove offset and limit from ADD_NEW_TRANSACTIONS action
Fixs ADD_NEW_TRANSACTIONS reducer implementation

* Improves useFetchNewTransactions usage to avoid re renders

* Fix newTransactionsCurrentPageSelector page calculation

* Fixs newTransactionsCurrentPageSelector
Adds loader state on newTxsTab

* Implements etags by page

* Implements pagination restrictions

* Fix import

* Reduce any's usage

* Replaces JSX.Element with ReactElement

* Fixs types

* Moves all the pagination actions to pagination.ts

* Simplify loadAllTransactions return values

* Replaces limit 100 to 50

* Rename actions

* Fix types

* Add TODO

* Replaces count/transactionsCount to totalTransactionsAmount

* Renames getNewTransactionsServiceUriFrom to getAllTransactionsUriFrom
Add types

* Rename newTxs to Transactions

* Add types to CopyBtn

* Replaces /transactionsNew with /all-transactions

* Replace btn handlers usage

* Uses hash as key

* Replaces redux with params

* Types

* Improves enum types

* Replaces is with boolean

* Merge branch 'development' of https://github.com/gnosis/safe-react into transactions_new

# Conflicts:
#	src/store/index.ts

* Types

* Enums

* Remove tabsValue()

* Moves store from ui to logic folder

* Fix imports

* Add type for new transactions

* Add Gnosis CLA (#1188)

* replace newTransactions with allTransactions

* bring back src/store

* bring back src/store 2

* Fix match type usage

* Merge branch 'development' of https://github.com/gnosis/safe-react into transactions_new

# Conflicts:
#	src/logic/addressBook/store/selectors/index.ts
#	src/logic/safe/transactions/send.ts

* Fix key null warning

* Removes limit and offset from allTransactions State

* Simplify allTransactions state

* Renames transactionsNew folder to allTransactions

* v2.9.0

* bump node in travis to 12

* add overflow hidden to iframe container in safe apps

* Merge branch 'development' of https://github.com/gnosis/safe-react into transactions_new

# Conflicts:
#	src/logic/safe/store/actions/__tests__/utils.test.ts
#	src/logic/safe/store/actions/addSafeModules.ts
#	src/logic/safe/store/reducer/safe.ts
#	src/logic/safe/store/reducer/types/safe.d.ts
#	src/routes/safe/components/Apps/index.tsx
#	src/routes/safe/components/Layout/Tabs/index.tsx
#	src/routes/safe/components/Settings/Advanced/dataFetcher.ts
#	src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/index.tsx
#	src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/CustomDescription.tsx
#	src/routes/safe/container/hooks/useFetchTokens.tsx
#	src/routes/safe/container/hooks/useLoadSafe.tsx
#	src/routes/safe/store/reducer/types/safe.d.ts
#	src/routes/safe/store/reducer/types/safe.ts

* Fix offchain signing

* fix crash when opening a mocked transaction

* Add Balancer Pool and Exchange Apps.

* Feedback, absolute imports

* Types

* Refactor all transactions, adds totalTransactionsAmount on redux

* Absolute path

Co-authored-by: Agustin Pane <agustin.pane@gmail.com>
Co-authored-by: Mikhail Mikheev <mmvsha73@gmail.com>
Co-authored-by: Mati Dastugue <matias.dastugue@altoros.com>
This commit is contained in:
nicolas 2020-08-14 12:15:09 -03:00 committed by GitHub
parent 7a4773511c
commit 691ef98048
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
164 changed files with 865 additions and 377 deletions

View File

@ -30,13 +30,13 @@ const useStyles = makeStyles({
interface CopyBtnProps {
className?: string
content: string
increaseZindex?: boolean
increaseZIndex?: boolean
}
const CopyBtn = ({ className = '', content, increaseZindex = false }: CopyBtnProps): React.ReactElement => {
const CopyBtn = ({ className = '', content, increaseZIndex = false }: CopyBtnProps): React.ReactElement => {
const [clicked, setClicked] = useState(false)
const classes = useStyles()
const customClasses = increaseZindex ? { popper: classes.increasedPopperZindex } : {}
const customClasses = increaseZIndex ? { popper: classes.increasedPopperZindex } : {}
return (
<Tooltip

View File

@ -8,7 +8,7 @@ import { connect } from 'react-redux'
import { SidebarContext } from 'src/components/Sidebar'
import Col from 'src/components/layout/Col'
import Paragraph from 'src/components/layout/Paragraph'
import { safesCountSelector } from 'src/routes/safe/store/selectors'
import { safesCountSelector } from 'src/logic/safe/store/selectors'
import { border, md, screenSm, sm, xs } from 'src/theme/variables'
import { AppReduxState } from 'src/store'

View File

@ -5,8 +5,8 @@ import React from 'react'
import { Provider } from 'react-redux'
import { ThemeProvider } from 'styled-components'
import Loader from '../Loader'
import PageFrame from '../layout/PageFrame'
import Loader from 'src/components/Loader'
import PageFrame from 'src/components/layout/PageFrame'
import AppRoutes from 'src/routes'
import { history, store } from 'src/store'
@ -16,7 +16,7 @@ import { wrapInSuspense } from 'src/utils/wrapInSuspense'
import './index.module.scss'
import './OnboardCustom.module.scss'
const Root = () => (
const Root = (): React.ReactElement => (
<ThemeProvider theme={styledTheme}>
<Provider store={store}>
<MuiThemeProvider theme={theme}>

View File

@ -5,9 +5,9 @@ import { EthHashInfo, Icon, Text, ButtonLink } from '@gnosis.pm/safe-react-compo
import * as React from 'react'
import styled from 'styled-components'
import { SafeRecord } from 'src/routes/safe/store/models/safe'
import { SafeRecord } from 'src/logic/safe/store/models/safe'
import { DefaultSafe } from 'src/routes/safe/store/reducer/types/safe'
import { SetDefaultSafe } from 'src/routes/safe/store/actions/setDefaultSafe'
import { SetDefaultSafe } from 'src/logic/safe/store/actions/setDefaultSafe'
import { getNetwork } from 'src/config'
import DefaultBadge from './DefaultBadge'
import Hairline from 'src/components/layout/Hairline'

View File

@ -15,9 +15,9 @@ import Hairline from 'src/components/layout/Hairline'
import Link from 'src/components/layout/Link'
import Row from 'src/components/layout/Row'
import { WELCOME_ADDRESS } from 'src/routes/routes'
import setDefaultSafe from 'src/routes/safe/store/actions/setDefaultSafe'
import setDefaultSafe from 'src/logic/safe/store/actions/setDefaultSafe'
import { defaultSafeSelector, safeParamAddressFromStateSelector } from 'src/routes/safe/store/selectors'
import { defaultSafeSelector, safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors'
import { AppReduxState } from 'src/store'
const { useEffect, useMemo, useState } = React

View File

@ -1,6 +1,6 @@
import { createSelector } from 'reselect'
import { safesListSelector } from 'src/routes/safe/store/selectors'
import { safesListSelector } from 'src/logic/safe/store/selectors'
export const sortedSafeListSelector = createSelector(safesListSelector, (safes) =>
safes.sort((a, b) => (a.name > b.name ? 1 : -1)),

View File

@ -59,6 +59,9 @@ export const getTxServiceUriFrom = (safeAddress) =>
export const getIncomingTxServiceUriTo = (safeAddress) =>
`safes/${safeAddress}/incoming-transfers/`
export const getAllTransactionsUriFrom = (safeAddress: string): string =>
`safes/${safeAddress}/all-transactions/`
export const getSafeCreationTxUri = (safeAddress) => `safes/${safeAddress}/creation/`
export const getRelayUrl = () => getConfig()[RELAY_API_URL]

View File

@ -5,8 +5,8 @@ import ReactDOM from 'react-dom'
import Root from 'src/components/Root'
import loadCurrentSessionFromStorage from 'src/logic/currentSession/store/actions/loadCurrentSessionFromStorage'
import loadActiveTokens from 'src/logic/tokens/store/actions/loadActiveTokens'
import loadDefaultSafe from 'src/routes/safe/store/actions/loadDefaultSafe'
import loadSafesFromStorage from 'src/routes/safe/store/actions/loadSafesFromStorage'
import loadDefaultSafe from 'src/logic/safe/store/actions/loadDefaultSafe'
import loadSafesFromStorage from 'src/logic/safe/store/actions/loadSafesFromStorage'
import { store } from 'src/store'
BigNumber.set({ EXPONENTIAL_AT: [-7, 255] })

View File

@ -3,7 +3,7 @@ import { List } from 'immutable'
import { loadAddressBook } from 'src/logic/addressBook/store/actions/loadAddressBook'
import { buildAddressBook } from 'src/logic/addressBook/store/reducer/addressBook'
import { getAddressBookFromStorage } from 'src/logic/addressBook/utils'
import { safesListSelector } from 'src/routes/safe/store/selectors'
import { safesListSelector } from 'src/logic/safe/store/selectors'
const loadAddressBookFromStorage = () => async (dispatch, getState) => {
try {

View File

@ -4,7 +4,7 @@ import { createSelector } from 'reselect'
import { ADDRESS_BOOK_REDUCER_ID } from 'src/logic/addressBook/store/reducer/addressBook'
import { AddressBookMap } from 'src/logic/addressBook/store/reducer/types/addressBook.d'
import { safeParamAddressFromStateSelector } from 'src/routes/safe/store/selectors'
import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors'
export const addressBookMapSelector = (state: AppReduxState): AddressBookMap =>
state[ADDRESS_BOOK_REDUCER_ID].get('addressBook')

View File

@ -1,7 +1,7 @@
import { List } from 'immutable'
import { loadFromStorage, saveToStorage } from 'src/utils/storage'
import { AddressBookEntryProps } from './../model/addressBook'
import { SafeOwner } from 'src/routes/safe/store/models/safe'
import { SafeOwner } from 'src/logic/safe/store/models/safe'
const ADDRESS_BOOK_STORAGE_KEY = 'ADDRESS_BOOK_STORAGE_KEY'

View File

@ -3,7 +3,7 @@ import { NFTAsset, NFTAssets, NFTTokens } from 'src/logic/collectibles/sources/O
import { AppReduxState } from 'src/store'
import { NFT_ASSETS_REDUCER_ID, NFT_TOKENS_REDUCER_ID } from 'src/logic/collectibles/store/reducer/collectibles'
import { safeActiveAssetsSelector } from 'src/routes/safe/store/selectors'
import { safeActiveAssetsSelector } from 'src/logic/safe/store/selectors'
export const nftAssetsSelector = (state: AppReduxState): NFTAssets => state[NFT_ASSETS_REDUCER_ID]
export const nftTokensSelector = (state: AppReduxState): NFTTokens => state[NFT_TOKENS_REDUCER_ID]

View File

@ -5,7 +5,7 @@ import {
CurrencyReducerMap,
CurrencyValuesState,
} from 'src/logic/currencyValues/store/reducer/currencyValues'
import { safeParamAddressFromStateSelector } from 'src/routes/safe/store/selectors'
import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors'
import { AppReduxState } from 'src/store'
import { CurrencyRateValue } from 'src/logic/currencyValues/store/model/currencyValues'
import { BigNumber } from 'bignumber.js'

View File

@ -1,6 +1,6 @@
import { getNewTxNonce, shouldExecuteTransaction } from 'src/routes/safe/store/actions/utils'
import { getNewTxNonce, shouldExecuteTransaction } from 'src/logic/safe/store/actions/utils'
import { GnosisSafe } from 'src/types/contracts/GnosisSafe.d'
import { TxServiceModel } from 'src/routes/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions'
import { TxServiceModel } from 'src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions'
describe('Store actions utils > getNewTxNonce', () => {
it(`Should return passed predicted transaction nonce if it's a valid value`, async () => {

View File

@ -1,10 +1,10 @@
import { List } from 'immutable'
import { createAction } from 'redux-actions'
import setDefaultSafe from 'src/routes/safe/store/actions/setDefaultSafe'
import { makeOwner } from 'src/routes/safe/store/models/owner'
import setDefaultSafe from 'src/logic/safe/store/actions/setDefaultSafe'
import { makeOwner } from 'src/logic/safe/store/models/owner'
import { safesListSelector } from 'src/routes/safe/store/selectors'
import { safesListSelector } from 'src/logic/safe/store/selectors'
export const ADD_SAFE = 'ADD_SAFE'

View File

@ -0,0 +1,89 @@
import axios, { AxiosResponse } from 'axios'
import { getAllTransactionsUriFrom, getTxServiceHost } from 'src/config'
import { checksumAddress } from 'src/utils/checksumAddress'
import { Transaction } from '../../models/types/transactions'
export type ServiceUriParams = {
safeAddress: string
limit: number
offset: number
orderBy?: string // todo: maybe this should be key of MultiSigTransaction | keyof EthereumTransaction
queued?: boolean
trusted?: boolean
}
type TransactionDTO = {
count: number
next?: string
previous?: string
results: Transaction[]
}
const getAllTransactionsUri = (safeAddress: string): string => {
const host = getTxServiceHost()
const address = checksumAddress(safeAddress)
const base = getAllTransactionsUriFrom(address)
return `${host}${base}`
}
const fetchAllTransactions = async (
urlParams: ServiceUriParams,
eTag: string | null,
): Promise<{ responseEtag: string; results: Transaction[]; count?: number }> => {
const { safeAddress, limit, offset, orderBy, queued, trusted } = urlParams
try {
const url = getAllTransactionsUri(safeAddress)
const config = {
params: {
limit,
offset,
orderBy,
queued,
trusted,
},
headers: eTag ? { 'If-None-Match': eTag } : undefined,
}
const response: AxiosResponse<TransactionDTO> = await axios.get(url, config)
if (response.data.count > 0) {
const { etag } = response.headers
if (eTag !== etag) {
return {
responseEtag: etag,
results: response.data.results,
count: response.data.count,
}
}
}
} catch (err) {
if (!(err && err.response && err.response.status === 304)) {
console.error(`Requests for outgoing transactions for ${safeAddress || 'unknown'} failed with 404`, err)
} else {
// NOTE: this is the expected implementation, currently the backend is not returning 304.
// So I check if the returned etag is the same instead (see above)
}
}
return { responseEtag: eTag, results: [] }
}
const etagsByPage = {}
export const loadAllTransactions = async (
uriParams: ServiceUriParams,
): Promise<{
transactions: Transaction[]
totalTransactionsAmount?: number
}> => {
const previousEtag = etagsByPage && etagsByPage[uriParams.offset]
const { responseEtag, results, count } = await fetchAllTransactions(uriParams, previousEtag)
etagsByPage[uriParams.offset] = responseEtag
return {
transactions: results,
totalTransactionsAmount: count,
}
}

View File

@ -0,0 +1,14 @@
import { createAction } from 'redux-actions'
import { Transaction } from '../../models/types/transactions'
export const LOAD_MORE_TRANSACTIONS = 'LOAD_MORE_TRANSACTIONS'
export type LoadMoreTransactionsAction = {
payload: {
safeAddress: string
transactions: Transaction[]
totalTransactionsAmount: number
}
}
export const loadMore = createAction(LOAD_MORE_TRANSACTIONS)

View File

@ -22,21 +22,21 @@ import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses'
import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions'
import { providerSelector } from 'src/logic/wallets/store/selectors'
import { SAFELIST_ADDRESS } from 'src/routes/routes'
import { addOrUpdateCancellationTransactions } from 'src/routes/safe/store/actions/transactions/addOrUpdateCancellationTransactions'
import { addOrUpdateTransactions } from 'src/routes/safe/store/actions/transactions/addOrUpdateTransactions'
import { removeCancellationTransaction } from 'src/routes/safe/store/actions/transactions/removeCancellationTransaction'
import { removeTransaction } from 'src/routes/safe/store/actions/transactions/removeTransaction'
import { addOrUpdateCancellationTransactions } from 'src/logic/safe/store/actions/transactions/addOrUpdateCancellationTransactions'
import { addOrUpdateTransactions } from 'src/logic/safe/store/actions/transactions/addOrUpdateTransactions'
import { removeCancellationTransaction } from 'src/logic/safe/store/actions/transactions/removeCancellationTransaction'
import { removeTransaction } from 'src/logic/safe/store/actions/transactions/removeTransaction'
import {
generateSafeTxHash,
mockTransaction,
TxToMock,
} from 'src/routes/safe/store/actions/transactions/utils/transactionHelpers'
import { getLastTx, getNewTxNonce, shouldExecuteTransaction } from 'src/routes/safe/store/actions/utils'
} from 'src/logic/safe/store/actions/transactions/utils/transactionHelpers'
import { getLastTx, getNewTxNonce, shouldExecuteTransaction } from 'src/logic/safe/store/actions/utils'
import { getErrorMessage } from 'src/test/utils/ethereumErrors'
import { makeConfirmation } from '../models/confirmation'
import fetchTransactions from './transactions/fetchTransactions'
import { safeTransactionsSelector } from 'src/routes/safe/store/selectors'
import { Transaction, TransactionStatus, TxArgs } from 'src/routes/safe/store/models/types/transaction'
import { safeTransactionsSelector } from 'src/logic/safe/store/selectors'
import { Transaction, TransactionStatus, TxArgs } from 'src/logic/safe/store/models/types/transaction'
import { AnyAction } from 'redux'
import { PayableTx } from 'src/types/contracts/types.d'
import { AppReduxState } from 'src/store'

View File

@ -1,6 +1,6 @@
import { getBalanceInEtherOf } from 'src/logic/wallets/getWeb3'
import updateSafe from 'src/routes/safe/store/actions/updateSafe'
import { SAFE_REDUCER_ID } from 'src/routes/safe/store/reducer/safe'
import updateSafe from 'src/logic/safe/store/actions/updateSafe'
import { SAFE_REDUCER_ID } from 'src/logic/safe/store/reducer/safe'
import { Dispatch } from 'redux'
import { backOff } from 'exponential-backoff'
import { AppReduxState } from 'src/store'

View File

@ -1,5 +1,5 @@
import { getCurrentMasterContractLastVersion } from 'src/logic/safe/utils/safeVersion'
import setLatestMasterContractVersion from 'src/routes/safe/store/actions/setLatestMasterContractVersion'
import setLatestMasterContractVersion from 'src/logic/safe/store/actions/setLatestMasterContractVersion'
const fetchLatestMasterContractVersion = () => async (dispatch) => {
const latestVersion = await getCurrentMasterContractLastVersion()

View File

@ -6,14 +6,14 @@ import { getLocalSafe, getSafeName } from 'src/logic/safe/utils'
import { enabledFeatures, safeNeedsUpdate } from 'src/logic/safe/utils/safeVersion'
import { sameAddress } from 'src/logic/wallets/ethAddresses'
import { getBalanceInEtherOf } from 'src/logic/wallets/getWeb3'
import addSafe from 'src/routes/safe/store/actions/addSafe'
import addSafeOwner from 'src/routes/safe/store/actions/addSafeOwner'
import removeSafeOwner from 'src/routes/safe/store/actions/removeSafeOwner'
import updateSafe from 'src/routes/safe/store/actions/updateSafe'
import { makeOwner } from 'src/routes/safe/store/models/owner'
import addSafe from 'src/logic/safe/store/actions/addSafe'
import addSafeOwner from 'src/logic/safe/store/actions/addSafeOwner'
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 } from 'src/routes/safe/store/models/safe'
import { ModulePair, SafeOwner } from 'src/logic/safe/store/models/safe'
import { Dispatch } from 'redux'
import { SENTINEL_ADDRESS } from 'src/logic/contracts/safeContracts'

View File

@ -3,8 +3,8 @@ import { List } from 'immutable'
import { buildSafeCreationTxUrl } from 'src/config'
import { addOrUpdateTransactions } from './transactions/addOrUpdateTransactions'
import { makeTransaction } from 'src/routes/safe/store/models/transaction'
import { TransactionTypes, TransactionStatus } from 'src/routes/safe/store/models/types/transaction'
import { makeTransaction } from 'src/logic/safe/store/models/transaction'
import { TransactionTypes, TransactionStatus } from 'src/logic/safe/store/models/types/transaction'
import { web3ReadOnly } from 'src/logic/wallets/getWeb3'
const getCreationTx = async (safeAddress) => {

View File

@ -2,7 +2,7 @@ import { addSafe } from './addSafe'
import { SAFES_KEY } from 'src/logic/safe/utils'
import { buildSafe } from 'src/routes/safe/store/reducer/safe'
import { buildSafe } from 'src/logic/safe/store/reducer/safe'
import { loadFromStorage } from 'src/utils/storage'

View File

@ -8,14 +8,14 @@ import { getApprovalTransaction, getExecutionTransaction, saveTxToHistory } from
import { SAFE_VERSION_FOR_OFFCHAIN_SIGNATURES, tryOffchainSigning } from 'src/logic/safe/transactions/offchainSigner'
import { getCurrentSafeVersion } from 'src/logic/safe/utils/safeVersion'
import { providerSelector } from 'src/logic/wallets/store/selectors'
import fetchSafe from 'src/routes/safe/store/actions/fetchSafe'
import fetchTransactions from 'src/routes/safe/store/actions/transactions/fetchTransactions'
import fetchSafe from 'src/logic/safe/store/actions/fetchSafe'
import fetchTransactions from 'src/logic/safe/store/actions/transactions/fetchTransactions'
import {
isCancelTransaction,
mockTransaction,
TxToMock,
} from 'src/routes/safe/store/actions/transactions/utils/transactionHelpers'
import { getLastTx, getNewTxNonce, shouldExecuteTransaction } from 'src/routes/safe/store/actions/utils'
} from 'src/logic/safe/store/actions/transactions/utils/transactionHelpers'
import { getLastTx, getNewTxNonce, shouldExecuteTransaction } from 'src/logic/safe/store/actions/utils'
import { getErrorMessage } from 'src/test/utils/ethereumErrors'
import { makeConfirmation } from '../models/confirmation'

View File

@ -2,9 +2,9 @@ import axios from 'axios'
import { buildTxServiceUrl } from 'src/logic/safe/transactions'
import { buildIncomingTxServiceUrl } from 'src/logic/safe/transactions/incomingTxHistory'
import { TxServiceModel } from 'src/routes/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions'
import { IncomingTxServiceModel } from 'src/routes/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions'
import { TransactionTypes } from 'src/routes/safe/store/models/types/transaction'
import { TxServiceModel } from 'src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions'
import { IncomingTxServiceModel } from 'src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions'
import { TransactionTypes } from 'src/logic/safe/store/models/types/transaction'
const getServiceUrl = (txType: string, safeAddress: string): string => {
return {

View File

@ -8,8 +8,8 @@ import { addIncomingTransactions } from '../../addIncomingTransactions'
import { loadIncomingTransactions } from './loadIncomingTransactions'
import { loadOutgoingTransactions } from './loadOutgoingTransactions'
import { addOrUpdateCancellationTransactions } from 'src/routes/safe/store/actions/transactions/addOrUpdateCancellationTransactions'
import { addOrUpdateTransactions } from 'src/routes/safe/store/actions/transactions/addOrUpdateTransactions'
import { addOrUpdateCancellationTransactions } from 'src/logic/safe/store/actions/transactions/addOrUpdateCancellationTransactions'
import { addOrUpdateTransactions } from 'src/logic/safe/store/actions/transactions/addOrUpdateTransactions'
import { AppReduxState } from 'src/store'
const noFunc = () => {}

View File

@ -4,9 +4,9 @@ import { List, Map } from 'immutable'
import generateBatchRequests from 'src/logic/contracts/generateBatchRequests'
import { ALTERNATIVE_TOKEN_ABI } from 'src/logic/tokens/utils/alternativeAbi'
import { web3ReadOnly } from 'src/logic/wallets/getWeb3'
import { makeIncomingTransaction } from 'src/routes/safe/store/models/incomingTransaction'
import fetchTransactions from 'src/routes/safe/store/actions/transactions/fetchTransactions/fetchTransactions'
import { TransactionTypes } from 'src/routes/safe/store/models/types/transaction'
import { makeIncomingTransaction } from 'src/logic/safe/store/models/incomingTransaction'
import fetchTransactions from 'src/logic/safe/store/actions/transactions/fetchTransactions/fetchTransactions'
import { TransactionTypes } from 'src/logic/safe/store/models/types/transaction'
export type IncomingTxServiceModel = {
blockNumber: number

View File

@ -4,14 +4,14 @@ import generateBatchRequests from 'src/logic/contracts/generateBatchRequests'
import { TOKEN_REDUCER_ID } from 'src/logic/tokens/store/reducer/tokens'
import { web3ReadOnly } from 'src/logic/wallets/getWeb3'
import { PROVIDER_REDUCER_ID } from 'src/logic/wallets/store/reducer/provider'
import { buildTx, isCancelTransaction } from 'src/routes/safe/store/actions/transactions/utils/transactionHelpers'
import { SAFE_REDUCER_ID } from 'src/routes/safe/store/reducer/safe'
import { buildTx, isCancelTransaction } from 'src/logic/safe/store/actions/transactions/utils/transactionHelpers'
import { SAFE_REDUCER_ID } from 'src/logic/safe/store/reducer/safe'
import { store } from 'src/store'
import fetchTransactions from 'src/routes/safe/store/actions/transactions/fetchTransactions/fetchTransactions'
import { Transaction, TransactionTypes } from 'src/routes/safe/store/models/types/transaction'
import fetchTransactions from 'src/logic/safe/store/actions/transactions/fetchTransactions/fetchTransactions'
import { Transaction, TransactionTypes } from 'src/logic/safe/store/models/types/transaction'
import { Token } from 'src/logic/tokens/store/model/token'
import { SafeRecord } from 'src/routes/safe/store/models/safe'
import { DataDecoded } from 'src/routes/safe/store/models/types/transactions.d'
import { SafeRecord } from 'src/logic/safe/store/models/safe'
import { DataDecoded } from 'src/logic/safe/store/models/types/transactions.d'
export type ConfirmationServiceModel = {
confirmationType: string

View File

@ -0,0 +1,11 @@
import { Transaction, TxType } from 'src/logic/safe/store/models/types/transactions'
export const isMultiSigTx = (tx: Transaction): boolean => {
return TxType[tx.txType] === TxType.MULTISIG_TRANSACTION
}
export const isModuleTx = (tx: Transaction): boolean => {
return TxType[tx.txType] === TxType.MODULE_TRANSACTION
}
export const isEthereumTx = (tx: Transaction): boolean => {
return TxType[tx.txType] === TxType.ETHEREUM_TRANSACTION
}

View File

@ -9,9 +9,9 @@ import {
} from 'src/logic/tokens/utils/tokenHelpers'
import { sameAddress, ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses'
import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions'
import { makeConfirmation } from 'src/routes/safe/store/models/confirmation'
import { Confirmation } from 'src/routes/safe/store/models/types/confirmation'
import { makeTransaction } from 'src/routes/safe/store/models/transaction'
import { makeConfirmation } from 'src/logic/safe/store/models/confirmation'
import { Confirmation } from 'src/logic/safe/store/models/types/confirmation'
import { makeTransaction } from 'src/logic/safe/store/models/transaction'
import {
Transaction,
TransactionStatus,
@ -19,21 +19,21 @@ import {
TransactionTypes,
TransactionTypeValues,
TxArgs,
} from 'src/routes/safe/store/models/types/transaction'
import { CANCELLATION_TRANSACTIONS_REDUCER_ID } from 'src/routes/safe/store/reducer/cancellationTransactions'
import { SAFE_REDUCER_ID } from 'src/routes/safe/store/reducer/safe'
import { TRANSACTIONS_REDUCER_ID } from 'src/routes/safe/store/reducer/transactions'
} from 'src/logic/safe/store/models/types/transaction'
import { CANCELLATION_TRANSACTIONS_REDUCER_ID } from 'src/logic/safe/store/reducer/cancellationTransactions'
import { SAFE_REDUCER_ID } from 'src/logic/safe/store/reducer/safe'
import { TRANSACTIONS_REDUCER_ID } from 'src/logic/safe/store/reducer/transactions'
import { AppReduxState, store } from 'src/store'
import { safeSelector, safeTransactionsSelector } from 'src/routes/safe/store/selectors'
import { addOrUpdateTransactions } from 'src/routes/safe/store/actions/transactions/addOrUpdateTransactions'
import { safeSelector, safeTransactionsSelector } from 'src/logic/safe/store/selectors'
import { addOrUpdateTransactions } from 'src/logic/safe/store/actions/transactions/addOrUpdateTransactions'
import {
BatchProcessTxsProps,
TxServiceModel,
} from 'src/routes/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions'
} from 'src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions'
import { TypedDataUtils } from 'eth-sig-util'
import { Token } from 'src/logic/tokens/store/model/token'
import { ProviderRecord } from 'src/logic/wallets/store/model/provider'
import { SafeRecord } from 'src/routes/safe/store/models/safe'
import { SafeRecord } from 'src/logic/safe/store/models/safe'
import { DecodedParams } from 'src/routes/safe/store/models/types/transactions.d'
export const isEmptyData = (data?: string | null): boolean => {

View File

@ -9,15 +9,15 @@ import { isUserAnOwner } from 'src/logic/wallets/ethAddresses'
import { userAccountSelector } from 'src/logic/wallets/store/selectors'
import { getIncomingTxAmount } from 'src/routes/safe/components/Transactions/TxsTable/columns'
import { grantedSelector } from 'src/routes/safe/container/selector'
import { ADD_INCOMING_TRANSACTIONS } from 'src/routes/safe/store/actions/addIncomingTransactions'
import { ADD_SAFE } from 'src/routes/safe/store/actions/addSafe'
import { ADD_OR_UPDATE_TRANSACTIONS } from 'src/routes/safe/store/actions/transactions/addOrUpdateTransactions'
import updateSafe from 'src/routes/safe/store/actions/updateSafe'
import { ADD_INCOMING_TRANSACTIONS } from 'src/logic/safe/store/actions/addIncomingTransactions'
import { ADD_SAFE } from 'src/logic/safe/store/actions/addSafe'
import { ADD_OR_UPDATE_TRANSACTIONS } from 'src/logic/safe/store/actions/transactions/addOrUpdateTransactions'
import updateSafe from 'src/logic/safe/store/actions/updateSafe'
import {
safeParamAddressFromStateSelector,
safesMapSelector,
safeCancellationTransactionsSelector,
} from 'src/routes/safe/store/selectors'
} from 'src/logic/safe/store/selectors'
import { loadFromStorage, saveToStorage } from 'src/utils/storage'

View File

@ -3,16 +3,16 @@ import { addAddressBookEntry } from 'src/logic/addressBook/store/actions/addAddr
import { saveDefaultSafe, saveSafes } from 'src/logic/safe/utils'
import { tokensSelector } from 'src/logic/tokens/store/selectors'
import { saveActiveTokens } from 'src/logic/tokens/utils/tokensStorage'
import { ACTIVATE_TOKEN_FOR_ALL_SAFES } from 'src/routes/safe/store/actions/activateTokenForAllSafes'
import { ADD_SAFE } from 'src/routes/safe/store/actions/addSafe'
import { ADD_SAFE_OWNER } from 'src/routes/safe/store/actions/addSafeOwner'
import { EDIT_SAFE_OWNER } from 'src/routes/safe/store/actions/editSafeOwner'
import { REMOVE_SAFE } from 'src/routes/safe/store/actions/removeSafe'
import { REMOVE_SAFE_OWNER } from 'src/routes/safe/store/actions/removeSafeOwner'
import { REPLACE_SAFE_OWNER } from 'src/routes/safe/store/actions/replaceSafeOwner'
import { SET_DEFAULT_SAFE } from 'src/routes/safe/store/actions/setDefaultSafe'
import { UPDATE_SAFE } from 'src/routes/safe/store/actions/updateSafe'
import { getActiveTokensAddressesForAllSafes, safesMapSelector } from 'src/routes/safe/store/selectors'
import { ACTIVATE_TOKEN_FOR_ALL_SAFES } from 'src/logic/safe/store/actions/activateTokenForAllSafes'
import { ADD_SAFE } from 'src/logic/safe/store/actions/addSafe'
import { ADD_SAFE_OWNER } from 'src/logic/safe/store/actions/addSafeOwner'
import { EDIT_SAFE_OWNER } from 'src/logic/safe/store/actions/editSafeOwner'
import { REMOVE_SAFE } from 'src/logic/safe/store/actions/removeSafe'
import { REMOVE_SAFE_OWNER } from 'src/logic/safe/store/actions/removeSafeOwner'
import { REPLACE_SAFE_OWNER } from 'src/logic/safe/store/actions/replaceSafeOwner'
import { SET_DEFAULT_SAFE } from 'src/logic/safe/store/actions/setDefaultSafe'
import { UPDATE_SAFE } from 'src/logic/safe/store/actions/updateSafe'
import { getActiveTokensAddressesForAllSafes, safesMapSelector } from 'src/logic/safe/store/selectors'
const watchedActions = [
ADD_SAFE,

View File

@ -6,7 +6,7 @@ import {
TransactionProps,
TransactionStatus,
TransactionTypes,
} from 'src/routes/safe/store/models/types/transaction'
} from 'src/logic/safe/store/models/types/transaction'
export const makeTransaction = Record<TransactionProps>({
baseGas: 0,

View File

@ -1,7 +1,8 @@
import { List, Map, RecordOf } from 'immutable'
import { Confirmation } from './confirmation'
import { GnosisSafe } from 'src/types/contracts/GnosisSafe.d'
import { DataDecoded, DecodedParams, Transfer } from './transactions'
import { DataDecoded, Transfer } from './transactions'
import { DecodedParams } from 'src/routes/safe/store/models/types/transactions'
export enum TransactionTypes {
INCOMING = 'incoming',

View File

@ -0,0 +1,254 @@
export enum TxConstants {
MULTI_SEND = 'multiSend',
UNKNOWN = 'UNKNOWN',
}
export enum Operation {
CALL = 'CALL',
DELEGATE_CALL = 'DELEGATE_CALL',
CREATE = 'CREATE',
}
// types comes from: https://github.com/gnosis/safe-client-gateway/blob/752e76b6d1d475791dbd7917b174bb41d2d9d8be/src/utils.rs
export enum TransferMethods {
TRANSFER = 'transfer',
TRANSFER_FROM = 'transferFrom',
SAFE_TRANSFER_FROM = 'safeTransferFrom',
}
export enum SettingsChangeMethods {
SETUP = 'setup',
SET_FALLBACK_HANDLER = 'setFallbackHandler',
ADD_OWNER_WITH_THRESHOLD = 'addOwnerWithThreshold',
REMOVE_OWNER = 'removeOwner',
REMOVE_OWNER_WITH_THRESHOLD = 'removeOwnerWithThreshold',
SWAP_OWNER = 'swapOwner',
CHANGE_THRESHOLD = 'changeThreshold',
CHANGE_MASTER_COPY = 'changeMasterCopy',
ENABLE_MODULE = 'enableModule',
DISABLE_MODULE = 'disableModule',
EXEC_TRANSACTION_FROM_MODULE = 'execTransactionFromModule',
APPROVE_HASH = 'approveHash',
EXEC_TRANSACTION = 'execTransaction',
}
// note: this extends SAFE_METHODS_NAMES in /logic/contracts/methodIds.ts, we need to figure out which one we are going to use
export type DataDecodedMethod = TransferMethods | SettingsChangeMethods | string
export interface DecodedValue {
operation: Operation
to: string
value: number
data: string
decodedData: DataDecoded
}
export interface SingleTransactionMethodParameter {
name: string
type: string
value: string
}
export interface MultiSendMethodParameter extends SingleTransactionMethodParameter {
decodedValue: DecodedValue[]
}
export type Parameter = MultiSendMethodParameter | SingleTransactionMethodParameter
export interface DataDecoded {
method: DataDecodedMethod
parameters: Parameter[]
}
export enum ConfirmationType {
CONFIRMATION = 'CONFIRMATION',
EXECUTION = 'EXECUTION',
}
export enum SignatureType {
CONTRACT_SIGNATURE = 'CONTRACT_SIGNATURE',
APPROVED_HASH = 'APPROVED_HASH',
EOA = 'EOA',
ETH_SIGN = 'ETH_SIGN',
}
export interface Confirmation {
owner: string
submissionDate: string
transactionHash: string | null
confirmationType: ConfirmationType
signature: string
signatureType: SignatureType
}
export enum TokenType {
ERC20 = 'ERC20',
ERC721 = 'ERC721',
OTHER = 'OTHER',
}
export interface TokenInfo {
type: TokenType
address: string
name: string
symbol: string
decimals: number
logoUri: string
}
export enum TransferType {
ETHER_TRANSFER = 'ETHER_TRANSFER',
ERC20_TRANSFER = 'ERC20_TRANSFER',
ERC721_TRANSFER = 'ERC721_TRANSFER',
UNKNOWN = 'UNKNOWN',
}
export interface Transfer {
type: TransferType
executionDate: string
blockNumber: number
transactionHash: string | null
to: string
value: string | null
tokenId: string | null
tokenAddress: string
tokenInfo: TokenInfo | null
from: string
}
export enum TxType {
MULTISIG_TRANSACTION = 'MULTISIG_TRANSACTION',
ETHEREUM_TRANSACTION = 'ETHEREUM_TRANSACTION',
MODULE_TRANSACTION = 'MODULE_TRANSACTION',
}
export interface MultiSigTransaction {
safe: string
to: string
value: string
data: string | null
operation: number
gasToken: string
safeTxGas: number
baseGas: number
gasPrice: string
refundReceiver: string
nonce: number
executionDate: string | null
submissionDate: string
modified: string
blockNumber: number | null
transactionHash: string | null
safeTxHash: string
executor: string | null
isExecuted: boolean
isSuccessful: boolean | null
ethGasPrice: string | null
gasUsed: number | null
fee: string | null
origin: string | null
dataDecoded: DataDecoded | null
confirmationsRequired: number | null
confirmations: Confirmation[]
signatures: string | null
transfers: Transfer[]
txType: TxType.MULTISIG_TRANSACTION
}
export interface ModuleTransaction {
created: string
executionDate: string
blockNumber: number
transactionHash: string
safe: string
module: string
to: string
value: string
data: string
operation: Operation
transfers: Transfer[]
txType: TxType.MODULE_TRANSACTION
}
export interface EthereumTransaction {
executionDate: string
to: string
data: string | null
txHash: string
blockNumber: number
transfers: Transfer[]
txType: TxType.ETHEREUM_TRANSACTION
from: string
}
export type Transaction = MultiSigTransaction | ModuleTransaction | EthereumTransaction
// SAFE METHODS TO ITS ID
// https://github.com/gnosis/safe-contracts/blob/development/test/safeMethodNaming.js
// https://github.com/gnosis/safe-contracts/blob/development/contracts/GnosisSafe.sol
// [
// { name: "addOwnerWithThreshold", id: "0x0d582f13" },
// { name: "DOMAIN_SEPARATOR_TYPEHASH", id: "0x1db61b54" },
// { name: "isOwner", id: "0x2f54bf6e" },
// { name: "execTransactionFromModule", id: "0x468721a7" },
// { name: "signedMessages", id: "0x5ae6bd37" },
// { name: "enableModule", id: "0x610b5925" },
// { name: "changeThreshold", id: "0x694e80c3" },
// { name: "approvedHashes", id: "0x7d832974" },
// { name: "changeMasterCopy", id: "0x7de7edef" },
// { name: "SENTINEL_MODULES", id: "0x85e332cd" },
// { name: "SENTINEL_OWNERS", id: "0x8cff6355" },
// { name: "getOwners", id: "0xa0e67e2b" },
// { name: "NAME", id: "0xa3f4df7e" },
// { name: "nonce", id: "0xaffed0e0" },
// { name: "getModules", id: "0xb2494df3" },
// { name: "SAFE_MSG_TYPEHASH", id: "0xc0856ffc" },
// { name: "SAFE_TX_TYPEHASH", id: "0xccafc387" },
// { name: "disableModule", id: "0xe009cfde" },
// { name: "swapOwner", id: "0xe318b52b" },
// { name: "getThreshold", id: "0xe75235b8" },
// { name: "domainSeparator", id: "0xf698da25" },
// { name: "removeOwner", id: "0xf8dc5dd9" },
// { name: "VERSION", id: "0xffa1ad74" },
// { name: "setup", id: "0xa97ab18a" },
// { name: "execTransaction", id: "0x6a761202" },
// { name: "requiredTxGas", id: "0xc4ca3a9c" },
// { name: "approveHash", id: "0xd4d9bdcd" },
// { name: "signMessage", id: "0x85a5affe" },
// { name: "isValidSignature", id: "0x20c13b0b" },
// { name: "getMessageHash", id: "0x0a1028c4" },
// { name: "encodeTransactionData", id: "0xe86637db" },
// { name: "getTransactionHash", id: "0xd8d11f78" }
// ]
export const SAFE_METHODS_NAMES = {
ADD_OWNER_WITH_THRESHOLD: 'addOwnerWithThreshold',
CHANGE_THRESHOLD: 'changeThreshold',
REMOVE_OWNER: 'removeOwner',
SWAP_OWNER: 'swapOwner',
ENABLE_MODULE: 'enableModule',
DISABLE_MODULE: 'disableModule',
}
export const METHOD_TO_ID = {
'0xe318b52b': SAFE_METHODS_NAMES.SWAP_OWNER,
'0x0d582f13': SAFE_METHODS_NAMES.ADD_OWNER_WITH_THRESHOLD,
'0xf8dc5dd9': SAFE_METHODS_NAMES.REMOVE_OWNER,
'0x694e80c3': SAFE_METHODS_NAMES.CHANGE_THRESHOLD,
'0x610b5925': SAFE_METHODS_NAMES.ENABLE_MODULE,
'0xe009cfde': SAFE_METHODS_NAMES.DISABLE_MODULE,
}
export type SafeMethods = typeof SAFE_METHODS_NAMES[keyof typeof SAFE_METHODS_NAMES]
type TokenMethods = 'transfer' | 'transferFrom' | 'safeTransferFrom'
type SafeDecodedParams = {
[key in SafeMethods]?: Record<string, string>
}
type TokenDecodedParams = {
[key in TokenMethods]?: Record<string, string>
}
export type DecodedParams = SafeDecodedParams | TokenDecodedParams | null

View File

@ -0,0 +1,34 @@
import { handleActions } from 'redux-actions'
import { Transaction } from '../models/types/transactions'
import { LOAD_MORE_TRANSACTIONS, LoadMoreTransactionsAction } from '../actions/allTransactions/pagination'
export const TRANSACTIONS = 'allTransactions'
export interface TransactionsState {
[safeAddress: string]: {
totalTransactionsCount: number
transactions: Transaction[]
}
}
export default handleActions(
{
// todo: because we are thinking in remove immutableJS, I will implement this without it so it can be easier removed in future
[LOAD_MORE_TRANSACTIONS]: (state: TransactionsState, action: LoadMoreTransactionsAction) => {
const { safeAddress, transactions, totalTransactionsAmount } = action.payload
const oldState = state[safeAddress]
return {
...state,
[safeAddress]: {
...oldState,
transactions: [...(oldState?.transactions || []), ...transactions],
totalTransactionsCount:
totalTransactionsAmount > 0 ? totalTransactionsAmount : state[safeAddress].totalTransactionsCount,
},
}
},
},
{},
)

View File

@ -1,9 +1,9 @@
import { Map } from 'immutable'
import { handleActions } from 'redux-actions'
import { ADD_OR_UPDATE_CANCELLATION_TRANSACTIONS } from 'src/routes/safe/store/actions/transactions/addOrUpdateCancellationTransactions'
import { REMOVE_CANCELLATION_TRANSACTION } from 'src/routes/safe/store/actions/transactions/removeCancellationTransaction'
import { Transaction } from 'src/routes/safe/store/models/types/transaction'
import { Transaction } from 'src/logic/safe/store/models/types/transaction'
import { ADD_OR_UPDATE_CANCELLATION_TRANSACTIONS } from 'src/logic/safe/store/actions/transactions/addOrUpdateCancellationTransactions'
import { REMOVE_CANCELLATION_TRANSACTION } from 'src/logic/safe/store/actions/transactions/removeCancellationTransaction'
export const CANCELLATION_TRANSACTIONS_REDUCER_ID = 'cancellationTransactions'

View File

@ -1,7 +1,7 @@
import { Map } from 'immutable'
import { handleActions } from 'redux-actions'
import { ADD_INCOMING_TRANSACTIONS } from 'src/routes/safe/store/actions/addIncomingTransactions'
import { ADD_INCOMING_TRANSACTIONS } from 'src/logic/safe/store/actions/addIncomingTransactions'
export const INCOMING_TRANSACTIONS_REDUCER_ID = 'incomingTransactions'

View File

@ -1,20 +1,20 @@
import { Map, Set } from 'immutable'
import { handleActions } from 'redux-actions'
import { ACTIVATE_TOKEN_FOR_ALL_SAFES } from 'src/routes/safe/store/actions/activateTokenForAllSafes'
import { ADD_SAFE, buildOwnersFrom } from 'src/routes/safe/store/actions/addSafe'
import { ADD_SAFE_OWNER } from 'src/routes/safe/store/actions/addSafeOwner'
import { EDIT_SAFE_OWNER } from 'src/routes/safe/store/actions/editSafeOwner'
import { REMOVE_SAFE } from 'src/routes/safe/store/actions/removeSafe'
import { REMOVE_SAFE_OWNER } from 'src/routes/safe/store/actions/removeSafeOwner'
import { REPLACE_SAFE_OWNER } from 'src/routes/safe/store/actions/replaceSafeOwner'
import { SET_DEFAULT_SAFE } from 'src/routes/safe/store/actions/setDefaultSafe'
import { SET_LATEST_MASTER_CONTRACT_VERSION } from 'src/routes/safe/store/actions/setLatestMasterContractVersion'
import { UPDATE_SAFE } from 'src/routes/safe/store/actions/updateSafe'
import { makeOwner } from 'src/routes/safe/store/models/owner'
import makeSafe from 'src/routes/safe/store/models/safe'
import { ACTIVATE_TOKEN_FOR_ALL_SAFES } from 'src/logic/safe/store/actions/activateTokenForAllSafes'
import { ADD_SAFE, buildOwnersFrom } from 'src/logic/safe/store/actions/addSafe'
import { ADD_SAFE_OWNER } from 'src/logic/safe/store/actions/addSafeOwner'
import { EDIT_SAFE_OWNER } from 'src/logic/safe/store/actions/editSafeOwner'
import { REMOVE_SAFE } from 'src/logic/safe/store/actions/removeSafe'
import { REMOVE_SAFE_OWNER } from 'src/logic/safe/store/actions/removeSafeOwner'
import { REPLACE_SAFE_OWNER } from 'src/logic/safe/store/actions/replaceSafeOwner'
import { SET_DEFAULT_SAFE } from 'src/logic/safe/store/actions/setDefaultSafe'
import { SET_LATEST_MASTER_CONTRACT_VERSION } from 'src/logic/safe/store/actions/setLatestMasterContractVersion'
import { UPDATE_SAFE } from 'src/logic/safe/store/actions/updateSafe'
import { makeOwner } from 'src/logic/safe/store/models/owner'
import makeSafe from 'src/logic/safe/store/models/safe'
import { checksumAddress } from 'src/utils/checksumAddress'
import { SafeReducerMap } from './types/safe'
import { SafeReducerMap } from 'src/routes/safe/store/reducer/types/safe'
export const SAFE_REDUCER_ID = 'safes'
export const DEFAULT_SAFE_INITIAL_STATE = 'NOT_ASKED'
@ -137,5 +137,3 @@ export default handleActions(
latestMasterContractVersion: '',
}),
)
export * from './types/safe'

View File

@ -1,8 +1,8 @@
import { Map } from 'immutable'
import { handleActions } from 'redux-actions'
import { ADD_OR_UPDATE_TRANSACTIONS } from 'src/routes/safe/store/actions/transactions/addOrUpdateTransactions'
import { REMOVE_TRANSACTION } from 'src/routes/safe/store/actions/transactions/removeTransaction'
import { ADD_OR_UPDATE_TRANSACTIONS } from 'src/logic/safe/store/actions/transactions/addOrUpdateTransactions'
import { REMOVE_TRANSACTION } from 'src/logic/safe/store/actions/transactions/removeTransaction'
export const TRANSACTIONS_REDUCER_ID = 'transactions'

View File

View File

@ -0,0 +1,22 @@
import { TransactionsState, TRANSACTIONS } from '../reducer/allTransactions'
import { createSelector } from 'reselect'
import { safeParamAddressFromStateSelector } from './index'
import { AppReduxState } from 'src/store'
export const getTransactionsStateSelector = (state: AppReduxState): TransactionsState => state[TRANSACTIONS]
export const allTransactionsSelector = createSelector(getTransactionsStateSelector, (transactionsState) => {
return transactionsState
})
export const safeAllTransactionsSelector = createSelector(
safeParamAddressFromStateSelector,
allTransactionsSelector,
(safeAddress, transactions) => transactions[safeAddress]?.transactions || [],
)
export const safeTotalTransactionsAmountSelector = createSelector(
safeParamAddressFromStateSelector,
allTransactionsSelector,
(safeAddress, transactions) => transactions[safeAddress]?.totalTransactionsCount || 0,
)

View File

@ -6,14 +6,15 @@ import { SAFELIST_ADDRESS, SAFE_PARAM_ADDRESS } from 'src/routes/routes'
import {
CANCELLATION_TRANSACTIONS_REDUCER_ID,
CancellationTransactions,
} from 'src/routes/safe/store/reducer/cancellationTransactions'
import { INCOMING_TRANSACTIONS_REDUCER_ID } from 'src/routes/safe/store/reducer/incomingTransactions'
import { SAFE_REDUCER_ID, SafesMap } from 'src/routes/safe/store/reducer/safe'
import { TRANSACTIONS_REDUCER_ID } from 'src/routes/safe/store/reducer/transactions'
} from 'src/logic/safe/store/reducer/cancellationTransactions'
import { INCOMING_TRANSACTIONS_REDUCER_ID } from 'src/logic/safe/store/reducer/incomingTransactions'
import { SAFE_REDUCER_ID } from 'src/logic/safe/store/reducer/safe'
import { TRANSACTIONS_REDUCER_ID } from 'src/logic/safe/store/reducer/transactions'
import { AppReduxState } from 'src/store'
import { checksumAddress } from 'src/utils/checksumAddress'
import makeSafe, { SafeRecord, SafeRecordProps } from '../models/safe'
import { SafesMap } from 'src/routes/safe/store/reducer/types/safe'
const safesStateSelector = (state: AppReduxState) => state[SAFE_REDUCER_ID]

View File

@ -1,8 +1,8 @@
import { List } from 'immutable'
import { createSelector } from 'reselect'
import { safeIncomingTransactionsSelector, safeTransactionsSelector } from 'src/routes/safe/store/selectors'
import { Transaction } from 'src/routes/safe/store/models/types/transaction'
import { safeIncomingTransactionsSelector, safeTransactionsSelector } from 'src/logic/safe/store/selectors'
import { Transaction } from 'src/logic/safe/store/models/types/transaction'
export const extendedTransactionsSelector = createSelector(
safeTransactionsSelector,

View File

@ -1,6 +1,6 @@
import { List } from 'immutable'
import { isPendingTransaction } from 'src/routes/safe/store/actions/transactions/utils/transactionHelpers'
import { isPendingTransaction } from 'src/logic/safe/store/actions/transactions/utils/transactionHelpers'
export const getAwaitingTransactions = (allTransactions = List([]), cancellationTxs, userAccount: string) => {
return allTransactions.filter((tx) => {

View File

@ -6,7 +6,7 @@ import { CALL } from '.'
import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts'
import { generateSignaturesFromTxConfirmations } from 'src/logic/safe/safeTxSigner'
import { Transaction } from 'src/routes/safe/store/models/types/transaction'
import { Transaction } from 'src/logic/safe/store/models/types/transaction'
import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses'
import { EMPTY_DATA, calculateGasOf, calculateGasPrice } from 'src/logic/wallets/ethTransactions'
import { getAccountFrom, getWeb3 } from 'src/logic/wallets/getWeb3'

View File

@ -1,5 +1,5 @@
import { NonPayableTransactionObject } from 'src/types/contracts/types.d'
import { TxArgs } from 'src/routes/safe/store/models/types/transaction'
import { TxArgs } from 'src/logic/safe/store/models/types/transaction'
export const CALL = 0
export const DELEGATE_CALL = 1

View File

@ -1,10 +1,10 @@
import { nftAssetsSelector } from 'src/logic/collectibles/store/selectors'
import updateActiveAssets from 'src/routes/safe/store/actions/updateActiveAssets'
import updateActiveAssets from 'src/logic/safe/store/actions/updateActiveAssets'
import {
safeActiveAssetsSelectorBySafe,
safeBlacklistedAssetsSelectorBySafe,
safesMapSelector,
} from 'src/routes/safe/store/selectors'
} from 'src/logic/safe/store/selectors'
const activateAssetsByBalance = (safeAddress) => async (dispatch, getState) => {
try {

View File

@ -15,17 +15,17 @@ import {
import addTokens from 'src/logic/tokens/store/actions/saveTokens'
import { makeToken, Token } from 'src/logic/tokens/store/model/token'
import { TokenState } from 'src/logic/tokens/store/reducer/tokens'
import updateSafe from 'src/routes/safe/store/actions/updateSafe'
import updateSafe from 'src/logic/safe/store/actions/updateSafe'
import { AppReduxState } from 'src/store'
import { humanReadableValue } from 'src/logic/tokens/utils/humanReadableValue'
import { SafeRecordProps } from 'src/routes/safe/store/models/safe'
import { SafeRecordProps } from 'src/logic/safe/store/models/safe'
import {
safeActiveTokensSelector,
safeBalancesSelector,
safeBlacklistedTokensSelector,
safeEthBalanceSelector,
safeSelector,
} from 'src/routes/safe/store/selectors'
} from 'src/logic/safe/store/selectors'
import { tokensSelector } from 'src/logic/tokens/store/selectors'
import { currencyValuesSelector } from 'src/logic/currencyValues/store/selectors'

View File

@ -8,8 +8,8 @@ import {
import { makeToken, Token } from 'src/logic/tokens/store/model/token'
import { ALTERNATIVE_TOKEN_ABI } from 'src/logic/tokens/utils/alternativeAbi'
import { web3ReadOnly as web3 } from 'src/logic/wallets/getWeb3'
import { isEmptyData } from 'src/routes/safe/store/actions/transactions/utils/transactionHelpers'
import { TxServiceModel } from 'src/routes/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions'
import { isEmptyData } from 'src/logic/safe/store/actions/transactions/utils/transactionHelpers'
import { TxServiceModel } from 'src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions'
import { Map } from 'immutable'
export const ETH_ADDRESS = '0x000'

View File

@ -1,5 +1,5 @@
import { List } from 'immutable'
import { SafeRecord } from 'src/routes/safe/store/models/safe'
import { SafeRecord } from 'src/logic/safe/store/models/safe'
export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
export const sameAddress = (firstAddress: string, secondAddress: string): boolean => {

View File

@ -7,7 +7,7 @@ import { NOTIFICATIONS, enhanceSnackbarForAction } from 'src/logic/notifications
import enqueueSnackbar from 'src/logic/notifications/store/actions/enqueueSnackbar'
import { ETHEREUM_NETWORK, ETHEREUM_NETWORK_IDS, getProviderInfo, getWeb3 } from 'src/logic/wallets/getWeb3'
import { makeProvider } from 'src/logic/wallets/store/model/provider'
import { updateStoredTransactionsStatus } from 'src/routes/safe/store/actions/transactions/utils/transactionHelpers'
import { updateStoredTransactionsStatus } from 'src/logic/safe/store/actions/transactions/utils/transactionHelpers'
import { Dispatch } from 'redux'
export const processProviderResponse = (dispatch, provider) => {

View File

@ -5,9 +5,9 @@ import { Redirect, Route, Switch, withRouter } from 'react-router-dom'
import { LOAD_ADDRESS, OPEN_ADDRESS, SAFELIST_ADDRESS, SAFE_PARAM_ADDRESS, WELCOME_ADDRESS } from './routes'
import Loader from 'src/components/Loader'
import { defaultSafeSelector } from 'src/routes/safe/store/selectors'
import { defaultSafeSelector } from 'src/logic/safe/store/selectors'
import { useAnalytics } from 'src/utils/googleAnalytics'
import { DEFAULT_SAFE_INITIAL_STATE } from 'src/routes/safe/store/reducer/safe'
import { DEFAULT_SAFE_INITIAL_STATE } from 'src/logic/safe/store/reducer/safe'
const Welcome = React.lazy(() => import('./welcome/container'))

View File

@ -12,11 +12,11 @@ import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts'
import { SAFES_KEY, saveSafes } from 'src/logic/safe/utils'
import { getNamesFrom, getOwnersFrom } from 'src/routes/open/utils/safeDataExtractor'
import { SAFELIST_ADDRESS } from 'src/routes/routes'
import { buildSafe } from 'src/routes/safe/store/actions/fetchSafe'
import { buildSafe } from 'src/logic/safe/store/actions/fetchSafe'
import { history } from 'src/store'
import { loadFromStorage } from 'src/utils/storage'
import { Dispatch } from 'redux'
import { SafeOwner } from '../../safe/store/models/safe'
import { SafeOwner } from '../../../logic/safe/store/models/safe'
import { List } from 'immutable'
import { checksumAddress } from 'src/utils/checksumAddress'

View File

@ -1,4 +1,4 @@
import addSafe from 'src/routes/safe/store/actions/addSafe'
import addSafe from 'src/logic/safe/store/actions/addSafe'
export default {
addSafe,

View File

@ -22,7 +22,7 @@ import {
getThresholdFrom,
} from 'src/routes/open/utils/safeDataExtractor'
import { SAFELIST_ADDRESS, WELCOME_ADDRESS } from 'src/routes/routes'
import { buildSafe } from 'src/routes/safe/store/actions/fetchSafe'
import { buildSafe } from 'src/logic/safe/store/actions/fetchSafe'
import { history } from 'src/store'
import { loadFromStorage, removeFromStorage, saveToStorage } from 'src/utils/storage'

View File

@ -1,4 +1,4 @@
import addSafe from 'src/routes/safe/store/actions/addSafe'
import addSafe from 'src/logic/safe/store/actions/addSafe'
export default {
addSafe,

View File

@ -1,7 +1,7 @@
import { List } from 'immutable'
import { makeOwner } from 'src/routes/safe/store/models/owner'
import { SafeOwner } from '../../safe/store/models/safe'
import { makeOwner } from 'src/logic/safe/store/models/owner'
import { SafeOwner } from '../../../logic/safe/store/models/safe'
export const getAccountsFrom = (values) => {
const accounts = Object.keys(values)

View File

@ -8,7 +8,7 @@ import React from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { SAFELIST_ADDRESS } from 'src/routes/routes'
import { safeParamAddressFromStateSelector } from 'src/routes/safe/store/selectors'
import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors'
import { xs } from 'src/theme/variables'
const useStyles = makeStyles({

View File

@ -39,7 +39,7 @@ import OwnerAddressTableCell from 'src/routes/safe/components/Settings/ManageOwn
import RenameOwnerIcon from 'src/routes/safe/components/Settings/ManageOwners/assets/icons/rename-owner.svg'
import RemoveOwnerIcon from 'src/routes/safe/components/Settings/assets/icons/bin.svg'
import RemoveOwnerIconDisabled from 'src/routes/safe/components/Settings/assets/icons/disabled-bin.svg'
import { addressBookQueryParamsSelector, safesListSelector } from 'src/routes/safe/store/selectors'
import { addressBookQueryParamsSelector, safesListSelector } from 'src/logic/safe/store/selectors'
import { checksumAddress } from 'src/utils/checksumAddress'
const AddressBookTable = ({ classes }) => {

View File

@ -0,0 +1,58 @@
import React, { useEffect, useState } from 'react'
import { useTransactions } from 'src/routes/safe/container/hooks/useTransactions'
import { ButtonLink, Loader } from '@gnosis.pm/safe-react-components'
import { Transaction } from 'src/logic/safe/store/models/types/transactions'
const Transactions = (): React.ReactElement => {
const [currentPage, setCurrentPage] = useState(0)
const [limit] = useState(50)
const [offset, setOffset] = useState(0)
const [maxPages, setMaxPages] = useState(0)
const { transactions, totalTransactionsCount } = useTransactions({ offset, limit })
const [transactionsByPage, setTransactionsByPage] = useState(transactions)
useEffect(() => {
const currentPage = Math.floor(offset / limit) + 1
const maxPages = Math.ceil(totalTransactionsCount / limit)
setCurrentPage(currentPage)
setMaxPages(maxPages)
const newTransactionsByPage = transactions ? transactions.slice(offset, offset * 2 || limit) : []
setTransactionsByPage(newTransactionsByPage)
}, [offset, limit, totalTransactionsCount, transactions])
// TODO: Remove this once we implement infinite scroll
const nextPageButtonHandler = () => {
setOffset(offset + limit)
}
const previousPageButtonHandler = () => {
setOffset(offset > 0 ? offset - limit : offset)
}
if (!transactionsByPage) return <div>No txs available for safe</div>
if (!transactionsByPage.length) return <Loader size="lg" />
return (
<>
{transactionsByPage.map((tx: Transaction, index) => {
let txHash = ''
if ('transactionHash' in tx) {
txHash = tx.transactionHash
}
if ('txHash' in tx) {
txHash = tx.txHash
}
return <div key={txHash || tx.executionDate || index}>Tx hash: {txHash}</div>
})}
<ButtonLink color="primary" onClick={previousPageButtonHandler} disabled={currentPage === 1}>
Previous Page
</ButtonLink>
<ButtonLink color="primary" onClick={nextPageButtonHandler} disabled={currentPage >= maxPages}>
Next Page
</ButtonLink>
</>
)
}
export default Transactions

View File

@ -14,7 +14,7 @@ import {
safeEthBalanceSelector,
safeNameSelector,
safeParamAddressFromStateSelector,
} from 'src/routes/safe/store/selectors'
} from 'src/logic/safe/store/selectors'
import { networkSelector } from 'src/logic/wallets/store/selectors'
import { SafeApp } from 'src/routes/safe/components/Apps/types'

View File

@ -12,7 +12,7 @@ import { OpenModalArgs } from 'src/routes/safe/components/Layout/interfaces'
import LCL from 'src/components/ListContentLayout'
import { networkSelector } from 'src/logic/wallets/store/selectors'
import { grantedSelector } from 'src/routes/safe/container/selector'
import { safeEthBalanceSelector, safeParamAddressFromStateSelector } from 'src/routes/safe/store/selectors'
import { safeEthBalanceSelector, safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors'
import { isSameURL } from 'src/utils/url'
import { useIframeMessageHandler } from './hooks/useIframeMessageHandler'

View File

@ -1,6 +1,6 @@
import { DELEGATE_CALL } from 'src/logic/safe/transactions/send'
import { getWeb3 } from 'src/logic/wallets/getWeb3'
import createTransaction from 'src/routes/safe/store/actions/createTransaction'
import createTransaction from 'src/logic/safe/store/actions/createTransaction'
import { MULTI_SEND_ADDRESS } from 'src/logic/contracts/safeContracts'
const multiSendAbi = [

View File

@ -8,7 +8,7 @@ import Item from './components/Item'
import Paragraph from 'src/components/layout/Paragraph'
import { activeNftAssetsListSelector, nftTokensSelector } from 'src/logic/collectibles/store/selectors'
import SendModal from 'src/routes/safe/components/Balances/SendModal'
import { safeSelector } from 'src/routes/safe/store/selectors'
import { safeSelector } from 'src/logic/safe/store/selectors'
import { fontColor, lg, screenSm, screenXs } from 'src/theme/variables'
const useStyles = makeStyles({

View File

@ -14,7 +14,7 @@ import Col from 'src/components/layout/Col'
import Hairline from 'src/components/layout/Hairline'
import Paragraph from 'src/components/layout/Paragraph'
import Row from 'src/components/layout/Row'
import { safeNameSelector, safeParamAddressFromStateSelector } from 'src/routes/safe/store/selectors'
import { safeNameSelector, safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors'
import { lg, md, screenSm, secondaryText, sm } from 'src/theme/variables'
import { copyToClipboard } from 'src/utils/clipboard'

View File

@ -2,7 +2,7 @@ import React from 'react'
import { useSelector } from 'react-redux'
import AddressInfo from 'src/components/AddressInfo'
import { safeSelector } from 'src/routes/safe/store/selectors'
import { safeSelector } from 'src/logic/safe/store/selectors'
const SafeInfo = () => {
const { address: safeAddress = '', ethBalance, name: safeName } = useSelector(safeSelector)

View File

@ -16,7 +16,7 @@ import Img from 'src/components/layout/Img'
import Paragraph from 'src/components/layout/Paragraph'
import Row from 'src/components/layout/Row'
import ContractInteractionIcon from 'src/routes/safe/components/Transactions/TxsTable/TxType/assets/custom.svg'
import { safeSelector } from 'src/routes/safe/store/selectors'
import { safeSelector } from 'src/logic/safe/store/selectors'
import { lg, md, sm } from 'src/theme/variables'
const useStyles = makeStyles({

View File

@ -13,7 +13,7 @@ import Paragraph from 'src/components/layout/Paragraph'
import Row from 'src/components/layout/Row'
import { isPayable } from 'src/logic/contractInteraction/sources/ABIService'
import { styles } from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/style'
import { safeSelector } from 'src/routes/safe/store/selectors'
import { safeSelector } from 'src/logic/safe/store/selectors'
const useStyles = makeStyles(styles)

View File

@ -20,8 +20,8 @@ import { getWeb3 } from 'src/logic/wallets/getWeb3'
import { styles } from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/style'
import Header from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Header'
import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils'
import createTransaction from 'src/routes/safe/store/actions/createTransaction'
import { safeSelector } from 'src/routes/safe/store/selectors'
import createTransaction from 'src/logic/safe/store/actions/createTransaction'
import { safeSelector } from 'src/logic/safe/store/selectors'
import { generateFormFieldKey, getValueFromTxInputs } from '../utils'
const useStyles = makeStyles(styles)

View File

@ -26,8 +26,8 @@ import { getEthAsToken } from 'src/logic/tokens/utils/tokenHelpers'
import { getWeb3 } from 'src/logic/wallets/getWeb3'
import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo'
import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils'
import createTransaction from 'src/routes/safe/store/actions/createTransaction'
import { safeSelector } from 'src/routes/safe/store/selectors'
import createTransaction from 'src/logic/safe/store/actions/createTransaction'
import { safeSelector } from 'src/logic/safe/store/selectors'
import { sm } from 'src/theme/variables'
type Props = {

View File

@ -30,7 +30,7 @@ import Paragraph from 'src/components/layout/Paragraph'
import Row from 'src/components/layout/Row'
import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo'
import AddressBookInput from 'src/routes/safe/components/Balances/SendModal/screens/AddressBookInput'
import { safeSelector } from 'src/routes/safe/store/selectors'
import { safeSelector } from 'src/logic/safe/store/selectors'
import { sm } from 'src/theme/variables'
export interface CreatedTx {

Some files were not shown because too many files have changed in this diff Show More