immortaldb wip
This commit is contained in:
parent
0e97f41c54
commit
7e150a2ff3
|
@ -3432,6 +3432,15 @@
|
|||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
|
||||
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.18.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz",
|
||||
"integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.3.0",
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
},
|
||||
"axobject-query": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz",
|
||||
|
@ -10206,7 +10215,6 @@
|
|||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.7.0.tgz",
|
||||
"integrity": "sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "^3.2.6"
|
||||
},
|
||||
|
@ -10215,7 +10223,6 @@
|
|||
"version": "3.2.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
|
||||
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
|
@ -10223,8 +10230,7 @@
|
|||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -18270,6 +18276,11 @@
|
|||
"postcss": "^7.0.14"
|
||||
}
|
||||
},
|
||||
"idb-keyval": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-3.1.0.tgz",
|
||||
"integrity": "sha512-iFwFN5n00KNNnVxlOOK280SJJfXWY7pbMUOQXdIXehvvc/mGCV/6T2Ae+Pk2KwAkkATDTwfMavOiDH5lrJKWXQ=="
|
||||
},
|
||||
"idna-uts46-hx": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz",
|
||||
|
@ -18308,6 +18319,15 @@
|
|||
"integrity": "sha512-3fmKM6ovaqDt0CdC9daXpNi5x/YCYS3i4cwLdTVkhJdk5jrDXoPs7lCm3IqM3yhfSnz4tjjxbRG2CziQ7m8ztg==",
|
||||
"dev": true
|
||||
},
|
||||
"immortal-db": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/immortal-db/-/immortal-db-1.0.2.tgz",
|
||||
"integrity": "sha512-7EaVr6vUaaqsl9Jnp+CY4FzA1jIQD+o1tFEY2+O4ibYgmVB+FEWDoyUNN/naq9ZfiYKw4+uly1fpxk0xyE358w==",
|
||||
"requires": {
|
||||
"idb-keyval": "^3.0.5",
|
||||
"js-cookie": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"immutable": {
|
||||
"version": "4.0.0-rc.12",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0-rc.12.tgz",
|
||||
|
@ -18600,8 +18620,7 @@
|
|||
"is-buffer": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
|
||||
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
|
||||
},
|
||||
"is-callable": {
|
||||
"version": "1.1.4",
|
||||
|
@ -19532,6 +19551,11 @@
|
|||
"nopt": "~4.0.1"
|
||||
}
|
||||
},
|
||||
"js-cookie": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.0.tgz",
|
||||
"integrity": "sha1-Gywnmm7s44ChIWi5JIUmWzWx7/s="
|
||||
},
|
||||
"js-levenshtein": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz",
|
||||
|
|
|
@ -67,10 +67,12 @@
|
|||
"@gnosis.pm/util-contracts": "^2.0.0",
|
||||
"@material-ui/core": "^3.0.1",
|
||||
"@material-ui/icons": "^3.0.1",
|
||||
"axios": "^0.18.0",
|
||||
"bignumber.js": "^8.1.1",
|
||||
"connected-react-router": "^6.3.1",
|
||||
"final-form": "^4.2.1",
|
||||
"history": "^4.7.2",
|
||||
"immortal-db": "^1.0.2",
|
||||
"immutable": "^4.0.0-rc.9",
|
||||
"material-ui-search-bar": "^1.0.0-beta.13",
|
||||
"optimize-css-assets-webpack-plugin": "^5.0.1",
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
// @flow
|
||||
import { createAction } from 'redux-actions'
|
||||
import { type Token } from '~/logic/tokens/store/model/token'
|
||||
import {
|
||||
setActiveTokenAddresses,
|
||||
getActiveTokenAddresses,
|
||||
setToken,
|
||||
} from '~/logic/tokens/utils/activeTokensStorage'
|
||||
import { setActiveTokenAddresses, getActiveTokenAddresses, setToken } from '~/logic/tokens/utils/tokensStorage'
|
||||
import type { Dispatch as ReduxDispatch } from 'redux'
|
||||
import { type GlobalState } from '~/store/index'
|
||||
|
||||
|
@ -24,14 +20,13 @@ const addToken = createAction(
|
|||
}),
|
||||
)
|
||||
|
||||
const saveToken = (safeAddress: string, token: Token) => (dispatch: ReduxDispatch<GlobalState>) => {
|
||||
const saveToken = (safeAddress: string, token: Token) => async (dispatch: ReduxDispatch<GlobalState>) => {
|
||||
dispatch(addToken(safeAddress, token))
|
||||
|
||||
const tokenAddress = token.get('address')
|
||||
const activeTokens = getActiveTokenAddresses(safeAddress)
|
||||
setActiveTokenAddresses(safeAddress, activeTokens.push(tokenAddress))
|
||||
const activeTokens = await getActiveTokenAddresses(safeAddress)
|
||||
await setActiveTokenAddresses(safeAddress, activeTokens.push(tokenAddress))
|
||||
setToken(safeAddress, token)
|
||||
}
|
||||
|
||||
|
||||
export default saveToken
|
||||
|
|
|
@ -5,7 +5,7 @@ import type { Dispatch as ReduxDispatch } from 'redux'
|
|||
import { type Token } from '~/logic/tokens/store/model/token'
|
||||
import { ensureOnce } from '~/utils/singleton'
|
||||
import { type GlobalState } from '~/store/index'
|
||||
import { setActiveTokenAddresses } from '~/logic/tokens/utils/activeTokensStorage'
|
||||
import { setActiveTokenAddresses } from '~/logic/tokens/utils/tokensStorage'
|
||||
import { calculateActiveErc20TokensFrom } from '~/logic/tokens/utils/tokenHelpers'
|
||||
|
||||
export const ADD_TOKENS = 'ADD_TOKENS'
|
||||
|
|
|
@ -3,7 +3,7 @@ import { createAction } from 'redux-actions'
|
|||
import { type Token } from '~/logic/tokens/store/model/token'
|
||||
import type { Dispatch as ReduxDispatch } from 'redux'
|
||||
import { type GlobalState } from '~/store/index'
|
||||
import { removeFromActiveTokens } from '~/logic/tokens/utils/activeTokensStorage'
|
||||
import { removeFromActiveTokens } from '~/logic/tokens/utils/tokensStorage'
|
||||
|
||||
export const DISABLE_TOKEN = 'DISABLE_TOKEN'
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { createAction } from 'redux-actions'
|
|||
import type { Dispatch as ReduxDispatch } from 'redux'
|
||||
import { type GlobalState } from '~/store/index'
|
||||
import { type Token } from '~/logic/tokens/store/model/token'
|
||||
import { setActiveTokenAddresses, getActiveTokenAddresses } from '~/logic/tokens/utils/activeTokensStorage'
|
||||
import { setActiveTokenAddresses, getActiveTokenAddresses } from '~/logic/tokens/utils/tokensStorage'
|
||||
|
||||
export const ENABLE_TOKEN = 'ENABLE_TOKEN'
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
import { List, Map } from 'immutable'
|
||||
import contract from 'truffle-contract'
|
||||
import axios from 'axios'
|
||||
import { BigNumber } from 'bignumber.js'
|
||||
import type { Dispatch as ReduxDispatch } from 'redux'
|
||||
import StandardToken from '@gnosis.pm/util-contracts/build/contracts/GnosisStandardToken.json'
|
||||
|
@ -9,9 +10,8 @@ import { getWeb3 } from '~/logic/wallets/getWeb3'
|
|||
import { type GlobalState } from '~/store/index'
|
||||
import { makeToken, type Token, type TokenProps } from '~/logic/tokens/store/model/token'
|
||||
import { ensureOnce } from '~/utils/singleton'
|
||||
import { getActiveTokenAddresses, getTokens } from '~/logic/tokens/utils/activeTokensStorage'
|
||||
import { getActiveTokenAddresses, getTokens } from '~/logic/tokens/utils/tokensStorage'
|
||||
import { getSafeEthToken } from '~/logic/tokens/utils/tokenHelpers'
|
||||
import { enhancedFetch } from '~/utils/fetch'
|
||||
import addTokens from './addTokens'
|
||||
import { getRelayUrl } from '~/config/index'
|
||||
|
||||
|
@ -52,14 +52,16 @@ export const fetchTokensData = async () => {
|
|||
const apiUrl = getRelayUrl()
|
||||
const url = `${apiUrl}/tokens`
|
||||
const errMsg = 'Error querying safe balances'
|
||||
return enhancedFetch(url, errMsg)
|
||||
return axios.get(url, errMsg)
|
||||
}
|
||||
|
||||
export const fetchTokens = (safeAddress: string) => async (dispatch: ReduxDispatch<GlobalState>) => {
|
||||
const tokens: List<string> = getActiveTokenAddresses(safeAddress)
|
||||
const tokens: List<string> = await getActiveTokenAddresses(safeAddress)
|
||||
const ethBalance = await getSafeEthToken(safeAddress)
|
||||
const customTokens = getTokens(safeAddress)
|
||||
const { results } = await fetchTokensData()
|
||||
const customTokens = await getTokens(safeAddress)
|
||||
const {
|
||||
data: { results },
|
||||
} = await fetchTokensData()
|
||||
|
||||
try {
|
||||
const balancesRecords = await Promise.all(
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// @flow
|
||||
import { createAction } from 'redux-actions'
|
||||
import { type Token } from '~/logic/tokens/store/model/token'
|
||||
import { removeTokenFromStorage, removeFromActiveTokens } from '~/logic/tokens/utils/activeTokensStorage'
|
||||
import { removeTokenFromStorage, removeFromActiveTokens } from '~/logic/tokens/utils/tokensStorage'
|
||||
import { type GlobalState } from '~/store/index'
|
||||
import type { Dispatch as ReduxDispatch } from 'redux'
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// @flow
|
||||
import { List } from 'immutable'
|
||||
import { load } from '~/utils/localStorage'
|
||||
import { ImmortalDB } from 'immortal-db'
|
||||
import { type Token, type TokenProps } from '~/logic/tokens/store/model/token'
|
||||
|
||||
export const ACTIVE_TOKENS_KEY = 'ACTIVE_TOKENS'
|
||||
|
@ -9,65 +9,60 @@ export const TOKENS_KEY = 'TOKENS'
|
|||
const getActiveTokensKey = (safeAddress: string) => `${ACTIVE_TOKENS_KEY}-${safeAddress}`
|
||||
const getTokensKey = (safeAddress: string) => `${TOKENS_KEY}-${safeAddress}`
|
||||
|
||||
export const setActiveTokenAddresses = (safeAddress: string, tokens: List<string>) => {
|
||||
export const setActiveTokenAddresses = async (safeAddress: string, tokens: List<string>) => {
|
||||
try {
|
||||
const serializedState = JSON.stringify(tokens)
|
||||
const key = getActiveTokensKey(safeAddress)
|
||||
localStorage.setItem(key, serializedState)
|
||||
await ImmortalDB.set(key, serializedState)
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line
|
||||
console.log('Error storing tokens in localstorage')
|
||||
}
|
||||
}
|
||||
|
||||
export const getActiveTokenAddresses = (safeAddress: string): List<string> => {
|
||||
export const getActiveTokenAddresses = async (safeAddress: string): Promise<List<string>> => {
|
||||
const key = getActiveTokensKey(safeAddress)
|
||||
const data = load(key)
|
||||
const data = await ImmortalDB.get(key)
|
||||
|
||||
return data ? List(data) : List()
|
||||
}
|
||||
|
||||
export const storedTokensBefore = (safeAddress: string) => {
|
||||
const key = getActiveTokensKey(safeAddress)
|
||||
return localStorage.getItem(key) === null
|
||||
}
|
||||
|
||||
export const getTokens = (safeAddress: string): List<TokenProps> => {
|
||||
export const getTokens = async (safeAddress: string): Promise<List<TokenProps>> => {
|
||||
const key = getTokensKey(safeAddress)
|
||||
const data = load(key)
|
||||
const data = await ImmortalDB.get(key)
|
||||
|
||||
return data ? List(data) : List()
|
||||
}
|
||||
|
||||
export const setToken = (safeAddress: string, token: Token) => {
|
||||
const data: List<TokenProps> = getTokens(safeAddress)
|
||||
export const setToken = async (safeAddress: string, token: Token) => {
|
||||
const data: List<TokenProps> = await getTokens(safeAddress)
|
||||
|
||||
try {
|
||||
const serializedState = JSON.stringify(data.push(token))
|
||||
const key = getTokensKey(safeAddress)
|
||||
localStorage.setItem(key, serializedState)
|
||||
ImmortalDB.set(key, serializedState)
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line
|
||||
console.log('Error adding token in localstorage')
|
||||
}
|
||||
}
|
||||
|
||||
export const removeTokenFromStorage = (safeAddress: string, token: Token) => {
|
||||
const data: List<TokenProps> = getTokens(safeAddress)
|
||||
export const removeTokenFromStorage = async (safeAddress: string, token: Token) => {
|
||||
const data: List<TokenProps> = await getTokens(safeAddress)
|
||||
|
||||
try {
|
||||
const index = data.indexOf(token)
|
||||
const serializedState = JSON.stringify(data.remove(index))
|
||||
const key = getTokensKey(safeAddress)
|
||||
localStorage.setItem(key, serializedState)
|
||||
await ImmortalDB.set(key, serializedState)
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line
|
||||
console.log('Error removing token in localstorage')
|
||||
}
|
||||
}
|
||||
|
||||
export const removeFromActiveTokens = (safeAddress: string, tokenAddress: string) => {
|
||||
const activeTokens = getActiveTokenAddresses(safeAddress)
|
||||
export const removeFromActiveTokens = async (safeAddress: string, tokenAddress: string) => {
|
||||
const activeTokens = await getActiveTokenAddresses(safeAddress)
|
||||
const index = activeTokens.indexOf(tokenAddress)
|
||||
setActiveTokenAddresses(safeAddress, activeTokens.delete(index))
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
// @flow
|
||||
import { BigNumber } from 'bignumber.js'
|
||||
import axios from 'axios'
|
||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||
import { enhancedFetch } from '~/utils/fetch'
|
||||
|
||||
// const MAINNET_NETWORK = 1
|
||||
export const EMPTY_DATA = '0x'
|
||||
|
@ -44,9 +44,9 @@ export const calculateGasPrice = async () => {
|
|||
|
||||
const url = 'https://ethgasstation.info/json/ethgasAPI.json'
|
||||
const errMsg = 'Error querying gas station'
|
||||
const json = await enhancedFetch(url, errMsg)
|
||||
const { data } = await axios.get(url, errMsg)
|
||||
|
||||
return new BigNumber(json.average).multipliedBy(1e8).toString()
|
||||
return new BigNumber(data.average).multipliedBy(1e8).toString()
|
||||
}
|
||||
|
||||
export const calculateGasOf = async (data: Object, from: string, to: string) => {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
import { List, Map } from 'immutable'
|
||||
import axios from 'axios'
|
||||
import type { Dispatch as ReduxDispatch } from 'redux'
|
||||
import { type GlobalState } from '~/store/index'
|
||||
import { makeOwner } from '~/routes/safe/store/model/owner'
|
||||
|
@ -7,7 +8,6 @@ import { makeTransaction, type Transaction } from '~/routes/safe/store/model/tra
|
|||
import { makeConfirmation } from '~/routes/safe/store/model/confirmation'
|
||||
import { loadSafeSubjects } from '~/utils/localStorage/transactions'
|
||||
import { buildTxServiceUrlFrom, type TxServiceType } from '~/logic/safe/safeTxHistory'
|
||||
import { enhancedFetch } from '~/utils/fetch'
|
||||
import { getOwners } from '~/utils/localStorage'
|
||||
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
||||
import addTransactions from './addTransactions'
|
||||
|
@ -34,15 +34,17 @@ type TxServiceModel = {
|
|||
const buildTransactionFrom = (safeAddress: string, tx: TxServiceModel, safeSubjects: Map<string, string>) => {
|
||||
const name = safeSubjects.get(String(tx.nonce)) || 'Unknown'
|
||||
const storedOwners = getOwners(safeAddress)
|
||||
const confirmations = List(tx.confirmations.map((conf: ConfirmationServiceModel) => {
|
||||
const ownerName = storedOwners.get(conf.owner.toLowerCase()) || 'UNKNOWN'
|
||||
const confirmations = List(
|
||||
tx.confirmations.map((conf: ConfirmationServiceModel) => {
|
||||
const ownerName = storedOwners.get(conf.owner.toLowerCase()) || 'UNKNOWN'
|
||||
|
||||
return makeConfirmation({
|
||||
owner: makeOwner({ address: conf.owner, name: ownerName }),
|
||||
type: ((conf.type.toLowerCase(): any): TxServiceType),
|
||||
hash: conf.transactionHash,
|
||||
})
|
||||
}))
|
||||
return makeConfirmation({
|
||||
owner: makeOwner({ address: conf.owner, name: ownerName }),
|
||||
type: ((conf.type.toLowerCase(): any): TxServiceType),
|
||||
hash: conf.transactionHash,
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
||||
return makeTransaction({
|
||||
name,
|
||||
|
@ -57,8 +59,8 @@ const buildTransactionFrom = (safeAddress: string, tx: TxServiceModel, safeSubje
|
|||
|
||||
export const loadSafeTransactions = async (safeAddress: string) => {
|
||||
const url = buildTxServiceUrlFrom(safeAddress)
|
||||
const response = await enhancedFetch(url, 'Error fetching txs information')
|
||||
const transactions: TxServiceModel[] = response.results
|
||||
const response = await axios.get(url)
|
||||
const transactions: TxServiceModel[] = response.data.results
|
||||
const safeSubjects = loadSafeSubjects(safeAddress)
|
||||
const txsRecord = transactions.map((tx: TxServiceModel) => buildTransactionFrom(safeAddress, tx, safeSubjects))
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import { travelToTokens } from '~/test/builder/safe.dom.utils'
|
|||
import { sleep } from '~/utils/timer'
|
||||
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
|
||||
import { tokenListSelector, activeTokensSelector } from '~/logic/tokens/store/selectors'
|
||||
import { getActiveTokenAddresses } from '~/logic/tokens/utils/activeTokensStorage'
|
||||
import { getActiveTokenAddresses } from '~/logic/tokens/utils/tokensStorage'
|
||||
import { enableFirstToken, testToken } from '~/test/builder/tokens.dom.utils'
|
||||
import * as fetchTokensModule from '~/logic/tokens/store/actions/fetchTokens'
|
||||
import * as enhancedFetchModule from '~/utils/fetch'
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
// @flow
|
||||
export const promisify = (inner: Function): Promise<any> =>
|
||||
new Promise((resolve, reject) =>
|
||||
inner((err, res) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
resolve(res)
|
||||
}
|
||||
}))
|
Loading…
Reference in New Issue