@1001-digital/components 1.2.2 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -21
- package/src/index.ts +0 -3
- package/src/evm/assets/wallets/coinbase.svg +0 -4
- package/src/evm/assets/wallets/in-app.svg +0 -5
- package/src/evm/assets/wallets/metamask.svg +0 -1
- package/src/evm/assets/wallets/phantom.svg +0 -4
- package/src/evm/assets/wallets/rabby.svg +0 -24
- package/src/evm/assets/wallets/rainbow.svg +0 -59
- package/src/evm/assets/wallets/safe.png +0 -0
- package/src/evm/assets/wallets/walletconnect.svg +0 -1
- package/src/evm/components/EvmAccount.vue +0 -28
- package/src/evm/components/EvmAvatar.vue +0 -62
- package/src/evm/components/EvmConnect.vue +0 -303
- package/src/evm/components/EvmConnectDialog.vue +0 -75
- package/src/evm/components/EvmConnectionStatus.vue +0 -13
- package/src/evm/components/EvmConnectorQR.vue +0 -86
- package/src/evm/components/EvmInAppWalletSetup.vue +0 -251
- package/src/evm/components/EvmMetaMaskQR.vue +0 -34
- package/src/evm/components/EvmProfile.vue +0 -186
- package/src/evm/components/EvmSeedPhraseInput.vue +0 -193
- package/src/evm/components/EvmSiwe.vue +0 -190
- package/src/evm/components/EvmSiweDialog.vue +0 -93
- package/src/evm/components/EvmSwitchNetwork.vue +0 -132
- package/src/evm/components/EvmTransactionFlow.vue +0 -353
- package/src/evm/components/EvmWalletConnectQR.vue +0 -13
- package/src/evm/components/EvmWalletConnectWallets.vue +0 -200
- package/src/evm/composables/base.ts +0 -7
- package/src/evm/composables/chainId.ts +0 -42
- package/src/evm/composables/ens.ts +0 -113
- package/src/evm/composables/gasPrice.ts +0 -37
- package/src/evm/composables/priceFeed.ts +0 -116
- package/src/evm/composables/siwe.ts +0 -89
- package/src/evm/composables/uri.ts +0 -12
- package/src/evm/composables/walletExplorer.ts +0 -130
- package/src/evm/config.ts +0 -35
- package/src/evm/connectors/inAppWallet.ts +0 -5
- package/src/evm/index.ts +0 -60
- package/src/evm/utils/addresses.ts +0 -6
- package/src/evm/utils/cache.ts +0 -59
- package/src/evm/utils/chains.ts +0 -32
- package/src/evm/utils/ens.ts +0 -116
- package/src/evm/utils/format-eth.ts +0 -15
- package/src/evm/utils/price.ts +0 -17
- package/src/evm/utils/siwe.ts +0 -70
- package/src/evm/utils/uri.ts +0 -24
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<p>
|
|
3
|
-
<slot name="instruction">Scan the code in your wallet application</slot>
|
|
4
|
-
</p>
|
|
5
|
-
<div class="qr-frame">
|
|
6
|
-
<canvas ref="qrCanvas"></canvas>
|
|
7
|
-
</div>
|
|
8
|
-
<Button
|
|
9
|
-
@click="copyUri"
|
|
10
|
-
class="copy-uri tertiary small"
|
|
11
|
-
>
|
|
12
|
-
<Icon :type="isCopied ? 'check' : 'copy'" />
|
|
13
|
-
<span>
|
|
14
|
-
{{ isCopied ? 'Copied' : 'Copy Link' }}
|
|
15
|
-
</span>
|
|
16
|
-
</Button>
|
|
17
|
-
</template>
|
|
18
|
-
|
|
19
|
-
<script setup lang="ts">
|
|
20
|
-
import { ref, watch, onMounted } from 'vue'
|
|
21
|
-
import QRCode from 'qrcode'
|
|
22
|
-
import { useClipboard } from '@vueuse/core'
|
|
23
|
-
import Button from '../../base/components/Button.vue'
|
|
24
|
-
import Icon from '../../base/components/Icon.vue'
|
|
25
|
-
|
|
26
|
-
const props = defineProps<{
|
|
27
|
-
uri: string
|
|
28
|
-
}>()
|
|
29
|
-
|
|
30
|
-
const qrCanvas = ref<HTMLCanvasElement | null>(null)
|
|
31
|
-
const { copy, copied: isCopied } = useClipboard()
|
|
32
|
-
|
|
33
|
-
const generateQR = async () => {
|
|
34
|
-
if (!qrCanvas.value || !props.uri) return
|
|
35
|
-
|
|
36
|
-
try {
|
|
37
|
-
await QRCode.toCanvas(qrCanvas.value, props.uri, {
|
|
38
|
-
width: 300,
|
|
39
|
-
margin: 2,
|
|
40
|
-
color: {
|
|
41
|
-
dark: '#000000',
|
|
42
|
-
light: '#FFFFFF',
|
|
43
|
-
},
|
|
44
|
-
})
|
|
45
|
-
} catch (error) {
|
|
46
|
-
console.error('Failed to generate QR code:', error)
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const copyUri = () => copy(props.uri)
|
|
51
|
-
|
|
52
|
-
watch(() => props.uri, generateQR, { immediate: true })
|
|
53
|
-
|
|
54
|
-
onMounted(() => {
|
|
55
|
-
generateQR()
|
|
56
|
-
})
|
|
57
|
-
</script>
|
|
58
|
-
|
|
59
|
-
<style scoped>
|
|
60
|
-
p {
|
|
61
|
-
text-align: center;
|
|
62
|
-
@mixin ui-font;
|
|
63
|
-
color: var(--muted);
|
|
64
|
-
font-size: var(--font-sm);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
.qr-frame {
|
|
68
|
-
background: white;
|
|
69
|
-
padding: var(--spacer-sm);
|
|
70
|
-
max-width: 15rem;
|
|
71
|
-
max-height: 15rem;
|
|
72
|
-
border: var(--border);
|
|
73
|
-
border-radius: var(--border-radius);
|
|
74
|
-
margin: 0 auto;
|
|
75
|
-
|
|
76
|
-
canvas {
|
|
77
|
-
width: 100% !important;
|
|
78
|
-
height: 100% !important;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
.copy-uri {
|
|
83
|
-
width: fit-content;
|
|
84
|
-
margin: 0 auto;
|
|
85
|
-
}
|
|
86
|
-
</style>
|
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="in-app-wallet-setup">
|
|
3
|
-
<!-- Step: Choose -->
|
|
4
|
-
<div
|
|
5
|
-
v-if="step === 'choose'"
|
|
6
|
-
class="setup-step"
|
|
7
|
-
>
|
|
8
|
-
<p class="muted font-sm">{{ note }}</p>
|
|
9
|
-
|
|
10
|
-
<div class="setup-options">
|
|
11
|
-
<Button
|
|
12
|
-
class="block"
|
|
13
|
-
@click="startGenerate"
|
|
14
|
-
>
|
|
15
|
-
<Icon type="plus" />
|
|
16
|
-
<span>Create New Wallet</span>
|
|
17
|
-
</Button>
|
|
18
|
-
<Button
|
|
19
|
-
class="block"
|
|
20
|
-
@click="step = 'restore'"
|
|
21
|
-
>
|
|
22
|
-
<Icon type="key" />
|
|
23
|
-
<span>Use Existing Recovery Key</span>
|
|
24
|
-
</Button>
|
|
25
|
-
</div>
|
|
26
|
-
<Button
|
|
27
|
-
class="link muted small"
|
|
28
|
-
@click="$emit('back')"
|
|
29
|
-
>
|
|
30
|
-
<Icon type="chevron-left" />
|
|
31
|
-
<span>Back</span>
|
|
32
|
-
</Button>
|
|
33
|
-
</div>
|
|
34
|
-
|
|
35
|
-
<!-- Step: Generate -->
|
|
36
|
-
<div
|
|
37
|
-
v-else-if="step === 'generate'"
|
|
38
|
-
class="setup-step"
|
|
39
|
-
>
|
|
40
|
-
<p class="muted font-sm">
|
|
41
|
-
Write down these 12 words in order. Think of them as your secure
|
|
42
|
-
password so keep them safe - you will need them to restore your account.
|
|
43
|
-
They will not be shown again.
|
|
44
|
-
</p>
|
|
45
|
-
|
|
46
|
-
<div class="generated-words">
|
|
47
|
-
<div
|
|
48
|
-
v-for="(word, i) in generatedWords"
|
|
49
|
-
:key="i"
|
|
50
|
-
class="generated-word"
|
|
51
|
-
>
|
|
52
|
-
<span class="word-number">{{ i + 1 }}</span>
|
|
53
|
-
<span class="word-text">{{ word }}</span>
|
|
54
|
-
</div>
|
|
55
|
-
</div>
|
|
56
|
-
|
|
57
|
-
<div>
|
|
58
|
-
<FormCheckbox v-model="backupConfirmed">
|
|
59
|
-
I've saved my seed phrase
|
|
60
|
-
</FormCheckbox>
|
|
61
|
-
</div>
|
|
62
|
-
|
|
63
|
-
<Button
|
|
64
|
-
class="block"
|
|
65
|
-
:disabled="!backupConfirmed"
|
|
66
|
-
@click="confirmGenerated"
|
|
67
|
-
>
|
|
68
|
-
Continue
|
|
69
|
-
</Button>
|
|
70
|
-
<Button
|
|
71
|
-
class="link muted small"
|
|
72
|
-
@click="step = 'choose'"
|
|
73
|
-
>
|
|
74
|
-
<Icon type="chevron-left" />
|
|
75
|
-
<span>Back</span>
|
|
76
|
-
</Button>
|
|
77
|
-
</div>
|
|
78
|
-
|
|
79
|
-
<!-- Step: Restore -->
|
|
80
|
-
<div
|
|
81
|
-
v-else-if="step === 'restore'"
|
|
82
|
-
class="setup-step"
|
|
83
|
-
>
|
|
84
|
-
<p class="muted font-sm">
|
|
85
|
-
Enter your 12-word seed phrase to restore your wallet.
|
|
86
|
-
</p>
|
|
87
|
-
|
|
88
|
-
<EvmSeedPhraseInput
|
|
89
|
-
v-model="restorePhrase"
|
|
90
|
-
@valid="restoreValid = $event"
|
|
91
|
-
@submit="restoreWallet"
|
|
92
|
-
/>
|
|
93
|
-
|
|
94
|
-
<Button
|
|
95
|
-
class="block"
|
|
96
|
-
:disabled="!restoreValid"
|
|
97
|
-
@click="restoreWallet"
|
|
98
|
-
>
|
|
99
|
-
Restore Wallet
|
|
100
|
-
</Button>
|
|
101
|
-
<Button
|
|
102
|
-
class="link muted small"
|
|
103
|
-
@click="step = 'choose'"
|
|
104
|
-
>
|
|
105
|
-
<Icon type="chevron-left" />
|
|
106
|
-
<span>Back</span>
|
|
107
|
-
</Button>
|
|
108
|
-
</div>
|
|
109
|
-
|
|
110
|
-
<!-- Step: Connecting -->
|
|
111
|
-
<div
|
|
112
|
-
v-else-if="step === 'connecting'"
|
|
113
|
-
class="setup-step"
|
|
114
|
-
>
|
|
115
|
-
<Loading
|
|
116
|
-
txt="Connecting wallet..."
|
|
117
|
-
spinner
|
|
118
|
-
stacked
|
|
119
|
-
/>
|
|
120
|
-
</div>
|
|
121
|
-
</div>
|
|
122
|
-
</template>
|
|
123
|
-
|
|
124
|
-
<script setup lang="ts">
|
|
125
|
-
import { ref, computed } from 'vue'
|
|
126
|
-
import { useConnect, useConnectors } from '@wagmi/vue'
|
|
127
|
-
import Button from '../../base/components/Button.vue'
|
|
128
|
-
import Icon from '../../base/components/Icon.vue'
|
|
129
|
-
import Alert from '../../base/components/Alert.vue'
|
|
130
|
-
import FormCheckbox from '../../base/components/FormCheckbox.vue'
|
|
131
|
-
import Loading from '../../base/components/Loading.vue'
|
|
132
|
-
import EvmSeedPhraseInput from './EvmSeedPhraseInput.vue'
|
|
133
|
-
import { prepareInAppWallet } from '../connectors/inAppWallet'
|
|
134
|
-
|
|
135
|
-
const props = withDefaults(
|
|
136
|
-
defineProps<{
|
|
137
|
-
note?: string
|
|
138
|
-
}>(),
|
|
139
|
-
{
|
|
140
|
-
note: 'Create a browser-based wallet stored locally on this device. Only you have access to your keys.',
|
|
141
|
-
},
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
const emit = defineEmits<{
|
|
145
|
-
connected: []
|
|
146
|
-
back: []
|
|
147
|
-
}>()
|
|
148
|
-
|
|
149
|
-
const connectors = useConnectors()
|
|
150
|
-
const { mutateAsync: connectAsync } = useConnect()
|
|
151
|
-
const inAppConnector = computed(() =>
|
|
152
|
-
connectors.value.find((c) => c.type === 'inAppWallet'),
|
|
153
|
-
)
|
|
154
|
-
|
|
155
|
-
type Step = 'choose' | 'generate' | 'restore' | 'connecting'
|
|
156
|
-
const step = ref<Step>('choose')
|
|
157
|
-
|
|
158
|
-
// Generate state
|
|
159
|
-
const generatedMnemonic = ref('')
|
|
160
|
-
const generatedWords = ref<string[]>([])
|
|
161
|
-
const backupConfirmed = ref(false)
|
|
162
|
-
|
|
163
|
-
// Restore state
|
|
164
|
-
const restorePhrase = ref('')
|
|
165
|
-
const restoreValid = ref(false)
|
|
166
|
-
|
|
167
|
-
async function startGenerate() {
|
|
168
|
-
const { generateMnemonic, english } = await import('viem/accounts')
|
|
169
|
-
generatedMnemonic.value = generateMnemonic(english)
|
|
170
|
-
generatedWords.value = generatedMnemonic.value.split(' ')
|
|
171
|
-
backupConfirmed.value = false
|
|
172
|
-
step.value = 'generate'
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
async function connectWithMnemonic(mnemonic: string) {
|
|
176
|
-
await prepareInAppWallet(mnemonic)
|
|
177
|
-
await connectAsync({ connector: inAppConnector.value! })
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
async function confirmGenerated() {
|
|
181
|
-
step.value = 'connecting'
|
|
182
|
-
try {
|
|
183
|
-
await connectWithMnemonic(generatedMnemonic.value)
|
|
184
|
-
emit('connected')
|
|
185
|
-
} catch (e) {
|
|
186
|
-
console.error('Failed to connect in-app wallet:', e)
|
|
187
|
-
step.value = 'generate'
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
async function restoreWallet() {
|
|
192
|
-
if (!restoreValid.value) return
|
|
193
|
-
step.value = 'connecting'
|
|
194
|
-
try {
|
|
195
|
-
await connectWithMnemonic(restorePhrase.value)
|
|
196
|
-
emit('connected')
|
|
197
|
-
} catch (e) {
|
|
198
|
-
console.error('Failed to restore in-app wallet:', e)
|
|
199
|
-
step.value = 'restore'
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
</script>
|
|
203
|
-
|
|
204
|
-
<style scoped>
|
|
205
|
-
.in-app-wallet-setup {
|
|
206
|
-
display: grid;
|
|
207
|
-
gap: var(--spacer);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
.setup-step {
|
|
211
|
-
display: grid;
|
|
212
|
-
gap: var(--spacer);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
.setup-options {
|
|
216
|
-
display: grid;
|
|
217
|
-
gap: var(--spacer);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
.generated-words {
|
|
221
|
-
display: grid;
|
|
222
|
-
grid-template-columns: repeat(3, 1fr);
|
|
223
|
-
gap: var(--spacer-sm);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
.generated-word {
|
|
227
|
-
display: flex;
|
|
228
|
-
align-items: center;
|
|
229
|
-
gap: var(--spacer-sm);
|
|
230
|
-
border: var(--border);
|
|
231
|
-
border-radius: var(--border-radius);
|
|
232
|
-
padding: var(--spacer-sm);
|
|
233
|
-
|
|
234
|
-
.word-number {
|
|
235
|
-
font-size: var(--font-xs);
|
|
236
|
-
color: var(--muted);
|
|
237
|
-
min-width: 1.5em;
|
|
238
|
-
text-align: right;
|
|
239
|
-
user-select: none;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
.word-text {
|
|
243
|
-
font-size: var(--font-sm);
|
|
244
|
-
font-family: var(--font-mono, monospace);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
.link.muted {
|
|
249
|
-
justify-self: center;
|
|
250
|
-
}
|
|
251
|
-
</style>
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<EvmConnectorQR :uri="uri">
|
|
3
|
-
<template #instruction>
|
|
4
|
-
Scan the code in your MetaMask mobile app
|
|
5
|
-
</template>
|
|
6
|
-
</EvmConnectorQR>
|
|
7
|
-
<Button
|
|
8
|
-
class="link muted small"
|
|
9
|
-
@click="$emit('back')"
|
|
10
|
-
>
|
|
11
|
-
<Icon type="chevron-left" />
|
|
12
|
-
<span>Back</span>
|
|
13
|
-
</Button>
|
|
14
|
-
</template>
|
|
15
|
-
|
|
16
|
-
<script setup lang="ts">
|
|
17
|
-
import EvmConnectorQR from './EvmConnectorQR.vue'
|
|
18
|
-
import Button from '../../base/components/Button.vue'
|
|
19
|
-
import Icon from '../../base/components/Icon.vue'
|
|
20
|
-
|
|
21
|
-
defineProps<{
|
|
22
|
-
uri: string
|
|
23
|
-
}>()
|
|
24
|
-
|
|
25
|
-
defineEmits<{
|
|
26
|
-
back: []
|
|
27
|
-
}>()
|
|
28
|
-
</script>
|
|
29
|
-
|
|
30
|
-
<style scoped>
|
|
31
|
-
.link.muted {
|
|
32
|
-
justify-self: center;
|
|
33
|
-
}
|
|
34
|
-
</style>
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<Button
|
|
3
|
-
@click="dialogOpen = true"
|
|
4
|
-
:class="className"
|
|
5
|
-
>
|
|
6
|
-
<slot
|
|
7
|
-
:address="address"
|
|
8
|
-
:display="display"
|
|
9
|
-
:ens-name="ensName"
|
|
10
|
-
:ens-avatar="ensAvatar"
|
|
11
|
-
>
|
|
12
|
-
{{ display }}
|
|
13
|
-
</slot>
|
|
14
|
-
</Button>
|
|
15
|
-
|
|
16
|
-
<Dialog
|
|
17
|
-
v-model:open="dialogOpen"
|
|
18
|
-
class="evm-profile"
|
|
19
|
-
title="Account"
|
|
20
|
-
compat
|
|
21
|
-
>
|
|
22
|
-
<div class="profile-header">
|
|
23
|
-
<div
|
|
24
|
-
class="banner"
|
|
25
|
-
:style="
|
|
26
|
-
ensHeader ? { backgroundImage: `url(${ensHeader})` } : undefined
|
|
27
|
-
"
|
|
28
|
-
/>
|
|
29
|
-
<div class="avatar-wrapper">
|
|
30
|
-
<EvmAvatar
|
|
31
|
-
:address="address"
|
|
32
|
-
large
|
|
33
|
-
/>
|
|
34
|
-
</div>
|
|
35
|
-
</div>
|
|
36
|
-
|
|
37
|
-
<div class="profile-identity">
|
|
38
|
-
<strong v-if="ensName">{{ ensName }}</strong>
|
|
39
|
-
<Button
|
|
40
|
-
class="link muted small"
|
|
41
|
-
@click="copyAddress"
|
|
42
|
-
>
|
|
43
|
-
<span>{{ shortAddr }}</span>
|
|
44
|
-
<Icon :type="copied ? 'check' : 'copy'" />
|
|
45
|
-
</Button>
|
|
46
|
-
</div>
|
|
47
|
-
|
|
48
|
-
<div class="profile-actions">
|
|
49
|
-
<slot name="actions" />
|
|
50
|
-
|
|
51
|
-
<EvmSwitchNetwork class-name="block">
|
|
52
|
-
<template #default="{ currentChain }">
|
|
53
|
-
<Icon type="wallet" />
|
|
54
|
-
<span>Switch Network ({{ currentChain?.name || 'Unknown' }})</span>
|
|
55
|
-
</template>
|
|
56
|
-
</EvmSwitchNetwork>
|
|
57
|
-
|
|
58
|
-
<Button
|
|
59
|
-
v-if="ensName"
|
|
60
|
-
class="block"
|
|
61
|
-
:to="`https://app.ens.domains/${ensName}`"
|
|
62
|
-
target="_blank"
|
|
63
|
-
>
|
|
64
|
-
<Icon type="link" />
|
|
65
|
-
<span>Manage ENS</span>
|
|
66
|
-
</Button>
|
|
67
|
-
|
|
68
|
-
<Button
|
|
69
|
-
class="block danger"
|
|
70
|
-
@click="disconnect"
|
|
71
|
-
>
|
|
72
|
-
<span>Disconnect</span>
|
|
73
|
-
</Button>
|
|
74
|
-
</div>
|
|
75
|
-
</Dialog>
|
|
76
|
-
</template>
|
|
77
|
-
|
|
78
|
-
<script setup lang="ts">
|
|
79
|
-
import { ref, computed, nextTick } from 'vue'
|
|
80
|
-
import { useConnection, useDisconnect } from '@wagmi/vue'
|
|
81
|
-
import { useClipboard } from '@vueuse/core'
|
|
82
|
-
import { useConfirm } from '../../base/composables/confirm'
|
|
83
|
-
import { useEnsProfile } from '../composables/ens'
|
|
84
|
-
import { useResolveUri } from '../composables/uri'
|
|
85
|
-
import { shortAddress } from '../utils/addresses'
|
|
86
|
-
import Button from '../../base/components/Button.vue'
|
|
87
|
-
import Dialog from '../../base/components/Dialog.vue'
|
|
88
|
-
import Icon from '../../base/components/Icon.vue'
|
|
89
|
-
import EvmAvatar from './EvmAvatar.vue'
|
|
90
|
-
import EvmSwitchNetwork from './EvmSwitchNetwork.vue'
|
|
91
|
-
|
|
92
|
-
defineProps<{
|
|
93
|
-
className?: string
|
|
94
|
-
}>()
|
|
95
|
-
|
|
96
|
-
const emit = defineEmits<{
|
|
97
|
-
disconnected: []
|
|
98
|
-
}>()
|
|
99
|
-
|
|
100
|
-
const { address } = useConnection()
|
|
101
|
-
const { mutate: disconnectWallet } = useDisconnect()
|
|
102
|
-
const { confirm } = useConfirm()
|
|
103
|
-
const { data: ensData } = useEnsProfile(address)
|
|
104
|
-
|
|
105
|
-
const { copy, copied } = useClipboard()
|
|
106
|
-
const resolve = useResolveUri()
|
|
107
|
-
|
|
108
|
-
const ensName = computed(() => ensData.value?.ens || null)
|
|
109
|
-
const ensAvatar = computed(() => resolve(ensData.value?.data?.avatar))
|
|
110
|
-
const ensHeader = computed(() => resolve(ensData.value?.data?.header))
|
|
111
|
-
|
|
112
|
-
const shortAddr = computed(() =>
|
|
113
|
-
address.value ? shortAddress(address.value) : '',
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
const display = computed(() => ensName.value || shortAddr.value)
|
|
117
|
-
|
|
118
|
-
const dialogOpen = ref(false)
|
|
119
|
-
|
|
120
|
-
const copyAddress = () => {
|
|
121
|
-
if (address.value) copy(address.value)
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const disconnect = async () => {
|
|
125
|
-
const confirmed = await confirm({
|
|
126
|
-
title: 'Disconnect Wallet',
|
|
127
|
-
description: 'Are you sure you want to disconnect your wallet?',
|
|
128
|
-
okText: 'Disconnect',
|
|
129
|
-
})
|
|
130
|
-
|
|
131
|
-
if (!confirmed) return
|
|
132
|
-
|
|
133
|
-
dialogOpen.value = false
|
|
134
|
-
await nextTick()
|
|
135
|
-
disconnectWallet()
|
|
136
|
-
emit('disconnected')
|
|
137
|
-
}
|
|
138
|
-
</script>
|
|
139
|
-
|
|
140
|
-
<style scoped>
|
|
141
|
-
.profile-header {
|
|
142
|
-
position: relative;
|
|
143
|
-
margin: calc(var(--spacer) * -3) calc(var(--spacer) * -1) 0;
|
|
144
|
-
margin-bottom: 0;
|
|
145
|
-
z-index: -1;
|
|
146
|
-
|
|
147
|
-
.banner {
|
|
148
|
-
aspect-ratio: 3 / 1;
|
|
149
|
-
width: 100%;
|
|
150
|
-
height: auto;
|
|
151
|
-
background-color: var(--gray-z-1);
|
|
152
|
-
background-size: cover;
|
|
153
|
-
background-position: center;
|
|
154
|
-
border-bottom: var(--border);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
.avatar-wrapper {
|
|
158
|
-
display: flex;
|
|
159
|
-
justify-content: center;
|
|
160
|
-
margin-top: -10%;
|
|
161
|
-
position: relative;
|
|
162
|
-
z-index: 1;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
:deep(.evm-avatar) {
|
|
166
|
-
border: 3px solid var(--background);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
.profile-identity {
|
|
171
|
-
display: grid;
|
|
172
|
-
justify-items: center;
|
|
173
|
-
gap: var(--spacer-sm);
|
|
174
|
-
|
|
175
|
-
> strong {
|
|
176
|
-
font-size: var(--font-lg);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
.profile-actions {
|
|
181
|
-
display: grid;
|
|
182
|
-
gap: var(--spacer);
|
|
183
|
-
padding-block-start: var(--spacer);
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
</style>
|