Skip to content
Draft
995 changes: 0 additions & 995 deletions core/wallet-ui-components/src/components/wallet-picker.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

import { WalletPickerEntry } from '@canton-network/core-types'
import { CSSResultGroup, html, LitElement, nothing } from 'lit'
import { customElement, property } from 'lit/decorators.js'
import { BaseElement } from '../../../../internal/base-element'
import styles from './styles'

@customElement('wallet-picker-card')
export class WalletPickerCard extends LitElement {
static styles: CSSResultGroup = [BaseElement.styles, styles]

@property({ type: Object })
entry!: WalletPickerEntry

@property({ type: Boolean })
isRemovable: boolean = true

private validate() {
if (!this.entry) throw Error('Property `entry` must be passed')
}

connectedCallback(): void {
this.validate()
}

renderIcon() {
return this.entry.icon
? html` <img src=${this.entry.icon} alt=${this.entry.name} /> `
: html`<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
${this.entry.type === 'browser'
? html`<rect
x="3"
y="11"
width="18"
height="11"
rx="2"
ry="2"
></rect>
<path d="M7 11V7a5 5 0 0 1 10 0v4" />`
: html` <rect
x="2"
y="3"
width="20"
height="14"
rx="2"
></rect>
<path d="M8 21h8"></path>
<path d="M12 17v4"></path>
<circle cx="12" cy="10" r="2" />`}
</svg>`
}

renderRemoveButton() {
if (!this.isRemovable || !this.entry.url) return nothing
return html`
<button
class="wallet-remove-btn"
type="button"
aria-label="Remove custom wallet ${this.entry.name}"
title="Remove custom wallet ${this.entry.name}"
@click=${this.handleRemove}
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
viewBox="0 0 16 16"
>
<path
d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0z"
/>
<path
d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4zM2.5 3h11V2h-11z"
/>
</svg>
</button>
`
}

render() {
return html`
<div
class="wallet-card"
role="button"
tabindex="0"
aria-label="Connect to ${this.entry.name}"
@click=${this.handleSelect}
>
<div class="wallet-icon">${this.renderIcon()}</div>
<span class="wallet-name">${this.entry.name}</span>
${this.renderRemoveButton()}
</div>
`
}

private handleSelect() {
this.dispatchEvent(
new CustomEvent('select', {
detail: this.entry,
})
)
// TODO: trigger this.selectWallet(entry)
}

private handleRemove(event: Event) {
event.stopPropagation()
this.dispatchEvent(new CustomEvent('remove'))
// TODO: trigger this.removeRecentGateway(entry.url!)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

import { css } from 'lit'
import commonStyles from '../../styles'

export default css`
${commonStyles}

.wallet-remove-btn {
border: none;
background: transparent;
color: var(--wg-theme-text-secondary);
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: color 0.15s ease;
flex-shrink: 0;
padding: 0;
width: 16px;
height: 16px;
}

.wallet-remove-btn:hover {
color: var(--wg-theme-error-color);
}

.wallet-remove-btn:focus-visible {
outline: 2px solid var(--wg-theme-accent-color);
outline-offset: 4px;
border-radius: 4px;
}

.wallet-remove-btn svg {
width: 16px;
height: 16px;
}

.wallet-card {
display: flex;
align-items: center;
gap: 12px;
padding: 14px 16px;
border-radius: 8px;
border: 1px solid var(--wg-theme-border-color);
background: var(--wg-theme-surface-color);
cursor: pointer;
transition: all 0.15s ease;
width: 100%;
text-align: left;
margin-bottom: 8px;
}

.wallet-card:hover {
background: var(--wg-theme-surface-hover);
border-color: var(--wg-theme-accent-color);
}

.wallet-card:focus-visible {
outline: 2px solid var(--wg-theme-accent-color);
outline-offset: 2px;
}

.wallet-card:active {
transform: scale(0.99);
}

.wallet-icon {
width: 32px;
height: 32px;
border-radius: 8px;
background: var(--wg-theme-icon-bg);
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
overflow: hidden;
}

.wallet-icon img {
width: 32px;
height: 32px;
border-radius: 8px;
object-fit: cover;
}

.wallet-icon svg {
width: 22px;
height: 22px;
color: var(--wg-theme-text-secondary);
}

.wallet-name {
flex: 1;
min-width: 0;
font-size: 15px;
font-weight: 500;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

import { CSSResultGroup, html, LitElement } from 'lit'
import { customElement, property } from 'lit/decorators.js'
import { BaseElement } from '../../../../internal/base-element'
import styles from './styles'

@customElement('wallet-picker-connected')
export class WalletPickerConnected extends LitElement {
static styles: CSSResultGroup = [BaseElement.styles, styles]

@property({ type: String })
entryName: string = ''

render() {
return html`
<div class="success-icon">
<svg
width="40"
height="40"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M20 6 9 17l-5-5" />
</svg>
</div>
<h3>Connected to ${this.entryName || 'wallet'}</h3>
`
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

import { css } from 'lit'
import commonStyles from '../../styles'

export default css`
${commonStyles}

.success-icon {
color: var(--wg-theme-success-color);
}
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

import { WalletPickerEntry } from '@canton-network/core-types'
import { CSSResultGroup, html, LitElement } from 'lit'
import { customElement, property, state } from 'lit/decorators.js'
import { BaseElement } from '../../../../internal/base-element'
import styles from './styles'

@customElement('wallet-picker-connecting')
export class WalletPickerConnecting extends LitElement {
static styles: CSSResultGroup = [BaseElement.styles, styles]

@property()
wcUri = ''

@property()
wcQrDataUrl = ''

@property({ type: Object })
entry: WalletPickerEntry | null = null

@state()
copyButtonClicked = false

render() {
return this.wcUri
? html`
${this.wcQrDataUrl &&
html` <img src="${this.wcQrDataUrl}" alt="QR Code" /> `}
<h3>
${this.wcQrDataUrl
? 'Or paste this URI in your wallet'
: 'Paste this URI in your wallet'}
</h3>
<code>${this.wcUri}</code>
<button @click=${this.handleCopy}>
${this.copyButtonClicked ? 'Copied!' : 'Copy URI'}
</button>
`
: html`
<div class="spinner"></div>
<h3>Connecting to ${this.entry?.name || ''}...</h3>
<p>
${this.entry?.type === 'remote'
? 'Approve the connection in the wallet popup'
: 'Approve the connection in your extension'}
</p>
`
}

private handleCopy() {
navigator.clipboard.writeText(this.wcUri)
this.copyButtonClicked = true
setTimeout(() => {
this.copyButtonClicked = false
}, 2000)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

import { css } from 'lit'
import commonStyles from '../../styles'

export default css`
${commonStyles}

code {
display: block;
word-break: break-all;
font-size: 11px;
background: var(--wg-theme-background-color, #111);
padding: 12px;
border-radius: 6px;
margin: 8px 0;
max-height: 120px;
overflow: auto;
user-select: all;
cursor: pointer;
}

img {
display: block;
margin: 0 auto 12px;
width: 200px;
height: 200px;
border-radius: 8px;
}

button {
padding: 8px 16px;
border-radius: 4px;
border: none;
background: #646cff;
color: white;
cursor: pointer;
font-size: 14px;
margin-top: 4px;
}

.spinner {
width: 36px;
height: 36px;
border: 3px solid var(--wg-theme-border-color);
border-top-color: var(--wg-theme-accent-color);
border-radius: 50%;
animation: spin 0.8s linear infinite;
}

@keyframes spin {
to {
transform: rotate(360deg);
}
}
`
Loading
Loading