Skip to content

Commit

Permalink
Merge pull request #330 from tallycash/implicitly-existential
Browse files Browse the repository at this point in the history
Implicitly Existential: Add noImplicitAny to TypeScript config, fix related issues
  • Loading branch information
mhluongo authored Oct 15, 2021
2 parents 702eee1 + 813666d commit 3d6e62e
Show file tree
Hide file tree
Showing 31 changed files with 264 additions and 242 deletions.
4 changes: 3 additions & 1 deletion background/constants/currencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ export const BTC = {

export const BASE_ASSETS = [ETH, BTC]

export const BASE_ASSETS_BY_SYMBOL = BASE_ASSETS.reduce((acc, asset) => {
export const BASE_ASSETS_BY_SYMBOL = BASE_ASSETS.reduce<{
[assetSymbol: string]: FungibleAsset
}>((acc, asset) => {
const newAcc = {
...acc,
}
Expand Down
52 changes: 0 additions & 52 deletions background/constants/default-state.ts

This file was deleted.

67 changes: 41 additions & 26 deletions background/lib/alchemy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import {
AlchemyProvider,
AlchemyWebSocketProvider,
} from "@ethersproject/providers"
import { logger, utils } from "ethers"
import { utils } from "ethers"

import logger from "./logger"
import { AssetTransfer, HexString, SmartContractFungibleAsset } from "../types"
import { ETH, ETHEREUM } from "../constants"

Expand Down Expand Up @@ -36,10 +37,20 @@ const alchemyAssetTransferJTD = {
additionalProperties: true,
} as const

type AlchemyAssetTransferResponse = JTDDataType<typeof alchemyAssetTransferJTD>
const alchemyGetAssetTransfersJTD = {
properties: {
transfers: {
elements: alchemyAssetTransferJTD,
},
},
} as const

type AlchemyAssetTransferResponse = JTDDataType<
typeof alchemyGetAssetTransfersJTD
>

const isValidAlchemyAssetTransferResponse =
ajv.compile<AlchemyAssetTransferResponse>(alchemyAssetTransferJTD)
ajv.compile<AlchemyAssetTransferResponse>(alchemyGetAssetTransfersJTD)

/**
* Use Alchemy's getAssetTransfers call to get historical transfers for an
Expand Down Expand Up @@ -82,51 +93,54 @@ export async function getAssetTransfers(
]),
])

return rpcResponses[0].transfers
.concat(rpcResponses[1].transfers)
.map((json: unknown) => {
if (!isValidAlchemyAssetTransferResponse(json)) {
logger.warn(
"Alchemy asset transfer response didn't validate, did the API change?",
json
)
return null
return rpcResponses
.flatMap((jsonResponse: unknown) => {
if (isValidAlchemyAssetTransferResponse(jsonResponse)) {
return jsonResponse.transfers
}

logger.warn(
"Alchemy asset transfer response didn't validate, did the API change?",
jsonResponse,
isValidAlchemyAssetTransferResponse.errors
)
return []
})
.map((transfer) => {
// TODO handle NFT asset lookup properly
if (json.erc721TokenId) {
if (transfer.erc721TokenId) {
return null
}

// we don't care about 0-value transfers
// TODO handle nonfungible assets properly
// TODO handle assets with a contract address and no name
if (
!json.rawContract ||
!json.rawContract.value ||
!json.rawContract.decimal ||
!json.asset
!transfer.rawContract ||
!transfer.rawContract.value ||
!transfer.rawContract.decimal ||
!transfer.asset
) {
return null
}

const asset = !json.rawContract.address
const asset = !transfer.rawContract.address
? {
contractAddress: json.rawContract.address,
decimals: Number(BigInt(json.rawContract.decimal)),
symbol: json.asset,
contractAddress: transfer.rawContract.address,
decimals: Number(BigInt(transfer.rawContract.decimal)),
symbol: transfer.asset,
homeNetwork: ETHEREUM, // TODO is this true?
}
: ETH
return {
network: ETHEREUM, // TODO make this friendly across other networks
assetAmount: {
asset,
amount: BigInt(json.rawContract.value),
amount: BigInt(transfer.rawContract.value),
},
txHash: json.hash,
to: json.to,
from: json.from,
txHash: transfer.hash,
to: transfer.to,
from: transfer.from,
dataSource: "alchemy",
} as AssetTransfer
})
Expand Down Expand Up @@ -182,7 +196,8 @@ export async function getTokenBalances(
if (!isValidAlchemyTokenBalanceResponse(json)) {
logger.warn(
"Alchemy token balance response didn't validate, did the API change?",
json
json,
isValidAlchemyTokenBalanceResponse.errors
)
return []
}
Expand Down
11 changes: 0 additions & 11 deletions background/lib/db.ts

This file was deleted.

4 changes: 3 additions & 1 deletion background/lib/erc20.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ export async function getBalances(
tokens.map((t) => t.contractAddress)
)

const assetByAddress = tokens.reduce((acc, asset) => {
const assetByAddress = tokens.reduce<{
[contractAddress: string]: SmartContractFungibleAsset
}>((acc, asset) => {
const newAcc = { ...acc }
newAcc[asset.contractAddress.toLowerCase()] = asset
return newAcc
Expand Down
10 changes: 5 additions & 5 deletions background/lib/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ enum LogLevel {
error = "error",
}

function genericLogger(level: LogLevel, input: any[]) {
function genericLogger(level: LogLevel, input: unknown[]) {
console[level](...input)

const stackTrace = new Error().stack.split("\n").filter((line) => {
Expand All @@ -29,19 +29,19 @@ function genericLogger(level: LogLevel, input: any[]) {
}

const logger = {
log(...input: any[]) {
log(...input: unknown[]): void {
genericLogger(LogLevel.log, input)
},

info(...input: any[]) {
info(...input: unknown[]): void {
genericLogger(LogLevel.info, input)
},

warn(...input: any[]) {
warn(...input: unknown[]): void {
genericLogger(LogLevel.warn, input)
},

error(...input: any[]) {
error(...input: unknown[]): void {
genericLogger(LogLevel.error, input)
},
}
Expand Down
24 changes: 16 additions & 8 deletions background/lib/prices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ export async function getPrice(
return null
}

return json ? parseFloat(json[coingeckoCoinId][currencySymbol]) : null
return json
? parseFloat(
json[coingeckoCoinId][currencySymbol] as string // FIXME Drop as when strict mode arrives and price schema type can include this.
)
: null
}

function multiplyByFloat(n: bigint, f: number, precision: number) {
Expand Down Expand Up @@ -78,7 +82,7 @@ export async function getPrices(
amounts: [
multiplyByFloat(
BigInt(10) ** BigInt(c.decimals),
parseFloat(simpleCoinPrices[symbol]),
simpleCoinPrices[symbol] as number, // FIXME Drop as when strict mode arrives and price schema type can include this.
8
),
BigInt(1),
Expand Down Expand Up @@ -113,7 +117,14 @@ export async function getEthereumTokenPrices(
const prices: {
[index: string]: UnitPricePoint
} = {}
Object.entries(json).forEach(([address, priceDetails]) => {
// TODO Improve typing with Ajv validation.
Object.entries(
json as {
[address: string]: { last_updated_at: number } & {
[currencySymbol: string]: string
}
}
).forEach(([address, priceDetails]) => {
// TODO parse this as a fixed decimal rather than a number. Will require
// custom JSON deserialization
const price: number = Number.parseFloat(
Expand All @@ -128,12 +139,9 @@ export async function getEthereumTokenPrices(
symbol: currencySymbol.toUpperCase(),
decimals: fiatDecimals,
},
amount: BigInt(price * 10 ** fiatDecimals),
amount: BigInt(Math.trunc(price * 10 ** fiatDecimals)),
},
time: Number.parseInt(
(priceDetails as { last_updated_at }).last_updated_at || 0,
10
),
time: priceDetails.last_updated_at,
}
})
return prices
Expand Down
2 changes: 1 addition & 1 deletion background/lib/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export function normalizeEVMAddress(address: string | Buffer): HexString {
return normalizeHexAddress(address)
}

export function convertToEth(value: string | number): string {
export function convertToEth(value: string | number | bigint): string {
if (value && value >= 1) {
return utils.formatUnits(BigInt(value))
}
Expand Down
2 changes: 1 addition & 1 deletion background/lib/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const coingeckoPriceSchema = {
},
additionalProperties: true,
},
}
} as const

type CoinGeckoPriceDataJtd = JTDDataType<typeof coingeckoPriceSchema>

Expand Down
10 changes: 3 additions & 7 deletions background/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { browser } from "webextension-polyfill-ts"
import { alias, wrapStore } from "webext-redux"
import { configureStore, isPlain } from "@reduxjs/toolkit"
import { configureStore, isPlain, Middleware } from "@reduxjs/toolkit"
import devToolsEnhancer from "remote-redux-devtools"
import ethers from "ethers"

Expand Down Expand Up @@ -36,12 +36,8 @@ import { assetsLoaded, newPricePoint } from "./redux-slices/assets"
import {
emitter as keyringSliceEmitter,
updateKeyrings,
importLegacyKeyring,
} from "./redux-slices/keyrings"
import {
transactionOptions,
emitter as transactionSliceEmitter,
} from "./redux-slices/transaction"
import { emitter as transactionSliceEmitter } from "./redux-slices/transaction"
import { allAliases } from "./redux-slices/utils"
import BaseService from "./services/base"

Expand All @@ -63,7 +59,7 @@ const devToolsSanitizer = (input: unknown) => {
}
}

const reduxCache = (store) => (next) => (action) => {
const reduxCache: Middleware = (store) => (next) => (action) => {
const result = next(action)
const state = store.getState()

Expand Down
15 changes: 0 additions & 15 deletions background/migrations/index.ts

This file was deleted.

34 changes: 0 additions & 34 deletions background/migrations/v0.ts

This file was deleted.

Loading

0 comments on commit 3d6e62e

Please sign in to comment.