Skip to content

Commit

Permalink
enhancement: persist verification state for dapp (#2357)
Browse files Browse the repository at this point in the history
* create persisted dapps store

* add verified icon to dapp list

* add migrations

* add verification icon to edit + details drawer

* add comment + fix profile version

* PR fixes

* update migrations

---------

Co-authored-by: Tuditi <[email protected]>
  • Loading branch information
MarkNerdi and Tuditi authored Apr 27, 2024
1 parent a9092a1 commit 9ac5681
Show file tree
Hide file tree
Showing 16 changed files with 202 additions and 99 deletions.
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
<script lang="ts">
import { IConnectedDapp } from '@auxiliary/wallet-connect/interface'
import { ClickableTile, NetworkAvatar } from '@ui'
import { ClickableTile, DappVerificationIcon, NetworkAvatar } from '@ui'
import { Avatar, AvatarGroup, IconName, Text } from '@bloomwalletio/ui'
import { NetworkId } from '@core/network'
import { getPersistedDappNamespacesForDapp } from '@auxiliary/wallet-connect/stores'
import { getPersistedDappNamespacesForDapp, persistedDapps } from '@auxiliary/wallet-connect/stores'
import { localize } from '@core/i18n'
import { activeProfileId } from '@core/profile/stores'
export let dapp: IConnectedDapp
export let disabled: boolean = false
export let onClick: (() => unknown) | undefined = undefined
$: networkIds = Object.values(
dapp.session?.namespaces ?? getPersistedDappNamespacesForDapp(dapp.metadata?.url)?.supported ?? {}
dapp.session?.namespaces ?? getPersistedDappNamespacesForDapp(dapp.metadata?.url ?? '')?.supported ?? {}
).flatMap((namespace) => namespace.chains as NetworkId[])
$: verifiedState = $activeProfileId
? $persistedDapps[$activeProfileId]?.[dapp.metadata?.url ?? '']?.verificationState
: undefined
</script>

<ClickableTile
Expand All @@ -28,14 +33,19 @@
<Avatar icon={IconName.Link} size="lg" surface={0} />
{/if}
<div class="flex flex-col overflow-hidden">
<Text type="body2" truncate>
<Text type="body2" truncate align="left">
{dapp.metadata?.name ?? localize('general.unknown')}
</Text>
{#if dapp.metadata?.url}
<Text type="sm" textColor="secondary" truncate>
{dapp.metadata?.url}
</Text>
{/if}
<div class="flex flex-row items-center gap-1">
{#if verifiedState}
<DappVerificationIcon {verifiedState} />
{/if}
{#if dapp.metadata?.url}
<Text type="sm" textColor="secondary" truncate>
{dapp.metadata?.url}
</Text>
{/if}
</div>
</div>
</div>
<div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import { localize } from '@core/i18n'
import { Router } from '@core/router'
import {
getPersistedDappNamespacesForDapp,
updateSupportedDappNamespacesForDapp,
selectedDapp,
sessionProposal,
getPersistedDapp,
} from '@auxiliary/wallet-connect/stores'
import { onMount } from 'svelte'
import { buildSupportedNamespacesFromSelections } from '@auxiliary/wallet-connect/actions'
Expand All @@ -21,9 +21,7 @@
export let disableContinue: boolean
$: dappMetadata = $selectedDapp?.metadata ?? ($sessionProposal?.params.proposer.metadata as IDappMetadata)
$: persistedSupportedNamespaces = dappMetadata
? getPersistedDappNamespacesForDapp(dappMetadata.url)?.supported
: undefined
$: persistedDapp = dappMetadata ? getPersistedDapp(dappMetadata.url) : undefined
$: requiredNamespaces =
$selectedDapp?.session?.requiredNamespaces ?? $sessionProposal?.params.requiredNamespaces ?? {}
$: optionalNamespaces =
Expand All @@ -34,7 +32,7 @@
selections,
requiredNamespaces,
optionalNamespaces,
persistedSupportedNamespaces
persistedDapp?.namespaces.supported
)
updateSupportedDappNamespacesForDapp(dappMetadata.url, updatedNamespace)
if ($selectedDapp?.session) {
Expand All @@ -56,11 +54,15 @@

<DrawerTemplate title={localize(`views.dashboard.drawers.${titleLocale}.title`)} {drawerRouter}>
<div class="w-full h-full flex flex-col">
<DappInfo metadata={dappMetadata} />
<DappInfo metadata={dappMetadata} verifiedState={persistedDapp?.verificationState} />

<div class="p-6 flex-grow overflow-hidden">
<div class="h-full flex flex-col gap-8 overflow-scroll">
<slot {persistedSupportedNamespaces} {requiredNamespaces} {optionalNamespaces} />
<slot
persistedSupportedNamespaces={persistedDapp?.namespaces.supported}
{requiredNamespaces}
{optionalNamespaces}
/>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { connectedDapps, persistedDappNamespaces, setSelectedDapp } from '@auxiliary/wallet-connect/stores'
import { connectedDapps, persistedDapps, setSelectedDapp } from '@auxiliary/wallet-connect/stores'
import { Button, IconName, Tabs, Text } from '@bloomwalletio/ui'
import { DappListActionsMenu, DrawerTemplate, EmptyListPlaceholder } from '@components'
import { localize } from '@core/i18n'
Expand Down Expand Up @@ -27,7 +27,7 @@
let selectedIndex = 0
$: connectedDappsForProfile = $connectedDapps.filter(
(dapp) => !!$persistedDappNamespaces[$activeProfileId as string]?.[dapp.metadata?.url ?? '']
(dapp) => !!$persistedDapps[$activeProfileId as string]?.[dapp.metadata?.url ?? '']
)
$: displayedDapps = connectedDappsForProfile.filter(
(dapp) => (selectedIndex === 0 && !!dapp.session) || (selectedIndex === 1 && !dapp.session)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { getPersistedDappNamespacesForDapp, selectedDapp } from '@auxiliary/wallet-connect/stores'
import { getPersistedDapp, selectedDapp } from '@auxiliary/wallet-connect/stores'
import { DrawerTemplate } from '@components/drawers'
import { Router } from '@core/router'
import { onMount } from 'svelte'
Expand All @@ -15,9 +15,7 @@
const localeKey = 'views.dashboard.drawers.dapps.details'
const dapp = structuredClone($selectedDapp) as IConnectedDapp
$: persistedSupportedNamespaces = dapp?.metadata
? getPersistedDappNamespacesForDapp(dapp?.metadata.url)?.supported
: undefined
$: persistedDapp = dapp?.metadata ? getPersistedDapp(dapp?.metadata.url) : undefined
onMount(() => {
if (!$selectedDapp) {
Expand All @@ -32,7 +30,7 @@
<DappActionsMenu {drawerRouter} {dapp} />
</div>
<div class="w-full h-full flex flex-col space-y-6 overflow-hidden">
<DappInfo metadata={dapp.metadata} />
<DappInfo metadata={dapp.metadata} verifiedState={persistedDapp?.verificationState} />

<div class="flex-grow overflow-hidden">
<div class="h-full space-y-6 overflow-scroll px-6 pb-4">
Expand All @@ -42,11 +40,11 @@
orientation="vertical"
/>
{/if}
{#if persistedSupportedNamespaces}
{#if persistedDapp?.namespaces.supported}
<ConnectionSummary
requiredNamespaces={dapp.session?.requiredNamespaces}
editable={!!dapp.session}
{persistedSupportedNamespaces}
persistedSupportedNamespaces={persistedDapp?.namespaces.supported}
{drawerRouter}
/>
{/if}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { IAccountState } from '@core/account'
import { persistDappNamespacesForDapp } from '../stores'
import { persistDapp } from '../stores'
import { approveSession } from './approveSession'
import { buildSupportedNamespacesFromSelections } from './buildSupportedNamespaceFromSelections'
import { clearOldPairings } from './clearOldPairings'
import { ISelections } from '../interface'
import { Web3WalletTypes } from '@walletconnect/web3wallet'
import { SupportedNamespaces } from '../types'
import { DappVerification } from '../enums'

export async function connectToDapp(
selections: ISelections,
Expand All @@ -25,5 +26,11 @@ export async function connectToDapp(

await clearOldPairings(dappUrl)
await approveSession(sessionProposal, supportedNamespaces, account)
persistDappNamespacesForDapp(dappUrl, supportedNamespaces, requiredNamespaces, optionalNamespaces)

const verificationState = sessionProposal.verifyContext.verified
persistDapp(
dappUrl,
verificationState.isScam ? DappVerification.Scam : (verificationState.validation as DappVerification),
{ supported: supportedNamespaces, required: requiredNamespaces, optional: optionalNamespaces }
)
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
connectedDapps,
getPersistedDappNamespacesForDapp,
getWalletClient,
removeDappNamespacesForDapp,
} from '../stores'
import { connectedDapps, getWalletClient, getPersistedDapp, removePersistedDapp } from '../stores'
import { get } from 'svelte/store'

export function removeAllDisconnectedDapps(): void {
Expand All @@ -13,12 +8,12 @@ export function removeAllDisconnectedDapps(): void {
}

const connectedDappsForProfile = get(connectedDapps).filter(
(dapp) => dapp.metadata?.url && !!getPersistedDappNamespacesForDapp(dapp.metadata.url) && !dapp.session
(dapp) => !!getPersistedDapp(dapp.metadata?.url ?? '') && !dapp.session
)

for (const dapp of connectedDappsForProfile) {
if (dapp.metadata) {
removeDappNamespacesForDapp(dapp.metadata.url)
removePersistedDapp(dapp.metadata.url)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getWalletClient, removeDappNamespacesForDapp, setConnectedDapps } from '../stores'
import { getWalletClient, removePersistedDapp, setConnectedDapps } from '../stores'
import { getSdkError } from '@walletconnect/utils'
import { IConnectedDapp } from '../interface'
import { handleError } from '@core/error/handlers'
Expand All @@ -20,7 +20,7 @@ export async function removeDapp(dapp: IConnectedDapp): Promise<void> {
handleError(err)
} finally {
if (dapp.metadata) {
removeDappNamespacesForDapp(dapp.metadata.url)
removePersistedDapp(dapp.metadata.url)
}
setConnectedDapps()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { NetworkId, getEvmNetwork } from '@core/network'
import { JsonRpcResponse } from '@walletconnect/jsonrpc-types'
import { getSdkError } from '@walletconnect/utils'
import { Web3WalletTypes } from '@walletconnect/web3wallet'
import { getConnectedDappByOrigin, getWalletClient, setConnectedDapps } from '../stores'
import { getConnectedDappByOrigin, getWalletClient, setConnectedDapps, updateVerificationStateForDapp } from '../stores'
import { CallbackParameters } from '../types'
import { handleEthSignTypedData } from './eth_signTypedData.handler'
import { handleEthTransaction } from './eth_transaction.handler'
Expand All @@ -20,9 +20,10 @@ export function onSessionRequest(event: Web3WalletTypes.SessionRequest): void {
const method = request.method as RpcMethod

const dapp = getConnectedDappByOrigin(verifyContext.verified.origin)
const verifiedState: DappVerification = verifyContext.verified.isScam
const verifiedState = verifyContext.verified.isScam
? DappVerification.Scam
: (verifyContext.verified.validation as DappVerification)
updateVerificationStateForDapp(verifyContext.verified.origin, verifiedState)

function returnResponse({ result, error }: CallbackParameters): void {
const response: JsonRpcResponse | undefined = result
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './connected-dapps.store'
export * from './wallet-client.store'
export * from './persisted-dapps.store'
export * from './persisted-dapp-namespaces.store'
export * from './selected-dapp.store'
export * from './session-proposal.store'
Original file line number Diff line number Diff line change
@@ -1,67 +1,11 @@
import { persistent } from '@core/utils/store'
import { Writable, get } from 'svelte/store'
import { SupportedNamespaces } from '../types'
import { getActiveProfile } from '@core/profile/stores'
import { ProposalTypes } from '@walletconnect/types'
import { Writable } from 'svelte/store'
import { IPersistedNamespaces } from '../interface'

interface IPersistedNamespacesStore {
[profileId: string]: {
[dappOriginUrl: string]: IPersistedNamespaces
}
}

// Keeping this store for for backwards compatibility for 1.0.1
export const persistedDappNamespaces: Writable<IPersistedNamespacesStore> = persistent('persistedDappNamespaces', {})

export function getPersistedDappNamespacesForDapp(dappOriginUrl: string): IPersistedNamespaces | undefined {
const profileId = getActiveProfile()?.id
return get(persistedDappNamespaces)?.[profileId]?.[dappOriginUrl]
}

export function persistDappNamespacesForDapp(
dappOriginUrl: string,
supported: SupportedNamespaces,
required: ProposalTypes.RequiredNamespaces,
optional: ProposalTypes.OptionalNamespaces
): void {
const profileId = getActiveProfile()?.id

return persistedDappNamespaces.update((state) => {
if (!state[profileId]) {
state[profileId] = {}
}
state[profileId][dappOriginUrl] = { supported, required, optional }

return state
})
}

export function updateSupportedDappNamespacesForDapp(dappOriginUrl: string, supported: SupportedNamespaces): void {
const profileId = getActiveProfile()?.id

return persistedDappNamespaces.update((state) => {
const persistedNamespaces = state?.[profileId]?.[dappOriginUrl]

if (!persistedNamespaces) {
return state
}

state[profileId][dappOriginUrl] = {
...persistedNamespaces,
supported: { ...persistedNamespaces.supported, ...supported },
}
return state
})
}

export function removeDappNamespacesForDapp(dappOriginUrl: string): void {
const profileId = getActiveProfile()?.id

return persistedDappNamespaces.update((state) => {
if (!state[profileId]) {
return state
}
delete state[profileId][dappOriginUrl]
return state
})
}
Loading

0 comments on commit 9ac5681

Please sign in to comment.