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: walletconnect certified #3206

Merged
merged 31 commits into from
Nov 10, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
da7dc93
feat: wc certified
magiziz Oct 30, 2024
bedc336
fix: merge conflicts
magiziz Oct 31, 2024
d9a35b9
chore: cleanup
magiziz Oct 31, 2024
c19795a
chore: finalize API integration and add tracking
magiziz Nov 4, 2024
f1f997d
chore: change styles for wallet list item and skeleton loaders
magiziz Nov 4, 2024
cfa0ff2
Merge branch 'main' into feat/wc-certified
magiziz Nov 4, 2024
fb55691
chore: cleanup tests
magiziz Nov 4, 2024
792a1e0
chore: make storage type optional
magiziz Nov 4, 2024
ae4fff6
chore: change version
magiziz Nov 4, 2024
7ba9817
chore: tweak params
magiziz Nov 4, 2024
e87acfd
chore: revert edit package version
magiziz Nov 4, 2024
a8c09bc
chore: tweak styles
magiziz Nov 6, 2024
3b5f724
chore: add e2e tests
magiziz Nov 6, 2024
5629018
chore: add unit test to SnackController.test
magiziz Nov 6, 2024
11dbf79
refactor: snackbar
magiziz Nov 6, 2024
d7c7f3a
fix: remove backgroundColor when calling showSvg
magiziz Nov 6, 2024
f1dd591
Merge branch 'main' into feat/wc-certified
magiziz Nov 6, 2024
b7727fe
fix: danger rules
magiziz Nov 6, 2024
cb210ee
Merge branch 'main' into feat/wc-certified
magiziz Nov 7, 2024
9974261
chore: optimize svg and update package version
magiziz Nov 9, 2024
a875ff5
chore: update changeset
magiziz Nov 9, 2024
23e6394
chore: update e2e test
magiziz Nov 9, 2024
259cd42
chore: update changeset
magiziz Nov 9, 2024
395fa80
chore: update e2e test
magiziz Nov 9, 2024
34382d3
chore: update event
magiziz Nov 9, 2024
c26b45e
chore: update SnackController.test
magiziz Nov 9, 2024
faf3c98
fix: merge conflict
magiziz Nov 9, 2024
16ef78d
revert: edit walletconnect svg icon
magiziz Nov 9, 2024
3d7558f
chore: run tests
magiziz Nov 10, 2024
311a800
chore: run tests
magiziz Nov 10, 2024
7b33ff6
chore: update e2e test
magiziz Nov 10, 2024
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
24 changes: 24 additions & 0 deletions .changeset/spicy-mice-scream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
'@reown/appkit-scaffold-ui': patch
'@apps/laboratory': patch
'@reown/appkit-core': patch
'@apps/gallery': patch
'@reown/appkit-ui': patch
'@apps/demo': patch
'@reown/appkit-adapter-ethers': patch
'@reown/appkit-adapter-ethers5': patch
'@reown/appkit-adapter-polkadot': patch
'@reown/appkit-adapter-solana': patch
'@reown/appkit-adapter-wagmi': patch
'@reown/appkit': patch
'@reown/appkit-utils': patch
'@reown/appkit-cdn': patch
'@reown/appkit-common': patch
'@reown/appkit-experimental': patch
'@reown/appkit-polyfills': patch
'@reown/appkit-siwe': patch
'@reown/appkit-siwx': patch
'@reown/appkit-wallet': patch
---

Added certified filtering feature to all wallets view.
27 changes: 27 additions & 0 deletions apps/gallery/stories/composites/wui-certified-switch.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { Meta } from '@storybook/web-components'
import '@reown/appkit-ui/src/composites/wui-certified-switch'
import type { WuiCertifiedSwitch } from '@reown/appkit-ui/src/composites/wui-certified-switch'
import { html } from 'lit'
import '../../components/gallery-container'

type Component = Meta<WuiCertifiedSwitch>

export default {
title: 'Composites/wui-certified-switch',
args: {
checked: false
},
argTypes: {
checked: {
control: { type: 'boolean' }
}
}
} as Component

export const Default: Component = {
render: args => html`
<gallery-container width="88" height="44">
<wui-certified-switch ?checked=${args.checked}></wui-certified-switch>
</gallery-container>
`
}
27 changes: 27 additions & 0 deletions apps/gallery/stories/composites/wui-switch.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { Meta } from '@storybook/web-components'
import '@reown/appkit-ui/src/composites/wui-switch'
import type { WuiSwitch } from '@reown/appkit-ui/src/composites/wui-switch'
import { html } from 'lit'
import '../../components/gallery-container'

type Component = Meta<WuiSwitch>

export default {
title: 'Composites/wui-switch',
args: {
checked: false
},
argTypes: {
checked: {
control: { type: 'boolean' }
}
}
} as Component

export const Default: Component = {
render: args => html`
<gallery-container width="32" height="32">
<wui-switch ?checked=${args.checked}></wui-switch>
</gallery-container>
`
}
6 changes: 6 additions & 0 deletions apps/laboratory/tests/shared/pages/ModalPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,12 @@ export class ModalPage {
await allWalletsListSearchItem.click()
}

async clickCertifiedToggle() {
const allWalletsListSearchItem = this.page.getByTestId('wui-certified-switch')
await expect(allWalletsListSearchItem).toBeVisible()
await allWalletsListSearchItem.click()
}

async clickTabWebApp() {
const tabWebApp = this.page.getByTestId('tab-webapp')
await expect(tabWebApp).toBeVisible()
Expand Down
5 changes: 5 additions & 0 deletions apps/laboratory/tests/shared/validators/ModalValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ export class ModalValidator {
expect(queryParameters[key]).toBe(value)
}

async expectAllWalletsListSearchItem(id: string) {
const allWalletsListSearchItem = this.page.getByTestId(`wallet-search-item-${id}`)
await expect(allWalletsListSearchItem).toBeVisible()
}

async expectNoSocials() {
const socialList = this.page.getByTestId('wui-list-social')
await expect(socialList).toBeHidden()
Expand Down
21 changes: 21 additions & 0 deletions apps/laboratory/tests/wallet-features.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ let context: BrowserContext
/* eslint-enable init-declarations */

const ABSOLUTE_WALLET_ID = 'bfa6967fd05add7bb2b19a442ac37cedb6a6b854483729194f5d7185272c5594'
// Only wallet that is certified
const SAMPLE_WALLET_ID = '92ebfc08f0ac3bc8015a9bf843f9366750d5139b00a166086ad893aeb701acd4'

// -- Setup --------------------------------------------------------------------
const walletFeaturesTest = test.extend<{ library: string }>({
Expand Down Expand Up @@ -102,4 +104,23 @@ walletFeaturesTest('it should open web app wallet', async () => {
key: 'uri',
value: copiedLink
})
await page.closeModal()
})

walletFeaturesTest('it should search for a certified wallet', async () => {
await page.openConnectModal()
await validator.expectAllWallets()
await page.openAllWallets()
await page.clickCertifiedToggle()
await page.page.waitForTimeout(500)
await validator.expectAllWalletsListSearchItem(SAMPLE_WALLET_ID)

// Try searching for a certified wallet while toggle is on
await page.search('sample')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd use the full wallet name to prevent matching unwanted things in the future

await validator.expectAllWalletsListSearchItem(SAMPLE_WALLET_ID)

// Try searching for a certified wallet while toggle is off
await page.clickCertifiedToggle()
await page.search('sample')
await validator.expectAllWalletsListSearchItem(SAMPLE_WALLET_ID)
})
39 changes: 23 additions & 16 deletions packages/core/src/controllers/ApiController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { AssetController } from './AssetController.js'
import { ConnectorController } from './ConnectorController.js'
import { OptionsController } from './OptionsController.js'
import { ChainController } from './ChainController.js'
import { EventsController } from './EventsController.js'

// -- Helpers ------------------------------------------- //
const baseUrl = CoreHelperUtil.getApiUrl()
Expand Down Expand Up @@ -56,13 +57,13 @@ export const ApiController = {
return subKey(state, key, callback)
},

_getApiHeaders() {
_getSdkProperties() {
const { projectId, sdkType, sdkVersion } = OptionsController.state

return {
'x-project-id': projectId,
'x-sdk-type': sdkType || 'appkit',
'x-sdk-version': sdkVersion || 'html-wagmi-4.2.2'
projectId,
st: sdkType || 'appkit',
sv: sdkVersion || 'html-wagmi-4.2.2'
}
},

Expand All @@ -76,31 +77,31 @@ export const ApiController = {

async _fetchWalletImage(imageId: string) {
const imageUrl = `${api.baseUrl}/getWalletImage/${imageId}`
const blob = await api.getBlob({ path: imageUrl, headers: ApiController._getApiHeaders() })
const blob = await api.getBlob({ path: imageUrl, params: ApiController._getSdkProperties() })
AssetController.setWalletImage(imageId, URL.createObjectURL(blob))
},

async _fetchNetworkImage(imageId: string) {
const imageUrl = `${api.baseUrl}/public/getAssetImage/${imageId}`
const blob = await api.getBlob({ path: imageUrl, headers: ApiController._getApiHeaders() })
const blob = await api.getBlob({ path: imageUrl, params: ApiController._getSdkProperties() })
AssetController.setNetworkImage(imageId, URL.createObjectURL(blob))
},

async _fetchConnectorImage(imageId: string) {
const imageUrl = `${api.baseUrl}/public/getAssetImage/${imageId}`
const blob = await api.getBlob({ path: imageUrl, headers: ApiController._getApiHeaders() })
const blob = await api.getBlob({ path: imageUrl, params: ApiController._getSdkProperties() })
AssetController.setConnectorImage(imageId, URL.createObjectURL(blob))
},

async _fetchCurrencyImage(countryCode: string) {
const imageUrl = `${api.baseUrl}/public/getCurrencyImage/${countryCode}`
const blob = await api.getBlob({ path: imageUrl, headers: ApiController._getApiHeaders() })
const blob = await api.getBlob({ path: imageUrl, params: ApiController._getSdkProperties() })
AssetController.setCurrencyImage(countryCode, URL.createObjectURL(blob))
},

async _fetchTokenImage(symbol: string) {
const imageUrl = `${api.baseUrl}/public/getTokenImage/${symbol}`
const blob = await api.getBlob({ path: imageUrl, headers: ApiController._getApiHeaders() })
const blob = await api.getBlob({ path: imageUrl, params: ApiController._getSdkProperties() })
AssetController.setTokenImage(symbol, URL.createObjectURL(blob))
},

Expand Down Expand Up @@ -134,8 +135,8 @@ export const ApiController = {
if (featuredWalletIds?.length) {
const { data } = await api.get<ApiGetWalletsResponse>({
path: '/getWallets',
headers: ApiController._getApiHeaders(),
params: {
...ApiController._getSdkProperties(),
page: '1',
entries: featuredWalletIds?.length
? String(featuredWalletIds.length)
Expand All @@ -156,8 +157,8 @@ export const ApiController = {
const exclude = [...(excludeWalletIds ?? []), ...(featuredWalletIds ?? [])].filter(Boolean)
const { data, count } = await api.get<ApiGetWalletsResponse>({
path: '/getWallets',
headers: ApiController._getApiHeaders(),
params: {
...ApiController._getSdkProperties(),
page: '1',
chains: ChainController.state.activeCaipNetwork?.caipNetworkId,
entries: recommendedEntries,
Expand Down Expand Up @@ -190,8 +191,8 @@ export const ApiController = {
].filter(Boolean)
const { data, count } = await api.get<ApiGetWalletsResponse>({
path: '/getWallets',
headers: ApiController._getApiHeaders(),
params: {
...ApiController._getSdkProperties(),
page: String(page),
entries,
chains: ChainController.state.activeCaipNetwork?.caipNetworkId,
Expand All @@ -216,8 +217,8 @@ export const ApiController = {
async searchWalletByIds({ ids }: { ids: string[] }) {
const { data } = await api.get<ApiGetWalletsResponse>({
path: '/getWallets',
headers: ApiController._getApiHeaders(),
params: {
...ApiController._getSdkProperties(),
page: '1',
entries: String(ids.length),
chains: ChainController.state.activeCaipNetwork?.caipNetworkId,
Expand All @@ -234,21 +235,27 @@ export const ApiController = {
}
},

async searchWallet({ search }: Pick<ApiGetWalletsRequest, 'search'>) {
async searchWallet({ search, badge }: Pick<ApiGetWalletsRequest, 'search' | 'badge'>) {
const { includeWalletIds, excludeWalletIds } = OptionsController.state
state.search = []
const { data } = await api.get<ApiGetWalletsResponse>({
path: '/getWallets',
headers: ApiController._getApiHeaders(),
params: {
...ApiController._getSdkProperties(),
page: '1',
entries: '100',
search: search?.trim(),
badge_type: badge,
chains: ChainController.state.activeCaipNetwork?.caipNetworkId,
include: includeWalletIds?.join(','),
exclude: excludeWalletIds?.join(',')
}
})
EventsController.sendEvent({
type: 'track',
event: 'SEARCH_WALLET',
properties: { badge: badge ?? 'none', search: search ?? '' }
})
const images = data.map(w => w.image_id).filter(Boolean)
await Promise.allSettled([
...(images as string[]).map(id => ApiController._fetchWalletImage(id)),
Expand Down Expand Up @@ -280,7 +287,7 @@ export const ApiController = {
async fetchAnalyticsConfig() {
const { isAnalyticsEnabled } = await api.get<ApiGetAnalyticsConfigResponse>({
path: '/getAnalyticsConfig',
headers: ApiController._getApiHeaders()
params: ApiController._getSdkProperties()
})
OptionsController.setFeatures({ analytics: isAnalyticsEnabled })
}
Expand Down
24 changes: 20 additions & 4 deletions packages/core/src/controllers/SnackController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { CoreHelperUtil } from '../utils/CoreHelperUtil.js'
export interface SnackControllerState {
message: string
variant: 'error' | 'success' | 'loading'
svg?: { iconColor: string; icon: string }
open: boolean
}

Expand All @@ -15,6 +16,7 @@ type StateKey = keyof SnackControllerState
const state = proxy<SnackControllerState>({
message: '',
variant: 'success',
svg: undefined,
open: false
})

Expand All @@ -27,33 +29,47 @@ export const SnackController = {
},

showLoading(message: SnackControllerState['message']) {
this._showMessage(message, 'loading')
this._showMessage({ message, variant: 'loading' })
},

showSuccess(message: SnackControllerState['message']) {
this._showMessage(message, 'success')
this._showMessage({ message, variant: 'success' })
},

showSvg(message: SnackControllerState['message'], svg: NonNullable<SnackControllerState['svg']>) {
this._showMessage({ message, svg })
},

showError(message: unknown) {
const errorMessage = CoreHelperUtil.parseError(message)
this._showMessage(errorMessage, 'error')
this._showMessage({ message: errorMessage, variant: 'error' })
},

hide() {
state.open = false
},

_showMessage(message: SnackControllerState['message'], variant: SnackControllerState['variant']) {
_showMessage({
message,
svg,
variant = 'success'
}: {
message: SnackControllerState['message']
svg?: SnackControllerState['svg']
variant?: SnackControllerState['variant']
}) {
if (state.open) {
state.open = false
setTimeout(() => {
state.message = message
state.variant = variant
state.svg = svg
state.open = true
}, 150)
} else {
state.message = message
state.variant = variant
state.svg = svg
state.open = true
}
}
Expand Down
12 changes: 12 additions & 0 deletions packages/core/src/utils/TypeUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ export type Metadata = {
export interface WcWallet {
id: string
name: string
badge_type?: BadgeType
homepage?: string
image_id?: string
image_url?: string
Expand All @@ -132,6 +133,7 @@ export interface ApiGetWalletsRequest {
chains: string
entries: number
search?: string
badge?: BadgeType
include?: string[]
exclude?: string[]
}
Expand Down Expand Up @@ -733,6 +735,14 @@ export type Event =
name: string
}
}
| {
type: 'track'
event: 'SEARCH_WALLET'
properties: {
badge: BadgeType
search: string
}
}
// Onramp Types
export type DestinationWallet = {
address: string
Expand Down Expand Up @@ -991,3 +1001,5 @@ export type UseAppKitNetworkReturn = {
chainId: number | string | undefined
caipNetworkId: CaipNetworkId | undefined
}

export type BadgeType = 'none' | 'certified'
Loading
Loading