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: add walletconnect notify api #2512

Merged
merged 12 commits into from
May 17, 2024
6 changes: 3 additions & 3 deletions packages/desktop/features/onboarding.features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const onboardingFeaturesForIota: IOnboardingFeaturesForNetwork = {
enabled: false,
},
defaultEvmChains: {
enabled: false,
enabled: true,
},
}

Expand Down Expand Up @@ -92,7 +92,7 @@ const onboardingFeaturesForShimmer: IOnboardingFeaturesForNetwork = {
enabled: true,
},
defaultEvmChains: {
enabled: false,
enabled: true,
},
}

Expand Down Expand Up @@ -233,7 +233,7 @@ const onboardingFeaturesForCustom: IOnboardingFeaturesForNetwork = {
enabled: true,
},
defaultEvmChains: {
enabled: false,
enabled: true,
},
}

Expand Down
6 changes: 6 additions & 0 deletions packages/desktop/features/wallet-connect.features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ import { IWalletConnectFeatures } from '@lib/features/interfaces'

const walletConnectFeatures: IWalletConnectFeatures = {
enabled: true,
web3Wallet: {
enabled: true,
},
notifications: {
enabled: true,
},
}

export default walletConnectFeatures
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<script lang="ts">
import { LogoName } from '@auxiliary/logo'
import { IconButton, IconName } from '@bloomwalletio/ui'
import { Button, IconButton, IconName, Pill } from '@bloomwalletio/ui'
import { ProfileActionsMenu, SidebarTab } from '@components'
import { APP_STAGE, AppStage } from '@core/app'
import { localize } from '@core/i18n'
import { SupportedStardustNetworkId } from '@core/network'
import { SupportedNetworkId, SupportedStardustNetworkId, getEvmNetwork } from '@core/network'
import { activeProfile, isSoftwareProfile } from '@core/profile/stores'
import {
DashboardRoute,
Expand All @@ -22,6 +22,11 @@
import LedgerStatusTile from './LedgerStatusTile.svelte'
import StrongholdStatusTile from './StrongholdStatusTile.svelte'
import { BackupToast, VersionToast } from './toasts'
import { selectedAccount } from '@core/account/stores'
import { checkActiveProfileAuth } from '@core/profile/actions'
import { LedgerAppName } from '@core/ledger/enums'
import { handleError } from '@core/error/handlers'
import { notificationsManager } from '@auxiliary/wallet-connect/notifications/classes'

let expanded = true
function toggleExpand(): void {
Expand Down Expand Up @@ -134,6 +139,20 @@
$governanceRouter.reset()
$settingsRouter.reset()
}

async function enableNotifications(): Promise<void> {
try {
await checkActiveProfileAuth(LedgerAppName.Ethereum)
} catch (error) {
return
}

try {
notificationsManager.registerAccount($selectedAccount, getEvmNetwork(SupportedNetworkId.Ethereum))
} catch (err) {
handleError(err)
}
}
</script>

<aside class:expanded class="flex flex-col justify-between">
Expand Down Expand Up @@ -167,6 +186,12 @@

{#if expanded}
<dashboard-sidebar-tiles class="w-full flex flex-col space-y-2">
{#if notificationsManager?.isRegistered($selectedAccount, getEvmNetwork(SupportedNetworkId.Ethereum))}
<Pill color="success">Can subscribe</Pill>
{:else}
<Button text="Enable notifications" on:click={() => enableNotifications()} />
{/if}

{#if APP_STAGE === AppStage.PROD}
<BackupToast />
{:else}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<script lang="ts">
import { notificationsManager } from '@auxiliary/wallet-connect/notifications'
import { Button, IconName } from '@bloomwalletio/ui'
import { AccountActionsMenu, AccountSwitcher, FormattedBalance } from '@components'
import { selectedAccountIndex } from '@core/account/stores'
import { selectedAccount, selectedAccountIndex } from '@core/account/stores'
import { formatCurrency, localize } from '@core/i18n'
import { resetLedgerPreparedOutput, resetShowInternalVerificationPopup } from '@core/ledger'
import { SupportedL1EvmNetworkId } from '@core/network'
import { allAccountFiatBalances, selectedAccountTokens } from '@core/token/stores'
import { resetSendFlowParameters } from '@core/wallet'
import { PopupId, openPopup } from '@desktop/auxiliary/popup'
Expand All @@ -29,9 +31,17 @@
}

function onReceiveClick(): void {
openPopup({
id: PopupId.ReceiveAddress,
})
subscribeToNotifications()

// openPopup({
// id: PopupId.ReceiveAddress,
// })
}

function subscribeToNotifications(): void {
// Get the domain of the target dapp from the Explorer API response (https://explorer-api.walletconnect.com/v3/dapps?projectId=YOUR_PROJECT_ID&is_notify_enabled=true)
const appDomain = new URL('https://gm.walletconnect.com').hostname
notificationsManager.subscribeToDapp(appDomain, $selectedAccount, SupportedL1EvmNetworkId.Ethereum)
}
</script>

Expand Down
6 changes: 5 additions & 1 deletion packages/desktop/webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ const appId = stage === 'prod' ? 'org.bloom-labs.bloom' : `org.bloom-labs.bloom.

const appProtocol = stage === 'prod' ? 'bloom' : `bloom-${stage.toLowerCase()}`

const WALLETCONNECT_PROJECT_ID =
mode !== 'development' ? process.env.WALLETCONNECT_PROJECT_ID : '41511f9b50c46a80cdf8bd1a3532f2f9'

// / ------------------------ Resolve ------------------------

const fallback: { [index: string]: string | false | string[] } = {
Expand Down Expand Up @@ -184,14 +187,15 @@ const rendererPlugins = [
new MiniCssExtractPlugin({
filename: '[name].css',
}),

new DefinePlugin({
'process.env.PLATFORM': JSON.stringify(process.env.PLATFORM || 'desktop'),
'process.platform': JSON.stringify(process.platform),
'process.env.STAGE': JSON.stringify(stage),
features: JSON.stringify(features),
PRELOAD_SCRIPT: JSON.stringify(false),
'process.env.APP_PROTOCOL': JSON.stringify(appProtocol),
'process.env.WALLETCONNECT_PROJECT_ID': JSON.stringify(process.env.WALLETCONNECT_PROJECT_ID),
'process.env.WALLETCONNECT_PROJECT_ID': JSON.stringify(WALLETCONNECT_PROJECT_ID),
}),
// The ethereumjs libraries require the NormalModuleReplacementPlugin & the ProvidePlugin
new NormalModuleReplacementPlugin(/node:/, (resource) => {
Expand Down
1 change: 1 addition & 0 deletions packages/shared/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@spruceid/siwe-parser": "2.0.2",
"@sveltejs/svelte-virtual-list": "3.0.1",
"@walletconnect/jsonrpc-types": "1.0.3",
"@walletconnect/notify-client": "^1.2.3",
"@walletconnect/types": "2.11.3",
"@walletconnect/web3wallet": "1.11.2",
"http-status-codes": "2.3.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { ProposalTypes } from '@walletconnect/types'
import { GENERAL_SUPPORTED_METHODS, SUPPORTED_EVENTS } from '../constants'
import { getAddressFromAccountForNetwork } from '@core/account/utils'
import { NetworkId } from '@core/network/types'
import { EvmNetworkId } from '@core/network/types'
import { ISelections } from '../interface'
import { ISupportedNamespace, SupportedNamespaces } from '../types'
import { buildNetworkAddressForWalletConnect } from '../utils'

export function buildSupportedNamespacesFromSelections(
selections: ISelections,
Expand Down Expand Up @@ -49,9 +49,8 @@ function buildSupportedNamespace(
addresses = allowedChains.flatMap((evmNetwork) => {
return (
selections.accounts
?.map((account) => getAddressFromAccountForNetwork(account, evmNetwork as NetworkId))
.filter(Boolean)
.map((address) => `${evmNetwork}:${address}`) ?? []
?.map((account) => buildNetworkAddressForWalletConnect(account, evmNetwork as EvmNetworkId) ?? '')
.filter(Boolean) ?? []
)
})
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,40 @@
import { handleError } from '@core/error/handlers'
import features from '@features/features'
import { Core } from '@walletconnect/core'
import { Web3Wallet } from '@walletconnect/web3wallet'
import { get } from 'svelte/store'
import { WALLET_METADATA } from '../constants'
import { onSessionDelete, onSessionProposal, onSessionRequest } from '../handlers'
import { walletClient } from '../stores'
import { walletClient } from '../stores/wallet-client.store'
import { setConnectedDapps } from '../stores/connected-dapps.store'
import { isFeatureEnabled } from '@lib/features/utils'

export async function initializeWalletConnect(): Promise<void> {
if (!features?.walletConnect?.enabled || get(walletClient)) {
if (isFeatureEnabled('walletConnect.web3Wallet')) {
await initializeWalletClient()
}
if (isFeatureEnabled('walletConnect.notifications')) {
// await initializeNotifyClient()
}
}

async function initializeWalletClient(): Promise<void> {
if (get(walletClient)) {
return
}

try {
const client = await Web3Wallet.init({
const _walletClient = await Web3Wallet.init({
core: new Core({
projectId: process.env.WALLETCONNECT_PROJECT_ID ?? '41511f9b50c46a80cdf8bd1a3532f2f9',
projectId: process.env.WALLETCONNECT_PROJECT_ID,
}),
metadata: WALLET_METADATA,
})
walletClient.set(client)
walletClient.set(_walletClient)
setConnectedDapps()

client.on('session_proposal', (sessionProposal) => void onSessionProposal(sessionProposal))
client.on('session_request', (event) => onSessionRequest(event))
client.on('session_delete', (event) => onSessionDelete(event))
_walletClient.on('session_proposal', (sessionProposal) => void onSessionProposal(sessionProposal))
_walletClient.on('session_request', (event) => onSessionRequest(event))
_walletClient.on('session_delete', (event) => onSessionDelete(event))
} catch (err) {
handleError(err)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './notificationsManager.class'
Loading
Loading