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

feat(wallet): add Coinshift appCode #3372

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion libs/wallet/src/api/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ export function useWalletDisplayedAddress(): string {
}

export function useGnosisSafeInfo(): GnosisSafeInfo | undefined {
return useAtomValue(gnosisSafeInfoAtom)
const v = useAtomValue(gnosisSafeInfoAtom)
console.log(`fuuuuck`, v)
return v
}

export function useIsBundlingSupported(): boolean {
Expand Down
2 changes: 2 additions & 0 deletions libs/wallet/src/api/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,5 @@ export const walletDisplayedAddress = atom((get) => {
})

export const hwAccountIndexAtom = atomWithStorage<number>('hw-account-index:v1', 0)

export const iframeReferrerAtom = atomWithStorage<string>('iframeReferrerAtom:v0', '')
74 changes: 53 additions & 21 deletions libs/wallet/src/web3-react/hooks/useWalletMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,9 @@ import { default as AlphaImage } from '../../api/assets/alpha.svg'
import { ConnectionType } from '../../api/types'
import { getIsAlphaWallet } from '../../api/utils/connection'
import { getWeb3ReactConnection } from '../utils/getWeb3ReactConnection'
import { useGnosisSafeInfo } from '../../api/hooks'

const WC_DESKTOP_GNOSIS_SAFE_APP_NAME = 'WalletConnect Safe App'
const WC_MOBILE_GNOSIS_SAFE_APP_NAME = 'Safe'
const SAFE_APP_NAME = 'Safe App'
const GNOSIS_SAFE_APP_NAME = 'Gnosis Safe App'
const SAFE_WALLET_NAME = 'Safe{Wallet}'
const SAFE_WALLET_IOS = 'Safe (iOS)'
const GNOSIS_APP_NAMES = [
SAFE_APP_NAME,
GNOSIS_SAFE_APP_NAME,
WC_DESKTOP_GNOSIS_SAFE_APP_NAME,
WC_MOBILE_GNOSIS_SAFE_APP_NAME,
SAFE_WALLET_NAME,
SAFE_WALLET_IOS,
]

const SAFE_ICON_URL = 'https://app.safe.global/favicon.ico'

Expand All @@ -47,6 +35,47 @@ function getWcWalletIcon(meta: any) {
return meta.icons?.length > 0 ? meta.icons[0] : undefined
}

function getSafeAppHostname(): string {
// Only available on chrome based browsers https://caniuse.com/?search=ancestorOrigins
const ancestorOrigins = window.location.ancestorOrigins?.[0]
// Might not be correctly populated on all occasions
const referrer = document.referrer

console.log(`getSafeAppHostname::referrer: `, ancestorOrigins, referrer)
return ancestorOrigins || referrer
}

const ALTERNATIVE_SAFE_APPS_METADATA: Record<string, WalletMetaData> = {
'safe\\.global': METADATA_SAFE,
'coinshift\\.xyz': {
walletName: 'Coinshift',
// TODO: get the real one from them
icon: 'https://uploads-ssl.webflow.com/640888e3259d86996ed8c6dd/643e7f44d3a00404bc08adfd_favicon-light%20theme.svg',
},
'ambire\\.com': {
walletName: 'Ambire',
// TODO: get the real one from them
icon: 'https://www.ambire.com/favicon.png',
},
}

function getSafeAppMetadata(): WalletMetaData {
const hostname = getSafeAppHostname()

// iterate over alternative safe apps metadata
for (const [hostnamePattern, metadata] of Object.entries(ALTERNATIVE_SAFE_APPS_METADATA)) {
// if hostname matches the pattern
if (new RegExp(hostnamePattern).test(hostname)) {
return metadata
}
}
// Fallback to hostname, if available, and Safe's icon because it's still a Safe context
return {
walletName: hostname || SAFE_APP_NAME,
icon: SAFE_ICON_URL,
}
}

function getWcPeerMetadata(provider: any | undefined): WalletMetaData {
// fix for this https://github.com/gnosis/cowswap/issues/1929
const defaultOutput = { walletName: undefined, icon: undefined }
Expand Down Expand Up @@ -88,7 +117,7 @@ export function useWalletMetaData(): WalletMetaData {
}

if (connectionType === ConnectionType.GNOSIS_SAFE) {
return METADATA_SAFE
return getSafeAppMetadata()
}

return METADATA_DISCONNECTED
Expand All @@ -100,21 +129,23 @@ export function useWalletMetaData(): WalletMetaData {
* It'll be false if connected to Safe wallet via WalletConnect
*/
export function useIsSafeApp(): boolean {
const { walletName } = useWalletMetaData()
const isSafeWallet = useIsSafeWallet()

return walletName === SAFE_APP_NAME
if (!isSafeWallet) {
return false
}

// Will only be a SafeApp if within an iframe
// Which means, window.parent is different than window
return window?.parent !== window
}

/**
* Detects whether the currently connected wallet is a Safe wallet
* regardless of the connection method (WalletConnect or inside Safe as an App)
*/
export function useIsSafeWallet(): boolean {
const { walletName } = useWalletMetaData()

if (!walletName) return false

return GNOSIS_APP_NAMES.includes(walletName.trim())
return !!useGnosisSafeInfo()
}

/**
Expand All @@ -125,5 +156,6 @@ export function useIsSafeViaWc(): boolean {
const isSafeApp = useIsSafeApp()
const isSafeWallet = useIsSafeWallet()

console.log(`fuuuuuck`, { isSafeWallet, isSafeApp })
return isSafeWallet && !isSafeApp
}
26 changes: 21 additions & 5 deletions libs/wallet/src/web3-react/updater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { getSafeInfo } from '@cowprotocol/core'
import { getCurrentChainIdFromUrl } from '@cowprotocol/common-utils'

import { useSafeAppsSdkInfo } from './hooks/useSafeAppsSdkInfo'
import { useIsSafeWallet, useWalletMetaData } from './hooks/useWalletMetadata'
import { useWalletMetaData } from './hooks/useWalletMetadata'

import { gnosisSafeInfoAtom, walletDetailsAtom, walletInfoAtom } from '../api/state'
import { gnosisSafeInfoAtom, iframeReferrerAtom, walletDetailsAtom, walletInfoAtom } from '../api/state'
import { GnosisSafeInfo, WalletDetails, WalletInfo } from '../api/types'
import { getWalletType } from '../api/utils/getWalletType'
import { getWalletTypeLabel } from '../api/utils/getWalletTypeLabel'
Expand Down Expand Up @@ -61,12 +61,11 @@ function _useWalletDetails(account?: string): WalletDetails {
function _useSafeInfo(walletInfo: WalletInfo): GnosisSafeInfo | undefined {
const { provider } = useWeb3React()
const { account, chainId } = walletInfo
const isSafeConnected = useIsSafeWallet()
const [safeInfo, setSafeInfo] = useState<GnosisSafeInfo>()
const { isReadOnly } = useSafeAppsSdkInfo() || {}

useEffect(() => {
if (chainId && account && isSafeConnected && provider) {
if (chainId && account && provider) {
getSafeInfo(chainId, account, provider)
.then((_safeInfo) =>
setSafeInfo({
Expand All @@ -80,7 +79,7 @@ function _useSafeInfo(walletInfo: WalletInfo): GnosisSafeInfo | undefined {
} else {
setSafeInfo(undefined)
}
}, [setSafeInfo, chainId, account, isSafeConnected, provider, isReadOnly])
}, [setSafeInfo, chainId, account, provider, isReadOnly])

return safeInfo
}
Expand All @@ -93,6 +92,13 @@ export function WalletUpdater() {
const setWalletInfo = useSetAtom(walletInfoAtom)
const setWalletDetails = useSetAtom(walletDetailsAtom)
const setGnosisSafeInfo = useSetAtom(gnosisSafeInfoAtom)
const setIframeReferrerAtom = useSetAtom(iframeReferrerAtom)

useEffect(() => {
const referrer = getIframeReferrer()
console.log('[WalletUpdater] setIframeReferrerAtom', referrer)
setIframeReferrerAtom(referrer)
}, [setIframeReferrerAtom])

// Update wallet info
useEffect(() => {
Expand All @@ -118,3 +124,13 @@ export function WalletUpdater() {

return null
}

function getIframeReferrer(): string {
// Only available on chrome based browsers https://caniuse.com/?search=ancestorOrigins
const ancestorOrigins = window.location.ancestorOrigins?.[0]
// Might not be correctly populated on all occasions
const referrer = document.referrer

console.log(`getIframeReferrer: ancestor: '${ancestorOrigins}' referrer: '${referrer}'`)
return ancestorOrigins || referrer
}
Loading