Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Binance Smart Chain support #2659

Merged
merged 31 commits into from
Dec 5, 2022
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
5754ab6
Add feature flag for Binance Smart Chain
Nov 21, 2022
05f96a0
Add Binance Smart Chain constants
Nov 21, 2022
2aa6920
Add Binance Smart Chain to the list of protocols in the top menu
Nov 21, 2022
57a4b74
Rename icons for Binance Smart Chain
Nov 21, 2022
8ac10df
Add icon for BNB coin
Nov 21, 2022
797869e
Add Binance Smart Chain to supported networks
Nov 22, 2022
599a9b2
Merge branch 'main' into add-binance-smart-chain
Nov 22, 2022
2f9191d
Rename title for Binance Smart Chain scan website
Nov 22, 2022
fdfb95f
Fix the issue for getting gas prices for Binance Smart Chain
Nov 22, 2022
7a7c9f2
Add a token token list for BSC
Nov 22, 2022
cc25336
Merge branch 'main' into add-binance-smart-chain
Nov 22, 2022
379717c
Update coin type for BNB
Nov 24, 2022
a7cb97b
Merge branch 'main' into add-binance-smart-chain
Nov 24, 2022
16da743
Add network chart color for Binance Smart Chain
Nov 24, 2022
07fe5ba
Fix the issue with displaying the asset amount for BSC
Nov 24, 2022
fe6c8c5
Fix the issue with displaying the asset amount for BSC for overview page
Nov 25, 2022
9265b9c
Merge branch 'main' into add-binance-smart-chain
Nov 25, 2022
1476c03
Merge branch 'main' into add-binance-smart-chain
Nov 25, 2022
3bf8cb0
Merge branch 'main' into add-binance-smart-chain
Nov 25, 2022
a508ad8
Delete unnecessary comment
Nov 28, 2022
65db03a
Merge branch 'main' into add-binance-smart-chain
Nov 28, 2022
1304ccb
Merge branch 'main' into add-binance-smart-chain
Nov 29, 2022
5f1bb26
Refactor for updating combined data function
Nov 29, 2022
8ed47c9
Merge branch 'main' into add-binance-smart-chain
Nov 30, 2022
695715a
Rename title for BSC scan website
Nov 30, 2022
f3673b0
Merge branch 'main' into add-binance-smart-chain
Nov 30, 2022
7cb4384
Merge branch 'main' of github.com:tallycash/extension into add-binanc…
Dec 1, 2022
d40bd51
Merge branch 'main' of github.com:tallycash/extension into add-binanc…
Dec 2, 2022
017c09e
Refactor for update combined data function
Dec 2, 2022
45a2a1f
Add a new RPC url for BSC
Dec 2, 2022
6cd98f5
Rename BNB Smart Chain to BNB Chain
Dec 5, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ SUPPORT_TABBED_ONBOARDING=false
SUPPORT_KEYRING_LOCKING=true
SUPPORT_FORGOT_PASSWORD=false
SUPPORT_AVALANCHE=false
SUPPORT_BINANCE_SMART_CHAIN=false
ENABLE_ACHIEVEMENTS_TAB=true
SUPPORT_ACHIEVEMENTS_BANNER=false
SWITCH_RUNTIME_FLAGS=false
Expand Down
1 change: 1 addition & 0 deletions background/constants/coin-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const coinTypesByAssetSymbol = {
RBTC: 137,
MATIC: 966,
AVAX: 9000,
BNB: 714,
} as const

/**
Expand Down
14 changes: 13 additions & 1 deletion background/constants/currencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,18 @@ export const AVAX: NetworkBaseAsset = {
},
}

export const BNB: NetworkBaseAsset = {
name: "Binance Coin",
symbol: "BNB",
decimals: 18,
coinType: coinTypesByAssetSymbol.BNB,
metadata: {
coinGeckoID: "binancecoin",
tokenLists: [],
websiteURL: "https://bnbchain.org",
},
}

export const BTC: NetworkBaseAsset = {
name: "Bitcoin",
symbol: "BTC",
Expand All @@ -87,7 +99,7 @@ export const BTC: NetworkBaseAsset = {
},
}

export const BASE_ASSETS = [ETH, BTC, MATIC, RBTC, OPTIMISTIC_ETH, AVAX]
export const BASE_ASSETS = [ETH, BTC, MATIC, RBTC, OPTIMISTIC_ETH, AVAX, BNB]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love to see this list expand :)


export const BASE_ASSETS_BY_SYMBOL = BASE_ASSETS.reduce<{
[assetSymbol: string]: NetworkBaseAsset
Expand Down
17 changes: 15 additions & 2 deletions background/constants/networks.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { EVMNetwork, Network } from "../networks"
import { AVAX, BTC, ETH, MATIC, OPTIMISTIC_ETH, RBTC } from "./currencies"
import { AVAX, BNB, BTC, ETH, MATIC, OPTIMISTIC_ETH, RBTC } from "./currencies"

export const ETHEREUM: EVMNetwork = {
name: "Ethereum",
Expand Down Expand Up @@ -41,6 +41,14 @@ export const AVALANCHE: EVMNetwork = {
coingeckoPlatformID: "avalanche",
}

export const BINANCE_SMART_CHAIN: EVMNetwork = {
name: "BNB Smart Chain",
baseAsset: BNB,
chainID: "56",
family: "EVM",
coingeckoPlatformID: "binance-smart-chain",
}

export const OPTIMISM: EVMNetwork = {
name: "Optimism",
baseAsset: OPTIMISTIC_ETH,
Expand Down Expand Up @@ -77,7 +85,9 @@ export const EIP_1559_COMPLIANT_CHAIN_IDS = new Set(
)

export const CHAINS_WITH_MEMPOOL = new Set(
[ETHEREUM, POLYGON, AVALANCHE, GOERLI].map((network) => network.chainID)
[ETHEREUM, POLYGON, AVALANCHE, GOERLI, BINANCE_SMART_CHAIN].map(
(network) => network.chainID
)
)

export const NETWORK_BY_CHAIN_ID = {
Expand All @@ -87,6 +97,7 @@ export const NETWORK_BY_CHAIN_ID = {
[ARBITRUM_ONE.chainID]: ARBITRUM_ONE,
[AVALANCHE.chainID]: AVALANCHE,
[OPTIMISM.chainID]: OPTIMISM,
[BINANCE_SMART_CHAIN.chainID]: BINANCE_SMART_CHAIN,
[GOERLI.chainID]: GOERLI,
[FORK.chainID]: FORK,
}
Expand All @@ -107,6 +118,7 @@ export const CHAIN_ID_TO_0X_API_BASE: {
[GOERLI.chainID]: "goerli.api.0x.org",
[ARBITRUM_ONE.chainID]: "arbitrum.api.0x.org",
[AVALANCHE.chainID]: "avalanche.api.0x.org",
[BINANCE_SMART_CHAIN.chainID]: "bsc.api.0x.org",
}

export const NETWORKS_SUPPORTING_SWAPS = new Set(
Expand Down Expand Up @@ -135,4 +147,5 @@ export const CHAIN_ID_TO_RPC_URLS: {
],
[GOERLI.chainID]: ["https://ethereum-goerli-rpc.allthatnode.com"],
[AVALANCHE.chainID]: ["https://api.avax.network/ext/bc/C/rpc"],
[BINANCE_SMART_CHAIN.chainID]: ["https://rpc.ankr.com/bsc"],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add the official one as well https://bsc-dataseed.binance.org

}
2 changes: 2 additions & 0 deletions background/features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export const RuntimeFlag = {
HIDE_TOKEN_FEATURES: process.env.HIDE_TOKEN_FEATURES === "true",
SUPPORT_RSK: process.env.SUPPORT_RSK === "true",
SUPPORT_AVALANCHE: process.env.SUPPORT_AVALANCHE === "true",
SUPPORT_BINANCE_SMART_CHAIN:
process.env.SUPPORT_BINANCE_SMART_CHAIN === "true",
SUPPORT_ACHIEVEMENTS_BANNER:
process.env.SUPPORT_ACHIEVEMENTS_BANNER === "true",
SUPPORT_NFT_TAB: process.env.SUPPORT_NFT_TAB === "true",
Expand Down
22 changes: 20 additions & 2 deletions background/redux-slices/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import { createSlice } from "@reduxjs/toolkit"
import { createBackgroundAsyncThunk } from "./utils"
import { AccountBalance, AddressOnNetwork, NameOnNetwork } from "../accounts"
import { EVMNetwork, Network } from "../networks"
import { AnyAsset, AnyAssetAmount, SmartContractFungibleAsset } from "../assets"
import {
AnyAsset,
AnyAssetAmount,
FungibleAsset,
SmartContractFungibleAsset,
} from "../assets"
import {
AssetMainCurrencyAmount,
AssetDecimalAmount,
Expand Down Expand Up @@ -172,9 +177,22 @@ function updateCombinedData(immerState: AccountState) {
[symbol: string]: AnyAssetAmount
}>((acc, combinedAssetAmount) => {
const assetSymbol = combinedAssetAmount.asset.symbol
let { amount } = combinedAssetAmount

if (acc[assetSymbol]?.asset) {
const { decimals } = acc[assetSymbol].asset as FungibleAsset
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This forced cast seems dangerous, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's change it and make it simpler.

const assetDecimals =
"decimals" in combinedAssetAmount.asset
? combinedAssetAmount.asset.decimals
: 0
if (assetDecimals > decimals) {
amount /= BigInt(`1${"0".repeat(assetDecimals - decimals)}`)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

convertFixedPoint should be your friend here I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great suggestion!

}

acc[assetSymbol] = {
...combinedAssetAmount,
amount: (acc[assetSymbol]?.amount || 0n) + combinedAssetAmount.amount,
amount: (acc[assetSymbol]?.amount || 0n) + amount,
}
return acc
}, {})
Expand Down
25 changes: 22 additions & 3 deletions background/redux-slices/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,13 @@ const selectPairedAssetSymbol = (
pairedAssetSymbol: string
) => pairedAssetSymbol

const selectChainID = (
_: AssetsState,
_2: string,
_3: string,
chainID: string
) => chainID

/**
* Executes an asset transfer between two addresses, for a set amount. Supports
* an optional fixed gas limit.
Expand Down Expand Up @@ -187,9 +194,21 @@ export const transferAsset = createBackgroundAsyncThunk(
* the selector will return them in the order [ETH, USD].
*/
export const selectAssetPricePoint = createSelector(
[selectAssetsState, selectAssetSymbol, selectPairedAssetSymbol],
(assets, assetSymbol, pairedAssetSymbol) => {
const pricedAsset = assets.find(
[
selectAssetsState,
selectAssetSymbol,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can pass the asset object here instead of the symbol and chainId separately. I suspect we were using the symbol because it's easier to find an existing price point, but, that's now causing issues for assets with different decimals because this is a best-effort match. For base network assets, it should be enough to find a price point with the symbol alone.

If we pass the asset here we should be able to match by the symbol and use convertFixedPoint to transform the pricePoint amount to be more accurate for the wanted asset. We can improve this to take into account BaseNetworkAssets and SmartContractFungible assets too but I think it would be better to address this in another issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with you that maybe we should pass on the whole asset here. However, we will probably want to expand the assets to include the home network. Let's fix it in another issue.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is def strange here. I think creating a new ticket was a good call for this work.

selectPairedAssetSymbol,
selectChainID,
],
(assets, assetSymbol, pairedAssetSymbol, chainID) => {
const pricedAsset = (
chainID
? assets.filter(
(asset) =>
"homeNetwork" in asset && asset.homeNetwork.chainID === chainID
)
: assets
).find(
(asset) =>
asset.symbol === assetSymbol &&
pairedAssetSymbol in asset.recentPrices &&
Expand Down
2 changes: 2 additions & 0 deletions background/redux-slices/dapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { createBackgroundAsyncThunk } from "./utils"
import { keyPermissionsByChainIdAddressOrigin } from "../services/provider-bridge/utils"
import {
AVALANCHE,
BINANCE_SMART_CHAIN,
ETHEREUM,
GOERLI,
OPTIMISM,
Expand Down Expand Up @@ -131,6 +132,7 @@ const dappSlice = createSlice({
POLYGON,
OPTIMISM,
AVALANCHE,
BINANCE_SMART_CHAIN,
GOERLI,
].map((network) => ({
...permission,
Expand Down
25 changes: 18 additions & 7 deletions background/redux-slices/selectors/accountsSelectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ const computeCombinedAssetAmountsData = (
assets: AssetsState,
mainCurrencySymbol: string,
currentNetwork: EVMNetwork,
hideDust: boolean
hideDust: boolean,
useCurrentNetwork = false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The API naming is misleading here because it comes from the selector api.
Here it means every network every asset sum or current network every asset sum

I would have used something like onlyForCurrentNetwork

): {
combinedAssetAmounts: CompleteAssetAmount[]
totalMainCurrencyAmount: number | undefined
Expand All @@ -98,7 +99,8 @@ const computeCombinedAssetAmountsData = (
const assetPricePoint = selectAssetPricePoint(
assets,
assetAmount.asset.symbol,
mainCurrencySymbol
mainCurrencySymbol,
useCurrentNetwork ? currentNetwork.chainID : undefined
)

const mainCurrencyEnrichedAssetAmount =
Expand Down Expand Up @@ -260,7 +262,8 @@ export const selectCurrentAccountBalances = createSelector(
assets,
mainCurrencySymbol,
currentNetwork,
hideDust
hideDust,
true
)

return {
Expand Down Expand Up @@ -319,14 +322,16 @@ const getAccountType = (
const getTotalBalance = (
accountBalances: { [assetSymbol: string]: AccountBalance },
assets: AssetsState,
mainCurrencySymbol: string
mainCurrencySymbol: string,
chainID: string
) => {
return Object.values(accountBalances)
.map(({ assetAmount }) => {
const assetPricePoint = selectAssetPricePoint(
assets,
assetAmount.asset.symbol,
mainCurrencySymbol
mainCurrencySymbol,
chainID
)

if (typeof assetPricePoint === "undefined") {
Expand Down Expand Up @@ -397,7 +402,12 @@ function getNetworkAccountTotalsByCategory(
avatarURL: accountData.ens.avatarURL ?? accountData.defaultAvatar,
localizedTotalMainCurrencyAmount: formatCurrencyAmount(
mainCurrencySymbol,
getTotalBalance(accountData.balances, assets, mainCurrencySymbol),
getTotalBalance(
accountData.balances,
assets,
mainCurrencySymbol,
network.chainID
),
desiredDecimals.default
),
}
Expand Down Expand Up @@ -469,7 +479,8 @@ export const selectAccountTotalsForOverview = createSelector(
accountsTotal[normalizedAddress].totals[chainID] = getTotalBalance(
accountData.balances,
assetsState,
mainCurrencySymbol
mainCurrencySymbol,
chainID
)
})
)
Expand Down
3 changes: 2 additions & 1 deletion background/redux-slices/utils/0x-swap-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ export async function getAssetAmount(
const assetPricePoint = selectAssetPricePoint(
assets,
asset?.symbol,
hardcodedMainCurrencySymbol
hardcodedMainCurrencySymbol,
network.chainID
)

return enrichAssetAmountWithMainCurrencyValues(
Expand Down
4 changes: 4 additions & 0 deletions background/services/chain/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
CHAINS_WITH_MEMPOOL,
EIP_1559_COMPLIANT_CHAIN_IDS,
AVALANCHE,
BINANCE_SMART_CHAIN,
} from "../../constants"
import { FeatureFlags, isEnabled } from "../../features"
import PreferenceService from "../preferences"
Expand Down Expand Up @@ -271,6 +272,9 @@ export default class ChainService extends BaseService<Events> {
ARBITRUM_ONE,
...(isEnabled(FeatureFlags.SUPPORT_RSK) ? [ROOTSTOCK] : []),
...(isEnabled(FeatureFlags.SUPPORT_AVALANCHE) ? [AVALANCHE] : []),
...(isEnabled(FeatureFlags.SUPPORT_BINANCE_SMART_CHAIN)
? [BINANCE_SMART_CHAIN]
: []),
]

this.trackedNetworks = []
Expand Down
11 changes: 11 additions & 0 deletions background/services/preferences/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,17 @@ export class PreferenceDatabase extends Dexie {
})
})

this.version(13).upgrade((tx) => {
return tx
.table("preferences")
.toCollection()
.modify((storedPreferences: Preferences) => {
storedPreferences.tokenLists.urls.push(
"https://tokens.pancakeswap.finance/pancakeswap-default.json"
)
})
})

// This is the old version for populate
// https://dexie.org/docs/Dexie/Dexie.on.populate-(old-version)
// The this does not behave according the new docs, but works
Expand Down
1 change: 1 addition & 0 deletions background/services/preferences/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const defaultPreferences: Preferences = {
"https://static.optimism.io/optimism.tokenlist.json", // Optimism Default Tokens
"https://bridge.arbitrum.io/token-list-42161.json", // Arbitrum Default tokens
"https://raw.githubusercontent.com/traderjoe-xyz/joe-tokenlists/main/src/joe.tokenlist-v2.json", // Trader Joe tokens
"https://tokens.pancakeswap.finance/pancakeswap-default.json", // PancakeSwap Default List
],
},
currency: USD,
Expand Down
3 changes: 2 additions & 1 deletion ui/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,8 @@
"HIDE_TOKEN_FEATURES": "Hide token features",
"SUPPORT_ACHIEVEMENTS_BANNER": "Enable achievements banner",
"SUPPORT_AVALANCHE": "Enable Avalanche network",
"SUPPORT_NFT_TAB": "Enable to open NFTs page from tab"
"SUPPORT_NFT_TAB": "Enable to open NFTs page from tab",
"SUPPORT_BINANCE_SMART_CHAIN": "Enable Binance Smart Chain network"
}
}
},
Expand Down
2 changes: 2 additions & 0 deletions ui/components/Overview/NetworksChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
OPTIMISM,
NETWORK_BY_CHAIN_ID,
POLYGON,
BINANCE_SMART_CHAIN,
} from "@tallyho/tally-background/constants"
import { FeatureFlags, isEnabled } from "@tallyho/tally-background/features"
import { AccountTotalList } from "@tallyho/tally-background/redux-slices/selectors"
Expand All @@ -16,6 +17,7 @@ const NETWORKS_CHART_COLORS = {
[POLYGON.chainID]: "#8347E5",
[ARBITRUM_ONE.chainID]: "#2083C5",
[OPTIMISM.chainID]: "#CD041C",
[BINANCE_SMART_CHAIN.chainID]: "#F3BA2F",
}

const getNetworksPercents = (
Expand Down
2 changes: 1 addition & 1 deletion ui/components/Shared/SharedAssetIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface Props {
symbol: string
}

const hardcodedIcons = new Set(["ETH", "MATIC", "DOGGO", "RBTC", "AVAX"])
const hardcodedIcons = new Set(["ETH", "MATIC", "DOGGO", "RBTC", "AVAX", "BNB"])
export default function SharedAssetIcon(props: Props): ReactElement {
const { size, logoURL, symbol } = props

Expand Down
22 changes: 15 additions & 7 deletions ui/components/TopMenu/TopMenuProtocolList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { ReactElement } from "react"
import {
ARBITRUM_ONE,
AVALANCHE,
BINANCE_SMART_CHAIN,
ETHEREUM,
GOERLI,
OPTIMISM,
Expand Down Expand Up @@ -57,13 +58,20 @@ const productionNetworks = [
isDisabled: true,
},
]),

// {
// name: "Binance Smart Chain",
// info: i18n.t("protocol.compatibleChain"),
// width: 24,
// height: 24,
// },
...(isEnabled(FeatureFlags.SUPPORT_BINANCE_SMART_CHAIN)
? [
{
network: BINANCE_SMART_CHAIN,
info: i18n.t("protocol.compatibleChain"),
},
]
: [
{
network: BINANCE_SMART_CHAIN,
info: i18n.t("comingSoon"),
isDisabled: true,
},
]),
// {
// name: "Celo",
// info: "Global payments infrastructure",
Expand Down
Binary file added ui/public/images/assets/bnb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
Loading