Skip to content

Commit

Permalink
chore: merge develop
Browse files Browse the repository at this point in the history
  • Loading branch information
0xdef1cafe committed May 24, 2022
2 parents 4017fc3 + aa6051a commit 8e0b91d
Show file tree
Hide file tree
Showing 11 changed files with 230 additions and 1 deletion.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@shapeshiftoss/hdwallet-native": "^1.21.2",
"@shapeshiftoss/hdwallet-native-vault": "^1.21.2",
"@shapeshiftoss/hdwallet-portis": "^1.21.2",
"@shapeshiftoss/hdwallet-xdefi": "^1.21.2",
"@shapeshiftoss/investor-foxy": "^3.0.0",
"@shapeshiftoss/investor-yearn": "^2.0.0",
"@shapeshiftoss/logger": "^1.1.2",
Expand Down
22 changes: 22 additions & 0 deletions src/assets/translations/en/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,28 @@
"body": "Unable to connect Portis wallet"
}
},
"xdefi": {
"errors": {
"unknown": "An unexpected error occurred communicating with XDEFI",
"connectFailure": "Unable to connect XDEFI wallet",
"network": "XDEFI isn't set to Ethereum Mainnet",
"multipleWallets": "Detected Ethereum provider is not XDEFI. Do you have multiple wallets installed?"
},
"connect": {
"header": "Pair XDEFI",
"body": "Click Pair and login to XDEFI from the popup window",
"button": "Pair"
},
"failure": {
"header": "Error",
"body": "Unable to connect XDEFI wallet"
},
"redirect": {
"header": "Open in XDEFI App",
"body": "Click to open ShapeShift dashboard in XDEFI",
"button": "Open"
}
},
"shapeShift": {
"load": {
"error": {
Expand Down
32 changes: 32 additions & 0 deletions src/components/Icons/XDEFIIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { createIcon } from '@chakra-ui/react'

export const XDEFIIcon = createIcon({
displayName: 'XDeFiIcon',
path: (
<svg
width='350'
height='350'
viewBox='0 0 24 24'
fill='none'
xmlns='http://www.w3.org/2000/svg'
>
<path
d='M14.2627 13.4013C12.4227 14.5307 9.95987 15.1124 7.46558 14.9881C5.36844 14.8865 3.64844 14.1411 2.60844 12.9157C1.69416 11.8201 1.33987 10.3745 1.57987 8.71143C1.66121 8.15874 1.82791 7.62166 2.07415 7.11896L2.10844 7.04837C2.9717 5.40595 4.25282 4.01397 5.82573 3.00942C7.39864 2.00486 9.20913 1.42236 11.079 1.31924C12.9489 1.21611 14.8137 1.59592 16.49 2.42128C18.1662 3.24665 19.5961 4.48912 20.6389 6.02641C21.6817 7.56371 22.3015 9.34285 22.4373 11.1887C22.5731 13.0346 22.2202 14.8836 21.4133 16.5538C20.6064 18.224 19.3734 19.6577 17.8355 20.714C16.2977 21.7702 14.508 22.4126 12.6427 22.5778L12.757 23.8738C14.8513 23.6894 16.8608 22.9691 18.5877 21.7837C20.3146 20.5984 21.6992 18.9889 22.6051 17.1138C23.511 15.2387 23.907 13.1627 23.7541 11.0904C23.6011 9.01808 22.9045 7.02088 21.7328 5.29555C20.5612 3.57022 18.9549 2.1763 17.0723 1.25111C15.1896 0.325909 13.0956 -0.0986411 10.9964 0.0192787C8.89722 0.137198 6.86533 0.79352 5.10091 1.92359C3.33649 3.05365 1.90042 4.61848 0.934157 6.4639L0.888441 6.55707C0.582976 7.1809 0.37674 7.84756 0.277013 8.53354C-0.00870132 10.5608 0.434153 12.3651 1.5913 13.7542C2.85701 15.2733 4.91701 16.1768 7.38844 16.2954C10.397 16.4451 13.3884 15.6347 15.5113 14.1439L14.2627 13.4013Z'
fill='#2041E0'
/>
<path
d='M16.78 14.875C15.5829 15.9028 12.8 17.7663 8.18286 18.0204C3.01429 18.3028 0.860001 16.6425 0.840001 16.6256L0.422856 17.1338L0.842856 16.6341L0 17.6336C0.0914286 17.7098 2.15714 19.3588 7.00857 19.3588C7.40571 19.3588 7.82286 19.3588 8.25714 19.3249C13.8371 19.0171 16.9029 16.6115 17.9714 15.5837L16.78 14.875Z'
fill='#2041E0'
/>
<path
d='M19.0199 16.2191C18.312 17.1386 17.4407 17.9232 16.4485 18.5344C12.9513 20.7649 8.50275 21.0529 5.38847 20.8976L5.32275 22.1993C5.84561 22.2247 6.34847 22.236 6.83704 22.236C15.6199 22.236 19.1685 18.2831 20.1599 16.8713L19.017 16.2078'
fill='#2041E0'
/>
<path
d='M18.6856 11.2923C19.2679 11.2923 19.7399 10.8258 19.7399 10.2504C19.7399 9.67496 19.2679 9.2085 18.6856 9.2085C18.1034 9.2085 17.6313 9.67496 17.6313 10.2504C17.6313 10.8258 18.1034 11.2923 18.6856 11.2923Z'
fill='#2041E0'
/>
</svg>
),
viewBox: '0 0 318.6 318.6',
})
1 change: 1 addition & 0 deletions src/context/WalletProvider/KeyManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export enum KeyManager {
MetaMask = 'metamask',
Portis = 'portis',
Demo = 'demo',
XDefi = 'xdefi',
}
25 changes: 25 additions & 0 deletions src/context/WalletProvider/WalletProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,31 @@ export const WalletProvider = ({ children }: { children: React.ReactNode }): JSX
}
dispatch({ type: WalletActions.SET_LOCAL_WALLET_LOADING, payload: false })
break
case KeyManager.XDefi:
const localXDEFIWallet = await state.adapters.get(KeyManager.XDefi)?.pairDevice()
if (localXDEFIWallet) {
const { name, icon } = SUPPORTED_WALLETS[KeyManager.XDefi]
try {
await localXDEFIWallet.initialize()
const deviceId = await localXDEFIWallet.getDeviceID()
dispatch({
type: WalletActions.SET_WALLET,
payload: {
wallet: localXDEFIWallet,
name,
icon,
deviceId,
},
})
dispatch({ type: WalletActions.SET_IS_CONNECTED, payload: true })
} catch (e) {
disconnect()
}
} else {
disconnect()
}
dispatch({ type: WalletActions.SET_LOCAL_WALLET_LOADING, payload: false })
break
default:
/**
* The fall-through case also handles clearing
Expand Down
113 changes: 113 additions & 0 deletions src/context/WalletProvider/XDEFI/components/Connect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { XDEFIHDWallet } from '@shapeshiftoss/hdwallet-xdefi'
import React, { useState } from 'react'
import { RouteComponentProps } from 'react-router-dom'
import { ActionTypes, WalletActions } from 'context/WalletProvider/actions'
import { KeyManager } from 'context/WalletProvider/KeyManager'
import { setLocalWalletTypeAndDeviceId } from 'context/WalletProvider/local-wallet'
import { useWallet } from 'hooks/useWallet/useWallet'

import { ConnectModal } from '../../components/ConnectModal'
import { LocationState } from '../../NativeWallet/types'
import { XDEFIConfig } from '../config'

export interface XDEFISetupProps
extends RouteComponentProps<
{},
any, // history
LocationState
> {
dispatch: React.Dispatch<ActionTypes>
}

export const XDEFIConnect = ({ history }: XDEFISetupProps) => {
const { dispatch, state } = useWallet()
const [loading, setLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
let provider: any

// eslint-disable-next-line no-sequences
const setErrorLoading = (e: string | null) => (setError(e), setLoading(false))

const pairDevice = async () => {
setError(null)
setLoading(true)

try {
provider = (globalThis as any).xfi && (globalThis as any).xfi.ethereum
} catch (error) {
throw new Error('walletProvider.xdefi.errors.connectFailure')
}

if (state.adapters && state.adapters?.has(KeyManager.XDefi)) {
try {
const wallet = (await state.adapters.get(KeyManager.XDefi)?.pairDevice()) as
| XDEFIHDWallet
| undefined
if (!wallet) {
setErrorLoading('walletProvider.errors.walletNotFound')
throw new Error('Call to hdwallet-xdefi::pairDevice returned null or undefined')
}

const { name, icon } = XDEFIConfig

const deviceId = await wallet.getDeviceID()

if (provider !== (globalThis as any).xfi.ethereum) {
throw new Error('walletProvider.xdefi.errors.multipleWallets')
}

if (provider?.chainId !== 1) {
throw new Error('walletProvider.xdefi.errors.network')
}

// Hack to handle XDEFI account changes
//TODO: handle this properly
const resetState = () => dispatch({ type: WalletActions.RESET_STATE })
provider?.on?.('accountsChanged', resetState)
provider?.on?.('chainChanged', resetState)

const oldDisconnect = wallet.disconnect.bind(wallet)
wallet.disconnect = () => {
provider?.removeListener?.('accountsChanged', resetState)
provider?.removeListener?.('chainChanged', resetState)
return oldDisconnect()
}

await wallet.initialize()

dispatch({
type: WalletActions.SET_WALLET,
payload: { wallet, name, icon, deviceId },
})
dispatch({ type: WalletActions.SET_IS_CONNECTED, payload: true })
setLocalWalletTypeAndDeviceId(KeyManager.XDefi, deviceId)
dispatch({ type: WalletActions.SET_WALLET_MODAL, payload: false })
} catch (e: any) {
if (e?.message?.startsWith('walletProvider.')) {
console.error('XDEFI Connect: There was an error initializing the wallet', e)
setErrorLoading(e?.message)
} else {
setErrorLoading('walletProvider.xdefi.errors.unknown')
history.push('/xdefi/failure')
// Safely navigate user to website if XDEFI is not found
if (e?.message === 'XDEFI provider not found') {
const newWindow = window.open('https://xdefi.io', '_blank', 'noopener noreferrer')
if (newWindow) newWindow.opener = null
}
}
}
}
setLoading(false)
}

return (
<ConnectModal
headerText={'walletProvider.xdefi.connect.header'}
bodyText={'walletProvider.xdefi.connect.body'}
buttonText={'walletProvider.xdefi.connect.button'}
pairDevice={pairDevice}
loading={loading}
error={error}
/>
)
}
10 changes: 10 additions & 0 deletions src/context/WalletProvider/XDEFI/components/Failure.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { FailureModal } from 'context/WalletProvider/components/FailureModal'

export const XDEFIFailure = () => {
return (
<FailureModal
headerText={'walletProvider.xdefi.failure.header'}
bodyText={'walletProvider.xdefi.failure.body'}
></FailureModal>
)
}
8 changes: 8 additions & 0 deletions src/context/WalletProvider/XDEFI/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { XDEFIAdapter } from '@shapeshiftoss/hdwallet-xdefi'
import { XDEFIIcon } from 'components/Icons/XDEFIIcon'

export const XDEFIConfig = {
adapter: XDEFIAdapter,
icon: XDEFIIcon,
name: 'XDEFI',
}
10 changes: 10 additions & 0 deletions src/context/WalletProvider/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ import { NativeConfig } from './NativeWallet/config'
import { PortisConnect } from './Portis/components/Connect'
import { PortisFailure } from './Portis/components/Failure'
import { PortisConfig } from './Portis/config'
import { XDEFIConnect } from './XDEFI/components/Connect'
import { XDEFIFailure } from './XDEFI/components/Failure'
import { XDEFIConfig } from './XDEFI/config'

export interface SupportedWalletInfo {
adapter: any
Expand Down Expand Up @@ -89,6 +92,13 @@ export const SUPPORTED_WALLETS: Record<KeyManager, SupportedWalletInfo> = {
{ path: '/portis/failure', component: PortisFailure },
],
},
[KeyManager.XDefi]: {
...XDEFIConfig,
routes: [
{ path: '/xdefi/connect', component: XDEFIConnect },
{ path: '/xdefi/failure', component: XDEFIFailure },
],
},
[KeyManager.Demo]: {
...DemoConfig,
routes: [],
Expand Down
1 change: 0 additions & 1 deletion src/hooks/useBalanceChartData/useBalanceChartData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,6 @@ export const useBalanceChartData: UseBalanceChartData = args => {
const hasNoDeviceId = isNil(walletInfo?.deviceId)
const hasNoAssetIds = !assetIds.length
const hasNoPriceHistoryData = isEmpty(cryptoPriceHistoryData) || !fiatPriceHistoryData?.length

if (hasNoDeviceId || hasNoAssetIds || hasNoPriceHistoryData) {
return setBalanceChartDataLoading(true)
}
Expand Down
8 changes: 8 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4004,6 +4004,14 @@
p-lazy "^3.1.0"
web3 "^1.5.1"

"@shapeshiftoss/hdwallet-xdefi@^1.21.2":
version "1.22.0"
resolved "https://registry.yarnpkg.com/@shapeshiftoss/hdwallet-xdefi/-/hdwallet-xdefi-1.22.0.tgz#74b39347bb39d165cdc4cc0a90b786b2bef7a6d2"
integrity sha512-XsczkfSteFLhNNgWEKiOqJO6ZPWTwJB9jevwxPks+yOzk4E/tEoGRRyybI3BJgnmnqCghb+7OwbIAhEnMgf4dA==
dependencies:
"@shapeshiftoss/hdwallet-core" "1.22.0"
lodash "^4.17.21"

"@shapeshiftoss/investor-foxy@^3.0.0":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@shapeshiftoss/investor-foxy/-/investor-foxy-3.0.1.tgz#64ae368f117ad98c5933b7bc2baff5798e880641"
Expand Down

0 comments on commit 8e0b91d

Please sign in to comment.