Skip to content

Commit

Permalink
injected web3 support multinetwork
Browse files Browse the repository at this point in the history
  • Loading branch information
xuwen committed May 28, 2021
1 parent 338f422 commit 8612191
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 31 deletions.
3 changes: 2 additions & 1 deletion app/scripts/controllers/alert.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import ObservableStore from 'obs-store'
import { decodeBech32Address } from '@alayanetwork/ethereumjs-util'

/**
* @typedef {Object} AlertControllerInitState
Expand Down Expand Up @@ -53,7 +54,7 @@ export default class AlertController {

preferencesStore.subscribe(({ selectedAddress }) => {
const currentState = this.store.getState()
if (currentState.unconnectedAccountAlertShownOrigins && this.selectedAddress !== selectedAddress) {
if (currentState.unconnectedAccountAlertShownOrigins && decodeBech32Address(this.selectedAddress) !== decodeBech32Address(selectedAddress)) {
this.selectedAddress = selectedAddress
this.store.updateState({ unconnectedAccountAlertShownOrigins: {} })
}
Expand Down
40 changes: 33 additions & 7 deletions app/scripts/controllers/permissions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
NOTIFICATION_NAMES,
CAVEAT_TYPES,
} from './enums'
import {decodeBech32Address, toBech32Address} from "@alayanetwork/ethereumjs-util";
import { isBech32Address, decodeBech32Address, toBech32Address } from '@alayanetwork/ethereumjs-util'

export class PermissionsController {

Expand Down Expand Up @@ -306,9 +306,15 @@ export class PermissionsController {
this.validatePermittedAccounts([account])

const oldPermittedAccounts = this._getPermittedAccounts(origin)
const oldPermittedAccountsHex = oldPermittedAccounts.map((acc) => {
if (isBech32Address(acc)) {
return decodeBech32Address(acc)
}
return acc
})
if (!oldPermittedAccounts) {
throw new Error(`Origin does not have 'platon_accounts' permission`)
} else if (oldPermittedAccounts.includes(account)) {
} else if (oldPermittedAccountsHex.includes(decodeBech32Address(account))) {
throw new Error('Account is already permitted for origin')
}

Expand Down Expand Up @@ -344,15 +350,20 @@ export class PermissionsController {
this.validatePermittedAccounts([account])

const oldPermittedAccounts = this._getPermittedAccounts(origin)
const oldPermittedAccountsHex = oldPermittedAccounts.map((acc) => {
if (isBech32Address(acc)) {
return decodeBech32Address(acc)
}
return acc
})
if (!oldPermittedAccounts) {
throw new Error(`Origin does not have 'platon_accounts' permission`)
} else if (!oldPermittedAccounts.includes(account)) {
} else if (!oldPermittedAccountsHex.includes(decodeBech32Address(account))) {
throw new Error('Account is not permitted for origin')
}

let newPermittedAccounts = oldPermittedAccounts
.filter((acc) => acc !== account)

.filter((acc) => decodeBech32Address(acc) !== decodeBech32Address(account))
if (newPermittedAccounts.length === 0) {
this.removePermissionsFor({ [origin]: [ 'platon_accounts' ] })
} else {
Expand Down Expand Up @@ -382,7 +393,16 @@ export class PermissionsController {

const domains = this.permissions.getDomains()
const connectedOrigins = Object.keys(domains)
.filter((origin) => this._getPermittedAccounts(origin).includes(account))
.filter((origin) => {
const permittedAccounts = this._getPermittedAccounts(origin)
const permittedAccountsHex = permittedAccounts.map((acc) => {
if (isBech32Address(acc)) {
return decodeBech32Address(acc)
}
return acc
})
return permittedAccountsHex.includes(decodeBech32Address(account))
})

await Promise.all(connectedOrigins.map((origin) => this.removePermittedAccount(origin, account)))
}
Expand Down Expand Up @@ -655,7 +675,13 @@ export class PermissionsController {
?.caveats
.find((caveat) => caveat.name === 'exposedAccounts')
?.value
return exposedAccounts?.includes(account)
const accounts = exposedAccounts.map((acc) => {
if (isBech32Address(acc)) {
return decodeBech32Address(acc)
}
return acc
})
return accounts?.includes(decodeBech32Address(account))
})
.map(([domain]) => domain)

Expand Down
3 changes: 2 additions & 1 deletion app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -391,11 +391,12 @@ export default class MetamaskController extends EventEmitter {
publicConfigStore.putState(selectPublicState(memState))
}

function selectPublicState ({ isUnlocked, network, provider }) {
function selectPublicState ({ isUnlocked, hrp, network, provider }) {
return {
isUnlocked,
networkVersion: network,
chainId: selectChainId({ network, provider }),
hrp: provider ? provider.hrp : hrp,
}
}
return publicConfigStore
Expand Down
5 changes: 3 additions & 2 deletions ui/app/components/app/account-menu/account-menu.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
} from '../../../helpers/constants/routes'
import TextField from '../../ui/text-field'
import SearchIcon from '../../ui/search-icon'
import { decodeBech32Address } from '@alayanetwork/ethereumjs-util'

export default class AccountMenu extends Component {
static contextTypes = {
Expand Down Expand Up @@ -134,12 +135,12 @@ export default class AccountMenu extends Component {
return filteredIdentities.map((identity) => {
const isSelected = identity.address === selectedAddress

const simpleAddress = identity.address.substring(2).toLowerCase()
const simpleAddress = identity.address.toLowerCase()

const keyring = keyrings.find((kr) => {
return kr.accounts.includes(simpleAddress) || kr.accounts.includes(identity.address)
})
const addressDomains = addressConnectedDomainMap[identity.address] || {}
const addressDomains = addressConnectedDomainMap[decodeBech32Address(identity.address)] || {}
const iconAndNameForOpenDomain = addressDomains[originOfCurrentTab]

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ import {
getOriginOfCurrentTab,
getSelectedAddress,
} from '../../../selectors'
import { decodeBech32Address } from '@alayanetwork/ethereumjs-util'


const mapStateToProps = (state) => {
const selectedAddress = getSelectedAddress(state)
const addressConnectedDomainMap = getAddressConnectedDomainMap(state)
const originOfCurrentTab = getOriginOfCurrentTab(state)

const selectedAddressDomainMap = addressConnectedDomainMap[selectedAddress]
const selectedAddressDomainMap = addressConnectedDomainMap[decodeBech32Address(selectedAddress)]
const currentTabIsConnectedToSelectedAddress = Boolean(selectedAddressDomainMap && selectedAddressDomainMap[originOfCurrentTab])

let status
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Button from '../../ui/button'
export default class LoadingNetworkScreen extends PureComponent {
state = {
showErrorScreen: false,
showWarnScreen: true,
}

static contextTypes = {
Expand Down Expand Up @@ -69,6 +70,26 @@ export default class LoadingNetworkScreen extends PureComponent {
)
}

renderWarnScreenContent = () => {
return (
<div className="overlay__warn-screen">
<span>{ this.context.t('Important Notes') }</span>
<span>Currently Switchd to []</span>
<span>Do not transfer assets from other networks to the current wallet address!</span>
<div className="overlay__warn-button">
<Button
type="primary"
onClick={() => {
this.setState({ showWarnScreen: false })
}}
>
{ this.context.t('I already know') }
</Button>
</div>
</div>
)
}

renderErrorScreenContent = () => {
const { showNetworkDropdown, setProviderArgs, setProviderType } = this.props

Expand Down Expand Up @@ -107,7 +128,10 @@ export default class LoadingNetworkScreen extends PureComponent {
const { isLoadingNetwork } = this.props

if (isLoadingNetwork) {
this.setState({ showWarnScreen: false })
this.setState({ showErrorScreen: true })
} else {
this.setState({ showWarnScreen: true })
}
}

Expand Down
23 changes: 19 additions & 4 deletions ui/app/selectors/permissions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { getMetaMaskAccountsOrdered, getOriginOfCurrentTab, getSelectedAddress }
import {
CAVEAT_NAMES,
} from '../../../app/scripts/controllers/permissions/enums'
import { decodeBech32Address, isBech32Address } from '@alayanetwork/ethereumjs-util'

// selectors

Expand Down Expand Up @@ -96,7 +97,13 @@ export function getConnectedDomainsForSelectedAddress (state) {

forOwn(domains, (domainValue, domainKey) => {
const exposedAccounts = getAccountsFromDomain(domainValue)
if (!exposedAccounts.includes(selectedAddress)) {
const accounts = exposedAccounts.map((acc) => {
if (isBech32Address(acc)) {
return decodeBech32Address(acc)
}
return acc
})
if (!accounts.includes(decodeBech32Address(selectedAddress))) {
return
}

Expand Down Expand Up @@ -141,7 +148,9 @@ export function getAddressConnectedDomainMap (state) {
accountsMap[domainKey].forEach((address) => {

const nameToRender = name || domainKey

if (isBech32Address(address)) {
address = decodeBech32Address(address)
}
addressConnectedIconMap[address] = addressConnectedIconMap[address]
? { ...addressConnectedIconMap[address], [domainKey]: { icon, name: nameToRender } }
: { [domainKey]: { icon, name: nameToRender } }
Expand Down Expand Up @@ -199,7 +208,7 @@ export function getAccountToConnectToActiveTab (state) {
const numberOfAccounts = Object.keys(identities).length

if (connectedAccounts.length && connectedAccounts.length !== numberOfAccounts) {
if (connectedAccounts.findIndex((address) => address === selectedAddress) === -1) {
if (connectedAccounts.findIndex((address) => decodeBech32Address(address) === decodeBech32Address(selectedAddress)) === -1) {
return identities[selectedAddress]
}
}
Expand All @@ -213,9 +222,15 @@ export function getOrderedConnectedAccountsForActiveTab (state) {
const permissionsHistoryByAccount = permissionsHistory[activeTab.origin]?.['platon_accounts']?.accounts
const orderedAccounts = getMetaMaskAccountsOrdered(state)
const connectedAccounts = getPermittedAccountsForCurrentTab(state)
const connectedAccountsHex = connectedAccounts.map((acc) => {
if (isBech32Address(acc)) {
return decodeBech32Address(acc)
}
return acc
})

return orderedAccounts
.filter((account) => connectedAccounts.includes(account.address))
.filter((account) => connectedAccountsHex.includes(decodeBech32Address(account.address)))
.map((account) => ({
...account,
lastActive: permissionsHistoryByAccount?.[account.address],
Expand Down
21 changes: 13 additions & 8 deletions ui/app/store/actions.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
import abi from 'human-standard-token-abi'
import pify from 'pify'
import getBuyEthUrl from '../../../app/scripts/lib/buy-eth-url'
import { checksumAddress } from '../helpers/utils/util'
// import { checksumAddress } from '../helpers/utils/util'
import { calcTokenBalance, estimateGas } from '../pages/send/send.utils'
import ethUtil from '@alayanetwork/ethereumjs-util'
import { fetchLocale, loadRelativeTimeFormatLocaleData } from '../helpers/utils/i18n-helper'
import { getMethodDataAsync } from '../helpers/utils/transactions.util'
import { fetchSymbolAndDecimals } from '../helpers/utils/token-util'
import switchDirection from '../helpers/utils/switch-direction'
import log from 'loglevel'
import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../app/scripts/lib/enums'
import { hasUnconfirmedTransactions } from '../helpers/utils/confirm-tx.util'
import { setCustomGasLimit } from '../ducks/gas/gas.duck'
import txHelper from '../../lib/tx-helper'
import { getEnvironmentType } from '../../../app/scripts/lib/util'
import * as actionConstants from './actionConstants'
import { decodeBech32Address } from '@alayanetwork/ethereumjs-util'
import { decodeBech32Address, addHexPrefix, isBech32Address } from '@alayanetwork/ethereumjs-util'
import {
getPermittedAccountsForCurrentTab,
getSelectedAddress,
} from '../selectors'
import { switchedToUnconnectedAccount } from '../ducks/alerts/unconnected-account'
import { getUnconnectedAccountAlertEnabledness } from '../ducks/metamask/metamask'
import {
setCustomGasLimit,
fetchBasicGasEstimates,
fetchBasicGasAndTimeEstimates,
} from '../ducks/gas/gas.duck'
Expand Down Expand Up @@ -766,7 +765,7 @@ export function signTokenTx (tokenAddress, toAddress, amount, txData) {
return (dispatch) => {
dispatch(showLoadingIndication())
const token = global.eth.contract(abi).at(tokenAddress)
token.transfer(toAddress, ethUtil.addHexPrefix(amount), txData)
token.transfer(toAddress, addHexPrefix(amount), txData)
.catch((err) => {
dispatch(hideLoadingIndication())
dispatch(displayWarning(err.message))
Expand Down Expand Up @@ -1203,8 +1202,14 @@ export function showAccountDetail (address) {
const activeTabOrigin = state.activeTab.origin
const selectedAddress = getSelectedAddress(state)
const permittedAccountsForCurrentTab = getPermittedAccountsForCurrentTab(state)
const currentTabIsConnectedToPreviousAddress = Boolean(activeTabOrigin) && permittedAccountsForCurrentTab.includes(selectedAddress)
const currentTabIsConnectedToNextAddress = Boolean(activeTabOrigin) && permittedAccountsForCurrentTab.includes(address)
const permittedAccountsForCurrentTabHex = permittedAccountsForCurrentTab.map((acc) => {
if (isBech32Address(acc)) {
return decodeBech32Address(acc)
}
return acc
})
const currentTabIsConnectedToPreviousAddress = Boolean(activeTabOrigin) && permittedAccountsForCurrentTabHex.includes(decodeBech32Address(selectedAddress))
const currentTabIsConnectedToNextAddress = Boolean(activeTabOrigin) && permittedAccountsForCurrentTabHex.includes(decodeBech32Address(address))
const switchingToUnconnectedAddress = currentTabIsConnectedToPreviousAddress && !currentTabIsConnectedToNextAddress

try {
Expand Down Expand Up @@ -2198,7 +2203,7 @@ export function loadingMethodDataFinished () {

export function getContractMethodData (data = '') {
return (dispatch, getState) => {
const prefixedData = ethUtil.addHexPrefix(data)
const prefixedData = addHexPrefix(data)
const fourBytePrefix = prefixedData.slice(0, 10)
const { knownMethodData } = getState().metamask

Expand Down
31 changes: 24 additions & 7 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -300,10 +300,11 @@
integrity sha512-az1IBp25ycqsv1MVJ+iGZEiC4x9571+usvShWy8dc1LxTSUUsbRpxzOF/uENIgFHC84FpvpDAf/sAOLXq/evvg==

"@alayanetwork/inpage-provider@^6.1.0":
version "6.1.0"
resolved "https://registry.yarnpkg.com/@alayanetwork/inpage-provider/-/inpage-provider-6.1.0.tgz#cb131b700d969565a1ba47549d47871192b53a27"
integrity sha512-miB9BDbiypTcpSjHm/xAspuSmjxekpZeuEB596YwXO9Fo9jDkO9ZApYf+vYKFFhXlfXrtrlZTv8ezs7BgE6LMg==
version "6.1.1"
resolved "https://registry.yarnpkg.com/@alayanetwork/inpage-provider/-/inpage-provider-6.1.1.tgz#fd6d2f4916ae152fb218a7936e18305a90318364"
integrity sha512-NXEC+sX3TjVQVw/frdwj884FHiyRhTr86NLjOvEgJvoNXu+Bzyc+3k1m1C8yV2SGMNTAzLyPh/EqdKZ3Ltw4Gw==
dependencies:
"@alayanetwork/ethereumjs-util" "^5.2.0"
eth-json-rpc-errors "^2.0.2"
fast-deep-equal "^2.0.1"
json-rpc-engine "^5.1.5"
Expand All @@ -324,16 +325,32 @@
await-semaphore "^0.1.3"

"@alayanetwork/rpc-cap@^3.1.0":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@alayanetwork/rpc-cap/-/rpc-cap-3.1.0.tgz#2baac42dc6a09eba5cdc0bf6b034e59b1a394a64"
integrity sha512-oes+DxX2EIHF9f7loo/csav0lVbYiSfr82N5WnJw03fgW57gD07I+ds+c8tzMHaJV5h0bZ9TNX7EhjJDJwGqYQ==
version "3.1.1"
resolved "https://registry.yarnpkg.com/@alayanetwork/rpc-cap/-/rpc-cap-3.1.1.tgz#02fc4207c7868516f75dd7967cd394f8858622c8"
integrity sha512-DL5E4btWIPjM6ock2BN5+HBG+3aVTdY+SoQbF7TFiltIAY+1Z1+KZsnbSLbJDUHUWx1yZTCAYoiSbNIBsUOMtg==
dependencies:
"@alayanetwork/controllers" "^3.0.1"
"@alayanetwork/web3-utils" "^0.13.3"
"@types/bn.js" "^4.11.6"
eth-rpc-errors "^2.1.1"
is-subset "^0.1.1"
json-rpc-engine "^5.2.0"
uuid "^3.3.2"

"@alayanetwork/web3-utils@^0.13.3":
version "0.13.3"
resolved "https://registry.yarnpkg.com/@alayanetwork/web3-utils/-/web3-utils-0.13.3.tgz#f0563fa5fb09334743fde6ddc176134455e7e931"
integrity sha512-T5fWhFO+R5q/RLU7fPPW8FHA9TkQo2znQAGYdw/u9SpfA+vA/ZmYsgWm4yh+DXPzyPZqEI4w4t5tl3nCKJtevg==
dependencies:
bn.js "4.11.8"
eth-lib "0.2.7"
ethereum-bloom-filters "^1.0.6"
ethjs-unit "0.1.6"
number-to-bn "1.7.0"
randombytes "^2.1.0"
underscore "1.9.1"
utf8 "3.0.0"

"@alayanetwork/web3@^0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@alayanetwork/web3/-/web3-0.1.0.tgz#7c5262b17f499010f6b3af2dc3f4170de0a7ac8b"
Expand Down Expand Up @@ -2743,7 +2760,7 @@
dependencies:
bignumber.js "*"

"@types/bn.js@^4.11.3", "@types/bn.js@^4.11.4":
"@types/bn.js@^4.11.3", "@types/bn.js@^4.11.4", "@types/bn.js@^4.11.6":
version "4.11.6"
resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c"
integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==
Expand Down

0 comments on commit 8612191

Please sign in to comment.