Merge pull request #97 from gnosis/83-tokens
83-Tokens progress: Internal refactorings
This commit is contained in:
commit
5d05861856
File diff suppressed because it is too large
Load Diff
22
package.json
22
package.json
|
@ -66,7 +66,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@gnosis.pm/util-contracts": "^2.0.0",
|
"@gnosis.pm/util-contracts": "^2.0.0",
|
||||||
"@material-ui/core": "^3.0.1",
|
"@material-ui/core": "^3.9.3",
|
||||||
"@material-ui/icons": "^3.0.1",
|
"@material-ui/icons": "^3.0.1",
|
||||||
"axios": "^0.18.0",
|
"axios": "^0.18.0",
|
||||||
"bignumber.js": "^8.1.1",
|
"bignumber.js": "^8.1.1",
|
||||||
|
@ -80,7 +80,7 @@
|
||||||
"react": "^16.8.6",
|
"react": "^16.8.6",
|
||||||
"react-dom": "^16.8.6",
|
"react-dom": "^16.8.6",
|
||||||
"react-final-form": "^4.1.0",
|
"react-final-form": "^4.1.0",
|
||||||
"react-hot-loader": "^4.8.0",
|
"react-hot-loader": "^4.8.2",
|
||||||
"react-infinite-scroll-component": "^4.5.2",
|
"react-infinite-scroll-component": "^4.5.2",
|
||||||
"react-redux": "^6.0.1",
|
"react-redux": "^6.0.1",
|
||||||
"react-router-dom": "^4.3.1",
|
"react-router-dom": "^4.3.1",
|
||||||
|
@ -117,10 +117,10 @@
|
||||||
"@babel/preset-flow": "^7.0.0-beta.40",
|
"@babel/preset-flow": "^7.0.0-beta.40",
|
||||||
"@babel/preset-react": "^7.0.0-beta.40",
|
"@babel/preset-react": "^7.0.0-beta.40",
|
||||||
"@sambego/storybook-state": "^1.0.7",
|
"@sambego/storybook-state": "^1.0.7",
|
||||||
"@storybook/addon-actions": "^5.0.5",
|
"@storybook/addon-actions": "^5.0.6",
|
||||||
"@storybook/addon-knobs": "^5.0.5",
|
"@storybook/addon-knobs": "^5.0.6",
|
||||||
"@storybook/addon-links": "^5.0.5",
|
"@storybook/addon-links": "^5.0.6",
|
||||||
"@storybook/react": "^5.0.5",
|
"@storybook/react": "^5.0.6",
|
||||||
"autoprefixer": "^9.4.10",
|
"autoprefixer": "^9.4.10",
|
||||||
"babel-core": "^7.0.0-bridge.0",
|
"babel-core": "^7.0.0-bridge.0",
|
||||||
"babel-eslint": "^10.0.1",
|
"babel-eslint": "^10.0.1",
|
||||||
|
@ -132,7 +132,7 @@
|
||||||
"classnames": "^2.2.5",
|
"classnames": "^2.2.5",
|
||||||
"css-loader": "^2.1.0",
|
"css-loader": "^2.1.0",
|
||||||
"detect-port": "^1.2.2",
|
"detect-port": "^1.2.2",
|
||||||
"eslint": "^5.15.3",
|
"eslint": "^5.16.0",
|
||||||
"eslint-config-airbnb": "^17.1.0",
|
"eslint-config-airbnb": "^17.1.0",
|
||||||
"eslint-plugin-flowtype": "^3.4.2",
|
"eslint-plugin-flowtype": "^3.4.2",
|
||||||
"eslint-plugin-import": "^2.9.0",
|
"eslint-plugin-import": "^2.9.0",
|
||||||
|
@ -142,7 +142,7 @@
|
||||||
"ethereumjs-abi": "^0.6.7",
|
"ethereumjs-abi": "^0.6.7",
|
||||||
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
||||||
"file-loader": "^3.0.1",
|
"file-loader": "^3.0.1",
|
||||||
"flow-bin": "^0.95.1",
|
"flow-bin": "0.96.0",
|
||||||
"fs-extra": "^7.0.1",
|
"fs-extra": "^7.0.1",
|
||||||
"html-loader": "^0.5.5",
|
"html-loader": "^0.5.5",
|
||||||
"html-webpack-plugin": "^3.0.4",
|
"html-webpack-plugin": "^3.0.4",
|
||||||
|
@ -158,9 +158,9 @@
|
||||||
"storybook-host": "^5.0.3",
|
"storybook-host": "^5.0.3",
|
||||||
"storybook-router": "^0.3.3",
|
"storybook-router": "^0.3.3",
|
||||||
"style-loader": "^0.23.1",
|
"style-loader": "^0.23.1",
|
||||||
"truffle": "^5.0.9",
|
"truffle": "^5.0.10",
|
||||||
"truffle-contract": "^4.0.10",
|
"truffle-contract": "^4.0.11",
|
||||||
"truffle-solidity-loader": "^0.1.9",
|
"truffle-solidity-loader": "^0.1.10",
|
||||||
"uglifyjs-webpack-plugin": "^2.1.2",
|
"uglifyjs-webpack-plugin": "^2.1.2",
|
||||||
"webpack": "^4.1.1",
|
"webpack": "^4.1.1",
|
||||||
"webpack-bundle-analyzer": "^3.1.0",
|
"webpack-bundle-analyzer": "^3.1.0",
|
||||||
|
|
|
@ -5,8 +5,6 @@ import { List } from 'immutable'
|
||||||
import Row from '~/components/layout/Row'
|
import Row from '~/components/layout/Row'
|
||||||
import Table from '@material-ui/core/Table'
|
import Table from '@material-ui/core/Table'
|
||||||
import TableBody from '@material-ui/core/TableBody'
|
import TableBody from '@material-ui/core/TableBody'
|
||||||
import TableRow from '@material-ui/core/TableRow'
|
|
||||||
import TableCell from '@material-ui/core/TableCell'
|
|
||||||
import { withStyles } from '@material-ui/core/styles'
|
import { withStyles } from '@material-ui/core/styles'
|
||||||
import CircularProgress from '@material-ui/core/CircularProgress'
|
import CircularProgress from '@material-ui/core/CircularProgress'
|
||||||
import TablePagination from '@material-ui/core/TablePagination'
|
import TablePagination from '@material-ui/core/TablePagination'
|
||||||
|
@ -136,14 +134,7 @@ class GnoTable<K> extends React.Component<Props<K>, State> {
|
||||||
{!isEmpty && (
|
{!isEmpty && (
|
||||||
<Table aria-labelledby={label} className={classes.root}>
|
<Table aria-labelledby={label} className={classes.root}>
|
||||||
<TableHead columns={columns} order={order} orderBy={orderByParam} onSort={this.onSort} />
|
<TableHead columns={columns} order={order} orderBy={orderByParam} onSort={this.onSort} />
|
||||||
<TableBody>
|
<TableBody>{children(sortedData)}</TableBody>
|
||||||
{children(sortedData)}
|
|
||||||
{emptyRows > 0 && (
|
|
||||||
<TableRow style={this.getEmptyStyle(emptyRows)}>
|
|
||||||
<TableCell colSpan={4} />
|
|
||||||
</TableRow>
|
|
||||||
)}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
</Table>
|
||||||
)}
|
)}
|
||||||
{isEmpty && (
|
{isEmpty && (
|
||||||
|
|
|
@ -4,5 +4,9 @@ import 'babel-polyfill'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import Root from '~/components/Root'
|
import Root from '~/components/Root'
|
||||||
|
import { store } from '~/store'
|
||||||
|
import loadSafesFromStorage from '~/routes/safe/store/actions/loadSafesFromStorage'
|
||||||
|
|
||||||
|
store.dispatch(loadSafesFromStorage())
|
||||||
|
|
||||||
ReactDOM.render(<Root />, document.getElementById('root'))
|
ReactDOM.render(<Root />, document.getElementById('root'))
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { type Operation, submitOperation } from '~/logic/safe/safeTxHistory'
|
||||||
import { getSafeEthereumInstance } from '~/logic/safe/safeFrontendOperations'
|
import { getSafeEthereumInstance } from '~/logic/safe/safeFrontendOperations'
|
||||||
import { buildSignaturesFrom } from '~/logic/safe/safeTxSigner'
|
import { buildSignaturesFrom } from '~/logic/safe/safeTxSigner'
|
||||||
import { generateMetamaskSignature, generateTxGasEstimateFrom, estimateDataGas } from '~/logic/safe/safeTxSignerEIP712'
|
import { generateMetamaskSignature, generateTxGasEstimateFrom, estimateDataGas } from '~/logic/safe/safeTxSignerEIP712'
|
||||||
import { storeSignature, getSignaturesFrom } from '~/utils/localStorage/signatures'
|
import { storeSignature, getSignaturesFrom } from '~/utils/storage/signatures'
|
||||||
import { signaturesViaMetamask } from '~/config'
|
import { signaturesViaMetamask } from '~/config'
|
||||||
|
|
||||||
export const approveTransaction = async (
|
export const approveTransaction = async (
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
||||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||||
import { type Safe } from '~/routes/safe/store/model/safe'
|
import { type Safe } from '~/routes/safe/store/model/safe'
|
||||||
import { getGnosisSafeContract } from '~/logic/contracts/safeContracts'
|
import { getGnosisSafeContract } from '~/logic/contracts/safeContracts'
|
||||||
import { storeSubject } from '~/utils/localStorage/transactions'
|
import { storeSubject } from '~/utils/storage/transactions'
|
||||||
|
|
||||||
export const TX_NAME_PARAM = 'txName'
|
export const TX_NAME_PARAM = 'txName'
|
||||||
export const TX_DESTINATION_PARAM = 'txDestination'
|
export const TX_DESTINATION_PARAM = 'txDestination'
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||||
import { BigNumber } from 'bignumber.js'
|
import { BigNumber } from 'bignumber.js'
|
||||||
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
||||||
import { getSignaturesFrom } from '~/utils/localStorage/signatures'
|
import { getSignaturesFrom } from '~/utils/storage/signatures'
|
||||||
|
|
||||||
const estimateDataGasCosts = (data) => {
|
const estimateDataGasCosts = (data) => {
|
||||||
const reducer = (accumulator, currentValue) => {
|
const reducer = (accumulator, currentValue) => {
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
export * from './safeStorage'
|
|
@ -0,0 +1,43 @@
|
||||||
|
// @flow
|
||||||
|
import { type Owner } from '~/routes/safe/store/model/owner'
|
||||||
|
import { List, Map } from 'immutable'
|
||||||
|
import { loadFromStorage, saveToStorage } from '~/utils/storage'
|
||||||
|
|
||||||
|
export const SAFES_KEY = 'SAFES'
|
||||||
|
export const TX_KEY = 'TX'
|
||||||
|
export const OWNERS_KEY = 'OWNERS'
|
||||||
|
|
||||||
|
export const getSafeName = async (safeAddress: string) => {
|
||||||
|
const safes = await loadFromStorage(SAFES_KEY)
|
||||||
|
if (!safes) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
const safe = safes[safeAddress]
|
||||||
|
|
||||||
|
return safe ? safe.name : undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
export const saveSafes = async (safes: Object) => {
|
||||||
|
try {
|
||||||
|
await saveToStorage(SAFES_KEY, safes)
|
||||||
|
} catch (err) {
|
||||||
|
// eslint-disable-next-line
|
||||||
|
console.log('Error storing safe info in localstorage')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const setOwners = async (safeAddress: string, owners: List<Owner>) => {
|
||||||
|
try {
|
||||||
|
const ownersAsMap = Map(owners.map((owner: Owner) => [owner.get('address').toLowerCase(), owner.get('name')]))
|
||||||
|
await saveToStorage(`${OWNERS_KEY}-${safeAddress}`, ownersAsMap)
|
||||||
|
} catch (err) {
|
||||||
|
// eslint-disable-next-line
|
||||||
|
console.log('Error storing owners in localstorage')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getOwners = async (safeAddress: string): Map<string, string> => {
|
||||||
|
const data: Object = await loadFromStorage(`${OWNERS_KEY}-${safeAddress}`)
|
||||||
|
|
||||||
|
return data ? Map(data) : Map()
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { List } from 'immutable'
|
import { List } from 'immutable'
|
||||||
import { ImmortalDB } from 'immortal-db'
|
|
||||||
import { type Token, type TokenProps } from '~/logic/tokens/store/model/token'
|
import { type Token, type TokenProps } from '~/logic/tokens/store/model/token'
|
||||||
|
import { loadFromStorage, saveToStorage } from '~/utils/storage'
|
||||||
|
|
||||||
export const ACTIVE_TOKENS_KEY = 'ACTIVE_TOKENS'
|
export const ACTIVE_TOKENS_KEY = 'ACTIVE_TOKENS'
|
||||||
export const TOKENS_KEY = 'TOKENS'
|
export const TOKENS_KEY = 'TOKENS'
|
||||||
|
@ -11,9 +11,8 @@ const getTokensKey = (safeAddress: string) => `${TOKENS_KEY}-${safeAddress}`
|
||||||
|
|
||||||
export const setActiveTokens = async (safeAddress: string, tokens: List<TokenProps>) => {
|
export const setActiveTokens = async (safeAddress: string, tokens: List<TokenProps>) => {
|
||||||
try {
|
try {
|
||||||
const serializedState = JSON.stringify(tokens.toJS())
|
|
||||||
const key = getActiveTokensKey(safeAddress)
|
const key = getActiveTokensKey(safeAddress)
|
||||||
await ImmortalDB.set(key, serializedState)
|
await saveToStorage(key, tokens.toJS())
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
console.log('Error storing tokens in localstorage')
|
console.log('Error storing tokens in localstorage')
|
||||||
|
@ -22,25 +21,24 @@ export const setActiveTokens = async (safeAddress: string, tokens: List<TokenPro
|
||||||
|
|
||||||
export const getActiveTokens = async (safeAddress: string): Promise<List<TokenProps>> => {
|
export const getActiveTokens = async (safeAddress: string): Promise<List<TokenProps>> => {
|
||||||
const key = getActiveTokensKey(safeAddress)
|
const key = getActiveTokensKey(safeAddress)
|
||||||
const data = await ImmortalDB.get(key)
|
const data = await loadFromStorage(key)
|
||||||
|
|
||||||
return data ? List(JSON.parse(data)) : List()
|
return data ? List(data) : List()
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getTokens = async (safeAddress: string): Promise<List<TokenProps>> => {
|
export const getTokens = async (safeAddress: string): Promise<List<TokenProps>> => {
|
||||||
const key = getTokensKey(safeAddress)
|
const key = getTokensKey(safeAddress)
|
||||||
const data = await ImmortalDB.get(key)
|
const data = await loadFromStorage(key)
|
||||||
|
|
||||||
return data ? List(JSON.parse(data)) : List()
|
return data ? List(data) : List()
|
||||||
}
|
}
|
||||||
|
|
||||||
export const setToken = async (safeAddress: string, token: Token) => {
|
export const setToken = async (safeAddress: string, token: Token) => {
|
||||||
const data: List<TokenProps> = await getTokens(safeAddress)
|
const data: List<TokenProps> = await getTokens(safeAddress)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const serializedState = JSON.stringify(data.push(token))
|
|
||||||
const key = getTokensKey(safeAddress)
|
const key = getTokensKey(safeAddress)
|
||||||
await ImmortalDB.set(key, serializedState)
|
await saveToStorage(key, data.push(token))
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
console.log('Error adding token in localstorage')
|
console.log('Error adding token in localstorage')
|
||||||
|
@ -52,9 +50,8 @@ export const removeTokenFromStorage = async (safeAddress: string, token: Token)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const index = data.indexOf(token)
|
const index = data.indexOf(token)
|
||||||
const serializedState = JSON.stringify(data.remove(index))
|
|
||||||
const key = getTokensKey(safeAddress)
|
const key = getTokensKey(safeAddress)
|
||||||
await ImmortalDB.set(key, serializedState)
|
await saveToStorage(key, data.remove(index))
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
console.log('Error removing token in localstorage')
|
console.log('Error removing token in localstorage')
|
||||||
|
|
|
@ -3,7 +3,8 @@ import * as React from 'react'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
import Page from '~/components/layout/Page'
|
import Page from '~/components/layout/Page'
|
||||||
import { buildSafe } from '~/routes/safe/store/actions/fetchSafe'
|
import { buildSafe } from '~/routes/safe/store/actions/fetchSafe'
|
||||||
import { SAFES_KEY, load, saveSafes } from '~/utils/localStorage'
|
import { SAFES_KEY, saveSafes } from '~/logic/safe/utils'
|
||||||
|
import { loadFromStorage } from '~/utils/storage'
|
||||||
import { SAFELIST_ADDRESS } from '~/routes/routes'
|
import { SAFELIST_ADDRESS } from '~/routes/routes'
|
||||||
import { history } from '~/store'
|
import { history } from '~/store'
|
||||||
import selector, { type SelectorProps } from './selector'
|
import selector, { type SelectorProps } from './selector'
|
||||||
|
@ -18,7 +19,7 @@ export const loadSafe = async (safeName: string, safeAddress: string, updateSafe
|
||||||
|
|
||||||
await updateSafe(safeRecord)
|
await updateSafe(safeRecord)
|
||||||
|
|
||||||
const storedSafes = load(SAFES_KEY) || {}
|
const storedSafes = await loadFromStorage(SAFES_KEY) || {}
|
||||||
storedSafes[safeAddress] = safeRecord.toJSON()
|
storedSafes[safeAddress] = safeRecord.toJSON()
|
||||||
|
|
||||||
saveSafes(storedSafes)
|
saveSafes(storedSafes)
|
||||||
|
|
|
@ -5,7 +5,7 @@ import Stepper from '~/components/Stepper'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
import { type Safe } from '~/routes/safe/store/model/safe'
|
import { type Safe } from '~/routes/safe/store/model/safe'
|
||||||
import { type Owner, makeOwner } from '~/routes/safe/store/model/owner'
|
import { type Owner, makeOwner } from '~/routes/safe/store/model/owner'
|
||||||
import { setOwners } from '~/utils/localStorage'
|
import { setOwners } from '~/utils/storage'
|
||||||
import { getSafeEthereumInstance, createTransaction } from '~/logic/safe/safeFrontendOperations'
|
import { getSafeEthereumInstance, createTransaction } from '~/logic/safe/safeFrontendOperations'
|
||||||
import AddOwnerForm, { NAME_PARAM, OWNER_ADDRESS_PARAM, INCREASE_PARAM } from './AddOwnerForm'
|
import AddOwnerForm, { NAME_PARAM, OWNER_ADDRESS_PARAM, INCREASE_PARAM } from './AddOwnerForm'
|
||||||
import Review from './Review'
|
import Review from './Review'
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { List } from 'immutable'
|
import { List } from 'immutable'
|
||||||
import { createAction } from 'redux-actions'
|
import { createAction } from 'redux-actions'
|
||||||
import { type SafeProps } from '~/routes/safe/store/model/safe'
|
import { type Safe, makeSafe } from '~/routes/safe/store/model/safe'
|
||||||
|
import { saveSafes, setOwners } from '~/logic/safe/utils'
|
||||||
import { makeOwner, type Owner } from '~/routes/safe/store/model/owner'
|
import { makeOwner, type Owner } from '~/routes/safe/store/model/owner'
|
||||||
|
import type { Dispatch as ReduxDispatch, GetState } from 'redux'
|
||||||
|
import { type GlobalState } from '~/store/index'
|
||||||
|
import { safesMapSelector } from '~/routes/safeList/store/selectors/index'
|
||||||
|
|
||||||
export const ADD_SAFE = 'ADD_SAFE'
|
export const ADD_SAFE = 'ADD_SAFE'
|
||||||
|
|
||||||
|
@ -12,18 +16,40 @@ export const buildOwnersFrom = (names: Array<string>, addresses: Array<string>)
|
||||||
return List(owners)
|
return List(owners)
|
||||||
}
|
}
|
||||||
|
|
||||||
const addSafe = createAction(
|
type ActionReturn = {
|
||||||
ADD_SAFE,
|
safe: Safe,
|
||||||
(name: string, address: string, threshold: number, ownersName: string[], ownersAddress: string[]): SafeProps => {
|
}
|
||||||
const owners: List<Owner> = buildOwnersFrom(ownersName, ownersAddress)
|
|
||||||
|
|
||||||
return {
|
export const addSafe = createAction<string, *, *>(
|
||||||
address,
|
ADD_SAFE,
|
||||||
name,
|
(safe: Safe): ActionReturn => ({
|
||||||
threshold,
|
safe,
|
||||||
owners,
|
}),
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
export default addSafe
|
const saveSafe = (
|
||||||
|
name: string,
|
||||||
|
address: string,
|
||||||
|
threshold: number,
|
||||||
|
ownersName: string[],
|
||||||
|
ownersAddress: string[],
|
||||||
|
) => async (dispatch: ReduxDispatch<GlobalState>, getState: GetState<GlobalState>) => {
|
||||||
|
const owners: List<Owner> = buildOwnersFrom(ownersName, ownersAddress)
|
||||||
|
const state: GlobalState = getState()
|
||||||
|
|
||||||
|
const safe: Safe = makeSafe({
|
||||||
|
name,
|
||||||
|
address,
|
||||||
|
threshold,
|
||||||
|
owners,
|
||||||
|
})
|
||||||
|
const safes = safesMapSelector(state)
|
||||||
|
const newSafes = safes.set(address, safe)
|
||||||
|
|
||||||
|
setOwners(address, owners)
|
||||||
|
saveSafes(newSafes.toJSON())
|
||||||
|
|
||||||
|
dispatch(addSafe(safe))
|
||||||
|
}
|
||||||
|
|
||||||
|
export default saveSafe
|
||||||
|
|
|
@ -3,4 +3,4 @@ import { createAction } from 'redux-actions'
|
||||||
|
|
||||||
export const ADD_TRANSACTIONS = 'ADD_TRANSACTIONS'
|
export const ADD_TRANSACTIONS = 'ADD_TRANSACTIONS'
|
||||||
|
|
||||||
export default createAction(ADD_TRANSACTIONS)
|
export default createAction<string, *>(ADD_TRANSACTIONS)
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { type GlobalState } from '~/store/index'
|
||||||
import { makeOwner } from '~/routes/safe/store/model/owner'
|
import { makeOwner } from '~/routes/safe/store/model/owner'
|
||||||
import { type SafeProps, makeSafe } from '~/routes/safe/store/model/safe'
|
import { type SafeProps, makeSafe } from '~/routes/safe/store/model/safe'
|
||||||
import updateSafe from '~/routes/safe/store/actions/updateSafe'
|
import updateSafe from '~/routes/safe/store/actions/updateSafe'
|
||||||
import { getOwners, getSafeName } from '~/utils/localStorage'
|
import { getOwners, getSafeName } from '~/logic/safe/utils'
|
||||||
import { getGnosisSafeContract } from '~/logic/contracts/safeContracts'
|
import { getGnosisSafeContract } from '~/logic/contracts/safeContracts'
|
||||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||||
|
|
||||||
|
@ -16,11 +16,11 @@ const buildOwnersFrom = (safeOwners: string[], storedOwners: Map<string, string>
|
||||||
|
|
||||||
export const buildSafe = async (safeAddress: string, safeName: string) => {
|
export const buildSafe = async (safeAddress: string, safeName: string) => {
|
||||||
const web3 = getWeb3()
|
const web3 = getWeb3()
|
||||||
const GnosisSafe = await getGnosisSafeContract(web3)
|
const SafeContract = await getGnosisSafeContract(web3)
|
||||||
const gnosisSafe = await GnosisSafe.at(safeAddress)
|
const gnosisSafe = await SafeContract.at(safeAddress)
|
||||||
|
|
||||||
const threshold = Number(await gnosisSafe.getThreshold())
|
const threshold = Number(await gnosisSafe.getThreshold())
|
||||||
const owners = List(buildOwnersFrom(await gnosisSafe.getOwners(), getOwners(safeAddress)))
|
const owners = List(buildOwnersFrom(await gnosisSafe.getOwners(), await getOwners(safeAddress)))
|
||||||
|
|
||||||
const safe: SafeProps = {
|
const safe: SafeProps = {
|
||||||
address: safeAddress,
|
address: safeAddress,
|
||||||
|
@ -34,7 +34,7 @@ export const buildSafe = async (safeAddress: string, safeName: string) => {
|
||||||
|
|
||||||
export default (safeAddress: string) => async (dispatch: ReduxDispatch<GlobalState>) => {
|
export default (safeAddress: string) => async (dispatch: ReduxDispatch<GlobalState>) => {
|
||||||
try {
|
try {
|
||||||
const safeName = getSafeName(safeAddress) || 'LOADED SAFE'
|
const safeName = await getSafeName(safeAddress) || 'LOADED SAFE'
|
||||||
const safeRecord = await buildSafe(safeAddress, safeName)
|
const safeRecord = await buildSafe(safeAddress, safeName)
|
||||||
|
|
||||||
return dispatch(updateSafe(safeRecord))
|
return dispatch(updateSafe(safeRecord))
|
||||||
|
|
|
@ -6,9 +6,9 @@ import { type GlobalState } from '~/store/index'
|
||||||
import { makeOwner } from '~/routes/safe/store/model/owner'
|
import { makeOwner } from '~/routes/safe/store/model/owner'
|
||||||
import { makeTransaction, type Transaction } from '~/routes/safe/store/model/transaction'
|
import { makeTransaction, type Transaction } from '~/routes/safe/store/model/transaction'
|
||||||
import { makeConfirmation } from '~/routes/safe/store/model/confirmation'
|
import { makeConfirmation } from '~/routes/safe/store/model/confirmation'
|
||||||
import { loadSafeSubjects } from '~/utils/localStorage/transactions'
|
import { loadSafeSubjects } from '~/utils/storage/transactions'
|
||||||
import { buildTxServiceUrlFrom, type TxServiceType } from '~/logic/safe/safeTxHistory'
|
import { buildTxServiceUrlFrom, type TxServiceType } from '~/logic/safe/safeTxHistory'
|
||||||
import { getOwners } from '~/utils/localStorage'
|
import { getOwners } from '~/logic/safe/utils'
|
||||||
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
||||||
import addTransactions from './addTransactions'
|
import addTransactions from './addTransactions'
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
// @flow
|
||||||
|
import type { Dispatch as ReduxDispatch } from 'redux'
|
||||||
|
import { type GlobalState } from '~/store/index'
|
||||||
|
import { SAFES_KEY } from '~/logic/safe/utils'
|
||||||
|
import { type SafeProps } from '~/routes/safe/store/model/safe'
|
||||||
|
import { loadFromStorage } from '~/utils/storage'
|
||||||
|
import { addSafe } from './addSafe'
|
||||||
|
import { buildSafe } from '~/routes/safe/store/reducer/safe'
|
||||||
|
|
||||||
|
export default () => async (dispatch: ReduxDispatch<GlobalState>) => {
|
||||||
|
try {
|
||||||
|
const safes: ?{ [string]: SafeProps } = await loadFromStorage(SAFES_KEY)
|
||||||
|
|
||||||
|
if (safes) {
|
||||||
|
Object.values(safes).forEach((safeProps: SafeProps) => {
|
||||||
|
dispatch(addSafe(buildSafe(safeProps)))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// eslint-disable-next-line
|
||||||
|
console.error('Error while getting safes from storage:', err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
|
@ -3,6 +3,6 @@ import { createAction } from 'redux-actions'
|
||||||
|
|
||||||
export const UPDATE_SAFE = 'UPDATE_SAFE'
|
export const UPDATE_SAFE = 'UPDATE_SAFE'
|
||||||
|
|
||||||
const updateSafe = createAction(UPDATE_SAFE)
|
const updateSafe = createAction<string, *>(UPDATE_SAFE)
|
||||||
|
|
||||||
export default updateSafe
|
export default updateSafe
|
||||||
|
|
|
@ -3,6 +3,6 @@ import { createAction } from 'redux-actions'
|
||||||
|
|
||||||
export const UPDATE_SAFES = 'UPDATE_SAFES'
|
export const UPDATE_SAFES = 'UPDATE_SAFES'
|
||||||
|
|
||||||
const updateSafesInBatch = createAction(UPDATE_SAFES)
|
const updateSafesInBatch = createAction<string, *>(UPDATE_SAFES)
|
||||||
|
|
||||||
export default updateSafesInBatch
|
export default updateSafesInBatch
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { Map } from 'immutable'
|
import { Map } from 'immutable'
|
||||||
import { handleActions, type ActionType } from 'redux-actions'
|
import { handleActions, type ActionType } from 'redux-actions'
|
||||||
import addSafe, { ADD_SAFE, buildOwnersFrom } from '~/routes/safe/store/actions/addSafe'
|
import { ADD_SAFE, buildOwnersFrom } from '~/routes/safe/store/actions/addSafe'
|
||||||
import { type Safe, type SafeProps, makeSafe } from '~/routes/safe/store/model/safe'
|
import { type Safe, type SafeProps, makeSafe } from '~/routes/safe/store/model/safe'
|
||||||
import { type OwnerProps } from '~/routes/safe/store/model/owner'
|
import { type OwnerProps } from '~/routes/safe/store/model/owner'
|
||||||
import {
|
import { loadFromStorage } from '~/utils/storage'
|
||||||
saveSafes, setOwners, load, SAFES_KEY,
|
import { SAFES_KEY } from '~/logic/safe/utils'
|
||||||
} from '~/utils/localStorage'
|
import { UPDATE_SAFE } from '~/routes/safe/store/actions/updateSafe'
|
||||||
import updateSafe, { UPDATE_SAFE } from '~/routes/safe/store/actions/updateSafe'
|
|
||||||
|
|
||||||
export const SAFE_REDUCER_ID = 'safes'
|
export const SAFE_REDUCER_ID = 'safes'
|
||||||
|
|
||||||
|
@ -46,8 +45,8 @@ const buildSafesFrom = (loadedSafes: Object): Map<string, Safe> => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const safesInitialState = (): State => {
|
export const safesInitialState = async (): Promise<State> => {
|
||||||
const storedSafes = load(SAFES_KEY)
|
const storedSafes = await loadFromStorage(SAFES_KEY)
|
||||||
const safes = storedSafes ? buildSafesFrom(storedSafes) : Map()
|
const safes = storedSafes ? buildSafesFrom(storedSafes) : Map()
|
||||||
|
|
||||||
return safes
|
return safes
|
||||||
|
@ -55,7 +54,7 @@ export const safesInitialState = (): State => {
|
||||||
|
|
||||||
export default handleActions<State, *>(
|
export default handleActions<State, *>(
|
||||||
{
|
{
|
||||||
[UPDATE_SAFE]: (state: State, action: ActionType<typeof updateSafe>): State => {
|
[UPDATE_SAFE]: (state: State, action: ActionType<Function>): State => {
|
||||||
const safe = action.payload
|
const safe = action.payload
|
||||||
const safeAddress = safe.get('address')
|
const safeAddress = safe.get('address')
|
||||||
|
|
||||||
|
@ -66,14 +65,10 @@ export default handleActions<State, *>(
|
||||||
|
|
||||||
return state.set(safeAddress, safe)
|
return state.set(safeAddress, safe)
|
||||||
},
|
},
|
||||||
[ADD_SAFE]: (state: State, action: ActionType<typeof addSafe>): State => {
|
[ADD_SAFE]: (state: State, action: ActionType<Function>): State => {
|
||||||
const safe: Safe = makeSafe(action.payload)
|
const { safe }: { safe: Safe } = action.payload
|
||||||
setOwners(safe.get('address'), safe.get('owners'))
|
|
||||||
|
|
||||||
const safes = state.set(action.payload.address, safe)
|
return state.set(safe.address, safe)
|
||||||
saveSafes(safes.toJSON())
|
|
||||||
|
|
||||||
return safes
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Map(),
|
Map(),
|
||||||
|
|
|
@ -18,4 +18,4 @@ const SafeList = ({ safes, provider }: Props) => (
|
||||||
</Page>
|
</Page>
|
||||||
)
|
)
|
||||||
|
|
||||||
export default connect(selector)(SafeList)
|
export default connect<*, *, *, *>(selector)(SafeList)
|
||||||
|
|
|
@ -6,8 +6,9 @@ import { type Safe } from '~/routes/safe/store/model/safe'
|
||||||
import { userAccountSelector } from '~/logic/wallets/store/selectors'
|
import { userAccountSelector } from '~/logic/wallets/store/selectors'
|
||||||
import { type Owner } from '~/routes/safe/store/model/owner'
|
import { type Owner } from '~/routes/safe/store/model/owner'
|
||||||
import { sameAddress } from '~/logic/wallets/ethAddresses'
|
import { sameAddress } from '~/logic/wallets/ethAddresses'
|
||||||
|
import { SAFE_REDUCER_ID } from '~/routes/safe/store/reducer/safe'
|
||||||
|
|
||||||
export const safesMapSelector = (state: GlobalState): Map<string, Safe> => state.safes
|
export const safesMapSelector = (state: GlobalState): Map<string, Safe> => state[SAFE_REDUCER_ID]
|
||||||
|
|
||||||
const safesListSelector: Selector<GlobalState, {}, List<Safe>> = createSelector(
|
const safesListSelector: Selector<GlobalState, {}, List<Safe>> = createSelector(
|
||||||
safesMapSelector,
|
safesMapSelector,
|
||||||
|
|
|
@ -6,7 +6,7 @@ import {
|
||||||
} from 'redux'
|
} from 'redux'
|
||||||
import thunk from 'redux-thunk'
|
import thunk from 'redux-thunk'
|
||||||
import provider, { PROVIDER_REDUCER_ID, type State as ProviderState } from '~/logic/wallets/store/reducer/provider'
|
import provider, { PROVIDER_REDUCER_ID, type State as ProviderState } from '~/logic/wallets/store/reducer/provider'
|
||||||
import safe, { SAFE_REDUCER_ID, type State as SafeState, safesInitialState } from '~/routes/safe/store/reducer/safe'
|
import safe, { SAFE_REDUCER_ID, type State as SafeState } from '~/routes/safe/store/reducer/safe'
|
||||||
import tokens, { TOKEN_REDUCER_ID, type State as TokensState } from '~/logic/tokens/store/reducer/tokens'
|
import tokens, { TOKEN_REDUCER_ID, type State as TokensState } from '~/logic/tokens/store/reducer/tokens'
|
||||||
import transactions, {
|
import transactions, {
|
||||||
type State as TransactionsState,
|
type State as TransactionsState,
|
||||||
|
@ -36,10 +36,6 @@ const reducers: Reducer<GlobalState> = combineReducers({
|
||||||
[TRANSACTIONS_REDUCER_ID]: transactions,
|
[TRANSACTIONS_REDUCER_ID]: transactions,
|
||||||
})
|
})
|
||||||
|
|
||||||
const initialState = {
|
export const store: Store<GlobalState> = createStore(reducers, finalCreateStore)
|
||||||
[SAFE_REDUCER_ID]: safesInitialState(),
|
|
||||||
}
|
|
||||||
|
|
||||||
export const store: Store<GlobalState> = createStore(reducers, initialState, finalCreateStore)
|
|
||||||
|
|
||||||
export const aNewStore = (localState?: Object): Store<GlobalState> => createStore(reducers, localState, finalCreateStore)
|
export const aNewStore = (localState?: Object): Store<GlobalState> => createStore(reducers, localState, finalCreateStore)
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { safesMapSelector } from '~/routes/safeList/store/selectors'
|
||||||
import { makeOwner, type Owner } from '~/routes/safe/store/model/owner'
|
import { makeOwner, type Owner } from '~/routes/safe/store/model/owner'
|
||||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||||
import { safesInitialState } from '~/routes/safe/store/reducer/safe'
|
import { safesInitialState } from '~/routes/safe/store/reducer/safe'
|
||||||
import { setOwners, OWNERS_KEY } from '~/utils/localStorage'
|
import { setOwners, OWNERS_KEY } from '~/utils/storage'
|
||||||
|
|
||||||
describe('Safe - redux load safe', () => {
|
describe('Safe - redux load safe', () => {
|
||||||
let store
|
let store
|
||||||
|
@ -40,7 +40,7 @@ describe('Safe - redux load safe', () => {
|
||||||
expect(safe.get('address')).toBe(safeAddress)
|
expect(safe.get('address')).toBe(safeAddress)
|
||||||
expect(safe.get('owners')).toEqual(List([makeOwner({ name: 'UNKNOWN', address: accounts[0] })]))
|
expect(safe.get('owners')).toEqual(List([makeOwner({ name: 'UNKNOWN', address: accounts[0] })]))
|
||||||
|
|
||||||
expect(safesInitialState()).toEqual(safes)
|
expect(await safesInitialState()).toEqual(safes)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('if safe is not present but owners, store and persist it with stored names', async () => {
|
it('if safe is not present but owners, store and persist it with stored names', async () => {
|
||||||
|
@ -64,7 +64,7 @@ describe('Safe - redux load safe', () => {
|
||||||
expect(safe.get('address')).toBe(safeAddress)
|
expect(safe.get('address')).toBe(safeAddress)
|
||||||
expect(safe.get('owners')).toEqual(List([makeOwner({ name: ownerName, address: accounts[0] })]))
|
expect(safe.get('owners')).toEqual(List([makeOwner({ name: ownerName, address: accounts[0] })]))
|
||||||
|
|
||||||
expect(safesInitialState()).toEqual(safes)
|
expect(await safesInitialState()).toEqual(safes)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('if safe is present but no owners, store and persist it with default names', async () => {
|
it('if safe is present but no owners, store and persist it with default names', async () => {
|
||||||
|
@ -86,7 +86,7 @@ describe('Safe - redux load safe', () => {
|
||||||
expect(safe.get('address')).toBe(safeAddress)
|
expect(safe.get('address')).toBe(safeAddress)
|
||||||
expect(safe.get('owners')).toEqual(List([makeOwner({ name: 'UNKNOWN', address: accounts[0] })]))
|
expect(safe.get('owners')).toEqual(List([makeOwner({ name: 'UNKNOWN', address: accounts[0] })]))
|
||||||
|
|
||||||
expect(safesInitialState()).toEqual(safes)
|
expect(await safesInitialState()).toEqual(safes)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('if safe is present but owners, store and persist it with stored names', async () => {
|
it('if safe is present but owners, store and persist it with stored names', async () => {
|
||||||
|
@ -107,6 +107,6 @@ describe('Safe - redux load safe', () => {
|
||||||
expect(safe.get('address')).toBe(safeAddress)
|
expect(safe.get('address')).toBe(safeAddress)
|
||||||
expect(safe.get('owners')).toEqual(List([makeOwner({ name: 'Adol 1 Eth Account', address: accounts[0] })]))
|
expect(safe.get('owners')).toEqual(List([makeOwner({ name: 'Adol 1 Eth Account', address: accounts[0] })]))
|
||||||
|
|
||||||
expect(safesInitialState()).toEqual(safes)
|
expect(await safesInitialState()).toEqual(safes)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
// @flow
|
|
||||||
import { List, Map } from 'immutable'
|
|
||||||
import { type Owner } from '~/routes/safe/store/model/owner'
|
|
||||||
|
|
||||||
export const SAFES_KEY = 'SAFES'
|
|
||||||
export const TX_KEY = 'TX'
|
|
||||||
export const OWNERS_KEY = 'OWNERS'
|
|
||||||
|
|
||||||
export const load = (key: string) => {
|
|
||||||
try {
|
|
||||||
const serializedState = localStorage.getItem(key)
|
|
||||||
if (serializedState === null) {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serializedState === undefined) {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
return JSON.parse(serializedState)
|
|
||||||
} catch (err) {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getSafeName = (safeAddress: string) => {
|
|
||||||
const safes = load(SAFES_KEY)
|
|
||||||
if (!safes) {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
const safe = safes[safeAddress]
|
|
||||||
|
|
||||||
return safe ? safe.name : undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
export const saveSafes = (safes: Object) => {
|
|
||||||
try {
|
|
||||||
const serializedState = JSON.stringify(safes)
|
|
||||||
localStorage.setItem(SAFES_KEY, serializedState)
|
|
||||||
} catch (err) {
|
|
||||||
// eslint-disable-next-line
|
|
||||||
console.log('Error storing safe info in localstorage')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const setOwners = (safeAddress: string, owners: List<Owner>) => {
|
|
||||||
try {
|
|
||||||
const ownersAsMap = Map(owners.map((owner: Owner) => [owner.get('address').toLowerCase(), owner.get('name')]))
|
|
||||||
const serializedState = JSON.stringify(ownersAsMap)
|
|
||||||
localStorage.setItem(`${OWNERS_KEY}-${safeAddress}`, serializedState)
|
|
||||||
} catch (err) {
|
|
||||||
// eslint-disable-next-line
|
|
||||||
console.log('Error storing owners in localstorage')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getOwners = (safeAddress: string): Map<string, string> => {
|
|
||||||
const data = load(`${OWNERS_KEY}-${safeAddress}`)
|
|
||||||
|
|
||||||
return data ? Map(data) : Map()
|
|
||||||
}
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
// @flow
|
||||||
|
import {
|
||||||
|
ImmortalStorage, CookieStore, IndexedDbStore, LocalStorageStore, SessionStorageStore,
|
||||||
|
} from 'immortal-db'
|
||||||
|
|
||||||
|
const stores = [CookieStore, IndexedDbStore, LocalStorageStore, SessionStorageStore]
|
||||||
|
export const storage = new ImmortalStorage(stores)
|
||||||
|
|
||||||
|
const PREFIX = 'v1'
|
||||||
|
|
||||||
|
export const loadFromStorage = async (key: string): Promise<*> => {
|
||||||
|
try {
|
||||||
|
const stringifiedValue = await storage.get(`${PREFIX}__${key}`)
|
||||||
|
if (stringifiedValue === null || stringifiedValue === undefined) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON.parse(stringifiedValue)
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Failed to load ${key} from storage:`, err)
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const saveToStorage = async (key: string, value: *): Promise<*> => {
|
||||||
|
try {
|
||||||
|
const stringifiedValue = JSON.stringify(value)
|
||||||
|
await storage.set(`${PREFIX}__${key}`, stringifiedValue)
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Failed to save ${key} in the storage:`, err)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,20 +1,19 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { Map } from 'immutable'
|
import { Map } from 'immutable'
|
||||||
import { load } from '~/utils/localStorage'
|
import { loadFromStorage, saveToStorage } from '~/utils/storage'
|
||||||
|
|
||||||
const getSignaturesKeyFrom = (safeAddress: string) => `TXS-SIGNATURES-${safeAddress}`
|
const getSignaturesKeyFrom = (safeAddress: string) => `TXS-SIGNATURES-${safeAddress}`
|
||||||
|
|
||||||
export const storeSignature = (safeAddress: string, nonce: number, signature: string) => {
|
export const storeSignature = async (safeAddress: string, nonce: number, signature: string) => {
|
||||||
const signaturesKey = getSignaturesKeyFrom(safeAddress)
|
const signaturesKey = getSignaturesKeyFrom(safeAddress)
|
||||||
const subjects = Map(load(signaturesKey)) || Map()
|
const subjects = Map(await loadFromStorage(signaturesKey)) || Map()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const key = `${nonce}`
|
const key = `${nonce}`
|
||||||
const existingSignatures = subjects.get(key)
|
const existingSignatures = subjects.get(key)
|
||||||
const signatures = existingSignatures ? existingSignatures + signature : signature
|
const signatures = existingSignatures ? existingSignatures + signature : signature
|
||||||
const updatedSubjects = subjects.set(key, signatures)
|
const updatedSubjects = subjects.set(key, signatures)
|
||||||
const serializedState = JSON.stringify(updatedSubjects)
|
await saveToStorage(signaturesKey, updatedSubjects)
|
||||||
localStorage.setItem(signaturesKey, serializedState)
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
console.log('Error storing signatures in localstorage')
|
console.log('Error storing signatures in localstorage')
|
||||||
|
@ -23,7 +22,7 @@ export const storeSignature = (safeAddress: string, nonce: number, signature: st
|
||||||
|
|
||||||
export const getSignaturesFrom = (safeAddress: string, nonce: number) => {
|
export const getSignaturesFrom = (safeAddress: string, nonce: number) => {
|
||||||
const key = getSignaturesKeyFrom(safeAddress)
|
const key = getSignaturesKeyFrom(safeAddress)
|
||||||
const data: any = load(key)
|
const data: any = loadFromStorage(key)
|
||||||
|
|
||||||
const signatures = data ? Map(data) : Map()
|
const signatures = data ? Map(data) : Map()
|
||||||
const txSigs = signatures.get(String(nonce)) || ''
|
const txSigs = signatures.get(String(nonce)) || ''
|
|
@ -1,17 +1,16 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { Map } from 'immutable'
|
import { Map } from 'immutable'
|
||||||
import { load } from '~/utils/localStorage'
|
import { loadFromStorage, saveToStorage } from '~/utils/storage'
|
||||||
|
|
||||||
const getSubjectKeyFrom = (safeAddress: string) => `TXS-SUBJECTS-${safeAddress}`
|
const getSubjectKeyFrom = (safeAddress: string) => `TXS-SUBJECTS-${safeAddress}`
|
||||||
|
|
||||||
export const storeSubject = (safeAddress: string, nonce: number, subject: string) => {
|
export const storeSubject = async (safeAddress: string, nonce: number, subject: string) => {
|
||||||
const key = getSubjectKeyFrom(safeAddress)
|
const key = getSubjectKeyFrom(safeAddress)
|
||||||
const subjects = Map(load(key)) || Map()
|
const subjects = Map(await loadFromStorage(key)) || Map()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const updatedSubjects = subjects.set(nonce, subject)
|
const updatedSubjects = subjects.set(nonce, subject)
|
||||||
const serializedState = JSON.stringify(updatedSubjects)
|
saveToStorage(key, updatedSubjects)
|
||||||
localStorage.setItem(key, serializedState)
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
console.log('Error storing transaction subject in localstorage')
|
console.log('Error storing transaction subject in localstorage')
|
||||||
|
@ -20,7 +19,7 @@ export const storeSubject = (safeAddress: string, nonce: number, subject: string
|
||||||
|
|
||||||
export const loadSafeSubjects = (safeAddress: string): Map<string, string> => {
|
export const loadSafeSubjects = (safeAddress: string): Map<string, string> => {
|
||||||
const key = getSubjectKeyFrom(safeAddress)
|
const key = getSubjectKeyFrom(safeAddress)
|
||||||
const data: any = load(key)
|
const data: any = loadFromStorage(key)
|
||||||
|
|
||||||
return data ? Map(data) : Map()
|
return data ? Map(data) : Map()
|
||||||
}
|
}
|
Loading…
Reference in New Issue